@iowarp/clio-coder 0.4.6 → 0.4.7

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 (657) hide show
  1. package/.claude-plugin/marketplace.json +283 -0
  2. package/CHANGELOG.md +50 -0
  3. package/CONTRIBUTING.md +102 -29
  4. package/NOTICE +8 -0
  5. package/README.md +37 -5
  6. package/dist/{acp-UVEVWSDL.js → acp-W3Y3TRHD.js} +12 -12
  7. package/dist/{agents-VWY37DTK.js → agents-J4ICNLQ3.js} +52 -52
  8. package/dist/assets/codewiki.json +1 -1
  9. package/dist/assets/tui-notices/get-east-asian-width-LICENSE +9 -0
  10. package/dist/assets/tui-notices/marked-LICENSE +44 -0
  11. package/dist/assets/tui-notices/pi-tui-LICENSE +21 -0
  12. package/dist/{auth-PCV2XQDV.js → auth-X2UJUMOC.js} +24 -24
  13. package/dist/{builtins-PD652MTK.js → builtins-XLXWWSRF.js} +6 -6
  14. package/dist/{chunk-DZK63TZJ.js → chunk-24S3DN22.js} +336 -612
  15. package/dist/{chunk-NTK3WTHM.js → chunk-24TOGHPO.js} +2 -2
  16. package/dist/{chunk-M6TAYK66.js → chunk-2O2LVQQK.js} +11 -4
  17. package/dist/{chunk-OQM5IVJY.js → chunk-34XHRVKG.js} +3 -3
  18. package/dist/{chunk-LY4N4TTL.js → chunk-3LXJOICS.js} +2 -2
  19. package/dist/{chunk-3BJGMT2D.js → chunk-3XE4NRLF.js} +1 -1
  20. package/dist/{chunk-N2OKBREN.js → chunk-4MFBBY2Z.js} +3 -3
  21. package/dist/{chunk-5VTJP36Q.js → chunk-4N2RZ4TO.js} +2 -2
  22. package/dist/{chunk-WNGF5AJX.js → chunk-4QKAITQT.js} +3 -3
  23. package/dist/chunk-4UHVS5T7.js +207 -0
  24. package/dist/{chunk-GLYBJ4RQ.js → chunk-5AJPUR72.js} +6 -6
  25. package/dist/{chunk-5CY4Q6QI.js → chunk-5EQO5NWP.js} +105 -3
  26. package/dist/{chunk-6HAO6X5B.js → chunk-65BGHOUR.js} +8 -5
  27. package/dist/{chunk-6VRRJT7L.js → chunk-6CA2BHOR.js} +2 -2
  28. package/dist/{chunk-HL26ADLH.js → chunk-6CB2IL4N.js} +2 -1
  29. package/dist/{chunk-E7RF4KBO.js → chunk-6LRLOJHQ.js} +3 -3
  30. package/dist/{chunk-HXHFDHB6.js → chunk-6TAATXXH.js} +6 -6
  31. package/dist/{chunk-P6M7RKMI.js → chunk-6YHPAAZR.js} +3 -3
  32. package/dist/{chunk-5QRX7SLS.js → chunk-7EEGBKV4.js} +7 -7
  33. package/dist/{chunk-BS4GAMUB.js → chunk-A67NR5AT.js} +2 -2
  34. package/dist/{chunk-WJIMKGD6.js → chunk-BAU36233.js} +8 -8
  35. package/dist/{chunk-PZN2LQY6.js → chunk-BO4XV5VX.js} +4 -4
  36. package/dist/{chunk-I2K2NCZQ.js → chunk-BQQ5MXUC.js} +6 -6
  37. package/dist/{chunk-X3BI7HTV.js → chunk-C3G5PNUO.js} +21 -21
  38. package/dist/{chunk-SRZOW5L2.js → chunk-C6GEXX4L.js} +1 -1
  39. package/dist/{chunk-6RYDAVQT.js → chunk-CE64C5K5.js} +219 -64
  40. package/dist/chunk-CP3HIR5H.js +2119 -0
  41. package/dist/{chunk-BBV5TKE6.js → chunk-CPXGJI2A.js} +2 -2
  42. package/dist/{chunk-IGLVVNEG.js → chunk-CULVKYTK.js} +4 -4
  43. package/dist/{chunk-DXLUVUD4.js → chunk-D2T66PDV.js} +5 -5
  44. package/dist/{chunk-NF3BK5WR.js → chunk-DACXIVVF.js} +5 -5
  45. package/dist/{chunk-IKRWLEDA.js → chunk-DLIYANB7.js} +20 -15
  46. package/dist/{chunk-RGZNQ5CT.js → chunk-DO7M3LSX.js} +9 -9
  47. package/dist/{chunk-2QPI3TR3.js → chunk-DVJL77SO.js} +2 -2
  48. package/dist/{chunk-ODUTYZIU.js → chunk-EUEXGXXR.js} +5 -5
  49. package/dist/{chunk-WKUYQBCG.js → chunk-EUZRMP4Y.js} +18 -16
  50. package/dist/{chunk-JMPL7NUB.js → chunk-G4LGUTOE.js} +4 -4
  51. package/dist/{chunk-CBSKDFWL.js → chunk-GEVQNST4.js} +2 -2
  52. package/dist/{chunk-NNWJYUNO.js → chunk-GFQ7P2UF.js} +7 -7
  53. package/dist/{chunk-SXQKNKRA.js → chunk-GI5RRMAH.js} +14 -14
  54. package/dist/{chunk-HPTJF6DG.js → chunk-GVZFCJHE.js} +336 -83
  55. package/dist/{chunk-ACCKVSHU.js → chunk-GXIWHXDB.js} +3 -3
  56. package/dist/{chunk-LUL5Z66S.js → chunk-HOX4YZ2K.js} +6 -5
  57. package/dist/chunk-HRAKUPIH.js +57 -0
  58. package/dist/{chunk-F5Z7EWMN.js → chunk-IJMW64DX.js} +50 -50
  59. package/dist/{chunk-QNWRHOMF.js → chunk-IMOD2YPV.js} +16 -9
  60. package/dist/{chunk-HZ2T2YED.js → chunk-IQCNVLO6.js} +28 -8
  61. package/dist/{chunk-HZFBVU5X.js → chunk-ISNCCX42.js} +8 -8
  62. package/dist/{chunk-7JSSKXG2.js → chunk-IZYTT3CD.js} +7 -3
  63. package/dist/chunk-KKEYGFX4.js +915 -0
  64. package/dist/{chunk-HHVJNVUJ.js → chunk-KS7ETA3P.js} +2 -2
  65. package/dist/{chunk-BLTEAUCB.js → chunk-L3Z5ANCV.js} +7 -7
  66. package/dist/{chunk-4VMV6OS6.js → chunk-LBFQMYS3.js} +2 -2
  67. package/dist/{chunk-URBGEOH3.js → chunk-M6Z2V6YU.js} +5 -5
  68. package/dist/{chunk-BT7HGDOX.js → chunk-MBJO5VNZ.js} +12 -12
  69. package/dist/chunk-MNQN3X6Y.js +595 -0
  70. package/dist/{chunk-3QKXHCGS.js → chunk-MZHXENL7.js} +5 -5
  71. package/dist/chunk-MZNWZUJM.js +1801 -0
  72. package/dist/{chunk-7YJWEF2L.js → chunk-N37QC5FV.js} +5 -5
  73. package/dist/{chunk-TJFDL26W.js → chunk-NCCQ6DVS.js} +7 -7
  74. package/dist/{chunk-P5JMBPDJ.js → chunk-NO7J45X6.js} +162 -47
  75. package/dist/chunk-OH3YYA3B.js +15 -0
  76. package/dist/{chunk-22PQ4TX4.js → chunk-P4DL2LM5.js} +16 -77
  77. package/dist/{chunk-LIN2K3EL.js → chunk-PFLOULP3.js} +4 -4
  78. package/dist/{chunk-QXFBABFJ.js → chunk-QKWL7SYE.js} +11 -11
  79. package/dist/chunk-RFCKPS2V.js +26 -0
  80. package/dist/{chunk-ZS43Y2FT.js → chunk-RTLNFZMD.js} +12 -4
  81. package/dist/{chunk-U7H5WRG5.js → chunk-RXFPB32E.js} +8 -6
  82. package/dist/{chunk-Q7NNUHQV.js → chunk-SEDI5K5B.js} +16 -16
  83. package/dist/{chunk-WV6TDAPN.js → chunk-SELG4SUR.js} +7 -7
  84. package/dist/{chunk-3WBALRQH.js → chunk-SER7RRAE.js} +27 -832
  85. package/dist/{chunk-K2HL3GBL.js → chunk-T4TY5GG3.js} +165 -15
  86. package/dist/chunk-T7QQBNLH.js +691 -0
  87. package/dist/{chunk-6OII3LOK.js → chunk-TLTGZTXI.js} +3 -3
  88. package/dist/chunk-TZ6UVP2H.js +637 -0
  89. package/dist/{chunk-3JLFK5MW.js → chunk-TZHN5ITX.js} +13 -41
  90. package/dist/{chunk-VANN3GDP.js → chunk-U3TPUXOQ.js} +399 -234
  91. package/dist/{chunk-VHMX7SXF.js → chunk-UA3W4FGC.js} +6 -6
  92. package/dist/{chunk-3O2ZAUGQ.js → chunk-UA6W4XFJ.js} +2 -2
  93. package/dist/chunk-UWD3JD5X.js +709 -0
  94. package/dist/chunk-V4ZKOKRB.js +13433 -0
  95. package/dist/{chunk-NC4KV7EL.js → chunk-VCRVEDUC.js} +5 -5
  96. package/dist/{chunk-4DU2TVI4.js → chunk-VMATUZB6.js} +12 -10
  97. package/dist/{chunk-J2FYEQ5L.js → chunk-VTYHHQ57.js} +2 -2
  98. package/dist/chunk-WB7POC6M.js +891 -0
  99. package/dist/{chunk-3HQVBIKD.js → chunk-WBVKKTUT.js} +2 -2
  100. package/dist/{chunk-EHOSNVVM.js → chunk-WLHX3MM5.js} +6 -2
  101. package/dist/{chunk-24T2YZ7A.js → chunk-WN552PKN.js} +553 -298
  102. package/dist/{chunk-4U4TKZFR.js → chunk-WT5TRMO4.js} +51 -26
  103. package/dist/{chunk-XWMSPJYN.js → chunk-WURGVOZJ.js} +56 -12
  104. package/dist/{chunk-7WUZEB2M.js → chunk-XR3XJN2M.js} +2 -2
  105. package/dist/chunk-XW2UZICE.js +372 -0
  106. package/dist/{chunk-2AKYFREM.js → chunk-XZ6UFQ52.js} +11 -11
  107. package/dist/chunk-Y3JU5RPK.js +8 -0
  108. package/dist/chunk-YKRJTYNP.js +1143 -0
  109. package/dist/{chunk-PWWSIB2A.js → chunk-ZGIGW4ZG.js} +5 -5
  110. package/dist/cli/index.js +34 -36
  111. package/dist/{clio-QQCMTUZE.js → clio-L2P7S2R2.js} +9 -9
  112. package/dist/{code-nav-GUPM6766.js → code-nav-B5LNX4KU.js} +25 -25
  113. package/dist/{components-TNIKXCBH.js → components-63MMQKUT.js} +6 -6
  114. package/dist/{config-IIM7YOD3.js → config-YXARKGTX.js} +70 -67
  115. package/dist/{configure-4ZM5HWJX.js → configure-LMVQJ46J.js} +47 -35
  116. package/dist/{context-OL5P3HEP.js → context-7HJEWTTP.js} +87 -44
  117. package/dist/{context-44BZLJ3J.js → context-XSZKKFBW.js} +14 -14
  118. package/dist/{context-AIDVQKMW.js → context-YG2LZDYZ.js} +60 -58
  119. package/dist/{context-clear-OQV76MYP.js → context-clear-AC5NXHM2.js} +57 -55
  120. package/dist/{context-index-HP2JFUWA.js → context-index-KKTPRV5G.js} +3 -3
  121. package/dist/{context-map-INTXD54D.js → context-map-T7ROR5D5.js} +4 -4
  122. package/dist/{context-working-set-ZUW3EGLS.js → context-working-set-F4Q4J3NS.js} +12 -10
  123. package/dist/{detail-UXPWRANG.js → detail-H73BEF2N.js} +58 -56
  124. package/dist/{dispatch-runner-P3ZW6G77.js → dispatch-runner-3RY5FSJC.js} +74 -72
  125. package/dist/{doctor-JJVGPZWT.js → doctor-EQYJOGUG.js} +44 -30
  126. package/dist/{eval-V2RTN3UH.js → eval-4P7O6CCE.js} +109 -46
  127. package/dist/{evidence-35PYWGSO.js → evidence-D6GUSYJW.js} +57 -55
  128. package/dist/{evidence-CIGGKI6J.js → evidence-O76QF7TZ.js} +62 -59
  129. package/dist/{evolve-33SM3NJP.js → evolve-H47BCETS.js} +58 -56
  130. package/dist/{extensions-YVRHX6ZI.js → extensions-NNL3ZOCU.js} +98 -20
  131. package/dist/{fleet-LFO7SIPC.js → fleet-KMNS6NOM.js} +106 -99
  132. package/dist/{fleet-commands-RLK72GU3.js → fleet-commands-DOWSYCBX.js} +14 -14
  133. package/dist/{fleet-decisions-3SBSCTCW.js → fleet-decisions-S3PTZV2D.js} +9 -9
  134. package/dist/{fleet-graph-JZIBCGMW.js → fleet-graph-F2DE2TME.js} +26 -24
  135. package/dist/{fleet-inspect-2L5YGGZJ.js → fleet-inspect-EN2Q6IVB.js} +60 -57
  136. package/dist/{fleet-preflight-QRSHIIDE.js → fleet-preflight-FRLETDD3.js} +3 -3
  137. package/dist/{fleet-validate-LIAVKDUU.js → fleet-validate-B2XDLS57.js} +28 -29
  138. package/dist/{fleet-verify-JIK3OQZR.js → fleet-verify-4JKUWGJ7.js} +57 -55
  139. package/dist/{fleet-view-IWHYGQKK.js → fleet-view-BHJFW26B.js} +60 -57
  140. package/dist/{init-NJEDOTQW.js → init-XAT5N5YM.js} +79 -74
  141. package/dist/interop-FVECHFKG.js +246 -0
  142. package/dist/{inventory-74UL7UHU.js → inventory-7KFQGLCV.js} +60 -57
  143. package/dist/library-NY2XOT75.js +492 -0
  144. package/dist/library-QAPAO23R.js +306 -0
  145. package/dist/library-import-5Y6MAS3R.js +183 -0
  146. package/dist/library-inventory-JT6HWITQ.js +56 -0
  147. package/dist/library-validation-EQUH25DC.js +42 -0
  148. package/dist/{memory-I76I5VUH.js → memory-DYVTTCP6.js} +58 -56
  149. package/dist/{models-D4YDIQZQ.js → models-MASFJ6Y2.js} +48 -36
  150. package/dist/{monitor-NKVD55HX.js → monitor-YMP4NXJJ.js} +64 -61
  151. package/dist/{orchestrator-I6OATVPK.js → orchestrator-AFQRRTEI.js} +3685 -1841
  152. package/dist/{panes-7BTYH3XQ.js → panes-D3Y2KFG5.js} +4 -4
  153. package/dist/{panes-WPOMEMRH.js → panes-NICTHQCV.js} +7 -7
  154. package/dist/{paths-J3KN7UAO.js → paths-PSFAUIGO.js} +5 -5
  155. package/dist/{preload-EJAWJEIO.js → preload-5Q7VXRFJ.js} +57 -55
  156. package/dist/{reset-4XMQKDNZ.js → reset-7NKZK7JN.js} +9 -9
  157. package/dist/{resources-TVYVXK3Q.js → resources-NILSIZAT.js} +94 -38
  158. package/dist/{run-OWQNNSJU.js → run-BPZGEBZV.js} +121 -105
  159. package/dist/{share-NPZZMUXG.js → share-EZ6ERBMH.js} +31 -28
  160. package/dist/skills-BTVVNYVM.js +100 -0
  161. package/dist/{skills-eval-J5TCKSJA.js → skills-eval-UY34MNK7.js} +110 -72
  162. package/dist/{skills-inventory-7II4DM57.js → skills-inventory-JDHSIA7I.js} +30 -25
  163. package/dist/{slash-commands-MDSDSWYF.js → slash-commands-K4FNQ2AT.js} +49 -46
  164. package/dist/{steer-S7D7IKPU.js → steer-2B3EQGFH.js} +4 -4
  165. package/dist/{support-5VAEC32W.js → support-L2SOL3IE.js} +7 -7
  166. package/dist/{targets-KILZEOCE.js → targets-44VKGFLN.js} +64 -58
  167. package/dist/{tasks-R6P6OV22.js → tasks-3KODKFU7.js} +12 -12
  168. package/dist/{terminal-lease-LZCG2KN3.js → terminal-lease-LXA7MMPO.js} +32 -19
  169. package/dist/{tools-6OCQ6SVB.js → tools-3UB7TEVR.js} +7 -7
  170. package/dist/{trace-JHLXWUMN.js → trace-TAMIU4OJ.js} +5 -4
  171. package/dist/{tui-primitives-RCY2HN7G.js → tui-primitives-A6MUW32V.js} +3 -2
  172. package/dist/{uninstall-FXYMFFRT.js → uninstall-QYVRPEM4.js} +9 -9
  173. package/dist/{upgrade-D2OZH6IQ.js → upgrade-7PMKM2JH.js} +15 -16
  174. package/dist/{usage-PIASNUS4.js → usage-6EQV7EQK.js} +70 -67
  175. package/dist/{verifiers-LTHUY2PX.js → verifiers-JLITWSHU.js} +15 -15
  176. package/dist/{verify-HYF7KBVE.js → verify-T7NAEVIG.js} +13 -13
  177. package/dist/{web-fetch-MQN4FH3X.js → web-fetch-W4TNW4Q7.js} +4 -4
  178. package/dist/{wiki-generate-RK7JQ5NP.js → wiki-generate-T2TJQJUA.js} +81 -76
  179. package/dist/{with-panes-OFTNAR4Y.js → with-panes-CHFC7HGI.js} +4 -4
  180. package/dist/worker/entry.js +283 -76
  181. package/docs/README.md +43 -0
  182. package/docs/architecture/architecture.md +8 -7
  183. package/docs/architecture/artifact-versions.md +3 -3
  184. package/docs/architecture/context-engine.md +35 -1
  185. package/docs/architecture/library.md +32 -0
  186. package/docs/architecture/middleware-and-components.md +1 -1
  187. package/docs/architecture/model-catalog.md +21 -1
  188. package/docs/architecture/pi-boundary.md +18 -0
  189. package/docs/architecture/prompt-envelope-and-tools.md +5 -5
  190. package/docs/architecture/safety-model.md +21 -2
  191. package/docs/architecture/session-lifecycle.md +12 -1
  192. package/docs/architecture/tui-design.md +108 -9
  193. package/docs/architecture/worker-context.md +106 -0
  194. package/docs/guide/authoring-plugins.md +160 -0
  195. package/docs/guide/built-in-agents.md +5 -5
  196. package/docs/guide/commands-and-modes.md +161 -56
  197. package/docs/guide/configuration-and-targets.md +1 -1
  198. package/docs/guide/configuration-reference.md +27 -34
  199. package/docs/guide/environment-variables.md +2 -2
  200. package/docs/guide/exit-codes-and-output.md +1 -1
  201. package/docs/guide/extensions-and-sharing.md +93 -53
  202. package/docs/guide/fleet-dispatch.md +31 -4
  203. package/docs/guide/glossary.md +1 -1
  204. package/docs/guide/harness-extensions.md +291 -0
  205. package/docs/guide/installation-and-lifecycle.md +9 -9
  206. package/docs/guide/interop.md +243 -0
  207. package/docs/guide/panes-and-files.md +3 -3
  208. package/docs/guide/plugins.md +80 -0
  209. package/docs/guide/resource-library.md +111 -45
  210. package/docs/guide/skills-marketplace.md +35 -72
  211. package/docs/guide/tool-usage.md +19 -7
  212. package/docs/guide/troubleshooting.md +1 -1
  213. package/docs/process/development-pipeline.md +14 -14
  214. package/docs/process/documentation-coverage.md +28 -1
  215. package/docs/process/documentation-guide.md +15 -7
  216. package/docs/process/eval-runner.md +8 -3
  217. package/docs/process/performance-methodology.md +1 -1
  218. package/docs/process/release-cut-checklist.md +4 -0
  219. package/docs/process/scientific-validation.md +23 -0
  220. package/evals/scalar-decision-machinery.ts +1 -1
  221. package/examples/extensions/README.md +67 -0
  222. package/examples/extensions/lab-status/clio-coder-extension.json +14 -0
  223. package/examples/extensions/lab-status/extension.mjs +68 -0
  224. package/examples/extensions/lab-status/jobs.synthetic.json +9 -0
  225. package/examples/extensions/measurements/clio-coder-extension.json +28 -0
  226. package/examples/extensions/measurements/summarize.cjs +23 -0
  227. package/library/README.md +109 -0
  228. package/library/_authoring/templates/agent/README.md +28 -0
  229. package/library/_authoring/templates/agent/agents/benchmark-scout.md +30 -0
  230. package/library/_authoring/templates/agent/plugin.json +23 -0
  231. package/library/_authoring/templates/fleet/README.md +29 -0
  232. package/library/_authoring/templates/fleet/fleets/pipeline-review.md +31 -0
  233. package/library/_authoring/templates/fleet/plugin.json +23 -0
  234. package/library/_authoring/templates/plugin/README.md +37 -0
  235. package/library/_authoring/templates/plugin/agents/data-curator.md +31 -0
  236. package/library/_authoring/templates/plugin/assets/curation-guide.md +22 -0
  237. package/library/_authoring/templates/plugin/plugin.json +42 -0
  238. package/library/_authoring/templates/plugin/prompts/inspect-dataset.md +15 -0
  239. package/library/_authoring/templates/plugin/skills/dataset-curation/SKILL.md +36 -0
  240. package/library/_authoring/templates/plugin/skills/dataset-curation/evals.md +17 -0
  241. package/library/_authoring/templates/prompt/README.md +28 -0
  242. package/library/_authoring/templates/prompt/plugin.json +23 -0
  243. package/library/_authoring/templates/prompt/prompts/paper-summary.md +26 -0
  244. package/library/_authoring/templates/skill/README.md +24 -0
  245. package/library/_authoring/templates/skill/SKILL.md +39 -0
  246. package/library/_authoring/templates/skill/evals.md +30 -0
  247. package/library/_authoring/templates/skill/plugin.json +23 -0
  248. package/library/agents/README.md +7 -0
  249. package/library/fleets/README.md +7 -0
  250. package/library/plugins/materio/README.md +137 -0
  251. package/library/plugins/materio/ai.iowarp.clio/agents/materio-lab-definer.md +208 -0
  252. package/library/plugins/materio/ai.iowarp.clio/agents/materio-literature-reviewer.md +308 -0
  253. package/library/plugins/materio/ai.iowarp.clio/agents/materio-research-explorer.md +249 -0
  254. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-executor.md +416 -0
  255. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-verifier.md +60 -0
  256. package/library/plugins/materio/ai.iowarp.clio/agents/materio-workflow-planner.md +238 -0
  257. package/library/plugins/materio/ai.iowarp.clio/fleets/materio-execute-task.md +50 -0
  258. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/add-task.md +66 -0
  259. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/archive-task.md +65 -0
  260. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/checkpoint.md +26 -0
  261. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-research-tasks.md +230 -0
  262. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-virtual-lab.md +181 -0
  263. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/execute-task.md +292 -0
  264. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/help.md +129 -0
  265. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/identify-research.md +206 -0
  266. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/literature-review.md +201 -0
  267. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/pause-research.md +12 -0
  268. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/progress.md +105 -0
  269. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/remove-task.md +63 -0
  270. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/resume-research.md +64 -0
  271. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/settings.md +16 -0
  272. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/status.md +92 -0
  273. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/upload-data.md +104 -0
  274. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/wtfp.md +145 -0
  275. package/library/plugins/materio/ai.iowarp.clio/references/execution.md +56 -0
  276. package/library/plugins/materio/ai.iowarp.portability/provenance.json +9 -0
  277. package/library/plugins/materio/assets/actions/add-task.md +86 -0
  278. package/library/plugins/materio/assets/actions/archive-task.md +84 -0
  279. package/library/plugins/materio/assets/actions/checkpoint.md +47 -0
  280. package/library/plugins/materio/assets/actions/define-research-tasks.md +228 -0
  281. package/library/plugins/materio/assets/actions/define-virtual-lab.md +179 -0
  282. package/library/plugins/materio/assets/actions/execute-task.md +290 -0
  283. package/library/plugins/materio/assets/actions/help.md +140 -0
  284. package/library/plugins/materio/assets/actions/identify-research.md +204 -0
  285. package/library/plugins/materio/assets/actions/literature-review.md +199 -0
  286. package/library/plugins/materio/assets/actions/pause-research.md +34 -0
  287. package/library/plugins/materio/assets/actions/progress.md +125 -0
  288. package/library/plugins/materio/assets/actions/remove-task.md +82 -0
  289. package/library/plugins/materio/assets/actions/resume-research.md +84 -0
  290. package/library/plugins/materio/assets/actions/settings.md +38 -0
  291. package/library/plugins/materio/assets/actions/status.md +112 -0
  292. package/library/plugins/materio/assets/actions/upload-data.md +123 -0
  293. package/library/plugins/materio/assets/actions/wtfp.md +179 -0
  294. package/library/plugins/materio/assets/references/research-domains.md +134 -0
  295. package/library/plugins/materio/assets/references/research-policy.md +77 -0
  296. package/library/plugins/materio/assets/references/traditional-workflows.md +146 -0
  297. package/library/plugins/materio/assets/scripts/check_physics.py +271 -0
  298. package/library/plugins/materio/assets/scripts/check_scripts.py +248 -0
  299. package/library/plugins/materio/assets/scripts/project_plugin.py +165 -0
  300. package/library/plugins/materio/assets/scripts/research_state.py +400 -0
  301. package/library/plugins/materio/assets/scripts/verify_citations.py +616 -0
  302. package/library/plugins/materio/assets/templates/RESEARCH.md +39 -0
  303. package/library/plugins/materio/assets/templates/VIRTUAL-LAB.md +120 -0
  304. package/library/plugins/materio/assets/templates/WORKFLOW.md +42 -0
  305. package/library/plugins/materio/assets/templates/config.json +5 -0
  306. package/library/plugins/materio/evals/scripts.yaml +29 -0
  307. package/library/plugins/materio/plugin.json +530 -0
  308. package/library/plugins/materio/skills/materio-lab-definer/SKILL.md +74 -0
  309. package/library/plugins/materio/skills/materio-literature-reviewer/SKILL.md +64 -0
  310. package/library/plugins/materio/skills/materio-research-explorer/SKILL.md +74 -0
  311. package/library/plugins/materio/skills/materio-task-executor/SKILL.md +214 -0
  312. package/library/plugins/materio/skills/materio-task-verifier/SKILL.md +46 -0
  313. package/library/plugins/materio/skills/materio-workflow-planner/SKILL.md +79 -0
  314. package/library/plugins/materio/tests/test_check_physics.py +139 -0
  315. package/library/plugins/materio/tests/test_check_scripts.py +140 -0
  316. package/library/plugins/materio/tests/test_research_state.py +291 -0
  317. package/library/plugins/materio/tests/test_verify_citations.py +337 -0
  318. package/library/prompts/README.md +7 -0
  319. package/library/registry.yaml +921 -0
  320. package/library/skills/README.md +120 -0
  321. package/{skills → library/skills}/coding/ast-grep/SKILL.md +1 -1
  322. package/{skills → library/skills}/coding/ast-grep/evals.md +1 -1
  323. package/library/skills/coding/ast-grep/plugin.json +23 -0
  324. package/{skills → library/skills}/coding/coding-standards/SKILL.md +1 -1
  325. package/{skills → library/skills}/coding/coding-standards/evals.md +1 -1
  326. package/library/skills/coding/coding-standards/plugin.json +23 -0
  327. package/{skills → library/skills}/coding/prototype/SKILL.md +1 -1
  328. package/{skills → library/skills}/coding/prototype/evals.md +1 -1
  329. package/library/skills/coding/prototype/plugin.json +23 -0
  330. package/{skills → library/skills}/coding/tdd/SKILL.md +1 -1
  331. package/{skills → library/skills}/coding/tdd/evals.md +1 -1
  332. package/library/skills/coding/tdd/plugin.json +23 -0
  333. package/{skills → library/skills}/context/context-handoff/SKILL.md +1 -1
  334. package/{skills → library/skills}/context/context-handoff/evals.md +1 -1
  335. package/library/skills/context/context-handoff/plugin.json +23 -0
  336. package/{skills → library/skills}/context/context-prime/SKILL.md +1 -1
  337. package/{skills → library/skills}/context/context-prime/evals.md +1 -1
  338. package/library/skills/context/context-prime/plugin.json +23 -0
  339. package/{skills → library/skills}/git/branch-closeout/SKILL.md +1 -1
  340. package/library/skills/git/branch-closeout/plugin.json +23 -0
  341. package/{skills → library/skills}/git/file-ticket/SKILL.md +1 -1
  342. package/library/skills/git/file-ticket/plugin.json +23 -0
  343. package/{skills → library/skills}/git/fix-issue/SKILL.md +1 -1
  344. package/library/skills/git/fix-issue/plugin.json +23 -0
  345. package/{skills → library/skills}/git/resolve-merge-conflicts/SKILL.md +1 -1
  346. package/{skills → library/skills}/git/resolve-merge-conflicts/evals.md +1 -1
  347. package/library/skills/git/resolve-merge-conflicts/plugin.json +23 -0
  348. package/{skills → library/skills}/git/ship/SKILL.md +1 -1
  349. package/library/skills/git/ship/plugin.json +23 -0
  350. package/{skills → library/skills}/git/worktree-create/SKILL.md +1 -1
  351. package/library/skills/git/worktree-create/plugin.json +23 -0
  352. package/{skills → library/skills}/git/worktree-merge/SKILL.md +1 -1
  353. package/library/skills/git/worktree-merge/plugin.json +23 -0
  354. package/{skills → library/skills}/meta/clio-coder-dev/SKILL.md +1 -1
  355. package/{skills → library/skills}/meta/clio-coder-dev/evals.md +1 -1
  356. package/library/skills/meta/clio-coder-dev/plugin.json +23 -0
  357. package/{skills → library/skills}/meta/clio-coder-test/SKILL.md +1 -1
  358. package/{skills → library/skills}/meta/clio-coder-test/evals.md +1 -1
  359. package/library/skills/meta/clio-coder-test/plugin.json +23 -0
  360. package/{skills → library/skills}/meta/credentials/SKILL.md +1 -1
  361. package/{skills → library/skills}/meta/credentials/evals.md +1 -1
  362. package/library/skills/meta/credentials/plugin.json +23 -0
  363. package/library/skills/meta/find-skills/SKILL.md +85 -0
  364. package/library/skills/meta/find-skills/evals.md +65 -0
  365. package/library/skills/meta/find-skills/plugin.json +23 -0
  366. package/{skills → library/skills}/meta/herdr/SKILL.md +1 -1
  367. package/{skills → library/skills}/meta/herdr/evals.md +1 -1
  368. package/library/skills/meta/herdr/plugin.json +23 -0
  369. package/{skills → library/skills}/meta/skill-craft/SKILL.md +23 -9
  370. package/{skills → library/skills}/meta/skill-craft/evals.md +11 -3
  371. package/library/skills/meta/skill-craft/plugin.json +23 -0
  372. package/{skills → library/skills}/planning/archify/SKILL.md +13 -13
  373. package/library/skills/planning/archify/plugin.json +23 -0
  374. package/{skills → library/skills}/planning/architecture/SKILL.md +1 -1
  375. package/{skills → library/skills}/planning/architecture/evals.md +1 -1
  376. package/library/skills/planning/architecture/plugin.json +23 -0
  377. package/{skills → library/skills}/planning/backlog/SKILL.md +1 -1
  378. package/{skills → library/skills}/planning/backlog/evals.md +1 -1
  379. package/library/skills/planning/backlog/plugin.json +23 -0
  380. package/{skills → library/skills}/planning/prd/SKILL.md +1 -1
  381. package/{skills → library/skills}/planning/prd/evals.md +1 -1
  382. package/library/skills/planning/prd/plugin.json +23 -0
  383. package/{skills → library/skills}/planning/product-intent/SKILL.md +1 -1
  384. package/{skills → library/skills}/planning/product-intent/evals.md +1 -1
  385. package/library/skills/planning/product-intent/plugin.json +23 -0
  386. package/{skills → library/skills}/planning/tech-spec/SKILL.md +1 -1
  387. package/{skills → library/skills}/planning/tech-spec/evals.md +1 -1
  388. package/library/skills/planning/tech-spec/plugin.json +23 -0
  389. package/{skills → library/skills}/registry.yaml +7 -7
  390. package/{skills → library/skills}/remote.yaml +1 -1
  391. package/{skills → library/skills}/research/arxiv-literature/SKILL.md +1 -1
  392. package/{skills → library/skills}/research/arxiv-literature/evals.md +1 -1
  393. package/library/skills/research/arxiv-literature/plugin.json +23 -0
  394. package/{skills → library/skills}/research/experiment-protocol/SKILL.md +1 -1
  395. package/{skills → library/skills}/research/experiment-protocol/evals.md +1 -1
  396. package/library/skills/research/experiment-protocol/plugin.json +23 -0
  397. package/{skills → library/skills}/research/scientific-debugging/SKILL.md +1 -1
  398. package/{skills → library/skills}/research/scientific-debugging/evals.md +1 -1
  399. package/library/skills/research/scientific-debugging/plugin.json +23 -0
  400. package/{skills → library/skills}/research/scientific-modernization/SKILL.md +1 -1
  401. package/{skills → library/skills}/research/scientific-modernization/evals.md +1 -1
  402. package/library/skills/research/scientific-modernization/plugin.json +23 -0
  403. package/{skills → library/skills}/skill-marketplace.json +37 -37
  404. package/{skills → library/skills}/workflow/cut-it/SKILL.md +1 -1
  405. package/{skills → library/skills}/workflow/cut-it/evals.md +1 -1
  406. package/library/skills/workflow/cut-it/plugin.json +23 -0
  407. package/{skills → library/skills}/workflow/design-council/SKILL.md +1 -1
  408. package/{skills → library/skills}/workflow/design-council/evals.md +1 -1
  409. package/library/skills/workflow/design-council/plugin.json +23 -0
  410. package/{skills → library/skills}/workflow/grill-me/SKILL.md +1 -1
  411. package/{skills → library/skills}/workflow/grill-me/evals.md +1 -1
  412. package/library/skills/workflow/grill-me/plugin.json +23 -0
  413. package/{skills → library/skills}/workflow/workflow-distiller/SKILL.md +14 -11
  414. package/{skills → library/skills}/workflow/workflow-distiller/evals.md +14 -6
  415. package/library/skills/workflow/workflow-distiller/plugin.json +23 -0
  416. package/package.json +12 -5
  417. package/src/cli/agents.ts +1 -1
  418. package/src/cli/config-inspect.ts +1 -1
  419. package/src/cli/configure.ts +2 -2
  420. package/src/cli/eval.ts +40 -6
  421. package/src/cli/extensions.ts +74 -8
  422. package/src/cli/fleet-preflight.ts +2 -0
  423. package/src/cli/fleet.ts +2 -0
  424. package/src/cli/index.ts +1 -3
  425. package/src/cli/interop-inspect.ts +61 -33
  426. package/src/cli/interop.ts +79 -9
  427. package/src/cli/library-import.ts +139 -0
  428. package/src/cli/library.ts +418 -120
  429. package/src/cli/run.ts +26 -9
  430. package/src/cli/skills-eval.ts +43 -6
  431. package/src/cli/skills-inventory.ts +6 -2
  432. package/src/cli/skills.ts +44 -491
  433. package/src/core/bus-events.ts +5 -0
  434. package/src/core/defaults.ts +1 -1
  435. package/src/core/recent-models.ts +2 -2
  436. package/src/core/session-routing.ts +3 -3
  437. package/src/core/state-file-lock.ts +1 -1
  438. package/src/core/tool-names.ts +5 -0
  439. package/src/domains/agents/extension.ts +42 -6
  440. package/src/domains/agents/fleet-commands.ts +92 -1
  441. package/src/domains/agents/fleet-contract.ts +87 -19
  442. package/src/domains/agents/recipe.ts +5 -4
  443. package/src/domains/agents/registry.ts +80 -24
  444. package/src/domains/config/keybindings.ts +155 -95
  445. package/src/domains/context/worker/contract.ts +91 -0
  446. package/src/domains/context/worker/pressure.ts +120 -0
  447. package/src/domains/context/worker/recall.ts +62 -0
  448. package/src/domains/context/worker/select.ts +164 -0
  449. package/src/domains/context/worker/snapshot.ts +35 -0
  450. package/src/domains/context/worker/store.ts +16 -0
  451. package/src/domains/context/working-set/replay/synthetic.ts +2 -1
  452. package/src/domains/dispatch/active-route-planner.ts +2 -0
  453. package/src/domains/dispatch/backoff.ts +1 -0
  454. package/src/domains/dispatch/code-step.ts +12 -2
  455. package/src/domains/dispatch/contract.ts +3 -0
  456. package/src/domains/dispatch/execution-plan.ts +2 -0
  457. package/src/domains/dispatch/extension.ts +109 -27
  458. package/src/domains/dispatch/fleet-plan.ts +10 -0
  459. package/src/domains/dispatch/fleet-run.ts +1 -0
  460. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  461. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  462. package/src/domains/dispatch/state.ts +1 -0
  463. package/src/domains/dispatch/types.ts +5 -0
  464. package/src/domains/dispatch/validation.ts +12 -0
  465. package/src/domains/dispatch/workspace-checkpoint.ts +1 -1
  466. package/src/domains/evidence/failure-attribution.ts +1 -0
  467. package/src/domains/evidence/trust-status.ts +22 -3
  468. package/src/domains/extensions/command-schema.ts +145 -0
  469. package/src/domains/extensions/command-tools.ts +15 -0
  470. package/src/domains/extensions/compatibility.ts +7 -0
  471. package/src/domains/extensions/contract.ts +0 -4
  472. package/src/domains/extensions/discovery.ts +69 -205
  473. package/src/domains/extensions/extension.ts +0 -4
  474. package/src/domains/extensions/index.ts +1 -5
  475. package/src/domains/extensions/manager.ts +1 -6
  476. package/src/domains/extensions/operator-commands.ts +29 -0
  477. package/src/domains/extensions/operator-runtime.ts +483 -0
  478. package/src/domains/extensions/public-api.ts +53 -0
  479. package/src/domains/extensions/runtime-child.mjs +114 -0
  480. package/src/domains/extensions/runtime-process.ts +306 -0
  481. package/src/domains/extensions/runtime-schema.ts +146 -0
  482. package/src/domains/extensions/{resources.ts → snapshot-access.ts} +1 -17
  483. package/src/domains/extensions/snapshot.ts +4 -32
  484. package/src/domains/extensions/state.ts +5 -83
  485. package/src/domains/extensions/types.ts +33 -34
  486. package/src/domains/interop/adopt.ts +546 -0
  487. package/src/domains/interop/detect.ts +50 -12
  488. package/src/domains/interop/foreign.ts +554 -0
  489. package/src/domains/interop/import.ts +277 -0
  490. package/src/domains/interop/index.ts +24 -0
  491. package/src/domains/interop/install.ts +6 -0
  492. package/src/domains/interop/inventory.ts +351 -0
  493. package/src/domains/interop/projection.ts +360 -0
  494. package/src/domains/interop/registry.ts +106 -3
  495. package/src/domains/interop/types.ts +51 -0
  496. package/src/domains/lifecycle/migrations/index.ts +0 -2
  497. package/src/domains/lifecycle/naming-resources.ts +1 -1
  498. package/src/domains/middleware/marketplace-offer.ts +1 -1
  499. package/src/domains/mux/contract.ts +1 -1
  500. package/src/domains/plugins/catalog.ts +204 -0
  501. package/src/domains/plugins/contract.ts +24 -0
  502. package/src/domains/plugins/discovery.ts +316 -0
  503. package/src/domains/plugins/extension.ts +40 -0
  504. package/src/domains/plugins/index.ts +77 -0
  505. package/src/domains/plugins/integrity.ts +6 -0
  506. package/src/domains/plugins/manifest.ts +3 -0
  507. package/src/domains/plugins/resources.ts +102 -0
  508. package/src/domains/plugins/state.ts +753 -0
  509. package/src/domains/plugins/types.ts +217 -0
  510. package/src/domains/prompts/extension.ts +9 -2
  511. package/src/domains/prompts/fragments/operating/skills.md +10 -10
  512. package/src/domains/resources/common-loader.ts +9 -6
  513. package/src/domains/resources/index.ts +67 -0
  514. package/src/domains/resources/library-actions.ts +836 -0
  515. package/src/domains/resources/library-evals.ts +38 -0
  516. package/src/domains/resources/library-inventory.ts +1048 -0
  517. package/src/domains/resources/library-types.ts +50 -0
  518. package/src/domains/resources/library-validation.ts +634 -0
  519. package/src/domains/resources/library.ts +437 -156
  520. package/src/domains/resources/package-references.ts +66 -0
  521. package/src/domains/resources/prompts/loader.ts +75 -41
  522. package/src/domains/resources/skills/install.ts +2 -2
  523. package/src/domains/resources/skills/loader.ts +77 -22
  524. package/src/domains/resources/skills/marketplace.ts +48 -57
  525. package/src/domains/resources/skills/promotion.ts +2 -2
  526. package/src/domains/resources/skills/provenance-pin.ts +17 -4
  527. package/src/domains/safety/action-classifier.ts +2 -2
  528. package/src/domains/safety/default-path-policy.ts +3 -1
  529. package/src/domains/safety/policy-engine.ts +1 -1
  530. package/src/domains/safety/protected-artifacts.ts +21 -5
  531. package/src/domains/safety/skill-authority.ts +5 -2
  532. package/src/domains/share/archive.ts +1 -1
  533. package/src/engine/apis/openai-completions.ts +52 -2
  534. package/src/engine/notices/pi-tui-LICENSE +21 -0
  535. package/src/engine/tui.ts +3 -0
  536. package/src/engine/worker-runtime.ts +58 -14
  537. package/src/engine/worker-tools.ts +5 -0
  538. package/src/entry/orchestrator.ts +26 -5
  539. package/src/entry/plugin-reload.ts +18 -0
  540. package/src/interactive/application-controller.ts +67 -21
  541. package/src/interactive/chat-loop.ts +32 -5
  542. package/src/interactive/chat-panel.ts +5 -1
  543. package/src/interactive/clio-editor.ts +53 -21
  544. package/src/interactive/command-output.ts +56 -1
  545. package/src/interactive/editor-submit.ts +65 -28
  546. package/src/interactive/fleet-run-preview.ts +2 -0
  547. package/src/interactive/follow-up-queue-panel.ts +3 -3
  548. package/src/interactive/footer/dashboard.ts +4 -1
  549. package/src/interactive/footer/notifications.ts +2 -2
  550. package/src/interactive/footer/widgets.ts +2 -2
  551. package/src/interactive/interactive-application.ts +209 -21
  552. package/src/interactive/interactive-input-runtime.ts +254 -7
  553. package/src/interactive/interactive-presentation.ts +41 -12
  554. package/src/interactive/interactive-slash-runtime.ts +37 -8
  555. package/src/interactive/keybinding-manager.ts +156 -79
  556. package/src/interactive/keyboard-owner.ts +37 -0
  557. package/src/interactive/leader-key.ts +49 -102
  558. package/src/interactive/leader-menu.ts +45 -0
  559. package/src/interactive/overlay-ask-user-lifecycle.ts +9 -1
  560. package/src/interactive/overlay-frame.ts +15 -0
  561. package/src/interactive/overlay-key-routing.ts +46 -47
  562. package/src/interactive/overlay-lifecycle.ts +30 -15
  563. package/src/interactive/overlay-resource-openers.ts +56 -46
  564. package/src/interactive/overlays/ask-user.ts +630 -556
  565. package/src/interactive/overlays/extension-panel.ts +70 -0
  566. package/src/interactive/overlays/extensions.ts +28 -5
  567. package/src/interactive/overlays/fleet-run-approval.ts +7 -3
  568. package/src/interactive/overlays/help-reference.ts +89 -40
  569. package/src/interactive/overlays/interop.ts +122 -3
  570. package/src/interactive/overlays/keybinding-detail.ts +2 -2
  571. package/src/interactive/overlays/library-lifecycle.ts +90 -0
  572. package/src/interactive/overlays/library-model.ts +574 -0
  573. package/src/interactive/overlays/library-review.ts +557 -0
  574. package/src/interactive/overlays/library-tabs.ts +3 -15
  575. package/src/interactive/overlays/library.ts +602 -0
  576. package/src/interactive/overlays/list-overlay.ts +218 -39
  577. package/src/interactive/overlays/model-selector.ts +28 -25
  578. package/src/interactive/overlays/session-selector.ts +9 -3
  579. package/src/interactive/overlays/settings.ts +25 -18
  580. package/src/interactive/overlays/tree-selector.ts +16 -11
  581. package/src/interactive/permission-hint.ts +13 -0
  582. package/src/interactive/permission-overlay.ts +77 -28
  583. package/src/interactive/prompt-source-label.ts +21 -0
  584. package/src/interactive/renderers/reference-card.ts +35 -0
  585. package/src/interactive/renderers/worker-entry.ts +35 -3
  586. package/src/interactive/slash-autocomplete.ts +99 -1
  587. package/src/interactive/slash-commands.ts +390 -67
  588. package/src/interactive/slash-spec.ts +0 -1
  589. package/src/interactive/terminal-lease.ts +44 -12
  590. package/src/interactive/turn-queues.ts +8 -7
  591. package/src/interactive/turn-runtime.ts +1 -1
  592. package/src/interactive/view/view-overlay.ts +19 -14
  593. package/src/interactive/welcome-dashboard.ts +525 -408
  594. package/src/tools/bootstrap.ts +8 -0
  595. package/src/tools/builtin-tool-catalog.ts +7 -2
  596. package/src/tools/context/index.ts +58 -5
  597. package/src/tools/context/library.ts +465 -0
  598. package/src/tools/context/surface.ts +20 -6
  599. package/src/tools/core-bootstrap.ts +3 -0
  600. package/src/tools/dispatch-admission.ts +24 -1
  601. package/src/tools/dispatch-arguments.ts +8 -0
  602. package/src/tools/dispatch-plan.ts +32 -0
  603. package/src/tools/dispatch-schema.ts +31 -1
  604. package/src/tools/dispatch-types.ts +3 -0
  605. package/src/tools/dispatch.ts +1 -1
  606. package/src/tools/harness-extensions.ts +169 -0
  607. package/src/tools/observation.ts +4 -0
  608. package/src/tools/policy.ts +7 -1
  609. package/src/tools/registry.ts +19 -1
  610. package/src/tools/worker-evidence.ts +5 -0
  611. package/src/worker/context-seed.ts +192 -0
  612. package/src/worker/entry.ts +1 -0
  613. package/src/worker/spec-contract.ts +8 -1
  614. package/dist/chunk-3UW3KU4A.js +0 -21
  615. package/dist/chunk-536HXRFE.js +0 -1257
  616. package/dist/chunk-B3MOMLJ4.js +0 -433
  617. package/dist/chunk-CXQ37WJH.js +0 -45
  618. package/dist/chunk-KTFSFCVN.js +0 -46
  619. package/dist/chunk-QCOV5DFY.js +0 -911
  620. package/dist/chunk-QRFXEO6Y.js +0 -17
  621. package/dist/chunk-VAHLPXPY.js +0 -399
  622. package/dist/interop-RVCAYECG.js +0 -115
  623. package/dist/library-CTKZA7K3.js +0 -226
  624. package/dist/skills-OXFEAWMT.js +0 -510
  625. package/skills/README.md +0 -418
  626. package/skills/meta/find-skills/SKILL.md +0 -78
  627. package/skills/meta/find-skills/evals.md +0 -47
  628. package/src/domains/extensions/resource-path.ts +0 -27
  629. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +0 -27
  630. package/src/interactive/overlays/agents.ts +0 -70
  631. package/src/interactive/overlays/library-install-confirm.ts +0 -152
  632. package/src/interactive/overlays/prompts.ts +0 -89
  633. package/src/interactive/overlays/skills-hub.ts +0 -615
  634. /package/{skills → library/skills}/coding/ast-grep/references/rule_reference.md +0 -0
  635. /package/{skills → library/skills}/coding/prototype/references/LOGIC.md +0 -0
  636. /package/{skills → library/skills}/coding/prototype/references/UI.md +0 -0
  637. /package/{skills → library/skills}/coding/tdd/references/mocking.md +0 -0
  638. /package/{skills → library/skills}/coding/tdd/references/tests.md +0 -0
  639. /package/{skills → library/skills}/context/context-handoff/scripts/new-handoff.sh +0 -0
  640. /package/{skills → library/skills}/git/branch-closeout/evals.md +0 -0
  641. /package/{skills → library/skills}/git/branch-closeout/references/closeout-checklist.md +0 -0
  642. /package/{skills → library/skills}/git/file-ticket/assets/issue-template.md +0 -0
  643. /package/{skills → library/skills}/git/file-ticket/evals.md +0 -0
  644. /package/{skills → library/skills}/git/file-ticket/references/issue-discovery.md +0 -0
  645. /package/{skills → library/skills}/git/fix-issue/evals.md +0 -0
  646. /package/{skills → library/skills}/git/fix-issue/references/diagnosis-and-rca.md +0 -0
  647. /package/{skills → library/skills}/git/resolve-merge-conflicts/references/conflict-matrix.md +0 -0
  648. /package/{skills → library/skills}/git/ship/assets/pr-template.md +0 -0
  649. /package/{skills → library/skills}/git/ship/evals.md +0 -0
  650. /package/{skills → library/skills}/git/ship/references/remote-and-branch-policy.md +0 -0
  651. /package/{skills → library/skills}/git/worktree-create/evals.md +0 -0
  652. /package/{skills → library/skills}/git/worktree-create/references/worktree-setup.md +0 -0
  653. /package/{skills → library/skills}/git/worktree-merge/evals.md +0 -0
  654. /package/{skills → library/skills}/git/worktree-merge/references/merge-strategies.md +0 -0
  655. /package/{skills → library/skills}/meta/clio-coder-test/references/harness.md +0 -0
  656. /package/{skills → library/skills}/meta/clio-coder-test/references/test-map.md +0 -0
  657. /package/{skills → library/skills}/planning/archify/evals.md +0 -0
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env python3
2
+ """Generate a peer host package without claiming equivalent fleet enforcement."""
3
+ import argparse
4
+ import json
5
+ from pathlib import Path
6
+ import shutil
7
+ import sys
8
+
9
+
10
+ ACTION_ROLES = {
11
+ "identify-research": "research-explorer", "literature-review": "literature-reviewer",
12
+ "define-virtual-lab": "lab-definer", "define-research-tasks": "workflow-planner",
13
+ "execute-task": "task-executor",
14
+ }
15
+
16
+
17
+ def render_peer_guides(target, output, name):
18
+ """Bind logical action/skill requests to capabilities actually exported."""
19
+ actions = sorted(path.stem for path in (output / "assets/actions").glob("*.md"))
20
+ invocations = {}
21
+ for action in actions:
22
+ skill = name + "-" + ACTION_ROLES.get(action, "research-explorer")
23
+ invocations[action] = ({"kind": "skill", "name": skill, "request": action}
24
+ if target == "codex" else {"kind": "command", "name": f"/{name}:{action}"})
25
+ paths = list((output / "assets/actions").glob("*.md")) + list((output / "skills").glob("*/SKILL.md"))
26
+ for path in paths:
27
+ text = path.read_text()
28
+ if target in {"claude", "gemini"}:
29
+ for action in actions:
30
+ skill = name + "-" + ACTION_ROLES.get(action, "research-explorer")
31
+ text = text.replace(f"Run {action} using the {skill} skill", f"/{name}:{action}")
32
+ text = text.replace("this standard package registers no slash commands",
33
+ "this native package registers the command routes shown below")
34
+ text = text.replace("actual skill invocation vocabulary", "native command vocabulary")
35
+ if path.parent.name == "actions":
36
+ role = ACTION_ROLES.get(path.stem)
37
+ if target == "claude" and role:
38
+ binding = (f"\n## Native role binding\n\nThe interactive orchestrator dispatches the registered agent `{name}:{role}`\n"
39
+ f"for the `{name}-{role}` scientific skill. After a checkpoint, dispatch that\n"
40
+ "same registered agent again with the complete transcript, prior outputs and\n"
41
+ "actual researcher answer. Skill names identify instructions, not agent IDs.\n"
42
+ "A worker returns the checkpoint and does not dispatch or interview.\n")
43
+ if role == "task-executor":
44
+ binding += (f"For the separate read-only artifact review, dispatch the registered agent `{name}:task-verifier`.\n"
45
+ "Give it no write grant and preserve any host grounding limitations.\n")
46
+ elif target in {"codex", "gemini"}:
47
+ binding = ("\n## Host role execution\n\nThis export registers no named agents. Apply the role's installed skill in the\n"
48
+ "main conversation, or give that skill and complete context to a generic worker\n"
49
+ "only when the host supports delegation. The interactive assistant owns every\n"
50
+ "researcher question and resumes the role with the actual answer.\n")
51
+ else:
52
+ binding = ""
53
+ text += binding
54
+ path.write_text(text)
55
+ return invocations
56
+
57
+
58
+ def project(target, output, source=None):
59
+ source = Path(source or Path(__file__).resolve().parents[2]).resolve(strict=True)
60
+ output = Path(output).absolute()
61
+ if output.exists() or output.is_symlink():
62
+ raise ValueError("projection output must not already exist")
63
+ output = output.resolve()
64
+ if source == output or source in output.parents:
65
+ raise ValueError("projection output must be outside the canonical bundle")
66
+ manifest = json.loads((source / "plugin.json").read_text())
67
+ output.mkdir(parents=True)
68
+ try:
69
+ for directory in ("skills", "assets"):
70
+ for path in (source / directory).rglob("*"):
71
+ if path.is_symlink():
72
+ raise ValueError(f"projection refuses symbolic link: {path}")
73
+ shutil.copytree(source / directory, output / directory,
74
+ ignore=shutil.ignore_patterns("__pycache__", "*.pyc"))
75
+ metadata = {key: manifest[key] for key in ("name", "version", "description", "author", "repository", "keywords") if key in manifest}
76
+ report = {"target": target, "skills": 6, "commands": 0, "agents": 0,
77
+ "fleet": "instructions only; no native write-scope enforcement claimed",
78
+ "scripts": "local Python helpers; no automatic execution",
79
+ "validation": "generated structure; run target-native validation before publication"}
80
+ report["invocations"] = render_peer_guides(target, output, metadata["name"])
81
+ report["agent_bindings"] = {}
82
+ if target == "codex":
83
+ # Codex recognizes the current portable standard. Do not fabricate a
84
+ # separate proprietary manifest or pretend Clio recipes are native.
85
+ portable = {"$schema": manifest["$schema"], **metadata}
86
+ (output / "plugin.json").write_text(json.dumps(portable, indent=2) + "\n")
87
+ elif target == "claude":
88
+ directory = output / ".claude-plugin"
89
+ directory.mkdir()
90
+ (directory / "plugin.json").write_text(json.dumps(metadata, indent=2) + "\n")
91
+ commands = output / "commands"
92
+ agents = output / "agents"
93
+ commands.mkdir()
94
+ agents.mkdir()
95
+ roles = ACTION_ROLES
96
+ for guide in sorted((output / "assets/actions").glob("*.md")):
97
+ assignment = (f"Delegate this scientific role to the registered agent `{metadata['name']}:{roles[guide.stem]}`.\n"
98
+ if guide.stem in roles else "This action is owned by the interactive orchestrator.\n")
99
+ text = (f"---\ndescription: Materials characterization {guide.stem} workflow.\n---\n\n"
100
+ f"Read ${{CLAUDE_PLUGIN_ROOT}}/assets/actions/{guide.name} and follow that workflow.\n"
101
+ + assignment +
102
+ "Use AskUserQuestion for the interactive interview. If delegating, use the registered\n"
103
+ "materio role agent and include full context; workers return\n"
104
+ "checkpoint questions to this orchestrator. Use Bash only for approved local helper\n"
105
+ "calls; bind PACKAGE_ROOT to ${CLAUDE_PLUGIN_ROOT} in each call.\n"
106
+ "Arguments: $ARGUMENTS\n")
107
+ (commands / guide.name).write_text(text)
108
+ report["commands"] += 1
109
+ for skill in sorted((output / "skills").glob("*/SKILL.md")):
110
+ role = skill.parent.name.removeprefix("materio-")
111
+ tools = "Read, Glob, Grep" if role == "task-verifier" else "Read, Glob, Grep, Write, Edit, Bash, WebFetch"
112
+ text = (f"---\nname: {role}\ndescription: Materials characterization {role} role.\n"
113
+ f"tools: {tools}\n---\n\n"
114
+ f"Read ${{CLAUDE_PLUGIN_ROOT}}/skills/{skill.parent.name}/SKILL.md.\n"
115
+ "Apply its scientific contract within the caller's approved output paths.\n"
116
+ "Return structured complete, blocked, or needs_input with checkpoint kind\n"
117
+ "decision, human-action, or human-verify. Do not interview the researcher.\n"
118
+ "The caller owns state reconciliation, optional recording and paper gates.\n")
119
+ (agents / (role + ".md")).write_text(text)
120
+ report["agents"] += 1
121
+ report["agent_bindings"][role] = metadata["name"] + ":" + role
122
+ elif target == "gemini":
123
+ (output / "gemini-extension.json").write_text(json.dumps({
124
+ "name": metadata["name"], "version": metadata["version"],
125
+ "description": metadata["description"], "contextFileName": "GEMINI.md"
126
+ }, indent=2) + "\n")
127
+ (output / "GEMINI.md").write_text(
128
+ "# Materials characterization\n\nUse the installed materio skills and their relative action-guide links.\n"
129
+ "The interactive assistant owns researcher questions and state changes. Roles may\n"
130
+ "run inline when delegation is unavailable. No native fleet boundary is claimed.\n")
131
+ directory = output / "commands/materio"
132
+ directory.mkdir(parents=True)
133
+ for guide in sorted((output / "assets/actions").glob("*.md")):
134
+ text = (f"Use the installed materio skills to perform {guide.stem}. "
135
+ f"Read their relative link to assets/actions/{guide.name} and follow its contract. "
136
+ "Use the host conversation tool for researcher interviews. Delegate only with "
137
+ "available capabilities; otherwise perform the role inline. Arguments: {{args}}")
138
+ (directory / (guide.stem + ".toml")).write_text(
139
+ "description = " + json.dumps(f"Materials characterization {guide.stem}") + "\n"
140
+ "prompt = " + json.dumps(text) + "\n")
141
+ report["commands"] += 1
142
+ else:
143
+ raise ValueError(f"unsupported peer target: {target}")
144
+ (output / "capability-report.json").write_text(json.dumps(report, indent=2) + "\n")
145
+ return report
146
+ except Exception:
147
+ shutil.rmtree(output)
148
+ raise
149
+
150
+
151
+ def main():
152
+ parser = argparse.ArgumentParser(description=__doc__)
153
+ parser.add_argument("--target", choices=["codex", "claude", "gemini"], required=True)
154
+ parser.add_argument("--output", required=True)
155
+ args = parser.parse_args()
156
+ try:
157
+ print(json.dumps(project(args.target, args.output), indent=2))
158
+ return 0
159
+ except (OSError, ValueError) as error:
160
+ print(str(error), file=sys.stderr)
161
+ return 2
162
+
163
+
164
+ if __name__ == "__main__":
165
+ sys.exit(main())
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env python3
2
+ """Deterministic local research state operations. Python 3.10+, stdlib only.
3
+
4
+ This helper never initializes git, tags a checkpoint, or writes paper state.
5
+ It does not run experiments or generated analysis programs.
6
+ """
7
+ import argparse
8
+ import hashlib
9
+ import io
10
+ import json
11
+ import os
12
+ from pathlib import Path
13
+ import re
14
+ import shutil
15
+ import subprocess
16
+ import sys
17
+ import tarfile
18
+ import tempfile
19
+ from datetime import datetime, timezone
20
+ from uuid import uuid4
21
+
22
+ DEFAULTS = {"web_search": False, "auto_checkpoint": True, "commit_research": False}
23
+ PRESERVED = {"data", "checkpoints"}
24
+ ARCHIVE_MANIFEST = ".snapshot-manifest.json"
25
+
26
+
27
+ def unique_object(pairs):
28
+ result = {}
29
+ for key, value in pairs:
30
+ if key in result:
31
+ raise ValueError(f"duplicate JSON key: {key}")
32
+ result[key] = value
33
+ return result
34
+
35
+
36
+ def research_root(project):
37
+ project = Path(project).resolve(strict=True)
38
+ root = project / ".research"
39
+ if root.is_symlink():
40
+ raise ValueError(".research must be a real directory, not a symlink")
41
+ return root
42
+
43
+
44
+ def config(root):
45
+ path = root / "config.json"
46
+ result = dict(DEFAULTS)
47
+ if path.is_symlink():
48
+ raise ValueError("config.json must not be a symlink")
49
+ if path.exists():
50
+ value = json.loads(path.read_text(), object_pairs_hook=unique_object)
51
+ if not isinstance(value, dict):
52
+ raise ValueError("research config must be a JSON object")
53
+ for key in DEFAULTS:
54
+ if key in value and type(value[key]) is not bool:
55
+ raise ValueError(f"{key} must be a JSON boolean")
56
+ result.update(value)
57
+ return result
58
+
59
+
60
+ def contained(root, relative, allow_missing=False):
61
+ relative = Path(relative)
62
+ if relative.is_absolute() or ".." in relative.parts or not relative.parts:
63
+ raise ValueError(f"invalid relative research path: {relative}")
64
+ path = root
65
+ for part in relative.parts:
66
+ path = path / part
67
+ if path.is_symlink():
68
+ raise ValueError(f"symlink is not permitted: {path}")
69
+ if not allow_missing and not path.exists():
70
+ raise ValueError(f"missing research path: {path}")
71
+ return path
72
+
73
+
74
+ def task_number(value):
75
+ if not re.fullmatch(r"[0-9]+", str(value)) or int(value) < 1:
76
+ raise ValueError("task must be a positive decimal integer")
77
+ return f"{int(value):02d}"
78
+
79
+
80
+ def workflow(root):
81
+ path = root / "WORKFLOW.md"
82
+ if not path.exists():
83
+ return [], []
84
+ text = contained(root, "WORKFLOW.md").read_text()
85
+ active_text, _, archive_text = text.partition("## Archived Tasks")
86
+ def parse(text):
87
+ matches = list(re.finditer(r"^### Task ([0-9]+):[^\n]*", text, re.M))
88
+ return [(task_number(m.group(1)), text[m.start():matches[i + 1].start() if i + 1 < len(matches) else len(text)]) for i, m in enumerate(matches)]
89
+ active, archived = parse(active_text), parse(archive_text)
90
+ ids = [number for number, _ in active + archived]
91
+ if len(set(ids)) != len(ids):
92
+ raise ValueError("duplicate task identity in WORKFLOW.md")
93
+ return active, archived
94
+
95
+
96
+ def next_task(root):
97
+ active, archived = workflow(root)
98
+ ids = [int(number) for number, _ in active + archived]
99
+ tasks = root / "tasks"
100
+ if tasks.exists():
101
+ contained(root, "tasks")
102
+ for path in tasks.iterdir():
103
+ m = re.fullmatch(r"task-([0-9]+)", path.name)
104
+ if m:
105
+ ids.append(int(m.group(1)))
106
+ return task_number(max(ids, default=0) + 1)
107
+
108
+
109
+ def validate_workflow(root):
110
+ active, archived = workflow(root)
111
+ ids = {number for number, _ in active}
112
+ archived_ids = {number for number, _ in archived}
113
+ graph = {}
114
+ for number, block in active:
115
+ match = re.search(r"^[-*] \*\*Dependencies\*\*:\s*(.*)$", block, re.M)
116
+ refs = [task_number(value) for value in re.findall(r"Task\s+([0-9]+)", match.group(1) if match else "")]
117
+ for ref in refs:
118
+ if ref not in ids:
119
+ kind = "archived" if ref in archived_ids else "missing"
120
+ raise ValueError(f"Task {number} depends on {kind} Task {ref}")
121
+ graph[number] = refs
122
+ visiting, visited = set(), set()
123
+ def visit(number):
124
+ if number in visiting:
125
+ raise ValueError(f"dependency cycle at Task {number}")
126
+ if number in visited:
127
+ return
128
+ visiting.add(number)
129
+ for ref in graph[number]:
130
+ visit(ref)
131
+ visiting.remove(number)
132
+ visited.add(number)
133
+ for number in graph:
134
+ visit(number)
135
+ return {"active": list(graph), "archived": sorted(archived_ids), "dependencies": graph}
136
+
137
+
138
+ def next_ready_task(root):
139
+ """Choose a pending/in-progress task by workflow order and completed inputs."""
140
+ graph = validate_workflow(root)["dependencies"]
141
+ active, _ = workflow(root)
142
+ statuses = {}
143
+ for number, block in active:
144
+ match = re.search(r"^[-*] \*\*Status\*\*:\s*(.*)$", block, re.M)
145
+ status = re.sub(r"^[^a-zA-Z]+", "", match.group(1) if match else "").lower()
146
+ statuses[number] = status.split()[0] if status else "unspecified"
147
+ blocked = []
148
+ for number, _ in active:
149
+ if statuses[number] not in {"pending", "in-progress"}:
150
+ continue
151
+ unsettled = [dependency for dependency in graph[number] if statuses[dependency] != "complete"]
152
+ if not unsettled:
153
+ return {"id": number, "status": statuses[number], "blocked": blocked}
154
+ blocked.append({"id": number, "dependencies": unsettled})
155
+ return {"id": None, "reason": "no dependency-ready pending task", "blocked": blocked}
156
+
157
+
158
+ def snapshot_files(root):
159
+ files = {}
160
+ for base, directories, names in os.walk(root, followlinks=False):
161
+ base = Path(base)
162
+ if base == root:
163
+ directories[:] = [name for name in directories if name not in PRESERVED]
164
+ for name in directories:
165
+ if (base / name).is_symlink():
166
+ raise ValueError(f"snapshot refuses symlink: {base / name}")
167
+ for name in names:
168
+ path = base / name
169
+ relative = path.relative_to(root).as_posix()
170
+ if base == root and name in PRESERVED:
171
+ continue
172
+ if path == root / ARCHIVE_MANIFEST:
173
+ raise ValueError(f"reserved snapshot filename: {ARCHIVE_MANIFEST}")
174
+ if path.is_symlink() or not path.is_file():
175
+ raise ValueError(f"snapshot needs regular files: {path}")
176
+ files[relative] = path.read_bytes()
177
+ return files
178
+
179
+
180
+ def checkpoint_save(root, label):
181
+ if not re.fullmatch(r"[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}", label):
182
+ raise ValueError("checkpoint label must be 1–64 path-safe characters")
183
+ if not root.is_dir():
184
+ raise ValueError("research state is not initialized")
185
+ directory = contained(root, "checkpoints", allow_missing=True)
186
+ directory.mkdir(exist_ok=True)
187
+ files = snapshot_files(root)
188
+ directories = []
189
+ for base, names, _ in os.walk(root, followlinks=False):
190
+ if Path(base) == root:
191
+ names[:] = [name for name in names if name not in PRESERVED]
192
+ directories.extend((Path(base) / name).relative_to(root).as_posix() for name in names)
193
+ modes = {name: (root / name).stat().st_mode & 0o777 for name in files}
194
+ manifest = {"version": 1, "files": {name: hashlib.sha256(data).hexdigest() for name, data in files.items()},
195
+ "directories": sorted(directories), "modes": modes}
196
+ name = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S.%fZ") + "-" + label + "-" + uuid4().hex[:8] + ".tgz"
197
+ destination = directory / name
198
+ created = False
199
+ try:
200
+ with destination.open("xb") as output:
201
+ created = True
202
+ with tarfile.open(fileobj=output, mode="w:gz") as archive:
203
+ for relative, data in sorted({**files, ARCHIVE_MANIFEST: json.dumps(manifest).encode()}.items()):
204
+ member = tarfile.TarInfo(relative)
205
+ member.size, member.mode = len(data), 0o600
206
+ archive.addfile(member, io.BytesIO(data))
207
+ except Exception:
208
+ if created:
209
+ destination.unlink(missing_ok=True)
210
+ raise
211
+ return {"checkpoint": name, "files": len(files), "excluded": sorted(PRESERVED)}
212
+
213
+
214
+ def checkpoint_read(root, name):
215
+ if not re.fullmatch(r"[a-zA-Z0-9][a-zA-Z0-9._-]*\.tgz", name):
216
+ raise ValueError("checkpoint must be a filename listed by checkpoint list")
217
+ path = contained(root, "checkpoints/" + name)
218
+ files = {}
219
+ with tarfile.open(path, "r:gz") as archive:
220
+ for member in archive:
221
+ relative = Path(member.name)
222
+ if member.name in files or relative.is_absolute() or ".." in relative.parts or not relative.parts:
223
+ raise ValueError(f"invalid or duplicate archive member: {member.name}")
224
+ if relative.parts[0] in PRESERVED or not member.isfile():
225
+ raise ValueError(f"archive member is not permitted: {member.name}")
226
+ if relative.as_posix() != member.name:
227
+ raise ValueError(f"noncanonical archive member: {member.name}")
228
+ files[member.name] = archive.extractfile(member).read()
229
+ if ARCHIVE_MANIFEST not in files:
230
+ raise ValueError("checkpoint has no integrity manifest")
231
+ manifest = json.loads(files.pop(ARCHIVE_MANIFEST), object_pairs_hook=unique_object)
232
+ observed = {key: hashlib.sha256(value).hexdigest() for key, value in files.items()}
233
+ if not isinstance(manifest, dict) or manifest.get("version") != 1 or manifest.get("files") != observed:
234
+ raise ValueError("checkpoint content integrity mismatch")
235
+ directories = manifest.get("directories", [])
236
+ modes = manifest.get("modes", {})
237
+ if not isinstance(directories, list) or not isinstance(modes, dict):
238
+ raise ValueError("invalid snapshot directory or mode inventory")
239
+ for directory in directories:
240
+ if not isinstance(directory, str):
241
+ raise ValueError("invalid snapshot directory")
242
+ relative = Path(directory)
243
+ if relative.is_absolute() or ".." in relative.parts or not relative.parts or relative.parts[0] in PRESERVED or relative.as_posix() != directory:
244
+ raise ValueError(f"invalid snapshot directory: {directory}")
245
+ if any(name not in files or type(mode) is not int or mode < 0 or mode > 0o777 for name, mode in modes.items()):
246
+ raise ValueError("invalid snapshot mode")
247
+ return files, directories, modes
248
+
249
+
250
+ def checkpoint_restore(root, name, confirmed):
251
+ if not confirmed:
252
+ raise ValueError("restore requires --confirmed after researcher confirmation")
253
+ archive_name = name
254
+ files, directories, modes = checkpoint_read(root, name)
255
+ # Validate and stage before touching current state. Data and checkpoints are
256
+ # moved, never traversed or copied, and rollback restores the original root.
257
+ stage = Path(tempfile.mkdtemp(prefix=".research-restore-", dir=root.parent))
258
+ backup = Path(tempfile.mkdtemp(prefix=".research-previous-", dir=root.parent))
259
+ backup.rmdir()
260
+ moved = []
261
+ swapped = False
262
+ try:
263
+ for directory in directories:
264
+ (stage / directory).mkdir(parents=True, exist_ok=True)
265
+ for relative, data in files.items():
266
+ path = stage / relative
267
+ path.parent.mkdir(parents=True, exist_ok=True)
268
+ path.write_bytes(data)
269
+ path.chmod(modes.get(relative, 0o600))
270
+ root.rename(backup)
271
+ swapped = True
272
+ for name in sorted(PRESERVED):
273
+ if (backup / name).exists() or (backup / name).is_symlink():
274
+ (backup / name).rename(stage / name)
275
+ moved.append(name)
276
+ stage.rename(root)
277
+ except Exception:
278
+ if swapped:
279
+ for name in reversed(moved):
280
+ (stage / name).rename(backup / name)
281
+ backup.rename(root)
282
+ raise
283
+ finally:
284
+ if stage.exists():
285
+ shutil.rmtree(stage)
286
+ shutil.rmtree(backup)
287
+ return {"restored": archive_name, "files": len(files), "preserved": sorted(PRESERVED)}
288
+
289
+
290
+ def record(root, message, paths):
291
+ if not config(root)["commit_research"]:
292
+ return {"recorded": False, "reason": "commit_research is false"}
293
+ project = root.parent
294
+ def git(*argv, check=True):
295
+ return subprocess.run(["git", "-C", str(project), *argv], text=True, capture_output=True, check=check)
296
+ git("rev-parse", "--show-toplevel")
297
+ if git("diff", "--cached", "--name-only").stdout.strip():
298
+ raise ValueError("optional record refused: unrelated or preexisting staged changes")
299
+ selected = []
300
+ for value in paths:
301
+ relative = Path(value)
302
+ if not relative.parts or relative.parts[0] != ".research":
303
+ raise ValueError("optional record accepts only explicit .research files")
304
+ path = contained(root, Path(*relative.parts[1:]))
305
+ if not path.is_file():
306
+ raise ValueError("record needs named files, not directory staging")
307
+ selected.append(relative.as_posix())
308
+ if not selected:
309
+ return {"recorded": False, "reason": "no changed files supplied"}
310
+ git("add", "--", *selected)
311
+ if git("diff", "--cached", "--quiet", check=False).returncode == 0:
312
+ return {"recorded": False, "reason": "no staged changes"}
313
+ result = git("commit", "-m", message)
314
+ return {"recorded": True, "files": selected, "detail": result.stdout.strip()}
315
+
316
+
317
+ def register_copy(root, source):
318
+ source = Path(source).resolve(strict=True)
319
+ if not source.is_file():
320
+ raise ValueError("data registration needs an actual file")
321
+ directory = contained(root, "data", allow_missing=True)
322
+ directory.mkdir(exist_ok=True)
323
+ target = directory / source.name
324
+ data = source.read_bytes()
325
+ digest = hashlib.sha256(data).hexdigest()
326
+ if target.exists() or target.is_symlink():
327
+ if target.is_file() and not target.is_symlink() and target.read_bytes() == data:
328
+ return {"path": str(target), "source": str(source), "sha256": digest, "copied": False}
329
+ raise ValueError(f"data filename collision: {target.name}; choose a distinct name")
330
+ with target.open("xb") as output:
331
+ output.write(data)
332
+ return {"path": str(target), "source": str(source), "sha256": digest, "copied": True}
333
+
334
+
335
+ def main(argv=None):
336
+ parser = argparse.ArgumentParser(description=__doc__)
337
+ parser.add_argument("--project", default=".")
338
+ sub = parser.add_subparsers(dest="action", required=True)
339
+ sub.add_parser("init")
340
+ cfg = sub.add_parser("config")
341
+ cfg.add_argument("--key", choices=sorted(DEFAULTS))
342
+ sub.add_parser("next-task-id")
343
+ sub.add_parser("next-task")
344
+ sub.add_parser("validate-workflow")
345
+ sub.add_parser("task-dirs")
346
+ checkpoint = sub.add_parser("checkpoint")
347
+ checkpoint.add_argument("operation", choices=["save", "restore", "list"])
348
+ checkpoint.add_argument("name", nargs="?", default="manual")
349
+ checkpoint.add_argument("--confirmed", action="store_true")
350
+ rec = sub.add_parser("record")
351
+ rec.add_argument("--message", required=True)
352
+ rec.add_argument("--files", nargs="+", required=True)
353
+ copy = sub.add_parser("copy-data")
354
+ copy.add_argument("source")
355
+ args = parser.parse_args(argv)
356
+ try:
357
+ root = research_root(args.project)
358
+ if args.action == "init":
359
+ config(root)
360
+ root.mkdir(exist_ok=True)
361
+ for name in ("tasks", "data", "checkpoints"):
362
+ contained(root, name, allow_missing=True).mkdir(exist_ok=True)
363
+ if not (root / "config.json").exists():
364
+ with (root / "config.json").open("x") as output:
365
+ output.write(json.dumps(DEFAULTS, indent=2) + "\n")
366
+ result = {"initialized": True, "config": config(root)}
367
+ elif args.action == "config":
368
+ result = config(root)
369
+ if args.key:
370
+ result = result[args.key]
371
+ elif args.action == "next-task-id":
372
+ result = {"id": next_task(root)}
373
+ elif args.action == "next-task":
374
+ result = next_ready_task(root)
375
+ elif args.action in ("validate-workflow", "task-dirs"):
376
+ result = validate_workflow(root)
377
+ if args.action == "task-dirs":
378
+ for number in result["active"]:
379
+ contained(root, f"tasks/task-{number}", allow_missing=True).mkdir(parents=True, exist_ok=True)
380
+ elif args.action == "checkpoint":
381
+ if args.operation == "save":
382
+ result = checkpoint_save(root, args.name)
383
+ elif args.operation == "restore":
384
+ result = checkpoint_restore(root, args.name, args.confirmed)
385
+ else:
386
+ directory = contained(root, "checkpoints", allow_missing=True)
387
+ result = {"checkpoints": sorted(p.name for p in directory.glob("*.tgz") if p.is_file() and not p.is_symlink())}
388
+ elif args.action == "record":
389
+ result = record(root, args.message, args.files)
390
+ else:
391
+ result = register_copy(root, args.source)
392
+ print(json.dumps(result, indent=2))
393
+ return 0
394
+ except (ValueError, OSError, json.JSONDecodeError, tarfile.TarError, subprocess.CalledProcessError) as error:
395
+ print(json.dumps({"error": str(error)}), file=sys.stderr)
396
+ return 2
397
+
398
+
399
+ if __name__ == "__main__":
400
+ sys.exit(main())