@sechroom/cli 2026.6.140-rc.176770e1 → 2026.6.141-rc.6cc560b2
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 +79 -137
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2859,9 +2859,9 @@ auto-resumes where you left off and checkpoints working state before compacting.
|
|
|
2859
2859
|
}
|
|
2860
2860
|
|
|
2861
2861
|
// src/setup/skills-offer.ts
|
|
2862
|
-
import { mkdirSync as
|
|
2863
|
-
import { homedir as
|
|
2864
|
-
import { join as
|
|
2862
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
2863
|
+
import { homedir as homedir6 } from "os";
|
|
2864
|
+
import { join as join6 } from "path";
|
|
2865
2865
|
|
|
2866
2866
|
// src/setup/lane-pin.ts
|
|
2867
2867
|
var CODE_LANE_PREFIX_BY_CLIENT = {
|
|
@@ -2981,6 +2981,34 @@ function resolveSkills(systemRows, personalRows, surface) {
|
|
|
2981
2981
|
return [...merged.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
2982
2982
|
}
|
|
2983
2983
|
|
|
2984
|
+
// src/setup/skills-lock.ts
|
|
2985
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
2986
|
+
import { homedir as homedir5 } from "os";
|
|
2987
|
+
import { join as join5 } from "path";
|
|
2988
|
+
var SKILLS_LOCK = ".sechroom-skills.json";
|
|
2989
|
+
var DEFAULT_SKILLS_SLUG = "operator-skills";
|
|
2990
|
+
function skillsDir(global) {
|
|
2991
|
+
return global ? join5(homedir5(), ".claude", "skills") : join5(process.cwd(), ".claude", "skills");
|
|
2992
|
+
}
|
|
2993
|
+
function readSkillsLock(dir) {
|
|
2994
|
+
const lockPath = join5(dir, SKILLS_LOCK);
|
|
2995
|
+
if (!existsSync6(lockPath)) return {};
|
|
2996
|
+
try {
|
|
2997
|
+
return JSON.parse(readFileSync5(lockPath, "utf8"));
|
|
2998
|
+
} catch {
|
|
2999
|
+
return {};
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
function writeSkillsLock(dir, lock) {
|
|
3003
|
+
mkdirSync5(dir, { recursive: true });
|
|
3004
|
+
writeFileSync5(join5(dir, SKILLS_LOCK), JSON.stringify(lock, null, 2) + "\n");
|
|
3005
|
+
}
|
|
3006
|
+
function recordMaterialisedSkills(dir, slug, skills, meta = {}) {
|
|
3007
|
+
const lock = readSkillsLock(dir);
|
|
3008
|
+
lock[slug] = { surface: meta.surface, skills: [...skills].sort() };
|
|
3009
|
+
writeSkillsLock(dir, lock);
|
|
3010
|
+
}
|
|
3011
|
+
|
|
2984
3012
|
// src/setup/skills-offer.ts
|
|
2985
3013
|
async function fetchFeedRows(cfg, workspaceId) {
|
|
2986
3014
|
try {
|
|
@@ -3020,18 +3048,19 @@ Would materialise ${style.bold(String(resolved.length))} operator skill(s) for $
|
|
|
3020
3048
|
Found ${style.bold(String(names.length))} operator skill(s) available to you: ${names.join(", ")}.
|
|
3021
3049
|
`
|
|
3022
3050
|
);
|
|
3023
|
-
const dir =
|
|
3051
|
+
const dir = join6(homedir6(), ".claude", "skills");
|
|
3024
3052
|
const materialise = opts.yes ? true : canPrompt() ? await promptYesNo(`Write them to ${dir}/ so ${surface} can use them?`) : false;
|
|
3025
3053
|
if (!materialise) return;
|
|
3026
3054
|
const written = [];
|
|
3027
3055
|
for (const s of resolved) {
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3056
|
+
mkdirSync6(join6(dir, s.name), { recursive: true });
|
|
3057
|
+
writeFileSync6(
|
|
3058
|
+
join6(dir, s.name, "SKILL.md"),
|
|
3031
3059
|
s.body.endsWith("\n") ? s.body : s.body + "\n"
|
|
3032
3060
|
);
|
|
3033
3061
|
written.push(s.name);
|
|
3034
3062
|
}
|
|
3063
|
+
recordMaterialisedSkills(dir, DEFAULT_SKILLS_SLUG, written, { surface });
|
|
3035
3064
|
process.stderr.write(
|
|
3036
3065
|
`${style.green("\u2713")} wrote ${written.length} skill(s) to ${dir}
|
|
3037
3066
|
`
|
|
@@ -3191,13 +3220,13 @@ async function runClients(clients, cmd, opts) {
|
|
|
3191
3220
|
}
|
|
3192
3221
|
|
|
3193
3222
|
// src/commands/onboard.ts
|
|
3194
|
-
import { existsSync as
|
|
3195
|
-
import { basename as basename3, join as
|
|
3223
|
+
import { existsSync as existsSync8 } from "fs";
|
|
3224
|
+
import { basename as basename3, join as join8 } from "path";
|
|
3196
3225
|
|
|
3197
3226
|
// src/commands/fanout.ts
|
|
3198
3227
|
import { spawnSync } from "child_process";
|
|
3199
|
-
import { existsSync as
|
|
3200
|
-
import { isAbsolute, join as
|
|
3228
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync, statSync } from "fs";
|
|
3229
|
+
import { isAbsolute, join as join7, resolve } from "path";
|
|
3201
3230
|
var ICON = {
|
|
3202
3231
|
refresh: "\u21BB",
|
|
3203
3232
|
bind: "+",
|
|
@@ -3217,21 +3246,21 @@ function discoverChildren(root) {
|
|
|
3217
3246
|
const out = [];
|
|
3218
3247
|
for (const name of names.sort()) {
|
|
3219
3248
|
if (name.startsWith(".") || name === "node_modules") continue;
|
|
3220
|
-
const dir =
|
|
3249
|
+
const dir = join7(root, name);
|
|
3221
3250
|
try {
|
|
3222
3251
|
if (!statSync(dir).isDirectory()) continue;
|
|
3223
3252
|
} catch {
|
|
3224
3253
|
continue;
|
|
3225
3254
|
}
|
|
3226
|
-
if (
|
|
3255
|
+
if (existsSync7(join7(dir, ".git")) || committedBindingPath(dir)) out.push(name);
|
|
3227
3256
|
}
|
|
3228
3257
|
return out;
|
|
3229
3258
|
}
|
|
3230
3259
|
function readManifest(path) {
|
|
3231
|
-
if (!
|
|
3260
|
+
if (!existsSync7(path)) return null;
|
|
3232
3261
|
let parsed;
|
|
3233
3262
|
try {
|
|
3234
|
-
parsed = JSON.parse(
|
|
3263
|
+
parsed = JSON.parse(readFileSync6(path, "utf8"));
|
|
3235
3264
|
} catch (err2) {
|
|
3236
3265
|
throw new Error(`couldn't parse ${path}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
3237
3266
|
}
|
|
@@ -3596,10 +3625,10 @@ async function chooseClients(clientFlag, yes, cwd) {
|
|
|
3596
3625
|
}
|
|
3597
3626
|
async function planRecurseChild(entry, root, client, opts) {
|
|
3598
3627
|
const dir = resolveChildDir(entry.path, root);
|
|
3599
|
-
if (!
|
|
3628
|
+
if (!existsSync8(dir)) {
|
|
3600
3629
|
return { label: entry.path, dir, disposition: "skip-missing", argv: [], reason: "directory does not exist" };
|
|
3601
3630
|
}
|
|
3602
|
-
if (
|
|
3631
|
+
if (existsSync8(join8(dir, ".sechroom.json"))) {
|
|
3603
3632
|
return {
|
|
3604
3633
|
label: entry.path,
|
|
3605
3634
|
dir,
|
|
@@ -3672,7 +3701,7 @@ This fan-out will pin the same lane in every repo:
|
|
|
3672
3701
|
async function runRecurse(cfg, g, opts) {
|
|
3673
3702
|
const { yes, dryRun, json } = opts;
|
|
3674
3703
|
const root = process.cwd();
|
|
3675
|
-
const manifestPath =
|
|
3704
|
+
const manifestPath = join8(root, ".sechroom", "repos.json");
|
|
3676
3705
|
const fromManifest = readManifest(manifestPath);
|
|
3677
3706
|
const entries = fromManifest ?? discoverChildren(root).map((path) => ({ path }));
|
|
3678
3707
|
const sourceLabel = fromManifest ? `manifest ${manifestPath}` : `auto-discovered under ${root}`;
|
|
@@ -3886,12 +3915,12 @@ async function printStarterPrompt(mode, cfg) {
|
|
|
3886
3915
|
}
|
|
3887
3916
|
|
|
3888
3917
|
// src/commands/sweep.ts
|
|
3889
|
-
import { existsSync as
|
|
3890
|
-
import { dirname as dirname6, join as
|
|
3891
|
-
var DEFAULT_MANIFEST =
|
|
3918
|
+
import { existsSync as existsSync9 } from "fs";
|
|
3919
|
+
import { dirname as dirname6, join as join9, resolve as resolve2 } from "path";
|
|
3920
|
+
var DEFAULT_MANIFEST = join9(".sechroom", "repos.json");
|
|
3892
3921
|
function planEntry(entry, root) {
|
|
3893
3922
|
const dir = resolveChildDir(entry.path, root);
|
|
3894
|
-
if (!
|
|
3923
|
+
if (!existsSync9(dir)) {
|
|
3895
3924
|
return { label: entry.path, dir, disposition: "skip-missing", argv: [], reason: "directory does not exist" };
|
|
3896
3925
|
}
|
|
3897
3926
|
if (committedBindingPath(dir)) {
|
|
@@ -3985,106 +4014,21 @@ Examples:
|
|
|
3985
4014
|
}
|
|
3986
4015
|
|
|
3987
4016
|
// src/commands/skills.ts
|
|
3988
|
-
import {
|
|
3989
|
-
import {
|
|
3990
|
-
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, rmSync as rmSync2, existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
|
|
3991
|
-
var DEFAULT_SLUG = "operator-skills";
|
|
3992
|
-
var ROLE_TAGS = ["sechroom:role:skill-template", "role:skill-template"];
|
|
3993
|
-
var LOCK = ".sechroom-skills.json";
|
|
3994
|
-
function skillsDir(global) {
|
|
3995
|
-
return global ? join9(homedir6(), ".claude", "skills") : join9(process.cwd(), ".claude", "skills");
|
|
3996
|
-
}
|
|
3997
|
-
function tagValue2(tags, prefix) {
|
|
3998
|
-
return (tags ?? []).find((t) => t.startsWith(prefix))?.slice(prefix.length);
|
|
3999
|
-
}
|
|
4000
|
-
function hasAny(tags, candidates) {
|
|
4001
|
-
return (tags ?? []).some((t) => candidates.includes(t));
|
|
4002
|
-
}
|
|
4017
|
+
import { join as join10 } from "path";
|
|
4018
|
+
import { existsSync as existsSync10, rmSync as rmSync2 } from "fs";
|
|
4003
4019
|
function registerSkills(program2) {
|
|
4004
|
-
const skills = program2.command("skills").description("
|
|
4020
|
+
const skills = program2.command("skills").description("Manage operator skills (materialised by `onboard`)");
|
|
4005
4021
|
skills.addHelpText(
|
|
4006
4022
|
"after",
|
|
4007
4023
|
`
|
|
4008
4024
|
Examples:
|
|
4009
|
-
$ sechroom skills install --code-lane claude-code-chris --design-lane claude-design-chris
|
|
4010
|
-
$ sechroom skills install operator-skills --surface claude-code --local
|
|
4011
4025
|
$ sechroom skills list
|
|
4012
4026
|
$ sechroom skills set-lane --code-lane claude-code-chris --design-lane claude-design-chris
|
|
4013
4027
|
$ sechroom skills lane
|
|
4014
|
-
$ sechroom skills clean
|
|
4028
|
+
$ sechroom skills clean
|
|
4029
|
+
|
|
4030
|
+
To install/refresh skills, run 'sechroom onboard' (it offers to materialise them).`
|
|
4015
4031
|
);
|
|
4016
|
-
skills.command("install [slug]").description(`Install a skills bundle (default ${DEFAULT_SLUG}) into your personal workspace + write SKILL.md files`).option("--version <v>", "bundle version (default: latest published in the catalogue)").option("--instance <name>", "install as a named, separate instance (install the same bundle more than once)").option("--code-lane <id>", "identity.code-lane binding (e.g. claude-code-chris)").option("--design-lane <id>", "identity.design-lane binding (e.g. claude-design-chris)").option("--surface <s>", "skill target surface to materialise", "claude-code").option("--local", "write to ./.claude/skills instead of ~/.claude/skills").option("--json", "machine output").action(async (slugArg, opts, cmd) => {
|
|
4017
|
-
const slug = slugArg || DEFAULT_SLUG;
|
|
4018
|
-
const client = await makeClient(resolveConfig(cmd.optsWithGlobals()));
|
|
4019
|
-
const pw = await runApi("resolving personal workspace", () => client.GET("/me/personal-workspace", {}));
|
|
4020
|
-
const personalWsId = pw?.id || pw?.workspaceId || pw?.personalWorkspaceId || pw?.item?.id;
|
|
4021
|
-
if (!personalWsId) fail("Could not resolve your personal workspace.");
|
|
4022
|
-
let version = opts.version;
|
|
4023
|
-
if (!version) {
|
|
4024
|
-
const cat = await runApi("reading the bundle catalogue", () => client.GET("/me/bundles", {}));
|
|
4025
|
-
const item = (cat?.bundles ?? cat?.Bundles ?? []).find((b) => (b.slug ?? b.Slug) === slug);
|
|
4026
|
-
if (!item) fail(`Bundle '${slug}' is not in your self-serve catalogue (must be UserInstallable + Published).`);
|
|
4027
|
-
version = item.latestVersion ?? item.LatestVersion;
|
|
4028
|
-
if (!version) fail(`Bundle '${slug}' has no installable (Published) version.`);
|
|
4029
|
-
}
|
|
4030
|
-
const installOptions = {};
|
|
4031
|
-
if (opts.codeLane) installOptions["identity.code-lane"] = opts.codeLane;
|
|
4032
|
-
if (opts.designLane) installOptions["identity.design-lane"] = opts.designLane;
|
|
4033
|
-
const res = await runApi(
|
|
4034
|
-
`installing ${slug}@${version}${opts.instance ? ` (${opts.instance})` : ""}`,
|
|
4035
|
-
() => client.POST("/me/bundles/{slug}/versions/{version}/install", {
|
|
4036
|
-
params: { path: { slug, version } },
|
|
4037
|
-
// instance: null/absent = the default instance (reinstall updates in
|
|
4038
|
-
// place); a name installs a separate instance.
|
|
4039
|
-
body: { installOptions, instance: opts.instance ?? null }
|
|
4040
|
-
})
|
|
4041
|
-
);
|
|
4042
|
-
const status = String(res?.status ?? res?.Status ?? "");
|
|
4043
|
-
if (status && status.toLowerCase() !== "completed") {
|
|
4044
|
-
fail(`Install did not complete (status=${status}; ${res?.failureReason ?? res?.FailureReason ?? ""}).`);
|
|
4045
|
-
}
|
|
4046
|
-
const feed = await runApi(
|
|
4047
|
-
"materialising skill files",
|
|
4048
|
-
() => client.GET("/workspaces/{workspaceId}/memories/feed", {
|
|
4049
|
-
// cascadeWorkspaces: skills land in an "Operator Skills" SUB-workspace of
|
|
4050
|
-
// the personal workspace, so we recurse from the personal-ws root.
|
|
4051
|
-
// includeText: the feed omits bodies by default; we need them for SKILL.md.
|
|
4052
|
-
params: {
|
|
4053
|
-
path: { workspaceId: personalWsId },
|
|
4054
|
-
query: { limit: 200, cascadeWorkspaces: true, includeText: true }
|
|
4055
|
-
}
|
|
4056
|
-
})
|
|
4057
|
-
);
|
|
4058
|
-
const rows = feed?.results ?? feed?.Results ?? [];
|
|
4059
|
-
const dir = skillsDir(!opts.local);
|
|
4060
|
-
const wantInstance = opts.instance || "default";
|
|
4061
|
-
const written = [];
|
|
4062
|
-
const bundleTagPrefix = `sechroom:bundle:${slug}@`;
|
|
4063
|
-
for (const r of rows) {
|
|
4064
|
-
const m = r.item ?? r;
|
|
4065
|
-
const tags = m.tags ?? m.Tags ?? [];
|
|
4066
|
-
if (!hasAny(tags, ROLE_TAGS)) continue;
|
|
4067
|
-
if (tagValue2(tags, "target:") !== opts.surface) continue;
|
|
4068
|
-
if (!tags.some((t) => t.startsWith(bundleTagPrefix))) continue;
|
|
4069
|
-
if ((tagValue2(tags, "sechroom:skill-instance:") ?? "default") !== wantInstance) continue;
|
|
4070
|
-
const name = tagValue2(tags, "skill:");
|
|
4071
|
-
if (!name) continue;
|
|
4072
|
-
const body = m.text ?? m.Text ?? "";
|
|
4073
|
-
mkdirSync6(join9(dir, name), { recursive: true });
|
|
4074
|
-
writeFileSync6(join9(dir, name, "SKILL.md"), body.endsWith("\n") ? body : body + "\n");
|
|
4075
|
-
written.push(name);
|
|
4076
|
-
}
|
|
4077
|
-
mkdirSync6(dir, { recursive: true });
|
|
4078
|
-
const lockPath = join9(dir, LOCK);
|
|
4079
|
-
const lock = existsSync9(lockPath) ? JSON.parse(readFileSync6(lockPath, "utf8")) : {};
|
|
4080
|
-
lock[slug] = { surface: opts.surface, version, instance: wantInstance, skills: written.sort() };
|
|
4081
|
-
writeFileSync6(lockPath, JSON.stringify(lock, null, 2) + "\n");
|
|
4082
|
-
if (opts.json) return emit({ slug, version, instance: wantInstance, surface: opts.surface, dir, installed: written }, true);
|
|
4083
|
-
const instanceNote = opts.instance ? ` (${opts.instance})` : "";
|
|
4084
|
-
console.log(style.green(`Installed ${slug}@${version}${instanceNote} \u2014 ${written.length} skill(s) \u2192 ${dir}`));
|
|
4085
|
-
written.forEach((n) => console.log(" " + style.dim("\u2022") + " " + n));
|
|
4086
|
-
if (written.length === 0) console.log(style.dim(` (no '${opts.surface}' skill bodies found; check --surface)`));
|
|
4087
|
-
});
|
|
4088
4032
|
skills.command("list").description("List your installed bundles (GET /me/bundle-installs)").option("--json", "machine output").action(async (opts, cmd) => {
|
|
4089
4033
|
const client = await makeClient(resolveConfig(cmd.optsWithGlobals()));
|
|
4090
4034
|
const data = await runApi("reading your installs", () => client.GET("/me/bundle-installs", {}));
|
|
@@ -4097,24 +4041,22 @@ Examples:
|
|
|
4097
4041
|
console.log(` ${i.bundleSlug ?? i.BundleSlug}@${i.bundleVersion ?? i.BundleVersion ?? "?"}${tag}`);
|
|
4098
4042
|
});
|
|
4099
4043
|
});
|
|
4100
|
-
skills.command("clean [slug]").description(`Remove
|
|
4101
|
-
const slug = slugArg ||
|
|
4044
|
+
skills.command("clean [slug]").description(`Remove skill files materialised by onboard (default ${DEFAULT_SKILLS_SLUG})`).option("--local", "clean ./.claude/skills instead of ~/.claude/skills").option("--json", "machine output").action(async (slugArg, opts) => {
|
|
4045
|
+
const slug = slugArg || DEFAULT_SKILLS_SLUG;
|
|
4102
4046
|
const dir = skillsDir(!opts.local);
|
|
4103
|
-
const
|
|
4104
|
-
if (!existsSync9(lockPath)) fail(`No skills lockfile at ${lockPath}; nothing to clean.`);
|
|
4105
|
-
const lock = JSON.parse(readFileSync6(lockPath, "utf8"));
|
|
4047
|
+
const lock = readSkillsLock(dir);
|
|
4106
4048
|
const entry = lock[slug];
|
|
4107
|
-
if (!entry) fail(`No
|
|
4049
|
+
if (!entry) fail(`No materialised skills recorded for '${slug}' in ${join10(dir, SKILLS_LOCK)}.`);
|
|
4108
4050
|
const removed = [];
|
|
4109
4051
|
for (const name of entry.skills) {
|
|
4110
|
-
const skillPath =
|
|
4111
|
-
if (
|
|
4052
|
+
const skillPath = join10(dir, name);
|
|
4053
|
+
if (existsSync10(skillPath)) {
|
|
4112
4054
|
rmSync2(skillPath, { recursive: true, force: true });
|
|
4113
4055
|
removed.push(name);
|
|
4114
4056
|
}
|
|
4115
4057
|
}
|
|
4116
4058
|
delete lock[slug];
|
|
4117
|
-
|
|
4059
|
+
writeSkillsLock(dir, lock);
|
|
4118
4060
|
if (opts.json) return emit({ slug, removed, dir }, true);
|
|
4119
4061
|
console.log(style.green(`Removed ${removed.length} skill(s) for ${slug} from ${dir}`));
|
|
4120
4062
|
});
|
|
@@ -4204,21 +4146,21 @@ Examples:
|
|
|
4204
4146
|
|
|
4205
4147
|
// src/commands/reset.ts
|
|
4206
4148
|
import { homedir as homedir7 } from "os";
|
|
4207
|
-
import { join as
|
|
4208
|
-
import { existsSync as
|
|
4209
|
-
var
|
|
4210
|
-
var localSkillsDir = () =>
|
|
4211
|
-
var globalSkillsDir = () =>
|
|
4149
|
+
import { join as join11 } from "path";
|
|
4150
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, rmSync as rmSync3 } from "fs";
|
|
4151
|
+
var SKILLS_LOCK2 = ".sechroom-skills.json";
|
|
4152
|
+
var localSkillsDir = () => join11(process.cwd(), ".claude", "skills");
|
|
4153
|
+
var globalSkillsDir = () => join11(homedir7(), ".claude", "skills");
|
|
4212
4154
|
function removeMaterialisedSkills(dir) {
|
|
4213
4155
|
const removed = [];
|
|
4214
|
-
const lockPath =
|
|
4215
|
-
if (!
|
|
4156
|
+
const lockPath = join11(dir, SKILLS_LOCK2);
|
|
4157
|
+
if (!existsSync11(lockPath)) return removed;
|
|
4216
4158
|
try {
|
|
4217
4159
|
const lock = JSON.parse(readFileSync7(lockPath, "utf8"));
|
|
4218
4160
|
for (const entry of Object.values(lock)) {
|
|
4219
4161
|
for (const name of entry.skills ?? []) {
|
|
4220
|
-
const p =
|
|
4221
|
-
if (
|
|
4162
|
+
const p = join11(dir, name);
|
|
4163
|
+
if (existsSync11(p)) {
|
|
4222
4164
|
rmSync3(p, { recursive: true, force: true });
|
|
4223
4165
|
removed.push(p);
|
|
4224
4166
|
}
|
|
@@ -4263,18 +4205,18 @@ function registerReset(program2) {
|
|
|
4263
4205
|
}
|
|
4264
4206
|
}
|
|
4265
4207
|
const removed = [];
|
|
4266
|
-
const stateDir =
|
|
4267
|
-
if (
|
|
4208
|
+
const stateDir = join11(process.cwd(), ".sechroom");
|
|
4209
|
+
if (existsSync11(stateDir)) {
|
|
4268
4210
|
rmSync3(stateDir, { recursive: true, force: true });
|
|
4269
4211
|
removed.push(stateDir);
|
|
4270
4212
|
}
|
|
4271
|
-
const legacyCfg =
|
|
4272
|
-
if (
|
|
4213
|
+
const legacyCfg = join11(process.cwd(), ".sechroom.json");
|
|
4214
|
+
if (existsSync11(legacyCfg)) {
|
|
4273
4215
|
rmSync3(legacyCfg, { force: true });
|
|
4274
4216
|
removed.push(legacyCfg);
|
|
4275
4217
|
}
|
|
4276
|
-
const legacySem =
|
|
4277
|
-
if (
|
|
4218
|
+
const legacySem = join11(process.cwd(), ".sem");
|
|
4219
|
+
if (existsSync11(legacySem)) {
|
|
4278
4220
|
rmSync3(legacySem, { force: true });
|
|
4279
4221
|
removed.push(legacySem);
|
|
4280
4222
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sechroom/cli",
|
|
3
|
-
"version": "2026.6.
|
|
3
|
+
"version": "2026.6.141-rc.6cc560b2",
|
|
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",
|