@moda-ai/cli 1.34.0 → 1.34.1
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 +19 -2
- package/dist/{cli-xwqb83jb.js → cli-8q7jffnj.js} +26 -13
- package/dist/{cli-q9t1tr1z.js → cli-cagbc7wz.js} +175 -37
- package/dist/cli.js +3 -3
- package/dist/{harness-g0jbmgsx.js → harness-1xj4f0qp.js} +1 -1
- package/dist/{harness-github-actions-43kt57xm.js → harness-github-actions-xk7n788g.js} +1 -1
- package/dist/{index-a0hvade2.js → index-h6gg66n5.js} +2 -2
- package/dist/prompt-source-mcp.js +1 -1
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
package/README.md
CHANGED
|
@@ -183,8 +183,13 @@ Independent review can classify a source as an authored definition, builder,
|
|
|
183
183
|
prompt transport, runtime context, non-prompt, or uncertain even when the
|
|
184
184
|
resolver stored it as text, messages, template, or builder. Usage is tracked
|
|
185
185
|
separately as active, conditional, display-only, or unknown, with an endpoint
|
|
186
|
-
verification flag
|
|
187
|
-
definition or builder
|
|
186
|
+
verification flag. Automatic code/configuration registration requires an authored
|
|
187
|
+
definition or builder with independently reviewed active or conditional model use
|
|
188
|
+
and a local consumer citation. Custom framework hooks can qualify without a
|
|
189
|
+
recognized SDK binding. Consumer relationships are semantic reviewer judgments,
|
|
190
|
+
not deterministic dataflow proofs; locally valid citations alone do not establish
|
|
191
|
+
model use. The separate `endpointVerified` flag reports SDK provenance. Display-only sources stay visible as related; sources
|
|
192
|
+
with unknown use remain pending. Helpers that forward prompt configuration or carry
|
|
188
193
|
runtime context are retained as related discovery candidates and diagnostics,
|
|
189
194
|
but are not synced as prompt sources. Builder provenance remains the source
|
|
190
195
|
mapping and dependency evidence, so discovery does not claim complete
|
|
@@ -195,6 +200,18 @@ surrounding relationships. Its definition citations, source hash, and source
|
|
|
195
200
|
stability are checked locally. Malformed review JSON gets one format-only repair
|
|
196
201
|
attempt; a repair that changes an already stated role or decision stays pending.
|
|
197
202
|
|
|
203
|
+
Before uploading, sync checks statically resolvable JavaScript/TypeScript lookups
|
|
204
|
+
into the repository's `.moda/prompts.lock.json`. A missing key stops the upload
|
|
205
|
+
and reports its source location. Preserve a stable runtime key by assigning it
|
|
206
|
+
to the intended source mapping, or update the lookup to the selected mapping key.
|
|
207
|
+
Dynamic lookups and other languages are not exhaustively checked; attribution
|
|
208
|
+
coverage remains partial. A real sync with candidates but no eligible sources
|
|
209
|
+
exits nonzero after printing discovery diagnostics; dry runs remain previews.
|
|
210
|
+
|
|
211
|
+
Configured mappings remain authoritative. To clean up sources previously
|
|
212
|
+
registered in error, remove their entries from `.moda/prompts.yml` and sync with
|
|
213
|
+
`--allow-untrack`. This removes local tracking, not historical registry versions.
|
|
214
|
+
|
|
198
215
|
You can also configure `.moda/prompts.yml` directly:
|
|
199
216
|
|
|
200
217
|
```yaml
|
|
@@ -183017,6 +183017,7 @@ function reviewEvidence(rootDir, source, evidence) {
|
|
|
183017
183017
|
if (!evidence.length)
|
|
183018
183018
|
return { valid: false, endpointVerified: false, reason: "Reviewer supplied no evidence" };
|
|
183019
183019
|
try {
|
|
183020
|
+
const endpoints = [];
|
|
183020
183021
|
for (const item of evidence) {
|
|
183021
183022
|
let text;
|
|
183022
183023
|
try {
|
|
@@ -183032,20 +183033,21 @@ function reviewEvidence(rootDir, source, evidence) {
|
|
|
183032
183033
|
continue;
|
|
183033
183034
|
return { valid: false, endpointVerified: false, reason: `Invalid definition evidence line ${item.path}:${item.line}` };
|
|
183034
183035
|
}
|
|
183036
|
+
if (item.kind === "model_endpoint" && item.reason.trim())
|
|
183037
|
+
endpoints.push(item);
|
|
183035
183038
|
}
|
|
183036
183039
|
const definition = evidence.some((item) => item.kind === "definition" && item.path === source.path && isSelectedDefinitionCitation(rootDir, source, item.line));
|
|
183037
183040
|
if (!definition) {
|
|
183038
183041
|
return { valid: false, endpointVerified: false, reason: "Reviewer evidence lacks a citation inside the selected definition" };
|
|
183039
183042
|
}
|
|
183040
|
-
const
|
|
183041
|
-
const endpointVerified = endpoint.some((item) => {
|
|
183043
|
+
const endpointVerified = endpoints.some((item) => {
|
|
183042
183044
|
try {
|
|
183043
183045
|
return proveSink(rootDir, { path: item.path, line: item.line, api: "" }) === "constructed";
|
|
183044
183046
|
} catch {
|
|
183045
183047
|
return false;
|
|
183046
183048
|
}
|
|
183047
183049
|
});
|
|
183048
|
-
return { valid: true, endpointVerified };
|
|
183050
|
+
return { valid: true, endpointVerified, reviewedConsumerCited: endpoints.length > 0 };
|
|
183049
183051
|
} catch (error) {
|
|
183050
183052
|
return { valid: false, endpointVerified: false, reason: error instanceof Error ? error.message : String(error) };
|
|
183051
183053
|
}
|
|
@@ -183065,7 +183067,8 @@ function promptVerificationInstruction(source, sourceHash, definition) {
|
|
|
183065
183067
|
"Classify helpers by the value they carry, not the storage mechanism: persisting/retrieving/forwarding instruction settings, prompt definitions, or tool descriptors is prompt_transport; retrieving/formatting runtime facts, memory, documents, tool results, or ordinary user data is runtime_context. Neither operation alone authors or composes instructions.",
|
|
183066
183068
|
"For a builder verdict, identify an actual instruction-composition operation owned by the selection: combining instruction fragments, assembling instructional messages, or rendering an instruction template with inputs. Merely passing an already-built value as a call argument, storing/retrieving it, or returning an identifier is not composition. A wrapper forwarding a prompt/tool descriptor remains transport or runtime_context unless it performs its own instruction composition. State the concrete operation in the definition evidence reason.",
|
|
183067
183069
|
"A selected definition citation is required for every positive role. An endpoint witness is optional for role evidence and independently determines usage. UI labels/layout copy, retrieval output, ordinary configuration, and response adapters are non_prompt. Prompt presets, display-only instruction copies, tool/schema descriptions, and instruction spans remain authored when the selected definition owns that text. For mixed functions, authored instruction operations take precedence over transport/context operations; inspect the whole selected body.",
|
|
183068
|
-
"usage.status
|
|
183070
|
+
"Instruction ownership alone does not qualify a source for automatic registration. Report usage.status active or conditional only after tracing this selected source to a concrete model input, including through imported builders, stored configuration, or a custom framework hook such as a returned system field. Cite that consumer as model_endpoint and explain the value flow from this source. A recognized SDK is not required for semantic usage; endpointVerified is computed separately by the local checker.",
|
|
183071
|
+
"Display copies, preset chips that only prefill an editor, and forms that concatenate or save editor state are display_only unless you trace the resulting value to an actual model consumer. Possible future use or the ability to click a UI control is not conditional model use. If the code is inconclusive, use unknown. Keep these definitions visible with their true semantic role; do not invent a model-use path to make them eligible.",
|
|
183069
183072
|
"For lifecycle hooks that return a system/instructions field, cite the returned field as an endpoint witness only. If the selected hook only delegates to a separate builder, classify it as transport; if its own body authors instruction spans, authored role takes precedence.",
|
|
183070
183073
|
`Candidate: ${JSON.stringify(source)}`,
|
|
183071
183074
|
`Expected source hash: ${sourceHash}`,
|
|
@@ -183076,6 +183079,7 @@ function promptVerificationInstruction(source, sourceHash, definition) {
|
|
|
183076
183079
|
...definition?.declarationKind === "class" ? ["This selected definition is a class container. Do not inherit roles from separately addressable member methods: map the owning method instead. Only class-owned instruction initializers justify an authored role on the class itself; otherwise classify the container as non_prompt or uncertain and explain which members own the behavior."] : [],
|
|
183077
183080
|
"Return exactly one JSON object between MODA_PROMPT_VERIFY_BEGIN and MODA_PROMPT_VERIFY_END:",
|
|
183078
183081
|
'{"verified":true,"role":"authored_definition","usage":{"status":"unknown","reason":"No trusted endpoint established","endpointVerified":false},"sourceHash":"...","evidence":[{"path":"src/agent.ts","line":1,"kind":"definition","reason":"..."}],"reason":"..."}',
|
|
183082
|
+
"usage.status must be exactly one of: active, conditional, display_only, unknown. Use display_only (with an underscore) for editor-only or display-only instruction text. Do not emit inactive, none, or display-only. endpointVerified must be false in your response; only the local checker establishes that flag.",
|
|
183079
183083
|
"Every response must include verified, role, sourceHash, evidence, and reason. role is authored_definition, builder, prompt_transport, runtime_context, non_prompt, or uncertain. Evidence kind is definition or model_endpoint and line is positive. Cite the endpoint expression START line when present."
|
|
183080
183084
|
].join(`
|
|
183081
183085
|
`);
|
|
@@ -183170,7 +183174,7 @@ ${output}` : "";
|
|
|
183170
183174
|
if (!reviewed.verified || reviewed.role === "uncertain")
|
|
183171
183175
|
return pending(reviewed.reason, reviewed.evidence, reviewed.role, normalizeUsage(undefined, false));
|
|
183172
183176
|
const evidence = reviewEvidence(rootDir, source, reviewed.evidence);
|
|
183173
|
-
const usage = normalizeUsage(reviewed.usage, evidence.endpointVerified);
|
|
183177
|
+
const usage = normalizeUsage(reviewed.usage, evidence.endpointVerified, evidence.reviewedConsumerCited);
|
|
183174
183178
|
if (!evidence.valid)
|
|
183175
183179
|
return pending(evidence.reason ?? "Reviewer evidence is invalid", reviewed.evidence, reviewed.role, usage);
|
|
183176
183180
|
return { status: "verified", reason: reviewed.reason, evidence: reviewed.evidence, sourceHash: checked.sourceHash, role: reviewed.role, usage };
|
|
@@ -183199,11 +183203,11 @@ function extractJudgment(output) {
|
|
|
183199
183203
|
return;
|
|
183200
183204
|
}
|
|
183201
183205
|
}
|
|
183202
|
-
function normalizeUsage(reviewed, endpointVerified) {
|
|
183206
|
+
function normalizeUsage(reviewed, endpointVerified, reviewedConsumerCited = false) {
|
|
183203
183207
|
if (!reviewed)
|
|
183204
183208
|
return { status: "unknown", reason: "Reviewer did not provide explicit usage status", endpointVerified };
|
|
183205
|
-
if (reviewed.status === "active" && !
|
|
183206
|
-
return { status: "unknown", reason: "
|
|
183209
|
+
if ((reviewed.status === "active" || reviewed.status === "conditional") && !reviewedConsumerCited)
|
|
183210
|
+
return { status: "unknown", reason: "Model usage requires reviewer evidence at a valid model-input source location", endpointVerified: false };
|
|
183207
183211
|
return { ...reviewed, endpointVerified };
|
|
183208
183212
|
}
|
|
183209
183213
|
|
|
@@ -183445,9 +183449,18 @@ async function investigateHarnessPrompts(options) {
|
|
|
183445
183449
|
candidate.role = decision.role;
|
|
183446
183450
|
if (decision.usage)
|
|
183447
183451
|
candidate.usage = decision.usage;
|
|
183448
|
-
if (decision.status === "verified" &&
|
|
183449
|
-
candidate.status = "
|
|
183450
|
-
|
|
183452
|
+
if (decision.status === "verified" && decision.usage?.status === "display_only") {
|
|
183453
|
+
candidate.status = "related";
|
|
183454
|
+
candidate.reason = `Display-only source is visible in discovery but is not eligible for automatic registration. ${decision.reason}`;
|
|
183455
|
+
related.push(candidate);
|
|
183456
|
+
} else if (decision.status === "verified" && (decision.role === "authored_definition" || decision.role === "builder")) {
|
|
183457
|
+
if (decision.usage?.status === "active" || decision.usage?.status === "conditional")
|
|
183458
|
+
candidate.status = "accepted";
|
|
183459
|
+
else {
|
|
183460
|
+
candidate.status = "pending";
|
|
183461
|
+
candidate.reason = `Instruction ownership is verified, but model use is unresolved. ${decision.reason}`;
|
|
183462
|
+
}
|
|
183463
|
+
} else if (decision.status === "verified" && (decision.role === "prompt_transport" || decision.role === "runtime_context")) {
|
|
183451
183464
|
candidate.status = "related";
|
|
183452
183465
|
related.push(candidate);
|
|
183453
183466
|
} else
|
|
@@ -184271,7 +184284,7 @@ async function runHarnessCommand(context) {
|
|
|
184271
184284
|
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.");
|
|
184272
184285
|
}
|
|
184273
184286
|
if (context.flags["github-actions"] === "true") {
|
|
184274
|
-
const { runGithubActionsAnalyze } = await import("./harness-github-actions-
|
|
184287
|
+
const { runGithubActionsAnalyze } = await import("./harness-github-actions-xk7n788g.js");
|
|
184275
184288
|
const result = await runGithubActionsAnalyze(rootDir, {
|
|
184276
184289
|
writeReport: (report2) => {
|
|
184277
184290
|
const normalized = normalizeHarnessReport(report2);
|
|
@@ -188281,4 +188294,4 @@ function hashText(text) {
|
|
|
188281
188294
|
return createHash4("sha256").update(text).digest("hex");
|
|
188282
188295
|
}
|
|
188283
188296
|
|
|
188284
|
-
export { ApiError, callDataAPI, callControlAPI, getApiRequestCount, resetApiRequestCount, $parseDocument, $stringify, inspectCodeSelectors, inspectPythonSelectors, resolvePromptSource, shouldColorTerminalOutput, terminalStyles, stripAnsi2 as stripAnsi, renderMarkdownForTerminal, HARNESS_REPORT_PATH, HARNESS_REPORT_APPROVAL_PATH, HARNESS_ANALYZE_CONCERNS, validateHarnessReport, readHarnessReport, hashHarnessReport, hashStableJson, startRemoteAnalyze, pollRemoteAnalyzeUntilDone, 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 };
|
|
188297
|
+
export { ApiError, callDataAPI, callControlAPI, getApiRequestCount, resetApiRequestCount, $parseDocument, $stringify, require_typescript, inspectCodeSelectors, inspectPythonSelectors, resolvePromptSource, shouldColorTerminalOutput, terminalStyles, stripAnsi2 as stripAnsi, renderMarkdownForTerminal, HARNESS_REPORT_PATH, HARNESS_REPORT_APPROVAL_PATH, HARNESS_ANALYZE_CONCERNS, validateHarnessReport, readHarnessReport, hashHarnessReport, hashStableJson, startRemoteAnalyze, pollRemoteAnalyzeUntilDone, 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 };
|
|
@@ -3,12 +3,15 @@ import {
|
|
|
3
3
|
$stringify,
|
|
4
4
|
callControlAPI,
|
|
5
5
|
callDataAPI,
|
|
6
|
+
inventoryFiles,
|
|
6
7
|
readHarnessSyncState,
|
|
7
8
|
renderDoctorHuman,
|
|
8
9
|
renderStatusHuman,
|
|
10
|
+
require_typescript,
|
|
9
11
|
resolvePromptSource,
|
|
12
|
+
safePromptEvidencePath,
|
|
10
13
|
scanHarness
|
|
11
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-8q7jffnj.js";
|
|
12
15
|
import {
|
|
13
16
|
isAuthSessionValid,
|
|
14
17
|
loadAuthSession
|
|
@@ -5547,7 +5550,7 @@ import {
|
|
|
5547
5550
|
rmSync,
|
|
5548
5551
|
writeFileSync as writeFileSync2
|
|
5549
5552
|
} from "node:fs";
|
|
5550
|
-
import { dirname, isAbsolute as isAbsolute3, join, relative, resolve as
|
|
5553
|
+
import { dirname as dirname2, isAbsolute as isAbsolute3, join, relative, resolve as resolve4 } from "node:path";
|
|
5551
5554
|
|
|
5552
5555
|
// src/prompts-ab.ts
|
|
5553
5556
|
import { existsSync } from "node:fs";
|
|
@@ -6030,6 +6033,131 @@ function parsePositiveInt2(raw, fallback, max) {
|
|
|
6030
6033
|
return Math.min(n, max);
|
|
6031
6034
|
}
|
|
6032
6035
|
|
|
6036
|
+
// src/prompt-attribution.ts
|
|
6037
|
+
var import_typescript = __toESM(require_typescript(), 1);
|
|
6038
|
+
import { dirname, extname, resolve as resolve3 } from "node:path";
|
|
6039
|
+
function checkPromptAttribution(rootDir, keys) {
|
|
6040
|
+
const result = { references: [], coverage: "partial", issues: [] };
|
|
6041
|
+
const known = new Set(keys), lock = resolve3(rootDir, ".moda/prompts.lock.json");
|
|
6042
|
+
let files;
|
|
6043
|
+
try {
|
|
6044
|
+
files = inventoryFiles(rootDir, []);
|
|
6045
|
+
} catch (error) {
|
|
6046
|
+
result.issues.push({ path: ".", reason: `Attribution scan incomplete: ${error instanceof Error ? error.message : String(error)}` });
|
|
6047
|
+
return result;
|
|
6048
|
+
}
|
|
6049
|
+
for (const file of files) {
|
|
6050
|
+
if (![".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(extname(file.path)) || !file.text?.includes("prompts.lock.json"))
|
|
6051
|
+
continue;
|
|
6052
|
+
if (/(^|\/)(?:tests?|__tests__|fixtures?)(\/|$)|\.(?:test|spec)\.[^.]+$/.test(file.path))
|
|
6053
|
+
continue;
|
|
6054
|
+
try {
|
|
6055
|
+
const absolute = safePromptEvidencePath(rootDir, file.path);
|
|
6056
|
+
const program = import_typescript.default.createProgram([absolute], { noResolve: true, noLib: true, types: [], allowJs: true });
|
|
6057
|
+
const sf = program.getSourceFile(absolute);
|
|
6058
|
+
if (!sf || program.getSyntacticDiagnostics(sf).length) {
|
|
6059
|
+
result.issues.push({ path: file.path, reason: "Attribution source could not be parsed" });
|
|
6060
|
+
continue;
|
|
6061
|
+
}
|
|
6062
|
+
const checker = program.getTypeChecker();
|
|
6063
|
+
const declaration = (node) => {
|
|
6064
|
+
const all = checker.getSymbolAtLocation(node)?.declarations;
|
|
6065
|
+
return all?.length === 1 ? all[0] : undefined;
|
|
6066
|
+
};
|
|
6067
|
+
const imported = (node) => {
|
|
6068
|
+
if (import_typescript.default.isImportSpecifier(node) && node.isTypeOnly)
|
|
6069
|
+
return false;
|
|
6070
|
+
let parent = node;
|
|
6071
|
+
while (parent && !import_typescript.default.isImportDeclaration(parent))
|
|
6072
|
+
parent = parent.parent;
|
|
6073
|
+
return !!parent && import_typescript.default.isImportDeclaration(parent) && !parent.importClause?.isTypeOnly && import_typescript.default.isStringLiteral(parent.moduleSpecifier) && parent.moduleSpecifier.text.startsWith(".") && resolve3(dirname(absolute), parent.moduleSpecifier.text) === lock;
|
|
6074
|
+
};
|
|
6075
|
+
const initializer = (node) => {
|
|
6076
|
+
const decl = declaration(node);
|
|
6077
|
+
return decl && import_typescript.default.isVariableDeclaration(decl) && import_typescript.default.isVariableDeclarationList(decl.parent) && !!(decl.parent.flags & import_typescript.default.NodeFlags.Const) ? decl.initializer : undefined;
|
|
6078
|
+
};
|
|
6079
|
+
const unwrap = (node) => {
|
|
6080
|
+
while (import_typescript.default.isParenthesizedExpression(node) || import_typescript.default.isAsExpression(node) || import_typescript.default.isTypeAssertionExpression(node) || import_typescript.default.isNonNullExpression(node))
|
|
6081
|
+
node = node.expression;
|
|
6082
|
+
return node;
|
|
6083
|
+
};
|
|
6084
|
+
const literal = (expression, seen = new Set) => {
|
|
6085
|
+
const node = unwrap(expression);
|
|
6086
|
+
if (seen.has(node))
|
|
6087
|
+
return;
|
|
6088
|
+
seen.add(node);
|
|
6089
|
+
if (import_typescript.default.isStringLiteral(node) || import_typescript.default.isNoSubstitutionTemplateLiteral(node))
|
|
6090
|
+
return node.text;
|
|
6091
|
+
if (import_typescript.default.isIdentifier(node)) {
|
|
6092
|
+
const init = initializer(node);
|
|
6093
|
+
return init ? literal(init, seen) : undefined;
|
|
6094
|
+
}
|
|
6095
|
+
if (import_typescript.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript.default.SyntaxKind.PlusToken) {
|
|
6096
|
+
const a = literal(node.left, new Set(seen)), b = literal(node.right, new Set(seen));
|
|
6097
|
+
return a !== undefined && b !== undefined ? a + b : undefined;
|
|
6098
|
+
}
|
|
6099
|
+
};
|
|
6100
|
+
const lockPath = (node) => import_typescript.default.isStringLiteral(node) && node.text.startsWith(".") && resolve3(dirname(absolute), node.text) === lock;
|
|
6101
|
+
const isConstBinding = (node) => import_typescript.default.isVariableDeclarationList(node.parent) && !!(node.parent.flags & import_typescript.default.NodeFlags.Const);
|
|
6102
|
+
const isLock = (expression, seen = new Set) => {
|
|
6103
|
+
const node = unwrap(expression);
|
|
6104
|
+
if (seen.has(node))
|
|
6105
|
+
return false;
|
|
6106
|
+
seen.add(node);
|
|
6107
|
+
if (import_typescript.default.isCallExpression(node) && import_typescript.default.isIdentifier(node.expression) && node.expression.text === "require" && !declaration(node.expression) && node.arguments.length === 1)
|
|
6108
|
+
return lockPath(node.arguments[0]);
|
|
6109
|
+
if (!import_typescript.default.isIdentifier(node))
|
|
6110
|
+
return false;
|
|
6111
|
+
const decl = declaration(node);
|
|
6112
|
+
if (decl && (import_typescript.default.isImportClause(decl) || import_typescript.default.isNamespaceImport(decl)))
|
|
6113
|
+
return imported(decl);
|
|
6114
|
+
const init = initializer(node);
|
|
6115
|
+
return !!init && isLock(init, seen);
|
|
6116
|
+
};
|
|
6117
|
+
const isTable = (expression, seen = new Set) => {
|
|
6118
|
+
const node = unwrap(expression);
|
|
6119
|
+
if (seen.has(node))
|
|
6120
|
+
return false;
|
|
6121
|
+
seen.add(node);
|
|
6122
|
+
if (import_typescript.default.isPropertyAccessExpression(node))
|
|
6123
|
+
return node.name.text === "prompts" && isLock(node.expression);
|
|
6124
|
+
if (import_typescript.default.isElementAccessExpression(node))
|
|
6125
|
+
return literal(node.argumentExpression) === "prompts" && isLock(node.expression);
|
|
6126
|
+
if (import_typescript.default.isIdentifier(node)) {
|
|
6127
|
+
const decl = declaration(node);
|
|
6128
|
+
if (decl && import_typescript.default.isBindingElement(decl) && import_typescript.default.isObjectBindingPattern(decl.parent) && import_typescript.default.isVariableDeclaration(decl.parent.parent)) {
|
|
6129
|
+
const owner = decl.parent.parent;
|
|
6130
|
+
const name = decl.propertyName ?? decl.name;
|
|
6131
|
+
if (!decl.dotDotDotToken && !decl.initializer && (import_typescript.default.isIdentifier(name) || import_typescript.default.isStringLiteral(name)) && name.text === "prompts" && isConstBinding(owner) && owner.initializer)
|
|
6132
|
+
return isLock(owner.initializer);
|
|
6133
|
+
}
|
|
6134
|
+
if (decl && import_typescript.default.isImportSpecifier(decl))
|
|
6135
|
+
return (decl.propertyName?.text ?? decl.name.text) === "prompts" && imported(decl);
|
|
6136
|
+
const init = initializer(node);
|
|
6137
|
+
return !!init && isTable(init, seen);
|
|
6138
|
+
}
|
|
6139
|
+
return false;
|
|
6140
|
+
};
|
|
6141
|
+
const visit = (node) => {
|
|
6142
|
+
if ((import_typescript.default.isElementAccessExpression(node) || import_typescript.default.isPropertyAccessExpression(node)) && isTable(node.expression)) {
|
|
6143
|
+
const key = import_typescript.default.isElementAccessExpression(node) ? literal(node.argumentExpression) : node.name.text;
|
|
6144
|
+
result.references.push({
|
|
6145
|
+
path: file.path,
|
|
6146
|
+
line: sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1,
|
|
6147
|
+
key,
|
|
6148
|
+
status: key === undefined ? "unresolved" : known.has(key) ? "mapped" : "missing"
|
|
6149
|
+
});
|
|
6150
|
+
}
|
|
6151
|
+
import_typescript.default.forEachChild(node, visit);
|
|
6152
|
+
};
|
|
6153
|
+
visit(sf);
|
|
6154
|
+
} catch (error) {
|
|
6155
|
+
result.issues.push({ path: file.path, reason: error instanceof Error ? error.message : String(error) });
|
|
6156
|
+
}
|
|
6157
|
+
}
|
|
6158
|
+
return result;
|
|
6159
|
+
}
|
|
6160
|
+
|
|
6033
6161
|
// src/prompts.ts
|
|
6034
6162
|
var MODA_DIR = ".moda";
|
|
6035
6163
|
var MANIFEST_PATH = join(MODA_DIR, "prompts.yml");
|
|
@@ -6101,8 +6229,8 @@ async function runPromptsCommand(input, legacyFlags, legacyProfileOptions) {
|
|
|
6101
6229
|
}
|
|
6102
6230
|
async function initPrompts(options = {}) {
|
|
6103
6231
|
const cwd = process.cwd();
|
|
6104
|
-
const manifestPath =
|
|
6105
|
-
const lockPath =
|
|
6232
|
+
const manifestPath = resolve4(cwd, MANIFEST_PATH);
|
|
6233
|
+
const lockPath = resolve4(cwd, LOCK_PATH);
|
|
6106
6234
|
if (existsSync2(MODA_DIR) && lstatSync(MODA_DIR).isSymbolicLink())
|
|
6107
6235
|
throw new Error(".moda must not be a symlink.");
|
|
6108
6236
|
mkdirSync(MODA_DIR, { recursive: true });
|
|
@@ -6151,8 +6279,8 @@ async function syncPrompts(flags, profileOptions, context) {
|
|
|
6151
6279
|
async function runPromptSync(flags, profileOptions, options = {}) {
|
|
6152
6280
|
if (flags["dry-run"] === "true")
|
|
6153
6281
|
return runPromptSyncExclusive(flags, profileOptions, options);
|
|
6154
|
-
mkdirSync(
|
|
6155
|
-
const syncLock =
|
|
6282
|
+
mkdirSync(dirname2(MANIFEST_PATH), { recursive: true });
|
|
6283
|
+
const syncLock = resolve4(dirname2(MANIFEST_PATH), "prompts.sync.lock");
|
|
6156
6284
|
try {
|
|
6157
6285
|
mkdirSync(syncLock);
|
|
6158
6286
|
} catch (error) {
|
|
@@ -6181,7 +6309,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
|
|
|
6181
6309
|
const analyzedDefinitions = new Map;
|
|
6182
6310
|
if (flags["no-analyze"] !== "true") {
|
|
6183
6311
|
options.onProgress?.("Analyzing prompt sources before sync.");
|
|
6184
|
-
const { analyzeHarnessPrompts } = await import("./harness-
|
|
6312
|
+
const { analyzeHarnessPrompts } = await import("./harness-1xj4f0qp.js");
|
|
6185
6313
|
const result = await analyzeHarnessPrompts({
|
|
6186
6314
|
rootDir: process.cwd(),
|
|
6187
6315
|
existing: established.flatMap((prompt) => prompt.sourceDefinition ? [prompt.sourceDefinition.source] : []),
|
|
@@ -6190,10 +6318,10 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
|
|
|
6190
6318
|
dryRun: flags["dry-run"] === "true",
|
|
6191
6319
|
onProgress: options.onProgress
|
|
6192
6320
|
});
|
|
6193
|
-
const legacyPaths = new Set(established.filter((prompt) => !prompt.sourceDefinition).map((prompt) =>
|
|
6321
|
+
const legacyPaths = new Set(established.filter((prompt) => !prompt.sourceDefinition).map((prompt) => resolve4(prompt.sourcePath)));
|
|
6194
6322
|
const exclusions = manifest.promptPaths.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
6195
|
-
const excludedPaths = new Set(exclusions.length ? import_fast_glob.default.sync(exclusions, { cwd: process.cwd(), onlyFiles: true, dot: true, followSymbolicLinks: false }).map((path) =>
|
|
6196
|
-
const found = result.sources.filter((source) => !legacyPaths.has(
|
|
6323
|
+
const excludedPaths = new Set(exclusions.length ? import_fast_glob.default.sync(exclusions, { cwd: process.cwd(), onlyFiles: true, dot: true, followSymbolicLinks: false }).map((path) => resolve4(path)) : []);
|
|
6324
|
+
const found = result.sources.filter((source) => !legacyPaths.has(resolve4(source.path)) && !excludedPaths.has(resolve4(source.path)));
|
|
6197
6325
|
for (const source of found) {
|
|
6198
6326
|
const analyzed = result.resolved.find((item) => item.key === source.key);
|
|
6199
6327
|
if (!analyzed)
|
|
@@ -6209,6 +6337,11 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
|
|
|
6209
6337
|
const mergedSources = mergePromptSources(manifest.sources, extraSources);
|
|
6210
6338
|
const manifestUpdate = stableJson(mergedSources) === stableJson(mergePromptSources(manifest.sources, [])) ? undefined : $stringify({ version: 2, prompt_paths: manifest.promptPaths, sources: mergedSources });
|
|
6211
6339
|
const prompts = discoverPrompts(extraSources);
|
|
6340
|
+
const attribution = checkPromptAttribution(process.cwd(), prompts.map((prompt) => prompt.key));
|
|
6341
|
+
const brokenAttribution = attribution.references.filter((reference) => reference.status === "missing");
|
|
6342
|
+
if (brokenAttribution.length) {
|
|
6343
|
+
throw new Error(`Prompt attribution keys are absent from this sync: ${brokenAttribution.map((reference) => `'${reference.key}' at ${reference.path}:${reference.line}`).join(", ")}. Map the referenced key to its verified source in .moda/prompts.yml, or update the runtime lookup to the intended mapped key. No prompt versions were uploaded.`);
|
|
6344
|
+
}
|
|
6212
6345
|
for (const prompt of prompts) {
|
|
6213
6346
|
const analyzed = analyzedDefinitions.get(prompt.key);
|
|
6214
6347
|
if (analyzed && analyzed !== stableJson(prompt.sourceDefinition))
|
|
@@ -6226,7 +6359,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
|
|
|
6226
6359
|
if (prompts.length === 0) {
|
|
6227
6360
|
if (!dryRun && flags["allow-untrack"] === "true")
|
|
6228
6361
|
writeLock([], []);
|
|
6229
|
-
return { synced: [], dryRun, discovery };
|
|
6362
|
+
return { synced: [], dryRun, discovery, attribution };
|
|
6230
6363
|
}
|
|
6231
6364
|
const signature = stableJson(prompts);
|
|
6232
6365
|
const response = await callControlAPI("/prompts/sync", {
|
|
@@ -6258,7 +6391,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
|
|
|
6258
6391
|
atomicWrite(MANIFEST_PATH, manifestUpdate);
|
|
6259
6392
|
writeLock(prompts, synced);
|
|
6260
6393
|
}
|
|
6261
|
-
return { synced: response.synced ?? [], dryRun, discovery };
|
|
6394
|
+
return { synced: response.synced ?? [], dryRun, discovery, attribution };
|
|
6262
6395
|
}
|
|
6263
6396
|
function writePromptSyncProgress(message, context, quiet = false) {
|
|
6264
6397
|
if (quiet || context?.quiet)
|
|
@@ -6277,12 +6410,17 @@ async function syncPromptsOnce(flags, profileOptions, context) {
|
|
|
6277
6410
|
const payload = {
|
|
6278
6411
|
synced: result.synced,
|
|
6279
6412
|
discovery: result.discovery,
|
|
6413
|
+
attribution: result.attribution,
|
|
6280
6414
|
lockfile: result.dryRun ? undefined : LOCK_PATH
|
|
6281
6415
|
};
|
|
6282
6416
|
if (context)
|
|
6283
6417
|
context.output.writeData(payload);
|
|
6284
6418
|
else
|
|
6285
6419
|
printJson(payload);
|
|
6420
|
+
if (!result.dryRun && result.synced.length === 0 && result.discovery?.candidates?.length) {
|
|
6421
|
+
writePromptSyncProgress("No eligible prompt sources were synced. Review discovery.pending and discovery.related.", context, flags.quiet === "true");
|
|
6422
|
+
process.exitCode = 1;
|
|
6423
|
+
}
|
|
6286
6424
|
}
|
|
6287
6425
|
async function watchPromptSync(flags, profileOptions) {
|
|
6288
6426
|
await syncPromptsOnce(flags, profileOptions);
|
|
@@ -6298,7 +6436,7 @@ async function watchPromptSync(flags, profileOptions) {
|
|
|
6298
6436
|
await syncPromptsOnce({ ...flags, watch: "false", "no-analyze": "true" }, profileOptions);
|
|
6299
6437
|
}
|
|
6300
6438
|
}
|
|
6301
|
-
await new Promise((
|
|
6439
|
+
await new Promise((resolve5) => setTimeout(resolve5, intervalMs));
|
|
6302
6440
|
}
|
|
6303
6441
|
}
|
|
6304
6442
|
async function promotePrompt(positionals, flags, profileOptions, context) {
|
|
@@ -6362,7 +6500,7 @@ function discoverPrompts(extraSources = []) {
|
|
|
6362
6500
|
const positive = pattern.startsWith("!") ? pattern.slice(1) : pattern;
|
|
6363
6501
|
if (isAbsolute3(positive) || positive.split(/[\\/]/).includes(".."))
|
|
6364
6502
|
throw new Error(`Prompt pattern must stay inside the repository: ${pattern}`);
|
|
6365
|
-
if (!pattern.startsWith("!") && !import_fast_glob.default.isDynamicPattern(pattern) && !existsSync2(
|
|
6503
|
+
if (!pattern.startsWith("!") && !import_fast_glob.default.isDynamicPattern(pattern) && !existsSync2(resolve4(root, pattern))) {
|
|
6366
6504
|
throw new Error(`Configured prompt file is missing: ${pattern}`);
|
|
6367
6505
|
}
|
|
6368
6506
|
}
|
|
@@ -6377,11 +6515,11 @@ function discoverPrompts(extraSources = []) {
|
|
|
6377
6515
|
const sources = new Map(manifest.sources.map((source) => [source.key, source]));
|
|
6378
6516
|
for (const source of extraSources)
|
|
6379
6517
|
sources.set(source.key, source);
|
|
6380
|
-
const selectedPaths = new Set([...sources.values()].map((source) =>
|
|
6381
|
-
const prompts = paths.filter((path) => !selectedPaths.has(
|
|
6518
|
+
const selectedPaths = new Set([...sources.values()].map((source) => resolve4(root, source.path)));
|
|
6519
|
+
const prompts = paths.filter((path) => !selectedPaths.has(resolve4(root, path))).map((path) => {
|
|
6382
6520
|
assertContainedSource(root, path);
|
|
6383
6521
|
if (/\.prompt\.(md|json)$/i.test(path))
|
|
6384
|
-
return parsePromptFile(
|
|
6522
|
+
return parsePromptFile(resolve4(root, path));
|
|
6385
6523
|
return normalizePrompt(resolvePromptSource(root, { key: keyFromPath(path), path }));
|
|
6386
6524
|
});
|
|
6387
6525
|
for (const source of sources.values())
|
|
@@ -6395,15 +6533,15 @@ function discoverPrompts(extraSources = []) {
|
|
|
6395
6533
|
return prompts.sort((a, b) => a.key.localeCompare(b.key));
|
|
6396
6534
|
}
|
|
6397
6535
|
function assertContainedSource(root, path) {
|
|
6398
|
-
const abs =
|
|
6536
|
+
const abs = resolve4(root, path);
|
|
6399
6537
|
const rel = relative(realpathSync(root), realpathSync(abs));
|
|
6400
6538
|
if (rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute3(rel))
|
|
6401
6539
|
throw new Error(`Prompt source escapes repository: ${path}`);
|
|
6402
6540
|
let cursor = abs;
|
|
6403
|
-
while (cursor !==
|
|
6541
|
+
while (cursor !== resolve4(root)) {
|
|
6404
6542
|
if (lstatSync(cursor).isSymbolicLink())
|
|
6405
6543
|
throw new Error(`Prompt source uses a symlink: ${path}`);
|
|
6406
|
-
const next =
|
|
6544
|
+
const next = dirname2(cursor);
|
|
6407
6545
|
if (next === cursor)
|
|
6408
6546
|
throw new Error(`Prompt source escapes repository: ${path}`);
|
|
6409
6547
|
cursor = next;
|
|
@@ -6520,7 +6658,7 @@ function readManifest() {
|
|
|
6520
6658
|
function readHarnessSources(reportPath) {
|
|
6521
6659
|
const selected = reportPath === "true" ? ".moda/harness-report.json" : reportPath;
|
|
6522
6660
|
assertContainedSource(process.cwd(), selected);
|
|
6523
|
-
const report = JSON.parse(readFileSync(
|
|
6661
|
+
const report = JSON.parse(readFileSync(resolve4(selected), "utf8"));
|
|
6524
6662
|
if (!Array.isArray(report?.graph?.artifacts))
|
|
6525
6663
|
throw new Error("Expected a harness report with graph.artifacts.");
|
|
6526
6664
|
const artifacts = report.graph.artifacts.filter((artifact) => artifact.type === "prompt");
|
|
@@ -6555,8 +6693,8 @@ function mergePromptSources(existingSources, sources) {
|
|
|
6555
6693
|
return [...merged.values()].sort((a, b) => a.key.localeCompare(b.key));
|
|
6556
6694
|
}
|
|
6557
6695
|
function atomicWrite(path, content) {
|
|
6558
|
-
mkdirSync(
|
|
6559
|
-
assertContainedSource(process.cwd(),
|
|
6696
|
+
mkdirSync(dirname2(path), { recursive: true });
|
|
6697
|
+
assertContainedSource(process.cwd(), dirname2(path));
|
|
6560
6698
|
if (existsSync2(path) && lstatSync(path).isSymbolicLink())
|
|
6561
6699
|
throw new Error(`Refusing to overwrite symlink: ${path}`);
|
|
6562
6700
|
const temp = `${path}.${process.pid}.tmp`;
|
|
@@ -6597,7 +6735,7 @@ function writeLock(prompts, synced) {
|
|
|
6597
6735
|
}];
|
|
6598
6736
|
}))
|
|
6599
6737
|
};
|
|
6600
|
-
mkdirSync(
|
|
6738
|
+
mkdirSync(dirname2(LOCK_PATH), { recursive: true });
|
|
6601
6739
|
atomicWrite(LOCK_PATH, `${JSON.stringify(lock, null, 2)}
|
|
6602
6740
|
`);
|
|
6603
6741
|
}
|
|
@@ -6658,10 +6796,10 @@ import { join as join3 } from "node:path";
|
|
|
6658
6796
|
import { confirm } from "@inquirer/prompts";
|
|
6659
6797
|
|
|
6660
6798
|
// src/package-assets.ts
|
|
6661
|
-
import { dirname as
|
|
6799
|
+
import { dirname as dirname3, join as join2 } from "node:path";
|
|
6662
6800
|
import { fileURLToPath } from "node:url";
|
|
6663
6801
|
function packageAssetPath(...parts) {
|
|
6664
|
-
return join2(
|
|
6802
|
+
return join2(dirname3(fileURLToPath(import.meta.url)), "..", ...parts);
|
|
6665
6803
|
}
|
|
6666
6804
|
|
|
6667
6805
|
// src/init/rules.ts
|
|
@@ -6838,7 +6976,7 @@ import {
|
|
|
6838
6976
|
readFileSync as readFileSync5,
|
|
6839
6977
|
writeFileSync as writeFileSync6
|
|
6840
6978
|
} from "node:fs";
|
|
6841
|
-
import { basename, dirname as
|
|
6979
|
+
import { basename, dirname as dirname6, join as join7, relative as relative3 } from "node:path";
|
|
6842
6980
|
|
|
6843
6981
|
// src/skills-manifest.ts
|
|
6844
6982
|
import {
|
|
@@ -6850,7 +6988,7 @@ import {
|
|
|
6850
6988
|
unlinkSync,
|
|
6851
6989
|
writeFileSync as writeFileSync4
|
|
6852
6990
|
} from "node:fs";
|
|
6853
|
-
import { dirname as
|
|
6991
|
+
import { dirname as dirname4, isAbsolute as isAbsolute4, join as join5, normalize, relative as relative2, resolve as resolve5 } from "node:path";
|
|
6854
6992
|
var SKILLS_MANIFEST_PATH = join5(".moda", "skills.yml");
|
|
6855
6993
|
var SKILL_SOURCE_HARNESS = "moda";
|
|
6856
6994
|
var SKILL_SOURCE_INTEGRATION_BUNDLED = "integration-bundled";
|
|
@@ -6910,7 +7048,7 @@ function writeSkillsManifest(cwd, header, records) {
|
|
|
6910
7048
|
]),
|
|
6911
7049
|
""
|
|
6912
7050
|
];
|
|
6913
|
-
mkdirSync3(
|
|
7051
|
+
mkdirSync3(dirname4(manifestPath), { recursive: true });
|
|
6914
7052
|
writeFileSync4(manifestPath, lines.join(`
|
|
6915
7053
|
`));
|
|
6916
7054
|
}
|
|
@@ -6941,7 +7079,7 @@ function pruneManagedSkillPaths(cwd, managedPaths, log) {
|
|
|
6941
7079
|
function pruneEmptyClaudeSkillDir(cwd, relativePath) {
|
|
6942
7080
|
if (!relativePath.startsWith(".claude/skills/") || !relativePath.endsWith("/SKILL.md"))
|
|
6943
7081
|
return;
|
|
6944
|
-
const dir =
|
|
7082
|
+
const dir = dirname4(join5(cwd, relativePath));
|
|
6945
7083
|
try {
|
|
6946
7084
|
if (existsSync5(dir) && readdirSync(dir).length === 0) {
|
|
6947
7085
|
rmdirSync(dir);
|
|
@@ -6949,8 +7087,8 @@ function pruneEmptyClaudeSkillDir(cwd, relativePath) {
|
|
|
6949
7087
|
} catch {}
|
|
6950
7088
|
}
|
|
6951
7089
|
function absoluteManagedPath(cwd, relativePath) {
|
|
6952
|
-
const abs =
|
|
6953
|
-
const root =
|
|
7090
|
+
const abs = resolve5(cwd, relativePath);
|
|
7091
|
+
const root = resolve5(cwd);
|
|
6954
7092
|
const rel = relative2(root, abs);
|
|
6955
7093
|
if (rel.startsWith("..") || isAbsolute4(rel))
|
|
6956
7094
|
return null;
|
|
@@ -7061,7 +7199,7 @@ function yamlQuote(value) {
|
|
|
7061
7199
|
|
|
7062
7200
|
// src/agents-md.ts
|
|
7063
7201
|
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
7064
|
-
import { dirname as
|
|
7202
|
+
import { dirname as dirname5, join as join6 } from "node:path";
|
|
7065
7203
|
var AGENTS_MD_FILENAME = "AGENTS.md";
|
|
7066
7204
|
var FIXES_BLOCK_BEGIN = "<!-- moda:fixes:begin -->";
|
|
7067
7205
|
var FIXES_BLOCK_END = "<!-- moda:fixes:end -->";
|
|
@@ -7107,7 +7245,7 @@ function upsertManagedBlock(existing, block) {
|
|
|
7107
7245
|
}
|
|
7108
7246
|
function writeFileIfChanged(filePath, content) {
|
|
7109
7247
|
try {
|
|
7110
|
-
mkdirSync4(
|
|
7248
|
+
mkdirSync4(dirname5(filePath), { recursive: true });
|
|
7111
7249
|
if (existsSync6(filePath)) {
|
|
7112
7250
|
const current = readFileSync4(filePath, "utf8");
|
|
7113
7251
|
if (current === content)
|
|
@@ -7263,7 +7401,7 @@ function formatRunStatusHuman(run, events) {
|
|
|
7263
7401
|
}
|
|
7264
7402
|
function writeIfChanged(filePath, content) {
|
|
7265
7403
|
try {
|
|
7266
|
-
mkdirSync5(
|
|
7404
|
+
mkdirSync5(dirname6(filePath), { recursive: true });
|
|
7267
7405
|
if (existsSync7(filePath)) {
|
|
7268
7406
|
const current = readFileSync5(filePath, "utf8");
|
|
7269
7407
|
if (current === content)
|
|
@@ -7407,7 +7545,7 @@ function discoverLocalSkills(cwd) {
|
|
|
7407
7545
|
const sourcePath = relative3(cwd, absPath).replace(/\\/g, "/");
|
|
7408
7546
|
if (managed.has(sourcePath))
|
|
7409
7547
|
continue;
|
|
7410
|
-
const key = basename(
|
|
7548
|
+
const key = basename(dirname6(absPath));
|
|
7411
7549
|
if (key === "moda-cli" || !/^[A-Za-z0-9_-]+$/.test(key))
|
|
7412
7550
|
continue;
|
|
7413
7551
|
let content;
|
|
@@ -7555,7 +7693,7 @@ function safeSkillId(skillId) {
|
|
|
7555
7693
|
}
|
|
7556
7694
|
function writeSkillProposalManifest(cwd, proposal, relativePath) {
|
|
7557
7695
|
const manifestPath = join7(cwd, SKILL_PROPOSALS_MANIFEST_PATH);
|
|
7558
|
-
mkdirSync5(
|
|
7696
|
+
mkdirSync5(dirname6(manifestPath), { recursive: true });
|
|
7559
7697
|
const existing = existsSync7(manifestPath) ? readFileSync5(manifestPath, "utf8") : `applied_proposals:
|
|
7560
7698
|
`;
|
|
7561
7699
|
const entry = [
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
runPromptsCommand,
|
|
9
9
|
runSkillsCommand,
|
|
10
10
|
runStatusCommand
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-cagbc7wz.js";
|
|
12
12
|
import {
|
|
13
13
|
ApiError,
|
|
14
14
|
HARNESS_REPORT_APPROVAL_PATH,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
summarizeHarness,
|
|
30
30
|
terminalStyles,
|
|
31
31
|
validateHarnessReport
|
|
32
|
-
} from "./cli-
|
|
32
|
+
} from "./cli-8q7jffnj.js";
|
|
33
33
|
import {
|
|
34
34
|
authFetch,
|
|
35
35
|
clearAuthSession,
|
|
@@ -6580,7 +6580,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6580
6580
|
resetApiRequestCountBeforeRun: true,
|
|
6581
6581
|
telemetry: "result",
|
|
6582
6582
|
handler: async (context) => {
|
|
6583
|
-
const { runInit } = await import("./index-
|
|
6583
|
+
const { runInit } = await import("./index-h6gg66n5.js");
|
|
6584
6584
|
if (context.outputMode === "agent-stream") {
|
|
6585
6585
|
context.output.writeEvent({
|
|
6586
6586
|
event: "started",
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
runPromptSync,
|
|
11
11
|
runSkillSync,
|
|
12
12
|
upsertSkillManifestRecord
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-cagbc7wz.js";
|
|
14
14
|
import {
|
|
15
15
|
codingAgentDisplayName,
|
|
16
16
|
describeCodingAgentEvent,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
runHarnessCommand,
|
|
29
29
|
startRemoteAnalyze,
|
|
30
30
|
stripAnsi
|
|
31
|
-
} from "./cli-
|
|
31
|
+
} from "./cli-8q7jffnj.js";
|
|
32
32
|
import {
|
|
33
33
|
selectTenantAndCreateKey
|
|
34
34
|
} from "./cli-4ycvzfdg.js";
|
package/package.json
CHANGED