@skaile/workspaces 1.15.1 → 2.0.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 +271 -0
- package/dist/{asset-feeds-MWEMXMZA.js → asset-feeds-7VQVISDI.js} +25 -24
- package/dist/asset-feeds-7VQVISDI.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +13 -1
- package/dist/asset-manager/index.js +10 -9
- package/dist/asset-manager/installer.js +7 -6
- package/dist/asset-manager/src/catalog-deployer.d.ts +70 -5
- package/dist/asset-manager/src/catalog-deployer.d.ts.map +1 -1
- package/dist/asset-manager/src/index.d.ts +22 -17
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +108 -56
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +3 -2
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +4 -3
- package/dist/bridge/drivers/continue.js.map +1 -1
- package/dist/bridge/drivers/echo.js +3 -2
- package/dist/bridge/drivers/echo.js.map +1 -1
- package/dist/bridge/drivers/gemini.js +5 -4
- package/dist/bridge/drivers/goose.js +4 -3
- package/dist/bridge/drivers/goose.js.map +1 -1
- package/dist/bridge/drivers/omp.js +3 -2
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +4 -3
- package/dist/bridge/drivers/opencode.js.map +1 -1
- package/dist/bridge/drivers/qwen.js +5 -4
- package/dist/bridge/drivers/qwen.js.map +1 -1
- package/dist/bridge/index.js +4 -3
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/scrub-transcript.d.ts +21 -1
- package/dist/bridge/src/drivers/scrub-transcript.d.ts.map +1 -1
- package/dist/{chunk-344DEXZS.js → chunk-35ELAMQ5.js} +4 -4
- package/dist/{chunk-344DEXZS.js.map → chunk-35ELAMQ5.js.map} +1 -1
- package/dist/{chunk-73HV7RV3.js → chunk-6FJH63NN.js} +4 -4
- package/dist/{chunk-73HV7RV3.js.map → chunk-6FJH63NN.js.map} +1 -1
- package/dist/{chunk-ISA7R7PK.js → chunk-72EOJJOM.js} +82 -38
- package/dist/chunk-72EOJJOM.js.map +1 -0
- package/dist/chunk-7GOCNYUV.js +300 -0
- package/dist/chunk-7GOCNYUV.js.map +1 -0
- package/dist/{chunk-TFIFNDT2.js → chunk-A5OYCQGT.js} +4 -4
- package/dist/{chunk-TFIFNDT2.js.map → chunk-A5OYCQGT.js.map} +1 -1
- package/dist/{chunk-KY5NY7LB.js → chunk-BCTU4TN7.js} +11 -11
- package/dist/chunk-BCTU4TN7.js.map +1 -0
- package/dist/chunk-BEAIJRVF.js +159 -0
- package/dist/chunk-BEAIJRVF.js.map +1 -0
- package/dist/chunk-BK3WL3QK.js +10 -0
- package/dist/chunk-BK3WL3QK.js.map +1 -0
- package/dist/{chunk-BI2NKPA4.js → chunk-CA5CWLGN.js} +3 -2
- package/dist/chunk-CA5CWLGN.js.map +1 -0
- package/dist/{chunk-2TSSCHCQ.js → chunk-CKVIN4H3.js} +5 -5
- package/dist/{chunk-2TSSCHCQ.js.map → chunk-CKVIN4H3.js.map} +1 -1
- package/dist/{chunk-GXC3TYMQ.js → chunk-CZZRDYT4.js} +70 -32
- package/dist/chunk-CZZRDYT4.js.map +1 -0
- package/dist/{chunk-MNKUZUN2.js → chunk-DRXDEL3A.js} +3 -3
- package/dist/{chunk-MNKUZUN2.js.map → chunk-DRXDEL3A.js.map} +1 -1
- package/dist/{chunk-Z6NGK5YC.js → chunk-DY2AK577.js} +3 -3
- package/dist/{chunk-Z6NGK5YC.js.map → chunk-DY2AK577.js.map} +1 -1
- package/dist/chunk-DYMWJAL4.js +552 -0
- package/dist/chunk-DYMWJAL4.js.map +1 -0
- package/dist/{chunk-ACXLKNIM.js → chunk-E7HKNQTH.js} +10 -4
- package/dist/chunk-E7HKNQTH.js.map +1 -0
- package/dist/{chunk-O5VCUU6D.js → chunk-KUZEIKZH.js} +4 -4
- package/dist/{chunk-O5VCUU6D.js.map → chunk-KUZEIKZH.js.map} +1 -1
- package/dist/{chunk-RADBQ5XJ.js → chunk-KYLWY3A7.js} +10 -10
- package/dist/{chunk-RADBQ5XJ.js.map → chunk-KYLWY3A7.js.map} +1 -1
- package/dist/{chunk-2BQBWWFX.js → chunk-LBZP2IYG.js} +6 -6
- package/dist/chunk-LBZP2IYG.js.map +1 -0
- package/dist/{chunk-MZV6WCF3.js → chunk-MAN7AGQJ.js} +3 -3
- package/dist/{chunk-MZV6WCF3.js.map → chunk-MAN7AGQJ.js.map} +1 -1
- package/dist/{chunk-7J7LQP6T.js → chunk-MMD2KQ3A.js} +31 -19
- package/dist/chunk-MMD2KQ3A.js.map +1 -0
- package/dist/{chunk-NRXVS7E4.js → chunk-NYCJ7B27.js} +19 -11
- package/dist/chunk-NYCJ7B27.js.map +1 -0
- package/dist/{chunk-ACWCVB5Q.js → chunk-ORZW7MMO.js} +3 -3
- package/dist/{chunk-ACWCVB5Q.js.map → chunk-ORZW7MMO.js.map} +1 -1
- package/dist/{chunk-M5GJT3D7.js → chunk-OYX22NJL.js} +3 -3
- package/dist/{chunk-M5GJT3D7.js.map → chunk-OYX22NJL.js.map} +1 -1
- package/dist/{chunk-MJEUK6VJ.js → chunk-QIQTYN7F.js} +3 -3
- package/dist/{chunk-MJEUK6VJ.js.map → chunk-QIQTYN7F.js.map} +1 -1
- package/dist/{chunk-2IJFUAZB.js → chunk-RK3HU3H3.js} +123 -18
- package/dist/chunk-RK3HU3H3.js.map +1 -0
- package/dist/{chunk-5NZ56R63.js → chunk-ST3DLLNZ.js} +18 -6
- package/dist/chunk-ST3DLLNZ.js.map +1 -0
- package/dist/{chunk-MTM6C7IS.js → chunk-SVL4EZJT.js} +463 -251
- package/dist/chunk-SVL4EZJT.js.map +1 -0
- package/dist/{chunk-JB35MVBN.js → chunk-U5POE4BA.js} +4 -298
- package/dist/chunk-U5POE4BA.js.map +1 -0
- package/dist/{chunk-DB264AVQ.js → chunk-UAQVFATZ.js} +8 -8
- package/dist/{chunk-DB264AVQ.js.map → chunk-UAQVFATZ.js.map} +1 -1
- package/dist/{chunk-DPUZJI45.js → chunk-UVW3R6S7.js} +72 -37
- package/dist/chunk-UVW3R6S7.js.map +1 -0
- package/dist/{chunk-STQOPWPS.js → chunk-VCU4NPUS.js} +4 -4
- package/dist/{chunk-STQOPWPS.js.map → chunk-VCU4NPUS.js.map} +1 -1
- package/dist/{chunk-MB6563TL.js → chunk-WCWXDW22.js} +3 -3
- package/dist/{chunk-MB6563TL.js.map → chunk-WCWXDW22.js.map} +1 -1
- package/dist/{chunk-EKGB4ZWR.js → chunk-WZPADAE7.js} +255 -136
- package/dist/chunk-WZPADAE7.js.map +1 -0
- package/dist/{chunk-SRWIVMJI.js → chunk-Y3JVBJ3Y.js} +5 -5
- package/dist/{chunk-SRWIVMJI.js.map → chunk-Y3JVBJ3Y.js.map} +1 -1
- package/dist/{chunk-3EBFDMZC.js → chunk-Y662DNQQ.js} +14 -3
- package/dist/chunk-Y662DNQQ.js.map +1 -0
- package/dist/cli/index.js +348 -128
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/asset-feeds.d.ts +2 -2
- package/dist/cli/src/asset-feeds.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +51 -2
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/connector.d.ts +1 -1
- package/dist/cli/src/commands/connector.d.ts.map +1 -1
- package/dist/cli/src/commands/logs.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +30 -3
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +5 -2
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/connectors/config.js +7 -6
- package/dist/connectors/index.js +9 -8
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/connector-prompt.d.ts.map +1 -1
- package/dist/connectors/src/watcher.d.ts.map +1 -1
- package/dist/connectors/src/worktree.d.ts +20 -2
- package/dist/connectors/src/worktree.d.ts.map +1 -1
- package/dist/core/index.js +6 -5
- package/dist/core/logging.js +2 -1
- package/dist/core/manifest.js +2 -1
- package/dist/core/runtime-assets.js +4 -3
- package/dist/core/src/fs-deadline.d.ts +84 -0
- package/dist/core/src/fs-deadline.d.ts.map +1 -0
- package/dist/core/src/index.d.ts +4 -3
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +142 -18
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/repo-manager.d.ts +2 -2
- package/dist/core/src/repo-manager.d.ts.map +1 -1
- package/dist/core/src/runtime-assets.d.ts.map +1 -1
- package/dist/core/src/subprocess.d.ts +33 -1
- package/dist/core/src/subprocess.d.ts.map +1 -1
- package/dist/core/src/walker.d.ts +1 -1
- package/dist/core/src/walker.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +9 -2
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/workspace-config.js +3 -2
- package/dist/deploy/index.js +12 -7
- package/dist/deploy/index.js.map +1 -1
- package/dist/deploy/src/targets/container-runtime.d.ts.map +1 -1
- package/dist/discovery/index.js +3 -2
- package/dist/{ensure-sources-QGL44IRI.js → ensure-sources-JLVHHZI2.js} +13 -12
- package/dist/ensure-sources-JLVHHZI2.js.map +1 -0
- package/dist/factory-assets/connectors/box.js +9 -8
- package/dist/factory-assets/connectors/deploy/CONNECTOR.md +19 -0
- package/dist/factory-assets/connectors/deploy/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/deploy.js +9 -8
- package/dist/factory-assets/connectors/devserver/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/devserver.js +9 -8
- package/dist/factory-assets/connectors/flow/CONNECTOR.md +3 -1
- package/dist/factory-assets/connectors/flow/adapter.d.ts +2 -1
- package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/adapter.js +9 -8
- package/dist/factory-assets/connectors/flow/engine.js +6 -5
- package/dist/factory-assets/connectors/flow/prompt-fragments.d.ts +9 -2
- package/dist/factory-assets/connectors/flow/prompt-fragments.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/prompt-fragments.js +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +11 -10
- package/dist/factory-assets/connectors/flow.js +9 -8
- package/dist/factory-assets/connectors/git/driver.d.ts +12 -1
- package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/git.js +9 -8
- package/dist/factory-assets/connectors/gmail.js +9 -8
- package/dist/factory-assets/connectors/googledrive.js +9 -8
- package/dist/factory-assets/connectors/local/driver.d.ts +25 -1
- package/dist/factory-assets/connectors/local/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/local.js +9 -8
- package/dist/factory-assets/connectors/mattermost.js +9 -8
- package/dist/factory-assets/connectors/memory.js +9 -8
- package/dist/factory-assets/connectors/minio.js +9 -8
- package/dist/factory-assets/connectors/postgres.js +9 -8
- package/dist/factory-assets/connectors/s3/driver.d.ts +15 -0
- package/dist/factory-assets/connectors/s3/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/s3.js +9 -8
- package/dist/factory-assets/connectors/sharepoint.js +9 -8
- package/dist/factory-assets/connectors/sqlite/adapter.d.ts +8 -1
- package/dist/factory-assets/connectors/sqlite/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/sqlite.js +9 -8
- package/dist/factory-assets/connectors/static-server/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/static-server.js +9 -8
- package/dist/factory-assets/connectors/tunnel.js +9 -8
- package/dist/factory-assets/connectors/webdav.js +9 -8
- package/dist/factory-assets/connectors/xstate/adapter.d.ts +6 -0
- package/dist/factory-assets/connectors/xstate/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/xstate-store.js +9 -8
- package/dist/factory-assets/connectors/xstate.js +9 -8
- package/dist/flows-LV5WYJ2I.js +20 -0
- package/dist/{flows-FHWBCLXF.js.map → flows-LV5WYJ2I.js.map} +1 -1
- package/dist/{helpers-FMWODXTW.js → helpers-PJ3CPUUL.js} +13 -12
- package/dist/{helpers-FMWODXTW.js.map → helpers-PJ3CPUUL.js.map} +1 -1
- package/dist/library/index.js +8 -7
- package/dist/library/install.js +6 -5
- package/dist/{library-publish-7YDHQGBN.js → library-publish-HVZRCE3C.js} +16 -15
- package/dist/library-publish-HVZRCE3C.js.map +1 -0
- package/dist/{open-library-O6T3ELPK.js → open-library-RMI2FTQ4.js} +14 -13
- package/dist/{open-library-O6T3ELPK.js.map → open-library-RMI2FTQ4.js.map} +1 -1
- package/dist/{paths-5QJJBAND.js → paths-JSVTQAVW.js} +11 -10
- package/dist/{paths-5QJJBAND.js.map → paths-JSVTQAVW.js.map} +1 -1
- package/dist/plugin-registry/src/deploy-helpers.d.ts +1 -1
- package/dist/{plugin-store-ZBJZ7F6D.js → plugin-store-7TVJB2TS.js} +8 -7
- package/dist/plugin-store-7TVJB2TS.js.map +1 -0
- package/dist/{project-HAMLHLD5.js → project-P636MSYT.js} +14 -13
- package/dist/{project-HAMLHLD5.js.map → project-P636MSYT.js.map} +1 -1
- package/dist/resolver/index.js +13 -1
- package/dist/resolver/src/types.d.ts +7 -0
- package/dist/resolver/src/types.d.ts.map +1 -1
- package/dist/resolver/src/validator.d.ts +8 -1
- package/dist/resolver/src/validator.d.ts.map +1 -1
- package/dist/runner/index.js +14 -13
- package/dist/runner/src/external-mcp.d.ts +1 -1
- package/dist/runner/src/external-mcp.d.ts.map +1 -1
- package/dist/runner/src/mcp-prompt.d.ts +7 -3
- package/dist/runner/src/mcp-prompt.d.ts.map +1 -1
- package/dist/runner/src/mcp-runtime-handlers.d.ts +12 -0
- package/dist/runner/src/mcp-runtime-handlers.d.ts.map +1 -1
- package/dist/runner/src/mixin-resolver.d.ts.map +1 -1
- package/dist/runner/src/recipe-resolver.d.ts +20 -6
- package/dist/runner/src/recipe-resolver.d.ts.map +1 -1
- package/dist/runner/src/resource-handler.d.ts +43 -0
- package/dist/runner/src/resource-handler.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts +12 -5
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +5 -5
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts +9 -0
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/runner/src/session-capability-wiring.d.ts +5 -0
- package/dist/runner/src/session-capability-wiring.d.ts.map +1 -1
- package/dist/runner/src/workspace-migration.d.ts +37 -3
- package/dist/runner/src/workspace-migration.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +10 -9
- package/dist/sdk/bridge.js +4 -3
- package/dist/sdk/core.js +6 -5
- package/dist/sdk/flow.js +6 -5
- package/dist/sdk/index.js +14 -13
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +13 -1
- package/dist/sdk/runner.js +14 -13
- package/dist/sdk/session.js +1 -1
- package/dist/sdk/store.js +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/{setup-WJPNUE32.js → setup-OYW3W3XK.js} +10 -9
- package/dist/setup-OYW3W3XK.js.map +1 -0
- package/dist/skills-QY5PHBD3.js +20 -0
- package/dist/{skills-BMI6H7HI.js.map → skills-QY5PHBD3.js.map} +1 -1
- package/dist/{source-ITDH4367.js → source-63CHWDC2.js} +15 -14
- package/dist/{source-ITDH4367.js.map → source-63CHWDC2.js.map} +1 -1
- package/dist/{source-manifest-publish-RMHC7R6M.js → source-manifest-publish-DLASGDK5.js} +17 -16
- package/dist/source-manifest-publish-DLASGDK5.js.map +1 -0
- package/dist/store/index.js +1 -1
- package/dist/store/src/store.d.ts +9 -0
- package/dist/store/src/store.d.ts.map +1 -1
- package/dist/tui/index.js +14 -13
- package/dist/tui/index.js.map +1 -1
- package/dist/validator-RN64BKFW.js +5 -0
- package/dist/{validator-VF5M764T.js.map → validator-RN64BKFW.js.map} +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +18 -5
- package/dist/workspace-plugin/adapters/mcp.js.map +1 -1
- package/dist/workspace-plugin/adapters/omp.js +10 -10
- package/dist/workspace-plugin/index.js +3 -2
- package/dist/workspace-plugin/src/tools/validator.d.ts.map +1 -1
- package/dist/workspace-plugin/src/utils/ai-assets.d.ts +11 -6
- package/dist/workspace-plugin/src/utils/ai-assets.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/asset-feeds-MWEMXMZA.js.map +0 -1
- package/dist/chunk-2BQBWWFX.js.map +0 -1
- package/dist/chunk-2IJFUAZB.js.map +0 -1
- package/dist/chunk-3EBFDMZC.js.map +0 -1
- package/dist/chunk-5NZ56R63.js.map +0 -1
- package/dist/chunk-7J7LQP6T.js.map +0 -1
- package/dist/chunk-ACXLKNIM.js.map +0 -1
- package/dist/chunk-BI2NKPA4.js.map +0 -1
- package/dist/chunk-BQCGFPHW.js +0 -345
- package/dist/chunk-BQCGFPHW.js.map +0 -1
- package/dist/chunk-DPUZJI45.js.map +0 -1
- package/dist/chunk-EKGB4ZWR.js.map +0 -1
- package/dist/chunk-GXC3TYMQ.js.map +0 -1
- package/dist/chunk-ISA7R7PK.js.map +0 -1
- package/dist/chunk-JB35MVBN.js.map +0 -1
- package/dist/chunk-KY5NY7LB.js.map +0 -1
- package/dist/chunk-LV2HPH3C.js +0 -73
- package/dist/chunk-LV2HPH3C.js.map +0 -1
- package/dist/chunk-MTM6C7IS.js.map +0 -1
- package/dist/chunk-NRXVS7E4.js.map +0 -1
- package/dist/chunk-XCBG2KDC.js +0 -23
- package/dist/chunk-XCBG2KDC.js.map +0 -1
- package/dist/ensure-sources-QGL44IRI.js.map +0 -1
- package/dist/flows-FHWBCLXF.js +0 -7
- package/dist/library-publish-7YDHQGBN.js.map +0 -1
- package/dist/plugin-store-ZBJZ7F6D.js.map +0 -1
- package/dist/setup-WJPNUE32.js.map +0 -1
- package/dist/skills-BMI6H7HI.js +0 -7
- package/dist/source-manifest-publish-RMHC7R6M.js.map +0 -1
- package/dist/validator-VF5M764T.js +0 -5
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../workspace-plugin/src/tools/flows.ts"],"names":[],"mappings":";;;;;AAmBA,eAAsB,SAAS,UAAA,EAAyC;AACtE,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GAAa,iBAAiB,UAAU,CAAA;AAC9C,IAAA,IAAI,CAAC,UAAA,EAAY,OAAO,MAAA,CAAO,EAAE,CAAA;AACjC,IAAA,MAAM,EAAE,YAAA,EAAa,GAAI,MAAM,OAC7B,4CACF,CAAA;AACA,IAAA,MAAM,KAAA,GAAQ,aAAa,UAAU,CAAA;AACrC,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAY;AAAA,MACrC,IAAI,CAAA,CAAE,EAAA;AAAA,MACN,IAAA,EAAM,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,EAAA;AAAA,MAClB,SAAA,EAAW,CAAA,CAAE,KAAA,EAAO,MAAA,IAAU;AAAA,KAChC,CAAE,CAAA;AACF,IAAA,OAAO,OAAO,OAAO,CAAA;AAAA,EACvB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAUA,eAAsB,QAAA,CAAS,YAAoB,MAAA,EAAqC;AACtF,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GAAa,iBAAiB,UAAU,CAAA;AAC9C,IAAA,IAAI,CAAC,UAAA,EAAY,OAAO,GAAA,CAAI,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAE,CAAA;AACvD,IAAA,MAAM,EAAE,YAAA,EAAa,GAAI,MAAM,OAC7B,4CACF,CAAA;AACA,IAAA,MAAM,KAAA,GAAQ,aAAa,UAAU,CAAA;AACrC,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAW,CAAA,CAAE,OAAO,MAAM,CAAA;AACnD,IAAA,IAAI,CAAC,IAAA,EAAM,OAAO,GAAA,CAAI,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAE,CAAA;AACjD,IAAA,OAAO,OAAO,IAAI,CAAA;AAAA,EACpB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAYA,eAAsB,iBAAiB,UAAA,EAAyC;AAC9E,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,UAAU,CAAA;AACjD,IAAA,OAAO,OAAO,QAAQ,CAAA;AAAA,EACxB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAUA,eAAsB,cAAA,CAAe,YAAoB,KAAA,EAAoC;AAC3F,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,UAAU,CAAA;AACjD,IAAA,MAAM,UAAU,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AACtD,IAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AACtD,IAAA,OAAO,OAAO,OAAO,CAAA;AAAA,EACvB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAaA,eAAsB,sBAAA,CACpB,YACA,KAAA,EACqB;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,UAAU,CAAA;AACjD,IAAA,MAAM,UAAU,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AACtD,IAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAEtD,IAAA,MAAM,UAAA,GAAa,iBAAiB,UAAU,CAAA;AAC9C,IAAA,IAAI,CAAC,UAAA,EAAY,OAAO,GAAA,CAAI,CAAA,4BAAA,EAA+B,KAAK,CAAA,oBAAA,CAAsB,CAAA;AAEtF,IAAA,MAAM,EAAE,YAAA,EAAa,GAAI,MAAM,OAC7B,4CACF,CAAA;AACA,IAAA,MAAM,KAAA,GAAQ,aAAa,UAAU,CAAA;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,CAAC,MAAW,CAAA,CAAE,EAAA,KAAO,QAAQ,MAAM,CAAA;AAC3D,IAAA,IAAI,CAAC,IAAA,EAAM,OAAO,IAAI,CAAA,gBAAA,EAAmB,OAAA,CAAQ,MAAM,CAAA,CAAE,CAAA;AACzD,IAAA,OAAO,OAAO,IAAI,CAAA;AAAA,EACpB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF","file":"chunk-2BQBWWFX.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 = 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 = 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 = 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"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../store/src/resource-client.ts","../store/src/store.ts"],"names":[],"mappings":"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","file":"chunk-2IJFUAZB.js","sourcesContent":["import type {\n AgentEvent,\n ConnectorContent,\n ConnectorEntry,\n ConnectorInfo,\n ConnectorResponseEvent,\n ConnectorStatusEvent,\n ListOptions,\n MountInfo,\n SearchOptions,\n} from \"@skaile/workspaces/types\";\nimport type {\n ConnectorStatus,\n ResourceClientSnapshot,\n StoreTransport,\n SubscribableStore,\n} from \"./types.js\";\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Lazy resource browser for agent connectors.\n *\n * Provides a reactive list of connected mounts and connectors, and\n * request/response methods for browsing connector contents. Shares\n * the same transport (`send` + `onEvent`) as `AgentStore`.\n * @docLink packages/store/concepts#resource-client\n */\nexport class ResourceClient implements SubscribableStore<ResourceClientSnapshot> {\n private readonly _send: StoreTransport[\"send\"];\n private _mounts: readonly MountInfo[] = [];\n private _connectors: readonly ConnectorInfo[] = [];\n\n /** Live connection status per connector, keyed by connector ID. Updated by connector_status events. */\n connectorStatus: Map<string, ConnectorStatus> = new Map();\n\n private _snapshot: ResourceClientSnapshot | null = null;\n private readonly _listeners = new Set<() => void>();\n private readonly _pendingRequests = new Map<\n string,\n {\n resolve: (event: ConnectorResponseEvent) => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n private readonly _unsubEvent: () => void;\n\n /**\n * @param transport - Shared transport (same instance as the AgentStore for this session).\n */\n constructor(transport: StoreTransport) {\n this._send = transport.send;\n this._unsubEvent = transport.onEvent((event) => this._handleEvent(event));\n }\n\n // -- Reactive state --------------------------------------------------------\n\n /** Mounts available in this session, populated from `resources_available` events. */\n get mounts(): readonly MountInfo[] {\n return this._mounts;\n }\n\n /** Tool-based connectors available in this session, populated from `resources_available` events. */\n get connectors(): readonly ConnectorInfo[] {\n return this._connectors;\n }\n\n // -- Resource operations ---------------------------------------------------\n\n /**\n * List directory entries at the given path within a connector.\n *\n * @param connectorId - ID of the connector to query.\n * @param path - Directory path to list. Omit for the connector root.\n * @param opts - Optional pagination and filter options.\n * @returns Array of entries (files, directories, etc.) at the given path.\n * @throws If the request times out or the connector returns an error.\n */\n async list(connectorId: string, path?: string, opts?: ListOptions): Promise<ConnectorEntry[]> {\n const response = await this._request(connectorId, \"list\", path, opts);\n return (response.data as ConnectorEntry[]) ?? [];\n }\n\n /**\n * Read the content of a single resource.\n *\n * @param connectorId - ID of the connector to query.\n * @param path - Full path to the resource within the connector.\n * @returns The resource content object.\n * @throws If the request times out or the connector returns an error.\n */\n async read(connectorId: string, path: string): Promise<ConnectorContent> {\n const response = await this._request(connectorId, \"read\", path);\n return response.data as ConnectorContent;\n }\n\n /**\n * Write content to a resource, creating it if it does not exist.\n *\n * @param connectorId - ID of the connector to write to.\n * @param path - Full path to the resource within the connector.\n * @param content - Content to write.\n * @throws If the request times out or the connector returns an error.\n */\n async write(connectorId: string, path: string, content: ConnectorContent): Promise<void> {\n await this._request(connectorId, \"write\", path, undefined, content);\n }\n\n /**\n * Delete a resource from a connector.\n *\n * @param connectorId - ID of the connector to delete from.\n * @param path - Full path to the resource within the connector.\n * @throws If the request times out or the connector returns an error.\n */\n async delete(connectorId: string, path: string): Promise<void> {\n await this._request(connectorId, \"delete\", path);\n }\n\n /**\n * Full-text search within a connector.\n *\n * @param connectorId - ID of the connector to search.\n * @param query - Search query string.\n * @param opts - Optional search options (e.g. path prefix, result limit).\n * @returns Matching entries, ordered by relevance as determined by the connector.\n * @throws If the request times out or the connector returns an error.\n */\n async search(\n connectorId: string,\n query: string,\n opts?: SearchOptions,\n ): Promise<ConnectorEntry[]> {\n const response = await this._request(connectorId, \"search\", query, opts);\n return (response.data as ConnectorEntry[]) ?? [];\n }\n\n // -- useSyncExternalStore interface ----------------------------------------\n\n /**\n * Register a change listener. Called after every resource availability change.\n *\n * Conforms to the `subscribe` parameter of React's `useSyncExternalStore`.\n *\n * @param listener - Callback invoked whenever mounts or connectors change.\n * @returns Unsubscribe function — call to stop receiving notifications.\n */\n subscribe = (listener: () => void): (() => void) => {\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n };\n\n /**\n * Return the current immutable resource snapshot.\n *\n * A new object is produced lazily after each `resources_available` event.\n * Conforms to the `getSnapshot` parameter of React's `useSyncExternalStore`.\n */\n getSnapshot = (): ResourceClientSnapshot => {\n if (!this._snapshot) {\n this._snapshot = { mounts: this._mounts, connectors: this._connectors };\n }\n return this._snapshot;\n };\n\n // -- Connector config mutations --------------------------------------------\n\n /**\n * Send a `connector_config` add command to wire a new connector at runtime,\n * without restarting the session. The runner receives this command and\n * calls `ConnectorManager.connect()`, which fires a `connector_status` event\n * back to the store once the connector is live.\n *\n * @param declaration - Connector declaration (id, driver, access level, options).\n */\n addConnector(declaration: {\n id: string;\n driver: string;\n access?: \"read-only\" | \"read-write\";\n options?: Record<string, unknown>;\n }): void {\n this._send({ type: \"connector_config\", action: \"add\", declaration });\n }\n\n /**\n * Send a `connector_config` remove command to disconnect a connector by ID\n * without restarting the session.\n *\n * @param connectorId - ID of the connector to disconnect and remove.\n */\n removeConnector(connectorId: string): void {\n this._send({ type: \"connector_config\", action: \"remove\", connectorId });\n }\n\n /**\n * Send a `connector_config` refresh command to reconnect all configured\n * connectors (e.g. after a credentials change).\n */\n refreshConnectors(): void {\n this._send({ type: \"connector_config\", action: \"refresh\" });\n }\n\n // -- Cleanup ---------------------------------------------------------------\n\n /**\n * Unsubscribe from transport events, reject all pending requests, and\n * clear all change listeners.\n *\n * All in-flight `list`/`read`/`write`/`delete`/`search` calls will reject\n * with `\"ResourceClient disposed\"`.\n */\n dispose(): void {\n this._unsubEvent();\n for (const [, pending] of this._pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(\"ResourceClient disposed\"));\n }\n this._pendingRequests.clear();\n this._listeners.clear();\n }\n\n // -- Internal --------------------------------------------------------------\n\n private _handleEvent(event: AgentEvent): void {\n if (event.type === \"connector_status\") {\n const e = event as ConnectorStatusEvent;\n const existing = this.connectorStatus.get(e.connectorId);\n const next = new Map(this.connectorStatus);\n next.set(e.connectorId, {\n id: e.connectorId,\n driver:\n existing?.driver ?? this._connectors.find((c) => c.id === e.connectorId)?.driver ?? \"\",\n state: e.status,\n ...(e.error !== undefined ? { error: e.error } : {}),\n ...(e.latencyMs !== undefined ? { latencyMs: e.latencyMs } : {}),\n lastUpdated: new Date(),\n });\n this.connectorStatus = next;\n for (const listener of this._listeners) {\n listener();\n }\n return;\n }\n\n if (event.type === \"resources_available\") {\n this._mounts = event.mounts;\n this._connectors = event.connectors;\n this._snapshot = null;\n for (const listener of this._listeners) {\n listener();\n }\n return;\n }\n\n if (event.type === \"resource_response\") {\n const pending = this._pendingRequests.get(event.requestId);\n if (!pending) return;\n\n clearTimeout(pending.timer);\n this._pendingRequests.delete(event.requestId);\n\n if (event.error) {\n pending.reject(new Error(event.error));\n } else {\n pending.resolve(event);\n }\n }\n }\n\n private _request(\n connectorId: string,\n operation: \"list\" | \"read\" | \"write\" | \"delete\" | \"search\",\n path?: string,\n options?: ListOptions | SearchOptions,\n content?: ConnectorContent,\n ): Promise<ConnectorResponseEvent> {\n const requestId = crypto.randomUUID();\n\n return new Promise<ConnectorResponseEvent>((resolve, reject) => {\n const timer = setTimeout(() => {\n this._pendingRequests.delete(requestId);\n reject(\n new Error(\n `Resource request timed out after ${DEFAULT_TIMEOUT_MS}ms: ${operation} ${connectorId}${path ? ` ${path}` : \"\"}`,\n ),\n );\n }, DEFAULT_TIMEOUT_MS);\n\n this._pendingRequests.set(requestId, { resolve, reject, timer });\n\n this._send({\n type: \"resource_request\",\n requestId,\n connectorId,\n operation,\n ...(path !== undefined ? { path } : {}),\n ...(options ? { options } : {}),\n ...(content ? { content } : {}),\n });\n });\n }\n}\n","import type {\n AgentCommand,\n AgentEvent,\n AgentPhase,\n Capability,\n IncompatibleProtocolEvent,\n Message,\n ProtocolInfoEvent,\n RenderInvokedEvent,\n} from \"@skaile/workspaces/types\";\nimport type {\n AgentClientLike,\n AgentStoreOptions,\n AgentStoreSnapshot,\n ConnectionStatus,\n SubscribableStore,\n} from \"./types.js\";\n\nconst DEFAULT_PAGE_SIZE = 50;\n\n/**\n * Headless reactive store for agent conversation state.\n *\n * Framework-agnostic — works with React (`useSyncExternalStore`),\n * Vue (`shallowRef` + `subscribe`), or any other UI framework.\n *\n * Accepts a minimal transport interface (`send` + `onEvent`) so it works\n * with WebSocket, tRPC, SSE, or any other delivery mechanism.\n * @docLink packages/store/concepts#agent-store\n */\nexport class AgentStore implements SubscribableStore<AgentStoreSnapshot> {\n private readonly _options: AgentStoreOptions;\n private _messages: Message[];\n private _streamingText = \"\";\n private _cancelledText = \"\";\n private _status: ConnectionStatus = \"idle\";\n private _phase: AgentPhase = \"idle\";\n private _pendingQuestion: AgentStoreSnapshot[\"pendingQuestion\"] = null;\n private _error: AgentStoreSnapshot[\"error\"] = null;\n private _isAllLoaded: boolean;\n private _seq: number;\n private _streamingFlushed = true;\n /** Shared state per store namespace — new Map instance on every mutation. */\n private _sharedState: Map<string, Record<string, unknown>> = new Map();\n /** Protocol v2 capability registry — new Map instance on every mutation. */\n private _capabilities: Map<string, Capability> = new Map();\n /** Protocol v2 active render invocations — new Map instance on every mutation. */\n private _activeRenderInvocations: Map<string, RenderInvokedEvent> = new Map();\n /** Protocol v2 — most recent `protocol_info` event from the runner. */\n private _protocolInfo: ProtocolInfoEvent | null = null;\n /** Protocol v2 — latest incompatible-protocol notice. */\n private _incompatibleProtocol: IncompatibleProtocolEvent | null = null;\n\n private _snapshot: AgentStoreSnapshot | null = null;\n private readonly _listeners = new Set<() => void>();\n private readonly _unsubEvent: () => void;\n private readonly _unsubStatus: (() => void) | undefined;\n\n /**\n * @param options - Store configuration including transport and optional pagination support.\n */\n constructor(options: AgentStoreOptions) {\n this._options = options;\n this._messages = options.initialMessages ? [...options.initialMessages] : [];\n this._isAllLoaded = !options.loadMessages;\n this._seq = this._messages.reduce((max, m) => Math.max(max, m.seq), 0);\n\n this._unsubEvent = options.onEvent((event) => this._handleEvent(event));\n this._unsubStatus = options.onStatusChange?.((status) => {\n this._status = status;\n this._notify();\n });\n }\n\n // -- Reactive state --------------------------------------------------------\n\n /** Accumulated conversation messages, oldest first. */\n get messages(): readonly Message[] {\n return this._messages;\n }\n\n /** Text currently streaming from the agent. Empty when not streaming. */\n get streamingText(): string {\n return this._streamingText;\n }\n\n /** Current connection lifecycle state. */\n get status(): ConnectionStatus {\n return this._status;\n }\n\n /** Current agent execution phase (e.g. `\"idle\"`, `\"thinking\"`, `\"executing\"`). */\n get phase(): AgentPhase {\n return this._phase;\n }\n\n /** The pending question the agent is waiting for the user to answer, or null. */\n get pendingQuestion(): AgentStoreSnapshot[\"pendingQuestion\"] {\n return this._pendingQuestion;\n }\n\n /** Most recent error, or null when no error is active. */\n get error(): AgentStoreSnapshot[\"error\"] {\n return this._error;\n }\n\n /** Partial text that was visible when the user cancelled. Empty when not cancelled. */\n get cancelledText(): string {\n return this._cancelledText;\n }\n\n /** True when there are no more older messages to load via pagination. */\n get isAllLoaded(): boolean {\n return this._isAllLoaded;\n }\n\n // -- Commands --------------------------------------------------------------\n\n /**\n * Send a user prompt to the agent and optimistically update local state.\n *\n * Clears any previous error and cancelled text, sets phase to `\"thinking\"`,\n * and appends the prompt as a local message before forwarding to the agent.\n *\n * @param text - The user's prompt text.\n */\n prompt(text: string): void {\n // A prompt sent mid-turn (sender interjecting while the agent streams) is a\n // boundary: finalize the in-flight text before this prompt so the two don't\n // merge into one bubble. No-op at turn start (nothing streaming).\n this._flushStreaming();\n this._error = null;\n this._cancelledText = \"\";\n this._streamingFlushed = false;\n this._phase = \"thinking\";\n this._appendMessage({ type: \"prompt\", prompt: text }, \"user\");\n this._options.send({ type: \"prompt\", prompt: text });\n this._notify();\n }\n\n /**\n * Send a reply to the agent's pending question.\n *\n * Clears the pending question locally before forwarding the reply command.\n *\n * @param answer - The user's answer text.\n * @param question - The sub-question being answered, verbatim from its\n * `question` event. Required for correctness in hosts that surface several\n * queued questions at once ({@link pendingQuestion} tracks only the latest,\n * so those hosts drive this from their own message history): without it the\n * agent files the answer under its next unanswered sub-question, which\n * mismatches any non-sequential reply.\n */\n reply(answer: string, question?: string): void {\n this._pendingQuestion = null;\n // Answering a pending question resumes the agent turn — restore the busy\n // phase (mirrors prompt()) so the thinking indicator reappears immediately\n // rather than after the agent's first resumed event lands.\n this._phase = \"thinking\";\n const command = {\n type: \"reply\",\n answer,\n ...(question !== undefined ? { question } : {}),\n } as const;\n this._appendMessage(command, \"user\");\n this._options.send(command);\n this._notify();\n }\n\n /**\n * Cancel the current agent turn.\n *\n * Preserves partial streaming text in {@link cancelledText} so the UI can\n * display it. Clears streaming state, resets phase to `\"idle\"`, and sends\n * a `cancel` command to the agent.\n */\n cancel(): void {\n // Preserve partial streaming text so the UI can still display it\n this._cancelledText = this._streamingText;\n this._streamingText = \"\";\n this._streamingFlushed = true;\n this._phase = \"idle\";\n this._options.send({ type: \"cancel\" });\n this._notify();\n }\n\n /**\n * Update shared state for a store namespace.\n *\n * Sends a `state_update` command to the agent and optimistically\n * updates local state so the change is reflected immediately.\n *\n * @param store - Store namespace (e.g. \"app\", \"component:render-123\").\n * @param state - Full state snapshot (replaces previous).\n */\n updateState(store: string, state: Record<string, unknown>): void {\n this._options.send({ type: \"state_update\", store, state });\n // Optimistic local update\n this._sharedState = new Map(this._sharedState);\n this._sharedState.set(store, state);\n this._notify();\n }\n\n /**\n * Send an arbitrary command to the agent.\n *\n * Use this for commands that don't have a dedicated convenience method\n * (e.g. `ui_interaction`). No local state changes — the command is\n * forwarded as-is to the transport.\n *\n * @param cmd - The command to send.\n */\n send(cmd: AgentCommand): void {\n this._options.send(cmd);\n }\n\n /**\n * Load the previous page of messages and prepend them to the current list.\n *\n * No-op when `loadMessages` was not provided at construction time or when\n * all history has already been loaded ({@link isAllLoaded} is true).\n * Sets {@link isAllLoaded} to true once the server returns fewer messages\n * than the configured page size.\n */\n async loadPreviousMessages(): Promise<void> {\n if (!this._options.loadMessages || this._isAllLoaded) return;\n\n const pageSize = this._options.pageSize ?? DEFAULT_PAGE_SIZE;\n const before = this._messages.length > 0 ? this._messages[0].seq : undefined;\n const older = await this._options.loadMessages({ before, limit: pageSize });\n\n if (older.length < pageSize) this._isAllLoaded = true;\n\n const existingIds = new Set(this._messages.map((m) => m.id));\n const unique = older.filter((m) => !existingIds.has(m.id));\n this._messages = [...unique, ...this._messages];\n\n this._notify();\n }\n\n // -- External control ------------------------------------------------------\n\n /**\n * Programmatically update the connection status.\n *\n * Called by transport wrappers that cannot use the `onStatusChange`\n * callback (e.g. tRPC subscriptions that track status externally).\n *\n * @param status - The new connection status.\n */\n setStatus(status: ConnectionStatus): void {\n this._status = status;\n this._notify();\n }\n\n // -- useSyncExternalStore interface ----------------------------------------\n\n /**\n * Register a change listener. Called synchronously after every state change.\n *\n * Conforms to the `subscribe` parameter of React's `useSyncExternalStore`.\n *\n * @param listener - Callback invoked whenever state changes.\n * @returns Unsubscribe function — call to stop receiving notifications.\n */\n subscribe = (listener: () => void): (() => void) => {\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n };\n\n /**\n * Return the current immutable state snapshot.\n *\n * A new object is produced lazily on the first call after each state change.\n * Subsequent calls return the same cached object until the next change.\n * Conforms to the `getSnapshot` parameter of React's `useSyncExternalStore`.\n */\n getSnapshot = (): AgentStoreSnapshot => {\n if (!this._snapshot) {\n this._snapshot = {\n messages: this._messages,\n streamingText: this._streamingText,\n cancelledText: this._cancelledText,\n status: this._status,\n phase: this._phase,\n pendingQuestion: this._pendingQuestion,\n error: this._error,\n isAllLoaded: this._isAllLoaded,\n sharedState: this._sharedState,\n capabilities: this._capabilities,\n activeRenderInvocations: this._activeRenderInvocations,\n protocolInfo: this._protocolInfo,\n incompatibleProtocol: this._incompatibleProtocol,\n };\n }\n return this._snapshot;\n };\n\n // -- Cleanup ---------------------------------------------------------------\n\n /**\n * Unsubscribe from transport events and clear all change listeners.\n *\n * Call this when the component or service that owns the store unmounts or\n * shuts down to prevent memory leaks.\n */\n dispose(): void {\n this._unsubEvent();\n this._unsubStatus?.();\n this._listeners.clear();\n }\n\n // -- Factory ---------------------------------------------------------------\n\n /**\n * Create an {@link AgentStore} connected to a duck-typed agent client.\n *\n * Adapts the client's `send`/`onEvent`/`offEvent` API to the\n * {@link StoreTransport} interface expected by the constructor, without\n * creating a hard runtime dependency on `@skaile/workspaces/client`.\n *\n * @param client - Any object implementing {@link AgentClientLike}.\n * @param opts - Optional store configuration.\n * @param opts.sessionId - Session ID for message envelopes (defaults to a new UUID).\n * @param opts.initialMessages - Messages to pre-populate the store with.\n *\n * @example\n * ```ts\n * const store = AgentStore.fromClient(agentClient, { sessionId: 'sess-123' })\n * ```\n */\n static fromClient(\n client: AgentClientLike,\n opts?: { sessionId?: string; initialMessages?: Message[] },\n ): AgentStore {\n return new AgentStore({\n sessionId: opts?.sessionId ?? crypto.randomUUID(),\n send: (cmd) => client.send(cmd),\n onEvent: (handler) => {\n client.onEvent(handler);\n return () => client.offEvent(handler);\n },\n initialMessages: opts?.initialMessages,\n });\n }\n\n // -- Internal --------------------------------------------------------------\n\n private _handleEvent(event: AgentEvent): void {\n switch (event.type) {\n case \"text\":\n this._cancelledText = \"\";\n this._streamingText += event.content;\n this._streamingFlushed = false;\n break;\n\n case \"finished\":\n this._cancelledText = \"\";\n this._flushStreaming();\n this._appendMessage(event);\n this._phase = \"idle\";\n this._pendingQuestion = null;\n break;\n\n case \"status\":\n this._phase = event.phase;\n break;\n\n case \"user_message\":\n // A peer's message mid-turn is a boundary: finalize the in-flight text\n // so it renders before the interjection. Flush-only — the peer message\n // is delivered via the host's history, not this transient echo.\n this._flushStreaming();\n break;\n\n case \"tool_call\":\n case \"tool_result\":\n case \"file_changed\":\n case \"subagent\":\n case \"dev_server\":\n case \"handoff\":\n case \"question_reply\":\n // Flush in-flight text first so each text block becomes its own\n // Message, interleaved with tool activity in order — otherwise text\n // before and after a tool call merges into one wall-of-text blob.\n this._flushStreaming();\n this._appendMessage(event);\n break;\n\n case \"question\":\n // A pending question is a human-in-the-loop pause — the agent is waiting\n // for the user, not working. Reset to idle (like finished/error) so any\n // phase-derived busy indicator clears until the user replies.\n this._flushStreaming();\n this._phase = \"idle\";\n this._pendingQuestion = event;\n this._appendMessage(event);\n break;\n\n case \"error\":\n this._error = { message: event.message, fatal: event.fatal };\n this._streamingText = \"\";\n this._streamingFlushed = true;\n this._phase = \"idle\";\n this._appendMessage(event);\n break;\n\n case \"state_changed\":\n // Accumulate state per store namespace (notify only — no message)\n this._sharedState = new Map(this._sharedState);\n this._sharedState.set(event.store, event.state);\n break;\n\n // ── Protocol v2 ────────────────────────────────────────────────────────\n\n case \"capability_register\":\n // TRANSIENT — accumulate v2 capabilities into the registry (no message).\n this._capabilities = new Map(this._capabilities);\n for (const cap of event.capabilities) {\n this._capabilities.set(cap.name, cap);\n }\n break;\n\n case \"capability_deregister\":\n // TRANSIENT — drop capabilities by name.\n if (event.names.length > 0) {\n this._capabilities = new Map(this._capabilities);\n for (const name of event.names) {\n this._capabilities.delete(name);\n }\n }\n break;\n\n case \"render_invoked\":\n // TRANSIENT — record latest render invocation (frontend pairs with\n // the matching `Capability.render` for placement).\n this._activeRenderInvocations = new Map(this._activeRenderInvocations);\n this._activeRenderInvocations.set(event.callId, event);\n break;\n\n case \"protocol_info\":\n // TRANSIENT — runner announced its protocol version.\n this._protocolInfo = event;\n break;\n\n case \"incompatible_protocol\":\n // TRANSIENT — runner detected version drift; platform restarts session.\n this._incompatibleProtocol = event;\n break;\n\n case \"capability_invoked\":\n // Backend intercepts client-side invocations and dispatches them\n // through V2CapabilityRegistryService — frontends should not see\n // these. Drop silently if one slips through.\n return;\n\n case \"resource_response\":\n case \"resources_available\":\n // Transient — handled by ResourceClient, not AgentStore\n return;\n }\n\n this._notify();\n }\n\n private _flushStreaming(): void {\n if (this._streamingFlushed || !this._streamingText) return;\n this._appendMessage({ type: \"text\", content: this._streamingText });\n this._streamingText = \"\";\n this._streamingFlushed = true;\n }\n\n private _appendMessage(payload: AgentCommand | AgentEvent, senderId?: string): void {\n this._seq++;\n this._messages = [\n ...this._messages,\n {\n id: crypto.randomUUID(),\n seq: this._seq,\n timestamp: new Date().toISOString(),\n sessionId: this._options.sessionId,\n ...(senderId ? { senderId } : {}),\n payload,\n },\n ];\n }\n\n private _notify(): void {\n this._snapshot = null;\n for (const listener of this._listeners) {\n listener();\n }\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../factory-assets/connectors/flow/prompt-fragments.ts"],"names":[],"mappings":"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","file":"chunk-3EBFDMZC.js","sourcesContent":["/**\n * Prompt fragments for the flow connector.\n *\n * Pure functions that translate a {@link TurnStimulus} into the strings the\n * runner's flow orchestrator splices into the per-turn agent prompt.\n * Extracted from `runner/src/flow-orchestrator.ts` in Phase 3 of the\n * flow-connector extraction (2026-05-08) so the connector owns its\n * prompt-rendering surface without a runtime dep on the orchestrator.\n *\n * The contract is byte-identical to the previous inline implementation —\n * any divergence is a regression.\n *\n * @docLink packages/factory-assets/flow#prompt-fragments\n */\n\nimport type { FlowExecution } from \"@skaile/workspaces/types\";\nimport type { FlowDefinition } from \"./engine/types.js\";\n\n/**\n * Reasons why a new turn is starting. The flow orchestrator's prompt template\n * renders a stimulus-specific paragraph (via {@link renderStimulusPrompt}) so\n * the agent knows exactly why it has been invoked.\n *\n * @docLink packages/factory-assets/flow#turn-stimulus\n */\nexport type TurnStimulus =\n | { kind: \"flow_started\" }\n | {\n kind: \"approval_received\";\n nodeId: string;\n decision: \"approved\" | \"rejected\";\n feedback?: string;\n decidedBy: string;\n }\n | { kind: \"input_received\"; nodeId: string; response: unknown; providedBy: string }\n | { kind: \"retry_requested\"; nodeId: string; requestedBy: string }\n | { kind: \"user_message\"; text: string; senderId: string }\n | { kind: \"resumed_after_hibernation\" }\n | { kind: \"cancelled\" }\n | { kind: \"state_changed\" };\n\n/**\n * Render the stimulus paragraph the agent sees at turn start.\n *\n * The output is a single paragraph (one or more sentences, no surrounding\n * whitespace) describing why the runner has woken the agent. Spliced into\n * the orchestrator prompt under the `## Why this turn is happening` heading.\n *\n * @docLink packages/factory-assets/flow#render-stimulus-prompt\n */\nexport function renderStimulusPrompt(stimulus: TurnStimulus): string {\n switch (stimulus.kind) {\n case \"flow_started\":\n return \"The user just started this flow. Begin with the first available node — call `get_available`, then `build_handoff` for your chosen node, then `start_node`.\";\n case \"approval_received\": {\n const { nodeId, decision, decidedBy, feedback } = stimulus;\n if (decision === \"approved\") {\n return `Node \\`${nodeId}\\` was **approved** by ${decidedBy}. Call \\`complete_node\\` for this node with the approved output, then advance to the next available node.`;\n }\n const fb = feedback ? ` Feedback: \"${feedback}\".` : \"\";\n return `Node \\`${nodeId}\\` was **rejected** by ${decidedBy}.${fb} Decide how to proceed: retry the node (the engine returned it to \\`available\\`), ask clarifying questions via \\`request_input\\`, or call \\`fail_node(..., recoverable: false)\\` if the issue cannot be addressed.`;\n }\n case \"input_received\":\n return `The user just provided input for node \\`${stimulus.nodeId}\\` (provided by ${stimulus.providedBy}). The node has returned to its prior status. Continue executing the node with this input.`;\n case \"retry_requested\":\n return `A user requested a retry of node \\`${stimulus.nodeId}\\` (requested by ${stimulus.requestedBy}). The node has been returned to \\`available\\` with its prior error preserved in history. Start a fresh attempt — review the error context if relevant and try a different approach.`;\n case \"user_message\":\n return `A user sent a message: \"${stimulus.text}\" (from ${stimulus.senderId}). You can respond directly without touching the flow, continue flow work, or both. If the message is a question about the flow, answer it; if it signals a new direction, consider whether to pause.`;\n case \"resumed_after_hibernation\":\n return \"This session was hibernated and has just resumed. Review the current state above and continue where you left off. No state was lost.\";\n case \"cancelled\":\n return \"The user has cancelled this flow. Wrap up cleanly: do not start any new nodes. You may record a short summary if relevant, then stop.\";\n case \"state_changed\":\n return \"The flow state changed. Review the current state above and continue work accordingly.\";\n }\n}\n\n/**\n * Build the full agent-orchestrator prompt for a flow turn.\n *\n * Reassembles the five-section prompt from the current FlowExecution snapshot\n * and the supplied stimulus:\n *\n * 1. Flow definition (markdown table of nodes)\n * 2. Current state (progress, available/blocked, interaction pointers)\n * 3. Why this turn is happening (stimulus-specific paragraph)\n * 4. Flow tools available (static documentation)\n * 5. Rules\n *\n * Identical to `FlowOrchestrator.buildOrchestratorPrompt` (Phase 3 lift —\n * any divergence is a regression). Pure — depends only on its inputs.\n *\n * @docLink packages/factory-assets/flow#build-orchestrator-prompt\n * @since 2.2.0\n */\nexport function buildOrchestratorPrompt(\n flowDef: FlowDefinition,\n state: FlowExecution,\n stimulus: TurnStimulus,\n): string {\n const skillNodes = flowDef.nodes.filter((n) => n.type === \"skill\");\n\n // ── Section 1: definition table ──\n const nodeRows = skillNodes\n .map((n) => {\n const deps =\n flowDef.edges\n .filter((e) => e.target === n.id && e.type === \"flow\")\n .map((e) => e.source)\n .join(\", \") || \"—\";\n const required = n.data?.optional ? \"optional\" : \"required\";\n const gate = n.data?.approval?.mandatory ? \"mandatory\" : \"—\";\n const nodeState = state.nodes[n.id];\n const status = nodeState?.status ?? \"not_started\";\n return `| ${n.id} | ${n.data?.skill ?? n.id} | ${n.data?.label ?? n.id} | ${required} | ${gate} | ${status} | ${deps} |`;\n })\n .join(\"\\n\");\n\n // ── Section 2: current state summary ──\n const nodesByStatus = (s: string) =>\n Object.values(state.nodes)\n .filter((n) => n.status === s)\n .map((n) => n.id);\n const available = nodesByStatus(\"available\");\n const awaitingApproval = nodesByStatus(\"awaiting_approval\");\n const awaitingInput = nodesByStatus(\"awaiting_input\");\n const running = nodesByStatus(\"running\");\n const failed = nodesByStatus(\"failed\");\n const completed = nodesByStatus(\"complete\");\n const totalRequired = skillNodes.filter((n) => !n.data?.optional).length;\n\n const stateSummary = [\n `- Run ID: ${state.runId}`,\n `- Status: ${state.status}`,\n `- Autonomous mode: ${state.autonomousMode}`,\n `- Progress: ${completed.length} / ${totalRequired} required nodes complete`,\n `- Available now: ${available.join(\", \") || \"(none)\"}`,\n `- Currently running: ${running.join(\", \") || \"(none)\"}`,\n `- Awaiting approval: ${awaitingApproval.join(\", \") || \"(none)\"}`,\n `- Awaiting input: ${awaitingInput.join(\", \") || \"(none)\"}`,\n `- Failed: ${failed.join(\", \") || \"(none)\"}`,\n ].join(\"\\n\");\n\n // ── Section 3: stimulus paragraph ──\n const stimulusParagraph = renderStimulusPrompt(stimulus);\n\n // ── Section 4+5: static tool surface and rules ──\n return `# Flow Execution Context\n\nYou are orchestrating the flow **${flowDef.name}** (${flowDef.id} v${flowDef.version}). This is a governed flow execution: your job is to run nodes through the flow tools, summarize their outputs for human review, and yield control at approval gates.\n\n## Flow definition\n\n| ID | Skill | Label | Required | Gate | Status | Depends on |\n|----|-------|-------|----------|------|--------|------------|\n${nodeRows}\n\nNodes with **Gate = mandatory** are hard approval gates: they always require \\`request_approval\\` and a human decision, even when autonomous mode is on. They cannot be skipped — \\`request_approval\\` → approval is their only completion path.\n\n## Current state\n\n${stateSummary}\n\n## Why this turn is happening\n\n${stimulusParagraph}\n\n## Flow tools available\n\nAll tools are exposed by the \\`flow\\` connector:\n\n- \\`get_available()\\` — list node IDs that are ready to start\n- \\`get_state()\\` — full current state including approvals, inputs, outputs\n- \\`build_handoff(nodeId)\\` — curated context from upstream predecessors (summaries + artifacts)\n- \\`start_node(nodeId)\\` — transition \\`available\\` → \\`running\\`; call before executing the skill\n- \\`request_approval(nodeId, summary, artifacts)\\` — transition \\`running\\` → \\`awaiting_approval\\`. **This ends your turn.**\n- \\`request_input(nodeId, prompt, schema)\\` — transition to \\`awaiting_input\\`. **This ends your turn.** Legal from \\`available\\`, \\`running\\`, or \\`awaiting_approval\\`.\n- \\`complete_node(nodeId, output)\\` — transition to \\`complete\\`. Valid only if the node was approved, OR autonomousMode is true and the node is not a mandatory gate.\n- \\`fail_node(nodeId, message, recoverable)\\` — transition to \\`failed\\`. \\`recoverable=true\\` returns the node to \\`available\\`.\n- \\`skip_node(nodeId)\\` — transition to \\`skipped\\`. Only valid for optional nodes.\n\n## Rules\n\n1. Before executing a skill, call \\`start_node(nodeId)\\`.\n2. After executing the skill, call \\`request_approval\\` unless \\`autonomousMode\\` is true — in which case call \\`complete_node\\` directly. Exception: nodes marked **Gate = mandatory** always require \\`request_approval\\` and a human decision, even in autonomous mode.\n3. If you need information from the user before or during execution, call \\`request_input\\`. This ends your turn until the user responds.\n4. On unrecoverable failure, call \\`fail_node(..., recoverable: false)\\`. On recoverable failure, call \\`fail_node(..., recoverable: true)\\` and the engine returns the node to \\`available\\`.\n5. When all required nodes are \\`complete\\` or \\`skipped\\`, stop. The runner marks the flow done automatically.\n6. Free-chat user messages do not require flow action. Respond directly, continue flow work, or both — your call.\n`;\n}\n\n/**\n * Single-line tag suitable for telemetry / logging. Derives a short, stable\n * summary of a stimulus that's safe to attach to spans, log entries, and\n * trace events. The kind is always included; node-specific stimuli also\n * include their `nodeId` so log queries can pivot on it.\n *\n * @docLink packages/factory-assets/flow#describe-stimulus\n */\nexport function describeStimulus(stimulus: TurnStimulus): string {\n switch (stimulus.kind) {\n case \"flow_started\":\n return \"flow_started\";\n case \"approval_received\":\n return `approval_received:${stimulus.nodeId}:${stimulus.decision}`;\n case \"input_received\":\n return `input_received:${stimulus.nodeId}`;\n case \"retry_requested\":\n return `retry_requested:${stimulus.nodeId}`;\n case \"user_message\":\n return `user_message:${stimulus.senderId}`;\n case \"resumed_after_hibernation\":\n return \"resumed_after_hibernation\";\n case \"cancelled\":\n return \"cancelled\";\n case \"state_changed\":\n return \"state_changed\";\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../core/src/lock.ts","../core/src/manifest-yaml-editor.ts","../core/src/conformance.ts","../core/src/patch.ts","../core/src/settings.ts","../core/src/subprocess.ts","../core/src/workspace-yaml-editor.ts"],"names":["path","existsSync","readFileSync","writeFileSync","join","spawnSync","parseDocument","Document","isMap","isSeq"],"mappings":"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","file":"chunk-5NZ56R63.js","sourcesContent":["/**\n * Lock file I/O and integrity verification (schema v3).\n *\n * The lock file (skaile.lock.yaml) captures the complete resolved state: every\n * asset keyed by its canonical ref `<kind>:@<publisher>/<name>#<version>`, the\n * upstream source + commit it resolved from, a per-file + composite content\n * hash for drift detection, and whether an `overrides[]` entry pinned it. A\n * top-level `sources:` block records every contributing source URL at its\n * resolved commit.\n *\n * Old v1 lockfiles (`lockfile_version: 1`, `repositories:`) are rejected with a\n * clear regenerate-from-scratch error.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parse, stringify } from \"yaml\";\nimport type { LockEntry, LockFile, LockPluginEntry, LockSourceEntry } from \"./models.js\";\nimport type { ProvenanceCandidate } from \"./walker.js\";\n\n// ── Lock file I/O ────────────────────────────────────────────────────────────\n\n/**\n * Serialize a `LockFile` to YAML and write it to disk.\n *\n * @param lockPath - Absolute path to write the lock file (e.g. `skaile.lock.yaml`)\n * @param data - Lock file data to serialize\n * @docLink packages/core/api-reference#write-lock\n */\nexport function writeLock(lockPath: string, data: LockFile): void {\n writeFileSync(lockPath, stringify(data, { lineWidth: 120 }));\n}\n\n/**\n * Read and parse a lock file from disk.\n *\n * @param lockPath - Absolute path to the lock file\n * @returns Parsed `LockFile`, or `null` if the file is missing or unparseable\n * @throws When the file is a legacy v1 lock — the shape changed and it must be regenerated.\n * @docLink packages/core/api-reference#read-lock\n */\nexport function readLock(lockPath: string): LockFile | null {\n if (!existsSync(lockPath)) return null;\n let raw: unknown;\n try {\n raw = parse(readFileSync(lockPath, \"utf8\"));\n } catch {\n return null;\n }\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n if (r.schema_version !== 3) {\n throw new Error(\n \"outdated lockfile schema detected — the lockfile shape changed. \" +\n \"Regenerate: `rm skaile.lock.yaml && skaile install`.\",\n );\n }\n return r as unknown as LockFile;\n}\n\n// ── Hashing ──────────────────────────────────────────────────────────────────\n\n/**\n * Compute the SHA-256 hash of a file's content (hex digest, no prefix).\n *\n * @param filePath - Absolute path to the file\n * @returns Hex-encoded SHA-256 hash string\n * @docLink packages/core/api-reference#compute-hash\n */\nexport function computeHash(filePath: string): string {\n const content = readFileSync(filePath);\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n/**\n * Composite hash: SHA-256 (bare 64-hex) over `localeCompare`-sorted\n * `<path>:<sha256>\\n` rows. Matches the walker's `compositeSha256`, the store's\n * `computeCompositeSha256`, and the `InstallManifest.sha256` rollup.\n */\nfunction compositeHash(files: Array<{ path: string; sha256: string }>): string {\n const lines = files\n .slice()\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((f) => `${f.path}:${f.sha256}\\n`)\n .join(\"\");\n return createHash(\"sha256\").update(lines).digest(\"hex\");\n}\n\n// ── Lock file construction ───────────────────────────────────────────────────\n\n/**\n * Build a v3 `LockFile` from the resolver's output.\n *\n * Assets are keyed by canonical ref `<kind>:@<publisher>/<name>#<version>`; the\n * top-level `sources:` block lists every contributing source URL pinned to its\n * resolved commit.\n *\n * @param resolved - Resolved provenance candidates (the resolver's `resolved` array).\n * @param overridesApplied - Canonical refs that an `overrides[]` entry pinned.\n * @returns Complete v2 `LockFile` ready for serialization.\n * @docLink packages/core/api-reference#build-lock-file\n */\nexport function buildLockFile(\n resolved: ProvenanceCandidate[],\n overridesApplied: Set<string>,\n): LockFile {\n const assets: Record<string, LockEntry> = {};\n const sourceMap = new Map<string, LockSourceEntry>();\n\n for (const c of resolved) {\n const canonicalRef = `${c.kind}:@${c.publisher}/${c.name}#${c.version}`;\n assets[canonicalRef] = {\n sha256: c.sha256,\n source: { url: c.sourceUrl, commit: c.commit },\n files: c.files,\n override_applied: overridesApplied.has(canonicalRef),\n };\n if (!sourceMap.has(c.sourceUrl)) {\n sourceMap.set(c.sourceUrl, { url: c.sourceUrl, commit: c.commit });\n }\n }\n\n return {\n schema_version: 3,\n locked_at: new Date().toISOString(),\n assets,\n sources: Array.from(sourceMap.values()).sort((a, b) => a.url.localeCompare(b.url)),\n };\n}\n\n// ── Plugins slice ────────────────────────────────────────────────────────────\n\n/** Absolute path to a project's lock file. */\nfunction lockPathFor(projectDir: string): string {\n return join(projectDir, \"skaile.lock.yaml\");\n}\n\n/**\n * Read the `plugins` slice from a project's `skaile.lock.yaml`.\n *\n * Total — never throws on a missing/unparseable/legacy lock file (returns\n * `undefined`). The plugin-store reconciler folds this into its reconcile-hash\n * so a lock edit invalidates the hash even without a manifest change.\n *\n * @param projectDir - Project root containing `skaile.lock.yaml`\n * @returns The `plugins` record, or `undefined` when absent\n */\nexport function readPluginsLockSlice(\n projectDir: string,\n): Record<string, LockPluginEntry> | undefined {\n try {\n return readLock(lockPathFor(projectDir))?.plugins;\n } catch {\n // Legacy v1 lock — no usable plugins slice.\n return undefined;\n }\n}\n\n/**\n * Merge a `plugins` slice into a project's `skaile.lock.yaml`, preserving all\n * other fields. Creates a minimal v3 lock file when none exists (or the\n * existing one is an outdated schema that can't be read).\n *\n * @param projectDir - Project root containing `skaile.lock.yaml`\n * @param slice - The `plugins` record to persist\n */\nexport function writePluginsLockSlice(\n projectDir: string,\n slice: Record<string, LockPluginEntry>,\n): void {\n const lockPath = lockPathFor(projectDir);\n let existing: LockFile | null = null;\n try {\n existing = readLock(lockPath);\n } catch {\n existing = null; // outdated schema — overwrite with a fresh v3 shell\n }\n const next: LockFile = existing ?? {\n schema_version: 3,\n locked_at: new Date().toISOString(),\n assets: {},\n sources: [],\n };\n next.plugins = slice;\n writeLock(lockPath, next);\n}\n\n// ── Verification ─────────────────────────────────────────────────────────────\n\n/**\n * Result of verifying a lock file against the current repository state.\n * @docLink packages/core/api-reference#verify-result\n */\nexport interface VerifyResult {\n /** `true` when no drift or missing assets were found. */\n ok: boolean;\n /** Canonical refs whose content hash no longer matches. */\n drifted: string[];\n /** Canonical refs whose files cannot be found on disk. */\n missing: string[];\n}\n\n/**\n * Verify a v2 lock file against the current on-disk source clones.\n *\n * For each locked asset, resolve its source clone directory via `resolveCloneDir`\n * (URL → on-disk path), re-hash the recorded files, and compare the recomputed\n * composite against the locked `sha256`. Reports assets whose hash changed\n * (`drifted`) and assets whose files are missing (`missing`).\n *\n * @param lock - Previously generated v2 `LockFile`.\n * @param resolveCloneDir - Maps a source URL to its on-disk clone root (or null).\n * @returns `VerifyResult` indicating drift and missing assets.\n * @docLink packages/core/api-reference#verify-lock\n */\nexport function verifyLock(\n lock: LockFile,\n resolveCloneDir: (sourceUrl: string) => string | null,\n): VerifyResult {\n const drifted: string[] = [];\n const missing: string[] = [];\n\n for (const [ref, entry] of Object.entries(lock.assets)) {\n const cloneDir = resolveCloneDir(entry.source.url);\n if (!cloneDir) {\n missing.push(ref);\n continue;\n }\n let allPresent = true;\n const recomputed: Array<{ path: string; sha256: string }> = [];\n for (const f of entry.files) {\n const abs = join(cloneDir, f.path);\n if (!existsSync(abs)) {\n allPresent = false;\n break;\n }\n recomputed.push({ path: f.path, sha256: computeHash(abs) });\n }\n if (!allPresent) {\n missing.push(ref);\n continue;\n }\n if (compositeHash(recomputed) !== entry.sha256) {\n drifted.push(ref);\n }\n }\n\n return { ok: drifted.length === 0 && missing.length === 0, drifted, missing };\n}\n","/**\n * Comment-preserving editor for `skaile.manifest.yaml` files.\n *\n * The publication counterpart to {@link WorkspaceYamlEditor}: it owns the\n * `publisher` / `version` / `assets[]` accessors that used to sit on the\n * workspace editor before the 2026-06-03 manifest/workspace file split. Uses the\n * `yaml` library's Document AST so untouched sections stay byte-identical.\n *\n * Usage:\n *\n * import { ManifestYamlEditor } from '@skaile/workspaces/core'\n *\n * const editor = ManifestYamlEditor.load('/project/skaile.manifest.yaml')\n * editor.setPublisher('skaile-ai')\n * editor.setAsset({ kind: 'skill', name: 'audit', root: 'skills/audit' })\n * editor.save()\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { Document, isMap, isSeq, parseDocument, type YAMLMap } from \"yaml\";\nimport type { AssetEntry } from \"./publish-manifest.js\";\n\n/**\n * Comment-preserving editor for `skaile.manifest.yaml` files.\n * Create with `ManifestYamlEditor.load(filePath)` or `ManifestYamlEditor.create(filePath)`.\n * @docLink packages/core/publish-manifest#manifest-yaml-editor\n */\nexport class ManifestYamlEditor {\n readonly path: string;\n private doc: Document;\n\n private constructor(path: string, doc: Document) {\n this.path = path;\n this.doc = doc;\n }\n\n /** Load an existing skaile.manifest.yaml file. */\n static load(filePath: string): ManifestYamlEditor {\n if (!existsSync(filePath)) {\n throw new Error(`File not found: ${filePath}`);\n }\n const raw = readFileSync(filePath, \"utf-8\");\n return new ManifestYamlEditor(filePath, parseDocument(raw));\n }\n\n /** Create a new empty document (for use when no file exists yet). */\n static create(filePath: string): ManifestYamlEditor {\n return new ManifestYamlEditor(filePath, new Document({}));\n }\n\n /** Write the document back to disk, preserving comments and formatting. */\n save(): void {\n writeFileSync(this.path, this.doc.toString());\n }\n\n /** Return the serialized YAML string without writing to disk. */\n toString(): string {\n return this.doc.toString();\n }\n\n // ── Publisher / version / repo-level defaults ───────────────────────────────\n\n /** Get the `publisher:` field. */\n getPublisher(): string | undefined {\n const v = this.doc.get(\"publisher\");\n return v != null ? String(v) : undefined;\n }\n\n /** Set the `publisher:` field. */\n setPublisher(p: string): void {\n this.doc.set(\"publisher\", p);\n }\n\n /** Get the `version:` field. */\n getVersion(): string | undefined {\n const v = this.doc.get(\"version\");\n return v != null ? String(v) : undefined;\n }\n\n /** Set the `version:` field. */\n setVersion(v: string): void {\n this.doc.set(\"version\", v);\n }\n\n /** Get the repo-level `license:` default. */\n getLicense(): string | undefined {\n const v = this.doc.get(\"license\");\n return v != null ? String(v) : undefined;\n }\n\n /** Set the repo-level `license:` default. */\n setLicense(v: string): void {\n this.doc.set(\"license\", v);\n }\n\n /** Get the repo-level `homepage:` default. */\n getHomepage(): string | undefined {\n const v = this.doc.get(\"homepage\");\n return v != null ? String(v) : undefined;\n }\n\n /** Set the repo-level `homepage:` default. */\n setHomepage(v: string): void {\n this.doc.set(\"homepage\", v);\n }\n\n // ── Assets ──────────────────────────────────────────────────────────────────\n\n /** Get all `assets:` entries. */\n getAssets(): AssetEntry[] {\n const node = this.doc.get(\"assets\", true);\n if (!isSeq(node)) return [];\n return node.toJSON() as AssetEntry[];\n }\n\n /** Add or update an asset entry, matched by `kind` + `name`. */\n setAsset(entry: AssetEntry): void {\n const node = this.doc.get(\"assets\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"assets\", this.doc.createNode([entry]));\n return;\n }\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (\n isMap(item) &&\n (item as YAMLMap).get(\"kind\") === entry.kind &&\n (item as YAMLMap).get(\"name\") === entry.name\n ) {\n node.set(i, this.doc.createNode(entry));\n found = true;\n break;\n }\n }\n if (!found) node.add(this.doc.createNode(entry));\n }\n\n /** Remove an asset entry by kind + name. Returns true when removed. */\n removeAsset(kind: string, name: string): boolean {\n const node = this.doc.get(\"assets\", true);\n if (!node || !isSeq(node)) return false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (\n isMap(item) &&\n (item as YAMLMap).get(\"kind\") === kind &&\n (item as YAMLMap).get(\"name\") === name\n ) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Raw access (escape hatch) ─────────────────────────────────────────────\n\n /** Get the underlying yaml Document for advanced manipulation. */\n get document(): Document {\n return this.doc;\n }\n}\n","/**\n * Agent Skills (agentskills.io) open-standard conformance lint for SKILL.md\n * frontmatter — pure, advisory, never a hard gate.\n * See devlog: 2026-06-21-agentskills-conformance-shipped.\n * @docLink core/conformance\n */\n\n/** A single agentskills.io conformance finding. */\nexport interface ConformanceFinding {\n /** `error` = hard standard violation; `warn` = portability risk. */\n level: \"error\" | \"warn\";\n /** Frontmatter field the finding concerns (e.g. \"name\", \"metadata.tags\"). */\n field: string;\n /** Human-readable, ready to print after a file path. */\n message: string;\n}\n\n/** Options for {@link checkAgentSkillConformance}. */\nexport interface ConformanceOptions {\n /**\n * Parent directory name, for the standard's `name === <dir>` rule.\n * Omit to skip that check (e.g. when validating a detached frontmatter blob).\n */\n dirName?: string;\n}\n\n// Standard limits — see https://agentskills.io/specification.\nconst NAME_MAX = 64;\nconst DESCRIPTION_MAX = 1024;\nconst COMPATIBILITY_MAX = 500;\n\n/**\n * Check a SKILL.md frontmatter object against the Agent Skills open standard.\n * Returns findings only — the caller maps severity to exit codes.\n *\n * @param frontmatter Parsed SKILL.md YAML frontmatter.\n * @param opts Optional context (`dirName` enables the name==dir rule).\n * @returns Zero or more {@link ConformanceFinding}s.\n */\nexport function checkAgentSkillConformance(\n frontmatter: Record<string, unknown>,\n opts: ConformanceOptions = {},\n): ConformanceFinding[] {\n const out: ConformanceFinding[] = [];\n const name = frontmatter.name;\n\n if (typeof name === \"string\") {\n if (name.length > NAME_MAX) {\n out.push({\n level: \"error\",\n field: \"name\",\n message: `name is ${name.length} chars (standard max ${NAME_MAX})`,\n });\n }\n if (opts.dirName !== undefined && name !== opts.dirName) {\n out.push({\n level: \"warn\",\n field: \"name\",\n message: `name \"${name}\" does not match parent directory \"${opts.dirName}\" (standard requires equality)`,\n });\n }\n }\n\n const description = frontmatter.description;\n if (typeof description === \"string\" && description.length > DESCRIPTION_MAX) {\n out.push({\n level: \"error\",\n field: \"description\",\n message: `description is ${description.length} chars (standard max ${DESCRIPTION_MAX})`,\n });\n }\n\n const compatibility = frontmatter.compatibility;\n if (typeof compatibility === \"string\" && compatibility.length > COMPATIBILITY_MAX) {\n out.push({\n level: \"error\",\n field: \"compatibility\",\n message: `compatibility is ${compatibility.length} chars (standard max ${COMPATIBILITY_MAX})`,\n });\n }\n\n // The standard defines metadata as a string→string map. skaile nests objects\n // here by design — report as a portability WARN, never an error, never rewrite.\n const metadata = frontmatter.metadata;\n if (metadata !== undefined && typeof metadata === \"object\" && metadata !== null) {\n for (const [k, v] of Object.entries(metadata as Record<string, unknown>)) {\n if (typeof v !== \"string\") {\n out.push({\n level: \"warn\",\n field: `metadata.${k}`,\n message: `metadata.${k} is ${Array.isArray(v) ? \"an array\" : typeof v}, not a string — non-portable to strict skills-ref consumers`,\n });\n }\n }\n }\n\n const allowedTools = frontmatter[\"allowed-tools\"];\n if (allowedTools !== undefined && typeof allowedTools !== \"string\") {\n out.push({\n level: \"warn\",\n field: \"allowed-tools\",\n message: \"allowed-tools must be a space-separated string\",\n });\n }\n\n return out;\n}\n","/**\n * Patch operations — extract, generate, apply patches for skill improvement.\n *\n * Patches allow editing deployed assets from remote repos and contributing\n * changes back upstream via PR.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport type { CatalogEntry } from \"./models.js\";\n\n/**\n * Copy an asset's source directory into a patch working directory for editing.\n *\n * @param entry - The catalog entry to extract\n * @param patchDir - Base directory where extracted copies are placed\n * @returns Absolute path to the extracted copy (`<patchDir>/<kind>-<name>`)\n * @docLink packages/core/api-reference#extract-for-patch\n */\nexport function extractForPatch(entry: CatalogEntry, patchDir: string): string {\n const ref = `${entry.kind}-${entry.name}`;\n const dest = join(patchDir, ref);\n mkdirSync(dest, { recursive: true });\n\n // Copy the asset's source directory (or file) to the patch dir\n const sourceDir = dirname(entry.source);\n const sourceName = basename(entry.source);\n\n // If source is a file in a directory (e.g., skills/overview/SKILL.md), copy the whole dir\n if (existsSync(sourceDir)) {\n cpSync(sourceDir, dest, { recursive: true });\n }\n\n return dest;\n}\n\n/**\n * Generate a unified diff between an original and patched directory using `diff -ruN`.\n *\n * @param originalDir - Unmodified copy of the asset directory\n * @param patchedDir - Modified copy of the asset directory\n * @returns Patch content string, or `null` if there are no differences (or on error)\n * @docLink packages/core/api-reference#generate-patch\n */\nexport function generatePatch(originalDir: string, patchedDir: string): string | null {\n const r = spawnSync(\"diff\", [\"-ruN\", originalDir, patchedDir], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n\n // diff returns 0 if no differences, 1 if differences, 2 on error\n if (r.status === 0) return null; // no differences\n if (r.status === 1) return r.stdout;\n return null; // error\n}\n\n/**\n * Apply a unified diff patch file to a directory using `patch -p1`.\n *\n * @param targetDir - Directory to apply the patch to\n * @param patchFile - Path to the `.patch` file\n * @returns `true` on success, `false` if the patch file is missing or the command fails\n * @docLink packages/core/api-reference#apply-patch\n */\nexport function applyPatch(targetDir: string, patchFile: string): boolean {\n if (!existsSync(patchFile)) return false;\n const r = spawnSync(\"patch\", [\"-p1\", \"-d\", targetDir, \"-i\", patchFile], {\n stdio: \"pipe\",\n });\n return r.status === 0;\n}\n\n/**\n * Return the paths of all `.patch` files in a directory.\n *\n * @param patchDir - Directory to scan for `.patch` files\n * @returns Array of absolute paths; empty array when `patchDir` does not exist\n * @docLink packages/core/api-reference#list-patches\n */\nexport function listPatches(patchDir: string): string[] {\n if (!existsSync(patchDir)) return [];\n return readdirSync(patchDir)\n .filter((f) => f.endsWith(\".patch\"))\n .map((f) => join(patchDir, f));\n}\n\n/**\n * Write patch content to a file, creating parent directories as needed.\n *\n * @param patchPath - Destination file path (including `.patch` extension)\n * @param content - Unified diff content to write\n * @docLink packages/core/api-reference#save-patch\n */\nexport function savePatch(patchPath: string, content: string): void {\n mkdirSync(dirname(patchPath), { recursive: true });\n writeFileSync(patchPath, content, \"utf8\");\n}\n\n/**\n * Read the content of a patch file.\n *\n * @param patchPath - Path to the `.patch` file\n * @returns File content as a string, or `null` if the file does not exist\n * @docLink packages/core/api-reference#read-patch\n */\nexport function readPatch(patchPath: string): string | null {\n if (!existsSync(patchPath)) return null;\n return readFileSync(patchPath, \"utf8\");\n}\n","/**\n * User-layer runtime settings.\n *\n * SkaileSettings represents the personal, machine-specific overrides stored in\n * .skaile/settings.json (gitignored). Project-level defaults (framework, agent\n * definition, resource connections, hooks) belong in skaile.yaml via SkWorkspaceConfig.\n *\n * Resolution order (highest priority first):\n * 1. CLI flags / API overrides\n * 2. Environment variables (API keys only)\n * 3. .skaile/settings.json (project-local, walking upward)\n * 4. ~/.skaile/settings.json (user global)\n * 5. skaile.yaml defaults: (via resolveSkWorkspaceConfig — no duplicate YAML parser)\n * 6. Built-in SETTINGS_DEFAULTS\n */\n\nimport fs from \"node:fs\";\nimport fsp from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport {\n cloudConfigFromProfile,\n type CloudTransportConfig,\n resolveSkWorkspaceConfig,\n} from \"./workspace-config.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\n/**\n * All supported LLM and voice provider identifiers.\n * @docLink packages/core/settings#all-providers\n */\nexport const ALL_PROVIDERS = [\n \"anthropic\",\n \"openai\",\n \"google\",\n \"mistral\",\n \"groq\",\n \"openrouter\",\n \"deepseek\",\n \"xai\",\n \"together\",\n \"fireworks\",\n \"deepgram\",\n \"elevenlabs\",\n] as const;\n\n/**\n * Union of supported LLM and voice provider identifiers.\n * @docLink packages/core/settings#provider\n */\nexport type Provider = (typeof ALL_PROVIDERS)[number];\n\n/**\n * Personal runtime settings — stored in .skaile/settings.json (gitignored).\n * Contains only user-specific overrides: credentials, preferred model/driver.\n *\n * Project-level config (framework, resources, hooks, agent definition) lives\n * in skaile.yaml as SkWorkspaceConfig. App-specific fields (voice, domains)\n * are added by forge-common-backend via AppSettings.\n * @docLink packages/core/settings#skaile-settings\n */\nexport interface SkaileSettings {\n /** Active LLM provider identifier (e.g. \"anthropic\", \"openai\"). */\n provider?: string;\n /** Active model identifier (e.g. \"claude-sonnet-4-6\"). */\n model?: string;\n /** Bridge driver to use: \"omp\", \"claude-sdk\", or \"codex\". */\n driver?: string;\n /**\n * AI cloud transport for claude-sdk (`default|bedrock|vertex|azure|gateway`).\n * Absent = default (provider's native API). Sourced from skaile.yaml\n * `agent-config.<profile>.cloud`; string-typed for forward compat.\n *\n * @since 1.3.0\n */\n cloud?: string;\n /**\n * Non-secret cloud transport settings (camelCase; converted once from the\n * skaile.yaml `cloud_config` snake_case wire shape).\n *\n * @since 1.3.0\n */\n cloudConfig?: CloudTransportConfig;\n /** API keys keyed by provider identifier. Merged with env-var keys at resolution time. */\n apiKeys?: Record<string, string>;\n /** Framework install path overrides. Normally derived from skaile.yaml defaults. */\n skillsDir?: string;\n /** Override for the agents directory. Normally derived from skaile.yaml defaults. */\n agentsDir?: string;\n /** Override for the prompts directory. Normally derived from skaile.yaml defaults. */\n promptsDir?: string;\n /** AI Asset Store API URL (default: https://store.skaile.ai) */\n storeUrl?: string;\n /** JWT access token for the AI Asset Store */\n storeJwt?: string;\n /** Refresh token for JWT renewal */\n storeRefreshToken?: string;\n}\n\n/**\n * Built-in default settings. Lowest-priority layer in resolveSettings().\n * Override via .skaile/settings.json, ~/.skaile/settings.json, or env vars.\n * @docLink packages/core/settings#settings-defaults\n */\nexport const SETTINGS_DEFAULTS: SkaileSettings = {\n apiKeys: {},\n driver: \"omp\",\n provider: \"anthropic\",\n model: \"claude-sonnet-4-6\",\n};\n\n// ── Legacy field mapping ───────────────────────────────────────────────────\n\nconst LEGACY_FIELD_MAP: Record<string, keyof SkaileSettings> = {\n defaultProvider: \"provider\",\n defaultModel: \"model\",\n defaultAgentType: \"driver\",\n};\n\n/**\n * Rename legacy field names in a raw parsed settings object to their current equivalents.\n * Maps `defaultProvider` → `provider`, `defaultModel` → `model`, `defaultAgentType` → `driver`.\n *\n * @param raw - Raw object from JSON.parse of a settings file\n * @returns Settings with legacy keys renamed to current ones\n * @docLink packages/core/settings#map-legacy-fields\n */\nexport function mapLegacyFields(raw: Record<string, unknown>): SkaileSettings {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(raw)) {\n const mapped = LEGACY_FIELD_MAP[key];\n if (mapped) {\n if (!(mapped in result) || result[mapped] == null) result[mapped] = value;\n } else {\n result[key] = value;\n }\n }\n return result as SkaileSettings;\n}\n\n// ── Paths ──────────────────────────────────────────────────────────────────\n\nconst SKAILE_DIR = \".skaile\";\nconst SETTINGS_FILE = \"settings.json\";\n\n/**\n * Return the path to the user-global settings file: `~/.skaile/settings.json`.\n * @docLink packages/core/settings#global-settings-path\n */\nexport function globalSettingsPath(): string {\n return path.join(os.homedir(), SKAILE_DIR, SETTINGS_FILE);\n}\n\n/**\n * Return the path to the project-local settings file: `<projectDir>/.skaile/settings.json`.\n *\n * @param projectDir - Absolute path to the project root\n * @returns Absolute path to the project settings file\n * @docLink packages/core/settings#project-settings-path\n */\nexport function projectSettingsPath(projectDir: string): string {\n return path.join(projectDir, SKAILE_DIR, SETTINGS_FILE);\n}\n\n// ── I/O ────────────────────────────────────────────────────────────────────\n\n/**\n * Load and parse a settings JSON file, merging over SETTINGS_DEFAULTS.\n * Returns defaults if the file does not exist or cannot be parsed.\n *\n * @param filePath - Absolute path to a settings.json file\n * @returns Parsed settings merged with built-in defaults\n * @docLink packages/core/settings#load-settings\n */\nexport async function loadSettings(filePath: string): Promise<SkaileSettings> {\n try {\n const raw = await fsp.readFile(filePath, \"utf-8\");\n return { ...SETTINGS_DEFAULTS, ...mapLegacyFields(JSON.parse(raw)) };\n } catch {\n return { ...SETTINGS_DEFAULTS };\n }\n}\n\n/**\n * Persist settings to a JSON file, creating parent directories as needed.\n *\n * @param settings - Settings object to serialize\n * @param filePath - Absolute path to write the settings.json file\n * @docLink packages/core/settings#save-settings\n */\nexport async function saveSettings(settings: SkaileSettings, filePath: string): Promise<void> {\n await fsp.mkdir(path.dirname(filePath), { recursive: true });\n await fsp.writeFile(filePath, JSON.stringify(settings, null, 2), \"utf-8\");\n}\n\n/**\n * Walk upward from `projectDir` (max 10 levels) and collect all\n * `.skaile/settings.json` paths found along the way.\n * Results are ordered nearest-to-root first.\n *\n * @param projectDir - Starting directory for the upward walk\n * @returns Array of absolute paths to settings files found\n * @docLink packages/core/settings#walk-for-settings\n */\nexport function walkForSettings(projectDir: string): string[] {\n const found: string[] = [];\n let dir = path.resolve(projectDir);\n const root = path.parse(dir).root;\n for (let i = 0; i < 10; i++) {\n const candidate = path.join(dir, SKAILE_DIR, SETTINGS_FILE);\n if (fs.existsSync(candidate)) found.push(candidate);\n const parent = path.dirname(dir);\n if (parent === dir || parent === root) break;\n dir = parent;\n }\n return found;\n}\n\n// ── Resolution ─────────────────────────────────────────────────────────────\n\nfunction mergeSettings(base: SkaileSettings, source: Partial<SkaileSettings>): SkaileSettings {\n const result = { ...base };\n for (const [key, value] of Object.entries(source)) {\n if (value !== undefined && value !== null && value !== \"\") {\n if (key === \"apiKeys\" && typeof value === \"object\") {\n result.apiKeys = { ...result.apiKeys, ...(value as Record<string, string>) };\n } else {\n (result as any)[key] = value;\n }\n }\n }\n return result;\n}\n\n/** Derive a SkaileSettings-compatible layer from SkWorkspaceConfig agent_config.default. */\nfunction settingsFromWorkspaceConfig(projectDir: string): SkaileSettings {\n try {\n const ws = resolveSkWorkspaceConfig(projectDir);\n // Read agent_config.default\n const p = ws.agent_config?.default;\n if (!p) return {};\n const result: SkaileSettings = {};\n if (p.driver) result.driver = p.driver;\n if (p.provider) result.provider = p.provider;\n if (p.cloud) result.cloud = p.cloud;\n const cloudConfig = cloudConfigFromProfile(p);\n if (cloudConfig) result.cloudConfig = cloudConfig;\n if (p.model) result.model = p.model;\n if (p.skills_dir) result.skillsDir = p.skills_dir;\n if (p.agents_dir) result.agentsDir = p.agents_dir;\n if (p.prompts_dir) result.promptsDir = p.prompts_dir;\n return result;\n } catch {\n return {};\n }\n}\n\n// ── Migration ──────────────────────────────────────────────────────────────\n\nconst _migrated = new Set<string>();\n\n/**\n * One-time migration from old config locations to .skaile/settings.json.\n * Does not delete old files — user can do that manually.\n * @docLink packages/core/settings#migrate-settings\n */\nexport async function migrateSettings(projectDir: string): Promise<void> {\n const resolved = path.resolve(projectDir);\n if (_migrated.has(resolved)) return;\n\n const targetPath = projectSettingsPath(resolved);\n if (fs.existsSync(targetPath)) {\n _migrated.add(resolved);\n return;\n }\n\n const sources: Record<string, unknown>[] = [];\n\n // Old location 1: data/settings.json (forge-project)\n const dataSettings = path.join(resolved, \"data\", \"settings.json\");\n if (fs.existsSync(dataSettings)) {\n try {\n sources.push(JSON.parse(fs.readFileSync(dataSettings, \"utf-8\")));\n } catch {}\n }\n\n // Old location 2: .cf/settings.json (forge-concept)\n const cfSettings = path.join(resolved, \".cf\", \"settings.json\");\n if (fs.existsSync(cfSettings)) {\n try {\n sources.push(JSON.parse(fs.readFileSync(cfSettings, \"utf-8\")));\n } catch {}\n }\n\n // Old location 3: .skaile/config.json (old SkailConfig)\n const oldConfig = path.join(resolved, \".skaile\", \"config.json\");\n if (fs.existsSync(oldConfig)) {\n try {\n sources.push(JSON.parse(fs.readFileSync(oldConfig, \"utf-8\")));\n } catch {}\n }\n\n if (sources.length > 0) {\n let merged: SkaileSettings = {};\n for (const source of sources) {\n merged = mergeSettings(merged, mapLegacyFields(source as Record<string, unknown>));\n }\n await saveSettings(merged, targetPath);\n }\n\n _migrated.add(resolved);\n}\n\n/**\n * Resolve effective settings through the 6-layer priority chain:\n * overrides > env vars (PREFERRED_PROVIDER, PREFERRED_MODEL, *_API_KEY) >\n * .skaile/settings.json (walks upward) > ~/.skaile/settings.json >\n * skaile.yaml agent_config defaults > SETTINGS_DEFAULTS.\n *\n * @param projectDir - Root directory of the project being operated on\n * @param overrides - Optional top-priority overrides (CLI flags, API body)\n * @returns Merged effective settings\n * @docLink packages/core/settings#resolve-settings\n */\nexport async function resolveSettings(\n projectDir: string,\n overrides?: Partial<SkaileSettings>,\n): Promise<SkaileSettings> {\n await migrateSettings(projectDir);\n\n // Base: built-in defaults\n let merged: SkaileSettings = { ...SETTINGS_DEFAULTS };\n\n // Layer: workspace config defaults (skaile.yaml via resolveSkWorkspaceConfig)\n merged = mergeSettings(merged, settingsFromWorkspaceConfig(projectDir));\n\n // Layer: user global settings\n const globalPath = globalSettingsPath();\n if (fs.existsSync(globalPath)) {\n try {\n const raw = JSON.parse(fs.readFileSync(globalPath, \"utf-8\"));\n merged = mergeSettings(merged, mapLegacyFields(raw));\n } catch {}\n }\n\n // Layer: project-local .skaile/settings.json (walking upward, farthest first)\n const settingsFiles = walkForSettings(projectDir);\n for (const filePath of settingsFiles.reverse()) {\n if (path.resolve(filePath) === path.resolve(globalPath)) continue;\n try {\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n merged = mergeSettings(merged, mapLegacyFields(raw));\n } catch {}\n }\n\n // Layer: environment variables (API keys + preferred provider/model)\n const envKeys = detectEnvApiKeys();\n if (Object.keys(envKeys).length > 0) {\n merged.apiKeys = { ...merged.apiKeys, ...envKeys };\n }\n if (process.env.PREFERRED_PROVIDER) merged.provider = process.env.PREFERRED_PROVIDER;\n if (process.env.PREFERRED_MODEL) merged.model = process.env.PREFERRED_MODEL;\n\n // Layer: explicit overrides\n if (overrides) merged = mergeSettings(merged, overrides);\n\n return merged;\n}\n\n// ── Provider / API key helpers ─────────────────────────────────────────────\n\n/**\n * Return the environment variable name for a provider's API key.\n * e.g. `providerEnvKey('anthropic')` → `'ANTHROPIC_API_KEY'`\n *\n * @param provider - Provider identifier (e.g. \"anthropic\", \"openai\")\n * @returns Environment variable name for that provider's API key\n * @docLink packages/core/settings#provider-env-key\n */\nexport function providerEnvKey(provider: string): string {\n return `${provider.toUpperCase().replace(/[^A-Z0-9]/g, \"_\")}_API_KEY`;\n}\n\n/**\n * Return the active API key for the given provider.\n * The matching environment variable (`*_API_KEY`) takes priority over\n * the value stored in `settings.apiKeys`.\n * Applies to `cloud: default`/`gateway` only — bedrock/vertex/azure sessions\n * carry their credentials as env bundles resolved by the runner instead.\n *\n * @param provider - Provider identifier (e.g. \"anthropic\")\n * @param settings - Current effective settings\n * @returns API key string, or undefined if not configured\n * @docLink packages/core/settings#resolve-api-key\n */\nexport function resolveApiKey(provider: string, settings: SkaileSettings): string | undefined {\n return process.env[providerEnvKey(provider)] || settings.apiKeys?.[provider];\n}\n\n/**\n * Return a masked version of an API key for safe logging.\n * Shows only the last four characters (e.g. `'****abc1'`).\n *\n * @param key - Raw API key to mask\n * @returns Masked key string, or empty string if key is falsy\n * @docLink packages/core/settings#mask-api-key\n */\nexport function maskApiKey(key: string): string {\n return key ? `****${key.slice(-4)}` : \"\";\n}\n\n/**\n * An API key resolved with information about where it came from.\n * @docLink packages/core/settings#resolved-key\n */\nexport interface ResolvedKey {\n /** Masked API key value (last 4 chars visible). */\n key: string;\n /** Whether the key came from an environment variable or stored settings. */\n source: \"env\" | \"stored\";\n}\n\n/**\n * Scan process.env (plus any `extraEnv` overrides) for recognized API key\n * variables and return them as a partial `apiKeys` record keyed by provider id.\n *\n * @param extraEnv - Additional environment entries to merge over process.env\n * @returns Partial apiKeys record containing only providers whose key was found\n * @docLink packages/core/settings#detect-env-api-keys\n */\nexport function detectEnvApiKeys(extraEnv?: Record<string, string>): Record<string, string> {\n const env = { ...process.env, ...extraEnv };\n const detected: Record<string, string> = {};\n for (const provider of ALL_PROVIDERS) {\n const val = env[providerEnvKey(provider)];\n if (val) detected[provider] = val;\n }\n return detected;\n}\n\n/**\n * Build a resolved key map for all known providers with source info and masked values.\n * Env-var keys take priority over stored keys when both exist.\n *\n * @param settings - Current effective settings (provides stored apiKeys)\n * @param envKeys - Keys detected from environment (e.g. from detectEnvApiKeys())\n * @returns Map from provider id to resolved key info; omits providers with no key\n * @docLink packages/core/settings#resolve-all-keys\n */\nexport function resolveAllKeys(\n settings: SkaileSettings,\n envKeys: Record<string, string>,\n): Record<string, ResolvedKey> {\n const result: Record<string, ResolvedKey> = {};\n for (const provider of ALL_PROVIDERS) {\n const envVal = envKeys[provider];\n const storedVal = settings.apiKeys?.[provider];\n if (envVal) {\n result[provider] = { key: maskApiKey(envVal), source: \"env\" };\n } else if (storedVal) {\n result[provider] = { key: maskApiKey(storedVal), source: \"stored\" };\n }\n }\n return result;\n}\n","/**\n * Runtime-portable subprocess spawning.\n *\n * `node:child_process` is implemented by both Node and Bun, so it is the\n * portable choice — no runtime detection needed (unlike embedded SQLite,\n * which has no shared API; see `logging/sinks/sqlite-runtime.ts`).\n *\n * These helpers wrap `node:child_process` to present a `Bun.Subprocess`-shaped\n * result — web `ReadableStream` stdio plus an `exited` promise — so call sites\n * migrated off `Bun.spawn` keep their stream-reading code unchanged.\n */\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { Readable } from \"node:stream\";\n\nexport interface PortableSpawnOptions {\n cwd?: string;\n env?: Record<string, string | undefined>;\n detached?: boolean;\n}\n\n/** A spawned process with stdout/stderr piped. Mirrors the shape of `Bun.Subprocess`. */\nexport interface PortableSubprocess {\n /** OS process id, or -1 if the process failed to spawn. */\n readonly pid: number;\n readonly stdout: ReadableStream<Uint8Array>;\n readonly stderr: ReadableStream<Uint8Array>;\n /** Resolves with the exit code once the process closes (-1 on spawn error). */\n readonly exited: Promise<number>;\n kill(signal?: number | NodeJS.Signals): void;\n}\n\nexport interface PortableSpawnSyncResult {\n /** Exit code; -1 when the process did not exit cleanly. */\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n/**\n * Spawn a subprocess with stdout/stderr piped. Works under Node and Bun.\n *\n * @param cmd - Command and arguments, e.g. `[\"docker\", \"ps\"]`.\n */\nexport function portableSpawn(cmd: string[], opts: PortableSpawnOptions = {}): PortableSubprocess {\n const [bin, ...args] = cmd;\n if (!bin) throw new Error(\"portableSpawn: empty command\");\n const child = spawn(bin, args, {\n cwd: opts.cwd,\n env: opts.env ?? process.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: opts.detached,\n });\n const exited = new Promise<number>((resolve) => {\n child.on(\"close\", (code) => resolve(code ?? 0));\n child.on(\"error\", () => resolve(-1));\n });\n return {\n pid: child.pid ?? -1,\n stdout: Readable.toWeb(child.stdout as Readable) as unknown as ReadableStream<Uint8Array>,\n stderr: Readable.toWeb(child.stderr as Readable) as unknown as ReadableStream<Uint8Array>,\n exited,\n kill: (signal) => {\n if (opts.detached && child.pid) {\n try {\n process.kill(-child.pid, signal);\n return;\n } catch {\n /* fall back to killing the direct child */\n }\n }\n child.kill(signal);\n },\n };\n}\n\n/**\n * Run a subprocess to completion synchronously, capturing stdout/stderr as\n * UTF-8 strings. Works under Node and Bun.\n *\n * @param cmd - Command and arguments, e.g. `[\"docker\", \"info\"]`.\n */\nexport function portableSpawnSync(\n cmd: string[],\n opts: PortableSpawnOptions = {},\n): PortableSpawnSyncResult {\n const [bin, ...args] = cmd;\n if (!bin) throw new Error(\"portableSpawnSync: empty command\");\n const result = spawnSync(bin, args, {\n cwd: opts.cwd,\n env: opts.env ?? process.env,\n encoding: \"utf8\",\n });\n return {\n exitCode: result.status ?? -1,\n stdout: result.stdout ?? \"\",\n stderr: result.stderr ?? \"\",\n };\n}\n","/**\n * Comment-preserving editor for skaile.yaml files.\n *\n * Uses the `yaml` library's Document API to parse into an AST that retains\n * comments, blank lines, and formatting. Mutations are applied to the AST\n * and serialized back — untouched sections remain byte-identical.\n *\n * Usage:\n *\n * import { WorkspaceYamlEditor } from '@skaile/workspaces/core'\n *\n * const editor = WorkspaceYamlEditor.load('/project/skaile.yaml')\n * editor.setAgentConfig('default', { driver: 'claude-sdk', model: 'claude-sonnet-4-6' })\n * editor.setSource({ url: 'https://github.com/skaile-ai/ai-assets' })\n * editor.save()\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { Document, isMap, isSeq, parseDocument, type YAMLMap } from \"yaml\";\nimport type {\n AgentConfigProfile,\n ConnectorDeclaration,\n McpServerDeclaration,\n OverrideEntry,\n SourceEntry,\n StoreEntry,\n} from \"./workspace-config.js\";\n\n/**\n * Comment-preserving editor for `skaile.yaml` files.\n * Uses the `yaml` library's Document AST so untouched sections remain byte-identical.\n * Create with `WorkspaceYamlEditor.load(filePath)` or `WorkspaceYamlEditor.create(filePath)`.\n * @docLink packages/core/workspace-config#workspace-yaml-editor\n */\nexport class WorkspaceYamlEditor {\n readonly path: string;\n private doc: Document;\n\n private constructor(path: string, doc: Document) {\n this.path = path;\n this.doc = doc;\n }\n\n /** Load an existing skaile.yaml file. */\n static load(filePath: string): WorkspaceYamlEditor {\n if (!existsSync(filePath)) {\n throw new Error(`File not found: ${filePath}`);\n }\n const raw = readFileSync(filePath, \"utf-8\");\n const doc = parseDocument(raw);\n return new WorkspaceYamlEditor(filePath, doc);\n }\n\n /** Create a new empty document (for use when no file exists yet). */\n static create(filePath: string): WorkspaceYamlEditor {\n const doc = new Document({});\n return new WorkspaceYamlEditor(filePath, doc);\n }\n\n /** Write the document back to disk, preserving comments and formatting. */\n save(): void {\n writeFileSync(this.path, this.doc.toString());\n }\n\n /** Return the serialized YAML string without writing to disk. */\n toString(): string {\n return this.doc.toString();\n }\n\n // ── Scalar fields ──────────────────────────────────────────────────────────\n\n /** Get a top-level scalar field (name, description). */\n get(key: \"name\" | \"description\"): string | undefined {\n const val = this.doc.get(key);\n return val != null ? String(val) : undefined;\n }\n\n /** Set a top-level scalar field. */\n set(key: \"name\" | \"description\", value: string): void {\n this.doc.set(key, value);\n }\n\n // ── Agent config ──────────────────────────────────────────────────────────\n\n /**\n * Get an agent config profile by name (usually \"default\").\n * Reads from `agent-config` (canonical YAML key).\n */\n getAgentConfig(profile = \"default\"): AgentConfigProfile | undefined {\n const section = this._getAgentConfigSection();\n if (!section) return undefined;\n const val = section.get(profile);\n return val && typeof val === \"object\" ? (val as unknown as AgentConfigProfile) : undefined;\n }\n\n /**\n * Set fields on an agent config profile. Merges with existing values —\n * only the provided fields are overwritten.\n */\n setAgentConfig(profile: string, values: Partial<AgentConfigProfile>): void {\n let section = this._getAgentConfigSection();\n if (!section) {\n // Create the section. Use 'agent-config' as the canonical YAML key.\n this.doc.set(\"agent-config\", { [profile]: {} });\n section = this._getAgentConfigSection()!;\n }\n\n const existing = section.get(profile, true);\n if (!existing || !isMap(existing)) {\n section.set(profile, { ...values });\n return;\n }\n\n for (const [k, v] of Object.entries(values)) {\n if (v === undefined) continue;\n existing.set(k, v);\n }\n }\n\n /**\n * Delete a field from an agent config profile.\n */\n deleteAgentConfigField(profile: string, field: string): void {\n const section = this._getAgentConfigSection();\n if (!section) return;\n const profileNode = section.get(profile, true);\n if (isMap(profileNode)) {\n profileNode.delete(field);\n }\n }\n\n private _getAgentConfigSection(): YAMLMap | undefined {\n // Try canonical 'agent-config' first, then 'agent_config'\n const node = this.doc.get(\"agent-config\", true) ?? this.doc.get(\"agent_config\", true);\n return isMap(node) ? (node as YAMLMap) : undefined;\n }\n\n // ── Connectors ─────────────────────────────────────────────────────────────\n\n /** Get all connectors. */\n getConnectors(): ConnectorDeclaration[] {\n const node = this.doc.get(\"connectors\", true) ?? this.doc.get(\"data_resources\", true);\n if (!isSeq(node)) return [];\n return node.toJSON() as ConnectorDeclaration[];\n }\n\n /** Add or update a connector by id. */\n setConnector(connector: ConnectorDeclaration): void {\n const key = \"connectors\";\n const node = this.doc.get(key, true);\n\n if (!node || !isSeq(node)) {\n this.doc.set(key, this.doc.createNode([connector]));\n return;\n }\n\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"id\") === connector.id) {\n node.set(i, this.doc.createNode(connector));\n found = true;\n break;\n }\n }\n\n if (!found) {\n node.add(this.doc.createNode(connector));\n }\n }\n\n /** Remove a connector by id. */\n removeConnector(id: string): boolean {\n const key = this.doc.has(\"connectors\") ? \"connectors\" : \"data_resources\";\n const node = this.doc.get(key, true);\n if (!node || !isSeq(node)) return false;\n\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"id\") === id) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── MCP servers ────────────────────────────────────────────────────────────\n\n /**\n * Add or replace an mcp server entry, matched by `id`.\n * Mirrors {@link setConnector}: an existing entry with the same `id` is\n * replaced in place; otherwise the declaration is appended.\n */\n setMcpServer(mcp: McpServerDeclaration): void {\n const key = \"mcp_servers\";\n const node = this.doc.get(key, true);\n\n if (!node || !isSeq(node)) {\n this.doc.set(key, this.doc.createNode([mcp]));\n return;\n }\n\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"id\") === mcp.id) {\n node.set(i, this.doc.createNode(mcp));\n found = true;\n break;\n }\n }\n\n if (!found) {\n node.add(this.doc.createNode(mcp));\n }\n }\n\n // ── Dependencies ───────────────────────────────────────────────────────────\n\n /**\n * Append a dependency ref to `dependencies:`, deduped by exact ref string.\n *\n * @param ref - Canonical dependency ref (e.g. `skill:@skaile/foo#1.0.0`).\n * @returns `true` when the ref was newly added, `false` when it was already present.\n */\n addDependency(ref: string): boolean {\n const node = this.doc.get(\"dependencies\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"dependencies\", this.doc.createNode([ref]));\n return true;\n }\n for (const item of node.items) {\n const cur = item != null && typeof item === \"object\" && \"value\" in item ? item.value : item;\n if (cur === ref) return false;\n }\n node.add(this.doc.createNode(ref));\n return true;\n }\n\n // ── Plugins ────────────────────────────────────────────────────────────────\n\n /** Get all `plugins:` specifiers. */\n getPlugins(): string[] {\n const node = this.doc.get(\"plugins\", true);\n if (!isSeq(node)) return [];\n const out: string[] = [];\n for (const item of node.items) {\n const cur = item != null && typeof item === \"object\" && \"value\" in item ? item.value : item;\n if (typeof cur === \"string\") out.push(cur);\n }\n return out;\n }\n\n /**\n * Add a plugin specifier to `plugins:`, deduped by package name.\n * If an entry with the same package name exists it is replaced (so a version\n * bump re-pins in place); otherwise the spec is appended.\n *\n * @param spec - npm specifier, e.g. `\"@skaile/provider-fly@^0.1.0\"`.\n * @param nameOf - Extracts the package name from a spec (caller passes `parseSpec`-derived names).\n * @returns `true` when an existing entry was replaced, `false` when appended.\n */\n addPlugin(spec: string, nameOf: (s: string) => string): boolean {\n const node = this.doc.get(\"plugins\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"plugins\", this.doc.createNode([spec]));\n return false;\n }\n\n const wantName = nameOf(spec);\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n const cur = item != null && typeof item === \"object\" && \"value\" in item ? item.value : item;\n if (typeof cur === \"string\" && nameOf(cur) === wantName) {\n node.set(i, this.doc.createNode(spec));\n return true;\n }\n }\n node.add(this.doc.createNode(spec));\n return false;\n }\n\n /**\n * Remove the `plugins:` entry whose package name matches `name`.\n *\n * @param name - Package name to remove (e.g. `\"@skaile/provider-fly\"`).\n * @param nameOf - Extracts the package name from a spec.\n * @returns `true` when an entry was removed.\n */\n removePlugin(name: string, nameOf: (s: string) => string): boolean {\n const node = this.doc.get(\"plugins\", true);\n if (!node || !isSeq(node)) return false;\n\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n const cur = item != null && typeof item === \"object\" && \"value\" in item ? item.value : item;\n if (typeof cur === \"string\" && nameOf(cur) === name) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Sources ────────────────────────────────────────────────────────────────\n\n /** Get all source entries (`{url, pin?}`). */\n getSources(): SourceEntry[] {\n const node = this.doc.get(\"sources\", true);\n if (!isSeq(node)) return [];\n return node.toJSON() as SourceEntry[];\n }\n\n /**\n * Add or update a source entry, matched by `url`.\n * If an entry with the same url exists, it is replaced.\n */\n setSource(entry: SourceEntry): void {\n const node = this.doc.get(\"sources\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"sources\", this.doc.createNode([entry]));\n return;\n }\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"url\") === entry.url) {\n node.set(i, this.doc.createNode(entry));\n found = true;\n break;\n }\n }\n if (!found) node.add(this.doc.createNode(entry));\n }\n\n /** Remove a source entry by url. Returns true when an entry was removed. */\n removeSource(url: string): boolean {\n const node = this.doc.get(\"sources\", true);\n if (!node || !isSeq(node)) return false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"url\") === url) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Stores ─────────────────────────────────────────────────────────────────\n\n /** Get all store entries (`{url}`). */\n getStores(): StoreEntry[] {\n const node = this.doc.get(\"stores\", true);\n if (!isSeq(node)) return [];\n return node.toJSON() as StoreEntry[];\n }\n\n /** Add or update a store entry, matched by `url`. */\n setStore(entry: StoreEntry): void {\n const node = this.doc.get(\"stores\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"stores\", this.doc.createNode([entry]));\n return;\n }\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"url\") === entry.url) {\n node.set(i, this.doc.createNode(entry));\n found = true;\n break;\n }\n }\n if (!found) node.add(this.doc.createNode(entry));\n }\n\n /** Remove a store entry by url. Returns true when an entry was removed. */\n removeStore(url: string): boolean {\n const node = this.doc.get(\"stores\", true);\n if (!node || !isSeq(node)) return false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"url\") === url) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Overrides ────────────────────────────────────────────────────────────────\n\n /** Get all override entries (`{ref, source, reason}`). */\n getOverrides(): OverrideEntry[] {\n const node = this.doc.get(\"overrides\", true);\n if (!isSeq(node)) return [];\n return node.toJSON() as OverrideEntry[];\n }\n\n /** Add or update an override entry, matched by `ref`. */\n setOverride(entry: OverrideEntry): void {\n const node = this.doc.get(\"overrides\", true);\n if (!node || !isSeq(node)) {\n this.doc.set(\"overrides\", this.doc.createNode([entry]));\n return;\n }\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"ref\") === entry.ref) {\n node.set(i, this.doc.createNode(entry));\n found = true;\n break;\n }\n }\n if (!found) node.add(this.doc.createNode(entry));\n }\n\n /** Remove an override entry by ref. Returns true when an entry was removed. */\n removeOverride(ref: string): boolean {\n const node = this.doc.get(\"overrides\", true);\n if (!node || !isSeq(node)) return false;\n for (let i = 0; i < node.items.length; i++) {\n const item = node.items[i];\n if (isMap(item) && (item as YAMLMap).get(\"ref\") === ref) {\n node.delete(i);\n return true;\n }\n }\n return false;\n }\n\n // ── Raw access (escape hatch) ─────────────────────────────────────────────\n\n /** Get the underlying yaml Document for advanced manipulation. */\n get document(): Document {\n return this.doc;\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../core/src/runtime-assets.ts"],"names":["resolvePath","require"],"mappings":"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","file":"chunk-7J7LQP6T.js","sourcesContent":["/**\n * Runtime asset resolution — read `skaile.yaml`, scan all declared repositories\n * (including the built-in `factory-assets/` directory as an implicit default),\n * and produce a unified view of connector catalog entries plus the implicit refs\n * that the `skaile.yaml` `connectors:` section adds to the dependency graph.\n *\n * This module is the single source of truth for \"which connectors does this\n * project see at runtime, and where do their implementations live on disk\".\n * Both the runner (serve, REPL, flow) and the platform's mid-session\n * `add_resource` flow consume `RuntimeAssetsResult.catalogEntries` and pass\n * it into `ConnectorManager` for catalog-based resolution.\n *\n * `factory-assets/` is the single first-party content tree (built-in connectors\n * + first-party skills + bundles) shipped inside the `@skaile/workspaces`\n * package — not a standalone package.\n *\n * It resolves to an **ordered list of roots** ({@link factoryAssetRoots}), not a\n * single dir. The bundled tree is always the baseline; an optional\n * `SKAILE_FACTORY_ASSETS_DIR` (legacy: `SKAILE_BASE_ASSETS_DIR`) is layered\n * **in front** as an additive override source — the agent container points it at\n * `/app/factory-assets/` (or a bind-mounted host dir) to ship updated skills /\n * flows / bundles / connector manifests without rebuilding the image. The two\n * roots resolve uniformly across every consumer (connector catalog scan, skill /\n * flow / completion discovery, the asset-manager factory source):\n * 1. `SKAILE_FACTORY_ASSETS_DIR` env dir, when set and existing (override layer).\n * 2. the bundled tree via {@link resolvePackagedAssetsDir} — the in-repo source\n * `packages/workspaces/factory-assets/` during dev, else the published\n * `dist/factory-assets/` after install (always-present baseline).\n *\n * Override semantics are **env-first**: on a name conflict the env root wins and\n * the bundled root fills the rest. Connector *code* still loads via the package's\n * static `exports` map, so the env root can override/add skills, flows, bundles,\n * and connector **manifests/metadata**, but cannot ship a new executable\n * connector — its `.js` is not on the package's import graph.\n */\n\nimport { existsSync, lstatSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve as resolvePath } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { scanDirectory } from \"./manifest.js\";\nimport type { CatalogEntry } from \"./models.js\";\nimport { getGlobalCacheDir, readLinks, sourceCacheKey } from \"./repo-manager.js\";\nimport type { SourceDeclaration, SourceEntry } from \"./workspace-config.js\";\nimport { resolveSkWorkspaceConfig } from \"./workspace-config.js\";\n\n/**\n * Map declared `sources[]` to internal `SourceDeclaration`s keyed by the\n * collision-free {@link sourceCacheKey} (`<host>/<owner>/<repo>`), pointing at\n * the unified machine-cache clone path (`getGlobalCacheDir()/<key>/`). Keyed by\n * the same function every other cache writer/reader uses so the path resolves.\n */\nfunction sourcesToDeclarations(\n sources: SourceEntry[] | undefined,\n): Record<string, SourceDeclaration> {\n const sourcesDir = getGlobalCacheDir();\n const out: Record<string, SourceDeclaration> = {};\n for (const s of sources ?? []) {\n const key = sourceCacheKey(s.url);\n if (out[key]) continue;\n out[key] = { path: join(sourcesDir, key), url: s.url, branch: s.pin };\n }\n return out;\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/**\n * Catalog entry filtered to mount/connector kinds. Same shape as `CatalogEntry`.\n * @docLink packages/core/concepts#runtime-catalog-entry\n */\nexport type RuntimeCatalogEntry = CatalogEntry;\n\n/**\n * Implicit catalog reference derived from a `connectors:` declaration in `skaile.yaml`.\n * Each connector driver becomes an implicit ref that must be resolved in the catalog.\n * @docLink packages/core/concepts#runtime-asset-ref\n */\nexport interface RuntimeAssetRef {\n kind: \"connector\";\n /** Driver name — matches `RuntimeCatalogEntry.name`. */\n name: string;\n /** Source declaration id from `skaile.yaml`. */\n declarationId: string;\n}\n\n/**\n * Aggregated npm packages required by all resolved mount/connector adapters.\n * Populated from `metadata.npm_deps` in each matched catalog entry.\n * @docLink packages/core/concepts#runtime-npm-deps\n */\nexport interface RuntimeNpmDeps {\n required: string[];\n optional: string[];\n}\n\n/**\n * Non-fatal warning emitted during `resolveRuntimeAssets` when a repo is unavailable\n * or a driver is not found in any catalog.\n * @docLink packages/core/concepts#runtime-asset-warning\n */\nexport interface RuntimeAssetWarning {\n /** Stable code for filtering / structured logging. */\n code: \"missing_driver\" | \"repo_unavailable\" | \"invalid_repo_decl\";\n message: string;\n /** Declaration id when applicable. */\n declarationId?: string;\n /** Driver / repository name when applicable. */\n name?: string;\n}\n\n/**\n * Repository name used for the implicit built-in `factory-assets` catalog entry\n * (the in-package connector tree).\n * @docLink packages/core/concepts#factory-assets-repo-name\n */\nexport const FACTORY_ASSETS_REPO_NAME = \"factory-assets\";\n\n/**\n * Repository name for the optional `SKAILE_FACTORY_ASSETS_DIR` override layer,\n * scanned ahead of (and overriding) the bundled {@link FACTORY_ASSETS_REPO_NAME}.\n */\nconst FACTORY_ASSETS_OVERRIDE_REPO_NAME = \"factory-assets:override\";\n\n/**\n * Result of `resolveRuntimeAssets`.\n * The same object is mutated in place by `refresh()`, allowing callers to hold\n * a stable reference and observe updates after a new repository is cloned or\n * a driver is installed mid-session.\n * @docLink packages/core/concepts#runtime-assets-result\n */\nexport interface RuntimeAssetsResult {\n catalogEntries: RuntimeCatalogEntry[];\n implicitRefs: RuntimeAssetRef[];\n requiredNpmDeps: RuntimeNpmDeps;\n warnings: RuntimeAssetWarning[];\n /** Re-scan repositories and re-derive implicit refs. Mutates in place. */\n refresh(): Promise<void>;\n /**\n * Catalog lookup. When `kind` is omitted and multiple entries share the\n * `name`, returns `undefined` (caller must disambiguate).\n */\n findEntry(query: { kind?: \"connector\"; name: string }): RuntimeCatalogEntry | undefined;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Resolve all runtime assets visible to a project by scanning declared repositories.\n *\n * Reads `skaile.yaml`, scans every declared repository (plus the implicit\n * built-in `factory-assets` repo), and derives implicit refs from `mounts:` /\n * `connectors:` declarations. Does not clone or install anything — purely a\n * read-only scan of what is already on disk. URL-only repositories that have\n * not been cloned yet are reported as `repo_unavailable` warnings.\n *\n * @param projectDir - Absolute path to the project workspace root\n * @returns `RuntimeAssetsResult` with catalog entries, implicit refs, npm deps, and warnings\n * @docLink packages/core/concepts#resolve-runtime-assets\n */\nexport async function resolveRuntimeAssets(projectDir: string): Promise<RuntimeAssetsResult> {\n const result: RuntimeAssetsResult = {\n catalogEntries: [],\n implicitRefs: [],\n requiredNpmDeps: { required: [], optional: [] },\n warnings: [],\n refresh: async () => {\n await populate(projectDir, result);\n },\n findEntry: (query) => findCatalogEntry(result.catalogEntries, query),\n };\n\n await populate(projectDir, result);\n return result;\n}\n\n/**\n * Resolve the ordered list of on-disk roots for the built-in `factory-assets`\n * tree (built-in connectors + first-party skills + bundles). This is the single\n * shared resolver every consumer goes through, so the env override and the\n * bundled baseline are honoured uniformly.\n *\n * Order (env-first = override-wins):\n * 1. `SKAILE_FACTORY_ASSETS_DIR` env dir (legacy: `SKAILE_BASE_ASSETS_DIR`),\n * when set and existing — an additive override layer.\n * 2. {@link resolvePackagedAssetsDir} — the bundled tree (in-repo source in dev,\n * `dist/factory-assets/` after install). Always-present baseline.\n *\n * Returns `[]` only when the package cannot be located at all. De-duplicated, so\n * pointing the env var at the bundled dir collapses to one root.\n *\n * @docLink packages/core/concepts#resolve-factory-assets-root\n */\nexport function factoryAssetRoots(): string[] {\n const roots: string[] = [];\n const envDir = process.env.SKAILE_FACTORY_ASSETS_DIR ?? process.env.SKAILE_BASE_ASSETS_DIR;\n if (envDir && existsSync(envDir)) roots.push(resolvePath(envDir));\n const bundled = resolvePackagedAssetsDir(\"factory-assets\");\n if (bundled) roots.push(bundled);\n return [...new Set(roots)];\n}\n\n/**\n * Resolve the primary on-disk root of the `factory-assets` tree — the first of\n * {@link factoryAssetRoots} (the env override when set, else the bundled tree).\n * Prefer {@link factoryAssetRoots} when you need to scan every layer; this\n * single-dir form is for callers that want one canonical path.\n *\n * @returns Absolute path to the highest-precedence `factory-assets` directory\n * @throws When no root can be located\n * @docLink packages/core/concepts#resolve-factory-assets-root\n */\nexport function resolveFactoryAssetsRoot(): string {\n const hit = resolveFactoryAssetsRootOrNull();\n if (hit) return hit;\n\n throw new Error(\n `Cannot resolve the factory-assets directory. ` +\n `Set SKAILE_FACTORY_ASSETS_DIR to the on-disk path, ` +\n `ensure @skaile/workspaces is installed, ` +\n `or run from within the @skaile/workspaces package tree.`,\n );\n}\n\n/**\n * Non-throwing variant of {@link resolveFactoryAssetsRoot}: the same\n * env-then-packaged resolution tiers, returning `null` instead of throwing when\n * none locate the directory. Callers that treat a missing factory tree as a\n * soft \"not present\" (e.g. the asset-manager's implicit-source injection) MUST\n * use this so they honour the `SKAILE_FACTORY_ASSETS_DIR` container override\n * identically to the runtime path.\n */\nexport function resolveFactoryAssetsRootOrNull(): string | null {\n return factoryAssetRoots()[0] ?? null;\n}\n\n/**\n * Resolve the `@skaile/workspaces` package root — the directory containing its\n * `package.json`. Tries `require.resolve` first (works when installed as a\n * dependency *and* in-repo via the self-reference), then walks upward from this\n * module looking for a `package.json` whose `name` is `@skaile/workspaces`\n * (bounded to 8 levels). Returns `null` when neither locates it.\n *\n * The single source of truth for finding content shipped inside the package —\n * the unified `factory-assets/` tree (built-in connectors + first-party skills\n * + bundles) resolves through {@link resolvePackagedAssetsDir} on top of this.\n *\n * Memoized: the package location is immutable for the process lifetime, but\n * this sits on the CLI hot path (every `findSkills` / flow / completion call\n * funnels through here), so the `require.resolve` + upward `package.json` walk\n * runs once. `undefined` = not yet computed.\n *\n * @docLink packages/core/concepts#resolve-factory-assets-root\n */\nlet workspacesPackageRootCache: string | null | undefined;\n\nexport function resolveWorkspacesPackageRoot(): string | null {\n if (workspacesPackageRootCache !== undefined) return workspacesPackageRootCache;\n workspacesPackageRootCache = computeWorkspacesPackageRoot();\n return workspacesPackageRootCache;\n}\n\nfunction computeWorkspacesPackageRoot(): string | null {\n try {\n const require = createRequire(import.meta.url);\n return dirname(require.resolve(\"@skaile/workspaces/package.json\"));\n } catch {\n // Fall through to the workspace walk.\n }\n let dir: string;\n try {\n dir = dirname(fileURLToPath(import.meta.url));\n } catch {\n return null;\n }\n for (let i = 0; i < 8; i++) {\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as { name?: string };\n if (pkg.name === \"@skaile/workspaces\") return dir;\n } catch {\n // Ignore malformed package.json and keep walking.\n }\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Locate a content-asset directory inside the package. Prefers the in-repo\n * **source** dir `<pkgRoot>/<subdir>` when present — in a dev checkout it is the\n * full tree (e.g. `factory-assets/` keeps the connector `.ts` entry files that\n * `dist/` does not) — then the published `dist/<subdir>` copy (what\n * `files: [\"dist\"]` ships, the only one present after `npm i`). Returns `null`\n * when neither exists.\n *\n * `factory-assets/` resolves to the source tree in dev (code + skills + bundles)\n * and to `dist/factory-assets` post-install (compiled connectors + copied\n * manifests/skills/bundles).\n *\n * @param subdir - `\"factory-assets\"` | …\n * @docLink packages/core/concepts#resolve-factory-assets-root\n */\nexport function resolvePackagedAssetsDir(subdir: string): string | null {\n const root = resolveWorkspacesPackageRoot();\n if (!root) return null;\n for (const cand of [join(root, subdir), join(root, \"dist\", subdir)]) {\n if (existsSync(cand)) return cand;\n }\n return null;\n}\n\n// ─── Internals ────────────────────────────────────────────────────────────────\n\nasync function populate(projectDir: string, target: RuntimeAssetsResult): Promise<void> {\n target.catalogEntries = [];\n target.implicitRefs = [];\n target.requiredNpmDeps = { required: [], optional: [] };\n target.warnings = [];\n\n const config = resolveSkWorkspaceConfig(projectDir);\n // Connector catalog scan runs over the project's declared sources[] (resolved\n // to their machine-cache clone paths) plus the implicit factory-assets repo.\n const repositories = buildEffectiveRepositories(sourcesToDeclarations(config.sources));\n const links = readLinks(projectDir);\n\n // Scan each repository for connector entries.\n for (const [name, decl] of Object.entries(repositories)) {\n const repoDir = resolveRepoDir(name, decl, projectDir, links);\n if (!repoDir) {\n target.warnings.push({\n code: \"repo_unavailable\",\n name,\n message: repoUnavailableMessage(name, decl),\n });\n continue;\n }\n try {\n // Both factory layers carry the same `factory-assets` provenance — the\n // override repo is an internal scan-order device, not a distinct source.\n const repoName = name === FACTORY_ASSETS_OVERRIDE_REPO_NAME ? FACTORY_ASSETS_REPO_NAME : name;\n const entries = scanDirectory(repoDir, repoName).filter((e) => e.kind === \"connector\");\n target.catalogEntries.push(...entries);\n } catch (err) {\n target.warnings.push({\n code: \"repo_unavailable\",\n name,\n message: `Failed to scan repository \"${name}\" at ${repoDir}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n });\n }\n }\n\n // De-duplicate by (kind, name), keeping the first occurrence. Scan order is\n // declared sources → env override → bundled baseline, so an env-supplied\n // connector manifest overrides the bundled one and the bundled one fills the\n // rest (the override layer can refresh built-in manifests in place).\n const seen = new Set<string>();\n target.catalogEntries = target.catalogEntries.filter((e) => {\n const key = `${e.kind}:${e.name}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n // Derive implicit refs from skaile.yaml connectors.\n for (const c of config.connectors ?? []) {\n target.implicitRefs.push({ kind: \"connector\", name: c.driver, declarationId: c.id });\n }\n\n // Validate refs and aggregate npm deps.\n const requiredSet = new Set<string>();\n const optionalSet = new Set<string>();\n for (const ref of target.implicitRefs) {\n const entry = findCatalogEntry(target.catalogEntries, ref);\n if (!entry) {\n target.warnings.push({\n code: \"missing_driver\",\n declarationId: ref.declarationId,\n name: ref.name,\n message:\n `Unknown ${ref.kind} driver \"${ref.name}\" referenced by ${ref.kind} \"${ref.declarationId}\". ` +\n `Run \\`skaile ${ref.kind} catalog\\` to see available drivers, ` +\n `or declare a repository in skaile.yaml that provides this driver.`,\n });\n continue;\n }\n const npm = (entry.metadata?.npm_deps ?? {}) as { required?: string[]; optional?: string[] };\n for (const p of npm.required ?? []) requiredSet.add(p);\n for (const p of npm.optional ?? []) optionalSet.add(p);\n }\n target.requiredNpmDeps.required = [...requiredSet];\n target.requiredNpmDeps.optional = [...optionalSet];\n}\n\n/**\n * Build the effective `repositories` map: caller's declarations first, then the\n * implicit built-in `factory-assets` repos. Each {@link factoryAssetRoots} layer\n * becomes its own repo, the env override inserted **before** the bundled\n * baseline so its connector entries win on the first-match dedup downstream.\n * When the package cannot be located at all, a path-less sentinel under\n * {@link FACTORY_ASSETS_REPO_NAME} drives the `repo_unavailable` warning.\n */\nfunction buildEffectiveRepositories(\n declared: Record<string, SourceDeclaration> | undefined,\n): Record<string, SourceDeclaration> {\n const result: Record<string, SourceDeclaration> = { ...(declared ?? {}) };\n const roots = factoryAssetRoots();\n if (roots.length === 0) {\n // Surface as a warning during scan rather than throwing here — let the\n // caller decide whether factory-assets is required. resolveRepoDir() /\n // repoUnavailableMessage re-discover the failure and emit it.\n if (!result[FACTORY_ASSETS_REPO_NAME]) result[FACTORY_ASSETS_REPO_NAME] = { path: \"\" };\n return result;\n }\n // override-first when both layers exist, so the env root's entries are scanned\n // (and matched) ahead of the bundled baseline.\n const keys =\n roots.length > 1\n ? [FACTORY_ASSETS_OVERRIDE_REPO_NAME, FACTORY_ASSETS_REPO_NAME]\n : [FACTORY_ASSETS_REPO_NAME];\n roots.forEach((dir, i) => {\n const key = keys[i] ?? `${FACTORY_ASSETS_REPO_NAME}:${i}`;\n if (!result[key]) result[key] = { path: dir };\n });\n return result;\n}\n\n/**\n * Resolve a repository declaration to an on-disk directory. Order:\n * 1. Linked override (`.skaile/links.yaml`).\n * 2. Local `path` — relative to `projectDir`.\n * 3. Cloned URL repo at `.skaile/cache/sources/<name>/` (must already exist).\n *\n * Returns `null` when none of these resolve. Does not clone.\n */\nfunction resolveRepoDir(\n name: string,\n decl: SourceDeclaration,\n projectDir: string,\n links: Record<string, string>,\n): string | null {\n // 1. Linked override\n const linked = links[name];\n if (linked && existsSync(linked)) return linked;\n\n // 2. Local path\n if (decl.path) {\n const resolved = resolvePath(projectDir, decl.path);\n return existsSync(resolved) ? resolved : null;\n }\n\n // 3. URL repo cloned to project's .skaile/cache/sources/<name> — the\n // project-local clone dir (often a symlink into the global cache, which\n // lives at getGlobalCacheDir()); NOT the global clone root itself.\n if (decl.url) {\n const projectDest = join(projectDir, \".skaile\", \"cache\", \"sources\", name);\n if (existsSync(projectDest)) {\n // Either a real directory or a symlink to the global cache.\n try {\n lstatSync(projectDest);\n return projectDest;\n } catch {\n return null;\n }\n }\n return null;\n }\n\n return null;\n}\n\nfunction repoUnavailableMessage(name: string, decl: SourceDeclaration): string {\n if (name === FACTORY_ASSETS_REPO_NAME && !decl.path && !decl.url) {\n return (\n `Cannot resolve the built-in factory-assets. ` +\n `Set SKAILE_FACTORY_ASSETS_DIR or ensure @skaile/workspaces is installed.`\n );\n }\n if (decl.url) {\n return `Repository \"${name}\" (${decl.url}) is not available. Register it as a Library Source via \\`skaile source add\\`.`;\n }\n if (decl.path) {\n return `Repository \"${name}\" path not found: ${decl.path}`;\n }\n return `Repository \"${name}\" has neither url nor path.`;\n}\n\nfunction findCatalogEntry(\n entries: RuntimeCatalogEntry[],\n query: { kind?: \"connector\"; name: string },\n): RuntimeCatalogEntry | undefined {\n if (query.kind) {\n return entries.find((e) => e.kind === query.kind && e.name === query.name);\n }\n const matches = entries.filter((e) => e.name === query.name);\n if (matches.length === 1) return matches[0];\n // 0 or >1 with no kind — caller must disambiguate.\n return undefined;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../workspace-plugin/src/tools/validator.ts"],"names":["val"],"mappings":"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","file":"chunk-ACXLKNIM.js","sourcesContent":["import { execSync } from \"node:child_process\";\nimport type { ToolResult } from \"../types.js\";\nimport { err, okJson } from \"../types.js\";\n\n// Minimal interface for WorkspacePlugin to avoid circular dep.\n// The unified ConnectorManager owns both filesystem-face (mountable) and\n// tool-face connectors — `listConnectors()` returns both; filesystem-face\n// entries carry a `mountPath`.\ninterface ConnectorSummary {\n id: string;\n driver: string;\n mountPath?: string;\n}\ninterface PluginLike {\n projectDir: string;\n connectorManager: { listConnectors(): ConnectorSummary[] } | null;\n reload(): Promise<void>;\n}\n\n/** Split a manager's connectors into mountable / tool-face groups. */\nfunction splitConnectors(plugin: PluginLike): {\n mounts: ConnectorSummary[];\n connectors: ConnectorSummary[];\n} {\n const all = plugin.connectorManager?.listConnectors() ?? [];\n return {\n mounts: all.filter((c) => typeof c.mountPath === \"string\"),\n connectors: all.filter((c) => typeof c.mountPath !== \"string\"),\n };\n}\n\nfunction maskSecret(value: string): string {\n if (value.length <= 4) return \"****\";\n return `${value.slice(0, 4)}****`;\n}\n\nfunction resolveEnvRef(ref: string): {\n resolved: boolean;\n value?: string;\n provider?: string;\n error?: string;\n} {\n if (ref.startsWith(\"env:\")) {\n const varName = ref.slice(4);\n const val = process.env[varName];\n if (val) return { resolved: true, value: val, provider: \"env\" };\n return { resolved: false, error: `env var '${varName}' is not set` };\n }\n const val = process.env[ref];\n if (val) return { resolved: true, value: val, provider: \"env\" };\n return { resolved: false, error: `'${ref}' not found in environment` };\n}\n\n/**\n * Return a summary of the current workspace configuration.\n *\n * Reports the active driver, provider, model, mount count, connector count,\n * and per-resource descriptors.\n *\n * @param plugin - Plugin instance (or compatible shape) exposing managers.\n * @param driver - Driver name (e.g. `\"omp\"`, `\"claude-sdk\"`).\n * @param provider - Provider identifier, if resolved.\n * @param model - Model identifier, if resolved.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function workspaceInfo(\n plugin: PluginLike,\n driver: string,\n provider: string | undefined,\n model: string | undefined,\n): Promise<ToolResult> {\n try {\n const { mounts, connectors } = splitConnectors(plugin);\n return okJson({\n driver,\n provider,\n model,\n mountCount: mounts.length,\n connectorCount: connectors.length,\n mounts: mounts.map((v) => ({ id: v.id, driver: v.driver, mounted: true })),\n connectors: connectors.map((c) => ({ id: c.id, adapter: c.driver })),\n projectDir: plugin.projectDir,\n });\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Test resolution of a secret reference.\n *\n * Resolves `env:<VAR>` references against `process.env`. For other provider\n * schemes (e.g. `forge:key`) reports that a running forge/vault context is\n * required. Returns a JSON object with `{ resolved, provider?, masked? }` —\n * the secret value is never returned in plain text.\n *\n * @param ref - Secret reference string, e.g. `\"env:ANTHROPIC_API_KEY\"`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function workspaceTestSecret(ref: string): Promise<ToolResult> {\n try {\n const result = resolveEnvRef(ref);\n if (result.resolved && result.value) {\n return okJson({\n resolved: true,\n provider: result.provider,\n masked: maskSecret(result.value),\n });\n }\n if (ref.includes(\":\") && !ref.startsWith(\"env:\")) {\n return okJson({\n resolved: false,\n error: `Provider '${ref.split(\":\")[0]}' requires a running forge/vault context. Use env: refs for standalone validation.`,\n });\n }\n return okJson({ resolved: false, error: result.error });\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Run a full health check on the workspace.\n *\n * Checks whether the driver binary is installed, then validates every\n * declared mount and connector. Returns a JSON report with a top-level\n * `passed` boolean and per-resource `ok` flags.\n *\n * @param plugin - Plugin instance (or compatible shape) exposing managers.\n * @param driver - Driver name used to locate the binary (`omp` or `claude`).\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function workspaceValidate(plugin: PluginLike, driver: string): Promise<ToolResult> {\n const report: Record<string, unknown> = {\n driver: { name: driver, installed: false },\n mounts: [] as unknown[],\n connectors: [] as unknown[],\n };\n\n try {\n const binaryName = driver === \"omp\" ? \"omp\" : \"claude\";\n execSync(`which ${binaryName}`, { stdio: \"pipe\" });\n (report.driver as any).installed = true;\n } catch {\n (report.driver as any).installed = false;\n (report.driver as any).hint = `Install the '${driver}' binary to use this driver`;\n }\n\n const { mounts, connectors } = splitConnectors(plugin);\n for (const v of mounts) {\n (report.mounts as any[]).push({\n id: v.id,\n driver: v.driver,\n mounted: true,\n ok: true,\n });\n }\n\n for (const c of connectors) {\n (report.connectors as any[]).push({\n id: c.id,\n adapter: c.driver,\n connected: true,\n ok: true,\n });\n }\n\n report.passed =\n (report.driver as any).installed &&\n (report.mounts as any[]).every((v) => v.ok) &&\n (report.connectors as any[]).every((c) => c.ok);\n\n return okJson(report);\n}\n\n/**\n * Re-read `skaile.yaml` and reinitialise all plugin resources.\n *\n * Delegates to `plugin.reload()`. Returns a JSON object comparing the\n * mount and connector counts before and after the reload.\n *\n * @param plugin - Plugin instance exposing a `reload()` method.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function workspaceReload(plugin: PluginLike): Promise<ToolResult> {\n try {\n const countBefore = splitConnectors(plugin);\n const before = { mounts: countBefore.mounts.length, connectors: countBefore.connectors.length };\n await plugin.reload();\n const countAfter = splitConnectors(plugin);\n const after = { mounts: countAfter.mounts.length, connectors: countAfter.connectors.length };\n return okJson({ reloaded: true, before, after });\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n"]}
|