@rryando/arcs 4.2.0 → 4.2.1

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 (185) hide show
  1. package/README.md +2 -2
  2. package/dist/cli/arcs-flash.d.ts +1 -1
  3. package/dist/cli/arcs-flash.d.ts.map +1 -1
  4. package/dist/cli/arcs-flash.js +3 -5
  5. package/dist/cli/arcs-flash.js.map +1 -1
  6. package/dist/cli/arcs-orchestrate.d.ts +1 -1
  7. package/dist/cli/arcs-orchestrate.d.ts.map +1 -1
  8. package/dist/cli/commands/index.d.ts +0 -1
  9. package/dist/cli/commands/index.d.ts.map +1 -1
  10. package/dist/cli/commands/index.js +0 -1
  11. package/dist/cli/commands/index.js.map +1 -1
  12. package/dist/cli/commands/project.js +1 -30
  13. package/dist/cli/commands/project.js.map +1 -1
  14. package/dist/cli/commands/proposal-doc.d.ts +2 -0
  15. package/dist/cli/commands/proposal-doc.d.ts.map +1 -0
  16. package/dist/cli/commands/proposal-doc.js +381 -0
  17. package/dist/cli/commands/proposal-doc.js.map +1 -0
  18. package/dist/cli/commands/web.js +4 -10
  19. package/dist/cli/commands/web.js.map +1 -1
  20. package/dist/cli/orchestrator-shared-blocks.d.ts +11 -10
  21. package/dist/cli/orchestrator-shared-blocks.d.ts.map +1 -1
  22. package/dist/cli/orchestrator-shared-blocks.js +21 -16
  23. package/dist/cli/orchestrator-shared-blocks.js.map +1 -1
  24. package/dist/utils/graphify-knowledge.d.ts +22 -0
  25. package/dist/utils/graphify-knowledge.d.ts.map +1 -0
  26. package/dist/utils/graphify-knowledge.js +47 -0
  27. package/dist/utils/graphify-knowledge.js.map +1 -0
  28. package/dist/utils/graphify.d.ts +104 -0
  29. package/dist/utils/graphify.d.ts.map +1 -0
  30. package/dist/utils/graphify.js +439 -0
  31. package/dist/utils/graphify.js.map +1 -0
  32. package/dist/utils/session-store.d.ts +24 -2
  33. package/dist/utils/session-store.d.ts.map +1 -1
  34. package/dist/utils/session-store.js +16 -7
  35. package/dist/utils/session-store.js.map +1 -1
  36. package/dist/utils/storage-utils.d.ts +1 -1
  37. package/dist/utils/storage-utils.d.ts.map +1 -1
  38. package/dist/utils/storage-utils.js +1 -1
  39. package/dist/utils/storage-utils.js.map +1 -1
  40. package/dist/web-client/assets/{GraphCanvas-BPDgvsyT.js → GraphCanvas-Dw6EcoDb.js} +1 -1
  41. package/dist/web-client/assets/{MarkdownEditor-D7TLp78z.js → MarkdownEditor-Cz5_44Ej.js} +1 -1
  42. package/dist/web-client/assets/{abnfDiagram-VRR7QNED-CyuP2N9t.js → abnfDiagram-VRR7QNED-CFJzLuew.js} +1 -1
  43. package/dist/web-client/assets/architecture-TIHT7OUA-CoHvhex9.js +1 -0
  44. package/dist/web-client/assets/{architectureDiagram-ZJ3FMSHR-DZ0ul9QX.js → architectureDiagram-ZJ3FMSHR-FRlSgnnW.js} +1 -1
  45. package/dist/web-client/assets/{blockDiagram-677ZJIJ3-LLGzlc9l.js → blockDiagram-677ZJIJ3-WUkkunPZ.js} +1 -1
  46. package/dist/web-client/assets/{c4Diagram-LMCZKHZV-CViu3CTc.js → c4Diagram-LMCZKHZV-BKeAsL6F.js} +1 -1
  47. package/dist/web-client/assets/channel-D8xMXC5_.js +1 -0
  48. package/dist/web-client/assets/{chunk-32BRIVSS-Bw_IuJCM.js → chunk-32BRIVSS-B0b9kUcF.js} +1 -1
  49. package/dist/web-client/assets/{chunk-52WLFC77-C29h440W.js → chunk-52WLFC77-i6Y-vfL3.js} +1 -1
  50. package/dist/web-client/assets/{chunk-C7G6YPKG-hhOrvw5w.js → chunk-C7G6YPKG-atYWm6iP.js} +1 -1
  51. package/dist/web-client/assets/{chunk-EX3LRPZG-COMzol-M.js → chunk-EX3LRPZG-CZD6y0UU.js} +1 -1
  52. package/dist/web-client/assets/{chunk-FWX5IMBZ-6vdX9EUn.js → chunk-FWX5IMBZ-CVErR-UZ.js} +2 -2
  53. package/dist/web-client/assets/{chunk-HOUHSVGY-DWDW6sxp.js → chunk-HOUHSVGY-BlHO2iQ3.js} +1 -1
  54. package/dist/web-client/assets/{chunk-ICXQ74PX-BdMYglo2.js → chunk-ICXQ74PX-Ar8kfXfa.js} +1 -1
  55. package/dist/web-client/assets/{chunk-MOJQB5TN-C0LAX_dC.js → chunk-MOJQB5TN-DKrK867P.js} +1 -1
  56. package/dist/web-client/assets/{chunk-OGEWGWER-CBx8MB7f.js → chunk-OGEWGWER-BmGykUeg.js} +1 -1
  57. package/dist/web-client/assets/{chunk-PUDLZKDR-DKssR1nf.js → chunk-PUDLZKDR-Bq23pnso.js} +1 -1
  58. package/dist/web-client/assets/{chunk-Q4XR5HBZ-B3kcxFE-.js → chunk-Q4XR5HBZ-g15qvFAN.js} +1 -1
  59. package/dist/web-client/assets/{chunk-V7JOEXUC-CAlymndy.js → chunk-V7JOEXUC-uyXA7S9r.js} +1 -1
  60. package/dist/web-client/assets/{chunk-VAUOI2AC-BowfsmTW.js → chunk-VAUOI2AC-WofZ-2M0.js} +1 -1
  61. package/dist/web-client/assets/{chunk-VR4S4FIN-BBOydgvt.js → chunk-VR4S4FIN-DtTkK86v.js} +1 -1
  62. package/dist/web-client/assets/{chunk-WYO6CB5R-DcymFbES.js → chunk-WYO6CB5R-zVyUwJq3.js} +1 -1
  63. package/dist/web-client/assets/{chunk-ZGVPDNZ5--uKFP-Lr.js → chunk-ZGVPDNZ5-CA1Oe3TK.js} +1 -1
  64. package/dist/web-client/assets/classDiagram-OUVF2IWQ-Doj1_hvZ.js +1 -0
  65. package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-Doj1_hvZ.js +1 -0
  66. package/dist/web-client/assets/{cynefin-VYW2F7L2-CjboUOMA.js → cynefin-VYW2F7L2-ivJY1h_9.js} +1 -1
  67. package/dist/web-client/assets/{cynefinDiagram-TSTJHNR4-BcxygBP7.js → cynefinDiagram-TSTJHNR4-D2DstShq.js} +1 -1
  68. package/dist/web-client/assets/{dagre-VKFMJZFB-D-tiERQE.js → dagre-VKFMJZFB-CwnMRy0K.js} +1 -1
  69. package/dist/web-client/assets/{diagram-FQU43EPY-ChPXczaS.js → diagram-FQU43EPY-BKJv6Cvw.js} +1 -1
  70. package/dist/web-client/assets/{diagram-G47NLZAW-CVL3Y91h.js → diagram-G47NLZAW-CwCXcgU5.js} +1 -1
  71. package/dist/web-client/assets/{diagram-NH7WQ7WH-DsaNA9Lh.js → diagram-NH7WQ7WH-CkghU1-6.js} +1 -1
  72. package/dist/web-client/assets/{diagram-OA4YK3LP-CXhrhdhU.js → diagram-OA4YK3LP-D3siQIGu.js} +1 -1
  73. package/dist/web-client/assets/{diagram-WEI45ONY-BTVPnk4E.js → diagram-WEI45ONY-CSs9xTBn.js} +1 -1
  74. package/dist/web-client/assets/{ebnfDiagram-CCIWWBDH-BAyrRBtM.js → ebnfDiagram-CCIWWBDH--i52vMiv.js} +1 -1
  75. package/dist/web-client/assets/{erDiagram-Q63AITRT-Qm24Wepm.js → erDiagram-Q63AITRT-q2hgOBY1.js} +1 -1
  76. package/dist/web-client/assets/eventmodeling-45OFAUF4-ESVuFkJJ.js +1 -0
  77. package/dist/web-client/assets/flowDiagram-23GEKE2U-DN9SdR9f.js +1 -0
  78. package/dist/web-client/assets/{ganttDiagram-NO4QXBWP-D8h7l3XJ.js → ganttDiagram-NO4QXBWP-BZ2rBbTe.js} +1 -1
  79. package/dist/web-client/assets/{gitGraph-TEB2WS4Q-DIBml1SB.js → gitGraph-TEB2WS4Q-OnJ8tHgt.js} +1 -1
  80. package/dist/web-client/assets/{gitGraphDiagram-IHSO6WYX-CtkYoXjn.js → gitGraphDiagram-IHSO6WYX-CPNExFAr.js} +1 -1
  81. package/dist/web-client/assets/{index-DOSH4Q9H.js → index-DCBn-YrR.js} +38 -38
  82. package/dist/web-client/assets/{info-DKCQHKI2-DLEUtV5Q.js → info-DKCQHKI2-DGuJbmdY.js} +1 -1
  83. package/dist/web-client/assets/{infoDiagram-FWYZ7A6U-BJQ7aQux.js → infoDiagram-FWYZ7A6U-ADIAn-P5.js} +1 -1
  84. package/dist/web-client/assets/{ishikawaDiagram-FXEZZL3T-BPM11FvG.js → ishikawaDiagram-FXEZZL3T-CUx-RGfg.js} +1 -1
  85. package/dist/web-client/assets/{journeyDiagram-5HDEW3XC-C0aX2z3c.js → journeyDiagram-5HDEW3XC-BH7-tBBy.js} +1 -1
  86. package/dist/web-client/assets/{kanban-definition-HUTT4EX6-C56F29Ib.js → kanban-definition-HUTT4EX6-BGEXBnI2.js} +1 -1
  87. package/dist/web-client/assets/{line-BLFHLF2N.js → line-CC-5ezU8.js} +1 -1
  88. package/dist/web-client/assets/{mermaid-parser.core-BLC8FhgU.js → mermaid-parser.core-Dw18Fjbq.js} +3 -3
  89. package/dist/web-client/assets/{mermaid.core-BBqkKuXt.js → mermaid.core-CMQBgE43.js} +3 -3
  90. package/dist/web-client/assets/{mindmap-definition-LN4V7U3C-aVZbsoPc.js → mindmap-definition-LN4V7U3C-CGtjw8tB.js} +1 -1
  91. package/dist/web-client/assets/{packet-7NZHBO7P-D4aqSQfB.js → packet-7NZHBO7P-w71Y4Hzd.js} +1 -1
  92. package/dist/web-client/assets/{pegDiagram-2B236MQR-DjfyNI0U.js → pegDiagram-2B236MQR-DWtfEm4T.js} +1 -1
  93. package/dist/web-client/assets/{pie-RZYD4A2V-ChCwYsYj.js → pie-RZYD4A2V-S9ztgnWs.js} +1 -1
  94. package/dist/web-client/assets/{pieDiagram-ENE6RG2P-BeHLKkXC.js → pieDiagram-ENE6RG2P-BWZQPN4m.js} +1 -1
  95. package/dist/web-client/assets/{quadrantDiagram-ABIIQ3AL-stga3gvq.js → quadrantDiagram-ABIIQ3AL-DINDwblH.js} +1 -1
  96. package/dist/web-client/assets/{radar-I7S5WNFK-DOGheiwT.js → radar-I7S5WNFK-BOGl9krB.js} +1 -1
  97. package/dist/web-client/assets/{railroad-3IZDKUUU-_JnU7M6L.js → railroad-3IZDKUUU-CR9kuYSZ.js} +1 -1
  98. package/dist/web-client/assets/railroad-abnf-AHOZXSZD-BvbCHrlR.js +1 -0
  99. package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-D869lbCL.js +1 -0
  100. package/dist/web-client/assets/railroad-peg-LSFZ7HO6-r4TXaJPI.js +1 -0
  101. package/dist/web-client/assets/{railroadDiagram-RFXS5EU6-C0CkMsOd.js → railroadDiagram-RFXS5EU6-byLCs9hp.js} +1 -1
  102. package/dist/web-client/assets/{requirementDiagram-TGXJPOKE-DuImwoRD.js → requirementDiagram-TGXJPOKE-Dn_FtbqW.js} +1 -1
  103. package/dist/web-client/assets/{sankeyDiagram-HTMAVEWB-kprq0XF9.js → sankeyDiagram-HTMAVEWB-DUjRrCeC.js} +1 -1
  104. package/dist/web-client/assets/{sequenceDiagram-DBY2YBRQ-DiXKJMF6.js → sequenceDiagram-DBY2YBRQ-BmBz8Wpq.js} +1 -1
  105. package/dist/web-client/assets/{stateDiagram-2N3HPSRC-D5qbVStE.js → stateDiagram-2N3HPSRC-BAYHjmqB.js} +1 -1
  106. package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-Bl-1K1zV.js +1 -0
  107. package/dist/web-client/assets/{swimlanes-5IMT3BWC-DCbw389c.js → swimlanes-5IMT3BWC-Bm942AR-.js} +1 -1
  108. package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-DHU7bsfA.js +8 -0
  109. package/dist/web-client/assets/{timeline-definition-FHXFAJF6-CQeaYN_9.js → timeline-definition-FHXFAJF6-CHAZHhQk.js} +1 -1
  110. package/dist/web-client/assets/{treeView-QDETBFTQ-Cf7Sq3qo.js → treeView-QDETBFTQ-DHHkLsSy.js} +1 -1
  111. package/dist/web-client/assets/{treemap-6X3UGDF4-BovzvoTU.js → treemap-6X3UGDF4-BUxZ8fhY.js} +1 -1
  112. package/dist/web-client/assets/{vennDiagram-L72KCM5P-CZsJy139.js → vennDiagram-L72KCM5P-BL9TRcUU.js} +1 -1
  113. package/dist/web-client/assets/{wardley-OPB4EBWU-DJ7MS6XZ.js → wardley-OPB4EBWU-CfJ5mO-y.js} +1 -1
  114. package/dist/web-client/assets/{wardleyDiagram-EHGQE667-rqhcmsbM.js → wardleyDiagram-EHGQE667-BlH1TSjy.js} +1 -1
  115. package/dist/web-client/assets/{xychartDiagram-FW5EYKEG-HuK4Seps.js → xychartDiagram-FW5EYKEG-BJN6wtrV.js} +1 -1
  116. package/dist/web-client/index.html +1 -1
  117. package/dist/web-server/app.d.ts.map +1 -1
  118. package/dist/web-server/app.js +1 -7
  119. package/dist/web-server/app.js.map +1 -1
  120. package/dist/web-server/claude-runner.d.ts +11 -4
  121. package/dist/web-server/claude-runner.d.ts.map +1 -1
  122. package/dist/web-server/claude-runner.js +10 -14
  123. package/dist/web-server/claude-runner.js.map +1 -1
  124. package/dist/web-server/index.d.ts.map +1 -1
  125. package/dist/web-server/index.js +4 -1
  126. package/dist/web-server/index.js.map +1 -1
  127. package/dist/web-server/opencode-client.d.ts +123 -0
  128. package/dist/web-server/opencode-client.d.ts.map +1 -0
  129. package/dist/web-server/opencode-client.js +514 -0
  130. package/dist/web-server/opencode-client.js.map +1 -0
  131. package/dist/web-server/prompt-assembly.d.ts.map +1 -1
  132. package/dist/web-server/prompt-assembly.js +1 -2
  133. package/dist/web-server/prompt-assembly.js.map +1 -1
  134. package/dist/web-server/routes/sessions.d.ts +9 -6
  135. package/dist/web-server/routes/sessions.d.ts.map +1 -1
  136. package/dist/web-server/routes/sessions.js +272 -205
  137. package/dist/web-server/routes/sessions.js.map +1 -1
  138. package/dist/web-server/run-driver.d.ts +113 -0
  139. package/dist/web-server/run-driver.d.ts.map +1 -0
  140. package/dist/web-server/run-driver.js +214 -0
  141. package/dist/web-server/run-driver.js.map +1 -0
  142. package/dist/web-server/run-event-log.d.ts +23 -1
  143. package/dist/web-server/run-event-log.d.ts.map +1 -1
  144. package/dist/web-server/run-event-log.js +29 -5
  145. package/dist/web-server/run-event-log.js.map +1 -1
  146. package/dist/web-server/web-auth.d.ts +3 -5
  147. package/dist/web-server/web-auth.d.ts.map +1 -1
  148. package/dist/web-server/web-auth.js +6 -11
  149. package/dist/web-server/web-auth.js.map +1 -1
  150. package/dist/web-server/web-token.d.ts +1 -2
  151. package/dist/web-server/web-token.d.ts.map +1 -1
  152. package/dist/web-server/web-token.js +1 -2
  153. package/dist/web-server/web-token.js.map +1 -1
  154. package/opencode/arcs/bundle-runtime.json +0 -3
  155. package/opencode/arcs/prompts/arcs-docs.txt +4 -4
  156. package/opencode/arcs/prompts/arcs-flash.txt +15 -21
  157. package/opencode/arcs/prompts/arcs-orchestrate-caveman.txt +17 -15
  158. package/opencode/arcs/prompts/arcs-orchestrate.txt +17 -15
  159. package/opencode/arcs/prompts/code-reviewer.txt +4 -4
  160. package/opencode/arcs/prompts/graph-explorer.txt +4 -4
  161. package/opencode/arcs/prompts/software-engineer.txt +2 -2
  162. package/opencode/arcs/prompts/tech-architect.txt +4 -4
  163. package/opencode/arcs/skills/brainstorming/SKILL.md +4 -4
  164. package/opencode/arcs/skills/enriching-codegraph-proposals/SKILL.md +1 -1
  165. package/opencode/arcs/skills/implementation/SKILL.md +6 -6
  166. package/opencode/arcs/skills/init-project/SKILL.md +4 -4
  167. package/opencode/arcs/skills/systematic-debugging/SKILL.md +2 -2
  168. package/opencode/arcs/skills/test-driven-development/SKILL.md +3 -3
  169. package/opencode/arcs/skills/to-diagram/SKILL.md +2 -2
  170. package/opencode/arcs/skills/writing-knowledge/SKILL.md +2 -2
  171. package/opencode/arcs/skills/writing-plans/SKILL.md +2 -2
  172. package/package.json +1 -1
  173. package/dist/web-client/assets/architecture-TIHT7OUA-Bdo2Yvm9.js +0 -1
  174. package/dist/web-client/assets/channel-DBNmizpo.js +0 -1
  175. package/dist/web-client/assets/classDiagram-OUVF2IWQ-CB3HiA1_.js +0 -1
  176. package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-CB3HiA1_.js +0 -1
  177. package/dist/web-client/assets/eventmodeling-45OFAUF4-DoTBIvl5.js +0 -1
  178. package/dist/web-client/assets/flowDiagram-23GEKE2U-BEH23L1A.js +0 -1
  179. package/dist/web-client/assets/railroad-abnf-AHOZXSZD-nhNub7LE.js +0 -1
  180. package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-BlQYe7Yf.js +0 -1
  181. package/dist/web-client/assets/railroad-peg-LSFZ7HO6-B3E8pRVN.js +0 -1
  182. package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-DWwTAG1r.js +0 -1
  183. package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-DabrCsjZ.js +0 -8
  184. package/opencode/arcs/skills/install-claude-code-hook/SKILL.md +0 -23
  185. package/scripts/claude-code-session-hook.mjs +0 -146
@@ -0,0 +1,439 @@
1
+ import { execSync, spawnSync } from "node:child_process";
2
+ import { appendFileSync, existsSync, readFileSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ export function detectGraphify() {
5
+ try {
6
+ const version = execSync("graphify --version", {
7
+ encoding: "utf-8",
8
+ stdio: ["pipe", "pipe", "pipe"],
9
+ timeout: 5000,
10
+ }).trim();
11
+ const resolvedPath = execSync("which graphify", {
12
+ encoding: "utf-8",
13
+ stdio: ["pipe", "pipe", "pipe"],
14
+ timeout: 5000,
15
+ }).trim();
16
+ // Extract semver from output (e.g. "graphify 0.8.18" or just "0.8.18")
17
+ const match = version.match(/(\d+\.\d+\.\d+)/);
18
+ return {
19
+ available: true,
20
+ version: match ? match[1] : version,
21
+ path: resolvedPath || undefined,
22
+ };
23
+ }
24
+ catch {
25
+ return { available: false };
26
+ }
27
+ }
28
+ function parseGraphJson(graphPath) {
29
+ try {
30
+ const raw = readFileSync(graphPath, "utf-8");
31
+ const data = JSON.parse(raw);
32
+ if (!Array.isArray(data?.nodes) || data.nodes.length === 0)
33
+ return null;
34
+ // Normalize links (graphify uses "links" key; older format used "edges")
35
+ const links = data.links || data.edges || [];
36
+ // Compute degree (total) plus directional in/out per node
37
+ const degreeMap = new Map();
38
+ const inMap = new Map();
39
+ const outMap = new Map();
40
+ for (const link of links) {
41
+ degreeMap.set(link.source, (degreeMap.get(link.source) || 0) + 1);
42
+ degreeMap.set(link.target, (degreeMap.get(link.target) || 0) + 1);
43
+ outMap.set(link.source, (outMap.get(link.source) || 0) + 1);
44
+ inMap.set(link.target, (inMap.get(link.target) || 0) + 1);
45
+ }
46
+ // Normalize nodes
47
+ const nodes = data.nodes.map((n) => ({
48
+ id: n.id,
49
+ label: n.label,
50
+ type: n.type || n.file_type || "unknown",
51
+ fileType: n.file_type || n.type || "unknown",
52
+ file: n.file || n.source_file || "",
53
+ community: n.community ?? -1,
54
+ degree: n.degree ?? degreeMap.get(n.id) ?? 0,
55
+ inDegree: inMap.get(n.id) ?? 0,
56
+ outDegree: outMap.get(n.id) ?? 0,
57
+ }));
58
+ // Use communities if available; otherwise synthesize from source_file grouping
59
+ const communities = data.communities || [];
60
+ if (communities.length === 0) {
61
+ // Group nodes by directory prefix as pseudo-communities
62
+ const dirGroups = new Map();
63
+ for (const node of nodes) {
64
+ if (!node.file)
65
+ continue;
66
+ const dir = node.file.split("/").slice(0, -1).join("/") || ".";
67
+ const list = dirGroups.get(dir) || [];
68
+ list.push(node.id);
69
+ dirGroups.set(dir, list);
70
+ }
71
+ let communityId = 0;
72
+ for (const [dir, nodeIds] of dirGroups) {
73
+ if (nodeIds.length >= 3) {
74
+ communities.push({
75
+ id: communityId++,
76
+ label: dir,
77
+ nodes: nodeIds,
78
+ });
79
+ }
80
+ }
81
+ }
82
+ return { nodes, communities, links };
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ function percentile(values, p) {
89
+ const sorted = [...values].sort((a, b) => a - b);
90
+ const idx = (p / 100) * (sorted.length - 1);
91
+ const lower = Math.floor(idx);
92
+ const frac = idx - lower;
93
+ if (lower + 1 >= sorted.length)
94
+ return sorted[lower];
95
+ return sorted[lower] + frac * (sorted[lower + 1] - sorted[lower]);
96
+ }
97
+ export function ingestGraph(graphJsonPath, _slug) {
98
+ const empty = {
99
+ proposals: [],
100
+ stats: { godNodes: 0, communities: 0, crossModuleCouplings: 0, totalProposals: 0 },
101
+ };
102
+ const graph = parseGraphJson(graphJsonPath);
103
+ if (!graph || graph.nodes.length === 0)
104
+ return empty;
105
+ const proposals = [];
106
+ const nodeMap = new Map(graph.nodes.map((n) => [n.id, n]));
107
+ // God nodes (degree > 95th percentile — top 5% most connected)
108
+ // Exclude test files — they naturally import many modules but aren't architectural hubs
109
+ const isTestFile = (file) => /\.(test|spec)\.[jt]sx?$/.test(file) ||
110
+ file.startsWith("test/") ||
111
+ file.startsWith("tests/") ||
112
+ file.includes("/__tests__/");
113
+ const degrees = graph.nodes.map((n) => n.degree).filter((d) => d > 0);
114
+ const threshold = percentile(degrees, 95);
115
+ const godNodes = graph.nodes
116
+ .filter((n) => n.degree > threshold && n.file && !isTestFile(n.file))
117
+ .sort((a, b) => b.degree - a.degree)
118
+ .slice(0, 8); // cap god nodes at 8 to leave room for other kinds
119
+ for (const node of godNodes) {
120
+ // Top callers: nodes with edge → this node, ranked by their own degree.
121
+ const callerDegreeById = new Map();
122
+ const calleeDegreeById = new Map();
123
+ for (const link of graph.links) {
124
+ if (link.target === node.id && link.source !== node.id) {
125
+ const src = nodeMap.get(link.source);
126
+ if (src)
127
+ callerDegreeById.set(src.id, src.degree);
128
+ }
129
+ if (link.source === node.id && link.target !== node.id) {
130
+ const tgt = nodeMap.get(link.target);
131
+ if (tgt)
132
+ calleeDegreeById.set(tgt.id, tgt.degree);
133
+ }
134
+ }
135
+ const topCallers = [...callerDegreeById.entries()]
136
+ .sort((a, b) => b[1] - a[1])
137
+ .slice(0, 5)
138
+ .map(([id]) => {
139
+ const n = nodeMap.get(id);
140
+ return n ? { label: n.label, file: n.file } : null;
141
+ })
142
+ .filter((x) => x !== null);
143
+ const topCallees = [...calleeDegreeById.entries()]
144
+ .sort((a, b) => b[1] - a[1])
145
+ .slice(0, 5)
146
+ .map(([id]) => {
147
+ const n = nodeMap.get(id);
148
+ return n ? { label: n.label, file: n.file } : null;
149
+ })
150
+ .filter((x) => x !== null);
151
+ proposals.push({
152
+ id: makeProposalId("graphify-god", `${node.label}-${node.file}`),
153
+ kind: "module",
154
+ label: node.label,
155
+ structuralFacts: {
156
+ nodeFile: node.file,
157
+ nodeIn: node.inDegree,
158
+ nodeOut: node.outDegree,
159
+ topCallers,
160
+ topCallees,
161
+ },
162
+ sourceFiles: [{ path: node.file }],
163
+ });
164
+ }
165
+ // Community clusters (sorted by size desc, top 8). Drop document-only clusters.
166
+ const allCommunities = [...(graph.communities || [])].sort((a, b) => b.nodes.length - a.nodes.length);
167
+ // Build community-membership map for cross-cluster degree calculations.
168
+ const communityIdByNode = new Map();
169
+ for (const c of allCommunities) {
170
+ for (const nodeId of c.nodes)
171
+ communityIdByNode.set(nodeId, c.id);
172
+ }
173
+ const survivingCommunities = [];
174
+ for (const community of allCommunities) {
175
+ const members = community.nodes.map((id) => nodeMap.get(id)).filter((n) => !!n);
176
+ if (members.length === 0)
177
+ continue;
178
+ // Filtering rule: drop the cluster if EVERY member has file_type === "document".
179
+ const hasNonDocument = members.some((m) => m.fileType !== "document");
180
+ if (!hasNonDocument)
181
+ continue;
182
+ survivingCommunities.push(community);
183
+ if (survivingCommunities.length >= 8)
184
+ break;
185
+ }
186
+ for (const community of survivingCommunities) {
187
+ const members = community.nodes.map((id) => nodeMap.get(id)).filter((n) => !!n);
188
+ // memberCount, fileCount, fileTypeBreakdown
189
+ const memberCount = members.length;
190
+ const fileSet = new Set();
191
+ const fileTypeBreakdown = {};
192
+ const fileEntityCount = new Map();
193
+ for (const m of members) {
194
+ if (m.file)
195
+ fileSet.add(m.file);
196
+ const ft = m.fileType || "unknown";
197
+ fileTypeBreakdown[ft] = (fileTypeBreakdown[ft] || 0) + 1;
198
+ if (m.file) {
199
+ fileEntityCount.set(m.file, (fileEntityCount.get(m.file) || 0) + 1);
200
+ }
201
+ }
202
+ // topHubs: top 3 by in+out
203
+ const topHubs = [...members]
204
+ .sort((a, b) => b.inDegree + b.outDegree - (a.inDegree + a.outDegree))
205
+ .slice(0, 3)
206
+ .filter((m) => m.inDegree + m.outDegree > 0)
207
+ .map((m) => ({ label: m.label, file: m.file, in: m.inDegree, out: m.outDegree }));
208
+ // topFilesByEntityCount: top 3
209
+ const topFilesByEntityCount = [...fileEntityCount.entries()]
210
+ .sort((a, b) => b[1] - a[1])
211
+ .slice(0, 3)
212
+ .map(([file, count]) => ({ file, count }));
213
+ // Cross-cluster degree: count links where one endpoint is in this community
214
+ // and the other endpoint is in a DIFFERENT community.
215
+ const memberIds = new Set(community.nodes);
216
+ let incoming = 0;
217
+ let outgoing = 0;
218
+ for (const link of graph.links) {
219
+ const srcInCluster = memberIds.has(link.source);
220
+ const tgtInCluster = memberIds.has(link.target);
221
+ if (srcInCluster === tgtInCluster)
222
+ continue; // same-side or both-out → ignore
223
+ // Only count edges where the OTHER endpoint belongs to some community
224
+ // (otherwise it's not "another cluster", just stray nodes).
225
+ const otherId = srcInCluster ? link.target : link.source;
226
+ const otherCommunity = communityIdByNode.get(otherId);
227
+ if (otherCommunity === undefined || otherCommunity === community.id)
228
+ continue;
229
+ if (srcInCluster)
230
+ outgoing++;
231
+ else
232
+ incoming++;
233
+ }
234
+ const uniqueFiles = [...fileSet];
235
+ proposals.push({
236
+ id: makeProposalId("graphify-cluster", community.label),
237
+ kind: "architecture",
238
+ label: community.label,
239
+ structuralFacts: {
240
+ memberCount,
241
+ fileCount: uniqueFiles.length,
242
+ fileTypeBreakdown,
243
+ topHubs,
244
+ topFilesByEntityCount,
245
+ incomingFromOtherClusters: incoming,
246
+ outgoingToOtherClusters: outgoing,
247
+ },
248
+ sourceFiles: uniqueFiles.map((p) => ({ path: p })),
249
+ });
250
+ }
251
+ const couplingByKey = new Map();
252
+ for (const link of graph.links) {
253
+ const nodeA = nodeMap.get(link.source);
254
+ const nodeB = nodeMap.get(link.target);
255
+ if (!nodeA || !nodeB || !nodeA.file || !nodeB.file)
256
+ continue;
257
+ if (isTestFile(nodeA.file) || isTestFile(nodeB.file))
258
+ continue;
259
+ const dirA = nodeA.file.split("/").slice(0, 2).join("/");
260
+ const dirB = nodeB.file.split("/").slice(0, 2).join("/");
261
+ if (!dirA || !dirB || dirA === dirB)
262
+ continue;
263
+ if (nodeA.degree <= threshold && nodeB.degree <= threshold)
264
+ continue;
265
+ const [first, second] = nodeA.id < nodeB.id ? [nodeA, nodeB] : [nodeB, nodeA];
266
+ const key = `${first.id}|${second.id}`;
267
+ const existing = couplingByKey.get(key);
268
+ if (existing) {
269
+ if (link.relation)
270
+ existing.relations.add(link.relation);
271
+ }
272
+ else {
273
+ couplingByKey.set(key, {
274
+ a: first,
275
+ b: second,
276
+ relations: new Set(link.relation ? [link.relation] : []),
277
+ combinedDegree: first.degree + second.degree,
278
+ });
279
+ }
280
+ }
281
+ const couplings = [...couplingByKey.values()]
282
+ .sort((x, y) => y.combinedDegree - x.combinedDegree)
283
+ .slice(0, 5);
284
+ for (const { a, b, relations } of couplings) {
285
+ proposals.push({
286
+ id: makeProposalId("graphify-coupling", `${a.label}-${b.label}`),
287
+ kind: "gotcha",
288
+ label: `${a.label} ↔ ${b.label}`,
289
+ structuralFacts: {
290
+ couplingA: { label: a.label, file: a.file, degree: a.degree },
291
+ couplingB: { label: b.label, file: b.file, degree: b.degree },
292
+ relations: [...relations],
293
+ },
294
+ sourceFiles: [{ path: a.file }, { path: b.file }],
295
+ });
296
+ }
297
+ // Cap at 20
298
+ const capped = proposals.slice(0, 20);
299
+ return {
300
+ proposals: capped,
301
+ stats: {
302
+ godNodes: godNodes.length,
303
+ communities: survivingCommunities.length,
304
+ crossModuleCouplings: capped.filter((p) => p.kind === "gotcha").length,
305
+ totalProposals: capped.length,
306
+ },
307
+ };
308
+ }
309
+ /**
310
+ * Slugify a label suffix and prefix it. Stable, lowercase, dash-separated.
311
+ * E.g. makeProposalId("graphify-cluster", "src/utils") → "graphify-cluster-src-utils".
312
+ */
313
+ function makeProposalId(prefix, suffix) {
314
+ const slug = suffix
315
+ .toLowerCase()
316
+ .replace(/[^a-z0-9]+/g, "-")
317
+ .replace(/^-+|-+$/g, "")
318
+ .slice(0, 80);
319
+ return slug ? `${prefix}-${slug}` : prefix;
320
+ }
321
+ export function queryGraph(question, workspacePath) {
322
+ const info = detectGraphify();
323
+ if (!info.available) {
324
+ return { success: false, error: "graphify binary not found" };
325
+ }
326
+ const graphPath = join(resolve(workspacePath), "graphify-out", "graph.json");
327
+ if (!existsSync(graphPath)) {
328
+ return { success: false, error: "graph.json not found" };
329
+ }
330
+ const result = spawnSync("graphify", ["query", question, "--graph", graphPath], {
331
+ encoding: "utf-8",
332
+ stdio: ["pipe", "pipe", "pipe"],
333
+ timeout: 30_000,
334
+ });
335
+ if (result.error) {
336
+ return { success: false, error: result.error.message };
337
+ }
338
+ if (result.status !== 0) {
339
+ return { success: false, error: result.stderr?.trim() || "Query failed" };
340
+ }
341
+ return { success: true, answer: result.stdout.trim() };
342
+ }
343
+ export function pathBetween(entityA, entityB, workspacePath) {
344
+ const info = detectGraphify();
345
+ if (!info.available) {
346
+ return { success: false, error: "graphify binary not found" };
347
+ }
348
+ const graphPath = join(resolve(workspacePath), "graphify-out", "graph.json");
349
+ if (!existsSync(graphPath)) {
350
+ return { success: false, error: "graph.json not found" };
351
+ }
352
+ const result = spawnSync("graphify", ["path", entityA, entityB, "--graph", graphPath], {
353
+ encoding: "utf-8",
354
+ stdio: ["pipe", "pipe", "pipe"],
355
+ timeout: 30_000,
356
+ });
357
+ if (result.error) {
358
+ return { success: false, error: result.error.message };
359
+ }
360
+ if (result.status !== 0) {
361
+ return { success: false, error: result.stderr?.trim() || "Path query failed" };
362
+ }
363
+ return { success: true, answer: result.stdout.trim() };
364
+ }
365
+ export function runExtraction(workspacePath) {
366
+ const info = detectGraphify();
367
+ if (!info.available) {
368
+ return {
369
+ success: false,
370
+ error: "graphify binary not found",
371
+ code: "ENOENT",
372
+ };
373
+ }
374
+ const absolutePath = resolve(workspacePath);
375
+ // Use `update --force --no-cluster` for AST-only extraction (no LLM API key needed)
376
+ const result = spawnSync("graphify", ["update", absolutePath, "--force", "--no-cluster"], {
377
+ encoding: "utf-8",
378
+ stdio: ["pipe", "pipe", "pipe"],
379
+ timeout: 120_000,
380
+ cwd: absolutePath,
381
+ });
382
+ if (result.error) {
383
+ const errCode = result.error.code;
384
+ return {
385
+ success: false,
386
+ error: result.error.message,
387
+ code: errCode === "ETIMEDOUT" ? "ETIMEDOUT" : errCode,
388
+ };
389
+ }
390
+ if (result.status !== 0) {
391
+ const stderr = result.stderr?.trim() || "Process exited with non-zero status";
392
+ return {
393
+ success: false,
394
+ error: stderr,
395
+ code: `EXIT_${result.status}`,
396
+ };
397
+ }
398
+ const graphJsonPath = join(absolutePath, "graphify-out", "graph.json");
399
+ if (!existsSync(graphJsonPath)) {
400
+ return {
401
+ success: false,
402
+ error: "Extraction completed but graph.json not found",
403
+ code: "ENOENT",
404
+ };
405
+ }
406
+ // Ensure graphify-out/ is in .gitignore so extraction output doesn't pollute the repo
407
+ ensureGitignoreEntry(absolutePath, "graphify-out/");
408
+ return {
409
+ success: true,
410
+ graphJsonPath,
411
+ };
412
+ }
413
+ /**
414
+ * Append an entry to .gitignore if it's not already present.
415
+ * Creates the file if it doesn't exist.
416
+ */
417
+ function ensureGitignoreEntry(workspacePath, entry) {
418
+ const gitignorePath = join(workspacePath, ".gitignore");
419
+ try {
420
+ if (existsSync(gitignorePath)) {
421
+ const content = readFileSync(gitignorePath, "utf-8");
422
+ // Check if entry already present (exact line match)
423
+ const lines = content.split("\n").map((l) => l.trim());
424
+ if (lines.includes(entry))
425
+ return;
426
+ // Append with newline separator if file doesn't end with one
427
+ const separator = content.endsWith("\n") ? "" : "\n";
428
+ appendFileSync(gitignorePath, `${separator}${entry}\n`, "utf-8");
429
+ }
430
+ else {
431
+ // Create .gitignore with the entry
432
+ appendFileSync(gitignorePath, `${entry}\n`, "utf-8");
433
+ }
434
+ }
435
+ catch {
436
+ // Non-fatal — don't fail extraction over .gitignore issues
437
+ }
438
+ }
439
+ //# sourceMappingURL=graphify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/utils/graphify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQ1C,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,QAAQ,CAAC,oBAAoB,EAAE;YAC7C,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,OAAO,EAAE,IAAI;SACd,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,MAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB,EAAE;YAC9C,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,OAAO,EAAE,IAAI;SACd,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,uEAAuE;QACvE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAE/C,OAAO;YACL,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;YACnC,IAAI,EAAE,YAAY,IAAI,SAAS;SAChC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;AACH,CAAC;AAoID,SAAS,cAAc,CAAC,SAAiB;IACvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAiB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAExE,yEAAyE;QACzE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAE7C,0DAA0D;QAC1D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAClE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAClE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5D,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,kBAAkB;QAClB,MAAM,KAAK,GAAgB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChD,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,SAAS;YACxC,QAAQ,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,IAAI,SAAS;YAC5C,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,IAAI,EAAE;YACnC,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC;YAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;YAC5C,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;YAC9B,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;SACjC,CAAC,CAAC,CAAC;QAEJ,+EAA+E;QAC/E,MAAM,WAAW,GAAqB,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QAC7D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,wDAAwD;YACxD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;YAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,IAAI;oBAAE,SAAS;gBACzB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;gBAC/D,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACnB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC3B,CAAC;YACD,IAAI,WAAW,GAAG,CAAC,CAAC;YACpB,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;gBACvC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;oBACxB,WAAW,CAAC,IAAI,CAAC;wBACf,EAAE,EAAE,WAAW,EAAE;wBACjB,KAAK,EAAE,GAAG;wBACV,KAAK,EAAE,OAAO;qBACf,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,MAAgB,EAAE,CAAS;IAC7C,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC;IACzB,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,aAAqB,EAAE,KAAa;IAC9D,MAAM,KAAK,GAAoB;QAC7B,SAAS,EAAE,EAAE;QACb,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE;KACnF,CAAC;IAEF,MAAM,KAAK,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErD,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3D,+DAA+D;IAC/D,wFAAwF;IACxF,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAClC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC;QACpC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAE/B,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK;SACzB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SACpE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;SACnC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,mDAAmD;IAEnE,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,wEAAwE;QACxE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;QACnD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;QACnD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;gBACvD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACrC,IAAI,GAAG;oBAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACpD,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;gBACvD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACrC,IAAI,GAAG;oBAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,GAAG,gBAAgB,CAAC,OAAO,EAAE,CAAC;aAC/C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACZ,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1B,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAwC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAEnE,MAAM,UAAU,GAAG,CAAC,GAAG,gBAAgB,CAAC,OAAO,EAAE,CAAC;aAC/C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACZ,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1B,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAwC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAEnE,SAAS,CAAC,IAAI,CAAC;YACb,EAAE,EAAE,cAAc,CAAC,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAChE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,eAAe,EAAE;gBACf,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,MAAM,EAAE,IAAI,CAAC,QAAQ;gBACrB,OAAO,EAAE,IAAI,CAAC,SAAS;gBACvB,UAAU;gBACV,UAAU;aACX;YACD,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IAED,gFAAgF;IAChF,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CACxD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAC1C,CAAC;IAEF,wEAAwE;IACxE,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,KAAK,MAAM,MAAM,IAAI,CAAC,CAAC,KAAK;YAAE,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,oBAAoB,GAAqB,EAAE,CAAC;IAClD,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChG,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACnC,iFAAiF;QACjF,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC;QACtE,IAAI,CAAC,cAAc;YAAE,SAAS;QAC9B,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,oBAAoB,CAAC,MAAM,IAAI,CAAC;YAAE,MAAM;IAC9C,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEhG,4CAA4C;QAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,MAAM,iBAAiB,GAA2B,EAAE,CAAC;QACrD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,IAAI;gBAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC;YACnC,iBAAiB,CAAC,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACzD,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBACX,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC;aACzB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;aACrE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;aAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAEpF,+BAA+B;QAC/B,MAAM,qBAAqB,GAAG,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC;aACzD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAE7C,4EAA4E;QAC5E,sDAAsD;QACtD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChD,IAAI,YAAY,KAAK,YAAY;gBAAE,SAAS,CAAC,iCAAiC;YAC9E,sEAAsE;YACtE,4DAA4D;YAC5D,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YACzD,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtD,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,SAAS,CAAC,EAAE;gBAAE,SAAS;YAC9E,IAAI,YAAY;gBAAE,QAAQ,EAAE,CAAC;;gBACxB,QAAQ,EAAE,CAAC;QAClB,CAAC;QAED,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QACjC,SAAS,CAAC,IAAI,CAAC;YACb,EAAE,EAAE,cAAc,CAAC,kBAAkB,EAAE,SAAS,CAAC,KAAK,CAAC;YACvD,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,eAAe,EAAE;gBACf,WAAW;gBACX,SAAS,EAAE,WAAW,CAAC,MAAM;gBAC7B,iBAAiB;gBACjB,OAAO;gBACP,qBAAqB;gBACrB,yBAAyB,EAAE,QAAQ;gBACnC,uBAAuB,EAAE,QAAQ;aAClC;YACD,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;SACnD,CAAC,CAAC;IACL,CAAC;IASD,MAAM,aAAa,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC3D,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI;YAAE,SAAS;QAC7D,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,SAAS;QAC9C,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS;YAAE,SAAS;QAErE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GACnB,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,KAAK,CAAW,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,KAAK,CAAW,CAAC;QAC9E,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,IAAI,CAAC,QAAQ;gBAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE;gBACrB,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,MAAM;gBACT,SAAS,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxD,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;aAC7C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;SAC1C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC;SACnD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEf,KAAK,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,SAAS,EAAE,CAAC;QAC5C,SAAS,CAAC,IAAI,CAAC;YACb,EAAE,EAAE,cAAc,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YAChE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,KAAK,EAAE;YAChC,eAAe,EAAE;gBACf,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;gBAC7D,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;gBAC7D,SAAS,EAAE,CAAC,GAAG,SAAS,CAAC;aAC1B;YACD,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;SAClD,CAAC,CAAC;IACL,CAAC;IAED,YAAY;IACZ,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEtC,OAAO;QACL,SAAS,EAAE,MAAM;QACjB,KAAK,EAAE;YACL,QAAQ,EAAE,QAAQ,CAAC,MAAM;YACzB,WAAW,EAAE,oBAAoB,CAAC,MAAM;YACxC,oBAAoB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,MAAM;YACtE,cAAc,EAAE,MAAM,CAAC,MAAM;SAC9B;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,MAAc,EAAE,MAAc;IACpD,MAAM,IAAI,GAAG,MAAM;SAChB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AAC7C,CAAC;AAgBD,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,aAAqB;IAChE,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IAC7E,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAC3D,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE;QAC9E,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,OAAO,EAAE,MAAM;KAChB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,cAAc,EAAE,CAAC;IAC5E,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,OAAe,EAAE,aAAqB;IACjF,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IAC7E,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAC3D,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE;QACrF,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,OAAO,EAAE,MAAM;KAChB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,mBAAmB,EAAE,CAAC;IACjF,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,aAAqB;IACjD,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,2BAA2B;YAClC,IAAI,EAAE,QAAQ;SACf,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,oFAAoF;IACpF,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE;QACxF,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,OAAO,EAAE,OAAO;QAChB,GAAG,EAAE,YAAY;KAClB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,OAAO,GAAI,MAAM,CAAC,KAA+B,CAAC,IAAI,CAAC;QAC7D,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;YAC3B,IAAI,EAAE,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO;SACtD,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,qCAAqC,CAAC;QAC9E,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,QAAQ,MAAM,CAAC,MAAM,EAAE;SAC9B,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IAEvE,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,+CAA+C;YACtD,IAAI,EAAE,QAAQ;SACf,CAAC;IACJ,CAAC;IAED,sFAAsF;IACtF,oBAAoB,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IAEpD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,aAAa;KACd,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,aAAqB,EAAE,KAAa;IAChE,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YACrD,oDAAoD;YACpD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACvD,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,OAAO;YAClC,6DAA6D;YAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACrD,cAAc,CAAC,aAAa,EAAE,GAAG,SAAS,GAAG,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,mCAAmC;YACnC,cAAc,CAAC,aAAa,EAAE,GAAG,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;AACH,CAAC"}
@@ -26,7 +26,12 @@ export interface SessionMeta {
26
26
  id: string;
27
27
  normalizedId: string;
28
28
  runtimeType: import("./storage-utils.js").SessionRuntimeType;
29
- /** Runtime-native session id, verbatim (e.g. a claude-code session uuid). */
29
+ /**
30
+ * Runtime-native session id, verbatim (e.g. a claude-code session uuid).
31
+ * Blank on a thread ARCS minted before its first run contacted the runtime —
32
+ * an opencode thread has no id of its own until the first settled run
33
+ * harvests one, and the run write-back persists it here.
34
+ */
30
35
  runtimeSessionId: string;
31
36
  /**
32
37
  * Provenance of the record. Persisted, never client-settable, and never
@@ -90,7 +95,18 @@ export interface SessionIndex {
90
95
  }
91
96
  export interface CreateSessionInput {
92
97
  runtimeType: import("./storage-utils.js").SessionRuntimeType;
93
- runtimeSessionId: string;
98
+ /**
99
+ * Runtime-native session id, verbatim. OPTIONAL for a thread ARCS mints
100
+ * before its first run: an opencode thread has none until its first settled
101
+ * run harvests one (persisted through `UpdateSessionInput`). Discovery
102
+ * bridges always have the id and never pass `recordName`.
103
+ */
104
+ runtimeSessionId?: string;
105
+ /**
106
+ * Explicit record name, used as the store key when the runtime id is not
107
+ * known yet. Absent → the key is normalizeIdentifier(runtimeSessionId).
108
+ */
109
+ recordName?: string;
94
110
  /**
95
111
  * Provenance, set once at creation and defaulting to `observed`. Only the
96
112
  * ARCS-minted headless threads pass `arcs`. Deliberately absent from every
@@ -108,6 +124,12 @@ export interface CreateSessionInput {
108
124
  export interface UpdateSessionInput {
109
125
  id: string;
110
126
  status?: import("./storage-utils.js").SessionStatus;
127
+ /**
128
+ * The runtime-native session id, verbatim — written by the run write-back
129
+ * that harvested it off a first settled run. Never client-settable: the web
130
+ * PATCH schema does not carry it.
131
+ */
132
+ runtimeSessionId?: string;
111
133
  /** Pass `null` to clear; pass an ISO timestamp to set. */
112
134
  lastMessageAt?: string | null;
113
135
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../src/utils/session-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../src/utils/session-store.ts"],"names":[],"mappings":"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"}
@@ -180,7 +180,9 @@ function buildSession(input, normalizedId) {
180
180
  id: normalizedId,
181
181
  normalizedId,
182
182
  runtimeType: input.runtimeType,
183
- runtimeSessionId: input.runtimeSessionId,
183
+ // Blank, never absent: a thread minted before its first run has no runtime
184
+ // id yet, and the first settled run writes it (UpdateSessionInput).
185
+ runtimeSessionId: input.runtimeSessionId ?? "",
184
186
  origin: input.origin ?? "observed",
185
187
  status: input.status ?? "active",
186
188
  startedAt: input.startedAt ?? ts,
@@ -193,14 +195,17 @@ function buildSession(input, normalizedId) {
193
195
  /**
194
196
  * Validates a create/upsert payload and returns the canonical normalized id.
195
197
  * Runtime session ids are opaque runtime-native strings, so the only structural
196
- * requirement is that they normalize to a non-empty identifier.
198
+ * requirement is that they normalize to a non-empty identifier — either their
199
+ * own, or the explicit record name of a thread minted before its runtime id
200
+ * exists.
197
201
  */
198
202
  function validateCreateInput(input) {
199
203
  validateSessionRuntimeType(input.runtimeType);
200
204
  validateSessionStatus(input.status ?? "active");
201
- const normalizedId = normalizeIdentifier(input.runtimeSessionId);
205
+ const key = input.recordName ?? input.runtimeSessionId ?? "";
206
+ const normalizedId = normalizeIdentifier(key);
202
207
  if (!normalizedId) {
203
- throw invalidSessionId(input.runtimeSessionId);
208
+ throw invalidSessionId(key);
204
209
  }
205
210
  return normalizedId;
206
211
  }
@@ -230,7 +235,7 @@ async function createSessionUnlocked(projectDir, input) {
230
235
  const normalizedId = validateCreateInput(input);
231
236
  const index = await readSessionIndex(projectDir);
232
237
  if (index.sessions.some((s) => s.normalizedId === normalizedId)) {
233
- throw normalizedIdCollision("session", input.runtimeSessionId, normalizedId);
238
+ throw normalizedIdCollision("session", input.recordName ?? input.runtimeSessionId ?? "", normalizedId);
234
239
  }
235
240
  const meta = buildSession(input, normalizedId);
236
241
  index.sessions.push(meta);
@@ -256,11 +261,12 @@ async function upsertSessionUnlocked(projectDir, input) {
256
261
  // creating writer fixes it for good. A hook observation must not demote an
257
262
  // ARCS-owned thread, and an ARCS run claiming an existing record as its
258
263
  // write-target must not erase the fact that a real terminal session is
259
- // attached to it.
264
+ // attached to it. `runtimeSessionId` merges only when the caller has one —
265
+ // a thread minted blank must not have a harvested id overwritten away.
260
266
  const merged = {
261
267
  ...existing,
262
268
  runtimeType: input.runtimeType,
263
- runtimeSessionId: input.runtimeSessionId,
269
+ ...(input.runtimeSessionId !== undefined && { runtimeSessionId: input.runtimeSessionId }),
264
270
  ...(input.status && { status: input.status }),
265
271
  ...(input.startedAt && { startedAt: input.startedAt }),
266
272
  ...(input.lastMessageAt && { lastMessageAt: input.lastMessageAt }),
@@ -317,6 +323,9 @@ async function updateSessionUnlocked(projectDir, input) {
317
323
  const session = index.sessions[sessionIndex];
318
324
  if (input.status !== undefined)
319
325
  session.status = input.status;
326
+ if (input.runtimeSessionId !== undefined && input.runtimeSessionId !== "") {
327
+ session.runtimeSessionId = input.runtimeSessionId;
328
+ }
320
329
  if (input.lastMessageAt !== undefined) {
321
330
  if (input.lastMessageAt === null || input.lastMessageAt === "") {
322
331
  delete session.lastMessageAt;