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 185 lines 7.3 kB view raw
1// SPDX-License-Identifier: MIT 2// Copyright (c) 2026 sol pbc 3 4import { requireDid } from '../lib/config.js'; 5import { CAP_COLLECTION } from '../lib/constants.js'; 6import { restoreAgent } from '../lib/oauth.js'; 7import { readBeaconSet, readFollowing, readLog } from '../lib/vit-dir.js'; 8import { requireAgent, detectCodingAgent } from '../lib/agent.js'; 9import { shouldBypassVet } from '../lib/trust-gate.js'; 10import { resolveRef, REF_PATTERN } from '../lib/cap-ref.js'; 11import { brand, name } from '../lib/brand.js'; 12import { resolvePds, listRecordsFromPds, batchQuery } from '../lib/pds.js'; 13import { loadConfig } from '../lib/config.js'; 14import { jsonOk, jsonError } from '../lib/json-output.js'; 15import { formatError } from '../lib/error-format.js'; 16 17export default function register(program) { 18 program 19 .command('remix') 20 .argument('<ref>', 'Three-word cap reference (e.g. fast-cache-invalidation)') 21 .description('Derive a vetted cap into the local codebase') 22 .option('--did <did>', 'DID to use') 23 .option('--json', 'Output as JSON') 24 .option('-v, --verbose', 'Show step-by-step details') 25 .action(async (ref, opts) => { 26 try { 27 const gate = requireAgent(); 28 if (!gate.ok) { 29 if (opts.json) { 30 jsonError('agent required', 'run vit remix from a coding agent'); 31 return; 32 } 33 console.error(`${name} remix should be run by a coding agent (e.g. claude code, gemini cli).`); 34 console.error(`open your agent and ask it to run '${name} remix' for you.`); 35 process.exitCode = 1; 36 return; 37 } 38 39 const { verbose } = opts; 40 const vlog = opts.json ? (...a) => console.error(...a) : console.log; 41 42 if (!REF_PATTERN.test(ref)) { 43 if (opts.json) { 44 jsonError('invalid ref', 'expected three lowercase words with dashes'); 45 return; 46 } 47 console.error('invalid ref. expected three lowercase words with dashes (e.g. fast-cache-invalidation)'); 48 process.exitCode = 1; 49 return; 50 } 51 52 if (opts.json && !(opts.did || loadConfig().did)) { 53 jsonError('no DID configured', "run 'vit login <handle>' first"); 54 return; 55 } 56 const did = requireDid(opts); 57 if (!did) return; 58 if (verbose) vlog(`[verbose] DID: ${did}`); 59 60 const beaconSet = readBeaconSet(); 61 if (beaconSet.size === 0) { 62 if (opts.json) { 63 jsonError('no beacon set', "run 'vit init' first"); 64 return; 65 } 66 console.error(`no beacon set. run '${name} init' in a project directory first.`); 67 process.exitCode = 1; 68 return; 69 } 70 if (verbose) vlog(`[verbose] beacons: ${[...beaconSet].join(', ')}`); 71 72 const trusted = readLog('trusted.jsonl'); 73 const trustedEntry = trusted.find(e => e.ref === ref); 74 if (!trustedEntry) { 75 const trustGate = shouldBypassVet(); 76 if (!trustGate.bypass) { 77 if (opts.json) { 78 jsonError(`cap '${ref}' is not trusted`, `tell your operator to run 'vit vet ${ref} --trust'`); 79 return; 80 } 81 console.error(`cap '${ref}' is not trusted. tell your operator to vet it first:`); 82 console.error(''); 83 console.error(` vit vet ${ref}`); 84 console.error(''); 85 console.error('after reviewing, they can trust it with:'); 86 console.error(''); 87 console.error(` vit vet ${ref} --trust`); 88 if (detectCodingAgent()) { 89 console.error(''); 90 console.error('or, to trust all items without review:'); 91 console.error(''); 92 console.error(' vit vet --dangerous-accept --confirm'); 93 } 94 process.exitCode = 1; 95 return; 96 } 97 if (verbose) vlog(`[verbose] vet gate bypassed: ${trustGate.reason}`); 98 } 99 if (verbose && trustedEntry) vlog(`[verbose] trusted entry found, uri: ${trustedEntry.uri}`); 100 101 const { agent } = await restoreAgent(did); 102 if (verbose) vlog('[verbose] session restored'); 103 104 const following = readFollowing(); 105 const dids = following.map(e => e.did); 106 dids.push(did); 107 108 const allRecords = await batchQuery(dids, async (repoDid) => { 109 const pds = await resolvePds(repoDid); 110 if (verbose) vlog(`[verbose] ${repoDid}: resolved PDS ${pds}`); 111 return (await listRecordsFromPds(pds, repoDid, CAP_COLLECTION, 50)).records; 112 }, { verbose }); 113 114 let match = null; 115 for (const records of allRecords) { 116 for (const rec of records) { 117 if (!beaconSet.has(rec.value.beacon)) continue; 118 const recRef = resolveRef(rec.value, rec.cid); 119 if (recRef === ref) { 120 if (!match || (rec.value.createdAt || '') > (match.value.createdAt || '')) { 121 match = rec; 122 } 123 } 124 } 125 } 126 127 if (!match) { 128 if (opts.json) { 129 jsonError(`no cap found with ref '${ref}' for this beacon`); 130 return; 131 } 132 console.error(`no cap found with ref '${ref}' for this beacon.`); 133 console.error(''); 134 console.error('hint: caps only appear from accounts you follow and your own.'); 135 console.error(` vit following check who you're following`); 136 console.error(` vit explore cap ${ref} search the network-wide index`); 137 process.exitCode = 1; 138 return; 139 } 140 141 const record = match.value; 142 const author = match.uri.split('/')[2]; 143 const title = record.title || ref; 144 const description = record.description || ''; 145 const text = record.text || ''; 146 147 if (opts.json) { 148 jsonOk({ ref, author, title, description, text }); 149 return; 150 } 151 152 console.log(`# ${brand} remix: ${title}`); 153 console.log(''); 154 console.log(`ref: ${ref}`); 155 console.log(`author: ${author}`); 156 if (description) console.log(`description: ${description}`); 157 console.log(''); 158 console.log('---'); 159 console.log(''); 160 console.log('you are remixing a vetted cap into the current codebase.'); 161 console.log('create a thorough implementation plan that:'); 162 console.log(''); 163 console.log('1. adapts the cap to this repo\'s architecture, conventions, and existing code'); 164 console.log('2. follows local guidelines (CLAUDE.md, project conventions, coding standards)'); 165 console.log('3. identifies all files to create or modify'); 166 console.log('4. specifies tests to add or update'); 167 console.log('5. notes any dependencies or migrations needed'); 168 console.log(''); 169 console.log('do not apply the cap blindly. produce a well-researched plan first.'); 170 console.log(''); 171 console.log('---'); 172 console.log(''); 173 console.log('## cap content'); 174 console.log(''); 175 console.log(text); 176 } catch (err) { 177 if (opts.json) { 178 jsonError(err); 179 return; 180 } 181 console.error(formatError(err, { verbose: opts.verbose })); 182 process.exitCode = 1; 183 } 184 }); 185}