@skaile/workspaces 0.15.0 → 0.16.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 (102) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/asset-feeds-L4ROBIAZ.js +90 -0
  3. package/dist/asset-feeds-L4ROBIAZ.js.map +1 -0
  4. package/dist/asset-manager/index.js +5 -5
  5. package/dist/asset-manager/installer.js +4 -4
  6. package/dist/asset-manager/src/index.d.ts.map +1 -1
  7. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  8. package/dist/base-assets/connectors/deploy.js +5 -5
  9. package/dist/base-assets/connectors/devserver.js +5 -5
  10. package/dist/base-assets/connectors/flow/adapter.js +5 -5
  11. package/dist/base-assets/connectors/flow/run-flow.js +6 -6
  12. package/dist/base-assets/connectors/flow.js +5 -5
  13. package/dist/base-assets/connectors/git.js +5 -5
  14. package/dist/base-assets/connectors/gmail.js +5 -5
  15. package/dist/base-assets/connectors/googledrive.js +5 -5
  16. package/dist/base-assets/connectors/local.js +5 -5
  17. package/dist/base-assets/connectors/mattermost.js +5 -5
  18. package/dist/base-assets/connectors/memory.js +5 -5
  19. package/dist/base-assets/connectors/minio.js +5 -5
  20. package/dist/base-assets/connectors/postgres.js +5 -5
  21. package/dist/base-assets/connectors/redis.js +5 -5
  22. package/dist/base-assets/connectors/s3.js +5 -5
  23. package/dist/base-assets/connectors/sharepoint.js +5 -5
  24. package/dist/base-assets/connectors/sqlite.js +5 -5
  25. package/dist/base-assets/connectors/static-server.js +5 -5
  26. package/dist/base-assets/connectors/tunnel.js +5 -5
  27. package/dist/base-assets/connectors/webdav.js +5 -5
  28. package/dist/base-assets/connectors/xstate-store.js +5 -5
  29. package/dist/base-assets/connectors/xstate.js +5 -5
  30. package/dist/base-assets/connectors/yjs.js +5 -5
  31. package/dist/{chunk-SVNFQSU3.js → chunk-3DS5VIQP.js} +3 -3
  32. package/dist/{chunk-SVNFQSU3.js.map → chunk-3DS5VIQP.js.map} +1 -1
  33. package/dist/{chunk-4GEVGRWB.js → chunk-42YLNYFK.js} +11 -13
  34. package/dist/chunk-42YLNYFK.js.map +1 -0
  35. package/dist/{chunk-4RUVG5GX.js → chunk-4BRSVK7Q.js} +46 -3
  36. package/dist/chunk-4BRSVK7Q.js.map +1 -0
  37. package/dist/{chunk-Z24KPZKU.js → chunk-75M5W7FX.js} +8 -8
  38. package/dist/{chunk-Z24KPZKU.js.map → chunk-75M5W7FX.js.map} +1 -1
  39. package/dist/{chunk-SO43XRWF.js → chunk-ALJM24WL.js} +5 -5
  40. package/dist/{chunk-SO43XRWF.js.map → chunk-ALJM24WL.js.map} +1 -1
  41. package/dist/{chunk-2NIOMFSQ.js → chunk-FNCYNUGS.js} +78 -81
  42. package/dist/chunk-FNCYNUGS.js.map +1 -0
  43. package/dist/{chunk-6EN5IJ2Y.js → chunk-IY4X7PZN.js} +3 -3
  44. package/dist/{chunk-6EN5IJ2Y.js.map → chunk-IY4X7PZN.js.map} +1 -1
  45. package/dist/{chunk-W75ASXH4.js → chunk-KJ2LLWRF.js} +3 -3
  46. package/dist/{chunk-W75ASXH4.js.map → chunk-KJ2LLWRF.js.map} +1 -1
  47. package/dist/{chunk-6DEGWPAR.js → chunk-SMFZFFIZ.js} +3 -3
  48. package/dist/{chunk-6DEGWPAR.js.map → chunk-SMFZFFIZ.js.map} +1 -1
  49. package/dist/{chunk-GAZINYCS.js → chunk-SOQMVRQL.js} +19 -3
  50. package/dist/chunk-SOQMVRQL.js.map +1 -0
  51. package/dist/{chunk-7R4WLTZW.js → chunk-YMMWP3YL.js} +29 -19
  52. package/dist/chunk-YMMWP3YL.js.map +1 -0
  53. package/dist/{chunk-HSOEX3TA.js → chunk-YW36VEVN.js} +4 -4
  54. package/dist/{chunk-HSOEX3TA.js.map → chunk-YW36VEVN.js.map} +1 -1
  55. package/dist/{chunk-G7O7WDXX.js → chunk-ZUQXHBEH.js} +2 -2
  56. package/dist/{chunk-G7O7WDXX.js.map → chunk-ZUQXHBEH.js.map} +1 -1
  57. package/dist/cli/index.js +376 -207
  58. package/dist/cli/index.js.map +1 -1
  59. package/dist/cli/src/asset-feeds.d.ts +42 -0
  60. package/dist/cli/src/asset-feeds.d.ts.map +1 -0
  61. package/dist/cli/src/commands/manage.d.ts +31 -20
  62. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  63. package/dist/cli/src/commands/project.d.ts.map +1 -1
  64. package/dist/cli/src/commands/source.d.ts +6 -4
  65. package/dist/cli/src/commands/source.d.ts.map +1 -1
  66. package/dist/cli/src/ensure-sources.d.ts +25 -0
  67. package/dist/cli/src/ensure-sources.d.ts.map +1 -0
  68. package/dist/connectors/config.js +4 -4
  69. package/dist/connectors/index.js +5 -5
  70. package/dist/core/index.js +3 -3
  71. package/dist/core/runtime-assets.js +2 -2
  72. package/dist/core/src/index.d.ts +1 -1
  73. package/dist/core/src/index.d.ts.map +1 -1
  74. package/dist/core/src/workspace-config.d.ts +27 -0
  75. package/dist/core/src/workspace-config.d.ts.map +1 -1
  76. package/dist/core/src/workspace-yaml-editor.d.ts +10 -1
  77. package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
  78. package/dist/core/workspace-config.js +1 -1
  79. package/dist/ensure-sources-V26CZNJF.js +68 -0
  80. package/dist/ensure-sources-V26CZNJF.js.map +1 -0
  81. package/dist/library/index.js +1 -1
  82. package/dist/library/src/local/db.d.ts.map +1 -1
  83. package/dist/library/src/local/store-paths.d.ts.map +1 -1
  84. package/dist/{open-library-XD7QYLMW.js → open-library-T6RXQJTQ.js} +4 -4
  85. package/dist/{open-library-XD7QYLMW.js.map → open-library-T6RXQJTQ.js.map} +1 -1
  86. package/dist/runner/index.js +7 -7
  87. package/dist/sdk/asset-manager.js +5 -5
  88. package/dist/sdk/core.js +3 -3
  89. package/dist/sdk/index.js +7 -7
  90. package/dist/sdk/runner.js +7 -7
  91. package/dist/{setup-WZFCLQ2J.js → setup-R6VWIPLL.js} +5 -5
  92. package/dist/{setup-WZFCLQ2J.js.map → setup-R6VWIPLL.js.map} +1 -1
  93. package/dist/{store-client-BM3IBDPT.js → store-client-FLD3XUY7.js} +6 -6
  94. package/dist/{store-client-BM3IBDPT.js.map → store-client-FLD3XUY7.js.map} +1 -1
  95. package/dist/tui/index.js +7 -7
  96. package/dist/workspace-plugin/index.js +1 -1
  97. package/package.json +1 -1
  98. package/dist/chunk-2NIOMFSQ.js.map +0 -1
  99. package/dist/chunk-4GEVGRWB.js.map +0 -1
  100. package/dist/chunk-4RUVG5GX.js.map +0 -1
  101. package/dist/chunk-7R4WLTZW.js.map +0 -1
  102. package/dist/chunk-GAZINYCS.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { logErr } from './chunk-4NDWKA64.js';
2
- import { knowledgeKindProvider } from './chunk-2NIOMFSQ.js';
2
+ import { knowledgeKindProvider } from './chunk-FNCYNUGS.js';
3
3
  import { createDefaultRegistry } from './chunk-GKIA2PU5.js';
4
4
  import { flowKindProvider } from './chunk-ICS76R4T.js';
5
5
 
@@ -97,5 +97,5 @@ async function openLibraryManager() {
97
97
  }
98
98
 
99
99
  export { createFullRegistry, openCatalogSource, openLibrary, openLibraryManager, resolveCatalogSource };
100
- //# sourceMappingURL=chunk-6EN5IJ2Y.js.map
101
- //# sourceMappingURL=chunk-6EN5IJ2Y.js.map
100
+ //# sourceMappingURL=chunk-IY4X7PZN.js.map
101
+ //# sourceMappingURL=chunk-IY4X7PZN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/open-registry.ts","../cli/src/open-library.ts"],"names":["source"],"mappings":"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","file":"chunk-6EN5IJ2Y.js","sourcesContent":["/**\n * open-registry.ts — shared helper to create a full AssetKindRegistry.\n *\n * Bootstraps the registry with all built-in providers (9 core + preset)\n * from @skaile/discovery, plus the extension kind providers (flow from\n * @skaile/workspaces/base-assets/connectors/flow/engine, knowledge from @skaile/library).\n *\n * This is the single registration point for the CLI. All code paths\n * that need a registry (source sync, lib-status, etc.) should use this.\n */\n\nimport { flowKindProvider } from \"@skaile/workspaces/base-assets/connectors/flow/engine\";\nimport type { AssetKindRegistry } from \"@skaile/workspaces/discovery\";\nimport { createDefaultRegistry } from \"@skaile/workspaces/discovery\";\nimport { knowledgeKindProvider } from \"@skaile/workspaces/library\";\n\n/**\n * Create a fully-configured AssetKindRegistry with all known providers.\n *\n * Registers:\n * - 9 core kinds (skill, agent, connector, mount, mcp-server, contract, prompt, persona, ruleset)\n * - preset (composition entity)\n * - flow (extension, from @skaile/workspaces/base-assets/connectors/flow/engine)\n * - knowledge (extension, from @skaile/library)\n *\n * @returns An unfrozen registry (auto-freezes on first read)\n */\nexport function createFullRegistry(): AssetKindRegistry {\n const registry = createDefaultRegistry();\n registry.register(flowKindProvider);\n registry.register(knowledgeKindProvider);\n return registry;\n}\n","/**\n * open-library.ts — shared helpers to open the LocalIndex and the configured\n * Catalog source.\n *\n * Lazy-loads the `@skaile/workspaces/library` subpath and returns the\n * LocalIndex instance (backed by `@libsql/client`; runs on Node and Bun).\n * The catalog-source helper reads\n * `~/.skaile/config.yaml` (and project-level overlay if `projectDir` is given)\n * to decide between {@link RemoteCatalogSource} (default — points at\n * `https://skaile.store`) and a {@link LocalCatalogSource} bound to the most\n * recent local library registered via `skaile source add`.\n */\n\nimport { logErr } from \"./helpers.ts\";\nimport { createFullRegistry } from \"./open-registry.ts\";\n\n/**\n * Open the LocalIndex with the full kind registry. Exits with code 1\n * if the library directory cannot be created.\n *\n * @returns A `LocalIndex` instance ready for use.\n * @docLink cli/dev-guide#open-library\n */\nexport async function openLibrary() {\n try {\n const { LocalIndex } = await import(\"@skaile/workspaces/library\");\n return new LocalIndex({ kindRegistry: createFullRegistry() });\n } catch (err) {\n logErr(`Could not open LocalIndex: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\n/**\n * Resolve the configured **remote** Catalog source for the CLI.\n *\n * Reads `~/.skaile/config.yaml` (plus the optional project-level overlay) and\n * returns a {@link RemoteCatalogSource} pointing at `catalog.url` (default:\n * `https://skaile.store`). The `cache_ttl: 0` config flag flips the source\n * into air-gapped mode: network reads are disabled, only `skaile update`\n * performs refreshes.\n *\n * **Local-mode rejection.** If the resolved config has `catalog.url: local`\n * this helper throws — callers wanting the dispatched local-or-remote source\n * must use {@link resolveCatalogSource}. Remote-only consumers like\n * `skaile update --catalog-only` rely on this strict behaviour.\n *\n * @param opts - Project directory (overlays project config) and explicit overrides.\n * @returns A configured {@link RemoteCatalogSource}.\n * @throws When `catalog.url` is the `local` sentinel.\n * @docLink cli/dev-guide#open-library\n */\nexport async function openCatalogSource(opts?: {\n projectDir?: string;\n baseUrlOverride?: string;\n /** Override the user-config path for tests. */\n userConfigFile?: string;\n}): Promise<\n | import(\"@skaile/workspaces/library\").RemoteCatalogSource\n | import(\"@skaile/workspaces/library\").RestCatalogSource\n> {\n const { resolveConfig, RemoteCatalogSource, RestCatalogSource, isLocalCatalogUrl } = await import(\n \"@skaile/workspaces/library\"\n );\n const cfg = resolveConfig({\n projectDir: opts?.projectDir,\n userConfigFile: opts?.userConfigFile,\n });\n const baseUrl = opts?.baseUrlOverride ?? cfg.catalog.url;\n if (isLocalCatalogUrl(baseUrl)) {\n throw new Error(\n \"catalog.url is set to 'local' — remote catalog is disabled. \" +\n \"Use `skaile source add <path>` + `skaile source sync` for local sources, \" +\n \"or set `catalog.url: https://skaile.store` in ~/.skaile/config.yaml.\",\n );\n }\n const cacheTtlMs = cfg.catalog.cache_ttl * 1000;\n if (cfg.catalog.framing === \"rest\") {\n return new RestCatalogSource({ baseUrl, cacheTtlMs });\n }\n return new RemoteCatalogSource({ baseUrl, cacheTtlMs });\n}\n\n/**\n * Resolved catalog source plus a close handle for releasing any underlying\n * resources (e.g. the `LocalIndex` SQLite connection in local mode).\n *\n * Callers MUST invoke `close()` when done — typically in a `finally` block.\n * For remote-mode sources `close()` is a no-op, but the contract is uniform\n * so consumers don't have to branch.\n *\n * @docLink cli/dev-guide#open-library\n */\nexport interface ResolvedCatalogSource {\n /** The {@link ICatalogSource} ready for use. */\n source: import(\"@skaile/workspaces/library\").ICatalogSource;\n /** Release any underlying resources (SQLite handle in local mode). */\n close(): void;\n}\n\n/**\n * Resolve the configured Catalog source — local or remote — based on\n * `~/.skaile/config.yaml`.\n *\n * Dispatch:\n * - `catalog.url: local` → opens {@link LocalIndex}, picks the most recently\n * registered local library whose `path` still exists on disk, and returns a\n * {@link LocalCatalogSource} bound to that library. Throws if no usable\n * local library is registered.\n * - any URL → returns {@link RemoteCatalogSource} (same as\n * {@link openCatalogSource}).\n *\n * The returned `close()` releases the underlying `LocalIndex` SQLite handle\n * in local mode (no-op in remote mode). Callers MUST invoke it — typically in\n * a `finally` block — to satisfy `library/CLAUDE.md` § \"Notes for Consumers\".\n *\n * @param opts - Project directory (overlays project config) and explicit overrides.\n * @returns A `ResolvedCatalogSource` carrying the source and a close handle.\n * @throws When `local` is configured but no usable local library is registered.\n * @docLink cli/dev-guide#open-library\n */\nexport async function resolveCatalogSource(opts?: {\n projectDir?: string;\n baseUrlOverride?: string;\n /** Override the user-config path for tests. */\n userConfigFile?: string;\n}): Promise<ResolvedCatalogSource> {\n const {\n resolveConfig,\n RemoteCatalogSource,\n RestCatalogSource,\n LocalCatalogSource,\n isLocalCatalogUrl,\n } = await import(\"@skaile/workspaces/library\");\n const cfg = resolveConfig({\n projectDir: opts?.projectDir,\n userConfigFile: opts?.userConfigFile,\n });\n const baseUrl = opts?.baseUrlOverride ?? cfg.catalog.url;\n\n if (isLocalCatalogUrl(baseUrl)) {\n const fs = await import(\"node:fs\");\n const library = await openLibrary();\n try {\n const sources = await library.listSources();\n type LibraryRow = (typeof sources)[number];\n // Type-narrow: `path` is required for local libraries after the filter.\n const usable = sources\n .filter(\n (s): s is LibraryRow & { path: string } =>\n s.backend === \"local\" && typeof s.path === \"string\" && s.path.length > 0,\n )\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n if (usable.length === 0) {\n throw new Error(\n \"catalog.url is set to 'local' but no local library is registered. \" +\n \"Run `skaile source add <path>` first, then `skaile source sync`.\",\n );\n }\n\n // Prefer the most recently added library whose path still exists.\n const present = usable.find((s) => fs.existsSync(s.path));\n if (!present) {\n const head = usable[0];\n throw new Error(\n `catalog.url is set to 'local' but every registered local library has a missing path on disk. ` +\n `Most recent: ${head.path} (library ${head.id}). ` +\n `Re-register with \\`skaile source add <existing-path>\\` or run \\`skaile source list\\` to inspect.`,\n );\n }\n\n const source = new LocalCatalogSource(\n library,\n present.id,\n present.path,\n createFullRegistry(),\n );\n return { source, close: () => library.close() };\n } catch (err) {\n // Release the handle on any failure during dispatch — otherwise the\n // SQLite WAL state leaks for the lifetime of the process.\n library.close();\n throw err;\n }\n }\n\n const cacheTtlMs = cfg.catalog.cache_ttl * 1000;\n const source =\n cfg.catalog.framing === \"rest\"\n ? new RestCatalogSource({ baseUrl, cacheTtlMs })\n : new RemoteCatalogSource({ baseUrl, cacheTtlMs });\n return { source, close: () => {} };\n}\n\n/**\n * Open the LibraryManager bound to the active LocalIndex.\n * Caller owns lifetime — must call `close()` (returned helper closes the\n * underlying LocalIndex).\n *\n * @docLink cli/dev-guide#open-library\n */\nexport async function openLibraryManager(): Promise<{\n manager: import(\"@skaile/workspaces/library\").LibraryManager;\n library: import(\"@skaile/workspaces/library\").LocalIndex;\n close: () => void;\n}> {\n const { LibraryManager } = await import(\"@skaile/workspaces/library\");\n const library = await openLibrary();\n const manager = new LibraryManager(library);\n return { manager, library, close: () => library.close() };\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/open-registry.ts","../cli/src/open-library.ts"],"names":["source"],"mappings":"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","file":"chunk-IY4X7PZN.js","sourcesContent":["/**\n * open-registry.ts — shared helper to create a full AssetKindRegistry.\n *\n * Bootstraps the registry with all built-in providers (9 core + preset)\n * from @skaile/discovery, plus the extension kind providers (flow from\n * @skaile/workspaces/base-assets/connectors/flow/engine, knowledge from @skaile/library).\n *\n * This is the single registration point for the CLI. All code paths\n * that need a registry (source sync, lib-status, etc.) should use this.\n */\n\nimport { flowKindProvider } from \"@skaile/workspaces/base-assets/connectors/flow/engine\";\nimport type { AssetKindRegistry } from \"@skaile/workspaces/discovery\";\nimport { createDefaultRegistry } from \"@skaile/workspaces/discovery\";\nimport { knowledgeKindProvider } from \"@skaile/workspaces/library\";\n\n/**\n * Create a fully-configured AssetKindRegistry with all known providers.\n *\n * Registers:\n * - 9 core kinds (skill, agent, connector, mount, mcp-server, contract, prompt, persona, ruleset)\n * - preset (composition entity)\n * - flow (extension, from @skaile/workspaces/base-assets/connectors/flow/engine)\n * - knowledge (extension, from @skaile/library)\n *\n * @returns An unfrozen registry (auto-freezes on first read)\n */\nexport function createFullRegistry(): AssetKindRegistry {\n const registry = createDefaultRegistry();\n registry.register(flowKindProvider);\n registry.register(knowledgeKindProvider);\n return registry;\n}\n","/**\n * open-library.ts — shared helpers to open the LocalIndex and the configured\n * Catalog source.\n *\n * Lazy-loads the `@skaile/workspaces/library` subpath and returns the\n * LocalIndex instance (backed by `@libsql/client`; runs on Node and Bun).\n * The catalog-source helper reads\n * `~/.skaile/config.yaml` (and project-level overlay if `projectDir` is given)\n * to decide between {@link RemoteCatalogSource} (default — points at\n * `https://skaile.store`) and a {@link LocalCatalogSource} bound to the most\n * recent local library registered via `skaile source add`.\n */\n\nimport { logErr } from \"./helpers.ts\";\nimport { createFullRegistry } from \"./open-registry.ts\";\n\n/**\n * Open the LocalIndex with the full kind registry. Exits with code 1\n * if the library directory cannot be created.\n *\n * @returns A `LocalIndex` instance ready for use.\n * @docLink cli/dev-guide#open-library\n */\nexport async function openLibrary() {\n try {\n const { LocalIndex } = await import(\"@skaile/workspaces/library\");\n return new LocalIndex({ kindRegistry: createFullRegistry() });\n } catch (err) {\n logErr(`Could not open LocalIndex: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\n/**\n * Resolve the configured **remote** Catalog source for the CLI.\n *\n * Reads `~/.skaile/config.yaml` (plus the optional project-level overlay) and\n * returns a {@link RemoteCatalogSource} pointing at `catalog.url` (default:\n * `https://skaile.store`). The `cache_ttl: 0` config flag flips the source\n * into air-gapped mode: network reads are disabled, only `skaile update`\n * performs refreshes.\n *\n * **Local-mode rejection.** If the resolved config has `catalog.url: local`\n * this helper throws — callers wanting the dispatched local-or-remote source\n * must use {@link resolveCatalogSource}. Remote-only consumers like\n * `skaile update --catalog-only` rely on this strict behaviour.\n *\n * @param opts - Project directory (overlays project config) and explicit overrides.\n * @returns A configured {@link RemoteCatalogSource}.\n * @throws When `catalog.url` is the `local` sentinel.\n * @docLink cli/dev-guide#open-library\n */\nexport async function openCatalogSource(opts?: {\n projectDir?: string;\n baseUrlOverride?: string;\n /** Override the user-config path for tests. */\n userConfigFile?: string;\n}): Promise<\n | import(\"@skaile/workspaces/library\").RemoteCatalogSource\n | import(\"@skaile/workspaces/library\").RestCatalogSource\n> {\n const { resolveConfig, RemoteCatalogSource, RestCatalogSource, isLocalCatalogUrl } = await import(\n \"@skaile/workspaces/library\"\n );\n const cfg = resolveConfig({\n projectDir: opts?.projectDir,\n userConfigFile: opts?.userConfigFile,\n });\n const baseUrl = opts?.baseUrlOverride ?? cfg.catalog.url;\n if (isLocalCatalogUrl(baseUrl)) {\n throw new Error(\n \"catalog.url is set to 'local' — remote catalog is disabled. \" +\n \"Use `skaile source add <path>` + `skaile source sync` for local sources, \" +\n \"or set `catalog.url: https://skaile.store` in ~/.skaile/config.yaml.\",\n );\n }\n const cacheTtlMs = cfg.catalog.cache_ttl * 1000;\n if (cfg.catalog.framing === \"rest\") {\n return new RestCatalogSource({ baseUrl, cacheTtlMs });\n }\n return new RemoteCatalogSource({ baseUrl, cacheTtlMs });\n}\n\n/**\n * Resolved catalog source plus a close handle for releasing any underlying\n * resources (e.g. the `LocalIndex` SQLite connection in local mode).\n *\n * Callers MUST invoke `close()` when done — typically in a `finally` block.\n * For remote-mode sources `close()` is a no-op, but the contract is uniform\n * so consumers don't have to branch.\n *\n * @docLink cli/dev-guide#open-library\n */\nexport interface ResolvedCatalogSource {\n /** The {@link ICatalogSource} ready for use. */\n source: import(\"@skaile/workspaces/library\").ICatalogSource;\n /** Release any underlying resources (SQLite handle in local mode). */\n close(): void;\n}\n\n/**\n * Resolve the configured Catalog source — local or remote — based on\n * `~/.skaile/config.yaml`.\n *\n * Dispatch:\n * - `catalog.url: local` → opens {@link LocalIndex}, picks the most recently\n * registered local library whose `path` still exists on disk, and returns a\n * {@link LocalCatalogSource} bound to that library. Throws if no usable\n * local library is registered.\n * - any URL → returns {@link RemoteCatalogSource} (same as\n * {@link openCatalogSource}).\n *\n * The returned `close()` releases the underlying `LocalIndex` SQLite handle\n * in local mode (no-op in remote mode). Callers MUST invoke it — typically in\n * a `finally` block — to satisfy `library/CLAUDE.md` § \"Notes for Consumers\".\n *\n * @param opts - Project directory (overlays project config) and explicit overrides.\n * @returns A `ResolvedCatalogSource` carrying the source and a close handle.\n * @throws When `local` is configured but no usable local library is registered.\n * @docLink cli/dev-guide#open-library\n */\nexport async function resolveCatalogSource(opts?: {\n projectDir?: string;\n baseUrlOverride?: string;\n /** Override the user-config path for tests. */\n userConfigFile?: string;\n}): Promise<ResolvedCatalogSource> {\n const {\n resolveConfig,\n RemoteCatalogSource,\n RestCatalogSource,\n LocalCatalogSource,\n isLocalCatalogUrl,\n } = await import(\"@skaile/workspaces/library\");\n const cfg = resolveConfig({\n projectDir: opts?.projectDir,\n userConfigFile: opts?.userConfigFile,\n });\n const baseUrl = opts?.baseUrlOverride ?? cfg.catalog.url;\n\n if (isLocalCatalogUrl(baseUrl)) {\n const fs = await import(\"node:fs\");\n const library = await openLibrary();\n try {\n const sources = await library.listSources();\n type LibraryRow = (typeof sources)[number];\n // Type-narrow: `path` is required for local libraries after the filter.\n const usable = sources\n .filter(\n (s): s is LibraryRow & { path: string } =>\n s.backend === \"local\" && typeof s.path === \"string\" && s.path.length > 0,\n )\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n if (usable.length === 0) {\n throw new Error(\n \"catalog.url is set to 'local' but no local library is registered. \" +\n \"Run `skaile source add <path>` first, then `skaile source sync`.\",\n );\n }\n\n // Prefer the most recently added library whose path still exists.\n const present = usable.find((s) => fs.existsSync(s.path));\n if (!present) {\n const head = usable[0];\n throw new Error(\n `catalog.url is set to 'local' but every registered local library has a missing path on disk. ` +\n `Most recent: ${head.path} (library ${head.id}). ` +\n `Re-register with \\`skaile source add <existing-path>\\` or run \\`skaile source list\\` to inspect.`,\n );\n }\n\n const source = new LocalCatalogSource(\n library,\n present.id,\n present.path,\n createFullRegistry(),\n );\n return { source, close: () => library.close() };\n } catch (err) {\n // Release the handle on any failure during dispatch — otherwise the\n // SQLite WAL state leaks for the lifetime of the process.\n library.close();\n throw err;\n }\n }\n\n const cacheTtlMs = cfg.catalog.cache_ttl * 1000;\n const source =\n cfg.catalog.framing === \"rest\"\n ? new RestCatalogSource({ baseUrl, cacheTtlMs })\n : new RemoteCatalogSource({ baseUrl, cacheTtlMs });\n return { source, close: () => {} };\n}\n\n/**\n * Open the LibraryManager bound to the active LocalIndex.\n * Caller owns lifetime — must call `close()` (returned helper closes the\n * underlying LocalIndex).\n *\n * @docLink cli/dev-guide#open-library\n */\nexport async function openLibraryManager(): Promise<{\n manager: import(\"@skaile/workspaces/library\").LibraryManager;\n library: import(\"@skaile/workspaces/library\").LocalIndex;\n close: () => void;\n}> {\n const { LibraryManager } = await import(\"@skaile/workspaces/library\");\n const library = await openLibrary();\n const manager = new LibraryManager(library);\n return { manager, library, close: () => library.close() };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { resolveSkWorkspaceConfig } from './chunk-GAZINYCS.js';
1
+ import { resolveSkWorkspaceConfig } from './chunk-SOQMVRQL.js';
2
2
  import { createLogger } from './chunk-24UIWON4.js';
3
3
 
4
4
  // connectors/src/secrets.ts
@@ -302,5 +302,5 @@ function resolveAuthRef(auth, mountId) {
302
302
  }
303
303
 
304
304
  export { EnvSecretProvider, ForgeSecretProvider, InMemorySecretProvider, LegacyAuthGrammarError, LockedSecretProvider, OAuthRequiredError, PreMintedSecretProvider, SecretProviderChain, createCliSecretProviderChain, createForgeSecretProviderChain, loadConnectorDeclarations, resolveAuth, resolveAuthRef, resolveBackendAuthFor };
305
- //# sourceMappingURL=chunk-W75ASXH4.js.map
306
- //# sourceMappingURL=chunk-W75ASXH4.js.map
305
+ //# sourceMappingURL=chunk-KJ2LLWRF.js.map
306
+ //# sourceMappingURL=chunk-KJ2LLWRF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../connectors/src/secrets.ts","../connectors/src/config.ts"],"names":[],"mappings":"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","file":"chunk-W75ASXH4.js","sourcesContent":["/**\n * Secret provider abstraction.\n *\n * Decouples credential resolution from process.env so secrets can be\n * provisioned over the transport bridge instead of living in the\n * container's environment.\n */\n\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\n\nconst log = createLogger({ kind: \"connector\", subkind: \"secrets\" });\n\n// ── Interfaces ──────────────────────────────────────────────────────────────\n\n/**\n * Read-only secret resolution. Adapters receive this interface.\n * @docLink packages/connectors/api-reference#secret-provider\n */\nexport interface SecretProvider {\n /**\n * Resolve a credential reference.\n *\n * @param ref - Credential reference such as \"env:GIT_TOKEN\",\n * \"oauth:google:user@example.com\", or an inline literal.\n * @returns The resolved secret value or undefined if not found.\n */\n resolve(ref: string): string | undefined;\n /**\n * Check whether a reference can be resolved.\n *\n * @param ref - Reference to check.\n * @returns True if resolve(ref) would return a non-undefined value.\n */\n has(ref: string): boolean;\n /**\n * Return all ref strings this provider can currently resolve.\n *\n * @returns All resolvable refs (used by forge UI and ConnectorFieldMissingError).\n */\n capabilities(): string[];\n}\n\n/**\n * Extends `SecretProvider` with the ability to load secrets at runtime via `provision()`.\n * @docLink packages/connectors/api-reference#provisionable-secret-provider\n */\nexport interface ProvisionableSecretProvider extends SecretProvider {\n /** Store a batch of key-value secrets. Keys are bare names (no prefix). */\n provision(secrets: Record<string, string>): void;\n}\n\n// ── Implementations ─────────────────────────────────────────────────────────\n\n/**\n * In-memory secret store. Secrets are provisioned over the transport bridge\n * and stored in a private Map — never touching the filesystem or process.env.\n *\n * Supports ref prefixes:\n * `\"env:KEY\"` — looks up KEY in the store\n * `\"vault:KEY\"` — looks up KEY in the store (future vault compat)\n * (no prefix) — returned as an inline value (backwards compat for non-chain usages)\n * @docLink packages/connectors/api-reference#in-memory-secret-provider\n */\nexport class InMemorySecretProvider implements ProvisionableSecretProvider {\n private readonly store = new Map<string, string>();\n\n /**\n * Store a batch of key-value secrets.\n *\n * @param secrets - Key-value map of secret names to values. Keys are bare names (no prefix).\n */\n provision(secrets: Record<string, string>): void {\n for (const [key, value] of Object.entries(secrets)) {\n this.store.set(key, value);\n }\n }\n\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n if (ref.startsWith(\"env:\")) return this.store.get(ref.slice(4));\n if (ref.startsWith(\"vault:\")) return this.store.get(ref.slice(6));\n // Bare key: check store first, then fall back to inline literal\n const stored = this.store.get(ref);\n if (stored !== undefined) return stored;\n return ref;\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n return [...this.store.keys()].map((k) => `env:${k}`);\n }\n}\n\n/**\n * Delegates to `process.env`. Used in CLI/standalone mode.\n * Does NOT pass through inline literals — returns `undefined` for any ref\n * that does not start with `\"env:\"`. Use `InMemorySecretProvider` for inline\n * literals in non-chain contexts.\n * @docLink packages/connectors/api-reference#env-secret-provider\n */\nexport class EnvSecretProvider implements SecretProvider {\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n if (ref.startsWith(\"env:\")) return process.env[ref.slice(4)];\n return undefined; // no inline passthrough\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n return Object.keys(process.env).map((k) => `env:${k}`);\n }\n}\n\n/**\n * Pre-minted credential entry. Mirrors the discriminated `CredentialMint`\n * shape from `@skaile/workspaces/types` but redeclared here to keep this package\n * free of cross-package type dependencies.\n *\n * The failure branch carries the platform-side `code` + `message` so the\n * `ConnectorManager`'s wrapped mediator can surface the real reason instead of\n * a generic \"no pre-mint\" placeholder when a mint comes back as `ok: false`.\n */\nexport type PreMintedCredential =\n | { ok: true; token: string; expiresAt: string | null; mintedAt?: string }\n | {\n ok: false;\n code?: \"not-configured\" | \"revoked\" | \"provider-error\" | \"backend-error\";\n message?: string;\n };\n\n/**\n * Pre-minted credential store. Holds short-lived tokens delivered upfront in\n * the v3 `session_init` envelope so the runner never has to call back to the\n * platform during mount setup.\n *\n * Resolves refs of the form `mount:<id>` and `connector:<id>`. Returns\n * `undefined` for any other ref so the chain falls through to the next\n * provider (`EnvSecretProvider` for `pat:env:NAME`, etc.).\n *\n * Tokens can be added/removed at runtime via {@link set} / {@link unset} so\n * `runner.add_mount` / `runner.add_connector` / `runner.update_credential`\n * capabilities stay strictly in-process — no round trip to the platform to\n * mint while the mount is hot-attached.\n *\n * For callers that need the full mint metadata (expiry timestamp, mintedAt\n * audit fields), use {@link mintFor} instead of the bare `resolve`. The\n * `ConnectorManager` consults this for the `auth: backend` initial-mint path so\n * the driver retains the original expiry semantics.\n *\n * Spec: `_devlog/specs/2026-05-10-deterministic-session-bootstrap.md`.\n *\n * @docLink packages/connectors/api-reference#pre-minted-secret-provider\n */\nexport class PreMintedSecretProvider implements SecretProvider {\n private readonly mints = new Map<string, PreMintedCredential>();\n\n /**\n * Seed pre-minted credentials from the v3 `session_init.credentials` map.\n *\n * Failed mints (`ok: false`) are stored too so callers can distinguish\n * \"not pre-minted\" from \"pre-minted but failed\"; {@link resolve} treats\n * both as `undefined`.\n *\n * @param credentials Optional initial `{ mounts, connectors }` map.\n */\n constructor(credentials?: {\n mounts?: Record<string, PreMintedCredential>;\n connectors?: Record<string, PreMintedCredential>;\n }) {\n if (!credentials) return;\n for (const [id, mint] of Object.entries(credentials.mounts ?? {})) {\n this.mints.set(`mount:${id}`, mint);\n }\n for (const [id, mint] of Object.entries(credentials.connectors ?? {})) {\n this.mints.set(`connector:${id}`, mint);\n }\n }\n\n /**\n * Insert (or replace) a pre-minted credential. Used by\n * `runner.add_mount` / `runner.add_connector` / `runner.update_credential`\n * capability handlers when the platform delivers new credentials\n * mid-session.\n */\n set(kind: \"mount\" | \"connector\", id: string, mint: PreMintedCredential): void {\n this.mints.set(`${kind}:${id}`, mint);\n }\n\n /**\n * Remove a stored pre-minted credential. Used by the\n * `runner.remove_resource` capability handler.\n */\n unset(kind: \"mount\" | \"connector\", id: string): boolean {\n return this.mints.delete(`${kind}:${id}`);\n }\n\n /**\n * Look up the full {@link PreMintedCredential} for a `mount:` /\n * `connector:` keyed entry. Callers that only need the token use\n * {@link resolve} via the chain; callers that need expiry / audit\n * metadata (e.g. ConnectorManager) use this entry point.\n */\n mintFor(kind: \"mount\" | \"connector\", id: string): PreMintedCredential | undefined {\n return this.mints.get(`${kind}:${id}`);\n }\n\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n if (!(ref.startsWith(\"mount:\") || ref.startsWith(\"connector:\"))) return undefined;\n const mint = this.mints.get(ref);\n return mint?.ok ? mint.token : undefined;\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n return [...this.mints.entries()].filter(([, m]) => m.ok).map(([k]) => k);\n }\n}\n\n/**\n * Forge session secret provider. Secrets are provisioned from the Forge settings\n * panel over the transport bridge. Only handles `\"forge:\"` prefixed refs — returns\n * `undefined` for all others.\n * @docLink packages/connectors/api-reference#forge-secret-provider\n */\nexport class ForgeSecretProvider implements ProvisionableSecretProvider {\n private readonly store = new Map<string, string>();\n\n provision(secrets: Record<string, string>): void {\n for (const [key, value] of Object.entries(secrets)) {\n this.store.set(key, value);\n }\n }\n\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n if (ref.startsWith(\"forge:\")) return this.store.get(ref.slice(6));\n return undefined;\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n return [...this.store.keys()].map((k) => `forge:${k}`);\n }\n}\n\n/**\n * Thrown when an OAuth-secured connector field requires user authorization before\n * it can be resolved. Contains the redirect URL to open in the user's browser.\n * @docLink packages/connectors/api-reference#o-auth-required-error\n */\nexport class OAuthRequiredError extends Error {\n readonly oauthRef: string;\n readonly authUrl: string;\n readonly state: string;\n\n /**\n * @param oauthRef - The 'oauth:<service>:<account>' ref that triggered the error\n * @param authUrl - Browser URL to open for OAuth authorization\n * @param state - OAuth state token for CSRF protection and callback correlation\n */\n constructor(oauthRef: string, authUrl: string, state: string) {\n super(`OAuth authorization required for ${oauthRef}`);\n this.name = \"OAuthRequiredError\";\n this.oauthRef = oauthRef;\n this.authUrl = authUrl;\n this.state = state;\n }\n}\n\n/**\n * Shape of an OAuth token bundle stored by `OAuthSecretProvider`.\n * @docLink packages/connectors/api-reference#o-auth-token-bundle\n */\nexport interface OAuthTokenBundle {\n accessToken: string;\n refreshToken?: string;\n /** Unix timestamp in ms */\n expiry?: number;\n}\n\n/**\n * Return value of `OAuthSecretProvider.initiateFlow()`. Contains the URL and CSRF state token.\n * @docLink packages/connectors/api-reference#o-auth-flow-request\n */\nexport interface OAuthFlowRequest {\n authUrl: string;\n state: string;\n}\n\n/**\n * OAuth token provider. Handles `\"oauth:<service>:<account>\"` refs.\n * Callers must call `chain.prepareRef()` before `chain.resolve()` for `oauth:` refs.\n * @docLink packages/connectors/api-reference#o-auth-secret-provider\n */\nexport interface OAuthSecretProvider extends SecretProvider {\n /**\n * Ensure the token for this ref is fresh.\n * Refreshes if expired.\n * Throws OAuthRequiredError if no token exists and user authorization is needed.\n */\n ensureFresh(ref: string): Promise<void>;\n\n /** Initiate the OAuth authorization flow. Returns URL to open in the user's browser. */\n initiateFlow(oauthService: string, account: string): Promise<OAuthFlowRequest>;\n\n /** Exchange authorization code for tokens and store the bundle. */\n completeFlow(state: string, code: string): Promise<void>;\n}\n\n/**\n * Abstract base for vault-backed secret providers (1Password, KeePass). Subclasses\n * implement `prefix` and `loadKeys()`. Locked until `unlock(credential)` is called.\n * @docLink packages/connectors/api-reference#locked-secret-provider\n */\nexport abstract class LockedSecretProvider implements SecretProvider {\n locked = true;\n protected readonly store = new Map<string, string>();\n abstract readonly prefix: string;\n\n async unlock(credential: string): Promise<void> {\n await this.loadKeys(credential);\n this.locked = false;\n }\n\n protected abstract loadKeys(credential: string): Promise<void>;\n\n resolve(ref: string): string | undefined {\n if (this.locked) return undefined;\n if (!ref.startsWith(this.prefix)) return undefined;\n return this.store.get(ref.slice(this.prefix.length));\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n if (this.locked) return [];\n return [...this.store.keys()].map((k) => `${this.prefix}${k}`);\n }\n}\n\n// ── Known provider prefixes ──────────────────────────────────────────────────\n\nconst KNOWN_PREFIXES = [\"env:\", \"forge:\", \"op:\", \"kp:\", \"oauth:\", \"mount:\", \"connector:\"] as const;\n\nfunction getPrefix(ref: string): string | undefined {\n return KNOWN_PREFIXES.find((p) => ref.startsWith(p));\n}\n\n/**\n * Chains multiple `SecretProvider` instances into a single resolver.\n * - Prefixed refs (`env:`, `forge:`, `op:`, `kp:`, `oauth:`) are routed to the first provider that can resolve them.\n * - Bare refs waterfall through all providers in order.\n * - Plain literals in `skaile.yaml` options are NOT passed to the chain; `ConnectorManager` handles them before calling `resolve()`.\n * @docLink packages/connectors/api-reference#secret-provider-chain\n */\nexport class SecretProviderChain implements SecretProvider {\n /**\n * @param providers - Ordered list of providers. For prefixed refs, the first\n * provider that can resolve wins. For bare refs, waterfall through all in order.\n */\n constructor(private readonly providers: SecretProvider[]) {}\n\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n const prefix = getPrefix(ref);\n log.debug(\"resolve secret\", { ref, prefix: prefix ?? \"(bare)\" });\n if (prefix) {\n for (const p of this.providers) {\n const val = p.resolve(ref);\n if (val !== undefined) return val;\n }\n log.warn(\"secret not resolvable\", { ref });\n return undefined;\n }\n // Waterfall for bare refs\n for (const p of this.providers) {\n const val = p.resolve(ref);\n if (val !== undefined) return val;\n }\n log.warn(\"secret not resolvable\", { ref });\n return undefined;\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n const all = this.providers.flatMap((p) => p.capabilities());\n return [...new Set(all)];\n }\n\n /** Returns the first provider that can resolve this ref. */\n providerFor(ref: string): SecretProvider | undefined {\n for (const p of this.providers) {\n if (p.resolve(ref) !== undefined) return p;\n }\n return undefined;\n }\n\n /**\n * Calls ensureFresh(ref) on the owning provider if it implements OAuthSecretProvider.\n * No-op for providers that don't have ensureFresh().\n *\n * @param ref - Must be an \"oauth:\" prefixed ref for this to have any effect.\n * Calls ensureFresh() on the owning OAuthSecretProvider.\n */\n async prepareRef(ref: string): Promise<void> {\n const owner = this.providerFor(ref);\n if (\n owner &&\n \"ensureFresh\" in owner &&\n typeof (owner as OAuthSecretProvider).ensureFresh === \"function\"\n ) {\n try {\n await (owner as OAuthSecretProvider).ensureFresh(ref);\n } catch (err) {\n log.error(\"secret provider ensureFresh failed\", err, { ref });\n throw err;\n }\n }\n }\n}\n","/**\n * Load connector declarations from skaile.yaml.\n *\n * The top-level `mounts:` key is no longer accepted (hard cut as of Task 11).\n * Filesystem-projected backends must be declared under `connectors:` with a\n * `mount:` sub-block. See `docs/migration-mounts-to-connectors.md`.\n */\n\nimport type { ConnectorDeclaration as WorkspaceConnector } from \"@skaile/workspaces/core\";\nimport { resolveSkWorkspaceConfig } from \"@skaile/workspaces/core\";\nimport type { ConnectorDeclaration } from \"./connector-types.js\";\n\n/**\n * Read `skaile.yaml` in `projectDir` and return all declared connectors as `ConnectorDeclaration[]`.\n *\n * Throws a migration error when the legacy top-level `mounts:` key is present.\n *\n * @param projectDir - Root of the workspace (directory containing `skaile.yaml`).\n * @returns Array of connector declarations, or an empty array if none are declared.\n * @docLink packages/connectors/api-reference#load-connector-declarations\n */\nexport function loadConnectorDeclarations(projectDir: string): ConnectorDeclaration[] {\n const config = resolveSkWorkspaceConfig(projectDir);\n\n // Hard cut: reject legacy top-level `mounts:` key with an actionable message.\n if (config.mounts && config.mounts.length > 0) {\n throw new Error(\n \"'mounts:' is no longer supported — move entries under 'connectors:' with a 'mount:' sub-block. See docs/migration-mounts-to-connectors.md\",\n );\n }\n\n if (!config.connectors || config.connectors.length === 0) return [];\n return config.connectors.map(workspaceConnectorToDeclaration);\n}\n\nfunction workspaceConnectorToDeclaration(c: WorkspaceConnector): ConnectorDeclaration {\n const decl: ConnectorDeclaration = {\n id: c.id,\n driver: c.driver,\n access: c.access ?? \"read-only\",\n auth: c.auth,\n options: c.options,\n };\n\n // Map the optional mount sub-block when present.\n if (c.mount) {\n decl.mount = {\n source: c.mount.source,\n target: c.mount.target,\n watch: c.mount.watch,\n exposeAccessToken: c.mount.exposeAccessToken,\n accessTokenTTL: c.mount.accessTokenTTL,\n };\n }\n\n return decl;\n}\n\nimport type { ForgeSecretProvider, SecretProvider } from \"./secrets.js\";\nimport { EnvSecretProvider, InMemorySecretProvider, SecretProviderChain } from \"./secrets.js\";\n\n/**\n * Build a `SecretProviderChain` for Forge session context.\n * `OAuthSecretProvider` is not wired here — it must be provided externally\n * (the Forge session manager constructs it and passes it in).\n * @param forgeProvider - The Forge-provisioned secret store.\n * @param extraProviders - Additional providers prepended to the chain (e.g. an OAuth provider).\n * @returns A chain that routes `forge:` refs to the Forge store and `env:` refs to process.env.\n * @docLink packages/connectors/api-reference#create-forge-secret-provider-chain\n */\nexport function createForgeSecretProviderChain(\n forgeProvider: ForgeSecretProvider,\n extraProviders: SecretProvider[] = [],\n): SecretProviderChain {\n return new SecretProviderChain([...extraProviders, forgeProvider, new EnvSecretProvider()]);\n}\n\n/**\n * Build a `SecretProviderChain` for CLI/standalone context.\n * `EnvSecretProvider` takes priority; `extraSecrets` are loaded into an `InMemorySecretProvider`.\n * @param extraSecrets - Inline secrets injected into memory (e.g. tokens passed via CLI flags).\n * @returns A chain that resolves `env:` refs from process.env plus any inline extras.\n * @docLink packages/connectors/api-reference#create-cli-secret-provider-chain\n */\nexport function createCliSecretProviderChain(\n extraSecrets: Record<string, string> = {},\n): SecretProviderChain {\n const mem = new InMemorySecretProvider();\n if (Object.keys(extraSecrets).length > 0) {\n mem.provision(extraSecrets);\n }\n return new SecretProviderChain([new EnvSecretProvider(), mem]);\n}\n\n/**\n * Resolve a credential reference using a `SecretProvider`, or fall back to `env:NAME` lookup.\n * @param auth - Credential reference (e.g. `\"env:GIT_TOKEN\"`).\n * @param secrets - Optional provider; falls back to `process.env` if omitted.\n * @returns Resolved secret value or `undefined`.\n * @deprecated Use `SecretProviderChain.resolve()` instead.\n * @docLink packages/connectors/api-reference#resolve-auth\n */\n// @TODO: Code-Review: deprecated shim kept for backward compat — remove once all callers migrate to SecretProviderChain.resolve()\nexport function resolveAuth(\n auth: string | undefined,\n secrets?: import(\"./secrets.js\").SecretProvider,\n): string | undefined {\n if (!auth) return undefined;\n if (secrets) return secrets.resolve(auth);\n if (auth.startsWith(\"env:\")) {\n const envVar = auth.slice(4);\n return process.env[envVar];\n }\n return auth;\n}\n\n// ── Auth grammar (mount-side, Tier 2 credential tiers) ───────────────────────\n\n/**\n * Provider kind for a mount auth ref.\n *\n * Two values are accepted:\n * - `pat` — static personal access token resolved via the secrets chain\n * (standalone CLI / non-platform contexts).\n * - `backend` — token minted by the platform's credential mediator over the\n * transport (`request_access_token` round-trip). Provider\n * dispatch (OAuth, GitHub App, ...) lives backend-side; the\n * runner stays provider-agnostic.\n *\n * @docLink packages/connectors/api-reference#mount-auth-kind\n */\nexport type MountAuthKind = \"pat\" | \"backend\";\n\n/**\n * Parsed mount `auth:` field.\n *\n * - `pat` → `value` is the inner secret ref (e.g. `env:NAME`).\n * - `backend` → `value` is empty (sentinel only); the runner asks the\n * backend for tokens via `request_access_token`.\n *\n * @docLink packages/connectors/api-reference#mount-auth-ref\n */\nexport interface MountAuthRef {\n kind: MountAuthKind;\n /** Prefix-stripped payload — see kind for shape. Empty for `backend`. */\n value: string;\n /** Original auth string from the declaration, kept for diagnostics. */\n raw: string;\n}\n\n/**\n * Thrown when a mount declaration's `auth:` field uses the legacy bare `env:NAME` grammar\n * or any other unrecognized form. Migrate to `pat:env:NAME` (standalone) or `backend`\n * (platform-mediated).\n * @docLink packages/connectors/api-reference#legacy-auth-grammar-error\n */\nexport class LegacyAuthGrammarError extends Error {\n readonly auth: string;\n constructor(auth: string, mountId?: string) {\n const where = mountId ? ` on mount '${mountId}'` : \"\";\n super(\n `Legacy or unrecognized auth grammar${where} ('${auth}'). ` +\n `Replace with one of:\\n` +\n ` - backend (platform-mediated, recommended)\\n` +\n ` - pat:env:NAME (standalone CLI / static token)\\n` +\n `See _devlog/specs/2026-05-06-tier-2-credential-mediation.md.`,\n );\n this.name = \"LegacyAuthGrammarError\";\n this.auth = auth;\n }\n}\n\n/**\n * Resolve the `auth: backend` initial mint for a given mount or connector id\n * by querying the secrets chain with a `${kind}:${id}` ref. Returns the\n * resolved bearer token or `undefined` if no pre-minted credential is\n * available.\n *\n * Used by the runner when wiring `ConnectorManager` to\n * answer initial-mint requests from `PreMintedSecretProvider` without\n * round-tripping to the platform. Drivers continue to receive a\n * `tokenMediator` for refresh + retry-401 paths.\n *\n * @param kind Resource family (`mount` or `connector`).\n * @param id Resource declaration id.\n * @param chain Secrets chain. Pass `undefined` to return `undefined`.\n * @returns The pre-minted token, or `undefined` if not stored on the chain.\n * @docLink packages/connectors/api-reference#resolve-backend-auth-for\n */\nexport function resolveBackendAuthFor(\n kind: \"mount\" | \"connector\",\n id: string,\n chain: import(\"./secrets.js\").SecretProvider | undefined,\n): string | undefined {\n if (!chain) return undefined;\n return chain.resolve(`${kind}:${id}`);\n}\n\n/**\n * Parse a mount-side auth ref into a typed `MountAuthRef`.\n *\n * Accepted forms:\n * - `backend` — platform-mediated mint via `request_access_token`.\n * - `pat:env:NAME` — static PAT resolved from the secrets chain.\n *\n * Rejects bare `env:NAME` (legacy) and provider-prefixed grammars (`oauth:`,\n * `github-app:`) — those moved backend-side as part of Tier-2 mediation.\n * Returns `undefined` when `auth` is absent or empty.\n *\n * @param auth - Raw `auth:` value from the mount declaration.\n * @param mountId - Optional mount id included in error messages.\n * @returns Parsed `MountAuthRef` or `undefined`.\n * @throws {LegacyAuthGrammarError} for any unrecognized grammar.\n * @docLink packages/connectors/api-reference#resolve-auth-ref\n */\nexport function resolveAuthRef(\n auth: string | undefined,\n mountId?: string,\n): MountAuthRef | undefined {\n if (!auth) return undefined;\n\n if (auth === \"backend\") {\n return { kind: \"backend\", value: \"\", raw: auth };\n }\n if (auth.startsWith(\"pat:\")) {\n return { kind: \"pat\", value: auth.slice(\"pat:\".length), raw: auth };\n }\n\n // Legacy bare `env:NAME` and the deprecated provider-prefixed grammars\n // (`oauth:`, `github-app:`) all land here.\n throw new LegacyAuthGrammarError(auth, mountId);\n}\n"]}
1
+ {"version":3,"sources":["../connectors/src/secrets.ts","../connectors/src/config.ts"],"names":[],"mappings":"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","file":"chunk-KJ2LLWRF.js","sourcesContent":["/**\n * Secret provider abstraction.\n *\n * Decouples credential resolution from process.env so secrets can be\n * provisioned over the transport bridge instead of living in the\n * container's environment.\n */\n\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\n\nconst log = createLogger({ kind: \"connector\", subkind: \"secrets\" });\n\n// ── Interfaces ──────────────────────────────────────────────────────────────\n\n/**\n * Read-only secret resolution. Adapters receive this interface.\n * @docLink packages/connectors/api-reference#secret-provider\n */\nexport interface SecretProvider {\n /**\n * Resolve a credential reference.\n *\n * @param ref - Credential reference such as \"env:GIT_TOKEN\",\n * \"oauth:google:user@example.com\", or an inline literal.\n * @returns The resolved secret value or undefined if not found.\n */\n resolve(ref: string): string | undefined;\n /**\n * Check whether a reference can be resolved.\n *\n * @param ref - Reference to check.\n * @returns True if resolve(ref) would return a non-undefined value.\n */\n has(ref: string): boolean;\n /**\n * Return all ref strings this provider can currently resolve.\n *\n * @returns All resolvable refs (used by forge UI and ConnectorFieldMissingError).\n */\n capabilities(): string[];\n}\n\n/**\n * Extends `SecretProvider` with the ability to load secrets at runtime via `provision()`.\n * @docLink packages/connectors/api-reference#provisionable-secret-provider\n */\nexport interface ProvisionableSecretProvider extends SecretProvider {\n /** Store a batch of key-value secrets. Keys are bare names (no prefix). */\n provision(secrets: Record<string, string>): void;\n}\n\n// ── Implementations ─────────────────────────────────────────────────────────\n\n/**\n * In-memory secret store. Secrets are provisioned over the transport bridge\n * and stored in a private Map — never touching the filesystem or process.env.\n *\n * Supports ref prefixes:\n * `\"env:KEY\"` — looks up KEY in the store\n * `\"vault:KEY\"` — looks up KEY in the store (future vault compat)\n * (no prefix) — returned as an inline value (backwards compat for non-chain usages)\n * @docLink packages/connectors/api-reference#in-memory-secret-provider\n */\nexport class InMemorySecretProvider implements ProvisionableSecretProvider {\n private readonly store = new Map<string, string>();\n\n /**\n * Store a batch of key-value secrets.\n *\n * @param secrets - Key-value map of secret names to values. Keys are bare names (no prefix).\n */\n provision(secrets: Record<string, string>): void {\n for (const [key, value] of Object.entries(secrets)) {\n this.store.set(key, value);\n }\n }\n\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n if (ref.startsWith(\"env:\")) return this.store.get(ref.slice(4));\n if (ref.startsWith(\"vault:\")) return this.store.get(ref.slice(6));\n // Bare key: check store first, then fall back to inline literal\n const stored = this.store.get(ref);\n if (stored !== undefined) return stored;\n return ref;\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n return [...this.store.keys()].map((k) => `env:${k}`);\n }\n}\n\n/**\n * Delegates to `process.env`. Used in CLI/standalone mode.\n * Does NOT pass through inline literals — returns `undefined` for any ref\n * that does not start with `\"env:\"`. Use `InMemorySecretProvider` for inline\n * literals in non-chain contexts.\n * @docLink packages/connectors/api-reference#env-secret-provider\n */\nexport class EnvSecretProvider implements SecretProvider {\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n if (ref.startsWith(\"env:\")) return process.env[ref.slice(4)];\n return undefined; // no inline passthrough\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n return Object.keys(process.env).map((k) => `env:${k}`);\n }\n}\n\n/**\n * Pre-minted credential entry. Mirrors the discriminated `CredentialMint`\n * shape from `@skaile/workspaces/types` but redeclared here to keep this package\n * free of cross-package type dependencies.\n *\n * The failure branch carries the platform-side `code` + `message` so the\n * `ConnectorManager`'s wrapped mediator can surface the real reason instead of\n * a generic \"no pre-mint\" placeholder when a mint comes back as `ok: false`.\n */\nexport type PreMintedCredential =\n | { ok: true; token: string; expiresAt: string | null; mintedAt?: string }\n | {\n ok: false;\n code?: \"not-configured\" | \"revoked\" | \"provider-error\" | \"backend-error\";\n message?: string;\n };\n\n/**\n * Pre-minted credential store. Holds short-lived tokens delivered upfront in\n * the v3 `session_init` envelope so the runner never has to call back to the\n * platform during mount setup.\n *\n * Resolves refs of the form `mount:<id>` and `connector:<id>`. Returns\n * `undefined` for any other ref so the chain falls through to the next\n * provider (`EnvSecretProvider` for `pat:env:NAME`, etc.).\n *\n * Tokens can be added/removed at runtime via {@link set} / {@link unset} so\n * `runner.add_mount` / `runner.add_connector` / `runner.update_credential`\n * capabilities stay strictly in-process — no round trip to the platform to\n * mint while the mount is hot-attached.\n *\n * For callers that need the full mint metadata (expiry timestamp, mintedAt\n * audit fields), use {@link mintFor} instead of the bare `resolve`. The\n * `ConnectorManager` consults this for the `auth: backend` initial-mint path so\n * the driver retains the original expiry semantics.\n *\n * Spec: `_devlog/specs/2026-05-10-deterministic-session-bootstrap.md`.\n *\n * @docLink packages/connectors/api-reference#pre-minted-secret-provider\n */\nexport class PreMintedSecretProvider implements SecretProvider {\n private readonly mints = new Map<string, PreMintedCredential>();\n\n /**\n * Seed pre-minted credentials from the v3 `session_init.credentials` map.\n *\n * Failed mints (`ok: false`) are stored too so callers can distinguish\n * \"not pre-minted\" from \"pre-minted but failed\"; {@link resolve} treats\n * both as `undefined`.\n *\n * @param credentials Optional initial `{ mounts, connectors }` map.\n */\n constructor(credentials?: {\n mounts?: Record<string, PreMintedCredential>;\n connectors?: Record<string, PreMintedCredential>;\n }) {\n if (!credentials) return;\n for (const [id, mint] of Object.entries(credentials.mounts ?? {})) {\n this.mints.set(`mount:${id}`, mint);\n }\n for (const [id, mint] of Object.entries(credentials.connectors ?? {})) {\n this.mints.set(`connector:${id}`, mint);\n }\n }\n\n /**\n * Insert (or replace) a pre-minted credential. Used by\n * `runner.add_mount` / `runner.add_connector` / `runner.update_credential`\n * capability handlers when the platform delivers new credentials\n * mid-session.\n */\n set(kind: \"mount\" | \"connector\", id: string, mint: PreMintedCredential): void {\n this.mints.set(`${kind}:${id}`, mint);\n }\n\n /**\n * Remove a stored pre-minted credential. Used by the\n * `runner.remove_resource` capability handler.\n */\n unset(kind: \"mount\" | \"connector\", id: string): boolean {\n return this.mints.delete(`${kind}:${id}`);\n }\n\n /**\n * Look up the full {@link PreMintedCredential} for a `mount:` /\n * `connector:` keyed entry. Callers that only need the token use\n * {@link resolve} via the chain; callers that need expiry / audit\n * metadata (e.g. ConnectorManager) use this entry point.\n */\n mintFor(kind: \"mount\" | \"connector\", id: string): PreMintedCredential | undefined {\n return this.mints.get(`${kind}:${id}`);\n }\n\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n if (!(ref.startsWith(\"mount:\") || ref.startsWith(\"connector:\"))) return undefined;\n const mint = this.mints.get(ref);\n return mint?.ok ? mint.token : undefined;\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n return [...this.mints.entries()].filter(([, m]) => m.ok).map(([k]) => k);\n }\n}\n\n/**\n * Forge session secret provider. Secrets are provisioned from the Forge settings\n * panel over the transport bridge. Only handles `\"forge:\"` prefixed refs — returns\n * `undefined` for all others.\n * @docLink packages/connectors/api-reference#forge-secret-provider\n */\nexport class ForgeSecretProvider implements ProvisionableSecretProvider {\n private readonly store = new Map<string, string>();\n\n provision(secrets: Record<string, string>): void {\n for (const [key, value] of Object.entries(secrets)) {\n this.store.set(key, value);\n }\n }\n\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n if (ref.startsWith(\"forge:\")) return this.store.get(ref.slice(6));\n return undefined;\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n return [...this.store.keys()].map((k) => `forge:${k}`);\n }\n}\n\n/**\n * Thrown when an OAuth-secured connector field requires user authorization before\n * it can be resolved. Contains the redirect URL to open in the user's browser.\n * @docLink packages/connectors/api-reference#o-auth-required-error\n */\nexport class OAuthRequiredError extends Error {\n readonly oauthRef: string;\n readonly authUrl: string;\n readonly state: string;\n\n /**\n * @param oauthRef - The 'oauth:<service>:<account>' ref that triggered the error\n * @param authUrl - Browser URL to open for OAuth authorization\n * @param state - OAuth state token for CSRF protection and callback correlation\n */\n constructor(oauthRef: string, authUrl: string, state: string) {\n super(`OAuth authorization required for ${oauthRef}`);\n this.name = \"OAuthRequiredError\";\n this.oauthRef = oauthRef;\n this.authUrl = authUrl;\n this.state = state;\n }\n}\n\n/**\n * Shape of an OAuth token bundle stored by `OAuthSecretProvider`.\n * @docLink packages/connectors/api-reference#o-auth-token-bundle\n */\nexport interface OAuthTokenBundle {\n accessToken: string;\n refreshToken?: string;\n /** Unix timestamp in ms */\n expiry?: number;\n}\n\n/**\n * Return value of `OAuthSecretProvider.initiateFlow()`. Contains the URL and CSRF state token.\n * @docLink packages/connectors/api-reference#o-auth-flow-request\n */\nexport interface OAuthFlowRequest {\n authUrl: string;\n state: string;\n}\n\n/**\n * OAuth token provider. Handles `\"oauth:<service>:<account>\"` refs.\n * Callers must call `chain.prepareRef()` before `chain.resolve()` for `oauth:` refs.\n * @docLink packages/connectors/api-reference#o-auth-secret-provider\n */\nexport interface OAuthSecretProvider extends SecretProvider {\n /**\n * Ensure the token for this ref is fresh.\n * Refreshes if expired.\n * Throws OAuthRequiredError if no token exists and user authorization is needed.\n */\n ensureFresh(ref: string): Promise<void>;\n\n /** Initiate the OAuth authorization flow. Returns URL to open in the user's browser. */\n initiateFlow(oauthService: string, account: string): Promise<OAuthFlowRequest>;\n\n /** Exchange authorization code for tokens and store the bundle. */\n completeFlow(state: string, code: string): Promise<void>;\n}\n\n/**\n * Abstract base for vault-backed secret providers (1Password, KeePass). Subclasses\n * implement `prefix` and `loadKeys()`. Locked until `unlock(credential)` is called.\n * @docLink packages/connectors/api-reference#locked-secret-provider\n */\nexport abstract class LockedSecretProvider implements SecretProvider {\n locked = true;\n protected readonly store = new Map<string, string>();\n abstract readonly prefix: string;\n\n async unlock(credential: string): Promise<void> {\n await this.loadKeys(credential);\n this.locked = false;\n }\n\n protected abstract loadKeys(credential: string): Promise<void>;\n\n resolve(ref: string): string | undefined {\n if (this.locked) return undefined;\n if (!ref.startsWith(this.prefix)) return undefined;\n return this.store.get(ref.slice(this.prefix.length));\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n if (this.locked) return [];\n return [...this.store.keys()].map((k) => `${this.prefix}${k}`);\n }\n}\n\n// ── Known provider prefixes ──────────────────────────────────────────────────\n\nconst KNOWN_PREFIXES = [\"env:\", \"forge:\", \"op:\", \"kp:\", \"oauth:\", \"mount:\", \"connector:\"] as const;\n\nfunction getPrefix(ref: string): string | undefined {\n return KNOWN_PREFIXES.find((p) => ref.startsWith(p));\n}\n\n/**\n * Chains multiple `SecretProvider` instances into a single resolver.\n * - Prefixed refs (`env:`, `forge:`, `op:`, `kp:`, `oauth:`) are routed to the first provider that can resolve them.\n * - Bare refs waterfall through all providers in order.\n * - Plain literals in `skaile.yaml` options are NOT passed to the chain; `ConnectorManager` handles them before calling `resolve()`.\n * @docLink packages/connectors/api-reference#secret-provider-chain\n */\nexport class SecretProviderChain implements SecretProvider {\n /**\n * @param providers - Ordered list of providers. For prefixed refs, the first\n * provider that can resolve wins. For bare refs, waterfall through all in order.\n */\n constructor(private readonly providers: SecretProvider[]) {}\n\n resolve(ref: string): string | undefined {\n if (!ref) return undefined;\n const prefix = getPrefix(ref);\n log.debug(\"resolve secret\", { ref, prefix: prefix ?? \"(bare)\" });\n if (prefix) {\n for (const p of this.providers) {\n const val = p.resolve(ref);\n if (val !== undefined) return val;\n }\n log.warn(\"secret not resolvable\", { ref });\n return undefined;\n }\n // Waterfall for bare refs\n for (const p of this.providers) {\n const val = p.resolve(ref);\n if (val !== undefined) return val;\n }\n log.warn(\"secret not resolvable\", { ref });\n return undefined;\n }\n\n has(ref: string): boolean {\n return this.resolve(ref) !== undefined;\n }\n\n capabilities(): string[] {\n const all = this.providers.flatMap((p) => p.capabilities());\n return [...new Set(all)];\n }\n\n /** Returns the first provider that can resolve this ref. */\n providerFor(ref: string): SecretProvider | undefined {\n for (const p of this.providers) {\n if (p.resolve(ref) !== undefined) return p;\n }\n return undefined;\n }\n\n /**\n * Calls ensureFresh(ref) on the owning provider if it implements OAuthSecretProvider.\n * No-op for providers that don't have ensureFresh().\n *\n * @param ref - Must be an \"oauth:\" prefixed ref for this to have any effect.\n * Calls ensureFresh() on the owning OAuthSecretProvider.\n */\n async prepareRef(ref: string): Promise<void> {\n const owner = this.providerFor(ref);\n if (\n owner &&\n \"ensureFresh\" in owner &&\n typeof (owner as OAuthSecretProvider).ensureFresh === \"function\"\n ) {\n try {\n await (owner as OAuthSecretProvider).ensureFresh(ref);\n } catch (err) {\n log.error(\"secret provider ensureFresh failed\", err, { ref });\n throw err;\n }\n }\n }\n}\n","/**\n * Load connector declarations from skaile.yaml.\n *\n * The top-level `mounts:` key is no longer accepted (hard cut as of Task 11).\n * Filesystem-projected backends must be declared under `connectors:` with a\n * `mount:` sub-block. See `docs/migration-mounts-to-connectors.md`.\n */\n\nimport type { ConnectorDeclaration as WorkspaceConnector } from \"@skaile/workspaces/core\";\nimport { resolveSkWorkspaceConfig } from \"@skaile/workspaces/core\";\nimport type { ConnectorDeclaration } from \"./connector-types.js\";\n\n/**\n * Read `skaile.yaml` in `projectDir` and return all declared connectors as `ConnectorDeclaration[]`.\n *\n * Throws a migration error when the legacy top-level `mounts:` key is present.\n *\n * @param projectDir - Root of the workspace (directory containing `skaile.yaml`).\n * @returns Array of connector declarations, or an empty array if none are declared.\n * @docLink packages/connectors/api-reference#load-connector-declarations\n */\nexport function loadConnectorDeclarations(projectDir: string): ConnectorDeclaration[] {\n const config = resolveSkWorkspaceConfig(projectDir);\n\n // Hard cut: reject legacy top-level `mounts:` key with an actionable message.\n if (config.mounts && config.mounts.length > 0) {\n throw new Error(\n \"'mounts:' is no longer supported — move entries under 'connectors:' with a 'mount:' sub-block. See docs/migration-mounts-to-connectors.md\",\n );\n }\n\n if (!config.connectors || config.connectors.length === 0) return [];\n return config.connectors.map(workspaceConnectorToDeclaration);\n}\n\nfunction workspaceConnectorToDeclaration(c: WorkspaceConnector): ConnectorDeclaration {\n const decl: ConnectorDeclaration = {\n id: c.id,\n driver: c.driver,\n access: c.access ?? \"read-only\",\n auth: c.auth,\n options: c.options,\n };\n\n // Map the optional mount sub-block when present.\n if (c.mount) {\n decl.mount = {\n source: c.mount.source,\n target: c.mount.target,\n watch: c.mount.watch,\n exposeAccessToken: c.mount.exposeAccessToken,\n accessTokenTTL: c.mount.accessTokenTTL,\n };\n }\n\n return decl;\n}\n\nimport type { ForgeSecretProvider, SecretProvider } from \"./secrets.js\";\nimport { EnvSecretProvider, InMemorySecretProvider, SecretProviderChain } from \"./secrets.js\";\n\n/**\n * Build a `SecretProviderChain` for Forge session context.\n * `OAuthSecretProvider` is not wired here — it must be provided externally\n * (the Forge session manager constructs it and passes it in).\n * @param forgeProvider - The Forge-provisioned secret store.\n * @param extraProviders - Additional providers prepended to the chain (e.g. an OAuth provider).\n * @returns A chain that routes `forge:` refs to the Forge store and `env:` refs to process.env.\n * @docLink packages/connectors/api-reference#create-forge-secret-provider-chain\n */\nexport function createForgeSecretProviderChain(\n forgeProvider: ForgeSecretProvider,\n extraProviders: SecretProvider[] = [],\n): SecretProviderChain {\n return new SecretProviderChain([...extraProviders, forgeProvider, new EnvSecretProvider()]);\n}\n\n/**\n * Build a `SecretProviderChain` for CLI/standalone context.\n * `EnvSecretProvider` takes priority; `extraSecrets` are loaded into an `InMemorySecretProvider`.\n * @param extraSecrets - Inline secrets injected into memory (e.g. tokens passed via CLI flags).\n * @returns A chain that resolves `env:` refs from process.env plus any inline extras.\n * @docLink packages/connectors/api-reference#create-cli-secret-provider-chain\n */\nexport function createCliSecretProviderChain(\n extraSecrets: Record<string, string> = {},\n): SecretProviderChain {\n const mem = new InMemorySecretProvider();\n if (Object.keys(extraSecrets).length > 0) {\n mem.provision(extraSecrets);\n }\n return new SecretProviderChain([new EnvSecretProvider(), mem]);\n}\n\n/**\n * Resolve a credential reference using a `SecretProvider`, or fall back to `env:NAME` lookup.\n * @param auth - Credential reference (e.g. `\"env:GIT_TOKEN\"`).\n * @param secrets - Optional provider; falls back to `process.env` if omitted.\n * @returns Resolved secret value or `undefined`.\n * @deprecated Use `SecretProviderChain.resolve()` instead.\n * @docLink packages/connectors/api-reference#resolve-auth\n */\n// @TODO: Code-Review: deprecated shim kept for backward compat — remove once all callers migrate to SecretProviderChain.resolve()\nexport function resolveAuth(\n auth: string | undefined,\n secrets?: import(\"./secrets.js\").SecretProvider,\n): string | undefined {\n if (!auth) return undefined;\n if (secrets) return secrets.resolve(auth);\n if (auth.startsWith(\"env:\")) {\n const envVar = auth.slice(4);\n return process.env[envVar];\n }\n return auth;\n}\n\n// ── Auth grammar (mount-side, Tier 2 credential tiers) ───────────────────────\n\n/**\n * Provider kind for a mount auth ref.\n *\n * Two values are accepted:\n * - `pat` — static personal access token resolved via the secrets chain\n * (standalone CLI / non-platform contexts).\n * - `backend` — token minted by the platform's credential mediator over the\n * transport (`request_access_token` round-trip). Provider\n * dispatch (OAuth, GitHub App, ...) lives backend-side; the\n * runner stays provider-agnostic.\n *\n * @docLink packages/connectors/api-reference#mount-auth-kind\n */\nexport type MountAuthKind = \"pat\" | \"backend\";\n\n/**\n * Parsed mount `auth:` field.\n *\n * - `pat` → `value` is the inner secret ref (e.g. `env:NAME`).\n * - `backend` → `value` is empty (sentinel only); the runner asks the\n * backend for tokens via `request_access_token`.\n *\n * @docLink packages/connectors/api-reference#mount-auth-ref\n */\nexport interface MountAuthRef {\n kind: MountAuthKind;\n /** Prefix-stripped payload — see kind for shape. Empty for `backend`. */\n value: string;\n /** Original auth string from the declaration, kept for diagnostics. */\n raw: string;\n}\n\n/**\n * Thrown when a mount declaration's `auth:` field uses the legacy bare `env:NAME` grammar\n * or any other unrecognized form. Migrate to `pat:env:NAME` (standalone) or `backend`\n * (platform-mediated).\n * @docLink packages/connectors/api-reference#legacy-auth-grammar-error\n */\nexport class LegacyAuthGrammarError extends Error {\n readonly auth: string;\n constructor(auth: string, mountId?: string) {\n const where = mountId ? ` on mount '${mountId}'` : \"\";\n super(\n `Legacy or unrecognized auth grammar${where} ('${auth}'). ` +\n `Replace with one of:\\n` +\n ` - backend (platform-mediated, recommended)\\n` +\n ` - pat:env:NAME (standalone CLI / static token)\\n` +\n `See _devlog/specs/2026-05-06-tier-2-credential-mediation.md.`,\n );\n this.name = \"LegacyAuthGrammarError\";\n this.auth = auth;\n }\n}\n\n/**\n * Resolve the `auth: backend` initial mint for a given mount or connector id\n * by querying the secrets chain with a `${kind}:${id}` ref. Returns the\n * resolved bearer token or `undefined` if no pre-minted credential is\n * available.\n *\n * Used by the runner when wiring `ConnectorManager` to\n * answer initial-mint requests from `PreMintedSecretProvider` without\n * round-tripping to the platform. Drivers continue to receive a\n * `tokenMediator` for refresh + retry-401 paths.\n *\n * @param kind Resource family (`mount` or `connector`).\n * @param id Resource declaration id.\n * @param chain Secrets chain. Pass `undefined` to return `undefined`.\n * @returns The pre-minted token, or `undefined` if not stored on the chain.\n * @docLink packages/connectors/api-reference#resolve-backend-auth-for\n */\nexport function resolveBackendAuthFor(\n kind: \"mount\" | \"connector\",\n id: string,\n chain: import(\"./secrets.js\").SecretProvider | undefined,\n): string | undefined {\n if (!chain) return undefined;\n return chain.resolve(`${kind}:${id}`);\n}\n\n/**\n * Parse a mount-side auth ref into a typed `MountAuthRef`.\n *\n * Accepted forms:\n * - `backend` — platform-mediated mint via `request_access_token`.\n * - `pat:env:NAME` — static PAT resolved from the secrets chain.\n *\n * Rejects bare `env:NAME` (legacy) and provider-prefixed grammars (`oauth:`,\n * `github-app:`) — those moved backend-side as part of Tier-2 mediation.\n * Returns `undefined` when `auth` is absent or empty.\n *\n * @param auth - Raw `auth:` value from the mount declaration.\n * @param mountId - Optional mount id included in error messages.\n * @returns Parsed `MountAuthRef` or `undefined`.\n * @throws {LegacyAuthGrammarError} for any unrecognized grammar.\n * @docLink packages/connectors/api-reference#resolve-auth-ref\n */\nexport function resolveAuthRef(\n auth: string | undefined,\n mountId?: string,\n): MountAuthRef | undefined {\n if (!auth) return undefined;\n\n if (auth === \"backend\") {\n return { kind: \"backend\", value: \"\", raw: auth };\n }\n if (auth.startsWith(\"pat:\")) {\n return { kind: \"pat\", value: auth.slice(\"pat:\".length), raw: auth };\n }\n\n // Legacy bare `env:NAME` and the deprecated provider-prefixed grammars\n // (`oauth:`, `github-app:`) all land here.\n throw new LegacyAuthGrammarError(auth, mountId);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { globalSettingsPath, mapLegacyFields } from './chunk-4RUVG5GX.js';
1
+ import { globalSettingsPath, mapLegacyFields } from './chunk-4BRSVK7Q.js';
2
2
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
3
3
  import { homedir } from 'os';
4
4
  import { join } from 'path';
@@ -89,5 +89,5 @@ function isStoreAuthenticated(config) {
89
89
  }
90
90
 
91
91
  export { clearStoreTokens, getStoreConfig, isStoreAuthenticated, saveStoreTokens, storeFetch };
92
- //# sourceMappingURL=chunk-6DEGWPAR.js.map
93
- //# sourceMappingURL=chunk-6DEGWPAR.js.map
92
+ //# sourceMappingURL=chunk-SMFZFFIZ.js.map
93
+ //# sourceMappingURL=chunk-SMFZFFIZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":"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","file":"chunk-6DEGWPAR.js","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\n\n/**\n * Connection configuration for the AI Asset Store API.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n refreshToken: string | null;\n}\n\n/**\n * Read store connection config from global user settings, falling back to\n * `SKAILE_STORE_URL` env var and the default store URL.\n *\n * @returns Populated {@link StoreConfig} with `url`, `jwt`, and `refreshToken`.\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://store.skaile.ai\",\n jwt: settings.storeJwt ?? null,\n refreshToken: settings.storeRefreshToken ?? null,\n };\n}\n\n/** Path to user-level settings */\nfunction userSettingsPath(): string {\n return join(homedir(), \".skaile\", \"settings.json\");\n}\n\n/**\n * Persist store authentication tokens to `~/.skaile/settings.json`.\n *\n * @param jwt - The JWT access token returned by the store login endpoint.\n * @param refreshToken - The refresh token for obtaining new JWTs.\n * @docLink cli/dev-guide#store-client\n */\nexport function saveStoreTokens(jwt: string, refreshToken: string): void {\n const settingsPath = userSettingsPath();\n const dir = join(settingsPath, \"..\");\n mkdirSync(dir, { recursive: true });\n\n let current: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n current = JSON.parse(readFileSync(settingsPath, \"utf-8\"));\n } catch {\n current = {};\n }\n }\n\n current.storeJwt = jwt;\n current.storeRefreshToken = refreshToken;\n writeFileSync(settingsPath, JSON.stringify(current, null, 2), \"utf-8\");\n}\n\n/**\n * Remove store authentication tokens from `~/.skaile/settings.json`.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function clearStoreTokens(): void {\n const settingsPath = userSettingsPath();\n if (!existsSync(settingsPath)) return;\n\n try {\n const current = JSON.parse(readFileSync(settingsPath, \"utf-8\"));\n delete current.storeJwt;\n delete current.storeRefreshToken;\n writeFileSync(settingsPath, JSON.stringify(current, null, 2), \"utf-8\");\n } catch {\n // ignore\n }\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API with a 1.5s timeout.\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, and extra headers.\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 },\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(), 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 throw new Error((body as any).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` if a JWT token is present in the provided (or default) store config.\n *\n * @param config - Optional pre-loaded config; if omitted, calls {@link getStoreConfig}.\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(config?: StoreConfig): boolean {\n const c = config ?? getStoreConfig();\n return !!c.jwt;\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":"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","file":"chunk-SMFZFFIZ.js","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\n\n/**\n * Connection configuration for the AI Asset Store API.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n refreshToken: string | null;\n}\n\n/**\n * Read store connection config from global user settings, falling back to\n * `SKAILE_STORE_URL` env var and the default store URL.\n *\n * @returns Populated {@link StoreConfig} with `url`, `jwt`, and `refreshToken`.\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://store.skaile.ai\",\n jwt: settings.storeJwt ?? null,\n refreshToken: settings.storeRefreshToken ?? null,\n };\n}\n\n/** Path to user-level settings */\nfunction userSettingsPath(): string {\n return join(homedir(), \".skaile\", \"settings.json\");\n}\n\n/**\n * Persist store authentication tokens to `~/.skaile/settings.json`.\n *\n * @param jwt - The JWT access token returned by the store login endpoint.\n * @param refreshToken - The refresh token for obtaining new JWTs.\n * @docLink cli/dev-guide#store-client\n */\nexport function saveStoreTokens(jwt: string, refreshToken: string): void {\n const settingsPath = userSettingsPath();\n const dir = join(settingsPath, \"..\");\n mkdirSync(dir, { recursive: true });\n\n let current: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n current = JSON.parse(readFileSync(settingsPath, \"utf-8\"));\n } catch {\n current = {};\n }\n }\n\n current.storeJwt = jwt;\n current.storeRefreshToken = refreshToken;\n writeFileSync(settingsPath, JSON.stringify(current, null, 2), \"utf-8\");\n}\n\n/**\n * Remove store authentication tokens from `~/.skaile/settings.json`.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function clearStoreTokens(): void {\n const settingsPath = userSettingsPath();\n if (!existsSync(settingsPath)) return;\n\n try {\n const current = JSON.parse(readFileSync(settingsPath, \"utf-8\"));\n delete current.storeJwt;\n delete current.storeRefreshToken;\n writeFileSync(settingsPath, JSON.stringify(current, null, 2), \"utf-8\");\n } catch {\n // ignore\n }\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API with a 1.5s timeout.\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, and extra headers.\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 },\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(), 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 throw new Error((body as any).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` if a JWT token is present in the provided (or default) store config.\n *\n * @param config - Optional pre-loaded config; if omitted, calls {@link getStoreConfig}.\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(config?: StoreConfig): boolean {\n const c = config ?? getStoreConfig();\n return !!c.jwt;\n}\n"]}
@@ -516,7 +516,9 @@ function mergeSkWorkspaceConfigs(base, overlay) {
516
516
  // from `ai_resources[]` entries.
517
517
  repositories: {},
518
518
  // dependencies: concatenate and dedupe
519
- dependencies: dedupe([...base.dependencies ?? [], ...overlay.dependencies ?? []])
519
+ dependencies: dedupe([...base.dependencies ?? [], ...overlay.dependencies ?? []]),
520
+ // sources: dedupe by name — overlay entry wins for the same name
521
+ sources: dedupeByKey([...base.sources ?? [], ...overlay.sources ?? []], "name")
520
522
  };
521
523
  }
522
524
  function normalizeConfig(raw) {
@@ -566,6 +568,20 @@ function normalizeConfig(raw) {
566
568
  if (Array.isArray(raw.dependencies)) {
567
569
  config.dependencies = raw.dependencies.filter((d) => typeof d === "string");
568
570
  }
571
+ if (Array.isArray(raw.sources)) {
572
+ const entries = [];
573
+ for (const item of raw.sources) {
574
+ if (!item || typeof item !== "object") continue;
575
+ const s = item;
576
+ const name = typeof s.name === "string" ? s.name : "";
577
+ const url = typeof s.url === "string" ? s.url : "";
578
+ if (!name || !url) continue;
579
+ const entry = { name, url };
580
+ if (typeof s.branch === "string" && s.branch.length > 0) entry.branch = s.branch;
581
+ entries.push(entry);
582
+ }
583
+ if (entries.length > 0) config.sources = entries;
584
+ }
569
585
  if (raw.telemetry && typeof raw.telemetry === "object" && !Array.isArray(raw.telemetry)) {
570
586
  config.telemetry = raw.telemetry;
571
587
  }
@@ -743,5 +759,5 @@ function resolveAgentDir(projectDir) {
743
759
  }
744
760
 
745
761
  export { COMPACTION_DEFAULTS, SKAILE_YAML_DEFAULT, SKAILE_YAML_SUFFIX, SK_WORKSPACE_DEFAULT_NAME, SK_WORKSPACE_SUFFIX, checkRepoStatus, checkoutPin, cloneRepo, ensureRepo, findWorkspaceRoot, getGlobalCacheDir, getRepoCommit, isWorkspaceConfigFilename, linkRepo, listSkWorkspaceConfigs, loadMcpServerDeclarations, loadSkWorkspaceConfig, mergeSkWorkspaceConfigs, normalizeConfig, pullRepo, readLinks, resolveAgentDir, resolveAll, resolveAsset, resolveSkWorkspaceConfig, saveSkWorkspaceConfig, scanRepo, unlinkRepo, validateAssetRecipeAttr, workspaceConfigFilename, workspaceNameFromFilename, writeLinks };
746
- //# sourceMappingURL=chunk-GAZINYCS.js.map
747
- //# sourceMappingURL=chunk-GAZINYCS.js.map
762
+ //# sourceMappingURL=chunk-SOQMVRQL.js.map
763
+ //# sourceMappingURL=chunk-SOQMVRQL.js.map