@skaile/workspaces 5.8.0 → 5.10.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/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-EYRZR4K5.js → asset-feeds-ELEBTNUS.js} +18 -18
- package/dist/{asset-feeds-EYRZR4K5.js.map → asset-feeds-ELEBTNUS.js.map} +1 -1
- package/dist/asset-manager/catalog-deployer.js +8 -8
- package/dist/asset-manager/index.js +14 -14
- package/dist/asset-manager/installer.js +10 -10
- package/dist/asset-manager/renderers.js +9 -9
- package/dist/asset-manager/src/index.d.ts +300 -36
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/install-agent.d.ts +3 -1
- package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
- package/dist/asset-manager/src/install-instances.d.ts +31 -1
- package/dist/asset-manager/src/install-instances.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +20 -0
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/asset-manager/src/renderers.d.ts +4 -5
- package/dist/asset-manager/src/renderers.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +170 -17
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +13 -11
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +10 -10
- package/dist/bridge/drivers/echo.js +4 -4
- package/dist/bridge/drivers/gemini.js +7 -7
- package/dist/bridge/drivers/goose.js +10 -10
- package/dist/bridge/drivers/omp.js +7 -5
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +10 -10
- package/dist/bridge/drivers/qwen.js +7 -7
- package/dist/bridge/index.js +14 -14
- package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts +31 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts +43 -0
- package/dist/bridge/src/drivers/claude-tool-allowlist.d.ts.map +1 -0
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/types.d.ts +20 -1
- package/dist/bridge/src/types.d.ts.map +1 -1
- package/dist/{chunk-36AFURKZ.js → chunk-2FMEGSBN.js} +38 -11
- package/dist/chunk-2FMEGSBN.js.map +1 -0
- package/dist/{chunk-GCICGXDD.js → chunk-2H73V6XR.js} +3 -3
- package/dist/{chunk-GCICGXDD.js.map → chunk-2H73V6XR.js.map} +1 -1
- package/dist/{chunk-H7QUDDKH.js → chunk-2JMLDZLP.js} +1069 -182
- package/dist/chunk-2JMLDZLP.js.map +1 -0
- package/dist/{chunk-B6GIW55K.js → chunk-32XKCNCL.js} +6 -3
- package/dist/chunk-32XKCNCL.js.map +1 -0
- package/dist/{chunk-4MQS7CAF.js → chunk-3BEY4WK3.js} +371 -175
- package/dist/chunk-3BEY4WK3.js.map +1 -0
- package/dist/{chunk-SH5D7U7N.js → chunk-3KHYGOEY.js} +3 -3
- package/dist/{chunk-SH5D7U7N.js.map → chunk-3KHYGOEY.js.map} +1 -1
- package/dist/{chunk-CGT45WN7.js → chunk-3MKPZZRE.js} +3 -3
- package/dist/{chunk-CGT45WN7.js.map → chunk-3MKPZZRE.js.map} +1 -1
- package/dist/{chunk-QVNRCDTV.js → chunk-4OV5DSBB.js} +4 -4
- package/dist/chunk-4OV5DSBB.js.map +1 -0
- package/dist/{chunk-GXXFLBUQ.js → chunk-4P3KTUZH.js} +33 -33
- package/dist/chunk-4P3KTUZH.js.map +1 -0
- package/dist/{chunk-I6NLLJHZ.js → chunk-5QI2JYJC.js} +2 -2
- package/dist/{chunk-I6NLLJHZ.js.map → chunk-5QI2JYJC.js.map} +1 -1
- package/dist/{chunk-EF7NPDDU.js → chunk-6HHE63CO.js} +31 -17
- package/dist/chunk-6HHE63CO.js.map +1 -0
- package/dist/{chunk-FTJJO3EM.js → chunk-7CR6HT2X.js} +10 -10
- package/dist/{chunk-FTJJO3EM.js.map → chunk-7CR6HT2X.js.map} +1 -1
- package/dist/{chunk-FZNG4V4J.js → chunk-7I5VRVDP.js} +3 -3
- package/dist/{chunk-FZNG4V4J.js.map → chunk-7I5VRVDP.js.map} +1 -1
- package/dist/{chunk-HG34RNTK.js → chunk-CLTHEKHR.js} +10 -9
- package/dist/chunk-CLTHEKHR.js.map +1 -0
- package/dist/{chunk-UMVKJM4Q.js → chunk-DALV4HHP.js} +18 -3
- package/dist/chunk-DALV4HHP.js.map +1 -0
- package/dist/{chunk-F3RDEH5U.js → chunk-F4NJDSR7.js} +6 -5
- package/dist/chunk-F4NJDSR7.js.map +1 -0
- package/dist/{chunk-LSXHED6I.js → chunk-FRPBSUFH.js} +6 -6
- package/dist/{chunk-LSXHED6I.js.map → chunk-FRPBSUFH.js.map} +1 -1
- package/dist/{chunk-W5DWWE4Y.js → chunk-G54USEUP.js} +4 -4
- package/dist/{chunk-W5DWWE4Y.js.map → chunk-G54USEUP.js.map} +1 -1
- package/dist/{chunk-Y7QA2OLD.js → chunk-GEWAIQZ5.js} +24 -20
- package/dist/chunk-GEWAIQZ5.js.map +1 -0
- package/dist/{chunk-GB7WDMH2.js → chunk-GFCXNFTW.js} +4 -4
- package/dist/{chunk-GB7WDMH2.js.map → chunk-GFCXNFTW.js.map} +1 -1
- package/dist/{chunk-AWQYXZVG.js → chunk-HJ5MCB3L.js} +28 -4
- package/dist/chunk-HJ5MCB3L.js.map +1 -0
- package/dist/{chunk-2LWYNQK7.js → chunk-HOHUEKES.js} +3 -3
- package/dist/{chunk-2LWYNQK7.js.map → chunk-HOHUEKES.js.map} +1 -1
- package/dist/{chunk-ZKSJMZKD.js → chunk-IJHH4DSW.js} +8 -8
- package/dist/{chunk-ZKSJMZKD.js.map → chunk-IJHH4DSW.js.map} +1 -1
- package/dist/{chunk-BTE2V4IW.js → chunk-IXWODEED.js} +40 -7
- package/dist/chunk-IXWODEED.js.map +1 -0
- package/dist/{chunk-OFBIWVCR.js → chunk-JFXQEVLF.js} +3 -3
- package/dist/{chunk-OFBIWVCR.js.map → chunk-JFXQEVLF.js.map} +1 -1
- package/dist/{chunk-JAKOMFC6.js → chunk-JZCSNEHK.js} +77 -31
- package/dist/chunk-JZCSNEHK.js.map +1 -0
- package/dist/{chunk-CKQEIY43.js → chunk-MVQ3Q2HM.js} +4 -4
- package/dist/{chunk-CKQEIY43.js.map → chunk-MVQ3Q2HM.js.map} +1 -1
- package/dist/{chunk-LEMHVDET.js → chunk-NRDSGLCQ.js} +188 -33
- package/dist/chunk-NRDSGLCQ.js.map +1 -0
- package/dist/{chunk-V2DXZYBB.js → chunk-NWDSLXOX.js} +3 -3
- package/dist/{chunk-V2DXZYBB.js.map → chunk-NWDSLXOX.js.map} +1 -1
- package/dist/{chunk-6GRX5L6A.js → chunk-OBVJ7RPW.js} +4 -4
- package/dist/{chunk-6GRX5L6A.js.map → chunk-OBVJ7RPW.js.map} +1 -1
- package/dist/{chunk-PTSGWKHR.js → chunk-OOWHXOK6.js} +4 -4
- package/dist/{chunk-PTSGWKHR.js.map → chunk-OOWHXOK6.js.map} +1 -1
- package/dist/{chunk-YSHVQGUS.js → chunk-PE36IF2D.js} +119 -30
- package/dist/chunk-PE36IF2D.js.map +1 -0
- package/dist/{chunk-S53LOR7B.js → chunk-QG3HOJEK.js} +3 -3
- package/dist/{chunk-S53LOR7B.js.map → chunk-QG3HOJEK.js.map} +1 -1
- package/dist/{chunk-2FRUUDZY.js → chunk-SBFW3CJH.js} +5 -5
- package/dist/{chunk-2FRUUDZY.js.map → chunk-SBFW3CJH.js.map} +1 -1
- package/dist/{chunk-UAROCOXF.js → chunk-SX5U422E.js} +3 -3
- package/dist/{chunk-UAROCOXF.js.map → chunk-SX5U422E.js.map} +1 -1
- package/dist/{chunk-QOP6KDFR.js → chunk-TH4CTXHX.js} +6 -6
- package/dist/{chunk-QOP6KDFR.js.map → chunk-TH4CTXHX.js.map} +1 -1
- package/dist/{chunk-F2EKONM7.js → chunk-TRSQP3JD.js} +3 -3
- package/dist/{chunk-F2EKONM7.js.map → chunk-TRSQP3JD.js.map} +1 -1
- package/dist/{chunk-FVJK4QWM.js → chunk-V5TZH4GF.js} +4 -4
- package/dist/{chunk-FVJK4QWM.js.map → chunk-V5TZH4GF.js.map} +1 -1
- package/dist/{chunk-HYDRDNKN.js → chunk-V7PQZOBR.js} +5 -5
- package/dist/{chunk-HYDRDNKN.js.map → chunk-V7PQZOBR.js.map} +1 -1
- package/dist/{chunk-IONAUNWB.js → chunk-VLXDXRRX.js} +3 -3
- package/dist/{chunk-IONAUNWB.js.map → chunk-VLXDXRRX.js.map} +1 -1
- package/dist/{chunk-CIFS5K6T.js → chunk-VMKMFS2Q.js} +28 -7
- package/dist/chunk-VMKMFS2Q.js.map +1 -0
- package/dist/{chunk-Y4N2NUZD.js → chunk-WBYDAL6X.js} +4 -4
- package/dist/{chunk-Y4N2NUZD.js.map → chunk-WBYDAL6X.js.map} +1 -1
- package/dist/{chunk-WTQ3TATB.js → chunk-X4BAYGMT.js} +3 -3
- package/dist/{chunk-WTQ3TATB.js.map → chunk-X4BAYGMT.js.map} +1 -1
- package/dist/{chunk-NPLPCRW5.js → chunk-XCNK4UE5.js} +5 -5
- package/dist/{chunk-NPLPCRW5.js.map → chunk-XCNK4UE5.js.map} +1 -1
- package/dist/{chunk-OJ4N4T4H.js → chunk-XDVR7QIT.js} +20 -6
- package/dist/chunk-XDVR7QIT.js.map +1 -0
- package/dist/{chunk-GTILM2CI.js → chunk-Y34MSWEZ.js} +43 -12
- package/dist/chunk-Y34MSWEZ.js.map +1 -0
- package/dist/{chunk-4PTSR4UU.js → chunk-Y63UQZ7P.js} +3 -3
- package/dist/{chunk-4PTSR4UU.js.map → chunk-Y63UQZ7P.js.map} +1 -1
- package/dist/chunk-YBQONMH2.js +465 -0
- package/dist/chunk-YBQONMH2.js.map +1 -0
- package/dist/{chunk-P23M65LB.js → chunk-Z2K6BGUR.js} +71 -24
- package/dist/chunk-Z2K6BGUR.js.map +1 -0
- package/dist/{chunk-BJNUNQAW.js → chunk-ZGQTS3Y4.js} +3 -3
- package/dist/{chunk-BJNUNQAW.js.map → chunk-ZGQTS3Y4.js.map} +1 -1
- package/dist/cli/index.js +913 -720
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +8 -5
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/diff.d.ts +3 -1
- package/dist/cli/src/commands/diff.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-index.d.ts +34 -2
- package/dist/cli/src/commands/library-index.d.ts.map +1 -1
- package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +6 -5
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
- package/dist/cli/src/commands/outdated.d.ts +7 -5
- package/dist/cli/src/commands/outdated.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +11 -8
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +30 -1
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/commands/why.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +47 -2
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/src/client.d.ts +10 -3
- package/dist/client/src/client.d.ts.map +1 -1
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +18 -18
- package/dist/{connectors-O6Y6VESP.js → connectors-OXP2JBGI.js} +21 -21
- package/dist/{connectors-O6Y6VESP.js.map → connectors-OXP2JBGI.js.map} +1 -1
- package/dist/connectors-shared/index.js +2 -2
- package/dist/core/index.js +7 -7
- package/dist/core/logging.js +1 -1
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/publish-manifest.js +2 -2
- package/dist/core/ref.js +1 -1
- package/dist/core/runtime-assets.js +5 -5
- package/dist/core/src/index.d.ts +2 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +5 -2
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/logging/sinks/sqlite-runtime.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +21 -5
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/publish-manifest.d.ts +19 -3
- package/dist/core/src/publish-manifest.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/requirements.d.ts +26 -0
- package/dist/core/src/requirements.d.ts.map +1 -0
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +18 -0
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts +4 -1
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +4 -4
- package/dist/deploy/index.js +7 -7
- package/dist/discovery/index.js +5 -5
- package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
- package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
- package/dist/discovery/src/discover.d.ts.map +1 -1
- package/dist/discovery/src/source-config.d.ts.map +1 -1
- package/dist/discovery/src/tree-entries.d.ts.map +1 -1
- package/dist/{ensure-sources-SKLNM4UZ.js → ensure-sources-5ISVIA4T.js} +17 -17
- package/dist/{ensure-sources-SKLNM4UZ.js.map → ensure-sources-5ISVIA4T.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +18 -18
- package/dist/factory-assets/connectors/deploy.js +18 -18
- package/dist/factory-assets/connectors/devserver.js +18 -18
- package/dist/factory-assets/connectors/flow/adapter.js +18 -18
- package/dist/factory-assets/connectors/flow/engine.js +8 -8
- package/dist/factory-assets/connectors/flow/run-flow.js +20 -20
- package/dist/factory-assets/connectors/flow.js +18 -18
- package/dist/factory-assets/connectors/git.js +18 -18
- package/dist/factory-assets/connectors/gmail.js +18 -18
- package/dist/factory-assets/connectors/googledrive.js +18 -18
- package/dist/factory-assets/connectors/local.js +18 -18
- package/dist/factory-assets/connectors/mattermost.js +18 -18
- package/dist/factory-assets/connectors/memory.js +18 -18
- package/dist/factory-assets/connectors/minio.js +18 -18
- package/dist/factory-assets/connectors/postgres.js +18 -18
- package/dist/factory-assets/connectors/s3.js +18 -18
- package/dist/factory-assets/connectors/sharepoint.js +18 -18
- package/dist/factory-assets/connectors/sqlite.js +18 -18
- package/dist/factory-assets/connectors/static-server.js +18 -18
- package/dist/factory-assets/connectors/tunnel.js +18 -18
- package/dist/factory-assets/connectors/webdav.js +18 -18
- package/dist/factory-assets/connectors/xstate-store.js +18 -18
- package/dist/factory-assets/connectors/xstate.js +18 -18
- package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +9 -3
- package/dist/{flows-CBYRSAGS.js → flows-HMSE76PO.js} +12 -12
- package/dist/{flows-CBYRSAGS.js.map → flows-HMSE76PO.js.map} +1 -1
- package/dist/{helpers-MWZDRBLD.js → helpers-X6URBGSF.js} +17 -17
- package/dist/{helpers-MWZDRBLD.js.map → helpers-X6URBGSF.js.map} +1 -1
- package/dist/library/index.js +11 -11
- package/dist/library/install.js +3 -3
- package/dist/library/src/index.d.ts +2 -1
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/local/library-dir.d.ts +42 -0
- package/dist/library/src/local/library-dir.d.ts.map +1 -0
- package/dist/library/src/local/library-manager.d.ts +10 -1
- package/dist/library/src/local/library-manager.d.ts.map +1 -1
- package/dist/library/src/local/library.d.ts +2 -2
- package/dist/library/src/local/library.d.ts.map +1 -1
- package/dist/library/src/local/local-catalog-source.d.ts +9 -0
- package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
- package/dist/library/src/manifest-writer.d.ts +55 -4
- package/dist/library/src/manifest-writer.d.ts.map +1 -1
- package/dist/library/src/remote/cache.d.ts +18 -1
- package/dist/library/src/remote/cache.d.ts.map +1 -1
- package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
- package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
- package/dist/library/src/sync/git-driver.d.ts +5 -6
- package/dist/library/src/sync/git-driver.d.ts.map +1 -1
- package/dist/{library-publish-PICMDSB2.js → library-publish-OS3JDW4S.js} +123 -41
- package/dist/library-publish-OS3JDW4S.js.map +1 -0
- package/dist/open-library-4QSUORI6.js +40 -0
- package/dist/{open-library-OG457THY.js.map → open-library-4QSUORI6.js.map} +1 -1
- package/dist/open-registry-VCKS3MP5.js +32 -0
- package/dist/{open-registry-ZUZJ7MS7.js.map → open-registry-VCKS3MP5.js.map} +1 -1
- package/dist/paths-BVO56A25.js +22 -0
- package/dist/{paths-FQ64OLJG.js.map → paths-BVO56A25.js.map} +1 -1
- package/dist/{plugin-store-MPAMD5OT.js → plugin-store-X7GPWGBG.js} +9 -9
- package/dist/{plugin-store-MPAMD5OT.js.map → plugin-store-X7GPWGBG.js.map} +1 -1
- package/dist/{project-2GFT5LEZ.js → project-PAXP46RD.js} +20 -20
- package/dist/{project-2GFT5LEZ.js.map → project-PAXP46RD.js.map} +1 -1
- package/dist/resolver/index.js +8 -8
- package/dist/runner/index.js +32 -32
- package/dist/runner/src/agent.d.ts.map +1 -1
- package/dist/runner/src/context-usage/compose.d.ts.map +1 -1
- package/dist/runner/src/platform-blocks.d.ts +55 -0
- package/dist/runner/src/platform-blocks.d.ts.map +1 -0
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +14 -14
- package/dist/sdk/bridge.js +14 -14
- package/dist/sdk/client.js +1 -1
- package/dist/sdk/core.js +7 -7
- package/dist/sdk/flow.js +8 -8
- package/dist/sdk/index.js +33 -33
- package/dist/sdk/resolver.js +8 -8
- package/dist/sdk/runner.js +32 -32
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/types.js +1 -1
- package/dist/session/index.js +2 -2
- package/dist/session/src/dispatcher.d.ts +25 -4
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/session/src/index.d.ts +1 -1
- package/dist/session/src/index.d.ts.map +1 -1
- package/dist/{setup-WHMCSIF2.js → setup-BV55VHWC.js} +24 -24
- package/dist/{setup-WHMCSIF2.js.map → setup-BV55VHWC.js.map} +1 -1
- package/dist/{skills-TVO26Y4V.js → skills-EDFUCJPX.js} +13 -13
- package/dist/{skills-TVO26Y4V.js.map → skills-EDFUCJPX.js.map} +1 -1
- package/dist/source-E4VAT5RZ.js +41 -0
- package/dist/{source-LKOFTOEK.js.map → source-E4VAT5RZ.js.map} +1 -1
- package/dist/{source-manifest-publish-L5J3QXER.js → source-manifest-publish-CLEE6TNH.js} +23 -23
- package/dist/{source-manifest-publish-L5J3QXER.js.map → source-manifest-publish-CLEE6TNH.js.map} +1 -1
- package/dist/tui/index.js +32 -32
- package/dist/types/index.js +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/events.d.ts +1 -1
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/manifests/agent.d.ts +2 -0
- package/dist/types/src/manifests/agent.d.ts.map +1 -1
- package/dist/types/src/manifests/contract.d.ts +2 -0
- package/dist/types/src/manifests/contract.d.ts.map +1 -1
- package/dist/types/src/manifests/index.d.ts +3 -3
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/types/src/manifests/prompt.d.ts +2 -0
- package/dist/types/src/manifests/prompt.d.ts.map +1 -1
- package/dist/types/src/protocol.d.ts +43 -1
- package/dist/types/src/protocol.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +17 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +25 -25
- package/dist/workspace-plugin/adapters/omp.js +14 -14
- package/dist/workspace-plugin/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-36AFURKZ.js.map +0 -1
- package/dist/chunk-4MQS7CAF.js.map +0 -1
- package/dist/chunk-AWQYXZVG.js.map +0 -1
- package/dist/chunk-B6GIW55K.js.map +0 -1
- package/dist/chunk-BTE2V4IW.js.map +0 -1
- package/dist/chunk-CIFS5K6T.js.map +0 -1
- package/dist/chunk-EF7NPDDU.js.map +0 -1
- package/dist/chunk-F3RDEH5U.js.map +0 -1
- package/dist/chunk-GTILM2CI.js.map +0 -1
- package/dist/chunk-GXXFLBUQ.js.map +0 -1
- package/dist/chunk-H7QUDDKH.js.map +0 -1
- package/dist/chunk-HG34RNTK.js.map +0 -1
- package/dist/chunk-JAKOMFC6.js.map +0 -1
- package/dist/chunk-LEMHVDET.js.map +0 -1
- package/dist/chunk-OJ4N4T4H.js.map +0 -1
- package/dist/chunk-P23M65LB.js.map +0 -1
- package/dist/chunk-QVNRCDTV.js.map +0 -1
- package/dist/chunk-UMVKJM4Q.js.map +0 -1
- package/dist/chunk-Y7QA2OLD.js.map +0 -1
- package/dist/chunk-YSHVQGUS.js.map +0 -1
- package/dist/chunk-ZAOGFXDO.js +0 -112
- package/dist/chunk-ZAOGFXDO.js.map +0 -1
- package/dist/library-publish-PICMDSB2.js.map +0 -1
- package/dist/open-library-OG457THY.js +0 -40
- package/dist/open-registry-ZUZJ7MS7.js +0 -32
- package/dist/paths-FQ64OLJG.js +0 -22
- package/dist/source-LKOFTOEK.js +0 -41
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../asset-manager/src/install-agent.ts","../asset-manager/src/installer.ts"],"names":["parseYaml","parseFrontmatter","join","basename","relative","resolve","existsSync","stringifyYaml","deployed"],"mappings":"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","file":"chunk-PE36IF2D.js","sourcesContent":["/**\n * Agent installation — renders a GitAgent package (agent.yaml + SOUL.md + RULES.md)\n * into the framework-native format (`.claude/agents/<name>.md`, `.omp/agents/<name>/`,\n * `.codex/agents/<name>.toml`) and resolves abilities, contracts, fragments, and\n * prompt extensions from the workspace config along the way.\n *\n * System prompt phases (per agent):\n * 1. extends merge — inherit from parent agent.yaml if manifest.extends is set\n * 2. instance overrides — model / budget / lifecycle of the `skaile.yaml` instance\n * 3. ability refs — read SKILL.md frontmatter of the composed skills\n * 4. contract refs — locate CONTRACT.md files of the composed contracts\n * 5. fragments — resolve framework fragments (agent-mode, handoff, etc.)\n * 6. prompt-extensions — load per-project markdown extensions from skaile.yaml\n *\n * Used by `installer.ts` (the asset-install path, one agent asset under its own\n * name) and `install-instances.ts` (`skaile install`, one rendering per\n * `skaile.yaml` agent instance, named by the instance id). Sub-agents composed as\n * `composes: [{ kind: agent }]` (binding `delegate`, the default) are installed\n * flat (no nesting) in the same deploy directory; `binding: run` sub-agents are\n * host-executed and get no native file.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { basename, join, relative, resolve } from \"node:path\";\nimport type { AgentInstanceConfig, DriverTarget, SkWorkspaceConfig } from \"@skaile/workspaces/core\";\nimport {\n AGENT_INSTANCE_ID_PATTERN,\n DRIVER_TARGETS,\n parseFrontmatter as parseMarkdownFrontmatter,\n parseAssetRefLoose,\n resolveAgentDefinitionDir,\n} from \"@skaile/workspaces/core\";\nimport type { AgentComposeItem, AgentLifecycle } from \"@skaile/workspaces/types/manifests\";\nimport { parse as parseYaml } from \"yaml\";\nimport {\n type AbilityRef,\n type ConnectorRef,\n type ContractRef,\n type FragmentContext,\n loadPromptExtensions,\n resolveFragments,\n} from \"./fragments.js\";\nimport { type AgentManifest, type AgentRenderInput, renderAgentToFramework } from \"./renderers.js\";\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/** Source file of the legacy markdown agent form: frontmatter + the system prompt as body. */\nconst AGENT_MD_FILE = \"AGENT.md\";\n\n/** A Claude-style `tools:` value (`\"Read, Grep\"` or a list) as the manifest's `tools.allowed`. */\nfunction toolsFromMarkdown(value: unknown): AgentManifest[\"tools\"] | undefined {\n if (Array.isArray(value)) return { allowed: value.map(String) };\n if (typeof value === \"string\") {\n const allowed = value.split(/[,\\s]+/).filter(Boolean);\n return allowed.length > 0 ? { allowed } : undefined;\n }\n return value && typeof value === \"object\" ? (value as AgentManifest[\"tools\"]) : undefined;\n}\n\n/**\n * The `AGENT.md` form of an agent as a manifest: the frontmatter, with the\n * Claude-style scalar `model:` / `tools:` shapes mapped to the manifest's\n * `model.preferred` / `tools.allowed`, and `metadata.version` read as `version`.\n */\nfunction readAgentMdManifest(agentDir: string): { manifest: AgentManifest; body: string } | null {\n const mdPath = join(agentDir, AGENT_MD_FILE);\n if (!existsSync(mdPath)) return null;\n try {\n const { data, body } = parseMarkdownFrontmatter(readFileSync(mdPath, \"utf-8\"));\n const meta = data.metadata as { version?: unknown } | undefined;\n const manifest: Record<string, unknown> = { ...data };\n if (manifest.version === undefined && meta?.version !== undefined) {\n manifest.version = String(meta.version);\n }\n if (typeof data.model === \"string\") manifest.model = { preferred: data.model };\n if (data.tools !== undefined) manifest.tools = toolsFromMarkdown(data.tools);\n return { manifest: manifest as AgentManifest, body };\n } catch {\n return null;\n }\n}\n\n/**\n * The agent's manifest: `agent.yaml`, else the frontmatter of the legacy\n * `AGENT.md`. `null` when the directory holds neither (or it cannot be parsed).\n */\nexport function readManifest(agentDir: string): AgentManifest | null {\n const yamlPath = join(agentDir, \"agent.yaml\");\n if (!existsSync(yamlPath)) return readAgentMdManifest(agentDir)?.manifest ?? null;\n try {\n return parseYaml(readFileSync(yamlPath, \"utf-8\")) as AgentManifest;\n } catch {\n return null;\n }\n}\n\nfunction readFile(agentDir: string, name: string): string | null {\n const p = join(agentDir, name);\n if (!existsSync(p)) return null;\n try {\n return readFileSync(p, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * The agent's identity text: `SOUL.md`; for an `AGENT.md` agent the markdown body\n * comes first, so a `SOUL.md` next to it extends the prompt rather than replacing it.\n */\nexport function readSoul(agentDir: string): string | null {\n const soul = readFile(agentDir, \"SOUL.md\");\n if (existsSync(join(agentDir, \"agent.yaml\"))) return soul;\n const body = readAgentMdManifest(agentDir)?.body;\n if (!body) return soul;\n return soul ? `${body}\\n\\n${soul}` : body;\n}\n\n/**\n * A name becomes a file or directory name under the deploy dir; one with a path\n * segment (`../x`, `a/b`) would write outside it. Refused, never sanitized.\n */\nfunction isSafeFileName(name: string): boolean {\n return name.length > 0 && name !== \".\" && name !== \"..\" && !/[\\\\/\\0]/.test(name);\n}\n\n/** Extract YAML frontmatter from a markdown file (content between first two --- delimiters). */\nfunction parseFrontmatter(content: string): Record<string, unknown> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n try {\n return (parseYaml(match[1]!) as Record<string, unknown>) ?? {};\n } catch {\n return {};\n }\n}\n\n/**\n * Merge parent and child agent manifests.\n * Scalars: child wins. Arrays: parent + child, deduplicated (`composes` by\n * kind + ref + slot id, other arrays by value).\n */\nfunction mergeManifests(parent: AgentManifest, child: AgentManifest): AgentManifest {\n const result: AgentManifest = { ...parent };\n for (const [k, val] of Object.entries(child) as [keyof AgentManifest, unknown][]) {\n if (val === undefined) continue;\n const parentVal = result[k as keyof AgentManifest];\n if (k === \"composes\" && Array.isArray(val) && Array.isArray(parentVal)) {\n const merged = new Map<string, AgentComposeItem>();\n for (const item of [...parentVal, ...val] as AgentComposeItem[]) {\n merged.set(`${item.kind}\\u0000${item.ref}\\u0000${item.id ?? \"\"}`, item);\n }\n result.composes = [...merged.values()];\n } else if (Array.isArray(val) && Array.isArray(parentVal)) {\n (result as Record<string, unknown>)[k] = [...new Set([...parentVal, ...val])];\n } else {\n (result as Record<string, unknown>)[k] = val;\n }\n }\n return result;\n}\n\n/**\n * Phase 1: inherit scalars/arrays from a parent agent when `manifest.extends` is set.\n * Returns the (possibly merged) manifest; pushes a warning when the parent is missing.\n */\nfunction applyExtendsMerge(\n manifest: AgentManifest,\n srcDir: string,\n warnings: string[],\n): AgentManifest {\n if (!manifest.extends) return manifest;\n const parentDir = resolve(srcDir, manifest.extends);\n const parentManifest = readManifest(parentDir);\n if (parentManifest) {\n return mergeManifests(parentManifest, manifest);\n }\n warnings.push(\n `extends: parent agent not found at \"${manifest.extends}\" (from ${srcDir}) — skipping inheritance`,\n );\n return manifest;\n}\n\n/**\n * Phase 2: apply the instance's overrides to the asset's manifest — the model\n * selector, the turn budget (`budget.max_turns` → `runtime.max_turns`) and the\n * lifecycle. Returns the effective manifest and lifecycle.\n */\nfunction applyInstanceOverrides(\n manifest: AgentManifest,\n instance: AgentInstanceConfig | undefined,\n): { manifest: AgentManifest; lifecycle: AgentLifecycle } {\n const lifecycle = instance?.lifecycle ?? manifest.lifecycle ?? \"standing\";\n if (!instance) return { manifest, lifecycle };\n const effective: AgentManifest = { ...manifest, lifecycle };\n if (instance.model) {\n effective.model = { ...manifest.model, ...instance.model } as AgentManifest[\"model\"];\n }\n if (instance.budget?.max_turns !== undefined) {\n effective.runtime = { ...manifest.runtime, max_turns: instance.budget.max_turns };\n }\n return { manifest: effective, lifecycle };\n}\n\n/**\n * The name a composed asset is installed under: the asset name of a canonical\n * ref (`skill:@pub/name#1.0.0` → `name`), else the last path segment\n * (`./skills/name` → `name`).\n */\nfunction composeRefName(ref: string): string {\n const parsed = parseAssetRefLoose(ref);\n if (parsed) return parsed.name;\n const tail = ref.replace(/\\/+$/, \"\").split(\"/\").pop() ?? ref;\n return tail.replace(/^[a-z-]+:/, \"\").replace(/#.*$/, \"\") || ref;\n}\n\n/** Names of the composed items of `kind`, in declaration order, de-duplicated. */\nfunction composedNames(manifest: AgentManifest, kind: string): string[] {\n const names = (manifest.composes ?? [])\n .filter((item) => item.kind === kind)\n .map((item) => composeRefName(item.ref));\n return [...new Set(names)];\n}\n\n/**\n * The MCP servers an agent's `mcp-server` slots are bound to: the server the\n * instance's `connectors` map binds the slot id to, else the composed asset's\n * own name (the id its server is rendered under).\n */\nfunction boundMcpServers(\n manifest: AgentManifest,\n instance: AgentInstanceConfig | undefined,\n): string[] {\n const names = (manifest.composes ?? [])\n .filter((item) => item.kind === \"mcp-server\")\n .map(\n (item) => (item.id ? instance?.connectors?.[item.id] : undefined) ?? composeRefName(item.ref),\n );\n return [...new Set(names)];\n}\n\n/** Phase 3: resolve ability refs — read description from the installed SKILL.md of each composed skill. */\nfunction resolveAbilityRefs(\n manifest: AgentManifest,\n workspaceRoot: string,\n skillsRelDir: string,\n): AbilityRef[] {\n const abilityRefs: AbilityRef[] = [];\n for (const name of composedNames(manifest, \"skill\")) {\n const skillMdPath = join(workspaceRoot, skillsRelDir, name, \"SKILL.md\");\n if (!existsSync(skillMdPath)) continue;\n try {\n const fm = parseFrontmatter(readFileSync(skillMdPath, \"utf-8\"));\n const desc = typeof fm.description === \"string\" ? fm.description : undefined;\n if (desc) abilityRefs.push({ name, description: desc });\n } catch {\n // skip unreadable SKILL.md\n }\n }\n return abilityRefs;\n}\n\n/** Phase 4: resolve contract refs — locate the CONTRACT.md of each composed contract in the skills dir. */\nfunction resolveContractRefs(\n manifest: AgentManifest,\n workspaceRoot: string,\n skillsRelDir: string,\n): ContractRef[] {\n const contractRefs: ContractRef[] = [];\n for (const name of composedNames(manifest, \"contract\")) {\n const contractAbsPath = join(workspaceRoot, skillsRelDir, name, \"CONTRACT.md\");\n if (!existsSync(contractAbsPath)) continue;\n contractRefs.push({ name, relativePath: relative(workspaceRoot, contractAbsPath) });\n }\n return contractRefs;\n}\n\n/** A `kind: agent` composition item rendered as its own native sub-agent file. */\ninterface DelegateSubAgent {\n /** `composes[].ref` as written. */\n ref: string;\n /** Absolute path of the sub-agent's source directory. */\n srcDir: string;\n /** File name: the item's `as`, else the sub-agent's own `name`. */\n name: string;\n /** `composes[].as`, forwarded as the install name override. */\n alias: string | undefined;\n}\n\n/**\n * Phase 5a: the `delegate` sub-agents of an agent — its `kind: agent` items\n * whose binding is not `run` (`delegate` is the default for the harnesses that\n * render native agent files). Catalog refs resolve like `agents.<id>.ref`;\n * anything else is a path relative to the composing agent's directory. An\n * unresolvable item is skipped with a warning.\n */\nfunction resolveDelegates(\n manifest: AgentManifest,\n agentName: string,\n srcDir: string,\n workspaceRoot: string,\n warnings: string[],\n): DelegateSubAgent[] {\n const delegates: DelegateSubAgent[] = [];\n for (const item of manifest.composes ?? []) {\n if (item.kind !== \"agent\" || item.binding === \"run\") continue;\n let subSrc: string | undefined;\n try {\n subSrc =\n item.ref.startsWith(\"agent:\") || item.ref.startsWith(\"ai-assets://\")\n ? resolveAgentDefinitionDir(workspaceRoot, item.ref)\n : resolve(srcDir, item.ref);\n } catch (err) {\n warnings.push(\n `Sub-agent ${item.ref} (from ${agentName}): ${err instanceof Error ? err.message : String(err)}`,\n );\n continue;\n }\n if (!subSrc || !existsSync(subSrc)) {\n warnings.push(`Sub-agent source not found: ${item.ref} (from ${agentName})`);\n continue;\n }\n const sub = readManifest(subSrc);\n const name = item.as ?? sub?.name ?? basename(subSrc);\n // The name is a file name under the deploy dir: refuse anything that is not a plain id.\n if (typeof name !== \"string\" || !AGENT_INSTANCE_ID_PATTERN.test(name)) {\n warnings.push(\n `Sub-agent ${item.ref} (from ${agentName}): name ${JSON.stringify(name)} must match ${AGENT_INSTANCE_ID_PATTERN} — skipped`,\n );\n continue;\n }\n delegates.push({\n ref: item.ref,\n srcDir: subSrc,\n name,\n alias: item.as,\n });\n }\n return delegates;\n}\n\n/** Phase 5b: assemble the fragment context from the manifest, workspace config, and resolved refs. */\nfunction buildFragmentContext(\n subAgentNames: string[],\n driverTarget: string,\n skillsRelDir: string,\n wsConfig: SkWorkspaceConfig | undefined,\n abilityRefs: AbilityRef[],\n contractRefs: ContractRef[],\n): FragmentContext {\n const connectors: ConnectorRef[] = (wsConfig?.connectors ?? []).map((c) => ({\n id: c.id,\n driver: c.driver,\n access: c.access ?? \"read-write\",\n }));\n\n const agentsRelDir = DRIVER_TARGETS[driverTarget as DriverTarget]?.local.agent ?? \"\";\n\n return {\n framework: driverTarget,\n skillsDir: skillsRelDir,\n agentsDir: agentsRelDir,\n subAgents: subAgentNames,\n connectors,\n abilityRefs,\n contractRefs,\n };\n}\n\n// ── Core installation ─────────────────────────────────────────────────────────\n\n/**\n * Install a single GitAgent source directory using the appropriate renderer.\n *\n * When `includeSubAgents` is `true`, recursively installs the `delegate`\n * sub-agents (`composes: [{ kind: agent }]`) as separate flat agents in the\n * same deploy directory (no nesting). Tracks visited directories to prevent\n * infinite loops in sub-agent cycles.\n *\n * @param srcDir - Absolute path to the GitAgent source directory (contains `agent.yaml`).\n * @param agentDeployDir - Absolute path to the framework's agent deploy directory.\n * @param workspaceRoot - Absolute path to the workspace root.\n * @param driverTarget - Agent framework ID used to select the renderer.\n * @param skillsRelDir - Relative path to the installed skills dir (e.g. `\".claude/skills\"`).\n * @param nameOverride - Override name for the installed agent. Defaults to `manifest.name`;\n * an instance render passes the instance id.\n * @param includeSubAgents - When `true`, recursively install `delegate` sub-agents.\n * @param visited - Set of resolved source paths already processed (cycle guard).\n * @param wsConfig - Workspace config from `skaile.yaml` (fragments, connectors, extensions).\n * @param log - Optional logger callback for progress messages.\n * @param instance - The `skaile.yaml` instance being rendered; its model / budget / lifecycle\n * override the asset's and its `connectors` map binds the `mcp-server` slots.\n * @returns Object with `created` file paths (every rendered file), `changed` (the subset whose\n * bytes differ from what was deployed before) and `warnings` list.\n * @docLink packages/asset-manager/concepts#install-agent\n */\nexport function installAgent(\n srcDir: string,\n agentDeployDir: string,\n workspaceRoot: string,\n driverTarget: string,\n /** Relative path to the installed skills dir (e.g. \".claude/skills\") */\n skillsRelDir: string,\n nameOverride: string | undefined,\n includeSubAgents: boolean,\n visited: Set<string>,\n wsConfig: SkWorkspaceConfig | undefined,\n log?: (msg: string) => void,\n instance?: AgentInstanceConfig,\n): { created: string[]; changed: string[]; warnings: string[] } {\n const created: string[] = [];\n const changed: string[] = [];\n const warnings: string[] = [];\n\n const realSrc = resolve(srcDir);\n if (visited.has(realSrc)) return { created, changed, warnings };\n visited.add(realSrc);\n\n const initialManifest = readManifest(srcDir);\n if (!initialManifest) {\n warnings.push(`${srcDir} has no agent.yaml or AGENT.md — skipping (not an agent package)`);\n return { created, changed, warnings };\n }\n\n // Phase 1: extends merge — inherit scalars/arrays from parent agent\n // Phase 2: instance overrides — model / budget / lifecycle\n const { manifest, lifecycle } = applyInstanceOverrides(\n applyExtendsMerge(initialManifest, srcDir, warnings),\n instance,\n );\n\n const agentName = nameOverride ?? manifest.name ?? basename(srcDir);\n if (typeof agentName !== \"string\" || !isSafeFileName(agentName)) {\n warnings.push(\n `${srcDir}: agent name ${JSON.stringify(agentName)} is not a valid file name (no path separators) — skipping`,\n );\n return { created, changed, warnings };\n }\n\n log?.(`Installing git-agent: ${agentName} (${driverTarget})`);\n\n // Phase 3: resolve ability refs — read description from installed SKILL.md files\n const abilityRefs = resolveAbilityRefs(manifest, workspaceRoot, skillsRelDir);\n\n // Phase 4: resolve contract refs — locate CONTRACT.md files in the skills dir\n const contractRefs = resolveContractRefs(manifest, workspaceRoot, skillsRelDir);\n\n // Phase 5: delegate sub-agents, fragment context, framework fragments + prompt extensions\n const delegates = resolveDelegates(manifest, agentName, srcDir, workspaceRoot, warnings);\n const fragmentCtx = buildFragmentContext(\n delegates.map((d) => d.name),\n driverTarget,\n skillsRelDir,\n wsConfig,\n abilityRefs,\n contractRefs,\n );\n\n const frameworkFragments = resolveFragments(\n fragmentCtx,\n wsConfig?.agent?.fragments,\n workspaceRoot,\n );\n const promptExtensions = loadPromptExtensions(\n wsConfig?.agent?.[\"prompt-extensions\"],\n workspaceRoot,\n );\n\n const input: AgentRenderInput = {\n manifest,\n soul: readSoul(srcDir),\n rules: readFile(srcDir, \"RULES.md\"),\n duties: readFile(srcDir, \"DUTIES.md\"),\n agentName,\n agentDeployDir,\n workspaceRoot,\n abilityRefs,\n contractRefs,\n frameworkFragments,\n promptExtensions,\n lifecycle,\n skills: composedNames(manifest, \"skill\"),\n mcpServers: boundMcpServers(manifest, instance),\n };\n\n const result = renderAgentToFramework(input, driverTarget, log);\n created.push(...result.created);\n changed.push(...result.changed);\n warnings.push(...result.warnings);\n\n // Recursively install delegate sub-agents as flat top-level agents\n if (includeSubAgents) {\n for (const delegate of delegates) {\n const sub = installAgent(\n delegate.srcDir,\n agentDeployDir,\n workspaceRoot,\n driverTarget,\n skillsRelDir,\n delegate.alias, // undefined → the sub-agent's own name from its agent.yaml\n includeSubAgents,\n visited,\n wsConfig,\n log,\n );\n created.push(...sub.created);\n changed.push(...sub.changed);\n warnings.push(...sub.warnings);\n }\n }\n\n return { created, changed, warnings };\n}\n","/**\n * Asset deployment — copies assets into framework dirs by default (self-contained,\n * cache-safe, portable); `--link` opts into a symlink for the local-path dev loop.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport {\n cpSync,\n existsSync,\n lstatSync,\n mkdirSync,\n mkdtempSync,\n readdirSync,\n rmSync,\n statSync,\n symlinkSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { basename, dirname, join, relative, resolve, sep } from \"node:path\";\nimport type {\n AiComponent,\n CatalogEntry,\n DriverTarget,\n SourceDeclaration,\n} from \"@skaile/workspaces/core\";\nimport {\n agentSourceCacheDir,\n applyPatch,\n assetRefToStr,\n computeHash,\n DRIVER_TARGETS,\n deployedBase,\n deployedDir,\n deployedPaths,\n isDeployed,\n resolveSkWorkspaceConfig,\n} from \"@skaile/workspaces/core\";\nimport {\n isNonAssetDir,\n isNonAssetFile,\n listSkippedSymlinks,\n} from \"@skaile/workspaces/core/publish-manifest\";\nimport {\n AGENT_BODY_PLACEHOLDER,\n CONTRACT_BODY_PLACEHOLDER,\n PRESET_DESCRIPTION_PLACEHOLDER,\n PRESET_ITEM_PLACEHOLDER_REF,\n PROMPT_BODY_PLACEHOLDER,\n SKILL_BODY_PLACEHOLDER,\n SKILL_DESCRIPTION_PLACEHOLDER,\n SKILL_DESCRIPTION_PLACEHOLDER_PREFIX,\n} from \"@skaile/workspaces/types/manifests\";\nimport type { IAssetKindProvider, IAssetKindRegistry } from \"@skaile/workspaces/plugins\";\nimport { stringify as stringifyYaml } from \"yaml\";\nimport { installAgent, readManifest, readSoul } from \"./install-agent.js\";\nimport { CODEX_IDENTITY_DIR, type Log } from \"./renderers.js\";\n\nexport type { Log } from \"./renderers.js\";\n\nconst noop: Log = () => {};\n\n/**\n * The printable canonical ref of a resolved entry — `kind:@publisher/name#version`,\n * the one ref grammar the CLI shows. An entry whose `publisher` is a clone key\n * carries the real ref in `canonicalRef`; with neither a `canonicalRef` nor a\n * publisher there is nothing to namespace it by, so it falls back to `kind:name`.\n */\nexport function canonicalEntryRef(entry: CatalogEntry): string {\n if (entry.canonicalRef) return entry.canonicalRef;\n const publisher = entry.publisher?.replace(/^@/, \"\");\n if (!publisher) return `${entry.kind}:${entry.name}`;\n return assetRefToStr({\n kind: entry.kind,\n name: entry.name,\n publisher,\n pin: entry.version || undefined,\n });\n}\n\n// ── Filesystem helpers ────────────────────────────────────────────────────────\n\nfunction clearDest(dest: string): void {\n try {\n const s = lstatSync(dest);\n if (s.isSymbolicLink()) unlinkSync(dest);\n else rmSync(dest, { recursive: true, force: true });\n } catch {}\n}\n\n/**\n * The harness component directory a kind installs into — the provider's\n * `installTarget` — or `undefined` for composition-only kinds (connector,\n * mcp-server, knowledge, persona, ruleset, preset) and unregistered kinds.\n * The registry is the only authority: there is no static list of deployable kinds.\n */\nexport function installTargetOf(\n registry: IAssetKindRegistry,\n kind: string,\n): AiComponent | undefined {\n return registry.getProvider(kind)?.installTarget;\n}\n\n/**\n * The manifest file of a resolved entry. `source` is normally the manifest file\n * itself; a directory source is searched for the provider's manifest.\n * `undefined` when `source` is a directory holding none.\n */\nfunction manifestFileOf(provider: IAssetKindProvider, source: string): string | undefined {\n if (!statSync(source).isDirectory()) return source;\n const hit = readdirSync(source).find((f) => provider.matchesPath(f));\n return hit ? join(source, hit) : undefined;\n}\n\n/**\n * A resolved entry ready to deploy: a {@link CatalogEntry} that may carry the\n * asset's authoritative file list.\n */\nexport interface DeployableEntry extends CatalogEntry {\n /**\n * Asset files relative to the manifest's directory. Set for store-staged\n * assets, whose verified pointer (not the provider's default filter) defines\n * what the asset is — a manifest-mode publish may list files the default filter\n * would not pick. Absent → the provider's `defaultFileFilter`.\n */\n files?: readonly string[];\n}\n\n/**\n * Copy an asset into `dest`: the entry's explicit `files` when it has them, else\n * exactly the files the provider's `defaultFileFilter` selects (the same set the\n * store publishes and hashes). A directory source without a recognisable\n * manifest is copied whole.\n */\nfunction copyAsset(\n provider: IAssetKindProvider,\n entry: DeployableEntry,\n dest: string,\n onSkippedSymlink?: (entry: DeployableEntry, path: string) => void,\n): void {\n const source = entry.source;\n clearDest(dest);\n const manifestPath = manifestFileOf(provider, source);\n if (!manifestPath) {\n // Same ignore list as the content hash: leftovers and symlinks are not part of the asset.\n cpSync(source, dest, {\n recursive: true,\n filter: (src) => {\n if (src === source) return true;\n if (isNonAssetDir(basename(src)) || isNonAssetFile(basename(src))) return false;\n if (lstatSync(src).isSymbolicLink()) {\n onSkippedSymlink?.(entry, join(basename(source), relative(source, src)));\n return false;\n }\n return true;\n },\n });\n return;\n }\n const filter = provider.defaultFileFilter(manifestPath);\n const assetRoot = filter.assetRoot;\n const files = entry.files ?? filter.files;\n mkdirSync(dest, { recursive: true });\n for (const rel of files) {\n const target = join(dest, rel);\n mkdirSync(dirname(target), { recursive: true });\n cpSync(join(assetRoot, rel), target);\n }\n // A lone manifest file shares its directory with other assets: only an asset that owns its\n // directory (several files, or a directory named after it) can say which links it drops.\n if (onSkippedSymlink && (files.length > 1 || basename(assetRoot) === entry.name)) {\n for (const rel of listSkippedSymlinks(assetRoot)) {\n onSkippedSymlink(entry, join(basename(assetRoot), rel));\n }\n }\n}\n\n/**\n * Symlink an asset (the `--link` dev-loop). A multi-file asset, or one living in\n * a directory named after it, links its whole directory; a lone manifest file\n * links into `dest/`.\n */\nfunction symlinkAsset(\n provider: IAssetKindProvider,\n source: string,\n dest: string,\n name: string,\n): void {\n clearDest(dest);\n mkdirSync(dirname(dest), { recursive: true });\n const manifestPath = manifestFileOf(provider, source);\n if (!manifestPath) {\n symlinkSync(resolve(source), dest);\n return;\n }\n const { assetRoot, files } = provider.defaultFileFilter(manifestPath);\n if (files.length > 1 || basename(assetRoot) === name) {\n symlinkSync(resolve(assetRoot), dest);\n } else {\n mkdirSync(dest, { recursive: true });\n symlinkSync(resolve(manifestPath), join(dest, basename(manifestPath)));\n }\n}\n\n// ── Deploy options ───────────────────────────────────────────────────────────\n\n/**\n * Options controlling where and how assets are deployed.\n *\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport interface DeployOptions {\n /** Asset-kind registry — decides, per kind, the harness install target and file set. */\n registry: IAssetKindRegistry;\n /** Agent framework to target (determines framework-specific directory layout). Defaults to `\"claude-code\"`. */\n driverTarget?: DriverTarget;\n /** When `true`, deploy into the global Skaile cache rather than a project workspace. */\n global?: boolean;\n /** Absolute path to the workspace root. Defaults to `process.cwd()`. */\n cwd?: string;\n /**\n * Opt into a symlink (the author dev-loop) instead of a copy — honoured only\n * when the source has a real local path. Machine-local / not for committing;\n * for store/factory sources (no stable local path) it is a no-op (still copy).\n */\n link?: boolean;\n /**\n * Called once per symlink inside an asset's own directory that a copy deploy\n * leaves out (symlinks are not part of an asset), with the asset entry and the\n * path of the link relative to the asset directory's parent (`<dir>/<rel>`).\n */\n onSkippedSymlink?: (entry: DeployableEntry, path: string) => void;\n}\n\n/**\n * Keep the agent's source (`agent.yaml`, `SOUL.md`, …) under\n * `<project>/.skaile/cache/agents/<name>/`, the one place `agents.<id>.ref:\n * agent:@pub/name` resolves an added library / source / store agent from: the\n * deployed copy is a rendering (`.claude/agents/<name>.md`) that has lost the\n * composition, triggers and slots an instance needs. An `AGENT.md` agent is stored\n * in the `agent.yaml` + `SOUL.md` form so every instance consumer reads one shape.\n * A failure is logged, never fatal: the rendered agent is deployed either way.\n */\nfunction materializeAgentSource(\n provider: IAssetKindProvider,\n entry: DeployableEntry,\n srcDir: string,\n workspaceRoot: string,\n log: Log,\n): void {\n const dest = join(agentSourceCacheDir(workspaceRoot), entry.name);\n try {\n copyAsset(provider, entry, dest);\n if (existsSync(join(dest, \"agent.yaml\"))) return;\n const manifest = readManifest(srcDir);\n if (!manifest) return;\n writeFileSync(\n join(dest, \"agent.yaml\"),\n stringifyYaml({ ...manifest, name: manifest.name ?? entry.name }),\n \"utf8\",\n );\n const soul = readSoul(srcDir);\n if (soul) writeFileSync(join(dest, \"SOUL.md\"), `${soul}\\n`, \"utf8\");\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n log(` warn: could not keep the source of agent ${entry.name}: ${reason}`);\n }\n}\n\n// ── Deploy / remove ──────────────────────────────────────────────────────────\n\n/**\n * Deploy a single asset to the framework-specific directory.\n *\n * Copies by default — self-contained, cache-safe, and portable, so a deployed\n * asset survives a `cache clean` of its source and a committed `.claude/` stays\n * machine-independent. `opts.link` opts into a symlink (the live dev-loop), but\n * only when the source has a real local path; store/factory sources (no stable\n * local path) ignore it and still copy. Agents are rendered via the enriched\n * `installAgent` path which resolves abilities, contracts, and framework\n * fragments before writing the native agent file.\n *\n * @param entry - Catalog entry describing the asset to deploy.\n * @param repositories - Repository declarations from `skaile.yaml` (used to\n * determine whether the source is a local path or a remote clone).\n * @param opts - Deployment target options.\n * @param log - Optional logger callback for progress messages.\n * @returns `true` when the asset was deployed successfully.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function deployAsset(\n entry: DeployableEntry,\n repositories: Record<string, SourceDeclaration>,\n opts: DeployOptions,\n log: Log = noop,\n): boolean {\n return deployEntry(entry, repositories, opts, log).deployed;\n}\n\n/**\n * {@link deployAsset} plus whether the deploy altered anything on disk. A copied asset always\n * counts as changed; an agent is re-rendered every time but counts as changed only when a\n * rendered file's bytes differ from the deployed one (an unchanged agent is left untouched).\n */\nfunction deployEntry(\n entry: DeployableEntry,\n repositories: Record<string, SourceDeclaration>,\n opts: DeployOptions,\n log: Log,\n): { deployed: boolean; changed: boolean } {\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n // Composition-only kinds (no `installTarget`) never land in a harness dir:\n // they are fetched + verified into the store cache and composed at session start.\n const provider = opts.registry.getProvider(entry.kind);\n const component = provider?.installTarget;\n if (!provider || !component) return { deployed: true, changed: false };\n\n // Agents need framework-specific rendering via the enriched installAgent path\n if (component === \"agent\") {\n const workspaceRoot = cwd ?? process.cwd();\n const agentDeployDir = deployedBase(\n component,\n driverTarget as DriverTarget,\n globalInstall,\n cwd,\n );\n const targetMap = DRIVER_TARGETS[driverTarget as DriverTarget];\n const skillsRelDir = targetMap?.local.skill ?? \"\";\n const wsConfig = resolveSkWorkspaceConfig(workspaceRoot);\n const srcDir = statSync(entry.source).isDirectory() ? entry.source : dirname(entry.source);\n const result = installAgent(\n srcDir,\n agentDeployDir,\n workspaceRoot,\n driverTarget,\n skillsRelDir,\n entry.name,\n /* includeSubAgents */ true,\n new Set<string>(),\n wsConfig,\n log,\n );\n for (const w of result.warnings) log(` warn: ${w}`);\n if (result.created.length > 0) {\n let changed = result.changed.length > 0;\n // An `AGENT.md` agent used to deploy raw into `<base>/<name>/AGENT.md`, which no\n // harness but omp (whose rendering is that directory) reads: drop the stale copy.\n const staleRawCopy = join(agentDeployDir, entry.name);\n if (driverTarget !== \"omp\" && existsSync(staleRawCopy)) {\n clearDest(staleRawCopy);\n changed = true;\n }\n if (!globalInstall) materializeAgentSource(provider, entry, srcDir, workspaceRoot, log);\n return { deployed: true, changed };\n }\n // Fall through to raw deploy if renderer produces no files (unsupported framework, etc.)\n }\n\n const dest = deployedDir(component, entry.name, driverTarget, globalInstall, cwd);\n mkdirSync(dirname(dest), { recursive: true });\n\n // Symlink only on explicit opt-in AND when the source has a real local path.\n // Factory sources have a `path` (the bundled dir under node_modules, replaced\n // on every upgrade) but no stable dev-loop, so they always copy. Default copy\n // keeps deploys cache-safe and portable.\n const repoDecl = entry.publisher ? repositories[entry.publisher] : undefined;\n const hasLocalPath = repoDecl?.path != null && repoDecl.factory !== true;\n\n if (opts.link === true && hasLocalPath) {\n symlinkAsset(provider, entry.source, dest, entry.name);\n log(` symlink ${entry.kind}:${entry.name}`);\n } else {\n copyAsset(provider, entry, dest, opts.onSkippedSymlink);\n log(` copy ${entry.kind}:${entry.name}`);\n }\n return { deployed: true, changed: true };\n}\n\n/**\n * Deploy all resolved assets, applying patches where configured.\n *\n * Already-deployed assets are skipped unless their deployed manifest content differs\n * from the source. This handles copies that have gone stale after a source update.\n * In copy mode (the default, `!opts.link`) an existing **symlink** dest is healed:\n * it is removed and re-deployed as a real copy, so an old/legacy symlink deploy is\n * silently upgraded. With `opts.link` an existing symlink is left alone.\n *\n * @param resolved - Catalog entries to deploy (output of `resolveAll`).\n * @param repositories - Repository declarations from `skaile.yaml`.\n * @param patches - Map of `kind:name` → patch file path for patch application.\n * @param opts - Deployment target options.\n * @param log - Optional logger callback for progress messages.\n * @returns Canonical refs (`kind:@publisher/name[#version]`; bare `kind:name`\n * when the entry carries no publisher) of the assets newly deployed in this call.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function deployAll(\n resolved: DeployableEntry[],\n repositories: Record<string, SourceDeclaration>,\n patches: Record<string, string>,\n opts: DeployOptions,\n log: Log = noop,\n): string[] {\n const deployed: string[] = [];\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n for (const entry of resolved) {\n // Skip composition-only kinds (no `installTarget`) — they live in the store\n // cache and are composed at session start, never copied into a harness dir.\n const component = installTargetOf(opts.registry, entry.kind);\n if (!component) continue;\n\n const ref = `${entry.kind}:${entry.name}`;\n\n // Agents are compiled artifacts: always re-rendered, never skipped on a manifest hash\n // (and a stale raw `<name>/AGENT.md` copy of the old layout must be replaced, not kept).\n if (\n component !== \"agent\" &&\n isDeployed(component, entry.name, driverTarget, globalInstall, cwd)\n ) {\n // Compare the deployed manifest file against the source to detect stale copies.\n // For symlinks the deployed path resolves through to the source file, so hashes\n // always match — symlinked installs are never needlessly re-linked.\n const dest = deployedDir(component, entry.name, driverTarget, globalInstall, cwd);\n // Heal: in copy mode an existing symlink dest is left to fall through to a\n // real copy below (cache-safe + portable) — bypass the hash skip entirely.\n // With --link a symlink dest is intentional, so it takes the normal skip path.\n let destIsSymlink = false;\n try {\n destIsSymlink = lstatSync(dest).isSymbolicLink();\n } catch {}\n const healSymlink = destIsSymlink && opts.link !== true;\n // Surface the one-time symlink→copy migration so an author who relied on a\n // live symlink dev-loop knows why edits stopped reflecting.\n if (healSymlink) log(` healed symlink → copy: ${ref} (use --link for the dev-loop)`);\n\n if (!healSymlink) {\n const manifestName = basename(entry.source);\n const deployedManifest = join(dest, manifestName);\n // isDeployed() only lstats the dir, so a present-but-empty dir (manifest\n // file deleted) reads as deployed. A missing manifest must never count as\n // \"already deployed\" — fall through to re-deploy instead of skipping.\n // (existsSync follows symlinks, so for symlinked installs the manifest\n // resolves through to the live source and the hash check below still\n // skips them.)\n if (existsSync(deployedManifest)) {\n let manifestUnchanged: boolean;\n try {\n manifestUnchanged = computeHash(entry.source) === computeHash(deployedManifest);\n } catch {\n // Deployed manifest unreadable (e.g. agent rendered to a different path) — skip\n log(` already deployed: ${ref}`);\n continue;\n }\n // Every other file the deploy writes must be present and identical too —\n // the manifest alone misses a deleted or stale companion (`.gitignore`,\n // `resources/`, `scripts/`) the copy below would restore. A companion\n // that cannot be compared counts as changed, so it is healed, not skipped.\n const srcRoot = dirname(entry.source);\n const companionsUnchanged = (entry.files ?? [])\n .filter((rel) => rel !== manifestName)\n .every((rel) => {\n const deployed = join(dest, rel);\n try {\n return (\n existsSync(deployed) && computeHash(join(srcRoot, rel)) === computeHash(deployed)\n );\n } catch {\n return false;\n }\n });\n if (manifestUnchanged && companionsUnchanged) {\n log(` already deployed: ${ref}`);\n continue;\n }\n log(` updating: ${ref} (content changed)`);\n // fall through to redeploy\n }\n }\n }\n\n // An agent is re-rendered every time; it is reported as deployed only when a rendered file\n // changed, so a repeat install leaves it (and the report) alone.\n const { changed } = deployEntry(entry, repositories, opts, log);\n if (changed) deployed.push(canonicalEntryRef(entry));\n\n // Apply patch if configured\n const patchFile = patches[ref];\n if (patchFile && existsSync(patchFile)) {\n const dest = deployedDir(component, entry.name, driverTarget, globalInstall, cwd);\n if (applyPatch(dest, patchFile)) {\n log(` patched ${ref}`);\n } else {\n log(` patch failed for ${ref}`);\n }\n }\n }\n\n return deployed;\n}\n\n/**\n * Unified diff from a deployed agent to its source, `-` lines in the deployed copy only and `+`\n * lines in the source only. An agent is a rendering, not a copy, so the source is rendered the way\n * {@link deployAsset} renders it (same renderer, same workspace context) into a scratch directory\n * and that is compared with what the harness holds: `<name>.md` for claude-code, `<name>.toml`\n * plus the `skaile-agents/<name>.md` identity for codex, the `<name>/` directory for omp.\n *\n * @param entry - The agent's catalog entry (`source` is its `agent.yaml` / `AGENT.md`).\n * @param opts - Deployment target options (must match the options used at install time).\n * @returns `null` when none of the agent's rendered files is deployed, else the diff text\n * (`\"\"` when the deployed agent matches its source).\n * @throws When `diff(1)` itself fails (exit status other than 0/1).\n */\nexport function diffDeployedAgent(entry: DeployableEntry, opts: DeployOptions): string | null {\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const workspaceRoot = opts.cwd ?? process.cwd();\n const deployedAgents = deployedBase(\"agent\", driverTarget, opts.global ?? false, opts.cwd);\n const scratch = mkdtempSync(join(tmpdir(), \"skaile-diff-agent-\"));\n try {\n const renderedAgents = join(scratch, \"agents\");\n const srcDir = statSync(entry.source).isDirectory() ? entry.source : dirname(entry.source);\n const rendered = installAgent(\n srcDir,\n renderedAgents,\n workspaceRoot,\n driverTarget,\n DRIVER_TARGETS[driverTarget]?.local.skill ?? \"\",\n entry.name,\n /* includeSubAgents */ false,\n new Set<string>(),\n resolveSkWorkspaceConfig(workspaceRoot),\n );\n if (rendered.created.length === 0) return null;\n\n // Each rendered top-level item pairs with the deployed item of the same name.\n const pairs: Array<[from: string, to: string]> = [];\n for (const [renderedRoot, deployedRoot] of [\n [renderedAgents, deployedAgents],\n [join(scratch, CODEX_IDENTITY_DIR), join(dirname(deployedAgents), CODEX_IDENTITY_DIR)],\n ] as const) {\n if (!existsSync(renderedRoot)) continue;\n for (const item of readdirSync(renderedRoot)) {\n pairs.push([join(deployedRoot, item), join(renderedRoot, item)]);\n }\n }\n if (!pairs.some(([from]) => existsSync(from))) return null;\n\n const diffs: string[] = [];\n for (const [from, to] of pairs) {\n const r = spawnSync(\"diff\", [\"-ruN\", from, to], { encoding: \"utf8\" });\n if (r.status === 1) diffs.push(r.stdout);\n else if (r.status !== 0) {\n throw new Error(\n `diff failed for agent:${entry.name}: ${r.stderr || r.error?.message || \"unknown error\"}`,\n );\n }\n }\n return diffs.join(\"\").split(`${scratch}${sep}`).join(`rendered${sep}`);\n } finally {\n rmSync(scratch, { recursive: true, force: true });\n }\n}\n\n/**\n * Remove a deployed asset from the framework directory.\n *\n * Removes symlinks with `unlink`; removes copied directories with `rm -rf`.\n *\n * @param kind - Asset kind (`skill`, `agent`, `prompt`, `flow`, `contract`).\n * @param name - Asset name as registered in the catalog.\n * @param opts - Deployment target options (must match the options used at install time).\n * @returns `true` if the asset existed and was removed; `false` if it was not deployed.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function removeAsset(kind: string, name: string, opts: DeployOptions): boolean {\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n // Composition-only kinds have no harness dir — never resolve (and delete) one.\n const component = installTargetOf(opts.registry, kind);\n if (!component) return false;\n let removed = false;\n for (const dest of deployedPaths(component, name, driverTarget, globalInstall, cwd)) {\n try {\n const s = lstatSync(dest);\n if (s.isSymbolicLink()) unlinkSync(dest);\n else rmSync(dest, { recursive: true, force: true });\n removed = true;\n } catch {\n // not deployed at this path\n }\n }\n if (component === \"agent\") {\n // The Codex identity file and the kept source live beside the deployed agent.\n const agentDir = deployedBase(component, driverTarget, globalInstall, cwd);\n const extras = [join(dirname(agentDir), CODEX_IDENTITY_DIR, `${name}.md`)];\n if (!globalInstall) extras.push(join(agentSourceCacheDir(cwd ?? process.cwd()), name));\n for (const extra of extras) {\n if (existsSync(extra)) {\n rmSync(extra, { recursive: true, force: true });\n removed = true;\n }\n }\n }\n return removed;\n}\n\n// ── Scaffold ─────────────────────────────────────────────────────────────────\n\n/** Markdown-marker scaffold (SKILL.md / CONTRACT.md / `*.prompt.md`); `body` is the kind's placeholder. */\nfunction markdownTemplate(name: string, description: string, body: string): string {\n // JSON.stringify yields a valid YAML double-quoted scalar, so any\n // user-supplied description (colons, quotes, `#`) survives the round-trip.\n return `---\nname: \"${name}\"\ndescription: ${JSON.stringify(description)}\nmetadata:\n version: \"0.1.0\"\n---\n\n# ${name}\n\n${body}\n`;\n}\n\n/** `agent.yaml` (spec 0.2) scaffold; the system prompt lives in the `SOUL.md` next to it. */\nfunction agentTemplate(name: string, description: string): string {\n return `spec_version: \"0.2\"\nname: \"${name}\"\nversion: 0.1.0\ndescription: ${JSON.stringify(description)}\nlifecycle: standing\n`;\n}\n\nfunction soulTemplate(name: string): string {\n return `# ${name}\n\n${AGENT_BODY_PLACEHOLDER}\n`;\n}\n\nfunction presetTemplate(name: string, description: string): string {\n return `name: ${name}\ndescription: ${JSON.stringify(description)}\nversion: 0.1.0\nitems:\n - ref: ${PRESET_ITEM_PLACEHOLDER_REF}\n`;\n}\n\nfunction flowTemplate(name: string, description: string): string {\n return `id: \"${name}\"\nversion: \"0.1.0\"\nname: \"${name}\"\ndescription: ${JSON.stringify(description)}\n\nglobals:\n approval_mode: checkpoint\n\nnodes: []\n`;\n}\n\n/** Asset kinds {@link createScaffold} has a real template for. */\nexport const SCAFFOLD_KINDS = [\"skill\", \"agent\", \"prompt\", \"flow\", \"preset\", \"contract\"] as const;\n\n/** Options for {@link createScaffold}. */\nexport interface ScaffoldOptions {\n /**\n * Description written into the manifest. Omitted: markdown kinds get a\n * `TODO:` placeholder that `skaile validate` rejects until it is replaced;\n * presets and flows keep their generic default.\n */\n description?: string;\n}\n\n/**\n * Create a minimal scaffold directory for a new asset.\n *\n * Writes the appropriate manifest file (`SKILL.md`, `agent.yaml` + `SOUL.md`, `CONTRACT.md`,\n * `<name>.preset.yaml`, `<name>.flow.yaml`, or `<name>.prompt.md`) inside a\n * new `<destDir>/<name>/` directory.\n *\n * @param name - Asset name (also used as the directory name).\n * @param kind - Asset kind: `skill` | `agent` | `preset` | `flow` | `prompt` | `contract`.\n * @param destDir - Parent directory to create the asset in.\n * @param opts - Optional scaffold content ({@link ScaffoldOptions}).\n * @returns `{ ok: true, path }` on success, `{ ok: false, path: errorMessage }` if the\n * directory already exists or `kind` is not one of {@link SCAFFOLD_KINDS}\n * (`Cannot scaffold kind \"<kind>\". Expected: ...`); nothing is created then.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function createScaffold(\n name: string,\n kind: string,\n destDir: string,\n opts: ScaffoldOptions = {},\n): { ok: boolean; path: string } {\n if (!(SCAFFOLD_KINDS as readonly string[]).includes(kind)) {\n return {\n ok: false,\n path: `Cannot scaffold kind \"${kind}\". Expected: ${SCAFFOLD_KINDS.join(\", \")}.`,\n };\n }\n const dest = join(destDir, name);\n if (existsSync(dest)) {\n return { ok: false, path: `Directory '${name}' already exists in ${destDir}` };\n }\n mkdirSync(dest, { recursive: true });\n\n const mdDescription =\n opts.description ??\n ([\"agent\", \"contract\", \"prompt\"].includes(kind)\n ? `${SKILL_DESCRIPTION_PLACEHOLDER_PREFIX} describe this ${kind}.`\n : SKILL_DESCRIPTION_PLACEHOLDER);\n\n if (kind === \"preset\") {\n writeFileSync(\n join(dest, `${name}.preset.yaml`),\n presetTemplate(name, opts.description ?? PRESET_DESCRIPTION_PLACEHOLDER),\n \"utf8\",\n );\n } else if (kind === \"flow\") {\n writeFileSync(\n join(dest, `${name}.flow.yaml`),\n flowTemplate(name, opts.description ?? \"Flow description\"),\n \"utf8\",\n );\n } else if (kind === \"prompt\") {\n writeFileSync(\n join(dest, `${name}.prompt.md`),\n markdownTemplate(name, mdDescription, PROMPT_BODY_PLACEHOLDER),\n \"utf8\",\n );\n } else if (kind === \"agent\") {\n writeFileSync(join(dest, \"agent.yaml\"), agentTemplate(name, mdDescription), \"utf8\");\n writeFileSync(join(dest, \"SOUL.md\"), soulTemplate(name), \"utf8\");\n } else if (kind === \"contract\") {\n writeFileSync(\n join(dest, \"CONTRACT.md\"),\n markdownTemplate(name, mdDescription, CONTRACT_BODY_PLACEHOLDER),\n \"utf8\",\n );\n } else {\n writeFileSync(\n join(dest, \"SKILL.md\"),\n markdownTemplate(name, mdDescription, SKILL_BODY_PLACEHOLDER),\n \"utf8\",\n );\n }\n\n return { ok: true, path: dest };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveAgentExec } from './chunk-YROR332M.js';
|
|
2
|
-
import { tryWithFsDeadline, fsDeadlineMs, withFsDeadline } from './chunk-
|
|
2
|
+
import { tryWithFsDeadline, fsDeadlineMs, withFsDeadline } from './chunk-Y34MSWEZ.js';
|
|
3
3
|
import { entryTransport, normalizeAnthropicBaseUrl, resolveEntryBaseUrl } from './chunk-MJHSLODD.js';
|
|
4
4
|
import { createWriteStream, createReadStream } from 'fs';
|
|
5
5
|
import { unlink, rename, readdir, stat } from 'fs/promises';
|
|
@@ -488,5 +488,5 @@ async function probeResumeTranscript(sessionId, opts) {
|
|
|
488
488
|
}
|
|
489
489
|
|
|
490
490
|
export { ANTHROPIC_DEFAULT_BASE_URL, agentTranscriptStore, buildClaudeEndpointEnv, claudeEndpointMode, localTranscriptStore, probeResumeTranscript, resolveClaudeConfigDir, scrubPoisonedTranscript, transcriptStoreForRuntime };
|
|
491
|
-
//# sourceMappingURL=chunk-
|
|
492
|
-
//# sourceMappingURL=chunk-
|
|
491
|
+
//# sourceMappingURL=chunk-QG3HOJEK.js.map
|
|
492
|
+
//# sourceMappingURL=chunk-QG3HOJEK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../bridge/src/cloud.ts","../bridge/src/drivers/scrub-transcript.ts","../bridge/src/agent-transcript.ts","../bridge/src/drivers/resume-probe.ts"],"names":["join"],"mappings":"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","file":"chunk-S53LOR7B.js","sourcesContent":["/**\n * AI endpoint transport for the `claude-sdk` driver — the Claude Agent SDK's\n * child-process environment.\n *\n * {@link buildClaudeEndpointEnv} takes an **AI provider registry entry** and\n * is what the driver calls, on every transport. It is plan §2.3's\n * `buildEndpointEnv` for the claude-sdk row (named for the driver because the\n * vars it emits — `CLAUDE_CODE_USE_*`, `ANTHROPIC_*` — are the Claude Agent\n * SDK's own contract, not a portable one).\n *\n * A registry entry says what the deleted `cloud` axis said — Amazon Bedrock,\n * Google Vertex AI, Azure AI Foundry, a generic gateway — with `surface` +\n * `transport` + `base_url` + `credential`, and says it for the direct\n * endpoint too, which the `cloud` axis could not address at all.\n *\n * Cross-repo contract: env key names and semantics here are load-bearing —\n * the platform resolves credential bundles against the same key set.\n */\n\nimport {\n type AIProviderEntry,\n type AIProviderLlmEntry,\n entryTransport,\n normalizeAnthropicBaseUrl,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\n\n/**\n * Env vars scrubbed from the inherited environment before an endpoint env is\n * assembled. Ambient first-party credentials or a stale `CLAUDE_CODE_USE_*`\n * flag must never leak into a session whose entry points elsewhere (the\n * ambient carriers are restored explicitly when the entry has none of its\n * own).\n *\n * Deliberately NOT exhaustive: ambient transport-specific vars (AWS_*,\n * GOOGLE_*, ANTHROPIC_VERTEX_PROJECT_ID, ANTHROPIC_FOUNDRY_*) survive so a\n * standalone CLI inherits its own signing chain; the SDK ignores vars whose\n * transport flag is unset.\n */\nconst SCRUBBED_ENV_KEYS = [\"ANTHROPIC_API_KEY\", \"ANTHROPIC_AUTH_TOKEN\", \"ANTHROPIC_BASE_URL\"];\n\n/**\n * The Anthropic first-party endpoint. An entry that resolves to exactly this\n * host needs no `ANTHROPIC_BASE_URL`: the SDK already points there, and an\n * explicit value would make every default session look like a third-party\n * redirect to Claude Code's own telemetry and auth heuristics.\n */\nexport const ANTHROPIC_DEFAULT_BASE_URL = \"https://api.anthropic.com\";\n\n/**\n * Headers the SDK owns and an entry must not restate through\n * `ANTHROPIC_CUSTOM_HEADERS`: the protocol version it was built against, and\n * the two credential carriers (which are `credential.ref`'s job — a literal\n * secret in `headers` is a validation error anyway).\n */\nconst SDK_OWNED_HEADERS: Record<string, true> = {\n \"anthropic-version\": true,\n authorization: true,\n \"x-api-key\": true,\n};\n\n/**\n * Which of the Claude Agent SDK's four native transports an entry addresses.\n *\n * The SDK has no `transport` field: it switches on a `CLAUDE_CODE_USE_*` flag.\n * Bedrock and Vertex are their own wire surfaces, so they are recognized by\n * `surface` as well as by `transport` — a legacy-derived entry that had no\n * region (and therefore no `params`, and therefore no `transport`) is still a\n * Bedrock session, exactly as it was before the registry existed.\n */\nexport type ClaudeEndpointMode = \"anthropic\" | \"bedrock\" | \"vertex\" | \"foundry\";\n\n/** Classify a registry entry into its {@link ClaudeEndpointMode}. */\nexport function claudeEndpointMode(entry: AIProviderEntry): ClaudeEndpointMode {\n const surface = (entry as AIProviderLlmEntry).surface;\n const transport = entryTransport(entry);\n if (surface === \"bedrock-converse-stream\" || transport === \"bedrock\") return \"bedrock\";\n if (surface === \"google-vertex\" || transport === \"vertex\") return \"vertex\";\n if (transport === \"foundry\") return \"foundry\";\n return \"anthropic\";\n}\n\n/** Arguments for {@link buildClaudeEndpointEnv}. */\nexport interface ClaudeEndpointEnvInput {\n /** The selected registry entry — the whole endpoint definition. */\n entry: AIProviderEntry;\n /**\n * The entry's credential, already resolved from its `credential.ref`\n * (`resolveEntryCredential`). Absent for `kind: none`, for an ambient\n * `sigv4` / `google_adc` / `azure_entra` chain, for `oauth` (whose blob the\n * runner writes to the Claude credentials file, never to the env), and for a\n * reference that did not resolve.\n */\n credential?: string;\n /**\n * The driver's base environment — `process.env` with `undefined` dropped.\n * The endpoint vars are layered **on top** of it, never instead of it, so\n * `PATH`, `HOME` and `SKAILE_SESSION_ID` reach the child.\n */\n baseEnv: Record<string, string>;\n /** `AgentConfig.env` plus any credential material the session carried. */\n configEnv?: Record<string, string>;\n}\n\n/**\n * Assemble the Claude Agent SDK child env for one registry entry (plan §2.3).\n *\n * Pure (no external state read, no input mutated). Starts from `baseEnv`\n * merged with `configEnv`, scrubs the inherited Anthropic credential/routing\n * vars and every `CLAUDE_CODE_USE_*` flag, then writes exactly what the entry\n * describes: at most one transport flag, the endpoint, and the credential in\n * the carrier its `kind` names.\n *\n * Credential kinds (§1.4): `api_key_header` → `ANTHROPIC_API_KEY` (the SDK\n * sends it as `x-api-key`); `bearer` → `ANTHROPIC_AUTH_TOKEN` (sent as\n * `Authorization: Bearer`); `sigv4` / `google_adc` / `azure_entra` emit\n * nothing and let the AWS/Google/Azure chain sign — which is why the scrub\n * deliberately spares ambient `AWS_*` / `GOOGLE_*` values; `oauth` and `none`\n * emit nothing, and the pre-scrub ambient carriers are restored so an OAuth or\n * shell-configured session keeps the auth it had.\n *\n * Never returns `undefined` or empty values; absent settings are omitted.\n */\nexport function buildClaudeEndpointEnv(args: ClaudeEndpointEnvInput): Record<string, string> {\n const { entry, credential, baseEnv, configEnv } = args;\n const env: Record<string, string> = { ...baseEnv, ...(configEnv ?? {}) };\n\n // Captured before the scrub — an entry with no credential material of its\n // own falls back to these, the way the gateway branch always has.\n const ambient = { authToken: env.ANTHROPIC_AUTH_TOKEN, apiKey: env.ANTHROPIC_API_KEY };\n\n for (const key of Object.keys(env)) {\n if (SCRUBBED_ENV_KEYS.includes(key) || key.startsWith(\"CLAUDE_CODE_USE_\")) {\n delete env[key];\n }\n }\n\n const set = (key: string, value: string | undefined) => {\n // Falsy check is deliberate: an empty-string credential/setting is never\n // valid env — dropping it beats shipping a key the SDK treats as set.\n if (value) env[key] = value;\n };\n\n const kind = entry.credential?.kind ?? \"none\";\n const params = (entry as AIProviderLlmEntry).params as Record<string, string> | undefined;\n\n // Static headers ride as ANTHROPIC_CUSTOM_HEADERS (`Name: Value` per line),\n // the only channel the SDK offers. An entry with none leaves an ambient\n // value alone.\n const headers = Object.entries(entry.headers ?? {}).filter(\n ([name]) => !SDK_OWNED_HEADERS[name.toLowerCase()],\n );\n if (headers.length > 0) {\n env.ANTHROPIC_CUSTOM_HEADERS = headers.map(([name, value]) => `${name}: ${value}`).join(\"\\n\");\n }\n\n switch (claudeEndpointMode(entry)) {\n case \"bedrock\": {\n env.CLAUDE_CODE_USE_BEDROCK = \"1\";\n // The AWS credential bundle itself is `configEnv` material (AWS_*), and\n // ambient AWS_* survived the scrub, so a standalone CLI keeps its own.\n set(\"AWS_REGION\", params?.region);\n break;\n }\n case \"vertex\": {\n env.CLAUDE_CODE_USE_VERTEX = \"1\";\n // GOOGLE_APPLICATION_CREDENTIALS is a path the runner materialized; it\n // arrives through `configEnv` or ambient, never from `credential`.\n set(\"ANTHROPIC_VERTEX_PROJECT_ID\", params?.project);\n set(\"CLOUD_ML_REGION\", params?.location);\n break;\n }\n case \"foundry\": {\n env.CLAUDE_CODE_USE_FOUNDRY = \"1\";\n // §1.3: an explicit `base_url` wins over the resource-derived endpoint,\n // and the SDK has a separate var for each form.\n if (entry.base_url) set(\"ANTHROPIC_FOUNDRY_BASE_URL\", entry.base_url);\n else set(\"ANTHROPIC_FOUNDRY_RESOURCE\", params?.resource);\n set(\"ANTHROPIC_FOUNDRY_API_KEY\", credential);\n break;\n }\n case \"anthropic\": {\n const baseUrl = normalizeAnthropicBaseUrl(resolveEntryBaseUrl(entry));\n if (baseUrl && baseUrl.toLowerCase() !== ANTHROPIC_DEFAULT_BASE_URL) {\n env.ANTHROPIC_BASE_URL = baseUrl;\n }\n if (kind === \"bearer\") set(\"ANTHROPIC_AUTH_TOKEN\", credential);\n else if (kind === \"api_key_header\") set(\"ANTHROPIC_API_KEY\", credential);\n if (!credential) {\n // `oauth` / `none` / an unresolved ref: the ambient carriers are the\n // only auth this session has, and the scrub just removed them.\n if (ambient.authToken) env.ANTHROPIC_AUTH_TOKEN = ambient.authToken;\n else set(\"ANTHROPIC_API_KEY\", ambient.apiKey);\n }\n break;\n }\n }\n\n return env;\n}\n","/**\n * Poisoned-transcript repair for the Claude Agent SDK driver.\n *\n * The Anthropic Messages API can permanently reject a conversation once its\n * persisted history contains a malformed content block. Because the bad block\n * lives in the SDK's on-disk JSONL transcript, every replayed turn fails with\n * the same `400 invalid_request_error` and the session is bricked with no\n * in-band recovery.\n *\n * This module repairs the transcript in place, covering three known poison\n * classes:\n *\n * 1. **Image `media_type` mismatch / omission.** An image block whose declared\n * `media_type` does not match — or is missing for — the actual bytes:\n * `... The image was specified using the image/png media type, but the\n * image appears to be a image/jpeg image`. Produced by the Claude Code\n * `Read` tool's format fallback (anthropics/claude-code#55338, #30124,\n * #33179). Repaired by sniffing the base64 magic bytes and correcting\n * `media_type`.\n * 2. **Oversized image.** An image whose decoded payload exceeds the API's\n * 5 MB per-image limit (anthropics/claude-code#34566). Replaced with a\n * text stub — the byte budget cannot be recovered any other way.\n * 3. **`cache_control` on an empty text block.** A text block carrying a\n * `cache_control` marker with empty/whitespace `text`\n * (anthropics/claude-code#59626). The `cache_control` field is stripped.\n *\n * Genuinely unidentifiable image blocks are also replaced with a text stub.\n *\n * Recovering by content scan (rather than parsing the API's `messages.N`\n * index) is deliberate: the index addresses the assembled API request, not a\n * JSONL line, and reproducing the SDK's message-assembly is fragile. A full\n * scan is index-free and repairs every poisoned block in one pass.\n *\n * **Async and line-streaming since #454.** A Claude Code transcript is routinely\n * multi-megabyte (base64 images inline in `tool_result` blocks), and this runs on\n * a failed turn *and before every resume* — inside the single-threaded `skaile\n * serve` loop. The previous `readFileSync` + `writeFileSync` + `renameSync` held\n * the loop for the whole file and materialised it twice over as one string. Both\n * passes now stream line by line off a `createReadStream`, so the loop is yielded\n * between lines and peak memory is one JSONL line rather than the whole file, and\n * every I/O phase is deadline-bounded.\n *\n * Streaming was chosen over a worker thread: the work is I/O-bound rather than\n * CPU-bound (per-line `JSON.parse` on a yielded loop is not what stalls a turn),\n * and a worker would add a structured-clone of the same multi-MB payload plus a\n * thread lifecycle to a path that must never block a turn.\n *\n * @module\n */\n\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport { readdir, rename, stat, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { fsDeadlineMs, tryWithFsDeadline, withFsDeadline } from \"@skaile/workspaces/core\";\n\n/**\n * Minimal logger shape accepted by {@link scrubPoisonedTranscript}. Compatible\n * with the bridge `Logger`, but narrowed so the helper stays unit-testable\n * without a real logger instance.\n *\n * @category Transcript repair\n */\nexport interface ScrubLogger {\n info(message: string, data?: Record<string, unknown>): void;\n warn(message: string, data?: Record<string, unknown>): void;\n}\n\n/**\n * Options for {@link scrubPoisonedTranscript}.\n *\n * @category Transcript repair\n */\nexport interface ScrubTranscriptOptions {\n /**\n * Claude Code config directory — the parent of `projects/`. Resolve from\n * `CLAUDE_CONFIG_DIR`, falling back to `~/.claude`.\n */\n configDir: string;\n /** SDK session id whose transcript JSONL should be repaired. */\n sessionId: string;\n /** Optional logger for diagnostics. */\n log?: ScrubLogger;\n /**\n * Where the transcript is read and written. Defaults to this process's own\n * filesystem access ({@link localTranscriptStore}); with the agent uid split\n * the transcript belongs to the agent uid and must be reached through it.\n */\n store?: TranscriptStore;\n}\n\n/**\n * Filesystem access to Claude Code transcripts. The CLI creates them 0600 in\n * 0700 dirs, so when it runs as a different uid than the runner, only that uid\n * can locate, read or rewrite them (see `agent-transcript.ts`).\n *\n * @category Transcript repair\n */\nexport interface TranscriptStore {\n /** Path of `<sessionId>.jsonl` under `<configDir>/projects/`, or `null` when absent. */\n locate(configDir: string, sessionId: string, timeoutMs?: number): Promise<string | null>;\n /** The file's contents as UTF-8 chunks. */\n read(filePath: string): AsyncIterable<string>;\n /** Atomically replace the file with `chunks` via a `.scrub-tmp` sibling. */\n replace(filePath: string, chunks: AsyncIterable<string>): Promise<void>;\n /** Remove the sibling a failed or abandoned {@link replace} left (best effort). */\n discardTemp(filePath: string): Promise<void>;\n}\n\n/**\n * Outcome of a {@link scrubPoisonedTranscript} pass.\n *\n * @category Transcript repair\n */\nexport interface ScrubTranscriptResult {\n /** The located JSONL transcript path, or `null` when not found. */\n filePath: string | null;\n /** Image blocks whose `media_type` was corrected (or filled in) to match the bytes. */\n corrected: number;\n /**\n * Image blocks replaced with a text stub — either unidentifiable bytes or a\n * payload over the API's 5 MB per-image limit.\n */\n stubbed: number;\n /** Empty text blocks from which a rejected `cache_control` marker was stripped. */\n cacheStripped: number;\n /**\n * `true` when the transcript was located, contained at least one poisoned\n * block, and was rewritten. `false` means nothing needed repair (or the\n * file was not found) — the caller should not retry the resume.\n */\n changed: boolean;\n}\n\n/** Text inserted in place of an image block whose format cannot be identified. */\nconst STUB_TEXT = \"[image removed: unprocessable image data]\";\n\n/** Text inserted in place of an image block that exceeds the API size limit. */\nconst STUB_TEXT_OVERSIZED = \"[image removed: image too large]\";\n\n/**\n * The Anthropic Messages API rejects any single image whose decoded payload\n * exceeds 5 MB. An image at or under this is left alone; a larger one is\n * stubbed (its byte budget cannot be recovered).\n */\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/**\n * Identify an image's media type from the leading bytes of its base64 payload.\n *\n * Recognises the four formats the Anthropic API accepts. Returns `null` when\n * the magic bytes match no known format — the caller treats that as a\n * genuinely corrupt block and stubs it.\n *\n * @param base64 - Base64-encoded image data (only the prefix is inspected).\n * @returns An `image/*` media type, or `null` when unrecognised.\n * @category Transcript repair\n */\nexport function sniffImageMediaType(base64: string): string | null {\n let buf: Buffer;\n try {\n // 32 base64 chars decode to 24 bytes — enough for the WebP check at 12.\n buf = Buffer.from(base64.slice(0, 32), \"base64\");\n } catch {\n return null;\n }\n if (buf.length < 4) {\n return null;\n }\n // JPEG — SOI marker `FF D8`. Third byte varies (and may be corrupt), so a\n // two-byte check is intentional: it still matches malformed JPEGs, which is\n // exactly the poison case the API flags as \"appears to be image/jpeg\".\n if (buf[0] === 0xff && buf[1] === 0xd8) {\n return \"image/jpeg\";\n }\n // PNG — `89 50 4E 47`.\n if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) {\n return \"image/png\";\n }\n // GIF — `47 49 46 38` (\"GIF8\").\n if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x38) {\n return \"image/gif\";\n }\n // WebP — `RIFF` at 0..3 and `WEBP` at 8..11.\n if (\n buf.length >= 12 &&\n buf[0] === 0x52 &&\n buf[1] === 0x49 &&\n buf[2] === 0x46 &&\n buf[3] === 0x46 &&\n buf[8] === 0x57 &&\n buf[9] === 0x45 &&\n buf[10] === 0x42 &&\n buf[11] === 0x50\n ) {\n return \"image/webp\";\n }\n return null;\n}\n\n/** A base64 image source on a content block (shape is SDK-defined). */\ninterface Base64ImageSource {\n type?: string;\n media_type?: string;\n data?: string;\n}\n\n/** Loosely-typed content block from a transcript message. */\ninterface ContentBlockLike {\n type?: string;\n source?: Base64ImageSource;\n content?: unknown;\n [k: string]: unknown;\n}\n\n/** Mutable counters threaded through one scrub pass. */\ninterface ScrubCounters {\n corrected: number;\n stubbed: number;\n cacheStripped: number;\n}\n\n/** Total repairs recorded in a counter set — used to detect per-line changes. */\nfunction totalChanges(c: ScrubCounters): number {\n return c.corrected + c.stubbed + c.cacheStripped;\n}\n\n/**\n * Repair a single content block. Returns the (possibly replaced) block.\n *\n * - A `tool_result` block recurses into its `content` array.\n * - A text block carrying a `cache_control` marker whose `text` is empty or\n * whitespace has the marker stripped (the API rejects `cache_control` on\n * empty text blocks).\n * - An image block whose decoded payload exceeds the API's 5 MB limit is\n * replaced with a text stub.\n * - An image block whose bytes match no known format is replaced with a text\n * stub (an image cannot simply be dropped — a `tool_result` must keep at\n * least one content entry, and a bare `image` block is replaced 1:1).\n * - An image block whose declared `media_type` mismatches (or is missing for)\n * the sniffed type is corrected in place.\n * - Every other block is returned untouched.\n */\nfunction scrubBlock(block: ContentBlockLike, counters: ScrubCounters): ContentBlockLike {\n if (block.type === \"tool_result\" && Array.isArray(block.content)) {\n return {\n ...block,\n content: (block.content as ContentBlockLike[]).map((inner) => scrubBlock(inner, counters)),\n };\n }\n\n // A `cache_control` marker on a text block whose text is empty or whitespace\n // is rejected by the API (\"cache_control cannot be set for empty text\n // blocks\"). Strip the marker — the empty block itself is harmless.\n if (block.type === \"text\" && block.cache_control != null) {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n if (text.trim() === \"\") {\n counters.cacheStripped++;\n const clone = { ...block };\n delete clone.cache_control;\n return clone;\n }\n }\n\n if (\n block.type === \"image\" &&\n block.source?.type === \"base64\" &&\n typeof block.source.data === \"string\"\n ) {\n const data = block.source.data;\n // The API rejects any image whose decoded payload exceeds 5 MB. The byte\n // budget cannot be salvaged, so the whole block becomes a text stub.\n // base64 encodes 3 bytes per 4 chars, so decoded length ≈ len * 3 / 4.\n if (Math.floor((data.length * 3) / 4) > MAX_IMAGE_BYTES) {\n counters.stubbed++;\n return { type: \"text\", text: STUB_TEXT_OVERSIZED };\n }\n const sniffed = sniffImageMediaType(data);\n if (sniffed === null) {\n counters.stubbed++;\n return { type: \"text\", text: STUB_TEXT };\n }\n if (sniffed !== block.source.media_type) {\n counters.corrected++;\n return { ...block, source: { ...block.source, media_type: sniffed } };\n }\n }\n\n return block;\n}\n\n/**\n * Locate the JSONL transcript for `sessionId` under `<configDir>/projects/`.\n *\n * Claude Code encodes the project directory into the `projects/` subfolder\n * name; rather than reproduce that encoding, this scans every subfolder for\n * `<sessionId>.jsonl` (the session id is a UUID — globally unique).\n *\n * Async and deadline-bounded since #454. The `existsSync(projectsDir)` probe is\n * gone: `readdir` already fails on a missing directory, so the probe was a\n * second stat on the same path for no information.\n *\n * `timeoutMs` defaults to {@link fsDeadlineMs} so callers that only need the\n * path (the resume probe) can omit it.\n *\n * @category Transcript repair\n */\nexport async function locateTranscriptPath(\n configDir: string,\n sessionId: string,\n timeoutMs: number = fsDeadlineMs(),\n): Promise<string | null> {\n const projectsDir = join(configDir, \"projects\");\n const entries = await tryWithFsDeadline(\n `readdir ${projectsDir}`,\n () => readdir(projectsDir),\n null,\n timeoutMs,\n );\n if (!entries) return null;\n for (const entry of entries) {\n const candidate = join(projectsDir, entry, `${sessionId}.jsonl`);\n const found = await tryWithFsDeadline(\n `stat ${candidate}`,\n async () => (await stat(candidate)).isFile(),\n false,\n timeoutMs,\n );\n if (found) return candidate;\n }\n return null;\n}\n\n/**\n * Yield a file's contents line by line, reproducing `readFileSync(...).split(\"\\n\")`\n * exactly — including the final (possibly empty) segment, so a trailing newline\n * survives a rewrite byte for byte.\n *\n * Splits on `\\n` alone, so a line out of a CRLF transcript arrives with its\n * `\\r` still attached. That carrier byte is part of the line here, and\n * {@link repairLine} re-attaches it to a line it rewrites — the file keeps the\n * terminator style it arrived with. Deliberately not `node:readline`:\n * `crlfDelay` strips the `\\r` outright (rewriting a CRLF transcript to LF) and\n * the interface swallows the trailing-newline distinction, either of which\n * would make the \"clean transcript is left byte-for-byte untouched\" guarantee\n * false. Only one line is held in memory at a time, so a multi-MB transcript\n * never materialises as a single string.\n */\nasync function* streamLines(chunks: AsyncIterable<string>): AsyncGenerator<string> {\n let pending = \"\";\n for await (const chunk of chunks) {\n pending += chunk;\n let idx = pending.indexOf(\"\\n\");\n while (idx !== -1) {\n yield pending.slice(0, idx);\n pending = pending.slice(idx + 1);\n idx = pending.indexOf(\"\\n\");\n }\n }\n yield pending;\n}\n\n/**\n * The runner's own filesystem access: the default {@link TranscriptStore}.\n *\n * @category Transcript repair\n */\nexport const localTranscriptStore: TranscriptStore = {\n locate: (configDir, sessionId, timeoutMs) =>\n locateTranscriptPath(configDir, sessionId, timeoutMs),\n async *read(filePath) {\n const stream = createReadStream(filePath, { encoding: \"utf8\" });\n try {\n for await (const chunk of stream) yield chunk as string;\n } finally {\n stream.destroy();\n }\n },\n async replace(filePath, chunks) {\n const tmpPath = `${filePath}.scrub-tmp`;\n await pipeline(chunks, createWriteStream(tmpPath, { encoding: \"utf8\" }));\n await rename(tmpPath, filePath);\n },\n async discardTemp(filePath) {\n const tmpPath = `${filePath}.scrub-tmp`;\n await tryWithFsDeadline(`unlink ${tmpPath}`, () => unlink(tmpPath), undefined, fsDeadlineMs());\n },\n};\n\n/**\n * Repair one JSONL line, returning the (possibly rewritten) line and mutating\n * `counters`. A non-JSON, blank, or content-less line is returned untouched.\n *\n * The reader splits on `\\n` only, so a line from a CRLF transcript still carries\n * its trailing `\\r`. An untouched line is returned verbatim and keeps it; a\n * rewritten one is rebuilt by `JSON.stringify`, which would drop it — leaving a\n * repaired CRLF transcript with mixed line endings. So the terminator is split\n * off before the parse and re-appended to the rewritten line.\n */\nfunction repairLine(line: string, counters: ScrubCounters): string {\n if (line.trim() === \"\") return line;\n const eol = line.endsWith(\"\\r\") ? \"\\r\" : \"\";\n const body = eol === \"\" ? line : line.slice(0, -1);\n let entry: { message?: { content?: unknown } };\n try {\n entry = JSON.parse(body);\n } catch {\n return line; // Not JSON — leave untouched.\n }\n const content = entry.message?.content;\n if (!Array.isArray(content)) return line;\n const before = totalChanges(counters);\n const scrubbed = (content as ContentBlockLike[]).map((block) => scrubBlock(block, counters));\n if (totalChanges(counters) === before) return line; // Nothing changed on this line.\n return `${JSON.stringify({ ...entry, message: { ...entry.message, content: scrubbed } })}${eol}`;\n}\n\n/**\n * Scan a Claude Code SDK transcript for image content blocks whose declared\n * `media_type` does not match the actual bytes, repair them, and atomically\n * rewrite the file.\n *\n * Safe to call after a turn has failed: the SDK query is dead at that point,\n * and the next resume re-reads the transcript from disk.\n *\n * **Async since #454.** Two streaming passes rather than one whole-file read:\n * pass 1 counts repairs without writing anything, and pass 2 runs only when\n * pass 1 found something. The common case — the preventive scrub of a clean\n * transcript before every resume — is therefore one streaming read and zero\n * writes, and a clean transcript is still left byte-for-byte untouched.\n *\n * @param opts - Config directory, session id, and an optional logger.\n * @returns A {@link ScrubTranscriptResult}. When `changed` is `true` the\n * caller may retry the resume with the same session id.\n * @category Transcript repair\n */\nexport async function scrubPoisonedTranscript(\n opts: ScrubTranscriptOptions,\n): Promise<ScrubTranscriptResult> {\n const { configDir, sessionId, log } = opts;\n const store = opts.store ?? localTranscriptStore;\n const timeoutMs = fsDeadlineMs();\n const result: ScrubTranscriptResult = {\n filePath: null,\n corrected: 0,\n stubbed: 0,\n cacheStripped: 0,\n changed: false,\n };\n\n let filePath: string | null;\n try {\n filePath = await store.locate(configDir, sessionId, timeoutMs);\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to locate transcript\", {\n configDir,\n sessionId,\n error: err instanceof Error ? err.message : String(err),\n });\n return result;\n }\n if (!filePath) {\n log?.warn(\"scrub-transcript: no transcript found\", { configDir, sessionId });\n return result;\n }\n result.filePath = filePath;\n\n // ── Pass 1: detect. Streams the transcript, counting repairs, writing nothing.\n const counters: ScrubCounters = { corrected: 0, stubbed: 0, cacheStripped: 0 };\n try {\n await withFsDeadline(\n `scan transcript ${filePath}`,\n async () => {\n for await (const line of streamLines(store.read(filePath))) repairLine(line, counters);\n },\n timeoutMs,\n );\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to read transcript\", {\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n return result;\n }\n\n result.corrected = counters.corrected;\n result.stubbed = counters.stubbed;\n result.cacheStripped = counters.cacheStripped;\n\n if (totalChanges(counters) === 0) {\n return result;\n }\n\n // ── Pass 2: rewrite. Atomic: stream a sibling temp file, then rename over the\n // original. Line separators are re-emitted exactly as pass 1 split them, so a\n // trailing newline and any blank lines survive verbatim.\n const source = filePath;\n try {\n await withFsDeadline(\n `rewrite transcript ${source}`,\n async () => {\n const discard: ScrubCounters = { corrected: 0, stubbed: 0, cacheStripped: 0 };\n await store.replace(\n source,\n (async function* () {\n let first = true;\n for await (const line of streamLines(store.read(source))) {\n yield first ? repairLine(line, discard) : `\\n${repairLine(line, discard)}`;\n first = false;\n }\n })(),\n );\n },\n timeoutMs,\n );\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to rewrite transcript\", {\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n // Never leave a half-written `.scrub-tmp` in the SDK's projects dir, also\n // when the deadline abandoned the replace mid-write.\n await store.discardTemp(source).catch(() => {});\n return result;\n }\n\n result.changed = true;\n log?.info(\"scrub-transcript: repaired poisoned transcript\", {\n filePath,\n corrected: result.corrected,\n stubbed: result.stubbed,\n cacheStripped: result.cacheStripped,\n });\n return result;\n}\n","import { type ChildProcess, spawn } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { fsDeadlineMs, withFsDeadline } from \"@skaile/workspaces/core\";\nimport { resolveAgentExec } from \"./agent-exec.js\";\nimport { localTranscriptStore, type TranscriptStore } from \"./drivers/scrub-transcript.js\";\n\n/**\n * Transcripts reached through the agent launch shim.\n *\n * With the uid split on, the Claude CLI runs as the agent uid and creates its\n * transcripts 0600 in 0700 dirs, so the runner can no longer list, read or\n * rewrite them itself. This store runs plain tools (`find`, `cat`, `sh`, `mv`)\n * as the agent uid through the shim instead. The child gets only `PATH` and\n * `LC_ALL`, never the runner's environment, and runs in `/` because the\n * runner's own cwd may not be enterable by the agent uid.\n */\nexport function agentTranscriptStore(shim: string): TranscriptStore {\n // A replace the scrub's deadline abandoned keeps running; discardTemp stops\n // it before removing its temp file.\n const inFlight = new Map<string, ChildProcess>();\n // Paths whose rewrite discardTemp gave up on: their rename must never run.\n const cancelled = new Set<string>();\n const track = (filePath: string, child: ChildProcess) => {\n inFlight.set(filePath, child);\n child.once(\"close\", () => {\n if (inFlight.get(filePath) === child) inFlight.delete(filePath);\n });\n };\n return {\n async locate(configDir, sessionId, timeoutMs = 10_000) {\n // A session id is a UUID; anything glob- or path-shaped is not ours.\n if (!/^[A-Za-z0-9._-]+$/.test(sessionId)) return null;\n const projectsDir = join(configDir, \"projects\");\n // Markers on stdout, not exit codes, carry the answer: a shim or launcher\n // failure has exit codes of its own and must never read as \"not found\".\n const { stdout } = await collect(\n runAsAgent(shim, [\n \"sh\",\n \"-c\",\n '[ -d \"$1\" ] || { echo \"@@no-projects\"; exit 0; }; ' +\n 'find \"$1\" -mindepth 2 -maxdepth 2 -type f -name \"$2\" -print -quit; echo \"@@find:$?\"',\n \"sh\",\n projectsDir,\n `${sessionId}.jsonl`,\n ]),\n timeoutMs,\n );\n const lines = stdout.split(\"\\n\").map((l) => l.trim());\n // A missing projects/ is the same \"not found\" as a failed readdir locally.\n if (lines.includes(\"@@no-projects\")) return null;\n const status = lines.find((l) => l.startsWith(\"@@find:\"));\n if (status === undefined)\n throw new Error(\"locating a transcript as the agent uid failed (no answer from the shim)\");\n // A path find printed counts even if it later hit an unreadable sibling.\n const found = lines.find((l) => l.startsWith(\"/\"));\n if (found) return found;\n if (status !== \"@@find:0\")\n throw new Error(`locating a transcript as the agent uid failed (${status.slice(2)})`);\n return null;\n },\n\n async *read(filePath) {\n const child = runAsAgent(shim, [\"cat\", \"--\", filePath]);\n const exited = exitOf(child);\n exited.catch(() => {}); // awaited below; this only stops an unhandled rejection\n const stderr = drain(child);\n child.stdout?.setEncoding(\"utf8\");\n for await (const chunk of child.stdout as AsyncIterable<string>) yield chunk;\n const code = await exited;\n if (code !== 0)\n throw new Error(`reading ${filePath} as the agent uid failed: ${await stderr}`);\n },\n\n async replace(filePath, chunks) {\n const child = runAsAgent(shim, [\n \"sh\",\n \"-c\",\n // 0600 like the CLI's own files. Only writes the temp file: the rename\n // is a separate step below, run only after the input was fully sent,\n // so a killed or starved writer can never commit a partial transcript.\n 'umask 077; cat > \"$1.scrub-tmp\"',\n \"sh\",\n filePath,\n ]);\n cancelled.delete(filePath);\n track(filePath, child);\n const exited = exitOf(child);\n exited.catch(() => {}); // awaited below; this only stops an unhandled rejection\n const stderr = drain(child);\n const stdin = child.stdin;\n if (!stdin) throw new Error(\"agent shim has no stdin\");\n // A child that dies early surfaces through its exit code, not an EPIPE crash.\n stdin.on(\"error\", () => {});\n const gone = exited.then(\n () => undefined,\n () => undefined,\n );\n // Stop pulling input as soon as the child is gone (killed by discardTemp,\n // or failed), instead of waiting on a producer that may never resume.\n const input = chunks[Symbol.asyncIterator]();\n let drained = false;\n try {\n for (;;) {\n const next = await Promise.race([\n input.next(),\n gone.then(() => ({ dead: true as const })),\n ]);\n if (\"dead\" in next || stdin.destroyed) break;\n if (next.done) {\n drained = true;\n break;\n }\n if (!stdin.write(next.value)) {\n await Promise.race([new Promise((resolve) => stdin.once(\"drain\", resolve)), gone]);\n }\n }\n } finally {\n stdin.end();\n // Close the producer too, so the reader feeding it (a `cat` through\n // the shim) is torn down rather than left blocked on a full pipe.\n if (!drained) void input.return?.()?.catch(() => {});\n }\n const code = await exited;\n if (code !== 0 || !drained)\n throw new Error(`rewriting ${filePath} as the agent uid failed: ${await stderr}`);\n if (cancelled.has(filePath)) throw new Error(`rewrite of ${filePath} was abandoned`);\n const mover = runAsAgent(shim, [\"mv\", \"-f\", \"--\", `${filePath}.scrub-tmp`, filePath]);\n track(filePath, mover);\n const moved = await collect(mover, 10_000);\n if (moved.code !== 0) throw new Error(`renaming the rewritten ${filePath} failed`);\n },\n\n async discardTemp(filePath) {\n // Before anything else, so a writer that is just finishing never renames.\n cancelled.add(filePath);\n const pending = inFlight.get(filePath);\n if (pending && pending.exitCode === null && pending.signalCode === null) {\n // The writer cannot commit (the rename is a separate step), so this only\n // stops it; bounded, since a writer stuck on a hung mount may never die.\n const closed = new Promise((resolve) => pending.once(\"close\", resolve));\n pending.kill(\"SIGKILL\");\n await withFsDeadline(`stop the rewrite of ${filePath}`, () => closed, fsDeadlineMs());\n }\n await collect(runAsAgent(shim, [\"rm\", \"-f\", \"--\", `${filePath}.scrub-tmp`]), 10_000);\n },\n };\n}\n\n/**\n * The transcript store for this runner: through the agent shim when\n * `SKAILE_AGENT_EXEC` is set, the runner's own filesystem otherwise.\n */\nexport function transcriptStoreForRuntime(\n env: Record<string, string | undefined> = process.env,\n): TranscriptStore {\n const shim = resolveAgentExec(env);\n return shim ? agentTranscriptStore(shim) : localTranscriptStore;\n}\n\nfunction runAsAgent(shim: string, argv: string[]): ChildProcess {\n return spawn(shim, [\"--\", ...argv], {\n cwd: \"/\",\n env: { PATH: process.env.PATH ?? \"/usr/bin:/bin\", LC_ALL: \"C\" },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n}\n\nfunction exitOf(child: ChildProcess): Promise<number> {\n return new Promise((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"close\", (code) => resolve(code ?? 1));\n });\n}\n\n/** Keep the last 1 KiB of stderr for the error message, and keep the pipe drained. */\nfunction drain(child: ChildProcess): Promise<string> {\n return new Promise((resolve) => {\n let tail = \"\";\n child.stderr?.setEncoding(\"utf8\");\n child.stderr?.on(\"data\", (c: string) => {\n tail = (tail + c).slice(-1024);\n });\n child.stderr?.once(\"close\", () => resolve(tail.trim()));\n });\n}\n\nasync function collect(\n child: ChildProcess,\n timeoutMs: number,\n): Promise<{ code: number; stdout: string }> {\n let stdout = \"\";\n child.stdout?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (c: string) => {\n stdout += c;\n });\n void drain(child);\n child.stdin?.end();\n let timer: NodeJS.Timeout | undefined;\n try {\n const code = await Promise.race([\n exitOf(child),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n reject(new Error(`agent shim did not answer within ${timeoutMs} ms`));\n }, timeoutMs);\n }),\n ]);\n return { code, stdout };\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Pre-first-turn resume probe for the Claude Agent SDK driver.\n *\n * A tier-1 native resume only hands its session id to the SDK inside the first\n * real turn, so the `jsonl_lost` outcome (\"No conversation found\") is invisible\n * until a turn is consumed. The runner shares the container filesystem with the\n * SDK, so a cheap `stat` of the on-disk JSONL transcript is an authoritative,\n * side-effect-free signal of whether the resume will find its history — no\n * probe query, no spurious model turn.\n *\n * @module\n */\n\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { withFsDeadline } from \"@skaile/workspaces/core\";\nimport { locateTranscriptPath } from \"./scrub-transcript.js\";\n\n/**\n * Overall wall-clock budget for the probe. Deliberately a small fraction of the\n * platform's `session_init_ack` timeout (`DEFAULT_INIT_ACK_TIMEOUT_MS`, 15s):\n * the probe runs synchronously on the pre-ack path, so a wedged\n * `CLAUDE_CONFIG_DIR` mount must never push the ack past its deadline.\n */\nconst RESUME_PROBE_TIMEOUT_MS = 2_000;\n\n/**\n * Outcome of {@link probeResumeTranscript}: whether the SDK transcript for a\n * requested tier-1 resume exists on disk.\n *\n * @category Resume probe\n */\nexport type ResumeProbeOutcome = \"transcript_found\" | \"jsonl_lost\";\n\n/**\n * Resolve the Claude Code config directory — the parent of `projects/` — from\n * an explicit env map, the process environment, or the `~/.claude` default.\n *\n * The runner's probe and the claude-sdk driver share this one resolver, so they\n * agree as long as they see the same `CLAUDE_CONFIG_DIR`. Today they do:\n * `CLAUDE_CONFIG_DIR` is container-scoped and neither side threads a per-session\n * override through `config.env`, so both fall through to `process.env`. If a\n * future change ever set the driver's `config.env.CLAUDE_CONFIG_DIR` to a\n * divergent path, the reactive `resume_failed { jsonl_lost }` turn remains the\n * safety net.\n *\n * @category Resume probe\n */\nexport function resolveClaudeConfigDir(env?: Record<string, string | undefined>): string {\n return env?.CLAUDE_CONFIG_DIR || process.env.CLAUDE_CONFIG_DIR || join(homedir(), \".claude\");\n}\n\n/**\n * Probe whether the SDK JSONL transcript for `sessionId` exists on disk.\n *\n * Non-null locator result → `transcript_found`; null → `jsonl_lost`;\n * `undefined` → outcome unknown (the probe exceeded its budget or errored). The\n * caller leaves the ack field ABSENT on `undefined` so the reactive\n * `resume_failed { jsonl_lost }` turn stays the safety net — a timed-out probe\n * must never masquerade as a genuine `jsonl_lost` and force a needless downgrade.\n *\n * `opts.timeoutMs` overrides {@link RESUME_PROBE_TIMEOUT_MS}; `opts.locate`\n * overrides the transcript locator (used by tests / alternate stores).\n *\n * @category Resume probe\n */\nexport async function probeResumeTranscript(\n sessionId: string,\n opts?: {\n env?: Record<string, string | undefined>;\n timeoutMs?: number;\n locate?: (configDir: string, sessionId: string) => Promise<string | null>;\n },\n): Promise<ResumeProbeOutcome | undefined> {\n const configDir = resolveClaudeConfigDir(opts?.env);\n const timeoutMs = opts?.timeoutMs ?? RESUME_PROBE_TIMEOUT_MS;\n const locate = opts?.locate ?? locateTranscriptPath;\n try {\n // Bound the whole probe on wall-clock and THROW on expiry: the inner per-op\n // deadline swallows a timeout into a null path (a false `jsonl_lost`), so a\n // wedged mount must yield \"unknown\" here rather than a spurious downgrade.\n const filePath = await withFsDeadline(\n `resume-probe ${sessionId}`,\n () => locate(configDir, sessionId),\n timeoutMs,\n );\n return filePath ? \"transcript_found\" : \"jsonl_lost\";\n } catch {\n return undefined;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../bridge/src/cloud.ts","../bridge/src/drivers/scrub-transcript.ts","../bridge/src/agent-transcript.ts","../bridge/src/drivers/resume-probe.ts"],"names":["join"],"mappings":"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","file":"chunk-QG3HOJEK.js","sourcesContent":["/**\n * AI endpoint transport for the `claude-sdk` driver — the Claude Agent SDK's\n * child-process environment.\n *\n * {@link buildClaudeEndpointEnv} takes an **AI provider registry entry** and\n * is what the driver calls, on every transport. It is plan §2.3's\n * `buildEndpointEnv` for the claude-sdk row (named for the driver because the\n * vars it emits — `CLAUDE_CODE_USE_*`, `ANTHROPIC_*` — are the Claude Agent\n * SDK's own contract, not a portable one).\n *\n * A registry entry says what the deleted `cloud` axis said — Amazon Bedrock,\n * Google Vertex AI, Azure AI Foundry, a generic gateway — with `surface` +\n * `transport` + `base_url` + `credential`, and says it for the direct\n * endpoint too, which the `cloud` axis could not address at all.\n *\n * Cross-repo contract: env key names and semantics here are load-bearing —\n * the platform resolves credential bundles against the same key set.\n */\n\nimport {\n type AIProviderEntry,\n type AIProviderLlmEntry,\n entryTransport,\n normalizeAnthropicBaseUrl,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\n\n/**\n * Env vars scrubbed from the inherited environment before an endpoint env is\n * assembled. Ambient first-party credentials or a stale `CLAUDE_CODE_USE_*`\n * flag must never leak into a session whose entry points elsewhere (the\n * ambient carriers are restored explicitly when the entry has none of its\n * own).\n *\n * Deliberately NOT exhaustive: ambient transport-specific vars (AWS_*,\n * GOOGLE_*, ANTHROPIC_VERTEX_PROJECT_ID, ANTHROPIC_FOUNDRY_*) survive so a\n * standalone CLI inherits its own signing chain; the SDK ignores vars whose\n * transport flag is unset.\n */\nconst SCRUBBED_ENV_KEYS = [\"ANTHROPIC_API_KEY\", \"ANTHROPIC_AUTH_TOKEN\", \"ANTHROPIC_BASE_URL\"];\n\n/**\n * The Anthropic first-party endpoint. An entry that resolves to exactly this\n * host needs no `ANTHROPIC_BASE_URL`: the SDK already points there, and an\n * explicit value would make every default session look like a third-party\n * redirect to Claude Code's own telemetry and auth heuristics.\n */\nexport const ANTHROPIC_DEFAULT_BASE_URL = \"https://api.anthropic.com\";\n\n/**\n * Headers the SDK owns and an entry must not restate through\n * `ANTHROPIC_CUSTOM_HEADERS`: the protocol version it was built against, and\n * the two credential carriers (which are `credential.ref`'s job — a literal\n * secret in `headers` is a validation error anyway).\n */\nconst SDK_OWNED_HEADERS: Record<string, true> = {\n \"anthropic-version\": true,\n authorization: true,\n \"x-api-key\": true,\n};\n\n/**\n * Which of the Claude Agent SDK's four native transports an entry addresses.\n *\n * The SDK has no `transport` field: it switches on a `CLAUDE_CODE_USE_*` flag.\n * Bedrock and Vertex are their own wire surfaces, so they are recognized by\n * `surface` as well as by `transport` — a legacy-derived entry that had no\n * region (and therefore no `params`, and therefore no `transport`) is still a\n * Bedrock session, exactly as it was before the registry existed.\n */\nexport type ClaudeEndpointMode = \"anthropic\" | \"bedrock\" | \"vertex\" | \"foundry\";\n\n/** Classify a registry entry into its {@link ClaudeEndpointMode}. */\nexport function claudeEndpointMode(entry: AIProviderEntry): ClaudeEndpointMode {\n const surface = (entry as AIProviderLlmEntry).surface;\n const transport = entryTransport(entry);\n if (surface === \"bedrock-converse-stream\" || transport === \"bedrock\") return \"bedrock\";\n if (surface === \"google-vertex\" || transport === \"vertex\") return \"vertex\";\n if (transport === \"foundry\") return \"foundry\";\n return \"anthropic\";\n}\n\n/** Arguments for {@link buildClaudeEndpointEnv}. */\nexport interface ClaudeEndpointEnvInput {\n /** The selected registry entry — the whole endpoint definition. */\n entry: AIProviderEntry;\n /**\n * The entry's credential, already resolved from its `credential.ref`\n * (`resolveEntryCredential`). Absent for `kind: none`, for an ambient\n * `sigv4` / `google_adc` / `azure_entra` chain, for `oauth` (whose blob the\n * runner writes to the Claude credentials file, never to the env), and for a\n * reference that did not resolve.\n */\n credential?: string;\n /**\n * The driver's base environment — `process.env` with `undefined` dropped.\n * The endpoint vars are layered **on top** of it, never instead of it, so\n * `PATH`, `HOME` and `SKAILE_SESSION_ID` reach the child.\n */\n baseEnv: Record<string, string>;\n /** `AgentConfig.env` plus any credential material the session carried. */\n configEnv?: Record<string, string>;\n}\n\n/**\n * Assemble the Claude Agent SDK child env for one registry entry (plan §2.3).\n *\n * Pure (no external state read, no input mutated). Starts from `baseEnv`\n * merged with `configEnv`, scrubs the inherited Anthropic credential/routing\n * vars and every `CLAUDE_CODE_USE_*` flag, then writes exactly what the entry\n * describes: at most one transport flag, the endpoint, and the credential in\n * the carrier its `kind` names.\n *\n * Credential kinds (§1.4): `api_key_header` → `ANTHROPIC_API_KEY` (the SDK\n * sends it as `x-api-key`); `bearer` → `ANTHROPIC_AUTH_TOKEN` (sent as\n * `Authorization: Bearer`); `sigv4` / `google_adc` / `azure_entra` emit\n * nothing and let the AWS/Google/Azure chain sign — which is why the scrub\n * deliberately spares ambient `AWS_*` / `GOOGLE_*` values; `oauth` and `none`\n * emit nothing, and the pre-scrub ambient carriers are restored so an OAuth or\n * shell-configured session keeps the auth it had.\n *\n * Never returns `undefined` or empty values; absent settings are omitted.\n */\nexport function buildClaudeEndpointEnv(args: ClaudeEndpointEnvInput): Record<string, string> {\n const { entry, credential, baseEnv, configEnv } = args;\n const env: Record<string, string> = { ...baseEnv, ...(configEnv ?? {}) };\n\n // Captured before the scrub — an entry with no credential material of its\n // own falls back to these, the way the gateway branch always has.\n const ambient = { authToken: env.ANTHROPIC_AUTH_TOKEN, apiKey: env.ANTHROPIC_API_KEY };\n\n for (const key of Object.keys(env)) {\n if (SCRUBBED_ENV_KEYS.includes(key) || key.startsWith(\"CLAUDE_CODE_USE_\")) {\n delete env[key];\n }\n }\n\n const set = (key: string, value: string | undefined) => {\n // Falsy check is deliberate: an empty-string credential/setting is never\n // valid env — dropping it beats shipping a key the SDK treats as set.\n if (value) env[key] = value;\n };\n\n const kind = entry.credential?.kind ?? \"none\";\n const params = (entry as AIProviderLlmEntry).params as Record<string, string> | undefined;\n\n // Static headers ride as ANTHROPIC_CUSTOM_HEADERS (`Name: Value` per line),\n // the only channel the SDK offers. An entry with none leaves an ambient\n // value alone.\n const headers = Object.entries(entry.headers ?? {}).filter(\n ([name]) => !SDK_OWNED_HEADERS[name.toLowerCase()],\n );\n if (headers.length > 0) {\n env.ANTHROPIC_CUSTOM_HEADERS = headers.map(([name, value]) => `${name}: ${value}`).join(\"\\n\");\n }\n\n switch (claudeEndpointMode(entry)) {\n case \"bedrock\": {\n env.CLAUDE_CODE_USE_BEDROCK = \"1\";\n // The AWS credential bundle itself is `configEnv` material (AWS_*), and\n // ambient AWS_* survived the scrub, so a standalone CLI keeps its own.\n set(\"AWS_REGION\", params?.region);\n break;\n }\n case \"vertex\": {\n env.CLAUDE_CODE_USE_VERTEX = \"1\";\n // GOOGLE_APPLICATION_CREDENTIALS is a path the runner materialized; it\n // arrives through `configEnv` or ambient, never from `credential`.\n set(\"ANTHROPIC_VERTEX_PROJECT_ID\", params?.project);\n set(\"CLOUD_ML_REGION\", params?.location);\n break;\n }\n case \"foundry\": {\n env.CLAUDE_CODE_USE_FOUNDRY = \"1\";\n // §1.3: an explicit `base_url` wins over the resource-derived endpoint,\n // and the SDK has a separate var for each form.\n if (entry.base_url) set(\"ANTHROPIC_FOUNDRY_BASE_URL\", entry.base_url);\n else set(\"ANTHROPIC_FOUNDRY_RESOURCE\", params?.resource);\n set(\"ANTHROPIC_FOUNDRY_API_KEY\", credential);\n break;\n }\n case \"anthropic\": {\n const baseUrl = normalizeAnthropicBaseUrl(resolveEntryBaseUrl(entry));\n if (baseUrl && baseUrl.toLowerCase() !== ANTHROPIC_DEFAULT_BASE_URL) {\n env.ANTHROPIC_BASE_URL = baseUrl;\n }\n if (kind === \"bearer\") set(\"ANTHROPIC_AUTH_TOKEN\", credential);\n else if (kind === \"api_key_header\") set(\"ANTHROPIC_API_KEY\", credential);\n if (!credential) {\n // `oauth` / `none` / an unresolved ref: the ambient carriers are the\n // only auth this session has, and the scrub just removed them.\n if (ambient.authToken) env.ANTHROPIC_AUTH_TOKEN = ambient.authToken;\n else set(\"ANTHROPIC_API_KEY\", ambient.apiKey);\n }\n break;\n }\n }\n\n return env;\n}\n","/**\n * Poisoned-transcript repair for the Claude Agent SDK driver.\n *\n * The Anthropic Messages API can permanently reject a conversation once its\n * persisted history contains a malformed content block. Because the bad block\n * lives in the SDK's on-disk JSONL transcript, every replayed turn fails with\n * the same `400 invalid_request_error` and the session is bricked with no\n * in-band recovery.\n *\n * This module repairs the transcript in place, covering three known poison\n * classes:\n *\n * 1. **Image `media_type` mismatch / omission.** An image block whose declared\n * `media_type` does not match — or is missing for — the actual bytes:\n * `... The image was specified using the image/png media type, but the\n * image appears to be a image/jpeg image`. Produced by the Claude Code\n * `Read` tool's format fallback (anthropics/claude-code#55338, #30124,\n * #33179). Repaired by sniffing the base64 magic bytes and correcting\n * `media_type`.\n * 2. **Oversized image.** An image whose decoded payload exceeds the API's\n * 5 MB per-image limit (anthropics/claude-code#34566). Replaced with a\n * text stub — the byte budget cannot be recovered any other way.\n * 3. **`cache_control` on an empty text block.** A text block carrying a\n * `cache_control` marker with empty/whitespace `text`\n * (anthropics/claude-code#59626). The `cache_control` field is stripped.\n *\n * Genuinely unidentifiable image blocks are also replaced with a text stub.\n *\n * Recovering by content scan (rather than parsing the API's `messages.N`\n * index) is deliberate: the index addresses the assembled API request, not a\n * JSONL line, and reproducing the SDK's message-assembly is fragile. A full\n * scan is index-free and repairs every poisoned block in one pass.\n *\n * **Async and line-streaming since #454.** A Claude Code transcript is routinely\n * multi-megabyte (base64 images inline in `tool_result` blocks), and this runs on\n * a failed turn *and before every resume* — inside the single-threaded `skaile\n * serve` loop. The previous `readFileSync` + `writeFileSync` + `renameSync` held\n * the loop for the whole file and materialised it twice over as one string. Both\n * passes now stream line by line off a `createReadStream`, so the loop is yielded\n * between lines and peak memory is one JSONL line rather than the whole file, and\n * every I/O phase is deadline-bounded.\n *\n * Streaming was chosen over a worker thread: the work is I/O-bound rather than\n * CPU-bound (per-line `JSON.parse` on a yielded loop is not what stalls a turn),\n * and a worker would add a structured-clone of the same multi-MB payload plus a\n * thread lifecycle to a path that must never block a turn.\n *\n * @module\n */\n\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport { readdir, rename, stat, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { fsDeadlineMs, tryWithFsDeadline, withFsDeadline } from \"@skaile/workspaces/core\";\n\n/**\n * Minimal logger shape accepted by {@link scrubPoisonedTranscript}. Compatible\n * with the bridge `Logger`, but narrowed so the helper stays unit-testable\n * without a real logger instance.\n *\n * @category Transcript repair\n */\nexport interface ScrubLogger {\n info(message: string, data?: Record<string, unknown>): void;\n warn(message: string, data?: Record<string, unknown>): void;\n}\n\n/**\n * Options for {@link scrubPoisonedTranscript}.\n *\n * @category Transcript repair\n */\nexport interface ScrubTranscriptOptions {\n /**\n * Claude Code config directory — the parent of `projects/`. Resolve from\n * `CLAUDE_CONFIG_DIR`, falling back to `~/.claude`.\n */\n configDir: string;\n /** SDK session id whose transcript JSONL should be repaired. */\n sessionId: string;\n /** Optional logger for diagnostics. */\n log?: ScrubLogger;\n /**\n * Where the transcript is read and written. Defaults to this process's own\n * filesystem access ({@link localTranscriptStore}); with the agent uid split\n * the transcript belongs to the agent uid and must be reached through it.\n */\n store?: TranscriptStore;\n}\n\n/**\n * Filesystem access to Claude Code transcripts. The CLI creates them 0600 in\n * 0700 dirs, so when it runs as a different uid than the runner, only that uid\n * can locate, read or rewrite them (see `agent-transcript.ts`).\n *\n * @category Transcript repair\n */\nexport interface TranscriptStore {\n /** Path of `<sessionId>.jsonl` under `<configDir>/projects/`, or `null` when absent. */\n locate(configDir: string, sessionId: string, timeoutMs?: number): Promise<string | null>;\n /** The file's contents as UTF-8 chunks. */\n read(filePath: string): AsyncIterable<string>;\n /** Atomically replace the file with `chunks` via a `.scrub-tmp` sibling. */\n replace(filePath: string, chunks: AsyncIterable<string>): Promise<void>;\n /** Remove the sibling a failed or abandoned {@link replace} left (best effort). */\n discardTemp(filePath: string): Promise<void>;\n}\n\n/**\n * Outcome of a {@link scrubPoisonedTranscript} pass.\n *\n * @category Transcript repair\n */\nexport interface ScrubTranscriptResult {\n /** The located JSONL transcript path, or `null` when not found. */\n filePath: string | null;\n /** Image blocks whose `media_type` was corrected (or filled in) to match the bytes. */\n corrected: number;\n /**\n * Image blocks replaced with a text stub — either unidentifiable bytes or a\n * payload over the API's 5 MB per-image limit.\n */\n stubbed: number;\n /** Empty text blocks from which a rejected `cache_control` marker was stripped. */\n cacheStripped: number;\n /**\n * `true` when the transcript was located, contained at least one poisoned\n * block, and was rewritten. `false` means nothing needed repair (or the\n * file was not found) — the caller should not retry the resume.\n */\n changed: boolean;\n}\n\n/** Text inserted in place of an image block whose format cannot be identified. */\nconst STUB_TEXT = \"[image removed: unprocessable image data]\";\n\n/** Text inserted in place of an image block that exceeds the API size limit. */\nconst STUB_TEXT_OVERSIZED = \"[image removed: image too large]\";\n\n/**\n * The Anthropic Messages API rejects any single image whose decoded payload\n * exceeds 5 MB. An image at or under this is left alone; a larger one is\n * stubbed (its byte budget cannot be recovered).\n */\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/**\n * Identify an image's media type from the leading bytes of its base64 payload.\n *\n * Recognises the four formats the Anthropic API accepts. Returns `null` when\n * the magic bytes match no known format — the caller treats that as a\n * genuinely corrupt block and stubs it.\n *\n * @param base64 - Base64-encoded image data (only the prefix is inspected).\n * @returns An `image/*` media type, or `null` when unrecognised.\n * @category Transcript repair\n */\nexport function sniffImageMediaType(base64: string): string | null {\n let buf: Buffer;\n try {\n // 32 base64 chars decode to 24 bytes — enough for the WebP check at 12.\n buf = Buffer.from(base64.slice(0, 32), \"base64\");\n } catch {\n return null;\n }\n if (buf.length < 4) {\n return null;\n }\n // JPEG — SOI marker `FF D8`. Third byte varies (and may be corrupt), so a\n // two-byte check is intentional: it still matches malformed JPEGs, which is\n // exactly the poison case the API flags as \"appears to be image/jpeg\".\n if (buf[0] === 0xff && buf[1] === 0xd8) {\n return \"image/jpeg\";\n }\n // PNG — `89 50 4E 47`.\n if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) {\n return \"image/png\";\n }\n // GIF — `47 49 46 38` (\"GIF8\").\n if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x38) {\n return \"image/gif\";\n }\n // WebP — `RIFF` at 0..3 and `WEBP` at 8..11.\n if (\n buf.length >= 12 &&\n buf[0] === 0x52 &&\n buf[1] === 0x49 &&\n buf[2] === 0x46 &&\n buf[3] === 0x46 &&\n buf[8] === 0x57 &&\n buf[9] === 0x45 &&\n buf[10] === 0x42 &&\n buf[11] === 0x50\n ) {\n return \"image/webp\";\n }\n return null;\n}\n\n/** A base64 image source on a content block (shape is SDK-defined). */\ninterface Base64ImageSource {\n type?: string;\n media_type?: string;\n data?: string;\n}\n\n/** Loosely-typed content block from a transcript message. */\ninterface ContentBlockLike {\n type?: string;\n source?: Base64ImageSource;\n content?: unknown;\n [k: string]: unknown;\n}\n\n/** Mutable counters threaded through one scrub pass. */\ninterface ScrubCounters {\n corrected: number;\n stubbed: number;\n cacheStripped: number;\n}\n\n/** Total repairs recorded in a counter set — used to detect per-line changes. */\nfunction totalChanges(c: ScrubCounters): number {\n return c.corrected + c.stubbed + c.cacheStripped;\n}\n\n/**\n * Repair a single content block. Returns the (possibly replaced) block.\n *\n * - A `tool_result` block recurses into its `content` array.\n * - A text block carrying a `cache_control` marker whose `text` is empty or\n * whitespace has the marker stripped (the API rejects `cache_control` on\n * empty text blocks).\n * - An image block whose decoded payload exceeds the API's 5 MB limit is\n * replaced with a text stub.\n * - An image block whose bytes match no known format is replaced with a text\n * stub (an image cannot simply be dropped — a `tool_result` must keep at\n * least one content entry, and a bare `image` block is replaced 1:1).\n * - An image block whose declared `media_type` mismatches (or is missing for)\n * the sniffed type is corrected in place.\n * - Every other block is returned untouched.\n */\nfunction scrubBlock(block: ContentBlockLike, counters: ScrubCounters): ContentBlockLike {\n if (block.type === \"tool_result\" && Array.isArray(block.content)) {\n return {\n ...block,\n content: (block.content as ContentBlockLike[]).map((inner) => scrubBlock(inner, counters)),\n };\n }\n\n // A `cache_control` marker on a text block whose text is empty or whitespace\n // is rejected by the API (\"cache_control cannot be set for empty text\n // blocks\"). Strip the marker — the empty block itself is harmless.\n if (block.type === \"text\" && block.cache_control != null) {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n if (text.trim() === \"\") {\n counters.cacheStripped++;\n const clone = { ...block };\n delete clone.cache_control;\n return clone;\n }\n }\n\n if (\n block.type === \"image\" &&\n block.source?.type === \"base64\" &&\n typeof block.source.data === \"string\"\n ) {\n const data = block.source.data;\n // The API rejects any image whose decoded payload exceeds 5 MB. The byte\n // budget cannot be salvaged, so the whole block becomes a text stub.\n // base64 encodes 3 bytes per 4 chars, so decoded length ≈ len * 3 / 4.\n if (Math.floor((data.length * 3) / 4) > MAX_IMAGE_BYTES) {\n counters.stubbed++;\n return { type: \"text\", text: STUB_TEXT_OVERSIZED };\n }\n const sniffed = sniffImageMediaType(data);\n if (sniffed === null) {\n counters.stubbed++;\n return { type: \"text\", text: STUB_TEXT };\n }\n if (sniffed !== block.source.media_type) {\n counters.corrected++;\n return { ...block, source: { ...block.source, media_type: sniffed } };\n }\n }\n\n return block;\n}\n\n/**\n * Locate the JSONL transcript for `sessionId` under `<configDir>/projects/`.\n *\n * Claude Code encodes the project directory into the `projects/` subfolder\n * name; rather than reproduce that encoding, this scans every subfolder for\n * `<sessionId>.jsonl` (the session id is a UUID — globally unique).\n *\n * Async and deadline-bounded since #454. The `existsSync(projectsDir)` probe is\n * gone: `readdir` already fails on a missing directory, so the probe was a\n * second stat on the same path for no information.\n *\n * `timeoutMs` defaults to {@link fsDeadlineMs} so callers that only need the\n * path (the resume probe) can omit it.\n *\n * @category Transcript repair\n */\nexport async function locateTranscriptPath(\n configDir: string,\n sessionId: string,\n timeoutMs: number = fsDeadlineMs(),\n): Promise<string | null> {\n const projectsDir = join(configDir, \"projects\");\n const entries = await tryWithFsDeadline(\n `readdir ${projectsDir}`,\n () => readdir(projectsDir),\n null,\n timeoutMs,\n );\n if (!entries) return null;\n for (const entry of entries) {\n const candidate = join(projectsDir, entry, `${sessionId}.jsonl`);\n const found = await tryWithFsDeadline(\n `stat ${candidate}`,\n async () => (await stat(candidate)).isFile(),\n false,\n timeoutMs,\n );\n if (found) return candidate;\n }\n return null;\n}\n\n/**\n * Yield a file's contents line by line, reproducing `readFileSync(...).split(\"\\n\")`\n * exactly — including the final (possibly empty) segment, so a trailing newline\n * survives a rewrite byte for byte.\n *\n * Splits on `\\n` alone, so a line out of a CRLF transcript arrives with its\n * `\\r` still attached. That carrier byte is part of the line here, and\n * {@link repairLine} re-attaches it to a line it rewrites — the file keeps the\n * terminator style it arrived with. Deliberately not `node:readline`:\n * `crlfDelay` strips the `\\r` outright (rewriting a CRLF transcript to LF) and\n * the interface swallows the trailing-newline distinction, either of which\n * would make the \"clean transcript is left byte-for-byte untouched\" guarantee\n * false. Only one line is held in memory at a time, so a multi-MB transcript\n * never materialises as a single string.\n */\nasync function* streamLines(chunks: AsyncIterable<string>): AsyncGenerator<string> {\n let pending = \"\";\n for await (const chunk of chunks) {\n pending += chunk;\n let idx = pending.indexOf(\"\\n\");\n while (idx !== -1) {\n yield pending.slice(0, idx);\n pending = pending.slice(idx + 1);\n idx = pending.indexOf(\"\\n\");\n }\n }\n yield pending;\n}\n\n/**\n * The runner's own filesystem access: the default {@link TranscriptStore}.\n *\n * @category Transcript repair\n */\nexport const localTranscriptStore: TranscriptStore = {\n locate: (configDir, sessionId, timeoutMs) =>\n locateTranscriptPath(configDir, sessionId, timeoutMs),\n async *read(filePath) {\n const stream = createReadStream(filePath, { encoding: \"utf8\" });\n try {\n for await (const chunk of stream) yield chunk as string;\n } finally {\n stream.destroy();\n }\n },\n async replace(filePath, chunks) {\n const tmpPath = `${filePath}.scrub-tmp`;\n await pipeline(chunks, createWriteStream(tmpPath, { encoding: \"utf8\" }));\n await rename(tmpPath, filePath);\n },\n async discardTemp(filePath) {\n const tmpPath = `${filePath}.scrub-tmp`;\n await tryWithFsDeadline(`unlink ${tmpPath}`, () => unlink(tmpPath), undefined, fsDeadlineMs());\n },\n};\n\n/**\n * Repair one JSONL line, returning the (possibly rewritten) line and mutating\n * `counters`. A non-JSON, blank, or content-less line is returned untouched.\n *\n * The reader splits on `\\n` only, so a line from a CRLF transcript still carries\n * its trailing `\\r`. An untouched line is returned verbatim and keeps it; a\n * rewritten one is rebuilt by `JSON.stringify`, which would drop it — leaving a\n * repaired CRLF transcript with mixed line endings. So the terminator is split\n * off before the parse and re-appended to the rewritten line.\n */\nfunction repairLine(line: string, counters: ScrubCounters): string {\n if (line.trim() === \"\") return line;\n const eol = line.endsWith(\"\\r\") ? \"\\r\" : \"\";\n const body = eol === \"\" ? line : line.slice(0, -1);\n let entry: { message?: { content?: unknown } };\n try {\n entry = JSON.parse(body);\n } catch {\n return line; // Not JSON — leave untouched.\n }\n const content = entry.message?.content;\n if (!Array.isArray(content)) return line;\n const before = totalChanges(counters);\n const scrubbed = (content as ContentBlockLike[]).map((block) => scrubBlock(block, counters));\n if (totalChanges(counters) === before) return line; // Nothing changed on this line.\n return `${JSON.stringify({ ...entry, message: { ...entry.message, content: scrubbed } })}${eol}`;\n}\n\n/**\n * Scan a Claude Code SDK transcript for image content blocks whose declared\n * `media_type` does not match the actual bytes, repair them, and atomically\n * rewrite the file.\n *\n * Safe to call after a turn has failed: the SDK query is dead at that point,\n * and the next resume re-reads the transcript from disk.\n *\n * **Async since #454.** Two streaming passes rather than one whole-file read:\n * pass 1 counts repairs without writing anything, and pass 2 runs only when\n * pass 1 found something. The common case — the preventive scrub of a clean\n * transcript before every resume — is therefore one streaming read and zero\n * writes, and a clean transcript is still left byte-for-byte untouched.\n *\n * @param opts - Config directory, session id, and an optional logger.\n * @returns A {@link ScrubTranscriptResult}. When `changed` is `true` the\n * caller may retry the resume with the same session id.\n * @category Transcript repair\n */\nexport async function scrubPoisonedTranscript(\n opts: ScrubTranscriptOptions,\n): Promise<ScrubTranscriptResult> {\n const { configDir, sessionId, log } = opts;\n const store = opts.store ?? localTranscriptStore;\n const timeoutMs = fsDeadlineMs();\n const result: ScrubTranscriptResult = {\n filePath: null,\n corrected: 0,\n stubbed: 0,\n cacheStripped: 0,\n changed: false,\n };\n\n let filePath: string | null;\n try {\n filePath = await store.locate(configDir, sessionId, timeoutMs);\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to locate transcript\", {\n configDir,\n sessionId,\n error: err instanceof Error ? err.message : String(err),\n });\n return result;\n }\n if (!filePath) {\n log?.warn(\"scrub-transcript: no transcript found\", { configDir, sessionId });\n return result;\n }\n result.filePath = filePath;\n\n // ── Pass 1: detect. Streams the transcript, counting repairs, writing nothing.\n const counters: ScrubCounters = { corrected: 0, stubbed: 0, cacheStripped: 0 };\n try {\n await withFsDeadline(\n `scan transcript ${filePath}`,\n async () => {\n for await (const line of streamLines(store.read(filePath))) repairLine(line, counters);\n },\n timeoutMs,\n );\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to read transcript\", {\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n return result;\n }\n\n result.corrected = counters.corrected;\n result.stubbed = counters.stubbed;\n result.cacheStripped = counters.cacheStripped;\n\n if (totalChanges(counters) === 0) {\n return result;\n }\n\n // ── Pass 2: rewrite. Atomic: stream a sibling temp file, then rename over the\n // original. Line separators are re-emitted exactly as pass 1 split them, so a\n // trailing newline and any blank lines survive verbatim.\n const source = filePath;\n try {\n await withFsDeadline(\n `rewrite transcript ${source}`,\n async () => {\n const discard: ScrubCounters = { corrected: 0, stubbed: 0, cacheStripped: 0 };\n await store.replace(\n source,\n (async function* () {\n let first = true;\n for await (const line of streamLines(store.read(source))) {\n yield first ? repairLine(line, discard) : `\\n${repairLine(line, discard)}`;\n first = false;\n }\n })(),\n );\n },\n timeoutMs,\n );\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to rewrite transcript\", {\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n // Never leave a half-written `.scrub-tmp` in the SDK's projects dir, also\n // when the deadline abandoned the replace mid-write.\n await store.discardTemp(source).catch(() => {});\n return result;\n }\n\n result.changed = true;\n log?.info(\"scrub-transcript: repaired poisoned transcript\", {\n filePath,\n corrected: result.corrected,\n stubbed: result.stubbed,\n cacheStripped: result.cacheStripped,\n });\n return result;\n}\n","import { type ChildProcess, spawn } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { fsDeadlineMs, withFsDeadline } from \"@skaile/workspaces/core\";\nimport { resolveAgentExec } from \"./agent-exec.js\";\nimport { localTranscriptStore, type TranscriptStore } from \"./drivers/scrub-transcript.js\";\n\n/**\n * Transcripts reached through the agent launch shim.\n *\n * With the uid split on, the Claude CLI runs as the agent uid and creates its\n * transcripts 0600 in 0700 dirs, so the runner can no longer list, read or\n * rewrite them itself. This store runs plain tools (`find`, `cat`, `sh`, `mv`)\n * as the agent uid through the shim instead. The child gets only `PATH` and\n * `LC_ALL`, never the runner's environment, and runs in `/` because the\n * runner's own cwd may not be enterable by the agent uid.\n */\nexport function agentTranscriptStore(shim: string): TranscriptStore {\n // A replace the scrub's deadline abandoned keeps running; discardTemp stops\n // it before removing its temp file.\n const inFlight = new Map<string, ChildProcess>();\n // Paths whose rewrite discardTemp gave up on: their rename must never run.\n const cancelled = new Set<string>();\n const track = (filePath: string, child: ChildProcess) => {\n inFlight.set(filePath, child);\n child.once(\"close\", () => {\n if (inFlight.get(filePath) === child) inFlight.delete(filePath);\n });\n };\n return {\n async locate(configDir, sessionId, timeoutMs = 10_000) {\n // A session id is a UUID; anything glob- or path-shaped is not ours.\n if (!/^[A-Za-z0-9._-]+$/.test(sessionId)) return null;\n const projectsDir = join(configDir, \"projects\");\n // Markers on stdout, not exit codes, carry the answer: a shim or launcher\n // failure has exit codes of its own and must never read as \"not found\".\n const { stdout } = await collect(\n runAsAgent(shim, [\n \"sh\",\n \"-c\",\n '[ -d \"$1\" ] || { echo \"@@no-projects\"; exit 0; }; ' +\n 'find \"$1\" -mindepth 2 -maxdepth 2 -type f -name \"$2\" -print -quit; echo \"@@find:$?\"',\n \"sh\",\n projectsDir,\n `${sessionId}.jsonl`,\n ]),\n timeoutMs,\n );\n const lines = stdout.split(\"\\n\").map((l) => l.trim());\n // A missing projects/ is the same \"not found\" as a failed readdir locally.\n if (lines.includes(\"@@no-projects\")) return null;\n const status = lines.find((l) => l.startsWith(\"@@find:\"));\n if (status === undefined)\n throw new Error(\"locating a transcript as the agent uid failed (no answer from the shim)\");\n // A path find printed counts even if it later hit an unreadable sibling.\n const found = lines.find((l) => l.startsWith(\"/\"));\n if (found) return found;\n if (status !== \"@@find:0\")\n throw new Error(`locating a transcript as the agent uid failed (${status.slice(2)})`);\n return null;\n },\n\n async *read(filePath) {\n const child = runAsAgent(shim, [\"cat\", \"--\", filePath]);\n const exited = exitOf(child);\n exited.catch(() => {}); // awaited below; this only stops an unhandled rejection\n const stderr = drain(child);\n child.stdout?.setEncoding(\"utf8\");\n for await (const chunk of child.stdout as AsyncIterable<string>) yield chunk;\n const code = await exited;\n if (code !== 0)\n throw new Error(`reading ${filePath} as the agent uid failed: ${await stderr}`);\n },\n\n async replace(filePath, chunks) {\n const child = runAsAgent(shim, [\n \"sh\",\n \"-c\",\n // 0600 like the CLI's own files. Only writes the temp file: the rename\n // is a separate step below, run only after the input was fully sent,\n // so a killed or starved writer can never commit a partial transcript.\n 'umask 077; cat > \"$1.scrub-tmp\"',\n \"sh\",\n filePath,\n ]);\n cancelled.delete(filePath);\n track(filePath, child);\n const exited = exitOf(child);\n exited.catch(() => {}); // awaited below; this only stops an unhandled rejection\n const stderr = drain(child);\n const stdin = child.stdin;\n if (!stdin) throw new Error(\"agent shim has no stdin\");\n // A child that dies early surfaces through its exit code, not an EPIPE crash.\n stdin.on(\"error\", () => {});\n const gone = exited.then(\n () => undefined,\n () => undefined,\n );\n // Stop pulling input as soon as the child is gone (killed by discardTemp,\n // or failed), instead of waiting on a producer that may never resume.\n const input = chunks[Symbol.asyncIterator]();\n let drained = false;\n try {\n for (;;) {\n const next = await Promise.race([\n input.next(),\n gone.then(() => ({ dead: true as const })),\n ]);\n if (\"dead\" in next || stdin.destroyed) break;\n if (next.done) {\n drained = true;\n break;\n }\n if (!stdin.write(next.value)) {\n await Promise.race([new Promise((resolve) => stdin.once(\"drain\", resolve)), gone]);\n }\n }\n } finally {\n stdin.end();\n // Close the producer too, so the reader feeding it (a `cat` through\n // the shim) is torn down rather than left blocked on a full pipe.\n if (!drained) void input.return?.()?.catch(() => {});\n }\n const code = await exited;\n if (code !== 0 || !drained)\n throw new Error(`rewriting ${filePath} as the agent uid failed: ${await stderr}`);\n if (cancelled.has(filePath)) throw new Error(`rewrite of ${filePath} was abandoned`);\n const mover = runAsAgent(shim, [\"mv\", \"-f\", \"--\", `${filePath}.scrub-tmp`, filePath]);\n track(filePath, mover);\n const moved = await collect(mover, 10_000);\n if (moved.code !== 0) throw new Error(`renaming the rewritten ${filePath} failed`);\n },\n\n async discardTemp(filePath) {\n // Before anything else, so a writer that is just finishing never renames.\n cancelled.add(filePath);\n const pending = inFlight.get(filePath);\n if (pending && pending.exitCode === null && pending.signalCode === null) {\n // The writer cannot commit (the rename is a separate step), so this only\n // stops it; bounded, since a writer stuck on a hung mount may never die.\n const closed = new Promise((resolve) => pending.once(\"close\", resolve));\n pending.kill(\"SIGKILL\");\n await withFsDeadline(`stop the rewrite of ${filePath}`, () => closed, fsDeadlineMs());\n }\n await collect(runAsAgent(shim, [\"rm\", \"-f\", \"--\", `${filePath}.scrub-tmp`]), 10_000);\n },\n };\n}\n\n/**\n * The transcript store for this runner: through the agent shim when\n * `SKAILE_AGENT_EXEC` is set, the runner's own filesystem otherwise.\n */\nexport function transcriptStoreForRuntime(\n env: Record<string, string | undefined> = process.env,\n): TranscriptStore {\n const shim = resolveAgentExec(env);\n return shim ? agentTranscriptStore(shim) : localTranscriptStore;\n}\n\nfunction runAsAgent(shim: string, argv: string[]): ChildProcess {\n return spawn(shim, [\"--\", ...argv], {\n cwd: \"/\",\n env: { PATH: process.env.PATH ?? \"/usr/bin:/bin\", LC_ALL: \"C\" },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n}\n\nfunction exitOf(child: ChildProcess): Promise<number> {\n return new Promise((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"close\", (code) => resolve(code ?? 1));\n });\n}\n\n/** Keep the last 1 KiB of stderr for the error message, and keep the pipe drained. */\nfunction drain(child: ChildProcess): Promise<string> {\n return new Promise((resolve) => {\n let tail = \"\";\n child.stderr?.setEncoding(\"utf8\");\n child.stderr?.on(\"data\", (c: string) => {\n tail = (tail + c).slice(-1024);\n });\n child.stderr?.once(\"close\", () => resolve(tail.trim()));\n });\n}\n\nasync function collect(\n child: ChildProcess,\n timeoutMs: number,\n): Promise<{ code: number; stdout: string }> {\n let stdout = \"\";\n child.stdout?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (c: string) => {\n stdout += c;\n });\n void drain(child);\n child.stdin?.end();\n let timer: NodeJS.Timeout | undefined;\n try {\n const code = await Promise.race([\n exitOf(child),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n reject(new Error(`agent shim did not answer within ${timeoutMs} ms`));\n }, timeoutMs);\n }),\n ]);\n return { code, stdout };\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Pre-first-turn resume probe for the Claude Agent SDK driver.\n *\n * A tier-1 native resume only hands its session id to the SDK inside the first\n * real turn, so the `jsonl_lost` outcome (\"No conversation found\") is invisible\n * until a turn is consumed. The runner shares the container filesystem with the\n * SDK, so a cheap `stat` of the on-disk JSONL transcript is an authoritative,\n * side-effect-free signal of whether the resume will find its history — no\n * probe query, no spurious model turn.\n *\n * @module\n */\n\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { withFsDeadline } from \"@skaile/workspaces/core\";\nimport { locateTranscriptPath } from \"./scrub-transcript.js\";\n\n/**\n * Overall wall-clock budget for the probe. Deliberately a small fraction of the\n * platform's `session_init_ack` timeout (`DEFAULT_INIT_ACK_TIMEOUT_MS`, 15s):\n * the probe runs synchronously on the pre-ack path, so a wedged\n * `CLAUDE_CONFIG_DIR` mount must never push the ack past its deadline.\n */\nconst RESUME_PROBE_TIMEOUT_MS = 2_000;\n\n/**\n * Outcome of {@link probeResumeTranscript}: whether the SDK transcript for a\n * requested tier-1 resume exists on disk.\n *\n * @category Resume probe\n */\nexport type ResumeProbeOutcome = \"transcript_found\" | \"jsonl_lost\";\n\n/**\n * Resolve the Claude Code config directory — the parent of `projects/` — from\n * an explicit env map, the process environment, or the `~/.claude` default.\n *\n * The runner's probe and the claude-sdk driver share this one resolver, so they\n * agree as long as they see the same `CLAUDE_CONFIG_DIR`. Today they do:\n * `CLAUDE_CONFIG_DIR` is container-scoped and neither side threads a per-session\n * override through `config.env`, so both fall through to `process.env`. If a\n * future change ever set the driver's `config.env.CLAUDE_CONFIG_DIR` to a\n * divergent path, the reactive `resume_failed { jsonl_lost }` turn remains the\n * safety net.\n *\n * @category Resume probe\n */\nexport function resolveClaudeConfigDir(env?: Record<string, string | undefined>): string {\n return env?.CLAUDE_CONFIG_DIR || process.env.CLAUDE_CONFIG_DIR || join(homedir(), \".claude\");\n}\n\n/**\n * Probe whether the SDK JSONL transcript for `sessionId` exists on disk.\n *\n * Non-null locator result → `transcript_found`; null → `jsonl_lost`;\n * `undefined` → outcome unknown (the probe exceeded its budget or errored). The\n * caller leaves the ack field ABSENT on `undefined` so the reactive\n * `resume_failed { jsonl_lost }` turn stays the safety net — a timed-out probe\n * must never masquerade as a genuine `jsonl_lost` and force a needless downgrade.\n *\n * `opts.timeoutMs` overrides {@link RESUME_PROBE_TIMEOUT_MS}; `opts.locate`\n * overrides the transcript locator (used by tests / alternate stores).\n *\n * @category Resume probe\n */\nexport async function probeResumeTranscript(\n sessionId: string,\n opts?: {\n env?: Record<string, string | undefined>;\n timeoutMs?: number;\n locate?: (configDir: string, sessionId: string) => Promise<string | null>;\n },\n): Promise<ResumeProbeOutcome | undefined> {\n const configDir = resolveClaudeConfigDir(opts?.env);\n const timeoutMs = opts?.timeoutMs ?? RESUME_PROBE_TIMEOUT_MS;\n const locate = opts?.locate ?? locateTranscriptPath;\n try {\n // Bound the whole probe on wall-clock and THROW on expiry: the inner per-op\n // deadline swallows a timeout into a null path (a false `jsonl_lost`), so a\n // wedged mount must yield \"unknown\" here rather than a spurious downgrade.\n const filePath = await withFsDeadline(\n `resume-probe ${sessionId}`,\n () => locate(configDir, sessionId),\n timeoutMs,\n );\n return filePath ? \"transcript_found\" : \"jsonl_lost\";\n } catch {\n return undefined;\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { flowKindProvider } from './chunk-
|
|
2
|
-
import { knowledgeKindProvider } from './chunk-
|
|
3
|
-
import { createDefaultKindRegistry } from './chunk-
|
|
1
|
+
import { flowKindProvider } from './chunk-7I5VRVDP.js';
|
|
2
|
+
import { knowledgeKindProvider } from './chunk-3BEY4WK3.js';
|
|
3
|
+
import { createDefaultKindRegistry } from './chunk-GEWAIQZ5.js';
|
|
4
4
|
|
|
5
5
|
// cli/src/open-registry.ts
|
|
6
6
|
var registry;
|
|
@@ -13,5 +13,5 @@ function getKnownKinds() {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export { getKindRegistry, getKnownKinds };
|
|
16
|
-
//# sourceMappingURL=chunk-
|
|
17
|
-
//# sourceMappingURL=chunk-
|
|
16
|
+
//# sourceMappingURL=chunk-SBFW3CJH.js.map
|
|
17
|
+
//# sourceMappingURL=chunk-SBFW3CJH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/open-registry.ts"],"names":[],"mappings":";;;;;AAgBA,IAAI,QAAA;AAQG,SAAS,eAAA,GAAqC;AACnD,EAAA,QAAA,KAAa,yBAAA,CAA0B,CAAC,gBAAA,EAAkB,qBAAqB,CAAC,CAAA;AAChF,EAAA,OAAO,QAAA;AACT;AAGO,SAAS,aAAA,GAAqC;AACnD,EAAA,OAAO,IAAI,GAAA,CAAI,eAAA,EAAgB,CAAE,aAAa,CAAA;AAChD","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../cli/src/open-registry.ts"],"names":[],"mappings":";;;;;AAgBA,IAAI,QAAA;AAQG,SAAS,eAAA,GAAqC;AACnD,EAAA,QAAA,KAAa,yBAAA,CAA0B,CAAC,gBAAA,EAAkB,qBAAqB,CAAC,CAAA;AAChF,EAAA,OAAO,QAAA;AACT;AAGO,SAAS,aAAA,GAAqC;AACnD,EAAA,OAAO,IAAI,GAAA,CAAI,eAAA,EAAgB,CAAE,aAAa,CAAA;AAChD","file":"chunk-SBFW3CJH.js","sourcesContent":["/**\n * open-registry.ts — the CLI's one AssetKindRegistry.\n *\n * The provider registry is the only authority on asset kinds. The CLI builds it\n * once per process with all built-in providers (from @skaile/workspaces/discovery)\n * plus the extension kinds (flow from\n * @skaile/workspaces/factory-assets/connectors/flow/engine, knowledge from\n * @skaile/workspaces/library) and hands the same instance to every consumer\n * (catalog sources, the installer, validation, composition).\n */\n\nimport type { AssetKindRegistry } from \"@skaile/workspaces/discovery\";\nimport { createDefaultKindRegistry } from \"@skaile/workspaces/discovery\";\nimport { flowKindProvider } from \"@skaile/workspaces/factory-assets/connectors/flow/engine\";\nimport { knowledgeKindProvider } from \"@skaile/workspaces/library\";\n\nlet registry: AssetKindRegistry | undefined;\n\n/**\n * The process-wide, fully-configured AssetKindRegistry.\n *\n * Registers every built-in kind plus flow and knowledge. Built lazily on first\n * call; every later call returns the same instance.\n */\nexport function getKindRegistry(): AssetKindRegistry {\n registry ??= createDefaultKindRegistry([flowKindProvider, knowledgeKindProvider]);\n return registry;\n}\n\n/** Registered kind names as a set — the `knownKinds` argument of the manifest scanners. */\nexport function getKnownKinds(): ReadonlySet<string> {\n return new Set(getKindRegistry().getAllKinds());\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readAllSessions } from './chunk-R6O6YWU7.js';
|
|
2
|
-
import { findAiAssetsRoot } from './chunk-
|
|
2
|
+
import { findAiAssetsRoot } from './chunk-Y63UQZ7P.js';
|
|
3
3
|
import { okJson, err } from './chunk-X5YPJV4N.js';
|
|
4
4
|
|
|
5
5
|
// workspace-plugin/src/tools/flows.ts
|
|
@@ -68,5 +68,5 @@ async function flowFindFlowForSession(projectDir, runId) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export { flowFindFlowForSession, flowGetSession, flowList, flowListSessions, flowShow };
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
71
|
+
//# sourceMappingURL=chunk-SX5U422E.js.map
|
|
72
|
+
//# sourceMappingURL=chunk-SX5U422E.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../workspace-plugin/src/tools/flows.ts"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../workspace-plugin/src/tools/flows.ts"],"names":[],"mappings":"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","file":"chunk-SX5U422E.js","sourcesContent":["// src/tools/flows.ts\n\nimport type { ToolResult } from \"../types.js\";\nimport { err, okJson } from \"../types.js\";\nimport { findAiAssetsRoot } from \"../utils/ai-assets.js\";\nimport { readAllSessions } from \"./sessions.js\";\n\n// ── Flow tools ────────────────────────────────────────────────────────────────\n\n/**\n * List all flow definitions available in the project's `ai-assets` directory.\n *\n * Returns a JSON array of summary objects `{ id, name, nodeCount }`.\n * Returns an empty array when no `ai-assets` root is found.\n *\n * @param projectDir - Absolute path to the skaile project root.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function flowList(projectDir: string): Promise<ToolResult> {\n try {\n const assetsRoot = await findAiAssetsRoot(projectDir);\n if (!assetsRoot) return okJson([]);\n const { loadAllFlows } = await import(\n \"@skaile/workspaces/factory-assets/connectors/flow/engine\"\n );\n const flows = loadAllFlows(assetsRoot);\n const summary = flows.map((f: any) => ({\n id: f.id,\n name: f.name ?? f.id,\n nodeCount: f.nodes?.length ?? 0,\n }));\n return okJson(summary);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Show the full flow definition (nodes, edges, metadata) for a specific flow.\n *\n * @param projectDir - Absolute path to the skaile project root.\n * @param flowId - Flow ID as returned by {@link flowList}.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function flowShow(projectDir: string, flowId: string): Promise<ToolResult> {\n try {\n const assetsRoot = await findAiAssetsRoot(projectDir);\n if (!assetsRoot) return err(`Flow not found: ${flowId}`);\n const { loadAllFlows } = await import(\n \"@skaile/workspaces/factory-assets/connectors/flow/engine\"\n );\n const flows = loadAllFlows(assetsRoot);\n const flow = flows.find((f: any) => f.id === flowId);\n if (!flow) return err(`Flow not found: ${flowId}`);\n return okJson(flow);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * List all past and active flow run sessions for the workspace.\n *\n * Delegates to {@link readAllSessions} (reads `.skaile/sessions/*.json`),\n * sorted newest-first by `updatedAt`.\n *\n * @param projectDir - Absolute path to the skaile project root.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function flowListSessions(projectDir: string): Promise<ToolResult> {\n try {\n const sessions = await readAllSessions(projectDir);\n return okJson(sessions);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Get driver metadata for a specific flow run session.\n *\n * @param projectDir - Absolute path to the skaile project root.\n * @param runId - Run ID from {@link flowListSessions}.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function flowGetSession(projectDir: string, runId: string): Promise<ToolResult> {\n try {\n const sessions = await readAllSessions(projectDir);\n const session = sessions.find((s) => s.runId === runId);\n if (!session) return err(`Session not found: ${runId}`);\n return okJson(session);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Resolve and return the flow definition that was used in a past session.\n *\n * Looks up the session by `runId`, reads its `flowId`, then returns the full\n * flow definition from `ai-assets`.\n *\n * @param projectDir - Absolute path to the skaile project root.\n * @param runId - Run ID from {@link flowListSessions}.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function flowFindFlowForSession(\n projectDir: string,\n runId: string,\n): Promise<ToolResult> {\n try {\n const sessions = await readAllSessions(projectDir);\n const session = sessions.find((s) => s.runId === runId);\n if (!session) return err(`Session not found: ${runId}`);\n\n const assetsRoot = await findAiAssetsRoot(projectDir);\n if (!assetsRoot) return err(`Flow not found for session: ${runId} (no ai-assets root)`);\n\n const { loadAllFlows } = await import(\n \"@skaile/workspaces/factory-assets/connectors/flow/engine\"\n );\n const flows = loadAllFlows(assetsRoot);\n const flow = flows.find((f: any) => f.id === session.flowId);\n if (!flow) return err(`Flow not found: ${session.flowId}`);\n return okJson(flow);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n"]}
|