@0dai-dev/cli 4.3.6 → 4.3.8
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/README.md +12 -11
- package/bin/0dai.js +133 -33
- package/lib/ai/manifest/mcp-exposure-contract.json +121 -0
- package/lib/ai/meta/manifest/mcp-tool-tiers.json +435 -0
- package/lib/ai/registry/mcp-catalog.json +98 -0
- package/lib/commands/auth.js +2 -1
- package/lib/commands/compliance.js +1 -1
- package/lib/commands/doctor.js +707 -12
- package/lib/commands/experience.js +40 -5
- package/lib/commands/feedback.js +157 -15
- package/lib/commands/gh.js +26 -0
- package/lib/commands/graph.js +9 -4
- package/lib/commands/heatmap.js +1 -1
- package/lib/commands/init.js +298 -27
- package/lib/commands/mcp.js +111 -33
- package/lib/commands/models.js +138 -41
- package/lib/commands/play.js +20 -4
- package/lib/commands/provider.js +30 -59
- package/lib/commands/quota.js +1 -1
- package/lib/commands/receipt.js +1 -1
- package/lib/commands/run.js +14 -6
- package/lib/commands/runner.js +31 -1
- package/lib/commands/status.js +176 -11
- package/lib/commands/swarm.js +130 -12
- package/lib/commands/trust.js +1 -1
- package/lib/commands/update.js +184 -38
- package/lib/commands/usage.js +1 -1
- package/lib/commands/validate.js +32 -3
- package/lib/commands/vault.js +43 -8
- package/lib/python/__init__.py +0 -0
- package/lib/python/agent_quotas.py +525 -0
- package/lib/python/anomaly_alert.py +397 -0
- package/lib/python/anti_pattern_detector.py +799 -0
- package/lib/python/auth.py +443 -0
- package/lib/python/capi_profile_guard.py +477 -0
- package/lib/python/compliance_report.py +581 -0
- package/lib/python/drift_detector.py +388 -0
- package/lib/python/experience_pipeline.py +1130 -0
- package/lib/python/graph.py +19 -0
- package/lib/python/graph_core.py +293 -0
- package/lib/python/graph_io.py +179 -0
- package/lib/python/graph_legacy.py +2052 -0
- package/lib/python/graph_legacy_helpers.py +221 -0
- package/lib/python/graph_outcomes_core.py +85 -0
- package/lib/python/graph_queries.py +171 -0
- package/lib/python/graph_slice.py +198 -0
- package/lib/python/graph_slicer.py +576 -0
- package/lib/python/graph_slicer_cli.py +60 -0
- package/lib/python/graph_validation.py +64 -0
- package/lib/python/heatmap.py +943 -0
- package/lib/python/json_utils.py +193 -0
- package/lib/python/mcp_exposure_check.py +247 -0
- package/lib/python/model_router.py +1434 -0
- package/lib/python/project_manager.py +621 -0
- package/lib/python/provider_profiles.py +1618 -0
- package/lib/python/provider_registry.py +1211 -0
- package/lib/python/provider_registry_cli.py +125 -0
- package/lib/python/receipt_png.py +727 -0
- package/lib/python/structural_memory.py +325 -0
- package/lib/python/swarm_cost.py +177 -0
- package/lib/python/usage_ledger.py +569 -0
- package/lib/scripts/mcp_tier_config.py +240 -0
- package/lib/shared.js +96 -12
- package/lib/tui/index.mjs +35174 -0
- package/lib/utils/activation_telemetry.js +1 -4
- package/lib/utils/constants.js +7 -1
- package/lib/utils/identity.js +184 -0
- package/lib/utils/mcp-auth.js +81 -15
- package/lib/utils/plan.js +1 -1
- package/lib/vault/index.js +19 -3
- package/lib/vault/storage.js +21 -2
- package/lib/wizard.js +5 -2
- package/package.json +9 -3
- package/scripts/build-python-bundle.js +106 -0
- package/scripts/build-tui.js +14 -1
- package/scripts/harvest_experience.py +523 -0
- package/scripts/postinstall.js +15 -9
package/README.md
CHANGED
|
@@ -43,39 +43,36 @@ Daily (regular work):
|
|
|
43
43
|
0dai run <goal> # split a backlog item into agent tasks [--dry-run] [--dry-cost] [--agent claude|codex|gemini]
|
|
44
44
|
0dai swarm status # show queued, active, and done tasks
|
|
45
45
|
0dai swarm add # queue one task [--task '...' --to agent]
|
|
46
|
-
0dai swarm
|
|
46
|
+
0dai swarm pick # pick one queued task [--agent codex]
|
|
47
|
+
0dai swarm-run # repo-checkout helper: add, dispatch, and wait for one swarm task as JSON
|
|
47
48
|
0dai harvest # convert experience events into candidate lessons
|
|
48
49
|
0dai watch # live task monitor [--interval N]
|
|
49
50
|
0dai reflect # session reflection: delivered, delegation, blockers
|
|
50
|
-
0dai standup # morning voice briefing about overnight agent work
|
|
51
|
-
0dai feedback push
|
|
51
|
+
0dai standup # repo-checkout helper: morning voice briefing about overnight agent work
|
|
52
|
+
0dai feedback push --target . # send feedback to 0dai
|
|
52
53
|
0dai feedback retry # retry queued feedback after a failed push
|
|
53
|
-
0dai persona-simulate "topic" # focus-group report and optional issue drafts
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
Pro / advanced:
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
59
|
0dai init-existing # existing-repo setup alias for init
|
|
60
|
-
0dai project bind # bind repository to your 0dai account [--json]
|
|
60
|
+
0dai project bind # bind repository to your 0dai account [--name NAME] [--json]
|
|
61
61
|
0dai project status # local project binding and health [--json]
|
|
62
62
|
0dai graph push # upload local graph (Pro: edges, Free: nodes)
|
|
63
63
|
0dai graph pull # download server graph and merge locally
|
|
64
64
|
0dai graph status # local graph stats and sync state
|
|
65
|
-
0dai ci # portable CI pipelines and AI-MQ [list|plan|mq-status]
|
|
66
65
|
0dai heatmap # repo treemap: LOC × agent-edit intensity
|
|
67
66
|
0dai session save # save session for roaming
|
|
68
|
-
0dai provider #
|
|
67
|
+
0dai provider # provider profiles and local BYOK registry [status|list|switch|clear]
|
|
69
68
|
0dai models # model ratings (--fast/--balanced/--deep/--available)
|
|
70
69
|
0dai quota # agent subscription usage [--refresh] [--json]
|
|
71
70
|
0dai usage # local token, task, and USD ledger [status|daily|monthly]
|
|
72
71
|
0dai workspace # tmux workspace sessions (init|up|status)
|
|
73
|
-
0dai
|
|
74
|
-
0dai report # privacy-safe project reports (preview|push|status)
|
|
72
|
+
0dai report # repo-checkout helper: privacy-safe project reports (preview|push|status)
|
|
75
73
|
0dai compliance # SOC2/ISO evidence and ADR audit-trail export
|
|
76
|
-
0dai experience # structured experience events (list|stats|sync|warnings|dismiss)
|
|
74
|
+
0dai experience # structured experience events (list|stats|record-json|sync|warnings|dismiss)
|
|
77
75
|
0dai receipt # session receipt PNG [--last|--active|--session ID]
|
|
78
|
-
0dai boneyard # weekly digest of worst agent moves [--week YYYY-WW|current]
|
|
79
76
|
0dai gh branch-protection # GitHub branch protection [print|apply|install]
|
|
80
77
|
0dai import claude-code-agents # import .claude/agents/*.md as personas [--dry-run]
|
|
81
78
|
0dai auth logout # remove credentials
|
|
@@ -100,6 +97,10 @@ Global flags: `--target PATH`, `--version`, `--help`, `--json`, `--quiet`. See `
|
|
|
100
97
|
|
|
101
98
|
Your source code is never sent. Only file names and package/build manifests.
|
|
102
99
|
|
|
100
|
+
## Privacy
|
|
101
|
+
|
|
102
|
+
Local activation and experience records stay on your machine: `ai/meta/telemetry/activation.jsonl`, `ai/experience/`, and the generated `ai/` layer/project agent configs are local files. Server-side activation sends one `free_tier_activated` event when you run `0dai activate free` unless telemetry is opted out. See https://0dai.dev/legal/privacy.
|
|
103
|
+
|
|
103
104
|
## Why 0dai, not just Cursor or Copilot?
|
|
104
105
|
|
|
105
106
|
Cursor and Copilot are editors. They help inside one coding session. 0dai writes a project layer that Claude Code, Codex, OpenCode, Gemini, and Aider can all read. The point is not another autocomplete box; it is one manifest, one set of agent roles, one task queue, and one health check for the repo.
|
package/bin/0dai.js
CHANGED
|
@@ -26,7 +26,7 @@ if ((earlyParsed.args[0] || "help") === "swarm-run") {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const shared = require("../lib/shared");
|
|
29
|
-
const { T, R, D, log, VERSION, fs, path, spawnSync, findRepoScript, checkVersion } = shared;
|
|
29
|
+
const { T, R, D, log, VERSION, fs, path, spawnSync, findRepoScript, repoScriptCandidates, checkVersion } = shared;
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Hot-path Go binary fallback (issue #2424).
|
|
@@ -130,7 +130,10 @@ function tryGoHotPath(cmdName, target, argv) {
|
|
|
130
130
|
if (!bin) return false;
|
|
131
131
|
if (!goBinaryCompatible(bin)) return false;
|
|
132
132
|
const forwarded = [cmdName, "--target", target, ...argv];
|
|
133
|
-
const res = spawnSync(bin, forwarded, {
|
|
133
|
+
const res = spawnSync(bin, forwarded, {
|
|
134
|
+
stdio: "inherit",
|
|
135
|
+
env: { ...process.env, ODAI_NODE_PTY_PROBE_DIR: path.join(__dirname, "..") },
|
|
136
|
+
});
|
|
134
137
|
if (res.error) return false;
|
|
135
138
|
if (typeof res.status === "number") process.exit(res.status);
|
|
136
139
|
process.exit(0);
|
|
@@ -157,7 +160,7 @@ const { cmdAudit } = require("../lib/commands/audit");
|
|
|
157
160
|
const { cmdExport } = require("../lib/commands/export");
|
|
158
161
|
const { cmdMcp } = require("../lib/commands/mcp");
|
|
159
162
|
const { cmdVault } = require("../lib/commands/vault");
|
|
160
|
-
const { cmdDoctor } = require("../lib/commands/doctor");
|
|
163
|
+
const { cmdDoctor, collectLayerVersionFreshness } = require("../lib/commands/doctor");
|
|
161
164
|
const { cmdValidate } = require("../lib/commands/validate");
|
|
162
165
|
const { cmdUpdate } = require("../lib/commands/update");
|
|
163
166
|
const { cmdUpgrade } = require("../lib/commands/upgrade");
|
|
@@ -207,7 +210,7 @@ function printHelp() {
|
|
|
207
210
|
console.log("");
|
|
208
211
|
console.log("Start (first 5 minutes):");
|
|
209
212
|
console.log(" init Create ai/ layer + MCP [--local] [--dry-run] [--minimal]");
|
|
210
|
-
console.log(" doctor Check health, credentials, and drift [--drift]");
|
|
213
|
+
console.log(" doctor Check health, credentials, and drift [--drift] [--security]");
|
|
211
214
|
console.log(" status Show maturity, swarm, and session state [--json]");
|
|
212
215
|
console.log(" quickstart Run auth, init, doctor, and status checks in order");
|
|
213
216
|
console.log(" detect Show detected stack");
|
|
@@ -221,40 +224,38 @@ function printHelp() {
|
|
|
221
224
|
console.log(" run <goal> Split a backlog item into agent tasks [--dry-run] [--dry-cost] [--max-cost N] [--agent claude|codex|gemini] [--provider X]");
|
|
222
225
|
console.log(" swarm status Show queued, active, and done tasks");
|
|
223
226
|
console.log(" swarm add Queue one task for an agent [--task '...' --to agent]");
|
|
224
|
-
console.log(" swarm
|
|
227
|
+
console.log(" swarm pick Pick one queued task for this agent [--agent codex]");
|
|
228
|
+
console.log(" swarm-run Repo-checkout helper: add, dispatch, and wait for one swarm task as JSON");
|
|
225
229
|
console.log(" harvest Convert experience events into candidate lessons");
|
|
226
230
|
console.log(" watch Live task monitor: queue, active, recently done [--interval N]");
|
|
227
231
|
console.log(" reflect Session reflection: delivered, delegation rate, blockers");
|
|
228
|
-
console.log(" standup
|
|
232
|
+
console.log(" standup Repo-checkout helper: morning voice briefing about overnight agent work");
|
|
229
233
|
console.log(" feedback push Send feedback to 0dai");
|
|
234
|
+
console.log(" feedback submit Send one feedback report file [--file ai/feedback/codex-report.json]");
|
|
230
235
|
console.log(" feedback retry Retry queued feedback after a failed push");
|
|
231
236
|
console.log("");
|
|
232
237
|
console.log("Pro / advanced:");
|
|
233
238
|
console.log(" init-existing Legacy alias for init (older docs / scripted bootstraps); use 'init' [--minimal] [--dry-run]");
|
|
234
|
-
console.log(" project bind Bind current repository to your 0dai account [--json]");
|
|
239
|
+
console.log(" project bind Bind current repository to your 0dai account [--name NAME] [--json]");
|
|
235
240
|
console.log(" project status Show local project binding and health state [--json]");
|
|
236
241
|
console.log(" graph push Upload local graph to server (Pro: edges, Free: nodes)");
|
|
237
242
|
console.log(" graph pull Download server graph and merge locally");
|
|
238
243
|
console.log(" graph status Show local graph stats and sync state");
|
|
239
|
-
console.log(" ci Plan portable 0dai CI pipelines and inspect AI-MQ [list|plan|mq-status] [--json]");
|
|
240
244
|
console.log(" mcp MCP server, tools, and health [list|catalog|doctor|call] [--json]");
|
|
241
245
|
console.log(" vault Local age-encrypted secrets vault [init|add|get] [--json]");
|
|
242
246
|
console.log(" heatmap Repo treemap: LOC x agent-edit intensity");
|
|
243
247
|
console.log(" session save Save session for roaming");
|
|
244
|
-
console.log(" provider Local provider profiles
|
|
248
|
+
console.log(" provider Local provider profiles and BYOK registry [status|list|switch|clear]");
|
|
245
249
|
console.log(" models Show model ratings (--fast/--balanced/--deep/--available)");
|
|
246
250
|
console.log(" models recommend Ledger-ranked model pick for a task type [--task TYPE] [--goal '...'] [--json]");
|
|
247
251
|
console.log(" quota Agent subscription usage table [--refresh] [--json]");
|
|
248
252
|
console.log(" usage Local token, task, and USD usage ledger [status|daily|monthly]");
|
|
249
253
|
console.log(" workspace Manage tmux workspace sessions (init|up|status)");
|
|
250
|
-
console.log("
|
|
251
|
-
console.log(" report Privacy-safe project reports (preview|push|status)");
|
|
254
|
+
console.log(" report Repo-checkout helper: privacy-safe project reports (preview|push|status)");
|
|
252
255
|
console.log(" trust Pre-run blast-radius: protected paths, authority matrix, egress [--json]");
|
|
253
256
|
console.log(" compliance SOC2/ISO evidence and ADR audit-trail export");
|
|
254
|
-
console.log(" experience Structured experience events (list|stats|sync|warnings|dismiss)");
|
|
255
|
-
console.log(" persona-simulate Produce a focus-group report and optional issue drafts");
|
|
257
|
+
console.log(" experience Structured experience events (list|stats|record-json|sync|warnings|dismiss)");
|
|
256
258
|
console.log(" receipt Render a 1200×630 session receipt PNG [--last|--active|--session ID]");
|
|
257
|
-
console.log(" boneyard Weekly digest of worst agent moves [--week YYYY-WW|current]");
|
|
258
259
|
console.log(" gh branch-protection [print|apply|install] Manage generated GitHub branch protection");
|
|
259
260
|
console.log(" import claude-code-agents Import .claude/agents/*.md as 0dai personas [--source DIR] [--target DIR] [--dry-run]");
|
|
260
261
|
console.log(" auth logout Remove credentials");
|
|
@@ -270,29 +271,106 @@ function printHelp() {
|
|
|
270
271
|
console.log("https://0dai.dev");
|
|
271
272
|
}
|
|
272
273
|
|
|
274
|
+
function explainMissingHarvestHelper(target, args) {
|
|
275
|
+
const candidates = repoScriptCandidates(target, "harvest_experience.py");
|
|
276
|
+
if (args.includes("--json")) {
|
|
277
|
+
console.log(JSON.stringify({
|
|
278
|
+
error: "harvest_helper_unavailable",
|
|
279
|
+
helper: "harvest_experience.py",
|
|
280
|
+
target,
|
|
281
|
+
looked_in: candidates,
|
|
282
|
+
fallback_inputs: [
|
|
283
|
+
"ai/experience/events/*.json",
|
|
284
|
+
"ai/experience/events/*.jsonl",
|
|
285
|
+
"ai/experience/outbox/*.json",
|
|
286
|
+
"ai/experience/outbox/*.jsonl",
|
|
287
|
+
],
|
|
288
|
+
required_fallback_fields: [
|
|
289
|
+
"schema",
|
|
290
|
+
"event_id",
|
|
291
|
+
"timestamp",
|
|
292
|
+
"event_type",
|
|
293
|
+
"tool",
|
|
294
|
+
"task_type",
|
|
295
|
+
"summary",
|
|
296
|
+
"paths",
|
|
297
|
+
"ci_passed",
|
|
298
|
+
"source",
|
|
299
|
+
],
|
|
300
|
+
}, null, 2));
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
log("harvest helper unavailable");
|
|
305
|
+
if (!args.includes("--explain")) return;
|
|
306
|
+
|
|
307
|
+
console.log(` ${D}looked for scripts/harvest_experience.py at:${R}`);
|
|
308
|
+
for (const candidate of candidates) {
|
|
309
|
+
console.log(` - ${candidate}`);
|
|
310
|
+
}
|
|
311
|
+
console.log(` ${D}fallback event inputs:${R}`);
|
|
312
|
+
console.log(" - ai/experience/events/*.json");
|
|
313
|
+
console.log(" - ai/experience/events/*.jsonl");
|
|
314
|
+
console.log(" - ai/experience/outbox/*.json");
|
|
315
|
+
console.log(" - ai/experience/outbox/*.jsonl");
|
|
316
|
+
console.log(` ${D}fallback schema fields:${R}`);
|
|
317
|
+
console.log(" schema, event_id, timestamp, event_type, tool, task_type, summary, paths, ci_passed, source");
|
|
318
|
+
}
|
|
319
|
+
|
|
273
320
|
const SYNC_ALLOWED_FLAGS = new Set([
|
|
321
|
+
"--check",
|
|
274
322
|
"--dry-run",
|
|
275
323
|
"--yes",
|
|
276
324
|
"-y",
|
|
277
325
|
"--quiet",
|
|
278
326
|
"-q",
|
|
279
327
|
"--force",
|
|
328
|
+
"--force-template-reset",
|
|
280
329
|
"--no-diff",
|
|
281
330
|
"--no-mcp-auth",
|
|
282
331
|
"--skip-link-check",
|
|
283
332
|
"--strict-links",
|
|
284
333
|
]);
|
|
285
334
|
|
|
335
|
+
function printInitHelp(commandName = "init") {
|
|
336
|
+
console.log(`\n ${T}0dai ${commandName}${R} — Create or refresh the managed ai/ layer\n`);
|
|
337
|
+
console.log("Usage:");
|
|
338
|
+
console.log(` 0dai ${commandName} [--local] [--minimal] [--dry-run] [--no-wizard] [--auth-code CODE] [--code LICENSE] [--no-mcp-auth] [--mcp-host HOST] [--reset] [--target PATH]`);
|
|
339
|
+
console.log("");
|
|
340
|
+
console.log("Options:");
|
|
341
|
+
console.log(" --local Generate the ai/ layer offline without signing in");
|
|
342
|
+
console.log(" --minimal Generate the smallest starter layer");
|
|
343
|
+
console.log(" --dry-run Preview init changes without writing them");
|
|
344
|
+
console.log(" (pair with --local to preview configs with no account or network)");
|
|
345
|
+
console.log(" --no-wizard Skip the interactive first-run wizard");
|
|
346
|
+
console.log(" --auth-code Exchange a browser/device auth code before init");
|
|
347
|
+
console.log(" --code Redeem an activation/license code before init");
|
|
348
|
+
console.log(" --no-mcp-auth Skip MCP cloud-token bootstrap during init");
|
|
349
|
+
console.log(" --mcp-host Use a custom MCP cloud host");
|
|
350
|
+
console.log(" --reset Overwrite managed MCP entries during bootstrap");
|
|
351
|
+
console.log(" --target PATH Run init against another project path");
|
|
352
|
+
console.log("");
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function handleInitHelp(args) {
|
|
356
|
+
const initArgs = args.slice(1);
|
|
357
|
+
if (!initArgs.includes("--help") && !initArgs.includes("-h")) return false;
|
|
358
|
+
printInitHelp(args[0] || "init");
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
|
|
286
362
|
function printSyncHelp() {
|
|
287
363
|
console.log(`\n ${T}0dai sync${R} — Update the managed ai/ layer\n`);
|
|
288
364
|
console.log("Usage:");
|
|
289
|
-
console.log(" 0dai sync [--dry-run] [--yes|-y] [--quiet|-q] [--force] [--no-diff] [--no-mcp-auth] [--target PATH]");
|
|
365
|
+
console.log(" 0dai sync [--check] [--dry-run] [--yes|-y] [--quiet|-q] [--force] [--force-template-reset] [--no-diff] [--no-mcp-auth] [--target PATH]");
|
|
290
366
|
console.log("");
|
|
291
367
|
console.log("Options:");
|
|
368
|
+
console.log(" --check CI-friendly alias for --dry-run --quiet");
|
|
292
369
|
console.log(" --dry-run Preview managed file changes without writing them");
|
|
293
370
|
console.log(" --yes, -y Apply changes without an interactive confirmation prompt");
|
|
294
371
|
console.log(" --quiet, -q Reduce non-essential output");
|
|
295
372
|
console.log(" --force Also overwrite native config files from managed ai/ sources");
|
|
373
|
+
console.log(" --force-template-reset Allow replacing project-owned roadmap/manifest state");
|
|
296
374
|
console.log(" --no-diff Hide unified diff output in previews/prompts");
|
|
297
375
|
console.log(" --no-mcp-auth Skip MCP cloud-token bootstrap during sync");
|
|
298
376
|
console.log(" --skip-link-check Skip the SPEC-028 doc cross-link scan after sync");
|
|
@@ -318,6 +396,24 @@ function handleSyncHelpOrInvalidArgs(args) {
|
|
|
318
396
|
return false;
|
|
319
397
|
}
|
|
320
398
|
|
|
399
|
+
function printActivateHelp() {
|
|
400
|
+
console.log(`\n ${T}0dai activate${R} — Claim or inspect a 0dai activation\n`);
|
|
401
|
+
console.log("Usage:");
|
|
402
|
+
console.log(" 0dai activate [free|status|code <CODE>] [--target PATH]");
|
|
403
|
+
console.log("");
|
|
404
|
+
console.log("Privacy:");
|
|
405
|
+
console.log(" Local files stay local; 'activate free' sends one free_tier_activated event unless telemetry is opted out.");
|
|
406
|
+
console.log(" https://0dai.dev/legal/privacy");
|
|
407
|
+
console.log("");
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function handleActivateHelp(args) {
|
|
411
|
+
const activateArgs = args.slice(1);
|
|
412
|
+
if (!activateArgs.includes("--help") && !activateArgs.includes("-h")) return false;
|
|
413
|
+
printActivateHelp();
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
|
|
321
417
|
async function main() {
|
|
322
418
|
const { args, target } = parseTargetAndArgs(process.argv.slice(2), process.cwd());
|
|
323
419
|
|
|
@@ -333,8 +429,18 @@ async function main() {
|
|
|
333
429
|
return;
|
|
334
430
|
}
|
|
335
431
|
|
|
336
|
-
|
|
337
|
-
|
|
432
|
+
if ((cmd === "init" || cmd === "init-existing") && handleInitHelp(args)) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (cmd === "activate" && handleActivateHelp(args)) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Non-blocking version check (runs in background, once per day). Skip
|
|
441
|
+
// machine-readable commands so update network I/O never holds JSON output
|
|
442
|
+
// open or pollutes stdout.
|
|
443
|
+
if (!args.includes("--json") && cmd !== "init" && cmd !== "init-existing") checkVersion();
|
|
338
444
|
|
|
339
445
|
// Track first run for time-to-init telemetry
|
|
340
446
|
try { require("../lib/onboarding").trackFirstRun(target); } catch {}
|
|
@@ -359,6 +465,7 @@ async function main() {
|
|
|
359
465
|
case "watch": cmdWatch(target, args.slice(1)); break;
|
|
360
466
|
case "audit": cmdAudit(target); break;
|
|
361
467
|
case "export": await cmdExport(target, args); break;
|
|
468
|
+
case "vault": cmdVault(target, args[1], args.slice(2)); break;
|
|
362
469
|
case "security": {
|
|
363
470
|
const subSec = args[1] || "";
|
|
364
471
|
if (subSec === "install-hook") {
|
|
@@ -397,26 +504,19 @@ async function main() {
|
|
|
397
504
|
case "detect": await cmdDetect(target); break;
|
|
398
505
|
case "doctor": {
|
|
399
506
|
const driftMode = args.includes("--drift");
|
|
507
|
+
const securityMode = args.includes("--security");
|
|
400
508
|
// Go fast-path covers only the base read-only doctor (no --drift, no
|
|
401
|
-
// network). Anything else falls through to the full Node
|
|
402
|
-
|
|
509
|
+
// --security, no network). Anything else falls through to the full Node
|
|
510
|
+
// implementation so the flag is not silently swallowed.
|
|
511
|
+
const layerFreshness = collectLayerVersionFreshness(target);
|
|
512
|
+
if (!driftMode && !securityMode && layerFreshness.status !== "stale") {
|
|
403
513
|
tryGoHotPath("doctor", target, args.slice(1));
|
|
404
514
|
}
|
|
405
|
-
cmdDoctor(target, { drift: driftMode, json: args.includes("--json") });
|
|
406
|
-
if (args.includes("--drift")) {
|
|
407
|
-
const ds = findRepoScript(target, "drift_detector.py");
|
|
408
|
-
console.log("\n drift report:");
|
|
409
|
-
if (ds) {
|
|
410
|
-
const result = spawnSync("python3", [ds, "report", "--target", target], { stdio: "inherit" });
|
|
411
|
-
if (typeof result.status === "number" && result.status !== 0) process.exit(result.status);
|
|
412
|
-
} else {
|
|
413
|
-
console.log(` ${D}drift detector unavailable in this environment${R}`);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
515
|
+
cmdDoctor(target, { drift: driftMode, security: securityMode, json: args.includes("--json") });
|
|
416
516
|
break;
|
|
417
517
|
}
|
|
418
518
|
case "drift": {
|
|
419
|
-
const ds =
|
|
519
|
+
const ds = shared.resolvePythonScript(target, "drift_detector.py");
|
|
420
520
|
if (!ds) { log("drift detector unavailable"); break; }
|
|
421
521
|
if (sub === "accept" && args[2]) {
|
|
422
522
|
spawnSync("python3", [ds, "accept", args[2], "--target", target], { stdio: "inherit" });
|
|
@@ -441,7 +541,7 @@ async function main() {
|
|
|
441
541
|
case "project":
|
|
442
542
|
if (sub === "status") cmdStatus(target, { json: args.includes("--json") });
|
|
443
543
|
else if (sub === "bind") await cmdProjectBind(target, args.slice(2));
|
|
444
|
-
else console.log("Usage: 0dai project [bind [--json]|status [--json]] [--target PATH]");
|
|
544
|
+
else console.log("Usage: 0dai project [bind [--name NAME] [--json]|status [--json]] [--target PATH]");
|
|
445
545
|
break;
|
|
446
546
|
case "auth":
|
|
447
547
|
if (sub === "login") await cmdAuthLogin(args.slice(2));
|
|
@@ -479,7 +579,7 @@ async function main() {
|
|
|
479
579
|
case "feedback": await cmdFeedback(target, sub, args); break;
|
|
480
580
|
case "harvest": {
|
|
481
581
|
const harvestScript = findRepoScript(target, "harvest_experience.py");
|
|
482
|
-
if (!harvestScript) {
|
|
582
|
+
if (!harvestScript) { explainMissingHarvestHelper(target, args); break; }
|
|
483
583
|
const result = spawnSync("python3", [harvestScript, "--target", target, ...args.slice(1)], { stdio: "inherit", timeout: 15000 });
|
|
484
584
|
if (typeof result.status === "number" && result.status !== 0) process.exit(result.status);
|
|
485
585
|
break;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"updated_at": "2026-05-28",
|
|
4
|
+
"purpose": "Expected MCP exposure contract for agent runtimes. Health checks compare observed tool names against this manifest and scripts/mcp_tier_config.py.",
|
|
5
|
+
"project_server": {
|
|
6
|
+
"name": "0dai",
|
|
7
|
+
"config_path": ".mcp.json",
|
|
8
|
+
"tool_count_source": "scripts/mcp_tier_config.py",
|
|
9
|
+
"expected_tool_count": 113
|
|
10
|
+
},
|
|
11
|
+
"normalization": {
|
|
12
|
+
"accepted_examples": [
|
|
13
|
+
"memory_search",
|
|
14
|
+
"mcp__0dai__memory_search",
|
|
15
|
+
"mcp__0dai_internal__.memory_search",
|
|
16
|
+
"mcp__0dai_internal__memory_search"
|
|
17
|
+
],
|
|
18
|
+
"rule": "Compare by canonical tool basename after MCP namespace prefixes."
|
|
19
|
+
},
|
|
20
|
+
"agents": {
|
|
21
|
+
"default": {
|
|
22
|
+
"required": [
|
|
23
|
+
"memory_search",
|
|
24
|
+
"get_project_health",
|
|
25
|
+
"get_codebase_map",
|
|
26
|
+
"record_experience"
|
|
27
|
+
],
|
|
28
|
+
"recommended": [
|
|
29
|
+
"get_anomaly_taxonomy",
|
|
30
|
+
"get_anomaly_events",
|
|
31
|
+
"get_anomaly_summary",
|
|
32
|
+
"memory_add",
|
|
33
|
+
"memory_inject",
|
|
34
|
+
"search_experience",
|
|
35
|
+
"get_project_graph",
|
|
36
|
+
"get_specs",
|
|
37
|
+
"get_session",
|
|
38
|
+
"save_session",
|
|
39
|
+
"get_wal"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"codex": {
|
|
43
|
+
"inherits": "default",
|
|
44
|
+
"required": [
|
|
45
|
+
"memory_search",
|
|
46
|
+
"get_project_health",
|
|
47
|
+
"get_codebase_map",
|
|
48
|
+
"record_experience"
|
|
49
|
+
],
|
|
50
|
+
"recommended": [
|
|
51
|
+
"get_anomaly_taxonomy",
|
|
52
|
+
"get_anomaly_events",
|
|
53
|
+
"get_anomaly_summary",
|
|
54
|
+
"record_anomaly",
|
|
55
|
+
"memory_add",
|
|
56
|
+
"memory_inject",
|
|
57
|
+
"search_experience",
|
|
58
|
+
"get_project_graph",
|
|
59
|
+
"get_specs",
|
|
60
|
+
"get_session",
|
|
61
|
+
"save_session",
|
|
62
|
+
"swarm_delegate",
|
|
63
|
+
"watch_tasks",
|
|
64
|
+
"get_portfolio",
|
|
65
|
+
"get_wal"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"claude": {
|
|
69
|
+
"inherits": "default",
|
|
70
|
+
"required": [
|
|
71
|
+
"memory_search",
|
|
72
|
+
"get_project_health",
|
|
73
|
+
"get_codebase_map",
|
|
74
|
+
"record_experience",
|
|
75
|
+
"get_session",
|
|
76
|
+
"save_session"
|
|
77
|
+
],
|
|
78
|
+
"recommended": [
|
|
79
|
+
"get_anomaly_taxonomy",
|
|
80
|
+
"get_anomaly_events",
|
|
81
|
+
"get_anomaly_summary",
|
|
82
|
+
"record_anomaly",
|
|
83
|
+
"memory_add",
|
|
84
|
+
"memory_inject",
|
|
85
|
+
"search_experience",
|
|
86
|
+
"swarm_delegate",
|
|
87
|
+
"watch_tasks",
|
|
88
|
+
"get_portfolio",
|
|
89
|
+
"gh_label_create",
|
|
90
|
+
"gh_issue_edit_body"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"pool": {
|
|
94
|
+
"inherits": "default",
|
|
95
|
+
"required": [
|
|
96
|
+
"memory_search",
|
|
97
|
+
"get_project_health",
|
|
98
|
+
"get_codebase_map",
|
|
99
|
+
"record_experience",
|
|
100
|
+
"watch_tasks"
|
|
101
|
+
],
|
|
102
|
+
"recommended": [
|
|
103
|
+
"get_anomaly_taxonomy",
|
|
104
|
+
"get_anomaly_events",
|
|
105
|
+
"get_anomaly_summary",
|
|
106
|
+
"memory_add",
|
|
107
|
+
"search_experience",
|
|
108
|
+
"swarm_delegate",
|
|
109
|
+
"run_task",
|
|
110
|
+
"get_swarm_status",
|
|
111
|
+
"save_session"
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"statuses": {
|
|
116
|
+
"green": "All required and recommended tools for the agent were observed.",
|
|
117
|
+
"yellow": "Required tools were observed, but recommended tools or full server count evidence is missing.",
|
|
118
|
+
"red": "One or more required tools are missing from the observed runtime.",
|
|
119
|
+
"unknown": "No observed tool evidence was supplied by the runtime."
|
|
120
|
+
}
|
|
121
|
+
}
|