open source is social v-it.org
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2026 sol pbc
3
4import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
5import { run } from './helpers.js';
6import { mkdirSync, rmSync } from 'node:fs';
7import { tmpdir } from 'node:os';
8import { join } from 'node:path';
9
10const NON_AGENT_ENV = { CLAUDECODE: '', GEMINI_CLI: '', CODEX_CI: '' };
11
12describe('vit adopt', () => {
13 let tmpDir;
14
15 beforeEach(() => {
16 tmpDir = join(tmpdir(), '.test-adopt-' + Math.random().toString(36).slice(2));
17 mkdirSync(tmpDir, { recursive: true });
18 });
19
20 afterEach(() => {
21 rmSync(tmpDir, { recursive: true, force: true });
22 });
23
24 test('shows help with <beacon> argument', () => {
25 const result = run('adopt --help', tmpDir);
26 expect(result.stdout).toContain('<beacon>');
27 expect(result.stdout).toContain('[name]');
28 });
29
30 test('fails with no arguments', () => {
31 const result = run('adopt', tmpDir);
32 expect(result.exitCode).not.toBe(0);
33 });
34
35 test('fails with invalid beacon', () => {
36 const result = run('adopt notaurl', tmpDir, NON_AGENT_ENV);
37 expect(result.exitCode).not.toBe(0);
38 expect(result.stderr).toContain('Invalid git URL');
39 });
40
41 test('fails if directory already exists', () => {
42 mkdirSync(join(tmpDir, 'hello-world'));
43 const result = run('adopt https://github.com/octocat/Hello-World', tmpDir, NON_AGENT_ENV);
44 expect(result.exitCode).not.toBe(0);
45 expect(result.stderr).toContain('already exists');
46 });
47
48 test('rejects when run inside a coding agent', () => {
49 const result = run('adopt https://github.com/octocat/Hello-World', tmpDir, { CLAUDECODE: '1' });
50 expect(result.exitCode).toBe(1);
51 expect(result.stderr).toContain('must be run by a human');
52 });
53
54 test('clones repo and shows guidance', () => {
55 const result = run('adopt https://github.com/octocat/Hello-World', tmpDir, NON_AGENT_ENV);
56 expect(result.exitCode).toBe(0);
57 expect(result.stdout).toContain('vit:github.com/octocat/hello-world');
58 expect(result.stdout).toContain('hello-world');
59 expect(result.stdout).toContain('start your agent');
60 }, 30000);
61
62 test('clones into custom directory name', () => {
63 const result = run('adopt https://github.com/octocat/Hello-World my-copy', tmpDir, NON_AGENT_ENV);
64 expect(result.exitCode).toBe(0);
65 expect(result.stdout).toContain('my-copy');
66 }, 30000);
67
68 test('handles vit: prefixed beacon', () => {
69 const result = run('adopt vit:github.com/octocat/Hello-World', tmpDir, NON_AGENT_ENV);
70 expect(result.exitCode).toBe(0);
71 expect(result.stdout).toContain('beacon: vit:github.com/octocat/hello-world');
72 }, 30000);
73
74 test('verbose flag shows step details', () => {
75 const result = run('adopt -v https://github.com/octocat/Hello-World', tmpDir, NON_AGENT_ENV);
76 expect(result.exitCode).toBe(0);
77 expect(result.stdout).toContain('[verbose]');
78 expect(result.stdout).toContain('resolving beacon');
79 }, 30000);
80
81 test('second adopt to same dir fails', () => {
82 run('adopt https://github.com/octocat/Hello-World', tmpDir, NON_AGENT_ENV);
83 const result = run('adopt https://github.com/octocat/Hello-World', tmpDir, NON_AGENT_ENV);
84 expect(result.exitCode).not.toBe(0);
85 expect(result.stderr).toContain('already exists');
86 }, 30000);
87});