@skaile/workspaces 3.27.1 → 4.1.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 +482 -0
- package/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-QF7LGRUX.js → asset-feeds-VEPD5ZU7.js} +11 -9
- package/dist/asset-feeds-VEPD5ZU7.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +5 -3
- package/dist/asset-manager/index.js +11 -9
- package/dist/asset-manager/installer.js +8 -6
- package/dist/asset-manager/renderers.js +2 -2
- package/dist/asset-manager/src/renderers.d.ts.map +1 -1
- package/dist/bridge/codex-app-server.js +15 -1
- package/dist/bridge/drivers/claude-sdk.js +102 -55
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +179 -23
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +199 -7
- package/dist/bridge/drivers/continue.js.map +1 -1
- package/dist/bridge/drivers/echo.js +10 -4
- package/dist/bridge/drivers/echo.js.map +1 -1
- package/dist/bridge/drivers/gemini.js +7 -4
- package/dist/bridge/drivers/goose.js +160 -7
- package/dist/bridge/drivers/goose.js.map +1 -1
- package/dist/bridge/drivers/omp.js +321 -96
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +148 -13
- package/dist/bridge/drivers/opencode.js.map +1 -1
- package/dist/bridge/drivers/qwen.js +41 -11
- package/dist/bridge/drivers/qwen.js.map +1 -1
- package/dist/bridge/index.js +12 -9
- package/dist/bridge/src/cloud.d.ts +62 -71
- package/dist/bridge/src/cloud.d.ts.map +1 -1
- package/dist/bridge/src/codex/config-toml.d.ts +128 -0
- package/dist/bridge/src/codex/config-toml.d.ts.map +1 -0
- package/dist/bridge/src/codex/credentials.d.ts +26 -0
- package/dist/bridge/src/codex/credentials.d.ts.map +1 -1
- package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
- package/dist/bridge/src/codex-app-server.d.ts.map +1 -1
- package/dist/bridge/src/drivers/_subprocess-cli.d.ts +9 -4
- package/dist/bridge/src/drivers/_subprocess-cli.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts +19 -11
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/codex.d.ts +26 -1
- package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
- package/dist/bridge/src/drivers/continue.d.ts +31 -5
- package/dist/bridge/src/drivers/continue.d.ts.map +1 -1
- package/dist/bridge/src/drivers/echo.d.ts.map +1 -1
- package/dist/bridge/src/drivers/gemini.d.ts +34 -3
- package/dist/bridge/src/drivers/gemini.d.ts.map +1 -1
- package/dist/bridge/src/drivers/goose.d.ts +26 -2
- package/dist/bridge/src/drivers/goose.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp-models-yml.d.ts +216 -0
- package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +1 -0
- package/dist/bridge/src/drivers/omp.d.ts +26 -23
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/drivers/opencode.d.ts +28 -3
- package/dist/bridge/src/drivers/opencode.d.ts.map +1 -1
- package/dist/bridge/src/drivers/qwen.d.ts +10 -4
- package/dist/bridge/src/drivers/qwen.d.ts.map +1 -1
- package/dist/bridge/src/index.d.ts +3 -1
- package/dist/bridge/src/index.d.ts.map +1 -1
- package/dist/bridge/src/models.d.ts +118 -19
- package/dist/bridge/src/models.d.ts.map +1 -1
- package/dist/bridge/src/provider-catalog.d.ts +188 -0
- package/dist/bridge/src/provider-catalog.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/continue-config-yaml.d.ts +117 -0
- package/dist/bridge/src/provider-materialize/continue-config-yaml.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/credential-env.d.ts +103 -0
- package/dist/bridge/src/provider-materialize/credential-env.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/env-drivers.d.ts +209 -0
- package/dist/bridge/src/provider-materialize/env-drivers.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/goose-custom-providers.d.ts +127 -0
- package/dist/bridge/src/provider-materialize/goose-custom-providers.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/opencode-config.d.ts +127 -0
- package/dist/bridge/src/provider-materialize/opencode-config.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/session-config-home.d.ts +63 -0
- package/dist/bridge/src/provider-materialize/session-config-home.d.ts.map +1 -0
- package/dist/bridge/src/provider-registry-derive.d.ts +59 -0
- package/dist/bridge/src/provider-registry-derive.d.ts.map +1 -0
- package/dist/bridge/src/registry.d.ts +19 -7
- package/dist/bridge/src/registry.d.ts.map +1 -1
- package/dist/bridge/src/runtime.d.ts.map +1 -1
- package/dist/bridge/src/types.d.ts +79 -60
- package/dist/bridge/src/types.d.ts.map +1 -1
- package/dist/bridge/src/validation.d.ts +2 -3
- package/dist/bridge/src/validation.d.ts.map +1 -1
- package/dist/{chunk-ZEXYTJ6Y.js → chunk-2GF42G2J.js} +6 -6
- package/dist/{chunk-ZEXYTJ6Y.js.map → chunk-2GF42G2J.js.map} +1 -1
- package/dist/{chunk-WWGU3REE.js → chunk-2K7NURDN.js} +7 -7
- package/dist/{chunk-WWGU3REE.js.map → chunk-2K7NURDN.js.map} +1 -1
- package/dist/{chunk-TCHEW3T2.js → chunk-2RO6N7DN.js} +6 -6
- package/dist/{chunk-TCHEW3T2.js.map → chunk-2RO6N7DN.js.map} +1 -1
- package/dist/{chunk-HSRHO7SK.js → chunk-3VSRJE3M.js} +155 -143
- package/dist/chunk-3VSRJE3M.js.map +1 -0
- package/dist/{chunk-T3YLZQS4.js → chunk-45LLHKQ2.js} +24 -3
- package/dist/chunk-45LLHKQ2.js.map +1 -0
- package/dist/chunk-5DQWB5TW.js +843 -0
- package/dist/chunk-5DQWB5TW.js.map +1 -0
- package/dist/{chunk-JMYOJ3PA.js → chunk-5HT5M5HX.js} +3 -3
- package/dist/{chunk-JMYOJ3PA.js.map → chunk-5HT5M5HX.js.map} +1 -1
- package/dist/{chunk-VN7DELUT.js → chunk-6AMTSRRO.js} +4 -4
- package/dist/{chunk-VN7DELUT.js.map → chunk-6AMTSRRO.js.map} +1 -1
- package/dist/{chunk-MX6TGDZ7.js → chunk-6DI4NTZN.js} +5 -5
- package/dist/{chunk-MX6TGDZ7.js.map → chunk-6DI4NTZN.js.map} +1 -1
- package/dist/{chunk-FFE7YLYO.js → chunk-AN7E2IL5.js} +7 -7
- package/dist/chunk-AN7E2IL5.js.map +1 -0
- package/dist/{chunk-A3HTL7XV.js → chunk-APDN5LW4.js} +3 -3
- package/dist/{chunk-A3HTL7XV.js.map → chunk-APDN5LW4.js.map} +1 -1
- package/dist/{chunk-FACPWN6P.js → chunk-ASU5IJZS.js} +9 -12
- package/dist/chunk-ASU5IJZS.js.map +1 -0
- package/dist/{chunk-J3IXRPZB.js → chunk-BTMDSMXF.js} +10 -10
- package/dist/{chunk-J3IXRPZB.js.map → chunk-BTMDSMXF.js.map} +1 -1
- package/dist/chunk-CTBUPYOQ.js +500 -0
- package/dist/chunk-CTBUPYOQ.js.map +1 -0
- package/dist/{chunk-K6VZQNTR.js → chunk-DKCFWSVW.js} +3 -3
- package/dist/{chunk-K6VZQNTR.js.map → chunk-DKCFWSVW.js.map} +1 -1
- package/dist/{chunk-MQASB52N.js → chunk-FEFTOV2Y.js} +3 -3
- package/dist/{chunk-MQASB52N.js.map → chunk-FEFTOV2Y.js.map} +1 -1
- package/dist/{chunk-XMULHVKX.js → chunk-FGTYTU6Q.js} +17 -15
- package/dist/chunk-FGTYTU6Q.js.map +1 -0
- package/dist/{chunk-WJVBJAM5.js → chunk-HHC2T7BM.js} +7 -7
- package/dist/{chunk-WJVBJAM5.js.map → chunk-HHC2T7BM.js.map} +1 -1
- package/dist/chunk-ILG4BXYE.js +936 -0
- package/dist/chunk-ILG4BXYE.js.map +1 -0
- package/dist/{chunk-E7HKNQTH.js → chunk-JXCUUZA3.js} +3 -4
- package/dist/chunk-JXCUUZA3.js.map +1 -0
- package/dist/{chunk-MBARHWMZ.js → chunk-K27T47OO.js} +79 -53
- package/dist/chunk-K27T47OO.js.map +1 -0
- package/dist/chunk-KSIRR5PL.js +142 -0
- package/dist/chunk-KSIRR5PL.js.map +1 -0
- package/dist/{chunk-SIREWRZE.js → chunk-KW7YIRYL.js} +3 -3
- package/dist/{chunk-SIREWRZE.js.map → chunk-KW7YIRYL.js.map} +1 -1
- package/dist/{chunk-3U3ZKYR7.js → chunk-LPF24MZA.js} +139 -29
- package/dist/chunk-LPF24MZA.js.map +1 -0
- package/dist/chunk-M2F5UXCX.js +187 -0
- package/dist/chunk-M2F5UXCX.js.map +1 -0
- package/dist/{chunk-DZ4UZOFB.js → chunk-M5H4DWIA.js} +3 -3
- package/dist/{chunk-DZ4UZOFB.js.map → chunk-M5H4DWIA.js.map} +1 -1
- package/dist/{chunk-PHBYB4XT.js → chunk-MLDJHV2U.js} +4 -8
- package/dist/chunk-MLDJHV2U.js.map +1 -0
- package/dist/{chunk-773WLEXL.js → chunk-MVBK4JUK.js} +3 -3
- package/dist/{chunk-773WLEXL.js.map → chunk-MVBK4JUK.js.map} +1 -1
- package/dist/{chunk-AN6NAFRT.js → chunk-N7B3LZ7V.js} +31 -6
- package/dist/chunk-N7B3LZ7V.js.map +1 -0
- package/dist/{chunk-EB72L5ZL.js → chunk-ORZBDXNS.js} +18 -30
- package/dist/chunk-ORZBDXNS.js.map +1 -0
- package/dist/{chunk-6H6HLMWG.js → chunk-OXTPH6HT.js} +3 -3
- package/dist/{chunk-6H6HLMWG.js.map → chunk-OXTPH6HT.js.map} +1 -1
- package/dist/{chunk-QSPCI4W2.js → chunk-PI244HAH.js} +175 -178
- package/dist/chunk-PI244HAH.js.map +1 -0
- package/dist/{chunk-NW65H5EV.js → chunk-PTETBRRC.js} +3 -3
- package/dist/{chunk-NW65H5EV.js.map → chunk-PTETBRRC.js.map} +1 -1
- package/dist/{chunk-UL4LD7KD.js → chunk-QQL3ET3J.js} +3 -3
- package/dist/{chunk-UL4LD7KD.js.map → chunk-QQL3ET3J.js.map} +1 -1
- package/dist/{chunk-GURXUF2J.js → chunk-R2GE2NXM.js} +95 -80
- package/dist/chunk-R2GE2NXM.js.map +1 -0
- package/dist/{chunk-IB4XKQMQ.js → chunk-REILIKVM.js} +3 -3
- package/dist/{chunk-IB4XKQMQ.js.map → chunk-REILIKVM.js.map} +1 -1
- package/dist/{chunk-3NCGSSCU.js → chunk-WLFRA5RM.js} +47 -45
- package/dist/chunk-WLFRA5RM.js.map +1 -0
- package/dist/{chunk-2BK4N3FS.js → chunk-WO65FA7W.js} +2 -7
- package/dist/chunk-WO65FA7W.js.map +1 -0
- package/dist/{chunk-72DG6GSB.js → chunk-YS4XBN7O.js} +4 -4
- package/dist/{chunk-72DG6GSB.js.map → chunk-YS4XBN7O.js.map} +1 -1
- package/dist/chunk-YSJKLJD4.js +32 -0
- package/dist/chunk-YSJKLJD4.js.map +1 -0
- package/dist/cli/index.js +765 -334
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/config.d.ts +17 -6
- package/dist/cli/src/commands/config.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-legacy-entry.d.ts +46 -0
- package/dist/cli/src/commands/migrate-legacy-entry.d.ts.map +1 -0
- package/dist/cli/src/commands/migrate-providers.d.ts +93 -0
- package/dist/cli/src/commands/migrate-providers.d.ts.map +1 -0
- package/dist/cli/src/commands/providers.d.ts +89 -0
- package/dist/cli/src/commands/providers.d.ts.map +1 -0
- package/dist/cli/src/commands/run.d.ts +1 -1
- package/dist/cli/src/commands/run.d.ts.map +1 -1
- package/dist/cli/src/setup.d.ts +46 -6
- package/dist/cli/src/setup.d.ts.map +1 -1
- package/dist/connectors/config.js +6 -4
- package/dist/connectors/index.js +15 -12
- package/dist/core/index.js +5 -3
- package/dist/core/provider-registry-credentials.d.ts +2 -0
- package/dist/core/provider-registry-credentials.js +5 -0
- package/dist/core/provider-registry-credentials.js.map +1 -0
- package/dist/core/provider-registry.d.ts +2 -0
- package/dist/core/provider-registry.js +4 -0
- package/dist/core/provider-registry.js.map +1 -0
- package/dist/core/runtime-assets.js +2 -2
- package/dist/core/src/index.d.ts +11 -4
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/process-alive.d.ts +28 -0
- package/dist/core/src/process-alive.d.ts.map +1 -0
- package/dist/core/src/provider-registry-credentials.d.ts +50 -0
- package/dist/core/src/provider-registry-credentials.d.ts.map +1 -0
- package/dist/core/src/provider-registry-files.d.ts +97 -0
- package/dist/core/src/provider-registry-files.d.ts.map +1 -0
- package/dist/core/src/provider-registry.d.ts +450 -0
- package/dist/core/src/provider-registry.d.ts.map +1 -0
- package/dist/core/src/settings.d.ts +18 -78
- package/dist/core/src/settings.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +31 -47
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +1 -1
- package/dist/deploy/index.js +9 -16
- package/dist/deploy/index.js.map +1 -1
- package/dist/deploy/src/targets/local.d.ts.map +1 -1
- package/dist/deploy/src/targets/nix.d.ts.map +1 -1
- package/dist/deploy/src/targets/process-handle.d.ts +0 -2
- package/dist/deploy/src/targets/process-handle.d.ts.map +1 -1
- package/dist/discovery/index.js +2 -2
- package/dist/{ensure-sources-GEJGBQIP.js → ensure-sources-B3VWHD5M.js} +14 -12
- package/dist/ensure-sources-B3VWHD5M.js.map +1 -0
- package/dist/factory-assets/connectors/box.js +15 -12
- package/dist/factory-assets/connectors/deploy.js +15 -12
- package/dist/factory-assets/connectors/devserver/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/devserver.js +15 -12
- package/dist/factory-assets/connectors/flow/adapter.js +15 -12
- package/dist/factory-assets/connectors/flow/engine.js +6 -4
- package/dist/factory-assets/connectors/flow/index.d.ts +1 -1
- package/dist/factory-assets/connectors/flow/index.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.d.ts +0 -3
- package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +16 -13
- package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts +31 -28
- package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow.js +15 -12
- package/dist/factory-assets/connectors/git.js +15 -12
- package/dist/factory-assets/connectors/gmail.js +15 -12
- package/dist/factory-assets/connectors/googledrive.js +15 -12
- package/dist/factory-assets/connectors/local.js +15 -12
- package/dist/factory-assets/connectors/mattermost.js +15 -12
- package/dist/factory-assets/connectors/memory.js +15 -12
- package/dist/factory-assets/connectors/minio.js +15 -12
- package/dist/factory-assets/connectors/postgres.js +15 -12
- package/dist/factory-assets/connectors/s3.js +15 -12
- package/dist/factory-assets/connectors/sharepoint.js +15 -12
- package/dist/factory-assets/connectors/sqlite.js +15 -12
- package/dist/factory-assets/connectors/static-server.js +15 -12
- package/dist/factory-assets/connectors/tunnel.js +15 -12
- package/dist/factory-assets/connectors/webdav.js +15 -12
- package/dist/factory-assets/connectors/xstate-store.js +15 -12
- package/dist/factory-assets/connectors/xstate.js +15 -12
- package/dist/{flows-MI2VM5JZ.js → flows-KIQH2VGA.js} +9 -7
- package/dist/{flows-MI2VM5JZ.js.map → flows-KIQH2VGA.js.map} +1 -1
- package/dist/{helpers-DXZOHX25.js → helpers-72W3NZ2L.js} +14 -12
- package/dist/{helpers-DXZOHX25.js.map → helpers-72W3NZ2L.js.map} +1 -1
- package/dist/library/index.js +8 -6
- package/dist/library/install.js +5 -3
- package/dist/{library-publish-CUPDG5NI.js → library-publish-YPHKEA6L.js} +18 -16
- package/dist/library-publish-YPHKEA6L.js.map +1 -0
- package/dist/{open-library-32XAI2LH.js → open-library-7OIUAGAH.js} +16 -14
- package/dist/{open-library-32XAI2LH.js.map → open-library-7OIUAGAH.js.map} +1 -1
- package/dist/paths-XLSP5K6C.js +18 -0
- package/dist/{paths-CZEH643M.js.map → paths-XLSP5K6C.js.map} +1 -1
- package/dist/plugin-registry/src/targets.d.ts +16 -2
- package/dist/plugin-registry/src/targets.d.ts.map +1 -1
- package/dist/{plugin-store-QJNBPIQK.js → plugin-store-V5BMOYGS.js} +7 -5
- package/dist/plugin-store-V5BMOYGS.js.map +1 -0
- package/dist/{project-RRHUCVXW.js → project-KNAZV4B3.js} +15 -13
- package/dist/{project-RRHUCVXW.js.map → project-KNAZV4B3.js.map} +1 -1
- package/dist/resolver/index.js +5 -3
- package/dist/runner/index.js +25 -22
- package/dist/runner/src/agent.d.ts +0 -2
- package/dist/runner/src/agent.d.ts.map +1 -1
- package/dist/runner/src/codex-init.d.ts.map +1 -1
- package/dist/runner/src/codex-resource-tools.d.ts.map +1 -1
- package/dist/runner/src/managed-codex-bootstrap.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts +1 -2
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts +31 -35
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/runner/src/session.d.ts +0 -2
- package/dist/runner/src/session.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +11 -9
- package/dist/sdk/bridge.js +12 -9
- package/dist/sdk/core.js +5 -3
- package/dist/sdk/flow.js +6 -4
- package/dist/sdk/index.js +25 -22
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +5 -3
- package/dist/sdk/runner.js +25 -22
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/types.js +1 -1
- package/dist/session/index.js +2 -2
- package/dist/setup-TG4KECRQ.js +435 -0
- package/dist/setup-TG4KECRQ.js.map +1 -0
- package/dist/{skills-IE3IWWB7.js → skills-KHBYF6AU.js} +7 -5
- package/dist/{skills-IE3IWWB7.js.map → skills-KHBYF6AU.js.map} +1 -1
- package/dist/{source-RHQLCTWA.js → source-7AFRUD3U.js} +17 -15
- package/dist/{source-RHQLCTWA.js.map → source-7AFRUD3U.js.map} +1 -1
- package/dist/{source-manifest-publish-DXMCSKU7.js → source-manifest-publish-JWOT7O3A.js} +19 -17
- package/dist/source-manifest-publish-JWOT7O3A.js.map +1 -0
- package/dist/tui/index.js +25 -23
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/src/repl.d.ts +0 -2
- package/dist/tui/src/repl.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/lifecycle.d.ts +35 -10
- package/dist/types/src/lifecycle.d.ts.map +1 -1
- package/dist/types/src/manifests/agent.d.ts +116 -22
- package/dist/types/src/manifests/agent.d.ts.map +1 -1
- package/dist/types/src/manifests/index.d.ts +2 -2
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/types/src/manifests/preset.d.ts +5 -5
- package/dist/types/src/runtime.d.ts +51 -5
- package/dist/types/src/runtime.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +18 -2
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/validator-P5ESKTW5.js +5 -0
- package/dist/{validator-RN64BKFW.js.map → validator-P5ESKTW5.js.map} +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +11 -9
- package/dist/workspace-plugin/adapters/omp.js +11 -11
- package/dist/workspace-plugin/adapters/omp.js.map +1 -1
- package/dist/workspace-plugin/index.js +1 -1
- package/dist/workspace-plugin/src/plugin.d.ts +1 -4
- package/dist/workspace-plugin/src/plugin.d.ts.map +1 -1
- package/dist/workspace-plugin/src/tools/validator.d.ts +4 -4
- package/dist/workspace-plugin/src/tools/validator.d.ts.map +1 -1
- package/package.json +13 -1
- package/dist/asset-feeds-QF7LGRUX.js.map +0 -1
- package/dist/bridge/src/provider-endpoints.d.ts +0 -55
- package/dist/bridge/src/provider-endpoints.d.ts.map +0 -1
- package/dist/chunk-2BK4N3FS.js.map +0 -1
- package/dist/chunk-3NCGSSCU.js.map +0 -1
- package/dist/chunk-3U3ZKYR7.js.map +0 -1
- package/dist/chunk-AN6NAFRT.js.map +0 -1
- package/dist/chunk-AQW4BWNR.js +0 -324
- package/dist/chunk-AQW4BWNR.js.map +0 -1
- package/dist/chunk-E7HKNQTH.js.map +0 -1
- package/dist/chunk-EB72L5ZL.js.map +0 -1
- package/dist/chunk-FACPWN6P.js.map +0 -1
- package/dist/chunk-FFE7YLYO.js.map +0 -1
- package/dist/chunk-FYIHH56K.js +0 -110
- package/dist/chunk-FYIHH56K.js.map +0 -1
- package/dist/chunk-GURXUF2J.js.map +0 -1
- package/dist/chunk-HSRHO7SK.js.map +0 -1
- package/dist/chunk-MBARHWMZ.js.map +0 -1
- package/dist/chunk-PHBYB4XT.js.map +0 -1
- package/dist/chunk-QSPCI4W2.js.map +0 -1
- package/dist/chunk-T3YLZQS4.js.map +0 -1
- package/dist/chunk-XMULHVKX.js.map +0 -1
- package/dist/ensure-sources-GEJGBQIP.js.map +0 -1
- package/dist/library-publish-CUPDG5NI.js.map +0 -1
- package/dist/paths-CZEH643M.js +0 -16
- package/dist/plugin-store-QJNBPIQK.js.map +0 -1
- package/dist/runner/src/cloud-bundle.d.ts +0 -36
- package/dist/runner/src/cloud-bundle.d.ts.map +0 -1
- package/dist/setup-CIRH5BYB.js +0 -517
- package/dist/setup-CIRH5BYB.js.map +0 -1
- package/dist/source-manifest-publish-DXMCSKU7.js.map +0 -1
- package/dist/validator-RN64BKFW.js +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,487 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#739](https://github.com/skaile-ai/workspaces/pull/739) [`390450b`](https://github.com/skaile-ai/workspaces/commit/390450b5432637dee051007faf1d20e7c3bc1b99) Thanks [@peteralbert](https://github.com/peteralbert)! - Pid liveness no longer counts a zombie as alive. The `local` and `nix` deploy targets (`health()`, `restore()`, `stop()`) and the devserver connector (`register`, status refresh) now use a shared `processAlive` from `@skaile/workspaces/core`, which on Linux also reads `/proc/<pid>/stat` and treats an exited-but-unreaped process as gone. A dead deploy or devserver process in a container without an init now reports unhealthy / crashed instead of healthy, and `restore()` refuses it. The devserver connector also rejects a pid <= 0 on `register`, which previously probed a process group.
|
|
8
|
+
|
|
9
|
+
`@skaile/workspaces/core` gains `processAlive`, `processGroupAlive` and `processExited`. `CodexAppServerClient.terminationConfirmed` now uses `processGroupAlive`, so a native process group left holding only unreaped zombies confirms termination instead of latching the managed driver's `cleanupUncertain`. An unreadable `/proc` entry (other than a vanished pid) never counts as gone.
|
|
10
|
+
|
|
11
|
+
## 4.0.0
|
|
12
|
+
|
|
13
|
+
### Major Changes
|
|
14
|
+
|
|
15
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - The AI provider registry is the only provider surface in the runtime.
|
|
16
|
+
|
|
17
|
+
`provider`, `cloud`, `cloudConfig`, `cloudSecrets` and the flat `apiKeys`
|
|
18
|
+
fan-out are deleted from `AgentConfig` (bridge), `AgentRuntimeConfig` and
|
|
19
|
+
`ResolvedAgentConfig` (types), and `AgentSessionConfig` / `AgentSession`
|
|
20
|
+
(runner). A session carries `registry` + `modelRef`; each entry references its
|
|
21
|
+
credential and the value reaches the child under `SKAILE_AIP_<ID>_KEY`.
|
|
22
|
+
|
|
23
|
+
Gone with them: `bridge/src/cloud.ts`'s legacy half (`buildClaudeCloudEnv`,
|
|
24
|
+
`CloudConfig`, `CloudId`, `SUPPORTED_CLOUDS`, `CLOUD_SECRET_ENV_KEYS`), the
|
|
25
|
+
vendor endpoint table (`bridge/src/provider-endpoints.ts` — model discovery and
|
|
26
|
+
key validation resolve through the catalog presets now), the per-driver env
|
|
27
|
+
allowlists and key fan-out (`OMP_PROVIDER_ENV_KEYS`, `mapApiKeysToEnv`, the
|
|
28
|
+
codex/gemini/qwen/continue key cascades), the mixed LLM/voice id list
|
|
29
|
+
(`core` `ALL_PROVIDERS`, with `providerEnvKey`, `resolveApiKey`,
|
|
30
|
+
`detectEnvApiKeys`, `resolveAllKeys`), the runner's per-session cloud resolver
|
|
31
|
+
and provider-key secrets lookup (`runner/src/cloud-bundle.ts` deleted), and the
|
|
32
|
+
session-boundary legacy derivation (`resolveSessionProviderBinding`,
|
|
33
|
+
`deriveLegacyProviderRegistry`). The one survivor is the user-local
|
|
34
|
+
`settings.json` `apiKeys` normalizer (`deriveRegistryFromLegacyApiKeys`), which
|
|
35
|
+
goes one minor later; `skaile migrate providers` keeps its own copy of the
|
|
36
|
+
`provider` × `cloud` translation because that is what it exists to migrate.
|
|
37
|
+
|
|
38
|
+
The runner now resolves each entry's `platform:<configId>` reference against
|
|
39
|
+
the `session_init` secrets map itself and materializes the values into the
|
|
40
|
+
child environment. A `session_init` whose `resolvedConfig.agentConfig` still
|
|
41
|
+
carries `provider`, `cloud` or `cloudConfig` is **rejected** with a fatal error
|
|
42
|
+
naming the replacement. Wire protocol 3.13.0 → **4.0.0**.
|
|
43
|
+
|
|
44
|
+
See `MIGRATION.md` for the full `from → to` table.
|
|
45
|
+
|
|
46
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - `skaile.yaml` selects a model, it no longer defines a provider.
|
|
47
|
+
|
|
48
|
+
`agent_config.<profile>.model` is a selector resolved through `parseModelRef`:
|
|
49
|
+
`"<providerId>/<modelId>"` picks a registry entry, a bare `"<modelId>"`
|
|
50
|
+
resolves against registry order, and `"@role"` resolves through the new
|
|
51
|
+
top-level `roles:` table (`SkWorkspaceConfig.roles`, merged per role name
|
|
52
|
+
across the scope chain, surfaced as `SkaileSettings.roles`). Role resolution is
|
|
53
|
+
lenient: an undefined role, a role chain, or a role naming a provider this
|
|
54
|
+
machine lacks falls back to registry order with a warning instead of failing
|
|
55
|
+
the session.
|
|
56
|
+
|
|
57
|
+
**Breaking — hard cutover, no warning period** (repo convention for
|
|
58
|
+
`skaile.yaml` schema changes). These are parse errors, and every message names
|
|
59
|
+
`skaile migrate providers`:
|
|
60
|
+
|
|
61
|
+
- `agent-config.<profile>.provider`, `.cloud`, `.cloud_config` (and
|
|
62
|
+
`.cloudConfig`) — including inside a flat, un-profiled `agent-config` block
|
|
63
|
+
- `providers`, `base_url`, `credential`, `headers`, `query_params`,
|
|
64
|
+
`transport` — at the top level and inside any profile
|
|
65
|
+
|
|
66
|
+
The reserved names are scoped to those two places: `mcp_servers[].transport`
|
|
67
|
+
and `mcp_servers[].headers` are a different noun and keep working.
|
|
68
|
+
`encodeSkaileYaml` strips the three legacy profile keys so the writer cannot
|
|
69
|
+
emit a file its own decoder rejects, and the now-unreachable
|
|
70
|
+
`unknown_provider` / `unknown_cloud` / `gateway_missing_base_url` diagnostics
|
|
71
|
+
are gone.
|
|
72
|
+
|
|
73
|
+
New `skaile migrate providers [--project-dir] [--workspace] [--dry-run]
|
|
74
|
+
[--force]` performs the one-time rewrite: for every `skaile.yaml` in the
|
|
75
|
+
project it derives the endpoint the legacy fields addressed (through the same
|
|
76
|
+
`deriveLegacyProviderRegistry` the runtime uses, so the base URL, surface and
|
|
77
|
+
credential carrier are identical), writes it to `~/.skaile/providers.yml`
|
|
78
|
+
through the `skaile providers add` write path, lifts a reserved top-level
|
|
79
|
+
`providers:` block into the same file, and leaves
|
|
80
|
+
`model: <providerId>/<modelId>` behind. Comments and formatting survive, an id
|
|
81
|
+
that already exists with different settings is reported instead of clobbered,
|
|
82
|
+
and a second run is a no-op.
|
|
83
|
+
|
|
84
|
+
`skaile setup` is now a front-end over `skaile providers add`: it picks
|
|
85
|
+
endpoints from the catalog presets (not `ALL_PROVIDERS`), writes entries whose
|
|
86
|
+
credential is an `env:` reference, sends typed secrets to a `.env` file or the
|
|
87
|
+
operator's shell, and saves `driver` plus one selector. It never writes
|
|
88
|
+
`settings.apiKeys`.
|
|
89
|
+
|
|
90
|
+
`skaile config` follows: `set provider|cloud|cloudConfig` is rejected with the
|
|
91
|
+
commands that replace it, `set apiKey.<provider>` creates the registry entry
|
|
92
|
+
with an `env:` reference instead of storing the secret, and `config show` gains
|
|
93
|
+
a "Model selection" section showing which entry, endpoint and credential the
|
|
94
|
+
selector resolves to.
|
|
95
|
+
|
|
96
|
+
A user-local `settings.json` that still carries `apiKeys` keeps working for one
|
|
97
|
+
more minor: `deriveRegistryFromLegacyApiKeys()` (new, in
|
|
98
|
+
`@skaile/workspaces/bridge`) normalizes it into registry entries with `env:`
|
|
99
|
+
references plus one deprecation line, and returns the literal values in a
|
|
100
|
+
`credentialEnv` map for the child environment.
|
|
101
|
+
|
|
102
|
+
Also fixed: `WorkspaceYamlEditor.setAgentConfig` threw when the file had no
|
|
103
|
+
`agent-config` section (it stored a plain object where a YAML node was
|
|
104
|
+
required), and `getAgentConfig` returned the AST node instead of the profile.
|
|
105
|
+
|
|
106
|
+
### Minor Changes
|
|
107
|
+
|
|
108
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - Every session now carries an AI provider `registry` and a `modelRef` beside the
|
|
109
|
+
fields it carried before. Nothing that works today changes: this is the expand
|
|
110
|
+
half of the provider-registry cutover, and the legacy `provider` / `cloud` /
|
|
111
|
+
`cloudConfig` / `cloudSecrets` / `apiKeys` inputs keep driving the drivers.
|
|
112
|
+
|
|
113
|
+
`AgentConfig` (bridge), `AgentRuntimeConfig` (types), `AgentSessionConfig` +
|
|
114
|
+
`AgentSession` (runner) and `SessionSubpromptRunnerOptions` (flow) all gain the
|
|
115
|
+
optional pair. Every session-assembly boundary fills it — CLI flags, the
|
|
116
|
+
platform's `session_init` resolved config, `skaile.yaml`, user settings, the
|
|
117
|
+
in-process `BridgeRuntime`, and isolated sub-prompt sessions. When a boundary
|
|
118
|
+
has only the legacy axis, `resolveSessionProviderBinding()`
|
|
119
|
+
(`@skaile/workspaces/bridge`) derives a **one-entry** registry describing
|
|
120
|
+
exactly the endpoint those fields already addressed — the catalog preset's base
|
|
121
|
+
URL (or the provider's `*_BASE_URL` override), the same wire surface, and the
|
|
122
|
+
same credential kind and carrier that `buildClaudeCloudEnv` uses for
|
|
123
|
+
`bedrock` / `vertex` / `azure` / `gateway` — and returns one deprecation line
|
|
124
|
+
for that boundary to log. The derivation lives in exactly one place; no
|
|
125
|
+
boundary re-implements it. Secrets never enter an entry: the derived
|
|
126
|
+
`credential.ref` names an env var and the value comes back separately as
|
|
127
|
+
`credentialEnv`.
|
|
128
|
+
|
|
129
|
+
**Protocol 3.12.0 → 3.13.0 (additive minor).**
|
|
130
|
+
`ResolvedAgentConfig` (`session_init.resolvedConfig.agentConfig`) gains optional
|
|
131
|
+
`registry?` — the bare `id → entry` map or the merged view — and `modelRef?`
|
|
132
|
+
(`"<providerId>/<modelId>"`, a bare id, or `"@role"`). Control-plane
|
|
133
|
+
credentials are referenced as `platform:<configId>` against the same sibling
|
|
134
|
+
`secrets` map that carries `<PROVIDER>_API_KEY` today. A platform that sends
|
|
135
|
+
only the legacy fields is byte-identical; a 3.12 runner ignores both keys.
|
|
136
|
+
|
|
137
|
+
**Breaking for callers of the model-listing API.** `listModelsForDriver()` and
|
|
138
|
+
`DriverTarget.listModels()` take a registry instead of a flat key map:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
// before
|
|
142
|
+
await listModelsForDriver("omp", settings.apiKeys ?? {});
|
|
143
|
+
// after
|
|
144
|
+
const { registry, credentialEnv } = deriveLegacyProviderRegistry({
|
|
145
|
+
provider: settings.provider,
|
|
146
|
+
apiKeys: settings.apiKeys,
|
|
147
|
+
});
|
|
148
|
+
await listModelsForDriver("omp", registry, {
|
|
149
|
+
env: { ...process.env, ...credentialEnv },
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
A legacy-derived registry yields the same results as the flat map did —
|
|
154
|
+
`registryApiKeys()` is the exact inverse. See `MIGRATION.md`.
|
|
155
|
+
|
|
156
|
+
`BUILTIN_DRIVER_CATALOG` now declares, per driver, the `surfaces` it can speak
|
|
157
|
+
and its `providerPlurality` (`registry` for omp; `credentials-n` for opencode,
|
|
158
|
+
goose and continue; `single` for claude-sdk, codex, gemini and qwen), so a
|
|
159
|
+
consumer can filter registry entries by what a backend can actually address
|
|
160
|
+
instead of matching vendor names. `DriverInfo` is now declared once, in
|
|
161
|
+
`@skaile/workspaces/types`, and re-exported from `@skaile/workspaces/bridge`
|
|
162
|
+
(it was duplicated field-for-field in both).
|
|
163
|
+
|
|
164
|
+
No driver dispatches through the registry yet — that lands per driver in the
|
|
165
|
+
following releases.
|
|
166
|
+
|
|
167
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - The `claude-sdk` driver now addresses the endpoint its AI provider registry
|
|
168
|
+
entry describes — on **every** transport, including the plain `direct` one.
|
|
169
|
+
|
|
170
|
+
Until now the Claude Agent SDK child env was assembled only when `cloud` was
|
|
171
|
+
something other than `default`, so a session whose provider config named a
|
|
172
|
+
custom `base_url` on the default transport silently talked to
|
|
173
|
+
`api.anthropic.com` with that endpoint's credential. The gate is gone: the
|
|
174
|
+
driver resolves its entry through `resolveSessionProviderBinding()` and builds
|
|
175
|
+
the child env from it with `buildClaudeEndpointEnv()`
|
|
176
|
+
(`@skaile/workspaces/bridge`, `src/cloud.ts`).
|
|
177
|
+
|
|
178
|
+
What the entry now decides:
|
|
179
|
+
|
|
180
|
+
- **Endpoint** — `base_url` (or the transport-derived one) becomes
|
|
181
|
+
`ANTHROPIC_BASE_URL`, except for Anthropic's own host, which needs no
|
|
182
|
+
redirect.
|
|
183
|
+
- **Credential** — `credential.kind: api_key_header` rides as
|
|
184
|
+
`ANTHROPIC_API_KEY` (the SDK sends `x-api-key`), `bearer` as
|
|
185
|
+
`ANTHROPIC_AUTH_TOKEN` (`Authorization: Bearer`). `sigv4`, `google_adc` and
|
|
186
|
+
`azure_entra` emit nothing and let the AWS/Google/Azure chain sign, as
|
|
187
|
+
before. `oauth` keeps the shipped `CLAUDE_CODE_CREDENTIALS_JSON` mechanism
|
|
188
|
+
(the runner writes the blob to the Claude credentials file; the driver adds
|
|
189
|
+
no env). `env:` and `cmd:` refs resolve against `process.env` + `config.env`;
|
|
190
|
+
a `platform:<configId>` ref is resolved by the runner (which holds the
|
|
191
|
+
`session_init` secrets map) and picked up from the `SKAILE_AIP_<ID>_KEY`
|
|
192
|
+
carrier it delivers.
|
|
193
|
+
- **Transport flag** — `bedrock-converse-stream` → `CLAUDE_CODE_USE_BEDROCK`,
|
|
194
|
+
`google-vertex` → `CLAUDE_CODE_USE_VERTEX`, `transport: foundry` →
|
|
195
|
+
`CLAUDE_CODE_USE_FOUNDRY`, with the same routing vars the `cloud` axis
|
|
196
|
+
emitted. A golden test pins Bedrock, Vertex, Foundry (by resource and by
|
|
197
|
+
base URL) and gateway output against the legacy builder, entry for entry.
|
|
198
|
+
- **Headers** — an entry's static `headers` reach the wire as
|
|
199
|
+
`ANTHROPIC_CUSTOM_HEADERS`, minus the ones the SDK owns.
|
|
200
|
+
- **Model** — the selector's `model_map` result is the model the session runs.
|
|
201
|
+
|
|
202
|
+
The child env is the driver's base environment **plus** the endpoint vars, so
|
|
203
|
+
`PATH`, `HOME` and `SKAILE_SESSION_ID` survive on every path (the OAuth path
|
|
204
|
+
previously dropped `config.env` entirely).
|
|
205
|
+
|
|
206
|
+
Model discovery follows the same entry: `listModels()` asks the entry's own
|
|
207
|
+
base URL with the entry's credential, reports nothing for Bedrock / Vertex /
|
|
208
|
+
Foundry (their model catalogs live behind their own control planes) and
|
|
209
|
+
nothing at all for an entry with no resolvable endpoint, rather than falling
|
|
210
|
+
back to Anthropic with someone else's key.
|
|
211
|
+
|
|
212
|
+
Sessions that still carry only the legacy `cloud` / `cloudConfig` /
|
|
213
|
+
`cloudSecrets` / `apiKeys` fields are unchanged: they get the one-entry
|
|
214
|
+
derivation, which now also keeps the Foundry transport when the endpoint is
|
|
215
|
+
given as a base URL rather than a resource name, and lets an explicitly
|
|
216
|
+
configured key override an ambient variable of the same name — the precedence
|
|
217
|
+
the drivers applied before the registry existed.
|
|
218
|
+
|
|
219
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - Codex takes its endpoints from a session-private `config.toml` instead of the
|
|
220
|
+
ambient `~/.codex`.
|
|
221
|
+
|
|
222
|
+
Codex is a file-shaped backend: it reads providers from `$CODEX_HOME/config.toml`
|
|
223
|
+
and from nowhere else. The standalone driver now renders the session's AI
|
|
224
|
+
provider registry into one — `[model_providers.<id>]` per entry, with
|
|
225
|
+
`base_url`, `env_key`, `wire_api`, `query_params` and `http_headers` mapping
|
|
226
|
+
1:1 onto the entry's `base_url`, `credential`, `surface`, `query_params` and
|
|
227
|
+
`headers`, plus top-level `model_provider`/`model` naming the selection — and
|
|
228
|
+
sets `CODEX_HOME` to the directory holding it. A session pointed at a gateway
|
|
229
|
+
now actually reaches that gateway, and `listModels()` discovers against the
|
|
230
|
+
same endpoint rather than always asking `api.openai.com`.
|
|
231
|
+
|
|
232
|
+
The rendered file never contains a credential. `env_key` names the per-entry
|
|
233
|
+
variable `SKAILE_AIP_<ID>_KEY` (the programme-wide naming rule, shared with the
|
|
234
|
+
omp and env-shaped adapters) and the value is delivered in the child
|
|
235
|
+
environment. An `oauth` entry gets `requires_openai_auth` instead, which routes
|
|
236
|
+
codex to its own auth manager.
|
|
237
|
+
|
|
238
|
+
Two deliberate limits, both from codex-cli itself. `wire_api` accepts only
|
|
239
|
+
`responses` as of codex-cli 0.154 (`chat` was removed, openai/codex#7782) and
|
|
240
|
+
an unknown value fails the whole document at load, so entries on a surface
|
|
241
|
+
codex cannot speak — `openai-completions`, `anthropic-messages`,
|
|
242
|
+
`bedrock-converse-stream`, `google-*` — are left out of the file and logged
|
|
243
|
+
rather than rendered into a config codex would reject. A session with no
|
|
244
|
+
registry entry codex can address writes no file at all and keeps codex's
|
|
245
|
+
built-in providers, exactly as before.
|
|
246
|
+
|
|
247
|
+
Managed codex restates its credential-isolation invariant on the registry: a
|
|
248
|
+
managed session may carry exactly one enabled `llm` entry, on
|
|
249
|
+
`openai-codex-responses`, whose credential is a platform-injected `oauth`
|
|
250
|
+
reference. A second entry, another surface, or an `env:` / `cmd:` / `keyring:`
|
|
251
|
+
reference fails the session with the existing `AI_PROFILE_INVALID` before the
|
|
252
|
+
native process starts. The one-entry projection the session boundary derives
|
|
253
|
+
from the legacy `provider`/`apiKeys`/`cloud` fields (layer `runtime`) is not a
|
|
254
|
+
configured endpoint and is exempt — those inputs are already covered by the
|
|
255
|
+
sibling checks on `provider`, `apiKeys.openai` and `env.OPENAI_API_KEY`.
|
|
256
|
+
Managed mode continues to bind its provider through the app-server login flow
|
|
257
|
+
and renders no provider table: a config-defined provider authenticates from
|
|
258
|
+
`env_key`, so redirecting `model_provider` at one would strip a managed session
|
|
259
|
+
of the very credential the isolation exists to protect.
|
|
260
|
+
|
|
261
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - The env-shaped CLI drivers — `gemini`, `qwen`, `opencode`, `goose` and
|
|
262
|
+
`continue` — now take their endpoints and credentials from the AI provider
|
|
263
|
+
registry instead of a hardcoded per-driver key allowlist.
|
|
264
|
+
|
|
265
|
+
**Single-provider backends (`gemini`, `qwen`).** The entry the session's model
|
|
266
|
+
selector names supplies everything: `qwen` sends that entry's `base_url`,
|
|
267
|
+
credential and mapped model id as `OPENAI_BASE_URL` / `OPENAI_API_KEY` /
|
|
268
|
+
`OPENAI_MODEL` (plus `-m`), and `gemini` sends `GEMINI_API_KEY` with `-m` from
|
|
269
|
+
the model ref and `GOOGLE_GEMINI_BASE_URL` for a non-default host. Once an
|
|
270
|
+
entry is bound it is the only authority: an inherited `OPENAI_*` /
|
|
271
|
+
`GEMINI_API_KEY` from the host shell no longer leaks into a session pointed
|
|
272
|
+
somewhere else. Pointing one of them at an entry whose `surface` it cannot
|
|
273
|
+
speak now fails at `start()` — before the first spawn — with the offending
|
|
274
|
+
surface and the backend's own surfaces named, rather than surfacing as an
|
|
275
|
+
opaque HTTP error mid-turn.
|
|
276
|
+
|
|
277
|
+
**`credentials-n` backends (`opencode`, `goose`, `continue`).** Every _enabled_
|
|
278
|
+
entry contributes one credential variable, `SKAILE_AIP_<ID>_KEY`, plus the
|
|
279
|
+
vendor carrier a stock catalog endpoint is already known by
|
|
280
|
+
(`ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, …). The active model is the registry
|
|
281
|
+
selection: `opencode -m <provider>/<model>`, `GOOSE_PROVIDER` +
|
|
282
|
+
`GOOSE_MODEL`, and — because `cn` has no model flag — a Continue **role
|
|
283
|
+
binding** for the `chat` role, which is also the shape the generated
|
|
284
|
+
`config.yaml` will be rendered from. A model selector that the registry
|
|
285
|
+
resolves is no longer passed to `cn --config`, which only ever named a Hub
|
|
286
|
+
assistant.
|
|
287
|
+
|
|
288
|
+
Model discovery takes the registry throughout: `gemini` and `qwen` query the
|
|
289
|
+
bound entry's own endpoint with its credential, and the three `credentials-n`
|
|
290
|
+
backends — which have no discovery endpoint of their own — list what the
|
|
291
|
+
registry declares, namespaced the way each takes it.
|
|
292
|
+
|
|
293
|
+
Two shared pieces come with this:
|
|
294
|
+
`bridge/src/provider-materialize/credential-env.ts` is the single naming rule
|
|
295
|
+
for per-entry credential variables (`providerCredentialEnvName`,
|
|
296
|
+
`registryCredentialEnv`), used by the omp, codex and CLI adapters alike, and
|
|
297
|
+
`bridge/src/provider-materialize/env-drivers.ts` resolves a session's
|
|
298
|
+
registry, binds its selector to an entry and enforces the surface.
|
|
299
|
+
|
|
300
|
+
`SubprocessCliDriver.baseEnv()` now merges `config.env` **over** the allowlist
|
|
301
|
+
instead of replacing it: setting one variable used to drop `PATH` and `HOME`
|
|
302
|
+
and make the spawn fail, which the registry delivery path depends on.
|
|
303
|
+
|
|
304
|
+
Sessions carrying only the legacy `provider` / `model` / `apiKeys` fields are
|
|
305
|
+
unchanged. The one-entry derivation those produce describes a credential, not
|
|
306
|
+
a chosen endpoint — `provider` defaults to `anthropic` for every session — so
|
|
307
|
+
the drivers take its credentials but keep their pre-registry model selection,
|
|
308
|
+
and a single-provider driver handed such an entry with an unusable surface
|
|
309
|
+
warns and falls back instead of failing.
|
|
310
|
+
|
|
311
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - Model identity is per wire surface, and model tiers resolve through the provider
|
|
312
|
+
registry.
|
|
313
|
+
|
|
314
|
+
An Anthropic-shaped model id is now required for exactly one target: `surface:
|
|
315
|
+
anthropic-messages` on `transport: direct` pointed at `api.anthropic.com`. Every
|
|
316
|
+
other endpoint names models we cannot enumerate — a Bedrock inference-profile
|
|
317
|
+
ARN, an Azure deployment name, `accounts/fireworks/models/…`,
|
|
318
|
+
`meta-llama/Llama-3.3-70B`, an Ollama tag — and those ids are now accepted.
|
|
319
|
+
New in `@skaile/workspaces/types/manifests`: `ModelIdTarget`,
|
|
320
|
+
`requiresAnthropicModelId()`, `modelIdSchemaForTarget()`,
|
|
321
|
+
`isFirstPartyAnthropicEndpoint()`, `ANTHROPIC_FIRST_PARTY_HOSTS`,
|
|
322
|
+
`FreeFormModelIdSchema` and `ModelSelectorSchema`. `ModelIdSchema` is unchanged
|
|
323
|
+
but is no longer a universal rule: it is the first-party Anthropic vocabulary,
|
|
324
|
+
selected by `modelIdSchemaForTarget()`. `modelIdSchemaForCloud()` keeps its
|
|
325
|
+
signature and is now free-form for every `cloud` other than `default` —
|
|
326
|
+
`bedrock`, `vertex` and `azure` rename the ids, so validating them against
|
|
327
|
+
Anthropic's namespace rejected working deployments.
|
|
328
|
+
|
|
329
|
+
`AgentManifest.model.preferred` / `.fallback` accept a model **selector**:
|
|
330
|
+
`@role`, `<providerId>/<modelId>`, a bare id, or an Anthropic alias. A manifest
|
|
331
|
+
is portable across providers and cannot know which entry will serve it, so the
|
|
332
|
+
id-vocabulary check moved to where the endpoint is known. Only a value no
|
|
333
|
+
endpoint could be handed (empty, or containing whitespace) still fails
|
|
334
|
+
`validateAgent`.
|
|
335
|
+
|
|
336
|
+
New in `@skaile/workspaces/bridge` (`bridge/src/models.ts`):
|
|
337
|
+
`resolveManifestModel()` resolves a manifest preference against the registry —
|
|
338
|
+
`@role` through `roles`, then `provider/id`, then a bare id, all via
|
|
339
|
+
`parseModelRef()` — and reports an `error` when the id the entry would receive
|
|
340
|
+
is not legal for its surface. `modelIdTargetForEntry()` derives that target from
|
|
341
|
+
an entry (falling back to its catalog preset for `surface` / `base_url`).
|
|
342
|
+
`resolveModelCapabilities()` reads `capabilities.context_window` /
|
|
343
|
+
`thinking_max` / `tools` / `images` from the entry serving a model, field by
|
|
344
|
+
field over a caller-supplied per-model fallback table.
|
|
345
|
+
|
|
346
|
+
`resolveModelTier()` takes `{registry, roles, providerId}` and resolves
|
|
347
|
+
`small`/`default`/`deep` through `roles[tier]` and then the selected entry's
|
|
348
|
+
`model_map[tier]` — which works for every provider, not just the ten in
|
|
349
|
+
`PROVIDER_MODEL_TIERS`. That table is now the **no-registry fallback only**:
|
|
350
|
+
where a registry is configured it is not consulted, and a tier the registry does
|
|
351
|
+
not define raises `ModelTierResolutionError` instead of substituting a guess.
|
|
352
|
+
Precedence is unchanged otherwise: a configured override first, and `default`
|
|
353
|
+
still inherits the session model before any table.
|
|
354
|
+
|
|
355
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - omp sees every configured AI provider, out of a session-private agent directory.
|
|
356
|
+
|
|
357
|
+
omp is the one backend whose native config already _is_ the registry shape:
|
|
358
|
+
`models.yml` is a `providers:` map with `baseUrl`, `api`, `apiKey`, `headers`,
|
|
359
|
+
`authHeader`, `auth`, `discovery` and `models[]`. So the new adapter
|
|
360
|
+
(`bridge/src/drivers/omp-models-yml.ts`) is a serializer, not a translator —
|
|
361
|
+
each enabled `llm` entry becomes one omp provider, `surface` is written
|
|
362
|
+
verbatim as `api` (the two enums are the same list), `model_map` becomes
|
|
363
|
+
`models[]` keyed by the provider-side id, and `AgentConfig.roles` becomes
|
|
364
|
+
`modelRoles` in a sibling `config.yml`. The result: three configured endpoints
|
|
365
|
+
are three selectable providers in one session, `@smol` and `@default` resolve
|
|
366
|
+
to different vendors, and a subagent pinned to `@smol` reaches that endpoint —
|
|
367
|
+
verified against omp 18.2.6 with fake servers logging the requests.
|
|
368
|
+
|
|
369
|
+
`apiKey` holds the **name** of `SKAILE_AIP_<ID>_KEY`, never a value: omp
|
|
370
|
+
resolves a `models.yml` `apiKey` as an environment variable name before it
|
|
371
|
+
falls back to treating it as a literal token, so the credential can stay in the
|
|
372
|
+
child environment where a config file cannot leak it. The ~50-name
|
|
373
|
+
`OMP_PROVIDER_ENV_KEYS` allowlist stops being the mechanism by which
|
|
374
|
+
credentials reach omp and survives only as an ambient fallback (and as the
|
|
375
|
+
carrier for the `sigv4` / `google_adc` signing chains an entry delegates to)
|
|
376
|
+
until the legacy-contract change deletes it.
|
|
377
|
+
|
|
378
|
+
`PI_CODING_AGENT_DIR` relocates omp's whole agent base — `config.yml`,
|
|
379
|
+
`models.yml` _and_ the auth store `agent.db` — so pointing it at a
|
|
380
|
+
session-private directory is what makes N providers per session possible
|
|
381
|
+
without ever writing the user's `~/.omp/agent`. The directory sits outside
|
|
382
|
+
`cwd`, the one tree the agent has write access to, matching the line managed
|
|
383
|
+
codex already draws for its private directory; `AgentConfig.agentDir`'s
|
|
384
|
+
identity files are symlinked in so `agent.yaml` / `SOUL.md` / `RULES.md` /
|
|
385
|
+
`knowledge/` still resolve.
|
|
386
|
+
|
|
387
|
+
Relocating that base would also have cost a developer their stored OAuth
|
|
388
|
+
logins, which was the one risk that could have descoped this to
|
|
389
|
+
"one active provider". It does not: a machine that has `~/.omp/agent` gets its
|
|
390
|
+
contents symlinked into the session directory, and an OAuth account stored
|
|
391
|
+
there still authenticates inside the relocated session (checked with `omp
|
|
392
|
+
token`, omp 18.2.6). `models.yml` is never seeded and `config.yml` is copied
|
|
393
|
+
rather than linked, so neither of the user's files can be written through the
|
|
394
|
+
session. A platform container has no such directory, so its session starts
|
|
395
|
+
empty — which is the correct behaviour there.
|
|
396
|
+
|
|
397
|
+
`AgentConfig` gains `roles` (the `skaile.yaml` role table) and
|
|
398
|
+
`DriverOptions.omp` (`agentHome`, `seedUserAgentDir`, `userAgentDir`); both are
|
|
399
|
+
additive. A session with no registry keeps the previous behaviour exactly.
|
|
400
|
+
|
|
401
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - A custom endpoint now reaches OpenCode, Goose and Continue, not only the
|
|
402
|
+
vendors their own tables know.
|
|
403
|
+
|
|
404
|
+
The env half of these three backends (`SKAILE_AIP_<ID>_KEY` per entry, plus
|
|
405
|
+
`-m <provider>/<model>` / `GOOSE_PROVIDER` / a Continue `chat` binding) can
|
|
406
|
+
name an endpoint the backend already knows. It cannot describe one it has
|
|
407
|
+
never heard of — a self-hosted gateway, a LiteLLM proxy, an Ollama box — and
|
|
408
|
+
each of these backends learns such an endpoint only from its own config file.
|
|
409
|
+
Each driver now renders one:
|
|
410
|
+
|
|
411
|
+
- `opencode` — `opencode/opencode.json` with a `provider.<id>` block
|
|
412
|
+
(`npm` from the entry's `surface`, `options.baseURL`, `options.apiKey`,
|
|
413
|
+
`models`), reached by pointing `XDG_CONFIG_HOME` at the session's own
|
|
414
|
+
directory.
|
|
415
|
+
- `goose` — a declarative provider per entry,
|
|
416
|
+
`config/custom_providers/<id>.json` (`engine`, `base_url`, `api_key_env`,
|
|
417
|
+
`models[]`, `headers`), reached through `GOOSE_PATH_ROOT`.
|
|
418
|
+
- `continue` — `config.yaml` with one `models[]` row per bound model, reached
|
|
419
|
+
through `CONTINUE_GLOBAL_DIR`. `cn` has no model flag, so the session's
|
|
420
|
+
`roles:` table is what binds them: each key that is a Continue role
|
|
421
|
+
(`chat`, `edit`, `apply`, `autocomplete`, `embed`, `rerank`, `summarize`;
|
|
422
|
+
`default` is read as `chat`) becomes that role's model, and the session's
|
|
423
|
+
own selector wins `chat`.
|
|
424
|
+
|
|
425
|
+
Three invariants hold across all three. The rendered file never contains a
|
|
426
|
+
credential — it names the per-entry variable (`{env:SKAILE_AIP_<ID>_KEY}`,
|
|
427
|
+
`api_key_env`, `${{ secrets.… }}`) and the value is delivered in the child
|
|
428
|
+
environment, the same rule the codex and omp adapters follow. The provider
|
|
429
|
+
name in the file is `backendProviderName`, the same name the env half puts on
|
|
430
|
+
the command line, so the two halves cannot drift apart. And the config home is
|
|
431
|
+
session-private, under `$SKAILE_HOME/<driver>/<sessionId>`: the developer's
|
|
432
|
+
`~/.config/opencode`, Goose config directory and `~/.continue` are neither
|
|
433
|
+
read nor written, which also keeps a session's state out of them.
|
|
434
|
+
|
|
435
|
+
Nothing is rendered unless something has to be. A session whose endpoints are
|
|
436
|
+
all stock catalog endpoints, and a session that carries only the legacy
|
|
437
|
+
`provider`/`model`/`apiKeys` fields, write no file and leave the config-home
|
|
438
|
+
variable unset — those backends behave exactly as before, including reading
|
|
439
|
+
the developer's own config.
|
|
440
|
+
|
|
441
|
+
Entries a backend genuinely cannot express are left out of the file and
|
|
442
|
+
logged, never guessed at: Goose's declarative providers are `openai` /
|
|
443
|
+
`anthropic` / `ollama` engines only, so `google-*` and
|
|
444
|
+
`bedrock-converse-stream` entries are reported instead; the same applies to
|
|
445
|
+
any surface with no OpenCode AI SDK package or Continue provider class.
|
|
446
|
+
|
|
447
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`194a9c3`](https://github.com/skaile-ai/workspaces/commit/194a9c36cfc6ed6ac028db4aeadaf6d37e32f3cf) Thanks [@mortegro](https://github.com/mortegro)! - Add the AI provider registry: `providers.yml` defines every LLM and voice
|
|
448
|
+
endpoint once, and `skaile providers list|add|set|rm|test` manages it.
|
|
449
|
+
|
|
450
|
+
New in `@skaile/workspaces/core` (`core/src/provider-registry.ts`, also exported
|
|
451
|
+
as `@skaile/workspaces/core/provider-registry`): the record types
|
|
452
|
+
(`kind, label, preset, surface, transport, base_url, params, headers,
|
|
453
|
+
query_params, credential{kind, ref}, model_map, capabilities, discovery,
|
|
454
|
+
enabled, locked`), `validateRegistry()`, `mergeRegistries()`,
|
|
455
|
+
`resolveCredential()`, `resolveEntryBaseUrl()` and `parseModelRef()`.
|
|
456
|
+
`surface` is omp's `api` vocabulary verbatim; `params` is a discriminated union
|
|
457
|
+
keyed on `transport`; `stt`/`tts` entries use a reduced record and reject the
|
|
458
|
+
llm-only fields. A literal secret in `credential.ref`, `headers`,
|
|
459
|
+
`query_params` or `base_url` is a validation error naming the offending key —
|
|
460
|
+
credentials are referenced as `env:NAME`, `cmd:<shell>`, `platform:<configId>`
|
|
461
|
+
or `keyring:<service>/<account>`.
|
|
462
|
+
|
|
463
|
+
`core/src/provider-registry-files.ts` loads `~/.skaile/providers.yml` under
|
|
464
|
+
`<workspace>/.skaile/providers.yml`; the layers are merged **before** they are
|
|
465
|
+
gated, so a file may hold a _partial_ entry — one that names only the fields it
|
|
466
|
+
overrides, `kind` included — and the nearer layer wins per key. An entry no
|
|
467
|
+
layer completes is the error (`missing_kind`, `missing_surface`, naming the
|
|
468
|
+
files that fed it), reported by `loadProviderRegistry()`;
|
|
469
|
+
`validateMergedRegistry()` is that gate for anyone merging layers themselves,
|
|
470
|
+
and `validateRegistry(raw, { layer })` reads one layer. An entry marked
|
|
471
|
+
`locked: true` in a higher layer cannot be overridden from a lower one.
|
|
472
|
+
`bridge/src/provider-catalog.ts` ships presets for the surveyed endpoints
|
|
473
|
+
(Anthropic, OpenAI, Google, Groq, DeepSeek, OpenRouter, Mistral, xAI, Together,
|
|
474
|
+
Fireworks, Bedrock, Vertex, Azure OpenAI, Foundry, Ollama, LM Studio, vLLM,
|
|
475
|
+
LiteLLM, Deepgram, ElevenLabs) so `skaile providers add --preset groq` needs
|
|
476
|
+
nothing but a credential reference.
|
|
477
|
+
|
|
478
|
+
`skaile init` now gitignores `.skaile/providers.yml`. No driver reads the
|
|
479
|
+
registry yet — this release is the schema, the catalog and the CLI.
|
|
480
|
+
|
|
481
|
+
### Patch Changes
|
|
482
|
+
|
|
483
|
+
- [#736](https://github.com/skaile-ai/workspaces/pull/736) [`2de14a6`](https://github.com/skaile-ai/workspaces/commit/2de14a64fdcd77ec8273679bb13f2a0bf149d845) Thanks [@mortegro](https://github.com/mortegro)! - Fix the provider registry dropping entries whose `kind` or transport `params` come from a preset: the catalog layer is now built from the pre-gate merge (`LoadedProviderRegistry.patches`), so `groq: { preset: groq }` plus a workspace `base_url` override resolves to a complete entry instead of a false "no layer supplies it" error, and a session whose entries all fail the gate logs the diagnostics instead of silently running with no endpoint. The completeness gate also re-scans `credential.ref`, `headers`, `query_params` and `base_url` on programmatically injected layers for literal secrets, and every merge-time diagnostic now names the files that contributed the entry.
|
|
484
|
+
|
|
3
485
|
## 3.27.1
|
|
4
486
|
|
|
5
487
|
### Patch Changes
|
package/dist/app-sdk/index.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import { assignDomain, buildDomainIndex, DOMAIN_MD_FILENAME, parseDomainMd } from './chunk-
|
|
1
|
+
import { assignDomain, buildDomainIndex, DOMAIN_MD_FILENAME, parseDomainMd } from './chunk-M5H4DWIA.js';
|
|
2
2
|
import './chunk-JXT46QFC.js';
|
|
3
|
-
import './chunk-
|
|
3
|
+
import './chunk-3VSRJE3M.js';
|
|
4
|
+
import { factoryAssetRoots } from './chunk-REILIKVM.js';
|
|
4
5
|
import './chunk-F3HNW354.js';
|
|
5
6
|
import './chunk-K5GBV4SA.js';
|
|
6
7
|
import './chunk-QVZA2MDT.js';
|
|
7
|
-
import {
|
|
8
|
-
import { scanRepo } from './chunk-MBARHWMZ.js';
|
|
8
|
+
import { scanRepo } from './chunk-K27T47OO.js';
|
|
9
9
|
import './chunk-MENCWIHW.js';
|
|
10
10
|
import './chunk-P4VHQA4N.js';
|
|
11
11
|
import { walkDir, parseFrontmatter } from './chunk-MKZOK4JU.js';
|
|
12
12
|
import './chunk-GEEW6SY2.js';
|
|
13
13
|
import './chunk-FTG7CRFD.js';
|
|
14
|
+
import './chunk-KSIRR5PL.js';
|
|
15
|
+
import './chunk-ILG4BXYE.js';
|
|
14
16
|
import './chunk-W4IPN3DD.js';
|
|
15
|
-
import './chunk-
|
|
17
|
+
import './chunk-N7B3LZ7V.js';
|
|
16
18
|
import './chunk-NSBPE2FW.js';
|
|
17
19
|
import { existsSync, readFileSync } from 'fs';
|
|
18
20
|
import * as path from 'path';
|
|
@@ -65,7 +67,7 @@ async function libraryAssets() {
|
|
|
65
67
|
const domains = [];
|
|
66
68
|
try {
|
|
67
69
|
const [{ openLibraryManager }, { skaileHomeDir }, { getGlobalCacheDir }] = await Promise.all([
|
|
68
|
-
import('./open-library-
|
|
70
|
+
import('./open-library-7OIUAGAH.js'),
|
|
69
71
|
import('./library/index.js'),
|
|
70
72
|
import('./core/index.js')
|
|
71
73
|
]);
|
|
@@ -98,7 +100,7 @@ async function libraryAssets() {
|
|
|
98
100
|
async function storeAssets(projectDir) {
|
|
99
101
|
const notes = [];
|
|
100
102
|
try {
|
|
101
|
-
const { resolveCatalogSource } = await import('./open-library-
|
|
103
|
+
const { resolveCatalogSource } = await import('./open-library-7OIUAGAH.js');
|
|
102
104
|
const { source, close } = await resolveCatalogSource({ projectDir });
|
|
103
105
|
try {
|
|
104
106
|
const assets = await source.listAssets();
|
|
@@ -202,5 +204,5 @@ function dedupeBySlug(domains) {
|
|
|
202
204
|
}
|
|
203
205
|
|
|
204
206
|
export { gatherAssetFeeds };
|
|
205
|
-
//# sourceMappingURL=asset-feeds-
|
|
206
|
-
//# sourceMappingURL=asset-feeds-
|
|
207
|
+
//# sourceMappingURL=asset-feeds-VEPD5ZU7.js.map
|
|
208
|
+
//# sourceMappingURL=asset-feeds-VEPD5ZU7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../cli/src/asset-feeds.ts"],"names":[],"mappings":"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","file":"asset-feeds-VEPD5ZU7.js","sourcesContent":["/**\n * asset-feeds.ts — gather installable assets from every feed the manage TUI\n * surfaces.\n *\n * Four feeds, normalized into `CatalogEntry`:\n * - **Project sources** — `skaile.yaml` `sources:` entries (scanned via\n * `AssetManager.search()`; the new `sources:` field is merged into the\n * legacy repositories map in `AssetManager.loadConfig`).\n * - **Local libraries** — user authoring places from `LocalIndex` (filesystem\n * scan of each library's `path`).\n * - **Factory assets** — the bundled first-party `factory-assets` tree\n * (`factoryAssetRoots()`), scanned from disk. Always present; no network.\n * - **Remote store** — the configured catalog source when `catalog.url` is\n * not `local`. Failures are non-fatal — they surface as notes.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n type AssetKind,\n type CatalogDomain,\n type CatalogEntry,\n factoryAssetRoots,\n parseFrontmatter,\n scanRepo,\n walkDir,\n} from \"@skaile/workspaces/core\";\nimport {\n assignDomain,\n buildDomainIndex,\n DOMAIN_MD_FILENAME,\n type DomainMd,\n parseDomainMd,\n} from \"@skaile/workspaces/discovery\";\n\n/** One non-fatal note returned to the caller for surfacing in the UI. */\nexport interface FeedNote {\n feed: \"sources\" | \"libraries\" | \"store\" | \"factory\";\n message: string;\n}\n\n/**\n * Which feed an asset came from. This is the top-level grouping axis in the\n * manage TUI (\"where is this skill coming from?\") and is intentionally distinct\n * from `publisher` (asset-intrinsic identity): the same publisher can legitimately\n * appear under more than one origin (e.g. a github repo you added as a `source`\n * that is also listed in the remote `store`).\n */\nexport type AssetOrigin = \"source\" | \"library\" | \"factory\" | \"store\";\n\n/** A catalog entry tagged with the feed it was gathered from. */\nexport interface OriginEntry {\n origin: AssetOrigin;\n entry: CatalogEntry;\n /**\n * Second-level grouping label for the manage tree. Defaults (when unset) to the\n * entry's `publisher`; the source feed sets it to the source's short repo name\n * so the Sources band groups by source — \"which repo did this come from\" — not\n * by the asset-intrinsic publisher.\n */\n group?: string;\n}\n\nexport interface AssetFeedResult {\n entries: OriginEntry[];\n /**\n * Display-only domain metadata, keyed (by the consumer) on `slug`. Populated\n * from the store's `catalog.listDomains` when the connected catalog source\n * exposes it; empty otherwise. The manage TUI joins `entry.domainSlug` → a\n * domain for grouping headers, descriptions, and relation badges.\n */\n domains: CatalogDomain[];\n notes: FeedNote[];\n}\n\n// ── Domain stamping (on-disk feeds) ──────────────────────────────────────────\n//\n// `scanRepo` (the source / library / factory scan path) does not read the\n// `DOMAIN.md` sidecars, so its entries arrive with no `domainSlug` and render\n// flat under their publisher band. We re-derive the grouping here from the\n// root's `DOMAIN.md` files (the same sidecars the remote store computes\n// server-side), and fall back to the repo/source name for any entry no domain\n// claims so it still groups instead of landing in the synthetic \"no domain\" pile.\n\n/** Repo-relative POSIX path (DOMAIN.md slugs are matched whole-segment, `/`-joined). */\nfunction toPosix(p: string): string {\n return p.split(path.sep).join(\"/\");\n}\n\n/** Parse every `DOMAIN.md` sidecar under `root` into a {@link DomainMd}. */\nasync function loadDomainMds(root: string): Promise<DomainMd[]> {\n const out: DomainMd[] = [];\n for await (const { path: filePath, name } of walkDir(root)) {\n if (name !== DOMAIN_MD_FILENAME) continue;\n try {\n const { data } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n out.push(parseDomainMd(toPosix(path.relative(root, filePath)), data));\n } catch {}\n }\n return out;\n}\n\n/**\n * Stamp `domainSlug` onto every entry scanned from `root` using the root's\n * `DOMAIN.md` sidecars. Returns the `CatalogDomain` registry for the real\n * domains, plus a synthetic fallback domain when any entry used the fallback.\n * Mutates `entries` in place (sets `entry.domainSlug`).\n *\n * `synthesizeFallback` (default true): entries no domain claims fall back to\n * `fallbackSlug` (the repo/source name). Pass `false` when the caller already\n * groups these entries one level up (e.g. the source feed groups by source\n * node) — unmatched entries then get no domain (`\"\"`) and hang directly under\n * that parent, instead of nesting under a same-named fallback domain.\n */\nasync function stampDomains(\n root: string,\n fallbackSlug: string,\n entries: CatalogEntry[],\n synthesizeFallback = true,\n): Promise<CatalogDomain[]> {\n const domainMds = await loadDomainMds(root);\n const assignables = entries.map((entry) => ({\n entry,\n ref: `${entry.kind}:${entry.name}`,\n relativePath: toPosix(path.relative(root, entry.source)),\n }));\n\n let usedFallback = false;\n for (const a of assignables) {\n const slug = assignDomain(a.relativePath, domainMds);\n if (slug) a.entry.domainSlug = slug;\n else if (synthesizeFallback) {\n a.entry.domainSlug = fallbackSlug;\n usedFallback = true;\n } else a.entry.domainSlug = \"\";\n }\n\n const { index } = buildDomainIndex(assignables, domainMds);\n const catalog: CatalogDomain[] = Object.values(index).map((d) => ({\n slug: d.slug,\n title: d.title,\n ...(d.description ? { description: d.description } : {}),\n ...(d.relation ? { relation: d.relation } : {}),\n ...(d.order !== undefined ? { order: d.order } : {}),\n ...(d.recommended[0] ? { recommendedRef: d.recommended[0] } : {}),\n }));\n if (usedFallback) catalog.push({ slug: fallbackSlug, title: fallbackSlug });\n return catalog;\n}\n\n/**\n * Pull assets from local libraries (the authoring places under\n * `~/.skaile/libraries/<name>/`, not the `~/.skaile/cache/sources/` cache). Each\n * library's `path` is scanned with `scanRepo` and grouped under the bare library\n * name (`group: <name>`) so the manage TUI shows a clean `<name>` band — no\n * `library:` prefix and no redundant same-named fallback domain (mirrors the\n * source feed).\n */\nasync function libraryAssets(): Promise<{\n entries: OriginEntry[];\n domains: CatalogDomain[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n const domains: CatalogDomain[] = [];\n try {\n const [{ openLibraryManager }, { skaileHomeDir }, { getGlobalCacheDir }] = await Promise.all([\n import(\"./open-library.ts\"),\n import(\"@skaile/workspaces/library\"),\n import(\"@skaile/workspaces/core\"),\n ]);\n const { manager, close } = await openLibraryManager();\n try {\n // Authoring libraries are the rows that are NOT source clones. index.db\n // rows predating the cache migration still carry the legacy\n // ~/.skaile/sources path, so exclude both roots.\n const newRoot = getGlobalCacheDir();\n const legacyRoot = path.join(skaileHomeDir(), \"sources\");\n const libs = (await manager.listLibraries()).filter(\n (l) => !l.path.startsWith(newRoot) && !l.path.startsWith(legacyRoot),\n );\n const entries: OriginEntry[] = [];\n for (const lib of libs) {\n if (!existsSync(lib.path)) continue;\n // Scan + group under the bare library name. `synthesizeFallback: false`\n // (as the source feed does) keeps domainless assets directly under the\n // library band instead of a redundant same-named fallback domain.\n const libEntries = [...(await scanRepo(lib.path, lib.name))];\n domains.push(...(await stampDomains(lib.path, lib.name, libEntries, false)));\n for (const entry of libEntries) entries.push({ origin: \"library\", entry, group: lib.name });\n }\n return { entries, domains, notes };\n } finally {\n close();\n }\n } catch (err) {\n notes.push({\n feed: \"libraries\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], domains, notes };\n }\n}\n\n/**\n * Pull a (best-effort) snapshot of the connected remote store catalog.\n *\n * - Returns no entries when the resolved catalog is local-only or the host\n * is unreachable (the failure becomes a note, not an exception).\n * - Maps `CatalogAsset` → `CatalogEntry`, carrying `publisher`, `repo`, and\n * `category` straight through and using `source = \"store://<id>\"`; per-file\n * `source` paths are not available for remote assets so the canonical ref is\n * a stable placeholder.\n */\nasync function storeAssets(projectDir: string): Promise<{\n entries: CatalogEntry[];\n domains: CatalogDomain[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const { resolveCatalogSource } = await import(\"./open-library.ts\");\n const { source, close } = await resolveCatalogSource({ projectDir });\n try {\n const assets = await source.listAssets();\n const entries: CatalogEntry[] = assets.map((a) => ({\n name: a.name,\n kind: (a.kind as AssetKind) ?? \"skill\",\n description: a.description ?? \"\",\n source: `store://${a.id}`,\n publisher: a.publisher,\n repo: a.repo,\n domainSlug: a.domainSlug,\n category: a.category,\n version: a.version,\n requires: [],\n dependencies: [],\n }));\n // Domains are optional on the catalog source — only the store backend\n // (post Part 4 `catalog.listDomains`) exposes them. Duck-type the call so\n // older sources and the local catalog degrade to no domains, not an error.\n const domains = await loadDomains(source);\n return { entries, domains, notes };\n } finally {\n close();\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // Local-only catalog throws a recognizable message — silence it; absence\n // is the user's choice, not an error.\n if (!/local/i.test(msg)) {\n notes.push({ feed: \"store\", message: msg });\n }\n return { entries: [], domains: [], notes };\n }\n}\n\n/** Optional `listDomains` capability — returns `[]` when the source lacks it. */\nasync function loadDomains(source: unknown): Promise<CatalogDomain[]> {\n const fn = (source as { listDomains?: () => Promise<CatalogDomain[]> }).listDomains;\n if (typeof fn !== \"function\") return [];\n const domains = await fn.call(source);\n return Array.isArray(domains) ? domains : [];\n}\n\n/** The slice of `AssetManager` the source feed needs (kept narrow for tests). */\ninterface AssetManagerLike {\n search: () => Promise<CatalogEntry[]>;\n searchRepoRoots: () => { repoName: string; root: string }[];\n}\n\n/**\n * Project-source feed: leans on `AssetManager.search()`, which now merges\n * `skaile.yaml`'s `sources:` field into the repositories map, then stamps\n * `DOMAIN.md`-derived domain grouping onto the scanned entries via\n * `searchRepoRoots()`.\n */\nasync function sourceAssets(\n am: AssetManagerLike,\n): Promise<{ entries: OriginEntry[]; domains: CatalogDomain[] }> {\n // The bundled factory tree is injected into the repositories map as an implicit\n // source, so `am.search()` returns it too. It has its own `factory` origin band,\n // so drop it here — otherwise the same first-party skills list twice under Sources.\n const factoryPrefixes = factoryAssetRoots().map((r) => (r.endsWith(path.sep) ? r : r + path.sep));\n const isFactoryPath = (p: string) =>\n factoryPrefixes.some((fp) => p === fp.slice(0, -1) || p.startsWith(fp));\n\n const all = (await am.search()).filter((e) => !isFactoryPath(e.source));\n const entries: OriginEntry[] = [];\n const domains: CatalogDomain[] = [];\n // Group each source's entries under the source node (its short repo name), not\n // the publisher: under Sources the navigational question is \"which repo did\n // this come from\". Each entry's `source` (absolute manifest path) lives under\n // exactly one declared root, so group + stamp by prefix. The cache slug is\n // URL-keyed `github.com/<org>/<repo>` — take the trailing segment.\n for (const { repoName, root } of am.searchRepoRoots()) {\n if (isFactoryPath(root)) continue;\n const prefix = root.endsWith(path.sep) ? root : root + path.sep;\n const owned = all.filter((e) => e.source === root || e.source.startsWith(prefix));\n if (owned.length === 0) continue;\n const sourceName = repoName.split(\"/\").pop() || repoName;\n // No synthetic fallback domain — the source node already groups these, so a\n // same-named fallback would just nest the source under itself.\n domains.push(...(await stampDomains(root, sourceName, owned, false)));\n for (const entry of owned) entries.push({ origin: \"source\", entry, group: sourceName });\n }\n return { entries, domains };\n}\n\n/**\n * Factory-asset feed: scan the bundled first-party `factory-assets` tree(s)\n * resolved by `factoryAssetRoots()` (the `SKAILE_FACTORY_ASSETS_DIR` override\n * layer ahead of the bundled tree). Local disk only, no network — the entries are\n * the built-in skills / connectors / bundles that ship with `@skaile/workspaces`.\n * `factoryAssetRoots()` already dedupes, so the env override pointing at the\n * bundled dir collapses to one root.\n */\nasync function factoryAssets(): Promise<{\n entries: CatalogEntry[];\n domains: CatalogDomain[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n const domains: CatalogDomain[] = [];\n try {\n const entries: CatalogEntry[] = [];\n for (const root of factoryAssetRoots()) {\n const rootEntries = [...(await scanRepo(root, \"skaile-factory\"))];\n domains.push(...(await stampDomains(root, \"skaile-factory\", rootEntries)));\n entries.push(...rootEntries);\n }\n return { entries, domains, notes };\n } catch (err) {\n notes.push({\n feed: \"factory\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], domains, notes };\n }\n}\n\n/** Tag a flat entry list with a single origin. */\nfunction tag(origin: AssetOrigin, entries: CatalogEntry[]): OriginEntry[] {\n return entries.map((entry) => ({ origin, entry }));\n}\n\n/**\n * Run all feeds and return a single normalized result.\n *\n * Feeds run in parallel where possible — the store fetch is the slow one\n * (one HTTP call) and is fired alongside the local library walk. The factory\n * scan is local disk only, so it runs inline.\n */\nexport async function gatherAssetFeeds(\n am: AssetManagerLike,\n projectDir: string,\n): Promise<AssetFeedResult> {\n const [libs, store] = await Promise.all([libraryAssets(), storeAssets(projectDir)]);\n const factory = await factoryAssets();\n const src = await sourceAssets(am);\n return {\n entries: [\n ...src.entries,\n ...libs.entries,\n ...tag(\"factory\", factory.entries),\n ...tag(\"store\", store.entries),\n ],\n // Store domains first (server-curated), then the on-disk feeds; dedupe by\n // slug, first-wins, so a store-served domain shadows a same-slug local one.\n domains: dedupeBySlug([...store.domains, ...src.domains, ...libs.domains, ...factory.domains]),\n notes: [...libs.notes, ...store.notes, ...factory.notes],\n };\n}\n\n/** First-wins dedupe of a domain list by `slug`. */\nfunction dedupeBySlug(domains: CatalogDomain[]): CatalogDomain[] {\n const seen = new Set<string>();\n const out: CatalogDomain[] = [];\n for (const d of domains) {\n if (seen.has(d.slug)) continue;\n seen.add(d.slug);\n out.push(d);\n }\n return out;\n}\n"]}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
export { WORKSPACE_MOUNT_ENV_VAR, deployAll, deployCatalogEntry, findAiAssetsRoot, isUnderWorkspaceMount, resolveFlowSkills, undeployCatalogEntry, workspaceMountDirs } from '../chunk-7BUZQVRR.js';
|
|
2
|
-
import '../chunk-
|
|
2
|
+
import '../chunk-3VSRJE3M.js';
|
|
3
|
+
import '../chunk-REILIKVM.js';
|
|
3
4
|
import '../chunk-F3HNW354.js';
|
|
4
5
|
import '../chunk-K5GBV4SA.js';
|
|
5
6
|
import '../chunk-QVZA2MDT.js';
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-MBARHWMZ.js';
|
|
7
|
+
import '../chunk-K27T47OO.js';
|
|
8
8
|
import '../chunk-MENCWIHW.js';
|
|
9
9
|
import '../chunk-P4VHQA4N.js';
|
|
10
10
|
import '../chunk-MKZOK4JU.js';
|
|
11
11
|
import '../chunk-GEEW6SY2.js';
|
|
12
12
|
import '../chunk-FTG7CRFD.js';
|
|
13
|
+
import '../chunk-KSIRR5PL.js';
|
|
14
|
+
import '../chunk-ILG4BXYE.js';
|
|
13
15
|
import '../chunk-W4IPN3DD.js';
|
|
14
16
|
import '../chunk-NSBPE2FW.js';
|
|
15
17
|
//# sourceMappingURL=catalog-deployer.js.map
|