@sechroom/cli 2026.6.20 → 2026.6.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 +64 -40
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1574,7 +1574,7 @@ Examples:
|
|
|
1574
1574
|
// src/commands/hook.ts
|
|
1575
1575
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
1576
1576
|
import { homedir as homedir3 } from "os";
|
|
1577
|
-
import { dirname as dirname4, join as join4 } from "path";
|
|
1577
|
+
import { delimiter, dirname as dirname4, join as join4 } from "path";
|
|
1578
1578
|
|
|
1579
1579
|
// src/sem.ts
|
|
1580
1580
|
import { basename as basename2, dirname as dirname2, join as join2 } from "path";
|
|
@@ -2049,6 +2049,25 @@ function detectHookSurfaces(cwd) {
|
|
|
2049
2049
|
if (detected.includes("codex")) surfaces.push("codex");
|
|
2050
2050
|
return surfaces;
|
|
2051
2051
|
}
|
|
2052
|
+
function isSechroomOnPath() {
|
|
2053
|
+
const pathEnv = process.env.PATH ?? "";
|
|
2054
|
+
if (!pathEnv) return false;
|
|
2055
|
+
const names = process.platform === "win32" ? ["sechroom.cmd", "sechroom.exe", "sechroom.bat", "sechroom"] : ["sechroom"];
|
|
2056
|
+
for (const dir of pathEnv.split(delimiter)) {
|
|
2057
|
+
if (!dir) continue;
|
|
2058
|
+
for (const name of names) {
|
|
2059
|
+
if (existsSync4(join4(dir, name))) return true;
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
return false;
|
|
2063
|
+
}
|
|
2064
|
+
function warnIfSechroomNotOnPath(write = (s) => void process.stderr.write(s)) {
|
|
2065
|
+
if (isSechroomOnPath()) return false;
|
|
2066
|
+
write(
|
|
2067
|
+
"\n\u26A0 `sechroom` isn't on your PATH. The hooks run a bare `sechroom hook \u2026` command\n when your agent fires them, so a non-global install (npx / local) will fail at\n that point. Install globally so the command resolves:\n npm i -g @sechroom/cli\n"
|
|
2068
|
+
);
|
|
2069
|
+
return true;
|
|
2070
|
+
}
|
|
2052
2071
|
function registerHook(program2) {
|
|
2053
2072
|
const hook = program2.command("hook").description("Agent-lifecycle hook adapter (Claude Code / Codex) \u2014 bridges hooks to continuity");
|
|
2054
2073
|
hook.addHelpText(
|
|
@@ -2160,6 +2179,7 @@ Fail-soft: no lane / no auth / no-or-partial intent file / API error -> exit 0,
|
|
|
2160
2179
|
} else {
|
|
2161
2180
|
process.stdout.write("\nRestart (or reload) your agent for the hooks to take effect.\n");
|
|
2162
2181
|
}
|
|
2182
|
+
warnIfSechroomNotOnPath();
|
|
2163
2183
|
return process.exit(0);
|
|
2164
2184
|
});
|
|
2165
2185
|
}
|
|
@@ -2588,9 +2608,47 @@ async function applyClient(cfg, setup, target, opts) {
|
|
|
2588
2608
|
return actions;
|
|
2589
2609
|
}
|
|
2590
2610
|
|
|
2611
|
+
// src/setup/hooks-offer.ts
|
|
2612
|
+
import { homedir as homedir4 } from "os";
|
|
2613
|
+
async function maybeOfferHooks(opts) {
|
|
2614
|
+
if (opts.dryRun) return;
|
|
2615
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
2616
|
+
const surfaces = detectHookSurfaces(cwd);
|
|
2617
|
+
if (surfaces.length === 0) return;
|
|
2618
|
+
const names = surfaces.map((s) => HOOK_SURFACE_LABEL[s]).join(" + ");
|
|
2619
|
+
process.stderr.write(
|
|
2620
|
+
`
|
|
2621
|
+
Sechroom can wire continuity lifecycle hooks into ${style.bold(names)} so your agent
|
|
2622
|
+
auto-resumes where you left off and checkpoints working state before compacting.
|
|
2623
|
+
`
|
|
2624
|
+
);
|
|
2625
|
+
const install = opts.yes ? true : canPrompt() ? await promptYesNo(`Install the continuity hooks for ${names}?`) : false;
|
|
2626
|
+
if (!install) return;
|
|
2627
|
+
try {
|
|
2628
|
+
const installed = installHookSurfaces(surfaces, { dryRun: false, cwd, home: homedir4() });
|
|
2629
|
+
let changed = false;
|
|
2630
|
+
for (const { surface, results } of installed) {
|
|
2631
|
+
for (const r of results) {
|
|
2632
|
+
if (r.status !== "current") changed = true;
|
|
2633
|
+
const verb = r.status === "current" ? "already configured" : r.status === "created" ? "created" : "updated";
|
|
2634
|
+
process.stderr.write(`${style.green("\u2713")} ${HOOK_SURFACE_LABEL[surface]}: ${r.path} (${verb})
|
|
2635
|
+
`);
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
if (changed) {
|
|
2639
|
+
process.stderr.write(`${style.dim("Restart (or reload) your agent for the hooks to take effect.")}
|
|
2640
|
+
`);
|
|
2641
|
+
}
|
|
2642
|
+
warnIfSechroomNotOnPath();
|
|
2643
|
+
} catch (err2) {
|
|
2644
|
+
process.stderr.write(`${style.dim(`(skipped hook install: ${err2.message})`)}
|
|
2645
|
+
`);
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2591
2649
|
// src/setup/skills-offer.ts
|
|
2592
2650
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
2593
|
-
import { homedir as
|
|
2651
|
+
import { homedir as homedir5 } from "os";
|
|
2594
2652
|
import { join as join5 } from "path";
|
|
2595
2653
|
|
|
2596
2654
|
// src/setup/lane-pin.ts
|
|
@@ -2706,7 +2764,7 @@ async function maybeOfferSkills(cfg, personalWorkspaceId, opts) {
|
|
|
2706
2764
|
Found ${style.bold(String(names.length))} operator skill(s) installed in your workspace: ${names.join(", ")}.
|
|
2707
2765
|
`
|
|
2708
2766
|
);
|
|
2709
|
-
const dir = join5(
|
|
2767
|
+
const dir = join5(homedir5(), ".claude", "skills");
|
|
2710
2768
|
const materialise = opts.yes ? true : canPrompt() ? await promptYesNo(`Write them to ${dir}/ so ${surface} can use them?`) : false;
|
|
2711
2769
|
if (!materialise) return;
|
|
2712
2770
|
const written = [];
|
|
@@ -2810,6 +2868,9 @@ Examples:
|
|
|
2810
2868
|
if (!json && !opts.dryRun && !opts.mcpOnly) {
|
|
2811
2869
|
await maybeOfferSkills(cfg, personalWorkspaceId, { yes: false, dryRun: Boolean(opts.dryRun), surface: "claude-code" });
|
|
2812
2870
|
}
|
|
2871
|
+
if (!json && !opts.dryRun && !opts.mcpOnly) {
|
|
2872
|
+
await maybeOfferHooks({ yes: false, dryRun: Boolean(opts.dryRun), cwd: process.cwd() });
|
|
2873
|
+
}
|
|
2813
2874
|
if (json) {
|
|
2814
2875
|
emit({ dryRun: Boolean(opts.dryRun), clients: result }, true);
|
|
2815
2876
|
return;
|
|
@@ -2865,43 +2926,6 @@ async function runClients(clients, cmd, opts) {
|
|
|
2865
2926
|
process.stdout.write(opts.dryRun ? "\n(dry run \u2014 nothing written)\n" : "\nDone.\n");
|
|
2866
2927
|
}
|
|
2867
2928
|
|
|
2868
|
-
// src/setup/hooks-offer.ts
|
|
2869
|
-
import { homedir as homedir5 } from "os";
|
|
2870
|
-
async function maybeOfferHooks(opts) {
|
|
2871
|
-
if (opts.dryRun) return;
|
|
2872
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
2873
|
-
const surfaces = detectHookSurfaces(cwd);
|
|
2874
|
-
if (surfaces.length === 0) return;
|
|
2875
|
-
const names = surfaces.map((s) => HOOK_SURFACE_LABEL[s]).join(" + ");
|
|
2876
|
-
process.stderr.write(
|
|
2877
|
-
`
|
|
2878
|
-
Sechroom can wire continuity lifecycle hooks into ${style.bold(names)} so your agent
|
|
2879
|
-
auto-resumes where you left off and checkpoints working state before compacting.
|
|
2880
|
-
`
|
|
2881
|
-
);
|
|
2882
|
-
const install = opts.yes ? true : canPrompt() ? await promptYesNo(`Install the continuity hooks for ${names}?`) : false;
|
|
2883
|
-
if (!install) return;
|
|
2884
|
-
try {
|
|
2885
|
-
const installed = installHookSurfaces(surfaces, { dryRun: false, cwd, home: homedir5() });
|
|
2886
|
-
let changed = false;
|
|
2887
|
-
for (const { surface, results } of installed) {
|
|
2888
|
-
for (const r of results) {
|
|
2889
|
-
if (r.status !== "current") changed = true;
|
|
2890
|
-
const verb = r.status === "current" ? "already configured" : r.status === "created" ? "created" : "updated";
|
|
2891
|
-
process.stderr.write(`${style.green("\u2713")} ${HOOK_SURFACE_LABEL[surface]}: ${r.path} (${verb})
|
|
2892
|
-
`);
|
|
2893
|
-
}
|
|
2894
|
-
}
|
|
2895
|
-
if (changed) {
|
|
2896
|
-
process.stderr.write(`${style.dim("Restart (or reload) your agent for the hooks to take effect.")}
|
|
2897
|
-
`);
|
|
2898
|
-
}
|
|
2899
|
-
} catch (err2) {
|
|
2900
|
-
process.stderr.write(`${style.dim(`(skipped hook install: ${err2.message})`)}
|
|
2901
|
-
`);
|
|
2902
|
-
}
|
|
2903
|
-
}
|
|
2904
|
-
|
|
2905
2929
|
// src/commands/onboard.ts
|
|
2906
2930
|
var DEFAULT_BASE_URL2 = "https://app.sechroom.ai/api";
|
|
2907
2931
|
function systemTimezone() {
|
package/package.json
CHANGED