@iowarp/clio-coder 0.4.2 → 0.4.4
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/CHANGELOG.md +98 -0
- package/CONTRIBUTING.md +86 -19
- package/README.md +35 -6
- package/dist/{acp-TMDQZDIG.js → acp-WNAYYF4F.js} +12 -13
- package/dist/{agents-5N5NG3XG.js → agents-3OKXHLOI.js} +60 -57
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-Z5CCBXKQ.js → auth-VKNNMGPU.js} +21 -19
- package/dist/{builtins-K6TNDT24.js → builtins-WGALA46I.js} +9 -4
- package/dist/{chunk-XE3PCIXH.js → chunk-23L32XTI.js} +12 -9
- package/dist/{chunk-I64IFBLB.js → chunk-25QBEXRS.js} +18 -11
- package/dist/{chunk-CDNVLKUX.js → chunk-26QSH3EJ.js} +13 -7
- package/dist/{chunk-QQLGQY2A.js → chunk-2ASED4PZ.js} +22 -22
- package/dist/{chunk-MCEPRMZW.js → chunk-2CU2H6KE.js} +2 -2
- package/dist/chunk-2DSOYNFC.js +108 -0
- package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
- package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
- package/dist/{chunk-O3YUNJZ2.js → chunk-2ZSONWVL.js} +82 -25
- package/dist/{chunk-2NHR3NAY.js → chunk-36CT5VVL.js} +331 -42
- package/dist/{chunk-2X4RYJTJ.js → chunk-3GY4F45V.js} +3 -3
- package/dist/{chunk-ZW55JB7N.js → chunk-3ODX73FK.js} +4 -6
- package/dist/{chunk-PBP4B7XR.js → chunk-3UNOLWNZ.js} +3 -3
- package/dist/{chunk-4JDLP6ZS.js → chunk-3UUXNFEX.js} +14 -10
- package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
- package/dist/{chunk-ZW4HH5JJ.js → chunk-4M6Z5QVF.js} +6 -6
- package/dist/{chunk-K6BSR66V.js → chunk-4NSRCOYP.js} +4 -1
- package/dist/{chunk-M2DAX4F6.js → chunk-4WR7VSYB.js} +2 -2
- package/dist/{chunk-FSP7CMNU.js → chunk-54X7T7DK.js} +61 -6
- package/dist/{chunk-54ODD65L.js → chunk-5636DCO5.js} +4 -4
- package/dist/chunk-57XXR6DR.js +3763 -0
- package/dist/{chunk-3KIPBMUA.js → chunk-5ICU3EUH.js} +2 -2
- package/dist/{chunk-77QIVUZB.js → chunk-5MEZN6CB.js} +4 -4
- package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
- package/dist/{chunk-YJISEZKC.js → chunk-5TUB6SLS.js} +6 -6
- package/dist/{chunk-IMXMHHMQ.js → chunk-6OSVSQL5.js} +341 -57
- package/dist/{chunk-Q4XWMHX6.js → chunk-6PAZTBPA.js} +14 -2
- package/dist/{chunk-FVDGR2ZL.js → chunk-6Q3CYFD3.js} +112 -39
- package/dist/{chunk-IDNA72AH.js → chunk-6QOTUPRG.js} +155 -36
- package/dist/{chunk-X7IARSHT.js → chunk-6UINWWS6.js} +16 -10
- package/dist/{chunk-CYZW7JHJ.js → chunk-72YIHOZQ.js} +9 -9
- package/dist/{chunk-IKSLQ4XV.js → chunk-75W7L2E2.js} +752 -861
- package/dist/{chunk-CRFOIAX3.js → chunk-7UGL4MB5.js} +6 -6
- package/dist/{chunk-HIICAHCJ.js → chunk-AUPNRN7C.js} +2 -2
- package/dist/{chunk-7BHIY2MW.js → chunk-BJVFZO5U.js} +8 -50
- package/dist/{chunk-B74PXLU7.js → chunk-CUSRQKPU.js} +65 -3
- package/dist/chunk-DQOVN6KV.js +386 -0
- package/dist/{chunk-E7GT7O5N.js → chunk-DT3LWJOB.js} +7 -4
- package/dist/chunk-DXKJURES.js +671 -0
- package/dist/{chunk-JBCS7CRR.js → chunk-EL24TAU4.js} +10 -10
- package/dist/{chunk-TPEQIQIE.js → chunk-ELWDPP3Y.js} +8 -8
- package/dist/{chunk-NDINPTJ4.js → chunk-ELZVTCGV.js} +5 -4
- package/dist/chunk-EXLD33WO.js +381 -0
- package/dist/chunk-FEAXX7B6.js +101 -0
- package/dist/{chunk-RLYRBIYQ.js → chunk-FFUPXJC4.js} +90 -331
- package/dist/{chunk-5PFYMY2V.js → chunk-FTMGRKEF.js} +2 -2
- package/dist/{chunk-34BHNEE3.js → chunk-GHS5EBTQ.js} +58 -7
- package/dist/{chunk-DYHAXKHD.js → chunk-GWZNEVM2.js} +12 -8
- package/dist/chunk-GX5WYQO4.js +59 -0
- package/dist/chunk-GYV6VZOC.js +26 -0
- package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
- package/dist/chunk-I2DWJ4GM.js +390 -0
- package/dist/{chunk-TXOTCRLG.js → chunk-I5FWO7L5.js} +5 -5
- package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
- package/dist/{chunk-XQRY4DTA.js → chunk-IGLP3ODT.js} +10 -10
- package/dist/chunk-IRXAATOX.js +539 -0
- package/dist/chunk-IXIY2H4R.js +44 -0
- package/dist/{chunk-SSEYRH53.js → chunk-IZXGRF7P.js} +92 -147
- package/dist/{chunk-5TSRNF4G.js → chunk-JCI2ROMZ.js} +164 -6
- package/dist/{chunk-JWJGP5DQ.js → chunk-JEIYHLOR.js} +7 -7
- package/dist/{chunk-F2I26BDK.js → chunk-JQLNNIKT.js} +4 -4
- package/dist/{chunk-BYMNWQ7O.js → chunk-JSD46VO2.js} +315 -63
- package/dist/{chunk-AK5XEFVZ.js → chunk-JT2RFCC5.js} +64 -14
- package/dist/{chunk-MCMZMDAC.js → chunk-K6T2ZAMZ.js} +168 -6
- package/dist/{chunk-PGF63K6I.js → chunk-KFV5L5SK.js} +73 -4
- package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
- package/dist/{chunk-PJX3WQUQ.js → chunk-LLXSDWXS.js} +3 -3
- package/dist/{chunk-DZAW46HP.js → chunk-LTIKRKFL.js} +3 -3
- package/dist/{chunk-DZEK6CJN.js → chunk-N56KALIC.js} +21 -21
- package/dist/{chunk-B7HM5Z7T.js → chunk-NAI6ZFCY.js} +9 -5
- package/dist/{chunk-I66ZTYNP.js → chunk-NRO2BJRH.js} +2656 -2213
- package/dist/{chunk-ZGNYYXQ6.js → chunk-NXIMQY5W.js} +3 -3
- package/dist/{chunk-IKOZFYBN.js → chunk-NXYCB2VD.js} +149 -106
- package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
- package/dist/{chunk-462T4EGZ.js → chunk-O5CVSAG5.js} +2 -2
- package/dist/chunk-ODGTEFFI.js +50 -0
- package/dist/{chunk-3F7VUY77.js → chunk-OEJSLEPW.js} +2 -2
- package/dist/{chunk-KKOJXO6R.js → chunk-OMQNJVKW.js} +4 -2
- package/dist/{chunk-5KW52TEP.js → chunk-Q4WO54TA.js} +132 -77
- package/dist/{chunk-W6NIE6OW.js → chunk-QUFRYSWI.js} +13 -7
- package/dist/{chunk-42FMPA75.js → chunk-QZWQA4DE.js} +2 -2
- package/dist/chunk-R6Q67RJH.js +134 -0
- package/dist/{chunk-W4YEMFBX.js → chunk-RAY4OVGZ.js} +3 -3
- package/dist/{chunk-ZNT2M6TG.js → chunk-RQCKCSRL.js} +17 -17
- package/dist/{chunk-LJID3DYZ.js → chunk-RXTN6AKH.js} +3 -3
- package/dist/{chunk-P75RZCJW.js → chunk-RZDWV63N.js} +3 -3
- package/dist/{chunk-UH632ZYL.js → chunk-S6PYF2XF.js} +2 -2
- package/dist/{chunk-HJWWJ6IL.js → chunk-TOIVGRUX.js} +17 -5
- package/dist/{chunk-HLAFFSEK.js → chunk-TQAHXW6Y.js} +2 -2
- package/dist/{chunk-JIEGK6UF.js → chunk-U6TMQNSI.js} +48 -4
- package/dist/{chunk-2HFQNRV3.js → chunk-UEPWCCTY.js} +12 -12
- package/dist/chunk-UOIZ7DA4.js +41 -0
- package/dist/{chunk-UH347SHR.js → chunk-USR47QNF.js} +11 -11
- package/dist/{chunk-AZ4WMN4W.js → chunk-V6HJFQZE.js} +2 -2
- package/dist/chunk-V76WTFTW.js +318 -0
- package/dist/{chunk-NMJXSHBJ.js → chunk-W54I7H25.js} +2 -2
- package/dist/{chunk-KPXDY6QF.js → chunk-XRZT5WY5.js} +2 -2
- package/dist/{chunk-UBRFI4HS.js → chunk-XULDXHTN.js} +142 -50
- package/dist/chunk-XXYSBZIQ.js +283 -0
- package/dist/{chunk-HKMD33FO.js → chunk-Y55JBDO5.js} +405 -122
- package/dist/{chunk-XOXV5GKE.js → chunk-YD5GIKET.js} +17 -8
- package/dist/{chunk-XGDPUNND.js → chunk-YECAMM3D.js} +2 -2
- package/dist/{chunk-BO7Y52RY.js → chunk-YNFKXPEC.js} +7 -7
- package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
- package/dist/{chunk-M2WXEHER.js → chunk-ZA4VCIGV.js} +2 -2
- package/dist/cli/index.js +42 -40
- package/dist/{clio-7VB377CC.js → clio-QLICPCF5.js} +7 -7
- package/dist/{code-nav-YVLCYA7V.js → code-nav-IJR2DBPR.js} +9 -9
- package/dist/{components-UBWCQSRW.js → components-2TGAI2RC.js} +5 -6
- package/dist/{config-4HVOS65E.js → config-IUA6OYNS.js} +88 -81
- package/dist/{configure-PIWO7B24.js → configure-VEPX4NMX.js} +26 -25
- package/dist/{context-KQYIWPWT.js → context-2DKHWH2T.js} +60 -45
- package/dist/{context-IYEHL3WQ.js → context-4MPR7WKB.js} +78 -69
- package/dist/{context-N6ZE3LGJ.js → context-BOYF5EJM.js} +15 -11
- package/dist/{context-clear-G4OGZJDS.js → context-clear-S4ZJCQUX.js} +73 -65
- package/dist/context-map-COB37XXN.js +505 -0
- package/dist/{context-working-set-BWLF6LJP.js → context-working-set-3I3FYX6Y.js} +18 -17
- package/dist/detail-A7JAVSIG.js +98 -0
- package/dist/{dispatch-runner-2QQAITS3.js → dispatch-runner-RJ5I2F2O.js} +99 -75
- package/dist/{docs-PD3EXDKU.js → docs-SPOV3BAN.js} +3 -5
- package/dist/{doctor-LHBD36VU.js → doctor-DKICC2SN.js} +71 -48
- package/dist/{eval-C45FYRJ6.js → eval-OQOQUDHK.js} +308 -146
- package/dist/{eval-inventory-6DEJPLBF.js → eval-inventory-Y6QRFOH5.js} +4 -4
- package/dist/{evidence-6SHONYAF.js → evidence-4DQ25GUQ.js} +79 -175
- package/dist/evidence-4F5USFKH.js +208 -0
- package/dist/{evolve-KRKMV72X.js → evolve-GSS52E5J.js} +71 -67
- package/dist/{extensions-KPZ2UHBB.js → extensions-G7MFLYHT.js} +8 -9
- package/dist/{fleet-IVTCKDHT.js → fleet-Q37YHHAQ.js} +126 -118
- package/dist/{fleet-commands-EDWL3IT7.js → fleet-commands-G7E4N7SM.js} +16 -13
- package/dist/{fleet-decisions-YP3YEFGK.js → fleet-decisions-O7M6QBA2.js} +9 -8
- package/dist/{fleet-graph-ZFWKHY2M.js → fleet-graph-TOUBW6OW.js} +21 -20
- package/dist/{fleet-inspect-FVUNCBML.js → fleet-inspect-SW33JJNI.js} +65 -60
- package/dist/{fleet-preflight-UN5XED4R.js → fleet-preflight-CV2655TW.js} +4 -5
- package/dist/{fleet-validate-XOWC4HSX.js → fleet-validate-KESZX2YH.js} +25 -24
- package/dist/{fleet-verify-UN3SODEL.js → fleet-verify-UQPMTVE3.js} +66 -61
- package/dist/{fleet-view-TWHJKCN6.js → fleet-view-MN2VG4MR.js} +65 -60
- package/dist/{init-T2QORQ3Y.js → init-PXEXQSBF.js} +90 -82
- package/dist/{interop-IN5I2A66.js → interop-ZG5T62U3.js} +12 -13
- package/dist/inventory-C26CFDRR.js +101 -0
- package/dist/{library-LSCATDLZ.js → library-B2W4N74O.js} +29 -29
- package/dist/{memory-HYOKAGGJ.js → memory-YCANYS5A.js} +73 -69
- package/dist/{models-2GPMFYCM.js → models-GERTU3YI.js} +51 -47
- package/dist/{monitor-E4ASVUJH.js → monitor-CPNIUULB.js} +74 -67
- package/dist/{orchestrator-DDMPR3PY.js → orchestrator-J4BSH4WQ.js} +1288 -1606
- package/dist/{panes-E3RUXOW5.js → panes-BOHAEGYC.js} +4 -4
- package/dist/{panes-IXKLOKA2.js → panes-NXSLDQZ2.js} +10 -11
- package/dist/{paths-L7LGY6RN.js → paths-VSUWNC22.js} +6 -7
- package/dist/reset-TNWTB5LU.js +343 -0
- package/dist/{resources-OTRSN34L.js → resources-4PXNMD5G.js} +29 -22
- package/dist/{run-5DEYH5QK.js → run-D6XJ34CN.js} +132 -132
- package/dist/{share-IHWTLO3M.js → share-2NWMJJEE.js} +27 -27
- package/dist/{skills-IYMXMKW4.js → skills-KR7WON5G.js} +40 -33
- package/dist/{skills-eval-DROHSJAR.js → skills-eval-O2ZNOLDS.js} +81 -77
- package/dist/{skills-inventory-D7X4L4ZX.js → skills-inventory-ZZOUBK7O.js} +23 -22
- package/dist/{slash-commands-QBM7UZ3B.js → slash-commands-ZXPJD64J.js} +47 -37
- package/dist/{steer-Z5DO23FJ.js → steer-XA25PSCS.js} +4 -4
- package/dist/{support-U7QOWY26.js → support-7EMVWYG2.js} +6 -6
- package/dist/{targets-P2FUC4IL.js → targets-OMH2XCSN.js} +50 -49
- package/dist/tasks-IPAGMEIX.js +36 -0
- package/dist/{terminal-lease-YREJ3JX2.js → terminal-lease-C2J3JYRE.js} +4 -4
- package/dist/{tools-5B7RO6MV.js → tools-EFFEAIDP.js} +8 -9
- package/dist/{trace-YMGMUM6A.js → trace-FXMXUZUF.js} +7 -7
- package/dist/uninstall-HALS6BLF.js +407 -0
- package/dist/upgrade-MS72RJEP.js +306 -0
- package/dist/{usage-ME5MPXGX.js → usage-NHG6MCJM.js} +162 -108
- package/dist/{verifiers-BVZ7IWOO.js → verifiers-7AUNVXDY.js} +155 -22
- package/dist/{verify-5K7ZKQFC.js → verify-FWYGPKMR.js} +14 -12
- package/dist/{web-fetch-MPARV2K7.js → web-fetch-V4FKSDAV.js} +4 -4
- package/dist/{wiki-generate-F5W5QTYY.js → wiki-generate-743CIGJW.js} +99 -90
- package/dist/{with-panes-BYOJCLAM.js → with-panes-BDQEWBRT.js} +10 -10
- package/dist/worker/entry.js +72 -68
- package/docs/README.md +3 -2
- package/docs/architecture/acp.md +17 -0
- package/docs/architecture/artifact-placement.md +1 -0
- package/docs/architecture/artifact-versions.md +2 -2
- package/docs/architecture/context-engine.md +4 -0
- package/docs/architecture/dispatch-typed-intent.md +1 -1
- package/docs/architecture/evidence-and-memory.md +1 -1
- package/docs/architecture/middleware-and-components.md +1 -1
- package/docs/architecture/model-catalog.md +21 -10
- package/docs/architecture/observability.md +19 -2
- package/docs/architecture/prompt-envelope-and-tools.md +17 -5
- package/docs/architecture/provider-adapter-cookbook.md +63 -0
- package/docs/architecture/safety-model.md +25 -22
- package/docs/architecture/tui-design.md +1 -1
- package/docs/guide/built-in-agents.md +25 -11
- package/docs/guide/commands-and-modes.md +18 -3
- package/docs/guide/configuration-and-targets.md +100 -10
- package/docs/guide/configuration-reference.md +17 -7
- package/docs/guide/environment-variables.md +4 -2
- package/docs/guide/installation-and-lifecycle.md +37 -4
- package/docs/guide/proactive-memory.md +66 -55
- package/docs/guide/skills-marketplace.md +18 -0
- package/docs/guide/tool-usage.md +78 -3
- package/docs/history/config-knobs-audit.md +2 -2
- package/docs/process/development-pipeline.md +40 -2
- package/docs/process/eval-runner.md +67 -3
- package/docs/process/git-commit-provenance.md +15 -0
- package/docs/process/release-cut-checklist.md +207 -0
- package/docs/process/scientific-validation.md +18 -17
- package/evals/behavioral-machinery-support.ts +1 -0
- package/evals/behavioral-machinery.yaml +1 -1
- package/evals/behavioral-model.yaml +3 -2
- package/package.json +2 -2
- package/skills/README.md +7 -5
- package/skills/coding/ast-grep/SKILL.md +101 -30
- package/skills/coding/ast-grep/evals.md +26 -0
- package/skills/coding/coding-standards/SKILL.md +47 -2
- package/skills/coding/coding-standards/evals.md +23 -0
- package/skills/coding/prototype/SKILL.md +87 -28
- package/skills/coding/prototype/evals.md +19 -0
- package/skills/coding/tdd/SKILL.md +80 -53
- package/skills/coding/tdd/evals.md +20 -0
- package/skills/context/context-handoff/SKILL.md +43 -2
- package/skills/context/context-handoff/evals.md +44 -0
- package/skills/context/context-prime/SKILL.md +45 -15
- package/skills/context/context-prime/evals.md +45 -0
- package/skills/git/branch-closeout/SKILL.md +132 -0
- package/skills/git/branch-closeout/evals.md +133 -0
- package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
- package/skills/git/file-ticket/SKILL.md +77 -63
- package/skills/git/file-ticket/assets/issue-template.md +22 -0
- package/skills/git/file-ticket/evals.md +31 -26
- package/skills/git/file-ticket/references/issue-discovery.md +49 -0
- package/skills/git/fix-issue/SKILL.md +87 -64
- package/skills/git/fix-issue/evals.md +35 -31
- package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
- package/skills/git/resolve-merge-conflicts/SKILL.md +100 -51
- package/skills/git/resolve-merge-conflicts/evals.md +52 -25
- package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
- package/skills/git/ship/SKILL.md +103 -67
- package/skills/git/ship/assets/pr-template.md +21 -0
- package/skills/git/ship/evals.md +44 -28
- package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
- package/skills/git/worktree-create/SKILL.md +80 -50
- package/skills/git/worktree-create/evals.md +40 -33
- package/skills/git/worktree-create/references/worktree-setup.md +62 -66
- package/skills/git/worktree-merge/SKILL.md +112 -65
- package/skills/git/worktree-merge/evals.md +42 -34
- package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
- package/skills/planning/archify/SKILL.md +196 -0
- package/skills/planning/archify/evals.md +65 -0
- package/skills/planning/architecture/SKILL.md +61 -12
- package/skills/planning/architecture/evals.md +65 -0
- package/skills/planning/backlog/SKILL.md +130 -14
- package/skills/planning/backlog/evals.md +142 -0
- package/skills/planning/prd/SKILL.md +47 -6
- package/skills/planning/prd/evals.md +54 -0
- package/skills/planning/product-intent/SKILL.md +57 -2
- package/skills/planning/product-intent/evals.md +70 -0
- package/skills/planning/tech-spec/SKILL.md +53 -2
- package/skills/planning/tech-spec/evals.md +73 -0
- package/skills/registry.yaml +58 -50
- package/skills/remote.yaml +13 -0
- package/skills/research/arxiv-literature/SKILL.md +76 -18
- package/skills/research/arxiv-literature/evals.md +50 -0
- package/skills/research/experiment-protocol/SKILL.md +20 -1
- package/skills/research/experiment-protocol/evals.md +23 -0
- package/skills/research/scientific-debugging/SKILL.md +24 -1
- package/skills/research/scientific-debugging/evals.md +18 -0
- package/skills/research/scientific-modernization/SKILL.md +26 -1
- package/skills/research/scientific-modernization/evals.md +27 -0
- package/skills/skill-marketplace.json +63 -28
- package/skills/workflow/cut-it/SKILL.md +64 -5
- package/skills/workflow/cut-it/evals.md +101 -0
- package/skills/workflow/design-council/SKILL.md +112 -27
- package/skills/workflow/design-council/evals.md +161 -0
- package/skills/workflow/grill-me/SKILL.md +85 -10
- package/skills/workflow/grill-me/evals.md +153 -0
- package/skills/workflow/workflow-distiller/SKILL.md +76 -17
- package/skills/workflow/workflow-distiller/evals.md +118 -0
- package/src/cli/args.ts +0 -8
- package/src/cli/configure-interop.ts +105 -13
- package/src/cli/configure-oauth.ts +57 -0
- package/src/cli/configure-onboarding.ts +980 -0
- package/src/cli/configure-target.ts +594 -0
- package/src/cli/configure.ts +1084 -529
- package/src/cli/context-map.ts +114 -0
- package/src/cli/context.ts +4 -0
- package/src/cli/doctor-state-size.ts +1 -12
- package/src/cli/doctor-validation-contract.ts +28 -0
- package/src/cli/doctor.ts +5 -0
- package/src/cli/evidence-detail.ts +1 -75
- package/src/cli/evidence-inventory.ts +1 -167
- package/src/cli/index.ts +3 -0
- package/src/cli/lifecycle-presenter.ts +436 -0
- package/src/cli/models.ts +10 -2
- package/src/cli/modes/print.ts +5 -1
- package/src/cli/reset.ts +228 -106
- package/src/cli/run.ts +7 -4
- package/src/cli/select.ts +664 -0
- package/src/cli/skills.ts +9 -2
- package/src/cli/targets.ts +3 -0
- package/src/cli/tasks.ts +84 -0
- package/src/cli/uninstall.ts +233 -165
- package/src/cli/upgrade.ts +210 -150
- package/src/cli/usage.ts +92 -27
- package/src/cli/validate-model.ts +3 -3
- package/src/cli/verifiers.ts +147 -1
- package/src/cli/wiki-generate.ts +1 -0
- package/src/core/commit-attribution.ts +41 -1
- package/src/core/config.ts +56 -0
- package/src/core/external-diagnostic.ts +44 -0
- package/src/core/gateway-routing.ts +157 -0
- package/src/core/git-commit-attribution.ts +46 -3
- package/src/core/run-overrides.ts +0 -5
- package/src/core/safe-exec.ts +17 -2
- package/src/core/skill-activation.ts +92 -2
- package/src/core/tool-names.ts +5 -2
- package/src/domains/agents/builtins/architect.md +1 -1
- package/src/domains/agents/builtins/coder.md +1 -1
- package/src/domains/agents/builtins/documenter.md +1 -1
- package/src/domains/agents/builtins/git-master.md +1 -1
- package/src/domains/agents/builtins/provenance.md +7 -7
- package/src/domains/agents/builtins/tester.md +1 -1
- package/src/domains/agents/builtins/verifier.md +2 -2
- package/src/domains/agents/builtins/wiki-writer.md +4 -3
- package/src/domains/agents/builtins/world-knowledge.md +31 -0
- package/src/domains/agents/catalog.ts +1 -1
- package/src/domains/agents/result-contract.ts +70 -0
- package/src/domains/context/extension.ts +31 -7
- package/src/domains/context/refresh.ts +3 -0
- package/src/domains/context/wiki/frontmatter.ts +5 -2
- package/src/domains/context/wiki/generate.ts +6 -0
- package/src/domains/context/wiki/map-seed.ts +589 -0
- package/src/domains/context/wiki/plan.ts +2 -2
- package/src/domains/context/wiki/prompts.ts +43 -0
- package/src/domains/dispatch/active-route-planner.ts +4 -0
- package/src/domains/dispatch/admission.ts +29 -0
- package/src/domains/dispatch/agent-candidates.ts +10 -0
- package/src/domains/dispatch/budget-envelope.ts +86 -1
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/capacity-lease.ts +17 -0
- package/src/domains/dispatch/code-step.ts +11 -4
- package/src/domains/dispatch/contract.ts +42 -8
- package/src/domains/dispatch/execution-scheduler.ts +2 -0
- package/src/domains/dispatch/extension.ts +184 -56
- package/src/domains/dispatch/fleet-commit-attribution.ts +5 -0
- package/src/domains/dispatch/fleet-run.ts +1 -0
- package/src/domains/dispatch/host-verification.ts +114 -13
- package/src/domains/dispatch/intent.ts +28 -18
- package/src/domains/dispatch/orphan-recovery.ts +2 -0
- package/src/domains/dispatch/receipt-integrity.ts +4 -0
- package/src/domains/dispatch/reservation-store.ts +5 -3
- package/src/domains/dispatch/state.ts +15 -2
- package/src/domains/dispatch/types.ts +20 -2
- package/src/domains/dispatch/worker-model-metadata.ts +38 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
- package/src/domains/eval/metrics/token-stream.ts +201 -31
- package/src/domains/eval/metrics/tracked.ts +40 -4
- package/src/domains/eval/runners/clio-run.ts +17 -11
- package/src/domains/eval/runners/context-index.ts +2 -7
- package/src/domains/eval/runners/context-init.ts +3 -6
- package/src/domains/eval/runners/external-command.ts +29 -11
- package/src/domains/eval/schema/suite.ts +28 -0
- package/src/domains/eval/schema/verdict.ts +2 -2
- package/src/domains/eval/suites/resolve.ts +13 -1
- package/src/domains/eval/suites/run.ts +24 -3
- package/src/domains/evidence/build.ts +102 -15
- package/src/domains/evidence/detail.ts +69 -0
- package/src/domains/evidence/eval.ts +13 -1
- package/src/domains/evidence/finish-contract-map.ts +5 -1
- package/src/domains/evidence/inventory.ts +167 -0
- package/src/domains/evidence/store.ts +16 -0
- package/src/domains/evidence/types.ts +12 -0
- package/src/domains/extensions/resources.ts +7 -0
- package/src/domains/interop/registry.ts +6 -2
- package/src/domains/interop/types.ts +4 -0
- package/src/domains/lifecycle/migrations/index.ts +4 -0
- package/src/domains/memory/task-memory-policy.ts +70 -26
- package/src/domains/memory/task-memory-telemetry.ts +1 -0
- package/src/domains/middleware/index.ts +0 -1
- package/src/domains/middleware/marketplace-offer.ts +22 -35
- package/src/domains/middleware/memory-intervention.ts +127 -32
- package/src/domains/middleware/memory-step-endpoint.ts +3 -2
- package/src/domains/middleware/runtime.ts +7 -3
- package/src/domains/middleware/skills-reminder.ts +31 -2
- package/src/domains/mux/detect.ts +3 -6
- package/src/domains/observability/accountability.ts +15 -1
- package/src/domains/observability/compaction-usage.ts +118 -0
- package/src/domains/observability/contract.ts +52 -7
- package/src/domains/observability/cost.ts +1 -1
- package/src/domains/observability/evidence-index.ts +10 -0
- package/src/domains/observability/extension.ts +15 -6
- package/src/domains/observability/out-of-turn-usage.ts +52 -21
- package/src/domains/observability/projection.ts +394 -45
- package/src/{interactive → domains/observability}/worker-progress.ts +3 -3
- package/src/domains/prompts/fragments/operating/contract.md +2 -0
- package/src/domains/prompts/fragments/wiki/page.md +8 -0
- package/src/domains/providers/contract.ts +4 -1
- package/src/domains/providers/extension.ts +40 -9
- package/src/domains/providers/model-capabilities.ts +9 -0
- package/src/domains/providers/model-discovery.ts +3 -4
- package/src/domains/providers/model-runtime-capabilities.ts +15 -5
- package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +48 -26
- package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
- package/src/domains/providers/runtimes/claude/claude-code.ts +9 -0
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
- package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
- package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
- package/src/domains/providers/support.ts +11 -5
- package/src/domains/providers/target-model-cache.ts +25 -2
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/runtime-descriptor.ts +20 -1
- package/src/domains/providers/types/target-descriptor.ts +19 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/skills/install.ts +72 -7
- package/src/domains/resources/skills/loader.ts +7 -0
- package/src/domains/resources/skills/marketplace.ts +63 -11
- package/src/domains/safety/action-classifier.ts +7 -0
- package/src/domains/safety/autonomy.ts +15 -0
- package/src/domains/safety/default-path-policy.ts +2 -0
- package/src/domains/safety/finish-contract-registration.ts +29 -14
- package/src/domains/safety/finish-contract.ts +252 -40
- package/src/domains/safety/index.ts +21 -1
- package/src/domains/safety/path-policy.ts +1 -1
- package/src/domains/safety/policy-engine.ts +60 -17
- package/src/domains/safety/protected-artifacts.ts +191 -88
- package/src/domains/safety/rigor.ts +53 -39
- package/src/domains/safety/run-effects.ts +2 -22
- package/src/domains/safety/skill-authority.ts +55 -0
- package/src/domains/safety/validation-contract.ts +388 -0
- package/src/domains/session/archive-readers.ts +10 -1
- package/src/domains/session/compaction/compact.ts +72 -22
- package/src/domains/session/decision-board.ts +101 -2
- package/src/domains/session/entries.ts +50 -7
- package/src/domains/session/extension.ts +4 -4
- package/src/domains/session/handoff.ts +2 -1
- package/src/domains/session/manager.ts +2 -3
- package/src/domains/session/task-board.ts +14 -1
- package/src/domains/session/tree/fork.ts +1 -2
- package/src/domains/session/tree/navigator.ts +1 -1
- package/src/domains/session/usage.ts +3 -3
- package/src/domains/user-tasks/acceptance.ts +56 -0
- package/src/domains/user-tasks/active-acceptance.ts +40 -0
- package/src/domains/user-tasks/store.ts +34 -3
- package/src/engine/acp/adapter.ts +24 -6
- package/src/engine/acp/server.ts +21 -4
- package/src/engine/acp/transport.ts +53 -8
- package/src/engine/acp/types.ts +4 -0
- package/src/engine/agent.ts +13 -3
- package/src/engine/ai.ts +26 -8
- package/src/engine/antigravity/subprocess-runtime.ts +386 -120
- package/src/engine/api-registry.ts +3 -0
- package/src/engine/apis/ollama-native.ts +15 -0
- package/src/engine/apis/openai-completions.ts +117 -14
- package/src/engine/claude/subprocess-runtime.ts +107 -60
- package/src/engine/external-subprocess.ts +122 -6
- package/src/entry/background-model-metadata.ts +18 -0
- package/src/entry/compaction-prompt.ts +57 -0
- package/src/entry/orchestrator.ts +416 -218
- package/src/entry/task-memory-lifecycle.ts +35 -0
- package/src/interactive/chat-loop-messages.ts +13 -4
- package/src/interactive/chat-loop.ts +65 -2
- package/src/interactive/chat-renderer.ts +1 -0
- package/src/interactive/cost-overlay.ts +26 -2
- package/src/interactive/dispatch-board.ts +46 -717
- package/src/interactive/fleet-run-preview.ts +2 -1
- package/src/interactive/interactive-application.ts +3 -2
- package/src/interactive/interactive-presentation.ts +55 -12
- package/src/interactive/interactive-slash-runtime.ts +4 -2
- package/src/interactive/oracle.ts +5 -2
- package/src/interactive/overlays/fleet-run-approval.ts +3 -2
- package/src/interactive/overlays/message-picker.ts +2 -2
- package/src/interactive/overlays/settings.ts +2 -2
- package/src/interactive/overlays/tree-selector.ts +2 -2
- package/src/interactive/renderers/branch-summary.ts +1 -1
- package/src/interactive/renderers/worker-entry.ts +32 -0
- package/src/interactive/slash-autocomplete.ts +4 -6
- package/src/interactive/slash-commands.ts +49 -45
- package/src/interactive/slash-spec.ts +28 -0
- package/src/interactive/theme/labels.ts +19 -13
- package/src/interactive/turn-context.ts +9 -5
- package/src/interactive/turn-recovery.ts +8 -0
- package/src/interactive/turn-runtime.ts +27 -11
- package/src/interactive/turn-state.ts +7 -0
- package/src/interactive/view/artifacts.ts +2 -0
- package/src/interactive/worker-receipts.ts +1 -0
- package/src/interactive/worker-stream.ts +13 -4
- package/src/tools/bootstrap.ts +4 -0
- package/src/tools/builtin-tool-catalog.ts +31 -0
- package/src/tools/compete-worktrees.ts +7 -1
- package/src/tools/context/index.ts +30 -9
- package/src/tools/core-bootstrap.ts +16 -0
- package/src/tools/decide.ts +136 -0
- package/src/tools/dispatch-admission.ts +21 -0
- package/src/tools/dispatch-arguments.ts +1 -0
- package/src/tools/dispatch-event-text.ts +10 -0
- package/src/tools/dispatch-plan.ts +6 -2
- package/src/tools/dispatch-runner.ts +27 -1
- package/src/tools/dispatch-types.ts +6 -0
- package/src/tools/evidence.ts +96 -0
- package/src/tools/limitation.ts +76 -0
- package/src/tools/policy.ts +9 -0
- package/src/tools/presentation.ts +3 -0
- package/src/tools/registry.ts +11 -5
- package/src/tools/result-shaping.ts +17 -5
- package/src/tools/task-worktree.ts +13 -3
- package/src/tools/tasks.ts +10 -1
- package/src/tools/verify/authoring.ts +170 -83
- package/src/tools/verify/catalog.ts +122 -5
- package/src/tools/verify/index.ts +2 -1
- package/src/tools/verify/numeric.ts +298 -0
- package/src/tools/verify/perf.ts +143 -0
- package/src/tools/verify/scripts.ts +229 -2
- package/src/tools/worker-evidence.ts +3 -1
- package/src/worker/spec-contract.ts +4 -0
- package/dist/chunk-2Z2IKEXI.js +0 -1554
- package/dist/chunk-RVG5JXAL.js +0 -41
- package/dist/chunk-T56WDKA5.js +0 -183
- package/dist/chunk-VN3SHNBN.js +0 -313
- package/dist/chunk-VPKWYKEY.js +0 -169
- package/dist/reset-OAQP3W4O.js +0 -230
- package/dist/uninstall-N34PCTGJ.js +0 -331
- package/dist/upgrade-PXK3S2YM.js +0 -325
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import type { AskUserToolPolicy } from "../../tools/registry.js";
|
|
2
3
|
import type { AutonomyExposure } from "../safety/autonomy.js";
|
|
3
|
-
import type
|
|
4
|
+
import { type DecisionLedgerEntry, type DecisionRecord, decisionRef } from "./entries.js";
|
|
4
5
|
|
|
5
6
|
export interface DecisionLedgerEntryFields {
|
|
6
7
|
kind: "decisionLedger";
|
|
7
8
|
parentTurnId: string;
|
|
9
|
+
origin?: "interview" | "agent";
|
|
8
10
|
interviewId: string;
|
|
9
11
|
interviewStatus: "complete" | "cancelled";
|
|
10
12
|
startedAt: string;
|
|
@@ -28,11 +30,35 @@ export interface DecisionBoardStoreDeps {
|
|
|
28
30
|
now?: () => Date;
|
|
29
31
|
}
|
|
30
32
|
|
|
33
|
+
/** One design choice the model records itself through the `decide` tool. */
|
|
34
|
+
export interface AgentDecisionInput {
|
|
35
|
+
key: string;
|
|
36
|
+
value: string;
|
|
37
|
+
alternatives: ReadonlyArray<string>;
|
|
38
|
+
rationale: string;
|
|
39
|
+
label?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface AgentDecisionOutcome {
|
|
43
|
+
/** The appended agent decision set; `decisionRef(entry.interviewId, key)` cites it. */
|
|
44
|
+
entry: DecisionLedgerEntryFields;
|
|
45
|
+
/** The earlier active record with the same key that this decision superseded, when there was one. */
|
|
46
|
+
superseded: { interviewId: string; key: string } | null;
|
|
47
|
+
}
|
|
48
|
+
|
|
31
49
|
export interface DecisionBoardStore {
|
|
32
50
|
/** Latest snapshot per interview, newest interview first. */
|
|
33
51
|
snapshot(): ReadonlyArray<DecisionLedgerEntry>;
|
|
34
52
|
/** Persist the one host-finalized snapshot for a settled interview. */
|
|
35
53
|
recordFinalizedInterview(policy: AskUserToolPolicy): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Append one agent-recorded decision as its own complete set
|
|
56
|
+
* (`origin: "agent"`, `interviewId: "agent:<uuid>"`, `roundCount: 0`). An
|
|
57
|
+
* earlier active agent decision with the same key is superseded first with
|
|
58
|
+
* the new rationale as its correction. An active operator decision with the
|
|
59
|
+
* same key is never overwritten by the model; that throws.
|
|
60
|
+
*/
|
|
61
|
+
recordAgentDecision(input: AgentDecisionInput): AgentDecisionOutcome;
|
|
36
62
|
/** Append an operator revision snapshot anchored to the active branch leaf. */
|
|
37
63
|
supersede(interviewId: string, key: string, correction?: string): DecisionLedgerEntryFields;
|
|
38
64
|
/** Force the next read to refold, including after a same-session tree switch. */
|
|
@@ -90,6 +116,24 @@ function finalizedInterviewEntryFields(policy: AskUserToolPolicy): DecisionLedge
|
|
|
90
116
|
};
|
|
91
117
|
}
|
|
92
118
|
|
|
119
|
+
/** Most decision refs one dispatch request, envelope, or receipt carries. */
|
|
120
|
+
export const DECISION_REFS_CAP = 32;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Refs of every active decision on a board snapshot, sorted and capped at
|
|
124
|
+
* {@link DECISION_REFS_CAP}. Dispatch seals this onto each request it builds;
|
|
125
|
+
* an empty board yields an empty list, which callers leave off the request.
|
|
126
|
+
*/
|
|
127
|
+
export function activeDecisionRefs(board: ReadonlyArray<DecisionLedgerEntry>): string[] {
|
|
128
|
+
const refs = new Set<string>();
|
|
129
|
+
for (const entry of board) {
|
|
130
|
+
for (const decision of entry.decisions) {
|
|
131
|
+
if (decision.status === "active") refs.add(decisionRef(entry.interviewId, decision.key));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return [...refs].sort().slice(0, DECISION_REFS_CAP);
|
|
135
|
+
}
|
|
136
|
+
|
|
93
137
|
function isDecisionLedgerEntry(value: unknown): value is DecisionLedgerEntry {
|
|
94
138
|
return !!value && typeof value === "object" && (value as { kind?: unknown }).kind === "decisionLedger";
|
|
95
139
|
}
|
|
@@ -143,7 +187,7 @@ export function createDecisionBoardStore(deps: DecisionBoardStoreDeps = {}): Dec
|
|
|
143
187
|
dirty = true;
|
|
144
188
|
};
|
|
145
189
|
|
|
146
|
-
|
|
190
|
+
const store: DecisionBoardStore = {
|
|
147
191
|
snapshot(): ReadonlyArray<DecisionLedgerEntry> {
|
|
148
192
|
syncToSession();
|
|
149
193
|
return interviews;
|
|
@@ -154,6 +198,51 @@ export function createDecisionBoardStore(deps: DecisionBoardStoreDeps = {}): Dec
|
|
|
154
198
|
append(entry);
|
|
155
199
|
return true;
|
|
156
200
|
},
|
|
201
|
+
recordAgentDecision(input: AgentDecisionInput): AgentDecisionOutcome {
|
|
202
|
+
syncToSession();
|
|
203
|
+
let superseded: AgentDecisionOutcome["superseded"] = null;
|
|
204
|
+
for (const interview of interviews) {
|
|
205
|
+
const prior = interview.decisions.find((decision) => decision.key === input.key && decision.status === "active");
|
|
206
|
+
if (prior === undefined) continue;
|
|
207
|
+
if (interview.origin !== "agent" || prior.source !== "agent") {
|
|
208
|
+
throw new Error(
|
|
209
|
+
`decision board: '${input.key}' is an operator decision (${interview.interviewId}); it can only be revised through ask_user`,
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
superseded = { interviewId: interview.interviewId, key: prior.key };
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
if (superseded !== null) store.supersede(superseded.interviewId, superseded.key, input.rationale);
|
|
216
|
+
const now = (deps.now?.() ?? new Date()).toISOString();
|
|
217
|
+
const entries = deps.readEntries?.() ?? [];
|
|
218
|
+
const parentTurnId = deps.getActiveLeafTurnId?.() ?? activeLeafFromEntries(entries);
|
|
219
|
+
if (!parentTurnId) throw new Error("decision board: no active branch leaf is available for the decision");
|
|
220
|
+
const entry: DecisionLedgerEntryFields = {
|
|
221
|
+
kind: "decisionLedger",
|
|
222
|
+
parentTurnId,
|
|
223
|
+
origin: "agent",
|
|
224
|
+
interviewId: `agent:${randomUUID()}`,
|
|
225
|
+
interviewStatus: "complete",
|
|
226
|
+
startedAt: now,
|
|
227
|
+
endedAt: now,
|
|
228
|
+
roundCount: 0,
|
|
229
|
+
exposure: "local",
|
|
230
|
+
decisions: [
|
|
231
|
+
{
|
|
232
|
+
key: input.key,
|
|
233
|
+
value: input.value,
|
|
234
|
+
...(input.label ? { label: input.label } : {}),
|
|
235
|
+
status: "active",
|
|
236
|
+
decidedAt: now,
|
|
237
|
+
source: "agent",
|
|
238
|
+
alternatives: [...input.alternatives],
|
|
239
|
+
rationale: input.rationale,
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
};
|
|
243
|
+
append(entry);
|
|
244
|
+
return { entry, superseded };
|
|
245
|
+
},
|
|
157
246
|
supersede(interviewId: string, key: string, correction?: string): DecisionLedgerEntryFields {
|
|
158
247
|
syncToSession();
|
|
159
248
|
const interview = interviews.find((candidate) => candidate.interviewId === interviewId);
|
|
@@ -191,4 +280,14 @@ export function createDecisionBoardStore(deps: DecisionBoardStoreDeps = {}): Dec
|
|
|
191
280
|
dirty = true;
|
|
192
281
|
},
|
|
193
282
|
};
|
|
283
|
+
return store;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** Preserve the recorded argument wherever a decision is carried into another prompt. */
|
|
287
|
+
export function decisionRationale(decision: DecisionRecord): string | undefined {
|
|
288
|
+
const parts: string[] = [];
|
|
289
|
+
if (decision.alternatives?.length) parts.push(`Alternatives: ${decision.alternatives.join("; ")}`);
|
|
290
|
+
if (decision.rationale) parts.push(`Rationale: ${decision.rationale}`);
|
|
291
|
+
if (parts.length > 0) return parts.join(". ");
|
|
292
|
+
return decision.source_question ?? decision.correction;
|
|
194
293
|
}
|
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
* carries its `kind` discriminant, a `turnId` (uuid v7 where possible so
|
|
6
6
|
* entries sort by creation), a parent pointer, and an ISO timestamp.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* - compactionSummary is produced by compaction/compact.ts
|
|
10
|
-
* - branchSummary is produced by the fork path
|
|
11
|
-
* - bashExecution
|
|
8
|
+
* Non-message kinds and where they come from:
|
|
9
|
+
* - compactionSummary is produced by compaction/compact.ts.
|
|
10
|
+
* - branchSummary is produced by the fork path.
|
|
11
|
+
* - bashExecution is produced by the editor bash path
|
|
12
|
+
* (interactive/editor-bash.ts).
|
|
13
|
+
* - fileEntry is consumed by the renderer, compaction, handoff, and
|
|
14
|
+
* evidence builders but has no in-tree producer.
|
|
12
15
|
*/
|
|
13
16
|
|
|
14
17
|
import { isSkillActivation, type SkillActivation } from "../../core/skill-activation.js";
|
|
@@ -101,6 +104,10 @@ export type CompactionTrigger = "auto" | "force" | "overflow";
|
|
|
101
104
|
* `usage` carries and the ledger usage fold reads both from one place.
|
|
102
105
|
*/
|
|
103
106
|
export interface CompactionUsage {
|
|
107
|
+
/** Executing route; absent on legacy checkpoints that used the active chat model. */
|
|
108
|
+
targetId?: string;
|
|
109
|
+
/** Requested wire model ID, not a verified physical backend identity. */
|
|
110
|
+
modelId?: string;
|
|
104
111
|
input: number;
|
|
105
112
|
output: number;
|
|
106
113
|
cacheRead: number;
|
|
@@ -209,6 +216,14 @@ export interface TaskLedgerEntry extends BaseSessionEntry {
|
|
|
209
216
|
|
|
210
217
|
export type DecisionStatus = "active" | "superseded";
|
|
211
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Who settled a decision. `operator` is an answer the operator gave in an
|
|
221
|
+
* `ask_user` interview. `agent` is a design choice the model recorded itself
|
|
222
|
+
* through the `decide` tool, with the alternatives it rejected and why. Absent
|
|
223
|
+
* on entries written before agent decisions existed, which were all operator.
|
|
224
|
+
*/
|
|
225
|
+
export type DecisionSource = "operator" | "agent";
|
|
226
|
+
|
|
212
227
|
export interface DecisionRecord {
|
|
213
228
|
key: string;
|
|
214
229
|
value: string;
|
|
@@ -218,11 +233,33 @@ export interface DecisionRecord {
|
|
|
218
233
|
decidedAt: string;
|
|
219
234
|
revisedAt?: string;
|
|
220
235
|
correction?: string;
|
|
236
|
+
source?: DecisionSource;
|
|
237
|
+
/** Options considered and not taken. Only agent decisions carry these. */
|
|
238
|
+
alternatives?: string[];
|
|
239
|
+
/** Why `value` won over `alternatives`. Only agent decisions carry this. */
|
|
240
|
+
rationale?: string;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Stable reference to one decision: `<interviewId>/<key>`. Both halves are
|
|
245
|
+
* already unique on the active path, so the pair needs no third id. Run
|
|
246
|
+
* envelopes, receipts, and commit trailers cite decisions by this string.
|
|
247
|
+
*/
|
|
248
|
+
export type DecisionRef = string;
|
|
249
|
+
|
|
250
|
+
export function decisionRef(interviewId: string, key: string): DecisionRef {
|
|
251
|
+
return `${interviewId}/${key}`;
|
|
221
252
|
}
|
|
222
253
|
|
|
223
|
-
/**
|
|
254
|
+
/**
|
|
255
|
+
* One complete, branch-anchored snapshot of a settled decision set. An
|
|
256
|
+
* `interview` origin is an operator `ask_user` round; an `agent` origin is a
|
|
257
|
+
* set the model recorded with the `decide` tool, where `interviewId` is the
|
|
258
|
+
* agent decision set id and `roundCount` is 0. Absent origin means interview.
|
|
259
|
+
*/
|
|
224
260
|
export interface DecisionLedgerEntry extends BaseSessionEntry {
|
|
225
261
|
kind: "decisionLedger";
|
|
262
|
+
origin?: "interview" | "agent";
|
|
226
263
|
interviewId: string;
|
|
227
264
|
interviewStatus: "complete" | "cancelled";
|
|
228
265
|
startedAt: string;
|
|
@@ -499,11 +536,14 @@ function isTaskLedgerEvidence(value: unknown): value is TaskLedgerValidationEvid
|
|
|
499
536
|
);
|
|
500
537
|
}
|
|
501
538
|
|
|
502
|
-
function isDecisionRecord(value: unknown): value is DecisionRecord {
|
|
539
|
+
export function isDecisionRecord(value: unknown): value is DecisionRecord {
|
|
503
540
|
if (!isRecord(value)) return false;
|
|
504
|
-
if (!isString(value.key) || !/^[a-z0-9]+(?:_[a-z0-9]+)*$/.test(value.key)) return false;
|
|
541
|
+
if (!isString(value.key) || !/^[a-z0-9]+(?:[_-][a-z0-9]+)*$/.test(value.key)) return false;
|
|
505
542
|
if (!isString(value.value) || !isOneOf(value.status, DECISION_STATUSES) || !isString(value.decidedAt)) return false;
|
|
506
543
|
if (!isOptionalString(value.label) || !isOptionalString(value.source_question)) return false;
|
|
544
|
+
if (value.source !== undefined && !isOneOf(value.source, ["operator", "agent"])) return false;
|
|
545
|
+
if (value.alternatives !== undefined && !isStringArray(value.alternatives)) return false;
|
|
546
|
+
if (!isOptionalString(value.rationale)) return false;
|
|
507
547
|
if (!isOptionalString(value.revisedAt) || !isOptionalString(value.correction)) return false;
|
|
508
548
|
return value.status === "superseded"
|
|
509
549
|
? isString(value.revisedAt)
|
|
@@ -515,6 +555,8 @@ function isOptionalCompactionUsage(value: unknown): boolean {
|
|
|
515
555
|
if (!isRecord(value)) return false;
|
|
516
556
|
const cost = value.cost;
|
|
517
557
|
return (
|
|
558
|
+
isOptionalString(value.targetId) &&
|
|
559
|
+
isOptionalString(value.modelId) &&
|
|
518
560
|
isNumber(value.input) &&
|
|
519
561
|
isNumber(value.output) &&
|
|
520
562
|
isNumber(value.cacheRead) &&
|
|
@@ -636,6 +678,7 @@ export function isSessionEntry(value: unknown): value is SessionEntry {
|
|
|
636
678
|
);
|
|
637
679
|
case "decisionLedger":
|
|
638
680
|
return (
|
|
681
|
+
(v.origin === undefined || isOneOf(v.origin, ["interview", "agent"])) &&
|
|
639
682
|
isString(v.interviewId) &&
|
|
640
683
|
isOneOf(v.interviewStatus, DECISION_INTERVIEW_STATUSES) &&
|
|
641
684
|
isString(v.startedAt) &&
|
|
@@ -282,10 +282,10 @@ export function createSessionBundle(context: DomainContext): DomainBundle<Sessio
|
|
|
282
282
|
return snapshotFor(id);
|
|
283
283
|
},
|
|
284
284
|
switchBranch(sessionId) {
|
|
285
|
-
// /tree-driven branch switch
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
//
|
|
285
|
+
// /tree-driven branch switch delegates to resume. Kept as a distinct
|
|
286
|
+
// contract method so telemetry or chat-loop rewiring can be layered on
|
|
287
|
+
// without changing resume's semantics. Same open-before-close ordering
|
|
288
|
+
// as resume() above and for the same reason.
|
|
289
289
|
if (state?.meta.id === sessionId) return state.meta;
|
|
290
290
|
const resumed = resumeSessionState(sessionId);
|
|
291
291
|
if (state) {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { isAbsolute, normalize, relative, resolve } from "node:path";
|
|
25
|
+
import { decisionRationale } from "./decision-board.js";
|
|
25
26
|
import type { DecisionLedgerEntry, SessionEntry } from "./entries.js";
|
|
26
27
|
import { filterEntriesToActivePath } from "./tree/active-path.js";
|
|
27
28
|
|
|
@@ -480,7 +481,7 @@ export function mergeHandoffDecisions(
|
|
|
480
481
|
if (decision.status !== "active") continue;
|
|
481
482
|
const name = decision.label ?? decision.key;
|
|
482
483
|
const summary = boundHandoffString(`${name}: ${decision.value}`).text;
|
|
483
|
-
const rationale = decision
|
|
484
|
+
const rationale = decisionRationale(decision);
|
|
484
485
|
settled.push({
|
|
485
486
|
summary,
|
|
486
487
|
...(rationale ? { rationale: boundHandoffString(rationale).text } : {}),
|
|
@@ -111,9 +111,8 @@ export function appendTurn(state: SessionManagerState, input: TurnInput): ClioTu
|
|
|
111
111
|
|
|
112
112
|
/**
|
|
113
113
|
* Append a rich SessionEntry via the engine writer. Non-message kinds are
|
|
114
|
-
* written as JSON lines to current.jsonl
|
|
115
|
-
*
|
|
116
|
-
* branch points too.
|
|
114
|
+
* written as JSON lines to current.jsonl and do not project into tree.json;
|
|
115
|
+
* the /fork picker offers assistant message turns only.
|
|
117
116
|
*/
|
|
118
117
|
export function appendEntry(state: SessionManagerState, input: SessionEntryInput): SessionEntry {
|
|
119
118
|
const turnId = input.turnId ?? newTurnId();
|
|
@@ -29,6 +29,7 @@ export interface TaskBoardTask {
|
|
|
29
29
|
status: TaskLedgerStatus;
|
|
30
30
|
origin?: "agent" | "user";
|
|
31
31
|
userTaskId?: string;
|
|
32
|
+
requiredValidationEvidence?: TaskLedgerValidationEvidence[];
|
|
32
33
|
/** Block or drop reason; empty for pending/active/completed tasks. */
|
|
33
34
|
reason?: string;
|
|
34
35
|
/** Evidence note recorded when the task was completed. */
|
|
@@ -64,7 +65,7 @@ export interface TaskBoardCounts {
|
|
|
64
65
|
export type TaskBoardMutation =
|
|
65
66
|
| { op: "plan"; title: string; tasks: ReadonlyArray<string> }
|
|
66
67
|
| { op: "add"; tasks: ReadonlyArray<string> }
|
|
67
|
-
| { op: "pick"; title: string; userTaskId: string }
|
|
68
|
+
| { op: "pick"; title: string; userTaskId: string; verification?: ReadonlyArray<{ check: string; timeoutMs: number }> }
|
|
68
69
|
| { op: "start"; id: string }
|
|
69
70
|
| { op: "done"; id: string; evidence: string }
|
|
70
71
|
| { op: "block"; id: string; reason: string }
|
|
@@ -179,6 +180,7 @@ function boardStatus(tasks: ReadonlyArray<TaskBoardTask>): TaskLedgerStatus {
|
|
|
179
180
|
export function toTaskLedgerEntryFields(board: TaskBoardSnapshot, now: Date): TaskLedgerEntryFields {
|
|
180
181
|
const evidence: TaskLedgerValidationEvidence[] = [];
|
|
181
182
|
const subgoals: TaskLedgerGoal[] = board.tasks.map((task) => {
|
|
183
|
+
evidence.push(...(task.requiredValidationEvidence ?? []).map((item) => ({ ...item })));
|
|
182
184
|
if (task.status === "completed" && task.evidence) {
|
|
183
185
|
evidence.push({
|
|
184
186
|
id: `${task.id}.evidence`,
|
|
@@ -308,6 +310,8 @@ function toEntryView(entry: {
|
|
|
308
310
|
origin: goal.origin ?? "agent",
|
|
309
311
|
};
|
|
310
312
|
if (goal.userTaskId) task.userTaskId = goal.userTaskId;
|
|
313
|
+
const required = entry.requiredValidationEvidence.filter((item) => item.id.startsWith(`${goal.id}.acceptance.`));
|
|
314
|
+
if (required.length > 0) task.requiredValidationEvidence = required.map((item) => ({ ...item }));
|
|
311
315
|
if (goal.description) task.reason = goal.description;
|
|
312
316
|
const evidence = evidenceByTask.get(goal.id);
|
|
313
317
|
if (evidence) task.evidence = evidence;
|
|
@@ -390,6 +394,15 @@ function applyMutation(
|
|
|
390
394
|
origin: "user",
|
|
391
395
|
userTaskId: mutation.userTaskId,
|
|
392
396
|
};
|
|
397
|
+
if (mutation.verification && mutation.verification.length > 0) {
|
|
398
|
+
picked.requiredValidationEvidence = mutation.verification.map((item, index) => ({
|
|
399
|
+
id: `${picked.id}.acceptance.${index}`,
|
|
400
|
+
description: `Operator acceptance: ${item.check}`,
|
|
401
|
+
command: item.check,
|
|
402
|
+
status: "pending",
|
|
403
|
+
notes: `timeoutMs=${item.timeoutMs}`,
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
393
406
|
return {
|
|
394
407
|
board: {
|
|
395
408
|
boardId: board?.boardId ?? "",
|
|
@@ -14,8 +14,7 @@ import { entryBelongsToPath } from "./active-path.js";
|
|
|
14
14
|
* install it as current.
|
|
15
15
|
*
|
|
16
16
|
* Used by SessionContract.fork (current session) and the /fork message
|
|
17
|
-
* picker
|
|
18
|
-
* bundle wiring stays thin.
|
|
17
|
+
* picker overlay. Kept out of extension.ts so the bundle wiring stays thin.
|
|
19
18
|
*/
|
|
20
19
|
export interface ForkInput {
|
|
21
20
|
/** The state we are forking from. Must carry a live writer. */
|
|
@@ -6,7 +6,7 @@ import type { ResolvedLabel } from "./manager.js";
|
|
|
6
6
|
* Purely functional tree-walk helpers. Given the raw SessionTreeNode[] that
|
|
7
7
|
* the engine persists plus a label map and a leaf pointer, produce a
|
|
8
8
|
* render-friendly snapshot. No I/O. Used by SessionContract.tree() to
|
|
9
|
-
* deliver a serializable structure to
|
|
9
|
+
* deliver a serializable structure to the /tree overlay renderer.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -101,9 +101,9 @@ export function ledgerUsageCalls(
|
|
|
101
101
|
const usage = entry.usage;
|
|
102
102
|
if (!usage || usage.totalTokens <= 0) continue;
|
|
103
103
|
calls.push({
|
|
104
|
-
providerId: currentTarget ?? "unknown",
|
|
105
|
-
attributedModelId: currentModel ?? "unknown",
|
|
106
|
-
requestedModelId: currentModel ?? "unknown",
|
|
104
|
+
providerId: usage.targetId ?? currentTarget ?? "unknown",
|
|
105
|
+
attributedModelId: usage.modelId ?? currentModel ?? "unknown",
|
|
106
|
+
requestedModelId: usage.modelId ?? currentModel ?? "unknown",
|
|
107
107
|
responseModelIdObservation: { state: "not-observed" },
|
|
108
108
|
input: usage.input,
|
|
109
109
|
output: usage.output,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DISPATCH_INTENT_TIMEOUT_MIN_MS,
|
|
3
|
+
type DispatchIntentCheckBound,
|
|
4
|
+
type DispatchIntentVerification,
|
|
5
|
+
normalizeIntentExpectedOutputs,
|
|
6
|
+
normalizeIntentVerification,
|
|
7
|
+
} from "../dispatch/intent.js";
|
|
8
|
+
|
|
9
|
+
export interface UserTaskAcceptance {
|
|
10
|
+
expectedOutputs: string[];
|
|
11
|
+
verification: DispatchIntentVerification[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Validate stored acceptance without consulting a catalog that may have changed. */
|
|
15
|
+
export function normalizeUserTaskAcceptance(raw: unknown): UserTaskAcceptance {
|
|
16
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
17
|
+
throw new Error("acceptance must be an object");
|
|
18
|
+
}
|
|
19
|
+
const value = raw as Record<string, unknown>;
|
|
20
|
+
if (Object.keys(value).some((key) => key !== "expectedOutputs" && key !== "verification")) {
|
|
21
|
+
throw new Error("acceptance contains an unknown field");
|
|
22
|
+
}
|
|
23
|
+
if (!Array.isArray(value.expectedOutputs) || !Array.isArray(value.verification)) {
|
|
24
|
+
throw new Error("acceptance requires expectedOutputs and verification arrays");
|
|
25
|
+
}
|
|
26
|
+
const checks = new Map<string, DispatchIntentCheckBound>();
|
|
27
|
+
const rawVerification = value.verification.map((entry: unknown) => {
|
|
28
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) {
|
|
29
|
+
throw new Error("acceptance verification must contain check and timeoutMs");
|
|
30
|
+
}
|
|
31
|
+
const item = entry as Record<string, unknown>;
|
|
32
|
+
if (Object.keys(item).some((key) => key !== "check" && key !== "timeoutMs")) {
|
|
33
|
+
throw new Error("acceptance verification contains an unknown field");
|
|
34
|
+
}
|
|
35
|
+
if (
|
|
36
|
+
typeof item.check !== "string" ||
|
|
37
|
+
typeof item.timeoutMs !== "number" ||
|
|
38
|
+
!Number.isSafeInteger(item.timeoutMs) ||
|
|
39
|
+
item.timeoutMs <= 0
|
|
40
|
+
) {
|
|
41
|
+
throw new Error("acceptance verification requires a check and a positive integer timeoutMs");
|
|
42
|
+
}
|
|
43
|
+
checks.set(item.check.trim(), {
|
|
44
|
+
id: item.check.trim(),
|
|
45
|
+
timeoutMs: Math.max(DISPATCH_INTENT_TIMEOUT_MIN_MS, item.timeoutMs, checks.get(item.check.trim())?.timeoutMs ?? 0),
|
|
46
|
+
});
|
|
47
|
+
return { check: item.check, timeout_ms: item.timeoutMs };
|
|
48
|
+
});
|
|
49
|
+
const expectedOutputs = normalizeIntentExpectedOutputs(value.expectedOutputs);
|
|
50
|
+
if (!Array.isArray(expectedOutputs))
|
|
51
|
+
throw new Error(expectedOutputs.ok ? "invalid acceptance outputs" : expectedOutputs.message);
|
|
52
|
+
const verification = normalizeIntentVerification(rawVerification, checks);
|
|
53
|
+
if (!Array.isArray(verification))
|
|
54
|
+
throw new Error(verification.ok ? "invalid acceptance verification" : verification.message);
|
|
55
|
+
return { expectedOutputs, verification };
|
|
56
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { isSessionEntry } from "../session/entries.js";
|
|
2
|
+
import type { TaskBoardSnapshot } from "../session/task-board.js";
|
|
3
|
+
import type { UserTaskAcceptance } from "./acceptance.js";
|
|
4
|
+
import type { UserTask } from "./store.js";
|
|
5
|
+
|
|
6
|
+
/** Keep a task's acceptance through the turn that finishes or blocks its board row. */
|
|
7
|
+
export function activeUserTaskAcceptance(
|
|
8
|
+
tasks: ReadonlyArray<UserTask>,
|
|
9
|
+
board: TaskBoardSnapshot | null,
|
|
10
|
+
sessionId: string | null,
|
|
11
|
+
window: ReadonlyArray<unknown>,
|
|
12
|
+
): UserTaskAcceptance | undefined {
|
|
13
|
+
if (!board || !sessionId) return undefined;
|
|
14
|
+
const touched = new Set<string>();
|
|
15
|
+
for (const entry of window) {
|
|
16
|
+
if (!isSessionEntry(entry) || entry.kind !== "message" || entry.role !== "tool_call") continue;
|
|
17
|
+
if (!entry.payload || typeof entry.payload !== "object") continue;
|
|
18
|
+
const payload = entry.payload as { name?: string; toolName?: string; args?: { action?: string; id?: string } };
|
|
19
|
+
if (
|
|
20
|
+
(payload.name ?? payload.toolName) === "tasks" &&
|
|
21
|
+
payload.args?.id &&
|
|
22
|
+
["done", "block", "drop"].includes(payload.args.action ?? "")
|
|
23
|
+
)
|
|
24
|
+
touched.add(payload.args.id);
|
|
25
|
+
}
|
|
26
|
+
const linked = new Set(
|
|
27
|
+
board.tasks
|
|
28
|
+
.filter((task) => task.status === "pending" || task.status === "active" || touched.has(task.id))
|
|
29
|
+
.map((task) => task.userTaskId),
|
|
30
|
+
);
|
|
31
|
+
const acceptance = tasks
|
|
32
|
+
.filter((task) => task.handedSessionId === sessionId && linked.has(task.id))
|
|
33
|
+
.flatMap((task) => (task.acceptance ? [task.acceptance] : []));
|
|
34
|
+
return acceptance.length > 0
|
|
35
|
+
? {
|
|
36
|
+
expectedOutputs: [...new Set(acceptance.flatMap((item) => item.expectedOutputs))],
|
|
37
|
+
verification: acceptance.flatMap((item) => item.verification),
|
|
38
|
+
}
|
|
39
|
+
: undefined;
|
|
40
|
+
}
|
|
@@ -2,6 +2,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { CLIO_PROJECT_DIR } from "../../core/artifact-paths.js";
|
|
4
4
|
import { atomicWrite } from "../../engine/session.js";
|
|
5
|
+
import { normalizeUserTaskAcceptance, type UserTaskAcceptance } from "./acceptance.js";
|
|
5
6
|
|
|
6
7
|
export const USER_TASKS_FILE_VERSION = 1 as const;
|
|
7
8
|
export const USER_TASKS_RELATIVE_PATH = `${CLIO_PROJECT_DIR}/user-tasks.json`;
|
|
@@ -12,6 +13,7 @@ export interface UserTask {
|
|
|
12
13
|
id: string;
|
|
13
14
|
title: string;
|
|
14
15
|
note?: string;
|
|
16
|
+
acceptance?: UserTaskAcceptance;
|
|
15
17
|
status: UserTaskStatus;
|
|
16
18
|
createdAt: string;
|
|
17
19
|
updatedAt: string;
|
|
@@ -37,7 +39,8 @@ export interface UserTasksStore {
|
|
|
37
39
|
readonly path: string;
|
|
38
40
|
snapshot(): ReadonlyArray<UserTask>;
|
|
39
41
|
get(id: string): UserTask | null;
|
|
40
|
-
add(title: string, note?: string): UserTask;
|
|
42
|
+
add(title: string, note?: string, acceptance?: UserTaskAcceptance): UserTask;
|
|
43
|
+
setAcceptance(id: string, acceptance: UserTaskAcceptance): UserTask;
|
|
41
44
|
hand(id: string, sessionId?: string): UserTask;
|
|
42
45
|
done(id: string): UserTask;
|
|
43
46
|
drop(id: string): UserTask;
|
|
@@ -65,6 +68,7 @@ const TASK_KEYS = new Set([
|
|
|
65
68
|
"id",
|
|
66
69
|
"title",
|
|
67
70
|
"note",
|
|
71
|
+
"acceptance",
|
|
68
72
|
"status",
|
|
69
73
|
"createdAt",
|
|
70
74
|
"updatedAt",
|
|
@@ -86,6 +90,13 @@ function isOptionalString(value: unknown): boolean {
|
|
|
86
90
|
|
|
87
91
|
function isUserTask(value: unknown): value is UserTask {
|
|
88
92
|
if (!isRecord(value) || !hasOnlyKeys(value, TASK_KEYS)) return false;
|
|
93
|
+
if (value.acceptance !== undefined) {
|
|
94
|
+
try {
|
|
95
|
+
normalizeUserTaskAcceptance(value.acceptance);
|
|
96
|
+
} catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
89
100
|
return (
|
|
90
101
|
typeof value.id === "string" &&
|
|
91
102
|
/^u[1-9]\d*$/.test(value.id) &&
|
|
@@ -138,7 +149,7 @@ function parseFile(body: string, path: string): UserTasksFile {
|
|
|
138
149
|
}
|
|
139
150
|
|
|
140
151
|
function copyTask(task: UserTask): UserTask {
|
|
141
|
-
return { ...task };
|
|
152
|
+
return { ...task, ...(task.acceptance ? { acceptance: normalizeUserTaskAcceptance(task.acceptance) } : {}) };
|
|
142
153
|
}
|
|
143
154
|
|
|
144
155
|
function initialFile(): UserTasksFile {
|
|
@@ -219,7 +230,8 @@ export function createUserTasksStore(deps: UserTasksStoreDeps): UserTasksStore {
|
|
|
219
230
|
const task = load().tasks.find((candidate) => candidate.id === id);
|
|
220
231
|
return task ? copyTask(task) : null;
|
|
221
232
|
},
|
|
222
|
-
add(title: string, note?: string): UserTask {
|
|
233
|
+
add(title: string, note?: string, acceptance?: UserTaskAcceptance): UserTask {
|
|
234
|
+
const normalizedAcceptance = acceptance === undefined ? undefined : normalizeAcceptance(acceptance);
|
|
223
235
|
const normalizedTitle = title.trim();
|
|
224
236
|
if (normalizedTitle.length === 0) throw new UserTasksStoreError("operator task title cannot be empty");
|
|
225
237
|
const normalizedNote = note?.trim();
|
|
@@ -229,6 +241,7 @@ export function createUserTasksStore(deps: UserTasksStoreDeps): UserTasksStore {
|
|
|
229
241
|
id: `u${file.nextId}`,
|
|
230
242
|
title: normalizedTitle,
|
|
231
243
|
...(normalizedNote ? { note: normalizedNote } : {}),
|
|
244
|
+
...(normalizedAcceptance ? { acceptance: normalizedAcceptance } : {}),
|
|
232
245
|
status: "open",
|
|
233
246
|
createdAt: timestamp,
|
|
234
247
|
updatedAt: timestamp,
|
|
@@ -238,6 +251,16 @@ export function createUserTasksStore(deps: UserTasksStoreDeps): UserTasksStore {
|
|
|
238
251
|
save(file);
|
|
239
252
|
return copyTask(task);
|
|
240
253
|
},
|
|
254
|
+
setAcceptance(id: string, acceptance: UserTaskAcceptance): UserTask {
|
|
255
|
+
const normalized = normalizeAcceptance(acceptance);
|
|
256
|
+
const file = load();
|
|
257
|
+
const task = file.tasks.find((item) => item.id === id);
|
|
258
|
+
if (!task) throw new UserTasksStoreError(`operator task ${id} was not found`);
|
|
259
|
+
task.acceptance = normalized;
|
|
260
|
+
task.updatedAt = now();
|
|
261
|
+
save(file);
|
|
262
|
+
return copyTask(task);
|
|
263
|
+
},
|
|
241
264
|
hand(id: string, sessionId?: string): UserTask {
|
|
242
265
|
return mutate(id, ["open"], "handed", sessionId);
|
|
243
266
|
},
|
|
@@ -295,3 +318,11 @@ export function createUserTasksStore(deps: UserTasksStoreDeps): UserTasksStore {
|
|
|
295
318
|
},
|
|
296
319
|
};
|
|
297
320
|
}
|
|
321
|
+
|
|
322
|
+
function normalizeAcceptance(raw: unknown): UserTaskAcceptance {
|
|
323
|
+
try {
|
|
324
|
+
return normalizeUserTaskAcceptance(raw);
|
|
325
|
+
} catch (error) {
|
|
326
|
+
throw new UserTasksStoreError(error instanceof Error ? error.message : String(error), { cause: error });
|
|
327
|
+
}
|
|
328
|
+
}
|
|
@@ -134,13 +134,15 @@ function flattenPrompt(input: AcpDelegationRunInput): string {
|
|
|
134
134
|
return parts.join("\n\n");
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
function emptyUsage(): AcpDelegationUsage {
|
|
137
|
+
export function emptyUsage(): AcpDelegationUsage {
|
|
138
138
|
return {
|
|
139
139
|
inputTokens: 0,
|
|
140
140
|
outputTokens: 0,
|
|
141
141
|
cacheReadTokens: 0,
|
|
142
142
|
cacheWriteTokens: 0,
|
|
143
143
|
reasoningTokens: 0,
|
|
144
|
+
totalTokens: 0,
|
|
145
|
+
costUsd: 0,
|
|
144
146
|
};
|
|
145
147
|
}
|
|
146
148
|
|
|
@@ -148,13 +150,29 @@ function finite(value: unknown): number {
|
|
|
148
150
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
149
151
|
}
|
|
150
152
|
|
|
151
|
-
|
|
153
|
+
/** Same field the ACP server side and `sumRunUsage` read for a dollar figure; cost is never re-derived here. */
|
|
154
|
+
function costTotal(raw: Record<string, unknown>): number {
|
|
155
|
+
const cost = raw.cost;
|
|
156
|
+
return isRecord(cost) ? finite(cost.total) : 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function mergeUsage(into: AcpDelegationUsage, raw: unknown): void {
|
|
152
160
|
if (!isRecord(raw)) return;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
161
|
+
const input = finite(raw.input) + finite(raw.inputTokens) + finite(raw.input_tokens);
|
|
162
|
+
const output = finite(raw.output) + finite(raw.outputTokens) + finite(raw.output_tokens);
|
|
163
|
+
const cacheRead = finite(raw.cacheRead) + finite(raw.cacheReadTokens) + finite(raw.cache_read_tokens);
|
|
164
|
+
const cacheWrite = finite(raw.cacheWrite) + finite(raw.cacheWriteTokens) + finite(raw.cache_write_tokens);
|
|
165
|
+
into.inputTokens += input;
|
|
166
|
+
into.outputTokens += output;
|
|
167
|
+
into.cacheReadTokens += cacheRead;
|
|
168
|
+
into.cacheWriteTokens += cacheWrite;
|
|
157
169
|
into.reasoningTokens += finite(raw.reasoning) + finite(raw.reasoningTokens) + finite(raw.reasoning_tokens);
|
|
170
|
+
// Same rule as the ACP server accumulator: prefer the peer's explicit total,
|
|
171
|
+
// otherwise sum the four billed categories (reasoning excluded, since a peer
|
|
172
|
+
// that reports it separately still counts it inside output).
|
|
173
|
+
const explicitTotal = finite(raw.totalTokens) + finite(raw.total_tokens);
|
|
174
|
+
into.totalTokens += explicitTotal > 0 ? explicitTotal : input + output + cacheRead + cacheWrite;
|
|
175
|
+
into.costUsd += costTotal(raw);
|
|
158
176
|
}
|
|
159
177
|
|
|
160
178
|
function errorMessage(value: unknown): string {
|