@sechroom/cli 2026.7.21-rc.59d9df67 → 2026.7.22
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 +8 -121
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3557,7 +3557,6 @@ Examples:
|
|
|
3557
3557
|
}
|
|
3558
3558
|
|
|
3559
3559
|
// src/commands/decomposition.ts
|
|
3560
|
-
import { readFile } from "fs/promises";
|
|
3561
3560
|
function registerDecomposition(program2) {
|
|
3562
3561
|
const decomposition = program2.command("decomposition").description(
|
|
3563
3562
|
"Drive a WLP decomposition: decompose a brief, then execute / accept / reject"
|
|
@@ -3567,8 +3566,6 @@ function registerDecomposition(program2) {
|
|
|
3567
3566
|
`
|
|
3568
3567
|
Examples:
|
|
3569
3568
|
$ sechroom decomposition decompose mem_XXXX
|
|
3570
|
-
$ sechroom decomposition from-plan mem_XXXX --file plan.json
|
|
3571
|
-
$ sechroom decomposition plan wlp_XXXX
|
|
3572
3569
|
$ sechroom decomposition execute sug_XXXX
|
|
3573
3570
|
$ sechroom decomposition publish-run sug_XXXX
|
|
3574
3571
|
$ sechroom decomposition accept sug_XXXX
|
|
@@ -3591,47 +3588,6 @@ Examples:
|
|
|
3591
3588
|
cmd.optsWithGlobals().json
|
|
3592
3589
|
);
|
|
3593
3590
|
});
|
|
3594
|
-
decomposition.command("from-plan <briefId>").description(
|
|
3595
|
-
"Create a decomposition from a hand-authored JSON plan; tasks may carry Unix-millisecond wakeAtMs"
|
|
3596
|
-
).requiredOption(
|
|
3597
|
-
"--file <path>",
|
|
3598
|
-
"JSON file containing { project, tasks, source? }; use - for stdin"
|
|
3599
|
-
).action(async (briefId, opts, cmd) => {
|
|
3600
|
-
const raw = opts.file === "-" ? await readStdin2() : await readFile(opts.file, "utf8");
|
|
3601
|
-
const body = parsePlanInput(raw, opts.file);
|
|
3602
|
-
const cfg = resolveConfig(cmd.optsWithGlobals());
|
|
3603
|
-
const data = await runApi(
|
|
3604
|
-
"Creating decomposition from plan",
|
|
3605
|
-
async () => {
|
|
3606
|
-
const client = await makeClient(cfg);
|
|
3607
|
-
return client.POST("/work-briefs/{id}/decompose-from-plan", {
|
|
3608
|
-
params: { path: { id: briefId } },
|
|
3609
|
-
body
|
|
3610
|
-
});
|
|
3611
|
-
}
|
|
3612
|
-
);
|
|
3613
|
-
emitAction(
|
|
3614
|
-
`created ${style.bold(data.suggestionId)} from ${data.taskCount} hand-authored task(s)`,
|
|
3615
|
-
data,
|
|
3616
|
-
cmd.optsWithGlobals().json
|
|
3617
|
-
);
|
|
3618
|
-
});
|
|
3619
|
-
decomposition.command("plan <decompositionId>").description(
|
|
3620
|
-
"Inspect the compiled plan, including each scheduled step's Unix-millisecond wakeAtMs"
|
|
3621
|
-
).action(async (decompositionId, _opts, cmd) => {
|
|
3622
|
-
const cfg = resolveConfig(cmd.optsWithGlobals());
|
|
3623
|
-
const data = await runApi("Reading decomposition plan", async () => {
|
|
3624
|
-
const client = await makeClient(cfg);
|
|
3625
|
-
return client.GET("/decompositions/{id}/plan", {
|
|
3626
|
-
params: { path: { id: decompositionId } }
|
|
3627
|
-
});
|
|
3628
|
-
});
|
|
3629
|
-
emitAction(
|
|
3630
|
-
`read ${style.bold(decompositionId)} plan (${data.steps.length} step(s))`,
|
|
3631
|
-
data,
|
|
3632
|
-
cmd.optsWithGlobals().json
|
|
3633
|
-
);
|
|
3634
|
-
});
|
|
3635
3591
|
decomposition.command("execute <decompositionId>").description(
|
|
3636
3592
|
"Execute a decomposition's Task graph (POST /decompositions/{id}/execute)"
|
|
3637
3593
|
).action(async (decompositionId, _opts, cmd) => {
|
|
@@ -3701,24 +3657,6 @@ Examples:
|
|
|
3701
3657
|
);
|
|
3702
3658
|
});
|
|
3703
3659
|
}
|
|
3704
|
-
function parsePlanInput(raw, sourceName = "plan input") {
|
|
3705
|
-
let value;
|
|
3706
|
-
try {
|
|
3707
|
-
value = JSON.parse(raw);
|
|
3708
|
-
} catch (error) {
|
|
3709
|
-
throw new Error(
|
|
3710
|
-
`${sourceName} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
3711
|
-
);
|
|
3712
|
-
}
|
|
3713
|
-
if (!value || typeof value !== "object" || !Array.isArray(value.tasks))
|
|
3714
|
-
throw new Error(`${sourceName} must contain an object with a tasks array`);
|
|
3715
|
-
return value;
|
|
3716
|
-
}
|
|
3717
|
-
async function readStdin2() {
|
|
3718
|
-
const chunks = [];
|
|
3719
|
-
for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
|
|
3720
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
3721
|
-
}
|
|
3722
3660
|
|
|
3723
3661
|
// src/commands/filing.ts
|
|
3724
3662
|
function registerFiling(program2) {
|
|
@@ -5984,23 +5922,23 @@ Examples:
|
|
|
5984
5922
|
});
|
|
5985
5923
|
emit(data, cmd.optsWithGlobals().json);
|
|
5986
5924
|
});
|
|
5987
|
-
suggestion.command("accept <id>").description("Accept a suggestion (POST /relationship-suggestions/{
|
|
5925
|
+
suggestion.command("accept <id>").description("Accept a suggestion (POST /relationship-suggestions/{id}/accept)").action(async (id, _opts, cmd) => {
|
|
5988
5926
|
const cfg = resolveConfig(cmd.optsWithGlobals());
|
|
5989
5927
|
const data = await runApi("Accepting suggestion", async () => {
|
|
5990
5928
|
const client = await makeClient(cfg);
|
|
5991
|
-
return client.POST("/relationship-suggestions/{
|
|
5992
|
-
params: { path: {
|
|
5929
|
+
return client.POST("/relationship-suggestions/{id}/accept", {
|
|
5930
|
+
params: { path: { id } },
|
|
5993
5931
|
body: {}
|
|
5994
5932
|
});
|
|
5995
5933
|
});
|
|
5996
5934
|
emitAction(`accepted suggestion ${style.bold(id)}`, data, cmd.optsWithGlobals().json);
|
|
5997
5935
|
});
|
|
5998
|
-
suggestion.command("reject <id>").description("Reject a suggestion (POST /relationship-suggestions/{
|
|
5936
|
+
suggestion.command("reject <id>").description("Reject a suggestion (POST /relationship-suggestions/{id}/reject)").option("--reason <reason>", "Why it's being rejected").option("--reason-code <code>", "Structured reason code").action(async (id, opts, cmd) => {
|
|
5999
5937
|
const cfg = resolveConfig(cmd.optsWithGlobals());
|
|
6000
5938
|
const data = await runApi("Rejecting suggestion", async () => {
|
|
6001
5939
|
const client = await makeClient(cfg);
|
|
6002
|
-
return client.POST("/relationship-suggestions/{
|
|
6003
|
-
params: { path: {
|
|
5940
|
+
return client.POST("/relationship-suggestions/{id}/reject", {
|
|
5941
|
+
params: { path: { id } },
|
|
6004
5942
|
body: {
|
|
6005
5943
|
reason: opts.reason ?? null,
|
|
6006
5944
|
...opts.reasonCode ? { reasonCode: opts.reasonCode } : {}
|
|
@@ -6553,7 +6491,7 @@ function registerTelemetry(program2) {
|
|
|
6553
6491
|
"Per-turn telemetry self-report for Claude Code hooks \u2014 Stop/SubagentStop \u2192 parsed + terminal, Notification/PermissionDenied \u2192 approval (reads stdin; no-op unless bound). Fail-soft."
|
|
6554
6492
|
).action(async (_opts, cmd) => {
|
|
6555
6493
|
try {
|
|
6556
|
-
const raw = await
|
|
6494
|
+
const raw = await readStdin2();
|
|
6557
6495
|
const input = parseHookInput2(raw);
|
|
6558
6496
|
const cwd = input.cwd ?? process.cwd();
|
|
6559
6497
|
const binding = findBinding(cwd);
|
|
@@ -6745,7 +6683,7 @@ function isPermissionNotification(input) {
|
|
|
6745
6683
|
if (t) return t.includes("permission");
|
|
6746
6684
|
return (input.message ?? "").toLowerCase().includes("permission");
|
|
6747
6685
|
}
|
|
6748
|
-
async function
|
|
6686
|
+
async function readStdin2() {
|
|
6749
6687
|
if (process.stdin.isTTY) return "";
|
|
6750
6688
|
const chunks = [];
|
|
6751
6689
|
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
@@ -6975,56 +6913,6 @@ Examples:
|
|
|
6975
6913
|
});
|
|
6976
6914
|
}
|
|
6977
6915
|
|
|
6978
|
-
// src/commands/work-brief.ts
|
|
6979
|
-
function registerWorkBrief(program2) {
|
|
6980
|
-
const workBrief = program2.command("work-brief").description("Control an active work brief run");
|
|
6981
|
-
workBrief.addHelpText(
|
|
6982
|
-
"after",
|
|
6983
|
-
`
|
|
6984
|
-
Examples:
|
|
6985
|
-
$ sechroom work-brief pause mem_XXXX --reason-code operator-hold --source claude-code-chris
|
|
6986
|
-
$ sechroom work-brief resume mem_XXXX --reason-code operator-resume --source claude-code-chris --reason "Ready to continue"
|
|
6987
|
-
$ sechroom work-brief cancel mem_XXXX --reason-code operator-stopped --source claude-code-chris --reason "Work no longer required"`
|
|
6988
|
-
);
|
|
6989
|
-
registerLifecycleAction(workBrief, "pause");
|
|
6990
|
-
registerLifecycleAction(workBrief, "resume");
|
|
6991
|
-
registerLifecycleAction(workBrief, "cancel");
|
|
6992
|
-
}
|
|
6993
|
-
function registerLifecycleAction(workBrief, action) {
|
|
6994
|
-
const presentParticiple = action === "pause" ? "Pausing" : action === "resume" ? "Resuming" : "Cancelling";
|
|
6995
|
-
const pastTense = action === "pause" ? "paused" : action === "resume" ? "resumed" : "cancelled";
|
|
6996
|
-
workBrief.command(`${action} <briefId>`).description(`${capitalize(action)} an active work brief run`).requiredOption(
|
|
6997
|
-
"--reason-code <code>",
|
|
6998
|
-
"Stable machine-readable reason code"
|
|
6999
|
-
).requiredOption(
|
|
7000
|
-
"--source <source>",
|
|
7001
|
-
"Calling surface or lane recorded in the audit"
|
|
7002
|
-
).option("--reason <text>", "Optional human-readable reason").action(async (briefId, opts, cmd) => {
|
|
7003
|
-
const globals = cmd.optsWithGlobals();
|
|
7004
|
-
const cfg = resolveConfig(globals);
|
|
7005
|
-
const data = await runApi(`${presentParticiple} work brief`, async () => {
|
|
7006
|
-
const client = await makeClient(cfg);
|
|
7007
|
-
return client.POST("/work-briefs/{id}/lifecycle", {
|
|
7008
|
-
params: { path: { id: briefId } },
|
|
7009
|
-
body: {
|
|
7010
|
-
action,
|
|
7011
|
-
reasonCode: opts.reasonCode,
|
|
7012
|
-
source: opts.source,
|
|
7013
|
-
reasonText: opts.reason ?? null
|
|
7014
|
-
}
|
|
7015
|
-
});
|
|
7016
|
-
});
|
|
7017
|
-
emitAction(
|
|
7018
|
-
`${pastTense} work brief ${style.bold(briefId)} \u2192 ${data.outcome}`,
|
|
7019
|
-
data,
|
|
7020
|
-
globals.json
|
|
7021
|
-
);
|
|
7022
|
-
});
|
|
7023
|
-
}
|
|
7024
|
-
function capitalize(value) {
|
|
7025
|
-
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
7026
|
-
}
|
|
7027
|
-
|
|
7028
6916
|
// src/index.ts
|
|
7029
6917
|
function resolveVersion() {
|
|
7030
6918
|
try {
|
|
@@ -7187,7 +7075,6 @@ registerLookup(program);
|
|
|
7187
7075
|
registerRelationships(program);
|
|
7188
7076
|
registerWorkspace(program);
|
|
7189
7077
|
registerProject(program);
|
|
7190
|
-
registerWorkBrief(program);
|
|
7191
7078
|
registerDecomposition(program);
|
|
7192
7079
|
registerExecutor(program);
|
|
7193
7080
|
registerClose(program);
|
package/package.json
CHANGED