@launchsecure/launch-kit 0.0.18 → 0.0.19

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 (69) hide show
  1. package/dist/chart-client/assets/index-C8ANseEa.js +441 -0
  2. package/dist/chart-client/index.html +1 -1
  3. package/dist/deck-client/assets/{_baseUniq-2gclQXo7.js → _baseUniq-DsfOm3t_.js} +1 -1
  4. package/dist/deck-client/assets/{arc-DcMY5Wm0.js → arc-NJuvkBv1.js} +1 -1
  5. package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-B8iirmmJ.js → architectureDiagram-Q4EWVU46-BgrcgZs0.js} +1 -1
  6. package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-B4JBLjmJ.js → blockDiagram-DXYQGD6D-C3XoLi15.js} +1 -1
  7. package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-CojrJAk8.js → c4Diagram-AHTNJAMY-FX2PjLfb.js} +1 -1
  8. package/dist/deck-client/assets/channel-ChQjD1T1.js +1 -0
  9. package/dist/deck-client/assets/{chunk-4BX2VUAB-Bmb_BMDo.js → chunk-4BX2VUAB-D0aqsJV0.js} +1 -1
  10. package/dist/deck-client/assets/{chunk-4TB4RGXK-CumBy8qe.js → chunk-4TB4RGXK-7qRCCAgK.js} +1 -1
  11. package/dist/deck-client/assets/{chunk-55IACEB6-Ka8Hb1wD.js → chunk-55IACEB6-DfHG-iqb.js} +1 -1
  12. package/dist/deck-client/assets/{chunk-EDXVE4YY-B3sIPiQo.js → chunk-EDXVE4YY-DrR52j3B.js} +1 -1
  13. package/dist/deck-client/assets/{chunk-FMBD7UC4-C1tYkaqu.js → chunk-FMBD7UC4-D5KSGATB.js} +1 -1
  14. package/dist/deck-client/assets/{chunk-OYMX7WX6-D7Wacbky.js → chunk-OYMX7WX6-M7hsLRNU.js} +1 -1
  15. package/dist/deck-client/assets/{chunk-QZHKN3VN-ChXI0vO3.js → chunk-QZHKN3VN-1ynAWO2m.js} +1 -1
  16. package/dist/deck-client/assets/{chunk-YZCP3GAM-BXhiqf8u.js → chunk-YZCP3GAM-S2-nGw3D.js} +1 -1
  17. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-B_9iqK1S.js +1 -0
  18. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-B_9iqK1S.js +1 -0
  19. package/dist/deck-client/assets/clone-BYt1AMfz.js +1 -0
  20. package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-Bqp3p68D.js → cose-bilkent-S5V4N54A-BcMwozS2.js} +1 -1
  21. package/dist/deck-client/assets/{dagre-KV5264BT-BS-rtyhZ.js → dagre-KV5264BT-DtKMhl_1.js} +1 -1
  22. package/dist/deck-client/assets/{diagram-5BDNPKRD-BIrj9YGI.js → diagram-5BDNPKRD-1plH69us.js} +1 -1
  23. package/dist/deck-client/assets/{diagram-G4DWMVQ6-noHWPIg4.js → diagram-G4DWMVQ6-D_o-BHO3.js} +1 -1
  24. package/dist/deck-client/assets/{diagram-MMDJMWI5-C2qHxvqV.js → diagram-MMDJMWI5-ClZ1LIx6.js} +1 -1
  25. package/dist/deck-client/assets/{diagram-TYMM5635-BytnGQr-.js → diagram-TYMM5635-B8dKHfRh.js} +1 -1
  26. package/dist/deck-client/assets/{erDiagram-SMLLAGMA-BfK5m2YQ.js → erDiagram-SMLLAGMA-CY2aCH7-.js} +1 -1
  27. package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-Cq925G1Z.js → flowDiagram-DWJPFMVM-DZZWHti8.js} +1 -1
  28. package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-DhhHPAmj.js → ganttDiagram-T4ZO3ILL-OwGGa6Lu.js} +1 -1
  29. package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-B3Lc0h9q.js → gitGraphDiagram-UUTBAWPF-GKyWD4Qt.js} +1 -1
  30. package/dist/deck-client/assets/{graph-RTawgVWm.js → graph-CORzYQdB.js} +1 -1
  31. package/dist/deck-client/assets/{index-BfIfJXmS.js → index-hiIpM7EP.js} +3 -3
  32. package/dist/deck-client/assets/{infoDiagram-42DDH7IO-BlR584kX.js → infoDiagram-42DDH7IO-DmgqJCcF.js} +1 -1
  33. package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-DygKoNGY.js → ishikawaDiagram-UXIWVN3A-D-1v7knu.js} +1 -1
  34. package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-BnaiYp9N.js → journeyDiagram-VCZTEJTY-CYrGQE7b.js} +1 -1
  35. package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-BQBUBzJC.js → kanban-definition-6JOO6SKY-BJFDWiH-.js} +1 -1
  36. package/dist/deck-client/assets/{layout-DeZ8HI1T.js → layout-BTFFcaxF.js} +1 -1
  37. package/dist/deck-client/assets/{linear-C6roLi_9.js → linear-DAbl6COS.js} +1 -1
  38. package/dist/deck-client/assets/{min-CbUksbuI.js → min-oWHBrFBm.js} +1 -1
  39. package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-iNxV62yN.js → mindmap-definition-QFDTVHPH-BTCB0VLO.js} +1 -1
  40. package/dist/deck-client/assets/{pieDiagram-DEJITSTG-DHVA0jaG.js → pieDiagram-DEJITSTG-CUZChWNA.js} +1 -1
  41. package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-DBeKKLUQ.js → quadrantDiagram-34T5L4WZ-4M1Um_e4.js} +1 -1
  42. package/dist/deck-client/assets/{requirementDiagram-MS252O5E-CBwITx7p.js → requirementDiagram-MS252O5E-DLzQZ0B3.js} +1 -1
  43. package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-BtE-1YTU.js → sankeyDiagram-XADWPNL6-DcNgzV3E.js} +1 -1
  44. package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-DN96yPP2.js → sequenceDiagram-FGHM5R23-CAcI2vC9.js} +1 -1
  45. package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-VUkKC2uJ.js → stateDiagram-FHFEXIEX-CntjTTm5.js} +1 -1
  46. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-YiaphOU_.js +1 -0
  47. package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-oUeZhRns.js → timeline-definition-GMOUNBTQ-D8zrit4U.js} +1 -1
  48. package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-D87fK90n.js → vennDiagram-DHZGUBPP-C4SuFPgo.js} +1 -1
  49. package/dist/deck-client/assets/wardley-RL74JXVD-B3F-Olcq.js +162 -0
  50. package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-Ca_i0QRA.js → wardleyDiagram-NUSXRM2D-kj73r6f-.js} +1 -1
  51. package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-CUOJVIvq.js → xychartDiagram-5P7HB3ND-CC_d_Ey3.js} +1 -1
  52. package/dist/deck-client/index.html +1 -1
  53. package/dist/server/chart-serve.js +392 -169
  54. package/dist/server/cli.js +384 -168
  55. package/dist/server/council-entry.js +0 -0
  56. package/dist/server/deck-server/deck-mcp-entry.js +0 -0
  57. package/dist/server/fb-wizard.js +0 -0
  58. package/dist/server/graph-mcp-entry.js +430 -206
  59. package/dist/server/server/cli.js +0 -0
  60. package/dist/server/server/fb-wizard.js +0 -0
  61. package/dist/server/server/graph-mcp-entry.js +0 -0
  62. package/package.json +18 -17
  63. package/dist/chart-client/assets/index-D7x8nz-H.js +0 -441
  64. package/dist/deck-client/assets/channel-ERh5jKXV.js +0 -1
  65. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-CMi1Gaev.js +0 -1
  66. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-CMi1Gaev.js +0 -1
  67. package/dist/deck-client/assets/clone-DfWhlD4X.js +0 -1
  68. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-CA0IjulK.js +0 -1
  69. package/dist/deck-client/assets/wardley-RL74JXVD-DYbYcpDp.js +0 -162
@@ -1731,7 +1731,7 @@ var require_usage_reader = __commonJS({
1731
1731
  async readJsonlFile(filePath, cutoffTime) {
1732
1732
  const entries = [];
1733
1733
  const fileProcessedEntries = /* @__PURE__ */ new Set();
1734
- return new Promise((resolve3) => {
1734
+ return new Promise((resolve4) => {
1735
1735
  const rl = readline.createInterface({
1736
1736
  input: createReadStream(filePath),
1737
1737
  crlfDelay: Infinity
@@ -1789,11 +1789,11 @@ var require_usage_reader = __commonJS({
1789
1789
  }
1790
1790
  });
1791
1791
  rl.on("close", () => {
1792
- resolve3(entries);
1792
+ resolve4(entries);
1793
1793
  });
1794
1794
  rl.on("error", (error) => {
1795
1795
  console.error("Error reading file:", filePath, error);
1796
- resolve3(entries);
1796
+ resolve4(entries);
1797
1797
  });
1798
1798
  });
1799
1799
  }
@@ -3591,7 +3591,7 @@ var require_src = __commonJS({
3591
3591
  if (session.active) throw new Error(`Agent already running in session ${sessionId}`);
3592
3592
  const { command, args = [], env = {} } = options;
3593
3593
  if (!command) throw new Error("startScriptInSession requires a command");
3594
- return new Promise((resolve3, reject) => {
3594
+ return new Promise((resolve4, reject) => {
3595
3595
  this.scriptBridge.startSession(sessionId, {
3596
3596
  command,
3597
3597
  args,
@@ -3613,7 +3613,7 @@ var require_src = __commonJS({
3613
3613
  session.lastActivity = /* @__PURE__ */ new Date();
3614
3614
  this.broadcastToSession(sessionId, { type: "script_stopped", sessionId });
3615
3615
  if (exitCode === 0) {
3616
- resolve3({ code: exitCode, signal });
3616
+ resolve4({ code: exitCode, signal });
3617
3617
  } else {
3618
3618
  reject(new Error(`Script exited with code ${exitCode}`));
3619
3619
  }
@@ -5908,7 +5908,7 @@ var PostImplLaunchExecutor = class {
5908
5908
  return 3001;
5909
5909
  }
5910
5910
  startDevServer(port, databaseUrl) {
5911
- return new Promise((resolve3) => {
5911
+ return new Promise((resolve4) => {
5912
5912
  const env = { ...process.env, PORT: String(port), ...databaseUrl ? { DATABASE_URL: databaseUrl } : {} };
5913
5913
  this.devProcess = (0, import_child_process3.spawn)("npm", ["run", "dev"], {
5914
5914
  cwd: this.workingDir,
@@ -5920,7 +5920,7 @@ var PostImplLaunchExecutor = class {
5920
5920
  const timeout = setTimeout(() => {
5921
5921
  if (!resolved) {
5922
5922
  resolved = true;
5923
- this.healthCheck(port).then(resolve3);
5923
+ this.healthCheck(port).then(resolve4);
5924
5924
  }
5925
5925
  }, 15e3);
5926
5926
  const onData = (data) => {
@@ -5929,7 +5929,7 @@ var PostImplLaunchExecutor = class {
5929
5929
  if (!resolved) {
5930
5930
  resolved = true;
5931
5931
  clearTimeout(timeout);
5932
- resolve3(true);
5932
+ resolve4(true);
5933
5933
  }
5934
5934
  }
5935
5935
  };
@@ -5940,7 +5940,7 @@ var PostImplLaunchExecutor = class {
5940
5940
  if (!resolved) {
5941
5941
  resolved = true;
5942
5942
  clearTimeout(timeout);
5943
- resolve3(false);
5943
+ resolve4(false);
5944
5944
  }
5945
5945
  });
5946
5946
  this.devProcess.unref();
@@ -6963,15 +6963,15 @@ ${links}
6963
6963
 
6964
6964
  // src/server/graph/index.ts
6965
6965
  var import_node_fs15 = require("node:fs");
6966
- var import_node_path17 = require("node:path");
6966
+ var import_node_path16 = require("node:path");
6967
6967
 
6968
6968
  // src/server/graph/core/graph-builder.ts
6969
6969
  var import_node_fs12 = require("node:fs");
6970
- var import_node_path13 = require("node:path");
6970
+ var import_node_path12 = require("node:path");
6971
6971
  init_config();
6972
6972
 
6973
6973
  // src/server/graph/core/parser-registry.ts
6974
- var import_node_path12 = require("node:path");
6974
+ var import_node_path11 = require("node:path");
6975
6975
 
6976
6976
  // src/server/graph/parsers/ts/typescript-project.ts
6977
6977
  var import_node_fs5 = require("node:fs");
@@ -6979,35 +6979,12 @@ var import_node_path5 = require("node:path");
6979
6979
  init_config();
6980
6980
 
6981
6981
  // src/server/graph/core/resolve-paths.ts
6982
- var import_node_fs2 = require("node:fs");
6983
- var import_node_path2 = require("node:path");
6984
- function detectDbDir(rootDir, config) {
6985
- if (config.paths?.dbDir) return (0, import_node_path2.join)(rootDir, config.paths.dbDir);
6986
- const prismaDir = (0, import_node_path2.join)(rootDir, "prisma");
6987
- if ((0, import_node_fs2.existsSync)(prismaDir)) return prismaDir;
6988
- return null;
6989
- }
6990
- function resolveProjectPaths(rootDir, config) {
6991
- const dbDir = detectDbDir(rootDir, config);
6992
- if (config.paths?.appDir) {
6993
- const appDir = (0, import_node_path2.join)(rootDir, config.paths.appDir);
6994
- const srcDir = config.paths.srcDir ? (0, import_node_path2.join)(rootDir, config.paths.srcDir) : (0, import_node_path2.dirname)(appDir);
6995
- return { srcDir, appDir, apiDir: (0, import_node_path2.join)(appDir, "api"), dbDir };
6996
- }
6997
- const srcApp = (0, import_node_path2.join)(rootDir, "src", "app");
6998
- if ((0, import_node_fs2.existsSync)(srcApp)) {
6999
- return { srcDir: (0, import_node_path2.join)(rootDir, "src"), appDir: srcApp, apiDir: (0, import_node_path2.join)(srcApp, "api"), dbDir };
7000
- }
7001
- const rootApp = (0, import_node_path2.join)(rootDir, "app");
7002
- if ((0, import_node_fs2.existsSync)(rootApp)) {
7003
- return { srcDir: rootDir, appDir: rootApp, apiDir: (0, import_node_path2.join)(rootApp, "api"), dbDir };
7004
- }
7005
- return null;
7006
- }
7007
-
7008
- // src/server/graph/core/walk.ts
7009
6982
  var import_node_fs3 = require("node:fs");
7010
6983
  var import_node_path3 = require("node:path");
6984
+
6985
+ // src/server/graph/core/walk.ts
6986
+ var import_node_fs2 = require("node:fs");
6987
+ var import_node_path2 = require("node:path");
7011
6988
  var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
7012
6989
  "node_modules",
7013
6990
  ".git",
@@ -7023,12 +7000,12 @@ var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
7023
7000
  ]);
7024
7001
  function walk(dir, exts) {
7025
7002
  const results = [];
7026
- if (!(0, import_node_fs3.existsSync)(dir)) return results;
7027
- for (const entry of (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true })) {
7028
- const full = (0, import_node_path3.join)(dir, entry.name);
7003
+ if (!(0, import_node_fs2.existsSync)(dir)) return results;
7004
+ for (const entry of (0, import_node_fs2.readdirSync)(dir, { withFileTypes: true })) {
7005
+ const full = (0, import_node_path2.join)(dir, entry.name);
7029
7006
  if (entry.isDirectory()) {
7030
7007
  results.push(...walk(full, exts));
7031
- } else if (exts.includes((0, import_node_path3.extname)(entry.name))) {
7008
+ } else if (exts.includes((0, import_node_path2.extname)(entry.name))) {
7032
7009
  results.push(full);
7033
7010
  }
7034
7011
  }
@@ -7036,19 +7013,205 @@ function walk(dir, exts) {
7036
7013
  }
7037
7014
  function walkWithIgnore(dir, exts, opts = {}) {
7038
7015
  const results = [];
7039
- if (!(0, import_node_fs3.existsSync)(dir)) return results;
7016
+ if (!(0, import_node_fs2.existsSync)(dir)) return results;
7040
7017
  const skip = opts.extraIgnore ? /* @__PURE__ */ new Set([...DEFAULT_IGNORE_DIRS, ...opts.extraIgnore]) : DEFAULT_IGNORE_DIRS;
7041
- for (const entry of (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true })) {
7018
+ for (const entry of (0, import_node_fs2.readdirSync)(dir, { withFileTypes: true })) {
7042
7019
  if (entry.isDirectory()) {
7043
7020
  if (skip.has(entry.name)) continue;
7044
- results.push(...walkWithIgnore((0, import_node_path3.join)(dir, entry.name), exts, opts));
7045
- } else if (exts.includes((0, import_node_path3.extname)(entry.name))) {
7046
- results.push((0, import_node_path3.join)(dir, entry.name));
7021
+ results.push(...walkWithIgnore((0, import_node_path2.join)(dir, entry.name), exts, opts));
7022
+ } else if (exts.includes((0, import_node_path2.extname)(entry.name))) {
7023
+ results.push((0, import_node_path2.join)(dir, entry.name));
7047
7024
  }
7048
7025
  }
7049
7026
  return results;
7050
7027
  }
7051
7028
 
7029
+ // src/server/graph/core/resolve-paths.ts
7030
+ function hasSqlFiles(dir) {
7031
+ if (!(0, import_node_fs3.existsSync)(dir)) return false;
7032
+ try {
7033
+ return (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true }).some(
7034
+ (e) => e.isFile() && e.name.endsWith(".sql")
7035
+ );
7036
+ } catch {
7037
+ return false;
7038
+ }
7039
+ }
7040
+ function hasNestedMigrationSql(dir) {
7041
+ if (!(0, import_node_fs3.existsSync)(dir)) return false;
7042
+ try {
7043
+ return (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true }).some(
7044
+ (e) => e.isDirectory() && (0, import_node_fs3.existsSync)((0, import_node_path3.join)(dir, e.name, "migration.sql"))
7045
+ );
7046
+ } catch {
7047
+ return false;
7048
+ }
7049
+ }
7050
+ function resolveDbFromDir(dir) {
7051
+ if (!(0, import_node_fs3.existsSync)(dir)) return { kind: "none", schemaPath: null, migrationsDir: null };
7052
+ const schemaPath = (0, import_node_path3.join)(dir, "schema.prisma");
7053
+ if ((0, import_node_fs3.existsSync)(schemaPath)) {
7054
+ const migrationsDir2 = (0, import_node_path3.join)(dir, "migrations");
7055
+ return {
7056
+ kind: "prisma",
7057
+ schemaPath,
7058
+ migrationsDir: (0, import_node_fs3.existsSync)(migrationsDir2) ? migrationsDir2 : null
7059
+ };
7060
+ }
7061
+ const migrationsDir = (0, import_node_path3.join)(dir, "migrations");
7062
+ if (hasSqlFiles(migrationsDir) || hasNestedMigrationSql(migrationsDir)) {
7063
+ return { kind: "sql-migrations", migrationsDir, schemaPath: null };
7064
+ }
7065
+ if (hasSqlFiles(dir) || hasNestedMigrationSql(dir)) {
7066
+ return { kind: "sql-migrations", migrationsDir: dir, schemaPath: null };
7067
+ }
7068
+ return { kind: "none", schemaPath: null, migrationsDir: null };
7069
+ }
7070
+ function detectDbConfig(rootDir, config) {
7071
+ if (config.paths?.dbDir) {
7072
+ return resolveDbFromDir((0, import_node_path3.join)(rootDir, config.paths.dbDir));
7073
+ }
7074
+ const candidates = ["prisma", "supabase", "drizzle", (0, import_node_path3.join)("db", "migrations"), "migrations"];
7075
+ for (const c of candidates) {
7076
+ const dir = (0, import_node_path3.join)(rootDir, c);
7077
+ const resolved = resolveDbFromDir(dir);
7078
+ if (resolved.kind !== "none") return resolved;
7079
+ }
7080
+ return { kind: "none", schemaPath: null, migrationsDir: null };
7081
+ }
7082
+ function detectDbDir(rootDir, config, dbConfig) {
7083
+ if (config.paths?.dbDir) return (0, import_node_path3.join)(rootDir, config.paths.dbDir);
7084
+ if (dbConfig.kind === "prisma") return (0, import_node_path3.dirname)(dbConfig.schemaPath);
7085
+ if (dbConfig.kind === "sql-migrations") return dbConfig.migrationsDir;
7086
+ return null;
7087
+ }
7088
+ var NON_SOURCE_DIRS = /* @__PURE__ */ new Set([
7089
+ ...DEFAULT_IGNORE_DIRS,
7090
+ // DB conventions (handled by db parsers)
7091
+ "prisma",
7092
+ "supabase",
7093
+ "drizzle",
7094
+ "migrations",
7095
+ // Web assets
7096
+ "public",
7097
+ "static",
7098
+ "assets",
7099
+ // Docs
7100
+ "docs",
7101
+ "documentation",
7102
+ // Test dirs (project tests aren't part of the structural graph)
7103
+ "tests",
7104
+ "__tests__",
7105
+ "e2e",
7106
+ "playwright",
7107
+ "cypress",
7108
+ // Monorepo workspace roots — separate graph projects per .launchchart.json
7109
+ "packages",
7110
+ "apps",
7111
+ "services",
7112
+ "libs"
7113
+ ]);
7114
+ function dirHasTSFiles(dir) {
7115
+ if (!(0, import_node_fs3.existsSync)(dir)) return false;
7116
+ try {
7117
+ const stack = [dir];
7118
+ while (stack.length > 0) {
7119
+ const cur = stack.pop();
7120
+ const entries = (0, import_node_fs3.readdirSync)(cur, { withFileTypes: true });
7121
+ for (const e of entries) {
7122
+ if (e.isFile() && (e.name.endsWith(".ts") || e.name.endsWith(".tsx"))) return true;
7123
+ if (e.isDirectory() && !e.name.startsWith(".") && !DEFAULT_IGNORE_DIRS.has(e.name)) {
7124
+ stack.push((0, import_node_path3.join)(cur, e.name));
7125
+ }
7126
+ }
7127
+ }
7128
+ } catch {
7129
+ }
7130
+ return false;
7131
+ }
7132
+ function collectCodeBearingChildren(dir, extraSkip) {
7133
+ if (!(0, import_node_fs3.existsSync)(dir)) return [];
7134
+ const out = [];
7135
+ try {
7136
+ for (const entry of (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true })) {
7137
+ if (!entry.isDirectory()) continue;
7138
+ if (entry.name.startsWith(".")) continue;
7139
+ if (NON_SOURCE_DIRS.has(entry.name)) continue;
7140
+ if (extraSkip?.has(entry.name)) continue;
7141
+ const full = (0, import_node_path3.join)(dir, entry.name);
7142
+ if (dirHasTSFiles(full)) out.push(full);
7143
+ }
7144
+ } catch {
7145
+ }
7146
+ return out;
7147
+ }
7148
+ function detectSrcRoots(rootDir, srcDir, appDir, config) {
7149
+ if (config.paths?.srcRoots && config.paths.srcRoots.length > 0) {
7150
+ const roots2 = /* @__PURE__ */ new Set();
7151
+ roots2.add(appDir);
7152
+ for (const r of config.paths.srcRoots) {
7153
+ const abs = (0, import_node_path3.isAbsolute)(r) ? r : (0, import_node_path3.resolve)(rootDir, r);
7154
+ roots2.add(abs);
7155
+ }
7156
+ return [...roots2];
7157
+ }
7158
+ const roots = /* @__PURE__ */ new Set();
7159
+ roots.add(appDir);
7160
+ for (const c of collectCodeBearingChildren(srcDir)) roots.add(c);
7161
+ if (srcDir !== rootDir) {
7162
+ const skipSrcWrapper = /* @__PURE__ */ new Set([(0, import_node_path3.basename)(srcDir)]);
7163
+ for (const c of collectCodeBearingChildren(rootDir, skipSrcWrapper)) roots.add(c);
7164
+ }
7165
+ return [...roots];
7166
+ }
7167
+ var CONVENTION_NAMES = ["middleware.ts", "middleware.tsx", "instrumentation.ts", "instrumentation.tsx"];
7168
+ function detectConventionFiles(rootDir, srcDir) {
7169
+ const out = [];
7170
+ const seen = /* @__PURE__ */ new Set();
7171
+ const dirs = srcDir === rootDir ? [rootDir] : [srcDir, rootDir];
7172
+ for (const dir of dirs) {
7173
+ for (const name of CONVENTION_NAMES) {
7174
+ const full = (0, import_node_path3.join)(dir, name);
7175
+ if (!seen.has(full) && (0, import_node_fs3.existsSync)(full)) {
7176
+ try {
7177
+ if ((0, import_node_fs3.statSync)(full).isFile()) {
7178
+ seen.add(full);
7179
+ out.push(full);
7180
+ }
7181
+ } catch {
7182
+ }
7183
+ }
7184
+ }
7185
+ }
7186
+ return out;
7187
+ }
7188
+ function resolveProjectPaths(rootDir, config) {
7189
+ let srcDir;
7190
+ let appDir;
7191
+ if (config.paths?.appDir) {
7192
+ appDir = (0, import_node_path3.join)(rootDir, config.paths.appDir);
7193
+ srcDir = config.paths.srcDir ? (0, import_node_path3.join)(rootDir, config.paths.srcDir) : (0, import_node_path3.dirname)(appDir);
7194
+ } else {
7195
+ const srcApp = (0, import_node_path3.join)(rootDir, "src", "app");
7196
+ const rootApp = (0, import_node_path3.join)(rootDir, "app");
7197
+ if ((0, import_node_fs3.existsSync)(srcApp)) {
7198
+ srcDir = (0, import_node_path3.join)(rootDir, "src");
7199
+ appDir = srcApp;
7200
+ } else if ((0, import_node_fs3.existsSync)(rootApp)) {
7201
+ srcDir = rootDir;
7202
+ appDir = rootApp;
7203
+ } else {
7204
+ return null;
7205
+ }
7206
+ }
7207
+ const apiDir = (0, import_node_path3.join)(appDir, "api");
7208
+ const dbConfig = detectDbConfig(rootDir, config);
7209
+ const dbDir = detectDbDir(rootDir, config, dbConfig);
7210
+ const srcRoots = detectSrcRoots(rootDir, srcDir, appDir, config);
7211
+ const conventionFiles = detectConventionFiles(rootDir, srcDir);
7212
+ return { srcDir, appDir, apiDir, dbDir, srcRoots, conventionFiles, dbConfig };
7213
+ }
7214
+
7052
7215
  // src/server/graph/parsers/ts/typescript-project.ts
7053
7216
  init_ts_extractor();
7054
7217
  var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]);
@@ -7065,8 +7228,12 @@ var CLASSIFICATION_TO_LAYER = {
7065
7228
  "mcp-tool": "ui",
7066
7229
  external: "ui"
7067
7230
  };
7068
- function toNodeId(srcDir, absPath) {
7069
- return (0, import_node_path5.relative)(srcDir, absPath).replace(/\\/g, "/");
7231
+ function toNodeId(srcDir, rootDir, absPath) {
7232
+ const relFromSrc = (0, import_node_path5.relative)(srcDir, absPath).replace(/\\/g, "/");
7233
+ if (relFromSrc.startsWith("..")) {
7234
+ return (0, import_node_path5.relative)(rootDir, absPath).replace(/\\/g, "/");
7235
+ }
7236
+ return relFromSrc;
7070
7237
  }
7071
7238
  function resolveImport(srcDir, specifier) {
7072
7239
  if (!specifier.startsWith("@/")) return null;
@@ -7156,12 +7323,13 @@ function extractRoute(id) {
7156
7323
  function nameFromFilename(absPath) {
7157
7324
  return (0, import_node_path5.basename)(absPath, (0, import_node_path5.extname)(absPath)).replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^(\w)/, (_, c) => c.toUpperCase());
7158
7325
  }
7159
- function filePathToApiRoute(apiDir, absPath) {
7160
- let route = "/" + (0, import_node_path5.relative)(apiDir, absPath).replace(/\\/g, "/").replace(/\/route\.tsx?$/, "");
7326
+ function filePathToAppRoute(appDir, absPath) {
7327
+ let route = ("/" + (0, import_node_path5.relative)(appDir, absPath).replace(/\\/g, "/")).replace(/\/route\.tsx?$/, "");
7328
+ route = route.replace(/\/\([^)]+\)/g, "");
7329
+ route = route.replace(/\[\.\.\.([^\]]+)\]/g, "*$1");
7161
7330
  route = route.replace(/\[([^\]]+)\]/g, ":$1");
7162
7331
  route = route.replace(/\/+/g, "/");
7163
- if (route === "/") return "/api";
7164
- return "/api" + route;
7332
+ return route === "" ? "/" : route;
7165
7333
  }
7166
7334
  function camelToPascal(s) {
7167
7335
  if (!s) return s;
@@ -7246,7 +7414,7 @@ function matchRouteToPage(route, routeToNodeId) {
7246
7414
  if (routeToNodeId.has(normalized)) return routeToNodeId.get(normalized);
7247
7415
  return null;
7248
7416
  }
7249
- function extractEdges(srcDir, absPath, sourceId, parsed, nodeIdSet, barrelMaps, routeToNodeId) {
7417
+ function extractEdges(srcDir, rootDir, absPath, sourceId, parsed, nodeIdSet, barrelMaps, routeToNodeId) {
7250
7418
  const edges = [];
7251
7419
  const flagged = [];
7252
7420
  const seen = /* @__PURE__ */ new Set();
@@ -7274,7 +7442,7 @@ function extractEdges(srcDir, absPath, sourceId, parsed, nodeIdSet, barrelMaps,
7274
7442
  for (const name of names) {
7275
7443
  const targetAbs = barrelMap.get(name);
7276
7444
  if (targetAbs) {
7277
- const targetId = toNodeId(srcDir, targetAbs);
7445
+ const targetId = toNodeId(srcDir, rootDir, targetAbs);
7278
7446
  if (nodeIdSet.has(targetId)) {
7279
7447
  if (!byTarget.has(targetId)) byTarget.set(targetId, []);
7280
7448
  byTarget.get(targetId).push(name);
@@ -7288,7 +7456,7 @@ function extractEdges(srcDir, absPath, sourceId, parsed, nodeIdSet, barrelMaps,
7288
7456
  } else {
7289
7457
  const resolved = resolveImport(srcDir, specifier);
7290
7458
  if (resolved) {
7291
- const targetId = toNodeId(srcDir, resolved);
7459
+ const targetId = toNodeId(srcDir, rootDir, resolved);
7292
7460
  if (nodeIdSet.has(targetId) && !targetId.endsWith("/index.ts") && !targetId.endsWith("/index.tsx")) {
7293
7461
  addEdge(targetId, edgeTypeFor(isTypeOnly, names));
7294
7462
  }
@@ -7297,7 +7465,7 @@ function extractEdges(srcDir, absPath, sourceId, parsed, nodeIdSet, barrelMaps,
7297
7465
  } else if (specifier.startsWith(".")) {
7298
7466
  const resolved = resolveRelativeImport(absPath, specifier);
7299
7467
  if (resolved) {
7300
- const targetId = toNodeId(srcDir, resolved);
7468
+ const targetId = toNodeId(srcDir, rootDir, resolved);
7301
7469
  if (nodeIdSet.has(targetId) && !targetId.endsWith("/index.ts") && !targetId.endsWith("/index.tsx")) {
7302
7470
  addEdge(targetId, edgeTypeFor(isTypeOnly, names));
7303
7471
  }
@@ -7349,13 +7517,22 @@ function generate(rootDir) {
7349
7517
  const config = loadConfig(rootDir);
7350
7518
  const paths = resolveProjectPaths(rootDir, config);
7351
7519
  const srcDir = paths.srcDir;
7352
- const apiDir = paths.apiDir;
7353
- const appFiles = walk(paths.appDir, [".tsx", ".ts"]);
7354
- const clientFiles = walk((0, import_node_path5.join)(srcDir, "client"), [".tsx", ".ts"]);
7355
- const serverFiles = walk((0, import_node_path5.join)(srcDir, "server"), [".ts", ".tsx"]);
7356
- const libFiles = walk((0, import_node_path5.join)(srcDir, "lib"), [".ts", ".tsx"]);
7357
- const configFiles = walk((0, import_node_path5.join)(srcDir, "config"), [".ts", ".tsx"]);
7358
- const allDiscovered = [...appFiles, ...clientFiles, ...serverFiles, ...libFiles, ...configFiles];
7520
+ const allDiscovered = [];
7521
+ const discoveredSet = /* @__PURE__ */ new Set();
7522
+ for (const root of paths.srcRoots) {
7523
+ for (const f of walk(root, [".tsx", ".ts"])) {
7524
+ if (!discoveredSet.has(f)) {
7525
+ discoveredSet.add(f);
7526
+ allDiscovered.push(f);
7527
+ }
7528
+ }
7529
+ }
7530
+ for (const conv of paths.conventionFiles) {
7531
+ if (!discoveredSet.has(conv)) {
7532
+ discoveredSet.add(conv);
7533
+ allDiscovered.push(conv);
7534
+ }
7535
+ }
7359
7536
  const parsedByPath = /* @__PURE__ */ new Map();
7360
7537
  for (const absPath of allDiscovered) {
7361
7538
  parsedByPath.set(absPath, parseFileTS(absPath));
@@ -7367,7 +7544,7 @@ function generate(rootDir) {
7367
7544
  const routeToNodeId = /* @__PURE__ */ new Map();
7368
7545
  const fileSet = allDiscovered.filter((f) => !(0, import_node_path5.basename)(f).startsWith("index."));
7369
7546
  for (const absPath of fileSet) {
7370
- const id = toNodeId(srcDir, absPath);
7547
+ const id = toNodeId(srcDir, rootDir, absPath);
7371
7548
  const type = classifyType(absPath, id);
7372
7549
  if (type === "test" || type === "story") continue;
7373
7550
  const parsed = parsedByPath.get(absPath);
@@ -7382,7 +7559,7 @@ function generate(rootDir) {
7382
7559
  const dbCalls = extractDbCallsTS(absPath);
7383
7560
  const authWrappers = extractAuthWrappersTS(absPath);
7384
7561
  const deep = extractDeep(absPath);
7385
- const routePath = (0, import_node_fs5.existsSync)(apiDir) ? filePathToApiRoute(apiDir, absPath) : `/api/${id.replace(/\/route\.tsx?$/, "")}`;
7562
+ const routePath = filePathToAppRoute(paths.appDir, absPath);
7386
7563
  const mutations = dbCalls.filter((c) => c.isMutation);
7387
7564
  const mutates = mutations.length > 0;
7388
7565
  const authStrategy = [...authWrappers];
@@ -7426,11 +7603,12 @@ function generate(rootDir) {
7426
7603
  const uiEdges = [];
7427
7604
  const uiFlagged = [];
7428
7605
  for (const absPath of fileSet) {
7429
- const id = toNodeId(srcDir, absPath);
7606
+ const id = toNodeId(srcDir, rootDir, absPath);
7430
7607
  if (!nodeIdSet.has(id)) continue;
7431
7608
  const parsed = parsedByPath.get(absPath);
7432
7609
  const { edges, flagged } = extractEdges(
7433
7610
  srcDir,
7611
+ rootDir,
7434
7612
  absPath,
7435
7613
  id,
7436
7614
  parsed,
@@ -7443,7 +7621,7 @@ function generate(rootDir) {
7443
7621
  }
7444
7622
  const fetchCallEntries = [];
7445
7623
  for (const absPath of fileSet) {
7446
- const sourceId = toNodeId(srcDir, absPath);
7624
+ const sourceId = toNodeId(srcDir, rootDir, absPath);
7447
7625
  if (!nodeIdSet.has(sourceId)) continue;
7448
7626
  const parsed = parsedByPath.get(absPath);
7449
7627
  if (parsed.fetchCalls.length === 0) continue;
@@ -7482,7 +7660,7 @@ function generate(rootDir) {
7482
7660
  for (const name of names) {
7483
7661
  const targetAbs = barrelMap.get(name);
7484
7662
  if (!targetAbs) continue;
7485
- const targetId2 = toNodeId(srcDir, targetAbs);
7663
+ const targetId2 = toNodeId(srcDir, rootDir, targetAbs);
7486
7664
  if (!nodeIdSet.has(targetId2)) continue;
7487
7665
  const key2 = `${externalId}\u2192${targetId2}`;
7488
7666
  if (seen.has(key2)) continue;
@@ -7496,7 +7674,7 @@ function generate(rootDir) {
7496
7674
  resolved = resolveRelativeImport(absPath, specifier);
7497
7675
  }
7498
7676
  if (!resolved) continue;
7499
- const targetId = toNodeId(srcDir, resolved);
7677
+ const targetId = toNodeId(srcDir, rootDir, resolved);
7500
7678
  if (!nodeIdSet.has(targetId)) continue;
7501
7679
  if (targetId.endsWith("/index.ts") || targetId.endsWith("/index.tsx")) continue;
7502
7680
  const key = `${externalId}\u2192${targetId}`;
@@ -7674,7 +7852,7 @@ var typescriptProjectParser = {
7674
7852
 
7675
7853
  // src/server/graph/parsers/db/prisma-schema.ts
7676
7854
  var import_node_fs6 = require("node:fs");
7677
- var import_node_path6 = require("node:path");
7855
+ init_config();
7678
7856
  function parseModels(content) {
7679
7857
  const nodes = [];
7680
7858
  const relations = [];
@@ -7765,10 +7943,24 @@ function parseEnums(content) {
7765
7943
  return nodes;
7766
7944
  }
7767
7945
  function detect2(rootDir) {
7768
- return (0, import_node_fs6.existsSync)((0, import_node_path6.join)(rootDir, "prisma", "schema.prisma"));
7946
+ const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
7947
+ return paths?.dbConfig.kind === "prisma" && (0, import_node_fs6.existsSync)(paths.dbConfig.schemaPath);
7769
7948
  }
7770
7949
  function generate2(rootDir) {
7771
- const schemaPath = (0, import_node_path6.join)(rootDir, "prisma", "schema.prisma");
7950
+ const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
7951
+ if (paths.dbConfig.kind !== "prisma") {
7952
+ return {
7953
+ metadata: { generated: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10), layer: "db", source: "none" },
7954
+ nodes: [],
7955
+ edges: [],
7956
+ cross_refs: [],
7957
+ contradictions: [],
7958
+ warnings: [],
7959
+ flagged_edges: [],
7960
+ patterns: { total_tables: 0, total_enums: 0, total_relations: 0 }
7961
+ };
7962
+ }
7963
+ const schemaPath = paths.dbConfig.schemaPath;
7772
7964
  const content = (0, import_node_fs6.readFileSync)(schemaPath, "utf-8");
7773
7965
  const { nodes: modelNodes, relations } = parseModels(content);
7774
7966
  const enumNodes = parseEnums(content);
@@ -7789,7 +7981,7 @@ function generate2(rootDir) {
7789
7981
  metadata: {
7790
7982
  generated: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
7791
7983
  scope: "prisma-schema",
7792
- source: "prisma/schema.prisma",
7984
+ source: schemaPath,
7793
7985
  provider: "postgresql",
7794
7986
  layer: "db",
7795
7987
  total_models: modelNodes.length,
@@ -7827,7 +8019,8 @@ var prismaSchemaParser = {
7827
8019
 
7828
8020
  // src/server/graph/parsers/db/sql-migrations.ts
7829
8021
  var import_node_fs7 = require("node:fs");
7830
- var import_node_path7 = require("node:path");
8022
+ var import_node_path6 = require("node:path");
8023
+ init_config();
7831
8024
  var PG_TO_PRISMA = {
7832
8025
  "TEXT": "String",
7833
8026
  "VARCHAR": "String",
@@ -7976,19 +8169,29 @@ function parseUniqueIndex(sql, state) {
7976
8169
  state.uniqueIndexes.get(m[1]).add(m[2]);
7977
8170
  }
7978
8171
  }
7979
- function parseMigrations(rootDir) {
7980
- const migrationsDir = (0, import_node_path7.join)(rootDir, "prisma", "migrations");
8172
+ function discoverMigrationFiles(migrationsDir) {
8173
+ if (!(0, import_node_fs7.existsSync)(migrationsDir)) return [];
8174
+ const out = [];
8175
+ const entries = (0, import_node_fs7.readdirSync)(migrationsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
8176
+ for (const entry of entries) {
8177
+ if (entry.isDirectory()) {
8178
+ const sqlPath = (0, import_node_path6.join)(migrationsDir, entry.name, "migration.sql");
8179
+ if ((0, import_node_fs7.existsSync)(sqlPath)) out.push(sqlPath);
8180
+ } else if (entry.isFile() && entry.name.endsWith(".sql")) {
8181
+ out.push((0, import_node_path6.join)(migrationsDir, entry.name));
8182
+ }
8183
+ }
8184
+ return out;
8185
+ }
8186
+ function parseMigrations(migrationsDir) {
7981
8187
  const state = {
7982
8188
  tables: /* @__PURE__ */ new Map(),
7983
8189
  enums: /* @__PURE__ */ new Map(),
7984
8190
  fks: [],
7985
8191
  uniqueIndexes: /* @__PURE__ */ new Map()
7986
8192
  };
7987
- if (!(0, import_node_fs7.existsSync)(migrationsDir)) return state;
7988
- const dirs = (0, import_node_fs7.readdirSync)(migrationsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
7989
- for (const dir of dirs) {
7990
- const sqlPath = (0, import_node_path7.join)(migrationsDir, dir, "migration.sql");
7991
- if (!(0, import_node_fs7.existsSync)(sqlPath)) continue;
8193
+ if (!migrationsDir) return state;
8194
+ for (const sqlPath of discoverMigrationFiles(migrationsDir)) {
7992
8195
  const sql = (0, import_node_fs7.readFileSync)(sqlPath, "utf-8");
7993
8196
  parseCreateEnum(sql, state);
7994
8197
  parseCreateTable(sql, state);
@@ -7999,9 +8202,8 @@ function parseMigrations(rootDir) {
7999
8202
  }
8000
8203
  return state;
8001
8204
  }
8002
- function loadPrismaState(rootDir) {
8003
- const schemaPath = (0, import_node_path7.join)(rootDir, "prisma", "schema.prisma");
8004
- if (!(0, import_node_fs7.existsSync)(schemaPath)) return null;
8205
+ function loadPrismaState(schemaPath) {
8206
+ if (!schemaPath || !(0, import_node_fs7.existsSync)(schemaPath)) return null;
8005
8207
  const content = (0, import_node_fs7.readFileSync)(schemaPath, "utf-8");
8006
8208
  const tables = /* @__PURE__ */ new Map();
8007
8209
  const enums = /* @__PURE__ */ new Map();
@@ -8166,14 +8368,28 @@ function verify(sqlState, prisma) {
8166
8368
  }
8167
8369
  return { contradictions, flaggedEdges };
8168
8370
  }
8371
+ function migrationsDirFor(rootDir) {
8372
+ const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
8373
+ if (!paths) return null;
8374
+ if (paths.dbConfig.kind === "prisma" || paths.dbConfig.kind === "sql-migrations") {
8375
+ return paths.dbConfig.migrationsDir;
8376
+ }
8377
+ return null;
8378
+ }
8379
+ function schemaPathFor(rootDir) {
8380
+ const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
8381
+ if (!paths) return null;
8382
+ return paths.dbConfig.kind === "prisma" ? paths.dbConfig.schemaPath : null;
8383
+ }
8169
8384
  function detect3(rootDir) {
8170
- const migrationsDir = (0, import_node_path7.join)(rootDir, "prisma", "migrations");
8171
- if (!(0, import_node_fs7.existsSync)(migrationsDir)) return false;
8172
- return (0, import_node_fs7.readdirSync)(migrationsDir, { withFileTypes: true }).some((d) => d.isDirectory() && (0, import_node_fs7.existsSync)((0, import_node_path7.join)(migrationsDir, d.name, "migration.sql")));
8385
+ const dir = migrationsDirFor(rootDir);
8386
+ if (!dir) return false;
8387
+ return discoverMigrationFiles(dir).length > 0;
8173
8388
  }
8174
8389
  function generate3(rootDir) {
8175
- const sqlState = parseMigrations(rootDir);
8176
- const prisma = loadPrismaState(rootDir);
8390
+ const migrationsDir = migrationsDirFor(rootDir);
8391
+ const sqlState = parseMigrations(migrationsDir);
8392
+ const prisma = loadPrismaState(schemaPathFor(rootDir));
8177
8393
  const prismaTableIds = prisma ? new Set(prisma.tables.keys()) : /* @__PURE__ */ new Set();
8178
8394
  const prismaEnumIds = prisma ? new Set(prisma.enums.keys()) : /* @__PURE__ */ new Set();
8179
8395
  const nodes = [];
@@ -8219,7 +8435,7 @@ function generate3(rootDir) {
8219
8435
  metadata: {
8220
8436
  generated: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
8221
8437
  scope: "sql-migrations",
8222
- source: "prisma/migrations/",
8438
+ source: migrationsDir ?? "none",
8223
8439
  layer: "db",
8224
8440
  sql_tables: sqlState.tables.size,
8225
8441
  sql_enums: sqlState.enums.size,
@@ -8458,31 +8674,31 @@ var fetchResolverParser = {
8458
8674
 
8459
8675
  // src/server/graph/parsers/crosslayer/api-annotations.ts
8460
8676
  var import_node_fs8 = require("node:fs");
8461
- var import_node_path8 = require("node:path");
8677
+ var import_node_path7 = require("node:path");
8462
8678
  var API_ANNOTATION_RE = /@api\s+(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+(\/\S+)/g;
8463
8679
  function walk2(dir, exts) {
8464
8680
  if (!(0, import_node_fs8.existsSync)(dir)) return [];
8465
8681
  const results = [];
8466
8682
  for (const entry of (0, import_node_fs8.readdirSync)(dir, { withFileTypes: true })) {
8467
8683
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
8468
- const full = (0, import_node_path8.join)(dir, entry.name);
8684
+ const full = (0, import_node_path7.join)(dir, entry.name);
8469
8685
  if (entry.isDirectory()) {
8470
8686
  results.push(...walk2(full, exts));
8471
- } else if (exts.includes((0, import_node_path8.extname)(entry.name))) {
8687
+ } else if (exts.includes((0, import_node_path7.extname)(entry.name))) {
8472
8688
  results.push(full);
8473
8689
  }
8474
8690
  }
8475
8691
  return results;
8476
8692
  }
8477
8693
  function toNodeId2(srcDir, absPath) {
8478
- return (0, import_node_path8.relative)(srcDir, absPath).replace(/\\/g, "/");
8694
+ return (0, import_node_path7.relative)(srcDir, absPath).replace(/\\/g, "/");
8479
8695
  }
8480
8696
  var apiAnnotationsParser = {
8481
8697
  id: "api-annotations",
8482
8698
  layer: "crosslayer",
8483
8699
  concern: "api-binding",
8484
8700
  detect(rootDir) {
8485
- return (0, import_node_fs8.existsSync)((0, import_node_path8.join)(rootDir, "src"));
8701
+ return (0, import_node_fs8.existsSync)((0, import_node_path7.join)(rootDir, "src"));
8486
8702
  },
8487
8703
  generate(rootDir, layerOutputs) {
8488
8704
  const apiOutput = layerOutputs.get("api");
@@ -8493,7 +8709,7 @@ var apiAnnotationsParser = {
8493
8709
  const uiNodeIds = new Set(uiOutput?.nodes.map((n) => n.id) ?? []);
8494
8710
  const apiRoutes = loadApiRoutesFromOutput(apiOutput);
8495
8711
  const apiPathMap = buildApiPathMap(apiRoutes);
8496
- const srcDir = (0, import_node_path8.join)(rootDir, "src");
8712
+ const srcDir = (0, import_node_path7.join)(rootDir, "src");
8497
8713
  const files = walk2(srcDir, [".ts", ".tsx"]);
8498
8714
  const crossRefs = [];
8499
8715
  const flaggedEdges = [];
@@ -8544,7 +8760,7 @@ var apiAnnotationsParser = {
8544
8760
 
8545
8761
  // src/server/graph/parsers/crosslayer/url-literal-scanner.ts
8546
8762
  var import_node_fs9 = require("node:fs");
8547
- var import_node_path9 = require("node:path");
8763
+ var import_node_path8 = require("node:path");
8548
8764
  init_config();
8549
8765
  var URL_LITERAL_RE = /['"`](\/api\/[^'"`\s]+?)['"`]/g;
8550
8766
  function walk3(dir, exts) {
@@ -8552,17 +8768,17 @@ function walk3(dir, exts) {
8552
8768
  const results = [];
8553
8769
  for (const entry of (0, import_node_fs9.readdirSync)(dir, { withFileTypes: true })) {
8554
8770
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
8555
- const full = (0, import_node_path9.join)(dir, entry.name);
8771
+ const full = (0, import_node_path8.join)(dir, entry.name);
8556
8772
  if (entry.isDirectory()) {
8557
8773
  results.push(...walk3(full, exts));
8558
- } else if (exts.includes((0, import_node_path9.extname)(entry.name))) {
8774
+ } else if (exts.includes((0, import_node_path8.extname)(entry.name))) {
8559
8775
  results.push(full);
8560
8776
  }
8561
8777
  }
8562
8778
  return results;
8563
8779
  }
8564
8780
  function toNodeId3(srcDir, absPath) {
8565
- return (0, import_node_path9.relative)(srcDir, absPath).replace(/\\/g, "/");
8781
+ return (0, import_node_path8.relative)(srcDir, absPath).replace(/\\/g, "/");
8566
8782
  }
8567
8783
  var urlLiteralScannerParser = {
8568
8784
  id: "url-literal-scanner",
@@ -8583,7 +8799,7 @@ var urlLiteralScannerParser = {
8583
8799
  const apiPathMap = buildApiPathMap(apiRoutes);
8584
8800
  const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
8585
8801
  const srcDir = paths.srcDir;
8586
- const clientDir = (0, import_node_path9.join)(srcDir, "client");
8802
+ const clientDir = (0, import_node_path8.join)(srcDir, "client");
8587
8803
  const files = [
8588
8804
  ...walk3(clientDir, [".ts", ".tsx"]),
8589
8805
  ...walk3(paths.appDir, [".ts", ".tsx"])
@@ -8625,7 +8841,7 @@ var urlLiteralScannerParser = {
8625
8841
 
8626
8842
  // src/server/graph/parsers/static/static-values.ts
8627
8843
  var import_node_fs10 = require("node:fs");
8628
- var import_node_path10 = require("node:path");
8844
+ var import_node_path9 = require("node:path");
8629
8845
  var parseCode = null;
8630
8846
  function tryLoadTreeSitter() {
8631
8847
  if (parseCode) return true;
@@ -8658,8 +8874,8 @@ function extractEnumValues(rootDir) {
8658
8874
  const nodes = [];
8659
8875
  const edges = [];
8660
8876
  const schemaPaths = [
8661
- (0, import_node_path10.join)(rootDir, "prisma", "schema.prisma"),
8662
- (0, import_node_path10.join)(rootDir, "prisma", "schema")
8877
+ (0, import_node_path9.join)(rootDir, "prisma", "schema.prisma"),
8878
+ (0, import_node_path9.join)(rootDir, "prisma", "schema")
8663
8879
  ];
8664
8880
  let content = "";
8665
8881
  for (const p of schemaPaths) {
@@ -8670,7 +8886,7 @@ function extractEnumValues(rootDir) {
8670
8886
  content = (0, import_node_fs10.readFileSync)(p, "utf-8");
8671
8887
  } else if (stat.isDirectory()) {
8672
8888
  const files = (0, import_node_fs10.readdirSync)(p).filter((f) => f.endsWith(".prisma"));
8673
- content = files.map((f) => (0, import_node_fs10.readFileSync)((0, import_node_path10.join)(p, f), "utf-8")).join("\n");
8889
+ content = files.map((f) => (0, import_node_fs10.readFileSync)((0, import_node_path9.join)(p, f), "utf-8")).join("\n");
8674
8890
  }
8675
8891
  } catch {
8676
8892
  continue;
@@ -8826,14 +9042,14 @@ function extractSeedData(rootDir) {
8826
9042
  const nodes = [];
8827
9043
  const edges = [];
8828
9044
  const seedFiles = [
8829
- (0, import_node_path10.join)(rootDir, "prisma", "seed.ts"),
8830
- (0, import_node_path10.join)(rootDir, "prisma", "seed.js"),
8831
- (0, import_node_path10.join)(rootDir, "src", "server", "lib", "system-tags.ts")
9045
+ (0, import_node_path9.join)(rootDir, "prisma", "seed.ts"),
9046
+ (0, import_node_path9.join)(rootDir, "prisma", "seed.js"),
9047
+ (0, import_node_path9.join)(rootDir, "src", "server", "lib", "system-tags.ts")
8832
9048
  ].filter(import_node_fs10.existsSync);
8833
9049
  const useTreeSitter = tryLoadTreeSitter();
8834
9050
  for (const filePath of seedFiles) {
8835
9051
  const content = (0, import_node_fs10.readFileSync)(filePath, "utf-8");
8836
- const relPath = (0, import_node_path10.relative)(rootDir, filePath);
9052
+ const relPath = (0, import_node_path9.relative)(rootDir, filePath);
8837
9053
  const seeded = detectSeededArrays(content, relPath);
8838
9054
  let astRoot = null;
8839
9055
  if (useTreeSitter && parseCode) {
@@ -8931,7 +9147,7 @@ function walkDir(dir, exts) {
8931
9147
  const results = [];
8932
9148
  for (const entry of (0, import_node_fs10.readdirSync)(dir, { withFileTypes: true })) {
8933
9149
  if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist") continue;
8934
- const full = (0, import_node_path10.join)(dir, entry.name);
9150
+ const full = (0, import_node_path9.join)(dir, entry.name);
8935
9151
  if (entry.isDirectory()) results.push(...walkDir(full, exts));
8936
9152
  else if (exts.some((ext) => entry.name.endsWith(ext))) results.push(full);
8937
9153
  }
@@ -8939,11 +9155,11 @@ function walkDir(dir, exts) {
8939
9155
  }
8940
9156
  function extractConstants(rootDir) {
8941
9157
  const nodes = [];
8942
- const srcDir = (0, import_node_path10.join)(rootDir, "src");
9158
+ const srcDir = (0, import_node_path9.join)(rootDir, "src");
8943
9159
  if (!(0, import_node_fs10.existsSync)(srcDir)) return { nodes };
8944
9160
  for (const filePath of walkDir(srcDir, [".ts", ".tsx"])) {
8945
9161
  const content = (0, import_node_fs10.readFileSync)(filePath, "utf-8");
8946
- const relPath = (0, import_node_path10.relative)(rootDir, filePath);
9162
+ const relPath = (0, import_node_path9.relative)(rootDir, filePath);
8947
9163
  const constArrayRe = /export\s+const\s+([A-Z][A-Z_0-9]+)\s*(?::[^=]+)?\s*=\s*\[/g;
8948
9164
  let cm;
8949
9165
  while ((cm = constArrayRe.exec(content)) !== null) {
@@ -8976,7 +9192,7 @@ function extractConstants(rootDir) {
8976
9192
  return { nodes };
8977
9193
  }
8978
9194
  function detect4(rootDir) {
8979
- return (0, import_node_fs10.existsSync)((0, import_node_path10.join)(rootDir, "prisma", "schema.prisma")) || (0, import_node_fs10.existsSync)((0, import_node_path10.join)(rootDir, "prisma", "seed.ts"));
9195
+ return (0, import_node_fs10.existsSync)((0, import_node_path9.join)(rootDir, "prisma", "schema.prisma")) || (0, import_node_fs10.existsSync)((0, import_node_path9.join)(rootDir, "prisma", "seed.ts"));
8980
9196
  }
8981
9197
  function generate4(rootDir) {
8982
9198
  const enumResult = extractEnumValues(rootDir);
@@ -9052,7 +9268,7 @@ var staticValuesParser = {
9052
9268
 
9053
9269
  // src/server/graph/parsers/crosslayer/static-ref-scanner.ts
9054
9270
  var import_node_fs11 = require("node:fs");
9055
- var import_node_path11 = require("node:path");
9271
+ var import_node_path10 = require("node:path");
9056
9272
  init_config();
9057
9273
  var MIN_VALUE_LENGTH = 4;
9058
9274
  var SKIP_VALUES = /* @__PURE__ */ new Set([
@@ -9196,11 +9412,11 @@ var staticRefScannerParser = {
9196
9412
  if (!paths) return { cross_refs: [], flagged_edges: [], warnings: [] };
9197
9413
  const srcDir = paths.srcDir;
9198
9414
  const files = [
9199
- ...walkWithIgnore((0, import_node_path11.join)(srcDir, "client"), [".ts", ".tsx"]),
9415
+ ...walkWithIgnore((0, import_node_path10.join)(srcDir, "client"), [".ts", ".tsx"]),
9200
9416
  ...walkWithIgnore(paths.appDir, [".ts", ".tsx"]),
9201
- ...walkWithIgnore((0, import_node_path11.join)(srcDir, "server"), [".ts", ".tsx"]),
9202
- ...walkWithIgnore((0, import_node_path11.join)(srcDir, "lib"), [".ts", ".tsx"]),
9203
- ...walkWithIgnore((0, import_node_path11.join)(srcDir, "config"), [".ts", ".tsx"])
9417
+ ...walkWithIgnore((0, import_node_path10.join)(srcDir, "server"), [".ts", ".tsx"]),
9418
+ ...walkWithIgnore((0, import_node_path10.join)(srcDir, "lib"), [".ts", ".tsx"]),
9419
+ ...walkWithIgnore((0, import_node_path10.join)(srcDir, "config"), [".ts", ".tsx"])
9204
9420
  ];
9205
9421
  const uiOutput = layerOutputs.get("ui");
9206
9422
  const apiOutput = layerOutputs.get("api");
@@ -9218,7 +9434,7 @@ var staticRefScannerParser = {
9218
9434
  const seen = /* @__PURE__ */ new Set();
9219
9435
  let filesScanned = 0;
9220
9436
  for (const absPath of files) {
9221
- const sourceId = (0, import_node_path11.relative)(srcDir, absPath).replace(/\\/g, "/");
9437
+ const sourceId = (0, import_node_path10.relative)(srcDir, absPath).replace(/\\/g, "/");
9222
9438
  const sourceLayer = uiNodeIds.has(sourceId) ? "ui" : apiNodeIds.has(sourceId) ? "api" : null;
9223
9439
  if (!sourceLayer) continue;
9224
9440
  const content = (0, import_node_fs11.readFileSync)(absPath, "utf-8");
@@ -9337,7 +9553,7 @@ function registerBuiltins(registry, disabled) {
9337
9553
  function loadCustomParsers(registry, config, rootDir, disabled) {
9338
9554
  for (const entry of config.parsers?.custom ?? []) {
9339
9555
  try {
9340
- const absPath = (0, import_node_path12.resolve)(rootDir, entry.path);
9556
+ const absPath = (0, import_node_path11.resolve)(rootDir, entry.path);
9341
9557
  const mod = require(absPath);
9342
9558
  const parser = "default" in mod ? mod.default : mod;
9343
9559
  if (disabled.has(parser.id)) continue;
@@ -9467,7 +9683,7 @@ function applyCrossLayerResults(uiOutput, results) {
9467
9683
 
9468
9684
  // src/server/graph/core/graph-builder.ts
9469
9685
  function readGraphFromDisk(rootDir, layer) {
9470
- const filePath = (0, import_node_path13.join)(rootDir, ".launchsecure", "graphs", `${layer}.json`);
9686
+ const filePath = (0, import_node_path12.join)(rootDir, ".launchsecure", "graphs", `${layer}.json`);
9471
9687
  if (!(0, import_node_fs12.existsSync)(filePath)) return null;
9472
9688
  try {
9473
9689
  return JSON.parse((0, import_node_fs12.readFileSync)(filePath, "utf-8"));
@@ -9571,11 +9787,11 @@ function generateAll(rootDir) {
9571
9787
  init_config();
9572
9788
 
9573
9789
  // src/server/graph/core/tagger-registry.ts
9574
- var import_node_path15 = require("node:path");
9790
+ var import_node_path14 = require("node:path");
9575
9791
 
9576
9792
  // src/server/graph/taggers/module-tagger.ts
9577
9793
  var import_node_fs13 = require("node:fs");
9578
- var import_node_path14 = require("node:path");
9794
+ var import_node_path13 = require("node:path");
9579
9795
  function matchGlob(pattern, id) {
9580
9796
  const patParts = pattern.split("/");
9581
9797
  const idParts = id.split("/");
@@ -9608,13 +9824,13 @@ function detectConventionDirs(rootDir, extraConventionDirs = []) {
9608
9824
  const conventionDirs = [...CONVENTION_DIRS_BUILTIN, ...extraConventionDirs];
9609
9825
  const searchDirs = [
9610
9826
  rootDir,
9611
- (0, import_node_path14.join)(rootDir, "src"),
9612
- (0, import_node_path14.join)(rootDir, "app"),
9613
- (0, import_node_path14.join)(rootDir, "lib")
9827
+ (0, import_node_path13.join)(rootDir, "src"),
9828
+ (0, import_node_path13.join)(rootDir, "app"),
9829
+ (0, import_node_path13.join)(rootDir, "lib")
9614
9830
  ];
9615
9831
  for (const base of searchDirs) {
9616
9832
  for (const convention of conventionDirs) {
9617
- const dir = (0, import_node_path14.join)(base, convention);
9833
+ const dir = (0, import_node_path13.join)(base, convention);
9618
9834
  if (!(0, import_node_fs13.existsSync)(dir)) continue;
9619
9835
  try {
9620
9836
  const stat = (0, import_node_fs13.statSync)(dir);
@@ -9913,7 +10129,7 @@ function loadCustomTaggers(registry, config, rootDir, disabled) {
9913
10129
  for (const entry of config.taggers?.custom ?? []) {
9914
10130
  if (disabled.has(entry.id)) continue;
9915
10131
  try {
9916
- const absPath = (0, import_node_path15.resolve)(rootDir, entry.path);
10132
+ const absPath = (0, import_node_path14.resolve)(rootDir, entry.path);
9917
10133
  const mod = require(absPath);
9918
10134
  const tagger = "default" in mod ? mod.default : mod;
9919
10135
  const override = config.taggers?.trackUntagged?.[tagger.id];
@@ -9937,12 +10153,12 @@ function createTaggerRegistry(config, rootDir) {
9937
10153
 
9938
10154
  // src/server/graph/core/tag-store.ts
9939
10155
  var import_node_fs14 = require("node:fs");
9940
- var import_node_path16 = require("node:path");
10156
+ var import_node_path15 = require("node:path");
9941
10157
  var TAGS_FILENAME = "tags.json";
9942
10158
  var GRAPHS_DIR = ".launchsecure/graphs";
9943
10159
  var tagCache = /* @__PURE__ */ new Map();
9944
10160
  function tagsFilePath(rootDir) {
9945
- return (0, import_node_path16.join)(rootDir, GRAPHS_DIR, TAGS_FILENAME);
10161
+ return (0, import_node_path15.join)(rootDir, GRAPHS_DIR, TAGS_FILENAME);
9946
10162
  }
9947
10163
  function readTagStore(rootDir) {
9948
10164
  const filePath = tagsFilePath(rootDir);
@@ -9963,7 +10179,7 @@ function readTagStore(rootDir) {
9963
10179
  }
9964
10180
  function writeTagStore(rootDir, store) {
9965
10181
  const filePath = tagsFilePath(rootDir);
9966
- const dir = (0, import_node_path16.dirname)(filePath);
10182
+ const dir = (0, import_node_path15.dirname)(filePath);
9967
10183
  (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
9968
10184
  const cleaned = {};
9969
10185
  for (const [nodeId, tags] of Object.entries(store)) {
@@ -9994,20 +10210,20 @@ function removeTag(rootDir, nodeId, key) {
9994
10210
  init_ts_extractor();
9995
10211
  var GRAPHS_DIR2 = ".launchsecure/graphs";
9996
10212
  function getAvailableLayers(rootDir) {
9997
- const dir = (0, import_node_path17.join)(rootDir, GRAPHS_DIR2);
10213
+ const dir = (0, import_node_path16.join)(rootDir, GRAPHS_DIR2);
9998
10214
  if (!(0, import_node_fs15.existsSync)(dir)) return [];
9999
10215
  return (0, import_node_fs15.readdirSync)(dir).filter((f) => f.endsWith(".json") && f !== "tags.json").map((f) => f.replace(".json", ""));
10000
10216
  }
10001
10217
  var graphCache = /* @__PURE__ */ new Map();
10002
10218
  var taggedCache = /* @__PURE__ */ new Map();
10003
10219
  function graphsDir(rootDir) {
10004
- return (0, import_node_path17.join)(rootDir, GRAPHS_DIR2);
10220
+ return (0, import_node_path16.join)(rootDir, GRAPHS_DIR2);
10005
10221
  }
10006
10222
  function graphFilePath(rootDir, layer) {
10007
- return (0, import_node_path17.join)(graphsDir(rootDir), `${layer}.json`);
10223
+ return (0, import_node_path16.join)(graphsDir(rootDir), `${layer}.json`);
10008
10224
  }
10009
10225
  function tagsFilePath2(rootDir) {
10010
- return (0, import_node_path17.join)(graphsDir(rootDir), "tags.json");
10226
+ return (0, import_node_path16.join)(graphsDir(rootDir), "tags.json");
10011
10227
  }
10012
10228
  function getMtimeMs(filePath) {
10013
10229
  if (!(0, import_node_fs15.existsSync)(filePath)) return 0;
@@ -10160,7 +10376,7 @@ async function handleGraphCommand(subcommand, args) {
10160
10376
 
10161
10377
  // src/server/graph-mcp.ts
10162
10378
  var import_node_fs19 = require("node:fs");
10163
- var import_node_path21 = require("node:path");
10379
+ var import_node_path20 = require("node:path");
10164
10380
  var import_node_child_process2 = require("node:child_process");
10165
10381
  var import_node_os2 = require("node:os");
10166
10382
 
@@ -10168,15 +10384,15 @@ var import_node_os2 = require("node:os");
10168
10384
  var import_node_child_process = require("node:child_process");
10169
10385
  var import_node_fs16 = require("node:fs");
10170
10386
  var import_node_os = require("node:os");
10171
- var import_node_path18 = require("node:path");
10387
+ var import_node_path17 = require("node:path");
10172
10388
  function lockDir(projectRoot) {
10173
10389
  if (projectRoot) {
10174
- return (0, import_node_path18.join)(projectRoot, ".launchsecure");
10390
+ return (0, import_node_path17.join)(projectRoot, ".launchsecure");
10175
10391
  }
10176
- return (0, import_node_path18.join)((0, import_node_os.homedir)(), ".launchsecure");
10392
+ return (0, import_node_path17.join)((0, import_node_os.homedir)(), ".launchsecure");
10177
10393
  }
10178
10394
  function lockPath(projectRoot) {
10179
- return (0, import_node_path18.join)(lockDir(projectRoot), "launch-chart.lock");
10395
+ return (0, import_node_path17.join)(lockDir(projectRoot), "launch-chart.lock");
10180
10396
  }
10181
10397
  var _activeProjectRoot;
10182
10398
  function readLock(projectRoot) {
@@ -10255,7 +10471,7 @@ init_config();
10255
10471
 
10256
10472
  // src/server/graph/core/language-detection.ts
10257
10473
  var import_node_fs17 = require("node:fs");
10258
- var import_node_path19 = require("node:path");
10474
+ var import_node_path18 = require("node:path");
10259
10475
  var EXTENSION_TO_LANGUAGE = {
10260
10476
  // Web / Frontend
10261
10477
  ".ts": "typescript",
@@ -10378,9 +10594,9 @@ function walkForExtensions(dir, extCounts, depth = 0) {
10378
10594
  if (entry.name.startsWith(".") && entry.isDirectory()) continue;
10379
10595
  if (entry.isDirectory()) {
10380
10596
  if (IGNORE_DIRS.has(entry.name)) continue;
10381
- walkForExtensions((0, import_node_path19.join)(dir, entry.name), extCounts, depth + 1);
10597
+ walkForExtensions((0, import_node_path18.join)(dir, entry.name), extCounts, depth + 1);
10382
10598
  } else {
10383
- const ext = (0, import_node_path19.extname)(entry.name).toLowerCase();
10599
+ const ext = (0, import_node_path18.extname)(entry.name).toLowerCase();
10384
10600
  if (ext && EXTENSION_TO_LANGUAGE[ext]) {
10385
10601
  extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
10386
10602
  }
@@ -10422,9 +10638,9 @@ function detectLanguages(rootDir, supportedLanguages) {
10422
10638
 
10423
10639
  // src/server/graph/core/audit-core.ts
10424
10640
  var import_node_fs18 = require("node:fs");
10425
- var import_node_path20 = require("node:path");
10641
+ var import_node_path19 = require("node:path");
10426
10642
  function readGraphFile(rootDir, layer) {
10427
- const filePath = (0, import_node_path20.join)(rootDir, ".launchsecure", "graphs", `${layer}.json`);
10643
+ const filePath = (0, import_node_path19.join)(rootDir, ".launchsecure", "graphs", `${layer}.json`);
10428
10644
  if (!(0, import_node_fs18.existsSync)(filePath)) return null;
10429
10645
  try {
10430
10646
  return JSON.parse((0, import_node_fs18.readFileSync)(filePath, "utf-8"));
@@ -10471,7 +10687,7 @@ function checkUnprotectedRoutes(rootDir) {
10471
10687
  const api = readGraphFile(rootDir, "api");
10472
10688
  const staticGraph = readGraphFile(rootDir, "static");
10473
10689
  if (!api) return buildReport("api", "unprotected_routes", findings);
10474
- const routePermsPath = (0, import_node_path20.join)(rootDir, "src", "config", "route-permissions.ts");
10690
+ const routePermsPath = (0, import_node_path19.join)(rootDir, "src", "config", "route-permissions.ts");
10475
10691
  let routePermsContent = "";
10476
10692
  if ((0, import_node_fs18.existsSync)(routePermsPath)) {
10477
10693
  routePermsContent = (0, import_node_fs18.readFileSync)(routePermsPath, "utf-8");
@@ -10551,7 +10767,7 @@ function checkUnenforcedPermissions(rootDir) {
10551
10767
  const staticGraph = readGraphFile(rootDir, "static");
10552
10768
  if (!staticGraph) return buildReport("static", "unenforced_permissions", findings);
10553
10769
  const permissions = staticGraph.nodes.filter((n) => n.type === "seed_permission").map((n) => ({ id: n.id, key: n.value, name: n.name }));
10554
- const routePermsPath = (0, import_node_path20.join)(rootDir, "src", "config", "route-permissions.ts");
10770
+ const routePermsPath = (0, import_node_path19.join)(rootDir, "src", "config", "route-permissions.ts");
10555
10771
  let routePermsContent = "";
10556
10772
  if ((0, import_node_fs18.existsSync)(routePermsPath)) {
10557
10773
  routePermsContent = (0, import_node_fs18.readFileSync)(routePermsPath, "utf-8");
@@ -10584,7 +10800,7 @@ function checkHardcodedValues(rootDir) {
10584
10800
  const seen = /* @__PURE__ */ new Set();
10585
10801
  for (const node of api.nodes) {
10586
10802
  if (node.type !== "endpoint") continue;
10587
- const filePath = (0, import_node_path20.join)(rootDir, "src", node.id);
10803
+ const filePath = (0, import_node_path19.join)(rootDir, "src", node.id);
10588
10804
  if (!(0, import_node_fs18.existsSync)(filePath)) continue;
10589
10805
  const content = (0, import_node_fs18.readFileSync)(filePath, "utf-8");
10590
10806
  let m;
@@ -11489,11 +11705,11 @@ function handleReadGraph(args) {
11489
11705
  return okJson(result);
11490
11706
  }
11491
11707
  function nodeToFilePath(rootDir, layer, nodeId) {
11492
- if (layer === "ui" || layer === "api") return (0, import_node_path21.join)(rootDir, "src", nodeId);
11493
- if (layer === "db") return (0, import_node_path21.join)(rootDir, "prisma", "schema.prisma");
11494
- const withSrc = (0, import_node_path21.join)(rootDir, "src", nodeId);
11708
+ if (layer === "ui" || layer === "api") return (0, import_node_path20.join)(rootDir, "src", nodeId);
11709
+ if (layer === "db") return (0, import_node_path20.join)(rootDir, "prisma", "schema.prisma");
11710
+ const withSrc = (0, import_node_path20.join)(rootDir, "src", nodeId);
11495
11711
  if ((0, import_node_fs19.existsSync)(withSrc)) return withSrc;
11496
- const direct = (0, import_node_path21.join)(rootDir, nodeId);
11712
+ const direct = (0, import_node_path20.join)(rootDir, nodeId);
11497
11713
  if ((0, import_node_fs19.existsSync)(direct)) return direct;
11498
11714
  return null;
11499
11715
  }
@@ -11706,9 +11922,9 @@ function handleStartChartServer(args) {
11706
11922
  });
11707
11923
  }
11708
11924
  const entryPath = process.argv[1];
11709
- const logDir = (0, import_node_path21.join)((0, import_node_os2.homedir)(), ".launchsecure");
11925
+ const logDir = (0, import_node_path20.join)((0, import_node_os2.homedir)(), ".launchsecure");
11710
11926
  (0, import_node_fs19.mkdirSync)(logDir, { recursive: true });
11711
- const logPath = (0, import_node_path21.join)(logDir, "launch-chart.log");
11927
+ const logPath = (0, import_node_path20.join)(logDir, "launch-chart.log");
11712
11928
  const out = (0, import_node_fs19.openSync)(logPath, "a");
11713
11929
  const err2 = (0, import_node_fs19.openSync)(logPath, "a");
11714
11930
  const portArgs = args.port ? ["--port", String(args.port)] : [];
@@ -11830,18 +12046,18 @@ function handleDetectProjectStack() {
11830
12046
  if (ref.type === "references_api") stats.references_api++;
11831
12047
  }
11832
12048
  }
11833
- const srcDir = (0, import_node_path21.join)(rootDir, "src");
12049
+ const srcDir = (0, import_node_path20.join)(rootDir, "src");
11834
12050
  if ((0, import_node_fs19.existsSync)(srcDir)) {
11835
12051
  const scanDir = (dir) => {
11836
12052
  if (!(0, import_node_fs19.existsSync)(dir)) return;
11837
12053
  for (const entry of (0, import_node_fs19.readdirSync)(dir, { withFileTypes: true })) {
11838
12054
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
11839
- const full = (0, import_node_path21.join)(dir, entry.name);
12055
+ const full = (0, import_node_path20.join)(dir, entry.name);
11840
12056
  if (entry.isDirectory()) {
11841
12057
  scanDir(full);
11842
12058
  continue;
11843
12059
  }
11844
- if (![".ts", ".tsx"].includes((0, import_node_path21.extname)(entry.name))) continue;
12060
+ if (![".ts", ".tsx"].includes((0, import_node_path20.extname)(entry.name))) continue;
11845
12061
  try {
11846
12062
  const content = (0, import_node_fs19.readFileSync)(full, "utf-8");
11847
12063
  const matches = content.match(/@api\s+(GET|POST|PUT|DELETE|PATCH)\s+\/\S+/g);
@@ -12062,7 +12278,7 @@ function parseArgs() {
12062
12278
  return { port, token, serverUrl: LAUNCHSECURE_URL, subcommand };
12063
12279
  }
12064
12280
  function tryListen(server, port, maxRetries = 10) {
12065
- return new Promise((resolve3, reject) => {
12281
+ return new Promise((resolve4, reject) => {
12066
12282
  let attempts = 0;
12067
12283
  function attempt(p) {
12068
12284
  server.once("error", (err2) => {
@@ -12073,7 +12289,7 @@ function tryListen(server, port, maxRetries = 10) {
12073
12289
  reject(err2);
12074
12290
  }
12075
12291
  });
12076
- server.listen(p, () => resolve3(p));
12292
+ server.listen(p, () => resolve4(p));
12077
12293
  }
12078
12294
  attempt(port);
12079
12295
  });
@@ -12094,7 +12310,7 @@ function saveCredentials(creds) {
12094
12310
  });
12095
12311
  }
12096
12312
  function verifyToken(serverUrl, token) {
12097
- return new Promise((resolve3) => {
12313
+ return new Promise((resolve4) => {
12098
12314
  const url = new URL("/api/mcp/verify", serverUrl);
12099
12315
  const body = JSON.stringify({ token });
12100
12316
  const mod = url.protocol === "https:" ? import_https.default : import_http.default;
@@ -12109,30 +12325,30 @@ function verifyToken(serverUrl, token) {
12109
12325
  res.on("data", (chunk) => data += chunk);
12110
12326
  res.on("end", () => {
12111
12327
  try {
12112
- resolve3(JSON.parse(data));
12328
+ resolve4(JSON.parse(data));
12113
12329
  } catch {
12114
- resolve3({ valid: false, error: "Invalid response from server" });
12330
+ resolve4({ valid: false, error: "Invalid response from server" });
12115
12331
  }
12116
12332
  });
12117
12333
  });
12118
12334
  req.on("error", (err2) => {
12119
- resolve3({ valid: false, error: `Cannot reach server: ${err2.message}` });
12335
+ resolve4({ valid: false, error: `Cannot reach server: ${err2.message}` });
12120
12336
  });
12121
12337
  req.setTimeout(1e4, () => {
12122
12338
  req.destroy();
12123
- resolve3({ valid: false, error: "Connection timed out" });
12339
+ resolve4({ valid: false, error: "Connection timed out" });
12124
12340
  });
12125
12341
  req.write(body);
12126
12342
  req.end();
12127
12343
  });
12128
12344
  }
12129
12345
  function httpRequest(reqUrl, options, body, timeout = 3e4) {
12130
- return new Promise((resolve3, reject) => {
12346
+ return new Promise((resolve4, reject) => {
12131
12347
  const mod = reqUrl.protocol === "https:" ? import_https.default : import_http.default;
12132
12348
  const r = mod.request(reqUrl, options, (resp) => {
12133
12349
  let data = "";
12134
12350
  resp.on("data", (chunk) => data += chunk);
12135
- resp.on("end", () => resolve3({ status: resp.statusCode || 0, headers: resp.headers, body: data }));
12351
+ resp.on("end", () => resolve4({ status: resp.statusCode || 0, headers: resp.headers, body: data }));
12136
12352
  });
12137
12353
  r.on("error", reject);
12138
12354
  r.setTimeout(timeout, () => {