@skaile/workspaces 4.20.0 → 4.21.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 +8 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-HQJGP42P.js → asset-feeds-HKPNPO7N.js} +4 -4
  4. package/dist/{asset-feeds-HQJGP42P.js.map → asset-feeds-HKPNPO7N.js.map} +1 -1
  5. package/dist/asset-manager/index.js +1 -1
  6. package/dist/bridge/drivers/claude-sdk.js +160 -5
  7. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  8. package/dist/bridge/drivers/codex.js +2 -2
  9. package/dist/bridge/drivers/continue.js +3 -3
  10. package/dist/bridge/drivers/echo.js +3 -3
  11. package/dist/bridge/drivers/gemini.js +5 -5
  12. package/dist/bridge/drivers/goose.js +3 -3
  13. package/dist/bridge/drivers/omp.js +20 -4
  14. package/dist/bridge/drivers/omp.js.map +1 -1
  15. package/dist/bridge/drivers/opencode.js +3 -3
  16. package/dist/bridge/drivers/qwen.js +5 -5
  17. package/dist/bridge/index.js +5 -5
  18. package/dist/bridge/src/drivers/claude-context-usage.d.ts +104 -0
  19. package/dist/bridge/src/drivers/claude-context-usage.d.ts.map +1 -0
  20. package/dist/bridge/src/drivers/claude-sdk.d.ts +13 -1
  21. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  22. package/dist/bridge/src/drivers/omp.d.ts +8 -1
  23. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  24. package/dist/bridge/src/types.d.ts +16 -1
  25. package/dist/bridge/src/types.d.ts.map +1 -1
  26. package/dist/{chunk-IDPHRLYV.js → chunk-5FMWNSAQ.js} +3 -3
  27. package/dist/{chunk-IDPHRLYV.js.map → chunk-5FMWNSAQ.js.map} +1 -1
  28. package/dist/{chunk-666BKSSR.js → chunk-5YDCUHJI.js} +3 -3
  29. package/dist/{chunk-666BKSSR.js.map → chunk-5YDCUHJI.js.map} +1 -1
  30. package/dist/{chunk-D3LQY3MT.js → chunk-AEOHSR27.js} +3 -3
  31. package/dist/{chunk-D3LQY3MT.js.map → chunk-AEOHSR27.js.map} +1 -1
  32. package/dist/{chunk-QNC7VEBL.js → chunk-EJU2TOGT.js} +3 -3
  33. package/dist/{chunk-QNC7VEBL.js.map → chunk-EJU2TOGT.js.map} +1 -1
  34. package/dist/{chunk-EMWWU6RR.js → chunk-ES4E6RDZ.js} +3 -3
  35. package/dist/{chunk-EMWWU6RR.js.map → chunk-ES4E6RDZ.js.map} +1 -1
  36. package/dist/{chunk-XJTD6KWX.js → chunk-EUGEEYGD.js} +2 -2
  37. package/dist/{chunk-XJTD6KWX.js.map → chunk-EUGEEYGD.js.map} +1 -1
  38. package/dist/{chunk-RJ67DIJI.js → chunk-FELWDKLQ.js} +3 -3
  39. package/dist/{chunk-RJ67DIJI.js.map → chunk-FELWDKLQ.js.map} +1 -1
  40. package/dist/{chunk-3FGGVQDU.js → chunk-HA674IQL.js} +6 -6
  41. package/dist/{chunk-3FGGVQDU.js.map → chunk-HA674IQL.js.map} +1 -1
  42. package/dist/{chunk-VFUY5O4T.js → chunk-I4VIRPHS.js} +3 -3
  43. package/dist/{chunk-VFUY5O4T.js.map → chunk-I4VIRPHS.js.map} +1 -1
  44. package/dist/{chunk-RZNASEEJ.js → chunk-IZAN5MHL.js} +3 -3
  45. package/dist/{chunk-RZNASEEJ.js.map → chunk-IZAN5MHL.js.map} +1 -1
  46. package/dist/{chunk-DMDZTEL4.js → chunk-ODIJJXXB.js} +6 -6
  47. package/dist/{chunk-DMDZTEL4.js.map → chunk-ODIJJXXB.js.map} +1 -1
  48. package/dist/{chunk-P6L3CMKN.js → chunk-OPSKLUB4.js} +2 -2
  49. package/dist/{chunk-P6L3CMKN.js.map → chunk-OPSKLUB4.js.map} +1 -1
  50. package/dist/{chunk-CHGN5BTN.js → chunk-R3EU2FFW.js} +4 -4
  51. package/dist/{chunk-CHGN5BTN.js.map → chunk-R3EU2FFW.js.map} +1 -1
  52. package/dist/{chunk-OR7C7PTE.js → chunk-RBTVXXD5.js} +3 -3
  53. package/dist/{chunk-OR7C7PTE.js.map → chunk-RBTVXXD5.js.map} +1 -1
  54. package/dist/{chunk-56UHERYI.js → chunk-RLACUE4X.js} +3 -3
  55. package/dist/{chunk-56UHERYI.js.map → chunk-RLACUE4X.js.map} +1 -1
  56. package/dist/{chunk-TLOP6FLY.js → chunk-RTD5KAM4.js} +17 -2
  57. package/dist/chunk-RTD5KAM4.js.map +1 -0
  58. package/dist/{chunk-TFCZYDOE.js → chunk-RZ2YIFT6.js} +6 -6
  59. package/dist/{chunk-TFCZYDOE.js.map → chunk-RZ2YIFT6.js.map} +1 -1
  60. package/dist/{chunk-PGQDBXS7.js → chunk-S5A5MVJN.js} +4 -4
  61. package/dist/chunk-S5A5MVJN.js.map +1 -0
  62. package/dist/{chunk-4WBZC7UF.js → chunk-XBMCUMZT.js} +4 -4
  63. package/dist/{chunk-4WBZC7UF.js.map → chunk-XBMCUMZT.js.map} +1 -1
  64. package/dist/{chunk-2KTI5R4T.js → chunk-YEQ3BXOY.js} +3 -3
  65. package/dist/{chunk-2KTI5R4T.js.map → chunk-YEQ3BXOY.js.map} +1 -1
  66. package/dist/{chunk-EC24QFGP.js → chunk-ZDSZGV5F.js} +7 -7
  67. package/dist/{chunk-EC24QFGP.js.map → chunk-ZDSZGV5F.js.map} +1 -1
  68. package/dist/{chunk-OFC725VA.js → chunk-ZJEQFNKE.js} +592 -11
  69. package/dist/chunk-ZJEQFNKE.js.map +1 -0
  70. package/dist/cli/index.js +35 -35
  71. package/dist/connectors/index.js +7 -7
  72. package/dist/connectors-shared/index.js +2 -2
  73. package/dist/{ensure-sources-LQNEZUFT.js → ensure-sources-MUS622KB.js} +4 -4
  74. package/dist/{ensure-sources-LQNEZUFT.js.map → ensure-sources-MUS622KB.js.map} +1 -1
  75. package/dist/factory-assets/connectors/box.js +7 -7
  76. package/dist/factory-assets/connectors/deploy.js +7 -7
  77. package/dist/factory-assets/connectors/devserver.js +7 -7
  78. package/dist/factory-assets/connectors/flow/adapter.js +7 -7
  79. package/dist/factory-assets/connectors/flow/run-flow.js +8 -8
  80. package/dist/factory-assets/connectors/flow.js +7 -7
  81. package/dist/factory-assets/connectors/git.js +7 -7
  82. package/dist/factory-assets/connectors/gmail.js +7 -7
  83. package/dist/factory-assets/connectors/googledrive.js +7 -7
  84. package/dist/factory-assets/connectors/local.js +7 -7
  85. package/dist/factory-assets/connectors/mattermost.js +7 -7
  86. package/dist/factory-assets/connectors/memory.js +7 -7
  87. package/dist/factory-assets/connectors/minio.js +7 -7
  88. package/dist/factory-assets/connectors/postgres.js +7 -7
  89. package/dist/factory-assets/connectors/s3.js +7 -7
  90. package/dist/factory-assets/connectors/sharepoint.js +7 -7
  91. package/dist/factory-assets/connectors/sqlite.js +7 -7
  92. package/dist/factory-assets/connectors/static-server.js +7 -7
  93. package/dist/factory-assets/connectors/tunnel.js +7 -7
  94. package/dist/factory-assets/connectors/webdav.js +7 -7
  95. package/dist/factory-assets/connectors/xstate-store.js +7 -7
  96. package/dist/factory-assets/connectors/xstate.js +7 -7
  97. package/dist/{helpers-73M3SDDE.js → helpers-V3IJWB75.js} +4 -4
  98. package/dist/{helpers-73M3SDDE.js.map → helpers-V3IJWB75.js.map} +1 -1
  99. package/dist/{library-publish-NLA2EBV7.js → library-publish-TXJM76SD.js} +6 -6
  100. package/dist/{library-publish-NLA2EBV7.js.map → library-publish-TXJM76SD.js.map} +1 -1
  101. package/dist/{open-library-FHPRGIP6.js → open-library-ORTV2RUE.js} +5 -5
  102. package/dist/{open-library-FHPRGIP6.js.map → open-library-ORTV2RUE.js.map} +1 -1
  103. package/dist/{project-OKV7M4BV.js → project-GI2A75UN.js} +5 -5
  104. package/dist/{project-OKV7M4BV.js.map → project-GI2A75UN.js.map} +1 -1
  105. package/dist/runner/index.js +11 -11
  106. package/dist/runner/src/compaction/orchestrator.d.ts +12 -0
  107. package/dist/runner/src/compaction/orchestrator.d.ts.map +1 -1
  108. package/dist/runner/src/context-usage/collector.d.ts +83 -0
  109. package/dist/runner/src/context-usage/collector.d.ts.map +1 -0
  110. package/dist/runner/src/context-usage/compose.d.ts +51 -0
  111. package/dist/runner/src/context-usage/compose.d.ts.map +1 -0
  112. package/dist/runner/src/context-usage/estimator.d.ts +13 -0
  113. package/dist/runner/src/context-usage/estimator.d.ts.map +1 -0
  114. package/dist/runner/src/context-usage/index.d.ts +6 -0
  115. package/dist/runner/src/context-usage/index.d.ts.map +1 -0
  116. package/dist/runner/src/context-usage/skill-listings.d.ts +8 -0
  117. package/dist/runner/src/context-usage/skill-listings.d.ts.map +1 -0
  118. package/dist/runner/src/context-usage/transcript-tracker.d.ts +35 -0
  119. package/dist/runner/src/context-usage/transcript-tracker.d.ts.map +1 -0
  120. package/dist/runner/src/serve.d.ts.map +1 -1
  121. package/dist/sdk/asset-manager.js +1 -1
  122. package/dist/sdk/bridge.js +5 -5
  123. package/dist/sdk/index.js +11 -11
  124. package/dist/sdk/runner.js +11 -11
  125. package/dist/sdk/session.js +2 -2
  126. package/dist/sdk/types.js +1 -1
  127. package/dist/session/index.js +2 -2
  128. package/dist/{setup-VBXJH72H.js → setup-GLCLE36X.js} +10 -10
  129. package/dist/{setup-VBXJH72H.js.map → setup-GLCLE36X.js.map} +1 -1
  130. package/dist/{source-6KKMQU67.js → source-N6EKFFH5.js} +6 -6
  131. package/dist/{source-6KKMQU67.js.map → source-N6EKFFH5.js.map} +1 -1
  132. package/dist/{source-manifest-publish-EPIP6RQ3.js → source-manifest-publish-BDMY4B4B.js} +7 -7
  133. package/dist/{source-manifest-publish-EPIP6RQ3.js.map → source-manifest-publish-BDMY4B4B.js.map} +1 -1
  134. package/dist/tui/index.js +11 -11
  135. package/dist/types/index.js +1 -1
  136. package/dist/types/src/context-usage.d.ts +142 -0
  137. package/dist/types/src/context-usage.d.ts.map +1 -0
  138. package/dist/types/src/events.d.ts +26 -1
  139. package/dist/types/src/events.d.ts.map +1 -1
  140. package/dist/types/src/index.d.ts +3 -2
  141. package/dist/types/src/index.d.ts.map +1 -1
  142. package/dist/types/src/protocol.d.ts +21 -1
  143. package/dist/types/src/protocol.d.ts.map +1 -1
  144. package/dist/types/src/version.d.ts +7 -1
  145. package/dist/types/src/version.d.ts.map +1 -1
  146. package/dist/workspace-plugin/adapters/mcp.js +2 -2
  147. package/dist/workspace-plugin/index.js +1 -1
  148. package/package.json +3 -3
  149. package/dist/chunk-OFC725VA.js.map +0 -1
  150. package/dist/chunk-PGQDBXS7.js.map +0 -1
  151. package/dist/chunk-TLOP6FLY.js.map +0 -1
@@ -1,29 +1,29 @@
1
- import { WorkspacePlugin } from './chunk-P6L3CMKN.js';
2
- import { buildWorkspaceToolDefs } from './chunk-IDPHRLYV.js';
1
+ import { WorkspacePlugin } from './chunk-OPSKLUB4.js';
2
+ import { buildWorkspaceToolDefs } from './chunk-5FMWNSAQ.js';
3
3
  import { findAiAssetsRoot } from './chunk-7IH3RKKK.js';
4
4
  import { WebSocketServerTransport } from './chunk-73ZXUUL6.js';
5
5
  import { assembleSystemPrompt, buildCapabilitiesPromptSection } from './chunk-W3UDISS2.js';
6
6
  import { prepareNativePolicy, codexInstanceEnvironment, parseCodexCredential, parseCodexRefreshInput, parseCodexRefreshResult } from './chunk-PE3A6FFW.js';
7
- import { resolveFlowPath } from './chunk-QNC7VEBL.js';
7
+ import { resolveFlowPath } from './chunk-EJU2TOGT.js';
8
8
  import { findAiAssetsRoot as findAiAssetsRoot$1, deployCatalogEntry, undeployCatalogEntry } from './chunk-Q6NDQ6BH.js';
9
- import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, buildSdkConnectorTools, buildLazySdkFlowTools, describeFlowOperations, buildConnectorToolDefs, buildFlowToolDefs, driveOrchestratorTurn, SessionNodeExecutor, SessionSubpromptRunner, ClassifierSubpromptRunner, SessionInlineSubFlowRunner, buildSdkFlowTools } from './chunk-EC24QFGP.js';
9
+ import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, buildSdkConnectorTools, buildLazySdkFlowTools, describeFlowOperations, buildConnectorToolDefs, buildFlowToolDefs, driveOrchestratorTurn, SessionNodeExecutor, SessionSubpromptRunner, ClassifierSubpromptRunner, SessionInlineSubFlowRunner, buildSdkFlowTools } from './chunk-ZDSZGV5F.js';
10
10
  import { loadYamlConnectorDeclarations, withMaterializedConnectorDeclarations, SecretProviderChain, ConnectorStartupError, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, isKnownSecretRef, deriveSingleMaterializedConnectorDeclaration } from './chunk-MC2MF4U5.js';
11
- import { EventNormalizer } from './chunk-4WBZC7UF.js';
11
+ import { EventNormalizer } from './chunk-XBMCUMZT.js';
12
12
  import { probeResumeTranscript, transcriptStoreForRuntime } from './chunk-6S5KL76M.js';
13
13
  import { CodexNativeStateUnavailable } from './chunk-LOO5CB5M.js';
14
- import { dispatchCapability } from './chunk-56UHERYI.js';
14
+ import { dispatchCapability } from './chunk-RLACUE4X.js';
15
15
  import { classifyClaudeSdkError } from './chunk-BGY4KTU6.js';
16
16
  import { agentExecRequested } from './chunk-YROR332M.js';
17
- import { createDriver, catalogLayer, providerCredentialEnvName, toMergedRegistry, registryCredentialEnv, AI_PROVIDER_PRESETS } from './chunk-TLOP6FLY.js';
17
+ import { createDriver, catalogLayer, providerCredentialEnvName, toMergedRegistry, registryCredentialEnv, AI_PROVIDER_PRESETS } from './chunk-RTD5KAM4.js';
18
18
  import { loadFlow } from './chunk-KTCMBEEB.js';
19
19
  import { parseFlowDefinition } from './chunk-ALLCAFHQ.js';
20
20
  import { renderStimulusPrompt } from './chunk-RQLL7L72.js';
21
- import { withActivityLabelJsonSchema, TOOL_ACTIVITY_PROMPT_SECTION, SESSION_ROOT_CONNECTOR_ID, PROTOCOL_VERSION } from './chunk-PGQDBXS7.js';
21
+ import { withActivityLabelJsonSchema, TOOL_ACTIVITY_PROMPT_SECTION, SESSION_ROOT_CONNECTOR_ID, PROTOCOL_VERSION } from './chunk-S5A5MVJN.js';
22
22
  import { resolveSettings, loadProviderRegistry } from './chunk-UWU572Q6.js';
23
23
  import { resolveRuntimeAssets } from './chunk-5RHPNNWP.js';
24
24
  import { resolveDriverPaths } from './chunk-K5GBV4SA.js';
25
25
  import { resolveSkWorkspaceConfig, resolveAgentDir, loadMcpServerDeclarations, COMPACTION_DEFAULTS, resolveCompactionThresholdPercent, validateAssetRecipeAttr, deriveSingleMaterializedMcpDeclaration, stageMaterializedSkills, readSkillAllowList, isStagedSkillMarkerFor, unstageSkill } from './chunk-DF7C3KZK.js';
26
- import { withFsDeadline, FsDeadlineError, fsDeadlineMs, tryWithFsDeadline } from './chunk-2FBPAR2V.js';
26
+ import { withFsDeadline, FsDeadlineError, fsDeadlineMs, parseFrontmatter, tryWithFsDeadline } from './chunk-2FBPAR2V.js';
27
27
  import { parseAssetRef } from './chunk-GEEW6SY2.js';
28
28
  import { resolveLogStoreConfig, createLogStoreFromConfig, OnLogBridgeSink, WsLogSink, resolveLogsRetention, enforceLogsRetention } from './chunk-JMKB7IB4.js';
29
29
  import { registryEntries, resolveEntryBaseUrl, parseModelRef, isEntryEnabled, parseCredentialRef } from './chunk-GZZPKAV5.js';
@@ -5047,6 +5047,12 @@ function resolveContextWindow(driverWindow, model) {
5047
5047
  }
5048
5048
  return driverWindow || DEFAULT_CONTEXT_WINDOW;
5049
5049
  }
5050
+ function reportedContextWindow(driverWindow, model) {
5051
+ if (model && ONE_MILLION_ALIAS_PATTERN.test(model)) {
5052
+ return Math.max(driverWindow ?? 0, ONE_MILLION_CONTEXT_WINDOW);
5053
+ }
5054
+ return driverWindow && driverWindow > 0 ? driverWindow : null;
5055
+ }
5050
5056
  function detectRateLimitInSummary(text2) {
5051
5057
  if (text2.length > RATE_LIMIT_TEXT_MAX_CHARS) return false;
5052
5058
  return RATE_LIMIT_TEXT_PATTERNS.some((p) => p.test(text2));
@@ -5097,6 +5103,20 @@ var CompactionOrchestrator = class {
5097
5103
  contextFill(usage) {
5098
5104
  return this.driver.getContextTokens?.() ?? contextTokens(usage);
5099
5105
  }
5106
+ /**
5107
+ * The context fill, in tokens, at which auto-compaction triggers — the same
5108
+ * window and tier {@link shouldCompact} uses. `null` when compaction is off.
5109
+ */
5110
+ compactAtTokens() {
5111
+ if (!this.config.enabled) return null;
5112
+ const contextWindow = resolveContextWindow(
5113
+ this.driver.getContextWindow(),
5114
+ this.driver.getModel() ?? null
5115
+ );
5116
+ return Math.round(
5117
+ contextWindow * resolveCompactionThresholdPercent(contextWindow, this.config) / 100
5118
+ );
5119
+ }
5100
5120
  trackMessage(seq) {
5101
5121
  this.currentSeq = seq;
5102
5122
  this.messagesSinceCompaction++;
@@ -5784,6 +5804,517 @@ function readCurrentClaudeAccessToken(home) {
5784
5804
  return typeof raw === "string" && raw.length > 0 ? raw : null;
5785
5805
  }
5786
5806
 
5807
+ // runner/src/context-usage/estimator.ts
5808
+ var CHARS_PER_TEXT_TOKEN = 4;
5809
+ var CHARS_PER_JSON_TOKEN = 2;
5810
+ var defaultTokenEstimator = {
5811
+ text(value) {
5812
+ return value.length === 0 ? 0 : Math.ceil(value.length / CHARS_PER_TEXT_TOKEN);
5813
+ },
5814
+ json(value) {
5815
+ if (value === void 0) return 0;
5816
+ let serialized;
5817
+ try {
5818
+ serialized = typeof value === "string" ? value : JSON.stringify(value) ?? "";
5819
+ } catch {
5820
+ return 0;
5821
+ }
5822
+ return serialized.length === 0 ? 0 : Math.ceil(serialized.length / CHARS_PER_JSON_TOKEN);
5823
+ }
5824
+ };
5825
+
5826
+ // runner/src/context-usage/compose.ts
5827
+ var SKAILE_LABELS = /* @__PURE__ */ new Set([
5828
+ "context",
5829
+ "environment",
5830
+ "resources",
5831
+ "mcp-guidance",
5832
+ "tool-activity",
5833
+ "home"
5834
+ ]);
5835
+ var BUCKET_ORDER = [
5836
+ "provider-system",
5837
+ "skaile-system",
5838
+ "agent-prompt",
5839
+ "memory",
5840
+ "skills",
5841
+ "mcp-tools",
5842
+ "builtin-tools",
5843
+ "subagents",
5844
+ "content",
5845
+ "free",
5846
+ "compaction-buffer"
5847
+ ];
5848
+ var MEASURED_DRIFT_TOLERANCE = 0.02;
5849
+ function composeContextUsageSnapshot(input) {
5850
+ const estimator = input.estimator ?? defaultTokenEstimator;
5851
+ const report = input.report;
5852
+ const fresh = report !== null && input.reportFresh;
5853
+ const driverFidelity = report?.breakdownFidelity ?? "measured";
5854
+ const buckets = /* @__PURE__ */ new Map();
5855
+ const sectionItems = input.systemPromptSections.map((s) => ({
5856
+ label: s.label,
5857
+ item: {
5858
+ name: s.label,
5859
+ tokens: estimator.text(s.value),
5860
+ ...s.source ? { source: s.source } : {}
5861
+ }
5862
+ }));
5863
+ const appended = report?.appendedSystemPromptTokens;
5864
+ if (appended !== void 0) {
5865
+ const shares = apportion(
5866
+ sectionItems.map((s) => s.item.tokens),
5867
+ appended
5868
+ );
5869
+ sectionItems.forEach((s, i) => {
5870
+ s.item.tokens = shares[i] ?? 0;
5871
+ });
5872
+ }
5873
+ const skaileItems = sectionItems.filter((s) => SKAILE_LABELS.has(s.label)).map((s) => s.item);
5874
+ const agentItems = sectionItems.filter((s) => !SKAILE_LABELS.has(s.label)).map((s) => s.item);
5875
+ buckets.set("skaile-system", itemBucket("skaile-system", skaileItems, "estimated"));
5876
+ buckets.set("agent-prompt", itemBucket("agent-prompt", agentItems, "estimated"));
5877
+ const runnerSectionTokens = sumTokens(skaileItems) + sumTokens(agentItems);
5878
+ let providerPending = false;
5879
+ if (report?.systemPromptTokens !== void 0) {
5880
+ const isolated = appended !== void 0;
5881
+ buckets.set("provider-system", {
5882
+ id: "provider-system",
5883
+ tokens: Math.max(0, report.systemPromptTokens - (isolated ? appended : runnerSectionTokens)),
5884
+ fidelity: driverFidelity === "estimated" ? "estimated" : isolated ? "measured" : "derived",
5885
+ ...report.systemPromptSections?.length ? { items: report.systemPromptSections } : {}
5886
+ });
5887
+ } else {
5888
+ providerPending = true;
5889
+ }
5890
+ setStatic(buckets, "memory", report?.memory, null, driverFidelity);
5891
+ setStatic(buckets, "skills", report?.skills, input.skills, driverFidelity);
5892
+ setStatic(buckets, "mcp-tools", report?.mcpTools, input.mcpTools, driverFidelity);
5893
+ setStatic(buckets, "builtin-tools", report?.builtinTools, null, driverFidelity);
5894
+ setStatic(buckets, "subagents", report?.subagents, null, driverFidelity);
5895
+ let contentPending = false;
5896
+ if (fresh && report.content) {
5897
+ buckets.set("content", reportBucket("content", report.content, driverFidelity));
5898
+ } else if (input.content?.complete) {
5899
+ buckets.set("content", itemBucket("content", input.content.items, "estimated"));
5900
+ } else {
5901
+ contentPending = true;
5902
+ }
5903
+ let used = null;
5904
+ let totalFidelity = "estimated";
5905
+ if (fresh && typeof report.usedTokens === "number") {
5906
+ used = report.usedTokens;
5907
+ totalFidelity = "measured";
5908
+ } else if (input.contextTokens !== null && input.contextTokens > 0) {
5909
+ used = input.contextTokens;
5910
+ totalFidelity = "measured";
5911
+ }
5912
+ if (used !== null) {
5913
+ const pinned = new Set(
5914
+ appended !== void 0 ? ["skaile-system", "agent-prompt"] : []
5915
+ );
5916
+ fitEstimatesWithin(buckets, used, pinned);
5917
+ const remaining = used - sumBuckets(buckets);
5918
+ if (contentPending) {
5919
+ buckets.set("content", {
5920
+ id: "content",
5921
+ tokens: Math.max(0, remaining),
5922
+ fidelity: "derived"
5923
+ });
5924
+ if (providerPending) buckets.set("provider-system", unknownBucket("provider-system"));
5925
+ } else if (providerPending) {
5926
+ buckets.set("provider-system", {
5927
+ id: "provider-system",
5928
+ tokens: Math.max(0, remaining),
5929
+ fidelity: "derived"
5930
+ });
5931
+ } else if (remaining !== 0) {
5932
+ absorbDrift(buckets, remaining, used);
5933
+ }
5934
+ } else {
5935
+ if (contentPending) buckets.set("content", unknownBucket("content"));
5936
+ if (providerPending) buckets.set("provider-system", unknownBucket("provider-system"));
5937
+ used = sumBuckets(buckets);
5938
+ totalFidelity = used > 0 ? "estimated" : "unknown";
5939
+ }
5940
+ const window = input.contextWindow ?? (fresh ? report.contextWindow ?? null : null);
5941
+ if (window !== null && window > 0) {
5942
+ const threshold = input.autoCompactAt !== null ? Math.min(input.autoCompactAt, window) : window;
5943
+ buckets.set("free", {
5944
+ id: "free",
5945
+ tokens: Math.max(0, threshold - used),
5946
+ fidelity: totalFidelity
5947
+ });
5948
+ if (input.autoCompactAt !== null) {
5949
+ buckets.set("compaction-buffer", {
5950
+ id: "compaction-buffer",
5951
+ tokens: Math.max(0, window - Math.max(used, threshold)),
5952
+ fidelity: totalFidelity
5953
+ });
5954
+ }
5955
+ }
5956
+ return {
5957
+ provider: input.provider,
5958
+ model: input.model,
5959
+ contextWindow: window !== null && window > 0 ? window : null,
5960
+ usedTokens: used,
5961
+ totalFidelity,
5962
+ autoCompactAt: input.autoCompactAt,
5963
+ buckets: BUCKET_ORDER.flatMap((id) => {
5964
+ const bucket = buckets.get(id);
5965
+ return bucket ? [bucket] : [];
5966
+ }),
5967
+ capturedAt: input.capturedAt,
5968
+ trigger: input.trigger
5969
+ };
5970
+ }
5971
+ function setStatic(buckets, id, reported, estimatedItems, reportedFidelity) {
5972
+ if (reported) buckets.set(id, reportBucket(id, reported, reportedFidelity));
5973
+ else if (estimatedItems) buckets.set(id, itemBucket(id, estimatedItems, "estimated"));
5974
+ else buckets.set(id, unknownBucket(id));
5975
+ }
5976
+ function reportBucket(id, reported, fidelity) {
5977
+ return {
5978
+ id,
5979
+ tokens: reported.tokens,
5980
+ fidelity,
5981
+ ...reported.items ? { items: reported.items } : {},
5982
+ ...reported.deferredTokens ? { deferredTokens: reported.deferredTokens } : {}
5983
+ };
5984
+ }
5985
+ function itemBucket(id, items, fidelity) {
5986
+ const deferred = sumTokens(items.filter((i) => i.deferred));
5987
+ return {
5988
+ id,
5989
+ tokens: sumTokens(items.filter((i) => !i.deferred)),
5990
+ fidelity,
5991
+ items,
5992
+ ...deferred > 0 ? { deferredTokens: deferred } : {}
5993
+ };
5994
+ }
5995
+ function unknownBucket(id) {
5996
+ return { id, tokens: 0, fidelity: "unknown" };
5997
+ }
5998
+ function fitEstimatesWithin(buckets, used, pinned) {
5999
+ const estimated = [...buckets.values()].filter(
6000
+ (b) => b.fidelity === "estimated" && !pinned.has(b.id)
6001
+ );
6002
+ const estimatedTotal = sumTokens(estimated);
6003
+ const fixedTotal = sumBuckets(buckets) - estimatedTotal;
6004
+ if (estimatedTotal === 0 || fixedTotal + estimatedTotal <= used) return;
6005
+ const budget = Math.max(0, used - fixedTotal);
6006
+ const shares = apportion(
6007
+ estimated.map((b) => b.tokens),
6008
+ budget
6009
+ );
6010
+ estimated.forEach((bucket, i) => {
6011
+ const target = shares[i] ?? 0;
6012
+ if (bucket.items) {
6013
+ const inWindow = bucket.items.filter((it) => !it.deferred);
6014
+ const itemShares = apportion(
6015
+ inWindow.map((it) => it.tokens),
6016
+ target
6017
+ );
6018
+ const scaled = new Map(inWindow.map((it, j) => [it, itemShares[j] ?? 0]));
6019
+ bucket.items = bucket.items.map(
6020
+ (it) => scaled.has(it) ? { ...it, tokens: scaled.get(it) ?? 0 } : it
6021
+ );
6022
+ }
6023
+ bucket.tokens = target;
6024
+ });
6025
+ }
6026
+ function absorbDrift(buckets, remaining, used) {
6027
+ const content = buckets.get("content");
6028
+ if (!content) return;
6029
+ content.tokens = Math.max(0, content.tokens + remaining);
6030
+ if (content.fidelity === "measured" && Math.abs(remaining) > used * MEASURED_DRIFT_TOLERANCE) {
6031
+ content.fidelity = "derived";
6032
+ delete content.items;
6033
+ }
6034
+ }
6035
+ function sumBuckets(buckets) {
6036
+ let total = 0;
6037
+ for (const b of buckets.values()) {
6038
+ if (b.id !== "free" && b.id !== "compaction-buffer") total += b.tokens;
6039
+ }
6040
+ return total;
6041
+ }
6042
+ function sumTokens(items) {
6043
+ return items.reduce((sum, i) => sum + i.tokens, 0);
6044
+ }
6045
+ function apportion(weights, total) {
6046
+ if (weights.length === 0) return [];
6047
+ const target = Math.max(0, Math.round(total));
6048
+ const weightSum = weights.reduce((sum, w) => sum + Math.max(0, w), 0);
6049
+ const raw = weights.map(
6050
+ (w) => weightSum > 0 ? Math.max(0, w) / weightSum * target : target / weights.length
6051
+ );
6052
+ const parts = raw.map(Math.floor);
6053
+ let leftover = target - parts.reduce((sum, p) => sum + p, 0);
6054
+ const byRemainder = raw.map((r, i) => ({ i, rem: r - Math.floor(r) })).sort((a, b) => b.rem - a.rem);
6055
+ for (const { i } of byRemainder) {
6056
+ if (leftover <= 0) break;
6057
+ parts[i] = (parts[i] ?? 0) + 1;
6058
+ leftover--;
6059
+ }
6060
+ return parts;
6061
+ }
6062
+
6063
+ // runner/src/context-usage/transcript-tracker.ts
6064
+ var USER = "User messages";
6065
+ var ASSISTANT = "Assistant messages";
6066
+ var SUMMARY = "Compaction summary";
6067
+ var TranscriptTokenTracker = class {
6068
+ constructor(estimator = defaultTokenEstimator) {
6069
+ this.estimator = estimator;
6070
+ }
6071
+ estimator;
6072
+ // Keyed by group and name, so a tool called "User messages" cannot merge into the user line.
6073
+ totals = /* @__PURE__ */ new Map();
6074
+ complete = false;
6075
+ /** Start over for a freshly built driver; `resuming` marks history we never saw. */
6076
+ reset(opts) {
6077
+ this.totals.clear();
6078
+ this.complete = !opts.resuming;
6079
+ }
6080
+ /** A compaction replaced the conversation with its summary. */
6081
+ resetToSummary(summary) {
6082
+ this.totals.clear();
6083
+ this.add(SUMMARY, "messages", this.estimator.text(summary));
6084
+ this.complete = true;
6085
+ }
6086
+ observeUserPrompt(text2) {
6087
+ this.add(USER, "messages", this.estimator.text(text2));
6088
+ }
6089
+ observe(event) {
6090
+ switch (event.type) {
6091
+ case "text":
6092
+ this.add(ASSISTANT, "messages", this.estimator.text(event.content));
6093
+ break;
6094
+ case "text_retract":
6095
+ this.add(ASSISTANT, "messages", -this.estimator.text(event.content));
6096
+ break;
6097
+ case "tool_call":
6098
+ if (event.parentToolUseId) return;
6099
+ this.add(event.tool, "tools", this.estimator.json(event.input));
6100
+ break;
6101
+ case "tool_result":
6102
+ if (event.parentToolUseId) return;
6103
+ this.add(
6104
+ event.tool,
6105
+ "tools",
6106
+ typeof event.output === "string" ? this.estimator.text(event.output) : this.estimator.json(event.output)
6107
+ );
6108
+ break;
6109
+ }
6110
+ }
6111
+ estimate() {
6112
+ const items = [...this.totals.values()].filter((v) => v.tokens > 0).map((v) => ({ name: v.name, tokens: v.tokens, group: v.group })).sort((a, b) => b.tokens - a.tokens);
6113
+ return {
6114
+ tokens: items.reduce((sum, i) => sum + i.tokens, 0),
6115
+ items,
6116
+ complete: this.complete
6117
+ };
6118
+ }
6119
+ add(name, group, tokens) {
6120
+ if (tokens === 0) return;
6121
+ const key = `${group}\0${name}`;
6122
+ const current = this.totals.get(key);
6123
+ this.totals.set(key, { name, group, tokens: Math.max(0, (current?.tokens ?? 0) + tokens) });
6124
+ }
6125
+ };
6126
+
6127
+ // runner/src/context-usage/collector.ts
6128
+ var DEFAULT_MEASURE_TIMEOUT_MS = 3e4;
6129
+ var SKILL_READ_TIMEOUT_MS = 5e3;
6130
+ var ContextUsageCollector = class {
6131
+ constructor(deps) {
6132
+ this.deps = deps;
6133
+ this.estimator = deps.estimator ?? defaultTokenEstimator;
6134
+ this.tracker = new TranscriptTokenTracker(this.estimator);
6135
+ }
6136
+ deps;
6137
+ tracker;
6138
+ estimator;
6139
+ lastReport = null;
6140
+ inflight = /* @__PURE__ */ new Map();
6141
+ skills = null;
6142
+ capabilityMemo = null;
6143
+ /** A driver was (re)built; everything measured or cached about the old one is void. */
6144
+ onDriverBuilt(opts) {
6145
+ this.tracker.reset(opts);
6146
+ this.lastReport = null;
6147
+ this.skills = null;
6148
+ this.inflight.clear();
6149
+ }
6150
+ onCompaction(summary) {
6151
+ this.tracker.resetToSummary(summary);
6152
+ }
6153
+ observeUserPrompt(text2) {
6154
+ this.tracker.observeUserPrompt(text2);
6155
+ }
6156
+ observeEvent(event) {
6157
+ this.tracker.observe(event);
6158
+ }
6159
+ async collect(opts) {
6160
+ try {
6161
+ return await this.collectUnsafe(opts);
6162
+ } catch (err) {
6163
+ return {
6164
+ snapshot: {
6165
+ provider: safeCall(() => this.deps.provider(), "unknown"),
6166
+ model: safeCall(() => this.deps.driver()?.getModel?.() ?? "", ""),
6167
+ contextWindow: null,
6168
+ usedTokens: 0,
6169
+ totalFidelity: "unknown",
6170
+ autoCompactAt: null,
6171
+ buckets: [],
6172
+ capturedAt: (this.deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
6173
+ trigger: opts.trigger
6174
+ },
6175
+ error: `context usage unavailable: ${err instanceof Error ? err.message : String(err)}`
6176
+ };
6177
+ }
6178
+ }
6179
+ async collectUnsafe(opts) {
6180
+ const driver = this.deps.driver();
6181
+ let error;
6182
+ let report = null;
6183
+ let reportFresh = false;
6184
+ if (opts.measure && driver?.getContextUsageReport) {
6185
+ try {
6186
+ const detail = opts.measure;
6187
+ const measure = driver.getContextUsageReport.bind(driver);
6188
+ report = await this.sharedMeasurement(detail, () => measure({ detail }));
6189
+ if (report) {
6190
+ this.lastReport = report;
6191
+ reportFresh = true;
6192
+ }
6193
+ } catch (err) {
6194
+ error = `measurement failed: ${err instanceof Error ? err.message : String(err)}`;
6195
+ }
6196
+ }
6197
+ report ??= this.lastReport;
6198
+ const model = driver?.getModel?.() ?? "";
6199
+ const usage = driver?.getTokenUsage() ?? null;
6200
+ const perCall = driver?.getContextTokens?.() ?? null;
6201
+ const fill = opts.trigger === "compaction" ? null : perCall ?? (usage ? contextTokens(usage) : null);
6202
+ const snapshot = composeContextUsageSnapshot({
6203
+ provider: this.deps.provider(),
6204
+ model,
6205
+ trigger: opts.trigger,
6206
+ capturedAt: (this.deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
6207
+ contextTokens: fill,
6208
+ contextWindow: driver ? reportedContextWindow(driver.getContextWindow(), model || null) : null,
6209
+ autoCompactAt: this.deps.autoCompactAt(),
6210
+ systemPromptSections: this.deps.systemPromptSections(),
6211
+ report,
6212
+ reportFresh,
6213
+ skills: report?.skills ? null : await this.skillItems(),
6214
+ mcpTools: report?.mcpTools ? null : this.capabilityItems(),
6215
+ content: this.tracker.estimate(),
6216
+ estimator: this.estimator
6217
+ });
6218
+ return error ? { snapshot, error } : { snapshot };
6219
+ }
6220
+ /**
6221
+ * One driver measurement per detail level at a time: a second request that
6222
+ * lands while a `full` count is running (two panels, a double click) shares
6223
+ * it instead of paying for another round of `count_tokens` calls.
6224
+ */
6225
+ sharedMeasurement(detail, measure) {
6226
+ const running = this.inflight.get(detail);
6227
+ if (running) return running;
6228
+ const measurement = withTimeout(
6229
+ measure(),
6230
+ this.deps.measureTimeoutMs ?? DEFAULT_MEASURE_TIMEOUT_MS
6231
+ ).finally(() => {
6232
+ if (this.inflight.get(detail) === measurement) this.inflight.delete(detail);
6233
+ });
6234
+ this.inflight.set(detail, measurement);
6235
+ return measurement;
6236
+ }
6237
+ skillItems() {
6238
+ this.skills ??= withTimeout(this.deps.readSkills(), SKILL_READ_TIMEOUT_MS).then(
6239
+ (skills) => skills.map((s) => ({
6240
+ name: s.name,
6241
+ tokens: this.estimator.text(s.frontmatter),
6242
+ ...s.source ? { source: s.source } : {}
6243
+ })),
6244
+ () => null
6245
+ );
6246
+ return this.skills;
6247
+ }
6248
+ capabilityItems() {
6249
+ const caps = this.deps.modelCapabilities();
6250
+ const key = caps.map((c) => c.name).join("\n");
6251
+ if (this.capabilityMemo?.key === key) return this.capabilityMemo.items;
6252
+ const items = caps.map((c) => ({
6253
+ name: c.name,
6254
+ tokens: this.estimator.text(c.name) + this.estimator.text(c.description) + this.estimator.json(c.inputSchema),
6255
+ group: capabilityGroup(c.origin)
6256
+ }));
6257
+ this.capabilityMemo = { key, items };
6258
+ return items;
6259
+ }
6260
+ };
6261
+ function capabilityGroup(origin) {
6262
+ switch (origin.kind) {
6263
+ case "mcp":
6264
+ return origin.serverId;
6265
+ case "connector":
6266
+ return origin.connectorId;
6267
+ case "mount":
6268
+ return origin.mountId;
6269
+ case "skill":
6270
+ return origin.skillId;
6271
+ case "flow":
6272
+ return origin.flowId;
6273
+ case "app":
6274
+ return origin.appId;
6275
+ default:
6276
+ return origin.kind;
6277
+ }
6278
+ }
6279
+ function safeCall(fn, fallback) {
6280
+ try {
6281
+ return fn();
6282
+ } catch {
6283
+ return fallback;
6284
+ }
6285
+ }
6286
+ function withTimeout(promise, ms) {
6287
+ let timer;
6288
+ const timeout2 = new Promise((_, reject) => {
6289
+ timer = setTimeout(() => reject(new Error(`timed out after ${ms} ms`)), ms);
6290
+ timer.unref?.();
6291
+ });
6292
+ return Promise.race([promise, timeout2]).finally(() => clearTimeout(timer));
6293
+ }
6294
+ var MAX_SKILLS = 500;
6295
+ async function readSkillListings(skillsDir) {
6296
+ let entries;
6297
+ try {
6298
+ entries = (await readdir(skillsDir, { withFileTypes: true })).filter((e) => e.isDirectory() || e.isSymbolicLink()).map((e) => e.name).slice(0, MAX_SKILLS);
6299
+ } catch {
6300
+ return [];
6301
+ }
6302
+ const listings = await Promise.all(
6303
+ entries.map(async (dir) => {
6304
+ const path6 = join(skillsDir, dir, "SKILL.md");
6305
+ try {
6306
+ const { data } = parseFrontmatter(await readFile(path6, "utf8"));
6307
+ const name = typeof data.name === "string" ? data.name : dir;
6308
+ const description = typeof data.description === "string" ? data.description : "";
6309
+ return { name, frontmatter: `${name}: ${description}`, source: path6 };
6310
+ } catch {
6311
+ return null;
6312
+ }
6313
+ })
6314
+ );
6315
+ return listings.filter((l) => l !== null);
6316
+ }
6317
+
5787
6318
  // runner/src/lifecycle-handler.ts
5788
6319
  function raiseHookFailures(phase, results, log) {
5789
6320
  const failed = results.filter((r) => !r.ok);
@@ -7650,6 +8181,19 @@ async function startAgentServer(opts) {
7650
8181
  });
7651
8182
  let sessionConfig;
7652
8183
  let agentSession;
8184
+ const contextUsage = new ContextUsageCollector({
8185
+ driver: () => driver,
8186
+ provider: () => agentSession?.driverType ?? "unknown",
8187
+ systemPromptSections: () => agentSession?.systemPromptSections ?? [],
8188
+ modelCapabilities: () => capabilityRegistry.list().filter(
8189
+ (cap) => (cap.audience ?? ["llm", "user"]).includes("llm") && !cap.name.startsWith("host.") && !cap.name.startsWith("runner.")
8190
+ ),
8191
+ readSkills: () => readSkillListings(join(opts.projectDir, activeSkillsDir())),
8192
+ autoCompactAt: () => compactionOrchestrator?.compactAtTokens() ?? null
8193
+ });
8194
+ function noteAgentSessionBuilt(resumeSessionId2) {
8195
+ contextUsage.onDriverBuilt({ resuming: !!resumeSessionId2 || !!managedCodex });
8196
+ }
7653
8197
  let flowToolsBaked = false;
7654
8198
  let secretProvider;
7655
8199
  let runtimeIdentity;
@@ -7729,6 +8273,7 @@ async function startAgentServer(opts) {
7729
8273
  sessionConfig = buildSessionConfig();
7730
8274
  agentSession = await createAgentSession(sessionConfig);
7731
8275
  emitSystemPromptComposed(agentSession, sendEvent);
8276
+ noteAgentSessionBuilt(sessionConfig.resumeSessionId);
7732
8277
  registerSessionComposition(agentSession);
7733
8278
  resolveSessionReady();
7734
8279
  captureBakedMcpServers();
@@ -7818,12 +8363,14 @@ async function startAgentServer(opts) {
7818
8363
  const normalizer = new EventNormalizer();
7819
8364
  function forwardNormalizedEvent(event) {
7820
8365
  if (compacting) return;
8366
+ contextUsage.observeEvent(event);
7821
8367
  const isTransient = event.type === "status" || event.type === "sync_status" || event.type === "resources_available" || event.type === "resource_response" || event.type === "commands_available";
7822
8368
  if (!isTransient) {
7823
8369
  eventSeq++;
7824
8370
  compactionOrchestrator?.trackMessage(eventSeq);
7825
8371
  }
7826
8372
  if (event.type === "finished") {
8373
+ scheduleContextUsageEmit("turn-end");
7827
8374
  if (!compacting && compactionOrchestrator?.shouldCompact()) {
7828
8375
  const compactionTimer = setTimeout(() => {
7829
8376
  if (compacting || !compactionOrchestrator?.shouldCompact()) return;
@@ -7894,6 +8441,16 @@ async function startAgentServer(opts) {
7894
8441
  let suppressedBy = null;
7895
8442
  let compactionOrchestrator = null;
7896
8443
  const compactionConfig = wsConfig.compaction;
8444
+ function scheduleContextUsageEmit(trigger) {
8445
+ const timer = setTimeout(() => {
8446
+ void contextUsage.collect({ trigger, measure: trigger === "turn-end" ? "summary" : false }).then(({ snapshot, error }) => {
8447
+ sendEvent({ type: "context_usage", snapshot, ...error ? { error } : {} });
8448
+ }).catch((err) => {
8449
+ serverLog.debug(`[serve] context_usage emit failed: ${String(err)}`);
8450
+ });
8451
+ }, 0);
8452
+ timer.unref?.();
8453
+ }
7897
8454
  function rebuildCompactionOrchestrator() {
7898
8455
  if (!driver) return;
7899
8456
  let gateHold = null;
@@ -7909,6 +8466,8 @@ async function startAgentServer(opts) {
7909
8466
  },
7910
8467
  onSnapshot: (snapshot) => {
7911
8468
  sendEvent(snapshot);
8469
+ contextUsage.onCompaction(snapshot.summary);
8470
+ scheduleContextUsageEmit("compaction");
7912
8471
  },
7913
8472
  onCompactionAttempt: (event) => {
7914
8473
  sendEvent(event);
@@ -8397,6 +8956,7 @@ async function startAgentServer(opts) {
8397
8956
  throw new Error("CODEX_RUNTIME_UNSUPPORTED");
8398
8957
  }
8399
8958
  emitSystemPromptComposed(agentSession, sendEvent);
8959
+ noteAgentSessionBuilt(sessionConfig.resumeSessionId);
8400
8960
  resourceManager = agentSession.resourceManager;
8401
8961
  driver = agentSession.driver;
8402
8962
  rebuildCompactionOrchestrator();
@@ -8471,6 +9031,7 @@ async function startAgentServer(opts) {
8471
9031
  resuming: !!overrides.resumeSessionId
8472
9032
  });
8473
9033
  emitSystemPromptComposed(agentSession, sendEvent);
9034
+ noteAgentSessionBuilt({ ...sessionConfig, ...overrides }.resumeSessionId);
8474
9035
  swapDriver();
8475
9036
  rebuildCompactionOrchestrator();
8476
9037
  captureBakedMcpServers();
@@ -9009,6 +9570,7 @@ async function startAgentServer(opts) {
9009
9570
  return;
9010
9571
  }
9011
9572
  log(`[serve] prompt: ${cmd.prompt.slice(0, 80)}...`);
9573
+ contextUsage.observeUserPrompt(cmd.prompt);
9012
9574
  await driverSwapGate.awaitSwap();
9013
9575
  if (!await awaitCompactionIdle("prompt")) return;
9014
9576
  await restageMaterializedSkills(true);
@@ -9250,6 +9812,22 @@ async function startAgentServer(opts) {
9250
9812
  }
9251
9813
  sendEvent({ type: "debug_result", query: cmd.query, data: result });
9252
9814
  }
9815
+ async function handleGetContextUsage(cmd) {
9816
+ try {
9817
+ await sessionReady;
9818
+ } catch {
9819
+ }
9820
+ const { snapshot, error } = await contextUsage.collect({
9821
+ trigger: "request",
9822
+ measure: cmd.detail === "estimated" ? "summary" : "full"
9823
+ });
9824
+ sendEvent({
9825
+ type: "context_usage",
9826
+ requestId: cmd.requestId,
9827
+ snapshot,
9828
+ ...error ? { error } : {}
9829
+ });
9830
+ }
9253
9831
  async function handleShutdown() {
9254
9832
  log("[serve] shutdown requested");
9255
9833
  await cleanup();
@@ -9370,6 +9948,9 @@ async function startAgentServer(opts) {
9370
9948
  case "debug":
9371
9949
  await handleDebug(cmd);
9372
9950
  break;
9951
+ case "get_context_usage":
9952
+ await handleGetContextUsage(cmd);
9953
+ break;
9373
9954
  // -----------------------------------------------------------------------
9374
9955
  // -----------------------------------------------------------------------
9375
9956
  // v3: add_resource, remove_resource, remount_mount, set_log_level,
@@ -9631,5 +10212,5 @@ function touchSession(state) {
9631
10212
  }
9632
10213
 
9633
10214
  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_STAT_BUDGET_MS, MOUNT_STAT_MAX_ENTRIES, MOUNT_TREE_OP_DEADLINE_FACTOR, MarkdownStreamer, PreInitRingSink, ResourceOperationError, SESSION_ROOT_WRITABLE_DIRS, SESSION_ROOT_WRITABLE_FILES, WS_AUTH_TOKEN_ENV, WS_AUTH_TOKEN_FILE_ENV, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, computeDirectoryTotals, 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, takeRunnerWsAuthToken, touchSession, validateInputResponse, writeClaudeCodeCredentialsFile };
9634
- //# sourceMappingURL=chunk-OFC725VA.js.map
9635
- //# sourceMappingURL=chunk-OFC725VA.js.map
10215
+ //# sourceMappingURL=chunk-ZJEQFNKE.js.map
10216
+ //# sourceMappingURL=chunk-ZJEQFNKE.js.map