@wrongstack/core 0.54.1 → 0.66.13

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 (63) hide show
  1. package/dist/{agent-bridge-Dnhw4tnM.d.ts → agent-bridge-D-j6OOBT.d.ts} +1 -1
  2. package/dist/agent-subagent-runner-DRZ9-NnR.d.ts +1042 -0
  3. package/dist/{compactor-Duhsf0ge.d.ts → compactor-D_ExJajC.d.ts} +1 -1
  4. package/dist/{config-bht0txXS.d.ts → config--86aHSln.d.ts} +112 -2
  5. package/dist/{context-DtPKqKYV.d.ts → context-y87Jc5ei.d.ts} +8 -8
  6. package/dist/coordination/index.d.ts +12 -12
  7. package/dist/coordination/index.js +87 -69
  8. package/dist/coordination/index.js.map +1 -1
  9. package/dist/defaults/index.d.ts +22 -22
  10. package/dist/defaults/index.js +365 -174
  11. package/dist/defaults/index.js.map +1 -1
  12. package/dist/{events-CbHTS4ZZ.d.ts → events-CIplI98R.d.ts} +20 -1
  13. package/dist/execution/index.d.ts +16 -385
  14. package/dist/execution/index.js +129 -61
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/extension/index.d.ts +7 -7
  17. package/dist/goal-store-C7jcumEh.d.ts +96 -0
  18. package/dist/index-DKUvyTvV.d.ts +560 -0
  19. package/dist/{index-ge5F2dnc.d.ts → index-b5uhfTSl.d.ts} +10 -8
  20. package/dist/index.d.ts +59 -33
  21. package/dist/index.js +1138 -733
  22. package/dist/index.js.map +1 -1
  23. package/dist/infrastructure/index.d.ts +6 -6
  24. package/dist/infrastructure/index.js +1 -1
  25. package/dist/infrastructure/index.js.map +1 -1
  26. package/dist/kernel/index.d.ts +9 -9
  27. package/dist/kernel/index.js +3 -1
  28. package/dist/kernel/index.js.map +1 -1
  29. package/dist/{mcp-servers-DE6gzBry.d.ts → mcp-servers-DwoNBf6r.d.ts} +3 -3
  30. package/dist/models/index.d.ts +2 -2
  31. package/dist/{multi-agent-coordinator-CjNX4uBD.d.ts → multi-agent-coordinator-CWnH-CiX.d.ts} +10 -2
  32. package/dist/{null-fleet-bus-BNiSlTna.d.ts → null-fleet-bus-VApKRxcp.d.ts} +6 -7
  33. package/dist/observability/index.d.ts +2 -2
  34. package/dist/parallel-eternal-engine-0UwotoSx.d.ts +483 -0
  35. package/dist/{path-resolver-Bax85amb.d.ts → path-resolver-DVkEcIw8.d.ts} +2 -2
  36. package/dist/{permission-Drm7LpPo.d.ts → permission-C1A5whY5.d.ts} +17 -1
  37. package/dist/{permission-policy-CU6sqWxF.d.ts → permission-policy-B2dK-T5N.d.ts} +28 -7
  38. package/dist/{plan-templates-CLRcurWN.d.ts → plan-templates-Bprrzhbu.d.ts} +4 -4
  39. package/dist/{provider-runner-BikCxGCx.d.ts → provider-runner-mXvXGSIw.d.ts} +3 -3
  40. package/dist/{retry-policy-Chtlvr5b.d.ts → retry-policy-CG3qvH_e.d.ts} +1 -1
  41. package/dist/sdd/index.d.ts +9 -9
  42. package/dist/sdd/index.js +59 -52
  43. package/dist/sdd/index.js.map +1 -1
  44. package/dist/security/index.d.ts +3 -3
  45. package/dist/security/index.js +144 -33
  46. package/dist/security/index.js.map +1 -1
  47. package/dist/{selector-BvSPdJj6.d.ts → selector-RvBR_YRW.d.ts} +1 -1
  48. package/dist/session-event-bridge-CDHxcmQU.d.ts +93 -0
  49. package/dist/{session-reader-BGhzMir4.d.ts → session-reader-BIpwM60D.d.ts} +1 -1
  50. package/dist/storage/index.d.ts +7 -6
  51. package/dist/{system-prompt-dtzV_mLm.d.ts → system-prompt-b61lOd49.d.ts} +32 -2
  52. package/dist/types/index.d.ts +23 -14
  53. package/dist/types/index.js +62 -6
  54. package/dist/types/index.js.map +1 -1
  55. package/dist/utils/index.d.ts +2 -2
  56. package/dist/utils/index.js.map +1 -1
  57. package/package.json +1 -1
  58. package/skills/multi-agent/SKILL.md +0 -2
  59. package/dist/agent-subagent-runner-By7jruZ_.d.ts +0 -182
  60. package/dist/goal-store-DwcTDDiX.d.ts +0 -188
  61. package/dist/index-CI271MjL.d.ts +0 -903
  62. package/dist/multi-agent-BmC_xiog.d.ts +0 -554
  63. package/dist/tool-executor-CgU0yWpB.d.ts +0 -110
@@ -1,4 +1,5 @@
1
- import { T as TextBlock, c as ContentBlock, Q as Tool } from './context-DtPKqKYV.js';
1
+ import { l as HookEvent, n as HookMatcher, I as InProcessHook, s as ShellHook, H as HookEntry } from './config--86aHSln.js';
2
+ import { T as TextBlock, c as ContentBlock, Q as Tool } from './context-y87Jc5ei.js';
2
3
 
3
4
  /**
4
5
  * Container — dependency injection with explicit bind / override / decorate.
@@ -160,6 +161,35 @@ declare class Pipeline<T> {
160
161
  private ensureUnique;
161
162
  }
162
163
 
164
+ /**
165
+ * Registry of lifecycle hooks (both in-process and shell). One instance is
166
+ * shared per session: the boot path loads `config.hooks` as shell entries and
167
+ * plugins add in-process entries via `PluginAPI.registerHook`. The
168
+ * `HookRunner` reads from it at each lifecycle phase.
169
+ */
170
+ declare class HookRegistry {
171
+ private readonly entries;
172
+ /** Register an in-process hook. Returns an unsubscribe function. */
173
+ registerInProcess(event: HookEvent, matcher: HookMatcher | undefined, hook: InProcessHook, owner?: string): () => void;
174
+ /** Register a single shell hook. Returns an unsubscribe function. */
175
+ registerShell(event: HookEvent, hook: ShellHook): () => void;
176
+ /** Bulk-load shell hooks from a `config.hooks` map. */
177
+ loadShellHooks(hooks: Partial<Record<HookEvent, ShellHook[]>> | undefined): void;
178
+ /** All entries registered for an event, in registration order. */
179
+ list(event: HookEvent): readonly HookEntry[];
180
+ /** True when any entry is registered for the event. */
181
+ has(event: HookEvent): boolean;
182
+ /** Drop every registered hook (used in teardown / tests). */
183
+ clear(): void;
184
+ private remove;
185
+ }
186
+ /**
187
+ * Does a hook matcher apply to a tool name? `*` (or empty) matches everything;
188
+ * otherwise the matcher is a case-insensitive pipe-delimited list of exact
189
+ * tool names (`"edit|write"`). Non-tool events pass `undefined` and always match.
190
+ */
191
+ declare function hookMatcherMatches(matcher: HookMatcher, toolName: string | undefined): boolean;
192
+
163
193
  interface Renderer {
164
194
  write(text: string | TextBlock): void;
165
195
  writeLine(text?: string): void;
@@ -201,4 +231,4 @@ interface SystemPromptBuilder {
201
231
  build(ctx: BuildContext): Promise<TextBlock[]>;
202
232
  }
203
233
 
204
- export { type BindOptions as B, Container as C, type Decorator as D, type Factory as F, type Middleware as M, type NextFn as N, Pipeline as P, type ReadonlyPipeline as R, type SystemPromptBuilder as S, type Token as T, type BuildContext as a, type MiddlewareHandler as b, type ModelCapabilities as c, type PipelineOptions as d, type Renderer as e };
234
+ export { type BindOptions as B, Container as C, type Decorator as D, type Factory as F, HookRegistry as H, type Middleware as M, type NextFn as N, Pipeline as P, type ReadonlyPipeline as R, type SystemPromptBuilder as S, type Token as T, type BuildContext as a, type MiddlewareHandler as b, type ModelCapabilities as c, type PipelineOptions as d, type Renderer as e, hookMatcherMatches as h };
@@ -1,30 +1,39 @@
1
- export { A as AgentError, a as Capabilities, b as ConfigError, c as ContentBlock, E as ERROR_CODES, g as ErrorCode, h as ErrorSeverity, i as ErrorSubsystem, F as FileSnapshot, j as FsError, I as ImageBlock, J as JSONSchema, M as Message, k as MessageRole, P as Permission, l as PluginError, m as Provider, n as ProviderError, o as ProviderErrorBody, p as Request, q as Response, r as ResumedSession, s as RiskTier, S as SessionData, v as SessionError, w as SessionEvent, x as SessionMetadata, y as SessionStore, z as SessionSummary, B as SessionWriter, H as StopReason, K as StreamEvent, T as TextBlock, L as ThinkingBlock, Q as Tool, U as ToolCallContext, V as ToolError, W as ToolFinalEvent, X as ToolProgressEvent, Y as ToolResultBlock, Z as ToolStreamEvent, _ as ToolUseBlock, $ as Usage, a0 as WrongStackError, a1 as asBlocks, a2 as asText, a4 as isAgentError, a5 as isConfigError, a6 as isFsError, a7 as isImageBlock, a8 as isPluginError, a9 as isSessionError, aa as isTextBlock, ab as isThinkingBlock, ac as isToolError, ad as isToolResultBlock, ae as isToolUseBlock, af as isWrongStackError, ag as toWrongStackError } from '../context-DtPKqKYV.js';
2
- export { P as ProviderRunner, R as RunProviderOptions } from '../provider-runner-BikCxGCx.js';
3
- export { A as AutonomyConfig, C as CONTEXT_WINDOW_MODES, a as Config, b as ConfigLoader, c as ConfigStore, d as ContextConfig, e as ContextWindowAggressiveOn, f as ContextWindowConfigLike, g as ContextWindowMode, h as ContextWindowModeId, i as ContextWindowPolicy, j as ContextWindowThresholds, k as CustomModelDefinition, D as DEFAULT_CONTEXT_WINDOW_MODE_ID, F as FeaturesConfig, L as LogConfig, M as MCPServerConfig, l as ModelMatrixEntry, P as PluginConfig, m as ProviderApiKey, n as ProviderConfig, S as SessionLoggingConfig, o as SyncCategory, p as SyncConfig, T as ToolsConfig, q as formatContextWindowModeList, r as getContextWindowMode, s as isContextWindowModeId, t as listContextWindowModes, u as resolveContextWindowPolicy } from '../config-bht0txXS.js';
4
- export { C as CompactReport, a as Compactor } from '../compactor-Duhsf0ge.js';
5
- export { P as PermissionDecision, a as PermissionPolicy, T as TrustPolicy } from '../permission-Drm7LpPo.js';
1
+ export { A as AgentError, a as Capabilities, b as ConfigError, c as ContentBlock, E as ERROR_CODES, g as ErrorCode, h as ErrorSeverity, i as ErrorSubsystem, F as FileSnapshot, j as FsError, I as ImageBlock, J as JSONSchema, M as Message, k as MessageRole, P as Permission, l as PluginError, m as Provider, n as ProviderError, o as ProviderErrorBody, p as Request, q as Response, r as ResumedSession, s as RiskTier, S as SessionData, v as SessionError, w as SessionEvent, x as SessionMetadata, y as SessionStore, z as SessionSummary, B as SessionWriter, H as StopReason, K as StreamEvent, T as TextBlock, L as ThinkingBlock, Q as Tool, U as ToolCallContext, V as ToolError, W as ToolFinalEvent, X as ToolProgressEvent, Y as ToolResultBlock, Z as ToolStreamEvent, _ as ToolUseBlock, $ as Usage, a0 as WrongStackError, a1 as asBlocks, a2 as asText, a4 as isAgentError, a5 as isConfigError, a6 as isFsError, a7 as isImageBlock, a8 as isPluginError, a9 as isSessionError, aa as isTextBlock, ab as isThinkingBlock, ac as isToolError, ad as isToolResultBlock, ae as isToolUseBlock, af as isWrongStackError, ag as toWrongStackError } from '../context-y87Jc5ei.js';
2
+ export { P as ProviderRunner, R as RunProviderOptions } from '../provider-runner-mXvXGSIw.js';
3
+ export { A as AutonomyConfig, C as CONTEXT_WINDOW_MODES, a as Config, b as ConfigLoader, c as ConfigStore, d as ContextConfig, e as ContextWindowAggressiveOn, f as ContextWindowConfigLike, g as ContextWindowMode, h as ContextWindowModeId, i as ContextWindowPolicy, j as ContextWindowThresholds, k as CustomModelDefinition, D as DEFAULT_CONTEXT_WINDOW_MODE_ID, F as FeaturesConfig, H as HookEntry, l as HookEvent, m as HookInput, n as HookMatcher, o as HookOutcome, I as InProcessHook, L as LogConfig, M as MCPServerConfig, p as ModelMatrixEntry, P as PluginConfig, q as ProviderApiKey, r as ProviderConfig, S as SessionLoggingConfig, s as ShellHook, t as SyncCategory, u as SyncConfig, T as ToolsConfig, v as formatContextWindowModeList, w as getContextWindowMode, x as isContextWindowModeId, y as listContextWindowModes, z as resolveContextWindowPolicy } from '../config--86aHSln.js';
4
+ export { C as CompactReport, a as Compactor } from '../compactor-D_ExJajC.js';
5
+ export { P as PermissionDecision, a as PermissionPolicy, T as TrustPolicy } from '../permission-C1A5whY5.js';
6
6
  export { C as CheckpointInfo, R as RewindResult, a as RewindResultExtended, S as SessionRewinder } from '../session-rewinder-C9HnMkhP.js';
7
- export { A as AddAttachmentInput, a as Attachment, b as AttachmentKind, c as AttachmentMeta, d as AttachmentRef, e as AttachmentStore, D as DefaultSessionReader } from '../session-reader-BGhzMir4.js';
7
+ export { A as AddAttachmentInput, a as Attachment, b as AttachmentKind, c as AttachmentMeta, d as AttachmentRef, e as AttachmentStore, D as DefaultSessionReader } from '../session-reader-BIpwM60D.js';
8
8
  export { D as DEFAULT_AUTONOMY_CONFIG, a as DEFAULT_CONTEXT_CONFIG, b as DEFAULT_SESSION_LOGGING_CONFIG, c as DEFAULT_TOOLS_CONFIG } from '../default-config-DEXI4jsl.js';
9
9
  export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-scrubber-7rSC_emZ.js';
10
10
  export { D as DefaultLogger, a as DefaultLoggerOptions } from '../logger-bOzkF5LL.js';
11
- export { D as DefaultPathResolver, a as DefaultTokenCounter } from '../path-resolver-Bax85amb.js';
11
+ export { D as DefaultPathResolver, a as DefaultTokenCounter } from '../path-resolver-DVkEcIw8.js';
12
12
  export { M as MemoryEntry, a as MemoryScope, b as MemoryStore } from '../memory-CEXuo7sz.js';
13
- export { C as CompactorOptions, D as DEFAULT_RECOVERY_STRATEGIES, a as DefaultErrorHandler, b as DefaultRetryPolicy, H as HybridCompactor, R as RecoveryStrategy, T as ToolExecutor, c as buildRecoveryStrategies } from '../tool-executor-CgU0yWpB.js';
13
+ import { I as IterationStage, g as ParallelIterationStage } from '../parallel-eternal-engine-0UwotoSx.js';
14
+ export { C as CompactorOptions, D as DEFAULT_RECOVERY_STRATEGIES, a as DefaultErrorHandler, b as DefaultRetryPolicy, H as HybridCompactor, R as RecoveryStrategy, T as ToolExecutor, h as buildRecoveryStrategies } from '../parallel-eternal-engine-0UwotoSx.js';
14
15
  export { S as SkillEntry, a as SkillLoader, b as SkillManifest } from '../skill-CxuWrsKK.js';
15
- export { a as BuildContext, c as ModelCapabilities, e as Renderer, S as SystemPromptBuilder } from '../system-prompt-dtzV_mLm.js';
16
+ export { a as BuildContext, c as ModelCapabilities, e as Renderer, S as SystemPromptBuilder } from '../system-prompt-b61lOd49.js';
16
17
  export { I as InputReader, P as PromptOption } from '../input-reader-E-ffP2ee.js';
17
- export { M as MCPRegistryView, j as MetricsSinkView, P as Plugin, k as PluginAPI, l as PluginCapabilities, m as PluginDependency, n as PluginPipelines, o as ProviderFactory, r as ProviderRegistryView, S as SessionWriterView, u as SlashCommand, v as SlashCommandRegistryView, w as SystemPromptContributor, F as ToolRegistryView } from '../index-CI271MjL.js';
18
+ export { C as CoordinatorEvents, o as CoordinatorStatus, D as DoneCondition, M as MCPRegistryView, t as MetricsSinkView, u as MultiAgentConfig, v as MultiAgentCoordinator, P as Plugin, w as PluginAPI, x as PluginCapabilities, y as PluginDependency, z as PluginPipelines, E as ProviderFactory, G as ProviderRegistryView, S as SessionWriterView, H as SlashCommand, I as SlashCommandRegistryView, J as SpawnResult, L as SubagentConfig, N as SubagentContext, O as SubagentError, Q as SubagentErrorKind, R as SubagentRunContext, T as SubagentRunOutcome, U as SubagentRunner, W as TaskDelegation, X as TaskResult, Y as TaskSpec, Z as ToolRegistryView } from '../agent-subagent-runner-DRZ9-NnR.js';
18
19
  export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-Cuq1C8V9.js';
19
20
  export { D as DEFAULT_MODES, M as Mode, a as ModeConfig, b as ModeManifest, c as ModeStore } from '../mode-CV077NjV.js';
20
- export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-Dnhw4tnM.js';
21
- export { C as CoordinatorEvents, k as CoordinatorStatus, D as DoneCondition, M as MultiAgentConfig, l as MultiAgentCoordinator, S as SpawnResult, n as SubagentConfig, o as SubagentContext, p as SubagentError, q as SubagentErrorKind, r as SubagentRunContext, s as SubagentRunOutcome, t as SubagentRunner, T as TaskDelegation, u as TaskResult, v as TaskSpec } from '../multi-agent-BmC_xiog.js';
21
+ export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-D-j6OOBT.js';
22
22
  export { C as CriticalPathResult, D as DEFAULT_SPEC_TEMPLATE, S as SpecAnalysis, a as SpecApiEndpoint, b as SpecRequirement, c as SpecSection, d as SpecSectionType, e as SpecStatus, f as SpecTemplate, g as SpecValidationResult, h as Specification, T as TaskAssignment, i as TaskDependency, j as TaskEdge, k as TaskFilter, l as TaskGraph, m as TaskNode, n as TaskPriority, o as TaskProgress, p as TaskSort, q as TaskStatus, r as TaskType, s as computeTaskProgress, t as findCriticalPath, u as topologicalSort } from '../task-graph-D1YQbpxF.js';
23
23
  export { A as AggregateHealth, H as HealthCheck, a as HealthCheckResult, b as HealthRegistry, c as HealthStatus, M as MetricLabels, d as MetricSeries, e as MetricsSink, f as MetricsSnapshot, S as Span, T as Tracer } from '../observability-BhnVLBLS.js';
24
- import '../events-CbHTS4ZZ.js';
24
+ export { S as SystemPromptContributor } from '../index-DKUvyTvV.js';
25
+ import '../events-CIplI98R.js';
25
26
  import '../logger-DDd5C--Z.js';
26
- import '../retry-policy-Chtlvr5b.js';
27
+ import '../retry-policy-CG3qvH_e.js';
27
28
  import '../models-registry-BcYJDKLm.js';
28
29
  import '../secret-vault-DoISxaKO.js';
29
30
  import '../secret-scrubber-3MHDDAtm.js';
30
31
  import '../path-resolver-CPRj4bFY.js';
32
+ import '../goal-store-C7jcumEh.js';
33
+ import '../multi-agent-coordinator-CWnH-CiX.js';
34
+ import 'node:events';
35
+
36
+ /** Union of serial and parallel autonomy engine stage types (from EternalAutonomyEngine / ParallelEternalEngine). */
37
+ type AutonomyStage = IterationStage | ParallelIterationStage;
38
+
39
+ export type { AutonomyStage };
@@ -1265,7 +1265,7 @@ var DefaultPathResolver = class {
1265
1265
  var NETWORK_ERR_RE = /ECONN|ETIMEDOUT|ETIME|ENOTFOUND|EAI_AGAIN|fetch failed/i;
1266
1266
 
1267
1267
  // src/execution/error-handler.ts
1268
- var CONTEXT_OVERFLOW_RE = /context|too long|tokens/i;
1268
+ var CONTEXT_OVERFLOW_RE = /context|too long|tokens|exceeds the context window|context window/i;
1269
1269
  function buildRecoveryStrategies(opts) {
1270
1270
  return [
1271
1271
  {
@@ -1273,7 +1273,7 @@ function buildRecoveryStrategies(opts) {
1273
1273
  compactor: opts?.compactor,
1274
1274
  async attempt(err, ctx) {
1275
1275
  if (!(err instanceof ProviderError)) return null;
1276
- if (err.status !== 413 && !CONTEXT_OVERFLOW_RE.test(err.message)) return null;
1276
+ if (err.status !== 413 && !isContextOverflowError(err)) return null;
1277
1277
  if (this.compactor) {
1278
1278
  try {
1279
1279
  const report = await this.compactor.compact(ctx, { aggressive: true });
@@ -1336,6 +1336,14 @@ function buildRecoveryStrategies(opts) {
1336
1336
  ];
1337
1337
  }
1338
1338
  var DEFAULT_RECOVERY_STRATEGIES = buildRecoveryStrategies();
1339
+ function isContextOverflowError(err) {
1340
+ return CONTEXT_OVERFLOW_RE.test([
1341
+ err.message,
1342
+ err.body?.message,
1343
+ err.body?.type,
1344
+ err.body?.raw
1345
+ ].filter(Boolean).join("\n"));
1346
+ }
1339
1347
  var DefaultErrorHandler = class {
1340
1348
  strategies;
1341
1349
  constructor(strategies = DEFAULT_RECOVERY_STRATEGIES) {
@@ -1352,7 +1360,7 @@ var DefaultErrorHandler = class {
1352
1360
  if (err.status === 429) return { kind: "rate_limit", retryable: true };
1353
1361
  if (err.status === 529) return { kind: "overloaded", retryable: true };
1354
1362
  if (err.status >= 500) return { kind: "server", retryable: true };
1355
- if (err.status === 413 || CONTEXT_OVERFLOW_RE.test(err.message)) {
1363
+ if (err.status === 413 || isContextOverflowError(err)) {
1356
1364
  return { kind: "context_overflow", retryable: false };
1357
1365
  }
1358
1366
  if (err.status >= 400) return { kind: "client", retryable: false };
@@ -2619,8 +2627,9 @@ var ToolExecutor = class {
2619
2627
  */
2620
2628
  async executeBatch(toolUses, ctx, strategy) {
2621
2629
  let budget = this.opts.perIterationOutputCapBytes ?? 1e5;
2622
- const runOne = async (use) => {
2630
+ const runOne = async (use0) => {
2623
2631
  const start = Date.now();
2632
+ let use = use0;
2624
2633
  const tool = this.registry.get(use.name);
2625
2634
  if (!tool) {
2626
2635
  const result = this.unknownToolResult(use, () => this.registry.list().map((t) => t.name));
@@ -2653,10 +2662,36 @@ Please call the tool again with arguments that match its inputSchema. You can us
2653
2662
  budget = this.decrementBudget(result, budget);
2654
2663
  return { result, tool, durationMs: Date.now() - start };
2655
2664
  }
2665
+ if (this.opts.hookRunner?.has("PreToolUse")) {
2666
+ const pre = await this.opts.hookRunner.preToolUse(tool.name, use.input, ctx);
2667
+ if (pre.block) {
2668
+ const result = this.blockedByHookResult(use, pre.reason);
2669
+ budget = this.decrementBudget(result, budget);
2670
+ return { result, tool, durationMs: Date.now() - start };
2671
+ }
2672
+ if (pre.input) {
2673
+ const reval = validateAgainstSchema(pre.input, tool.inputSchema);
2674
+ if (!reval.ok) {
2675
+ const errorDetails = reval.errors.map((e) => ` - ${e.path || "input"}: ${e.message}`).join("\n");
2676
+ const result = {
2677
+ type: "tool_result",
2678
+ tool_use_id: use.id,
2679
+ content: `A PreToolUse hook rewrote the arguments for "${tool.name}" into an invalid shape.
2680
+
2681
+ Validation errors:
2682
+ ${errorDetails}`,
2683
+ is_error: true
2684
+ };
2685
+ budget = this.decrementBudget(result, budget);
2686
+ return { result, tool, durationMs: Date.now() - start };
2687
+ }
2688
+ use = { ...use, input: pre.input };
2689
+ }
2690
+ }
2656
2691
  const decision = await this.opts.permissionPolicy.evaluate(tool, use.input, ctx);
2657
2692
  let effectivePermission = decision.permission;
2658
2693
  const policy = this.opts.permissionPolicy;
2659
- const yolo = policy.getYolo?.() === true || policy.getForceAllYolo?.() === true;
2694
+ const yolo = policy.getYolo?.() === true || policy.getYoloDestructive?.() === true || policy.getForceAllYolo?.() === true;
2660
2695
  if (toolDangerousCaps.length > 0 && effectivePermission === "auto" && !yolo) {
2661
2696
  effectivePermission = "confirm";
2662
2697
  }
@@ -2699,7 +2734,20 @@ Please call the tool again with arguments that match its inputSchema. You can us
2699
2734
  "tool.has_dangerous_capabilities": toolCapsForAudit.length > 0
2700
2735
  });
2701
2736
  try {
2702
- const result = await this.executeTool(tool, use, ctx, budget);
2737
+ let result = await this.executeTool(tool, use, ctx, budget);
2738
+ if (this.opts.hookRunner?.has("PostToolUse")) {
2739
+ const post = await this.opts.hookRunner.postToolUse(
2740
+ tool.name,
2741
+ use.input,
2742
+ { content: String(result.content), isError: !!result.is_error },
2743
+ ctx
2744
+ );
2745
+ if (post.additionalContext) {
2746
+ result = { ...result, content: `${result.content}
2747
+
2748
+ ${post.additionalContext}` };
2749
+ }
2750
+ }
2703
2751
  budget = this.decrementBudget(result, budget);
2704
2752
  span?.setAttribute("tool.is_error", !!result.is_error);
2705
2753
  span?.setAttribute(
@@ -2888,6 +2936,14 @@ ${excerpt}`;
2888
2936
  is_error: true
2889
2937
  };
2890
2938
  }
2939
+ blockedByHookResult(use, reason) {
2940
+ return {
2941
+ type: "tool_result",
2942
+ tool_use_id: use.id,
2943
+ content: `Tool "${use.name}" was blocked by a PreToolUse hook: ${reason ?? "no reason given"}`,
2944
+ is_error: true
2945
+ };
2946
+ }
2891
2947
  decrementBudget(result, budget) {
2892
2948
  const contentBytes = typeof result.content === "string" ? Buffer.byteLength(result.content, "utf8") : Buffer.byteLength(JSON.stringify(result.content), "utf8");
2893
2949
  return Math.max(0, budget - contentBytes);