@iowarp/clio-coder 0.3.1 → 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 (595) hide show
  1. package/CHANGELOG.md +90 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +284 -613
  4. package/dist/{acp-FPR54DGL.js → acp-BIYHVZIM.js} +43 -53
  5. package/dist/{agents-OGPIHPJH.js → agents-YT6SSRIT.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-PV4JUBVJ.js → chunk-2EHAIA3X.js} +40 -21
  9. package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
  10. package/dist/chunk-2SFS6XQE.js +122 -0
  11. package/dist/chunk-2VTFPG5O.js +48 -0
  12. package/dist/{chunk-MAR7Y6HW.js → chunk-3ZXDFGR5.js} +23 -16
  13. package/dist/chunk-4BJ5BYCE.js +61 -0
  14. package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
  15. package/dist/chunk-4KLWL3UC.js +18 -0
  16. package/dist/chunk-4VP4KH3K.js +962 -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-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
  21. package/dist/chunk-65DEGPJ6.js +52 -0
  22. package/dist/chunk-6EJMN2Y3.js +17 -0
  23. package/dist/chunk-6EJV5X2W.js +16405 -0
  24. package/dist/chunk-6N5PTWMY.js +136 -0
  25. package/dist/chunk-6XLNIQDB.js +27 -0
  26. package/dist/{chunk-TEKV33Q5.js → chunk-77VKQEHF.js} +65 -33
  27. package/dist/chunk-7CR24IG7.js +242 -0
  28. package/dist/{chunk-M5T5VO65.js → chunk-7EYHLWU7.js} +837 -635
  29. package/dist/chunk-7MNJORFF.js +22 -0
  30. package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
  31. package/dist/chunk-AGYYIBLL.js +1069 -0
  32. package/dist/chunk-AO4RKG4M.js +277 -0
  33. package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
  34. package/dist/chunk-ARBGF5F7.js +174 -0
  35. package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
  36. package/dist/chunk-CBCAPZAA.js +229 -0
  37. package/dist/chunk-CMZWFGD2.js +352 -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-RPTR2H26.js → chunk-EPVUXGXG.js} +21 -15
  42. package/dist/chunk-FCSXB6T2.js +338 -0
  43. package/dist/chunk-FJ3H4MN5.js +48 -0
  44. package/dist/chunk-FQ4SKYE4.js +29 -0
  45. package/dist/chunk-G2DE3C7R.js +644 -0
  46. package/dist/chunk-G4BMMOKF.js +182 -0
  47. package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
  48. package/dist/chunk-HC4CLZ2Y.js +68 -0
  49. package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
  50. package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
  51. package/dist/chunk-I4HZDVNP.js +73 -0
  52. package/dist/{chunk-4QKXUHSR.js → chunk-IGLFWIYI.js} +70 -20
  53. package/dist/chunk-IKCO5N3L.js +162 -0
  54. package/dist/chunk-IR4CFBFN.js +56 -0
  55. package/dist/{chunk-PFEFKVGL.js → chunk-J5HN4RYU.js} +13 -11
  56. package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
  57. package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
  58. package/dist/chunk-KJ5LWLOE.js +1077 -0
  59. package/dist/chunk-LBMZMYH2.js +285 -0
  60. package/dist/{chunk-G34LV2PF.js → chunk-LBNRH5WM.js} +84 -170
  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-MAW544W2.js +1882 -0
  64. package/dist/chunk-MBS4V7ZP.js +217 -0
  65. package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
  66. package/dist/chunk-MNA4JGU4.js +255 -0
  67. package/dist/chunk-MQSRRFWA.js +3428 -0
  68. package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
  69. package/dist/chunk-OAO4GE4M.js +619 -0
  70. package/dist/chunk-OHHN2SO4.js +5135 -0
  71. package/dist/chunk-OKGUZO2U.js +34 -0
  72. package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
  73. package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
  74. package/dist/chunk-OQE5J4C6.js +73 -0
  75. package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
  76. package/dist/chunk-POHLU5DW.js +1186 -0
  77. package/dist/chunk-QKMUKYO7.js +4961 -0
  78. package/dist/{chunk-ASND7OZK.js → chunk-QTYWRVRA.js} +13 -13
  79. package/dist/{chunk-EYOKLTMF.js → chunk-SRF2PJNW.js} +17 -3
  80. package/dist/chunk-SST6Z5JA.js +80 -0
  81. package/dist/chunk-STBPMHSX.js +2456 -0
  82. package/dist/chunk-T6YILFSB.js +80 -0
  83. package/dist/chunk-TZTZS7QK.js +227 -0
  84. package/dist/chunk-UOV2BYIW.js +107 -0
  85. package/dist/{chunk-Q3RUPKEJ.js → chunk-V4RXGQ5Q.js} +58 -189
  86. package/dist/chunk-VAKQQHWR.js +434 -0
  87. package/dist/chunk-VG7TBQIY.js +128 -0
  88. package/dist/chunk-VJWL6YS5.js +244 -0
  89. package/dist/chunk-WEH5XRJQ.js +32 -0
  90. package/dist/chunk-WMSVI4G2.js +2095 -0
  91. package/dist/chunk-WVO7V2QY.js +797 -0
  92. package/dist/chunk-X4RCMKVQ.js +641 -0
  93. package/dist/chunk-X75S7HFS.js +374 -0
  94. package/dist/chunk-XN3L4EYL.js +46 -0
  95. package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
  96. package/dist/chunk-YHZX5GEU.js +193 -0
  97. package/dist/chunk-YXLYO42X.js +91 -0
  98. package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
  99. package/dist/chunk-ZI647VB5.js +37 -0
  100. package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
  101. package/dist/cli/index.js +62 -54
  102. package/dist/clio-4LY5K2AC.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-GTLUW2PR.js} +92 -55
  108. package/dist/configure-R6A64DHX.js +42 -0
  109. package/dist/context-5VKGUVJJ.js +866 -0
  110. package/dist/{context-3KWFLHJG.js → context-JFZEJ7W5.js} +15 -13
  111. package/dist/{context-5RADCKTR.js → context-RW5HC47S.js} +71 -35
  112. package/dist/{context-clear-7TSNPAAI.js → context-clear-6ZHBAZZT.js} +54 -28
  113. package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
  114. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  115. package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
  116. package/dist/{doctor-UC5NAJYQ.js → doctor-KI767GSN.js} +27 -17
  117. package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
  118. package/dist/{evidence-YEGUW4L3.js → evidence-UA6AWDQQ.js} +46 -26
  119. package/dist/{evolve-TXARCTPG.js → evolve-QNTFGV6Z.js} +45 -25
  120. package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
  121. package/dist/{fleet-6G3DHNYE.js → fleet-Q7UOMUSG.js} +163 -54
  122. package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
  123. package/dist/{init-KZ5QTF6M.js → init-WBB65ZHQ.js} +69 -32
  124. package/dist/{memory-73ESV5YC.js → memory-MD3O64RI.js} +48 -27
  125. package/dist/{models-A4PVNWJK.js → models-BZU34YWD.js} +39 -25
  126. package/dist/monitor-MEQA5C3I.js +661 -0
  127. package/dist/{chunk-FCIH3BIZ.js → orchestrator-CGFKEP27.js} +11832 -8687
  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-IV4Q6RLN.js} +101 -61
  132. package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
  133. package/dist/{skills-2V6RA3OQ.js → skills-LQEKRDTN.js} +34 -14
  134. package/dist/{skills-eval-S2TVJO4F.js → skills-eval-3DC4HEWS.js} +70 -34
  135. package/dist/steer-GGWFUJUD.js +77 -0
  136. package/dist/{targets-TYXLPB23.js → targets-C4SSGQOB.js} +43 -27
  137. package/dist/terminal-lease-IT5JW2NR.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-7TT7SQ3G.js} +45 -25
  142. package/dist/{usage-ZAFSXKKG.js → usage-GV4PKT3M.js} +62 -31
  143. package/dist/verify-G6V4D2G7.js +716 -0
  144. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  145. package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-DQF6Z66B.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 +362 -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 +42 -6
  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 +173 -47
  444. package/src/interactive/chat-renderer.ts +262 -72
  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 +228 -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 +20 -2
  456. package/src/interactive/footer-panel.ts +2 -2
  457. package/src/interactive/format-time.ts +14 -2
  458. package/src/interactive/interactive-application.ts +201 -17
  459. package/src/interactive/interactive-event-projection.ts +6 -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 +176 -114
  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/decisions.ts +300 -0
  474. package/src/interactive/overlays/help-reference.ts +15 -10
  475. package/src/interactive/overlays/model-selector.ts +34 -16
  476. package/src/interactive/overlays/session-selector.ts +18 -0
  477. package/src/interactive/overlays/settings.ts +105 -17
  478. package/src/interactive/overlays/skills-hub.ts +4 -4
  479. package/src/interactive/overlays/tree-selector.ts +41 -6
  480. package/src/interactive/render-trace.ts +499 -90
  481. package/src/interactive/renderers/compaction-summary.ts +2 -2
  482. package/src/interactive/renderers/diff.ts +115 -104
  483. package/src/interactive/renderers/mermaid.ts +53 -0
  484. package/src/interactive/renderers/tool-execution.ts +386 -133
  485. package/src/interactive/renderers/worker-entry.ts +20 -4
  486. package/src/interactive/session-switch-settlement.ts +10 -0
  487. package/src/interactive/slash-autocomplete.ts +6 -114
  488. package/src/interactive/slash-commands.ts +135 -47
  489. package/src/interactive/slash-spec.ts +9 -38
  490. package/src/interactive/status/controller.ts +5 -1
  491. package/src/interactive/stdout-backpressure.ts +99 -0
  492. package/src/interactive/stream-pacer.ts +530 -0
  493. package/src/interactive/stream-pacing-policy.ts +66 -0
  494. package/src/interactive/tasks-overlay.ts +368 -14
  495. package/src/interactive/terminal-lease.ts +485 -0
  496. package/src/interactive/theme/tokens.ts +1 -1
  497. package/src/interactive/turn-context.ts +4 -3
  498. package/src/interactive/turn-persistence.ts +30 -13
  499. package/src/interactive/turn-queues.ts +12 -0
  500. package/src/interactive/turn-recovery.ts +25 -8
  501. package/src/interactive/turn-runtime.ts +79 -12
  502. package/src/interactive/turn-state.ts +10 -0
  503. package/src/interactive/view/artifacts.ts +114 -4
  504. package/src/interactive/view/view-overlay.ts +3 -0
  505. package/src/interactive/welcome-dashboard.ts +17 -16
  506. package/src/interactive/worker-receipts.ts +52 -3
  507. package/src/interactive/worker-stream.ts +5 -1
  508. package/src/tools/agent-tools.ts +23 -3
  509. package/src/tools/artifact.ts +2 -2
  510. package/src/tools/ask-user.ts +23 -13
  511. package/src/tools/bash.ts +30 -2
  512. package/src/tools/bootstrap.ts +34 -431
  513. package/src/tools/builtin-tool-catalog.ts +265 -0
  514. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  515. package/src/tools/codewiki/code-nav.ts +8 -22
  516. package/src/tools/codewiki/shared.ts +41 -38
  517. package/src/tools/context/docs-engine.ts +14 -3
  518. package/src/tools/context/index.ts +107 -28
  519. package/src/tools/context/surface.ts +19 -0
  520. package/src/tools/core-bootstrap.ts +168 -0
  521. package/src/tools/credential-present.ts +5 -5
  522. package/src/tools/dispatch-admission.ts +533 -0
  523. package/src/tools/dispatch-background.ts +54 -0
  524. package/src/tools/dispatch-event-text.ts +6 -0
  525. package/src/tools/dispatch-plan.ts +9 -4
  526. package/src/tools/dispatch-run-events.ts +238 -0
  527. package/src/tools/dispatch-runner.ts +2370 -0
  528. package/src/tools/dispatch-scout-admission.ts +295 -0
  529. package/src/tools/dispatch-types.ts +77 -0
  530. package/src/tools/dispatch.ts +67 -3161
  531. package/src/tools/find.ts +4 -2
  532. package/src/tools/grep.ts +2 -2
  533. package/src/tools/lazy-tool.ts +60 -0
  534. package/src/tools/ledger.ts +3 -3
  535. package/src/tools/monitor-surface.ts +36 -0
  536. package/src/tools/monitor.ts +2 -32
  537. package/src/tools/observers.ts +2 -2
  538. package/src/tools/registry.ts +39 -27
  539. package/src/tools/safe-exec.ts +2 -2
  540. package/src/tools/steer-surface.ts +17 -0
  541. package/src/tools/steer.ts +2 -13
  542. package/src/tools/tasks.ts +108 -11
  543. package/src/tools/truncate.ts +25 -184
  544. package/src/tools/verify/frontend.ts +3 -1
  545. package/src/tools/verify/index.ts +3 -38
  546. package/src/tools/verify/surface.ts +46 -0
  547. package/src/tools/web-fetch-surface.ts +23 -0
  548. package/src/tools/web-fetch.ts +2 -20
  549. package/src/tools/write.ts +7 -2
  550. package/src/worker/entry.ts +39 -2
  551. package/src/worker/spec-contract.ts +26 -5
  552. package/dist/chunk-7SS2CTV2.js +0 -61361
  553. package/dist/chunk-DKGKUHFA.js +0 -924
  554. package/dist/chunk-GEP36Y4X.js +0 -12796
  555. package/dist/chunk-XYWBQRDM.js +0 -137
  556. package/dist/clio-BZVGEUFJ.js +0 -58
  557. package/dist/configure-S7S6F6CL.js +0 -32
  558. package/docs/html/agents_blueprint.html +0 -936
  559. package/docs/html/alcf_blueprint.html +0 -324
  560. package/docs/html/architecture_blueprint.html +0 -850
  561. package/docs/html/commands_blueprint.html +0 -939
  562. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  563. package/docs/html/configuration_blueprint.html +0 -1080
  564. package/docs/html/context_blueprint.html +0 -603
  565. package/docs/html/documentation_blueprint.html +0 -832
  566. package/docs/html/environment_blueprint.html +0 -404
  567. package/docs/html/eval_blueprint.html +0 -743
  568. package/docs/html/evals_internal_blueprint.html +0 -190
  569. package/docs/html/evolution_blueprint.html +0 -674
  570. package/docs/html/extensions_blueprint.html +0 -2065
  571. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  572. package/docs/html/index.html +0 -919
  573. package/docs/html/lifecycle_blueprint.html +0 -723
  574. package/docs/html/memory_blueprint.html +0 -699
  575. package/docs/html/middleware_blueprint.html +0 -664
  576. package/docs/html/models_blueprint.html +0 -2366
  577. package/docs/html/observability_blueprint.html +0 -683
  578. package/docs/html/provider_adapter_blueprint.html +0 -245
  579. package/docs/html/safety_blueprint.html +0 -1386
  580. package/docs/html/shared.css +0 -571
  581. package/docs/html/shared.js +0 -143
  582. package/docs/html/skills_blueprint.html +0 -671
  583. package/docs/html/soak_blueprint.html +0 -182
  584. package/docs/html/tool_usage_blueprint.html +0 -350
  585. package/docs/html/tools_blueprint.html +0 -2249
  586. package/docs/html/trace_blueprint.html +0 -235
  587. package/docs/html/tui_design_blueprint.html +0 -374
  588. package/docs/html/validation_blueprint.html +0 -961
  589. package/docs/html/worker_dispatch_blueprint.html +0 -231
  590. package/src/core/release.ts +0 -2
  591. package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
  592. package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
  593. package/src/engine/apis/lmstudio-native.ts +0 -1438
  594. package/src/engine/apis/thinking-replay.ts +0 -11
  595. package/src/tools/string-enum.ts +0 -15
@@ -4,20 +4,21 @@ import {
4
4
  } from "./chunk-5WIGXA4T.js";
5
5
  import {
6
6
  loadMemoryRecordsSync
7
- } from "./chunk-PFEFKVGL.js";
7
+ } from "./chunk-J5HN4RYU.js";
8
+ import {
9
+ sha256
10
+ } from "./chunk-6EJV5X2W.js";
8
11
  import {
9
12
  WIKI_INDEX,
10
13
  WIKI_PLAN_FILE,
11
14
  WIKI_QUICKSTART,
12
15
  changedPathsSince,
13
- compileGlobRegex,
14
16
  computeWikiContentHash,
15
17
  computeWikiContentHashOfDir,
16
18
  currentWikiGitHead,
17
19
  isGeneratedWikiFile,
18
20
  listWikiPages,
19
21
  listWikiPagesInDir,
20
- normalizeGlobInput,
21
22
  readWikiMeta,
22
23
  readWikiPage,
23
24
  readWikiPlanFile,
@@ -32,49 +33,53 @@ import {
32
33
  wikiStaleness,
33
34
  writeWikiMeta,
34
35
  writeWikiPlanFile
35
- } from "./chunk-7SS2CTV2.js";
36
+ } from "./chunk-X4RCMKVQ.js";
36
37
  import {
37
- computeFingerprint,
38
- computeFingerprintAsync,
39
- computeFingerprintCached,
40
- isStale,
38
+ buildCodewikiCandidate,
39
+ coordinateCodewikiExclusive,
40
+ coordinateCodewikiWrite,
41
+ drainCodewikiWrites,
41
42
  readClioState,
42
43
  statePath,
43
44
  writeClioState
44
- } from "./chunk-BSU2YIWB.js";
45
+ } from "./chunk-MVVUPGPW.js";
46
+ import {
47
+ compileGlobRegex,
48
+ normalizeGlobInput
49
+ } from "./chunk-VG7TBQIY.js";
50
+ import {
51
+ detectProjectType
52
+ } from "./chunk-YHZX5GEU.js";
53
+ import {
54
+ computeFingerprintCached,
55
+ isStale
56
+ } from "./chunk-VJWL6YS5.js";
45
57
  import {
46
- buildCodewiki,
47
- codewikiNeedsBackfill,
48
58
  codewikiPath,
49
- createSlicer,
50
- detectProjectType,
51
- enumerateWorkspaceFiles,
52
- parseCodewikiRaw,
53
- readCodewiki,
54
- readCodewikiAsync,
55
- syncCodewiki,
56
- updateCodewikiPaths,
57
- writeCodewiki
58
- } from "./chunk-N6F52NLF.js";
59
+ readCodewiki
60
+ } from "./chunk-LBMZMYH2.js";
59
61
  import {
60
- classifyProjectPreload
61
- } from "./chunk-K5XEMXTI.js";
62
+ enumerateWorkspaceFiles
63
+ } from "./chunk-EKMEHE4H.js";
62
64
  import {
63
65
  ceilChars
64
- } from "./chunk-H6F6BYOH.js";
66
+ } from "./chunk-LZSJBIVT.js";
65
67
  import {
66
68
  INTEROP_AGENT_KINDS
67
69
  } from "./chunk-IHXBNWMM.js";
68
- import {
69
- BusChannels
70
- } from "./chunk-Q5WJOSJ7.js";
71
70
  import {
72
71
  require_dist
73
- } from "./chunk-GB6QRBXN.js";
72
+ } from "./chunk-APJ265NV.js";
74
73
  import {
75
74
  clioDataDir,
76
75
  resolveClioDirs
77
76
  } from "./chunk-BNAZZHFG.js";
77
+ import {
78
+ BusChannels
79
+ } from "./chunk-OQ33BKR3.js";
80
+ import {
81
+ classifyProjectPreload
82
+ } from "./chunk-JVCV3ICN.js";
78
83
  import {
79
84
  resolvePackageRoot
80
85
  } from "./chunk-IWHMRKLL.js";
@@ -86,12 +91,6 @@ import {
86
91
  // src/domains/context/index.ts
87
92
  init_esm_shims();
88
93
 
89
- // src/domains/context/extension.ts
90
- init_esm_shims();
91
- import { createHash as createHash2 } from "node:crypto";
92
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
93
- import { isAbsolute, relative as relative3 } from "node:path";
94
-
95
94
  // src/domains/context/adoption.ts
96
95
  init_esm_shims();
97
96
  import { createHash } from "node:crypto";
@@ -159,7 +158,7 @@ var SECRET_LINE_PATTERNS = [
159
158
  /\bxox[baprs]-[A-Za-z0-9-]{20,}\b/,
160
159
  /\bAIza[0-9A-Za-z_-]{20,}\b/
161
160
  ];
162
- function sha256(text) {
161
+ function sha2562(text) {
163
162
  return createHash("sha256").update(text).digest("hex");
164
163
  }
165
164
  function normalizeText(text) {
@@ -236,8 +235,8 @@ function discoverCandidateSpecs(cwd, home, includeGlobal) {
236
235
  const specs = [];
237
236
  const seen = /* @__PURE__ */ new Set();
238
237
  let order = 0;
239
- const add = (path, scope, provider, kind) => {
240
- const abs = resolve(path);
238
+ const add = (path2, scope, provider, kind) => {
239
+ const abs = resolve(path2);
241
240
  if (seen.has(abs)) return;
242
241
  seen.add(abs);
243
242
  const scopedDir = scope === "project" && kind === "instructions" ? relative(cwd, dirname(abs)) : "";
@@ -509,7 +508,7 @@ function rejectedCandidate(spec, displayPath2, reason, evidence) {
509
508
  kind: spec.kind,
510
509
  ...spec.directoryScope ? { directoryScope: spec.directoryScope } : {},
511
510
  reason,
512
- fingerprintSha256: sha256(`rejected\0${reason}\0${evidence}`)
511
+ fingerprintSha256: sha2562(`rejected\0${reason}\0${evidence}`)
513
512
  };
514
513
  }
515
514
  function statEvidence(stat) {
@@ -558,7 +557,7 @@ function readCandidate(spec, cwd, home) {
558
557
  kindLabel: KIND_LABELS[spec.kind],
559
558
  ...spec.directoryScope ? { directoryScope: spec.directoryScope } : {},
560
559
  content,
561
- contentSha256: sha256(content),
560
+ contentSha256: sha2562(content),
562
561
  byteLength: Buffer.byteLength(content, "utf8"),
563
562
  itemCount: rules.length,
564
563
  order: spec.order
@@ -622,7 +621,7 @@ function scanAgentConfigs(options) {
622
621
  kind: result.kind,
623
622
  ...result.directoryScope ? { directoryScope: result.directoryScope } : {},
624
623
  reason: "aggregate source byte budget exceeded",
625
- fingerprintSha256: sha256(`rejected\0aggregate source byte budget exceeded\0${result.contentSha256}`)
624
+ fingerprintSha256: sha2562(`rejected\0aggregate source byte budget exceeded\0${result.contentSha256}`)
626
625
  });
627
626
  continue;
628
627
  }
@@ -648,8 +647,8 @@ function scanAgentConfigs(options) {
648
647
  };
649
648
  }
650
649
  function renderSourceList(paths) {
651
- if (paths.length <= 3) return paths.map((path) => `\`${path}\``).join(", ");
652
- return `${paths.slice(0, 3).map((path) => `\`${path}\``).join(", ")} +${paths.length - 3} more`;
650
+ if (paths.length <= 3) return paths.map((path2) => `\`${path2}\``).join(", ");
651
+ return `${paths.slice(0, 3).map((path2) => `\`${path2}\``).join(", ")} +${paths.length - 3} more`;
653
652
  }
654
653
  function quoteShort(text) {
655
654
  const cleaned = text.replace(/\s+/g, " ").trim();
@@ -756,12 +755,12 @@ function adoptionSourcesChanged(snapshots, options = {}) {
756
755
  init_esm_shims();
757
756
  import { execFileSync } from "node:child_process";
758
757
  import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync4, writeFileSync } from "node:fs";
759
- import { dirname as dirname2, join as join4, parse } from "node:path";
758
+ import { dirname as dirname3, join as join4, parse } from "node:path";
760
759
 
761
760
  // src/domains/context/clio-md.ts
762
761
  init_esm_shims();
763
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
764
- import { join as join2 } from "node:path";
762
+ import { existsSync as existsSync2, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
763
+ import { basename as basename2, dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
765
764
  var FOOTER_RE = /<!--\s*clio:fingerprint v1\s*\n([\s\S]*?)\n\s*-->/;
766
765
  var H1_RE = /^#\s+(.+?)\s*$/gm;
767
766
  var H2_RE = /^##\s+(.+?)\s*$/gm;
@@ -973,7 +972,10 @@ function serializeClioMd(input) {
973
972
  function renderProjectTypeFragment(projectType) {
974
973
  return `<project-type>${projectType}</project-type>`;
975
974
  }
976
- function renderProjectContextFragment(parsed) {
975
+ function escapeXmlAttribute(value) {
976
+ return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
977
+ }
978
+ function renderProjectContextFragment(parsed, sourcePath) {
977
979
  const sections = [`# ${parsed.projectName}`, parsed.identity];
978
980
  if (parsed.conventions.length > 0) {
979
981
  sections.push("## Conventions", ...parsed.conventions.map((item) => `- ${item}`));
@@ -987,24 +989,82 @@ function renderProjectContextFragment(parsed) {
987
989
  if (parsed.importedAgentContext) {
988
990
  sections.push("## Imported agent context", parsed.importedAgentContext);
989
991
  }
990
- return `<project-context>
992
+ const source = sourcePath ? ` path="${escapeXmlAttribute(sourcePath)}"` : "";
993
+ return `<project-context${source}>
991
994
  ${sections.join("\n\n")}
992
995
  </project-context>`;
993
996
  }
994
- function tryReadClioMd(cwd) {
995
- const filePath = join2(cwd, "CLIO-CODER.md");
996
- if (!existsSync2(filePath)) return null;
997
+ var PROJECT_CONTEXT_CANDIDATES = ["CLIO-CODER.override.md", "CLIO-CODER.md"];
998
+ function selectedClioMdPath(directory) {
999
+ for (const filename of PROJECT_CONTEXT_CANDIDATES) {
1000
+ const filePath = join2(directory, filename);
1001
+ if (!existsSync2(filePath)) continue;
1002
+ try {
1003
+ if (statSync2(filePath).isFile()) return filePath;
1004
+ } catch {
1005
+ return filePath;
1006
+ }
1007
+ }
1008
+ return null;
1009
+ }
1010
+ function readClioMdPath(filePath) {
997
1011
  let content;
998
1012
  try {
999
1013
  content = readFileSync2(filePath, "utf8");
1000
1014
  } catch (err) {
1001
- const message = err instanceof Error ? err.message : String(err);
1002
- return { ok: false, error: message };
1015
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
1003
1016
  }
1004
1017
  const parsed = parseClioMd(content);
1005
1018
  if (!parsed.ok) return { ok: false, error: parsed.errors.join("; ") };
1006
1019
  return { ok: true, value: parsed.value };
1007
1020
  }
1021
+ function mergeClioMdFiles(files) {
1022
+ const nearest = files.at(-1)?.value;
1023
+ if (!nearest) return null;
1024
+ return {
1025
+ projectName: nearest.projectName,
1026
+ identity: files.map((file) => file.value.identity).join("\n\n"),
1027
+ conventions: files.flatMap((file) => file.value.conventions),
1028
+ invariants: files.flatMap((file) => file.value.invariants),
1029
+ sections: files.flatMap((file) => file.value.sections),
1030
+ importedAgentContext: files.map((file) => file.value.importedAgentContext).filter((value) => value !== null).join("\n\n") || null,
1031
+ fingerprint: nearest.fingerprint,
1032
+ firstInit: nearest.firstInit,
1033
+ warnings: files.flatMap((file) => file.value.warnings)
1034
+ };
1035
+ }
1036
+ function loadProjectClioMd(cwd) {
1037
+ const directories = [];
1038
+ let directory = resolve2(cwd);
1039
+ while (true) {
1040
+ directories.unshift(directory);
1041
+ const parent = dirname2(directory);
1042
+ if (parent === directory) break;
1043
+ directory = parent;
1044
+ }
1045
+ const selectedPaths = [];
1046
+ for (const current of directories) {
1047
+ const selected = selectedClioMdPath(current);
1048
+ if (!selected) continue;
1049
+ if (basename2(selected) === "CLIO-CODER.override.md") {
1050
+ selectedPaths.length = 0;
1051
+ }
1052
+ selectedPaths.push(selected);
1053
+ }
1054
+ const files = [];
1055
+ const errors = [];
1056
+ for (const filePath of selectedPaths) {
1057
+ const read = readClioMdPath(filePath);
1058
+ if (read.ok) files.push({ path: filePath, value: read.value });
1059
+ else errors.push({ path: filePath, error: read.error });
1060
+ }
1061
+ return { files, errors, value: mergeClioMdFiles(files) };
1062
+ }
1063
+ function tryReadClioMd(cwd) {
1064
+ const filePath = join2(cwd, "CLIO-CODER.md");
1065
+ if (!existsSync2(filePath)) return null;
1066
+ return readClioMdPath(filePath);
1067
+ }
1008
1068
 
1009
1069
  // src/domains/context/project-metadata.ts
1010
1070
  init_esm_shims();
@@ -1062,6 +1122,14 @@ function tomlTableValue(raw, table, key) {
1062
1122
  }
1063
1123
  return null;
1064
1124
  }
1125
+ function hasTomlTable(raw, table) {
1126
+ const header = `[${table}]`;
1127
+ return raw.split(/\r?\n/u).some((line) => {
1128
+ const trimmed = line.trim();
1129
+ if (!trimmed.startsWith(header)) return false;
1130
+ return /^\s*(?:#.*)?$/u.test(trimmed.slice(header.length));
1131
+ });
1132
+ }
1065
1133
  function keyEqualsValue(raw, key) {
1066
1134
  const match = new RegExp(`^[ \\t]*${key}[ \\t]*(?:\\+?=)[ \\t]*(.+)$`, "mu").exec(raw);
1067
1135
  const value = match?.[1]?.trim();
@@ -1354,13 +1422,12 @@ function renderPromptContext(cwd) {
1354
1422
  const projectType = detectProjectType(cwd);
1355
1423
  const pieces = [renderProjectTypeFragment(projectType)];
1356
1424
  const warnings = [];
1357
- const clio = tryReadClioMd(cwd);
1358
- let clioMd = null;
1359
- if (clio?.ok) {
1360
- clioMd = clio.value;
1361
- pieces.push(renderProjectContextFragment(clio.value));
1425
+ const loadedClioMd = loadProjectClioMd(cwd);
1426
+ const clioMd = loadedClioMd.value;
1427
+ for (const file of loadedClioMd.files) pieces.push(renderProjectContextFragment(file.value, file.path));
1428
+ for (const issue of loadedClioMd.errors) {
1429
+ warnings.push(`clio: malformed ${issue.path} ignored: ${issue.error}`);
1362
1430
  }
1363
- if (clio && !clio.ok) warnings.push(`clio: malformed CLIO-CODER.md ignored: ${clio.error}`);
1364
1431
  const codewiki = readCodewiki(cwd);
1365
1432
  if (codewiki) {
1366
1433
  const state = readClioState(cwd);
@@ -1382,7 +1449,7 @@ function renderPromptContext(cwd) {
1382
1449
  const suffix = notes.length > 0 ? ` (${notes.join("; ")}; run clio-coder context wiki --update)` : "";
1383
1450
  pieces.push(`<wiki>${pages.length} pages at .clio-coder/wiki (start: quickstart.md)${suffix}</wiki>`);
1384
1451
  }
1385
- return { text: pieces.join("\n\n"), clioMd, warnings };
1452
+ return { text: pieces.join("\n\n"), clioMd, warnings, handbookFiles: loadedClioMd.files.map((file) => file.path) };
1386
1453
  }
1387
1454
 
1388
1455
  // src/domains/context/bootstrap.ts
@@ -1597,6 +1664,44 @@ function packageManager(cwd) {
1597
1664
  return "npm";
1598
1665
  }
1599
1666
  var MUTATING_SCRIPT_RE = /(?:^|\s)--(?:fix|write)(?:\s|$)/;
1667
+ function cmakePresetName(presets, key) {
1668
+ if (typeof presets !== "object" || presets === null || Array.isArray(presets)) return null;
1669
+ const list = presets[key];
1670
+ if (!Array.isArray(list)) return null;
1671
+ for (const entry of list) {
1672
+ if (entry?.hidden === true) continue;
1673
+ const name2 = stringField2(entry, "name");
1674
+ if (name2 !== null) return name2;
1675
+ }
1676
+ return null;
1677
+ }
1678
+ function cmakeVerificationLines(cwd) {
1679
+ const presets = readJsonFile(join4(cwd, "CMakePresets.json"));
1680
+ if (presets === null) return [];
1681
+ const configure = cmakePresetName(presets, "configurePresets");
1682
+ const build = cmakePresetName(presets, "buildPresets");
1683
+ const test = cmakePresetName(presets, "testPresets");
1684
+ const lines = [];
1685
+ if (configure !== null) lines.push(`Configure with \`cmake --preset ${configure}\`.`);
1686
+ if (build !== null) lines.push(`Build with \`cmake --build --preset ${build}\`.`);
1687
+ if (test !== null) lines.push(`Run tests with \`ctest --preset ${test}\`.`);
1688
+ return lines;
1689
+ }
1690
+ function pythonVerificationLines(cwd) {
1691
+ let pyproject = "";
1692
+ try {
1693
+ pyproject = readFileSync4(join4(cwd, "pyproject.toml"), "utf8");
1694
+ } catch {
1695
+ pyproject = "";
1696
+ }
1697
+ if (existsSync4(join4(cwd, "tox.ini")) || hasTomlTable(pyproject, "tool.tox")) {
1698
+ return ["Run `tox` before handoff."];
1699
+ }
1700
+ if (existsSync4(join4(cwd, "pytest.ini")) || hasTomlTable(pyproject, "tool.pytest.ini_options")) {
1701
+ return ["Run `pytest` before handoff."];
1702
+ }
1703
+ return [];
1704
+ }
1600
1705
  function verificationSection(cwd) {
1601
1706
  const scripts = packageScripts(cwd);
1602
1707
  const pm = packageManager(cwd);
@@ -1624,6 +1729,14 @@ function verificationSection(cwd) {
1624
1729
  if (hasScript("ci")) {
1625
1730
  lines.push(`Use ${command("ci")} for the full local gate before committing broad or shared behavior changes.`);
1626
1731
  }
1732
+ lines.push(...cmakeVerificationLines(cwd));
1733
+ if (existsSync4(join4(cwd, "Cargo.toml"))) {
1734
+ lines.push("Run `cargo build` and `cargo test` before handoff.");
1735
+ }
1736
+ if (existsSync4(join4(cwd, "go.mod"))) {
1737
+ lines.push("Run `go build ./...` and `go test ./...` before handoff.");
1738
+ }
1739
+ lines.push(...pythonVerificationLines(cwd));
1627
1740
  if (lines.length === 0) return null;
1628
1741
  return { title: "Verification expectations", body: lines.join(" ") };
1629
1742
  }
@@ -1751,12 +1864,10 @@ function stabilizeGeneratedOutput(input, base, onModelSectionRetained, groundMod
1751
1864
  function codewikiSections(codewiki) {
1752
1865
  const sections = [];
1753
1866
  const entryPoints = codewikiEntryPoints(codewiki, 8);
1754
- const indexedCount = indexedSourceFileCount(codewiki);
1755
1867
  if (entryPoints.length > 0) {
1756
1868
  sections.push({
1757
1869
  title: "Context retrieval",
1758
1870
  body: [
1759
- `The codewiki currently indexes ${indexedCount} source file${indexedCount === 1 ? "" : "s"}.`,
1760
1871
  `Start orientation with these indexed entry points: ${entryPoints.map((entry) => `\`${entry}\``).join(", ")}.`,
1761
1872
  "Use `code_nav` (modes: symbol, path, entries, outline, deps, dependents, wiki) before broad reads when the task is navigational."
1762
1873
  ].join(" ")
@@ -1852,7 +1963,7 @@ function countStatusLines(status) {
1852
1963
  return status.split("\n").map((line) => line.trim()).filter(Boolean).length;
1853
1964
  }
1854
1965
  function basenameList(paths) {
1855
- const names = paths.map((path) => parse(path).base).sort((a, b) => a.localeCompare(b));
1966
+ const names = paths.map((path2) => parse(path2).base).sort((a, b) => a.localeCompare(b));
1856
1967
  if (names.length === 0) return "";
1857
1968
  if (names.length <= 3) return names.join(", ");
1858
1969
  return `${names.slice(0, 3).join(", ")} +${names.length - 3}`;
@@ -1974,7 +2085,7 @@ function serializeBootstrapOutput(output) {
1974
2085
  }
1975
2086
  function writeClioMdFile(cwd, output) {
1976
2087
  const clioMdPath = join4(cwd, "CLIO-CODER.md");
1977
- mkdirSync(dirname2(clioMdPath), { recursive: true });
2088
+ mkdirSync(dirname3(clioMdPath), { recursive: true });
1978
2089
  const serialized = serializeBootstrapOutput(output);
1979
2090
  const parsed = parseClioMd(serialized);
1980
2091
  if (!parsed.ok) throw new Error(`bootstrap produced invalid CLIO-CODER.md: ${parsed.errors.join("; ")}`);
@@ -2032,8 +2143,7 @@ function durableGenerationTelemetry(telemetry) {
2032
2143
  }
2033
2144
  return state;
2034
2145
  }
2035
- function writeProjectState(cwd, projectType, now, indexedAt, adoption, recordAdoption, codewikiVersion, generation, generated) {
2036
- const finalFingerprint = computeFingerprint(cwd);
2146
+ function writeProjectState(cwd, projectType, now, indexedAt, adoption, recordAdoption, codewikiVersion, fingerprint, generation, generated) {
2037
2147
  const statePath2 = statePath(cwd);
2038
2148
  const prev = readClioState(cwd);
2039
2149
  const lastBootstrap = generated ? durableGenerationTelemetry(generation) : prev?.lastBootstrap ?? durableGenerationTelemetry(generation);
@@ -2042,7 +2152,7 @@ function writeProjectState(cwd, projectType, now, indexedAt, adoption, recordAdo
2042
2152
  writeClioState(cwd, {
2043
2153
  version: 1,
2044
2154
  projectType,
2045
- fingerprint: finalFingerprint,
2155
+ fingerprint,
2046
2156
  codewikiVersion,
2047
2157
  lastInitAt: now.toISOString(),
2048
2158
  lastSessionAt: now.toISOString(),
@@ -2053,13 +2163,12 @@ function writeProjectState(cwd, projectType, now, indexedAt, adoption, recordAdo
2053
2163
  });
2054
2164
  return statePath2;
2055
2165
  }
2056
- function persistCodewikiForGeneration(cwd, projectType, indexedAt, codewiki) {
2057
- writeCodewiki(cwd, codewiki);
2166
+ function persistCodewikiForGeneration(cwd, projectType, indexedAt, codewiki, fingerprint) {
2058
2167
  const prev = readClioState(cwd);
2059
2168
  writeClioState(cwd, {
2060
2169
  version: 1,
2061
2170
  projectType,
2062
- fingerprint: computeFingerprint(cwd, codewiki),
2171
+ fingerprint,
2063
2172
  codewikiVersion: codewiki.version,
2064
2173
  ...prev?.contextSources ? { contextSources: prev.contextSources } : {},
2065
2174
  ...prev?.contextSourceHash ? { contextSourceHash: prev.contextSourceHash } : {},
@@ -2096,7 +2205,7 @@ function codewikiEntryPoints(codewiki, limit = 6) {
2096
2205
  if (!("toFileId" in edge)) continue;
2097
2206
  inDegree.set(edge.toFileId, (inDegree.get(edge.toFileId) ?? 0) + 1);
2098
2207
  }
2099
- const ranked = [...inDegree.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([fileId]) => fileById.get(fileId)?.path).filter((path) => typeof path === "string").filter((path) => !tagged.includes(path));
2208
+ const ranked = [...inDegree.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([fileId]) => fileById.get(fileId)?.path).filter((path2) => typeof path2 === "string").filter((path2) => !tagged.includes(path2));
2100
2209
  return [...tagged, ...ranked].slice(0, limit);
2101
2210
  }
2102
2211
  async function runBootstrap(input = {}) {
@@ -2124,7 +2233,21 @@ async function runBootstrap(input = {}) {
2124
2233
  const now = input.now?.() ?? /* @__PURE__ */ new Date();
2125
2234
  const indexedAt = now.toISOString();
2126
2235
  progress(input, { phase: "codewiki", status: "started", message: "building codewiki index" });
2127
- const codewiki = await buildCodewiki({ cwd, language: projectType, generatedAt: indexedAt });
2236
+ let codewiki;
2237
+ let codewikiFingerprint;
2238
+ if (input.preview === true) {
2239
+ const candidate = await buildCodewikiCandidate(cwd, projectType);
2240
+ codewiki = candidate.codewiki;
2241
+ codewikiFingerprint = candidate.fingerprint;
2242
+ } else {
2243
+ const coordinated = await coordinateCodewikiWrite(cwd, () => ({ kind: "build", cwd, language: projectType }), {
2244
+ beforeCommit: (_result, workspace) => ensureGitignore(workspace, input),
2245
+ afterCommit: ({ codewiki: committed, fingerprint }, workspace) => persistCodewikiForGeneration(workspace, projectType, indexedAt, committed, fingerprint)
2246
+ });
2247
+ if (!coordinated) throw new Error("codewiki bootstrap transaction did not commit");
2248
+ codewiki = coordinated.codewiki;
2249
+ codewikiFingerprint = coordinated.worker.fingerprint;
2250
+ }
2128
2251
  const codewikiEntryCount = indexedSourceFileCount(codewiki);
2129
2252
  progress(input, {
2130
2253
  phase: "codewiki",
@@ -2133,10 +2256,6 @@ async function runBootstrap(input = {}) {
2133
2256
  current: codewikiEntryCount,
2134
2257
  total: codewikiEntryCount
2135
2258
  });
2136
- if (input.preview !== true) {
2137
- await ensureGitignore(cwd, input);
2138
- persistCodewikiForGeneration(cwd, projectType, indexedAt, codewiki);
2139
- }
2140
2259
  const hadClioMd = existsSync4(join4(cwd, "CLIO-CODER.md"));
2141
2260
  const useExistingClioMdAsSource = hadClioMd && input.rewriteClioMd !== true;
2142
2261
  const existingClioMdText = useExistingClioMdAsSource ? readExistingClioMdText(cwd) : null;
@@ -2282,6 +2401,7 @@ async function runBootstrap(input = {}) {
2282
2401
  adoption,
2283
2402
  adoptionApplied,
2284
2403
  codewiki.version,
2404
+ codewikiFingerprint,
2285
2405
  generation,
2286
2406
  shouldGenerate
2287
2407
  );
@@ -2341,6 +2461,7 @@ var ACCUMULATED_CONTEXT_PATHS = [
2341
2461
  ];
2342
2462
  var PRESERVED_CONTEXT_PATHS = [
2343
2463
  "CLIO-CODER.md",
2464
+ "CLIO-CODER.override.md",
2344
2465
  ".clio-coder/agents",
2345
2466
  ".clio-coder/skills",
2346
2467
  ".clio-coder/wiki"
@@ -2364,17 +2485,20 @@ async function runContextClear(input = {}) {
2364
2485
  out2(input.io, "clio-coder context reset cancelled; no files removed.\n");
2365
2486
  return { action: "cancelled", removed: [], preserved: [...PRESERVED_CONTEXT_PATHS] };
2366
2487
  }
2367
- const removed = [];
2368
- for (const relPath of ACCUMULATED_CONTEXT_PATHS) removeIfPresent(cwd, relPath, removed);
2369
- const preserved = [...PRESERVED_CONTEXT_PATHS];
2370
- if (input.all === true) {
2371
- const confirmedAll = await input.confirmAll?.();
2372
- if (confirmedAll === true) {
2373
- removeIfPresent(cwd, "CLIO-CODER.md", removed);
2374
- const index = preserved.indexOf("CLIO-CODER.md");
2375
- if (index !== -1) preserved.splice(index, 1);
2488
+ const { removed, preserved } = await coordinateCodewikiExclusive(cwd, async (workspace) => {
2489
+ const removed2 = [];
2490
+ for (const relPath of ACCUMULATED_CONTEXT_PATHS) removeIfPresent(workspace, relPath, removed2);
2491
+ const preserved2 = [...PRESERVED_CONTEXT_PATHS];
2492
+ if (input.all === true) {
2493
+ const confirmedAll = await input.confirmAll?.();
2494
+ if (confirmedAll === true) {
2495
+ removeIfPresent(workspace, "CLIO-CODER.md", removed2);
2496
+ const index = preserved2.indexOf("CLIO-CODER.md");
2497
+ if (index !== -1) preserved2.splice(index, 1);
2498
+ }
2376
2499
  }
2377
- }
2500
+ return { removed: removed2, preserved: preserved2 };
2501
+ });
2378
2502
  out2(
2379
2503
  input.io,
2380
2504
  [
@@ -2386,130 +2510,378 @@ async function runContextClear(input = {}) {
2386
2510
  return { action: "cleared", removed, preserved };
2387
2511
  }
2388
2512
 
2389
- // src/domains/context/refresh.ts
2390
- init_esm_shims();
2391
- import { writeFileSync as writeFileSync3 } from "node:fs";
2392
- import { join as join8 } from "node:path";
2393
-
2394
- // src/domains/context/wiki/generate.ts
2395
- init_esm_shims();
2396
- import {
2397
- closeSync,
2398
- copyFileSync,
2399
- existsSync as existsSync6,
2400
- mkdirSync as mkdirSync3,
2401
- mkdtempSync,
2402
- openSync,
2403
- readdirSync as readdirSync3,
2404
- readFileSync as readFileSync6,
2405
- renameSync,
2406
- rmSync as rmSync3,
2407
- statSync as statSync2,
2408
- writeSync
2409
- } from "node:fs";
2410
- import { dirname as dirname4, join as join7 } from "node:path";
2411
-
2412
- // src/domains/context/wiki/assemble.ts
2513
+ // src/domains/context/operator-profile.ts
2413
2514
  init_esm_shims();
2414
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
2415
- import { basename as basename2, dirname as dirname3, join as join6, normalize, posix, relative as relative2 } from "node:path";
2416
- var SOURCE_CITATION = /`((?:src|tests?|scripts|benchmarks|docs|packages|apps|lib|config|\.github)\/[^`\s:#]+)(?::(\d+)(?:-\d+)?)?(?::[A-Za-z_$][\w$.-]*)?`/g;
2417
- var INTERNAL_LINK = /\[[^\]]*\]\((?![a-z][a-z\d+.-]*:|\/\/|#)([^)\s]+\.md)(?:#[^)\s]*)?\)/gi;
2418
- var REPAIR_NOTE = /^<!-- clio:wiki .*-->$/gm;
2419
- function readText2(filePath) {
2420
- try {
2421
- return readFileSync5(filePath, "utf8");
2422
- } catch {
2423
- return "";
2424
- }
2425
- }
2426
- function writeText(filePath, text) {
2427
- mkdirSync2(dirname3(filePath), { recursive: true });
2428
- writeFileSync2(filePath, text, "utf8");
2515
+ var import_yaml2 = __toESM(require_dist(), 1);
2516
+ import { createHash as createHash2 } from "node:crypto";
2517
+ import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
2518
+ import { join as join6 } from "node:path";
2519
+ var RESPONSE_POSTURES = ["concise", "balanced", "thorough"];
2520
+ var VALIDATION_PREFERENCES = ["tests-first", "manual", "trust"];
2521
+ var COMMIT_MESSAGE_STYLES = ["conventional", "descriptive", "terse"];
2522
+ var OPERATOR_PROFILE_MAX_CHARS = 700;
2523
+ var OPERATOR_PROFILE_MAX_LOCAL_PATHS = 8;
2524
+ function isRecord2(value) {
2525
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2429
2526
  }
2430
- function stripRepairNotes(body) {
2431
- return body.replace(REPAIR_NOTE, "").replace(/\n{3,}/g, "\n\n");
2527
+ function readEnum(value, allowed, field, issues) {
2528
+ if (value === void 0) return void 0;
2529
+ if (typeof value === "string" && allowed.includes(value)) return value;
2530
+ issues.push(`${field} must be one of ${allowed.join(", ")}`);
2531
+ return void 0;
2432
2532
  }
2433
- function renderRepairNote(issues) {
2434
- const links = issues.filter((issue) => issue.kind === "link").map((issue) => issue.reference);
2435
- const citations = issues.filter((issue) => issue.kind === "citation").map((issue) => issue.reference);
2436
- const parts = [];
2437
- if (links.length > 0) parts.push(`unresolved links: ${[...new Set(links)].join(", ")}`);
2438
- if (citations.length > 0) parts.push(`unresolved sources: ${[...new Set(citations)].join(", ")}`);
2439
- return parts.length === 0 ? "" : `
2440
- <!-- clio:wiki ${parts.join("; ")} -->
2441
- `;
2533
+ function readProfileBlob(value, issues) {
2534
+ if (!isRecord2(value)) {
2535
+ if (value !== null && value !== void 0) issues.push("profile must be a mapping at the root");
2536
+ return {};
2537
+ }
2538
+ const profile = {};
2539
+ const posture = readEnum(value.responsePosture, RESPONSE_POSTURES, "responsePosture", issues);
2540
+ if (posture) profile.responsePosture = posture;
2541
+ const validation = readEnum(value.validationPreference, VALIDATION_PREFERENCES, "validationPreference", issues);
2542
+ if (validation) profile.validationPreference = validation;
2543
+ const commit = readEnum(value.commitMessageStyle, COMMIT_MESSAGE_STYLES, "commitMessageStyle", issues);
2544
+ if (commit) profile.commitMessageStyle = commit;
2545
+ if (value.localOnlyPaths !== void 0) {
2546
+ if (Array.isArray(value.localOnlyPaths)) {
2547
+ const paths = value.localOnlyPaths.filter((item) => typeof item === "string" && item.length > 0);
2548
+ if (paths.length > 0) profile.localOnlyPaths = paths.slice(0, OPERATOR_PROFILE_MAX_LOCAL_PATHS);
2549
+ } else {
2550
+ issues.push("localOnlyPaths must be an array of strings");
2551
+ }
2552
+ }
2553
+ return profile;
2442
2554
  }
2443
- function repairPage(dir, sourceRoot, relPath, knownPages) {
2444
- const filePath = join6(dir, relPath);
2445
- const original = readText2(filePath);
2446
- const parsed = readWikiPage({ pagePath: relPath, content: original, sourceRoot });
2447
- const body = stripRepairNotes(parsed.body);
2448
- if (body.replace(/^#.*$/gm, "").trim().length === 0) {
2449
- return { metadata: parsed.metadata, changed: false, issues: [], empty: true };
2555
+ function readProfileFile(path2, issues) {
2556
+ if (!existsSync6(path2)) return { profile: {}, present: false };
2557
+ try {
2558
+ return { profile: readProfileBlob((0, import_yaml2.parse)(readFileSync5(path2, "utf8")), issues), present: true };
2559
+ } catch (err) {
2560
+ issues.push(`${path2}: invalid YAML: ${err instanceof Error ? err.message : String(err)}`);
2561
+ return { profile: {}, present: false };
2450
2562
  }
2563
+ }
2564
+ function loadOperatorProfile(cwd, options = {}) {
2451
2565
  const issues = [];
2452
- for (const cited of parsed.unresolvedPaths) {
2453
- issues.push({ page: relPath, kind: "citation", reference: cited });
2454
- }
2455
- for (const match of body.matchAll(SOURCE_CITATION)) {
2456
- const cited = match[1] ?? "";
2457
- if (resolveSourcePath(sourceRoot, cited) === null) {
2458
- issues.push({ page: relPath, kind: "citation", reference: cited });
2459
- }
2566
+ const userPath = options.userPath ?? join6(resolveClioDirs().config, "profile.yaml");
2567
+ const projectPath = join6(cwd, ".clio-coder", "profile.yaml");
2568
+ const user = readProfileFile(userPath, issues);
2569
+ const project = readProfileFile(projectPath, issues);
2570
+ const profile = { ...user.profile, ...project.profile };
2571
+ let origin = "none";
2572
+ let sourcePath;
2573
+ if (project.present) {
2574
+ origin = "project";
2575
+ sourcePath = projectPath;
2576
+ } else if (user.present) {
2577
+ origin = "user";
2578
+ sourcePath = userPath;
2460
2579
  }
2461
- for (const match of body.matchAll(INTERNAL_LINK)) {
2462
- const href = match[1] ?? "";
2463
- const target = posix.normalize(posix.join(posix.dirname(relPath), href));
2464
- if (target.startsWith("..") || !knownPages.has(target)) {
2465
- issues.push({ page: relPath, kind: "link", reference: href });
2466
- }
2580
+ const result = { profile, origin, issues };
2581
+ if (sourcePath !== void 0) {
2582
+ result.sourcePath = sourcePath;
2583
+ result.hash = createHash2("sha256").update(JSON.stringify(profile)).digest("hex").slice(0, 16);
2467
2584
  }
2468
- const rebuilt = `${renderWikiPage(parsed.metadata, body).trimEnd()}
2469
- ${renderRepairNote(issues)}`;
2470
- if (rebuilt !== original) writeText(filePath, rebuilt);
2471
- return { metadata: parsed.metadata, changed: rebuilt !== original, issues, empty: false };
2585
+ return result;
2472
2586
  }
2473
- function linkTo(fromDir, target) {
2474
- const href = posix.relative(fromDir === "." ? "" : fromDir, target);
2475
- return href.length > 0 ? href : posix.basename(target);
2587
+ function renderOperatorProfile(profile) {
2588
+ const lines = [];
2589
+ if (profile.responsePosture) lines.push(`- Response posture: ${profile.responsePosture}.`);
2590
+ if (profile.validationPreference) lines.push(`- Validation preference: ${profile.validationPreference}.`);
2591
+ if (profile.commitMessageStyle) lines.push(`- Commit-message style: ${profile.commitMessageStyle}.`);
2592
+ if (profile.localOnlyPaths && profile.localOnlyPaths.length > 0) {
2593
+ lines.push(`- Keep local-only (do not push or share): ${profile.localOnlyPaths.join(", ")}.`);
2594
+ }
2595
+ if (lines.length === 0) return { text: "", tokenEstimate: 0 };
2596
+ const full = `## Operator profile
2597
+ ${lines.join("\n")}`;
2598
+ const text = full.length > OPERATOR_PROFILE_MAX_CHARS ? `${full.slice(0, OPERATOR_PROFILE_MAX_CHARS - 1)}\u2026` : full;
2599
+ return { text, tokenEstimate: ceilChars(text.length) };
2476
2600
  }
2477
- function escapeCell(value) {
2478
- return value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
2601
+
2602
+ // src/domains/context/project-rules.ts
2603
+ init_esm_shims();
2604
+ var import_yaml3 = __toESM(require_dist(), 1);
2605
+ import { createHash as createHash3 } from "node:crypto";
2606
+ import { readdirSync as readdirSync3, readFileSync as readFileSync6 } from "node:fs";
2607
+ import { join as join7, relative as relative2, sep as sep2 } from "node:path";
2608
+ var FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n?/;
2609
+ function isRecord3(value) {
2610
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2479
2611
  }
2480
- function codeList(values, limit) {
2481
- if (values.length === 0) return "\u2014";
2482
- const shown = values.slice(0, limit).map((value) => `\`${escapeCell(value)}\``);
2483
- return values.length > limit ? `${shown.join(", ")}, \u2026` : shown.join(", ");
2612
+ function readStringArray(value) {
2613
+ if (!Array.isArray(value)) return void 0;
2614
+ const out3 = [];
2615
+ for (const item of value) {
2616
+ if (typeof item === "string" && item.length > 0) out3.push(item);
2617
+ }
2618
+ return out3.length > 0 ? out3 : void 0;
2484
2619
  }
2485
- function renderQuickstart(sourceRoot, plan, pages) {
2486
- const content = pages.filter((page) => page.path !== WIKI_QUICKSTART);
2487
- const lines = [`# ${basename2(sourceRoot)} wiki`, ""];
2488
- if (plan.overview.trim().length > 0) lines.push(plan.overview.trim(), "");
2489
- lines.push(
2490
- `This wiki is generated by \`clio-coder context wiki\` from ${content.length} page${content.length === 1 ? "" : "s"}. Each page opens with front matter naming the sources, symbols, and tests it documents.`,
2491
- "",
2492
- "## Pages",
2493
- ""
2494
- );
2495
- let currentSection = null;
2496
- for (const page of content) {
2497
- const section = posix.dirname(page.path);
2498
- if (section !== "." && section !== currentSection) {
2499
- lines.push(`- **${section}/**`);
2500
- currentSection = section;
2501
- }
2502
- const indent = section === "." ? "" : " ";
2503
- const summary = page.metadata.summary.length > 0 ? ` \u2014 ${page.metadata.summary}` : "";
2504
- lines.push(`${indent}- [${page.metadata.title}](${page.path})${summary}`);
2620
+ function validateGlobArray(value, field, id, issues) {
2621
+ const parsed = readStringArray(value);
2622
+ if (parsed === void 0) {
2623
+ issues.push(`${id}: frontmatter ${field} must be a non-empty string array`);
2624
+ return void 0;
2505
2625
  }
2506
- const routable = content.filter(
2507
- (page) => page.metadata.sources.length > 0 || page.metadata.symbols.length > 0 || page.metadata.tests.length > 0
2508
- );
2509
- if (routable.length > 0) {
2510
- lines.push(
2511
- "",
2512
- "## Task routing",
2626
+ for (const pattern of parsed) {
2627
+ try {
2628
+ compileGlobRegex(pattern);
2629
+ } catch (err) {
2630
+ issues.push(
2631
+ `${id}: invalid ${field} glob ${JSON.stringify(pattern)}: ${err instanceof Error ? err.message : String(err)}`
2632
+ );
2633
+ return void 0;
2634
+ }
2635
+ }
2636
+ return parsed;
2637
+ }
2638
+ function walkMarkdown(dir, root, out3) {
2639
+ let entries;
2640
+ try {
2641
+ entries = readdirSync3(dir, { withFileTypes: true });
2642
+ } catch {
2643
+ return;
2644
+ }
2645
+ for (const entry of entries) {
2646
+ const full = join7(dir, entry.name);
2647
+ if (entry.isDirectory()) walkMarkdown(full, root, out3);
2648
+ else if (entry.isFile() && entry.name.endsWith(".md")) out3.push(full);
2649
+ }
2650
+ }
2651
+ function parseRule(filePath, root, issues) {
2652
+ let text;
2653
+ try {
2654
+ text = readFileSync6(filePath, "utf8").replace(/\r\n/g, "\n");
2655
+ } catch (err) {
2656
+ issues.push(`${filePath}: ${err instanceof Error ? err.message : String(err)}`);
2657
+ return { excludes: [] };
2658
+ }
2659
+ const id = relative2(root, filePath).split(sep2).join("/");
2660
+ let body = text;
2661
+ let paths;
2662
+ let excludes = [];
2663
+ let enabled = true;
2664
+ let description2;
2665
+ let invalidFrontmatter = false;
2666
+ const match = FRONTMATTER_RE.exec(text);
2667
+ if (match) {
2668
+ body = text.slice(match[0].length);
2669
+ try {
2670
+ const front = (0, import_yaml3.parse)(match[1] ?? "");
2671
+ if (isRecord3(front)) {
2672
+ if (Object.hasOwn(front, "paths")) {
2673
+ const parsedPaths = validateGlobArray(front.paths, "paths", id, issues);
2674
+ if (parsedPaths === void 0) invalidFrontmatter = true;
2675
+ else paths = parsedPaths;
2676
+ }
2677
+ if (Object.hasOwn(front, "excludes")) {
2678
+ const parsedExcludes = validateGlobArray(front.excludes, "excludes", id, issues);
2679
+ if (parsedExcludes === void 0) invalidFrontmatter = true;
2680
+ else excludes = parsedExcludes;
2681
+ }
2682
+ if (Object.hasOwn(front, "enabled")) {
2683
+ if (typeof front.enabled === "boolean") enabled = front.enabled;
2684
+ else {
2685
+ issues.push(`${id}: frontmatter enabled must be a boolean`);
2686
+ invalidFrontmatter = true;
2687
+ }
2688
+ }
2689
+ if (Object.hasOwn(front, "description")) {
2690
+ if (typeof front.description === "string") description2 = front.description;
2691
+ else {
2692
+ issues.push(`${id}: frontmatter description must be a string`);
2693
+ invalidFrontmatter = true;
2694
+ }
2695
+ }
2696
+ } else if (front !== null && front !== void 0) {
2697
+ issues.push(`${id}: frontmatter must be a mapping`);
2698
+ invalidFrontmatter = true;
2699
+ }
2700
+ } catch (err) {
2701
+ issues.push(`${id}: invalid frontmatter: ${err instanceof Error ? err.message : String(err)}`);
2702
+ invalidFrontmatter = true;
2703
+ }
2704
+ } else if (text.startsWith("---\n")) {
2705
+ issues.push(`${id}: invalid frontmatter: missing closing marker`);
2706
+ invalidFrontmatter = true;
2707
+ }
2708
+ if (invalidFrontmatter) return { excludes: [] };
2709
+ const trimmedBody = body.trim();
2710
+ const hash = createHash3("sha256").update(trimmedBody).digest("hex").slice(0, 16);
2711
+ const rule = {
2712
+ id,
2713
+ sourcePath: join7(".clio-coder", "rules", id),
2714
+ hash,
2715
+ tokenEstimate: ceilChars(trimmedBody.length),
2716
+ enabled,
2717
+ body: trimmedBody
2718
+ };
2719
+ if (paths !== void 0) rule.paths = paths;
2720
+ if (description2 !== void 0) rule.description = description2;
2721
+ return { rule, excludes };
2722
+ }
2723
+ function loadProjectRules(cwd) {
2724
+ const root = join7(cwd, ".clio-coder", "rules");
2725
+ const issues = [];
2726
+ const files = [];
2727
+ walkMarkdown(root, root, files);
2728
+ files.sort();
2729
+ const rules = [];
2730
+ const excludeSet = /* @__PURE__ */ new Set();
2731
+ for (const file of files) {
2732
+ const parsed = parseRule(file, root, issues);
2733
+ if (parsed.rule) rules.push(parsed.rule);
2734
+ for (const glob of parsed.excludes) excludeSet.add(glob);
2735
+ }
2736
+ rules.sort((a, b) => a.id.localeCompare(b.id));
2737
+ return { rules, excludes: [...excludeSet], issues };
2738
+ }
2739
+ function ruleMatchesAnyPath(rule, workingPaths) {
2740
+ for (const pattern of rule.paths ?? []) {
2741
+ let regex;
2742
+ try {
2743
+ regex = compileGlobRegex(pattern);
2744
+ } catch {
2745
+ continue;
2746
+ }
2747
+ for (const path2 of workingPaths) {
2748
+ if (regex.test(normalizeGlobInput(path2))) return true;
2749
+ }
2750
+ }
2751
+ return false;
2752
+ }
2753
+ function selectActiveRules(rules, workingContextPaths) {
2754
+ return rules.filter((rule) => {
2755
+ if (!rule.enabled) return false;
2756
+ if (rule.paths === void 0) return true;
2757
+ return ruleMatchesAnyPath(rule, workingContextPaths);
2758
+ });
2759
+ }
2760
+
2761
+ // src/domains/context/refresh.ts
2762
+ init_esm_shims();
2763
+ import { writeFileSync as writeFileSync3 } from "node:fs";
2764
+ import { join as join10 } from "node:path";
2765
+
2766
+ // src/domains/context/wiki/generate.ts
2767
+ init_esm_shims();
2768
+ import {
2769
+ closeSync,
2770
+ copyFileSync,
2771
+ existsSync as existsSync7,
2772
+ mkdirSync as mkdirSync3,
2773
+ mkdtempSync,
2774
+ openSync,
2775
+ readdirSync as readdirSync4,
2776
+ readFileSync as readFileSync8,
2777
+ renameSync,
2778
+ rmSync as rmSync3,
2779
+ statSync as statSync3,
2780
+ writeSync
2781
+ } from "node:fs";
2782
+ import { dirname as dirname5, join as join9 } from "node:path";
2783
+
2784
+ // src/domains/context/wiki/assemble.ts
2785
+ init_esm_shims();
2786
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync7, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
2787
+ import { basename as basename3, dirname as dirname4, join as join8, normalize, posix, relative as relative3 } from "node:path";
2788
+ var SOURCE_CITATION = /`((?:src|tests?|scripts|benchmarks|docs|packages|apps|lib|config|\.github)\/[^`\s:#]+)(?::(\d+)(?:-\d+)?)?(?::[A-Za-z_$][\w$.-]*)?`/g;
2789
+ var INTERNAL_LINK = /\[[^\]]*\]\((?![a-z][a-z\d+.-]*:|\/\/|#)([^)\s]+\.md)(?:#[^)\s]*)?\)/gi;
2790
+ var REPAIR_NOTE = /^<!-- clio:wiki .*-->$/gm;
2791
+ function readText2(filePath) {
2792
+ try {
2793
+ return readFileSync7(filePath, "utf8");
2794
+ } catch {
2795
+ return "";
2796
+ }
2797
+ }
2798
+ function writeText(filePath, text) {
2799
+ mkdirSync2(dirname4(filePath), { recursive: true });
2800
+ writeFileSync2(filePath, text, "utf8");
2801
+ }
2802
+ function stripRepairNotes(body) {
2803
+ return body.replace(REPAIR_NOTE, "").replace(/\n{3,}/g, "\n\n");
2804
+ }
2805
+ function renderRepairNote(issues) {
2806
+ const links = issues.filter((issue) => issue.kind === "link").map((issue) => issue.reference);
2807
+ const citations = issues.filter((issue) => issue.kind === "citation").map((issue) => issue.reference);
2808
+ const parts = [];
2809
+ if (links.length > 0) parts.push(`unresolved links: ${[...new Set(links)].join(", ")}`);
2810
+ if (citations.length > 0) parts.push(`unresolved sources: ${[...new Set(citations)].join(", ")}`);
2811
+ return parts.length === 0 ? "" : `
2812
+ <!-- clio:wiki ${parts.join("; ")} -->
2813
+ `;
2814
+ }
2815
+ function repairPage(dir, sourceRoot, relPath, knownPages) {
2816
+ const filePath = join8(dir, relPath);
2817
+ const original = readText2(filePath);
2818
+ const parsed = readWikiPage({ pagePath: relPath, content: original, sourceRoot });
2819
+ const body = stripRepairNotes(parsed.body);
2820
+ if (body.replace(/^#.*$/gm, "").trim().length === 0) {
2821
+ return { metadata: parsed.metadata, changed: false, issues: [], empty: true };
2822
+ }
2823
+ const issues = [];
2824
+ for (const cited of parsed.unresolvedPaths) {
2825
+ issues.push({ page: relPath, kind: "citation", reference: cited });
2826
+ }
2827
+ for (const match of body.matchAll(SOURCE_CITATION)) {
2828
+ const cited = match[1] ?? "";
2829
+ if (resolveSourcePath(sourceRoot, cited) === null) {
2830
+ issues.push({ page: relPath, kind: "citation", reference: cited });
2831
+ }
2832
+ }
2833
+ for (const match of body.matchAll(INTERNAL_LINK)) {
2834
+ const href = match[1] ?? "";
2835
+ const target = posix.normalize(posix.join(posix.dirname(relPath), href));
2836
+ if (target.startsWith("..") || !knownPages.has(target)) {
2837
+ issues.push({ page: relPath, kind: "link", reference: href });
2838
+ }
2839
+ }
2840
+ const rebuilt = `${renderWikiPage(parsed.metadata, body).trimEnd()}
2841
+ ${renderRepairNote(issues)}`;
2842
+ if (rebuilt !== original) writeText(filePath, rebuilt);
2843
+ return { metadata: parsed.metadata, changed: rebuilt !== original, issues, empty: false };
2844
+ }
2845
+ function linkTo(fromDir, target) {
2846
+ const href = posix.relative(fromDir === "." ? "" : fromDir, target);
2847
+ return href.length > 0 ? href : posix.basename(target);
2848
+ }
2849
+ function escapeCell(value) {
2850
+ return value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
2851
+ }
2852
+ function codeList(values, limit) {
2853
+ if (values.length === 0) return "\u2014";
2854
+ const shown = values.slice(0, limit).map((value) => `\`${escapeCell(value)}\``);
2855
+ return values.length > limit ? `${shown.join(", ")}, \u2026` : shown.join(", ");
2856
+ }
2857
+ function renderQuickstart(sourceRoot, plan, pages) {
2858
+ const content = pages.filter((page) => page.path !== WIKI_QUICKSTART);
2859
+ const lines = [`# ${basename3(sourceRoot)} wiki`, ""];
2860
+ if (plan.overview.trim().length > 0) lines.push(plan.overview.trim(), "");
2861
+ lines.push(
2862
+ `This wiki is generated by \`clio-coder context wiki\` from ${content.length} page${content.length === 1 ? "" : "s"}. Each page opens with front matter naming the sources, symbols, and tests it documents.`,
2863
+ "",
2864
+ "## Pages",
2865
+ ""
2866
+ );
2867
+ let currentSection = null;
2868
+ for (const page of content) {
2869
+ const section = posix.dirname(page.path);
2870
+ if (section !== "." && section !== currentSection) {
2871
+ lines.push(`- **${section}/**`);
2872
+ currentSection = section;
2873
+ }
2874
+ const indent = section === "." ? "" : " ";
2875
+ const summary = page.metadata.summary.length > 0 ? ` \u2014 ${page.metadata.summary}` : "";
2876
+ lines.push(`${indent}- [${page.metadata.title}](${page.path})${summary}`);
2877
+ }
2878
+ const routable = content.filter(
2879
+ (page) => page.metadata.sources.length > 0 || page.metadata.symbols.length > 0 || page.metadata.tests.length > 0
2880
+ );
2881
+ if (routable.length > 0) {
2882
+ lines.push(
2883
+ "",
2884
+ "## Task routing",
2513
2885
  "",
2514
2886
  "| Area | Page | Sources | Symbols | Tests | Validate |",
2515
2887
  "| --- | --- | --- | --- | --- | --- |"
@@ -2553,7 +2925,7 @@ function assembleWikiTree(input) {
2553
2925
  for (const relPath of authored) {
2554
2926
  const result = repairPage(dir, sourceRoot, relPath, knownPages);
2555
2927
  if (result.empty) {
2556
- rmSync2(join6(dir, relPath), { force: true });
2928
+ rmSync2(join8(dir, relPath), { force: true });
2557
2929
  dropped.push(relPath);
2558
2930
  continue;
2559
2931
  }
@@ -2561,7 +2933,7 @@ function assembleWikiTree(input) {
2561
2933
  issues.push(...result.issues);
2562
2934
  assembled.push({ path: relPath, metadata: result.metadata });
2563
2935
  }
2564
- writeText(join6(dir, WIKI_QUICKSTART), renderQuickstart(sourceRoot, input.plan, assembled));
2936
+ writeText(join8(dir, WIKI_QUICKSTART), renderQuickstart(sourceRoot, input.plan, assembled));
2565
2937
  const directories = /* @__PURE__ */ new Set(["."]);
2566
2938
  for (const page of assembled) {
2567
2939
  let section = posix.dirname(page.path);
@@ -2574,12 +2946,12 @@ function assembleWikiTree(input) {
2574
2946
  const pagesHere = assembled.filter((page) => posix.dirname(page.path) === directory);
2575
2947
  const sectionsHere = [...directories].filter((candidate) => candidate !== "." && posix.dirname(candidate) === directory).sort();
2576
2948
  const indexPath = directory === "." ? WIKI_INDEX : `${directory}/${WIKI_INDEX}`;
2577
- writeText(join6(dir, indexPath), renderIndex(directory, pagesHere, sectionsHere));
2949
+ writeText(join8(dir, indexPath), renderIndex(directory, pagesHere, sectionsHere));
2578
2950
  }
2579
2951
  for (const relPath of wikiMarkdownFilesInDir(dir)) {
2580
2952
  if (!isGeneratedWikiFile(relPath) || relPath === WIKI_QUICKSTART) continue;
2581
2953
  const directory = posix.dirname(relPath);
2582
- if (!directories.has(directory)) rmSync2(join6(dir, relPath), { force: true });
2954
+ if (!directories.has(directory)) rmSync2(join8(dir, relPath), { force: true });
2583
2955
  }
2584
2956
  return { pages: listWikiPagesInDir(dir), repaired, dropped, issues };
2585
2957
  }
@@ -2587,14 +2959,14 @@ function pageSourceIndex(dir, sourceRoot) {
2587
2959
  const index = /* @__PURE__ */ new Map();
2588
2960
  for (const relPath of wikiMarkdownFilesInDir(dir)) {
2589
2961
  if (isGeneratedWikiFile(relPath)) continue;
2590
- const { metadata } = readWikiPage({ pagePath: relPath, content: readText2(join6(dir, relPath)), sourceRoot });
2962
+ const { metadata } = readWikiPage({ pagePath: relPath, content: readText2(join8(dir, relPath)), sourceRoot });
2591
2963
  index.set(relPath, [...metadata.sources, ...metadata.tests]);
2592
2964
  }
2593
2965
  return index;
2594
2966
  }
2595
2967
  function normalizeRepoPath(sourceRoot, candidate) {
2596
- const resolved = normalize(join6(sourceRoot, candidate));
2597
- const rel = relative2(sourceRoot, resolved);
2968
+ const resolved = normalize(join8(sourceRoot, candidate));
2969
+ const rel = relative3(sourceRoot, resolved);
2598
2970
  return rel.split("\\").join("/");
2599
2971
  }
2600
2972
 
@@ -2606,8 +2978,8 @@ var WIKI_DEPTH_STRATEGY = {
2606
2978
  detailed: { areaDepth: 3, areaShare: 8e-3, minAreaLines: 150 }
2607
2979
  };
2608
2980
  var MAX_PAGE_SOURCES = 8;
2609
- function areaForPath(path, maxDepth) {
2610
- const directories = path.split("/").filter(Boolean).slice(0, -1);
2981
+ function areaForPath(path2, maxDepth) {
2982
+ const directories = path2.split("/").filter(Boolean).slice(0, -1);
2611
2983
  if (directories.length === 0) return ".";
2612
2984
  return directories.slice(0, Math.max(1, maxDepth)).join("/");
2613
2985
  }
@@ -2699,14 +3071,14 @@ function dedupePagePaths(plan) {
2699
3071
  const seen = /* @__PURE__ */ new Set();
2700
3072
  const pages = [];
2701
3073
  for (const page of plan.pages) {
2702
- let path = page.path;
3074
+ let path2 = page.path;
2703
3075
  let suffix = 2;
2704
- while (seen.has(path)) {
2705
- path = page.path.replace(/\.md$/, `-${suffix}.md`);
3076
+ while (seen.has(path2)) {
3077
+ path2 = page.path.replace(/\.md$/, `-${suffix}.md`);
2706
3078
  suffix += 1;
2707
3079
  }
2708
- seen.add(path);
2709
- pages.push({ ...page, path });
3080
+ seen.add(path2);
3081
+ pages.push({ ...page, path: path2 });
2710
3082
  }
2711
3083
  return { ...plan, pages };
2712
3084
  }
@@ -2726,29 +3098,38 @@ function indexedSourceFileCount2(codewiki) {
2726
3098
  return codewiki.files.filter((file) => file.lang !== "config").length;
2727
3099
  }
2728
3100
  async function loadOrBuildCodewiki(cwd) {
2729
- const existing = readCodewiki(cwd);
2730
- const prev = readClioState(cwd);
2731
- if (existing && !codewikiNeedsBackfill(existing)) {
2732
- const fingerprint = computeFingerprint(cwd, existing);
2733
- if (prev && !isStale(prev.fingerprint, fingerprint)) return existing;
2734
- }
2735
3101
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
2736
3102
  const projectType = detectProjectType(cwd);
2737
- const rebuilt = await buildCodewiki({ cwd, language: projectType, generatedAt });
2738
- writeCodewiki(cwd, rebuilt);
2739
- writeClioState(cwd, {
2740
- version: 1,
2741
- projectType: prev?.projectType ?? projectType,
2742
- fingerprint: computeFingerprint(cwd, rebuilt),
2743
- codewikiVersion: rebuilt.version,
2744
- ...prev?.contextSources ? { contextSources: prev.contextSources } : {},
2745
- ...prev?.contextSourceHash ? { contextSourceHash: prev.contextSourceHash } : {},
2746
- ...prev?.lastBootstrap ? { lastBootstrap: prev.lastBootstrap } : {},
2747
- ...prev?.lastInitAt ? { lastInitAt: prev.lastInitAt } : {},
2748
- lastSessionAt: prev?.lastSessionAt ?? generatedAt,
2749
- lastIndexedAt: generatedAt
2750
- });
2751
- return rebuilt;
3103
+ const coordinated = await coordinateCodewikiWrite(
3104
+ cwd,
3105
+ (current, workspace) => ({
3106
+ kind: "ensure",
3107
+ cwd: workspace,
3108
+ language: projectType,
3109
+ current,
3110
+ previous: readClioState(workspace)?.fingerprint ?? null
3111
+ }),
3112
+ {
3113
+ afterCommit: ({ codewiki, fingerprint, changed }, workspace) => {
3114
+ const prev = readClioState(workspace);
3115
+ if (!changed && prev) return;
3116
+ writeClioState(workspace, {
3117
+ version: 1,
3118
+ projectType: prev?.projectType ?? projectType,
3119
+ fingerprint,
3120
+ codewikiVersion: codewiki.version,
3121
+ ...prev?.contextSources ? { contextSources: prev.contextSources } : {},
3122
+ ...prev?.contextSourceHash ? { contextSourceHash: prev.contextSourceHash } : {},
3123
+ ...prev?.lastBootstrap ? { lastBootstrap: prev.lastBootstrap } : {},
3124
+ ...prev?.lastInitAt ? { lastInitAt: prev.lastInitAt } : {},
3125
+ lastSessionAt: prev?.lastSessionAt ?? generatedAt,
3126
+ lastIndexedAt: generatedAt
3127
+ });
3128
+ }
3129
+ }
3130
+ );
3131
+ if (!coordinated) throw new Error("codewiki wiki transaction did not commit");
3132
+ return { codewiki: coordinated.codewiki, fingerprint: coordinated.worker.fingerprint };
2752
3133
  }
2753
3134
  function failed(problems, pages) {
2754
3135
  return { status: "failed", pages, problems };
@@ -2757,7 +3138,7 @@ var STAGING_PREFIX = "wiki-staging-";
2757
3138
  var WIKI_PREV_DIR = "wiki-prev";
2758
3139
  var WIKI_LOCK_FILE = "wiki.lock";
2759
3140
  function clioDir(cwd) {
2760
- return join7(cwd, ".clio-coder");
3141
+ return join9(cwd, ".clio-coder");
2761
3142
  }
2762
3143
  function isProcessAlive(pid) {
2763
3144
  try {
@@ -2769,7 +3150,7 @@ function isProcessAlive(pid) {
2769
3150
  }
2770
3151
  function readLockPid(lockPath) {
2771
3152
  try {
2772
- const parsed = Number.parseInt(readFileSync6(lockPath, "utf8").trim(), 10);
3153
+ const parsed = Number.parseInt(readFileSync8(lockPath, "utf8").trim(), 10);
2773
3154
  return Number.isInteger(parsed) && parsed > 0 ? parsed : null;
2774
3155
  } catch {
2775
3156
  return null;
@@ -2778,7 +3159,7 @@ function readLockPid(lockPath) {
2778
3159
  function acquireWikiLock(cwd) {
2779
3160
  const dir = clioDir(cwd);
2780
3161
  mkdirSync3(dir, { recursive: true });
2781
- const lockPath = join7(dir, WIKI_LOCK_FILE);
3162
+ const lockPath = join9(dir, WIKI_LOCK_FILE);
2782
3163
  const release = () => {
2783
3164
  try {
2784
3165
  rmSync3(lockPath, { force: true });
@@ -2828,10 +3209,10 @@ function removeDir(dir) {
2828
3209
  function seedStaging(cwd, stagingDir) {
2829
3210
  const source = wikiDir(cwd);
2830
3211
  for (const relPath of wikiMarkdownFilesInDir(source)) {
2831
- const target = join7(stagingDir, relPath);
2832
- mkdirSync3(dirname4(target), { recursive: true });
3212
+ const target = join9(stagingDir, relPath);
3213
+ mkdirSync3(dirname5(target), { recursive: true });
2833
3214
  try {
2834
- copyFileSync(join7(source, relPath), target);
3215
+ copyFileSync(join9(source, relPath), target);
2835
3216
  } catch {
2836
3217
  }
2837
3218
  }
@@ -2841,29 +3222,29 @@ function adoptOrCreateStaging(cwd) {
2841
3222
  mkdirSync3(dir, { recursive: true });
2842
3223
  let entries;
2843
3224
  try {
2844
- entries = readdirSync3(dir, { withFileTypes: true });
3225
+ entries = readdirSync4(dir, { withFileTypes: true });
2845
3226
  } catch {
2846
3227
  entries = [];
2847
3228
  }
2848
- const candidates = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(STAGING_PREFIX)).map((entry) => join7(dir, entry.name)).sort((a, b) => {
2849
- const at = statSync2(a).mtimeMs;
2850
- const bt = statSync2(b).mtimeMs;
3229
+ const candidates = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(STAGING_PREFIX)).map((entry) => join9(dir, entry.name)).sort((a, b) => {
3230
+ const at = statSync3(a).mtimeMs;
3231
+ const bt = statSync3(b).mtimeMs;
2851
3232
  return bt - at;
2852
3233
  });
2853
- const resumable = candidates.find((candidate) => existsSync6(join7(candidate, WIKI_PLAN_FILE)));
3234
+ const resumable = candidates.find((candidate) => existsSync7(join9(candidate, WIKI_PLAN_FILE)));
2854
3235
  for (const candidate of candidates) {
2855
3236
  if (candidate !== resumable) removeDir(candidate);
2856
3237
  }
2857
3238
  if (resumable !== void 0) return { dir: resumable, adopted: true };
2858
- const fresh = mkdtempSync(join7(dir, STAGING_PREFIX));
3239
+ const fresh = mkdtempSync(join9(dir, STAGING_PREFIX));
2859
3240
  seedStaging(cwd, fresh);
2860
3241
  return { dir: fresh, adopted: false };
2861
3242
  }
2862
3243
  function promoteStaging(cwd, stagingDir, writeMeta) {
2863
3244
  const wiki = wikiDir(cwd);
2864
- const prev = join7(clioDir(cwd), WIKI_PREV_DIR);
3245
+ const prev = join9(clioDir(cwd), WIKI_PREV_DIR);
2865
3246
  removeDir(prev);
2866
- const hadWiki = existsSync6(wiki);
3247
+ const hadWiki = existsSync7(wiki);
2867
3248
  if (hadWiki) renameSync(wiki, prev);
2868
3249
  try {
2869
3250
  renameSync(stagingDir, wiki);
@@ -2891,7 +3272,7 @@ function resolvePlan(input) {
2891
3272
  if (input.mode === "update" && input.previousPlan !== void 0) {
2892
3273
  const pageSources = pageSourceIndex(input.stagingDir, input.cwd);
2893
3274
  const changed = new Set(
2894
- changedPathsSince(input.cwd, input.gitHead).map((path) => normalizeRepoPath(input.cwd, path))
3275
+ changedPathsSince(input.cwd, input.gitHead).map((path2) => normalizeRepoPath(input.cwd, path2))
2895
3276
  );
2896
3277
  return {
2897
3278
  plan: scopePlanForUpdate({
@@ -2940,8 +3321,8 @@ async function runWikiGenerate(input = { model: "configured-clio-target" }) {
2940
3321
  }
2941
3322
  try {
2942
3323
  progress2(input, { phase: "codewiki", status: "started", message: "loading codewiki for wiki generation" });
2943
- const codewiki = await loadOrBuildCodewiki(cwd);
2944
- const sourceTreeHash = computeFingerprint(cwd, codewiki).treeHash;
3324
+ const { codewiki, fingerprint } = await loadOrBuildCodewiki(cwd);
3325
+ const sourceTreeHash = fingerprint.treeHash;
2945
3326
  const generation = planWikiGeneration(codewiki, input.depth ?? "auto");
2946
3327
  progress2(input, {
2947
3328
  phase: "codewiki",
@@ -3015,7 +3396,7 @@ async function runWikiGenerate(input = { model: "configured-clio-target" }) {
3015
3396
  message: `assembled ${report.pages.length} page${report.pages.length === 1 ? "" : "s"}`,
3016
3397
  detail: `${report.repaired} repaired; ${report.issues.length} unresolved reference${report.issues.length === 1 ? "" : "s"}` + (report.dropped.length > 0 ? `; ${report.dropped.length} empty page dropped` : "") + (pendingCount > 0 ? `; ${pendingCount} page${pendingCount === 1 ? "" : "s"} still to write` : "")
3017
3398
  });
3018
- rmSync3(join7(staging.dir, WIKI_PLAN_FILE), { force: true });
3399
+ rmSync3(join9(staging.dir, WIKI_PLAN_FILE), { force: true });
3019
3400
  const afterHash = computeWikiContentHashOfDir(staging.dir);
3020
3401
  const stagedPages = listWikiPagesInDir(staging.dir);
3021
3402
  const problems = report.issues.map((issue) => `${issue.page} has an unresolved ${issue.kind}: ${issue.reference}`);
@@ -3098,7 +3479,7 @@ function curateClioMd(cwd, codewiki) {
3098
3479
  });
3099
3480
  if (!changed) return "unchanged";
3100
3481
  writeFileSync3(
3101
- join8(cwd, "CLIO-CODER.md"),
3482
+ join10(cwd, "CLIO-CODER.md"),
3102
3483
  serializeClioMd({
3103
3484
  projectName: handbook.projectName,
3104
3485
  identity: handbook.identity,
@@ -3133,23 +3514,30 @@ async function runContextRefresh(input = {}) {
3133
3514
  const projectType = prev?.projectType ?? detectProjectType(cwd);
3134
3515
  const indexedAt = now().toISOString();
3135
3516
  input.onProgress?.({ phase: "codewiki", status: "started", message: "rebuilding codewiki" });
3136
- const codewiki = await buildCodewiki({ cwd, language: projectType, generatedAt: indexedAt });
3137
- writeCodewiki(cwd, codewiki);
3138
- const fingerprint = computeFingerprint(cwd, codewiki);
3139
- const clioMd = curateClioMd(cwd, codewiki);
3140
- input.onProgress?.({ phase: "state", status: "running", message: "writing state" });
3141
- writeClioState(cwd, {
3142
- version: 1,
3143
- projectType,
3144
- fingerprint,
3145
- codewikiVersion: codewiki.version,
3146
- ...prev?.contextSources ? { contextSources: prev.contextSources } : {},
3147
- ...prev?.contextSourceHash ? { contextSourceHash: prev.contextSourceHash } : {},
3148
- ...prev?.lastBootstrap ? { lastBootstrap: prev.lastBootstrap } : {},
3149
- ...prev?.lastInitAt ? { lastInitAt: prev.lastInitAt } : {},
3150
- lastSessionAt: prev?.lastSessionAt ?? indexedAt,
3151
- lastIndexedAt: indexedAt
3517
+ let fingerprint;
3518
+ let clioMd = "absent";
3519
+ const coordinated = await coordinateCodewikiWrite(cwd, () => ({ kind: "build", cwd, language: projectType }), {
3520
+ afterCommit: (result, workspace) => {
3521
+ fingerprint = result.fingerprint;
3522
+ clioMd = curateClioMd(workspace, result.codewiki);
3523
+ input.onProgress?.({ phase: "state", status: "running", message: "writing state" });
3524
+ const latest = readClioState(workspace);
3525
+ writeClioState(workspace, {
3526
+ version: 1,
3527
+ projectType,
3528
+ fingerprint: result.fingerprint,
3529
+ codewikiVersion: result.codewiki.version,
3530
+ ...latest?.contextSources ? { contextSources: latest.contextSources } : {},
3531
+ ...latest?.contextSourceHash ? { contextSourceHash: latest.contextSourceHash } : {},
3532
+ ...latest?.lastBootstrap ? { lastBootstrap: latest.lastBootstrap } : {},
3533
+ ...latest?.lastInitAt ? { lastInitAt: latest.lastInitAt } : {},
3534
+ lastSessionAt: latest?.lastSessionAt ?? indexedAt,
3535
+ lastIndexedAt: indexedAt
3536
+ });
3537
+ }
3152
3538
  });
3539
+ if (!coordinated || !fingerprint) throw new Error("codewiki refresh transaction did not commit");
3540
+ const codewiki = coordinated.codewiki;
3153
3541
  const entries = indexedSourceFileCount3(codewiki);
3154
3542
  let wikiResult;
3155
3543
  let hint;
@@ -3166,7 +3554,8 @@ async function runContextRefresh(input = {}) {
3166
3554
  } else if (hasWiki) {
3167
3555
  hint = incompleteWikiHint(cwd) ?? (wikiStaleness(cwd).state === "stale" ? STALE_WIKI_REFRESH_HINT : void 0);
3168
3556
  }
3169
- const handbookNote = clioMd === "updated" ? "; CLIO-CODER.md index sections updated" : "";
3557
+ const committedClioMd = clioMd;
3558
+ const handbookNote = committedClioMd === "updated" ? "; CLIO-CODER.md index sections updated" : "";
3170
3559
  input.io?.stdout(
3171
3560
  `clio-coder context refresh: codewiki rebuilt (${entries} source file${entries === 1 ? "" : "s"})${handbookNote}
3172
3561
  `
@@ -3176,17 +3565,23 @@ async function runContextRefresh(input = {}) {
3176
3565
  action: "refreshed",
3177
3566
  codewikiEntries: entries,
3178
3567
  fingerprint,
3179
- clioMd,
3568
+ clioMd: committedClioMd,
3180
3569
  ...wikiResult ? { wiki: wikiResult } : {},
3181
3570
  ...hint ? { hint } : {}
3182
3571
  };
3183
3572
  }
3184
3573
 
3574
+ // src/domains/context/runtime.ts
3575
+ init_esm_shims();
3576
+
3185
3577
  // src/domains/context/extension.ts
3186
- function persistState(cwd, fingerprint, indexedAt, prev, codewikiVersion) {
3578
+ init_esm_shims();
3579
+ import { existsSync as existsSync8 } from "node:fs";
3580
+ import { isAbsolute, join as join11, relative as relative4, resolve as resolve3 } from "node:path";
3581
+ function persistState(cwd, fingerprint, indexedAt, prev, codewikiVersion, projectType) {
3187
3582
  writeClioState(cwd, {
3188
3583
  version: 1,
3189
- projectType: prev?.projectType ?? detectProjectType(cwd),
3584
+ projectType: prev?.projectType ?? projectType,
3190
3585
  fingerprint,
3191
3586
  codewikiVersion,
3192
3587
  ...prev?.contextSources ? { contextSources: prev.contextSources } : {},
@@ -3200,23 +3595,26 @@ function persistState(cwd, fingerprint, indexedAt, prev, codewikiVersion) {
3200
3595
  async function ensureCodewikiFresh(cwd) {
3201
3596
  if (process.env.CLIO_CODER_BOOTSTRAP_GENERATE_CHILD === "1") return;
3202
3597
  const state = readClioState(cwd);
3203
- if (!state && !existsSync7(codewikiPath(cwd))) return;
3204
- const slicer = createSlicer();
3205
- const codewiki = await readCodewikiAsync(cwd);
3206
- const fingerprint = await computeFingerprintAsync(cwd, codewiki, { slicer });
3207
- const stale = !state || isStale(state.fingerprint, fingerprint) || !existsSync7(codewikiPath(cwd)) || !codewiki || codewikiNeedsBackfill(codewiki);
3208
- if (!stale) return;
3598
+ if (!state && !existsSync8(codewikiPath(cwd))) return;
3209
3599
  const indexedAt = (/* @__PURE__ */ new Date()).toISOString();
3210
- const projectType = state?.projectType ?? detectProjectType(cwd);
3211
- const synced = codewiki ? await syncCodewiki(cwd, codewiki, { slicer }) : await buildCodewiki({ cwd, language: projectType, generatedAt: indexedAt }, { slicer });
3212
- writeCodewiki(cwd, synced);
3213
- persistState(cwd, await computeFingerprintAsync(cwd, synced, { slicer }), indexedAt, state, synced.version);
3600
+ await coordinateCodewikiWrite(
3601
+ cwd,
3602
+ (current, workspace) => {
3603
+ const language = readClioState(workspace)?.projectType ?? current?.language;
3604
+ return {
3605
+ kind: "ensure",
3606
+ cwd,
3607
+ ...language ? { language } : {},
3608
+ current,
3609
+ previous: readClioState(workspace)?.fingerprint ?? null
3610
+ };
3611
+ },
3612
+ {
3613
+ afterCommit: ({ codewiki, fingerprint }, workspace) => persistState(workspace, fingerprint, indexedAt, readClioState(workspace), codewiki.version, codewiki.language)
3614
+ }
3615
+ );
3214
3616
  }
3215
3617
  var CONTEXT_STATE_CACHE_TTL_MS = 1500;
3216
- var CODEWIKI_CACHE_LIMIT = 4;
3217
- function codewikiContentHash(raw) {
3218
- return createHash2("sha256").update(raw).digest("hex");
3219
- }
3220
3618
  function memoryCount() {
3221
3619
  try {
3222
3620
  return loadMemoryRecordsSync(clioDataDir()).length;
@@ -3225,11 +3623,12 @@ function memoryCount() {
3225
3623
  }
3226
3624
  }
3227
3625
  function resolveClioMdState(cwd) {
3228
- const clio = tryReadClioMd(cwd);
3229
- if (!clio) return "none";
3230
- if (!clio.ok) return "malformed";
3626
+ const clio = loadProjectClioMd(cwd);
3627
+ if (clio.files.length === 0 && clio.errors.length === 0) return "none";
3628
+ if (clio.errors.length > 0) return "malformed";
3231
3629
  const state = readClioState(cwd);
3232
- if (state?.contextSources !== void 0 && adoptionSourcesChanged(state.contextSources, { cwd })) {
3630
+ const localStandardIsEffective = clio.files.some((file) => file.path === join11(resolve3(cwd), "CLIO-CODER.md"));
3631
+ if (localStandardIsEffective && state?.contextSources !== void 0 && adoptionSourcesChanged(state.contextSources, { cwd })) {
3233
3632
  return "stale";
3234
3633
  }
3235
3634
  return "ok";
@@ -3258,12 +3657,12 @@ function collectStartupHints(cwd, options = {}) {
3258
3657
  } catch {
3259
3658
  projectType = "unknown";
3260
3659
  }
3261
- const clio = tryReadClioMd(cwd);
3262
- if (!clio && projectType !== "unknown" && options.noContextFiles !== true) {
3660
+ const clio = loadProjectClioMd(cwd);
3661
+ if (clio.files.length === 0 && clio.errors.length === 0 && projectType !== "unknown" && options.noContextFiles !== true) {
3263
3662
  hints.push("clio: No CLIO-CODER.md detected. Run /context init to explore the repo and bootstrap context.");
3264
3663
  }
3265
- if (clio && !clio.ok) {
3266
- hints.push(`clio: malformed CLIO-CODER.md ignored: ${clio.error}`);
3664
+ for (const issue of clio.errors) {
3665
+ hints.push(`clio: malformed ${issue.path} ignored: ${issue.error}`);
3267
3666
  }
3268
3667
  const state = readClioState(cwd);
3269
3668
  if (!state) return hints;
@@ -3274,44 +3673,9 @@ function collectStartupHints(cwd, options = {}) {
3274
3673
  }
3275
3674
  function createContextBundle(_context, options = {}) {
3276
3675
  let lastCwd = process.cwd();
3676
+ let stopping = false;
3277
3677
  let startupHints = [];
3278
3678
  const contextState = createContextStateReader();
3279
- const codewikiCache = /* @__PURE__ */ new Map();
3280
- const rememberCodewiki = (cwd, hash, codewiki) => {
3281
- codewikiCache.delete(cwd);
3282
- codewikiCache.set(cwd, { hash, codewiki });
3283
- while (codewikiCache.size > CODEWIKI_CACHE_LIMIT) {
3284
- const oldest = codewikiCache.keys().next().value;
3285
- if (oldest === void 0) break;
3286
- codewikiCache.delete(oldest);
3287
- }
3288
- };
3289
- const readCachedCodewiki = (cwd) => {
3290
- let raw;
3291
- try {
3292
- raw = readFileSync7(codewikiPath(cwd), "utf8");
3293
- } catch {
3294
- codewikiCache.delete(cwd);
3295
- return null;
3296
- }
3297
- const hash = codewikiContentHash(raw);
3298
- const cached = codewikiCache.get(cwd);
3299
- if (cached && cached.hash === hash) {
3300
- rememberCodewiki(cwd, hash, cached.codewiki);
3301
- return cached.codewiki;
3302
- }
3303
- const codewiki = parseCodewikiRaw(raw);
3304
- if (!codewiki) {
3305
- codewikiCache.delete(cwd);
3306
- return null;
3307
- }
3308
- rememberCodewiki(cwd, hash, codewiki);
3309
- return codewiki;
3310
- };
3311
- const writeCachedCodewiki = (cwd, codewiki) => {
3312
- const serialized = writeCodewiki(cwd, codewiki);
3313
- rememberCodewiki(cwd, codewikiContentHash(serialized), codewiki);
3314
- };
3315
3679
  const onStart = () => {
3316
3680
  lastCwd = process.cwd();
3317
3681
  void ensureCodewikiFresh(lastCwd).catch(() => {
@@ -3323,23 +3687,30 @@ function createContextBundle(_context, options = {}) {
3323
3687
  };
3324
3688
  let incrementalQueue = Promise.resolve();
3325
3689
  const noteFileChanges = (paths, cwd = lastCwd) => {
3690
+ if (stopping) return;
3691
+ const workspace = resolve3(cwd);
3326
3692
  incrementalQueue = incrementalQueue.then(async () => {
3327
3693
  if (paths.length === 0) return;
3328
- const codewiki = readCachedCodewiki(cwd);
3329
- if (!codewiki) return;
3330
- const rel = paths.map((p) => isAbsolute(p) ? relative3(cwd, p) : p).filter((p) => p.length > 0 && !p.startsWith(".."));
3331
- const slicer = createSlicer();
3332
- const updated = await updateCodewikiPaths(cwd, codewiki, rel, { slicer });
3333
- if (updated === codewiki) return;
3334
- writeCachedCodewiki(cwd, updated);
3335
- persistState(
3336
- cwd,
3337
- await computeFingerprintAsync(cwd, updated, { slicer }),
3338
- (/* @__PURE__ */ new Date()).toISOString(),
3339
- readClioState(cwd),
3340
- updated.version
3694
+ const rel = paths.map((p) => isAbsolute(p) ? relative4(workspace, p) : p).filter((p) => p.length > 0 && !p.startsWith(".."));
3695
+ await coordinateCodewikiWrite(
3696
+ workspace,
3697
+ (current) => current ? { kind: "incremental", cwd: workspace, current, paths: rel } : null,
3698
+ {
3699
+ requireExisting: true,
3700
+ afterCommit: ({ codewiki, fingerprint, changed }, committedWorkspace) => {
3701
+ if (!changed) return;
3702
+ persistState(
3703
+ committedWorkspace,
3704
+ fingerprint,
3705
+ (/* @__PURE__ */ new Date()).toISOString(),
3706
+ readClioState(committedWorkspace),
3707
+ codewiki.version,
3708
+ codewiki.language
3709
+ );
3710
+ }
3711
+ }
3341
3712
  );
3342
- contextState.invalidate(cwd);
3713
+ contextState.invalidate(workspace);
3343
3714
  }).catch(() => {
3344
3715
  });
3345
3716
  };
@@ -3349,33 +3720,13 @@ function createContextBundle(_context, options = {}) {
3349
3720
  unsubscribeSessionStart = _context.bus.on(BusChannels.SessionStart, onStart);
3350
3721
  },
3351
3722
  async stop() {
3723
+ stopping = true;
3352
3724
  unsubscribeSessionStart?.();
3353
3725
  unsubscribeSessionStart = null;
3354
- await incrementalQueue;
3355
- const slicer = createSlicer();
3356
- const projectType = detectProjectType(lastCwd);
3726
+ await Promise.all([incrementalQueue, drainCodewikiWrites(lastCwd)]);
3357
3727
  const state = readClioState(lastCwd);
3358
- let codewiki = readCachedCodewiki(lastCwd);
3359
- let fingerprint = await computeFingerprintAsync(lastCwd, codewiki, { slicer });
3360
- let lastIndexedAt = state?.lastIndexedAt;
3361
- if (!state || isStale(state.fingerprint, fingerprint) || !codewiki || codewikiNeedsBackfill(codewiki)) {
3362
- lastIndexedAt = (/* @__PURE__ */ new Date()).toISOString();
3363
- codewiki = codewiki ? await syncCodewiki(lastCwd, codewiki, { slicer }) : await buildCodewiki({ cwd: lastCwd, language: projectType, generatedAt: lastIndexedAt }, { slicer });
3364
- writeCachedCodewiki(lastCwd, codewiki);
3365
- fingerprint = await computeFingerprintAsync(lastCwd, codewiki, { slicer });
3366
- }
3367
- writeClioState(lastCwd, {
3368
- version: 1,
3369
- projectType,
3370
- fingerprint,
3371
- ...codewiki ? { codewikiVersion: codewiki.version } : {},
3372
- ...state?.contextSources ? { contextSources: state.contextSources } : {},
3373
- ...state?.contextSourceHash ? { contextSourceHash: state.contextSourceHash } : {},
3374
- ...state?.lastBootstrap ? { lastBootstrap: state.lastBootstrap } : {},
3375
- ...state?.lastInitAt ? { lastInitAt: state.lastInitAt } : {},
3376
- lastSessionAt: (/* @__PURE__ */ new Date()).toISOString(),
3377
- ...lastIndexedAt ? { lastIndexedAt } : {}
3378
- });
3728
+ if (!state) return;
3729
+ writeClioState(lastCwd, { ...state, lastSessionAt: (/* @__PURE__ */ new Date()).toISOString() });
3379
3730
  }
3380
3731
  };
3381
3732
  const contract = {
@@ -3466,16 +3817,13 @@ function createContextBundle(_context, options = {}) {
3466
3817
  },
3467
3818
  renderPromptContext,
3468
3819
  projectStructuredContext(cwd = process.cwd()) {
3469
- const clio = tryReadClioMd(cwd);
3470
- if (!clio?.ok) return null;
3471
- const verification = clio.value.sections.find(
3472
- (section) => section.title.toLowerCase() === "verification expectations"
3473
- );
3474
- const verificationBody = verification?.body.trim() ?? "";
3820
+ const clio = loadProjectClioMd(cwd).value;
3821
+ if (!clio) return null;
3822
+ const verificationBody = clio.sections.filter((section) => section.title.toLowerCase() === "verification expectations").map((section) => section.body.trim()).filter((body) => body.length > 0).join("\n\n");
3475
3823
  return {
3476
- projectName: clio.value.projectName,
3477
- conventions: [...clio.value.conventions],
3478
- invariants: [...clio.value.invariants],
3824
+ projectName: clio.projectName,
3825
+ conventions: [...clio.conventions],
3826
+ invariants: [...clio.invariants],
3479
3827
  ...verificationBody.length > 0 ? { verificationExpectations: verificationBody } : {}
3480
3828
  };
3481
3829
  },
@@ -3493,264 +3841,128 @@ var ContextManifest = {
3493
3841
  dependsOn: ["resources"]
3494
3842
  };
3495
3843
 
3496
- // src/domains/context/operator-profile.ts
3497
- init_esm_shims();
3498
- var import_yaml2 = __toESM(require_dist(), 1);
3499
- import { createHash as createHash3 } from "node:crypto";
3500
- import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
3501
- import { join as join9 } from "node:path";
3502
- var RESPONSE_POSTURES = ["concise", "balanced", "thorough"];
3503
- var VALIDATION_PREFERENCES = ["tests-first", "manual", "trust"];
3504
- var COMMIT_MESSAGE_STYLES = ["conventional", "descriptive", "terse"];
3505
- var OPERATOR_PROFILE_MAX_CHARS = 700;
3506
- var OPERATOR_PROFILE_MAX_LOCAL_PATHS = 8;
3507
- function isRecord2(value) {
3508
- return value !== null && typeof value === "object" && !Array.isArray(value);
3509
- }
3510
- function readEnum(value, allowed, field, issues) {
3511
- if (value === void 0) return void 0;
3512
- if (typeof value === "string" && allowed.includes(value)) return value;
3513
- issues.push(`${field} must be one of ${allowed.join(", ")}`);
3514
- return void 0;
3515
- }
3516
- function readProfileBlob(value, issues) {
3517
- if (!isRecord2(value)) {
3518
- if (value !== null && value !== void 0) issues.push("profile must be a mapping at the root");
3519
- return {};
3520
- }
3521
- const profile = {};
3522
- const posture = readEnum(value.responsePosture, RESPONSE_POSTURES, "responsePosture", issues);
3523
- if (posture) profile.responsePosture = posture;
3524
- const validation = readEnum(value.validationPreference, VALIDATION_PREFERENCES, "validationPreference", issues);
3525
- if (validation) profile.validationPreference = validation;
3526
- const commit = readEnum(value.commitMessageStyle, COMMIT_MESSAGE_STYLES, "commitMessageStyle", issues);
3527
- if (commit) profile.commitMessageStyle = commit;
3528
- if (value.localOnlyPaths !== void 0) {
3529
- if (Array.isArray(value.localOnlyPaths)) {
3530
- const paths = value.localOnlyPaths.filter((item) => typeof item === "string" && item.length > 0);
3531
- if (paths.length > 0) profile.localOnlyPaths = paths.slice(0, OPERATOR_PROFILE_MAX_LOCAL_PATHS);
3532
- } else {
3533
- issues.push("localOnlyPaths must be an array of strings");
3534
- }
3535
- }
3536
- return profile;
3537
- }
3538
- function readProfileFile(path, issues) {
3539
- if (!existsSync8(path)) return { profile: {}, present: false };
3540
- try {
3541
- return { profile: readProfileBlob((0, import_yaml2.parse)(readFileSync8(path, "utf8")), issues), present: true };
3542
- } catch (err) {
3543
- issues.push(`${path}: invalid YAML: ${err instanceof Error ? err.message : String(err)}`);
3544
- return { profile: {}, present: false };
3545
- }
3546
- }
3547
- function loadOperatorProfile(cwd, options = {}) {
3548
- const issues = [];
3549
- const userPath = options.userPath ?? join9(resolveClioDirs().config, "profile.yaml");
3550
- const projectPath = join9(cwd, ".clio-coder", "profile.yaml");
3551
- const user = readProfileFile(userPath, issues);
3552
- const project = readProfileFile(projectPath, issues);
3553
- const profile = { ...user.profile, ...project.profile };
3554
- let origin = "none";
3555
- let sourcePath;
3556
- if (project.present) {
3557
- origin = "project";
3558
- sourcePath = projectPath;
3559
- } else if (user.present) {
3560
- origin = "user";
3561
- sourcePath = userPath;
3562
- }
3563
- const result = { profile, origin, issues };
3564
- if (sourcePath !== void 0) {
3565
- result.sourcePath = sourcePath;
3566
- result.hash = createHash3("sha256").update(JSON.stringify(profile)).digest("hex").slice(0, 16);
3567
- }
3568
- return result;
3569
- }
3570
- function renderOperatorProfile(profile) {
3571
- const lines = [];
3572
- if (profile.responsePosture) lines.push(`- Response posture: ${profile.responsePosture}.`);
3573
- if (profile.validationPreference) lines.push(`- Validation preference: ${profile.validationPreference}.`);
3574
- if (profile.commitMessageStyle) lines.push(`- Commit-message style: ${profile.commitMessageStyle}.`);
3575
- if (profile.localOnlyPaths && profile.localOnlyPaths.length > 0) {
3576
- lines.push(`- Keep local-only (do not push or share): ${profile.localOnlyPaths.join(", ")}.`);
3577
- }
3578
- if (lines.length === 0) return { text: "", tokenEstimate: 0 };
3579
- const full = `## Operator profile
3580
- ${lines.join("\n")}`;
3581
- const text = full.length > OPERATOR_PROFILE_MAX_CHARS ? `${full.slice(0, OPERATOR_PROFILE_MAX_CHARS - 1)}\u2026` : full;
3582
- return { text, tokenEstimate: ceilChars(text.length) };
3844
+ // src/domains/context/runtime.ts
3845
+ var ContextDomainModule = {
3846
+ manifest: ContextManifest,
3847
+ createExtension: createContextBundle
3848
+ };
3849
+ function createContextDomainModule(options = {}) {
3850
+ return {
3851
+ manifest: ContextManifest,
3852
+ createExtension: (context) => createContextBundle(context, options)
3853
+ };
3583
3854
  }
3584
3855
 
3585
- // src/domains/context/project-rules.ts
3856
+ // src/domains/context/wiki/prompts.ts
3586
3857
  init_esm_shims();
3587
- var import_yaml3 = __toESM(require_dist(), 1);
3588
- import { createHash as createHash4 } from "node:crypto";
3589
- import { readdirSync as readdirSync4, readFileSync as readFileSync9 } from "node:fs";
3590
- import { join as join10, relative as relative4, sep as sep2 } from "node:path";
3591
- var FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n?/;
3592
- function isRecord3(value) {
3593
- return value !== null && typeof value === "object" && !Array.isArray(value);
3594
- }
3595
- function readStringArray(value) {
3596
- if (!Array.isArray(value)) return void 0;
3858
+ import { execFileSync as execFileSync2 } from "node:child_process";
3859
+ import { existsSync as existsSync9, realpathSync, statSync as statSync4 } from "node:fs";
3860
+ import { isAbsolute as isAbsolute2, join as join12, relative as relative5 } from "node:path";
3861
+
3862
+ // src/domains/prompts/fragment-loader.ts
3863
+ init_esm_shims();
3864
+ var import_yaml4 = __toESM(require_dist(), 1);
3865
+ import { readdirSync as readdirSync5, readFileSync as readFileSync9 } from "node:fs";
3866
+ import path from "node:path";
3867
+ var frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
3868
+ var fragmentIdRegex = /^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;
3869
+ function defaultRootDir() {
3870
+ return path.join(resolvePackageRoot(), "src", "domains", "prompts", "fragments");
3871
+ }
3872
+ function walk(root) {
3597
3873
  const out3 = [];
3598
- for (const item of value) {
3599
- if (typeof item === "string" && item.length > 0) out3.push(item);
3600
- }
3601
- return out3.length > 0 ? out3 : void 0;
3602
- }
3603
- function validateGlobArray(value, field, id, issues) {
3604
- const parsed = readStringArray(value);
3605
- if (parsed === void 0) {
3606
- issues.push(`${id}: frontmatter ${field} must be a non-empty string array`);
3607
- return void 0;
3608
- }
3609
- for (const pattern of parsed) {
3610
- try {
3611
- compileGlobRegex(pattern);
3612
- } catch (err) {
3613
- issues.push(
3614
- `${id}: invalid ${field} glob ${JSON.stringify(pattern)}: ${err instanceof Error ? err.message : String(err)}`
3615
- );
3616
- return void 0;
3617
- }
3618
- }
3619
- return parsed;
3620
- }
3621
- function walkMarkdown(dir, root, out3) {
3622
3874
  let entries;
3623
3875
  try {
3624
- entries = readdirSync4(dir, { withFileTypes: true });
3876
+ entries = readdirSync5(root, { withFileTypes: true });
3625
3877
  } catch {
3626
- return;
3878
+ return out3;
3627
3879
  }
3628
3880
  for (const entry of entries) {
3629
- const full = join10(dir, entry.name);
3630
- if (entry.isDirectory()) walkMarkdown(full, root, out3);
3631
- else if (entry.isFile() && entry.name.endsWith(".md")) out3.push(full);
3881
+ const full = path.join(root, entry.name);
3882
+ if (entry.isDirectory()) {
3883
+ out3.push(...walk(full));
3884
+ continue;
3885
+ }
3886
+ if (entry.isFile() && entry.name.endsWith(".md")) {
3887
+ out3.push(full);
3888
+ }
3632
3889
  }
3890
+ return out3.sort((left, right) => left.localeCompare(right));
3633
3891
  }
3634
- function parseRule(filePath, root, issues) {
3635
- let text;
3892
+ function parseFragment(filePath, rootDir) {
3893
+ const raw = readFileSync9(filePath, "utf8");
3894
+ const rawRel = path.relative(rootDir, filePath);
3895
+ const relPath = rawRel.split(path.sep).join("/");
3896
+ const match = raw.match(frontmatterRegex);
3897
+ if (!match) {
3898
+ throw new Error(`fragment-loader: ${relPath}: missing or malformed YAML frontmatter`);
3899
+ }
3900
+ const frontmatterText = match[1] ?? "";
3901
+ const body = match[2] ?? "";
3902
+ let parsed;
3636
3903
  try {
3637
- text = readFileSync9(filePath, "utf8").replace(/\r\n/g, "\n");
3904
+ parsed = import_yaml4.default.parse(frontmatterText);
3638
3905
  } catch (err) {
3639
- issues.push(`${filePath}: ${err instanceof Error ? err.message : String(err)}`);
3640
- return { excludes: [] };
3906
+ const reason = err instanceof Error ? err.message : String(err);
3907
+ throw new Error(`fragment-loader: ${relPath}: invalid YAML frontmatter (${reason})`);
3641
3908
  }
3642
- const id = relative4(root, filePath).split(sep2).join("/");
3643
- let body = text;
3644
- let paths;
3645
- let excludes = [];
3646
- let enabled = true;
3647
- let description2;
3648
- let invalidFrontmatter = false;
3649
- const match = FRONTMATTER_RE.exec(text);
3650
- if (match) {
3651
- body = text.slice(match[0].length);
3652
- try {
3653
- const front = (0, import_yaml3.parse)(match[1] ?? "");
3654
- if (isRecord3(front)) {
3655
- if (Object.hasOwn(front, "paths")) {
3656
- const parsedPaths = validateGlobArray(front.paths, "paths", id, issues);
3657
- if (parsedPaths === void 0) invalidFrontmatter = true;
3658
- else paths = parsedPaths;
3659
- }
3660
- if (Object.hasOwn(front, "excludes")) {
3661
- const parsedExcludes = validateGlobArray(front.excludes, "excludes", id, issues);
3662
- if (parsedExcludes === void 0) invalidFrontmatter = true;
3663
- else excludes = parsedExcludes;
3664
- }
3665
- if (Object.hasOwn(front, "enabled")) {
3666
- if (typeof front.enabled === "boolean") enabled = front.enabled;
3667
- else {
3668
- issues.push(`${id}: frontmatter enabled must be a boolean`);
3669
- invalidFrontmatter = true;
3670
- }
3671
- }
3672
- if (Object.hasOwn(front, "description")) {
3673
- if (typeof front.description === "string") description2 = front.description;
3674
- else {
3675
- issues.push(`${id}: frontmatter description must be a string`);
3676
- invalidFrontmatter = true;
3677
- }
3678
- }
3679
- } else if (front !== null && front !== void 0) {
3680
- issues.push(`${id}: frontmatter must be a mapping`);
3681
- invalidFrontmatter = true;
3682
- }
3683
- } catch (err) {
3684
- issues.push(`${id}: invalid frontmatter: ${err instanceof Error ? err.message : String(err)}`);
3685
- invalidFrontmatter = true;
3686
- }
3687
- } else if (text.startsWith("---\n")) {
3688
- issues.push(`${id}: invalid frontmatter: missing closing marker`);
3689
- invalidFrontmatter = true;
3909
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
3910
+ throw new Error(`fragment-loader: ${relPath}: frontmatter must be a YAML object`);
3690
3911
  }
3691
- if (invalidFrontmatter) return { excludes: [] };
3692
- const trimmedBody = body.trim();
3693
- const hash = createHash4("sha256").update(trimmedBody).digest("hex").slice(0, 16);
3694
- const rule = {
3912
+ const fm = parsed;
3913
+ const id = fm.id;
3914
+ if (typeof id !== "string" || !fragmentIdRegex.test(id)) {
3915
+ throw new Error(`fragment-loader: ${relPath}: frontmatter.id must be a dot-separated namespace`);
3916
+ }
3917
+ const version = fm.version;
3918
+ if (version !== 1) {
3919
+ throw new Error(`fragment-loader: ${relPath}: frontmatter.version must be 1`);
3920
+ }
3921
+ const description2 = fm.description;
3922
+ if (typeof description2 !== "string" || description2.trim() === "") {
3923
+ throw new Error(`fragment-loader: ${relPath}: frontmatter.description must be a non-empty string`);
3924
+ }
3925
+ const dynamicRaw = fm.dynamic;
3926
+ if (dynamicRaw !== void 0 && typeof dynamicRaw !== "boolean") {
3927
+ throw new Error(`fragment-loader: ${relPath}: frontmatter.dynamic must be a boolean when present`);
3928
+ }
3929
+ return {
3930
+ path: filePath,
3931
+ relPath,
3695
3932
  id,
3696
- sourcePath: join10(".clio-coder", "rules", id),
3697
- hash,
3698
- tokenEstimate: ceilChars(trimmedBody.length),
3699
- enabled,
3700
- body: trimmedBody
3933
+ version,
3934
+ description: description2,
3935
+ dynamic: dynamicRaw === true,
3936
+ body,
3937
+ contentHash: sha256(raw)
3701
3938
  };
3702
- if (paths !== void 0) rule.paths = paths;
3703
- if (description2 !== void 0) rule.description = description2;
3704
- return { rule, excludes };
3705
3939
  }
3706
- function loadProjectRules(cwd) {
3707
- const root = join10(cwd, ".clio-coder", "rules");
3708
- const issues = [];
3709
- const files = [];
3710
- walkMarkdown(root, root, files);
3711
- files.sort();
3712
- const rules = [];
3713
- const excludeSet = /* @__PURE__ */ new Set();
3940
+ function loadFragments(options) {
3941
+ const rootDir = typeof options === "string" ? options : options?.rootDir;
3942
+ const resolvedRoot = rootDir ? path.resolve(rootDir) : defaultRootDir();
3943
+ const files = walk(resolvedRoot);
3944
+ const byId = /* @__PURE__ */ new Map();
3714
3945
  for (const file of files) {
3715
- const parsed = parseRule(file, root, issues);
3716
- if (parsed.rule) rules.push(parsed.rule);
3717
- for (const glob of parsed.excludes) excludeSet.add(glob);
3718
- }
3719
- rules.sort((a, b) => a.id.localeCompare(b.id));
3720
- return { rules, excludes: [...excludeSet], issues };
3721
- }
3722
- function ruleMatchesAnyPath(rule, workingPaths) {
3723
- for (const pattern of rule.paths ?? []) {
3724
- let regex;
3725
- try {
3726
- regex = compileGlobRegex(pattern);
3727
- } catch {
3728
- continue;
3729
- }
3730
- for (const path of workingPaths) {
3731
- if (regex.test(normalizeGlobInput(path))) return true;
3946
+ const fragment = parseFragment(file, resolvedRoot);
3947
+ const existing = byId.get(fragment.id);
3948
+ if (existing) {
3949
+ throw new Error(
3950
+ `fragment-loader: duplicate fragment id "${fragment.id}" in ${existing.relPath} and ${fragment.relPath}`
3951
+ );
3732
3952
  }
3953
+ byId.set(fragment.id, fragment);
3733
3954
  }
3734
- return false;
3735
- }
3736
- function selectActiveRules(rules, workingContextPaths) {
3737
- return rules.filter((rule) => {
3738
- if (!rule.enabled) return false;
3739
- if (rule.paths === void 0) return true;
3740
- return ruleMatchesAnyPath(rule, workingContextPaths);
3741
- });
3955
+ return { byId, rootDir: resolvedRoot };
3742
3956
  }
3743
3957
 
3744
3958
  // src/domains/context/wiki/prompts.ts
3745
- init_esm_shims();
3746
- import { execFileSync as execFileSync2 } from "node:child_process";
3747
- import { existsSync as existsSync9, readFileSync as readFileSync10, realpathSync, statSync as statSync3 } from "node:fs";
3748
- import { isAbsolute as isAbsolute2, join as join11, relative as relative5 } from "node:path";
3749
- function fragmentPath(fragment) {
3750
- return join11(resolvePackageRoot(), "src", "domains", "prompts", "fragments", "wiki", `${fragment}.md`);
3751
- }
3752
3959
  function readWikiFragment(fragment, substitutions) {
3753
- let text = readFileSync10(fragmentPath(fragment), "utf8").trim();
3960
+ const id = `wiki.${fragment}`;
3961
+ const loaded = loadFragments().byId.get(id);
3962
+ if (!loaded) {
3963
+ throw new Error(`context/wiki: fragment "${id}" not found; check prompts/fragments/wiki/${fragment}.md frontmatter`);
3964
+ }
3965
+ let text = loaded.body.trim();
3754
3966
  for (const [token, value] of Object.entries(substitutions)) {
3755
3967
  text = text.split(`{{${token}}}`).join(value);
3756
3968
  }
@@ -3780,11 +3992,11 @@ function repositoryGuidancePaths(cwd) {
3780
3992
  const seen = /* @__PURE__ */ new Set();
3781
3993
  const paths = [];
3782
3994
  for (const relPath of REPOSITORY_GUIDANCE_CANDIDATES) {
3783
- const absPath = join11(cwd, relPath);
3995
+ const absPath = join12(cwd, relPath);
3784
3996
  if (!existsSync9(absPath)) continue;
3785
3997
  try {
3786
3998
  const resolved = realpathSync(absPath);
3787
- const stat = statSync3(resolved);
3999
+ const stat = statSync4(resolved);
3788
4000
  if (!isWithin(root, resolved) || !stat.isFile() || stat.size === 0 || seen.has(resolved)) continue;
3789
4001
  seen.add(resolved);
3790
4002
  paths.push(relPath);
@@ -3800,7 +4012,7 @@ function repositoryGuidance(cwd) {
3800
4012
  }
3801
4013
  return [
3802
4014
  "Read every detected instruction file before drafting:",
3803
- ...paths.map((path) => `- ${path}`),
4015
+ ...paths.map((path2) => `- ${path2}`),
3804
4016
  "Treat these files as repository instructions, not implementation proof. If one designates a planning, specification, or engineering-truth authority, read that authority before making status claims, then verify mutable implementation claims against live source, configuration, and tests."
3805
4017
  ].join("\n");
3806
4018
  }
@@ -3851,7 +4063,7 @@ function buildWikiPlanPrompt(input) {
3851
4063
  const plan = input.plan ?? generation.plan;
3852
4064
  const unclaimed = input.unclaimedAreas ?? [];
3853
4065
  const sections = [
3854
- readWikiFragment("plan", { planPath: join11(input.outputDir, WIKI_PLAN_FILE) }),
4066
+ readWikiFragment("plan", { planPath: join12(input.outputDir, WIKI_PLAN_FILE) }),
3855
4067
  "## Repository scale",
3856
4068
  `${generation.sourceFiles} indexed source files, ${generation.sourceLines} source lines, decomposed at ${generation.depth} depth into ${generation.plan.pages.length} candidate pages.`,
3857
4069
  "## Candidate plan",
@@ -3901,7 +4113,7 @@ function buildWikiPagePrompt(input) {
3901
4113
  const siblingLines = input.siblings.filter((sibling) => sibling.path !== page.path).map((sibling) => `- ${sibling.path} \u2014 ${sibling.title}`);
3902
4114
  const sections = [
3903
4115
  readWikiFragment("page", {
3904
- pagePath: join11(input.outputDir, page.path),
4116
+ pagePath: join12(input.outputDir, page.path),
3905
4117
  pageRelPath: page.path,
3906
4118
  pageTitle: page.title
3907
4119
  }),
@@ -3922,25 +4134,13 @@ ${page.sources.map((source) => `- ${source}`).join("\n")}` : "No anchor sources
3922
4134
  if (input.seeded) {
3923
4135
  sections.push(
3924
4136
  "## Revision",
3925
- `A previous version of this page is already at ${join11(input.outputDir, page.path)}. Read it first and revise it in place. Correct what the current source contradicts and fill what it omits; keep accurate prose as it stands.`
4137
+ `A previous version of this page is already at ${join12(input.outputDir, page.path)}. Read it first and revise it in place. Correct what the current source contradicts and fill what it omits; keep accurate prose as it stands.`
3926
4138
  );
3927
4139
  }
3928
4140
  return `${sections.join("\n\n")}
3929
4141
  `;
3930
4142
  }
3931
4143
 
3932
- // src/domains/context/index.ts
3933
- var ContextDomainModule = {
3934
- manifest: ContextManifest,
3935
- createExtension: createContextBundle
3936
- };
3937
- function createContextDomainModule(options = {}) {
3938
- return {
3939
- manifest: ContextManifest,
3940
- createExtension: (context) => createContextBundle(context, options)
3941
- };
3942
- }
3943
-
3944
4144
  export {
3945
4145
  adoptionSnapshotsHash,
3946
4146
  scanAgentConfigs,
@@ -3948,11 +4148,17 @@ export {
3948
4148
  adoptionSourcesChanged,
3949
4149
  parseClioMd,
3950
4150
  serializeClioMd,
4151
+ loadProjectClioMd,
3951
4152
  tryReadClioMd,
3952
4153
  renderPromptContext,
3953
4154
  fallbackBootstrapOutput,
3954
4155
  runBootstrap,
3955
4156
  runContextClear,
4157
+ OPERATOR_PROFILE_MAX_CHARS,
4158
+ loadOperatorProfile,
4159
+ renderOperatorProfile,
4160
+ loadProjectRules,
4161
+ selectActiveRules,
3956
4162
  assembleWikiTree,
3957
4163
  WIKI_DEPTH_STRATEGY,
3958
4164
  pagePathForArea,
@@ -3960,14 +4166,10 @@ export {
3960
4166
  planWikiGeneration,
3961
4167
  runWikiGenerate,
3962
4168
  runContextRefresh,
3963
- OPERATOR_PROFILE_MAX_CHARS,
3964
- loadOperatorProfile,
3965
- renderOperatorProfile,
3966
- loadProjectRules,
3967
- selectActiveRules,
3968
- buildWikiPlanPrompt,
3969
- buildWikiPagePrompt,
3970
4169
  ContextDomainModule,
3971
- createContextDomainModule
4170
+ createContextDomainModule,
4171
+ loadFragments,
4172
+ buildWikiPlanPrompt,
4173
+ buildWikiPagePrompt
3972
4174
  };
3973
- //# sourceMappingURL=chunk-M5T5VO65.js.map
4175
+ //# sourceMappingURL=chunk-7EYHLWU7.js.map