@launchsecure/launch-kit 0.0.30 → 0.0.32
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/beacon/beacon.mjs +1027 -929
- package/dist/beacon/beacon.mjs.map +1 -1
- package/dist/beacon/beacon.umd.js +9 -9
- package/dist/beacon/beacon.umd.js.map +1 -1
- package/dist/beacon/types/internal/pick-mode-overlay.d.ts.map +1 -1
- package/dist/beacon/types/internal/picker.d.ts.map +1 -1
- package/dist/beacon/types/internal/pin-popover.d.ts.map +1 -1
- package/dist/beacon/types/internal/screenshot.d.ts +19 -1
- package/dist/beacon/types/internal/screenshot.d.ts.map +1 -1
- package/dist/beacon/types/internal/selector.d.ts.map +1 -1
- package/dist/beacon/types/plugins/domEle.d.ts.map +1 -1
- package/dist/chart-client/assets/{index-CJ4mgRRF.css → index-CDIhdgWg.css} +1 -1
- package/dist/chart-client/index.html +2 -2
- package/dist/client/assets/{index-DI5qSR_w.css → index-CfW4n40I.css} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/council-client/assets/{index-C_-vAM9L.css → index-CZim6x1u.css} +1 -1
- package/dist/council-client/index.html +2 -2
- package/dist/deck-client/assets/{_baseUniq-DCt2IMRR.js → _baseUniq-C7GsHvgg.js} +1 -1
- package/dist/deck-client/assets/{arc-h-ifqmNR.js → arc-CSrZRINY.js} +1 -1
- package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-C9dITSPv.js → architectureDiagram-Q4EWVU46-zoB-G17J.js} +1 -1
- package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-BHuJT34t.js → blockDiagram-DXYQGD6D-BRjjtYH6.js} +1 -1
- package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-CpvMGtDG.js → c4Diagram-AHTNJAMY-C3D3sd2U.js} +1 -1
- package/dist/deck-client/assets/channel-8ReQnQfH.js +1 -0
- package/dist/deck-client/assets/{chunk-4BX2VUAB-B6md1VIm.js → chunk-4BX2VUAB-DhpDMOPO.js} +1 -1
- package/dist/deck-client/assets/{chunk-4TB4RGXK-BmEnX8ik.js → chunk-4TB4RGXK-BIRgPXRl.js} +1 -1
- package/dist/deck-client/assets/{chunk-55IACEB6-BZPUyZAZ.js → chunk-55IACEB6-BF24dwDZ.js} +1 -1
- package/dist/deck-client/assets/{chunk-EDXVE4YY-BWwNUK-l.js → chunk-EDXVE4YY-CW75Y61B.js} +1 -1
- package/dist/deck-client/assets/{chunk-FMBD7UC4-o7gSppGI.js → chunk-FMBD7UC4-B5-oyL79.js} +1 -1
- package/dist/deck-client/assets/{chunk-OYMX7WX6-C4KoTL5p.js → chunk-OYMX7WX6-BB2bHe_Q.js} +1 -1
- package/dist/deck-client/assets/{chunk-QZHKN3VN-jkf68sDs.js → chunk-QZHKN3VN-D80eZO4B.js} +1 -1
- package/dist/deck-client/assets/{chunk-YZCP3GAM-Cd4yBE7o.js → chunk-YZCP3GAM-Dz9787p_.js} +1 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-cRxTeGkK.js +1 -0
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-cRxTeGkK.js +1 -0
- package/dist/deck-client/assets/clone-LSHZ3K6R.js +1 -0
- package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-DeGFUgAV.js → cose-bilkent-S5V4N54A-MQjiZLcL.js} +1 -1
- package/dist/deck-client/assets/{dagre-KV5264BT-ekcYJuUV.js → dagre-KV5264BT-DG4EcLpJ.js} +1 -1
- package/dist/deck-client/assets/{diagram-5BDNPKRD-YHPk4rV2.js → diagram-5BDNPKRD-1n7hM3Gc.js} +1 -1
- package/dist/deck-client/assets/{diagram-G4DWMVQ6-DM-JCd_B.js → diagram-G4DWMVQ6-CYMarncV.js} +1 -1
- package/dist/deck-client/assets/{diagram-MMDJMWI5-l5FK1ybk.js → diagram-MMDJMWI5-DSisoipe.js} +1 -1
- package/dist/deck-client/assets/{diagram-TYMM5635-CIN4_1-j.js → diagram-TYMM5635-Btnq49OJ.js} +1 -1
- package/dist/deck-client/assets/{erDiagram-SMLLAGMA-MyinSkEl.js → erDiagram-SMLLAGMA-Cu2Hb_Tz.js} +1 -1
- package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-Dk8nn42x.js → flowDiagram-DWJPFMVM-CGJzUzsO.js} +1 -1
- package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-BU1ihicu.js → ganttDiagram-T4ZO3ILL-D9sqGUBT.js} +1 -1
- package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-BjsTL13C.js → gitGraphDiagram-UUTBAWPF-C0QwX2od.js} +1 -1
- package/dist/deck-client/assets/{graph-DJmh-xi7.js → graph-CcBjOQCl.js} +1 -1
- package/dist/deck-client/assets/index-0arwoc0z.js +1195 -0
- package/dist/deck-client/assets/index-6sdqbm2o.js +2 -0
- package/dist/deck-client/assets/{index-DsIZ3LqL.css → index-BlTlhxFW.css} +1 -1
- package/dist/deck-client/assets/{infoDiagram-42DDH7IO-Dxvy_RB4.js → infoDiagram-42DDH7IO-DTimhhhS.js} +1 -1
- package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-DPOaNF1l.js → ishikawaDiagram-UXIWVN3A-DxOxg_B4.js} +1 -1
- package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-DMew3K5c.js → journeyDiagram-VCZTEJTY-Bpq0qa4j.js} +1 -1
- package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-csciJFuk.js → kanban-definition-6JOO6SKY-aTIrpcVO.js} +1 -1
- package/dist/deck-client/assets/{layout-Dg4yyms2.js → layout-DqglLR2E.js} +1 -1
- package/dist/deck-client/assets/{linear-BA3zU6gq.js → linear-D5GxehPc.js} +1 -1
- package/dist/deck-client/assets/{min-lz-Ird-p.js → min-DXLfSREq.js} +1 -1
- package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-CCEN8OQV.js → mindmap-definition-QFDTVHPH-mO5Vys7I.js} +1 -1
- package/dist/deck-client/assets/{pieDiagram-DEJITSTG-DM6n1HY7.js → pieDiagram-DEJITSTG-Dm0gzdAr.js} +1 -1
- package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-_ULoR66n.js → quadrantDiagram-34T5L4WZ-Daq7j3qD.js} +1 -1
- package/dist/deck-client/assets/{requirementDiagram-MS252O5E-BuwJs7Tn.js → requirementDiagram-MS252O5E-CmwV95um.js} +1 -1
- package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-BEsuzkW4.js → sankeyDiagram-XADWPNL6-BOYl3Nkf.js} +1 -1
- package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-CP2H0YWf.js → sequenceDiagram-FGHM5R23-BuUjhIcW.js} +1 -1
- package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-B5Gw_NNL.js → stateDiagram-FHFEXIEX-LUZ_uwio.js} +1 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-CnnRwE5D.js +1 -0
- package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-DsoYydQa.js → timeline-definition-GMOUNBTQ-CDUxCCAW.js} +1 -1
- package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-Dz8JT_ob.js → vennDiagram-DHZGUBPP-BRb24Tf7.js} +1 -1
- package/dist/deck-client/assets/{wardley-RL74JXVD-DGHQ_Ijv.js → wardley-RL74JXVD-B0BYyVBY.js} +1 -1
- package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-DN1LJMB1.js → wardleyDiagram-NUSXRM2D-BLGlYrQz.js} +1 -1
- package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-nb0oSfrQ.js → xychartDiagram-5P7HB3ND-De31MSnk.js} +1 -1
- package/dist/deck-client/index.html +2 -2
- package/dist/server/cli.js +666 -12
- package/dist/server/council-entry.js +0 -0
- package/dist/server/deck-mcp-entry.js +224 -61
- package/dist/server/deck-serve.js +195 -41
- package/dist/server/fb-wizard.js +0 -0
- package/dist/server/graph-mcp-entry.js +666 -12
- package/dist/server/init-entry.js +231 -82
- package/package.json +23 -21
- package/scaffolds/ls-marketplace/plugins/kit/skills/analyse/SKILL.md +180 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/{blast-radius.md → blast-radius/SKILL.md} +28 -12
- package/scaffolds/ls-marketplace/plugins/kit/skills/{debug.md → debug/SKILL.md} +2 -9
- package/scaffolds/ls-marketplace/plugins/kit/skills/diagram/SKILL.md +174 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/{prototype.md → prototype/SKILL.md} +21 -1
- package/scaffolds/ls-marketplace/plugins/kit/skills/recovery/SKILL.md +95 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/{wireframe.md → wireframe/SKILL.md} +21 -1
- package/scaffolds/migrate-safety/scripts/migrate-with-backup.sh +0 -0
- package/scaffolds/recall-hook/scripts/ensure-recall.sh +0 -0
- package/dist/deck-client/assets/channel-2PZVMiXf.js +0 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-Bt8xBAof.js +0 -1
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-Bt8xBAof.js +0 -1
- package/dist/deck-client/assets/clone-BHQryoDl.js +0 -1
- package/dist/deck-client/assets/index-KsShfCV-.js +0 -476
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-4T4wMDXr.js +0 -1
- package/scaffolds/ls-marketplace/plugins/kit/skills/diagram.md +0 -134
- package/scaffolds/ls-marketplace/plugins/kit/skills/recall.md +0 -83
- /package/dist/chart-client/assets/{index-Ccy-DpI-.js → index-B__ARB8k.js} +0 -0
- /package/dist/client/assets/{index-Dp0_okva.js → index-h8kMzVtG.js} +0 -0
- /package/dist/council-client/assets/{index-Dt4zWKSj.js → index-CWaDcsFR.js} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{beacon-array.md → beacon-array/SKILL.md} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{beacon-clear.md → beacon-clear/SKILL.md} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{beacon-pulse.md → beacon-pulse/SKILL.md} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{beacon-scan.md → beacon-scan/SKILL.md} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{brief.md → brief/SKILL.md} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{course.md → course/SKILL.md} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{deploy-check.md → deploy-check/SKILL.md} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{orbit.md → orbit/SKILL.md} +0 -0
- /package/scaffolds/ls-marketplace/plugins/kit/skills/{show-mcp-status.md → show-mcp-status/SKILL.md} +0 -0
|
@@ -295,6 +295,50 @@ function recoverCred(targetDir, opts) {
|
|
|
295
295
|
init_statusline_install();
|
|
296
296
|
var DEFAULT_SERVER_URL = "https://launchsecure-v2.vercel.app";
|
|
297
297
|
var ONBOARD_SCRIPT_NAME = "onboard";
|
|
298
|
+
var TTY = process.stdout.isTTY === true && process.env.NO_COLOR !== "1";
|
|
299
|
+
var c = {
|
|
300
|
+
dim: (s) => TTY ? `\x1B[2m${s}\x1B[0m` : s,
|
|
301
|
+
bold: (s) => TTY ? `\x1B[1m${s}\x1B[0m` : s,
|
|
302
|
+
cyan: (s) => TTY ? `\x1B[36m${s}\x1B[0m` : s,
|
|
303
|
+
green: (s) => TTY ? `\x1B[32m${s}\x1B[0m` : s,
|
|
304
|
+
yellow: (s) => TTY ? `\x1B[33m${s}\x1B[0m` : s,
|
|
305
|
+
red: (s) => TTY ? `\x1B[31m${s}\x1B[0m` : s
|
|
306
|
+
};
|
|
307
|
+
var PHASE_NAME_COL = 16;
|
|
308
|
+
var HEADER_WIDTH = 64;
|
|
309
|
+
function header(title, kv) {
|
|
310
|
+
if (VERBOSE) return;
|
|
311
|
+
const dashes = "\u2500".repeat(Math.max(3, HEADER_WIDTH - title.length - 5));
|
|
312
|
+
console.log("");
|
|
313
|
+
console.log(c.cyan(`\u2500\u2500\u2500 ${c.bold(title)} ${dashes}`));
|
|
314
|
+
if (kv.length > 0) {
|
|
315
|
+
const labelWidth = Math.max(...kv.map(([k]) => k.length));
|
|
316
|
+
for (const [k, v] of kv) console.log(` ${c.dim(k.padEnd(labelWidth))} ${v}`);
|
|
317
|
+
}
|
|
318
|
+
console.log("");
|
|
319
|
+
}
|
|
320
|
+
function phase(name, result) {
|
|
321
|
+
if (VERBOSE) return;
|
|
322
|
+
const mark = result.status === "ok" ? c.green("\u2713") : result.status === "in-sync" ? c.dim("\xB7") : result.status === "skipped" ? c.dim("\u2212") : c.yellow("\u26A0");
|
|
323
|
+
const summary = result.status === "in-sync" || result.status === "skipped" ? c.dim(result.summary) : result.summary;
|
|
324
|
+
const label = name.padEnd(PHASE_NAME_COL);
|
|
325
|
+
console.log(` ${result.status === "warn" ? c.yellow(label) : label} ${mark} ${summary}`);
|
|
326
|
+
}
|
|
327
|
+
function section(title) {
|
|
328
|
+
if (VERBOSE) return;
|
|
329
|
+
console.log("");
|
|
330
|
+
console.log(` ${c.dim("\u2500 " + title + " \u2500")}`);
|
|
331
|
+
}
|
|
332
|
+
function footer(msg, hints = []) {
|
|
333
|
+
if (VERBOSE) return;
|
|
334
|
+
console.log("");
|
|
335
|
+
console.log(` ${c.bold(msg)}`);
|
|
336
|
+
for (const h of hints) console.log(` ${c.dim(h)}`);
|
|
337
|
+
console.log("");
|
|
338
|
+
}
|
|
339
|
+
function warn(msg) {
|
|
340
|
+
console.log(` ${c.yellow("\u26A0")} ${msg}`);
|
|
341
|
+
}
|
|
298
342
|
var LAUNCH_KIT_PKG = "@launchsecure/launch-kit";
|
|
299
343
|
var LAUNCH_KIT_TOOLS_GUIDE_STATIC_HEAD = `
|
|
300
344
|
Wired in Claude Code (.mcp.json):
|
|
@@ -317,24 +361,30 @@ var LAUNCH_KIT_TOOLS_GUIDE_STATIC_TAIL = `
|
|
|
317
361
|
Open this repo in Claude Code; on first open you'll be prompted to install
|
|
318
362
|
the "launch-secure" marketplace \u2014 accept to enable the commands above.
|
|
319
363
|
`;
|
|
320
|
-
function
|
|
364
|
+
function listEntries(dir, kind) {
|
|
365
|
+
if (kind === "commands") {
|
|
366
|
+
return fs4.readdirSync(dir).filter((f) => f.endsWith(".md")).sort().map((f) => ({ name: f.replace(/\.md$/, ""), file: path4.join(dir, f) }));
|
|
367
|
+
}
|
|
368
|
+
return fs4.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && fs4.existsSync(path4.join(dir, e.name, "SKILL.md"))).map((e) => e.name).sort().map((name) => ({ name, file: path4.join(dir, name, "SKILL.md") }));
|
|
369
|
+
}
|
|
370
|
+
function renderEntries(dir, kind) {
|
|
321
371
|
if (!fs4.existsSync(dir)) return `
|
|
322
|
-
LS slash ${
|
|
372
|
+
LS slash ${kind}: (scaffold dir not bundled \u2014 this is a packaging bug)
|
|
323
373
|
`;
|
|
324
|
-
const
|
|
325
|
-
if (
|
|
326
|
-
LS slash ${
|
|
374
|
+
const entries = listEntries(dir, kind);
|
|
375
|
+
if (entries.length === 0) return `
|
|
376
|
+
LS slash ${kind}: (none defined)
|
|
327
377
|
`;
|
|
328
|
-
const names =
|
|
378
|
+
const names = entries.map((e) => `/${PLUGIN_ID}:${e.name}`);
|
|
329
379
|
const colWidth = Math.max(26, ...names.map((n) => n.length + 2));
|
|
330
|
-
const lines =
|
|
331
|
-
const text = fs4.readFileSync(
|
|
380
|
+
const lines = entries.map((entry, i) => {
|
|
381
|
+
const text = fs4.readFileSync(entry.file, "utf-8");
|
|
332
382
|
const fmMatch = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
333
383
|
const desc = fmMatch?.[1].match(/^description:\s*(.+)$/m)?.[1]?.trim() ?? "";
|
|
334
384
|
return ` ${names[i].padEnd(colWidth)} \u2014 ${desc}`;
|
|
335
385
|
});
|
|
336
386
|
return `
|
|
337
|
-
LS slash ${
|
|
387
|
+
LS slash ${kind} (run inside Claude Code in this project):
|
|
338
388
|
${lines.join("\n")}
|
|
339
389
|
`;
|
|
340
390
|
}
|
|
@@ -363,7 +413,10 @@ var KNOWN_BOOL_FLAGS = /* @__PURE__ */ new Set([
|
|
|
363
413
|
"--refresh-scaffolds",
|
|
364
414
|
"--quiet",
|
|
365
415
|
"--force",
|
|
366
|
-
"--dry-run"
|
|
416
|
+
"--dry-run",
|
|
417
|
+
"--verbose",
|
|
418
|
+
"--guide",
|
|
419
|
+
"--no-guide"
|
|
367
420
|
]);
|
|
368
421
|
var KNOWN_KV_KEYS = /* @__PURE__ */ new Set(["token", "org", "project", "url", "dir", "course"]);
|
|
369
422
|
function parseArgs(argv) {
|
|
@@ -384,6 +437,8 @@ function parseArgs(argv) {
|
|
|
384
437
|
quiet: false,
|
|
385
438
|
force: false,
|
|
386
439
|
dryRun: false,
|
|
440
|
+
verbose: false,
|
|
441
|
+
guide: null,
|
|
387
442
|
help: false
|
|
388
443
|
};
|
|
389
444
|
const unknown = [];
|
|
@@ -434,6 +489,18 @@ function parseArgs(argv) {
|
|
|
434
489
|
args.dryRun = true;
|
|
435
490
|
continue;
|
|
436
491
|
}
|
|
492
|
+
if (raw === "--verbose") {
|
|
493
|
+
args.verbose = true;
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
if (raw === "--guide") {
|
|
497
|
+
args.guide = true;
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
if (raw === "--no-guide") {
|
|
501
|
+
args.guide = false;
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
437
504
|
const eq = raw.indexOf("=");
|
|
438
505
|
if (raw.startsWith("--") && eq > 0) {
|
|
439
506
|
const key = raw.slice(2, eq);
|
|
@@ -505,8 +572,15 @@ Options:
|
|
|
505
572
|
--refresh-scaffolds Force-overwrite migrate-safety files (default is to
|
|
506
573
|
preserve user edits). Use this to pull updates
|
|
507
574
|
published to @launchsecure/launch-kit.
|
|
508
|
-
--
|
|
575
|
+
--verbose Print the legacy per-line debug log instead of the
|
|
576
|
+
default compact phase summary. Useful when refresh
|
|
577
|
+
reports a warn-status phase and you want detail.
|
|
578
|
+
--guide Print the trailing tools guide (MCP table + every
|
|
579
|
+
/kit:* command). Off by default on refresh.
|
|
580
|
+
--quiet Suppress the tools guide and the next-steps hint.
|
|
581
|
+
Overrides --guide.
|
|
509
582
|
--dry-run Preview every file write without making changes.
|
|
583
|
+
Implies --verbose.
|
|
510
584
|
--help Show this help.
|
|
511
585
|
|
|
512
586
|
Tip: prefix the command with @latest (\`launch-kit@latest refresh\`) to force
|
|
@@ -564,9 +638,17 @@ Options:
|
|
|
564
638
|
user edits; use this to pull updates published to
|
|
565
639
|
@launchsecure/launch-kit (e.g., a newer
|
|
566
640
|
migrate-with-backup.sh).
|
|
567
|
-
--
|
|
568
|
-
|
|
569
|
-
|
|
641
|
+
--verbose Print the legacy per-line debug log instead of the
|
|
642
|
+
default compact phase summary. Useful when a phase
|
|
643
|
+
reports a warn status and you want per-file detail.
|
|
644
|
+
--guide Print the trailing tools guide (MCP table + every
|
|
645
|
+
/kit:* command). On by default for init; pair with
|
|
646
|
+
--no-guide to suppress.
|
|
647
|
+
--no-guide Suppress the trailing tools guide (handy after the
|
|
648
|
+
first init, when you don't need the catalog again).
|
|
649
|
+
--quiet Suppress the post-run tools guide AND the next-steps
|
|
650
|
+
hint. Useful for idempotent re-runs in CI or scripts.
|
|
651
|
+
Overrides --guide.
|
|
570
652
|
--force Skip the auto-delegate-to-refresh check. By default
|
|
571
653
|
init detects an existing bootstrap (cred file +
|
|
572
654
|
launch-secure MCP entry) and runs refresh instead.
|
|
@@ -617,11 +699,12 @@ function fail(msg) {
|
|
|
617
699
|
console.error(`[launch-kit] \u2717 ${msg}`);
|
|
618
700
|
process.exit(1);
|
|
619
701
|
}
|
|
702
|
+
var VERBOSE = false;
|
|
620
703
|
function info(msg) {
|
|
621
|
-
console.log(`[launch-kit] ${msg}`);
|
|
704
|
+
if (VERBOSE) console.log(`[launch-kit] ${msg}`);
|
|
622
705
|
}
|
|
623
706
|
function ok(msg) {
|
|
624
|
-
console.log(`[launch-kit] \u2713 ${msg}`);
|
|
707
|
+
if (VERBOSE) console.log(`[launch-kit] \u2713 ${msg}`);
|
|
625
708
|
}
|
|
626
709
|
var DRY_RUN = false;
|
|
627
710
|
function dryNote(msg) {
|
|
@@ -679,7 +762,7 @@ function attemptProjectInfo(args) {
|
|
|
679
762
|
},
|
|
680
763
|
(res) => {
|
|
681
764
|
const chunks = [];
|
|
682
|
-
res.on("data", (
|
|
765
|
+
res.on("data", (c2) => chunks.push(c2));
|
|
683
766
|
res.on("end", () => {
|
|
684
767
|
const text = Buffer.concat(chunks).toString("utf-8");
|
|
685
768
|
if (res.statusCode === 401) {
|
|
@@ -930,13 +1013,15 @@ function mergeMcpFile(targetDir, launchKitEntries) {
|
|
|
930
1013
|
}
|
|
931
1014
|
}
|
|
932
1015
|
if (DRY_RUN) {
|
|
933
|
-
const
|
|
934
|
-
dryNote(`${
|
|
935
|
-
return;
|
|
1016
|
+
const action = hadExisting && existingServerCount > 0 ? "would merge into" : "would write";
|
|
1017
|
+
dryNote(`${action} .mcp.json \u2014 overwriting [${overwrites.join(", ") || "none"}], adding [${additions.join(", ") || "none"}]`);
|
|
1018
|
+
return { status: "skipped", summary: "(dry-run)" };
|
|
936
1019
|
}
|
|
937
1020
|
fs4.writeFileSync(p, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
938
|
-
const
|
|
939
|
-
ok(`${
|
|
1021
|
+
const verb = hadExisting && existingServerCount > 0 ? "merged" : "wrote";
|
|
1022
|
+
ok(`${verb === "merged" ? "merged into" : "wrote"} .mcp.json (${Object.keys(launchKitEntries).length} launch-kit entries)`);
|
|
1023
|
+
const total = Object.keys(launchKitEntries).length;
|
|
1024
|
+
return { status: "ok", summary: `${verb} ${total} entries` };
|
|
940
1025
|
}
|
|
941
1026
|
function detectPackageManager(repoDir) {
|
|
942
1027
|
const pkgPath = path4.join(repoDir, "package.json");
|
|
@@ -1087,8 +1172,8 @@ function copyScaffoldDirAlways(srcDir, destDir, labelPrefix) {
|
|
|
1087
1172
|
function scaffoldMigrateSafety(targetDir, refreshScaffolds = false) {
|
|
1088
1173
|
const scaffoldsRoot = path4.resolve(__dirname, "..", "..", "scaffolds", "migrate-safety");
|
|
1089
1174
|
if (!fs4.existsSync(scaffoldsRoot)) {
|
|
1090
|
-
|
|
1091
|
-
return;
|
|
1175
|
+
warn(`migrate-safety scaffolds missing at ${scaffoldsRoot} \u2014 packaging bug; main onboarding unaffected`);
|
|
1176
|
+
return { status: "warn", summary: "scaffolds missing (packaging bug)" };
|
|
1092
1177
|
}
|
|
1093
1178
|
const files = [
|
|
1094
1179
|
{
|
|
@@ -1108,9 +1193,33 @@ function scaffoldMigrateSafety(targetDir, refreshScaffolds = false) {
|
|
|
1108
1193
|
}
|
|
1109
1194
|
];
|
|
1110
1195
|
info(`scaffolding migrate-safety (pg_dump wrapper + GHA backup workflow + runbook)${refreshScaffolds ? " \u2014 --refresh-scaffolds active" : ""} \u2026`);
|
|
1111
|
-
|
|
1196
|
+
const counts = { wrote: 0, inSync: 0, drifted: 0, refreshed: 0, missing: 0 };
|
|
1197
|
+
for (const f of files) {
|
|
1198
|
+
const r = copyScaffoldDriftAware(f.src, f.dest, f.label, refreshScaffolds);
|
|
1199
|
+
if (r === "wrote") counts.wrote++;
|
|
1200
|
+
else if (r === "in-sync") counts.inSync++;
|
|
1201
|
+
else if (r === "drifted-preserved") counts.drifted++;
|
|
1202
|
+
else if (r === "drifted-refreshed") counts.refreshed++;
|
|
1203
|
+
else counts.missing++;
|
|
1204
|
+
}
|
|
1112
1205
|
ensureGitignoreLine(targetDir, ".backups/");
|
|
1113
1206
|
ok("migrate-safety ready \u2014 see docs/migrations-runbook.md for db:migrate wiring + PROD_DATABASE_URL secret setup");
|
|
1207
|
+
return summarizeFileCounts(counts);
|
|
1208
|
+
}
|
|
1209
|
+
function summarizeFileCounts(counts) {
|
|
1210
|
+
const total = counts.wrote + counts.inSync + counts.drifted + counts.refreshed + counts.missing;
|
|
1211
|
+
const parts = [];
|
|
1212
|
+
if (counts.wrote) parts.push(`${counts.wrote} written`);
|
|
1213
|
+
if (counts.refreshed) parts.push(`${counts.refreshed} refreshed`);
|
|
1214
|
+
if (counts.drifted) parts.push(`${counts.drifted} drifted (preserved \u2014 pass --refresh-scaffolds to update)`);
|
|
1215
|
+
if (counts.inSync && (counts.wrote || counts.refreshed || counts.drifted)) parts.push(`${counts.inSync} in sync`);
|
|
1216
|
+
if (counts.missing) parts.push(`${counts.missing} missing scaffold src`);
|
|
1217
|
+
if (parts.length === 0) parts.push(`in sync (${total} file${total === 1 ? "" : "s"})`);
|
|
1218
|
+
else if (!counts.wrote && !counts.refreshed && !counts.drifted && counts.inSync === total) {
|
|
1219
|
+
return { status: "in-sync", summary: `in sync (${total} file${total === 1 ? "" : "s"})` };
|
|
1220
|
+
}
|
|
1221
|
+
const status = counts.drifted || counts.missing ? "warn" : counts.wrote || counts.refreshed ? "ok" : "in-sync";
|
|
1222
|
+
return { status, summary: parts.join(", ") };
|
|
1114
1223
|
}
|
|
1115
1224
|
function hashFile(p) {
|
|
1116
1225
|
try {
|
|
@@ -1180,21 +1289,22 @@ function isDogfoodMarketplace(targetDir) {
|
|
|
1180
1289
|
function scaffoldLsMarketplace(targetDir) {
|
|
1181
1290
|
const scaffoldsRoot = path4.resolve(__dirname, "..", "..", "scaffolds", "ls-marketplace");
|
|
1182
1291
|
if (!fs4.existsSync(scaffoldsRoot)) {
|
|
1183
|
-
|
|
1184
|
-
return;
|
|
1292
|
+
warn(`ls-marketplace scaffolds missing at ${scaffoldsRoot} \u2014 packaging bug`);
|
|
1293
|
+
return { status: "warn", summary: "scaffolds missing (packaging bug)" };
|
|
1185
1294
|
}
|
|
1186
1295
|
const dogfood = isDogfoodMarketplace(targetDir);
|
|
1187
1296
|
if (dogfood.isDogfood) {
|
|
1188
1297
|
info(`dogfood marketplace pointer detected (${dogfood.existingPath}) \u2014 skipping copy, only refreshing enabledPlugins`);
|
|
1189
1298
|
wireLsSettings(targetDir);
|
|
1190
1299
|
ok(`launch-secure marketplace (dogfood) \u2014 Claude Code loads commands from ${dogfood.existingPath}`);
|
|
1191
|
-
return;
|
|
1300
|
+
return { status: "ok", summary: `dogfood pointer (${dogfood.existingPath})` };
|
|
1192
1301
|
}
|
|
1193
1302
|
const marketplaceRoot = path4.join(targetDir, ".claude", "marketplace");
|
|
1194
1303
|
info("scaffolding launch-secure marketplace (Claude Code /kit: namespace \u2014 refreshes every /kit:* command found in the scaffold) \u2026");
|
|
1195
1304
|
copyScaffoldDirAlways(scaffoldsRoot, marketplaceRoot, ".claude/marketplace");
|
|
1196
1305
|
wireLsSettings(targetDir);
|
|
1197
1306
|
ok(`launch-secure marketplace ready \u2014 open this repo in Claude Code, approve the "${MARKETPLACE_ID}" marketplace prompt, then try /kit:activate-beacon, /kit:standup, or /kit:show-mcp-status`);
|
|
1307
|
+
return { status: "ok", summary: "marketplace tree + settings refreshed" };
|
|
1198
1308
|
}
|
|
1199
1309
|
function wireLsSettings(targetDir) {
|
|
1200
1310
|
const p = path4.join(targetDir, ".claude", "settings.json");
|
|
@@ -1241,13 +1351,14 @@ var RECALL_HOOK_COMMAND = 'bash "${CLAUDE_PROJECT_DIR:-$PWD}/scripts/ensure-reca
|
|
|
1241
1351
|
function scaffoldRecallHook(targetDir) {
|
|
1242
1352
|
const scaffoldsRoot = path4.resolve(__dirname, "..", "..", "scaffolds", "recall-hook");
|
|
1243
1353
|
if (!fs4.existsSync(scaffoldsRoot)) {
|
|
1244
|
-
|
|
1245
|
-
return;
|
|
1354
|
+
warn(`recall-hook scaffolds missing at ${scaffoldsRoot} \u2014 packaging bug`);
|
|
1355
|
+
return { status: "warn", summary: "scaffolds missing (packaging bug)" };
|
|
1246
1356
|
}
|
|
1247
1357
|
info("scaffolding recall-hook (SessionStart watcher-respawn hook + ensure-recall.sh) \u2026");
|
|
1248
1358
|
copyScaffoldDirAlways(scaffoldsRoot, targetDir, "");
|
|
1249
|
-
wireRecallHook(targetDir);
|
|
1359
|
+
const wired = wireRecallHook(targetDir);
|
|
1250
1360
|
ok("recall-hook ready \u2014 opens with Claude Code will respawn the launch-recall watcher if it died between sessions");
|
|
1361
|
+
return wired ? { status: "ok", summary: "ensure-recall.sh refreshed + SessionStart hook appended" } : { status: "ok", summary: "ensure-recall.sh refreshed (hook already wired)" };
|
|
1251
1362
|
}
|
|
1252
1363
|
function wireRecallHook(targetDir) {
|
|
1253
1364
|
const p = path4.join(targetDir, ".claude", "settings.json");
|
|
@@ -1267,7 +1378,7 @@ function wireRecallHook(targetDir) {
|
|
|
1267
1378
|
);
|
|
1268
1379
|
if (alreadyWired) {
|
|
1269
1380
|
info(".claude/settings.json SessionStart hook already references ensure-recall.sh \u2014 leaving alone");
|
|
1270
|
-
return;
|
|
1381
|
+
return false;
|
|
1271
1382
|
}
|
|
1272
1383
|
const newGroup = {
|
|
1273
1384
|
hooks: [{ type: "command", command: RECALL_HOOK_COMMAND }]
|
|
@@ -1281,23 +1392,28 @@ function wireRecallHook(targetDir) {
|
|
|
1281
1392
|
};
|
|
1282
1393
|
if (DRY_RUN) {
|
|
1283
1394
|
dryNote(`would append SessionStart hook to .claude/settings.json (bash scripts/ensure-recall.sh; preserves every other key + existing hooks)`);
|
|
1284
|
-
return;
|
|
1395
|
+
return true;
|
|
1285
1396
|
}
|
|
1286
1397
|
fs4.mkdirSync(path4.dirname(p), { recursive: true });
|
|
1287
1398
|
fs4.writeFileSync(p, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
1288
1399
|
ok(`appended SessionStart hook to .claude/settings.json (bash scripts/ensure-recall.sh)`);
|
|
1400
|
+
return true;
|
|
1289
1401
|
}
|
|
1290
1402
|
function tryActivateStatusline() {
|
|
1291
1403
|
if (DRY_RUN) {
|
|
1292
1404
|
dryNote(`would wrap ~/.claude/settings.json statusLine.command with launch-kit's MCP chip wrapper (skips silently if no statusline configured)`);
|
|
1293
|
-
return;
|
|
1405
|
+
return { status: "skipped", summary: "(dry-run)" };
|
|
1294
1406
|
}
|
|
1295
1407
|
const res = activateStatusline();
|
|
1296
1408
|
if (res.ok && res.outcome === "activated") {
|
|
1297
1409
|
ok(`statusline wrapped \u2014 MCP chips will render alongside your existing statusline next session`);
|
|
1298
|
-
|
|
1410
|
+
return { status: "ok", summary: "wrapped \u2014 MCP chips render next session" };
|
|
1411
|
+
}
|
|
1412
|
+
if (res.ok && res.outcome === "refreshed") {
|
|
1299
1413
|
info(`statusline already wrapped \u2014 refreshed chip scripts`);
|
|
1414
|
+
return { status: "ok", summary: "chip scripts refreshed" };
|
|
1300
1415
|
}
|
|
1416
|
+
return null;
|
|
1301
1417
|
}
|
|
1302
1418
|
async function main() {
|
|
1303
1419
|
const subcommand = process.argv[2];
|
|
@@ -1341,11 +1457,12 @@ async function main() {
|
|
|
1341
1457
|
fail(`Unknown subcommand "${subcommand}". Supported: init, refresh, statusline. Run with --help for usage.`);
|
|
1342
1458
|
}
|
|
1343
1459
|
DRY_RUN = args.dryRun;
|
|
1460
|
+
VERBOSE = args.verbose || DRY_RUN;
|
|
1344
1461
|
if (DRY_RUN) {
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1462
|
+
console.log(c.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1463
|
+
console.log(c.bold("DRY RUN") + c.dim(" \u2014 no files will be written, no commands will run."));
|
|
1464
|
+
console.log(c.dim("Lines tagged (dry-run) show what would happen."));
|
|
1465
|
+
console.log(c.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1349
1466
|
}
|
|
1350
1467
|
if (subcommand === "refresh") return mainRefresh(args);
|
|
1351
1468
|
return mainInit(args);
|
|
@@ -1384,25 +1501,34 @@ async function mainRefresh(args) {
|
|
|
1384
1501
|
const active = nested.profiles[nested.active];
|
|
1385
1502
|
if (!active) fail(`${CONFIG_FILENAME} active profile "${nested.active}" is not present in profiles.`);
|
|
1386
1503
|
info(`refreshing launch-kit in ${targetDir} (course: ${nested.active}, project: ${active.orgSlug}/${active.projectSlug}) \u2026`);
|
|
1504
|
+
header("launch-kit refresh", [
|
|
1505
|
+
["course", nested.active],
|
|
1506
|
+
["project", `${active.orgSlug}/${active.projectSlug}`],
|
|
1507
|
+
["dir", path4.relative(cwd, targetDir) || "."]
|
|
1508
|
+
]);
|
|
1387
1509
|
const cfg = { pat: active.pat, orgSlug: active.orgSlug, projectSlug: active.projectSlug, serverUrl: active.serverUrl };
|
|
1388
|
-
mergeMcpFile(targetDir, buildLaunchKitMcpEntries(cfg));
|
|
1510
|
+
phase(".mcp.json", mergeMcpFile(targetDir, buildLaunchKitMcpEntries(cfg)));
|
|
1389
1511
|
ensureGitignoreLine(targetDir, CONFIG_FILENAME);
|
|
1390
|
-
if (!args.noMigrateSafety) scaffoldMigrateSafety(targetDir, args.refreshScaffolds);
|
|
1391
|
-
if (!args.noLsMarketplace) scaffoldLsMarketplace(targetDir);
|
|
1392
|
-
if (!args.noRecallHook) scaffoldRecallHook(targetDir);
|
|
1393
|
-
tryActivateStatusline();
|
|
1394
|
-
|
|
1512
|
+
if (!args.noMigrateSafety) phase("migrate-safety", scaffoldMigrateSafety(targetDir, args.refreshScaffolds));
|
|
1513
|
+
if (!args.noLsMarketplace) phase("ls-marketplace", scaffoldLsMarketplace(targetDir));
|
|
1514
|
+
if (!args.noRecallHook) phase("recall-hook", scaffoldRecallHook(targetDir));
|
|
1515
|
+
const slR = tryActivateStatusline();
|
|
1516
|
+
if (slR) phase("statusline", slR);
|
|
1395
1517
|
if (DRY_RUN) {
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1518
|
+
console.log("");
|
|
1519
|
+
console.log(c.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1520
|
+
console.log(c.bold("DRY RUN COMPLETE") + c.dim(" \u2014 refresh would have applied the above; no files modified."));
|
|
1521
|
+
console.log(c.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1399
1522
|
return;
|
|
1400
1523
|
}
|
|
1401
1524
|
ok(`refresh complete \u2014 restart Claude Code to pick up any new /kit:* commands`);
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1525
|
+
const showGuide = args.quiet ? false : args.guide === true;
|
|
1526
|
+
const hints = ["Restart Claude Code to pick up any new /kit:* commands."];
|
|
1527
|
+
if (!showGuide && !args.quiet) hints.push("Run with --guide to print the full MCP + slash-command catalog. --verbose for per-file detail.");
|
|
1528
|
+
footer("Refresh complete.", hints);
|
|
1529
|
+
if (showGuide) {
|
|
1530
|
+
console.log(c.dim(`(refresh never runs these: clone, dependency install, onboard script, launch-recall init \u2014 use \`launch-kit init\` for a full bootstrap)`));
|
|
1531
|
+
console.log(getLaunchKitToolsGuide());
|
|
1406
1532
|
}
|
|
1407
1533
|
}
|
|
1408
1534
|
async function mainInit(args) {
|
|
@@ -1448,7 +1574,13 @@ async function mainInit(args) {
|
|
|
1448
1574
|
if (!/^ls_pat_/.test(args.token)) fail("Token does not look like a LaunchSecure PAT (expected prefix ls_pat_).");
|
|
1449
1575
|
if (!args.orgSlug) fail("--org=<orgSlug> is required.");
|
|
1450
1576
|
if (!args.projectSlug) fail("--project=<projectSlug> is required.");
|
|
1577
|
+
header("launch-kit init", [
|
|
1578
|
+
["org", args.orgSlug],
|
|
1579
|
+
["project", args.projectSlug],
|
|
1580
|
+
["server", args.serverUrl]
|
|
1581
|
+
]);
|
|
1451
1582
|
const { hasGh } = preflight();
|
|
1583
|
+
phase("preflight", { status: "ok", summary: `node ${process.versions.node}${hasGh ? " \xB7 git \xB7 gh" : " \xB7 git (gh not found \u2014 will use git for clone)"}` });
|
|
1452
1584
|
info(`resolving project ${args.orgSlug}/${args.projectSlug} on ${args.serverUrl} \u2026`);
|
|
1453
1585
|
let resolved;
|
|
1454
1586
|
try {
|
|
@@ -1457,6 +1589,7 @@ async function mainInit(args) {
|
|
|
1457
1589
|
fail(err instanceof Error ? err.message : String(err));
|
|
1458
1590
|
}
|
|
1459
1591
|
ok(`resolved "${resolved.projectName}"`);
|
|
1592
|
+
phase("project_info", { status: "ok", summary: `"${resolved.projectName}"` });
|
|
1460
1593
|
if (!resolved.repositoryUrl) {
|
|
1461
1594
|
fail(
|
|
1462
1595
|
`Project "${resolved.projectSlug}" has no GitHub repository configured. Connect GitHub at ${args.serverUrl}/${resolved.orgSlug}/projects/${resolved.projectSlug}/settings/integrations, then re-run init.`
|
|
@@ -1480,7 +1613,14 @@ async function mainInit(args) {
|
|
|
1480
1613
|
fail(`${targetDir} exists and is not empty (and not a matching git repo). Refusing to clone into it. Pass --dir=<other-path>.`);
|
|
1481
1614
|
}
|
|
1482
1615
|
}
|
|
1483
|
-
|
|
1616
|
+
const relTarget = path4.relative(cwd, targetDir) || ".";
|
|
1617
|
+
if (!skipClone) {
|
|
1618
|
+
section(`Cloning ${repoUrl}`);
|
|
1619
|
+
cloneRepo(repoUrl, targetDir, hasGh);
|
|
1620
|
+
phase("clone", { status: "ok", summary: `\u2192 ${relTarget}` });
|
|
1621
|
+
} else {
|
|
1622
|
+
phase("clone", { status: "in-sync", summary: `${relTarget} (already a clone of this repo)` });
|
|
1623
|
+
}
|
|
1484
1624
|
const cfg = {
|
|
1485
1625
|
pat: args.token,
|
|
1486
1626
|
orgSlug: resolved.orgSlug,
|
|
@@ -1489,7 +1629,8 @@ async function mainInit(args) {
|
|
|
1489
1629
|
};
|
|
1490
1630
|
const courseName = args.course ?? inferCourseName(cfg.serverUrl);
|
|
1491
1631
|
writeConfigFile(targetDir, cfg, courseName);
|
|
1492
|
-
|
|
1632
|
+
phase("cred file", { status: "ok", summary: `course=${courseName}, active` });
|
|
1633
|
+
phase(".mcp.json", mergeMcpFile(targetDir, buildLaunchKitMcpEntries(cfg)));
|
|
1493
1634
|
ensureGitignoreLine(targetDir, CONFIG_FILENAME);
|
|
1494
1635
|
let installSkippedReason = null;
|
|
1495
1636
|
const detected = detectPackageManager(targetDir);
|
|
@@ -1499,43 +1640,51 @@ async function mainInit(args) {
|
|
|
1499
1640
|
} else if (!detected) {
|
|
1500
1641
|
installSkippedReason = "no package.json found";
|
|
1501
1642
|
} else {
|
|
1643
|
+
section(`Installing dependencies (${detected.pm.name})`);
|
|
1502
1644
|
runInstall(targetDir, detected);
|
|
1503
|
-
|
|
1645
|
+
phase("install", { status: "ok", summary: `${detected.pm.binary} ${detected.pm.installArgs.join(" ")}` });
|
|
1646
|
+
if (!args.noOnboard && hasOnboardScript(targetDir)) {
|
|
1647
|
+
section(`Running ${detected.pm.binary} run ${ONBOARD_SCRIPT_NAME}`);
|
|
1648
|
+
runOnboard(targetDir, detected.pm);
|
|
1649
|
+
phase("onboard", { status: "ok", summary: `${detected.pm.binary} run ${ONBOARD_SCRIPT_NAME}` });
|
|
1650
|
+
}
|
|
1504
1651
|
}
|
|
1505
1652
|
const hasOnboard = hasOnboardScript(targetDir);
|
|
1506
|
-
if (
|
|
1507
|
-
if (!args.
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1653
|
+
if (installSkippedReason) phase("install", { status: "skipped", summary: installSkippedReason });
|
|
1654
|
+
if (!args.noRecall) {
|
|
1655
|
+
section("Initializing launch-recall (shadow git backup)");
|
|
1656
|
+
runRecallInit(targetDir);
|
|
1657
|
+
phase("launch-recall", { status: "ok", summary: "shadow git ready" });
|
|
1658
|
+
}
|
|
1659
|
+
if (!args.noMigrateSafety) phase("migrate-safety", scaffoldMigrateSafety(targetDir, args.refreshScaffolds));
|
|
1660
|
+
if (!args.noLsMarketplace) phase("ls-marketplace", scaffoldLsMarketplace(targetDir));
|
|
1661
|
+
if (!args.noRecallHook) phase("recall-hook", scaffoldRecallHook(targetDir));
|
|
1662
|
+
const slR = tryActivateStatusline();
|
|
1663
|
+
if (slR) phase("statusline", slR);
|
|
1513
1664
|
if (DRY_RUN) {
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1665
|
+
console.log("");
|
|
1666
|
+
console.log(c.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1667
|
+
console.log(c.bold("DRY RUN COMPLETE") + c.dim(` \u2014 no files were modified, no commands ran.`));
|
|
1668
|
+
console.log(c.dim(`Target: ${targetDir}`));
|
|
1669
|
+
console.log(c.dim(`Re-run without --dry-run to apply the changes shown above.`));
|
|
1670
|
+
console.log(c.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1519
1671
|
return;
|
|
1520
1672
|
}
|
|
1521
1673
|
ok(`done \u2014 ${resolved.projectName} is ready at ${targetDir}`);
|
|
1674
|
+
const showGuide = args.quiet ? false : args.guide ?? true;
|
|
1675
|
+
const nextSteps = [`cd ${relTarget}`];
|
|
1522
1676
|
if (installSkippedReason) {
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
Next steps (install skipped: ${installSkippedReason}):
|
|
1528
|
-
cd ${relTarget}
|
|
1529
|
-
${installLine}${onboardLine}
|
|
1530
|
-
claude # launch Claude Code (5 MCPs wired)${args.quiet ? "" : `
|
|
1531
|
-
${getLaunchKitToolsGuide()}`}`);
|
|
1532
|
-
} else if (!args.quiet) {
|
|
1533
|
-
console.log(`
|
|
1534
|
-
Next steps:
|
|
1535
|
-
cd ${relTarget}
|
|
1536
|
-
claude # launch Claude Code (5 MCPs wired)
|
|
1537
|
-
${getLaunchKitToolsGuide()}`);
|
|
1677
|
+
nextSteps.push(detected ? `${detected.pm.binary} ${detected.pm.installArgs.join(" ")} # install skipped: ${installSkippedReason}` : `npm install # install skipped: ${installSkippedReason}`);
|
|
1678
|
+
if (hasOnboard && detected && !args.noOnboard) {
|
|
1679
|
+
nextSteps.push(`${detected.pm.binary} run ${ONBOARD_SCRIPT_NAME} # project setup hook`);
|
|
1680
|
+
}
|
|
1538
1681
|
}
|
|
1682
|
+
nextSteps.push("claude # launch Claude Code (5 MCPs wired)");
|
|
1683
|
+
footer(`${resolved.projectName} is ready at ${relTarget}.`, [
|
|
1684
|
+
"Next:",
|
|
1685
|
+
...nextSteps.map((s) => " " + s)
|
|
1686
|
+
]);
|
|
1687
|
+
if (showGuide) console.log(getLaunchKitToolsGuide());
|
|
1539
1688
|
}
|
|
1540
1689
|
main().catch((err) => {
|
|
1541
1690
|
console.error(`[launch-kit] unexpected error: ${err instanceof Error ? err.stack ?? err.message : String(err)}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@launchsecure/launch-kit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"description": "LaunchSecure toolkit — launch-pod (pipeline), launch-chart (project graph MCP), launch-deck (visual playground MCP), launch-kit-beacon (feedback Web Component), launch-recall (file-watcher backup).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "LaunchSecure - AutomateWithUs",
|
|
@@ -56,6 +56,24 @@
|
|
|
56
56
|
"launch-course": "./dist/server/course-entry.js",
|
|
57
57
|
"launch-beacon": "./dist/server/beacon-monitor-entry.js"
|
|
58
58
|
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "pnpm build:client && pnpm build:chart-client && pnpm build:deck-client && pnpm build:council-client && pnpm build:beacon && pnpm build:server",
|
|
61
|
+
"build:beacon": "vite build --config vite.beacon.config.ts && tsc -p tsconfig.beacon.json --emitDeclarationOnly --outDir dist/beacon/types",
|
|
62
|
+
"test:beacon": "vitest run --config vite.beacon.config.ts",
|
|
63
|
+
"test:radar": "vitest run --config vite.radar.config.ts",
|
|
64
|
+
"test:chart": "vitest run --config vite.chart.test.config.ts",
|
|
65
|
+
"build:deck-client": "vite build --config vite.deck.config.ts",
|
|
66
|
+
"build:council-client": "vite build --config vite.council.config.ts",
|
|
67
|
+
"build:client": "vite build",
|
|
68
|
+
"build:chart-client": "vite build --config vite.chart.config.ts",
|
|
69
|
+
"build:server": "esbuild src/server/cli.ts src/server/fb-wizard.ts src/server/graph-mcp-entry.ts src/server/chart-serve.ts src/server/deck-mcp-entry.ts src/server/deck-serve.ts src/server/council-entry.ts src/server/council-serve.ts src/server/recall-entry.ts src/server/init-entry.ts src/server/orbit-entry.ts src/server/course-entry.ts src/server/beacon-monitor-entry.ts src/server/parse-worker-entry.ts --bundle --platform=node --target=node18 --outdir=dist/server --external:node-pty --external:ws --external:typescript --external:web-tree-sitter --external:tree-sitter-typescript --external:cloudflared --external:pg --external:pg-native --external:pgsql-parser --external:libpg-query && rm -rf dist/server/public && cp -r ../claude-code-web/src/public dist/server/public && rm -rf dist/server/graph/queries && mkdir -p dist/server/graph && cp -r src/server/graph/queries dist/server/graph/queries",
|
|
70
|
+
"dev:client": "vite",
|
|
71
|
+
"dev:deck-serve": "cd ../.. && tsx watch packages/cli/src/server/deck-mcp-entry.ts serve",
|
|
72
|
+
"dev:chart": "pnpm build:server && pnpm build:chart-client && node dist/server/graph-mcp-entry.js serve",
|
|
73
|
+
"dev:server": "pnpm build:server && node dist/server/cli.js",
|
|
74
|
+
"dev": "pnpm build:server && concurrently -k -n client,server -c cyan,magenta \"vite\" \"node dist/server/cli.js\"",
|
|
75
|
+
"prepublishOnly": "pnpm build"
|
|
76
|
+
},
|
|
59
77
|
"files": [
|
|
60
78
|
"dist",
|
|
61
79
|
"prompts",
|
|
@@ -76,6 +94,8 @@
|
|
|
76
94
|
"ws": "^8.18.0"
|
|
77
95
|
},
|
|
78
96
|
"devDependencies": {
|
|
97
|
+
"@launchsecure/claude-code-web": "workspace:*",
|
|
98
|
+
"@launchsecure/ui": "workspace:*",
|
|
79
99
|
"@types/node": "^20.0.0",
|
|
80
100
|
"@types/pg": "^8.11.10",
|
|
81
101
|
"@types/react": "^18.3.12",
|
|
@@ -99,24 +119,6 @@
|
|
|
99
119
|
"react-router-dom": "^6.28.0",
|
|
100
120
|
"tailwindcss": "^3.4.19",
|
|
101
121
|
"vite": "^5.4.11",
|
|
102
|
-
"vitest": "^1.6.0"
|
|
103
|
-
"@launchsecure/claude-code-web": "0.0.1",
|
|
104
|
-
"@launchsecure/ui": "0.0.1"
|
|
105
|
-
},
|
|
106
|
-
"scripts": {
|
|
107
|
-
"build": "pnpm build:client && pnpm build:chart-client && pnpm build:deck-client && pnpm build:council-client && pnpm build:beacon && pnpm build:server",
|
|
108
|
-
"build:beacon": "vite build --config vite.beacon.config.ts && tsc -p tsconfig.beacon.json --emitDeclarationOnly --outDir dist/beacon/types",
|
|
109
|
-
"test:beacon": "vitest run --config vite.beacon.config.ts",
|
|
110
|
-
"test:radar": "vitest run --config vite.radar.config.ts",
|
|
111
|
-
"test:chart": "vitest run --config vite.chart.test.config.ts",
|
|
112
|
-
"build:deck-client": "vite build --config vite.deck.config.ts",
|
|
113
|
-
"build:council-client": "vite build --config vite.council.config.ts",
|
|
114
|
-
"build:client": "vite build",
|
|
115
|
-
"build:chart-client": "vite build --config vite.chart.config.ts",
|
|
116
|
-
"build:server": "esbuild src/server/cli.ts src/server/fb-wizard.ts src/server/graph-mcp-entry.ts src/server/chart-serve.ts src/server/deck-mcp-entry.ts src/server/deck-serve.ts src/server/council-entry.ts src/server/council-serve.ts src/server/recall-entry.ts src/server/init-entry.ts src/server/orbit-entry.ts src/server/course-entry.ts src/server/beacon-monitor-entry.ts src/server/parse-worker-entry.ts --bundle --platform=node --target=node18 --outdir=dist/server --external:node-pty --external:ws --external:typescript --external:web-tree-sitter --external:tree-sitter-typescript --external:cloudflared --external:pg --external:pg-native --external:pgsql-parser --external:libpg-query && rm -rf dist/server/public && cp -r ../claude-code-web/src/public dist/server/public && rm -rf dist/server/graph/queries && mkdir -p dist/server/graph && cp -r src/server/graph/queries dist/server/graph/queries",
|
|
117
|
-
"dev:client": "vite",
|
|
118
|
-
"dev:chart": "pnpm build:server && pnpm build:chart-client && node dist/server/graph-mcp-entry.js serve",
|
|
119
|
-
"dev:server": "pnpm build:server && node dist/server/cli.js",
|
|
120
|
-
"dev": "pnpm build:server && concurrently -k -n client,server -c cyan,magenta \"vite\" \"node dist/server/cli.js\""
|
|
122
|
+
"vitest": "^1.6.0"
|
|
121
123
|
}
|
|
122
|
-
}
|
|
124
|
+
}
|