@launchsecure/launch-kit 0.0.29 → 0.0.30

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 (191) hide show
  1. package/dist/beacon/beacon.mjs +2759 -1246
  2. package/dist/beacon/beacon.mjs.map +1 -1
  3. package/dist/beacon/beacon.umd.js +710 -95
  4. package/dist/beacon/beacon.umd.js.map +1 -1
  5. package/dist/beacon/types/core.d.ts +14 -0
  6. package/dist/beacon/types/core.d.ts.map +1 -0
  7. package/dist/beacon/types/ctx.d.ts +14 -0
  8. package/dist/beacon/types/ctx.d.ts.map +1 -0
  9. package/dist/beacon/types/element.d.ts +16 -48
  10. package/dist/beacon/types/element.d.ts.map +1 -1
  11. package/dist/beacon/types/index.d.ts +5 -4
  12. package/dist/beacon/types/index.d.ts.map +1 -1
  13. package/dist/beacon/types/internal/annotation-cache.d.ts +10 -0
  14. package/dist/beacon/types/internal/annotation-cache.d.ts.map +1 -0
  15. package/dist/beacon/types/internal/element-capture.d.ts +19 -0
  16. package/dist/beacon/types/internal/element-capture.d.ts.map +1 -0
  17. package/dist/beacon/types/internal/event-buffer.d.ts +16 -0
  18. package/dist/beacon/types/internal/event-buffer.d.ts.map +1 -0
  19. package/dist/beacon/types/internal/framework-detect.d.ts +6 -0
  20. package/dist/beacon/types/internal/framework-detect.d.ts.map +1 -0
  21. package/dist/beacon/types/internal/markers.d.ts +17 -0
  22. package/dist/beacon/types/internal/markers.d.ts.map +1 -0
  23. package/dist/beacon/types/internal/monitor/capture-dom.d.ts +14 -0
  24. package/dist/beacon/types/internal/monitor/capture-dom.d.ts.map +1 -0
  25. package/dist/beacon/types/internal/monitor/capture-network.d.ts +12 -0
  26. package/dist/beacon/types/internal/monitor/capture-network.d.ts.map +1 -0
  27. package/dist/beacon/types/internal/monitor/overlay.d.ts +16 -0
  28. package/dist/beacon/types/internal/monitor/overlay.d.ts.map +1 -0
  29. package/dist/beacon/types/internal/monitor/session.d.ts +41 -0
  30. package/dist/beacon/types/internal/monitor/session.d.ts.map +1 -0
  31. package/dist/beacon/types/{monitor → internal/monitor}/transport.d.ts +3 -3
  32. package/dist/beacon/types/internal/monitor/transport.d.ts.map +1 -0
  33. package/dist/beacon/types/{monitor/types.d.ts → internal/monitor/wire.d.ts} +69 -27
  34. package/dist/beacon/types/internal/monitor/wire.d.ts.map +1 -0
  35. package/dist/beacon/types/{ui → internal}/pick-mode-overlay.d.ts +4 -5
  36. package/dist/beacon/types/internal/pick-mode-overlay.d.ts.map +1 -0
  37. package/dist/beacon/types/{capture → internal}/picker.d.ts +0 -1
  38. package/dist/beacon/types/internal/picker.d.ts.map +1 -0
  39. package/dist/beacon/types/{ui → internal}/pin-popover.d.ts +1 -1
  40. package/dist/beacon/types/internal/pin-popover.d.ts.map +1 -0
  41. package/dist/beacon/types/{capture → internal}/screenshot.d.ts +1 -0
  42. package/dist/beacon/types/internal/screenshot.d.ts.map +1 -0
  43. package/dist/beacon/types/internal/selector.d.ts.map +1 -0
  44. package/dist/beacon/types/plugins/domEle.d.ts +14 -0
  45. package/dist/beacon/types/plugins/domEle.d.ts.map +1 -0
  46. package/dist/beacon/types/plugins/domSS.d.ts +8 -0
  47. package/dist/beacon/types/plugins/domSS.d.ts.map +1 -0
  48. package/dist/beacon/types/plugins/errors.d.ts +3 -0
  49. package/dist/beacon/types/plugins/errors.d.ts.map +1 -0
  50. package/dist/beacon/types/plugins/index.d.ts +8 -0
  51. package/dist/beacon/types/plugins/index.d.ts.map +1 -0
  52. package/dist/beacon/types/plugins/liveMonitor.d.ts +14 -0
  53. package/dist/beacon/types/plugins/liveMonitor.d.ts.map +1 -0
  54. package/dist/beacon/types/plugins/metadata.d.ts +3 -0
  55. package/dist/beacon/types/plugins/metadata.d.ts.map +1 -0
  56. package/dist/beacon/types/registry.d.ts +33 -0
  57. package/dist/beacon/types/registry.d.ts.map +1 -0
  58. package/dist/beacon/types/styles.d.ts +8 -0
  59. package/dist/beacon/types/styles.d.ts.map +1 -0
  60. package/dist/beacon/types/transport.d.ts +3 -0
  61. package/dist/beacon/types/transport.d.ts.map +1 -0
  62. package/dist/beacon/types/types.d.ts +152 -68
  63. package/dist/beacon/types/types.d.ts.map +1 -1
  64. package/dist/beacon/types/ui/dialog.d.ts +53 -0
  65. package/dist/beacon/types/ui/dialog.d.ts.map +1 -0
  66. package/dist/beacon/types/ui/form.d.ts +7 -0
  67. package/dist/beacon/types/ui/form.d.ts.map +1 -0
  68. package/dist/beacon/types/ui/overlay.d.ts +6 -0
  69. package/dist/beacon/types/ui/overlay.d.ts.map +1 -0
  70. package/dist/deck-client/assets/{_baseUniq-W2JQDmje.js → _baseUniq-DCt2IMRR.js} +1 -1
  71. package/dist/deck-client/assets/{arc-DIBWAId9.js → arc-h-ifqmNR.js} +1 -1
  72. package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-CAIRMvJK.js → architectureDiagram-Q4EWVU46-C9dITSPv.js} +1 -1
  73. package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-BeNaNiOi.js → blockDiagram-DXYQGD6D-BHuJT34t.js} +1 -1
  74. package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-B9Ozi62h.js → c4Diagram-AHTNJAMY-CpvMGtDG.js} +1 -1
  75. package/dist/deck-client/assets/channel-2PZVMiXf.js +1 -0
  76. package/dist/deck-client/assets/{chunk-4BX2VUAB-D7AZ47dt.js → chunk-4BX2VUAB-B6md1VIm.js} +1 -1
  77. package/dist/deck-client/assets/{chunk-4TB4RGXK-DnVnNPcI.js → chunk-4TB4RGXK-BmEnX8ik.js} +1 -1
  78. package/dist/deck-client/assets/{chunk-55IACEB6-UKYs-YNd.js → chunk-55IACEB6-BZPUyZAZ.js} +1 -1
  79. package/dist/deck-client/assets/{chunk-EDXVE4YY-D43b-SKn.js → chunk-EDXVE4YY-BWwNUK-l.js} +1 -1
  80. package/dist/deck-client/assets/{chunk-FMBD7UC4-QzBAoyyW.js → chunk-FMBD7UC4-o7gSppGI.js} +1 -1
  81. package/dist/deck-client/assets/{chunk-OYMX7WX6-Cjif4r6W.js → chunk-OYMX7WX6-C4KoTL5p.js} +1 -1
  82. package/dist/deck-client/assets/{chunk-QZHKN3VN-CqLDirEI.js → chunk-QZHKN3VN-jkf68sDs.js} +1 -1
  83. package/dist/deck-client/assets/{chunk-YZCP3GAM-_FQvmMs4.js → chunk-YZCP3GAM-Cd4yBE7o.js} +1 -1
  84. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-Bt8xBAof.js +1 -0
  85. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-Bt8xBAof.js +1 -0
  86. package/dist/deck-client/assets/clone-BHQryoDl.js +1 -0
  87. package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-rfrocesE.js → cose-bilkent-S5V4N54A-DeGFUgAV.js} +1 -1
  88. package/dist/deck-client/assets/{dagre-KV5264BT-Bv_7DJat.js → dagre-KV5264BT-ekcYJuUV.js} +1 -1
  89. package/dist/deck-client/assets/{diagram-5BDNPKRD-4F1414G5.js → diagram-5BDNPKRD-YHPk4rV2.js} +1 -1
  90. package/dist/deck-client/assets/{diagram-G4DWMVQ6-C4-Pszqm.js → diagram-G4DWMVQ6-DM-JCd_B.js} +1 -1
  91. package/dist/deck-client/assets/{diagram-MMDJMWI5-B647TIx9.js → diagram-MMDJMWI5-l5FK1ybk.js} +1 -1
  92. package/dist/deck-client/assets/{diagram-TYMM5635-BFAqpezd.js → diagram-TYMM5635-CIN4_1-j.js} +1 -1
  93. package/dist/deck-client/assets/{erDiagram-SMLLAGMA-BfBfrJOC.js → erDiagram-SMLLAGMA-MyinSkEl.js} +1 -1
  94. package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-DX9YAYes.js → flowDiagram-DWJPFMVM-Dk8nn42x.js} +1 -1
  95. package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-DCuiy7wF.js → ganttDiagram-T4ZO3ILL-BU1ihicu.js} +1 -1
  96. package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-CGp1IXUh.js → gitGraphDiagram-UUTBAWPF-BjsTL13C.js} +1 -1
  97. package/dist/deck-client/assets/{graph-B7g8aoxv.js → graph-DJmh-xi7.js} +1 -1
  98. package/dist/deck-client/assets/{index-Dg1r-WSN.js → index-KsShfCV-.js} +3 -3
  99. package/dist/deck-client/assets/{infoDiagram-42DDH7IO-L3fahMkF.js → infoDiagram-42DDH7IO-Dxvy_RB4.js} +1 -1
  100. package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-aS_EjWBZ.js → ishikawaDiagram-UXIWVN3A-DPOaNF1l.js} +1 -1
  101. package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-djTSQZF9.js → journeyDiagram-VCZTEJTY-DMew3K5c.js} +1 -1
  102. package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-CcTHo4CM.js → kanban-definition-6JOO6SKY-csciJFuk.js} +1 -1
  103. package/dist/deck-client/assets/{layout-mEJiadb7.js → layout-Dg4yyms2.js} +1 -1
  104. package/dist/deck-client/assets/{linear-XgTKqyRu.js → linear-BA3zU6gq.js} +1 -1
  105. package/dist/deck-client/assets/{min-Ct9jZdpd.js → min-lz-Ird-p.js} +1 -1
  106. package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-BaFxCGNU.js → mindmap-definition-QFDTVHPH-CCEN8OQV.js} +1 -1
  107. package/dist/deck-client/assets/{pieDiagram-DEJITSTG-CIbYYjtw.js → pieDiagram-DEJITSTG-DM6n1HY7.js} +1 -1
  108. package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-D9EtCOvh.js → quadrantDiagram-34T5L4WZ-_ULoR66n.js} +1 -1
  109. package/dist/deck-client/assets/{requirementDiagram-MS252O5E-xeni9eVG.js → requirementDiagram-MS252O5E-BuwJs7Tn.js} +1 -1
  110. package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-LYeknz9h.js → sankeyDiagram-XADWPNL6-BEsuzkW4.js} +1 -1
  111. package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-RDbsKFZf.js → sequenceDiagram-FGHM5R23-CP2H0YWf.js} +1 -1
  112. package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-BH1Zjglk.js → stateDiagram-FHFEXIEX-B5Gw_NNL.js} +1 -1
  113. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-4T4wMDXr.js +1 -0
  114. package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-IFXxKptt.js → timeline-definition-GMOUNBTQ-DsoYydQa.js} +1 -1
  115. package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-D-sLkQs9.js → vennDiagram-DHZGUBPP-Dz8JT_ob.js} +1 -1
  116. package/dist/deck-client/assets/wardley-RL74JXVD-DGHQ_Ijv.js +162 -0
  117. package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-BTjjuDU3.js → wardleyDiagram-NUSXRM2D-DN1LJMB1.js} +1 -1
  118. package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-AYbv92n-.js → xychartDiagram-5P7HB3ND-nb0oSfrQ.js} +1 -1
  119. package/dist/deck-client/index.html +1 -1
  120. package/dist/server/beacon-monitor-entry.js +548 -6
  121. package/dist/server/chart-serve.js +917 -248
  122. package/dist/server/cli.js +1368 -374
  123. package/dist/server/council-entry.js +0 -0
  124. package/dist/server/fb-wizard.js +0 -0
  125. package/dist/server/graph-mcp-entry.js +1326 -322
  126. package/dist/server/init-entry.js +16 -11
  127. package/dist/server/orbit-entry.js +135 -7
  128. package/dist/server/parse-worker-entry.js +918 -247
  129. package/package.json +22 -22
  130. package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-array.md +107 -0
  131. package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-clear.md +94 -0
  132. package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-pulse.md +82 -0
  133. package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-scan.md +66 -0
  134. package/scaffolds/ls-marketplace/plugins/kit/skills/blast-radius.md +101 -0
  135. package/scaffolds/ls-marketplace/plugins/kit/skills/brief.md +112 -0
  136. package/scaffolds/ls-marketplace/plugins/kit/skills/course.md +84 -0
  137. package/scaffolds/ls-marketplace/plugins/kit/skills/debug.md +92 -0
  138. package/scaffolds/ls-marketplace/plugins/kit/skills/deploy-check.md +160 -0
  139. package/scaffolds/ls-marketplace/plugins/kit/skills/diagram.md +134 -0
  140. package/scaffolds/ls-marketplace/plugins/kit/skills/orbit.md +87 -0
  141. package/scaffolds/ls-marketplace/plugins/kit/skills/prototype.md +90 -0
  142. package/scaffolds/ls-marketplace/plugins/kit/skills/recall.md +83 -0
  143. package/scaffolds/ls-marketplace/plugins/kit/{commands → skills}/show-mcp-status.md +4 -4
  144. package/scaffolds/ls-marketplace/plugins/kit/skills/wireframe.md +70 -0
  145. package/scaffolds/migrate-safety/scripts/migrate-with-backup.sh +0 -0
  146. package/scaffolds/recall-hook/scripts/ensure-recall.sh +0 -0
  147. package/scaffolds/statusline/statusline-mcp.sh +21 -9
  148. package/dist/beacon/types/capture/element.d.ts +0 -3
  149. package/dist/beacon/types/capture/element.d.ts.map +0 -1
  150. package/dist/beacon/types/capture/events.d.ts +0 -20
  151. package/dist/beacon/types/capture/events.d.ts.map +0 -1
  152. package/dist/beacon/types/capture/framework.d.ts +0 -3
  153. package/dist/beacon/types/capture/framework.d.ts.map +0 -1
  154. package/dist/beacon/types/capture/metadata.d.ts +0 -3
  155. package/dist/beacon/types/capture/metadata.d.ts.map +0 -1
  156. package/dist/beacon/types/capture/overlay.d.ts +0 -7
  157. package/dist/beacon/types/capture/overlay.d.ts.map +0 -1
  158. package/dist/beacon/types/capture/picker.d.ts.map +0 -1
  159. package/dist/beacon/types/capture/screenshot.d.ts.map +0 -1
  160. package/dist/beacon/types/capture/selector.d.ts.map +0 -1
  161. package/dist/beacon/types/monitor/dom.d.ts +0 -13
  162. package/dist/beacon/types/monitor/dom.d.ts.map +0 -1
  163. package/dist/beacon/types/monitor/index.d.ts +0 -19
  164. package/dist/beacon/types/monitor/index.d.ts.map +0 -1
  165. package/dist/beacon/types/monitor/network.d.ts +0 -12
  166. package/dist/beacon/types/monitor/network.d.ts.map +0 -1
  167. package/dist/beacon/types/monitor/transport.d.ts.map +0 -1
  168. package/dist/beacon/types/monitor/types.d.ts.map +0 -1
  169. package/dist/beacon/types/transport/submit.d.ts +0 -3
  170. package/dist/beacon/types/transport/submit.d.ts.map +0 -1
  171. package/dist/beacon/types/ui/button.d.ts +0 -2
  172. package/dist/beacon/types/ui/button.d.ts.map +0 -1
  173. package/dist/beacon/types/ui/drawer.d.ts +0 -33
  174. package/dist/beacon/types/ui/drawer.d.ts.map +0 -1
  175. package/dist/beacon/types/ui/icons.d.ts +0 -9
  176. package/dist/beacon/types/ui/icons.d.ts.map +0 -1
  177. package/dist/beacon/types/ui/monitor-panel.d.ts +0 -19
  178. package/dist/beacon/types/ui/monitor-panel.d.ts.map +0 -1
  179. package/dist/beacon/types/ui/pick-mode-overlay.d.ts.map +0 -1
  180. package/dist/beacon/types/ui/pin-popover.d.ts.map +0 -1
  181. package/dist/deck-client/assets/channel-CRdozqbp.js +0 -1
  182. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-lIZMp57W.js +0 -1
  183. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-lIZMp57W.js +0 -1
  184. package/dist/deck-client/assets/clone-BtWeSTyJ.js +0 -1
  185. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-BrV78NDR.js +0 -1
  186. package/dist/deck-client/assets/wardley-RL74JXVD-C010F8l4.js +0 -162
  187. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-array.md +0 -92
  188. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-clear.md +0 -68
  189. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-pulse.md +0 -80
  190. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-scan.md +0 -62
  191. /package/dist/beacon/types/{capture → internal}/selector.d.ts +0 -0
@@ -1184,6 +1184,8 @@ function extractDeep(absPath) {
1184
1184
  false
1185
1185
  );
1186
1186
  const hasEffects = Object.keys(fileEffects).length > 0;
1187
+ const uiLabels = collectUiLabels(root);
1188
+ const notes = collectNotes(root);
1187
1189
  return {
1188
1190
  elements,
1189
1191
  stateVars,
@@ -1191,10 +1193,77 @@ function extractDeep(absPath) {
1191
1193
  variables,
1192
1194
  responses,
1193
1195
  params,
1194
- ...hasEffects ? { effects: fileEffects } : {}
1196
+ ...hasEffects ? { effects: fileEffects } : {},
1197
+ ...uiLabels.length > 0 ? { ui_labels: uiLabels } : {},
1198
+ ...notes.length > 0 ? { notes } : {}
1195
1199
  };
1196
1200
  }
1197
- var import_node_fs5, import_node_path5, 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;
1201
+ function collectNotes(root) {
1202
+ const out = [];
1203
+ const seen = /* @__PURE__ */ new Set();
1204
+ function visit(node) {
1205
+ if (out.length >= NOTES_MAX) return;
1206
+ if (node.type === "comment") {
1207
+ const text = node.text;
1208
+ const startRow = node.startPosition.row;
1209
+ NOTE_REGEX.lastIndex = 0;
1210
+ let m;
1211
+ while ((m = NOTE_REGEX.exec(text)) !== null) {
1212
+ const kind = m[1];
1213
+ const author = m[2];
1214
+ const body = m[3];
1215
+ if (!kind || !body) continue;
1216
+ const newlinesBefore = (text.slice(0, m.index).match(/\n/g) ?? []).length;
1217
+ const line = startRow + 1 + newlinesBefore;
1218
+ const key = `${line}:${kind}`;
1219
+ if (seen.has(key)) continue;
1220
+ seen.add(key);
1221
+ const note = {
1222
+ kind,
1223
+ text: body.length <= 200 ? body : body.slice(0, 200) + "...",
1224
+ line
1225
+ };
1226
+ if (author) note.author = author;
1227
+ out.push(note);
1228
+ if (out.length >= NOTES_MAX) return;
1229
+ }
1230
+ }
1231
+ for (const child of node.namedChildren) {
1232
+ visit(child);
1233
+ if (out.length >= NOTES_MAX) return;
1234
+ }
1235
+ }
1236
+ visit(root);
1237
+ return out;
1238
+ }
1239
+ function collectUiLabels(root) {
1240
+ const out = [];
1241
+ const seen = /* @__PURE__ */ new Set();
1242
+ function visit(node) {
1243
+ if (out.length >= UI_LABELS_MAX) return;
1244
+ if (node.type === "pair") {
1245
+ const key = node.childForFieldName("key");
1246
+ const val = node.childForFieldName("value");
1247
+ if (key && val) {
1248
+ const keyText = key.type === "property_identifier" ? key.text : stringLiteralValue(key) ?? key.text;
1249
+ if (UI_LABEL_KEYS.has(keyText)) {
1250
+ const strVal = stringLiteralValue(val);
1251
+ if (strVal && strVal.length > 0 && strVal.length <= 200 && !seen.has(strVal)) {
1252
+ seen.add(strVal);
1253
+ out.push(strVal);
1254
+ }
1255
+ }
1256
+ }
1257
+ }
1258
+ for (const child of node.namedChildren) {
1259
+ visit(child);
1260
+ if (out.length >= UI_LABELS_MAX) return;
1261
+ }
1262
+ }
1263
+ visit(root);
1264
+ return out;
1265
+ }
1266
+ var import_node_fs5, import_node_path5, 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;
1198
1267
  var init_ts_extractor = __esm({
1199
1268
  "src/server/graph/core/ts-extractor.ts"() {
1200
1269
  "use strict";
@@ -1313,6 +1382,27 @@ var init_ts_extractor = __esm({
1313
1382
  "selected",
1314
1383
  "disabled"
1315
1384
  ]);
1385
+ UI_LABEL_KEYS = /* @__PURE__ */ new Set([
1386
+ "label",
1387
+ "title",
1388
+ "name",
1389
+ "text",
1390
+ "description",
1391
+ "placeholder",
1392
+ "tooltip",
1393
+ "heading",
1394
+ "subheading",
1395
+ "sheetTitle",
1396
+ "sheetDescription",
1397
+ "caption",
1398
+ "cta",
1399
+ "buttonText",
1400
+ "emptyText",
1401
+ "subtitle"
1402
+ ]);
1403
+ UI_LABELS_MAX = 200;
1404
+ NOTE_REGEX = /^\s*(?:\/\/|\/\*+|\*)\s*([A-Z][A-Z0-9_]{1,15})(?:\(([^)]+)\))?:\s*(\S.*?)\s*(?:\*\/)?$/gm;
1405
+ NOTES_MAX = 100;
1316
1406
  }
1317
1407
  });
1318
1408
 
@@ -1320,6 +1410,7 @@ var init_ts_extractor = __esm({
1320
1410
  var parse_worker_entry_exports = {};
1321
1411
  module.exports = __toCommonJS(parse_worker_entry_exports);
1322
1412
  var import_node_worker_threads = require("node:worker_threads");
1413
+ var import_pgsql_parser2 = require("pgsql-parser");
1323
1414
 
1324
1415
  // src/server/graph/core/config.ts
1325
1416
  var import_node_fs = require("node:fs");
@@ -1988,6 +2079,7 @@ function generate(rootDir) {
1988
2079
  responses: deep.responses,
1989
2080
  params: deep.params,
1990
2081
  ...deep.effects ? { effects: deep.effects } : {},
2082
+ ...deep.notes ? { notes: deep.notes } : {},
1991
2083
  _dbCalls: dbCalls
1992
2084
  // temp: used for cross-ref building below
1993
2085
  });
@@ -2008,6 +2100,8 @@ function generate(rootDir) {
2008
2100
  conditions: deep.conditions,
2009
2101
  variables: deep.variables,
2010
2102
  ...deep.effects ? { effects: deep.effects } : {},
2103
+ ...deep.ui_labels ? { ui_labels: deep.ui_labels } : {},
2104
+ ...deep.notes ? { notes: deep.notes } : {},
2011
2105
  ...authWrappers.length > 0 ? { auth: authWrappers } : {},
2012
2106
  ...dbCalls.length > 0 ? { _dbCalls: dbCalls } : {}
2013
2107
  });
@@ -2608,6 +2702,7 @@ var prismaSchemaParser = {
2608
2702
  // src/server/graph/parsers/db/sql-migrations.ts
2609
2703
  var import_node_fs8 = require("node:fs");
2610
2704
  var import_node_path7 = require("node:path");
2705
+ var import_pgsql_parser = require("pgsql-parser");
2611
2706
  var PG_TO_PRISMA = {
2612
2707
  "TEXT": "String",
2613
2708
  "VARCHAR": "String",
@@ -2638,243 +2733,6 @@ function pgTypeToPrisma(pgType) {
2638
2733
  const upper = pgType.toUpperCase().trim();
2639
2734
  return PG_TO_PRISMA[upper] ?? upper;
2640
2735
  }
2641
- var ID = `(?:"[\\w$]+"|[\\w$]+)`;
2642
- var QID = `(?:${ID}\\.)?${ID}`;
2643
- function bareName(captured) {
2644
- const parts = captured.split(".");
2645
- const last = parts[parts.length - 1];
2646
- return last.replace(/^"(.*)"$/, "$1").trim();
2647
- }
2648
- function parseCreateTable(sql, state) {
2649
- const re = new RegExp(
2650
- `CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${QID})\\s*\\(([\\s\\S]*?)\\);`,
2651
- "gi"
2652
- );
2653
- let m;
2654
- while ((m = re.exec(sql)) !== null) {
2655
- const tableName = bareName(m[1]);
2656
- const body = m[2];
2657
- const columns = /* @__PURE__ */ new Map();
2658
- let primaryCol = null;
2659
- const inlineFks = [];
2660
- const lines = splitTopLevelCommas(body);
2661
- for (const raw of lines) {
2662
- const trimmed = raw.trim().replace(/,\s*$/, "");
2663
- if (!trimmed || trimmed.startsWith("--")) continue;
2664
- const namedPk = trimmed.match(new RegExp(`^CONSTRAINT\\s+${ID}\\s+PRIMARY\\s+KEY\\s*\\(\\s*(${QID})`, "i"));
2665
- if (namedPk) {
2666
- primaryCol = bareName(namedPk[1]);
2667
- continue;
2668
- }
2669
- const tablePk = trimmed.match(new RegExp(`^PRIMARY\\s+KEY\\s*\\(\\s*(${QID})`, "i"));
2670
- if (tablePk) {
2671
- primaryCol = bareName(tablePk[1]);
2672
- continue;
2673
- }
2674
- if (/^UNIQUE\s*\(/i.test(trimmed)) continue;
2675
- const namedFk = trimmed.match(new RegExp(
2676
- `^CONSTRAINT\\s+(${ID})\\s+FOREIGN\\s+KEY\\s*\\(\\s*(${QID})\\s*\\)\\s+REFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
2677
- "i"
2678
- ));
2679
- if (namedFk) {
2680
- inlineFks.push({
2681
- constraintName: bareName(namedFk[1]),
2682
- sourceTable: tableName,
2683
- sourceColumn: bareName(namedFk[2]),
2684
- targetTable: bareName(namedFk[3]),
2685
- targetColumn: bareName(namedFk[4]),
2686
- onDelete: namedFk[5] ?? null
2687
- });
2688
- continue;
2689
- }
2690
- const bareFk = trimmed.match(new RegExp(
2691
- `^FOREIGN\\s+KEY\\s*\\(\\s*(${QID})\\s*\\)\\s+REFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
2692
- "i"
2693
- ));
2694
- if (bareFk) {
2695
- inlineFks.push({
2696
- constraintName: `${tableName}_${bareName(bareFk[1])}_fkey`,
2697
- sourceTable: tableName,
2698
- sourceColumn: bareName(bareFk[1]),
2699
- targetTable: bareName(bareFk[2]),
2700
- targetColumn: bareName(bareFk[3]),
2701
- onDelete: bareFk[4] ?? null
2702
- });
2703
- continue;
2704
- }
2705
- if (/^CONSTRAINT\s/i.test(trimmed)) continue;
2706
- const colMatch = trimmed.match(new RegExp(`^(${ID})\\s+(.+)`, "i"));
2707
- if (!colMatch) continue;
2708
- const colName = bareName(colMatch[1]);
2709
- let rest = colMatch[2];
2710
- const inlineRefMatch = rest.match(new RegExp(
2711
- `\\bREFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
2712
- "i"
2713
- ));
2714
- if (inlineRefMatch) {
2715
- inlineFks.push({
2716
- constraintName: `${tableName}_${colName}_fkey`,
2717
- sourceTable: tableName,
2718
- sourceColumn: colName,
2719
- targetTable: bareName(inlineRefMatch[1]),
2720
- targetColumn: bareName(inlineRefMatch[2]),
2721
- onDelete: inlineRefMatch[3] ?? null
2722
- });
2723
- rest = rest.replace(inlineRefMatch[0], "").trim();
2724
- }
2725
- const isNotNull = /\bNOT\s+NULL\b/i.test(rest);
2726
- const isPrimaryKey = /\bPRIMARY\s+KEY\b/i.test(rest);
2727
- const isUnique = /\bUNIQUE\b/i.test(rest);
2728
- const defaultMatch = rest.match(/\bDEFAULT\s+(.+?)(?:\s*,?\s*$)/i);
2729
- const defaultVal = defaultMatch ? defaultMatch[1].trim() : null;
2730
- let colType = rest.replace(/\bNOT\s+NULL\b/gi, "").replace(/\bPRIMARY\s+KEY\b/gi, "").replace(/\bUNIQUE\b/gi, "").replace(/\bDEFAULT\s+.*/gi, "").trim().replace(/,\s*$/, "").trim();
2731
- columns.set(colName, {
2732
- name: colName,
2733
- type: colType,
2734
- nullable: !isNotNull && !isPrimaryKey,
2735
- primary: isPrimaryKey,
2736
- unique: isUnique,
2737
- default: defaultVal
2738
- });
2739
- if (isPrimaryKey) primaryCol = colName;
2740
- }
2741
- if (primaryCol && columns.has(primaryCol)) {
2742
- columns.get(primaryCol).primary = true;
2743
- }
2744
- state.tables.set(tableName, { name: tableName, columns });
2745
- state.fks.push(...inlineFks);
2746
- }
2747
- }
2748
- function splitTopLevelCommas(body) {
2749
- const out = [];
2750
- let depth = 0;
2751
- let buf = "";
2752
- let inString = null;
2753
- for (const ch of body) {
2754
- if (inString) {
2755
- buf += ch;
2756
- if (ch === inString) inString = null;
2757
- continue;
2758
- }
2759
- if (ch === "'" || ch === '"') {
2760
- inString = ch;
2761
- buf += ch;
2762
- continue;
2763
- }
2764
- if (ch === "(") depth++;
2765
- else if (ch === ")") depth--;
2766
- if (ch === "," && depth === 0) {
2767
- out.push(buf);
2768
- buf = "";
2769
- continue;
2770
- }
2771
- buf += ch;
2772
- }
2773
- if (buf.trim()) out.push(buf);
2774
- return out;
2775
- }
2776
- function parseCreateEnum(sql, state) {
2777
- const re = new RegExp(
2778
- `CREATE\\s+TYPE\\s+(${QID})\\s+AS\\s+ENUM\\s*\\(([^)]+)\\)`,
2779
- "gi"
2780
- );
2781
- let m;
2782
- while ((m = re.exec(sql)) !== null) {
2783
- const enumName = bareName(m[1]);
2784
- const valuesStr = m[2];
2785
- const values = new Set(
2786
- valuesStr.split(",").map((v) => v.trim().replace(/^'(.*)'$/, "$1")).filter(Boolean)
2787
- );
2788
- state.enums.set(enumName, { name: enumName, values });
2789
- }
2790
- }
2791
- function parseAlterTable(sql, state) {
2792
- const addColRe = new RegExp(
2793
- `ALTER\\s+TABLE\\s+(${QID})\\s+ADD\\s+COLUMN\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${QID})\\s+(.+?);`,
2794
- "gi"
2795
- );
2796
- let m;
2797
- while ((m = addColRe.exec(sql)) !== null) {
2798
- const tableName = bareName(m[1]);
2799
- const colName = bareName(m[2]);
2800
- let rest = m[3];
2801
- const table = state.tables.get(tableName);
2802
- if (!table) continue;
2803
- const isNotNull = /\bNOT\s+NULL\b/i.test(rest);
2804
- const defaultMatch = rest.match(/\bDEFAULT\s+(.+?)$/i);
2805
- const defaultVal = defaultMatch ? defaultMatch[1].trim() : null;
2806
- let colType = rest.replace(/\bNOT\s+NULL\b/gi, "").replace(/\bDEFAULT\s+.*/gi, "").trim();
2807
- table.columns.set(colName, {
2808
- name: colName,
2809
- type: colType,
2810
- nullable: !isNotNull,
2811
- primary: false,
2812
- unique: false,
2813
- default: defaultVal
2814
- });
2815
- }
2816
- const dropColRe = new RegExp(
2817
- `ALTER\\s+TABLE\\s+(${QID})\\s+DROP\\s+COLUMN\\s+(?:IF\\s+EXISTS\\s+)?(${QID})`,
2818
- "gi"
2819
- );
2820
- while ((m = dropColRe.exec(sql)) !== null) {
2821
- const table = state.tables.get(bareName(m[1]));
2822
- if (table) table.columns.delete(bareName(m[2]));
2823
- }
2824
- const fkRe = new RegExp(
2825
- `ALTER\\s+TABLE\\s+(${QID})\\s+ADD\\s+CONSTRAINT\\s+(${ID})\\s+FOREIGN\\s+KEY\\s*\\(\\s*(${QID})\\s*\\)\\s+REFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
2826
- "gi"
2827
- );
2828
- while ((m = fkRe.exec(sql)) !== null) {
2829
- state.fks.push({
2830
- constraintName: bareName(m[2]),
2831
- sourceTable: bareName(m[1]),
2832
- sourceColumn: bareName(m[3]),
2833
- targetTable: bareName(m[4]),
2834
- targetColumn: bareName(m[5]),
2835
- onDelete: m[6] ?? null
2836
- });
2837
- }
2838
- }
2839
- function parseAlterEnum(sql, state) {
2840
- const re = new RegExp(
2841
- `ALTER\\s+TYPE\\s+(${QID})\\s+ADD\\s+VALUE\\s+'([^']+)'`,
2842
- "gi"
2843
- );
2844
- let m;
2845
- while ((m = re.exec(sql)) !== null) {
2846
- const en = state.enums.get(bareName(m[1]));
2847
- if (en) en.values.add(m[2]);
2848
- }
2849
- }
2850
- function parseDropTable(sql, state) {
2851
- const re = new RegExp(
2852
- `DROP\\s+TABLE\\s+(?:IF\\s+EXISTS\\s+)?(${QID})`,
2853
- "gi"
2854
- );
2855
- let m;
2856
- while ((m = re.exec(sql)) !== null) {
2857
- const dropped = bareName(m[1]);
2858
- state.tables.delete(dropped);
2859
- state.fks = state.fks.filter((fk) => fk.sourceTable !== dropped && fk.targetTable !== dropped);
2860
- }
2861
- }
2862
- function parseUniqueIndex(sql, state) {
2863
- const re = new RegExp(
2864
- `CREATE\\s+UNIQUE\\s+INDEX\\s+(?:(?:IF\\s+NOT\\s+EXISTS\\s+)?(?:${ID}\\s+)?)?ON\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)`,
2865
- "gi"
2866
- );
2867
- let m;
2868
- while ((m = re.exec(sql)) !== null) {
2869
- const tableName = bareName(m[1]);
2870
- const colName = bareName(m[2]);
2871
- const table = state.tables.get(tableName);
2872
- const col = table?.columns.get(colName);
2873
- if (col) col.unique = true;
2874
- if (!state.uniqueIndexes.has(tableName)) state.uniqueIndexes.set(tableName, /* @__PURE__ */ new Set());
2875
- state.uniqueIndexes.get(tableName).add(colName);
2876
- }
2877
- }
2878
2736
  function discoverMigrationFiles(migrationsDir) {
2879
2737
  if (!(0, import_node_fs8.existsSync)(migrationsDir)) return [];
2880
2738
  const out = [];
@@ -2889,25 +2747,614 @@ function discoverMigrationFiles(migrationsDir) {
2889
2747
  }
2890
2748
  return out;
2891
2749
  }
2892
- function parseMigrations(migrationsDir) {
2750
+ var postgresDialect = {
2751
+ parse(sql) {
2752
+ return (0, import_pgsql_parser.parseSync)(sql);
2753
+ },
2754
+ applyAll(ast, state, filepath) {
2755
+ const stmts = ast.stmts ?? [];
2756
+ extractTablesFromStmts(stmts, state);
2757
+ extractEnumsFromStmts(stmts, state);
2758
+ extractIndexesFromStmts(stmts, state, filepath);
2759
+ extractPoliciesFromStmts(stmts, state, filepath);
2760
+ extractExtensionsFromStmts(stmts, state, filepath);
2761
+ extractTriggersFromStmts(stmts, state, filepath);
2762
+ extractFunctionsFromStmts(stmts, state, filepath);
2763
+ extractViewsFromStmts(stmts, state, filepath);
2764
+ applyDropIndexes(stmts, state);
2765
+ applyDropPolicies(stmts, state);
2766
+ applyDropsForSchemaObjects(stmts, state);
2767
+ applyAstAlterEnums(stmts, state);
2768
+ applyAstAlterations(stmts, state);
2769
+ },
2770
+ extractMigrationInfo(ast, name, filepath) {
2771
+ const stmts = ast.stmts ?? [];
2772
+ return extractMigrationInfoFromStmts(stmts, name, filepath);
2773
+ }
2774
+ };
2775
+ function parseMigrations(migrationsDir, dialect = postgresDialect) {
2893
2776
  const state = {
2894
2777
  tables: /* @__PURE__ */ new Map(),
2895
2778
  enums: /* @__PURE__ */ new Map(),
2896
2779
  fks: [],
2897
- uniqueIndexes: /* @__PURE__ */ new Map()
2780
+ uniqueIndexes: /* @__PURE__ */ new Map(),
2781
+ indexes: [],
2782
+ policies: [],
2783
+ extensions: [],
2784
+ triggers: [],
2785
+ functions: [],
2786
+ views: []
2898
2787
  };
2899
2788
  if (!migrationsDir) return state;
2900
2789
  for (const sqlPath of discoverMigrationFiles(migrationsDir)) {
2901
2790
  const sql = (0, import_node_fs8.readFileSync)(sqlPath, "utf-8");
2902
- parseCreateEnum(sql, state);
2903
- parseCreateTable(sql, state);
2904
- parseAlterTable(sql, state);
2905
- parseAlterEnum(sql, state);
2906
- parseDropTable(sql, state);
2907
- parseUniqueIndex(sql, state);
2791
+ let ast;
2792
+ try {
2793
+ ast = dialect.parse(sql);
2794
+ } catch {
2795
+ continue;
2796
+ }
2797
+ dialect.applyAll(ast, state, sqlPath);
2908
2798
  }
2909
2799
  return state;
2910
2800
  }
2801
+ function extractIndexesFromStmts(stmts, state, filepath) {
2802
+ for (const wrap of stmts) {
2803
+ const stmt = wrap.stmt ?? {};
2804
+ const ix = stmt.IndexStmt;
2805
+ if (!ix) continue;
2806
+ const name = ix.idxname ?? "";
2807
+ if (!name) continue;
2808
+ const table = ix.relation?.relname ?? "";
2809
+ const unique = !!ix.unique;
2810
+ const method = String(ix.accessMethod ?? "btree").toLowerCase();
2811
+ const params = ix.indexParams ?? [];
2812
+ const columns = [];
2813
+ let hasExpressions = false;
2814
+ for (const p of params) {
2815
+ const elem = p.IndexElem;
2816
+ if (!elem) continue;
2817
+ if (elem.name) columns.push(elem.name);
2818
+ else if (elem.expr) hasExpressions = true;
2819
+ }
2820
+ const hasPredicate = !!ix.whereClause;
2821
+ const existing = state.indexes.findIndex((i) => i.name === name);
2822
+ const next = { name, table, unique, method, columns, hasExpressions, hasPredicate, filepath };
2823
+ if (existing >= 0) state.indexes[existing] = next;
2824
+ else state.indexes.push(next);
2825
+ if (unique && columns.length === 1 && !hasPredicate && !hasExpressions) {
2826
+ const t = state.tables.get(table);
2827
+ const col = t?.columns.get(columns[0]);
2828
+ if (col) col.unique = true;
2829
+ if (!state.uniqueIndexes.has(table)) state.uniqueIndexes.set(table, /* @__PURE__ */ new Set());
2830
+ state.uniqueIndexes.get(table).add(columns[0]);
2831
+ }
2832
+ }
2833
+ }
2834
+ function applyDropIndexes(stmts, state) {
2835
+ for (const wrap of stmts) {
2836
+ const drop = wrap.stmt?.DropStmt;
2837
+ if (!drop || drop.removeType !== "OBJECT_INDEX") continue;
2838
+ const objects = drop.objects ?? [];
2839
+ const droppedNames = /* @__PURE__ */ new Set();
2840
+ for (const obj of objects) {
2841
+ const items = obj.List?.items ?? [];
2842
+ const last = items[items.length - 1]?.String?.sval;
2843
+ if (last) droppedNames.add(last);
2844
+ }
2845
+ if (droppedNames.size > 0) {
2846
+ state.indexes = state.indexes.filter((i) => !droppedNames.has(i.name));
2847
+ }
2848
+ }
2849
+ }
2850
+ function formatPgTypeName(typeName) {
2851
+ const names = (typeName?.names ?? []).map((n) => n.String?.sval ?? "").filter(Boolean);
2852
+ const base = (names[names.length - 1] ?? "").toLowerCase();
2853
+ const PG_INTERNAL_MAP = {
2854
+ int4: "INTEGER",
2855
+ int8: "BIGINT",
2856
+ int2: "SMALLINT",
2857
+ float8: "DOUBLE PRECISION",
2858
+ float4: "REAL",
2859
+ bool: "BOOLEAN",
2860
+ bpchar: "CHAR",
2861
+ timestamptz: "TIMESTAMPTZ",
2862
+ timestamp: "TIMESTAMP",
2863
+ numeric: "NUMERIC",
2864
+ text: "TEXT",
2865
+ varchar: "VARCHAR",
2866
+ jsonb: "JSONB",
2867
+ json: "JSON",
2868
+ uuid: "UUID",
2869
+ date: "DATE",
2870
+ bytea: "BYTEA"
2871
+ };
2872
+ return PG_INTERNAL_MAP[base] ?? base.toUpperCase();
2873
+ }
2874
+ function applyAstAlterations(stmts, state) {
2875
+ for (const wrap of stmts) {
2876
+ const stmt = wrap.stmt ?? {};
2877
+ const kind = Object.keys(stmt)[0];
2878
+ if (!kind) continue;
2879
+ if (kind === "AlterTableStmt") {
2880
+ const body = stmt.AlterTableStmt;
2881
+ const tableName = body.relation?.relname ?? "";
2882
+ const table = state.tables.get(tableName);
2883
+ if (!table) continue;
2884
+ const cmds = body.cmds ?? [];
2885
+ for (const c of cmds) {
2886
+ const cmd = c.AlterTableCmd;
2887
+ if (!cmd) continue;
2888
+ const subtype = cmd.subtype ?? "";
2889
+ const colName = cmd.name ?? "";
2890
+ const col = colName ? table.columns.get(colName) : void 0;
2891
+ switch (subtype) {
2892
+ case "AT_AlterColumnType": {
2893
+ if (!col) break;
2894
+ const typeName = cmd.def?.ColumnDef?.typeName ?? cmd.def?.typeName;
2895
+ if (typeName) col.type = formatPgTypeNameWithMods(typeName);
2896
+ break;
2897
+ }
2898
+ case "AT_SetNotNull":
2899
+ if (col) col.nullable = false;
2900
+ break;
2901
+ case "AT_DropNotNull":
2902
+ if (col) col.nullable = true;
2903
+ break;
2904
+ case "AT_AddColumn": {
2905
+ const cd = cmd.def?.ColumnDef;
2906
+ if (!cd) break;
2907
+ const newColName = cd.colname ?? "";
2908
+ if (!newColName) break;
2909
+ if (table.columns.has(newColName)) break;
2910
+ let nullable = true;
2911
+ let primary = false;
2912
+ let unique = false;
2913
+ let defaultVal = null;
2914
+ for (const c2 of cd.constraints ?? []) {
2915
+ const ct = c2.Constraint;
2916
+ if (!ct) continue;
2917
+ if (ct.contype === "CONSTR_NOTNULL") nullable = false;
2918
+ else if (ct.contype === "CONSTR_PRIMARY") {
2919
+ primary = true;
2920
+ nullable = false;
2921
+ } else if (ct.contype === "CONSTR_UNIQUE") unique = true;
2922
+ else if (ct.contype === "CONSTR_DEFAULT") defaultVal = "<expr>";
2923
+ }
2924
+ table.columns.set(newColName, {
2925
+ name: newColName,
2926
+ type: formatPgTypeNameWithMods(cd.typeName),
2927
+ nullable,
2928
+ primary,
2929
+ unique,
2930
+ default: defaultVal
2931
+ });
2932
+ break;
2933
+ }
2934
+ case "AT_DropColumn":
2935
+ if (colName) table.columns.delete(colName);
2936
+ break;
2937
+ case "AT_AddConstraint": {
2938
+ const ct = cmd.def?.Constraint;
2939
+ if (!ct) break;
2940
+ if (ct.contype !== "CONSTR_FOREIGN") break;
2941
+ const fkCols = (ct.fk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
2942
+ const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
2943
+ const pkTable = ct.pktable?.relname ?? "";
2944
+ if (fkCols.length && pkCols.length && pkTable) {
2945
+ state.fks.push({
2946
+ constraintName: ct.conname || `${tableName}_${fkCols[0]}_fkey`,
2947
+ sourceTable: tableName,
2948
+ sourceColumn: fkCols[0],
2949
+ targetTable: pkTable,
2950
+ targetColumn: pkCols[0],
2951
+ onDelete: mapFkAction(ct.fk_del_action)
2952
+ });
2953
+ }
2954
+ break;
2955
+ }
2956
+ }
2957
+ }
2958
+ } else if (kind === "RenameStmt") {
2959
+ const body = stmt.RenameStmt;
2960
+ const renameType = body.renameType ?? "";
2961
+ const newName = body.newname ?? "";
2962
+ if (renameType === "OBJECT_COLUMN") {
2963
+ const tableName = body.relation?.relname ?? "";
2964
+ const oldName = body.subname ?? "";
2965
+ const table = state.tables.get(tableName);
2966
+ if (!table || !oldName || !newName) continue;
2967
+ const col = table.columns.get(oldName);
2968
+ if (col) {
2969
+ col.name = newName;
2970
+ table.columns.delete(oldName);
2971
+ table.columns.set(newName, col);
2972
+ }
2973
+ } else if (renameType === "OBJECT_TABLE") {
2974
+ const oldName = body.relation?.relname ?? "";
2975
+ if (!oldName || !newName) continue;
2976
+ const t = state.tables.get(oldName);
2977
+ if (!t) continue;
2978
+ state.tables.delete(oldName);
2979
+ t.name = newName;
2980
+ state.tables.set(newName, t);
2981
+ for (const fk of state.fks) {
2982
+ if (fk.sourceTable === oldName) fk.sourceTable = newName;
2983
+ if (fk.targetTable === oldName) fk.targetTable = newName;
2984
+ }
2985
+ }
2986
+ }
2987
+ }
2988
+ }
2989
+ function extractPoliciesFromStmts(stmts, state, filepath) {
2990
+ for (const wrap of stmts) {
2991
+ const body = wrap.stmt?.CreatePolicyStmt;
2992
+ if (!body) continue;
2993
+ const name = body.policy_name ?? "";
2994
+ if (!name) continue;
2995
+ const table = body.table?.relname ?? "";
2996
+ const cmdRaw = String(body.cmd_name ?? "all").toUpperCase();
2997
+ const command = ["SELECT", "INSERT", "UPDATE", "DELETE", "ALL"].includes(cmdRaw) ? cmdRaw : "ALL";
2998
+ const permissive = body.permissive === true;
2999
+ const roles = (body.roles ?? []).map((r) => {
3000
+ const rs = r.RoleSpec;
3001
+ if (!rs) return "";
3002
+ if (rs.roletype === "ROLESPEC_PUBLIC") return "public";
3003
+ if (rs.roletype === "ROLESPEC_CURRENT_USER") return "current_user";
3004
+ if (rs.roletype === "ROLESPEC_CSTRING" && rs.rolename) return rs.rolename;
3005
+ return "";
3006
+ }).filter(Boolean);
3007
+ const hasUsing = !!body.qual;
3008
+ const hasWithCheck = !!body.with_check;
3009
+ const existing = state.policies.findIndex((p) => p.table === table && p.name === name);
3010
+ const next = { name, table, command, permissive, roles, hasUsing, hasWithCheck, filepath };
3011
+ if (existing >= 0) state.policies[existing] = next;
3012
+ else state.policies.push(next);
3013
+ }
3014
+ }
3015
+ function applyDropPolicies(stmts, state) {
3016
+ for (const wrap of stmts) {
3017
+ const drop = wrap.stmt?.DropStmt;
3018
+ if (!drop || drop.removeType !== "OBJECT_POLICY") continue;
3019
+ const objects = drop.objects ?? [];
3020
+ for (const obj of objects) {
3021
+ const items = obj.List?.items ?? [];
3022
+ if (items.length < 2) continue;
3023
+ const table = items[0]?.String?.sval ?? "";
3024
+ const policyName = items[items.length - 1]?.String?.sval ?? "";
3025
+ if (!table || !policyName) continue;
3026
+ state.policies = state.policies.filter((p) => !(p.table === table && p.name === policyName));
3027
+ }
3028
+ }
3029
+ }
3030
+ function mapFkAction(action) {
3031
+ if (!action) return null;
3032
+ const m = {
3033
+ r: "RESTRICT",
3034
+ c: "CASCADE",
3035
+ s: "SET NULL",
3036
+ d: "SET DEFAULT",
3037
+ a: "NO ACTION",
3038
+ // pgsql-parser may also emit FKCONSTR_ACTION_* enum strings:
3039
+ FKCONSTR_ACTION_RESTRICT: "RESTRICT",
3040
+ FKCONSTR_ACTION_CASCADE: "CASCADE",
3041
+ FKCONSTR_ACTION_SETNULL: "SET NULL",
3042
+ FKCONSTR_ACTION_SETDEFAULT: "SET DEFAULT",
3043
+ FKCONSTR_ACTION_NOACTION: "NO ACTION"
3044
+ };
3045
+ return m[action] ?? null;
3046
+ }
3047
+ function formatPgTypeNameWithMods(typeName) {
3048
+ const base = formatPgTypeName(typeName);
3049
+ if (base === "String" || base === "unknown") return base;
3050
+ const typmods = [];
3051
+ for (const m of typeName?.typmods ?? []) {
3052
+ const v = m.A_Const?.ival?.ival;
3053
+ if (typeof v === "number") typmods.push(v);
3054
+ }
3055
+ return typmods.length ? `${base}(${typmods.join(",")})` : base;
3056
+ }
3057
+ function extractTablesFromStmts(stmts, state) {
3058
+ for (const wrap of stmts) {
3059
+ const body = wrap.stmt?.CreateStmt;
3060
+ if (!body) continue;
3061
+ const tableName = body.relation?.relname ?? "";
3062
+ if (!tableName) continue;
3063
+ const columns = /* @__PURE__ */ new Map();
3064
+ const fks = [];
3065
+ let primaryCol = null;
3066
+ for (const elt of body.tableElts ?? []) {
3067
+ if (elt.ColumnDef) {
3068
+ const cd = elt.ColumnDef;
3069
+ const colName = cd.colname ?? "";
3070
+ if (!colName) continue;
3071
+ const colType = formatPgTypeNameWithMods(cd.typeName);
3072
+ let nullable = true;
3073
+ let primary = false;
3074
+ let unique = false;
3075
+ let defaultVal = null;
3076
+ for (const c of cd.constraints ?? []) {
3077
+ const ct = c.Constraint;
3078
+ if (!ct) continue;
3079
+ switch (ct.contype) {
3080
+ case "CONSTR_NOTNULL":
3081
+ nullable = false;
3082
+ break;
3083
+ case "CONSTR_PRIMARY":
3084
+ primary = true;
3085
+ nullable = false;
3086
+ primaryCol = colName;
3087
+ break;
3088
+ case "CONSTR_UNIQUE":
3089
+ unique = true;
3090
+ break;
3091
+ case "CONSTR_DEFAULT":
3092
+ defaultVal = "<expr>";
3093
+ break;
3094
+ case "CONSTR_FOREIGN": {
3095
+ const pkTable = ct.pktable?.relname ?? "";
3096
+ const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3097
+ if (pkTable && pkCols.length) {
3098
+ fks.push({
3099
+ constraintName: ct.conname || `${tableName}_${colName}_fkey`,
3100
+ sourceTable: tableName,
3101
+ sourceColumn: colName,
3102
+ targetTable: pkTable,
3103
+ targetColumn: pkCols[0],
3104
+ onDelete: mapFkAction(ct.fk_del_action)
3105
+ });
3106
+ }
3107
+ break;
3108
+ }
3109
+ }
3110
+ }
3111
+ columns.set(colName, {
3112
+ name: colName,
3113
+ type: colType,
3114
+ nullable,
3115
+ primary,
3116
+ unique,
3117
+ default: defaultVal
3118
+ });
3119
+ } else if (elt.Constraint) {
3120
+ const ct = elt.Constraint;
3121
+ switch (ct.contype) {
3122
+ case "CONSTR_PRIMARY": {
3123
+ const keys = (ct.keys ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3124
+ if (keys.length) primaryCol = keys[0];
3125
+ break;
3126
+ }
3127
+ case "CONSTR_FOREIGN": {
3128
+ const fkCols = (ct.fk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3129
+ const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3130
+ const pkTable = ct.pktable?.relname ?? "";
3131
+ if (fkCols.length && pkCols.length && pkTable) {
3132
+ fks.push({
3133
+ constraintName: ct.conname || `${tableName}_${fkCols[0]}_fkey`,
3134
+ sourceTable: tableName,
3135
+ sourceColumn: fkCols[0],
3136
+ targetTable: pkTable,
3137
+ targetColumn: pkCols[0],
3138
+ onDelete: mapFkAction(ct.fk_del_action)
3139
+ });
3140
+ }
3141
+ break;
3142
+ }
3143
+ }
3144
+ }
3145
+ }
3146
+ if (primaryCol && columns.has(primaryCol)) {
3147
+ columns.get(primaryCol).primary = true;
3148
+ columns.get(primaryCol).nullable = false;
3149
+ }
3150
+ state.tables.set(tableName, { name: tableName, columns });
3151
+ state.fks.push(...fks);
3152
+ }
3153
+ }
3154
+ function extractEnumsFromStmts(stmts, state) {
3155
+ for (const wrap of stmts) {
3156
+ const body = wrap.stmt?.CreateEnumStmt;
3157
+ if (!body) continue;
3158
+ const names = (body.typeName ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3159
+ const enumName = names[names.length - 1] ?? "";
3160
+ if (!enumName) continue;
3161
+ const vals = new Set(
3162
+ (body.vals ?? []).map((s) => s.String?.sval ?? "").filter(Boolean)
3163
+ );
3164
+ state.enums.set(enumName, { name: enumName, values: vals });
3165
+ }
3166
+ }
3167
+ function applyAstAlterEnums(stmts, state) {
3168
+ for (const wrap of stmts) {
3169
+ const body = wrap.stmt?.AlterEnumStmt;
3170
+ if (!body) continue;
3171
+ const names = (body.typeName ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3172
+ const enumName = names[names.length - 1] ?? "";
3173
+ const en = state.enums.get(enumName);
3174
+ if (!en) continue;
3175
+ if (body.newVal) en.values.add(String(body.newVal));
3176
+ }
3177
+ }
3178
+ function extractExtensionsFromStmts(stmts, state, filepath) {
3179
+ for (const wrap of stmts) {
3180
+ const body = wrap.stmt?.CreateExtensionStmt;
3181
+ if (!body) continue;
3182
+ const name = body.extname ?? "";
3183
+ if (!name) continue;
3184
+ let schema = null;
3185
+ let version = null;
3186
+ for (const opt of body.options ?? []) {
3187
+ const de = opt.DefElem;
3188
+ if (!de) continue;
3189
+ if (de.defname === "schema" && de.arg?.String?.sval) schema = de.arg.String.sval;
3190
+ else if (de.defname === "new_version" && de.arg?.String?.sval) version = de.arg.String.sval;
3191
+ }
3192
+ const next = { name, schema, version, filepath };
3193
+ const existing = state.extensions.findIndex((e) => e.name === name);
3194
+ if (existing >= 0) state.extensions[existing] = next;
3195
+ else state.extensions.push(next);
3196
+ }
3197
+ }
3198
+ function extractTriggersFromStmts(stmts, state, filepath) {
3199
+ for (const wrap of stmts) {
3200
+ const body = wrap.stmt?.CreateTrigStmt;
3201
+ if (!body) continue;
3202
+ const name = body.trigname ?? "";
3203
+ if (!name) continue;
3204
+ const table = body.relation?.relname ?? "";
3205
+ const timingVal = body.timing ?? 0;
3206
+ const eventsVal = body.events ?? 0;
3207
+ const timing = timingVal & 2 ? "BEFORE" : timingVal & 64 ? "INSTEAD OF" : "AFTER";
3208
+ const events = [];
3209
+ if (eventsVal & 4) events.push("INSERT");
3210
+ if (eventsVal & 8) events.push("DELETE");
3211
+ if (eventsVal & 16) events.push("UPDATE");
3212
+ if (eventsVal & 32) events.push("TRUNCATE");
3213
+ const funcname = body.funcname ?? [];
3214
+ const funcCall = funcname[funcname.length - 1]?.String?.sval ?? "";
3215
+ const forEach = body.row ? "ROW" : "STATEMENT";
3216
+ const hasWhen = !!body.whenClause;
3217
+ const next = { name, table, timing, events, function: funcCall, hasWhen, forEach, filepath };
3218
+ const existing = state.triggers.findIndex((t) => t.table === table && t.name === name);
3219
+ if (existing >= 0) state.triggers[existing] = next;
3220
+ else state.triggers.push(next);
3221
+ }
3222
+ }
3223
+ function functionIdFor(name, schema) {
3224
+ return schema ? `${schema}.${name}` : name;
3225
+ }
3226
+ function extractFunctionsFromStmts(stmts, state, filepath) {
3227
+ for (const wrap of stmts) {
3228
+ const body = wrap.stmt?.CreateFunctionStmt;
3229
+ if (!body) continue;
3230
+ const fn = body.funcname ?? [];
3231
+ if (fn.length === 0) continue;
3232
+ const name = fn[fn.length - 1]?.String?.sval ?? "";
3233
+ if (!name) continue;
3234
+ const schema = fn.length > 1 ? fn[fn.length - 2]?.String?.sval ?? null : null;
3235
+ let language = "sql";
3236
+ for (const opt of body.options ?? []) {
3237
+ const de = opt.DefElem;
3238
+ if (de?.defname === "language" && de.arg?.String?.sval) language = de.arg.String.sval;
3239
+ }
3240
+ const returnType = body.returnType ? formatPgTypeName(body.returnType) : "";
3241
+ const isProcedure = !!body.is_procedure;
3242
+ const next = { name, schema, language, returnType, isProcedure, filepath };
3243
+ const id = functionIdFor(name, schema);
3244
+ const existing = state.functions.findIndex((f) => functionIdFor(f.name, f.schema) === id);
3245
+ if (existing >= 0) state.functions[existing] = next;
3246
+ else state.functions.push(next);
3247
+ }
3248
+ }
3249
+ function extractViewsFromStmts(stmts, state, filepath) {
3250
+ for (const wrap of stmts) {
3251
+ const stmt = wrap.stmt ?? {};
3252
+ const view = stmt.ViewStmt;
3253
+ if (view) {
3254
+ const name = view.view?.relname ?? "";
3255
+ if (!name) continue;
3256
+ const schema = view.view?.schemaname ?? null;
3257
+ const next = {
3258
+ name,
3259
+ schema,
3260
+ isMaterialized: false,
3261
+ withCheckOption: String(view.withCheckOption ?? "NO_CHECK_OPTION"),
3262
+ filepath
3263
+ };
3264
+ const id = functionIdFor(name, schema);
3265
+ const existing = state.views.findIndex((v) => functionIdFor(v.name, v.schema) === id);
3266
+ if (existing >= 0) state.views[existing] = next;
3267
+ else state.views.push(next);
3268
+ }
3269
+ const ctas = stmt.CreateTableAsStmt;
3270
+ if (ctas && ctas.objtype === "OBJECT_MATVIEW") {
3271
+ const name = ctas.into?.rel?.relname ?? "";
3272
+ if (!name) continue;
3273
+ const schema = ctas.into?.rel?.schemaname ?? null;
3274
+ const next = {
3275
+ name,
3276
+ schema,
3277
+ isMaterialized: true,
3278
+ withCheckOption: "N/A",
3279
+ filepath
3280
+ };
3281
+ const id = functionIdFor(name, schema);
3282
+ const existing = state.views.findIndex((v) => functionIdFor(v.name, v.schema) === id);
3283
+ if (existing >= 0) state.views[existing] = next;
3284
+ else state.views.push(next);
3285
+ }
3286
+ }
3287
+ }
3288
+ function applyDropsForSchemaObjects(stmts, state) {
3289
+ for (const wrap of stmts) {
3290
+ const drop = wrap.stmt?.DropStmt;
3291
+ if (!drop) continue;
3292
+ const removeType = drop.removeType ?? "";
3293
+ const objects = drop.objects ?? [];
3294
+ if (removeType === "OBJECT_TABLE") {
3295
+ const droppedTables = /* @__PURE__ */ new Set();
3296
+ for (const obj of objects) {
3297
+ const items = obj.List?.items ?? [];
3298
+ const last = items[items.length - 1]?.String?.sval;
3299
+ if (last) droppedTables.add(last);
3300
+ }
3301
+ if (droppedTables.size > 0) {
3302
+ for (const t of droppedTables) state.tables.delete(t);
3303
+ state.fks = state.fks.filter((fk) => !droppedTables.has(fk.sourceTable) && !droppedTables.has(fk.targetTable));
3304
+ }
3305
+ } else if (removeType === "OBJECT_TYPE") {
3306
+ const droppedEnums = /* @__PURE__ */ new Set();
3307
+ for (const obj of objects) {
3308
+ const tn = obj.TypeName;
3309
+ if (!tn) continue;
3310
+ const names = (tn.names ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3311
+ const last = names[names.length - 1];
3312
+ if (last) droppedEnums.add(last);
3313
+ }
3314
+ for (const e of droppedEnums) state.enums.delete(e);
3315
+ } else if (removeType === "OBJECT_EXTENSION") {
3316
+ const names = /* @__PURE__ */ new Set();
3317
+ for (const obj of objects) {
3318
+ const sval = obj.String?.sval;
3319
+ if (sval) names.add(sval);
3320
+ }
3321
+ if (names.size > 0) state.extensions = state.extensions.filter((e) => !names.has(e.name));
3322
+ } else if (removeType === "OBJECT_TRIGGER") {
3323
+ for (const obj of objects) {
3324
+ const items = obj.List?.items ?? [];
3325
+ if (items.length < 2) continue;
3326
+ const table = items[0]?.String?.sval ?? "";
3327
+ const trigName = items[items.length - 1]?.String?.sval ?? "";
3328
+ if (!table || !trigName) continue;
3329
+ state.triggers = state.triggers.filter((t) => !(t.table === table && t.name === trigName));
3330
+ }
3331
+ } else if (removeType === "OBJECT_FUNCTION" || removeType === "OBJECT_PROCEDURE") {
3332
+ for (const obj of objects) {
3333
+ const items = obj.ObjectWithArgs?.objname?.items ?? obj.ObjectWithArgs?.objname ?? obj.List?.items ?? [];
3334
+ if (!items.length) continue;
3335
+ const segs = items.map((s) => s.String?.sval ?? "").filter(Boolean);
3336
+ if (!segs.length) continue;
3337
+ const name = segs[segs.length - 1];
3338
+ const schema = segs.length > 1 ? segs[segs.length - 2] : null;
3339
+ const id = functionIdFor(name, schema);
3340
+ state.functions = state.functions.filter((f) => functionIdFor(f.name, f.schema) !== id);
3341
+ }
3342
+ } else if (removeType === "OBJECT_VIEW" || removeType === "OBJECT_MATVIEW") {
3343
+ for (const obj of objects) {
3344
+ const items = obj.List?.items ?? [];
3345
+ if (!items.length) continue;
3346
+ const name = items[items.length - 1]?.String?.sval ?? "";
3347
+ const schema = items.length > 1 ? items[items.length - 2]?.String?.sval ?? null : null;
3348
+ if (!name) continue;
3349
+ const id = functionIdFor(name, schema);
3350
+ state.views = state.views.filter((v) => functionIdFor(v.name, v.schema) !== id);
3351
+ }
3352
+ }
3353
+ }
3354
+ }
3355
+ function indexIsPrismaUncoverable(idx) {
3356
+ return idx.hasPredicate || idx.hasExpressions || idx.method !== "btree";
3357
+ }
2911
3358
  function loadPrismaState(schemaPath) {
2912
3359
  if (!schemaPath || !(0, import_node_fs8.existsSync)(schemaPath)) return null;
2913
3360
  const content = (0, import_node_fs8.readFileSync)(schemaPath, "utf-8");
@@ -3074,6 +3521,96 @@ function verify(sqlState, prisma) {
3074
3521
  }
3075
3522
  return { contradictions, flaggedEdges };
3076
3523
  }
3524
+ function deriveMigrationName(sqlPath) {
3525
+ const segments = sqlPath.split(/[\\/]/);
3526
+ const last = segments[segments.length - 1];
3527
+ if (last === "migration.sql" && segments.length >= 2) {
3528
+ return segments[segments.length - 2];
3529
+ }
3530
+ return last.replace(/\.sql$/, "");
3531
+ }
3532
+ function extractMigrationInfoFromStmts(stmts, name, filepath) {
3533
+ let isDestructive = false;
3534
+ let hasOrphanCheck = false;
3535
+ let hasSidecarBackup = false;
3536
+ let hasPreFlightNotice = false;
3537
+ let containsBackfill = false;
3538
+ let containsDropColumn = false;
3539
+ let containsDropTable = false;
3540
+ for (const wrap of stmts) {
3541
+ const stmt = wrap.stmt ?? {};
3542
+ const kind = Object.keys(stmt)[0];
3543
+ if (!kind) continue;
3544
+ const body = stmt[kind] ?? {};
3545
+ switch (kind) {
3546
+ case "AlterTableStmt": {
3547
+ const cmds = body.cmds ?? [];
3548
+ for (const c of cmds) {
3549
+ const subtype = c.AlterTableCmd?.subtype;
3550
+ if (subtype === "AT_DropColumn") {
3551
+ containsDropColumn = true;
3552
+ isDestructive = true;
3553
+ } else if (subtype === "AT_AlterColumnType" || subtype === "AT_DropNotNull" || subtype === "AT_DropConstraint") {
3554
+ isDestructive = true;
3555
+ }
3556
+ }
3557
+ break;
3558
+ }
3559
+ case "DropStmt": {
3560
+ const removeType = body.removeType ?? "";
3561
+ if (removeType === "OBJECT_TABLE") {
3562
+ containsDropTable = true;
3563
+ isDestructive = true;
3564
+ } else if (removeType === "OBJECT_TYPE" || removeType === "OBJECT_COLUMN" || removeType === "OBJECT_INDEX" || removeType === "OBJECT_POLICY") {
3565
+ isDestructive = true;
3566
+ }
3567
+ break;
3568
+ }
3569
+ case "CreateStmt": {
3570
+ const relname = body.relation?.relname ?? "";
3571
+ if (relname.startsWith("_backup_")) hasSidecarBackup = true;
3572
+ break;
3573
+ }
3574
+ case "CreateTableAsStmt": {
3575
+ const relname = body.into?.rel?.relname ?? "";
3576
+ if (relname.startsWith("_backup_")) hasSidecarBackup = true;
3577
+ break;
3578
+ }
3579
+ case "UpdateStmt":
3580
+ case "InsertStmt":
3581
+ case "DeleteStmt": {
3582
+ containsBackfill = true;
3583
+ break;
3584
+ }
3585
+ case "DoStmt": {
3586
+ const args = body.args ?? [];
3587
+ for (const arg of args) {
3588
+ const def = arg.DefElem;
3589
+ if (!def || def.defname !== "as") continue;
3590
+ const code = def.arg?.String?.sval ?? "";
3591
+ if (/\bRAISE\s+EXCEPTION\b/i.test(code)) hasOrphanCheck = true;
3592
+ if (/\bRAISE\s+NOTICE\b/i.test(code)) hasPreFlightNotice = true;
3593
+ }
3594
+ break;
3595
+ }
3596
+ }
3597
+ }
3598
+ const tsMatch = name.match(/^(\d{8,14})/);
3599
+ const timestamp = tsMatch ? tsMatch[1] : null;
3600
+ return {
3601
+ name,
3602
+ filepath,
3603
+ timestamp,
3604
+ isDestructive,
3605
+ hasOrphanCheck,
3606
+ hasSidecarBackup,
3607
+ hasPreFlightNotice,
3608
+ containsBackfill,
3609
+ containsDropColumn,
3610
+ containsDropTable,
3611
+ statementCount: stmts.length
3612
+ };
3613
+ }
3077
3614
  function migrationsDirFor(rootDir) {
3078
3615
  const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
3079
3616
  if (!paths) return null;
@@ -3128,6 +3665,132 @@ function generate3(rootDir) {
3128
3665
  values: [...sqlEnum.values]
3129
3666
  });
3130
3667
  }
3668
+ let indexNodeCount = 0;
3669
+ for (const idx of sqlState.indexes) {
3670
+ if (!indexIsPrismaUncoverable(idx)) continue;
3671
+ nodes.push({
3672
+ id: `index:${idx.name}`,
3673
+ type: "index",
3674
+ name: idx.name,
3675
+ source: "sql",
3676
+ table: idx.table,
3677
+ unique: idx.unique,
3678
+ method: idx.method,
3679
+ columns: idx.columns,
3680
+ has_expressions: idx.hasExpressions,
3681
+ has_predicate: idx.hasPredicate,
3682
+ filepath: idx.filepath
3683
+ });
3684
+ indexNodeCount++;
3685
+ }
3686
+ let extensionNodeCount = 0;
3687
+ for (const ext of sqlState.extensions) {
3688
+ nodes.push({
3689
+ id: `extension:${ext.name}`,
3690
+ type: "extension",
3691
+ name: ext.name,
3692
+ source: "sql",
3693
+ schema: ext.schema,
3694
+ version: ext.version,
3695
+ filepath: ext.filepath
3696
+ });
3697
+ extensionNodeCount++;
3698
+ }
3699
+ let triggerNodeCount = 0;
3700
+ for (const trg of sqlState.triggers) {
3701
+ nodes.push({
3702
+ id: `trigger:${trg.table}:${trg.name}`,
3703
+ type: "trigger",
3704
+ name: trg.name,
3705
+ source: "sql",
3706
+ table: trg.table,
3707
+ timing: trg.timing,
3708
+ events: trg.events,
3709
+ function: trg.function,
3710
+ has_when: trg.hasWhen,
3711
+ for_each: trg.forEach,
3712
+ filepath: trg.filepath
3713
+ });
3714
+ triggerNodeCount++;
3715
+ }
3716
+ let functionNodeCount = 0;
3717
+ for (const fn of sqlState.functions) {
3718
+ const qualified = fn.schema ? `${fn.schema}.${fn.name}` : fn.name;
3719
+ nodes.push({
3720
+ id: `function:${qualified}`,
3721
+ type: "function",
3722
+ name: fn.name,
3723
+ source: "sql",
3724
+ schema: fn.schema,
3725
+ language: fn.language,
3726
+ return_type: fn.returnType,
3727
+ is_procedure: fn.isProcedure,
3728
+ filepath: fn.filepath
3729
+ });
3730
+ functionNodeCount++;
3731
+ }
3732
+ let viewNodeCount = 0;
3733
+ for (const vw of sqlState.views) {
3734
+ const qualified = vw.schema ? `${vw.schema}.${vw.name}` : vw.name;
3735
+ nodes.push({
3736
+ id: `${vw.isMaterialized ? "matview" : "view"}:${qualified}`,
3737
+ type: vw.isMaterialized ? "materialized_view" : "view",
3738
+ name: vw.name,
3739
+ source: "sql",
3740
+ schema: vw.schema,
3741
+ is_materialized: vw.isMaterialized,
3742
+ with_check_option: vw.withCheckOption,
3743
+ filepath: vw.filepath
3744
+ });
3745
+ viewNodeCount++;
3746
+ }
3747
+ let policyNodeCount = 0;
3748
+ for (const pol of sqlState.policies) {
3749
+ nodes.push({
3750
+ id: `policy:${pol.table}:${pol.name}`,
3751
+ type: "policy",
3752
+ name: pol.name,
3753
+ source: "sql",
3754
+ table: pol.table,
3755
+ command: pol.command,
3756
+ permissive: pol.permissive,
3757
+ roles: pol.roles,
3758
+ has_using: pol.hasUsing,
3759
+ has_with_check: pol.hasWithCheck,
3760
+ filepath: pol.filepath
3761
+ });
3762
+ policyNodeCount++;
3763
+ }
3764
+ const migrationFiles = migrationsDir ? discoverMigrationFiles(migrationsDir) : [];
3765
+ let migrationNodeCount = 0;
3766
+ for (const sqlPath of migrationFiles) {
3767
+ const sql = (0, import_node_fs8.readFileSync)(sqlPath, "utf-8");
3768
+ const name = deriveMigrationName(sqlPath);
3769
+ let ast;
3770
+ try {
3771
+ ast = postgresDialect.parse(sql);
3772
+ } catch {
3773
+ ast = { stmts: [] };
3774
+ }
3775
+ const info = postgresDialect.extractMigrationInfo(ast, name, sqlPath);
3776
+ nodes.push({
3777
+ id: `migration:${name}`,
3778
+ type: "migration",
3779
+ name,
3780
+ source: "sql",
3781
+ filepath: info.filepath,
3782
+ timestamp: info.timestamp,
3783
+ is_destructive: info.isDestructive,
3784
+ has_orphan_check: info.hasOrphanCheck,
3785
+ has_sidecar_backup: info.hasSidecarBackup,
3786
+ has_pre_flight_notice: info.hasPreFlightNotice,
3787
+ contains_backfill: info.containsBackfill,
3788
+ contains_drop_column: info.containsDropColumn,
3789
+ contains_drop_table: info.containsDropTable,
3790
+ statement_count: info.statementCount
3791
+ });
3792
+ migrationNodeCount++;
3793
+ }
3131
3794
  const sqlOnlyTables = new Set(nodes.filter((n) => n.type === "table").map((n) => n.id));
3132
3795
  const edges = sqlState.fks.filter((fk) => sqlOnlyTables.has(fk.sourceTable)).map((fk) => ({
3133
3796
  source: fk.sourceTable,
@@ -3146,6 +3809,13 @@ function generate3(rootDir) {
3146
3809
  sql_tables: sqlState.tables.size,
3147
3810
  sql_enums: sqlState.enums.size,
3148
3811
  sql_fks: sqlState.fks.length,
3812
+ sql_index_nodes: indexNodeCount,
3813
+ sql_policy_nodes: policyNodeCount,
3814
+ sql_extension_nodes: extensionNodeCount,
3815
+ sql_trigger_nodes: triggerNodeCount,
3816
+ sql_function_nodes: functionNodeCount,
3817
+ sql_view_nodes: viewNodeCount,
3818
+ sql_migration_nodes: migrationNodeCount,
3149
3819
  additive_nodes: nodes.length,
3150
3820
  contradictions_found: contradictions.length,
3151
3821
  flagged_edges_found: flaggedEdges.length
@@ -4693,6 +5363,7 @@ if (!import_node_worker_threads.parentPort) {
4693
5363
  async function run(req) {
4694
5364
  try {
4695
5365
  await initTreeSitter();
5366
+ await (0, import_pgsql_parser2.loadModule)();
4696
5367
  const config = loadConfig(req.rootDir);
4697
5368
  setExtractorConfig({
4698
5369
  dbIdentifiers: config.parsers?.patterns?.dbIdentifiers,