@iowarp/clio-coder 0.3.8 → 0.4.0
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 +102 -0
- package/NOTICE +33 -0
- package/README.md +12 -3
- package/dist/{acp-U67UHUK2.js → acp-G5WJBNCT.js} +13 -12
- package/dist/{agents-YU6SGALZ.js → agents-FMV2Q5G4.js} +41 -36
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5ZPJOIVG.js → auth-3IDSJEIK.js} +18 -18
- package/dist/{builtins-C6JMZVV6.js → builtins-XCZWXSC7.js} +5 -5
- package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/{chunk-XWSF374K.js → chunk-2OQE55CK.js} +3 -3
- package/dist/{chunk-5H3GB5BO.js → chunk-32KWKNSF.js} +8 -384
- package/dist/{chunk-KTYTFRMB.js → chunk-36EJLSQQ.js} +34 -36
- package/dist/{chunk-FHJEP5SW.js → chunk-3BT2XMV4.js} +19 -13
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-GU2UIAFZ.js → chunk-3URVFKWK.js} +7 -7
- package/dist/{chunk-WEH5XRJQ.js → chunk-3XML7CDN.js} +3 -3
- package/dist/chunk-42FMPA75.js +101 -0
- package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
- package/dist/{chunk-VCBR6CU7.js → chunk-5PSMVOLM.js} +2 -2
- package/dist/{chunk-NMPKI6XL.js → chunk-6DB53AJS.js} +203 -25
- package/dist/{chunk-3BINW3FP.js → chunk-76ONBSIA.js} +2 -2
- package/dist/{chunk-26LEYJZH.js → chunk-7MCTRUCE.js} +2 -2
- package/dist/{chunk-TYPGUK6W.js → chunk-AB44T6BB.js} +111 -5
- package/dist/{chunk-K4XHGFR5.js → chunk-B7OBL7PK.js} +317 -721
- package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
- package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
- package/dist/{chunk-ZVJ5BLO2.js → chunk-BKFJHQCA.js} +154 -16
- package/dist/chunk-BKFM6EJV.js +462 -0
- package/dist/chunk-BMS5RKQY.js +27 -0
- package/dist/{chunk-ZNLWCMVZ.js → chunk-BPKCPIL7.js} +2 -2
- package/dist/{chunk-TLQJPP24.js → chunk-BUMFYQFY.js} +1394 -1349
- package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
- package/dist/chunk-C2LTL2W6.js +2447 -0
- package/dist/{chunk-ME6CCNFO.js → chunk-CODPRO7Q.js} +8 -8
- package/dist/{chunk-E77JEWSD.js → chunk-CTJ4RNAA.js} +7 -37
- package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
- package/dist/{chunk-7RFXX52T.js → chunk-DQITNCXG.js} +642 -172
- package/dist/{chunk-TTHACPOM.js → chunk-DYJP44XW.js} +578 -117
- package/dist/{chunk-2HFZQUHL.js → chunk-F4CKPOEQ.js} +18 -8
- package/dist/{chunk-DGSYXYMX.js → chunk-FEFIFZTL.js} +3 -3
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
- package/dist/chunk-GKF55TAZ.js +391 -0
- package/dist/{chunk-VWZOAB7K.js → chunk-GR5G2PVF.js} +9 -8
- package/dist/{chunk-4DGYLA73.js → chunk-GXNLGKAB.js} +80 -9
- package/dist/chunk-HHV2GANA.js +88 -0
- package/dist/{chunk-IIZWH4XA.js → chunk-HI63TFOG.js} +5 -4
- package/dist/{chunk-WLFILSD5.js → chunk-HJJTYUHX.js} +113 -83
- package/dist/{chunk-TT36MB5S.js → chunk-HLW2MRKE.js} +3 -1
- package/dist/{chunk-PMDBGQSJ.js → chunk-HWHKMHUA.js} +7 -7
- package/dist/chunk-HZHHCK24.js +1631 -0
- package/dist/{chunk-WSB3FPX7.js → chunk-I5VEOC6I.js} +39 -143
- package/dist/chunk-IBEBSCYA.js +564 -0
- package/dist/chunk-IQ7KR472.js +362 -0
- package/dist/{chunk-A3WNZD3P.js → chunk-J4W7KFM7.js} +949 -972
- package/dist/{chunk-TB5666IT.js → chunk-JDG2WCRO.js} +5 -5
- package/dist/{chunk-N22QMJKY.js → chunk-K5C3NCBD.js} +4 -4
- package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
- package/dist/{chunk-5C3AQNDW.js → chunk-KFZI4NIL.js} +216 -38
- package/dist/chunk-KMVISBZR.js +132 -0
- package/dist/{chunk-WXY7KU3G.js → chunk-LDQ2ZF2M.js} +2 -2
- package/dist/{chunk-XN3L4EYL.js → chunk-LQ3DZAMX.js} +3 -3
- package/dist/{chunk-U6MBIEMB.js → chunk-LY4S7GJC.js} +173 -144
- package/dist/{chunk-4SPRNWDE.js → chunk-MLKNTWH2.js} +19 -19
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/chunk-NEKRRTYW.js +56 -0
- package/dist/{chunk-SPULKLCF.js → chunk-NHCZP4K7.js} +3 -3
- package/dist/chunk-NHLBIGRH.js +1506 -0
- package/dist/chunk-NQQH3YT7.js +302 -0
- package/dist/chunk-NYS75XW5.js +15 -0
- package/dist/{chunk-GN57SG4G.js → chunk-O4XIVISU.js} +10 -8
- package/dist/{chunk-EMYUUSFG.js → chunk-O6TL7WWY.js} +6 -6
- package/dist/chunk-OQBA45DZ.js +97 -0
- package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
- package/dist/chunk-PMZCIOCJ.js +25 -0
- package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
- package/dist/{chunk-J3YUBZWY.js → chunk-QBJA7R7N.js} +62 -6
- package/dist/chunk-QDC3K2U3.js +262 -0
- package/dist/{chunk-2HEJ2F35.js → chunk-QLFS5GO2.js} +22 -10
- package/dist/{chunk-7RGZWPB6.js → chunk-QLL7ILRG.js} +95 -32
- package/dist/{chunk-YS5VLNH5.js → chunk-QREDIESB.js} +6 -6
- package/dist/chunk-QSNYB6ZV.js +195 -0
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-P43ETTHK.js → chunk-SJ5ZKQ4S.js} +2 -2
- package/dist/{chunk-GPIEI3LY.js → chunk-SP2RXXYO.js} +6 -54
- package/dist/chunk-SUCTJL45.js +45 -0
- package/dist/{chunk-DYIM5TJT.js → chunk-SUW5DORT.js} +263 -7
- package/dist/chunk-T56WDKA5.js +183 -0
- package/dist/chunk-TVHHYFHE.js +255 -0
- package/dist/{chunk-FJ3H4MN5.js → chunk-TZ3SGWZZ.js} +3 -3
- package/dist/{chunk-MXKJU4JB.js → chunk-U77AMWDL.js} +91 -10
- package/dist/{chunk-5DHKRSMQ.js → chunk-ULC6OTWO.js} +11 -7
- package/dist/{chunk-RWSI4YD7.js → chunk-UM7N4G5A.js} +33 -12
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-IGWKHNIQ.js → chunk-UXMFQ54G.js} +44 -37
- package/dist/{chunk-HFSBBKSQ.js → chunk-V5DHCITQ.js} +171 -3
- package/dist/{chunk-5WIGXA4T.js → chunk-VAZSBTKF.js} +111 -4
- package/dist/{chunk-VHN4MY6O.js → chunk-VEO4AP2K.js} +2 -2
- package/dist/{chunk-IJ7RPIYJ.js → chunk-VFA6GDY5.js} +65 -4
- package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
- package/dist/chunk-VO67MWHC.js +75 -0
- package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
- package/dist/{chunk-TANS5ZJS.js → chunk-VYMXRQI6.js} +36 -22
- package/dist/{chunk-WWCZ5F23.js → chunk-W5VSYASO.js} +77 -16
- package/dist/{chunk-WNIJTQQK.js → chunk-WZR7K7ZX.js} +72 -116
- package/dist/{chunk-5Q2VVUKB.js → chunk-X3YGUTOB.js} +4 -4
- package/dist/chunk-X75E3D2N.js +686 -0
- package/dist/{chunk-VAWNZU7Z.js → chunk-YDFRH54B.js} +4 -4
- package/dist/chunk-YJX4SHTD.js +40 -0
- package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
- package/dist/chunk-Z2RR6MAK.js +127 -0
- package/dist/{chunk-FBVTI2TJ.js → chunk-Z4TXYIEG.js} +12 -131
- package/dist/cli/index.js +47 -36
- package/dist/{clio-QVTYJ57A.js → clio-2JXHBBY5.js} +7 -7
- package/dist/{code-nav-FGGFIE7L.js → code-nav-3YYRMYNF.js} +8 -8
- package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
- package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
- package/dist/{config-LW5IJFQN.js → config-QZPCMYSO.js} +99 -63
- package/dist/{configure-7XIZCOU4.js → configure-TEGEBYCA.js} +23 -22
- package/dist/{context-Y6Y7QPR6.js → context-AV7OEZ4D.js} +12 -12
- package/dist/{context-L3WL3X7K.js → context-E6H5RNMC.js} +56 -47
- package/dist/{context-N52ZA626.js → context-GSXUE4CT.js} +29 -27
- package/dist/{context-clear-MBQRLSDQ.js → context-clear-SHIBYK6T.js} +55 -46
- package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
- package/dist/{context-working-set-GS6DSO7F.js → context-working-set-5ZGKPGZQ.js} +13 -13
- package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-EFMJT4LD.js} +93 -64
- package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
- package/dist/doctor-QOA5FNY5.js +313 -0
- package/dist/{eval-BEC2WHDA.js → eval-TFBYQH4H.js} +2032 -156
- package/dist/eval-inventory-SXH7PDKX.js +316 -0
- package/dist/{evidence-REJUMSKM.js → evidence-ERGESKGN.js} +203 -48
- package/dist/{evolve-PY5ZBA5K.js → evolve-VDXTSYCJ.js} +52 -43
- package/dist/{extensions-HVKU65YU.js → extensions-7BGBHN57.js} +13 -7
- package/dist/{fleet-7WZEWRFA.js → fleet-2RRVDF2V.js} +228 -108
- package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-VJ726XIA.js} +11 -11
- package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
- package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-JF5QOATM.js} +18 -15
- package/dist/fleet-inspect-VLY4S7QM.js +442 -0
- package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-AIZUEJOY.js} +5 -5
- package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-AJRPDMDV.js} +22 -19
- package/dist/fleet-verify-JFEL2L3H.js +175 -0
- package/dist/fleet-view-ZCON35AG.js +102 -0
- package/dist/{init-OG3TPGQG.js → init-DN2WWLFE.js} +72 -62
- package/dist/install-XGLBQY5E.js +13 -0
- package/dist/interop-OZBKXAYL.js +114 -0
- package/dist/{library-CNTMPLRF.js → library-YWZG7IMW.js} +21 -18
- package/dist/{memory-6IS7F275.js → memory-I4C4HMLW.js} +54 -45
- package/dist/{models-ENRJDA5W.js → models-CEYXJBO6.js} +33 -30
- package/dist/{monitor-XLDVO7TN.js → monitor-NZ6GCI3P.js} +59 -52
- package/dist/{orchestrator-6KSPYRHA.js → orchestrator-GCGQ4N5I.js} +7827 -7328
- package/dist/panes-HMABYVO4.js +58 -0
- package/dist/panes-KY6W3V2E.js +103 -0
- package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
- package/dist/{reset-RZ4ER727.js → reset-DQ6FGCSH.js} +13 -11
- package/dist/resources-BB3MVJMD.js +111 -0
- package/dist/{run-Y2CNK5RU.js → run-H2GQDUER.js} +119 -87
- package/dist/{share-A55GYP6Z.js → share-GTJN6A5O.js} +20 -17
- package/dist/{skills-ALC5J6AT.js → skills-L55TEW6R.js} +33 -24
- package/dist/{skills-eval-JPBEBYQU.js → skills-eval-XVXPH2JI.js} +67 -56
- package/dist/skills-inventory-S4MXPJFV.js +126 -0
- package/dist/slash-commands-ZSGASKJC.js +77 -0
- package/dist/{steer-GGWFUJUD.js → steer-RZGSCY4R.js} +4 -4
- package/dist/{support-MIETYA5E.js → support-PKEUNNQL.js} +6 -6
- package/dist/{targets-VGNXIR3S.js → targets-NCPZ644J.js} +68 -40
- package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-44SV3YCN.js} +6 -4
- package/dist/tools-DAF3DI3C.js +27 -0
- package/dist/{trace-PNCASAXC.js → trace-FYVW2MQA.js} +207 -10
- package/dist/tui-primitives-2AKXQNZK.js +13 -0
- package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
- package/dist/{upgrade-FUSUAGHR.js → upgrade-3XPP6OQL.js} +27 -24
- package/dist/{usage-N4MKVHKD.js → usage-3NLHGTU2.js} +114 -62
- package/dist/{verifiers-YAWOJ3H2.js → verifiers-SSQONKRT.js} +172 -13
- package/dist/{verify-LTDHYBGY.js → verify-3U6J7FZI.js} +10 -10
- package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
- package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-CEHYGPGQ.js} +75 -65
- package/dist/with-panes-MKB46MPQ.js +782 -0
- package/dist/worker/entry.js +106 -75
- package/docs/README.md +3 -2
- package/docs/acp.md +24 -3
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +9 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +62 -3
- package/docs/commands-and-modes.md +31 -2
- package/docs/configuration-and-targets.md +69 -12
- package/docs/context-engine.md +63 -4
- package/docs/development-pipeline.md +19 -0
- package/docs/dispatch-typed-intent.md +385 -0
- package/docs/documentation-coverage.md +5 -5
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +3 -0
- package/docs/eval-runner.md +262 -11
- package/docs/evals-internal.md +72 -2
- package/docs/evidence-and-memory.md +12 -11
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +27 -1
- package/docs/fleet-dispatch.md +25 -4
- package/docs/installation-and-lifecycle.md +15 -2
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +10 -1
- package/docs/observability.md +55 -4
- package/docs/proactive-memory.md +127 -14
- package/docs/prompt-envelope-and-tools.md +19 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +19 -3
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +18 -8
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +88 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +5 -2
- package/src/cli/acp.ts +6 -2
- package/src/cli/agents.ts +1 -1
- package/src/cli/argv.ts +25 -0
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/configure.ts +23 -21
- package/src/cli/doctor-panes.ts +124 -0
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor-toolchain.ts +57 -0
- package/src/cli/doctor.ts +22 -1
- package/src/cli/eval-inventory.ts +436 -0
- package/src/cli/eval.ts +93 -16
- package/src/cli/evidence-detail.ts +88 -0
- package/src/cli/evidence-inventory.ts +183 -0
- package/src/cli/evidence.ts +30 -5
- package/src/cli/extensions.ts +5 -1
- package/src/cli/fleet-decisions.ts +69 -0
- package/src/cli/fleet-inspect.ts +334 -0
- package/src/cli/fleet-verify.ts +133 -0
- package/src/cli/fleet-view.ts +810 -0
- package/src/cli/fleet.ts +179 -39
- package/src/cli/index.ts +14 -2
- package/src/cli/interop-inspect.ts +128 -0
- package/src/cli/interop.ts +34 -0
- package/src/cli/panes.ts +35 -0
- package/src/cli/reset.ts +5 -2
- package/src/cli/run.ts +58 -0
- package/src/cli/skills-inventory.ts +185 -0
- package/src/cli/skills.ts +16 -13
- package/src/cli/targets.ts +44 -13
- package/src/cli/tools.ts +321 -0
- package/src/cli/trace-inspect.ts +252 -0
- package/src/cli/trace.ts +85 -5
- package/src/cli/usage.ts +63 -14
- package/src/cli/verifiers-inspect.ts +347 -0
- package/src/cli/verifiers.ts +9 -0
- package/src/core/bus-events.ts +33 -1
- package/src/core/cache-telemetry.ts +42 -0
- package/src/core/config.ts +67 -0
- package/src/core/defaults.ts +124 -8
- package/src/core/endpoint-key.ts +27 -0
- package/src/core/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +80 -6
- package/src/core/theme-token-hex.ts +43 -0
- package/src/core/tool-names.ts +2 -1
- package/src/core/xdg.ts +1 -1
- package/src/domains/agents/fleets/build-review.md +0 -3
- package/src/domains/agents/fleets/build-test.md +0 -3
- package/src/domains/agents/result-contract-filesystem.ts +32 -0
- package/src/domains/agents/result-contract.ts +164 -35
- package/src/domains/config/classify.ts +6 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/dispatch/admission-error.ts +9 -0
- package/src/domains/dispatch/admission.ts +52 -14
- package/src/domains/dispatch/capacity-lease.ts +118 -9
- package/src/domains/dispatch/contract.ts +11 -0
- package/src/domains/dispatch/council-topology.ts +398 -0
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/extension.ts +378 -82
- package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
- package/src/domains/dispatch/fleet-plan.ts +7 -2
- package/src/domains/dispatch/fleet-run.ts +87 -4
- package/src/domains/dispatch/gate-decisions.ts +11 -1
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/gate-topology.ts +289 -0
- package/src/domains/dispatch/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +22 -0
- package/src/domains/dispatch/intent-compatibility.ts +330 -0
- package/src/domains/dispatch/intent.ts +85 -1
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/reservation-store.ts +139 -11
- package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
- package/src/domains/dispatch/run-event-journal.ts +598 -0
- package/src/domains/dispatch/state.ts +49 -1
- package/src/domains/dispatch/types.ts +13 -0
- package/src/domains/dispatch/validation.ts +33 -8
- package/src/domains/dispatch/worker-spawn.ts +25 -11
- package/src/domains/dispatch/write-boundary-enforcer.ts +20 -3
- package/src/domains/dispatch/write-boundary.ts +62 -1
- package/src/domains/eval/artifacts/store.ts +62 -0
- package/src/domains/eval/compare/behavioral.ts +224 -0
- package/src/domains/eval/compare/compare.ts +342 -2
- package/src/domains/eval/compare/envelope.ts +128 -0
- package/src/domains/eval/compare/gates.ts +24 -6
- package/src/domains/eval/compare/thresholds.ts +30 -3
- package/src/domains/eval/execution-provenance.ts +240 -0
- package/src/domains/eval/inventory.ts +113 -0
- package/src/domains/eval/metrics/aggregate.ts +136 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
- package/src/domains/eval/metrics/tracked.ts +413 -0
- package/src/domains/eval/provenance.ts +117 -0
- package/src/domains/eval/reports/comparison.ts +128 -0
- package/src/domains/eval/reports/junit.ts +17 -3
- package/src/domains/eval/reports/markdown.ts +3 -3
- package/src/domains/eval/reports/text.ts +14 -0
- package/src/domains/eval/run-compare.ts +20 -0
- package/src/domains/eval/runners/clio-run.ts +127 -0
- package/src/domains/eval/runners/external-command.ts +28 -3
- package/src/domains/eval/schema/adapter.ts +111 -0
- package/src/domains/eval/schema/artifact.ts +20 -0
- package/src/domains/eval/schema/behavioral-metrics.ts +204 -0
- package/src/domains/eval/schema/behavioral.ts +520 -0
- package/src/domains/eval/schema/execution-envelope.ts +194 -0
- package/src/domains/eval/schema/serving.ts +105 -0
- package/src/domains/eval/schema/suite.ts +38 -8
- package/src/domains/eval/schema/validate.ts +58 -3
- package/src/domains/eval/schema/verdict.ts +237 -0
- package/src/domains/eval/suites/resolve.ts +2 -0
- package/src/domains/eval/suites/run.ts +264 -33
- package/src/domains/eval/verifiers/command.ts +2 -1
- package/src/domains/eval/workspaces/temp-copy.ts +145 -13
- package/src/domains/evidence/build.ts +2 -13
- package/src/domains/evidence/eval.ts +2 -12
- package/src/domains/evidence/findings-markdown.ts +33 -0
- package/src/domains/evidence/run-trust.ts +7 -113
- package/src/domains/evidence/store.ts +6 -0
- package/src/domains/evidence/trust-projection.ts +2 -2
- package/src/domains/extensions/compatibility.ts +285 -0
- package/src/domains/extensions/discovery.ts +38 -3
- package/src/domains/extensions/resources.ts +1 -1
- package/src/domains/extensions/state.ts +12 -3
- package/src/domains/extensions/types.ts +2 -0
- package/src/domains/lifecycle/doctor.ts +69 -1
- package/src/domains/memory/index.ts +14 -1
- package/src/domains/memory/task-bank-promotion.ts +64 -0
- package/src/domains/memory/task-memory-policy.ts +82 -17
- package/src/domains/memory/task-memory-spend.ts +131 -0
- package/src/domains/memory/task-memory-status.ts +7 -0
- package/src/domains/memory/task-memory-telemetry.ts +3 -0
- package/src/domains/middleware/index.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +97 -21
- package/src/domains/middleware/memory-step-endpoint.ts +71 -0
- package/src/domains/mux/contract.ts +434 -0
- package/src/domains/mux/detect.ts +158 -0
- package/src/domains/mux/extension.ts +47 -0
- package/src/domains/mux/index.ts +96 -0
- package/src/domains/mux/manifest.ts +6 -0
- package/src/domains/mux/operations.ts +164 -0
- package/src/domains/mux/pane-registry.ts +90 -0
- package/src/domains/mux/protocol.ts +49 -0
- package/src/domains/mux/socket-client.ts +816 -0
- package/src/domains/mux/types.ts +222 -0
- package/src/domains/mux/viewer-command.ts +59 -0
- package/src/domains/mux/yazi/assets/init.lua +2 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
- package/src/domains/mux/yazi/assets/yazi.toml +17 -0
- package/src/domains/mux/yazi/event-stream.ts +180 -0
- package/src/domains/mux/yazi/profile.ts +299 -0
- package/src/domains/mux/yazi/session.ts +228 -0
- package/src/domains/mux/yazi/theme.ts +30 -0
- package/src/domains/observability/background-memory-usage.ts +140 -0
- package/src/domains/observability/cost.ts +22 -1
- package/src/domains/observability/index.ts +9 -0
- package/src/domains/observability/out-of-turn-usage.ts +51 -2
- package/src/domains/observability/trace-store.ts +234 -2
- package/src/domains/prompts/compiler.ts +100 -13
- package/src/domains/providers/endpoint-capacity.ts +228 -0
- package/src/domains/providers/endpoint-slots-store.ts +189 -0
- package/src/domains/providers/extension.ts +20 -3
- package/src/domains/providers/index.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +32 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +243 -1
- package/src/domains/providers/runtime-resolution.ts +8 -1
- package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +31 -9
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +4 -1
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +4 -1
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +6 -1
- package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
- package/src/domains/providers/support.ts +1 -0
- package/src/domains/providers/target-model-cache.ts +124 -0
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/target-descriptor.ts +2 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/prompts/loader.ts +95 -33
- package/src/domains/resources/skills/loader.ts +33 -0
- package/src/domains/safety/action-classifier.ts +6 -0
- package/src/domains/safety/call-target.ts +52 -0
- package/src/domains/safety/run-effects.ts +35 -4
- package/src/domains/session/context-accounting.ts +52 -1
- package/src/domains/session/context-ledger.ts +37 -13
- package/src/domains/session/index.ts +6 -0
- package/src/domains/session/prompt-cache.ts +140 -0
- package/src/domains/session/prompt-manifest.ts +42 -0
- package/src/domains/toolchain/archive.ts +175 -0
- package/src/domains/toolchain/contract.ts +28 -0
- package/src/domains/toolchain/extension.ts +47 -0
- package/src/domains/toolchain/index.ts +39 -0
- package/src/domains/toolchain/install.ts +327 -0
- package/src/domains/toolchain/manifest.ts +8 -0
- package/src/domains/toolchain/paths.ts +34 -0
- package/src/domains/toolchain/registry.ts +265 -0
- package/src/domains/toolchain/remove.ts +218 -0
- package/src/domains/toolchain/resolve.ts +182 -0
- package/src/domains/toolchain/types.ts +113 -0
- package/src/domains/toolchain/version.ts +88 -0
- package/src/engine/acp/adapter.ts +18 -3
- package/src/engine/acp/server.ts +413 -70
- package/src/engine/acp/types.ts +19 -1
- package/src/engine/ai.ts +35 -0
- package/src/engine/apis/llamacpp-residency.ts +55 -3
- package/src/engine/apis/lmstudio.ts +25 -5
- package/src/engine/apis/ollama-native.ts +2 -1
- package/src/engine/apis/openai-completions.ts +80 -17
- package/src/engine/apis/residency-lock.ts +3 -1
- package/src/engine/apis/residency.ts +34 -1
- package/src/engine/claude/sdk-module.ts +98 -0
- package/src/engine/claude/sdk-runtime.ts +19 -11
- package/src/engine/provider-payload.ts +29 -1
- package/src/engine/tui-primitives.ts +21 -0
- package/src/engine/tui.ts +1 -0
- package/src/engine/worker-runtime.ts +2 -13
- package/src/entry/boot-options.ts +2 -0
- package/src/entry/orchestrator.ts +279 -35
- package/src/entry/panes-activation.ts +31 -0
- package/src/entry/with-panes.ts +20 -0
- package/src/interactive/chat-loop-messages.ts +26 -7
- package/src/interactive/chat-loop.ts +318 -41
- package/src/interactive/chat-panel.ts +62 -8
- package/src/interactive/clio-editor.ts +45 -8
- package/src/interactive/context-activity.ts +5 -1
- package/src/interactive/context-meter.ts +1 -1
- package/src/interactive/context-overlay.ts +41 -10
- package/src/interactive/cost-overlay.ts +66 -6
- package/src/interactive/council-grid.ts +1 -3
- package/src/interactive/council.ts +11 -0
- package/src/interactive/dispatch-board.ts +102 -20
- package/src/interactive/fleet-run-preview.ts +41 -15
- package/src/interactive/handoff-round.ts +41 -2
- package/src/interactive/interactive-application.ts +177 -7
- package/src/interactive/interactive-input-runtime.ts +15 -0
- package/src/interactive/interactive-presentation.ts +4 -0
- package/src/interactive/interactive-shell.ts +20 -17
- package/src/interactive/interactive-slash-runtime.ts +63 -10
- package/src/interactive/memory-overlay.ts +9 -0
- package/src/interactive/modal-marker.ts +170 -0
- package/src/interactive/mutation-preview.ts +295 -0
- package/src/interactive/mux-bridge.ts +214 -0
- package/src/interactive/overlay-frame.ts +58 -2
- package/src/interactive/overlay-general-openers.ts +17 -0
- package/src/interactive/overlay-key-routing.ts +52 -3
- package/src/interactive/overlay-lifecycle.ts +56 -7
- package/src/interactive/overlay-model-selectors.ts +40 -3
- package/src/interactive/overlay-permission-lifecycle.ts +112 -24
- package/src/interactive/overlay-session-lifecycle.ts +73 -9
- package/src/interactive/overlay-transitions.ts +18 -4
- package/src/interactive/overlays/agents.ts +1 -0
- package/src/interactive/overlays/ask-user.ts +227 -49
- package/src/interactive/overlays/auth-dialog.ts +1 -0
- package/src/interactive/overlays/context-reset.ts +1 -0
- package/src/interactive/overlays/cwd-fallback.ts +1 -0
- package/src/interactive/overlays/decisions.ts +11 -11
- package/src/interactive/overlays/extensions.ts +1 -0
- package/src/interactive/overlays/fleet-run-approval.ts +1 -0
- package/src/interactive/overlays/handoff-review.ts +1 -0
- package/src/interactive/overlays/help-reference.ts +6 -0
- package/src/interactive/overlays/interop.ts +1 -0
- package/src/interactive/overlays/library-install-confirm.ts +1 -0
- package/src/interactive/overlays/library-tabs.ts +28 -0
- package/src/interactive/overlays/list-overlay.ts +10 -1
- package/src/interactive/overlays/message-picker.ts +1 -0
- package/src/interactive/overlays/model-scope.ts +86 -0
- package/src/interactive/overlays/model-selector.ts +1 -0
- package/src/interactive/overlays/prompts.ts +12 -1
- package/src/interactive/overlays/session-selector.ts +1 -0
- package/src/interactive/overlays/settings-sections.ts +30 -0
- package/src/interactive/overlays/settings.ts +614 -45
- package/src/interactive/overlays/side-question.ts +1 -0
- package/src/interactive/overlays/skills-hub.ts +3 -11
- package/src/interactive/overlays/tree-selector.ts +1 -0
- package/src/interactive/pane-policy.ts +46 -0
- package/src/interactive/panes-runtime.ts +292 -0
- package/src/interactive/permission-hint.ts +34 -2
- package/src/interactive/permission-overlay.ts +159 -9
- package/src/interactive/prewarm.ts +197 -0
- package/src/interactive/render-trace.ts +162 -15
- package/src/interactive/renderers/compaction-summary.ts +29 -0
- package/src/interactive/renderers/tool-execution.ts +4 -0
- package/src/interactive/renderers/worker-entry.ts +122 -14
- package/src/interactive/side-question.ts +58 -1
- package/src/interactive/slash-commands.ts +251 -15
- package/src/interactive/status/controller.ts +11 -0
- package/src/interactive/status/state-machine.ts +54 -2
- package/src/interactive/status/types.ts +7 -0
- package/src/interactive/tasks-overlay.ts +1 -0
- package/src/interactive/terminal-lease.ts +2 -0
- package/src/interactive/theme/tokens.ts +3 -14
- package/src/interactive/turn-context.ts +346 -33
- package/src/interactive/turn-persistence.ts +14 -4
- package/src/interactive/turn-prewarm.ts +364 -0
- package/src/interactive/turn-queues.ts +7 -4
- package/src/interactive/turn-runtime.ts +8 -1
- package/src/interactive/turn-state.ts +23 -0
- package/src/interactive/view/artifacts.ts +109 -1
- package/src/interactive/view/view-overlay.ts +29 -3
- package/src/interactive/watch-pane.ts +152 -0
- package/src/interactive/worker-progress.ts +7 -1
- package/src/interactive/worker-receipts.ts +19 -1
- package/src/interactive/worker-stream.ts +5 -0
- package/src/interactive/yazi-bridge.ts +444 -0
- package/src/tools/ask-user.ts +43 -2
- package/src/tools/bootstrap.ts +26 -2
- package/src/tools/builtin-tool-catalog.ts +15 -0
- package/src/tools/compete-worktrees.ts +83 -2
- package/src/tools/core-bootstrap.ts +2 -1
- package/src/tools/dispatch-admission.ts +14 -3
- package/src/tools/dispatch-arguments.ts +20 -20
- package/src/tools/dispatch-plan.ts +17 -9
- package/src/tools/dispatch-run-events.ts +134 -19
- package/src/tools/dispatch-runner.ts +29 -7
- package/src/tools/dispatch-scout.ts +1 -1
- package/src/tools/dispatch-types.ts +15 -3
- package/src/tools/dispatch.ts +1 -1
- package/src/tools/executables.ts +17 -14
- package/src/tools/observation.ts +54 -4
- package/src/tools/panes-surface.ts +38 -0
- package/src/tools/panes.ts +112 -0
- package/src/tools/policy.ts +10 -1
- package/src/tools/presentation.ts +1 -0
- package/src/tools/registry.ts +16 -0
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HLE42MG7.js +0 -37
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-JOZYP4GM.js +0 -279
- package/dist/doctor-M7YEDGAE.js +0 -91
|
@@ -0,0 +1,1631 @@
|
|
|
1
|
+
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
parseTomlDocument
|
|
4
|
+
} from "./chunk-LCGCVYZ4.js";
|
|
5
|
+
import {
|
|
6
|
+
describeResolution,
|
|
7
|
+
resolveToolBinary,
|
|
8
|
+
toolStatus
|
|
9
|
+
} from "./chunk-QSNYB6ZV.js";
|
|
10
|
+
import {
|
|
11
|
+
findPinnedTool
|
|
12
|
+
} from "./chunk-QDC3K2U3.js";
|
|
13
|
+
import {
|
|
14
|
+
readClioVersion,
|
|
15
|
+
resolvePackageRoot
|
|
16
|
+
} from "./chunk-IWHMRKLL.js";
|
|
17
|
+
import {
|
|
18
|
+
clioCacheDir,
|
|
19
|
+
resolveClioDirs
|
|
20
|
+
} from "./chunk-BYP5D4HI.js";
|
|
21
|
+
import {
|
|
22
|
+
init_esm_shims
|
|
23
|
+
} from "./chunk-3R73A4XB.js";
|
|
24
|
+
|
|
25
|
+
// src/domains/mux/yazi/profile.ts
|
|
26
|
+
init_esm_shims();
|
|
27
|
+
import { spawnSync } from "node:child_process";
|
|
28
|
+
import { createHash } from "node:crypto";
|
|
29
|
+
import {
|
|
30
|
+
cpSync,
|
|
31
|
+
mkdirSync,
|
|
32
|
+
mkdtempSync,
|
|
33
|
+
readdirSync,
|
|
34
|
+
readFileSync,
|
|
35
|
+
renameSync,
|
|
36
|
+
rmSync,
|
|
37
|
+
statSync,
|
|
38
|
+
writeFileSync
|
|
39
|
+
} from "node:fs";
|
|
40
|
+
import { homedir } from "node:os";
|
|
41
|
+
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
42
|
+
|
|
43
|
+
// src/domains/mux/yazi/theme.ts
|
|
44
|
+
init_esm_shims();
|
|
45
|
+
|
|
46
|
+
// src/core/theme-token-hex.ts
|
|
47
|
+
init_esm_shims();
|
|
48
|
+
var TOKEN_HEX = {
|
|
49
|
+
accent: "#46e5d0",
|
|
50
|
+
accentDeep: "#1fb7a6",
|
|
51
|
+
action: "#ff7e29",
|
|
52
|
+
success: "#57e389",
|
|
53
|
+
warning: "#ffb454",
|
|
54
|
+
error: "#ff5c66",
|
|
55
|
+
info: "#5ba8ff",
|
|
56
|
+
reason: "#9d8cff",
|
|
57
|
+
dim: "#6a7a85",
|
|
58
|
+
muted: "#8a99a4",
|
|
59
|
+
title: "#46e5d0",
|
|
60
|
+
frame: "#2f5d5a",
|
|
61
|
+
frameStrong: "#2aab9e"
|
|
62
|
+
};
|
|
63
|
+
function tokenHex(token2) {
|
|
64
|
+
return TOKEN_HEX[token2];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/domains/mux/yazi/theme.ts
|
|
68
|
+
function renderYaziTheme() {
|
|
69
|
+
return `# Generated by Clio Coder. Changes are replaced when the managed profile regenerates.
|
|
70
|
+
|
|
71
|
+
[mgr]
|
|
72
|
+
cwd = { fg = "${tokenHex("accent")}" }
|
|
73
|
+
find_keyword = { fg = "${tokenHex("warning")}" }
|
|
74
|
+
marker_selected = { fg = "${tokenHex("success")}", bg = "${tokenHex("success")}" }
|
|
75
|
+
marker_copied = { fg = "${tokenHex("accent")}", bg = "${tokenHex("accent")}" }
|
|
76
|
+
marker_cut = { fg = "${tokenHex("error")}", bg = "${tokenHex("error")}" }
|
|
77
|
+
border_style = { fg = "${tokenHex("frame")}" }
|
|
78
|
+
|
|
79
|
+
[mode]
|
|
80
|
+
normal_main = { bg = "${tokenHex("accent")}" }
|
|
81
|
+
normal_alt = { fg = "${tokenHex("accent")}" }
|
|
82
|
+
select_main = { bg = "${tokenHex("action")}" }
|
|
83
|
+
select_alt = { fg = "${tokenHex("action")}" }
|
|
84
|
+
unset_main = { bg = "${tokenHex("error")}" }
|
|
85
|
+
unset_alt = { fg = "${tokenHex("error")}" }
|
|
86
|
+
|
|
87
|
+
[tabs]
|
|
88
|
+
active = { bg = "${tokenHex("accent")}" }
|
|
89
|
+
inactive = { fg = "${tokenHex("accent")}" }
|
|
90
|
+
|
|
91
|
+
[status]
|
|
92
|
+
perm_sep = { fg = "${tokenHex("dim")}" }
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/domains/mux/yazi/profile.ts
|
|
97
|
+
var PROFILE_FILES = ["yazi.toml", "keymap.toml", "theme.toml", "init.lua"];
|
|
98
|
+
var PROFILE_PLUGIN_FILES = ["main.lua", "types.lua", "LICENSE", "README.md"];
|
|
99
|
+
var STAMP_FILE = "stamp.json";
|
|
100
|
+
function yaziProfileDir(cacheDir = resolveClioDirs().cache) {
|
|
101
|
+
return join(cacheDir, "yazi", "profile");
|
|
102
|
+
}
|
|
103
|
+
function userYaziConfigDir(env = process.env, home = homedir()) {
|
|
104
|
+
const xdg = env.XDG_CONFIG_HOME;
|
|
105
|
+
return xdg && isAbsolute(xdg) ? join(xdg, "yazi") : join(home, ".config", "yazi");
|
|
106
|
+
}
|
|
107
|
+
function resetYaziProfile(profileDir = yaziProfileDir()) {
|
|
108
|
+
rmSync(profileDir, { recursive: true, force: true });
|
|
109
|
+
}
|
|
110
|
+
function defaultAssetDir() {
|
|
111
|
+
return join(resolvePackageRoot(), "src", "domains", "mux", "yazi", "assets");
|
|
112
|
+
}
|
|
113
|
+
function yaziPin() {
|
|
114
|
+
return findPinnedTool("yazi")?.version ?? "unknown";
|
|
115
|
+
}
|
|
116
|
+
function sha256(input) {
|
|
117
|
+
return createHash("sha256").update(input).digest("hex");
|
|
118
|
+
}
|
|
119
|
+
function filesBelow(root, current = root) {
|
|
120
|
+
const files = [];
|
|
121
|
+
for (const entry of readdirSync(current, { withFileTypes: true }).sort(
|
|
122
|
+
(left, right) => left.name.localeCompare(right.name)
|
|
123
|
+
)) {
|
|
124
|
+
const path = join(current, entry.name);
|
|
125
|
+
if (entry.isDirectory()) files.push(...filesBelow(root, path));
|
|
126
|
+
else if (entry.isFile()) files.push(relative(root, path).replaceAll("\\", "/"));
|
|
127
|
+
}
|
|
128
|
+
return files;
|
|
129
|
+
}
|
|
130
|
+
function hashYaziAssetTree(assetDir) {
|
|
131
|
+
const hash = createHash("sha256");
|
|
132
|
+
for (const file of filesBelow(assetDir)) {
|
|
133
|
+
hash.update(file);
|
|
134
|
+
hash.update("\0");
|
|
135
|
+
hash.update(readFileSync(join(assetDir, file)));
|
|
136
|
+
hash.update("\0");
|
|
137
|
+
}
|
|
138
|
+
return hash.digest("hex");
|
|
139
|
+
}
|
|
140
|
+
function shellQuote(value) {
|
|
141
|
+
return `'${value.replaceAll("'", `'\\''`)}'`;
|
|
142
|
+
}
|
|
143
|
+
function renderYaziKeymap(yaPath) {
|
|
144
|
+
const command = `shell -- ${shellQuote(yaPath)} pub-to "$YAZI_ID" clio-pick --list "$CLIO_YAZI_PICK_TOKEN" %s`;
|
|
145
|
+
return `# Generated by Clio Coder. Changes are replaced when the managed profile regenerates.
|
|
146
|
+
|
|
147
|
+
[[mgr.prepend_keymap]]
|
|
148
|
+
on = "<C-y>"
|
|
149
|
+
run = ${JSON.stringify(command)}
|
|
150
|
+
desc = "Send the selection to Clio"
|
|
151
|
+
`;
|
|
152
|
+
}
|
|
153
|
+
function expected(options) {
|
|
154
|
+
const assetDir = options.assetDir ?? defaultAssetDir();
|
|
155
|
+
const themeToml = options.themeToml ?? renderYaziTheme();
|
|
156
|
+
const yaziToml = options.yaziToml ?? readFileSync(join(assetDir, "yazi.toml"), "utf8");
|
|
157
|
+
const keymapToml = options.keymapToml ?? renderYaziKeymap(options.yaPath);
|
|
158
|
+
return {
|
|
159
|
+
dir: options.profileDir ?? yaziProfileDir(),
|
|
160
|
+
assetDir,
|
|
161
|
+
yaziToml,
|
|
162
|
+
keymapToml,
|
|
163
|
+
themeToml,
|
|
164
|
+
stamp: {
|
|
165
|
+
yaziVersion: options.yaziVersion ?? yaziPin(),
|
|
166
|
+
clioVersion: options.clioVersion ?? readClioVersion(),
|
|
167
|
+
yaPath: options.yaPath,
|
|
168
|
+
assetSha256: hashYaziAssetTree(assetDir),
|
|
169
|
+
themeSha256: sha256(themeToml)
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function readStamp(dir) {
|
|
174
|
+
try {
|
|
175
|
+
const value = JSON.parse(readFileSync(join(dir, STAMP_FILE), "utf8"));
|
|
176
|
+
if (typeof value.yaziVersion !== "string" || typeof value.clioVersion !== "string" || typeof value.yaPath !== "string" || typeof value.assetSha256 !== "string" || typeof value.themeSha256 !== "string") {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
return value;
|
|
180
|
+
} catch {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function sameStamp(left, right) {
|
|
185
|
+
return left !== null && left.yaziVersion === right.yaziVersion && left.clioVersion === right.clioVersion && left.yaPath === right.yaPath && left.assetSha256 === right.assetSha256 && left.themeSha256 === right.themeSha256;
|
|
186
|
+
}
|
|
187
|
+
function profileFilesExist(dir) {
|
|
188
|
+
return PROFILE_FILES.every((file) => statSync(join(dir, file), { throwIfNoEntry: false })?.isFile()) && PROFILE_PLUGIN_FILES.every(
|
|
189
|
+
(file) => statSync(join(dir, "plugins", "git.yazi", file), { throwIfNoEntry: false })?.isFile() === true
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
function inspectYaziProfile(options) {
|
|
193
|
+
const inputs = expected(options);
|
|
194
|
+
const present = statSync(inputs.dir, { throwIfNoEntry: false })?.isDirectory() === true;
|
|
195
|
+
const current = present && profileFilesExist(inputs.dir) && sameStamp(readStamp(inputs.dir), inputs.stamp);
|
|
196
|
+
return {
|
|
197
|
+
dir: inputs.dir,
|
|
198
|
+
userConfigDir: userYaziConfigDir(),
|
|
199
|
+
state: current ? "current" : present ? "stale" : "missing",
|
|
200
|
+
stamp: inputs.stamp
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function inspectCurrentYaziProfile() {
|
|
204
|
+
return inspectYaziProfile({ yaPath: resolveToolBinary("ya").binaryPath ?? "(unresolved)" });
|
|
205
|
+
}
|
|
206
|
+
function describeYaziProfile(inspection) {
|
|
207
|
+
return `${inspection.dir} (${inspection.state}); user config ${inspection.userConfigDir} is separate and untouched`;
|
|
208
|
+
}
|
|
209
|
+
function parseGenerated(dir) {
|
|
210
|
+
return ["yazi.toml", "keymap.toml", "theme.toml"].every((file) => {
|
|
211
|
+
try {
|
|
212
|
+
return parseTomlDocument(readFileSync(join(dir, file), "utf8")) !== null;
|
|
213
|
+
} catch {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
var YAZI_CONFIG_ERROR_MARKERS = ["Failed to parse config", "Press <Enter> to continue with preset settings"];
|
|
219
|
+
function validatesWithYazi(dir, yaziPath) {
|
|
220
|
+
const scratchHome = mkdtempSync(join(dirname(dir), ".yazi-validation-"));
|
|
221
|
+
try {
|
|
222
|
+
const result = spawnSync(yaziPath, ["--debug"], {
|
|
223
|
+
cwd: scratchHome,
|
|
224
|
+
env: {
|
|
225
|
+
...process.env,
|
|
226
|
+
HOME: scratchHome,
|
|
227
|
+
XDG_CACHE_HOME: join(scratchHome, "cache"),
|
|
228
|
+
XDG_CONFIG_HOME: join(scratchHome, "config"),
|
|
229
|
+
YAZI_CONFIG_HOME: dir
|
|
230
|
+
},
|
|
231
|
+
encoding: "utf8",
|
|
232
|
+
timeout: 5e3
|
|
233
|
+
});
|
|
234
|
+
const output = `${result.stdout ?? ""}
|
|
235
|
+
${result.stderr ?? ""}`;
|
|
236
|
+
return result.error === void 0 && result.status === 0 && YAZI_CONFIG_ERROR_MARKERS.every((marker) => !output.includes(marker));
|
|
237
|
+
} catch {
|
|
238
|
+
return false;
|
|
239
|
+
} finally {
|
|
240
|
+
rmSync(scratchHome, { recursive: true, force: true });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function ensureYaziProfile(options) {
|
|
244
|
+
let inputs;
|
|
245
|
+
try {
|
|
246
|
+
inputs = expected({ ...options, profileDir: options.profileDir ?? yaziProfileDir(clioCacheDir()) });
|
|
247
|
+
} catch {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
if (profileFilesExist(inputs.dir) && sameStamp(readStamp(inputs.dir), inputs.stamp)) {
|
|
251
|
+
return { dir: inputs.dir, stamp: inputs.stamp };
|
|
252
|
+
}
|
|
253
|
+
mkdirSync(dirname(inputs.dir), { recursive: true });
|
|
254
|
+
const staging = mkdtempSync(join(dirname(inputs.dir), ".profile-"));
|
|
255
|
+
try {
|
|
256
|
+
cpSync(join(inputs.assetDir, "init.lua"), join(staging, "init.lua"));
|
|
257
|
+
cpSync(join(inputs.assetDir, "plugins"), join(staging, "plugins"), { recursive: true });
|
|
258
|
+
writeFileSync(join(staging, "yazi.toml"), inputs.yaziToml);
|
|
259
|
+
writeFileSync(join(staging, "keymap.toml"), inputs.keymapToml);
|
|
260
|
+
writeFileSync(join(staging, "theme.toml"), inputs.themeToml);
|
|
261
|
+
writeFileSync(join(staging, STAMP_FILE), `${JSON.stringify(inputs.stamp, null, 2)}
|
|
262
|
+
`);
|
|
263
|
+
if (!parseGenerated(staging) || !validatesWithYazi(staging, options.yaziPath)) {
|
|
264
|
+
rmSync(inputs.dir, { recursive: true, force: true });
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
rmSync(inputs.dir, { recursive: true, force: true });
|
|
268
|
+
renameSync(staging, inputs.dir);
|
|
269
|
+
return { dir: inputs.dir, stamp: inputs.stamp };
|
|
270
|
+
} catch {
|
|
271
|
+
rmSync(inputs.dir, { recursive: true, force: true });
|
|
272
|
+
return null;
|
|
273
|
+
} finally {
|
|
274
|
+
rmSync(staging, { recursive: true, force: true });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// src/domains/mux/index.ts
|
|
279
|
+
init_esm_shims();
|
|
280
|
+
|
|
281
|
+
// src/domains/mux/extension.ts
|
|
282
|
+
init_esm_shims();
|
|
283
|
+
|
|
284
|
+
// src/domains/mux/contract.ts
|
|
285
|
+
init_esm_shims();
|
|
286
|
+
|
|
287
|
+
// src/domains/mux/pane-registry.ts
|
|
288
|
+
init_esm_shims();
|
|
289
|
+
function createPaneRegistry() {
|
|
290
|
+
const byPane = /* @__PURE__ */ new Map();
|
|
291
|
+
return {
|
|
292
|
+
record(entry) {
|
|
293
|
+
byPane.set(entry.ref.paneId, entry);
|
|
294
|
+
},
|
|
295
|
+
byPaneId(paneId) {
|
|
296
|
+
return byPane.get(paneId) ?? null;
|
|
297
|
+
},
|
|
298
|
+
byPurpose(purpose) {
|
|
299
|
+
let newest = null;
|
|
300
|
+
for (const entry of byPane.values()) {
|
|
301
|
+
if (entry.purpose === purpose) newest = entry;
|
|
302
|
+
}
|
|
303
|
+
return newest;
|
|
304
|
+
},
|
|
305
|
+
owns(paneId) {
|
|
306
|
+
return byPane.has(paneId);
|
|
307
|
+
},
|
|
308
|
+
forget(paneId) {
|
|
309
|
+
const entry = byPane.get(paneId);
|
|
310
|
+
if (!entry) return null;
|
|
311
|
+
byPane.delete(paneId);
|
|
312
|
+
return entry;
|
|
313
|
+
},
|
|
314
|
+
reconcile(livePaneIds) {
|
|
315
|
+
const live = new Set(livePaneIds);
|
|
316
|
+
const dropped = [];
|
|
317
|
+
for (const [paneId, entry] of byPane) {
|
|
318
|
+
if (!live.has(paneId)) dropped.push(entry);
|
|
319
|
+
}
|
|
320
|
+
for (const entry of dropped) byPane.delete(entry.ref.paneId);
|
|
321
|
+
return dropped;
|
|
322
|
+
},
|
|
323
|
+
list() {
|
|
324
|
+
return [...byPane.values()];
|
|
325
|
+
},
|
|
326
|
+
clear() {
|
|
327
|
+
byPane.clear();
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function paneRecord(ref, fields) {
|
|
332
|
+
return {
|
|
333
|
+
ref,
|
|
334
|
+
purpose: fields.purpose,
|
|
335
|
+
label: fields.label,
|
|
336
|
+
openedAt: fields.openedAt,
|
|
337
|
+
...fields.adopted === true ? { adopted: true } : {}
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// src/domains/mux/protocol.ts
|
|
342
|
+
init_esm_shims();
|
|
343
|
+
var MUX_METHOD_MIN_PROTOCOL = {
|
|
344
|
+
"notification.show": 17,
|
|
345
|
+
"pane.rename": 17,
|
|
346
|
+
"worktree.list": 10,
|
|
347
|
+
"worktree.create": 10,
|
|
348
|
+
"worktree.open": 10,
|
|
349
|
+
"worktree.remove": 10
|
|
350
|
+
};
|
|
351
|
+
function muxSupportsMethod(server, method) {
|
|
352
|
+
if (server === null) return false;
|
|
353
|
+
return server.protocol >= MUX_METHOD_MIN_PROTOCOL[method];
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/domains/mux/types.ts
|
|
357
|
+
init_esm_shims();
|
|
358
|
+
var MuxError = class extends Error {
|
|
359
|
+
kind;
|
|
360
|
+
/** The server's raw error code, when the failure came back over the wire. */
|
|
361
|
+
wireCode;
|
|
362
|
+
method;
|
|
363
|
+
constructor(kind, message, options = {}) {
|
|
364
|
+
super(message);
|
|
365
|
+
this.name = "MuxError";
|
|
366
|
+
this.kind = kind;
|
|
367
|
+
this.wireCode = options.wireCode ?? null;
|
|
368
|
+
this.method = options.method ?? null;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
var MuxRequestTimeout = class extends MuxError {
|
|
372
|
+
timeoutMs;
|
|
373
|
+
constructor(method, timeoutMs) {
|
|
374
|
+
super("timeout", `mux request ${method} timed out after ${timeoutMs}ms`, { method });
|
|
375
|
+
this.name = "MuxRequestTimeout";
|
|
376
|
+
this.timeoutMs = timeoutMs;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
var ERROR_KIND_BY_WIRE_CODE = {
|
|
380
|
+
agent_blocked: "agent_blocked",
|
|
381
|
+
agent_prompt_stalled: "agent_prompt_stalled",
|
|
382
|
+
feature_disabled: "feature_disabled",
|
|
383
|
+
invalid_params: "invalid_params",
|
|
384
|
+
invalid_request: "invalid_params",
|
|
385
|
+
not_found: "not_found"
|
|
386
|
+
};
|
|
387
|
+
function muxErrorKind(wireCode) {
|
|
388
|
+
const mapped = ERROR_KIND_BY_WIRE_CODE[wireCode];
|
|
389
|
+
if (mapped) return mapped;
|
|
390
|
+
if (wireCode.endsWith("_not_found")) return "not_found";
|
|
391
|
+
if (wireCode.startsWith("invalid_")) return "invalid_params";
|
|
392
|
+
return "unknown";
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// src/domains/mux/contract.ts
|
|
396
|
+
var METADATA_SOURCE = "clio:mux";
|
|
397
|
+
var SELF_AGENT_SOURCE = "clio:coder";
|
|
398
|
+
var OWNER_TOKEN_KEY = "clio_owner";
|
|
399
|
+
var OWNER_TOKEN_VALUE = "clio:mux";
|
|
400
|
+
var TOKEN_VALUE_MAX = 80;
|
|
401
|
+
var DEGRADE_COOLDOWN_MS = 5e3;
|
|
402
|
+
function shellQuote2(argv) {
|
|
403
|
+
return argv.map((arg) => `'${arg.replaceAll("'", `'\\''`)}'`).join(" ");
|
|
404
|
+
}
|
|
405
|
+
function token(value) {
|
|
406
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
407
|
+
return value.length > TOKEN_VALUE_MAX ? value.slice(0, TOKEN_VALUE_MAX) : value;
|
|
408
|
+
}
|
|
409
|
+
function createMuxRuntime(options) {
|
|
410
|
+
const { detection, client } = options;
|
|
411
|
+
const log = options.log ?? (() => void 0);
|
|
412
|
+
const now = options.now ?? Date.now;
|
|
413
|
+
const registry = createPaneRegistry();
|
|
414
|
+
let healthy = client !== null;
|
|
415
|
+
let probeHealthAt = 0;
|
|
416
|
+
let stopped = false;
|
|
417
|
+
let subscription = null;
|
|
418
|
+
const paneGoneHandlers = /* @__PURE__ */ new Set();
|
|
419
|
+
const degrade = (what, error) => {
|
|
420
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
421
|
+
const transport = error instanceof MuxError && (error.kind === "transport" || error.kind === "timeout");
|
|
422
|
+
if (transport) {
|
|
423
|
+
healthy = false;
|
|
424
|
+
probeHealthAt = now() + DEGRADE_COOLDOWN_MS;
|
|
425
|
+
}
|
|
426
|
+
log(transport ? "warning" : "debug", `mux ${what} failed: ${message}`);
|
|
427
|
+
};
|
|
428
|
+
const usable = () => {
|
|
429
|
+
if (stopped || client === null || detection.mode === "none") return false;
|
|
430
|
+
return healthy || now() >= probeHealthAt;
|
|
431
|
+
};
|
|
432
|
+
const attempt = async (what, run, fallback) => {
|
|
433
|
+
if (!usable() || client === null) return fallback;
|
|
434
|
+
try {
|
|
435
|
+
const value = await run(client);
|
|
436
|
+
healthy = true;
|
|
437
|
+
return value;
|
|
438
|
+
} catch (error) {
|
|
439
|
+
degrade(what, error);
|
|
440
|
+
return fallback;
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
const tagOwner = async (live, paneId, tokens, title) => {
|
|
444
|
+
await live.paneReportMetadata({
|
|
445
|
+
paneId,
|
|
446
|
+
source: METADATA_SOURCE,
|
|
447
|
+
...title === void 0 ? {} : { title },
|
|
448
|
+
tokens: { [OWNER_TOKEN_KEY]: OWNER_TOKEN_VALUE, ...tokens }
|
|
449
|
+
});
|
|
450
|
+
};
|
|
451
|
+
const onEvent = (event) => {
|
|
452
|
+
const dropped = registry.forget(event.paneId);
|
|
453
|
+
if (dropped) {
|
|
454
|
+
log("debug", `mux pane ${event.paneId} left on ${event.kind}; dropped from the registry`);
|
|
455
|
+
for (const handler of paneGoneHandlers) {
|
|
456
|
+
try {
|
|
457
|
+
handler(dropped);
|
|
458
|
+
} catch (error) {
|
|
459
|
+
log("debug", `mux pane-gone handler threw: ${error instanceof Error ? error.message : String(error)}`);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
const contract = {
|
|
465
|
+
mode: detection.mode,
|
|
466
|
+
available() {
|
|
467
|
+
return usable();
|
|
468
|
+
},
|
|
469
|
+
detection() {
|
|
470
|
+
return detection;
|
|
471
|
+
},
|
|
472
|
+
async openUtilityPane(request) {
|
|
473
|
+
return await attempt(
|
|
474
|
+
"openUtilityPane",
|
|
475
|
+
async (live) => {
|
|
476
|
+
const anchor = detection.self.paneId ?? (await live.paneCurrent()).paneId;
|
|
477
|
+
const pane = await live.paneSplit({
|
|
478
|
+
direction: request.direction ?? "right",
|
|
479
|
+
targetPaneId: anchor,
|
|
480
|
+
cwd: request.cwd,
|
|
481
|
+
focus: false,
|
|
482
|
+
...request.env ? { env: request.env } : {}
|
|
483
|
+
});
|
|
484
|
+
const ref = { paneId: pane.paneId, tabId: pane.tabId, workspaceId: pane.workspaceId };
|
|
485
|
+
const purpose = request.purpose ?? "utility";
|
|
486
|
+
registry.record(paneRecord(ref, { purpose, label: request.label, openedAt: now() }));
|
|
487
|
+
const title = request.title;
|
|
488
|
+
const titleSupported = title !== void 0 && muxSupportsMethod(detection.server, "pane.rename");
|
|
489
|
+
if (titleSupported) {
|
|
490
|
+
try {
|
|
491
|
+
await live.paneRename(pane.paneId, title);
|
|
492
|
+
} catch {
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
await tagOwner(live, pane.paneId, { role: token(purpose) }, titleSupported ? title : void 0);
|
|
496
|
+
if (request.argv.length > 0) {
|
|
497
|
+
const redirect = request.stdoutPath ? ` > ${shellQuote2([request.stdoutPath])}` : "";
|
|
498
|
+
await live.paneSendText(pane.paneId, `exec ${shellQuote2(request.argv)}${redirect}
|
|
499
|
+
`);
|
|
500
|
+
}
|
|
501
|
+
return ref;
|
|
502
|
+
},
|
|
503
|
+
null
|
|
504
|
+
);
|
|
505
|
+
},
|
|
506
|
+
async closePane(paneId) {
|
|
507
|
+
if (!registry.owns(paneId)) return false;
|
|
508
|
+
return await attempt(
|
|
509
|
+
"closePane",
|
|
510
|
+
async (live) => {
|
|
511
|
+
await live.paneClose(paneId);
|
|
512
|
+
registry.forget(paneId);
|
|
513
|
+
return true;
|
|
514
|
+
},
|
|
515
|
+
false
|
|
516
|
+
);
|
|
517
|
+
},
|
|
518
|
+
async adoptPane(request) {
|
|
519
|
+
const existing = registry.byPurpose(request.purpose);
|
|
520
|
+
if (existing) return existing.ref;
|
|
521
|
+
return await attempt(
|
|
522
|
+
"adoptPane",
|
|
523
|
+
async (live) => {
|
|
524
|
+
const snapshot = await live.snapshot();
|
|
525
|
+
for (const pane of snapshot.panes) {
|
|
526
|
+
if (pane.tokens[OWNER_TOKEN_KEY] !== OWNER_TOKEN_VALUE) continue;
|
|
527
|
+
if (pane.tokens.role !== request.purpose) continue;
|
|
528
|
+
if (registry.owns(pane.paneId)) continue;
|
|
529
|
+
if (detection.self.workspaceId !== null && pane.workspaceId !== detection.self.workspaceId) continue;
|
|
530
|
+
const ref = { paneId: pane.paneId, tabId: pane.tabId, workspaceId: pane.workspaceId };
|
|
531
|
+
registry.record(
|
|
532
|
+
paneRecord(ref, { purpose: request.purpose, label: request.label, openedAt: now(), adopted: true })
|
|
533
|
+
);
|
|
534
|
+
log("info", `mux adopted a ${request.purpose} pane left open by a previous session`);
|
|
535
|
+
return ref;
|
|
536
|
+
}
|
|
537
|
+
return null;
|
|
538
|
+
},
|
|
539
|
+
null
|
|
540
|
+
);
|
|
541
|
+
},
|
|
542
|
+
async notify(request) {
|
|
543
|
+
if (!muxSupportsMethod(detection.server, "notification.show")) {
|
|
544
|
+
log("debug", `mux notify skipped, server protocol is below the notification.show floor: ${request.title}`);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
await attempt(
|
|
548
|
+
"notify",
|
|
549
|
+
async (live) => {
|
|
550
|
+
const result = await live.notificationShow({
|
|
551
|
+
title: request.title,
|
|
552
|
+
...request.body ? { body: request.body } : {},
|
|
553
|
+
...request.sound ? { sound: request.sound } : {}
|
|
554
|
+
});
|
|
555
|
+
if (!result.shown) log("debug", `mux notify not shown (${result.reason}): ${request.title}`);
|
|
556
|
+
return void 0;
|
|
557
|
+
},
|
|
558
|
+
void 0
|
|
559
|
+
);
|
|
560
|
+
},
|
|
561
|
+
async worktreeCreate(request) {
|
|
562
|
+
if (!muxSupportsMethod(detection.server, "worktree.create")) {
|
|
563
|
+
log("debug", "mux worktree.create skipped, server protocol is below the worktree floor");
|
|
564
|
+
return null;
|
|
565
|
+
}
|
|
566
|
+
return await attempt("worktreeCreate", (live) => live.worktreeCreate(request), null);
|
|
567
|
+
},
|
|
568
|
+
async worktreeRemove(workspaceId, removeOptions = {}) {
|
|
569
|
+
if (!muxSupportsMethod(detection.server, "worktree.remove")) {
|
|
570
|
+
log("debug", "mux worktree.remove skipped, server protocol is below the worktree floor");
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
return await attempt(
|
|
574
|
+
"worktreeRemove",
|
|
575
|
+
async (live) => {
|
|
576
|
+
await live.worktreeRemove(workspaceId, removeOptions);
|
|
577
|
+
return true;
|
|
578
|
+
},
|
|
579
|
+
false
|
|
580
|
+
);
|
|
581
|
+
},
|
|
582
|
+
onPaneGone(handler) {
|
|
583
|
+
paneGoneHandlers.add(handler);
|
|
584
|
+
return () => {
|
|
585
|
+
paneGoneHandlers.delete(handler);
|
|
586
|
+
};
|
|
587
|
+
},
|
|
588
|
+
list() {
|
|
589
|
+
return registry.list();
|
|
590
|
+
},
|
|
591
|
+
async reportSelf(report) {
|
|
592
|
+
const paneId = detection.self.paneId;
|
|
593
|
+
if (detection.mode !== "guest" || !paneId) return false;
|
|
594
|
+
return await attempt(
|
|
595
|
+
"reportSelf",
|
|
596
|
+
async (live) => {
|
|
597
|
+
await live.paneReportAgent({
|
|
598
|
+
paneId,
|
|
599
|
+
source: SELF_AGENT_SOURCE,
|
|
600
|
+
agent: "clio-coder",
|
|
601
|
+
state: report.state,
|
|
602
|
+
...report.message ? { message: report.message } : {}
|
|
603
|
+
});
|
|
604
|
+
if (report.tokens || report.stateLabels || report.ttlMs !== void 0) {
|
|
605
|
+
await live.paneReportMetadata({
|
|
606
|
+
paneId,
|
|
607
|
+
source: METADATA_SOURCE,
|
|
608
|
+
...report.tokens ? { tokens: report.tokens } : {},
|
|
609
|
+
...report.stateLabels ? { stateLabels: report.stateLabels } : {},
|
|
610
|
+
...report.ttlMs !== void 0 ? { ttlMs: report.ttlMs } : {}
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
return true;
|
|
614
|
+
},
|
|
615
|
+
false
|
|
616
|
+
);
|
|
617
|
+
},
|
|
618
|
+
async shutdown() {
|
|
619
|
+
if (stopped) return;
|
|
620
|
+
stopped = true;
|
|
621
|
+
subscription?.close();
|
|
622
|
+
subscription = null;
|
|
623
|
+
paneGoneHandlers.clear();
|
|
624
|
+
if (client) await client.close().catch(() => void 0);
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
const start = async () => {
|
|
628
|
+
if (detection.mode === "none" || client === null) return;
|
|
629
|
+
try {
|
|
630
|
+
subscription = await client.subscribe(["pane.closed", "pane.exited"], onEvent, {
|
|
631
|
+
onResync: (snapshot) => {
|
|
632
|
+
const dropped = registry.reconcile(snapshot.panes.map((pane) => pane.paneId));
|
|
633
|
+
if (dropped.length > 0) {
|
|
634
|
+
log("info", `mux reconciled ${dropped.length} pane(s) closed while the socket was down`);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
} catch (error) {
|
|
639
|
+
degrade("event subscription", error);
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
return { contract, start, stop: contract.shutdown, registry };
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// src/domains/mux/detect.ts
|
|
646
|
+
init_esm_shims();
|
|
647
|
+
import { homedir as homedir2 } from "node:os";
|
|
648
|
+
import { join as join2 } from "node:path";
|
|
649
|
+
|
|
650
|
+
// src/domains/mux/socket-client.ts
|
|
651
|
+
init_esm_shims();
|
|
652
|
+
import * as net from "node:net";
|
|
653
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 5e3;
|
|
654
|
+
var DEFAULT_CONNECT_TIMEOUT_MS = 2e3;
|
|
655
|
+
var DEFAULT_BACKOFF = { initialDelayMs: 250, maxDelayMs: 5e3, factor: 2 };
|
|
656
|
+
var MAX_LINE_BYTES = 8 * 1024 * 1024;
|
|
657
|
+
function connectSocket(socketPath, timeoutMs) {
|
|
658
|
+
return new Promise((resolve, reject) => {
|
|
659
|
+
const socket = net.connect({ path: socketPath });
|
|
660
|
+
socket.setNoDelay(true);
|
|
661
|
+
const timer = setTimeout(() => {
|
|
662
|
+
socket.destroy();
|
|
663
|
+
reject(new MuxError("transport", `mux socket connect to ${socketPath} timed out after ${timeoutMs}ms`));
|
|
664
|
+
}, timeoutMs);
|
|
665
|
+
timer.unref?.();
|
|
666
|
+
const settle = (error) => {
|
|
667
|
+
clearTimeout(timer);
|
|
668
|
+
socket.removeListener("connect", onConnect);
|
|
669
|
+
socket.removeListener("error", onError);
|
|
670
|
+
if (error) {
|
|
671
|
+
socket.destroy();
|
|
672
|
+
reject(new MuxError("transport", `mux socket connect to ${socketPath} failed: ${error.message}`));
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
resolve(socket);
|
|
676
|
+
};
|
|
677
|
+
const onConnect = () => settle(null);
|
|
678
|
+
const onError = (error) => settle(error);
|
|
679
|
+
socket.once("connect", onConnect);
|
|
680
|
+
socket.once("error", onError);
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
function readJsonLines(socket, onValue, onOverflow) {
|
|
684
|
+
let buffer = "";
|
|
685
|
+
socket.setEncoding("utf8");
|
|
686
|
+
socket.on("data", (chunk) => {
|
|
687
|
+
buffer += chunk;
|
|
688
|
+
if (buffer.length > MAX_LINE_BYTES) {
|
|
689
|
+
buffer = "";
|
|
690
|
+
onOverflow();
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
let newline = buffer.indexOf("\n");
|
|
694
|
+
while (newline >= 0) {
|
|
695
|
+
const line = buffer.slice(0, newline).trim();
|
|
696
|
+
buffer = buffer.slice(newline + 1);
|
|
697
|
+
if (line.length > 0) {
|
|
698
|
+
let parsed;
|
|
699
|
+
try {
|
|
700
|
+
parsed = JSON.parse(line);
|
|
701
|
+
} catch {
|
|
702
|
+
parsed = null;
|
|
703
|
+
}
|
|
704
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
705
|
+
onValue(parsed);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
newline = buffer.indexOf("\n");
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
function asRecord(value) {
|
|
713
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
714
|
+
}
|
|
715
|
+
function requireString(source, key, context) {
|
|
716
|
+
const value = source[key];
|
|
717
|
+
if (typeof value !== "string") {
|
|
718
|
+
throw new MuxError("protocol", `mux ${context} response is missing string field ${key}`);
|
|
719
|
+
}
|
|
720
|
+
return value;
|
|
721
|
+
}
|
|
722
|
+
function optionalString(source, key) {
|
|
723
|
+
const value = source[key];
|
|
724
|
+
return typeof value === "string" ? value : null;
|
|
725
|
+
}
|
|
726
|
+
function stringMap(value) {
|
|
727
|
+
const source = asRecord(value);
|
|
728
|
+
if (!source) return {};
|
|
729
|
+
const out = {};
|
|
730
|
+
for (const [key, entry] of Object.entries(source)) {
|
|
731
|
+
if (typeof entry === "string") out[key] = entry;
|
|
732
|
+
}
|
|
733
|
+
return out;
|
|
734
|
+
}
|
|
735
|
+
var AGENT_STATES = /* @__PURE__ */ new Set(["idle", "working", "blocked", "done", "unknown"]);
|
|
736
|
+
function readAgentState(value) {
|
|
737
|
+
return typeof value === "string" && AGENT_STATES.has(value) ? value : "unknown";
|
|
738
|
+
}
|
|
739
|
+
function readPane(value) {
|
|
740
|
+
const source = asRecord(value);
|
|
741
|
+
if (!source) throw new MuxError("protocol", "mux pane response is not an object");
|
|
742
|
+
const revision = source.revision;
|
|
743
|
+
return {
|
|
744
|
+
paneId: requireString(source, "pane_id", "pane"),
|
|
745
|
+
tabId: requireString(source, "tab_id", "pane"),
|
|
746
|
+
workspaceId: requireString(source, "workspace_id", "pane"),
|
|
747
|
+
focused: source.focused === true,
|
|
748
|
+
agentState: readAgentState(source.agent_status),
|
|
749
|
+
revision: typeof revision === "number" ? revision : 0,
|
|
750
|
+
label: optionalString(source, "label"),
|
|
751
|
+
title: optionalString(source, "title"),
|
|
752
|
+
cwd: optionalString(source, "cwd"),
|
|
753
|
+
agent: optionalString(source, "agent"),
|
|
754
|
+
tokens: stringMap(source.tokens)
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
function readTab(value) {
|
|
758
|
+
const source = asRecord(value);
|
|
759
|
+
if (!source) throw new MuxError("protocol", "mux tab response is not an object");
|
|
760
|
+
const number = source.number;
|
|
761
|
+
const paneCount = source.pane_count;
|
|
762
|
+
return {
|
|
763
|
+
tabId: requireString(source, "tab_id", "tab"),
|
|
764
|
+
workspaceId: requireString(source, "workspace_id", "tab"),
|
|
765
|
+
number: typeof number === "number" ? number : 0,
|
|
766
|
+
label: optionalString(source, "label") ?? "",
|
|
767
|
+
focused: source.focused === true,
|
|
768
|
+
paneCount: typeof paneCount === "number" ? paneCount : 0,
|
|
769
|
+
agentState: readAgentState(source.agent_status)
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
function readWorktree(value) {
|
|
773
|
+
const source = asRecord(value);
|
|
774
|
+
if (!source) throw new MuxError("protocol", "mux worktree response is not an object");
|
|
775
|
+
return {
|
|
776
|
+
path: requireString(source, "path", "worktree"),
|
|
777
|
+
branch: optionalString(source, "branch"),
|
|
778
|
+
isBare: source.is_bare === true,
|
|
779
|
+
isDetached: source.is_detached === true,
|
|
780
|
+
isPrunable: source.is_prunable === true,
|
|
781
|
+
isLinkedWorktree: source.is_linked_worktree === true,
|
|
782
|
+
openWorkspaceId: optionalString(source, "open_workspace_id"),
|
|
783
|
+
label: optionalString(source, "label") ?? ""
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
function readWorktreeSource(value) {
|
|
787
|
+
const source = asRecord(value);
|
|
788
|
+
if (!source) throw new MuxError("protocol", "mux worktree source response is not an object");
|
|
789
|
+
return {
|
|
790
|
+
repoKey: requireString(source, "repo_key", "worktree source"),
|
|
791
|
+
repoName: requireString(source, "repo_name", "worktree source"),
|
|
792
|
+
repoRoot: requireString(source, "repo_root", "worktree source"),
|
|
793
|
+
sourceCheckoutPath: requireString(source, "source_checkout_path", "worktree source"),
|
|
794
|
+
sourceWorkspaceId: optionalString(source, "source_workspace_id")
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
function readArray(source, key) {
|
|
798
|
+
const value = source[key];
|
|
799
|
+
return Array.isArray(value) ? value : [];
|
|
800
|
+
}
|
|
801
|
+
function readServerInfo(source) {
|
|
802
|
+
const protocol = source.protocol;
|
|
803
|
+
return {
|
|
804
|
+
version: optionalString(source, "version") ?? "",
|
|
805
|
+
protocol: typeof protocol === "number" ? protocol : 0
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
function readSnapshot(value) {
|
|
809
|
+
const source = asRecord(value);
|
|
810
|
+
if (!source) throw new MuxError("protocol", "mux snapshot response is not an object");
|
|
811
|
+
return {
|
|
812
|
+
server: readServerInfo(source),
|
|
813
|
+
focusedPaneId: optionalString(source, "focused_pane_id"),
|
|
814
|
+
focusedTabId: optionalString(source, "focused_tab_id"),
|
|
815
|
+
focusedWorkspaceId: optionalString(source, "focused_workspace_id"),
|
|
816
|
+
panes: readArray(source, "panes").map(readPane),
|
|
817
|
+
tabs: readArray(source, "tabs").map(readTab)
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
var EVENT_KIND_BY_WIRE = {
|
|
821
|
+
pane_closed: "pane.closed",
|
|
822
|
+
pane_exited: "pane.exited"
|
|
823
|
+
};
|
|
824
|
+
function readEvent(line) {
|
|
825
|
+
const wireKind = line.event;
|
|
826
|
+
if (typeof wireKind !== "string") return null;
|
|
827
|
+
const kind = EVENT_KIND_BY_WIRE[wireKind];
|
|
828
|
+
if (!kind) return null;
|
|
829
|
+
const data = asRecord(line.data);
|
|
830
|
+
if (!data) return null;
|
|
831
|
+
const paneId = data.pane_id;
|
|
832
|
+
const workspaceId = data.workspace_id;
|
|
833
|
+
if (typeof paneId !== "string" || typeof workspaceId !== "string") return null;
|
|
834
|
+
return { kind, paneId, workspaceId };
|
|
835
|
+
}
|
|
836
|
+
function params(entries) {
|
|
837
|
+
const out = {};
|
|
838
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
839
|
+
if (value !== void 0) out[key] = value;
|
|
840
|
+
}
|
|
841
|
+
return out;
|
|
842
|
+
}
|
|
843
|
+
function createMuxClient(options) {
|
|
844
|
+
const socketPath = options.socketPath;
|
|
845
|
+
const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
846
|
+
const connectTimeoutMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
847
|
+
const backoff = options.backoff ?? DEFAULT_BACKOFF;
|
|
848
|
+
const log = options.log ?? (() => void 0);
|
|
849
|
+
let disposed = false;
|
|
850
|
+
let nextId = 0;
|
|
851
|
+
let reachable = false;
|
|
852
|
+
let serverInfo = null;
|
|
853
|
+
let snapshotCache = null;
|
|
854
|
+
let connectFailures = 0;
|
|
855
|
+
let retryAt = 0;
|
|
856
|
+
const delayFor = (failures) => Math.min(backoff.maxDelayMs, backoff.initialDelayMs * backoff.factor ** Math.max(0, failures - 1));
|
|
857
|
+
const call = async (method, callParams, timeoutMs) => {
|
|
858
|
+
if (disposed) throw new MuxError("transport", "mux client is closed");
|
|
859
|
+
const waitMs = retryAt - Date.now();
|
|
860
|
+
if (waitMs > 0) {
|
|
861
|
+
throw new MuxError("transport", `mux socket ${socketPath} is in backoff for another ${waitMs}ms`);
|
|
862
|
+
}
|
|
863
|
+
let socket;
|
|
864
|
+
try {
|
|
865
|
+
socket = await connectSocket(socketPath, connectTimeoutMs);
|
|
866
|
+
} catch (error) {
|
|
867
|
+
connectFailures += 1;
|
|
868
|
+
retryAt = Date.now() + delayFor(connectFailures);
|
|
869
|
+
reachable = false;
|
|
870
|
+
throw error;
|
|
871
|
+
}
|
|
872
|
+
connectFailures = 0;
|
|
873
|
+
retryAt = 0;
|
|
874
|
+
nextId += 1;
|
|
875
|
+
const id = `clio-${nextId}`;
|
|
876
|
+
const budget = timeoutMs ?? requestTimeoutMs;
|
|
877
|
+
try {
|
|
878
|
+
const result = await new Promise((resolve, reject) => {
|
|
879
|
+
let settled = false;
|
|
880
|
+
const finish = (settle) => {
|
|
881
|
+
if (settled) return;
|
|
882
|
+
settled = true;
|
|
883
|
+
clearTimeout(timer);
|
|
884
|
+
socket.destroy();
|
|
885
|
+
settle();
|
|
886
|
+
};
|
|
887
|
+
const timer = setTimeout(() => finish(() => reject(new MuxRequestTimeout(method, budget))), budget);
|
|
888
|
+
timer.unref?.();
|
|
889
|
+
readJsonLines(
|
|
890
|
+
socket,
|
|
891
|
+
(line) => {
|
|
892
|
+
const responseId = line.id;
|
|
893
|
+
if (typeof responseId !== "string") return;
|
|
894
|
+
const error = asRecord(line.error);
|
|
895
|
+
if (responseId !== id && !(responseId === "" && error)) return;
|
|
896
|
+
if (error) {
|
|
897
|
+
const code = typeof error.code === "string" ? error.code : "unknown";
|
|
898
|
+
const message = typeof error.message === "string" ? error.message : code;
|
|
899
|
+
finish(() => reject(new MuxError(muxErrorKind(code), message, { wireCode: code, method })));
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
finish(() => resolve(line.result));
|
|
903
|
+
},
|
|
904
|
+
() => finish(() => reject(new MuxError("protocol", `mux ${method} response line was oversized`, { method })))
|
|
905
|
+
);
|
|
906
|
+
socket.on(
|
|
907
|
+
"error",
|
|
908
|
+
(error) => finish(() => reject(new MuxError("transport", `mux request ${method} failed: ${error.message}`, { method })))
|
|
909
|
+
);
|
|
910
|
+
socket.on(
|
|
911
|
+
"close",
|
|
912
|
+
() => finish(() => reject(new MuxError("transport", `mux request ${method} lost its connection`, { method })))
|
|
913
|
+
);
|
|
914
|
+
socket.write(`${JSON.stringify({ id, method, params: callParams })}
|
|
915
|
+
`, (error) => {
|
|
916
|
+
if (!error) return;
|
|
917
|
+
finish(
|
|
918
|
+
() => reject(new MuxError("transport", `mux request ${method} failed to write: ${error.message}`, { method }))
|
|
919
|
+
);
|
|
920
|
+
});
|
|
921
|
+
});
|
|
922
|
+
reachable = true;
|
|
923
|
+
return result;
|
|
924
|
+
} catch (error) {
|
|
925
|
+
if (error instanceof MuxError && error.kind === "transport") reachable = false;
|
|
926
|
+
throw error;
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
const callObject = async (method, callParams, timeoutMs) => {
|
|
930
|
+
const result = asRecord(await call(method, callParams, timeoutMs));
|
|
931
|
+
if (!result) throw new MuxError("protocol", `mux ${method} returned a non-object result`, { method });
|
|
932
|
+
return result;
|
|
933
|
+
};
|
|
934
|
+
const snapshot = async () => {
|
|
935
|
+
const result = await callObject("session.snapshot", {});
|
|
936
|
+
const parsed = readSnapshot(result.snapshot);
|
|
937
|
+
snapshotCache = parsed;
|
|
938
|
+
serverInfo = parsed.server;
|
|
939
|
+
return parsed;
|
|
940
|
+
};
|
|
941
|
+
const subscribe = async (kinds, handler, subscribeOptions = {}) => {
|
|
942
|
+
let closed = false;
|
|
943
|
+
let socket = null;
|
|
944
|
+
let retryTimer = null;
|
|
945
|
+
let failures = 0;
|
|
946
|
+
const scheduleReopen = () => {
|
|
947
|
+
if (closed || disposed) return;
|
|
948
|
+
failures += 1;
|
|
949
|
+
const delay = delayFor(failures);
|
|
950
|
+
retryTimer = setTimeout(() => {
|
|
951
|
+
retryTimer = null;
|
|
952
|
+
void open(true);
|
|
953
|
+
}, delay);
|
|
954
|
+
retryTimer.unref?.();
|
|
955
|
+
};
|
|
956
|
+
const open = async (isReconnect) => {
|
|
957
|
+
if (closed || disposed) return;
|
|
958
|
+
let stream;
|
|
959
|
+
try {
|
|
960
|
+
stream = await connectSocket(socketPath, connectTimeoutMs);
|
|
961
|
+
} catch (error) {
|
|
962
|
+
log("debug", `mux event stream connect failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
963
|
+
scheduleReopen();
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
if (closed || disposed) {
|
|
967
|
+
stream.destroy();
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
socket = stream;
|
|
971
|
+
let acknowledged = false;
|
|
972
|
+
readJsonLines(
|
|
973
|
+
stream,
|
|
974
|
+
(line) => {
|
|
975
|
+
if (!acknowledged && typeof line.id === "string") {
|
|
976
|
+
acknowledged = true;
|
|
977
|
+
failures = 0;
|
|
978
|
+
if (isReconnect) {
|
|
979
|
+
void snapshot().then(
|
|
980
|
+
(fresh) => subscribeOptions.onResync?.(fresh),
|
|
981
|
+
(error) => log("debug", `mux snapshot re-bootstrap failed: ${error instanceof Error ? error.message : String(error)}`)
|
|
982
|
+
);
|
|
983
|
+
}
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
const event = readEvent(line);
|
|
987
|
+
if (event) handler(event);
|
|
988
|
+
},
|
|
989
|
+
() => stream.destroy()
|
|
990
|
+
);
|
|
991
|
+
const onGone = () => {
|
|
992
|
+
if (socket !== stream) return;
|
|
993
|
+
socket = null;
|
|
994
|
+
stream.destroy();
|
|
995
|
+
scheduleReopen();
|
|
996
|
+
};
|
|
997
|
+
stream.on("error", onGone);
|
|
998
|
+
stream.on("close", onGone);
|
|
999
|
+
stream.write(
|
|
1000
|
+
`${JSON.stringify({
|
|
1001
|
+
id: `clio-sub-${kinds.join("+")}`,
|
|
1002
|
+
method: "events.subscribe",
|
|
1003
|
+
params: { subscriptions: kinds.map((kind) => ({ type: kind })) }
|
|
1004
|
+
})}
|
|
1005
|
+
`
|
|
1006
|
+
);
|
|
1007
|
+
};
|
|
1008
|
+
await open(false);
|
|
1009
|
+
return {
|
|
1010
|
+
close() {
|
|
1011
|
+
closed = true;
|
|
1012
|
+
if (retryTimer) clearTimeout(retryTimer);
|
|
1013
|
+
retryTimer = null;
|
|
1014
|
+
socket?.destroy();
|
|
1015
|
+
socket = null;
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
};
|
|
1019
|
+
return {
|
|
1020
|
+
socketPath,
|
|
1021
|
+
connected() {
|
|
1022
|
+
return reachable;
|
|
1023
|
+
},
|
|
1024
|
+
server() {
|
|
1025
|
+
return serverInfo;
|
|
1026
|
+
},
|
|
1027
|
+
cachedSnapshot() {
|
|
1028
|
+
return snapshotCache;
|
|
1029
|
+
},
|
|
1030
|
+
async ping(pingOptions = {}) {
|
|
1031
|
+
const result = await callObject("ping", {}, pingOptions.timeoutMs);
|
|
1032
|
+
const info = readServerInfo(result);
|
|
1033
|
+
serverInfo = info;
|
|
1034
|
+
return info;
|
|
1035
|
+
},
|
|
1036
|
+
snapshot,
|
|
1037
|
+
async paneCurrent(callerPaneId) {
|
|
1038
|
+
const result = await callObject("pane.current", params({ caller_pane_id: callerPaneId }));
|
|
1039
|
+
return readPane(result.pane);
|
|
1040
|
+
},
|
|
1041
|
+
async paneList(workspaceId) {
|
|
1042
|
+
const result = await callObject("pane.list", params({ workspace_id: workspaceId }));
|
|
1043
|
+
return readArray(result, "panes").map(readPane);
|
|
1044
|
+
},
|
|
1045
|
+
async paneSplit(request) {
|
|
1046
|
+
const result = await callObject(
|
|
1047
|
+
"pane.split",
|
|
1048
|
+
params({
|
|
1049
|
+
direction: request.direction,
|
|
1050
|
+
target_pane_id: request.targetPaneId,
|
|
1051
|
+
workspace_id: request.workspaceId,
|
|
1052
|
+
cwd: request.cwd,
|
|
1053
|
+
env: request.env,
|
|
1054
|
+
focus: request.focus ?? false,
|
|
1055
|
+
ratio: request.ratio
|
|
1056
|
+
})
|
|
1057
|
+
);
|
|
1058
|
+
return readPane(result.pane);
|
|
1059
|
+
},
|
|
1060
|
+
async paneRename(paneId, label) {
|
|
1061
|
+
await call("pane.rename", { pane_id: paneId, label });
|
|
1062
|
+
},
|
|
1063
|
+
async paneClose(paneId) {
|
|
1064
|
+
await call("pane.close", { pane_id: paneId });
|
|
1065
|
+
},
|
|
1066
|
+
async paneLayout(paneId) {
|
|
1067
|
+
const result = await callObject("pane.layout", params({ pane_id: paneId }));
|
|
1068
|
+
const layout = asRecord(result.layout);
|
|
1069
|
+
if (!layout) throw new MuxError("protocol", "mux pane.layout returned no layout");
|
|
1070
|
+
const ids = [];
|
|
1071
|
+
for (const entry of readArray(layout, "panes")) {
|
|
1072
|
+
const pane = asRecord(entry);
|
|
1073
|
+
const id = pane ? pane.pane_id : void 0;
|
|
1074
|
+
if (typeof id === "string") ids.push(id);
|
|
1075
|
+
}
|
|
1076
|
+
return ids;
|
|
1077
|
+
},
|
|
1078
|
+
async worktreeList(request = {}) {
|
|
1079
|
+
const result = await callObject("worktree.list", params({ workspace_id: request.workspaceId, cwd: request.cwd }));
|
|
1080
|
+
return { source: readWorktreeSource(result.source), worktrees: readArray(result, "worktrees").map(readWorktree) };
|
|
1081
|
+
},
|
|
1082
|
+
async worktreeCreate(request) {
|
|
1083
|
+
const result = await callObject(
|
|
1084
|
+
"worktree.create",
|
|
1085
|
+
params({
|
|
1086
|
+
workspace_id: request.workspaceId,
|
|
1087
|
+
cwd: request.cwd,
|
|
1088
|
+
branch: request.branch,
|
|
1089
|
+
base: request.base,
|
|
1090
|
+
path: request.path,
|
|
1091
|
+
label: request.label,
|
|
1092
|
+
focus: request.focus ?? false
|
|
1093
|
+
})
|
|
1094
|
+
);
|
|
1095
|
+
const workspace = asRecord(result.workspace);
|
|
1096
|
+
if (!workspace) throw new MuxError("protocol", "mux worktree.create returned no workspace");
|
|
1097
|
+
return {
|
|
1098
|
+
workspaceId: requireString(workspace, "workspace_id", "workspace"),
|
|
1099
|
+
tab: readTab(result.tab),
|
|
1100
|
+
rootPane: readPane(result.root_pane),
|
|
1101
|
+
worktree: readWorktree(result.worktree)
|
|
1102
|
+
};
|
|
1103
|
+
},
|
|
1104
|
+
async worktreeOpen(request) {
|
|
1105
|
+
const result = await callObject(
|
|
1106
|
+
"worktree.open",
|
|
1107
|
+
params({
|
|
1108
|
+
workspace_id: request.workspaceId,
|
|
1109
|
+
cwd: request.cwd,
|
|
1110
|
+
branch: request.branch,
|
|
1111
|
+
path: request.path,
|
|
1112
|
+
label: request.label,
|
|
1113
|
+
focus: request.focus ?? false
|
|
1114
|
+
})
|
|
1115
|
+
);
|
|
1116
|
+
const workspace = asRecord(result.workspace);
|
|
1117
|
+
if (!workspace) throw new MuxError("protocol", "mux worktree.open returned no workspace");
|
|
1118
|
+
return {
|
|
1119
|
+
workspaceId: requireString(workspace, "workspace_id", "workspace"),
|
|
1120
|
+
tab: readTab(result.tab),
|
|
1121
|
+
rootPane: readPane(result.root_pane),
|
|
1122
|
+
worktree: readWorktree(result.worktree),
|
|
1123
|
+
alreadyOpen: result.already_open === true
|
|
1124
|
+
};
|
|
1125
|
+
},
|
|
1126
|
+
async worktreeRemove(workspaceId, removeOptions = {}) {
|
|
1127
|
+
const result = await callObject("worktree.remove", {
|
|
1128
|
+
workspace_id: workspaceId,
|
|
1129
|
+
force: removeOptions.force ?? false
|
|
1130
|
+
});
|
|
1131
|
+
return {
|
|
1132
|
+
workspaceId: requireString(result, "workspace_id", "worktree.remove"),
|
|
1133
|
+
path: requireString(result, "path", "worktree.remove"),
|
|
1134
|
+
forced: result.forced === true
|
|
1135
|
+
};
|
|
1136
|
+
},
|
|
1137
|
+
async paneSendText(paneId, text) {
|
|
1138
|
+
await call("pane.send_text", { pane_id: paneId, text });
|
|
1139
|
+
},
|
|
1140
|
+
async paneReportAgent(request) {
|
|
1141
|
+
await call(
|
|
1142
|
+
"pane.report_agent",
|
|
1143
|
+
params({
|
|
1144
|
+
pane_id: request.paneId,
|
|
1145
|
+
source: request.source,
|
|
1146
|
+
agent: request.agent,
|
|
1147
|
+
state: request.state,
|
|
1148
|
+
message: request.message
|
|
1149
|
+
})
|
|
1150
|
+
);
|
|
1151
|
+
},
|
|
1152
|
+
async paneReportMetadata(request) {
|
|
1153
|
+
await call(
|
|
1154
|
+
"pane.report_metadata",
|
|
1155
|
+
params({
|
|
1156
|
+
pane_id: request.paneId,
|
|
1157
|
+
source: request.source,
|
|
1158
|
+
agent: request.agent,
|
|
1159
|
+
title: request.title,
|
|
1160
|
+
display_agent: request.displayAgent,
|
|
1161
|
+
tokens: request.tokens,
|
|
1162
|
+
state_labels: request.stateLabels,
|
|
1163
|
+
ttl_ms: request.ttlMs
|
|
1164
|
+
})
|
|
1165
|
+
);
|
|
1166
|
+
},
|
|
1167
|
+
async notificationShow(request) {
|
|
1168
|
+
const result = await callObject(
|
|
1169
|
+
"notification.show",
|
|
1170
|
+
params({ title: request.title, body: request.body, sound: request.sound })
|
|
1171
|
+
);
|
|
1172
|
+
return {
|
|
1173
|
+
shown: result.shown === true,
|
|
1174
|
+
reason: optionalString(result, "reason") ?? (result.shown === true ? "shown" : "unknown")
|
|
1175
|
+
};
|
|
1176
|
+
},
|
|
1177
|
+
subscribe,
|
|
1178
|
+
async close() {
|
|
1179
|
+
disposed = true;
|
|
1180
|
+
reachable = false;
|
|
1181
|
+
}
|
|
1182
|
+
};
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
// src/domains/mux/detect.ts
|
|
1186
|
+
var PING_TIMEOUT_MS = 1e3;
|
|
1187
|
+
function herdrConfigDir(env) {
|
|
1188
|
+
const xdg = env.XDG_CONFIG_HOME;
|
|
1189
|
+
if (typeof xdg === "string" && xdg.length > 0) return join2(xdg, "herdr");
|
|
1190
|
+
const home = typeof env.HOME === "string" && env.HOME.length > 0 ? env.HOME : homedir2();
|
|
1191
|
+
return join2(home, ".config", "herdr");
|
|
1192
|
+
}
|
|
1193
|
+
function resolveSocketCandidates(env) {
|
|
1194
|
+
const candidates = [];
|
|
1195
|
+
const explicit = env.HERDR_SOCKET_PATH;
|
|
1196
|
+
if (typeof explicit === "string" && explicit.length > 0) candidates.push(explicit);
|
|
1197
|
+
const configDir = herdrConfigDir(env);
|
|
1198
|
+
const session = env.HERDR_SESSION;
|
|
1199
|
+
if (typeof session === "string" && session.length > 0) {
|
|
1200
|
+
candidates.push(join2(configDir, "sessions", session, "herdr.sock"));
|
|
1201
|
+
}
|
|
1202
|
+
candidates.push(join2(configDir, "herdr.sock"));
|
|
1203
|
+
return [...new Set(candidates)];
|
|
1204
|
+
}
|
|
1205
|
+
function readSelfLocation(env) {
|
|
1206
|
+
const read = (key) => {
|
|
1207
|
+
const value = env[key];
|
|
1208
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1209
|
+
};
|
|
1210
|
+
return {
|
|
1211
|
+
workspaceId: read("HERDR_WORKSPACE_ID"),
|
|
1212
|
+
tabId: read("HERDR_TAB_ID"),
|
|
1213
|
+
paneId: read("HERDR_PANE_ID")
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
function none(reason, candidates = []) {
|
|
1217
|
+
return {
|
|
1218
|
+
mode: "none",
|
|
1219
|
+
socketPath: null,
|
|
1220
|
+
server: null,
|
|
1221
|
+
self: { workspaceId: null, tabId: null, paneId: null },
|
|
1222
|
+
candidates,
|
|
1223
|
+
reason
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
async function detectMux(options = {}) {
|
|
1227
|
+
const env = options.env ?? process.env;
|
|
1228
|
+
const enabled = options.enabled ?? "auto";
|
|
1229
|
+
const log = options.log ?? (() => void 0);
|
|
1230
|
+
if (enabled === "off") {
|
|
1231
|
+
return { detection: none("panes are turned off"), client: null };
|
|
1232
|
+
}
|
|
1233
|
+
if (enabled === "embedded") {
|
|
1234
|
+
return { detection: none("embedded mode is not implemented yet; it ships in phase 5"), client: null };
|
|
1235
|
+
}
|
|
1236
|
+
if (env.HERDR_ENV !== "1") {
|
|
1237
|
+
return { detection: none("HERDR_ENV is not 1, so Clio is not running inside a pane host"), client: null };
|
|
1238
|
+
}
|
|
1239
|
+
const candidates = resolveSocketCandidates(env);
|
|
1240
|
+
const openClient = options.openClient ?? ((socketPath) => createMuxClient({ socketPath, log }));
|
|
1241
|
+
const pingTimeoutMs = options.pingTimeoutMs ?? PING_TIMEOUT_MS;
|
|
1242
|
+
for (const socketPath of candidates) {
|
|
1243
|
+
const client = openClient(socketPath);
|
|
1244
|
+
try {
|
|
1245
|
+
const server = await client.ping({ timeoutMs: pingTimeoutMs });
|
|
1246
|
+
return {
|
|
1247
|
+
detection: {
|
|
1248
|
+
mode: "guest",
|
|
1249
|
+
socketPath,
|
|
1250
|
+
server,
|
|
1251
|
+
self: readSelfLocation(env),
|
|
1252
|
+
candidates,
|
|
1253
|
+
reason: `guest mode on ${socketPath} (herdr ${server.version}, protocol ${server.protocol})`
|
|
1254
|
+
},
|
|
1255
|
+
client
|
|
1256
|
+
};
|
|
1257
|
+
} catch (error) {
|
|
1258
|
+
log("debug", `mux ping ${socketPath} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1259
|
+
await client.close().catch(() => void 0);
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
return {
|
|
1263
|
+
detection: none(
|
|
1264
|
+
candidates.length > 0 ? `no herdr socket answered a ping: tried ${candidates.join(", ")}` : "no herdr socket candidates resolved",
|
|
1265
|
+
candidates
|
|
1266
|
+
),
|
|
1267
|
+
client: null
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
// src/domains/mux/extension.ts
|
|
1272
|
+
async function createMuxBundle(_context, options = {}) {
|
|
1273
|
+
const log = options.log ?? (() => void 0);
|
|
1274
|
+
const { detection, client } = await detectMux({
|
|
1275
|
+
...options.enabled ? { enabled: options.enabled } : {},
|
|
1276
|
+
...options.env ? { env: options.env } : {},
|
|
1277
|
+
log
|
|
1278
|
+
});
|
|
1279
|
+
log(detection.mode === "none" ? "debug" : "info", `mux mode ${detection.mode}: ${detection.reason}`);
|
|
1280
|
+
const runtime = createMuxRuntime({ detection, client, log });
|
|
1281
|
+
const extension = {
|
|
1282
|
+
async start() {
|
|
1283
|
+
await runtime.start();
|
|
1284
|
+
},
|
|
1285
|
+
async stop() {
|
|
1286
|
+
await runtime.stop();
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
return { extension, contract: runtime.contract };
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
// src/domains/mux/manifest.ts
|
|
1293
|
+
init_esm_shims();
|
|
1294
|
+
var MuxManifest = {
|
|
1295
|
+
name: "mux",
|
|
1296
|
+
dependsOn: []
|
|
1297
|
+
};
|
|
1298
|
+
|
|
1299
|
+
// src/domains/mux/viewer-command.ts
|
|
1300
|
+
init_esm_shims();
|
|
1301
|
+
import { join as join3 } from "node:path";
|
|
1302
|
+
function clioCliEntryPath() {
|
|
1303
|
+
return join3(resolvePackageRoot(), "dist/cli/index.js");
|
|
1304
|
+
}
|
|
1305
|
+
function watchViewerCommand(selectionPath, options = {}) {
|
|
1306
|
+
const layout = options.dirs === void 0 ? [] : [
|
|
1307
|
+
"--config-dir",
|
|
1308
|
+
options.dirs.config,
|
|
1309
|
+
"--data-dir",
|
|
1310
|
+
options.dirs.data,
|
|
1311
|
+
"--state-dir",
|
|
1312
|
+
options.dirs.state,
|
|
1313
|
+
"--cache-dir",
|
|
1314
|
+
options.dirs.cache
|
|
1315
|
+
];
|
|
1316
|
+
return [
|
|
1317
|
+
options.execPath ?? process.execPath,
|
|
1318
|
+
options.entryPath ?? clioCliEntryPath(),
|
|
1319
|
+
"fleet",
|
|
1320
|
+
"view",
|
|
1321
|
+
...layout,
|
|
1322
|
+
"--watch",
|
|
1323
|
+
selectionPath
|
|
1324
|
+
];
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
// src/domains/mux/yazi/event-stream.ts
|
|
1328
|
+
init_esm_shims();
|
|
1329
|
+
import { closeSync, openSync, readSync, statSync as statSync2 } from "node:fs";
|
|
1330
|
+
import { StringDecoder } from "node:string_decoder";
|
|
1331
|
+
var YAZI_STREAM_POLL_MS = 250;
|
|
1332
|
+
var YAZI_STREAM_MAX_BYTES = 1024 * 1024;
|
|
1333
|
+
function record(value) {
|
|
1334
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1335
|
+
}
|
|
1336
|
+
function parseYaziEventLine(line) {
|
|
1337
|
+
const first = line.indexOf(",");
|
|
1338
|
+
const second = first < 0 ? -1 : line.indexOf(",", first + 1);
|
|
1339
|
+
const third = second < 0 ? -1 : line.indexOf(",", second + 1);
|
|
1340
|
+
if (first <= 0 || second <= first + 1 || third <= second + 1) return null;
|
|
1341
|
+
const kind = line.slice(0, first);
|
|
1342
|
+
if (kind !== "cd" && kind !== "clio-pick") return null;
|
|
1343
|
+
const receiver = line.slice(first + 1, second);
|
|
1344
|
+
const sender = line.slice(second + 1, third);
|
|
1345
|
+
try {
|
|
1346
|
+
const body = JSON.parse(line.slice(third + 1));
|
|
1347
|
+
if (kind === "cd") {
|
|
1348
|
+
if (!record(body) || typeof body.url !== "string") return null;
|
|
1349
|
+
const tab = body.tab;
|
|
1350
|
+
if (typeof tab !== "number" && typeof tab !== "string") return null;
|
|
1351
|
+
return { kind, receiver, sender, tab: String(tab), cwd: body.url };
|
|
1352
|
+
}
|
|
1353
|
+
if (!Array.isArray(body) || !body.every((value) => typeof value === "string")) return null;
|
|
1354
|
+
return { kind, receiver, sender, values: body };
|
|
1355
|
+
} catch {
|
|
1356
|
+
return null;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
function createYaziEventStream(options) {
|
|
1360
|
+
const log = options.log ?? (() => void 0);
|
|
1361
|
+
const now = options.now ?? Date.now;
|
|
1362
|
+
const maxBytes = options.maxBytes ?? YAZI_STREAM_MAX_BYTES;
|
|
1363
|
+
let offset = 0;
|
|
1364
|
+
let carry = "";
|
|
1365
|
+
let decoder = new StringDecoder("utf8");
|
|
1366
|
+
let stopped = false;
|
|
1367
|
+
let polling = false;
|
|
1368
|
+
let interval = null;
|
|
1369
|
+
let settleDone = () => {
|
|
1370
|
+
};
|
|
1371
|
+
const done = new Promise((resolve) => {
|
|
1372
|
+
settleDone = resolve;
|
|
1373
|
+
});
|
|
1374
|
+
const state = {
|
|
1375
|
+
bytesRead: 0,
|
|
1376
|
+
linesRead: 0,
|
|
1377
|
+
malformedLines: 0,
|
|
1378
|
+
lastLineAt: null,
|
|
1379
|
+
stopReason: null
|
|
1380
|
+
};
|
|
1381
|
+
const stop = (reason = "stopped") => {
|
|
1382
|
+
if (stopped) return;
|
|
1383
|
+
stopped = true;
|
|
1384
|
+
state.stopReason = reason;
|
|
1385
|
+
if (interval) clearInterval(interval);
|
|
1386
|
+
interval = null;
|
|
1387
|
+
log(reason === "size-cap" ? "warning" : "debug", `yazi event stream stopped (${reason}): ${options.path}`);
|
|
1388
|
+
settleDone(reason);
|
|
1389
|
+
};
|
|
1390
|
+
const poll = async () => {
|
|
1391
|
+
if (stopped || polling) return;
|
|
1392
|
+
polling = true;
|
|
1393
|
+
try {
|
|
1394
|
+
if (!await options.isAlive()) {
|
|
1395
|
+
stop("pane-gone");
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
const stat = statSync2(options.path, { throwIfNoEntry: false });
|
|
1399
|
+
if (!stat?.isFile()) {
|
|
1400
|
+
stop("file-missing");
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
if (stat.size > maxBytes) {
|
|
1404
|
+
stop("size-cap");
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
if (stat.size < offset) {
|
|
1408
|
+
offset = 0;
|
|
1409
|
+
carry = "";
|
|
1410
|
+
decoder = new StringDecoder("utf8");
|
|
1411
|
+
}
|
|
1412
|
+
const remaining = stat.size - offset;
|
|
1413
|
+
if (remaining <= 0) return;
|
|
1414
|
+
const bytes = Buffer.allocUnsafe(remaining);
|
|
1415
|
+
const fd = openSync(options.path, "r");
|
|
1416
|
+
let read = 0;
|
|
1417
|
+
try {
|
|
1418
|
+
read = readSync(fd, bytes, 0, remaining, offset);
|
|
1419
|
+
} finally {
|
|
1420
|
+
closeSync(fd);
|
|
1421
|
+
}
|
|
1422
|
+
offset += read;
|
|
1423
|
+
state.bytesRead += read;
|
|
1424
|
+
const complete = `${carry}${decoder.write(bytes.subarray(0, read))}`.split("\n");
|
|
1425
|
+
carry = complete.pop() ?? "";
|
|
1426
|
+
for (const raw of complete) {
|
|
1427
|
+
const line = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
|
|
1428
|
+
if (line.length === 0) continue;
|
|
1429
|
+
const kind = line.slice(0, line.indexOf(","));
|
|
1430
|
+
if (kind !== "cd" && kind !== "clio-pick") continue;
|
|
1431
|
+
const event = parseYaziEventLine(line);
|
|
1432
|
+
if (!event) {
|
|
1433
|
+
state.malformedLines += 1;
|
|
1434
|
+
continue;
|
|
1435
|
+
}
|
|
1436
|
+
state.linesRead += 1;
|
|
1437
|
+
state.lastLineAt = now();
|
|
1438
|
+
try {
|
|
1439
|
+
options.onEvent(event);
|
|
1440
|
+
} catch (error) {
|
|
1441
|
+
log("warning", `yazi event consumer failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
} finally {
|
|
1445
|
+
polling = false;
|
|
1446
|
+
}
|
|
1447
|
+
};
|
|
1448
|
+
if (options.autoStart !== false) {
|
|
1449
|
+
interval = setInterval(() => void poll(), options.pollMs ?? YAZI_STREAM_POLL_MS);
|
|
1450
|
+
interval.unref();
|
|
1451
|
+
void poll();
|
|
1452
|
+
}
|
|
1453
|
+
return { poll, stop, stats: () => ({ ...state }), done };
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// src/domains/mux/yazi/session.ts
|
|
1457
|
+
init_esm_shims();
|
|
1458
|
+
import { spawn } from "node:child_process";
|
|
1459
|
+
import { randomUUID } from "node:crypto";
|
|
1460
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1461
|
+
import { join as join4 } from "node:path";
|
|
1462
|
+
function resolveYaziBinaries() {
|
|
1463
|
+
const entry = findPinnedTool("yazi");
|
|
1464
|
+
const status = entry ? toolStatus(entry) : null;
|
|
1465
|
+
return {
|
|
1466
|
+
yaziPath: status?.resolution.binaryPath ?? null,
|
|
1467
|
+
yaPath: resolveToolBinary("ya").binaryPath,
|
|
1468
|
+
missingYaziDetail: status ? describeResolution(status) : "yazi is not in the pinned tool registry"
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
function runYa(file, args, env) {
|
|
1472
|
+
return new Promise((resolve) => {
|
|
1473
|
+
const child = spawn(file, args, { env: { ...env }, stdio: "ignore" });
|
|
1474
|
+
child.once("error", () => resolve(false));
|
|
1475
|
+
child.once("exit", (code) => resolve(code === 0));
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
function readOptional(path) {
|
|
1479
|
+
try {
|
|
1480
|
+
return readFileSync2(path, "utf8");
|
|
1481
|
+
} catch {
|
|
1482
|
+
return "";
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
async function createYaziSession(options) {
|
|
1486
|
+
const binaries = (options.resolveBinaries ?? resolveYaziBinaries)();
|
|
1487
|
+
if (!binaries.yaziPath) {
|
|
1488
|
+
return { status: "missing-binary", binary: "yazi", detail: binaries.missingYaziDetail };
|
|
1489
|
+
}
|
|
1490
|
+
if (options.profileMode === "managed" && !binaries.yaPath) {
|
|
1491
|
+
return {
|
|
1492
|
+
status: "missing-binary",
|
|
1493
|
+
binary: "ya",
|
|
1494
|
+
detail: "the Yazi helper `ya` is not available; install the complete pinned Yazi tool"
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
const cacheDir = options.cacheDir ?? clioCacheDir();
|
|
1498
|
+
const sessionId = options.sessionId ?? randomUUID();
|
|
1499
|
+
const sessionsDir = join4(cacheDir, "yazi", "sessions");
|
|
1500
|
+
mkdirSync2(sessionsDir, { recursive: true });
|
|
1501
|
+
const managedProfile = options.profileMode === "managed" ? (options.ensureProfile ?? ensureYaziProfile)({
|
|
1502
|
+
yaPath: binaries.yaPath,
|
|
1503
|
+
yaziPath: binaries.yaziPath,
|
|
1504
|
+
profileDir: yaziProfileDir(cacheDir)
|
|
1505
|
+
}) : null;
|
|
1506
|
+
if (options.profileMode === "managed" && !managedProfile) {
|
|
1507
|
+
return { status: "profile-error", reason: "Clio could not generate a valid managed Yazi profile" };
|
|
1508
|
+
}
|
|
1509
|
+
const streamPath = join4(sessionsDir, `${sessionId}.stream`);
|
|
1510
|
+
const chooserPath = join4(sessionsDir, `${sessionId}.chooser`);
|
|
1511
|
+
const cwdPath = join4(sessionsDir, `${sessionId}.cwd`);
|
|
1512
|
+
const token2 = options.mode === "companion" ? options.pickToken ?? randomUUID() : null;
|
|
1513
|
+
const env = {
|
|
1514
|
+
...managedProfile ? { YAZI_CONFIG_HOME: managedProfile.dir } : {},
|
|
1515
|
+
...token2 ? { CLIO_YAZI_PICK_TOKEN: token2 } : {}
|
|
1516
|
+
};
|
|
1517
|
+
let argv;
|
|
1518
|
+
let stdoutPath;
|
|
1519
|
+
if (options.mode === "companion") {
|
|
1520
|
+
writeFileSync2(streamPath, "");
|
|
1521
|
+
argv = [binaries.yaziPath, "--local-events", "cd,clio-pick", "--remote-events", "clio-pick"];
|
|
1522
|
+
stdoutPath = streamPath;
|
|
1523
|
+
} else {
|
|
1524
|
+
writeFileSync2(chooserPath, "");
|
|
1525
|
+
writeFileSync2(cwdPath, "");
|
|
1526
|
+
argv = [binaries.yaziPath, options.cwd, "--chooser-file", chooserPath, "--cwd-file", cwdPath];
|
|
1527
|
+
}
|
|
1528
|
+
const pane = await options.mux.openUtilityPane({
|
|
1529
|
+
argv,
|
|
1530
|
+
cwd: options.cwd,
|
|
1531
|
+
label: "yazi",
|
|
1532
|
+
...Object.keys(env).length > 0 ? { env } : {},
|
|
1533
|
+
...stdoutPath ? { stdoutPath } : {}
|
|
1534
|
+
});
|
|
1535
|
+
if (!pane) return { status: "unavailable", reason: "pane host refused to open yazi" };
|
|
1536
|
+
let paneCwd = options.cwd;
|
|
1537
|
+
let instanceId = null;
|
|
1538
|
+
let stream = null;
|
|
1539
|
+
let chooserTimer = null;
|
|
1540
|
+
let stopped = false;
|
|
1541
|
+
const alive = () => options.mux.list().some((record2) => record2.ref.paneId === pane.paneId);
|
|
1542
|
+
const stop = (reason) => {
|
|
1543
|
+
if (stopped) return;
|
|
1544
|
+
stopped = true;
|
|
1545
|
+
if (chooserTimer) clearInterval(chooserTimer);
|
|
1546
|
+
chooserTimer = null;
|
|
1547
|
+
options.onStopped?.(reason);
|
|
1548
|
+
};
|
|
1549
|
+
if (options.mode === "companion") {
|
|
1550
|
+
stream = createYaziEventStream({
|
|
1551
|
+
path: streamPath,
|
|
1552
|
+
isAlive: alive,
|
|
1553
|
+
...options.pollMs !== void 0 ? { pollMs: options.pollMs } : {},
|
|
1554
|
+
...options.log ? { log: options.log } : {},
|
|
1555
|
+
onEvent: (event) => {
|
|
1556
|
+
if (event.kind === "cd") {
|
|
1557
|
+
paneCwd = event.cwd;
|
|
1558
|
+
instanceId = event.sender;
|
|
1559
|
+
}
|
|
1560
|
+
options.onEvent(event);
|
|
1561
|
+
}
|
|
1562
|
+
});
|
|
1563
|
+
void stream.done.then((reason) => stop(reason));
|
|
1564
|
+
} else {
|
|
1565
|
+
const pollChooser = () => {
|
|
1566
|
+
if (stopped || alive()) return;
|
|
1567
|
+
const raw = readOptional(chooserPath);
|
|
1568
|
+
const cwd = readOptional(cwdPath).trim() || paneCwd;
|
|
1569
|
+
paneCwd = cwd;
|
|
1570
|
+
const paths = raw.length === 0 ? [] : raw.split("\n").filter((path) => path.length > 0);
|
|
1571
|
+
options.onChooser({ paths, cwd });
|
|
1572
|
+
stop("pane-gone");
|
|
1573
|
+
};
|
|
1574
|
+
chooserTimer = setInterval(pollChooser, options.pollMs ?? YAZI_STREAM_POLL_MS);
|
|
1575
|
+
chooserTimer.unref();
|
|
1576
|
+
}
|
|
1577
|
+
const session = {
|
|
1578
|
+
mode: options.mode,
|
|
1579
|
+
pane,
|
|
1580
|
+
token: token2,
|
|
1581
|
+
profile: managedProfile,
|
|
1582
|
+
snapshot: () => ({
|
|
1583
|
+
mode: options.mode,
|
|
1584
|
+
paneId: pane.paneId,
|
|
1585
|
+
paneCwd,
|
|
1586
|
+
instanceId,
|
|
1587
|
+
lastLineAt: stream?.stats().lastLineAt ?? null,
|
|
1588
|
+
streamPath: options.mode === "companion" ? streamPath : null,
|
|
1589
|
+
chooserPath: options.mode === "chooser" ? chooserPath : null
|
|
1590
|
+
}),
|
|
1591
|
+
async pushCwd(cwd) {
|
|
1592
|
+
if (!instanceId || !binaries.yaPath) return false;
|
|
1593
|
+
const pushed = await (options.runYa ?? runYa)(binaries.yaPath, ["emit-to", instanceId, "cd", cwd], {
|
|
1594
|
+
...process.env,
|
|
1595
|
+
...managedProfile ? { YAZI_CONFIG_HOME: managedProfile.dir } : {}
|
|
1596
|
+
});
|
|
1597
|
+
return pushed;
|
|
1598
|
+
},
|
|
1599
|
+
async close() {
|
|
1600
|
+
stream?.stop();
|
|
1601
|
+
stop("stopped");
|
|
1602
|
+
await options.mux.closePane(pane.paneId);
|
|
1603
|
+
}
|
|
1604
|
+
};
|
|
1605
|
+
return { status: "opened", session };
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
// src/domains/mux/index.ts
|
|
1609
|
+
function createMuxDomainModule(options) {
|
|
1610
|
+
return {
|
|
1611
|
+
manifest: MuxManifest,
|
|
1612
|
+
createExtension: (context) => createMuxBundle(context, options)
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
export {
|
|
1617
|
+
MUX_METHOD_MIN_PROTOCOL,
|
|
1618
|
+
resolveSocketCandidates,
|
|
1619
|
+
detectMux,
|
|
1620
|
+
watchViewerCommand,
|
|
1621
|
+
yaziProfileDir,
|
|
1622
|
+
userYaziConfigDir,
|
|
1623
|
+
resetYaziProfile,
|
|
1624
|
+
inspectCurrentYaziProfile,
|
|
1625
|
+
describeYaziProfile,
|
|
1626
|
+
ensureYaziProfile,
|
|
1627
|
+
resolveYaziBinaries,
|
|
1628
|
+
createYaziSession,
|
|
1629
|
+
createMuxDomainModule
|
|
1630
|
+
};
|
|
1631
|
+
//# sourceMappingURL=chunk-HZHHCK24.js.map
|