@sechroom/cli 2026.7.4-rc.ce2b31c6 → 2026.7.5-rc.ef6a4180
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.js +64 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -633,7 +633,22 @@ async function runApi(label, fn) {
|
|
|
633
633
|
return res.data;
|
|
634
634
|
}
|
|
635
635
|
function fail(error) {
|
|
636
|
-
|
|
636
|
+
let msg;
|
|
637
|
+
if (typeof error === "object" && error !== null && "title" in error) {
|
|
638
|
+
const problem = error;
|
|
639
|
+
msg = String(problem.title);
|
|
640
|
+
if (problem.errors && typeof problem.errors === "object") {
|
|
641
|
+
const detail = Object.entries(problem.errors).flatMap(
|
|
642
|
+
([field, msgs]) => (Array.isArray(msgs) ? msgs : [msgs]).map((m) => ` ${field}: ${String(m)}`)
|
|
643
|
+
);
|
|
644
|
+
if (detail.length > 0) msg += `
|
|
645
|
+
${detail.join("\n")}`;
|
|
646
|
+
}
|
|
647
|
+
} else if (typeof error === "object" && error !== null) {
|
|
648
|
+
msg = JSON.stringify(error);
|
|
649
|
+
} else {
|
|
650
|
+
msg = String(error);
|
|
651
|
+
}
|
|
637
652
|
process.stderr.write(`error: ${msg}
|
|
638
653
|
`);
|
|
639
654
|
process.exit(1);
|
|
@@ -2551,6 +2566,9 @@ function registerClose(program2) {
|
|
|
2551
2566
|
).option(
|
|
2552
2567
|
"--no-status-flip",
|
|
2553
2568
|
"Skip the status flip on a BARE task. (Managed runs never flip here \u2014 the run engine reflects the verdict onto the task on resume.)"
|
|
2569
|
+
).option(
|
|
2570
|
+
"--to-version <n>",
|
|
2571
|
+
"Pin the Reference edge at this task version \u2014 the DISPATCHED version the executor worked against (D-continuity-2). Default: the task's current version (status flips are metadata edits that don't bump the version, so current == dispatched in the normal case; pass this when the task's content changed between dispatch and close)."
|
|
2554
2572
|
).option("--source <source>", "Source / lane stamp", "cli").addHelpText(
|
|
2555
2573
|
"after",
|
|
2556
2574
|
`
|
|
@@ -2584,6 +2602,7 @@ Examples:
|
|
|
2584
2602
|
);
|
|
2585
2603
|
const client = await makeClient(cfg);
|
|
2586
2604
|
let matchTags;
|
|
2605
|
+
let dispatchedVersion;
|
|
2587
2606
|
if (opts.decomposition) {
|
|
2588
2607
|
const run = await runApi(
|
|
2589
2608
|
"Reading run contract",
|
|
@@ -2601,6 +2620,8 @@ Examples:
|
|
|
2601
2620
|
`run ${opts.decomposition} is awaiting task ${run.awaitingTaskId}, not ${opts.task} \u2014 refusing to mis-key the resume.`
|
|
2602
2621
|
);
|
|
2603
2622
|
matchTags = await_.matchTags;
|
|
2623
|
+
if (typeof await_.dispatchedTaskVersion === "number")
|
|
2624
|
+
dispatchedVersion = await_.dispatchedTaskVersion;
|
|
2604
2625
|
} else {
|
|
2605
2626
|
matchTags = [`wlp-task:${opts.task}`];
|
|
2606
2627
|
}
|
|
@@ -2627,11 +2648,34 @@ Examples:
|
|
|
2627
2648
|
}
|
|
2628
2649
|
})
|
|
2629
2650
|
);
|
|
2651
|
+
let toVersion;
|
|
2652
|
+
if (opts.toVersion !== void 0) {
|
|
2653
|
+
toVersion = Number(opts.toVersion);
|
|
2654
|
+
if (!Number.isInteger(toVersion) || toVersion < 1)
|
|
2655
|
+
fail(
|
|
2656
|
+
`--to-version must be an integer >= 1 \u2014 got '${opts.toVersion}'`
|
|
2657
|
+
);
|
|
2658
|
+
} else if (dispatchedVersion !== void 0) {
|
|
2659
|
+
toVersion = dispatchedVersion;
|
|
2660
|
+
} else {
|
|
2661
|
+
const task = await runApi(
|
|
2662
|
+
"Reading task version",
|
|
2663
|
+
async () => client.GET("/memories/{memoryId}", {
|
|
2664
|
+
params: { path: { memoryId: opts.task } }
|
|
2665
|
+
})
|
|
2666
|
+
);
|
|
2667
|
+
const v = task?.item?.currentVersion ?? task?.currentVersion;
|
|
2668
|
+
if (typeof v !== "number" || v < 1)
|
|
2669
|
+
fail(
|
|
2670
|
+
`could not read task ${opts.task} version to pin the Reference edge \u2014 pass --to-version <n>`
|
|
2671
|
+
);
|
|
2672
|
+
toVersion = v;
|
|
2673
|
+
}
|
|
2630
2674
|
const edge = await runApi(
|
|
2631
2675
|
"Wiring Reference edge",
|
|
2632
2676
|
async () => client.POST("/memories/{memoryId}/relationships", {
|
|
2633
2677
|
params: { path: { memoryId: closeout.id } },
|
|
2634
|
-
body: { toMemoryId: opts.task, type: "Reference" }
|
|
2678
|
+
body: { toMemoryId: opts.task, type: "Reference", toVersion }
|
|
2635
2679
|
})
|
|
2636
2680
|
);
|
|
2637
2681
|
let taskStatus;
|
|
@@ -2847,6 +2891,7 @@ function registerDecomposition(program2) {
|
|
|
2847
2891
|
Examples:
|
|
2848
2892
|
$ sechroom decomposition decompose mem_XXXX
|
|
2849
2893
|
$ sechroom decomposition execute sug_XXXX
|
|
2894
|
+
$ sechroom decomposition publish-run sug_XXXX
|
|
2850
2895
|
$ sechroom decomposition accept sug_XXXX
|
|
2851
2896
|
$ sechroom decomposition reject sug_XXXX --reason "wrong shape"`
|
|
2852
2897
|
);
|
|
@@ -2884,6 +2929,23 @@ Examples:
|
|
|
2884
2929
|
cmd.optsWithGlobals().json
|
|
2885
2930
|
);
|
|
2886
2931
|
});
|
|
2932
|
+
decomposition.command("publish-run <decompositionId>").description(
|
|
2933
|
+
"Publish an accepted decomposition's context pack on demand (POST /decompositions/{id}/publish-run)"
|
|
2934
|
+
).action(async (decompositionId, _opts, cmd) => {
|
|
2935
|
+
const cfg = resolveConfig(cmd.optsWithGlobals());
|
|
2936
|
+
const data = await runApi("Publishing context pack", async () => {
|
|
2937
|
+
const client = await makeClient(cfg);
|
|
2938
|
+
return client.POST("/decompositions/{id}/publish-run", {
|
|
2939
|
+
params: { path: { id: decompositionId } },
|
|
2940
|
+
body: {}
|
|
2941
|
+
});
|
|
2942
|
+
});
|
|
2943
|
+
emitAction(
|
|
2944
|
+
`published ${style.bold(decompositionId)} \u2192 run ${style.bold(data.runRecordId)} (${data.outcome})`,
|
|
2945
|
+
data,
|
|
2946
|
+
cmd.optsWithGlobals().json
|
|
2947
|
+
);
|
|
2948
|
+
});
|
|
2887
2949
|
decomposition.command("accept <decompositionId>").description(
|
|
2888
2950
|
"Accept a Pending decomposition \u2014 promote + ratify its Tasks (POST /decompositions/{id}/accept)"
|
|
2889
2951
|
).action(async (decompositionId, _opts, cmd) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sechroom/cli",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.5-rc.ef6a4180",
|
|
4
4
|
"description": "Sechroom CLI — a thin, generated client over the Sechroom HTTP API. An agent/human surface alongside MCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|