@launchsecure/launch-kit 0.0.29 → 0.0.31

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 (202) hide show
  1. package/dist/beacon/beacon.mjs +2825 -1243
  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/internal/screenshot.d.ts +26 -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/chart-client/assets/{index-CJ4mgRRF.css → index-CDIhdgWg.css} +1 -1
  71. package/dist/chart-client/index.html +2 -2
  72. package/dist/client/assets/{index-DI5qSR_w.css → index-CfW4n40I.css} +1 -1
  73. package/dist/client/index.html +2 -2
  74. package/dist/council-client/assets/{index-C_-vAM9L.css → index-CZim6x1u.css} +1 -1
  75. package/dist/council-client/index.html +2 -2
  76. package/dist/deck-client/assets/{_baseUniq-W2JQDmje.js → _baseUniq-DdHaBFYO.js} +1 -1
  77. package/dist/deck-client/assets/{arc-DIBWAId9.js → arc-D98e_18X.js} +1 -1
  78. package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-CAIRMvJK.js → architectureDiagram-Q4EWVU46-DNFZzh-4.js} +1 -1
  79. package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-BeNaNiOi.js → blockDiagram-DXYQGD6D-DeQvGUdX.js} +1 -1
  80. package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-B9Ozi62h.js → c4Diagram-AHTNJAMY-B6ekZf1n.js} +1 -1
  81. package/dist/deck-client/assets/channel-DmR7Tyyt.js +1 -0
  82. package/dist/deck-client/assets/{chunk-4BX2VUAB-D7AZ47dt.js → chunk-4BX2VUAB-9aDWymq2.js} +1 -1
  83. package/dist/deck-client/assets/{chunk-4TB4RGXK-DnVnNPcI.js → chunk-4TB4RGXK-DtKQqaI7.js} +1 -1
  84. package/dist/deck-client/assets/{chunk-55IACEB6-UKYs-YNd.js → chunk-55IACEB6-COy9hEae.js} +1 -1
  85. package/dist/deck-client/assets/{chunk-EDXVE4YY-D43b-SKn.js → chunk-EDXVE4YY-D_f861An.js} +1 -1
  86. package/dist/deck-client/assets/{chunk-FMBD7UC4-QzBAoyyW.js → chunk-FMBD7UC4-CmuA5UKn.js} +1 -1
  87. package/dist/deck-client/assets/{chunk-OYMX7WX6-Cjif4r6W.js → chunk-OYMX7WX6-vT8z8D-0.js} +1 -1
  88. package/dist/deck-client/assets/{chunk-QZHKN3VN-CqLDirEI.js → chunk-QZHKN3VN-CTlwwg-R.js} +1 -1
  89. package/dist/deck-client/assets/{chunk-YZCP3GAM-_FQvmMs4.js → chunk-YZCP3GAM-C44yr620.js} +1 -1
  90. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-Bl4ozQWs.js +1 -0
  91. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-Bl4ozQWs.js +1 -0
  92. package/dist/deck-client/assets/clone-BAy58j24.js +1 -0
  93. package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-rfrocesE.js → cose-bilkent-S5V4N54A-DBB2J2nL.js} +1 -1
  94. package/dist/deck-client/assets/{dagre-KV5264BT-Bv_7DJat.js → dagre-KV5264BT-DxDTYbKl.js} +1 -1
  95. package/dist/deck-client/assets/{diagram-5BDNPKRD-4F1414G5.js → diagram-5BDNPKRD-DByWrWd1.js} +1 -1
  96. package/dist/deck-client/assets/{diagram-G4DWMVQ6-C4-Pszqm.js → diagram-G4DWMVQ6-B8B6ddMq.js} +1 -1
  97. package/dist/deck-client/assets/{diagram-MMDJMWI5-B647TIx9.js → diagram-MMDJMWI5-BMUZ2PWK.js} +1 -1
  98. package/dist/deck-client/assets/{diagram-TYMM5635-BFAqpezd.js → diagram-TYMM5635-Bk9e8BB-.js} +1 -1
  99. package/dist/deck-client/assets/{erDiagram-SMLLAGMA-BfBfrJOC.js → erDiagram-SMLLAGMA-DcOSwSol.js} +1 -1
  100. package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-DX9YAYes.js → flowDiagram-DWJPFMVM-DI-4BR0F.js} +1 -1
  101. package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-DCuiy7wF.js → ganttDiagram-T4ZO3ILL-BeZuXBoU.js} +1 -1
  102. package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-CGp1IXUh.js → gitGraphDiagram-UUTBAWPF-Bcki__f-.js} +1 -1
  103. package/dist/deck-client/assets/{graph-B7g8aoxv.js → graph-CifKx6G1.js} +1 -1
  104. package/dist/deck-client/assets/index-6sdqbm2o.js +2 -0
  105. package/dist/deck-client/assets/{index-DsIZ3LqL.css → index-BlTlhxFW.css} +1 -1
  106. package/dist/deck-client/assets/index-CB-qlwRT.js +1195 -0
  107. package/dist/deck-client/assets/{infoDiagram-42DDH7IO-L3fahMkF.js → infoDiagram-42DDH7IO-CReN1nFN.js} +1 -1
  108. package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-aS_EjWBZ.js → ishikawaDiagram-UXIWVN3A-CDF_VLN_.js} +1 -1
  109. package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-djTSQZF9.js → journeyDiagram-VCZTEJTY-DwgGrNVB.js} +1 -1
  110. package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-CcTHo4CM.js → kanban-definition-6JOO6SKY-DB_zohh5.js} +1 -1
  111. package/dist/deck-client/assets/{layout-mEJiadb7.js → layout-DFfX1O3z.js} +1 -1
  112. package/dist/deck-client/assets/{linear-XgTKqyRu.js → linear-CtKb4EXj.js} +1 -1
  113. package/dist/deck-client/assets/{min-Ct9jZdpd.js → min-DCRRwUZv.js} +1 -1
  114. package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-BaFxCGNU.js → mindmap-definition-QFDTVHPH-D0QBOiFe.js} +1 -1
  115. package/dist/deck-client/assets/{pieDiagram-DEJITSTG-CIbYYjtw.js → pieDiagram-DEJITSTG-CD-EV5WB.js} +1 -1
  116. package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-D9EtCOvh.js → quadrantDiagram-34T5L4WZ-B-JXZ8xI.js} +1 -1
  117. package/dist/deck-client/assets/{requirementDiagram-MS252O5E-xeni9eVG.js → requirementDiagram-MS252O5E-D2_OK5Dp.js} +1 -1
  118. package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-LYeknz9h.js → sankeyDiagram-XADWPNL6-BbBJqVSC.js} +1 -1
  119. package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-RDbsKFZf.js → sequenceDiagram-FGHM5R23-Db8A-Rkk.js} +1 -1
  120. package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-BH1Zjglk.js → stateDiagram-FHFEXIEX-DGJnanjS.js} +1 -1
  121. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-CR7riiab.js +1 -0
  122. package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-IFXxKptt.js → timeline-definition-GMOUNBTQ-BRkr6T4w.js} +1 -1
  123. package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-D-sLkQs9.js → vennDiagram-DHZGUBPP-d0rsTqFo.js} +1 -1
  124. package/dist/deck-client/assets/{wardley-RL74JXVD-C010F8l4.js → wardley-RL74JXVD-2t7cMqdS.js} +1 -1
  125. package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-BTjjuDU3.js → wardleyDiagram-NUSXRM2D-DzboAsHh.js} +1 -1
  126. package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-AYbv92n-.js → xychartDiagram-5P7HB3ND-CgTP9u2V.js} +1 -1
  127. package/dist/deck-client/index.html +2 -2
  128. package/dist/server/beacon-monitor-entry.js +548 -6
  129. package/dist/server/chart-serve.js +917 -248
  130. package/dist/server/cli.js +2033 -385
  131. package/dist/server/deck-mcp-entry.js +141 -21
  132. package/dist/server/deck-serve.js +141 -21
  133. package/dist/server/graph-mcp-entry.js +1991 -333
  134. package/dist/server/init-entry.js +24 -13
  135. package/dist/server/orbit-entry.js +135 -7
  136. package/dist/server/parse-worker-entry.js +918 -247
  137. package/package.json +4 -2
  138. package/scaffolds/ls-marketplace/plugins/kit/skills/analyse/SKILL.md +180 -0
  139. package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-array/SKILL.md +107 -0
  140. package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-clear/SKILL.md +94 -0
  141. package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-pulse/SKILL.md +82 -0
  142. package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-scan/SKILL.md +66 -0
  143. package/scaffolds/ls-marketplace/plugins/kit/skills/blast-radius/SKILL.md +117 -0
  144. package/scaffolds/ls-marketplace/plugins/kit/skills/brief/SKILL.md +112 -0
  145. package/scaffolds/ls-marketplace/plugins/kit/skills/course/SKILL.md +84 -0
  146. package/scaffolds/ls-marketplace/plugins/kit/skills/debug/SKILL.md +85 -0
  147. package/scaffolds/ls-marketplace/plugins/kit/skills/deploy-check/SKILL.md +160 -0
  148. package/scaffolds/ls-marketplace/plugins/kit/skills/diagram/SKILL.md +152 -0
  149. package/scaffolds/ls-marketplace/plugins/kit/skills/orbit/SKILL.md +87 -0
  150. package/scaffolds/ls-marketplace/plugins/kit/skills/prototype/SKILL.md +110 -0
  151. package/scaffolds/ls-marketplace/plugins/kit/skills/recovery/SKILL.md +95 -0
  152. package/scaffolds/ls-marketplace/plugins/kit/{commands/show-mcp-status.md → skills/show-mcp-status/SKILL.md} +4 -4
  153. package/scaffolds/ls-marketplace/plugins/kit/skills/wireframe/SKILL.md +90 -0
  154. package/scaffolds/statusline/statusline-mcp.sh +21 -9
  155. package/dist/beacon/types/capture/element.d.ts +0 -3
  156. package/dist/beacon/types/capture/element.d.ts.map +0 -1
  157. package/dist/beacon/types/capture/events.d.ts +0 -20
  158. package/dist/beacon/types/capture/events.d.ts.map +0 -1
  159. package/dist/beacon/types/capture/framework.d.ts +0 -3
  160. package/dist/beacon/types/capture/framework.d.ts.map +0 -1
  161. package/dist/beacon/types/capture/metadata.d.ts +0 -3
  162. package/dist/beacon/types/capture/metadata.d.ts.map +0 -1
  163. package/dist/beacon/types/capture/overlay.d.ts +0 -7
  164. package/dist/beacon/types/capture/overlay.d.ts.map +0 -1
  165. package/dist/beacon/types/capture/picker.d.ts.map +0 -1
  166. package/dist/beacon/types/capture/screenshot.d.ts +0 -7
  167. package/dist/beacon/types/capture/screenshot.d.ts.map +0 -1
  168. package/dist/beacon/types/capture/selector.d.ts.map +0 -1
  169. package/dist/beacon/types/monitor/dom.d.ts +0 -13
  170. package/dist/beacon/types/monitor/dom.d.ts.map +0 -1
  171. package/dist/beacon/types/monitor/index.d.ts +0 -19
  172. package/dist/beacon/types/monitor/index.d.ts.map +0 -1
  173. package/dist/beacon/types/monitor/network.d.ts +0 -12
  174. package/dist/beacon/types/monitor/network.d.ts.map +0 -1
  175. package/dist/beacon/types/monitor/transport.d.ts.map +0 -1
  176. package/dist/beacon/types/monitor/types.d.ts.map +0 -1
  177. package/dist/beacon/types/transport/submit.d.ts +0 -3
  178. package/dist/beacon/types/transport/submit.d.ts.map +0 -1
  179. package/dist/beacon/types/ui/button.d.ts +0 -2
  180. package/dist/beacon/types/ui/button.d.ts.map +0 -1
  181. package/dist/beacon/types/ui/drawer.d.ts +0 -33
  182. package/dist/beacon/types/ui/drawer.d.ts.map +0 -1
  183. package/dist/beacon/types/ui/icons.d.ts +0 -9
  184. package/dist/beacon/types/ui/icons.d.ts.map +0 -1
  185. package/dist/beacon/types/ui/monitor-panel.d.ts +0 -19
  186. package/dist/beacon/types/ui/monitor-panel.d.ts.map +0 -1
  187. package/dist/beacon/types/ui/pick-mode-overlay.d.ts.map +0 -1
  188. package/dist/beacon/types/ui/pin-popover.d.ts.map +0 -1
  189. package/dist/deck-client/assets/channel-CRdozqbp.js +0 -1
  190. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-lIZMp57W.js +0 -1
  191. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-lIZMp57W.js +0 -1
  192. package/dist/deck-client/assets/clone-BtWeSTyJ.js +0 -1
  193. package/dist/deck-client/assets/index-Dg1r-WSN.js +0 -476
  194. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-BrV78NDR.js +0 -1
  195. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-array.md +0 -92
  196. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-clear.md +0 -68
  197. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-pulse.md +0 -80
  198. package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-scan.md +0 -62
  199. /package/dist/beacon/types/{capture → internal}/selector.d.ts +0 -0
  200. /package/dist/chart-client/assets/{index-Ccy-DpI-.js → index-B__ARB8k.js} +0 -0
  201. /package/dist/client/assets/{index-Dp0_okva.js → index-h8kMzVtG.js} +0 -0
  202. /package/dist/council-client/assets/{index-Dt4zWKSj.js → index-CWaDcsFR.js} +0 -0
@@ -1084,6 +1084,8 @@ function extractDeep(absPath) {
1084
1084
  false
1085
1085
  );
1086
1086
  const hasEffects = Object.keys(fileEffects).length > 0;
1087
+ const uiLabels = collectUiLabels(root);
1088
+ const notes = collectNotes(root);
1087
1089
  return {
1088
1090
  elements,
1089
1091
  stateVars,
@@ -1091,10 +1093,77 @@ function extractDeep(absPath) {
1091
1093
  variables,
1092
1094
  responses,
1093
1095
  params,
1094
- ...hasEffects ? { effects: fileEffects } : {}
1096
+ ...hasEffects ? { effects: fileEffects } : {},
1097
+ ...uiLabels.length > 0 ? { ui_labels: uiLabels } : {},
1098
+ ...notes.length > 0 ? { notes } : {}
1095
1099
  };
1096
1100
  }
1097
- var import_node_fs11, import_node_path13, 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;
1101
+ function collectNotes(root) {
1102
+ const out = [];
1103
+ const seen = /* @__PURE__ */ new Set();
1104
+ function visit(node) {
1105
+ if (out.length >= NOTES_MAX) return;
1106
+ if (node.type === "comment") {
1107
+ const text = node.text;
1108
+ const startRow = node.startPosition.row;
1109
+ NOTE_REGEX.lastIndex = 0;
1110
+ let m;
1111
+ while ((m = NOTE_REGEX.exec(text)) !== null) {
1112
+ const kind = m[1];
1113
+ const author = m[2];
1114
+ const body = m[3];
1115
+ if (!kind || !body) continue;
1116
+ const newlinesBefore = (text.slice(0, m.index).match(/\n/g) ?? []).length;
1117
+ const line = startRow + 1 + newlinesBefore;
1118
+ const key = `${line}:${kind}`;
1119
+ if (seen.has(key)) continue;
1120
+ seen.add(key);
1121
+ const note = {
1122
+ kind,
1123
+ text: body.length <= 200 ? body : body.slice(0, 200) + "...",
1124
+ line
1125
+ };
1126
+ if (author) note.author = author;
1127
+ out.push(note);
1128
+ if (out.length >= NOTES_MAX) return;
1129
+ }
1130
+ }
1131
+ for (const child of node.namedChildren) {
1132
+ visit(child);
1133
+ if (out.length >= NOTES_MAX) return;
1134
+ }
1135
+ }
1136
+ visit(root);
1137
+ return out;
1138
+ }
1139
+ function collectUiLabels(root) {
1140
+ const out = [];
1141
+ const seen = /* @__PURE__ */ new Set();
1142
+ function visit(node) {
1143
+ if (out.length >= UI_LABELS_MAX) return;
1144
+ if (node.type === "pair") {
1145
+ const key = node.childForFieldName("key");
1146
+ const val = node.childForFieldName("value");
1147
+ if (key && val) {
1148
+ const keyText = key.type === "property_identifier" ? key.text : stringLiteralValue(key) ?? key.text;
1149
+ if (UI_LABEL_KEYS.has(keyText)) {
1150
+ const strVal = stringLiteralValue(val);
1151
+ if (strVal && strVal.length > 0 && strVal.length <= 200 && !seen.has(strVal)) {
1152
+ seen.add(strVal);
1153
+ out.push(strVal);
1154
+ }
1155
+ }
1156
+ }
1157
+ }
1158
+ for (const child of node.namedChildren) {
1159
+ visit(child);
1160
+ if (out.length >= UI_LABELS_MAX) return;
1161
+ }
1162
+ }
1163
+ visit(root);
1164
+ return out;
1165
+ }
1166
+ var import_node_fs11, import_node_path13, 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;
1098
1167
  var init_ts_extractor = __esm({
1099
1168
  "src/server/graph/core/ts-extractor.ts"() {
1100
1169
  "use strict";
@@ -1213,6 +1282,27 @@ var init_ts_extractor = __esm({
1213
1282
  "selected",
1214
1283
  "disabled"
1215
1284
  ]);
1285
+ UI_LABEL_KEYS = /* @__PURE__ */ new Set([
1286
+ "label",
1287
+ "title",
1288
+ "name",
1289
+ "text",
1290
+ "description",
1291
+ "placeholder",
1292
+ "tooltip",
1293
+ "heading",
1294
+ "subheading",
1295
+ "sheetTitle",
1296
+ "sheetDescription",
1297
+ "caption",
1298
+ "cta",
1299
+ "buttonText",
1300
+ "emptyText",
1301
+ "subtitle"
1302
+ ]);
1303
+ UI_LABELS_MAX = 200;
1304
+ NOTE_REGEX = /^\s*(?:\/\/|\/\*+|\*)\s*([A-Z][A-Z0-9_]{1,15})(?:\(([^)]+)\))?:\s*(\S.*?)\s*(?:\*\/)?$/gm;
1305
+ NOTES_MAX = 100;
1216
1306
  }
1217
1307
  });
1218
1308
 
@@ -1936,7 +2026,7 @@ var NON_LAYER_GRAPH_FILES = /* @__PURE__ */ new Set(["tags.json", "effects-index
1936
2026
  function getAvailableLayers(rootDir) {
1937
2027
  const dir = (0, import_node_path9.join)(rootDir, GRAPHS_DIR2);
1938
2028
  if (!(0, import_node_fs7.existsSync)(dir)) return [];
1939
- return (0, import_node_fs7.readdirSync)(dir).filter((f) => f.endsWith(".json") && !NON_LAYER_GRAPH_FILES.has(f)).map((f) => f.replace(".json", ""));
2029
+ return (0, import_node_fs7.readdirSync)(dir).filter((f) => f.endsWith(".json") && !f.startsWith(".") && !NON_LAYER_GRAPH_FILES.has(f)).map((f) => f.replace(".json", ""));
1940
2030
  }
1941
2031
  var graphCache = /* @__PURE__ */ new Map();
1942
2032
  var taggedCache = /* @__PURE__ */ new Map();
@@ -2832,6 +2922,7 @@ function generate(rootDir) {
2832
2922
  responses: deep.responses,
2833
2923
  params: deep.params,
2834
2924
  ...deep.effects ? { effects: deep.effects } : {},
2925
+ ...deep.notes ? { notes: deep.notes } : {},
2835
2926
  _dbCalls: dbCalls
2836
2927
  // temp: used for cross-ref building below
2837
2928
  });
@@ -2852,6 +2943,8 @@ function generate(rootDir) {
2852
2943
  conditions: deep.conditions,
2853
2944
  variables: deep.variables,
2854
2945
  ...deep.effects ? { effects: deep.effects } : {},
2946
+ ...deep.ui_labels ? { ui_labels: deep.ui_labels } : {},
2947
+ ...deep.notes ? { notes: deep.notes } : {},
2855
2948
  ...authWrappers.length > 0 ? { auth: authWrappers } : {},
2856
2949
  ...dbCalls.length > 0 ? { _dbCalls: dbCalls } : {}
2857
2950
  });
@@ -3453,6 +3546,7 @@ var prismaSchemaParser = {
3453
3546
  // src/server/graph/parsers/db/sql-migrations.ts
3454
3547
  var import_node_fs14 = require("node:fs");
3455
3548
  var import_node_path15 = require("node:path");
3549
+ var import_pgsql_parser = require("pgsql-parser");
3456
3550
  init_config();
3457
3551
  var PG_TO_PRISMA = {
3458
3552
  "TEXT": "String",
@@ -3484,243 +3578,6 @@ function pgTypeToPrisma(pgType) {
3484
3578
  const upper = pgType.toUpperCase().trim();
3485
3579
  return PG_TO_PRISMA[upper] ?? upper;
3486
3580
  }
3487
- var ID = `(?:"[\\w$]+"|[\\w$]+)`;
3488
- var QID = `(?:${ID}\\.)?${ID}`;
3489
- function bareName(captured) {
3490
- const parts = captured.split(".");
3491
- const last = parts[parts.length - 1];
3492
- return last.replace(/^"(.*)"$/, "$1").trim();
3493
- }
3494
- function parseCreateTable(sql, state) {
3495
- const re = new RegExp(
3496
- `CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${QID})\\s*\\(([\\s\\S]*?)\\);`,
3497
- "gi"
3498
- );
3499
- let m;
3500
- while ((m = re.exec(sql)) !== null) {
3501
- const tableName = bareName(m[1]);
3502
- const body = m[2];
3503
- const columns = /* @__PURE__ */ new Map();
3504
- let primaryCol = null;
3505
- const inlineFks = [];
3506
- const lines = splitTopLevelCommas(body);
3507
- for (const raw of lines) {
3508
- const trimmed = raw.trim().replace(/,\s*$/, "");
3509
- if (!trimmed || trimmed.startsWith("--")) continue;
3510
- const namedPk = trimmed.match(new RegExp(`^CONSTRAINT\\s+${ID}\\s+PRIMARY\\s+KEY\\s*\\(\\s*(${QID})`, "i"));
3511
- if (namedPk) {
3512
- primaryCol = bareName(namedPk[1]);
3513
- continue;
3514
- }
3515
- const tablePk = trimmed.match(new RegExp(`^PRIMARY\\s+KEY\\s*\\(\\s*(${QID})`, "i"));
3516
- if (tablePk) {
3517
- primaryCol = bareName(tablePk[1]);
3518
- continue;
3519
- }
3520
- if (/^UNIQUE\s*\(/i.test(trimmed)) continue;
3521
- const namedFk = trimmed.match(new RegExp(
3522
- `^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+)?))?`,
3523
- "i"
3524
- ));
3525
- if (namedFk) {
3526
- inlineFks.push({
3527
- constraintName: bareName(namedFk[1]),
3528
- sourceTable: tableName,
3529
- sourceColumn: bareName(namedFk[2]),
3530
- targetTable: bareName(namedFk[3]),
3531
- targetColumn: bareName(namedFk[4]),
3532
- onDelete: namedFk[5] ?? null
3533
- });
3534
- continue;
3535
- }
3536
- const bareFk = trimmed.match(new RegExp(
3537
- `^FOREIGN\\s+KEY\\s*\\(\\s*(${QID})\\s*\\)\\s+REFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
3538
- "i"
3539
- ));
3540
- if (bareFk) {
3541
- inlineFks.push({
3542
- constraintName: `${tableName}_${bareName(bareFk[1])}_fkey`,
3543
- sourceTable: tableName,
3544
- sourceColumn: bareName(bareFk[1]),
3545
- targetTable: bareName(bareFk[2]),
3546
- targetColumn: bareName(bareFk[3]),
3547
- onDelete: bareFk[4] ?? null
3548
- });
3549
- continue;
3550
- }
3551
- if (/^CONSTRAINT\s/i.test(trimmed)) continue;
3552
- const colMatch = trimmed.match(new RegExp(`^(${ID})\\s+(.+)`, "i"));
3553
- if (!colMatch) continue;
3554
- const colName = bareName(colMatch[1]);
3555
- let rest = colMatch[2];
3556
- const inlineRefMatch = rest.match(new RegExp(
3557
- `\\bREFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
3558
- "i"
3559
- ));
3560
- if (inlineRefMatch) {
3561
- inlineFks.push({
3562
- constraintName: `${tableName}_${colName}_fkey`,
3563
- sourceTable: tableName,
3564
- sourceColumn: colName,
3565
- targetTable: bareName(inlineRefMatch[1]),
3566
- targetColumn: bareName(inlineRefMatch[2]),
3567
- onDelete: inlineRefMatch[3] ?? null
3568
- });
3569
- rest = rest.replace(inlineRefMatch[0], "").trim();
3570
- }
3571
- const isNotNull = /\bNOT\s+NULL\b/i.test(rest);
3572
- const isPrimaryKey = /\bPRIMARY\s+KEY\b/i.test(rest);
3573
- const isUnique = /\bUNIQUE\b/i.test(rest);
3574
- const defaultMatch = rest.match(/\bDEFAULT\s+(.+?)(?:\s*,?\s*$)/i);
3575
- const defaultVal = defaultMatch ? defaultMatch[1].trim() : null;
3576
- 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();
3577
- columns.set(colName, {
3578
- name: colName,
3579
- type: colType,
3580
- nullable: !isNotNull && !isPrimaryKey,
3581
- primary: isPrimaryKey,
3582
- unique: isUnique,
3583
- default: defaultVal
3584
- });
3585
- if (isPrimaryKey) primaryCol = colName;
3586
- }
3587
- if (primaryCol && columns.has(primaryCol)) {
3588
- columns.get(primaryCol).primary = true;
3589
- }
3590
- state.tables.set(tableName, { name: tableName, columns });
3591
- state.fks.push(...inlineFks);
3592
- }
3593
- }
3594
- function splitTopLevelCommas(body) {
3595
- const out = [];
3596
- let depth = 0;
3597
- let buf = "";
3598
- let inString = null;
3599
- for (const ch of body) {
3600
- if (inString) {
3601
- buf += ch;
3602
- if (ch === inString) inString = null;
3603
- continue;
3604
- }
3605
- if (ch === "'" || ch === '"') {
3606
- inString = ch;
3607
- buf += ch;
3608
- continue;
3609
- }
3610
- if (ch === "(") depth++;
3611
- else if (ch === ")") depth--;
3612
- if (ch === "," && depth === 0) {
3613
- out.push(buf);
3614
- buf = "";
3615
- continue;
3616
- }
3617
- buf += ch;
3618
- }
3619
- if (buf.trim()) out.push(buf);
3620
- return out;
3621
- }
3622
- function parseCreateEnum(sql, state) {
3623
- const re = new RegExp(
3624
- `CREATE\\s+TYPE\\s+(${QID})\\s+AS\\s+ENUM\\s*\\(([^)]+)\\)`,
3625
- "gi"
3626
- );
3627
- let m;
3628
- while ((m = re.exec(sql)) !== null) {
3629
- const enumName = bareName(m[1]);
3630
- const valuesStr = m[2];
3631
- const values = new Set(
3632
- valuesStr.split(",").map((v) => v.trim().replace(/^'(.*)'$/, "$1")).filter(Boolean)
3633
- );
3634
- state.enums.set(enumName, { name: enumName, values });
3635
- }
3636
- }
3637
- function parseAlterTable(sql, state) {
3638
- const addColRe = new RegExp(
3639
- `ALTER\\s+TABLE\\s+(${QID})\\s+ADD\\s+COLUMN\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${QID})\\s+(.+?);`,
3640
- "gi"
3641
- );
3642
- let m;
3643
- while ((m = addColRe.exec(sql)) !== null) {
3644
- const tableName = bareName(m[1]);
3645
- const colName = bareName(m[2]);
3646
- let rest = m[3];
3647
- const table = state.tables.get(tableName);
3648
- if (!table) continue;
3649
- const isNotNull = /\bNOT\s+NULL\b/i.test(rest);
3650
- const defaultMatch = rest.match(/\bDEFAULT\s+(.+?)$/i);
3651
- const defaultVal = defaultMatch ? defaultMatch[1].trim() : null;
3652
- let colType = rest.replace(/\bNOT\s+NULL\b/gi, "").replace(/\bDEFAULT\s+.*/gi, "").trim();
3653
- table.columns.set(colName, {
3654
- name: colName,
3655
- type: colType,
3656
- nullable: !isNotNull,
3657
- primary: false,
3658
- unique: false,
3659
- default: defaultVal
3660
- });
3661
- }
3662
- const dropColRe = new RegExp(
3663
- `ALTER\\s+TABLE\\s+(${QID})\\s+DROP\\s+COLUMN\\s+(?:IF\\s+EXISTS\\s+)?(${QID})`,
3664
- "gi"
3665
- );
3666
- while ((m = dropColRe.exec(sql)) !== null) {
3667
- const table = state.tables.get(bareName(m[1]));
3668
- if (table) table.columns.delete(bareName(m[2]));
3669
- }
3670
- const fkRe = new RegExp(
3671
- `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+)?))?`,
3672
- "gi"
3673
- );
3674
- while ((m = fkRe.exec(sql)) !== null) {
3675
- state.fks.push({
3676
- constraintName: bareName(m[2]),
3677
- sourceTable: bareName(m[1]),
3678
- sourceColumn: bareName(m[3]),
3679
- targetTable: bareName(m[4]),
3680
- targetColumn: bareName(m[5]),
3681
- onDelete: m[6] ?? null
3682
- });
3683
- }
3684
- }
3685
- function parseAlterEnum(sql, state) {
3686
- const re = new RegExp(
3687
- `ALTER\\s+TYPE\\s+(${QID})\\s+ADD\\s+VALUE\\s+'([^']+)'`,
3688
- "gi"
3689
- );
3690
- let m;
3691
- while ((m = re.exec(sql)) !== null) {
3692
- const en = state.enums.get(bareName(m[1]));
3693
- if (en) en.values.add(m[2]);
3694
- }
3695
- }
3696
- function parseDropTable(sql, state) {
3697
- const re = new RegExp(
3698
- `DROP\\s+TABLE\\s+(?:IF\\s+EXISTS\\s+)?(${QID})`,
3699
- "gi"
3700
- );
3701
- let m;
3702
- while ((m = re.exec(sql)) !== null) {
3703
- const dropped = bareName(m[1]);
3704
- state.tables.delete(dropped);
3705
- state.fks = state.fks.filter((fk) => fk.sourceTable !== dropped && fk.targetTable !== dropped);
3706
- }
3707
- }
3708
- function parseUniqueIndex(sql, state) {
3709
- const re = new RegExp(
3710
- `CREATE\\s+UNIQUE\\s+INDEX\\s+(?:(?:IF\\s+NOT\\s+EXISTS\\s+)?(?:${ID}\\s+)?)?ON\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)`,
3711
- "gi"
3712
- );
3713
- let m;
3714
- while ((m = re.exec(sql)) !== null) {
3715
- const tableName = bareName(m[1]);
3716
- const colName = bareName(m[2]);
3717
- const table = state.tables.get(tableName);
3718
- const col = table?.columns.get(colName);
3719
- if (col) col.unique = true;
3720
- if (!state.uniqueIndexes.has(tableName)) state.uniqueIndexes.set(tableName, /* @__PURE__ */ new Set());
3721
- state.uniqueIndexes.get(tableName).add(colName);
3722
- }
3723
- }
3724
3581
  function discoverMigrationFiles(migrationsDir) {
3725
3582
  if (!(0, import_node_fs14.existsSync)(migrationsDir)) return [];
3726
3583
  const out = [];
@@ -3735,25 +3592,614 @@ function discoverMigrationFiles(migrationsDir) {
3735
3592
  }
3736
3593
  return out;
3737
3594
  }
3738
- function parseMigrations(migrationsDir) {
3595
+ var postgresDialect = {
3596
+ parse(sql) {
3597
+ return (0, import_pgsql_parser.parseSync)(sql);
3598
+ },
3599
+ applyAll(ast, state, filepath) {
3600
+ const stmts = ast.stmts ?? [];
3601
+ extractTablesFromStmts(stmts, state);
3602
+ extractEnumsFromStmts(stmts, state);
3603
+ extractIndexesFromStmts(stmts, state, filepath);
3604
+ extractPoliciesFromStmts(stmts, state, filepath);
3605
+ extractExtensionsFromStmts(stmts, state, filepath);
3606
+ extractTriggersFromStmts(stmts, state, filepath);
3607
+ extractFunctionsFromStmts(stmts, state, filepath);
3608
+ extractViewsFromStmts(stmts, state, filepath);
3609
+ applyDropIndexes(stmts, state);
3610
+ applyDropPolicies(stmts, state);
3611
+ applyDropsForSchemaObjects(stmts, state);
3612
+ applyAstAlterEnums(stmts, state);
3613
+ applyAstAlterations(stmts, state);
3614
+ },
3615
+ extractMigrationInfo(ast, name, filepath) {
3616
+ const stmts = ast.stmts ?? [];
3617
+ return extractMigrationInfoFromStmts(stmts, name, filepath);
3618
+ }
3619
+ };
3620
+ function parseMigrations(migrationsDir, dialect = postgresDialect) {
3739
3621
  const state = {
3740
3622
  tables: /* @__PURE__ */ new Map(),
3741
3623
  enums: /* @__PURE__ */ new Map(),
3742
3624
  fks: [],
3743
- uniqueIndexes: /* @__PURE__ */ new Map()
3625
+ uniqueIndexes: /* @__PURE__ */ new Map(),
3626
+ indexes: [],
3627
+ policies: [],
3628
+ extensions: [],
3629
+ triggers: [],
3630
+ functions: [],
3631
+ views: []
3744
3632
  };
3745
3633
  if (!migrationsDir) return state;
3746
3634
  for (const sqlPath of discoverMigrationFiles(migrationsDir)) {
3747
3635
  const sql = (0, import_node_fs14.readFileSync)(sqlPath, "utf-8");
3748
- parseCreateEnum(sql, state);
3749
- parseCreateTable(sql, state);
3750
- parseAlterTable(sql, state);
3751
- parseAlterEnum(sql, state);
3752
- parseDropTable(sql, state);
3753
- parseUniqueIndex(sql, state);
3636
+ let ast;
3637
+ try {
3638
+ ast = dialect.parse(sql);
3639
+ } catch {
3640
+ continue;
3641
+ }
3642
+ dialect.applyAll(ast, state, sqlPath);
3754
3643
  }
3755
3644
  return state;
3756
3645
  }
3646
+ function extractIndexesFromStmts(stmts, state, filepath) {
3647
+ for (const wrap of stmts) {
3648
+ const stmt = wrap.stmt ?? {};
3649
+ const ix = stmt.IndexStmt;
3650
+ if (!ix) continue;
3651
+ const name = ix.idxname ?? "";
3652
+ if (!name) continue;
3653
+ const table = ix.relation?.relname ?? "";
3654
+ const unique = !!ix.unique;
3655
+ const method = String(ix.accessMethod ?? "btree").toLowerCase();
3656
+ const params = ix.indexParams ?? [];
3657
+ const columns = [];
3658
+ let hasExpressions = false;
3659
+ for (const p of params) {
3660
+ const elem = p.IndexElem;
3661
+ if (!elem) continue;
3662
+ if (elem.name) columns.push(elem.name);
3663
+ else if (elem.expr) hasExpressions = true;
3664
+ }
3665
+ const hasPredicate = !!ix.whereClause;
3666
+ const existing = state.indexes.findIndex((i) => i.name === name);
3667
+ const next = { name, table, unique, method, columns, hasExpressions, hasPredicate, filepath };
3668
+ if (existing >= 0) state.indexes[existing] = next;
3669
+ else state.indexes.push(next);
3670
+ if (unique && columns.length === 1 && !hasPredicate && !hasExpressions) {
3671
+ const t = state.tables.get(table);
3672
+ const col = t?.columns.get(columns[0]);
3673
+ if (col) col.unique = true;
3674
+ if (!state.uniqueIndexes.has(table)) state.uniqueIndexes.set(table, /* @__PURE__ */ new Set());
3675
+ state.uniqueIndexes.get(table).add(columns[0]);
3676
+ }
3677
+ }
3678
+ }
3679
+ function applyDropIndexes(stmts, state) {
3680
+ for (const wrap of stmts) {
3681
+ const drop = wrap.stmt?.DropStmt;
3682
+ if (!drop || drop.removeType !== "OBJECT_INDEX") continue;
3683
+ const objects = drop.objects ?? [];
3684
+ const droppedNames = /* @__PURE__ */ new Set();
3685
+ for (const obj of objects) {
3686
+ const items = obj.List?.items ?? [];
3687
+ const last = items[items.length - 1]?.String?.sval;
3688
+ if (last) droppedNames.add(last);
3689
+ }
3690
+ if (droppedNames.size > 0) {
3691
+ state.indexes = state.indexes.filter((i) => !droppedNames.has(i.name));
3692
+ }
3693
+ }
3694
+ }
3695
+ function formatPgTypeName(typeName) {
3696
+ const names = (typeName?.names ?? []).map((n) => n.String?.sval ?? "").filter(Boolean);
3697
+ const base = (names[names.length - 1] ?? "").toLowerCase();
3698
+ const PG_INTERNAL_MAP = {
3699
+ int4: "INTEGER",
3700
+ int8: "BIGINT",
3701
+ int2: "SMALLINT",
3702
+ float8: "DOUBLE PRECISION",
3703
+ float4: "REAL",
3704
+ bool: "BOOLEAN",
3705
+ bpchar: "CHAR",
3706
+ timestamptz: "TIMESTAMPTZ",
3707
+ timestamp: "TIMESTAMP",
3708
+ numeric: "NUMERIC",
3709
+ text: "TEXT",
3710
+ varchar: "VARCHAR",
3711
+ jsonb: "JSONB",
3712
+ json: "JSON",
3713
+ uuid: "UUID",
3714
+ date: "DATE",
3715
+ bytea: "BYTEA"
3716
+ };
3717
+ return PG_INTERNAL_MAP[base] ?? base.toUpperCase();
3718
+ }
3719
+ function applyAstAlterations(stmts, state) {
3720
+ for (const wrap of stmts) {
3721
+ const stmt = wrap.stmt ?? {};
3722
+ const kind = Object.keys(stmt)[0];
3723
+ if (!kind) continue;
3724
+ if (kind === "AlterTableStmt") {
3725
+ const body = stmt.AlterTableStmt;
3726
+ const tableName = body.relation?.relname ?? "";
3727
+ const table = state.tables.get(tableName);
3728
+ if (!table) continue;
3729
+ const cmds = body.cmds ?? [];
3730
+ for (const c of cmds) {
3731
+ const cmd = c.AlterTableCmd;
3732
+ if (!cmd) continue;
3733
+ const subtype = cmd.subtype ?? "";
3734
+ const colName = cmd.name ?? "";
3735
+ const col = colName ? table.columns.get(colName) : void 0;
3736
+ switch (subtype) {
3737
+ case "AT_AlterColumnType": {
3738
+ if (!col) break;
3739
+ const typeName = cmd.def?.ColumnDef?.typeName ?? cmd.def?.typeName;
3740
+ if (typeName) col.type = formatPgTypeNameWithMods(typeName);
3741
+ break;
3742
+ }
3743
+ case "AT_SetNotNull":
3744
+ if (col) col.nullable = false;
3745
+ break;
3746
+ case "AT_DropNotNull":
3747
+ if (col) col.nullable = true;
3748
+ break;
3749
+ case "AT_AddColumn": {
3750
+ const cd = cmd.def?.ColumnDef;
3751
+ if (!cd) break;
3752
+ const newColName = cd.colname ?? "";
3753
+ if (!newColName) break;
3754
+ if (table.columns.has(newColName)) break;
3755
+ let nullable = true;
3756
+ let primary = false;
3757
+ let unique = false;
3758
+ let defaultVal = null;
3759
+ for (const c2 of cd.constraints ?? []) {
3760
+ const ct = c2.Constraint;
3761
+ if (!ct) continue;
3762
+ if (ct.contype === "CONSTR_NOTNULL") nullable = false;
3763
+ else if (ct.contype === "CONSTR_PRIMARY") {
3764
+ primary = true;
3765
+ nullable = false;
3766
+ } else if (ct.contype === "CONSTR_UNIQUE") unique = true;
3767
+ else if (ct.contype === "CONSTR_DEFAULT") defaultVal = "<expr>";
3768
+ }
3769
+ table.columns.set(newColName, {
3770
+ name: newColName,
3771
+ type: formatPgTypeNameWithMods(cd.typeName),
3772
+ nullable,
3773
+ primary,
3774
+ unique,
3775
+ default: defaultVal
3776
+ });
3777
+ break;
3778
+ }
3779
+ case "AT_DropColumn":
3780
+ if (colName) table.columns.delete(colName);
3781
+ break;
3782
+ case "AT_AddConstraint": {
3783
+ const ct = cmd.def?.Constraint;
3784
+ if (!ct) break;
3785
+ if (ct.contype !== "CONSTR_FOREIGN") break;
3786
+ const fkCols = (ct.fk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3787
+ const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3788
+ const pkTable = ct.pktable?.relname ?? "";
3789
+ if (fkCols.length && pkCols.length && pkTable) {
3790
+ state.fks.push({
3791
+ constraintName: ct.conname || `${tableName}_${fkCols[0]}_fkey`,
3792
+ sourceTable: tableName,
3793
+ sourceColumn: fkCols[0],
3794
+ targetTable: pkTable,
3795
+ targetColumn: pkCols[0],
3796
+ onDelete: mapFkAction(ct.fk_del_action)
3797
+ });
3798
+ }
3799
+ break;
3800
+ }
3801
+ }
3802
+ }
3803
+ } else if (kind === "RenameStmt") {
3804
+ const body = stmt.RenameStmt;
3805
+ const renameType = body.renameType ?? "";
3806
+ const newName = body.newname ?? "";
3807
+ if (renameType === "OBJECT_COLUMN") {
3808
+ const tableName = body.relation?.relname ?? "";
3809
+ const oldName = body.subname ?? "";
3810
+ const table = state.tables.get(tableName);
3811
+ if (!table || !oldName || !newName) continue;
3812
+ const col = table.columns.get(oldName);
3813
+ if (col) {
3814
+ col.name = newName;
3815
+ table.columns.delete(oldName);
3816
+ table.columns.set(newName, col);
3817
+ }
3818
+ } else if (renameType === "OBJECT_TABLE") {
3819
+ const oldName = body.relation?.relname ?? "";
3820
+ if (!oldName || !newName) continue;
3821
+ const t = state.tables.get(oldName);
3822
+ if (!t) continue;
3823
+ state.tables.delete(oldName);
3824
+ t.name = newName;
3825
+ state.tables.set(newName, t);
3826
+ for (const fk of state.fks) {
3827
+ if (fk.sourceTable === oldName) fk.sourceTable = newName;
3828
+ if (fk.targetTable === oldName) fk.targetTable = newName;
3829
+ }
3830
+ }
3831
+ }
3832
+ }
3833
+ }
3834
+ function extractPoliciesFromStmts(stmts, state, filepath) {
3835
+ for (const wrap of stmts) {
3836
+ const body = wrap.stmt?.CreatePolicyStmt;
3837
+ if (!body) continue;
3838
+ const name = body.policy_name ?? "";
3839
+ if (!name) continue;
3840
+ const table = body.table?.relname ?? "";
3841
+ const cmdRaw = String(body.cmd_name ?? "all").toUpperCase();
3842
+ const command = ["SELECT", "INSERT", "UPDATE", "DELETE", "ALL"].includes(cmdRaw) ? cmdRaw : "ALL";
3843
+ const permissive = body.permissive === true;
3844
+ const roles = (body.roles ?? []).map((r) => {
3845
+ const rs = r.RoleSpec;
3846
+ if (!rs) return "";
3847
+ if (rs.roletype === "ROLESPEC_PUBLIC") return "public";
3848
+ if (rs.roletype === "ROLESPEC_CURRENT_USER") return "current_user";
3849
+ if (rs.roletype === "ROLESPEC_CSTRING" && rs.rolename) return rs.rolename;
3850
+ return "";
3851
+ }).filter(Boolean);
3852
+ const hasUsing = !!body.qual;
3853
+ const hasWithCheck = !!body.with_check;
3854
+ const existing = state.policies.findIndex((p) => p.table === table && p.name === name);
3855
+ const next = { name, table, command, permissive, roles, hasUsing, hasWithCheck, filepath };
3856
+ if (existing >= 0) state.policies[existing] = next;
3857
+ else state.policies.push(next);
3858
+ }
3859
+ }
3860
+ function applyDropPolicies(stmts, state) {
3861
+ for (const wrap of stmts) {
3862
+ const drop = wrap.stmt?.DropStmt;
3863
+ if (!drop || drop.removeType !== "OBJECT_POLICY") continue;
3864
+ const objects = drop.objects ?? [];
3865
+ for (const obj of objects) {
3866
+ const items = obj.List?.items ?? [];
3867
+ if (items.length < 2) continue;
3868
+ const table = items[0]?.String?.sval ?? "";
3869
+ const policyName = items[items.length - 1]?.String?.sval ?? "";
3870
+ if (!table || !policyName) continue;
3871
+ state.policies = state.policies.filter((p) => !(p.table === table && p.name === policyName));
3872
+ }
3873
+ }
3874
+ }
3875
+ function mapFkAction(action) {
3876
+ if (!action) return null;
3877
+ const m = {
3878
+ r: "RESTRICT",
3879
+ c: "CASCADE",
3880
+ s: "SET NULL",
3881
+ d: "SET DEFAULT",
3882
+ a: "NO ACTION",
3883
+ // pgsql-parser may also emit FKCONSTR_ACTION_* enum strings:
3884
+ FKCONSTR_ACTION_RESTRICT: "RESTRICT",
3885
+ FKCONSTR_ACTION_CASCADE: "CASCADE",
3886
+ FKCONSTR_ACTION_SETNULL: "SET NULL",
3887
+ FKCONSTR_ACTION_SETDEFAULT: "SET DEFAULT",
3888
+ FKCONSTR_ACTION_NOACTION: "NO ACTION"
3889
+ };
3890
+ return m[action] ?? null;
3891
+ }
3892
+ function formatPgTypeNameWithMods(typeName) {
3893
+ const base = formatPgTypeName(typeName);
3894
+ if (base === "String" || base === "unknown") return base;
3895
+ const typmods = [];
3896
+ for (const m of typeName?.typmods ?? []) {
3897
+ const v = m.A_Const?.ival?.ival;
3898
+ if (typeof v === "number") typmods.push(v);
3899
+ }
3900
+ return typmods.length ? `${base}(${typmods.join(",")})` : base;
3901
+ }
3902
+ function extractTablesFromStmts(stmts, state) {
3903
+ for (const wrap of stmts) {
3904
+ const body = wrap.stmt?.CreateStmt;
3905
+ if (!body) continue;
3906
+ const tableName = body.relation?.relname ?? "";
3907
+ if (!tableName) continue;
3908
+ const columns = /* @__PURE__ */ new Map();
3909
+ const fks = [];
3910
+ let primaryCol = null;
3911
+ for (const elt of body.tableElts ?? []) {
3912
+ if (elt.ColumnDef) {
3913
+ const cd = elt.ColumnDef;
3914
+ const colName = cd.colname ?? "";
3915
+ if (!colName) continue;
3916
+ const colType = formatPgTypeNameWithMods(cd.typeName);
3917
+ let nullable = true;
3918
+ let primary = false;
3919
+ let unique = false;
3920
+ let defaultVal = null;
3921
+ for (const c of cd.constraints ?? []) {
3922
+ const ct = c.Constraint;
3923
+ if (!ct) continue;
3924
+ switch (ct.contype) {
3925
+ case "CONSTR_NOTNULL":
3926
+ nullable = false;
3927
+ break;
3928
+ case "CONSTR_PRIMARY":
3929
+ primary = true;
3930
+ nullable = false;
3931
+ primaryCol = colName;
3932
+ break;
3933
+ case "CONSTR_UNIQUE":
3934
+ unique = true;
3935
+ break;
3936
+ case "CONSTR_DEFAULT":
3937
+ defaultVal = "<expr>";
3938
+ break;
3939
+ case "CONSTR_FOREIGN": {
3940
+ const pkTable = ct.pktable?.relname ?? "";
3941
+ const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3942
+ if (pkTable && pkCols.length) {
3943
+ fks.push({
3944
+ constraintName: ct.conname || `${tableName}_${colName}_fkey`,
3945
+ sourceTable: tableName,
3946
+ sourceColumn: colName,
3947
+ targetTable: pkTable,
3948
+ targetColumn: pkCols[0],
3949
+ onDelete: mapFkAction(ct.fk_del_action)
3950
+ });
3951
+ }
3952
+ break;
3953
+ }
3954
+ }
3955
+ }
3956
+ columns.set(colName, {
3957
+ name: colName,
3958
+ type: colType,
3959
+ nullable,
3960
+ primary,
3961
+ unique,
3962
+ default: defaultVal
3963
+ });
3964
+ } else if (elt.Constraint) {
3965
+ const ct = elt.Constraint;
3966
+ switch (ct.contype) {
3967
+ case "CONSTR_PRIMARY": {
3968
+ const keys = (ct.keys ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3969
+ if (keys.length) primaryCol = keys[0];
3970
+ break;
3971
+ }
3972
+ case "CONSTR_FOREIGN": {
3973
+ const fkCols = (ct.fk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3974
+ const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
3975
+ const pkTable = ct.pktable?.relname ?? "";
3976
+ if (fkCols.length && pkCols.length && pkTable) {
3977
+ fks.push({
3978
+ constraintName: ct.conname || `${tableName}_${fkCols[0]}_fkey`,
3979
+ sourceTable: tableName,
3980
+ sourceColumn: fkCols[0],
3981
+ targetTable: pkTable,
3982
+ targetColumn: pkCols[0],
3983
+ onDelete: mapFkAction(ct.fk_del_action)
3984
+ });
3985
+ }
3986
+ break;
3987
+ }
3988
+ }
3989
+ }
3990
+ }
3991
+ if (primaryCol && columns.has(primaryCol)) {
3992
+ columns.get(primaryCol).primary = true;
3993
+ columns.get(primaryCol).nullable = false;
3994
+ }
3995
+ state.tables.set(tableName, { name: tableName, columns });
3996
+ state.fks.push(...fks);
3997
+ }
3998
+ }
3999
+ function extractEnumsFromStmts(stmts, state) {
4000
+ for (const wrap of stmts) {
4001
+ const body = wrap.stmt?.CreateEnumStmt;
4002
+ if (!body) continue;
4003
+ const names = (body.typeName ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
4004
+ const enumName = names[names.length - 1] ?? "";
4005
+ if (!enumName) continue;
4006
+ const vals = new Set(
4007
+ (body.vals ?? []).map((s) => s.String?.sval ?? "").filter(Boolean)
4008
+ );
4009
+ state.enums.set(enumName, { name: enumName, values: vals });
4010
+ }
4011
+ }
4012
+ function applyAstAlterEnums(stmts, state) {
4013
+ for (const wrap of stmts) {
4014
+ const body = wrap.stmt?.AlterEnumStmt;
4015
+ if (!body) continue;
4016
+ const names = (body.typeName ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
4017
+ const enumName = names[names.length - 1] ?? "";
4018
+ const en = state.enums.get(enumName);
4019
+ if (!en) continue;
4020
+ if (body.newVal) en.values.add(String(body.newVal));
4021
+ }
4022
+ }
4023
+ function extractExtensionsFromStmts(stmts, state, filepath) {
4024
+ for (const wrap of stmts) {
4025
+ const body = wrap.stmt?.CreateExtensionStmt;
4026
+ if (!body) continue;
4027
+ const name = body.extname ?? "";
4028
+ if (!name) continue;
4029
+ let schema = null;
4030
+ let version = null;
4031
+ for (const opt of body.options ?? []) {
4032
+ const de = opt.DefElem;
4033
+ if (!de) continue;
4034
+ if (de.defname === "schema" && de.arg?.String?.sval) schema = de.arg.String.sval;
4035
+ else if (de.defname === "new_version" && de.arg?.String?.sval) version = de.arg.String.sval;
4036
+ }
4037
+ const next = { name, schema, version, filepath };
4038
+ const existing = state.extensions.findIndex((e) => e.name === name);
4039
+ if (existing >= 0) state.extensions[existing] = next;
4040
+ else state.extensions.push(next);
4041
+ }
4042
+ }
4043
+ function extractTriggersFromStmts(stmts, state, filepath) {
4044
+ for (const wrap of stmts) {
4045
+ const body = wrap.stmt?.CreateTrigStmt;
4046
+ if (!body) continue;
4047
+ const name = body.trigname ?? "";
4048
+ if (!name) continue;
4049
+ const table = body.relation?.relname ?? "";
4050
+ const timingVal = body.timing ?? 0;
4051
+ const eventsVal = body.events ?? 0;
4052
+ const timing = timingVal & 2 ? "BEFORE" : timingVal & 64 ? "INSTEAD OF" : "AFTER";
4053
+ const events = [];
4054
+ if (eventsVal & 4) events.push("INSERT");
4055
+ if (eventsVal & 8) events.push("DELETE");
4056
+ if (eventsVal & 16) events.push("UPDATE");
4057
+ if (eventsVal & 32) events.push("TRUNCATE");
4058
+ const funcname = body.funcname ?? [];
4059
+ const funcCall = funcname[funcname.length - 1]?.String?.sval ?? "";
4060
+ const forEach = body.row ? "ROW" : "STATEMENT";
4061
+ const hasWhen = !!body.whenClause;
4062
+ const next = { name, table, timing, events, function: funcCall, hasWhen, forEach, filepath };
4063
+ const existing = state.triggers.findIndex((t) => t.table === table && t.name === name);
4064
+ if (existing >= 0) state.triggers[existing] = next;
4065
+ else state.triggers.push(next);
4066
+ }
4067
+ }
4068
+ function functionIdFor(name, schema) {
4069
+ return schema ? `${schema}.${name}` : name;
4070
+ }
4071
+ function extractFunctionsFromStmts(stmts, state, filepath) {
4072
+ for (const wrap of stmts) {
4073
+ const body = wrap.stmt?.CreateFunctionStmt;
4074
+ if (!body) continue;
4075
+ const fn = body.funcname ?? [];
4076
+ if (fn.length === 0) continue;
4077
+ const name = fn[fn.length - 1]?.String?.sval ?? "";
4078
+ if (!name) continue;
4079
+ const schema = fn.length > 1 ? fn[fn.length - 2]?.String?.sval ?? null : null;
4080
+ let language = "sql";
4081
+ for (const opt of body.options ?? []) {
4082
+ const de = opt.DefElem;
4083
+ if (de?.defname === "language" && de.arg?.String?.sval) language = de.arg.String.sval;
4084
+ }
4085
+ const returnType = body.returnType ? formatPgTypeName(body.returnType) : "";
4086
+ const isProcedure = !!body.is_procedure;
4087
+ const next = { name, schema, language, returnType, isProcedure, filepath };
4088
+ const id = functionIdFor(name, schema);
4089
+ const existing = state.functions.findIndex((f) => functionIdFor(f.name, f.schema) === id);
4090
+ if (existing >= 0) state.functions[existing] = next;
4091
+ else state.functions.push(next);
4092
+ }
4093
+ }
4094
+ function extractViewsFromStmts(stmts, state, filepath) {
4095
+ for (const wrap of stmts) {
4096
+ const stmt = wrap.stmt ?? {};
4097
+ const view = stmt.ViewStmt;
4098
+ if (view) {
4099
+ const name = view.view?.relname ?? "";
4100
+ if (!name) continue;
4101
+ const schema = view.view?.schemaname ?? null;
4102
+ const next = {
4103
+ name,
4104
+ schema,
4105
+ isMaterialized: false,
4106
+ withCheckOption: String(view.withCheckOption ?? "NO_CHECK_OPTION"),
4107
+ filepath
4108
+ };
4109
+ const id = functionIdFor(name, schema);
4110
+ const existing = state.views.findIndex((v) => functionIdFor(v.name, v.schema) === id);
4111
+ if (existing >= 0) state.views[existing] = next;
4112
+ else state.views.push(next);
4113
+ }
4114
+ const ctas = stmt.CreateTableAsStmt;
4115
+ if (ctas && ctas.objtype === "OBJECT_MATVIEW") {
4116
+ const name = ctas.into?.rel?.relname ?? "";
4117
+ if (!name) continue;
4118
+ const schema = ctas.into?.rel?.schemaname ?? null;
4119
+ const next = {
4120
+ name,
4121
+ schema,
4122
+ isMaterialized: true,
4123
+ withCheckOption: "N/A",
4124
+ filepath
4125
+ };
4126
+ const id = functionIdFor(name, schema);
4127
+ const existing = state.views.findIndex((v) => functionIdFor(v.name, v.schema) === id);
4128
+ if (existing >= 0) state.views[existing] = next;
4129
+ else state.views.push(next);
4130
+ }
4131
+ }
4132
+ }
4133
+ function applyDropsForSchemaObjects(stmts, state) {
4134
+ for (const wrap of stmts) {
4135
+ const drop = wrap.stmt?.DropStmt;
4136
+ if (!drop) continue;
4137
+ const removeType = drop.removeType ?? "";
4138
+ const objects = drop.objects ?? [];
4139
+ if (removeType === "OBJECT_TABLE") {
4140
+ const droppedTables = /* @__PURE__ */ new Set();
4141
+ for (const obj of objects) {
4142
+ const items = obj.List?.items ?? [];
4143
+ const last = items[items.length - 1]?.String?.sval;
4144
+ if (last) droppedTables.add(last);
4145
+ }
4146
+ if (droppedTables.size > 0) {
4147
+ for (const t of droppedTables) state.tables.delete(t);
4148
+ state.fks = state.fks.filter((fk) => !droppedTables.has(fk.sourceTable) && !droppedTables.has(fk.targetTable));
4149
+ }
4150
+ } else if (removeType === "OBJECT_TYPE") {
4151
+ const droppedEnums = /* @__PURE__ */ new Set();
4152
+ for (const obj of objects) {
4153
+ const tn = obj.TypeName;
4154
+ if (!tn) continue;
4155
+ const names = (tn.names ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
4156
+ const last = names[names.length - 1];
4157
+ if (last) droppedEnums.add(last);
4158
+ }
4159
+ for (const e of droppedEnums) state.enums.delete(e);
4160
+ } else if (removeType === "OBJECT_EXTENSION") {
4161
+ const names = /* @__PURE__ */ new Set();
4162
+ for (const obj of objects) {
4163
+ const sval = obj.String?.sval;
4164
+ if (sval) names.add(sval);
4165
+ }
4166
+ if (names.size > 0) state.extensions = state.extensions.filter((e) => !names.has(e.name));
4167
+ } else if (removeType === "OBJECT_TRIGGER") {
4168
+ for (const obj of objects) {
4169
+ const items = obj.List?.items ?? [];
4170
+ if (items.length < 2) continue;
4171
+ const table = items[0]?.String?.sval ?? "";
4172
+ const trigName = items[items.length - 1]?.String?.sval ?? "";
4173
+ if (!table || !trigName) continue;
4174
+ state.triggers = state.triggers.filter((t) => !(t.table === table && t.name === trigName));
4175
+ }
4176
+ } else if (removeType === "OBJECT_FUNCTION" || removeType === "OBJECT_PROCEDURE") {
4177
+ for (const obj of objects) {
4178
+ const items = obj.ObjectWithArgs?.objname?.items ?? obj.ObjectWithArgs?.objname ?? obj.List?.items ?? [];
4179
+ if (!items.length) continue;
4180
+ const segs = items.map((s) => s.String?.sval ?? "").filter(Boolean);
4181
+ if (!segs.length) continue;
4182
+ const name = segs[segs.length - 1];
4183
+ const schema = segs.length > 1 ? segs[segs.length - 2] : null;
4184
+ const id = functionIdFor(name, schema);
4185
+ state.functions = state.functions.filter((f) => functionIdFor(f.name, f.schema) !== id);
4186
+ }
4187
+ } else if (removeType === "OBJECT_VIEW" || removeType === "OBJECT_MATVIEW") {
4188
+ for (const obj of objects) {
4189
+ const items = obj.List?.items ?? [];
4190
+ if (!items.length) continue;
4191
+ const name = items[items.length - 1]?.String?.sval ?? "";
4192
+ const schema = items.length > 1 ? items[items.length - 2]?.String?.sval ?? null : null;
4193
+ if (!name) continue;
4194
+ const id = functionIdFor(name, schema);
4195
+ state.views = state.views.filter((v) => functionIdFor(v.name, v.schema) !== id);
4196
+ }
4197
+ }
4198
+ }
4199
+ }
4200
+ function indexIsPrismaUncoverable(idx) {
4201
+ return idx.hasPredicate || idx.hasExpressions || idx.method !== "btree";
4202
+ }
3757
4203
  function loadPrismaState(schemaPath) {
3758
4204
  if (!schemaPath || !(0, import_node_fs14.existsSync)(schemaPath)) return null;
3759
4205
  const content = (0, import_node_fs14.readFileSync)(schemaPath, "utf-8");
@@ -3920,6 +4366,96 @@ function verify(sqlState, prisma) {
3920
4366
  }
3921
4367
  return { contradictions, flaggedEdges };
3922
4368
  }
4369
+ function deriveMigrationName(sqlPath) {
4370
+ const segments = sqlPath.split(/[\\/]/);
4371
+ const last = segments[segments.length - 1];
4372
+ if (last === "migration.sql" && segments.length >= 2) {
4373
+ return segments[segments.length - 2];
4374
+ }
4375
+ return last.replace(/\.sql$/, "");
4376
+ }
4377
+ function extractMigrationInfoFromStmts(stmts, name, filepath) {
4378
+ let isDestructive = false;
4379
+ let hasOrphanCheck = false;
4380
+ let hasSidecarBackup = false;
4381
+ let hasPreFlightNotice = false;
4382
+ let containsBackfill = false;
4383
+ let containsDropColumn = false;
4384
+ let containsDropTable = false;
4385
+ for (const wrap of stmts) {
4386
+ const stmt = wrap.stmt ?? {};
4387
+ const kind = Object.keys(stmt)[0];
4388
+ if (!kind) continue;
4389
+ const body = stmt[kind] ?? {};
4390
+ switch (kind) {
4391
+ case "AlterTableStmt": {
4392
+ const cmds = body.cmds ?? [];
4393
+ for (const c of cmds) {
4394
+ const subtype = c.AlterTableCmd?.subtype;
4395
+ if (subtype === "AT_DropColumn") {
4396
+ containsDropColumn = true;
4397
+ isDestructive = true;
4398
+ } else if (subtype === "AT_AlterColumnType" || subtype === "AT_DropNotNull" || subtype === "AT_DropConstraint") {
4399
+ isDestructive = true;
4400
+ }
4401
+ }
4402
+ break;
4403
+ }
4404
+ case "DropStmt": {
4405
+ const removeType = body.removeType ?? "";
4406
+ if (removeType === "OBJECT_TABLE") {
4407
+ containsDropTable = true;
4408
+ isDestructive = true;
4409
+ } else if (removeType === "OBJECT_TYPE" || removeType === "OBJECT_COLUMN" || removeType === "OBJECT_INDEX" || removeType === "OBJECT_POLICY") {
4410
+ isDestructive = true;
4411
+ }
4412
+ break;
4413
+ }
4414
+ case "CreateStmt": {
4415
+ const relname = body.relation?.relname ?? "";
4416
+ if (relname.startsWith("_backup_")) hasSidecarBackup = true;
4417
+ break;
4418
+ }
4419
+ case "CreateTableAsStmt": {
4420
+ const relname = body.into?.rel?.relname ?? "";
4421
+ if (relname.startsWith("_backup_")) hasSidecarBackup = true;
4422
+ break;
4423
+ }
4424
+ case "UpdateStmt":
4425
+ case "InsertStmt":
4426
+ case "DeleteStmt": {
4427
+ containsBackfill = true;
4428
+ break;
4429
+ }
4430
+ case "DoStmt": {
4431
+ const args = body.args ?? [];
4432
+ for (const arg of args) {
4433
+ const def = arg.DefElem;
4434
+ if (!def || def.defname !== "as") continue;
4435
+ const code = def.arg?.String?.sval ?? "";
4436
+ if (/\bRAISE\s+EXCEPTION\b/i.test(code)) hasOrphanCheck = true;
4437
+ if (/\bRAISE\s+NOTICE\b/i.test(code)) hasPreFlightNotice = true;
4438
+ }
4439
+ break;
4440
+ }
4441
+ }
4442
+ }
4443
+ const tsMatch = name.match(/^(\d{8,14})/);
4444
+ const timestamp = tsMatch ? tsMatch[1] : null;
4445
+ return {
4446
+ name,
4447
+ filepath,
4448
+ timestamp,
4449
+ isDestructive,
4450
+ hasOrphanCheck,
4451
+ hasSidecarBackup,
4452
+ hasPreFlightNotice,
4453
+ containsBackfill,
4454
+ containsDropColumn,
4455
+ containsDropTable,
4456
+ statementCount: stmts.length
4457
+ };
4458
+ }
3923
4459
  function migrationsDirFor(rootDir) {
3924
4460
  const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
3925
4461
  if (!paths) return null;
@@ -3974,6 +4510,132 @@ function generate3(rootDir) {
3974
4510
  values: [...sqlEnum.values]
3975
4511
  });
3976
4512
  }
4513
+ let indexNodeCount = 0;
4514
+ for (const idx of sqlState.indexes) {
4515
+ if (!indexIsPrismaUncoverable(idx)) continue;
4516
+ nodes.push({
4517
+ id: `index:${idx.name}`,
4518
+ type: "index",
4519
+ name: idx.name,
4520
+ source: "sql",
4521
+ table: idx.table,
4522
+ unique: idx.unique,
4523
+ method: idx.method,
4524
+ columns: idx.columns,
4525
+ has_expressions: idx.hasExpressions,
4526
+ has_predicate: idx.hasPredicate,
4527
+ filepath: idx.filepath
4528
+ });
4529
+ indexNodeCount++;
4530
+ }
4531
+ let extensionNodeCount = 0;
4532
+ for (const ext of sqlState.extensions) {
4533
+ nodes.push({
4534
+ id: `extension:${ext.name}`,
4535
+ type: "extension",
4536
+ name: ext.name,
4537
+ source: "sql",
4538
+ schema: ext.schema,
4539
+ version: ext.version,
4540
+ filepath: ext.filepath
4541
+ });
4542
+ extensionNodeCount++;
4543
+ }
4544
+ let triggerNodeCount = 0;
4545
+ for (const trg of sqlState.triggers) {
4546
+ nodes.push({
4547
+ id: `trigger:${trg.table}:${trg.name}`,
4548
+ type: "trigger",
4549
+ name: trg.name,
4550
+ source: "sql",
4551
+ table: trg.table,
4552
+ timing: trg.timing,
4553
+ events: trg.events,
4554
+ function: trg.function,
4555
+ has_when: trg.hasWhen,
4556
+ for_each: trg.forEach,
4557
+ filepath: trg.filepath
4558
+ });
4559
+ triggerNodeCount++;
4560
+ }
4561
+ let functionNodeCount = 0;
4562
+ for (const fn of sqlState.functions) {
4563
+ const qualified = fn.schema ? `${fn.schema}.${fn.name}` : fn.name;
4564
+ nodes.push({
4565
+ id: `function:${qualified}`,
4566
+ type: "function",
4567
+ name: fn.name,
4568
+ source: "sql",
4569
+ schema: fn.schema,
4570
+ language: fn.language,
4571
+ return_type: fn.returnType,
4572
+ is_procedure: fn.isProcedure,
4573
+ filepath: fn.filepath
4574
+ });
4575
+ functionNodeCount++;
4576
+ }
4577
+ let viewNodeCount = 0;
4578
+ for (const vw of sqlState.views) {
4579
+ const qualified = vw.schema ? `${vw.schema}.${vw.name}` : vw.name;
4580
+ nodes.push({
4581
+ id: `${vw.isMaterialized ? "matview" : "view"}:${qualified}`,
4582
+ type: vw.isMaterialized ? "materialized_view" : "view",
4583
+ name: vw.name,
4584
+ source: "sql",
4585
+ schema: vw.schema,
4586
+ is_materialized: vw.isMaterialized,
4587
+ with_check_option: vw.withCheckOption,
4588
+ filepath: vw.filepath
4589
+ });
4590
+ viewNodeCount++;
4591
+ }
4592
+ let policyNodeCount = 0;
4593
+ for (const pol of sqlState.policies) {
4594
+ nodes.push({
4595
+ id: `policy:${pol.table}:${pol.name}`,
4596
+ type: "policy",
4597
+ name: pol.name,
4598
+ source: "sql",
4599
+ table: pol.table,
4600
+ command: pol.command,
4601
+ permissive: pol.permissive,
4602
+ roles: pol.roles,
4603
+ has_using: pol.hasUsing,
4604
+ has_with_check: pol.hasWithCheck,
4605
+ filepath: pol.filepath
4606
+ });
4607
+ policyNodeCount++;
4608
+ }
4609
+ const migrationFiles = migrationsDir ? discoverMigrationFiles(migrationsDir) : [];
4610
+ let migrationNodeCount = 0;
4611
+ for (const sqlPath of migrationFiles) {
4612
+ const sql = (0, import_node_fs14.readFileSync)(sqlPath, "utf-8");
4613
+ const name = deriveMigrationName(sqlPath);
4614
+ let ast;
4615
+ try {
4616
+ ast = postgresDialect.parse(sql);
4617
+ } catch {
4618
+ ast = { stmts: [] };
4619
+ }
4620
+ const info = postgresDialect.extractMigrationInfo(ast, name, sqlPath);
4621
+ nodes.push({
4622
+ id: `migration:${name}`,
4623
+ type: "migration",
4624
+ name,
4625
+ source: "sql",
4626
+ filepath: info.filepath,
4627
+ timestamp: info.timestamp,
4628
+ is_destructive: info.isDestructive,
4629
+ has_orphan_check: info.hasOrphanCheck,
4630
+ has_sidecar_backup: info.hasSidecarBackup,
4631
+ has_pre_flight_notice: info.hasPreFlightNotice,
4632
+ contains_backfill: info.containsBackfill,
4633
+ contains_drop_column: info.containsDropColumn,
4634
+ contains_drop_table: info.containsDropTable,
4635
+ statement_count: info.statementCount
4636
+ });
4637
+ migrationNodeCount++;
4638
+ }
3977
4639
  const sqlOnlyTables = new Set(nodes.filter((n) => n.type === "table").map((n) => n.id));
3978
4640
  const edges = sqlState.fks.filter((fk) => sqlOnlyTables.has(fk.sourceTable)).map((fk) => ({
3979
4641
  source: fk.sourceTable,
@@ -3992,6 +4654,13 @@ function generate3(rootDir) {
3992
4654
  sql_tables: sqlState.tables.size,
3993
4655
  sql_enums: sqlState.enums.size,
3994
4656
  sql_fks: sqlState.fks.length,
4657
+ sql_index_nodes: indexNodeCount,
4658
+ sql_policy_nodes: policyNodeCount,
4659
+ sql_extension_nodes: extensionNodeCount,
4660
+ sql_trigger_nodes: triggerNodeCount,
4661
+ sql_function_nodes: functionNodeCount,
4662
+ sql_view_nodes: viewNodeCount,
4663
+ sql_migration_nodes: migrationNodeCount,
3995
4664
  additive_nodes: nodes.length,
3996
4665
  contradictions_found: contradictions.length,
3997
4666
  flagged_edges_found: flaggedEdges.length