@skaile/workspaces 1.14.1 → 1.15.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 (193) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/NOTICE +13 -0
  3. package/dist/app-sdk/index.js +1 -1
  4. package/dist/{asset-feeds-ZQLJ2DCP.js → asset-feeds-MWEMXMZA.js} +5 -5
  5. package/dist/{asset-feeds-ZQLJ2DCP.js.map → asset-feeds-MWEMXMZA.js.map} +1 -1
  6. package/dist/asset-manager/index.js +5 -5
  7. package/dist/asset-manager/installer.js +1 -1
  8. package/dist/bridge/drivers/claude-sdk.js +31 -26
  9. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  10. package/dist/bridge/drivers/codex.js +1 -1
  11. package/dist/bridge/drivers/continue.js +2 -2
  12. package/dist/bridge/drivers/echo.js +1 -1
  13. package/dist/bridge/drivers/gemini.js +3 -3
  14. package/dist/bridge/drivers/goose.js +2 -2
  15. package/dist/bridge/drivers/omp.js +1 -1
  16. package/dist/bridge/drivers/opencode.js +2 -2
  17. package/dist/bridge/drivers/qwen.js +3 -3
  18. package/dist/bridge/index.js +2 -2
  19. package/dist/bridge/src/drivers/claude-sdk.d.ts +12 -56
  20. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  21. package/dist/channels/adapters/msteams/activity.d.ts +70 -0
  22. package/dist/channels/adapters/msteams/activity.d.ts.map +1 -0
  23. package/dist/channels/adapters/msteams/client.d.ts +46 -0
  24. package/dist/channels/adapters/msteams/client.d.ts.map +1 -0
  25. package/dist/channels/adapters/msteams/index.d.ts +81 -0
  26. package/dist/channels/adapters/msteams/index.d.ts.map +1 -0
  27. package/dist/channels/adapters/msteams/jwt.d.ts +27 -0
  28. package/dist/channels/adapters/msteams/jwt.d.ts.map +1 -0
  29. package/dist/channels/adapters/msteams.d.ts +2 -0
  30. package/dist/channels/adapters/msteams.js +595 -0
  31. package/dist/channels/adapters/msteams.js.map +1 -0
  32. package/dist/channels/index.d.ts +2 -0
  33. package/dist/channels/index.js +1069 -0
  34. package/dist/channels/index.js.map +1 -0
  35. package/dist/channels/src/adapter.d.ts +54 -0
  36. package/dist/channels/src/adapter.d.ts.map +1 -0
  37. package/dist/channels/src/dedupe.d.ts +67 -0
  38. package/dist/channels/src/dedupe.d.ts.map +1 -0
  39. package/dist/channels/src/egress/output-mirror.d.ts +63 -0
  40. package/dist/channels/src/egress/output-mirror.d.ts.map +1 -0
  41. package/dist/channels/src/egress/vendor/auto-close-streaming.d.ts +26 -0
  42. package/dist/channels/src/egress/vendor/auto-close-streaming.d.ts.map +1 -0
  43. package/dist/channels/src/egress/vendor/chunked-message-stream.d.ts +79 -0
  44. package/dist/channels/src/egress/vendor/chunked-message-stream.d.ts.map +1 -0
  45. package/dist/channels/src/egress/vendor/markdown-to-mrkdwn.d.ts +21 -0
  46. package/dist/channels/src/egress/vendor/markdown-to-mrkdwn.d.ts.map +1 -0
  47. package/dist/channels/src/egress/vendor/message-stream.d.ts +57 -0
  48. package/dist/channels/src/egress/vendor/message-stream.d.ts.map +1 -0
  49. package/dist/channels/src/engine.d.ts +125 -0
  50. package/dist/channels/src/engine.d.ts.map +1 -0
  51. package/dist/channels/src/format/adaptive-card.d.ts +17 -0
  52. package/dist/channels/src/format/adaptive-card.d.ts.map +1 -0
  53. package/dist/channels/src/format/mrkdwn.d.ts +4 -0
  54. package/dist/channels/src/format/mrkdwn.d.ts.map +1 -0
  55. package/dist/channels/src/format/types.d.ts +9 -0
  56. package/dist/channels/src/format/types.d.ts.map +1 -0
  57. package/dist/channels/src/index.d.ts +17 -0
  58. package/dist/channels/src/index.d.ts.map +1 -0
  59. package/dist/channels/src/mention/lookup-tool.d.ts +23 -0
  60. package/dist/channels/src/mention/lookup-tool.d.ts.map +1 -0
  61. package/dist/channels/src/mention/normalize.d.ts +27 -0
  62. package/dist/channels/src/mention/normalize.d.ts.map +1 -0
  63. package/dist/channels/src/mention/render.d.ts +10 -0
  64. package/dist/channels/src/mention/render.d.ts.map +1 -0
  65. package/dist/channels/src/ports.d.ts +71 -0
  66. package/dist/channels/src/ports.d.ts.map +1 -0
  67. package/dist/channels/src/types.d.ts +169 -0
  68. package/dist/channels/src/types.d.ts.map +1 -0
  69. package/dist/{chunk-A7GDV5BV.js → chunk-2BQBWWFX.js} +2 -2
  70. package/dist/{chunk-A7GDV5BV.js.map → chunk-2BQBWWFX.js.map} +1 -1
  71. package/dist/{chunk-MWE7DEGC.js → chunk-344DEXZS.js} +3 -3
  72. package/dist/{chunk-MWE7DEGC.js.map → chunk-344DEXZS.js.map} +1 -1
  73. package/dist/{chunk-T2H2ZCU4.js → chunk-73HV7RV3.js} +3 -3
  74. package/dist/{chunk-T2H2ZCU4.js.map → chunk-73HV7RV3.js.map} +1 -1
  75. package/dist/{chunk-HLIN4HRK.js → chunk-ACWCVB5Q.js} +2 -2
  76. package/dist/{chunk-HLIN4HRK.js.map → chunk-ACWCVB5Q.js.map} +1 -1
  77. package/dist/{chunk-P5VLR3L7.js → chunk-BI2NKPA4.js} +8 -4
  78. package/dist/chunk-BI2NKPA4.js.map +1 -0
  79. package/dist/{chunk-4RI4TNMO.js → chunk-DB264AVQ.js} +2 -2
  80. package/dist/{chunk-4RI4TNMO.js.map → chunk-DB264AVQ.js.map} +1 -1
  81. package/dist/{chunk-IIGWJE5T.js → chunk-DPUZJI45.js} +3 -3
  82. package/dist/{chunk-IIGWJE5T.js.map → chunk-DPUZJI45.js.map} +1 -1
  83. package/dist/{chunk-ZWPXSHMW.js → chunk-EKGB4ZWR.js} +336 -100
  84. package/dist/chunk-EKGB4ZWR.js.map +1 -0
  85. package/dist/chunk-F2IBDVBP.js +72 -0
  86. package/dist/chunk-F2IBDVBP.js.map +1 -0
  87. package/dist/{chunk-G73FOLLO.js → chunk-M5GJT3D7.js} +3 -3
  88. package/dist/{chunk-G73FOLLO.js.map → chunk-M5GJT3D7.js.map} +1 -1
  89. package/dist/{chunk-CS6NFRNQ.js → chunk-MJEUK6VJ.js} +2 -2
  90. package/dist/{chunk-CS6NFRNQ.js.map → chunk-MJEUK6VJ.js.map} +1 -1
  91. package/dist/{chunk-NIZNN42B.js → chunk-MNKUZUN2.js} +3 -3
  92. package/dist/{chunk-NIZNN42B.js.map → chunk-MNKUZUN2.js.map} +1 -1
  93. package/dist/{chunk-AF2NTM4B.js → chunk-NRXVS7E4.js} +6 -6
  94. package/dist/{chunk-AF2NTM4B.js.map → chunk-NRXVS7E4.js.map} +1 -1
  95. package/dist/{chunk-CC6LFFTI.js → chunk-O5VCUU6D.js} +4 -4
  96. package/dist/{chunk-CC6LFFTI.js.map → chunk-O5VCUU6D.js.map} +1 -1
  97. package/dist/{chunk-UDUFMVJD.js → chunk-RADBQ5XJ.js} +7 -7
  98. package/dist/{chunk-UDUFMVJD.js.map → chunk-RADBQ5XJ.js.map} +1 -1
  99. package/dist/{chunk-TSB46BHR.js → chunk-RDE43ORT.js} +4 -4
  100. package/dist/{chunk-TSB46BHR.js.map → chunk-RDE43ORT.js.map} +1 -1
  101. package/dist/{chunk-KECY74AL.js → chunk-SRWIVMJI.js} +4 -4
  102. package/dist/{chunk-KECY74AL.js.map → chunk-SRWIVMJI.js.map} +1 -1
  103. package/dist/{chunk-VK24PIAB.js → chunk-TFIFNDT2.js} +3 -3
  104. package/dist/{chunk-VK24PIAB.js.map → chunk-TFIFNDT2.js.map} +1 -1
  105. package/dist/{chunk-BIAA3N2A.js → chunk-Z6NGK5YC.js} +3 -3
  106. package/dist/{chunk-BIAA3N2A.js.map → chunk-Z6NGK5YC.js.map} +1 -1
  107. package/dist/cli/index.js +41 -41
  108. package/dist/connectors/config.js +1 -1
  109. package/dist/connectors/index.js +1 -1
  110. package/dist/core/index.js +1 -1
  111. package/dist/deploy/index.js +1 -1
  112. package/dist/{ensure-sources-O7X3LYLG.js → ensure-sources-QGL44IRI.js} +8 -8
  113. package/dist/{ensure-sources-O7X3LYLG.js.map → ensure-sources-QGL44IRI.js.map} +1 -1
  114. package/dist/factory-assets/connectors/box.js +1 -1
  115. package/dist/factory-assets/connectors/deploy.js +1 -1
  116. package/dist/factory-assets/connectors/devserver.js +1 -1
  117. package/dist/factory-assets/connectors/flow/adapter.js +1 -1
  118. package/dist/factory-assets/connectors/flow/engine.js +1 -1
  119. package/dist/factory-assets/connectors/flow/run-flow.js +2 -2
  120. package/dist/factory-assets/connectors/flow.js +1 -1
  121. package/dist/factory-assets/connectors/git.js +1 -1
  122. package/dist/factory-assets/connectors/gmail.js +1 -1
  123. package/dist/factory-assets/connectors/googledrive.js +1 -1
  124. package/dist/factory-assets/connectors/local.js +1 -1
  125. package/dist/factory-assets/connectors/mattermost.js +1 -1
  126. package/dist/factory-assets/connectors/memory.js +1 -1
  127. package/dist/factory-assets/connectors/minio.js +1 -1
  128. package/dist/factory-assets/connectors/postgres.js +1 -1
  129. package/dist/factory-assets/connectors/s3.js +1 -1
  130. package/dist/factory-assets/connectors/sharepoint.js +1 -1
  131. package/dist/factory-assets/connectors/sqlite.js +1 -1
  132. package/dist/factory-assets/connectors/static-server.js +1 -1
  133. package/dist/factory-assets/connectors/tunnel.js +1 -1
  134. package/dist/factory-assets/connectors/webdav.js +1 -1
  135. package/dist/factory-assets/connectors/xstate-store.js +1 -1
  136. package/dist/factory-assets/connectors/xstate.js +1 -1
  137. package/dist/{flows-TIUWM7SZ.js → flows-FHWBCLXF.js} +3 -3
  138. package/dist/{flows-TIUWM7SZ.js.map → flows-FHWBCLXF.js.map} +1 -1
  139. package/dist/{helpers-DNTGJSA5.js → helpers-FMWODXTW.js} +8 -8
  140. package/dist/{helpers-DNTGJSA5.js.map → helpers-FMWODXTW.js.map} +1 -1
  141. package/dist/library/index.js +4 -4
  142. package/dist/library/install.js +1 -1
  143. package/dist/{library-publish-XKQN6RTR.js → library-publish-7YDHQGBN.js} +10 -10
  144. package/dist/{library-publish-XKQN6RTR.js.map → library-publish-7YDHQGBN.js.map} +1 -1
  145. package/dist/{open-library-2BWIUK4F.js → open-library-O6T3ELPK.js} +9 -9
  146. package/dist/{open-library-2BWIUK4F.js.map → open-library-O6T3ELPK.js.map} +1 -1
  147. package/dist/{paths-KOKCMBL5.js → paths-5QJJBAND.js} +7 -7
  148. package/dist/{paths-KOKCMBL5.js.map → paths-5QJJBAND.js.map} +1 -1
  149. package/dist/{plugin-store-QMJ2B3VM.js → plugin-store-ZBJZ7F6D.js} +3 -3
  150. package/dist/{plugin-store-QMJ2B3VM.js.map → plugin-store-ZBJZ7F6D.js.map} +1 -1
  151. package/dist/{project-4NPDM7R3.js → project-HAMLHLD5.js} +9 -9
  152. package/dist/{project-4NPDM7R3.js.map → project-HAMLHLD5.js.map} +1 -1
  153. package/dist/runner/index.js +8 -8
  154. package/dist/runner/src/serve.d.ts +138 -1
  155. package/dist/runner/src/serve.d.ts.map +1 -1
  156. package/dist/sdk/asset-manager.js +5 -5
  157. package/dist/sdk/bridge.js +2 -2
  158. package/dist/sdk/core.js +1 -1
  159. package/dist/sdk/flow.js +1 -1
  160. package/dist/sdk/index.js +8 -8
  161. package/dist/sdk/runner.js +8 -8
  162. package/dist/sdk/session.js +2 -2
  163. package/dist/sdk/transport/ws.js +1 -1
  164. package/dist/sdk/transport.js +1 -1
  165. package/dist/sdk/types.js +1 -1
  166. package/dist/session/index.js +2 -2
  167. package/dist/session/src/dispatcher.d.ts.map +1 -1
  168. package/dist/{setup-TNHKXCBL.js → setup-WJPNUE32.js} +5 -5
  169. package/dist/{setup-TNHKXCBL.js.map → setup-WJPNUE32.js.map} +1 -1
  170. package/dist/{source-HVMQJZU7.js → source-ITDH4367.js} +10 -10
  171. package/dist/{source-HVMQJZU7.js.map → source-ITDH4367.js.map} +1 -1
  172. package/dist/{source-manifest-publish-JN62UMZD.js → source-manifest-publish-RMHC7R6M.js} +11 -11
  173. package/dist/{source-manifest-publish-JN62UMZD.js.map → source-manifest-publish-RMHC7R6M.js.map} +1 -1
  174. package/dist/transport/index.js +1 -1
  175. package/dist/transport/ws.js +1 -1
  176. package/dist/tui/index.js +8 -8
  177. package/dist/types/index.js +1 -1
  178. package/dist/types/src/events.d.ts +74 -1
  179. package/dist/types/src/events.d.ts.map +1 -1
  180. package/dist/types/src/flow.d.ts +34 -0
  181. package/dist/types/src/flow.d.ts.map +1 -1
  182. package/dist/types/src/index.d.ts +2 -2
  183. package/dist/types/src/index.d.ts.map +1 -1
  184. package/dist/types/src/protocol.d.ts +6 -0
  185. package/dist/types/src/protocol.d.ts.map +1 -1
  186. package/dist/types/src/version.d.ts +23 -1
  187. package/dist/types/src/version.d.ts.map +1 -1
  188. package/dist/workspace-plugin/adapters/mcp.js +1 -1
  189. package/dist/workspace-plugin/adapters/omp.js +3 -3
  190. package/dist/workspace-plugin/index.js +1 -1
  191. package/package.json +15 -2
  192. package/dist/chunk-P5VLR3L7.js.map +0 -1
  193. package/dist/chunk-ZWPXSHMW.js.map +0 -1
@@ -1,20 +1,20 @@
1
- import { WorkspacePlugin } from './chunk-CS6NFRNQ.js';
2
- import { WebSocketServerTransport } from './chunk-WQ7DE5UC.js';
1
+ import { WorkspacePlugin } from './chunk-MJEUK6VJ.js';
3
2
  import { assembleSystemPrompt, buildCapabilitiesPromptSection } from './chunk-W3UDISS2.js';
4
- import { EventNormalizer } from './chunk-G73FOLLO.js';
3
+ import { WebSocketServerTransport } from './chunk-WQ7DE5UC.js';
4
+ import { EventNormalizer } from './chunk-M5GJT3D7.js';
5
5
  import { SUPPORTED_CLOUDS, CLOUD_SECRET_ENV_KEYS } from './chunk-ISQWMBKD.js';
6
6
  import { classifyClaudeSdkError } from './chunk-GAH4YRCI.js';
7
- import { createDriver } from './chunk-HLIN4HRK.js';
7
+ import { createDriver } from './chunk-ACWCVB5Q.js';
8
8
  import { deployCatalogEntry, undeployCatalogEntry } from './chunk-LV2HPH3C.js';
9
9
  import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, ConnectorStartupError, buildSdkConnectorTools, buildSdkFlowTools } from './chunk-MTM6C7IS.js';
10
10
  import { loadConnectorDeclarations, SecretProviderChain, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, isKnownSecretRef, deriveSingleMaterializedConnectorDeclaration } from './chunk-2TSSCHCQ.js';
11
11
  import { renderStimulusPrompt, buildOrchestratorPrompt } from './chunk-3EBFDMZC.js';
12
- import { PROTOCOL_VERSION } from './chunk-TSB46BHR.js';
12
+ import { PROTOCOL_VERSION } from './chunk-RDE43ORT.js';
13
13
  import { resolveSettings, resolveApiKey, providerEnvKey } from './chunk-5NZ56R63.js';
14
+ import { resolveDriverPaths } from './chunk-K5GBV4SA.js';
14
15
  import { resolveRuntimeAssets } from './chunk-7J7LQP6T.js';
15
16
  import { resolveSkWorkspaceConfig, resolveAgentDir, cloudConfigFromProfile, stageMaterializedSkills, loadMcpServerDeclarations, COMPACTION_DEFAULTS, validateAssetRecipeAttr, deriveSingleMaterializedMcpDeclaration } from './chunk-ISA7R7PK.js';
16
17
  import { parseAssetRef } from './chunk-GEEW6SY2.js';
17
- import { resolveDriverPaths } from './chunk-K5GBV4SA.js';
18
18
  import { getLogStore, resolveLogStoreConfig, createLogStoreFromConfig, OnLogBridgeSink, WsLogSink, registerLogStore, resetLogStore, createLogger } from './chunk-JB35MVBN.js';
19
19
  import { __require } from './chunk-NSBPE2FW.js';
20
20
  import pc from 'picocolors';
@@ -4392,6 +4392,155 @@ function planFlowMutate(cmd, ctx) {
4392
4392
  }
4393
4393
  return { kind: "dispatch", dispatchId };
4394
4394
  }
4395
+ var DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS = 8e3;
4396
+ function resolveFlowMutateConnectorWaitMs(env = process.env) {
4397
+ const parsed = Number.parseInt(env.SKAILE_FLOW_MUTATE_CONNECTOR_WAIT_MS ?? "", 10);
4398
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS;
4399
+ }
4400
+ function createFlowConnectorReadiness(isReady) {
4401
+ const waiters = [];
4402
+ return {
4403
+ wait(timeoutMs, isSatisfied) {
4404
+ const satisfied = isSatisfied ?? isReady;
4405
+ if (satisfied()) return Promise.resolve(true);
4406
+ return new Promise((resolve4) => {
4407
+ let timer;
4408
+ const waiter = {
4409
+ satisfied,
4410
+ release: () => {
4411
+ clearTimeout(timer);
4412
+ resolve4(true);
4413
+ }
4414
+ };
4415
+ timer = setTimeout(() => {
4416
+ const idx = waiters.indexOf(waiter);
4417
+ if (idx >= 0) waiters.splice(idx, 1);
4418
+ resolve4(false);
4419
+ }, timeoutMs);
4420
+ timer.unref?.();
4421
+ waiters.push(waiter);
4422
+ });
4423
+ },
4424
+ drain() {
4425
+ for (const waiter of waiters.splice(0)) {
4426
+ if (waiter.satisfied()) waiter.release();
4427
+ else waiters.push(waiter);
4428
+ }
4429
+ },
4430
+ pending: () => waiters.length
4431
+ };
4432
+ }
4433
+ function validateInputResponse(schema, response) {
4434
+ if (!schema || typeof schema !== "object") return true;
4435
+ switch (schema.kind) {
4436
+ case "text":
4437
+ return typeof response === "string";
4438
+ case "choice": {
4439
+ const ids = new Set((Array.isArray(schema.options) ? schema.options : []).map((o) => o?.id));
4440
+ if (schema.multiple) {
4441
+ return Array.isArray(response) && response.every((v) => typeof v === "string" && ids.has(v));
4442
+ }
4443
+ return typeof response === "string" && ids.has(response);
4444
+ }
4445
+ case "form": {
4446
+ if (!response || typeof response !== "object" || Array.isArray(response)) return false;
4447
+ const value = response;
4448
+ for (const field of Array.isArray(schema.fields) ? schema.fields : []) {
4449
+ if (!field?.id) continue;
4450
+ const v = value[field.id];
4451
+ if (field.required && (v === void 0 || v === null || v === "")) return false;
4452
+ if (v === void 0 || v === null) continue;
4453
+ if (field.type === "number" && typeof v !== "number") return false;
4454
+ if (field.type === "boolean" && typeof v !== "boolean") return false;
4455
+ if (field.type === "choice" && Array.isArray(field.options) && field.options.length > 0) {
4456
+ if (!field.options.some((o) => o?.id === v)) return false;
4457
+ }
4458
+ }
4459
+ return true;
4460
+ }
4461
+ case "file":
4462
+ return Array.isArray(response) || typeof response === "object" && response !== null;
4463
+ default:
4464
+ return true;
4465
+ }
4466
+ }
4467
+ function reconcilePendingDecisions(execution, pending) {
4468
+ const toApply = [];
4469
+ const reconciled = { applied: [], skipped: [] };
4470
+ if (!Array.isArray(pending)) return { toApply, reconciled };
4471
+ const nodes = execution?.nodes ?? {};
4472
+ for (const raw of pending) {
4473
+ if (!raw || typeof raw !== "object") continue;
4474
+ const entry = raw;
4475
+ const nodeId = typeof entry.nodeId === "string" && entry.nodeId ? entry.nodeId : null;
4476
+ const kind = entry.kind;
4477
+ if (kind !== "approval" && kind !== "input") {
4478
+ if (nodeId) reconciled.skipped.push({ nodeId, reason: "payload_invalid" });
4479
+ continue;
4480
+ }
4481
+ if (!nodeId) continue;
4482
+ const node = nodes[nodeId];
4483
+ if (!node) {
4484
+ reconciled.skipped.push({ nodeId, reason: "unknown_node" });
4485
+ continue;
4486
+ }
4487
+ const wantStatus = kind === "approval" ? "awaiting_approval" : "awaiting_input";
4488
+ if (node.status !== wantStatus) {
4489
+ reconciled.skipped.push({ nodeId, reason: "not_parked" });
4490
+ continue;
4491
+ }
4492
+ const decidedAt = kind === "approval" ? node.approval?.decidedAt : node.input?.providedAt;
4493
+ if (decidedAt != null) {
4494
+ reconciled.skipped.push({ nodeId, reason: "already_decided" });
4495
+ continue;
4496
+ }
4497
+ if (kind === "approval") {
4498
+ const decision = entry.decision;
4499
+ if (decision !== "approved" && decision !== "rejected") {
4500
+ reconciled.skipped.push({ nodeId, reason: "payload_invalid" });
4501
+ continue;
4502
+ }
4503
+ toApply.push({
4504
+ kind: "approval",
4505
+ nodeId,
4506
+ decision,
4507
+ decidedBy: typeof entry.decidedBy === "string" ? entry.decidedBy : "user",
4508
+ ...typeof entry.feedback === "string" ? { feedback: entry.feedback } : {}
4509
+ });
4510
+ } else {
4511
+ if (!validateInputResponse(node.input?.schema, entry.response)) {
4512
+ reconciled.skipped.push({ nodeId, reason: "payload_invalid" });
4513
+ continue;
4514
+ }
4515
+ toApply.push({
4516
+ kind: "input",
4517
+ nodeId,
4518
+ response: entry.response,
4519
+ providedBy: typeof entry.providedBy === "string" ? entry.providedBy : "user"
4520
+ });
4521
+ }
4522
+ reconciled.applied.push(nodeId);
4523
+ }
4524
+ return { toApply, reconciled };
4525
+ }
4526
+ function pendingDecisionOp(decision) {
4527
+ return decision.kind === "approval" ? {
4528
+ op: "applyApproval",
4529
+ payload: {
4530
+ nodeId: decision.nodeId,
4531
+ decision: decision.decision,
4532
+ decidedBy: decision.decidedBy,
4533
+ ...decision.feedback !== void 0 ? { feedback: decision.feedback } : {}
4534
+ }
4535
+ } : {
4536
+ op: "applyInput",
4537
+ payload: {
4538
+ nodeId: decision.nodeId,
4539
+ response: decision.response,
4540
+ providedBy: decision.providedBy
4541
+ }
4542
+ };
4543
+ }
4395
4544
  function hostOpResumeStimulus(op, payload) {
4396
4545
  switch (op) {
4397
4546
  case "applyApproval":
@@ -4419,6 +4568,142 @@ function hostOpResumeStimulus(op, payload) {
4419
4568
  return null;
4420
4569
  }
4421
4570
  }
4571
+ async function executeConnectorMutate(cmd, deps) {
4572
+ let acked = false;
4573
+ const respond = (r) => {
4574
+ if (!cmd.requestId || acked) return;
4575
+ acked = true;
4576
+ deps.sendEvent({ type: "connector_mutate_response", requestId: cmd.requestId, ...r });
4577
+ };
4578
+ try {
4579
+ await deps.sessionReady;
4580
+ } catch (err) {
4581
+ const message = `Session not available: ${err.message}`;
4582
+ deps.sendEvent({ type: "error", message, fatal: true });
4583
+ respond({ ok: false, code: "session_unavailable", error: message });
4584
+ return;
4585
+ }
4586
+ const payload = cmd.payload ?? {};
4587
+ const planContext = () => {
4588
+ const targetExists = deps.hasConnector(cmd.id);
4589
+ const state = deps.flowState();
4590
+ return {
4591
+ targetExists,
4592
+ isExistingFlow: targetExists && deps.isFlowConnector(cmd.id),
4593
+ hasActiveFlow: state.hasActiveFlow,
4594
+ hasRunningFlow: state.hasRunningFlow,
4595
+ onlyActiveConnectorId: state.activeFlow?.connectorId ?? null
4596
+ };
4597
+ };
4598
+ try {
4599
+ deps.assertResourcesReady();
4600
+ let plan = planFlowMutate(cmd, planContext());
4601
+ const flowTargeted = cmd.id === "flow" || cmd.id.startsWith("flow:");
4602
+ if (plan.kind === "dispatch" && flowTargeted && !deps.hasConnector(plan.dispatchId)) {
4603
+ const ready = await deps.waitForFlowConnector(
4604
+ deps.connectorWaitMs,
4605
+ cmd.id === "flow" ? void 0 : () => deps.hasConnector(cmd.id)
4606
+ );
4607
+ if (!ready) {
4608
+ deps.log.warn("connector_mutate timed out waiting for the flow connector", {
4609
+ id: cmd.id,
4610
+ op: cmd.op,
4611
+ waitedMs: deps.connectorWaitMs
4612
+ });
4613
+ respond({
4614
+ ok: false,
4615
+ code: "connector_unavailable",
4616
+ error: `Connector not found: "${cmd.id}" (waited ${deps.connectorWaitMs}ms)`
4617
+ });
4618
+ return;
4619
+ }
4620
+ plan = planFlowMutate(cmd, planContext());
4621
+ }
4622
+ switch (plan.kind) {
4623
+ case "create-start": {
4624
+ const entry = await deps.createActiveFlow(plan.flowDef, { seed: plan.seed });
4625
+ deps.log.info("connector_mutate flow.start", {
4626
+ runId: entry.runId,
4627
+ flowId: plan.flowDef.id
4628
+ });
4629
+ respond({ ok: true });
4630
+ deps.signalStimulus(entry, { kind: "flow_started" });
4631
+ return;
4632
+ }
4633
+ case "create-hydrate": {
4634
+ const entry = await deps.createActiveFlow(plan.flowDef, { execution: plan.execution });
4635
+ deps.log.info("connector_mutate flow.hydrate (bootstrap)", {
4636
+ runId: entry.runId,
4637
+ flowId: plan.flowDef.id
4638
+ });
4639
+ if (payload.pendingDecisions === void 0) {
4640
+ respond({ ok: true });
4641
+ return;
4642
+ }
4643
+ const { toApply, reconciled } = reconcilePendingDecisions(
4644
+ plan.execution,
4645
+ payload.pendingDecisions
4646
+ );
4647
+ let lastApplied = null;
4648
+ const applied = [];
4649
+ for (const decision of toApply) {
4650
+ const { op, payload: opPayload } = pendingDecisionOp(decision);
4651
+ try {
4652
+ await deps.executeOp(entry.connectorId, op, opPayload);
4653
+ applied.push(decision.nodeId);
4654
+ const stimulus = hostOpResumeStimulus(op, opPayload);
4655
+ if (stimulus) lastApplied = { target: entry, stimulus };
4656
+ } catch (err) {
4657
+ reconciled.skipped.push({ nodeId: decision.nodeId, reason: "not_parked" });
4658
+ deps.log.warn("flow hydrate reconciliation refused", {
4659
+ nodeId: decision.nodeId,
4660
+ op,
4661
+ error: err instanceof Error ? err.message : String(err)
4662
+ });
4663
+ }
4664
+ }
4665
+ reconciled.applied = applied;
4666
+ respond({ ok: true, reconciled });
4667
+ if (lastApplied) deps.signalStimulus(lastApplied.target, lastApplied.stimulus);
4668
+ return;
4669
+ }
4670
+ case "reject": {
4671
+ deps.log.warn("connector_mutate rejected", {
4672
+ id: cmd.id,
4673
+ op: cmd.op,
4674
+ reason: plan.reason
4675
+ });
4676
+ deps.sendEvent({
4677
+ type: "error",
4678
+ message: `connector_mutate rejected (id=${cmd.id}, op=${cmd.op}): ${plan.reason}`,
4679
+ fatal: false,
4680
+ category: "validation"
4681
+ });
4682
+ respond({ ok: false, code: "rejected", error: plan.reason });
4683
+ return;
4684
+ }
4685
+ case "dispatch": {
4686
+ const result = await deps.executeOp(plan.dispatchId, cmd.op, payload);
4687
+ const ignoredReplay = cmd.op === "hydrate" && payload.pendingDecisions !== void 0;
4688
+ respond({
4689
+ ok: true,
4690
+ ...result !== void 0 && result !== null ? { result } : {},
4691
+ ...ignoredReplay ? { reconciled: { applied: [], skipped: [] } } : {}
4692
+ });
4693
+ const resumeStimulus = hostOpResumeStimulus(cmd.op, payload);
4694
+ if (resumeStimulus) {
4695
+ const active = deps.flowState().activeFlow;
4696
+ if (active) deps.signalStimulus(active, resumeStimulus);
4697
+ }
4698
+ return;
4699
+ }
4700
+ }
4701
+ } catch (err) {
4702
+ const message = err instanceof Error ? err.message : String(err);
4703
+ deps.log.warn("connector_mutate failed", { id: cmd.id, op: cmd.op, error: message });
4704
+ respond({ ok: false, code: "op_failed", error: message });
4705
+ }
4706
+ }
4422
4707
  function reconstructTypedStimulus(meta) {
4423
4708
  switch (meta.kind) {
4424
4709
  case "flow_started":
@@ -4983,6 +5268,8 @@ async function startAgentServer(opts) {
4983
5268
  const iter = activeFlows.values().next();
4984
5269
  return iter.done ? null : iter.value;
4985
5270
  }
5271
+ const flowConnectorReadiness = createFlowConnectorReadiness(() => getOnlyActiveFlow() !== null);
5272
+ const flowMutateConnectorWaitMs = resolveFlowMutateConnectorWaitMs();
4986
5273
  function getOrCreateStimulusBus() {
4987
5274
  if (stimulusBus) return stimulusBus;
4988
5275
  stimulusBus = createSessionStimulusBus({
@@ -5118,6 +5405,7 @@ async function startAgentServer(opts) {
5118
5405
  const entry = { runId, flowDef, adapter, handle, connectorId };
5119
5406
  const pruned = registerActiveFlow(activeFlows, runId, entry);
5120
5407
  if (pruned.length > 0) serverLog.debug("pruned terminal flow runs", { runIds: pruned });
5408
+ flowConnectorReadiness.drain();
5121
5409
  return entry;
5122
5410
  }
5123
5411
  const refreshFlagPath = join(opts.projectDir, ".skaile", "refresh-request");
@@ -5787,98 +6075,46 @@ async function startAgentServer(opts) {
5787
6075
  void handleResourceRequest(cmd, resourceManager, sendEvent);
5788
6076
  }
5789
6077
  async function handleConnectorMutate(cmd) {
5790
- try {
5791
- await sessionReady;
5792
- } catch (err) {
5793
- sendEvent({
5794
- type: "error",
5795
- message: `Session not available: ${err.message}`,
5796
- fatal: true
5797
- });
5798
- return;
5799
- }
5800
- try {
5801
- if (!resourceManager) throw new Error("connector_mutate before resources ready");
5802
- const targetEntry = resourceManager.has?.(cmd.id) ? resourceManager.get(cmd.id) : null;
5803
- const isExistingFlow = targetEntry?.connector?.name === "flow";
5804
- const plan = planFlowMutate(cmd, {
5805
- targetExists: !!targetEntry,
5806
- isExistingFlow,
5807
- hasActiveFlow: activeFlows.size > 0,
5808
- hasRunningFlow: hasNonTerminalFlow(activeFlows.values()),
5809
- onlyActiveConnectorId: getOnlyActiveFlow()?.connectorId ?? null
5810
- });
5811
- switch (plan.kind) {
5812
- case "create-start": {
5813
- const entry = await createActiveFlow(plan.flowDef, { seed: plan.seed });
5814
- serverLog.info("connector_mutate flow.start", {
5815
- runId: entry.runId,
5816
- flowId: plan.flowDef.id
5817
- });
5818
- const startStimulus = { kind: "flow_started" };
5819
- void getOrCreateStimulusBus().signal(entry.connectorId, {
5820
- promptFragment: renderStimulusPrompt(startStimulus),
5821
- meta: { kind: startStimulus.kind, runId: entry.runId }
5822
- }).catch((err) => {
5823
- serverLog.warn("flow_started turn failed", {
5824
- runId: entry.runId,
5825
- error: err instanceof Error ? err.message : String(err)
5826
- });
5827
- });
5828
- return;
5829
- }
5830
- case "create-hydrate": {
5831
- const entry = await createActiveFlow(plan.flowDef, { execution: plan.execution });
5832
- serverLog.info("connector_mutate flow.hydrate (bootstrap)", {
5833
- runId: entry.runId,
5834
- flowId: plan.flowDef.id
5835
- });
5836
- return;
5837
- }
5838
- case "reject": {
5839
- serverLog.warn("connector_mutate rejected", {
5840
- id: cmd.id,
5841
- op: cmd.op,
5842
- reason: plan.reason
5843
- });
5844
- sendEvent({
5845
- type: "error",
5846
- message: `connector_mutate rejected (id=${cmd.id}, op=${cmd.op}): ${plan.reason}`,
5847
- fatal: false,
5848
- category: "validation"
6078
+ await executeConnectorMutate(cmd, {
6079
+ sessionReady,
6080
+ sendEvent,
6081
+ assertResourcesReady: () => {
6082
+ if (!resourceManager) throw new Error("connector_mutate before resources ready");
6083
+ },
6084
+ hasConnector: (id) => resourceManager?.has?.(id) ?? false,
6085
+ isFlowConnector: (id) => resourceManager?.has?.(id) === true && resourceManager.get(id).connector?.name === "flow",
6086
+ executeOp: (id, op, args) => {
6087
+ if (!resourceManager) throw new Error("connector_mutate before resources ready");
6088
+ return resourceManager.executeOp(id, op, args);
6089
+ },
6090
+ flowState: () => {
6091
+ const active = getOnlyActiveFlow();
6092
+ return {
6093
+ hasActiveFlow: activeFlows.size > 0,
6094
+ hasRunningFlow: hasNonTerminalFlow(activeFlows.values()),
6095
+ activeFlow: active ? { runId: active.runId, connectorId: active.connectorId } : null
6096
+ };
6097
+ },
6098
+ createActiveFlow: async (flowDef, seedOrExecution) => {
6099
+ const entry = await createActiveFlow(flowDef, seedOrExecution);
6100
+ return { runId: entry.runId, connectorId: entry.connectorId };
6101
+ },
6102
+ waitForFlowConnector: (timeoutMs, isSatisfied) => flowConnectorReadiness.wait(timeoutMs, isSatisfied),
6103
+ connectorWaitMs: flowMutateConnectorWaitMs,
6104
+ signalStimulus: (target, stimulus) => {
6105
+ void getOrCreateStimulusBus().signal(target.connectorId, {
6106
+ promptFragment: renderStimulusPrompt(stimulus),
6107
+ meta: { ...stimulus, runId: target.runId }
6108
+ }).catch((err) => {
6109
+ serverLog.warn("flow turn kick failed", {
6110
+ kind: stimulus.kind,
6111
+ runId: target.runId,
6112
+ error: err instanceof Error ? err.message : String(err)
5849
6113
  });
5850
- return;
5851
- }
5852
- case "dispatch": {
5853
- await resourceManager.executeOp(plan.dispatchId, cmd.op, cmd.payload ?? {});
5854
- const resumeStimulus = hostOpResumeStimulus(cmd.op, cmd.payload ?? {});
5855
- if (resumeStimulus) {
5856
- const entry = getOnlyActiveFlow();
5857
- if (entry) {
5858
- void getOrCreateStimulusBus().signal(entry.connectorId, {
5859
- promptFragment: renderStimulusPrompt(resumeStimulus),
5860
- meta: {
5861
- ...resumeStimulus,
5862
- runId: entry.runId
5863
- }
5864
- }).catch((err) => {
5865
- serverLog.warn("host-op resume turn failed", {
5866
- op: cmd.op,
5867
- error: err instanceof Error ? err.message : String(err)
5868
- });
5869
- });
5870
- }
5871
- }
5872
- return;
5873
- }
5874
- }
5875
- } catch (err) {
5876
- serverLog.warn("connector_mutate failed", {
5877
- id: cmd.id,
5878
- op: cmd.op,
5879
- error: err instanceof Error ? err.message : String(err)
5880
- });
5881
- }
6114
+ });
6115
+ },
6116
+ log: serverLog
6117
+ });
5882
6118
  }
5883
6119
  async function handleConnectorQuery(cmd) {
5884
6120
  try {
@@ -6330,6 +6566,6 @@ function touchSession(state) {
6330
6566
  return { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
6331
6567
  }
6332
6568
 
6333
- export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, MarkdownStreamer, PreInitRingSink, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, connectorRefreshKind, createAgentSession, createSessionStimulusBus, defineCapability, deleteSession, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureGitConfigInclude, extractClaudeAiOauthExpiresAt, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, hasNonTerminalFlow, hostOpResumeStimulus, installPreInitRingSink, isTerminalFlowStatus, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadSession, loadSessionById, mcpAuthSecretKey, newSession, pickRepointedManager, planFlowMutate, registerActiveFlow, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveMixin, runAgentChat, saveSession, setCurrentSession, startAgentServer, stimulusFromMetas, touchSession, writeClaudeCodeCredentialsFile };
6334
- //# sourceMappingURL=chunk-ZWPXSHMW.js.map
6335
- //# sourceMappingURL=chunk-ZWPXSHMW.js.map
6569
+ export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS, MarkdownStreamer, PreInitRingSink, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, connectorRefreshKind, createAgentSession, createFlowConnectorReadiness, createSessionStimulusBus, defineCapability, deleteSession, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureGitConfigInclude, executeConnectorMutate, extractClaudeAiOauthExpiresAt, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, hasNonTerminalFlow, hostOpResumeStimulus, installPreInitRingSink, isTerminalFlowStatus, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadSession, loadSessionById, mcpAuthSecretKey, newSession, pickRepointedManager, planFlowMutate, reconcilePendingDecisions, registerActiveFlow, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveFlowMutateConnectorWaitMs, resolveMixin, runAgentChat, saveSession, setCurrentSession, startAgentServer, stimulusFromMetas, touchSession, validateInputResponse, writeClaudeCodeCredentialsFile };
6570
+ //# sourceMappingURL=chunk-EKGB4ZWR.js.map
6571
+ //# sourceMappingURL=chunk-EKGB4ZWR.js.map