@wrongstack/core 0.255.0 → 0.256.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 (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,9 +1,9 @@
1
1
  export { D as DefaultLogger, a as DefaultLoggerOptions, L as LogFormat } from '../logger-DmmQhf4P.js';
2
- export { D as DefaultPathResolver, a as DefaultTokenCounter } from '../path-resolver-B7VjhUHq.js';
3
- 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, p as playwrightServer, s as sentinelServer, q as slackServer, z as zaiVisionServer } from '../mcp-servers-DfXxCASH.js';
2
+ export { D as DefaultPathResolver, a as DefaultTokenCounter } from '../path-resolver-CbkT-RMU.js';
3
+ 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, p as playwrightServer, s as sentinelServer, q as slackServer, z as zaiVisionServer } from '../mcp-servers-D8YnLaEp.js';
4
4
  import '../logger-B63L5bTg.js';
5
- import '../brain-BaQsRNka.js';
6
- import '../context-CLz3z_E8.js';
7
- import '../config-eSsrto5d.js';
5
+ import '../brain-TjEEwSpw.js';
6
+ import '../context-CGdgA0q6.js';
7
+ import '../config-DuAu23zm.js';
8
8
  import '../path-resolver-CPRj4bFY.js';
9
- import '../compactor-BRfg3QPd.js';
9
+ import '../compactor-C5sT4U7I.js';
@@ -1,15 +1,15 @@
1
- export { r as BindOptions, C as Container, D as Decorator, F as Factory, s as Middleware, M as MiddlewareHandler, N as NextFn, P as Pipeline, t as PipelineOptions, T as Token } from '../pipeline-Bxa3wDcy.js';
2
- export { E as EventBus, n as EventLogger, o as EventMap, a as EventName, L as Listener, w as ScopedEventBus } from '../brain-BaQsRNka.js';
3
- export { R as RunController, b as RunControllerOptions, T as TOKENS } from '../index-BilZMsOK.js';
4
- import '../context-CLz3z_E8.js';
5
- import '../config-eSsrto5d.js';
6
- import '../compactor-BRfg3QPd.js';
7
- import '../retry-policy-BVnkbMET.js';
1
+ export { r as BindOptions, C as Container, D as Decorator, F as Factory, s as Middleware, M as MiddlewareHandler, N as NextFn, P as Pipeline, t as PipelineOptions, T as Token } from '../pipeline-JG8XoudC.js';
2
+ export { E as EventBus, n as EventLogger, o as EventMap, a as EventName, L as Listener, w as ScopedEventBus } from '../brain-TjEEwSpw.js';
3
+ export { R as RunController, b as RunControllerOptions, T as TOKENS } from '../index-CC0Mcm05.js';
4
+ import '../context-CGdgA0q6.js';
5
+ import '../config-DuAu23zm.js';
6
+ import '../compactor-C5sT4U7I.js';
7
+ import '../retry-policy-Tg7LXkoK.js';
8
8
  import '../input-reader-E-ffP2ee.js';
9
9
  import '../logger-B63L5bTg.js';
10
10
  import '../mode-CZlO9iU1.js';
11
11
  import '../path-resolver-CPRj4bFY.js';
12
- import '../permission-DbWPbuoA.js';
13
- import '../provider-runner-C8_e4Lo1.js';
12
+ import '../permission-CwBBpCoF.js';
13
+ import '../provider-runner-hM7EXlLI.js';
14
14
  import '../observability-D-HZN_mF.js';
15
- import '../skill-Bj6Ezqb8.js';
15
+ import '../skill-DGIXCtdv.js';
@@ -1,6 +1,6 @@
1
1
  import { M as ModeStore, a as ModeConfig, b as Mode } from './mode-CZlO9iU1.js';
2
- import { P as Provider, M as Message } from './context-CLz3z_E8.js';
3
- import { M as MessageSelector, S as SelectorResult } from './selector-Cb4_9-hf.js';
2
+ import { P as Provider, M as Message } from './context-CGdgA0q6.js';
3
+ import { M as MessageSelector, S as SelectorResult } from './selector-DWsqVjGf.js';
4
4
 
5
5
  declare class DefaultModeStore implements ModeStore {
6
6
  private activeModeId;
@@ -1,6 +1,6 @@
1
- import { C as Compactor } from './compactor-BRfg3QPd.js';
2
- import { M as Message, T as Tool } from './context-CLz3z_E8.js';
3
- import { c as MCPServerConfig } from './config-eSsrto5d.js';
1
+ import { C as Compactor } from './compactor-C5sT4U7I.js';
2
+ import { M as Message, T as Tool } from './context-CGdgA0q6.js';
3
+ import { c as MCPServerConfig } from './config-DuAu23zm.js';
4
4
 
5
5
  type ContextManagerAction = 'check' | 'summary' | 'prune' | 'add_note' | 'compact' | 'repair';
6
6
  interface ContextManagerInput {
@@ -1,9 +1,9 @@
1
- export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-DpanBg8D.js';
2
- export { D as DefaultModeStore, L as LLMSelector, a as LLMSelectorOptions, M as ModeLoaderOptions, l as loadProjectModes, b as loadUserModes } from '../llm-selector-D22R4AFz.js';
3
- import { d as ModelMatrixEntry, P as ProviderConfig } from '../config-eSsrto5d.js';
1
+ export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-ByZCdFuQ.js';
2
+ export { D as DefaultModeStore, L as LLMSelector, a as LLMSelectorOptions, M as ModeLoaderOptions, l as loadProjectModes, b as loadUserModes } from '../llm-selector-CJ4SyAFE.js';
3
+ import { d as ModelMatrixEntry, P as ProviderConfig } from '../config-DuAu23zm.js';
4
4
  import '../mode-CZlO9iU1.js';
5
- import '../context-CLz3z_E8.js';
6
- import '../selector-Cb4_9-hf.js';
5
+ import '../context-CGdgA0q6.js';
6
+ import '../selector-DWsqVjGf.js';
7
7
 
8
8
  /**
9
9
  * Model Intelligence — knowledge base of model capabilities, strengths,
@@ -1,4 +1,4 @@
1
- import { M as ModelsRegistry, a as ModelsDevPayload, R as ResolvedProvider, b as ResolvedModel, W as WireFamily } from './config-eSsrto5d.js';
1
+ import { M as ModelsRegistry, a as ModelsDevPayload, R as ResolvedProvider, b as ResolvedModel, W as WireFamily } from './config-DuAu23zm.js';
2
2
 
3
3
  interface DefaultModelsRegistryOptions {
4
4
  cacheFile: string;
@@ -1,4 +1,4 @@
1
- import { S as SubagentConfig, M as MultiAgentCoordinator, c as MultiAgentConfig, d as SubagentRunner, F as FleetBus, e as SpawnResult, T as TaskSpec, a as BridgeMessage, A as AgentBridge, C as CoordinatorStatus, f as TaskResult } from './agent-subagent-runner-DhYLgAJo.js';
1
+ import { S as SubagentConfig, M as MultiAgentCoordinator, c as MultiAgentConfig, d as SubagentRunner, F as FleetBus, e as SpawnResult, T as TaskSpec, a as BridgeMessage, A as AgentBridge, C as CoordinatorStatus, f as TaskResult } from './agent-subagent-runner-US741uBH.js';
2
2
  import { EventEmitter } from 'node:events';
3
3
 
4
4
  /**
@@ -1,11 +1,11 @@
1
- import { d as AgentPhase, A as AgentDefinition, a as DefaultMultiAgentCoordinator, D as DispatchClassifier } from './multi-agent-coordinator-Bs-M0Mo6.js';
2
- import { F as FleetBus, u as FleetUsage, S as SubagentConfig, v as FleetUsageAggregator, f as TaskResult, C as CoordinatorStatus, T as TaskSpec, c as MultiAgentConfig, d as SubagentRunner } from './agent-subagent-runner-DhYLgAJo.js';
3
- import { a as SessionWriter, T as Tool, i as SessionStore } from './context-CLz3z_E8.js';
4
- import { B as BrainArbiter, E as EventBus } from './brain-BaQsRNka.js';
1
+ import { d as AgentPhase, A as AgentDefinition, a as DefaultMultiAgentCoordinator, D as DispatchClassifier } from './multi-agent-coordinator-DqTUEAeC.js';
2
+ import { F as FleetBus, u as FleetUsage, S as SubagentConfig, v as FleetUsageAggregator, f as TaskResult, C as CoordinatorStatus, T as TaskSpec, c as MultiAgentConfig, d as SubagentRunner } from './agent-subagent-runner-US741uBH.js';
3
+ import { a as SessionWriter, T as Tool, i as SessionStore } from './context-CGdgA0q6.js';
4
+ import { B as BrainArbiter, E as EventBus } from './brain-TjEEwSpw.js';
5
5
  import { EventEmitter } from 'node:events';
6
6
  import { D as DirectorStateSnapshot } from './director-state-BfeCUbmk.js';
7
- import { d as ModelMatrixEntry } from './config-eSsrto5d.js';
8
- import { I as InMemoryAgentBridge } from './agent-bridge-l_DsFEbr.js';
7
+ import { d as ModelMatrixEntry } from './config-DuAu23zm.js';
8
+ import { I as InMemoryAgentBridge } from './agent-bridge-BrxWHEOm.js';
9
9
 
10
10
  /**
11
11
  * Alert levels the Director can emit when a collab session needs attention.
@@ -1125,6 +1125,17 @@ declare class Director implements ICoordinator {
1125
1125
  * default cap.
1126
1126
  */
1127
1127
  private taskCompletedListener;
1128
+ /**
1129
+ * Unsub handles for the two `FleetBus.filter()` calls installed in the
1130
+ * constructor for timeout-heartbeat tracking. Without capturing these
1131
+ * and calling them in `shutdown()`, repeated Director construction
1132
+ * (tests, hot reloads, `--director` restarts) accumulates 2 dangling
1133
+ * listeners per Director on the FleetBus, slowly drifting the
1134
+ * EventEmitter past its default cap. Mirrors the rationale on
1135
+ * `taskCompletedListener` above.
1136
+ */
1137
+ private toolExecFilter;
1138
+ private budgetFilter;
1128
1139
  /** Optional LLM classifier for smart dispatch. Passed from options. */
1129
1140
  readonly dispatchClassifier?: DispatchClassifier | undefined;
1130
1141
  /** Leader agent's current context pressure (full request tokens). */
@@ -1,6 +1,6 @@
1
1
  import { M as MetricsSink, d as MetricLabels, f as MetricsSnapshot, H as HealthRegistry, a as HealthCheck, A as AggregateHealth, T as Tracer, S as Span } from '../observability-D-HZN_mF.js';
2
- import { E as EventBus } from '../brain-BaQsRNka.js';
3
- import '../context-CLz3z_E8.js';
2
+ import { E as EventBus } from '../brain-TjEEwSpw.js';
3
+ import '../context-CGdgA0q6.js';
4
4
 
5
5
  /**
6
6
  * In-memory metrics sink. Suitable for embedded use, tests, and /metrics
@@ -1,6 +1,6 @@
1
- import { b as Mailbox, c as MailboxSendInput, d as MailboxMessage, e as MailboxQuery, f as MailboxAckInput, g as MailboxAgentStatus, A as AgentRegistrationInput, h as AgentHeartbeatInput, i as ClientRegistrationInput, j as ClientHeartbeatInput, k as ClientStatus } from './pipeline-Bxa3wDcy.js';
2
- import { E as EventBus, B as BrainArbiter } from './brain-BaQsRNka.js';
3
- import { C as Context, T as Tool } from './context-CLz3z_E8.js';
1
+ import { b as Mailbox, c as MailboxSendInput, d as MailboxMessage, e as MailboxQuery, f as MailboxAckInput, g as MailboxAgentStatus, A as AgentRegistrationInput, h as AgentHeartbeatInput, i as ClientRegistrationInput, j as ClientHeartbeatInput, k as ClientStatus } from './pipeline-JG8XoudC.js';
2
+ import { E as EventBus, B as BrainArbiter } from './brain-TjEEwSpw.js';
3
+ import { C as Context, T as Tool } from './context-CGdgA0q6.js';
4
4
 
5
5
  /**
6
6
  * DefaultMailbox — append-only JSONL inter-agent mailbox (per-session).
@@ -1,12 +1,12 @@
1
- import { e as ProviderError, C as Context, T as Tool, l as ToolUseBlock, m as ToolResultBlock } from './context-CLz3z_E8.js';
2
- import { R as RetryPolicy, E as ErrorHandler, a as RecoveryDecision } from './retry-policy-BVnkbMET.js';
3
- import { C as Compactor, a as CompactReport } from './compactor-BRfg3QPd.js';
4
- import { M as ModelsRegistry } from './config-eSsrto5d.js';
5
- import { T as ToolExecutorOptions, a as ToolExecutorStrategy, b as ToolBatchResult } from './index-Csoc_bKs.js';
6
- import { g as Agent, h as AgentFactory } from './agent-subagent-runner-DhYLgAJo.js';
7
- import { B as BrainArbiter } from './brain-BaQsRNka.js';
1
+ import { e as ProviderError, C as Context, T as Tool, l as ToolUseBlock, m as ToolResultBlock } from './context-CGdgA0q6.js';
2
+ import { R as RetryPolicy, E as ErrorHandler, a as RecoveryDecision } from './retry-policy-Tg7LXkoK.js';
3
+ import { C as Compactor, a as CompactReport } from './compactor-C5sT4U7I.js';
4
+ import { M as ModelsRegistry } from './config-DuAu23zm.js';
5
+ import { T as ToolExecutorOptions, a as ToolExecutorStrategy, b as ToolBatchResult } from './index-CitPrI3a.js';
6
+ import { g as Agent, h as AgentFactory } from './agent-subagent-runner-US741uBH.js';
7
+ import { B as BrainArbiter } from './brain-TjEEwSpw.js';
8
8
  import { J as JournalEntry } from './goal-store-CV9Yz2X_.js';
9
- import { D as DispatchClassifier, a as DefaultMultiAgentCoordinator } from './multi-agent-coordinator-Bs-M0Mo6.js';
9
+ import { D as DispatchClassifier, a as DefaultMultiAgentCoordinator } from './multi-agent-coordinator-DqTUEAeC.js';
10
10
 
11
11
  declare class DefaultRetryPolicy implements RetryPolicy {
12
12
  shouldRetry(err: Error | ProviderError, attempt: number): boolean;
@@ -123,14 +123,28 @@ declare class ToolExecutor {
123
123
  * invoking the tool — closes the observability gap between "model decided
124
124
  * to call a tool" and "tool.executed".
125
125
  */
126
- executeTool(tool: Tool, use: ToolUseBlock, ctx: Context, budget: number): Promise<ToolResultBlock>;
126
+ executeTool(tool: Tool, use: ToolUseBlock, ctx: Context, budget: number): Promise<{
127
+ block: ToolResultBlock;
128
+ bytes: number;
129
+ }>;
127
130
  private runWithTimeout;
128
131
  private runStreamedTool;
129
132
  private unknownToolResult;
130
133
  private malformedInputResult;
131
134
  private deniedResult;
132
135
  private blockedByHookResult;
133
- private decrementBudget;
136
+ /**
137
+ * Subtract a string-content result's UTF-8 byte length from the
138
+ * iteration output budget. Used for synthesized results (unknown tool,
139
+ * validation error, blocked, threw) where the content is a small
140
+ * string built in the executor. The success path no longer goes
141
+ * through here — `executeTool` carries the exact byte count it spent
142
+ * in its return value, derived from `enforceCap`'s `newBudget`.
143
+ *
144
+ * Floors the result at 0 to match the pre-fix `decrementBudget`
145
+ * semantics (over-budget spends don't underflow the running total).
146
+ */
147
+ private budgetForString;
134
148
  /**
135
149
  * Compute the suggestedPattern string for a tool+input pair.
136
150
  * Matches the logic in DefaultPermissionPolicy so the TUI shows the
@@ -1,6 +1,6 @@
1
- import { E as EventBus } from './brain-BaQsRNka.js';
2
- import { M as ModelsRegistry, b as ResolvedModel } from './config-eSsrto5d.js';
3
- import { c as TokenCounter, U as Usage, d as CacheStats } from './context-CLz3z_E8.js';
1
+ import { E as EventBus } from './brain-TjEEwSpw.js';
2
+ import { M as ModelsRegistry, b as ResolvedModel } from './config-DuAu23zm.js';
3
+ import { c as TokenCounter, U as Usage, d as CacheStats } from './context-CGdgA0q6.js';
4
4
  import { P as PathResolver } from './path-resolver-CPRj4bFY.js';
5
5
 
6
6
  /**
@@ -1,4 +1,4 @@
1
- import { T as Tool, C as Context, f as Permission } from './context-CLz3z_E8.js';
1
+ import { T as Tool, C as Context, f as Permission } from './context-CGdgA0q6.js';
2
2
 
3
3
  interface SecretScrubber {
4
4
  scrub(text: string): string;
@@ -1,6 +1,6 @@
1
- import { T as Tool, C as Context } from './context-CLz3z_E8.js';
1
+ import { T as Tool, C as Context } from './context-CGdgA0q6.js';
2
2
  import { I as InputReader } from './input-reader-E-ffP2ee.js';
3
- import { P as PermissionPolicy, a as PermissionDecision } from './permission-DbWPbuoA.js';
3
+ import { P as PermissionPolicy, a as PermissionDecision } from './permission-CwBBpCoF.js';
4
4
 
5
5
  interface PermissionPolicyOptions {
6
6
  trustFile: string;
@@ -60,6 +60,21 @@ declare class DefaultPermissionPolicy implements PermissionPolicy {
60
60
  private promptDelegate?;
61
61
  /** Pre-compiled wildcard patterns — rebuilt on reload for O(1) lookup. */
62
62
  private wildcardEntries;
63
+ /**
64
+ * Evaluate-result cache. Keyed by `tool.name::subject` so repeated calls
65
+ * with the same tool+input skip namespace matching, subject computation,
66
+ * pattern matching (matchAny), and YOLO destructive gating.
67
+ *
68
+ * Cleared on any state change (reload, trust, deny, yolo toggle) because
69
+ * the result depends on the full policy state. The write-tool smart-bypass
70
+ * (step 7 in `evaluate()`) is not cached since `ctx.hasRead()` changes
71
+ * dynamically within a session.
72
+ *
73
+ * LRU eviction is not needed — the cache is cleared on state changes
74
+ * that are rare (trust file ops, user confirm) and the number of unique
75
+ * tool+subject pairs per iteration is small (<50).
76
+ */
77
+ private _evalCache;
63
78
  constructor(opts: PermissionPolicyOptions);
64
79
  /**
65
80
  * Replace (or clear) the interactive prompt delegate at runtime.
@@ -121,7 +136,29 @@ declare class DefaultPermissionPolicy implements PermissionPolicy {
121
136
  * is kept only for backward compatibility with tools that have not yet
122
137
  * declared capabilities.
123
138
  */
139
+ /**
140
+ * Auto-approving PermissionPolicy used for subagents. Subagents run
141
+ * non-interactively under a director — they cannot answer permission
142
+ * prompts, so a non-YOLO policy on the leader would silently hang the
143
+ * delegated run on the first sensitive tool call. The user already
144
+ * authorized the delegation when they invoked the leader; subagents
145
+ * inherit that authorization automatically.
146
+ *
147
+ * Tool defaults of `permission: 'deny'` are still honored (this is a
148
+ * subagent capability override, not a deny-bypass).
149
+ *
150
+ * 2026-06+: Primary decision is now based on declared `Tool.capabilities`
151
+ * (capability allowlist / denylist model). The legacy name-based DENY set
152
+ * is kept only for backward compatibility with tools that have not yet
153
+ * declared capabilities.
154
+ *
155
+ * 2026-06-13+: Switched to allowlist-by-default. Only tools with explicitly
156
+ * allowed capabilities are auto-approved. Everything else is denied.
157
+ * Default allowed: fs.read, net.outbound (read-only, safe operations).
158
+ */
124
159
  declare class AutoApprovePermissionPolicy implements PermissionPolicy {
160
+ private readonly allowedCapabilities;
161
+ constructor(allowedCapabilities?: readonly string[]);
125
162
  private static isMcpTool;
126
163
  evaluate(tool: Tool): Promise<PermissionDecision>;
127
164
  trust(): Promise<void>;
@@ -1,5 +1,5 @@
1
- import { T as Tool, n as TextBlock, g as ContentBlock } from './context-CLz3z_E8.js';
2
- import { H as HookEvent, e as HookMatcher, I as InProcessHook, S as ShellHook, f as HookEntry } from './config-eSsrto5d.js';
1
+ import { T as Tool, n as TextBlock, g as ContentBlock } from './context-CGdgA0q6.js';
2
+ import { H as HookEvent, e as HookMatcher, I as InProcessHook, S as ShellHook, f as HookEntry } from './config-DuAu23zm.js';
3
3
 
4
4
  /**
5
5
  * Mailbox — persistent inter-agent messaging system with cross-session support.
@@ -1,9 +1,9 @@
1
- import { E as EventBus, M as MemoryScope, k as MemoryEntry, l as MemoryStore, m as MemoryRelevanceContext, S as ScoredEntry } from './brain-BaQsRNka.js';
2
- import { S as SecretScrubber } from './permission-DbWPbuoA.js';
3
- import { i as SessionStore, h as SessionMetadata, a as SessionWriter, p as ResumedSession, q as SessionData, r as SessionSummary, g as ContentBlock, S as SessionEvent, s as TodoItem, t as ConversationState } from './context-CLz3z_E8.js';
4
- import { A as AttachmentStore, a as AddAttachmentInput, b as AttachmentRef, c as Attachment } from './session-reader-CCOssnBS.js';
1
+ import { E as EventBus, M as MemoryScope, k as MemoryEntry, l as MemoryStore, m as MemoryRelevanceContext, S as ScoredEntry } from './brain-TjEEwSpw.js';
2
+ import { S as SecretScrubber } from './permission-CwBBpCoF.js';
3
+ import { i as SessionStore, h as SessionMetadata, a as SessionWriter, p as ResumedSession, q as SessionData, r as SessionSummary, g as ContentBlock, S as SessionEvent, s as TodoItem, t as ConversationState } from './context-CGdgA0q6.js';
4
+ import { A as AttachmentStore, a as AddAttachmentInput, b as AttachmentRef, c as Attachment } from './session-reader-CqRvaL5v.js';
5
5
  import { W as WstackPaths } from './wstack-paths-CJjEwPXn.js';
6
- import { i as ConfigStore, h as Config, j as ConfigLoader, k as SyncConfig } from './config-eSsrto5d.js';
6
+ import { i as ConfigStore, h as Config, j as ConfigLoader, k as SyncConfig } from './config-DuAu23zm.js';
7
7
  import { S as SecretVault } from './secret-vault-BJDY28ev.js';
8
8
 
9
9
  interface SessionStoreOptions {
@@ -1,8 +1,8 @@
1
- import { E as EventBus } from './brain-BaQsRNka.js';
1
+ import { E as EventBus } from './brain-TjEEwSpw.js';
2
2
  import { L as Logger } from './logger-B63L5bTg.js';
3
3
  import { T as Tracer } from './observability-D-HZN_mF.js';
4
- import { P as Provider, R as Request, C as Context, b as Response } from './context-CLz3z_E8.js';
5
- import { R as RetryPolicy } from './retry-policy-BVnkbMET.js';
4
+ import { P as Provider, R as Request, C as Context, b as Response } from './context-CGdgA0q6.js';
5
+ import { R as RetryPolicy } from './retry-policy-Tg7LXkoK.js';
6
6
 
7
7
  /**
8
8
  * Options passed to a ProviderRunner when calling the provider.
@@ -1,4 +1,4 @@
1
- import { C as Context, b as Response, e as ProviderError } from './context-CLz3z_E8.js';
1
+ import { C as Context, b as Response, e as ProviderError } from './context-CGdgA0q6.js';
2
2
 
3
3
  type RecoveryDecision = {
4
4
  /**
@@ -1,15 +1,15 @@
1
1
  import { h as Specification, S as SpecAnalysis, g as SpecValidationResult, e as SpecStatus, f as SpecTemplate, b as SpecRequirement } from '../spec-TBi3Jr6T.js';
2
2
  import { d as TaskGraph, e as TaskNode, i as TaskFilter, j as TaskSort, c as TaskProgress, T as TaskType, a as TaskPriority } from '../task-graph-u1q9Jkyk.js';
3
- import { E as EventBus } from '../brain-BaQsRNka.js';
4
- import { D as DoneCondition, g as Agent, h as AgentFactory, f as TaskResult } from '../agent-subagent-runner-DhYLgAJo.js';
5
- import '../context-CLz3z_E8.js';
6
- import '../index-Csoc_bKs.js';
3
+ import { E as EventBus } from '../brain-TjEEwSpw.js';
4
+ import { D as DoneCondition, g as Agent, h as AgentFactory, f as TaskResult } from '../agent-subagent-runner-US741uBH.js';
5
+ import '../context-CGdgA0q6.js';
6
+ import '../index-CitPrI3a.js';
7
7
  import '../logger-B63L5bTg.js';
8
- import '../pipeline-Bxa3wDcy.js';
9
- import '../config-eSsrto5d.js';
8
+ import '../pipeline-JG8XoudC.js';
9
+ import '../config-DuAu23zm.js';
10
10
  import '../observability-D-HZN_mF.js';
11
- import '../permission-DbWPbuoA.js';
12
- import '../retry-policy-BVnkbMET.js';
11
+ import '../permission-CwBBpCoF.js';
12
+ import '../retry-policy-Tg7LXkoK.js';
13
13
 
14
14
  declare class SpecParser {
15
15
  parse(content: string): Specification;
@@ -1,4 +1,4 @@
1
- import { S as SecretScrubber } from './permission-DbWPbuoA.js';
1
+ import { S as SecretScrubber } from './permission-CwBBpCoF.js';
2
2
  import { L as Logger } from './logger-B63L5bTg.js';
3
3
  import { S as SecretVault } from './secret-vault-BJDY28ev.js';
4
4
 
@@ -1,7 +1,7 @@
1
- export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, i as isSecretField, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-vault-CeVNiy_f.js';
2
- export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-AOk0LVsV.js';
3
- import '../permission-DbWPbuoA.js';
4
- import '../context-CLz3z_E8.js';
1
+ export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, i as isSecretField, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-vault-BkYkJWQs.js';
2
+ export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-B8rSu908.js';
3
+ import '../permission-CwBBpCoF.js';
4
+ import '../context-CGdgA0q6.js';
5
5
  import '../logger-B63L5bTg.js';
6
6
  import '../secret-vault-BJDY28ev.js';
7
7
  import '../input-reader-E-ffP2ee.js';
@@ -61,9 +61,28 @@ var PATTERNS = [
61
61
  }
62
62
  ];
63
63
  var SCRUB_CHUNK_BYTES = 64 * 1024;
64
+ function hasCredentialAnchors(text) {
65
+ return text.includes("-----BEGIN") || // Private keys (most unique → cheap reject)
66
+ text.includes("sk-") || // Anthropic + OpenAI keys
67
+ text.includes("sk_") || // Stripe live/test keys
68
+ text.includes("ghp_") || // GitHub PAT v1
69
+ text.includes("github_pat_") || // GitHub PAT v2
70
+ text.includes("eyJ") || // JWT
71
+ text.includes("AKIA") || // AWS access key
72
+ text.includes("AIza") || // GCP service key
73
+ text.includes("xox") || // Slack token (xoxa/xoxb/xoxp/xoxo/xoxs)
74
+ text.includes("Bearer ") || // Bearer token (space suffix reduces false positives)
75
+ text.includes("/bot") || // Telegram bot token (URL path pattern)
76
+ text.includes("_KEY=") || // High-entropy env vars: API_KEY=, SECRET_KEY=, ...
77
+ text.includes("_TOKEN=") || // ACCESS_TOKEN=, AUTH_TOKEN=, ...
78
+ text.includes("_SECRET=") || // API_SECRET=, CLIENT_SECRET=, ...
79
+ text.includes("_PASSWORD=") || // DB_PASSWORD=, ROOT_PASSWORD=, ...
80
+ text.includes("mongodb://") || text.includes("mongodb+srv://") || text.includes("postgres://") || text.includes("postgresql://") || text.includes("mysql://") || text.includes("redis://");
81
+ }
64
82
  var DefaultSecretScrubber = class {
65
83
  scrub(text) {
66
84
  if (!text) return text;
85
+ if (!hasCredentialAnchors(text)) return text;
67
86
  if (text.length <= SCRUB_CHUNK_BYTES) {
68
87
  return this.scrubOne(text);
69
88
  }
@@ -81,6 +100,7 @@ var DefaultSecretScrubber = class {
81
100
  return out.join("");
82
101
  }
83
102
  scrubOne(text) {
103
+ if (!hasCredentialAnchors(text)) return text;
84
104
  let out = text;
85
105
  for (const p of PATTERNS) {
86
106
  out = out.replace(p.regex, (_match, group1, group2) => {
@@ -851,6 +871,21 @@ var DefaultPermissionPolicy = class {
851
871
  promptDelegate;
852
872
  /** Pre-compiled wildcard patterns — rebuilt on reload for O(1) lookup. */
853
873
  wildcardEntries = [];
874
+ /**
875
+ * Evaluate-result cache. Keyed by `tool.name::subject` so repeated calls
876
+ * with the same tool+input skip namespace matching, subject computation,
877
+ * pattern matching (matchAny), and YOLO destructive gating.
878
+ *
879
+ * Cleared on any state change (reload, trust, deny, yolo toggle) because
880
+ * the result depends on the full policy state. The write-tool smart-bypass
881
+ * (step 7 in `evaluate()`) is not cached since `ctx.hasRead()` changes
882
+ * dynamically within a session.
883
+ *
884
+ * LRU eviction is not needed — the cache is cleared on state changes
885
+ * that are rare (trust file ops, user confirm) and the number of unique
886
+ * tool+subject pairs per iteration is small (<50).
887
+ */
888
+ _evalCache = /* @__PURE__ */ new Map();
854
889
  constructor(opts) {
855
890
  this.trustFile = opts.trustFile;
856
891
  this.yolo = opts.yolo ?? false;
@@ -869,6 +904,7 @@ var DefaultPermissionPolicy = class {
869
904
  }
870
905
  /** Toggle YOLO (auto-approve) mode at runtime. */
871
906
  setYolo(enabled) {
907
+ if (this.yolo !== enabled) this._evalCache.clear();
872
908
  this.yolo = enabled;
873
909
  }
874
910
  /** Check whether YOLO mode is currently active. */
@@ -877,6 +913,7 @@ var DefaultPermissionPolicy = class {
877
913
  }
878
914
  /** Toggle the destructive YOLO override at runtime. */
879
915
  setYoloDestructive(enabled) {
916
+ if (this.yoloDestructive !== enabled) this._evalCache.clear();
880
917
  this.yoloDestructive = enabled;
881
918
  }
882
919
  /** Check whether the destructive YOLO override is active. */
@@ -885,6 +922,7 @@ var DefaultPermissionPolicy = class {
885
922
  }
886
923
  /** Toggle destructive confirmation gate (only meaningful when yolo is active). */
887
924
  setConfirmDestructive(enabled) {
925
+ if (this.confirmDestructive !== enabled) this._evalCache.clear();
888
926
  this.confirmDestructive = enabled;
889
927
  }
890
928
  /** Check whether destructive confirmation gate is active. */
@@ -905,6 +943,7 @@ var DefaultPermissionPolicy = class {
905
943
  }
906
944
  this.sessionDenied.clear();
907
945
  this.sessionAllowed.clear();
946
+ this._evalCache.clear();
908
947
  this.loaded = true;
909
948
  }
910
949
  async evaluate(tool, input, ctx) {
@@ -912,44 +951,60 @@ var DefaultPermissionPolicy = class {
912
951
  const namespaceEntry = this.findNamespaceEntry(tool.name);
913
952
  const entry = this.policy[tool.name] ?? namespaceEntry;
914
953
  const subject = this.subjectFor(tool.name, input, tool.subjectKey);
915
- const subjectKey = `${tool.name}::${subject ?? tool.name}`;
916
- if (this.sessionDenied.has(subjectKey)) {
917
- return { permission: "deny", source: "deny", reason: "session soft deny (user pressed no)" };
954
+ const cacheKey = `${tool.name}::${subject ?? tool.name}`;
955
+ if (tool.name !== "write") {
956
+ const cached = this._evalCache.get(cacheKey);
957
+ if (cached !== void 0) return cached;
918
958
  }
919
- if (this.sessionAllowed.has(subjectKey)) {
920
- return {
959
+ if (this.sessionDenied.has(cacheKey)) {
960
+ const decision = { permission: "deny", source: "deny", reason: "session soft deny (user pressed no)" };
961
+ this._evalCache.set(cacheKey, decision);
962
+ return decision;
963
+ }
964
+ if (this.sessionAllowed.has(cacheKey)) {
965
+ const decision = {
921
966
  permission: "auto",
922
967
  source: "trust",
923
968
  reason: "session soft allow (user pressed yes)"
924
969
  };
970
+ this._evalCache.set(cacheKey, decision);
971
+ return decision;
925
972
  }
926
973
  if (entry?.deny && subject && matchAny(entry.deny, subject)) {
927
- return { permission: "deny", source: "deny", reason: "matched deny pattern" };
974
+ const decision = { permission: "deny", source: "deny", reason: "matched deny pattern" };
975
+ this._evalCache.set(cacheKey, decision);
976
+ return decision;
928
977
  }
929
978
  if (tool.permission === "deny") {
930
- return { permission: "deny", source: "default", reason: "tool default deny" };
979
+ const decision = { permission: "deny", source: "default", reason: "tool default deny" };
980
+ this._evalCache.set(cacheKey, decision);
981
+ return decision;
931
982
  }
932
983
  if (entry?.allow && subject && matchAny(entry.allow, subject)) {
933
- return { permission: "auto", source: "trust", reason: "matched allow pattern" };
984
+ const decision = { permission: "auto", source: "trust", reason: "matched allow pattern" };
985
+ this._evalCache.set(cacheKey, decision);
986
+ return decision;
934
987
  }
935
988
  if (entry?.auto) {
936
- return { permission: "auto", source: "trust" };
989
+ const decision = { permission: "auto", source: "trust" };
990
+ this._evalCache.set(cacheKey, decision);
991
+ return decision;
937
992
  }
938
993
  if (this.yolo) {
939
994
  if (this.confirmDestructive) {
940
995
  const destructive = this.isDestructiveYoloCall(tool, input, ctx);
941
996
  if (destructive) {
942
997
  if (this.promptDelegate) {
943
- const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
944
- if (decision === "always") {
998
+ const decision2 = await this.promptDelegate(tool, input, subject ?? tool.name);
999
+ if (decision2 === "always") {
945
1000
  await this.trust({ tool: tool.name, pattern: subject ?? tool.name });
946
1001
  return { permission: "auto", source: "user", reason: "destructive yolo always-allowed" };
947
1002
  }
948
- if (decision === "deny") {
1003
+ if (decision2 === "deny") {
949
1004
  await this.deny({ tool: tool.name, pattern: subject ?? tool.name });
950
1005
  return { permission: "deny", source: "user", reason: "user denied destructive yolo" };
951
1006
  }
952
- return { permission: decision === "yes" ? "auto" : "deny", source: "user" };
1007
+ return { permission: decision2 === "yes" ? "auto" : "deny", source: "user" };
953
1008
  }
954
1009
  return {
955
1010
  permission: "confirm",
@@ -959,7 +1014,9 @@ var DefaultPermissionPolicy = class {
959
1014
  };
960
1015
  }
961
1016
  }
962
- return { permission: "auto", source: "yolo" };
1017
+ const decision = { permission: "auto", source: "yolo" };
1018
+ this._evalCache.set(cacheKey, decision);
1019
+ return decision;
963
1020
  }
964
1021
  if (tool.name === "write" && subject) {
965
1022
  if (ctx.hasRead(subject)) {
@@ -971,7 +1028,9 @@ var DefaultPermissionPolicy = class {
971
1028
  }
972
1029
  }
973
1030
  if (tool.permission === "auto" && !tool.mutating) {
974
- return { permission: "auto", source: "default" };
1031
+ const decision = { permission: "auto", source: "default" };
1032
+ this._evalCache.set(cacheKey, decision);
1033
+ return decision;
975
1034
  }
976
1035
  if (this.promptDelegate) {
977
1036
  const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
@@ -1004,6 +1063,7 @@ var DefaultPermissionPolicy = class {
1004
1063
  const entry = this.policy[rule.tool] ?? {};
1005
1064
  entry.allow = Array.from(/* @__PURE__ */ new Set([...entry.allow ?? [], rule.pattern]));
1006
1065
  this.policy[rule.tool] = entry;
1066
+ this._evalCache.clear();
1007
1067
  try {
1008
1068
  await atomicWrite(this.trustFile, JSON.stringify(this.policy, null, 2));
1009
1069
  } catch (err) {
@@ -1021,6 +1081,7 @@ var DefaultPermissionPolicy = class {
1021
1081
  const entry = this.policy[rule.tool] ?? {};
1022
1082
  entry.deny = Array.from(/* @__PURE__ */ new Set([...entry.deny ?? [], rule.pattern]));
1023
1083
  this.policy[rule.tool] = entry;
1084
+ this._evalCache.clear();
1024
1085
  try {
1025
1086
  await atomicWrite(this.trustFile, JSON.stringify(this.policy, null, 2));
1026
1087
  } catch (err) {
@@ -1035,10 +1096,12 @@ var DefaultPermissionPolicy = class {
1035
1096
  /** Block this tool+pattern for the rest of this session (no trust file). */
1036
1097
  denyOnce(rule) {
1037
1098
  this.sessionDenied.set(`${rule.tool}::${rule.pattern}`, true);
1099
+ this._evalCache.clear();
1038
1100
  }
1039
1101
  /** Auto-approve this tool+pattern for the rest of this session (no trust file). */
1040
1102
  allowOnce(rule) {
1041
1103
  this.sessionAllowed.set(`${rule.tool}::${rule.pattern}`, true);
1104
+ this._evalCache.clear();
1042
1105
  }
1043
1106
  subjectFor(toolName, input, subjectKey) {
1044
1107
  if (!input || typeof input !== "object") return void 0;
@@ -1074,15 +1137,23 @@ var DefaultPermissionPolicy = class {
1074
1137
  }
1075
1138
  };
1076
1139
  var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
1140
+ allowedCapabilities;
1141
+ constructor(allowedCapabilities) {
1142
+ this.allowedCapabilities = allowedCapabilities ?? [
1143
+ ToolCapabilities.FS_READ,
1144
+ ToolCapabilities.NET_OUTBOUND
1145
+ ];
1146
+ }
1077
1147
  static isMcpTool(name) {
1078
1148
  return name.startsWith("mcp__");
1079
1149
  }
1080
1150
  async evaluate(tool) {
1081
- const hasDangerousCap = hasDangerousCapabilityForSubagents(tool);
1151
+ const caps = tool.capabilities ?? [];
1152
+ const hasAllowedCap = caps.some((c) => this.allowedCapabilities.includes(c));
1082
1153
  const isMcp = _AutoApprovePermissionPolicy.isMcpTool(tool.name);
1083
- const blocked = tool.permission === "deny" || hasDangerousCap || isMcp;
1154
+ const blocked = tool.permission === "deny" || isMcp || !hasAllowedCap;
1084
1155
  if (blocked) {
1085
- 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";
1156
+ 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(", ")})`;
1086
1157
  return {
1087
1158
  permission: "deny",
1088
1159
  source: "subagent_guard",