UNPKG

aiwg

Version:

Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 6 more) so one source of truth works across 10 platfo

88 lines (86 loc) 3.65 kB
import { checkRepoAccess, findRepoEntry, formatRepoAccessEntry, loadRepoAccessManifest, } from '../../policy/repo-access.js'; function valueAfter(args, flag) { const index = args.indexOf(flag); if (index < 0) return null; return args[index + 1] ?? null; } function printHelp() { console.log(` aiwg repo-access — repo authorization manifest preflight Usage: aiwg repo-access list aiwg repo-access explain --path <repo-or-file> aiwg repo-access check --path <repo-or-file> --action <read|write|commit|push|issue-comment|service-action|destructive> Manifest: .aiwg/ops/security/repo-access.manifest.yaml .aiwg/security/repo-access.manifest.yaml (fallback) `); } async function handleRepoAccess(ctx) { const [subcommand = 'help', ...args] = ctx.args; if (subcommand === 'help' || subcommand === '--help' || subcommand === '-h') { printHelp(); return { exitCode: 0 }; } try { const manifest = loadRepoAccessManifest(ctx.cwd); if (subcommand === 'list') { console.log(`Repo access manifest: ${manifest.path}`); console.log(`Default policy: ${manifest.defaultPolicy}`); for (const repo of manifest.repos) { console.log(`- ${formatRepoAccessEntry(repo)}`); } return { exitCode: 0 }; } if (subcommand === 'explain') { const requestedPath = valueAfter(args, '--path'); if (!requestedPath) return { exitCode: 2, message: 'repo-access explain requires --path <repo-or-file>' }; const entry = findRepoEntry(manifest, requestedPath, ctx.cwd); if (!entry) { console.log(`Path: ${requestedPath}`); console.log('Matched repo: none'); console.log('Decision: unlisted repo/path defaults to denied'); return { exitCode: 0 }; } console.log(`Path: ${requestedPath}`); console.log(`Matched repo: ${formatRepoAccessEntry(entry)}`); return { exitCode: 0 }; } if (subcommand === 'check') { const requestedPath = valueAfter(args, '--path'); const action = valueAfter(args, '--action'); if (!requestedPath) return { exitCode: 2, message: 'repo-access check requires --path <repo-or-file>' }; if (!action) return { exitCode: 2, message: 'repo-access check requires --action <action>' }; const decision = checkRepoAccess(manifest, requestedPath, action, ctx.cwd); const status = decision.allowed ? 'ALLOW' : 'DENY'; console.log(`${status} ${decision.action} ${decision.requestedPath}`); console.log(decision.reason); if (decision.matchedRepo) { console.log(`matched: ${formatRepoAccessEntry(decision.matchedRepo)}`); } return { exitCode: decision.allowed ? 0 : 1 }; } return { exitCode: 2, message: `Unknown repo-access subcommand: ${subcommand}` }; } catch (error) { return { exitCode: 2, message: error instanceof Error ? error.message : String(error), error: error instanceof Error ? error : undefined, }; } } export const repoAccessHandler = { id: 'repo-access', name: 'Repo Access', description: 'Validate and query repo access manifest permissions', category: 'utility', aliases: [], execute: handleRepoAccess, }; export const repoAccessHandlers = [repoAccessHandler]; //# sourceMappingURL=repo-access.js.map