@wrongstack/core 0.257.2 → 0.264.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 (82) hide show
  1. package/dist/{agent-bridge-BrxWHEOm.d.ts → agent-bridge-D8sa1vtv.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-US741uBH.d.ts → agent-subagent-runner-c9DLkaas.d.ts} +31 -9
  3. package/dist/{brain-TjEEwSpw.d.ts → brain-O1IdKPaK.d.ts} +59 -2
  4. package/dist/{compactor-C5sT4U7I.d.ts → compactor-BBy0rCtB.d.ts} +1 -1
  5. package/dist/{config-DuAu23zm.d.ts → config-Dz2F3H2K.d.ts} +7 -1
  6. package/dist/{context-CGdgA0q6.d.ts → context-BGSpZNSE.d.ts} +33 -0
  7. package/dist/coordination/index.d.ts +1681 -15
  8. package/dist/coordination/index.js +2826 -405
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +25 -25
  11. package/dist/defaults/index.js +2258 -1433
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/dispatcher-types.d-BBeXBQgS.d.ts +66 -0
  14. package/dist/execution/index.d.ts +15 -15
  15. package/dist/execution/index.js +502 -398
  16. package/dist/execution/index.js.map +1 -1
  17. package/dist/execution/prompt-enhancer.d.ts +2 -2
  18. package/dist/execution/prompt-enhancer.js +7 -1
  19. package/dist/execution/prompt-enhancer.js.map +1 -1
  20. package/dist/extension/index.d.ts +6 -6
  21. package/dist/extension/index.js.map +1 -1
  22. package/dist/{goal-preamble-CznHTZqP.d.ts → goal-preamble-DzjFuN3p.d.ts} +21 -9
  23. package/dist/{goal-store-CV9Yz2X_.d.ts → goal-store-CxWmCGbH.d.ts} +4 -2
  24. package/dist/{index-CC0Mcm05.d.ts → index-CYIQrXVF.d.ts} +8 -8
  25. package/dist/{index-CitPrI3a.d.ts → index-CbLSI66_.d.ts} +5 -5
  26. package/dist/index.d.ts +50 -94
  27. package/dist/index.js +16009 -12406
  28. package/dist/index.js.map +1 -1
  29. package/dist/infrastructure/index.d.ts +6 -6
  30. package/dist/kernel/index.d.ts +9 -9
  31. package/dist/kernel/index.js +6 -1
  32. package/dist/kernel/index.js.map +1 -1
  33. package/dist/{llm-selector-CJ4SyAFE.d.ts → llm-selector-DzxuZnNz.d.ts} +2 -2
  34. package/dist/{mcp-servers-D8YnLaEp.d.ts → mcp-servers-DC4QRPUI.d.ts} +3 -3
  35. package/dist/models/index.d.ts +5 -5
  36. package/dist/models/index.js +6 -1
  37. package/dist/models/index.js.map +1 -1
  38. package/dist/{models-registry-ByZCdFuQ.d.ts → models-registry-B_siPxqN.d.ts} +1 -1
  39. package/dist/{multi-agent-coordinator-DqTUEAeC.d.ts → multi-agent-coordinator-CK5Jdj9K.d.ts} +2 -2
  40. package/dist/{null-fleet-bus-B5mfTJXT.d.ts → null-fleet-bus-DgvD4SCO.d.ts} +13 -8
  41. package/dist/observability/index.d.ts +2 -2
  42. package/dist/observability/index.js +8 -3
  43. package/dist/observability/index.js.map +1 -1
  44. package/dist/{parallel-eternal-engine-C0juOszP.d.ts → parallel-eternal-engine-bK0JQBR_.d.ts} +13 -9
  45. package/dist/{path-resolver-CbkT-RMU.d.ts → path-resolver-BPEDlN38.d.ts} +3 -3
  46. package/dist/{permission-CwBBpCoF.d.ts → permission-4yvGmMRB.d.ts} +1 -1
  47. package/dist/{permission-policy-B8rSu908.d.ts → permission-policy-C6XpsBOy.d.ts} +3 -2
  48. package/dist/{pipeline-JG8XoudC.d.ts → pipeline-CXCeMz8J.d.ts} +58 -3
  49. package/dist/{plan-templates-DPiQMkBz.d.ts → plan-templates-BvzRBkJc.d.ts} +32 -11
  50. package/dist/{provider-runner-hM7EXlLI.d.ts → provider-runner-C5aQpDWE.d.ts} +3 -3
  51. package/dist/{retry-policy-Tg7LXkoK.d.ts → retry-policy-CFhdtRzz.d.ts} +1 -1
  52. package/dist/sdd/index.d.ts +8 -8
  53. package/dist/sdd/index.js +59 -31
  54. package/dist/sdd/index.js.map +1 -1
  55. package/dist/{secret-vault-gxtFZYBt.d.ts → secret-vault-CxiVLbt1.d.ts} +1 -1
  56. package/dist/security/index.d.ts +4 -4
  57. package/dist/security/index.js +238 -204
  58. package/dist/security/index.js.map +1 -1
  59. package/dist/{selector-DWsqVjGf.d.ts → selector-gIuhRTkN.d.ts} +1 -1
  60. package/dist/{session-event-bridge-BAFWdgQ3.d.ts → session-event-bridge-DkvvrpDt.d.ts} +8 -2
  61. package/dist/{session-reader-CqRvaL5v.d.ts → session-reader-KdfVwkKP.d.ts} +1 -1
  62. package/dist/skills/index.js +67 -64
  63. package/dist/skills/index.js.map +1 -1
  64. package/dist/storage/index.d.ts +50 -22
  65. package/dist/storage/index.js +1654 -525
  66. package/dist/storage/index.js.map +1 -1
  67. package/dist/tools/index.d.ts +57 -0
  68. package/dist/tools/index.js +411 -0
  69. package/dist/tools/index.js.map +1 -0
  70. package/dist/types/index.d.ts +19 -19
  71. package/dist/types/index.js +711 -694
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/utils/error.d.ts +7 -0
  74. package/dist/utils/error.js +8 -0
  75. package/dist/utils/error.js.map +1 -0
  76. package/dist/utils/index.d.ts +7 -67
  77. package/dist/utils/index.js +17 -5
  78. package/dist/utils/index.js.map +1 -1
  79. package/package.json +5 -1
  80. package/skills/output-standards/SKILL.md +14 -9
  81. package/skills/output-standards/SKILL.save.md +3 -2
  82. package/dist/package-outdated-watcher-BSgR_kK-.d.ts +0 -581
@@ -1,4 +1,4 @@
1
- import { S as SecretScrubber } from './permission-CwBBpCoF.js';
1
+ import { S as SecretScrubber } from './permission-4yvGmMRB.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-gxtFZYBt.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';
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-CxiVLbt1.js';
2
+ export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-C6XpsBOy.js';
3
+ import '../permission-4yvGmMRB.js';
4
+ import '../context-BGSpZNSE.js';
5
5
  import '../logger-B63L5bTg.js';
6
6
  import '../secret-vault-BJDY28ev.js';
7
7
  import '../input-reader-E-ffP2ee.js';
@@ -143,108 +143,6 @@ var DefaultSecretScrubber = class {
143
143
  return visit(obj);
144
144
  }
145
145
  };
146
-
147
- // src/types/errors.ts
148
- var ERROR_CODES = {
149
- // Provider
150
- PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
151
- PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
152
- PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
153
- PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
154
- PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
155
- PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
156
- PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
157
- // Tool
158
- TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
159
- TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
160
- TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
161
- TOOL_TIMEOUT: "TOOL_TIMEOUT",
162
- TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
163
- // Config
164
- CONFIG_INVALID: "CONFIG_INVALID",
165
- CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
166
- CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
167
- CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
168
- // Plugin
169
- PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
170
- PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
171
- PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
172
- // Agent
173
- AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
174
- AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
175
- AGENT_ABORTED: "AGENT_ABORTED",
176
- AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
177
- // Session
178
- SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
179
- SESSION_CORRUPTED: "SESSION_CORRUPTED",
180
- SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
181
- // Container / Registry
182
- CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
183
- CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
184
- CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
185
- REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
186
- REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
187
- REGISTRY_INVALID: "REGISTRY_INVALID",
188
- // File system
189
- FS_READ_FAILED: "FS_READ_FAILED",
190
- FS_WRITE_FAILED: "FS_WRITE_FAILED",
191
- FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
192
- FS_DELETE_FAILED: "FS_DELETE_FAILED",
193
- FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
194
- // SDD (Spec-Driven Development)
195
- SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
196
- SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
197
- SDD_INVALID_STATE: "SDD_INVALID_STATE",
198
- SDD_NOT_READY: "SDD_NOT_READY",
199
- // General
200
- VALIDATION_ERROR: "VALIDATION_ERROR",
201
- UNKNOWN: "UNKNOWN"
202
- };
203
- var WrongStackError = class extends Error {
204
- code;
205
- subsystem;
206
- severity;
207
- recoverable;
208
- context;
209
- constructor(opts) {
210
- super(opts.message, { cause: opts.cause });
211
- this.name = "WrongStackError";
212
- this.code = opts.code;
213
- this.subsystem = opts.subsystem;
214
- this.severity = opts.severity ?? "error";
215
- this.recoverable = opts.recoverable ?? false;
216
- this.context = opts.context;
217
- }
218
- /**
219
- * Render a one-line user-facing description.
220
- * Subclasses should override for domain-specific formatting.
221
- */
222
- describe() {
223
- const ctx = this.context ? ` ${formatContext(this.context)}` : "";
224
- return `${this.code}: ${this.message}${ctx}`;
225
- }
226
- };
227
- function formatContext(ctx) {
228
- const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
229
- return parts.length > 0 ? `[${parts.join(" ")}]` : "";
230
- }
231
- var ConfigError = class extends WrongStackError {
232
- constructor(opts) {
233
- super({
234
- message: opts.message,
235
- code: opts.code,
236
- subsystem: "config",
237
- severity: "fatal",
238
- recoverable: false,
239
- context: opts.context,
240
- cause: opts.cause
241
- });
242
- this.name = "ConfigError";
243
- }
244
- };
245
-
246
- // src/types/secret-vault.ts
247
- var ENCRYPTED_PREFIX = "enc:v1:";
248
146
  async function atomicWrite(targetPath, content, opts = {}) {
249
147
  const dir = path3.dirname(targetPath);
250
148
  await fs.mkdir(dir, { recursive: true });
@@ -307,6 +205,112 @@ async function renameWithRetry(from, to) {
307
205
  throw lastErr;
308
206
  }
309
207
 
208
+ // src/utils/error.ts
209
+ function toErrorMessage(err) {
210
+ return err instanceof Error ? err.message : String(err);
211
+ }
212
+
213
+ // src/utils/safe-json.ts
214
+ function safeParse(input, maxBytes = 5e6) {
215
+ if (input.length > maxBytes) {
216
+ return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };
217
+ }
218
+ try {
219
+ return { ok: true, value: JSON.parse(input) };
220
+ } catch (err) {
221
+ return {
222
+ ok: false,
223
+ error: toErrorMessage(err)
224
+ };
225
+ }
226
+ }
227
+
228
+ // src/utils/expect-defined.ts
229
+ function expectDefined(value, label) {
230
+ if (value === null || value === void 0) {
231
+ const err = new Error("Expected value to be defined");
232
+ err.name = "ExpectDefinedError";
233
+ throw err;
234
+ }
235
+ return value;
236
+ }
237
+
238
+ // src/utils/glob-match.ts
239
+ function escapeRegex(s) {
240
+ return s.replace(/[.+^${}()|\\]/g, "\\$&");
241
+ }
242
+ var COMPILED_GLOB_CACHE = /* @__PURE__ */ new Map();
243
+ var CACHE_MAX_SIZE = 2e3;
244
+ function getCachedGlob(pattern) {
245
+ const cached = COMPILED_GLOB_CACHE.get(pattern);
246
+ if (cached) return cached;
247
+ if (COMPILED_GLOB_CACHE.size >= CACHE_MAX_SIZE) {
248
+ const keys = [...COMPILED_GLOB_CACHE.keys()];
249
+ for (let i = 0; i < Math.floor(CACHE_MAX_SIZE / 4); i++) {
250
+ COMPILED_GLOB_CACHE.delete(expectDefined(keys[i]));
251
+ }
252
+ }
253
+ const re = compileGlob(pattern);
254
+ COMPILED_GLOB_CACHE.set(pattern, re);
255
+ return re;
256
+ }
257
+ var MAX_GLOB_PATTERN_LEN = 1024;
258
+ function compileGlob(pattern) {
259
+ if (pattern.length > MAX_GLOB_PATTERN_LEN) {
260
+ throw new Error(`Glob pattern exceeds ${MAX_GLOB_PATTERN_LEN} characters`);
261
+ }
262
+ let i = 0;
263
+ let re = "^";
264
+ while (i < pattern.length) {
265
+ const c = pattern[i];
266
+ if (c === "*") {
267
+ if (pattern[i + 1] === "*") {
268
+ re += ".*";
269
+ i += 2;
270
+ if (pattern[i] === "/") i++;
271
+ } else {
272
+ re += "[^/]*";
273
+ i++;
274
+ }
275
+ } else if (c === "?") {
276
+ re += "[^/]";
277
+ i++;
278
+ } else if (c === "[") {
279
+ let cls = "[";
280
+ i++;
281
+ if (pattern[i] === "!" || pattern[i] === "^") {
282
+ cls += "^";
283
+ i++;
284
+ }
285
+ while (i < pattern.length && pattern[i] !== "]") {
286
+ const ch = pattern[i] ?? "";
287
+ if (ch === "\\") {
288
+ cls += "\\\\";
289
+ } else if (ch === "]" || ch === "^") {
290
+ cls += `\\${ch}`;
291
+ } else {
292
+ cls += ch;
293
+ }
294
+ i++;
295
+ }
296
+ cls += "]";
297
+ re += cls;
298
+ i++;
299
+ } else {
300
+ re += escapeRegex(c ?? "");
301
+ i++;
302
+ }
303
+ }
304
+ re += "$";
305
+ return new RegExp(re);
306
+ }
307
+ function matchGlob(pattern, input) {
308
+ return getCachedGlob(pattern).test(input);
309
+ }
310
+ function matchAny(patterns, input) {
311
+ return patterns.some((p) => matchGlob(p, input));
312
+ }
313
+
310
314
  // src/utils/deep-merge.ts
311
315
  var FORBIDDEN_PROTO_KEYS = /* @__PURE__ */ new Set([
312
316
  "__proto__",
@@ -366,6 +370,108 @@ function deepMerge(base, patch, options = {}) {
366
370
  return out;
367
371
  }
368
372
 
373
+ // src/types/errors.ts
374
+ var ERROR_CODES = {
375
+ // Provider
376
+ PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
377
+ PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
378
+ PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
379
+ PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
380
+ PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
381
+ PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
382
+ PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
383
+ // Tool
384
+ TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
385
+ TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
386
+ TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
387
+ TOOL_TIMEOUT: "TOOL_TIMEOUT",
388
+ TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
389
+ // Config
390
+ CONFIG_INVALID: "CONFIG_INVALID",
391
+ CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
392
+ CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
393
+ CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
394
+ // Plugin
395
+ PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
396
+ PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
397
+ PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
398
+ // Agent
399
+ AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
400
+ AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
401
+ AGENT_ABORTED: "AGENT_ABORTED",
402
+ AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
403
+ // Session
404
+ SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
405
+ SESSION_CORRUPTED: "SESSION_CORRUPTED",
406
+ SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
407
+ // Container / Registry
408
+ CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
409
+ CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
410
+ CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
411
+ REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
412
+ REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
413
+ REGISTRY_INVALID: "REGISTRY_INVALID",
414
+ // File system
415
+ FS_READ_FAILED: "FS_READ_FAILED",
416
+ FS_WRITE_FAILED: "FS_WRITE_FAILED",
417
+ FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
418
+ FS_DELETE_FAILED: "FS_DELETE_FAILED",
419
+ FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
420
+ // SDD (Spec-Driven Development)
421
+ SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
422
+ SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
423
+ SDD_INVALID_STATE: "SDD_INVALID_STATE",
424
+ SDD_NOT_READY: "SDD_NOT_READY",
425
+ // General
426
+ VALIDATION_ERROR: "VALIDATION_ERROR",
427
+ UNKNOWN: "UNKNOWN"
428
+ };
429
+ var WrongStackError = class extends Error {
430
+ code;
431
+ subsystem;
432
+ severity;
433
+ recoverable;
434
+ context;
435
+ constructor(opts) {
436
+ super(opts.message, { cause: opts.cause });
437
+ this.name = "WrongStackError";
438
+ this.code = opts.code;
439
+ this.subsystem = opts.subsystem;
440
+ this.severity = opts.severity ?? "error";
441
+ this.recoverable = opts.recoverable ?? false;
442
+ this.context = opts.context;
443
+ }
444
+ /**
445
+ * Render a one-line user-facing description.
446
+ * Subclasses should override for domain-specific formatting.
447
+ */
448
+ describe() {
449
+ const ctx = this.context ? ` ${formatContext(this.context)}` : "";
450
+ return `${this.code}: ${this.message}${ctx}`;
451
+ }
452
+ };
453
+ function formatContext(ctx) {
454
+ const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
455
+ return parts.length > 0 ? `[${parts.join(" ")}]` : "";
456
+ }
457
+ var ConfigError = class extends WrongStackError {
458
+ constructor(opts) {
459
+ super({
460
+ message: opts.message,
461
+ code: opts.code,
462
+ subsystem: "config",
463
+ severity: "fatal",
464
+ recoverable: false,
465
+ context: opts.context,
466
+ cause: opts.cause
467
+ });
468
+ this.name = "ConfigError";
469
+ }
470
+ };
471
+
472
+ // src/types/secret-vault.ts
473
+ var ENCRYPTED_PREFIX = "enc:v1:";
474
+
369
475
  // src/security/secret-vault.ts
370
476
  var KEY_BYTES = 32;
371
477
  var IV_BYTES = 12;
@@ -664,107 +770,6 @@ function getDangerousCapabilities(toolOrCaps) {
664
770
  (c) => DANGEROUS_FOR_SUBAGENTS.includes(c)
665
771
  );
666
772
  }
667
-
668
- // src/utils/expect-defined.ts
669
- function expectDefined(value, label) {
670
- if (value === null || value === void 0) {
671
- const err = new Error("Expected value to be defined");
672
- err.name = "ExpectDefinedError";
673
- throw err;
674
- }
675
- return value;
676
- }
677
-
678
- // src/utils/glob-match.ts
679
- function escapeRegex(s) {
680
- return s.replace(/[.+^${}()|\\]/g, "\\$&");
681
- }
682
- var COMPILED_GLOB_CACHE = /* @__PURE__ */ new Map();
683
- var CACHE_MAX_SIZE = 2e3;
684
- function getCachedGlob(pattern) {
685
- const cached = COMPILED_GLOB_CACHE.get(pattern);
686
- if (cached) return cached;
687
- if (COMPILED_GLOB_CACHE.size >= CACHE_MAX_SIZE) {
688
- const keys = [...COMPILED_GLOB_CACHE.keys()];
689
- for (let i = 0; i < Math.floor(CACHE_MAX_SIZE / 4); i++) {
690
- COMPILED_GLOB_CACHE.delete(expectDefined(keys[i]));
691
- }
692
- }
693
- const re = compileGlob(pattern);
694
- COMPILED_GLOB_CACHE.set(pattern, re);
695
- return re;
696
- }
697
- var MAX_GLOB_PATTERN_LEN = 1024;
698
- function compileGlob(pattern) {
699
- if (pattern.length > MAX_GLOB_PATTERN_LEN) {
700
- throw new Error(`Glob pattern exceeds ${MAX_GLOB_PATTERN_LEN} characters`);
701
- }
702
- let i = 0;
703
- let re = "^";
704
- while (i < pattern.length) {
705
- const c = pattern[i];
706
- if (c === "*") {
707
- if (pattern[i + 1] === "*") {
708
- re += ".*";
709
- i += 2;
710
- if (pattern[i] === "/") i++;
711
- } else {
712
- re += "[^/]*";
713
- i++;
714
- }
715
- } else if (c === "?") {
716
- re += "[^/]";
717
- i++;
718
- } else if (c === "[") {
719
- let cls = "[";
720
- i++;
721
- if (pattern[i] === "!" || pattern[i] === "^") {
722
- cls += "^";
723
- i++;
724
- }
725
- while (i < pattern.length && pattern[i] !== "]") {
726
- const ch = pattern[i] ?? "";
727
- if (ch === "\\") {
728
- cls += "\\\\";
729
- } else if (ch === "]" || ch === "^") {
730
- cls += `\\${ch}`;
731
- } else {
732
- cls += ch;
733
- }
734
- i++;
735
- }
736
- cls += "]";
737
- re += cls;
738
- i++;
739
- } else {
740
- re += escapeRegex(c ?? "");
741
- i++;
742
- }
743
- }
744
- re += "$";
745
- return new RegExp(re);
746
- }
747
- function matchGlob(pattern, input) {
748
- return getCachedGlob(pattern).test(input);
749
- }
750
- function matchAny(patterns, input) {
751
- return patterns.some((p) => matchGlob(p, input));
752
- }
753
-
754
- // src/utils/safe-json.ts
755
- function safeParse(input, maxBytes = 5e6) {
756
- if (input.length > maxBytes) {
757
- return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };
758
- }
759
- try {
760
- return { ok: true, value: JSON.parse(input) };
761
- } catch (err) {
762
- return {
763
- ok: false,
764
- error: err instanceof Error ? err.message : String(err)
765
- };
766
- }
767
- }
768
773
  var DESTRUCTIVE_BASH_PATTERNS = [
769
774
  /\bgit\s+(?:clean\s+-[^\s]*[xdf]|reset\s+--hard)\b/i,
770
775
  /\b(?:drop|truncate)\s+(?:table|database|schema)\b/i,
@@ -1041,7 +1046,16 @@ var DefaultPermissionPolicy = class {
1041
1046
  };
1042
1047
  }
1043
1048
  }
1044
- if (tool.permission === "auto" && !tool.mutating) {
1049
+ const hasWriteCap = hasCapability(tool, ToolCapabilities.FS_WRITE);
1050
+ const hasShellCap = hasCapability(tool, [
1051
+ ToolCapabilities.SHELL_ARBITRARY,
1052
+ ToolCapabilities.SHELL_RESTRICTED
1053
+ ]);
1054
+ const hasInstallCap = hasCapability(tool, ToolCapabilities.PACKAGE_INSTALL);
1055
+ const hasConfigCap = hasCapability(tool, ToolCapabilities.CONFIG_MUTATE);
1056
+ const hasSubagentCap = hasCapability(tool, ToolCapabilities.SUBAGENT_SPAWN);
1057
+ const isMutating = tool.mutating || hasWriteCap || hasShellCap || hasInstallCap || hasConfigCap || hasSubagentCap;
1058
+ if (tool.permission === "auto" && !isMutating) {
1045
1059
  const decision = { permission: "auto", source: "default" };
1046
1060
  this._evalCache.set(cacheKey, decision);
1047
1061
  return decision;
@@ -1060,7 +1074,27 @@ var DefaultPermissionPolicy = class {
1060
1074
  }
1061
1075
  return { permission: "confirm", source: "default" };
1062
1076
  }
1077
+ // Capability-based destructive check (preferred over name-based)
1078
+ isDestructiveByCapability(tool) {
1079
+ const caps = tool.capabilities ?? [];
1080
+ if (caps.includes("shell.arbitrary")) return true;
1081
+ if (caps.includes("fs.write")) return true;
1082
+ if (caps.includes("fs.write.outside-project")) return true;
1083
+ return false;
1084
+ }
1063
1085
  isDestructiveYoloCall(tool, input, ctx) {
1086
+ if (this.isDestructiveByCapability(tool)) {
1087
+ if (tool.name === "bash") {
1088
+ const command = getInputString(input, "command");
1089
+ return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;
1090
+ }
1091
+ if (tool.name === "write" || tool.name === "edit" || tool.name === "replace" || tool.name === "patch") {
1092
+ const targetPath = getInputString(input, "path") ?? getInputString(input, "file");
1093
+ if (!targetPath || !ctx.projectRoot) return false;
1094
+ return !pathLooksInsideProject(targetPath, ctx.projectRoot);
1095
+ }
1096
+ return true;
1097
+ }
1064
1098
  if (tool.name === "bash") {
1065
1099
  const command = getInputString(input, "command");
1066
1100
  return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;