open source is social v-it.org
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 93 lines 3.5 kB view raw
1// SPDX-License-Identifier: MIT 2// Copyright (c) 2026 sol pbc 3 4import { existsSync } from 'node:fs'; 5import { resolve } from 'node:path'; 6import { execFileSync } from 'node:child_process'; 7import { parseGitUrl, toBeacon, beaconToHttps } from '../lib/beacon.js'; 8import { requireNotAgent } from '../lib/agent.js'; 9import { which } from '../lib/compat.js'; 10import { mark, name } from '../lib/brand.js'; 11import { formatError } from '../lib/error-format.js'; 12 13export default function register(program) { 14 program 15 .command('adopt') 16 .argument('<beacon>', 'Beacon URI, git URL, or slug to adopt (e.g. vit:github.com/org/repo)') 17 .argument('[name]', 'Local directory name (defaults to repo name)') 18 .description('Fork or clone a project') 19 .option('-v, --verbose', 'Show step-by-step details') 20 .action(async (beacon, targetName, opts) => { 21 try { 22 const gate = requireNotAgent(); 23 if (!gate.ok) { 24 console.error(`${name} adopt must be run by a human. run it in your own terminal.`); 25 process.exitCode = 1; 26 return; 27 } 28 29 const { verbose } = opts; 30 31 // resolve beacon 32 if (verbose) console.log(`[verbose] resolving beacon: ${beacon}`); 33 const httpsUrl = beaconToHttps(beacon); 34 const parsed = parseGitUrl(httpsUrl); 35 const beaconUri = 'vit:' + toBeacon(httpsUrl); 36 if (verbose) console.log(`[verbose] beacon: ${beaconUri}`); 37 if (verbose) console.log(`[verbose] https: ${httpsUrl}`); 38 39 // determine directory name 40 const dirName = targetName || parsed.repo; 41 const dirPath = resolve(dirName); 42 if (verbose) console.log(`[verbose] target directory: ${dirPath}`); 43 44 // fail fast if directory exists 45 if (existsSync(dirPath)) { 46 console.error(`Directory already exists: ${dirName}`); 47 process.exitCode = 1; 48 return; 49 } 50 51 // detect gh + github host 52 const ghPath = which('gh'); 53 const isGitHub = parsed.host === 'github.com'; 54 if (verbose) console.log(`[verbose] gh available: ${ghPath ? 'yes' : 'no'}, github host: ${isGitHub ? 'yes' : 'no'}`); 55 56 if (ghPath && isGitHub) { 57 if (verbose) console.log(`[verbose] gh found at ${ghPath}, forking via gh`); 58 try { 59 execFileSync('gh', ['repo', 'fork', httpsUrl, '--clone', '--', dirName], { 60 encoding: 'utf-8', 61 stdio: ['pipe', 'pipe', 'pipe'], 62 }); 63 } catch (err) { 64 console.error(`Fork failed: ${(err.stderr || err.message || '').trim()}`); 65 process.exitCode = 1; 66 return; 67 } 68 } else { 69 if (verbose) console.log(`[verbose] cloning via git`); 70 try { 71 execFileSync('git', ['clone', httpsUrl, dirName], { 72 encoding: 'utf-8', 73 stdio: ['pipe', 'pipe', 'pipe'], 74 }); 75 } catch (err) { 76 console.error(`Clone failed: ${(err.stderr || err.message || '').trim()}`); 77 process.exitCode = 1; 78 return; 79 } 80 } 81 82 // success output 83 console.log(`${mark} beacon: ${beaconUri}`); 84 console.log(`${mark} directory: ${dirName}`); 85 console.log(`run: cd ${dirName}`); 86 console.log(''); 87 console.log(`next: start your agent and ask it to run '${name} init'`); 88 } catch (err) { 89 console.error(formatError(err, { verbose: opts.verbose })); 90 process.exitCode = 1; 91 } 92 }); 93}