@moda-ai/cli 1.52.0 → 1.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -106,8 +106,9 @@ Legacy aliases (same behavior, kept for existing scripts): `moda conversations`
106
106
  Prompt management:
107
107
 
108
108
  ```bash
109
- moda prompts init # Create .moda/prompts.yml
109
+ moda prompts init # Create .moda/prompts.yml (version 2)
110
110
  moda prompts status # Read-only local prompt status
111
+ moda prompts migrate --dry-run # Preview a version 1 -> 2 manifest rewrite
111
112
  moda prompts sync # Upload changed prompt versions
112
113
  moda prompts promote support.triage --label=prod --version=pver_abc123
113
114
  ```
@@ -176,7 +177,10 @@ results on stdout remain unchanged; `--quiet` suppresses progress and
176
177
  `--watch` starts with analysis and then watches mapped definitions; re-run sync
177
178
  to discover new sources that do not affect an existing mapping. You can also
178
179
  run `harness analyze --experimental --concern=prompts` and import its report
179
- with `prompts init --from-harness=<report>`. Discovery reports partial coverage:
180
+ with `prompts init --from-harness=<report>`. Older reports are normalized and
181
+ prompts without a `promptSource` are mapped from `sourcePath` when unambiguous;
182
+ prompts that still do not resolve are returned in `skipped` with a reason, and the
183
+ import fails only when none resolve. Discovery reports partial coverage:
180
184
  finding a prompt fragment does not prove that every composition or model call
181
185
  has been covered.
182
186
 
@@ -239,6 +243,14 @@ sources:
239
243
  - path: config/policy.txt
240
244
  ```
241
245
 
246
+ Manifests from older CLIs say `version: 1`. Those CLIs matched `.prompt.*` files
247
+ anywhere in the repository; patterns are now exact globs from the repository root.
248
+ `prompts status` reports `zeroMatchPatterns` and `legacyOnlyFiles` (files only the
249
+ old discovery found), and `moda prompts migrate [--dry-run] [--discover]` rewrites
250
+ the manifest to version 2, adding those files as explicit paths so their keys and
251
+ lockfile entries are unchanged. The lockfile `contentHash` is
252
+ `computePromptContentHash` from `@moda-ai/cli/prompt-hash` (`PROMPT_HASH_VERSION` 1).
253
+
242
254
  Selectors support named TypeScript/JavaScript/Python definitions and JSON Pointer
243
255
  selection in JSON/YAML. Python resolution requires `python3`; the helper parses
244
256
  ASTs without importing customer modules. Static literals and supported constant
@@ -182903,6 +182903,19 @@ function discoverStructuredPromptSources(rootDir, sourcePath) {
182903
182903
  walk(value, [], 0, []);
182904
182904
  return sources;
182905
182905
  }
182906
+ function backfillPromptSource(rootDir, artifact) {
182907
+ if (artifact.promptSource)
182908
+ return artifact.promptSource;
182909
+ if (!artifact.sourcePath)
182910
+ return;
182911
+ if (/\.(?:[cm]?[jt]sx?|py)$/.test(artifact.sourcePath)) {
182912
+ const candidates = discoverCodePromptSources(rootDir, artifact.sourcePath);
182913
+ const name = (artifact.name ?? "").replace(/[^a-z0-9]/gi, "").toLowerCase();
182914
+ const matching = candidates.filter((source) => source.selector?.symbol?.replace(/[^a-z0-9]/gi, "").toLowerCase() === name);
182915
+ return matching.length === 1 ? matching[0] : undefined;
182916
+ }
182917
+ return { key: artifact.id, path: artifact.sourcePath };
182918
+ }
182906
182919
  function discoverCodePromptSources(rootDir, sourcePath) {
182907
182920
  return discoverCodePromptCandidates(rootDir, sourcePath).map((candidate) => candidate.source);
182908
182921
  }
@@ -184857,7 +184870,7 @@ async function runHarnessCommand(context) {
184857
184870
  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.");
184858
184871
  }
184859
184872
  if (context.flags["github-actions"] === "true") {
184860
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-gbty3k66.js");
184873
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-075xzdvp.js");
184861
184874
  const result = await runGithubActionsAnalyze(rootDir, {
184862
184875
  writeReport: (report2) => {
184863
184876
  const normalized = normalizeHarnessReport(report2);
@@ -185501,19 +185514,10 @@ function repairExternalAnalystReport(report, rootDir, options = {}) {
185501
185514
  if (artifact.type !== "prompt")
185502
185515
  continue;
185503
185516
  try {
185504
- if (!artifact.promptSource && artifact.sourcePath) {
185505
- if (/\.(?:[cm]?[jt]sx?|py)$/.test(artifact.sourcePath)) {
185506
- const candidates = discoverCodePromptSources(rootDir, artifact.sourcePath);
185507
- const name = artifact.name.replace(/[^a-z0-9]/gi, "").toLowerCase();
185508
- const matching = candidates.filter((source2) => source2.selector?.symbol?.replace(/[^a-z0-9]/gi, "").toLowerCase() === name);
185509
- if (matching.length === 1)
185510
- artifact.promptSource = matching[0];
185511
- } else {
185512
- artifact.promptSource = { key: artifact.id, path: artifact.sourcePath };
185513
- }
185514
- }
185515
- if (!artifact.promptSource)
185517
+ const backfilled = backfillPromptSource(rootDir, artifact);
185518
+ if (!backfilled)
185516
185519
  continue;
185520
+ artifact.promptSource = backfilled;
185517
185521
  const source = resolvePromptSource(rootDir, artifact.promptSource);
185518
185522
  artifact.body = source.content;
185519
185523
  artifact.sourceDefinition = source.sourceDefinition;
@@ -188911,4 +188915,4 @@ function hashText(text) {
188911
188915
  return createHash4("sha256").update(text).digest("hex");
188912
188916
  }
188913
188917
 
188914
- export { ApiError, callDataAPI, callControlAPI, getApiRequestCount, resetApiRequestCount, $parseDocument, $stringify, require_typescript, inspectCodeSelectors, inspectPythonSelectors, resolvePromptSource, assertFlags, assertPositionals, runUsersCommand, runUserCommand, runProblemReopenCommand, runSignalsManagementCommand, SIGNALS_MANAGEMENT_SUBCOMMANDS, unknownSignalsSubcommandError, shouldColorTerminalOutput, terminalStyles, stripAnsi2 as stripAnsi, renderMarkdownForTerminal, HARNESS_REPORT_PATH, HARNESS_REPORT_APPROVAL_PATH, HARNESS_ANALYZE_CONCERNS, validateHarnessReport, readHarnessReport, hashHarnessReport, hashStableJson, startRemoteAnalyze, pollRemoteAnalyzeUntilDone, isRecoverableRemoteRun, checkPromptMapping, safePromptEvidencePath, discoverHarnessPromptSources, renderDoctorHuman, renderStatusHuman, renderInitBanner, renderInitStep, renderInitNote, renderInitSetupPlan, renderInitComplete, runHarnessCommand, writeHarnessAnalyzeResult, emitWrittenArtifacts, analyzeHarnessPrompts, repairExternalAnalystReport, deriveRelationshipsFromGraph, mergeDeterministicArtifacts, describeCodingAgentEvent, analystEventProgress, isRetryableExternalAnalystFailure, sleep, summarizeInvalidAnalystReport, isDeterministicLocalAnalyst, resolveHarnessAnalyzeConcern, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, resolveAnalystModel, renderExternalHarnessAnalystPrompt, CONCERN_CANDIDATE_KINDS, SEED_CANDIDATE_KIND_LABELS, renderAnalystCandidateLines, renderAnalystSeedLines, truncateText, scanHarness, summarizeHarness, buildSourceSnapshot, writeHumanProgress, readHarnessSyncState, describeSyncIdentity, describeSyncTenantLabel, findFresherHarnessReports, writeHarnessArtifacts, assertHarnessGraphSyncQuality, graphForSync, inventoryFiles, numericEnv, numericEnvAllowZero, computeDeterministicFloor, stableId2 as stableId, titleFromId2 as titleFromId, promptNameFromPath };
188918
+ export { ApiError, callDataAPI, callControlAPI, getApiRequestCount, resetApiRequestCount, $isSeq, $parseDocument, $stringify, require_typescript, inspectCodeSelectors, inspectPythonSelectors, resolvePromptSource, backfillPromptSource, HARNESS_REPORT_PATH, HARNESS_REPORT_APPROVAL_PATH, HARNESS_ANALYZE_CONCERNS, validateHarnessReport, readHarnessReport, normalizeHarnessReport, hashHarnessReport, hashStableJson, assertFlags, assertPositionals, runUsersCommand, runUserCommand, runProblemReopenCommand, runSignalsManagementCommand, SIGNALS_MANAGEMENT_SUBCOMMANDS, unknownSignalsSubcommandError, shouldColorTerminalOutput, terminalStyles, stripAnsi2 as stripAnsi, renderMarkdownForTerminal, startRemoteAnalyze, pollRemoteAnalyzeUntilDone, isRecoverableRemoteRun, checkPromptMapping, safePromptEvidencePath, discoverHarnessPromptSources, renderDoctorHuman, renderStatusHuman, renderInitBanner, renderInitStep, renderInitNote, renderInitSetupPlan, renderInitComplete, runHarnessCommand, writeHarnessAnalyzeResult, emitWrittenArtifacts, analyzeHarnessPrompts, repairExternalAnalystReport, deriveRelationshipsFromGraph, mergeDeterministicArtifacts, describeCodingAgentEvent, analystEventProgress, isRetryableExternalAnalystFailure, sleep, summarizeInvalidAnalystReport, isDeterministicLocalAnalyst, resolveHarnessAnalyzeConcern, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, resolveAnalystModel, renderExternalHarnessAnalystPrompt, CONCERN_CANDIDATE_KINDS, SEED_CANDIDATE_KIND_LABELS, renderAnalystCandidateLines, renderAnalystSeedLines, truncateText, scanHarness, summarizeHarness, buildSourceSnapshot, writeHumanProgress, readHarnessSyncState, describeSyncIdentity, describeSyncTenantLabel, findFresherHarnessReports, writeHarnessArtifacts, assertHarnessGraphSyncQuality, graphForSync, inventoryFiles, numericEnv, numericEnvAllowZero, computeDeterministicFloor, stableId2 as stableId, titleFromId2 as titleFromId, promptNameFromPath };