@skaile/workspaces 1.8.1 → 1.9.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 (101) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-Y66NCOQZ.js → asset-feeds-LD6QKJ2R.js} +4 -4
  4. package/dist/{asset-feeds-Y66NCOQZ.js.map → asset-feeds-LD6QKJ2R.js.map} +1 -1
  5. package/dist/asset-manager/index.js +1 -1
  6. package/dist/{chunk-LLNSPJWB.js → chunk-5F3GULZT.js} +3 -3
  7. package/dist/{chunk-LLNSPJWB.js.map → chunk-5F3GULZT.js.map} +1 -1
  8. package/dist/{chunk-Y3UCU4ZK.js → chunk-5LPARFB5.js} +2 -2
  9. package/dist/{chunk-Y3UCU4ZK.js.map → chunk-5LPARFB5.js.map} +1 -1
  10. package/dist/{chunk-TITPPC54.js → chunk-6Q7CNVU3.js} +3 -3
  11. package/dist/{chunk-TITPPC54.js.map → chunk-6Q7CNVU3.js.map} +1 -1
  12. package/dist/{chunk-PP2LOT4W.js → chunk-A2CDJRRH.js} +3 -3
  13. package/dist/{chunk-PP2LOT4W.js.map → chunk-A2CDJRRH.js.map} +1 -1
  14. package/dist/{chunk-FK2L3MTF.js → chunk-HGLQYLZB.js} +336 -245
  15. package/dist/chunk-HGLQYLZB.js.map +1 -0
  16. package/dist/{chunk-VBRXFLIP.js → chunk-JCKGYBWY.js} +24 -16
  17. package/dist/chunk-JCKGYBWY.js.map +1 -0
  18. package/dist/{chunk-O3D4KYFG.js → chunk-JPKWPX5Q.js} +3 -3
  19. package/dist/{chunk-O3D4KYFG.js.map → chunk-JPKWPX5Q.js.map} +1 -1
  20. package/dist/{chunk-THJZ3JZE.js → chunk-MBGSJM7H.js} +6 -6
  21. package/dist/{chunk-THJZ3JZE.js.map → chunk-MBGSJM7H.js.map} +1 -1
  22. package/dist/{chunk-UPZGQZEJ.js → chunk-MW7GNYRT.js} +3 -3
  23. package/dist/{chunk-UPZGQZEJ.js.map → chunk-MW7GNYRT.js.map} +1 -1
  24. package/dist/{chunk-34U5UC6G.js → chunk-SBU73P7R.js} +6 -6
  25. package/dist/{chunk-34U5UC6G.js.map → chunk-SBU73P7R.js.map} +1 -1
  26. package/dist/{chunk-35OWUKOD.js → chunk-VWSR6K7C.js} +2 -2
  27. package/dist/{chunk-35OWUKOD.js.map → chunk-VWSR6K7C.js.map} +1 -1
  28. package/dist/{chunk-PK7Q7MC7.js → chunk-XJOPAGZX.js} +4 -4
  29. package/dist/{chunk-PK7Q7MC7.js.map → chunk-XJOPAGZX.js.map} +1 -1
  30. package/dist/cli/index.js +25 -25
  31. package/dist/connectors/index.js +1 -1
  32. package/dist/connectors/src/credential-helper-script.d.ts +8 -5
  33. package/dist/connectors/src/credential-helper-script.d.ts.map +1 -1
  34. package/dist/connectors/src/managed-gitconfig.d.ts +4 -2
  35. package/dist/connectors/src/managed-gitconfig.d.ts.map +1 -1
  36. package/dist/{ensure-sources-NXBYK5GP.js → ensure-sources-S6QBARWF.js} +4 -4
  37. package/dist/{ensure-sources-NXBYK5GP.js.map → ensure-sources-S6QBARWF.js.map} +1 -1
  38. package/dist/factory-assets/connectors/box.js +1 -1
  39. package/dist/factory-assets/connectors/deploy.js +1 -1
  40. package/dist/factory-assets/connectors/devserver.js +1 -1
  41. package/dist/factory-assets/connectors/flow/adapter.d.ts +3 -2
  42. package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
  43. package/dist/factory-assets/connectors/flow/adapter.js +1 -1
  44. package/dist/factory-assets/connectors/flow/run-flow.js +2 -2
  45. package/dist/factory-assets/connectors/flow.js +1 -1
  46. package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -1
  47. package/dist/factory-assets/connectors/git.js +1 -1
  48. package/dist/factory-assets/connectors/gmail.js +1 -1
  49. package/dist/factory-assets/connectors/googledrive.js +1 -1
  50. package/dist/factory-assets/connectors/local.js +1 -1
  51. package/dist/factory-assets/connectors/mattermost.js +1 -1
  52. package/dist/factory-assets/connectors/memory.js +1 -1
  53. package/dist/factory-assets/connectors/minio.js +1 -1
  54. package/dist/factory-assets/connectors/postgres.js +1 -1
  55. package/dist/factory-assets/connectors/s3.js +1 -1
  56. package/dist/factory-assets/connectors/sharepoint.js +1 -1
  57. package/dist/factory-assets/connectors/sqlite.js +1 -1
  58. package/dist/factory-assets/connectors/static-server.js +1 -1
  59. package/dist/factory-assets/connectors/tunnel.js +1 -1
  60. package/dist/factory-assets/connectors/webdav.js +1 -1
  61. package/dist/factory-assets/connectors/xstate-store.js +1 -1
  62. package/dist/factory-assets/connectors/xstate.js +1 -1
  63. package/dist/{helpers-DN4MWOHB.js → helpers-ZZZY7HUJ.js} +4 -4
  64. package/dist/{helpers-DN4MWOHB.js.map → helpers-ZZZY7HUJ.js.map} +1 -1
  65. package/dist/{library-publish-TPWFSO3Q.js → library-publish-NCMIFF3V.js} +6 -6
  66. package/dist/{library-publish-TPWFSO3Q.js.map → library-publish-NCMIFF3V.js.map} +1 -1
  67. package/dist/{open-library-ST2VFQTK.js → open-library-VFS6WIO7.js} +5 -5
  68. package/dist/{open-library-ST2VFQTK.js.map → open-library-VFS6WIO7.js.map} +1 -1
  69. package/dist/{project-4M6QXHCH.js → project-SC7TVEQ6.js} +5 -5
  70. package/dist/{project-4M6QXHCH.js.map → project-SC7TVEQ6.js.map} +1 -1
  71. package/dist/runner/index.js +4 -4
  72. package/dist/runner/src/serve.d.ts +67 -4
  73. package/dist/runner/src/serve.d.ts.map +1 -1
  74. package/dist/runner/src/session-capability-wiring.d.ts +49 -0
  75. package/dist/runner/src/session-capability-wiring.d.ts.map +1 -0
  76. package/dist/runner/src/session-resource-handlers.d.ts +1 -2
  77. package/dist/runner/src/session-resource-handlers.d.ts.map +1 -1
  78. package/dist/sdk/asset-manager.js +1 -1
  79. package/dist/sdk/index.js +4 -4
  80. package/dist/sdk/runner.js +4 -4
  81. package/dist/sdk/session.js +2 -2
  82. package/dist/sdk/types.js +1 -1
  83. package/dist/session/index.js +2 -2
  84. package/dist/{source-KUWAEJOO.js → source-Z5HNLF6J.js} +6 -6
  85. package/dist/{source-KUWAEJOO.js.map → source-Z5HNLF6J.js.map} +1 -1
  86. package/dist/{source-manifest-publish-FTSKRYPI.js → source-manifest-publish-FA2KLZJ6.js} +7 -7
  87. package/dist/{source-manifest-publish-FTSKRYPI.js.map → source-manifest-publish-FA2KLZJ6.js.map} +1 -1
  88. package/dist/tui/index.js +4 -4
  89. package/dist/types/index.js +1 -1
  90. package/dist/types/src/flow.d.ts +26 -28
  91. package/dist/types/src/flow.d.ts.map +1 -1
  92. package/dist/types/src/index.d.ts +1 -1
  93. package/dist/types/src/index.d.ts.map +1 -1
  94. package/dist/types/src/lifecycle.d.ts +0 -8
  95. package/dist/types/src/lifecycle.d.ts.map +1 -1
  96. package/dist/types/src/version.d.ts +17 -1
  97. package/dist/types/src/version.d.ts.map +1 -1
  98. package/dist/workspace-plugin/index.js +1 -1
  99. package/package.json +1 -1
  100. package/dist/chunk-FK2L3MTF.js.map +0 -1
  101. package/dist/chunk-VBRXFLIP.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { WorkspacePlugin } from './chunk-35OWUKOD.js';
1
+ import { WorkspacePlugin } from './chunk-VWSR6K7C.js';
2
2
  import { WebSocketServerTransport } from './chunk-WQ7DE5UC.js';
3
3
  import { assembleSystemPrompt, buildCapabilitiesPromptSection } from './chunk-W3UDISS2.js';
4
4
  import { EventNormalizer } from './chunk-HKX5VSWQ.js';
@@ -6,10 +6,10 @@ import { SUPPORTED_CLOUDS, CLOUD_SECRET_ENV_KEYS } from './chunk-ISQWMBKD.js';
6
6
  import { classifyClaudeSdkError } from './chunk-GAH4YRCI.js';
7
7
  import { createDriver } from './chunk-TNSCHS4I.js';
8
8
  import { deployCatalogEntry, undeployCatalogEntry } from './chunk-LV2HPH3C.js';
9
- import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, ConnectorStartupError, buildSdkConnectorTools } from './chunk-VBRXFLIP.js';
9
+ import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, ConnectorStartupError, buildSdkConnectorTools } from './chunk-JCKGYBWY.js';
10
10
  import { loadConnectorDeclarations, SecretProviderChain, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, deriveSingleMaterializedConnectorDeclaration } from './chunk-Y6FV73IH.js';
11
11
  import { renderStimulusPrompt, buildOrchestratorPrompt } from './chunk-DEYYRFQU.js';
12
- import { PROTOCOL_VERSION } from './chunk-PK7Q7MC7.js';
12
+ import { PROTOCOL_VERSION } from './chunk-XJOPAGZX.js';
13
13
  import { resolveSettings, resolveApiKey, providerEnvKey } from './chunk-5NZ56R63.js';
14
14
  import { resolveRuntimeAssets } from './chunk-7J7LQP6T.js';
15
15
  import { resolveSkWorkspaceConfig, resolveAgentDir, cloudConfigFromProfile, stageMaterializedSkills, loadMcpServerDeclarations, COMPACTION_DEFAULTS, validateAssetRecipeAttr, deriveSingleMaterializedMcpDeclaration } from './chunk-ISA7R7PK.js';
@@ -3292,6 +3292,137 @@ function rewriteFileChangedPath(event, cwd, mounts) {
3292
3292
  }
3293
3293
  return event;
3294
3294
  }
3295
+ function parseFleetHealthBody(body) {
3296
+ const trimmed = body.trim().toLowerCase();
3297
+ if (trimmed === "healthy") return "healthy";
3298
+ if (trimmed === "degraded") return "degraded";
3299
+ return "error";
3300
+ }
3301
+ async function dispatchFleetHealthFlag(dir, fileName, manager, log) {
3302
+ if (!manager) return;
3303
+ const connectorId = fileName;
3304
+ if (!connectorId || connectorId.startsWith(".")) return;
3305
+ let verdict;
3306
+ try {
3307
+ verdict = parseFleetHealthBody(await readFile(join(dir, connectorId), "utf8"));
3308
+ } catch {
3309
+ verdict = "error";
3310
+ }
3311
+ try {
3312
+ await manager.reportFleetHealth(connectorId, verdict);
3313
+ log.debug("fleet-health flag dispatched", { connectorId, verdict });
3314
+ } catch (err) {
3315
+ log.warn("fleet-health flag dispatch failed", {
3316
+ connectorId,
3317
+ error: err instanceof Error ? err.message : String(err)
3318
+ });
3319
+ }
3320
+ }
3321
+
3322
+ // runner/src/refresh-flag-dispatcher.ts
3323
+ async function dispatchRefreshToExposedGitMounts(manager, log) {
3324
+ if (!manager) return;
3325
+ let gitConnectors;
3326
+ try {
3327
+ gitConnectors = manager.listGitConnectors();
3328
+ } catch (err) {
3329
+ log.warn("listGitConnectors failed during refresh-flag dispatch", {
3330
+ error: err instanceof Error ? err.message : String(err)
3331
+ });
3332
+ return;
3333
+ }
3334
+ const eligible = gitConnectors.filter(
3335
+ (m) => m.exposeAccessToken === true && m.auth === "backend"
3336
+ );
3337
+ if (eligible.length === 0) {
3338
+ log.debug("refresh-flag fired but no eligible git connectors (Tier-2 backend) found");
3339
+ return;
3340
+ }
3341
+ log.info("refresh-flag fired -- dispatching backend mediation", {
3342
+ connectorIds: eligible.map((m) => m.id)
3343
+ });
3344
+ await Promise.all(
3345
+ eligible.map(async (m) => {
3346
+ try {
3347
+ const entry = manager.get(m.id);
3348
+ if (typeof entry.connector.refreshExposedCredential !== "function") {
3349
+ log.debug("connector lacks refreshExposedCredential -- skipping", {
3350
+ connectorId: m.id
3351
+ });
3352
+ return;
3353
+ }
3354
+ await entry.connector.refreshExposedCredential(m.id, entry.handle);
3355
+ } catch (err) {
3356
+ log.warn("refresh-flag dispatch failed for connector", {
3357
+ connectorId: m.id,
3358
+ error: err instanceof Error ? err.message : String(err)
3359
+ });
3360
+ }
3361
+ })
3362
+ );
3363
+ }
3364
+ var CLAUDE_CODE_CREDENTIALS_KEY = "CLAUDE_CODE_CREDENTIALS_JSON";
3365
+ async function writeClaudeCodeCredentialsFile(home, json) {
3366
+ const claudeDir = join(home, ".claude");
3367
+ await mkdir(claudeDir, { recursive: true, mode: 448 });
3368
+ const finalPath = join(claudeDir, ".credentials.json");
3369
+ const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
3370
+ await writeFile(tmpPath, json, { mode: 384 });
3371
+ await rename(tmpPath, finalPath);
3372
+ return finalPath;
3373
+ }
3374
+ async function mergeAndRewriteCredentialsFile(home, accessToken, expiresAt) {
3375
+ const credPath = join(home, ".claude", ".credentials.json");
3376
+ let merged = {};
3377
+ if (existsSync(credPath)) {
3378
+ try {
3379
+ merged = JSON.parse(readFileSync(credPath, "utf-8"));
3380
+ } catch {
3381
+ merged = {};
3382
+ }
3383
+ }
3384
+ const oauthBlock = merged.claudeAiOauth ?? {};
3385
+ oauthBlock.accessToken = accessToken;
3386
+ if (expiresAt) oauthBlock.expiresAt = expiresAt;
3387
+ merged.claudeAiOauth = oauthBlock;
3388
+ merged.accessToken = accessToken;
3389
+ return writeClaudeCodeCredentialsFile(home, JSON.stringify(merged));
3390
+ }
3391
+ function extractClaudeAiOauthExpiresAt(json) {
3392
+ let parsed;
3393
+ try {
3394
+ parsed = JSON.parse(json);
3395
+ } catch {
3396
+ return null;
3397
+ }
3398
+ if (!parsed || typeof parsed !== "object") return null;
3399
+ const obj = parsed;
3400
+ const oauth = obj.claudeAiOauth;
3401
+ const raw = oauth?.expiresAt ?? obj.expiresAt;
3402
+ if (raw == null) return null;
3403
+ if (typeof raw === "string") {
3404
+ const t = Date.parse(raw);
3405
+ return Number.isFinite(t) ? new Date(t).toISOString() : null;
3406
+ }
3407
+ if (typeof raw === "number" && Number.isFinite(raw)) {
3408
+ return new Date(raw).toISOString();
3409
+ }
3410
+ return null;
3411
+ }
3412
+ function readCurrentClaudeAccessToken(home) {
3413
+ const credPath = join(home, ".claude", ".credentials.json");
3414
+ if (!existsSync(credPath)) return null;
3415
+ let parsed;
3416
+ try {
3417
+ parsed = JSON.parse(readFileSync(credPath, "utf-8"));
3418
+ } catch {
3419
+ return null;
3420
+ }
3421
+ if (!parsed || typeof parsed !== "object") return null;
3422
+ const obj = parsed;
3423
+ const raw = obj.claudeAiOauth?.accessToken ?? obj.accessToken;
3424
+ return typeof raw === "string" && raw.length > 0 ? raw : null;
3425
+ }
3295
3426
 
3296
3427
  // runner/src/lifecycle-handler.ts
3297
3428
  function buildLifecycleHandler(deps) {
@@ -3534,75 +3665,6 @@ function buildMcpRuntimeHandlers(deps) {
3534
3665
  }
3535
3666
  };
3536
3667
  }
3537
- function parseFleetHealthBody(body) {
3538
- const trimmed = body.trim().toLowerCase();
3539
- if (trimmed === "healthy") return "healthy";
3540
- if (trimmed === "degraded") return "degraded";
3541
- return "error";
3542
- }
3543
- async function dispatchFleetHealthFlag(dir, fileName, manager, log) {
3544
- if (!manager) return;
3545
- const connectorId = fileName;
3546
- if (!connectorId || connectorId.startsWith(".")) return;
3547
- let verdict;
3548
- try {
3549
- verdict = parseFleetHealthBody(await readFile(join(dir, connectorId), "utf8"));
3550
- } catch {
3551
- verdict = "error";
3552
- }
3553
- try {
3554
- await manager.reportFleetHealth(connectorId, verdict);
3555
- log.debug("fleet-health flag dispatched", { connectorId, verdict });
3556
- } catch (err) {
3557
- log.warn("fleet-health flag dispatch failed", {
3558
- connectorId,
3559
- error: err instanceof Error ? err.message : String(err)
3560
- });
3561
- }
3562
- }
3563
-
3564
- // runner/src/refresh-flag-dispatcher.ts
3565
- async function dispatchRefreshToExposedGitMounts(manager, log) {
3566
- if (!manager) return;
3567
- let gitConnectors;
3568
- try {
3569
- gitConnectors = manager.listGitConnectors();
3570
- } catch (err) {
3571
- log.warn("listGitConnectors failed during refresh-flag dispatch", {
3572
- error: err instanceof Error ? err.message : String(err)
3573
- });
3574
- return;
3575
- }
3576
- const eligible = gitConnectors.filter(
3577
- (m) => m.exposeAccessToken === true && m.auth === "backend"
3578
- );
3579
- if (eligible.length === 0) {
3580
- log.debug("refresh-flag fired but no eligible git connectors (Tier-2 backend) found");
3581
- return;
3582
- }
3583
- log.info("refresh-flag fired -- dispatching backend mediation", {
3584
- connectorIds: eligible.map((m) => m.id)
3585
- });
3586
- await Promise.all(
3587
- eligible.map(async (m) => {
3588
- try {
3589
- const entry = manager.get(m.id);
3590
- if (typeof entry.connector.refreshExposedCredential !== "function") {
3591
- log.debug("connector lacks refreshExposedCredential -- skipping", {
3592
- connectorId: m.id
3593
- });
3594
- return;
3595
- }
3596
- await entry.connector.refreshExposedCredential(m.id, entry.handle);
3597
- } catch (err) {
3598
- log.warn("refresh-flag dispatch failed for connector", {
3599
- connectorId: m.id,
3600
- error: err instanceof Error ? err.message : String(err)
3601
- });
3602
- }
3603
- })
3604
- );
3605
- }
3606
3668
  var RUNNER_CAP_ORIGIN = { kind: "framework" };
3607
3669
  function notImplemented(name) {
3608
3670
  return {
@@ -3823,67 +3885,68 @@ function buildRunnerCapabilities(handlers) {
3823
3885
  })
3824
3886
  ];
3825
3887
  }
3826
- var CLAUDE_CODE_CREDENTIALS_KEY = "CLAUDE_CODE_CREDENTIALS_JSON";
3827
- async function writeClaudeCodeCredentialsFile(home, json) {
3828
- const claudeDir = join(home, ".claude");
3829
- await mkdir(claudeDir, { recursive: true, mode: 448 });
3830
- const finalPath = join(claudeDir, ".credentials.json");
3831
- const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
3832
- await writeFile(tmpPath, json, { mode: 384 });
3833
- await rename(tmpPath, finalPath);
3834
- return finalPath;
3835
- }
3836
- async function mergeAndRewriteCredentialsFile(home, accessToken, expiresAt) {
3837
- const credPath = join(home, ".claude", ".credentials.json");
3838
- let merged = {};
3839
- if (existsSync(credPath)) {
3840
- try {
3841
- merged = JSON.parse(readFileSync(credPath, "utf-8"));
3842
- } catch {
3843
- merged = {};
3844
- }
3845
- }
3846
- const oauthBlock = merged.claudeAiOauth ?? {};
3847
- oauthBlock.accessToken = accessToken;
3848
- if (expiresAt) oauthBlock.expiresAt = expiresAt;
3849
- merged.claudeAiOauth = oauthBlock;
3850
- merged.accessToken = accessToken;
3851
- return writeClaudeCodeCredentialsFile(home, JSON.stringify(merged));
3852
- }
3853
- function extractClaudeAiOauthExpiresAt(json) {
3854
- let parsed;
3855
- try {
3856
- parsed = JSON.parse(json);
3857
- } catch {
3858
- return null;
3859
- }
3860
- if (!parsed || typeof parsed !== "object") return null;
3861
- const obj = parsed;
3862
- const oauth = obj.claudeAiOauth;
3863
- const raw = oauth?.expiresAt ?? obj.expiresAt;
3864
- if (raw == null) return null;
3865
- if (typeof raw === "string") {
3866
- const t = Date.parse(raw);
3867
- return Number.isFinite(t) ? new Date(t).toISOString() : null;
3868
- }
3869
- if (typeof raw === "number" && Number.isFinite(raw)) {
3870
- return new Date(raw).toISOString();
3871
- }
3872
- return null;
3873
- }
3874
- function readCurrentClaudeAccessToken(home) {
3875
- const credPath = join(home, ".claude", ".credentials.json");
3876
- if (!existsSync(credPath)) return null;
3877
- let parsed;
3878
- try {
3879
- parsed = JSON.parse(readFileSync(credPath, "utf-8"));
3880
- } catch {
3881
- return null;
3888
+
3889
+ // runner/src/session-capability-wiring.ts
3890
+ function wireSessionCapabilities(deps) {
3891
+ const {
3892
+ capabilityRegistry,
3893
+ remoteCapabilityInvoker,
3894
+ getResourceManager,
3895
+ getPreMintedSecrets,
3896
+ emitResourcesAvailable,
3897
+ driverPicksUpToolsLive,
3898
+ getOrCreateMcpManager,
3899
+ getCompactionOrchestrator,
3900
+ getProjectDir,
3901
+ attachSkillInstance,
3902
+ log
3903
+ } = deps;
3904
+ capabilityRegistry.setRemoteInvoker(remoteCapabilityInvoker);
3905
+ const { attachConnectorInstance, ...resourceCaps } = buildSessionResourceHandlers({
3906
+ getResourceManager,
3907
+ getPreMintedSecrets,
3908
+ emitResourcesAvailable,
3909
+ log,
3910
+ getProjectDir
3911
+ });
3912
+ const mcpHandlers = buildMcpRuntimeHandlers({
3913
+ getOrCreateMcpManager,
3914
+ getPreMintedSecrets: () => getPreMintedSecrets() ?? null,
3915
+ driverPicksUpToolsLive,
3916
+ emitResourcesAvailable,
3917
+ log,
3918
+ getProjectDir
3919
+ });
3920
+ const runnerCaps = buildRunnerCapabilities({
3921
+ ...resourceCaps,
3922
+ ...mcpHandlers,
3923
+ // attach_instance routes by kind: skills stage-then-fast-restart,
3924
+ // connectors materialize-then-connect; everything else stays on the
3925
+ // MCP attach path.
3926
+ attachInstance: async (input) => {
3927
+ if (input.kind === "skill") {
3928
+ return attachSkillInstance(input.name);
3929
+ }
3930
+ if (input.kind === "connector") {
3931
+ return attachConnectorInstance(input.name, input.preMintedToken);
3932
+ }
3933
+ return mcpHandlers.attachInstance ? mcpHandlers.attachInstance(input) : {
3934
+ ok: false,
3935
+ code: "not_implemented",
3936
+ message: "attach_instance handler not configured"
3937
+ };
3938
+ },
3939
+ // setLogLevel left undefined (the cap self-falls-back to getLogStore);
3940
+ // setState remains a stub (not resource hot-plug).
3941
+ lifecycle: buildLifecycleHandler({
3942
+ getCompactionOrchestrator,
3943
+ getResourceManager,
3944
+ log
3945
+ })
3946
+ });
3947
+ for (const cap of runnerCaps) {
3948
+ capabilityRegistry.register(cap, "agent");
3882
3949
  }
3883
- if (!parsed || typeof parsed !== "object") return null;
3884
- const obj = parsed;
3885
- const raw = obj.claudeAiOauth?.accessToken ?? obj.accessToken;
3886
- return typeof raw === "string" && raw.length > 0 ? raw : null;
3887
3950
  }
3888
3951
 
3889
3952
  // runner/src/session-stimulus.ts
@@ -4032,6 +4095,11 @@ function splitConnectorsForWire(manager) {
4032
4095
  }
4033
4096
  return { mounts, connectors };
4034
4097
  }
4098
+ function pickRepointedManager(next, current, disposed) {
4099
+ if (next !== null) return next;
4100
+ if (current !== null && current === disposed) return null;
4101
+ return current;
4102
+ }
4035
4103
  function buildResourcesAvailablePayload(manager, mcpManager, driverLive, bakedServerIds) {
4036
4104
  const { mounts, connectors } = splitConnectorsForWire(manager);
4037
4105
  const mcp_servers = (mcpManager?.listServers() ?? []).map((s) => ({
@@ -4152,6 +4220,50 @@ function buildConnectorTokenMediator(deps) {
4152
4220
  }
4153
4221
  };
4154
4222
  }
4223
+ function planFlowMutate(cmd, ctx) {
4224
+ const isBareFlowId = cmd.id === "flow";
4225
+ const flowIntercept = ctx.isExistingFlow || isBareFlowId;
4226
+ const payload = cmd.payload ?? {};
4227
+ if (cmd.op === "start" && flowIntercept) {
4228
+ const flowDef = payload.flow;
4229
+ const seed = payload.seed;
4230
+ if (!flowDef?.id || !seed?.runId || !seed?.startedBy) {
4231
+ return {
4232
+ kind: "reject",
4233
+ reason: "flow.start payload missing required fields (need payload.flow.id, payload.seed.runId, payload.seed.startedBy)"
4234
+ };
4235
+ }
4236
+ if (ctx.hasActiveFlow) {
4237
+ return {
4238
+ kind: "reject",
4239
+ reason: "flow.start ignored: a flow is already active (one active flow per session; cancel it first)"
4240
+ };
4241
+ }
4242
+ return { kind: "create-start", flowDef, seed };
4243
+ }
4244
+ if (cmd.op === "hydrate" && flowIntercept && !ctx.hasActiveFlow) {
4245
+ const state = payload.state;
4246
+ if (!state || typeof state !== "object" || typeof state.runId !== "string") {
4247
+ return {
4248
+ kind: "reject",
4249
+ reason: "flow.hydrate payload missing required field payload.state (FlowExecution snapshot)"
4250
+ };
4251
+ }
4252
+ const flowDef = payload.flow;
4253
+ if (!flowDef?.id) {
4254
+ return {
4255
+ kind: "reject",
4256
+ reason: "flow.hydrate cannot bootstrap a cold container without payload.flow (FlowDefinition required when no flow is active)"
4257
+ };
4258
+ }
4259
+ return { kind: "create-hydrate", flowDef, execution: state };
4260
+ }
4261
+ let dispatchId = cmd.id;
4262
+ if (!ctx.targetExists && isBareFlowId && ctx.onlyActiveConnectorId) {
4263
+ dispatchId = ctx.onlyActiveConnectorId;
4264
+ }
4265
+ return { kind: "dispatch", dispatchId };
4266
+ }
4155
4267
  async function startAgentServer(opts) {
4156
4268
  const port = opts.port ?? 8080;
4157
4269
  const sessionId = opts.sessionId ?? process.env.SKAILE_SESSION_ID ?? "session-unknown";
@@ -4487,6 +4599,15 @@ async function startAgentServer(opts) {
4487
4599
  captureBakedMcpServers();
4488
4600
  }
4489
4601
  let resourceManager = secretsMode === "env" ? agentSession.resourceManager : null;
4602
+ const driverPicksUpToolsLive = () => agentSession?.driverType !== "claude-sdk";
4603
+ const emitResourcesAvailable = () => sendEvent(
4604
+ buildResourcesAvailablePayload(
4605
+ resourceManager,
4606
+ agentSession?.getExternalMcpManager(),
4607
+ driverPicksUpToolsLive(),
4608
+ bakedMcpServerIds
4609
+ )
4610
+ );
4490
4611
  if (secretsMode === "env") {
4491
4612
  if (!agentSession.provider) {
4492
4613
  log(
@@ -4767,15 +4888,7 @@ async function startAgentServer(opts) {
4767
4888
  log(
4768
4889
  `[serve] restarting driver to register flow connector tools (resume=${prevSessionId ?? "none"})`
4769
4890
  );
4770
- await agentSession.dispose();
4771
- agentSession = await createAgentSession({
4772
- ...sessionConfig,
4773
- resumeSessionId: prevSessionId
4774
- });
4775
- emitSystemPromptComposed(agentSession, sendEvent);
4776
- swapDriver();
4777
- rebuildCompactionOrchestrator();
4778
- captureBakedMcpServers();
4891
+ await recreateAgentSession({ resumeSessionId: prevSessionId });
4779
4892
  }
4780
4893
  driver.config.mcpServers = { "skaile-connectors": server };
4781
4894
  log(`[serve] rebuilt MCP connector tools for flow ${connectorId}`);
@@ -4959,6 +5072,7 @@ async function startAgentServer(opts) {
4959
5072
  cloudSecrets,
4960
5073
  fallbackConnectorDeclarations
4961
5074
  );
5075
+ let needsWireFallbackRecreate = false;
4962
5076
  if (!agentSession) {
4963
5077
  agentSession = await createAgentSession(sessionConfig);
4964
5078
  emitSystemPromptComposed(agentSession, sendEvent);
@@ -4966,88 +5080,61 @@ async function startAgentServer(opts) {
4966
5080
  driver = agentSession.driver;
4967
5081
  rebuildCompactionOrchestrator();
4968
5082
  registerSessionComposition(agentSession);
4969
- const driverPicksUpToolsLive = () => agentSession?.driverType !== "claude-sdk";
4970
- const emitResourcesAvailable = () => sendEvent(
4971
- buildResourcesAvailablePayload(
4972
- resourceManager,
4973
- agentSession?.getExternalMcpManager(),
4974
- driverPicksUpToolsLive(),
4975
- bakedMcpServerIds
4976
- )
4977
- );
4978
5083
  captureBakedMcpServers();
4979
5084
  emitResourcesAvailable();
4980
5085
  agentSession.startWatching();
4981
- capabilityRegistry.setRemoteInvoker(remoteCapabilityInvoker);
4982
- const { attachConnectorInstance, ...resourceCaps } = buildSessionResourceHandlers({
4983
- getResourceManager: () => resourceManager,
4984
- getPreMintedSecrets: () => preMintedSecrets,
4985
- emitResourcesAvailable,
4986
- log,
4987
- getProjectDir: () => opts.projectDir
4988
- });
4989
- const mcpHandlers = buildMcpRuntimeHandlers({
4990
- getOrCreateMcpManager: () => agentSession?.getOrCreateExternalMcpManager() ?? null,
4991
- getPreMintedSecrets: () => preMintedSecrets ?? null,
4992
- driverPicksUpToolsLive,
4993
- emitResourcesAvailable,
4994
- log,
4995
- getProjectDir: () => opts.projectDir
4996
- });
4997
- const runnerCaps = buildRunnerCapabilities({
4998
- ...resourceCaps,
4999
- ...mcpHandlers,
5000
- // attach_instance routes by kind: skills stage-then-fast-restart,
5001
- // connectors materialize-then-connect; everything else stays on the
5002
- // MCP attach path.
5003
- attachInstance: async (input) => {
5004
- if (input.kind === "skill") {
5005
- return attachSkillInstance(input.name);
5006
- }
5007
- if (input.kind === "connector") {
5008
- return attachConnectorInstance(input.name, input.preMintedToken);
5009
- }
5010
- return mcpHandlers.attachInstance ? mcpHandlers.attachInstance(input) : {
5011
- ok: false,
5012
- code: "not_implemented",
5013
- message: "attach_instance handler not configured"
5014
- };
5015
- },
5016
- // setLogLevel left undefined (the cap self-falls-back to getLogStore);
5017
- // setState remains a stub (not resource hot-plug).
5018
- lifecycle: buildLifecycleHandler({
5019
- getCompactionOrchestrator: () => compactionOrchestrator,
5020
- getResourceManager: () => resourceManager,
5021
- log
5022
- })
5023
- });
5024
- for (const cap of runnerCaps) {
5025
- capabilityRegistry.register(cap, "agent");
5026
- }
5027
5086
  log("[serve] session built from session_init envelope");
5028
5087
  } else if ((fallbackConnectorDeclarations?.length ?? 0) > 0 && !agentSession.resourceManager) {
5029
5088
  log(
5030
5089
  `[serve] session_init: recreating eagerly-built session to apply ${fallbackConnectorDeclarations.length} wire connector declaration(s) (no disk declarations)`
5031
5090
  );
5032
- return { needsWireFallbackRecreate: true };
5091
+ needsWireFallbackRecreate = true;
5033
5092
  }
5034
- return { needsWireFallbackRecreate: false };
5093
+ wireSessionCapabilities({
5094
+ capabilityRegistry,
5095
+ remoteCapabilityInvoker,
5096
+ getResourceManager: () => resourceManager,
5097
+ getPreMintedSecrets: () => preMintedSecrets,
5098
+ emitResourcesAvailable,
5099
+ driverPicksUpToolsLive,
5100
+ getOrCreateMcpManager: () => agentSession?.getOrCreateExternalMcpManager() ?? null,
5101
+ getCompactionOrchestrator: () => compactionOrchestrator,
5102
+ getProjectDir: () => opts.projectDir,
5103
+ attachSkillInstance,
5104
+ log
5105
+ });
5106
+ return { needsWireFallbackRecreate };
5035
5107
  }
5036
- async function recreateSessionForInit(pendingResumeSessionId) {
5108
+ async function recreateAgentSession(overrides) {
5109
+ const disposedManager = agentSession.resourceManager;
5037
5110
  await agentSession.dispose();
5038
- agentSession = await createAgentSession({
5039
- ...sessionConfig,
5040
- ...aiProviderConfigId ? { aiProviderConfigId } : {},
5041
- ...pendingResumeSessionId ? { resumeSessionId: pendingResumeSessionId } : {}
5042
- });
5111
+ agentSession = await createAgentSession({ ...sessionConfig, ...overrides });
5043
5112
  emitSystemPromptComposed(agentSession, sendEvent);
5044
5113
  swapDriver();
5045
5114
  rebuildCompactionOrchestrator();
5046
5115
  captureBakedMcpServers();
5047
- resourceManager = agentSession.resourceManager;
5116
+ const repointed = pickRepointedManager(
5117
+ agentSession.resourceManager,
5118
+ resourceManager,
5119
+ disposedManager
5120
+ );
5121
+ if (resourceManager !== null && resourceManager !== disposedManager && repointed !== resourceManager) {
5122
+ log(
5123
+ "[serve] WARNING: recreate displaced a lazily-created sharedState resource manager \u2014 registered shared-state stores were dropped and must be re-registered"
5124
+ );
5125
+ }
5126
+ resourceManager = repointed;
5048
5127
  agentSession.startWatching();
5049
5128
  emitAvailability();
5050
5129
  }
5130
+ async function recreateSessionForInit(pendingResumeSessionId) {
5131
+ await recreateAgentSession({
5132
+ ...aiProviderConfigId ? { aiProviderConfigId } : {},
5133
+ // Conditional, unlike the skill path's unconditional pass: here an absent
5134
+ // hint must fall through to sessionConfig's, which the platform may have set.
5135
+ ...pendingResumeSessionId ? { resumeSessionId: pendingResumeSessionId } : {}
5136
+ });
5137
+ }
5051
5138
  async function applyInitSharedState(sharedState) {
5052
5139
  if (!ensureResourceManagerForSharedState()) {
5053
5140
  sendEvent({ type: "configured" });
@@ -5226,15 +5313,7 @@ async function startAgentServer(opts) {
5226
5313
  }
5227
5314
  const prevSessionId = driver.runtimeSessionId;
5228
5315
  log(`[serve] restarting driver to pick up skill changes (resume=${prevSessionId ?? "none"})`);
5229
- await agentSession.dispose();
5230
- agentSession = await createAgentSession({
5231
- ...sessionConfig,
5232
- resumeSessionId: prevSessionId
5233
- });
5234
- emitSystemPromptComposed(agentSession, sendEvent);
5235
- swapDriver();
5236
- rebuildCompactionOrchestrator();
5237
- captureBakedMcpServers();
5316
+ await recreateAgentSession({ resumeSessionId: prevSessionId });
5238
5317
  sendEvent({
5239
5318
  type: "skills_changed",
5240
5319
  skills: catalogActions.map((a) => ({
@@ -5473,36 +5552,48 @@ async function startAgentServer(opts) {
5473
5552
  if (!resourceManager) throw new Error("connector_mutate before resources ready");
5474
5553
  const targetEntry = resourceManager.has?.(cmd.id) ? resourceManager.get(cmd.id) : null;
5475
5554
  const isExistingFlow = targetEntry?.connector?.name === "flow";
5476
- const isBareFlowId = cmd.id === "flow";
5477
- if (cmd.op === "start") {
5478
- if (isExistingFlow || isBareFlowId) {
5479
- const payload = cmd.payload ?? {};
5480
- const flowDef = payload.flow;
5481
- const seed = payload.seed;
5482
- if (flowDef?.id && seed?.runId && seed?.startedBy) {
5483
- if (activeFlows.size > 0) {
5484
- serverLog.warn("connector_mutate flow.start: another flow already active", {
5485
- activeRunIds: Array.from(activeFlows.keys())
5486
- });
5487
- return;
5488
- }
5489
- const entry = await createActiveFlow(flowDef, { seed });
5490
- serverLog.info("connector_mutate flow.start", {
5491
- runId: entry.runId,
5492
- flowId: flowDef.id
5493
- });
5494
- return;
5495
- }
5555
+ const plan = planFlowMutate(cmd, {
5556
+ targetExists: !!targetEntry,
5557
+ isExistingFlow,
5558
+ hasActiveFlow: activeFlows.size > 0,
5559
+ onlyActiveConnectorId: getOnlyActiveFlow()?.connectorId ?? null
5560
+ });
5561
+ switch (plan.kind) {
5562
+ case "create-start": {
5563
+ const entry = await createActiveFlow(plan.flowDef, { seed: plan.seed });
5564
+ serverLog.info("connector_mutate flow.start", {
5565
+ runId: entry.runId,
5566
+ flowId: plan.flowDef.id
5567
+ });
5568
+ return;
5496
5569
  }
5497
- }
5498
- let dispatchId = cmd.id;
5499
- if (!targetEntry && isBareFlowId) {
5500
- const onlyActive = getOnlyActiveFlow();
5501
- if (onlyActive) {
5502
- dispatchId = onlyActive.connectorId;
5570
+ case "create-hydrate": {
5571
+ const entry = await createActiveFlow(plan.flowDef, { execution: plan.execution });
5572
+ serverLog.info("connector_mutate flow.hydrate (bootstrap)", {
5573
+ runId: entry.runId,
5574
+ flowId: plan.flowDef.id
5575
+ });
5576
+ return;
5577
+ }
5578
+ case "reject": {
5579
+ serverLog.warn("connector_mutate rejected", {
5580
+ id: cmd.id,
5581
+ op: cmd.op,
5582
+ reason: plan.reason
5583
+ });
5584
+ sendEvent({
5585
+ type: "error",
5586
+ message: `connector_mutate rejected (id=${cmd.id}, op=${cmd.op}): ${plan.reason}`,
5587
+ fatal: false,
5588
+ category: "validation"
5589
+ });
5590
+ return;
5591
+ }
5592
+ case "dispatch": {
5593
+ await resourceManager.executeOp(plan.dispatchId, cmd.op, cmd.payload ?? {});
5594
+ return;
5503
5595
  }
5504
5596
  }
5505
- await resourceManager.executeOp(dispatchId, cmd.op, cmd.payload ?? {});
5506
5597
  } catch (err) {
5507
5598
  serverLog.warn("connector_mutate failed", {
5508
5599
  id: cmd.id,
@@ -5599,7 +5690,7 @@ async function startAgentServer(opts) {
5599
5690
  }
5600
5691
  async function handleDebug(cmd) {
5601
5692
  if (!await awaitSessionReadyOrFail()) return;
5602
- log(`[serve] debug query=${cmd.query}`);
5693
+ serverLog.debug(`[serve] debug query=${cmd.query}`);
5603
5694
  let result;
5604
5695
  try {
5605
5696
  result = await computeDebugResult(cmd);
@@ -5948,6 +6039,6 @@ function touchSession(state) {
5948
6039
  return { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
5949
6040
  }
5950
6041
 
5951
- 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, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, connectorRefreshKind, createAgentSession, createSessionStimulusBus, defineCapability, deleteSession, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureGitConfigInclude, extractClaudeAiOauthExpiresAt, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, installPreInitRingSink, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadSession, loadSessionById, mcpAuthSecretKey, newSession, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveMixin, runAgentChat, saveSession, setCurrentSession, startAgentServer, touchSession, writeClaudeCodeCredentialsFile };
5952
- //# sourceMappingURL=chunk-FK2L3MTF.js.map
5953
- //# sourceMappingURL=chunk-FK2L3MTF.js.map
6042
+ 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, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, connectorRefreshKind, createAgentSession, createSessionStimulusBus, defineCapability, deleteSession, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureGitConfigInclude, extractClaudeAiOauthExpiresAt, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, installPreInitRingSink, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadSession, loadSessionById, mcpAuthSecretKey, newSession, pickRepointedManager, planFlowMutate, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveMixin, runAgentChat, saveSession, setCurrentSession, startAgentServer, touchSession, writeClaudeCodeCredentialsFile };
6043
+ //# sourceMappingURL=chunk-HGLQYLZB.js.map
6044
+ //# sourceMappingURL=chunk-HGLQYLZB.js.map