@skaile/workspaces 3.24.0 → 3.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-M3XC5SQD.js → asset-feeds-ISSC2HYE.js} +4 -4
  4. package/dist/{asset-feeds-M3XC5SQD.js.map → asset-feeds-ISSC2HYE.js.map} +1 -1
  5. package/dist/asset-manager/index.js +1 -1
  6. package/dist/bridge/drivers/claude-sdk.js +4 -3
  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 +3 -3
  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 +4 -4
  17. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  18. package/dist/bridge/src/normalizer.d.ts +6 -0
  19. package/dist/bridge/src/normalizer.d.ts.map +1 -1
  20. package/dist/{chunk-NTWVXLOZ.js → chunk-3DOLXE4Z.js} +3 -3
  21. package/dist/{chunk-NTWVXLOZ.js.map → chunk-3DOLXE4Z.js.map} +1 -1
  22. package/dist/{chunk-HTIGD3DR.js → chunk-5SXY4B65.js} +3 -3
  23. package/dist/{chunk-HTIGD3DR.js.map → chunk-5SXY4B65.js.map} +1 -1
  24. package/dist/{chunk-WQ7DE5UC.js → chunk-73ZXUUL6.js} +25 -8
  25. package/dist/chunk-73ZXUUL6.js.map +1 -0
  26. package/dist/{chunk-VOT47UVY.js → chunk-A565EFTW.js} +3 -3
  27. package/dist/{chunk-VOT47UVY.js.map → chunk-A565EFTW.js.map} +1 -1
  28. package/dist/{chunk-Y5PKES63.js → chunk-ALSDJ6F4.js} +2 -2
  29. package/dist/{chunk-Y5PKES63.js.map → chunk-ALSDJ6F4.js.map} +1 -1
  30. package/dist/{chunk-U3BH5VCG.js → chunk-AY4OKT3U.js} +2 -2
  31. package/dist/{chunk-U3BH5VCG.js.map → chunk-AY4OKT3U.js.map} +1 -1
  32. package/dist/{chunk-6EJOXLVH.js → chunk-DGPCBJNQ.js} +2 -2
  33. package/dist/{chunk-6EJOXLVH.js.map → chunk-DGPCBJNQ.js.map} +1 -1
  34. package/dist/{chunk-VKLCLC7K.js → chunk-GLOHIJ7B.js} +3 -3
  35. package/dist/{chunk-VKLCLC7K.js.map → chunk-GLOHIJ7B.js.map} +1 -1
  36. package/dist/{chunk-J4WDQL42.js → chunk-KFH5GCDB.js} +3 -3
  37. package/dist/{chunk-J4WDQL42.js.map → chunk-KFH5GCDB.js.map} +1 -1
  38. package/dist/{chunk-6NTKN6QC.js → chunk-NQG77HXO.js} +3 -3
  39. package/dist/{chunk-6NTKN6QC.js.map → chunk-NQG77HXO.js.map} +1 -1
  40. package/dist/{chunk-Z6YHCANW.js → chunk-NRKEZBVP.js} +42 -12
  41. package/dist/chunk-NRKEZBVP.js.map +1 -0
  42. package/dist/{chunk-Q3YS5M3E.js → chunk-Q6SWQEF7.js} +284 -61
  43. package/dist/chunk-Q6SWQEF7.js.map +1 -0
  44. package/dist/{chunk-QBR3WRXB.js → chunk-RPE5VYB6.js} +65 -11
  45. package/dist/chunk-RPE5VYB6.js.map +1 -0
  46. package/dist/{chunk-IDY7A5KA.js → chunk-S3Z5KF6R.js} +3 -3
  47. package/dist/{chunk-IDY7A5KA.js.map → chunk-S3Z5KF6R.js.map} +1 -1
  48. package/dist/{chunk-V6QKAC3Z.js → chunk-U2QALNKX.js} +8 -5
  49. package/dist/chunk-U2QALNKX.js.map +1 -0
  50. package/dist/{chunk-UPGHKBJ7.js → chunk-UOERRCR3.js} +6 -6
  51. package/dist/{chunk-UPGHKBJ7.js.map → chunk-UOERRCR3.js.map} +1 -1
  52. package/dist/{chunk-HIZH3CSZ.js → chunk-UQTPSVJV.js} +6 -6
  53. package/dist/{chunk-HIZH3CSZ.js.map → chunk-UQTPSVJV.js.map} +1 -1
  54. package/dist/{chunk-EEOY4LI5.js → chunk-XGO6CP5S.js} +3 -3
  55. package/dist/{chunk-EEOY4LI5.js.map → chunk-XGO6CP5S.js.map} +1 -1
  56. package/dist/{chunk-EE627CQN.js → chunk-XHPWI6XF.js} +4 -4
  57. package/dist/{chunk-EE627CQN.js.map → chunk-XHPWI6XF.js.map} +1 -1
  58. package/dist/cli/index.js +33 -33
  59. package/dist/connectors/index.js +5 -5
  60. package/dist/connectors/src/connector-prompt.d.ts +32 -0
  61. package/dist/connectors/src/connector-prompt.d.ts.map +1 -1
  62. package/dist/connectors/src/index.d.ts +2 -2
  63. package/dist/connectors/src/index.d.ts.map +1 -1
  64. package/dist/{ensure-sources-YMHAHTN2.js → ensure-sources-YH6X5XI4.js} +4 -4
  65. package/dist/{ensure-sources-YMHAHTN2.js.map → ensure-sources-YH6X5XI4.js.map} +1 -1
  66. package/dist/factory-assets/connectors/box.js +5 -5
  67. package/dist/factory-assets/connectors/deploy.js +5 -5
  68. package/dist/factory-assets/connectors/devserver.js +5 -5
  69. package/dist/factory-assets/connectors/flow/adapter.d.ts +8 -1
  70. package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
  71. package/dist/factory-assets/connectors/flow/adapter.js +5 -5
  72. package/dist/factory-assets/connectors/flow/index.d.ts +1 -1
  73. package/dist/factory-assets/connectors/flow/index.d.ts.map +1 -1
  74. package/dist/factory-assets/connectors/flow/run-flow.js +6 -6
  75. package/dist/factory-assets/connectors/flow.js +5 -5
  76. package/dist/factory-assets/connectors/git.js +5 -5
  77. package/dist/factory-assets/connectors/gmail.js +5 -5
  78. package/dist/factory-assets/connectors/googledrive.js +5 -5
  79. package/dist/factory-assets/connectors/local.js +5 -5
  80. package/dist/factory-assets/connectors/mattermost.js +5 -5
  81. package/dist/factory-assets/connectors/memory.js +5 -5
  82. package/dist/factory-assets/connectors/minio.js +5 -5
  83. package/dist/factory-assets/connectors/postgres.js +5 -5
  84. package/dist/factory-assets/connectors/s3.js +5 -5
  85. package/dist/factory-assets/connectors/sharepoint.js +5 -5
  86. package/dist/factory-assets/connectors/sqlite.js +5 -5
  87. package/dist/factory-assets/connectors/static-server.js +5 -5
  88. package/dist/factory-assets/connectors/tunnel.js +5 -5
  89. package/dist/factory-assets/connectors/webdav.js +5 -5
  90. package/dist/factory-assets/connectors/xstate-store.js +5 -5
  91. package/dist/factory-assets/connectors/xstate.js +5 -5
  92. package/dist/{helpers-4SPTON2W.js → helpers-EJEK6NN6.js} +4 -4
  93. package/dist/{helpers-4SPTON2W.js.map → helpers-EJEK6NN6.js.map} +1 -1
  94. package/dist/{library-publish-TE3JGRLE.js → library-publish-66FHWXAA.js} +6 -6
  95. package/dist/{library-publish-TE3JGRLE.js.map → library-publish-66FHWXAA.js.map} +1 -1
  96. package/dist/{open-library-SZFLVRIH.js → open-library-4W2UGVJN.js} +5 -5
  97. package/dist/{open-library-SZFLVRIH.js.map → open-library-4W2UGVJN.js.map} +1 -1
  98. package/dist/{project-F54LXGLW.js → project-6OECVELE.js} +5 -5
  99. package/dist/{project-F54LXGLW.js.map → project-6OECVELE.js.map} +1 -1
  100. package/dist/runner/index.js +10 -10
  101. package/dist/runner/src/compaction-gate.d.ts +2 -0
  102. package/dist/runner/src/compaction-gate.d.ts.map +1 -1
  103. package/dist/runner/src/driver-swap-gate.d.ts +13 -0
  104. package/dist/runner/src/driver-swap-gate.d.ts.map +1 -1
  105. package/dist/runner/src/flow-turn-dispatch.d.ts +40 -0
  106. package/dist/runner/src/flow-turn-dispatch.d.ts.map +1 -0
  107. package/dist/runner/src/resource-handler.d.ts +34 -1
  108. package/dist/runner/src/resource-handler.d.ts.map +1 -1
  109. package/dist/runner/src/serve.d.ts +25 -1
  110. package/dist/runner/src/serve.d.ts.map +1 -1
  111. package/dist/runner/src/session-builder.d.ts +10 -0
  112. package/dist/runner/src/session-builder.d.ts.map +1 -1
  113. package/dist/sdk/asset-manager.js +1 -1
  114. package/dist/sdk/bridge.js +4 -4
  115. package/dist/sdk/index.js +10 -10
  116. package/dist/sdk/runner.js +10 -10
  117. package/dist/sdk/session.js +2 -2
  118. package/dist/sdk/transport/ws/server.js +1 -1
  119. package/dist/sdk/transport/ws.js +1 -1
  120. package/dist/sdk/transport.js +1 -1
  121. package/dist/sdk/types.js +1 -1
  122. package/dist/session/index.js +2 -2
  123. package/dist/{setup-K6CUBTZS.js → setup-6IEVFDWB.js} +6 -6
  124. package/dist/{setup-K6CUBTZS.js.map → setup-6IEVFDWB.js.map} +1 -1
  125. package/dist/{source-5FLDWOBP.js → source-HJQNRGTP.js} +6 -6
  126. package/dist/{source-5FLDWOBP.js.map → source-HJQNRGTP.js.map} +1 -1
  127. package/dist/{source-manifest-publish-NPNXIC56.js → source-manifest-publish-VU4BGFDU.js} +7 -7
  128. package/dist/{source-manifest-publish-NPNXIC56.js.map → source-manifest-publish-VU4BGFDU.js.map} +1 -1
  129. package/dist/transport/index.js +1 -1
  130. package/dist/transport/src/ws/server.d.ts +3 -1
  131. package/dist/transport/src/ws/server.d.ts.map +1 -1
  132. package/dist/transport/ws/server.js +1 -1
  133. package/dist/transport/ws.js +1 -1
  134. package/dist/tui/index.js +10 -10
  135. package/dist/types/index.js +1 -1
  136. package/dist/types/src/events.d.ts +7 -0
  137. package/dist/types/src/events.d.ts.map +1 -1
  138. package/dist/types/src/index.d.ts +1 -0
  139. package/dist/types/src/index.d.ts.map +1 -1
  140. package/dist/types/src/protocol.d.ts +11 -0
  141. package/dist/types/src/protocol.d.ts.map +1 -1
  142. package/dist/types/src/version.d.ts +6 -1
  143. package/dist/types/src/version.d.ts.map +1 -1
  144. package/dist/workspace-plugin/adapters/mcp.js +2 -2
  145. package/dist/workspace-plugin/index.js +1 -1
  146. package/package.json +1 -1
  147. package/dist/chunk-Q3YS5M3E.js.map +0 -1
  148. package/dist/chunk-QBR3WRXB.js.map +0 -1
  149. package/dist/chunk-V6QKAC3Z.js.map +0 -1
  150. package/dist/chunk-WQ7DE5UC.js.map +0 -1
  151. package/dist/chunk-Z6YHCANW.js.map +0 -1
@@ -1,23 +1,23 @@
1
- import { buildWorkspaceToolDefs } from './chunk-J4WDQL42.js';
1
+ import { buildWorkspaceToolDefs } from './chunk-KFH5GCDB.js';
2
2
  import { findAiAssetsRoot } from './chunk-7IRJ4K4F.js';
3
- import { WorkspacePlugin } from './chunk-Y5PKES63.js';
3
+ import { WorkspacePlugin } from './chunk-ALSDJ6F4.js';
4
4
  import { assembleSystemPrompt, buildCapabilitiesPromptSection } from './chunk-W3UDISS2.js';
5
- import { WebSocketServerTransport } from './chunk-WQ7DE5UC.js';
5
+ import { WebSocketServerTransport } from './chunk-73ZXUUL6.js';
6
6
  import { prepareNativePolicy, codexInstanceEnvironment, parseCodexCredential, parseCodexRefreshInput, parseCodexRefreshResult } from './chunk-T3YLZQS4.js';
7
- import { resolveFlowPath } from './chunk-IDY7A5KA.js';
7
+ import { resolveFlowPath } from './chunk-S3Z5KF6R.js';
8
8
  import { findAiAssetsRoot as findAiAssetsRoot$1, deployCatalogEntry, undeployCatalogEntry } from './chunk-7BUZQVRR.js';
9
- import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, ConnectorStartupError, buildSdkConnectorTools, buildConnectorToolDefs, buildFlowToolDefs, driveOrchestratorTurn, SessionNodeExecutor, SessionSubpromptRunner, SessionInlineSubFlowRunner, buildSdkFlowTools } from './chunk-Z6YHCANW.js';
9
+ import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, ConnectorStartupError, buildSdkConnectorTools, buildLazySdkFlowTools, describeFlowOperations, buildConnectorToolDefs, buildFlowToolDefs, driveOrchestratorTurn, SessionNodeExecutor, SessionSubpromptRunner, SessionInlineSubFlowRunner, buildSdkFlowTools } from './chunk-NRKEZBVP.js';
10
10
  import { loadConnectorDeclarations, SecretProviderChain, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, isKnownSecretRef, deriveSingleMaterializedConnectorDeclaration } from './chunk-SIREWRZE.js';
11
- import { EventNormalizer } from './chunk-QBR3WRXB.js';
11
+ import { EventNormalizer } from './chunk-RPE5VYB6.js';
12
12
  import { SUPPORTED_CLOUDS, probeResumeTranscript, CLOUD_SECRET_ENV_KEYS } from './chunk-3NCGSSCU.js';
13
13
  import { CodexNativeStateUnavailable } from './chunk-LOO5CB5M.js';
14
- import { dispatchCapability } from './chunk-HTIGD3DR.js';
14
+ import { dispatchCapability } from './chunk-5SXY4B65.js';
15
15
  import { classifyClaudeSdkError } from './chunk-GAH4YRCI.js';
16
- import { createDriver } from './chunk-6EJOXLVH.js';
16
+ import { createDriver } from './chunk-DGPCBJNQ.js';
17
17
  import { loadFlow } from './chunk-W5LPG3X6.js';
18
18
  import { parseFlowDefinition } from './chunk-CP62G5PK.js';
19
19
  import { renderStimulusPrompt } from './chunk-2D5BYAL6.js';
20
- import { withActivityLabelJsonSchema, TOOL_ACTIVITY_PROMPT_SECTION, PROTOCOL_VERSION } from './chunk-V6QKAC3Z.js';
20
+ import { withActivityLabelJsonSchema, TOOL_ACTIVITY_PROMPT_SECTION, SESSION_ROOT_CONNECTOR_ID, PROTOCOL_VERSION } from './chunk-U2QALNKX.js';
21
21
  import { resolveSettings, resolveApiKey, providerEnvKey } from './chunk-HSRHO7SK.js';
22
22
  import { resolveDriverPaths } from './chunk-K5GBV4SA.js';
23
23
  import { resolveRuntimeAssets } from './chunk-IB4XKQMQ.js';
@@ -30,7 +30,7 @@ import { __require } from './chunk-NSBPE2FW.js';
30
30
  import pc from 'picocolors';
31
31
  import { Marked } from 'marked';
32
32
  import { markedTerminal } from 'marked-terminal';
33
- import fs4, { readFile, stat, rm, unlink, mkdir, writeFile, readdir, rename, realpath, mkdtemp, lstat } from 'fs/promises';
33
+ import fs4, { readFile, stat, rm, unlink, mkdir, writeFile, readdir, realpath, lstat, rename, readlink, mkdtemp } from 'fs/promises';
34
34
  import { createHash, randomBytes, timingSafeEqual, randomUUID } from 'crypto';
35
35
  import path4, { join, resolve, relative, sep, isAbsolute, dirname, basename } from 'path';
36
36
  import { existsSync, lstatSync, realpathSync, readFileSync, mkdirSync, writeFileSync, watch, chmodSync, accessSync, constants, rmSync } from 'fs';
@@ -2349,6 +2349,8 @@ async function createAgentSession(config) {
2349
2349
  const maxTurns = maxTurnsOverride ?? manifest?.runtime?.max_turns;
2350
2350
  let driver;
2351
2351
  try {
2352
+ const extraMcpServers = driverType === "claude-sdk" ? await config.extraInProcessMcpServers?.() : void 0;
2353
+ const driverMcpServers = extraMcpServers ? { ...mcpServers, ...extraMcpServers } : mcpServers;
2352
2354
  driver = await createSessionDriver({
2353
2355
  config,
2354
2356
  driverType,
@@ -2365,7 +2367,7 @@ async function createAgentSession(config) {
2365
2367
  effort,
2366
2368
  sessionId,
2367
2369
  resumeSessionId,
2368
- mcpServers,
2370
+ mcpServers: driverMcpServers,
2369
2371
  agentDir
2370
2372
  });
2371
2373
  } catch (error) {
@@ -3333,6 +3335,144 @@ async function handleMountResourceRequest(command, manager, emit) {
3333
3335
  });
3334
3336
  }
3335
3337
  }
3338
+ var SESSION_ROOT_WRITABLE_FILES = ["skaile.yaml"];
3339
+ var SESSION_ROOT_WRITABLE_DIRS = [
3340
+ ".skaile/assets",
3341
+ ".skaile/chat-files"
3342
+ ];
3343
+ function isSessionRootPathAllowed(rel, operation) {
3344
+ if (SESSION_ROOT_WRITABLE_FILES.includes(rel)) return true;
3345
+ return SESSION_ROOT_WRITABLE_DIRS.some(
3346
+ (dir) => rel.startsWith(`${dir}/`) || operation === "delete" && rel === dir
3347
+ );
3348
+ }
3349
+ function isWithin(root, child) {
3350
+ const rel = relative(root, child);
3351
+ return rel === "" || !(rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel));
3352
+ }
3353
+ var SESSION_ROOT_MAX_LINK_HOPS = 32;
3354
+ async function resolveOnDisk(absPath) {
3355
+ let current = absPath;
3356
+ const missing = [];
3357
+ let hops = 0;
3358
+ for (; ; ) {
3359
+ try {
3360
+ const real = await withFsDeadline(`realpath ${current}`, () => realpath(current));
3361
+ return join(real, ...missing.reverse());
3362
+ } catch (err) {
3363
+ const code = err.code;
3364
+ if (code !== "ENOENT" && code !== "ENOTDIR") throw err;
3365
+ const linkTarget = code === "ENOENT" ? await readDanglingLink(current) : null;
3366
+ if (linkTarget !== null) {
3367
+ if (++hops > SESSION_ROOT_MAX_LINK_HOPS) {
3368
+ throw new Error("Too many symlinks in the session-root path");
3369
+ }
3370
+ const linkDir = dirname(current);
3371
+ const realLinkDir = await withFsDeadline(`realpath ${linkDir}`, () => realpath(linkDir));
3372
+ current = resolve(realLinkDir, linkTarget);
3373
+ continue;
3374
+ }
3375
+ const parent = dirname(current);
3376
+ if (parent === current) throw err;
3377
+ missing.push(basename(current));
3378
+ current = parent;
3379
+ }
3380
+ }
3381
+ }
3382
+ async function readDanglingLink(absPath) {
3383
+ try {
3384
+ const st = await withFsDeadline(`lstat ${absPath}`, () => lstat(absPath));
3385
+ if (!st.isSymbolicLink()) return null;
3386
+ } catch (err) {
3387
+ if (err.code === "ENOENT") return null;
3388
+ throw err;
3389
+ }
3390
+ return withFsDeadline(`readlink ${absPath}`, () => readlink(absPath));
3391
+ }
3392
+ async function handleSessionRootResourceRequest(command, rootDir, emit) {
3393
+ const { requestId, connectorId, operation, path: reqPath, content } = command;
3394
+ try {
3395
+ if (operation !== "write" && operation !== "delete") {
3396
+ throw new Error(`Unsupported operation for the session root: ${operation}`);
3397
+ }
3398
+ if (!reqPath) throw new Error("A path is required for the session root");
3399
+ if (isAbsolute(reqPath)) throw new Error("Absolute paths are not allowed for the session root");
3400
+ const root = resolve(rootDir);
3401
+ const targetPath = resolve(root, reqPath);
3402
+ if (!isWithin(root, targetPath)) throw new Error("Path traversal outside the session root");
3403
+ const rel = relative(root, targetPath).split(sep).join("/");
3404
+ if (!isSessionRootPathAllowed(rel, operation)) {
3405
+ throw new Error(
3406
+ `Path "${rel}" is not writable in the session root \u2014 allowed: ${[...SESSION_ROOT_WRITABLE_FILES, ...SESSION_ROOT_WRITABLE_DIRS.map((d) => `${d}/**`)].join(", ")}`
3407
+ );
3408
+ }
3409
+ const realRoot = await withFsDeadline(`realpath ${root}`, () => realpath(root));
3410
+ const onDisk = operation === "write" ? await resolveOnDisk(targetPath) : join(await resolveOnDisk(dirname(targetPath)), basename(targetPath));
3411
+ if (!isWithin(realRoot, operation === "write" ? onDisk : dirname(onDisk))) {
3412
+ throw new Error("Path escapes the session root through a symlink");
3413
+ }
3414
+ let data = true;
3415
+ if (operation === "write") {
3416
+ const parentDir = dirname(onDisk);
3417
+ await withFsDeadline(`mkdir ${parentDir}`, () => mkdir(parentDir, { recursive: true }));
3418
+ const writeContent = typeof content === "string" ? content : content?.data ?? "";
3419
+ const encoding = typeof content === "string" ? void 0 : content?.encoding;
3420
+ await withFsDeadline(
3421
+ `writeFile ${onDisk}`,
3422
+ () => encoding === "binary" ? writeFile(onDisk, Buffer.from(writeContent, "base64")) : writeFile(onDisk, writeContent, "utf-8")
3423
+ );
3424
+ } else {
3425
+ let st = null;
3426
+ try {
3427
+ st = await withFsDeadline(`lstat ${onDisk}`, () => lstat(onDisk));
3428
+ } catch (err) {
3429
+ if (err.code !== "ENOENT") throw err;
3430
+ }
3431
+ if (!st) {
3432
+ data = false;
3433
+ } else if (st.isDirectory()) {
3434
+ await withFsDeadline(
3435
+ `rm -r ${onDisk}`,
3436
+ () => rm(onDisk, { recursive: true, force: true }),
3437
+ fsDeadlineMs() * MOUNT_TREE_OP_DEADLINE_FACTOR
3438
+ );
3439
+ } else {
3440
+ await withFsDeadline(`unlink ${onDisk}`, () => unlink(onDisk));
3441
+ }
3442
+ }
3443
+ emit({ type: "resource_response", requestId, resourceId: connectorId, operation, data });
3444
+ } catch (err) {
3445
+ emit({
3446
+ type: "resource_response",
3447
+ requestId,
3448
+ resourceId: connectorId,
3449
+ operation,
3450
+ error: err instanceof Error ? err.message : String(err)
3451
+ });
3452
+ }
3453
+ }
3454
+ async function dispatchResourceRequest(command, deps) {
3455
+ const { resourceManager, projectDir, emit } = deps;
3456
+ if (command.connectorId === SESSION_ROOT_CONNECTOR_ID) {
3457
+ await handleSessionRootResourceRequest(command, projectDir, emit);
3458
+ return;
3459
+ }
3460
+ if (resourceManager?.has(command.connectorId)) {
3461
+ await handleMountResourceRequest(command, resourceManager, emit);
3462
+ return;
3463
+ }
3464
+ if (!resourceManager) {
3465
+ emit({
3466
+ type: "resource_response",
3467
+ requestId: command.requestId,
3468
+ resourceId: command.connectorId,
3469
+ operation: command.operation,
3470
+ error: "No resources available \u2014 no mounts or connectors configured"
3471
+ });
3472
+ return;
3473
+ }
3474
+ void handleResourceRequest(command, resourceManager, emit);
3475
+ }
3336
3476
 
3337
3477
  // runner/src/codex-init.ts
3338
3478
  function validateCodexInit(cmd, supported, previous) {
@@ -3812,6 +3952,10 @@ var CompactionGate = class {
3812
3952
  this.release = null;
3813
3953
  release2?.();
3814
3954
  }
3955
+ /** Whether no compaction holds the driver right now. */
3956
+ isIdle() {
3957
+ return this.held.size === 0;
3958
+ }
3815
3959
  /**
3816
3960
  * Wait for the driver to be free.
3817
3961
  *
@@ -3892,6 +4036,29 @@ var DriverSwapGate = class {
3892
4036
  resolveTurn();
3893
4037
  };
3894
4038
  }
4039
+ /**
4040
+ * Take a turn slot behind every turn already in flight, and resolve once they
4041
+ * have all settled. Unlike {@link beginTurn}, the caller waits its turn: a
4042
+ * turn whose completion is observed by listening for the driver's next
4043
+ * `agent_end` must not dispatch while another turn is still running, or it
4044
+ * observes that turn's end instead of its own. The slot is claimed
4045
+ * synchronously, so a swap that starts during the wait awaits this turn too —
4046
+ * check {@link isSwapping} after acquiring and release the slot if one is
4047
+ * pending, or the swap and this turn wait on each other.
4048
+ */
4049
+ async beginQueuedTurn() {
4050
+ const earlier = this.turnTail;
4051
+ const endTurn = this.beginTurn();
4052
+ try {
4053
+ await earlier;
4054
+ } catch {
4055
+ }
4056
+ return endTurn;
4057
+ }
4058
+ /** Whether a driver swap is registered and has not settled yet. */
4059
+ isSwapping() {
4060
+ return this.activeDriverSwap !== null;
4061
+ }
3895
4062
  /**
3896
4063
  * Await any in-flight turn before tearing a driver down. Awaits the FIFO tail
3897
4064
  * (not a single "latest turn" field) so an earlier turn that outlives a later
@@ -3931,6 +4098,53 @@ var DriverSwapGate = class {
3931
4098
  }
3932
4099
  };
3933
4100
 
4101
+ // runner/src/flow-turn-dispatch.ts
4102
+ var FLOW_TURN_COMPACTION_TIMEOUT = "Flow turn abandoned: a compaction held the driver";
4103
+ async function dispatchFlowTurn(deps, prompt, timeoutMs) {
4104
+ for (; ; ) {
4105
+ await deps.gate.awaitSwap();
4106
+ if (!await deps.awaitCompactionIdle()) throw new Error(FLOW_TURN_COMPACTION_TIMEOUT);
4107
+ const endTurn = await deps.gate.beginQueuedTurn();
4108
+ if (deps.gate.isSwapping() || deps.isCompacting()) {
4109
+ endTurn();
4110
+ continue;
4111
+ }
4112
+ try {
4113
+ await deps.ensureDriverStarted();
4114
+ await awaitAgentEnd(deps.getDriver(), prompt, timeoutMs);
4115
+ return;
4116
+ } finally {
4117
+ endTurn();
4118
+ }
4119
+ }
4120
+ }
4121
+ function awaitAgentEnd(driver, prompt, timeoutMs) {
4122
+ return new Promise((resolve5, reject) => {
4123
+ let settled = false;
4124
+ const onEvent = (raw) => {
4125
+ const event = raw;
4126
+ if (event.type === "agent_end") done();
4127
+ else if (event.type === "error")
4128
+ done(new Error(event.error ?? event.message ?? "Agent error"));
4129
+ };
4130
+ const done = (err) => {
4131
+ if (settled) return;
4132
+ settled = true;
4133
+ clearTimeout(timer);
4134
+ if (driver.off) driver.off("agent-event", onEvent);
4135
+ else driver.removeListener("agent-event", onEvent);
4136
+ if (err) reject(err);
4137
+ else resolve5();
4138
+ };
4139
+ const timer = setTimeout(
4140
+ () => done(new Error(`Flow turn timed out after ${timeoutMs / 1e3}s`)),
4141
+ timeoutMs
4142
+ );
4143
+ driver.on("agent-event", onEvent);
4144
+ driver.prompt(prompt).catch(done);
4145
+ });
4146
+ }
4147
+
3934
4148
  // runner/src/reply-routing.ts
3935
4149
  async function routeReply(deps) {
3936
4150
  const current = deps.getDriver();
@@ -5502,7 +5716,7 @@ function buildResourcesAvailablePayload(manager, mcpManager, driverLive, bakedSe
5502
5716
  ...s,
5503
5717
  live: driverLive || (bakedServerIds?.has(s.id) ?? false)
5504
5718
  }));
5505
- return { type: "resources_available", mounts, connectors, mcp_servers };
5719
+ return { type: "resources_available", mounts, connectors, mcp_servers, sessionRoot: true };
5506
5720
  }
5507
5721
  function isTerminalFlowStatus(status) {
5508
5722
  return status === "complete" || status === "cancelled";
@@ -5524,6 +5738,16 @@ function registerActiveFlow(flows, runId, entry) {
5524
5738
  flows.set(runId, entry);
5525
5739
  return removed;
5526
5740
  }
5741
+ function pickFlowToolTarget(flows, manager) {
5742
+ let latest;
5743
+ for (const entry of flows) latest = entry;
5744
+ if (!latest || !manager) return null;
5745
+ if (isTerminalFlowStatus(latest.adapter.getExecution(latest.handle).status)) return null;
5746
+ return { manager, connectorId: latest.connectorId };
5747
+ }
5748
+ function flowStartNeedsDriverRestart(state) {
5749
+ return state.driverStarted && state.driverType === "claude-sdk" && !state.flowToolsBaked;
5750
+ }
5527
5751
  async function setUpFlowConnector(deps) {
5528
5752
  const recreated = await deps.recreateForFlowTools();
5529
5753
  const manager = deps.resolveManager();
@@ -6428,6 +6652,8 @@ async function startAgentServer(opts) {
6428
6652
  ...cloudSecrets ? { cloudSecrets } : {},
6429
6653
  ...wireAgentConfig?.thinking ? { thinking: wireAgentConfig.thinking } : {},
6430
6654
  ...wireAgentConfig?.effort ? { effort: wireAgentConfig.effort } : {},
6655
+ // Every claude-sdk driver carries the flow tools, so a run can start mid-turn.
6656
+ extraInProcessMcpServers: buildPermanentFlowMcpServers,
6431
6657
  // Protocol v2 `<CAPABILITIES>` block — joins each registered capability's
6432
6658
  // `promptFragment` (framework first, then client, then agent-side
6433
6659
  // surfaces). Built lazily inside `buildSessionConfig` so newly registered
@@ -6513,6 +6739,7 @@ async function startAgentServer(opts) {
6513
6739
  });
6514
6740
  let sessionConfig;
6515
6741
  let agentSession;
6742
+ let flowToolsBaked = false;
6516
6743
  let secretProvider;
6517
6744
  let runtimeIdentity;
6518
6745
  let preMintedSecrets;
@@ -6767,6 +6994,16 @@ async function startAgentServer(opts) {
6767
6994
  const iter = activeFlows.values().next();
6768
6995
  return iter.done ? null : iter.value;
6769
6996
  }
6997
+ function resolveFlowToolTarget() {
6998
+ return pickFlowToolTarget(activeFlows.values(), resourceManager);
6999
+ }
7000
+ async function buildPermanentFlowMcpServers() {
7001
+ const server = await buildLazySdkFlowTools(describeFlowOperations(), resolveFlowToolTarget, {
7002
+ z: z
7003
+ });
7004
+ flowToolsBaked = server !== null;
7005
+ return server ? { "skaile-flow": server } : void 0;
7006
+ }
6770
7007
  const flowConnectorReadiness = createFlowConnectorReadiness(() => getOnlyActiveFlow() !== null);
6771
7008
  const flowMutateConnectorWaitMs = resolveFlowMutateConnectorWaitMs();
6772
7009
  async function ensureDriverStarted() {
@@ -6833,33 +7070,17 @@ async function startAgentServer(opts) {
6833
7070
  return stimulusBus;
6834
7071
  }
6835
7072
  function awaitFlowAgentEnd(prompt, timeoutMs) {
6836
- return new Promise((resolve5, reject) => {
6837
- let settled = false;
6838
- const onEvent = (event) => {
6839
- if (event.type === "agent_end") done();
6840
- else if (event.type === "error") {
6841
- const msg = event.error ?? event.message ?? "Agent error";
6842
- done(new Error(msg));
6843
- }
6844
- };
6845
- const done = (err) => {
6846
- if (settled) return;
6847
- settled = true;
6848
- clearTimeout(timer);
6849
- driver.off?.(
6850
- "agent-event",
6851
- onEvent
6852
- ) ?? driver.removeListener("agent-event", onEvent);
6853
- if (err) reject(err);
6854
- else resolve5();
6855
- };
6856
- const timer = setTimeout(
6857
- () => done(new Error(`Flow turn timed out after ${timeoutMs / 1e3}s`)),
6858
- timeoutMs
6859
- );
6860
- driver.on("agent-event", onEvent);
6861
- driver.prompt(prompt).catch(done);
6862
- });
7073
+ return dispatchFlowTurn(
7074
+ {
7075
+ gate: driverSwapGate,
7076
+ awaitCompactionIdle: () => awaitCompactionIdle("flow turn"),
7077
+ isCompacting: () => !compactionGate.isIdle(),
7078
+ ensureDriverStarted,
7079
+ getDriver: () => driver
7080
+ },
7081
+ prompt,
7082
+ timeoutMs
7083
+ );
6863
7084
  }
6864
7085
  function ensureResourceManagerForFlow() {
6865
7086
  if (!resourceManager) {
@@ -6873,7 +7094,13 @@ async function startAgentServer(opts) {
6873
7094
  return resourceManager;
6874
7095
  }
6875
7096
  async function recreateDriverForFlowTools() {
6876
- if (!driverStarted || agentSession?.driverType !== "claude-sdk") return false;
7097
+ if (!flowStartNeedsDriverRestart({
7098
+ driverStarted,
7099
+ driverType: agentSession?.driverType,
7100
+ flowToolsBaked
7101
+ })) {
7102
+ return false;
7103
+ }
6877
7104
  const prevSessionId = driver.runtimeSessionId;
6878
7105
  log(
6879
7106
  `[serve] restarting driver to register flow connector tools (resume=${prevSessionId ?? "none"})`
@@ -6983,9 +7210,14 @@ async function startAgentServer(opts) {
6983
7210
  if (agentSession?.driverType === "claude-sdk") {
6984
7211
  try {
6985
7212
  const server = await buildSdkConnectorTools(manager, { z: z });
6986
- const flowServer = await buildSdkFlowTools(manager, connectorId, { z: z });
7213
+ const flowServer = flowToolsBaked ? null : await buildSdkFlowTools(manager, connectorId, { z: z });
7214
+ const driverConfig = driver.config;
7215
+ driverConfig.mcpServers = {
7216
+ ...driverConfig.mcpServers,
7217
+ ...server ? { "skaile-connectors": server } : {},
7218
+ ...flowServer ? { "skaile-flow": flowServer } : {}
7219
+ };
6987
7220
  if (server) {
6988
- driver.config.mcpServers = flowServer ? { "skaile-connectors": server, "skaile-flow": flowServer } : { "skaile-connectors": server };
6989
7221
  log(
6990
7222
  `[serve] rebuilt MCP connector tools for flow ${connectorId}` + (flowServer ? " (+ skaile-flow agent tools)" : "")
6991
7223
  );
@@ -7388,7 +7620,8 @@ async function startAgentServer(opts) {
7388
7620
  try {
7389
7621
  const server = await buildSdkConnectorTools(resourceManager, { z: z });
7390
7622
  if (server) {
7391
- driver.config.mcpServers = { "skaile-connectors": server };
7623
+ const driverConfig = driver.config;
7624
+ driverConfig.mcpServers = { ...driverConfig.mcpServers, "skaile-connectors": server };
7392
7625
  log(`[serve] rebuilt MCP connector tools (${storesRegistered} new store(s))`);
7393
7626
  } else {
7394
7627
  log(`[serve] buildSdkConnectorTools returned null`);
@@ -7848,21 +8081,11 @@ async function startAgentServer(opts) {
7848
8081
  }
7849
8082
  async function handleResourceRequestCommand(cmd) {
7850
8083
  if (!await awaitSessionReadyOrFail()) return;
7851
- if (resourceManager?.has(cmd.connectorId)) {
7852
- await handleMountResourceRequest(cmd, resourceManager, sendEvent);
7853
- return;
7854
- }
7855
- if (!resourceManager) {
7856
- sendEvent({
7857
- type: "resource_response",
7858
- requestId: cmd.requestId,
7859
- resourceId: cmd.connectorId,
7860
- operation: cmd.operation,
7861
- error: "No resources available \u2014 no mounts or connectors configured"
7862
- });
7863
- return;
7864
- }
7865
- void handleResourceRequest(cmd, resourceManager, sendEvent);
8084
+ await dispatchResourceRequest(cmd, {
8085
+ resourceManager,
8086
+ projectDir: opts.projectDir,
8087
+ emit: sendEvent
8088
+ });
7866
8089
  }
7867
8090
  async function handleConnectorMutate(cmd) {
7868
8091
  await executeConnectorMutate(cmd, {
@@ -8387,6 +8610,6 @@ function touchSession(state) {
8387
8610
  return { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
8388
8611
  }
8389
8612
 
8390
- export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS, MOUNT_LIST_MAX_DEPTH, MOUNT_LIST_MAX_ENTRIES, MOUNT_READ_DEADLINE_FACTOR, MOUNT_TREE_OP_DEADLINE_FACTOR, MarkdownStreamer, PreInitRingSink, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, connectorRefreshKind, createAgentSession, createFlowConnectorReadiness, createManagedCodexSubpromptDriver, createSessionStimulusBus, defineCapability, deleteSession, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureClaudeSettingsDisablesConnectors, ensureGitConfigInclude, executeConnectorMutate, extractClaudeAiOauthExpiresAt, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, hasNonTerminalFlow, hostOpResumeStimulus, installPreInitRingSink, isTerminalFlowStatus, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadManagedCodexHostConfig, loadSession, loadSessionById, mcpAuthSecretKey, newSession, nulTailPaddingLength, pickRepointedManager, planFlowMutate, prepareCodexTools, reconcilePendingDecisions, registerActiveFlow, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveFlowMutateConnectorWaitMs, resolveMixin, runAgentChat, saveSession, setCurrentSession, setUpFlowConnector, startAgentServer, stimulusFromMetas, supportsLiveToolUpdates, touchSession, validateInputResponse, writeClaudeCodeCredentialsFile };
8391
- //# sourceMappingURL=chunk-Q3YS5M3E.js.map
8392
- //# sourceMappingURL=chunk-Q3YS5M3E.js.map
8613
+ export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS, MOUNT_LIST_MAX_DEPTH, MOUNT_LIST_MAX_ENTRIES, MOUNT_READ_DEADLINE_FACTOR, MOUNT_TREE_OP_DEADLINE_FACTOR, MarkdownStreamer, PreInitRingSink, SESSION_ROOT_WRITABLE_DIRS, SESSION_ROOT_WRITABLE_FILES, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, connectorRefreshKind, createAgentSession, createFlowConnectorReadiness, createManagedCodexSubpromptDriver, createSessionStimulusBus, defineCapability, deleteSession, dispatchResourceRequest, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureClaudeSettingsDisablesConnectors, ensureGitConfigInclude, executeConnectorMutate, extractClaudeAiOauthExpiresAt, flowStartNeedsDriverRestart, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, handleSessionRootResourceRequest, hasNonTerminalFlow, hostOpResumeStimulus, installPreInitRingSink, isSessionRootPathAllowed, isTerminalFlowStatus, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadManagedCodexHostConfig, loadSession, loadSessionById, mcpAuthSecretKey, newSession, nulTailPaddingLength, pickFlowToolTarget, pickRepointedManager, planFlowMutate, prepareCodexTools, reconcilePendingDecisions, registerActiveFlow, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveFlowMutateConnectorWaitMs, resolveMixin, runAgentChat, saveSession, setCurrentSession, setUpFlowConnector, startAgentServer, stimulusFromMetas, supportsLiveToolUpdates, touchSession, validateInputResponse, writeClaudeCodeCredentialsFile };
8614
+ //# sourceMappingURL=chunk-Q6SWQEF7.js.map
8615
+ //# sourceMappingURL=chunk-Q6SWQEF7.js.map