@iowarp/clio-coder 0.3.0 → 0.3.2

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 (1187) hide show
  1. package/CHANGELOG.md +123 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +295 -627
  4. package/dist/acp-BIYHVZIM.js +128 -0
  5. package/dist/{agents-Q4MYPMUW.js → agents-YT6SSRIT.js} +52 -27
  6. package/dist/assets/codewiki.json +1 -0
  7. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
  8. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
  9. package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
  10. package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
  11. package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
  12. package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
  13. package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
  14. package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
  15. package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
  16. package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
  17. package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
  18. package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
  19. package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
  20. package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
  21. package/dist/assets/grammars/tree-sitter.wasm +0 -0
  22. package/dist/{auth-O6HYIJ6J.js → auth-5TWEIYDN.js} +30 -15
  23. package/dist/chunk-2EHAIA3X.js +481 -0
  24. package/dist/{chunk-ME6DNWIU.js → chunk-2IR2NMPA.js} +12 -4
  25. package/dist/chunk-2SFS6XQE.js +122 -0
  26. package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
  27. package/dist/chunk-2VTFPG5O.js +48 -0
  28. package/dist/chunk-3I7MS7N2.js +40 -0
  29. package/dist/chunk-3R73A4XB.js +69 -0
  30. package/dist/{chunk-JPOWPFCU.js → chunk-3ZXDFGR5.js} +52 -23
  31. package/dist/chunk-4BJ5BYCE.js +61 -0
  32. package/dist/{chunk-26BZQOAD.js → chunk-4BPJXDWC.js} +161 -260
  33. package/dist/chunk-4KLWL3UC.js +18 -0
  34. package/dist/{chunk-5LDRNKX2.js → chunk-4VP4KH3K.js} +161 -262
  35. package/dist/chunk-4ZG3XFUR.js +77 -0
  36. package/dist/chunk-5B2AEOW5.js +5407 -0
  37. package/dist/chunk-5TSRNF4G.js +510 -0
  38. package/dist/{chunk-WD6AJM35.js → chunk-5UUP6MWO.js} +48 -69
  39. package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
  40. package/dist/chunk-65DEGPJ6.js +52 -0
  41. package/dist/chunk-6EJMN2Y3.js +17 -0
  42. package/dist/chunk-6EJV5X2W.js +16405 -0
  43. package/dist/chunk-6N5PTWMY.js +136 -0
  44. package/dist/chunk-6XLNIQDB.js +27 -0
  45. package/dist/{chunk-XNISANGE.js → chunk-77VKQEHF.js} +171 -74
  46. package/dist/chunk-7CR24IG7.js +242 -0
  47. package/dist/{chunk-UWIJNAOB.js → chunk-7EYHLWU7.js} +907 -638
  48. package/dist/chunk-7MNJORFF.js +22 -0
  49. package/dist/{chunk-JWHCJDCI.js → chunk-A3CYT5EX.js} +257 -79
  50. package/dist/chunk-AGYYIBLL.js +1069 -0
  51. package/dist/chunk-AO4RKG4M.js +277 -0
  52. package/dist/chunk-APJ265NV.js +7410 -0
  53. package/dist/chunk-ARBGF5F7.js +174 -0
  54. package/dist/{chunk-TFSSEXL6.js → chunk-BMEMKKIT.js} +14 -4
  55. package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
  56. package/dist/chunk-CBCAPZAA.js +229 -0
  57. package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
  58. package/dist/chunk-CMZWFGD2.js +352 -0
  59. package/dist/chunk-ECH6PKUQ.js +39 -0
  60. package/dist/{chunk-67MTHP2E.js → chunk-ED4KHGC3.js} +13 -5
  61. package/dist/chunk-EKMEHE4H.js +340 -0
  62. package/dist/{chunk-O4EJEDHO.js → chunk-EPVUXGXG.js} +50 -35
  63. package/dist/chunk-FCSXB6T2.js +338 -0
  64. package/dist/chunk-FJ3H4MN5.js +48 -0
  65. package/dist/chunk-FQ4SKYE4.js +29 -0
  66. package/dist/chunk-G2DE3C7R.js +644 -0
  67. package/dist/chunk-G4BMMOKF.js +182 -0
  68. package/dist/{chunk-7BHLZB3A.js → chunk-GGXXDWE4.js} +190 -1218
  69. package/dist/chunk-HC4CLZ2Y.js +68 -0
  70. package/dist/{chunk-E3NYWENM.js → chunk-HFSBBKSQ.js} +55 -61
  71. package/dist/chunk-HKIYEGME.js +30 -0
  72. package/dist/chunk-I4HZDVNP.js +73 -0
  73. package/dist/chunk-IGLFWIYI.js +161 -0
  74. package/dist/chunk-IHXBNWMM.js +137 -0
  75. package/dist/chunk-IKCO5N3L.js +162 -0
  76. package/dist/chunk-IR4CFBFN.js +56 -0
  77. package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
  78. package/dist/{chunk-VOO7NYPP.js → chunk-J5HN4RYU.js} +27 -9
  79. package/dist/{chunk-4UQA7NCT.js → chunk-J5Q24KAG.js} +7 -2
  80. package/dist/{chunk-KBR4MZZR.js → chunk-JVCV3ICN.js} +7 -1
  81. package/dist/chunk-KJ5LWLOE.js +1077 -0
  82. package/dist/chunk-LBMZMYH2.js +285 -0
  83. package/dist/{chunk-3DANZDGR.js → chunk-LBNRH5WM.js} +100 -161
  84. package/dist/{chunk-TKHQ4DGZ.js → chunk-LZSJBIVT.js} +7358 -7414
  85. package/dist/{chunk-UGYAX5YI.js → chunk-M6SHUN7Q.js} +13 -8
  86. package/dist/chunk-MAW544W2.js +1882 -0
  87. package/dist/chunk-MBS4V7ZP.js +217 -0
  88. package/dist/{chunk-2J63S4SF.js → chunk-MFFY33HR.js} +167 -140
  89. package/dist/chunk-MNA4JGU4.js +255 -0
  90. package/dist/chunk-MQSRRFWA.js +3428 -0
  91. package/dist/{chunk-RQDWMVRB.js → chunk-MVVUPGPW.js} +138 -137
  92. package/dist/chunk-OAO4GE4M.js +619 -0
  93. package/dist/chunk-OHHN2SO4.js +5135 -0
  94. package/dist/chunk-OKGUZO2U.js +34 -0
  95. package/dist/{chunk-BBUH4VAA.js → chunk-OOJYHWRB.js} +60 -361
  96. package/dist/{chunk-D5YD55AR.js → chunk-OQ33BKR3.js} +12 -1
  97. package/dist/chunk-OQE5J4C6.js +73 -0
  98. package/dist/{chunk-AMFR5YA3.js → chunk-ORBHGJC5.js} +26 -12
  99. package/dist/chunk-POHLU5DW.js +1186 -0
  100. package/dist/chunk-QKMUKYO7.js +4961 -0
  101. package/dist/{chunk-7RBKDI66.js → chunk-QTYWRVRA.js} +104 -12
  102. package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
  103. package/dist/chunk-SRF2PJNW.js +184 -0
  104. package/dist/chunk-SST6Z5JA.js +80 -0
  105. package/dist/{chunk-XV4ZJ6ZM.js → chunk-STBPMHSX.js} +473 -1194
  106. package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
  107. package/dist/chunk-T6YILFSB.js +80 -0
  108. package/dist/chunk-TXOTCRLG.js +15 -0
  109. package/dist/chunk-TZTZS7QK.js +227 -0
  110. package/dist/chunk-UOV2BYIW.js +107 -0
  111. package/dist/{chunk-527KG6XR.js → chunk-V4RXGQ5Q.js} +72 -185
  112. package/dist/chunk-VAKQQHWR.js +434 -0
  113. package/dist/chunk-VG7TBQIY.js +128 -0
  114. package/dist/chunk-VJWL6YS5.js +244 -0
  115. package/dist/chunk-WEH5XRJQ.js +32 -0
  116. package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
  117. package/dist/chunk-WMSVI4G2.js +2095 -0
  118. package/dist/chunk-WVO7V2QY.js +797 -0
  119. package/dist/chunk-X4RCMKVQ.js +641 -0
  120. package/dist/chunk-X75S7HFS.js +374 -0
  121. package/dist/chunk-XN3L4EYL.js +46 -0
  122. package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
  123. package/dist/{chunk-PIDUD6M2.js → chunk-YCWGATWI.js} +12 -5
  124. package/dist/chunk-YHZX5GEU.js +193 -0
  125. package/dist/chunk-YXLYO42X.js +91 -0
  126. package/dist/{chunk-UHTSULZS.js → chunk-ZDOOVTXZ.js} +38 -73
  127. package/dist/chunk-ZI647VB5.js +37 -0
  128. package/dist/{chunk-CLJ5HLUD.js → chunk-ZWLZP4ZT.js} +25 -6
  129. package/dist/cli/index.js +70 -56
  130. package/dist/clio-4LY5K2AC.js +25 -0
  131. package/dist/code-nav-7AX6FYE6.js +600 -0
  132. package/dist/codewiki/build-worker.js +66 -0
  133. package/dist/compile-cache-CVJMMODC.js +18 -0
  134. package/dist/{components-JVHMUBEB.js → components-KELWS457.js} +31 -9
  135. package/dist/{config-ZFCDBMDC.js → config-GTLUW2PR.js} +104 -56
  136. package/dist/configure-R6A64DHX.js +42 -0
  137. package/dist/context-5VKGUVJJ.js +866 -0
  138. package/dist/{context-CDXTP2MP.js → context-JFZEJ7W5.js} +21 -13
  139. package/dist/{context-E3KIFVXI.js → context-RW5HC47S.js} +77 -36
  140. package/dist/{context-clear-3F4PLXOS.js → context-clear-6ZHBAZZT.js} +64 -30
  141. package/dist/{context-index-Q7YSYTR3.js → context-index-BZ4UYMTC.js} +36 -24
  142. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  143. package/dist/{docs-YIETIWZI.js → docs-2C2LTVT2.js} +32 -13
  144. package/dist/doctor-KI767GSN.js +87 -0
  145. package/dist/{eval-B3KZZESM.js → eval-XSSNATB4.js} +93 -27
  146. package/dist/{evidence-V67CHM35.js → evidence-UA6AWDQQ.js} +55 -27
  147. package/dist/{evolve-YDZSUQYA.js → evolve-QNTFGV6Z.js} +59 -26
  148. package/dist/{extensions-SRG7XCAH.js → extensions-QVDOHDGJ.js} +23 -8
  149. package/dist/{fleet-CA2CRTVG.js → fleet-Q7UOMUSG.js} +173 -56
  150. package/dist/fleet-preflight-DDN536IT.js +26 -0
  151. package/dist/{init-2OZDJE2D.js → init-WBB65ZHQ.js} +79 -34
  152. package/dist/{memory-3PIQQAKX.js → memory-MD3O64RI.js} +57 -28
  153. package/dist/{models-DY35XI7Y.js → models-BZU34YWD.js} +49 -24
  154. package/dist/monitor-MEQA5C3I.js +661 -0
  155. package/dist/{chunk-PS4PFJQP.js → orchestrator-CGFKEP27.js} +22837 -18564
  156. package/dist/{paths-5OMXW7Z4.js → paths-UXLN5YYZ.js} +17 -6
  157. package/dist/preload-P6DGH2PZ.js +13 -0
  158. package/dist/{reset-PIFYNOS3.js → reset-L2FQEE3E.js} +25 -13
  159. package/dist/{run-3VSPP24F.js → run-IV4Q6RLN.js} +115 -63
  160. package/dist/{share-D36RQCXM.js → share-S5BZQC5I.js} +23 -10
  161. package/dist/{skills-F2MRLELY.js → skills-LQEKRDTN.js} +42 -15
  162. package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-3DC4HEWS.js} +90 -45
  163. package/dist/steer-GGWFUJUD.js +77 -0
  164. package/dist/{targets-DZMEZAH4.js → targets-C4SSGQOB.js} +78 -60
  165. package/dist/terminal-lease-IT5JW2NR.js +395 -0
  166. package/dist/{trace-7NYCUI2J.js → trace-PNCASAXC.js} +48 -17
  167. package/dist/tree-sitter-HGKH6LG4.js +4673 -0
  168. package/dist/{uninstall-AD3JWHBB.js → uninstall-FZCQCDKC.js} +19 -8
  169. package/dist/{upgrade-WYYBKGDY.js → upgrade-7TT7SQ3G.js} +66 -24
  170. package/dist/{usage-ULIDAGFF.js → usage-GV4PKT3M.js} +71 -32
  171. package/dist/verify-G6V4D2G7.js +716 -0
  172. package/dist/version-KGEG7EPO.js +21 -0
  173. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  174. package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-DQF6Z66B.js} +98 -48
  175. package/dist/worker/entry.js +297 -54
  176. package/dist/workspace-G4ZWUIPR.js +22 -0
  177. package/docs/README.md +29 -21
  178. package/docs/acp.md +191 -16
  179. package/docs/alcf-provider.md +1 -1
  180. package/docs/architecture.md +157 -7
  181. package/docs/artifact-placement.md +101 -0
  182. package/docs/artifact-versions.md +1 -1
  183. package/docs/built-in-agents.md +4 -2
  184. package/docs/capacity-and-scheduling.md +1 -1
  185. package/docs/commands-and-modes.md +224 -97
  186. package/docs/config-knobs-audit.md +1 -3
  187. package/docs/configuration-and-targets.md +236 -38
  188. package/docs/context-engine.md +34 -7
  189. package/docs/development-pipeline.md +102 -0
  190. package/docs/dispatch-architecture-rationale.md +1 -1
  191. package/docs/documentation-coverage.md +4 -4
  192. package/docs/documentation-guide.md +3 -3
  193. package/docs/environment-variables.md +15 -6
  194. package/docs/eval-runner.md +3 -3
  195. package/docs/evals-internal.md +2 -2
  196. package/docs/evidence-and-memory.md +10 -2
  197. package/docs/evolution.md +2 -2
  198. package/docs/exit-codes-and-output.md +15 -9
  199. package/docs/extensions-and-sharing.md +25 -18
  200. package/docs/fleet-demo-runbook.md +22 -23
  201. package/docs/fleet-dispatch.md +117 -16
  202. package/docs/git-commit-provenance.md +120 -0
  203. package/docs/glossary.md +107 -15
  204. package/docs/installation-and-lifecycle.md +75 -17
  205. package/docs/middleware-and-components.md +1 -1
  206. package/docs/model-catalog.md +46 -15
  207. package/docs/observability.md +8 -5
  208. package/docs/performance-methodology.md +491 -0
  209. package/docs/pi-boundary.md +72 -0
  210. package/docs/proactive-memory.md +14 -14
  211. package/docs/prompt-envelope-and-tools.md +25 -4
  212. package/docs/provider-adapter-cookbook.md +57 -4
  213. package/docs/release-cut-checklist.md +129 -111
  214. package/docs/safety-model.md +28 -8
  215. package/docs/scientific-validation.md +3 -3
  216. package/docs/session-lifecycle.md +55 -12
  217. package/docs/skills-marketplace.md +12 -8
  218. package/docs/time-conventions.md +101 -0
  219. package/docs/tool-usage.md +6 -5
  220. package/docs/trace-store.md +1 -1
  221. package/docs/troubleshooting.md +10 -7
  222. package/docs/tui-design.md +121 -28
  223. package/docs/worker-dispatch-mechanics.md +3 -3
  224. package/package.json +33 -36
  225. package/skills/README.md +5 -6
  226. package/skills/coding/ast-grep/SKILL.md +136 -0
  227. package/skills/coding/ast-grep/evals.md +56 -0
  228. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  229. package/skills/coding/coding-standards/SKILL.md +113 -0
  230. package/skills/coding/coding-standards/evals.md +34 -0
  231. package/skills/coding/prototype/SKILL.md +86 -0
  232. package/skills/coding/prototype/evals.md +42 -0
  233. package/skills/coding/prototype/references/LOGIC.md +67 -0
  234. package/skills/coding/prototype/references/UI.md +112 -0
  235. package/skills/coding/tdd/SKILL.md +101 -0
  236. package/skills/coding/tdd/evals.md +41 -0
  237. package/skills/coding/tdd/references/mocking.md +59 -0
  238. package/skills/coding/tdd/references/tests.md +77 -0
  239. package/skills/context/context-handoff/SKILL.md +126 -0
  240. package/skills/context/context-handoff/evals.md +57 -0
  241. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  242. package/skills/context/context-prime/SKILL.md +95 -0
  243. package/skills/context/context-prime/evals.md +54 -0
  244. package/skills/git/file-ticket/SKILL.md +107 -0
  245. package/skills/git/file-ticket/evals.md +54 -0
  246. package/skills/git/fix-issue/SKILL.md +106 -0
  247. package/skills/git/fix-issue/evals.md +71 -0
  248. package/skills/git/ship/SKILL.md +92 -0
  249. package/skills/git/ship/evals.md +72 -0
  250. package/skills/meta/clio-dev/SKILL.md +91 -0
  251. package/skills/meta/clio-dev/evals.md +45 -0
  252. package/skills/meta/clio-test/SKILL.md +130 -0
  253. package/skills/meta/clio-test/evals.md +43 -0
  254. package/skills/meta/clio-test/references/harness.md +97 -0
  255. package/skills/meta/clio-test/references/test-map.md +59 -0
  256. package/skills/meta/credentials/SKILL.md +125 -0
  257. package/skills/meta/credentials/evals.md +104 -0
  258. package/skills/meta/find-skills/SKILL.md +72 -0
  259. package/skills/meta/find-skills/evals.md +47 -0
  260. package/skills/meta/herdr/SKILL.md +127 -0
  261. package/skills/meta/herdr/evals.md +38 -0
  262. package/skills/meta/skill-craft/SKILL.md +102 -0
  263. package/skills/meta/skill-craft/evals.md +41 -0
  264. package/skills/planning/architecture/SKILL.md +129 -0
  265. package/skills/planning/architecture/evals.md +36 -0
  266. package/skills/planning/backlog/SKILL.md +90 -0
  267. package/skills/planning/backlog/evals.md +43 -0
  268. package/skills/planning/prd/SKILL.md +82 -0
  269. package/skills/planning/prd/evals.md +49 -0
  270. package/skills/planning/product-intent/SKILL.md +112 -0
  271. package/skills/planning/product-intent/evals.md +36 -0
  272. package/skills/planning/tech-spec/SKILL.md +115 -0
  273. package/skills/planning/tech-spec/evals.md +47 -0
  274. package/skills/registry.yaml +136 -0
  275. package/skills/research/arxiv-literature/SKILL.md +104 -0
  276. package/skills/research/arxiv-literature/evals.md +58 -0
  277. package/skills/research/experiment-protocol/SKILL.md +122 -0
  278. package/skills/research/experiment-protocol/evals.md +91 -0
  279. package/skills/research/scientific-debugging/SKILL.md +119 -0
  280. package/skills/research/scientific-debugging/evals.md +138 -0
  281. package/skills/research/scientific-modernization/SKILL.md +138 -0
  282. package/skills/research/scientific-modernization/evals.md +84 -0
  283. package/skills/skill-marketplace.json +12 -20
  284. package/skills/workflow/design-council/SKILL.md +139 -0
  285. package/skills/workflow/design-council/evals.md +97 -0
  286. package/skills/workflow/grill-me/SKILL.md +186 -0
  287. package/skills/workflow/grill-me/evals.md +78 -0
  288. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  289. package/skills/workflow/workflow-distiller/evals.md +107 -0
  290. package/src/cli/acp.ts +115 -0
  291. package/src/cli/agents.ts +60 -0
  292. package/src/cli/args.ts +280 -0
  293. package/src/cli/argv.ts +170 -0
  294. package/src/cli/ask.ts +34 -0
  295. package/src/cli/auth.ts +468 -0
  296. package/src/cli/bootstrap-generate.ts +498 -0
  297. package/src/cli/clio.ts +96 -0
  298. package/src/cli/components.ts +195 -0
  299. package/src/cli/config-inspect.ts +336 -0
  300. package/src/cli/config.ts +72 -0
  301. package/src/cli/configure-interop.ts +67 -0
  302. package/src/cli/configure-layout.ts +172 -0
  303. package/src/cli/configure.ts +1525 -0
  304. package/src/cli/context-clear.ts +76 -0
  305. package/src/cli/context-index.ts +100 -0
  306. package/src/cli/context.ts +321 -0
  307. package/src/cli/default-target.ts +55 -0
  308. package/src/cli/docs.ts +346 -0
  309. package/src/cli/doctor.ts +54 -0
  310. package/src/cli/eval.ts +315 -0
  311. package/src/cli/evidence.ts +225 -0
  312. package/src/cli/evolve.ts +219 -0
  313. package/src/cli/extensions.ts +214 -0
  314. package/src/cli/fleet.ts +868 -0
  315. package/src/cli/index.ts +338 -0
  316. package/src/cli/init.ts +219 -0
  317. package/src/cli/initial-message.ts +47 -0
  318. package/src/cli/internal-dispatch.ts +55 -0
  319. package/src/cli/memory.ts +182 -0
  320. package/src/cli/models.ts +257 -0
  321. package/src/cli/modes/json-stream.ts +121 -0
  322. package/src/cli/modes/jsonl.ts +9 -0
  323. package/src/cli/modes/print.ts +604 -0
  324. package/src/cli/oauth-manual-input.ts +72 -0
  325. package/src/cli/oauth-select.ts +36 -0
  326. package/src/cli/output-guard.ts +48 -0
  327. package/src/cli/paths.ts +44 -0
  328. package/src/cli/provider-target.ts +113 -0
  329. package/src/cli/removal.ts +72 -0
  330. package/src/cli/reset.ts +253 -0
  331. package/src/cli/run.ts +497 -0
  332. package/src/cli/share.ts +243 -0
  333. package/src/cli/shared.ts +60 -0
  334. package/src/cli/skills-eval.ts +1240 -0
  335. package/src/cli/skills.ts +485 -0
  336. package/src/cli/steer-channel.ts +86 -0
  337. package/src/cli/targets.ts +1154 -0
  338. package/src/cli/text-layout.ts +112 -0
  339. package/src/cli/trace.ts +322 -0
  340. package/src/cli/uninstall.ts +405 -0
  341. package/src/cli/upgrade.ts +286 -0
  342. package/src/cli/usage.ts +876 -0
  343. package/src/cli/validate-model.ts +28 -0
  344. package/src/cli/version.ts +7 -0
  345. package/src/cli/wiki-generate.ts +510 -0
  346. package/src/core/agent-environment.ts +7 -0
  347. package/src/core/artifact-paths.ts +43 -0
  348. package/src/core/bash-exec.ts +313 -0
  349. package/src/core/boot-trace.ts +42 -0
  350. package/src/core/bus-events.ts +744 -0
  351. package/src/core/bus-trace.ts +53 -0
  352. package/src/core/c-header-language.ts +265 -0
  353. package/src/core/clio-repo.ts +78 -0
  354. package/src/core/commit-attribution.ts +157 -0
  355. package/src/core/compile-cache.ts +159 -0
  356. package/src/core/config.ts +1722 -0
  357. package/src/core/context-floor.ts +33 -0
  358. package/src/core/defaults.ts +659 -0
  359. package/src/core/domain-loader.ts +177 -0
  360. package/src/core/event-bus.ts +94 -0
  361. package/src/core/file-references.ts +282 -0
  362. package/src/core/git-commit-attribution.ts +362 -0
  363. package/src/core/guardrails.ts +185 -0
  364. package/src/core/headless-permission.ts +21 -0
  365. package/src/core/incomplete-installation.ts +45 -0
  366. package/src/core/init.ts +223 -0
  367. package/src/core/json-payload.ts +58 -0
  368. package/src/core/package-root.ts +54 -0
  369. package/src/core/path-canonical.ts +37 -0
  370. package/src/core/process-identity.ts +41 -0
  371. package/src/core/recent-models.ts +91 -0
  372. package/src/core/residency-protection.ts +56 -0
  373. package/src/core/resolve-config-value.ts +88 -0
  374. package/src/core/response-schema.ts +279 -0
  375. package/src/core/run-overrides.ts +77 -0
  376. package/src/core/safe-exec.ts +205 -0
  377. package/src/core/safe-id.ts +37 -0
  378. package/src/core/safe-resource-write.ts +162 -0
  379. package/src/core/session-routing.ts +339 -0
  380. package/src/core/settings-layers.ts +354 -0
  381. package/src/core/shared-bus.ts +8 -0
  382. package/src/core/shell-quote.ts +26 -0
  383. package/src/core/skill-activation.ts +190 -0
  384. package/src/core/startup-timer.ts +37 -0
  385. package/src/core/state-file-lock.ts +219 -0
  386. package/src/core/termination.ts +275 -0
  387. package/src/core/timers.ts +38 -0
  388. package/src/core/tool-names.ts +65 -0
  389. package/src/core/verification-scripts.ts +13 -0
  390. package/src/core/workspace-files.ts +492 -0
  391. package/src/core/xdg.ts +177 -0
  392. package/src/domains/agents/builtins/architect.md +4 -4
  393. package/src/domains/agents/builtins/coder.md +3 -2
  394. package/src/domains/agents/builtins/debugger.md +1 -1
  395. package/src/domains/agents/builtins/documenter.md +1 -1
  396. package/src/domains/agents/builtins/git-master.md +3 -3
  397. package/src/domains/agents/builtins/provenance.md +1 -1
  398. package/src/domains/agents/builtins/researcher.md +1 -1
  399. package/src/domains/agents/builtins/scout.md +1 -1
  400. package/src/domains/agents/builtins/tester.md +1 -1
  401. package/src/domains/agents/builtins/verifier.md +1 -1
  402. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  403. package/src/domains/agents/catalog.ts +172 -0
  404. package/src/domains/agents/contract.ts +16 -0
  405. package/src/domains/agents/extension.ts +110 -0
  406. package/src/domains/agents/fleet-commands.ts +154 -0
  407. package/src/domains/agents/fleet-contract.ts +797 -0
  408. package/src/domains/agents/frontmatter.ts +40 -0
  409. package/src/domains/agents/index.ts +102 -0
  410. package/src/domains/agents/manifest.ts +6 -0
  411. package/src/domains/agents/recipe-schema.ts +202 -0
  412. package/src/domains/agents/recipe.ts +125 -0
  413. package/src/domains/agents/registry.ts +111 -0
  414. package/src/domains/agents/result-contract.ts +1265 -0
  415. package/src/domains/agents/spec.ts +371 -0
  416. package/src/domains/agents/write-boundary.ts +109 -0
  417. package/src/domains/components/diff.ts +99 -0
  418. package/src/domains/components/hash.ts +21 -0
  419. package/src/domains/components/index.ts +3 -0
  420. package/src/domains/components/scan.ts +304 -0
  421. package/src/domains/components/snapshot.ts +108 -0
  422. package/src/domains/components/types.ts +82 -0
  423. package/src/domains/config/agent-namespace.ts +13 -0
  424. package/src/domains/config/classify.ts +106 -0
  425. package/src/domains/config/contract.ts +22 -0
  426. package/src/domains/config/extension.ts +142 -0
  427. package/src/domains/config/index.ts +23 -0
  428. package/src/domains/config/keybindings.ts +200 -0
  429. package/src/domains/config/manifest.ts +6 -0
  430. package/src/domains/config/watcher.ts +41 -0
  431. package/src/domains/context/adoption.ts +880 -0
  432. package/src/domains/context/bootstrap-prompt.ts +273 -0
  433. package/src/domains/context/bootstrap.ts +1502 -0
  434. package/src/domains/context/clear.ts +91 -0
  435. package/src/domains/context/clio-md.ts +429 -0
  436. package/src/domains/context/codewiki/artifact.ts +400 -0
  437. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  438. package/src/domains/context/codewiki/build-worker.ts +54 -0
  439. package/src/domains/context/codewiki/cmake.ts +356 -0
  440. package/src/domains/context/codewiki/cooperative.ts +46 -0
  441. package/src/domains/context/codewiki/coordinator.ts +182 -0
  442. package/src/domains/context/codewiki/digest.ts +135 -0
  443. package/src/domains/context/codewiki/grammar-assets.ts +33 -0
  444. package/src/domains/context/codewiki/indexer.ts +1529 -0
  445. package/src/domains/context/codewiki/paths.ts +67 -0
  446. package/src/domains/context/codewiki/schema.ts +80 -0
  447. package/src/domains/context/codewiki/tree-sitter.ts +771 -0
  448. package/src/domains/context/contract.ts +68 -0
  449. package/src/domains/context/excluded-dirs.ts +1 -0
  450. package/src/domains/context/extension.ts +358 -0
  451. package/src/domains/context/fingerprint.ts +198 -0
  452. package/src/domains/context/index.ts +154 -0
  453. package/src/domains/context/init-options.ts +69 -0
  454. package/src/domains/context/manifest.ts +6 -0
  455. package/src/domains/context/operator-profile.ts +157 -0
  456. package/src/domains/context/project-metadata.ts +529 -0
  457. package/src/domains/context/project-rules.ts +227 -0
  458. package/src/domains/context/prompt-context.ts +61 -0
  459. package/src/domains/context/refresh.ts +178 -0
  460. package/src/domains/context/runtime.ts +17 -0
  461. package/src/domains/context/sibling-files.ts +10 -0
  462. package/src/domains/context/state.ts +237 -0
  463. package/src/domains/context/wiki/assemble.ts +303 -0
  464. package/src/domains/context/wiki/frontmatter.ts +210 -0
  465. package/src/domains/context/wiki/generate.ts +595 -0
  466. package/src/domains/context/wiki/layout.ts +111 -0
  467. package/src/domains/context/wiki/meta.ts +221 -0
  468. package/src/domains/context/wiki/plan-store.ts +217 -0
  469. package/src/domains/context/wiki/plan.ts +250 -0
  470. package/src/domains/context/wiki/prompts.ts +283 -0
  471. package/src/domains/context/wiki/staleness.ts +198 -0
  472. package/src/domains/dispatch/active-route-planner.ts +168 -0
  473. package/src/domains/dispatch/admission-queue.ts +150 -0
  474. package/src/domains/dispatch/admission.ts +334 -0
  475. package/src/domains/dispatch/agent-candidates.ts +307 -0
  476. package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
  477. package/src/domains/dispatch/agent-ledger-store.ts +257 -0
  478. package/src/domains/dispatch/agent-ledger.ts +212 -0
  479. package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
  480. package/src/domains/dispatch/assignment-events.ts +132 -0
  481. package/src/domains/dispatch/assignment-reconcile.ts +76 -0
  482. package/src/domains/dispatch/assignment-store.ts +162 -0
  483. package/src/domains/dispatch/assignment.ts +278 -0
  484. package/src/domains/dispatch/backoff.ts +59 -0
  485. package/src/domains/dispatch/batch-store.ts +134 -0
  486. package/src/domains/dispatch/batch-tracker.ts +66 -0
  487. package/src/domains/dispatch/capability-match.ts +155 -0
  488. package/src/domains/dispatch/capacity-lease.ts +413 -0
  489. package/src/domains/dispatch/code-step-store.ts +52 -0
  490. package/src/domains/dispatch/code-step.ts +387 -0
  491. package/src/domains/dispatch/contract.ts +278 -0
  492. package/src/domains/dispatch/dedup.ts +133 -0
  493. package/src/domains/dispatch/event-pump.ts +251 -0
  494. package/src/domains/dispatch/execution-handoff.ts +29 -0
  495. package/src/domains/dispatch/execution-plan.ts +328 -0
  496. package/src/domains/dispatch/execution-role.ts +277 -0
  497. package/src/domains/dispatch/execution-scheduler.ts +583 -0
  498. package/src/domains/dispatch/extension.ts +6006 -0
  499. package/src/domains/dispatch/failure-classification.ts +147 -0
  500. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  501. package/src/domains/dispatch/fleet-plan.ts +225 -0
  502. package/src/domains/dispatch/fleet-preflight.ts +394 -0
  503. package/src/domains/dispatch/gate-decisions.ts +1040 -0
  504. package/src/domains/dispatch/gate-role-prompts.ts +58 -0
  505. package/src/domains/dispatch/heartbeat.ts +27 -0
  506. package/src/domains/dispatch/index.ts +137 -0
  507. package/src/domains/dispatch/joint-route-adapter.ts +114 -0
  508. package/src/domains/dispatch/joint-route-resolver.ts +283 -0
  509. package/src/domains/dispatch/manifest.ts +6 -0
  510. package/src/domains/dispatch/orphan-recovery.ts +266 -0
  511. package/src/domains/dispatch/outcome.ts +109 -0
  512. package/src/domains/dispatch/phase-timing.ts +47 -0
  513. package/src/domains/dispatch/placement.ts +202 -0
  514. package/src/domains/dispatch/receipt-findings.ts +255 -0
  515. package/src/domains/dispatch/receipt-integrity.ts +383 -0
  516. package/src/domains/dispatch/recovery-candidates.ts +74 -0
  517. package/src/domains/dispatch/reproducibility.ts +48 -0
  518. package/src/domains/dispatch/reservation-store.ts +501 -0
  519. package/src/domains/dispatch/route-approval.ts +177 -0
  520. package/src/domains/dispatch/route-candidates.ts +57 -0
  521. package/src/domains/dispatch/route-decision.ts +1079 -0
  522. package/src/domains/dispatch/route-facts.ts +187 -0
  523. package/src/domains/dispatch/route-history.ts +238 -0
  524. package/src/domains/dispatch/route-observer.ts +488 -0
  525. package/src/domains/dispatch/route-policy.ts +327 -0
  526. package/src/domains/dispatch/route-quality.ts +256 -0
  527. package/src/domains/dispatch/route-readiness.ts +120 -0
  528. package/src/domains/dispatch/routing-intent.ts +287 -0
  529. package/src/domains/dispatch/run-identity.ts +56 -0
  530. package/src/domains/dispatch/scout-transition.ts +130 -0
  531. package/src/domains/dispatch/state.ts +302 -0
  532. package/src/domains/dispatch/tool-stats.ts +132 -0
  533. package/src/domains/dispatch/transport.ts +210 -0
  534. package/src/domains/dispatch/types.ts +799 -0
  535. package/src/domains/dispatch/validation-grounding.ts +154 -0
  536. package/src/domains/dispatch/validation.ts +721 -0
  537. package/src/domains/dispatch/worker-protocol.ts +275 -0
  538. package/src/domains/dispatch/worker-spawn.ts +585 -0
  539. package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
  540. package/src/domains/dispatch/write-boundary.ts +426 -0
  541. package/src/domains/eval/artifacts/redact.ts +42 -0
  542. package/src/domains/eval/artifacts/store.ts +173 -0
  543. package/src/domains/eval/compare/compare.ts +33 -0
  544. package/src/domains/eval/compare/gates.ts +66 -0
  545. package/src/domains/eval/compare/thresholds.ts +92 -0
  546. package/src/domains/eval/harness-metrics.ts +62 -0
  547. package/src/domains/eval/index.ts +66 -0
  548. package/src/domains/eval/metrics/chaos-stream.ts +93 -0
  549. package/src/domains/eval/metrics/context.ts +34 -0
  550. package/src/domains/eval/metrics/coverage.ts +21 -0
  551. package/src/domains/eval/metrics/evidence.ts +182 -0
  552. package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
  553. package/src/domains/eval/metrics/invariants.ts +736 -0
  554. package/src/domains/eval/metrics/latency.ts +4 -0
  555. package/src/domains/eval/metrics/token-stream.ts +139 -0
  556. package/src/domains/eval/metrics/tokens.ts +51 -0
  557. package/src/domains/eval/metrics/tool-calls.ts +7 -0
  558. package/src/domains/eval/proactive-memory.ts +279 -0
  559. package/src/domains/eval/provenance.ts +35 -0
  560. package/src/domains/eval/report.ts +234 -0
  561. package/src/domains/eval/reports/json.ts +5 -0
  562. package/src/domains/eval/reports/junit.ts +23 -0
  563. package/src/domains/eval/reports/markdown.ts +20 -0
  564. package/src/domains/eval/reports/swe-jsonl.ts +16 -0
  565. package/src/domains/eval/reports/text.ts +25 -0
  566. package/src/domains/eval/run-compare.ts +274 -0
  567. package/src/domains/eval/runner.ts +244 -0
  568. package/src/domains/eval/runners/clio-run.ts +148 -0
  569. package/src/domains/eval/runners/context-index.ts +56 -0
  570. package/src/domains/eval/runners/context-init.ts +203 -0
  571. package/src/domains/eval/runners/external-command.ts +350 -0
  572. package/src/domains/eval/runtime-paths.ts +171 -0
  573. package/src/domains/eval/schema/artifact.ts +75 -0
  574. package/src/domains/eval/schema/suite.ts +235 -0
  575. package/src/domains/eval/schema/validate.ts +339 -0
  576. package/src/domains/eval/store.ts +392 -0
  577. package/src/domains/eval/suites/load.ts +74 -0
  578. package/src/domains/eval/suites/matrix.ts +19 -0
  579. package/src/domains/eval/suites/resolve.ts +44 -0
  580. package/src/domains/eval/suites/run.ts +325 -0
  581. package/src/domains/eval/task-file.ts +186 -0
  582. package/src/domains/eval/types.ts +140 -0
  583. package/src/domains/eval/verifiers/command.ts +27 -0
  584. package/src/domains/eval/verifiers/file-exists.ts +6 -0
  585. package/src/domains/eval/verifiers/patch.ts +22 -0
  586. package/src/domains/eval/workspaces/git.ts +41 -0
  587. package/src/domains/eval/workspaces/local.ts +17 -0
  588. package/src/domains/eval/workspaces/temp-copy.ts +29 -0
  589. package/src/domains/evidence/build.ts +1754 -0
  590. package/src/domains/evidence/eval.ts +605 -0
  591. package/src/domains/evidence/failure-attribution.ts +54 -0
  592. package/src/domains/evidence/finish-contract-map.ts +42 -0
  593. package/src/domains/evidence/index.ts +55 -0
  594. package/src/domains/evidence/provenance.ts +200 -0
  595. package/src/domains/evidence/redact.ts +81 -0
  596. package/src/domains/evidence/store.ts +291 -0
  597. package/src/domains/evidence/types.ts +325 -0
  598. package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
  599. package/src/domains/evolution/index.ts +26 -0
  600. package/src/domains/evolution/manifest.ts +154 -0
  601. package/src/domains/evolution/validate.ts +304 -0
  602. package/src/domains/extensions/contract.ts +22 -0
  603. package/src/domains/extensions/discovery.ts +193 -0
  604. package/src/domains/extensions/extension.ts +46 -0
  605. package/src/domains/extensions/index.ts +34 -0
  606. package/src/domains/extensions/manager.ts +30 -0
  607. package/src/domains/extensions/manifest.ts +6 -0
  608. package/src/domains/extensions/resources.ts +38 -0
  609. package/src/domains/extensions/state.ts +224 -0
  610. package/src/domains/extensions/types.ts +83 -0
  611. package/src/domains/interop/consent.ts +185 -0
  612. package/src/domains/interop/contract.ts +29 -0
  613. package/src/domains/interop/detect.ts +173 -0
  614. package/src/domains/interop/extension.ts +59 -0
  615. package/src/domains/interop/index.ts +34 -0
  616. package/src/domains/interop/manifest.ts +6 -0
  617. package/src/domains/interop/registry.ts +139 -0
  618. package/src/domains/interop/state.ts +92 -0
  619. package/src/domains/interop/types.ts +109 -0
  620. package/src/domains/lifecycle/contract.ts +11 -0
  621. package/src/domains/lifecycle/doctor.ts +536 -0
  622. package/src/domains/lifecycle/extension.ts +23 -0
  623. package/src/domains/lifecycle/index.ts +21 -0
  624. package/src/domains/lifecycle/install-method.ts +51 -0
  625. package/src/domains/lifecycle/manifest.ts +6 -0
  626. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  627. package/src/domains/lifecycle/migrations/index.ts +114 -0
  628. package/src/domains/lifecycle/state.ts +93 -0
  629. package/src/domains/lifecycle/upgrade-notice.ts +35 -0
  630. package/src/domains/lifecycle/version.ts +35 -0
  631. package/src/domains/memory/index.ts +128 -0
  632. package/src/domains/memory/operations.ts +143 -0
  633. package/src/domains/memory/prompt-section.ts +86 -0
  634. package/src/domains/memory/proposal.ts +180 -0
  635. package/src/domains/memory/store.ts +163 -0
  636. package/src/domains/memory/task-bank.ts +229 -0
  637. package/src/domains/memory/task-memory-handoff.ts +222 -0
  638. package/src/domains/memory/task-memory-policy.ts +602 -0
  639. package/src/domains/memory/task-memory-status.ts +58 -0
  640. package/src/domains/memory/task-memory-telemetry.ts +346 -0
  641. package/src/domains/memory/task-memory-trace.ts +89 -0
  642. package/src/domains/memory/types.ts +74 -0
  643. package/src/domains/memory/validate.ts +297 -0
  644. package/src/domains/middleware/budget.ts +216 -0
  645. package/src/domains/middleware/contract.ts +35 -0
  646. package/src/domains/middleware/dispatch-nudge.ts +469 -0
  647. package/src/domains/middleware/extension.ts +129 -0
  648. package/src/domains/middleware/hook-receipts.ts +70 -0
  649. package/src/domains/middleware/hooks-io.ts +186 -0
  650. package/src/domains/middleware/hooks.ts +432 -0
  651. package/src/domains/middleware/index.ts +154 -0
  652. package/src/domains/middleware/manifest.ts +6 -0
  653. package/src/domains/middleware/memory-intervention.ts +701 -0
  654. package/src/domains/middleware/rules.ts +42 -0
  655. package/src/domains/middleware/runtime.ts +333 -0
  656. package/src/domains/middleware/skills-reminder.ts +202 -0
  657. package/src/domains/middleware/snapshot.ts +71 -0
  658. package/src/domains/middleware/stalled-turn.ts +71 -0
  659. package/src/domains/middleware/task-board-reminder.ts +87 -0
  660. package/src/domains/middleware/task-nudge.ts +77 -0
  661. package/src/domains/middleware/tool-choice-control.ts +42 -0
  662. package/src/domains/middleware/types.ts +131 -0
  663. package/src/domains/middleware/validate.ts +329 -0
  664. package/src/domains/observability/accountability.ts +67 -0
  665. package/src/domains/observability/contract.ts +168 -0
  666. package/src/domains/observability/cost.ts +206 -0
  667. package/src/domains/observability/evidence-index.ts +123 -0
  668. package/src/domains/observability/extension.ts +281 -0
  669. package/src/domains/observability/index.ts +78 -0
  670. package/src/domains/observability/manifest.ts +10 -0
  671. package/src/domains/observability/metrics.ts +37 -0
  672. package/src/domains/observability/projection.ts +477 -0
  673. package/src/domains/observability/telemetry.ts +89 -0
  674. package/src/domains/observability/trace-store.ts +1454 -0
  675. package/src/domains/prompts/compiler.ts +614 -0
  676. package/src/domains/prompts/contract.ts +46 -0
  677. package/src/domains/prompts/extension.ts +336 -0
  678. package/src/domains/prompts/fragment-loader.ts +138 -0
  679. package/src/domains/prompts/fragments/identity/clio.md +5 -6
  680. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  681. package/src/domains/prompts/fragments/identity/self-awareness.md +19 -0
  682. package/src/domains/prompts/fragments/operating/contract.md +4 -41
  683. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  684. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  685. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  686. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  687. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  688. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  689. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  690. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  691. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  692. package/src/domains/prompts/hash.ts +73 -0
  693. package/src/domains/prompts/index.ts +32 -0
  694. package/src/domains/prompts/manifest.ts +8 -0
  695. package/src/domains/prompts/memory-intervention.ts +57 -0
  696. package/src/domains/prompts/preload.ts +82 -0
  697. package/src/domains/providers/auth/api-key.ts +47 -0
  698. package/src/domains/providers/auth/backend-file.ts +79 -0
  699. package/src/domains/providers/auth/backend-memory.ts +72 -0
  700. package/src/domains/providers/auth/boot-status.ts +65 -0
  701. package/src/domains/providers/auth/index.ts +37 -0
  702. package/src/domains/providers/auth/oauth.ts +37 -0
  703. package/src/domains/providers/auth/storage.ts +726 -0
  704. package/src/domains/providers/capabilities.ts +58 -0
  705. package/src/domains/providers/catalog.ts +162 -0
  706. package/src/domains/providers/contract.ts +162 -0
  707. package/src/domains/providers/credentials.ts +20 -0
  708. package/src/domains/providers/eligibility.ts +24 -0
  709. package/src/domains/providers/errors.ts +64 -0
  710. package/src/domains/providers/extension.ts +548 -0
  711. package/src/domains/providers/index.ts +142 -0
  712. package/src/domains/providers/knowledge-base-path.ts +102 -0
  713. package/src/domains/providers/manifest.ts +6 -0
  714. package/src/domains/providers/model-capabilities.ts +136 -0
  715. package/src/domains/providers/model-discovery.ts +144 -0
  716. package/src/domains/providers/model-family.ts +32 -0
  717. package/src/domains/providers/model-runtime-capabilities.ts +723 -0
  718. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +120 -37
  719. package/src/domains/providers/plugins.ts +61 -0
  720. package/src/domains/providers/probe/fingerprint.ts +64 -0
  721. package/src/domains/providers/probe/http.ts +114 -0
  722. package/src/domains/providers/probe/reasoning.ts +111 -0
  723. package/src/domains/providers/registry.ts +187 -0
  724. package/src/domains/providers/resolver.ts +156 -0
  725. package/src/domains/providers/runtime-resolution.ts +720 -0
  726. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
  727. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  728. package/src/domains/providers/runtimes/builtins.ts +78 -0
  729. package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
  730. package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
  731. package/src/domains/providers/runtimes/claude/common.ts +55 -0
  732. package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
  733. package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
  734. package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
  735. package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
  736. package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
  737. package/src/domains/providers/runtimes/cloud/google.ts +41 -0
  738. package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
  739. package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
  740. package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
  741. package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
  742. package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
  743. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  744. package/src/domains/providers/runtimes/common/local-synth.ts +164 -0
  745. package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
  746. package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
  747. package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
  748. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
  749. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
  750. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
  751. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
  752. package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
  753. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  754. package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
  755. package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
  756. package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
  757. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
  758. package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
  759. package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
  760. package/src/domains/providers/runtimes/protocol/google.ts +27 -0
  761. package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
  762. package/src/domains/providers/support.ts +241 -0
  763. package/src/domains/providers/thinking-control-policy.ts +85 -0
  764. package/src/domains/providers/types/capability-flags.ts +114 -0
  765. package/src/domains/providers/types/cost-provenance.ts +7 -0
  766. package/src/domains/providers/types/inference.ts +41 -0
  767. package/src/domains/providers/types/knowledge-base.ts +156 -0
  768. package/src/domains/providers/types/local-model-quirks.ts +216 -0
  769. package/src/domains/providers/types/runtime-descriptor.ts +181 -0
  770. package/src/domains/providers/types/target-descriptor.ts +60 -0
  771. package/src/domains/resources/collision.ts +92 -0
  772. package/src/domains/resources/common-loader.ts +140 -0
  773. package/src/domains/resources/contract.ts +24 -0
  774. package/src/domains/resources/extension.ts +59 -0
  775. package/src/domains/resources/index.ts +74 -0
  776. package/src/domains/resources/loader.ts +85 -0
  777. package/src/domains/resources/manifest.ts +6 -0
  778. package/src/domains/resources/prompts/loader.ts +246 -0
  779. package/src/domains/resources/prompts/substitute.ts +1 -0
  780. package/src/domains/resources/skills/content-hash.ts +107 -0
  781. package/src/domains/resources/skills/evals.ts +175 -0
  782. package/src/domains/resources/skills/install.ts +427 -0
  783. package/src/domains/resources/skills/loader.ts +985 -0
  784. package/src/domains/resources/skills/marketplace.ts +301 -0
  785. package/src/domains/resources/skills/provenance-pin.ts +115 -0
  786. package/src/domains/safety/action-classifier.ts +270 -0
  787. package/src/domains/safety/approval-axis.ts +23 -0
  788. package/src/domains/safety/audit.ts +493 -0
  789. package/src/domains/safety/autonomy.ts +174 -0
  790. package/src/domains/safety/call-target.ts +59 -0
  791. package/src/domains/safety/contract.ts +65 -0
  792. package/src/domains/safety/damage-control.ts +44 -0
  793. package/src/domains/safety/default-path-policy.ts +117 -0
  794. package/src/domains/safety/extension.ts +383 -0
  795. package/src/domains/safety/finish-contract-registration.ts +128 -0
  796. package/src/domains/safety/finish-contract.ts +554 -0
  797. package/src/domains/safety/index.ts +44 -0
  798. package/src/domains/safety/loop-detector.ts +143 -0
  799. package/src/domains/safety/manifest.ts +6 -0
  800. package/src/domains/safety/path-policy.ts +164 -0
  801. package/src/domains/safety/policy-engine.ts +994 -0
  802. package/src/domains/safety/project-policy.ts +391 -0
  803. package/src/domains/safety/protected-artifacts-registration.ts +189 -0
  804. package/src/domains/safety/protected-artifacts.ts +993 -0
  805. package/src/domains/safety/rejection-feedback.ts +102 -0
  806. package/src/domains/safety/rigor.ts +72 -0
  807. package/src/domains/safety/rule-compiler.ts +48 -0
  808. package/src/domains/safety/rule-pack-loader.ts +92 -0
  809. package/src/domains/safety/run-effects.ts +197 -0
  810. package/src/domains/safety/scope.ts +61 -0
  811. package/src/domains/scheduling/budget.ts +35 -0
  812. package/src/domains/scheduling/cluster.ts +175 -0
  813. package/src/domains/scheduling/contract.ts +30 -0
  814. package/src/domains/scheduling/extension.ts +91 -0
  815. package/src/domains/scheduling/index.ts +12 -0
  816. package/src/domains/scheduling/manifest.ts +6 -0
  817. package/src/domains/session/archive-readers.ts +208 -0
  818. package/src/domains/session/checkpoint.ts +38 -0
  819. package/src/domains/session/compaction/auto.ts +89 -0
  820. package/src/domains/session/compaction/branch-summary.ts +187 -0
  821. package/src/domains/session/compaction/compact.ts +493 -0
  822. package/src/domains/session/compaction/cut-point.ts +172 -0
  823. package/src/domains/session/compaction/defaults.ts +34 -0
  824. package/src/domains/session/compaction/mask-observations.ts +265 -0
  825. package/src/domains/session/compaction/session-entries.ts +18 -0
  826. package/src/domains/session/compaction/tokens.ts +148 -0
  827. package/src/domains/session/context-accounting.ts +583 -0
  828. package/src/domains/session/context-ledger.ts +362 -0
  829. package/src/domains/session/contract.ts +159 -0
  830. package/src/domains/session/cwd-fallback.ts +65 -0
  831. package/src/domains/session/decision-board.ts +190 -0
  832. package/src/domains/session/entries.ts +572 -0
  833. package/src/domains/session/extension.ts +403 -0
  834. package/src/domains/session/history.ts +172 -0
  835. package/src/domains/session/index.ts +84 -0
  836. package/src/domains/session/manager.ts +128 -0
  837. package/src/domains/session/manifest.ts +6 -0
  838. package/src/domains/session/migrations/index.ts +27 -0
  839. package/src/domains/session/prompt-manifest.ts +173 -0
  840. package/src/domains/session/protected-artifact-journal.ts +241 -0
  841. package/src/domains/session/protected-artifacts.ts +90 -0
  842. package/src/domains/session/retry.ts +230 -0
  843. package/src/domains/session/session-artifacts.ts +107 -0
  844. package/src/domains/session/task-board.ts +569 -0
  845. package/src/domains/session/tree/active-path.ts +137 -0
  846. package/src/domains/session/tree/fork.ts +159 -0
  847. package/src/domains/session/tree/manager.ts +128 -0
  848. package/src/domains/session/tree/navigator.ts +177 -0
  849. package/src/domains/session/tree/preview.ts +259 -0
  850. package/src/domains/session/usage.ts +148 -0
  851. package/src/domains/session/workspace/git-probe.ts +167 -0
  852. package/src/domains/session/workspace/index.ts +4 -0
  853. package/src/domains/session/workspace/project-type.ts +217 -0
  854. package/src/domains/session/workspace/snapshot.ts +74 -0
  855. package/src/domains/share/archive.ts +684 -0
  856. package/src/domains/share/contract.ts +9 -0
  857. package/src/domains/share/extension.ts +26 -0
  858. package/src/domains/share/index.ts +28 -0
  859. package/src/domains/share/manifest.ts +6 -0
  860. package/src/domains/user-tasks/store.ts +297 -0
  861. package/src/engine/acp/adapter.ts +397 -0
  862. package/src/engine/acp/errors.ts +128 -0
  863. package/src/engine/acp/event-mapper.ts +154 -0
  864. package/src/engine/acp/server.ts +2238 -0
  865. package/src/engine/acp/tool-mediator.ts +686 -0
  866. package/src/engine/acp/transport.ts +775 -0
  867. package/src/engine/acp/types.ts +196 -0
  868. package/src/engine/agent.ts +29 -0
  869. package/src/engine/ai.ts +207 -0
  870. package/src/engine/alcf-oauth.ts +205 -0
  871. package/src/engine/antigravity/subprocess-runtime.ts +205 -0
  872. package/src/engine/api-registry.ts +223 -0
  873. package/src/engine/apis/degraded-inference.ts +95 -0
  874. package/src/engine/apis/index.ts +16 -0
  875. package/src/engine/apis/llamacpp-residency.ts +292 -0
  876. package/src/engine/apis/lmstudio-residency.ts +76 -0
  877. package/src/engine/apis/lmstudio.ts +243 -0
  878. package/src/engine/apis/ollama-native.ts +528 -0
  879. package/src/engine/apis/openai-completions.ts +795 -0
  880. package/src/engine/apis/output-budget.ts +99 -0
  881. package/src/engine/apis/residency-lock.ts +29 -0
  882. package/src/engine/apis/residency.ts +776 -0
  883. package/src/engine/apis/resident-models.ts +42 -0
  884. package/src/engine/apis/sampling-overrides.ts +38 -0
  885. package/src/engine/apis/types.ts +16 -0
  886. package/src/engine/claude/sdk-runtime.ts +685 -0
  887. package/src/engine/claude/session-id.ts +5 -0
  888. package/src/engine/claude/subprocess-runtime.ts +316 -0
  889. package/src/engine/claude/tool-safety.ts +400 -0
  890. package/src/engine/env-api-keys.ts +98 -0
  891. package/src/engine/external-subprocess.ts +23 -0
  892. package/src/engine/gemma-channel-filter.ts +223 -0
  893. package/src/engine/harmony-response.ts +165 -0
  894. package/src/engine/instrumented-tui.ts +192 -0
  895. package/src/engine/loop-guard.ts +1127 -0
  896. package/src/engine/messages.ts +14 -0
  897. package/src/engine/models.ts +42 -0
  898. package/src/engine/oauth.ts +196 -0
  899. package/src/engine/pi-mono-names.ts +13 -0
  900. package/src/engine/prompt-templates.ts +1 -0
  901. package/src/engine/provider-payload.ts +272 -0
  902. package/src/engine/select-list.ts +53 -0
  903. package/src/engine/session.ts +834 -0
  904. package/src/engine/strip-tokenizer-sentinels.ts +125 -0
  905. package/src/engine/truncate.ts +9 -0
  906. package/src/engine/tui.ts +111 -0
  907. package/src/engine/types.ts +63 -0
  908. package/src/engine/worker-events.ts +100 -0
  909. package/src/engine/worker-runtime-capabilities.ts +5 -0
  910. package/src/engine/worker-runtime.ts +1022 -0
  911. package/src/engine/worker-tools.ts +208 -0
  912. package/src/entry/boot-options.ts +50 -0
  913. package/src/entry/orchestrator.ts +2011 -0
  914. package/src/interactive/application-controller.ts +433 -0
  915. package/src/interactive/bus-notices.ts +265 -0
  916. package/src/interactive/chat-loop-messages.ts +626 -0
  917. package/src/interactive/chat-loop-policy.ts +18 -0
  918. package/src/interactive/chat-loop.ts +1090 -0
  919. package/src/interactive/chat-panel.ts +1820 -0
  920. package/src/interactive/chat-renderer.ts +1228 -0
  921. package/src/interactive/clio-editor.ts +161 -0
  922. package/src/interactive/command-fallbacks.ts +23 -0
  923. package/src/interactive/command-output.ts +85 -0
  924. package/src/interactive/context-activity.ts +203 -0
  925. package/src/interactive/context-meter.ts +223 -0
  926. package/src/interactive/context-overlay.ts +246 -0
  927. package/src/interactive/cost-overlay.ts +279 -0
  928. package/src/interactive/dispatch-board.ts +1319 -0
  929. package/src/interactive/dispatch-steering.ts +86 -0
  930. package/src/interactive/editor-bash.ts +46 -0
  931. package/src/interactive/editor-steer.ts +51 -0
  932. package/src/interactive/editor-submit.ts +507 -0
  933. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  934. package/src/interactive/export-html/index.ts +51 -0
  935. package/src/interactive/export-html/template.ts +45 -0
  936. package/src/interactive/export-html/tool-renderer.ts +54 -0
  937. package/src/interactive/external-editor.ts +67 -0
  938. package/src/interactive/follow-up-queue-panel.ts +75 -0
  939. package/src/interactive/footer/dashboard.ts +538 -0
  940. package/src/interactive/footer/notifications.ts +275 -0
  941. package/src/interactive/footer/widgets.ts +1264 -0
  942. package/src/interactive/footer-panel.ts +187 -0
  943. package/src/interactive/format-time.ts +97 -0
  944. package/src/interactive/index.ts +11 -0
  945. package/src/interactive/interactive-application.ts +939 -0
  946. package/src/interactive/interactive-event-projection.ts +385 -0
  947. package/src/interactive/interactive-input-runtime.ts +307 -0
  948. package/src/interactive/interactive-presentation.ts +584 -0
  949. package/src/interactive/interactive-shell.ts +388 -0
  950. package/src/interactive/interactive-slash-runtime.ts +554 -0
  951. package/src/interactive/interactive-subscriptions.ts +111 -0
  952. package/src/interactive/interactive-tickers.ts +183 -0
  953. package/src/interactive/keybinding-manager.ts +496 -0
  954. package/src/interactive/layout.ts +57 -0
  955. package/src/interactive/leader-key.ts +143 -0
  956. package/src/interactive/loop-guard-interrupt.ts +101 -0
  957. package/src/interactive/memory-overlay.ts +280 -0
  958. package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
  959. package/src/interactive/overlay-auth-lifecycle.ts +308 -0
  960. package/src/interactive/overlay-frame.ts +502 -0
  961. package/src/interactive/overlay-general-openers.ts +274 -0
  962. package/src/interactive/overlay-key-routing.ts +216 -0
  963. package/src/interactive/overlay-lifecycle.ts +426 -0
  964. package/src/interactive/overlay-model-selectors.ts +127 -0
  965. package/src/interactive/overlay-permission-lifecycle.ts +345 -0
  966. package/src/interactive/overlay-resource-openers.ts +112 -0
  967. package/src/interactive/overlay-session-lifecycle.ts +327 -0
  968. package/src/interactive/overlay-transitions.ts +57 -0
  969. package/src/interactive/overlays/agents.ts +69 -0
  970. package/src/interactive/overlays/ask-user.ts +921 -0
  971. package/src/interactive/overlays/auth-dialog.ts +221 -0
  972. package/src/interactive/overlays/context-reset.ts +108 -0
  973. package/src/interactive/overlays/cwd-fallback.ts +141 -0
  974. package/src/interactive/overlays/decisions.ts +300 -0
  975. package/src/interactive/overlays/extensions.ts +54 -0
  976. package/src/interactive/overlays/help-reference.ts +145 -0
  977. package/src/interactive/overlays/interop.ts +139 -0
  978. package/src/interactive/overlays/keybinding-detail.ts +90 -0
  979. package/src/interactive/overlays/list-overlay.ts +606 -0
  980. package/src/interactive/overlays/message-picker.ts +155 -0
  981. package/src/interactive/overlays/model-selector.ts +1109 -0
  982. package/src/interactive/overlays/prompts.ts +72 -0
  983. package/src/interactive/overlays/session-selector-search.ts +31 -0
  984. package/src/interactive/overlays/session-selector.ts +284 -0
  985. package/src/interactive/overlays/settings.ts +3451 -0
  986. package/src/interactive/overlays/skills-hub.ts +237 -0
  987. package/src/interactive/overlays/tree-selector.ts +422 -0
  988. package/src/interactive/permission-overlay.ts +170 -0
  989. package/src/interactive/render-trace.ts +534 -0
  990. package/src/interactive/renderers/branch-summary.ts +86 -0
  991. package/src/interactive/renderers/code-ink.ts +420 -0
  992. package/src/interactive/renderers/compaction-summary.ts +112 -0
  993. package/src/interactive/renderers/diff.ts +137 -0
  994. package/src/interactive/renderers/mermaid.ts +53 -0
  995. package/src/interactive/renderers/notice.ts +28 -0
  996. package/src/interactive/renderers/retry-status.ts +31 -0
  997. package/src/interactive/renderers/structured.ts +89 -0
  998. package/src/interactive/renderers/tool-execution.ts +1357 -0
  999. package/src/interactive/renderers/worker-entry.ts +280 -0
  1000. package/src/interactive/session-last-turn.ts +186 -0
  1001. package/src/interactive/session-switch-settlement.ts +10 -0
  1002. package/src/interactive/session-transcript.ts +105 -0
  1003. package/src/interactive/session-usage-reseed.ts +74 -0
  1004. package/src/interactive/slash-autocomplete.ts +256 -0
  1005. package/src/interactive/slash-commands.ts +1407 -0
  1006. package/src/interactive/slash-spec.ts +424 -0
  1007. package/src/interactive/status/controller.ts +260 -0
  1008. package/src/interactive/status/index.ts +23 -0
  1009. package/src/interactive/status/state-machine.ts +530 -0
  1010. package/src/interactive/status/summary.ts +170 -0
  1011. package/src/interactive/status/types.ts +121 -0
  1012. package/src/interactive/status/verbs.ts +163 -0
  1013. package/src/interactive/status/watchdog.ts +24 -0
  1014. package/src/interactive/stdout-backpressure.ts +99 -0
  1015. package/src/interactive/stream-pacer.ts +530 -0
  1016. package/src/interactive/stream-pacing-policy.ts +66 -0
  1017. package/src/interactive/tasks-overlay.ts +540 -0
  1018. package/src/interactive/terminal-lease.ts +485 -0
  1019. package/src/interactive/theme/components.ts +55 -0
  1020. package/src/interactive/theme/glyphs.ts +70 -0
  1021. package/src/interactive/theme/index.ts +15 -0
  1022. package/src/interactive/theme/labels.ts +88 -0
  1023. package/src/interactive/theme/rules.ts +138 -0
  1024. package/src/interactive/theme/segments.ts +88 -0
  1025. package/src/interactive/theme/tokens.ts +121 -0
  1026. package/src/interactive/thinking-level-policy.ts +6 -0
  1027. package/src/interactive/tool-prose-loop.ts +122 -0
  1028. package/src/interactive/tool-prose-registration.ts +48 -0
  1029. package/src/interactive/turn-context.ts +855 -0
  1030. package/src/interactive/turn-middleware.ts +283 -0
  1031. package/src/interactive/turn-persistence.ts +458 -0
  1032. package/src/interactive/turn-queues.ts +181 -0
  1033. package/src/interactive/turn-recovery.ts +323 -0
  1034. package/src/interactive/turn-runtime.ts +869 -0
  1035. package/src/interactive/turn-state.ts +133 -0
  1036. package/src/interactive/view/artifacts.ts +1452 -0
  1037. package/src/interactive/view/view-overlay.ts +735 -0
  1038. package/src/interactive/welcome-dashboard.ts +537 -0
  1039. package/src/interactive/worker-receipts.ts +143 -0
  1040. package/src/interactive/worker-replay.ts +111 -0
  1041. package/src/interactive/worker-share.ts +100 -0
  1042. package/src/interactive/worker-stream.ts +446 -0
  1043. package/src/interactive/workspace-facts.ts +141 -0
  1044. package/src/tools/agent-tools.ts +402 -0
  1045. package/src/tools/artifact.ts +103 -0
  1046. package/src/tools/ask-user.ts +666 -0
  1047. package/src/tools/bash.ts +204 -0
  1048. package/src/tools/bootstrap.ts +77 -0
  1049. package/src/tools/builtin-tool-catalog.ts +265 -0
  1050. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  1051. package/src/tools/codewiki/code-nav.ts +549 -0
  1052. package/src/tools/codewiki/shared.ts +118 -0
  1053. package/src/tools/compete-worktrees.ts +898 -0
  1054. package/src/tools/context/docs-engine.ts +630 -0
  1055. package/src/tools/context/index.ts +514 -0
  1056. package/src/tools/context/surface.ts +19 -0
  1057. package/src/tools/core-bootstrap.ts +168 -0
  1058. package/src/tools/credential-present.ts +151 -0
  1059. package/src/tools/dispatch-admission.ts +533 -0
  1060. package/src/tools/dispatch-arguments.ts +228 -0
  1061. package/src/tools/dispatch-background.ts +54 -0
  1062. package/src/tools/dispatch-event-text.ts +6 -0
  1063. package/src/tools/dispatch-plan.ts +746 -0
  1064. package/src/tools/dispatch-run-events.ts +238 -0
  1065. package/src/tools/dispatch-runner.ts +2370 -0
  1066. package/src/tools/dispatch-scout-admission.ts +295 -0
  1067. package/src/tools/dispatch-scout.ts +461 -0
  1068. package/src/tools/dispatch-types.ts +77 -0
  1069. package/src/tools/dispatch.ts +244 -0
  1070. package/src/tools/edit-diff.ts +534 -0
  1071. package/src/tools/edit.ts +128 -0
  1072. package/src/tools/executables.ts +22 -0
  1073. package/src/tools/file-mutation-queue.ts +35 -0
  1074. package/src/tools/find.ts +294 -0
  1075. package/src/tools/grep.ts +495 -0
  1076. package/src/tools/ignore-policy.ts +169 -0
  1077. package/src/tools/lazy-tool.ts +60 -0
  1078. package/src/tools/ledger.ts +206 -0
  1079. package/src/tools/ls.ts +110 -0
  1080. package/src/tools/monitor-surface.ts +36 -0
  1081. package/src/tools/monitor.ts +767 -0
  1082. package/src/tools/network-policy.ts +29 -0
  1083. package/src/tools/observation.ts +421 -0
  1084. package/src/tools/observers.ts +99 -0
  1085. package/src/tools/path-utils.ts +79 -0
  1086. package/src/tools/policy.ts +154 -0
  1087. package/src/tools/profiles.ts +108 -0
  1088. package/src/tools/read.ts +173 -0
  1089. package/src/tools/registry.ts +1169 -0
  1090. package/src/tools/result-shaping.ts +204 -0
  1091. package/src/tools/safe-exec.ts +128 -0
  1092. package/src/tools/spawn-hygiene.ts +182 -0
  1093. package/src/tools/steer-surface.ts +17 -0
  1094. package/src/tools/steer.ts +77 -0
  1095. package/src/tools/tasks.ts +265 -0
  1096. package/src/tools/truncate-utf8.ts +17 -0
  1097. package/src/tools/truncate.ts +43 -0
  1098. package/src/tools/verify/frontend.ts +687 -0
  1099. package/src/tools/verify/index.ts +31 -0
  1100. package/src/tools/verify/scripts.ts +108 -0
  1101. package/src/tools/verify/surface.ts +46 -0
  1102. package/src/tools/web-fetch-surface.ts +23 -0
  1103. package/src/tools/web-fetch.ts +759 -0
  1104. package/src/tools/worker-evidence.ts +215 -0
  1105. package/src/tools/write.ts +57 -0
  1106. package/src/utils/exif-orientation.ts +192 -0
  1107. package/src/utils/git.ts +24 -0
  1108. package/src/utils/image-resize.ts +148 -0
  1109. package/src/utils/photon.ts +103 -0
  1110. package/src/worker/control-lane.ts +22 -0
  1111. package/src/worker/entry.ts +294 -0
  1112. package/src/worker/event-projection.ts +56 -0
  1113. package/src/worker/heartbeat.ts +24 -0
  1114. package/src/worker/ledger-mirror.ts +95 -0
  1115. package/src/worker/ndjson.ts +40 -0
  1116. package/src/worker/protocol.ts +529 -0
  1117. package/src/worker/resource-facts.ts +79 -0
  1118. package/src/worker/runtime-registry.ts +12 -0
  1119. package/src/worker/spec-contract.ts +675 -0
  1120. package/src/worker/stdin-demux.ts +316 -0
  1121. package/dist/acp-UMLFVA3F.js +0 -92
  1122. package/dist/chunk-262G75JS.js +0 -35
  1123. package/dist/chunk-6CWDTGUC.js +0 -20
  1124. package/dist/chunk-BYEU76JP.js +0 -899
  1125. package/dist/chunk-GNGDQYDU.js +0 -34688
  1126. package/dist/chunk-GOTUR54M.js +0 -9
  1127. package/dist/chunk-NI4DEJMC.js +0 -88
  1128. package/dist/chunk-TPOCL34A.js +0 -2876
  1129. package/dist/chunk-UU3R62TT.js +0 -128
  1130. package/dist/clio-KIQ5SNDS.js +0 -53
  1131. package/dist/configure-G4E3A2PG.js +0 -27
  1132. package/dist/doctor-M5HJJZOL.js +0 -61
  1133. package/dist/domains/agents/builtins/architect.md +0 -33
  1134. package/dist/domains/agents/builtins/coder.md +0 -31
  1135. package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
  1136. package/dist/domains/agents/builtins/debugger.md +0 -30
  1137. package/dist/domains/agents/builtins/documenter.md +0 -31
  1138. package/dist/domains/agents/builtins/git-master.md +0 -30
  1139. package/dist/domains/agents/builtins/provenance.md +0 -30
  1140. package/dist/domains/agents/builtins/researcher.md +0 -71
  1141. package/dist/domains/agents/builtins/scout.md +0 -42
  1142. package/dist/domains/agents/builtins/tester.md +0 -31
  1143. package/dist/domains/agents/builtins/verifier.md +0 -30
  1144. package/dist/domains/agents/builtins/wiki-writer.md +0 -41
  1145. package/dist/fleet-preflight-CLIAX7YR.js +0 -21
  1146. package/dist/preload-KZVHET2B.js +0 -11
  1147. package/dist/version-ROZ6CZKH.js +0 -16
  1148. package/docs/html/agents_blueprint.html +0 -936
  1149. package/docs/html/alcf_blueprint.html +0 -324
  1150. package/docs/html/architecture_blueprint.html +0 -850
  1151. package/docs/html/commands_blueprint.html +0 -794
  1152. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  1153. package/docs/html/configuration_blueprint.html +0 -1080
  1154. package/docs/html/context_blueprint.html +0 -603
  1155. package/docs/html/documentation_blueprint.html +0 -832
  1156. package/docs/html/environment_blueprint.html +0 -404
  1157. package/docs/html/eval_blueprint.html +0 -743
  1158. package/docs/html/evals_internal_blueprint.html +0 -190
  1159. package/docs/html/evolution_blueprint.html +0 -674
  1160. package/docs/html/extensions_blueprint.html +0 -2065
  1161. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  1162. package/docs/html/index.html +0 -919
  1163. package/docs/html/lifecycle_blueprint.html +0 -723
  1164. package/docs/html/memory_blueprint.html +0 -699
  1165. package/docs/html/middleware_blueprint.html +0 -664
  1166. package/docs/html/models_blueprint.html +0 -2366
  1167. package/docs/html/observability_blueprint.html +0 -683
  1168. package/docs/html/provider_adapter_blueprint.html +0 -245
  1169. package/docs/html/safety_blueprint.html +0 -1386
  1170. package/docs/html/shared.css +0 -571
  1171. package/docs/html/shared.js +0 -143
  1172. package/docs/html/skills_blueprint.html +0 -671
  1173. package/docs/html/soak_blueprint.html +0 -182
  1174. package/docs/html/tool_usage_blueprint.html +0 -350
  1175. package/docs/html/tools_blueprint.html +0 -2249
  1176. package/docs/html/trace_blueprint.html +0 -235
  1177. package/docs/html/tui_design_blueprint.html +0 -314
  1178. package/docs/html/validation_blueprint.html +0 -961
  1179. package/docs/html/worker_dispatch_blueprint.html +0 -231
  1180. package/skills/git/commit-crafting/SKILL.md +0 -79
  1181. package/skills/git/commit-crafting/evals.md +0 -92
  1182. package/skills/git/create-pr/SKILL.md +0 -116
  1183. package/skills/git/create-pr/evals.md +0 -114
  1184. package/skills/git/investigate-issue/SKILL.md +0 -139
  1185. package/skills/git/investigate-issue/evals.md +0 -94
  1186. package/skills/git/review-changes/SKILL.md +0 -103
  1187. package/skills/git/review-changes/evals.md +0 -85
@@ -0,0 +1,1529 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, readFileSync, statSync } from "node:fs";
3
+ import { readFile as readFileAsync } from "node:fs/promises";
4
+ import { dirname, join, relative, resolve } from "node:path";
5
+ import { classifyCHeaderLanguage, isAmbiguousHeaderPath } from "../../../core/c-header-language.js";
6
+ import { safeResourceWrite } from "../../../core/safe-resource-write.js";
7
+ import { enumerateWorkspaceFilesAsync, filterWorkspaceFileCandidates } from "../../../core/workspace-files.js";
8
+ import type { ProjectType } from "../../session/workspace/project-type.js";
9
+ import { EXCLUDED_DIRS } from "../excluded-dirs.js";
10
+ import { extractCMake, isCMakePath } from "./cmake.js";
11
+ import { type CooperativeSlicer, createSlicer } from "./cooperative.js";
12
+ import { isIndexablePath, languageForPath } from "./paths.js";
13
+ import {
14
+ type BuildCodewikiInput,
15
+ CODEWIKI_VERSION,
16
+ type Codewiki,
17
+ type CodewikiEdge,
18
+ type CodewikiEntry,
19
+ type CodewikiExternalEdge,
20
+ type CodewikiFile,
21
+ type CodewikiFileRole,
22
+ type CodewikiInternalEdge,
23
+ type CodewikiLanguage,
24
+ type CodewikiReadFile,
25
+ type CodewikiSymbol,
26
+ type CodewikiSymbolKind,
27
+ type ExtractedSymbol,
28
+ type LanguageExtraction,
29
+ type LanguageExtractor,
30
+ } from "./schema.js";
31
+ import type { TreeSitterExtractor } from "./tree-sitter.js";
32
+
33
+ export {
34
+ type BuildCodewikiInput,
35
+ CODEWIKI_VERSION,
36
+ type Codewiki,
37
+ type CodewikiEdge,
38
+ type CodewikiEntry,
39
+ type CodewikiExternalEdge,
40
+ type CodewikiFile,
41
+ type CodewikiFileRole,
42
+ type CodewikiInternalEdge,
43
+ type CodewikiLanguage,
44
+ type CodewikiReadFile,
45
+ type CodewikiSymbol,
46
+ type CodewikiSymbolKind,
47
+ type ExtractedSymbol,
48
+ type LanguageExtraction,
49
+ type LanguageExtractor,
50
+ } from "./schema.js";
51
+
52
+ const CODEWIKI_SYMBOL_KINDS_WITH_SIG = new Set<CodewikiSymbolKind>(["func", "class", "method", "type"]);
53
+
54
+ export interface CodewikiBuildOptions {
55
+ readFile?: CodewikiReadFile;
56
+ /**
57
+ * Slice budget shared across a whole index run. Callers that chain several
58
+ * phases pass one slicer so the budget applies end to end rather than
59
+ * resetting at each phase boundary. Defaults to a fresh slicer.
60
+ */
61
+ slicer?: CooperativeSlicer;
62
+ }
63
+
64
+ let treeSitterExtractorPromise: Promise<TreeSitterExtractor> | null = null;
65
+
66
+ function loadTreeSitterExtractor(): Promise<TreeSitterExtractor> {
67
+ treeSitterExtractorPromise ??= import("./tree-sitter.js").then(({ createTreeSitterExtractor }) =>
68
+ createTreeSitterExtractor(),
69
+ );
70
+ return treeSitterExtractorPromise;
71
+ }
72
+
73
+ const RESOLUTION_EXTENSIONS = [
74
+ ".ts",
75
+ ".tsx",
76
+ ".mts",
77
+ ".cts",
78
+ ".js",
79
+ ".jsx",
80
+ ".mjs",
81
+ ".cjs",
82
+ ".py",
83
+ ".go",
84
+ ".rs",
85
+ ".c",
86
+ ".h",
87
+ ".cc",
88
+ ".cpp",
89
+ ".cxx",
90
+ ".hpp",
91
+ ".hh",
92
+ ".hxx",
93
+ ".cu",
94
+ ".cuh",
95
+ ".java",
96
+ ".rb",
97
+ ".cs",
98
+ ];
99
+
100
+ function compareStrings(a: string, b: string): number {
101
+ return a.localeCompare(b);
102
+ }
103
+
104
+ function stableFileId(path: string): string {
105
+ return `f_${createHash("sha256").update(path).digest("hex").slice(0, 16)}`;
106
+ }
107
+
108
+ function contentHash(text: string): string {
109
+ return createHash("sha256").update(text).digest("hex").slice(0, 16);
110
+ }
111
+
112
+ function defaultReadFile(path: string): string | null {
113
+ try {
114
+ return readFileSync(path, "utf8");
115
+ } catch {
116
+ return null;
117
+ }
118
+ }
119
+
120
+ function normalizeRel(cwd: string, filePath: string): string {
121
+ return relative(cwd, filePath).split("\\").join("/");
122
+ }
123
+
124
+ function normalizeInputPath(path: string): string {
125
+ return path.split("\\").join("/").replace(/^\.\//, "");
126
+ }
127
+
128
+ export { isIndexablePath } from "./paths.js";
129
+
130
+ function lineCount(text: string): number {
131
+ if (text.length === 0) return 0;
132
+ return text.endsWith("\n") ? text.split("\n").length - 1 : text.split("\n").length;
133
+ }
134
+
135
+ function roleFor(relPath: string, language: CodewikiLanguage): CodewikiFileRole {
136
+ if (language === "config") return "config";
137
+ const lower = relPath.toLowerCase();
138
+ if (
139
+ lower.includes("/test/") ||
140
+ lower.includes("/tests/") ||
141
+ /\.(test|spec)\.[cm]?[jt]sx?$/.test(lower) ||
142
+ /(^|\/)test_.*\.py$/.test(lower) ||
143
+ /(^|\/).*_test\.(go|rs|rb)$/.test(lower)
144
+ ) {
145
+ return "test";
146
+ }
147
+ if (/(^|\/)(index|main|server|cli|orchestrator|bootstrap)\.[^.]+$/.test(lower) || lower.endsWith("/__main__.py")) {
148
+ return "entry";
149
+ }
150
+ return "module";
151
+ }
152
+
153
+ function firstDocSummary(text: string): string | null {
154
+ const jsDoc = /\/\*\*([\s\S]*?)\*\//.exec(text)?.[1];
155
+ const pythonDoc = /^\s*(?:"""([\s\S]*?)"""|'''([\s\S]*?)''')/.exec(text);
156
+ const raw = jsDoc ?? pythonDoc?.[1] ?? pythonDoc?.[2];
157
+ if (!raw) return null;
158
+ const cleaned = raw
159
+ .split("\n")
160
+ .map((line) => line.replace(/^\s*\*\s?/, "").trim())
161
+ .filter((line) => line.length > 0 && !line.startsWith("@"))
162
+ .join(" ")
163
+ .replace(/\s+/g, " ")
164
+ .trim();
165
+ return cleaned.length > 0 ? cleaned.slice(0, 160) : null;
166
+ }
167
+
168
+ function sanitizeSymbolName(value: string): string {
169
+ return value
170
+ .trim()
171
+ .replace(/^self\./, "")
172
+ .replace(/^this\./, "")
173
+ .slice(0, 160);
174
+ }
175
+
176
+ function addSymbol(
177
+ target: ExtractedSymbol[],
178
+ seen: Set<string>,
179
+ name: string | undefined,
180
+ kind: CodewikiSymbolKind,
181
+ line: number,
182
+ sig?: string,
183
+ ): void {
184
+ if (!name) return;
185
+ const clean = sanitizeSymbolName(name);
186
+ if (clean.length === 0) return;
187
+ const key = `${clean}\0${kind}\0${line}`;
188
+ if (seen.has(key)) return;
189
+ seen.add(key);
190
+ target.push({
191
+ name: clean,
192
+ kind,
193
+ line,
194
+ ...(sig && sig.trim().length > 0 ? { sig: sig.trim().slice(0, 240) } : {}),
195
+ });
196
+ }
197
+
198
+ function uniqueSorted(values: Iterable<string>): string[] {
199
+ return [...new Set([...values].filter((item) => item.length > 0))].sort(compareStrings);
200
+ }
201
+
202
+ function extractWithLineRegex(
203
+ text: string,
204
+ patterns: ReadonlyArray<{ regex: RegExp; kind: CodewikiSymbolKind; nameIndex?: number }>,
205
+ ): ExtractedSymbol[] {
206
+ const symbols: ExtractedSymbol[] = [];
207
+ const seen = new Set<string>();
208
+ const lines = text.split(/\r?\n/);
209
+ for (const [index, line] of lines.entries()) {
210
+ for (const pattern of patterns) {
211
+ const match = pattern.regex.exec(line);
212
+ if (!match) continue;
213
+ const name = match[pattern.nameIndex ?? 1];
214
+ addSymbol(symbols, seen, name, pattern.kind, index + 1, line.trim());
215
+ }
216
+ }
217
+ return symbols.sort(compareSymbols);
218
+ }
219
+
220
+ function compareSymbols(
221
+ a: Pick<CodewikiSymbol, "name" | "kind" | "line">,
222
+ b: Pick<CodewikiSymbol, "name" | "kind" | "line">,
223
+ ): number {
224
+ return a.line - b.line || a.name.localeCompare(b.name) || a.kind.localeCompare(b.kind);
225
+ }
226
+
227
+ function extractMatches(text: string, regex: RegExp, group = 1): string[] {
228
+ const out: string[] = [];
229
+ for (const match of text.matchAll(regex)) {
230
+ const value = match[group];
231
+ if (value) out.push(value);
232
+ }
233
+ return out;
234
+ }
235
+
236
+ interface CFamilyAliasStatement {
237
+ text: string;
238
+ masked: string;
239
+ line: number;
240
+ }
241
+
242
+ function maskCFamilyCommentsAndStrings(text: string): string {
243
+ // split("") preserves UTF-16 offsets so slices of the masked text line up
244
+ // exactly with slices of the original source, including astral characters.
245
+ const chars = text.split("");
246
+ let state: "code" | "line-comment" | "block-comment" | "single-quote" | "double-quote" = "code";
247
+ for (let index = 0; index < chars.length; index += 1) {
248
+ const current = chars[index] ?? "";
249
+ const next = chars[index + 1] ?? "";
250
+ if (state === "code") {
251
+ if (current === "/" && next === "/") {
252
+ chars[index] = " ";
253
+ chars[index + 1] = " ";
254
+ state = "line-comment";
255
+ index += 1;
256
+ } else if (current === "/" && next === "*") {
257
+ chars[index] = " ";
258
+ chars[index + 1] = " ";
259
+ state = "block-comment";
260
+ index += 1;
261
+ } else if (current === "'") {
262
+ chars[index] = " ";
263
+ state = "single-quote";
264
+ } else if (current === '"') {
265
+ chars[index] = " ";
266
+ state = "double-quote";
267
+ }
268
+ continue;
269
+ }
270
+ if (current === "\n") {
271
+ if (state === "line-comment") state = "code";
272
+ continue;
273
+ }
274
+ chars[index] = " ";
275
+ if (state === "block-comment" && current === "*" && next === "/") {
276
+ chars[index + 1] = " ";
277
+ state = "code";
278
+ index += 1;
279
+ continue;
280
+ }
281
+ if ((state === "single-quote" || state === "double-quote") && current === "\\") {
282
+ if (index + 1 < chars.length && chars[index + 1] !== "\n") {
283
+ chars[index + 1] = " ";
284
+ index += 1;
285
+ }
286
+ continue;
287
+ }
288
+ if (state === "single-quote" && current === "'") state = "code";
289
+ if (state === "double-quote" && current === '"') state = "code";
290
+ }
291
+ return chars.join("");
292
+ }
293
+
294
+ function cFamilyAliasStatements(text: string): CFamilyAliasStatement[] {
295
+ const masked = maskCFamilyCommentsAndStrings(text);
296
+ const statements: CFamilyAliasStatement[] = [];
297
+ const token = /\b(?:typedef|using)\b/g;
298
+ for (let match = token.exec(masked); match; match = token.exec(masked)) {
299
+ const start = match.index;
300
+ const lineStart = masked.lastIndexOf("\n", start - 1) + 1;
301
+ if (masked.slice(lineStart, start).trimStart().startsWith("#")) continue;
302
+ let braces = 0;
303
+ let parentheses = 0;
304
+ let brackets = 0;
305
+ let end = -1;
306
+ for (let index = token.lastIndex; index < masked.length; index += 1) {
307
+ const current = masked[index];
308
+ if (current === "{") braces += 1;
309
+ else if (current === "}") braces = Math.max(0, braces - 1);
310
+ else if (current === "(") parentheses += 1;
311
+ else if (current === ")") parentheses = Math.max(0, parentheses - 1);
312
+ else if (current === "[") brackets += 1;
313
+ else if (current === "]") brackets = Math.max(0, brackets - 1);
314
+ else if (current === ";" && braces === 0 && parentheses === 0 && brackets === 0) {
315
+ end = index + 1;
316
+ break;
317
+ }
318
+ }
319
+ if (end === -1) continue;
320
+ statements.push({
321
+ text: text.slice(start, end),
322
+ masked: masked.slice(start, end),
323
+ line: 1 + Array.from(masked.slice(0, start).matchAll(/\n/g)).length,
324
+ });
325
+ token.lastIndex = end;
326
+ }
327
+ return statements;
328
+ }
329
+
330
+ function stripCFamilyBraceBodies(statement: string): string {
331
+ let depth = 0;
332
+ let result = "";
333
+ for (const current of statement) {
334
+ if (current === "{") {
335
+ depth += 1;
336
+ result += " ";
337
+ continue;
338
+ }
339
+ if (current === "}") {
340
+ depth = Math.max(0, depth - 1);
341
+ result += " ";
342
+ continue;
343
+ }
344
+ result += depth === 0 || current === "\n" ? current : " ";
345
+ }
346
+ return result;
347
+ }
348
+
349
+ function splitCFamilyDeclarators(value: string): string[] {
350
+ const parts: string[] = [];
351
+ let start = 0;
352
+ let parentheses = 0;
353
+ let brackets = 0;
354
+ let angles = 0;
355
+ for (let index = 0; index < value.length; index += 1) {
356
+ const current = value[index];
357
+ if (current === "(") parentheses += 1;
358
+ else if (current === ")") parentheses = Math.max(0, parentheses - 1);
359
+ else if (current === "[") brackets += 1;
360
+ else if (current === "]") brackets = Math.max(0, brackets - 1);
361
+ else if (current === "<") angles += 1;
362
+ else if (current === ">") angles = Math.max(0, angles - 1);
363
+ else if (current === "," && parentheses === 0 && brackets === 0 && angles === 0) {
364
+ parts.push(value.slice(start, index));
365
+ start = index + 1;
366
+ }
367
+ }
368
+ parts.push(value.slice(start));
369
+ return parts;
370
+ }
371
+
372
+ const C_FAMILY_TYPE_WORDS = new Set([
373
+ "typedef",
374
+ "const",
375
+ "volatile",
376
+ "restrict",
377
+ "signed",
378
+ "unsigned",
379
+ "short",
380
+ "long",
381
+ "void",
382
+ "char",
383
+ "int",
384
+ "float",
385
+ "double",
386
+ "struct",
387
+ "union",
388
+ "enum",
389
+ "class",
390
+ "typename",
391
+ "auto",
392
+ ]);
393
+
394
+ function stripTrailingCFamilyDeclaratorSuffixes(value: string): string {
395
+ let end = value.length;
396
+ while (end > 0) {
397
+ while (end > 0 && /\s/.test(value[end - 1] ?? "")) end -= 1;
398
+ const close = value[end - 1];
399
+ if (close !== ")" && close !== "]") break;
400
+ const open = close === ")" ? "(" : "[";
401
+ let depth = 1;
402
+ let start = end - 1;
403
+ for (start -= 1; start >= 0; start -= 1) {
404
+ const current = value[start];
405
+ if (current === close) depth += 1;
406
+ else if (current === open) {
407
+ depth -= 1;
408
+ if (depth === 0) break;
409
+ }
410
+ }
411
+ if (start < 0) break;
412
+ // A suffix follows an identifier, another completed declarator group, or
413
+ // an array. A standalone `(Alias)` is a wrapper around the name itself and
414
+ // must remain available to the identifier search below. Requiring direct
415
+ // adjacency is what distinguishes `callable_t(...)` from `int (Wrapped)`.
416
+ if (start === 0 || !/[A-Za-z_0-9)\]]/.test(value[start - 1] ?? "")) break;
417
+ end = start;
418
+ }
419
+ return value.slice(0, end);
420
+ }
421
+
422
+ function cFamilyTypedefNames(maskedStatement: string): string[] {
423
+ const withoutBodies = stripCFamilyBraceBodies(maskedStatement)
424
+ .replace(/^\s*typedef\b/, "")
425
+ .replace(/;\s*$/, "");
426
+ const names: string[] = [];
427
+ for (const declarator of splitCFamilyDeclarators(withoutBodies)) {
428
+ const functionPointerNames = Array.from(
429
+ declarator.matchAll(
430
+ /\(\s*(?:[A-Za-z_]\w*\s+)*[*&]+\s*(?:(?:const|volatile|restrict)\s+)*([A-Za-z_]\w*)\s*(?:\[[^\]]*\]\s*)*\)(?=\s*\()/g,
431
+ ),
432
+ (match) => match[1] ?? "",
433
+ ).filter((name) => name.length > 0);
434
+ if (functionPointerNames.length > 0) {
435
+ names.push(...functionPointerNames);
436
+ continue;
437
+ }
438
+ const declaratorWithoutSuffixes = stripTrailingCFamilyDeclaratorSuffixes(declarator);
439
+ const identifiers = Array.from(declaratorWithoutSuffixes.matchAll(/\b[A-Za-z_]\w*\b/g), (match) => match[0]).filter(
440
+ (name) => !C_FAMILY_TYPE_WORDS.has(name),
441
+ );
442
+ const name = identifiers.at(-1);
443
+ if (name) names.push(name);
444
+ }
445
+ return uniqueSorted(names);
446
+ }
447
+
448
+ function extractCFamilyAliasSymbols(text: string): ExtractedSymbol[] {
449
+ const symbols: ExtractedSymbol[] = [];
450
+ const seen = new Set<string>();
451
+ for (const statement of cFamilyAliasStatements(text)) {
452
+ const usingName = /^\s*using\s+([A-Za-z_]\w*)\s*=/.exec(statement.masked)?.[1];
453
+ const names = usingName
454
+ ? [usingName]
455
+ : /^\s*typedef\b/.test(statement.masked)
456
+ ? cFamilyTypedefNames(statement.masked)
457
+ : [];
458
+ const signature = statement.text.replace(/\s+/g, " ").trim();
459
+ for (const name of names) addSymbol(symbols, seen, name, "type", statement.line, signature);
460
+ }
461
+ return symbols;
462
+ }
463
+
464
+ const tsJsExtractor: LanguageExtractor = {
465
+ langs: ["typescript", "javascript"],
466
+ extractImports(_path, text) {
467
+ return uniqueSorted([
468
+ ...extractMatches(text, /\bimport\s+(?:type\s+)?(?:[^'"]*?\s+from\s+)?["']([^"']+)["']/g),
469
+ ...extractMatches(text, /\bexport\s+[^'"]*?\s+from\s+["']([^"']+)["']/g),
470
+ ...extractMatches(text, /\brequire\s*\(\s*["']([^"']+)["']\s*\)/g),
471
+ ...extractMatches(text, /\bimport\s*\(\s*["']([^"']+)["']\s*\)/g),
472
+ ]);
473
+ },
474
+ extract(_path, text) {
475
+ const symbols = extractWithLineRegex(text, [
476
+ { regex: /^\s*export\s+default\s+(?:async\s+)?function\s+([A-Za-z_$][\w$]*)?/, kind: "func" },
477
+ { regex: /^\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)\s*\(/, kind: "func" },
478
+ { regex: /^\s*(?:export\s+)?class\s+([A-Za-z_$][\w$]*)\b/, kind: "class" },
479
+ { regex: /^\s*(?:export\s+)?interface\s+([A-Za-z_$][\w$]*)\b/, kind: "iface" },
480
+ { regex: /^\s*(?:export\s+)?type\s+([A-Za-z_$][\w$]*)\b/, kind: "type" },
481
+ { regex: /^\s*(?:export\s+)?enum\s+([A-Za-z_$][\w$]*)\b/, kind: "type" },
482
+ { regex: /^(?:\s*export\s+)?const\s+([A-Za-z_$][\w$]*)\b/, kind: "const" },
483
+ { regex: /^(?:\s*export\s+)?(?:let|var)\s+([A-Za-z_$][\w$]*)\b/, kind: "var" },
484
+ {
485
+ regex:
486
+ /^(?: {2,}|\t+)(?:public\s+|private\s+|protected\s+|static\s+|override\s+|abstract\s+|async\s+|get\s+|set\s+)*(?!(?:if|for|while|switch|catch|return|typeof|else|do|new|await|yield)\b)([A-Za-z_$][\w$]*)\s*\([^)]*\)\s*\{?$/,
487
+ kind: "method",
488
+ },
489
+ ]);
490
+ return { symbols, imports: tsJsExtractor.extractImports?.(_path, text) ?? [] };
491
+ },
492
+ };
493
+
494
+ const pythonExtractor: LanguageExtractor = {
495
+ langs: ["python"],
496
+ extractImports(_path, text) {
497
+ return uniqueSorted([
498
+ ...extractMatches(text, /^\s*import\s+([A-Za-z_][\w.]*)(?:\s+as\s+\w+)?/gm),
499
+ ...extractMatches(text, /^\s*from\s+([.\w]+)\s+import\s+/gm),
500
+ ]);
501
+ },
502
+ extract(_path, text) {
503
+ const rawSymbols = extractWithLineRegex(text, [
504
+ { regex: /^(\s*)def\s+([A-Za-z_]\w*)\s*\(/, kind: "func", nameIndex: 2 },
505
+ { regex: /^(\s*)async\s+def\s+([A-Za-z_]\w*)\s*\(/, kind: "func", nameIndex: 2 },
506
+ { regex: /^\s*class\s+([A-Za-z_]\w*)\b/, kind: "class" },
507
+ { regex: /^([A-Z][A-Z0-9_]*)\s*=/, kind: "const" },
508
+ { regex: /^([A-Za-z_]\w*)\s*=/, kind: "var" },
509
+ ]);
510
+ const symbols: ExtractedSymbol[] = rawSymbols.map((symbol) => {
511
+ if ((symbol.kind === "func" || symbol.kind === "var") && /^\s+/.test(symbol.sig ?? "")) {
512
+ return { ...symbol, kind: symbol.kind === "func" ? "method" : symbol.kind };
513
+ }
514
+ return symbol;
515
+ });
516
+ return { symbols: symbols.sort(compareSymbols), imports: pythonExtractor.extractImports?.(_path, text) ?? [] };
517
+ },
518
+ };
519
+
520
+ const goExtractor: LanguageExtractor = {
521
+ langs: ["go"],
522
+ extractImports(_path, text) {
523
+ return uniqueSorted([
524
+ ...extractMatches(text, /^\s*import\s+"([^"]+)"/gm),
525
+ ...extractMatches(text, /^\s*"([^"]+)"\s*$/gm),
526
+ ]);
527
+ },
528
+ extract(_path, text) {
529
+ const rawSymbols = extractWithLineRegex(text, [
530
+ { regex: /^\s*func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)\s*\(/, kind: "func" },
531
+ { regex: /^\s*type\s+([A-Za-z_]\w*)\s+interface\b/, kind: "iface" },
532
+ { regex: /^\s*type\s+([A-Za-z_]\w*)\s+struct\b/, kind: "type" },
533
+ { regex: /^\s*type\s+([A-Za-z_]\w*)\b/, kind: "type" },
534
+ { regex: /^const\s+([A-Za-z_]\w*)\b/, kind: "const" },
535
+ { regex: /^var\s+([A-Za-z_]\w*)\b/, kind: "var" },
536
+ ]);
537
+ const symbols: ExtractedSymbol[] = rawSymbols.map((symbol) => {
538
+ if (symbol.kind === "func" && /^\s*func\s+\(/.test(symbol.sig ?? "")) return { ...symbol, kind: "method" };
539
+ return symbol;
540
+ });
541
+ return { symbols: symbols.sort(compareSymbols), imports: goExtractor.extractImports?.(_path, text) ?? [] };
542
+ },
543
+ };
544
+
545
+ const rustExtractor: LanguageExtractor = {
546
+ langs: ["rust"],
547
+ extractImports(_path, text) {
548
+ return uniqueSorted([
549
+ ...extractMatches(text, /^\s*use\s+([^;]+);/gm).map((item) => item.trim()),
550
+ ...extractMatches(text, /^\s*extern\s+crate\s+([A-Za-z_]\w*)/gm),
551
+ ]);
552
+ },
553
+ extract(_path, text) {
554
+ const symbols = extractWithLineRegex(text, [
555
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?fn\s+([A-Za-z_]\w*)\s*[<(]/, kind: "func" },
556
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?struct\s+([A-Za-z_]\w*)\b/, kind: "type" },
557
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?enum\s+([A-Za-z_]\w*)\b/, kind: "type" },
558
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?trait\s+([A-Za-z_]\w*)\b/, kind: "trait" },
559
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?type\s+([A-Za-z_]\w*)\b/, kind: "type" },
560
+ { regex: /^(?:\s*pub(?:\([^)]*\))?\s+)?const\s+([A-Za-z_]\w*)\b/, kind: "const" },
561
+ { regex: /^(?:\s*pub(?:\([^)]*\))?\s+)?static\s+([A-Za-z_]\w*)\b/, kind: "var" },
562
+ ]);
563
+ return { symbols, imports: rustExtractor.extractImports?.(_path, text) ?? [] };
564
+ },
565
+ };
566
+
567
+ const cFamilyExtractor: LanguageExtractor = {
568
+ langs: ["c", "c++"],
569
+ extractImports(_path, text) {
570
+ const imports: string[] = [];
571
+ for (const match of text.matchAll(/^\s*#\s*include\s*(?:"([^"]+)"|<([^>]+)>)/gm)) {
572
+ const quoted = match[1];
573
+ const system = match[2];
574
+ if (quoted) imports.push(quoted.startsWith(".") || quoted.startsWith("/") ? quoted : `./${quoted}`);
575
+ else if (system) imports.push(system);
576
+ }
577
+ return uniqueSorted(imports);
578
+ },
579
+ extract(_path, text) {
580
+ const regexSymbols = extractWithLineRegex(text, [
581
+ { regex: /^\s*class\s+([A-Za-z_]\w*)\b/, kind: "class" },
582
+ {
583
+ regex: /^\s*(?:typedef\s+)?(?:struct\s+|union\s+|enum\s+(?:(?:class|struct)\s+)?)([A-Za-z_]\w*)\b/,
584
+ kind: "type",
585
+ },
586
+ {
587
+ regex:
588
+ /^\s*(?!(?:typedef|using)\b)(?:template\s*<[^>]+>\s*)?(?:[A-Za-z_][\w:<>,*&\s]+\s+)+(?:(?:[A-Za-z_]\w*)::)*([~A-Za-z_]\w*)\s*\([^;]*\)\s*(?:const\s*)?(?:noexcept\s*)?(?:;|\{)?$/,
589
+ kind: "func",
590
+ },
591
+ { regex: /^(?:const\s+)?[A-Za-z_][\w:<>,*&\s]+\s+([A-Z][A-Z0-9_]*)\s*=/, kind: "const" },
592
+ ]);
593
+ const symbolsByKey = new Map<string, ExtractedSymbol>();
594
+ for (const symbol of [...regexSymbols, ...extractCFamilyAliasSymbols(text)]) {
595
+ const key = `${symbol.name}\0${symbol.kind}\0${symbol.line}`;
596
+ if (!symbolsByKey.has(key)) symbolsByKey.set(key, symbol);
597
+ }
598
+ const symbols = [...symbolsByKey.values()].sort(compareSymbols);
599
+ return { symbols, imports: cFamilyExtractor.extractImports?.(_path, text) ?? [] };
600
+ },
601
+ };
602
+
603
+ const javaExtractor: LanguageExtractor = {
604
+ langs: ["java"],
605
+ extractImports(_path, text) {
606
+ return uniqueSorted(extractMatches(text, /^\s*import\s+(?:static\s+)?([A-Za-z_][\w.*]*);/gm));
607
+ },
608
+ extract(_path, text) {
609
+ const symbols = extractWithLineRegex(text, [
610
+ { regex: /^\s*(?:public\s+|private\s+|protected\s+|abstract\s+|final\s+)*class\s+([A-Za-z_]\w*)\b/, kind: "class" },
611
+ {
612
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|abstract\s+|final\s+)*interface\s+([A-Za-z_]\w*)\b/,
613
+ kind: "iface",
614
+ },
615
+ { regex: /^\s*(?:public\s+|private\s+|protected\s+|abstract\s+|final\s+)*enum\s+([A-Za-z_]\w*)\b/, kind: "type" },
616
+ {
617
+ regex:
618
+ /^\s*(?:public\s+|private\s+|protected\s+|static\s+|final\s+|synchronized\s+)*[A-Za-z_][\w<>,[\]\s]*\s+([A-Za-z_]\w*)\s*\([^)]*\)\s*\{?$/,
619
+ kind: "method",
620
+ },
621
+ {
622
+ regex: /^\s*public\s+(?:static\s+|final\s+)*[A-Za-z_][\w<>,[\]\s]*\s+([A-Z][A-Z0-9_]*)\s*=/,
623
+ kind: "const",
624
+ },
625
+ ]);
626
+ return { symbols, imports: javaExtractor.extractImports?.(_path, text) ?? [] };
627
+ },
628
+ };
629
+
630
+ const rubyExtractor: LanguageExtractor = {
631
+ langs: ["ruby"],
632
+ extractImports(_path, text) {
633
+ return uniqueSorted([
634
+ ...extractMatches(text, /^\s*require\s+["']([^"']+)["']/gm),
635
+ ...extractMatches(text, /^\s*require_relative\s+["']([^"']+)["']/gm).map((item) => `./${item}`),
636
+ ]);
637
+ },
638
+ extract(_path, text) {
639
+ const symbols = extractWithLineRegex(text, [
640
+ { regex: /^\s*class\s+([A-Z]\w*(?:::[A-Z]\w*)*)\b/, kind: "class" },
641
+ { regex: /^\s*module\s+([A-Z]\w*(?:::[A-Z]\w*)*)\b/, kind: "type" },
642
+ { regex: /^\s*def\s+(?:self\.)?([A-Za-z_]\w*[!?=]?)\b/, kind: "func" },
643
+ { regex: /^([A-Z][A-Z0-9_]*)\s*=/, kind: "const" },
644
+ ]);
645
+ return { symbols, imports: rubyExtractor.extractImports?.(_path, text) ?? [] };
646
+ },
647
+ };
648
+
649
+ const csharpExtractor: LanguageExtractor = {
650
+ langs: ["c#"],
651
+ extractImports(_path, text) {
652
+ // Mirrors the tree-sitter using-directive handling: static prefixes are
653
+ // stripped and alias directives resolve to their right-hand side.
654
+ return uniqueSorted(
655
+ extractMatches(text, /^\s*using\s+(?:static\s+)?(?:[A-Za-z_]\w*\s*=\s*)?([A-Za-z_][\w.]*)\s*;/gm),
656
+ );
657
+ },
658
+ extract(_path, text) {
659
+ const symbols = extractWithLineRegex(text, [
660
+ {
661
+ regex:
662
+ /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|static\s+|sealed\s+|abstract\s+|partial\s+)*class\s+([A-Za-z_]\w*)\b/,
663
+ kind: "class",
664
+ },
665
+ {
666
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|partial\s+)*interface\s+([A-Za-z_]\w*)\b/,
667
+ kind: "iface",
668
+ },
669
+ {
670
+ regex:
671
+ /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|readonly\s+|partial\s+)*(?:enum|struct|record)\s+([A-Za-z_]\w*)\b/,
672
+ kind: "type",
673
+ },
674
+ {
675
+ regex:
676
+ /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|static\s+|virtual\s+|override\s+|abstract\s+|sealed\s+|async\s+|partial\s+|new\s+)*(?!(?:if|for|foreach|while|switch|catch|return|using|else|do|new|class|interface|enum|struct|record|namespace|lock|throw)\b)[A-Za-z_][\w<>,[\].?\s]*\s+([A-Za-z_]\w*)\s*\([^)]*\)\s*\{?$/,
677
+ kind: "method",
678
+ },
679
+ {
680
+ regex:
681
+ /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|static\s+)*const\s+[A-Za-z_][\w<>,[\]\s]*\s+([A-Za-z_]\w*)\s*=/,
682
+ kind: "const",
683
+ },
684
+ ]);
685
+ return { symbols, imports: csharpExtractor.extractImports?.(_path, text) ?? [] };
686
+ },
687
+ };
688
+
689
+ const fallbackExtractors: ReadonlyArray<LanguageExtractor> = [
690
+ tsJsExtractor,
691
+ pythonExtractor,
692
+ goExtractor,
693
+ rustExtractor,
694
+ cFamilyExtractor,
695
+ javaExtractor,
696
+ rubyExtractor,
697
+ csharpExtractor,
698
+ ];
699
+
700
+ function extractWithExtractors(
701
+ extractors: ReadonlyArray<LanguageExtractor>,
702
+ language: CodewikiLanguage,
703
+ relPath: string,
704
+ text: string,
705
+ ): LanguageExtraction {
706
+ const symbols = new Map<string, ExtractedSymbol>();
707
+ const imports: string[] = [];
708
+ for (const extractor of extractors) {
709
+ if (!extractor.langs.includes(language)) continue;
710
+ const extracted = extractor.extract(relPath, text);
711
+ for (const symbol of extracted.symbols) {
712
+ const key = `${symbol.name}\0${symbol.kind}\0${symbol.line}`;
713
+ if (!symbols.has(key)) symbols.set(key, symbol);
714
+ }
715
+ imports.push(...extracted.imports);
716
+ }
717
+ return {
718
+ symbols: [...symbols.values()].sort(compareSymbols),
719
+ imports: uniqueSorted(imports),
720
+ };
721
+ }
722
+
723
+ function extractImportsWithExtractors(
724
+ extractors: ReadonlyArray<LanguageExtractor>,
725
+ language: CodewikiLanguage,
726
+ relPath: string,
727
+ text: string,
728
+ ): string[] {
729
+ const imports: string[] = [];
730
+ for (const extractor of extractors) {
731
+ if (!extractor.langs.includes(language) || !extractor.extractImports) continue;
732
+ imports.push(...extractor.extractImports(relPath, text));
733
+ }
734
+ return uniqueSorted(imports);
735
+ }
736
+
737
+ interface BuiltFile {
738
+ file: CodewikiFile;
739
+ symbols: CodewikiSymbol[];
740
+ }
741
+
742
+ function mergeTreeSitterWithRegexImports(
743
+ language: CodewikiLanguage,
744
+ relPath: string,
745
+ text: string,
746
+ extracted: LanguageExtraction,
747
+ ): LanguageExtraction {
748
+ const regexImports = extractImportsWithExtractors(fallbackExtractors, language, relPath, text);
749
+ return {
750
+ symbols: extracted.symbols.sort(compareSymbols),
751
+ imports: uniqueSorted([...extracted.imports, ...regexImports]),
752
+ };
753
+ }
754
+
755
+ export function fallbackExtraction(language: CodewikiLanguage, relPath: string, text: string): LanguageExtraction {
756
+ return extractWithExtractors(fallbackExtractors, language, relPath, text);
757
+ }
758
+
759
+ /**
760
+ * Largest source text handed to tree-sitter. The cooperative slicer yields
761
+ * between files, never inside one, so a single parse is the longest stretch the
762
+ * event loop can be held for; measured on this machine that is roughly 0.5 ms
763
+ * per KiB of ordinary source and 2 to 3 ms per KiB of a minified bundle, which
764
+ * made one 9 MiB vendored bundle a 25 s freeze that no shutdown budget could
765
+ * interrupt (issue #99). Nothing hand-written is this big; anything above the
766
+ * cap is generated or vendored, and the regex extractor covers it in tens of
767
+ * milliseconds. Under the cap one parse of ordinary source is a few hundred
768
+ * milliseconds at most; a minified file right at the cap can still take about a
769
+ * second, which is bounded, and the loop gets its turn at the next file.
770
+ */
771
+ export const MAX_TREE_SITTER_SOURCE_CHARS = 512 * 1024;
772
+
773
+ function extractSourceFile(
774
+ language: CodewikiLanguage,
775
+ relPath: string,
776
+ text: string,
777
+ treeSitterExtractor: LanguageExtractor,
778
+ ): LanguageExtraction {
779
+ if (!treeSitterExtractor.langs.includes(language)) return fallbackExtraction(language, relPath, text);
780
+ if (text.length > MAX_TREE_SITTER_SOURCE_CHARS) return fallbackExtraction(language, relPath, text);
781
+ try {
782
+ return mergeTreeSitterWithRegexImports(language, relPath, text, treeSitterExtractor.extract(relPath, text));
783
+ } catch {
784
+ return fallbackExtraction(language, relPath, text);
785
+ }
786
+ }
787
+
788
+ function buildFile(
789
+ cwd: string,
790
+ relPath: string,
791
+ treeSitterExtractor: LanguageExtractor,
792
+ readFile: CodewikiReadFile,
793
+ ): BuiltFile | null {
794
+ const pathLanguage = languageForPath(relPath);
795
+ if (!pathLanguage) return null;
796
+ let text: string | null;
797
+ try {
798
+ text = readFile(join(cwd, relPath));
799
+ } catch {
800
+ return null;
801
+ }
802
+ if (text === null) return null;
803
+ // Ambiguous `.h` headers classify from content so both full builds and
804
+ // incremental updates land on the same C/C++ decision.
805
+ const language = pathLanguage === "c" && isAmbiguousHeaderPath(relPath) ? classifyCHeaderLanguage(text) : pathLanguage;
806
+ const file: CodewikiFile = {
807
+ id: stableFileId(relPath),
808
+ path: relPath,
809
+ lang: language,
810
+ loc: lineCount(text),
811
+ role: roleFor(relPath, language),
812
+ hash: contentHash(text),
813
+ imports: [],
814
+ };
815
+ if (text.trim().length === 0) return { file, symbols: [] };
816
+ const extracted = isCMakePath(relPath)
817
+ ? extractCMake(text)
818
+ : language !== "config"
819
+ ? extractSourceFile(language, relPath, text, treeSitterExtractor)
820
+ : null;
821
+ if (!extracted) return { file, symbols: [] };
822
+ const summary = firstDocSummary(text);
823
+ const sourceFile: CodewikiFile = {
824
+ ...file,
825
+ imports: extracted.imports,
826
+ ...(summary ? { summary } : {}),
827
+ };
828
+ const symbols = extracted.symbols.map((symbol) => ({
829
+ name: symbol.name,
830
+ kind: symbol.kind,
831
+ fileId: sourceFile.id,
832
+ line: symbol.line,
833
+ ...symbolSigFields(symbol.kind, symbol.sig),
834
+ }));
835
+ return {
836
+ file: sourceFile,
837
+ symbols,
838
+ };
839
+ }
840
+
841
+ function candidatePathsForImport(cwd: string, fromRel: string, specifier: string): string[] {
842
+ const fromDir = dirname(join(cwd, fromRel));
843
+ const cleaned = specifier.replace(/\\/g, "/");
844
+ const base = cleaned.startsWith(".") || cleaned.startsWith("/") ? resolve(fromDir, cleaned) : "";
845
+ if (!base) return [];
846
+ const candidates = [base];
847
+ for (const ext of RESOLUTION_EXTENSIONS) candidates.push(`${base}${ext}`);
848
+ for (const ext of RESOLUTION_EXTENSIONS) candidates.push(join(base, `index${ext}`));
849
+ if (cleaned.endsWith(".js")) {
850
+ const stripped = base.replace(/\.js$/, "");
851
+ for (const ext of [".ts", ".tsx", ".mts", ".cts"]) candidates.push(`${stripped}${ext}`);
852
+ }
853
+ if (/^[.]+[A-Za-z_]/.test(cleaned)) {
854
+ const pythonModule = cleaned.replace(/^\.+/, "").replace(/\./g, "/");
855
+ const pythonBase = resolve(fromDir, pythonModule);
856
+ candidates.push(`${pythonBase}.py`, join(pythonBase, "__init__.py"));
857
+ }
858
+ return uniqueSorted(
859
+ candidates.map((candidate) => normalizeRel(cwd, candidate)).filter((candidate) => !candidate.startsWith("..")),
860
+ );
861
+ }
862
+
863
+ /**
864
+ * Per-run memo for import resolution.
865
+ *
866
+ * A candidate list depends only on the importing file's directory and the
867
+ * specifier, and a candidate's on-disk status cannot change while a single edge
868
+ * rebuild is in flight, so both collapse to a map lookup after the first miss.
869
+ * Uncached, one rebuild of a 1100-file TypeScript repo issued roughly 80 000
870
+ * `statSync` calls, most of them for paths that do not exist, and spent about
871
+ * four seconds doing it.
872
+ */
873
+ function createImportResolver(cwd: string): {
874
+ resolve(fromRel: string, specifier: string, pathToId: ReadonlyMap<string, string>): string | null;
875
+ } {
876
+ const candidatesByOrigin = new Map<string, string[]>();
877
+ const onDisk = new Map<string, boolean>();
878
+ const candidatesFor = (fromRel: string, specifier: string): string[] => {
879
+ // The candidate set is a function of the directory, not the file: every
880
+ // sibling importing the same specifier resolves through the same list.
881
+ const key = `${dirname(fromRel)}\0${specifier}`;
882
+ let candidates = candidatesByOrigin.get(key);
883
+ if (!candidates) {
884
+ candidates = candidatePathsForImport(cwd, fromRel, specifier);
885
+ candidatesByOrigin.set(key, candidates);
886
+ }
887
+ return candidates;
888
+ };
889
+ const isFile = (candidate: string): boolean => {
890
+ const cached = onDisk.get(candidate);
891
+ if (cached !== undefined) return cached;
892
+ let exists: boolean;
893
+ try {
894
+ exists = statSync(join(cwd, candidate)).isFile();
895
+ } catch {
896
+ exists = false;
897
+ }
898
+ onDisk.set(candidate, exists);
899
+ return exists;
900
+ };
901
+ return {
902
+ resolve(fromRel, specifier, pathToId): string | null {
903
+ for (const candidate of candidatesFor(fromRel, specifier)) {
904
+ if (pathToId.has(candidate)) return pathToId.get(candidate) ?? null;
905
+ // An unindexed file that exists still claims the specifier: it shadows
906
+ // any later candidate, and having no id makes the edge external.
907
+ if (isFile(candidate)) return null;
908
+ }
909
+ return null;
910
+ },
911
+ };
912
+ }
913
+
914
+ async function buildEdges(
915
+ cwd: string,
916
+ files: ReadonlyArray<CodewikiFile>,
917
+ slicer: CooperativeSlicer,
918
+ ): Promise<CodewikiEdge[]> {
919
+ const pathToId = new Map(files.map((file) => [file.path, file.id] as const));
920
+ const resolver = createImportResolver(cwd);
921
+ const edges: CodewikiEdge[] = [];
922
+ const seen = new Set<string>();
923
+ for (const file of files) {
924
+ for (const specifier of file.imports) {
925
+ await slicer.tick();
926
+ const target = resolver.resolve(file.path, specifier, pathToId);
927
+ const edge = target
928
+ ? ({ fileId: file.id, toFileId: target } satisfies CodewikiInternalEdge)
929
+ : ({ fileId: file.id, externalModule: specifier } satisfies CodewikiExternalEdge);
930
+ const key = "toFileId" in edge ? `${edge.fileId}\0${edge.toFileId}` : `${edge.fileId}\0${edge.externalModule}`;
931
+ if (seen.has(key)) continue;
932
+ seen.add(key);
933
+ edges.push(edge);
934
+ }
935
+ }
936
+ return edges.sort(compareEdges);
937
+ }
938
+
939
+ function compareFiles(a: CodewikiFile, b: CodewikiFile): number {
940
+ return a.path.localeCompare(b.path);
941
+ }
942
+
943
+ function compareCodewikiSymbols(a: CodewikiSymbol, b: CodewikiSymbol): number {
944
+ const pathCmp = a.fileId.localeCompare(b.fileId);
945
+ return pathCmp || a.line - b.line || a.name.localeCompare(b.name) || a.kind.localeCompare(b.kind);
946
+ }
947
+
948
+ function compareEdges(a: CodewikiEdge, b: CodewikiEdge): number {
949
+ const fileCmp = a.fileId.localeCompare(b.fileId);
950
+ if (fileCmp !== 0) return fileCmp;
951
+ const aTarget = "toFileId" in a ? a.toFileId : `~${a.externalModule}`;
952
+ const bTarget = "toFileId" in b ? b.toFileId : `~${b.externalModule}`;
953
+ return aTarget.localeCompare(bTarget);
954
+ }
955
+
956
+ function promoteSingleSourceEntry(files: CodewikiFile[]): CodewikiFile[] {
957
+ const sourceFiles = files.filter((file) => file.lang !== "config");
958
+ if (sourceFiles.length !== 1) return files;
959
+ const only = sourceFiles[0];
960
+ if (only?.role !== "module") return files;
961
+ return files.map((file) => (file.id === only.id ? { ...file, role: "entry" } : file));
962
+ }
963
+
964
+ async function codewikiFromBuiltFiles(
965
+ cwd: string,
966
+ language: ProjectType,
967
+ builtFiles: ReadonlyArray<BuiltFile>,
968
+ slicer: CooperativeSlicer,
969
+ ): Promise<Codewiki> {
970
+ const baseBuiltFiles = builtFiles.map((item) => ({
971
+ ...item,
972
+ file: { ...item.file, role: roleFor(item.file.path, item.file.lang) },
973
+ }));
974
+ const files = promoteSingleSourceEntry(baseBuiltFiles.map((item) => item.file).sort(compareFiles));
975
+ const roleById = new Map(files.map((file) => [file.id, file.role] as const));
976
+ const normalizedBuilt = baseBuiltFiles.map((item) => {
977
+ const role = roleById.get(item.file.id);
978
+ return role && role !== item.file.role ? { ...item, file: { ...item.file, role } } : item;
979
+ });
980
+ const normalizedFiles = normalizedBuilt.map((item) => item.file).sort(compareFiles);
981
+ return {
982
+ version: CODEWIKI_VERSION,
983
+ language,
984
+ files: normalizedFiles,
985
+ symbols: normalizedBuilt.flatMap((item) => item.symbols).sort(compareCodewikiSymbols),
986
+ edges: await buildEdges(cwd, normalizedFiles, slicer),
987
+ };
988
+ }
989
+
990
+ async function buildFromPaths(
991
+ cwd: string,
992
+ language: ProjectType,
993
+ relPaths: ReadonlyArray<string>,
994
+ options: CodewikiBuildOptions = {},
995
+ ): Promise<Codewiki> {
996
+ const slicer = options.slicer ?? createSlicer();
997
+ const sortedPaths = [...relPaths].sort(compareStrings);
998
+ const treeSitterExtractor = await loadTreeSitterExtractor();
999
+ await treeSitterExtractor.ensureGrammarsForPaths(sortedPaths);
1000
+ const readFile = options.readFile ?? defaultReadFile;
1001
+ const builtFiles: BuiltFile[] = [];
1002
+ for (const relPath of sortedPaths) {
1003
+ // One read plus one tree-sitter parse per file; a full build of a large
1004
+ // repo is thousands of them and must not land as a single turn.
1005
+ await slicer.tick();
1006
+ const built = buildFile(cwd, relPath, treeSitterExtractor, readFile);
1007
+ if (built) builtFiles.push(built);
1008
+ }
1009
+ return codewikiFromBuiltFiles(cwd, language, builtFiles, slicer);
1010
+ }
1011
+
1012
+ export async function buildCodewiki(input: BuildCodewikiInput, options: CodewikiBuildOptions = {}): Promise<Codewiki> {
1013
+ const slicer = options.slicer ?? createSlicer();
1014
+ const files = (await enumerateWorkspaceFilesAsync(input.cwd, EXCLUDED_DIRS, undefined, slicer)).filter(
1015
+ isIndexablePath,
1016
+ );
1017
+ return buildFromPaths(input.cwd, input.language, files, { ...options, slicer });
1018
+ }
1019
+
1020
+ /**
1021
+ * Apply an incremental update for a set of changed paths. The changed file
1022
+ * records and symbols are replaced in-place, and edges are rebuilt from stored
1023
+ * imports across the merged file set.
1024
+ */
1025
+ export async function updateCodewikiPaths(
1026
+ cwd: string,
1027
+ codewiki: Codewiki,
1028
+ paths: ReadonlyArray<string>,
1029
+ options: CodewikiBuildOptions = {},
1030
+ ): Promise<Codewiki> {
1031
+ const normalizedPaths = uniqueSorted(
1032
+ paths.map(normalizeInputPath).filter((path) => path.length > 0 && !path.startsWith("..")),
1033
+ );
1034
+ if (normalizedPaths.length === 0) return codewiki;
1035
+ if (
1036
+ normalizedPaths.some(
1037
+ (path) =>
1038
+ path === ".gitignore" ||
1039
+ path.endsWith("/.gitignore") ||
1040
+ path === ".git/info/exclude" ||
1041
+ path === ".git/index" ||
1042
+ path === ".gitmodules",
1043
+ )
1044
+ ) {
1045
+ // Ignore and index metadata can add or remove paths that are not present in
1046
+ // the mutation batch itself. Re-enumerate once so incremental visibility
1047
+ // remains byte-equivalent to a full build.
1048
+ return buildCodewiki({ cwd, language: codewiki.language }, options);
1049
+ }
1050
+ const slicer = options.slicer ?? createSlicer();
1051
+ const existingPaths = new Set(codewiki.files.map((file) => file.path));
1052
+ const visiblePaths = new Set(filterWorkspaceFileCandidates(cwd, normalizedPaths, EXCLUDED_DIRS));
1053
+ const readFile = options.readFile ?? defaultReadFile;
1054
+ const changedPathSet = new Set(normalizedPaths);
1055
+ const rebuildPaths: string[] = [];
1056
+ let hasIndexChange = false;
1057
+ for (const relPath of normalizedPaths) {
1058
+ const wasIndexed = existingPaths.has(relPath);
1059
+ const isCurrentIndexableFile = isIndexablePath(relPath) && visiblePaths.has(relPath);
1060
+ if (!wasIndexed && !isCurrentIndexableFile) continue;
1061
+ hasIndexChange = true;
1062
+ if (isCurrentIndexableFile) rebuildPaths.push(relPath);
1063
+ }
1064
+ if (!hasIndexChange) return codewiki;
1065
+ const rebuiltFiles: BuiltFile[] = [];
1066
+ if (rebuildPaths.length > 0) {
1067
+ const treeSitterExtractor = await loadTreeSitterExtractor();
1068
+ await treeSitterExtractor.ensureGrammarsForPaths(rebuildPaths);
1069
+ for (const relPath of rebuildPaths) {
1070
+ await slicer.tick();
1071
+ const built = buildFile(cwd, relPath, treeSitterExtractor, readFile);
1072
+ if (built) rebuiltFiles.push(built);
1073
+ }
1074
+ }
1075
+ const removedFileIds = new Set(codewiki.files.filter((file) => changedPathSet.has(file.path)).map((file) => file.id));
1076
+ const symbolsByFileId = new Map<string, CodewikiSymbol[]>();
1077
+ for (const symbol of codewiki.symbols) {
1078
+ if (removedFileIds.has(symbol.fileId)) continue;
1079
+ const symbols = symbolsByFileId.get(symbol.fileId) ?? [];
1080
+ symbols.push(symbol);
1081
+ symbolsByFileId.set(symbol.fileId, symbols);
1082
+ }
1083
+ const keptFiles: BuiltFile[] = codewiki.files
1084
+ .filter((file) => !changedPathSet.has(file.path))
1085
+ .map((file) => ({ file, symbols: symbolsByFileId.get(file.id) ?? [] }));
1086
+ return codewikiFromBuiltFiles(cwd, codewiki.language, [...keptFiles, ...rebuiltFiles], slicer);
1087
+ }
1088
+
1089
+ /**
1090
+ * Reconcile an existing index with the current workspace without parsing
1091
+ * unchanged files. The scan reads and hashes candidate files, then delegates
1092
+ * extraction to the incremental updater only for additions, removals, and
1093
+ * content changes. Callers can still use buildCodewiki when the artifact is
1094
+ * missing or structurally incompatible.
1095
+ */
1096
+ export async function syncCodewiki(
1097
+ cwd: string,
1098
+ codewiki: Codewiki,
1099
+ options: CodewikiBuildOptions = {},
1100
+ ): Promise<Codewiki> {
1101
+ const slicer = options.slicer ?? createSlicer();
1102
+ const readFile = options.readFile ?? defaultReadFile;
1103
+ const currentPaths = (await enumerateWorkspaceFilesAsync(cwd, EXCLUDED_DIRS, undefined, slicer)).filter(
1104
+ isIndexablePath,
1105
+ );
1106
+ const currentFiles = new Map<string, string>();
1107
+ const currentTexts = new Map<string, string>();
1108
+ for (const relPath of currentPaths) {
1109
+ // Reads and hashes every visible file in the workspace. Cheap per file,
1110
+ // seconds in aggregate on a large repo.
1111
+ await slicer.tick();
1112
+ const text = readFile(join(cwd, relPath));
1113
+ if (text !== null) {
1114
+ currentFiles.set(relPath, contentHash(text));
1115
+ currentTexts.set(relPath, text);
1116
+ }
1117
+ }
1118
+ const indexedFiles = new Map(codewiki.files.map((file) => [file.path, file] as const));
1119
+ const changedPaths = new Set<string>();
1120
+ for (const [relPath, hash] of currentFiles) {
1121
+ if (indexedFiles.get(relPath)?.hash !== hash) changedPaths.add(relPath);
1122
+ }
1123
+ for (const relPath of indexedFiles.keys()) {
1124
+ if (!currentFiles.has(relPath)) changedPaths.add(relPath);
1125
+ }
1126
+ if (changedPaths.size === 0) return codewiki;
1127
+ const syncOptions: CodewikiBuildOptions = {
1128
+ ...options,
1129
+ slicer,
1130
+ readFile: (path) => currentTexts.get(normalizeRel(cwd, path)) ?? readFile(path),
1131
+ };
1132
+ return updateCodewikiPaths(cwd, codewiki, [...changedPaths], syncOptions);
1133
+ }
1134
+
1135
+ export function codewikiPath(cwd: string): string {
1136
+ return join(cwd, ".clio-coder", "codewiki.json");
1137
+ }
1138
+
1139
+ export function serializeCodewiki(codewiki: Codewiki): string {
1140
+ return `${JSON.stringify(normalizeCodewiki(codewiki))}\n`;
1141
+ }
1142
+
1143
+ export function writeCodewiki(cwd: string, codewiki: Codewiki): string {
1144
+ const serialized = serializeCodewiki(codewiki);
1145
+ safeResourceWrite(codewikiPath(cwd), serialized, {
1146
+ encoding: "utf8",
1147
+ });
1148
+ return serialized;
1149
+ }
1150
+
1151
+ export function parseCodewikiRaw(raw: string): Codewiki | null {
1152
+ let parsed: unknown;
1153
+ try {
1154
+ parsed = JSON.parse(raw);
1155
+ } catch {
1156
+ return null;
1157
+ }
1158
+ return upgradeCodewiki(parsed);
1159
+ }
1160
+
1161
+ function readCodewikiRaw(cwd: string): { raw: string; codewiki: Codewiki } | null {
1162
+ const filePath = codewikiPath(cwd);
1163
+ if (!existsSync(filePath)) return null;
1164
+ let raw: string;
1165
+ try {
1166
+ raw = readFileSync(filePath, "utf8");
1167
+ } catch {
1168
+ return null;
1169
+ }
1170
+ const codewiki = parseCodewikiRaw(raw);
1171
+ return codewiki ? { raw, codewiki } : null;
1172
+ }
1173
+
1174
+ export function readCodewiki(cwd: string): Codewiki | null {
1175
+ return readCodewikiRaw(cwd)?.codewiki ?? null;
1176
+ }
1177
+
1178
+ /**
1179
+ * Read and parse the artifact without blocking on the file read. The parse
1180
+ * itself still runs as one turn, which is what a JSON artifact costs; the read
1181
+ * is the part that scales with repository size and it now happens off the loop.
1182
+ * For status surfaces that poll, prefer this over `readCodewiki`.
1183
+ */
1184
+ export async function readCodewikiAsync(cwd: string): Promise<Codewiki | null> {
1185
+ let raw: string;
1186
+ try {
1187
+ raw = await readFileAsync(codewikiPath(cwd), "utf8");
1188
+ } catch {
1189
+ return null;
1190
+ }
1191
+ return parseCodewikiRaw(raw);
1192
+ }
1193
+
1194
+ export function codewikiEntries(codewiki: Codewiki): CodewikiEntry[] {
1195
+ const fileById = new Map(codewiki.files.map((file) => [file.id, file] as const));
1196
+ const exportsByFile = new Map<string, string[]>();
1197
+ for (const symbol of codewiki.symbols) {
1198
+ const list = exportsByFile.get(symbol.fileId) ?? [];
1199
+ list.push(symbol.name);
1200
+ exportsByFile.set(symbol.fileId, list);
1201
+ }
1202
+ const importsByFile = new Map<string, string[]>();
1203
+ for (const edge of codewiki.edges) {
1204
+ const list = importsByFile.get(edge.fileId) ?? [];
1205
+ if ("toFileId" in edge) {
1206
+ const target = fileById.get(edge.toFileId);
1207
+ if (target) list.push(target.path);
1208
+ } else {
1209
+ list.push(edge.externalModule);
1210
+ }
1211
+ importsByFile.set(edge.fileId, list);
1212
+ }
1213
+ return codewiki.files
1214
+ .filter((file) => file.lang !== "config")
1215
+ .map<CodewikiEntry>((file) => ({
1216
+ path: file.path,
1217
+ exports: uniqueSorted(exportsByFile.get(file.id) ?? []),
1218
+ imports: uniqueSorted(importsByFile.get(file.id) ?? []),
1219
+ kind: file.role === "entry" ? "entry-point" : file.role === "test" ? "test" : "module",
1220
+ ...(file.summary ? { summary: file.summary } : {}),
1221
+ }))
1222
+ .sort((a, b) => a.path.localeCompare(b.path));
1223
+ }
1224
+
1225
+ export function codewikiNeedsBackfill(codewiki: Codewiki): boolean {
1226
+ return codewiki.files.some((file) => file.lang !== "config" && file.hash.length === 0);
1227
+ }
1228
+
1229
+ export function structuralCodewikiHash(codewiki: Codewiki): string {
1230
+ return createHash("sha256")
1231
+ .update(JSON.stringify(normalizeCodewiki(codewiki)))
1232
+ .digest("hex");
1233
+ }
1234
+
1235
+ function normalizeCodewikiFile(file: CodewikiFile): CodewikiFile {
1236
+ return {
1237
+ id: file.id,
1238
+ path: file.path,
1239
+ lang: file.lang,
1240
+ loc: file.loc,
1241
+ role: file.role,
1242
+ hash: file.hash,
1243
+ imports: uniqueSorted(file.imports),
1244
+ ...(file.summary ? { summary: file.summary } : {}),
1245
+ };
1246
+ }
1247
+
1248
+ function symbolSigFields(kind: CodewikiSymbolKind, sig: string | undefined): Pick<CodewikiSymbol, "sig"> {
1249
+ if (!CODEWIKI_SYMBOL_KINDS_WITH_SIG.has(kind)) return {};
1250
+ const clean = sig?.trim().slice(0, 240);
1251
+ return clean && clean.length > 0 ? { sig: clean } : {};
1252
+ }
1253
+
1254
+ function normalizeCodewikiSymbol(symbol: CodewikiSymbol): CodewikiSymbol {
1255
+ return {
1256
+ name: symbol.name,
1257
+ kind: symbol.kind,
1258
+ fileId: symbol.fileId,
1259
+ line: symbol.line,
1260
+ ...symbolSigFields(symbol.kind, symbol.sig),
1261
+ };
1262
+ }
1263
+
1264
+ function normalizeCodewiki(codewiki: Codewiki): Codewiki {
1265
+ return {
1266
+ version: CODEWIKI_VERSION,
1267
+ language: codewiki.language,
1268
+ files: codewiki.files.map(normalizeCodewikiFile).sort(compareFiles),
1269
+ symbols: codewiki.symbols.map(normalizeCodewikiSymbol).sort(compareCodewikiSymbols),
1270
+ edges: [...codewiki.edges].sort(compareEdges),
1271
+ };
1272
+ }
1273
+
1274
+ function upgradeCodewiki(value: unknown): Codewiki | null {
1275
+ if (isCodewikiV5(value)) return normalizeCodewiki(value);
1276
+ if (isCodewikiV4(value)) return upgradeV4Codewiki(value);
1277
+ if (isCodewikiV3(value)) return upgradeV3Codewiki(value);
1278
+ if (isCodewikiV2(value)) return upgradeV2Codewiki(value);
1279
+ return null;
1280
+ }
1281
+
1282
+ interface CodewikiFileV3 {
1283
+ id: string;
1284
+ path: string;
1285
+ lang: CodewikiLanguage;
1286
+ loc: number;
1287
+ role: CodewikiFileRole;
1288
+ }
1289
+
1290
+ interface CodewikiV3 {
1291
+ version: 3;
1292
+ language: ProjectType;
1293
+ files: CodewikiFileV3[];
1294
+ symbols: CodewikiSymbol[];
1295
+ edges: CodewikiEdge[];
1296
+ }
1297
+
1298
+ interface CodewikiV4 {
1299
+ version: 4;
1300
+ language: ProjectType;
1301
+ files: CodewikiFile[];
1302
+ symbols: CodewikiSymbol[];
1303
+ edges: CodewikiEdge[];
1304
+ }
1305
+
1306
+ interface CodewikiV2 {
1307
+ version: 2;
1308
+ generatedAt: string;
1309
+ language: ProjectType;
1310
+ entries: CodewikiEntry[];
1311
+ }
1312
+
1313
+ function upgradeV3Codewiki(value: CodewikiV3): Codewiki {
1314
+ return normalizeCodewiki({
1315
+ version: CODEWIKI_VERSION,
1316
+ language: value.language,
1317
+ files: value.files.map((file) => ({
1318
+ ...file,
1319
+ hash: "",
1320
+ imports: [],
1321
+ })),
1322
+ symbols: value.symbols,
1323
+ edges: value.edges,
1324
+ });
1325
+ }
1326
+
1327
+ function upgradeV4Codewiki(value: CodewikiV4): Codewiki {
1328
+ return normalizeCodewiki({
1329
+ version: CODEWIKI_VERSION,
1330
+ language: value.language,
1331
+ // v5 changes C-family extraction and adds CUDA paths. Blank hashes force
1332
+ // one complete rebuild instead of treating a structurally obsolete v4
1333
+ // artifact as fresh.
1334
+ files: value.files.map((file) => ({ ...file, hash: "" })),
1335
+ symbols: value.symbols,
1336
+ edges: value.edges,
1337
+ });
1338
+ }
1339
+
1340
+ function upgradeV2Codewiki(value: CodewikiV2): Codewiki {
1341
+ const files: CodewikiFileV3[] = value.entries.map((entry) => {
1342
+ const lang =
1343
+ languageForPath(entry.path) ??
1344
+ (value.language === "unknown" || value.language === "polyglot" || value.language === "dotfiles"
1345
+ ? "config"
1346
+ : value.language);
1347
+ return {
1348
+ id: stableFileId(entry.path),
1349
+ path: entry.path,
1350
+ lang,
1351
+ loc: 0,
1352
+ role: entry.kind === "entry-point" ? "entry" : entry.kind === "test" ? "test" : "module",
1353
+ };
1354
+ });
1355
+ const pathToId = new Map(files.map((file) => [file.path, file.id] as const));
1356
+ const symbols: CodewikiSymbol[] = [];
1357
+ for (const entry of value.entries) {
1358
+ const fileId = pathToId.get(entry.path);
1359
+ if (!fileId) continue;
1360
+ for (const name of entry.exports) symbols.push({ name, kind: "const", fileId, line: 1 });
1361
+ }
1362
+ const edges: CodewikiEdge[] = [];
1363
+ for (const entry of value.entries) {
1364
+ const fileId = pathToId.get(entry.path);
1365
+ if (!fileId) continue;
1366
+ for (const item of entry.imports) {
1367
+ const toFileId = pathToId.get(item);
1368
+ edges.push(toFileId ? { fileId, toFileId } : { fileId, externalModule: item });
1369
+ }
1370
+ }
1371
+ return upgradeV3Codewiki({
1372
+ version: 3,
1373
+ language: value.language,
1374
+ files,
1375
+ symbols,
1376
+ edges,
1377
+ });
1378
+ }
1379
+
1380
+ function isNormalizedRelativeCodewikiPath(path: string): boolean {
1381
+ if (path.length === 0 || path.includes("\0") || path.includes("\\") || path.startsWith("/")) return false;
1382
+ if (/^[A-Za-z]:\//.test(path)) return false;
1383
+ const segments = path.split("/");
1384
+ return segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
1385
+ }
1386
+
1387
+ function hasValidNativeV5Semantics(value: Codewiki): boolean {
1388
+ const fileIds = new Set<string>();
1389
+ const filePaths = new Set<string>();
1390
+ const locByFileId = new Map<string, number>();
1391
+ for (const file of value.files) {
1392
+ if (fileIds.has(file.id) || filePaths.has(file.path)) return false;
1393
+ if (!isNormalizedRelativeCodewikiPath(file.path) || !/^[0-9a-f]{16}$/.test(file.hash)) return false;
1394
+ fileIds.add(file.id);
1395
+ filePaths.add(file.path);
1396
+ locByFileId.set(file.id, file.loc);
1397
+ }
1398
+ for (const symbol of value.symbols) {
1399
+ const loc = locByFileId.get(symbol.fileId);
1400
+ if (loc === undefined || symbol.line > loc) return false;
1401
+ }
1402
+ for (const edge of value.edges) {
1403
+ if (!fileIds.has(edge.fileId)) return false;
1404
+ if ("toFileId" in edge && !fileIds.has(edge.toFileId)) return false;
1405
+ }
1406
+ return true;
1407
+ }
1408
+
1409
+ function isCodewikiV5(value: unknown): value is Codewiki {
1410
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1411
+ const obj = value as Record<string, unknown>;
1412
+ if (obj.version !== CODEWIKI_VERSION || typeof obj.language !== "string") return false;
1413
+ if (!Array.isArray(obj.files) || !Array.isArray(obj.symbols) || !Array.isArray(obj.edges)) return false;
1414
+ if (!obj.files.every(isCodewikiFile) || !obj.symbols.every(isCodewikiSymbol) || !obj.edges.every(isCodewikiEdge)) {
1415
+ return false;
1416
+ }
1417
+ return hasValidNativeV5Semantics(obj as unknown as Codewiki);
1418
+ }
1419
+
1420
+ function isCodewikiV4(value: unknown): value is CodewikiV4 {
1421
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1422
+ const obj = value as Record<string, unknown>;
1423
+ if (obj.version !== 4 || typeof obj.language !== "string") return false;
1424
+ if (!Array.isArray(obj.files) || !Array.isArray(obj.symbols) || !Array.isArray(obj.edges)) return false;
1425
+ return obj.files.every(isCodewikiFile) && obj.symbols.every(isCodewikiSymbol) && obj.edges.every(isCodewikiEdge);
1426
+ }
1427
+
1428
+ function isCodewikiV3(value: unknown): value is CodewikiV3 {
1429
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1430
+ const obj = value as Record<string, unknown>;
1431
+ if (obj.version !== 3 || typeof obj.language !== "string") return false;
1432
+ if (!Array.isArray(obj.files) || !Array.isArray(obj.symbols) || !Array.isArray(obj.edges)) return false;
1433
+ return obj.files.every(isCodewikiFileV3) && obj.symbols.every(isCodewikiSymbol) && obj.edges.every(isCodewikiEdge);
1434
+ }
1435
+
1436
+ function isCodewikiV2(value: unknown): value is CodewikiV2 {
1437
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1438
+ const obj = value as Record<string, unknown>;
1439
+ if (obj.version !== 2 || typeof obj.generatedAt !== "string" || typeof obj.language !== "string") return false;
1440
+ if (!Array.isArray(obj.entries)) return false;
1441
+ return obj.entries.every(isCodewikiEntry);
1442
+ }
1443
+
1444
+ const CODEWIKI_LANGUAGES = new Set<CodewikiLanguage>([
1445
+ "typescript",
1446
+ "javascript",
1447
+ "python",
1448
+ "rust",
1449
+ "go",
1450
+ "c",
1451
+ "c++",
1452
+ "java",
1453
+ "ruby",
1454
+ "c#",
1455
+ "config",
1456
+ ]);
1457
+ const FILE_ROLES = new Set<CodewikiFileRole>(["entry", "test", "module", "config"]);
1458
+ const SYMBOL_KINDS = new Set<CodewikiSymbolKind>(["func", "class", "method", "type", "const", "var", "trait", "iface"]);
1459
+
1460
+ function isCodewikiFile(value: unknown): value is CodewikiFile {
1461
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1462
+ const obj = value as Record<string, unknown>;
1463
+ return (
1464
+ typeof obj.id === "string" &&
1465
+ typeof obj.path === "string" &&
1466
+ typeof obj.lang === "string" &&
1467
+ CODEWIKI_LANGUAGES.has(obj.lang as CodewikiLanguage) &&
1468
+ typeof obj.loc === "number" &&
1469
+ Number.isInteger(obj.loc) &&
1470
+ obj.loc >= 0 &&
1471
+ typeof obj.role === "string" &&
1472
+ FILE_ROLES.has(obj.role as CodewikiFileRole) &&
1473
+ typeof obj.hash === "string" &&
1474
+ Array.isArray(obj.imports) &&
1475
+ obj.imports.every((item) => typeof item === "string") &&
1476
+ (!("summary" in obj) || typeof obj.summary === "string")
1477
+ );
1478
+ }
1479
+
1480
+ function isCodewikiFileV3(value: unknown): value is CodewikiFileV3 {
1481
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1482
+ const obj = value as Record<string, unknown>;
1483
+ return (
1484
+ typeof obj.id === "string" &&
1485
+ typeof obj.path === "string" &&
1486
+ typeof obj.lang === "string" &&
1487
+ CODEWIKI_LANGUAGES.has(obj.lang as CodewikiLanguage) &&
1488
+ typeof obj.loc === "number" &&
1489
+ Number.isInteger(obj.loc) &&
1490
+ obj.loc >= 0 &&
1491
+ typeof obj.role === "string" &&
1492
+ FILE_ROLES.has(obj.role as CodewikiFileRole)
1493
+ );
1494
+ }
1495
+
1496
+ function isCodewikiSymbol(value: unknown): value is CodewikiSymbol {
1497
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1498
+ const obj = value as Record<string, unknown>;
1499
+ return (
1500
+ typeof obj.name === "string" &&
1501
+ typeof obj.kind === "string" &&
1502
+ SYMBOL_KINDS.has(obj.kind as CodewikiSymbolKind) &&
1503
+ typeof obj.fileId === "string" &&
1504
+ typeof obj.line === "number" &&
1505
+ Number.isInteger(obj.line) &&
1506
+ obj.line >= 1 &&
1507
+ (!("sig" in obj) || typeof obj.sig === "string")
1508
+ );
1509
+ }
1510
+
1511
+ function isCodewikiEdge(value: unknown): value is CodewikiEdge {
1512
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1513
+ const obj = value as Record<string, unknown>;
1514
+ if (typeof obj.fileId !== "string") return false;
1515
+ const hasToFile = typeof obj.toFileId === "string";
1516
+ const hasExternal = typeof obj.externalModule === "string";
1517
+ return hasToFile !== hasExternal;
1518
+ }
1519
+
1520
+ function isCodewikiEntry(value: unknown): value is CodewikiEntry {
1521
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1522
+ const obj = value as Record<string, unknown>;
1523
+ if (typeof obj.path !== "string") return false;
1524
+ if (!Array.isArray(obj.exports) || obj.exports.some((item) => typeof item !== "string")) return false;
1525
+ if (!Array.isArray(obj.imports) || obj.imports.some((item) => typeof item !== "string")) return false;
1526
+ if (obj.kind !== "entry-point" && obj.kind !== "test" && obj.kind !== "module") return false;
1527
+ if ("summary" in obj && typeof obj.summary !== "string") return false;
1528
+ return true;
1529
+ }