@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.
Files changed (140) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/LICENSE +21 -0
  3. package/README.md +334 -0
  4. package/bin/cli.js +31 -0
  5. package/dist/commands/bench.d.ts +8 -0
  6. package/dist/commands/bench.js +52 -0
  7. package/dist/commands/db.d.ts +22 -0
  8. package/dist/commands/db.js +415 -0
  9. package/dist/commands/doctor.d.ts +38 -0
  10. package/dist/commands/doctor.js +169 -0
  11. package/dist/commands/hook.d.ts +31 -0
  12. package/dist/commands/hook.js +105 -0
  13. package/dist/commands/init.d.ts +3 -0
  14. package/dist/commands/init.js +144 -0
  15. package/dist/commands/mcp.d.ts +5 -0
  16. package/dist/commands/mcp.js +16 -0
  17. package/dist/commands/setup.d.ts +17 -0
  18. package/dist/commands/setup.js +51 -0
  19. package/dist/commands/status.d.ts +5 -0
  20. package/dist/commands/status.js +75 -0
  21. package/dist/commands/task.d.ts +83 -0
  22. package/dist/commands/task.js +807 -0
  23. package/dist/commands/test-gen.d.ts +14 -0
  24. package/dist/commands/test-gen.js +52 -0
  25. package/dist/commands/triage.d.ts +70 -0
  26. package/dist/commands/triage.js +343 -0
  27. package/dist/commands/update.d.ts +14 -0
  28. package/dist/commands/update.js +112 -0
  29. package/dist/commands/validate.d.ts +1 -0
  30. package/dist/commands/validate.js +89 -0
  31. package/dist/commands/verify.d.ts +8 -0
  32. package/dist/commands/verify.js +65 -0
  33. package/dist/commands/worktree.d.ts +47 -0
  34. package/dist/commands/worktree.js +396 -0
  35. package/dist/core/benchmark.d.ts +57 -0
  36. package/dist/core/benchmark.js +772 -0
  37. package/dist/core/enforcement.d.ts +80 -0
  38. package/dist/core/enforcement.js +271 -0
  39. package/dist/core/legacy-templates.d.ts +24 -0
  40. package/dist/core/legacy-templates.js +60 -0
  41. package/dist/core/lock-manager.d.ts +54 -0
  42. package/dist/core/lock-manager.js +260 -0
  43. package/dist/core/root-resolver.d.ts +32 -0
  44. package/dist/core/root-resolver.js +149 -0
  45. package/dist/core/setup-assets.d.ts +123 -0
  46. package/dist/core/setup-assets.js +438 -0
  47. package/dist/core/telemetry.d.ts +156 -0
  48. package/dist/core/telemetry.js +416 -0
  49. package/dist/core/test-generator-types.d.ts +227 -0
  50. package/dist/core/test-generator-types.js +179 -0
  51. package/dist/core/test-generator.d.ts +34 -0
  52. package/dist/core/test-generator.js +1690 -0
  53. package/dist/core/tier1-liaison.d.ts +139 -0
  54. package/dist/core/tier1-liaison.js +320 -0
  55. package/dist/core/verifier.d.ts +52 -0
  56. package/dist/core/verifier.js +249 -0
  57. package/dist/core/version.d.ts +5 -0
  58. package/dist/core/version.js +14 -0
  59. package/dist/core/worktree-merge.d.ts +30 -0
  60. package/dist/core/worktree-merge.js +98 -0
  61. package/dist/db/data-engine.d.ts +46 -0
  62. package/dist/db/data-engine.js +802 -0
  63. package/dist/db/diff.d.ts +39 -0
  64. package/dist/db/diff.js +420 -0
  65. package/dist/db/env-parser.d.ts +86 -0
  66. package/dist/db/env-parser.js +549 -0
  67. package/dist/db/introspector.d.ts +21 -0
  68. package/dist/db/introspector.js +835 -0
  69. package/dist/db/types.d.ts +217 -0
  70. package/dist/db/types.js +9 -0
  71. package/dist/governor/circuit-breaker.d.ts +100 -0
  72. package/dist/governor/circuit-breaker.js +231 -0
  73. package/dist/governor/evaluator.d.ts +67 -0
  74. package/dist/governor/evaluator.js +851 -0
  75. package/dist/governor/index.d.ts +6 -0
  76. package/dist/governor/index.js +6 -0
  77. package/dist/governor/rules/api-rules.d.ts +2 -0
  78. package/dist/governor/rules/api-rules.js +140 -0
  79. package/dist/governor/rules/db-rules.d.ts +2 -0
  80. package/dist/governor/rules/db-rules.js +180 -0
  81. package/dist/governor/store.d.ts +33 -0
  82. package/dist/governor/store.js +84 -0
  83. package/dist/governor/types.d.ts +64 -0
  84. package/dist/governor/types.js +1 -0
  85. package/dist/index.d.ts +3 -0
  86. package/dist/index.js +358 -0
  87. package/dist/mcp/server.d.ts +3 -0
  88. package/dist/mcp/server.js +309 -0
  89. package/dist/providers/claude-api.d.ts +5 -0
  90. package/dist/providers/claude-api.js +75 -0
  91. package/dist/providers/claude-cli.d.ts +13 -0
  92. package/dist/providers/claude-cli.js +134 -0
  93. package/dist/providers/gemini.d.ts +8 -0
  94. package/dist/providers/gemini.js +78 -0
  95. package/dist/providers/index.d.ts +5 -0
  96. package/dist/providers/index.js +5 -0
  97. package/dist/providers/registry.d.ts +38 -0
  98. package/dist/providers/registry.js +121 -0
  99. package/dist/providers/types.d.ts +74 -0
  100. package/dist/providers/types.js +25 -0
  101. package/dist/runner/agent-supervisor.d.ts +363 -0
  102. package/dist/runner/agent-supervisor.js +1672 -0
  103. package/dist/scanner/context-builder.d.ts +2 -0
  104. package/dist/scanner/context-builder.js +29 -0
  105. package/dist/scanner/detector.d.ts +2 -0
  106. package/dist/scanner/detector.js +760 -0
  107. package/dist/scanner/types.d.ts +80 -0
  108. package/dist/scanner/types.js +50 -0
  109. package/dist/server/studio-server.d.ts +39 -0
  110. package/dist/server/studio-server.js +1931 -0
  111. package/dist/server/studio-ui.d.ts +15 -0
  112. package/dist/server/studio-ui.js +5321 -0
  113. package/package.json +70 -0
  114. package/plugin/.claude-plugin/plugin.json +18 -0
  115. package/plugin/.mcp.json +10 -0
  116. package/plugin/agents/architect.md +28 -0
  117. package/plugin/agents/verifier.md +28 -0
  118. package/plugin/agents/worker.md +26 -0
  119. package/plugin/hooks/hooks.json +28 -0
  120. package/plugin/skills/nativ/SKILL.md +75 -0
  121. package/templates/.claudeignore +45 -0
  122. package/templates/AGENTS.md +67 -0
  123. package/templates/CLAUDE.md +32 -0
  124. package/templates/GEMINI.md +66 -0
  125. package/templates/claude-agents/architect.md +28 -0
  126. package/templates/claude-agents/verifier.md +28 -0
  127. package/templates/claude-agents/worker.md +26 -0
  128. package/templates/dot-ai/api_contracts.json +66 -0
  129. package/templates/dot-ai/context.md +38 -0
  130. package/templates/dot-ai/db_schema.json +39 -0
  131. package/templates/dot-ai/master_plan.json +28 -0
  132. package/templates/dot-ai/subagents/backend.md +11 -0
  133. package/templates/dot-ai/subagents/database.md +10 -0
  134. package/templates/dot-ai/subagents/db-migration.md +11 -0
  135. package/templates/dot-ai/subagents/devops-agent.md +11 -0
  136. package/templates/dot-ai/subagents/flutter-developer.md +11 -0
  137. package/templates/dot-ai/subagents/frontend.md +126 -0
  138. package/templates/dot-ai/subagents/qa-tester.md +13 -0
  139. package/templates/dot-ai/subagents/security-auditor.md +11 -0
  140. 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
+ }
@@ -0,0 +1,3 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function createMcpServer(targetDirArg?: string): McpServer;
3
+ export declare function startMcpServer(targetDirArg?: string): Promise<void>;