@moda-ai/cli 1.30.0 → 1.30.2

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.
@@ -11,7 +11,7 @@ import {
11
11
  renderStatusHuman,
12
12
  scanHarness,
13
13
  validateHarnessReport
14
- } from "./cli-5e0rd8mf.js";
14
+ } from "./cli-ts6nhn51.js";
15
15
  import {
16
16
  isAuthSessionValid,
17
17
  loadAuthSession
@@ -284,6 +284,7 @@ var HARNESS_REPORT_PATH = join(".moda", "harness-report.json");
284
284
  var HARNESS_REPORT_MARKDOWN_PATH = join(".moda", "HARNESS_REPORT.md");
285
285
  var HARNESS_REPORT_VALIDATION_PATH = join(".moda", "harness-report-validation.json");
286
286
  var HARNESS_REPORT_APPROVAL_PATH = join(".moda", "harness-report-approval.json");
287
+ var HARNESS_ANALYZE_CONCERNS = ["topology", "tools", "prompts", "evals"];
287
288
  var HARNESS_GRAPH_ARRAY_FIELDS = [
288
289
  "agentFamilies",
289
290
  "runtimeAgents",
@@ -713,7 +714,7 @@ function validateHarnessReport(report, rootDir, options) {
713
714
  }
714
715
  }
715
716
  }
716
- validateDeterministicFloor(report, options?.deterministicFloor, check, warn);
717
+ validateDeterministicFloor(report, options?.deterministicFloor, check, warn, options?.concern);
717
718
  return {
718
719
  schemaVersion: HARNESS_REPORT_VALIDATION_SCHEMA_VERSION,
719
720
  reportId: report?.reportId ?? "unknown",
@@ -725,24 +726,26 @@ function validateHarnessReport(report, rootDir, options) {
725
726
  warnings
726
727
  };
727
728
  }
728
- function validateDeterministicFloor(report, floor, check, warn) {
729
+ function validateDeterministicFloor(report, floor, check, warn, concern) {
729
730
  if (!floor)
730
731
  return;
731
732
  if (process.env.MODA_HARNESS_FLOOR_CHECK === "0")
732
733
  return;
734
+ const applyToolFloor = concern === undefined || concern === "tools";
735
+ const applyTopologyFloors = concern === undefined || concern === "topology";
733
736
  const graph = isRecord(report?.graph) ? report.graph : {};
734
737
  const toolArtifactCount = Array.isArray(graph.artifacts) ? graph.artifacts.filter((artifact) => isRecord(artifact) && artifact.type === "tool").length : 0;
735
738
  const providerCount = safeArrayLength(graph.modelProviders);
736
739
  const runtimeAgentCount = safeArrayLength(graph.runtimeAgents);
737
- if (typeof floor.toolCandidates === "number" && floor.toolCandidates >= 5) {
740
+ if (applyToolFloor && typeof floor.toolCandidates === "number" && floor.toolCandidates >= 5) {
738
741
  const minimumTools = Math.ceil(0.5 * floor.toolCandidates);
739
742
  check("floor_tools", toolArtifactCount >= minimumTools, `Deterministic scan found ${floor.toolCandidates} high-confidence tool definition candidate(s); the report graph must include at least ${minimumTools} tool artifact(s) but has ${toolArtifactCount}.`);
740
743
  }
741
744
  const providerPackages = Array.isArray(floor.providerPackages) ? floor.providerPackages.filter((name) => typeof name === "string" && name.length > 0) : [];
742
- if (providerPackages.length > 0) {
745
+ if (applyTopologyFloors && providerPackages.length > 0) {
743
746
  check("floor_providers", providerCount > 0, `Manifest dependencies include model-provider package(s) ${providerPackages.join(", ")}, but the report graph.modelProviders is empty.`);
744
747
  }
745
- if (typeof floor.llmCallSites === "number" && floor.llmCallSites > 0 && runtimeAgentCount === 0) {
748
+ if (applyTopologyFloors && typeof floor.llmCallSites === "number" && floor.llmCallSites > 0 && runtimeAgentCount === 0) {
746
749
  warn("floor_agents", `Deterministic scan found ${floor.llmCallSites} LLM call site(s) but the report graph.runtimeAgents is empty; sync will be blocked by the zero-agent gate.`);
747
750
  }
748
751
  }
@@ -2973,7 +2976,6 @@ function assertHarnessGraphSyncSize(graph) {
2973
2976
  `));
2974
2977
  }
2975
2978
  }
2976
-
2977
2979
  // src/tui.ts
2978
2980
  var STATUS_LABELS = {
2979
2981
  pass: "ok",
@@ -3524,6 +3526,13 @@ async function runHarnessCommand(context) {
3524
3526
  writeHumanProgress(context, "moda harness analyze is disabled: connect the Moda GitHub App (Settings → Integrations) for automatic analysis, or pass --experimental to run the CLI analyze.");
3525
3527
  return { exitCode: 1 };
3526
3528
  }
3529
+ const concern = resolveHarnessAnalyzeConcern(context.flags, context.env);
3530
+ if (concern) {
3531
+ const unsupported = context.flags["github-actions"] === "true" ? "--github-actions" : isRemoteHarnessAnalyze(context) ? "hosted (--remote) analysis" : await resolveHarnessAnalystAdapter(context) === "local-scan" ? "--analyst=local-scan" : "";
3532
+ if (unsupported) {
3533
+ throw new CliInputError(`--concern=${concern} is not supported by ${unsupported}.`, "Concern scoping narrows the analyst prompt and gates deterministic seeds, promotion, and floors, which only the local coding-agent analyst does today. Drop --concern, or run with --analyst=claude|codex|cursor.");
3534
+ }
3535
+ }
3527
3536
  await approveScanIfNeeded(scanPlan, {
3528
3537
  context,
3529
3538
  message: "Run Moda Analyst to investigate this project and produce a cited harness report?",
@@ -3537,7 +3546,7 @@ async function runHarnessCommand(context) {
3537
3546
  elapsed_ms: Date.now() - context.startedAt
3538
3547
  });
3539
3548
  if (context.flags["github-actions"] === "true") {
3540
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-dmy8fz54.js");
3549
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-ze17s10y.js");
3541
3550
  const result = await runGithubActionsAnalyze(rootDir, {
3542
3551
  writeReport: (report2) => {
3543
3552
  const normalized = normalizeHarnessReport(report2);
@@ -3565,7 +3574,8 @@ async function runHarnessCommand(context) {
3565
3574
  rootDir,
3566
3575
  scanPlan,
3567
3576
  tenant,
3568
- adapter: analyst
3577
+ adapter: analyst,
3578
+ concern
3569
3579
  });
3570
3580
  }
3571
3581
  context.output.writeEvent({
@@ -3838,7 +3848,8 @@ async function runExternalHarnessAnalyst(options) {
3838
3848
  const prompt = renderExternalHarnessAnalystPrompt({
3839
3849
  adapter: options.adapter,
3840
3850
  rootDir: options.rootDir,
3841
- tenantId: options.tenant?.tenantId
3851
+ tenantId: options.tenant?.tenantId,
3852
+ concern: options.concern
3842
3853
  });
3843
3854
  const streamAnalystProgress = options.context.outputMode === "agent-stream";
3844
3855
  const invocation = resolveExternalHarnessAnalystInvocation({
@@ -3897,12 +3908,15 @@ async function runExternalHarnessAnalyst(options) {
3897
3908
  },
3898
3909
  onAgentEvent: streamAnalystProgress ? (event) => {
3899
3910
  const progress = analystEventProgress(event);
3900
- if (!progress)
3911
+ if (!progress && !event.usage)
3901
3912
  return;
3902
3913
  options.context.output.writeEvent({
3903
3914
  event: "progress",
3904
- phase: progress.phase,
3905
- message: progress.message,
3915
+ phase: progress?.phase ?? "analyst_usage",
3916
+ message: progress?.message ?? "analyst usage update",
3917
+ ...event.usage ? { usage: event.usage } : {},
3918
+ ...event.model ? { model: event.model } : {},
3919
+ ...event.durationMs !== undefined ? { duration_ms: event.durationMs } : {},
3906
3920
  elapsed_ms: Date.now() - options.context.startedAt
3907
3921
  });
3908
3922
  } : undefined
@@ -3921,7 +3935,7 @@ async function runExternalHarnessAnalyst(options) {
3921
3935
  ${result.stderr}`, 1200);
3922
3936
  throw new CliInputError(`Harness analyst ${options.adapter} exited with status ${result.status ?? "unknown"}.`, output || "Rerun with the selected coding agent CLI fixed, or choose another analyst with `--analyst=claude|codex|cursor`.");
3923
3937
  }
3924
- const report = readExternalAnalystReport(options.rootDir, result, options.adapter);
3938
+ const report = readExternalAnalystReport(options.rootDir, result, options.adapter, options.concern);
3925
3939
  analystTui?.setSummary({
3926
3940
  runtimeAgentCount: report.graph.runtimeAgents.length,
3927
3941
  agentFamilyCount: report.graph.agentFamilies.length,
@@ -3940,7 +3954,8 @@ ${result.stderr}`, 1200);
3940
3954
  });
3941
3955
  analystTui?.setValidation("running");
3942
3956
  const validation = validateHarnessReport(report, options.rootDir, {
3943
- deterministicFloor: computeDeterministicFloor(options.rootDir)
3957
+ deterministicFloor: computeDeterministicFloor(options.rootDir),
3958
+ concern: options.concern
3944
3959
  });
3945
3960
  analystTui?.setValidation(validation.status === "pass" ? "pass" : "fail");
3946
3961
  if (!analystTui)
@@ -3990,10 +4005,10 @@ function buildExternalAnalystEnv(env) {
3990
4005
  }
3991
4006
  return next;
3992
4007
  }
3993
- function readExternalAnalystReport(rootDir, result, adapter) {
4008
+ function readExternalAnalystReport(rootDir, result, adapter, concern) {
3994
4009
  const reportPath = resolve5(rootDir, HARNESS_REPORT_PATH);
3995
4010
  if (existsSync3(reportPath))
3996
- return repairExternalAnalystReport(readHarnessReport(reportPath), rootDir);
4011
+ return repairExternalAnalystReport(readHarnessReport(reportPath), rootDir, { concern });
3997
4012
  const output = [
3998
4013
  result.stdout,
3999
4014
  result.stderr,
@@ -4001,7 +4016,7 @@ function readExternalAnalystReport(rootDir, result, adapter) {
4001
4016
  extractAgentTextFromOutput(result.stderr)
4002
4017
  ].filter(Boolean).join(`
4003
4018
  `);
4004
- const parsed = extractHarnessReportFromText(output, rootDir);
4019
+ const parsed = extractHarnessReportFromText(output, rootDir, concern);
4005
4020
  if (parsed)
4006
4021
  return parsed;
4007
4022
  let debugHint = "";
@@ -4025,11 +4040,11 @@ function readExternalAnalystReport(rootDir, result, adapter) {
4025
4040
  ].filter(Boolean).join(`
4026
4041
  `));
4027
4042
  }
4028
- function extractHarnessReportFromText(output, rootDir) {
4043
+ function extractHarnessReportFromText(output, rootDir, concern) {
4029
4044
  for (const candidate of reportJsonCandidates(output)) {
4030
4045
  const parsed = parseHarnessReportCandidate(candidate);
4031
4046
  if (parsed)
4032
- return repairExternalAnalystReport(parsed, rootDir);
4047
+ return repairExternalAnalystReport(parsed, rootDir, { concern });
4033
4048
  }
4034
4049
  return;
4035
4050
  }
@@ -4063,13 +4078,32 @@ function parseHarnessReportCandidate(candidate) {
4063
4078
  }
4064
4079
  return;
4065
4080
  }
4066
- function repairExternalAnalystReport(report, rootDir) {
4081
+ function repairExternalAnalystReport(report, rootDir, options = {}) {
4067
4082
  const normalized = normalizeHarnessReport(report);
4068
4083
  repairCitationLines(normalized, rootDir);
4069
- mergeDeterministicArtifacts(normalized.graph, rootDir);
4084
+ mergeDeterministicArtifacts(normalized.graph, rootDir, { concern: options.concern });
4070
4085
  hydratePromptAndToolBodies(normalized.graph, rootDir);
4071
4086
  deriveRelationshipsFromGraph(normalized.graph);
4072
4087
  repairReportSummaryCounts(normalized);
4088
+ if (options.concern) {
4089
+ normalized.source = {
4090
+ ...normalized.source ?? {
4091
+ graphSchemaVersion: normalized.graph?.schemaVersion ?? SCHEMA_VERSION,
4092
+ graphHash: "",
4093
+ readPlan: normalized.graph?.scan?.readPlan ?? {
4094
+ scope: "broad",
4095
+ rootPaths: ["."],
4096
+ willRead: [],
4097
+ willSkip: [],
4098
+ skipsSecretFiles: true,
4099
+ followsSymlinks: false,
4100
+ uploadsSourceByDefault: false
4101
+ },
4102
+ deterministicInventory: false
4103
+ },
4104
+ concern: options.concern
4105
+ };
4106
+ }
4073
4107
  if (normalized.source?.graphHash) {
4074
4108
  normalized.source.graphHash = hashStableJson(graphForReport(normalized.graph));
4075
4109
  }
@@ -4111,9 +4145,18 @@ function deriveRelationshipsFromGraph(graph) {
4111
4145
  }
4112
4146
  return { added };
4113
4147
  }
4114
- function mergeDeterministicArtifacts(graph, rootDir) {
4148
+ var CONCERN_PROMOTED_ARTIFACT_TYPES = {
4149
+ topology: new Set,
4150
+ tools: new Set(["tool"]),
4151
+ prompts: new Set(["prompt"]),
4152
+ evals: new Set(["model_config"])
4153
+ };
4154
+ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
4115
4155
  if (process.env.MODA_HARNESS_DETERMINISTIC_MERGE === "0")
4116
4156
  return { added: 0 };
4157
+ if (options.concern === "topology")
4158
+ return { added: 0 };
4159
+ const allowedTypes = options.concern ? CONCERN_PROMOTED_ARTIFACT_TYPES[options.concern] : undefined;
4117
4160
  let promoted;
4118
4161
  try {
4119
4162
  promoted = promoteHarnessCandidates(detectHarnessCandidates(rootDir), rootDir);
@@ -4122,6 +4165,8 @@ function mergeDeterministicArtifacts(graph, rootDir) {
4122
4165
  }
4123
4166
  let added = 0;
4124
4167
  for (const artifact of promoted) {
4168
+ if (allowedTypes && !allowedTypes.has(artifact.type))
4169
+ continue;
4125
4170
  if (graphCoversPromotedArtifact(graph, artifact))
4126
4171
  continue;
4127
4172
  graph.artifacts.push(artifact);
@@ -4442,6 +4487,8 @@ function recordExternalAgentEventLine(line, options) {
4442
4487
  options.onAgentEvent?.(event);
4443
4488
  if (!options.inheritedOutput)
4444
4489
  return;
4490
+ if (event.telemetryOnly)
4491
+ return;
4445
4492
  options.tui?.recordEvent(event);
4446
4493
  if (options.tui)
4447
4494
  return;
@@ -4466,7 +4513,35 @@ function formatExternalAgentDisplayEvent(event, adapter) {
4466
4513
  return ` ${analystDisplayName(adapter)}: ${event.message}
4467
4514
  `;
4468
4515
  }
4516
+ function extractAgentEventTelemetry(event) {
4517
+ const message = isRecord3(event.message) ? event.message : undefined;
4518
+ const usage = isRecord3(event.usage) ? event.usage : isRecord3(message?.usage) ? message.usage : undefined;
4519
+ const modelUsage = isRecord3(event.modelUsage) ? event.modelUsage : undefined;
4520
+ const model = stringValue(event.model) ?? stringValue(message?.model) ?? (modelUsage ? Object.keys(modelUsage)[0] : undefined);
4521
+ const durationValue = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
4522
+ const durationMs = durationValue(event.duration_ms) ?? durationValue(event.durationMs) ?? durationValue(event.duration_api_ms);
4523
+ if (!usage && !model && durationMs === undefined)
4524
+ return;
4525
+ return {
4526
+ ...usage ? { usage } : {},
4527
+ ...model ? { model } : {},
4528
+ ...durationMs !== undefined ? { durationMs } : {}
4529
+ };
4530
+ }
4469
4531
  function parseExternalAgentEvent(event) {
4532
+ const body = parseExternalAgentEventBody(event);
4533
+ if (!isRecord3(event))
4534
+ return body;
4535
+ const telemetry = extractAgentEventTelemetry(event);
4536
+ if (!telemetry)
4537
+ return body;
4538
+ if (body)
4539
+ return { ...body, ...telemetry };
4540
+ if (!telemetry.usage)
4541
+ return;
4542
+ return { kind: "system", message: "usage update", telemetryOnly: true, ...telemetry };
4543
+ }
4544
+ function parseExternalAgentEventBody(event) {
4470
4545
  if (!isRecord3(event))
4471
4546
  return { kind: "agent_text", message: truncateText(String(event), 500) };
4472
4547
  const msg = isRecord3(event.msg) ? event.msg : undefined;
@@ -4628,6 +4703,17 @@ function isDeterministicLocalAnalyst(raw) {
4628
4703
  const value = raw?.trim().toLowerCase();
4629
4704
  return value === "local-scan" || value === "local" || value === "scripted" || value === "moda";
4630
4705
  }
4706
+ function resolveHarnessAnalyzeConcern(flags, env = process.env) {
4707
+ const flagValue = flags.concern && flags.concern !== "true" ? flags.concern : undefined;
4708
+ const raw = flagValue ?? env.MODA_HARNESS_CONCERN;
4709
+ const value = raw?.trim().toLowerCase();
4710
+ if (!value)
4711
+ return;
4712
+ if (HARNESS_ANALYZE_CONCERNS.includes(value)) {
4713
+ return value;
4714
+ }
4715
+ throw new CliInputError(`Unknown harness analyze concern '${raw}'. Valid concerns: ${HARNESS_ANALYZE_CONCERNS.join("|")}.`, `Use --concern=${HARNESS_ANALYZE_CONCERNS.join("|")} (or MODA_HARNESS_CONCERN; the flag wins).`);
4716
+ }
4631
4717
  function normalizeAnalystAdapter(raw) {
4632
4718
  const value = (raw && raw !== "true" ? raw : "auto").trim().toLowerCase();
4633
4719
  if (value === "auto")
@@ -4765,9 +4851,100 @@ function resolveAnalystModel(adapter, flags) {
4765
4851
  return raw;
4766
4852
  return adapter === "claude" ? DEFAULT_CLAUDE_ANALYST_MODEL : undefined;
4767
4853
  }
4854
+ var CONCERN_AGENT_STUB_LINE = 'Runtime agents may be represented ONLY as bare low-confidence stubs when linkage needs a target: id, name, kind:"runtime_agent", root, confidence, evidence — nothing more. Do not investigate agent topology beyond that; the topology concern pass owns it.';
4855
+ var CONCERN_LOCATION_PIN_LINE = "Every artifact you author MUST pin an exact source location so downstream optimization can retrieve the item text: carry a numeric `line` on at least one evidence entry (evidence: [{ path, line, reason }]) at the definition line. The only exception is an artifact whose entire dedicated file is the text — set its sourcePath and cite that file, no line required. When a single file holds multiple inline definitions, give each artifact its own distinct line.";
4856
+ var CONCERN_NO_TRANSCRIPTION_LINE = "Do NOT transcribe prompt/tool text into `body` when it exists verbatim in the repo — pin its exact location instead and Moda hydrates `body` locally after validation. Set `body` inline ONLY for content that cannot be recovered from one pinned location (e.g. fragments assembled at runtime). Redact any secret literals.";
4857
+ var CONCERN_CAPS_LINE = "- Keep going until every in-concern item is represented as an artifact. Respect the hard caps (<=250 claims, <=400 citations): artifacts are uncapped, so keep enumerating them as artifacts and reserve claims/citations for the most important ones.";
4858
+ var CONCERN_PROMPT_SPECS = {
4859
+ topology: {
4860
+ mission: "Your single concern for this pass is TOPOLOGY: the agents and the infrastructure they run on. Other concern passes exhaustively enumerate tools, prompts, and evals — you must not.",
4861
+ taskLines: [
4862
+ "1. Map the harness topology: runtime agents, agent families, channel adapters, identity namespaces, environments, agent frameworks, model providers, deployments, the relationships among them, and open questions.",
4863
+ "2. Do NOT exhaustively enumerate tools, prompts, guardrails, or evals as artifacts — separate concern passes produce those inventories. Keep graph.artifacts minimal: entrypoint artifacts only, plus agent artifactIds references you discover naturally along the way."
4864
+ ],
4865
+ protocolLines: [
4866
+ "- Focus EXCLUSIVELY on topology: runtime agents, agent families, channel adapters, identity namespaces, environments, agent frameworks, model providers, deployments, and how they relate.",
4867
+ "- Do NOT enumerate tools, prompts, guardrails, or evals as artifacts. Keep graph.artifacts minimal: entrypoints only.",
4868
+ "- For every runtime agent, read and cite at least one concrete entrypoint or orchestration line, and populate every linkage field (entrypointIds, channelAdapterIds, identityNamespaceIds, deploymentIds, frameworkIds, modelProviderIds).",
4869
+ "- Reserve explicit `relationships` entries for what linkage fields cannot express: covered_by_eval, runs_in_environment, invoked_by_channel, deployed_as, shares_artifact_with, resolves_identity_to, emits_telemetry."
4870
+ ],
4871
+ contractLines: [
4872
+ 'Runtime agents must include id, name, kind:"runtime_agent", root, entrypointIds, channelAdapterIds, artifactIds, identityNamespaceIds, deploymentIds, frameworkIds, modelProviderIds, confidence, evidence. Agent linkage fields are the product of this pass — empty linkage means a disconnected map.',
4873
+ "Agent families must include id, name, runtimeAgentIds, sharedArtifactIds, confidence, evidence.",
4874
+ "Frameworks/providers must include packageNames and runtimeAgentIds arrays; providers also include envVars and modelHints arrays.",
4875
+ "Keep graph.artifacts minimal (entrypoints only); do not enumerate tools, prompts, guardrails, or evals."
4876
+ ],
4877
+ largeRepoLine: "If the repository is very large, model runtime agents representatively rather than exhaustively, but never drop channel adapters, providers, frameworks, or deployments you have evidence for."
4878
+ },
4879
+ tools: {
4880
+ mission: "Your single concern for this pass is TOOLS: the exhaustive tool inventory. Other concern passes cover agents/topology, prompts, and evals — you must not enumerate those.",
4881
+ taskLines: [
4882
+ "1. Exhaustively enumerate EVERY tool as its own `tool` graph artifact — the complete inventory, not a sample. This report feeds tool optimization, so a missing tool is a real defect.",
4883
+ "2. Do NOT enumerate prompts, guardrails, or evals, and do not map agent topology beyond bare stubs needed for tool linkage."
4884
+ ],
4885
+ protocolLines: [
4886
+ "- Tools: emit a `tool` artifact for EVERY tool definition — each `@function_tool` / `function_tool(...)`-decorated function, every hosted/first-party tool class (e.g. WebSearchTool, FileSearchTool, ComputerTool, CodeInterpreterTool, HostedMCPTool, ImageGenerationTool, LocalShellTool), and every `tool({...})` / `createTool(...)` / `new *Tool(...)` factory. Name each artifact after the tool/function and cite its definition line.",
4887
+ "- Populate usedByAgentIds on every tool artifact whenever the using agent is determinable (and ownedByAgentId when a single agent owns it).",
4888
+ `- ${CONCERN_AGENT_STUB_LINE}`,
4889
+ "- Do NOT emit prompt, guardrail, eval, memory, or retrieval_index artifacts — other concern passes own those.",
4890
+ CONCERN_CAPS_LINE
4891
+ ],
4892
+ contractLines: [
4893
+ 'Artifacts must include id, type:"tool", name, scope, usedByAgentIds, confidence, evidence, and optional sourcePath/contentHash/ownedByAgentId. Emit one artifact PER tool — enumerate them all.',
4894
+ CONCERN_NO_TRANSCRIPTION_LINE,
4895
+ CONCERN_LOCATION_PIN_LINE,
4896
+ CONCERN_AGENT_STUB_LINE
4897
+ ],
4898
+ largeRepoLine: "If the repository is very large, keep enumerating tools as artifacts (uncapped) — do not drop tools to save space."
4899
+ },
4900
+ prompts: {
4901
+ mission: "Your single concern for this pass is PROMPTS: the exhaustive prompt inventory. Other concern passes cover agents/topology, tools, and evals — you must not enumerate those.",
4902
+ taskLines: [
4903
+ "1. Exhaustively enumerate EVERY distinct prompt as its own `prompt` graph artifact — dedicated prompt files AND inline system prompts, the complete inventory, not a sample. This report feeds prompt optimization, so a missing prompt is a real defect.",
4904
+ "2. Do NOT enumerate tools, guardrails, or evals, and do not map agent topology beyond bare stubs needed for prompt linkage."
4905
+ ],
4906
+ protocolLines: [
4907
+ "- Prompts: emit a `prompt` artifact for EVERY distinct prompt — dedicated prompt files AND inline system prompts (`instructions=`, `system=`, `SYSTEM_PROMPT`, prompt-template strings), one per agent/definition, each with its exact file+line location so the prompt text can be retrieved and optimized later.",
4908
+ "- Populate usedByAgentIds on every prompt artifact whenever the using agent is determinable (and ownedByAgentId when a single agent owns it).",
4909
+ `- ${CONCERN_AGENT_STUB_LINE}`,
4910
+ "- Do NOT emit tool, guardrail, eval, memory, or retrieval_index artifacts — other concern passes own those.",
4911
+ CONCERN_CAPS_LINE
4912
+ ],
4913
+ contractLines: [
4914
+ 'Artifacts must include id, type:"prompt", name, scope, usedByAgentIds, confidence, evidence, and optional sourcePath/contentHash/ownedByAgentId. Emit one artifact PER prompt (including each inline system prompt) — enumerate them all.',
4915
+ CONCERN_NO_TRANSCRIPTION_LINE,
4916
+ CONCERN_LOCATION_PIN_LINE,
4917
+ CONCERN_AGENT_STUB_LINE
4918
+ ],
4919
+ largeRepoLine: "If the repository is very large, keep enumerating prompts as artifacts (uncapped) — do not drop prompts to save space."
4920
+ },
4921
+ evals: {
4922
+ mission: "Your single concern for this pass is EVALS & SAFETY CONFIG: evals, guardrails, model configs, and memory/retrieval stores. Other concern passes cover agents/topology, tools, and prompts — you must not enumerate those.",
4923
+ taskLines: [
4924
+ '1. Exhaustively enumerate EVERY eval (type "eval"), guardrail (type "guardrail"), model configuration (type "model_config"), memory/session store (type "memory"), and retrieval index (type "retrieval_index") as its own graph artifact — the complete inventory, not a sample.',
4925
+ "2. Do NOT enumerate tools or prompts, and do not map agent topology beyond bare stubs needed for linkage."
4926
+ ],
4927
+ protocolLines: [
4928
+ '- Emit artifacts for evals/tests-of-agents (type "eval"), guardrails (type "guardrail"), model configuration (type "model_config"), memory/session stores (type "memory"), and retrieval indexes (type "retrieval_index").',
4929
+ "- Short bodies are welcome here: `guardrail` (the rule), `eval` (what it asserts), `model_config` (the config values). Redact any secret literals.",
4930
+ "- Populate usedByAgentIds on every artifact whenever the using agent is determinable.",
4931
+ `- ${CONCERN_AGENT_STUB_LINE}`,
4932
+ "- Do NOT emit tool or prompt artifacts — other concern passes own those.",
4933
+ CONCERN_CAPS_LINE
4934
+ ],
4935
+ contractLines: [
4936
+ "Artifacts must include id, type, name, scope, usedByAgentIds, confidence, evidence, and optional sourcePath/contentHash/ownedByAgentId; artifact types for this pass are eval, guardrail, model_config, memory, retrieval_index. Emit one artifact PER item — enumerate them all.",
4937
+ "Short bodies are welcome: `guardrail` (the rule), `eval` (what it asserts), `model_config` (the config values). Redact any secret literals.",
4938
+ CONCERN_AGENT_STUB_LINE
4939
+ ],
4940
+ largeRepoLine: "If the repository is very large, keep enumerating evals, guardrails, and model configs as artifacts (uncapped) — do not drop them to save space."
4941
+ }
4942
+ };
4768
4943
  function renderExternalHarnessAnalystPrompt(options) {
4944
+ const spec = options.concern ? CONCERN_PROMPT_SPECS[options.concern] : undefined;
4769
4945
  return [
4770
4946
  "You are Moda Analyst, investigating an agent harness for Moda CLI onboarding.",
4947
+ spec?.mission ?? "",
4771
4948
  "",
4772
4949
  "Do real repository investigation. Do not call `moda harness scan` or `moda harness analyze` yourself. When Moda provides deterministic scanner seeds below, treat them as navigation candidates to verify against the real files — never as evidence or as a complete inventory.",
4773
4950
  "Only inspect the Repository root named below and files/directories under it. Do not inspect parent directories, sibling projects, the Moda CLI implementation, or this monorepo unless the Repository root itself is that directory.",
@@ -4777,13 +4954,15 @@ function renderExternalHarnessAnalystPrompt(options) {
4777
4954
  `The ONLY path you may write is ${HARNESS_REPORT_PATH}. Write the final report JSON there with the Write tool as soon as it is complete — the file is the durable deliverable and survives a dropped connection, unlike a long printed message. If (and only if) the write fails, print the report JSON between the sentinel markers instead.`,
4778
4955
  "",
4779
4956
  "Your task:",
4780
- renderExternalAnalystProtocol(),
4781
- "1. Identify the runtime agent harnesses, agent families, channel adapters, identity mappings, model providers, frameworks, deployments, and open questions.",
4782
- "2. Exhaustively enumerate EVERY prompt, tool, guardrail, and eval as its own graph artifact — the complete inventory, not a sample. This report feeds prompt optimization and tool optimization, so a missing tool or prompt is a real defect. Runtime agents may be modeled representatively on framework/example repos, but prompts and tools must be complete.",
4957
+ renderExternalAnalystProtocol(options.concern),
4958
+ ...spec ? spec.taskLines : [
4959
+ "1. Identify the runtime agent harnesses, agent families, channel adapters, identity mappings, model providers, frameworks, deployments, and open questions.",
4960
+ "2. Exhaustively enumerate EVERY prompt, tool, guardrail, and eval as its own graph artifact — the complete inventory, not a sample. This report feeds prompt optimization and tool optimization, so a missing tool or prompt is a real defect. Runtime agents may be modeled representatively on framework/example repos, but prompts and tools must be complete."
4961
+ ],
4783
4962
  "3. Cite every narrative claim with local file paths, exact line numbers, and excerpts. File citations without line numbers are invalid for agent-authored reports. Enumerated artifacts only need evidence:[{path, reason}], so completeness of the artifact inventory is not limited by the citation cap.",
4784
4963
  `4. After completing investigation, WRITE the report JSON to ${HARNESS_REPORT_PATH} with the Write tool, then print a one-line confirmation naming the file. Only if that write fails, print the report JSON between ${REPORT_JSON_BEGIN} and ${REPORT_JSON_END}. Moda CLI validates whichever it finds (the file wins).`,
4785
4964
  "Do not end with commentary about being read-only and do not summarize without delivering the report: either the written file or the sentinel-wrapped JSON must exist before you finish.",
4786
- "If the repository is very large, keep enumerating prompts/tools/guardrails/evals as artifacts (uncapped) and only summarize runtime AGENTS representatively — do not drop tools or prompts to save space.",
4965
+ spec?.largeRepoLine ?? "If the repository is very large, keep enumerating prompts/tools/guardrails/evals as artifacts (uncapped) and only summarize runtime AGENTS representatively — do not drop tools or prompts to save space.",
4787
4966
  "",
4788
4967
  "Final output format:",
4789
4968
  REPORT_JSON_BEGIN,
@@ -4797,7 +4976,7 @@ function renderExternalHarnessAnalystPrompt(options) {
4797
4976
  "- reportId, harnessId, createdAt",
4798
4977
  `- analyst: { "id": "moda-${options.adapter}-analyst", "adapter": "${options.adapter}", "mode": "agent", "version": "cli" }`,
4799
4978
  '- repo: { root: ".", name, packageManagers, languages }',
4800
- '- source: { graphSchemaVersion: "harness.v0.1", graphHash: "", readPlan, deterministicInventory: false }',
4979
+ options.concern ? `- source: { graphSchemaVersion: "harness.v0.1", graphHash: "", readPlan, deterministicInventory: false, concern: "${options.concern}" }` : '- source: { graphSchemaVersion: "harness.v0.1", graphHash: "", readPlan, deterministicInventory: false }',
4801
4980
  "- summary: numeric fields named runtimeAgentCount, agentFamilyCount, artifactCount, sharedArtifactCount, channelAdapterCount, identityNamespaceCount, environmentCount, agentFrameworkCount, modelProviderCount, deploymentCount, relationshipCount, unknownCount",
4802
4981
  "- graph: an exact sanitized harness.v0.1 graph with arrays for agentFamilies, runtimeAgents, developerAgentAdapters, channelAdapters, artifacts, identityNamespaces, environments, agentFrameworks, modelProviders, deployments, relationships, unknowns",
4803
4982
  "- claims: cited claims about graph items. Each claim must include kind, subjectId, title, summary, confidence, inference, and citationIds; kind should be one of runtime_agent, agent_family, developer_agent_adapter, artifact, channel_adapter, identity_namespace, environment, agent_framework, model_provider, deployment, relationship, unknown. subjectId should be the id of the runtime agent, agent family, developer adapter, artifact, provider, adapter, deployment, relationship, or unknown being claimed.",
@@ -4807,13 +4986,15 @@ function renderExternalHarnessAnalystPrompt(options) {
4807
4986
  "",
4808
4987
  '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).',
4809
4988
  "Each graph item with evidence must use evidence: [{ path, reason }], not citationIds/citations.",
4810
- 'Runtime agents must include id, name, kind:"runtime_agent", root, entrypointIds, channelAdapterIds, artifactIds, identityNamespaceIds, deploymentIds, frameworkIds, modelProviderIds, confidence, evidence.',
4811
- "Artifacts must include id, type, name, scope, usedByAgentIds, confidence, evidence, and optional sourcePath/contentHash/ownedByAgentId. Emit one artifact PER tool, PER prompt (including each inline system prompt), PER guardrail, and PER eval — enumerate them all; artifact types are entrypoint, prompt, tool, skill, eval, retrieval_index, memory, guardrail, model_config, unknown.",
4812
- "Do NOT transcribe prompt/tool text into `body` when it exists verbatim in the repo — pin its exact location instead (sourcePath for a dedicated file, or evidence [{ path, line, reason }] at the definition line) and Moda hydrates `body` locally from that location after validation. Set `body` inline ONLY for content that cannot be recovered from one pinned location: dynamically assembled prompts, fragments concatenated at runtime, or values you had to derive. Short bodies for `guardrail` (the rule), `eval` (what it asserts), and `model_config` (the config values) are still welcome. Redact any secret literals.",
4813
- "For every `prompt` and `tool` artifact, at least one evidence entry MUST pin an exact source location so downstream optimization can retrieve the item text: carry a numeric `line` (the definition line, or the first line of the range) — evidence: [{ path, line, reason }]. The only exception is an artifact whose entire dedicated file is the text (e.g. a standalone prompt file); set its sourcePath and cite that same file and no line is required. When a single file holds multiple inline prompts or tool definitions, give each its own distinct line — a bare { path, reason } is a defect there.",
4814
- "LINKAGE IS MANDATORY, not optional metadata: every artifact you author must carry usedByAgentIds naming each runtime agent that uses it (and ownedByAgentId when a single agent owns it), and every runtime agent's artifactIds must list its prompts, tools, and evals. Moda derives uses_artifact/owns_artifact edges from these fields after your run, so empty linkage means a disconnected map. Reserve explicit `relationships` entries for what linkage fields cannot express: covered_by_eval, runs_in_environment, invoked_by_channel, deployed_as, shares_artifact_with, resolves_identity_to, emits_telemetry.",
4815
- "Agent families must include id, name, runtimeAgentIds, sharedArtifactIds, confidence, evidence.",
4816
- "Frameworks/providers must include packageNames and runtimeAgentIds arrays; providers also include envVars and modelHints arrays.",
4989
+ ...spec ? spec.contractLines : [
4990
+ 'Runtime agents must include id, name, kind:"runtime_agent", root, entrypointIds, channelAdapterIds, artifactIds, identityNamespaceIds, deploymentIds, frameworkIds, modelProviderIds, confidence, evidence.',
4991
+ "Artifacts must include id, type, name, scope, usedByAgentIds, confidence, evidence, and optional sourcePath/contentHash/ownedByAgentId. Emit one artifact PER tool, PER prompt (including each inline system prompt), PER guardrail, and PER eval — enumerate them all; artifact types are entrypoint, prompt, tool, skill, eval, retrieval_index, memory, guardrail, model_config, unknown.",
4992
+ "Do NOT transcribe prompt/tool text into `body` when it exists verbatim in the repo — pin its exact location instead (sourcePath for a dedicated file, or evidence [{ path, line, reason }] at the definition line) and Moda hydrates `body` locally from that location after validation. Set `body` inline ONLY for content that cannot be recovered from one pinned location: dynamically assembled prompts, fragments concatenated at runtime, or values you had to derive. Short bodies for `guardrail` (the rule), `eval` (what it asserts), and `model_config` (the config values) are still welcome. Redact any secret literals.",
4993
+ "For every `prompt` and `tool` artifact, at least one evidence entry MUST pin an exact source location so downstream optimization can retrieve the item text: carry a numeric `line` (the definition line, or the first line of the range) — evidence: [{ path, line, reason }]. The only exception is an artifact whose entire dedicated file is the text (e.g. a standalone prompt file); set its sourcePath and cite that same file and no line is required. When a single file holds multiple inline prompts or tool definitions, give each its own distinct line — a bare { path, reason } is a defect there.",
4994
+ "LINKAGE IS MANDATORY, not optional metadata: every artifact you author must carry usedByAgentIds naming each runtime agent that uses it (and ownedByAgentId when a single agent owns it), and every runtime agent's artifactIds must list its prompts, tools, and evals. Moda derives uses_artifact/owns_artifact edges from these fields after your run, so empty linkage means a disconnected map. Reserve explicit `relationships` entries for what linkage fields cannot express: covered_by_eval, runs_in_environment, invoked_by_channel, deployed_as, shares_artifact_with, resolves_identity_to, emits_telemetry.",
4995
+ "Agent families must include id, name, runtimeAgentIds, sharedArtifactIds, confidence, evidence.",
4996
+ "Frameworks/providers must include packageNames and runtimeAgentIds arrays; providers also include envVars and modelHints arrays."
4997
+ ],
4817
4998
  "Unknowns in graph must include id, question, candidateIds, evidence. Report-level unknowns must include id, question, citationIds.",
4818
4999
  "Do not make every claim about the repo or harness id. Claims should name the specific graph item they support.",
4819
5000
  "",
@@ -4821,16 +5002,24 @@ function renderExternalHarnessAnalystPrompt(options) {
4821
5002
  options.tenantId ? `Tenant ID to include in graph.tenant: ${options.tenantId}` : "No tenant ID was provided for this analysis.",
4822
5003
  `Repository root: ${options.rootDir}`,
4823
5004
  renderAnalystPreflightSection(options.rootDir),
4824
- renderAnalystSeedSection(options.rootDir),
5005
+ renderAnalystSeedSection(options.rootDir, options.concern),
4825
5006
  "",
4826
5007
  "Be conservative. If something is unclear, put it in unknowns instead of inventing an agent."
4827
5008
  ].filter(Boolean).join(`
4828
5009
  `);
4829
5010
  }
4830
- function renderExternalAnalystProtocol() {
5011
+ function renderExternalAnalystProtocol(concern) {
4831
5012
  const protocol = process.env.MODA_HARNESS_ANALYST_PROTOCOL?.trim().toLowerCase();
4832
5013
  if (protocol === "classic" || protocol === "none" || protocol === "0")
4833
5014
  return "";
5015
+ if (concern) {
5016
+ return [
5017
+ "Focused investigation protocol:",
5018
+ "- First build a quick repo map with read-only commands such as pwd, git ls-files, rg, and targeted manifest/doc reads.",
5019
+ ...CONCERN_PROMPT_SPECS[concern].protocolLines
5020
+ ].join(`
5021
+ `);
5022
+ }
4834
5023
  return [
4835
5024
  "Focused investigation protocol:",
4836
5025
  "- First build a quick repo map with read-only commands such as pwd, git ls-files, rg, and targeted manifest/doc reads.",
@@ -4879,23 +5068,31 @@ function renderPreflightGroup(label, paths) {
4879
5068
  return [`${label}:`, ...paths.map((path) => `- ${path}`)];
4880
5069
  }
4881
5070
  var MAX_SEED_ARTIFACT_LINES = 150;
4882
- function renderAnalystSeedSection(rootDir) {
5071
+ function renderAnalystSeedSection(rootDir, concern) {
4883
5072
  if (process.env.MODA_HARNESS_ANALYST_SEEDS === "0")
4884
5073
  return "";
4885
5074
  const sections = [];
5075
+ if (concern === undefined || concern === "topology") {
5076
+ try {
5077
+ const lines = renderAnalystSeedLines(scanHarness({ rootDir, dryRun: true, pathWasExplicit: true }));
5078
+ if (lines)
5079
+ sections.push(lines);
5080
+ } catch {}
5081
+ }
4886
5082
  try {
4887
- const lines = renderAnalystSeedLines(scanHarness({ rootDir, dryRun: true, pathWasExplicit: true }));
4888
- if (lines)
4889
- sections.push(lines);
4890
- } catch {}
4891
- try {
4892
- const lines = renderAnalystCandidateLines(detectHarnessCandidates(rootDir));
5083
+ const lines = renderAnalystCandidateLines(detectHarnessCandidates(rootDir), concern);
4893
5084
  if (lines)
4894
5085
  sections.push(lines);
4895
5086
  } catch {}
4896
5087
  return sections.join(`
4897
5088
  `);
4898
5089
  }
5090
+ var CONCERN_CANDIDATE_KINDS = {
5091
+ topology: ["llm_call_site", "framework_construct"],
5092
+ tools: ["tool_definition", "tool_schema"],
5093
+ prompts: ["prompt_file", "prompt_literal", "message_construction"],
5094
+ evals: ["model_config"]
5095
+ };
4899
5096
  var MAX_SEED_CANDIDATES_PER_KIND = 40;
4900
5097
  var MAX_SEED_READ_PLAN_FILES = 25;
4901
5098
  var SEED_CANDIDATE_KIND_LABELS = {
@@ -4908,11 +5105,13 @@ var SEED_CANDIDATE_KIND_LABELS = {
4908
5105
  prompt_literal: "Inline prompt literals",
4909
5106
  model_config: "Model configuration"
4910
5107
  };
4911
- function renderAnalystCandidateLines(report) {
4912
- if (report.candidates.length === 0)
5108
+ function renderAnalystCandidateLines(report, concern) {
5109
+ const allowedKinds = concern ? new Set(CONCERN_CANDIDATE_KINDS[concern]) : undefined;
5110
+ const candidates = allowedKinds ? report.candidates.filter((candidate) => allowedKinds.has(candidate.kind)) : report.candidates;
5111
+ if (candidates.length === 0)
4913
5112
  return "";
4914
5113
  const byKind = new Map;
4915
- for (const candidate of report.candidates) {
5114
+ for (const candidate of candidates) {
4916
5115
  const bucket = byKind.get(candidate.kind);
4917
5116
  if (bucket)
4918
5117
  bucket.push(candidate);
@@ -4921,9 +5120,12 @@ function renderAnalystCandidateLines(report) {
4921
5120
  }
4922
5121
  const lines = [
4923
5122
  "",
4924
- `Deterministic candidate inventory (${report.candidates.length} candidates across ${report.stats.filesWithCandidates} files, scanned in ${report.stats.durationMs}ms):`,
4925
- "Each entry is path:line [detector] excerpt. Candidates are pattern matches — verify each against the real file and drop false positives. Verified deterministic candidates are also auto-merged into the graph after your run, so prioritize (1) agents, topology, and relationships, (2) verifying or refuting these candidates (list refuted ones in unknowns), and (3) artifacts the patterns cannot see (runtime agents, prompts assembled at runtime, cross-file wiring) — rather than re-listing every candidate as an artifact. Do not cite this list as evidence; cite the files."
5123
+ concern ? `Deterministic candidate inventory for the ${concern} concern (${candidates.length} candidates, scanned in ${report.stats.durationMs}ms):` : `Deterministic candidate inventory (${candidates.length} candidates across ${report.stats.filesWithCandidates} files, scanned in ${report.stats.durationMs}ms):`,
5124
+ concern ? "Each entry is path:line [detector] excerpt. Candidates are pattern matches — verify each against the real file, drop false positives (list refuted ones in unknowns), and hunt for in-concern items the patterns cannot see. Do not cite this list as evidence; cite the files." : "Each entry is path:line [detector] excerpt. Candidates are pattern matches — verify each against the real file and drop false positives. Verified deterministic candidates are also auto-merged into the graph after your run, so prioritize (1) agents, topology, and relationships, (2) verifying or refuting these candidates (list refuted ones in unknowns), and (3) artifacts the patterns cannot see (runtime agents, prompts assembled at runtime, cross-file wiring) — rather than re-listing every candidate as an artifact. Do not cite this list as evidence; cite the files."
4926
5125
  ];
5126
+ if (concern === "evals") {
5127
+ lines.push("Note: evals, guardrails, and memory/retrieval stores have no deterministic detector — only model_config candidates are seeded. Discover the rest by investigation.");
5128
+ }
4927
5129
  for (const [kind, label] of Object.entries(SEED_CANDIDATE_KIND_LABELS)) {
4928
5130
  const bucket = byKind.get(kind);
4929
5131
  if (!bucket || bucket.length === 0)
package/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  runPromptsCommand,
9
9
  runSkillsCommand,
10
10
  runStatusCommand
11
- } from "./cli-3ba4qcpr.js";
11
+ } from "./cli-c1vhkg8n.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-5e0rd8mf.js";
32
+ } from "./cli-ts6nhn51.js";
33
33
  import {
34
34
  authFetch,
35
35
  clearAuthSession,
@@ -2240,6 +2240,13 @@ var agentEventSchema = {
2240
2240
  phase: { type: "string" },
2241
2241
  message: { type: "string" },
2242
2242
  elapsed_ms: { type: "number" },
2243
+ usage: {
2244
+ type: "object",
2245
+ description: "Per-LLM-call token usage passed through verbatim from the underlying coding-agent stream (e.g. input_tokens/output_tokens/cache_* from claude stream-json).",
2246
+ additionalProperties: true
2247
+ },
2248
+ model: { type: "string", description: "Model id reported by the underlying coding-agent stream for this call." },
2249
+ duration_ms: { type: "number", description: "Duration in ms reported by the underlying coding-agent stream (result events)." },
2243
2250
  artifact: agentArtifactSchema,
2244
2251
  result: agentEnvelopeSchema,
2245
2252
  error: agentErrorSchema,
@@ -5507,6 +5514,11 @@ Init flags:
5507
5514
  --analyst-model=MODEL Model for the claude analyst (default: sonnet;
5508
5515
  "default" = the claude CLI's own default;
5509
5516
  env: MODA_HARNESS_ANALYST_MODEL)
5517
+ --concern=topology|tools|prompts|evals
5518
+ Harness analyze: restrict the pass to one
5519
+ concern (whole repo, one report scope); an
5520
+ orchestrator merges the per-concern reports
5521
+ (env: MODA_HARNESS_CONCERN, flag wins)
5510
5522
  --allow-no-agents Allow harness sync to push a graph with zero
5511
5523
  runtime agents despite detected LLM usage
5512
5524
  --remote Run harness analysis server-side (Moda-hosted,
@@ -6514,7 +6526,7 @@ var commandRegistry = createCommandRegistry([
6514
6526
  resetApiRequestCountBeforeRun: true,
6515
6527
  telemetry: "result",
6516
6528
  handler: async (context) => {
6517
- const { runInit } = await import("./index-nes2m734.js");
6529
+ const { runInit } = await import("./index-v3j2848b.js");
6518
6530
  if (context.outputMode === "agent-stream") {
6519
6531
  context.output.writeEvent({
6520
6532
  event: "started",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildSourceSnapshot
3
- } from "./cli-5e0rd8mf.js";
3
+ } from "./cli-ts6nhn51.js";
4
4
  import"./cli-59yacef3.js";
5
5
 
6
6
  // src/harness-github-actions.ts
@@ -9,7 +9,7 @@ import {
9
9
  runPromptSync,
10
10
  runSkillSync,
11
11
  upsertSkillManifestRecord
12
- } from "./cli-3ba4qcpr.js";
12
+ } from "./cli-c1vhkg8n.js";
13
13
  import {
14
14
  codingAgentDisplayName,
15
15
  describeCodingAgentEvent,
@@ -27,7 +27,7 @@ import {
27
27
  runHarnessCommand,
28
28
  startRemoteAnalyze,
29
29
  stripAnsi
30
- } from "./cli-5e0rd8mf.js";
30
+ } from "./cli-ts6nhn51.js";
31
31
  import {
32
32
  selectTenantAndCreateKey
33
33
  } from "./cli-pq6rte0w.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moda-ai/cli",
3
- "version": "1.30.0",
3
+ "version": "1.30.2",
4
4
  "description": "CLI for Moda - AI agent analytics and observability",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": "moda.skill_index.v1",
3
- "bundled_at": "2026-09-02T01:04:59.515Z",
4
- "cli_version": "1.30.0",
3
+ "bundled_at": "2026-09-03T05:01:51.741Z",
4
+ "cli_version": "1.30.2",
5
5
  "skills": [
6
6
  {
7
7
  "id": "integration-node-anthropic",