@launchsecure/launch-kit 0.0.38 → 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/beacon/beacon.mjs +308 -298
- package/dist/beacon/beacon.mjs.map +1 -1
- package/dist/beacon/beacon.umd.js +6 -6
- package/dist/beacon/beacon.umd.js.map +1 -1
- package/dist/beacon/types/internal/screenshot.d.ts.map +1 -1
- 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-CgW32Gdk.js → _baseUniq-BZP7n41F.js} +1 -1
- package/dist/deck-client/assets/{arc-D-Mg9gvM.js → arc-31biU3Az.js} +1 -1
- package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-CdTsXsgl.js → architectureDiagram-Q4EWVU46-DHg6Ss--.js} +1 -1
- package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-mwTneYyB.js → blockDiagram-DXYQGD6D-CUdblaWk.js} +1 -1
- package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-C4R8IbjO.js → c4Diagram-AHTNJAMY-MfAO5lak.js} +1 -1
- package/dist/deck-client/assets/channel-BBkRLdnC.js +1 -0
- package/dist/deck-client/assets/{chunk-4BX2VUAB-ZWuRIUwb.js → chunk-4BX2VUAB-DQ1MrGgN.js} +1 -1
- package/dist/deck-client/assets/{chunk-4TB4RGXK-PNHX10sF.js → chunk-4TB4RGXK-BUJtZ7jO.js} +1 -1
- package/dist/deck-client/assets/{chunk-55IACEB6-CD9MUgPr.js → chunk-55IACEB6-BdSnXB6g.js} +1 -1
- package/dist/deck-client/assets/{chunk-EDXVE4YY-C_CpORb3.js → chunk-EDXVE4YY-94yZIUI8.js} +1 -1
- package/dist/deck-client/assets/{chunk-FMBD7UC4-Bg5RoVC-.js → chunk-FMBD7UC4-PnZ9v6ey.js} +1 -1
- package/dist/deck-client/assets/{chunk-OYMX7WX6-DhTwgQwd.js → chunk-OYMX7WX6-DXrWNOsV.js} +1 -1
- package/dist/deck-client/assets/{chunk-QZHKN3VN-C5VLMaFa.js → chunk-QZHKN3VN-CsIGIDKX.js} +1 -1
- package/dist/deck-client/assets/{chunk-YZCP3GAM-NAGHy4Sr.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-CpUczjZk.js → cose-bilkent-S5V4N54A-m126Oh3b.js} +1 -1
- package/dist/deck-client/assets/{dagre-KV5264BT-BOvb07MG.js → dagre-KV5264BT-C2aig8U5.js} +1 -1
- package/dist/deck-client/assets/{diagram-5BDNPKRD-BPxwTiC-.js → diagram-5BDNPKRD-CKpoRfGn.js} +1 -1
- package/dist/deck-client/assets/{diagram-G4DWMVQ6-Dz_gsHgx.js → diagram-G4DWMVQ6-Cjh115Ep.js} +1 -1
- package/dist/deck-client/assets/{diagram-MMDJMWI5-B7z-oVTW.js → diagram-MMDJMWI5-DKlBv_2L.js} +1 -1
- package/dist/deck-client/assets/{diagram-TYMM5635-CAIAglLQ.js → diagram-TYMM5635-CdBh4cEn.js} +1 -1
- package/dist/deck-client/assets/{erDiagram-SMLLAGMA-BiViTWF3.js → erDiagram-SMLLAGMA-56pn_93p.js} +1 -1
- package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-DYVemp0H.js → flowDiagram-DWJPFMVM-BtV3M5xJ.js} +1 -1
- package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-Chc1Iyu1.js → ganttDiagram-T4ZO3ILL-DTIsC6Zg.js} +1 -1
- package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-B7eFgaj5.js → gitGraphDiagram-UUTBAWPF-CJYeyCLe.js} +1 -1
- package/dist/deck-client/assets/{graph-CKaIoNwb.js → graph-BDvMu1Ss.js} +1 -1
- package/dist/deck-client/assets/index-D4eSxcBn.css +1 -0
- package/dist/deck-client/assets/{index-BRawc7RA.js → index-QnGVE9PZ.js} +83 -83
- package/dist/deck-client/assets/{infoDiagram-42DDH7IO-BxsVq7vO.js → infoDiagram-42DDH7IO-BWyKJnpW.js} +1 -1
- package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-DAM7vPwa.js → ishikawaDiagram-UXIWVN3A-DXYkdO3T.js} +1 -1
- package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-Xe20Nf7R.js → journeyDiagram-VCZTEJTY-C2zBr-J5.js} +1 -1
- package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-DS8YguzB.js → kanban-definition-6JOO6SKY-CdoYLS4Z.js} +1 -1
- package/dist/deck-client/assets/{layout-DKMBpzR-.js → layout-vOnxnCQU.js} +1 -1
- package/dist/deck-client/assets/{linear-DTNtBg5h.js → linear-B0J0WCGz.js} +1 -1
- package/dist/deck-client/assets/{min-C4DrxCcA.js → min-B0AXlT9L.js} +1 -1
- package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-B4nEtsw5.js → mindmap-definition-QFDTVHPH-oAybLedr.js} +1 -1
- package/dist/deck-client/assets/{pieDiagram-DEJITSTG-BzHdGNu5.js → pieDiagram-DEJITSTG-BjHyHxGk.js} +1 -1
- package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-CaX0SD4-.js → quadrantDiagram-34T5L4WZ-dtluDZXs.js} +1 -1
- package/dist/deck-client/assets/{requirementDiagram-MS252O5E-QeG4p2ni.js → requirementDiagram-MS252O5E-Cq8l7bOl.js} +1 -1
- package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-BoAwgAj-.js → sankeyDiagram-XADWPNL6-C1Vih91z.js} +1 -1
- package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-Dn4pYYgu.js → sequenceDiagram-FGHM5R23-CYkd7oQK.js} +1 -1
- package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-Is6KRmQV.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-v64IZGuY.js → timeline-definition-GMOUNBTQ-DZIxSyd1.js} +1 -1
- package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-noh9eouF.js → vennDiagram-DHZGUBPP-Ct4JVRDM.js} +1 -1
- package/dist/deck-client/assets/{wardley-RL74JXVD-cJ_1is2S.js → wardley-RL74JXVD-V29ycxOW.js} +1 -1
- package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-DxR4j737.js → wardleyDiagram-NUSXRM2D-D-Ua6Cmi.js} +1 -1
- package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-B26vodaL.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 +270 -108
- package/dist/server/deck-serve.js +101 -23
- package/dist/server/fb-wizard.js +0 -0
- package/dist/server/graph-mcp-entry.js +866 -357
- package/dist/server/init-entry.js +152 -25
- package/dist/server/orbit-entry.js +91 -7
- package/dist/server/radar-docker-init-entry.js +0 -0
- package/dist/server/radar-entrypoint-entry.js +0 -0
- package/dist/server/radar-teardown-entry.js +0 -0
- package/dist/server/recall-entry.js +94 -12
- package/dist/server/rover-entry.js +44 -1
- package/package.json +23 -22
- package/scaffolds/ls-marketplace/plugins/kit/commands/activate-statusline.md +8 -7
- package/scaffolds/ls-marketplace/plugins/kit/commands/deactivate-statusline.md +2 -2
- package/scaffolds/ls-marketplace/plugins/kit/skills/comms/SKILL.md +88 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/project-info/SKILL.md +88 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/slides/SKILL.md +118 -0
- package/scaffolds/migrate-safety/scripts/migrate-with-backup.sh +0 -0
- package/scaffolds/recall-hook/scripts/ensure-recall.sh +0 -0
- package/scaffolds/statusline/statusline-base.sh +20 -0
- package/scaffolds/statusline/statusline-mcp.sh +68 -19
- package/scaffolds/statusline/statusline-wrapper.sh +12 -9
- package/dist/chart-client/assets/index-B6rR0CWx.css +0 -1
- package/dist/client/assets/index-D6uX1lQe.css +0 -32
- package/dist/council-client/assets/index-CleYLarJ.css +0 -1
- package/dist/deck-client/assets/channel-CuSee7GO.js +0 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-_kTisqzs.js +0 -1
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-_kTisqzs.js +0 -1
- package/dist/deck-client/assets/clone-kb3zkY60.js +0 -1
- package/dist/deck-client/assets/index-55P73aS_.css +0 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-Cy45Ttqq.js +0 -1
- /package/dist/chart-client/assets/{index-C_xCi3gW.js → index-Dzlj-oCj.js} +0 -0
- /package/dist/client/assets/{index-CRecYFUA.js → index-tTg_ezUF.js} +0 -0
- /package/dist/council-client/assets/{index-DO-Vn15O.js → index-B1v46vTE.js} +0 -0
|
@@ -128,24 +128,24 @@ var init_deck_lockfile = __esm({
|
|
|
128
128
|
|
|
129
129
|
// src/server/deck-config.ts
|
|
130
130
|
function loadDeckConfig(rootDir) {
|
|
131
|
-
const configPath = (0,
|
|
132
|
-
if (!(0,
|
|
131
|
+
const configPath = (0, import_node_path3.join)(rootDir, CONFIG_FILENAME);
|
|
132
|
+
if (!(0, import_node_fs3.existsSync)(configPath)) return {};
|
|
133
133
|
try {
|
|
134
|
-
return JSON.parse((0,
|
|
134
|
+
return JSON.parse((0, import_node_fs3.readFileSync)(configPath, "utf-8"));
|
|
135
135
|
} catch {
|
|
136
136
|
return {};
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
function saveDeckConfig(rootDir, config) {
|
|
140
|
-
const configPath = (0,
|
|
141
|
-
(0,
|
|
140
|
+
const configPath = (0, import_node_path3.join)(rootDir, CONFIG_FILENAME);
|
|
141
|
+
(0, import_node_fs3.writeFileSync)(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
142
142
|
}
|
|
143
|
-
var
|
|
143
|
+
var import_node_fs3, import_node_path3, CONFIG_FILENAME;
|
|
144
144
|
var init_deck_config = __esm({
|
|
145
145
|
"src/server/deck-config.ts"() {
|
|
146
146
|
"use strict";
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
import_node_fs3 = require("node:fs");
|
|
148
|
+
import_node_path3 = require("node:path");
|
|
149
149
|
CONFIG_FILENAME = ".launchdeck.json";
|
|
150
150
|
}
|
|
151
151
|
});
|
|
@@ -1250,7 +1250,7 @@ var init_cred_shape = __esm({
|
|
|
1250
1250
|
});
|
|
1251
1251
|
|
|
1252
1252
|
// src/server/mcp-client.ts
|
|
1253
|
-
function
|
|
1253
|
+
function mcpConfigForProfile(projectRoot, name) {
|
|
1254
1254
|
let cred;
|
|
1255
1255
|
try {
|
|
1256
1256
|
cred = readCredFile(projectRoot);
|
|
@@ -1260,7 +1260,7 @@ function mcpConfigFromCourse(projectRoot) {
|
|
|
1260
1260
|
if (!cred) return null;
|
|
1261
1261
|
const nested = toNested(cred);
|
|
1262
1262
|
if (!nested) return null;
|
|
1263
|
-
const profile = nested.profiles[
|
|
1263
|
+
const profile = nested.profiles[name];
|
|
1264
1264
|
if (!profile?.pat || !profile.serverUrl || !profile.orgSlug || !profile.projectSlug) {
|
|
1265
1265
|
return null;
|
|
1266
1266
|
}
|
|
@@ -1273,6 +1273,37 @@ function mcpConfigFromCourse(projectRoot) {
|
|
|
1273
1273
|
}
|
|
1274
1274
|
};
|
|
1275
1275
|
}
|
|
1276
|
+
function mcpConfigFromCourse(projectRoot) {
|
|
1277
|
+
let cred;
|
|
1278
|
+
try {
|
|
1279
|
+
cred = readCredFile(projectRoot);
|
|
1280
|
+
} catch {
|
|
1281
|
+
return null;
|
|
1282
|
+
}
|
|
1283
|
+
if (!cred) return null;
|
|
1284
|
+
const nested = toNested(cred);
|
|
1285
|
+
if (!nested) return null;
|
|
1286
|
+
return mcpConfigForProfile(projectRoot, nested.active);
|
|
1287
|
+
}
|
|
1288
|
+
function listCourses(projectRoot) {
|
|
1289
|
+
let cred;
|
|
1290
|
+
try {
|
|
1291
|
+
cred = readCredFile(projectRoot);
|
|
1292
|
+
} catch {
|
|
1293
|
+
return [];
|
|
1294
|
+
}
|
|
1295
|
+
if (!cred) return [];
|
|
1296
|
+
const nested = toNested(cred);
|
|
1297
|
+
if (!nested) return [];
|
|
1298
|
+
return Object.entries(nested.profiles).map(([name, p]) => ({
|
|
1299
|
+
name,
|
|
1300
|
+
org: p.orgSlug ?? "",
|
|
1301
|
+
project: p.projectSlug ?? "",
|
|
1302
|
+
serverUrl: p.serverUrl ?? "",
|
|
1303
|
+
active: name === nested.active,
|
|
1304
|
+
usable: Boolean(p.pat && p.serverUrl && p.orgSlug && p.projectSlug)
|
|
1305
|
+
}));
|
|
1306
|
+
}
|
|
1276
1307
|
function loadMcpConfig(projectRoot) {
|
|
1277
1308
|
if (_config) return _config;
|
|
1278
1309
|
const fromCourse = mcpConfigFromCourse(projectRoot);
|
|
@@ -1280,13 +1311,13 @@ function loadMcpConfig(projectRoot) {
|
|
|
1280
1311
|
_config = fromCourse;
|
|
1281
1312
|
return _config;
|
|
1282
1313
|
}
|
|
1283
|
-
const mcpPath = (0,
|
|
1284
|
-
if (!(0,
|
|
1314
|
+
const mcpPath = (0, import_node_path4.join)(projectRoot, ".mcp.json");
|
|
1315
|
+
if (!(0, import_node_fs4.existsSync)(mcpPath)) {
|
|
1285
1316
|
throw new Error(
|
|
1286
1317
|
`No active course in ${CONFIG_FILENAME2} and no .mcp.json at ${mcpPath}. Run \`launch-course\` or bootstrap with \`launch-kit init\`.`
|
|
1287
1318
|
);
|
|
1288
1319
|
}
|
|
1289
|
-
const raw = JSON.parse((0,
|
|
1320
|
+
const raw = JSON.parse((0, import_node_fs4.readFileSync)(mcpPath, "utf-8"));
|
|
1290
1321
|
const entry = raw.mcpServers["launch-secure"];
|
|
1291
1322
|
if (!entry?.url) {
|
|
1292
1323
|
throw new Error(
|
|
@@ -1299,6 +1330,23 @@ function loadMcpConfig(projectRoot) {
|
|
|
1299
1330
|
};
|
|
1300
1331
|
return _config;
|
|
1301
1332
|
}
|
|
1333
|
+
function withMcpConfig(override, fn) {
|
|
1334
|
+
const run = async () => {
|
|
1335
|
+
const prevConfig = _config;
|
|
1336
|
+
const prevSession = _sessionId;
|
|
1337
|
+
_config = override;
|
|
1338
|
+
_sessionId = null;
|
|
1339
|
+
try {
|
|
1340
|
+
return await fn();
|
|
1341
|
+
} finally {
|
|
1342
|
+
_config = prevConfig;
|
|
1343
|
+
_sessionId = prevSession;
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
const result = _overrideLock.then(run, run);
|
|
1347
|
+
_overrideLock = result.then(() => void 0, () => void 0);
|
|
1348
|
+
return result;
|
|
1349
|
+
}
|
|
1302
1350
|
function parseSSE(text2) {
|
|
1303
1351
|
const lines = text2.split("\n");
|
|
1304
1352
|
for (const line of lines) {
|
|
@@ -1406,16 +1454,17 @@ async function updateDeck(commentId, input) {
|
|
|
1406
1454
|
async function deleteDeck(commentId) {
|
|
1407
1455
|
await callTool("communication_delete", { comment_id: commentId });
|
|
1408
1456
|
}
|
|
1409
|
-
var
|
|
1457
|
+
var import_node_fs4, import_node_path4, _config, _requestId, _sessionId, _overrideLock;
|
|
1410
1458
|
var init_mcp_client = __esm({
|
|
1411
1459
|
"src/server/mcp-client.ts"() {
|
|
1412
1460
|
"use strict";
|
|
1413
|
-
|
|
1414
|
-
|
|
1461
|
+
import_node_fs4 = require("node:fs");
|
|
1462
|
+
import_node_path4 = require("node:path");
|
|
1415
1463
|
init_cred_shape();
|
|
1416
1464
|
_config = null;
|
|
1417
1465
|
_requestId = 0;
|
|
1418
1466
|
_sessionId = null;
|
|
1467
|
+
_overrideLock = Promise.resolve();
|
|
1419
1468
|
}
|
|
1420
1469
|
});
|
|
1421
1470
|
|
|
@@ -1430,14 +1479,14 @@ __export(deck_serve_exports, {
|
|
|
1430
1479
|
startDeckServer: () => startDeckServer
|
|
1431
1480
|
});
|
|
1432
1481
|
function sessionDir(cwd, session) {
|
|
1433
|
-
return
|
|
1482
|
+
return import_node_path5.default.join(cwd, LAUNCHSECURE_DIR, "deck-files", session);
|
|
1434
1483
|
}
|
|
1435
1484
|
function sessionJsonPath(cwd, session) {
|
|
1436
|
-
return
|
|
1485
|
+
return import_node_path5.default.join(sessionDir(cwd, session), "session.json");
|
|
1437
1486
|
}
|
|
1438
1487
|
function readPersistedSession(cwd, session) {
|
|
1439
1488
|
try {
|
|
1440
|
-
const raw =
|
|
1489
|
+
const raw = import_node_fs5.default.readFileSync(sessionJsonPath(cwd, session), "utf-8");
|
|
1441
1490
|
return JSON.parse(raw);
|
|
1442
1491
|
} catch {
|
|
1443
1492
|
return null;
|
|
@@ -1445,7 +1494,7 @@ function readPersistedSession(cwd, session) {
|
|
|
1445
1494
|
}
|
|
1446
1495
|
function writePersistedSession(cwd, session, payload) {
|
|
1447
1496
|
const dir = sessionDir(cwd, session);
|
|
1448
|
-
|
|
1497
|
+
import_node_fs5.default.mkdirSync(dir, { recursive: true });
|
|
1449
1498
|
const existing = readPersistedSession(cwd, session);
|
|
1450
1499
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1451
1500
|
const next = {
|
|
@@ -1457,18 +1506,19 @@ function writePersistedSession(cwd, session, payload) {
|
|
|
1457
1506
|
createdAt: existing?.createdAt ?? now,
|
|
1458
1507
|
updatedAt: now
|
|
1459
1508
|
};
|
|
1460
|
-
|
|
1509
|
+
import_node_fs5.default.writeFileSync(sessionJsonPath(cwd, session), JSON.stringify(next, null, 2));
|
|
1461
1510
|
return next;
|
|
1462
1511
|
}
|
|
1463
1512
|
function listPersistedSessions(cwd) {
|
|
1464
|
-
const base =
|
|
1465
|
-
if (!
|
|
1466
|
-
const entries =
|
|
1513
|
+
const base = import_node_path5.default.join(cwd, LAUNCHSECURE_DIR, "deck-files");
|
|
1514
|
+
if (!import_node_fs5.default.existsSync(base)) return [];
|
|
1515
|
+
const entries = import_node_fs5.default.readdirSync(base, { withFileTypes: true });
|
|
1467
1516
|
const sessions = [];
|
|
1468
1517
|
for (const entry of entries) {
|
|
1469
1518
|
if (!entry.isDirectory()) continue;
|
|
1470
1519
|
const persisted = readPersistedSession(cwd, entry.name);
|
|
1471
1520
|
if (!persisted) continue;
|
|
1521
|
+
const sync = readSyncRecord(cwd, persisted.id);
|
|
1472
1522
|
sessions.push({
|
|
1473
1523
|
id: persisted.id,
|
|
1474
1524
|
mode: persisted.mode,
|
|
@@ -1476,33 +1526,34 @@ function listPersistedSessions(cwd) {
|
|
|
1476
1526
|
version: persisted.version,
|
|
1477
1527
|
createdAt: persisted.createdAt,
|
|
1478
1528
|
updatedAt: persisted.updatedAt,
|
|
1479
|
-
shared: Boolean(
|
|
1529
|
+
shared: Boolean(sync),
|
|
1530
|
+
stale: Boolean(sync) && persisted.version > (sync?.version ?? 0)
|
|
1480
1531
|
});
|
|
1481
1532
|
}
|
|
1482
1533
|
sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
1483
1534
|
return sessions;
|
|
1484
1535
|
}
|
|
1485
1536
|
function deletePersistedSession(cwd, session) {
|
|
1486
|
-
const base =
|
|
1537
|
+
const base = import_node_path5.default.join(cwd, LAUNCHSECURE_DIR, "deck-files");
|
|
1487
1538
|
if (session === "all") {
|
|
1488
|
-
if (
|
|
1539
|
+
if (import_node_fs5.default.existsSync(base)) import_node_fs5.default.rmSync(base, { recursive: true, force: true });
|
|
1489
1540
|
return;
|
|
1490
1541
|
}
|
|
1491
1542
|
const dir = sessionDir(cwd, session);
|
|
1492
|
-
if (
|
|
1543
|
+
if (import_node_fs5.default.existsSync(dir)) import_node_fs5.default.rmSync(dir, { recursive: true, force: true });
|
|
1493
1544
|
}
|
|
1494
1545
|
function syncJsonPath(cwd, session) {
|
|
1495
|
-
return
|
|
1546
|
+
return import_node_path5.default.join(sessionDir(cwd, session), ".sync.json");
|
|
1496
1547
|
}
|
|
1497
1548
|
function readSyncRecord(cwd, session) {
|
|
1498
1549
|
try {
|
|
1499
|
-
return JSON.parse(
|
|
1550
|
+
return JSON.parse(import_node_fs5.default.readFileSync(syncJsonPath(cwd, session), "utf-8"));
|
|
1500
1551
|
} catch {
|
|
1501
1552
|
return null;
|
|
1502
1553
|
}
|
|
1503
1554
|
}
|
|
1504
1555
|
function writeSyncRecord(cwd, session, rec) {
|
|
1505
|
-
|
|
1556
|
+
import_node_fs5.default.writeFileSync(syncJsonPath(cwd, session), JSON.stringify(rec, null, 2));
|
|
1506
1557
|
}
|
|
1507
1558
|
function escHtml2(s) {
|
|
1508
1559
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
@@ -1515,7 +1566,7 @@ function readIframeArtifact(cwd, src) {
|
|
|
1515
1566
|
const rel = decodeURIComponent(src.slice("/deck-files/".length));
|
|
1516
1567
|
if (rel.includes("..")) return null;
|
|
1517
1568
|
try {
|
|
1518
|
-
return
|
|
1569
|
+
return import_node_fs5.default.readFileSync(import_node_path5.default.join(cwd, LAUNCHSECURE_DIR, "deck-files", rel), "utf-8");
|
|
1519
1570
|
} catch {
|
|
1520
1571
|
return null;
|
|
1521
1572
|
}
|
|
@@ -1612,23 +1663,23 @@ function broadcastToClients(message) {
|
|
|
1612
1663
|
}
|
|
1613
1664
|
}
|
|
1614
1665
|
function serveStatic(res, filePath) {
|
|
1615
|
-
if (!
|
|
1616
|
-
const ext =
|
|
1666
|
+
if (!import_node_fs5.default.existsSync(filePath) || !import_node_fs5.default.statSync(filePath).isFile()) return false;
|
|
1667
|
+
const ext = import_node_path5.default.extname(filePath).toLowerCase();
|
|
1617
1668
|
const mime = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
1618
1669
|
res.writeHead(200, { "Content-Type": mime, "Cache-Control": "no-cache" });
|
|
1619
|
-
|
|
1670
|
+
import_node_fs5.default.createReadStream(filePath).pipe(res);
|
|
1620
1671
|
return true;
|
|
1621
1672
|
}
|
|
1622
1673
|
function resolveClientDir() {
|
|
1623
|
-
const sibling =
|
|
1624
|
-
if (
|
|
1625
|
-
const devDist =
|
|
1626
|
-
if (
|
|
1674
|
+
const sibling = import_node_path5.default.join(__dirname, "..", "deck-client");
|
|
1675
|
+
if (import_node_fs5.default.existsSync(import_node_path5.default.join(sibling, "assets"))) return sibling;
|
|
1676
|
+
const devDist = import_node_path5.default.join(__dirname, "..", "..", "dist", "deck-client");
|
|
1677
|
+
if (import_node_fs5.default.existsSync(import_node_path5.default.join(devDist, "assets"))) return devDist;
|
|
1627
1678
|
return sibling;
|
|
1628
1679
|
}
|
|
1629
1680
|
function serveIndex(res, clientDir) {
|
|
1630
|
-
const indexPath =
|
|
1631
|
-
if (!
|
|
1681
|
+
const indexPath = import_node_path5.default.join(clientDir, "index.html");
|
|
1682
|
+
if (!import_node_fs5.default.existsSync(indexPath)) {
|
|
1632
1683
|
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
1633
1684
|
res.end(`LaunchDeck client bundle not found at ${clientDir}. Run 'npm run build:client'.`);
|
|
1634
1685
|
return;
|
|
@@ -1711,6 +1762,10 @@ async function startDeckServer(opts = {}) {
|
|
|
1711
1762
|
jsonResponse(res, 200, { config: cfg });
|
|
1712
1763
|
return;
|
|
1713
1764
|
}
|
|
1765
|
+
if (req.method === "GET" && url2.pathname === "/api/deck/courses") {
|
|
1766
|
+
jsonResponse(res, 200, { courses: listCourses(cwd) });
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1714
1769
|
if (req.method === "POST" && url2.pathname === "/api/deck/config") {
|
|
1715
1770
|
try {
|
|
1716
1771
|
const body = JSON.parse(await readBody(req));
|
|
@@ -1732,15 +1787,15 @@ async function startDeckServer(opts = {}) {
|
|
|
1732
1787
|
const baseUrl = `/deck-files/${sessionEncoded}`;
|
|
1733
1788
|
const html = generateBlastRadiusHtml(block.manifest, baseUrl);
|
|
1734
1789
|
const report = generateBlastRadiusReport(block.manifest);
|
|
1735
|
-
const dir =
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1790
|
+
const dir = import_node_path5.default.join(cwd, LAUNCHSECURE_DIR, "deck-files", body.session);
|
|
1791
|
+
import_node_fs5.default.mkdirSync(dir, { recursive: true });
|
|
1792
|
+
import_node_fs5.default.writeFileSync(import_node_path5.default.join(dir, "blast-radius.html"), html);
|
|
1793
|
+
import_node_fs5.default.writeFileSync(import_node_path5.default.join(dir, "blast-radius-report.md"), report);
|
|
1794
|
+
import_node_fs5.default.writeFileSync(import_node_path5.default.join(dir, "blast-radius-manifest.json"), JSON.stringify(block.manifest, null, 2));
|
|
1740
1795
|
const contractData = generateContract(block.manifest);
|
|
1741
1796
|
const contractMd = contractToMarkdown(contractData);
|
|
1742
|
-
|
|
1743
|
-
|
|
1797
|
+
import_node_fs5.default.writeFileSync(import_node_path5.default.join(dir, "contract.json"), JSON.stringify(contractData, null, 2));
|
|
1798
|
+
import_node_fs5.default.writeFileSync(import_node_path5.default.join(dir, "contract.md"), contractMd);
|
|
1744
1799
|
block.type = "iframe";
|
|
1745
1800
|
block.src = `${baseUrl}/blast-radius.html`;
|
|
1746
1801
|
delete block.manifest;
|
|
@@ -1767,9 +1822,9 @@ async function startDeckServer(opts = {}) {
|
|
|
1767
1822
|
const sessionEncoded = encodeURIComponent(body.session);
|
|
1768
1823
|
const baseUrl = `/deck-files/${sessionEncoded}`;
|
|
1769
1824
|
const filename = `${slugify(block.label)}.html`;
|
|
1770
|
-
const dir =
|
|
1771
|
-
|
|
1772
|
-
|
|
1825
|
+
const dir = import_node_path5.default.join(cwd, LAUNCHSECURE_DIR, "deck-files", body.session);
|
|
1826
|
+
import_node_fs5.default.mkdirSync(dir, { recursive: true });
|
|
1827
|
+
import_node_fs5.default.writeFileSync(import_node_path5.default.join(dir, filename), html);
|
|
1773
1828
|
block.type = "iframe";
|
|
1774
1829
|
block.src = `${baseUrl}/${filename}`;
|
|
1775
1830
|
delete block.content;
|
|
@@ -1809,14 +1864,34 @@ async function startDeckServer(opts = {}) {
|
|
|
1809
1864
|
jsonResponse(res, 404, { ok: false, error: "session not found" });
|
|
1810
1865
|
return;
|
|
1811
1866
|
}
|
|
1867
|
+
let course;
|
|
1812
1868
|
try {
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1869
|
+
const raw = await readBody(req);
|
|
1870
|
+
if (raw.trim()) {
|
|
1871
|
+
course = JSON.parse(raw).course?.trim() || void 0;
|
|
1872
|
+
}
|
|
1873
|
+
} catch {
|
|
1874
|
+
}
|
|
1875
|
+
let override = null;
|
|
1876
|
+
if (course) {
|
|
1877
|
+
override = mcpConfigForProfile(cwd, course);
|
|
1878
|
+
if (!override) {
|
|
1879
|
+
jsonResponse(res, 400, {
|
|
1880
|
+
ok: false,
|
|
1881
|
+
error: `Course "${course}" is not a usable profile in .launch-secure.cred.config (missing pat/serverUrl/orgSlug/projectSlug?).`
|
|
1882
|
+
});
|
|
1883
|
+
return;
|
|
1884
|
+
}
|
|
1885
|
+
} else {
|
|
1886
|
+
try {
|
|
1887
|
+
loadMcpConfig(cwd);
|
|
1888
|
+
} catch (err) {
|
|
1889
|
+
jsonResponse(res, 400, {
|
|
1890
|
+
ok: false,
|
|
1891
|
+
error: `Cloud sharing needs an active LaunchSecure course (.launch-secure.cred.config) or a "launch-secure" entry in .mcp.json: ${String(err)}`
|
|
1892
|
+
});
|
|
1893
|
+
return;
|
|
1894
|
+
}
|
|
1820
1895
|
}
|
|
1821
1896
|
try {
|
|
1822
1897
|
const blocks = Array.isArray(persisted.blocks) ? persisted.blocks : [];
|
|
@@ -1825,24 +1900,27 @@ async function startDeckServer(opts = {}) {
|
|
|
1825
1900
|
const body = `Shared deck "${id}" \u2014 ${blocks.length} block${blocks.length === 1 ? "" : "s"}${types.length ? ` (${types.join(", ")})` : ""}. Open the Decks tab in the Communication Center to view.`;
|
|
1826
1901
|
const input = { title: id, body, html, sessionId: id, blockCount: blocks.length };
|
|
1827
1902
|
const existing2 = readSyncRecord(cwd, id);
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1903
|
+
const doShare = async () => {
|
|
1904
|
+
if (existing2?.resourceId) {
|
|
1905
|
+
try {
|
|
1906
|
+
const { id: rid2 } = await updateDeck(existing2.resourceId, input);
|
|
1907
|
+
return { resourceId: rid2, updated: true };
|
|
1908
|
+
} catch {
|
|
1909
|
+
const { id: rid2 } = await writeDeck(input);
|
|
1910
|
+
return { resourceId: rid2, updated: false };
|
|
1911
|
+
}
|
|
1836
1912
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
}
|
|
1913
|
+
const { id: rid } = await writeDeck(input);
|
|
1914
|
+
return { resourceId: rid, updated: false };
|
|
1915
|
+
};
|
|
1916
|
+
const { resourceId, updated } = override ? await withMcpConfig(override, doShare) : await doShare();
|
|
1840
1917
|
writeSyncRecord(cwd, id, {
|
|
1841
1918
|
resourceId,
|
|
1842
1919
|
sharedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1843
|
-
version: persisted.version
|
|
1920
|
+
version: persisted.version,
|
|
1921
|
+
course
|
|
1844
1922
|
});
|
|
1845
|
-
jsonResponse(res, 200, { ok: true, resourceId, updated });
|
|
1923
|
+
jsonResponse(res, 200, { ok: true, resourceId, updated, course });
|
|
1846
1924
|
} catch (err) {
|
|
1847
1925
|
jsonResponse(res, 500, { ok: false, error: String(err) });
|
|
1848
1926
|
}
|
|
@@ -1865,7 +1943,7 @@ async function startDeckServer(opts = {}) {
|
|
|
1865
1943
|
try {
|
|
1866
1944
|
await deleteDeck(sync.resourceId);
|
|
1867
1945
|
try {
|
|
1868
|
-
|
|
1946
|
+
import_node_fs5.default.rmSync(syncJsonPath(cwd, id), { force: true });
|
|
1869
1947
|
} catch {
|
|
1870
1948
|
}
|
|
1871
1949
|
jsonResponse(res, 200, { ok: true, deleted: true });
|
|
@@ -1976,7 +2054,7 @@ async function startDeckServer(opts = {}) {
|
|
|
1976
2054
|
res.end("Forbidden");
|
|
1977
2055
|
return;
|
|
1978
2056
|
}
|
|
1979
|
-
const filePath =
|
|
2057
|
+
const filePath = import_node_path5.default.join(cwd, LAUNCHSECURE_DIR, "deck-files", relative);
|
|
1980
2058
|
if (serveStatic(res, filePath)) return;
|
|
1981
2059
|
res.writeHead(404);
|
|
1982
2060
|
res.end("Not found");
|
|
@@ -1989,25 +2067,25 @@ async function startDeckServer(opts = {}) {
|
|
|
1989
2067
|
res.end("Forbidden");
|
|
1990
2068
|
return;
|
|
1991
2069
|
}
|
|
1992
|
-
const filePath =
|
|
1993
|
-
if (!
|
|
2070
|
+
const filePath = import_node_path5.default.join(cwd, LAUNCHSECURE_DIR, "deck-files", relative);
|
|
2071
|
+
if (!import_node_fs5.default.existsSync(filePath) || !import_node_fs5.default.statSync(filePath).isFile()) {
|
|
1994
2072
|
res.writeHead(404);
|
|
1995
2073
|
res.end("Not found");
|
|
1996
2074
|
return;
|
|
1997
2075
|
}
|
|
1998
|
-
const ext =
|
|
2076
|
+
const ext = import_node_path5.default.extname(filePath).toLowerCase();
|
|
1999
2077
|
const mime = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
2000
|
-
const filename =
|
|
2078
|
+
const filename = import_node_path5.default.basename(filePath);
|
|
2001
2079
|
res.writeHead(200, {
|
|
2002
2080
|
"Content-Type": mime,
|
|
2003
2081
|
"Content-Disposition": `attachment; filename="${filename}"`,
|
|
2004
2082
|
"Cache-Control": "no-cache"
|
|
2005
2083
|
});
|
|
2006
|
-
|
|
2084
|
+
import_node_fs5.default.createReadStream(filePath).pipe(res);
|
|
2007
2085
|
return;
|
|
2008
2086
|
}
|
|
2009
2087
|
if (url2.pathname !== "/") {
|
|
2010
|
-
const staticPath =
|
|
2088
|
+
const staticPath = import_node_path5.default.join(clientDir, url2.pathname);
|
|
2011
2089
|
if (serveStatic(res, staticPath)) return;
|
|
2012
2090
|
}
|
|
2013
2091
|
serveIndex(res, clientDir);
|
|
@@ -2106,13 +2184,13 @@ function runServeCli(argv) {
|
|
|
2106
2184
|
process.exit(1);
|
|
2107
2185
|
});
|
|
2108
2186
|
}
|
|
2109
|
-
var import_node_http,
|
|
2187
|
+
var import_node_http, import_node_fs5, import_node_path5, import_ws, DEFAULT_PORT, MAX_PORT_SCAN, MIME_TYPES, pendingFeedback, lastRenderError, wss;
|
|
2110
2188
|
var init_deck_serve = __esm({
|
|
2111
2189
|
"src/server/deck-serve.ts"() {
|
|
2112
2190
|
"use strict";
|
|
2113
2191
|
import_node_http = __toESM(require("node:http"));
|
|
2114
|
-
|
|
2115
|
-
|
|
2192
|
+
import_node_fs5 = __toESM(require("node:fs"));
|
|
2193
|
+
import_node_path5 = __toESM(require("node:path"));
|
|
2116
2194
|
import_ws = require("ws");
|
|
2117
2195
|
init_launch_kit_paths();
|
|
2118
2196
|
init_deck_lockfile();
|
|
@@ -2206,15 +2284,15 @@ async function handleTool(name, args) {
|
|
|
2206
2284
|
const baseUrl = `/deck-files/${sessionEncoded}`;
|
|
2207
2285
|
const html = generateBlastRadiusHtml(block.manifest, baseUrl);
|
|
2208
2286
|
const report = generateBlastRadiusReport(block.manifest);
|
|
2209
|
-
const dir = (0,
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2287
|
+
const dir = (0, import_node_path6.join)(projectRoot, LAUNCHSECURE_DIR, "deck-files", session);
|
|
2288
|
+
import_node_fs6.default.mkdirSync(dir, { recursive: true });
|
|
2289
|
+
import_node_fs6.default.writeFileSync((0, import_node_path6.join)(dir, "blast-radius.html"), html);
|
|
2290
|
+
import_node_fs6.default.writeFileSync((0, import_node_path6.join)(dir, "blast-radius-report.md"), report);
|
|
2291
|
+
import_node_fs6.default.writeFileSync((0, import_node_path6.join)(dir, "blast-radius-manifest.json"), JSON.stringify(block.manifest, null, 2));
|
|
2214
2292
|
const contractData = generateContract(block.manifest);
|
|
2215
2293
|
const contractMd = contractToMarkdown(contractData);
|
|
2216
|
-
|
|
2217
|
-
|
|
2294
|
+
import_node_fs6.default.writeFileSync((0, import_node_path6.join)(dir, "contract.json"), JSON.stringify(contractData, null, 2));
|
|
2295
|
+
import_node_fs6.default.writeFileSync((0, import_node_path6.join)(dir, "contract.md"), contractMd);
|
|
2218
2296
|
block.type = "iframe";
|
|
2219
2297
|
block.src = `${baseUrl}/blast-radius.html`;
|
|
2220
2298
|
delete block.manifest;
|
|
@@ -2241,9 +2319,9 @@ async function handleTool(name, args) {
|
|
|
2241
2319
|
const sessionEncoded = encodeURIComponent(session);
|
|
2242
2320
|
const baseUrl = `/deck-files/${sessionEncoded}`;
|
|
2243
2321
|
const filename = `${slugify(block.label)}.html`;
|
|
2244
|
-
const dir = (0,
|
|
2245
|
-
|
|
2246
|
-
|
|
2322
|
+
const dir = (0, import_node_path6.join)(projectRoot, LAUNCHSECURE_DIR, "deck-files", session);
|
|
2323
|
+
import_node_fs6.default.mkdirSync(dir, { recursive: true });
|
|
2324
|
+
import_node_fs6.default.writeFileSync((0, import_node_path6.join)(dir, filename), html);
|
|
2247
2325
|
block.type = "iframe";
|
|
2248
2326
|
block.src = `${baseUrl}/${filename}`;
|
|
2249
2327
|
delete block.content;
|
|
@@ -2337,11 +2415,11 @@ async function handleTool(name, args) {
|
|
|
2337
2415
|
}));
|
|
2338
2416
|
}
|
|
2339
2417
|
try {
|
|
2340
|
-
const logDir = (0,
|
|
2341
|
-
(0,
|
|
2342
|
-
const logPath = (0,
|
|
2343
|
-
const out = (0,
|
|
2344
|
-
const err = (0,
|
|
2418
|
+
const logDir = (0, import_node_path6.join)((0, import_node_os3.homedir)(), LAUNCHSECURE_DIR);
|
|
2419
|
+
(0, import_node_fs7.mkdirSync)(logDir, { recursive: true });
|
|
2420
|
+
const logPath = (0, import_node_path6.join)(logDir, "launch-deck.log");
|
|
2421
|
+
const out = (0, import_node_fs7.openSync)(logPath, "a");
|
|
2422
|
+
const err = (0, import_node_fs7.openSync)(logPath, "a");
|
|
2345
2423
|
const entryPath = process.argv[1];
|
|
2346
2424
|
const config = loadDeckConfig(projectRoot);
|
|
2347
2425
|
const resolvedPort = args.port ?? config.port;
|
|
@@ -2397,21 +2475,21 @@ async function handleTool(name, args) {
|
|
|
2397
2475
|
}
|
|
2398
2476
|
case "generate_contract": {
|
|
2399
2477
|
const session = args.session;
|
|
2400
|
-
const dir = (0,
|
|
2401
|
-
const manifestPath = (0,
|
|
2402
|
-
if (!
|
|
2478
|
+
const dir = (0, import_node_path6.join)(projectRoot, LAUNCHSECURE_DIR, "deck-files", session);
|
|
2479
|
+
const manifestPath = (0, import_node_path6.join)(dir, "blast-radius-manifest.json");
|
|
2480
|
+
if (!import_node_fs6.default.existsSync(manifestPath)) {
|
|
2403
2481
|
return text(JSON.stringify({
|
|
2404
2482
|
error: `No blast radius manifest found for session "${session}". Push a blast-radius block first.`,
|
|
2405
2483
|
hint: "Use the deck tool with a blast-radius block type to create a session."
|
|
2406
2484
|
}));
|
|
2407
2485
|
}
|
|
2408
2486
|
try {
|
|
2409
|
-
const raw =
|
|
2487
|
+
const raw = import_node_fs6.default.readFileSync(manifestPath, "utf-8");
|
|
2410
2488
|
const manifest = JSON.parse(raw);
|
|
2411
2489
|
const contract = generateContract(manifest);
|
|
2412
2490
|
const markdown = contractToMarkdown(contract);
|
|
2413
|
-
|
|
2414
|
-
|
|
2491
|
+
import_node_fs6.default.writeFileSync((0, import_node_path6.join)(dir, "contract.json"), JSON.stringify(contract, null, 2));
|
|
2492
|
+
import_node_fs6.default.writeFileSync((0, import_node_path6.join)(dir, "contract.md"), markdown);
|
|
2415
2493
|
return text(JSON.stringify(contract));
|
|
2416
2494
|
} catch (err) {
|
|
2417
2495
|
return text(JSON.stringify({ error: `Failed to generate contract: ${err}` }));
|
|
@@ -2502,16 +2580,16 @@ function startDeckMcpServer() {
|
|
|
2502
2580
|
process.exit(0);
|
|
2503
2581
|
});
|
|
2504
2582
|
}
|
|
2505
|
-
var import_node_http2,
|
|
2583
|
+
var import_node_http2, import_node_fs6, import_node_path6, import_node_child_process2, import_node_fs7, import_node_os3, SERVER_INFO, TOOLS;
|
|
2506
2584
|
var init_deck_mcp = __esm({
|
|
2507
2585
|
"src/server/deck-mcp.ts"() {
|
|
2508
2586
|
"use strict";
|
|
2509
2587
|
import_node_http2 = __toESM(require("node:http"));
|
|
2510
|
-
|
|
2511
|
-
|
|
2588
|
+
import_node_fs6 = __toESM(require("node:fs"));
|
|
2589
|
+
import_node_path6 = require("node:path");
|
|
2512
2590
|
import_node_child_process2 = require("node:child_process");
|
|
2513
|
-
|
|
2514
|
-
|
|
2591
|
+
import_node_fs7 = require("node:fs");
|
|
2592
|
+
import_node_os3 = require("node:os");
|
|
2515
2593
|
init_launch_kit_paths();
|
|
2516
2594
|
init_deck_lockfile();
|
|
2517
2595
|
init_deck_config();
|
|
@@ -2655,8 +2733,92 @@ var init_deck_mcp = __esm({
|
|
|
2655
2733
|
|
|
2656
2734
|
// src/server/deck-mcp-entry.ts
|
|
2657
2735
|
init_deck_lockfile();
|
|
2736
|
+
|
|
2737
|
+
// src/server/prune-npx-cache.ts
|
|
2738
|
+
var import_node_fs2 = require("node:fs");
|
|
2739
|
+
var import_node_os2 = require("node:os");
|
|
2740
|
+
var import_node_path2 = require("node:path");
|
|
2741
|
+
var import_node_util = require("node:util");
|
|
2742
|
+
var PKG = "@launchsecure/launch-kit";
|
|
2743
|
+
var readFileAsync = (0, import_node_util.promisify)(import_node_fs2.readFile);
|
|
2744
|
+
var readdirAsync = (0, import_node_util.promisify)(import_node_fs2.readdir);
|
|
2745
|
+
var rmAsync = (0, import_node_util.promisify)(import_node_fs2.rm);
|
|
2746
|
+
var realpathAsync = (0, import_node_util.promisify)(import_node_fs2.realpath);
|
|
2747
|
+
function npxCacheRoot() {
|
|
2748
|
+
const cache = process.env.npm_config_cache;
|
|
2749
|
+
if (cache && cache.trim()) return (0, import_node_path2.join)(cache, "_npx");
|
|
2750
|
+
if (process.platform === "win32") {
|
|
2751
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
2752
|
+
if (localAppData) return (0, import_node_path2.join)(localAppData, "npm-cache", "_npx");
|
|
2753
|
+
}
|
|
2754
|
+
return (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".npm", "_npx");
|
|
2755
|
+
}
|
|
2756
|
+
function ownVersion() {
|
|
2757
|
+
let dir = __dirname;
|
|
2758
|
+
for (let i = 0; i < 8; i++) {
|
|
2759
|
+
try {
|
|
2760
|
+
const pkg = JSON.parse((0, import_node_fs2.readFileSync)((0, import_node_path2.join)(dir, "package.json"), "utf8"));
|
|
2761
|
+
if (pkg && pkg.name === PKG) return typeof pkg.version === "string" ? pkg.version : null;
|
|
2762
|
+
} catch {
|
|
2763
|
+
}
|
|
2764
|
+
const parent = (0, import_node_path2.dirname)(dir);
|
|
2765
|
+
if (parent === dir) break;
|
|
2766
|
+
dir = parent;
|
|
2767
|
+
}
|
|
2768
|
+
return null;
|
|
2769
|
+
}
|
|
2770
|
+
async function pruneStaleNpxCache() {
|
|
2771
|
+
try {
|
|
2772
|
+
const version = ownVersion();
|
|
2773
|
+
if (!version) return;
|
|
2774
|
+
const root = npxCacheRoot();
|
|
2775
|
+
let hashes;
|
|
2776
|
+
try {
|
|
2777
|
+
hashes = await readdirAsync(root);
|
|
2778
|
+
} catch {
|
|
2779
|
+
return;
|
|
2780
|
+
}
|
|
2781
|
+
const selfPath = await realpathAsync(process.argv[1] || __dirname).catch(() => __dirname);
|
|
2782
|
+
let reaped = 0;
|
|
2783
|
+
for (const hash of hashes) {
|
|
2784
|
+
const dir = (0, import_node_path2.join)(root, hash);
|
|
2785
|
+
if (selfPath === dir || selfPath.startsWith(dir + import_node_path2.sep)) continue;
|
|
2786
|
+
let ver;
|
|
2787
|
+
try {
|
|
2788
|
+
const lkPkg = JSON.parse(
|
|
2789
|
+
await readFileAsync((0, import_node_path2.join)(dir, "node_modules", PKG, "package.json"), "utf8")
|
|
2790
|
+
);
|
|
2791
|
+
ver = lkPkg.version;
|
|
2792
|
+
} catch {
|
|
2793
|
+
continue;
|
|
2794
|
+
}
|
|
2795
|
+
if (ver === version) continue;
|
|
2796
|
+
try {
|
|
2797
|
+
const top = JSON.parse(await readFileAsync((0, import_node_path2.join)(dir, "package.json"), "utf8"));
|
|
2798
|
+
const spec = top?.dependencies?.[PKG];
|
|
2799
|
+
if (typeof spec === "string" && spec.startsWith("file:")) continue;
|
|
2800
|
+
} catch {
|
|
2801
|
+
}
|
|
2802
|
+
try {
|
|
2803
|
+
await rmAsync(dir, { recursive: true, force: true });
|
|
2804
|
+
reaped++;
|
|
2805
|
+
} catch {
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
if (reaped > 0) {
|
|
2809
|
+
process.stderr.write(
|
|
2810
|
+
`[launch-kit] npx-cache: reaped ${reaped} stale copy(ies), kept v${version}
|
|
2811
|
+
`
|
|
2812
|
+
);
|
|
2813
|
+
}
|
|
2814
|
+
} catch {
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
// src/server/deck-mcp-entry.ts
|
|
2658
2819
|
async function main() {
|
|
2659
2820
|
setProjectRoot(process.cwd());
|
|
2821
|
+
void pruneStaleNpxCache();
|
|
2660
2822
|
const argv = process.argv.slice(2);
|
|
2661
2823
|
const subcommand = argv[0];
|
|
2662
2824
|
if (subcommand === "serve") {
|