@iowarp/clio-coder 0.3.1 → 0.3.3

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 (601) hide show
  1. package/CHANGELOG.md +233 -373
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +284 -613
  4. package/dist/{acp-FPR54DGL.js → acp-P2AQILE2.js} +43 -53
  5. package/dist/{agents-OGPIHPJH.js → agents-72W3BI7I.js} +43 -26
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
  8. package/dist/chunk-2DJ2KNFG.js +2095 -0
  9. package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
  10. package/dist/chunk-2SFS6XQE.js +122 -0
  11. package/dist/{chunk-PV4JUBVJ.js → chunk-2TLUCQVG.js} +40 -21
  12. package/dist/chunk-2VTFPG5O.js +48 -0
  13. package/dist/chunk-4BJ5BYCE.js +61 -0
  14. package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
  15. package/dist/chunk-4VP4KH3K.js +962 -0
  16. package/dist/chunk-4XUGQOHA.js +797 -0
  17. package/dist/chunk-4ZG3XFUR.js +77 -0
  18. package/dist/chunk-5B2AEOW5.js +5407 -0
  19. package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
  20. package/dist/{chunk-4QKXUHSR.js → chunk-5UFT4SUX.js} +70 -20
  21. package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
  22. package/dist/chunk-65DEGPJ6.js +52 -0
  23. package/dist/chunk-6EJMN2Y3.js +17 -0
  24. package/dist/chunk-6N5PTWMY.js +136 -0
  25. package/dist/chunk-6SGHMWE3.js +277 -0
  26. package/dist/chunk-6XLNIQDB.js +27 -0
  27. package/dist/chunk-7CR24IG7.js +242 -0
  28. package/dist/chunk-7MNJORFF.js +22 -0
  29. package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
  30. package/dist/chunk-AGYYIBLL.js +1069 -0
  31. package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
  32. package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
  33. package/dist/chunk-CBCAPZAA.js +229 -0
  34. package/dist/chunk-CMZWFGD2.js +352 -0
  35. package/dist/chunk-COU2UHX6.js +400 -0
  36. package/dist/chunk-DSELYM6W.js +1077 -0
  37. package/dist/chunk-DUYJ5IO6.js +644 -0
  38. package/dist/chunk-ECH6PKUQ.js +39 -0
  39. package/dist/chunk-ED4KHGC3.js +143 -0
  40. package/dist/chunk-EKMEHE4H.js +340 -0
  41. package/dist/chunk-FCSXB6T2.js +338 -0
  42. package/dist/chunk-FJ3H4MN5.js +48 -0
  43. package/dist/{chunk-RPTR2H26.js → chunk-FNTMWMX5.js} +21 -15
  44. package/dist/chunk-FQ4SKYE4.js +29 -0
  45. package/dist/chunk-G4BMMOKF.js +182 -0
  46. package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
  47. package/dist/chunk-HC4CLZ2Y.js +68 -0
  48. package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
  49. package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
  50. package/dist/chunk-I4HZDVNP.js +73 -0
  51. package/dist/chunk-IKCO5N3L.js +162 -0
  52. package/dist/chunk-IR4CFBFN.js +56 -0
  53. package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
  54. package/dist/chunk-J7CWMCQD.js +255 -0
  55. package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
  56. package/dist/chunk-KZWTDYJF.js +217 -0
  57. package/dist/chunk-LBMZMYH2.js +285 -0
  58. package/dist/{chunk-G34LV2PF.js → chunk-LM5TQCJZ.js} +84 -170
  59. package/dist/chunk-LW6DSM3M.js +5135 -0
  60. package/dist/chunk-LWLEKMDQ.js +3482 -0
  61. package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
  62. package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
  63. package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
  64. package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
  65. package/dist/chunk-OAO4GE4M.js +619 -0
  66. package/dist/{chunk-Q3RUPKEJ.js → chunk-OC7FIQPC.js} +58 -189
  67. package/dist/chunk-OKGUZO2U.js +34 -0
  68. package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
  69. package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
  70. package/dist/chunk-OQE5J4C6.js +73 -0
  71. package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
  72. package/dist/{chunk-MAR7Y6HW.js → chunk-PAJK6MAQ.js} +23 -16
  73. package/dist/{chunk-M5T5VO65.js → chunk-PIWWS5BL.js} +837 -635
  74. package/dist/chunk-POHLU5DW.js +1186 -0
  75. package/dist/chunk-QKMUKYO7.js +4961 -0
  76. package/dist/chunk-SRDMMSEP.js +16405 -0
  77. package/dist/chunk-SST6Z5JA.js +80 -0
  78. package/dist/chunk-STBPMHSX.js +2456 -0
  79. package/dist/chunk-T6YILFSB.js +80 -0
  80. package/dist/chunk-TZK7PACC.js +174 -0
  81. package/dist/chunk-TZTZS7QK.js +227 -0
  82. package/dist/{chunk-ASND7OZK.js → chunk-UFIIWP2H.js} +13 -13
  83. package/dist/chunk-UOV2BYIW.js +107 -0
  84. package/dist/{chunk-PFEFKVGL.js → chunk-V6RTAOC2.js} +13 -11
  85. package/dist/chunk-VAKQQHWR.js +434 -0
  86. package/dist/chunk-VG7TBQIY.js +128 -0
  87. package/dist/chunk-VJWL6YS5.js +244 -0
  88. package/dist/{chunk-EYOKLTMF.js → chunk-VPAYEGVX.js} +17 -3
  89. package/dist/chunk-WEH5XRJQ.js +32 -0
  90. package/dist/chunk-X4RCMKVQ.js +641 -0
  91. package/dist/{chunk-TEKV33Q5.js → chunk-X6IAEBZR.js} +65 -33
  92. package/dist/chunk-XBXAASKX.js +18 -0
  93. package/dist/chunk-XN3L4EYL.js +46 -0
  94. package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
  95. package/dist/chunk-YHZX5GEU.js +193 -0
  96. package/dist/chunk-YXLYO42X.js +91 -0
  97. package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
  98. package/dist/chunk-ZI647VB5.js +37 -0
  99. package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
  100. package/dist/chunk-ZWMF7253.js +1882 -0
  101. package/dist/cli/index.js +62 -54
  102. package/dist/clio-JOU4FXVA.js +25 -0
  103. package/dist/code-nav-7AX6FYE6.js +600 -0
  104. package/dist/codewiki/build-worker.js +66 -0
  105. package/dist/compile-cache-CVJMMODC.js +18 -0
  106. package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
  107. package/dist/{config-IRUQ7SE4.js → config-XCDVKR23.js} +92 -55
  108. package/dist/configure-4GAP54ZW.js +42 -0
  109. package/dist/{context-5RADCKTR.js → context-4UOGGLQ5.js} +71 -35
  110. package/dist/context-5VKGUVJJ.js +866 -0
  111. package/dist/{context-3KWFLHJG.js → context-77FM5DV5.js} +15 -13
  112. package/dist/{context-clear-7TSNPAAI.js → context-clear-XXJRLCJJ.js} +54 -28
  113. package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
  114. package/dist/dispatch-runner-QPRDDBDX.js +1997 -0
  115. package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
  116. package/dist/{doctor-UC5NAJYQ.js → doctor-HR46URBJ.js} +27 -17
  117. package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
  118. package/dist/{evidence-YEGUW4L3.js → evidence-6HG2PY2B.js} +46 -26
  119. package/dist/{evolve-TXARCTPG.js → evolve-K7YU3NCY.js} +45 -25
  120. package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
  121. package/dist/{fleet-6G3DHNYE.js → fleet-VY3HHKN6.js} +163 -54
  122. package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
  123. package/dist/{init-KZ5QTF6M.js → init-JYGXI3FK.js} +69 -32
  124. package/dist/{memory-73ESV5YC.js → memory-WFZMGYHX.js} +48 -27
  125. package/dist/{models-A4PVNWJK.js → models-I5QWSEOM.js} +39 -25
  126. package/dist/monitor-GE4ID3IA.js +661 -0
  127. package/dist/{chunk-FCIH3BIZ.js → orchestrator-EM5MC3HM.js} +15979 -12407
  128. package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
  129. package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
  130. package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
  131. package/dist/{run-YTPEYQOH.js → run-ZU3QMZPZ.js} +101 -61
  132. package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
  133. package/dist/{skills-2V6RA3OQ.js → skills-X5VXCRNQ.js} +34 -14
  134. package/dist/{skills-eval-S2TVJO4F.js → skills-eval-WKIHWTHR.js} +70 -34
  135. package/dist/steer-GGWFUJUD.js +77 -0
  136. package/dist/{targets-TYXLPB23.js → targets-SNCPI2NR.js} +43 -27
  137. package/dist/terminal-lease-BNAHVHBS.js +395 -0
  138. package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
  139. package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
  140. package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
  141. package/dist/{upgrade-33G2LMM5.js → upgrade-JQHHPQ4K.js} +45 -25
  142. package/dist/{usage-ZAFSXKKG.js → usage-OR4O5SMZ.js} +62 -31
  143. package/dist/verify-375KUB3Y.js +716 -0
  144. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  145. package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-UEXP2ARI.js} +74 -34
  146. package/dist/worker/entry.js +221 -36
  147. package/dist/workspace-G4ZWUIPR.js +22 -0
  148. package/docs/README.md +22 -17
  149. package/docs/acp.md +168 -16
  150. package/docs/alcf-provider.md +1 -1
  151. package/docs/architecture.md +136 -7
  152. package/docs/artifact-versions.md +1 -1
  153. package/docs/built-in-agents.md +1 -1
  154. package/docs/capacity-and-scheduling.md +1 -1
  155. package/docs/commands-and-modes.md +114 -71
  156. package/docs/config-knobs-audit.md +1 -3
  157. package/docs/configuration-and-targets.md +174 -46
  158. package/docs/context-engine.md +29 -6
  159. package/docs/development-pipeline.md +26 -1
  160. package/docs/dispatch-architecture-rationale.md +1 -1
  161. package/docs/documentation-coverage.md +2 -2
  162. package/docs/documentation-guide.md +1 -1
  163. package/docs/environment-variables.md +13 -5
  164. package/docs/eval-runner.md +1 -1
  165. package/docs/evals-internal.md +1 -1
  166. package/docs/evidence-and-memory.md +6 -2
  167. package/docs/evolution.md +2 -2
  168. package/docs/exit-codes-and-output.md +15 -9
  169. package/docs/extensions-and-sharing.md +9 -9
  170. package/docs/fleet-dispatch.md +7 -5
  171. package/docs/git-commit-provenance.md +120 -0
  172. package/docs/glossary.md +1 -1
  173. package/docs/installation-and-lifecycle.md +34 -27
  174. package/docs/middleware-and-components.md +1 -1
  175. package/docs/model-catalog.md +45 -14
  176. package/docs/observability.md +8 -5
  177. package/docs/performance-methodology.md +491 -0
  178. package/docs/pi-boundary.md +72 -0
  179. package/docs/proactive-memory.md +3 -3
  180. package/docs/prompt-envelope-and-tools.md +24 -3
  181. package/docs/provider-adapter-cookbook.md +57 -4
  182. package/docs/release-cut-checklist.md +129 -115
  183. package/docs/safety-model.md +9 -5
  184. package/docs/scientific-validation.md +3 -3
  185. package/docs/session-lifecycle.md +55 -12
  186. package/docs/skills-marketplace.md +12 -8
  187. package/docs/time-conventions.md +1 -1
  188. package/docs/tool-usage.md +3 -3
  189. package/docs/trace-store.md +1 -1
  190. package/docs/troubleshooting.md +10 -7
  191. package/docs/tui-design.md +47 -10
  192. package/docs/worker-dispatch-mechanics.md +1 -1
  193. package/package.json +19 -22
  194. package/skills/coding/ast-grep/SKILL.md +136 -0
  195. package/skills/coding/ast-grep/evals.md +56 -0
  196. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  197. package/skills/coding/coding-standards/SKILL.md +113 -0
  198. package/skills/coding/coding-standards/evals.md +34 -0
  199. package/skills/coding/prototype/SKILL.md +86 -0
  200. package/skills/coding/prototype/evals.md +42 -0
  201. package/skills/coding/prototype/references/LOGIC.md +67 -0
  202. package/skills/coding/prototype/references/UI.md +112 -0
  203. package/skills/coding/tdd/SKILL.md +101 -0
  204. package/skills/coding/tdd/evals.md +41 -0
  205. package/skills/coding/tdd/references/mocking.md +59 -0
  206. package/skills/coding/tdd/references/tests.md +77 -0
  207. package/skills/context/context-handoff/SKILL.md +126 -0
  208. package/skills/context/context-handoff/evals.md +57 -0
  209. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  210. package/skills/context/context-prime/SKILL.md +95 -0
  211. package/skills/context/context-prime/evals.md +54 -0
  212. package/skills/meta/clio-dev/SKILL.md +91 -0
  213. package/skills/meta/clio-dev/evals.md +45 -0
  214. package/skills/meta/clio-test/SKILL.md +130 -0
  215. package/skills/meta/clio-test/evals.md +43 -0
  216. package/skills/meta/clio-test/references/harness.md +97 -0
  217. package/skills/meta/clio-test/references/test-map.md +59 -0
  218. package/skills/meta/credentials/SKILL.md +125 -0
  219. package/skills/meta/credentials/evals.md +104 -0
  220. package/skills/meta/find-skills/SKILL.md +72 -0
  221. package/skills/meta/find-skills/evals.md +47 -0
  222. package/skills/meta/herdr/SKILL.md +127 -0
  223. package/skills/meta/herdr/evals.md +38 -0
  224. package/skills/meta/skill-craft/SKILL.md +102 -0
  225. package/skills/meta/skill-craft/evals.md +41 -0
  226. package/skills/planning/architecture/SKILL.md +129 -0
  227. package/skills/planning/architecture/evals.md +36 -0
  228. package/skills/planning/backlog/SKILL.md +90 -0
  229. package/skills/planning/backlog/evals.md +43 -0
  230. package/skills/planning/prd/SKILL.md +82 -0
  231. package/skills/planning/prd/evals.md +49 -0
  232. package/skills/planning/product-intent/SKILL.md +112 -0
  233. package/skills/planning/product-intent/evals.md +36 -0
  234. package/skills/planning/tech-spec/SKILL.md +115 -0
  235. package/skills/planning/tech-spec/evals.md +47 -0
  236. package/skills/registry.yaml +136 -0
  237. package/skills/research/arxiv-literature/SKILL.md +104 -0
  238. package/skills/research/arxiv-literature/evals.md +58 -0
  239. package/skills/research/experiment-protocol/SKILL.md +122 -0
  240. package/skills/research/experiment-protocol/evals.md +91 -0
  241. package/skills/research/scientific-debugging/SKILL.md +119 -0
  242. package/skills/research/scientific-debugging/evals.md +138 -0
  243. package/skills/research/scientific-modernization/SKILL.md +138 -0
  244. package/skills/research/scientific-modernization/evals.md +84 -0
  245. package/skills/workflow/design-council/SKILL.md +139 -0
  246. package/skills/workflow/design-council/evals.md +97 -0
  247. package/skills/workflow/grill-me/SKILL.md +186 -0
  248. package/skills/workflow/grill-me/evals.md +78 -0
  249. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  250. package/skills/workflow/workflow-distiller/evals.md +107 -0
  251. package/src/cli/acp.ts +31 -4
  252. package/src/cli/clio.ts +68 -6
  253. package/src/cli/config-inspect.ts +28 -22
  254. package/src/cli/configure.ts +47 -9
  255. package/src/cli/context-clear.ts +2 -2
  256. package/src/cli/context-index.ts +21 -23
  257. package/src/cli/context.ts +13 -8
  258. package/src/cli/default-target.ts +9 -17
  259. package/src/cli/docs.ts +11 -5
  260. package/src/cli/evidence.ts +4 -1
  261. package/src/cli/extensions.ts +10 -1
  262. package/src/cli/fleet.ts +47 -6
  263. package/src/cli/index.ts +55 -26
  264. package/src/cli/memory.ts +3 -1
  265. package/src/cli/models.ts +1 -1
  266. package/src/cli/modes/json-stream.ts +37 -1
  267. package/src/cli/modes/print.ts +24 -9
  268. package/src/cli/run.ts +2 -2
  269. package/src/cli/skills-eval.ts +23 -8
  270. package/src/cli/skills.ts +19 -4
  271. package/src/cli/targets.ts +4 -0
  272. package/src/cli/text-layout.ts +15 -5
  273. package/src/cli/trace.ts +62 -14
  274. package/src/cli/upgrade.ts +18 -2
  275. package/src/cli/usage.ts +10 -3
  276. package/src/cli/wiki-generate.ts +2 -1
  277. package/src/core/agent-environment.ts +7 -0
  278. package/src/core/bash-exec.ts +72 -1
  279. package/src/core/boot-trace.ts +9 -4
  280. package/src/core/bus-events.ts +20 -4
  281. package/src/core/commit-attribution.ts +157 -0
  282. package/src/core/compile-cache.ts +159 -0
  283. package/src/core/config.ts +131 -2
  284. package/src/core/defaults.ts +39 -5
  285. package/src/core/domain-loader.ts +12 -5
  286. package/src/core/git-commit-attribution.ts +387 -0
  287. package/src/core/incomplete-installation.ts +45 -0
  288. package/src/core/response-schema.ts +1 -1
  289. package/src/core/safe-exec.ts +13 -1
  290. package/src/core/settings-layers.ts +155 -21
  291. package/src/core/skill-activation.ts +1 -1
  292. package/src/core/startup-timer.ts +3 -3
  293. package/src/core/state-file-lock.ts +13 -1
  294. package/src/core/termination.ts +78 -5
  295. package/src/domains/config/classify.ts +15 -3
  296. package/src/domains/config/extension.ts +19 -13
  297. package/src/domains/config/index.ts +10 -0
  298. package/src/domains/config/keybindings.ts +45 -9
  299. package/src/domains/context/bootstrap-prompt.ts +1 -1
  300. package/src/domains/context/bootstrap.ts +111 -18
  301. package/src/domains/context/clear.ts +16 -11
  302. package/src/domains/context/clio-md.ts +111 -9
  303. package/src/domains/context/codewiki/artifact.ts +400 -0
  304. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  305. package/src/domains/context/codewiki/build-worker.ts +54 -0
  306. package/src/domains/context/codewiki/coordinator.ts +182 -0
  307. package/src/domains/context/codewiki/indexer.ts +59 -144
  308. package/src/domains/context/codewiki/paths.ts +67 -0
  309. package/src/domains/context/codewiki/schema.ts +80 -0
  310. package/src/domains/context/codewiki/tree-sitter.ts +1 -1
  311. package/src/domains/context/contract.ts +11 -5
  312. package/src/domains/context/extension.ts +94 -143
  313. package/src/domains/context/fingerprint.ts +3 -1
  314. package/src/domains/context/index.ts +12 -22
  315. package/src/domains/context/project-metadata.ts +19 -0
  316. package/src/domains/context/prompt-context.ts +9 -10
  317. package/src/domains/context/refresh.ts +29 -21
  318. package/src/domains/context/runtime.ts +17 -0
  319. package/src/domains/context/wiki/generate.ts +39 -34
  320. package/src/domains/context/wiki/plan.ts +1 -1
  321. package/src/domains/context/wiki/prompts.ts +21 -8
  322. package/src/domains/dispatch/code-step.ts +20 -1
  323. package/src/domains/dispatch/extension.ts +158 -21
  324. package/src/domains/dispatch/failure-classification.ts +6 -0
  325. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  326. package/src/domains/dispatch/orphan-recovery.ts +50 -8
  327. package/src/domains/dispatch/receipt-integrity.ts +5 -0
  328. package/src/domains/dispatch/state.ts +31 -6
  329. package/src/domains/dispatch/transport.ts +2 -1
  330. package/src/domains/dispatch/types.ts +14 -0
  331. package/src/domains/dispatch/worker-spawn.ts +21 -2
  332. package/src/domains/eval/metrics/context.ts +1 -1
  333. package/src/domains/eval/types.ts +0 -1
  334. package/src/domains/evidence/build.ts +41 -1
  335. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  336. package/src/domains/lifecycle/migrations/index.ts +24 -4
  337. package/src/domains/middleware/hooks-io.ts +12 -0
  338. package/src/domains/middleware/skills-reminder.ts +30 -15
  339. package/src/domains/prompts/compiler.ts +142 -84
  340. package/src/domains/prompts/contract.ts +18 -2
  341. package/src/domains/prompts/extension.ts +39 -7
  342. package/src/domains/prompts/fragment-loader.ts +0 -1
  343. package/src/domains/prompts/fragments/identity/clio.md +2 -4
  344. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  345. package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
  346. package/src/domains/prompts/fragments/operating/contract.md +4 -50
  347. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  348. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  349. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  350. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  351. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  352. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  353. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  354. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  355. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  356. package/src/domains/prompts/preload.ts +3 -3
  357. package/src/domains/providers/auth/api-key.ts +1 -1
  358. package/src/domains/providers/auth/backend-file.ts +20 -10
  359. package/src/domains/providers/auth/backend-memory.ts +59 -4
  360. package/src/domains/providers/auth/boot-status.ts +65 -0
  361. package/src/domains/providers/auth/oauth.ts +2 -1
  362. package/src/domains/providers/auth/storage.ts +97 -38
  363. package/src/domains/providers/capabilities.ts +12 -4
  364. package/src/domains/providers/contract.ts +15 -4
  365. package/src/domains/providers/extension.ts +18 -6
  366. package/src/domains/providers/model-runtime-capabilities.ts +15 -4
  367. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
  368. package/src/domains/providers/plugins.ts +5 -3
  369. package/src/domains/providers/probe/fingerprint.ts +25 -5
  370. package/src/domains/providers/registry.ts +31 -10
  371. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  372. package/src/domains/providers/runtimes/builtins.ts +2 -2
  373. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  374. package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
  375. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  376. package/src/domains/providers/support.ts +6 -3
  377. package/src/domains/providers/types/local-model-quirks.ts +7 -9
  378. package/src/domains/providers/types/runtime-descriptor.ts +12 -1
  379. package/src/domains/providers/types/target-descriptor.ts +22 -0
  380. package/src/domains/resources/contract.ts +0 -1
  381. package/src/domains/resources/extension.ts +1 -3
  382. package/src/domains/resources/loader.ts +3 -4
  383. package/src/domains/resources/prompts/loader.ts +16 -2
  384. package/src/domains/resources/prompts/substitute.ts +1 -65
  385. package/src/domains/resources/skills/content-hash.ts +2 -0
  386. package/src/domains/resources/skills/install.ts +17 -0
  387. package/src/domains/resources/skills/loader.ts +17 -10
  388. package/src/domains/resources/skills/marketplace.ts +55 -9
  389. package/src/domains/safety/action-classifier.ts +4 -2
  390. package/src/domains/safety/audit.ts +8 -2
  391. package/src/domains/safety/extension.ts +1 -1
  392. package/src/domains/session/compaction/branch-summary.ts +3 -2
  393. package/src/domains/session/compaction/cut-point.ts +2 -1
  394. package/src/domains/session/compaction/tokens.ts +2 -1
  395. package/src/domains/session/context-ledger.ts +14 -0
  396. package/src/domains/session/contract.ts +15 -0
  397. package/src/domains/session/decision-board.ts +190 -0
  398. package/src/domains/session/entries.ts +66 -3
  399. package/src/domains/session/extension.ts +93 -12
  400. package/src/domains/session/retry.ts +10 -18
  401. package/src/domains/session/session-artifacts.ts +107 -0
  402. package/src/domains/session/task-board.ts +207 -13
  403. package/src/domains/session/tree/active-path.ts +44 -5
  404. package/src/domains/session/tree/fork.ts +26 -27
  405. package/src/domains/session/tree/preview.ts +2 -2
  406. package/src/domains/session/workspace/git-probe.ts +17 -11
  407. package/src/domains/user-tasks/store.ts +297 -0
  408. package/src/engine/acp/errors.ts +96 -0
  409. package/src/engine/acp/server.ts +1728 -146
  410. package/src/engine/acp/transport.ts +135 -14
  411. package/src/engine/acp/types.ts +26 -0
  412. package/src/engine/agent.ts +3 -3
  413. package/src/engine/ai.ts +32 -27
  414. package/src/engine/alcf-oauth.ts +26 -19
  415. package/src/engine/api-registry.ts +223 -0
  416. package/src/engine/apis/index.ts +3 -7
  417. package/src/engine/apis/llamacpp-residency.ts +49 -9
  418. package/src/engine/apis/lmstudio-residency.ts +5 -21
  419. package/src/engine/apis/lmstudio.ts +243 -0
  420. package/src/engine/apis/ollama-native.ts +24 -3
  421. package/src/engine/apis/openai-completions.ts +170 -91
  422. package/src/engine/apis/residency.ts +139 -3
  423. package/src/engine/apis/types.ts +16 -0
  424. package/src/engine/env-api-keys.ts +98 -0
  425. package/src/engine/gemma-channel-filter.ts +223 -0
  426. package/src/engine/instrumented-tui.ts +192 -0
  427. package/src/engine/messages.ts +14 -0
  428. package/src/engine/models.ts +42 -0
  429. package/src/engine/oauth.ts +16 -12
  430. package/src/engine/prompt-templates.ts +1 -0
  431. package/src/engine/provider-payload.ts +16 -59
  432. package/src/engine/strip-tokenizer-sentinels.ts +1 -1
  433. package/src/engine/truncate.ts +9 -0
  434. package/src/engine/tui.ts +17 -9
  435. package/src/engine/types.ts +3 -6
  436. package/src/engine/worker-runtime-capabilities.ts +5 -0
  437. package/src/engine/worker-runtime.ts +1 -1
  438. package/src/engine/worker-tools.ts +9 -4
  439. package/src/entry/boot-options.ts +50 -0
  440. package/src/entry/orchestrator.ts +288 -150
  441. package/src/interactive/application-controller.ts +89 -2
  442. package/src/interactive/chat-loop.ts +266 -41
  443. package/src/interactive/chat-panel.ts +715 -278
  444. package/src/interactive/chat-renderer.ts +306 -85
  445. package/src/interactive/clio-editor.ts +3 -8
  446. package/src/interactive/command-fallbacks.ts +2 -2
  447. package/src/interactive/context-overlay.ts +27 -1
  448. package/src/interactive/editor-submit.ts +253 -24
  449. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  450. package/src/interactive/export-html/index.ts +51 -0
  451. package/src/interactive/export-html/template.ts +45 -0
  452. package/src/interactive/export-html/tool-renderer.ts +54 -0
  453. package/src/interactive/footer/dashboard.ts +4 -0
  454. package/src/interactive/footer/notifications.ts +1 -1
  455. package/src/interactive/footer/widgets.ts +42 -22
  456. package/src/interactive/footer-panel.ts +8 -3
  457. package/src/interactive/format-time.ts +14 -2
  458. package/src/interactive/interactive-application.ts +203 -17
  459. package/src/interactive/interactive-event-projection.ts +18 -1
  460. package/src/interactive/interactive-input-runtime.ts +50 -4
  461. package/src/interactive/interactive-presentation.ts +151 -19
  462. package/src/interactive/interactive-shell.ts +268 -14
  463. package/src/interactive/interactive-slash-runtime.ts +184 -117
  464. package/src/interactive/interactive-tickers.ts +38 -7
  465. package/src/interactive/keybinding-manager.ts +1 -1
  466. package/src/interactive/layout.ts +40 -3
  467. package/src/interactive/overlay-frame.ts +1 -1
  468. package/src/interactive/overlay-general-openers.ts +58 -1
  469. package/src/interactive/overlay-key-routing.ts +3 -0
  470. package/src/interactive/overlay-lifecycle.ts +13 -0
  471. package/src/interactive/overlay-permission-lifecycle.ts +2 -1
  472. package/src/interactive/overlay-session-lifecycle.ts +69 -12
  473. package/src/interactive/overlays/ask-user.ts +146 -24
  474. package/src/interactive/overlays/decisions.ts +300 -0
  475. package/src/interactive/overlays/help-reference.ts +15 -10
  476. package/src/interactive/overlays/model-selector.ts +34 -16
  477. package/src/interactive/overlays/session-selector.ts +18 -0
  478. package/src/interactive/overlays/settings.ts +105 -17
  479. package/src/interactive/overlays/skills-hub.ts +4 -4
  480. package/src/interactive/overlays/tree-selector.ts +41 -6
  481. package/src/interactive/render-trace.ts +499 -90
  482. package/src/interactive/renderers/compaction-summary.ts +2 -2
  483. package/src/interactive/renderers/diff.ts +115 -104
  484. package/src/interactive/renderers/mermaid.ts +53 -0
  485. package/src/interactive/renderers/tool-execution.ts +516 -168
  486. package/src/interactive/renderers/worker-entry.ts +20 -4
  487. package/src/interactive/session-switch-settlement.ts +10 -0
  488. package/src/interactive/slash-autocomplete.ts +6 -114
  489. package/src/interactive/slash-commands.ts +135 -47
  490. package/src/interactive/slash-spec.ts +9 -38
  491. package/src/interactive/status/controller.ts +5 -1
  492. package/src/interactive/status/index.ts +12 -1
  493. package/src/interactive/status/reasoning.ts +87 -0
  494. package/src/interactive/status/summary.ts +13 -2
  495. package/src/interactive/stdout-backpressure.ts +99 -0
  496. package/src/interactive/stream-pacer.ts +530 -0
  497. package/src/interactive/stream-pacing-policy.ts +66 -0
  498. package/src/interactive/tasks-overlay.ts +368 -14
  499. package/src/interactive/terminal-lease.ts +485 -0
  500. package/src/interactive/theme/tokens.ts +1 -1
  501. package/src/interactive/transcript-detail.ts +120 -0
  502. package/src/interactive/turn-context.ts +4 -3
  503. package/src/interactive/turn-persistence.ts +30 -13
  504. package/src/interactive/turn-queues.ts +12 -0
  505. package/src/interactive/turn-recovery.ts +25 -8
  506. package/src/interactive/turn-runtime.ts +79 -12
  507. package/src/interactive/turn-state.ts +10 -0
  508. package/src/interactive/view/artifacts.ts +114 -4
  509. package/src/interactive/view/view-overlay.ts +3 -0
  510. package/src/interactive/welcome-dashboard.ts +17 -16
  511. package/src/interactive/worker-receipts.ts +52 -3
  512. package/src/interactive/worker-stream.ts +5 -1
  513. package/src/tools/agent-tools.ts +23 -3
  514. package/src/tools/artifact.ts +2 -2
  515. package/src/tools/ask-user.ts +23 -13
  516. package/src/tools/bash.ts +30 -2
  517. package/src/tools/bootstrap.ts +34 -431
  518. package/src/tools/builtin-tool-catalog.ts +271 -0
  519. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  520. package/src/tools/codewiki/code-nav.ts +8 -22
  521. package/src/tools/codewiki/shared.ts +41 -38
  522. package/src/tools/context/docs-engine.ts +14 -3
  523. package/src/tools/context/index.ts +107 -28
  524. package/src/tools/context/surface.ts +19 -0
  525. package/src/tools/core-bootstrap.ts +168 -0
  526. package/src/tools/credential-present.ts +5 -5
  527. package/src/tools/dispatch-admission.ts +533 -0
  528. package/src/tools/dispatch-background.ts +54 -0
  529. package/src/tools/dispatch-event-text.ts +6 -0
  530. package/src/tools/dispatch-plan.ts +9 -4
  531. package/src/tools/dispatch-run-events.ts +238 -0
  532. package/src/tools/dispatch-runner.ts +2370 -0
  533. package/src/tools/dispatch-scout-admission.ts +295 -0
  534. package/src/tools/dispatch-types.ts +77 -0
  535. package/src/tools/dispatch.ts +67 -3161
  536. package/src/tools/find.ts +4 -2
  537. package/src/tools/grep.ts +2 -2
  538. package/src/tools/lazy-tool.ts +60 -0
  539. package/src/tools/ledger.ts +3 -3
  540. package/src/tools/monitor-surface.ts +36 -0
  541. package/src/tools/monitor.ts +2 -32
  542. package/src/tools/observers.ts +2 -2
  543. package/src/tools/presentation.ts +107 -0
  544. package/src/tools/registry.ts +45 -27
  545. package/src/tools/safe-exec.ts +2 -2
  546. package/src/tools/steer-surface.ts +17 -0
  547. package/src/tools/steer.ts +2 -13
  548. package/src/tools/tasks.ts +108 -11
  549. package/src/tools/truncate.ts +25 -184
  550. package/src/tools/verify/frontend.ts +3 -1
  551. package/src/tools/verify/index.ts +3 -38
  552. package/src/tools/verify/surface.ts +46 -0
  553. package/src/tools/web-fetch-surface.ts +23 -0
  554. package/src/tools/web-fetch.ts +2 -20
  555. package/src/tools/write.ts +7 -2
  556. package/src/worker/entry.ts +39 -2
  557. package/src/worker/spec-contract.ts +26 -5
  558. package/dist/chunk-7SS2CTV2.js +0 -61361
  559. package/dist/chunk-DKGKUHFA.js +0 -924
  560. package/dist/chunk-GEP36Y4X.js +0 -12796
  561. package/dist/chunk-XYWBQRDM.js +0 -137
  562. package/dist/clio-BZVGEUFJ.js +0 -58
  563. package/dist/configure-S7S6F6CL.js +0 -32
  564. package/docs/html/agents_blueprint.html +0 -936
  565. package/docs/html/alcf_blueprint.html +0 -324
  566. package/docs/html/architecture_blueprint.html +0 -850
  567. package/docs/html/commands_blueprint.html +0 -939
  568. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  569. package/docs/html/configuration_blueprint.html +0 -1080
  570. package/docs/html/context_blueprint.html +0 -603
  571. package/docs/html/documentation_blueprint.html +0 -832
  572. package/docs/html/environment_blueprint.html +0 -404
  573. package/docs/html/eval_blueprint.html +0 -743
  574. package/docs/html/evals_internal_blueprint.html +0 -190
  575. package/docs/html/evolution_blueprint.html +0 -674
  576. package/docs/html/extensions_blueprint.html +0 -2065
  577. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  578. package/docs/html/index.html +0 -919
  579. package/docs/html/lifecycle_blueprint.html +0 -723
  580. package/docs/html/memory_blueprint.html +0 -699
  581. package/docs/html/middleware_blueprint.html +0 -664
  582. package/docs/html/models_blueprint.html +0 -2366
  583. package/docs/html/observability_blueprint.html +0 -683
  584. package/docs/html/provider_adapter_blueprint.html +0 -245
  585. package/docs/html/safety_blueprint.html +0 -1386
  586. package/docs/html/shared.css +0 -571
  587. package/docs/html/shared.js +0 -143
  588. package/docs/html/skills_blueprint.html +0 -671
  589. package/docs/html/soak_blueprint.html +0 -182
  590. package/docs/html/tool_usage_blueprint.html +0 -350
  591. package/docs/html/tools_blueprint.html +0 -2249
  592. package/docs/html/trace_blueprint.html +0 -235
  593. package/docs/html/tui_design_blueprint.html +0 -374
  594. package/docs/html/validation_blueprint.html +0 -961
  595. package/docs/html/worker_dispatch_blueprint.html +0 -231
  596. package/src/core/release.ts +0 -2
  597. package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
  598. package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
  599. package/src/engine/apis/lmstudio-native.ts +0 -1438
  600. package/src/engine/apis/thinking-replay.ts +0 -11
  601. package/src/tools/string-enum.ts +0 -15
@@ -0,0 +1,400 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import { safeResourceWrite } from "../../../core/safe-resource-write.js";
6
+ import type { ProjectType } from "../../session/workspace/project-type.js";
7
+ import {
8
+ CODEWIKI_VERSION,
9
+ type Codewiki,
10
+ type CodewikiEdge,
11
+ type CodewikiEntry,
12
+ type CodewikiFile,
13
+ type CodewikiFileRole,
14
+ type CodewikiLanguage,
15
+ type CodewikiSymbol,
16
+ type CodewikiSymbolKind,
17
+ } from "./schema.js";
18
+
19
+ function uniqueSorted(values: Iterable<string>): string[] {
20
+ return [...new Set([...values].filter((item) => item.length > 0))].sort((a, b) => a.localeCompare(b));
21
+ }
22
+
23
+ function stableFileId(path: string): string {
24
+ return `f_${createHash("sha256").update(path).digest("hex").slice(0, 16)}`;
25
+ }
26
+
27
+ function languageForLegacyPath(path: string): CodewikiLanguage | null {
28
+ if (path.endsWith(".d.ts")) return null;
29
+ const extension = path.slice(path.lastIndexOf("."));
30
+ const source = new Map<string, Exclude<CodewikiLanguage, "config">>([
31
+ [".ts", "typescript"],
32
+ [".tsx", "typescript"],
33
+ [".mts", "typescript"],
34
+ [".cts", "typescript"],
35
+ [".js", "javascript"],
36
+ [".jsx", "javascript"],
37
+ [".mjs", "javascript"],
38
+ [".cjs", "javascript"],
39
+ [".py", "python"],
40
+ [".pyw", "python"],
41
+ [".rs", "rust"],
42
+ [".go", "go"],
43
+ [".c", "c"],
44
+ [".h", "c"],
45
+ [".cc", "c++"],
46
+ [".cpp", "c++"],
47
+ [".cxx", "c++"],
48
+ [".hpp", "c++"],
49
+ [".hh", "c++"],
50
+ [".hxx", "c++"],
51
+ [".cu", "c++"],
52
+ [".cuh", "c++"],
53
+ [".java", "java"],
54
+ [".rb", "ruby"],
55
+ [".cs", "c#"],
56
+ ]).get(extension);
57
+ if (source) return source;
58
+ const name = path.split("/").pop() ?? path;
59
+ return new Set([
60
+ "package.json",
61
+ "pyproject.toml",
62
+ "setup.py",
63
+ "Cargo.toml",
64
+ "go.mod",
65
+ "pom.xml",
66
+ "CMakeLists.txt",
67
+ "compile_commands.json",
68
+ "Gemfile",
69
+ ]).has(name) ||
70
+ name.endsWith(".csproj") ||
71
+ name.toLowerCase().endsWith(".cmake")
72
+ ? "config"
73
+ : null;
74
+ }
75
+
76
+ function compareFiles(a: CodewikiFile, b: CodewikiFile): number {
77
+ return a.path.localeCompare(b.path);
78
+ }
79
+ function compareSymbols(a: CodewikiSymbol, b: CodewikiSymbol): number {
80
+ return (
81
+ a.fileId.localeCompare(b.fileId) || a.line - b.line || a.name.localeCompare(b.name) || a.kind.localeCompare(b.kind)
82
+ );
83
+ }
84
+ function compareEdges(a: CodewikiEdge, b: CodewikiEdge): number {
85
+ const file = a.fileId.localeCompare(b.fileId);
86
+ if (file !== 0) return file;
87
+ const left = "toFileId" in a ? a.toFileId : `~${a.externalModule}`;
88
+ const right = "toFileId" in b ? b.toFileId : `~${b.externalModule}`;
89
+ return left.localeCompare(right);
90
+ }
91
+
92
+ const SIG_KINDS = new Set<CodewikiSymbolKind>(["func", "class", "method", "type"]);
93
+ function normalizeSymbol(symbol: CodewikiSymbol): CodewikiSymbol {
94
+ const sig = SIG_KINDS.has(symbol.kind) ? symbol.sig?.trim().slice(0, 240) : undefined;
95
+ return { name: symbol.name, kind: symbol.kind, fileId: symbol.fileId, line: symbol.line, ...(sig ? { sig } : {}) };
96
+ }
97
+ function normalizeCodewiki(codewiki: Codewiki): Codewiki {
98
+ return {
99
+ version: CODEWIKI_VERSION,
100
+ language: codewiki.language,
101
+ files: codewiki.files
102
+ .map((file) => ({
103
+ id: file.id,
104
+ path: file.path,
105
+ lang: file.lang,
106
+ loc: file.loc,
107
+ role: file.role,
108
+ hash: file.hash,
109
+ imports: uniqueSorted(file.imports),
110
+ ...(file.summary ? { summary: file.summary } : {}),
111
+ }))
112
+ .sort(compareFiles),
113
+ symbols: codewiki.symbols.map(normalizeSymbol).sort(compareSymbols),
114
+ edges: [...codewiki.edges].sort(compareEdges),
115
+ };
116
+ }
117
+
118
+ export function codewikiPath(cwd: string): string {
119
+ return join(cwd, ".clio-coder", "codewiki.json");
120
+ }
121
+ export function serializeCodewiki(codewiki: Codewiki): string {
122
+ return `${JSON.stringify(normalizeCodewiki(codewiki))}\n`;
123
+ }
124
+ export function writeCodewiki(cwd: string, codewiki: Codewiki): string {
125
+ const serialized = serializeCodewiki(codewiki);
126
+ safeResourceWrite(codewikiPath(cwd), serialized, { encoding: "utf8" });
127
+ return serialized;
128
+ }
129
+
130
+ interface CodewikiFileV3 {
131
+ id: string;
132
+ path: string;
133
+ lang: CodewikiLanguage;
134
+ loc: number;
135
+ role: CodewikiFileRole;
136
+ }
137
+ interface CodewikiV3 {
138
+ version: 3;
139
+ language: ProjectType;
140
+ files: CodewikiFileV3[];
141
+ symbols: CodewikiSymbol[];
142
+ edges: CodewikiEdge[];
143
+ }
144
+ interface CodewikiV4 {
145
+ version: 4;
146
+ language: ProjectType;
147
+ files: CodewikiFile[];
148
+ symbols: CodewikiSymbol[];
149
+ edges: CodewikiEdge[];
150
+ }
151
+ interface CodewikiV2 {
152
+ version: 2;
153
+ generatedAt: string;
154
+ language: ProjectType;
155
+ entries: CodewikiEntry[];
156
+ }
157
+
158
+ function upgradeV3(value: CodewikiV3): Codewiki {
159
+ return normalizeCodewiki({
160
+ version: CODEWIKI_VERSION,
161
+ language: value.language,
162
+ files: value.files.map((file) => ({ ...file, hash: "", imports: [] })),
163
+ symbols: value.symbols,
164
+ edges: value.edges,
165
+ });
166
+ }
167
+ function upgradeV4(value: CodewikiV4): Codewiki {
168
+ return normalizeCodewiki({
169
+ version: CODEWIKI_VERSION,
170
+ language: value.language,
171
+ files: value.files.map((file) => ({ ...file, hash: "" })),
172
+ symbols: value.symbols,
173
+ edges: value.edges,
174
+ });
175
+ }
176
+ function upgradeV2(value: CodewikiV2): Codewiki {
177
+ const files: CodewikiFileV3[] = value.entries.map((entry) => ({
178
+ id: stableFileId(entry.path),
179
+ path: entry.path,
180
+ lang:
181
+ languageForLegacyPath(entry.path) ??
182
+ (value.language === "unknown" || value.language === "polyglot" || value.language === "dotfiles"
183
+ ? "config"
184
+ : value.language),
185
+ loc: 0,
186
+ role: entry.kind === "entry-point" ? "entry" : entry.kind === "test" ? "test" : "module",
187
+ }));
188
+ const ids = new Map(files.map((file) => [file.path, file.id] as const));
189
+ const symbols = value.entries
190
+ .flatMap((entry) =>
191
+ entry.exports.map((name) => ({ name, kind: "const" as const, fileId: ids.get(entry.path) ?? "", line: 1 })),
192
+ )
193
+ .filter((symbol) => symbol.fileId);
194
+ const edges = value.entries
195
+ .flatMap((entry) =>
196
+ entry.imports.map((item): CodewikiEdge => {
197
+ const fileId = ids.get(entry.path) ?? "";
198
+ const toFileId = ids.get(item);
199
+ return toFileId ? { fileId, toFileId } : { fileId, externalModule: item };
200
+ }),
201
+ )
202
+ .filter((edge) => edge.fileId);
203
+ return upgradeV3({ version: 3, language: value.language, files, symbols, edges });
204
+ }
205
+
206
+ const LANGUAGES = new Set<CodewikiLanguage>([
207
+ "typescript",
208
+ "javascript",
209
+ "python",
210
+ "rust",
211
+ "go",
212
+ "c",
213
+ "c++",
214
+ "java",
215
+ "ruby",
216
+ "c#",
217
+ "config",
218
+ ]);
219
+ const ROLES = new Set<CodewikiFileRole>(["entry", "test", "module", "config"]);
220
+ const KINDS = new Set<CodewikiSymbolKind>(["func", "class", "method", "type", "const", "var", "trait", "iface"]);
221
+ function object(value: unknown): Record<string, unknown> | null {
222
+ return typeof value === "object" && value !== null && !Array.isArray(value)
223
+ ? (value as Record<string, unknown>)
224
+ : null;
225
+ }
226
+ function validFile(value: unknown, hash: boolean): boolean {
227
+ const item = object(value);
228
+ if (!item) return false;
229
+ return (
230
+ typeof item.id === "string" &&
231
+ typeof item.path === "string" &&
232
+ typeof item.lang === "string" &&
233
+ LANGUAGES.has(item.lang as CodewikiLanguage) &&
234
+ Number.isInteger(item.loc) &&
235
+ (item.loc as number) >= 0 &&
236
+ typeof item.role === "string" &&
237
+ ROLES.has(item.role as CodewikiFileRole) &&
238
+ (!hash ||
239
+ (typeof item.hash === "string" &&
240
+ Array.isArray(item.imports) &&
241
+ item.imports.every((v) => typeof v === "string"))) &&
242
+ (!("summary" in item) || typeof item.summary === "string")
243
+ );
244
+ }
245
+ function validSymbol(value: unknown): boolean {
246
+ const item = object(value);
247
+ if (!item) return false;
248
+ return (
249
+ typeof item.name === "string" &&
250
+ typeof item.kind === "string" &&
251
+ KINDS.has(item.kind as CodewikiSymbolKind) &&
252
+ typeof item.fileId === "string" &&
253
+ Number.isInteger(item.line) &&
254
+ (item.line as number) >= 1 &&
255
+ (!("sig" in item) || typeof item.sig === "string")
256
+ );
257
+ }
258
+ function validEdge(value: unknown): boolean {
259
+ const item = object(value);
260
+ if (!item || typeof item.fileId !== "string") return false;
261
+ return (typeof item.toFileId === "string") !== (typeof item.externalModule === "string");
262
+ }
263
+ function validEntry(value: unknown): boolean {
264
+ const item = object(value);
265
+ if (!item || typeof item.path !== "string") return false;
266
+ return (
267
+ Array.isArray(item.exports) &&
268
+ item.exports.every((v) => typeof v === "string") &&
269
+ Array.isArray(item.imports) &&
270
+ item.imports.every((v) => typeof v === "string") &&
271
+ (item.kind === "entry-point" || item.kind === "test" || item.kind === "module") &&
272
+ (!("summary" in item) || typeof item.summary === "string")
273
+ );
274
+ }
275
+ function validNative(value: Codewiki): boolean {
276
+ const ids = new Set<string>();
277
+ const paths = new Set<string>();
278
+ const loc = new Map<string, number>();
279
+ for (const file of value.files) {
280
+ const segments = file.path.split("/");
281
+ if (
282
+ ids.has(file.id) ||
283
+ paths.has(file.path) ||
284
+ file.path.length === 0 ||
285
+ file.path.includes("\0") ||
286
+ file.path.includes("\\") ||
287
+ file.path.startsWith("/") ||
288
+ /^[A-Za-z]:\//.test(file.path) ||
289
+ segments.some((part) => part.length === 0 || part === "." || part === "..") ||
290
+ !/^[0-9a-f]{16}$/.test(file.hash)
291
+ )
292
+ return false;
293
+ ids.add(file.id);
294
+ paths.add(file.path);
295
+ loc.set(file.id, file.loc);
296
+ }
297
+ for (const symbol of value.symbols) {
298
+ const lines = loc.get(symbol.fileId);
299
+ if (lines === undefined || symbol.line > lines) return false;
300
+ }
301
+ return value.edges.every((edge) => ids.has(edge.fileId) && (!("toFileId" in edge) || ids.has(edge.toFileId)));
302
+ }
303
+
304
+ function upgrade(value: unknown): Codewiki | null {
305
+ const item = object(value);
306
+ if (!item || typeof item.language !== "string") return null;
307
+ if (
308
+ item.version === 5 &&
309
+ Array.isArray(item.files) &&
310
+ item.files.every((v) => validFile(v, true)) &&
311
+ Array.isArray(item.symbols) &&
312
+ item.symbols.every(validSymbol) &&
313
+ Array.isArray(item.edges) &&
314
+ item.edges.every(validEdge) &&
315
+ validNative(item as unknown as Codewiki)
316
+ )
317
+ return normalizeCodewiki(item as unknown as Codewiki);
318
+ if (
319
+ item.version === 4 &&
320
+ Array.isArray(item.files) &&
321
+ item.files.every((v) => validFile(v, true)) &&
322
+ Array.isArray(item.symbols) &&
323
+ item.symbols.every(validSymbol) &&
324
+ Array.isArray(item.edges) &&
325
+ item.edges.every(validEdge)
326
+ )
327
+ return upgradeV4(item as unknown as CodewikiV4);
328
+ if (
329
+ item.version === 3 &&
330
+ Array.isArray(item.files) &&
331
+ item.files.every((v) => validFile(v, false)) &&
332
+ Array.isArray(item.symbols) &&
333
+ item.symbols.every(validSymbol) &&
334
+ Array.isArray(item.edges) &&
335
+ item.edges.every(validEdge)
336
+ )
337
+ return upgradeV3(item as unknown as CodewikiV3);
338
+ if (
339
+ item.version === 2 &&
340
+ typeof item.generatedAt === "string" &&
341
+ Array.isArray(item.entries) &&
342
+ item.entries.every(validEntry)
343
+ )
344
+ return upgradeV2(item as unknown as CodewikiV2);
345
+ return null;
346
+ }
347
+
348
+ export function parseCodewikiRaw(raw: string): Codewiki | null {
349
+ try {
350
+ return upgrade(JSON.parse(raw));
351
+ } catch {
352
+ return null;
353
+ }
354
+ }
355
+ export function readCodewiki(cwd: string): Codewiki | null {
356
+ const path = codewikiPath(cwd);
357
+ if (!existsSync(path)) return null;
358
+ try {
359
+ return parseCodewikiRaw(readFileSync(path, "utf8"));
360
+ } catch {
361
+ return null;
362
+ }
363
+ }
364
+ export async function readCodewikiAsync(cwd: string): Promise<Codewiki | null> {
365
+ try {
366
+ return parseCodewikiRaw(await readFile(codewikiPath(cwd), "utf8"));
367
+ } catch {
368
+ return null;
369
+ }
370
+ }
371
+ export function codewikiNeedsBackfill(codewiki: Codewiki): boolean {
372
+ return codewiki.files.some((file) => file.lang !== "config" && file.hash.length === 0);
373
+ }
374
+ export function structuralCodewikiHash(codewiki: Codewiki): string {
375
+ return createHash("sha256")
376
+ .update(JSON.stringify(normalizeCodewiki(codewiki)))
377
+ .digest("hex");
378
+ }
379
+ export function codewikiEntries(codewiki: Codewiki): CodewikiEntry[] {
380
+ const files = new Map(codewiki.files.map((file) => [file.id, file] as const));
381
+ const exports = new Map<string, string[]>();
382
+ const imports = new Map<string, string[]>();
383
+ for (const symbol of codewiki.symbols)
384
+ exports.set(symbol.fileId, [...(exports.get(symbol.fileId) ?? []), symbol.name]);
385
+ for (const edge of codewiki.edges) {
386
+ const value = "toFileId" in edge ? files.get(edge.toFileId)?.path : edge.externalModule;
387
+ if (value) imports.set(edge.fileId, [...(imports.get(edge.fileId) ?? []), value]);
388
+ }
389
+ return codewiki.files
390
+ .filter((file) => file.lang !== "config")
391
+ .map((file) => ({
392
+ path: file.path,
393
+ exports: uniqueSorted(exports.get(file.id) ?? []),
394
+ imports: uniqueSorted(imports.get(file.id) ?? []),
395
+ kind:
396
+ file.role === "entry" ? ("entry-point" as const) : file.role === "test" ? ("test" as const) : ("module" as const),
397
+ ...(file.summary ? { summary: file.summary } : {}),
398
+ }))
399
+ .sort((a, b) => a.path.localeCompare(b.path));
400
+ }
@@ -0,0 +1,24 @@
1
+ import type { Fingerprint } from "../fingerprint.js";
2
+ import type { Codewiki } from "./schema.js";
3
+
4
+ export type CodewikiBuildWorkerRequest =
5
+ | { kind: "build"; cwd: string; language: Codewiki["language"] }
6
+ | {
7
+ kind: "ensure";
8
+ cwd: string;
9
+ /** Optional when neither state nor an existing artifact identifies the project. */
10
+ language?: Codewiki["language"];
11
+ current: Codewiki | null;
12
+ previous: Fingerprint | null;
13
+ }
14
+ | { kind: "incremental"; cwd: string; current: Codewiki; paths: string[] };
15
+
16
+ export interface CodewikiBuildWorkerResult {
17
+ codewiki: Codewiki;
18
+ fingerprint: Fingerprint;
19
+ changed: boolean;
20
+ }
21
+
22
+ export type CodewikiBuildWorkerMessage =
23
+ | { ok: true; result: CodewikiBuildWorkerResult }
24
+ | { ok: false; error: string; stack?: string };
@@ -0,0 +1,54 @@
1
+ import { parentPort, workerData } from "node:worker_threads";
2
+ import { detectProjectType } from "../../session/workspace/project-type.js";
3
+ import { computeFingerprint, isStale } from "../fingerprint.js";
4
+ import { codewikiNeedsBackfill } from "./artifact.js";
5
+ import type {
6
+ CodewikiBuildWorkerMessage,
7
+ CodewikiBuildWorkerRequest,
8
+ CodewikiBuildWorkerResult,
9
+ } from "./build-worker-protocol.js";
10
+ import { buildCodewiki, syncCodewiki, updateCodewikiPaths } from "./indexer.js";
11
+
12
+ async function execute(request: CodewikiBuildWorkerRequest): Promise<CodewikiBuildWorkerResult> {
13
+ if (request.kind === "build") {
14
+ const codewiki = await buildCodewiki({ cwd: request.cwd, language: request.language });
15
+ return { codewiki, fingerprint: computeFingerprint(request.cwd, codewiki), changed: true };
16
+ }
17
+ if (request.kind === "incremental") {
18
+ const codewiki = await updateCodewikiPaths(request.cwd, request.current, request.paths);
19
+ return {
20
+ codewiki,
21
+ fingerprint: computeFingerprint(request.cwd, codewiki),
22
+ changed: codewiki !== request.current,
23
+ };
24
+ }
25
+ if (request.current && !codewikiNeedsBackfill(request.current)) {
26
+ const currentFingerprint = computeFingerprint(request.cwd, request.current);
27
+ if (request.previous && !isStale(request.previous, currentFingerprint)) {
28
+ return { codewiki: request.current, fingerprint: currentFingerprint, changed: false };
29
+ }
30
+ }
31
+ const codewiki = request.current
32
+ ? await syncCodewiki(request.cwd, request.current)
33
+ : await buildCodewiki({ cwd: request.cwd, language: request.language ?? detectProjectType(request.cwd) });
34
+ return { codewiki, fingerprint: computeFingerprint(request.cwd, codewiki), changed: true };
35
+ }
36
+
37
+ const port = parentPort;
38
+ if (!port) throw new Error("codewiki build worker requires a worker_threads parent");
39
+
40
+ execute(workerData as CodewikiBuildWorkerRequest).then(
41
+ (result) => {
42
+ port.postMessage({ ok: true, result } satisfies CodewikiBuildWorkerMessage);
43
+ port.close();
44
+ },
45
+ (error: unknown) => {
46
+ const message = error instanceof Error ? error.message : String(error);
47
+ port.postMessage({
48
+ ok: false,
49
+ error: message,
50
+ ...(error instanceof Error && error.stack ? { stack: error.stack } : {}),
51
+ } satisfies CodewikiBuildWorkerMessage);
52
+ port.close();
53
+ },
54
+ );
@@ -0,0 +1,182 @@
1
+ import { existsSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { resolve } from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ import { Worker } from "node:worker_threads";
6
+ import { withStateFileLock } from "../../../core/state-file-lock.js";
7
+ import { codewikiPath, readCodewiki, writeCodewiki } from "./artifact.js";
8
+ import type {
9
+ CodewikiBuildWorkerMessage,
10
+ CodewikiBuildWorkerRequest,
11
+ CodewikiBuildWorkerResult,
12
+ } from "./build-worker-protocol.js";
13
+ import type { Codewiki } from "./schema.js";
14
+
15
+ const BUILD_TIMEOUT_MS = 120_000;
16
+ const workspaceTails = new Map<string, Promise<void>>();
17
+ const require = createRequire(import.meta.url);
18
+
19
+ function buildWorkerUrl(): URL {
20
+ if (!import.meta.url.endsWith(".ts")) return new URL("./codewiki/build-worker.js", import.meta.url);
21
+ // Test/source execution changes cwd for hermetic fixtures. A tiny JavaScript
22
+ // bootstrap imports the absolute TypeScript loader before dynamically loading
23
+ // the source worker; relying on inherited `--import tsx` would resolve `tsx`
24
+ // from the fixture and Node 24 would otherwise strip the entry's types without
25
+ // remapping its internal `.js` specifiers back to `.ts`.
26
+ const loaderApi = pathToFileURL(require.resolve("tsx/esm/api")).href;
27
+ const source = new URL("./build-worker.ts", import.meta.url).href;
28
+ return new URL(
29
+ `data:text/javascript,${encodeURIComponent(`const { tsImport } = await import(${JSON.stringify(loaderApi)}); await tsImport(${JSON.stringify(source)}, import.meta.url);`)}`,
30
+ );
31
+ }
32
+
33
+ async function executeInWorker(request: CodewikiBuildWorkerRequest): Promise<CodewikiBuildWorkerResult> {
34
+ // Do not inherit test-runner/application `--import` hooks. In particular,
35
+ // `--import tsx` would be re-resolved from a hermetic fixture cwd before the
36
+ // source bootstrap can install its absolute loader.
37
+ const worker = new Worker(buildWorkerUrl(), { workerData: request, execArgv: [] });
38
+ let exited = false;
39
+ const exit = new Promise<void>((resolve) => {
40
+ worker.once("exit", () => {
41
+ exited = true;
42
+ resolve();
43
+ });
44
+ });
45
+ let timer: NodeJS.Timeout | undefined;
46
+ try {
47
+ return await new Promise<CodewikiBuildWorkerResult>((resolve, reject) => {
48
+ let settled = false;
49
+ const finish = (callback: () => void): void => {
50
+ if (settled) return;
51
+ settled = true;
52
+ if (timer) clearTimeout(timer);
53
+ callback();
54
+ };
55
+ timer = setTimeout(() => {
56
+ finish(() => reject(new Error(`codewiki build worker exceeded ${BUILD_TIMEOUT_MS} ms`)));
57
+ }, BUILD_TIMEOUT_MS);
58
+ timer.unref();
59
+ worker.once("message", (message: CodewikiBuildWorkerMessage) => {
60
+ finish(() => {
61
+ if (message.ok) resolve(message.result);
62
+ else {
63
+ const error = new Error(message.error);
64
+ if (message.stack) error.stack = message.stack;
65
+ reject(error);
66
+ }
67
+ });
68
+ });
69
+ worker.once("error", (error) =>
70
+ finish(() => {
71
+ reject(error);
72
+ }),
73
+ );
74
+ worker.once("exit", (code) => {
75
+ if (code !== 0)
76
+ finish(() => {
77
+ reject(new Error(`codewiki build worker exited with code ${code}`));
78
+ });
79
+ });
80
+ });
81
+ } finally {
82
+ if (timer) clearTimeout(timer);
83
+ if (!exited) {
84
+ await Promise.race([
85
+ exit,
86
+ new Promise<void>((resolve) => {
87
+ const grace = setTimeout(resolve, 250);
88
+ grace.unref();
89
+ }),
90
+ ]);
91
+ }
92
+ if (!exited) await worker.terminate().catch(() => undefined);
93
+ }
94
+ }
95
+
96
+ function enqueueWorkspace<T>(cwd: string, task: () => Promise<T>): Promise<T> {
97
+ const key = codewikiPath(cwd);
98
+ const previous = workspaceTails.get(key) ?? Promise.resolve();
99
+ const result = previous.catch(() => undefined).then(task);
100
+ const tail = result.then(
101
+ () => undefined,
102
+ () => undefined,
103
+ );
104
+ workspaceTails.set(key, tail);
105
+ void tail.finally(() => {
106
+ if (workspaceTails.get(key) === tail) workspaceTails.delete(key);
107
+ });
108
+ return result;
109
+ }
110
+
111
+ export interface CodewikiCoordinatedResult {
112
+ codewiki: Codewiki;
113
+ worker: CodewikiBuildWorkerResult;
114
+ wrote: boolean;
115
+ }
116
+
117
+ export interface CodewikiCoordinateOptions {
118
+ /** Never create an artifact merely because a background session happened to start. */
119
+ requireExisting?: boolean;
120
+ /** Optional identity-checked cache, evaluated only after the cross-process lease is held. */
121
+ readCurrent?: (workspace: string) => Codewiki | undefined;
122
+ beforeCommit?: (result: CodewikiBuildWorkerResult, workspace: string) => void | Promise<void>;
123
+ afterCommit?: (result: CodewikiBuildWorkerResult, workspace: string) => void | Promise<void>;
124
+ }
125
+
126
+ /**
127
+ * The only production codewiki commit transaction. The in-process queue gives
128
+ * demand, idle, incremental, and explicit operations one generation order; the
129
+ * file lease extends the same order across Clio processes. The request is
130
+ * selected after the lease is held and the artifact has been re-read, so an
131
+ * incremental update can never be based on a generation that another writer
132
+ * already replaced.
133
+ */
134
+ export function coordinateCodewikiWrite(
135
+ cwd: string,
136
+ select: (
137
+ current: Codewiki | null,
138
+ workspace: string,
139
+ ) => CodewikiBuildWorkerRequest | null | Promise<CodewikiBuildWorkerRequest | null>,
140
+ options: CodewikiCoordinateOptions = {},
141
+ ): Promise<CodewikiCoordinatedResult | null> {
142
+ const workspace = resolve(cwd);
143
+ return enqueueWorkspace(workspace, () =>
144
+ withStateFileLock(codewikiPath(workspace), async () => {
145
+ if (options.requireExisting && !existsSync(codewikiPath(workspace))) return null;
146
+ const current = options.readCurrent?.(workspace) ?? readCodewiki(workspace);
147
+ const request = await select(current, workspace);
148
+ if (!request) return null;
149
+ const worker = await executeInWorker({ ...request, cwd: workspace });
150
+ await options.beforeCommit?.(worker, workspace);
151
+ const wrote = worker.changed || !existsSync(codewikiPath(workspace));
152
+ if (wrote) writeCodewiki(workspace, worker.codewiki);
153
+ await options.afterCommit?.(worker, workspace);
154
+ return { codewiki: !worker.changed && current ? current : worker.codewiki, worker, wrote };
155
+ }),
156
+ );
157
+ }
158
+
159
+ /** Serialize a non-build artifact transaction such as reset with every writer. */
160
+ export function coordinateCodewikiExclusive<T>(cwd: string, task: (workspace: string) => T | Promise<T>): Promise<T> {
161
+ const workspace = resolve(cwd);
162
+ return enqueueWorkspace(workspace, () => withStateFileLock(codewikiPath(workspace), () => task(workspace)));
163
+ }
164
+
165
+ /** Build a preview candidate in the worker without acquiring a writer lease or touching disk. */
166
+ export function buildCodewikiCandidate(
167
+ cwd: string,
168
+ language: Codewiki["language"],
169
+ ): Promise<CodewikiBuildWorkerResult> {
170
+ return executeInWorker({ kind: "build", cwd: resolve(cwd), language });
171
+ }
172
+
173
+ /** Await every writer already admitted for one workspace, including idle refresh. */
174
+ export async function drainCodewikiWrites(cwd: string): Promise<void> {
175
+ const workspace = resolve(cwd);
176
+ for (;;) {
177
+ const tail = workspaceTails.get(codewikiPath(workspace));
178
+ if (!tail) return;
179
+ await tail;
180
+ if (workspaceTails.get(codewikiPath(workspace)) === tail) return;
181
+ }
182
+ }