@launchsecure/launch-kit 0.0.27 → 0.0.29
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 +1003 -440
- package/dist/beacon/beacon.mjs.map +1 -1
- package/dist/beacon/beacon.umd.js +45 -24
- package/dist/beacon/beacon.umd.js.map +1 -1
- package/dist/beacon/types/capture/events.d.ts +20 -0
- package/dist/beacon/types/capture/events.d.ts.map +1 -0
- package/dist/beacon/types/element.d.ts +1 -0
- package/dist/beacon/types/element.d.ts.map +1 -1
- package/dist/beacon/types/index.d.ts +2 -1
- package/dist/beacon/types/index.d.ts.map +1 -1
- package/dist/beacon/types/monitor/dom.d.ts +13 -0
- package/dist/beacon/types/monitor/dom.d.ts.map +1 -0
- package/dist/beacon/types/monitor/index.d.ts +19 -0
- package/dist/beacon/types/monitor/index.d.ts.map +1 -0
- package/dist/beacon/types/monitor/network.d.ts +12 -0
- package/dist/beacon/types/monitor/network.d.ts.map +1 -0
- package/dist/beacon/types/monitor/transport.d.ts +27 -0
- package/dist/beacon/types/monitor/transport.d.ts.map +1 -0
- package/dist/beacon/types/monitor/types.d.ts +117 -0
- package/dist/beacon/types/monitor/types.d.ts.map +1 -0
- package/dist/beacon/types/types.d.ts +10 -0
- package/dist/beacon/types/types.d.ts.map +1 -1
- package/dist/beacon/types/ui/drawer.d.ts +3 -1
- package/dist/beacon/types/ui/drawer.d.ts.map +1 -1
- package/dist/beacon/types/ui/monitor-panel.d.ts +19 -0
- package/dist/beacon/types/ui/monitor-panel.d.ts.map +1 -0
- package/dist/server/beacon-monitor-entry.js +353 -0
- package/dist/server/chart-serve.js +3 -1
- package/dist/server/cli.js +276 -218
- package/dist/server/course-entry.js +246 -0
- package/dist/server/graph-mcp-entry.js +35 -72
- package/dist/server/init-entry.js +1051 -122
- package/dist/server/orbit-entry.js +187 -24
- package/package.json +5 -3
- package/scaffolds/ls-marketplace/.claude-plugin/marketplace.json +15 -0
- package/scaffolds/ls-marketplace/plugins/kit/.claude-plugin/plugin.json +19 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/activate-beacon.md +216 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/activate-statusline.md +46 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-array.md +92 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-clear.md +68 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-pulse.md +80 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-scan.md +62 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/deactivate-statusline.md +34 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/show-mcp-status.md +109 -0
- package/scaffolds/ls-marketplace/plugins/kit/commands/standup.md +191 -0
- package/scaffolds/recall-hook/scripts/ensure-recall.sh +69 -0
- package/scaffolds/statusline/statusline-mcp.sh +192 -0
- package/scaffolds/statusline/statusline-wrapper.sh +50 -0
package/dist/server/cli.js
CHANGED
|
@@ -553,8 +553,8 @@ var require_claude_bridge = __commonJS({
|
|
|
553
553
|
"../claude-code-web/src/claude-bridge.js"(exports2, module2) {
|
|
554
554
|
"use strict";
|
|
555
555
|
var { spawn: spawn4 } = require("node-pty");
|
|
556
|
-
var
|
|
557
|
-
var
|
|
556
|
+
var path13 = require("path");
|
|
557
|
+
var fs11 = require("fs");
|
|
558
558
|
var ClaudeBridge = class {
|
|
559
559
|
constructor() {
|
|
560
560
|
this.sessions = /* @__PURE__ */ new Map();
|
|
@@ -565,14 +565,14 @@ var require_claude_bridge = __commonJS({
|
|
|
565
565
|
"/home/ec2-user/.claude/local/claude",
|
|
566
566
|
"claude",
|
|
567
567
|
"claude-code",
|
|
568
|
-
|
|
569
|
-
|
|
568
|
+
path13.join(process.env.HOME || "/", ".claude", "local", "claude"),
|
|
569
|
+
path13.join(process.env.HOME || "/", ".local", "bin", "claude"),
|
|
570
570
|
"/usr/local/bin/claude",
|
|
571
571
|
"/usr/bin/claude"
|
|
572
572
|
];
|
|
573
573
|
for (const cmd of possibleCommands) {
|
|
574
574
|
try {
|
|
575
|
-
if (
|
|
575
|
+
if (fs11.existsSync(cmd) || this.commandExists(cmd)) {
|
|
576
576
|
console.log(`Found Claude command at: ${cmd}`);
|
|
577
577
|
return cmd;
|
|
578
578
|
}
|
|
@@ -797,8 +797,8 @@ var require_codex_bridge = __commonJS({
|
|
|
797
797
|
"../claude-code-web/src/codex-bridge.js"(exports2, module2) {
|
|
798
798
|
"use strict";
|
|
799
799
|
var { spawn: spawn4 } = require("node-pty");
|
|
800
|
-
var
|
|
801
|
-
var
|
|
800
|
+
var path13 = require("path");
|
|
801
|
+
var fs11 = require("fs");
|
|
802
802
|
var CodexBridge = class {
|
|
803
803
|
constructor() {
|
|
804
804
|
this.sessions = /* @__PURE__ */ new Map();
|
|
@@ -806,16 +806,16 @@ var require_codex_bridge = __commonJS({
|
|
|
806
806
|
}
|
|
807
807
|
findCodexCommand() {
|
|
808
808
|
const possibleCommands = [
|
|
809
|
-
|
|
809
|
+
path13.join(process.env.HOME || "/", ".codex", "local", "codex"),
|
|
810
810
|
"codex",
|
|
811
811
|
"codex-code",
|
|
812
|
-
|
|
812
|
+
path13.join(process.env.HOME || "/", ".local", "bin", "codex"),
|
|
813
813
|
"/usr/local/bin/codex",
|
|
814
814
|
"/usr/bin/codex"
|
|
815
815
|
];
|
|
816
816
|
for (const cmd of possibleCommands) {
|
|
817
817
|
try {
|
|
818
|
-
if (
|
|
818
|
+
if (fs11.existsSync(cmd) || this.commandExists(cmd)) {
|
|
819
819
|
console.log(`Found Codex command at: ${cmd}`);
|
|
820
820
|
return cmd;
|
|
821
821
|
}
|
|
@@ -990,8 +990,8 @@ var require_agent_bridge = __commonJS({
|
|
|
990
990
|
"../claude-code-web/src/agent-bridge.js"(exports2, module2) {
|
|
991
991
|
"use strict";
|
|
992
992
|
var { spawn: spawn4 } = require("node-pty");
|
|
993
|
-
var
|
|
994
|
-
var
|
|
993
|
+
var path13 = require("path");
|
|
994
|
+
var fs11 = require("fs");
|
|
995
995
|
var AgentBridge = class {
|
|
996
996
|
constructor() {
|
|
997
997
|
this.sessions = /* @__PURE__ */ new Map();
|
|
@@ -999,15 +999,15 @@ var require_agent_bridge = __commonJS({
|
|
|
999
999
|
}
|
|
1000
1000
|
findAgentCommand() {
|
|
1001
1001
|
const possibleCommands = [
|
|
1002
|
-
|
|
1002
|
+
path13.join(process.env.HOME || "/", ".cursor", "local", "cursor-agent"),
|
|
1003
1003
|
"cursor-agent",
|
|
1004
|
-
|
|
1004
|
+
path13.join(process.env.HOME || "/", ".local", "bin", "cursor-agent"),
|
|
1005
1005
|
"/usr/local/bin/cursor-agent",
|
|
1006
1006
|
"/usr/bin/cursor-agent"
|
|
1007
1007
|
];
|
|
1008
1008
|
for (const cmd of possibleCommands) {
|
|
1009
1009
|
try {
|
|
1010
|
-
if (
|
|
1010
|
+
if (fs11.existsSync(cmd) || this.commandExists(cmd)) {
|
|
1011
1011
|
console.log(`Found Agent command at: ${cmd}`);
|
|
1012
1012
|
return cmd;
|
|
1013
1013
|
}
|
|
@@ -1331,25 +1331,25 @@ var require_script_bridge = __commonJS({
|
|
|
1331
1331
|
var require_session_store = __commonJS({
|
|
1332
1332
|
"../claude-code-web/src/utils/session-store.js"(exports2, module2) {
|
|
1333
1333
|
"use strict";
|
|
1334
|
-
var
|
|
1335
|
-
var
|
|
1334
|
+
var fs11 = require("fs").promises;
|
|
1335
|
+
var path13 = require("path");
|
|
1336
1336
|
var os4 = require("os");
|
|
1337
1337
|
var SessionStore = class {
|
|
1338
1338
|
constructor(options = {}) {
|
|
1339
|
-
this.storageDir = options.storageDir ||
|
|
1340
|
-
this.sessionsFile =
|
|
1339
|
+
this.storageDir = options.storageDir || path13.join(os4.homedir(), ".claude-code-web");
|
|
1340
|
+
this.sessionsFile = path13.join(this.storageDir, "sessions.json");
|
|
1341
1341
|
this.initializeStorage();
|
|
1342
1342
|
}
|
|
1343
1343
|
async initializeStorage() {
|
|
1344
1344
|
try {
|
|
1345
|
-
await
|
|
1345
|
+
await fs11.mkdir(this.storageDir, { recursive: true });
|
|
1346
1346
|
} catch (error) {
|
|
1347
1347
|
console.error("Failed to create storage directory:", error);
|
|
1348
1348
|
}
|
|
1349
1349
|
}
|
|
1350
1350
|
async saveSessions(sessions) {
|
|
1351
1351
|
try {
|
|
1352
|
-
await
|
|
1352
|
+
await fs11.mkdir(this.storageDir, { recursive: true });
|
|
1353
1353
|
const sessionsArray = Array.from(sessions.entries()).map(([id, session]) => ({
|
|
1354
1354
|
id,
|
|
1355
1355
|
name: session.name || "Unnamed Session",
|
|
@@ -1380,9 +1380,9 @@ var require_session_store = __commonJS({
|
|
|
1380
1380
|
sessions: sessionsArray
|
|
1381
1381
|
};
|
|
1382
1382
|
const tempFile = `${this.sessionsFile}.tmp`;
|
|
1383
|
-
await
|
|
1384
|
-
await
|
|
1385
|
-
await
|
|
1383
|
+
await fs11.writeFile(tempFile, JSON.stringify(data, null, 2));
|
|
1384
|
+
await fs11.mkdir(this.storageDir, { recursive: true });
|
|
1385
|
+
await fs11.rename(tempFile, this.sessionsFile);
|
|
1386
1386
|
return true;
|
|
1387
1387
|
} catch (error) {
|
|
1388
1388
|
console.error("Failed to save sessions:", error.message);
|
|
@@ -1391,8 +1391,8 @@ var require_session_store = __commonJS({
|
|
|
1391
1391
|
}
|
|
1392
1392
|
async loadSessions() {
|
|
1393
1393
|
try {
|
|
1394
|
-
await
|
|
1395
|
-
const data = await
|
|
1394
|
+
await fs11.access(this.sessionsFile);
|
|
1395
|
+
const data = await fs11.readFile(this.sessionsFile, "utf8");
|
|
1396
1396
|
if (!data || !data.trim()) {
|
|
1397
1397
|
console.log("Sessions file is empty, starting fresh");
|
|
1398
1398
|
return /* @__PURE__ */ new Map();
|
|
@@ -1403,7 +1403,7 @@ var require_session_store = __commonJS({
|
|
|
1403
1403
|
} catch (parseError) {
|
|
1404
1404
|
console.error("Sessions file is corrupted, starting fresh:", parseError.message);
|
|
1405
1405
|
try {
|
|
1406
|
-
await
|
|
1406
|
+
await fs11.rename(this.sessionsFile, `${this.sessionsFile}.corrupted.${Date.now()}`);
|
|
1407
1407
|
} catch (renameError) {
|
|
1408
1408
|
}
|
|
1409
1409
|
return /* @__PURE__ */ new Map();
|
|
@@ -1447,7 +1447,7 @@ var require_session_store = __commonJS({
|
|
|
1447
1447
|
}
|
|
1448
1448
|
async clearOldSessions() {
|
|
1449
1449
|
try {
|
|
1450
|
-
await
|
|
1450
|
+
await fs11.unlink(this.sessionsFile);
|
|
1451
1451
|
console.log("Cleared old sessions");
|
|
1452
1452
|
return true;
|
|
1453
1453
|
} catch (error) {
|
|
@@ -1459,9 +1459,9 @@ var require_session_store = __commonJS({
|
|
|
1459
1459
|
}
|
|
1460
1460
|
async getSessionMetadata() {
|
|
1461
1461
|
try {
|
|
1462
|
-
await
|
|
1463
|
-
const stats = await
|
|
1464
|
-
const data = await
|
|
1462
|
+
await fs11.access(this.sessionsFile);
|
|
1463
|
+
const stats = await fs11.stat(this.sessionsFile);
|
|
1464
|
+
const data = await fs11.readFile(this.sessionsFile, "utf8");
|
|
1465
1465
|
const parsed = JSON.parse(data);
|
|
1466
1466
|
return {
|
|
1467
1467
|
exists: true,
|
|
@@ -1486,13 +1486,13 @@ var require_session_store = __commonJS({
|
|
|
1486
1486
|
var require_usage_reader = __commonJS({
|
|
1487
1487
|
"../claude-code-web/src/usage-reader.js"(exports2, module2) {
|
|
1488
1488
|
"use strict";
|
|
1489
|
-
var
|
|
1490
|
-
var
|
|
1489
|
+
var fs11 = require("fs").promises;
|
|
1490
|
+
var path13 = require("path");
|
|
1491
1491
|
var readline = require("readline");
|
|
1492
1492
|
var { createReadStream } = require("fs");
|
|
1493
1493
|
var UsageReader = class {
|
|
1494
1494
|
constructor(sessionDurationHours = 5) {
|
|
1495
|
-
this.claudeProjectsPath =
|
|
1495
|
+
this.claudeProjectsPath = path13.join(process.env.HOME, ".claude", "projects");
|
|
1496
1496
|
this.cache = null;
|
|
1497
1497
|
this.cacheTime = null;
|
|
1498
1498
|
this.cacheTimeout = 5e3;
|
|
@@ -1692,14 +1692,14 @@ var require_usage_reader = __commonJS({
|
|
|
1692
1692
|
try {
|
|
1693
1693
|
const cwd = process.cwd();
|
|
1694
1694
|
const projectDirName = cwd.replace(/\//g, "-");
|
|
1695
|
-
let projectPath =
|
|
1695
|
+
let projectPath = path13.join(this.claudeProjectsPath, projectDirName);
|
|
1696
1696
|
try {
|
|
1697
|
-
await
|
|
1697
|
+
await fs11.access(projectPath);
|
|
1698
1698
|
} catch (err2) {
|
|
1699
1699
|
console.log(`Project directory not found: ${projectPath}`);
|
|
1700
1700
|
return null;
|
|
1701
1701
|
}
|
|
1702
|
-
const files = await
|
|
1702
|
+
const files = await fs11.readdir(projectPath);
|
|
1703
1703
|
const jsonlFiles = files.filter((f) => f.endsWith(".jsonl"));
|
|
1704
1704
|
if (jsonlFiles.length === 0) {
|
|
1705
1705
|
return null;
|
|
@@ -1707,8 +1707,8 @@ var require_usage_reader = __commonJS({
|
|
|
1707
1707
|
let mostRecentFile = null;
|
|
1708
1708
|
let mostRecentTime = 0;
|
|
1709
1709
|
for (const file of jsonlFiles) {
|
|
1710
|
-
const filePath =
|
|
1711
|
-
const stat = await
|
|
1710
|
+
const filePath = path13.join(projectPath, file);
|
|
1711
|
+
const stat = await fs11.stat(filePath);
|
|
1712
1712
|
if (stat.mtime.getTime() > mostRecentTime) {
|
|
1713
1713
|
mostRecentTime = stat.mtime.getTime();
|
|
1714
1714
|
mostRecentFile = filePath;
|
|
@@ -1723,17 +1723,17 @@ var require_usage_reader = __commonJS({
|
|
|
1723
1723
|
async findJsonlFiles(onlyRecent = false) {
|
|
1724
1724
|
const files = [];
|
|
1725
1725
|
try {
|
|
1726
|
-
const projectDirs = await
|
|
1726
|
+
const projectDirs = await fs11.readdir(this.claudeProjectsPath);
|
|
1727
1727
|
for (const projectDir of projectDirs) {
|
|
1728
|
-
const projectPath =
|
|
1729
|
-
const stat = await
|
|
1728
|
+
const projectPath = path13.join(this.claudeProjectsPath, projectDir);
|
|
1729
|
+
const stat = await fs11.stat(projectPath);
|
|
1730
1730
|
if (stat.isDirectory()) {
|
|
1731
|
-
const projectFiles = await
|
|
1731
|
+
const projectFiles = await fs11.readdir(projectPath);
|
|
1732
1732
|
const jsonlFiles = projectFiles.filter((f) => f.endsWith(".jsonl"));
|
|
1733
1733
|
for (const jsonlFile of jsonlFiles) {
|
|
1734
|
-
const filePath =
|
|
1734
|
+
const filePath = path13.join(projectPath, jsonlFile);
|
|
1735
1735
|
if (onlyRecent) {
|
|
1736
|
-
const fileStat = await
|
|
1736
|
+
const fileStat = await fs11.stat(filePath);
|
|
1737
1737
|
const hoursSinceModified = (Date.now() - fileStat.mtime.getTime()) / (1e3 * 60 * 60);
|
|
1738
1738
|
if (hoursSinceModified <= 24) {
|
|
1739
1739
|
files.push(filePath);
|
|
@@ -1894,9 +1894,9 @@ var require_usage_reader = __commonJS({
|
|
|
1894
1894
|
if (!sessionId) {
|
|
1895
1895
|
return null;
|
|
1896
1896
|
}
|
|
1897
|
-
const sessionFile =
|
|
1897
|
+
const sessionFile = path13.join(this.claudeProjectsPath, path13.basename(process.cwd()).replace(/[^a-zA-Z0-9-]/g, "-"), `${sessionId}.jsonl`);
|
|
1898
1898
|
try {
|
|
1899
|
-
await
|
|
1899
|
+
await fs11.access(sessionFile);
|
|
1900
1900
|
} catch (err2) {
|
|
1901
1901
|
return null;
|
|
1902
1902
|
}
|
|
@@ -2552,7 +2552,7 @@ var require_usage_analytics = __commonJS({
|
|
|
2552
2552
|
var require_src = __commonJS({
|
|
2553
2553
|
"../claude-code-web/src/index.js"(exports2, module2) {
|
|
2554
2554
|
"use strict";
|
|
2555
|
-
var
|
|
2555
|
+
var path13 = require("path");
|
|
2556
2556
|
var WebSocket2 = require("ws");
|
|
2557
2557
|
var { v4: uuidv4 } = (init_esm_node(), __toCommonJS(esm_node_exports));
|
|
2558
2558
|
var ClaudeBridge = require_claude_bridge();
|
|
@@ -2562,7 +2562,7 @@ var require_src = __commonJS({
|
|
|
2562
2562
|
var SessionStore = require_session_store();
|
|
2563
2563
|
var UsageReader = require_usage_reader();
|
|
2564
2564
|
var UsageAnalytics = require_usage_analytics();
|
|
2565
|
-
var
|
|
2565
|
+
var fs11 = require("fs");
|
|
2566
2566
|
function stripAnsi2(str) {
|
|
2567
2567
|
return str.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").replace(/\x1b\][^\x07]*\x07/g, "").replace(/\x1b[()][AB012]/g, "").replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "").replace(/\r\n?/g, "\n").trim();
|
|
2568
2568
|
}
|
|
@@ -2637,8 +2637,8 @@ var require_src = __commonJS({
|
|
|
2637
2637
|
// ── Path validation ──────────────────────────────────────────────────
|
|
2638
2638
|
isPathWithinBase(targetPath) {
|
|
2639
2639
|
try {
|
|
2640
|
-
const resolvedTarget =
|
|
2641
|
-
const resolvedBase =
|
|
2640
|
+
const resolvedTarget = path13.resolve(targetPath);
|
|
2641
|
+
const resolvedBase = path13.resolve(this.baseFolder);
|
|
2642
2642
|
return resolvedTarget.startsWith(resolvedBase);
|
|
2643
2643
|
} catch (error) {
|
|
2644
2644
|
return false;
|
|
@@ -2648,7 +2648,7 @@ var require_src = __commonJS({
|
|
|
2648
2648
|
if (!targetPath) {
|
|
2649
2649
|
return { valid: false, error: "Path is required" };
|
|
2650
2650
|
}
|
|
2651
|
-
const resolvedPath =
|
|
2651
|
+
const resolvedPath = path13.resolve(targetPath);
|
|
2652
2652
|
if (!this.isPathWithinBase(resolvedPath)) {
|
|
2653
2653
|
return {
|
|
2654
2654
|
valid: false,
|
|
@@ -2820,14 +2820,14 @@ var require_src = __commonJS({
|
|
|
2820
2820
|
return true;
|
|
2821
2821
|
}
|
|
2822
2822
|
try {
|
|
2823
|
-
const items =
|
|
2823
|
+
const items = fs11.readdirSync(validation.path, { withFileTypes: true });
|
|
2824
2824
|
const showHidden = url.searchParams.get("showHidden") === "true";
|
|
2825
2825
|
const folders = items.filter((item) => item.isDirectory()).filter((item) => !item.name.startsWith(".") || showHidden).map((item) => ({
|
|
2826
2826
|
name: item.name,
|
|
2827
|
-
path:
|
|
2827
|
+
path: path13.join(validation.path, item.name),
|
|
2828
2828
|
isDirectory: true
|
|
2829
2829
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
2830
|
-
const parentDir =
|
|
2830
|
+
const parentDir = path13.dirname(validation.path);
|
|
2831
2831
|
const canGoUp = this.isPathWithinBase(parentDir) && parentDir !== validation.path;
|
|
2832
2832
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2833
2833
|
res.end(JSON.stringify({
|
|
@@ -2855,7 +2855,7 @@ var require_src = __commonJS({
|
|
|
2855
2855
|
res.end(JSON.stringify({ error: validation.error }));
|
|
2856
2856
|
return;
|
|
2857
2857
|
}
|
|
2858
|
-
if (!
|
|
2858
|
+
if (!fs11.existsSync(validation.path) || !fs11.statSync(validation.path).isDirectory()) {
|
|
2859
2859
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2860
2860
|
res.end(JSON.stringify({ error: "Not a valid directory" }));
|
|
2861
2861
|
return;
|
|
@@ -2882,7 +2882,7 @@ var require_src = __commonJS({
|
|
|
2882
2882
|
res.end(JSON.stringify({ error: validation.error }));
|
|
2883
2883
|
return;
|
|
2884
2884
|
}
|
|
2885
|
-
if (!
|
|
2885
|
+
if (!fs11.existsSync(validation.path) || !fs11.statSync(validation.path).isDirectory()) {
|
|
2886
2886
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2887
2887
|
res.end(JSON.stringify({ error: "Invalid directory path" }));
|
|
2888
2888
|
return;
|
|
@@ -2909,7 +2909,7 @@ var require_src = __commonJS({
|
|
|
2909
2909
|
return;
|
|
2910
2910
|
}
|
|
2911
2911
|
const basePath = parentPath || this.baseFolder;
|
|
2912
|
-
const fullPath =
|
|
2912
|
+
const fullPath = path13.join(basePath, folderName);
|
|
2913
2913
|
const parentValidation = this.validatePath(basePath);
|
|
2914
2914
|
const fullValidation = this.validatePath(fullPath);
|
|
2915
2915
|
if (!parentValidation.valid || !fullValidation.valid) {
|
|
@@ -2917,12 +2917,12 @@ var require_src = __commonJS({
|
|
|
2917
2917
|
res.end(JSON.stringify({ message: "Cannot create folder outside the allowed area" }));
|
|
2918
2918
|
return;
|
|
2919
2919
|
}
|
|
2920
|
-
if (
|
|
2920
|
+
if (fs11.existsSync(fullValidation.path)) {
|
|
2921
2921
|
res.writeHead(409, { "Content-Type": "application/json" });
|
|
2922
2922
|
res.end(JSON.stringify({ message: "Folder already exists" }));
|
|
2923
2923
|
return;
|
|
2924
2924
|
}
|
|
2925
|
-
|
|
2925
|
+
fs11.mkdirSync(fullValidation.path, { recursive: true });
|
|
2926
2926
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2927
2927
|
res.end(JSON.stringify({ success: true, path: fullValidation.path }));
|
|
2928
2928
|
} catch (e) {
|
|
@@ -2946,10 +2946,10 @@ var require_src = __commonJS({
|
|
|
2946
2946
|
const url = new URL(req.url || "/", `http://localhost`);
|
|
2947
2947
|
let filePath = url.pathname.replace(/^\/terminal\/?/, "");
|
|
2948
2948
|
if (!filePath || filePath === "") filePath = "index.html";
|
|
2949
|
-
const fullPath =
|
|
2949
|
+
const fullPath = path13.join(__dirname, "public", filePath);
|
|
2950
2950
|
try {
|
|
2951
|
-
if (!
|
|
2952
|
-
const ext =
|
|
2951
|
+
if (!fs11.existsSync(fullPath)) return false;
|
|
2952
|
+
const ext = path13.extname(fullPath);
|
|
2953
2953
|
const mimeTypes = {
|
|
2954
2954
|
".html": "text/html",
|
|
2955
2955
|
".js": "application/javascript",
|
|
@@ -2960,7 +2960,7 @@ var require_src = __commonJS({
|
|
|
2960
2960
|
".ico": "image/x-icon"
|
|
2961
2961
|
};
|
|
2962
2962
|
const mime = mimeTypes[ext] || "application/octet-stream";
|
|
2963
|
-
const content =
|
|
2963
|
+
const content = fs11.readFileSync(fullPath);
|
|
2964
2964
|
res.writeHead(200, { "Content-Type": mime });
|
|
2965
2965
|
res.end(content);
|
|
2966
2966
|
return true;
|
|
@@ -4553,14 +4553,14 @@ var require_util = __commonJS({
|
|
|
4553
4553
|
}
|
|
4554
4554
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
4555
4555
|
let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
|
|
4556
|
-
let
|
|
4556
|
+
let path13 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
4557
4557
|
if (origin[origin.length - 1] === "/") {
|
|
4558
4558
|
origin = origin.slice(0, origin.length - 1);
|
|
4559
4559
|
}
|
|
4560
|
-
if (
|
|
4561
|
-
|
|
4560
|
+
if (path13 && path13[0] !== "/") {
|
|
4561
|
+
path13 = `/${path13}`;
|
|
4562
4562
|
}
|
|
4563
|
-
return new URL(`${origin}${
|
|
4563
|
+
return new URL(`${origin}${path13}`);
|
|
4564
4564
|
}
|
|
4565
4565
|
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
4566
4566
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -5011,39 +5011,39 @@ var require_diagnostics = __commonJS({
|
|
|
5011
5011
|
});
|
|
5012
5012
|
diagnosticsChannel.channel("undici:client:sendHeaders").subscribe((evt) => {
|
|
5013
5013
|
const {
|
|
5014
|
-
request: { method, path:
|
|
5014
|
+
request: { method, path: path13, origin }
|
|
5015
5015
|
} = evt;
|
|
5016
|
-
debuglog("sending request to %s %s/%s", method, origin,
|
|
5016
|
+
debuglog("sending request to %s %s/%s", method, origin, path13);
|
|
5017
5017
|
});
|
|
5018
5018
|
diagnosticsChannel.channel("undici:request:headers").subscribe((evt) => {
|
|
5019
5019
|
const {
|
|
5020
|
-
request: { method, path:
|
|
5020
|
+
request: { method, path: path13, origin },
|
|
5021
5021
|
response: { statusCode }
|
|
5022
5022
|
} = evt;
|
|
5023
5023
|
debuglog(
|
|
5024
5024
|
"received response to %s %s/%s - HTTP %d",
|
|
5025
5025
|
method,
|
|
5026
5026
|
origin,
|
|
5027
|
-
|
|
5027
|
+
path13,
|
|
5028
5028
|
statusCode
|
|
5029
5029
|
);
|
|
5030
5030
|
});
|
|
5031
5031
|
diagnosticsChannel.channel("undici:request:trailers").subscribe((evt) => {
|
|
5032
5032
|
const {
|
|
5033
|
-
request: { method, path:
|
|
5033
|
+
request: { method, path: path13, origin }
|
|
5034
5034
|
} = evt;
|
|
5035
|
-
debuglog("trailers received from %s %s/%s", method, origin,
|
|
5035
|
+
debuglog("trailers received from %s %s/%s", method, origin, path13);
|
|
5036
5036
|
});
|
|
5037
5037
|
diagnosticsChannel.channel("undici:request:error").subscribe((evt) => {
|
|
5038
5038
|
const {
|
|
5039
|
-
request: { method, path:
|
|
5039
|
+
request: { method, path: path13, origin },
|
|
5040
5040
|
error
|
|
5041
5041
|
} = evt;
|
|
5042
5042
|
debuglog(
|
|
5043
5043
|
"request to %s %s/%s errored - %s",
|
|
5044
5044
|
method,
|
|
5045
5045
|
origin,
|
|
5046
|
-
|
|
5046
|
+
path13,
|
|
5047
5047
|
error.message
|
|
5048
5048
|
);
|
|
5049
5049
|
});
|
|
@@ -5092,9 +5092,9 @@ var require_diagnostics = __commonJS({
|
|
|
5092
5092
|
});
|
|
5093
5093
|
diagnosticsChannel.channel("undici:client:sendHeaders").subscribe((evt) => {
|
|
5094
5094
|
const {
|
|
5095
|
-
request: { method, path:
|
|
5095
|
+
request: { method, path: path13, origin }
|
|
5096
5096
|
} = evt;
|
|
5097
|
-
debuglog("sending request to %s %s/%s", method, origin,
|
|
5097
|
+
debuglog("sending request to %s %s/%s", method, origin, path13);
|
|
5098
5098
|
});
|
|
5099
5099
|
}
|
|
5100
5100
|
diagnosticsChannel.channel("undici:websocket:open").subscribe((evt) => {
|
|
@@ -5157,7 +5157,7 @@ var require_request = __commonJS({
|
|
|
5157
5157
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
5158
5158
|
var Request = class {
|
|
5159
5159
|
constructor(origin, {
|
|
5160
|
-
path:
|
|
5160
|
+
path: path13,
|
|
5161
5161
|
method,
|
|
5162
5162
|
body,
|
|
5163
5163
|
headers,
|
|
@@ -5172,11 +5172,11 @@ var require_request = __commonJS({
|
|
|
5172
5172
|
expectContinue,
|
|
5173
5173
|
servername
|
|
5174
5174
|
}, handler2) {
|
|
5175
|
-
if (typeof
|
|
5175
|
+
if (typeof path13 !== "string") {
|
|
5176
5176
|
throw new InvalidArgumentError("path must be a string");
|
|
5177
|
-
} else if (
|
|
5177
|
+
} else if (path13[0] !== "/" && !(path13.startsWith("http://") || path13.startsWith("https://")) && method !== "CONNECT") {
|
|
5178
5178
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
5179
|
-
} else if (invalidPathRegex.test(
|
|
5179
|
+
} else if (invalidPathRegex.test(path13)) {
|
|
5180
5180
|
throw new InvalidArgumentError("invalid request path");
|
|
5181
5181
|
}
|
|
5182
5182
|
if (typeof method !== "string") {
|
|
@@ -5242,7 +5242,7 @@ var require_request = __commonJS({
|
|
|
5242
5242
|
this.completed = false;
|
|
5243
5243
|
this.aborted = false;
|
|
5244
5244
|
this.upgrade = upgrade || null;
|
|
5245
|
-
this.path = query ? buildURL(
|
|
5245
|
+
this.path = query ? buildURL(path13, query) : path13;
|
|
5246
5246
|
this.origin = origin;
|
|
5247
5247
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
5248
5248
|
this.blocking = blocking == null ? false : blocking;
|
|
@@ -9768,7 +9768,7 @@ var require_client_h1 = __commonJS({
|
|
|
9768
9768
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
9769
9769
|
}
|
|
9770
9770
|
function writeH1(client, request) {
|
|
9771
|
-
const { method, path:
|
|
9771
|
+
const { method, path: path13, host, upgrade, blocking, reset } = request;
|
|
9772
9772
|
let { body, headers, contentLength } = request;
|
|
9773
9773
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
9774
9774
|
if (util.isFormDataLike(body)) {
|
|
@@ -9834,7 +9834,7 @@ var require_client_h1 = __commonJS({
|
|
|
9834
9834
|
if (blocking) {
|
|
9835
9835
|
socket[kBlocking] = true;
|
|
9836
9836
|
}
|
|
9837
|
-
let header = `${method} ${
|
|
9837
|
+
let header = `${method} ${path13} HTTP/1.1\r
|
|
9838
9838
|
`;
|
|
9839
9839
|
if (typeof host === "string") {
|
|
9840
9840
|
header += `host: ${host}\r
|
|
@@ -10360,7 +10360,7 @@ var require_client_h2 = __commonJS({
|
|
|
10360
10360
|
}
|
|
10361
10361
|
function writeH2(client, request) {
|
|
10362
10362
|
const session = client[kHTTP2Session];
|
|
10363
|
-
const { method, path:
|
|
10363
|
+
const { method, path: path13, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
|
|
10364
10364
|
let { body } = request;
|
|
10365
10365
|
if (upgrade) {
|
|
10366
10366
|
util.errorRequest(client, request, new Error("Upgrade not supported for H2"));
|
|
@@ -10427,7 +10427,7 @@ var require_client_h2 = __commonJS({
|
|
|
10427
10427
|
});
|
|
10428
10428
|
return true;
|
|
10429
10429
|
}
|
|
10430
|
-
headers[HTTP2_HEADER_PATH] =
|
|
10430
|
+
headers[HTTP2_HEADER_PATH] = path13;
|
|
10431
10431
|
headers[HTTP2_HEADER_SCHEME] = "https";
|
|
10432
10432
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
10433
10433
|
if (body && typeof body.read === "function") {
|
|
@@ -10780,9 +10780,9 @@ var require_redirect_handler = __commonJS({
|
|
|
10780
10780
|
return this.handler.onHeaders(statusCode, headers, resume, statusText);
|
|
10781
10781
|
}
|
|
10782
10782
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
10783
|
-
const
|
|
10783
|
+
const path13 = search ? `${pathname}${search}` : pathname;
|
|
10784
10784
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
10785
|
-
this.opts.path =
|
|
10785
|
+
this.opts.path = path13;
|
|
10786
10786
|
this.opts.origin = origin;
|
|
10787
10787
|
this.opts.maxRedirections = 0;
|
|
10788
10788
|
this.opts.query = null;
|
|
@@ -12017,10 +12017,10 @@ var require_proxy_agent = __commonJS({
|
|
|
12017
12017
|
};
|
|
12018
12018
|
const {
|
|
12019
12019
|
origin,
|
|
12020
|
-
path:
|
|
12020
|
+
path: path13 = "/",
|
|
12021
12021
|
headers = {}
|
|
12022
12022
|
} = opts;
|
|
12023
|
-
opts.path = origin +
|
|
12023
|
+
opts.path = origin + path13;
|
|
12024
12024
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
12025
12025
|
const { host } = new URL3(origin);
|
|
12026
12026
|
headers.host = host;
|
|
@@ -13941,20 +13941,20 @@ var require_mock_utils = __commonJS({
|
|
|
13941
13941
|
}
|
|
13942
13942
|
return true;
|
|
13943
13943
|
}
|
|
13944
|
-
function safeUrl(
|
|
13945
|
-
if (typeof
|
|
13946
|
-
return
|
|
13944
|
+
function safeUrl(path13) {
|
|
13945
|
+
if (typeof path13 !== "string") {
|
|
13946
|
+
return path13;
|
|
13947
13947
|
}
|
|
13948
|
-
const pathSegments =
|
|
13948
|
+
const pathSegments = path13.split("?");
|
|
13949
13949
|
if (pathSegments.length !== 2) {
|
|
13950
|
-
return
|
|
13950
|
+
return path13;
|
|
13951
13951
|
}
|
|
13952
13952
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
13953
13953
|
qp.sort();
|
|
13954
13954
|
return [...pathSegments, qp.toString()].join("?");
|
|
13955
13955
|
}
|
|
13956
|
-
function matchKey(mockDispatch2, { path:
|
|
13957
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
13956
|
+
function matchKey(mockDispatch2, { path: path13, method, body, headers }) {
|
|
13957
|
+
const pathMatch = matchValue(mockDispatch2.path, path13);
|
|
13958
13958
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
13959
13959
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
13960
13960
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -13976,7 +13976,7 @@ var require_mock_utils = __commonJS({
|
|
|
13976
13976
|
function getMockDispatch(mockDispatches, key) {
|
|
13977
13977
|
const basePath = key.query ? buildURL(key.path, key.query) : key.path;
|
|
13978
13978
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
13979
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
13979
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path13 }) => matchValue(safeUrl(path13), resolvedPath));
|
|
13980
13980
|
if (matchedMockDispatches.length === 0) {
|
|
13981
13981
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
13982
13982
|
}
|
|
@@ -14014,9 +14014,9 @@ var require_mock_utils = __commonJS({
|
|
|
14014
14014
|
}
|
|
14015
14015
|
}
|
|
14016
14016
|
function buildKey(opts) {
|
|
14017
|
-
const { path:
|
|
14017
|
+
const { path: path13, method, body, headers, query } = opts;
|
|
14018
14018
|
return {
|
|
14019
|
-
path:
|
|
14019
|
+
path: path13,
|
|
14020
14020
|
method,
|
|
14021
14021
|
body,
|
|
14022
14022
|
headers,
|
|
@@ -14479,10 +14479,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
14479
14479
|
}
|
|
14480
14480
|
format(pendingInterceptors) {
|
|
14481
14481
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
14482
|
-
({ method, path:
|
|
14482
|
+
({ method, path: path13, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
14483
14483
|
Method: method,
|
|
14484
14484
|
Origin: origin,
|
|
14485
|
-
Path:
|
|
14485
|
+
Path: path13,
|
|
14486
14486
|
"Status code": statusCode,
|
|
14487
14487
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
14488
14488
|
Invocations: timesInvoked,
|
|
@@ -19363,9 +19363,9 @@ var require_util6 = __commonJS({
|
|
|
19363
19363
|
}
|
|
19364
19364
|
}
|
|
19365
19365
|
}
|
|
19366
|
-
function validateCookiePath(
|
|
19367
|
-
for (let i = 0; i <
|
|
19368
|
-
const code =
|
|
19366
|
+
function validateCookiePath(path13) {
|
|
19367
|
+
for (let i = 0; i < path13.length; ++i) {
|
|
19368
|
+
const code = path13.charCodeAt(i);
|
|
19369
19369
|
if (code < 32 || // exclude CTLs (0-31)
|
|
19370
19370
|
code === 127 || // DEL
|
|
19371
19371
|
code === 59) {
|
|
@@ -22042,11 +22042,11 @@ var require_undici = __commonJS({
|
|
|
22042
22042
|
if (typeof opts.path !== "string") {
|
|
22043
22043
|
throw new InvalidArgumentError("invalid opts.path");
|
|
22044
22044
|
}
|
|
22045
|
-
let
|
|
22045
|
+
let path13 = opts.path;
|
|
22046
22046
|
if (!opts.path.startsWith("/")) {
|
|
22047
|
-
|
|
22047
|
+
path13 = `/${path13}`;
|
|
22048
22048
|
}
|
|
22049
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
22049
|
+
url = new URL(util.parseOrigin(url).origin + path13);
|
|
22050
22050
|
} else {
|
|
22051
22051
|
if (!opts) {
|
|
22052
22052
|
opts = typeof url === "object" ? url : {};
|
|
@@ -22727,9 +22727,9 @@ function buildEffectsIndex(layerOutputs) {
|
|
|
22727
22727
|
return idx;
|
|
22728
22728
|
}
|
|
22729
22729
|
function writeEffectsIndex(rootDir, idx) {
|
|
22730
|
-
const
|
|
22731
|
-
atomicWriteFileSync(
|
|
22732
|
-
return
|
|
22730
|
+
const path13 = (0, import_node_path11.join)(rootDir, LAUNCHSECURE_DIR, "graphs", "effects-index.json");
|
|
22731
|
+
atomicWriteFileSync(path13, JSON.stringify(idx, null, 2) + "\n");
|
|
22732
|
+
return path13;
|
|
22733
22733
|
}
|
|
22734
22734
|
var import_node_path11;
|
|
22735
22735
|
var init_effects_index = __esm({
|
|
@@ -23040,10 +23040,10 @@ async function generateGraph(rootDir, layer) {
|
|
|
23040
23040
|
return results;
|
|
23041
23041
|
}
|
|
23042
23042
|
function readEffectsIndex(rootDir) {
|
|
23043
|
-
const
|
|
23044
|
-
if (!(0, import_node_fs11.existsSync)(
|
|
23043
|
+
const path13 = (0, import_node_path13.join)(rootDir, GRAPHS_DIR2, "effects-index.json");
|
|
23044
|
+
if (!(0, import_node_fs11.existsSync)(path13)) return null;
|
|
23045
23045
|
try {
|
|
23046
|
-
return JSON.parse((0, import_node_fs11.readFileSync)(
|
|
23046
|
+
return JSON.parse((0, import_node_fs11.readFileSync)(path13, "utf-8"));
|
|
23047
23047
|
} catch {
|
|
23048
23048
|
return null;
|
|
23049
23049
|
}
|
|
@@ -24463,6 +24463,18 @@ function initLaunchPodTerminalBridge(httpServer, projectDir) {
|
|
|
24463
24463
|
var import_fs = __toESM(require("fs"));
|
|
24464
24464
|
var import_path2 = __toESM(require("path"));
|
|
24465
24465
|
var MANAGED_SERVERS = ["launch-pod", "launch-chart"];
|
|
24466
|
+
function mergeMcpEntry(existing, ours) {
|
|
24467
|
+
if (!existing || typeof existing !== "object") return ours;
|
|
24468
|
+
const prev = existing;
|
|
24469
|
+
const merged = { ...prev, ...ours };
|
|
24470
|
+
if (prev.headers || ours.headers) {
|
|
24471
|
+
merged.headers = { ...prev.headers ?? {}, ...ours.headers ?? {} };
|
|
24472
|
+
}
|
|
24473
|
+
if (prev.env || ours.env) {
|
|
24474
|
+
merged.env = { ...prev.env ?? {}, ...ours.env ?? {} };
|
|
24475
|
+
}
|
|
24476
|
+
return merged;
|
|
24477
|
+
}
|
|
24466
24478
|
var writtenPaths = [];
|
|
24467
24479
|
function writeMcpConfigs(opts) {
|
|
24468
24480
|
const { projectDir, token, serverUrl } = opts;
|
|
@@ -24524,17 +24536,17 @@ function writeClaudeConfig(projectDir, mcpUrl, token) {
|
|
|
24524
24536
|
}
|
|
24525
24537
|
}
|
|
24526
24538
|
const servers = existing.mcpServers ?? {};
|
|
24527
|
-
servers["launch-pod"] = {
|
|
24539
|
+
servers["launch-pod"] = mergeMcpEntry(servers["launch-pod"], {
|
|
24528
24540
|
type: "http",
|
|
24529
24541
|
url: mcpUrl,
|
|
24530
24542
|
headers: {
|
|
24531
24543
|
Authorization: `Bearer ${token}`
|
|
24532
24544
|
}
|
|
24533
|
-
};
|
|
24534
|
-
servers["launch-chart"] = {
|
|
24545
|
+
});
|
|
24546
|
+
servers["launch-chart"] = mergeMcpEntry(servers["launch-chart"], {
|
|
24535
24547
|
command: "launch-chart",
|
|
24536
24548
|
args: []
|
|
24537
|
-
};
|
|
24549
|
+
});
|
|
24538
24550
|
existing.mcpServers = servers;
|
|
24539
24551
|
import_fs.default.writeFileSync(filePath, JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
|
|
24540
24552
|
writtenPaths.push(filePath);
|
|
@@ -27072,8 +27084,7 @@ function buildAnalyzerMcpConfig() {
|
|
|
27072
27084
|
"launch-chart": {
|
|
27073
27085
|
command: process.execPath,
|
|
27074
27086
|
// current node binary, guaranteed-resolvable
|
|
27075
|
-
args: [graphEntry]
|
|
27076
|
-
env: { LAUNCH_CHART_AUTOSERVE: "1" }
|
|
27087
|
+
args: [graphEntry]
|
|
27077
27088
|
}
|
|
27078
27089
|
}
|
|
27079
27090
|
});
|
|
@@ -27091,7 +27102,7 @@ function buildAnalyzerPrompt(ctx) {
|
|
|
27091
27102
|
lines.push("If this feedback contains MULTIPLE distinct issues, the first line categorises the PRIMARY one. List the others on subsequent lines as `also <bug|feature|\u2026>: <one sentence>`. The first line is harvested as the card preview; the rest belong to your detailed analysis.");
|
|
27092
27103
|
lines.push("");
|
|
27093
27104
|
lines.push("ISSUE ENUMERATION \u2014 DO THIS BEFORE ANY OTHER STEP.");
|
|
27094
|
-
lines.push("The user's intent is spread across
|
|
27105
|
+
lines.push("The user's intent + diagnostic signal is spread across FOUR places: the FEEDBACK BODY, each PIN's NOTE, any RUNTIME EVENTS the beacon captured around the report (silent errors / unhandled rejections \u2014 these often reveal the real failure even when the body is vague), and the SCREENSHOT. Sub-bugs frequently live in pin notes, not the body. Before any tool call, enumerate every distinct issue you can identify across all four sources. For each issue, decide one of:");
|
|
27095
27106
|
lines.push(" \u2022 fix it now (add to your plan)");
|
|
27096
27107
|
lines.push(" \u2022 defer it (note why \u2014 out of scope, requires user input, etc.)");
|
|
27097
27108
|
lines.push(" \u2022 ambiguous \u2192 surface via `AskUserQuestion` BEFORE editing. Do NOT silently drop unclear fragments.");
|
|
@@ -27141,6 +27152,21 @@ function buildAnalyzerPrompt(ctx) {
|
|
|
27141
27152
|
}
|
|
27142
27153
|
lines.push("");
|
|
27143
27154
|
}
|
|
27155
|
+
if (ctx.events && ctx.events.length > 0) {
|
|
27156
|
+
lines.push(`RUNTIME EVENTS (${ctx.events.length}) \u2014 captured by the beacon between page load and Send. Treat these as the highest-signal diagnostic when the body is short. Always check whether the named source file matches a route/component you're investigating before blaming the user-described symptom.`);
|
|
27157
|
+
for (const ev of ctx.events) {
|
|
27158
|
+
const offset = formatEventOffset(ev.ts, ctx.capturedAt);
|
|
27159
|
+
const kindLabel = ev.kind === "unhandledrejection" ? "rejection" : "error";
|
|
27160
|
+
const location = ev.source ? `${ev.source}${ev.line ? `:${ev.line}` : ""}${ev.col ? `:${ev.col}` : ""}` : null;
|
|
27161
|
+
lines.push(`${kindLabel.toUpperCase()} (${offset}): ${ev.message}`);
|
|
27162
|
+
if (location) lines.push(` at ${location}`);
|
|
27163
|
+
if (ev.stack) {
|
|
27164
|
+
const stackHead = ev.stack.split("\n").slice(0, 5).join("\n").slice(0, 600);
|
|
27165
|
+
for (const sl of stackHead.split("\n")) lines.push(` ${sl}`);
|
|
27166
|
+
}
|
|
27167
|
+
}
|
|
27168
|
+
lines.push("");
|
|
27169
|
+
}
|
|
27144
27170
|
lines.push("PROCEDURE (step 0 is the mandatory category line above \u2014 do NOT repeat the format instruction):");
|
|
27145
27171
|
let n = 1;
|
|
27146
27172
|
if (ctx.screenshotLocalPath) {
|
|
@@ -27161,6 +27187,16 @@ function buildAnalyzerPrompt(ctx) {
|
|
|
27161
27187
|
lines.push(` ${n++}. If any fix is non-trivial, ambiguous, or would touch many files, STOP and either (a) ask via \`AskUserQuestion\`, or (b) write a plan in your final response instead of editing. Better to leave the user a clear next-step than to commit a wrong change.`);
|
|
27162
27188
|
return lines.join("\n");
|
|
27163
27189
|
}
|
|
27190
|
+
function formatEventOffset(eventTs, capturedAt) {
|
|
27191
|
+
if (!capturedAt) return `ts=${eventTs}`;
|
|
27192
|
+
const diffMs = eventTs - new Date(capturedAt).getTime();
|
|
27193
|
+
if (!Number.isFinite(diffMs)) return `ts=${eventTs}`;
|
|
27194
|
+
const direction = diffMs <= 0 ? "before report" : "after report";
|
|
27195
|
+
const abs = Math.abs(diffMs);
|
|
27196
|
+
if (abs < 1e3) return `${abs}ms ${direction}`;
|
|
27197
|
+
if (abs < 6e4) return `${(abs / 1e3).toFixed(1)}s ${direction}`;
|
|
27198
|
+
return `${(abs / 6e4).toFixed(1)}m ${direction}`;
|
|
27199
|
+
}
|
|
27164
27200
|
async function resumeAnalysisSession(params) {
|
|
27165
27201
|
const { sessionId, projectDir } = params;
|
|
27166
27202
|
const id = createSessionDirect(`radar: ${sessionId.slice(-8)} (resumed)`, projectDir, sessionId);
|
|
@@ -27561,6 +27597,23 @@ function buildContext(payload) {
|
|
|
27561
27597
|
const body = typeof resource.body === "string" ? resource.body : payload.message;
|
|
27562
27598
|
const severity = typeof fields.severity === "string" ? fields.severity : void 0;
|
|
27563
27599
|
const route = typeof beaconMeta.url === "string" ? beaconMeta.url : void 0;
|
|
27600
|
+
const rawEvents = Array.isArray(fields.events) ? fields.events : [];
|
|
27601
|
+
const events = rawEvents.map((e) => {
|
|
27602
|
+
const kind = e.kind === "error" || e.kind === "unhandledrejection" ? e.kind : null;
|
|
27603
|
+
const ts = typeof e.ts === "number" ? e.ts : null;
|
|
27604
|
+
const message = typeof e.message === "string" ? e.message : null;
|
|
27605
|
+
if (!kind || ts === null || !message) return null;
|
|
27606
|
+
return {
|
|
27607
|
+
ts,
|
|
27608
|
+
kind,
|
|
27609
|
+
message,
|
|
27610
|
+
...typeof e.stack === "string" ? { stack: e.stack } : {},
|
|
27611
|
+
...typeof e.source === "string" ? { source: e.source } : {},
|
|
27612
|
+
...typeof e.line === "number" ? { line: e.line } : {},
|
|
27613
|
+
...typeof e.col === "number" ? { col: e.col } : {}
|
|
27614
|
+
};
|
|
27615
|
+
}).filter((e) => e !== null);
|
|
27616
|
+
const capturedAt = typeof beaconMeta.capturedAt === "string" ? beaconMeta.capturedAt : void 0;
|
|
27564
27617
|
const viewport = isViewport(beaconMeta.viewport) ? { w: beaconMeta.viewport.w, h: beaconMeta.viewport.h } : void 0;
|
|
27565
27618
|
const theme = beaconMeta.theme === "light" || beaconMeta.theme === "dark" ? beaconMeta.theme : void 0;
|
|
27566
27619
|
const userAgent = typeof beaconMeta.userAgent === "string" ? beaconMeta.userAgent : void 0;
|
|
@@ -27573,6 +27626,8 @@ function buildContext(payload) {
|
|
|
27573
27626
|
severity,
|
|
27574
27627
|
route,
|
|
27575
27628
|
pins: pins.length > 0 ? pins : void 0,
|
|
27629
|
+
events: events.length > 0 ? events : void 0,
|
|
27630
|
+
capturedAt,
|
|
27576
27631
|
viewport,
|
|
27577
27632
|
theme,
|
|
27578
27633
|
userAgent,
|
|
@@ -27718,19 +27773,19 @@ var import_node_path3 = require("node:path");
|
|
|
27718
27773
|
init_launch_kit_paths();
|
|
27719
27774
|
var MAX_DEDUPE_SET = 1e3;
|
|
27720
27775
|
var MAX_PINGS = 200;
|
|
27721
|
-
function readJson(
|
|
27722
|
-
if (!(0, import_node_fs2.existsSync)(
|
|
27776
|
+
function readJson(path13, fallback) {
|
|
27777
|
+
if (!(0, import_node_fs2.existsSync)(path13)) return fallback;
|
|
27723
27778
|
try {
|
|
27724
|
-
return JSON.parse((0, import_node_fs2.readFileSync)(
|
|
27779
|
+
return JSON.parse((0, import_node_fs2.readFileSync)(path13, "utf-8"));
|
|
27725
27780
|
} catch {
|
|
27726
27781
|
return fallback;
|
|
27727
27782
|
}
|
|
27728
27783
|
}
|
|
27729
|
-
function writeJsonAtomic(
|
|
27730
|
-
(0, import_node_fs2.mkdirSync)((0, import_node_path3.dirname)(
|
|
27731
|
-
const tmp = `${
|
|
27784
|
+
function writeJsonAtomic(path13, value) {
|
|
27785
|
+
(0, import_node_fs2.mkdirSync)((0, import_node_path3.dirname)(path13), { recursive: true });
|
|
27786
|
+
const tmp = `${path13}.tmp.${process.pid}.${Date.now()}`;
|
|
27732
27787
|
(0, import_node_fs2.writeFileSync)(tmp, JSON.stringify(value, null, 2), "utf-8");
|
|
27733
|
-
(0, import_node_fs2.renameSync)(tmp,
|
|
27788
|
+
(0, import_node_fs2.renameSync)(tmp, path13);
|
|
27734
27789
|
}
|
|
27735
27790
|
var RadarState = class {
|
|
27736
27791
|
constructor(projectRoot) {
|
|
@@ -27863,9 +27918,9 @@ var RadarState = class {
|
|
|
27863
27918
|
});
|
|
27864
27919
|
}
|
|
27865
27920
|
/** Persist the local path of a successfully-prefetched screenshot. */
|
|
27866
|
-
setScreenshotLocalPath(id,
|
|
27921
|
+
setScreenshotLocalPath(id, path13) {
|
|
27867
27922
|
return this.mutate(id, (p) => {
|
|
27868
|
-
p.context.screenshotLocalPath =
|
|
27923
|
+
p.context.screenshotLocalPath = path13;
|
|
27869
27924
|
});
|
|
27870
27925
|
}
|
|
27871
27926
|
/**
|
|
@@ -30882,12 +30937,12 @@ init_launch_kit_paths();
|
|
|
30882
30937
|
function loadApiRoutesFromOutput(apiOutput) {
|
|
30883
30938
|
const routes = [];
|
|
30884
30939
|
for (const n of apiOutput.nodes) {
|
|
30885
|
-
const
|
|
30886
|
-
if (!
|
|
30940
|
+
const path13 = n.path;
|
|
30941
|
+
if (!path13 || typeof path13 !== "string") continue;
|
|
30887
30942
|
routes.push({
|
|
30888
|
-
path:
|
|
30943
|
+
path: path13,
|
|
30889
30944
|
nodeId: n.id,
|
|
30890
|
-
segments:
|
|
30945
|
+
segments: path13.split("/").filter(Boolean)
|
|
30891
30946
|
});
|
|
30892
30947
|
}
|
|
30893
30948
|
return routes;
|
|
@@ -30979,16 +31034,16 @@ function resolveFetchCall(call, apiPathMap, apiRoutes) {
|
|
|
30979
31034
|
if (call.isConcat) {
|
|
30980
31035
|
return { kind: "dynamic", normalizedUrl: raw };
|
|
30981
31036
|
}
|
|
30982
|
-
const { path:
|
|
30983
|
-
if (!
|
|
30984
|
-
return { kind: "unresolved", normalizedUrl:
|
|
31037
|
+
const { path: path13, hadInterpolation } = normalizeFetchUrl(raw);
|
|
31038
|
+
if (!path13.startsWith("/")) {
|
|
31039
|
+
return { kind: "unresolved", normalizedUrl: path13 };
|
|
30985
31040
|
}
|
|
30986
|
-
const segs =
|
|
31041
|
+
const segs = path13.split("/").filter(Boolean);
|
|
30987
31042
|
if (hadInterpolation && segs.length > 0 && segs[0].startsWith(":")) {
|
|
30988
|
-
return { kind: "dynamic", normalizedUrl:
|
|
31043
|
+
return { kind: "dynamic", normalizedUrl: path13 };
|
|
30989
31044
|
}
|
|
30990
|
-
const exact = apiPathMap.get(
|
|
30991
|
-
if (exact) return { kind: "resolved", nodeId: exact, normalizedUrl:
|
|
31045
|
+
const exact = apiPathMap.get(path13);
|
|
31046
|
+
if (exact) return { kind: "resolved", nodeId: exact, normalizedUrl: path13 };
|
|
30992
31047
|
let bestScore = -1;
|
|
30993
31048
|
let bestId = null;
|
|
30994
31049
|
for (const r of apiRoutes) {
|
|
@@ -30999,21 +31054,21 @@ function resolveFetchCall(call, apiPathMap, apiRoutes) {
|
|
|
30999
31054
|
}
|
|
31000
31055
|
}
|
|
31001
31056
|
if (bestId && bestScore > 0) {
|
|
31002
|
-
return { kind: "resolved", nodeId: bestId, normalizedUrl:
|
|
31057
|
+
return { kind: "resolved", nodeId: bestId, normalizedUrl: path13 };
|
|
31003
31058
|
}
|
|
31004
|
-
return { kind: "unresolved", normalizedUrl:
|
|
31059
|
+
return { kind: "unresolved", normalizedUrl: path13 };
|
|
31005
31060
|
}
|
|
31006
31061
|
function resolveUrlPath(urlPath, apiPathMap, apiRoutes) {
|
|
31007
|
-
const { path:
|
|
31008
|
-
if (!
|
|
31009
|
-
return { kind: "unresolved", normalizedUrl:
|
|
31062
|
+
const { path: path13, hadInterpolation } = normalizeFetchUrl(urlPath);
|
|
31063
|
+
if (!path13.startsWith("/")) {
|
|
31064
|
+
return { kind: "unresolved", normalizedUrl: path13 };
|
|
31010
31065
|
}
|
|
31011
|
-
const segs =
|
|
31066
|
+
const segs = path13.split("/").filter(Boolean);
|
|
31012
31067
|
if (hadInterpolation && segs.length > 0 && segs[0].startsWith(":")) {
|
|
31013
|
-
return { kind: "dynamic", normalizedUrl:
|
|
31068
|
+
return { kind: "dynamic", normalizedUrl: path13 };
|
|
31014
31069
|
}
|
|
31015
|
-
const exact = apiPathMap.get(
|
|
31016
|
-
if (exact) return { kind: "resolved", nodeId: exact, normalizedUrl:
|
|
31070
|
+
const exact = apiPathMap.get(path13);
|
|
31071
|
+
if (exact) return { kind: "resolved", nodeId: exact, normalizedUrl: path13 };
|
|
31017
31072
|
let bestScore = -1;
|
|
31018
31073
|
let bestId = null;
|
|
31019
31074
|
for (const r of apiRoutes) {
|
|
@@ -31024,9 +31079,9 @@ function resolveUrlPath(urlPath, apiPathMap, apiRoutes) {
|
|
|
31024
31079
|
}
|
|
31025
31080
|
}
|
|
31026
31081
|
if (bestId && bestScore > 0) {
|
|
31027
|
-
return { kind: "resolved", nodeId: bestId, normalizedUrl:
|
|
31082
|
+
return { kind: "resolved", nodeId: bestId, normalizedUrl: path13 };
|
|
31028
31083
|
}
|
|
31029
|
-
return { kind: "unresolved", normalizedUrl:
|
|
31084
|
+
return { kind: "unresolved", normalizedUrl: path13 };
|
|
31030
31085
|
}
|
|
31031
31086
|
|
|
31032
31087
|
// src/server/graph/parsers/crosslayer/fetch-resolver.ts
|
|
@@ -32004,9 +32059,9 @@ function collectTargets(apiOutput, uiOutput) {
|
|
|
32004
32059
|
const out = [];
|
|
32005
32060
|
for (const n of apiOutput?.nodes ?? []) {
|
|
32006
32061
|
if (n.type !== "endpoint") continue;
|
|
32007
|
-
const
|
|
32008
|
-
if (typeof
|
|
32009
|
-
out.push({ id: n.id, route:
|
|
32062
|
+
const path13 = n.path;
|
|
32063
|
+
if (typeof path13 !== "string" || !path13) continue;
|
|
32064
|
+
out.push({ id: n.id, route: path13, layer: "api" });
|
|
32010
32065
|
}
|
|
32011
32066
|
for (const n of uiOutput?.nodes ?? []) {
|
|
32012
32067
|
if (n.type !== "page") continue;
|
|
@@ -34297,8 +34352,7 @@ function handleStartChartServer(args) {
|
|
|
34297
34352
|
const portArgs = args.port ? ["--port", String(args.port)] : [];
|
|
34298
34353
|
const child = (0, import_node_child_process3.spawn)(process.execPath, [entryPath, "serve", ...portArgs], {
|
|
34299
34354
|
detached: true,
|
|
34300
|
-
stdio: ["ignore", out, err2]
|
|
34301
|
-
env: { ...process.env, LAUNCH_CHART_AUTOSERVE: "" }
|
|
34355
|
+
stdio: ["ignore", out, err2]
|
|
34302
34356
|
});
|
|
34303
34357
|
child.unref();
|
|
34304
34358
|
return okJson({
|
|
@@ -34633,6 +34687,53 @@ function startGraphMcpServer() {
|
|
|
34633
34687
|
|
|
34634
34688
|
// src/server/cli.ts
|
|
34635
34689
|
init_launch_kit_paths();
|
|
34690
|
+
|
|
34691
|
+
// src/server/cred-shape.ts
|
|
34692
|
+
var fs9 = __toESM(require("node:fs"));
|
|
34693
|
+
var path11 = __toESM(require("node:path"));
|
|
34694
|
+
var CONFIG_FILENAME = ".launch-secure.cred.config";
|
|
34695
|
+
function inferCourseName(serverUrl) {
|
|
34696
|
+
try {
|
|
34697
|
+
const host = new URL(serverUrl).hostname.toLowerCase();
|
|
34698
|
+
if (host === "localhost" || host === "127.0.0.1" || host.endsWith(".local")) return "local";
|
|
34699
|
+
if (host.includes("staging")) return "staging";
|
|
34700
|
+
if (host.endsWith(".vercel.app")) return "prod";
|
|
34701
|
+
return host.split(".")[0] || "default";
|
|
34702
|
+
} catch {
|
|
34703
|
+
return "default";
|
|
34704
|
+
}
|
|
34705
|
+
}
|
|
34706
|
+
function toNested(cred) {
|
|
34707
|
+
if (cred.profiles && cred.active && cred.profiles[cred.active]) {
|
|
34708
|
+
return { active: cred.active, profiles: cred.profiles };
|
|
34709
|
+
}
|
|
34710
|
+
if (!cred.pat || !cred.orgSlug || !cred.projectSlug || !cred.serverUrl) {
|
|
34711
|
+
return null;
|
|
34712
|
+
}
|
|
34713
|
+
const name = inferCourseName(cred.serverUrl);
|
|
34714
|
+
return {
|
|
34715
|
+
active: name,
|
|
34716
|
+
profiles: {
|
|
34717
|
+
[name]: {
|
|
34718
|
+
pat: cred.pat,
|
|
34719
|
+
orgSlug: cred.orgSlug,
|
|
34720
|
+
projectSlug: cred.projectSlug,
|
|
34721
|
+
serverUrl: cred.serverUrl
|
|
34722
|
+
}
|
|
34723
|
+
}
|
|
34724
|
+
};
|
|
34725
|
+
}
|
|
34726
|
+
function readCredFile(repoRoot) {
|
|
34727
|
+
const p = path11.join(repoRoot, CONFIG_FILENAME);
|
|
34728
|
+
if (!fs9.existsSync(p)) return null;
|
|
34729
|
+
try {
|
|
34730
|
+
return JSON.parse(fs9.readFileSync(p, "utf-8"));
|
|
34731
|
+
} catch (err2) {
|
|
34732
|
+
throw new Error(`could not parse ${CONFIG_FILENAME}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
34733
|
+
}
|
|
34734
|
+
}
|
|
34735
|
+
|
|
34736
|
+
// src/server/cli.ts
|
|
34636
34737
|
var DEFAULT_CAPABILITIES = {
|
|
34637
34738
|
workspace_setup: true,
|
|
34638
34739
|
terminal: true
|
|
@@ -35246,7 +35347,7 @@ if (parsedArgs.subcommand === "graph:generate" || parsedArgs.subcommand === "gra
|
|
|
35246
35347
|
const result = (0, import_child_process4.spawnSync)(
|
|
35247
35348
|
process.execPath,
|
|
35248
35349
|
[chartEntry, chartSubcommand, ...process.argv.slice(3)],
|
|
35249
|
-
{ stdio: "inherit"
|
|
35350
|
+
{ stdio: "inherit" }
|
|
35250
35351
|
);
|
|
35251
35352
|
process.exit(result.status ?? 1);
|
|
35252
35353
|
}
|
|
@@ -35256,71 +35357,28 @@ if (parsedArgs.subcommand === "mcp:graph") {
|
|
|
35256
35357
|
var __isMcpMode = parsedArgs.subcommand === "mcp:graph";
|
|
35257
35358
|
var __isRadarMode = parsedArgs.subcommand === "radar";
|
|
35258
35359
|
var radar = null;
|
|
35259
|
-
var CRED_CONFIG_FILENAME = ".launch-secure.cred.config";
|
|
35260
|
-
var LEGACY_CRED_CONFIG_FILENAME = ".launch-secure.config";
|
|
35261
|
-
function migrateLegacyCredConfig(repoRoot) {
|
|
35262
|
-
const legacy = import_path9.default.join(repoRoot, LEGACY_CRED_CONFIG_FILENAME);
|
|
35263
|
-
const dest = import_path9.default.join(repoRoot, CRED_CONFIG_FILENAME);
|
|
35264
|
-
if (!import_fs8.default.existsSync(legacy) || import_fs8.default.existsSync(dest)) return;
|
|
35265
|
-
let parsed;
|
|
35266
|
-
try {
|
|
35267
|
-
parsed = JSON.parse(import_fs8.default.readFileSync(legacy, "utf-8"));
|
|
35268
|
-
} catch {
|
|
35269
|
-
return;
|
|
35270
|
-
}
|
|
35271
|
-
const pat = parsed?.pat;
|
|
35272
|
-
if (typeof pat !== "string" || !pat.startsWith("ls_pat_")) return;
|
|
35273
|
-
import_fs8.default.renameSync(legacy, dest);
|
|
35274
|
-
console.warn(`[launchpod] migrated legacy ${LEGACY_CRED_CONFIG_FILENAME} \u2192 ${CRED_CONFIG_FILENAME} (the old name is now reserved for file-backed-config)`);
|
|
35275
|
-
}
|
|
35276
35360
|
function readLaunchSecureMcpConfig() {
|
|
35277
|
-
|
|
35278
|
-
const
|
|
35279
|
-
if (
|
|
35280
|
-
|
|
35281
|
-
try {
|
|
35282
|
-
parsed = JSON.parse(import_fs8.default.readFileSync(configPath, "utf-8"));
|
|
35283
|
-
} catch (err2) {
|
|
35284
|
-
throw new Error(`Could not parse ${configPath}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
35285
|
-
}
|
|
35286
|
-
const { pat: pat2, orgSlug: orgSlug2, projectSlug: projectSlug2, serverUrl } = parsed;
|
|
35287
|
-
if (!pat2 || !pat2.startsWith("ls_pat_")) {
|
|
35288
|
-
throw new Error(`${CRED_CONFIG_FILENAME} "pat" is missing or not a LaunchSecure PAT (ls_pat_...).`);
|
|
35289
|
-
}
|
|
35290
|
-
if (!orgSlug2 || !projectSlug2 || !serverUrl) {
|
|
35291
|
-
throw new Error(`${CRED_CONFIG_FILENAME} is missing required fields (orgSlug, projectSlug, serverUrl).`);
|
|
35292
|
-
}
|
|
35293
|
-
return { pat: pat2, orgSlug: orgSlug2, projectSlug: projectSlug2, serverUrl, source: CRED_CONFIG_FILENAME };
|
|
35361
|
+
const fix = `Run \`npx @launchsecure/launch-kit@latest refresh\` to re-sync this project (or \`init\` if you haven't bootstrapped yet).`;
|
|
35362
|
+
const cred = readCredFile(REPO_ROOT);
|
|
35363
|
+
if (!cred) {
|
|
35364
|
+
throw new Error(`${CONFIG_FILENAME} not found in ${REPO_ROOT}. ${fix}`);
|
|
35294
35365
|
}
|
|
35295
|
-
const
|
|
35296
|
-
if (!
|
|
35297
|
-
throw new Error(
|
|
35298
|
-
`Neither ${CRED_CONFIG_FILENAME} nor .mcp.json found in ${REPO_ROOT}. Run \`npx launch-kit init --token=... --org=... --project=...\` to bootstrap.`
|
|
35299
|
-
);
|
|
35366
|
+
const nested = toNested(cred);
|
|
35367
|
+
if (!nested) {
|
|
35368
|
+
throw new Error(`${CONFIG_FILENAME} is malformed or missing required fields (pat/orgSlug/projectSlug/serverUrl). ${fix}`);
|
|
35300
35369
|
}
|
|
35301
|
-
const
|
|
35302
|
-
|
|
35303
|
-
|
|
35304
|
-
const entry = raw.mcpServers?.[entryName];
|
|
35305
|
-
if (!entry?.url) {
|
|
35306
|
-
throw new Error(`No "${entryName}" entry with url found in .mcp.json (set LAUNCHPOD_MCP_NAME=<name> to pick a different one, or migrate to ${CRED_CONFIG_FILENAME} via \`launch-kit init\`)`);
|
|
35370
|
+
const profile = nested.profiles[nested.active];
|
|
35371
|
+
if (!profile) {
|
|
35372
|
+
throw new Error(`${CONFIG_FILENAME} active course "${nested.active}" not found in profiles. ${fix}`);
|
|
35307
35373
|
}
|
|
35308
|
-
const
|
|
35309
|
-
|
|
35310
|
-
|
|
35311
|
-
throw new Error(
|
|
35312
|
-
`.mcp.json launch-secure Authorization header is not a PAT (ls_pat_...). Migrate to ${CRED_CONFIG_FILENAME} via \`launch-kit init\`, or update the header.`
|
|
35313
|
-
);
|
|
35374
|
+
const { pat, orgSlug, projectSlug, serverUrl } = profile;
|
|
35375
|
+
if (!pat || !pat.startsWith("ls_pat_")) {
|
|
35376
|
+
throw new Error(`${CONFIG_FILENAME} "pat" is missing or not a LaunchSecure PAT (ls_pat_...). ${fix}`);
|
|
35314
35377
|
}
|
|
35315
|
-
|
|
35316
|
-
|
|
35317
|
-
if (!orgSlug || !projectSlug) {
|
|
35318
|
-
throw new Error(
|
|
35319
|
-
"Missing X-Org-Slug / X-Project-Slug headers in .mcp.json launch-secure entry."
|
|
35320
|
-
);
|
|
35378
|
+
if (!orgSlug || !projectSlug || !serverUrl) {
|
|
35379
|
+
throw new Error(`${CONFIG_FILENAME} is missing required fields (orgSlug, projectSlug, serverUrl). ${fix}`);
|
|
35321
35380
|
}
|
|
35322
|
-
|
|
35323
|
-
return { pat, orgSlug, projectSlug, serverUrl: `${url.protocol}//${url.host}`, source: `.mcp.json[${entryName}]` };
|
|
35381
|
+
return { pat, orgSlug, projectSlug, serverUrl, source: `${CONFIG_FILENAME}[${nested.active}]` };
|
|
35324
35382
|
}
|
|
35325
35383
|
if (!__isMcpMode) {
|
|
35326
35384
|
let gracefulShutdown = function() {
|