@njeybe/nativ 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/LICENSE +21 -0
- package/README.md +334 -0
- package/bin/cli.js +31 -0
- package/dist/commands/bench.d.ts +8 -0
- package/dist/commands/bench.js +52 -0
- package/dist/commands/db.d.ts +22 -0
- package/dist/commands/db.js +415 -0
- package/dist/commands/doctor.d.ts +38 -0
- package/dist/commands/doctor.js +169 -0
- package/dist/commands/hook.d.ts +31 -0
- package/dist/commands/hook.js +105 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.js +144 -0
- package/dist/commands/mcp.d.ts +5 -0
- package/dist/commands/mcp.js +16 -0
- package/dist/commands/setup.d.ts +17 -0
- package/dist/commands/setup.js +51 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.js +75 -0
- package/dist/commands/task.d.ts +83 -0
- package/dist/commands/task.js +807 -0
- package/dist/commands/test-gen.d.ts +14 -0
- package/dist/commands/test-gen.js +52 -0
- package/dist/commands/triage.d.ts +70 -0
- package/dist/commands/triage.js +343 -0
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.js +112 -0
- package/dist/commands/validate.d.ts +1 -0
- package/dist/commands/validate.js +89 -0
- package/dist/commands/verify.d.ts +8 -0
- package/dist/commands/verify.js +65 -0
- package/dist/commands/worktree.d.ts +47 -0
- package/dist/commands/worktree.js +396 -0
- package/dist/core/benchmark.d.ts +57 -0
- package/dist/core/benchmark.js +772 -0
- package/dist/core/enforcement.d.ts +80 -0
- package/dist/core/enforcement.js +271 -0
- package/dist/core/legacy-templates.d.ts +24 -0
- package/dist/core/legacy-templates.js +60 -0
- package/dist/core/lock-manager.d.ts +54 -0
- package/dist/core/lock-manager.js +260 -0
- package/dist/core/root-resolver.d.ts +32 -0
- package/dist/core/root-resolver.js +149 -0
- package/dist/core/setup-assets.d.ts +123 -0
- package/dist/core/setup-assets.js +438 -0
- package/dist/core/telemetry.d.ts +156 -0
- package/dist/core/telemetry.js +416 -0
- package/dist/core/test-generator-types.d.ts +227 -0
- package/dist/core/test-generator-types.js +179 -0
- package/dist/core/test-generator.d.ts +34 -0
- package/dist/core/test-generator.js +1690 -0
- package/dist/core/tier1-liaison.d.ts +139 -0
- package/dist/core/tier1-liaison.js +320 -0
- package/dist/core/verifier.d.ts +52 -0
- package/dist/core/verifier.js +249 -0
- package/dist/core/version.d.ts +5 -0
- package/dist/core/version.js +14 -0
- package/dist/core/worktree-merge.d.ts +30 -0
- package/dist/core/worktree-merge.js +98 -0
- package/dist/db/data-engine.d.ts +46 -0
- package/dist/db/data-engine.js +802 -0
- package/dist/db/diff.d.ts +39 -0
- package/dist/db/diff.js +420 -0
- package/dist/db/env-parser.d.ts +86 -0
- package/dist/db/env-parser.js +549 -0
- package/dist/db/introspector.d.ts +21 -0
- package/dist/db/introspector.js +835 -0
- package/dist/db/types.d.ts +217 -0
- package/dist/db/types.js +9 -0
- package/dist/governor/circuit-breaker.d.ts +100 -0
- package/dist/governor/circuit-breaker.js +231 -0
- package/dist/governor/evaluator.d.ts +67 -0
- package/dist/governor/evaluator.js +851 -0
- package/dist/governor/index.d.ts +6 -0
- package/dist/governor/index.js +6 -0
- package/dist/governor/rules/api-rules.d.ts +2 -0
- package/dist/governor/rules/api-rules.js +140 -0
- package/dist/governor/rules/db-rules.d.ts +2 -0
- package/dist/governor/rules/db-rules.js +180 -0
- package/dist/governor/store.d.ts +33 -0
- package/dist/governor/store.js +84 -0
- package/dist/governor/types.d.ts +64 -0
- package/dist/governor/types.js +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +358 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.js +309 -0
- package/dist/providers/claude-api.d.ts +5 -0
- package/dist/providers/claude-api.js +75 -0
- package/dist/providers/claude-cli.d.ts +13 -0
- package/dist/providers/claude-cli.js +134 -0
- package/dist/providers/gemini.d.ts +8 -0
- package/dist/providers/gemini.js +78 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.js +5 -0
- package/dist/providers/registry.d.ts +38 -0
- package/dist/providers/registry.js +121 -0
- package/dist/providers/types.d.ts +74 -0
- package/dist/providers/types.js +25 -0
- package/dist/runner/agent-supervisor.d.ts +363 -0
- package/dist/runner/agent-supervisor.js +1672 -0
- package/dist/scanner/context-builder.d.ts +2 -0
- package/dist/scanner/context-builder.js +29 -0
- package/dist/scanner/detector.d.ts +2 -0
- package/dist/scanner/detector.js +760 -0
- package/dist/scanner/types.d.ts +80 -0
- package/dist/scanner/types.js +50 -0
- package/dist/server/studio-server.d.ts +39 -0
- package/dist/server/studio-server.js +1931 -0
- package/dist/server/studio-ui.d.ts +15 -0
- package/dist/server/studio-ui.js +5321 -0
- package/package.json +70 -0
- package/plugin/.claude-plugin/plugin.json +18 -0
- package/plugin/.mcp.json +10 -0
- package/plugin/agents/architect.md +28 -0
- package/plugin/agents/verifier.md +28 -0
- package/plugin/agents/worker.md +26 -0
- package/plugin/hooks/hooks.json +28 -0
- package/plugin/skills/nativ/SKILL.md +75 -0
- package/templates/.claudeignore +45 -0
- package/templates/AGENTS.md +67 -0
- package/templates/CLAUDE.md +32 -0
- package/templates/GEMINI.md +66 -0
- package/templates/claude-agents/architect.md +28 -0
- package/templates/claude-agents/verifier.md +28 -0
- package/templates/claude-agents/worker.md +26 -0
- package/templates/dot-ai/api_contracts.json +66 -0
- package/templates/dot-ai/context.md +38 -0
- package/templates/dot-ai/db_schema.json +39 -0
- package/templates/dot-ai/master_plan.json +28 -0
- package/templates/dot-ai/subagents/backend.md +11 -0
- package/templates/dot-ai/subagents/database.md +10 -0
- package/templates/dot-ai/subagents/db-migration.md +11 -0
- package/templates/dot-ai/subagents/devops-agent.md +11 -0
- package/templates/dot-ai/subagents/flutter-developer.md +11 -0
- package/templates/dot-ai/subagents/frontend.md +126 -0
- package/templates/dot-ai/subagents/qa-tester.md +13 -0
- package/templates/dot-ai/subagents/security-auditor.md +11 -0
- package/templates/dot-ai/ui_specs.md +78 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { runInit } from './commands/init.js';
|
|
3
|
+
import { runStatus } from './commands/status.js';
|
|
4
|
+
import { runValidate } from './commands/validate.js';
|
|
5
|
+
import { runTaskList, runTaskNext, runTaskStart, runTaskComplete, runTaskBlock, runTaskEscalate, runTaskAdd, runTaskProposePatch, runTaskUnlock, } from './commands/task.js';
|
|
6
|
+
import { runHookCheck, runHookStatus } from './commands/hook.js';
|
|
7
|
+
import { runSetup } from './commands/setup.js';
|
|
8
|
+
import { runDoctor } from './commands/doctor.js';
|
|
9
|
+
import { runSessionContext } from './core/setup-assets.js';
|
|
10
|
+
import { runWorktreeCreate, runWorktreeList, runWorktreeMerge, runWorktreeRemove, } from './commands/worktree.js';
|
|
11
|
+
import { runUpdate } from './commands/update.js';
|
|
12
|
+
import { runDbStatus, runDbInspect, runDbDiff, runDbSync, runDbUi } from './commands/db.js';
|
|
13
|
+
import { runMcp } from './commands/mcp.js';
|
|
14
|
+
import { runVerify } from './commands/verify.js';
|
|
15
|
+
import { runTestGen, TEST_GEN_FRAMEWORK_HELP } from './commands/test-gen.js';
|
|
16
|
+
import { runBench } from './commands/bench.js';
|
|
17
|
+
import { runTriage } from './commands/triage.js';
|
|
18
|
+
import { packageVersion } from './core/version.js';
|
|
19
|
+
export function createProgram() {
|
|
20
|
+
const program = new Command();
|
|
21
|
+
program
|
|
22
|
+
.name('nativ')
|
|
23
|
+
.description('Role-based multi-agent workflow harness: Claude Code by default, other AI agents pluggable')
|
|
24
|
+
.version(packageVersion());
|
|
25
|
+
program
|
|
26
|
+
.command('init [targetDir]')
|
|
27
|
+
.description('Scaffold the workflow (.ai/, AGENTS.md, directives) and the Claude Code configuration in the target directory')
|
|
28
|
+
.option('-f, --force', 'Overwrite existing specification and directive files')
|
|
29
|
+
.action(async (targetDir, options) => {
|
|
30
|
+
await runInit(targetDir, options);
|
|
31
|
+
});
|
|
32
|
+
program
|
|
33
|
+
.command('setup [targetDir]')
|
|
34
|
+
.description('Write the Claude Code configuration (.mcp.json, .claude/settings.json, agents, AGENTS.md), merging without overwriting your own settings')
|
|
35
|
+
.option('--command <cli>', 'How Claude Code should start nativ, e.g. "npx -y @njeybe/nativ" (default: nativ when installed globally)')
|
|
36
|
+
.option('--enforcement <mode>', 'Role enforcement mode: warn (default), block or off')
|
|
37
|
+
.option('--dry-run', 'Show what would change without writing anything')
|
|
38
|
+
.option('-f, --force', 'Also overwrite agent and directive files that were edited by hand')
|
|
39
|
+
.option('--json', 'Output the result as JSON')
|
|
40
|
+
.action(async (targetDir, options) => {
|
|
41
|
+
await runSetup(targetDir, { command: options.command, enforcement: options.enforcement, dryRun: options.dryRun, force: options.force, json: options.json });
|
|
42
|
+
});
|
|
43
|
+
program
|
|
44
|
+
.command('doctor [targetDir]')
|
|
45
|
+
.description('Check the Claude Code integration for drift (MCP server, hooks, permissions, agents, providers) and repair it with --fix')
|
|
46
|
+
.option('--fix', 'Repair missing or out-of-date files (runs setup)')
|
|
47
|
+
.option('--command <cli>', 'How Claude Code should start nativ (see setup)')
|
|
48
|
+
.option('--no-deep', 'Skip asking Claude Code itself (`claude mcp list`, a few seconds) whether the MCP server connects')
|
|
49
|
+
.option('--json', 'Output the report as JSON')
|
|
50
|
+
.action((targetDir, options) => {
|
|
51
|
+
runDoctor(targetDir, { fix: options.fix, command: options.command, json: options.json, deep: options.deep !== false });
|
|
52
|
+
});
|
|
53
|
+
program
|
|
54
|
+
.command('update [targetDir]')
|
|
55
|
+
.description('Refresh directives, role guides and the Claude Code configuration to the latest templates. Files you edited are kept; contracts and the plan are never touched')
|
|
56
|
+
.option('-f, --force', 'Also replace directive and role-guide files that were edited by hand')
|
|
57
|
+
.action(async (targetDir, options) => {
|
|
58
|
+
await runUpdate(targetDir, { force: options.force });
|
|
59
|
+
});
|
|
60
|
+
program
|
|
61
|
+
.command('status [targetDir]')
|
|
62
|
+
.description('Inspect current execution progress and telemetry from .ai/master_plan.json')
|
|
63
|
+
.option('-t, --telemetry', 'Display token usage, duration, and cost estimation telemetry')
|
|
64
|
+
.option('--json', 'Output project status and telemetry as JSON')
|
|
65
|
+
.action(async (targetDir, options) => {
|
|
66
|
+
await runStatus(targetDir, options);
|
|
67
|
+
});
|
|
68
|
+
program
|
|
69
|
+
.command('validate [targetDir]')
|
|
70
|
+
.description('Verify integrity of all .ai contracts, schemas, and agent profiles')
|
|
71
|
+
.action(async (targetDir) => {
|
|
72
|
+
await runValidate(targetDir);
|
|
73
|
+
});
|
|
74
|
+
program
|
|
75
|
+
.command('tasks [targetDir]')
|
|
76
|
+
.description('List all project tasks with optional filters (--available, --status, --milestone, --json)')
|
|
77
|
+
.option('-a, --available', 'Show only available unblocked tasks ready for execution')
|
|
78
|
+
.option('-s, --status <status>', 'Filter tasks by status (pending, in_progress, completed, blocked)')
|
|
79
|
+
.option('-m, --milestone <id>', 'Filter tasks by milestone ID or name')
|
|
80
|
+
.option('--fast-path', 'Show only fast-path tasks')
|
|
81
|
+
.option('--json', 'Output filtered tasks as JSON')
|
|
82
|
+
.action(async (targetDir, options) => {
|
|
83
|
+
await runTaskList(targetDir, options);
|
|
84
|
+
});
|
|
85
|
+
program
|
|
86
|
+
.command('verify [taskId] [targetDir]')
|
|
87
|
+
.description('Execute task verification commands to prevent regressions and validate build health')
|
|
88
|
+
.option('-a, --all', 'Run verification commands for all completed tasks in the project')
|
|
89
|
+
.option('-m, --milestone <id>', 'Run verification commands for all tasks in a specific milestone')
|
|
90
|
+
.option('--json', 'Output verification telemetry as JSON')
|
|
91
|
+
.option('--timeout <ms>', 'Execution timeout in milliseconds per command (default 120000)', parseInt)
|
|
92
|
+
.action(async (taskId, targetDir, options) => {
|
|
93
|
+
await runVerify(taskId, targetDir, options);
|
|
94
|
+
});
|
|
95
|
+
program
|
|
96
|
+
.command('bench [targetDir]')
|
|
97
|
+
.description('Run synthetic evaluation benchmarks across concurrency, invariants, verifications, and telemetry')
|
|
98
|
+
.option('-s, --scenario <scenario>', 'Target scenario to benchmark (concurrency, governor, verification, telemetry, e2e, all)', 'all')
|
|
99
|
+
.option('-c, --concurrency <number>', 'Number of simulated concurrent agent workers', parseInt)
|
|
100
|
+
.option('-o, --output <file>', 'Path to write the JSON benchmark report')
|
|
101
|
+
.option('--json', 'Output raw benchmark metrics as JSON')
|
|
102
|
+
.action(async (targetDir, options) => {
|
|
103
|
+
await runBench(targetDir, options);
|
|
104
|
+
});
|
|
105
|
+
const task = program
|
|
106
|
+
.command('task')
|
|
107
|
+
.description('Manage task lifecycle and JIT context slicing in .ai/master_plan.json');
|
|
108
|
+
task
|
|
109
|
+
.command('list [targetDir]')
|
|
110
|
+
.description('List all project tasks with optional filters (--available, --status, --milestone, --json)')
|
|
111
|
+
.option('-a, --available', 'Show only available unblocked tasks ready for execution')
|
|
112
|
+
.option('-s, --status <status>', 'Filter tasks by status (pending, in_progress, completed, blocked)')
|
|
113
|
+
.option('-m, --milestone <id>', 'Filter tasks by milestone ID or name')
|
|
114
|
+
.option('--fast-path', 'Show only fast-path tasks')
|
|
115
|
+
.option('--json', 'Output filtered tasks as JSON')
|
|
116
|
+
.action(async (targetDir, options) => {
|
|
117
|
+
await runTaskList(targetDir, options);
|
|
118
|
+
});
|
|
119
|
+
task
|
|
120
|
+
.command('add <title> [targetDir]')
|
|
121
|
+
.description('Append a task to .ai/master_plan.json with an auto-incremented ID (planned or --fast-path track)')
|
|
122
|
+
.option('-m, --milestone <id>', 'Target milestone ID or name (default: active milestone, or the fast-path milestone with --fast-path)')
|
|
123
|
+
.option('-a, --agent <name>', 'Assigned sub-agent (default backend)')
|
|
124
|
+
.option('-v, --verify <command>', 'Verification command run by the task complete gatekeeper')
|
|
125
|
+
.option('-f, --files <paths>', 'Comma-separated target files')
|
|
126
|
+
.option('-d, --description <text>', 'Task description')
|
|
127
|
+
.option('--fast-path', 'Route to the fast-path milestone (created on first use) and flag the task as fast path')
|
|
128
|
+
.option('--deps <ids>', 'Comma-separated dependency task IDs')
|
|
129
|
+
.option('--json', 'Output the created task as JSON')
|
|
130
|
+
.action(async (title, targetDir, options) => {
|
|
131
|
+
await runTaskAdd(title, targetDir, options);
|
|
132
|
+
});
|
|
133
|
+
task
|
|
134
|
+
.command('next [targetDir]')
|
|
135
|
+
.description('Inspect the next executable task and its JIT contract slice')
|
|
136
|
+
.option('--json', 'Output task information as JSON')
|
|
137
|
+
.action(async (targetDir, options) => {
|
|
138
|
+
await runTaskNext(targetDir, options);
|
|
139
|
+
});
|
|
140
|
+
task
|
|
141
|
+
.command('start <taskId> [targetDir]')
|
|
142
|
+
.description('Mark a task as in_progress')
|
|
143
|
+
.action(async (taskId, targetDir) => {
|
|
144
|
+
await runTaskStart(taskId, targetDir);
|
|
145
|
+
});
|
|
146
|
+
task
|
|
147
|
+
.command('complete <taskId> [targetDir]')
|
|
148
|
+
.description('Mark a task as completed (executes verification command unless --no-verify is passed)')
|
|
149
|
+
.option('-n, --notes <notes>', 'Completion notes or summary')
|
|
150
|
+
.option('--no-verify', 'Skip automated verification command execution')
|
|
151
|
+
.option('--timeout <ms>', 'Verification execution timeout in milliseconds', parseInt)
|
|
152
|
+
.action(async (taskId, targetDir, options) => {
|
|
153
|
+
await runTaskComplete(taskId, targetDir, {
|
|
154
|
+
notes: options.notes,
|
|
155
|
+
skipVerify: options.verify === false,
|
|
156
|
+
timeout: options.timeout,
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
task
|
|
160
|
+
.command('verify [taskId] [targetDir]')
|
|
161
|
+
.description('Execute task verification commands to prevent regressions and validate build health')
|
|
162
|
+
.option('-a, --all', 'Run verification commands for all completed tasks in the project')
|
|
163
|
+
.option('-m, --milestone <id>', 'Run verification commands for all tasks in a specific milestone')
|
|
164
|
+
.option('--json', 'Output verification telemetry as JSON')
|
|
165
|
+
.option('--timeout <ms>', 'Execution timeout in milliseconds per command (default 120000)', parseInt)
|
|
166
|
+
.action(async (taskId, targetDir, options) => {
|
|
167
|
+
await runVerify(taskId, targetDir, options);
|
|
168
|
+
});
|
|
169
|
+
task
|
|
170
|
+
.command('block <taskId> [targetDir]')
|
|
171
|
+
.description('Mark a task as blocked with a required reason')
|
|
172
|
+
.requiredOption('-r, --reason <reason>', 'Reason why the task is blocked')
|
|
173
|
+
.action(async (taskId, targetDir, options) => {
|
|
174
|
+
await runTaskBlock(taskId, options.reason, targetDir);
|
|
175
|
+
});
|
|
176
|
+
task
|
|
177
|
+
.command('escalate <taskId> [targetDir]')
|
|
178
|
+
.description('Escalate an architectural/contract blocker to the Architect role (.ai/escalation.json)')
|
|
179
|
+
.option('-t, --type <type>', 'Escalation type (contract_drift, schema_flaw, missing_credential, dependency_conflict, architectural_ambiguity)')
|
|
180
|
+
.option('-d, --details <details>', 'Detailed explanation of the blocker')
|
|
181
|
+
.option('-a, --affected <contracts>', 'Comma-separated affected contracts')
|
|
182
|
+
.action(async (taskId, targetDir, options) => {
|
|
183
|
+
await runTaskEscalate(taskId, targetDir, options);
|
|
184
|
+
});
|
|
185
|
+
task
|
|
186
|
+
.command('propose-patch <taskId> [targetDir]')
|
|
187
|
+
.description('Propose a modification to .ai/db_schema.json or .ai/api_contracts.json through the Contract Governor')
|
|
188
|
+
.requiredOption('--target <target>', 'Target contract (db_schema or api_contracts)')
|
|
189
|
+
.requiredOption('--op <operation>', 'Operation (ADD, ALTER, DROP, RENAME)')
|
|
190
|
+
.requiredOption('--path <path>', 'Dot-notation or pointer path to modify (e.g. users.columns.status)')
|
|
191
|
+
.option('--value <jsonOrString>', 'Value or schema definition to apply')
|
|
192
|
+
.requiredOption('-r, --reason <reason>', 'Technical rationale for proposing this patch')
|
|
193
|
+
.option('--base-hash <hash>', 'Base schema hash to prevent concurrent dirty writes')
|
|
194
|
+
.option('--json', 'Output evaluation verdict as JSON')
|
|
195
|
+
.action(async (taskId, targetDir, options) => {
|
|
196
|
+
await runTaskProposePatch(targetDir, {
|
|
197
|
+
taskId,
|
|
198
|
+
target: options.target,
|
|
199
|
+
operation: options.op,
|
|
200
|
+
path: options.path,
|
|
201
|
+
value: options.value,
|
|
202
|
+
reason: options.reason,
|
|
203
|
+
baseHash: options.baseHash,
|
|
204
|
+
json: options.json,
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
task
|
|
208
|
+
.command('unlock <taskId> [targetDir]')
|
|
209
|
+
.description('Emergency override: let the task edit files outside its targetFiles (contracts and secrets stay protected)')
|
|
210
|
+
.option('-r, --reason <reason>', 'Why enforcement is being lifted')
|
|
211
|
+
.option('--revoke', 'Re-lock the task to its target files')
|
|
212
|
+
.action(async (taskId, targetDir, options) => {
|
|
213
|
+
await runTaskUnlock(taskId, targetDir, { reason: options.reason, revoke: options.revoke });
|
|
214
|
+
});
|
|
215
|
+
const hook = program
|
|
216
|
+
.command('hook')
|
|
217
|
+
.description('Claude Code hook entry points for role enforcement');
|
|
218
|
+
hook
|
|
219
|
+
.command('check [targetDir]')
|
|
220
|
+
.description('PreToolUse hook: read the tool call from stdin and warn or deny writes outside the active task scope')
|
|
221
|
+
.action(async (targetDir) => {
|
|
222
|
+
await runHookCheck(targetDir);
|
|
223
|
+
});
|
|
224
|
+
hook
|
|
225
|
+
.command('context [targetDir]')
|
|
226
|
+
.description('SessionStart hook: print a short orientation for a new Claude Code session')
|
|
227
|
+
.action((targetDir) => {
|
|
228
|
+
runSessionContext(targetDir);
|
|
229
|
+
});
|
|
230
|
+
hook
|
|
231
|
+
.command('status [targetDir]')
|
|
232
|
+
.description('Show the enforcement mode, role and active task scope')
|
|
233
|
+
.option('--json', 'Output status as JSON')
|
|
234
|
+
.action((targetDir, options) => {
|
|
235
|
+
runHookStatus(targetDir, { json: options.json });
|
|
236
|
+
});
|
|
237
|
+
const worktree = program
|
|
238
|
+
.command('worktree')
|
|
239
|
+
.description('Manage isolated git worktrees for parallel agent execution');
|
|
240
|
+
worktree
|
|
241
|
+
.command('create <taskId> [targetDir]')
|
|
242
|
+
.description('Create an isolated git worktree branch for a task with mounted .ai/ contracts')
|
|
243
|
+
.option('--json', 'Output result as JSON')
|
|
244
|
+
.action(async (taskId, targetDir, options) => {
|
|
245
|
+
await runWorktreeCreate(taskId, targetDir, options);
|
|
246
|
+
});
|
|
247
|
+
worktree
|
|
248
|
+
.command('list [targetDir]')
|
|
249
|
+
.description('List active agent git worktrees')
|
|
250
|
+
.option('--json', 'Output worktree list as JSON')
|
|
251
|
+
.action(async (targetDir, options) => {
|
|
252
|
+
await runWorktreeList(targetDir, options);
|
|
253
|
+
});
|
|
254
|
+
worktree
|
|
255
|
+
.command('merge <taskId> [targetDir]')
|
|
256
|
+
.description('Merge and cleanup an agent git worktree branch (Safe Merge Gatekeeper enforced)')
|
|
257
|
+
.option('-f, --force', 'Bypass Safe Merge Gatekeeper checks')
|
|
258
|
+
.option('--json', 'Output result as JSON')
|
|
259
|
+
.action(async (taskId, targetDir, options) => {
|
|
260
|
+
await runWorktreeMerge(taskId, targetDir, options);
|
|
261
|
+
});
|
|
262
|
+
worktree
|
|
263
|
+
.command('remove <taskId> [targetDir]')
|
|
264
|
+
.alias('cleanup')
|
|
265
|
+
.description('Safely remove an agent worktree and discard its branch without merging')
|
|
266
|
+
.option('-f, --force', 'Force removal of worktree and branch')
|
|
267
|
+
.option('--json', 'Output result as JSON')
|
|
268
|
+
.action(async (taskId, targetDir, options) => {
|
|
269
|
+
await runWorktreeRemove(taskId, targetDir, options);
|
|
270
|
+
});
|
|
271
|
+
const db = program
|
|
272
|
+
.command('db')
|
|
273
|
+
.description('Database telemetry, schema introspection, drift detection, and the local DB Studio (credentials never leave this process)');
|
|
274
|
+
db
|
|
275
|
+
.command('status [targetDir]')
|
|
276
|
+
.description('Show Dev/Prod connection health, engine, ping latency, and table count (masked URLs only)')
|
|
277
|
+
.option('--json', 'Output status as JSON')
|
|
278
|
+
.action(async (targetDir, options) => {
|
|
279
|
+
await runDbStatus(targetDir, options);
|
|
280
|
+
});
|
|
281
|
+
db
|
|
282
|
+
.command('inspect [targetDir]')
|
|
283
|
+
.description('Print introspected table structures (columns, types, keys, indexes)')
|
|
284
|
+
.option('-e, --env <env>', 'Environment to inspect (dev or prod)', 'dev')
|
|
285
|
+
.option('-t, --table <name>', 'Only show a single table')
|
|
286
|
+
.option('--json', 'Output schema as JSON')
|
|
287
|
+
.action(async (targetDir, options) => {
|
|
288
|
+
await runDbInspect(targetDir, options);
|
|
289
|
+
});
|
|
290
|
+
db
|
|
291
|
+
.command('diff [targetDir]')
|
|
292
|
+
.description('Compute schema drift from Dev to Prod (or to .ai/db_schema.json with --target contract)')
|
|
293
|
+
.option('--target <target>', 'Comparison target (prod or contract)', 'prod')
|
|
294
|
+
.option('--json', 'Output diff as JSON')
|
|
295
|
+
.option('--exit-code', 'Exit with code 1 when drift is detected (for CI)')
|
|
296
|
+
.action(async (targetDir, options) => {
|
|
297
|
+
await runDbDiff(targetDir, options);
|
|
298
|
+
});
|
|
299
|
+
db
|
|
300
|
+
.command('sync [targetDir]')
|
|
301
|
+
.description('Export a live schema (structure only) into .ai/db_schema.json; previews unless --yes is given')
|
|
302
|
+
.option('-s, --source <env>', 'Source environment (dev or prod)', 'dev')
|
|
303
|
+
.option('-y, --yes', 'Write .ai/db_schema.json instead of previewing')
|
|
304
|
+
.action(async (targetDir, options) => {
|
|
305
|
+
await runDbSync(targetDir, options);
|
|
306
|
+
});
|
|
307
|
+
db
|
|
308
|
+
.command('ui [targetDir]')
|
|
309
|
+
.description('Launch the local Nativ DB Studio web dashboard')
|
|
310
|
+
.option('-p, --port <port>', 'Port to listen on (default 4983)')
|
|
311
|
+
.option('--no-open', 'Do not open the browser automatically')
|
|
312
|
+
.action(async (targetDir, options) => {
|
|
313
|
+
await runDbUi(targetDir, options);
|
|
314
|
+
});
|
|
315
|
+
program
|
|
316
|
+
.command('studio [targetDir]')
|
|
317
|
+
.description('Launch the local Nativ DB Studio web dashboard (alias for `db ui`)')
|
|
318
|
+
.option('-p, --port <port>', 'Port to listen on (default 4983)')
|
|
319
|
+
.option('--no-open', 'Do not open the browser automatically')
|
|
320
|
+
.action(async (targetDir, options) => {
|
|
321
|
+
await runDbUi(targetDir, options);
|
|
322
|
+
});
|
|
323
|
+
const test = program
|
|
324
|
+
.command('test')
|
|
325
|
+
.description('Generate contract and database integrity tests from .ai/ contracts');
|
|
326
|
+
test
|
|
327
|
+
.command('gen [targetDir]')
|
|
328
|
+
.description('Synthesize API contract and DB integrity test suites from .ai/api_contracts.json and .ai/db_schema.json')
|
|
329
|
+
.option('-o, --output <dir>', 'Output directory, relative to the project (default tests/contract)')
|
|
330
|
+
.option('-f, --framework <name>', `${TEST_GEN_FRAMEWORK_HELP} (default vitest)`)
|
|
331
|
+
.option('-b, --base-url <url>', 'Base URL the API suites call (default http://localhost:3000)')
|
|
332
|
+
.option('--dry-run', 'Show what would be generated without writing files')
|
|
333
|
+
.option('--json', 'Output the generation result as JSON')
|
|
334
|
+
.action(async (targetDir, options) => {
|
|
335
|
+
await runTestGen(targetDir, options);
|
|
336
|
+
});
|
|
337
|
+
program
|
|
338
|
+
.command('triage [escalationId] [targetDir]')
|
|
339
|
+
.description('Run the Tier 1 AI Strategist (Claude by default, Gemini optional) on pending escalations: auto-resolve safe contract fixes or present a decision card')
|
|
340
|
+
.option('-a, --all', 'Triage every pending escalation (report only, no prompts)')
|
|
341
|
+
.option('--apply', 'Write sandbox-proven additive patches to the contracts and unblock their tasks')
|
|
342
|
+
.option('--threshold <policy>', "Risk threshold: 'safe_contracts_only' (default) or 'all_non_destructive'")
|
|
343
|
+
.option('--json', 'Output evaluations as JSON (no prompts)')
|
|
344
|
+
.action(async (escalationId, targetDir, options) => {
|
|
345
|
+
await runTriage(escalationId, targetDir, options);
|
|
346
|
+
});
|
|
347
|
+
program
|
|
348
|
+
.command('mcp [targetDir]')
|
|
349
|
+
.description('Run the native MCP (Model Context Protocol) server over stdio, exposing nativ tools and .ai/ contract resources')
|
|
350
|
+
.action(async (targetDir) => {
|
|
351
|
+
await runMcp(targetDir);
|
|
352
|
+
});
|
|
353
|
+
return program;
|
|
354
|
+
}
|
|
355
|
+
export async function run() {
|
|
356
|
+
const program = createProgram();
|
|
357
|
+
await program.parseAsync(process.argv);
|
|
358
|
+
}
|