@launchsecure/launch-kit 0.0.39 → 0.0.40
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/chart-client/assets/index-CWJFFDPu.css +1 -0
- package/dist/chart-client/index.html +2 -2
- package/dist/client/assets/index-CTzFcfGV.css +32 -0
- package/dist/client/index.html +2 -2
- package/dist/council-client/assets/index-ArgRc5mN.css +1 -0
- package/dist/council-client/index.html +2 -2
- package/dist/deck-client/assets/{_baseUniq-DOrnEQMI.js → _baseUniq-BZP7n41F.js} +1 -1
- package/dist/deck-client/assets/{arc-DOWK7V3m.js → arc-31biU3Az.js} +1 -1
- package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-DPhzvk7q.js → architectureDiagram-Q4EWVU46-DHg6Ss--.js} +1 -1
- package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-CwAGy9lU.js → blockDiagram-DXYQGD6D-CUdblaWk.js} +1 -1
- package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-L_g_SS21.js → c4Diagram-AHTNJAMY-MfAO5lak.js} +1 -1
- package/dist/deck-client/assets/channel-BBkRLdnC.js +1 -0
- package/dist/deck-client/assets/{chunk-4BX2VUAB-RKm0LXpu.js → chunk-4BX2VUAB-DQ1MrGgN.js} +1 -1
- package/dist/deck-client/assets/{chunk-4TB4RGXK-Bk0FUbxU.js → chunk-4TB4RGXK-BUJtZ7jO.js} +1 -1
- package/dist/deck-client/assets/{chunk-55IACEB6-Cl3hja-M.js → chunk-55IACEB6-BdSnXB6g.js} +1 -1
- package/dist/deck-client/assets/{chunk-EDXVE4YY-CNIMQCV2.js → chunk-EDXVE4YY-94yZIUI8.js} +1 -1
- package/dist/deck-client/assets/{chunk-FMBD7UC4-DqOvWr1k.js → chunk-FMBD7UC4-PnZ9v6ey.js} +1 -1
- package/dist/deck-client/assets/{chunk-OYMX7WX6-1Kd7yK5u.js → chunk-OYMX7WX6-DXrWNOsV.js} +1 -1
- package/dist/deck-client/assets/{chunk-QZHKN3VN-6_kraYpP.js → chunk-QZHKN3VN-CsIGIDKX.js} +1 -1
- package/dist/deck-client/assets/{chunk-YZCP3GAM-FgAwIWlo.js → chunk-YZCP3GAM-DVkBO9tn.js} +1 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-DFCaeF-7.js +1 -0
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-DFCaeF-7.js +1 -0
- package/dist/deck-client/assets/clone-GCEVRScB.js +1 -0
- package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-CigVnnPr.js → cose-bilkent-S5V4N54A-m126Oh3b.js} +1 -1
- package/dist/deck-client/assets/{dagre-KV5264BT-DHZXTktX.js → dagre-KV5264BT-C2aig8U5.js} +1 -1
- package/dist/deck-client/assets/{diagram-5BDNPKRD-H5k0eauU.js → diagram-5BDNPKRD-CKpoRfGn.js} +1 -1
- package/dist/deck-client/assets/{diagram-G4DWMVQ6-Bg3dFhSY.js → diagram-G4DWMVQ6-Cjh115Ep.js} +1 -1
- package/dist/deck-client/assets/{diagram-MMDJMWI5-CQLC410N.js → diagram-MMDJMWI5-DKlBv_2L.js} +1 -1
- package/dist/deck-client/assets/{diagram-TYMM5635-DFTCHVkP.js → diagram-TYMM5635-CdBh4cEn.js} +1 -1
- package/dist/deck-client/assets/{erDiagram-SMLLAGMA-aiv9GZnL.js → erDiagram-SMLLAGMA-56pn_93p.js} +1 -1
- package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-C6Fhvtsy.js → flowDiagram-DWJPFMVM-BtV3M5xJ.js} +1 -1
- package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-DSaGMPM4.js → ganttDiagram-T4ZO3ILL-DTIsC6Zg.js} +1 -1
- package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-DMjL2Vix.js → gitGraphDiagram-UUTBAWPF-CJYeyCLe.js} +1 -1
- package/dist/deck-client/assets/{graph-B7Vn5lkK.js → graph-BDvMu1Ss.js} +1 -1
- package/dist/deck-client/assets/index-D4eSxcBn.css +1 -0
- package/dist/deck-client/assets/{index-BD36e-tD.js → index-QnGVE9PZ.js} +72 -72
- package/dist/deck-client/assets/{infoDiagram-42DDH7IO-mNi4iygG.js → infoDiagram-42DDH7IO-BWyKJnpW.js} +1 -1
- package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-BwCUmUVt.js → ishikawaDiagram-UXIWVN3A-DXYkdO3T.js} +1 -1
- package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-C6qoqJmJ.js → journeyDiagram-VCZTEJTY-C2zBr-J5.js} +1 -1
- package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-Dz1Tt3sA.js → kanban-definition-6JOO6SKY-CdoYLS4Z.js} +1 -1
- package/dist/deck-client/assets/{layout-CZTyRhOG.js → layout-vOnxnCQU.js} +1 -1
- package/dist/deck-client/assets/{linear--7n7iEvd.js → linear-B0J0WCGz.js} +1 -1
- package/dist/deck-client/assets/{min-Bh130DN8.js → min-B0AXlT9L.js} +1 -1
- package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-CfXcK1qH.js → mindmap-definition-QFDTVHPH-oAybLedr.js} +1 -1
- package/dist/deck-client/assets/{pieDiagram-DEJITSTG-DjVHLAVw.js → pieDiagram-DEJITSTG-BjHyHxGk.js} +1 -1
- package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-CXwvZ1i1.js → quadrantDiagram-34T5L4WZ-dtluDZXs.js} +1 -1
- package/dist/deck-client/assets/{requirementDiagram-MS252O5E-Cl6xm0fR.js → requirementDiagram-MS252O5E-Cq8l7bOl.js} +1 -1
- package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-BOH9sLyh.js → sankeyDiagram-XADWPNL6-C1Vih91z.js} +1 -1
- package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-BC1MYBn6.js → sequenceDiagram-FGHM5R23-CYkd7oQK.js} +1 -1
- package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-kNp9bv8K.js → stateDiagram-FHFEXIEX-CtyG8wBK.js} +1 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-BLyKWfcN.js +1 -0
- package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-DKnITsD4.js → timeline-definition-GMOUNBTQ-DZIxSyd1.js} +1 -1
- package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-BdajXRrh.js → vennDiagram-DHZGUBPP-Ct4JVRDM.js} +1 -1
- package/dist/deck-client/assets/wardley-RL74JXVD-V29ycxOW.js +162 -0
- package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-B2hDCDl2.js → wardleyDiagram-NUSXRM2D-D-Ua6Cmi.js} +1 -1
- package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-CvnYFs51.js → xychartDiagram-5P7HB3ND-BPCOuRVl.js} +1 -1
- package/dist/deck-client/index.html +2 -2
- package/dist/server/beacon-monitor-entry.js +106 -24
- package/dist/server/chart-serve.js +544 -247
- package/dist/server/cli.js +743 -324
- package/dist/server/council-entry.js +16 -3
- package/dist/server/council-serve.js +15 -2
- package/dist/server/deck-mcp-entry.js +267 -107
- package/dist/server/deck-serve.js +98 -22
- package/dist/server/graph-mcp-entry.js +866 -357
- package/dist/server/orbit-entry.js +91 -7
- package/dist/server/recall-entry.js +94 -12
- package/dist/server/rover-entry.js +1 -1
- package/package.json +1 -1
- package/scaffolds/statusline/statusline-mcp.sh +68 -19
- package/scaffolds/statusline/statusline-wrapper.sh +12 -9
- package/dist/chart-client/assets/index-ysGpLeOW.css +0 -1
- package/dist/client/assets/index-CMN3tlGP.css +0 -32
- package/dist/council-client/assets/index-ChmNX6bZ.css +0 -1
- package/dist/deck-client/assets/channel-DqiACUUq.js +0 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-D23cq2C3.js +0 -1
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-D23cq2C3.js +0 -1
- package/dist/deck-client/assets/clone-C7jSigGq.js +0 -1
- package/dist/deck-client/assets/index-CGbNOpk9.css +0 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-hRsAFc2t.js +0 -1
- package/dist/deck-client/assets/wardley-RL74JXVD-BL802-su.js +0 -162
- /package/dist/chart-client/assets/{index-BlsuXuQ1.js → index-Dzlj-oCj.js} +0 -0
- /package/dist/client/assets/{index-BA7BHBWT.js → index-tTg_ezUF.js} +0 -0
- /package/dist/council-client/assets/{index-jjBWyhry.js → index-B1v46vTE.js} +0 -0
|
@@ -1385,7 +1385,7 @@ function rewriteEnvFile(filePath, rewrites) {
|
|
|
1385
1385
|
const out = lines.map((line) => {
|
|
1386
1386
|
const m = LINE_RE.exec(line);
|
|
1387
1387
|
if (!m) return line;
|
|
1388
|
-
const [, indent, key,
|
|
1388
|
+
const [, indent, key, sep2, rawValue] = m;
|
|
1389
1389
|
if (!(key in rewrites)) return line;
|
|
1390
1390
|
touched.add(key);
|
|
1391
1391
|
const { quote, inner } = stripQuotes2(rawValue);
|
|
@@ -1396,7 +1396,7 @@ function rewriteEnvFile(filePath, rewrites) {
|
|
|
1396
1396
|
return line;
|
|
1397
1397
|
}
|
|
1398
1398
|
result.changed.push(key);
|
|
1399
|
-
return `${indent}${key}${
|
|
1399
|
+
return `${indent}${key}${sep2}${quote}${next2}${quote}`;
|
|
1400
1400
|
});
|
|
1401
1401
|
for (const key of Object.keys(rewrites)) {
|
|
1402
1402
|
if (!touched.has(key)) result.missing.push(key);
|
|
@@ -3060,10 +3060,93 @@ var init_orbit_mcp = __esm({
|
|
|
3060
3060
|
});
|
|
3061
3061
|
|
|
3062
3062
|
// src/server/orbit-entry.ts
|
|
3063
|
-
var
|
|
3064
|
-
var
|
|
3063
|
+
var import_node_fs14 = require("node:fs");
|
|
3064
|
+
var import_node_path11 = require("node:path");
|
|
3065
3065
|
init_orchestrator();
|
|
3066
3066
|
init_logger();
|
|
3067
|
+
|
|
3068
|
+
// src/server/prune-npx-cache.ts
|
|
3069
|
+
var import_node_fs13 = require("node:fs");
|
|
3070
|
+
var import_node_os5 = require("node:os");
|
|
3071
|
+
var import_node_path10 = require("node:path");
|
|
3072
|
+
var import_node_util = require("node:util");
|
|
3073
|
+
var PKG = "@launchsecure/launch-kit";
|
|
3074
|
+
var readFileAsync = (0, import_node_util.promisify)(import_node_fs13.readFile);
|
|
3075
|
+
var readdirAsync = (0, import_node_util.promisify)(import_node_fs13.readdir);
|
|
3076
|
+
var rmAsync = (0, import_node_util.promisify)(import_node_fs13.rm);
|
|
3077
|
+
var realpathAsync = (0, import_node_util.promisify)(import_node_fs13.realpath);
|
|
3078
|
+
function npxCacheRoot() {
|
|
3079
|
+
const cache = process.env.npm_config_cache;
|
|
3080
|
+
if (cache && cache.trim()) return (0, import_node_path10.join)(cache, "_npx");
|
|
3081
|
+
if (process.platform === "win32") {
|
|
3082
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
3083
|
+
if (localAppData) return (0, import_node_path10.join)(localAppData, "npm-cache", "_npx");
|
|
3084
|
+
}
|
|
3085
|
+
return (0, import_node_path10.join)((0, import_node_os5.homedir)(), ".npm", "_npx");
|
|
3086
|
+
}
|
|
3087
|
+
function ownVersion() {
|
|
3088
|
+
let dir = __dirname;
|
|
3089
|
+
for (let i = 0; i < 8; i++) {
|
|
3090
|
+
try {
|
|
3091
|
+
const pkg = JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path10.join)(dir, "package.json"), "utf8"));
|
|
3092
|
+
if (pkg && pkg.name === PKG) return typeof pkg.version === "string" ? pkg.version : null;
|
|
3093
|
+
} catch {
|
|
3094
|
+
}
|
|
3095
|
+
const parent = (0, import_node_path10.dirname)(dir);
|
|
3096
|
+
if (parent === dir) break;
|
|
3097
|
+
dir = parent;
|
|
3098
|
+
}
|
|
3099
|
+
return null;
|
|
3100
|
+
}
|
|
3101
|
+
async function pruneStaleNpxCache() {
|
|
3102
|
+
try {
|
|
3103
|
+
const version = ownVersion();
|
|
3104
|
+
if (!version) return;
|
|
3105
|
+
const root = npxCacheRoot();
|
|
3106
|
+
let hashes;
|
|
3107
|
+
try {
|
|
3108
|
+
hashes = await readdirAsync(root);
|
|
3109
|
+
} catch {
|
|
3110
|
+
return;
|
|
3111
|
+
}
|
|
3112
|
+
const selfPath = await realpathAsync(process.argv[1] || __dirname).catch(() => __dirname);
|
|
3113
|
+
let reaped = 0;
|
|
3114
|
+
for (const hash of hashes) {
|
|
3115
|
+
const dir = (0, import_node_path10.join)(root, hash);
|
|
3116
|
+
if (selfPath === dir || selfPath.startsWith(dir + import_node_path10.sep)) continue;
|
|
3117
|
+
let ver;
|
|
3118
|
+
try {
|
|
3119
|
+
const lkPkg = JSON.parse(
|
|
3120
|
+
await readFileAsync((0, import_node_path10.join)(dir, "node_modules", PKG, "package.json"), "utf8")
|
|
3121
|
+
);
|
|
3122
|
+
ver = lkPkg.version;
|
|
3123
|
+
} catch {
|
|
3124
|
+
continue;
|
|
3125
|
+
}
|
|
3126
|
+
if (ver === version) continue;
|
|
3127
|
+
try {
|
|
3128
|
+
const top = JSON.parse(await readFileAsync((0, import_node_path10.join)(dir, "package.json"), "utf8"));
|
|
3129
|
+
const spec = top?.dependencies?.[PKG];
|
|
3130
|
+
if (typeof spec === "string" && spec.startsWith("file:")) continue;
|
|
3131
|
+
} catch {
|
|
3132
|
+
}
|
|
3133
|
+
try {
|
|
3134
|
+
await rmAsync(dir, { recursive: true, force: true });
|
|
3135
|
+
reaped++;
|
|
3136
|
+
} catch {
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
if (reaped > 0) {
|
|
3140
|
+
process.stderr.write(
|
|
3141
|
+
`[launch-kit] npx-cache: reaped ${reaped} stale copy(ies), kept v${version}
|
|
3142
|
+
`
|
|
3143
|
+
);
|
|
3144
|
+
}
|
|
3145
|
+
} catch {
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
|
|
3149
|
+
// src/server/orbit-entry.ts
|
|
3067
3150
|
function parseFlags(argv) {
|
|
3068
3151
|
const positional = [];
|
|
3069
3152
|
const flags = { emitCd: false, noBackup: false, skipGates: [], deep: false, all: false, json: false, force: false };
|
|
@@ -3099,6 +3182,7 @@ function parseFlags(argv) {
|
|
|
3099
3182
|
return { positional, flags };
|
|
3100
3183
|
}
|
|
3101
3184
|
async function main() {
|
|
3185
|
+
void pruneStaleNpxCache();
|
|
3102
3186
|
const argv = process.argv.slice(2);
|
|
3103
3187
|
const subcommand = argv[0];
|
|
3104
3188
|
if (!subcommand || subcommand === "mcp") {
|
|
@@ -3328,8 +3412,8 @@ function formatRollup(reports) {
|
|
|
3328
3412
|
return out.join("\n") + "\n";
|
|
3329
3413
|
}
|
|
3330
3414
|
function runInit(projectRoot) {
|
|
3331
|
-
const path = (0,
|
|
3332
|
-
if ((0,
|
|
3415
|
+
const path = (0, import_node_path11.join)(projectRoot, "orbit.json");
|
|
3416
|
+
if ((0, import_node_fs14.existsSync)(path)) {
|
|
3333
3417
|
process.stderr.write(`[launch-orbit] orbit.json already exists at ${path}
|
|
3334
3418
|
`);
|
|
3335
3419
|
process.exit(1);
|
|
@@ -3384,7 +3468,7 @@ function runInit(projectRoot) {
|
|
|
3384
3468
|
full: { resources: ["db", "ports"] }
|
|
3385
3469
|
}
|
|
3386
3470
|
};
|
|
3387
|
-
(0,
|
|
3471
|
+
(0, import_node_fs14.writeFileSync)(path, JSON.stringify(starter, null, 2) + "\n", "utf-8");
|
|
3388
3472
|
process.stdout.write(`\u2713 wrote ${path}
|
|
3389
3473
|
`);
|
|
3390
3474
|
}
|
|
@@ -284,14 +284,14 @@ function pidFilePath(recallDir) {
|
|
|
284
284
|
function existingWatcherPid() {
|
|
285
285
|
const { recallDir } = resolveRecallPaths();
|
|
286
286
|
const pf = pidFilePath(recallDir);
|
|
287
|
-
if (!(0,
|
|
288
|
-
const pid = Number((0,
|
|
287
|
+
if (!(0, import_node_fs2.existsSync)(pf)) return null;
|
|
288
|
+
const pid = Number((0, import_node_fs2.readFileSync)(pf, "utf-8").trim());
|
|
289
289
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
290
290
|
return isPidAlive(pid) ? pid : null;
|
|
291
291
|
}
|
|
292
292
|
function ensureWatcher() {
|
|
293
293
|
const { gitDir, workTree } = resolveRecallPaths();
|
|
294
|
-
if (!(0,
|
|
294
|
+
if (!(0, import_node_fs2.existsSync)(gitDir)) {
|
|
295
295
|
process.stderr.write(
|
|
296
296
|
`[launch-recall mcp] shadow repo missing at ${gitDir} \u2014 run \`launch-recall init\` first. MCP tools will still serve read-only queries, but nothing will be captured.
|
|
297
297
|
`
|
|
@@ -358,7 +358,7 @@ async function handleTool(name, args) {
|
|
|
358
358
|
function doctorTool() {
|
|
359
359
|
const { gitDir, recallDir } = resolveRecallPaths();
|
|
360
360
|
const checks = [];
|
|
361
|
-
const shadowOk = (0,
|
|
361
|
+
const shadowOk = (0, import_node_fs2.existsSync)(gitDir);
|
|
362
362
|
checks.push({
|
|
363
363
|
name: "shadow_repo",
|
|
364
364
|
ok: shadowOk,
|
|
@@ -391,7 +391,7 @@ function doctorTool() {
|
|
|
391
391
|
}
|
|
392
392
|
function reportTool() {
|
|
393
393
|
const { gitDir, recallDir, workTree } = resolveRecallPaths();
|
|
394
|
-
if (!(0,
|
|
394
|
+
if (!(0, import_node_fs2.existsSync)(gitDir)) return { error: "shadow repo not initialised" };
|
|
395
395
|
let totalSnapshots = 0;
|
|
396
396
|
try {
|
|
397
397
|
const out = (0, import_node_child_process2.execFileSync)("git", [`--git-dir=${gitDir}`, "rev-list", "--count", "HEAD"], {
|
|
@@ -425,9 +425,9 @@ function reportTool() {
|
|
|
425
425
|
}
|
|
426
426
|
let config = null;
|
|
427
427
|
const cfgPath = `${workTree}/.launch-recall.json`;
|
|
428
|
-
if ((0,
|
|
428
|
+
if ((0, import_node_fs2.existsSync)(cfgPath)) {
|
|
429
429
|
try {
|
|
430
|
-
config = JSON.parse((0,
|
|
430
|
+
config = JSON.parse((0, import_node_fs2.readFileSync)(cfgPath, "utf-8"));
|
|
431
431
|
} catch {
|
|
432
432
|
}
|
|
433
433
|
}
|
|
@@ -435,7 +435,7 @@ function reportTool() {
|
|
|
435
435
|
}
|
|
436
436
|
function historyTool(path7, limit) {
|
|
437
437
|
const { gitDir, workTree } = resolveRecallPaths();
|
|
438
|
-
if (!(0,
|
|
438
|
+
if (!(0, import_node_fs2.existsSync)(gitDir)) return { error: "shadow repo not initialised", path: path7, snapshots: [] };
|
|
439
439
|
const rel = path7.startsWith("/") ? path7.replace(`${workTree}/`, "").replace(/^\/+/, "") : path7;
|
|
440
440
|
const snapshots = [];
|
|
441
441
|
try {
|
|
@@ -456,7 +456,7 @@ function statusTool() {
|
|
|
456
456
|
const { gitDir, workTree } = resolveRecallPaths();
|
|
457
457
|
const pid = existingWatcherPid();
|
|
458
458
|
let lastSnapshotAt = null;
|
|
459
|
-
if ((0,
|
|
459
|
+
if ((0, import_node_fs2.existsSync)(gitDir)) {
|
|
460
460
|
try {
|
|
461
461
|
lastSnapshotAt = (0, import_node_child_process2.execFileSync)("git", [`--git-dir=${gitDir}`, "log", "-1", "--format=%aI"], {
|
|
462
462
|
encoding: "utf-8",
|
|
@@ -551,14 +551,14 @@ function startRecallMcpServer() {
|
|
|
551
551
|
process.stderr.write("[launch-recall mcp] stdin closed, exiting\n");
|
|
552
552
|
teardown();
|
|
553
553
|
});
|
|
554
|
-
void
|
|
554
|
+
void import_node_fs2.statSync;
|
|
555
555
|
}
|
|
556
|
-
var import_node_child_process2,
|
|
556
|
+
var import_node_child_process2, import_node_fs2, SERVER_INFO, TOOLS, childWatcher;
|
|
557
557
|
var init_recall_mcp = __esm({
|
|
558
558
|
"src/server/recall-mcp.ts"() {
|
|
559
559
|
"use strict";
|
|
560
560
|
import_node_child_process2 = require("node:child_process");
|
|
561
|
-
|
|
561
|
+
import_node_fs2 = require("node:fs");
|
|
562
562
|
init_paths();
|
|
563
563
|
SERVER_INFO = { name: "launch-recall", version: "0.0.1" };
|
|
564
564
|
TOOLS = [
|
|
@@ -1355,6 +1355,87 @@ var init_uninstall = __esm({
|
|
|
1355
1355
|
}
|
|
1356
1356
|
});
|
|
1357
1357
|
|
|
1358
|
+
// src/server/prune-npx-cache.ts
|
|
1359
|
+
var import_node_fs = require("node:fs");
|
|
1360
|
+
var import_node_os = require("node:os");
|
|
1361
|
+
var import_node_path = require("node:path");
|
|
1362
|
+
var import_node_util = require("node:util");
|
|
1363
|
+
var PKG = "@launchsecure/launch-kit";
|
|
1364
|
+
var readFileAsync = (0, import_node_util.promisify)(import_node_fs.readFile);
|
|
1365
|
+
var readdirAsync = (0, import_node_util.promisify)(import_node_fs.readdir);
|
|
1366
|
+
var rmAsync = (0, import_node_util.promisify)(import_node_fs.rm);
|
|
1367
|
+
var realpathAsync = (0, import_node_util.promisify)(import_node_fs.realpath);
|
|
1368
|
+
function npxCacheRoot() {
|
|
1369
|
+
const cache = process.env.npm_config_cache;
|
|
1370
|
+
if (cache && cache.trim()) return (0, import_node_path.join)(cache, "_npx");
|
|
1371
|
+
if (process.platform === "win32") {
|
|
1372
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
1373
|
+
if (localAppData) return (0, import_node_path.join)(localAppData, "npm-cache", "_npx");
|
|
1374
|
+
}
|
|
1375
|
+
return (0, import_node_path.join)((0, import_node_os.homedir)(), ".npm", "_npx");
|
|
1376
|
+
}
|
|
1377
|
+
function ownVersion() {
|
|
1378
|
+
let dir = __dirname;
|
|
1379
|
+
for (let i = 0; i < 8; i++) {
|
|
1380
|
+
try {
|
|
1381
|
+
const pkg = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(dir, "package.json"), "utf8"));
|
|
1382
|
+
if (pkg && pkg.name === PKG) return typeof pkg.version === "string" ? pkg.version : null;
|
|
1383
|
+
} catch {
|
|
1384
|
+
}
|
|
1385
|
+
const parent = (0, import_node_path.dirname)(dir);
|
|
1386
|
+
if (parent === dir) break;
|
|
1387
|
+
dir = parent;
|
|
1388
|
+
}
|
|
1389
|
+
return null;
|
|
1390
|
+
}
|
|
1391
|
+
async function pruneStaleNpxCache() {
|
|
1392
|
+
try {
|
|
1393
|
+
const version = ownVersion();
|
|
1394
|
+
if (!version) return;
|
|
1395
|
+
const root = npxCacheRoot();
|
|
1396
|
+
let hashes;
|
|
1397
|
+
try {
|
|
1398
|
+
hashes = await readdirAsync(root);
|
|
1399
|
+
} catch {
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
const selfPath = await realpathAsync(process.argv[1] || __dirname).catch(() => __dirname);
|
|
1403
|
+
let reaped = 0;
|
|
1404
|
+
for (const hash of hashes) {
|
|
1405
|
+
const dir = (0, import_node_path.join)(root, hash);
|
|
1406
|
+
if (selfPath === dir || selfPath.startsWith(dir + import_node_path.sep)) continue;
|
|
1407
|
+
let ver;
|
|
1408
|
+
try {
|
|
1409
|
+
const lkPkg = JSON.parse(
|
|
1410
|
+
await readFileAsync((0, import_node_path.join)(dir, "node_modules", PKG, "package.json"), "utf8")
|
|
1411
|
+
);
|
|
1412
|
+
ver = lkPkg.version;
|
|
1413
|
+
} catch {
|
|
1414
|
+
continue;
|
|
1415
|
+
}
|
|
1416
|
+
if (ver === version) continue;
|
|
1417
|
+
try {
|
|
1418
|
+
const top = JSON.parse(await readFileAsync((0, import_node_path.join)(dir, "package.json"), "utf8"));
|
|
1419
|
+
const spec = top?.dependencies?.[PKG];
|
|
1420
|
+
if (typeof spec === "string" && spec.startsWith("file:")) continue;
|
|
1421
|
+
} catch {
|
|
1422
|
+
}
|
|
1423
|
+
try {
|
|
1424
|
+
await rmAsync(dir, { recursive: true, force: true });
|
|
1425
|
+
reaped++;
|
|
1426
|
+
} catch {
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
if (reaped > 0) {
|
|
1430
|
+
process.stderr.write(
|
|
1431
|
+
`[launch-kit] npx-cache: reaped ${reaped} stale copy(ies), kept v${version}
|
|
1432
|
+
`
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
} catch {
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1358
1439
|
// src/server/recall-entry.ts
|
|
1359
1440
|
function logStderr(msg) {
|
|
1360
1441
|
process.stderr.write(`[launch-recall] ${msg}
|
|
@@ -1383,6 +1464,7 @@ function printUsage() {
|
|
|
1383
1464
|
);
|
|
1384
1465
|
}
|
|
1385
1466
|
async function main() {
|
|
1467
|
+
void pruneStaleNpxCache();
|
|
1386
1468
|
const argv = process.argv.slice(2);
|
|
1387
1469
|
const subcommand = argv[0];
|
|
1388
1470
|
if (!subcommand || subcommand === "--help" || subcommand === "-h") {
|
|
@@ -608,7 +608,7 @@ var require_package = __commonJS({
|
|
|
608
608
|
"package.json"(exports2, module2) {
|
|
609
609
|
module2.exports = {
|
|
610
610
|
name: "@launchsecure/launch-kit",
|
|
611
|
-
version: "0.0.
|
|
611
|
+
version: "0.0.40",
|
|
612
612
|
description: "LaunchSecure toolkit \u2014 launch-sequencer (pipeline runner + terminal bridge), launch-radar (feedback webhook receiver), launch-chart (project graph MCP), launch-deck (visual playground MCP), launch-kit-beacon (feedback Web Component), launch-recall (file-watcher backup). launch-pod is the container image these run inside.",
|
|
613
613
|
license: "MIT",
|
|
614
614
|
author: "LaunchSecure - AutomateWithUs",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@launchsecure/launch-kit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.40",
|
|
4
4
|
"description": "LaunchSecure toolkit — launch-sequencer (pipeline runner + terminal bridge), launch-radar (feedback webhook receiver), launch-chart (project graph MCP), launch-deck (visual playground MCP), launch-kit-beacon (feedback Web Component), launch-recall (file-watcher backup). launch-pod is the container image these run inside.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "LaunchSecure - AutomateWithUs",
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
# statusline-mcp.sh --show=recall,chart # only the listed chips
|
|
9
9
|
# statusline-mcp.sh --compact # collapse to `mcp <up>/<total>`
|
|
10
10
|
# green when all up, red if any down
|
|
11
|
+
# statusline-mcp.sh --course # print only the active-course line
|
|
12
|
+
# (`course: <profile> → <org>/<project>`)
|
|
11
13
|
#
|
|
12
14
|
# `secure` differs from the others: recall/chart/deck/council are local
|
|
13
15
|
# daemons probed via a pidfile/lockfile/freshness file, but launch-secure is
|
|
@@ -22,10 +24,12 @@ set -u
|
|
|
22
24
|
|
|
23
25
|
show=""
|
|
24
26
|
compact=0
|
|
27
|
+
course_mode=0
|
|
25
28
|
for arg in "$@"; do
|
|
26
29
|
case "$arg" in
|
|
27
30
|
--show=*) show="${arg#--show=}" ;;
|
|
28
31
|
--compact) compact=1 ;;
|
|
32
|
+
--course) course_mode=1 ;;
|
|
29
33
|
esac
|
|
30
34
|
done
|
|
31
35
|
[ -z "$show" ] && show="recall,chart,deck,council,secure"
|
|
@@ -40,6 +44,14 @@ ORANGE=$'\033[33m'
|
|
|
40
44
|
RED=$'\033[31m'
|
|
41
45
|
RESET=$'\033[0m'
|
|
42
46
|
|
|
47
|
+
# Course-line palette: three distinct shades of orange (256-color) for the
|
|
48
|
+
# course / org / project segments, plus a DIM ` | ` separator that matches the
|
|
49
|
+
# user's first-line separator style (^[[2m).
|
|
50
|
+
COURSE_C1=$'\033[38;5;214m' # amber — course (profile)
|
|
51
|
+
COURSE_C2=$'\033[38;5;208m' # orange — org
|
|
52
|
+
COURSE_C3=$'\033[38;5;166m' # burnt — project
|
|
53
|
+
COURSE_SEP=$'\033[0m\033[2m | \033[0m'
|
|
54
|
+
|
|
43
55
|
find_project_root() {
|
|
44
56
|
# `.recall` only exists at the repo root (launch-recall init creates it
|
|
45
57
|
# there). `.launchsecure` can appear in subdirs too (e.g. packages/cli
|
|
@@ -184,23 +196,24 @@ chip_council() {
|
|
|
184
196
|
_state="orange"; _display="${ORANGE}council${RESET}"
|
|
185
197
|
}
|
|
186
198
|
|
|
187
|
-
# Pull the active profile
|
|
188
|
-
# jq (the chip script stays coreutils-only). Handles both shapes the
|
|
189
|
-
# can take — profiled ({active, profiles:{<name>:{
|
|
190
|
-
# ({
|
|
191
|
-
|
|
192
|
-
|
|
199
|
+
# Pull a string field out of the active profile in .launch-secure.cred.config
|
|
200
|
+
# without jq (the chip script stays coreutils-only). Handles both shapes the
|
|
201
|
+
# cred file can take — profiled ({active, profiles:{<name>:{...}}}) and flat
|
|
202
|
+
# ({...}) — mirroring the .mcp.json headersHelper's own fallback. $2 is the key
|
|
203
|
+
# (serverUrl, orgSlug, projectSlug).
|
|
204
|
+
extract_profile_field() {
|
|
205
|
+
local cred="$1" field="$2" active
|
|
193
206
|
active=$(grep -o '"active"[[:space:]]*:[[:space:]]*"[^"]*"' "$cred" 2>/dev/null | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
|
194
|
-
awk -v prof="$active" '
|
|
207
|
+
awk -v prof="$active" -v field="$field" '
|
|
195
208
|
function opens(s){ return gsub(/{/,"&",s) }
|
|
196
209
|
function closes(s){ return gsub(/}/,"&",s) }
|
|
197
|
-
BEGIN { inprof = (prof == "") ? 1 : 0; depth = 0 }
|
|
210
|
+
BEGIN { inprof = (prof == "") ? 1 : 0; depth = 0; pat = "\"" field "\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" }
|
|
198
211
|
{
|
|
199
212
|
if (prof != "" && !inprof) {
|
|
200
213
|
if (index($0, "\"" prof "\"") > 0 && index($0, "{") > 0) { inprof = 1; depth = opens($0) - closes($0) }
|
|
201
214
|
next
|
|
202
215
|
}
|
|
203
|
-
if (match($0,
|
|
216
|
+
if (match($0, pat)) {
|
|
204
217
|
s = substr($0, RSTART, RLENGTH)
|
|
205
218
|
sub(/.*:[[:space:]]*"/, "", s); sub(/".*/, "", s)
|
|
206
219
|
print s; exit
|
|
@@ -210,12 +223,42 @@ extract_secure_url() {
|
|
|
210
223
|
' "$cred" 2>/dev/null
|
|
211
224
|
}
|
|
212
225
|
|
|
226
|
+
extract_secure_url() { extract_profile_field "$1" "serverUrl"; }
|
|
227
|
+
|
|
228
|
+
# Emit the active-course line: `course: <profile> → <org>/<project>`. Sourced
|
|
229
|
+
# from the same cred file the secure chip reads, so it always agrees with which
|
|
230
|
+
# org/project this session's MCP calls (decks, comments, secrets) target. Each
|
|
231
|
+
# segment gets its own orange shade; the ` | ` matches the first-line separator.
|
|
232
|
+
# Silent when no cred/slugs exist.
|
|
233
|
+
render_course_line() {
|
|
234
|
+
local cred="$PROJECT_ROOT/.launch-secure.cred.config"
|
|
235
|
+
[ -f "$cred" ] || return 0
|
|
236
|
+
local active org project parts=""
|
|
237
|
+
active=$(grep -o '"active"[[:space:]]*:[[:space:]]*"[^"]*"' "$cred" 2>/dev/null | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
|
238
|
+
org=$(extract_profile_field "$cred" "orgSlug")
|
|
239
|
+
project=$(extract_profile_field "$cred" "projectSlug")
|
|
240
|
+
# Labeled, pipe-joined segments — each appears only when its value exists.
|
|
241
|
+
# Each segment carries its own orange shade; separators match the first line.
|
|
242
|
+
if [ -n "$active" ]; then parts="${COURSE_C1}course: ${active}${RESET}"; fi
|
|
243
|
+
if [ -n "$org" ]; then
|
|
244
|
+
[ -n "$parts" ] && parts="${parts}${COURSE_SEP}"
|
|
245
|
+
parts="${parts}${COURSE_C2}org: ${org}${RESET}"
|
|
246
|
+
fi
|
|
247
|
+
if [ -n "$project" ]; then
|
|
248
|
+
[ -n "$parts" ] && parts="${parts}${COURSE_SEP}"
|
|
249
|
+
parts="${parts}${COURSE_C3}project: ${project}${RESET}"
|
|
250
|
+
fi
|
|
251
|
+
[ -z "$parts" ] && return 0
|
|
252
|
+
printf '%s' "$parts"
|
|
253
|
+
}
|
|
254
|
+
|
|
213
255
|
_render_secure() {
|
|
214
|
-
# $1 = state (green|red|unknown)
|
|
256
|
+
# $1 = state (green|red|unknown). The active profile name lives on the course
|
|
257
|
+
# line (see render_course_line), so the chip stays a bare reachability light.
|
|
215
258
|
case "$1" in
|
|
216
|
-
green) _state="green"; _display="${GREEN}secure
|
|
217
|
-
unknown) _state="orange"; _display="${ORANGE}secure
|
|
218
|
-
*) _state="red"; _display="${RED}secure
|
|
259
|
+
green) _state="green"; _display="${GREEN}secure${RESET}" ;;
|
|
260
|
+
unknown) _state="orange"; _display="${ORANGE}secure${RESET}" ;;
|
|
261
|
+
*) _state="red"; _display="${RED}secure${RESET}" ;;
|
|
219
262
|
esac
|
|
220
263
|
}
|
|
221
264
|
|
|
@@ -223,11 +266,9 @@ chip_secure() {
|
|
|
223
266
|
local cred="$PROJECT_ROOT/.launch-secure.cred.config"
|
|
224
267
|
if [ ! -f "$cred" ]; then _state="orange"; _display="${ORANGE}secure(?)${RESET}"; return; fi
|
|
225
268
|
|
|
226
|
-
local
|
|
227
|
-
active=$(grep -o '"active"[[:space:]]*:[[:space:]]*"[^"]*"' "$cred" 2>/dev/null | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
|
269
|
+
local url
|
|
228
270
|
url=$(extract_secure_url "$cred")
|
|
229
|
-
if [ -z "$url" ]; then _state="orange"; _display="${ORANGE}secure
|
|
230
|
-
label="${active:-secure}"
|
|
271
|
+
if [ -z "$url" ]; then _state="orange"; _display="${ORANGE}secure${RESET}"; return; fi
|
|
231
272
|
|
|
232
273
|
# Cache keyed on the URL so a course-switch (prod↔local) invalidates instantly.
|
|
233
274
|
local cache="$PROJECT_ROOT/.launchsecure/.statusline-secure.cache"
|
|
@@ -236,7 +277,7 @@ chip_secure() {
|
|
|
236
277
|
local c_ts c_url c_state
|
|
237
278
|
IFS='|' read -r c_ts c_url c_state < "$cache" 2>/dev/null || true
|
|
238
279
|
if [ -n "${c_ts:-}" ] && [ "${c_url:-}" = "$url" ] && [ $((now - c_ts)) -lt "$SECURE_CACHE_TTL" ]; then
|
|
239
|
-
_render_secure "$c_state"
|
|
280
|
+
_render_secure "$c_state"; return
|
|
240
281
|
fi
|
|
241
282
|
fi
|
|
242
283
|
|
|
@@ -249,9 +290,17 @@ chip_secure() {
|
|
|
249
290
|
if [ -n "$code" ] && [ "$code" != "000" ]; then state="green"; else state="red"; fi
|
|
250
291
|
fi
|
|
251
292
|
printf '%s|%s|%s\n' "$now" "$url" "$state" > "$cache" 2>/dev/null || true
|
|
252
|
-
_render_secure "$state"
|
|
293
|
+
_render_secure "$state"
|
|
253
294
|
}
|
|
254
295
|
|
|
296
|
+
# --course mode: print only the active-course line and exit. The wrapper calls
|
|
297
|
+
# this separately so the course renders on its own line between the user's
|
|
298
|
+
# statusline and the MCP chips, regardless of compact/show.
|
|
299
|
+
if [ "$course_mode" = "1" ]; then
|
|
300
|
+
render_course_line
|
|
301
|
+
exit 0
|
|
302
|
+
fi
|
|
303
|
+
|
|
255
304
|
show_list=$(echo "$show" | tr ',' ' ')
|
|
256
305
|
total=0
|
|
257
306
|
up=0
|
|
@@ -27,6 +27,7 @@ if command -v jq >/dev/null 2>&1; then
|
|
|
27
27
|
fi
|
|
28
28
|
|
|
29
29
|
chips=""
|
|
30
|
+
course=""
|
|
30
31
|
if [ -x "$HOME/.launchsecure/statusline-mcp.sh" ]; then
|
|
31
32
|
# Build args array conditionally; `set -u` + empty `"${args[@]}"` would
|
|
32
33
|
# error on bash 4 (default macOS bash), so test length before expanding.
|
|
@@ -38,20 +39,22 @@ if [ -x "$HOME/.launchsecure/statusline-mcp.sh" ]; then
|
|
|
38
39
|
else
|
|
39
40
|
chips=$(LK_STATUSLINE_CWD="$cwd" "$HOME/.launchsecure/statusline-mcp.sh" "${args[@]}" 2>/dev/null || true)
|
|
40
41
|
fi
|
|
42
|
+
# Active-course line (`course: <profile> → <org>/<project>`), independent of
|
|
43
|
+
# show/compact — surfaces which org/project this session's MCP calls target.
|
|
44
|
+
course=$(LK_STATUSLINE_CWD="$cwd" "$HOME/.launchsecure/statusline-mcp.sh" --course 2>/dev/null || true)
|
|
41
45
|
fi
|
|
42
46
|
|
|
43
|
-
# Layout: by default
|
|
44
|
-
#
|
|
47
|
+
# Layout: by default each segment goes on its OWN line (Claude Code renders each
|
|
48
|
+
# stdout newline as a new row), in order: original · course · chips. Set
|
|
45
49
|
# LK_STATUSLINE_INLINE=1 to keep the old single-line ` | `-joined layout.
|
|
46
50
|
if [ "${LK_STATUSLINE_INLINE:-0}" = "1" ]; then
|
|
47
51
|
sep=$'\033[2m | \033[0m'
|
|
48
52
|
else
|
|
49
53
|
sep=$'\n'
|
|
50
54
|
fi
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
fi
|
|
55
|
+
out=""
|
|
56
|
+
for seg in "$original_output" "$course" "$chips"; do
|
|
57
|
+
[ -z "$seg" ] && continue
|
|
58
|
+
if [ -z "$out" ]; then out="$seg"; else out="${out}${sep}${seg}"; fi
|
|
59
|
+
done
|
|
60
|
+
printf '%s' "$out"
|