@wrongstack/core 0.265.1 → 0.267.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 (69) hide show
  1. package/dist/{agent-bridge-DrkBxszZ.d.ts → agent-bridge-STJ3JwwK.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-DM2pP-B6.d.ts → agent-subagent-runner-CzPGP3jA.d.ts} +25 -7
  3. package/dist/{brain-BXd_61kQ.d.ts → brain-Cdg77tVN.d.ts} +73 -1
  4. package/dist/{compactor-B8pOf45Y.d.ts → compactor-iMZ84CXq.d.ts} +19 -1
  5. package/dist/{config-BMCj_XDs.d.ts → config-Du3pYYln.d.ts} +54 -3
  6. package/dist/{context-MRk5PhNv.d.ts → context-dT5Ueund.d.ts} +65 -1
  7. package/dist/coordination/index.d.ts +17 -17
  8. package/dist/coordination/index.js +138 -114
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +25 -25
  11. package/dist/defaults/index.js +1729 -781
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +15 -15
  14. package/dist/execution/index.js +1119 -229
  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-DvHDSKSe.d.ts → goal-preamble-SulMTowG.d.ts} +28 -11
  19. package/dist/{goal-store-DtLMySNb.d.ts → goal-store-CABDwdFE.d.ts} +1 -1
  20. package/dist/{index-CEDeNodM.d.ts → index-Bms0m4oy.d.ts} +5 -5
  21. package/dist/{index-B-ch8K9C.d.ts → index-DtCVWel4.d.ts} +8 -8
  22. package/dist/index-IEuxQd-E.d.ts +82 -0
  23. package/dist/index.d.ts +118 -45
  24. package/dist/index.js +3083 -1602
  25. package/dist/index.js.map +1 -1
  26. package/dist/infrastructure/index.d.ts +6 -6
  27. package/dist/infrastructure/index.js +72 -1
  28. package/dist/infrastructure/index.js.map +1 -1
  29. package/dist/kernel/index.d.ts +9 -9
  30. package/dist/kernel/index.js.map +1 -1
  31. package/dist/{mcp-servers-2x4w6Jn9.d.ts → mcp-servers-C2cBTxUR.d.ts} +3 -3
  32. package/dist/models/index.d.ts +5 -5
  33. package/dist/models/index.js +30 -1
  34. package/dist/models/index.js.map +1 -1
  35. package/dist/{models-registry-DmJlKuNp.d.ts → models-registry-BqGZNJQ-.d.ts} +1 -1
  36. package/dist/{multi-agent-coordinator-DyCkCZnU.d.ts → multi-agent-coordinator-B8R43uPz.d.ts} +1 -1
  37. package/dist/{null-fleet-bus-CG9QY2aP.d.ts → null-fleet-bus-CnXa5oTH.d.ts} +14 -9
  38. package/dist/observability/index.d.ts +2 -2
  39. package/dist/{parallel-eternal-engine-Jw9uhEoT.d.ts → parallel-eternal-engine-DdNnw9BQ.d.ts} +11 -9
  40. package/dist/{path-resolver-Dy2ej-gE.d.ts → path-resolver-COIMLCQL.d.ts} +3 -3
  41. package/dist/{permission-B9SB45lp.d.ts → permission-B75JAi3-.d.ts} +1 -1
  42. package/dist/{permission-policy-CkjSXabK.d.ts → permission-policy-DlR9eJAM.d.ts} +2 -2
  43. package/dist/{pipeline-DPDxH_7m.d.ts → pipeline-BfD2k1rT.d.ts} +2 -2
  44. package/dist/{plan-templates-CzD9GnAU.d.ts → plan-templates-DSIKCXZN.d.ts} +5 -5
  45. package/dist/{llm-selector-C0tfTCUe.d.ts → provider-model-resolve-BNRsNuJx.d.ts} +40 -3
  46. package/dist/{provider-runner-DMa70ODu.d.ts → provider-runner-CX7iIvox.d.ts} +3 -3
  47. package/dist/{retry-policy-CN0khdlj.d.ts → retry-policy-BilV1ujH.d.ts} +1 -1
  48. package/dist/sdd/index.d.ts +8 -8
  49. package/dist/sdd/index.js +12 -12
  50. package/dist/sdd/index.js.map +1 -1
  51. package/dist/{secret-vault-B2yw84VT.d.ts → secret-vault-gkvEZZfE.d.ts} +2 -2
  52. package/dist/security/index.d.ts +5 -67
  53. package/dist/security/index.js +96 -76
  54. package/dist/security/index.js.map +1 -1
  55. package/dist/{selector-CzHh_igB.d.ts → selector-Bc7eWtT3.d.ts} +1 -1
  56. package/dist/{session-event-bridge-BUI6Jf-4.d.ts → session-event-bridge-D-araDEz.d.ts} +1 -1
  57. package/dist/{session-reader-CMgdMSRP.d.ts → session-reader-D7Dapswh.d.ts} +1 -1
  58. package/dist/storage/index.d.ts +11 -11
  59. package/dist/storage/index.js +81 -84
  60. package/dist/storage/index.js.map +1 -1
  61. package/dist/tools/index.d.ts +4 -2
  62. package/dist/tools/index.js.map +1 -1
  63. package/dist/types/index.d.ts +19 -19
  64. package/dist/types/index.js +1265 -400
  65. package/dist/types/index.js.map +1 -1
  66. package/dist/utils/index.d.ts +454 -406
  67. package/dist/utils/index.js +2191 -1201
  68. package/dist/utils/index.js.map +1 -1
  69. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { S as SecretScrubber } from './permission-B9SB45lp.js';
1
+ import { S as SecretScrubber } from './permission-B75JAi3-.js';
2
2
  import { L as Logger } from './logger-B63L5bTg.js';
3
3
  import { R as RotatableSecretVault, S as SecretVault } from './secret-vault-BAKpgFw_.js';
4
4
 
@@ -107,4 +107,4 @@ declare function rotateConfigKeys(configPath: string, vault: RotatableSecretVaul
107
107
  file: string;
108
108
  }>;
109
109
 
110
- export { DefaultSecretScrubber as D, type SecretVaultOptions as S, DefaultSecretVault as a, rotateConfigKeys as b, decryptConfigSecrets as d, encryptConfigSecrets as e, isSecretField as i, migratePlaintextSecrets as m, rewriteConfigEncrypted as r };
110
+ export { DefaultSecretVault as D, type SecretVaultOptions as S, DefaultSecretScrubber as a, rotateConfigKeys as b, decryptConfigSecrets as d, encryptConfigSecrets as e, isSecretField as i, migratePlaintextSecrets as m, rewriteConfigEncrypted as r };
@@ -1,70 +1,8 @@
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, b as rotateConfigKeys } from '../secret-vault-B2yw84VT.js';
2
- export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-CkjSXabK.js';
3
- import '../permission-B9SB45lp.js';
4
- import '../context-MRk5PhNv.js';
1
+ export { a as DefaultSecretScrubber, D as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, i as isSecretField, m as migratePlaintextSecrets, r as rewriteConfigEncrypted, b as rotateConfigKeys } from '../secret-vault-gkvEZZfE.js';
2
+ export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-DlR9eJAM.js';
3
+ export { D as DANGEROUS_FOR_SUBAGENTS, T as ToolCapabilities, a as ToolCapability, g as getDangerousCapabilities, h as hasCapability, b as hasDangerousCapabilityForSubagents } from '../index-IEuxQd-E.js';
4
+ import '../permission-B75JAi3-.js';
5
+ import '../context-dT5Ueund.js';
5
6
  import '../logger-B63L5bTg.js';
6
7
  import '../secret-vault-BAKpgFw_.js';
7
8
  import '../input-reader-E-ffP2ee.js';
8
-
9
- /**
10
- * Well-known tool capabilities used for authorization decisions.
11
- *
12
- * These are the preferred values for `Tool.capabilities`.
13
- * New capabilities should be added here with clear documentation.
14
- *
15
- * Philosophy (2026-06+):
16
- * - Prefer capabilities over exact tool name matching.
17
- * - Subagent guards and future policies should primarily key off capabilities.
18
- * - Name-based denylists are legacy and will be phased down.
19
- */
20
- declare const ToolCapabilities: {
21
- /** Can execute arbitrary commands in the user's shell (the `bash` tool). */
22
- readonly SHELL_ARBITRARY: "shell.arbitrary";
23
- /** Can execute a restricted set of commands (the `exec` tool). */
24
- readonly SHELL_RESTRICTED: "shell.restricted";
25
- /** Can read files inside the project (and possibly outside via symlinks if not guarded). */
26
- readonly FS_READ: "fs.read";
27
- /** Can write / modify / delete files inside the project. */
28
- readonly FS_WRITE: "fs.write";
29
- /** Can write files outside the current project root (very high risk). */
30
- readonly FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project";
31
- /** Can perform outbound network requests. */
32
- readonly NET_OUTBOUND: "net.outbound";
33
- /** Proxies tools from external MCP servers (unknown capability). */
34
- readonly MCP_PROXY: "mcp.proxy";
35
- /** Can spawn or manage subagents / multi-agent tasks. */
36
- readonly SUBAGENT_SPAWN: "subagent.spawn";
37
- /** Can mutate global or session configuration / trust state. */
38
- readonly CONFIG_MUTATE: "config.mutate";
39
- /** Can install packages or run package managers with side effects. */
40
- readonly PACKAGE_INSTALL: "package.install";
41
- };
42
- type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];
43
- /**
44
- * Set of capabilities that are considered dangerous for subagents by default.
45
- * Subagents should not receive these capabilities unless the leader explicitly
46
- * allows the specific tool at spawn time.
47
- */
48
- declare const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[];
49
- /**
50
- * Check if a tool (or its capabilities array) includes any dangerous capability
51
- * for subagent execution.
52
- */
53
- declare function hasDangerousCapabilityForSubagents(toolOrCaps: {
54
- capabilities?: readonly string[] | undefined;
55
- } | readonly string[] | undefined): boolean;
56
- /**
57
- * Check if a tool declares a specific capability (or any of the provided ones).
58
- */
59
- declare function hasCapability(toolOrCaps: {
60
- capabilities?: readonly string[] | undefined;
61
- } | readonly string[] | undefined, capability: ToolCapability | ToolCapability[]): boolean;
62
- /**
63
- * Returns the intersection of a tool's capabilities with the dangerous set.
64
- * Useful for logging and audit trails.
65
- */
66
- declare function getDangerousCapabilities(toolOrCaps: {
67
- capabilities?: readonly string[] | undefined;
68
- } | readonly string[] | undefined): ToolCapability[];
69
-
70
- export { DANGEROUS_FOR_SUBAGENTS, ToolCapabilities, type ToolCapability, getDangerousCapabilities, hasCapability, hasDangerousCapabilityForSubagents };
@@ -230,24 +230,68 @@ async function renameWithRetry(from, to) {
230
230
  throw lastErr;
231
231
  }
232
232
 
233
- // src/utils/error.ts
234
- function toErrorMessage(err) {
235
- return err instanceof Error ? err.message : String(err);
233
+ // src/utils/deep-merge.ts
234
+ var FORBIDDEN_PROTO_KEYS = /* @__PURE__ */ new Set([
235
+ "__proto__",
236
+ "constructor",
237
+ "prototype",
238
+ "__defineGetter__",
239
+ "__defineSetter__",
240
+ "__lookupGetter__",
241
+ "__lookupSetter__"
242
+ ]);
243
+ function isPrimitiveArray(a) {
244
+ return a.every((v) => v === null || typeof v !== "object" && typeof v !== "function");
236
245
  }
237
-
238
- // src/utils/safe-json.ts
239
- function safeParse(input, maxBytes = 5e6) {
240
- if (input.length > maxBytes) {
241
- return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };
246
+ function deepMerge(base, patch, options = {}) {
247
+ const {
248
+ conflictResolution = "prefer-patch",
249
+ arrayMode = "replace",
250
+ protectProto = true,
251
+ onNonPrimitiveArrayReplace
252
+ } = options;
253
+ if (typeof base !== "object" || base === null) {
254
+ return conflictResolution === "prefer-patch" ? patch : base;
242
255
  }
243
- try {
244
- return { ok: true, value: JSON.parse(input) };
245
- } catch (err) {
246
- return {
247
- ok: false,
248
- error: toErrorMessage(err)
249
- };
256
+ if (typeof patch !== "object" || patch === null) {
257
+ return conflictResolution === "prefer-patch" ? patch : base;
250
258
  }
259
+ if (Array.isArray(base) && Array.isArray(patch)) {
260
+ if (arrayMode === "concat-primitives" && isPrimitiveArray(base) && isPrimitiveArray(patch)) {
261
+ return [.../* @__PURE__ */ new Set([...base, ...patch])];
262
+ }
263
+ return conflictResolution === "prefer-patch" ? patch : base;
264
+ }
265
+ if (Array.isArray(base) || Array.isArray(patch)) {
266
+ return conflictResolution === "prefer-patch" ? patch : base;
267
+ }
268
+ const baseObj = base;
269
+ const patchObj = patch;
270
+ const out = { ...baseObj };
271
+ for (const [k, v] of Object.entries(patchObj)) {
272
+ if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;
273
+ const existing = out[k];
274
+ if (v !== null && typeof v === "object" && !Array.isArray(v) && existing !== null && typeof existing === "object" && !Array.isArray(existing)) {
275
+ out[k] = deepMerge(existing, v, options);
276
+ } else if (Array.isArray(v) && Array.isArray(existing)) {
277
+ if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {
278
+ onNonPrimitiveArrayReplace(k, existing.length, v.length);
279
+ }
280
+ out[k] = deepMerge(existing, v, options);
281
+ } else if (v !== void 0) {
282
+ if (onNonPrimitiveArrayReplace && Array.isArray(v) && !isPrimitiveArray(v)) {
283
+ const existingLen = Array.isArray(existing) ? existing.length : 0;
284
+ onNonPrimitiveArrayReplace(k, existingLen, v.length);
285
+ }
286
+ out[k] = v;
287
+ }
288
+ }
289
+ return out;
290
+ }
291
+
292
+ // src/utils/error.ts
293
+ function toErrorMessage(err) {
294
+ return err instanceof Error ? err.message : String(err);
251
295
  }
252
296
 
253
297
  // src/utils/expect-defined.ts
@@ -336,63 +380,19 @@ function matchAny(patterns, input) {
336
380
  return patterns.some((p) => matchGlob(p, input));
337
381
  }
338
382
 
339
- // src/utils/deep-merge.ts
340
- var FORBIDDEN_PROTO_KEYS = /* @__PURE__ */ new Set([
341
- "__proto__",
342
- "constructor",
343
- "prototype",
344
- "__defineGetter__",
345
- "__defineSetter__",
346
- "__lookupGetter__",
347
- "__lookupSetter__"
348
- ]);
349
- function isPrimitiveArray(a) {
350
- return a.every((v) => v === null || typeof v !== "object" && typeof v !== "function");
351
- }
352
- function deepMerge(base, patch, options = {}) {
353
- const {
354
- conflictResolution = "prefer-patch",
355
- arrayMode = "replace",
356
- protectProto = true,
357
- onNonPrimitiveArrayReplace
358
- } = options;
359
- if (typeof base !== "object" || base === null) {
360
- return conflictResolution === "prefer-patch" ? patch : base;
361
- }
362
- if (typeof patch !== "object" || patch === null) {
363
- return conflictResolution === "prefer-patch" ? patch : base;
364
- }
365
- if (Array.isArray(base) && Array.isArray(patch)) {
366
- if (arrayMode === "concat-primitives" && isPrimitiveArray(base) && isPrimitiveArray(patch)) {
367
- return [.../* @__PURE__ */ new Set([...base, ...patch])];
368
- }
369
- return conflictResolution === "prefer-patch" ? patch : base;
370
- }
371
- if (Array.isArray(base) || Array.isArray(patch)) {
372
- return conflictResolution === "prefer-patch" ? patch : base;
383
+ // src/utils/safe-json.ts
384
+ function safeParse(input, maxBytes = 5e6) {
385
+ if (input.length > maxBytes) {
386
+ return { ok: false, error: `Input exceeds limit (${maxBytes} bytes)` };
373
387
  }
374
- const baseObj = base;
375
- const patchObj = patch;
376
- const out = { ...baseObj };
377
- for (const [k, v] of Object.entries(patchObj)) {
378
- if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;
379
- const existing = out[k];
380
- if (v !== null && typeof v === "object" && !Array.isArray(v) && existing !== null && typeof existing === "object" && !Array.isArray(existing)) {
381
- out[k] = deepMerge(existing, v, options);
382
- } else if (Array.isArray(v) && Array.isArray(existing)) {
383
- if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {
384
- onNonPrimitiveArrayReplace(k, existing.length, v.length);
385
- }
386
- out[k] = deepMerge(existing, v, options);
387
- } else if (v !== void 0) {
388
- if (onNonPrimitiveArrayReplace && Array.isArray(v) && !isPrimitiveArray(v)) {
389
- const existingLen = Array.isArray(existing) ? existing.length : 0;
390
- onNonPrimitiveArrayReplace(k, existingLen, v.length);
391
- }
392
- out[k] = v;
393
- }
388
+ try {
389
+ return { ok: true, value: JSON.parse(input) };
390
+ } catch (err) {
391
+ return {
392
+ ok: false,
393
+ error: toErrorMessage(err)
394
+ };
394
395
  }
395
- return out;
396
396
  }
397
397
 
398
398
  // src/types/errors.ts
@@ -788,8 +788,13 @@ async function rotateConfigKeys(configPath, vault, logger) {
788
788
  warn(`[secret-vault] Config file ${configPath} is not valid JSON \u2014 skipping rotation`);
789
789
  return { rotated: 0, oldVersion: vault.keyVersion, newVersion: vault.keyVersion, file: configPath };
790
790
  }
791
- const counter = { n: 0 };
791
+ const counter = { n: 0, failed: [] };
792
792
  const decrypted = walkDecryptCount(parsed, vault, counter);
793
+ if (counter.failed.length > 0) {
794
+ throw new Error(
795
+ `[secret-vault] Aborting key rotation: ${counter.failed.length} field(s) could not be decrypted with the current key and would be permanently lost on rotation: ${counter.failed.join(", ")}. Restore or remove these fields before rotating.`
796
+ );
797
+ }
793
798
  if (counter.n === 0) {
794
799
  const { oldVersion: oldVersion2, newVersion: newVersion2 } = vault.rotateKey();
795
800
  log(`[secret-vault] Key rotated (v${oldVersion2} \u2192 v${newVersion2}) \u2014 no encrypted fields to re-encrypt`);
@@ -802,23 +807,27 @@ async function rotateConfigKeys(configPath, vault, logger) {
802
807
  log(`[secret-vault] Key rotated (v${oldVersion} \u2192 v${newVersion}) \u2014 re-encrypted ${counter.n} field(s)`);
803
808
  return { rotated: counter.n, oldVersion, newVersion, file: configPath };
804
809
  }
805
- function walkDecryptCount(node, vault, counter) {
810
+ function walkDecryptCount(node, vault, counter, pathPrefix = "") {
806
811
  if (node === null || node === void 0) return node;
807
812
  if (typeof node !== "object") return node;
808
813
  if (Array.isArray(node)) {
809
- return node.map((item) => walkDecryptCount(item, vault, counter));
814
+ return node.map(
815
+ (item, i) => walkDecryptCount(item, vault, counter, `${pathPrefix}[${i}]`)
816
+ );
810
817
  }
811
818
  const out = /* @__PURE__ */ Object.create(null);
812
819
  for (const [k, v] of Object.entries(node)) {
820
+ const keyPath = pathPrefix ? `${pathPrefix}.${k}` : k;
813
821
  if (typeof v === "string" && vault.isEncrypted(v)) {
814
822
  try {
815
823
  out[k] = vault.decrypt(v);
816
824
  counter.n++;
817
825
  } catch {
826
+ counter.failed.push(keyPath);
818
827
  out[k] = v;
819
828
  }
820
829
  } else if (typeof v === "object" && v !== null) {
821
- out[k] = walkDecryptCount(v, vault, counter);
830
+ out[k] = walkDecryptCount(v, vault, counter, keyPath);
822
831
  } else {
823
832
  out[k] = v;
824
833
  }
@@ -930,6 +939,14 @@ var DANGEROUS_FOR_SUBAGENTS = [
930
939
  ToolCapabilities.CONFIG_MUTATE,
931
940
  ToolCapabilities.PACKAGE_INSTALL
932
941
  ];
942
+ [
943
+ ToolCapabilities.FS_READ,
944
+ ToolCapabilities.FS_WRITE,
945
+ ToolCapabilities.NET_OUTBOUND,
946
+ ToolCapabilities.SHELL_ARBITRARY,
947
+ ToolCapabilities.SHELL_RESTRICTED,
948
+ ToolCapabilities.PACKAGE_INSTALL
949
+ ];
933
950
  function hasDangerousCapabilityForSubagents(toolOrCaps) {
934
951
  if (!toolOrCaps) return false;
935
952
  const input = toolOrCaps;
@@ -1380,9 +1397,12 @@ var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
1380
1397
  const caps = tool.capabilities ?? [];
1381
1398
  const hasAllowedCap = caps.some((c) => this.allowedCapabilities.includes(c));
1382
1399
  const isMcp = _AutoApprovePermissionPolicy.isMcpTool(tool.name);
1383
- const blocked = tool.permission === "deny" || isMcp || !hasAllowedCap;
1400
+ const dangerousNotAllowed = getDangerousCapabilities(tool).filter(
1401
+ (c) => !this.allowedCapabilities.includes(c)
1402
+ );
1403
+ const blocked = tool.permission === "deny" || isMcp || !hasAllowedCap || dangerousNotAllowed.length > 0;
1384
1404
  if (blocked) {
1385
- 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(", ")})`;
1405
+ 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" : dangerousNotAllowed.length > 0 ? `tool requires un-granted dangerous capability (needs: ${dangerousNotAllowed.join(", ")}, allowed: ${this.allowedCapabilities.join(", ")})` : `tool lacks allowed capability (has: ${caps.join(", ") || "none"}, allowed: ${this.allowedCapabilities.join(", ")})`;
1386
1406
  return {
1387
1407
  permission: "deny",
1388
1408
  source: "subagent_guard",