gsd-pi 2.74.0-dev.b741afb → 2.74.0-dev.ffbcc03

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 (403) hide show
  1. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  2. package/dist/resources/extensions/gsd/auto/loop.js +147 -10
  3. package/dist/resources/extensions/gsd/auto/phases.js +113 -3
  4. package/dist/resources/extensions/gsd/auto/session.js +10 -0
  5. package/dist/resources/extensions/gsd/auto-dispatch.js +11 -1
  6. package/dist/resources/extensions/gsd/auto-model-selection.js +51 -5
  7. package/dist/resources/extensions/gsd/auto-post-unit.js +215 -8
  8. package/dist/resources/extensions/gsd/auto-recovery.js +24 -10
  9. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  10. package/dist/resources/extensions/gsd/auto-verification.js +100 -2
  11. package/dist/resources/extensions/gsd/auto.js +28 -2
  12. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +10 -1
  13. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +61 -9
  14. package/dist/resources/extensions/gsd/cache.js +16 -5
  15. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  16. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  17. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  18. package/dist/resources/extensions/gsd/docs/preferences-reference.md +14 -1
  19. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
  20. package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
  21. package/dist/resources/extensions/gsd/git-service.js +49 -1
  22. package/dist/resources/extensions/gsd/graph-context.js +98 -7
  23. package/dist/resources/extensions/gsd/gsd-db.js +260 -2
  24. package/dist/resources/extensions/gsd/guided-flow.js +24 -1
  25. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  26. package/dist/resources/extensions/gsd/journal.js +27 -0
  27. package/dist/resources/extensions/gsd/metrics.js +19 -0
  28. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  29. package/dist/resources/extensions/gsd/preferences-models.js +20 -3
  30. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  31. package/dist/resources/extensions/gsd/preferences-validation.js +108 -2
  32. package/dist/resources/extensions/gsd/preferences.js +26 -0
  33. package/dist/resources/extensions/gsd/safety/evidence-collector.js +15 -30
  34. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  35. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  36. package/dist/resources/extensions/gsd/tools/complete-slice.js +5 -0
  37. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  38. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  39. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  40. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  41. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  42. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  43. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  44. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  45. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  46. package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
  47. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  48. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  49. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  50. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  51. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  52. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  53. package/dist/web/standalone/.next/BUILD_ID +1 -1
  54. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  55. package/dist/web/standalone/.next/build-manifest.json +2 -2
  56. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  57. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/index.html +1 -1
  79. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  86. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  87. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  88. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  89. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  90. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  91. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  92. package/package.json +1 -1
  93. package/packages/mcp-server/dist/readers/graph.d.ts +1 -1
  94. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -1
  95. package/packages/mcp-server/dist/readers/graph.js +107 -0
  96. package/packages/mcp-server/dist/readers/graph.js.map +1 -1
  97. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  98. package/packages/mcp-server/dist/workflow-tools.js +88 -6
  99. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  100. package/packages/mcp-server/src/readers/graph.test.ts +178 -0
  101. package/packages/mcp-server/src/readers/graph.ts +148 -1
  102. package/packages/mcp-server/src/workflow-tools.ts +95 -10
  103. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  104. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  105. package/packages/pi-ai/dist/index.d.ts +1 -9
  106. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  107. package/packages/pi-ai/dist/index.js +1 -9
  108. package/packages/pi-ai/dist/index.js.map +1 -1
  109. package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
  110. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
  111. package/packages/pi-ai/dist/models/capability-patches.js +36 -0
  112. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
  113. package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
  114. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
  115. package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
  116. package/packages/pi-ai/dist/models/custom.js.map +1 -0
  117. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
  118. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
  119. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
  120. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
  121. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
  122. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
  123. package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
  124. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
  125. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
  126. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
  127. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
  128. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
  129. package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
  130. package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
  131. package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
  132. package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
  133. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
  134. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
  135. package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
  136. package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
  137. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
  138. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
  139. package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
  140. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
  141. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
  142. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
  143. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
  144. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
  145. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
  146. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
  147. package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
  148. package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
  149. package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
  150. package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
  151. package/packages/pi-ai/dist/models/generated/google.js +464 -0
  152. package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
  153. package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
  154. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
  155. package/packages/pi-ai/dist/models/generated/groq.js +311 -0
  156. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
  157. package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
  158. package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
  159. package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
  160. package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
  161. package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
  162. package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
  163. package/packages/pi-ai/dist/models/generated/index.js +51 -0
  164. package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
  165. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
  166. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
  167. package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
  168. package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
  169. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
  170. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
  172. package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
  173. package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
  174. package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
  175. package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
  176. package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
  177. package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
  178. package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
  179. package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
  180. package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
  181. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
  182. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
  183. package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
  184. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
  185. package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
  186. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
  187. package/packages/pi-ai/dist/models/generated/openai.js +702 -0
  188. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
  189. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
  190. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
  191. package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
  192. package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
  193. package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
  194. package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
  195. package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
  196. package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
  197. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
  198. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
  199. package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
  200. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
  201. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
  202. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
  203. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
  204. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
  205. package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
  206. package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
  207. package/packages/pi-ai/dist/models/generated/xai.js +413 -0
  208. package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
  209. package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
  210. package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
  211. package/packages/pi-ai/dist/models/generated/zai.js +239 -0
  212. package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
  213. package/packages/pi-ai/dist/models/index.d.ts +27 -0
  214. package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
  215. package/packages/pi-ai/dist/models/index.js +80 -0
  216. package/packages/pi-ai/dist/models/index.js.map +1 -0
  217. package/packages/pi-ai/dist/models.d.ts +1 -36
  218. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  219. package/packages/pi-ai/dist/models.generated.test.js +1 -2
  220. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  221. package/packages/pi-ai/dist/models.js +3 -112
  222. package/packages/pi-ai/dist/models.js.map +1 -1
  223. package/packages/pi-ai/dist/models.test.js +6 -5
  224. package/packages/pi-ai/dist/models.test.js.map +1 -1
  225. package/packages/pi-ai/scripts/generate-models.ts +74 -40
  226. package/packages/pi-ai/src/index.ts +1 -9
  227. package/packages/pi-ai/src/models/capability-patches.ts +40 -0
  228. package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
  229. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
  230. package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
  231. package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
  232. package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
  233. package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
  234. package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
  235. package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
  236. package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
  237. package/packages/pi-ai/src/models/generated/google.ts +466 -0
  238. package/packages/pi-ai/src/models/generated/groq.ts +313 -0
  239. package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
  240. package/packages/pi-ai/src/models/generated/index.ts +52 -0
  241. package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
  242. package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
  243. package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
  244. package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
  245. package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
  246. package/packages/pi-ai/src/models/generated/openai.ts +704 -0
  247. package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
  248. package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
  249. package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
  250. package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
  251. package/packages/pi-ai/src/models/generated/xai.ts +415 -0
  252. package/packages/pi-ai/src/models/generated/zai.ts +241 -0
  253. package/packages/pi-ai/src/models/index.ts +106 -0
  254. package/packages/pi-ai/src/models.generated.test.ts +1 -2
  255. package/packages/pi-ai/src/models.test.ts +6 -5
  256. package/packages/pi-ai/src/models.ts +3 -153
  257. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  258. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
  260. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +472 -0
  262. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  264. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  265. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  266. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  267. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  269. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +11 -0
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -0
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +23 -9
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +47 -0
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +68 -8
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  288. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +232 -18
  289. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  291. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -0
  295. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +70 -6
  297. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  298. package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
  299. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +612 -0
  300. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  301. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  302. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +19 -0
  303. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +25 -10
  304. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +67 -0
  305. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +83 -7
  306. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
  307. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +298 -41
  308. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  309. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +92 -6
  310. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  311. package/packages/pi-coding-agent/tsconfig.json +2 -2
  312. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  313. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  314. package/src/resources/extensions/gsd/auto/loop-deps.ts +4 -0
  315. package/src/resources/extensions/gsd/auto/loop.ts +159 -10
  316. package/src/resources/extensions/gsd/auto/phases.ts +123 -3
  317. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  318. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -6
  319. package/src/resources/extensions/gsd/auto-model-selection.ts +66 -5
  320. package/src/resources/extensions/gsd/auto-post-unit.ts +226 -9
  321. package/src/resources/extensions/gsd/auto-recovery.ts +29 -9
  322. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  323. package/src/resources/extensions/gsd/auto-verification.ts +129 -2
  324. package/src/resources/extensions/gsd/auto.ts +34 -2
  325. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -1
  326. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +72 -8
  327. package/src/resources/extensions/gsd/cache.ts +16 -5
  328. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  329. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  330. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  331. package/src/resources/extensions/gsd/docs/preferences-reference.md +14 -1
  332. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
  333. package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
  334. package/src/resources/extensions/gsd/git-service.ts +68 -0
  335. package/src/resources/extensions/gsd/graph-context.ts +139 -12
  336. package/src/resources/extensions/gsd/gsd-db.ts +321 -3
  337. package/src/resources/extensions/gsd/guided-flow.ts +33 -1
  338. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  339. package/src/resources/extensions/gsd/journal.ts +30 -0
  340. package/src/resources/extensions/gsd/metrics.ts +26 -0
  341. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  342. package/src/resources/extensions/gsd/preferences-models.ts +20 -3
  343. package/src/resources/extensions/gsd/preferences-types.ts +32 -0
  344. package/src/resources/extensions/gsd/preferences-validation.ts +107 -2
  345. package/src/resources/extensions/gsd/preferences.ts +28 -0
  346. package/src/resources/extensions/gsd/safety/evidence-collector.ts +15 -31
  347. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  348. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  349. package/src/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  350. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +177 -0
  351. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +7 -3
  352. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  353. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  354. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +272 -0
  355. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  356. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  357. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  358. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  359. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
  360. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  361. package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
  362. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  363. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  364. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  365. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  366. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  367. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
  368. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -5
  369. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  370. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
  371. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  372. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
  373. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  374. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  375. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  376. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  377. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  378. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  379. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  380. package/src/resources/extensions/gsd/tools/complete-slice.ts +9 -2
  381. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  382. package/src/resources/extensions/gsd/types.ts +14 -1
  383. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  384. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  385. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  386. package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
  387. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  388. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  389. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  390. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  391. package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
  392. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  393. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  394. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  395. package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
  396. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  397. package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
  398. package/packages/pi-ai/dist/models.custom.js.map +0 -1
  399. package/packages/pi-ai/dist/models.generated.js +0 -14343
  400. package/packages/pi-ai/dist/models.generated.js.map +0 -1
  401. package/packages/pi-ai/src/models.generated.ts +0 -14345
  402. /package/dist/web/standalone/.next/static/{XnHY5eXUsTCFmNodWHetD → kn6xzWKYnogsxp2b6RpDD}/_buildManifest.js +0 -0
  403. /package/dist/web/standalone/.next/static/{XnHY5eXUsTCFmNodWHetD → kn6xzWKYnogsxp2b6RpDD}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- globalThis.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-42372ed130431b0a.js"],devFiles:[],lowPriorityFiles:["static/XnHY5eXUsTCFmNodWHetD/_buildManifest.js","static/XnHY5eXUsTCFmNodWHetD/_ssgManifest.js"],rootMainFiles:["static/chunks/webpack-b868033a5834586d.js","static/chunks/4bd1b696-e356ca5ba0218e27.js","static/chunks/3794-42fdce068d44fa4f.js","static/chunks/main-app-fdab67f7802d7832.js"],rootMainFilesTree:{},pages:{"/_app":[]}};
1
+ globalThis.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-42372ed130431b0a.js"],devFiles:[],lowPriorityFiles:["static/kn6xzWKYnogsxp2b6RpDD/_buildManifest.js","static/kn6xzWKYnogsxp2b6RpDD/_ssgManifest.js"],rootMainFiles:["static/chunks/webpack-b868033a5834586d.js","static/chunks/4bd1b696-e356ca5ba0218e27.js","static/chunks/3794-42fdce068d44fa4f.js","static/chunks/main-app-fdab67f7802d7832.js"],rootMainFilesTree:{},pages:{"/_app":[]}};
@@ -18,11 +18,11 @@
18
18
  "wasm": [],
19
19
  "assets": [],
20
20
  "env": {
21
- "__NEXT_BUILD_ID": "XnHY5eXUsTCFmNodWHetD",
22
- "NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "MrGfoNifP0MCLPdWuTY6qj/sV24r1KBESovBh4Llrts=",
23
- "__NEXT_PREVIEW_MODE_ID": "c5940de80ca165aae824ac333798cf7c",
24
- "__NEXT_PREVIEW_MODE_SIGNING_KEY": "30006194f59e75c0ed873d9eec7bcafc7aeb206c744c6573ec9633331744e123",
25
- "__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "3738db77029dc2c0302104673ac390af9386e70b1dcbf045881d54fdfa2c97f3"
21
+ "__NEXT_BUILD_ID": "kn6xzWKYnogsxp2b6RpDD",
22
+ "NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "b2DAKNW2cpd+vUM1CSKQPoeUZWWQos72CRZjJCP3908=",
23
+ "__NEXT_PREVIEW_MODE_ID": "0f127d7f44ae13191b77bd961912de3a",
24
+ "__NEXT_PREVIEW_MODE_SIGNING_KEY": "08c446a32f9c4c5951168c338da9fcf2e53e8b9f91ca985f7a6b61b7eeb0eeea",
25
+ "__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "e3785b89ede429224eab7208b115eace2e03554565d5e72be2900d24c8c7887a"
26
26
  }
27
27
  }
28
28
  },
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="preload" href="/_next/static/media/4cf2300e9c8272f7-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/93f479601ee12b01-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/de70bee13400563f.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/f6e8833d46e738d8.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-b868033a5834586d.js"/><script src="/_next/static/chunks/4bd1b696-e356ca5ba0218e27.js" async=""></script><script src="/_next/static/chunks/3794-42fdce068d44fa4f.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><script src="/_next/static/chunks/4986-c2fc8845ce785303.js" async=""></script><script src="/_next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>GSD</title><meta name="description" content="The evolution of Get Shit Done — now a real coding agent. One command. Walk away. Come back to a built project."/><meta name="application-name" content="GSD"/><link rel="icon" href="/icon-light-32x32.png" media="(prefers-color-scheme: light)"/><link rel="icon" href="/icon-dark-32x32.png" media="(prefers-color-scheme: dark)"/><link rel="icon" href="/icon.svg" type="image/svg+xml"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__variable_188709 __variable_9a8899 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","dark",null,["light","dark"],null,true,true)</script><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><script src="/_next/static/chunks/webpack-b868033a5834586d.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[21942,[\"4986\",\"static/chunks/4986-c2fc8845ce785303.js\",\"7177\",\"static/chunks/app/layout-a16c7a7ecdf0c2cf.js\"],\"ThemeProvider\"]\n3:I[57121,[],\"\"]\n4:I[74581,[],\"\"]\n5:I[61549,[\"4986\",\"static/chunks/4986-c2fc8845ce785303.js\",\"7177\",\"static/chunks/app/layout-a16c7a7ecdf0c2cf.js\"],\"Toaster\"]\n6:I[90484,[],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\na:I[90484,[],\"ViewportBoundary\"]\nc:I[90484,[],\"MetadataBoundary\"]\ne:I[27123,[],\"default\",1]\n:HL[\"/_next/static/media/4cf2300e9c8272f7-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/93f479601ee12b01-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/de70bee13400563f.css\",\"style\"]\n:HL[\"/_next/static/css/f6e8833d46e738d8.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/de70bee13400563f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/f6e8833d46e738d8.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"__variable_188709 __variable_9a8899 font-sans antialiased\",\"children\":[\"$\",\"$L2\",null,{\"attribute\":\"class\",\"defaultTheme\":\"dark\",\"children\":[[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L5\",null,{\"position\":\"bottom-right\"}]]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,null]},null,false,\"$@9\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$La\",null,{\"children\":\"$Lb\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lc\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Ld\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"XnHY5eXUsTCFmNodWHetD\"}\n"])</script><script>self.__next_f.push([1,"f:[]\n9:\"$Wf\"\n"])</script><script>self.__next_f.push([1,"b:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\"}]]\n"])</script><script>self.__next_f.push([1,"10:I[86869,[],\"IconMark\"]\n8:null\nd:[[\"$\",\"title\",\"0\",{\"children\":\"GSD\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"The evolution of Get Shit Done — now a real coding agent. One command. Walk away. Come back to a built project.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"application-name\",\"content\":\"GSD\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon-light-32x32.png\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/icon-dark-32x32.png\",\"media\":\"(prefers-color-scheme: dark)\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/icon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"$L10\",\"6\",{}]]\n"])</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="preload" href="/_next/static/media/4cf2300e9c8272f7-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/93f479601ee12b01-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/de70bee13400563f.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/f6e8833d46e738d8.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-b868033a5834586d.js"/><script src="/_next/static/chunks/4bd1b696-e356ca5ba0218e27.js" async=""></script><script src="/_next/static/chunks/3794-42fdce068d44fa4f.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><script src="/_next/static/chunks/4986-c2fc8845ce785303.js" async=""></script><script src="/_next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>GSD</title><meta name="description" content="The evolution of Get Shit Done — now a real coding agent. One command. Walk away. Come back to a built project."/><meta name="application-name" content="GSD"/><link rel="icon" href="/icon-light-32x32.png" media="(prefers-color-scheme: light)"/><link rel="icon" href="/icon-dark-32x32.png" media="(prefers-color-scheme: dark)"/><link rel="icon" href="/icon.svg" type="image/svg+xml"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__variable_188709 __variable_9a8899 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","dark",null,["light","dark"],null,true,true)</script><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><script src="/_next/static/chunks/webpack-b868033a5834586d.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[21942,[\"4986\",\"static/chunks/4986-c2fc8845ce785303.js\",\"7177\",\"static/chunks/app/layout-a16c7a7ecdf0c2cf.js\"],\"ThemeProvider\"]\n3:I[57121,[],\"\"]\n4:I[74581,[],\"\"]\n5:I[61549,[\"4986\",\"static/chunks/4986-c2fc8845ce785303.js\",\"7177\",\"static/chunks/app/layout-a16c7a7ecdf0c2cf.js\"],\"Toaster\"]\n6:I[90484,[],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\na:I[90484,[],\"ViewportBoundary\"]\nc:I[90484,[],\"MetadataBoundary\"]\ne:I[27123,[],\"default\",1]\n:HL[\"/_next/static/media/4cf2300e9c8272f7-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/93f479601ee12b01-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/de70bee13400563f.css\",\"style\"]\n:HL[\"/_next/static/css/f6e8833d46e738d8.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/de70bee13400563f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/f6e8833d46e738d8.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"__variable_188709 __variable_9a8899 font-sans antialiased\",\"children\":[\"$\",\"$L2\",null,{\"attribute\":\"class\",\"defaultTheme\":\"dark\",\"children\":[[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L5\",null,{\"position\":\"bottom-right\"}]]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,null]},null,false,\"$@9\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$La\",null,{\"children\":\"$Lb\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lc\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Ld\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"kn6xzWKYnogsxp2b6RpDD\"}\n"])</script><script>self.__next_f.push([1,"f:[]\n9:\"$Wf\"\n"])</script><script>self.__next_f.push([1,"b:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\"}]]\n"])</script><script>self.__next_f.push([1,"10:I[86869,[],\"IconMark\"]\n8:null\nd:[[\"$\",\"title\",\"0\",{\"children\":\"GSD\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"The evolution of Get Shit Done — now a real coding agent. One command. Walk away. Come back to a built project.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"application-name\",\"content\":\"GSD\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon-light-32x32.png\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/icon-dark-32x32.png\",\"media\":\"(prefers-color-scheme: dark)\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/icon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"$L10\",\"6\",{}]]\n"])</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-b868033a5834586d.js"/><script src="/_next/static/chunks/4bd1b696-e356ca5ba0218e27.js" async=""></script><script src="/_next/static/chunks/3794-42fdce068d44fa4f.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-b868033a5834586d.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n4:I[90484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[90484,[],\"ViewportBoundary\"]\na:I[90484,[],\"MetadataBoundary\"]\nc:I[27123,[],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"XnHY5eXUsTCFmNodWHetD\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-b868033a5834586d.js"/><script src="/_next/static/chunks/4bd1b696-e356ca5ba0218e27.js" async=""></script><script src="/_next/static/chunks/3794-42fdce068d44fa4f.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-b868033a5834586d.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n4:I[90484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[90484,[],\"ViewportBoundary\"]\na:I[90484,[],\"MetadataBoundary\"]\nc:I[27123,[],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"kn6xzWKYnogsxp2b6RpDD\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
@@ -1 +1 @@
1
- {"node":{},"edge":{},"encryptionKey":"MrGfoNifP0MCLPdWuTY6qj/sV24r1KBESovBh4Llrts="}
1
+ {"node":{},"edge":{},"encryptionKey":"b2DAKNW2cpd+vUM1CSKQPoeUZWWQos72CRZjJCP3908="}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsd-pi",
3
- "version": "2.74.0-dev.b741afb",
3
+ "version": "2.74.0-dev.ffbcc03",
4
4
  "description": "GSD — Get Shit Done coding agent",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,4 +1,4 @@
1
- export type NodeType = 'milestone' | 'slice' | 'task' | 'rule' | 'pattern' | 'lesson' | 'concept';
1
+ export type NodeType = 'milestone' | 'slice' | 'task' | 'rule' | 'pattern' | 'lesson' | 'concept' | 'decision';
2
2
  export type EdgeType = 'contains' | 'depends_on' | 'relates_to' | 'implements';
3
3
  export type ConfidenceTier = 'EXTRACTED' | 'INFERRED' | 'AMBIGUOUS';
4
4
  export interface GraphNode {
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/readers/graph.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,QAAQ,GAChB,WAAW,GACX,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,GACT,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,QAAQ,GAChB,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,CAAC;AAEpE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,cAAc,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAiTD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAwC5E;AAMD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAStF;AAMD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlE;AAMD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA4BhF;AAgED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,MAAM,SAAO,GACZ,OAAO,CAAC,gBAAgB,CAAC,CAwC3B;AAMD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAwD5E"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/readers/graph.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,QAAQ,GAChB,WAAW,GACX,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,GACT,QAAQ,GACR,SAAS,GACT,UAAU,CAAC;AAEf,MAAM,MAAM,QAAQ,GAChB,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,CAAC;AAEpE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,cAAc,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAkcD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAyC5E;AAMD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAStF;AAMD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlE;AAMD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA4BhF;AAgED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,MAAM,SAAO,GACZ,OAAO,CAAC,gBAAgB,CAAC,CAwC3B;AAMD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAwD5E"}
@@ -280,6 +280,112 @@ function parseTasksFromPlan(content, milestoneId, sliceId, sliceNodeId, nodes, e
280
280
  }
281
281
  }
282
282
  // ---------------------------------------------------------------------------
283
+ // LEARNINGS.md parser
284
+ // ---------------------------------------------------------------------------
285
+ /**
286
+ * Parse all *-LEARNINGS.md files found in milestone directories.
287
+ * Extracts Decisions, Lessons, Patterns, and Surprises as typed graph nodes.
288
+ * Surprises are mapped to the 'lesson' NodeType (no distinct type exists).
289
+ * Parse errors per file are caught — the file is skipped, never rethrows.
290
+ */
291
+ function parseLearningsFiles(gsdRoot, nodes, edges) {
292
+ const milestoneIds = findMilestoneIds(gsdRoot);
293
+ for (const milestoneId of milestoneIds) {
294
+ try {
295
+ parseSingleLearningsFile(gsdRoot, milestoneId, nodes, edges);
296
+ }
297
+ catch {
298
+ // Skip this milestone's LEARNINGS.md on any error
299
+ }
300
+ }
301
+ }
302
+ function parseSingleLearningsFile(gsdRoot, milestoneId, nodes, edges) {
303
+ const mDir = resolveMilestoneDir(gsdRoot, milestoneId);
304
+ if (!mDir)
305
+ return;
306
+ const learningsPath = join(mDir, `${milestoneId}-LEARNINGS.md`);
307
+ if (!existsSync(learningsPath))
308
+ return;
309
+ let content;
310
+ try {
311
+ content = readFileSync(learningsPath, 'utf-8');
312
+ }
313
+ catch {
314
+ return;
315
+ }
316
+ // Strip YAML frontmatter if present
317
+ const withoutFrontmatter = content.replace(/^---[\s\S]*?---\n?/, '');
318
+ const milestoneNodeId = `milestone:${milestoneId}`;
319
+ const sourceFile = `milestones/${milestoneId}/${milestoneId}-LEARNINGS.md`;
320
+ // Parse each section: [sectionName, nodeType, idPrefix]
321
+ const sections = [
322
+ ['Decisions', 'decision', 'decision'],
323
+ ['Lessons', 'lesson', 'lesson'],
324
+ ['Patterns', 'pattern', 'pattern'],
325
+ ['Surprises', 'lesson', 'surprise'],
326
+ ];
327
+ for (const [sectionName, nodeType, idPrefix] of sections) {
328
+ const sectionMatch = withoutFrontmatter.match(new RegExp(`##\\s+${sectionName}\\s*\\n([\\s\\S]*?)(?=\\n##\\s|$)`, 'i'));
329
+ if (!sectionMatch)
330
+ continue;
331
+ const sectionContent = sectionMatch[1];
332
+ parseLearningsSection(sectionContent, milestoneId, idPrefix, nodeType, milestoneNodeId, sourceFile, nodes, edges);
333
+ }
334
+ }
335
+ function parseLearningsSection(sectionContent, milestoneId, idPrefix, nodeType, milestoneNodeId, sourceFile, nodes, edges) {
336
+ // Each item is a bullet line starting with "- " followed by optional
337
+ // indented "Source: ..." line.
338
+ // We collect bullet items and their associated source attribution.
339
+ const lines = sectionContent.split('\n');
340
+ let itemIndex = 0;
341
+ let currentText = null;
342
+ let currentSource = null;
343
+ const flushItem = () => {
344
+ if (!currentText)
345
+ return;
346
+ itemIndex += 1;
347
+ const nodeId = `${idPrefix}:${milestoneId}:${itemIndex}`;
348
+ const description = currentSource ? `${currentSource}` : undefined;
349
+ nodes.push({
350
+ id: nodeId,
351
+ label: currentText,
352
+ type: nodeType,
353
+ description,
354
+ confidence: 'EXTRACTED',
355
+ sourceFile,
356
+ });
357
+ // Edge: milestone relates_to this learning node
358
+ edges.push({
359
+ from: milestoneNodeId,
360
+ to: nodeId,
361
+ type: 'relates_to',
362
+ confidence: 'EXTRACTED',
363
+ });
364
+ currentText = null;
365
+ currentSource = null;
366
+ };
367
+ for (const line of lines) {
368
+ const bulletMatch = line.match(/^[-*]\s+(.+)/);
369
+ if (bulletMatch) {
370
+ flushItem();
371
+ currentText = bulletMatch[1].trim();
372
+ continue;
373
+ }
374
+ // Indented source attribution: " Source: ..."
375
+ const sourceMatch = line.match(/^\s+Source:\s+(.+)/i);
376
+ if (sourceMatch && currentText !== null) {
377
+ currentSource = `Source: ${sourceMatch[1].trim()}`;
378
+ continue;
379
+ }
380
+ // Continuation of current item text (indented non-source line)
381
+ const continuationMatch = line.match(/^\s{2,}(.+)/);
382
+ if (continuationMatch && currentText !== null && currentSource === null) {
383
+ currentText += ' ' + continuationMatch[1].trim();
384
+ }
385
+ }
386
+ flushItem();
387
+ }
388
+ // ---------------------------------------------------------------------------
283
389
  // buildGraph
284
390
  // ---------------------------------------------------------------------------
285
391
  /**
@@ -297,6 +403,7 @@ export async function buildGraph(projectDir) {
297
403
  parseStateFile,
298
404
  parseKnowledgeFile,
299
405
  parseMilestoneFiles,
406
+ parseLearningsFiles,
300
407
  ];
301
408
  for (const parser of parsers) {
302
409
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/readers/graph.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,4DAA4D;AAE5D;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAyElH,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,SAAS,SAAS,CAAC,OAAe;IAChC,OAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,2BAA2B,CAAC,CAAC;AAC/D,CAAC;AAED,8EAA8E;AAC9E,sDAAsD;AACtD,8EAA8E;AAE9E;;GAEG;AACH,SAAS,cAAc,CAAC,OAAe,EAAE,KAAkB,EAAE,MAAmB;IAC9E,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO;IAEnC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,2BAA2B;IAC3B,MAAM,oBAAoB,GAAG,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC9F,IAAI,oBAAoB,EAAE,CAAC;QACzB,MAAM,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,oBAAoB,CAAC;QACpD,MAAM,EAAE,GAAG,aAAa,WAAW,EAAE,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE;gBACF,KAAK,EAAE,GAAG,WAAW,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE;gBACxC,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,qBAAqB,WAAW,EAAE;gBAC/C,UAAU,EAAE,WAAW;gBACvB,UAAU,EAAE,UAAU;aACvB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC5D,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,iBAAiB,KAAK,EAAE;YAC5B,KAAK,EAAE,UAAU,KAAK,EAAE;YACxB,IAAI,EAAE,SAAS;YACf,UAAU,EAAE,WAAW;YACvB,UAAU,EAAE,UAAU;SACvB,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,OAAe,EAAE,KAAkB,EAAE,MAAmB;IAClF,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO;IAEvC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,oBAAoB;IACpB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACxE,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,SAAS;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC/B,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACnE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAE,SAAS;YAClC,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,QAAQ,EAAE,EAAE;gBAChB,KAAK,EAAE,EAAE;gBACT,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC3B,UAAU,EAAE,WAAW;gBACvB,UAAU,EAAE,cAAc;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC9E,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,SAAS;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC/B,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACnE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAE,SAAS;YAClC,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,WAAW,EAAE,EAAE;gBACnB,KAAK,EAAE,EAAE;gBACT,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC3B,UAAU,EAAE,WAAW;gBACvB,UAAU,EAAE,cAAc;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACpF,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,SAAS;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC/B,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACnE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAE,SAAS;YAClC,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,UAAU,EAAE,EAAE;gBAClB,KAAK,EAAE,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC3B,UAAU,EAAE,WAAW;gBACvB,UAAU,EAAE,cAAc;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,OAAe,EACf,KAAkB,EAClB,KAAkB;IAElB,MAAM,YAAY,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE/C,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAC3B,OAAe,EACf,WAAmB,EACnB,KAAkB,EAClB,KAAkB;IAElB,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,eAAe,GAAG,aAAa,WAAW,EAAE,CAAC;IAEnD,+BAA+B;IAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,WAAW,aAAa,CAAC,CAAC;IAC5D,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,cAAc,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,IAAI,cAAc,GAAG,WAAW,CAAC;IACjC,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAClE,IAAI,UAAU;YAAE,cAAc,GAAG,GAAG,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IAC7E,CAAC;IAED,+BAA+B;IAC/B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,EAAE,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,eAAe;YACnB,KAAK,EAAE,cAAc;YACrB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,WAAW;YACvB,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,cAAc,WAAW,IAAI,WAAW,aAAa,CAAC,CAAC,CAAC,SAAS;SAC/F,CAAC,CAAC;IACL,CAAC;IAED,gDAAgD;IAChD,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACpD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACjF,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,OAAe,EACf,WAAmB,EACnB,OAAe,EACf,eAAuB,EACvB,KAAkB,EAClB,KAAkB;IAElB,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,WAAW,GAAG,SAAS,WAAW,IAAI,OAAO,EAAE,CAAC;IAEtD,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,UAAU,CAAC,CAAC;IAClD,IAAI,UAAU,GAAG,GAAG,WAAW,IAAI,OAAO,EAAE,CAAC;IAC7C,IAAI,WAAW,GAAkB,IAAI,CAAC;IAEtC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAC/D,IAAI,UAAU;gBAAE,UAAU,GAAG,GAAG,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC;QACT,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,UAAU;QACjB,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,WAAW;QACvB,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,cAAc,WAAW,WAAW,OAAO,IAAI,OAAO,UAAU,CAAC,CAAC,CAAC,SAAS;KACvG,CAAC,CAAC;IAEH,iCAAiC;IACjC,KAAK,CAAC,IAAI,CAAC;QACT,IAAI,EAAE,eAAe;QACrB,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,WAAW;KACxB,CAAC,CAAC;IAEH,kCAAkC;IAClC,IAAI,WAAW,EAAE,CAAC;QAChB,kBAAkB,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACnF,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,OAAe,EACf,WAAmB,EACnB,OAAe,EACf,WAAmB,EACnB,KAAkB,EAClB,KAAkB;IAElB,uDAAuD;IACvD,MAAM,WAAW,GAAG,8CAA8C,CAAC;IACnE,IAAI,KAA6B,CAAC;IAElC,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;QACpC,MAAM,UAAU,GAAG,QAAQ,WAAW,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;QAE9D,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,UAAU;YACd,KAAK,EAAE,GAAG,MAAM,KAAK,SAAS,CAAC,IAAI,EAAE,EAAE;YACvC,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,WAAW;SACxB,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,WAAW;YACjB,EAAE,EAAE,UAAU;YACd,IAAI,EAAE,UAAU;YAChB,UAAU,EAAE,WAAW;SACxB,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAEpD,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,8DAA8D;IAC9D,MAAM,OAAO,GAA+D;QAC1E,cAAc;QACd,kBAAkB;QAClB,mBAAmB;KACpB,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,wDAAwD;YACxD,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,SAAS,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;gBACxC,KAAK,EAAE,kBAAkB,MAAM,CAAC,IAAI,EAAE;gBACtC,IAAI,EAAE,SAAS;gBACf,UAAU,EAAE,WAAW;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACtC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,KAAK;QACL,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAClC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,6CAA6C;AAC7C,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,KAAqB;IACrE,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpC,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAErC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC5D,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO;IAE7B,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpC,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvC,IAAI,KAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAEpE,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACnF,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB;IAClD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;QAEhD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,QAAQ,GAAG,EAAE,CAAC;QAE5B,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,OAAO;YAClB,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;YAC7B,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;YAC7B,KAAK;YACL,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,uDAAuD;AACvD,8EAA8E;AAE9E;;;;;;GAMG;AACH,SAAS,WAAW,CAClB,KAAqB,EACrB,OAAoB,EACpB,MAAc;IAEd,oDAAoD;IACpD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,OAAO,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAE3B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBACrD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,IAAI,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACpD,CAAC;IAEF,0CAA0C;IAC1C,4CAA4C;IAC5C,MAAM,QAAQ,GAAG,GAAW,EAAE,CAC5B,WAAW,CAAC,MAAM,GAAG,EAAE,GAAG,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC;IAEpD,IAAI,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;QACxB,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,WAAW,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;QACxB,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;QACxB,6DAA6D;QAC7D,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,KAAK,WAAW,CAC3D,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAChD,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AACpD,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,UAAkB,EAClB,IAAY,EACZ,MAAM,GAAG,IAAI;IAEb,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,KAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAChC,mCAAmC;QACnC,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAEjC,sCAAsC;IACtC,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,KAAK,CAAC,KAAK;SACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;QACxE,OAAO,UAAU,IAAI,SAAS,CAAC;IACjC,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACpB,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACnD,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,UAAkB;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACpD,MAAM,KAAK,GAAoB;QAC7B,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QAC9C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;KAClC,CAAC;IAEF,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAEnC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAEpC,IAAI,OAAuB,CAAC;IAC5B,IAAI,QAAwB,CAAC;IAE7B,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAmB,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAmB,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/D,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvF,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAEzF,sDAAsD;IACtD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,OAAO,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,CAAC;IACtE,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAEpB,gDAAgD;IAChD,MAAM,OAAO,GAAG,CAAC,CAAY,EAAU,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACzE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5D,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9D,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/F,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAEjG,OAAO;QACL,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;QAClC,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE;KACpD,CAAC;AACJ,CAAC","sourcesContent":["// GSD MCP Server — knowledge graph reader\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\n/**\n * Knowledge Graph for GSD projects.\n *\n * Parses .gsd/ artifacts (STATE.md, milestone ROADMAPs, slice PLANs,\n * KNOWLEDGE.md) into a graph of nodes and edges. Parse errors in any\n * single artifact are caught and never propagate — the artifact is skipped\n * and the rest of the graph is returned.\n *\n * writeGraph() is atomic: writes to graph.tmp.json then renames to graph.json.\n */\n\nimport { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { resolveGsdRoot, findMilestoneIds, resolveMilestoneDir, findSliceIds, resolveSliceDir } from './paths.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type NodeType =\n | 'milestone'\n | 'slice'\n | 'task'\n | 'rule'\n | 'pattern'\n | 'lesson'\n | 'concept';\n\nexport type EdgeType =\n | 'contains'\n | 'depends_on'\n | 'relates_to'\n | 'implements';\n\nexport type ConfidenceTier = 'EXTRACTED' | 'INFERRED' | 'AMBIGUOUS';\n\nexport interface GraphNode {\n id: string;\n label: string;\n type: NodeType;\n description?: string;\n confidence: ConfidenceTier;\n sourceFile?: string;\n}\n\nexport interface GraphEdge {\n from: string;\n to: string;\n type: EdgeType;\n confidence: ConfidenceTier;\n}\n\nexport interface KnowledgeGraph {\n nodes: GraphNode[];\n edges: GraphEdge[];\n builtAt: string;\n}\n\nexport interface GraphStatusResult {\n exists: boolean;\n lastBuild?: string;\n nodeCount?: number;\n edgeCount?: number;\n stale?: boolean;\n ageHours?: number;\n}\n\nexport interface GraphQueryResult {\n nodes: GraphNode[];\n edges: GraphEdge[];\n term: string;\n budget: number;\n}\n\nexport interface GraphDiffResult {\n nodes: {\n added: string[];\n removed: string[];\n changed: string[];\n };\n edges: {\n added: string[];\n removed: string[];\n };\n}\n\n// ---------------------------------------------------------------------------\n// Graph file paths\n// ---------------------------------------------------------------------------\n\nfunction graphsDir(gsdRoot: string): string {\n return join(gsdRoot, 'graphs');\n}\n\nfunction graphJsonPath(gsdRoot: string): string {\n return join(graphsDir(gsdRoot), 'graph.json');\n}\n\nfunction graphTmpPath(gsdRoot: string): string {\n return join(graphsDir(gsdRoot), 'graph.tmp.json');\n}\n\nfunction snapshotPath(gsdRoot: string): string {\n return join(graphsDir(gsdRoot), '.last-build-snapshot.json');\n}\n\n// ---------------------------------------------------------------------------\n// Parsers — each returns nodes/edges and never throws\n// ---------------------------------------------------------------------------\n\n/**\n * Parse STATE.md for active milestone and phase concepts.\n */\nfunction parseStateFile(gsdRoot: string, nodes: GraphNode[], _edges: GraphEdge[]): void {\n const statePath = join(gsdRoot, 'STATE.md');\n if (!existsSync(statePath)) return;\n\n let content: string;\n try {\n content = readFileSync(statePath, 'utf-8');\n } catch {\n return;\n }\n\n // Extract active milestone\n const activeMilestoneMatch = content.match(/\\*\\*Active Milestone:\\*\\*\\s+([A-Z]\\d+):\\s+(.+)/i);\n if (activeMilestoneMatch) {\n const [, milestoneId, title] = activeMilestoneMatch;\n const id = `milestone:${milestoneId}`;\n if (!nodes.some((n) => n.id === id)) {\n nodes.push({\n id,\n label: `${milestoneId}: ${title.trim()}`,\n type: 'milestone',\n description: `Active milestone: ${milestoneId}`,\n confidence: 'EXTRACTED',\n sourceFile: 'STATE.md',\n });\n }\n }\n\n // Extract phase as concept\n const phaseMatch = content.match(/\\*\\*Phase:\\*\\*\\s+(\\S+)/i);\n if (phaseMatch) {\n const phase = phaseMatch[1].trim();\n nodes.push({\n id: `concept:phase:${phase}`,\n label: `Phase: ${phase}`,\n type: 'concept',\n confidence: 'EXTRACTED',\n sourceFile: 'STATE.md',\n });\n }\n}\n\n/**\n * Parse KNOWLEDGE.md for rules, patterns, and lessons.\n */\nfunction parseKnowledgeFile(gsdRoot: string, nodes: GraphNode[], _edges: GraphEdge[]): void {\n const knowledgePath = join(gsdRoot, 'KNOWLEDGE.md');\n if (!existsSync(knowledgePath)) return;\n\n let content: string;\n try {\n content = readFileSync(knowledgePath, 'utf-8');\n } catch {\n return;\n }\n\n // Parse Rules table\n const rulesMatch = content.match(/## Rules\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i);\n if (rulesMatch) {\n for (const line of rulesMatch[1].split('\\n')) {\n if (!line.includes('|')) continue;\n const cells = line.split('|').map((c) => c.trim()).filter(Boolean);\n if (cells.length < 3) continue;\n if (cells[0].startsWith('#') || cells[0].startsWith('-')) continue;\n const id = cells[0];\n if (!/^K\\d+$/i.test(id)) continue;\n nodes.push({\n id: `rule:${id}`,\n label: id,\n type: 'rule',\n description: cells[2] ?? '',\n confidence: 'EXTRACTED',\n sourceFile: 'KNOWLEDGE.md',\n });\n }\n }\n\n // Parse Patterns table\n const patternsMatch = content.match(/## Patterns\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i);\n if (patternsMatch) {\n for (const line of patternsMatch[1].split('\\n')) {\n if (!line.includes('|')) continue;\n const cells = line.split('|').map((c) => c.trim()).filter(Boolean);\n if (cells.length < 2) continue;\n if (cells[0].startsWith('#') || cells[0].startsWith('-')) continue;\n const id = cells[0];\n if (!/^P\\d+$/i.test(id)) continue;\n nodes.push({\n id: `pattern:${id}`,\n label: id,\n type: 'pattern',\n description: cells[1] ?? '',\n confidence: 'EXTRACTED',\n sourceFile: 'KNOWLEDGE.md',\n });\n }\n }\n\n // Parse Lessons Learned table\n const lessonsMatch = content.match(/## Lessons Learned\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i);\n if (lessonsMatch) {\n for (const line of lessonsMatch[1].split('\\n')) {\n if (!line.includes('|')) continue;\n const cells = line.split('|').map((c) => c.trim()).filter(Boolean);\n if (cells.length < 2) continue;\n if (cells[0].startsWith('#') || cells[0].startsWith('-')) continue;\n const id = cells[0];\n if (!/^L\\d+$/i.test(id)) continue;\n nodes.push({\n id: `lesson:${id}`,\n label: id,\n type: 'lesson',\n description: cells[1] ?? '',\n confidence: 'EXTRACTED',\n sourceFile: 'KNOWLEDGE.md',\n });\n }\n }\n}\n\n/**\n * Parse milestone ROADMAP.md files for milestones and slices.\n */\nfunction parseMilestoneFiles(\n gsdRoot: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n const milestoneIds = findMilestoneIds(gsdRoot);\n\n for (const milestoneId of milestoneIds) {\n try {\n parseSingleMilestone(gsdRoot, milestoneId, nodes, edges);\n } catch {\n // Skip this milestone on any error\n }\n }\n}\n\nfunction parseSingleMilestone(\n gsdRoot: string,\n milestoneId: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n const mDir = resolveMilestoneDir(gsdRoot, milestoneId);\n if (!mDir) return;\n\n const milestoneNodeId = `milestone:${milestoneId}`;\n\n // Try to read the roadmap file\n const roadmapPath = join(mDir, `${milestoneId}-ROADMAP.md`);\n let roadmapContent: string | null = null;\n if (existsSync(roadmapPath)) {\n try {\n roadmapContent = readFileSync(roadmapPath, 'utf-8');\n } catch {\n // Skip\n }\n }\n\n // Extract milestone title from roadmap\n let milestoneTitle = milestoneId;\n if (roadmapContent) {\n const titleMatch = roadmapContent.match(/^#\\s+[A-Z]\\d+:\\s+(.+)/m);\n if (titleMatch) milestoneTitle = `${milestoneId}: ${titleMatch[1].trim()}`;\n }\n\n // Ensure milestone node exists\n if (!nodes.some((n) => n.id === milestoneNodeId)) {\n nodes.push({\n id: milestoneNodeId,\n label: milestoneTitle,\n type: 'milestone',\n confidence: 'EXTRACTED',\n sourceFile: roadmapContent ? `milestones/${milestoneId}/${milestoneId}-ROADMAP.md` : undefined,\n });\n }\n\n // Parse slices from roadmap table or filesystem\n const sliceIds = findSliceIds(gsdRoot, milestoneId);\n for (const sliceId of sliceIds) {\n try {\n parseSingleSlice(gsdRoot, milestoneId, sliceId, milestoneNodeId, nodes, edges);\n } catch {\n // Skip this slice on any error\n }\n }\n}\n\nfunction parseSingleSlice(\n gsdRoot: string,\n milestoneId: string,\n sliceId: string,\n milestoneNodeId: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n const sDir = resolveSliceDir(gsdRoot, milestoneId, sliceId);\n if (!sDir) return;\n\n const sliceNodeId = `slice:${milestoneId}:${sliceId}`;\n\n // Try to read the slice plan\n const planPath = join(sDir, `${sliceId}-PLAN.md`);\n let sliceTitle = `${milestoneId}/${sliceId}`;\n let planContent: string | null = null;\n\n if (existsSync(planPath)) {\n try {\n planContent = readFileSync(planPath, 'utf-8');\n const titleMatch = planContent.match(/^#\\s+[A-Z]\\d+:\\s+(.+)/m);\n if (titleMatch) sliceTitle = `${sliceId}: ${titleMatch[1].trim()}`;\n } catch {\n // Use default title\n }\n }\n\n nodes.push({\n id: sliceNodeId,\n label: sliceTitle,\n type: 'slice',\n confidence: 'EXTRACTED',\n sourceFile: planContent ? `milestones/${milestoneId}/slices/${sliceId}/${sliceId}-PLAN.md` : undefined,\n });\n\n // Edge: milestone contains slice\n edges.push({\n from: milestoneNodeId,\n to: sliceNodeId,\n type: 'contains',\n confidence: 'EXTRACTED',\n });\n\n // Parse tasks from the slice plan\n if (planContent) {\n parseTasksFromPlan(planContent, milestoneId, sliceId, sliceNodeId, nodes, edges);\n }\n}\n\nfunction parseTasksFromPlan(\n content: string,\n milestoneId: string,\n sliceId: string,\n sliceNodeId: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n // Match lines like: - [ ] **T01: Title** — description\n const taskPattern = /[-*]\\s+\\[[ x]\\]\\s+\\*\\*(T\\d+):\\s*([^*]+)\\*\\*/g;\n let match: RegExpExecArray | null;\n\n while ((match = taskPattern.exec(content)) !== null) {\n const [, taskId, taskTitle] = match;\n const taskNodeId = `task:${milestoneId}:${sliceId}:${taskId}`;\n\n nodes.push({\n id: taskNodeId,\n label: `${taskId}: ${taskTitle.trim()}`,\n type: 'task',\n confidence: 'EXTRACTED',\n });\n\n edges.push({\n from: sliceNodeId,\n to: taskNodeId,\n type: 'contains',\n confidence: 'EXTRACTED',\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// buildGraph\n// ---------------------------------------------------------------------------\n\n/**\n * Build a KnowledgeGraph by parsing all .gsd/ artifacts.\n *\n * Parse errors in any single artifact are caught — the artifact is skipped\n * and never causes buildGraph() to throw.\n */\nexport async function buildGraph(projectDir: string): Promise<KnowledgeGraph> {\n const gsdRoot = resolveGsdRoot(resolve(projectDir));\n\n const nodes: GraphNode[] = [];\n const edges: GraphEdge[] = [];\n\n // Each parser is wrapped so a crash in one never stops others\n const parsers: Array<(g: string, n: GraphNode[], e: GraphEdge[]) => void> = [\n parseStateFile,\n parseKnowledgeFile,\n parseMilestoneFiles,\n ];\n\n for (const parser of parsers) {\n try {\n parser(gsdRoot, nodes, edges);\n } catch {\n // Parsing error — skip this artifact, mark as ambiguous\n nodes.push({\n id: `error:${parser.name}:${Date.now()}`,\n label: `Parse error in ${parser.name}`,\n type: 'concept',\n confidence: 'AMBIGUOUS',\n });\n }\n }\n\n // Deduplicate nodes by id (keep first occurrence)\n const seen = new Set<string>();\n const dedupedNodes = nodes.filter((n) => {\n if (seen.has(n.id)) return false;\n seen.add(n.id);\n return true;\n });\n\n return {\n nodes: dedupedNodes,\n edges,\n builtAt: new Date().toISOString(),\n };\n}\n\n// ---------------------------------------------------------------------------\n// writeGraph — atomic write via tmp + rename\n// ---------------------------------------------------------------------------\n\n/**\n * Write the graph to .gsd/graphs/graph.json atomically.\n *\n * Writes to graph.tmp.json first, then renames to graph.json.\n * Creates the graphs/ directory if it does not exist.\n */\nexport async function writeGraph(gsdRoot: string, graph: KnowledgeGraph): Promise<void> {\n const dir = graphsDir(gsdRoot);\n mkdirSync(dir, { recursive: true });\n\n const tmp = graphTmpPath(gsdRoot);\n const final = graphJsonPath(gsdRoot);\n\n writeFileSync(tmp, JSON.stringify(graph, null, 2), 'utf-8');\n renameSync(tmp, final);\n}\n\n// ---------------------------------------------------------------------------\n// writeSnapshot\n// ---------------------------------------------------------------------------\n\n/**\n * Copy the current graph.json to .last-build-snapshot.json.\n * Adds a snapshotAt timestamp to the copy.\n */\nexport async function writeSnapshot(gsdRoot: string): Promise<void> {\n const src = graphJsonPath(gsdRoot);\n if (!existsSync(src)) return;\n\n const dir = graphsDir(gsdRoot);\n mkdirSync(dir, { recursive: true });\n\n const raw = readFileSync(src, 'utf-8');\n let graph: KnowledgeGraph;\n try {\n graph = JSON.parse(raw) as KnowledgeGraph;\n } catch {\n return;\n }\n const snapshot = { ...graph, snapshotAt: new Date().toISOString() };\n\n writeFileSync(snapshotPath(gsdRoot), JSON.stringify(snapshot, null, 2), 'utf-8');\n}\n\n// ---------------------------------------------------------------------------\n// graphStatus\n// ---------------------------------------------------------------------------\n\n/**\n * Return status of the graph: whether it exists, its age, and whether it is stale.\n * Stale means builtAt is older than 24 hours.\n */\nexport async function graphStatus(projectDir: string): Promise<GraphStatusResult> {\n const gsdRoot = resolveGsdRoot(resolve(projectDir));\n const graphPath = graphJsonPath(gsdRoot);\n\n if (!existsSync(graphPath)) {\n return { exists: false };\n }\n\n try {\n const raw = readFileSync(graphPath, 'utf-8');\n const graph = JSON.parse(raw) as KnowledgeGraph;\n\n const builtAt = graph.builtAt;\n const ageMs = Date.now() - new Date(builtAt).getTime();\n const ageHours = ageMs / (1000 * 60 * 60);\n const stale = ageHours > 24;\n\n return {\n exists: true,\n lastBuild: builtAt,\n nodeCount: graph.nodes.length,\n edgeCount: graph.edges.length,\n stale,\n ageHours,\n };\n } catch {\n return { exists: false };\n }\n}\n\n// ---------------------------------------------------------------------------\n// applyBudget — trim edges to stay within token budget\n// ---------------------------------------------------------------------------\n\n/**\n * Given a set of seed node IDs and the full graph, apply BFS to collect\n * reachable nodes and edges. Trims AMBIGUOUS edges first, then INFERRED,\n * stopping when the estimated token count drops within budget.\n *\n * Budget is a rough token estimate: 1 node ≈ 20 tokens, 1 edge ≈ 10 tokens.\n */\nfunction applyBudget(\n graph: KnowledgeGraph,\n seedIds: Set<string>,\n budget: number,\n): { nodes: GraphNode[]; edges: GraphEdge[] } {\n // BFS to collect reachable nodes (start from seeds)\n const reachable = new Set<string>(seedIds);\n const queue = [...seedIds];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const edge of graph.edges) {\n if (edge.from === current && !reachable.has(edge.to)) {\n reachable.add(edge.to);\n queue.push(edge.to);\n }\n }\n }\n\n let resultNodes = graph.nodes.filter((n) => reachable.has(n.id));\n let resultEdges = graph.edges.filter(\n (e) => reachable.has(e.from) && reachable.has(e.to),\n );\n\n // Estimate tokens and trim if over budget\n // Trim AMBIGUOUS edges first, then INFERRED\n const estimate = (): number =>\n resultNodes.length * 20 + resultEdges.length * 10;\n\n if (estimate() > budget) {\n resultEdges = resultEdges.filter((e) => e.confidence !== 'AMBIGUOUS');\n }\n if (estimate() > budget) {\n resultEdges = resultEdges.filter((e) => e.confidence !== 'INFERRED');\n }\n if (estimate() > budget) {\n // Hard trim — keep only seed nodes and their EXTRACTED edges\n const seedNodes = resultNodes.filter((n) => seedIds.has(n.id));\n const seedEdges = resultEdges.filter(\n (e) => seedIds.has(e.from) && e.confidence === 'EXTRACTED',\n );\n return { nodes: seedNodes, edges: seedEdges };\n }\n\n return { nodes: resultNodes, edges: resultEdges };\n}\n\n// ---------------------------------------------------------------------------\n// graphQuery\n// ---------------------------------------------------------------------------\n\n/**\n * Query the graph for nodes matching a term (case-insensitive on label + description).\n * BFS from seed nodes, applying budget trimming.\n *\n * Reads from the pre-built graph.json. Falls back to an empty result if no\n * graph exists.\n */\nexport async function graphQuery(\n projectDir: string,\n term: string,\n budget = 4000,\n): Promise<GraphQueryResult> {\n const gsdRoot = resolveGsdRoot(resolve(projectDir));\n const graphPath = graphJsonPath(gsdRoot);\n\n if (!existsSync(graphPath)) {\n return { nodes: [], edges: [], term, budget };\n }\n\n let graph: KnowledgeGraph;\n try {\n const raw = readFileSync(graphPath, 'utf-8');\n graph = JSON.parse(raw) as KnowledgeGraph;\n } catch {\n return { nodes: [], edges: [], term, budget };\n }\n\n if (!term || term.trim() === '') {\n // Empty term — return empty result\n return { nodes: [], edges: [], term, budget };\n }\n\n const lower = term.toLowerCase();\n\n // Find seed nodes that match the term\n const seedIds = new Set<string>(\n graph.nodes\n .filter((n) => {\n const labelMatch = n.label.toLowerCase().includes(lower);\n const descMatch = n.description?.toLowerCase().includes(lower) ?? false;\n return labelMatch || descMatch;\n })\n .map((n) => n.id),\n );\n\n if (seedIds.size === 0) {\n return { nodes: [], edges: [], term, budget };\n }\n\n const result = applyBudget(graph, seedIds, budget);\n return { ...result, term, budget };\n}\n\n// ---------------------------------------------------------------------------\n// graphDiff\n// ---------------------------------------------------------------------------\n\n/**\n * Compare the current graph.json with .last-build-snapshot.json.\n * Returns added/removed/changed nodes and added/removed edges.\n *\n * If no snapshot exists, returns empty diff arrays.\n */\nexport async function graphDiff(projectDir: string): Promise<GraphDiffResult> {\n const gsdRoot = resolveGsdRoot(resolve(projectDir));\n const empty: GraphDiffResult = {\n nodes: { added: [], removed: [], changed: [] },\n edges: { added: [], removed: [] },\n };\n\n const graphPath = graphJsonPath(gsdRoot);\n const snap = snapshotPath(gsdRoot);\n\n if (!existsSync(graphPath)) return empty;\n if (!existsSync(snap)) return empty;\n\n let current: KnowledgeGraph;\n let snapshot: KnowledgeGraph;\n\n try {\n current = JSON.parse(readFileSync(graphPath, 'utf-8')) as KnowledgeGraph;\n } catch {\n return empty;\n }\n\n try {\n snapshot = JSON.parse(readFileSync(snap, 'utf-8')) as KnowledgeGraph;\n } catch {\n return empty;\n }\n\n const currentNodeIds = new Set(current.nodes.map((n) => n.id));\n const snapshotNodeIds = new Set(snapshot.nodes.map((n) => n.id));\n\n const added = current.nodes.filter((n) => !snapshotNodeIds.has(n.id)).map((n) => n.id);\n const removed = snapshot.nodes.filter((n) => !currentNodeIds.has(n.id)).map((n) => n.id);\n\n // Changed: same id but different label or description\n const snapshotNodeMap = new Map(snapshot.nodes.map((n) => [n.id, n]));\n const changed = current.nodes\n .filter((n) => {\n const snap = snapshotNodeMap.get(n.id);\n if (!snap) return false;\n return n.label !== snap.label || n.description !== snap.description;\n })\n .map((n) => n.id);\n\n // Edges — compare by string key \"from->to:type\"\n const edgeKey = (e: GraphEdge): string => `${e.from}->${e.to}:${e.type}`;\n const currentEdgeKeys = new Set(current.edges.map(edgeKey));\n const snapshotEdgeKeys = new Set(snapshot.edges.map(edgeKey));\n\n const edgesAdded = current.edges.filter((e) => !snapshotEdgeKeys.has(edgeKey(e))).map(edgeKey);\n const edgesRemoved = snapshot.edges.filter((e) => !currentEdgeKeys.has(edgeKey(e))).map(edgeKey);\n\n return {\n nodes: { added, removed, changed },\n edges: { added: edgesAdded, removed: edgesRemoved },\n };\n}\n"]}
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/readers/graph.ts"],"names":[],"mappings":"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","sourcesContent":["// GSD MCP Server — knowledge graph reader\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\n/**\n * Knowledge Graph for GSD projects.\n *\n * Parses .gsd/ artifacts (STATE.md, milestone ROADMAPs, slice PLANs,\n * KNOWLEDGE.md) into a graph of nodes and edges. Parse errors in any\n * single artifact are caught and never propagate — the artifact is skipped\n * and the rest of the graph is returned.\n *\n * writeGraph() is atomic: writes to graph.tmp.json then renames to graph.json.\n */\n\nimport { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { resolveGsdRoot, findMilestoneIds, resolveMilestoneDir, findSliceIds, resolveSliceDir } from './paths.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type NodeType =\n | 'milestone'\n | 'slice'\n | 'task'\n | 'rule'\n | 'pattern'\n | 'lesson'\n | 'concept'\n | 'decision';\n\nexport type EdgeType =\n | 'contains'\n | 'depends_on'\n | 'relates_to'\n | 'implements';\n\nexport type ConfidenceTier = 'EXTRACTED' | 'INFERRED' | 'AMBIGUOUS';\n\nexport interface GraphNode {\n id: string;\n label: string;\n type: NodeType;\n description?: string;\n confidence: ConfidenceTier;\n sourceFile?: string;\n}\n\nexport interface GraphEdge {\n from: string;\n to: string;\n type: EdgeType;\n confidence: ConfidenceTier;\n}\n\nexport interface KnowledgeGraph {\n nodes: GraphNode[];\n edges: GraphEdge[];\n builtAt: string;\n}\n\nexport interface GraphStatusResult {\n exists: boolean;\n lastBuild?: string;\n nodeCount?: number;\n edgeCount?: number;\n stale?: boolean;\n ageHours?: number;\n}\n\nexport interface GraphQueryResult {\n nodes: GraphNode[];\n edges: GraphEdge[];\n term: string;\n budget: number;\n}\n\nexport interface GraphDiffResult {\n nodes: {\n added: string[];\n removed: string[];\n changed: string[];\n };\n edges: {\n added: string[];\n removed: string[];\n };\n}\n\n// ---------------------------------------------------------------------------\n// Graph file paths\n// ---------------------------------------------------------------------------\n\nfunction graphsDir(gsdRoot: string): string {\n return join(gsdRoot, 'graphs');\n}\n\nfunction graphJsonPath(gsdRoot: string): string {\n return join(graphsDir(gsdRoot), 'graph.json');\n}\n\nfunction graphTmpPath(gsdRoot: string): string {\n return join(graphsDir(gsdRoot), 'graph.tmp.json');\n}\n\nfunction snapshotPath(gsdRoot: string): string {\n return join(graphsDir(gsdRoot), '.last-build-snapshot.json');\n}\n\n// ---------------------------------------------------------------------------\n// Parsers — each returns nodes/edges and never throws\n// ---------------------------------------------------------------------------\n\n/**\n * Parse STATE.md for active milestone and phase concepts.\n */\nfunction parseStateFile(gsdRoot: string, nodes: GraphNode[], _edges: GraphEdge[]): void {\n const statePath = join(gsdRoot, 'STATE.md');\n if (!existsSync(statePath)) return;\n\n let content: string;\n try {\n content = readFileSync(statePath, 'utf-8');\n } catch {\n return;\n }\n\n // Extract active milestone\n const activeMilestoneMatch = content.match(/\\*\\*Active Milestone:\\*\\*\\s+([A-Z]\\d+):\\s+(.+)/i);\n if (activeMilestoneMatch) {\n const [, milestoneId, title] = activeMilestoneMatch;\n const id = `milestone:${milestoneId}`;\n if (!nodes.some((n) => n.id === id)) {\n nodes.push({\n id,\n label: `${milestoneId}: ${title.trim()}`,\n type: 'milestone',\n description: `Active milestone: ${milestoneId}`,\n confidence: 'EXTRACTED',\n sourceFile: 'STATE.md',\n });\n }\n }\n\n // Extract phase as concept\n const phaseMatch = content.match(/\\*\\*Phase:\\*\\*\\s+(\\S+)/i);\n if (phaseMatch) {\n const phase = phaseMatch[1].trim();\n nodes.push({\n id: `concept:phase:${phase}`,\n label: `Phase: ${phase}`,\n type: 'concept',\n confidence: 'EXTRACTED',\n sourceFile: 'STATE.md',\n });\n }\n}\n\n/**\n * Parse KNOWLEDGE.md for rules, patterns, and lessons.\n */\nfunction parseKnowledgeFile(gsdRoot: string, nodes: GraphNode[], _edges: GraphEdge[]): void {\n const knowledgePath = join(gsdRoot, 'KNOWLEDGE.md');\n if (!existsSync(knowledgePath)) return;\n\n let content: string;\n try {\n content = readFileSync(knowledgePath, 'utf-8');\n } catch {\n return;\n }\n\n // Parse Rules table\n const rulesMatch = content.match(/## Rules\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i);\n if (rulesMatch) {\n for (const line of rulesMatch[1].split('\\n')) {\n if (!line.includes('|')) continue;\n const cells = line.split('|').map((c) => c.trim()).filter(Boolean);\n if (cells.length < 3) continue;\n if (cells[0].startsWith('#') || cells[0].startsWith('-')) continue;\n const id = cells[0];\n if (!/^K\\d+$/i.test(id)) continue;\n nodes.push({\n id: `rule:${id}`,\n label: id,\n type: 'rule',\n description: cells[2] ?? '',\n confidence: 'EXTRACTED',\n sourceFile: 'KNOWLEDGE.md',\n });\n }\n }\n\n // Parse Patterns table\n const patternsMatch = content.match(/## Patterns\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i);\n if (patternsMatch) {\n for (const line of patternsMatch[1].split('\\n')) {\n if (!line.includes('|')) continue;\n const cells = line.split('|').map((c) => c.trim()).filter(Boolean);\n if (cells.length < 2) continue;\n if (cells[0].startsWith('#') || cells[0].startsWith('-')) continue;\n const id = cells[0];\n if (!/^P\\d+$/i.test(id)) continue;\n nodes.push({\n id: `pattern:${id}`,\n label: id,\n type: 'pattern',\n description: cells[1] ?? '',\n confidence: 'EXTRACTED',\n sourceFile: 'KNOWLEDGE.md',\n });\n }\n }\n\n // Parse Lessons Learned table\n const lessonsMatch = content.match(/## Lessons Learned\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i);\n if (lessonsMatch) {\n for (const line of lessonsMatch[1].split('\\n')) {\n if (!line.includes('|')) continue;\n const cells = line.split('|').map((c) => c.trim()).filter(Boolean);\n if (cells.length < 2) continue;\n if (cells[0].startsWith('#') || cells[0].startsWith('-')) continue;\n const id = cells[0];\n if (!/^L\\d+$/i.test(id)) continue;\n nodes.push({\n id: `lesson:${id}`,\n label: id,\n type: 'lesson',\n description: cells[1] ?? '',\n confidence: 'EXTRACTED',\n sourceFile: 'KNOWLEDGE.md',\n });\n }\n }\n}\n\n/**\n * Parse milestone ROADMAP.md files for milestones and slices.\n */\nfunction parseMilestoneFiles(\n gsdRoot: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n const milestoneIds = findMilestoneIds(gsdRoot);\n\n for (const milestoneId of milestoneIds) {\n try {\n parseSingleMilestone(gsdRoot, milestoneId, nodes, edges);\n } catch {\n // Skip this milestone on any error\n }\n }\n}\n\nfunction parseSingleMilestone(\n gsdRoot: string,\n milestoneId: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n const mDir = resolveMilestoneDir(gsdRoot, milestoneId);\n if (!mDir) return;\n\n const milestoneNodeId = `milestone:${milestoneId}`;\n\n // Try to read the roadmap file\n const roadmapPath = join(mDir, `${milestoneId}-ROADMAP.md`);\n let roadmapContent: string | null = null;\n if (existsSync(roadmapPath)) {\n try {\n roadmapContent = readFileSync(roadmapPath, 'utf-8');\n } catch {\n // Skip\n }\n }\n\n // Extract milestone title from roadmap\n let milestoneTitle = milestoneId;\n if (roadmapContent) {\n const titleMatch = roadmapContent.match(/^#\\s+[A-Z]\\d+:\\s+(.+)/m);\n if (titleMatch) milestoneTitle = `${milestoneId}: ${titleMatch[1].trim()}`;\n }\n\n // Ensure milestone node exists\n if (!nodes.some((n) => n.id === milestoneNodeId)) {\n nodes.push({\n id: milestoneNodeId,\n label: milestoneTitle,\n type: 'milestone',\n confidence: 'EXTRACTED',\n sourceFile: roadmapContent ? `milestones/${milestoneId}/${milestoneId}-ROADMAP.md` : undefined,\n });\n }\n\n // Parse slices from roadmap table or filesystem\n const sliceIds = findSliceIds(gsdRoot, milestoneId);\n for (const sliceId of sliceIds) {\n try {\n parseSingleSlice(gsdRoot, milestoneId, sliceId, milestoneNodeId, nodes, edges);\n } catch {\n // Skip this slice on any error\n }\n }\n}\n\nfunction parseSingleSlice(\n gsdRoot: string,\n milestoneId: string,\n sliceId: string,\n milestoneNodeId: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n const sDir = resolveSliceDir(gsdRoot, milestoneId, sliceId);\n if (!sDir) return;\n\n const sliceNodeId = `slice:${milestoneId}:${sliceId}`;\n\n // Try to read the slice plan\n const planPath = join(sDir, `${sliceId}-PLAN.md`);\n let sliceTitle = `${milestoneId}/${sliceId}`;\n let planContent: string | null = null;\n\n if (existsSync(planPath)) {\n try {\n planContent = readFileSync(planPath, 'utf-8');\n const titleMatch = planContent.match(/^#\\s+[A-Z]\\d+:\\s+(.+)/m);\n if (titleMatch) sliceTitle = `${sliceId}: ${titleMatch[1].trim()}`;\n } catch {\n // Use default title\n }\n }\n\n nodes.push({\n id: sliceNodeId,\n label: sliceTitle,\n type: 'slice',\n confidence: 'EXTRACTED',\n sourceFile: planContent ? `milestones/${milestoneId}/slices/${sliceId}/${sliceId}-PLAN.md` : undefined,\n });\n\n // Edge: milestone contains slice\n edges.push({\n from: milestoneNodeId,\n to: sliceNodeId,\n type: 'contains',\n confidence: 'EXTRACTED',\n });\n\n // Parse tasks from the slice plan\n if (planContent) {\n parseTasksFromPlan(planContent, milestoneId, sliceId, sliceNodeId, nodes, edges);\n }\n}\n\nfunction parseTasksFromPlan(\n content: string,\n milestoneId: string,\n sliceId: string,\n sliceNodeId: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n // Match lines like: - [ ] **T01: Title** — description\n const taskPattern = /[-*]\\s+\\[[ x]\\]\\s+\\*\\*(T\\d+):\\s*([^*]+)\\*\\*/g;\n let match: RegExpExecArray | null;\n\n while ((match = taskPattern.exec(content)) !== null) {\n const [, taskId, taskTitle] = match;\n const taskNodeId = `task:${milestoneId}:${sliceId}:${taskId}`;\n\n nodes.push({\n id: taskNodeId,\n label: `${taskId}: ${taskTitle.trim()}`,\n type: 'task',\n confidence: 'EXTRACTED',\n });\n\n edges.push({\n from: sliceNodeId,\n to: taskNodeId,\n type: 'contains',\n confidence: 'EXTRACTED',\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// LEARNINGS.md parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse all *-LEARNINGS.md files found in milestone directories.\n * Extracts Decisions, Lessons, Patterns, and Surprises as typed graph nodes.\n * Surprises are mapped to the 'lesson' NodeType (no distinct type exists).\n * Parse errors per file are caught — the file is skipped, never rethrows.\n */\nfunction parseLearningsFiles(gsdRoot: string, nodes: GraphNode[], edges: GraphEdge[]): void {\n const milestoneIds = findMilestoneIds(gsdRoot);\n\n for (const milestoneId of milestoneIds) {\n try {\n parseSingleLearningsFile(gsdRoot, milestoneId, nodes, edges);\n } catch {\n // Skip this milestone's LEARNINGS.md on any error\n }\n }\n}\n\nfunction parseSingleLearningsFile(\n gsdRoot: string,\n milestoneId: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n const mDir = resolveMilestoneDir(gsdRoot, milestoneId);\n if (!mDir) return;\n\n const learningsPath = join(mDir, `${milestoneId}-LEARNINGS.md`);\n if (!existsSync(learningsPath)) return;\n\n let content: string;\n try {\n content = readFileSync(learningsPath, 'utf-8');\n } catch {\n return;\n }\n\n // Strip YAML frontmatter if present\n const withoutFrontmatter = content.replace(/^---[\\s\\S]*?---\\n?/, '');\n\n const milestoneNodeId = `milestone:${milestoneId}`;\n const sourceFile = `milestones/${milestoneId}/${milestoneId}-LEARNINGS.md`;\n\n // Parse each section: [sectionName, nodeType, idPrefix]\n const sections: Array<[string, NodeType, string]> = [\n ['Decisions', 'decision', 'decision'],\n ['Lessons', 'lesson', 'lesson'],\n ['Patterns', 'pattern', 'pattern'],\n ['Surprises', 'lesson', 'surprise'],\n ];\n\n for (const [sectionName, nodeType, idPrefix] of sections) {\n const sectionMatch = withoutFrontmatter.match(\n new RegExp(`##\\\\s+${sectionName}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n##\\\\s|$)`, 'i'),\n );\n if (!sectionMatch) continue;\n\n const sectionContent = sectionMatch[1];\n parseLearningsSection(\n sectionContent,\n milestoneId,\n idPrefix,\n nodeType,\n milestoneNodeId,\n sourceFile,\n nodes,\n edges,\n );\n }\n}\n\nfunction parseLearningsSection(\n sectionContent: string,\n milestoneId: string,\n idPrefix: string,\n nodeType: NodeType,\n milestoneNodeId: string,\n sourceFile: string,\n nodes: GraphNode[],\n edges: GraphEdge[],\n): void {\n // Each item is a bullet line starting with \"- \" followed by optional\n // indented \"Source: ...\" line.\n // We collect bullet items and their associated source attribution.\n const lines = sectionContent.split('\\n');\n let itemIndex = 0;\n let currentText: string | null = null;\n let currentSource: string | null = null;\n\n const flushItem = (): void => {\n if (!currentText) return;\n itemIndex += 1;\n const nodeId = `${idPrefix}:${milestoneId}:${itemIndex}`;\n const description = currentSource ? `${currentSource}` : undefined;\n\n nodes.push({\n id: nodeId,\n label: currentText,\n type: nodeType,\n description,\n confidence: 'EXTRACTED',\n sourceFile,\n });\n\n // Edge: milestone relates_to this learning node\n edges.push({\n from: milestoneNodeId,\n to: nodeId,\n type: 'relates_to',\n confidence: 'EXTRACTED',\n });\n\n currentText = null;\n currentSource = null;\n };\n\n for (const line of lines) {\n const bulletMatch = line.match(/^[-*]\\s+(.+)/);\n if (bulletMatch) {\n flushItem();\n currentText = bulletMatch[1].trim();\n continue;\n }\n\n // Indented source attribution: \" Source: ...\"\n const sourceMatch = line.match(/^\\s+Source:\\s+(.+)/i);\n if (sourceMatch && currentText !== null) {\n currentSource = `Source: ${sourceMatch[1].trim()}`;\n continue;\n }\n\n // Continuation of current item text (indented non-source line)\n const continuationMatch = line.match(/^\\s{2,}(.+)/);\n if (continuationMatch && currentText !== null && currentSource === null) {\n currentText += ' ' + continuationMatch[1].trim();\n }\n }\n\n flushItem();\n}\n\n// ---------------------------------------------------------------------------\n// buildGraph\n// ---------------------------------------------------------------------------\n\n/**\n * Build a KnowledgeGraph by parsing all .gsd/ artifacts.\n *\n * Parse errors in any single artifact are caught — the artifact is skipped\n * and never causes buildGraph() to throw.\n */\nexport async function buildGraph(projectDir: string): Promise<KnowledgeGraph> {\n const gsdRoot = resolveGsdRoot(resolve(projectDir));\n\n const nodes: GraphNode[] = [];\n const edges: GraphEdge[] = [];\n\n // Each parser is wrapped so a crash in one never stops others\n const parsers: Array<(g: string, n: GraphNode[], e: GraphEdge[]) => void> = [\n parseStateFile,\n parseKnowledgeFile,\n parseMilestoneFiles,\n parseLearningsFiles,\n ];\n\n for (const parser of parsers) {\n try {\n parser(gsdRoot, nodes, edges);\n } catch {\n // Parsing error — skip this artifact, mark as ambiguous\n nodes.push({\n id: `error:${parser.name}:${Date.now()}`,\n label: `Parse error in ${parser.name}`,\n type: 'concept',\n confidence: 'AMBIGUOUS',\n });\n }\n }\n\n // Deduplicate nodes by id (keep first occurrence)\n const seen = new Set<string>();\n const dedupedNodes = nodes.filter((n) => {\n if (seen.has(n.id)) return false;\n seen.add(n.id);\n return true;\n });\n\n return {\n nodes: dedupedNodes,\n edges,\n builtAt: new Date().toISOString(),\n };\n}\n\n// ---------------------------------------------------------------------------\n// writeGraph — atomic write via tmp + rename\n// ---------------------------------------------------------------------------\n\n/**\n * Write the graph to .gsd/graphs/graph.json atomically.\n *\n * Writes to graph.tmp.json first, then renames to graph.json.\n * Creates the graphs/ directory if it does not exist.\n */\nexport async function writeGraph(gsdRoot: string, graph: KnowledgeGraph): Promise<void> {\n const dir = graphsDir(gsdRoot);\n mkdirSync(dir, { recursive: true });\n\n const tmp = graphTmpPath(gsdRoot);\n const final = graphJsonPath(gsdRoot);\n\n writeFileSync(tmp, JSON.stringify(graph, null, 2), 'utf-8');\n renameSync(tmp, final);\n}\n\n// ---------------------------------------------------------------------------\n// writeSnapshot\n// ---------------------------------------------------------------------------\n\n/**\n * Copy the current graph.json to .last-build-snapshot.json.\n * Adds a snapshotAt timestamp to the copy.\n */\nexport async function writeSnapshot(gsdRoot: string): Promise<void> {\n const src = graphJsonPath(gsdRoot);\n if (!existsSync(src)) return;\n\n const dir = graphsDir(gsdRoot);\n mkdirSync(dir, { recursive: true });\n\n const raw = readFileSync(src, 'utf-8');\n let graph: KnowledgeGraph;\n try {\n graph = JSON.parse(raw) as KnowledgeGraph;\n } catch {\n return;\n }\n const snapshot = { ...graph, snapshotAt: new Date().toISOString() };\n\n writeFileSync(snapshotPath(gsdRoot), JSON.stringify(snapshot, null, 2), 'utf-8');\n}\n\n// ---------------------------------------------------------------------------\n// graphStatus\n// ---------------------------------------------------------------------------\n\n/**\n * Return status of the graph: whether it exists, its age, and whether it is stale.\n * Stale means builtAt is older than 24 hours.\n */\nexport async function graphStatus(projectDir: string): Promise<GraphStatusResult> {\n const gsdRoot = resolveGsdRoot(resolve(projectDir));\n const graphPath = graphJsonPath(gsdRoot);\n\n if (!existsSync(graphPath)) {\n return { exists: false };\n }\n\n try {\n const raw = readFileSync(graphPath, 'utf-8');\n const graph = JSON.parse(raw) as KnowledgeGraph;\n\n const builtAt = graph.builtAt;\n const ageMs = Date.now() - new Date(builtAt).getTime();\n const ageHours = ageMs / (1000 * 60 * 60);\n const stale = ageHours > 24;\n\n return {\n exists: true,\n lastBuild: builtAt,\n nodeCount: graph.nodes.length,\n edgeCount: graph.edges.length,\n stale,\n ageHours,\n };\n } catch {\n return { exists: false };\n }\n}\n\n// ---------------------------------------------------------------------------\n// applyBudget — trim edges to stay within token budget\n// ---------------------------------------------------------------------------\n\n/**\n * Given a set of seed node IDs and the full graph, apply BFS to collect\n * reachable nodes and edges. Trims AMBIGUOUS edges first, then INFERRED,\n * stopping when the estimated token count drops within budget.\n *\n * Budget is a rough token estimate: 1 node ≈ 20 tokens, 1 edge ≈ 10 tokens.\n */\nfunction applyBudget(\n graph: KnowledgeGraph,\n seedIds: Set<string>,\n budget: number,\n): { nodes: GraphNode[]; edges: GraphEdge[] } {\n // BFS to collect reachable nodes (start from seeds)\n const reachable = new Set<string>(seedIds);\n const queue = [...seedIds];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const edge of graph.edges) {\n if (edge.from === current && !reachable.has(edge.to)) {\n reachable.add(edge.to);\n queue.push(edge.to);\n }\n }\n }\n\n let resultNodes = graph.nodes.filter((n) => reachable.has(n.id));\n let resultEdges = graph.edges.filter(\n (e) => reachable.has(e.from) && reachable.has(e.to),\n );\n\n // Estimate tokens and trim if over budget\n // Trim AMBIGUOUS edges first, then INFERRED\n const estimate = (): number =>\n resultNodes.length * 20 + resultEdges.length * 10;\n\n if (estimate() > budget) {\n resultEdges = resultEdges.filter((e) => e.confidence !== 'AMBIGUOUS');\n }\n if (estimate() > budget) {\n resultEdges = resultEdges.filter((e) => e.confidence !== 'INFERRED');\n }\n if (estimate() > budget) {\n // Hard trim — keep only seed nodes and their EXTRACTED edges\n const seedNodes = resultNodes.filter((n) => seedIds.has(n.id));\n const seedEdges = resultEdges.filter(\n (e) => seedIds.has(e.from) && e.confidence === 'EXTRACTED',\n );\n return { nodes: seedNodes, edges: seedEdges };\n }\n\n return { nodes: resultNodes, edges: resultEdges };\n}\n\n// ---------------------------------------------------------------------------\n// graphQuery\n// ---------------------------------------------------------------------------\n\n/**\n * Query the graph for nodes matching a term (case-insensitive on label + description).\n * BFS from seed nodes, applying budget trimming.\n *\n * Reads from the pre-built graph.json. Falls back to an empty result if no\n * graph exists.\n */\nexport async function graphQuery(\n projectDir: string,\n term: string,\n budget = 4000,\n): Promise<GraphQueryResult> {\n const gsdRoot = resolveGsdRoot(resolve(projectDir));\n const graphPath = graphJsonPath(gsdRoot);\n\n if (!existsSync(graphPath)) {\n return { nodes: [], edges: [], term, budget };\n }\n\n let graph: KnowledgeGraph;\n try {\n const raw = readFileSync(graphPath, 'utf-8');\n graph = JSON.parse(raw) as KnowledgeGraph;\n } catch {\n return { nodes: [], edges: [], term, budget };\n }\n\n if (!term || term.trim() === '') {\n // Empty term — return empty result\n return { nodes: [], edges: [], term, budget };\n }\n\n const lower = term.toLowerCase();\n\n // Find seed nodes that match the term\n const seedIds = new Set<string>(\n graph.nodes\n .filter((n) => {\n const labelMatch = n.label.toLowerCase().includes(lower);\n const descMatch = n.description?.toLowerCase().includes(lower) ?? false;\n return labelMatch || descMatch;\n })\n .map((n) => n.id),\n );\n\n if (seedIds.size === 0) {\n return { nodes: [], edges: [], term, budget };\n }\n\n const result = applyBudget(graph, seedIds, budget);\n return { ...result, term, budget };\n}\n\n// ---------------------------------------------------------------------------\n// graphDiff\n// ---------------------------------------------------------------------------\n\n/**\n * Compare the current graph.json with .last-build-snapshot.json.\n * Returns added/removed/changed nodes and added/removed edges.\n *\n * If no snapshot exists, returns empty diff arrays.\n */\nexport async function graphDiff(projectDir: string): Promise<GraphDiffResult> {\n const gsdRoot = resolveGsdRoot(resolve(projectDir));\n const empty: GraphDiffResult = {\n nodes: { added: [], removed: [], changed: [] },\n edges: { added: [], removed: [] },\n };\n\n const graphPath = graphJsonPath(gsdRoot);\n const snap = snapshotPath(gsdRoot);\n\n if (!existsSync(graphPath)) return empty;\n if (!existsSync(snap)) return empty;\n\n let current: KnowledgeGraph;\n let snapshot: KnowledgeGraph;\n\n try {\n current = JSON.parse(readFileSync(graphPath, 'utf-8')) as KnowledgeGraph;\n } catch {\n return empty;\n }\n\n try {\n snapshot = JSON.parse(readFileSync(snap, 'utf-8')) as KnowledgeGraph;\n } catch {\n return empty;\n }\n\n const currentNodeIds = new Set(current.nodes.map((n) => n.id));\n const snapshotNodeIds = new Set(snapshot.nodes.map((n) => n.id));\n\n const added = current.nodes.filter((n) => !snapshotNodeIds.has(n.id)).map((n) => n.id);\n const removed = snapshot.nodes.filter((n) => !currentNodeIds.has(n.id)).map((n) => n.id);\n\n // Changed: same id but different label or description\n const snapshotNodeMap = new Map(snapshot.nodes.map((n) => [n.id, n]));\n const changed = current.nodes\n .filter((n) => {\n const snap = snapshotNodeMap.get(n.id);\n if (!snap) return false;\n return n.label !== snap.label || n.description !== snap.description;\n })\n .map((n) => n.id);\n\n // Edges — compare by string key \"from->to:type\"\n const edgeKey = (e: GraphEdge): string => `${e.from}->${e.to}:${e.type}`;\n const currentEdgeKeys = new Set(current.edges.map(edgeKey));\n const snapshotEdgeKeys = new Set(snapshot.edges.map(edgeKey));\n\n const edgesAdded = current.edges.filter((e) => !snapshotEdgeKeys.has(edgeKey(e))).map(edgeKey);\n const edgesRemoved = snapshot.edges.filter((e) => !currentEdgeKeys.has(edgeKey(e))).map(edgeKey);\n\n return {\n nodes: { added, removed, changed },\n edges: { added: edgesAdded, removed: edgesRemoved },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-tools.d.ts","sourceRoot":"","sources":["../src/workflow-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqVH,4CAA4C;AAC5C,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBrE;AA6FD,UAAU,aAAa;IACrB,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAC3D,OAAO,CAAC;CACZ;AAED,eAAO,MAAM,mBAAmB,8pBA8BtB,CAAC;AAyeX,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CA8ajE"}
1
+ {"version":3,"file":"workflow-tools.d.ts","sourceRoot":"","sources":["../src/workflow-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmaH,4CAA4C;AAC5C,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBrE;AA6FD,UAAU,aAAa;IACrB,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAC3D,OAAO,CAAC;CACZ;AAED,eAAO,MAAM,mBAAmB,8pBA8BtB,CAAC;AAgfX,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CA8ajE"}