@launchsecure/launch-kit 0.0.45 → 0.0.46

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.
Files changed (74) hide show
  1. package/dist/chart-client/assets/index-CXWFhknu.css +1 -0
  2. package/dist/chart-client/index.html +2 -2
  3. package/dist/client/assets/{index-BqiDfvZi.js → index-BQi0ccnm.js} +38 -38
  4. package/dist/client/assets/index-BxHD8tLY.css +32 -0
  5. package/dist/client/index.html +2 -2
  6. package/dist/council-client/assets/index-K5s7bSOk.css +1 -0
  7. package/dist/council-client/index.html +2 -2
  8. package/dist/deck-client/assets/{_baseUniq-9540Lrb7.js → _baseUniq-Dc3nUqjn.js} +1 -1
  9. package/dist/deck-client/assets/{arc-2FFU5_0l.js → arc-Pk4Hg5AC.js} +1 -1
  10. package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-CV2e3n5Z.js → architectureDiagram-Q4EWVU46-ClHfwBM_.js} +1 -1
  11. package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-B9JFwjAL.js → blockDiagram-DXYQGD6D-byyj3c2H.js} +1 -1
  12. package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-C0Gwco04.js → c4Diagram-AHTNJAMY-DAIz-EzX.js} +1 -1
  13. package/dist/deck-client/assets/channel-CrtYAG0j.js +1 -0
  14. package/dist/deck-client/assets/{chunk-4BX2VUAB-pnGex62D.js → chunk-4BX2VUAB-D9ILfgjn.js} +1 -1
  15. package/dist/deck-client/assets/{chunk-4TB4RGXK-BRfs5enT.js → chunk-4TB4RGXK-D5-01wU-.js} +1 -1
  16. package/dist/deck-client/assets/{chunk-55IACEB6-DV2sc7BN.js → chunk-55IACEB6-BQsygkyC.js} +1 -1
  17. package/dist/deck-client/assets/{chunk-EDXVE4YY-BH8QD8Jn.js → chunk-EDXVE4YY-BEQCd4L_.js} +1 -1
  18. package/dist/deck-client/assets/{chunk-FMBD7UC4-BVuRSGoP.js → chunk-FMBD7UC4-D347YT2V.js} +1 -1
  19. package/dist/deck-client/assets/{chunk-OYMX7WX6-DBBVRR48.js → chunk-OYMX7WX6-CN_JK0dw.js} +1 -1
  20. package/dist/deck-client/assets/{chunk-QZHKN3VN-DNLfqlpV.js → chunk-QZHKN3VN-Bt2J1da-.js} +1 -1
  21. package/dist/deck-client/assets/{chunk-YZCP3GAM-w7-OIPaD.js → chunk-YZCP3GAM-CyG1EIPO.js} +1 -1
  22. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-C6PSTf3r.js +1 -0
  23. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-C6PSTf3r.js +1 -0
  24. package/dist/deck-client/assets/clone-00e5l4vU.js +1 -0
  25. package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-D8kmXu30.js → cose-bilkent-S5V4N54A-pidjvoDW.js} +1 -1
  26. package/dist/deck-client/assets/{dagre-KV5264BT--b1FD3_Y.js → dagre-KV5264BT-B7y7oCcY.js} +1 -1
  27. package/dist/deck-client/assets/{diagram-5BDNPKRD-DKPVzUtl.js → diagram-5BDNPKRD-CCuv-nL4.js} +1 -1
  28. package/dist/deck-client/assets/{diagram-G4DWMVQ6-DYSdoCus.js → diagram-G4DWMVQ6-UNm_Nh5Y.js} +1 -1
  29. package/dist/deck-client/assets/{diagram-MMDJMWI5-DmqAI88z.js → diagram-MMDJMWI5-ozJ1XX_Q.js} +1 -1
  30. package/dist/deck-client/assets/{diagram-TYMM5635-Dbt6BCnF.js → diagram-TYMM5635-DbGkQand.js} +1 -1
  31. package/dist/deck-client/assets/{erDiagram-SMLLAGMA-C7Kfi12r.js → erDiagram-SMLLAGMA-CyyS0CgV.js} +1 -1
  32. package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-h1nKPzIv.js → flowDiagram-DWJPFMVM-B5-cES0d.js} +1 -1
  33. package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-40rX1Tln.js → ganttDiagram-T4ZO3ILL-8uB-aHPV.js} +1 -1
  34. package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-CtvJWtdg.js → gitGraphDiagram-UUTBAWPF-B3kn9oxf.js} +1 -1
  35. package/dist/deck-client/assets/{graph-ByiwozwM.js → graph-48RwtCOC.js} +1 -1
  36. package/dist/deck-client/assets/{index-CGG2xGJc.js → index-B_IK1EJu.js} +1 -1
  37. package/dist/deck-client/assets/index-CvIV2mXs.css +1 -0
  38. package/dist/deck-client/assets/{infoDiagram-42DDH7IO-CrGXAAvG.js → infoDiagram-42DDH7IO-DG1xrRXV.js} +1 -1
  39. package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-csBJinUG.js → ishikawaDiagram-UXIWVN3A-vHZT8oXQ.js} +1 -1
  40. package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-B2dZRDOR.js → journeyDiagram-VCZTEJTY-BAAi_YhC.js} +1 -1
  41. package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-Dyznt2QN.js → kanban-definition-6JOO6SKY-CfNP3Cu6.js} +1 -1
  42. package/dist/deck-client/assets/{layout-tvNTD61-.js → layout-DIXGbv3Y.js} +1 -1
  43. package/dist/deck-client/assets/{linear-BTcLgDqZ.js → linear-C9PVcQFx.js} +1 -1
  44. package/dist/deck-client/assets/{mermaid.core-CZoq2C4e.js → mermaid.core-w8AQRITb.js} +4 -4
  45. package/dist/deck-client/assets/{min-J7Zsly_t.js → min-B0k-NaRG.js} +1 -1
  46. package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-Ba-GyprJ.js → mindmap-definition-QFDTVHPH-F3oNoTMv.js} +1 -1
  47. package/dist/deck-client/assets/{pieDiagram-DEJITSTG-BMLzzK64.js → pieDiagram-DEJITSTG-tsvvDV0T.js} +1 -1
  48. package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-Dh_Ut0Yp.js → quadrantDiagram-34T5L4WZ-UwD6L8ht.js} +1 -1
  49. package/dist/deck-client/assets/{requirementDiagram-MS252O5E-Dkva9qg0.js → requirementDiagram-MS252O5E-De7hY7i9.js} +1 -1
  50. package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-3lcCBbua.js → sankeyDiagram-XADWPNL6-BAo56uzq.js} +1 -1
  51. package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-MH0H8qIE.js → sequenceDiagram-FGHM5R23-DBQe60Jv.js} +1 -1
  52. package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-ByLZbwGe.js → stateDiagram-FHFEXIEX-CcRfAns5.js} +1 -1
  53. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-CpnNRLqf.js +1 -0
  54. package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-COT8qN-f.js → timeline-definition-GMOUNBTQ-BlMy5lUr.js} +1 -1
  55. package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-YuKnKVX_.js → vennDiagram-DHZGUBPP-CiVqs92J.js} +1 -1
  56. package/dist/deck-client/assets/wardley-RL74JXVD-C19dhJoR.js +162 -0
  57. package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-BuLtRVnC.js → wardleyDiagram-NUSXRM2D-s_zVaEmu.js} +1 -1
  58. package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-CcIc1c6H.js → xychartDiagram-5P7HB3ND-DShsSL-Z.js} +1 -1
  59. package/dist/deck-client/index.html +2 -2
  60. package/dist/server/cli.js +472 -360
  61. package/dist/server/rover-entry.js +1 -1
  62. package/package.json +1 -1
  63. package/dist/chart-client/assets/index-DOKsFe5i.css +0 -1
  64. package/dist/client/assets/index-Mewz-s77.css +0 -32
  65. package/dist/council-client/assets/index-o_3y7Z0J.css +0 -1
  66. package/dist/deck-client/assets/channel-DUo1BfyB.js +0 -1
  67. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-sHUWMvyj.js +0 -1
  68. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-sHUWMvyj.js +0 -1
  69. package/dist/deck-client/assets/clone-pfbkP49m.js +0 -1
  70. package/dist/deck-client/assets/index-C6YxyZay.css +0 -1
  71. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-C87YsgaN.js +0 -1
  72. package/dist/deck-client/assets/wardley-RL74JXVD-C4YfwXTm.js +0 -162
  73. /package/dist/chart-client/assets/{index-DJQYgFcp.js → index-B7lPHV9b.js} +0 -0
  74. /package/dist/council-client/assets/{index-Wn06apTg.js → index-B04u6r-y.js} +0 -0
@@ -22157,20 +22157,20 @@ __export(config_exports, {
22157
22157
  loadConfig: () => loadConfig
22158
22158
  });
22159
22159
  function loadConfig(rootDir) {
22160
- const configPath = (0, import_node_path5.join)(rootDir, LAUNCHCHART_CONFIG_FILE);
22161
- if (!(0, import_node_fs5.existsSync)(configPath)) return {};
22160
+ const configPath = (0, import_node_path6.join)(rootDir, LAUNCHCHART_CONFIG_FILE);
22161
+ if (!(0, import_node_fs6.existsSync)(configPath)) return {};
22162
22162
  try {
22163
- return JSON.parse((0, import_node_fs5.readFileSync)(configPath, "utf-8"));
22163
+ return JSON.parse((0, import_node_fs6.readFileSync)(configPath, "utf-8"));
22164
22164
  } catch {
22165
22165
  return {};
22166
22166
  }
22167
22167
  }
22168
- var import_node_fs5, import_node_path5;
22168
+ var import_node_fs6, import_node_path6;
22169
22169
  var init_config = __esm({
22170
22170
  "src/server/graph/core/config.ts"() {
22171
22171
  "use strict";
22172
- import_node_fs5 = require("node:fs");
22173
- import_node_path5 = require("node:path");
22172
+ import_node_fs6 = require("node:fs");
22173
+ import_node_path6 = require("node:path");
22174
22174
  init_launch_kit_paths();
22175
22175
  }
22176
22176
  });
@@ -22207,18 +22207,18 @@ function detectConventionDirs(rootDir, extraConventionDirs = []) {
22207
22207
  const conventionDirs = [...CONVENTION_DIRS_BUILTIN, ...extraConventionDirs];
22208
22208
  const searchDirs = [
22209
22209
  rootDir,
22210
- (0, import_node_path6.join)(rootDir, "src"),
22211
- (0, import_node_path6.join)(rootDir, "app"),
22212
- (0, import_node_path6.join)(rootDir, "lib")
22210
+ (0, import_node_path7.join)(rootDir, "src"),
22211
+ (0, import_node_path7.join)(rootDir, "app"),
22212
+ (0, import_node_path7.join)(rootDir, "lib")
22213
22213
  ];
22214
22214
  for (const base of searchDirs) {
22215
22215
  for (const convention of conventionDirs) {
22216
- const dir = (0, import_node_path6.join)(base, convention);
22217
- if (!(0, import_node_fs6.existsSync)(dir)) continue;
22216
+ const dir = (0, import_node_path7.join)(base, convention);
22217
+ if (!(0, import_node_fs7.existsSync)(dir)) continue;
22218
22218
  try {
22219
- const stat = (0, import_node_fs6.statSync)(dir);
22219
+ const stat = (0, import_node_fs7.statSync)(dir);
22220
22220
  if (!stat.isDirectory()) continue;
22221
- const entries = (0, import_node_fs6.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
22221
+ const entries = (0, import_node_fs7.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
22222
22222
  if (entries.length > 0) {
22223
22223
  const relPath = dir.replace(rootDir + "/", "").replace(rootDir + "\\", "");
22224
22224
  result.set(relPath, entries);
@@ -22294,12 +22294,12 @@ function extractModuleFromPath(id, extraTrivial, extraSkipSegments, extraGeneric
22294
22294
  }
22295
22295
  return "root";
22296
22296
  }
22297
- var import_node_fs6, import_node_path6, CONVENTION_DIRS_BUILTIN, GENERIC_ROLE_NAMES_BUILTIN, SKIP_SEGMENTS_BUILTIN, TRIVIAL_GROUPS, cachedRootDir, cachedConventionDirs, moduleTagger;
22297
+ var import_node_fs7, import_node_path7, CONVENTION_DIRS_BUILTIN, GENERIC_ROLE_NAMES_BUILTIN, SKIP_SEGMENTS_BUILTIN, TRIVIAL_GROUPS, cachedRootDir, cachedConventionDirs, moduleTagger;
22298
22298
  var init_module_tagger = __esm({
22299
22299
  "src/server/graph/taggers/module-tagger.ts"() {
22300
22300
  "use strict";
22301
- import_node_fs6 = require("node:fs");
22302
- import_node_path6 = require("node:path");
22301
+ import_node_fs7 = require("node:fs");
22302
+ import_node_path7 = require("node:path");
22303
22303
  CONVENTION_DIRS_BUILTIN = ["features", "modules", "domains", "areas"];
22304
22304
  GENERIC_ROLE_NAMES_BUILTIN = /* @__PURE__ */ new Set([
22305
22305
  // JS/TS
@@ -22514,7 +22514,7 @@ function loadCustomTaggers(registry, config, rootDir, disabled) {
22514
22514
  for (const entry of config.taggers?.custom ?? []) {
22515
22515
  if (disabled.has(entry.id)) continue;
22516
22516
  try {
22517
- const absPath = (0, import_node_path7.resolve)(rootDir, entry.path);
22517
+ const absPath = (0, import_node_path8.resolve)(rootDir, entry.path);
22518
22518
  const mod = require(absPath);
22519
22519
  const tagger = "default" in mod ? mod.default : mod;
22520
22520
  const override = config.taggers?.trackUntagged?.[tagger.id];
@@ -22535,11 +22535,11 @@ function createTaggerRegistry(config, rootDir) {
22535
22535
  loadCustomTaggers(registry, config, rootDir, disabled);
22536
22536
  return registry;
22537
22537
  }
22538
- var import_node_path7, TaggerRegistry, BUILTIN_TAGGERS;
22538
+ var import_node_path8, TaggerRegistry, BUILTIN_TAGGERS;
22539
22539
  var init_tagger_registry = __esm({
22540
22540
  "src/server/graph/core/tagger-registry.ts"() {
22541
22541
  "use strict";
22542
- import_node_path7 = require("node:path");
22542
+ import_node_path8 = require("node:path");
22543
22543
  init_module_tagger();
22544
22544
  init_screen_tagger();
22545
22545
  TaggerRegistry = class {
@@ -22567,42 +22567,42 @@ var init_tagger_registry = __esm({
22567
22567
 
22568
22568
  // src/server/graph/core/atomic-write.ts
22569
22569
  function atomicWriteFileSync(filePath, content, encoding = "utf-8") {
22570
- (0, import_node_fs7.mkdirSync)((0, import_node_path8.dirname)(filePath), { recursive: true });
22570
+ (0, import_node_fs8.mkdirSync)((0, import_node_path9.dirname)(filePath), { recursive: true });
22571
22571
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
22572
22572
  try {
22573
- (0, import_node_fs7.writeFileSync)(tmp, content, typeof content === "string" ? encoding : void 0);
22574
- (0, import_node_fs7.renameSync)(tmp, filePath);
22573
+ (0, import_node_fs8.writeFileSync)(tmp, content, typeof content === "string" ? encoding : void 0);
22574
+ (0, import_node_fs8.renameSync)(tmp, filePath);
22575
22575
  } catch (e) {
22576
22576
  try {
22577
- (0, import_node_fs7.unlinkSync)(tmp);
22577
+ (0, import_node_fs8.unlinkSync)(tmp);
22578
22578
  } catch {
22579
22579
  }
22580
22580
  throw e;
22581
22581
  }
22582
22582
  }
22583
- var import_node_fs7, import_node_path8;
22583
+ var import_node_fs8, import_node_path9;
22584
22584
  var init_atomic_write = __esm({
22585
22585
  "src/server/graph/core/atomic-write.ts"() {
22586
22586
  "use strict";
22587
- import_node_fs7 = require("node:fs");
22588
- import_node_path8 = require("node:path");
22587
+ import_node_fs8 = require("node:fs");
22588
+ import_node_path9 = require("node:path");
22589
22589
  }
22590
22590
  });
22591
22591
 
22592
22592
  // src/server/graph/core/tag-store.ts
22593
22593
  function tagsFilePath(rootDir) {
22594
- return (0, import_node_path9.join)(rootDir, GRAPHS_DIR, TAGS_FILENAME);
22594
+ return (0, import_node_path10.join)(rootDir, GRAPHS_DIR, TAGS_FILENAME);
22595
22595
  }
22596
22596
  function readTagStore(rootDir) {
22597
22597
  const filePath = tagsFilePath(rootDir);
22598
- if (!(0, import_node_fs8.existsSync)(filePath)) return {};
22599
- const stat = (0, import_node_fs8.statSync)(filePath);
22598
+ if (!(0, import_node_fs9.existsSync)(filePath)) return {};
22599
+ const stat = (0, import_node_fs9.statSync)(filePath);
22600
22600
  const cached = tagCache.get(filePath);
22601
22601
  if (cached && cached.mtimeMs === stat.mtimeMs) {
22602
22602
  return cached.store;
22603
22603
  }
22604
22604
  try {
22605
- const content = (0, import_node_fs8.readFileSync)(filePath, "utf-8");
22605
+ const content = (0, import_node_fs9.readFileSync)(filePath, "utf-8");
22606
22606
  const store = JSON.parse(content);
22607
22607
  tagCache.set(filePath, { mtimeMs: stat.mtimeMs, store });
22608
22608
  return store;
@@ -22612,8 +22612,8 @@ function readTagStore(rootDir) {
22612
22612
  }
22613
22613
  function writeTagStore(rootDir, store) {
22614
22614
  const filePath = tagsFilePath(rootDir);
22615
- const dir = (0, import_node_path9.dirname)(filePath);
22616
- (0, import_node_fs8.mkdirSync)(dir, { recursive: true });
22615
+ const dir = (0, import_node_path10.dirname)(filePath);
22616
+ (0, import_node_fs9.mkdirSync)(dir, { recursive: true });
22617
22617
  const cleaned = {};
22618
22618
  for (const [nodeId, tags] of Object.entries(store)) {
22619
22619
  if (Object.keys(tags).length > 0) {
@@ -22638,12 +22638,12 @@ function removeTag(rootDir, nodeId, key) {
22638
22638
  }
22639
22639
  writeTagStore(rootDir, store);
22640
22640
  }
22641
- var import_node_fs8, import_node_path9, TAGS_FILENAME, GRAPHS_DIR, tagCache;
22641
+ var import_node_fs9, import_node_path10, TAGS_FILENAME, GRAPHS_DIR, tagCache;
22642
22642
  var init_tag_store = __esm({
22643
22643
  "src/server/graph/core/tag-store.ts"() {
22644
22644
  "use strict";
22645
- import_node_fs8 = require("node:fs");
22646
- import_node_path9 = require("node:path");
22645
+ import_node_fs9 = require("node:fs");
22646
+ import_node_path10 = require("node:path");
22647
22647
  init_atomic_write();
22648
22648
  TAGS_FILENAME = "tags.json";
22649
22649
  GRAPHS_DIR = ".launchsecure/graphs";
@@ -22653,10 +22653,10 @@ var init_tag_store = __esm({
22653
22653
 
22654
22654
  // src/server/graph/core/parse-worker-host.ts
22655
22655
  function resolveWorkerPath() {
22656
- const sibling = (0, import_node_path10.join)(__dirname, "parse-worker-entry.js");
22657
- if ((0, import_node_fs9.existsSync)(sibling)) return sibling;
22658
- const srcSibling = (0, import_node_path10.join)(__dirname, "..", "..", "parse-worker-entry.ts");
22659
- if ((0, import_node_fs9.existsSync)(srcSibling)) return srcSibling;
22656
+ const sibling = (0, import_node_path11.join)(__dirname, "parse-worker-entry.js");
22657
+ if ((0, import_node_fs10.existsSync)(sibling)) return sibling;
22658
+ const srcSibling = (0, import_node_path11.join)(__dirname, "..", "..", "parse-worker-entry.ts");
22659
+ if ((0, import_node_fs10.existsSync)(srcSibling)) return srcSibling;
22660
22660
  throw new Error(
22661
22661
  `parse-worker-entry not found. Build the chart server first (pnpm --filter @launchsecure/launch-kit build:server). Looked at: ${sibling} and ${srcSibling}`
22662
22662
  );
@@ -22698,12 +22698,12 @@ function runParseInWorker(req) {
22698
22698
  worker.postMessage(req);
22699
22699
  });
22700
22700
  }
22701
- var import_node_fs9, import_node_path10, import_node_worker_threads;
22701
+ var import_node_fs10, import_node_path11, import_node_worker_threads;
22702
22702
  var init_parse_worker_host = __esm({
22703
22703
  "src/server/graph/core/parse-worker-host.ts"() {
22704
22704
  "use strict";
22705
- import_node_fs9 = require("node:fs");
22706
- import_node_path10 = require("node:path");
22705
+ import_node_fs10 = require("node:fs");
22706
+ import_node_path11 = require("node:path");
22707
22707
  import_node_worker_threads = require("node:worker_threads");
22708
22708
  }
22709
22709
  });
@@ -22761,16 +22761,16 @@ function buildEffectsIndex(layerOutputs) {
22761
22761
  return idx;
22762
22762
  }
22763
22763
  function writeEffectsIndex(rootDir, idx) {
22764
- const path13 = (0, import_node_path11.join)(rootDir, LAUNCHSECURE_DIR, "graphs", "effects-index.json");
22764
+ const path13 = (0, import_node_path12.join)(rootDir, LAUNCHSECURE_DIR, "graphs", "effects-index.json");
22765
22765
  atomicWriteFileSync(path13, JSON.stringify(idx, null, 2) + "\n");
22766
22766
  return path13;
22767
22767
  }
22768
- var import_node_path11;
22768
+ var import_node_path12;
22769
22769
  var init_effects_index = __esm({
22770
22770
  "src/server/graph/core/effects-index.ts"() {
22771
22771
  "use strict";
22772
22772
  init_atomic_write();
22773
- import_node_path11 = require("node:path");
22773
+ import_node_path12 = require("node:path");
22774
22774
  init_launch_kit_paths();
22775
22775
  }
22776
22776
  });
@@ -22870,13 +22870,13 @@ var init_nextjs_prisma = __esm({
22870
22870
 
22871
22871
  // src/server/graph/core/context/overlay.ts
22872
22872
  function overlayPath(rootDir) {
22873
- return (0, import_node_path12.join)(rootDir, OVERLAY_FILE);
22873
+ return (0, import_node_path13.join)(rootDir, OVERLAY_FILE);
22874
22874
  }
22875
22875
  function loadOverlay(rootDir) {
22876
22876
  const path13 = overlayPath(rootDir);
22877
- if (!(0, import_node_fs10.existsSync)(path13)) return null;
22877
+ if (!(0, import_node_fs11.existsSync)(path13)) return null;
22878
22878
  try {
22879
- return JSON.parse((0, import_node_fs10.readFileSync)(path13, "utf-8"));
22879
+ return JSON.parse((0, import_node_fs11.readFileSync)(path13, "utf-8"));
22880
22880
  } catch (e) {
22881
22881
  process.stderr.write(`[launch-chart] failed to parse ${OVERLAY_FILE}: ${e.message}
22882
22882
  `);
@@ -22892,18 +22892,18 @@ function applyOverlayRejections(edges, rootDir) {
22892
22892
  );
22893
22893
  return edges.filter((e) => !rejectKeys.has(`${e.source}|${e.type}|${e.target}`));
22894
22894
  }
22895
- var import_node_fs10, import_node_path12, OVERLAY_FILE, overlayProvider;
22895
+ var import_node_fs11, import_node_path13, OVERLAY_FILE, overlayProvider;
22896
22896
  var init_overlay = __esm({
22897
22897
  "src/server/graph/core/context/overlay.ts"() {
22898
22898
  "use strict";
22899
- import_node_fs10 = require("node:fs");
22900
- import_node_path12 = require("node:path");
22899
+ import_node_fs11 = require("node:fs");
22900
+ import_node_path13 = require("node:path");
22901
22901
  init_types();
22902
22902
  OVERLAY_FILE = ".launchchart.context.json";
22903
22903
  overlayProvider = {
22904
22904
  id: "overlay",
22905
22905
  detect(_layerOutputs, rootDir) {
22906
- return (0, import_node_fs10.existsSync)(overlayPath(rootDir));
22906
+ return (0, import_node_fs11.existsSync)(overlayPath(rootDir));
22907
22907
  },
22908
22908
  derive(_layerOutputs, rootDir) {
22909
22909
  const overlay = loadOverlay(rootDir);
@@ -22952,7 +22952,7 @@ function registerBuiltins2(registry, disabled) {
22952
22952
  function loadCustomProviders(registry, config, rootDir, disabled) {
22953
22953
  for (const entry of config.context?.providers ?? []) {
22954
22954
  try {
22955
- const absPath = (0, import_node_path13.resolve)(rootDir, entry.path);
22955
+ const absPath = (0, import_node_path14.resolve)(rootDir, entry.path);
22956
22956
  const mod = require(absPath);
22957
22957
  const provider = "default" in mod ? mod.default : mod;
22958
22958
  if (disabled.has(provider.id)) continue;
@@ -22970,11 +22970,11 @@ function createContextProviderRegistry(config, rootDir) {
22970
22970
  loadCustomProviders(registry, config, rootDir, disabled);
22971
22971
  return registry;
22972
22972
  }
22973
- var import_node_path13, ContextProviderRegistry;
22973
+ var import_node_path14, ContextProviderRegistry;
22974
22974
  var init_registry = __esm({
22975
22975
  "src/server/graph/core/context/registry.ts"() {
22976
22976
  "use strict";
22977
- import_node_path13 = require("node:path");
22977
+ import_node_path14 = require("node:path");
22978
22978
  init_nextjs_prisma();
22979
22979
  init_overlay();
22980
22980
  ContextProviderRegistry = class {
@@ -23079,16 +23079,16 @@ function buildContextMap(layerOutputs, rootDir) {
23079
23079
  };
23080
23080
  }
23081
23081
  function writeContextMap(rootDir, output) {
23082
- const path13 = (0, import_node_path14.join)(rootDir, LAUNCHSECURE_DIR, "graphs", "context.json");
23082
+ const path13 = (0, import_node_path15.join)(rootDir, LAUNCHSECURE_DIR, "graphs", "context.json");
23083
23083
  atomicWriteFileSync(path13, JSON.stringify(output, null, 2) + "\n");
23084
23084
  return path13;
23085
23085
  }
23086
- var import_node_path14;
23086
+ var import_node_path15;
23087
23087
  var init_context_map = __esm({
23088
23088
  "src/server/graph/core/context-map.ts"() {
23089
23089
  "use strict";
23090
23090
  init_atomic_write();
23091
- import_node_path14 = require("node:path");
23091
+ import_node_path15 = require("node:path");
23092
23092
  init_launch_kit_paths();
23093
23093
  init_config();
23094
23094
  init_registry();
@@ -23112,12 +23112,12 @@ function getFreshnessTracker(rootDir) {
23112
23112
  }
23113
23113
  return t;
23114
23114
  }
23115
- var import_node_fs11, import_node_path15, SCHEMA_VERSION, MAX_PATCHED_FILES_TRACKED, DRIFTING_PATCH_THRESHOLD, HARD_ESCALATION_PATTERNS, FreshnessTracker, trackers;
23115
+ var import_node_fs12, import_node_path16, SCHEMA_VERSION, MAX_PATCHED_FILES_TRACKED, DRIFTING_PATCH_THRESHOLD, HARD_ESCALATION_PATTERNS, FreshnessTracker, trackers;
23116
23116
  var init_freshness = __esm({
23117
23117
  "src/server/graph/core/freshness.ts"() {
23118
23118
  "use strict";
23119
- import_node_fs11 = require("node:fs");
23120
- import_node_path15 = require("node:path");
23119
+ import_node_fs12 = require("node:fs");
23120
+ import_node_path16 = require("node:path");
23121
23121
  init_launch_kit_paths();
23122
23122
  init_atomic_write();
23123
23123
  SCHEMA_VERSION = 1;
@@ -23134,7 +23134,7 @@ var init_freshness = __esm({
23134
23134
  FreshnessTracker = class {
23135
23135
  constructor(rootDir) {
23136
23136
  this.dirty = false;
23137
- this.filePath = (0, import_node_path15.join)(rootDir, LAUNCHSECURE_DIR, "graphs", ".freshness.json");
23137
+ this.filePath = (0, import_node_path16.join)(rootDir, LAUNCHSECURE_DIR, "graphs", ".freshness.json");
23138
23138
  this.snapshot = this.load() ?? {
23139
23139
  state: "fresh",
23140
23140
  lastFullRegenAt: null,
@@ -23221,9 +23221,9 @@ var init_freshness = __esm({
23221
23221
  }
23222
23222
  }
23223
23223
  load() {
23224
- if (!(0, import_node_fs11.existsSync)(this.filePath)) return null;
23224
+ if (!(0, import_node_fs12.existsSync)(this.filePath)) return null;
23225
23225
  try {
23226
- const parsed = JSON.parse((0, import_node_fs11.readFileSync)(this.filePath, "utf-8"));
23226
+ const parsed = JSON.parse((0, import_node_fs12.readFileSync)(this.filePath, "utf-8"));
23227
23227
  if (parsed.schemaVersion !== SCHEMA_VERSION) return null;
23228
23228
  return {
23229
23229
  state: parsed.state,
@@ -23245,22 +23245,22 @@ var init_freshness = __esm({
23245
23245
 
23246
23246
  // src/server/graph/index.ts
23247
23247
  function getAvailableLayers(rootDir) {
23248
- const dir = (0, import_node_path16.join)(rootDir, GRAPHS_DIR2);
23249
- if (!(0, import_node_fs12.existsSync)(dir)) return [];
23250
- return (0, import_node_fs12.readdirSync)(dir).filter((f) => f.endsWith(".json") && !f.startsWith(".") && !NON_LAYER_GRAPH_FILES.has(f)).map((f) => f.replace(".json", ""));
23248
+ const dir = (0, import_node_path17.join)(rootDir, GRAPHS_DIR2);
23249
+ if (!(0, import_node_fs13.existsSync)(dir)) return [];
23250
+ return (0, import_node_fs13.readdirSync)(dir).filter((f) => f.endsWith(".json") && !f.startsWith(".") && !NON_LAYER_GRAPH_FILES.has(f)).map((f) => f.replace(".json", ""));
23251
23251
  }
23252
23252
  function graphsDir(rootDir) {
23253
- return (0, import_node_path16.join)(rootDir, GRAPHS_DIR2);
23253
+ return (0, import_node_path17.join)(rootDir, GRAPHS_DIR2);
23254
23254
  }
23255
23255
  function graphFilePath(rootDir, layer) {
23256
- return (0, import_node_path16.join)(graphsDir(rootDir), `${layer}.json`);
23256
+ return (0, import_node_path17.join)(graphsDir(rootDir), `${layer}.json`);
23257
23257
  }
23258
23258
  function tagsFilePath2(rootDir) {
23259
- return (0, import_node_path16.join)(graphsDir(rootDir), "tags.json");
23259
+ return (0, import_node_path17.join)(graphsDir(rootDir), "tags.json");
23260
23260
  }
23261
23261
  function getMtimeMs(filePath) {
23262
- if (!(0, import_node_fs12.existsSync)(filePath)) return 0;
23263
- return (0, import_node_fs12.statSync)(filePath).mtimeMs;
23262
+ if (!(0, import_node_fs13.existsSync)(filePath)) return 0;
23263
+ return (0, import_node_fs13.statSync)(filePath).mtimeMs;
23264
23264
  }
23265
23265
  function invalidateCache(filePath) {
23266
23266
  graphCache.delete(filePath);
@@ -23299,20 +23299,20 @@ function applyTags(graph, layer, rootDir) {
23299
23299
  }
23300
23300
  function readGraphRaw(rootDir, layer) {
23301
23301
  const filePath = graphFilePath(rootDir, layer);
23302
- if (!(0, import_node_fs12.existsSync)(filePath)) return null;
23303
- const stat = (0, import_node_fs12.statSync)(filePath);
23302
+ if (!(0, import_node_fs13.existsSync)(filePath)) return null;
23303
+ const stat = (0, import_node_fs13.statSync)(filePath);
23304
23304
  const cached = graphCache.get(filePath);
23305
23305
  if (cached && cached.mtimeMs === stat.mtimeMs) {
23306
23306
  return cached.graph;
23307
23307
  }
23308
- const content = (0, import_node_fs12.readFileSync)(filePath, "utf-8");
23308
+ const content = (0, import_node_fs13.readFileSync)(filePath, "utf-8");
23309
23309
  const graph = JSON.parse(content);
23310
23310
  graphCache.set(filePath, { mtimeMs: stat.mtimeMs, graph });
23311
23311
  return graph;
23312
23312
  }
23313
23313
  function readGraph(rootDir, layer) {
23314
23314
  const rawFilePath = graphFilePath(rootDir, layer);
23315
- if (!(0, import_node_fs12.existsSync)(rawFilePath)) return null;
23315
+ if (!(0, import_node_fs13.existsSync)(rawFilePath)) return null;
23316
23316
  const rawMtime = getMtimeMs(rawFilePath);
23317
23317
  const tagsMtime = getMtimeMs(tagsFilePath2(rootDir));
23318
23318
  const cacheKey = `${rootDir}:${layer}`;
@@ -23336,7 +23336,7 @@ function readAllGraphs(rootDir) {
23336
23336
  }
23337
23337
  async function generateGraph(rootDir, layer) {
23338
23338
  const dir = graphsDir(rootDir);
23339
- (0, import_node_fs12.mkdirSync)(dir, { recursive: true });
23339
+ (0, import_node_fs13.mkdirSync)(dir, { recursive: true });
23340
23340
  const { results, failedFiles } = await runParseInWorker({ rootDir, layer });
23341
23341
  for (const result of results) {
23342
23342
  const filePath = graphFilePath(rootDir, result.layer);
@@ -23347,13 +23347,13 @@ async function generateGraph(rootDir, layer) {
23347
23347
  if (!layer) {
23348
23348
  const producedLayers = new Set(results.map((r) => r.layer));
23349
23349
  try {
23350
- for (const f of (0, import_node_fs12.readdirSync)(dir)) {
23350
+ for (const f of (0, import_node_fs13.readdirSync)(dir)) {
23351
23351
  if (!f.endsWith(".json") || f === "tags.json" || f === "effects-index.json" || f === "context.json") continue;
23352
23352
  const layerName = f.replace(/\.json$/, "");
23353
23353
  if (producedLayers.has(layerName)) continue;
23354
- const orphan = (0, import_node_path16.join)(dir, f);
23354
+ const orphan = (0, import_node_path17.join)(dir, f);
23355
23355
  try {
23356
- (0, import_node_fs12.unlinkSync)(orphan);
23356
+ (0, import_node_fs13.unlinkSync)(orphan);
23357
23357
  invalidateCache(orphan);
23358
23358
  invalidateTaggedCache(rootDir, layerName);
23359
23359
  process.stderr.write(`[launch-chart] removed orphan layer file: ${f} (no parser produced ${layerName} this run)
@@ -23367,7 +23367,7 @@ async function generateGraph(rootDir, layer) {
23367
23367
  const allLayers = {};
23368
23368
  for (const r of results) allLayers[r.layer] = r.output;
23369
23369
  if (layer) {
23370
- for (const f of (0, import_node_fs12.readdirSync)(dir)) {
23370
+ for (const f of (0, import_node_fs13.readdirSync)(dir)) {
23371
23371
  if (!f.endsWith(".json") || f.startsWith(".") || f === "tags.json" || f === "effects-index.json" || f === "context.json") continue;
23372
23372
  const layerName = f.replace(/\.json$/, "");
23373
23373
  if (allLayers[layerName]) continue;
@@ -23405,20 +23405,20 @@ async function generateGraph(rootDir, layer) {
23405
23405
  return results;
23406
23406
  }
23407
23407
  function readEffectsIndex(rootDir) {
23408
- const path13 = (0, import_node_path16.join)(rootDir, GRAPHS_DIR2, "effects-index.json");
23409
- if (!(0, import_node_fs12.existsSync)(path13)) return null;
23408
+ const path13 = (0, import_node_path17.join)(rootDir, GRAPHS_DIR2, "effects-index.json");
23409
+ if (!(0, import_node_fs13.existsSync)(path13)) return null;
23410
23410
  try {
23411
- return JSON.parse((0, import_node_fs12.readFileSync)(path13, "utf-8"));
23411
+ return JSON.parse((0, import_node_fs13.readFileSync)(path13, "utf-8"));
23412
23412
  } catch {
23413
23413
  return null;
23414
23414
  }
23415
23415
  }
23416
- var import_node_fs12, import_node_path16, GRAPHS_DIR2, NON_LAYER_GRAPH_FILES, graphCache, taggedCache;
23416
+ var import_node_fs13, import_node_path17, GRAPHS_DIR2, NON_LAYER_GRAPH_FILES, graphCache, taggedCache;
23417
23417
  var init_graph = __esm({
23418
23418
  "src/server/graph/index.ts"() {
23419
23419
  "use strict";
23420
- import_node_fs12 = require("node:fs");
23421
- import_node_path16 = require("node:path");
23420
+ import_node_fs13 = require("node:fs");
23421
+ import_node_path17 = require("node:path");
23422
23422
  init_config();
23423
23423
  init_tagger_registry();
23424
23424
  init_tag_store();
@@ -23502,8 +23502,8 @@ function getQuery(name) {
23502
23502
  ensureInit();
23503
23503
  const cached = queryCache.get(name);
23504
23504
  if (cached) return cached;
23505
- const scmPath = (0, import_node_path22.join)(queriesDir, `${name}.scm`);
23506
- const scm = (0, import_node_fs17.readFileSync)(scmPath, "utf-8");
23505
+ const scmPath = (0, import_node_path23.join)(queriesDir, `${name}.scm`);
23506
+ const scm = (0, import_node_fs18.readFileSync)(scmPath, "utf-8");
23507
23507
  const query = tsxLanguage.query(scm);
23508
23508
  queryCache.set(name, query);
23509
23509
  return query;
@@ -23523,13 +23523,13 @@ function parseSource(absPath) {
23523
23523
  ensureInit();
23524
23524
  let content;
23525
23525
  try {
23526
- const stat = (0, import_node_fs17.statSync)(absPath);
23526
+ const stat = (0, import_node_fs18.statSync)(absPath);
23527
23527
  if (stat.size > MAX_PARSEABLE_BYTES) {
23528
23528
  process.stderr.write(`[lc-extractor] skipping ${absPath}: ${stat.size} bytes exceeds max ${MAX_PARSEABLE_BYTES}
23529
23529
  `);
23530
23530
  return null;
23531
23531
  }
23532
- content = (0, import_node_fs17.readFileSync)(absPath, "utf-8");
23532
+ content = (0, import_node_fs18.readFileSync)(absPath, "utf-8");
23533
23533
  } catch (e) {
23534
23534
  process.stderr.write(`[lc-extractor] read failed for ${absPath}: ${e instanceof Error ? e.message : String(e)}
23535
23535
  `);
@@ -24563,18 +24563,18 @@ function collectUiLabels(root) {
24563
24563
  visit(root);
24564
24564
  return out;
24565
24565
  }
24566
- var import_node_fs17, import_node_path22, tsxLanguage, parserInstance, TreeSitterCtor, initPromise, initialized, queriesDir, queryCache, MAX_PARSEABLE_BYTES, MAX_CONSECUTIVE_PARSE_FAILURES, consecutiveParseFailures, ParseCascadeError, PRISMA_MUTATION_METHODS_BUILTIN, SUPABASE_MUTATION_METHODS_BUILTIN, DB_IDENTIFIERS_FALLBACK, extraDbIdentifiers, extraMutationMethods, INLINE_AUTH_IMPORTS, EXEMPT_NAME_PATTERNS, PROTECT_NAME_PATTERNS, TRUST_AS_PROTECT_KEYS, TIMER_FNS, DOM_METHOD_NAMES, CLASSLIST_METHODS, STORAGE_OBJECTS, HISTORY_METHODS, LOCATION_METHODS, ASSIGN_DOM_PROPS, UI_LABEL_KEYS, UI_LABELS_MAX, NOTE_REGEX, NOTES_MAX;
24566
+ var import_node_fs18, import_node_path23, tsxLanguage, parserInstance, TreeSitterCtor, initPromise, initialized, queriesDir, queryCache, MAX_PARSEABLE_BYTES, MAX_CONSECUTIVE_PARSE_FAILURES, consecutiveParseFailures, ParseCascadeError, PRISMA_MUTATION_METHODS_BUILTIN, SUPABASE_MUTATION_METHODS_BUILTIN, DB_IDENTIFIERS_FALLBACK, extraDbIdentifiers, extraMutationMethods, INLINE_AUTH_IMPORTS, EXEMPT_NAME_PATTERNS, PROTECT_NAME_PATTERNS, TRUST_AS_PROTECT_KEYS, TIMER_FNS, DOM_METHOD_NAMES, CLASSLIST_METHODS, STORAGE_OBJECTS, HISTORY_METHODS, LOCATION_METHODS, ASSIGN_DOM_PROPS, UI_LABEL_KEYS, UI_LABELS_MAX, NOTE_REGEX, NOTES_MAX;
24567
24567
  var init_ts_extractor = __esm({
24568
24568
  "src/server/graph/core/ts-extractor.ts"() {
24569
24569
  "use strict";
24570
- import_node_fs17 = require("node:fs");
24571
- import_node_path22 = require("node:path");
24570
+ import_node_fs18 = require("node:fs");
24571
+ import_node_path23 = require("node:path");
24572
24572
  init_parse_failure_cache();
24573
24573
  initialized = false;
24574
24574
  queriesDir = (() => {
24575
- const srcPath = (0, import_node_path22.join)((0, import_node_path22.dirname)(__filename), "..", "queries");
24575
+ const srcPath = (0, import_node_path23.join)((0, import_node_path23.dirname)(__filename), "..", "queries");
24576
24576
  if (require("fs").existsSync(srcPath)) return srcPath;
24577
- return (0, import_node_path22.join)((0, import_node_path22.dirname)(__filename), "graph", "queries");
24577
+ return (0, import_node_path23.join)((0, import_node_path23.dirname)(__filename), "graph", "queries");
24578
24578
  })();
24579
24579
  queryCache = /* @__PURE__ */ new Map();
24580
24580
  MAX_PARSEABLE_BYTES = 2 * 1024 * 1024;
@@ -24714,7 +24714,7 @@ __export(watcher_exports, {
24714
24714
  function isIgnoredPath(rel) {
24715
24715
  if (rel.startsWith(GRAPHS_RELATIVE)) return true;
24716
24716
  if (rel.endsWith(".lock") || rel.endsWith(".log")) return true;
24717
- for (const part of rel.split(import_node_path37.sep)) {
24717
+ for (const part of rel.split(import_node_path38.sep)) {
24718
24718
  if (IGNORE_SEGMENTS.has(part)) return true;
24719
24719
  }
24720
24720
  return false;
@@ -24756,7 +24756,7 @@ function startGraphWatcher(rootDir, opts = {}) {
24756
24756
  regenerating = false;
24757
24757
  }
24758
24758
  }
24759
- const watcher = (0, import_node_fs29.watch)(rootDir, { recursive: true }, (event, filename) => {
24759
+ const watcher = (0, import_node_fs30.watch)(rootDir, { recursive: true }, (event, filename) => {
24760
24760
  if (!filename) return;
24761
24761
  const rel = filename.toString();
24762
24762
  if (process.env.LAUNCH_CHART_WATCH_TRACE === "1") {
@@ -24789,12 +24789,12 @@ function startGraphWatcher(rootDir, opts = {}) {
24789
24789
  freshness: () => getFreshnessTracker(rootDir).get()
24790
24790
  };
24791
24791
  }
24792
- var import_node_fs29, import_node_path37, IGNORE_SEGMENTS, TRIGGER_EXTENSIONS, GRAPHS_RELATIVE;
24792
+ var import_node_fs30, import_node_path38, IGNORE_SEGMENTS, TRIGGER_EXTENSIONS, GRAPHS_RELATIVE;
24793
24793
  var init_watcher = __esm({
24794
24794
  "src/server/graph/core/watcher.ts"() {
24795
24795
  "use strict";
24796
- import_node_fs29 = require("node:fs");
24797
- import_node_path37 = require("node:path");
24796
+ import_node_fs30 = require("node:fs");
24797
+ import_node_path38 = require("node:path");
24798
24798
  init_launch_kit_paths();
24799
24799
  init_graph();
24800
24800
  init_freshness();
@@ -24823,7 +24823,7 @@ var init_watcher = __esm({
24823
24823
  ".prisma",
24824
24824
  ".sql"
24825
24825
  ]);
24826
- GRAPHS_RELATIVE = (0, import_node_path37.join)(LAUNCHSECURE_DIR, "graphs");
24826
+ GRAPHS_RELATIVE = (0, import_node_path38.join)(LAUNCHSECURE_DIR, "graphs");
24827
24827
  }
24828
24828
  });
24829
24829
 
@@ -27836,6 +27836,34 @@ function openInBrowser(url) {
27836
27836
  }
27837
27837
  }
27838
27838
 
27839
+ // src/server/radar/credential-store.ts
27840
+ var import_node_fs = require("node:fs");
27841
+ var import_node_os2 = require("node:os");
27842
+ var import_node_path2 = require("node:path");
27843
+ function tokenPath() {
27844
+ const home = process.env.HOME ?? (0, import_node_os2.homedir)();
27845
+ return (0, import_node_path2.join)(home, ".claude", ".radar-oauth-token");
27846
+ }
27847
+ function persistOauthToken(token) {
27848
+ const path13 = tokenPath();
27849
+ (0, import_node_fs.mkdirSync)((0, import_node_path2.dirname)(path13), { recursive: true });
27850
+ (0, import_node_fs.writeFileSync)(path13, `${token.trim()}
27851
+ `, { mode: 384 });
27852
+ (0, import_node_fs.chmodSync)(path13, 384);
27853
+ }
27854
+ function loadPersistedOauthToken() {
27855
+ const path13 = tokenPath();
27856
+ if (!(0, import_node_fs.existsSync)(path13)) return false;
27857
+ try {
27858
+ const token = (0, import_node_fs.readFileSync)(path13, "utf8").trim();
27859
+ if (!token) return false;
27860
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = token;
27861
+ return true;
27862
+ } catch {
27863
+ return false;
27864
+ }
27865
+ }
27866
+
27839
27867
  // src/server/radar/mcp.ts
27840
27868
  var import_node_https = require("node:https");
27841
27869
  var import_node_http = require("node:http");
@@ -28403,8 +28431,8 @@ async function releaseRegistration(params) {
28403
28431
  }
28404
28432
 
28405
28433
  // src/server/radar/screenshot.ts
28406
- var import_node_fs = require("node:fs");
28407
- var import_node_path2 = require("node:path");
28434
+ var import_node_fs2 = require("node:fs");
28435
+ var import_node_path3 = require("node:path");
28408
28436
  init_launch_kit_paths();
28409
28437
  async function fetchScreenshotIfPresent(opts) {
28410
28438
  const { blobId, mcp, projectRoot } = opts;
@@ -28425,11 +28453,11 @@ async function fetchScreenshotIfPresent(opts) {
28425
28453
  return null;
28426
28454
  }
28427
28455
  const ext = payload.contentType?.includes("png") ? "png" : "jpg";
28428
- const dir = (0, import_node_path2.join)(projectRoot, LAUNCHPOD_DIR, "screenshots");
28429
- if (!(0, import_node_fs.existsSync)(dir)) (0, import_node_fs.mkdirSync)(dir, { recursive: true });
28430
- const localPath = (0, import_node_path2.join)(dir, `${blobId}.${ext}`);
28456
+ const dir = (0, import_node_path3.join)(projectRoot, LAUNCHPOD_DIR, "screenshots");
28457
+ if (!(0, import_node_fs2.existsSync)(dir)) (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
28458
+ const localPath = (0, import_node_path3.join)(dir, `${blobId}.${ext}`);
28431
28459
  try {
28432
- (0, import_node_fs.writeFileSync)(localPath, Buffer.from(payload.dataBase64, "base64"));
28460
+ (0, import_node_fs2.writeFileSync)(localPath, Buffer.from(payload.dataBase64, "base64"));
28433
28461
  } catch (err2) {
28434
28462
  const msg = err2 instanceof Error ? err2.message : String(err2);
28435
28463
  console.warn(`[radar] screenshot write failed (${blobId}): ${msg}`);
@@ -28439,30 +28467,30 @@ async function fetchScreenshotIfPresent(opts) {
28439
28467
  }
28440
28468
 
28441
28469
  // src/server/radar/state.ts
28442
- var import_node_fs2 = require("node:fs");
28443
- var import_node_path3 = require("node:path");
28470
+ var import_node_fs3 = require("node:fs");
28471
+ var import_node_path4 = require("node:path");
28444
28472
  init_launch_kit_paths();
28445
28473
  var MAX_DEDUPE_SET = 1e3;
28446
28474
  var MAX_PINGS = 200;
28447
28475
  function readJson(path13, fallback) {
28448
- if (!(0, import_node_fs2.existsSync)(path13)) return fallback;
28476
+ if (!(0, import_node_fs3.existsSync)(path13)) return fallback;
28449
28477
  try {
28450
- return JSON.parse((0, import_node_fs2.readFileSync)(path13, "utf-8"));
28478
+ return JSON.parse((0, import_node_fs3.readFileSync)(path13, "utf-8"));
28451
28479
  } catch {
28452
28480
  return fallback;
28453
28481
  }
28454
28482
  }
28455
28483
  function writeJsonAtomic(path13, value) {
28456
- (0, import_node_fs2.mkdirSync)((0, import_node_path3.dirname)(path13), { recursive: true });
28484
+ (0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(path13), { recursive: true });
28457
28485
  const tmp = `${path13}.tmp.${process.pid}.${Date.now()}`;
28458
- (0, import_node_fs2.writeFileSync)(tmp, JSON.stringify(value, null, 2), "utf-8");
28459
- (0, import_node_fs2.renameSync)(tmp, path13);
28486
+ (0, import_node_fs3.writeFileSync)(tmp, JSON.stringify(value, null, 2), "utf-8");
28487
+ (0, import_node_fs3.renameSync)(tmp, path13);
28460
28488
  }
28461
28489
  var RadarState = class {
28462
28490
  constructor(projectRoot) {
28463
- const dir = (0, import_node_path3.join)(projectRoot, LAUNCHPOD_DIR);
28464
- this.regPath = (0, import_node_path3.join)(dir, "radar.json");
28465
- this.pingsPath = (0, import_node_path3.join)(dir, "radar-pings.json");
28491
+ const dir = (0, import_node_path4.join)(projectRoot, LAUNCHPOD_DIR);
28492
+ this.regPath = (0, import_node_path4.join)(dir, "radar.json");
28493
+ this.pingsPath = (0, import_node_path4.join)(dir, "radar-pings.json");
28466
28494
  this.registration = readJson(this.regPath, null);
28467
28495
  this.pingsState = readJson(this.pingsPath, { seenActivityLogIds: [], pings: [] });
28468
28496
  this.migrateLoadedPings();
@@ -28501,9 +28529,9 @@ var RadarState = class {
28501
28529
  }
28502
28530
  clearRegistration() {
28503
28531
  this.registration = null;
28504
- if ((0, import_node_fs2.existsSync)(this.regPath)) {
28532
+ if ((0, import_node_fs3.existsSync)(this.regPath)) {
28505
28533
  try {
28506
- (0, import_node_fs2.unlinkSync)(this.regPath);
28534
+ (0, import_node_fs3.unlinkSync)(this.regPath);
28507
28535
  } catch {
28508
28536
  }
28509
28537
  }
@@ -28659,14 +28687,14 @@ var RadarState = class {
28659
28687
  };
28660
28688
 
28661
28689
  // src/server/tunnel/index.ts
28662
- var import_node_fs3 = require("node:fs");
28690
+ var import_node_fs4 = require("node:fs");
28663
28691
  var import_node_events = require("node:events");
28664
28692
  var import_promises = require("node:dns/promises");
28665
28693
 
28666
28694
  // ../../node_modules/.pnpm/cacheable-lookup@7.0.0/node_modules/cacheable-lookup/source/index.js
28667
28695
  var import_node_dns = require("node:dns");
28668
28696
  var import_node_util = require("node:util");
28669
- var import_node_os2 = __toESM(require("node:os"), 1);
28697
+ var import_node_os3 = __toESM(require("node:os"), 1);
28670
28698
  var { Resolver: AsyncResolver } = import_node_dns.promises;
28671
28699
  var kCacheableLookupCreateConnection = /* @__PURE__ */ Symbol("cacheableLookupCreateConnection");
28672
28700
  var kCacheableLookupInstance = /* @__PURE__ */ Symbol("cacheableLookupInstance");
@@ -28689,7 +28717,7 @@ var map4to6 = (entries) => {
28689
28717
  var getIfaceInfo = () => {
28690
28718
  let has4 = false;
28691
28719
  let has6 = false;
28692
- for (const device of Object.values(import_node_os2.default.networkInterfaces())) {
28720
+ for (const device of Object.values(import_node_os3.default.networkInterfaces())) {
28693
28721
  for (const iface of device) {
28694
28722
  if (iface.internal) {
28695
28723
  continue;
@@ -29072,7 +29100,7 @@ var CloudflaredTunnel = class extends import_node_events.EventEmitter {
29072
29100
  }
29073
29101
  async start() {
29074
29102
  if (this.tunnel) return;
29075
- if (!(0, import_node_fs3.existsSync)(import_cloudflared.bin)) {
29103
+ if (!(0, import_node_fs4.existsSync)(import_cloudflared.bin)) {
29076
29104
  console.log("[tunnel] downloading cloudflared binary (one-time setup)\u2026");
29077
29105
  try {
29078
29106
  await (0, import_cloudflared.install)(import_cloudflared.bin);
@@ -29307,6 +29335,9 @@ var Radar = class _Radar {
29307
29335
  start() {
29308
29336
  this.status = "tunneling";
29309
29337
  console.log("[radar] starting cloudflared tunnel\u2026");
29338
+ if (loadPersistedOauthToken()) {
29339
+ console.log("[radar] applied persisted Claude token saved from a previous Config update");
29340
+ }
29310
29341
  this.preflightAuth();
29311
29342
  this.tunnel.on("ready", (publicUrl) => {
29312
29343
  void this.handleTunnelReady(publicUrl);
@@ -29814,32 +29845,88 @@ var Radar = class _Radar {
29814
29845
  if (firstHit) console.error(`[radar] \u2717 auth failure \u2014 ${detail}`);
29815
29846
  this.broadcastStatus();
29816
29847
  }
29848
+ /**
29849
+ * Run a single non-interactive Claude turn and classify the outcome.
29850
+ * - rejected: 401 / invalid creds / login prompt → the token is dead.
29851
+ * - inconclusive: binary missing, network, timeout → don't judge the token.
29852
+ * - ok: credential accepted.
29853
+ * `envOverride` is layered over process.env for the spawned child — used to
29854
+ * trial a candidate token before committing it. NB: must NOT use `--bare` —
29855
+ * bare mode ignores CLAUDE_CODE_OAUTH_TOKEN.
29856
+ */
29857
+ probeClaudeAuth(envOverride) {
29858
+ return new Promise((resolve7) => {
29859
+ const child = (0, import_node_child_process2.execFile)(
29860
+ "claude",
29861
+ ["-p", "Reply with: ok", "--max-turns", "1"],
29862
+ { timeout: 6e4, maxBuffer: 1 << 20, env: envOverride ? { ...process.env, ...envOverride } : process.env },
29863
+ (err2, stdout, stderr) => {
29864
+ const out = `${stdout ?? ""}
29865
+ ${stderr ?? ""}`;
29866
+ if (/Please run \/login|Invalid authentication credentials|API Error: 401/i.test(out)) {
29867
+ resolve7({ ok: false, rejected: true, detail: "Claude credential rejected (401)." });
29868
+ } else if (err2 && /timed out|ETIMEDOUT/i.test(String(err2))) {
29869
+ resolve7({ ok: false, rejected: false, detail: "verification timed out." });
29870
+ } else if (err2) {
29871
+ resolve7({ ok: false, rejected: false, detail: err2.message });
29872
+ } else {
29873
+ resolve7({ ok: true, rejected: false, detail: "ok" });
29874
+ }
29875
+ }
29876
+ );
29877
+ child.on("error", (e) => resolve7({ ok: false, rejected: false, detail: `could not spawn claude: ${e.message}` }));
29878
+ });
29879
+ }
29817
29880
  /**
29818
29881
  * Best-effort credential probe at boot. Catches a dead token immediately
29819
29882
  * (raises the banner) instead of only discovering it when the first real ping
29820
29883
  * fails — the failure mode that can leave a pod silently broken for days. Runs
29821
29884
  * a single non-interactive turn. Opt out with RADAR_SKIP_AUTH_PREFLIGHT=1.
29822
- * NB: must NOT use `--bare` — bare mode ignores CLAUDE_CODE_OAUTH_TOKEN.
29823
29885
  */
29824
29886
  preflightAuth() {
29825
29887
  if (process.env.RADAR_SKIP_AUTH_PREFLIGHT === "1") return;
29826
- const child = (0, import_node_child_process2.execFile)(
29827
- "claude",
29828
- ["-p", "Reply with: ok", "--max-turns", "1"],
29829
- { timeout: 6e4, maxBuffer: 1 << 20 },
29830
- (err2, stdout, stderr) => {
29831
- const out = `${stdout ?? ""}
29832
- ${stderr ?? ""}`;
29833
- if (/Please run \/login|Invalid authentication credentials|API Error: 401/i.test(out)) {
29834
- this.flagAuthErrorBanner("Boot credential check failed \u2014 Claude credential rejected (401). Regenerate the pod's Claude credentials and restart the pod.");
29835
- } else if (err2 && !/timed out|ETIMEDOUT/i.test(String(err2))) {
29836
- console.warn(`[radar] auth preflight inconclusive: ${err2.message}`);
29837
- } else if (!err2) {
29838
- console.log("[radar] \u2713 auth preflight passed");
29839
- }
29888
+ void this.probeClaudeAuth().then((r) => {
29889
+ if (r.rejected) {
29890
+ this.flagAuthErrorBanner("Boot credential check failed \u2014 Claude credential rejected (401). Paste a fresh token in Config (gear icon) to fix it without a redeploy, or regenerate the pod's credentials.");
29891
+ } else if (!r.ok) {
29892
+ console.warn(`[radar] auth preflight inconclusive: ${r.detail}`);
29893
+ } else {
29894
+ console.log("[radar] \u2713 auth preflight passed");
29840
29895
  }
29841
- );
29842
- child.on("error", (e) => console.warn(`[radar] auth preflight could not spawn claude: ${e.message}`));
29896
+ });
29897
+ }
29898
+ /**
29899
+ * Operator pasted a fresh long-lived CLAUDE_CODE_OAUTH_TOKEN in the Config
29900
+ * screen. Validate it with a live probe BEFORE committing anything, then:
29901
+ * - set process.env so every subsequent `claude` spawn (analyzers, the next
29902
+ * preflight) uses it immediately — no restart, because claude reads the
29903
+ * env on each run;
29904
+ * - persist it to the pod's persistent store so it survives a redeploy;
29905
+ * - clear the auth banner.
29906
+ * Returns {ok:false} WITHOUT changing anything if the token is rejected, so a
29907
+ * bad paste can't replace a working (or recoverable) credential.
29908
+ */
29909
+ async updateClaudeCredential(rawToken) {
29910
+ const token = rawToken.trim();
29911
+ if (!token) return { ok: false, error: "Token is empty." };
29912
+ const probe = await this.probeClaudeAuth({ CLAUDE_CODE_OAUTH_TOKEN: token });
29913
+ if (probe.rejected) {
29914
+ return { ok: false, error: "Claude rejected this token (401). Paste a fresh one from `claude setup-token`." };
29915
+ }
29916
+ if (!probe.ok) {
29917
+ return { ok: false, error: `Could not verify the token \u2014 ${probe.detail} Nothing was changed.` };
29918
+ }
29919
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = token;
29920
+ try {
29921
+ persistOauthToken(token);
29922
+ } catch (err2) {
29923
+ console.warn(`[radar] token applied live but persist failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
29924
+ this.clearAuthErrorOnRecovery();
29925
+ return { ok: true, error: "Applied for now, but saving it for redeploys failed \u2014 check pod storage permissions." };
29926
+ }
29927
+ console.log("[radar] \u2713 Claude token updated via Config \u2014 applied live and persisted");
29928
+ this.clearAuthErrorOnRecovery();
29929
+ return { ok: true };
29843
29930
  }
29844
29931
  /**
29845
29932
  * A later session authenticated successfully (it produced a summary), so any
@@ -29878,14 +29965,14 @@ function sameStringSet(a, b) {
29878
29965
  }
29879
29966
 
29880
29967
  // src/server/radar/transcript-reader.ts
29881
- var import_node_fs4 = require("node:fs");
29882
- var import_node_os3 = __toESM(require("node:os"));
29883
- var import_node_path4 = __toESM(require("node:path"));
29968
+ var import_node_fs5 = require("node:fs");
29969
+ var import_node_os4 = __toESM(require("node:os"));
29970
+ var import_node_path5 = __toESM(require("node:path"));
29884
29971
  function flattenCwd(absCwd) {
29885
29972
  return absCwd.replace(/\//g, "-");
29886
29973
  }
29887
29974
  function getJsonlPath(projectDir, sessionId) {
29888
- return import_node_path4.default.join(import_node_os3.default.homedir(), ".claude", "projects", flattenCwd(projectDir), `${sessionId}.jsonl`);
29975
+ return import_node_path5.default.join(import_node_os4.default.homedir(), ".claude", "projects", flattenCwd(projectDir), `${sessionId}.jsonl`);
29889
29976
  }
29890
29977
  var RENDERABLE_TYPES = /* @__PURE__ */ new Set(["user", "assistant", "system"]);
29891
29978
  function parseMetaLine(raw) {
@@ -30002,7 +30089,7 @@ function streamTranscript(opts) {
30002
30089
  const tick = async () => {
30003
30090
  if (cancelled) return;
30004
30091
  try {
30005
- const stat = await import_node_fs4.promises.stat(filePath).catch(() => null);
30092
+ const stat = await import_node_fs5.promises.stat(filePath).catch(() => null);
30006
30093
  if (!stat) {
30007
30094
  if (!waitingNotified) {
30008
30095
  waitingNotified = true;
@@ -30017,7 +30104,7 @@ function streamTranscript(opts) {
30017
30104
  }
30018
30105
  const jsonlGrew = stat.size > offset;
30019
30106
  if (jsonlGrew) {
30020
- const fh = await import_node_fs4.promises.open(filePath, "r");
30107
+ const fh = await import_node_fs5.promises.open(filePath, "r");
30021
30108
  try {
30022
30109
  const len = stat.size - offset;
30023
30110
  const buf = Buffer.alloc(len);
@@ -30077,10 +30164,10 @@ function streamTranscript(opts) {
30077
30164
  }
30078
30165
 
30079
30166
  // src/server/graph-mcp.ts
30080
- var import_node_fs30 = require("node:fs");
30081
- var import_node_path38 = require("node:path");
30167
+ var import_node_fs31 = require("node:fs");
30168
+ var import_node_path39 = require("node:path");
30082
30169
  var import_node_child_process4 = require("node:child_process");
30083
- var import_node_os6 = require("node:os");
30170
+ var import_node_os7 = require("node:os");
30084
30171
  init_launch_kit_paths();
30085
30172
  init_graph();
30086
30173
 
@@ -30118,8 +30205,8 @@ export const ${exportName} = {
30118
30205
  }
30119
30206
 
30120
30207
  // src/server/graph/core/context/snippet-registry.ts
30121
- var import_node_fs13 = require("node:fs");
30122
- var import_node_path17 = require("node:path");
30208
+ var import_node_fs14 = require("node:fs");
30209
+ var import_node_path18 = require("node:path");
30123
30210
  var DEFAULT_SNIPPETS_DIR = "tests/snippets";
30124
30211
  function parseStringArray(src, key) {
30125
30212
  const m = src.match(new RegExp(`${key}\\s*:\\s*\\[([^\\]]*)\\]`));
@@ -30140,15 +30227,15 @@ function parseSnippetFile(content, file) {
30140
30227
  };
30141
30228
  }
30142
30229
  function loadSnippetIndex(rootDir, snippetsDir = DEFAULT_SNIPPETS_DIR) {
30143
- const dir = (0, import_node_path17.join)(rootDir, snippetsDir);
30230
+ const dir = (0, import_node_path18.join)(rootDir, snippetsDir);
30144
30231
  const index = /* @__PURE__ */ new Map();
30145
- if (!(0, import_node_fs13.existsSync)(dir)) return index;
30146
- for (const f of (0, import_node_fs13.readdirSync)(dir)) {
30232
+ if (!(0, import_node_fs14.existsSync)(dir)) return index;
30233
+ for (const f of (0, import_node_fs14.readdirSync)(dir)) {
30147
30234
  if (!f.endsWith(".ts") && !f.endsWith(".tsx")) continue;
30148
- const full = (0, import_node_path17.join)(dir, f);
30235
+ const full = (0, import_node_path18.join)(dir, f);
30149
30236
  try {
30150
- if (!(0, import_node_fs13.statSync)(full).isFile()) continue;
30151
- const entry = parseSnippetFile((0, import_node_fs13.readFileSync)(full, "utf-8"), (0, import_node_path17.join)(snippetsDir, f));
30237
+ if (!(0, import_node_fs14.statSync)(full).isFile()) continue;
30238
+ const entry = parseSnippetFile((0, import_node_fs14.readFileSync)(full, "utf-8"), (0, import_node_path18.join)(snippetsDir, f));
30152
30239
  if (entry) index.set(entry.id, entry);
30153
30240
  } catch {
30154
30241
  }
@@ -30229,7 +30316,7 @@ function buildTestPlan(graph, targetId, snippets) {
30229
30316
  }
30230
30317
 
30231
30318
  // src/server/graph/core/context/spec-gen.ts
30232
- var import_node_path18 = require("node:path");
30319
+ var import_node_path19 = require("node:path");
30233
30320
  function toEnvRef(name) {
30234
30321
  return `process.env.${name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase()}`;
30235
30322
  }
@@ -30246,7 +30333,7 @@ function classify(name) {
30246
30333
  return { kind: "faker", faker: "faker.lorem.word()" };
30247
30334
  }
30248
30335
  function relImport(specDir, file) {
30249
- let r = (0, import_node_path18.relative)(specDir, file).replace(/\.tsx?$/, "");
30336
+ let r = (0, import_node_path19.relative)(specDir, file).replace(/\.tsx?$/, "");
30250
30337
  if (!r.startsWith(".")) r = `./${r}`;
30251
30338
  return r;
30252
30339
  }
@@ -30297,29 +30384,29 @@ ${[...warnings, ...callLines].join("\n")}
30297
30384
 
30298
30385
  // src/server/lockfile.ts
30299
30386
  var import_node_child_process3 = require("node:child_process");
30300
- var import_node_fs14 = require("node:fs");
30301
- var import_node_os4 = require("node:os");
30302
- var import_node_path19 = require("node:path");
30387
+ var import_node_fs15 = require("node:fs");
30388
+ var import_node_os5 = require("node:os");
30389
+ var import_node_path20 = require("node:path");
30303
30390
  init_launch_kit_paths();
30304
30391
  function lockDir(projectRoot) {
30305
30392
  if (projectRoot) {
30306
- return (0, import_node_path19.join)(projectRoot, LAUNCHSECURE_DIR);
30393
+ return (0, import_node_path20.join)(projectRoot, LAUNCHSECURE_DIR);
30307
30394
  }
30308
- return (0, import_node_path19.join)((0, import_node_os4.homedir)(), LAUNCHSECURE_DIR);
30395
+ return (0, import_node_path20.join)((0, import_node_os5.homedir)(), LAUNCHSECURE_DIR);
30309
30396
  }
30310
30397
  function lockPath(projectRoot) {
30311
- return (0, import_node_path19.join)(lockDir(projectRoot), "launch-chart.lock");
30398
+ return (0, import_node_path20.join)(lockDir(projectRoot), "launch-chart.lock");
30312
30399
  }
30313
30400
  var _activeProjectRoot;
30314
30401
  function readLock(projectRoot) {
30315
30402
  const root = projectRoot ?? _activeProjectRoot;
30316
30403
  const p = lockPath(root);
30317
- if (!(0, import_node_fs14.existsSync)(p)) {
30404
+ if (!(0, import_node_fs15.existsSync)(p)) {
30318
30405
  if (root) {
30319
30406
  const globalP = lockPath();
30320
- if ((0, import_node_fs14.existsSync)(globalP)) {
30407
+ if ((0, import_node_fs15.existsSync)(globalP)) {
30321
30408
  try {
30322
- const data = JSON.parse((0, import_node_fs14.readFileSync)(globalP, "utf-8"));
30409
+ const data = JSON.parse((0, import_node_fs15.readFileSync)(globalP, "utf-8"));
30323
30410
  if (typeof data.pid === "number" && typeof data.port === "number" && data.cwd === root) {
30324
30411
  return data;
30325
30412
  }
@@ -30330,7 +30417,7 @@ function readLock(projectRoot) {
30330
30417
  return null;
30331
30418
  }
30332
30419
  try {
30333
- const data = JSON.parse((0, import_node_fs14.readFileSync)(p, "utf-8"));
30420
+ const data = JSON.parse((0, import_node_fs15.readFileSync)(p, "utf-8"));
30334
30421
  if (typeof data.pid !== "number" || typeof data.port !== "number") return null;
30335
30422
  return data;
30336
30423
  } catch {
@@ -30367,7 +30454,7 @@ function getLiveLock(projectRoot) {
30367
30454
  const live = listenerPid !== null ? listenerPid === lock.pid : isPidAlive(lock.pid);
30368
30455
  if (!live) {
30369
30456
  try {
30370
- (0, import_node_fs14.unlinkSync)(lockPath(root));
30457
+ (0, import_node_fs15.unlinkSync)(lockPath(root));
30371
30458
  } catch {
30372
30459
  }
30373
30460
  return null;
@@ -30377,7 +30464,7 @@ function getLiveLock(projectRoot) {
30377
30464
  function clearLock(projectRoot) {
30378
30465
  const root = projectRoot ?? _activeProjectRoot;
30379
30466
  try {
30380
- (0, import_node_fs14.unlinkSync)(lockPath(root));
30467
+ (0, import_node_fs15.unlinkSync)(lockPath(root));
30381
30468
  } catch {
30382
30469
  }
30383
30470
  }
@@ -30386,20 +30473,20 @@ function clearLock(projectRoot) {
30386
30473
  init_config();
30387
30474
 
30388
30475
  // src/server/graph/core/parser-registry.ts
30389
- var import_node_path30 = require("node:path");
30476
+ var import_node_path31 = require("node:path");
30390
30477
 
30391
30478
  // src/server/graph/parsers/ts/typescript-project.ts
30392
- var import_node_fs18 = require("node:fs");
30393
- var import_node_path23 = require("node:path");
30479
+ var import_node_fs19 = require("node:fs");
30480
+ var import_node_path24 = require("node:path");
30394
30481
  init_config();
30395
30482
 
30396
30483
  // src/server/graph/core/resolve-paths.ts
30397
- var import_node_fs16 = require("node:fs");
30398
- var import_node_path21 = require("node:path");
30484
+ var import_node_fs17 = require("node:fs");
30485
+ var import_node_path22 = require("node:path");
30399
30486
 
30400
30487
  // src/server/graph/core/walk.ts
30401
- var import_node_fs15 = require("node:fs");
30402
- var import_node_path20 = require("node:path");
30488
+ var import_node_fs16 = require("node:fs");
30489
+ var import_node_path21 = require("node:path");
30403
30490
  var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
30404
30491
  "node_modules",
30405
30492
  "dist",
@@ -30409,12 +30496,12 @@ var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
30409
30496
  ]);
30410
30497
  function walk(dir, exts) {
30411
30498
  const results = [];
30412
- if (!(0, import_node_fs15.existsSync)(dir)) return results;
30413
- for (const entry of (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true })) {
30414
- const full = (0, import_node_path20.join)(dir, entry.name);
30499
+ if (!(0, import_node_fs16.existsSync)(dir)) return results;
30500
+ for (const entry of (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true })) {
30501
+ const full = (0, import_node_path21.join)(dir, entry.name);
30415
30502
  if (entry.isDirectory()) {
30416
30503
  results.push(...walk(full, exts));
30417
- } else if (exts.includes((0, import_node_path20.extname)(entry.name))) {
30504
+ } else if (exts.includes((0, import_node_path21.extname)(entry.name))) {
30418
30505
  results.push(full);
30419
30506
  }
30420
30507
  }
@@ -30422,15 +30509,15 @@ function walk(dir, exts) {
30422
30509
  }
30423
30510
  function walkWithIgnore(dir, exts, opts = {}) {
30424
30511
  const results = [];
30425
- if (!(0, import_node_fs15.existsSync)(dir)) return results;
30512
+ if (!(0, import_node_fs16.existsSync)(dir)) return results;
30426
30513
  const skip = opts.extraIgnore ? /* @__PURE__ */ new Set([...DEFAULT_IGNORE_DIRS, ...opts.extraIgnore]) : DEFAULT_IGNORE_DIRS;
30427
- for (const entry of (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true })) {
30514
+ for (const entry of (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true })) {
30428
30515
  if (entry.isDirectory()) {
30429
30516
  if (entry.name.startsWith(".")) continue;
30430
30517
  if (skip.has(entry.name)) continue;
30431
- results.push(...walkWithIgnore((0, import_node_path20.join)(dir, entry.name), exts, opts));
30432
- } else if (exts.includes((0, import_node_path20.extname)(entry.name))) {
30433
- results.push((0, import_node_path20.join)(dir, entry.name));
30518
+ results.push(...walkWithIgnore((0, import_node_path21.join)(dir, entry.name), exts, opts));
30519
+ } else if (exts.includes((0, import_node_path21.extname)(entry.name))) {
30520
+ results.push((0, import_node_path21.join)(dir, entry.name));
30434
30521
  }
30435
30522
  }
30436
30523
  return results;
@@ -30438,9 +30525,9 @@ function walkWithIgnore(dir, exts, opts = {}) {
30438
30525
 
30439
30526
  // src/server/graph/core/resolve-paths.ts
30440
30527
  function hasSqlFiles(dir) {
30441
- if (!(0, import_node_fs16.existsSync)(dir)) return false;
30528
+ if (!(0, import_node_fs17.existsSync)(dir)) return false;
30442
30529
  try {
30443
- return (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true }).some(
30530
+ return (0, import_node_fs17.readdirSync)(dir, { withFileTypes: true }).some(
30444
30531
  (e) => e.isFile() && e.name.endsWith(".sql")
30445
30532
  );
30446
30533
  } catch {
@@ -30448,27 +30535,27 @@ function hasSqlFiles(dir) {
30448
30535
  }
30449
30536
  }
30450
30537
  function hasNestedMigrationSql(dir) {
30451
- if (!(0, import_node_fs16.existsSync)(dir)) return false;
30538
+ if (!(0, import_node_fs17.existsSync)(dir)) return false;
30452
30539
  try {
30453
- return (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true }).some(
30454
- (e) => e.isDirectory() && (0, import_node_fs16.existsSync)((0, import_node_path21.join)(dir, e.name, "migration.sql"))
30540
+ return (0, import_node_fs17.readdirSync)(dir, { withFileTypes: true }).some(
30541
+ (e) => e.isDirectory() && (0, import_node_fs17.existsSync)((0, import_node_path22.join)(dir, e.name, "migration.sql"))
30455
30542
  );
30456
30543
  } catch {
30457
30544
  return false;
30458
30545
  }
30459
30546
  }
30460
30547
  function resolveDbFromDir(dir) {
30461
- if (!(0, import_node_fs16.existsSync)(dir)) return { kind: "none", schemaPath: null, migrationsDir: null };
30462
- const schemaPath = (0, import_node_path21.join)(dir, "schema.prisma");
30463
- if ((0, import_node_fs16.existsSync)(schemaPath)) {
30464
- const migrationsDir2 = (0, import_node_path21.join)(dir, "migrations");
30548
+ if (!(0, import_node_fs17.existsSync)(dir)) return { kind: "none", schemaPath: null, migrationsDir: null };
30549
+ const schemaPath = (0, import_node_path22.join)(dir, "schema.prisma");
30550
+ if ((0, import_node_fs17.existsSync)(schemaPath)) {
30551
+ const migrationsDir2 = (0, import_node_path22.join)(dir, "migrations");
30465
30552
  return {
30466
30553
  kind: "prisma",
30467
30554
  schemaPath,
30468
- migrationsDir: (0, import_node_fs16.existsSync)(migrationsDir2) ? migrationsDir2 : null
30555
+ migrationsDir: (0, import_node_fs17.existsSync)(migrationsDir2) ? migrationsDir2 : null
30469
30556
  };
30470
30557
  }
30471
- const migrationsDir = (0, import_node_path21.join)(dir, "migrations");
30558
+ const migrationsDir = (0, import_node_path22.join)(dir, "migrations");
30472
30559
  if (hasSqlFiles(migrationsDir) || hasNestedMigrationSql(migrationsDir)) {
30473
30560
  return { kind: "sql-migrations", migrationsDir, schemaPath: null };
30474
30561
  }
@@ -30479,19 +30566,19 @@ function resolveDbFromDir(dir) {
30479
30566
  }
30480
30567
  function detectDbConfig(rootDir, config) {
30481
30568
  if (config.paths?.dbDir) {
30482
- return resolveDbFromDir((0, import_node_path21.join)(rootDir, config.paths.dbDir));
30569
+ return resolveDbFromDir((0, import_node_path22.join)(rootDir, config.paths.dbDir));
30483
30570
  }
30484
- const candidates = ["prisma", "supabase", "drizzle", (0, import_node_path21.join)("db", "migrations"), "migrations"];
30571
+ const candidates = ["prisma", "supabase", "drizzle", (0, import_node_path22.join)("db", "migrations"), "migrations"];
30485
30572
  for (const c of candidates) {
30486
- const dir = (0, import_node_path21.join)(rootDir, c);
30573
+ const dir = (0, import_node_path22.join)(rootDir, c);
30487
30574
  const resolved = resolveDbFromDir(dir);
30488
30575
  if (resolved.kind !== "none") return resolved;
30489
30576
  }
30490
30577
  return { kind: "none", schemaPath: null, migrationsDir: null };
30491
30578
  }
30492
30579
  function detectDbDir(rootDir, config, dbConfig) {
30493
- if (config.paths?.dbDir) return (0, import_node_path21.join)(rootDir, config.paths.dbDir);
30494
- if (dbConfig.kind === "prisma") return (0, import_node_path21.dirname)(dbConfig.schemaPath);
30580
+ if (config.paths?.dbDir) return (0, import_node_path22.join)(rootDir, config.paths.dbDir);
30581
+ if (dbConfig.kind === "prisma") return (0, import_node_path22.dirname)(dbConfig.schemaPath);
30495
30582
  if (dbConfig.kind === "sql-migrations") return dbConfig.migrationsDir;
30496
30583
  return null;
30497
30584
  }
@@ -30522,16 +30609,16 @@ var NON_SOURCE_DIRS = /* @__PURE__ */ new Set([
30522
30609
  "libs"
30523
30610
  ]);
30524
30611
  function dirHasTSFiles(dir) {
30525
- if (!(0, import_node_fs16.existsSync)(dir)) return false;
30612
+ if (!(0, import_node_fs17.existsSync)(dir)) return false;
30526
30613
  try {
30527
30614
  const stack = [dir];
30528
30615
  while (stack.length > 0) {
30529
30616
  const cur = stack.pop();
30530
- const entries = (0, import_node_fs16.readdirSync)(cur, { withFileTypes: true });
30617
+ const entries = (0, import_node_fs17.readdirSync)(cur, { withFileTypes: true });
30531
30618
  for (const e of entries) {
30532
30619
  if (e.isFile() && (e.name.endsWith(".ts") || e.name.endsWith(".tsx"))) return true;
30533
30620
  if (e.isDirectory() && !e.name.startsWith(".") && !DEFAULT_IGNORE_DIRS.has(e.name)) {
30534
- stack.push((0, import_node_path21.join)(cur, e.name));
30621
+ stack.push((0, import_node_path22.join)(cur, e.name));
30535
30622
  }
30536
30623
  }
30537
30624
  }
@@ -30540,15 +30627,15 @@ function dirHasTSFiles(dir) {
30540
30627
  return false;
30541
30628
  }
30542
30629
  function collectCodeBearingChildren(dir, extraSkip) {
30543
- if (!(0, import_node_fs16.existsSync)(dir)) return [];
30630
+ if (!(0, import_node_fs17.existsSync)(dir)) return [];
30544
30631
  const out = [];
30545
30632
  try {
30546
- for (const entry of (0, import_node_fs16.readdirSync)(dir, { withFileTypes: true })) {
30633
+ for (const entry of (0, import_node_fs17.readdirSync)(dir, { withFileTypes: true })) {
30547
30634
  if (!entry.isDirectory()) continue;
30548
30635
  if (entry.name.startsWith(".")) continue;
30549
30636
  if (NON_SOURCE_DIRS.has(entry.name)) continue;
30550
30637
  if (extraSkip?.has(entry.name)) continue;
30551
- const full = (0, import_node_path21.join)(dir, entry.name);
30638
+ const full = (0, import_node_path22.join)(dir, entry.name);
30552
30639
  if (dirHasTSFiles(full)) out.push(full);
30553
30640
  }
30554
30641
  } catch {
@@ -30560,7 +30647,7 @@ function detectSrcRoots(rootDir, srcDir, appDir, config) {
30560
30647
  const roots2 = /* @__PURE__ */ new Set();
30561
30648
  roots2.add(appDir);
30562
30649
  for (const r of config.paths.srcRoots) {
30563
- const abs = (0, import_node_path21.isAbsolute)(r) ? r : (0, import_node_path21.resolve)(rootDir, r);
30650
+ const abs = (0, import_node_path22.isAbsolute)(r) ? r : (0, import_node_path22.resolve)(rootDir, r);
30564
30651
  roots2.add(abs);
30565
30652
  }
30566
30653
  return [...roots2];
@@ -30569,7 +30656,7 @@ function detectSrcRoots(rootDir, srcDir, appDir, config) {
30569
30656
  roots.add(appDir);
30570
30657
  for (const c of collectCodeBearingChildren(srcDir)) roots.add(c);
30571
30658
  if (srcDir !== rootDir) {
30572
- const skipSrcWrapper = /* @__PURE__ */ new Set([(0, import_node_path21.basename)(srcDir)]);
30659
+ const skipSrcWrapper = /* @__PURE__ */ new Set([(0, import_node_path22.basename)(srcDir)]);
30573
30660
  for (const c of collectCodeBearingChildren(rootDir, skipSrcWrapper)) roots.add(c);
30574
30661
  }
30575
30662
  return [...roots];
@@ -30581,10 +30668,10 @@ function detectConventionFiles(rootDir, srcDir) {
30581
30668
  const dirs = srcDir === rootDir ? [rootDir] : [srcDir, rootDir];
30582
30669
  for (const dir of dirs) {
30583
30670
  for (const name of CONVENTION_NAMES) {
30584
- const full = (0, import_node_path21.join)(dir, name);
30585
- if (!seen.has(full) && (0, import_node_fs16.existsSync)(full)) {
30671
+ const full = (0, import_node_path22.join)(dir, name);
30672
+ if (!seen.has(full) && (0, import_node_fs17.existsSync)(full)) {
30586
30673
  try {
30587
- if ((0, import_node_fs16.statSync)(full).isFile()) {
30674
+ if ((0, import_node_fs17.statSync)(full).isFile()) {
30588
30675
  seen.add(full);
30589
30676
  out.push(full);
30590
30677
  }
@@ -30599,22 +30686,22 @@ function resolveProjectPaths(rootDir, config) {
30599
30686
  let srcDir;
30600
30687
  let appDir;
30601
30688
  if (config.paths?.appDir) {
30602
- appDir = (0, import_node_path21.join)(rootDir, config.paths.appDir);
30603
- srcDir = config.paths.srcDir ? (0, import_node_path21.join)(rootDir, config.paths.srcDir) : (0, import_node_path21.dirname)(appDir);
30689
+ appDir = (0, import_node_path22.join)(rootDir, config.paths.appDir);
30690
+ srcDir = config.paths.srcDir ? (0, import_node_path22.join)(rootDir, config.paths.srcDir) : (0, import_node_path22.dirname)(appDir);
30604
30691
  } else {
30605
- const srcApp = (0, import_node_path21.join)(rootDir, "src", "app");
30606
- const rootApp = (0, import_node_path21.join)(rootDir, "app");
30607
- if ((0, import_node_fs16.existsSync)(srcApp)) {
30608
- srcDir = (0, import_node_path21.join)(rootDir, "src");
30692
+ const srcApp = (0, import_node_path22.join)(rootDir, "src", "app");
30693
+ const rootApp = (0, import_node_path22.join)(rootDir, "app");
30694
+ if ((0, import_node_fs17.existsSync)(srcApp)) {
30695
+ srcDir = (0, import_node_path22.join)(rootDir, "src");
30609
30696
  appDir = srcApp;
30610
- } else if ((0, import_node_fs16.existsSync)(rootApp)) {
30697
+ } else if ((0, import_node_fs17.existsSync)(rootApp)) {
30611
30698
  srcDir = rootDir;
30612
30699
  appDir = rootApp;
30613
30700
  } else {
30614
30701
  return null;
30615
30702
  }
30616
30703
  }
30617
- const apiDir = (0, import_node_path21.join)(appDir, "api");
30704
+ const apiDir = (0, import_node_path22.join)(appDir, "api");
30618
30705
  const dbConfig = detectDbConfig(rootDir, config);
30619
30706
  const dbDir = detectDbDir(rootDir, config, dbConfig);
30620
30707
  const srcRoots = detectSrcRoots(rootDir, srcDir, appDir, config);
@@ -30641,25 +30728,25 @@ var CLASSIFICATION_TO_LAYER = {
30641
30728
  external: "ui"
30642
30729
  };
30643
30730
  function toNodeId(srcDir, rootDir, absPath) {
30644
- const relFromSrc = (0, import_node_path23.relative)(srcDir, absPath).replace(/\\/g, "/");
30731
+ const relFromSrc = (0, import_node_path24.relative)(srcDir, absPath).replace(/\\/g, "/");
30645
30732
  if (relFromSrc.startsWith("..")) {
30646
- return (0, import_node_path23.relative)(rootDir, absPath).replace(/\\/g, "/");
30733
+ return (0, import_node_path24.relative)(rootDir, absPath).replace(/\\/g, "/");
30647
30734
  }
30648
30735
  return relFromSrc;
30649
30736
  }
30650
30737
  function resolveImport(srcDir, specifier) {
30651
30738
  if (!specifier.startsWith("@/")) return null;
30652
30739
  const rel = specifier.slice(2);
30653
- const base = (0, import_node_path23.join)(srcDir, rel);
30654
- for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path23.join)(base, "index.ts"), (0, import_node_path23.join)(base, "index.tsx")]) {
30655
- if ((0, import_node_fs18.existsSync)(c) && (0, import_node_fs18.statSync)(c).isFile()) return c;
30740
+ const base = (0, import_node_path24.join)(srcDir, rel);
30741
+ for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path24.join)(base, "index.ts"), (0, import_node_path24.join)(base, "index.tsx")]) {
30742
+ if ((0, import_node_fs19.existsSync)(c) && (0, import_node_fs19.statSync)(c).isFile()) return c;
30656
30743
  }
30657
30744
  return null;
30658
30745
  }
30659
30746
  function resolveRelativeImport(fromFile, specifier) {
30660
- const base = (0, import_node_path23.join)((0, import_node_path23.dirname)(fromFile), specifier);
30661
- for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path23.join)(base, "index.ts"), (0, import_node_path23.join)(base, "index.tsx")]) {
30662
- if ((0, import_node_fs18.existsSync)(c) && (0, import_node_fs18.statSync)(c).isFile()) return c;
30747
+ const base = (0, import_node_path24.join)((0, import_node_path24.dirname)(fromFile), specifier);
30748
+ for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path24.join)(base, "index.ts"), (0, import_node_path24.join)(base, "index.tsx")]) {
30749
+ if ((0, import_node_fs19.existsSync)(c) && (0, import_node_fs19.statSync)(c).isFile()) return c;
30663
30750
  }
30664
30751
  return null;
30665
30752
  }
@@ -30680,7 +30767,7 @@ function resolveBarrelMap(barrelAbsPath, parsedByPath, memo, visiting) {
30680
30767
  const resolved = resolveRelativeImport(barrelAbsPath, re.from);
30681
30768
  if (!resolved) continue;
30682
30769
  if (re.isWildcard) {
30683
- const targetBn = (0, import_node_path23.basename)(resolved);
30770
+ const targetBn = (0, import_node_path24.basename)(resolved);
30684
30771
  const targetIsBarrel = targetBn === "index.ts" || targetBn === "index.tsx";
30685
30772
  if (targetIsBarrel) {
30686
30773
  const nested = resolveBarrelMap(resolved, parsedByPath, memo, visiting);
@@ -30707,12 +30794,12 @@ function buildAllBarrelMaps(srcDir, parsedByPath) {
30707
30794
  const barrels = /* @__PURE__ */ new Map();
30708
30795
  const memo = /* @__PURE__ */ new Map();
30709
30796
  for (const [absPath, parsed] of parsedByPath) {
30710
- const bn = (0, import_node_path23.basename)(absPath);
30797
+ const bn = (0, import_node_path24.basename)(absPath);
30711
30798
  if (bn !== "index.ts" && bn !== "index.tsx") continue;
30712
30799
  if (parsed.reExports.length === 0) continue;
30713
30800
  const map = resolveBarrelMap(absPath, parsedByPath, memo, /* @__PURE__ */ new Set());
30714
30801
  if (map.size > 0) {
30715
- const barrelId = (0, import_node_path23.relative)(srcDir, (0, import_node_path23.dirname)(absPath)).replace(/\\/g, "/");
30802
+ const barrelId = (0, import_node_path24.relative)(srcDir, (0, import_node_path24.dirname)(absPath)).replace(/\\/g, "/");
30716
30803
  barrels.set(barrelId, map);
30717
30804
  }
30718
30805
  }
@@ -30737,10 +30824,10 @@ function extractRoute(id) {
30737
30824
  return route || "/";
30738
30825
  }
30739
30826
  function nameFromFilename(absPath) {
30740
- return (0, import_node_path23.basename)(absPath, (0, import_node_path23.extname)(absPath)).replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^(\w)/, (_, c) => c.toUpperCase());
30827
+ return (0, import_node_path24.basename)(absPath, (0, import_node_path24.extname)(absPath)).replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^(\w)/, (_, c) => c.toUpperCase());
30741
30828
  }
30742
30829
  function filePathToAppRoute(appDir, absPath) {
30743
- let route = ("/" + (0, import_node_path23.relative)(appDir, absPath).replace(/\\/g, "/")).replace(/\/route\.tsx?$/, "");
30830
+ let route = ("/" + (0, import_node_path24.relative)(appDir, absPath).replace(/\\/g, "/")).replace(/\/route\.tsx?$/, "");
30744
30831
  route = route.replace(/\/\([^)]+\)/g, "");
30745
30832
  route = route.replace(/\[\[\.\.\.([^\]]+)\]\]/g, "*$1?");
30746
30833
  route = route.replace(/\[\.\.\.([^\]]+)\]/g, "*$1");
@@ -30988,7 +31075,7 @@ function generate(rootDir) {
30988
31075
  const apiNodes = [];
30989
31076
  const nodeIdSet = /* @__PURE__ */ new Set();
30990
31077
  const routeToNodeId = /* @__PURE__ */ new Map();
30991
- const fileSet = allDiscovered.filter((f) => !(0, import_node_path23.basename)(f).startsWith("index."));
31078
+ const fileSet = allDiscovered.filter((f) => !(0, import_node_path24.basename)(f).startsWith("index."));
30992
31079
  for (const absPath of fileSet) {
30993
31080
  const id = toNodeId(srcDir, rootDir, absPath);
30994
31081
  const type = classifyType(absPath, id);
@@ -31148,7 +31235,7 @@ function generate(rootDir) {
31148
31235
  } catch {
31149
31236
  continue;
31150
31237
  }
31151
- const externalId = (0, import_node_path23.relative)(rootDir, absPath).replace(/\\/g, "/");
31238
+ const externalId = (0, import_node_path24.relative)(rootDir, absPath).replace(/\\/g, "/");
31152
31239
  const edgesFromThis = [];
31153
31240
  const seen = /* @__PURE__ */ new Set();
31154
31241
  for (const imp of parsed.imports) {
@@ -31498,7 +31585,7 @@ var typescriptProjectParser = {
31498
31585
  };
31499
31586
 
31500
31587
  // src/server/graph/parsers/db/prisma-schema.ts
31501
- var import_node_fs19 = require("node:fs");
31588
+ var import_node_fs20 = require("node:fs");
31502
31589
  init_config();
31503
31590
  function parseModels(content) {
31504
31591
  const nodes = [];
@@ -31591,7 +31678,7 @@ function parseEnums(content) {
31591
31678
  }
31592
31679
  function detect2(rootDir) {
31593
31680
  const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
31594
- return paths?.dbConfig.kind === "prisma" && (0, import_node_fs19.existsSync)(paths.dbConfig.schemaPath);
31681
+ return paths?.dbConfig.kind === "prisma" && (0, import_node_fs20.existsSync)(paths.dbConfig.schemaPath);
31595
31682
  }
31596
31683
  function generate2(rootDir) {
31597
31684
  const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
@@ -31608,7 +31695,7 @@ function generate2(rootDir) {
31608
31695
  };
31609
31696
  }
31610
31697
  const schemaPath = paths.dbConfig.schemaPath;
31611
- const content = (0, import_node_fs19.readFileSync)(schemaPath, "utf-8");
31698
+ const content = (0, import_node_fs20.readFileSync)(schemaPath, "utf-8");
31612
31699
  const { nodes: modelNodes, relations } = parseModels(content);
31613
31700
  const enumNodes = parseEnums(content);
31614
31701
  const allNodes = [...modelNodes, ...enumNodes];
@@ -31665,8 +31752,8 @@ var prismaSchemaParser = {
31665
31752
  };
31666
31753
 
31667
31754
  // src/server/graph/parsers/db/sql-migrations.ts
31668
- var import_node_fs20 = require("node:fs");
31669
- var import_node_path24 = require("node:path");
31755
+ var import_node_fs21 = require("node:fs");
31756
+ var import_node_path25 = require("node:path");
31670
31757
  var import_pgsql_parser = require("pgsql-parser");
31671
31758
  init_config();
31672
31759
  var PG_TO_PRISMA = {
@@ -31700,15 +31787,15 @@ function pgTypeToPrisma(pgType) {
31700
31787
  return PG_TO_PRISMA[upper] ?? upper;
31701
31788
  }
31702
31789
  function discoverMigrationFiles(migrationsDir) {
31703
- if (!(0, import_node_fs20.existsSync)(migrationsDir)) return [];
31790
+ if (!(0, import_node_fs21.existsSync)(migrationsDir)) return [];
31704
31791
  const out = [];
31705
- const entries = (0, import_node_fs20.readdirSync)(migrationsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
31792
+ const entries = (0, import_node_fs21.readdirSync)(migrationsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
31706
31793
  for (const entry of entries) {
31707
31794
  if (entry.isDirectory()) {
31708
- const sqlPath = (0, import_node_path24.join)(migrationsDir, entry.name, "migration.sql");
31709
- if ((0, import_node_fs20.existsSync)(sqlPath)) out.push(sqlPath);
31795
+ const sqlPath = (0, import_node_path25.join)(migrationsDir, entry.name, "migration.sql");
31796
+ if ((0, import_node_fs21.existsSync)(sqlPath)) out.push(sqlPath);
31710
31797
  } else if (entry.isFile() && entry.name.endsWith(".sql")) {
31711
- out.push((0, import_node_path24.join)(migrationsDir, entry.name));
31798
+ out.push((0, import_node_path25.join)(migrationsDir, entry.name));
31712
31799
  }
31713
31800
  }
31714
31801
  return out;
@@ -31753,7 +31840,7 @@ function parseMigrations(migrationsDir, dialect = postgresDialect) {
31753
31840
  };
31754
31841
  if (!migrationsDir) return state;
31755
31842
  for (const sqlPath of discoverMigrationFiles(migrationsDir)) {
31756
- const sql = (0, import_node_fs20.readFileSync)(sqlPath, "utf-8");
31843
+ const sql = (0, import_node_fs21.readFileSync)(sqlPath, "utf-8");
31757
31844
  let ast;
31758
31845
  try {
31759
31846
  ast = dialect.parse(sql);
@@ -32322,8 +32409,8 @@ function indexIsPrismaUncoverable(idx) {
32322
32409
  return idx.hasPredicate || idx.hasExpressions || idx.method !== "btree";
32323
32410
  }
32324
32411
  function loadPrismaState(schemaPath) {
32325
- if (!schemaPath || !(0, import_node_fs20.existsSync)(schemaPath)) return null;
32326
- const content = (0, import_node_fs20.readFileSync)(schemaPath, "utf-8");
32412
+ if (!schemaPath || !(0, import_node_fs21.existsSync)(schemaPath)) return null;
32413
+ const content = (0, import_node_fs21.readFileSync)(schemaPath, "utf-8");
32327
32414
  const tables = /* @__PURE__ */ new Map();
32328
32415
  const enums = /* @__PURE__ */ new Map();
32329
32416
  const relations = [];
@@ -32730,7 +32817,7 @@ function generate3(rootDir) {
32730
32817
  const migrationFiles = migrationsDir ? discoverMigrationFiles(migrationsDir) : [];
32731
32818
  let migrationNodeCount = 0;
32732
32819
  for (const sqlPath of migrationFiles) {
32733
- const sql = (0, import_node_fs20.readFileSync)(sqlPath, "utf-8");
32820
+ const sql = (0, import_node_fs21.readFileSync)(sqlPath, "utf-8");
32734
32821
  const name = deriveMigrationName(sqlPath);
32735
32822
  let ast;
32736
32823
  try {
@@ -33048,14 +33135,14 @@ var fetchResolverParser = {
33048
33135
  };
33049
33136
 
33050
33137
  // src/server/graph/parsers/crosslayer/api-annotations.ts
33051
- var import_node_fs21 = require("node:fs");
33052
- var import_node_path25 = require("node:path");
33138
+ var import_node_fs22 = require("node:fs");
33139
+ var import_node_path26 = require("node:path");
33053
33140
  init_config();
33054
33141
  var API_ANNOTATION_RE = /@api\s+(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+(\/\S+)/g;
33055
33142
  function toNodeId2(srcDir, rootDir, absPath) {
33056
- const relFromSrc = (0, import_node_path25.relative)(srcDir, absPath).replace(/\\/g, "/");
33143
+ const relFromSrc = (0, import_node_path26.relative)(srcDir, absPath).replace(/\\/g, "/");
33057
33144
  if (relFromSrc.startsWith("..")) {
33058
- return (0, import_node_path25.relative)(rootDir, absPath).replace(/\\/g, "/");
33145
+ return (0, import_node_path26.relative)(rootDir, absPath).replace(/\\/g, "/");
33059
33146
  }
33060
33147
  return relFromSrc;
33061
33148
  }
@@ -33100,7 +33187,7 @@ var apiAnnotationsParser = {
33100
33187
  const flaggedEdges = [];
33101
33188
  const seenEdge = /* @__PURE__ */ new Set();
33102
33189
  for (const absPath of files) {
33103
- const content = (0, import_node_fs21.readFileSync)(absPath, "utf-8");
33190
+ const content = (0, import_node_fs22.readFileSync)(absPath, "utf-8");
33104
33191
  const sourceId = toNodeId2(srcDir, rootDir, absPath);
33105
33192
  if (!uiNodeIds.has(sourceId)) continue;
33106
33193
  let match;
@@ -33144,14 +33231,14 @@ var apiAnnotationsParser = {
33144
33231
  };
33145
33232
 
33146
33233
  // src/server/graph/parsers/crosslayer/url-literal-scanner.ts
33147
- var import_node_fs22 = require("node:fs");
33148
- var import_node_path26 = require("node:path");
33234
+ var import_node_fs23 = require("node:fs");
33235
+ var import_node_path27 = require("node:path");
33149
33236
  init_config();
33150
33237
  var URL_LITERAL_RE = /['"`](\/[a-zA-Z][^'"`\s]*?)['"`]/g;
33151
33238
  function toNodeId3(srcDir, rootDir, absPath) {
33152
- const relFromSrc = (0, import_node_path26.relative)(srcDir, absPath).replace(/\\/g, "/");
33239
+ const relFromSrc = (0, import_node_path27.relative)(srcDir, absPath).replace(/\\/g, "/");
33153
33240
  if (relFromSrc.startsWith("..")) {
33154
- return (0, import_node_path26.relative)(rootDir, absPath).replace(/\\/g, "/");
33241
+ return (0, import_node_path27.relative)(rootDir, absPath).replace(/\\/g, "/");
33155
33242
  }
33156
33243
  return relFromSrc;
33157
33244
  }
@@ -33195,7 +33282,7 @@ var urlLiteralScannerParser = {
33195
33282
  for (const absPath of files) {
33196
33283
  const sourceId = toNodeId3(srcDir, rootDir, absPath);
33197
33284
  if (!uiNodeIds.has(sourceId)) continue;
33198
- const content = (0, import_node_fs22.readFileSync)(absPath, "utf-8");
33285
+ const content = (0, import_node_fs23.readFileSync)(absPath, "utf-8");
33199
33286
  let match;
33200
33287
  URL_LITERAL_RE.lastIndex = 0;
33201
33288
  while ((match = URL_LITERAL_RE.exec(content)) !== null) {
@@ -33226,8 +33313,8 @@ var urlLiteralScannerParser = {
33226
33313
  };
33227
33314
 
33228
33315
  // src/server/graph/parsers/static/static-values.ts
33229
- var import_node_fs23 = require("node:fs");
33230
- var import_node_path27 = require("node:path");
33316
+ var import_node_fs24 = require("node:fs");
33317
+ var import_node_path28 = require("node:path");
33231
33318
  init_config();
33232
33319
  var parseCode = null;
33233
33320
  function tryLoadTreeSitter() {
@@ -33264,21 +33351,21 @@ function extractEnumValues(rootDir) {
33264
33351
  const schemaPaths = [];
33265
33352
  if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath) {
33266
33353
  schemaPaths.push(paths.dbConfig.schemaPath);
33267
- schemaPaths.push((0, import_node_path27.join)((0, import_node_path27.dirname)(paths.dbConfig.schemaPath), "schema"));
33354
+ schemaPaths.push((0, import_node_path28.join)((0, import_node_path28.dirname)(paths.dbConfig.schemaPath), "schema"));
33268
33355
  } else {
33269
- schemaPaths.push((0, import_node_path27.join)(rootDir, "prisma", "schema.prisma"));
33270
- schemaPaths.push((0, import_node_path27.join)(rootDir, "prisma", "schema"));
33356
+ schemaPaths.push((0, import_node_path28.join)(rootDir, "prisma", "schema.prisma"));
33357
+ schemaPaths.push((0, import_node_path28.join)(rootDir, "prisma", "schema"));
33271
33358
  }
33272
33359
  let content = "";
33273
33360
  for (const p of schemaPaths) {
33274
- if ((0, import_node_fs23.existsSync)(p)) {
33361
+ if ((0, import_node_fs24.existsSync)(p)) {
33275
33362
  try {
33276
- const stat = (0, import_node_fs23.statSync)(p);
33363
+ const stat = (0, import_node_fs24.statSync)(p);
33277
33364
  if (stat.isFile()) {
33278
- content = (0, import_node_fs23.readFileSync)(p, "utf-8");
33365
+ content = (0, import_node_fs24.readFileSync)(p, "utf-8");
33279
33366
  } else if (stat.isDirectory()) {
33280
- const files = (0, import_node_fs23.readdirSync)(p).filter((f) => f.endsWith(".prisma"));
33281
- content = files.map((f) => (0, import_node_fs23.readFileSync)((0, import_node_path27.join)(p, f), "utf-8")).join("\n");
33367
+ const files = (0, import_node_fs24.readdirSync)(p).filter((f) => f.endsWith(".prisma"));
33368
+ content = files.map((f) => (0, import_node_fs24.readFileSync)((0, import_node_path28.join)(p, f), "utf-8")).join("\n");
33282
33369
  }
33283
33370
  } catch {
33284
33371
  continue;
@@ -33436,27 +33523,27 @@ function extractSeedData(rootDir) {
33436
33523
  const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
33437
33524
  const candidates = [];
33438
33525
  if (paths?.dbDir) {
33439
- candidates.push((0, import_node_path27.join)(paths.dbDir, "seed.ts"));
33440
- candidates.push((0, import_node_path27.join)(paths.dbDir, "seed.js"));
33526
+ candidates.push((0, import_node_path28.join)(paths.dbDir, "seed.ts"));
33527
+ candidates.push((0, import_node_path28.join)(paths.dbDir, "seed.js"));
33441
33528
  } else {
33442
- candidates.push((0, import_node_path27.join)(rootDir, "prisma", "seed.ts"));
33443
- candidates.push((0, import_node_path27.join)(rootDir, "prisma", "seed.js"));
33529
+ candidates.push((0, import_node_path28.join)(rootDir, "prisma", "seed.ts"));
33530
+ candidates.push((0, import_node_path28.join)(rootDir, "prisma", "seed.js"));
33444
33531
  }
33445
- const baseRoots = paths?.srcRoots ?? [(0, import_node_path27.join)(rootDir, "src")];
33532
+ const baseRoots = paths?.srcRoots ?? [(0, import_node_path28.join)(rootDir, "src")];
33446
33533
  for (const root of baseRoots) {
33447
- candidates.push((0, import_node_path27.join)(root, "server", "lib", "system-tags.ts"));
33534
+ candidates.push((0, import_node_path28.join)(root, "server", "lib", "system-tags.ts"));
33448
33535
  }
33449
33536
  const seedFiles = candidates.filter((p) => {
33450
33537
  try {
33451
- return (0, import_node_fs23.existsSync)(p) && (0, import_node_fs23.statSync)(p).isFile();
33538
+ return (0, import_node_fs24.existsSync)(p) && (0, import_node_fs24.statSync)(p).isFile();
33452
33539
  } catch {
33453
33540
  return false;
33454
33541
  }
33455
33542
  });
33456
33543
  const useTreeSitter = tryLoadTreeSitter();
33457
33544
  for (const filePath of seedFiles) {
33458
- const content = (0, import_node_fs23.readFileSync)(filePath, "utf-8");
33459
- const relPath = (0, import_node_path27.relative)(rootDir, filePath);
33545
+ const content = (0, import_node_fs24.readFileSync)(filePath, "utf-8");
33546
+ const relPath = (0, import_node_path28.relative)(rootDir, filePath);
33460
33547
  const seeded = detectSeededArrays(content, relPath);
33461
33548
  let astRoot = null;
33462
33549
  if (useTreeSitter && parseCode) {
@@ -33550,11 +33637,11 @@ function extractSeedData(rootDir) {
33550
33637
  return { nodes, edges };
33551
33638
  }
33552
33639
  function walkDir(dir, exts) {
33553
- if (!(0, import_node_fs23.existsSync)(dir)) return [];
33640
+ if (!(0, import_node_fs24.existsSync)(dir)) return [];
33554
33641
  const results = [];
33555
- for (const entry of (0, import_node_fs23.readdirSync)(dir, { withFileTypes: true })) {
33642
+ for (const entry of (0, import_node_fs24.readdirSync)(dir, { withFileTypes: true })) {
33556
33643
  if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist") continue;
33557
- const full = (0, import_node_path27.join)(dir, entry.name);
33644
+ const full = (0, import_node_path28.join)(dir, entry.name);
33558
33645
  if (entry.isDirectory()) results.push(...walkDir(full, exts));
33559
33646
  else if (exts.some((ext) => entry.name.endsWith(ext))) results.push(full);
33560
33647
  }
@@ -33563,7 +33650,7 @@ function walkDir(dir, exts) {
33563
33650
  function extractConstants(rootDir) {
33564
33651
  const nodes = [];
33565
33652
  const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
33566
- const roots = paths?.srcRoots ?? [(0, import_node_path27.join)(rootDir, "src")];
33653
+ const roots = paths?.srcRoots ?? [(0, import_node_path28.join)(rootDir, "src")];
33567
33654
  const seenFile = /* @__PURE__ */ new Set();
33568
33655
  const allFiles = [];
33569
33656
  for (const root of roots) {
@@ -33576,8 +33663,8 @@ function extractConstants(rootDir) {
33576
33663
  }
33577
33664
  if (allFiles.length === 0) return { nodes };
33578
33665
  for (const filePath of allFiles) {
33579
- const content = (0, import_node_fs23.readFileSync)(filePath, "utf-8");
33580
- const relPath = (0, import_node_path27.relative)(rootDir, filePath);
33666
+ const content = (0, import_node_fs24.readFileSync)(filePath, "utf-8");
33667
+ const relPath = (0, import_node_path28.relative)(rootDir, filePath);
33581
33668
  const constArrayRe = /export\s+const\s+([A-Z][A-Z_0-9]+)\s*(?::[^=]+)?\s*=\s*\[/g;
33582
33669
  let cm;
33583
33670
  while ((cm = constArrayRe.exec(content)) !== null) {
@@ -33611,13 +33698,13 @@ function extractConstants(rootDir) {
33611
33698
  }
33612
33699
  function detect4(rootDir) {
33613
33700
  const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
33614
- if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath && (0, import_node_fs23.existsSync)(paths.dbConfig.schemaPath)) {
33701
+ if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath && (0, import_node_fs24.existsSync)(paths.dbConfig.schemaPath)) {
33615
33702
  return true;
33616
33703
  }
33617
33704
  if (paths?.dbDir) {
33618
- if ((0, import_node_fs23.existsSync)((0, import_node_path27.join)(paths.dbDir, "seed.ts")) || (0, import_node_fs23.existsSync)((0, import_node_path27.join)(paths.dbDir, "seed.js"))) return true;
33705
+ if ((0, import_node_fs24.existsSync)((0, import_node_path28.join)(paths.dbDir, "seed.ts")) || (0, import_node_fs24.existsSync)((0, import_node_path28.join)(paths.dbDir, "seed.js"))) return true;
33619
33706
  }
33620
- return (0, import_node_fs23.existsSync)((0, import_node_path27.join)(rootDir, "prisma", "schema.prisma")) || (0, import_node_fs23.existsSync)((0, import_node_path27.join)(rootDir, "prisma", "seed.ts"));
33707
+ return (0, import_node_fs24.existsSync)((0, import_node_path28.join)(rootDir, "prisma", "schema.prisma")) || (0, import_node_fs24.existsSync)((0, import_node_path28.join)(rootDir, "prisma", "seed.ts"));
33621
33708
  }
33622
33709
  function generate4(rootDir) {
33623
33710
  const enumResult = extractEnumValues(rootDir);
@@ -33692,8 +33779,8 @@ var staticValuesParser = {
33692
33779
  };
33693
33780
 
33694
33781
  // src/server/graph/parsers/crosslayer/static-ref-scanner.ts
33695
- var import_node_fs24 = require("node:fs");
33696
- var import_node_path28 = require("node:path");
33782
+ var import_node_fs25 = require("node:fs");
33783
+ var import_node_path29 = require("node:path");
33697
33784
  init_config();
33698
33785
  var MIN_VALUE_LENGTH = 4;
33699
33786
  var SKIP_VALUES = /* @__PURE__ */ new Set([
@@ -33868,11 +33955,11 @@ var staticRefScannerParser = {
33868
33955
  const seen = /* @__PURE__ */ new Set();
33869
33956
  let filesScanned = 0;
33870
33957
  for (const absPath of files) {
33871
- const relFromSrc = (0, import_node_path28.relative)(srcDir, absPath).replace(/\\/g, "/");
33872
- const sourceId = relFromSrc.startsWith("..") ? (0, import_node_path28.relative)(rootDir, absPath).replace(/\\/g, "/") : relFromSrc;
33958
+ const relFromSrc = (0, import_node_path29.relative)(srcDir, absPath).replace(/\\/g, "/");
33959
+ const sourceId = relFromSrc.startsWith("..") ? (0, import_node_path29.relative)(rootDir, absPath).replace(/\\/g, "/") : relFromSrc;
33873
33960
  const sourceLayer = uiNodeIds.has(sourceId) ? "ui" : apiNodeIds.has(sourceId) ? "api" : null;
33874
33961
  if (!sourceLayer) continue;
33875
- const content = (0, import_node_fs24.readFileSync)(absPath, "utf-8");
33962
+ const content = (0, import_node_fs25.readFileSync)(absPath, "utf-8");
33876
33963
  filesScanned++;
33877
33964
  let fileRefs;
33878
33965
  if (parseCode2) {
@@ -33914,13 +34001,13 @@ var staticRefScannerParser = {
33914
34001
  };
33915
34002
 
33916
34003
  // src/server/graph/parsers/crosslayer/middleware-gates.ts
33917
- var import_node_path29 = require("node:path");
34004
+ var import_node_path30 = require("node:path");
33918
34005
  init_ts_extractor();
33919
34006
  init_config();
33920
34007
  function toNodeId4(srcDir, rootDir, absPath) {
33921
- const relFromSrc = (0, import_node_path29.relative)(srcDir, absPath).replace(/\\/g, "/");
34008
+ const relFromSrc = (0, import_node_path30.relative)(srcDir, absPath).replace(/\\/g, "/");
33922
34009
  if (relFromSrc.startsWith("..")) {
33923
- return (0, import_node_path29.relative)(rootDir, absPath).replace(/\\/g, "/");
34010
+ return (0, import_node_path30.relative)(rootDir, absPath).replace(/\\/g, "/");
33924
34011
  }
33925
34012
  return relFromSrc;
33926
34013
  }
@@ -34222,7 +34309,7 @@ function registerBuiltins3(registry, disabled) {
34222
34309
  function loadCustomParsers(registry, config, rootDir, disabled) {
34223
34310
  for (const entry of config.parsers?.custom ?? []) {
34224
34311
  try {
34225
- const absPath = (0, import_node_path30.resolve)(rootDir, entry.path);
34312
+ const absPath = (0, import_node_path31.resolve)(rootDir, entry.path);
34226
34313
  const mod = require(absPath);
34227
34314
  const parser = "default" in mod ? mod.default : mod;
34228
34315
  if (disabled.has(parser.id)) continue;
@@ -34251,8 +34338,8 @@ function createRegistry(config, rootDir) {
34251
34338
  }
34252
34339
 
34253
34340
  // src/server/graph/core/language-detection.ts
34254
- var import_node_fs25 = require("node:fs");
34255
- var import_node_path31 = require("node:path");
34341
+ var import_node_fs26 = require("node:fs");
34342
+ var import_node_path32 = require("node:path");
34256
34343
  init_launch_kit_paths();
34257
34344
  var EXTENSION_TO_LANGUAGE = {
34258
34345
  // Web / Frontend
@@ -34365,10 +34452,10 @@ var AUXILIARY_LANGUAGES = /* @__PURE__ */ new Set([
34365
34452
  ]);
34366
34453
  function walkForExtensions(dir, extCounts, depth = 0) {
34367
34454
  if (depth > 10) return;
34368
- if (!(0, import_node_fs25.existsSync)(dir)) return;
34455
+ if (!(0, import_node_fs26.existsSync)(dir)) return;
34369
34456
  let entries;
34370
34457
  try {
34371
- entries = (0, import_node_fs25.readdirSync)(dir, { withFileTypes: true });
34458
+ entries = (0, import_node_fs26.readdirSync)(dir, { withFileTypes: true });
34372
34459
  } catch {
34373
34460
  return;
34374
34461
  }
@@ -34376,9 +34463,9 @@ function walkForExtensions(dir, extCounts, depth = 0) {
34376
34463
  if (entry.name.startsWith(".") && entry.isDirectory()) continue;
34377
34464
  if (entry.isDirectory()) {
34378
34465
  if (IGNORE_DIRS.has(entry.name)) continue;
34379
- walkForExtensions((0, import_node_path31.join)(dir, entry.name), extCounts, depth + 1);
34466
+ walkForExtensions((0, import_node_path32.join)(dir, entry.name), extCounts, depth + 1);
34380
34467
  } else {
34381
- const ext = (0, import_node_path31.extname)(entry.name).toLowerCase();
34468
+ const ext = (0, import_node_path32.extname)(entry.name).toLowerCase();
34382
34469
  if (ext && EXTENSION_TO_LANGUAGE[ext]) {
34383
34470
  extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
34384
34471
  }
@@ -34419,13 +34506,13 @@ function detectLanguages(rootDir, supportedLanguages) {
34419
34506
  }
34420
34507
 
34421
34508
  // src/server/graph/core/audit-core.ts
34422
- var import_node_fs27 = require("node:fs");
34423
- var import_node_path33 = require("node:path");
34509
+ var import_node_fs28 = require("node:fs");
34510
+ var import_node_path34 = require("node:path");
34424
34511
  init_launch_kit_paths();
34425
34512
 
34426
34513
  // src/server/graph/core/audit-security.ts
34427
- var import_node_fs26 = require("node:fs");
34428
- var import_node_path32 = require("node:path");
34514
+ var import_node_fs27 = require("node:fs");
34515
+ var import_node_path33 = require("node:path");
34429
34516
  init_ts_extractor();
34430
34517
  init_config();
34431
34518
  function collectSourceFiles(rootDir) {
@@ -34450,9 +34537,9 @@ function collectSourceFiles(rootDir) {
34450
34537
  return out;
34451
34538
  }
34452
34539
  function toNodeId5(rootDir, srcDir, absPath) {
34453
- const relFromSrc = (0, import_node_path32.relative)(srcDir, absPath).replace(/\\/g, "/");
34540
+ const relFromSrc = (0, import_node_path33.relative)(srcDir, absPath).replace(/\\/g, "/");
34454
34541
  if (relFromSrc.startsWith("..")) {
34455
- return (0, import_node_path32.relative)(rootDir, absPath).replace(/\\/g, "/");
34542
+ return (0, import_node_path33.relative)(rootDir, absPath).replace(/\\/g, "/");
34456
34543
  }
34457
34544
  return relFromSrc;
34458
34545
  }
@@ -34562,18 +34649,18 @@ function collectDeclaredEnvKeys(rootDir) {
34562
34649
  const files = [];
34563
34650
  let entries = [];
34564
34651
  try {
34565
- entries = (0, import_node_fs26.readdirSync)(rootDir);
34652
+ entries = (0, import_node_fs27.readdirSync)(rootDir);
34566
34653
  } catch {
34567
34654
  return { keys, files };
34568
34655
  }
34569
34656
  for (const name of entries) {
34570
34657
  if (!name.startsWith(".env")) continue;
34571
- const abs = (0, import_node_path32.join)(rootDir, name);
34572
- if (!(0, import_node_fs26.existsSync)(abs)) continue;
34658
+ const abs = (0, import_node_path33.join)(rootDir, name);
34659
+ if (!(0, import_node_fs27.existsSync)(abs)) continue;
34573
34660
  files.push(name);
34574
34661
  let content = "";
34575
34662
  try {
34576
- content = (0, import_node_fs26.readFileSync)(abs, "utf-8");
34663
+ content = (0, import_node_fs27.readFileSync)(abs, "utf-8");
34577
34664
  } catch {
34578
34665
  continue;
34579
34666
  }
@@ -34760,10 +34847,10 @@ function checkHardcodedUrlFallback(rootDir, core) {
34760
34847
 
34761
34848
  // src/server/graph/core/audit-core.ts
34762
34849
  function readGraphFile(rootDir, layer) {
34763
- const filePath = (0, import_node_path33.join)(rootDir, LAUNCHSECURE_DIR, "graphs", `${layer}.json`);
34764
- if (!(0, import_node_fs27.existsSync)(filePath)) return null;
34850
+ const filePath = (0, import_node_path34.join)(rootDir, LAUNCHSECURE_DIR, "graphs", `${layer}.json`);
34851
+ if (!(0, import_node_fs28.existsSync)(filePath)) return null;
34765
34852
  try {
34766
- return JSON.parse((0, import_node_fs27.readFileSync)(filePath, "utf-8"));
34853
+ return JSON.parse((0, import_node_fs28.readFileSync)(filePath, "utf-8"));
34767
34854
  } catch {
34768
34855
  return null;
34769
34856
  }
@@ -34805,15 +34892,15 @@ function checkUnprotectedRoutes(rootDir) {
34805
34892
  const findings = [];
34806
34893
  const api = readGraphFile(rootDir, "api");
34807
34894
  if (!api) return buildSkipped("api", "unprotected_routes", "no api graph");
34808
- const routePermsPath = (0, import_node_path33.join)(rootDir, "src", "config", "route-permissions.ts");
34809
- if (!(0, import_node_fs27.existsSync)(routePermsPath)) {
34895
+ const routePermsPath = (0, import_node_path34.join)(rootDir, "src", "config", "route-permissions.ts");
34896
+ if (!(0, import_node_fs28.existsSync)(routePermsPath)) {
34810
34897
  return buildSkipped(
34811
34898
  "api",
34812
34899
  "unprotected_routes",
34813
34900
  `no src/config/route-permissions.ts \u2014 this check needs a centralized ROUTE_PERMISSIONS inventory to compare endpoints against`
34814
34901
  );
34815
34902
  }
34816
- const routePermsContent = (0, import_node_fs27.readFileSync)(routePermsPath, "utf-8");
34903
+ const routePermsContent = (0, import_node_fs28.readFileSync)(routePermsPath, "utf-8");
34817
34904
  const registeredRoutes = /* @__PURE__ */ new Set();
34818
34905
  const routeEntryRe = /path:\s*'([^']+)'/g;
34819
34906
  let rm;
@@ -34898,15 +34985,15 @@ function checkUnenforcedPermissions(rootDir) {
34898
34985
  `no seed_permission nodes \u2014 this project either has no seed permissions or hasn't tagged them in seed.ts`
34899
34986
  );
34900
34987
  }
34901
- const routePermsPath = (0, import_node_path33.join)(rootDir, "src", "config", "route-permissions.ts");
34902
- if (!(0, import_node_fs27.existsSync)(routePermsPath)) {
34988
+ const routePermsPath = (0, import_node_path34.join)(rootDir, "src", "config", "route-permissions.ts");
34989
+ if (!(0, import_node_fs28.existsSync)(routePermsPath)) {
34903
34990
  return buildSkipped(
34904
34991
  "static",
34905
34992
  "unenforced_permissions",
34906
34993
  `no src/config/route-permissions.ts to compare seed permissions against`
34907
34994
  );
34908
34995
  }
34909
- const routePermsContent = (0, import_node_fs27.readFileSync)(routePermsPath, "utf-8");
34996
+ const routePermsContent = (0, import_node_fs28.readFileSync)(routePermsPath, "utf-8");
34910
34997
  for (const perm of permissions) {
34911
34998
  const regex = new RegExp(`permission:\\s*['"]${perm.key}['"]`);
34912
34999
  if (!regex.test(routePermsContent)) {
@@ -34942,9 +35029,9 @@ function checkHardcodedValues(rootDir) {
34942
35029
  const seen = /* @__PURE__ */ new Set();
34943
35030
  for (const node of api.nodes) {
34944
35031
  if (node.type !== "endpoint") continue;
34945
- const filePath = (0, import_node_path33.join)(rootDir, "src", node.id);
34946
- if (!(0, import_node_fs27.existsSync)(filePath)) continue;
34947
- const content = (0, import_node_fs27.readFileSync)(filePath, "utf-8");
35032
+ const filePath = (0, import_node_path34.join)(rootDir, "src", node.id);
35033
+ if (!(0, import_node_fs28.existsSync)(filePath)) continue;
35034
+ const content = (0, import_node_fs28.readFileSync)(filePath, "utf-8");
34948
35035
  let m;
34949
35036
  allCapsRe.lastIndex = 0;
34950
35037
  while ((m = allCapsRe.exec(content)) !== null) {
@@ -35049,26 +35136,26 @@ function runAudit(rootDir, layer, check) {
35049
35136
  }
35050
35137
 
35051
35138
  // src/server/graph/core/projects.ts
35052
- var import_node_path36 = require("node:path");
35139
+ var import_node_path37 = require("node:path");
35053
35140
 
35054
35141
  // src/server/lib/worktree.ts
35055
- var import_node_path35 = require("node:path");
35142
+ var import_node_path36 = require("node:path");
35056
35143
 
35057
35144
  // src/server/orbit/registry.ts
35058
- var import_node_fs28 = require("node:fs");
35059
- var import_node_os5 = require("node:os");
35060
- var import_node_path34 = require("node:path");
35145
+ var import_node_fs29 = require("node:fs");
35146
+ var import_node_os6 = require("node:os");
35147
+ var import_node_path35 = require("node:path");
35061
35148
  init_launch_kit_paths();
35062
- var REGISTRY_DIR = (0, import_node_path34.join)((0, import_node_os5.homedir)(), LAUNCHSECURE_DIR, "orbit");
35063
- var REGISTRY_PATH = (0, import_node_path34.join)(REGISTRY_DIR, "state.json");
35064
- var LOCK_PATH = (0, import_node_path34.join)(REGISTRY_DIR, "state.json.lock");
35149
+ var REGISTRY_DIR = (0, import_node_path35.join)((0, import_node_os6.homedir)(), LAUNCHSECURE_DIR, "orbit");
35150
+ var REGISTRY_PATH = (0, import_node_path35.join)(REGISTRY_DIR, "state.json");
35151
+ var LOCK_PATH = (0, import_node_path35.join)(REGISTRY_DIR, "state.json.lock");
35065
35152
  function emptyRegistry() {
35066
35153
  return { version: 1, worktrees: {} };
35067
35154
  }
35068
35155
  function readRegistry() {
35069
- if (!(0, import_node_fs28.existsSync)(REGISTRY_PATH)) return emptyRegistry();
35156
+ if (!(0, import_node_fs29.existsSync)(REGISTRY_PATH)) return emptyRegistry();
35070
35157
  try {
35071
- const parsed = JSON.parse((0, import_node_fs28.readFileSync)(REGISTRY_PATH, "utf-8"));
35158
+ const parsed = JSON.parse((0, import_node_fs29.readFileSync)(REGISTRY_PATH, "utf-8"));
35072
35159
  if (parsed?.version === 1 && parsed.worktrees && typeof parsed.worktrees === "object") {
35073
35160
  return parsed;
35074
35161
  }
@@ -35098,7 +35185,7 @@ function resolveWorktreeRoot(slug, monorepoRoot) {
35098
35185
  function resolveWorktreeOrProjectRoot(args, monorepoRoot) {
35099
35186
  const projectRoot = typeof args.project_root === "string" ? args.project_root.trim() : "";
35100
35187
  if (projectRoot) {
35101
- return (0, import_node_path35.isAbsolute)(projectRoot) ? projectRoot : (0, import_node_path35.resolve)(monorepoRoot, projectRoot);
35188
+ return (0, import_node_path36.isAbsolute)(projectRoot) ? projectRoot : (0, import_node_path36.resolve)(monorepoRoot, projectRoot);
35102
35189
  }
35103
35190
  const worktree = typeof args.worktree === "string" ? args.worktree.trim() : "";
35104
35191
  if (worktree) {
@@ -35117,7 +35204,7 @@ function listProjects(monorepoRoot) {
35117
35204
  return entries.map((p) => ({
35118
35205
  name: p.name,
35119
35206
  root: p.root,
35120
- absoluteRoot: (0, import_node_path36.resolve)(monorepoRoot, p.root)
35207
+ absoluteRoot: (0, import_node_path37.resolve)(monorepoRoot, p.root)
35121
35208
  }));
35122
35209
  }
35123
35210
  function resolveProject(name, projects) {
@@ -36556,12 +36643,12 @@ function handleReadGraph(args) {
36556
36643
  return okJson(result);
36557
36644
  }
36558
36645
  function nodeToFilePath(rootDir, layer, nodeId) {
36559
- if (layer === "ui" || layer === "api") return (0, import_node_path38.join)(rootDir, "src", nodeId);
36560
- if (layer === "db") return (0, import_node_path38.join)(rootDir, "prisma", "schema.prisma");
36561
- const withSrc = (0, import_node_path38.join)(rootDir, "src", nodeId);
36562
- if ((0, import_node_fs30.existsSync)(withSrc)) return withSrc;
36563
- const direct = (0, import_node_path38.join)(rootDir, nodeId);
36564
- if ((0, import_node_fs30.existsSync)(direct)) return direct;
36646
+ if (layer === "ui" || layer === "api") return (0, import_node_path39.join)(rootDir, "src", nodeId);
36647
+ if (layer === "db") return (0, import_node_path39.join)(rootDir, "prisma", "schema.prisma");
36648
+ const withSrc = (0, import_node_path39.join)(rootDir, "src", nodeId);
36649
+ if ((0, import_node_fs31.existsSync)(withSrc)) return withSrc;
36650
+ const direct = (0, import_node_path39.join)(rootDir, nodeId);
36651
+ if ((0, import_node_fs31.existsSync)(direct)) return direct;
36565
36652
  return null;
36566
36653
  }
36567
36654
  function handleInspectNode(args) {
@@ -36829,11 +36916,11 @@ function handleGrepNodes(args) {
36829
36916
  let filesSearched = 0;
36830
36917
  let truncated = false;
36831
36918
  for (const [filePath, nodeId] of filePaths) {
36832
- if (!(0, import_node_fs30.existsSync)(filePath)) continue;
36919
+ if (!(0, import_node_fs31.existsSync)(filePath)) continue;
36833
36920
  filesSearched++;
36834
36921
  let content;
36835
36922
  try {
36836
- content = (0, import_node_fs30.readFileSync)(filePath, "utf-8");
36923
+ content = (0, import_node_fs31.readFileSync)(filePath, "utf-8");
36837
36924
  } catch {
36838
36925
  continue;
36839
36926
  }
@@ -37052,11 +37139,11 @@ function handleStartChartServer(args) {
37052
37139
  });
37053
37140
  }
37054
37141
  const entryPath = process.argv[1];
37055
- const logDir = (0, import_node_path38.join)((0, import_node_os6.homedir)(), LAUNCHSECURE_DIR);
37056
- (0, import_node_fs30.mkdirSync)(logDir, { recursive: true });
37057
- const logPath = (0, import_node_path38.join)(logDir, "launch-chart.log");
37058
- const out = (0, import_node_fs30.openSync)(logPath, "a");
37059
- const err2 = (0, import_node_fs30.openSync)(logPath, "a");
37142
+ const logDir = (0, import_node_path39.join)((0, import_node_os7.homedir)(), LAUNCHSECURE_DIR);
37143
+ (0, import_node_fs31.mkdirSync)(logDir, { recursive: true });
37144
+ const logPath = (0, import_node_path39.join)(logDir, "launch-chart.log");
37145
+ const out = (0, import_node_fs31.openSync)(logPath, "a");
37146
+ const err2 = (0, import_node_fs31.openSync)(logPath, "a");
37060
37147
  const portArgs = args.port ? ["--port", String(args.port)] : [];
37061
37148
  const child = (0, import_node_child_process4.spawn)(process.execPath, [entryPath, "serve", ...portArgs], {
37062
37149
  detached: true,
@@ -37569,20 +37656,20 @@ function handleDetectProjectStack() {
37569
37656
  if (ref.type === "references_api") stats.references_api++;
37570
37657
  }
37571
37658
  }
37572
- const srcDir = (0, import_node_path38.join)(rootDir, "src");
37573
- if ((0, import_node_fs30.existsSync)(srcDir)) {
37659
+ const srcDir = (0, import_node_path39.join)(rootDir, "src");
37660
+ if ((0, import_node_fs31.existsSync)(srcDir)) {
37574
37661
  const scanDir = (dir) => {
37575
- if (!(0, import_node_fs30.existsSync)(dir)) return;
37576
- for (const entry of (0, import_node_fs30.readdirSync)(dir, { withFileTypes: true })) {
37662
+ if (!(0, import_node_fs31.existsSync)(dir)) return;
37663
+ for (const entry of (0, import_node_fs31.readdirSync)(dir, { withFileTypes: true })) {
37577
37664
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
37578
- const full = (0, import_node_path38.join)(dir, entry.name);
37665
+ const full = (0, import_node_path39.join)(dir, entry.name);
37579
37666
  if (entry.isDirectory()) {
37580
37667
  scanDir(full);
37581
37668
  continue;
37582
37669
  }
37583
- if (![".ts", ".tsx"].includes((0, import_node_path38.extname)(entry.name))) continue;
37670
+ if (![".ts", ".tsx"].includes((0, import_node_path39.extname)(entry.name))) continue;
37584
37671
  try {
37585
- const content = (0, import_node_fs30.readFileSync)(full, "utf-8");
37672
+ const content = (0, import_node_fs31.readFileSync)(full, "utf-8");
37586
37673
  const matches = content.match(/@api\s+(GET|POST|PUT|DELETE|PATCH)\s+\/\S+/g);
37587
37674
  if (matches) stats.annotations += matches.length;
37588
37675
  } catch {
@@ -37601,7 +37688,7 @@ function handleDetectProjectStack() {
37601
37688
  name: p.name,
37602
37689
  root: p.root,
37603
37690
  absolute_root: p.absoluteRoot,
37604
- has_graph: (0, import_node_fs30.existsSync)((0, import_node_path38.join)(p.absoluteRoot, LAUNCHSECURE_DIR, "graphs"))
37691
+ has_graph: (0, import_node_fs31.existsSync)((0, import_node_path39.join)(p.absoluteRoot, LAUNCHSECURE_DIR, "graphs"))
37605
37692
  }));
37606
37693
  return okJson({
37607
37694
  languages,
@@ -38972,6 +39059,31 @@ if (!__isMcpMode) {
38972
39059
  });
38973
39060
  return;
38974
39061
  }
39062
+ if (req.method === "POST" && url.pathname === "/api/radar/credentials") {
39063
+ const chunks = [];
39064
+ req.on("data", (c) => chunks.push(c));
39065
+ req.on("end", () => {
39066
+ let token;
39067
+ try {
39068
+ const body = JSON.parse(Buffer.concat(chunks).toString("utf-8") || "{}");
39069
+ token = body.token;
39070
+ } catch {
39071
+ }
39072
+ if (typeof token !== "string" || !token.trim()) {
39073
+ res.writeHead(400, { "Content-Type": "application/json" });
39074
+ res.end(JSON.stringify({ ok: false, error: "body must be {token: string}" }));
39075
+ return;
39076
+ }
39077
+ radar.updateClaudeCredential(token).then((result) => {
39078
+ res.writeHead(result.ok ? 200 : 400, { "Content-Type": "application/json" });
39079
+ res.end(JSON.stringify(result));
39080
+ }).catch((err2) => {
39081
+ res.writeHead(500, { "Content-Type": "application/json" });
39082
+ res.end(JSON.stringify({ ok: false, error: err2.message }));
39083
+ });
39084
+ });
39085
+ return;
39086
+ }
38975
39087
  const sessionRenameMatch = url.pathname.match(/^\/api\/radar\/session\/([^/]+)$/);
38976
39088
  if (req.method === "PATCH" && sessionRenameMatch) {
38977
39089
  const pingId = sessionRenameMatch[1];