@iowarp/clio-coder 0.4.5 → 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 (700) hide show
  1. package/.claude-plugin/marketplace.json +283 -0
  2. package/CHANGELOG.md +74 -0
  3. package/CONTRIBUTING.md +116 -38
  4. package/NOTICE +24 -0
  5. package/README.md +341 -682
  6. package/dist/{acp-H3CU2HBQ.js → acp-W3Y3TRHD.js} +12 -12
  7. package/dist/{agents-IXQQZ7BD.js → agents-J4ICNLQ3.js} +57 -56
  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-R7KYF7N3.js → auth-X2UJUMOC.js} +25 -25
  13. package/dist/{builtins-CRFDQUVP.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-SE4ZKILO.js → chunk-3XE4NRLF.js} +30 -9
  20. package/dist/{chunk-YYB3MC65.js → chunk-4MFBBY2Z.js} +3 -3
  21. package/dist/{chunk-5VTJP36Q.js → chunk-4N2RZ4TO.js} +2 -2
  22. package/dist/{chunk-FKIOX6DS.js → chunk-4QKAITQT.js} +10 -5
  23. package/dist/chunk-4UHVS5T7.js +207 -0
  24. package/dist/{chunk-VLPTKCKT.js → chunk-5AJPUR72.js} +6 -6
  25. package/dist/{chunk-5CY4Q6QI.js → chunk-5EQO5NWP.js} +105 -3
  26. package/dist/{chunk-RXIOCVBZ.js → chunk-65BGHOUR.js} +8 -5
  27. package/dist/{chunk-T53XI6I7.js → chunk-6CA2BHOR.js} +2 -2
  28. package/dist/{chunk-HL26ADLH.js → chunk-6CB2IL4N.js} +2 -1
  29. package/dist/{chunk-HR3HPQ76.js → chunk-6LRLOJHQ.js} +3 -3
  30. package/dist/{chunk-HXHFDHB6.js → chunk-6TAATXXH.js} +6 -6
  31. package/dist/{chunk-WFKDPU7U.js → chunk-6YHPAAZR.js} +3 -3
  32. package/dist/{chunk-ZMZQEBKI.js → chunk-7EEGBKV4.js} +11 -11
  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-MDU3C27C.js → chunk-BO4XV5VX.js} +8 -8
  36. package/dist/{chunk-KF6GFW6O.js → chunk-BQQ5MXUC.js} +11 -11
  37. package/dist/{chunk-K6RDB7IA.js → chunk-C3G5PNUO.js} +23 -23
  38. package/dist/{chunk-SRZOW5L2.js → chunk-C6GEXX4L.js} +1 -1
  39. package/dist/{chunk-U2JOLB7O.js → chunk-CE64C5K5.js} +227 -72
  40. package/dist/chunk-CP3HIR5H.js +2119 -0
  41. package/dist/{chunk-BBV5TKE6.js → chunk-CPXGJI2A.js} +2 -2
  42. package/dist/{chunk-5DDOTTG4.js → chunk-CULVKYTK.js} +5 -5
  43. package/dist/{chunk-F34AR6O3.js → chunk-D2T66PDV.js} +6 -6
  44. package/dist/{chunk-NF3BK5WR.js → chunk-DACXIVVF.js} +5 -5
  45. package/dist/{chunk-4SVIVOMC.js → chunk-DLIYANB7.js} +20 -15
  46. package/dist/{chunk-E3BQTQUP.js → chunk-DO7M3LSX.js} +9 -9
  47. package/dist/{chunk-2QPI3TR3.js → chunk-DVJL77SO.js} +2 -2
  48. package/dist/chunk-EM2WNQS2.js +93 -0
  49. package/dist/{chunk-ODUTYZIU.js → chunk-EUEXGXXR.js} +5 -5
  50. package/dist/{chunk-UL36QJX6.js → chunk-EUZRMP4Y.js} +18 -16
  51. package/dist/{chunk-R6MAYTMS.js → chunk-G4LGUTOE.js} +4 -4
  52. package/dist/{chunk-CBSKDFWL.js → chunk-GEVQNST4.js} +2 -2
  53. package/dist/{chunk-XXBQKW32.js → chunk-GFQ7P2UF.js} +7 -7
  54. package/dist/{chunk-SBZX6ARC.js → chunk-GI5RRMAH.js} +14 -14
  55. package/dist/{chunk-KDWLXVMN.js → chunk-GVZFCJHE.js} +343 -113
  56. package/dist/{chunk-633EXGZA.js → chunk-GXIWHXDB.js} +3 -3
  57. package/dist/{chunk-LUL5Z66S.js → chunk-HOX4YZ2K.js} +6 -5
  58. package/dist/chunk-HRAKUPIH.js +57 -0
  59. package/dist/{chunk-KYKNBD4Y.js → chunk-IJMW64DX.js} +978 -258
  60. package/dist/{chunk-DIMRLNIC.js → chunk-IMOD2YPV.js} +16 -9
  61. package/dist/{chunk-6CDNRHWH.js → chunk-IQCNVLO6.js} +28 -8
  62. package/dist/{chunk-UTUNT5QL.js → chunk-ISNCCX42.js} +9 -9
  63. package/dist/{chunk-RLTT5GVY.js → chunk-IZYTT3CD.js} +9 -5
  64. package/dist/{chunk-5ZMXGW7P.js → chunk-KAFMW7WM.js} +4 -85
  65. package/dist/chunk-KKEYGFX4.js +915 -0
  66. package/dist/{chunk-HHVJNVUJ.js → chunk-KS7ETA3P.js} +2 -2
  67. package/dist/{chunk-UXAC2FX4.js → chunk-L3Z5ANCV.js} +7 -7
  68. package/dist/{chunk-EHCPSZJF.js → chunk-LBFQMYS3.js} +2 -2
  69. package/dist/{chunk-QEQISF75.js → chunk-LK2FN5JY.js} +1 -1
  70. package/dist/{chunk-URBGEOH3.js → chunk-M6Z2V6YU.js} +5 -5
  71. package/dist/{chunk-DRD2A54W.js → chunk-MBJO5VNZ.js} +18 -18
  72. package/dist/chunk-MNQN3X6Y.js +595 -0
  73. package/dist/{chunk-GXCCHKN6.js → chunk-MZHXENL7.js} +7 -7
  74. package/dist/chunk-MZNWZUJM.js +1801 -0
  75. package/dist/{chunk-7YJWEF2L.js → chunk-N37QC5FV.js} +5 -5
  76. package/dist/{chunk-WLMSOT73.js → chunk-NCCQ6DVS.js} +7 -7
  77. package/dist/{chunk-TZ7MFRG4.js → chunk-NO7J45X6.js} +170 -53
  78. package/dist/chunk-OH3YYA3B.js +15 -0
  79. package/dist/{chunk-22PQ4TX4.js → chunk-P4DL2LM5.js} +16 -77
  80. package/dist/{chunk-R6MICQYU.js → chunk-PFLOULP3.js} +4 -4
  81. package/dist/{chunk-MC3JSVR6.js → chunk-QJMRYTCX.js} +7 -7
  82. package/dist/{chunk-ILJ7DWGE.js → chunk-QKWL7SYE.js} +12 -12
  83. package/dist/chunk-R2CT5YDO.js +66 -0
  84. package/dist/chunk-RFCKPS2V.js +26 -0
  85. package/dist/{chunk-ONRTXOZY.js → chunk-RTLNFZMD.js} +12 -4
  86. package/dist/{chunk-U7H5WRG5.js → chunk-RXFPB32E.js} +8 -6
  87. package/dist/{chunk-S32UQ5GL.js → chunk-SEDI5K5B.js} +18 -18
  88. package/dist/{chunk-ICO4TQ2F.js → chunk-SELG4SUR.js} +41 -25
  89. package/dist/{chunk-YEJIG7LN.js → chunk-SER7RRAE.js} +27 -832
  90. package/dist/{chunk-K2HL3GBL.js → chunk-T4TY5GG3.js} +165 -15
  91. package/dist/chunk-T7QQBNLH.js +691 -0
  92. package/dist/{chunk-HGSLRG33.js → chunk-TLTGZTXI.js} +3 -3
  93. package/dist/chunk-TZ6UVP2H.js +637 -0
  94. package/dist/{chunk-EWD5P3GK.js → chunk-TZHN5ITX.js} +13 -41
  95. package/dist/{chunk-7TKWWPD7.js → chunk-U3TPUXOQ.js} +398 -253
  96. package/dist/{chunk-GNQRWTMY.js → chunk-UA3W4FGC.js} +6 -6
  97. package/dist/{chunk-O2RQ7LCK.js → chunk-UA6W4XFJ.js} +2 -2
  98. package/dist/chunk-UWD3JD5X.js +709 -0
  99. package/dist/chunk-V4ZKOKRB.js +13433 -0
  100. package/dist/{chunk-NC4KV7EL.js → chunk-VCRVEDUC.js} +5 -5
  101. package/dist/{chunk-I7VLWRK2.js → chunk-VMATUZB6.js} +12 -10
  102. package/dist/{chunk-J2FYEQ5L.js → chunk-VTYHHQ57.js} +2 -2
  103. package/dist/chunk-WB7POC6M.js +891 -0
  104. package/dist/{chunk-GVYWZNRK.js → chunk-WBVKKTUT.js} +2 -2
  105. package/dist/{chunk-EHOSNVVM.js → chunk-WLHX3MM5.js} +6 -2
  106. package/dist/{chunk-SDWNDICN.js → chunk-WN552PKN.js} +573 -316
  107. package/dist/{chunk-TEG3RYVZ.js → chunk-WT5TRMO4.js} +51 -26
  108. package/dist/{chunk-NY6IWDVU.js → chunk-WURGVOZJ.js} +56 -12
  109. package/dist/{chunk-7WUZEB2M.js → chunk-XR3XJN2M.js} +2 -2
  110. package/dist/chunk-XW2UZICE.js +372 -0
  111. package/dist/{chunk-FSTIBAGM.js → chunk-XZ6UFQ52.js} +11 -11
  112. package/dist/chunk-Y3JU5RPK.js +8 -0
  113. package/dist/chunk-YKRJTYNP.js +1143 -0
  114. package/dist/{chunk-7HBHHVCK.js → chunk-YPRSNUTC.js} +2 -2
  115. package/dist/{chunk-PWWSIB2A.js → chunk-ZGIGW4ZG.js} +5 -5
  116. package/dist/cli/index.js +34 -36
  117. package/dist/{clio-5I2IBFYL.js → clio-L2P7S2R2.js} +9 -9
  118. package/dist/{code-nav-YXIAEZVS.js → code-nav-B5LNX4KU.js} +25 -25
  119. package/dist/{components-TNIKXCBH.js → components-63MMQKUT.js} +6 -6
  120. package/dist/{config-Y2JDJ3JJ.js → config-YXARKGTX.js} +81 -77
  121. package/dist/configure-LMVQJ46J.js +85 -0
  122. package/dist/{context-QQ53HSGJ.js → context-7HJEWTTP.js} +92 -48
  123. package/dist/{context-S2EEC3EJ.js → context-XSZKKFBW.js} +14 -14
  124. package/dist/{context-P5YSEO55.js → context-YG2LZDYZ.js} +67 -64
  125. package/dist/{context-clear-TMEQCOTH.js → context-clear-AC5NXHM2.js} +64 -61
  126. package/dist/{context-index-HP2JFUWA.js → context-index-KKTPRV5G.js} +3 -3
  127. package/dist/{context-map-INTXD54D.js → context-map-T7ROR5D5.js} +4 -4
  128. package/dist/{context-working-set-CNLSQN5K.js → context-working-set-F4Q4J3NS.js} +15 -12
  129. package/dist/{detail-5572VLBO.js → detail-H73BEF2N.js} +65 -62
  130. package/dist/{dispatch-runner-FRHD6P2O.js → dispatch-runner-3RY5FSJC.js} +83 -80
  131. package/dist/{doctor-N3LCM2LG.js → doctor-EQYJOGUG.js} +47 -32
  132. package/dist/{eval-BUU3ZOUZ.js → eval-4P7O6CCE.js} +114 -50
  133. package/dist/{evidence-DTGEN456.js → evidence-D6GUSYJW.js} +64 -61
  134. package/dist/{evidence-SQ5DNFEN.js → evidence-O76QF7TZ.js} +69 -65
  135. package/dist/{evolve-IJNUFZDS.js → evolve-H47BCETS.js} +65 -62
  136. package/dist/{extensions-YVRHX6ZI.js → extensions-NNL3ZOCU.js} +98 -20
  137. package/dist/{fleet-ZNNVSYFO.js → fleet-KMNS6NOM.js} +115 -107
  138. package/dist/{fleet-commands-5YE7NPJL.js → fleet-commands-DOWSYCBX.js} +15 -15
  139. package/dist/{fleet-decisions-3SBSCTCW.js → fleet-decisions-S3PTZV2D.js} +9 -9
  140. package/dist/{fleet-graph-6HHPWF5T.js → fleet-graph-F2DE2TME.js} +26 -24
  141. package/dist/{fleet-inspect-JEYMGCGC.js → fleet-inspect-EN2Q6IVB.js} +67 -63
  142. package/dist/{fleet-preflight-QRSHIIDE.js → fleet-preflight-FRLETDD3.js} +3 -3
  143. package/dist/{fleet-validate-4PM4GDDL.js → fleet-validate-B2XDLS57.js} +28 -29
  144. package/dist/{fleet-verify-NJDTHTO3.js → fleet-verify-4JKUWGJ7.js} +64 -61
  145. package/dist/{fleet-view-UP2BWQQY.js → fleet-view-BHJFW26B.js} +67 -63
  146. package/dist/{init-S3GZQ5ZF.js → init-XAT5N5YM.js} +86 -80
  147. package/dist/interop-FVECHFKG.js +246 -0
  148. package/dist/{inventory-K2OZ36YJ.js → inventory-7KFQGLCV.js} +67 -63
  149. package/dist/library-NY2XOT75.js +492 -0
  150. package/dist/library-QAPAO23R.js +306 -0
  151. package/dist/library-import-5Y6MAS3R.js +183 -0
  152. package/dist/library-inventory-JT6HWITQ.js +56 -0
  153. package/dist/library-validation-EQUH25DC.js +42 -0
  154. package/dist/{memory-OQOXQGYD.js → memory-DYVTTCP6.js} +65 -62
  155. package/dist/{models-3IK2Y5WE.js → models-MASFJ6Y2.js} +51 -38
  156. package/dist/{monitor-FTJLTKCQ.js → monitor-YMP4NXJJ.js} +73 -69
  157. package/dist/{orchestrator-N47O7SFD.js → orchestrator-AFQRRTEI.js} +4255 -2845
  158. package/dist/{panes-7BTYH3XQ.js → panes-D3Y2KFG5.js} +4 -4
  159. package/dist/{panes-WPOMEMRH.js → panes-NICTHQCV.js} +7 -7
  160. package/dist/{paths-J3KN7UAO.js → paths-PSFAUIGO.js} +5 -5
  161. package/dist/{preload-65U34NG6.js → preload-5Q7VXRFJ.js} +64 -61
  162. package/dist/{reset-MUVQDLNL.js → reset-7NKZK7JN.js} +11 -9
  163. package/dist/{resources-LM76COAO.js → resources-NILSIZAT.js} +94 -38
  164. package/dist/{run-3VFZQ33N.js → run-BPZGEBZV.js} +131 -114
  165. package/dist/{share-4JUB4BL7.js → share-EZ6ERBMH.js} +31 -28
  166. package/dist/skills-BTVVNYVM.js +100 -0
  167. package/dist/{skills-eval-G6T57L7M.js → skills-eval-UY34MNK7.js} +117 -78
  168. package/dist/{skills-inventory-WLM46PJH.js → skills-inventory-JDHSIA7I.js} +30 -25
  169. package/dist/{slash-commands-GBARG3Y7.js → slash-commands-K4FNQ2AT.js} +53 -49
  170. package/dist/{steer-S7D7IKPU.js → steer-2B3EQGFH.js} +4 -4
  171. package/dist/{support-5VAEC32W.js → support-L2SOL3IE.js} +7 -7
  172. package/dist/{targets-N5REUETU.js → targets-44VKGFLN.js} +69 -47
  173. package/dist/{tasks-6BVY5YZF.js → tasks-3KODKFU7.js} +14 -14
  174. package/dist/{terminal-lease-57UEOJKS.js → terminal-lease-LXA7MMPO.js} +32 -19
  175. package/dist/{tools-6OCQ6SVB.js → tools-3UB7TEVR.js} +7 -7
  176. package/dist/{trace-JHLXWUMN.js → trace-TAMIU4OJ.js} +5 -4
  177. package/dist/{tui-primitives-RCY2HN7G.js → tui-primitives-A6MUW32V.js} +3 -2
  178. package/dist/{uninstall-FXYMFFRT.js → uninstall-QYVRPEM4.js} +9 -9
  179. package/dist/{upgrade-4HD5HAIV.js → upgrade-7PMKM2JH.js} +17 -18
  180. package/dist/{usage-4GWM2WWP.js → usage-6EQV7EQK.js} +77 -73
  181. package/dist/{verifiers-GSKWKWVG.js → verifiers-JLITWSHU.js} +16 -16
  182. package/dist/{verify-3AS3ULCY.js → verify-T7NAEVIG.js} +13 -13
  183. package/dist/{web-fetch-MQN4FH3X.js → web-fetch-W4TNW4Q7.js} +4 -4
  184. package/dist/{wiki-generate-7BV7XWIY.js → wiki-generate-T2TJQJUA.js} +90 -84
  185. package/dist/{with-panes-OFTNAR4Y.js → with-panes-CHFC7HGI.js} +4 -4
  186. package/dist/worker/entry.js +297 -88
  187. package/docs/README.md +43 -0
  188. package/docs/architecture/architecture.md +8 -7
  189. package/docs/architecture/artifact-versions.md +3 -3
  190. package/docs/architecture/context-engine.md +36 -2
  191. package/docs/architecture/library.md +32 -0
  192. package/docs/architecture/middleware-and-components.md +1 -1
  193. package/docs/architecture/model-catalog.md +21 -1
  194. package/docs/architecture/pi-boundary.md +18 -0
  195. package/docs/architecture/prompt-envelope-and-tools.md +5 -5
  196. package/docs/architecture/safety-model.md +21 -2
  197. package/docs/architecture/session-lifecycle.md +12 -1
  198. package/docs/architecture/tui-design.md +153 -39
  199. package/docs/architecture/worker-context.md +106 -0
  200. package/docs/guide/authoring-plugins.md +160 -0
  201. package/docs/guide/built-in-agents.md +5 -5
  202. package/docs/guide/commands-and-modes.md +186 -80
  203. package/docs/guide/configuration-and-targets.md +123 -28
  204. package/docs/guide/configuration-reference.md +36 -38
  205. package/docs/guide/environment-variables.md +2 -2
  206. package/docs/guide/exit-codes-and-output.md +1 -1
  207. package/docs/guide/extensions-and-sharing.md +93 -53
  208. package/docs/guide/fleet-dispatch.md +32 -10
  209. package/docs/guide/glossary.md +2 -2
  210. package/docs/guide/harness-extensions.md +291 -0
  211. package/docs/guide/installation-and-lifecycle.md +53 -20
  212. package/docs/guide/interop.md +243 -0
  213. package/docs/guide/panes-and-files.md +3 -3
  214. package/docs/guide/plugins.md +80 -0
  215. package/docs/guide/resource-library.md +111 -45
  216. package/docs/guide/skills-marketplace.md +35 -72
  217. package/docs/guide/tool-usage.md +19 -7
  218. package/docs/guide/troubleshooting.md +1 -1
  219. package/docs/process/development-pipeline.md +15 -15
  220. package/docs/process/documentation-coverage.md +29 -2
  221. package/docs/process/documentation-guide.md +15 -7
  222. package/docs/process/eval-runner.md +8 -3
  223. package/docs/process/performance-methodology.md +1 -1
  224. package/docs/process/release-cut-checklist.md +22 -6
  225. package/docs/process/scientific-validation.md +23 -0
  226. package/evals/scalar-decision-machinery.ts +1 -1
  227. package/examples/extensions/README.md +67 -0
  228. package/examples/extensions/lab-status/clio-coder-extension.json +14 -0
  229. package/examples/extensions/lab-status/extension.mjs +68 -0
  230. package/examples/extensions/lab-status/jobs.synthetic.json +9 -0
  231. package/examples/extensions/measurements/clio-coder-extension.json +28 -0
  232. package/examples/extensions/measurements/summarize.cjs +23 -0
  233. package/library/README.md +109 -0
  234. package/library/_authoring/templates/agent/README.md +28 -0
  235. package/library/_authoring/templates/agent/agents/benchmark-scout.md +30 -0
  236. package/library/_authoring/templates/agent/plugin.json +23 -0
  237. package/library/_authoring/templates/fleet/README.md +29 -0
  238. package/library/_authoring/templates/fleet/fleets/pipeline-review.md +31 -0
  239. package/library/_authoring/templates/fleet/plugin.json +23 -0
  240. package/library/_authoring/templates/plugin/README.md +37 -0
  241. package/library/_authoring/templates/plugin/agents/data-curator.md +31 -0
  242. package/library/_authoring/templates/plugin/assets/curation-guide.md +22 -0
  243. package/library/_authoring/templates/plugin/plugin.json +42 -0
  244. package/library/_authoring/templates/plugin/prompts/inspect-dataset.md +15 -0
  245. package/library/_authoring/templates/plugin/skills/dataset-curation/SKILL.md +36 -0
  246. package/library/_authoring/templates/plugin/skills/dataset-curation/evals.md +17 -0
  247. package/library/_authoring/templates/prompt/README.md +28 -0
  248. package/library/_authoring/templates/prompt/plugin.json +23 -0
  249. package/library/_authoring/templates/prompt/prompts/paper-summary.md +26 -0
  250. package/library/_authoring/templates/skill/README.md +24 -0
  251. package/library/_authoring/templates/skill/SKILL.md +39 -0
  252. package/library/_authoring/templates/skill/evals.md +30 -0
  253. package/library/_authoring/templates/skill/plugin.json +23 -0
  254. package/library/agents/README.md +7 -0
  255. package/library/fleets/README.md +7 -0
  256. package/library/plugins/materio/README.md +137 -0
  257. package/library/plugins/materio/ai.iowarp.clio/agents/materio-lab-definer.md +208 -0
  258. package/library/plugins/materio/ai.iowarp.clio/agents/materio-literature-reviewer.md +308 -0
  259. package/library/plugins/materio/ai.iowarp.clio/agents/materio-research-explorer.md +249 -0
  260. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-executor.md +416 -0
  261. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-verifier.md +60 -0
  262. package/library/plugins/materio/ai.iowarp.clio/agents/materio-workflow-planner.md +238 -0
  263. package/library/plugins/materio/ai.iowarp.clio/fleets/materio-execute-task.md +50 -0
  264. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/add-task.md +66 -0
  265. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/archive-task.md +65 -0
  266. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/checkpoint.md +26 -0
  267. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-research-tasks.md +230 -0
  268. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-virtual-lab.md +181 -0
  269. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/execute-task.md +292 -0
  270. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/help.md +129 -0
  271. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/identify-research.md +206 -0
  272. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/literature-review.md +201 -0
  273. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/pause-research.md +12 -0
  274. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/progress.md +105 -0
  275. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/remove-task.md +63 -0
  276. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/resume-research.md +64 -0
  277. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/settings.md +16 -0
  278. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/status.md +92 -0
  279. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/upload-data.md +104 -0
  280. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/wtfp.md +145 -0
  281. package/library/plugins/materio/ai.iowarp.clio/references/execution.md +56 -0
  282. package/library/plugins/materio/ai.iowarp.portability/provenance.json +9 -0
  283. package/library/plugins/materio/assets/actions/add-task.md +86 -0
  284. package/library/plugins/materio/assets/actions/archive-task.md +84 -0
  285. package/library/plugins/materio/assets/actions/checkpoint.md +47 -0
  286. package/library/plugins/materio/assets/actions/define-research-tasks.md +228 -0
  287. package/library/plugins/materio/assets/actions/define-virtual-lab.md +179 -0
  288. package/library/plugins/materio/assets/actions/execute-task.md +290 -0
  289. package/library/plugins/materio/assets/actions/help.md +140 -0
  290. package/library/plugins/materio/assets/actions/identify-research.md +204 -0
  291. package/library/plugins/materio/assets/actions/literature-review.md +199 -0
  292. package/library/plugins/materio/assets/actions/pause-research.md +34 -0
  293. package/library/plugins/materio/assets/actions/progress.md +125 -0
  294. package/library/plugins/materio/assets/actions/remove-task.md +82 -0
  295. package/library/plugins/materio/assets/actions/resume-research.md +84 -0
  296. package/library/plugins/materio/assets/actions/settings.md +38 -0
  297. package/library/plugins/materio/assets/actions/status.md +112 -0
  298. package/library/plugins/materio/assets/actions/upload-data.md +123 -0
  299. package/library/plugins/materio/assets/actions/wtfp.md +179 -0
  300. package/library/plugins/materio/assets/references/research-domains.md +134 -0
  301. package/library/plugins/materio/assets/references/research-policy.md +77 -0
  302. package/library/plugins/materio/assets/references/traditional-workflows.md +146 -0
  303. package/library/plugins/materio/assets/scripts/check_physics.py +271 -0
  304. package/library/plugins/materio/assets/scripts/check_scripts.py +248 -0
  305. package/library/plugins/materio/assets/scripts/project_plugin.py +165 -0
  306. package/library/plugins/materio/assets/scripts/research_state.py +400 -0
  307. package/library/plugins/materio/assets/scripts/verify_citations.py +616 -0
  308. package/library/plugins/materio/assets/templates/RESEARCH.md +39 -0
  309. package/library/plugins/materio/assets/templates/VIRTUAL-LAB.md +120 -0
  310. package/library/plugins/materio/assets/templates/WORKFLOW.md +42 -0
  311. package/library/plugins/materio/assets/templates/config.json +5 -0
  312. package/library/plugins/materio/evals/scripts.yaml +29 -0
  313. package/library/plugins/materio/plugin.json +530 -0
  314. package/library/plugins/materio/skills/materio-lab-definer/SKILL.md +74 -0
  315. package/library/plugins/materio/skills/materio-literature-reviewer/SKILL.md +64 -0
  316. package/library/plugins/materio/skills/materio-research-explorer/SKILL.md +74 -0
  317. package/library/plugins/materio/skills/materio-task-executor/SKILL.md +214 -0
  318. package/library/plugins/materio/skills/materio-task-verifier/SKILL.md +46 -0
  319. package/library/plugins/materio/skills/materio-workflow-planner/SKILL.md +79 -0
  320. package/library/plugins/materio/tests/test_check_physics.py +139 -0
  321. package/library/plugins/materio/tests/test_check_scripts.py +140 -0
  322. package/library/plugins/materio/tests/test_research_state.py +291 -0
  323. package/library/plugins/materio/tests/test_verify_citations.py +337 -0
  324. package/library/prompts/README.md +7 -0
  325. package/library/registry.yaml +921 -0
  326. package/library/skills/README.md +120 -0
  327. package/{skills → library/skills}/coding/ast-grep/SKILL.md +1 -1
  328. package/{skills → library/skills}/coding/ast-grep/evals.md +1 -1
  329. package/library/skills/coding/ast-grep/plugin.json +23 -0
  330. package/{skills → library/skills}/coding/coding-standards/SKILL.md +1 -1
  331. package/{skills → library/skills}/coding/coding-standards/evals.md +1 -1
  332. package/library/skills/coding/coding-standards/plugin.json +23 -0
  333. package/{skills → library/skills}/coding/prototype/SKILL.md +1 -1
  334. package/{skills → library/skills}/coding/prototype/evals.md +1 -1
  335. package/library/skills/coding/prototype/plugin.json +23 -0
  336. package/{skills → library/skills}/coding/tdd/SKILL.md +1 -1
  337. package/{skills → library/skills}/coding/tdd/evals.md +1 -1
  338. package/library/skills/coding/tdd/plugin.json +23 -0
  339. package/{skills → library/skills}/context/context-handoff/SKILL.md +1 -1
  340. package/{skills → library/skills}/context/context-handoff/evals.md +1 -1
  341. package/library/skills/context/context-handoff/plugin.json +23 -0
  342. package/{skills → library/skills}/context/context-prime/SKILL.md +1 -1
  343. package/{skills → library/skills}/context/context-prime/evals.md +1 -1
  344. package/library/skills/context/context-prime/plugin.json +23 -0
  345. package/{skills → library/skills}/git/branch-closeout/SKILL.md +1 -1
  346. package/library/skills/git/branch-closeout/plugin.json +23 -0
  347. package/{skills → library/skills}/git/file-ticket/SKILL.md +1 -1
  348. package/library/skills/git/file-ticket/plugin.json +23 -0
  349. package/{skills → library/skills}/git/fix-issue/SKILL.md +1 -1
  350. package/library/skills/git/fix-issue/plugin.json +23 -0
  351. package/{skills → library/skills}/git/resolve-merge-conflicts/SKILL.md +1 -1
  352. package/{skills → library/skills}/git/resolve-merge-conflicts/evals.md +1 -1
  353. package/library/skills/git/resolve-merge-conflicts/plugin.json +23 -0
  354. package/{skills → library/skills}/git/ship/SKILL.md +1 -1
  355. package/library/skills/git/ship/plugin.json +23 -0
  356. package/{skills → library/skills}/git/worktree-create/SKILL.md +1 -1
  357. package/library/skills/git/worktree-create/plugin.json +23 -0
  358. package/{skills → library/skills}/git/worktree-merge/SKILL.md +1 -1
  359. package/library/skills/git/worktree-merge/plugin.json +23 -0
  360. package/{skills → library/skills}/meta/clio-coder-dev/SKILL.md +1 -1
  361. package/{skills → library/skills}/meta/clio-coder-dev/evals.md +1 -1
  362. package/library/skills/meta/clio-coder-dev/plugin.json +23 -0
  363. package/{skills → library/skills}/meta/clio-coder-test/SKILL.md +1 -1
  364. package/{skills → library/skills}/meta/clio-coder-test/evals.md +1 -1
  365. package/library/skills/meta/clio-coder-test/plugin.json +23 -0
  366. package/{skills → library/skills}/meta/credentials/SKILL.md +1 -1
  367. package/{skills → library/skills}/meta/credentials/evals.md +1 -1
  368. package/library/skills/meta/credentials/plugin.json +23 -0
  369. package/library/skills/meta/find-skills/SKILL.md +85 -0
  370. package/library/skills/meta/find-skills/evals.md +65 -0
  371. package/library/skills/meta/find-skills/plugin.json +23 -0
  372. package/{skills → library/skills}/meta/herdr/SKILL.md +1 -1
  373. package/{skills → library/skills}/meta/herdr/evals.md +1 -1
  374. package/library/skills/meta/herdr/plugin.json +23 -0
  375. package/{skills → library/skills}/meta/skill-craft/SKILL.md +23 -9
  376. package/{skills → library/skills}/meta/skill-craft/evals.md +11 -3
  377. package/library/skills/meta/skill-craft/plugin.json +23 -0
  378. package/{skills → library/skills}/planning/archify/SKILL.md +13 -13
  379. package/library/skills/planning/archify/plugin.json +23 -0
  380. package/{skills → library/skills}/planning/architecture/SKILL.md +1 -1
  381. package/{skills → library/skills}/planning/architecture/evals.md +1 -1
  382. package/library/skills/planning/architecture/plugin.json +23 -0
  383. package/{skills → library/skills}/planning/backlog/SKILL.md +1 -1
  384. package/{skills → library/skills}/planning/backlog/evals.md +1 -1
  385. package/library/skills/planning/backlog/plugin.json +23 -0
  386. package/{skills → library/skills}/planning/prd/SKILL.md +1 -1
  387. package/{skills → library/skills}/planning/prd/evals.md +1 -1
  388. package/library/skills/planning/prd/plugin.json +23 -0
  389. package/{skills → library/skills}/planning/product-intent/SKILL.md +1 -1
  390. package/{skills → library/skills}/planning/product-intent/evals.md +1 -1
  391. package/library/skills/planning/product-intent/plugin.json +23 -0
  392. package/{skills → library/skills}/planning/tech-spec/SKILL.md +1 -1
  393. package/{skills → library/skills}/planning/tech-spec/evals.md +1 -1
  394. package/library/skills/planning/tech-spec/plugin.json +23 -0
  395. package/{skills → library/skills}/registry.yaml +7 -7
  396. package/{skills → library/skills}/remote.yaml +1 -1
  397. package/{skills → library/skills}/research/arxiv-literature/SKILL.md +1 -1
  398. package/{skills → library/skills}/research/arxiv-literature/evals.md +1 -1
  399. package/library/skills/research/arxiv-literature/plugin.json +23 -0
  400. package/{skills → library/skills}/research/experiment-protocol/SKILL.md +1 -1
  401. package/{skills → library/skills}/research/experiment-protocol/evals.md +1 -1
  402. package/library/skills/research/experiment-protocol/plugin.json +23 -0
  403. package/{skills → library/skills}/research/scientific-debugging/SKILL.md +1 -1
  404. package/{skills → library/skills}/research/scientific-debugging/evals.md +1 -1
  405. package/library/skills/research/scientific-debugging/plugin.json +23 -0
  406. package/{skills → library/skills}/research/scientific-modernization/SKILL.md +1 -1
  407. package/{skills → library/skills}/research/scientific-modernization/evals.md +1 -1
  408. package/library/skills/research/scientific-modernization/plugin.json +23 -0
  409. package/{skills → library/skills}/skill-marketplace.json +37 -37
  410. package/{skills → library/skills}/workflow/cut-it/SKILL.md +1 -1
  411. package/{skills → library/skills}/workflow/cut-it/evals.md +1 -1
  412. package/library/skills/workflow/cut-it/plugin.json +23 -0
  413. package/{skills → library/skills}/workflow/design-council/SKILL.md +1 -1
  414. package/{skills → library/skills}/workflow/design-council/evals.md +1 -1
  415. package/library/skills/workflow/design-council/plugin.json +23 -0
  416. package/{skills → library/skills}/workflow/grill-me/SKILL.md +1 -1
  417. package/{skills → library/skills}/workflow/grill-me/evals.md +1 -1
  418. package/library/skills/workflow/grill-me/plugin.json +23 -0
  419. package/{skills → library/skills}/workflow/workflow-distiller/SKILL.md +14 -11
  420. package/{skills → library/skills}/workflow/workflow-distiller/evals.md +14 -6
  421. package/library/skills/workflow/workflow-distiller/plugin.json +23 -0
  422. package/package.json +12 -5
  423. package/src/cli/agents.ts +1 -1
  424. package/src/cli/ask.ts +10 -10
  425. package/src/cli/config-inspect.ts +1 -1
  426. package/src/cli/configure-editor.ts +51 -0
  427. package/src/cli/configure-interop.ts +1 -1
  428. package/src/cli/configure-oauth.ts +1 -1
  429. package/src/cli/configure-onboarding.ts +232 -96
  430. package/src/cli/configure-prompts.ts +76 -0
  431. package/src/cli/configure-quick.ts +274 -0
  432. package/src/cli/configure-target.ts +14 -2
  433. package/src/cli/configure.ts +415 -176
  434. package/src/cli/eval.ts +40 -6
  435. package/src/cli/extensions.ts +74 -8
  436. package/src/cli/fleet-preflight.ts +2 -0
  437. package/src/cli/fleet.ts +2 -0
  438. package/src/cli/index.ts +1 -3
  439. package/src/cli/interop-inspect.ts +61 -33
  440. package/src/cli/interop.ts +79 -9
  441. package/src/cli/library-import.ts +139 -0
  442. package/src/cli/library.ts +418 -120
  443. package/src/cli/oauth-manual-input.ts +1 -1
  444. package/src/cli/reset.ts +2 -0
  445. package/src/cli/run.ts +26 -9
  446. package/src/cli/select.ts +35 -4
  447. package/src/cli/skills-eval.ts +43 -6
  448. package/src/cli/skills-inventory.ts +6 -2
  449. package/src/cli/skills.ts +44 -491
  450. package/src/cli/upgrade.ts +2 -2
  451. package/src/core/bus-events.ts +5 -0
  452. package/src/core/config.ts +6 -1
  453. package/src/core/defaults.ts +34 -12
  454. package/src/{interactive → core}/external-editor.ts +4 -4
  455. package/src/core/recent-models.ts +2 -2
  456. package/src/core/session-routing.ts +3 -3
  457. package/src/core/state-file-lock.ts +1 -1
  458. package/src/core/tool-names.ts +5 -0
  459. package/src/domains/agents/extension.ts +42 -6
  460. package/src/domains/agents/fleet-commands.ts +92 -1
  461. package/src/domains/agents/fleet-contract.ts +87 -19
  462. package/src/domains/agents/recipe.ts +5 -4
  463. package/src/domains/agents/registry.ts +80 -24
  464. package/src/domains/config/classify.ts +1 -1
  465. package/src/domains/config/keybindings.ts +156 -124
  466. package/src/domains/context/worker/contract.ts +91 -0
  467. package/src/domains/context/worker/pressure.ts +120 -0
  468. package/src/domains/context/worker/recall.ts +62 -0
  469. package/src/domains/context/worker/select.ts +164 -0
  470. package/src/domains/context/worker/snapshot.ts +35 -0
  471. package/src/domains/context/worker/store.ts +16 -0
  472. package/src/domains/context/working-set/replay/synthetic.ts +2 -1
  473. package/src/domains/dispatch/active-route-planner.ts +2 -0
  474. package/src/domains/dispatch/backoff.ts +1 -0
  475. package/src/domains/dispatch/code-step.ts +12 -2
  476. package/src/domains/dispatch/contract.ts +3 -0
  477. package/src/domains/dispatch/execution-plan.ts +2 -0
  478. package/src/domains/dispatch/extension.ts +109 -27
  479. package/src/domains/dispatch/fleet-plan.ts +10 -0
  480. package/src/domains/dispatch/fleet-run.ts +1 -0
  481. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  482. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  483. package/src/domains/dispatch/state.ts +1 -0
  484. package/src/domains/dispatch/types.ts +5 -0
  485. package/src/domains/dispatch/validation.ts +12 -0
  486. package/src/domains/dispatch/workspace-checkpoint.ts +1 -1
  487. package/src/domains/evidence/failure-attribution.ts +1 -0
  488. package/src/domains/evidence/trust-status.ts +22 -3
  489. package/src/domains/extensions/command-schema.ts +145 -0
  490. package/src/domains/extensions/command-tools.ts +15 -0
  491. package/src/domains/extensions/compatibility.ts +7 -0
  492. package/src/domains/extensions/contract.ts +0 -4
  493. package/src/domains/extensions/discovery.ts +69 -205
  494. package/src/domains/extensions/extension.ts +0 -4
  495. package/src/domains/extensions/index.ts +1 -5
  496. package/src/domains/extensions/manager.ts +1 -6
  497. package/src/domains/extensions/operator-commands.ts +29 -0
  498. package/src/domains/extensions/operator-runtime.ts +483 -0
  499. package/src/domains/extensions/public-api.ts +53 -0
  500. package/src/domains/extensions/runtime-child.mjs +114 -0
  501. package/src/domains/extensions/runtime-process.ts +306 -0
  502. package/src/domains/extensions/runtime-schema.ts +146 -0
  503. package/src/domains/extensions/{resources.ts → snapshot-access.ts} +1 -17
  504. package/src/domains/extensions/snapshot.ts +4 -32
  505. package/src/domains/extensions/state.ts +5 -83
  506. package/src/domains/extensions/types.ts +33 -34
  507. package/src/domains/interop/adopt.ts +546 -0
  508. package/src/domains/interop/detect.ts +50 -12
  509. package/src/domains/interop/foreign.ts +554 -0
  510. package/src/domains/interop/import.ts +277 -0
  511. package/src/domains/interop/index.ts +24 -0
  512. package/src/domains/interop/install.ts +6 -0
  513. package/src/domains/interop/inventory.ts +351 -0
  514. package/src/domains/interop/projection.ts +360 -0
  515. package/src/domains/interop/registry.ts +106 -3
  516. package/src/domains/interop/types.ts +51 -0
  517. package/src/domains/lifecycle/migrations/index.ts +0 -2
  518. package/src/domains/lifecycle/naming-resources.ts +1 -1
  519. package/src/domains/middleware/marketplace-offer.ts +1 -1
  520. package/src/domains/mux/contract.ts +1 -1
  521. package/src/domains/plugins/catalog.ts +204 -0
  522. package/src/domains/plugins/contract.ts +24 -0
  523. package/src/domains/plugins/discovery.ts +316 -0
  524. package/src/domains/plugins/extension.ts +40 -0
  525. package/src/domains/plugins/index.ts +77 -0
  526. package/src/domains/plugins/integrity.ts +6 -0
  527. package/src/domains/plugins/manifest.ts +3 -0
  528. package/src/domains/plugins/resources.ts +102 -0
  529. package/src/domains/plugins/state.ts +753 -0
  530. package/src/domains/plugins/types.ts +217 -0
  531. package/src/domains/prompts/extension.ts +9 -2
  532. package/src/domains/prompts/fragments/operating/skills.md +10 -10
  533. package/src/domains/providers/probe/fingerprint.ts +13 -6
  534. package/src/domains/providers/probe/reasoning.ts +2 -0
  535. package/src/domains/providers/runtimes/common/probe-helpers.ts +23 -7
  536. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +7 -2
  537. package/src/domains/providers/runtimes/protocol/openai-compat.ts +10 -4
  538. package/src/domains/resources/common-loader.ts +9 -6
  539. package/src/domains/resources/index.ts +67 -0
  540. package/src/domains/resources/library-actions.ts +836 -0
  541. package/src/domains/resources/library-evals.ts +38 -0
  542. package/src/domains/resources/library-inventory.ts +1048 -0
  543. package/src/domains/resources/library-types.ts +50 -0
  544. package/src/domains/resources/library-validation.ts +634 -0
  545. package/src/domains/resources/library.ts +437 -156
  546. package/src/domains/resources/package-references.ts +66 -0
  547. package/src/domains/resources/prompts/loader.ts +75 -41
  548. package/src/domains/resources/skills/install.ts +2 -2
  549. package/src/domains/resources/skills/loader.ts +77 -22
  550. package/src/domains/resources/skills/marketplace.ts +48 -57
  551. package/src/domains/resources/skills/promotion.ts +2 -2
  552. package/src/domains/resources/skills/provenance-pin.ts +17 -4
  553. package/src/domains/safety/action-classifier.ts +2 -2
  554. package/src/domains/safety/default-path-policy.ts +3 -1
  555. package/src/domains/safety/policy-engine.ts +1 -1
  556. package/src/domains/safety/protected-artifacts.ts +21 -5
  557. package/src/domains/safety/skill-authority.ts +5 -2
  558. package/src/domains/share/archive.ts +1 -1
  559. package/src/engine/apis/openai-completions.ts +52 -2
  560. package/src/engine/notices/pi-tui-LICENSE +21 -0
  561. package/src/engine/tui.ts +3 -0
  562. package/src/engine/worker-runtime.ts +58 -14
  563. package/src/engine/worker-tools.ts +5 -0
  564. package/src/entry/orchestrator.ts +26 -5
  565. package/src/entry/plugin-reload.ts +18 -0
  566. package/src/interactive/application-controller.ts +68 -52
  567. package/src/interactive/chat-loop.ts +32 -5
  568. package/src/interactive/chat-panel.ts +168 -638
  569. package/src/interactive/chat-renderer.ts +13 -30
  570. package/src/interactive/clio-editor.ts +53 -21
  571. package/src/interactive/command-output.ts +56 -1
  572. package/src/interactive/dispatch-board.ts +1 -3
  573. package/src/interactive/editor-submit.ts +73 -59
  574. package/src/interactive/fleet-run-preview.ts +2 -0
  575. package/src/interactive/follow-up-queue-panel.ts +3 -3
  576. package/src/interactive/footer/dashboard.ts +12 -4
  577. package/src/interactive/footer/notifications.ts +2 -2
  578. package/src/interactive/footer/widgets.ts +52 -93
  579. package/src/interactive/interactive-application.ts +225 -63
  580. package/src/interactive/interactive-event-projection.ts +2 -44
  581. package/src/interactive/interactive-input-runtime.ts +257 -35
  582. package/src/interactive/interactive-presentation.ts +71 -21
  583. package/src/interactive/interactive-slash-runtime.ts +40 -48
  584. package/src/interactive/keybinding-manager.ts +156 -79
  585. package/src/interactive/keyboard-owner.ts +37 -0
  586. package/src/interactive/layout.ts +29 -4
  587. package/src/interactive/leader-key.ts +49 -102
  588. package/src/interactive/leader-menu.ts +45 -0
  589. package/src/interactive/overlay-ask-user-lifecycle.ts +9 -1
  590. package/src/interactive/overlay-frame.ts +15 -0
  591. package/src/interactive/overlay-general-openers.ts +2 -0
  592. package/src/interactive/overlay-key-routing.ts +46 -47
  593. package/src/interactive/overlay-lifecycle.ts +31 -15
  594. package/src/interactive/overlay-resource-openers.ts +56 -46
  595. package/src/interactive/overlay-session-lifecycle.ts +1 -1
  596. package/src/interactive/overlays/ask-user.ts +630 -556
  597. package/src/interactive/overlays/extension-panel.ts +70 -0
  598. package/src/interactive/overlays/extensions.ts +28 -5
  599. package/src/interactive/overlays/fleet-run-approval.ts +7 -3
  600. package/src/interactive/overlays/help-reference.ts +89 -40
  601. package/src/interactive/overlays/interop.ts +122 -3
  602. package/src/interactive/overlays/keybinding-detail.ts +2 -2
  603. package/src/interactive/overlays/library-lifecycle.ts +90 -0
  604. package/src/interactive/overlays/library-model.ts +574 -0
  605. package/src/interactive/overlays/library-review.ts +557 -0
  606. package/src/interactive/overlays/library-tabs.ts +3 -15
  607. package/src/interactive/overlays/library.ts +602 -0
  608. package/src/interactive/overlays/list-overlay.ts +218 -39
  609. package/src/interactive/overlays/model-selector.ts +28 -25
  610. package/src/interactive/overlays/session-selector.ts +9 -3
  611. package/src/interactive/overlays/settings.ts +34 -26
  612. package/src/interactive/overlays/tree-selector.ts +16 -11
  613. package/src/interactive/permission-hint.ts +13 -0
  614. package/src/interactive/permission-overlay.ts +77 -28
  615. package/src/interactive/prompt-source-label.ts +21 -0
  616. package/src/interactive/renderers/preview.ts +16 -0
  617. package/src/interactive/renderers/reference-card.ts +35 -0
  618. package/src/interactive/renderers/tool-execution.ts +67 -160
  619. package/src/interactive/renderers/worker-entry.ts +90 -42
  620. package/src/interactive/slash-autocomplete.ts +100 -7
  621. package/src/interactive/slash-commands.ts +396 -105
  622. package/src/interactive/slash-spec.ts +0 -1
  623. package/src/interactive/status/controller.ts +0 -5
  624. package/src/interactive/status/state-machine.ts +44 -26
  625. package/src/interactive/status/types.ts +3 -0
  626. package/src/interactive/status/verbs.ts +13 -12
  627. package/src/interactive/terminal-lease.ts +44 -12
  628. package/src/interactive/transcript-detail.ts +50 -112
  629. package/src/interactive/turn-queues.ts +8 -7
  630. package/src/interactive/turn-runtime.ts +1 -1
  631. package/src/interactive/view/artifacts.ts +4 -0
  632. package/src/interactive/view/view-overlay.ts +58 -43
  633. package/src/interactive/welcome-dashboard.ts +525 -408
  634. package/src/tools/bootstrap.ts +8 -0
  635. package/src/tools/builtin-tool-catalog.ts +7 -2
  636. package/src/tools/context/index.ts +58 -5
  637. package/src/tools/context/library.ts +465 -0
  638. package/src/tools/context/surface.ts +20 -6
  639. package/src/tools/core-bootstrap.ts +3 -0
  640. package/src/tools/dispatch-admission.ts +24 -1
  641. package/src/tools/dispatch-arguments.ts +8 -0
  642. package/src/tools/dispatch-plan.ts +32 -0
  643. package/src/tools/dispatch-schema.ts +31 -1
  644. package/src/tools/dispatch-types.ts +3 -0
  645. package/src/tools/dispatch.ts +1 -1
  646. package/src/tools/harness-extensions.ts +169 -0
  647. package/src/tools/observation.ts +4 -0
  648. package/src/tools/policy.ts +7 -1
  649. package/src/tools/presentation.ts +1 -1
  650. package/src/tools/registry.ts +20 -2
  651. package/src/tools/verify/numeric.ts +4 -4
  652. package/src/tools/worker-evidence.ts +5 -0
  653. package/src/worker/context-seed.ts +192 -0
  654. package/src/worker/entry.ts +1 -0
  655. package/src/worker/spec-contract.ts +8 -1
  656. package/dist/chunk-3UW3KU4A.js +0 -21
  657. package/dist/chunk-6SYEGZI3.js +0 -433
  658. package/dist/chunk-CXQ37WJH.js +0 -45
  659. package/dist/chunk-EQEJJ53P.js +0 -399
  660. package/dist/chunk-KTFSFCVN.js +0 -46
  661. package/dist/chunk-QRFXEO6Y.js +0 -17
  662. package/dist/chunk-T7FDXNRU.js +0 -1257
  663. package/dist/chunk-U7VQ4NI4.js +0 -911
  664. package/dist/configure-SML6UBZ5.js +0 -55
  665. package/dist/interop-YOTGXFJM.js +0 -115
  666. package/dist/library-GJI6W6OK.js +0 -226
  667. package/dist/skills-S36AAJHU.js +0 -510
  668. package/skills/README.md +0 -418
  669. package/skills/meta/find-skills/SKILL.md +0 -78
  670. package/skills/meta/find-skills/evals.md +0 -47
  671. package/src/domains/extensions/resource-path.ts +0 -27
  672. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +0 -27
  673. package/src/interactive/overlays/agents.ts +0 -70
  674. package/src/interactive/overlays/library-install-confirm.ts +0 -152
  675. package/src/interactive/overlays/prompts.ts +0 -89
  676. package/src/interactive/overlays/skills-hub.ts +0 -615
  677. /package/{skills → library/skills}/coding/ast-grep/references/rule_reference.md +0 -0
  678. /package/{skills → library/skills}/coding/prototype/references/LOGIC.md +0 -0
  679. /package/{skills → library/skills}/coding/prototype/references/UI.md +0 -0
  680. /package/{skills → library/skills}/coding/tdd/references/mocking.md +0 -0
  681. /package/{skills → library/skills}/coding/tdd/references/tests.md +0 -0
  682. /package/{skills → library/skills}/context/context-handoff/scripts/new-handoff.sh +0 -0
  683. /package/{skills → library/skills}/git/branch-closeout/evals.md +0 -0
  684. /package/{skills → library/skills}/git/branch-closeout/references/closeout-checklist.md +0 -0
  685. /package/{skills → library/skills}/git/file-ticket/assets/issue-template.md +0 -0
  686. /package/{skills → library/skills}/git/file-ticket/evals.md +0 -0
  687. /package/{skills → library/skills}/git/file-ticket/references/issue-discovery.md +0 -0
  688. /package/{skills → library/skills}/git/fix-issue/evals.md +0 -0
  689. /package/{skills → library/skills}/git/fix-issue/references/diagnosis-and-rca.md +0 -0
  690. /package/{skills → library/skills}/git/resolve-merge-conflicts/references/conflict-matrix.md +0 -0
  691. /package/{skills → library/skills}/git/ship/assets/pr-template.md +0 -0
  692. /package/{skills → library/skills}/git/ship/evals.md +0 -0
  693. /package/{skills → library/skills}/git/ship/references/remote-and-branch-policy.md +0 -0
  694. /package/{skills → library/skills}/git/worktree-create/evals.md +0 -0
  695. /package/{skills → library/skills}/git/worktree-create/references/worktree-setup.md +0 -0
  696. /package/{skills → library/skills}/git/worktree-merge/evals.md +0 -0
  697. /package/{skills → library/skills}/git/worktree-merge/references/merge-strategies.md +0 -0
  698. /package/{skills → library/skills}/meta/clio-coder-test/references/harness.md +0 -0
  699. /package/{skills → library/skills}/meta/clio-coder-test/references/test-map.md +0 -0
  700. /package/{skills → library/skills}/planning/archify/evals.md +0 -0
@@ -0,0 +1,616 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ verify_citations; resolve the citations in Materio research output against a
4
+ bibliographic registry (Crossref) to surface unresolved identities and
5
+ metadata conflicts for researcher review.
6
+
7
+ It reads LITERATURE.md and/or .bib files, extracts citation candidates
8
+ (BibTeX entries, quoted paper titles from the "Key Papers" table the
9
+ literature agent writes, and quoted titles on other table rows that carry a
10
+ 4-digit year), then queries Crossref by DOI or by title and classifies each
11
+ candidate:
12
+
13
+ VERIFIED matched a real published work (title similar, year consistent)
14
+ MISMATCH a work was found but the metadata disagrees (wrong year, or
15
+ only a weak title match); requires source inspection
16
+ NOT_FOUND no plausible match in Crossref; inspect the source manually
17
+ UNVERIFIABLE no extractable title (e.g. a placeholder like "[ML disc. 2024]")
18
+
19
+ Design notes:
20
+ * No DOIs are assumed; the literature agent usually emits none, so title+
21
+ year resolution is the primary path.
22
+ * Network is OPTIONAL. `--offline` (or a failed request) falls back to
23
+ structural checks + placeholder detection so the tool still runs in CI or
24
+ air-gapped sessions; unresolved entries become UNVERIFIABLE (offline).
25
+ * Crossref is free and needs no key; we identify via a descriptive
26
+ User-Agent. HTTP 429 / 5xx responses are retried once after a short
27
+ backoff before an entry is reported UNVERIFIABLE.
28
+
29
+ Exit status: 1 for NOT_FOUND/MISMATCH findings; 2 for incomplete input coverage.
30
+ Zero deps (Python stdlib only).
31
+
32
+ Usage (invoked from a project root, where .claude/ and .research/ live):
33
+ python3 assets/scripts/verify_citations.py .research/LITERATURE.md
34
+ python3 assets/scripts/verify_citations.py --offline path.bib
35
+ python3 assets/scripts/verify_citations.py --json task-01.bib
36
+ """
37
+ import argparse
38
+ import difflib
39
+ import json
40
+ import re
41
+ import sys
42
+ import time
43
+ import urllib.error
44
+ import urllib.parse
45
+ import urllib.request
46
+
47
+ CROSSREF = "https://api.crossref.org/works"
48
+ UA = "materio-verify-citations/0.1 (Materio research assistant; citation verifier)"
49
+ TITLE_MATCH = 0.75 # >= this title similarity => same paper
50
+ TITLE_WEAK = 0.50 # [WEAK, MATCH) => MISMATCH (found but doubtful)
51
+ REQ_TIMEOUT = 15
52
+ REQ_PAUSE = 0.2 # polite spacing between Crossref calls
53
+ RETRY_BACKOFF = 2.0 # seconds before the single retry on HTTP 429 / 5xx
54
+
55
+
56
+ # ---- extraction -----------------------------------------------------------
57
+
58
+ class Cite:
59
+ __slots__ = ("title", "year", "authors", "doi", "source", "raw")
60
+
61
+ def __init__(self, title=None, year=None, authors=None, doi=None,
62
+ source="", raw=""):
63
+ self.title = title
64
+ self.year = year
65
+ self.authors = authors
66
+ self.doi = doi
67
+ self.source = source # where in the file it came from
68
+ self.raw = raw # original text snippet
69
+
70
+
71
+ def _norm(s):
72
+ """Lowercase, strip non-alphanumerics to single spaces; for comparison."""
73
+ return re.sub(r"[^a-z0-9]+", " ", (s or "").lower()).strip()
74
+
75
+
76
+ def similarity(a, b):
77
+ return difflib.SequenceMatcher(None, _norm(a), _norm(b)).ratio()
78
+
79
+
80
+ # Parse BibTeX groups without importing or executing anything. Nested title
81
+ # braces and one-line entries are common in real researcher bibliographies.
82
+ def _group(text, start):
83
+ opening = text[start]
84
+ closing = '}' if opening == '{' else ')' if opening == '(' else '"'
85
+ depth, index, quoted = 1, start + 1, False
86
+ while index < len(text):
87
+ char = text[index]
88
+ if char == "\\":
89
+ index += 2
90
+ continue
91
+ if opening == '"':
92
+ if char == '"':
93
+ return text[start + 1:index], index + 1
94
+ else:
95
+ if char == '"':
96
+ quoted = not quoted
97
+ if not quoted:
98
+ if char == opening:
99
+ depth += 1
100
+ elif char == closing:
101
+ depth -= 1
102
+ if depth == 0:
103
+ return text[start + 1:index], index + 1
104
+ index += 1
105
+ raise ValueError("unterminated BibTeX value")
106
+
107
+
108
+ def _bibtex_entries(text):
109
+ index = 0
110
+ while index < len(text):
111
+ match = re.search(r"@(\w+)\s*([{(])", text[index:])
112
+ if not match:
113
+ return
114
+ start = index + match.start()
115
+ group_start = index + match.end() - 1
116
+ try:
117
+ body, end = _group(text, group_start)
118
+ except ValueError:
119
+ return
120
+ index = end
121
+ if match.group(1).lower() not in {"comment", "preamble", "string"}:
122
+ yield body, text[start:end]
123
+
124
+
125
+ def _bibtex_fields(body):
126
+ index = body.find(',') + 1
127
+ fields = {}
128
+ while index > 0 and index < len(body):
129
+ match = re.match(r"\s*,?\s*([\w-]+)\s*=\s*", body[index:])
130
+ if not match:
131
+ break
132
+ name = match.group(1).lower()
133
+ index += match.end()
134
+ if index >= len(body):
135
+ break
136
+ if body[index] in '{"':
137
+ try:
138
+ value, index = _group(body, index)
139
+ except ValueError:
140
+ break
141
+ else:
142
+ end = body.find(',', index)
143
+ if end == -1:
144
+ end = len(body)
145
+ value, index = body[index:end].strip(), end
146
+ fields[name] = re.sub(r"[{}]", "", value).strip()
147
+ return fields
148
+
149
+
150
+ def extract_bibtex(text, source):
151
+ """Extract balanced BibTeX entries, preserving complete title contents."""
152
+ cites = []
153
+ for body, raw in _bibtex_entries(text):
154
+ fields = _bibtex_fields(body)
155
+ title = fields.get("title")
156
+ if title:
157
+ cites.append(Cite(title=title, year=fields.get("year"),
158
+ authors=fields.get("author"), doi=fields.get("doi"),
159
+ source=source, raw=raw[:160]))
160
+ return cites
161
+
162
+
163
+ # A quoted title: straight or curly quotes wrapping 20+ non-quote characters
164
+ # (the length floor rules out short quoted phrases and acronyms).
165
+ _QUOTED = re.compile(r"[\"“]([^\"”“]{20,})[\"”]")
166
+
167
+ # A 4-digit publication year.
168
+ _YEAR = re.compile(r"\b(?:19|20)\d{2}\b")
169
+
170
+ # An inline citation key like [Gong 2014] or [du Plessis 2019].
171
+ _INLINE = re.compile(r"\[([A-Za-z][\w.\- ]*?\s(?:19|20)\d{2}[a-z]?)\]")
172
+
173
+ # Placeholder-looking inline keys: contain a hyphenated/lowercase filler token
174
+ # rather than a proper surname (e.g. "ML domain-discovery 2024").
175
+ _PLACEHOLDER_HINT = re.compile(r"[a-z]+-[a-z]+|\b(?:ml|opt|disc|tbd|xxx)\b",
176
+ re.IGNORECASE)
177
+
178
+ # Markdown table separator row: |---|:---:|
179
+ _TABLE_SEP = re.compile(r"^\s*\|?\s*:?-{3,}")
180
+
181
+ # An author list as the literature agent writes it at the head of a Key
182
+ # Papers row: "King W.E. et al.", "W.E. King and R. Smith",
183
+ # "Tang M., Pistorius P.C.", "Scipioni Bertoli U. et al.".
184
+ _INITIALS = r"(?:[A-Z]\.\s?){1,3}"
185
+ _SURNAME = r"[A-Z][A-Za-z'’\-]+(?:\s+[A-Z][A-Za-z'’\-]+)?"
186
+ _AUTHOR = rf"(?:{_INITIALS}\s*)?{_SURNAME}(?:\s+{_INITIALS})?"
187
+ _AUTHOR_LIST = re.compile(
188
+ rf"^{_AUTHOR}(?:\s*(?:,|;|&|\band\b)\s*{_AUTHOR})*"
189
+ rf"(?:,?\s*et\s+al\.?)?\.?$")
190
+ # ...and at least one multi-author marker or initial, so a bare capitalized
191
+ # phrase ("Additive Manufacturing") is not mistaken for a surname pair.
192
+ _AUTHOR_MARK = re.compile(r"\bet\s+al\b|\band\b|&|,|;|\b[A-Z]\.")
193
+
194
+
195
+ def _cells(line):
196
+ return [c.strip() for c in line.strip().strip("|").split("|")]
197
+
198
+
199
+ def _table_kind(header, heading):
200
+ """
201
+ Classify a markdown table by its header row (falling back to the section
202
+ heading above it). The literature agent writes two tables:
203
+
204
+ ## Key Papers | Paper | Year | Why Important |
205
+ ## Methodological Landscape | Approach | Strengths | Limitations | Key Papers |
206
+
207
+ Only the first is bibliographic. The Landscape table's "Key Papers"
208
+ column repeats titles in shorthand, usually ellipsis-truncated, which
209
+ produced false NOT_FOUND/MISMATCH flags, so it is skipped outright.
210
+ """
211
+ cells = [c.lower() for c in _cells(header)]
212
+ first = cells[0] if cells else ""
213
+ if "approach" in first:
214
+ return "landscape"
215
+ if "paper" in first:
216
+ return "papers"
217
+ h = (heading or "").lower()
218
+ if "landscape" in h:
219
+ return "landscape"
220
+ if "key papers" in h:
221
+ return "papers"
222
+ return "other"
223
+
224
+
225
+ def _looks_like_authors(seg):
226
+ """True if a Key Papers first-cell prefix reads as an author list."""
227
+ if not seg or len(seg) > 80 or re.search(r"\d", seg):
228
+ return False
229
+ return bool(_AUTHOR_LIST.match(seg)) and bool(_AUTHOR_MARK.search(seg))
230
+
231
+
232
+ def _row_authors(first_cell):
233
+ """
234
+ Author string from the text that precedes the quoted title in a Key
235
+ Papers row, or None when that text is not an author list. Anything
236
+ else (a journal in *italics*, a volume number, prose) yields None so the
237
+ Crossref query is by title alone rather than polluted with junk.
238
+ """
239
+ seg = re.split(r"[\"“]", first_cell, 1)[0]
240
+ seg = re.split(r"[*_(\[]|\s[—–-]\s", seg, 1)[0]
241
+ seg = seg.strip().strip(",;:—–- ").strip()
242
+ return seg if _looks_like_authors(seg) else None
243
+
244
+
245
+ def _titles_in(line):
246
+ """Yield (title, truncated) for each quoted title on a line."""
247
+ for qm in _QUOTED.finditer(line):
248
+ raw = qm.group(1).strip()
249
+ truncated = raw.endswith("...") or raw.endswith("…")
250
+ title = raw.rstrip(".…").rstrip(",;:").strip()
251
+ yield title, truncated
252
+
253
+
254
+ def _row_year(line):
255
+ """First 4-digit year on a row, looking outside the quoted titles first."""
256
+ outside = _QUOTED.sub(" ", line)
257
+ ym = _YEAR.search(outside) or _YEAR.search(line)
258
+ return ym.group(0) if ym else None
259
+
260
+
261
+ def dedup_truncated(cites):
262
+ """Deduplicate exact identities only; a complete prefix can be another paper.
263
+
264
+ Preserve conflicting DOI metadata as separate findings. Explicit ellipsis
265
+ fragments are omitted by the Markdown extractor, not guessed by title length.
266
+ """
267
+ seen, out = set(), []
268
+ for cite in cites:
269
+ key = (_norm(cite.title), cite.year, (cite.doi or "").lower())
270
+ if key not in seen:
271
+ seen.add(key)
272
+ out.append(cite)
273
+ return out
274
+
275
+
276
+ def extract_markdown(text, source):
277
+ """
278
+ Extract citation candidates from a LITERATURE.md-style document. Only
279
+ three places are treated as bibliographic:
280
+ * BibTeX entries embedded in the document
281
+ * rows of the Key Papers table (title from the quoted string; authors
282
+ only when the row's first cell starts with an author list)
283
+ * rows of any other table that carry a 4-digit year
284
+ Prose lines are never scanned (quoted emphasis phrases are not titles),
285
+ and the Methodological Landscape table is skipped. Titles that end in an
286
+ ellipsis are omitted as incomplete fragments. Complete prefix titles remain
287
+ distinct; exact identity duplicates are removed. Also returns inline [Author Year] keys that look
288
+ like placeholders.
289
+ """
290
+ cites = list(extract_bibtex(text, source))
291
+ without_bibtex = text
292
+ for _, raw in _bibtex_entries(text):
293
+ without_bibtex = without_bibtex.replace(raw, "")
294
+ lines = without_bibtex.splitlines()
295
+ seen_titles = {(_norm(c.title), c.year) for c in cites}
296
+ heading, in_table, kind = None, False, "other"
297
+ for i, line in enumerate(lines):
298
+ if "|" not in line:
299
+ in_table = False
300
+ if line.lstrip().startswith("#"):
301
+ heading = line.lstrip("# ").strip()
302
+ continue
303
+ if not in_table:
304
+ in_table = True
305
+ # A header row is one followed by a |---| separator; a table
306
+ # without one is classified by its section heading alone.
307
+ nxt = lines[i + 1] if i + 1 < len(lines) else ""
308
+ if _TABLE_SEP.match(nxt):
309
+ kind = _table_kind(line, heading)
310
+ continue
311
+ kind = _table_kind("", heading)
312
+ if _TABLE_SEP.match(line) or kind == "landscape":
313
+ continue
314
+ year = _row_year(line)
315
+ if kind != "papers" and not year:
316
+ continue
317
+ authors = _row_authors(_cells(line)[0]) if kind == "papers" else None
318
+ for title, truncated in _titles_in(line):
319
+ key = _norm(title)
320
+ if truncated or (key, year) in seen_titles or len(key) < 12:
321
+ continue
322
+ seen_titles.add((key, year))
323
+ cites.append(Cite(title=title, year=year, authors=authors,
324
+ source=source, raw=line.strip()[:160]))
325
+ return dedup_truncated(cites), _extract_inline(text, source)
326
+
327
+
328
+ def _surnames(authors):
329
+ """
330
+ Plausible primary-author surname tokens from a free-form author string.
331
+ Author order is ambiguous here; tables use both "King W.E." (surname
332
+ first) and "W.E. King" (surname last); so we return every token that
333
+ looks like a surname (capitalized, mostly letters) and drop initials
334
+ like "W.E.". The caller matches this set against the work's authors.
335
+ """
336
+ if not authors:
337
+ return set()
338
+ first = re.split(r"\band\b|;|&", authors)[0]
339
+ first = re.sub(r"\bet al\.?\b", "", first, flags=re.IGNORECASE)
340
+ out = set()
341
+ for tok in re.split(r"[\s,]+", first):
342
+ letters = re.sub(r"[^A-Za-z]", "", tok)
343
+ if len(letters) < 2:
344
+ continue
345
+ # An initials cluster like "W.E." -> "WE" is all-caps and short; skip.
346
+ if tok.replace(".", "").isupper() and len(letters) <= 3:
347
+ continue
348
+ if tok[:1].isupper():
349
+ out.add(_norm(letters))
350
+ return out
351
+
352
+
353
+ def _item_surnames(item):
354
+ """Normalized family names AND their word tokens (handles compound
355
+ surnames like 'Scipioni Bertoli' whichever way the source split them)."""
356
+ out = set()
357
+ for a in (item.get("author") or []):
358
+ fam = a.get("family")
359
+ if not fam:
360
+ continue
361
+ nf = _norm(fam)
362
+ out.add(nf)
363
+ out.update(nf.split())
364
+ return out
365
+
366
+
367
+ def _extract_inline(text, source):
368
+ """Return inline [Author Year]-style keys that look like placeholders
369
+ (a non-name filler token rather than a real surname, e.g.
370
+ "[ML domain-discovery 2024]"); these are unverifiable by construction."""
371
+ placeholders = []
372
+ seen = set()
373
+ for m in _INLINE.finditer(text):
374
+ key = m.group(1).strip()
375
+ if key in seen:
376
+ continue
377
+ seen.add(key)
378
+ if _PLACEHOLDER_HINT.search(key):
379
+ placeholders.append(Cite(title=None, source=source,
380
+ raw="[" + key + "]"))
381
+ return placeholders
382
+
383
+
384
+ # ---- verification ---------------------------------------------------------
385
+
386
+ def _retryable(code):
387
+ return code == 429 or 500 <= code < 600
388
+
389
+
390
+ def _get(url):
391
+ """GET JSON. One retry after RETRY_BACKOFF on HTTP 429 / 5xx (Crossref
392
+ rate limiting or a transient server fault); any other error propagates."""
393
+ req = urllib.request.Request(url, headers={"User-Agent": UA})
394
+ for attempt in (0, 1):
395
+ try:
396
+ with urllib.request.urlopen(req, timeout=REQ_TIMEOUT) as r:
397
+ return json.load(r)
398
+ except urllib.error.HTTPError as e:
399
+ if attempt == 0 and _retryable(e.code):
400
+ time.sleep(RETRY_BACKOFF)
401
+ continue
402
+ raise
403
+
404
+
405
+ DOI_ABSENT = object() # sentinel: DOI definitively not in Crossref (HTTP 404)
406
+
407
+
408
+ def crossref_by_doi(doi):
409
+ """Return the work dict, DOI_ABSENT if Crossref lacks the DOI (other agencies may own it),
410
+ or None on a real network error."""
411
+ try:
412
+ data = _get(CROSSREF + "/" + urllib.parse.quote(doi))
413
+ return data.get("message")
414
+ except urllib.error.HTTPError as e:
415
+ return DOI_ABSENT if e.code == 404 else None
416
+ except Exception:
417
+ return None
418
+
419
+
420
+ def crossref_by_title(title, authors=None, year=None):
421
+ q = title
422
+ if authors:
423
+ q = authors + " " + q
424
+ params = {"rows": "5", "query.bibliographic": q}
425
+ url = CROSSREF + "?" + urllib.parse.urlencode(params)
426
+ try:
427
+ data = _get(url)
428
+ return data.get("message", {}).get("items", [])
429
+ except Exception:
430
+ return None # None = network failure (vs [] = no results)
431
+
432
+
433
+ def _item_year(item):
434
+ for k in ("published-print", "published-online", "issued"):
435
+ dp = item.get(k, {}).get("date-parts") if item else None
436
+ if dp and dp[0] and dp[0][0]:
437
+ return str(dp[0][0])
438
+ return None
439
+
440
+
441
+ def verify_one(c, offline):
442
+ """Return (status, detail_dict)."""
443
+ if not c.title:
444
+ return "UNVERIFIABLE", {"reason": "no extractable title (placeholder)"}
445
+ if offline:
446
+ return "UNVERIFIABLE", {"reason": "offline mode; not resolved"}
447
+
448
+ # DOI path
449
+ if c.doi:
450
+ item = crossref_by_doi(c.doi)
451
+ if item is DOI_ABSENT:
452
+ return "UNVERIFIABLE", {"doi": c.doi,
453
+ "reason": "DOI absent from Crossref; another registration agency may own it"}
454
+ if item is None:
455
+ return "UNVERIFIABLE", {"reason": "network error resolving DOI"}
456
+ rt = (item.get("title") or [""])[0]
457
+ sim = similarity(c.title, rt)
458
+ ry = _item_year(item)
459
+ year_ok = not (c.year and ry) or (c.year.isdigit() and ry.isdigit() and abs(int(c.year) - int(ry)) <= 1)
460
+ if sim >= TITLE_MATCH and year_ok:
461
+ return "VERIFIED", {"doi": c.doi, "matched_title": rt,
462
+ "similarity": round(sim, 2)}
463
+ return "MISMATCH", {"doi": c.doi, "matched_title": rt,
464
+ "similarity": round(sim, 2),
465
+ "reason": "DOI metadata needs review: weak title match or inconsistent year"}
466
+
467
+ # Title path
468
+ items = crossref_by_title(c.title, c.authors, c.year)
469
+ if items is None:
470
+ return "UNVERIFIABLE", {"reason": "network error querying Crossref"}
471
+ best, best_sim = None, 0.0
472
+ for it in items:
473
+ rt = (it.get("title") or [""])[0]
474
+ s = similarity(c.title, rt)
475
+ if s > best_sim:
476
+ best, best_sim = it, s
477
+ if best is None:
478
+ return "NOT_FOUND", {"reason": "no Crossref results"}
479
+ rt = (best.get("title") or [""])[0]
480
+ ry = _item_year(best)
481
+ detail = {"matched_title": rt, "similarity": round(best_sim, 2),
482
+ "doi": best.get("DOI"), "matched_year": ry}
483
+
484
+ year_ok = not (c.year and ry) or (c.year.isdigit() and ry.isdigit() and abs(int(c.year) - int(ry)) <= 1)
485
+ # Author+year corroboration rescues abbreviated titles (e.g. a source
486
+ # that shortened "...laser powder-bed fusion" to "...LPBF"): the primary
487
+ # author's surname appearing in the matched work, with a consistent year,
488
+ # is strong independent evidence it is the same paper.
489
+ author_ok = bool(_surnames(c.authors) & _item_surnames(best))
490
+
491
+ if best_sim >= TITLE_MATCH:
492
+ if not year_ok:
493
+ detail["reason"] = f"year {c.year} vs Crossref {ry}"
494
+ return "MISMATCH", detail
495
+ return "VERIFIED", detail
496
+ if best_sim >= TITLE_WEAK:
497
+ if author_ok and year_ok:
498
+ detail["reason"] = "abbreviated title; confirmed by author + year"
499
+ return "VERIFIED", detail
500
+ detail["reason"] = "only a weak title match; verify manually"
501
+ return "MISMATCH", detail
502
+ detail["reason"] = "closest Crossref result is unrelated"
503
+ return "NOT_FOUND", detail
504
+
505
+
506
+ # ---- driver ---------------------------------------------------------------
507
+
508
+ def collect(paths):
509
+ cites, placeholders = [], []
510
+ for p in paths:
511
+ try:
512
+ with open(p, encoding="utf-8") as f:
513
+ text = f.read()
514
+ except OSError as e:
515
+ print(f"WARN: cannot read {p}: {e}", file=sys.stderr)
516
+ continue
517
+ if p.endswith(".bib"):
518
+ cites += extract_bibtex(text, p)
519
+ else:
520
+ md_cites, md_ph = extract_markdown(text, p)
521
+ cites += md_cites
522
+ placeholders += md_ph
523
+ return dedup_truncated(cites), placeholders
524
+
525
+
526
+ def main():
527
+ ap = argparse.ArgumentParser(description="Verify citations against Crossref.")
528
+ ap.add_argument("paths", nargs="+", help="LITERATURE.md and/or .bib files")
529
+ ap.add_argument("--offline", action="store_true",
530
+ help="skip network; structural + placeholder checks only")
531
+ ap.add_argument("--json", action="store_true", help="machine-readable output")
532
+ args = ap.parse_args()
533
+
534
+ unreadable = []
535
+ for path in args.paths:
536
+ try:
537
+ with open(path, encoding="utf-8") as source:
538
+ source.read()
539
+ except (OSError, UnicodeError) as error:
540
+ unreadable.append({"file": path, "reason": str(error)})
541
+ readable = [path for path in args.paths if path not in {item["file"] for item in unreadable}]
542
+ cites, placeholders = collect(readable)
543
+
544
+ results = []
545
+ for c in cites:
546
+ status, detail = verify_one(c, args.offline)
547
+ results.append((c, status, detail))
548
+ if not args.offline and not c.doi:
549
+ time.sleep(REQ_PAUSE)
550
+ for ph in placeholders:
551
+ results.append((ph, "UNVERIFIABLE",
552
+ {"reason": "self-flagged placeholder citation key"}))
553
+
554
+ counts = {}
555
+ for _, status, _ in results:
556
+ counts[status] = counts.get(status, 0) + 1
557
+
558
+ if args.json:
559
+ out = {
560
+ "coverage": {"files_requested": len(args.paths), "files_read": len(readable), "unreadable": unreadable, "candidates": len(cites)},
561
+ "summary": counts,
562
+ "results": [
563
+ {"title": c.title, "year": c.year, "doi": c.doi,
564
+ "source": c.source, "raw": c.raw,
565
+ "status": status, "detail": detail}
566
+ for c, status, detail in results
567
+ ],
568
+ }
569
+ print(json.dumps(out, indent=2))
570
+ else:
571
+ _print_report(results, counts, args.offline)
572
+
573
+ bad = counts.get("NOT_FOUND", 0) + counts.get("MISMATCH", 0)
574
+ if unreadable or not results:
575
+ if not args.json:
576
+ print("Citation coverage incomplete: unreadable inputs or no extractable citations", file=sys.stderr)
577
+ return 2
578
+ return 1 if bad else 0
579
+
580
+
581
+ _ICON = {"VERIFIED": "OK ", "MISMATCH": "WARN", "NOT_FOUND": "FAIL",
582
+ "UNVERIFIABLE": "?? "}
583
+
584
+
585
+ def _print_report(results, counts, offline):
586
+ order = ["NOT_FOUND", "MISMATCH", "UNVERIFIABLE", "VERIFIED"]
587
+ for status in order:
588
+ group = [(c, d) for c, s, d in results if s == status]
589
+ if not group:
590
+ continue
591
+ print(f"\n{status} ({len(group)}):")
592
+ for c, d in group:
593
+ label = c.title or c.raw or "?"
594
+ line = f" [{_ICON[status]}] {label[:88]}"
595
+ print(line)
596
+ bits = []
597
+ if d.get("reason"):
598
+ bits.append(d["reason"])
599
+ if d.get("matched_title"):
600
+ tag = "closest:" if status == "NOT_FOUND" else "~"
601
+ bits.append(f"{tag} {d['matched_title'][:70]}")
602
+ if d.get("doi") and status != "UNVERIFIABLE":
603
+ bits.append(f"doi:{d['doi']}")
604
+ if bits:
605
+ print(" " + " | ".join(bits))
606
+ mode = " (offline)" if offline else ""
607
+ counts_str = ", ".join(f"{k}={v}" for k, v in sorted(counts.items())) \
608
+ or "no citations found"
609
+ print(f"\nverify-citations{mode}: {counts_str}")
610
+ bad = counts.get("NOT_FOUND", 0) + counts.get("MISMATCH", 0)
611
+ if bad:
612
+ print(f" -> {bad} citation(s) need attention.")
613
+
614
+
615
+ if __name__ == "__main__":
616
+ sys.exit(main())
@@ -0,0 +1,39 @@
1
+ # Research Identity
2
+
3
+ ## Research Area
4
+ - **Domain**: [Structural Materials | Functional Materials | Energy Materials | Biomaterials | Nanomaterials | Polymers | Computational MatSci | Characterization]
5
+ - **Sub-field**: [e.g., High-entropy alloys, Solid-state batteries, Bone scaffolds, 2D materials]
6
+ - **Specific Interest**: [precise topic; phenomena, material system, or application]
7
+
8
+ ## Research Prompt
9
+ [The refined research question; one sentence. What does this research answer?]
10
+
11
+ ## Scope
12
+ ### In Scope
13
+ - [specific materials, phenomena, length scales, conditions]
14
+ - [specific characterization methods or computational approaches]
15
+
16
+ ### Out of Scope
17
+ - [explicit exclusions; what this research will NOT address]
18
+
19
+ ## Researcher Profile
20
+ - **Career Stage**: [undergrad | grad student | postdoc | PI | industry researcher]
21
+ - **Available Resources**: [experimental equipment | computational cluster | literature only | combination]
22
+ - **Timeline**: [months/years]
23
+ - **Institutional Context**: [university lab | national lab | industry R&D | independent]
24
+
25
+ ## Initial Keywords
26
+ - **Primary**: []
27
+ - **Secondary**: []
28
+ - **Exclude from search**: []
29
+
30
+ ## Suggested Research Prompts (generated during interview)
31
+ 1. [prompt option A; fundamental understanding focus]
32
+ 2. [prompt option B; application focus]
33
+ 3. [prompt option C; methodological focus]
34
+
35
+ ## Selected Prompt
36
+ [User-confirmed research prompt after interview]
37
+
38
+ ## Key Decisions
39
+ [Decisions locked in during identify-research; scope choices, methodological constraints, etc.]