snipara-companion 3.2.0 → 3.2.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/dist/index.d.ts +3 -0
- package/dist/index.js +146 -36
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3869,6 +3869,9 @@ interface RuntimeDetectionReport {
|
|
|
3869
3869
|
cliAvailable: boolean;
|
|
3870
3870
|
command?: string;
|
|
3871
3871
|
version?: string;
|
|
3872
|
+
source?: "path" | "workspace_venv";
|
|
3873
|
+
workspacePackageVersion?: string;
|
|
3874
|
+
versionMismatch?: boolean;
|
|
3872
3875
|
};
|
|
3873
3876
|
providerKeys: {
|
|
3874
3877
|
openai: boolean;
|
package/dist/index.js
CHANGED
|
@@ -437,14 +437,14 @@ function resolveProject(opts = {}) {
|
|
|
437
437
|
}
|
|
438
438
|
return { identifier: path2.basename(cwd), source: "cwd-basename" };
|
|
439
439
|
}
|
|
440
|
-
function findUpward(startDir,
|
|
440
|
+
function findUpward(startDir, relative8) {
|
|
441
441
|
let dir = path2.resolve(startDir);
|
|
442
442
|
try {
|
|
443
443
|
dir = fs2.realpathSync(dir);
|
|
444
444
|
} catch {
|
|
445
445
|
}
|
|
446
446
|
while (true) {
|
|
447
|
-
const candidate = path2.join(dir,
|
|
447
|
+
const candidate = path2.join(dir, relative8);
|
|
448
448
|
if (fs2.existsSync(candidate)) return candidate;
|
|
449
449
|
const parent = path2.dirname(dir);
|
|
450
450
|
if (parent === dir) return null;
|
|
@@ -2281,8 +2281,8 @@ function normalizeRelativePath2(value) {
|
|
|
2281
2281
|
return value.split(path5.sep).join("/");
|
|
2282
2282
|
}
|
|
2283
2283
|
function toRepoRelative(repoRoot, absolutePath) {
|
|
2284
|
-
const
|
|
2285
|
-
return normalizeRelativePath2(
|
|
2284
|
+
const relative8 = path5.relative(repoRoot, absolutePath);
|
|
2285
|
+
return normalizeRelativePath2(relative8 || path5.basename(absolutePath));
|
|
2286
2286
|
}
|
|
2287
2287
|
function sha2562(content) {
|
|
2288
2288
|
return crypto2.createHash("sha256").update(content, "utf8").digest("hex");
|
|
@@ -10243,8 +10243,8 @@ function decisionPendingCount(cwd = process.cwd()) {
|
|
|
10243
10243
|
return listPendingDecisionRequests(cwd).filter((entry) => entry.status === "pending").length;
|
|
10244
10244
|
}
|
|
10245
10245
|
function toProjectRelativePath(absolutePath, cwd) {
|
|
10246
|
-
const
|
|
10247
|
-
return
|
|
10246
|
+
const relative8 = path11.relative(cwd, absolutePath).replace(/\\/g, "/");
|
|
10247
|
+
return relative8.startsWith(".") ? relative8 : `.${path11.sep}${relative8}`.replace(/\\/g, "/");
|
|
10248
10248
|
}
|
|
10249
10249
|
|
|
10250
10250
|
// src/commands/memory.ts
|
|
@@ -11228,6 +11228,8 @@ function detectRuntimeEnvironment(cwd = process.cwd(), env = process.env) {
|
|
|
11228
11228
|
const mcpConfigPaths = findRuntimeMcpConfigPaths(cwd, workspaceRoot);
|
|
11229
11229
|
const sandboxCli = detectSandboxCli();
|
|
11230
11230
|
const orchestratorCli = detectOrchestratorCli(cwd, workspaceRoot);
|
|
11231
|
+
const workspaceOrchestratorVersion = findWorkspaceOrchestratorVersion(cwd, workspaceRoot);
|
|
11232
|
+
const orchestratorCliVersion = parseOrchestratorVersion(orchestratorCli.version);
|
|
11231
11233
|
const parsedVersion = parseRuntimeVersion(sandboxCli.version);
|
|
11232
11234
|
const providerKeys = detectProviderKeys(cwd, workspaceRoot, env);
|
|
11233
11235
|
return {
|
|
@@ -11251,7 +11253,12 @@ function detectRuntimeEnvironment(cwd = process.cwd(), env = process.env) {
|
|
|
11251
11253
|
orchestrator: {
|
|
11252
11254
|
cliAvailable: Boolean(orchestratorCli.command),
|
|
11253
11255
|
command: orchestratorCli.command,
|
|
11254
|
-
version: orchestratorCli.version
|
|
11256
|
+
version: orchestratorCli.version,
|
|
11257
|
+
source: orchestratorCli.source,
|
|
11258
|
+
workspacePackageVersion: workspaceOrchestratorVersion,
|
|
11259
|
+
versionMismatch: Boolean(
|
|
11260
|
+
orchestratorCliVersion && workspaceOrchestratorVersion && orchestratorCliVersion !== workspaceOrchestratorVersion
|
|
11261
|
+
)
|
|
11255
11262
|
},
|
|
11256
11263
|
providerKeys,
|
|
11257
11264
|
docker: {
|
|
@@ -11391,7 +11398,8 @@ function detectOrchestratorCli(cwd, workspaceRoot) {
|
|
|
11391
11398
|
if (version || commandExists(ORCHESTRATOR_COMMAND)) {
|
|
11392
11399
|
return {
|
|
11393
11400
|
command: ORCHESTRATOR_COMMAND,
|
|
11394
|
-
version
|
|
11401
|
+
version,
|
|
11402
|
+
source: "path"
|
|
11395
11403
|
};
|
|
11396
11404
|
}
|
|
11397
11405
|
for (const candidate of findWorkspaceExecutableCandidates(
|
|
@@ -11404,11 +11412,46 @@ function detectOrchestratorCli(cwd, workspaceRoot) {
|
|
|
11404
11412
|
}
|
|
11405
11413
|
return {
|
|
11406
11414
|
command: candidate,
|
|
11407
|
-
version: getCommandVersion(candidate)
|
|
11415
|
+
version: getCommandVersion(candidate),
|
|
11416
|
+
source: "workspace_venv"
|
|
11408
11417
|
};
|
|
11409
11418
|
}
|
|
11410
11419
|
return {};
|
|
11411
11420
|
}
|
|
11421
|
+
function findWorkspaceOrchestratorVersion(cwd, workspaceRoot) {
|
|
11422
|
+
const roots = Array.from(
|
|
11423
|
+
new Set([workspaceRoot, path13.resolve(cwd)].filter((value) => Boolean(value)))
|
|
11424
|
+
);
|
|
11425
|
+
for (const root of roots) {
|
|
11426
|
+
const version = readPyprojectVersion(
|
|
11427
|
+
path13.join(root, "packages", "agentic-orchestrator", "pyproject.toml"),
|
|
11428
|
+
"snipara-orchestrator"
|
|
11429
|
+
);
|
|
11430
|
+
if (version) {
|
|
11431
|
+
return version;
|
|
11432
|
+
}
|
|
11433
|
+
}
|
|
11434
|
+
return void 0;
|
|
11435
|
+
}
|
|
11436
|
+
function readPyprojectVersion(filePath, packageName) {
|
|
11437
|
+
if (!fs14.existsSync(filePath)) {
|
|
11438
|
+
return void 0;
|
|
11439
|
+
}
|
|
11440
|
+
const content = fs14.readFileSync(filePath, "utf-8");
|
|
11441
|
+
const nameMatch = content.match(/^\s*name\s*=\s*["']([^"']+)["']/m);
|
|
11442
|
+
if (nameMatch && nameMatch[1] !== packageName) {
|
|
11443
|
+
return void 0;
|
|
11444
|
+
}
|
|
11445
|
+
const versionMatch = content.match(/^\s*version\s*=\s*["']([^"']+)["']/m);
|
|
11446
|
+
return versionMatch?.[1];
|
|
11447
|
+
}
|
|
11448
|
+
function parseOrchestratorVersion(version) {
|
|
11449
|
+
if (!version) {
|
|
11450
|
+
return void 0;
|
|
11451
|
+
}
|
|
11452
|
+
const match = version.match(/snipara-orchestrator\s+([^\s]+)/i);
|
|
11453
|
+
return match?.[1];
|
|
11454
|
+
}
|
|
11412
11455
|
function findWorkspaceExecutableCandidates(command, cwd, workspaceRoot) {
|
|
11413
11456
|
const executableName = process.platform === "win32" ? `${command}.exe` : command;
|
|
11414
11457
|
const roots = Array.from(
|
|
@@ -11998,7 +12041,14 @@ function runtimeVersionSummary(report) {
|
|
|
11998
12041
|
return `available (CLI ${report.runtime.cliVersion})`;
|
|
11999
12042
|
}
|
|
12000
12043
|
function orchestratorVersionSummary(report) {
|
|
12001
|
-
|
|
12044
|
+
const parts = [
|
|
12045
|
+
report.orchestrator.version ?? "version unknown",
|
|
12046
|
+
report.orchestrator.command ? `path ${report.orchestrator.command}` : null,
|
|
12047
|
+
report.orchestrator.source ? `source ${report.orchestrator.source}` : null,
|
|
12048
|
+
report.orchestrator.workspacePackageVersion ? `workspace ${report.orchestrator.workspacePackageVersion}` : null,
|
|
12049
|
+
report.orchestrator.versionMismatch ? "source/install mismatch" : null
|
|
12050
|
+
].filter((value) => Boolean(value));
|
|
12051
|
+
return `available (${parts.join(", ")})`;
|
|
12002
12052
|
}
|
|
12003
12053
|
function sourceLabel(source2) {
|
|
12004
12054
|
return source2 === "env-file" ? ".env" : "environment";
|
|
@@ -12170,6 +12220,7 @@ function buildAdaptiveWorkRoutingRecommendation(options) {
|
|
|
12170
12220
|
});
|
|
12171
12221
|
const warnings = [
|
|
12172
12222
|
"Recommendation-only dry run; companion does not launch or claim workers.",
|
|
12223
|
+
"Declare local runtimes with `snipara-companion workers local add ...` before expecting a local worker route.",
|
|
12173
12224
|
...preferredEndpointTypes.includes("local") ? ["Local endpoint preference requires a runtime catalog or gateway to confirm availability."] : []
|
|
12174
12225
|
];
|
|
12175
12226
|
const routingCard = {
|
|
@@ -13555,11 +13606,7 @@ function normalizeAdapterTarget(value) {
|
|
|
13555
13606
|
return "custom";
|
|
13556
13607
|
}
|
|
13557
13608
|
function normalizeAdapterValues(values) {
|
|
13558
|
-
return [
|
|
13559
|
-
...new Set(
|
|
13560
|
-
(values ?? []).flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean)
|
|
13561
|
-
)
|
|
13562
|
-
];
|
|
13609
|
+
return [...new Set((values ?? []).map((value) => value.trim()).filter(Boolean))];
|
|
13563
13610
|
}
|
|
13564
13611
|
function normalizeConflictPosture(value, payload) {
|
|
13565
13612
|
const normalized = value?.trim().toLowerCase().replace(/-/g, "_");
|
|
@@ -15040,6 +15087,15 @@ var FINAL_COMMIT_RETRY_SUMMARY_MAX_CHARS = 600;
|
|
|
15040
15087
|
var DEFAULT_ADAPTIVE_ROUTING_CATALOG_LIMIT = 20;
|
|
15041
15088
|
var DEFAULT_LOCAL_ORCHESTRATOR_TIMEOUT_MS = 8e3;
|
|
15042
15089
|
var ADAPTIVE_ROUTING_POLICY_RELATIVE_PATH2 = path19.join(".snipara", "adaptive-routing.json");
|
|
15090
|
+
var MEMORY_DECISION_PRODUCER_ACTIONS = /* @__PURE__ */ new Set([
|
|
15091
|
+
"accept",
|
|
15092
|
+
"reject",
|
|
15093
|
+
"archive",
|
|
15094
|
+
"invalidate",
|
|
15095
|
+
"merge",
|
|
15096
|
+
"supersede",
|
|
15097
|
+
"verify"
|
|
15098
|
+
]);
|
|
15043
15099
|
var SHARED_CONTEXT_INTENT_PATTERN = /\b(standard|standards|convention|conventions|guideline|guidelines|best practice|best practices|policy|policies|compliance|compliant|security rules|team rules|style guide|playbook|checklist)\b/i;
|
|
15044
15100
|
var DOCUMENT_SYNC_FORMATS = {
|
|
15045
15101
|
".adoc": { kind: "DOC", format: "adoc" },
|
|
@@ -16110,8 +16166,8 @@ function defaultWorkflowPlanOutputPath(preset, cwd = process.cwd()) {
|
|
|
16110
16166
|
return path19.resolve(cwd, WORKFLOW_PLANS_RELATIVE_DIR, `${preset}-plan.json`);
|
|
16111
16167
|
}
|
|
16112
16168
|
function toProjectRelativePath2(absolutePath, cwd = process.cwd()) {
|
|
16113
|
-
const
|
|
16114
|
-
return
|
|
16169
|
+
const relative8 = path19.relative(cwd, absolutePath);
|
|
16170
|
+
return relative8 && !relative8.startsWith("..") ? relative8 : absolutePath;
|
|
16115
16171
|
}
|
|
16116
16172
|
function buildWorkflowPlanScaffold(preset, options = {}) {
|
|
16117
16173
|
const cwd = path19.resolve(options.cwd ?? process.cwd());
|
|
@@ -17004,6 +17060,30 @@ async function workflowProducerTriageCommand(options) {
|
|
|
17004
17060
|
}
|
|
17005
17061
|
async function workflowDecisionProducerMemoryCommand(options) {
|
|
17006
17062
|
const action = options.action.trim();
|
|
17063
|
+
if (!MEMORY_DECISION_PRODUCER_ACTIONS.has(action)) {
|
|
17064
|
+
throw new Error(
|
|
17065
|
+
`Invalid memory decision action '${action}'. Use one of: ${[
|
|
17066
|
+
...MEMORY_DECISION_PRODUCER_ACTIONS
|
|
17067
|
+
].join(", ")}. Internal review item types such as review_queue_item are not human actions.`
|
|
17068
|
+
);
|
|
17069
|
+
}
|
|
17070
|
+
const reviewItem = await findMemoryReviewConnectorItem(options.memoryId);
|
|
17071
|
+
if (reviewItem) {
|
|
17072
|
+
const request2 = buildMemoryReviewDecisionRequest({
|
|
17073
|
+
...reviewItem,
|
|
17074
|
+
action,
|
|
17075
|
+
recommendation: options.reviewerHint ?? reviewItem.recommendation,
|
|
17076
|
+
options: action === "verify" ? ["verify", "keep_pending", "invalidate"] : action === "invalidate" ? ["invalidate", "keep", "inspect"] : reviewItem.options.includes(action) ? reviewItem.options : [action, ...reviewItem.options.filter((option) => option !== action)]
|
|
17077
|
+
});
|
|
17078
|
+
const write2 = writeDecisionRequest(request2);
|
|
17079
|
+
if (options.json) {
|
|
17080
|
+
printJson2({ request: request2, write: write2, inheritedFrom: "memory reviews" });
|
|
17081
|
+
return;
|
|
17082
|
+
}
|
|
17083
|
+
console.log(`Decision request ${write2.status}: ${write2.requestId}`);
|
|
17084
|
+
console.log(request2.question);
|
|
17085
|
+
return;
|
|
17086
|
+
}
|
|
17007
17087
|
const applyPath = action === "verify" ? "snipara_memory_verify" : action === "invalidate" ? "snipara_memory_invalidate" : "snipara_memory_resolve_queue_item";
|
|
17008
17088
|
const request = buildDecisionRequest({
|
|
17009
17089
|
producer: {
|
|
@@ -17031,6 +17111,20 @@ async function workflowDecisionProducerMemoryCommand(options) {
|
|
|
17031
17111
|
}
|
|
17032
17112
|
console.log(`Decision request ${write.status}: ${write.requestId}`);
|
|
17033
17113
|
}
|
|
17114
|
+
async function findMemoryReviewConnectorItem(memoryId) {
|
|
17115
|
+
try {
|
|
17116
|
+
const result = await buildMemoryReviewConnector({
|
|
17117
|
+
limit: 50,
|
|
17118
|
+
includeCleanCandidates: false,
|
|
17119
|
+
includeDuplicates: false
|
|
17120
|
+
});
|
|
17121
|
+
return result.items.find(
|
|
17122
|
+
(item) => item.memoryId === memoryId || item.evidenceItem.ref === memoryId || item.evidenceItem.ref === `memory:${memoryId}`
|
|
17123
|
+
) ?? null;
|
|
17124
|
+
} catch {
|
|
17125
|
+
return null;
|
|
17126
|
+
}
|
|
17127
|
+
}
|
|
17034
17128
|
async function workflowDecisionProducerContextRiskCommand(options) {
|
|
17035
17129
|
const kind = options.kind === "document_tombstone" ? "document_tombstone" : "unknown_registry_risk";
|
|
17036
17130
|
const request = buildDecisionRequest({
|
|
@@ -19498,9 +19592,9 @@ function normalizeSyncDocumentsPayload(payload) {
|
|
|
19498
19592
|
};
|
|
19499
19593
|
}
|
|
19500
19594
|
function toUploadPath(filePath, rootDir, prefix) {
|
|
19501
|
-
const
|
|
19595
|
+
const relative8 = path19.relative(rootDir, filePath).split(path19.sep).join("/");
|
|
19502
19596
|
const trimmedPrefix = prefix?.replace(/^\/+|\/+$/g, "");
|
|
19503
|
-
return trimmedPrefix ? `${trimmedPrefix}/${
|
|
19597
|
+
return trimmedPrefix ? `${trimmedPrefix}/${relative8}` : relative8;
|
|
19504
19598
|
}
|
|
19505
19599
|
function collectDirectoryDocuments(options) {
|
|
19506
19600
|
const rootDir = path19.resolve(options.dir);
|
|
@@ -22436,11 +22530,7 @@ function normalizeTarget(target) {
|
|
|
22436
22530
|
return "custom";
|
|
22437
22531
|
}
|
|
22438
22532
|
function unique2(values) {
|
|
22439
|
-
return [
|
|
22440
|
-
...new Set(
|
|
22441
|
-
(values ?? []).flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean)
|
|
22442
|
-
)
|
|
22443
|
-
];
|
|
22533
|
+
return [...new Set((values ?? []).map((value) => value.trim()).filter(Boolean))];
|
|
22444
22534
|
}
|
|
22445
22535
|
function normalizeTask(task) {
|
|
22446
22536
|
const normalized = task?.trim();
|
|
@@ -22464,8 +22554,8 @@ function safeReadJson(filePath) {
|
|
|
22464
22554
|
}
|
|
22465
22555
|
}
|
|
22466
22556
|
function relativePath(rootDir, filePath) {
|
|
22467
|
-
const
|
|
22468
|
-
return
|
|
22557
|
+
const relative8 = path21.relative(rootDir, filePath);
|
|
22558
|
+
return relative8 && !relative8.startsWith("..") ? relative8 : filePath;
|
|
22469
22559
|
}
|
|
22470
22560
|
function collectAgentReadinessLocalSignals(rootDir = process.cwd()) {
|
|
22471
22561
|
const workflowPath = path21.join(rootDir, ".snipara", "workflow", "current.json");
|
|
@@ -22927,11 +23017,7 @@ function normalizeTask2(task) {
|
|
|
22927
23017
|
return normalized ? normalized : void 0;
|
|
22928
23018
|
}
|
|
22929
23019
|
function unique3(values) {
|
|
22930
|
-
return [
|
|
22931
|
-
...new Set(
|
|
22932
|
-
(values ?? []).flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean)
|
|
22933
|
-
)
|
|
22934
|
-
];
|
|
23020
|
+
return [...new Set((values ?? []).map((value) => value.trim()).filter(Boolean))];
|
|
22935
23021
|
}
|
|
22936
23022
|
function isRecord11(value) {
|
|
22937
23023
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -24285,6 +24371,15 @@ function writeReport2(outputPath, report) {
|
|
|
24285
24371
|
`;
|
|
24286
24372
|
fs23.writeFileSync(absolute, content, "utf8");
|
|
24287
24373
|
}
|
|
24374
|
+
function defaultJsonOutputPath(cwd, report) {
|
|
24375
|
+
const timestamp = report.generatedAt.replace(/[:.]/g, "-");
|
|
24376
|
+
return path22.join(
|
|
24377
|
+
cwd,
|
|
24378
|
+
".snipara",
|
|
24379
|
+
"lead-plans",
|
|
24380
|
+
`${timestamp}-${slug(report.task ?? "lead-plan", "lead-plan")}.json`
|
|
24381
|
+
);
|
|
24382
|
+
}
|
|
24288
24383
|
async function leadPlanCommand(options) {
|
|
24289
24384
|
const cwd = path22.resolve(options.dir ?? process.cwd());
|
|
24290
24385
|
const report = buildCompanionEngineeringLeadPlanReport({
|
|
@@ -24292,11 +24387,26 @@ async function leadPlanCommand(options) {
|
|
|
24292
24387
|
cwd,
|
|
24293
24388
|
localSignals: collectAgentReadinessLocalSignals(cwd)
|
|
24294
24389
|
});
|
|
24295
|
-
|
|
24296
|
-
|
|
24390
|
+
const writtenOutput = options.output ?? (options.json ? defaultJsonOutputPath(cwd, report) : void 0);
|
|
24391
|
+
if (writtenOutput) {
|
|
24392
|
+
writeReport2(writtenOutput, report);
|
|
24297
24393
|
}
|
|
24298
24394
|
if (options.json) {
|
|
24299
|
-
console.log(
|
|
24395
|
+
console.log(
|
|
24396
|
+
JSON.stringify(
|
|
24397
|
+
{
|
|
24398
|
+
...report,
|
|
24399
|
+
outputPath: writtenOutput ? path22.resolve(writtenOutput) : void 0,
|
|
24400
|
+
relativeOutputPath: writtenOutput ? path22.relative(cwd, path22.resolve(writtenOutput)) : void 0,
|
|
24401
|
+
nextCommand: writtenOutput ? `snipara-orchestrator team-sync gate --plan ${path22.relative(
|
|
24402
|
+
cwd,
|
|
24403
|
+
path22.resolve(writtenOutput)
|
|
24404
|
+
)} --json` : void 0
|
|
24405
|
+
},
|
|
24406
|
+
null,
|
|
24407
|
+
2
|
|
24408
|
+
)
|
|
24409
|
+
);
|
|
24300
24410
|
return;
|
|
24301
24411
|
}
|
|
24302
24412
|
console.log(formatCompanionEngineeringLeadPlanReport(report));
|
|
@@ -29763,7 +29873,7 @@ program.command("outcome-capture").description("Extract review-pending why/outco
|
|
|
29763
29873
|
program.command("lead-plan").description("Create a fail-closed Companion Engineering Lead Plan").option("--task <task>", "Current task or work package summary").option(
|
|
29764
29874
|
"--target <target>",
|
|
29765
29875
|
"Target agent or ADE (codex|claude-code|cursor|orca|windsurf|custom)"
|
|
29766
|
-
).option("--changed-files <files...>", "Changed or relevant files").option("--context <refs...>", "Context references, decisions, docs, or source facts").option("--proof <proof...>", "Required proof gates or verification evidence").option("--acceptance <criteria...>", "Acceptance criteria for the delegated work").option("--risk <risks...>", "Known risks or caveats").option("--from-cockpit <file>", "Read a Project Health cockpit JSON export").option("--from-plan <file>", "Read a Companion or Project Health Engineering Lead Plan JSON").option("--reconcile", "Reconcile an imported lead plan against current local Companion signals").option("-d, --dir <directory>", "Project directory (default: current)").option("-o, --output <file>", "Write Markdown or JSON report").option("--json", "Print raw JSON").action(async (options) => {
|
|
29876
|
+
).option("--changed-files <files...>", "Changed or relevant files").option("--context <refs...>", "Context references, decisions, docs, or source facts").option("--proof <proof...>", "Required proof gates or verification evidence").option("--acceptance <criteria...>", "Acceptance criteria for the delegated work").option("--risk <risks...>", "Known risks or caveats").option("--from-cockpit <file>", "Read a Project Health cockpit JSON export").option("--from-plan <file>", "Read a Companion or Project Health Engineering Lead Plan JSON").option("--reconcile", "Reconcile an imported lead plan against current local Companion signals").option("-d, --dir <directory>", "Project directory (default: current)").option("-o, --output <file>", "Write Markdown or JSON report").option("--out <file>", "Alias for --output").option("--json", "Print raw JSON").action(async (options) => {
|
|
29767
29877
|
await leadPlanCommand({
|
|
29768
29878
|
task: options.task,
|
|
29769
29879
|
target: options.target,
|
|
@@ -29776,7 +29886,7 @@ program.command("lead-plan").description("Create a fail-closed Companion Enginee
|
|
|
29776
29886
|
fromPlan: options.fromPlan,
|
|
29777
29887
|
reconcile: Boolean(options.reconcile),
|
|
29778
29888
|
dir: options.dir,
|
|
29779
|
-
output: options.output,
|
|
29889
|
+
output: options.output ?? options.out,
|
|
29780
29890
|
json: Boolean(options.json)
|
|
29781
29891
|
});
|
|
29782
29892
|
});
|