@wrongstack/core 0.255.0 → 0.256.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/dist/{agent-bridge-l_DsFEbr.d.ts → agent-bridge-BrxWHEOm.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-DhYLgAJo.d.ts → agent-subagent-runner-US741uBH.d.ts} +17 -8
  3. package/dist/{brain-BaQsRNka.d.ts → brain-TjEEwSpw.d.ts} +1 -1
  4. package/dist/{compactor-BRfg3QPd.d.ts → compactor-C5sT4U7I.d.ts} +1 -1
  5. package/dist/{config-eSsrto5d.d.ts → config-DuAu23zm.d.ts} +16 -1
  6. package/dist/{context-CLz3z_E8.d.ts → context-CGdgA0q6.d.ts} +13 -0
  7. package/dist/coordination/index.d.ts +14 -14
  8. package/dist/coordination/index.js +21 -2
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +25 -25
  11. package/dist/defaults/index.js +238 -42
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +15 -15
  14. package/dist/execution/index.js +121 -22
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/execution/prompt-enhancer.d.ts +1 -1
  17. package/dist/extension/index.d.ts +6 -6
  18. package/dist/{goal-preamble-BgoPmZ8l.d.ts → goal-preamble-UiEkbNmW.d.ts} +21 -10
  19. package/dist/{index-BilZMsOK.d.ts → index-CC0Mcm05.d.ts} +9 -9
  20. package/dist/{index-Csoc_bKs.d.ts → index-CitPrI3a.d.ts} +20 -7
  21. package/dist/index.d.ts +112 -42
  22. package/dist/index.js +609 -111
  23. package/dist/index.js.map +1 -1
  24. package/dist/infrastructure/index.d.ts +6 -6
  25. package/dist/kernel/index.d.ts +10 -10
  26. package/dist/{llm-selector-D22R4AFz.d.ts → llm-selector-CJ4SyAFE.d.ts} +2 -2
  27. package/dist/{mcp-servers-DfXxCASH.d.ts → mcp-servers-D8YnLaEp.d.ts} +3 -3
  28. package/dist/models/index.d.ts +5 -5
  29. package/dist/{models-registry-DpanBg8D.d.ts → models-registry-ByZCdFuQ.d.ts} +1 -1
  30. package/dist/{multi-agent-coordinator-Bs-M0Mo6.d.ts → multi-agent-coordinator-DqTUEAeC.d.ts} +1 -1
  31. package/dist/{null-fleet-bus-CWdU1_cO.d.ts → null-fleet-bus-B5mfTJXT.d.ts} +17 -6
  32. package/dist/observability/index.d.ts +2 -2
  33. package/dist/{package-outdated-watcher-Dz-eNZlQ.d.ts → package-outdated-watcher-BSgR_kK-.d.ts} +3 -3
  34. package/dist/{parallel-eternal-engine-CAMabk-X.d.ts → parallel-eternal-engine-C0juOszP.d.ts} +24 -10
  35. package/dist/{path-resolver-B7VjhUHq.d.ts → path-resolver-CbkT-RMU.d.ts} +3 -3
  36. package/dist/{permission-DbWPbuoA.d.ts → permission-CwBBpCoF.d.ts} +1 -1
  37. package/dist/{permission-policy-AOk0LVsV.d.ts → permission-policy-B8rSu908.d.ts} +39 -2
  38. package/dist/{pipeline-Bxa3wDcy.d.ts → pipeline-JG8XoudC.d.ts} +2 -2
  39. package/dist/{plan-templates-D3guWwTi.d.ts → plan-templates-DPiQMkBz.d.ts} +5 -5
  40. package/dist/{provider-runner-C8_e4Lo1.d.ts → provider-runner-hM7EXlLI.d.ts} +3 -3
  41. package/dist/{retry-policy-BVnkbMET.d.ts → retry-policy-Tg7LXkoK.d.ts} +1 -1
  42. package/dist/sdd/index.d.ts +8 -8
  43. package/dist/{secret-vault-CeVNiy_f.d.ts → secret-vault-BkYkJWQs.d.ts} +1 -1
  44. package/dist/security/index.d.ts +4 -4
  45. package/dist/security/index.js +89 -18
  46. package/dist/security/index.js.map +1 -1
  47. package/dist/{selector-Cb4_9-hf.d.ts → selector-DWsqVjGf.d.ts} +1 -1
  48. package/dist/{session-event-bridge-BhtkkFFy.d.ts → session-event-bridge-BAFWdgQ3.d.ts} +1 -1
  49. package/dist/{session-reader-CCOssnBS.d.ts → session-reader-CqRvaL5v.d.ts} +1 -1
  50. package/dist/{skill-Bj6Ezqb8.d.ts → skill-DGIXCtdv.d.ts} +6 -0
  51. package/dist/skills/index.d.ts +1 -1
  52. package/dist/storage/index.d.ts +10 -10
  53. package/dist/storage/index.js +8 -1
  54. package/dist/storage/index.js.map +1 -1
  55. package/dist/types/index.d.ts +19 -19
  56. package/dist/types/index.js +83 -25
  57. package/dist/types/index.js.map +1 -1
  58. package/dist/utils/index.d.ts +2 -2
  59. package/dist/utils/index.js +3 -0
  60. package/dist/utils/index.js.map +1 -1
  61. package/package.json +1 -1
  62. package/skills/api-design/SKILL.md +1 -0
  63. package/skills/api-design/SKILL.save.md +26 -0
  64. package/skills/audit-log/SKILL.md +9 -2
  65. package/skills/audit-log/SKILL.save.md +22 -0
  66. package/skills/bug-hunter/SKILL.md +10 -2
  67. package/skills/bug-hunter/SKILL.save.md +33 -0
  68. package/skills/chimera/SKILL.md +12 -18
  69. package/skills/chimera/SKILL.save.md +26 -0
  70. package/skills/docker-deploy/SKILL.md +1 -0
  71. package/skills/docker-deploy/SKILL.save.md +23 -0
  72. package/skills/git-flow/SKILL.md +23 -2
  73. package/skills/git-flow/SKILL.save.md +25 -0
  74. package/skills/multi-agent/SKILL.md +23 -2
  75. package/skills/multi-agent/SKILL.save.md +26 -0
  76. package/skills/node-modern/SKILL.md +2 -1
  77. package/skills/node-modern/SKILL.save.md +21 -0
  78. package/skills/observability/SKILL.md +1 -0
  79. package/skills/observability/SKILL.save.md +34 -0
  80. package/skills/output-standards/SKILL.md +133 -0
  81. package/skills/output-standards/SKILL.save.md +21 -0
  82. package/skills/prompt-engineering/SKILL.md +2 -1
  83. package/skills/prompt-engineering/SKILL.save.md +29 -0
  84. package/skills/react-modern/SKILL.md +2 -1
  85. package/skills/react-modern/SKILL.save.md +24 -0
  86. package/skills/refactor-planner/SKILL.md +9 -2
  87. package/skills/refactor-planner/SKILL.save.md +26 -0
  88. package/skills/research-web/SKILL.md +1 -0
  89. package/skills/research-web/SKILL.save.md +25 -0
  90. package/skills/sdd/SKILL.md +2 -1
  91. package/skills/sdd/SKILL.save.md +19 -0
  92. package/skills/security-scanner/SKILL.md +10 -3
  93. package/skills/security-scanner/SKILL.save.md +23 -0
  94. package/skills/skill-creator/SKILL.md +2 -1
  95. package/skills/skill-creator/SKILL.save.md +20 -0
  96. package/skills/tech-stack/SKILL.md +13 -226
  97. package/skills/tech-stack/SKILL.save.md +25 -0
  98. package/skills/testing/SKILL.md +1 -0
  99. package/skills/testing/SKILL.save.md +22 -0
  100. package/skills/typescript-strict/SKILL.md +2 -1
  101. package/skills/typescript-strict/SKILL.save.md +19 -0
@@ -1,39 +1,39 @@
1
1
  export { D as DefaultLogger, a as DefaultLoggerOptions, L as LogFormat } from '../logger-DmmQhf4P.js';
2
- export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, k as MemoryStoreOptions, l as MigrationContext, m as MigrationResult, P as PersistedQueueItem, n as PlanFile, o as PlanItem, p as PlanTemplate, Q as QueueStore, R as RecoveryLock, q as RecoveryLockOptions, S as SessionAnalyzer, r as SessionStoreOptions, T as TodosCheckpointFile, s as addPlanItem, t as attachPlanCheckpoint, u as attachTodosCheckpoint, v as clearPlan, w as deriveTodosFromPlanItem, x as emptyPlan, y as formatPlan, z as formatPlanTemplates, B as getPlanTemplate, E as listPlanTemplates, G as loadPlan, H as loadTodosCheckpoint, K as removePlanItem, L as runConfigMigrations, N as savePlan, O as saveTodosCheckpoint, U as setPlanItemStatus } from '../plan-templates-D3guWwTi.js';
3
- export { D as DefaultSessionReader } from '../session-reader-CCOssnBS.js';
4
- export { A as AuditLevel, S as SessionEventBridge, b as SessionEventBridgeOptions, c as SessionSamplingOptions, T as ToolProgressSamplingOptions, d as createSessionEventBridge, r as resolveAuditLevel, e as resolveSessionLoggingConfig } from '../session-event-bridge-BhtkkFFy.js';
2
+ export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, k as MemoryStoreOptions, l as MigrationContext, m as MigrationResult, P as PersistedQueueItem, n as PlanFile, o as PlanItem, p as PlanTemplate, Q as QueueStore, R as RecoveryLock, q as RecoveryLockOptions, S as SessionAnalyzer, r as SessionStoreOptions, T as TodosCheckpointFile, s as addPlanItem, t as attachPlanCheckpoint, u as attachTodosCheckpoint, v as clearPlan, w as deriveTodosFromPlanItem, x as emptyPlan, y as formatPlan, z as formatPlanTemplates, B as getPlanTemplate, E as listPlanTemplates, G as loadPlan, H as loadTodosCheckpoint, K as removePlanItem, L as runConfigMigrations, N as savePlan, O as saveTodosCheckpoint, U as setPlanItemStatus } from '../plan-templates-DPiQMkBz.js';
3
+ export { D as DefaultSessionReader } from '../session-reader-CqRvaL5v.js';
4
+ export { A as AuditLevel, S as SessionEventBridge, b as SessionEventBridgeOptions, c as SessionSamplingOptions, T as ToolProgressSamplingOptions, d as createSessionEventBridge, r as resolveAuditLevel, e as resolveSessionLoggingConfig } from '../session-event-bridge-BAFWdgQ3.js';
5
5
  export { a as DirectorStateCheckpoint, D as DirectorStateSnapshot, b as DirectorSubagentState, c as DirectorTaskState, l as loadDirectorState } from '../director-state-BfeCUbmk.js';
6
- export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-vault-CeVNiy_f.js';
7
- export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-AOk0LVsV.js';
8
- export { C as CompactorOptions, a as DefaultErrorHandler, b as DefaultRetryPolicy, E as EternalAutonomyEngine, c as EternalAutonomyOptions, d as EternalEngineState, H as HybridCompactor, I as IterationStage, P as ParallelEngineState, e as ParallelEternalEngine, f as ParallelEternalOptions, g as ParallelIterationStage, T as ToolExecutor } from '../parallel-eternal-engine-CAMabk-X.js';
9
- export { A as AutoCompactionMiddleware, a as AutonomousRunner, b as AutonomousRunnerOptions, c as AutonomyPromptContributorOptions, C as CompactorStrategy, D as DefaultSkillLoader, d as DoneCheckResult, e as DoneConditionChecker, I as IntelligentCompactor, f as IntelligentCompactorOptions, S as SelectiveCompactor, g as SelectiveCompactorOptions, h as SkillLoaderOptions, i as StrategyCompactorOptions, j as buildGoalPreamble, k as createStrategyCompactor, m as makeAutonomyPromptContributor } from '../goal-preamble-BgoPmZ8l.js';
10
- import { P as ProviderRunner, R as RunProviderOptions } from '../provider-runner-C8_e4Lo1.js';
11
- import { b as Response } from '../context-CLz3z_E8.js';
12
- export { a as AGENTS_BY_PHASE, b as AGENT_CATALOG, c as ALL_AGENT_DEFINITIONS, d as ALL_FLEET_AGENTS, e as AUDIT_LOG_AGENT, f as AutoExtendCeiling, g as AutoExtendPolicy, B as BUG_HUNTER_AGENT, n as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, q as DEFAULT_SUBAGENT_BASELINE, r as DelegateHost, s as Director, w as DirectorPromptParts, x as DirectorSessionFactory, y as DirectorSessionFactoryOptions, F as FLEET_ROSTER, z as FLEET_ROSTER_BUDGETS, J as FleetRosterBudget, K as FleetSpawnBudgetError, L as ICoordinator, M as IFleetManager, O as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, V as SubagentPromptParts, W as applyRosterBudget, X as attachAutoExtend, Y as composeDirectorPrompt, Z as composeSubagentPrompt, _ as createDelegateTool, $ as getAgentDefinition, a1 as makeAskTool, a2 as makeAssignTool, a3 as makeAwaitTasksTool, a4 as makeCollabDebugTool, a5 as makeDirectorSessionFactory, a6 as makeFleetEmitTool, a7 as makeFleetHealthTool, a8 as makeFleetSessionTool, a9 as makeFleetStatusTool, aa as makeFleetUsageTool, ab as makeRollUpTool, ac as makeSpawnTool, ad as makeTerminateTool, af as rosterSummaryFromConfigs } from '../null-fleet-bus-CWdU1_cO.js';
13
- export { b as AgentBudgetTier, c as AgentCapability, A as AgentDefinition, d as AgentPhase, e as DEFAULT_DISPATCH_ROLE, a as DefaultMultiAgentCoordinator, f as DispatchCandidate, D as DispatchClassifier, g as DispatchMethod, h as DispatchOptions, i as DispatchResult, j as MultiAgentCoordinatorOptions, k as dispatchAgent, m as makeLLMClassifier, s as scoreAgents } from '../multi-agent-coordinator-Bs-M0Mo6.js';
14
- export { h as AgentFactory, i as AgentFactoryResult, j as AgentRunnerOptions, k as BudgetExceededError, l as BudgetKind, m as BudgetLimits, r as BudgetUsage, F as FleetBus, s as FleetEvent, t as FleetHandler, u as FleetUsage, v as FleetUsageAggregator, w as SubagentBudget, x as SubagentUsageSnapshot, y as makeAgentSubagentRunner } from '../agent-subagent-runner-DhYLgAJo.js';
15
- export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-l_DsFEbr.js';
16
- export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-DpanBg8D.js';
17
- export { D as DefaultModeStore, L as LLMSelector, a as LLMSelectorOptions, M as ModeLoaderOptions, l as loadProjectModes, b as loadUserModes } from '../llm-selector-D22R4AFz.js';
6
+ export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-vault-BkYkJWQs.js';
7
+ export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-B8rSu908.js';
8
+ export { C as CompactorOptions, a as DefaultErrorHandler, b as DefaultRetryPolicy, E as EternalAutonomyEngine, c as EternalAutonomyOptions, d as EternalEngineState, H as HybridCompactor, I as IterationStage, P as ParallelEngineState, e as ParallelEternalEngine, f as ParallelEternalOptions, g as ParallelIterationStage, T as ToolExecutor } from '../parallel-eternal-engine-C0juOszP.js';
9
+ export { A as AutoCompactionMiddleware, a as AutonomousRunner, b as AutonomousRunnerOptions, c as AutonomyPromptContributorOptions, C as CompactorStrategy, D as DefaultSkillLoader, d as DoneCheckResult, e as DoneConditionChecker, I as IntelligentCompactor, f as IntelligentCompactorOptions, S as SelectiveCompactor, g as SelectiveCompactorOptions, h as SkillLoaderOptions, i as StrategyCompactorOptions, j as buildGoalPreamble, k as createStrategyCompactor, m as makeAutonomyPromptContributor } from '../goal-preamble-UiEkbNmW.js';
10
+ import { P as ProviderRunner, R as RunProviderOptions } from '../provider-runner-hM7EXlLI.js';
11
+ import { b as Response } from '../context-CGdgA0q6.js';
12
+ export { a as AGENTS_BY_PHASE, b as AGENT_CATALOG, c as ALL_AGENT_DEFINITIONS, d as ALL_FLEET_AGENTS, e as AUDIT_LOG_AGENT, f as AutoExtendCeiling, g as AutoExtendPolicy, B as BUG_HUNTER_AGENT, n as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, q as DEFAULT_SUBAGENT_BASELINE, r as DelegateHost, s as Director, w as DirectorPromptParts, x as DirectorSessionFactory, y as DirectorSessionFactoryOptions, F as FLEET_ROSTER, z as FLEET_ROSTER_BUDGETS, J as FleetRosterBudget, K as FleetSpawnBudgetError, L as ICoordinator, M as IFleetManager, O as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, V as SubagentPromptParts, W as applyRosterBudget, X as attachAutoExtend, Y as composeDirectorPrompt, Z as composeSubagentPrompt, _ as createDelegateTool, $ as getAgentDefinition, a1 as makeAskTool, a2 as makeAssignTool, a3 as makeAwaitTasksTool, a4 as makeCollabDebugTool, a5 as makeDirectorSessionFactory, a6 as makeFleetEmitTool, a7 as makeFleetHealthTool, a8 as makeFleetSessionTool, a9 as makeFleetStatusTool, aa as makeFleetUsageTool, ab as makeRollUpTool, ac as makeSpawnTool, ad as makeTerminateTool, af as rosterSummaryFromConfigs } from '../null-fleet-bus-B5mfTJXT.js';
13
+ export { b as AgentBudgetTier, c as AgentCapability, A as AgentDefinition, d as AgentPhase, e as DEFAULT_DISPATCH_ROLE, a as DefaultMultiAgentCoordinator, f as DispatchCandidate, D as DispatchClassifier, g as DispatchMethod, h as DispatchOptions, i as DispatchResult, j as MultiAgentCoordinatorOptions, k as dispatchAgent, m as makeLLMClassifier, s as scoreAgents } from '../multi-agent-coordinator-DqTUEAeC.js';
14
+ export { h as AgentFactory, i as AgentFactoryResult, j as AgentRunnerOptions, k as BudgetExceededError, l as BudgetKind, m as BudgetLimits, r as BudgetUsage, F as FleetBus, s as FleetEvent, t as FleetHandler, u as FleetUsage, v as FleetUsageAggregator, w as SubagentBudget, x as SubagentUsageSnapshot, y as makeAgentSubagentRunner } from '../agent-subagent-runner-US741uBH.js';
15
+ export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-BrxWHEOm.js';
16
+ export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-ByZCdFuQ.js';
17
+ export { D as DefaultModeStore, L as LLMSelector, a as LLMSelectorOptions, M as ModeLoaderOptions, l as loadProjectModes, b as loadUserModes } from '../llm-selector-CJ4SyAFE.js';
18
18
  export { AISpecBuilder, AISpecBuilderOptions, AISpecPhase, AISpecSession, AutoExecutor, AutoExecutorOptions, BottleneckTask, CollectedAnswer, CriticalPathAnalysis, DefaultTaskStore, ExecutionSummary, GeneratedTask, RunResult, SPEC_TEMPLATES, SddParallelRun, SddParallelRunOptions, SddProgress, SddTaskDecomposer, SddTaskDecomposerOptions, SpecDiff, SpecDrivenDev, SpecDrivenDevOptions, SpecIndexEntry, SpecParser, SpecStore, SpecStoreOptions, SpecVersion, SpecVersioning, TaskBatch, TaskExecutionContext, TaskExecutionResult, TaskFlow, TaskFlowEventMap, TaskFlowEventName, TaskFlowExecutionContext, TaskFlowOptions, TaskFlowPhase, TaskGenerator, TaskGeneratorOptions, TaskGraphIndexEntry, TaskGraphStore, TaskGraphStoreOptions, TaskStore, TaskTracker, TaskTrackerOptions, TaskTransition, WaveResult, analyzeCriticalPath, createAutoExecutor, getTemplate, listTemplates, renderProgress, renderSpecAnalysis, renderTaskGraph, renderTaskList, templateToMarkdown } from '../sdd/index.js';
19
19
  export { DefaultHealthRegistry, InMemoryMetricsSink, MetricsServerHandle, MetricsServerOptions, NoopMetricsSink, NoopTracer, OTelTracer, OtlpMetricsExporterHandle, OtlpMetricsExporterOptions, OtlpTraceExporterHandle, OtlpTraceExporterOptions, PROMETHEUS_CONTENT_TYPE, buildOtlpMetricsRequest, buildOtlpTracesRequest, renderPrometheus, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, wireMetricsToEvents } from '../observability/index.js';
20
- export { C as ContextManagerAction, a as ContextManagerInput, b as ContextManagerResult, c as ContextManagerToolOptions, d as allServers, e as awsServer, f as blockServer, g as braveSearchServer, h as context7Server, i as contextManagerTool, j as createContextManagerTool, k as everArtServer, l as filesystemServer, m as githubServer, n as googleMapsServer, o as miniMaxVisionServer, s as sentinelServer, q as slackServer, z as zaiVisionServer } from '../mcp-servers-DfXxCASH.js';
20
+ export { C as ContextManagerAction, a as ContextManagerInput, b as ContextManagerResult, c as ContextManagerToolOptions, d as allServers, e as awsServer, f as blockServer, g as braveSearchServer, h as context7Server, i as contextManagerTool, j as createContextManagerTool, k as everArtServer, l as filesystemServer, m as githubServer, n as googleMapsServer, o as miniMaxVisionServer, s as sentinelServer, q as slackServer, z as zaiVisionServer } from '../mcp-servers-D8YnLaEp.js';
21
21
  export { D as DEFAULT_AUTONOMY_CONFIG, a as DEFAULT_CONTEXT_CONFIG, d as DEFAULT_TOOLS_CONFIG } from '../default-config-CXsDvOmP.js';
22
22
  import '../logger-B63L5bTg.js';
23
- import '../brain-BaQsRNka.js';
24
- import '../permission-DbWPbuoA.js';
23
+ import '../brain-TjEEwSpw.js';
24
+ import '../permission-CwBBpCoF.js';
25
25
  import '../wstack-paths-CJjEwPXn.js';
26
- import '../config-eSsrto5d.js';
26
+ import '../config-DuAu23zm.js';
27
27
  import '../secret-vault-BJDY28ev.js';
28
28
  import '../input-reader-E-ffP2ee.js';
29
- import '../retry-policy-BVnkbMET.js';
30
- import '../compactor-BRfg3QPd.js';
31
- import '../index-Csoc_bKs.js';
32
- import '../pipeline-Bxa3wDcy.js';
29
+ import '../retry-policy-Tg7LXkoK.js';
30
+ import '../compactor-C5sT4U7I.js';
31
+ import '../index-CitPrI3a.js';
32
+ import '../pipeline-JG8XoudC.js';
33
33
  import '../observability-D-HZN_mF.js';
34
34
  import '../goal-store-CV9Yz2X_.js';
35
- import '../skill-Bj6Ezqb8.js';
36
- import '../selector-Cb4_9-hf.js';
35
+ import '../skill-DGIXCtdv.js';
36
+ import '../selector-DWsqVjGf.js';
37
37
  import 'node:events';
38
38
  import '../mode-CZlO9iU1.js';
39
39
  import '../spec-TBi3Jr6T.js';
@@ -4366,9 +4366,28 @@ var PATTERNS = [
4366
4366
  }
4367
4367
  ];
4368
4368
  var SCRUB_CHUNK_BYTES = 64 * 1024;
4369
+ function hasCredentialAnchors(text) {
4370
+ return text.includes("-----BEGIN") || // Private keys (most unique → cheap reject)
4371
+ text.includes("sk-") || // Anthropic + OpenAI keys
4372
+ text.includes("sk_") || // Stripe live/test keys
4373
+ text.includes("ghp_") || // GitHub PAT v1
4374
+ text.includes("github_pat_") || // GitHub PAT v2
4375
+ text.includes("eyJ") || // JWT
4376
+ text.includes("AKIA") || // AWS access key
4377
+ text.includes("AIza") || // GCP service key
4378
+ text.includes("xox") || // Slack token (xoxa/xoxb/xoxp/xoxo/xoxs)
4379
+ text.includes("Bearer ") || // Bearer token (space suffix reduces false positives)
4380
+ text.includes("/bot") || // Telegram bot token (URL path pattern)
4381
+ text.includes("_KEY=") || // High-entropy env vars: API_KEY=, SECRET_KEY=, ...
4382
+ text.includes("_TOKEN=") || // ACCESS_TOKEN=, AUTH_TOKEN=, ...
4383
+ text.includes("_SECRET=") || // API_SECRET=, CLIENT_SECRET=, ...
4384
+ text.includes("_PASSWORD=") || // DB_PASSWORD=, ROOT_PASSWORD=, ...
4385
+ text.includes("mongodb://") || text.includes("mongodb+srv://") || text.includes("postgres://") || text.includes("postgresql://") || text.includes("mysql://") || text.includes("redis://");
4386
+ }
4369
4387
  var DefaultSecretScrubber = class {
4370
4388
  scrub(text) {
4371
4389
  if (!text) return text;
4390
+ if (!hasCredentialAnchors(text)) return text;
4372
4391
  if (text.length <= SCRUB_CHUNK_BYTES) {
4373
4392
  return this.scrubOne(text);
4374
4393
  }
@@ -4386,6 +4405,7 @@ var DefaultSecretScrubber = class {
4386
4405
  return out.join("");
4387
4406
  }
4388
4407
  scrubOne(text) {
4408
+ if (!hasCredentialAnchors(text)) return text;
4389
4409
  let out = text;
4390
4410
  for (const p of PATTERNS) {
4391
4411
  out = out.replace(p.regex, (_match, group1, group2) => {
@@ -4421,10 +4441,14 @@ var ToolCapabilities = {
4421
4441
  SHELL_ARBITRARY: "shell.arbitrary",
4422
4442
  /** Can execute a restricted set of commands (the `exec` tool). */
4423
4443
  SHELL_RESTRICTED: "shell.restricted",
4444
+ /** Can read files inside the project (and possibly outside via symlinks if not guarded). */
4445
+ FS_READ: "fs.read",
4424
4446
  /** Can write / modify / delete files inside the project. */
4425
4447
  FS_WRITE: "fs.write",
4426
4448
  /** Can write files outside the current project root (very high risk). */
4427
4449
  FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project",
4450
+ /** Can perform outbound network requests. */
4451
+ NET_OUTBOUND: "net.outbound",
4428
4452
  /** Proxies tools from external MCP servers (unknown capability). */
4429
4453
  MCP_PROXY: "mcp.proxy",
4430
4454
  /** Can spawn or manage subagents / multi-agent tasks. */
@@ -4657,6 +4681,21 @@ var DefaultPermissionPolicy = class {
4657
4681
  promptDelegate;
4658
4682
  /** Pre-compiled wildcard patterns — rebuilt on reload for O(1) lookup. */
4659
4683
  wildcardEntries = [];
4684
+ /**
4685
+ * Evaluate-result cache. Keyed by `tool.name::subject` so repeated calls
4686
+ * with the same tool+input skip namespace matching, subject computation,
4687
+ * pattern matching (matchAny), and YOLO destructive gating.
4688
+ *
4689
+ * Cleared on any state change (reload, trust, deny, yolo toggle) because
4690
+ * the result depends on the full policy state. The write-tool smart-bypass
4691
+ * (step 7 in `evaluate()`) is not cached since `ctx.hasRead()` changes
4692
+ * dynamically within a session.
4693
+ *
4694
+ * LRU eviction is not needed — the cache is cleared on state changes
4695
+ * that are rare (trust file ops, user confirm) and the number of unique
4696
+ * tool+subject pairs per iteration is small (<50).
4697
+ */
4698
+ _evalCache = /* @__PURE__ */ new Map();
4660
4699
  constructor(opts) {
4661
4700
  this.trustFile = opts.trustFile;
4662
4701
  this.yolo = opts.yolo ?? false;
@@ -4675,6 +4714,7 @@ var DefaultPermissionPolicy = class {
4675
4714
  }
4676
4715
  /** Toggle YOLO (auto-approve) mode at runtime. */
4677
4716
  setYolo(enabled) {
4717
+ if (this.yolo !== enabled) this._evalCache.clear();
4678
4718
  this.yolo = enabled;
4679
4719
  }
4680
4720
  /** Check whether YOLO mode is currently active. */
@@ -4683,6 +4723,7 @@ var DefaultPermissionPolicy = class {
4683
4723
  }
4684
4724
  /** Toggle the destructive YOLO override at runtime. */
4685
4725
  setYoloDestructive(enabled) {
4726
+ if (this.yoloDestructive !== enabled) this._evalCache.clear();
4686
4727
  this.yoloDestructive = enabled;
4687
4728
  }
4688
4729
  /** Check whether the destructive YOLO override is active. */
@@ -4691,6 +4732,7 @@ var DefaultPermissionPolicy = class {
4691
4732
  }
4692
4733
  /** Toggle destructive confirmation gate (only meaningful when yolo is active). */
4693
4734
  setConfirmDestructive(enabled) {
4735
+ if (this.confirmDestructive !== enabled) this._evalCache.clear();
4694
4736
  this.confirmDestructive = enabled;
4695
4737
  }
4696
4738
  /** Check whether destructive confirmation gate is active. */
@@ -4711,6 +4753,7 @@ var DefaultPermissionPolicy = class {
4711
4753
  }
4712
4754
  this.sessionDenied.clear();
4713
4755
  this.sessionAllowed.clear();
4756
+ this._evalCache.clear();
4714
4757
  this.loaded = true;
4715
4758
  }
4716
4759
  async evaluate(tool, input, ctx) {
@@ -4718,44 +4761,60 @@ var DefaultPermissionPolicy = class {
4718
4761
  const namespaceEntry = this.findNamespaceEntry(tool.name);
4719
4762
  const entry = this.policy[tool.name] ?? namespaceEntry;
4720
4763
  const subject = this.subjectFor(tool.name, input, tool.subjectKey);
4721
- const subjectKey = `${tool.name}::${subject ?? tool.name}`;
4722
- if (this.sessionDenied.has(subjectKey)) {
4723
- return { permission: "deny", source: "deny", reason: "session soft deny (user pressed no)" };
4764
+ const cacheKey = `${tool.name}::${subject ?? tool.name}`;
4765
+ if (tool.name !== "write") {
4766
+ const cached = this._evalCache.get(cacheKey);
4767
+ if (cached !== void 0) return cached;
4768
+ }
4769
+ if (this.sessionDenied.has(cacheKey)) {
4770
+ const decision = { permission: "deny", source: "deny", reason: "session soft deny (user pressed no)" };
4771
+ this._evalCache.set(cacheKey, decision);
4772
+ return decision;
4724
4773
  }
4725
- if (this.sessionAllowed.has(subjectKey)) {
4726
- return {
4774
+ if (this.sessionAllowed.has(cacheKey)) {
4775
+ const decision = {
4727
4776
  permission: "auto",
4728
4777
  source: "trust",
4729
4778
  reason: "session soft allow (user pressed yes)"
4730
4779
  };
4780
+ this._evalCache.set(cacheKey, decision);
4781
+ return decision;
4731
4782
  }
4732
4783
  if (entry?.deny && subject && matchAny(entry.deny, subject)) {
4733
- return { permission: "deny", source: "deny", reason: "matched deny pattern" };
4784
+ const decision = { permission: "deny", source: "deny", reason: "matched deny pattern" };
4785
+ this._evalCache.set(cacheKey, decision);
4786
+ return decision;
4734
4787
  }
4735
4788
  if (tool.permission === "deny") {
4736
- return { permission: "deny", source: "default", reason: "tool default deny" };
4789
+ const decision = { permission: "deny", source: "default", reason: "tool default deny" };
4790
+ this._evalCache.set(cacheKey, decision);
4791
+ return decision;
4737
4792
  }
4738
4793
  if (entry?.allow && subject && matchAny(entry.allow, subject)) {
4739
- return { permission: "auto", source: "trust", reason: "matched allow pattern" };
4794
+ const decision = { permission: "auto", source: "trust", reason: "matched allow pattern" };
4795
+ this._evalCache.set(cacheKey, decision);
4796
+ return decision;
4740
4797
  }
4741
4798
  if (entry?.auto) {
4742
- return { permission: "auto", source: "trust" };
4799
+ const decision = { permission: "auto", source: "trust" };
4800
+ this._evalCache.set(cacheKey, decision);
4801
+ return decision;
4743
4802
  }
4744
4803
  if (this.yolo) {
4745
4804
  if (this.confirmDestructive) {
4746
4805
  const destructive = this.isDestructiveYoloCall(tool, input, ctx);
4747
4806
  if (destructive) {
4748
4807
  if (this.promptDelegate) {
4749
- const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
4750
- if (decision === "always") {
4808
+ const decision2 = await this.promptDelegate(tool, input, subject ?? tool.name);
4809
+ if (decision2 === "always") {
4751
4810
  await this.trust({ tool: tool.name, pattern: subject ?? tool.name });
4752
4811
  return { permission: "auto", source: "user", reason: "destructive yolo always-allowed" };
4753
4812
  }
4754
- if (decision === "deny") {
4813
+ if (decision2 === "deny") {
4755
4814
  await this.deny({ tool: tool.name, pattern: subject ?? tool.name });
4756
4815
  return { permission: "deny", source: "user", reason: "user denied destructive yolo" };
4757
4816
  }
4758
- return { permission: decision === "yes" ? "auto" : "deny", source: "user" };
4817
+ return { permission: decision2 === "yes" ? "auto" : "deny", source: "user" };
4759
4818
  }
4760
4819
  return {
4761
4820
  permission: "confirm",
@@ -4765,7 +4824,9 @@ var DefaultPermissionPolicy = class {
4765
4824
  };
4766
4825
  }
4767
4826
  }
4768
- return { permission: "auto", source: "yolo" };
4827
+ const decision = { permission: "auto", source: "yolo" };
4828
+ this._evalCache.set(cacheKey, decision);
4829
+ return decision;
4769
4830
  }
4770
4831
  if (tool.name === "write" && subject) {
4771
4832
  if (ctx.hasRead(subject)) {
@@ -4777,7 +4838,9 @@ var DefaultPermissionPolicy = class {
4777
4838
  }
4778
4839
  }
4779
4840
  if (tool.permission === "auto" && !tool.mutating) {
4780
- return { permission: "auto", source: "default" };
4841
+ const decision = { permission: "auto", source: "default" };
4842
+ this._evalCache.set(cacheKey, decision);
4843
+ return decision;
4781
4844
  }
4782
4845
  if (this.promptDelegate) {
4783
4846
  const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
@@ -4810,6 +4873,7 @@ var DefaultPermissionPolicy = class {
4810
4873
  const entry = this.policy[rule.tool] ?? {};
4811
4874
  entry.allow = Array.from(/* @__PURE__ */ new Set([...entry.allow ?? [], rule.pattern]));
4812
4875
  this.policy[rule.tool] = entry;
4876
+ this._evalCache.clear();
4813
4877
  try {
4814
4878
  await atomicWrite(this.trustFile, JSON.stringify(this.policy, null, 2));
4815
4879
  } catch (err) {
@@ -4827,6 +4891,7 @@ var DefaultPermissionPolicy = class {
4827
4891
  const entry = this.policy[rule.tool] ?? {};
4828
4892
  entry.deny = Array.from(/* @__PURE__ */ new Set([...entry.deny ?? [], rule.pattern]));
4829
4893
  this.policy[rule.tool] = entry;
4894
+ this._evalCache.clear();
4830
4895
  try {
4831
4896
  await atomicWrite(this.trustFile, JSON.stringify(this.policy, null, 2));
4832
4897
  } catch (err) {
@@ -4841,10 +4906,12 @@ var DefaultPermissionPolicy = class {
4841
4906
  /** Block this tool+pattern for the rest of this session (no trust file). */
4842
4907
  denyOnce(rule) {
4843
4908
  this.sessionDenied.set(`${rule.tool}::${rule.pattern}`, true);
4909
+ this._evalCache.clear();
4844
4910
  }
4845
4911
  /** Auto-approve this tool+pattern for the rest of this session (no trust file). */
4846
4912
  allowOnce(rule) {
4847
4913
  this.sessionAllowed.set(`${rule.tool}::${rule.pattern}`, true);
4914
+ this._evalCache.clear();
4848
4915
  }
4849
4916
  subjectFor(toolName, input, subjectKey) {
4850
4917
  if (!input || typeof input !== "object") return void 0;
@@ -4880,15 +4947,23 @@ var DefaultPermissionPolicy = class {
4880
4947
  }
4881
4948
  };
4882
4949
  var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
4950
+ allowedCapabilities;
4951
+ constructor(allowedCapabilities) {
4952
+ this.allowedCapabilities = allowedCapabilities ?? [
4953
+ ToolCapabilities.FS_READ,
4954
+ ToolCapabilities.NET_OUTBOUND
4955
+ ];
4956
+ }
4883
4957
  static isMcpTool(name) {
4884
4958
  return name.startsWith("mcp__");
4885
4959
  }
4886
4960
  async evaluate(tool) {
4887
- const hasDangerousCap = hasDangerousCapabilityForSubagents(tool);
4961
+ const caps = tool.capabilities ?? [];
4962
+ const hasAllowedCap = caps.some((c) => this.allowedCapabilities.includes(c));
4888
4963
  const isMcp = _AutoApprovePermissionPolicy.isMcpTool(tool.name);
4889
- const blocked = tool.permission === "deny" || hasDangerousCap || isMcp;
4964
+ const blocked = tool.permission === "deny" || isMcp || !hasAllowedCap;
4890
4965
  if (blocked) {
4891
- const reason = hasDangerousCap ? `tool declares dangerous capability (${tool.capabilities?.join(", ")}) \u2014 not auto-approved for subagents` : isMcp ? `MCP tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow it explicitly` : "tool default deny";
4966
+ const reason = isMcp ? `MCP tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow it explicitly` : tool.permission === "deny" ? "tool default deny" : `tool lacks allowed capability (has: ${caps.join(", ") || "none"}, allowed: ${this.allowedCapabilities.join(", ")})`;
4892
4967
  return {
4893
4968
  permission: "deny",
4894
4969
  source: "subagent_guard",
@@ -5101,6 +5176,35 @@ var DefaultErrorHandler = class {
5101
5176
  return null;
5102
5177
  }
5103
5178
  };
5179
+ function stripFrontmatter(raw) {
5180
+ if (!raw.startsWith("---")) return raw;
5181
+ const end = raw.indexOf("\n---", 4);
5182
+ if (end === -1) return raw;
5183
+ let body = raw.slice(end + 4);
5184
+ if (body.startsWith("\n")) body = body.slice(1);
5185
+ return body;
5186
+ }
5187
+ function compactSkillBody(body) {
5188
+ const sections = [];
5189
+ const overviewMatch = body.match(/##\s*Overview\s*\n([\s\S]*?)(?=\n##|\n$|$)/i);
5190
+ const overview = overviewMatch?.[1];
5191
+ if (overview?.trim()) {
5192
+ sections.push(overview.trim().slice(0, 200));
5193
+ }
5194
+ const rulesMatch = body.match(/##\s*Rules\s*\n([\s\S]*?)(?=\n##|\n$|$)/i);
5195
+ const rules = rulesMatch?.[1];
5196
+ if (rules?.trim()) {
5197
+ const trimmed = rules.trim().slice(0, 350);
5198
+ const ruleLines = trimmed.split("\n").filter((l) => /^\s*[-*]\s/.test(l) || /^\s*\d+[.)]\s/.test(l)).slice(0, 6).join("\n");
5199
+ if (ruleLines) sections.push(ruleLines);
5200
+ }
5201
+ if (sections.length === 0) {
5202
+ const first = body.trim().slice(0, 200);
5203
+ if (first) sections.push(first);
5204
+ }
5205
+ const result = sections.join("\n\n");
5206
+ return result.length > 450 ? result.slice(0, 447) + "\u2026" : result;
5207
+ }
5104
5208
  var DefaultSkillLoader = class {
5105
5209
  dirs;
5106
5210
  cache;
@@ -5182,6 +5286,24 @@ var DefaultSkillLoader = class {
5182
5286
  if (!m) throw new Error(`Skill "${name}" not found`);
5183
5287
  return fsp.readFile(m.path, "utf8");
5184
5288
  }
5289
+ async readSaveBody(name) {
5290
+ const m = await this.find(name);
5291
+ if (!m) throw new Error(`Skill "${name}" not found`);
5292
+ const savePath = path11.join(path11.dirname(m.path), "SKILL.save.md");
5293
+ try {
5294
+ return await fsp.readFile(savePath, "utf8");
5295
+ } catch {
5296
+ const full = await fsp.readFile(m.path, "utf8");
5297
+ const body = stripFrontmatter(full);
5298
+ const compact = compactSkillBody(body);
5299
+ if (compact) {
5300
+ return `## Overview
5301
+
5302
+ ${compact}`;
5303
+ }
5304
+ return body.trim().slice(0, 300);
5305
+ }
5306
+ }
5185
5307
  };
5186
5308
  function parseFrontmatter(raw) {
5187
5309
  if (!raw.startsWith("---")) return {};
@@ -5237,6 +5359,9 @@ function parseDescription(raw) {
5237
5359
  function completePartialObject(s) {
5238
5360
  if (!s.trim().startsWith("{")) return s;
5239
5361
  if (tryParse(s).ok) return s;
5362
+ return repairTruncated(s);
5363
+ }
5364
+ function repairTruncated(s) {
5240
5365
  const stack = [];
5241
5366
  let inString = false;
5242
5367
  let escaped = false;
@@ -5833,6 +5958,14 @@ function estimateRequestTokens(messages, systemPrompt, tools, calibrationKey = C
5833
5958
  total
5834
5959
  };
5835
5960
  }
5961
+ function getCalibrationState(calibrationKey = CALIBRATION_GLOBAL_KEY) {
5962
+ const cal = calState(calibrationKey);
5963
+ return {
5964
+ ratio: cal.ratio,
5965
+ count: cal.count,
5966
+ calibrated: cal.count >= MIN_SAMPLES_FOR_CALIBRATION
5967
+ };
5968
+ }
5836
5969
  function estimateRequestTokensCalibrated(messages, systemPrompt, tools, calibrationKey = CALIBRATION_GLOBAL_KEY) {
5837
5970
  const result = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);
5838
5971
  const cal = calState(calibrationKey);
@@ -6841,6 +6974,13 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
6841
6974
  tokens = this._estimator(ctx);
6842
6975
  } else if (msgCount === this._cachedMsgCount && toolCount === this._cachedToolCount && this._cachedTokens >= 0) {
6843
6976
  tokens = this._cachedTokens;
6977
+ } else if (this.tryStashedTokens(ctx, msgCount, toolCount) !== null) {
6978
+ const stashed = this.tryStashedTokens(ctx, msgCount, toolCount);
6979
+ const cal = getCalibrationState(`${ctx.provider?.id ?? "unknown"}/${ctx.model}`);
6980
+ tokens = cal.calibrated ? Math.round(stashed * Math.min(1.5, Math.max(0.5, cal.ratio))) : stashed;
6981
+ this._cachedTokens = tokens;
6982
+ this._cachedMsgCount = msgCount;
6983
+ this._cachedToolCount = toolCount;
6844
6984
  } else {
6845
6985
  tokens = estimateRequestTokensCalibrated(
6846
6986
  ctx.messages,
@@ -6873,6 +7013,25 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
6873
7013
  return next(ctx);
6874
7014
  };
6875
7015
  }
7016
+ /**
7017
+ * H1: try to read a pre-computed token total from `ctx.lastRequestTokens`
7018
+ * (set by the agent loop's pre-flight or its restash in emitContextPct).
7019
+ * Returns the uncalibrated total when the stash is valid for the current
7020
+ * context shape (positive number, and the message count it was computed
7021
+ * at matches the current one — otherwise tool results have been appended
7022
+ * since and the value is stale). Returns null when missing or stale so
7023
+ * the caller falls back to a fresh walk.
7024
+ */
7025
+ tryStashedTokens(ctx, msgCount, toolCount) {
7026
+ const stashed = ctx.lastRequestTokens;
7027
+ if (typeof stashed !== "number" || stashed <= 0) return null;
7028
+ const stashedAt = ctx.meta?.["lastRequestTokensAt"];
7029
+ if (typeof stashedAt !== "object" || stashedAt === null) return null;
7030
+ const meta = stashedAt;
7031
+ if (meta.msgCount !== msgCount) return null;
7032
+ if (typeof meta.toolCount === "number" && meta.toolCount !== toolCount) return null;
7033
+ return stashed;
7034
+ }
6876
7035
  /**
6877
7036
  * Returns true when the previous compaction at the same or higher pressure
6878
7037
  * level reduced nothing and context has not grown materially since. Prevents
@@ -7128,7 +7287,7 @@ var ToolExecutor = class _ToolExecutor {
7128
7287
  const tool = this.registry.get(use.name);
7129
7288
  if (!tool) {
7130
7289
  const result = this.unknownToolResult(use, () => this.registry.list().map((t) => t.name));
7131
- budget = this.decrementBudget(result, budget);
7290
+ budget = this.budgetForString(result.content, budget);
7132
7291
  return { result, tool, durationMs: Date.now() - start };
7133
7292
  }
7134
7293
  const validation = validateAgainstSchema(use.input, tool.inputSchema);
@@ -7145,20 +7304,20 @@ ${errorDetails}
7145
7304
  Please call the tool again with arguments that match its inputSchema. You can use the "tool-help" tool with name="${tool.name}" to see the exact expected schema.`,
7146
7305
  is_error: true
7147
7306
  };
7148
- budget = this.decrementBudget(result, budget);
7307
+ budget = this.budgetForString(result.content, budget);
7149
7308
  return { result, tool, durationMs: Date.now() - start };
7150
7309
  }
7151
7310
  const toolDangerousCaps = getDangerousCapabilities(tool);
7152
7311
  if (hasMalformedArguments(use.input)) {
7153
7312
  const result = this.malformedInputResult(use, extractMalformedRaw(use.input));
7154
- budget = this.decrementBudget(result, budget);
7313
+ budget = this.budgetForString(result.content, budget);
7155
7314
  return { result, tool, durationMs: Date.now() - start };
7156
7315
  }
7157
7316
  if (this.opts.hookRunner?.has("PreToolUse")) {
7158
7317
  const pre = await this.opts.hookRunner.preToolUse(tool.name, use.input, ctx);
7159
7318
  if (pre.block) {
7160
7319
  const result = this.blockedByHookResult(use, pre.reason);
7161
- budget = this.decrementBudget(result, budget);
7320
+ budget = this.budgetForString(result.content, budget);
7162
7321
  return { result, tool, durationMs: Date.now() - start };
7163
7322
  }
7164
7323
  if (pre.input) {
@@ -7174,7 +7333,7 @@ Validation errors:
7174
7333
  ${errorDetails}`,
7175
7334
  is_error: true
7176
7335
  };
7177
- budget = this.decrementBudget(result, budget);
7336
+ budget = this.budgetForString(result.content, budget);
7178
7337
  return { result, tool, durationMs: Date.now() - start };
7179
7338
  }
7180
7339
  use = { ...use, input: pre.input };
@@ -7189,7 +7348,7 @@ ${errorDetails}`,
7189
7348
  }
7190
7349
  if (effectivePermission === "deny") {
7191
7350
  const result = this.deniedResult(use, decision.reason);
7192
- budget = this.decrementBudget(result, budget);
7351
+ budget = this.budgetForString(result.content, budget);
7193
7352
  return { result, tool, durationMs: Date.now() - start };
7194
7353
  }
7195
7354
  if (effectivePermission === "confirm") {
@@ -7202,7 +7361,7 @@ ${errorDetails}`,
7202
7361
  content: `Tool "${tool.name}" denied by user.`,
7203
7362
  is_error: true
7204
7363
  };
7205
- budget = this.decrementBudget(result, budget);
7364
+ budget = this.budgetForString(result.content, budget);
7206
7365
  return { result, tool, durationMs: Date.now() - start };
7207
7366
  }
7208
7367
  } else {
@@ -7226,7 +7385,8 @@ ${errorDetails}`,
7226
7385
  "tool.has_dangerous_capabilities": toolCapsForAudit.length > 0
7227
7386
  });
7228
7387
  try {
7229
- let result = await this.executeTool(tool, use, ctx, budget);
7388
+ let { block: result, bytes } = await this.executeTool(tool, use, ctx, budget);
7389
+ budget -= bytes;
7230
7390
  if (this.opts.hookRunner?.has("PostToolUse")) {
7231
7391
  const post = await this.opts.hookRunner.postToolUse(
7232
7392
  tool.name,
@@ -7235,12 +7395,13 @@ ${errorDetails}`,
7235
7395
  ctx
7236
7396
  );
7237
7397
  if (post.additionalContext) {
7238
- result = { ...result, content: `${result.content}
7398
+ const appended = `
7239
7399
 
7240
- ${post.additionalContext}` };
7400
+ ${post.additionalContext}`;
7401
+ result = { ...result, content: `${result.content}${appended}` };
7402
+ budget = Math.max(0, budget - Buffer.byteLength(appended, "utf8"));
7241
7403
  }
7242
7404
  }
7243
- budget = this.decrementBudget(result, budget);
7244
7405
  span?.setAttribute("tool.is_error", !!result.is_error);
7245
7406
  span?.setAttribute(
7246
7407
  "tool.output_bytes",
@@ -7257,7 +7418,7 @@ ${post.additionalContext}` };
7257
7418
  content: `Tool "${tool.name}" threw: ${scrubbed}`,
7258
7419
  is_error: true
7259
7420
  };
7260
- budget = this.decrementBudget(result, budget);
7421
+ budget = this.budgetForString(result.content, budget);
7261
7422
  if (err instanceof Error) span?.recordError(err);
7262
7423
  span?.setAttribute("tool.is_error", true);
7263
7424
  return { result, tool, durationMs: Date.now() - start };
@@ -7277,7 +7438,7 @@ ${post.additionalContext}` };
7277
7438
  content: `Tool "${use.name}" execution failed: ${scrubbed}`,
7278
7439
  is_error: true
7279
7440
  };
7280
- budget = this.decrementBudget(result, budget);
7441
+ budget = this.budgetForString(result.content, budget);
7281
7442
  return { result, tool: this.registry.get(use.name), durationMs: 0 };
7282
7443
  }
7283
7444
  };
@@ -7326,14 +7487,20 @@ ${post.additionalContext}` };
7326
7487
  const output = await this.runWithTimeout(tool, use.input, ctx.signal, ctx, use.id);
7327
7488
  const text = this.serializer.serialize(output);
7328
7489
  const scrubbed = this.opts.secretScrubber.scrub(text);
7329
- const { text: capped } = this.serializer.enforceCap(scrubbed, budget);
7490
+ const { text: capped, newBudget } = this.serializer.enforceCap(scrubbed, budget);
7330
7491
  this.opts.renderer?.writeToolResult(tool.name, capped, false);
7331
7492
  return {
7332
- type: "tool_result",
7333
- tool_use_id: use.id,
7334
- name: tool.name,
7335
- content: capped,
7336
- is_error: false
7493
+ block: {
7494
+ type: "tool_result",
7495
+ tool_use_id: use.id,
7496
+ name: tool.name,
7497
+ content: capped,
7498
+ is_error: false
7499
+ },
7500
+ // `budget - newBudget` is the exact byte count enforceCap spent
7501
+ // (capped at `budget` so a truncated output shows as `budget`
7502
+ // consumed, matching the pre-fix `decrementBudget` semantics).
7503
+ bytes: budget - newBudget
7337
7504
  };
7338
7505
  }
7339
7506
  async runWithTimeout(tool, input, parentSignal, ctx, toolUseId) {
@@ -7473,9 +7640,19 @@ ${excerpt}`;
7473
7640
  is_error: true
7474
7641
  };
7475
7642
  }
7476
- decrementBudget(result, budget) {
7477
- const contentBytes = typeof result.content === "string" ? Buffer.byteLength(result.content, "utf8") : Buffer.byteLength(JSON.stringify(result.content), "utf8");
7478
- return Math.max(0, budget - contentBytes);
7643
+ /**
7644
+ * Subtract a string-content result's UTF-8 byte length from the
7645
+ * iteration output budget. Used for synthesized results (unknown tool,
7646
+ * validation error, blocked, threw) where the content is a small
7647
+ * string built in the executor. The success path no longer goes
7648
+ * through here — `executeTool` carries the exact byte count it spent
7649
+ * in its return value, derived from `enforceCap`'s `newBudget`.
7650
+ *
7651
+ * Floors the result at 0 to match the pre-fix `decrementBudget`
7652
+ * semantics (over-budget spends don't underflow the running total).
7653
+ */
7654
+ budgetForString(content, budget) {
7655
+ return Math.max(0, budget - Buffer.byteLength(content, "utf8"));
7479
7656
  }
7480
7657
  /**
7481
7658
  * Compute the suggestedPattern string for a tool+input pair.
@@ -15426,6 +15603,17 @@ var Director = class _Director {
15426
15603
  * default cap.
15427
15604
  */
15428
15605
  taskCompletedListener = null;
15606
+ /**
15607
+ * Unsub handles for the two `FleetBus.filter()` calls installed in the
15608
+ * constructor for timeout-heartbeat tracking. Without capturing these
15609
+ * and calling them in `shutdown()`, repeated Director construction
15610
+ * (tests, hot reloads, `--director` restarts) accumulates 2 dangling
15611
+ * listeners per Director on the FleetBus, slowly drifting the
15612
+ * EventEmitter past its default cap. Mirrors the rationale on
15613
+ * `taskCompletedListener` above.
15614
+ */
15615
+ toolExecFilter = null;
15616
+ budgetFilter = null;
15429
15617
  /** Optional LLM classifier for smart dispatch. Passed from options. */
15430
15618
  dispatchClassifier;
15431
15619
  /** Leader agent's current context pressure (full request tokens). */
@@ -15563,10 +15751,10 @@ var Director = class _Director {
15563
15751
  const extendCounts = /* @__PURE__ */ new Map();
15564
15752
  const progressBySubagent = /* @__PURE__ */ new Map();
15565
15753
  const lastTimeoutProgress = /* @__PURE__ */ new Map();
15566
- this.fleet.filter("tool.executed", (e) => {
15754
+ this.toolExecFilter = this.fleet.filter("tool.executed", (e) => {
15567
15755
  progressBySubagent.set(e.subagentId, (progressBySubagent.get(e.subagentId) ?? 0) + 1);
15568
15756
  });
15569
- this.fleet.filter("budget.threshold_reached", (e) => {
15757
+ this.budgetFilter = this.fleet.filter("budget.threshold_reached", (e) => {
15570
15758
  const payload = e.payload;
15571
15759
  if (e.subagentId.startsWith("bug-hunter-") || e.subagentId.startsWith("refactor-planner-") || e.subagentId.startsWith("critic-")) {
15572
15760
  return;
@@ -16097,6 +16285,14 @@ var Director = class _Director {
16097
16285
  this.coordinator.off("task.completed", this.taskCompletedListener);
16098
16286
  this.taskCompletedListener = null;
16099
16287
  }
16288
+ if (this.toolExecFilter) {
16289
+ this.toolExecFilter();
16290
+ this.toolExecFilter = null;
16291
+ }
16292
+ if (this.budgetFilter) {
16293
+ this.budgetFilter();
16294
+ this.budgetFilter = null;
16295
+ }
16100
16296
  await this.coordinator.stopAll();
16101
16297
  for (const b of this.subagentBridges.values()) {
16102
16298
  await b.stop().catch((err) => this.logShutdownError("subagent_bridge_stop", err));