open source is social v-it.org
0
fork

Configure Feed

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

add vet command with agent gate and trust marking

New files: src/cmd/vet.js, test/vet.test.js

Modified: src/cli.js

+140
+2
src/cli.js
··· 11 11 import registerFirehose from './cmd/firehose.js'; 12 12 import registerShip from './cmd/ship.js'; 13 13 import registerSkim from './cmd/skim.js'; 14 + import registerVet from './cmd/vet.js'; 14 15 import registerFollow from './cmd/follow.js'; 15 16 import registerSetup from './cmd/setup.js'; 16 17 ··· 29 30 registerFirehose(program); 30 31 registerShip(program); 31 32 registerSkim(program); 33 + registerVet(program); 32 34 registerFollow(program); 33 35 registerSetup(program); 34 36
+99
src/cmd/vet.js
··· 1 + // SPDX-License-Identifier: AGPL-3.0-only 2 + // Copyright (c) 2026 sol pbc 3 + 4 + import { loadConfig } from '../lib/config.js'; 5 + import { restoreAgent } from '../lib/oauth.js'; 6 + import { appendLog } from '../lib/vit-dir.js'; 7 + import { requireNotAgent } from '../lib/agent.js'; 8 + 9 + export default function register(program) { 10 + program 11 + .command('vet') 12 + .argument('<cap-ref>', 'AT URI of the cap to review (e.g. at://did:plc:.../org.v-it.cap/...)') 13 + .description('Review a cap before trusting it') 14 + .option('--did <did>', 'DID to use (reads saved DID from config if not provided)') 15 + .option('--trust', 'Mark the cap as locally trusted') 16 + .option('-v, --verbose', 'Show step-by-step details') 17 + .action(async (capRef, opts) => { 18 + try { 19 + const gate = requireNotAgent(); 20 + if (!gate.ok) { 21 + console.error(`vit vet cannot run inside ${gate.name} (detected ${gate.envVar}=1).`); 22 + console.error(''); 23 + console.error('Cap vetting requires human review for safety.'); 24 + console.error('Ask your user to run this command in their terminal:'); 25 + console.error(''); 26 + console.error(` vit vet ${capRef}`); 27 + console.error(''); 28 + console.error('After reviewing, they can trust it with:'); 29 + console.error(''); 30 + console.error(` vit vet ${capRef} --trust`); 31 + console.error(''); 32 + console.error('Once trusted, ask your user to confirm and you can proceed.'); 33 + process.exitCode = 1; 34 + return; 35 + } 36 + 37 + const { verbose } = opts; 38 + 39 + const parts = capRef.split('/'); 40 + // at://did:plc:xxx/org.v-it.cap/tid -> ['at:', '', 'did:plc:xxx', 'org.v-it.cap', 'tid'] 41 + if (parts.length < 5 || parts[0] !== 'at:' || !parts[2] || !parts[3] || !parts[4]) { 42 + console.error('Invalid cap reference. Expected AT URI: at://did:plc:.../org.v-it.cap/...'); 43 + process.exitCode = 1; 44 + return; 45 + } 46 + const repo = parts[2]; 47 + const collection = parts[3]; 48 + const rkey = parts[4]; 49 + if (verbose) console.log(`[verbose] Parsed URI repo=${repo} collection=${collection} rkey=${rkey}`); 50 + 51 + const did = opts.did || loadConfig().did; 52 + if (!did) { 53 + console.error("No DID configured. Run 'vit login <handle>' first or pass --did."); 54 + process.exitCode = 1; 55 + return; 56 + } 57 + if (verbose) console.log(`[verbose] DID: ${did}`); 58 + 59 + const { agent, session } = await restoreAgent(did); 60 + if (verbose) console.log(`[verbose] Session restored, PDS: ${session.serverMetadata?.issuer}`); 61 + 62 + if (verbose) console.log(`[verbose] Fetching ${collection} from ${repo} rkey=${rkey}`); 63 + const res = await agent.com.atproto.repo.getRecord({ repo, collection, rkey }); 64 + const record = res.data.value; 65 + 66 + if (opts.trust) { 67 + appendLog('trusted.jsonl', { 68 + uri: capRef, 69 + trustedAt: new Date().toISOString(), 70 + }); 71 + console.log(`Trusted: ${capRef}`); 72 + return; 73 + } 74 + 75 + const author = repo; 76 + const time = record.createdAt || 'unknown'; 77 + const beacon = record.beacon || 'none'; 78 + const text = record.text || ''; 79 + 80 + console.log('=== Cap Review ==='); 81 + console.log('Review this cap carefully before trusting it.'); 82 + console.log(''); 83 + console.log(` Author: ${author}`); 84 + console.log(` Time: ${time}`); 85 + console.log(` Beacon: ${beacon}`); 86 + console.log(''); 87 + console.log('--- Text ---'); 88 + console.log(text); 89 + console.log('---'); 90 + console.log(''); 91 + console.log('To trust this cap, run:'); 92 + console.log(''); 93 + console.log(` vit vet ${capRef} --trust`); 94 + } catch (err) { 95 + console.error(err instanceof Error ? err.message : String(err)); 96 + process.exitCode = 1; 97 + } 98 + }); 99 + }
+39
test/vet.test.js
··· 1 + // SPDX-License-Identifier: AGPL-3.0-only 2 + // Copyright (c) 2026 sol pbc 3 + 4 + import { describe, test, expect } from 'bun:test'; 5 + import { run } from './helpers.js'; 6 + 7 + const FAKE_URI = 'at://did:plc:fake123/org.v-it.cap/fake456'; 8 + 9 + describe('vit vet', () => { 10 + test('shows help with <cap-ref> argument', () => { 11 + const result = run('vet --help'); 12 + expect(result.stdout).toContain('<cap-ref>'); 13 + }); 14 + 15 + test('rejects when run inside a coding agent', () => { 16 + const result = run('vet ' + FAKE_URI, undefined, { CLAUDECODE: '1' }); 17 + expect(result.exitCode).toBe(1); 18 + expect(result.stderr).toContain('cannot run inside claude code'); 19 + expect(result.stderr).toContain(`vit vet ${FAKE_URI}`); 20 + expect(result.stderr).toContain('--trust'); 21 + }); 22 + 23 + test('rejects when run inside gemini', () => { 24 + const result = run('vet ' + FAKE_URI, undefined, { CLAUDECODE: '', GEMINI_CLI: '1', CODEX_CI: '' }); 25 + expect(result.exitCode).toBe(1); 26 + expect(result.stderr).toContain('cannot run inside gemini cli'); 27 + }); 28 + 29 + test('rejects invalid AT URI', () => { 30 + const result = run('vet not-a-valid-uri', undefined, { CLAUDECODE: '', GEMINI_CLI: '', CODEX_CI: '' }); 31 + expect(result.exitCode).not.toBe(0); 32 + expect(result.stderr).toContain('Invalid cap reference'); 33 + }); 34 + 35 + test('fails with no arguments', () => { 36 + const result = run('vet'); 37 + expect(result.exitCode).not.toBe(0); 38 + }); 39 + });