@skaile/workspaces 5.16.0 → 5.17.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.
Files changed (162) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-BELBSJEE.js → asset-feeds-MALYFZUM.js} +4 -4
  4. package/dist/{asset-feeds-BELBSJEE.js.map → asset-feeds-MALYFZUM.js.map} +1 -1
  5. package/dist/asset-manager/index.js +1 -1
  6. package/dist/bridge/drivers/claude-sdk.js +279 -96
  7. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  8. package/dist/bridge/drivers/codex.js +4 -4
  9. package/dist/bridge/drivers/continue.js +4 -4
  10. package/dist/bridge/drivers/echo.js +4 -4
  11. package/dist/bridge/drivers/gemini.js +6 -6
  12. package/dist/bridge/drivers/goose.js +4 -4
  13. package/dist/bridge/drivers/omp.js +6 -6
  14. package/dist/bridge/drivers/opencode.js +4 -4
  15. package/dist/bridge/drivers/qwen.js +6 -6
  16. package/dist/bridge/index.js +8 -8
  17. package/dist/bridge/src/drivers/claude-sdk.d.ts +74 -20
  18. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  19. package/dist/bridge/src/drivers/claude-self-turns.d.ts +25 -6
  20. package/dist/bridge/src/drivers/claude-self-turns.d.ts.map +1 -1
  21. package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts +10 -0
  22. package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts.map +1 -1
  23. package/dist/bridge/src/drivers/scrub-transcript.d.ts +20 -0
  24. package/dist/bridge/src/drivers/scrub-transcript.d.ts.map +1 -1
  25. package/dist/{chunk-NSNM2ZXF.js → chunk-3OYOBTY4.js} +44 -4
  26. package/dist/chunk-3OYOBTY4.js.map +1 -0
  27. package/dist/{chunk-6RTEUWXX.js → chunk-5SWED2LW.js} +3 -3
  28. package/dist/{chunk-6RTEUWXX.js.map → chunk-5SWED2LW.js.map} +1 -1
  29. package/dist/{chunk-PW3TYWOI.js → chunk-AJ7EGIFR.js} +3 -3
  30. package/dist/{chunk-PW3TYWOI.js.map → chunk-AJ7EGIFR.js.map} +1 -1
  31. package/dist/{chunk-E634MBP6.js → chunk-BBRMS4IC.js} +3 -3
  32. package/dist/{chunk-E634MBP6.js.map → chunk-BBRMS4IC.js.map} +1 -1
  33. package/dist/{chunk-SMUIYYCH.js → chunk-BVXXBZWA.js} +7 -7
  34. package/dist/{chunk-SMUIYYCH.js.map → chunk-BVXXBZWA.js.map} +1 -1
  35. package/dist/{chunk-ISSYT5AZ.js → chunk-CWAWYXD5.js} +3 -3
  36. package/dist/{chunk-ISSYT5AZ.js.map → chunk-CWAWYXD5.js.map} +1 -1
  37. package/dist/{chunk-OHNNCXMB.js → chunk-DR5ZOEYI.js} +7 -7
  38. package/dist/{chunk-OHNNCXMB.js.map → chunk-DR5ZOEYI.js.map} +1 -1
  39. package/dist/{chunk-YIDZJHY6.js → chunk-EFLKSMCO.js} +3 -3
  40. package/dist/{chunk-YIDZJHY6.js.map → chunk-EFLKSMCO.js.map} +1 -1
  41. package/dist/{chunk-CQFVKN6S.js → chunk-EOKWTN4N.js} +207 -66
  42. package/dist/chunk-EOKWTN4N.js.map +1 -0
  43. package/dist/{chunk-Y25V2MW2.js → chunk-EYDRONKO.js} +3 -3
  44. package/dist/{chunk-Y25V2MW2.js.map → chunk-EYDRONKO.js.map} +1 -1
  45. package/dist/{chunk-DQOAPR4M.js → chunk-FACRITOL.js} +2 -2
  46. package/dist/{chunk-DQOAPR4M.js.map → chunk-FACRITOL.js.map} +1 -1
  47. package/dist/{chunk-TXGVG7VH.js → chunk-GYZJKZPJ.js} +3 -3
  48. package/dist/{chunk-TXGVG7VH.js.map → chunk-GYZJKZPJ.js.map} +1 -1
  49. package/dist/{chunk-TADJCATD.js → chunk-HLETG3CX.js} +3 -3
  50. package/dist/{chunk-TADJCATD.js.map → chunk-HLETG3CX.js.map} +1 -1
  51. package/dist/{chunk-FWAJUWXQ.js → chunk-KZWZRNIY.js} +4 -4
  52. package/dist/{chunk-FWAJUWXQ.js.map → chunk-KZWZRNIY.js.map} +1 -1
  53. package/dist/{chunk-X5O56UO4.js → chunk-L2AMXONH.js} +3 -3
  54. package/dist/chunk-L2AMXONH.js.map +1 -0
  55. package/dist/{chunk-6Q7NKTDG.js → chunk-LQT2IKYY.js} +2 -2
  56. package/dist/{chunk-6Q7NKTDG.js.map → chunk-LQT2IKYY.js.map} +1 -1
  57. package/dist/{chunk-A7AZ3RL5.js → chunk-MMARPEV7.js} +4 -4
  58. package/dist/{chunk-A7AZ3RL5.js.map → chunk-MMARPEV7.js.map} +1 -1
  59. package/dist/{chunk-J4RRH2NP.js → chunk-OQN7PCI4.js} +3 -3
  60. package/dist/{chunk-J4RRH2NP.js.map → chunk-OQN7PCI4.js.map} +1 -1
  61. package/dist/{chunk-5CE6J4DB.js → chunk-OXUCYHL5.js} +5 -5
  62. package/dist/{chunk-5CE6J4DB.js.map → chunk-OXUCYHL5.js.map} +1 -1
  63. package/dist/{chunk-A26MUUN7.js → chunk-QBY74UBH.js} +7 -7
  64. package/dist/{chunk-A26MUUN7.js.map → chunk-QBY74UBH.js.map} +1 -1
  65. package/dist/{chunk-VJ2DZLDM.js → chunk-QEX75L77.js} +3 -3
  66. package/dist/{chunk-VJ2DZLDM.js.map → chunk-QEX75L77.js.map} +1 -1
  67. package/dist/{chunk-HG52NGAV.js → chunk-QSLXB44M.js} +3 -3
  68. package/dist/{chunk-HG52NGAV.js.map → chunk-QSLXB44M.js.map} +1 -1
  69. package/dist/{chunk-TKI7YDWE.js → chunk-QW534EZB.js} +6 -6
  70. package/dist/{chunk-TKI7YDWE.js.map → chunk-QW534EZB.js.map} +1 -1
  71. package/dist/{chunk-XGR7IDTY.js → chunk-QXA2W6UB.js} +3 -3
  72. package/dist/{chunk-XGR7IDTY.js.map → chunk-QXA2W6UB.js.map} +1 -1
  73. package/dist/{chunk-OJHPG6HK.js → chunk-V5CDPKDA.js} +7 -7
  74. package/dist/{chunk-OJHPG6HK.js.map → chunk-V5CDPKDA.js.map} +1 -1
  75. package/dist/{chunk-DADAZLFW.js → chunk-W44KA24A.js} +2 -2
  76. package/dist/{chunk-DADAZLFW.js.map → chunk-W44KA24A.js.map} +1 -1
  77. package/dist/{chunk-SAGBVBY2.js → chunk-WY22FMZF.js} +4 -4
  78. package/dist/{chunk-SAGBVBY2.js.map → chunk-WY22FMZF.js.map} +1 -1
  79. package/dist/{chunk-D5WTOVLG.js → chunk-Y56YIT6J.js} +2 -2
  80. package/dist/chunk-Y56YIT6J.js.map +1 -0
  81. package/dist/{chunk-ZIW34FGO.js → chunk-YIF2IJUA.js} +3 -3
  82. package/dist/{chunk-ZIW34FGO.js.map → chunk-YIF2IJUA.js.map} +1 -1
  83. package/dist/{chunk-RTNWU2UD.js → chunk-ZPCABSSW.js} +3 -3
  84. package/dist/{chunk-RTNWU2UD.js.map → chunk-ZPCABSSW.js.map} +1 -1
  85. package/dist/{chunk-72KZJE3G.js → chunk-ZWUJ22RF.js} +4 -4
  86. package/dist/{chunk-72KZJE3G.js.map → chunk-ZWUJ22RF.js.map} +1 -1
  87. package/dist/cli/index.js +47 -47
  88. package/dist/connectors/index.js +10 -10
  89. package/dist/{connectors-44RE2QEM.js → connectors-CIEIMJY2.js} +13 -13
  90. package/dist/{connectors-44RE2QEM.js.map → connectors-CIEIMJY2.js.map} +1 -1
  91. package/dist/connectors-shared/index.js +2 -2
  92. package/dist/{ensure-sources-R6AHZ7RV.js → ensure-sources-I62QMZZP.js} +4 -4
  93. package/dist/{ensure-sources-R6AHZ7RV.js.map → ensure-sources-I62QMZZP.js.map} +1 -1
  94. package/dist/factory-assets/connectors/box.js +10 -10
  95. package/dist/factory-assets/connectors/deploy.js +10 -10
  96. package/dist/factory-assets/connectors/devserver.js +10 -10
  97. package/dist/factory-assets/connectors/flow/adapter.js +10 -10
  98. package/dist/factory-assets/connectors/flow/run-flow.js +11 -11
  99. package/dist/factory-assets/connectors/flow.js +10 -10
  100. package/dist/factory-assets/connectors/git.js +10 -10
  101. package/dist/factory-assets/connectors/gmail.js +10 -10
  102. package/dist/factory-assets/connectors/googledrive.js +10 -10
  103. package/dist/factory-assets/connectors/local.js +10 -10
  104. package/dist/factory-assets/connectors/mattermost.js +10 -10
  105. package/dist/factory-assets/connectors/memory.js +10 -10
  106. package/dist/factory-assets/connectors/minio.js +10 -10
  107. package/dist/factory-assets/connectors/postgres.js +10 -10
  108. package/dist/factory-assets/connectors/s3.js +10 -10
  109. package/dist/factory-assets/connectors/sharepoint.js +10 -10
  110. package/dist/factory-assets/connectors/sqlite.js +10 -10
  111. package/dist/factory-assets/connectors/static-server.js +10 -10
  112. package/dist/factory-assets/connectors/tunnel.js +10 -10
  113. package/dist/factory-assets/connectors/webdav.js +10 -10
  114. package/dist/factory-assets/connectors/xstate-store.js +10 -10
  115. package/dist/factory-assets/connectors/xstate.js +10 -10
  116. package/dist/{helpers-FNQL5PI7.js → helpers-3FOM37BO.js} +4 -4
  117. package/dist/{helpers-FNQL5PI7.js.map → helpers-3FOM37BO.js.map} +1 -1
  118. package/dist/{library-publish-GHPVY42Y.js → library-publish-EFKITCGE.js} +26 -26
  119. package/dist/{library-publish-GHPVY42Y.js.map → library-publish-EFKITCGE.js.map} +1 -1
  120. package/dist/model-endpoint/index.js +3 -3
  121. package/dist/{open-library-YSUGNP36.js → open-library-NZUI4XGF.js} +5 -5
  122. package/dist/{open-library-YSUGNP36.js.map → open-library-NZUI4XGF.js.map} +1 -1
  123. package/dist/{project-NDSLXERO.js → project-2BNFZ2CR.js} +22 -22
  124. package/dist/{project-NDSLXERO.js.map → project-2BNFZ2CR.js.map} +1 -1
  125. package/dist/runner/index.js +17 -17
  126. package/dist/runner/src/coalesced-restart.d.ts +41 -0
  127. package/dist/runner/src/coalesced-restart.d.ts.map +1 -0
  128. package/dist/runner/src/compaction/prompt.d.ts.map +1 -1
  129. package/dist/runner/src/mcp-runtime-handlers.d.ts +27 -0
  130. package/dist/runner/src/mcp-runtime-handlers.d.ts.map +1 -1
  131. package/dist/runner/src/runner-capabilities.d.ts +7 -0
  132. package/dist/runner/src/runner-capabilities.d.ts.map +1 -1
  133. package/dist/runner/src/serve.d.ts.map +1 -1
  134. package/dist/runner/src/session-capability-wiring.d.ts +2 -0
  135. package/dist/runner/src/session-capability-wiring.d.ts.map +1 -1
  136. package/dist/sdk/asset-manager.js +1 -1
  137. package/dist/sdk/bridge.js +8 -8
  138. package/dist/sdk/index.js +17 -17
  139. package/dist/sdk/runner.js +17 -17
  140. package/dist/sdk/session.js +2 -2
  141. package/dist/sdk/types.js +1 -1
  142. package/dist/{serve-preflight-ON2LS3SD.js → serve-preflight-V5GM33T3.js} +2 -2
  143. package/dist/{serve-preflight-ON2LS3SD.js.map → serve-preflight-V5GM33T3.js.map} +1 -1
  144. package/dist/session/index.js +2 -2
  145. package/dist/{setup-MFPEQS2I.js → setup-ZMAPTKJW.js} +13 -13
  146. package/dist/{setup-MFPEQS2I.js.map → setup-ZMAPTKJW.js.map} +1 -1
  147. package/dist/{source-4QVRD5NV.js → source-6BZA34F5.js} +24 -24
  148. package/dist/{source-4QVRD5NV.js.map → source-6BZA34F5.js.map} +1 -1
  149. package/dist/{source-manifest-publish-ZIO24GUM.js → source-manifest-publish-MJXCSUKT.js} +26 -26
  150. package/dist/{source-manifest-publish-ZIO24GUM.js.map → source-manifest-publish-MJXCSUKT.js.map} +1 -1
  151. package/dist/tui/index.js +17 -17
  152. package/dist/types/index.js +1 -1
  153. package/dist/types/src/events.d.ts +7 -4
  154. package/dist/types/src/events.d.ts.map +1 -1
  155. package/dist/workspace-plugin/adapters/mcp.js +12 -12
  156. package/dist/workspace-plugin/adapters/omp.js +7 -7
  157. package/dist/workspace-plugin/index.js +1 -1
  158. package/package.json +1 -1
  159. package/dist/chunk-CQFVKN6S.js.map +0 -1
  160. package/dist/chunk-D5WTOVLG.js.map +0 -1
  161. package/dist/chunk-NSNM2ZXF.js.map +0 -1
  162. package/dist/chunk-X5O56UO4.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { getAccessToken, loadStoreAuthConfig, hasStoredAuth } from './chunk-5CE6J4DB.js';
1
+ import { getAccessToken, loadStoreAuthConfig, hasStoredAuth } from './chunk-OXUCYHL5.js';
2
2
  import { globalSettingsPath, mapLegacyFields } from './chunk-PIC23DDE.js';
3
3
  import { existsSync, readFileSync } from 'fs';
4
4
 
@@ -60,5 +60,5 @@ function isStoreAuthenticated() {
60
60
  }
61
61
 
62
62
  export { getStoreConfig, getStoreToken, isStoreAuthenticated, storeFetch };
63
- //# sourceMappingURL=chunk-Y25V2MW2.js.map
64
- //# sourceMappingURL=chunk-Y25V2MW2.js.map
63
+ //# sourceMappingURL=chunk-EYDRONKO.js.map
64
+ //# sourceMappingURL=chunk-EYDRONKO.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":";;;;AAuBO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,eAAe,kBAAA,EAAmB;AACxC,EAAA,IAAI,WAAgC,EAAC;AACrC,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,gBAAgB,IAAA,CAAK,KAAA,CAAM,aAAa,YAAA,EAAc,OAAO,CAAC,CAAC,CAAA;AAAA,IAC5E,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,GAAW,EAAC;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,QAAA,CAAS,QAAA,IAAY,OAAA,CAAQ,IAAI,gBAAA,IAAoB,0BAAA;AAAA,IAC1D,GAAA,EAAK;AAAA,GACP;AACF;AAOO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,OAAO,cAAA,CAAe,mBAAA,EAAoB,EAAG,IAAI,CAAA;AACnD;AAaA,eAAsB,UAAA,CACpB,MAAA,EACA,IAAA,EACA,IAAA,EAOY;AACZ,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,GAAG,GAAG,IAAI,CAAA,CAAA;AAC9B,EAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,CAAgB,IAAA,CAAK,MAAM,CAAA;AAC1C,IAAA,GAAA,IAAO,IAAI,EAAE,CAAA,CAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAkC;AAAA,IACtC,cAAA,EAAgB,kBAAA;AAAA,IAChB,MAAA,EAAQ,kBAAA;AAAA,IACR,GAAI,IAAA,EAAM,OAAA,IAAW;AAAC,GACxB;AACA,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,MAAA,CAAO,GAAG,CAAA,CAAA;AAAA,EAC9C;AAEA,EAAA,MAAM,SAAA,GAAyB;AAAA,IAC7B,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,SAAA,CAAU,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,OAAA,GAAU,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,IAAA,EAAM,aAAa,IAAK,CAAA;AAC7E,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,SAAA,EAAW,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,IAAG,CAAE,CAAA;AAI3E,MAAA,MAAM,CAAA,GAAI,IAAA;AACV,MAAA,MAAM,IAAI,MAAM,CAAA,CAAE,OAAA,IAAW,EAAE,KAAA,IAAS,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO,IAAI,IAAA,EAAK;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,OAAO,CAAA;AAAA,EACtB;AACF;AASO,SAAS,oBAAA,GAAgC;AAC9C,EAAA,OAAO,aAAA,CAAc,qBAAqB,CAAA;AAC5C","file":"chunk-Y25V2MW2.js","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\nimport { type AuthDeps, getAccessToken, hasStoredAuth, loadStoreAuthConfig } from \"./store-auth.ts\";\n\n/**\n * Connection configuration for the AI Asset Store API. `jwt` is normally left\n * null here and filled per-call by the caller from {@link getStoreToken} (the\n * device-flow session); it stays on the type for the `{ ...config, jwt }` spread.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n}\n\n/**\n * Read the store API base URL (settings `storeUrl` → `SKAILE_STORE_URL` →\n * default). Auth is not read here — it lives in the device-flow session; see\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://api.skaile.store\",\n jwt: null,\n };\n}\n\n/**\n * Return a valid store access token (Keycloak device-flow session, refreshed if\n * needed). Throws a \"run `skaile store login`\" error when there is no session.\n * This is the auth source for every `/api/v1/*` publisher call.\n */\nexport function getStoreToken(deps?: AuthDeps): Promise<string> {\n return getAccessToken(loadStoreAuthConfig(), deps);\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, extra headers, and\n * `timeoutMs` (default 1500). Publisher calls pass a longer timeout because\n * they trigger server-side clone/sync work.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n // Prefer the store's human-readable `message` (e.g. \"Namespace '@x' is\n // reserved … Sign in with GitHub to claim it\") over the bare `error` code\n // (`UNPROCESSABLE_CONTENT`) — the message is the actionable part.\n const b = body as { message?: string; error?: string };\n throw new Error(b.message ?? b.error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` when a store session exists (a Keycloak device-flow token cached\n * at `~/.skaile/auth.json`). Validity/refresh is resolved on use via\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(): boolean {\n return hasStoredAuth(loadStoreAuthConfig());\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":";;;;AAuBO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,eAAe,kBAAA,EAAmB;AACxC,EAAA,IAAI,WAAgC,EAAC;AACrC,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,gBAAgB,IAAA,CAAK,KAAA,CAAM,aAAa,YAAA,EAAc,OAAO,CAAC,CAAC,CAAA;AAAA,IAC5E,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,GAAW,EAAC;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,QAAA,CAAS,QAAA,IAAY,OAAA,CAAQ,IAAI,gBAAA,IAAoB,0BAAA;AAAA,IAC1D,GAAA,EAAK;AAAA,GACP;AACF;AAOO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,OAAO,cAAA,CAAe,mBAAA,EAAoB,EAAG,IAAI,CAAA;AACnD;AAaA,eAAsB,UAAA,CACpB,MAAA,EACA,IAAA,EACA,IAAA,EAOY;AACZ,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,GAAG,GAAG,IAAI,CAAA,CAAA;AAC9B,EAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,CAAgB,IAAA,CAAK,MAAM,CAAA;AAC1C,IAAA,GAAA,IAAO,IAAI,EAAE,CAAA,CAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAkC;AAAA,IACtC,cAAA,EAAgB,kBAAA;AAAA,IAChB,MAAA,EAAQ,kBAAA;AAAA,IACR,GAAI,IAAA,EAAM,OAAA,IAAW;AAAC,GACxB;AACA,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,MAAA,CAAO,GAAG,CAAA,CAAA;AAAA,EAC9C;AAEA,EAAA,MAAM,SAAA,GAAyB;AAAA,IAC7B,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,SAAA,CAAU,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,OAAA,GAAU,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,IAAA,EAAM,aAAa,IAAK,CAAA;AAC7E,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,SAAA,EAAW,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,IAAG,CAAE,CAAA;AAI3E,MAAA,MAAM,CAAA,GAAI,IAAA;AACV,MAAA,MAAM,IAAI,MAAM,CAAA,CAAE,OAAA,IAAW,EAAE,KAAA,IAAS,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO,IAAI,IAAA,EAAK;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,OAAO,CAAA;AAAA,EACtB;AACF;AASO,SAAS,oBAAA,GAAgC;AAC9C,EAAA,OAAO,aAAA,CAAc,qBAAqB,CAAA;AAC5C","file":"chunk-EYDRONKO.js","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\nimport { type AuthDeps, getAccessToken, hasStoredAuth, loadStoreAuthConfig } from \"./store-auth.ts\";\n\n/**\n * Connection configuration for the AI Asset Store API. `jwt` is normally left\n * null here and filled per-call by the caller from {@link getStoreToken} (the\n * device-flow session); it stays on the type for the `{ ...config, jwt }` spread.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n}\n\n/**\n * Read the store API base URL (settings `storeUrl` → `SKAILE_STORE_URL` →\n * default). Auth is not read here — it lives in the device-flow session; see\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://api.skaile.store\",\n jwt: null,\n };\n}\n\n/**\n * Return a valid store access token (Keycloak device-flow session, refreshed if\n * needed). Throws a \"run `skaile store login`\" error when there is no session.\n * This is the auth source for every `/api/v1/*` publisher call.\n */\nexport function getStoreToken(deps?: AuthDeps): Promise<string> {\n return getAccessToken(loadStoreAuthConfig(), deps);\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, extra headers, and\n * `timeoutMs` (default 1500). Publisher calls pass a longer timeout because\n * they trigger server-side clone/sync work.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n // Prefer the store's human-readable `message` (e.g. \"Namespace '@x' is\n // reserved … Sign in with GitHub to claim it\") over the bare `error` code\n // (`UNPROCESSABLE_CONTENT`) — the message is the actionable part.\n const b = body as { message?: string; error?: string };\n throw new Error(b.message ?? b.error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` when a store session exists (a Keycloak device-flow token cached\n * at `~/.skaile/auth.json`). Validity/refresh is resolved on use via\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(): boolean {\n return hasStoredAuth(loadStoreAuthConfig());\n}\n"]}
@@ -301,5 +301,5 @@ function resolveProjectDir(additionalEnvVars) {
301
301
  }
302
302
 
303
303
  export { PluginStore, WorkspacePlugin, buildClaudePluginFiles, resolveProjectDir };
304
- //# sourceMappingURL=chunk-DQOAPR4M.js.map
305
- //# sourceMappingURL=chunk-DQOAPR4M.js.map
304
+ //# sourceMappingURL=chunk-FACRITOL.js.map
305
+ //# sourceMappingURL=chunk-FACRITOL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../workspace-plugin/src/adapters/claude-code.ts","../workspace-plugin/src/store.ts","../workspace-plugin/src/plugin.ts","../workspace-plugin/src/utils/project-dir.ts"],"names":["err"],"mappings":"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","file":"chunk-DQOAPR4M.js","sourcesContent":["// ── Claude Code plugin-directory generator (STATELESS) ──────────────────────\n// Generates the contents of a Claude Code plugin directory\n// (`.claude/plugins/skaile/`) as an in-memory file map. No plugin instance or\n// boot() is required — safe to call from install commands.\n//\n// The previous standalone `@skaile/workspace-plugin-claude` package shipped\n// these as static files plus loose `.mjs` hook scripts; they are now\n// CLI-owned templates. Hooks invoke the `skaile` binary directly\n// (`skaile integration hook <event>`) and MCP runs via `skaile mcp-server` — no\n// generated script files, no shebang, no runtime assumption.\n\n/**\n * The Claude Code plugin manifest. `name` is `skaile`; `hooks` and\n * `mcpServers` point at sibling files in the generated directory.\n */\nconst PLUGIN_JSON = {\n name: \"skaile\",\n version: \"0.1.0\",\n description: \"Skaile workspace — connectors, mounts, skills, flows, shared state\",\n author: { name: \"skaile-ai\", url: \"https://github.com/skaile-ai\" },\n repository: \"https://github.com/skaile-ai/workspaces\",\n keywords: [\"skaile\", \"connectors\", \"workspace\", \"ai-assets\"],\n hooks: \"./hooks/hooks.json\",\n mcpServers: \"./.mcp.json\",\n userConfig: {\n skaile_yaml_path: {\n type: \"string\",\n title: \"skaile.yaml path\",\n description: \"Override path to skaile.yaml (default: auto-detect from project root)\",\n },\n },\n};\n\n/**\n * Hook wiring. Each lifecycle event invokes the `skaile` binary directly —\n * no loose `.mjs` scripts. `skaile integration hook <event>` resolves the project\n * directory itself (`CLAUDE_PROJECT_DIR` / cwd) and always exits 0.\n */\nconst HOOKS_JSON = {\n hooks: {\n SessionStart: [\n { hooks: [{ type: \"command\", command: \"skaile integration hook session-start\" }] },\n ],\n SessionEnd: [{ hooks: [{ type: \"command\", command: \"skaile integration hook session-end\" }] }],\n UserPromptSubmit: [\n { hooks: [{ type: \"command\", command: \"skaile integration hook user-prompt-submit\" }] },\n ],\n },\n};\n\n/**\n * MCP server wiring. Spawns `skaile mcp-server` — a stdio MCP subprocess that\n * runs on plain Node (no Claude Agent SDK).\n */\nconst MCP_JSON = {\n mcpServers: {\n \"skaile-workspace\": {\n command: \"skaile\",\n args: [\"mcp-server\"],\n env: {},\n },\n },\n};\n\n/**\n * Build the Claude Code plugin directory as an in-memory file map.\n *\n * Returns `{ relativePath: contents }` for every file the installer must\n * write under `<projectDir>/.claude/plugins/skaile/`. The installer is also\n * responsible for populating `skills/` from the project's `.skaile/skills/`.\n *\n * Stateless — no plugin instance, no `boot()`. The generated artifacts carry\n * no project-specific paths: hooks and the MCP server resolve the project\n * directory themselves at runtime.\n *\n * @returns A map of plugin-relative file paths to their string contents.\n *\n * @docLink packages/workspace-plugin/concepts#adapters\n */\nexport function buildClaudePluginFiles(): Record<string, string> {\n return {\n \".claude-plugin/plugin.json\": `${JSON.stringify(PLUGIN_JSON, null, 2)}\\n`,\n \"hooks/hooks.json\": `${JSON.stringify(HOOKS_JSON, null, 2)}\\n`,\n \".mcp.json\": `${JSON.stringify(MCP_JSON, null, 2)}\\n`,\n \"skills/.gitkeep\": \"\",\n };\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\ninterface Subscriber {\n regex: RegExp;\n handler: (key: string, value: unknown) => void;\n}\n\n/**\n * Disk-backed reactive key-value store for plugin state.\n *\n * Keeps an in-memory map that can be flushed to / loaded from a JSON file.\n * Supports glob-style subscriptions (`connector:*`, `*`).\n *\n * State is persisted to `<projectDir>/.skaile/plugin-state.json`.\n * The instance is available on {@link WorkspacePlugin} as the public `store`\n * field after `boot()` resolves.\n *\n * @docLink packages/workspace-plugin/concepts#plugin-store\n */\nexport class PluginStore {\n private readonly statePath: string;\n private data: Map<string, unknown> = new Map();\n private subscribers: Subscriber[] = [];\n\n constructor(statePath: string) {\n this.statePath = statePath;\n }\n\n /** Synchronous read from in-memory map. */\n get<T>(key: string): T | undefined {\n return this.data.get(key) as T | undefined;\n }\n\n /** Write to in-memory map and notify matching subscribers. */\n set<T>(key: string, value: T): void {\n this.data.set(key, value);\n this.notify(key, value);\n }\n\n /** Remove key and notify matching subscribers. */\n delete(key: string): void {\n this.data.delete(key);\n this.notify(key, undefined);\n }\n\n /**\n * Subscribe to changes matching a glob-style pattern.\n * `*` matches any sequence of characters.\n * Returns an unsubscribe function.\n */\n subscribe(pattern: string, handler: (key: string, value: unknown) => void): () => void {\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regexStr = `^${escaped.replace(/\\*/g, \".*\")}$`;\n const sub: Subscriber = { regex: new RegExp(regexStr), handler };\n this.subscribers.push(sub);\n\n return () => {\n const idx = this.subscribers.indexOf(sub);\n if (idx !== -1) this.subscribers.splice(idx, 1);\n };\n }\n\n /** Rehydrate from disk JSON. Missing file = empty store (no throw). */\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.statePath, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n this.data = new Map(Object.entries(parsed));\n }\n } catch (e: unknown) {\n // Missing file or invalid JSON — start with empty store\n }\n }\n\n /** Write entire store to disk as JSON. Creates parent dirs if needed. */\n async flush(): Promise<void> {\n const obj = Object.fromEntries(this.data);\n const json = JSON.stringify(obj, null, 2);\n await mkdir(dirname(this.statePath), { recursive: true });\n await writeFile(this.statePath, json, \"utf-8\");\n }\n\n private notify(key: string, value: unknown): void {\n for (const sub of this.subscribers) {\n if (sub.regex.test(key)) {\n sub.handler(key, value);\n }\n }\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ConnectorManager } from \"@skaile/workspaces/connectors\";\nimport { DEFAULT_DRIVER_ID } from \"@skaile/workspaces/core/framework\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type { Logger } from \"@skaile/workspaces/types\";\nimport { PluginStore } from \"./store.js\";\n\n/**\n * Construction options for {@link WorkspacePlugin}.\n *\n * At minimum `projectDir` must be supplied. All other fields are optional\n * and are pre-resolved by the caller when available (e.g. the runner already\n * knows `driver`/`model` from its own settings resolution).\n *\n * @docLink packages/workspace-plugin/concepts#workspaceplugin-lifecycle\n */\nexport interface WorkspacePluginOpts {\n projectDir: string;\n /**\n * Active connector manager. The unified `ConnectorManager` owns both\n * filesystem-face (mountable) and tool-face connectors.\n */\n connectorManager?: ConnectorManager;\n bootOwned?: boolean;\n onLog?: (msg: string) => void;\n /** Pre-resolved driver type (avoids needing boot() to read settings). */\n driver?: string;\n /** Pre-resolved model. */\n model?: string;\n}\n\n/**\n * Shared runtime core for the skaile workspace plugin.\n *\n * Manages the full lifecycle (`boot` → tools available → `shutdown`) and\n * surfaces workspace capabilities — mounts, connectors, flows, skills,\n * sessions, and config validation — through two adapters:\n *\n * - **MCP, in-process** (runner): call {@link buildWorkspaceMcpServer} for the\n * Claude Agent SDK server the runner embeds into its `query()` call.\n * - **MCP, stdio** (`skaile mcp-server`): call {@link runMcpServerStdio} for a\n * raw `@modelcontextprotocol/sdk` server — no Claude Agent SDK.\n * - **OMP**: call {@link buildOmpToolSet} for the 13-tool native subset and\n * {@link buildOmpExtensionSource} for the generated extension file.\n *\n * Two boot modes are supported via {@link WorkspacePluginOpts.bootOwned}:\n * - `bootOwned: false` (default) — managers injected externally by the runner.\n * - `bootOwned: true` — plugin owns the full manager lifecycle (standalone MCP\n * subprocess or OMP extension).\n *\n * @docLink packages/workspace-plugin/concepts#workspaceplugin-lifecycle\n */\nexport class WorkspacePlugin {\n readonly projectDir: string;\n connectorManager: ConnectorManager | null;\n readonly store: PluginStore;\n\n private readonly bootOwned: boolean;\n private readonly onLog: (msg: string) => void;\n private readonly log: Logger = createLogger({\n kind: \"mcp\",\n subkind: \"skaile-workspace\",\n });\n driver?: string;\n model?: string;\n\n constructor(opts: WorkspacePluginOpts) {\n this.projectDir = opts.projectDir;\n this.connectorManager = opts.connectorManager ?? null;\n this.store = new PluginStore(join(opts.projectDir, \".skaile\", \"plugin-state.json\"));\n this.bootOwned = opts.bootOwned ?? false;\n if (opts.driver) this.driver = opts.driver;\n if (opts.model) this.model = opts.model;\n this.onLog = opts.onLog ?? (() => {});\n this.log.debug(\"plugin constructed\", {\n driver: opts.driver,\n hasConnectors: !!opts.connectorManager,\n model: opts.model,\n bootOwned: this.bootOwned,\n });\n }\n\n async boot(): Promise<void> {\n if (!this.bootOwned) {\n // Managers were injected externally — resolve settings only (non-fatal)\n try {\n const { resolveSettings } = await import(\"@skaile/workspaces/core\");\n const settings = await resolveSettings(this.projectDir);\n this.driver = settings.driver ?? DEFAULT_DRIVER_ID;\n this.model = settings.model;\n } catch {\n /* non-fatal */\n }\n await this.store.load();\n return;\n }\n\n // bootOwned: we own the managers lifecycle\n try {\n const { resolveSettings } = await import(\"@skaile/workspaces/core\");\n const settings = await resolveSettings(this.projectDir);\n this.driver = settings.driver ?? DEFAULT_DRIVER_ID;\n this.model = settings.model;\n } catch {\n /* non-fatal */\n }\n\n try {\n const {\n ConnectorManager,\n loadConnectorDeclarations,\n registerBuiltinConnectors,\n createCliSecretProviderChain,\n } = await import(\"@skaile/workspaces/connectors\");\n\n registerBuiltinConnectors();\n\n const secrets = createCliSecretProviderChain();\n\n const connectorDecls = await loadConnectorDeclarations(this.projectDir);\n const cm = new ConnectorManager(this.projectDir, { secrets });\n await cm.connectAll(connectorDecls);\n this.connectorManager = cm;\n\n this.log.info(\"workspace plugin booted\", {\n connectors: connectorDecls.length,\n });\n this.onLog(`WorkspacePlugin booted: ${connectorDecls.length} connectors`);\n } catch (err) {\n this.log.warn(\"workspace plugin boot warning\", {\n error: err instanceof Error ? err.message : String(err),\n });\n this.onLog(`WorkspacePlugin boot warning: ${err}`);\n }\n\n await this.store.load();\n }\n\n async reload(): Promise<void> {\n if (!this.bootOwned) return;\n await this.shutdown();\n await this.boot();\n }\n\n async shutdown(): Promise<void> {\n this.log.info(\"workspace plugin shutdown\");\n await this.store.flush();\n if (!this.bootOwned) return;\n try {\n await (this.connectorManager as any)?.disconnectAll?.();\n } catch {\n /* best-effort */\n }\n this.connectorManager = null;\n }\n\n buildSystemPromptSection(driver?: string): string {\n const d = driver ?? this.driver ?? \"unknown\";\n // The unified ConnectorManager owns both mountable (filesystem-face) and\n // tool-face connectors. Filesystem-face connectors expose a `mountPath`.\n const all = (this.connectorManager as any)?.listConnectors?.() ?? [];\n const mounts = (all as any[]).filter((c) => typeof c.mountPath === \"string\");\n const connectors = (all as any[]).filter((c) => typeof c.mountPath !== \"string\");\n const lines = [\"## Workspace (skaile)\", \"\", `Driver: ${d}`, `Project: ${this.projectDir}`];\n if (mounts.length > 0) {\n lines.push(\"\", \"Mounts:\");\n for (const v of mounts) {\n lines.push(` · ${v.id} (${v.driver}) → ${v.mountPath ?? \"(unmounted)\"}`);\n }\n }\n if (connectors.length > 0) {\n lines.push(\"\", \"Connectors:\");\n for (const c of connectors) {\n lines.push(` · ${c.id} (${c.driver})`);\n }\n }\n lines.push(\"\", \"Use workspace_info for full details. Use workspace_validate to check health.\");\n\n for (const name of [\"SOUL.md\", \"RULES.md\"]) {\n const skaileOverride = join(this.projectDir, \".skaile\", name);\n const rootFile = join(this.projectDir, name);\n for (const candidate of [skaileOverride, rootFile]) {\n try {\n const content = readFileSync(candidate, \"utf-8\").trim();\n if (content) {\n lines.push(\"\", `## ${name.replace(\".md\", \"\")}`, \"\", content);\n break;\n }\n } catch {\n // file not found, try next\n }\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Build the in-process Claude Agent SDK MCP server (runner embedding).\n * Returns `null` when `@anthropic-ai/claude-agent-sdk` is unavailable.\n */\n async buildWorkspaceMcpServer(): Promise<unknown | null> {\n this.log.info(\"building workspace MCP server\");\n try {\n const { buildWorkspaceMcpServer } = await import(\"./adapters/mcp.js\");\n const server = await buildWorkspaceMcpServer(this);\n if (server) this.log.info(\"workspace MCP server ready\");\n else this.log.debug(\"workspace MCP server skipped (no tools)\");\n return server;\n } catch (err) {\n this.log.error(\"workspace MCP server build failed\", err);\n throw err;\n }\n }\n\n /**\n * Build the raw `@modelcontextprotocol/sdk` stdio MCP server — no Claude\n * Agent SDK. Used by the `skaile mcp-server` subprocess. The returned\n * server is not yet connected to a transport.\n */\n async buildWorkspaceMcpStdioServer(): Promise<unknown> {\n this.log.info(\"building workspace stdio MCP server\");\n const { buildWorkspaceMcpStdioServer } = await import(\"./adapters/mcp.js\");\n return buildWorkspaceMcpStdioServer(this);\n }\n\n /**\n * Build and run the stdio MCP server: builds the raw\n * `@modelcontextprotocol/sdk` server and connects a `StdioServerTransport`.\n * Used by the `skaile mcp-server` subprocess.\n */\n async runMcpServerStdio(): Promise<void> {\n this.log.info(\"starting workspace stdio MCP server\");\n const { runMcpServerStdio } = await import(\"./adapters/mcp.js\");\n await runMcpServerStdio(this);\n }\n\n async buildOmpToolSet(): Promise<unknown[]> {\n const { buildOmpToolSet } = await import(\"./adapters/omp.js\");\n return buildOmpToolSet(this);\n }\n\n async buildOmpExtensionSource(): Promise<string> {\n const { buildOmpExtensionSource } = await import(\"./adapters/omp.js\");\n return buildOmpExtensionSource(this.projectDir);\n }\n\n async handleSlashCommand(group: string, args: string[]): Promise<string> {\n const { handleSlashCommand } = await import(\"./adapters/omp.js\");\n return handleSlashCommand(this, group, args);\n }\n}\n","// utils/project-dir.ts\n// Centralised project-directory resolution used by all plugin entry points.\n\n/**\n * Resolve the skaile project directory from environment variables.\n *\n * Resolution order:\n * 1. `SKAILE_PROJECT_DIR` (always checked first)\n * 2. Any additional env var keys supplied by the caller (in order)\n * 3. `process.cwd()` as final fallback\n *\n * @param additionalEnvVars - Optional list of extra environment variable names\n * to check before falling back to `process.cwd()`.\n * @returns Absolute path to the resolved project directory.\n *\n * @example\n * // Claude Code — also checks CLAUDE_PROJECT_DIR\n * const projectDir = resolveProjectDir([\"CLAUDE_PROJECT_DIR\"]);\n *\n * // OMP / standalone — SKAILE_PROJECT_DIR or cwd only\n * const projectDir = resolveProjectDir();\n *\n * @docLink packages/workspace-plugin/concepts#workspaceplugin-lifecycle\n */\nexport function resolveProjectDir(additionalEnvVars?: string[]): string {\n if (process.env.SKAILE_PROJECT_DIR) return process.env.SKAILE_PROJECT_DIR;\n for (const key of additionalEnvVars ?? []) {\n const val = process.env[key];\n if (val) return val;\n }\n return process.cwd();\n}\n"]}
1
+ {"version":3,"sources":["../workspace-plugin/src/adapters/claude-code.ts","../workspace-plugin/src/store.ts","../workspace-plugin/src/plugin.ts","../workspace-plugin/src/utils/project-dir.ts"],"names":["err"],"mappings":"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","file":"chunk-FACRITOL.js","sourcesContent":["// ── Claude Code plugin-directory generator (STATELESS) ──────────────────────\n// Generates the contents of a Claude Code plugin directory\n// (`.claude/plugins/skaile/`) as an in-memory file map. No plugin instance or\n// boot() is required — safe to call from install commands.\n//\n// The previous standalone `@skaile/workspace-plugin-claude` package shipped\n// these as static files plus loose `.mjs` hook scripts; they are now\n// CLI-owned templates. Hooks invoke the `skaile` binary directly\n// (`skaile integration hook <event>`) and MCP runs via `skaile mcp-server` — no\n// generated script files, no shebang, no runtime assumption.\n\n/**\n * The Claude Code plugin manifest. `name` is `skaile`; `hooks` and\n * `mcpServers` point at sibling files in the generated directory.\n */\nconst PLUGIN_JSON = {\n name: \"skaile\",\n version: \"0.1.0\",\n description: \"Skaile workspace — connectors, mounts, skills, flows, shared state\",\n author: { name: \"skaile-ai\", url: \"https://github.com/skaile-ai\" },\n repository: \"https://github.com/skaile-ai/workspaces\",\n keywords: [\"skaile\", \"connectors\", \"workspace\", \"ai-assets\"],\n hooks: \"./hooks/hooks.json\",\n mcpServers: \"./.mcp.json\",\n userConfig: {\n skaile_yaml_path: {\n type: \"string\",\n title: \"skaile.yaml path\",\n description: \"Override path to skaile.yaml (default: auto-detect from project root)\",\n },\n },\n};\n\n/**\n * Hook wiring. Each lifecycle event invokes the `skaile` binary directly —\n * no loose `.mjs` scripts. `skaile integration hook <event>` resolves the project\n * directory itself (`CLAUDE_PROJECT_DIR` / cwd) and always exits 0.\n */\nconst HOOKS_JSON = {\n hooks: {\n SessionStart: [\n { hooks: [{ type: \"command\", command: \"skaile integration hook session-start\" }] },\n ],\n SessionEnd: [{ hooks: [{ type: \"command\", command: \"skaile integration hook session-end\" }] }],\n UserPromptSubmit: [\n { hooks: [{ type: \"command\", command: \"skaile integration hook user-prompt-submit\" }] },\n ],\n },\n};\n\n/**\n * MCP server wiring. Spawns `skaile mcp-server` — a stdio MCP subprocess that\n * runs on plain Node (no Claude Agent SDK).\n */\nconst MCP_JSON = {\n mcpServers: {\n \"skaile-workspace\": {\n command: \"skaile\",\n args: [\"mcp-server\"],\n env: {},\n },\n },\n};\n\n/**\n * Build the Claude Code plugin directory as an in-memory file map.\n *\n * Returns `{ relativePath: contents }` for every file the installer must\n * write under `<projectDir>/.claude/plugins/skaile/`. The installer is also\n * responsible for populating `skills/` from the project's `.skaile/skills/`.\n *\n * Stateless — no plugin instance, no `boot()`. The generated artifacts carry\n * no project-specific paths: hooks and the MCP server resolve the project\n * directory themselves at runtime.\n *\n * @returns A map of plugin-relative file paths to their string contents.\n *\n * @docLink packages/workspace-plugin/concepts#adapters\n */\nexport function buildClaudePluginFiles(): Record<string, string> {\n return {\n \".claude-plugin/plugin.json\": `${JSON.stringify(PLUGIN_JSON, null, 2)}\\n`,\n \"hooks/hooks.json\": `${JSON.stringify(HOOKS_JSON, null, 2)}\\n`,\n \".mcp.json\": `${JSON.stringify(MCP_JSON, null, 2)}\\n`,\n \"skills/.gitkeep\": \"\",\n };\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\ninterface Subscriber {\n regex: RegExp;\n handler: (key: string, value: unknown) => void;\n}\n\n/**\n * Disk-backed reactive key-value store for plugin state.\n *\n * Keeps an in-memory map that can be flushed to / loaded from a JSON file.\n * Supports glob-style subscriptions (`connector:*`, `*`).\n *\n * State is persisted to `<projectDir>/.skaile/plugin-state.json`.\n * The instance is available on {@link WorkspacePlugin} as the public `store`\n * field after `boot()` resolves.\n *\n * @docLink packages/workspace-plugin/concepts#plugin-store\n */\nexport class PluginStore {\n private readonly statePath: string;\n private data: Map<string, unknown> = new Map();\n private subscribers: Subscriber[] = [];\n\n constructor(statePath: string) {\n this.statePath = statePath;\n }\n\n /** Synchronous read from in-memory map. */\n get<T>(key: string): T | undefined {\n return this.data.get(key) as T | undefined;\n }\n\n /** Write to in-memory map and notify matching subscribers. */\n set<T>(key: string, value: T): void {\n this.data.set(key, value);\n this.notify(key, value);\n }\n\n /** Remove key and notify matching subscribers. */\n delete(key: string): void {\n this.data.delete(key);\n this.notify(key, undefined);\n }\n\n /**\n * Subscribe to changes matching a glob-style pattern.\n * `*` matches any sequence of characters.\n * Returns an unsubscribe function.\n */\n subscribe(pattern: string, handler: (key: string, value: unknown) => void): () => void {\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regexStr = `^${escaped.replace(/\\*/g, \".*\")}$`;\n const sub: Subscriber = { regex: new RegExp(regexStr), handler };\n this.subscribers.push(sub);\n\n return () => {\n const idx = this.subscribers.indexOf(sub);\n if (idx !== -1) this.subscribers.splice(idx, 1);\n };\n }\n\n /** Rehydrate from disk JSON. Missing file = empty store (no throw). */\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.statePath, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n this.data = new Map(Object.entries(parsed));\n }\n } catch (e: unknown) {\n // Missing file or invalid JSON — start with empty store\n }\n }\n\n /** Write entire store to disk as JSON. Creates parent dirs if needed. */\n async flush(): Promise<void> {\n const obj = Object.fromEntries(this.data);\n const json = JSON.stringify(obj, null, 2);\n await mkdir(dirname(this.statePath), { recursive: true });\n await writeFile(this.statePath, json, \"utf-8\");\n }\n\n private notify(key: string, value: unknown): void {\n for (const sub of this.subscribers) {\n if (sub.regex.test(key)) {\n sub.handler(key, value);\n }\n }\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ConnectorManager } from \"@skaile/workspaces/connectors\";\nimport { DEFAULT_DRIVER_ID } from \"@skaile/workspaces/core/framework\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type { Logger } from \"@skaile/workspaces/types\";\nimport { PluginStore } from \"./store.js\";\n\n/**\n * Construction options for {@link WorkspacePlugin}.\n *\n * At minimum `projectDir` must be supplied. All other fields are optional\n * and are pre-resolved by the caller when available (e.g. the runner already\n * knows `driver`/`model` from its own settings resolution).\n *\n * @docLink packages/workspace-plugin/concepts#workspaceplugin-lifecycle\n */\nexport interface WorkspacePluginOpts {\n projectDir: string;\n /**\n * Active connector manager. The unified `ConnectorManager` owns both\n * filesystem-face (mountable) and tool-face connectors.\n */\n connectorManager?: ConnectorManager;\n bootOwned?: boolean;\n onLog?: (msg: string) => void;\n /** Pre-resolved driver type (avoids needing boot() to read settings). */\n driver?: string;\n /** Pre-resolved model. */\n model?: string;\n}\n\n/**\n * Shared runtime core for the skaile workspace plugin.\n *\n * Manages the full lifecycle (`boot` → tools available → `shutdown`) and\n * surfaces workspace capabilities — mounts, connectors, flows, skills,\n * sessions, and config validation — through two adapters:\n *\n * - **MCP, in-process** (runner): call {@link buildWorkspaceMcpServer} for the\n * Claude Agent SDK server the runner embeds into its `query()` call.\n * - **MCP, stdio** (`skaile mcp-server`): call {@link runMcpServerStdio} for a\n * raw `@modelcontextprotocol/sdk` server — no Claude Agent SDK.\n * - **OMP**: call {@link buildOmpToolSet} for the 13-tool native subset and\n * {@link buildOmpExtensionSource} for the generated extension file.\n *\n * Two boot modes are supported via {@link WorkspacePluginOpts.bootOwned}:\n * - `bootOwned: false` (default) — managers injected externally by the runner.\n * - `bootOwned: true` — plugin owns the full manager lifecycle (standalone MCP\n * subprocess or OMP extension).\n *\n * @docLink packages/workspace-plugin/concepts#workspaceplugin-lifecycle\n */\nexport class WorkspacePlugin {\n readonly projectDir: string;\n connectorManager: ConnectorManager | null;\n readonly store: PluginStore;\n\n private readonly bootOwned: boolean;\n private readonly onLog: (msg: string) => void;\n private readonly log: Logger = createLogger({\n kind: \"mcp\",\n subkind: \"skaile-workspace\",\n });\n driver?: string;\n model?: string;\n\n constructor(opts: WorkspacePluginOpts) {\n this.projectDir = opts.projectDir;\n this.connectorManager = opts.connectorManager ?? null;\n this.store = new PluginStore(join(opts.projectDir, \".skaile\", \"plugin-state.json\"));\n this.bootOwned = opts.bootOwned ?? false;\n if (opts.driver) this.driver = opts.driver;\n if (opts.model) this.model = opts.model;\n this.onLog = opts.onLog ?? (() => {});\n this.log.debug(\"plugin constructed\", {\n driver: opts.driver,\n hasConnectors: !!opts.connectorManager,\n model: opts.model,\n bootOwned: this.bootOwned,\n });\n }\n\n async boot(): Promise<void> {\n if (!this.bootOwned) {\n // Managers were injected externally — resolve settings only (non-fatal)\n try {\n const { resolveSettings } = await import(\"@skaile/workspaces/core\");\n const settings = await resolveSettings(this.projectDir);\n this.driver = settings.driver ?? DEFAULT_DRIVER_ID;\n this.model = settings.model;\n } catch {\n /* non-fatal */\n }\n await this.store.load();\n return;\n }\n\n // bootOwned: we own the managers lifecycle\n try {\n const { resolveSettings } = await import(\"@skaile/workspaces/core\");\n const settings = await resolveSettings(this.projectDir);\n this.driver = settings.driver ?? DEFAULT_DRIVER_ID;\n this.model = settings.model;\n } catch {\n /* non-fatal */\n }\n\n try {\n const {\n ConnectorManager,\n loadConnectorDeclarations,\n registerBuiltinConnectors,\n createCliSecretProviderChain,\n } = await import(\"@skaile/workspaces/connectors\");\n\n registerBuiltinConnectors();\n\n const secrets = createCliSecretProviderChain();\n\n const connectorDecls = await loadConnectorDeclarations(this.projectDir);\n const cm = new ConnectorManager(this.projectDir, { secrets });\n await cm.connectAll(connectorDecls);\n this.connectorManager = cm;\n\n this.log.info(\"workspace plugin booted\", {\n connectors: connectorDecls.length,\n });\n this.onLog(`WorkspacePlugin booted: ${connectorDecls.length} connectors`);\n } catch (err) {\n this.log.warn(\"workspace plugin boot warning\", {\n error: err instanceof Error ? err.message : String(err),\n });\n this.onLog(`WorkspacePlugin boot warning: ${err}`);\n }\n\n await this.store.load();\n }\n\n async reload(): Promise<void> {\n if (!this.bootOwned) return;\n await this.shutdown();\n await this.boot();\n }\n\n async shutdown(): Promise<void> {\n this.log.info(\"workspace plugin shutdown\");\n await this.store.flush();\n if (!this.bootOwned) return;\n try {\n await (this.connectorManager as any)?.disconnectAll?.();\n } catch {\n /* best-effort */\n }\n this.connectorManager = null;\n }\n\n buildSystemPromptSection(driver?: string): string {\n const d = driver ?? this.driver ?? \"unknown\";\n // The unified ConnectorManager owns both mountable (filesystem-face) and\n // tool-face connectors. Filesystem-face connectors expose a `mountPath`.\n const all = (this.connectorManager as any)?.listConnectors?.() ?? [];\n const mounts = (all as any[]).filter((c) => typeof c.mountPath === \"string\");\n const connectors = (all as any[]).filter((c) => typeof c.mountPath !== \"string\");\n const lines = [\"## Workspace (skaile)\", \"\", `Driver: ${d}`, `Project: ${this.projectDir}`];\n if (mounts.length > 0) {\n lines.push(\"\", \"Mounts:\");\n for (const v of mounts) {\n lines.push(` · ${v.id} (${v.driver}) → ${v.mountPath ?? \"(unmounted)\"}`);\n }\n }\n if (connectors.length > 0) {\n lines.push(\"\", \"Connectors:\");\n for (const c of connectors) {\n lines.push(` · ${c.id} (${c.driver})`);\n }\n }\n lines.push(\"\", \"Use workspace_info for full details. Use workspace_validate to check health.\");\n\n for (const name of [\"SOUL.md\", \"RULES.md\"]) {\n const skaileOverride = join(this.projectDir, \".skaile\", name);\n const rootFile = join(this.projectDir, name);\n for (const candidate of [skaileOverride, rootFile]) {\n try {\n const content = readFileSync(candidate, \"utf-8\").trim();\n if (content) {\n lines.push(\"\", `## ${name.replace(\".md\", \"\")}`, \"\", content);\n break;\n }\n } catch {\n // file not found, try next\n }\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Build the in-process Claude Agent SDK MCP server (runner embedding).\n * Returns `null` when `@anthropic-ai/claude-agent-sdk` is unavailable.\n */\n async buildWorkspaceMcpServer(): Promise<unknown | null> {\n this.log.info(\"building workspace MCP server\");\n try {\n const { buildWorkspaceMcpServer } = await import(\"./adapters/mcp.js\");\n const server = await buildWorkspaceMcpServer(this);\n if (server) this.log.info(\"workspace MCP server ready\");\n else this.log.debug(\"workspace MCP server skipped (no tools)\");\n return server;\n } catch (err) {\n this.log.error(\"workspace MCP server build failed\", err);\n throw err;\n }\n }\n\n /**\n * Build the raw `@modelcontextprotocol/sdk` stdio MCP server — no Claude\n * Agent SDK. Used by the `skaile mcp-server` subprocess. The returned\n * server is not yet connected to a transport.\n */\n async buildWorkspaceMcpStdioServer(): Promise<unknown> {\n this.log.info(\"building workspace stdio MCP server\");\n const { buildWorkspaceMcpStdioServer } = await import(\"./adapters/mcp.js\");\n return buildWorkspaceMcpStdioServer(this);\n }\n\n /**\n * Build and run the stdio MCP server: builds the raw\n * `@modelcontextprotocol/sdk` server and connects a `StdioServerTransport`.\n * Used by the `skaile mcp-server` subprocess.\n */\n async runMcpServerStdio(): Promise<void> {\n this.log.info(\"starting workspace stdio MCP server\");\n const { runMcpServerStdio } = await import(\"./adapters/mcp.js\");\n await runMcpServerStdio(this);\n }\n\n async buildOmpToolSet(): Promise<unknown[]> {\n const { buildOmpToolSet } = await import(\"./adapters/omp.js\");\n return buildOmpToolSet(this);\n }\n\n async buildOmpExtensionSource(): Promise<string> {\n const { buildOmpExtensionSource } = await import(\"./adapters/omp.js\");\n return buildOmpExtensionSource(this.projectDir);\n }\n\n async handleSlashCommand(group: string, args: string[]): Promise<string> {\n const { handleSlashCommand } = await import(\"./adapters/omp.js\");\n return handleSlashCommand(this, group, args);\n }\n}\n","// utils/project-dir.ts\n// Centralised project-directory resolution used by all plugin entry points.\n\n/**\n * Resolve the skaile project directory from environment variables.\n *\n * Resolution order:\n * 1. `SKAILE_PROJECT_DIR` (always checked first)\n * 2. Any additional env var keys supplied by the caller (in order)\n * 3. `process.cwd()` as final fallback\n *\n * @param additionalEnvVars - Optional list of extra environment variable names\n * to check before falling back to `process.cwd()`.\n * @returns Absolute path to the resolved project directory.\n *\n * @example\n * // Claude Code — also checks CLAUDE_PROJECT_DIR\n * const projectDir = resolveProjectDir([\"CLAUDE_PROJECT_DIR\"]);\n *\n * // OMP / standalone — SKAILE_PROJECT_DIR or cwd only\n * const projectDir = resolveProjectDir();\n *\n * @docLink packages/workspace-plugin/concepts#workspaceplugin-lifecycle\n */\nexport function resolveProjectDir(additionalEnvVars?: string[]): string {\n if (process.env.SKAILE_PROJECT_DIR) return process.env.SKAILE_PROJECT_DIR;\n for (const key of additionalEnvVars ?? []) {\n const val = process.env[key];\n if (val) return val;\n }\n return process.cwd();\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { getProviderPreset, registryCredentialEnv, providerCredentialEnvName, BUILTIN_DRIVER_CATALOG } from './chunk-6Q7NKTDG.js';
1
+ import { getProviderPreset, registryCredentialEnv, providerCredentialEnvName, BUILTIN_DRIVER_CATALOG } from './chunk-LQT2IKYY.js';
2
2
  import { mergeRegistries, resolveEntryBaseUrl, normalizeEntryBaseUrl, registryEntries, isEntryEnabled, parseModelRef } from './chunk-MJHSLODD.js';
3
3
 
4
4
  // bridge/src/provider-materialize/env-drivers.ts
@@ -137,5 +137,5 @@ function continueRoleBinding(session) {
137
137
  }
138
138
 
139
139
  export { bindSingleProviderEntry, continueRoleBinding, credentialsForEveryProvider, entryBaseUrl, entryModelIds, entrySurface, harnessModelSelector, harnessProviderName, isStockCatalogEndpoint, registryModelEntries, resolveEnvDriverSession, resolveRegistryBinding, selectableEntries, versionedAnthropicBaseUrl };
140
- //# sourceMappingURL=chunk-TXGVG7VH.js.map
141
- //# sourceMappingURL=chunk-TXGVG7VH.js.map
140
+ //# sourceMappingURL=chunk-GYZJKZPJ.js.map
141
+ //# sourceMappingURL=chunk-GYZJKZPJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../bridge/src/provider-materialize/env-drivers.ts"],"names":[],"mappings":";;;;AAyEO,SAAS,uBAAA,CACd,MAAA,EACA,UAAA,GAAiD,OAAA,CAAQ,GAAA,EACvC;AAClB,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,MAAA,CAAO,QAAA,IAAY,eAAA,CAAgB,EAAE,CAAA;AAAA,IAC/C,WAAW,EAAE,GAAG,UAAA,EAAY,GAAG,OAAO,GAAA,EAAI;AAAA,IAC1C,GAAI,OAAO,QAAA,GAAW,EAAE,UAAU,MAAA,CAAO,QAAA,KAAa,EAAC;AAAA,IACvD,GAAI,OAAO,KAAA,GAAQ,EAAE,OAAO,MAAA,CAAO,KAAA,KAAU;AAAC,GAChD;AACF;AA2BO,SAAS,aAAa,KAAA,EAA0D;AACrF,EAAA,IAAI,KAAA,CAAM,OAAA,EAAS,OAAO,KAAA,CAAM,OAAA;AAChC,EAAA,OAAO,MAAM,MAAA,GAAS,iBAAA,CAAkB,KAAA,CAAM,MAAM,GAAG,OAAA,GAAU,MAAA;AACnE;AAcO,SAAS,aAAa,KAAA,EAA+C;AAC1E,EAAA,MAAM,QAAA,GACJ,mBAAA,CAAoB,KAAK,CAAA,KACxB,KAAA,CAAM,SAAS,iBAAA,CAAkB,KAAA,CAAM,MAAM,CAAA,EAAG,QAAA,GAAW,MAAA,CAAA;AAC9D,EAAA,OAAO,qBAAA,CAAsB,QAAA,EAAU,YAAA,CAAa,KAAK,CAAC,CAAA;AAC5D;AASO,SAAS,yBAAA,CACd,SACA,OAAA,EACQ;AACR,EAAA,IAAI,OAAA,KAAY,sBAAsB,OAAO,OAAA;AAE7C,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAO,CAAA;AAC3B,IAAA,GAAA,CAAI,WAAW,CAAA,EAAG,GAAA,CAAI,SAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,GAAA,CAAA;AAClD,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,GAAG,OAAO,CAAA,GAAA,CAAA;AAAA,EACnB;AACF;AAcO,SAAS,uBAAuB,KAAA,EAAoC;AACzE,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA,GAAS,iBAAA,CAAkB,KAAA,CAAM,MAAM,CAAA,GAAI,MAAA;AAChE,EAAA,IAAI,CAAC,QAAQ,OAAO,KAAA;AACpB,EAAA,OAAO,YAAA,CAAa,KAAK,CAAA,KAAM,qBAAA,CAAsB,OAAO,QAAA,EAAU,YAAA,CAAa,KAAK,CAAC,CAAA;AAC3F;AAaO,SAAS,mBAAA,CAAoB,YAAoB,KAAA,EAAmC;AACzF,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA,GAAS,iBAAA,CAAkB,KAAA,CAAM,MAAM,CAAA,GAAI,MAAA;AAChE,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,sBAAA,CAAuB,KAAK,GAAG,OAAO,UAAA;AACtD,EAAA,OAAO,MAAA,CAAO,EAAA;AAChB;AAQO,SAAS,kBACd,QAAA,EACqC;AACrC,EAAA,OAAO,eAAA,CAAgB,QAAQ,CAAA,CAAE,MAAA;AAAA,IAC/B,CAAC,IAAA,KAAA,CACE,IAAA,CAAK,CAAC,EAAE,IAAA,KAAS,KAAA,IAAS,IAAA,CAAK,CAAC,EAAE,IAAA,KAAS,OAAA,KAAY,cAAA,CAAe,IAAA,CAAK,CAAC,CAAC;AAAA,GAClF;AACF;AAOO,SAAS,cAAc,KAAA,EAAoD;AAChF,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,GAAG,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,SAAA,IAAa,EAAE,CAAA;AAAA,IACpC,GAAG,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,YAAA,IAAgB,EAAE,CAAA,CAAE,MAAA,CAAO,CAAC,OAAO,EAAE,EAAA,KAAO,KAAA,CAAM,SAAA,IAAa,EAAC,CAAA,CAAG;AAAA,GAC1F;AACA,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,CAAC,EAAA,KAAO,CAAC,EAAA,EAAI,KAAA,CAAM,SAAA,GAAY,EAAE,CAAA,IAAK,EAAE,CAAC,CAAA;AACjE;AAEA,SAAS,eAAA,CACP,UAAA,EACA,KAAA,EACA,OAAA,EACA,iBACA,QAAA,EACsB;AACtB,EAAA,MAAM,OAAA,GAAU,aAAa,KAAK,CAAA;AAClC,EAAA,MAAM,OAAA,GAAU,aAAa,KAAK,CAAA;AAClC,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAI,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAQ;AAAA,IAC3C,GAAI,eAAA,KAAoB,MAAA,GAAY,EAAC,GAAI,EAAE,eAAA,EAAgB;AAAA,IAC3D,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,IAC7B,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,IAC7B,iBAAA,EAAmB,mBAAA,CAAoB,UAAA,EAAY,KAAK,CAAA;AAAA,IACxD;AAAA,GACF;AACF;AAUO,SAAS,uBACd,OAAA,EACkC;AAClC,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,OAAA,CAAQ,QAAQ,CAAA;AAClD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAEjC,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,QAAA,EAAU,IAAA,EAAK;AACxC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,CAAC,UAAA,EAAY,KAAK,CAAA,GAAI,QAAQ,CAAC,CAAA;AACrC,IAAA,OAAO,gBAAgB,UAAA,EAAY,KAAA,EAAO,MAAA,EAAW,MAAA,EAAW,EAAE,CAAA;AAAA,EACpE;AAKA,EAAA,MAAM,KAAA,GAAQ,QAAQ,IAAA,CAAK,CAAC,CAAC,EAAE,CAAA,KAAM,OAAO,QAAQ,CAAA;AACpD,EAAA,IAAI,KAAA,EAAO,OAAO,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,MAAA,EAAW,MAAA,EAAW,EAAE,CAAA;AAE9E,EAAA,MAAM,WAAW,aAAA,CAAc,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,QAAQ,KAAK,CAAA;AACxE,EAAA,IAAI,CAAC,UAAU,OAAO,MAAA;AACtB,EAAA,MAAM,KAAA,GAAQ,QAAQ,IAAA,CAAK,CAAC,CAAC,EAAE,CAAA,KAAM,EAAA,KAAO,QAAA,CAAS,UAAU,CAAA;AAC/D,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,OAAO,eAAA;AAAA,IACL,MAAM,CAAC,CAAA;AAAA,IACP,MAAM,CAAC,CAAA;AAAA,IACP,QAAA,CAAS,OAAA;AAAA,IACT,QAAA,CAAS,eAAA;AAAA,IACT,QAAA,CAAS;AAAA,GACX;AACF;AAQO,SAAS,4BAA4B,OAAA,EAAmD;AAC7F,EAAA,OAAO,sBAAsB,OAAA,CAAQ,QAAA,EAAU,EAAE,GAAA,EAAK,OAAA,CAAQ,WAAW,CAAA;AAC3E;AASO,SAAS,yBAAA,CACd,QAAA,EACA,WAAA,EACA,OAAA,EACM;AACN,EAAA,MAAM,SAAA,GAAY,sBAAA,CAAuB,QAAQ,CAAA,EAAG,QAAA;AACpD,EAAA,IAAI,CAAC,SAAA,IAAa,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG;AAC1C,EAAA,MAAM,UAAU,OAAA,CAAQ,OAAA;AACxB,EAAA,IAAI,CAAC,OAAA,IAAW,SAAA,CAAU,QAAA,CAAS,OAAO,CAAA,EAAG;AAC7C,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAAA,EAAG,WAAW,CAAA,mBAAA,EAAsB,OAAO,mCACrC,OAAA,CAAQ,UAAU,CAAA,GAAA,EAAM,WAAW,YAAY,SAAA,CAAU,IAAA,CAAK,IAAI,CAAC,2GAEjC,OAAO,CAAA,EAAA;AAAA,GACjD;AACF;AAYO,SAAS,qBAAqB,OAAA,EAAyC;AAC5E,EAAA,MAAM,MAAoB,EAAC;AAC3B,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,CAAC,UAAA,EAAY,KAAK,KAAK,iBAAA,CAAkB,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACrE,IAAA,MAAM,SAAA,GAAY,mBAAA,CAAoB,UAAA,EAAY,KAAK,CAAA;AACvD,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,IAAS,UAAA;AAC7B,IAAA,KAAA,MAAW,CAAC,SAAA,EAAW,eAAe,CAAA,IAAK,aAAA,CAAc,KAAK,CAAA,EAAG;AAC/D,MAAA,MAAM,EAAA,GAAK,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,eAAe,CAAA,CAAA;AAC1C,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,EAAG;AAClB,MAAA,IAAA,CAAK,IAAI,EAAE,CAAA;AACX,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,GAAG,KAAK,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,CAAA;AAAA,IAChD;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAWO,SAAS,uBAAA,CACd,QAAA,EACA,WAAA,EACA,OAAA,EACkC;AAClC,EAAA,MAAM,OAAA,GAAU,uBAAuB,OAAO,CAAA;AAC9C,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,yBAAA,CAA0B,QAAA,EAAU,aAAa,OAAO,CAAA;AACxD,EAAA,OAAO,OAAA;AACT;AAOO,SAAS,qBAAqB,OAAA,EAAmD;AACtF,EAAA,IAAI,CAAC,OAAA,CAAQ,eAAA,EAAiB,OAAO,MAAA;AACrC,EAAA,OAAO,CAAA,EAAG,OAAA,CAAQ,iBAAiB,CAAA,CAAA,EAAI,QAAQ,eAAe,CAAA,CAAA;AAChE;AAgCO,SAAS,oBAAoB,OAAA,EAA4D;AAC9F,EAAA,MAAM,OAAA,GAAU,uBAAuB,OAAO,CAAA;AAC9C,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,YAAY,OAAA,CAAQ,UAAA;AAAA,IACpB,UAAU,OAAA,CAAQ,iBAAA;AAAA,IAClB,GAAI,QAAQ,eAAA,GAAkB,EAAE,OAAO,OAAA,CAAQ,eAAA,KAAoB,EAAC;AAAA,IACpE,GAAI,OAAA,CAAQ,OAAA,GACR,EAAE,OAAA,EAAS,yBAAA,CAA0B,OAAA,CAAQ,OAAA,EAAS,OAAA,CAAQ,OAAO,CAAA,EAAE,GACvE,EAAC;AAAA,IACL,SAAA,EAAW,yBAAA,CAA0B,OAAA,CAAQ,UAAU;AAAA,GACzD;AACF","file":"chunk-TXGVG7VH.js","sourcesContent":["/**\n * Registry adapter for the **env-shaped CLI drivers** — Gemini, Qwen, OpenCode,\n * Goose and Continue (§2.3).\n *\n * These harnesses take their endpoint from the environment rather than from a\n * config file, so the adapter's job is three things: resolve which registry\n * entry the session's model selector names, refuse at start when that entry\n * speaks a wire surface the harness cannot, and hand the driver the\n * provider-side model id it must put on the command line.\n *\n * Two pluralities meet here (`BUILTIN_DRIVER_CATALOG.providerPlurality`):\n *\n * - `single` — Gemini and Qwen address exactly one endpoint. The bound entry\n * supplies the credential *and* the base URL, and a surface mismatch is\n * fatal: a Gemini CLI pointed at an `openai-completions` endpoint cannot\n * work, and failing at start names the surface instead of leaving the user\n * with an opaque error mid-turn.\n * - `credentials-n` — OpenCode, Goose and Continue accept every enabled\n * entry's credential at once and select one active model. The credential\n * fan-out is `registryCredentialEnv`; the active model is this module's\n * `<provider>/<model>` binding.\n *\n * Writing the per-endpoint config files those three need for *custom*\n * endpoints (`opencode.json`, Goose `custom_providers/*.json`, Continue\n * `config.yaml`) is the file half, and is deliberately not here.\n *\n * @see PROVIDER-CONFIG-PLAN.md §2.3\n */\n\nimport {\n type AIProviderLlmEntry,\n type AIProviderSurface,\n isEntryEnabled,\n type MergedAIProviderRegistry,\n mergeRegistries,\n normalizeEntryBaseUrl,\n parseModelRef,\n registryEntries,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport type { ModelEntry } from \"../models.js\";\nimport { getProviderPreset } from \"../provider-catalog.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport type { AgentConfig } from \"../types.js\";\nimport { providerCredentialEnvName, registryCredentialEnv } from \"./credential-env.js\";\n\n/**\n * Everything a CLI driver needs to know about this session's AI providers,\n * resolved once from its {@link AgentConfig}.\n */\nexport interface EnvDriverSession {\n /** The merged registry this session may address. Empty when none was configured. */\n registry: MergedAIProviderRegistry;\n /**\n * Environment `credential.ref` lookups resolve against — the process\n * environment widened with `config.env`, which is where the session\n * boundary delivered every resolved `SKAILE_AIP_<ID>_KEY`.\n */\n lookupEnv: Record<string, string | undefined>;\n /** Model selector: `<providerId>/<modelId>`, a bare id, or `@role`. */\n modelRef?: string;\n /** Roles table an `@role` selector resolves through. */\n roles?: Record<string, string>;\n}\n\n/**\n * Resolve the session's providers once, from its {@link AgentConfig}.\n *\n * `config.env` is folded into `lookupEnv` rather than kept apart: it is part\n * of the session's environment, not an extra, and a credential or\n * `*_BASE_URL` delivered there must be visible exactly as the child will see\n * it.\n */\nexport function resolveEnvDriverSession(\n config: AgentConfig,\n processEnv: Record<string, string | undefined> = process.env,\n): EnvDriverSession {\n return {\n registry: config.registry ?? mergeRegistries([]),\n lookupEnv: { ...processEnv, ...config.env },\n ...(config.modelRef ? { modelRef: config.modelRef } : {}),\n ...(config.roles ? { roles: config.roles } : {}),\n };\n}\n\n/** One resolved endpoint + model — everything a driver needs to spawn. */\nexport interface RegistryModelBinding {\n /** Registry id of the selected entry. */\n providerId: string;\n /** The selected entry itself. */\n entry: AIProviderLlmEntry;\n /** Logical model id, after `@role` expansion and before `model_map`. */\n modelId?: string;\n /** Provider-side model id — what goes on the wire / command line. */\n providerModelId?: string;\n /** Wire protocol, from the entry or its preset. */\n surface?: AIProviderSurface;\n /** Resolved endpoint, from the entry, its transport params, or its preset. */\n baseUrl?: string;\n /**\n * The provider name the *harness* knows this endpoint by — a catalog preset\n * id for a stock endpoint, the registry id for anything custom. See\n * {@link harnessProviderName}.\n */\n harnessProviderId: string;\n /** Non-fatal notes from `parseModelRef` (dangling role, disabled provider). */\n warnings: string[];\n}\n\n/** The entry's wire surface: its own, else its preset's. */\nexport function entrySurface(entry: AIProviderLlmEntry): AIProviderSurface | undefined {\n if (entry.surface) return entry.surface;\n return entry.preset ? getProviderPreset(entry.preset)?.surface : undefined;\n}\n\n/**\n * The entry's endpoint: its literal or transport-derived URL, else its\n * preset's literal, in the canonical spelling for its surface\n * (`normalizeEntryBaseUrl`: an `anthropic-messages` endpoint is its host root,\n * so `https://api.anthropic.com/v1` reads as `https://api.anthropic.com`).\n * Transport templates that still carry `{param}` placeholders never come\n * back — `resolveEntryBaseUrl` withholds those, and a preset's template is not\n * a URL.\n *\n * Every adapter reads the endpoint here and only re-spells it for a client\n * that wants something else ({@link versionedAnthropicBaseUrl}).\n */\nexport function entryBaseUrl(entry: AIProviderLlmEntry): string | undefined {\n const resolved =\n resolveEntryBaseUrl(entry) ??\n (entry.preset ? getProviderPreset(entry.preset)?.base_url : undefined);\n return normalizeEntryBaseUrl(resolved, entrySurface(entry));\n}\n\n/**\n * An `anthropic-messages` endpoint spelled for a client that appends only\n * `/messages` — `@ai-sdk/anthropic` (OpenCode) and Continue — rather than\n * `/v1/messages` like the Claude CLI, the Anthropic SDK and Goose. `baseUrl`\n * must already be canonical ({@link entryBaseUrl}); every other surface passes\n * through unchanged.\n */\nexport function versionedAnthropicBaseUrl(\n baseUrl: string,\n surface: AIProviderSurface | undefined,\n): string {\n if (surface !== \"anthropic-messages\") return baseUrl;\n // Append to the path, not the string: a query or fragment stays at the end.\n try {\n const url = new URL(baseUrl);\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}/v1`;\n return url.toString();\n } catch {\n return `${baseUrl}/v1`;\n }\n}\n\n/**\n * True when a `credentials-n` harness already knows this endpoint under its\n * own catalog name — the entry names a preset and did not move it somewhere\n * else. Both sides are compared canonically, so `https://api.anthropic.com/v1`\n * is still the `anthropic` preset's endpoint.\n *\n * The one rule both halves of §2.3 read: it decides the name the env half\n * puts on the command line ({@link harnessProviderName}) *and* whether the\n * file half has to describe the endpoint at all. Reading it twice is what\n * keeps `-m <name>/<model>` and the generated provider file talking about the\n * same thing.\n */\nexport function isStockCatalogEndpoint(entry: AIProviderLlmEntry): boolean {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset) return false;\n return entryBaseUrl(entry) === normalizeEntryBaseUrl(preset.base_url, entrySurface(entry));\n}\n\n/**\n * The provider name to give a `credentials-n` harness (`-m <name>/<model>`,\n * `GOOSE_PROVIDER`).\n *\n * A stock catalog endpoint is named by its preset, because that is the name\n * OpenCode's models.dev list and Goose's built-in provider table already use —\n * `prod-claude: {preset: anthropic}` is still Anthropic to them. An entry with\n * an endpoint of its own is named by its registry id: no built-in table knows\n * it, so the id is what its generated provider file is keyed by (the file half\n * of §2.3).\n */\nexport function harnessProviderName(providerId: string, entry: AIProviderLlmEntry): string {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset || !isStockCatalogEndpoint(entry)) return providerId;\n return preset.id;\n}\n\n/**\n * Enabled `llm`/`embed` entries, in registry order. Also the set the file\n * adapters render (`opencode-config.ts`, `goose-custom-providers.ts`,\n * `continue-config-yaml.ts`): the env half and the file half must agree on\n * which entries exist before they can agree on what to call them.\n */\nexport function selectableEntries(\n registry: MergedAIProviderRegistry,\n): Array<[string, AIProviderLlmEntry]> {\n return registryEntries(registry).filter(\n (pair): pair is [string, AIProviderLlmEntry] =>\n (pair[1].kind === \"llm\" || pair[1].kind === \"embed\") && isEntryEnabled(pair[1]),\n );\n}\n\n/**\n * The provider-side model ids an entry declares, as `[logicalId, providerId]`\n * pairs in declaration order: every `model_map` entry, plus every\n * `capabilities` key the map does not rename.\n */\nexport function entryModelIds(entry: AIProviderLlmEntry): Array<[string, string]> {\n const logicalIds = [\n ...Object.keys(entry.model_map ?? {}),\n ...Object.keys(entry.capabilities ?? {}).filter((id) => !(id in (entry.model_map ?? {}))),\n ];\n return logicalIds.map((id) => [id, entry.model_map?.[id] ?? id]);\n}\n\nfunction describeBinding(\n providerId: string,\n entry: AIProviderLlmEntry,\n modelId: string | undefined,\n providerModelId: string | undefined,\n warnings: string[],\n): RegistryModelBinding {\n const surface = entrySurface(entry);\n const baseUrl = entryBaseUrl(entry);\n return {\n providerId,\n entry,\n ...(modelId === undefined ? {} : { modelId }),\n ...(providerModelId === undefined ? {} : { providerModelId }),\n ...(surface ? { surface } : {}),\n ...(baseUrl ? { baseUrl } : {}),\n harnessProviderId: harnessProviderName(providerId, entry),\n warnings,\n };\n}\n\n/**\n * Resolve the session's endpoint + model.\n *\n * With no selector the first entry in registry order wins and the harness\n * keeps its own default model — exactly what an absent `model` meant before\n * the registry existed. Returns `undefined` when no entry can serve a model\n * (an empty, fully-disabled or voice-only registry).\n */\nexport function resolveRegistryBinding(\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const entries = selectableEntries(session.registry);\n if (entries.length === 0) return undefined;\n\n const selector = session.modelRef?.trim();\n if (!selector) {\n const [providerId, entry] = entries[0];\n return describeBinding(providerId, entry, undefined, undefined, []);\n }\n\n // A selector that is exactly an entry id names the endpoint and nothing\n // else: the harness keeps its own default model. `parseModelRef` would read\n // it as a bare *model* id and fall back to registry order.\n const named = entries.find(([id]) => id === selector);\n if (named) return describeBinding(named[0], named[1], undefined, undefined, []);\n\n const resolved = parseModelRef(selector, session.registry, session.roles);\n if (!resolved) return undefined;\n const match = entries.find(([id]) => id === resolved.providerId);\n if (!match) return undefined;\n return describeBinding(\n match[0],\n match[1],\n resolved.modelId,\n resolved.providerModelId,\n resolved.warnings,\n );\n}\n\n/**\n * Every credential a `credentials-n` harness may use: one variable per\n * enabled registry entry. OpenCode, Goose and Continue have always received\n * *all* of them, not just the selected endpoint's, because they route across\n * providers inside a single session.\n */\nexport function credentialsForEveryProvider(session: EnvDriverSession): Record<string, string> {\n return registryCredentialEnv(session.registry, { env: session.lookupEnv });\n}\n\n/**\n * Throw when the bound entry speaks a wire surface this driver cannot.\n *\n * The message names the offending surface and lists the ones the harness does\n * speak (`BUILTIN_DRIVER_CATALOG[driverId].surfaces`). An entry that declares\n * no surface and names no preset is not judged — there is nothing to compare.\n */\nexport function assertDriverSpeaksSurface(\n driverId: string,\n productName: string,\n binding: RegistryModelBinding,\n): void {\n const supported = BUILTIN_DRIVER_CATALOG[driverId]?.surfaces;\n if (!supported || supported.length === 0) return;\n const surface = binding.surface;\n if (!surface || supported.includes(surface)) return;\n throw new Error(\n `${productName} cannot speak the '${surface}' surface of AI provider entry ` +\n `'${binding.providerId}'. ${productName} speaks: ${supported.join(\", \")}. ` +\n `Point this session's model at an entry with one of those surfaces, ` +\n `or run it on a driver that speaks '${surface}'.`,\n );\n}\n\n/**\n * The models a `credentials-n` harness can be pointed at, straight from the\n * registry: every enabled entry's mapped ids, namespaced the way the harness\n * takes them (`-m <provider>/<model>`).\n *\n * These harnesses have no model-list endpoint of their own — OpenCode reads\n * models.dev, Goose and Continue read their config — so the registry is the\n * only list that describes *this* session's reachable models, and it needs no\n * network call to produce.\n */\nexport function registryModelEntries(session: EnvDriverSession): ModelEntry[] {\n const out: ModelEntry[] = [];\n const seen = new Set<string>();\n for (const [providerId, entry] of selectableEntries(session.registry)) {\n const harnessId = harnessProviderName(providerId, entry);\n const label = entry.label ?? providerId;\n for (const [logicalId, providerModelId] of entryModelIds(entry)) {\n const id = `${harnessId}/${providerModelId}`;\n if (seen.has(id)) continue;\n seen.add(id);\n out.push({ id, name: `${label} ${logicalId}` });\n }\n }\n return out;\n}\n\n/**\n * Resolve the binding and enforce the surface — what a `single`-plurality\n * driver does at start.\n *\n * The registry is authoritative: pointing the driver at an entry it cannot\n * speak throws rather than silently running somewhere else. `undefined` when\n * the session configured no endpoint at all, which leaves the driver on its\n * own native auth.\n */\nexport function bindSingleProviderEntry(\n driverId: string,\n productName: string,\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n assertDriverSpeaksSurface(driverId, productName, binding);\n return binding;\n}\n\n/**\n * The `<provider>/<model>` selector a `credentials-n` harness takes on its\n * command line (`opencode -m`). `undefined` when no model was selected — the\n * harness then uses its own default rather than being handed a bare provider.\n */\nexport function harnessModelSelector(binding: RegistryModelBinding): string | undefined {\n if (!binding.providerModelId) return undefined;\n return `${binding.harnessProviderId}/${binding.providerModelId}`;\n}\n\n/**\n * Continue's model selection is a **role binding**, not a flag: `cn` has no\n * `--model` option (only `--config <slug>`), and its `config.yaml` binds each\n * model to roles (`chat`, `edit`, `apply`, …). This is the binding for the\n * role a headless `cn -p` turn runs as, and the shape its generated\n * `config.yaml` is rendered from.\n *\n * `apiKeyEnv` is a variable *name*: the secret travels in the child\n * environment, never in a rendered config.\n */\nexport interface ContinueRoleBinding {\n /** Continue role this model serves. A headless prompt is a `chat` turn. */\n role: \"chat\";\n /** Registry id of the entry. */\n providerId: string;\n /** Provider name Continue knows the endpoint by. */\n provider: string;\n /** Provider-side model id. */\n model?: string;\n /** Endpoint, when the entry states one, spelled the way Continue's `apiBase` wants it. */\n apiBase?: string;\n /** Env var holding the credential — the name, never the value. */\n apiKeyEnv: string;\n}\n\n/**\n * Map the session's chosen endpoint onto the Continue role a headless turn\n * runs as. `undefined` when the session configured no endpoint — `cn` then\n * runs against whatever its own `config.yaml` / Hub login provides.\n */\nexport function continueRoleBinding(session: EnvDriverSession): ContinueRoleBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n return {\n role: \"chat\",\n providerId: binding.providerId,\n provider: binding.harnessProviderId,\n ...(binding.providerModelId ? { model: binding.providerModelId } : {}),\n ...(binding.baseUrl\n ? { apiBase: versionedAnthropicBaseUrl(binding.baseUrl, binding.surface) }\n : {}),\n apiKeyEnv: providerCredentialEnvName(binding.providerId),\n };\n}\n"]}
1
+ {"version":3,"sources":["../bridge/src/provider-materialize/env-drivers.ts"],"names":[],"mappings":"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","file":"chunk-GYZJKZPJ.js","sourcesContent":["/**\n * Registry adapter for the **env-shaped CLI drivers** — Gemini, Qwen, OpenCode,\n * Goose and Continue (§2.3).\n *\n * These harnesses take their endpoint from the environment rather than from a\n * config file, so the adapter's job is three things: resolve which registry\n * entry the session's model selector names, refuse at start when that entry\n * speaks a wire surface the harness cannot, and hand the driver the\n * provider-side model id it must put on the command line.\n *\n * Two pluralities meet here (`BUILTIN_DRIVER_CATALOG.providerPlurality`):\n *\n * - `single` — Gemini and Qwen address exactly one endpoint. The bound entry\n * supplies the credential *and* the base URL, and a surface mismatch is\n * fatal: a Gemini CLI pointed at an `openai-completions` endpoint cannot\n * work, and failing at start names the surface instead of leaving the user\n * with an opaque error mid-turn.\n * - `credentials-n` — OpenCode, Goose and Continue accept every enabled\n * entry's credential at once and select one active model. The credential\n * fan-out is `registryCredentialEnv`; the active model is this module's\n * `<provider>/<model>` binding.\n *\n * Writing the per-endpoint config files those three need for *custom*\n * endpoints (`opencode.json`, Goose `custom_providers/*.json`, Continue\n * `config.yaml`) is the file half, and is deliberately not here.\n *\n * @see PROVIDER-CONFIG-PLAN.md §2.3\n */\n\nimport {\n type AIProviderLlmEntry,\n type AIProviderSurface,\n isEntryEnabled,\n type MergedAIProviderRegistry,\n mergeRegistries,\n normalizeEntryBaseUrl,\n parseModelRef,\n registryEntries,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport type { ModelEntry } from \"../models.js\";\nimport { getProviderPreset } from \"../provider-catalog.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport type { AgentConfig } from \"../types.js\";\nimport { providerCredentialEnvName, registryCredentialEnv } from \"./credential-env.js\";\n\n/**\n * Everything a CLI driver needs to know about this session's AI providers,\n * resolved once from its {@link AgentConfig}.\n */\nexport interface EnvDriverSession {\n /** The merged registry this session may address. Empty when none was configured. */\n registry: MergedAIProviderRegistry;\n /**\n * Environment `credential.ref` lookups resolve against — the process\n * environment widened with `config.env`, which is where the session\n * boundary delivered every resolved `SKAILE_AIP_<ID>_KEY`.\n */\n lookupEnv: Record<string, string | undefined>;\n /** Model selector: `<providerId>/<modelId>`, a bare id, or `@role`. */\n modelRef?: string;\n /** Roles table an `@role` selector resolves through. */\n roles?: Record<string, string>;\n}\n\n/**\n * Resolve the session's providers once, from its {@link AgentConfig}.\n *\n * `config.env` is folded into `lookupEnv` rather than kept apart: it is part\n * of the session's environment, not an extra, and a credential or\n * `*_BASE_URL` delivered there must be visible exactly as the child will see\n * it.\n */\nexport function resolveEnvDriverSession(\n config: AgentConfig,\n processEnv: Record<string, string | undefined> = process.env,\n): EnvDriverSession {\n return {\n registry: config.registry ?? mergeRegistries([]),\n lookupEnv: { ...processEnv, ...config.env },\n ...(config.modelRef ? { modelRef: config.modelRef } : {}),\n ...(config.roles ? { roles: config.roles } : {}),\n };\n}\n\n/** One resolved endpoint + model — everything a driver needs to spawn. */\nexport interface RegistryModelBinding {\n /** Registry id of the selected entry. */\n providerId: string;\n /** The selected entry itself. */\n entry: AIProviderLlmEntry;\n /** Logical model id, after `@role` expansion and before `model_map`. */\n modelId?: string;\n /** Provider-side model id — what goes on the wire / command line. */\n providerModelId?: string;\n /** Wire protocol, from the entry or its preset. */\n surface?: AIProviderSurface;\n /** Resolved endpoint, from the entry, its transport params, or its preset. */\n baseUrl?: string;\n /**\n * The provider name the *harness* knows this endpoint by — a catalog preset\n * id for a stock endpoint, the registry id for anything custom. See\n * {@link harnessProviderName}.\n */\n harnessProviderId: string;\n /** Non-fatal notes from `parseModelRef` (dangling role, disabled provider). */\n warnings: string[];\n}\n\n/** The entry's wire surface: its own, else its preset's. */\nexport function entrySurface(entry: AIProviderLlmEntry): AIProviderSurface | undefined {\n if (entry.surface) return entry.surface;\n return entry.preset ? getProviderPreset(entry.preset)?.surface : undefined;\n}\n\n/**\n * The entry's endpoint: its literal or transport-derived URL, else its\n * preset's literal, in the canonical spelling for its surface\n * (`normalizeEntryBaseUrl`: an `anthropic-messages` endpoint is its host root,\n * so `https://api.anthropic.com/v1` reads as `https://api.anthropic.com`).\n * Transport templates that still carry `{param}` placeholders never come\n * back — `resolveEntryBaseUrl` withholds those, and a preset's template is not\n * a URL.\n *\n * Every adapter reads the endpoint here and only re-spells it for a client\n * that wants something else ({@link versionedAnthropicBaseUrl}).\n */\nexport function entryBaseUrl(entry: AIProviderLlmEntry): string | undefined {\n const resolved =\n resolveEntryBaseUrl(entry) ??\n (entry.preset ? getProviderPreset(entry.preset)?.base_url : undefined);\n return normalizeEntryBaseUrl(resolved, entrySurface(entry));\n}\n\n/**\n * An `anthropic-messages` endpoint spelled for a client that appends only\n * `/messages` — `@ai-sdk/anthropic` (OpenCode) and Continue — rather than\n * `/v1/messages` like the Claude CLI, the Anthropic SDK and Goose. `baseUrl`\n * must already be canonical ({@link entryBaseUrl}); every other surface passes\n * through unchanged.\n */\nexport function versionedAnthropicBaseUrl(\n baseUrl: string,\n surface: AIProviderSurface | undefined,\n): string {\n if (surface !== \"anthropic-messages\") return baseUrl;\n // Append to the path, not the string: a query or fragment stays at the end.\n try {\n const url = new URL(baseUrl);\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}/v1`;\n return url.toString();\n } catch {\n return `${baseUrl}/v1`;\n }\n}\n\n/**\n * True when a `credentials-n` harness already knows this endpoint under its\n * own catalog name — the entry names a preset and did not move it somewhere\n * else. Both sides are compared canonically, so `https://api.anthropic.com/v1`\n * is still the `anthropic` preset's endpoint.\n *\n * The one rule both halves of §2.3 read: it decides the name the env half\n * puts on the command line ({@link harnessProviderName}) *and* whether the\n * file half has to describe the endpoint at all. Reading it twice is what\n * keeps `-m <name>/<model>` and the generated provider file talking about the\n * same thing.\n */\nexport function isStockCatalogEndpoint(entry: AIProviderLlmEntry): boolean {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset) return false;\n return entryBaseUrl(entry) === normalizeEntryBaseUrl(preset.base_url, entrySurface(entry));\n}\n\n/**\n * The provider name to give a `credentials-n` harness (`-m <name>/<model>`,\n * `GOOSE_PROVIDER`).\n *\n * A stock catalog endpoint is named by its preset, because that is the name\n * OpenCode's models.dev list and Goose's built-in provider table already use —\n * `prod-claude: {preset: anthropic}` is still Anthropic to them. An entry with\n * an endpoint of its own is named by its registry id: no built-in table knows\n * it, so the id is what its generated provider file is keyed by (the file half\n * of §2.3).\n */\nexport function harnessProviderName(providerId: string, entry: AIProviderLlmEntry): string {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset || !isStockCatalogEndpoint(entry)) return providerId;\n return preset.id;\n}\n\n/**\n * Enabled `llm`/`embed` entries, in registry order. Also the set the file\n * adapters render (`opencode-config.ts`, `goose-custom-providers.ts`,\n * `continue-config-yaml.ts`): the env half and the file half must agree on\n * which entries exist before they can agree on what to call them.\n */\nexport function selectableEntries(\n registry: MergedAIProviderRegistry,\n): Array<[string, AIProviderLlmEntry]> {\n return registryEntries(registry).filter(\n (pair): pair is [string, AIProviderLlmEntry] =>\n (pair[1].kind === \"llm\" || pair[1].kind === \"embed\") && isEntryEnabled(pair[1]),\n );\n}\n\n/**\n * The provider-side model ids an entry declares, as `[logicalId, providerId]`\n * pairs in declaration order: every `model_map` entry, plus every\n * `capabilities` key the map does not rename.\n */\nexport function entryModelIds(entry: AIProviderLlmEntry): Array<[string, string]> {\n const logicalIds = [\n ...Object.keys(entry.model_map ?? {}),\n ...Object.keys(entry.capabilities ?? {}).filter((id) => !(id in (entry.model_map ?? {}))),\n ];\n return logicalIds.map((id) => [id, entry.model_map?.[id] ?? id]);\n}\n\nfunction describeBinding(\n providerId: string,\n entry: AIProviderLlmEntry,\n modelId: string | undefined,\n providerModelId: string | undefined,\n warnings: string[],\n): RegistryModelBinding {\n const surface = entrySurface(entry);\n const baseUrl = entryBaseUrl(entry);\n return {\n providerId,\n entry,\n ...(modelId === undefined ? {} : { modelId }),\n ...(providerModelId === undefined ? {} : { providerModelId }),\n ...(surface ? { surface } : {}),\n ...(baseUrl ? { baseUrl } : {}),\n harnessProviderId: harnessProviderName(providerId, entry),\n warnings,\n };\n}\n\n/**\n * Resolve the session's endpoint + model.\n *\n * With no selector the first entry in registry order wins and the harness\n * keeps its own default model — exactly what an absent `model` meant before\n * the registry existed. Returns `undefined` when no entry can serve a model\n * (an empty, fully-disabled or voice-only registry).\n */\nexport function resolveRegistryBinding(\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const entries = selectableEntries(session.registry);\n if (entries.length === 0) return undefined;\n\n const selector = session.modelRef?.trim();\n if (!selector) {\n const [providerId, entry] = entries[0];\n return describeBinding(providerId, entry, undefined, undefined, []);\n }\n\n // A selector that is exactly an entry id names the endpoint and nothing\n // else: the harness keeps its own default model. `parseModelRef` would read\n // it as a bare *model* id and fall back to registry order.\n const named = entries.find(([id]) => id === selector);\n if (named) return describeBinding(named[0], named[1], undefined, undefined, []);\n\n const resolved = parseModelRef(selector, session.registry, session.roles);\n if (!resolved) return undefined;\n const match = entries.find(([id]) => id === resolved.providerId);\n if (!match) return undefined;\n return describeBinding(\n match[0],\n match[1],\n resolved.modelId,\n resolved.providerModelId,\n resolved.warnings,\n );\n}\n\n/**\n * Every credential a `credentials-n` harness may use: one variable per\n * enabled registry entry. OpenCode, Goose and Continue have always received\n * *all* of them, not just the selected endpoint's, because they route across\n * providers inside a single session.\n */\nexport function credentialsForEveryProvider(session: EnvDriverSession): Record<string, string> {\n return registryCredentialEnv(session.registry, { env: session.lookupEnv });\n}\n\n/**\n * Throw when the bound entry speaks a wire surface this driver cannot.\n *\n * The message names the offending surface and lists the ones the harness does\n * speak (`BUILTIN_DRIVER_CATALOG[driverId].surfaces`). An entry that declares\n * no surface and names no preset is not judged — there is nothing to compare.\n */\nexport function assertDriverSpeaksSurface(\n driverId: string,\n productName: string,\n binding: RegistryModelBinding,\n): void {\n const supported = BUILTIN_DRIVER_CATALOG[driverId]?.surfaces;\n if (!supported || supported.length === 0) return;\n const surface = binding.surface;\n if (!surface || supported.includes(surface)) return;\n throw new Error(\n `${productName} cannot speak the '${surface}' surface of AI provider entry ` +\n `'${binding.providerId}'. ${productName} speaks: ${supported.join(\", \")}. ` +\n `Point this session's model at an entry with one of those surfaces, ` +\n `or run it on a driver that speaks '${surface}'.`,\n );\n}\n\n/**\n * The models a `credentials-n` harness can be pointed at, straight from the\n * registry: every enabled entry's mapped ids, namespaced the way the harness\n * takes them (`-m <provider>/<model>`).\n *\n * These harnesses have no model-list endpoint of their own — OpenCode reads\n * models.dev, Goose and Continue read their config — so the registry is the\n * only list that describes *this* session's reachable models, and it needs no\n * network call to produce.\n */\nexport function registryModelEntries(session: EnvDriverSession): ModelEntry[] {\n const out: ModelEntry[] = [];\n const seen = new Set<string>();\n for (const [providerId, entry] of selectableEntries(session.registry)) {\n const harnessId = harnessProviderName(providerId, entry);\n const label = entry.label ?? providerId;\n for (const [logicalId, providerModelId] of entryModelIds(entry)) {\n const id = `${harnessId}/${providerModelId}`;\n if (seen.has(id)) continue;\n seen.add(id);\n out.push({ id, name: `${label} ${logicalId}` });\n }\n }\n return out;\n}\n\n/**\n * Resolve the binding and enforce the surface — what a `single`-plurality\n * driver does at start.\n *\n * The registry is authoritative: pointing the driver at an entry it cannot\n * speak throws rather than silently running somewhere else. `undefined` when\n * the session configured no endpoint at all, which leaves the driver on its\n * own native auth.\n */\nexport function bindSingleProviderEntry(\n driverId: string,\n productName: string,\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n assertDriverSpeaksSurface(driverId, productName, binding);\n return binding;\n}\n\n/**\n * The `<provider>/<model>` selector a `credentials-n` harness takes on its\n * command line (`opencode -m`). `undefined` when no model was selected — the\n * harness then uses its own default rather than being handed a bare provider.\n */\nexport function harnessModelSelector(binding: RegistryModelBinding): string | undefined {\n if (!binding.providerModelId) return undefined;\n return `${binding.harnessProviderId}/${binding.providerModelId}`;\n}\n\n/**\n * Continue's model selection is a **role binding**, not a flag: `cn` has no\n * `--model` option (only `--config <slug>`), and its `config.yaml` binds each\n * model to roles (`chat`, `edit`, `apply`, …). This is the binding for the\n * role a headless `cn -p` turn runs as, and the shape its generated\n * `config.yaml` is rendered from.\n *\n * `apiKeyEnv` is a variable *name*: the secret travels in the child\n * environment, never in a rendered config.\n */\nexport interface ContinueRoleBinding {\n /** Continue role this model serves. A headless prompt is a `chat` turn. */\n role: \"chat\";\n /** Registry id of the entry. */\n providerId: string;\n /** Provider name Continue knows the endpoint by. */\n provider: string;\n /** Provider-side model id. */\n model?: string;\n /** Endpoint, when the entry states one, spelled the way Continue's `apiBase` wants it. */\n apiBase?: string;\n /** Env var holding the credential — the name, never the value. */\n apiKeyEnv: string;\n}\n\n/**\n * Map the session's chosen endpoint onto the Continue role a headless turn\n * runs as. `undefined` when the session configured no endpoint — `cn` then\n * runs against whatever its own `config.yaml` / Hub login provides.\n */\nexport function continueRoleBinding(session: EnvDriverSession): ContinueRoleBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n return {\n role: \"chat\",\n providerId: binding.providerId,\n provider: binding.harnessProviderId,\n ...(binding.providerModelId ? { model: binding.providerModelId } : {}),\n ...(binding.baseUrl\n ? { apiBase: versionedAnthropicBaseUrl(binding.baseUrl, binding.surface) }\n : {}),\n apiKeyEnv: providerCredentialEnvName(binding.providerId),\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { err, okJson, ok } from './chunk-X5YPJV4N.js';
2
- import { buildConnectorListPayload } from './chunk-OJHPG6HK.js';
2
+ import { buildConnectorListPayload } from './chunk-V5CDPKDA.js';
3
3
  import { readFile } from 'fs/promises';
4
4
  import { join } from 'path';
5
5
 
@@ -117,5 +117,5 @@ async function connectorDescribe(manager, id) {
117
117
  }
118
118
 
119
119
  export { connectorDescribe, connectorExec, connectorList, connectorLoadSkill, connectorRead, connectorSearch, connectorWrite, mountList, mountRead, mountStatus, mountSync };
120
- //# sourceMappingURL=chunk-TADJCATD.js.map
121
- //# sourceMappingURL=chunk-TADJCATD.js.map
120
+ //# sourceMappingURL=chunk-HLETG3CX.js.map
121
+ //# sourceMappingURL=chunk-HLETG3CX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../workspace-plugin/src/tools/connectors.ts"],"names":[],"mappings":";;;;;AAwBA,SAAS,cAAc,OAAA,EAAiD;AACtE,EAAA,OAAO,OAAA,CACJ,gBAAe,CACf,MAAA,CAAO,CAAC,CAAA,KAA+B,OAAO,CAAA,CAAE,SAAA,KAAc,QAAQ,CAAA;AAC3E;AAaA,eAAe,YAAA,CACb,SACA,KAAA,EACoB;AAEpB,EAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,kBAAA,GAAqB,MAAM,EAAE,CAAA;AAC5D,EAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,KAAA,KAAU,QAAQ,OAAO,KAAA;AACnD,EAAA,IAAI,QAAA,CAAS,KAAA,KAAU,MAAA,EAAQ,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAQ,QAAA,CAAS,MAAA,EAAO;AAC3F,EAAA,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQ,SAAS,MAAA,EAAO;AAC7C;AAUA,eAAsB,UAAU,OAAA,EAAuD;AACrF,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,OAAO,MAAA,CAAO,MAAM,OAAA,CAAQ,GAAA,CAAI,cAAc,OAAO,CAAA,CAAE,GAAA,CAAI,CAAC,MAAM,YAAA,CAAa,OAAA,EAAS,CAAC,CAAC,CAAC,CAAC,CAAA;AAAA,EAC9F,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAUA,eAAsB,SAAA,CACpB,SACA,OAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA;AACzC,IAAA,OAAO,OAAO,MAAM,CAAA;AAAA,EACtB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAUA,eAAsB,WAAA,CACpB,SACA,OAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,cAAc,OAAO,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,OAAO,CAAA;AACjE,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,GAAA,CAAI,CAAA,kBAAA,EAAqB,OAAO,CAAA,CAAA,CAAG,CAAA;AACtD,IAAA,OAAO,MAAA,CAAO,MAAM,YAAA,CAAa,OAAA,EAAS,KAAK,CAAC,CAAA;AAAA,EAClD,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAYA,eAAsB,SAAA,CACpB,OAAA,EACA,OAAA,EACA,QAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,cAAc,OAAO,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,OAAO,CAAA;AACjE,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,GAAA,CAAI,CAAA,kBAAA,EAAqB,OAAO,CAAA,CAAA,CAAG,CAAA;AACtD,IAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,IAAA,CAAK,MAAM,SAAA,EAAW,QAAQ,GAAG,OAAO,CAAA;AACvE,IAAA,OAAO,GAAG,OAAO,CAAA;AAAA,EACnB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAiBA,eAAsB,cAAc,OAAA,EAAuD;AACzF,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AAEF,IAAA,OAAO,MAAA,CAAO,MAAM,yBAAA,CAA0B,OAAO,CAAC,CAAA;AAAA,EACxD,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAcA,eAAsB,aAAA,CACpB,OAAA,EACA,EAAA,EACA,IAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,IAAI,CAAA;AAC3C,IAAA,IAAI,OAAA,KAAY,MAAM,OAAO,GAAA,CAAI,uBAAuB,IAAI,CAAA,gBAAA,EAAmB,EAAE,CAAA,CAAA,CAAG,CAAA;AACpF,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;AAcA,eAAsB,cAAA,CACpB,OAAA,EACA,EAAA,EACA,IAAA,EACA,OAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,QAAQ,KAAA,CAAM,EAAA,EAAI,MAAM,EAAE,IAAA,EAAM,SAAS,CAAA;AAC/C,IAAA,OAAO,EAAA,CAAG,CAAA,YAAA,EAAe,IAAI,CAAA,gBAAA,EAAmB,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,EACvD,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAaA,eAAsB,eAAA,CACpB,OAAA,EACA,EAAA,EACA,KAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAK,CAAA;AAC9C,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;AAgBA,eAAsB,aAAA,CACpB,OAAA,EACA,EAAA,EACA,SAAA,EACA,IAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAM,OAAA,CAAQ,SAAA,CAAU,EAAA,EAAI,WAAW,IAAI,CAAA;AAC1D,IAAA,OAAO,GAAG,MAAM,CAAA;AAAA,EAClB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAcA,eAAsB,kBAAA,CACpB,SACA,EAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,SAAA,CAAU,EAAE,CAAA;AAClC,IAAA,OAAO,GAAG,KAAK,CAAA;AAAA,EACjB,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF;AAcA,eAAsB,iBAAA,CACpB,SACA,EAAA,EACqB;AACrB,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,GAAA,CAAI,yCAAyC,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,QAAQ,UAAA,EAAW;AAClC,IAAA,MAAM,aAAa,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AACjD,IAAA,IAAI,CAAC,UAAA,EAAY,OAAO,GAAA,CAAI,CAAA,mCAAA,EAAsC,EAAE,CAAA,CAAA,CAAG,CAAA;AACvE,IAAA,OAAO,OAAO,UAAU,CAAA;AAAA,EAC1B,SAAS,CAAA,EAAY;AACnB,IAAA,OAAO,IAAI,CAAA,YAAa,KAAA,GAAQ,EAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACvD;AACF","file":"chunk-TADJCATD.js","sourcesContent":["// src/tools/connectors.ts\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { buildConnectorListPayload, type ConnectorManager } from \"@skaile/workspaces/connectors\";\nimport type { ToolResult } from \"../types.js\";\nimport { err, ok, okJson } from \"../types.js\";\n\n// ── Mountable-connector helpers ──────────────────────────────────────────────\n//\n// The unified ConnectorManager owns mountable (filesystem-face) connectors too.\n// A connector is mountable when its `listConnectors()` summary carries a\n// `mountPath`. The `mount*` helpers below project that subset for the legacy\n// `mount_*` tool surface.\n\n/**\n * A connector summary that carries a projected filesystem path. Unlike the raw\n * `listConnectors()` summary, `mountPath` is non-optional here — `listMountable()`\n * runtime-filters to exactly those entries before narrowing to this type.\n */\ntype MountableConnector = ReturnType<ConnectorManager[\"listConnectors\"]>[number] & {\n mountPath: string;\n};\n\n/** Return the mountable (filesystem-face) connectors from a manager. */\nfunction listMountable(manager: ConnectorManager): MountableConnector[] {\n return manager\n .listConnectors()\n .filter((c): c is MountableConnector => typeof c.mountPath === \"string\");\n}\n\n/**\n * A mountable connector as reported to the agent, with an optional `reason`.\n *\n * A fleet-managed mount whose path is gone reports `status: \"error\"` plus a\n * `reason`, even though the connector handle still reads `connected`. One whose\n * probe timed out keeps its cached status and gains a `reason` saying it is\n * unverified: a slow cloud mount is not reported dead.\n */\ntype MountView = MountableConnector & { reason?: string };\n\n/** Overlay a live re-check on the cached connect-time status where one applies. */\nasync function withLiveness(\n manager: ConnectorManager,\n mount: MountableConnector,\n): Promise<MountView> {\n // Optional call: the tool tests' manager doubles omit the method.\n const liveness = await manager.checkMountLiveness?.(mount.id);\n if (!liveness || liveness.state === \"live\") return mount;\n if (liveness.state === \"dead\") return { ...mount, status: \"error\", reason: liveness.reason };\n return { ...mount, reason: liveness.reason };\n}\n\n/**\n * List all mountable (filesystem-face) connectors declared in `skaile.yaml`\n * with their current mount status.\n *\n * @param manager - Active `ConnectorManager` or `null` when not configured.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function mountList(manager: ConnectorManager | null): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n return okJson(await Promise.all(listMountable(manager).map((m) => withLiveness(manager, m))));\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Sync a mountable connector — pull the latest content from its remote source.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param mountId - Connector ID declared in `skaile.yaml`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function mountSync(\n manager: ConnectorManager | null,\n mountId: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const result = await manager.sync(mountId);\n return okJson(result);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Get the current status and metadata for a single mountable connector.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param mountId - Connector ID declared in `skaile.yaml`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function mountStatus(\n manager: ConnectorManager | null,\n mountId: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const mount = listMountable(manager).find((v) => v.id === mountId);\n if (!mount) return err(`Mount not found: \"${mountId}\"`);\n return okJson(await withLiveness(manager, mount));\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Read a file from within a mountable connector's projected directory by its\n * relative path.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param mountId - Connector ID declared in `skaile.yaml`.\n * @param filePath - Relative path within the projected mount directory.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function mountRead(\n manager: ConnectorManager | null,\n mountId: string,\n filePath: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const mount = listMountable(manager).find((v) => v.id === mountId);\n if (!mount) return err(`Mount not found: \"${mountId}\"`);\n const content = await readFile(join(mount.mountPath, filePath), \"utf-8\");\n return ok(content);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * List all connectors registered with the `ConnectorManager`.\n *\n * Returns `{ connected, failed }` — `connected` from `manager.listConnectors()`,\n * `failed` from `manager.listFailedConnectors()`. A connector that threw during\n * `connect()` never enters the active map, so it is absent from the first list\n * entirely; without the second one an agent driven through MCP or OMP has no\n * way to learn that a mount it is about to write into is dead. Returns an error\n * result when no manager is configured (i.e. `skaile.yaml` has no `connectors`\n * section).\n *\n * @param manager - Active `ConnectorManager` or `null` when not configured.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorList(manager: ConnectorManager | null): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n // Same payload as the Claude SDK tool: per-mount health and a notice when one is not ok.\n return okJson(await buildConnectorListPayload(manager));\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Read content from a connector at the given path.\n *\n * Delegates to `manager.read(id, path)`. Returns an error result when the\n * path yields `null` (not found) or the manager is absent.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n * @param path - Resource path within the connector (connector-specific format).\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorRead(\n manager: ConnectorManager | null,\n id: string,\n path: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const content = await manager.read(id, path);\n if (content === null) return err(`No content at path \"${path}\" in connector \"${id}\"`);\n return okJson(content);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Write string content to a connector at the given path.\n *\n * Delegates to `manager.write(id, path, { data: content })`.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n * @param path - Destination path within the connector.\n * @param content - String payload to write.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorWrite(\n manager: ConnectorManager | null,\n id: string,\n path: string,\n content: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n await manager.write(id, path, { data: content });\n return ok(`Written to \"${path}\" in connector \"${id}\"`);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Search a connector's data using a query string.\n *\n * Delegates to `manager.search(id, query)` and returns the result set as JSON.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n * @param query - Free-text or structured query (connector-specific format).\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorSearch(\n manager: ConnectorManager | null,\n id: string,\n query: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const results = await manager.search(id, query);\n return okJson(results);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Execute a named operation on a connector.\n *\n * Delegates to `manager.executeOp(id, operation, args)`. Operations and\n * their argument shapes are connector-specific; use {@link connectorDescribe}\n * to discover what operations a connector supports.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n * @param operation - Operation name (from the connector's `RuntimeSkillDescriptor`).\n * @param args - Named arguments for the operation.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorExec(\n manager: ConnectorManager | null,\n id: string,\n operation: string,\n args: Record<string, unknown>,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const result = await manager.executeOp(id, operation, args);\n return ok(result);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Load the rendered skill body for a connector.\n *\n * Delegates to `manager.loadSkill(id)` and returns the skill content as\n * plain text. Useful when the agent needs the connector's operations and\n * usage instructions injected as prompt context.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorLoadSkill(\n manager: ConnectorManager | null,\n id: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const skill = manager.loadSkill(id);\n return ok(skill);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Describe a connector's capabilities via its `RuntimeSkillDescriptor`.\n *\n * Finds the matching skill descriptor from `manager.listSkills()` and returns\n * it as JSON. The descriptor includes the connector's operations, argument\n * shapes, and usage instructions.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorDescribe(\n manager: ConnectorManager | null,\n id: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const skills = manager.listSkills();\n const descriptor = skills.find((s) => s.id === id);\n if (!descriptor) return err(`No skill descriptor for connector \"${id}\"`);\n return okJson(descriptor);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n"]}
1
+ {"version":3,"sources":["../workspace-plugin/src/tools/connectors.ts"],"names":[],"mappings":"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","file":"chunk-HLETG3CX.js","sourcesContent":["// src/tools/connectors.ts\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { buildConnectorListPayload, type ConnectorManager } from \"@skaile/workspaces/connectors\";\nimport type { ToolResult } from \"../types.js\";\nimport { err, ok, okJson } from \"../types.js\";\n\n// ── Mountable-connector helpers ──────────────────────────────────────────────\n//\n// The unified ConnectorManager owns mountable (filesystem-face) connectors too.\n// A connector is mountable when its `listConnectors()` summary carries a\n// `mountPath`. The `mount*` helpers below project that subset for the legacy\n// `mount_*` tool surface.\n\n/**\n * A connector summary that carries a projected filesystem path. Unlike the raw\n * `listConnectors()` summary, `mountPath` is non-optional here — `listMountable()`\n * runtime-filters to exactly those entries before narrowing to this type.\n */\ntype MountableConnector = ReturnType<ConnectorManager[\"listConnectors\"]>[number] & {\n mountPath: string;\n};\n\n/** Return the mountable (filesystem-face) connectors from a manager. */\nfunction listMountable(manager: ConnectorManager): MountableConnector[] {\n return manager\n .listConnectors()\n .filter((c): c is MountableConnector => typeof c.mountPath === \"string\");\n}\n\n/**\n * A mountable connector as reported to the agent, with an optional `reason`.\n *\n * A fleet-managed mount whose path is gone reports `status: \"error\"` plus a\n * `reason`, even though the connector handle still reads `connected`. One whose\n * probe timed out keeps its cached status and gains a `reason` saying it is\n * unverified: a slow cloud mount is not reported dead.\n */\ntype MountView = MountableConnector & { reason?: string };\n\n/** Overlay a live re-check on the cached connect-time status where one applies. */\nasync function withLiveness(\n manager: ConnectorManager,\n mount: MountableConnector,\n): Promise<MountView> {\n // Optional call: the tool tests' manager doubles omit the method.\n const liveness = await manager.checkMountLiveness?.(mount.id);\n if (!liveness || liveness.state === \"live\") return mount;\n if (liveness.state === \"dead\") return { ...mount, status: \"error\", reason: liveness.reason };\n return { ...mount, reason: liveness.reason };\n}\n\n/**\n * List all mountable (filesystem-face) connectors declared in `skaile.yaml`\n * with their current mount status.\n *\n * @param manager - Active `ConnectorManager` or `null` when not configured.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function mountList(manager: ConnectorManager | null): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n return okJson(await Promise.all(listMountable(manager).map((m) => withLiveness(manager, m))));\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Sync a mountable connector — pull the latest content from its remote source.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param mountId - Connector ID declared in `skaile.yaml`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function mountSync(\n manager: ConnectorManager | null,\n mountId: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const result = await manager.sync(mountId);\n return okJson(result);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Get the current status and metadata for a single mountable connector.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param mountId - Connector ID declared in `skaile.yaml`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function mountStatus(\n manager: ConnectorManager | null,\n mountId: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const mount = listMountable(manager).find((v) => v.id === mountId);\n if (!mount) return err(`Mount not found: \"${mountId}\"`);\n return okJson(await withLiveness(manager, mount));\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Read a file from within a mountable connector's projected directory by its\n * relative path.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param mountId - Connector ID declared in `skaile.yaml`.\n * @param filePath - Relative path within the projected mount directory.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function mountRead(\n manager: ConnectorManager | null,\n mountId: string,\n filePath: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const mount = listMountable(manager).find((v) => v.id === mountId);\n if (!mount) return err(`Mount not found: \"${mountId}\"`);\n const content = await readFile(join(mount.mountPath, filePath), \"utf-8\");\n return ok(content);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * List all connectors registered with the `ConnectorManager`.\n *\n * Returns `{ connected, failed }` — `connected` from `manager.listConnectors()`,\n * `failed` from `manager.listFailedConnectors()`. A connector that threw during\n * `connect()` never enters the active map, so it is absent from the first list\n * entirely; without the second one an agent driven through MCP or OMP has no\n * way to learn that a mount it is about to write into is dead. Returns an error\n * result when no manager is configured (i.e. `skaile.yaml` has no `connectors`\n * section).\n *\n * @param manager - Active `ConnectorManager` or `null` when not configured.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorList(manager: ConnectorManager | null): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n // Same payload as the Claude SDK tool: per-mount health and a notice when one is not ok.\n return okJson(await buildConnectorListPayload(manager));\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Read content from a connector at the given path.\n *\n * Delegates to `manager.read(id, path)`. Returns an error result when the\n * path yields `null` (not found) or the manager is absent.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n * @param path - Resource path within the connector (connector-specific format).\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorRead(\n manager: ConnectorManager | null,\n id: string,\n path: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const content = await manager.read(id, path);\n if (content === null) return err(`No content at path \"${path}\" in connector \"${id}\"`);\n return okJson(content);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Write string content to a connector at the given path.\n *\n * Delegates to `manager.write(id, path, { data: content })`.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n * @param path - Destination path within the connector.\n * @param content - String payload to write.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorWrite(\n manager: ConnectorManager | null,\n id: string,\n path: string,\n content: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n await manager.write(id, path, { data: content });\n return ok(`Written to \"${path}\" in connector \"${id}\"`);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Search a connector's data using a query string.\n *\n * Delegates to `manager.search(id, query)` and returns the result set as JSON.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n * @param query - Free-text or structured query (connector-specific format).\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorSearch(\n manager: ConnectorManager | null,\n id: string,\n query: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const results = await manager.search(id, query);\n return okJson(results);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Execute a named operation on a connector.\n *\n * Delegates to `manager.executeOp(id, operation, args)`. Operations and\n * their argument shapes are connector-specific; use {@link connectorDescribe}\n * to discover what operations a connector supports.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n * @param operation - Operation name (from the connector's `RuntimeSkillDescriptor`).\n * @param args - Named arguments for the operation.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorExec(\n manager: ConnectorManager | null,\n id: string,\n operation: string,\n args: Record<string, unknown>,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const result = await manager.executeOp(id, operation, args);\n return ok(result);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Load the rendered skill body for a connector.\n *\n * Delegates to `manager.loadSkill(id)` and returns the skill content as\n * plain text. Useful when the agent needs the connector's operations and\n * usage instructions injected as prompt context.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorLoadSkill(\n manager: ConnectorManager | null,\n id: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const skill = manager.loadSkill(id);\n return ok(skill);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n\n/**\n * Describe a connector's capabilities via its `RuntimeSkillDescriptor`.\n *\n * Finds the matching skill descriptor from `manager.listSkills()` and returns\n * it as JSON. The descriptor includes the connector's operations, argument\n * shapes, and usage instructions.\n *\n * @param manager - Active `ConnectorManager` or `null`.\n * @param id - Connector ID declared in `skaile.yaml`.\n *\n * @docLink packages/workspace-plugin/concepts#tool-delivery\n */\nexport async function connectorDescribe(\n manager: ConnectorManager | null,\n id: string,\n): Promise<ToolResult> {\n if (!manager) return err(\"No connectors configured in skaile.yaml\");\n try {\n const skills = manager.listSkills();\n const descriptor = skills.find((s) => s.id === id);\n if (!descriptor) return err(`No skill descriptor for connector \"${id}\"`);\n return okJson(descriptor);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : String(e));\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { registeredAssetKeys, unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, reportLibrarySymlinks, composeRefContext, assetEntryRef, manifestPublisherProblems, manifestRootProblems, manifestEntryNameProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, manifestVersionMismatchMessage, checkAsset, invalidSemverText } from './chunk-5CE6J4DB.js';
1
+ import { registeredAssetKeys, unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, reportLibrarySymlinks, composeRefContext, assetEntryRef, manifestPublisherProblems, manifestRootProblems, manifestEntryNameProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, manifestVersionMismatchMessage, checkAsset, invalidSemverText } from './chunk-OXUCYHL5.js';
2
2
  import { AI_RESOURCES } from './chunk-WKEBNB5S.js';
3
- import { logErr, logInfo, logWarn, logOk } from './chunk-VJ2DZLDM.js';
3
+ import { logErr, logInfo, logWarn, logOk } from './chunk-QEX75L77.js';
4
4
  import { getKindRegistry } from './chunk-2SKPPIV7.js';
5
5
  import { validateFlowVersions } from './chunk-D5REDKVU.js';
6
6
  import { loadFlow } from './chunk-SPV2CXJ3.js';
@@ -1012,5 +1012,5 @@ function makeValidateCommand() {
1012
1012
  }
1013
1013
 
1014
1014
  export { isRecord, makeValidateCommand, scanIdentities };
1015
- //# sourceMappingURL=chunk-FWAJUWXQ.js.map
1016
- //# sourceMappingURL=chunk-FWAJUWXQ.js.map
1015
+ //# sourceMappingURL=chunk-KZWZRNIY.js.map
1016
+ //# sourceMappingURL=chunk-KZWZRNIY.js.map