@skaile/workspaces 0.41.6 → 0.42.1

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 (172) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/dist/{asset-feeds-FKD5AB2R.js → asset-feeds-UPJJGR3O.js} +8 -8
  3. package/dist/{asset-feeds-FKD5AB2R.js.map → asset-feeds-UPJJGR3O.js.map} +1 -1
  4. package/dist/asset-manager/index.js +6 -6
  5. package/dist/asset-manager/installer.js +5 -5
  6. package/dist/bridge/drivers/claude-sdk.js +112 -7
  7. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  8. package/dist/bridge/drivers/codex.js +1 -1
  9. package/dist/bridge/drivers/continue.js +2 -2
  10. package/dist/bridge/drivers/echo.js +1 -1
  11. package/dist/bridge/drivers/gemini.js +3 -3
  12. package/dist/bridge/drivers/goose.js +2 -2
  13. package/dist/bridge/drivers/omp.js +1 -1
  14. package/dist/bridge/drivers/opencode.js +2 -2
  15. package/dist/bridge/drivers/qwen.js +3 -3
  16. package/dist/bridge/index.js +2 -2
  17. package/dist/bridge/src/drivers/claude-sdk.d.ts +6 -0
  18. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  19. package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts +53 -0
  20. package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts.map +1 -0
  21. package/dist/{chunk-J4RF5ABK.js → chunk-2BEDUMTA.js} +3 -3
  22. package/dist/{chunk-J4RF5ABK.js.map → chunk-2BEDUMTA.js.map} +1 -1
  23. package/dist/{chunk-5VJVSYXX.js → chunk-3HUUP3JC.js} +41 -3
  24. package/dist/chunk-3HUUP3JC.js.map +1 -0
  25. package/dist/{chunk-SBGHNXJD.js → chunk-3K2CYDBT.js} +17 -7
  26. package/dist/chunk-3K2CYDBT.js.map +1 -0
  27. package/dist/{chunk-2XFTGANB.js → chunk-4HKLAUHJ.js} +5 -5
  28. package/dist/{chunk-2XFTGANB.js.map → chunk-4HKLAUHJ.js.map} +1 -1
  29. package/dist/{chunk-5IXCNMMU.js → chunk-5C3QJSOD.js} +3 -3
  30. package/dist/{chunk-5IXCNMMU.js.map → chunk-5C3QJSOD.js.map} +1 -1
  31. package/dist/{chunk-TNYWP6EQ.js → chunk-5VMVNQGB.js} +6 -6
  32. package/dist/{chunk-TNYWP6EQ.js.map → chunk-5VMVNQGB.js.map} +1 -1
  33. package/dist/{chunk-B5PEERRZ.js → chunk-6IDBWPK2.js} +7 -4
  34. package/dist/chunk-6IDBWPK2.js.map +1 -0
  35. package/dist/{chunk-3KX5W3ZU.js → chunk-7WLJW457.js} +4 -4
  36. package/dist/{chunk-3KX5W3ZU.js.map → chunk-7WLJW457.js.map} +1 -1
  37. package/dist/{chunk-ZJ27BHIH.js → chunk-BXYMGZCI.js} +3 -3
  38. package/dist/{chunk-ZJ27BHIH.js.map → chunk-BXYMGZCI.js.map} +1 -1
  39. package/dist/{chunk-2ZI2FFFN.js → chunk-F5Q2RMH4.js} +229 -76
  40. package/dist/chunk-F5Q2RMH4.js.map +1 -0
  41. package/dist/{chunk-2JCUYKUN.js → chunk-G6FJZG4C.js} +2 -2
  42. package/dist/{chunk-2JCUYKUN.js.map → chunk-G6FJZG4C.js.map} +1 -1
  43. package/dist/{chunk-NQDJQ7WB.js → chunk-GJI6FZ56.js} +8 -4
  44. package/dist/chunk-GJI6FZ56.js.map +1 -0
  45. package/dist/{chunk-JAOXG3LL.js → chunk-HVCZLD5Z.js} +4 -4
  46. package/dist/{chunk-JAOXG3LL.js.map → chunk-HVCZLD5Z.js.map} +1 -1
  47. package/dist/{chunk-IODU6UDT.js → chunk-JZQFZ55W.js} +2 -2
  48. package/dist/{chunk-IODU6UDT.js.map → chunk-JZQFZ55W.js.map} +1 -1
  49. package/dist/{chunk-MO2VGW6U.js → chunk-K5TROTFK.js} +3 -3
  50. package/dist/{chunk-MO2VGW6U.js.map → chunk-K5TROTFK.js.map} +1 -1
  51. package/dist/{chunk-MVXXAXDW.js → chunk-KYQNWFJV.js} +3 -3
  52. package/dist/{chunk-MVXXAXDW.js.map → chunk-KYQNWFJV.js.map} +1 -1
  53. package/dist/{chunk-KM6DCR7A.js → chunk-OCAQH66V.js} +2 -2
  54. package/dist/{chunk-KM6DCR7A.js.map → chunk-OCAQH66V.js.map} +1 -1
  55. package/dist/{chunk-HZXOCRLD.js → chunk-OMAK7GNL.js} +78 -39
  56. package/dist/chunk-OMAK7GNL.js.map +1 -0
  57. package/dist/{chunk-X4FCLBI7.js → chunk-R4H6EJW5.js} +7 -5
  58. package/dist/chunk-R4H6EJW5.js.map +1 -0
  59. package/dist/{chunk-U3TV7SRR.js → chunk-RSK6FDMV.js} +3 -3
  60. package/dist/{chunk-U3TV7SRR.js.map → chunk-RSK6FDMV.js.map} +1 -1
  61. package/dist/{chunk-TB342H55.js → chunk-SURALYSM.js} +4 -4
  62. package/dist/{chunk-TB342H55.js.map → chunk-SURALYSM.js.map} +1 -1
  63. package/dist/{chunk-4NZD7423.js → chunk-WJ3RP2FS.js} +3 -3
  64. package/dist/{chunk-4NZD7423.js.map → chunk-WJ3RP2FS.js.map} +1 -1
  65. package/dist/{chunk-4ZACMAT3.js → chunk-Z3GAAIJK.js} +4 -4
  66. package/dist/{chunk-4ZACMAT3.js.map → chunk-Z3GAAIJK.js.map} +1 -1
  67. package/dist/cli/index.js +34 -34
  68. package/dist/connectors/config.js +5 -5
  69. package/dist/connectors/index.js +7 -7
  70. package/dist/connectors/rclone.js +1 -1
  71. package/dist/connectors/src/connector-manager.d.ts +17 -0
  72. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  73. package/dist/connectors/src/connector-types.d.ts +26 -0
  74. package/dist/connectors/src/connector-types.d.ts.map +1 -1
  75. package/dist/connectors/src/fleet-health-gate.d.ts +53 -36
  76. package/dist/connectors/src/fleet-health-gate.d.ts.map +1 -1
  77. package/dist/connectors/src/fleet-utils.d.ts +11 -2
  78. package/dist/connectors/src/fleet-utils.d.ts.map +1 -1
  79. package/dist/connectors/src/index.d.ts +3 -3
  80. package/dist/connectors/src/index.d.ts.map +1 -1
  81. package/dist/connectors/src/materialized-connectors.d.ts.map +1 -1
  82. package/dist/connectors/src/mount-placeholder.d.ts +19 -0
  83. package/dist/connectors/src/mount-placeholder.d.ts.map +1 -1
  84. package/dist/connectors/src/rclone-process-manager.d.ts +36 -2
  85. package/dist/connectors/src/rclone-process-manager.d.ts.map +1 -1
  86. package/dist/core/index.js +4 -4
  87. package/dist/core/manifest.js +1 -1
  88. package/dist/core/runtime-assets.js +3 -3
  89. package/dist/core/src/index.d.ts +1 -1
  90. package/dist/core/src/index.d.ts.map +1 -1
  91. package/dist/core/src/manifest.d.ts +11 -0
  92. package/dist/core/src/manifest.d.ts.map +1 -1
  93. package/dist/core/src/workspace-config.d.ts +2 -0
  94. package/dist/core/src/workspace-config.d.ts.map +1 -1
  95. package/dist/core/workspace-config.js +2 -2
  96. package/dist/deploy/index.js +4 -4
  97. package/dist/discovery/index.js +2 -2
  98. package/dist/{ensure-sources-EWK7EXKN.js → ensure-sources-TZHDV3BF.js} +8 -8
  99. package/dist/{ensure-sources-EWK7EXKN.js.map → ensure-sources-TZHDV3BF.js.map} +1 -1
  100. package/dist/factory-assets/connectors/deploy.js +7 -7
  101. package/dist/factory-assets/connectors/devserver.js +7 -7
  102. package/dist/factory-assets/connectors/flow/adapter.js +7 -7
  103. package/dist/factory-assets/connectors/flow/engine.js +4 -4
  104. package/dist/factory-assets/connectors/flow/run-flow.js +8 -8
  105. package/dist/factory-assets/connectors/flow.js +7 -7
  106. package/dist/factory-assets/connectors/git.js +7 -7
  107. package/dist/factory-assets/connectors/gmail.js +7 -7
  108. package/dist/factory-assets/connectors/googledrive/driver.d.ts.map +1 -1
  109. package/dist/factory-assets/connectors/googledrive.js +7 -7
  110. package/dist/factory-assets/connectors/local.js +7 -7
  111. package/dist/factory-assets/connectors/mattermost.js +7 -7
  112. package/dist/factory-assets/connectors/memory.js +7 -7
  113. package/dist/factory-assets/connectors/minio.js +7 -7
  114. package/dist/factory-assets/connectors/postgres.js +7 -7
  115. package/dist/factory-assets/connectors/s3.js +7 -7
  116. package/dist/factory-assets/connectors/sharepoint/driver.d.ts.map +1 -1
  117. package/dist/factory-assets/connectors/sharepoint.js +7 -7
  118. package/dist/factory-assets/connectors/sqlite.js +7 -7
  119. package/dist/factory-assets/connectors/static-server.js +7 -7
  120. package/dist/factory-assets/connectors/tunnel.js +7 -7
  121. package/dist/factory-assets/connectors/webdav/driver.d.ts.map +1 -1
  122. package/dist/factory-assets/connectors/webdav.js +7 -7
  123. package/dist/factory-assets/connectors/xstate-store.js +7 -7
  124. package/dist/factory-assets/connectors/xstate.js +7 -7
  125. package/dist/{flows-3MBK2PDN.js → flows-KTBCZ5GQ.js} +3 -3
  126. package/dist/{flows-3MBK2PDN.js.map → flows-KTBCZ5GQ.js.map} +1 -1
  127. package/dist/library/index.js +6 -6
  128. package/dist/library/install.js +4 -4
  129. package/dist/{open-library-QSIPFN5N.js → open-library-EV7UCOFU.js} +9 -9
  130. package/dist/{open-library-QSIPFN5N.js.map → open-library-EV7UCOFU.js.map} +1 -1
  131. package/dist/{paths-KNLBYALO.js → paths-7H5CSBLQ.js} +7 -7
  132. package/dist/{paths-KNLBYALO.js.map → paths-7H5CSBLQ.js.map} +1 -1
  133. package/dist/{plugin-store-CL6CTREE.js → plugin-store-LGLN2QUX.js} +6 -6
  134. package/dist/{plugin-store-CL6CTREE.js.map → plugin-store-LGLN2QUX.js.map} +1 -1
  135. package/dist/runner/index.js +11 -11
  136. package/dist/runner/src/fleet-health-flag-dispatcher.d.ts +3 -2
  137. package/dist/runner/src/fleet-health-flag-dispatcher.d.ts.map +1 -1
  138. package/dist/runner/src/mcp-prompt.d.ts +8 -0
  139. package/dist/runner/src/mcp-prompt.d.ts.map +1 -0
  140. package/dist/runner/src/resource-handler.d.ts +1 -1
  141. package/dist/runner/src/resource-handler.d.ts.map +1 -1
  142. package/dist/runner/src/resources.d.ts +6 -0
  143. package/dist/runner/src/resources.d.ts.map +1 -1
  144. package/dist/runner/src/session-builder.d.ts.map +1 -1
  145. package/dist/sdk/asset-manager.js +6 -6
  146. package/dist/sdk/bridge.js +2 -2
  147. package/dist/sdk/core.js +4 -4
  148. package/dist/sdk/flow.js +4 -4
  149. package/dist/sdk/index.js +11 -11
  150. package/dist/sdk/runner.js +11 -11
  151. package/dist/sdk/session.js +1 -1
  152. package/dist/session/index.js +1 -1
  153. package/dist/session/src/dispatcher.d.ts +8 -0
  154. package/dist/session/src/dispatcher.d.ts.map +1 -1
  155. package/dist/{setup-345XOCH3.js → setup-EVNPECSY.js} +8 -8
  156. package/dist/{setup-345XOCH3.js.map → setup-EVNPECSY.js.map} +1 -1
  157. package/dist/{store-client-W3HKRE46.js → store-client-4XN7IB3R.js} +7 -7
  158. package/dist/{store-client-W3HKRE46.js.map → store-client-4XN7IB3R.js.map} +1 -1
  159. package/dist/tui/index.js +11 -11
  160. package/dist/types/src/events.d.ts +1 -1
  161. package/dist/types/src/events.d.ts.map +1 -1
  162. package/dist/workspace-plugin/adapters/mcp.js +1 -1
  163. package/dist/workspace-plugin/adapters/omp.js +3 -3
  164. package/dist/workspace-plugin/index.js +1 -1
  165. package/package.json +1 -1
  166. package/dist/chunk-2ZI2FFFN.js.map +0 -1
  167. package/dist/chunk-5VJVSYXX.js.map +0 -1
  168. package/dist/chunk-B5PEERRZ.js.map +0 -1
  169. package/dist/chunk-HZXOCRLD.js.map +0 -1
  170. package/dist/chunk-NQDJQ7WB.js.map +0 -1
  171. package/dist/chunk-SBGHNXJD.js.map +0 -1
  172. package/dist/chunk-X4FCLBI7.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../session/src/dispatcher.ts","../session/src/mentions.ts"],"names":[],"mappings":"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","file":"chunk-SBGHNXJD.js","sourcesContent":["import type { AgentClient } from \"@skaile/workspaces/client\";\nimport type {\n AgentCommand,\n AgentEvent,\n ConnectorRequestCommand,\n ConnectorResponseEvent,\n Mention,\n ReplyRef,\n} from \"@skaile/workspaces/types\";\nimport type { Message, MessageStore, SubscriberInfo, SubscriberTransport } from \"./types.js\";\n\n/**\n * Construction options for {@link SessionDispatcher}.\n *\n * All three infrastructure objects (`client`, `store`, `transport`) are\n * injected by the caller so the dispatcher remains testable and framework-agnostic.\n *\n * @docLink packages/session/api-reference#session-dispatcher\n */\nexport interface SessionDispatcherOptions {\n /** Unique identifier for the session this dispatcher manages. */\n sessionId: string;\n /** Connected agent client used to send commands and receive events. */\n client: AgentClient;\n /** Persistence layer for all non-transient messages. */\n store: MessageStore;\n /** Fan-out transport for broadcasting events to connected frontends. */\n transport: SubscriberTransport;\n /**\n * When true, the dispatcher prepends conversation history to every prompt\n * command sent to the agent. Enable for agents without native session\n * continuity (e.g. mock mode). Agents with native multi-turn support\n * (Claude SDK, OMP) should set this to false to avoid duplicate context.\n * Default: false.\n */\n injectConversationHistory?: boolean;\n /** Max conversation history messages to include in enriched prompts (default: 50). */\n historyLimit?: number;\n /**\n * Optional callback to transform prompt text before forwarding to the agent.\n * The original (untransformed) prompt is persisted and broadcast to subscribers.\n * Applied after conversation history enrichment. Use this to inject context\n * (e.g. UI state) that the agent should see but subscribers should not.\n */\n transformPrompt?: (prompt: string, senderId: string | undefined, replyTo?: ReplyRef) => string;\n}\n\n/**\n * Command and event types classified as transient RPC — high-frequency,\n * ephemeral, and not part of the conversation history.\n *\n * Matching payloads are forwarded and broadcast but never persisted\n * or assigned a sequence number, preventing bloat in the message log.\n */\nconst TRANSIENT_TYPES = new Set([\n \"resource_request\",\n \"resource_response\",\n \"resources_available\",\n \"commands_available\",\n \"state_changed\",\n \"typing\",\n \"user_message\",\n // OMP session tracking — forwarded to subscribers but not persisted\n \"session_info\",\n // Structured log forwarding — high-volume; persisted in per-session SQLite, not the message store\n \"log_entry\",\n // Generic connector dispatch — system RPC, not chat messages.\n // Replaces the 6 typed flow commands removed in Protocol 2.2 (Phase 4 of the\n // flow-connector extraction). `connector_mutate` against the `flow` connector\n // is now how hosts drive flow execution between turns.\n \"connector_mutate\",\n \"connector_query\",\n \"connector_query_response\",\n]);\n\n/**\n * Bridges a single agent session between an {@link AgentClient} and one or more\n * frontend subscribers.\n *\n * Responsibilities:\n * - Persists every non-transient command and event as a {@link Message} with a\n * monotonic sequence number via the injected {@link MessageStore}.\n * - Fans agent events out to all connected frontends via the injected\n * {@link SubscriberTransport}.\n * - Optionally enriches prompt commands with conversation history so agents\n * without native multi-turn support maintain context across turns.\n *\n * **Lifecycle:** call {@link init} before any other method, and {@link disconnect}\n * when the session ends.\n *\n * @example\n * ```ts\n * const dispatcher = new SessionDispatcher({\n * sessionId: 'sess-123',\n * client: agentClient,\n * store: prismaMessageStore,\n * transport: trpcTransport,\n * })\n * await dispatcher.init()\n * const history = await dispatcher.subscribe('ws-conn-abc', { limit: 50 })\n * const msg = await dispatcher.sendCommand({ type: 'prompt', prompt: 'Hello' }, 'user-42')\n * await dispatcher.disconnect()\n * ```\n *\n * @docLink packages/session/api-reference#session-dispatcher\n */\nexport class SessionDispatcher {\n /** The session identifier this dispatcher is bound to. */\n readonly sessionId: string;\n private client: AgentClient;\n private store: MessageStore;\n private transport: SubscriberTransport;\n private subscribers: Set<string> = new Set();\n private subscriberMeta: Map<string, SubscriberInfo> = new Map();\n private seq: number = 0;\n private _availableResources: { mounts: unknown[]; connectors: unknown[] } = {\n mounts: [],\n connectors: [],\n };\n\n /** Whether to inject conversation history into prompt commands. */\n private readonly injectConversationHistory: boolean;\n /** Maximum number of history messages to include in enriched prompts. */\n private readonly historyLimit: number;\n /** Optional prompt transformer applied before forwarding (after persistence). */\n private _transformPrompt?: (\n prompt: string,\n senderId: string | undefined,\n replyTo?: ReplyRef,\n ) => string;\n /** Whether the dispatcher is currently in compaction mode. */\n private _compacting = false;\n /** Accumulated text content during compaction. */\n private _compactionText = \"\";\n\n /**\n * One-shot waiters registered via {@link onceNextFinished}. Each is invoked\n * exactly once with the text of the next `finished` assistant event, then\n * the list is cleared. Backs the A2A router's synchronous `ask` answer\n * capture.\n */\n private nextFinishedWaiters: Array<(text: string) => void> = [];\n /**\n * Text streamed by the agent since the last `finished` event. Used as the\n * fallback answer text for {@link onceNextFinished} when a `finished` event\n * carries an empty `summary` (drivers that stream `text` chunks and leave\n * the summary blank).\n */\n private _turnText = \"\";\n\n /**\n * @param opts - Dispatcher configuration — see {@link SessionDispatcherOptions}.\n */\n constructor(opts: SessionDispatcherOptions) {\n this.sessionId = opts.sessionId;\n this.client = opts.client;\n this.store = opts.store;\n this.transport = opts.transport;\n this.injectConversationHistory = opts.injectConversationHistory ?? false;\n this.historyLimit = opts.historyLimit ?? 50;\n this._transformPrompt = opts.transformPrompt;\n }\n\n /**\n * Replace the prompt transformer at runtime.\n *\n * Useful when additional context (e.g. a UI state cache) becomes available\n * after the dispatcher is constructed but before the first prompt is sent.\n */\n set transformPrompt(fn:\n | ((prompt: string, senderId: string | undefined, replyTo?: ReplyRef) => string)\n | undefined,) {\n this._transformPrompt = fn;\n }\n\n /**\n * Initialize the dispatcher for this session.\n *\n * Restores the monotonic sequence counter from the store and wires up the\n * agent event listener. Must be called once before any other method.\n *\n * @throws If {@link MessageStore.getLatestSeq} rejects.\n */\n async init(): Promise<void> {\n this.seq = await this.store.getLatestSeq(this.sessionId);\n this.client.onEvent((event: AgentEvent) => {\n void this.handleAgentEvent(event);\n });\n }\n\n /**\n * Register a frontend subscriber and return recent message history.\n *\n * Subsequent agent events are pushed to this subscriber via the\n * {@link SubscriberTransport} until {@link unsubscribe} is called.\n *\n * @param subscriberId - Opaque connection ID (e.g. WebSocket session ID).\n * @param opts - Optional subscription options.\n * @param opts.limit - Number of recent messages to return (default: 50).\n * @returns Recent messages ordered by seq ascending.\n */\n async subscribe(\n subscriberId: string,\n opts?: { limit?: number; userId?: string; roles?: string[] },\n ): Promise<Message[]> {\n this.subscribers.add(subscriberId);\n if (opts?.userId !== undefined || opts?.roles !== undefined) {\n this.subscriberMeta.set(subscriberId, {\n userId: opts.userId,\n roles: opts.roles,\n });\n }\n return this.store.getMessages(this.sessionId, {\n limit: opts?.limit ?? 50,\n });\n }\n\n /**\n * Remove a frontend subscriber and release transport resources.\n *\n * @param subscriberId - The ID passed to {@link subscribe}.\n */\n unsubscribe(subscriberId: string): void {\n this.subscribers.delete(subscriberId);\n this.subscriberMeta.delete(subscriberId);\n this.transport.remove(subscriberId);\n }\n\n /**\n * Send a command from a frontend to the agent.\n *\n * Persistent commands are wrapped in a Message envelope and stored before\n * forwarding. Transient commands (resource RPC) are forwarded directly\n * without persistence — returns null in that case.\n *\n * For `prompt` commands, the original message is persisted, but an enriched\n * version (with conversation history prepended) is sent to the agent so it\n * maintains context across turns.\n *\n * @param command - The command to dispatch to the agent (a prompt or tool result).\n * @param senderId - ID of the user sending the command, if known.\n * @param mentions - Resolved mention objects extracted from the prompt text.\n * @param visibility - Optional platform visibility envelope (F-23). When\n * `visibilityMode` is `HumansOnly`, or `Private` without the `\"__agent__\"`\n * sentinel in `privateRecipientIds` (B-30), the message is persisted and\n * broadcast to subscribers but NOT forwarded to the agent.\n * @param outgoingPrefix - Optional text prepended to the outgoing command's\n * user-text field ({@link command.prompt} / `command.answer` /\n * `command.content`) AFTER persistence but BEFORE history enrichment and\n * {@link transformPrompt}. The persisted {@link Message} envelope is built\n * from the original `command` and never sees the prefix. Use this to\n * inject one-shot wake-time context (Option B1 pending restoration\n * prompt) that the agent must see but UI subscribers must not.\n * @returns The persisted Message envelope, or null for transient command types.\n */\n async sendCommand(\n command: AgentCommand,\n senderId?: string,\n mentions?: Mention[],\n visibility?: NonNullable<Message[\"visibility\"]>,\n outgoingPrefix?: string,\n ): Promise<Message | null> {\n if (!this.shouldPersist(command)) {\n this.client.send(command);\n return null;\n }\n // Persist the original command (unenriched/untransformed/un-prefixed).\n // `outgoingPrefix` is intentionally NOT applied here — it must only\n // reach the agent client, never the MessageStore.\n const message = this.createMessage(command, senderId);\n // @TODO: Code-Review: v1 back-compat — mentions field no longer used by Protocol v2+ persistence layers; remove once platform PrismaMessageStore is migrated\n if (mentions?.length) message.mentions = mentions;\n // F-23: platform-extension visibility metadata (3.2.0). The platform\n // MessageStore reads this off the envelope and writes the\n // Message.visibilityMode column + recipient rows atomically with\n // the message itself — no post-send patch, no race window where a\n // concurrent send could mis-tag the wrong message id.\n if (visibility) message.visibility = visibility;\n await this.store.append(message);\n\n // Build the outgoing command — enrich and transform prompt commands\n // while leaving the persisted message untouched.\n let outgoing: AgentCommand = command;\n if (command.type === \"prompt\") {\n let prompt = command.prompt;\n // Restoration prefix lands FIRST (innermost) so the user's typed\n // text remains adjacent to its own framing, with history and reply\n // preambles wrapping the combined block from the outside in.\n if (outgoingPrefix) {\n prompt = `${outgoingPrefix}${prompt}`;\n }\n if (this.injectConversationHistory) {\n prompt = await this.enrichPromptWithHistory(prompt);\n }\n if (this._transformPrompt) {\n prompt = this._transformPrompt(prompt, senderId, command.replyTo);\n }\n if (prompt !== command.prompt) {\n outgoing = { ...command, prompt };\n }\n } else if (outgoingPrefix && command.type === \"reply\") {\n // `reply` carries user text in `answer`. Prefix is invisible to\n // subscribers (who see the persisted Message.payload.answer) but\n // visible to the agent driver.\n outgoing = { ...command, answer: `${outgoingPrefix}${command.answer}` };\n } else if (outgoingPrefix && command.type === \"custom_message\") {\n // `custom_message` carries user text in `content`. Same persist/send\n // split as the `reply` branch above.\n outgoing = { ...command, content: `${outgoingPrefix}${command.content}` };\n }\n\n // F-23 P3 review (B1) — HumansOnly visibility means the message is\n // intended for human recipients only; the agent must NOT see the\n // prompt content. Persist + broadcast (humans read it via\n // SubscriberTransport) but skip the agent forward. This closes a\n // critical privacy hole where `@user: secret` was persisted with\n // visibilityMode='HumansOnly' yet still reached the LLM. Threads\n // starting HumansOnly stay agent-invisible even on Public follow-ups\n // (parent-thread visibility threading is intentionally out of scope\n // for v1; only the immediate message is gated). See\n // platform/_concept/plans/f-23-p3-review-blockers.md.\n if (visibility?.visibilityMode === \"HumansOnly\") {\n return message;\n }\n\n // B-30 — Private visibility (F-23 `@mention_` underscore suffix) means the\n // message is addressed to an explicit recipient set. The agent is only a\n // recipient when the sender wrote `@agent_`, which the platform encodes as\n // the `\"__agent__\"` sentinel in `privateRecipientIds`. When the sentinel is\n // absent the message is a private human-to-human exchange: persist +\n // broadcast (the named human recipients read it via SubscriberTransport)\n // but skip the agent forward so the LLM never sees private content.\n if (\n visibility?.visibilityMode === \"Private\" &&\n !visibility.privateRecipientIds?.includes(\"__agent__\")\n ) {\n return message;\n }\n\n this.client.send(outgoing);\n return message;\n }\n\n /**\n * Persist a synthetic event (not received from the agent) and broadcast it.\n *\n * Used by the platform to inject events like a partial-text `finished` record\n * before a cancel command.\n *\n * @param event - The agent event to persist.\n * @param mentions - Resolved mentions from the originating command.\n */\n async persistEvent(event: AgentEvent, mentions?: Mention[]): Promise<Message | null> {\n return this.handleAgentEvent(event, mentions);\n }\n\n /**\n * Load paginated message history for this session.\n *\n * @param opts.before - Return messages with seq strictly less than this value.\n * @param opts.limit - Maximum number of messages to return.\n */\n async getMessages(opts?: { before?: number; limit?: number }): Promise<Message[]> {\n return this.store.getMessages(this.sessionId, opts);\n }\n\n /**\n * Available mounts and connectors captured from the most recent\n * `resources_available` event emitted by the agent on connect.\n *\n * Empty until the agent emits the event or {@link seedResources} is called.\n */\n get availableResources(): { mounts: unknown[]; connectors: unknown[] } {\n return this._availableResources;\n }\n\n /**\n * Seed the available resources from an external cache.\n *\n * This is needed when the dispatcher is created after the agent has already\n * emitted `resources_available` on WebSocket connect. Without seeding, the\n * dispatcher would report an empty resource list until the next reconnect.\n *\n * @param resources - Resource handles to register before the session starts.\n */\n seedResources(resources: { mounts: unknown[]; connectors: unknown[] }): void {\n const empty =\n this._availableResources.mounts.length === 0 &&\n this._availableResources.connectors.length === 0;\n if (empty && (resources.mounts.length > 0 || resources.connectors.length > 0)) {\n this._availableResources = resources;\n }\n }\n\n /**\n * Deliver a prompt to the agent that triggers a turn but is NOT persisted.\n *\n * Unlike {@link sendCommand}, this never touches the {@link MessageStore}:\n * the prompt is forwarded straight to the agent client. The caller owns\n * persistence of whatever conversation rows should represent this turn.\n *\n * Used by the platform's A2A router to deliver a `from-peer` prompt to a\n * target session: the router writes the authoritative A2A `Message` rows\n * itself, so persisting the framed prompt here too would create an extra,\n * un-attributed plain `prompt` row. The dispatcher's job for this prompt is\n * delivery only.\n *\n * The agent still produces a normal turn, so an A2A `ask` round-trip can\n * capture the answer via {@link onceNextFinished}.\n *\n * @param prompt - The fully-formed prompt text to deliver to the agent.\n */\n deliverPrompt(prompt: string): void {\n this.client.send({ type: \"prompt\", prompt });\n }\n\n /**\n * Send a resource request and await the correlated response.\n *\n * This is a convenience method for request/response resource RPC.\n * The request is transient (not persisted). A one-shot event listener\n * waits for the matching `resource_response` by `requestId`.\n *\n * @param command - A ConnectorRequestCommand (caller must set requestId).\n * @param timeoutMs - How long to wait before rejecting (default: 30s).\n */\n async requestResource(\n command: ConnectorRequestCommand,\n timeoutMs = 30_000,\n ): Promise<ConnectorResponseEvent> {\n return new Promise<ConnectorResponseEvent>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.client.offEvent(handler);\n reject(\n new Error(\n `Resource request timed out after ${timeoutMs}ms: ${command.operation} ${command.connectorId}`,\n ),\n );\n }, timeoutMs);\n\n const handler = (event: AgentEvent) => {\n if (event.type === \"resource_response\" && event.requestId === command.requestId) {\n clearTimeout(timer);\n this.client.offEvent(handler);\n resolve(event);\n }\n };\n\n this.client.onEvent(handler);\n this.client.send(command);\n });\n }\n\n /**\n * Broadcast a transient event to all subscribers without persisting it.\n *\n * Used for ephemeral signals like typing indicators or user-command\n * echoes that other subscribers need to see in real time.\n */\n broadcast(event: AgentEvent): void {\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n }\n\n /** Disconnect the agent client and clean up all subscribers. */\n async disconnect(): Promise<void> {\n for (const id of this.subscribers) {\n this.transport.remove(id);\n }\n this.subscribers.clear();\n this.subscriberMeta.clear();\n // Clear any pending A2A waiters so they don't leak if the session\n // disconnects before the target ever emits a `finished` event.\n this.nextFinishedWaiters = [];\n await this.client.dispose();\n }\n\n /**\n * Enter compaction mode. While active, events from the agent are captured\n * but NOT persisted. Text content is accumulated for the snapshot.\n */\n beginCompaction(): void {\n this._compacting = true;\n this._compactionText = \"\";\n }\n\n /**\n * Exit compaction mode and return the accumulated text.\n * The caller is responsible for creating and emitting the snapshot event.\n */\n endCompaction(): string {\n this._compacting = false;\n const text = this._compactionText;\n this._compactionText = \"\";\n return text;\n }\n\n /** Whether the dispatcher is currently in compaction mode. */\n get isCompacting(): boolean {\n return this._compacting;\n }\n\n /**\n * Register a one-shot callback fired with the text of this session's next\n * finished assistant turn. Returns an unsubscribe function.\n *\n * Semantics:\n * - The callback fires **at most once** — on the first `finished` event\n * observed after registration. Later finished turns do not re-fire it.\n * - A waiter registered after a `finished` event waits for the *following*\n * one. The hook captures the *next* finished turn, not a past one.\n * - The answer text is the `finished` event's `summary`; when that is\n * empty (drivers that stream `text` and leave the summary blank), the\n * text accumulated since the previous finished turn is used instead.\n * - Calling the returned function removes the waiter; if it has already\n * fired this is a no-op.\n *\n * Used by the platform's A2A router (`A2ARouterService.ask`) to capture a\n * peer session's answer to a `from-peer` question. v1 captures the first\n * finished turn after delivery — see the busy-target notes in the A2A\n * design spec for the known turn-matching limitation.\n *\n * @param cb - Invoked once with the next finished turn's text.\n * @returns Unsubscribe function that removes this waiter.\n */\n onceNextFinished(cb: (text: string) => void): () => void {\n this.nextFinishedWaiters.push(cb);\n return () => {\n const idx = this.nextFinishedWaiters.indexOf(cb);\n if (idx !== -1) {\n this.nextFinishedWaiters.splice(idx, 1);\n }\n };\n }\n\n // -- Private ----------------------------------------------------------------\n\n /**\n * Build an enriched prompt by prepending conversation history.\n *\n * Loads recent persisted messages, formats user/assistant turns, and\n * wraps them in a `<conversation_history>` block. The current user\n * message (just persisted) is excluded since it is already the prompt.\n *\n * Returns the original prompt unchanged if there is no prior history.\n */\n private async enrichPromptWithHistory(currentPrompt: string): Promise<string> {\n const messages = await this.store.getMessages(this.sessionId, {\n limit: this.historyLimit,\n });\n\n // Filter to conversation-relevant types and exclude the message we just appended\n const history = messages\n .filter((m) => {\n const type = m.payload.type;\n return type === \"prompt\" || type === \"finished\" || type === \"question\";\n })\n .slice(0, -1); // Exclude the current message (last by seq)\n\n if (history.length === 0) {\n return currentPrompt;\n }\n\n const lines = history.map((m) => {\n const p = m.payload as Record<string, unknown>;\n if (p.type === \"prompt\") {\n return `[User]: ${String(p.prompt ?? \"\")}`;\n }\n // finished (assistant response) or question\n const content = String(p.summary ?? p.question ?? \"\");\n return `[Assistant]: ${content}`;\n });\n\n return `<conversation_history>\\n${lines.join(\"\\n\")}\\n</conversation_history>\\n\\n${currentPrompt}`;\n }\n\n private async handleAgentEvent(event: AgentEvent, mentions?: Mention[]): Promise<Message | null> {\n // ── Compaction mode: capture text but don't persist ─────────────────\n if (this._compacting) {\n if (event.type === \"text\") {\n this._compactionText += (event as { content: string }).content;\n }\n // Still broadcast to subscribers (UI shows compaction progress)\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n return null;\n }\n\n // Capture resource metadata when the server announces available resources\n if (event.type === \"resources_available\") {\n const payload = event as { mounts?: unknown[]; connectors?: unknown[] };\n this._availableResources = {\n mounts: payload.mounts ?? [],\n connectors: payload.connectors ?? [],\n };\n }\n\n // ── onceNextFinished — one-shot \"next finished turn\" answer capture ──\n // Accumulate streamed text across the turn so the answer is available\n // even when a driver emits an empty `finished.summary`. On `finished`,\n // drain every queued waiter exactly once, then reset the accumulator.\n if (event.type === \"text\") {\n this._turnText += (event as { content: string }).content;\n } else if (event.type === \"finished\") {\n const summary = (event as { summary?: string }).summary ?? \"\";\n const answer = summary.length > 0 ? summary : this._turnText;\n this._turnText = \"\";\n if (this.nextFinishedWaiters.length > 0) {\n const waiters = this.nextFinishedWaiters;\n this.nextFinishedWaiters = [];\n for (const cb of waiters) {\n cb(answer);\n }\n }\n }\n\n let message: Message | null = null;\n if (this.shouldPersist(event)) {\n message = this.createMessage(event);\n if (mentions?.length) message.mentions = mentions;\n await this.store.append(message);\n }\n\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n return message;\n }\n\n private shouldPersist(payload: AgentCommand | AgentEvent): boolean {\n return !TRANSIENT_TYPES.has(payload.type);\n }\n\n private createMessage(payload: AgentCommand | AgentEvent, senderId?: string): Message {\n this.seq++;\n return {\n id: crypto.randomUUID(),\n seq: this.seq,\n timestamp: new Date().toISOString(),\n sessionId: this.sessionId,\n ...(senderId ? { senderId } : {}),\n payload,\n };\n }\n}\n","import type { Mention, MentionGroup } from \"@skaile/workspaces/types\";\nimport { MENTION_GROUPS } from \"@skaile/workspaces/types\";\n\n/**\n * Re-exported from `@skaile/workspaces/types` so consumers can import mention\n * types directly from `@skaile/workspaces/session` without a separate dependency.\n */\nexport type { Mention, MentionGroup };\n\n// ---------------------------------------------------------------------------\n// MentionResolver\n// ---------------------------------------------------------------------------\n\n/**\n * Consumer-provided resolver that maps @mention tokens to users and groups.\n *\n * The platform provides an implementation backed by Prisma and the live\n * presence service. Tests use lightweight mocks.\n *\n * @example\n * ```ts\n * const resolver: MentionResolver = {\n * resolveUser: (name) => db.users.findByName(name),\n * resolveGroup: (group) => presence.getMemberIds(group),\n * getOnlineUserIds: () => presence.getOnlineIds(),\n * }\n * ```\n *\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport interface MentionResolver {\n /**\n * Resolve a `@name` token to a user record.\n *\n * @param name - The token after the `@` symbol (case-insensitive lookup).\n * @returns User record, or null if the name is not found.\n */\n resolveUser(name: string): { userId: string; name: string } | null;\n /**\n * Resolve a group mention token to the list of member user IDs.\n *\n * @param group - The well-known group name (e.g. `\"agent\"`, `\"all\"`).\n * @returns Array of member user IDs belonging to the group.\n */\n resolveGroup(group: MentionGroup): string[];\n /** Return the IDs of users currently online (used by the `here` and `humans_here` groups). */\n getOnlineUserIds(): string[];\n}\n\n// ---------------------------------------------------------------------------\n// parseMentions\n// ---------------------------------------------------------------------------\n\nconst MENTION_RE = /@(\\w+)/g;\nconst MENTION_GROUP_SET: ReadonlySet<string> = new Set(MENTION_GROUPS);\n\n/**\n * Scan `text` for @token patterns and return resolved {@link Mention} objects.\n *\n * - Well-known group tokens (`agent`, `humans`, `humans_here`, `here`, `all`)\n * are resolved via {@link MentionResolver.resolveGroup}.\n * - All other tokens are resolved via {@link MentionResolver.resolveUser}.\n * - Tokens that cannot be resolved are silently ignored.\n * - Results are sorted by character offset ascending.\n *\n * @param text - Raw message text to scan for `@token` patterns.\n * @param resolver - Resolver that maps tokens to users and groups.\n * @returns Resolved mentions ordered by position in text.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function parseMentions(text: string, resolver: MentionResolver): Mention[] {\n const mentions: Mention[] = [];\n\n for (const match of text.matchAll(MENTION_RE)) {\n const token = match[1]!;\n const offset = match.index!;\n const length = match[0].length; // includes the @\n\n if (MENTION_GROUP_SET.has(token)) {\n const group = token as MentionGroup;\n mentions.push({\n type: \"group\",\n group,\n resolved: resolver.resolveGroup(group),\n offset,\n length,\n });\n } else {\n const user = resolver.resolveUser(token);\n if (user) {\n mentions.push({\n type: \"user\",\n userId: user.userId,\n name: user.name,\n offset,\n length,\n });\n }\n }\n }\n\n // matchAll iterates left-to-right, so mentions are already offset-ascending.\n return mentions;\n}\n\n// ---------------------------------------------------------------------------\n// isMentioned\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if `userId` is directly mentioned or is a member of any\n * group mention's resolved list.\n *\n * @param userId - The user ID to check (e.g. from the auth context).\n * @param mentions - Parsed mentions from {@link parseMentions}.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function isMentioned(userId: string, mentions: Mention[]): boolean {\n for (const m of mentions) {\n if (m.type === \"user\" && m.userId === userId) return true;\n if (m.type === \"group\" && m.resolved.includes(userId)) return true;\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// isAgentAddressed\n// ---------------------------------------------------------------------------\n\n/** Groups that include the agent in their resolved membership. */\nconst AGENT_GROUPS: ReadonlySet<MentionGroup> = new Set([\"agent\", \"here\", \"all\"]);\n\n/**\n * Returns true if the agent is addressed by any mention in the list.\n *\n * The groups `@agent`, `@here`, and `@all` address the agent. `@humans`\n * and `@humans_here` do not. Individual user mentions are also not matched\n * here — agent addressing is group-based.\n *\n * @param mentions - Parsed mentions from {@link parseMentions}.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function isAgentAddressed(mentions: Mention[]): boolean {\n return mentions.some((m) => m.type === \"group\" && AGENT_GROUPS.has(m.group));\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../connectors/src/materialized-connectors.ts","../connectors/src/secrets.ts","../connectors/src/config.ts"],"names":[],"mappings":"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","file":"chunk-X4FCLBI7.js","sourcesContent":["/**\n * Derive runtime connector declarations from the platform-materialized\n * `.skaile/assets/connector/<name>/CONNECTOR.md` projection.\n *\n * Connector mirror of MCP's `loadMaterializedMcpDeclarations` /\n * `deriveSingleMaterializedMcpDeclaration`. The generated `CONNECTOR.md` carries\n * a RUNTIME declaration (driver/access/auth/mode/options/mount) — distinct from\n * the catalog `CONNECTOR.md` parsed by `core/manifest.ts:fromConnectorMd`\n * (entry/fields). Driver is referenced by name (first-party; resolved via the\n * connector registry — no code-loading).\n */\nimport { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parseFrontmatter } from \"@skaile/workspaces/core\";\nimport type { ConnectorDeclaration } from \"./connector-types.js\";\n\n/** Parse a generated CONNECTOR.md (runtime projection) into a ConnectorDeclaration. */\nexport function fromMaterializedConnectorMd(filePath: string, name: string): ConnectorDeclaration {\n const { data: meta } = parseFrontmatter(readFileSync(filePath, \"utf8\"));\n const id = String(meta.name ?? name);\n const decl: ConnectorDeclaration = {\n id,\n driver: String(meta.driver ?? \"\"),\n access: meta.access === \"read-write\" ? \"read-write\" : \"read-only\",\n };\n if (typeof meta.auth === \"string\") decl.auth = meta.auth;\n if (meta.mode === \"agent\" || meta.mode === \"sync\") decl.mode = meta.mode;\n if (meta.options && typeof meta.options === \"object\" && !Array.isArray(meta.options)) {\n decl.options = meta.options as Record<string, unknown>;\n }\n if (meta.mount && typeof meta.mount === \"object\" && !Array.isArray(meta.mount)) {\n const m = meta.mount as Record<string, unknown>;\n decl.mount = {\n source: String(m.source ?? \"\"),\n ...(m.target !== undefined ? { target: String(m.target) } : {}),\n ...(typeof m.watch === \"boolean\" ? { watch: m.watch } : {}),\n ...(typeof m.exposeAccessToken === \"boolean\"\n ? { exposeAccessToken: m.exposeAccessToken }\n : {}),\n ...(typeof m.accessTokenTTL === \"number\" ? { accessTokenTTL: m.accessTokenTTL } : {}),\n };\n }\n return decl;\n}\n\n/** Provide `.instance.json` config entries as defaults under the declaration's options (the CONNECTOR.md declaration wins on key collision). */\nfunction foldInstanceConfig(decl: ConnectorDeclaration, instancePath: string): void {\n if (!existsSync(instancePath)) return;\n let parsed: { config?: Record<string, unknown> };\n try {\n parsed = JSON.parse(readFileSync(instancePath, \"utf8\"));\n } catch {\n return;\n }\n const config = parsed.config;\n if (!config || typeof config !== \"object\" || Array.isArray(config)) return;\n decl.options = { ...(config as Record<string, unknown>), ...(decl.options ?? {}) };\n}\n\n/** Derive a single materialized connector declaration; null when no CONNECTOR.md. */\nexport function deriveSingleMaterializedConnectorDeclaration(\n connectorAssetsDir: string,\n name: string,\n): ConnectorDeclaration | null {\n const sub = join(connectorAssetsDir, name);\n const md = join(sub, \"CONNECTOR.md\");\n if (!existsSync(md)) return null;\n const decl = fromMaterializedConnectorMd(md, name);\n foldInstanceConfig(decl, join(sub, \".instance.json\"));\n return decl;\n}\n\n/** Scan `<projectDir>/.skaile/assets/connector/*` for materialized connectors. */\nexport function loadMaterializedConnectorDeclarations(projectDir: string): ConnectorDeclaration[] {\n const root = join(projectDir, \".skaile/assets/connector\");\n if (!existsSync(root)) return [];\n const out: ConnectorDeclaration[] = [];\n for (const name of readdirSync(root)) {\n try {\n const sub = join(root, name);\n if (!statSync(sub).isDirectory()) continue;\n const decl = deriveSingleMaterializedConnectorDeclaration(root, name);\n if (decl) out.push(decl);\n } catch {\n // Per-directory failure is isolated — one bad asset never aborts the scan.\n }\n }\n return out;\n}\n","/**\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>`, `connector:<id>`, and `mcp:<id>`.\n * Returns `undefined` for any other ref so the chain falls through to the\n * next 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.add_mcp` capabilities\n * stay strictly in-process — no round trip to the platform to mint while\n * the resource 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, mcp }` map.\n */\n constructor(credentials?: {\n mounts?: Record<string, PreMintedCredential>;\n connectors?: Record<string, PreMintedCredential>;\n mcp?: 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 for (const [id, mint] of Object.entries(credentials.mcp ?? {})) {\n this.mints.set(`mcp:${id}`, mint);\n }\n }\n\n /**\n * Insert (or replace) a pre-minted credential. Used by\n * `runner.add_mount` / `runner.add_connector` / `runner.add_mcp` capability\n * handlers when the platform delivers new credentials mid-session.\n */\n set(kind: \"mount\" | \"connector\" | \"mcp\", 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\" | \"mcp\", 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:` / `mcp:` 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\" | \"mcp\", 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:\") || ref.startsWith(\"mcp:\")))\n 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 = [\n \"env:\",\n \"forge:\",\n \"op:\",\n \"kp:\",\n \"oauth:\",\n \"mount:\",\n \"connector:\",\n \"mcp:\",\n] 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 { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type {\n ConnectorDeclaration,\n TokenMediator,\n TokenMediatorResult,\n} from \"./connector-types.js\";\nimport { loadMaterializedConnectorDeclarations } from \"./materialized-connectors.js\";\n\nconst configLog = createLogger({ kind: \"connector\", subkind: \"config\" });\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 Merged array of connector declarations from `skaile.yaml` and the materialized\n * `.skaile/assets/connector/*` disk projection (Phase 2.5); empty array if neither source\n * contributes any entries. `skaile.yaml` wins on id collision.\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 const yamlDecls =\n config.connectors && config.connectors.length > 0\n ? config.connectors.map(workspaceConnectorToDeclaration)\n : [];\n\n // Library-assigned connectors reach the runner via the materialized disk\n // projection (Phase 2.5). skaile.yaml is explicit user config — it wins on id\n // collision; the shadowed materialized connector is logged, not silently dropped.\n const byId = new Map<string, ConnectorDeclaration>();\n for (const d of yamlDecls) byId.set(d.id, d);\n for (const d of loadMaterializedConnectorDeclarations(projectDir)) {\n if (byId.has(d.id)) {\n configLog.warn(\n `materialized connector '${d.id}' shadowed by an explicit skaile.yaml connector`,\n );\n continue;\n }\n byId.set(d.id, d);\n }\n return [...byId.values()];\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"]}