@moda-ai/cli 1.31.1 → 1.31.3
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 +10 -0
- package/dist/{cli-p3271yp2.js → cli-76tsfpta.js} +2 -3
- package/dist/{cli-j3rr0nh7.js → cli-aeggte1q.js} +3 -146
- package/dist/cli.js +5 -5
- package/dist/{harness-github-actions-kbw4z7q4.js → harness-github-actions-89sn0hqd.js} +1 -1
- package/dist/{index-4enh6fq6.js → index-kx1t9k2w.js} +2 -2
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
package/README.md
CHANGED
|
@@ -32,6 +32,16 @@ export MODA_API_KEY="moda_sk_..."
|
|
|
32
32
|
|
|
33
33
|
Get your API key from [moda.dev/settings](https://moda.dev/settings).
|
|
34
34
|
|
|
35
|
+
## Diagnostics
|
|
36
|
+
|
|
37
|
+
`moda doctor --online` checks configuration and cloud data flow. Experimental
|
|
38
|
+
harness report citations, approval, and report sync do not affect normal doctor
|
|
39
|
+
or status health; use the explicit harness commands to validate those reports.
|
|
40
|
+
The legacy `status.harnessReport` JSON field is retained as `skipped`. Source
|
|
41
|
+
folder presence is not evidence of SDK initialization, so doctor does not warn
|
|
42
|
+
about instrumentation solely because a `src` or `app` directory exists. Verify
|
|
43
|
+
your integration with a fresh application conversation and `moda audit`.
|
|
44
|
+
|
|
35
45
|
## Usage
|
|
36
46
|
|
|
37
47
|
Find things by meaning, then drill in:
|
|
@@ -3040,7 +3040,6 @@ function renderStatusHuman(status, options = {}) {
|
|
|
3040
3040
|
lines.push(` Data flow ${ui.status(status.dataFlow)}`);
|
|
3041
3041
|
lines.push(` Harness ${ui.status(status.harness)}`);
|
|
3042
3042
|
lines.push(` Harness sync ${ui.status(status.harnessSync)}`);
|
|
3043
|
-
lines.push(` Harness report ${ui.status(status.harnessReport)}`);
|
|
3044
3043
|
lines.push(` Shadow Spark ${ui.status(status.shadowSpark)}`);
|
|
3045
3044
|
lines.push(` Prompts ${ui.status(status.prompts)}`);
|
|
3046
3045
|
lines.push(` Skills ${ui.status(status.skills)}`);
|
|
@@ -3546,7 +3545,7 @@ async function runHarnessCommand(context) {
|
|
|
3546
3545
|
elapsed_ms: Date.now() - context.startedAt
|
|
3547
3546
|
});
|
|
3548
3547
|
if (context.flags["github-actions"] === "true") {
|
|
3549
|
-
const { runGithubActionsAnalyze } = await import("./harness-github-actions-
|
|
3548
|
+
const { runGithubActionsAnalyze } = await import("./harness-github-actions-89sn0hqd.js");
|
|
3550
3549
|
const result = await runGithubActionsAnalyze(rootDir, {
|
|
3551
3550
|
writeReport: (report2) => {
|
|
3552
3551
|
const normalized = normalizeHarnessReport(report2);
|
|
@@ -7786,4 +7785,4 @@ async function remoteAnalyzeFetch(url, apiKey, init, timeoutMs) {
|
|
|
7786
7785
|
return response.json();
|
|
7787
7786
|
}
|
|
7788
7787
|
|
|
7789
|
-
export { ApiError, callDataAPI, callControlAPI, getApiRequestCount, resetApiRequestCount, shouldColorTerminalOutput, terminalStyles, stripAnsi, renderMarkdownForTerminal,
|
|
7788
|
+
export { ApiError, callDataAPI, callControlAPI, getApiRequestCount, resetApiRequestCount, shouldColorTerminalOutput, terminalStyles, stripAnsi, renderMarkdownForTerminal, HARNESS_REPORT_PATH, HARNESS_REPORT_APPROVAL_PATH, validateHarnessReport, readHarnessReport, hashHarnessReport, hashStableJson, startRemoteAnalyze, pollRemoteAnalyzeUntilDone, renderDoctorHuman, renderStatusHuman, renderInitBanner, renderInitStep, renderInitNote, renderInitSetupPlan, renderInitComplete, runHarnessCommand, describeCodingAgentEvent, isDeterministicLocalAnalyst, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, scanHarness, summarizeHarness, buildSourceSnapshot, readHarnessSyncState, describeSyncIdentity, describeSyncTenantLabel, graphForSync };
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
HARNESS_REPORT_APPROVAL_PATH,
|
|
3
|
-
HARNESS_REPORT_APPROVAL_SCHEMA_VERSION,
|
|
4
|
-
HARNESS_REPORT_PATH,
|
|
5
2
|
callControlAPI,
|
|
6
3
|
callDataAPI,
|
|
7
|
-
hashHarnessReport,
|
|
8
|
-
readHarnessReport,
|
|
9
4
|
readHarnessSyncState,
|
|
10
5
|
renderDoctorHuman,
|
|
11
6
|
renderStatusHuman,
|
|
12
|
-
scanHarness
|
|
13
|
-
|
|
14
|
-
} from "./cli-p3271yp2.js";
|
|
7
|
+
scanHarness
|
|
8
|
+
} from "./cli-76tsfpta.js";
|
|
15
9
|
import {
|
|
16
10
|
isAuthSessionValid,
|
|
17
11
|
loadAuthSession
|
|
@@ -2141,7 +2135,7 @@ async function runStatusCommand(context) {
|
|
|
2141
2135
|
dataFlow: checkStatus(report.checks, "cloud_data_flow"),
|
|
2142
2136
|
harness: checkStatus(report.checks, "harness_manifest_current"),
|
|
2143
2137
|
harnessSync: checkStatus(report.checks, "harness_sync_state_present"),
|
|
2144
|
-
harnessReport:
|
|
2138
|
+
harnessReport: "skipped",
|
|
2145
2139
|
shadowSpark: checkStatus(report.checks, "shadow_spark_workspace_health"),
|
|
2146
2140
|
prompts: checkStatus(report.checks, "prompts_discovered"),
|
|
2147
2141
|
skills: checkStatus(report.checks, "skills_discovered"),
|
|
@@ -2241,7 +2235,6 @@ async function buildDoctorReport(context, options) {
|
|
|
2241
2235
|
});
|
|
2242
2236
|
checks.push(harnessCurrentCheck(context.cwd, manifestPath, manifestExists, tenantId));
|
|
2243
2237
|
checks.push(harnessSyncStateCheck(context.cwd));
|
|
2244
|
-
checks.push(harnessReportStateCheck(context.cwd));
|
|
2245
2238
|
checks.push(discoveryCheck("prompts_discovered", "harness", "Prompts are discovered", context.cwd, [
|
|
2246
2239
|
"prompts",
|
|
2247
2240
|
".moda/prompts.yml"
|
|
@@ -2256,7 +2249,6 @@ async function buildDoctorReport(context, options) {
|
|
|
2256
2249
|
"tests",
|
|
2257
2250
|
"__tests__"
|
|
2258
2251
|
]));
|
|
2259
|
-
checks.push(sdkInitializationCheck(context.cwd));
|
|
2260
2252
|
checks.push(validationEventPathCheck(ingestUrl));
|
|
2261
2253
|
if (options.offline || !apiKey) {
|
|
2262
2254
|
checks.push(...offlineCloudChecks(options.offline));
|
|
@@ -2516,118 +2508,6 @@ function harnessSyncStateCheck(cwd) {
|
|
|
2516
2508
|
]
|
|
2517
2509
|
};
|
|
2518
2510
|
}
|
|
2519
|
-
function harnessReportStateCheck(cwd) {
|
|
2520
|
-
const reportPath = join8(cwd, HARNESS_REPORT_PATH);
|
|
2521
|
-
if (!existsSync8(reportPath)) {
|
|
2522
|
-
return {
|
|
2523
|
-
id: "harness_report_approved_synced",
|
|
2524
|
-
group: "harness",
|
|
2525
|
-
title: "Harness analyst report is approved and synced",
|
|
2526
|
-
status: "warning",
|
|
2527
|
-
severity: "warning",
|
|
2528
|
-
evidence: [{ label: "path", value: HARNESS_REPORT_PATH }],
|
|
2529
|
-
remediation: "Run a Moda Analyst pass so the harness graph has cited evidence before cloud sync.",
|
|
2530
|
-
nextCommand: "moda harness analyze --experimental --summary"
|
|
2531
|
-
};
|
|
2532
|
-
}
|
|
2533
|
-
try {
|
|
2534
|
-
const report = readHarnessReport(reportPath);
|
|
2535
|
-
const validation = validateHarnessReport(report, cwd);
|
|
2536
|
-
const reportHash = hashHarnessReport(report);
|
|
2537
|
-
const evidence = [
|
|
2538
|
-
{ label: "path", value: HARNESS_REPORT_PATH },
|
|
2539
|
-
{ label: "report_hash", value: reportHash.slice(0, 12) },
|
|
2540
|
-
{ label: "validation", value: validation.status }
|
|
2541
|
-
];
|
|
2542
|
-
if (validation.status !== "pass") {
|
|
2543
|
-
return {
|
|
2544
|
-
id: "harness_report_approved_synced",
|
|
2545
|
-
group: "harness",
|
|
2546
|
-
title: "Harness analyst report is approved and synced",
|
|
2547
|
-
status: "fail",
|
|
2548
|
-
severity: "critical",
|
|
2549
|
-
evidence: [
|
|
2550
|
-
...evidence,
|
|
2551
|
-
{ label: "errors", value: validation.errors.slice(0, 3).join(" | ") || "validation failed" }
|
|
2552
|
-
],
|
|
2553
|
-
remediation: "Regenerate or fix the harness report before approving or syncing.",
|
|
2554
|
-
nextCommand: "moda harness analyze --experimental --summary"
|
|
2555
|
-
};
|
|
2556
|
-
}
|
|
2557
|
-
const approval = readHarnessReportApproval(cwd);
|
|
2558
|
-
const approved = approval?.schemaVersion === HARNESS_REPORT_APPROVAL_SCHEMA_VERSION && approval.reportId === report.reportId && approval.reportHash === reportHash && approval.approved === true;
|
|
2559
|
-
evidence.push({ label: "approval", value: approved ? "approved" : approval ? "stale_or_invalid" : "missing" });
|
|
2560
|
-
if (approval && !approved) {
|
|
2561
|
-
return {
|
|
2562
|
-
id: "harness_report_approved_synced",
|
|
2563
|
-
group: "harness",
|
|
2564
|
-
title: "Harness analyst report is approved and synced",
|
|
2565
|
-
status: "fail",
|
|
2566
|
-
severity: "critical",
|
|
2567
|
-
evidence,
|
|
2568
|
-
remediation: "Approval no longer matches the current report. Review and approve the report again.",
|
|
2569
|
-
nextCommand: "moda harness approve --yes"
|
|
2570
|
-
};
|
|
2571
|
-
}
|
|
2572
|
-
if (!approved) {
|
|
2573
|
-
return {
|
|
2574
|
-
id: "harness_report_approved_synced",
|
|
2575
|
-
group: "harness",
|
|
2576
|
-
title: "Harness analyst report is approved and synced",
|
|
2577
|
-
status: "warning",
|
|
2578
|
-
severity: "warning",
|
|
2579
|
-
evidence,
|
|
2580
|
-
remediation: "Review and approve the validated harness report before syncing.",
|
|
2581
|
-
nextCommand: "moda harness approve --yes"
|
|
2582
|
-
};
|
|
2583
|
-
}
|
|
2584
|
-
const state = readHarnessSyncState(cwd);
|
|
2585
|
-
const synced = state?.source === "approved_report" && state.report?.reportHash === reportHash;
|
|
2586
|
-
evidence.push({ label: "sync", value: synced ? "synced" : "not_synced_to_this_report" }, ...state?.report?.reportHash ? [{ label: "sync_report_hash", value: state.report.reportHash.slice(0, 12) }] : []);
|
|
2587
|
-
return {
|
|
2588
|
-
id: "harness_report_approved_synced",
|
|
2589
|
-
group: "harness",
|
|
2590
|
-
title: "Harness analyst report is approved and synced",
|
|
2591
|
-
status: synced ? "pass" : "warning",
|
|
2592
|
-
severity: synced ? "info" : "warning",
|
|
2593
|
-
evidence,
|
|
2594
|
-
remediation: synced ? undefined : "Sync the approved harness report so Moda cloud has the same harness graph.",
|
|
2595
|
-
nextCommand: synced ? undefined : "moda harness sync --from-report .moda/harness-report.json"
|
|
2596
|
-
};
|
|
2597
|
-
} catch (err) {
|
|
2598
|
-
return {
|
|
2599
|
-
id: "harness_report_approved_synced",
|
|
2600
|
-
group: "harness",
|
|
2601
|
-
title: "Harness analyst report is approved and synced",
|
|
2602
|
-
status: "fail",
|
|
2603
|
-
severity: "critical",
|
|
2604
|
-
evidence: [
|
|
2605
|
-
{ label: "path", value: HARNESS_REPORT_PATH },
|
|
2606
|
-
{ label: "error", value: err instanceof Error ? err.message : String(err) }
|
|
2607
|
-
],
|
|
2608
|
-
remediation: "Regenerate the harness report.",
|
|
2609
|
-
nextCommand: "moda harness analyze --experimental --summary"
|
|
2610
|
-
};
|
|
2611
|
-
}
|
|
2612
|
-
}
|
|
2613
|
-
function readHarnessReportApproval(cwd) {
|
|
2614
|
-
const approvalPath = join8(cwd, HARNESS_REPORT_APPROVAL_PATH);
|
|
2615
|
-
if (!existsSync8(approvalPath))
|
|
2616
|
-
return null;
|
|
2617
|
-
try {
|
|
2618
|
-
return JSON.parse(readFileSync6(approvalPath, "utf8"));
|
|
2619
|
-
} catch {
|
|
2620
|
-
return {
|
|
2621
|
-
schemaVersion: HARNESS_REPORT_APPROVAL_SCHEMA_VERSION,
|
|
2622
|
-
reportId: "unreadable",
|
|
2623
|
-
reportHash: "unreadable",
|
|
2624
|
-
approved: true,
|
|
2625
|
-
approvedAt: "",
|
|
2626
|
-
approvedBy: "local-human",
|
|
2627
|
-
reportPath: HARNESS_REPORT_PATH
|
|
2628
|
-
};
|
|
2629
|
-
}
|
|
2630
|
-
}
|
|
2631
2511
|
function discoveryCheck(id, group, title, cwd, relativePaths, nextCommand) {
|
|
2632
2512
|
const found = relativePaths.filter((path) => existsSync8(join8(cwd, path)));
|
|
2633
2513
|
return {
|
|
@@ -2641,29 +2521,6 @@ function discoveryCheck(id, group, title, cwd, relativePaths, nextCommand) {
|
|
|
2641
2521
|
nextCommand: found.length > 0 ? undefined : nextCommand
|
|
2642
2522
|
};
|
|
2643
2523
|
}
|
|
2644
|
-
function sdkInitializationCheck(cwd) {
|
|
2645
|
-
const candidates = ["src", "app", "agent_harness"];
|
|
2646
|
-
let detected = false;
|
|
2647
|
-
for (const candidate of candidates) {
|
|
2648
|
-
const path = join8(cwd, candidate);
|
|
2649
|
-
if (!existsSync8(path))
|
|
2650
|
-
continue;
|
|
2651
|
-
try {
|
|
2652
|
-
const stat = statSync(path);
|
|
2653
|
-
detected ||= stat.isDirectory() || stat.isFile();
|
|
2654
|
-
} catch {}
|
|
2655
|
-
}
|
|
2656
|
-
return {
|
|
2657
|
-
id: "sdk_initialization_detected",
|
|
2658
|
-
group: "harness",
|
|
2659
|
-
title: "SDK initialization is detectable",
|
|
2660
|
-
status: detected ? "warning" : "skipped",
|
|
2661
|
-
severity: "warning",
|
|
2662
|
-
evidence: [{ label: "status", value: detected ? "code present, instrumentation not verified" : "no source candidates" }],
|
|
2663
|
-
remediation: "Use the generated integration guide to add Moda SDK instrumentation.",
|
|
2664
|
-
nextCommand: "moda init"
|
|
2665
|
-
};
|
|
2666
|
-
}
|
|
2667
2524
|
function validationEventPathCheck(ingestUrl) {
|
|
2668
2525
|
return {
|
|
2669
2526
|
id: "validation_event_path_defined",
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
runPromptsCommand,
|
|
9
9
|
runSkillsCommand,
|
|
10
10
|
runStatusCommand
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-aeggte1q.js";
|
|
12
12
|
import {
|
|
13
13
|
ApiError,
|
|
14
14
|
HARNESS_REPORT_APPROVAL_PATH,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
summarizeHarness,
|
|
30
30
|
terminalStyles,
|
|
31
31
|
validateHarnessReport
|
|
32
|
-
} from "./cli-
|
|
32
|
+
} from "./cli-76tsfpta.js";
|
|
33
33
|
import {
|
|
34
34
|
authFetch,
|
|
35
35
|
clearAuthSession,
|
|
@@ -5597,7 +5597,7 @@ Examples:
|
|
|
5597
5597
|
moda --agent doctor
|
|
5598
5598
|
moda agent context
|
|
5599
5599
|
moda agent next-action
|
|
5600
|
-
moda agent evidence doctor:
|
|
5600
|
+
moda agent evidence doctor:api_key_resolves
|
|
5601
5601
|
moda investigate
|
|
5602
5602
|
moda failures
|
|
5603
5603
|
moda ask "what should I fix first?"
|
|
@@ -6579,7 +6579,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6579
6579
|
resetApiRequestCountBeforeRun: true,
|
|
6580
6580
|
telemetry: "result",
|
|
6581
6581
|
handler: async (context) => {
|
|
6582
|
-
const { runInit } = await import("./index-
|
|
6582
|
+
const { runInit } = await import("./index-kx1t9k2w.js");
|
|
6583
6583
|
if (context.outputMode === "agent-stream") {
|
|
6584
6584
|
context.output.writeEvent({
|
|
6585
6585
|
event: "started",
|
|
@@ -6822,7 +6822,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6822
6822
|
"moda agent context",
|
|
6823
6823
|
"moda agent investigate",
|
|
6824
6824
|
"moda agent next-action",
|
|
6825
|
-
"moda agent evidence doctor:
|
|
6825
|
+
"moda agent evidence doctor:api_key_resolves"
|
|
6826
6826
|
],
|
|
6827
6827
|
auth: "none",
|
|
6828
6828
|
outputModes: ["agent", "agent-stream", "json"],
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
runPromptSync,
|
|
11
11
|
runSkillSync,
|
|
12
12
|
upsertSkillManifestRecord
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-aeggte1q.js";
|
|
14
14
|
import {
|
|
15
15
|
codingAgentDisplayName,
|
|
16
16
|
describeCodingAgentEvent,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
runHarnessCommand,
|
|
29
29
|
startRemoteAnalyze,
|
|
30
30
|
stripAnsi
|
|
31
|
-
} from "./cli-
|
|
31
|
+
} from "./cli-76tsfpta.js";
|
|
32
32
|
import {
|
|
33
33
|
selectTenantAndCreateKey
|
|
34
34
|
} from "./cli-pq6rte0w.js";
|
package/package.json
CHANGED