@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.
- package/.claude-plugin/marketplace.json +283 -0
- package/CHANGELOG.md +50 -0
- package/CONTRIBUTING.md +102 -29
- package/NOTICE +8 -0
- package/README.md +37 -5
- package/dist/{acp-UVEVWSDL.js → acp-W3Y3TRHD.js} +12 -12
- package/dist/{agents-VWY37DTK.js → agents-J4ICNLQ3.js} +52 -52
- package/dist/assets/codewiki.json +1 -1
- package/dist/assets/tui-notices/get-east-asian-width-LICENSE +9 -0
- package/dist/assets/tui-notices/marked-LICENSE +44 -0
- package/dist/assets/tui-notices/pi-tui-LICENSE +21 -0
- package/dist/{auth-PCV2XQDV.js → auth-X2UJUMOC.js} +24 -24
- package/dist/{builtins-PD652MTK.js → builtins-XLXWWSRF.js} +6 -6
- package/dist/{chunk-DZK63TZJ.js → chunk-24S3DN22.js} +336 -612
- package/dist/{chunk-NTK3WTHM.js → chunk-24TOGHPO.js} +2 -2
- package/dist/{chunk-M6TAYK66.js → chunk-2O2LVQQK.js} +11 -4
- package/dist/{chunk-OQM5IVJY.js → chunk-34XHRVKG.js} +3 -3
- package/dist/{chunk-LY4N4TTL.js → chunk-3LXJOICS.js} +2 -2
- package/dist/{chunk-3BJGMT2D.js → chunk-3XE4NRLF.js} +1 -1
- package/dist/{chunk-N2OKBREN.js → chunk-4MFBBY2Z.js} +3 -3
- package/dist/{chunk-5VTJP36Q.js → chunk-4N2RZ4TO.js} +2 -2
- package/dist/{chunk-WNGF5AJX.js → chunk-4QKAITQT.js} +3 -3
- package/dist/chunk-4UHVS5T7.js +207 -0
- package/dist/{chunk-GLYBJ4RQ.js → chunk-5AJPUR72.js} +6 -6
- package/dist/{chunk-5CY4Q6QI.js → chunk-5EQO5NWP.js} +105 -3
- package/dist/{chunk-6HAO6X5B.js → chunk-65BGHOUR.js} +8 -5
- package/dist/{chunk-6VRRJT7L.js → chunk-6CA2BHOR.js} +2 -2
- package/dist/{chunk-HL26ADLH.js → chunk-6CB2IL4N.js} +2 -1
- package/dist/{chunk-E7RF4KBO.js → chunk-6LRLOJHQ.js} +3 -3
- package/dist/{chunk-HXHFDHB6.js → chunk-6TAATXXH.js} +6 -6
- package/dist/{chunk-P6M7RKMI.js → chunk-6YHPAAZR.js} +3 -3
- package/dist/{chunk-5QRX7SLS.js → chunk-7EEGBKV4.js} +7 -7
- package/dist/{chunk-BS4GAMUB.js → chunk-A67NR5AT.js} +2 -2
- package/dist/{chunk-WJIMKGD6.js → chunk-BAU36233.js} +8 -8
- package/dist/{chunk-PZN2LQY6.js → chunk-BO4XV5VX.js} +4 -4
- package/dist/{chunk-I2K2NCZQ.js → chunk-BQQ5MXUC.js} +6 -6
- package/dist/{chunk-X3BI7HTV.js → chunk-C3G5PNUO.js} +21 -21
- package/dist/{chunk-SRZOW5L2.js → chunk-C6GEXX4L.js} +1 -1
- package/dist/{chunk-6RYDAVQT.js → chunk-CE64C5K5.js} +219 -64
- package/dist/chunk-CP3HIR5H.js +2119 -0
- package/dist/{chunk-BBV5TKE6.js → chunk-CPXGJI2A.js} +2 -2
- package/dist/{chunk-IGLVVNEG.js → chunk-CULVKYTK.js} +4 -4
- package/dist/{chunk-DXLUVUD4.js → chunk-D2T66PDV.js} +5 -5
- package/dist/{chunk-NF3BK5WR.js → chunk-DACXIVVF.js} +5 -5
- package/dist/{chunk-IKRWLEDA.js → chunk-DLIYANB7.js} +20 -15
- package/dist/{chunk-RGZNQ5CT.js → chunk-DO7M3LSX.js} +9 -9
- package/dist/{chunk-2QPI3TR3.js → chunk-DVJL77SO.js} +2 -2
- package/dist/{chunk-ODUTYZIU.js → chunk-EUEXGXXR.js} +5 -5
- package/dist/{chunk-WKUYQBCG.js → chunk-EUZRMP4Y.js} +18 -16
- package/dist/{chunk-JMPL7NUB.js → chunk-G4LGUTOE.js} +4 -4
- package/dist/{chunk-CBSKDFWL.js → chunk-GEVQNST4.js} +2 -2
- package/dist/{chunk-NNWJYUNO.js → chunk-GFQ7P2UF.js} +7 -7
- package/dist/{chunk-SXQKNKRA.js → chunk-GI5RRMAH.js} +14 -14
- package/dist/{chunk-HPTJF6DG.js → chunk-GVZFCJHE.js} +336 -83
- package/dist/{chunk-ACCKVSHU.js → chunk-GXIWHXDB.js} +3 -3
- package/dist/{chunk-LUL5Z66S.js → chunk-HOX4YZ2K.js} +6 -5
- package/dist/chunk-HRAKUPIH.js +57 -0
- package/dist/{chunk-F5Z7EWMN.js → chunk-IJMW64DX.js} +50 -50
- package/dist/{chunk-QNWRHOMF.js → chunk-IMOD2YPV.js} +16 -9
- package/dist/{chunk-HZ2T2YED.js → chunk-IQCNVLO6.js} +28 -8
- package/dist/{chunk-HZFBVU5X.js → chunk-ISNCCX42.js} +8 -8
- package/dist/{chunk-7JSSKXG2.js → chunk-IZYTT3CD.js} +7 -3
- package/dist/chunk-KKEYGFX4.js +915 -0
- package/dist/{chunk-HHVJNVUJ.js → chunk-KS7ETA3P.js} +2 -2
- package/dist/{chunk-BLTEAUCB.js → chunk-L3Z5ANCV.js} +7 -7
- package/dist/{chunk-4VMV6OS6.js → chunk-LBFQMYS3.js} +2 -2
- package/dist/{chunk-URBGEOH3.js → chunk-M6Z2V6YU.js} +5 -5
- package/dist/{chunk-BT7HGDOX.js → chunk-MBJO5VNZ.js} +12 -12
- package/dist/chunk-MNQN3X6Y.js +595 -0
- package/dist/{chunk-3QKXHCGS.js → chunk-MZHXENL7.js} +5 -5
- package/dist/chunk-MZNWZUJM.js +1801 -0
- package/dist/{chunk-7YJWEF2L.js → chunk-N37QC5FV.js} +5 -5
- package/dist/{chunk-TJFDL26W.js → chunk-NCCQ6DVS.js} +7 -7
- package/dist/{chunk-P5JMBPDJ.js → chunk-NO7J45X6.js} +162 -47
- package/dist/chunk-OH3YYA3B.js +15 -0
- package/dist/{chunk-22PQ4TX4.js → chunk-P4DL2LM5.js} +16 -77
- package/dist/{chunk-LIN2K3EL.js → chunk-PFLOULP3.js} +4 -4
- package/dist/{chunk-QXFBABFJ.js → chunk-QKWL7SYE.js} +11 -11
- package/dist/chunk-RFCKPS2V.js +26 -0
- package/dist/{chunk-ZS43Y2FT.js → chunk-RTLNFZMD.js} +12 -4
- package/dist/{chunk-U7H5WRG5.js → chunk-RXFPB32E.js} +8 -6
- package/dist/{chunk-Q7NNUHQV.js → chunk-SEDI5K5B.js} +16 -16
- package/dist/{chunk-WV6TDAPN.js → chunk-SELG4SUR.js} +7 -7
- package/dist/{chunk-3WBALRQH.js → chunk-SER7RRAE.js} +27 -832
- package/dist/{chunk-K2HL3GBL.js → chunk-T4TY5GG3.js} +165 -15
- package/dist/chunk-T7QQBNLH.js +691 -0
- package/dist/{chunk-6OII3LOK.js → chunk-TLTGZTXI.js} +3 -3
- package/dist/chunk-TZ6UVP2H.js +637 -0
- package/dist/{chunk-3JLFK5MW.js → chunk-TZHN5ITX.js} +13 -41
- package/dist/{chunk-VANN3GDP.js → chunk-U3TPUXOQ.js} +399 -234
- package/dist/{chunk-VHMX7SXF.js → chunk-UA3W4FGC.js} +6 -6
- package/dist/{chunk-3O2ZAUGQ.js → chunk-UA6W4XFJ.js} +2 -2
- package/dist/chunk-UWD3JD5X.js +709 -0
- package/dist/chunk-V4ZKOKRB.js +13433 -0
- package/dist/{chunk-NC4KV7EL.js → chunk-VCRVEDUC.js} +5 -5
- package/dist/{chunk-4DU2TVI4.js → chunk-VMATUZB6.js} +12 -10
- package/dist/{chunk-J2FYEQ5L.js → chunk-VTYHHQ57.js} +2 -2
- package/dist/chunk-WB7POC6M.js +891 -0
- package/dist/{chunk-3HQVBIKD.js → chunk-WBVKKTUT.js} +2 -2
- package/dist/{chunk-EHOSNVVM.js → chunk-WLHX3MM5.js} +6 -2
- package/dist/{chunk-24T2YZ7A.js → chunk-WN552PKN.js} +553 -298
- package/dist/{chunk-4U4TKZFR.js → chunk-WT5TRMO4.js} +51 -26
- package/dist/{chunk-XWMSPJYN.js → chunk-WURGVOZJ.js} +56 -12
- package/dist/{chunk-7WUZEB2M.js → chunk-XR3XJN2M.js} +2 -2
- package/dist/chunk-XW2UZICE.js +372 -0
- package/dist/{chunk-2AKYFREM.js → chunk-XZ6UFQ52.js} +11 -11
- package/dist/chunk-Y3JU5RPK.js +8 -0
- package/dist/chunk-YKRJTYNP.js +1143 -0
- package/dist/{chunk-PWWSIB2A.js → chunk-ZGIGW4ZG.js} +5 -5
- package/dist/cli/index.js +34 -36
- package/dist/{clio-QQCMTUZE.js → clio-L2P7S2R2.js} +9 -9
- package/dist/{code-nav-GUPM6766.js → code-nav-B5LNX4KU.js} +25 -25
- package/dist/{components-TNIKXCBH.js → components-63MMQKUT.js} +6 -6
- package/dist/{config-IIM7YOD3.js → config-YXARKGTX.js} +70 -67
- package/dist/{configure-4ZM5HWJX.js → configure-LMVQJ46J.js} +47 -35
- package/dist/{context-OL5P3HEP.js → context-7HJEWTTP.js} +87 -44
- package/dist/{context-44BZLJ3J.js → context-XSZKKFBW.js} +14 -14
- package/dist/{context-AIDVQKMW.js → context-YG2LZDYZ.js} +60 -58
- package/dist/{context-clear-OQV76MYP.js → context-clear-AC5NXHM2.js} +57 -55
- package/dist/{context-index-HP2JFUWA.js → context-index-KKTPRV5G.js} +3 -3
- package/dist/{context-map-INTXD54D.js → context-map-T7ROR5D5.js} +4 -4
- package/dist/{context-working-set-ZUW3EGLS.js → context-working-set-F4Q4J3NS.js} +12 -10
- package/dist/{detail-UXPWRANG.js → detail-H73BEF2N.js} +58 -56
- package/dist/{dispatch-runner-P3ZW6G77.js → dispatch-runner-3RY5FSJC.js} +74 -72
- package/dist/{doctor-JJVGPZWT.js → doctor-EQYJOGUG.js} +44 -30
- package/dist/{eval-V2RTN3UH.js → eval-4P7O6CCE.js} +109 -46
- package/dist/{evidence-35PYWGSO.js → evidence-D6GUSYJW.js} +57 -55
- package/dist/{evidence-CIGGKI6J.js → evidence-O76QF7TZ.js} +62 -59
- package/dist/{evolve-33SM3NJP.js → evolve-H47BCETS.js} +58 -56
- package/dist/{extensions-YVRHX6ZI.js → extensions-NNL3ZOCU.js} +98 -20
- package/dist/{fleet-LFO7SIPC.js → fleet-KMNS6NOM.js} +106 -99
- package/dist/{fleet-commands-RLK72GU3.js → fleet-commands-DOWSYCBX.js} +14 -14
- package/dist/{fleet-decisions-3SBSCTCW.js → fleet-decisions-S3PTZV2D.js} +9 -9
- package/dist/{fleet-graph-JZIBCGMW.js → fleet-graph-F2DE2TME.js} +26 -24
- package/dist/{fleet-inspect-2L5YGGZJ.js → fleet-inspect-EN2Q6IVB.js} +60 -57
- package/dist/{fleet-preflight-QRSHIIDE.js → fleet-preflight-FRLETDD3.js} +3 -3
- package/dist/{fleet-validate-LIAVKDUU.js → fleet-validate-B2XDLS57.js} +28 -29
- package/dist/{fleet-verify-JIK3OQZR.js → fleet-verify-4JKUWGJ7.js} +57 -55
- package/dist/{fleet-view-IWHYGQKK.js → fleet-view-BHJFW26B.js} +60 -57
- package/dist/{init-NJEDOTQW.js → init-XAT5N5YM.js} +79 -74
- package/dist/interop-FVECHFKG.js +246 -0
- package/dist/{inventory-74UL7UHU.js → inventory-7KFQGLCV.js} +60 -57
- package/dist/library-NY2XOT75.js +492 -0
- package/dist/library-QAPAO23R.js +306 -0
- package/dist/library-import-5Y6MAS3R.js +183 -0
- package/dist/library-inventory-JT6HWITQ.js +56 -0
- package/dist/library-validation-EQUH25DC.js +42 -0
- package/dist/{memory-I76I5VUH.js → memory-DYVTTCP6.js} +58 -56
- package/dist/{models-D4YDIQZQ.js → models-MASFJ6Y2.js} +48 -36
- package/dist/{monitor-NKVD55HX.js → monitor-YMP4NXJJ.js} +64 -61
- package/dist/{orchestrator-I6OATVPK.js → orchestrator-AFQRRTEI.js} +3685 -1841
- package/dist/{panes-7BTYH3XQ.js → panes-D3Y2KFG5.js} +4 -4
- package/dist/{panes-WPOMEMRH.js → panes-NICTHQCV.js} +7 -7
- package/dist/{paths-J3KN7UAO.js → paths-PSFAUIGO.js} +5 -5
- package/dist/{preload-EJAWJEIO.js → preload-5Q7VXRFJ.js} +57 -55
- package/dist/{reset-4XMQKDNZ.js → reset-7NKZK7JN.js} +9 -9
- package/dist/{resources-TVYVXK3Q.js → resources-NILSIZAT.js} +94 -38
- package/dist/{run-OWQNNSJU.js → run-BPZGEBZV.js} +121 -105
- package/dist/{share-NPZZMUXG.js → share-EZ6ERBMH.js} +31 -28
- package/dist/skills-BTVVNYVM.js +100 -0
- package/dist/{skills-eval-J5TCKSJA.js → skills-eval-UY34MNK7.js} +110 -72
- package/dist/{skills-inventory-7II4DM57.js → skills-inventory-JDHSIA7I.js} +30 -25
- package/dist/{slash-commands-MDSDSWYF.js → slash-commands-K4FNQ2AT.js} +49 -46
- package/dist/{steer-S7D7IKPU.js → steer-2B3EQGFH.js} +4 -4
- package/dist/{support-5VAEC32W.js → support-L2SOL3IE.js} +7 -7
- package/dist/{targets-KILZEOCE.js → targets-44VKGFLN.js} +64 -58
- package/dist/{tasks-R6P6OV22.js → tasks-3KODKFU7.js} +12 -12
- package/dist/{terminal-lease-LZCG2KN3.js → terminal-lease-LXA7MMPO.js} +32 -19
- package/dist/{tools-6OCQ6SVB.js → tools-3UB7TEVR.js} +7 -7
- package/dist/{trace-JHLXWUMN.js → trace-TAMIU4OJ.js} +5 -4
- package/dist/{tui-primitives-RCY2HN7G.js → tui-primitives-A6MUW32V.js} +3 -2
- package/dist/{uninstall-FXYMFFRT.js → uninstall-QYVRPEM4.js} +9 -9
- package/dist/{upgrade-D2OZH6IQ.js → upgrade-7PMKM2JH.js} +15 -16
- package/dist/{usage-PIASNUS4.js → usage-6EQV7EQK.js} +70 -67
- package/dist/{verifiers-LTHUY2PX.js → verifiers-JLITWSHU.js} +15 -15
- package/dist/{verify-HYF7KBVE.js → verify-T7NAEVIG.js} +13 -13
- package/dist/{web-fetch-MQN4FH3X.js → web-fetch-W4TNW4Q7.js} +4 -4
- package/dist/{wiki-generate-RK7JQ5NP.js → wiki-generate-T2TJQJUA.js} +81 -76
- package/dist/{with-panes-OFTNAR4Y.js → with-panes-CHFC7HGI.js} +4 -4
- package/dist/worker/entry.js +283 -76
- package/docs/README.md +43 -0
- package/docs/architecture/architecture.md +8 -7
- package/docs/architecture/artifact-versions.md +3 -3
- package/docs/architecture/context-engine.md +35 -1
- package/docs/architecture/library.md +32 -0
- package/docs/architecture/middleware-and-components.md +1 -1
- package/docs/architecture/model-catalog.md +21 -1
- package/docs/architecture/pi-boundary.md +18 -0
- package/docs/architecture/prompt-envelope-and-tools.md +5 -5
- package/docs/architecture/safety-model.md +21 -2
- package/docs/architecture/session-lifecycle.md +12 -1
- package/docs/architecture/tui-design.md +108 -9
- package/docs/architecture/worker-context.md +106 -0
- package/docs/guide/authoring-plugins.md +160 -0
- package/docs/guide/built-in-agents.md +5 -5
- package/docs/guide/commands-and-modes.md +161 -56
- package/docs/guide/configuration-and-targets.md +1 -1
- package/docs/guide/configuration-reference.md +27 -34
- package/docs/guide/environment-variables.md +2 -2
- package/docs/guide/exit-codes-and-output.md +1 -1
- package/docs/guide/extensions-and-sharing.md +93 -53
- package/docs/guide/fleet-dispatch.md +31 -4
- package/docs/guide/glossary.md +1 -1
- package/docs/guide/harness-extensions.md +291 -0
- package/docs/guide/installation-and-lifecycle.md +9 -9
- package/docs/guide/interop.md +243 -0
- package/docs/guide/panes-and-files.md +3 -3
- package/docs/guide/plugins.md +80 -0
- package/docs/guide/resource-library.md +111 -45
- package/docs/guide/skills-marketplace.md +35 -72
- package/docs/guide/tool-usage.md +19 -7
- package/docs/guide/troubleshooting.md +1 -1
- package/docs/process/development-pipeline.md +14 -14
- package/docs/process/documentation-coverage.md +28 -1
- package/docs/process/documentation-guide.md +15 -7
- package/docs/process/eval-runner.md +8 -3
- package/docs/process/performance-methodology.md +1 -1
- package/docs/process/release-cut-checklist.md +4 -0
- package/docs/process/scientific-validation.md +23 -0
- package/evals/scalar-decision-machinery.ts +1 -1
- package/examples/extensions/README.md +67 -0
- package/examples/extensions/lab-status/clio-coder-extension.json +14 -0
- package/examples/extensions/lab-status/extension.mjs +68 -0
- package/examples/extensions/lab-status/jobs.synthetic.json +9 -0
- package/examples/extensions/measurements/clio-coder-extension.json +28 -0
- package/examples/extensions/measurements/summarize.cjs +23 -0
- package/library/README.md +109 -0
- package/library/_authoring/templates/agent/README.md +28 -0
- package/library/_authoring/templates/agent/agents/benchmark-scout.md +30 -0
- package/library/_authoring/templates/agent/plugin.json +23 -0
- package/library/_authoring/templates/fleet/README.md +29 -0
- package/library/_authoring/templates/fleet/fleets/pipeline-review.md +31 -0
- package/library/_authoring/templates/fleet/plugin.json +23 -0
- package/library/_authoring/templates/plugin/README.md +37 -0
- package/library/_authoring/templates/plugin/agents/data-curator.md +31 -0
- package/library/_authoring/templates/plugin/assets/curation-guide.md +22 -0
- package/library/_authoring/templates/plugin/plugin.json +42 -0
- package/library/_authoring/templates/plugin/prompts/inspect-dataset.md +15 -0
- package/library/_authoring/templates/plugin/skills/dataset-curation/SKILL.md +36 -0
- package/library/_authoring/templates/plugin/skills/dataset-curation/evals.md +17 -0
- package/library/_authoring/templates/prompt/README.md +28 -0
- package/library/_authoring/templates/prompt/plugin.json +23 -0
- package/library/_authoring/templates/prompt/prompts/paper-summary.md +26 -0
- package/library/_authoring/templates/skill/README.md +24 -0
- package/library/_authoring/templates/skill/SKILL.md +39 -0
- package/library/_authoring/templates/skill/evals.md +30 -0
- package/library/_authoring/templates/skill/plugin.json +23 -0
- package/library/agents/README.md +7 -0
- package/library/fleets/README.md +7 -0
- package/library/plugins/materio/README.md +137 -0
- package/library/plugins/materio/ai.iowarp.clio/agents/materio-lab-definer.md +208 -0
- package/library/plugins/materio/ai.iowarp.clio/agents/materio-literature-reviewer.md +308 -0
- package/library/plugins/materio/ai.iowarp.clio/agents/materio-research-explorer.md +249 -0
- package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-executor.md +416 -0
- package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-verifier.md +60 -0
- package/library/plugins/materio/ai.iowarp.clio/agents/materio-workflow-planner.md +238 -0
- package/library/plugins/materio/ai.iowarp.clio/fleets/materio-execute-task.md +50 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/add-task.md +66 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/archive-task.md +65 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/checkpoint.md +26 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-research-tasks.md +230 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-virtual-lab.md +181 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/execute-task.md +292 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/help.md +129 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/identify-research.md +206 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/literature-review.md +201 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/pause-research.md +12 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/progress.md +105 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/remove-task.md +63 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/resume-research.md +64 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/settings.md +16 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/status.md +92 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/upload-data.md +104 -0
- package/library/plugins/materio/ai.iowarp.clio/prompts/materio/wtfp.md +145 -0
- package/library/plugins/materio/ai.iowarp.clio/references/execution.md +56 -0
- package/library/plugins/materio/ai.iowarp.portability/provenance.json +9 -0
- package/library/plugins/materio/assets/actions/add-task.md +86 -0
- package/library/plugins/materio/assets/actions/archive-task.md +84 -0
- package/library/plugins/materio/assets/actions/checkpoint.md +47 -0
- package/library/plugins/materio/assets/actions/define-research-tasks.md +228 -0
- package/library/plugins/materio/assets/actions/define-virtual-lab.md +179 -0
- package/library/plugins/materio/assets/actions/execute-task.md +290 -0
- package/library/plugins/materio/assets/actions/help.md +140 -0
- package/library/plugins/materio/assets/actions/identify-research.md +204 -0
- package/library/plugins/materio/assets/actions/literature-review.md +199 -0
- package/library/plugins/materio/assets/actions/pause-research.md +34 -0
- package/library/plugins/materio/assets/actions/progress.md +125 -0
- package/library/plugins/materio/assets/actions/remove-task.md +82 -0
- package/library/plugins/materio/assets/actions/resume-research.md +84 -0
- package/library/plugins/materio/assets/actions/settings.md +38 -0
- package/library/plugins/materio/assets/actions/status.md +112 -0
- package/library/plugins/materio/assets/actions/upload-data.md +123 -0
- package/library/plugins/materio/assets/actions/wtfp.md +179 -0
- package/library/plugins/materio/assets/references/research-domains.md +134 -0
- package/library/plugins/materio/assets/references/research-policy.md +77 -0
- package/library/plugins/materio/assets/references/traditional-workflows.md +146 -0
- package/library/plugins/materio/assets/scripts/check_physics.py +271 -0
- package/library/plugins/materio/assets/scripts/check_scripts.py +248 -0
- package/library/plugins/materio/assets/scripts/project_plugin.py +165 -0
- package/library/plugins/materio/assets/scripts/research_state.py +400 -0
- package/library/plugins/materio/assets/scripts/verify_citations.py +616 -0
- package/library/plugins/materio/assets/templates/RESEARCH.md +39 -0
- package/library/plugins/materio/assets/templates/VIRTUAL-LAB.md +120 -0
- package/library/plugins/materio/assets/templates/WORKFLOW.md +42 -0
- package/library/plugins/materio/assets/templates/config.json +5 -0
- package/library/plugins/materio/evals/scripts.yaml +29 -0
- package/library/plugins/materio/plugin.json +530 -0
- package/library/plugins/materio/skills/materio-lab-definer/SKILL.md +74 -0
- package/library/plugins/materio/skills/materio-literature-reviewer/SKILL.md +64 -0
- package/library/plugins/materio/skills/materio-research-explorer/SKILL.md +74 -0
- package/library/plugins/materio/skills/materio-task-executor/SKILL.md +214 -0
- package/library/plugins/materio/skills/materio-task-verifier/SKILL.md +46 -0
- package/library/plugins/materio/skills/materio-workflow-planner/SKILL.md +79 -0
- package/library/plugins/materio/tests/test_check_physics.py +139 -0
- package/library/plugins/materio/tests/test_check_scripts.py +140 -0
- package/library/plugins/materio/tests/test_research_state.py +291 -0
- package/library/plugins/materio/tests/test_verify_citations.py +337 -0
- package/library/prompts/README.md +7 -0
- package/library/registry.yaml +921 -0
- package/library/skills/README.md +120 -0
- package/{skills → library/skills}/coding/ast-grep/SKILL.md +1 -1
- package/{skills → library/skills}/coding/ast-grep/evals.md +1 -1
- package/library/skills/coding/ast-grep/plugin.json +23 -0
- package/{skills → library/skills}/coding/coding-standards/SKILL.md +1 -1
- package/{skills → library/skills}/coding/coding-standards/evals.md +1 -1
- package/library/skills/coding/coding-standards/plugin.json +23 -0
- package/{skills → library/skills}/coding/prototype/SKILL.md +1 -1
- package/{skills → library/skills}/coding/prototype/evals.md +1 -1
- package/library/skills/coding/prototype/plugin.json +23 -0
- package/{skills → library/skills}/coding/tdd/SKILL.md +1 -1
- package/{skills → library/skills}/coding/tdd/evals.md +1 -1
- package/library/skills/coding/tdd/plugin.json +23 -0
- package/{skills → library/skills}/context/context-handoff/SKILL.md +1 -1
- package/{skills → library/skills}/context/context-handoff/evals.md +1 -1
- package/library/skills/context/context-handoff/plugin.json +23 -0
- package/{skills → library/skills}/context/context-prime/SKILL.md +1 -1
- package/{skills → library/skills}/context/context-prime/evals.md +1 -1
- package/library/skills/context/context-prime/plugin.json +23 -0
- package/{skills → library/skills}/git/branch-closeout/SKILL.md +1 -1
- package/library/skills/git/branch-closeout/plugin.json +23 -0
- package/{skills → library/skills}/git/file-ticket/SKILL.md +1 -1
- package/library/skills/git/file-ticket/plugin.json +23 -0
- package/{skills → library/skills}/git/fix-issue/SKILL.md +1 -1
- package/library/skills/git/fix-issue/plugin.json +23 -0
- package/{skills → library/skills}/git/resolve-merge-conflicts/SKILL.md +1 -1
- package/{skills → library/skills}/git/resolve-merge-conflicts/evals.md +1 -1
- package/library/skills/git/resolve-merge-conflicts/plugin.json +23 -0
- package/{skills → library/skills}/git/ship/SKILL.md +1 -1
- package/library/skills/git/ship/plugin.json +23 -0
- package/{skills → library/skills}/git/worktree-create/SKILL.md +1 -1
- package/library/skills/git/worktree-create/plugin.json +23 -0
- package/{skills → library/skills}/git/worktree-merge/SKILL.md +1 -1
- package/library/skills/git/worktree-merge/plugin.json +23 -0
- package/{skills → library/skills}/meta/clio-coder-dev/SKILL.md +1 -1
- package/{skills → library/skills}/meta/clio-coder-dev/evals.md +1 -1
- package/library/skills/meta/clio-coder-dev/plugin.json +23 -0
- package/{skills → library/skills}/meta/clio-coder-test/SKILL.md +1 -1
- package/{skills → library/skills}/meta/clio-coder-test/evals.md +1 -1
- package/library/skills/meta/clio-coder-test/plugin.json +23 -0
- package/{skills → library/skills}/meta/credentials/SKILL.md +1 -1
- package/{skills → library/skills}/meta/credentials/evals.md +1 -1
- package/library/skills/meta/credentials/plugin.json +23 -0
- package/library/skills/meta/find-skills/SKILL.md +85 -0
- package/library/skills/meta/find-skills/evals.md +65 -0
- package/library/skills/meta/find-skills/plugin.json +23 -0
- package/{skills → library/skills}/meta/herdr/SKILL.md +1 -1
- package/{skills → library/skills}/meta/herdr/evals.md +1 -1
- package/library/skills/meta/herdr/plugin.json +23 -0
- package/{skills → library/skills}/meta/skill-craft/SKILL.md +23 -9
- package/{skills → library/skills}/meta/skill-craft/evals.md +11 -3
- package/library/skills/meta/skill-craft/plugin.json +23 -0
- package/{skills → library/skills}/planning/archify/SKILL.md +13 -13
- package/library/skills/planning/archify/plugin.json +23 -0
- package/{skills → library/skills}/planning/architecture/SKILL.md +1 -1
- package/{skills → library/skills}/planning/architecture/evals.md +1 -1
- package/library/skills/planning/architecture/plugin.json +23 -0
- package/{skills → library/skills}/planning/backlog/SKILL.md +1 -1
- package/{skills → library/skills}/planning/backlog/evals.md +1 -1
- package/library/skills/planning/backlog/plugin.json +23 -0
- package/{skills → library/skills}/planning/prd/SKILL.md +1 -1
- package/{skills → library/skills}/planning/prd/evals.md +1 -1
- package/library/skills/planning/prd/plugin.json +23 -0
- package/{skills → library/skills}/planning/product-intent/SKILL.md +1 -1
- package/{skills → library/skills}/planning/product-intent/evals.md +1 -1
- package/library/skills/planning/product-intent/plugin.json +23 -0
- package/{skills → library/skills}/planning/tech-spec/SKILL.md +1 -1
- package/{skills → library/skills}/planning/tech-spec/evals.md +1 -1
- package/library/skills/planning/tech-spec/plugin.json +23 -0
- package/{skills → library/skills}/registry.yaml +7 -7
- package/{skills → library/skills}/remote.yaml +1 -1
- package/{skills → library/skills}/research/arxiv-literature/SKILL.md +1 -1
- package/{skills → library/skills}/research/arxiv-literature/evals.md +1 -1
- package/library/skills/research/arxiv-literature/plugin.json +23 -0
- package/{skills → library/skills}/research/experiment-protocol/SKILL.md +1 -1
- package/{skills → library/skills}/research/experiment-protocol/evals.md +1 -1
- package/library/skills/research/experiment-protocol/plugin.json +23 -0
- package/{skills → library/skills}/research/scientific-debugging/SKILL.md +1 -1
- package/{skills → library/skills}/research/scientific-debugging/evals.md +1 -1
- package/library/skills/research/scientific-debugging/plugin.json +23 -0
- package/{skills → library/skills}/research/scientific-modernization/SKILL.md +1 -1
- package/{skills → library/skills}/research/scientific-modernization/evals.md +1 -1
- package/library/skills/research/scientific-modernization/plugin.json +23 -0
- package/{skills → library/skills}/skill-marketplace.json +37 -37
- package/{skills → library/skills}/workflow/cut-it/SKILL.md +1 -1
- package/{skills → library/skills}/workflow/cut-it/evals.md +1 -1
- package/library/skills/workflow/cut-it/plugin.json +23 -0
- package/{skills → library/skills}/workflow/design-council/SKILL.md +1 -1
- package/{skills → library/skills}/workflow/design-council/evals.md +1 -1
- package/library/skills/workflow/design-council/plugin.json +23 -0
- package/{skills → library/skills}/workflow/grill-me/SKILL.md +1 -1
- package/{skills → library/skills}/workflow/grill-me/evals.md +1 -1
- package/library/skills/workflow/grill-me/plugin.json +23 -0
- package/{skills → library/skills}/workflow/workflow-distiller/SKILL.md +14 -11
- package/{skills → library/skills}/workflow/workflow-distiller/evals.md +14 -6
- package/library/skills/workflow/workflow-distiller/plugin.json +23 -0
- package/package.json +12 -5
- package/src/cli/agents.ts +1 -1
- package/src/cli/config-inspect.ts +1 -1
- package/src/cli/configure.ts +2 -2
- package/src/cli/eval.ts +40 -6
- package/src/cli/extensions.ts +74 -8
- package/src/cli/fleet-preflight.ts +2 -0
- package/src/cli/fleet.ts +2 -0
- package/src/cli/index.ts +1 -3
- package/src/cli/interop-inspect.ts +61 -33
- package/src/cli/interop.ts +79 -9
- package/src/cli/library-import.ts +139 -0
- package/src/cli/library.ts +418 -120
- package/src/cli/run.ts +26 -9
- package/src/cli/skills-eval.ts +43 -6
- package/src/cli/skills-inventory.ts +6 -2
- package/src/cli/skills.ts +44 -491
- package/src/core/bus-events.ts +5 -0
- package/src/core/defaults.ts +1 -1
- package/src/core/recent-models.ts +2 -2
- package/src/core/session-routing.ts +3 -3
- package/src/core/state-file-lock.ts +1 -1
- package/src/core/tool-names.ts +5 -0
- package/src/domains/agents/extension.ts +42 -6
- package/src/domains/agents/fleet-commands.ts +92 -1
- package/src/domains/agents/fleet-contract.ts +87 -19
- package/src/domains/agents/recipe.ts +5 -4
- package/src/domains/agents/registry.ts +80 -24
- package/src/domains/config/keybindings.ts +155 -95
- package/src/domains/context/worker/contract.ts +91 -0
- package/src/domains/context/worker/pressure.ts +120 -0
- package/src/domains/context/worker/recall.ts +62 -0
- package/src/domains/context/worker/select.ts +164 -0
- package/src/domains/context/worker/snapshot.ts +35 -0
- package/src/domains/context/worker/store.ts +16 -0
- package/src/domains/context/working-set/replay/synthetic.ts +2 -1
- package/src/domains/dispatch/active-route-planner.ts +2 -0
- package/src/domains/dispatch/backoff.ts +1 -0
- package/src/domains/dispatch/code-step.ts +12 -2
- package/src/domains/dispatch/contract.ts +3 -0
- package/src/domains/dispatch/execution-plan.ts +2 -0
- package/src/domains/dispatch/extension.ts +109 -27
- package/src/domains/dispatch/fleet-plan.ts +10 -0
- package/src/domains/dispatch/fleet-run.ts +1 -0
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +4 -0
- package/src/domains/dispatch/state.ts +1 -0
- package/src/domains/dispatch/types.ts +5 -0
- package/src/domains/dispatch/validation.ts +12 -0
- package/src/domains/dispatch/workspace-checkpoint.ts +1 -1
- package/src/domains/evidence/failure-attribution.ts +1 -0
- package/src/domains/evidence/trust-status.ts +22 -3
- package/src/domains/extensions/command-schema.ts +145 -0
- package/src/domains/extensions/command-tools.ts +15 -0
- package/src/domains/extensions/compatibility.ts +7 -0
- package/src/domains/extensions/contract.ts +0 -4
- package/src/domains/extensions/discovery.ts +69 -205
- package/src/domains/extensions/extension.ts +0 -4
- package/src/domains/extensions/index.ts +1 -5
- package/src/domains/extensions/manager.ts +1 -6
- package/src/domains/extensions/operator-commands.ts +29 -0
- package/src/domains/extensions/operator-runtime.ts +483 -0
- package/src/domains/extensions/public-api.ts +53 -0
- package/src/domains/extensions/runtime-child.mjs +114 -0
- package/src/domains/extensions/runtime-process.ts +306 -0
- package/src/domains/extensions/runtime-schema.ts +146 -0
- package/src/domains/extensions/{resources.ts → snapshot-access.ts} +1 -17
- package/src/domains/extensions/snapshot.ts +4 -32
- package/src/domains/extensions/state.ts +5 -83
- package/src/domains/extensions/types.ts +33 -34
- package/src/domains/interop/adopt.ts +546 -0
- package/src/domains/interop/detect.ts +50 -12
- package/src/domains/interop/foreign.ts +554 -0
- package/src/domains/interop/import.ts +277 -0
- package/src/domains/interop/index.ts +24 -0
- package/src/domains/interop/install.ts +6 -0
- package/src/domains/interop/inventory.ts +351 -0
- package/src/domains/interop/projection.ts +360 -0
- package/src/domains/interop/registry.ts +106 -3
- package/src/domains/interop/types.ts +51 -0
- package/src/domains/lifecycle/migrations/index.ts +0 -2
- package/src/domains/lifecycle/naming-resources.ts +1 -1
- package/src/domains/middleware/marketplace-offer.ts +1 -1
- package/src/domains/mux/contract.ts +1 -1
- package/src/domains/plugins/catalog.ts +204 -0
- package/src/domains/plugins/contract.ts +24 -0
- package/src/domains/plugins/discovery.ts +316 -0
- package/src/domains/plugins/extension.ts +40 -0
- package/src/domains/plugins/index.ts +77 -0
- package/src/domains/plugins/integrity.ts +6 -0
- package/src/domains/plugins/manifest.ts +3 -0
- package/src/domains/plugins/resources.ts +102 -0
- package/src/domains/plugins/state.ts +753 -0
- package/src/domains/plugins/types.ts +217 -0
- package/src/domains/prompts/extension.ts +9 -2
- package/src/domains/prompts/fragments/operating/skills.md +10 -10
- package/src/domains/resources/common-loader.ts +9 -6
- package/src/domains/resources/index.ts +67 -0
- package/src/domains/resources/library-actions.ts +836 -0
- package/src/domains/resources/library-evals.ts +38 -0
- package/src/domains/resources/library-inventory.ts +1048 -0
- package/src/domains/resources/library-types.ts +50 -0
- package/src/domains/resources/library-validation.ts +634 -0
- package/src/domains/resources/library.ts +437 -156
- package/src/domains/resources/package-references.ts +66 -0
- package/src/domains/resources/prompts/loader.ts +75 -41
- package/src/domains/resources/skills/install.ts +2 -2
- package/src/domains/resources/skills/loader.ts +77 -22
- package/src/domains/resources/skills/marketplace.ts +48 -57
- package/src/domains/resources/skills/promotion.ts +2 -2
- package/src/domains/resources/skills/provenance-pin.ts +17 -4
- package/src/domains/safety/action-classifier.ts +2 -2
- package/src/domains/safety/default-path-policy.ts +3 -1
- package/src/domains/safety/policy-engine.ts +1 -1
- package/src/domains/safety/protected-artifacts.ts +21 -5
- package/src/domains/safety/skill-authority.ts +5 -2
- package/src/domains/share/archive.ts +1 -1
- package/src/engine/apis/openai-completions.ts +52 -2
- package/src/engine/notices/pi-tui-LICENSE +21 -0
- package/src/engine/tui.ts +3 -0
- package/src/engine/worker-runtime.ts +58 -14
- package/src/engine/worker-tools.ts +5 -0
- package/src/entry/orchestrator.ts +26 -5
- package/src/entry/plugin-reload.ts +18 -0
- package/src/interactive/application-controller.ts +67 -21
- package/src/interactive/chat-loop.ts +32 -5
- package/src/interactive/chat-panel.ts +5 -1
- package/src/interactive/clio-editor.ts +53 -21
- package/src/interactive/command-output.ts +56 -1
- package/src/interactive/editor-submit.ts +65 -28
- package/src/interactive/fleet-run-preview.ts +2 -0
- package/src/interactive/follow-up-queue-panel.ts +3 -3
- package/src/interactive/footer/dashboard.ts +4 -1
- package/src/interactive/footer/notifications.ts +2 -2
- package/src/interactive/footer/widgets.ts +2 -2
- package/src/interactive/interactive-application.ts +209 -21
- package/src/interactive/interactive-input-runtime.ts +254 -7
- package/src/interactive/interactive-presentation.ts +41 -12
- package/src/interactive/interactive-slash-runtime.ts +37 -8
- package/src/interactive/keybinding-manager.ts +156 -79
- package/src/interactive/keyboard-owner.ts +37 -0
- package/src/interactive/leader-key.ts +49 -102
- package/src/interactive/leader-menu.ts +45 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +9 -1
- package/src/interactive/overlay-frame.ts +15 -0
- package/src/interactive/overlay-key-routing.ts +46 -47
- package/src/interactive/overlay-lifecycle.ts +30 -15
- package/src/interactive/overlay-resource-openers.ts +56 -46
- package/src/interactive/overlays/ask-user.ts +630 -556
- package/src/interactive/overlays/extension-panel.ts +70 -0
- package/src/interactive/overlays/extensions.ts +28 -5
- package/src/interactive/overlays/fleet-run-approval.ts +7 -3
- package/src/interactive/overlays/help-reference.ts +89 -40
- package/src/interactive/overlays/interop.ts +122 -3
- package/src/interactive/overlays/keybinding-detail.ts +2 -2
- package/src/interactive/overlays/library-lifecycle.ts +90 -0
- package/src/interactive/overlays/library-model.ts +574 -0
- package/src/interactive/overlays/library-review.ts +557 -0
- package/src/interactive/overlays/library-tabs.ts +3 -15
- package/src/interactive/overlays/library.ts +602 -0
- package/src/interactive/overlays/list-overlay.ts +218 -39
- package/src/interactive/overlays/model-selector.ts +28 -25
- package/src/interactive/overlays/session-selector.ts +9 -3
- package/src/interactive/overlays/settings.ts +25 -18
- package/src/interactive/overlays/tree-selector.ts +16 -11
- package/src/interactive/permission-hint.ts +13 -0
- package/src/interactive/permission-overlay.ts +77 -28
- package/src/interactive/prompt-source-label.ts +21 -0
- package/src/interactive/renderers/reference-card.ts +35 -0
- package/src/interactive/renderers/worker-entry.ts +35 -3
- package/src/interactive/slash-autocomplete.ts +99 -1
- package/src/interactive/slash-commands.ts +390 -67
- package/src/interactive/slash-spec.ts +0 -1
- package/src/interactive/terminal-lease.ts +44 -12
- package/src/interactive/turn-queues.ts +8 -7
- package/src/interactive/turn-runtime.ts +1 -1
- package/src/interactive/view/view-overlay.ts +19 -14
- package/src/interactive/welcome-dashboard.ts +525 -408
- package/src/tools/bootstrap.ts +8 -0
- package/src/tools/builtin-tool-catalog.ts +7 -2
- package/src/tools/context/index.ts +58 -5
- package/src/tools/context/library.ts +465 -0
- package/src/tools/context/surface.ts +20 -6
- package/src/tools/core-bootstrap.ts +3 -0
- package/src/tools/dispatch-admission.ts +24 -1
- package/src/tools/dispatch-arguments.ts +8 -0
- package/src/tools/dispatch-plan.ts +32 -0
- package/src/tools/dispatch-schema.ts +31 -1
- package/src/tools/dispatch-types.ts +3 -0
- package/src/tools/dispatch.ts +1 -1
- package/src/tools/harness-extensions.ts +169 -0
- package/src/tools/observation.ts +4 -0
- package/src/tools/policy.ts +7 -1
- package/src/tools/registry.ts +19 -1
- package/src/tools/worker-evidence.ts +5 -0
- package/src/worker/context-seed.ts +192 -0
- package/src/worker/entry.ts +1 -0
- package/src/worker/spec-contract.ts +8 -1
- package/dist/chunk-3UW3KU4A.js +0 -21
- package/dist/chunk-536HXRFE.js +0 -1257
- package/dist/chunk-B3MOMLJ4.js +0 -433
- package/dist/chunk-CXQ37WJH.js +0 -45
- package/dist/chunk-KTFSFCVN.js +0 -46
- package/dist/chunk-QCOV5DFY.js +0 -911
- package/dist/chunk-QRFXEO6Y.js +0 -17
- package/dist/chunk-VAHLPXPY.js +0 -399
- package/dist/interop-RVCAYECG.js +0 -115
- package/dist/library-CTKZA7K3.js +0 -226
- package/dist/skills-OXFEAWMT.js +0 -510
- package/skills/README.md +0 -418
- package/skills/meta/find-skills/SKILL.md +0 -78
- package/skills/meta/find-skills/evals.md +0 -47
- package/src/domains/extensions/resource-path.ts +0 -27
- package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +0 -27
- package/src/interactive/overlays/agents.ts +0 -70
- package/src/interactive/overlays/library-install-confirm.ts +0 -152
- package/src/interactive/overlays/prompts.ts +0 -89
- package/src/interactive/overlays/skills-hub.ts +0 -615
- /package/{skills → library/skills}/coding/ast-grep/references/rule_reference.md +0 -0
- /package/{skills → library/skills}/coding/prototype/references/LOGIC.md +0 -0
- /package/{skills → library/skills}/coding/prototype/references/UI.md +0 -0
- /package/{skills → library/skills}/coding/tdd/references/mocking.md +0 -0
- /package/{skills → library/skills}/coding/tdd/references/tests.md +0 -0
- /package/{skills → library/skills}/context/context-handoff/scripts/new-handoff.sh +0 -0
- /package/{skills → library/skills}/git/branch-closeout/evals.md +0 -0
- /package/{skills → library/skills}/git/branch-closeout/references/closeout-checklist.md +0 -0
- /package/{skills → library/skills}/git/file-ticket/assets/issue-template.md +0 -0
- /package/{skills → library/skills}/git/file-ticket/evals.md +0 -0
- /package/{skills → library/skills}/git/file-ticket/references/issue-discovery.md +0 -0
- /package/{skills → library/skills}/git/fix-issue/evals.md +0 -0
- /package/{skills → library/skills}/git/fix-issue/references/diagnosis-and-rca.md +0 -0
- /package/{skills → library/skills}/git/resolve-merge-conflicts/references/conflict-matrix.md +0 -0
- /package/{skills → library/skills}/git/ship/assets/pr-template.md +0 -0
- /package/{skills → library/skills}/git/ship/evals.md +0 -0
- /package/{skills → library/skills}/git/ship/references/remote-and-branch-policy.md +0 -0
- /package/{skills → library/skills}/git/worktree-create/evals.md +0 -0
- /package/{skills → library/skills}/git/worktree-create/references/worktree-setup.md +0 -0
- /package/{skills → library/skills}/git/worktree-merge/evals.md +0 -0
- /package/{skills → library/skills}/git/worktree-merge/references/merge-strategies.md +0 -0
- /package/{skills → library/skills}/meta/clio-coder-test/references/harness.md +0 -0
- /package/{skills → library/skills}/meta/clio-coder-test/references/test-map.md +0 -0
- /package/{skills → library/skills}/planning/archify/evals.md +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Traditional Research Workflows in Material Science
|
|
2
|
+
|
|
3
|
+
## 1. Experimental Research Workflow
|
|
4
|
+
**Best for**: New material synthesis, property measurement, structure-property relationships
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
Task 01: Literature review & gap identification
|
|
8
|
+
Task 02: Hypothesis formulation
|
|
9
|
+
Task 03: Experimental design (DOE, sample matrix)
|
|
10
|
+
Task 04: Sample/specimen preparation
|
|
11
|
+
Task 05: Characterization (structure)
|
|
12
|
+
Task 06: Property measurement (mechanical / functional / etc.)
|
|
13
|
+
Task 07: Data analysis & statistical treatment
|
|
14
|
+
Task 08: Interpretation & mechanism identification
|
|
15
|
+
Task 09: Write-up & publication
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Key assumptions to interview about each task**:
|
|
19
|
+
- Task 03: What variables are being controlled? What is the sample size?
|
|
20
|
+
- Task 04: What processing routes are available? What are contamination risks?
|
|
21
|
+
- Task 05: What characterization tools are accessible? What resolution is needed?
|
|
22
|
+
- Task 06: What standards (ASTM, ISO) apply? What test conditions?
|
|
23
|
+
- Task 07: What statistical methods? Are outliers expected?
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. Computational Research Workflow
|
|
28
|
+
**Best for**: Property prediction, screening, mechanism understanding, new hypothesis generation
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Task 01: Literature review & gap identification
|
|
32
|
+
Task 02: Problem formulation & model selection
|
|
33
|
+
Task 03: Parameter validation (benchmarking vs. experiment)
|
|
34
|
+
Task 04: Main simulations / calculations
|
|
35
|
+
Task 05: Convergence & sensitivity testing
|
|
36
|
+
Task 06: Data analysis & visualization
|
|
37
|
+
Task 07: Interpretation & physical insight
|
|
38
|
+
Task 08: Experimental validation (if applicable)
|
|
39
|
+
Task 09: Write-up & publication
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Key assumptions per task**:
|
|
43
|
+
- Task 02: DFT vs. MD vs. phase-field? What exchange-correlation functional?
|
|
44
|
+
- Task 03: What experimental data exists for benchmarking?
|
|
45
|
+
- Task 04: What system sizes and timescales are computationally feasible?
|
|
46
|
+
- Task 05: What convergence criteria are acceptable?
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 3. Integrated Experimental + Computational Workflow
|
|
51
|
+
**Best for**: Mechanistic studies, structure-property-processing relationships
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Task 01: Literature review & gap identification
|
|
55
|
+
Task 02: Hypothesis formulation
|
|
56
|
+
Task 03: Computational screening / pre-selection
|
|
57
|
+
Task 04: Experimental design based on computational insights
|
|
58
|
+
Task 05: Sample preparation
|
|
59
|
+
Task 06: Characterization
|
|
60
|
+
Task 07: Property measurement
|
|
61
|
+
Task 08: Computational validation / refinement
|
|
62
|
+
Task 09: Mechanism elucidation (combined)
|
|
63
|
+
Task 10: Write-up & publication
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 4. Materials Optimization Workflow
|
|
69
|
+
**Best for**: Alloy design, processing parameter optimization, performance maximization
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Task 01: Literature review; identify composition/process space
|
|
73
|
+
Task 02: Design of experiments (DOE) or high-throughput plan
|
|
74
|
+
Task 03: Sample library preparation
|
|
75
|
+
Task 04: Rapid characterization (screening)
|
|
76
|
+
Task 05: Property measurement (screening)
|
|
77
|
+
Task 06: Down-selection & focused study
|
|
78
|
+
Task 07: Detailed characterization of top candidates
|
|
79
|
+
Task 08: Mechanism analysis
|
|
80
|
+
Task 09: Performance validation (application-relevant conditions)
|
|
81
|
+
Task 10: Write-up & publication
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 5. Literature Review / Meta-Analysis Workflow
|
|
87
|
+
**Best for**: Review papers, meta-analysis, identifying trends across datasets
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
Task 01: Define scope & inclusion/exclusion criteria
|
|
91
|
+
Task 02: Database search & paper collection
|
|
92
|
+
Task 03: Abstract screening
|
|
93
|
+
Task 04: Full-text review & data extraction
|
|
94
|
+
Task 05: Data harmonization (units, conditions, definitions)
|
|
95
|
+
Task 06: Statistical analysis / meta-analysis
|
|
96
|
+
Task 07: Trend identification & gap analysis
|
|
97
|
+
Task 08: Synthesis & narrative development
|
|
98
|
+
Task 09: Write review paper
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 6. Device / Application Workflow
|
|
104
|
+
**Best for**: Proof-of-concept demonstration, prototype development
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Task 01: Literature review; material requirements & state of art
|
|
108
|
+
Task 02: Material selection / design
|
|
109
|
+
Task 03: Fabrication process development
|
|
110
|
+
Task 04: Device assembly
|
|
111
|
+
Task 05: Performance testing (device-level)
|
|
112
|
+
Task 06: Degradation / lifetime study
|
|
113
|
+
Task 07: Benchmarking vs. state-of-art
|
|
114
|
+
Task 08: Write-up & publication
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Task Type Definitions
|
|
120
|
+
|
|
121
|
+
| Type | What It Means | Agent Behavior |
|
|
122
|
+
|------|---------------|----------------|
|
|
123
|
+
| `literature` | Search, read, synthesize papers | Review supplied corpus and permitted provided URLs, then summarize → update LITERATURE.md |
|
|
124
|
+
| `experimental` | Physical lab work | Generate protocol + recording template + checklist |
|
|
125
|
+
| `computational` | Simulation / calculation | Generate input files + analysis scripts |
|
|
126
|
+
| `analytical` | Mathematical modeling, theory | Derive equations + validate against data |
|
|
127
|
+
| `data-analysis` | Process existing data | Write analysis code + produce figures |
|
|
128
|
+
| `writing` | Draft paper sections | Prepare author-reviewed paper handoff |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Checkpoint Placement Guidelines
|
|
133
|
+
|
|
134
|
+
Place `checkpoint:human-action` when:
|
|
135
|
+
- Experimental data needs to be uploaded before analysis can proceed
|
|
136
|
+
- A go/no-go decision is needed based on preliminary results
|
|
137
|
+
- Equipment access or resource availability must be confirmed
|
|
138
|
+
|
|
139
|
+
Place `checkpoint:decision` when:
|
|
140
|
+
- Two valid experimental paths exist (e.g., XRD vs. neutron diffraction)
|
|
141
|
+
- Computational model must be chosen (DFT vs. MD vs. phase-field)
|
|
142
|
+
- Scope must be narrowed after unexpected preliminary results
|
|
143
|
+
|
|
144
|
+
Place `checkpoint:human-verify` when:
|
|
145
|
+
- Assumptions have been generated and need domain expert sign-off
|
|
146
|
+
- Analysis results need interpretation before the next task begins
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
check_physics; scan Materio task outputs for physically impossible or
|
|
4
|
+
implausible numeric values.
|
|
5
|
+
|
|
6
|
+
It reads generated protocol / results / input files, extracts (value, unit)
|
|
7
|
+
pairs, and checks them against physical bounds:
|
|
8
|
+
|
|
9
|
+
* absolute temperature below 0 K (or below -273.15 C / -459.67 F) -> ERROR
|
|
10
|
+
* density <= 0, or implausibly high (> 30 g/cm3) -> ERROR / WARN
|
|
11
|
+
* a fraction unit (wt%, at%, mol%, vol%) outside 0-100 -> ERROR
|
|
12
|
+
* a plain % tied to a bounded quantity (porosity, purity, ...) -> ERROR
|
|
13
|
+
* an alloy composition block whose wt%/at% values do not sum ~100 -> WARN
|
|
14
|
+
|
|
15
|
+
DESIGN; to keep false positives low, v1 only asserts things that are
|
|
16
|
+
unconditionally true. It does not flag a value merely for being negative:
|
|
17
|
+
many materials quantities are legitimately negative (DFT total / formation
|
|
18
|
+
energies, binding enthalpies, stresses, thermal-expansion mismatch,
|
|
19
|
+
coordinates), as are temperature differences, rates, and gradients. Only
|
|
20
|
+
quantities that are non-negative by definition (absolute temperature,
|
|
21
|
+
density, a bounded fraction) are sign-checked.
|
|
22
|
+
|
|
23
|
+
Exit status: non-zero if any ERROR. Zero deps (Python stdlib only).
|
|
24
|
+
|
|
25
|
+
Usage:
|
|
26
|
+
python3 assets/scripts/check_physics.py .research/tasks/task-01/*.md
|
|
27
|
+
python3 assets/scripts/check_physics.py --json protocol.md
|
|
28
|
+
"""
|
|
29
|
+
import argparse
|
|
30
|
+
import json
|
|
31
|
+
import re
|
|
32
|
+
import sys
|
|
33
|
+
|
|
34
|
+
# A signed number that is NOT the tail of a range like "250-300" or "5.0-6".
|
|
35
|
+
# The lookbehind rejects a preceding digit/dot/comma so range internals and
|
|
36
|
+
# en-dash ranges ("250–300", en-dash is not a sign) are not read as negative.
|
|
37
|
+
_NUM = r"(?<![\d.,])([-−]?\d[\d,]*\.?\d*(?:[eE][+-]?\d+)?)"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _to_float(s):
|
|
41
|
+
return float(s.replace(",", "").replace("−", "-"))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# ---- findings -------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
class Findings:
|
|
47
|
+
def __init__(self):
|
|
48
|
+
self.errors = []
|
|
49
|
+
self.warnings = []
|
|
50
|
+
|
|
51
|
+
def error(self, path, line, rule, msg):
|
|
52
|
+
self.errors.append((path, line, rule, msg))
|
|
53
|
+
|
|
54
|
+
def warn(self, path, line, rule, msg):
|
|
55
|
+
self.warnings.append((path, line, rule, msg))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# ---- individual checks ----------------------------------------------------
|
|
59
|
+
|
|
60
|
+
def _iter_matches(pattern, text):
|
|
61
|
+
for m in re.finditer(pattern, text):
|
|
62
|
+
line_no = text.count("\n", 0, m.start()) + 1
|
|
63
|
+
yield m, line_no
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# A temperature UNIT also appears in signed quantities that are legitimately
|
|
67
|
+
# negative: differences (ΔT), rates (K/s), and gradients (K/mm). We only
|
|
68
|
+
# sign-check a value that reads as an ABSOLUTE temperature; one not followed
|
|
69
|
+
# by "/" (a rate/gradient) and not on a line about a delta/rate/gradient.
|
|
70
|
+
_TEMP_SIGNED_CTX = re.compile(
|
|
71
|
+
r"Δ|∆|\bdelta\b|\bgradient\b|\brate\b|\bchange\b|\bdifference\b",
|
|
72
|
+
re.IGNORECASE)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def check_temperature(text, path, fnd):
|
|
76
|
+
for ln, line in enumerate(text.splitlines(), 1):
|
|
77
|
+
signed = _TEMP_SIGNED_CTX.search(line)
|
|
78
|
+
for m in re.finditer(_NUM + r"\s*K\b(?!\s*/)", line):
|
|
79
|
+
v = _to_float(m.group(1))
|
|
80
|
+
if v < 0 and not signed:
|
|
81
|
+
fnd.error(path, ln, "temp-kelvin",
|
|
82
|
+
f"{v:g} K is below absolute zero (0 K)")
|
|
83
|
+
elif v > 100000:
|
|
84
|
+
fnd.warn(path, ln, "temp-kelvin",
|
|
85
|
+
f"{v:g} K is implausibly high; check units")
|
|
86
|
+
for m in re.finditer(_NUM + r"\s*(?:°\s*C|degC|℃)(?!\s*/)", line):
|
|
87
|
+
v = _to_float(m.group(1))
|
|
88
|
+
if v < -273.15 and not signed:
|
|
89
|
+
fnd.error(path, ln, "temp-celsius",
|
|
90
|
+
f"{v:g} C is below absolute zero (-273.15 C)")
|
|
91
|
+
for m in re.finditer(_NUM + r"\s*(?:°\s*F|degF|℉)(?!\s*/)", line):
|
|
92
|
+
v = _to_float(m.group(1))
|
|
93
|
+
if v < -459.67 and not signed:
|
|
94
|
+
fnd.error(path, ln, "temp-fahrenheit",
|
|
95
|
+
f"{v:g} F is below absolute zero (-459.67 F)")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# density units -> factor to convert into g/cm^3
|
|
99
|
+
_DENSITY = [
|
|
100
|
+
(r"g\s*/\s*cm\s*(?:\^?3|³)", 1.0),
|
|
101
|
+
(r"g\s*/\s*cc\b", 1.0),
|
|
102
|
+
(r"g\s*/\s*mL\b", 1.0),
|
|
103
|
+
(r"kg\s*/\s*m\s*(?:\^?3|³)", 0.001),
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def check_density(text, path, fnd):
|
|
108
|
+
for unit_re, factor in _DENSITY:
|
|
109
|
+
for m, ln in _iter_matches(_NUM + r"\s*(?:" + unit_re + r")", text):
|
|
110
|
+
v = _to_float(m.group(1)) * factor
|
|
111
|
+
if v <= 0:
|
|
112
|
+
fnd.error(path, ln, "density",
|
|
113
|
+
f"density {v:g} g/cm^3 must be positive")
|
|
114
|
+
elif v > 30:
|
|
115
|
+
fnd.warn(path, ln, "density",
|
|
116
|
+
f"density {v:g} g/cm^3 exceeds any known solid "
|
|
117
|
+
"(osmium ~22.6); check value/units")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# Fraction units are bounded 0-100 by definition.
|
|
121
|
+
_FRACTION_UNITS = r"(?:wt|at|mol|vol)\s*\.?\s*%"
|
|
122
|
+
# A bare % counts as a bounded fraction only near one of these words.
|
|
123
|
+
_BOUNDED_KEYWORDS = re.compile(
|
|
124
|
+
r"porosit|relative density|rel\.?\s*density|densit|purit|"
|
|
125
|
+
r"fraction|content|concentrat|abundance|yield|efficien|"
|
|
126
|
+
r"conversion|selectivit|recover", re.IGNORECASE)
|
|
127
|
+
# ...but not when the % is a relative change (which can exceed 100%), e.g.
|
|
128
|
+
# "efficiency improved by 250%".
|
|
129
|
+
_RELATIVE_CHANGE = re.compile(
|
|
130
|
+
r"\b(?:improv\w*|increas\w*|decreas\w*|reduc\w*|gain\w*|higher|lower\w*|"
|
|
131
|
+
r"relativ\w*|baselin\w*|faster|slower|growth)\b|×|\bx\d",
|
|
132
|
+
re.IGNORECASE)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def check_fractions(text, path, fnd):
|
|
136
|
+
for m, ln in _iter_matches(_NUM + r"\s*(?:" + _FRACTION_UNITS + r")", text):
|
|
137
|
+
v = _to_float(m.group(1))
|
|
138
|
+
if v < 0 or v > 100:
|
|
139
|
+
fnd.error(path, ln, "fraction",
|
|
140
|
+
f"{v:g}% is outside the valid 0-100% range")
|
|
141
|
+
for line_no, line in enumerate(text.splitlines(), 1):
|
|
142
|
+
if not _BOUNDED_KEYWORDS.search(line) or _RELATIVE_CHANGE.search(line):
|
|
143
|
+
continue
|
|
144
|
+
for m in re.finditer(_NUM + r"\s*%(?![a-zA-Z])", line):
|
|
145
|
+
v = _to_float(m.group(1))
|
|
146
|
+
if v < 0 or v > 100:
|
|
147
|
+
fnd.error(path, line_no, "fraction",
|
|
148
|
+
f"{v:g}% is outside 0-100% for a bounded quantity")
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def check_composition(text, path, fnd):
|
|
152
|
+
"""
|
|
153
|
+
Flag an alloy composition group whose wt%/at%/mol% values do not sum to
|
|
154
|
+
~100%. A group is either an inline list (>=2 same-unit values on one line,
|
|
155
|
+
e.g. "Ti 90 wt%, Al 6 wt%, V 4 wt%") or a contiguous run of lines each
|
|
156
|
+
carrying exactly one same-unit value (a vertical table). Conservative:
|
|
157
|
+
needs >=2 values and a total in a sane window, so unrelated scattered
|
|
158
|
+
percentages are not summed together.
|
|
159
|
+
"""
|
|
160
|
+
unit = re.compile(_NUM + r"\s*(" + _FRACTION_UNITS + r")")
|
|
161
|
+
lines = text.splitlines()
|
|
162
|
+
|
|
163
|
+
def check_group(values, kind, ref_line, span):
|
|
164
|
+
if len(values) >= 2:
|
|
165
|
+
total = sum(values)
|
|
166
|
+
if 80 <= total <= 120 and abs(total - 100) > 1.0:
|
|
167
|
+
fnd.warn(path, ref_line, "composition",
|
|
168
|
+
f"{kind} composition {span} sums to {total:g}% "
|
|
169
|
+
f"(expected ~100%)")
|
|
170
|
+
|
|
171
|
+
run, start_line, run_kind = [], None, None
|
|
172
|
+
|
|
173
|
+
def flush(end_line):
|
|
174
|
+
span = (f"block (lines {start_line}-{end_line})"
|
|
175
|
+
if end_line != start_line else f"on line {start_line}")
|
|
176
|
+
check_group(run, run_kind, start_line, span)
|
|
177
|
+
|
|
178
|
+
for i, line in enumerate(lines, 1):
|
|
179
|
+
by_kind = {}
|
|
180
|
+
for val, u in unit.findall(line):
|
|
181
|
+
k = re.sub(r"[\s.]", "", u).lower()
|
|
182
|
+
by_kind.setdefault(k, []).append(_to_float(val))
|
|
183
|
+
|
|
184
|
+
inline = {k: v for k, v in by_kind.items() if len(v) >= 2}
|
|
185
|
+
if inline: # inline composition list
|
|
186
|
+
if run:
|
|
187
|
+
flush(i - 1)
|
|
188
|
+
run, start_line, run_kind = [], None, None
|
|
189
|
+
for k, vals in inline.items():
|
|
190
|
+
check_group(vals, k, i, f"on line {i}")
|
|
191
|
+
continue
|
|
192
|
+
|
|
193
|
+
if len(by_kind) == 1 and sum(len(v) for v in by_kind.values()) == 1:
|
|
194
|
+
k = next(iter(by_kind)) # single value: vertical run
|
|
195
|
+
if run and k != run_kind:
|
|
196
|
+
flush(i - 1)
|
|
197
|
+
run, start_line, run_kind = [], None, None
|
|
198
|
+
if not run:
|
|
199
|
+
start_line, run_kind = i, k
|
|
200
|
+
run.append(by_kind[k][0])
|
|
201
|
+
else:
|
|
202
|
+
if run:
|
|
203
|
+
flush(i - 1)
|
|
204
|
+
run, start_line, run_kind = [], None, None
|
|
205
|
+
if run:
|
|
206
|
+
flush(len(lines))
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
CHECKS = [check_temperature, check_density, check_fractions, check_composition]
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# ---- driver ---------------------------------------------------------------
|
|
213
|
+
|
|
214
|
+
def scan(paths):
|
|
215
|
+
fnd = Findings()
|
|
216
|
+
for p in paths:
|
|
217
|
+
try:
|
|
218
|
+
with open(p, encoding="utf-8") as f:
|
|
219
|
+
text = f.read()
|
|
220
|
+
except OSError as e:
|
|
221
|
+
print(f"WARN: cannot read {p}: {e}", file=sys.stderr)
|
|
222
|
+
continue
|
|
223
|
+
for check in CHECKS:
|
|
224
|
+
check(text, p, fnd)
|
|
225
|
+
return fnd
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def main():
|
|
229
|
+
ap = argparse.ArgumentParser(description="Physical sanity checks for "
|
|
230
|
+
"Materio task outputs.")
|
|
231
|
+
ap.add_argument("paths", nargs="+", help="files to scan (.md, input files)")
|
|
232
|
+
ap.add_argument("--json", action="store_true", help="machine-readable output")
|
|
233
|
+
args = ap.parse_args()
|
|
234
|
+
|
|
235
|
+
unreadable = []
|
|
236
|
+
for path in args.paths:
|
|
237
|
+
try:
|
|
238
|
+
with open(path, encoding="utf-8") as source:
|
|
239
|
+
source.read()
|
|
240
|
+
except (OSError, UnicodeError) as error:
|
|
241
|
+
unreadable.append({"file": path, "reason": str(error)})
|
|
242
|
+
readable = [path for path in args.paths if path not in {item["file"] for item in unreadable}]
|
|
243
|
+
fnd = scan(readable)
|
|
244
|
+
|
|
245
|
+
if args.json:
|
|
246
|
+
print(json.dumps({
|
|
247
|
+
"coverage": {"files_requested": len(args.paths), "files_read": len(readable), "unreadable": unreadable},
|
|
248
|
+
"errors": [{"file": p, "line": l, "rule": r, "message": m}
|
|
249
|
+
for p, l, r, m in fnd.errors],
|
|
250
|
+
"warnings": [{"file": p, "line": l, "rule": r, "message": m}
|
|
251
|
+
for p, l, r, m in fnd.warnings],
|
|
252
|
+
}, indent=2))
|
|
253
|
+
else:
|
|
254
|
+
def emit(items, label):
|
|
255
|
+
if not items:
|
|
256
|
+
return
|
|
257
|
+
print(f"\n{label} ({len(items)}):")
|
|
258
|
+
for p, l, r, m in sorted(items):
|
|
259
|
+
print(f" {p}:{l} [{r}] {m}")
|
|
260
|
+
emit(fnd.errors, "IMPOSSIBLE (errors)")
|
|
261
|
+
emit(fnd.warnings, "IMPLAUSIBLE (warnings)")
|
|
262
|
+
n = len(fnd.errors) + len(fnd.warnings)
|
|
263
|
+
print(f"\ncheck-physics: {len(fnd.errors)} error(s), "
|
|
264
|
+
f"{len(fnd.warnings)} warning(s)."
|
|
265
|
+
+ ("" if n else " No physical-sanity issues found."))
|
|
266
|
+
|
|
267
|
+
return 2 if unreadable else 1 if fnd.errors else 0
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
if __name__ == "__main__":
|
|
271
|
+
sys.exit(main())
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
check_scripts; "runnable by construction" checks for the Materio code
|
|
4
|
+
generates in computational / data-analysis tasks. A generated script that
|
|
5
|
+
doesn't parse, imports a package that doesn't exist, or is a silent stub
|
|
6
|
+
fails only when the researcher runs it; these checks catch that earlier.
|
|
7
|
+
|
|
8
|
+
For each generated file this checks, without executing anything:
|
|
9
|
+
|
|
10
|
+
Python (.py)
|
|
11
|
+
* syntax ; ast.parse; a SyntaxError is a hard bug -> ERROR
|
|
12
|
+
* imports ; top-level imports that are neither stdlib, a
|
|
13
|
+
recognized scientific package, nor a sibling
|
|
14
|
+
script (likely a typo / hallucinated package) -> WARN
|
|
15
|
+
* stubs ; bare `...`, `raise NotImplementedError`,
|
|
16
|
+
pass-only functions, or template placeholders
|
|
17
|
+
(path/to/, YOUR_, <...>, TODO/FIXME) -> WARN
|
|
18
|
+
Shell (.sh, .bash)
|
|
19
|
+
* syntax ; `bash -n` -> ERROR
|
|
20
|
+
|
|
21
|
+
Nothing is imported or run, so this is safe on untrusted generated code and
|
|
22
|
+
has no environment dependencies (a package being importable in the user's
|
|
23
|
+
env is deliberately NOT required; that would false-positive in CI).
|
|
24
|
+
|
|
25
|
+
Exit status: non-zero if any ERROR. Zero third-party deps.
|
|
26
|
+
|
|
27
|
+
Usage:
|
|
28
|
+
python3 assets/scripts/check_scripts.py .research/tasks/task-01/*.py
|
|
29
|
+
python3 assets/scripts/check_scripts.py --json task-01-analysis.py
|
|
30
|
+
"""
|
|
31
|
+
import argparse
|
|
32
|
+
import ast
|
|
33
|
+
import json
|
|
34
|
+
import os
|
|
35
|
+
import re
|
|
36
|
+
import subprocess
|
|
37
|
+
import sys
|
|
38
|
+
|
|
39
|
+
# Common scientific / materials-science packages an analysis script may import.
|
|
40
|
+
# Anything here OR in the stdlib OR a sibling .py is "recognized".
|
|
41
|
+
KNOWN_PACKAGES = {
|
|
42
|
+
"numpy", "scipy", "pandas", "matplotlib", "mpl_toolkits", "seaborn",
|
|
43
|
+
"sklearn", "skimage", "sympy", "statsmodels", "networkx", "numba", "cython",
|
|
44
|
+
"h5py", "netCDF4", "xarray", "zarr", "plotly", "bokeh", "altair",
|
|
45
|
+
"tensorflow", "torch", "keras", "jax", "jaxlib", "pint", "uncertainties",
|
|
46
|
+
"lmfit", "tqdm", "requests", "yaml", "toml", "joblib", "numexpr", "dask",
|
|
47
|
+
"ase", "pymatgen", "phonopy", "phono3py", "spglib", "MDAnalysis",
|
|
48
|
+
"mdanalysis", "openmm", "rdkit", "pyvista", "vtk", "mayavi", "ovito",
|
|
49
|
+
"atomman", "lammps", "gpaw", "abipy", "aiida", "monty", "click", "typer",
|
|
50
|
+
"mp_api", "matminer", "fireworks", "custodian", "emmet", "pybamm",
|
|
51
|
+
"fenics", "dolfin", "meshio", "gmsh", "pillow", "PIL", "cv2", "numpydoc",
|
|
52
|
+
"pytest", "hypothesis", "sqlalchemy", "polars", "pyarrow",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Fallback for Python < 3.10, which has no sys.stdlib_module_names. Not
|
|
57
|
+
# exhaustive: a stdlib module missing here surfaces as an advisory import
|
|
58
|
+
# warning on an old interpreter, never as a crash.
|
|
59
|
+
_STDLIB_FALLBACK = {
|
|
60
|
+
"abc", "argparse", "ast", "asyncio", "base64", "bisect", "builtins",
|
|
61
|
+
"collections", "concurrent", "contextlib", "copy", "csv", "dataclasses",
|
|
62
|
+
"datetime", "decimal", "difflib", "enum", "errno", "fractions",
|
|
63
|
+
"functools", "glob", "gzip", "hashlib", "heapq", "http", "importlib",
|
|
64
|
+
"inspect", "io", "itertools", "json", "logging", "math",
|
|
65
|
+
"multiprocessing", "operator", "os", "pathlib", "pickle", "platform",
|
|
66
|
+
"pprint", "queue", "random", "re", "shlex", "shutil", "signal", "socket",
|
|
67
|
+
"statistics", "string", "struct", "subprocess", "sys", "tarfile",
|
|
68
|
+
"tempfile", "textwrap", "threading", "time", "timeit", "traceback",
|
|
69
|
+
"types", "typing", "unittest", "urllib", "uuid", "warnings", "weakref",
|
|
70
|
+
"xml", "zipfile", "zlib",
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def stdlib_names():
|
|
75
|
+
"""Top-level stdlib module names: sys.stdlib_module_names on 3.10+,
|
|
76
|
+
the hardcoded fallback set otherwise."""
|
|
77
|
+
names = getattr(sys, "stdlib_module_names", None)
|
|
78
|
+
return set(names) if names else set(_STDLIB_FALLBACK)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class Findings:
|
|
82
|
+
def __init__(self):
|
|
83
|
+
self.errors = []
|
|
84
|
+
self.warnings = []
|
|
85
|
+
|
|
86
|
+
def error(self, path, line, rule, msg):
|
|
87
|
+
self.errors.append((path, line, rule, msg))
|
|
88
|
+
|
|
89
|
+
def warn(self, path, line, rule, msg):
|
|
90
|
+
self.warnings.append((path, line, rule, msg))
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
_PLACEHOLDER_TEXT = re.compile(
|
|
94
|
+
r"path/to/|/path/to|YOUR_[A-Z]|<[a-z_]+>|\bTODO\b|\bFIXME\b|"
|
|
95
|
+
r"REPLACE_ME|FILL_IN|XXXX", re.IGNORECASE)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _top_module(name):
|
|
99
|
+
return (name or "").split(".")[0]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _stub_findings(tree, path, fnd):
|
|
103
|
+
for node in ast.walk(tree):
|
|
104
|
+
# bare `...` used as a statement (not numpy `a[...]` indexing)
|
|
105
|
+
if (isinstance(node, ast.Expr) and isinstance(node.value, ast.Constant)
|
|
106
|
+
and node.value.value is Ellipsis):
|
|
107
|
+
fnd.warn(path, node.lineno, "stub",
|
|
108
|
+
"bare `...` placeholder; body not implemented")
|
|
109
|
+
if isinstance(node, ast.Raise):
|
|
110
|
+
exc = node.exc
|
|
111
|
+
name = None
|
|
112
|
+
if isinstance(exc, ast.Call):
|
|
113
|
+
name = getattr(exc.func, "id", None)
|
|
114
|
+
elif isinstance(exc, ast.Name):
|
|
115
|
+
name = exc.id
|
|
116
|
+
if name == "NotImplementedError":
|
|
117
|
+
fnd.warn(path, node.lineno, "stub",
|
|
118
|
+
"raises NotImplementedError; not implemented")
|
|
119
|
+
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
120
|
+
body = node.body
|
|
121
|
+
if body and isinstance(body[0], ast.Expr) and \
|
|
122
|
+
isinstance(body[0].value, ast.Constant) and \
|
|
123
|
+
isinstance(body[0].value.value, str):
|
|
124
|
+
body = body[1:] # drop docstring
|
|
125
|
+
if len(body) == 1 and isinstance(body[0], ast.Pass):
|
|
126
|
+
fnd.warn(path, node.lineno, "stub",
|
|
127
|
+
f"function '{node.name}' has an empty (pass-only) body")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def check_python(text, path, fnd, local_modules):
|
|
131
|
+
try:
|
|
132
|
+
tree = ast.parse(text, filename=path)
|
|
133
|
+
except SyntaxError as e:
|
|
134
|
+
fnd.error(path, e.lineno or 0, "syntax",
|
|
135
|
+
f"SyntaxError: {e.msg}")
|
|
136
|
+
return
|
|
137
|
+
# imports
|
|
138
|
+
known = stdlib_names() | KNOWN_PACKAGES | local_modules
|
|
139
|
+
for node in ast.walk(tree):
|
|
140
|
+
if isinstance(node, ast.Import):
|
|
141
|
+
for alias in node.names:
|
|
142
|
+
mod = _top_module(alias.name)
|
|
143
|
+
if mod and mod not in known:
|
|
144
|
+
fnd.warn(path, node.lineno, "import",
|
|
145
|
+
f"'{mod}' is not stdlib or a recognized package "
|
|
146
|
+
"— check spelling / that it's real")
|
|
147
|
+
elif isinstance(node, ast.ImportFrom):
|
|
148
|
+
if node.level: # relative import: skip
|
|
149
|
+
continue
|
|
150
|
+
mod = _top_module(node.module)
|
|
151
|
+
if mod and mod not in known:
|
|
152
|
+
fnd.warn(path, node.lineno, "import",
|
|
153
|
+
f"'{mod}' is not stdlib or a recognized package "
|
|
154
|
+
"— check spelling / that it's real")
|
|
155
|
+
# stubs (AST-based) + textual placeholders
|
|
156
|
+
_stub_findings(tree, path, fnd)
|
|
157
|
+
for i, line in enumerate(text.splitlines(), 1):
|
|
158
|
+
m = _PLACEHOLDER_TEXT.search(line)
|
|
159
|
+
if not m:
|
|
160
|
+
continue
|
|
161
|
+
where = "in comment" if line.lstrip().startswith("#") else "in code"
|
|
162
|
+
fnd.warn(path, i, "placeholder",
|
|
163
|
+
f"template placeholder {where}: '{m.group(0)}'")
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def check_shell(path, fnd):
|
|
167
|
+
try:
|
|
168
|
+
r = subprocess.run(["bash", "-n", path], capture_output=True,
|
|
169
|
+
text=True, timeout=15)
|
|
170
|
+
except (OSError, subprocess.SubprocessError) as e:
|
|
171
|
+
fnd.warn(path, 0, "shell", f"could not run `bash -n`: {e}")
|
|
172
|
+
return
|
|
173
|
+
if r.returncode != 0:
|
|
174
|
+
msg = (r.stderr or "").strip().splitlines()
|
|
175
|
+
fnd.error(path, 0, "syntax",
|
|
176
|
+
"bash syntax error: " + (msg[-1] if msg else "see bash -n"))
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def scan(paths):
|
|
180
|
+
fnd = Findings()
|
|
181
|
+
local_modules = {os.path.splitext(os.path.basename(p))[0]
|
|
182
|
+
for p in paths if p.endswith(".py")}
|
|
183
|
+
for p in paths:
|
|
184
|
+
try:
|
|
185
|
+
if p.endswith(".py"):
|
|
186
|
+
with open(p, encoding="utf-8") as f:
|
|
187
|
+
check_python(f.read(), p, fnd, local_modules)
|
|
188
|
+
elif p.endswith((".sh", ".bash")):
|
|
189
|
+
check_shell(p, fnd)
|
|
190
|
+
except OSError as e:
|
|
191
|
+
print(f"WARN: cannot read {p}: {e}", file=sys.stderr)
|
|
192
|
+
return fnd
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def main():
|
|
196
|
+
ap = argparse.ArgumentParser(
|
|
197
|
+
description="Runnable-by-construction checks for generated scripts.")
|
|
198
|
+
ap.add_argument("paths", nargs="+", help=".py / .sh files to check")
|
|
199
|
+
ap.add_argument("--json", action="store_true")
|
|
200
|
+
args = ap.parse_args()
|
|
201
|
+
|
|
202
|
+
unreadable = []
|
|
203
|
+
for path in args.paths:
|
|
204
|
+
try:
|
|
205
|
+
with open(path, encoding="utf-8") as source:
|
|
206
|
+
source.read()
|
|
207
|
+
except (OSError, UnicodeError) as error:
|
|
208
|
+
unreadable.append({"file": path, "reason": str(error)})
|
|
209
|
+
readable = [path for path in args.paths if path not in {item["file"] for item in unreadable}]
|
|
210
|
+
fnd = scan(readable)
|
|
211
|
+
|
|
212
|
+
if args.json:
|
|
213
|
+
print(json.dumps({
|
|
214
|
+
"coverage": {"files_requested": len(args.paths), "files_read": len(readable), "unreadable": unreadable},
|
|
215
|
+
"errors": [{"file": p, "line": l, "rule": r, "message": m}
|
|
216
|
+
for p, l, r, m in fnd.errors],
|
|
217
|
+
"warnings": [{"file": p, "line": l, "rule": r, "message": m}
|
|
218
|
+
for p, l, r, m in fnd.warnings],
|
|
219
|
+
}, indent=2))
|
|
220
|
+
else:
|
|
221
|
+
def emit(items, label):
|
|
222
|
+
if not items:
|
|
223
|
+
return
|
|
224
|
+
print(f"\n{label} ({len(items)}):")
|
|
225
|
+
for p, l, r, m in sorted(items):
|
|
226
|
+
loc = f"{p}:{l}" if l else p
|
|
227
|
+
print(f" {loc} [{r}] {m}")
|
|
228
|
+
emit(fnd.errors, "WILL NOT RUN (errors)")
|
|
229
|
+
emit(fnd.warnings, "SUSPECT (warnings)")
|
|
230
|
+
for item in unreadable:
|
|
231
|
+
print(f" UNREAD {item['file']} {item['reason']}")
|
|
232
|
+
n = len(fnd.errors) + len(fnd.warnings)
|
|
233
|
+
verdict = ""
|
|
234
|
+
if unreadable:
|
|
235
|
+
verdict = (f" {len(unreadable)} path(s) could not be read as script files"
|
|
236
|
+
" (pass .py/.sh files, not directories); coverage is incomplete.")
|
|
237
|
+
elif not readable:
|
|
238
|
+
verdict = " No files were checked."
|
|
239
|
+
elif not n:
|
|
240
|
+
verdict = " Checked scripts parse cleanly."
|
|
241
|
+
print(f"\ncheck-scripts: {len(fnd.errors)} error(s), "
|
|
242
|
+
f"{len(fnd.warnings)} warning(s)." + verdict)
|
|
243
|
+
|
|
244
|
+
return 2 if unreadable else 1 if fnd.errors else 0
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
if __name__ == "__main__":
|
|
248
|
+
sys.exit(main())
|