@moda-ai/cli 1.55.54 → 1.55.55

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 (34) hide show
  1. package/dist/{agent-rmmtap23.js → agent-dc9zkdsm.js} +10 -10
  2. package/dist/{cli-3dj84cbk.js → cli-2jwxdhh5.js} +1 -1
  3. package/dist/{cli-1ehmy9rh.js → cli-31ybq5f2.js} +2 -2
  4. package/dist/{cli-rdh9jjr2.js → cli-94r5x9bg.js} +1 -1
  5. package/dist/{cli-c1k20j6e.js → cli-9a4b1wxz.js} +1 -1
  6. package/dist/{cli-4pzbgxcn.js → cli-9g8kp42c.js} +2 -2
  7. package/dist/{cli-mf37dxpc.js → cli-b918vs2m.js} +4 -4
  8. package/dist/{cli-4vc2cksg.js → cli-eqj302as.js} +5 -5
  9. package/dist/{cli-wry78bg8.js → cli-hawwf30b.js} +1 -1
  10. package/dist/{cli-c1vmgdjb.js → cli-jnwba1f3.js} +8 -8
  11. package/dist/{cli-dxxc7tzq.js → cli-m25c0rke.js} +3 -3
  12. package/dist/{cli-40fqk078.js → cli-pnarsb96.js} +1 -1
  13. package/dist/{cli-7ye5004e.js → cli-px4dmcy0.js} +68 -301
  14. package/dist/{cli-6hdqp65a.js → cli-rtkjjf0a.js} +1255 -66
  15. package/dist/{cli-gtke9wrw.js → cli-v2h21cgf.js} +1 -1
  16. package/dist/{cli-vswckv9g.js → cli-y5d33a1y.js} +1 -1
  17. package/dist/cli.js +20 -20
  18. package/dist/{doctor-b34em2fm.js → doctor-r16n0me8.js} +8 -8
  19. package/dist/{harness-github-actions-rayyxh1w.js → harness-github-actions-6bex338w.js} +8 -8
  20. package/dist/{harness-jcqwf5h6.js → harness-j0n400bv.js} +8 -8
  21. package/dist/{harness-report-rjcjbh93.js → harness-report-gz5d3y48.js} +1 -1
  22. package/dist/{index-cqnp8pfv.js → index-ecy3ntzc.js} +14 -14
  23. package/dist/{production-intelligence-zek0rkzj.js → production-intelligence-fqvhzq6s.js} +4 -4
  24. package/dist/{profile-commands-nbaec4y9.js → profile-commands-yvpe4d8y.js} +5 -5
  25. package/dist/{prompt-attribution-gyx0g661.js → prompt-attribution-x84cgdct.js} +8 -8
  26. package/dist/prompt-source-mcp.js +8 -8
  27. package/dist/{prompt-sources-qw2p4t5h.js → prompt-sources-1hycgx6r.js} +2 -2
  28. package/dist/{prompts-s4y90zs7.js → prompts-r0mv69yx.js} +6 -6
  29. package/dist/{provision-tch8rc3y.js → provision-aqhfbnez.js} +6 -6
  30. package/dist/{registry-tv8fktxc.js → registry-wv1zzyce.js} +4 -4
  31. package/dist/{skills-mwftqzyk.js → skills-etzcqhp8.js} +6 -6
  32. package/dist/{sync-qxf3gkhy.js → sync-p4dz7qmn.js} +10 -10
  33. package/package.json +1 -1
  34. package/skills/integration/index.json +2 -2
@@ -13,16 +13,16 @@ import {
13
13
  import {
14
14
  createCommandContext,
15
15
  stringOption
16
- } from "./cli-gtke9wrw.js";
16
+ } from "./cli-v2h21cgf.js";
17
17
  import {
18
18
  assertFlags,
19
19
  assertPositionals,
20
20
  requireTenant
21
- } from "./cli-1ehmy9rh.js";
21
+ } from "./cli-31ybq5f2.js";
22
22
  import {
23
23
  ApiError,
24
24
  callControlAPI
25
- } from "./cli-wry78bg8.js";
25
+ } from "./cli-hawwf30b.js";
26
26
  import {
27
27
  embeddedTenantIdFromApiKey,
28
28
  getActiveProfile,
@@ -32,7 +32,7 @@ import {
32
32
  resolveModaBaseUrl,
33
33
  resolveTenantId,
34
34
  shellArg
35
- } from "./cli-40fqk078.js";
35
+ } from "./cli-pnarsb96.js";
36
36
  import {
37
37
  PYTHON_AGENT_MODULES,
38
38
  TYPESCRIPT_AGENT_MODULES,
@@ -44,7 +44,7 @@ import {
44
44
  require_typescript,
45
45
  resolvePromptSource,
46
46
  validatePromptSource
47
- } from "./cli-vswckv9g.js";
47
+ } from "./cli-y5d33a1y.js";
48
48
  import {
49
49
  $isMap,
50
50
  $isNode,
@@ -70,7 +70,7 @@ import {
70
70
  packSnapshot,
71
71
  redactDeep,
72
72
  shouldInventoryFile
73
- } from "./cli-c1k20j6e.js";
73
+ } from "./cli-9a4b1wxz.js";
74
74
  import {
75
75
  HARNESS_ANALYZE_CONCERNS,
76
76
  HARNESS_REPORT_PATH,
@@ -83,14 +83,16 @@ import {
83
83
  hashHarnessReport,
84
84
  hashStableJson,
85
85
  loadHarnessReportForSync,
86
+ mergeBoundRuntimeClasses,
86
87
  normalizeHarnessReport,
87
88
  readHarnessReport,
88
89
  requiresArtifactBody,
89
90
  resolveHarnessReportPath,
90
91
  stampRemoteSnapshotTruncation,
92
+ tagComponentStatus,
91
93
  validateHarnessReport,
92
94
  writeHarnessReportArtifacts
93
- } from "./cli-6hdqp65a.js";
95
+ } from "./cli-rtkjjf0a.js";
94
96
  import {
95
97
  CliInputError,
96
98
  CliInputRequiredError
@@ -107,15 +109,15 @@ import { homedir, tmpdir as tmpdir2 } from "node:os";
107
109
  import { fileURLToPath } from "node:url";
108
110
  import {
109
111
  existsSync as existsSync8,
110
- lstatSync as lstatSync8,
112
+ lstatSync as lstatSync7,
111
113
  mkdtempSync as mkdtempSync2,
112
114
  mkdirSync as mkdirSync5,
113
- readFileSync as readFileSync13,
114
- readdirSync as readdirSync5,
115
+ readFileSync as readFileSync12,
116
+ readdirSync as readdirSync4,
115
117
  writeFileSync as writeFileSync5,
116
118
  rmSync as rmSync4
117
119
  } from "node:fs";
118
- import { basename as basename6, delimiter, dirname as dirname7, join as join10, relative as relative7, resolve as resolve10, sep as sep5 } from "node:path";
120
+ import { basename as basename6, delimiter, dirname as dirname7, join as join9, relative as relative6, resolve as resolve10, sep as sep5 } from "node:path";
119
121
  import { confirm, select } from "@inquirer/prompts";
120
122
 
121
123
  // src/analyst-tui.ts
@@ -14528,245 +14530,6 @@ function promoteHarnessCandidates(report, rootDir) {
14528
14530
  return [...byId.values()];
14529
14531
  }
14530
14532
 
14531
- // src/harness-wrangler-bindings.ts
14532
- import { lstatSync as lstatSync7, readdirSync as readdirSync4, readFileSync as readFileSync12 } from "node:fs";
14533
- import { join as join9, relative as relative6 } from "node:path";
14534
- var WRANGLER_FILE = /^wrangler\.jsonc?$/;
14535
- var SKIPPED_DIRS2 = new Set(["node_modules", ".git", ".wrangler", "dist", "build", ".next", ".turbo", "vendor"]);
14536
- var MAX_DEPTH = 4;
14537
- var AGENT_CLASS = /Agent(?:V\d+)?$/;
14538
- function stripJsonc2(text) {
14539
- let out = "";
14540
- let inString = false;
14541
- for (let i = 0;i < text.length; i += 1) {
14542
- const ch = text[i];
14543
- if (inString) {
14544
- out += ch;
14545
- if (ch === "\\") {
14546
- out += text[i + 1] ?? "";
14547
- i += 1;
14548
- } else if (ch === '"') {
14549
- inString = false;
14550
- }
14551
- continue;
14552
- }
14553
- if (ch === '"') {
14554
- inString = true;
14555
- out += ch;
14556
- } else if (ch === "/" && text[i + 1] === "/") {
14557
- while (i < text.length && text[i] !== `
14558
- `)
14559
- i += 1;
14560
- out += `
14561
- `;
14562
- } else if (ch === "/" && text[i + 1] === "*") {
14563
- i += 2;
14564
- while (i < text.length && !(text[i] === "*" && text[i + 1] === "/")) {
14565
- if (text[i] === `
14566
- `)
14567
- out += `
14568
- `;
14569
- i += 1;
14570
- }
14571
- i += 1;
14572
- } else {
14573
- out += ch;
14574
- }
14575
- }
14576
- return out.replace(/,(\s*[}\]])/g, "$1");
14577
- }
14578
- function findWranglerFiles(rootDir) {
14579
- const found = [];
14580
- const walk = (dir, depth) => {
14581
- let entries;
14582
- try {
14583
- entries = readdirSync4(dir);
14584
- } catch {
14585
- return;
14586
- }
14587
- for (const name of entries) {
14588
- const abs = join9(dir, name);
14589
- let stat;
14590
- try {
14591
- stat = lstatSync7(abs);
14592
- } catch {
14593
- continue;
14594
- }
14595
- if (stat.isDirectory()) {
14596
- if (depth < MAX_DEPTH && !SKIPPED_DIRS2.has(name) && !name.startsWith("."))
14597
- walk(abs, depth + 1);
14598
- } else if (stat.isFile() && WRANGLER_FILE.test(name)) {
14599
- found.push(abs);
14600
- }
14601
- }
14602
- };
14603
- walk(rootDir, 0);
14604
- return found.sort();
14605
- }
14606
- function lineOf(text, className) {
14607
- const index = text.search(new RegExp(`"class_name"\\s*:\\s*"${className.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"`));
14608
- return index < 0 ? undefined : text.slice(0, index).split(`
14609
- `).length;
14610
- }
14611
- function workerDir(path) {
14612
- const slash = path.lastIndexOf("/");
14613
- return slash < 0 ? "" : path.slice(0, slash);
14614
- }
14615
- function detectBoundRuntimeClasses(rootDir) {
14616
- const byClass = new Map;
14617
- for (const abs of findWranglerFiles(rootDir)) {
14618
- let text;
14619
- let config2;
14620
- try {
14621
- text = readFileSync12(abs, "utf8");
14622
- config2 = JSON.parse(stripJsonc2(text));
14623
- } catch {
14624
- continue;
14625
- }
14626
- if (!config2 || typeof config2 !== "object")
14627
- continue;
14628
- const path = relative6(rootDir, abs).split("\\").join("/");
14629
- const root = config2;
14630
- const sections2 = [root, ...Object.values(root.env ?? {})];
14631
- for (const section of sections2) {
14632
- if (!section || typeof section !== "object")
14633
- continue;
14634
- const s = section;
14635
- const durable = s.durable_objects?.bindings;
14636
- const entries = [
14637
- ...Array.isArray(durable) ? durable.map((b) => ["durable_object", b]) : [],
14638
- ...Array.isArray(s.workflows) ? s.workflows.map((w) => ["workflow", w]) : []
14639
- ];
14640
- for (const [kind, raw] of entries) {
14641
- if (!raw || typeof raw !== "object")
14642
- continue;
14643
- const entry = raw;
14644
- const className = typeof entry.class_name === "string" ? entry.class_name : "";
14645
- const scriptName = typeof entry.script_name === "string" && entry.script_name ? entry.script_name : undefined;
14646
- const key = `${className}|${scriptName ? "external" : `config:${path}`}`;
14647
- if (!className || byClass.has(key))
14648
- continue;
14649
- const binding = typeof (kind === "workflow" ? entry.binding : entry.name) === "string" ? String(kind === "workflow" ? entry.binding : entry.name) : className;
14650
- byClass.set(key, {
14651
- className,
14652
- kind,
14653
- binding,
14654
- ...scriptName ? { scriptName } : {},
14655
- path,
14656
- line: lineOf(text, className)
14657
- });
14658
- }
14659
- }
14660
- }
14661
- return [...byClass.values()];
14662
- }
14663
- function norm(value) {
14664
- return typeof value === "string" ? value.toLowerCase().replace(/[^a-z0-9]/g, "") : "";
14665
- }
14666
- function itemPaths(item) {
14667
- const paths = [];
14668
- for (const value of [item.root, item.sourcePath]) {
14669
- if (typeof value === "string" && value && value !== ".")
14670
- paths.push(value.replace(/^\.\//, ""));
14671
- }
14672
- for (const entry of Array.isArray(item.evidence) ? item.evidence : []) {
14673
- const path = entry && typeof entry === "object" ? entry.path : undefined;
14674
- if (typeof path === "string" && path)
14675
- paths.push(path.replace(/^\.\//, ""));
14676
- }
14677
- return paths;
14678
- }
14679
- function withinWorker(path, dir, otherDirs) {
14680
- const inside = (d) => d === "" || path === d || path.startsWith(`${d}/`);
14681
- return inside(dir) && !otherDirs.some((other) => other.length > dir.length && inside(other));
14682
- }
14683
- function graphNamesClass(graph, bound, all) {
14684
- const target = norm(bound.className);
14685
- const named = (name) => {
14686
- if (typeof name !== "string")
14687
- return false;
14688
- const bare = name.replace(/\s*\([^)]*\)\s*$/, "");
14689
- return norm(bare) === target || bare.split(/[^A-Za-z0-9_]+/).some((word) => norm(word) === target);
14690
- };
14691
- const sameName = bound.scriptName ? [bound] : all.filter((other) => other.className === bound.className && !other.scriptName);
14692
- const dir = workerDir(bound.path);
14693
- const otherDirs = sameName.map((other) => workerDir(other.path)).filter((other) => other !== dir);
14694
- const covers = (item) => {
14695
- if (!named(item.name))
14696
- return false;
14697
- if (sameName.length < 2)
14698
- return true;
14699
- return itemPaths(item).some((path) => withinWorker(path, dir, otherDirs));
14700
- };
14701
- return graph.runtimeAgents.some(covers) || graph.artifacts.some(covers);
14702
- }
14703
- function bindingReason(bound) {
14704
- const what = bound.kind === "workflow" ? "Workflow" : "Durable Object";
14705
- const where = bound.scriptName ? ` served by the external Worker "${bound.scriptName}"` : "";
14706
- return `${what} binding ${bound.binding} -> class ${bound.className}${where}`;
14707
- }
14708
- function uniqueId(base, taken) {
14709
- let id = base;
14710
- for (let n = 2;taken.has(id); n += 1)
14711
- id = `${base}-${n}`;
14712
- taken.add(id);
14713
- return id;
14714
- }
14715
- function mergeBoundRuntimeClasses(graph, rootDir) {
14716
- if (process.env.MODA_HARNESS_DETERMINISTIC_MERGE === "0")
14717
- return { added: 0 };
14718
- let bound;
14719
- try {
14720
- bound = detectBoundRuntimeClasses(rootDir);
14721
- } catch {
14722
- return { added: 0 };
14723
- }
14724
- const taken = new Set([
14725
- ...graph.runtimeAgents.map((agent) => agent.id),
14726
- ...graph.artifacts.map((artifact) => artifact.id)
14727
- ]);
14728
- let added = 0;
14729
- for (const entry of bound) {
14730
- if (graphNamesClass(graph, entry, bound))
14731
- continue;
14732
- const evidence = [{ path: entry.path, ...entry.line ? { line: entry.line } : {}, reason: bindingReason(entry) }];
14733
- const slug = entry.className.replace(/[^A-Za-z0-9]+/g, "-").toLowerCase();
14734
- if (entry.kind === "durable_object" && AGENT_CLASS.test(entry.className) && !entry.scriptName) {
14735
- const agent = {
14736
- id: uniqueId(`agent.bound.${slug}`, taken),
14737
- name: entry.className,
14738
- kind: "runtime_agent",
14739
- purpose: "Agent class bound as a Durable Object.",
14740
- root: ".",
14741
- entrypointIds: [],
14742
- channelAdapterIds: [],
14743
- artifactIds: [],
14744
- identityNamespaceIds: [],
14745
- deploymentIds: [],
14746
- frameworkIds: [],
14747
- modelProviderIds: [],
14748
- confidence: 0.6,
14749
- evidence
14750
- };
14751
- graph.runtimeAgents.push(agent);
14752
- } else {
14753
- const artifact = {
14754
- id: uniqueId(`entrypoint.bound.${slug}`, taken),
14755
- type: "entrypoint",
14756
- name: entry.className,
14757
- scope: "shared",
14758
- sourcePath: entry.path,
14759
- usedByAgentIds: [],
14760
- confidence: 0.6,
14761
- evidence
14762
- };
14763
- graph.artifacts.push(artifact);
14764
- }
14765
- added += 1;
14766
- }
14767
- return { added };
14768
- }
14769
-
14770
14533
  // src/harness-sync-limits.ts
14771
14534
  var MAX_HARNESS_SYNC_GRAPH_BYTES = 2000000;
14772
14535
  function assertHarnessGraphSyncSize(graph) {
@@ -14785,8 +14548,8 @@ function assertHarnessGraphSyncSize(graph) {
14785
14548
  }
14786
14549
  // src/harness.ts
14787
14550
  var MODA_DIR = ".moda";
14788
- var HARNESS_PATH = join10(MODA_DIR, "harness.json");
14789
- var HARNESS_SUMMARY_PATH = join10(MODA_DIR, "HARNESS.md");
14551
+ var HARNESS_PATH = join9(MODA_DIR, "harness.json");
14552
+ var HARNESS_SUMMARY_PATH = join9(MODA_DIR, "HARNESS.md");
14790
14553
  var SCHEMA_VERSION = "harness.v0.1";
14791
14554
  var REPORT_JSON_BEGIN = "MODA_HARNESS_REPORT_JSON_BEGIN";
14792
14555
  var REPORT_JSON_END = "MODA_HARNESS_REPORT_JSON_END";
@@ -14952,7 +14715,7 @@ async function runHarnessCommand(context) {
14952
14715
  report: {
14953
14716
  reportId: report.reportId,
14954
14717
  reportHash,
14955
- path: normalizePath2(relative7(rootDir, reportPath)) || ".moda/harness-report.json"
14718
+ path: normalizePath2(relative6(rootDir, reportPath)) || ".moda/harness-report.json"
14956
14719
  },
14957
14720
  validation,
14958
14721
  approval: {
@@ -15098,7 +14861,7 @@ async function runHarnessCommand(context) {
15098
14861
  throw new CliInputError("Focused remote prompt analysis is not supported yet.", "Use local --analyst=claude|codex|cursor|local-scan, or drop --concern for a full remote report.");
15099
14862
  }
15100
14863
  if (context.flags["github-actions"] === "true") {
15101
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-rayyxh1w.js");
14864
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-6bex338w.js");
15102
14865
  const result = await runGithubActionsAnalyze(rootDir, {
15103
14866
  writeReport: (report2) => {
15104
14867
  const normalized = normalizeHarnessReport(report2);
@@ -15220,7 +14983,7 @@ async function runHarnessCommand(context) {
15220
14983
  report: {
15221
14984
  reportId: approval.report.reportId,
15222
14985
  reportHash: hashHarnessReport(approval.report),
15223
- path: normalizePath2(relative7(rootDir, reportPath)) || ".moda/harness-report.json"
14986
+ path: normalizePath2(relative6(rootDir, reportPath)) || ".moda/harness-report.json"
15224
14987
  },
15225
14988
  validation: approval.validation,
15226
14989
  approval: approval.approval
@@ -15243,6 +15006,7 @@ async function runHarnessCommand(context) {
15243
15006
  throw new CliInputError("Missing output path for --out.", "Usage: moda harness candidates --promote=<concern|all> --out=<file>");
15244
15007
  }
15245
15008
  const artifacts = deterministicArtifacts(rootDir, promote === "all" ? undefined : promote);
15009
+ tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
15246
15010
  const promoted = { concern: promote, artifacts };
15247
15011
  const promoteWritten = [];
15248
15012
  if (promoteOut && !context.dryRun) {
@@ -15310,7 +15074,7 @@ async function runHarnessCommand(context) {
15310
15074
  return { exitCode: 0 };
15311
15075
  }
15312
15076
  case "status": {
15313
- const manifestPath = join10(rootDir, HARNESS_PATH);
15077
+ const manifestPath = join9(rootDir, HARNESS_PATH);
15314
15078
  const graph = existsSync8(manifestPath) ? readHarnessGraph(manifestPath) : scanHarness({
15315
15079
  rootDir,
15316
15080
  tenantId: tenant?.tenantId,
@@ -15451,10 +15215,10 @@ function emitWrittenArtifacts(context, written, description) {
15451
15215
  }
15452
15216
  }
15453
15217
  async function runPromptConcernAnalysis(context, rootDir, scanPlan, tenant) {
15454
- const manifest = join10(rootDir, ".moda/prompts.yml");
15218
+ const manifest = join9(rootDir, ".moda/prompts.yml");
15455
15219
  let existing = [];
15456
15220
  if (existsSync8(manifest)) {
15457
- const document = $parseDocument(readFileSync13(manifest, "utf8"));
15221
+ const document = $parseDocument(readFileSync12(manifest, "utf8"));
15458
15222
  if (document.errors.length)
15459
15223
  throw new CliInputError("Invalid prompt manifest.", document.errors[0].message);
15460
15224
  existing = document.toJS({ maxAliasCount: 20 })?.sources ?? [];
@@ -15708,7 +15472,7 @@ function readExternalAnalystReport(rootDir, result, adapter, concern) {
15708
15472
  result.stderr
15709
15473
  ].join(`
15710
15474
  `));
15711
- debugHint = `Raw analyst output saved to ${join10(MODA_DIR, "analyst-debug.log")} for debugging.`;
15475
+ debugHint = `Raw analyst output saved to ${join9(MODA_DIR, "analyst-debug.log")} for debugging.`;
15712
15476
  } catch {}
15713
15477
  throw new CliInputError(`Harness analyst ${adapter} did not return a harness report.`, [
15714
15478
  `Expected ${HARNESS_REPORT_PATH} or final JSON between ${REPORT_JSON_BEGIN} and ${REPORT_JSON_END}.`,
@@ -15819,6 +15583,7 @@ function repairExternalAnalystReport(report, rootDir, options = {}) {
15819
15583
  mergeDeterministicArtifacts(normalized.graph, rootDir, { concern: options.concern });
15820
15584
  if (!options.concern || options.concern === "topology")
15821
15585
  mergeBoundRuntimeClasses(normalized.graph, rootDir);
15586
+ tagComponentStatus(normalized.graph, rootDir);
15822
15587
  hydratePromptAndToolBodies(normalized.graph, rootDir);
15823
15588
  const unverified = new Set;
15824
15589
  for (const artifact of normalized.graph.artifacts) {
@@ -16115,7 +15880,7 @@ function repairCitationLines(report, rootDir) {
16115
15880
  continue;
16116
15881
  let text;
16117
15882
  try {
16118
- text = readFileSync13(candidatePath, "utf8");
15883
+ text = readFileSync12(candidatePath, "utf8");
16119
15884
  } catch {
16120
15885
  continue;
16121
15886
  }
@@ -16721,14 +16486,14 @@ function createPromptAnalystIsolation(adapter, rootDir) {
16721
16486
  const serverPath = bundledServer ? bundled : source;
16722
16487
  const command = bundledServer ? process.execPath : resolveBunRuntime();
16723
16488
  const serverArgs = [serverPath, "--root", rootDir];
16724
- const tempPath = mkdtempSync2(join10(tmpdir2(), "moda-prompt-analyst-"));
16489
+ const tempPath = mkdtempSync2(join9(tmpdir2(), "moda-prompt-analyst-"));
16725
16490
  const cleanup = () => {
16726
16491
  try {
16727
16492
  rmSync4(tempPath, { recursive: true, force: true });
16728
16493
  } catch {}
16729
16494
  };
16730
16495
  if (adapter === "claude") {
16731
- const configPath = join10(tempPath, "claude-mcp.json");
16496
+ const configPath = join9(tempPath, "claude-mcp.json");
16732
16497
  writeFileSync5(configPath, JSON.stringify({ mcpServers: { "moda-prompt-source": { command, args: serverArgs } } }));
16733
16498
  return { configPath, cleanup };
16734
16499
  }
@@ -16939,6 +16704,7 @@ function renderExternalHarnessAnalystPrompt(options) {
16939
16704
  "",
16940
16705
  'Use exact field names and numeric confidence values from 0 to 1. Do not write string confidence values like "high". Do not use confidence >= 0.90 unless the claim is direct evidence from the cited line(s).',
16941
16706
  `Name each runtime agent after the class or exported symbol that defines it, adding the role in parentheses when helpful, e.g. "AutonomousPlanWorkflow (weekly planner)"; a Cloudflare Workflow or Durable Object class keeps its class name. Never emit an agent whose class is not defined or exported in this source tree: a binding to another worker's class (e.g. a wrangler script_name binding) is a deployment detail, not an agent of this repo.`,
16707
+ "Include every real harness component in your scope whether or not anything uses it: a tool defined but never registered, a prompt file or prompt literal nothing references, an agent, Workflow, or Durable Object class defined or exported but never bound, an eval or fixture that tests the agent, a model config declared but unused. Never drop a component for being unused, dead, or legacy; Moda tags its deployment status separately. A class defined here that nothing binds or instantiates is an `entrypoint` artifact, not a runtime agent.",
16942
16708
  'A `tool` artifact is one tool definition. Never emit a group of tools ("MCP server tools", "composio_*", "worker tools") as a tool; record a dynamic tool source (MCP servers, Composio, webhooks) as a graph unknown that cites where the tools are loaded.',
16943
16709
  "Ignore any checked-in .moda/ directory: it is the output of an earlier Moda run and is often stale. Never cite it or reuse its entities.",
16944
16710
  'Every graph item with confidence below 0.85 must also carry confidenceReason: one sentence naming what held confidence down, e.g. "Inferred from AGENTS.md:231-232 only; no source file defines this agent." or "Entrypoint read, but the tool registry was outside the snapshot."',
@@ -17144,10 +16910,10 @@ function readDirectoryPreflightPaths(rootDir) {
17144
16910
  const stack = ["."];
17145
16911
  while (stack.length > 0 && paths.length < 2000) {
17146
16912
  const current = stack.pop() ?? ".";
17147
- const absolute = current === "." ? rootDir : join10(rootDir, current);
16913
+ const absolute = current === "." ? rootDir : join9(rootDir, current);
17148
16914
  let entries;
17149
16915
  try {
17150
- entries = readdirSync5(absolute);
16916
+ entries = readdirSync4(absolute);
17151
16917
  } catch {
17152
16918
  continue;
17153
16919
  }
@@ -17155,10 +16921,10 @@ function readDirectoryPreflightPaths(rootDir) {
17155
16921
  const child = current === "." ? entry : `${current}/${entry}`;
17156
16922
  if (shouldSkipPreflightPath(child))
17157
16923
  continue;
17158
- const childAbsolute = join10(rootDir, child);
16924
+ const childAbsolute = join9(rootDir, child);
17159
16925
  let stat;
17160
16926
  try {
17161
- stat = lstatSync8(childAbsolute);
16927
+ stat = lstatSync7(childAbsolute);
17162
16928
  } catch {
17163
16929
  continue;
17164
16930
  }
@@ -17220,7 +16986,7 @@ function findOnPath(command) {
17220
16986
  if (command.includes("/") && existsSync8(command))
17221
16987
  return command;
17222
16988
  for (const dir of (process.env.PATH ?? "").split(delimiter).filter(Boolean)) {
17223
- const candidate = join10(dir, command);
16989
+ const candidate = join9(dir, command);
17224
16990
  if (existsSync8(candidate))
17225
16991
  return candidate;
17226
16992
  }
@@ -17274,6 +17040,7 @@ function scanHarness(options = {}) {
17274
17040
  linkFrameworksAndProviders(graph);
17275
17041
  finalizeGraph(graph);
17276
17042
  hydratePromptAndToolBodies(graph, rootDir);
17043
+ tagComponentStatus(graph, rootDir);
17277
17044
  enrichScanCaptureMetadata(graph);
17278
17045
  return graph;
17279
17046
  }
@@ -17298,10 +17065,10 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
17298
17065
  let inventoryFileCount = 0;
17299
17066
  let inventoryTextBytes = 0;
17300
17067
  function walk(current) {
17301
- const path = normalizePath2(relative7(rootDir, current)) || ".";
17068
+ const path = normalizePath2(relative6(rootDir, current)) || ".";
17302
17069
  let stat;
17303
17070
  try {
17304
- stat = lstatSync8(current);
17071
+ stat = lstatSync7(current);
17305
17072
  } catch {
17306
17073
  return;
17307
17074
  }
@@ -17312,8 +17079,8 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
17312
17079
  if (stat.isDirectory()) {
17313
17080
  if (path !== "." && (isSkippedDir(path) || isSkippedPathPrefix(path)))
17314
17081
  return;
17315
- for (const entry of readdirSync5(current).sort())
17316
- walk(join10(current, entry));
17082
+ for (const entry of readdirSync4(current).sort())
17083
+ walk(join9(current, entry));
17317
17084
  return;
17318
17085
  }
17319
17086
  if (!stat.isFile())
@@ -17336,7 +17103,7 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
17336
17103
  let text = "";
17337
17104
  if (isTextFile(path)) {
17338
17105
  try {
17339
- text = readFileSync13(current, "utf8");
17106
+ text = readFileSync12(current, "utf8");
17340
17107
  inventoryTextBytes += Buffer.byteLength(text, "utf8");
17341
17108
  } catch {
17342
17109
  return;
@@ -17355,7 +17122,7 @@ function buildSourceSnapshot(rootDir) {
17355
17122
  const inputs = collectSnapshotInputs(root, maxFiles, maxTextBytes);
17356
17123
  const repo = detectRepo(root, inputs.map((input) => ({
17357
17124
  path: input.path,
17358
- absPath: join10(root, input.path),
17125
+ absPath: join9(root, input.path),
17359
17126
  rootDir: root,
17360
17127
  text: input.text
17361
17128
  })));
@@ -17369,7 +17136,7 @@ function buildSourceSnapshot(rootDir) {
17369
17136
  }
17370
17137
  function buildCommandScanPlan(context, rootDir) {
17371
17138
  const explicitPath = context.flags.path !== undefined;
17372
- const rel2 = normalizePath2(relative7(context.cwd, rootDir)) || ".";
17139
+ const rel2 = normalizePath2(relative6(context.cwd, rootDir)) || ".";
17373
17140
  const scope = explicitPath && rel2 !== "." ? "narrow" : "broad";
17374
17141
  const machineReadable = context.outputMode !== "human";
17375
17142
  const approvalRequired = context.positional === "analyze" && scope === "broad" && !context.yes;
@@ -17454,7 +17221,7 @@ function writeHumanBlock(context, message) {
17454
17221
  function buildHarnessReadPlan(rootDir, pathWasExplicit) {
17455
17222
  return {
17456
17223
  scope: pathWasExplicit ? "narrow" : "broad",
17457
- rootPaths: [normalizePath2(relative7(rootDir, rootDir)) || "."],
17224
+ rootPaths: [normalizePath2(relative6(rootDir, rootDir)) || "."],
17458
17225
  willRead: [
17459
17226
  "package manifests",
17460
17227
  "source files under the selected path",
@@ -17572,7 +17339,7 @@ async function syncHarnessWithRemote(context, body) {
17572
17339
  }, profileOptions);
17573
17340
  }
17574
17341
  function writeHarnessSyncState(rootDir, state) {
17575
- const path = join10(rootDir, SYNC_STATE_PATH);
17342
+ const path = join9(rootDir, SYNC_STATE_PATH);
17576
17343
  mkdirSync5(dirname7(path), { recursive: true });
17577
17344
  writeFileSync5(path, `${JSON.stringify(state, null, 2)}
17578
17345
  `);
@@ -17586,7 +17353,7 @@ function selectedRuntimeAgentId(flags) {
17586
17353
  return;
17587
17354
  }
17588
17355
  function loadOrScanHarness(rootDir, tenant, context) {
17589
- const manifestPath = join10(rootDir, HARNESS_PATH);
17356
+ const manifestPath = join9(rootDir, HARNESS_PATH);
17590
17357
  if (existsSync8(manifestPath))
17591
17358
  return readHarnessGraph(manifestPath);
17592
17359
  if (context) {
@@ -17643,7 +17410,7 @@ var FRESHER_REPORT_MAX_DIRS = 4000;
17643
17410
  function findFresherHarnessReports(rootDir) {
17644
17411
  let rootMtimeMs = 0;
17645
17412
  try {
17646
- rootMtimeMs = lstatSync8(join10(rootDir, HARNESS_REPORT_PATH)).mtimeMs;
17413
+ rootMtimeMs = lstatSync7(join9(rootDir, HARNESS_REPORT_PATH)).mtimeMs;
17647
17414
  } catch {
17648
17415
  rootMtimeMs = 0;
17649
17416
  }
@@ -17655,19 +17422,19 @@ function findFresherHarnessReports(rootDir) {
17655
17422
  visited += 1;
17656
17423
  let entries;
17657
17424
  try {
17658
- entries = readdirSync5(dir, { withFileTypes: true });
17425
+ entries = readdirSync4(dir, { withFileTypes: true });
17659
17426
  } catch {
17660
17427
  return;
17661
17428
  }
17662
17429
  for (const entry of entries) {
17663
17430
  if (!entry.isDirectory() || entry.name.startsWith(".") || SKIPPED_DIRS.has(entry.name))
17664
17431
  continue;
17665
- const child = join10(dir, entry.name);
17432
+ const child = join9(dir, entry.name);
17666
17433
  try {
17667
- const candidate = lstatSync8(join10(child, HARNESS_REPORT_PATH));
17434
+ const candidate = lstatSync7(join9(child, HARNESS_REPORT_PATH));
17668
17435
  if (candidate.isFile() && candidate.mtimeMs > rootMtimeMs) {
17669
17436
  fresher.push({
17670
- path: normalizePath2(relative7(rootDir, join10(child, HARNESS_REPORT_PATH))),
17437
+ path: normalizePath2(relative6(rootDir, join9(child, HARNESS_REPORT_PATH))),
17671
17438
  mtimeMs: candidate.mtimeMs
17672
17439
  });
17673
17440
  }
@@ -17679,7 +17446,7 @@ function findFresherHarnessReports(rootDir) {
17679
17446
  return fresher.sort((a, b) => b.mtimeMs - a.mtimeMs);
17680
17447
  }
17681
17448
  function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
17682
- const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath2(relative7(rootDir, resolve10(rootDir, explicitReport))) : undefined;
17449
+ const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath2(relative6(rootDir, resolve10(rootDir, explicitReport))) : undefined;
17683
17450
  if (explicitReportPath && explicitReportPath !== normalizePath2(HARNESS_REPORT_PATH))
17684
17451
  return;
17685
17452
  let fresher;
@@ -17692,16 +17459,16 @@ function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
17692
17459
  return;
17693
17460
  const newest = fresher[0];
17694
17461
  const subdir = normalizePath2(dirname7(dirname7(newest.path)));
17695
- const rootState = existsSync8(join10(rootDir, HARNESS_REPORT_PATH)) ? `older ${HARNESS_REPORT_PATH}` : `no ${HARNESS_REPORT_PATH}`;
17462
+ const rootState = existsSync8(join9(rootDir, HARNESS_REPORT_PATH)) ? `older ${HARNESS_REPORT_PATH}` : `no ${HARNESS_REPORT_PATH}`;
17696
17463
  writeHarnessNotice(context, `A fresher harness report exists at ${newest.path} (this directory has ${rootState}). If you meant that report, re-run with --path=${subdir}.`);
17697
17464
  }
17698
17465
  function readHarnessGraph(manifestPath) {
17699
- return JSON.parse(readFileSync13(manifestPath, "utf8"));
17466
+ return JSON.parse(readFileSync12(manifestPath, "utf8"));
17700
17467
  }
17701
17468
  function writeHarnessArtifacts(graph, rootDir, options = {}) {
17702
- const modaDir = join10(rootDir, MODA_DIR);
17469
+ const modaDir = join9(rootDir, MODA_DIR);
17703
17470
  mkdirSync5(modaDir, { recursive: true });
17704
- const manifestPath = join10(rootDir, HARNESS_PATH);
17471
+ const manifestPath = join9(rootDir, HARNESS_PATH);
17705
17472
  writeFileSync5(manifestPath, `${JSON.stringify(graph, null, 2)}
17706
17473
  `);
17707
17474
  const written = [HARNESS_PATH];
@@ -17711,7 +17478,7 @@ function writeHarnessArtifacts(graph, rootDir, options = {}) {
17711
17478
  return written;
17712
17479
  }
17713
17480
  function writeHarnessSummary(graph, rootDir) {
17714
- const summaryPath = join10(rootDir, HARNESS_SUMMARY_PATH);
17481
+ const summaryPath = join9(rootDir, HARNESS_SUMMARY_PATH);
17715
17482
  mkdirSync5(dirname7(summaryPath), { recursive: true });
17716
17483
  writeFileSync5(summaryPath, renderHarnessMarkdown(graph));
17717
17484
  return HARNESS_SUMMARY_PATH;
@@ -17886,10 +17653,10 @@ function inventoryFiles(rootDir, skipped, options = {}) {
17886
17653
  const maxTextBytes = numericEnv("MODA_HARNESS_MAX_TEXT_BYTES", DEFAULT_MAX_INVENTORY_TEXT_BYTES);
17887
17654
  let textBytes = 0;
17888
17655
  function walk(current) {
17889
- const rel2 = normalizePath2(relative7(rootReal, current)) || ".";
17656
+ const rel2 = normalizePath2(relative6(rootReal, current)) || ".";
17890
17657
  let stat;
17891
17658
  try {
17892
- stat = lstatSync8(current);
17659
+ stat = lstatSync7(current);
17893
17660
  } catch {
17894
17661
  recordSkipped(skipped, { path: rel2, reason: "stat failed" });
17895
17662
  return;
@@ -17903,8 +17670,8 @@ function inventoryFiles(rootDir, skipped, options = {}) {
17903
17670
  recordSkipped(skipped, { path: rel2, reason: "ignored directory" });
17904
17671
  return;
17905
17672
  }
17906
- for (const entry of readdirSync5(current).sort()) {
17907
- walk(join10(current, entry));
17673
+ for (const entry of readdirSync4(current).sort()) {
17674
+ walk(join9(current, entry));
17908
17675
  }
17909
17676
  return;
17910
17677
  }
@@ -17935,7 +17702,7 @@ function inventoryFiles(rootDir, skipped, options = {}) {
17935
17702
  recordSkipped(skipped, { path: rel2, reason: "scan text budget exceeded" });
17936
17703
  } else {
17937
17704
  try {
17938
- item.text = readFileSync13(current, "utf8");
17705
+ item.text = readFileSync12(current, "utf8");
17939
17706
  textBytes += Buffer.byteLength(item.text, "utf8");
17940
17707
  } catch {
17941
17708
  recordSkipped(skipped, { path: rel2, reason: "text read failed" });
@@ -18242,7 +18009,7 @@ function maybeAddPromptArtifact(graph, file) {
18242
18009
  if (!isPrompt)
18243
18010
  return;
18244
18011
  const id = stableId("prompt", file.path);
18245
- const text = file.text ?? readFileSync13(file.absPath, "utf8");
18012
+ const text = file.text ?? readFileSync12(file.absPath, "utf8");
18246
18013
  upsertArtifact(graph, {
18247
18014
  id,
18248
18015
  type: "prompt",
@@ -18820,10 +18587,10 @@ function computeDeterministicFloor(rootDir) {
18820
18587
  }
18821
18588
  function detectProviderPackagesInManifests(rootDir) {
18822
18589
  const present = new Set;
18823
- const packageJsonPath = join10(rootDir, "package.json");
18590
+ const packageJsonPath = join9(rootDir, "package.json");
18824
18591
  if (existsSync8(packageJsonPath)) {
18825
18592
  try {
18826
- const deps = packageDependencyNames(readFileSync13(packageJsonPath, "utf8"));
18593
+ const deps = packageDependencyNames(readFileSync12(packageJsonPath, "utf8"));
18827
18594
  for (const provider of PROVIDER_CATALOG) {
18828
18595
  for (const name of provider.packageNames) {
18829
18596
  if (deps.has(name))
@@ -18832,10 +18599,10 @@ function detectProviderPackagesInManifests(rootDir) {
18832
18599
  }
18833
18600
  } catch {}
18834
18601
  }
18835
- const pyprojectPath = join10(rootDir, "pyproject.toml");
18602
+ const pyprojectPath = join9(rootDir, "pyproject.toml");
18836
18603
  if (existsSync8(pyprojectPath)) {
18837
18604
  try {
18838
- const deps = pyprojectDependencyNames(readFileSync13(pyprojectPath, "utf8"));
18605
+ const deps = pyprojectDependencyNames(readFileSync12(pyprojectPath, "utf8"));
18839
18606
  for (const provider of PROVIDER_CATALOG) {
18840
18607
  for (const name of provider.packageNames) {
18841
18608
  if (deps.has(name.toLowerCase()))
@@ -19237,12 +19004,12 @@ function contentHashForAnnotatedSource(sourcePath, annotation) {
19237
19004
  function readSmallTextFileForHash(absPath, rootDir) {
19238
19005
  if (!existsSync8(absPath))
19239
19006
  return;
19240
- const rel2 = normalizePath2(relative7(rootDir, absPath));
19007
+ const rel2 = normalizePath2(relative6(rootDir, absPath));
19241
19008
  if (isSecretishPath(rel2))
19242
19009
  return;
19243
19010
  let stat;
19244
19011
  try {
19245
- stat = lstatSync8(absPath);
19012
+ stat = lstatSync7(absPath);
19246
19013
  } catch {
19247
19014
  return;
19248
19015
  }
@@ -19252,7 +19019,7 @@ function readSmallTextFileForHash(absPath, rootDir) {
19252
19019
  if (!isTextFile(rel2))
19253
19020
  return;
19254
19021
  try {
19255
- return readFileSync13(absPath, "utf8");
19022
+ return readFileSync12(absPath, "utf8");
19256
19023
  } catch {
19257
19024
  return;
19258
19025
  }