@skaile/workspaces 0.33.0 → 0.34.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 (107) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/{asset-feeds-DX5JPM76.js → asset-feeds-6R2C2NHB.js} +7 -7
  3. package/dist/{asset-feeds-DX5JPM76.js.map → asset-feeds-6R2C2NHB.js.map} +1 -1
  4. package/dist/asset-manager/index.js +5 -5
  5. package/dist/asset-manager/installer.js +4 -4
  6. package/dist/{chunk-RQG5TXIR.js → chunk-2VM62DX7.js} +3 -3
  7. package/dist/{chunk-RQG5TXIR.js.map → chunk-2VM62DX7.js.map} +1 -1
  8. package/dist/{chunk-R2I7RHT7.js → chunk-4RSCLQYX.js} +190 -22
  9. package/dist/chunk-4RSCLQYX.js.map +1 -0
  10. package/dist/{chunk-KKERAIPQ.js → chunk-5JAQVXPV.js} +2 -2
  11. package/dist/{chunk-KKERAIPQ.js.map → chunk-5JAQVXPV.js.map} +1 -1
  12. package/dist/{chunk-XQRAXAL5.js → chunk-BKE2E5AC.js} +6 -6
  13. package/dist/{chunk-XQRAXAL5.js.map → chunk-BKE2E5AC.js.map} +1 -1
  14. package/dist/{chunk-PTDVTMQL.js → chunk-DHN6VW4B.js} +4 -4
  15. package/dist/{chunk-PTDVTMQL.js.map → chunk-DHN6VW4B.js.map} +1 -1
  16. package/dist/{chunk-PKPUVQJP.js → chunk-DVIIYYD5.js} +3 -3
  17. package/dist/{chunk-PKPUVQJP.js.map → chunk-DVIIYYD5.js.map} +1 -1
  18. package/dist/{chunk-AZODLVKH.js → chunk-E5VRPYUX.js} +2 -2
  19. package/dist/{chunk-AZODLVKH.js.map → chunk-E5VRPYUX.js.map} +1 -1
  20. package/dist/{chunk-EJZFQCQG.js → chunk-FM2BJYX4.js} +2 -2
  21. package/dist/{chunk-EJZFQCQG.js.map → chunk-FM2BJYX4.js.map} +1 -1
  22. package/dist/{chunk-BUMDC3R2.js → chunk-JLSK6HR4.js} +5 -5
  23. package/dist/{chunk-BUMDC3R2.js.map → chunk-JLSK6HR4.js.map} +1 -1
  24. package/dist/{chunk-4ZVS6KV4.js → chunk-QLHOORR7.js} +2 -2
  25. package/dist/{chunk-4ZVS6KV4.js.map → chunk-QLHOORR7.js.map} +1 -1
  26. package/dist/{chunk-LRFZNLB2.js → chunk-UQ5JY2GQ.js} +3 -3
  27. package/dist/{chunk-LRFZNLB2.js.map → chunk-UQ5JY2GQ.js.map} +1 -1
  28. package/dist/{chunk-VXW2K4YH.js → chunk-VSLSRDQZ.js} +3 -3
  29. package/dist/{chunk-VXW2K4YH.js.map → chunk-VSLSRDQZ.js.map} +1 -1
  30. package/dist/{chunk-QUWXW2N3.js → chunk-W6TLIJG3.js} +3 -3
  31. package/dist/{chunk-QUWXW2N3.js.map → chunk-W6TLIJG3.js.map} +1 -1
  32. package/dist/{chunk-362QBS57.js → chunk-WQRDLR3K.js} +211 -11
  33. package/dist/chunk-WQRDLR3K.js.map +1 -0
  34. package/dist/cli/index.js +28 -28
  35. package/dist/connectors/config.js +4 -4
  36. package/dist/connectors/index.js +5 -5
  37. package/dist/connectors/src/connector-manager.d.ts +56 -3
  38. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  39. package/dist/connectors/src/fleet-health-gate.d.ts +86 -0
  40. package/dist/connectors/src/fleet-health-gate.d.ts.map +1 -0
  41. package/dist/connectors/src/fleet-utils.d.ts +16 -0
  42. package/dist/connectors/src/fleet-utils.d.ts.map +1 -1
  43. package/dist/connectors/src/index.d.ts +4 -1
  44. package/dist/connectors/src/index.d.ts.map +1 -1
  45. package/dist/core/index.js +3 -3
  46. package/dist/core/runtime-assets.js +2 -2
  47. package/dist/core/src/workspace-config.d.ts +13 -0
  48. package/dist/core/src/workspace-config.d.ts.map +1 -1
  49. package/dist/core/workspace-config.js +1 -1
  50. package/dist/deploy/index.js +3 -3
  51. package/dist/{ensure-sources-O6RMWP6C.js → ensure-sources-GYEQ65ET.js} +5 -5
  52. package/dist/{ensure-sources-O6RMWP6C.js.map → ensure-sources-GYEQ65ET.js.map} +1 -1
  53. package/dist/factory-assets/connectors/deploy.js +5 -5
  54. package/dist/factory-assets/connectors/devserver.js +5 -5
  55. package/dist/factory-assets/connectors/flow/adapter.js +5 -5
  56. package/dist/factory-assets/connectors/flow/engine.js +3 -3
  57. package/dist/factory-assets/connectors/flow/run-flow.js +6 -6
  58. package/dist/factory-assets/connectors/flow.js +5 -5
  59. package/dist/factory-assets/connectors/git.js +5 -5
  60. package/dist/factory-assets/connectors/gmail.js +5 -5
  61. package/dist/factory-assets/connectors/googledrive.js +5 -5
  62. package/dist/factory-assets/connectors/local.js +5 -5
  63. package/dist/factory-assets/connectors/mattermost.js +5 -5
  64. package/dist/factory-assets/connectors/memory.js +5 -5
  65. package/dist/factory-assets/connectors/minio.js +5 -5
  66. package/dist/factory-assets/connectors/postgres.js +5 -5
  67. package/dist/factory-assets/connectors/s3.js +5 -5
  68. package/dist/factory-assets/connectors/sharepoint.js +5 -5
  69. package/dist/factory-assets/connectors/sqlite.js +5 -5
  70. package/dist/factory-assets/connectors/static-server.js +5 -5
  71. package/dist/factory-assets/connectors/tunnel.js +5 -5
  72. package/dist/factory-assets/connectors/webdav.js +5 -5
  73. package/dist/factory-assets/connectors/xstate-store.js +5 -5
  74. package/dist/factory-assets/connectors/xstate.js +5 -5
  75. package/dist/{flows-QWYIUDA2.js → flows-TJUVSMRR.js} +3 -3
  76. package/dist/{flows-QWYIUDA2.js.map → flows-TJUVSMRR.js.map} +1 -1
  77. package/dist/library/index.js +3 -3
  78. package/dist/library/install.js +3 -3
  79. package/dist/{open-library-B7BLYXYK.js → open-library-GPZUB7N3.js} +6 -6
  80. package/dist/{open-library-B7BLYXYK.js.map → open-library-GPZUB7N3.js.map} +1 -1
  81. package/dist/{paths-5IUR235S.js → paths-R6WA7PKV.js} +6 -6
  82. package/dist/{paths-5IUR235S.js.map → paths-R6WA7PKV.js.map} +1 -1
  83. package/dist/{plugin-store-WWOJXWG7.js → plugin-store-TF7GECYJ.js} +5 -5
  84. package/dist/{plugin-store-WWOJXWG7.js.map → plugin-store-TF7GECYJ.js.map} +1 -1
  85. package/dist/runner/index.js +7 -7
  86. package/dist/runner/src/external-mcp.d.ts +45 -4
  87. package/dist/runner/src/external-mcp.d.ts.map +1 -1
  88. package/dist/runner/src/fleet-health-flag-dispatcher.d.ts +40 -0
  89. package/dist/runner/src/fleet-health-flag-dispatcher.d.ts.map +1 -0
  90. package/dist/runner/src/resources.d.ts.map +1 -1
  91. package/dist/runner/src/serve.d.ts.map +1 -1
  92. package/dist/sdk/asset-manager.js +5 -5
  93. package/dist/sdk/core.js +3 -3
  94. package/dist/sdk/flow.js +3 -3
  95. package/dist/sdk/index.js +7 -7
  96. package/dist/sdk/runner.js +7 -7
  97. package/dist/{setup-2RD6EDBZ.js → setup-YKL43RQJ.js} +5 -5
  98. package/dist/{setup-2RD6EDBZ.js.map → setup-YKL43RQJ.js.map} +1 -1
  99. package/dist/{store-client-XQQRHYDW.js → store-client-H7MHTZVU.js} +6 -6
  100. package/dist/{store-client-XQQRHYDW.js.map → store-client-H7MHTZVU.js.map} +1 -1
  101. package/dist/tui/index.js +7 -7
  102. package/dist/workspace-plugin/adapters/mcp.js +1 -1
  103. package/dist/workspace-plugin/adapters/omp.js +3 -3
  104. package/dist/workspace-plugin/index.js +1 -1
  105. package/package.json +1 -1
  106. package/dist/chunk-362QBS57.js.map +0 -1
  107. package/dist/chunk-R2I7RHT7.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../connectors/src/secrets.ts","../connectors/src/config.ts"],"names":[],"mappings":"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","file":"chunk-LRFZNLB2.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 {\n ConnectorDeclaration,\n TokenMediator,\n TokenMediatorResult,\n} 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\n// ── rclone mount credential bridge (auth: backend) ───────────────────────────\n\n/**\n * Thrown when the backend credential mediator refuses or cannot deliver a\n * mount credential for an `auth: backend` rclone connector. Carries the\n * wire-format error code so callers can branch on it. Mirrors the git driver's\n * `TokenMediatorError`, but lives here so all three rclone drivers share it.\n *\n * @docLink packages/connectors/api-reference#mount-token-mediator-error\n */\nexport class MountTokenMediatorError extends Error {\n readonly code: Extract<TokenMediatorResult, { ok: false }>[\"code\"];\n readonly connectorId: string;\n constructor(\n message: string,\n code: Extract<TokenMediatorResult, { ok: false }>[\"code\"],\n connectorId: string,\n ) {\n super(`Mount connector '${connectorId}': backend mediator ${code} — ${message}`);\n this.name = \"MountTokenMediatorError\";\n this.code = code;\n this.connectorId = connectorId;\n }\n}\n\n/**\n * Resolve the credential *string* an rclone mount driver feeds into its\n * `parseAuthBlob` / `parseAuth` helper.\n *\n * Two cases, branched on `declaration.auth`:\n * - `backend` → the credential is minted by the platform mediator. Calls\n * `tokenMediator({connectorId, reason: 'initial'})` and returns\n * the result's `token` string verbatim (already a JSON blob for\n * sharepoint/googledrive, or a `user:pass`/bearer string for\n * webdav). Throws `MountTokenMediatorError` when the mediator\n * refuses, or a plain `Error` when no mediator is wired (the\n * standalone CLI has none — `env:`/inline auth is the path there).\n * - anything else (`env:NAME`, inline, undefined) → resolves through the\n * legacy `resolveAuth` secrets/env path and NEVER touches the\n * mediator.\n *\n * For `auth: backend` the mediator also surfaces the access token's expiry,\n * which the rclone drivers use to arm a proactive refresh tick (the\n * client_secret is stripped from Skaile-managed Entra blobs, so rclone cannot\n * self-refresh) — see {@link resolveMountCredential}.\n *\n * @param declaration - The connector declaration (supplies `auth` + `id`).\n * @param secrets - Secrets chain for the legacy `env:`/inline path.\n * @param tokenMediator - Backend mediator, present only for platform sessions.\n * @returns The credential string, or `undefined` when no auth is declared.\n * @throws {MountTokenMediatorError} when the mediator refuses an `auth: backend` mint.\n * @docLink packages/connectors/api-reference#resolve-mount-credential-string\n */\nexport async function resolveMountCredentialString(\n declaration: ConnectorDeclaration,\n secrets: import(\"./secrets.js\").SecretProvider | undefined,\n tokenMediator: TokenMediator | undefined,\n): Promise<string | undefined> {\n return (await resolveMountCredential(declaration, secrets, tokenMediator, \"initial\")).token;\n}\n\n/**\n * The credential string an rclone mount driver feeds into `parseAuthBlob` /\n * `parseAuth`, paired with the access token's ISO expiry (`null` for static\n * credentials / the legacy env path).\n */\nexport interface ResolvedMountCredential {\n /** The credential string, or `undefined` when no auth is declared. */\n token: string | undefined;\n /** ISO-8601 expiry of the access token, or `null` if unknown / static. */\n expiresAt: string | null;\n}\n\n/**\n * Resolve a mount credential together with its expiry. The richer companion of\n * {@link resolveMountCredentialString}: rclone drivers use the returned\n * `expiresAt` to arm a proactive token-refresh tick, and re-call this with\n * `reason: 'refresh'` (or `'retry-401'` on the reactive path) to re-mint.\n *\n * Branches on `declaration.auth` exactly like `resolveMountCredentialString`:\n * `backend` mints through the mediator (and fails closed on refusal / empty\n * token); everything else resolves through the legacy `resolveAuth` secrets\n * path with a `null` expiry and never touches the mediator.\n *\n * @throws {MountTokenMediatorError} when the mediator refuses an `auth: backend` mint.\n * @docLink packages/connectors/api-reference#resolve-mount-credential\n */\nexport async function resolveMountCredential(\n declaration: ConnectorDeclaration,\n secrets: import(\"./secrets.js\").SecretProvider | undefined,\n tokenMediator: TokenMediator | undefined,\n reason: \"initial\" | \"refresh\" | \"retry-401\" = \"initial\",\n): Promise<ResolvedMountCredential> {\n if (declaration.auth === \"backend\") {\n if (!tokenMediator) {\n throw new Error(\n `Connector '${declaration.id}' uses 'auth: backend' but no token mediator is wired ` +\n `(standalone has none — use env:/inline auth instead).`,\n );\n }\n const result = await tokenMediator({ connectorId: declaration.id, reason });\n if (!result.ok) {\n throw new MountTokenMediatorError(result.message, result.code, declaration.id);\n }\n // Fail closed: an empty backend-minted token is a mediator bug. webdav would\n // otherwise silently fall back to an anonymous mount instead of erroring.\n if (!result.token) {\n throw new MountTokenMediatorError(\n \"mediator returned an empty token\",\n \"backend-error\",\n declaration.id,\n );\n }\n return { token: result.token, expiresAt: result.expiresAt };\n }\n\n return { token: resolveAuth(declaration.auth, secrets), expiresAt: null };\n}\n"]}
1
+ {"version":3,"sources":["../connectors/src/secrets.ts","../connectors/src/config.ts"],"names":[],"mappings":"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","file":"chunk-UQ5JY2GQ.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 {\n ConnectorDeclaration,\n TokenMediator,\n TokenMediatorResult,\n} 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\n// ── rclone mount credential bridge (auth: backend) ───────────────────────────\n\n/**\n * Thrown when the backend credential mediator refuses or cannot deliver a\n * mount credential for an `auth: backend` rclone connector. Carries the\n * wire-format error code so callers can branch on it. Mirrors the git driver's\n * `TokenMediatorError`, but lives here so all three rclone drivers share it.\n *\n * @docLink packages/connectors/api-reference#mount-token-mediator-error\n */\nexport class MountTokenMediatorError extends Error {\n readonly code: Extract<TokenMediatorResult, { ok: false }>[\"code\"];\n readonly connectorId: string;\n constructor(\n message: string,\n code: Extract<TokenMediatorResult, { ok: false }>[\"code\"],\n connectorId: string,\n ) {\n super(`Mount connector '${connectorId}': backend mediator ${code} — ${message}`);\n this.name = \"MountTokenMediatorError\";\n this.code = code;\n this.connectorId = connectorId;\n }\n}\n\n/**\n * Resolve the credential *string* an rclone mount driver feeds into its\n * `parseAuthBlob` / `parseAuth` helper.\n *\n * Two cases, branched on `declaration.auth`:\n * - `backend` → the credential is minted by the platform mediator. Calls\n * `tokenMediator({connectorId, reason: 'initial'})` and returns\n * the result's `token` string verbatim (already a JSON blob for\n * sharepoint/googledrive, or a `user:pass`/bearer string for\n * webdav). Throws `MountTokenMediatorError` when the mediator\n * refuses, or a plain `Error` when no mediator is wired (the\n * standalone CLI has none — `env:`/inline auth is the path there).\n * - anything else (`env:NAME`, inline, undefined) → resolves through the\n * legacy `resolveAuth` secrets/env path and NEVER touches the\n * mediator.\n *\n * For `auth: backend` the mediator also surfaces the access token's expiry,\n * which the rclone drivers use to arm a proactive refresh tick (the\n * client_secret is stripped from Skaile-managed Entra blobs, so rclone cannot\n * self-refresh) — see {@link resolveMountCredential}.\n *\n * @param declaration - The connector declaration (supplies `auth` + `id`).\n * @param secrets - Secrets chain for the legacy `env:`/inline path.\n * @param tokenMediator - Backend mediator, present only for platform sessions.\n * @returns The credential string, or `undefined` when no auth is declared.\n * @throws {MountTokenMediatorError} when the mediator refuses an `auth: backend` mint.\n * @docLink packages/connectors/api-reference#resolve-mount-credential-string\n */\nexport async function resolveMountCredentialString(\n declaration: ConnectorDeclaration,\n secrets: import(\"./secrets.js\").SecretProvider | undefined,\n tokenMediator: TokenMediator | undefined,\n): Promise<string | undefined> {\n return (await resolveMountCredential(declaration, secrets, tokenMediator, \"initial\")).token;\n}\n\n/**\n * The credential string an rclone mount driver feeds into `parseAuthBlob` /\n * `parseAuth`, paired with the access token's ISO expiry (`null` for static\n * credentials / the legacy env path).\n */\nexport interface ResolvedMountCredential {\n /** The credential string, or `undefined` when no auth is declared. */\n token: string | undefined;\n /** ISO-8601 expiry of the access token, or `null` if unknown / static. */\n expiresAt: string | null;\n}\n\n/**\n * Resolve a mount credential together with its expiry. The richer companion of\n * {@link resolveMountCredentialString}: rclone drivers use the returned\n * `expiresAt` to arm a proactive token-refresh tick, and re-call this with\n * `reason: 'refresh'` (or `'retry-401'` on the reactive path) to re-mint.\n *\n * Branches on `declaration.auth` exactly like `resolveMountCredentialString`:\n * `backend` mints through the mediator (and fails closed on refusal / empty\n * token); everything else resolves through the legacy `resolveAuth` secrets\n * path with a `null` expiry and never touches the mediator.\n *\n * @throws {MountTokenMediatorError} when the mediator refuses an `auth: backend` mint.\n * @docLink packages/connectors/api-reference#resolve-mount-credential\n */\nexport async function resolveMountCredential(\n declaration: ConnectorDeclaration,\n secrets: import(\"./secrets.js\").SecretProvider | undefined,\n tokenMediator: TokenMediator | undefined,\n reason: \"initial\" | \"refresh\" | \"retry-401\" = \"initial\",\n): Promise<ResolvedMountCredential> {\n if (declaration.auth === \"backend\") {\n if (!tokenMediator) {\n throw new Error(\n `Connector '${declaration.id}' uses 'auth: backend' but no token mediator is wired ` +\n `(standalone has none — use env:/inline auth instead).`,\n );\n }\n const result = await tokenMediator({ connectorId: declaration.id, reason });\n if (!result.ok) {\n throw new MountTokenMediatorError(result.message, result.code, declaration.id);\n }\n // Fail closed: an empty backend-minted token is a mediator bug. webdav would\n // otherwise silently fall back to an anonymous mount instead of erroring.\n if (!result.token) {\n throw new MountTokenMediatorError(\n \"mediator returned an empty token\",\n \"backend-error\",\n declaration.id,\n );\n }\n return { token: result.token, expiresAt: result.expiresAt };\n }\n\n return { token: resolveAuth(declaration.auth, secrets), expiresAt: null };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { globalSettingsPath, mapLegacyFields } from './chunk-PKPUVQJP.js';
1
+ import { globalSettingsPath, mapLegacyFields } from './chunk-DVIIYYD5.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-VXW2K4YH.js.map
93
- //# sourceMappingURL=chunk-VXW2K4YH.js.map
92
+ //# sourceMappingURL=chunk-VSLSRDQZ.js.map
93
+ //# sourceMappingURL=chunk-VSLSRDQZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":"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","file":"chunk-VXW2K4YH.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-VSLSRDQZ.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,4 +1,4 @@
1
- import { factoryAssetRoots } from './chunk-RQG5TXIR.js';
1
+ import { factoryAssetRoots } from './chunk-2VM62DX7.js';
2
2
  import fs from 'fs';
3
3
  import os from 'os';
4
4
  import path from 'path';
@@ -24,5 +24,5 @@ function aiResourceRoots() {
24
24
  }
25
25
 
26
26
  export { AI_RESOURCES, MONOREPO_ROOT, aiResourceRoots };
27
- //# sourceMappingURL=chunk-QUWXW2N3.js.map
28
- //# sourceMappingURL=chunk-QUWXW2N3.js.map
27
+ //# sourceMappingURL=chunk-W6TLIJG3.js.map
28
+ //# sourceMappingURL=chunk-W6TLIJG3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/paths.ts"],"names":[],"mappings":";;;;;;AAMA,IAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAW5D,SAAS,iBAAiB,IAAA,EAA6B;AACrD,EAAA,IAAI,GAAA,GAAM,IAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IAAI,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,KAAK,YAAY,CAAC,GAAG,OAAO,GAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC/B,IAAA,IAAI,WAAW,GAAA,EAAK;AACpB,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACA,EAAA,OAAO,IAAA;AACT;AAYO,IAAM,aAAA,GAA+B,iBAAiB,QAAQ;AAc9D,IAAM,YAAA,GACX,iBAAA,EAAkB,CAAE,CAAC,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,SAAA,EAAW,WAAW;AAoBnE,SAAS,eAAA,GAA4B;AAC1C,EAAA,MAAM,KAAA,GAAkB,CAAC,GAAG,iBAAA,EAAmB,CAAA;AAC/C,EAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAA,CAAK,EAAA,CAAG,SAAQ,EAAG,SAAA,EAAW,WAAW,CAAC,CAAA;AAC1D,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,EAAA,CAAG,UAAA,CAAW,CAAC,CAAC,CAAA;AAC3D","file":"chunk-QUWXW2N3.js","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { factoryAssetRoots } from \"@skaile/workspaces/core\";\n\nconst __ownDir = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Walk up from `from` looking for the monorepo marker (`biome.json`, the\n * repo-root shared tooling config). Returns the matching directory or `null`\n * when none is found within eight levels — the latter is the typical case when\n * `@skaile/workspaces` has been installed via `npm i` without a skaile-dev\n * workspace context. Used only to gate dev-only commands (e.g.\n * `serve --compile-test`); first-party content is located via\n * {@link aiResourceRoots}, not this.\n */\nfunction findMonorepoRoot(from: string): string | null {\n let dir = from;\n for (let i = 0; i < 8; i++) {\n if (fs.existsSync(path.join(dir, \"biome.json\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Absolute path to the monorepo root, or `null` when the CLI is running\n * outside the skaile-dev workspace (typical for `npm i -g` installs).\n *\n * Consumers that only make sense inside the workspace (e.g.\n * `skaile serve --compile-test`) MUST check for `null` and report a\n * \"monorepo-only feature\" error before proceeding.\n *\n * @docLink cli/dev-guide#paths\n */\nexport const MONOREPO_ROOT: string | null = findMonorepoRoot(__ownDir);\n\n/**\n * Default content root used by path display and the `validate` command.\n *\n * The primary first-party `factory-assets/` root resolved through the shared\n * `factoryAssetRoots()` helper — the `SKAILE_FACTORY_ASSETS_DIR` override when\n * set, else the in-repo source during dev / bundled `dist/factory-assets/` after\n * `npm i`. Falls back to `~/.skaile/libraries/` — the user-library directory\n * managed by `skaile library add` — when the package cannot be located.\n * Consumers `fs.existsSync` first and degrade to \"no skills / flows discovered\".\n *\n * @docLink cli/dev-guide#paths\n */\nexport const AI_RESOURCES: string =\n factoryAssetRoots()[0] ?? path.join(os.homedir(), \".skaile\", \"libraries\");\n\n/**\n * All content roots that skill / flow discovery should walk, in priority order,\n * filtered to those that exist on disk and de-duplicated.\n *\n * - The first-party `factory-assets/` roots from the shared `factoryAssetRoots()`\n * helper — the `SKAILE_FACTORY_ASSETS_DIR` override layer (when set) ahead of\n * the bundled tree (in-repo source in dev, `dist/factory-assets/` after\n * install). No monorepo special-case.\n * - The user-library dir `~/.skaile/libraries/`.\n *\n * Order is significant: `findSkills` / flow discovery dedupe first-root-wins, so\n * the env override shadows the bundled tree on a name clash.\n *\n * This is the discovery surface used by `findSkills`, flow discovery, and the\n * completion resolvers.\n *\n * @docLink cli/dev-guide#paths\n */\nexport function aiResourceRoots(): string[] {\n const roots: string[] = [...factoryAssetRoots()];\n roots.push(path.join(os.homedir(), \".skaile\", \"libraries\"));\n return [...new Set(roots)].filter((r) => fs.existsSync(r));\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/paths.ts"],"names":[],"mappings":";;;;;;AAMA,IAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAW5D,SAAS,iBAAiB,IAAA,EAA6B;AACrD,EAAA,IAAI,GAAA,GAAM,IAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IAAI,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,KAAK,YAAY,CAAC,GAAG,OAAO,GAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC/B,IAAA,IAAI,WAAW,GAAA,EAAK;AACpB,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACA,EAAA,OAAO,IAAA;AACT;AAYO,IAAM,aAAA,GAA+B,iBAAiB,QAAQ;AAc9D,IAAM,YAAA,GACX,iBAAA,EAAkB,CAAE,CAAC,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,SAAA,EAAW,WAAW;AAoBnE,SAAS,eAAA,GAA4B;AAC1C,EAAA,MAAM,KAAA,GAAkB,CAAC,GAAG,iBAAA,EAAmB,CAAA;AAC/C,EAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAA,CAAK,EAAA,CAAG,SAAQ,EAAG,SAAA,EAAW,WAAW,CAAC,CAAA;AAC1D,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,EAAA,CAAG,UAAA,CAAW,CAAC,CAAC,CAAA;AAC3D","file":"chunk-W6TLIJG3.js","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { factoryAssetRoots } from \"@skaile/workspaces/core\";\n\nconst __ownDir = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Walk up from `from` looking for the monorepo marker (`biome.json`, the\n * repo-root shared tooling config). Returns the matching directory or `null`\n * when none is found within eight levels — the latter is the typical case when\n * `@skaile/workspaces` has been installed via `npm i` without a skaile-dev\n * workspace context. Used only to gate dev-only commands (e.g.\n * `serve --compile-test`); first-party content is located via\n * {@link aiResourceRoots}, not this.\n */\nfunction findMonorepoRoot(from: string): string | null {\n let dir = from;\n for (let i = 0; i < 8; i++) {\n if (fs.existsSync(path.join(dir, \"biome.json\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Absolute path to the monorepo root, or `null` when the CLI is running\n * outside the skaile-dev workspace (typical for `npm i -g` installs).\n *\n * Consumers that only make sense inside the workspace (e.g.\n * `skaile serve --compile-test`) MUST check for `null` and report a\n * \"monorepo-only feature\" error before proceeding.\n *\n * @docLink cli/dev-guide#paths\n */\nexport const MONOREPO_ROOT: string | null = findMonorepoRoot(__ownDir);\n\n/**\n * Default content root used by path display and the `validate` command.\n *\n * The primary first-party `factory-assets/` root resolved through the shared\n * `factoryAssetRoots()` helper — the `SKAILE_FACTORY_ASSETS_DIR` override when\n * set, else the in-repo source during dev / bundled `dist/factory-assets/` after\n * `npm i`. Falls back to `~/.skaile/libraries/` — the user-library directory\n * managed by `skaile library add` — when the package cannot be located.\n * Consumers `fs.existsSync` first and degrade to \"no skills / flows discovered\".\n *\n * @docLink cli/dev-guide#paths\n */\nexport const AI_RESOURCES: string =\n factoryAssetRoots()[0] ?? path.join(os.homedir(), \".skaile\", \"libraries\");\n\n/**\n * All content roots that skill / flow discovery should walk, in priority order,\n * filtered to those that exist on disk and de-duplicated.\n *\n * - The first-party `factory-assets/` roots from the shared `factoryAssetRoots()`\n * helper — the `SKAILE_FACTORY_ASSETS_DIR` override layer (when set) ahead of\n * the bundled tree (in-repo source in dev, `dist/factory-assets/` after\n * install). No monorepo special-case.\n * - The user-library dir `~/.skaile/libraries/`.\n *\n * Order is significant: `findSkills` / flow discovery dedupe first-root-wins, so\n * the env override shadows the bundled tree on a name clash.\n *\n * This is the discovery surface used by `findSkills`, flow discovery, and the\n * completion resolvers.\n *\n * @docLink cli/dev-guide#paths\n */\nexport function aiResourceRoots(): string[] {\n const roots: string[] = [...factoryAssetRoots()];\n roots.push(path.join(os.homedir(), \".skaile\", \"libraries\"));\n return [...new Set(roots)].filter((r) => fs.existsSync(r));\n}\n"]}
@@ -1,11 +1,11 @@
1
1
  import { renderGoogleDriveConfig, renderOneDriveConfig, renderWebDAVConfig } from './chunk-OVRSNIKJ.js';
2
- import { resolveAuthRef, resolveAuth, resolveMountCredentialString, resolveMountCredential } from './chunk-LRFZNLB2.js';
2
+ import { resolveAuthRef, resolveAuth, resolveMountCredentialString, resolveMountCredential } from './chunk-UQ5JY2GQ.js';
3
3
  import { PortPool, createFsWatcher, RcloneProcessManager, ensureDirMode } from './chunk-XT6AZWK3.js';
4
4
  import { pluginRegistry } from './chunk-6E6PKKAD.js';
5
5
  import { computeFlowStateFromSnapshots } from './chunk-X46FY45B.js';
6
6
  import { renderStimulusPrompt } from './chunk-DEYYRFQU.js';
7
7
  import { computeStimulus } from './chunk-IFGTRL2I.js';
8
- import { portableSpawn } from './chunk-PKPUVQJP.js';
8
+ import { portableSpawn } from './chunk-DVIIYYD5.js';
9
9
  import { createLogger } from './chunk-JB35MVBN.js';
10
10
  import { existsSync, mkdirSync, renameSync, writeFileSync, readFileSync, cpSync, statSync, createReadStream, readdirSync, openSync, writeSync, closeSync, chmodSync } from 'fs';
11
11
  import path, { join, dirname, resolve, sep } from 'path';
@@ -5273,6 +5273,115 @@ var ConnectorStartupError = class extends Error {
5273
5273
  this.failedReadWrite = failedReadWrite;
5274
5274
  }
5275
5275
  };
5276
+
5277
+ // connectors/src/fleet-health-gate.ts
5278
+ var FleetHealthGate = class {
5279
+ constructor(target, barrier, log, opts) {
5280
+ this.target = target;
5281
+ this.barrier = barrier;
5282
+ this.log = log;
5283
+ this.unhealthyThreshold = Math.max(1, opts?.unhealthyThreshold ?? 2);
5284
+ this.healthyThreshold = Math.max(1, opts?.healthyThreshold ?? 2);
5285
+ }
5286
+ target;
5287
+ barrier;
5288
+ log;
5289
+ unhealthyThreshold;
5290
+ healthyThreshold;
5291
+ /** True while the read-only barrier is established over the target. */
5292
+ gated = false;
5293
+ /**
5294
+ * The gate state that the most recently *enqueued* transition will settle on.
5295
+ * Hysteresis is measured against this, not `gated`, so that verdicts arriving
5296
+ * while a (slow, async) establish/remove is still in flight are counted toward
5297
+ * the post-transition state rather than the stale pre-transition one. Without
5298
+ * this, fast healthy verdicts arriving during a slow `establish()` could meet
5299
+ * `healthyThreshold` before the gate finished tripping, ungating it on the
5300
+ * first healthy verdict afterwards and defeating the threshold.
5301
+ */
5302
+ pendingGated = false;
5303
+ /** Consecutive same-verdict run length, signed by the *current* run's verdict. */
5304
+ unhealthyRun = 0;
5305
+ healthyRun = 0;
5306
+ /** Serialises establish/remove so overlapping observe() calls can't race. */
5307
+ transition = Promise.resolve();
5308
+ /** True while the read-only barrier is established (test/observability hook). */
5309
+ get isGated() {
5310
+ return this.gated;
5311
+ }
5312
+ /**
5313
+ * Feed one health verdict. Applies hysteresis, then establishes or removes the
5314
+ * barrier on a state change. Resolves once the (possibly no-op) transition is
5315
+ * applied. Never throws — a failed establish is treated as gated (fail-closed).
5316
+ */
5317
+ observe(verdict) {
5318
+ if (verdict === "healthy") {
5319
+ this.healthyRun += 1;
5320
+ this.unhealthyRun = 0;
5321
+ if (this.pendingGated && this.healthyRun >= this.healthyThreshold) {
5322
+ this.pendingGated = false;
5323
+ this.healthyRun = 0;
5324
+ return this.enqueue(() => this.ungate());
5325
+ }
5326
+ } else {
5327
+ this.unhealthyRun += 1;
5328
+ this.healthyRun = 0;
5329
+ if (!this.pendingGated && this.unhealthyRun >= this.unhealthyThreshold) {
5330
+ this.pendingGated = true;
5331
+ this.unhealthyRun = 0;
5332
+ return this.enqueue(() => this.gate());
5333
+ }
5334
+ }
5335
+ return this.transition;
5336
+ }
5337
+ /**
5338
+ * Tear the gate down. If currently gated, removes the barrier so a leftover
5339
+ * read-only tmpfs is not leaked. Call only after the connector above the target
5340
+ * is disconnected (top-down, no leaked mount).
5341
+ */
5342
+ dispose() {
5343
+ if (!this.gated) return this.transition;
5344
+ return this.enqueue(() => this.ungate());
5345
+ }
5346
+ enqueue(step) {
5347
+ this.transition = this.transition.then(step, step);
5348
+ return this.transition;
5349
+ }
5350
+ async gate() {
5351
+ if (this.gated) {
5352
+ this.pendingGated = true;
5353
+ return;
5354
+ }
5355
+ try {
5356
+ await this.barrier.establish(this.target, this.log);
5357
+ this.gated = true;
5358
+ this.log?.warn("fleet mount unhealthy \u2014 gated read-only", { target: this.target });
5359
+ } catch (err) {
5360
+ this.gated = true;
5361
+ this.log?.error(
5362
+ "fleet read-only gate establish threw \u2014 treating as gated (fail-closed)",
5363
+ err,
5364
+ {
5365
+ target: this.target
5366
+ }
5367
+ );
5368
+ }
5369
+ }
5370
+ async ungate() {
5371
+ if (!this.gated) return;
5372
+ try {
5373
+ await this.barrier.remove(this.target, this.log);
5374
+ } catch (err) {
5375
+ this.pendingGated = true;
5376
+ this.log?.error("fleet read-only gate remove failed \u2014 staying gated", err, {
5377
+ target: this.target
5378
+ });
5379
+ return;
5380
+ }
5381
+ this.gated = false;
5382
+ this.log?.info("fleet mount recovered \u2014 gate lifted, writable again", { target: this.target });
5383
+ }
5384
+ };
5276
5385
  function isFleetManaged(connectorId) {
5277
5386
  const raw = process.env.SKAILE_FLEET_MANAGED_MOUNTS ?? "";
5278
5387
  if (raw.length === 0) return false;
@@ -5301,6 +5410,16 @@ async function ensureFleetMounted(dir, log, options) {
5301
5410
  `fleet mount ${dir} not ready after ${timeoutMs}ms \u2014 check SKAILE_FLEET_MANAGED_MOUNTS env var and host bind: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}`
5302
5411
  );
5303
5412
  }
5413
+ async function probeFleetHealth(dir) {
5414
+ try {
5415
+ const st = await stat(dir);
5416
+ if (!st.isDirectory()) return "error";
5417
+ await readdir(dir);
5418
+ return "healthy";
5419
+ } catch {
5420
+ return "error";
5421
+ }
5422
+ }
5304
5423
  var NOT_READY_SENTINEL = ".skaile-workspace-not-ready";
5305
5424
  var SENTINEL_BODY = [
5306
5425
  "This workspace is backed by a remote mount that is not live yet.",
@@ -5427,6 +5546,12 @@ var defaultMountPlaceholderBarrier = new RoMountPlaceholderBarrier();
5427
5546
 
5428
5547
  // connectors/src/connector-manager.ts
5429
5548
  var KNOWN_PREFIXES = ["env:", "forge:", "op:", "kp:", "oauth:"];
5549
+ var DEFAULT_FLEET_HEALTH_POLL_MS = 5e3;
5550
+ function parseFleetHealthPollMs(raw = process.env.SKAILE_FLEET_HEALTH_POLL_MS) {
5551
+ if (raw === void 0) return DEFAULT_FLEET_HEALTH_POLL_MS;
5552
+ const n = Number(raw);
5553
+ return Number.isFinite(n) && n >= 0 ? n : DEFAULT_FLEET_HEALTH_POLL_MS;
5554
+ }
5430
5555
  function hasKnownPrefix(ref) {
5431
5556
  return KNOWN_PREFIXES.some((p) => ref.startsWith(p));
5432
5557
  }
@@ -5527,6 +5652,7 @@ var ConnectorManager = class {
5527
5652
  this.tokenMediator = opts.tokenMediator;
5528
5653
  this.preMintedSecrets = opts.preMintedSecrets;
5529
5654
  this.placeholderBarrier = opts.placeholderBarrier ?? defaultMountPlaceholderBarrier;
5655
+ this.fleetHealthPollMs = opts.fleetHealthPollMs ?? parseFleetHealthPollMs();
5530
5656
  const secrets = opts.secrets;
5531
5657
  if (secrets && typeof secrets === "object" && "prepareRef" in secrets) {
5532
5658
  this.chain = secrets;
@@ -5555,6 +5681,10 @@ var ConnectorManager = class {
5555
5681
  disposeController = new AbortController();
5556
5682
  /** Tracks the background task driving deferred (rclone-backed) mounts. */
5557
5683
  deferredConnect;
5684
+ /** Periodic local fleet-health probe; runs only while a fleet gate is active. */
5685
+ fleetHealthTimer;
5686
+ /** Local fleet-health poll interval (ms). 0 disables the local probe. */
5687
+ fleetHealthPollMs;
5558
5688
  // ── Private helpers ──────────────────────────────────────────────────────────
5559
5689
  /**
5560
5690
  * Wrap the user-supplied `TokenMediator` so `reason: 'initial'` calls for an
@@ -5826,7 +5956,9 @@ var ConnectorManager = class {
5826
5956
  connector,
5827
5957
  handle,
5828
5958
  declaration: decl,
5829
- placeholderTarget: previous?.placeholderTarget
5959
+ placeholderTarget: previous?.placeholderTarget,
5960
+ fleetHealthGate: previous?.fleetHealthGate,
5961
+ fleetHealthTarget: previous?.fleetHealthTarget
5830
5962
  });
5831
5963
  this.opts.onStatusChange?.({
5832
5964
  type: "connector_status",
@@ -5862,16 +5994,25 @@ var ConnectorManager = class {
5862
5994
  * prompt before the background mount completes.
5863
5995
  *
5864
5996
  * Before exposing the target, a read-only barrier is established so the agent
5865
- * cannot write a phantom workspace into a not-yet-mounted remote. Fleet-managed
5866
- * mounts are skipped: the host already bound the live share at the target, so a
5867
- * barrier on top would shadow real content.
5997
+ * cannot write a phantom workspace into a not-yet-mounted remote.
5998
+ *
5999
+ * Fleet-managed mounts skip the *static* boot-time barrier (the host already
6000
+ * bound the live share at the target — a static barrier would shadow real
6001
+ * content) but instead get a *dynamic* health gate: while the host fleet rclone
6002
+ * is healthy the target stays writable exactly as before; when it wedges, the
6003
+ * gate establishes the same read-only barrier until the mount recovers.
5868
6004
  */
5869
6005
  async preRegisterDeferred(decl, connector) {
5870
6006
  const mountTarget = this.resolveMountTarget(decl);
5871
6007
  if (!existsSync(mountTarget)) mkdirSync(mountTarget, { recursive: true });
5872
6008
  const fleetManaged = isFleetManaged(decl.id);
5873
6009
  let placeholderTarget;
5874
- if (!fleetManaged) {
6010
+ let fleetHealthGate;
6011
+ let fleetHealthTarget;
6012
+ if (fleetManaged) {
6013
+ fleetHealthGate = new FleetHealthGate(mountTarget, this.placeholderBarrier, this.mgrLog);
6014
+ fleetHealthTarget = mountTarget;
6015
+ } else {
5875
6016
  try {
5876
6017
  await this.placeholderBarrier.establish(mountTarget, this.mgrLog);
5877
6018
  placeholderTarget = mountTarget;
@@ -5890,7 +6031,58 @@ var ConnectorManager = class {
5890
6031
  // returns cleanly instead of dereferencing null state.
5891
6032
  state: {}
5892
6033
  };
5893
- this.active.set(decl.id, { connector, handle, declaration: decl, placeholderTarget });
6034
+ this.active.set(decl.id, {
6035
+ connector,
6036
+ handle,
6037
+ declaration: decl,
6038
+ placeholderTarget,
6039
+ fleetHealthGate,
6040
+ fleetHealthTarget
6041
+ });
6042
+ if (fleetHealthGate) this.ensureFleetHealthPoll();
6043
+ }
6044
+ /**
6045
+ * Start the periodic local fleet-health probe if it is not already running and
6046
+ * the poll interval is enabled. Each tick `stat`+`readdir`s every fleet target
6047
+ * and feeds the verdict to its gate (hysteresis lives in the gate). The probe
6048
+ * only catches directly-detectable failures (EIO / dead bind); silent
6049
+ * degradation is covered by the platform signal via `reportFleetHealth`.
6050
+ */
6051
+ ensureFleetHealthPoll() {
6052
+ if (this.fleetHealthTimer || this.fleetHealthPollMs <= 0 || this.disposed) return;
6053
+ this.fleetHealthTimer = setInterval(() => {
6054
+ void this.runFleetHealthProbe();
6055
+ }, this.fleetHealthPollMs);
6056
+ this.fleetHealthTimer.unref?.();
6057
+ }
6058
+ async runFleetHealthProbe() {
6059
+ if (this.disposed) return;
6060
+ const gates = [...this.active.values()].filter(
6061
+ (e) => e.fleetHealthGate != null && e.fleetHealthTarget != null
6062
+ );
6063
+ await Promise.all(
6064
+ gates.map(async (e) => {
6065
+ if (e.fleetHealthGate.isGated) return;
6066
+ const verdict = await probeFleetHealth(e.fleetHealthTarget);
6067
+ await e.fleetHealthGate.observe(verdict).catch(() => {
6068
+ });
6069
+ })
6070
+ );
6071
+ }
6072
+ /**
6073
+ * Feed an externally-derived fleet-health verdict for a connector into its gate.
6074
+ *
6075
+ * This is the consume side of the platform fleet-health signal: the host fleet
6076
+ * health poll knows `core/stats.errors` and can detect a *silently-empty-but-
6077
+ * writable* degraded mount that the local probe cannot. The runner watches the
6078
+ * `<workspace>/.skaile/fleet-health/<connectorId>` flag and forwards its verdict
6079
+ * here. Unknown / non-fleet ids are ignored.
6080
+ */
6081
+ async reportFleetHealth(connectorId, verdict) {
6082
+ const entry = this.active.get(connectorId);
6083
+ if (!entry?.fleetHealthGate) return;
6084
+ await entry.fleetHealthGate.observe(verdict).catch(() => {
6085
+ });
5894
6086
  }
5895
6087
  /** Drive all deferred mounts concurrently; resolves when every one settles. */
5896
6088
  async connectDeferred(deferred) {
@@ -5937,6 +6129,10 @@ var ConnectorManager = class {
5937
6129
  this.mgrLog.info("disconnectAll start", { count: this.active.size });
5938
6130
  this.disposed = true;
5939
6131
  this.disposeController.abort();
6132
+ if (this.fleetHealthTimer) {
6133
+ clearInterval(this.fleetHealthTimer);
6134
+ this.fleetHealthTimer = void 0;
6135
+ }
5940
6136
  if (this.deferredConnect) {
5941
6137
  try {
5942
6138
  await this.deferredConnect;
@@ -5954,6 +6150,8 @@ var ConnectorManager = class {
5954
6150
  await this.placeholderBarrier.remove(entry.placeholderTarget, this.mgrLog).catch(() => {
5955
6151
  });
5956
6152
  }
6153
+ if (entry.fleetHealthGate) await entry.fleetHealthGate.dispose().catch(() => {
6154
+ });
5957
6155
  this.opts.onStatusChange?.({
5958
6156
  type: "connector_status",
5959
6157
  connectorId: id,
@@ -6044,6 +6242,8 @@ var ConnectorManager = class {
6044
6242
  await this.placeholderBarrier.remove(entry.placeholderTarget, this.mgrLog).catch(() => {
6045
6243
  });
6046
6244
  }
6245
+ if (entry.fleetHealthGate) await entry.fleetHealthGate.dispose().catch(() => {
6246
+ });
6047
6247
  this.active.delete(id);
6048
6248
  this.opts.onStatusChange?.({
6049
6249
  type: "connector_status",
@@ -8164,6 +8364,6 @@ function createConnector() {
8164
8364
  return new FlowAdapter();
8165
8365
  }
8166
8366
 
8167
- export { AbstractConnector, BUILTIN_CONNECTOR_CATALOG, ConnectorFieldMissingError, ConnectorManager, ConnectorStartupError, DEFAULT_REACTIVE_COOLDOWN_MS, DeployConnector, DevServerConnector, FlowAdapter, GitConnector, GmailConnector, GoogleDriveConnector, LocalConnector, LogBuffer, ManagedGitconfigCollisionError, MattermostConnector, MemoryConnector, MinIOConnector, NOT_READY_SENTINEL, PROACTIVE_RCLONE_REFRESH_MARGIN_MS, PostgresConnector, RoMountPlaceholderBarrier, S3Connector, SQLiteConnector, SharePointConnector, StaticServerConnector, TunnelConnector, WebDAVConnector, XStateConnector, XStateStoreConnector, __test, atomicReplaceCredential, buildConnectorPromptSection, buildSdkConnectorTools, createConnector, createConnector10, createConnector11, createConnector12, createConnector13, createConnector14, createConnector15, createConnector16, createConnector17, createConnector18, createConnector19, createConnector2, createConnector3, createConnector4, createConnector5, createConnector6, createConnector7, createConnector8, createConnector9, createRcloneTokenRefresh, createWorktree, defaultMountPlaceholderBarrier, defaultSpawn, ensureFleetMounted, findGitRoot, findMissingPackages, getConnector, installNpmPackages, isFleetManaged, isPackageResolvable, listConnectors, listWorktrees, registerBuiltinConnectors, removeMountBlock, renderCredentialHelperScript, tryGetConnector, worktreeRegistry, writeHelperScript, writeMountBlock };
8168
- //# sourceMappingURL=chunk-362QBS57.js.map
8169
- //# sourceMappingURL=chunk-362QBS57.js.map
8367
+ export { AbstractConnector, BUILTIN_CONNECTOR_CATALOG, ConnectorFieldMissingError, ConnectorManager, ConnectorStartupError, DEFAULT_REACTIVE_COOLDOWN_MS, DeployConnector, DevServerConnector, FleetHealthGate, FlowAdapter, GitConnector, GmailConnector, GoogleDriveConnector, LocalConnector, LogBuffer, ManagedGitconfigCollisionError, MattermostConnector, MemoryConnector, MinIOConnector, NOT_READY_SENTINEL, PROACTIVE_RCLONE_REFRESH_MARGIN_MS, PostgresConnector, RoMountPlaceholderBarrier, S3Connector, SQLiteConnector, SharePointConnector, StaticServerConnector, TunnelConnector, WebDAVConnector, XStateConnector, XStateStoreConnector, __test, atomicReplaceCredential, buildConnectorPromptSection, buildSdkConnectorTools, createConnector, createConnector10, createConnector11, createConnector12, createConnector13, createConnector14, createConnector15, createConnector16, createConnector17, createConnector18, createConnector19, createConnector2, createConnector3, createConnector4, createConnector5, createConnector6, createConnector7, createConnector8, createConnector9, createRcloneTokenRefresh, createWorktree, defaultMountPlaceholderBarrier, defaultSpawn, ensureFleetMounted, findGitRoot, findMissingPackages, getConnector, installNpmPackages, isFleetManaged, isPackageResolvable, listConnectors, listWorktrees, probeFleetHealth, registerBuiltinConnectors, removeMountBlock, renderCredentialHelperScript, tryGetConnector, worktreeRegistry, writeHelperScript, writeMountBlock };
8368
+ //# sourceMappingURL=chunk-WQRDLR3K.js.map
8369
+ //# sourceMappingURL=chunk-WQRDLR3K.js.map