@wrongstack/core 0.265.1 → 0.268.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.
- package/dist/{agent-bridge-DrkBxszZ.d.ts → agent-bridge-UhojbpWx.d.ts} +1 -1
- package/dist/{agent-subagent-runner-DM2pP-B6.d.ts → agent-subagent-runner-Bvtf1o9K.d.ts} +25 -7
- package/dist/{brain-BXd_61kQ.d.ts → brain-69wzMKp1.d.ts} +73 -1
- package/dist/{compactor-B8pOf45Y.d.ts → compactor-CBQAJoDc.d.ts} +19 -1
- package/dist/{config-BMCj_XDs.d.ts → config-VKfOZ-6X.d.ts} +122 -3
- package/dist/{context-MRk5PhNv.d.ts → context-C0U8B9NF.d.ts} +88 -1
- package/dist/coordination/index.d.ts +57 -161
- package/dist/coordination/index.js +471 -177
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +26 -25
- package/dist/defaults/index.js +1818 -844
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +72 -16
- package/dist/execution/index.js +1270 -265
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +7 -6
- package/dist/global-mailbox-KByEFFBa.d.ts +663 -0
- package/dist/{goal-preamble-DvHDSKSe.d.ts → goal-preamble-CrYjmdw4.d.ts} +28 -11
- package/dist/{goal-store-DtLMySNb.d.ts → goal-store-Y_zdLZ3q.d.ts} +1 -1
- package/dist/hq/index.d.ts +195 -0
- package/dist/hq/index.js +1884 -0
- package/dist/hq/index.js.map +1 -0
- package/dist/index-BfaS-f_m.d.ts +82 -0
- package/dist/{index-B-ch8K9C.d.ts → index-CtQnmkaS.d.ts} +8 -8
- package/dist/{index-CEDeNodM.d.ts → index-gCv830d7.d.ts} +5 -5
- package/dist/index.d.ts +124 -47
- package/dist/index.js +5600 -2662
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +117 -19
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +10 -9
- package/dist/kernel/index.js.map +1 -1
- package/dist/{pipeline-DPDxH_7m.d.ts → mailbox-types-Ct2hJq0P.d.ts} +1 -244
- package/dist/{mcp-servers-2x4w6Jn9.d.ts → mcp-servers-HT3Fi7Bl.d.ts} +10 -4
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +33 -3
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-DmJlKuNp.d.ts → models-registry-Bvcl3Vaa.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-DyCkCZnU.d.ts → multi-agent-coordinator-BACjsmkC.d.ts} +1 -1
- package/dist/{null-fleet-bus-CG9QY2aP.d.ts → null-fleet-bus-DA7fvhUg.d.ts} +14 -9
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-Jw9uhEoT.d.ts → parallel-eternal-engine-Ci71gYu_.d.ts} +11 -15
- package/dist/{path-resolver-Dy2ej-gE.d.ts → path-resolver-O1IJnmKE.d.ts} +4 -3
- package/dist/{permission-B9SB45lp.d.ts → permission-Bd-57Lbl.d.ts} +1 -1
- package/dist/{permission-policy-CkjSXabK.d.ts → permission-policy-uNXC6Kge.d.ts} +2 -3
- package/dist/pipeline-BDNvENyV.d.ts +245 -0
- package/dist/{plan-templates-CzD9GnAU.d.ts → plan-templates-EMsalEtN.d.ts} +5 -5
- package/dist/{llm-selector-C0tfTCUe.d.ts → provider-model-resolve-CEb9x886.d.ts} +40 -3
- package/dist/{provider-runner-DMa70ODu.d.ts → provider-runner-DWJbpo70.d.ts} +3 -3
- package/dist/{retry-policy-CN0khdlj.d.ts → retry-policy-C3s_lvdK.d.ts} +1 -1
- package/dist/sdd/index.d.ts +9 -8
- package/dist/sdd/index.js +44 -14
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-B2yw84VT.d.ts → secret-vault-Cgduf5xL.d.ts} +2 -2
- package/dist/security/index.d.ts +5 -67
- package/dist/security/index.js +129 -99
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-CzHh_igB.d.ts → selector-47LBnBVk.d.ts} +1 -1
- package/dist/{session-event-bridge-BUI6Jf-4.d.ts → session-event-bridge-Cw7oqmW2.d.ts} +1 -1
- package/dist/{session-reader-CMgdMSRP.d.ts → session-reader-DD4v2Obw.d.ts} +1 -1
- package/dist/storage/index.d.ts +14 -12
- package/dist/storage/index.js +144 -120
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +4 -2
- package/dist/tools/index.js +166 -31
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +20 -19
- package/dist/types/index.js +1358 -476
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +472 -405
- package/dist/utils/index.js +2321 -1193
- package/dist/utils/index.js.map +1 -1
- package/package.json +5 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SecretScrubber } from './permission-
|
|
1
|
+
import { S as SecretScrubber } from './permission-Bd-57Lbl.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 {
|
|
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 };
|
package/dist/security/index.d.ts
CHANGED
|
@@ -1,70 +1,8 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-
|
|
3
|
-
|
|
4
|
-
import '../
|
|
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-Cgduf5xL.js';
|
|
2
|
+
export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-uNXC6Kge.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-BfaS-f_m.js';
|
|
4
|
+
import '../permission-Bd-57Lbl.js';
|
|
5
|
+
import '../context-C0U8B9NF.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 };
|
package/dist/security/index.js
CHANGED
|
@@ -230,24 +230,68 @@ async function renameWithRetry(from, to) {
|
|
|
230
230
|
throw lastErr;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
// src/utils/
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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
|
-
|
|
244
|
-
return
|
|
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,54 @@ function matchAny(patterns, input) {
|
|
|
336
380
|
return patterns.some((p) => matchGlob(p, input));
|
|
337
381
|
}
|
|
338
382
|
|
|
339
|
-
// src/utils/
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
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;
|
|
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)` };
|
|
361
387
|
}
|
|
362
|
-
|
|
363
|
-
return
|
|
388
|
+
try {
|
|
389
|
+
return { ok: true, value: JSON.parse(input) };
|
|
390
|
+
} catch (err) {
|
|
391
|
+
return {
|
|
392
|
+
ok: false,
|
|
393
|
+
error: toErrorMessage(err)
|
|
394
|
+
};
|
|
364
395
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// src/utils/tool-subject.ts
|
|
399
|
+
var GLOB_METACHARACTERS = /[*?[\]]/g;
|
|
400
|
+
function escapeGlobSubject(value) {
|
|
401
|
+
return value.replace(GLOB_METACHARACTERS, (char) => `\\${char}`);
|
|
402
|
+
}
|
|
403
|
+
function normalizePathSubject(value) {
|
|
404
|
+
return escapeGlobSubject(value.replace(/\\/g, "/"));
|
|
405
|
+
}
|
|
406
|
+
function isPathSubjectKey(subjectKey) {
|
|
407
|
+
return subjectKey === "path" || subjectKey === "file" || subjectKey === "files";
|
|
408
|
+
}
|
|
409
|
+
function subjectForToolInput(toolName, input, subjectKey) {
|
|
410
|
+
if (!input || typeof input !== "object") return void 0;
|
|
411
|
+
const obj = input;
|
|
412
|
+
if (subjectKey) {
|
|
413
|
+
const value = obj[subjectKey];
|
|
414
|
+
if (typeof value === "string") {
|
|
415
|
+
return isPathSubjectKey(subjectKey) ? normalizePathSubject(value) : escapeGlobSubject(value);
|
|
368
416
|
}
|
|
369
|
-
return conflictResolution === "prefer-patch" ? patch : base;
|
|
370
417
|
}
|
|
371
|
-
if (
|
|
372
|
-
return
|
|
418
|
+
if (toolName === "bash" && typeof obj.command === "string") {
|
|
419
|
+
return escapeGlobSubject(obj.command);
|
|
373
420
|
}
|
|
374
|
-
|
|
375
|
-
|
|
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
|
-
}
|
|
421
|
+
if (typeof obj.path === "string") {
|
|
422
|
+
return normalizePathSubject(obj.path);
|
|
394
423
|
}
|
|
395
|
-
|
|
424
|
+
if (typeof obj.url === "string") {
|
|
425
|
+
return escapeGlobSubject(obj.url);
|
|
426
|
+
}
|
|
427
|
+
if (typeof obj.name === "string") {
|
|
428
|
+
return escapeGlobSubject(obj.name);
|
|
429
|
+
}
|
|
430
|
+
return void 0;
|
|
396
431
|
}
|
|
397
432
|
|
|
398
433
|
// src/types/errors.ts
|
|
@@ -788,8 +823,13 @@ async function rotateConfigKeys(configPath, vault, logger) {
|
|
|
788
823
|
warn(`[secret-vault] Config file ${configPath} is not valid JSON \u2014 skipping rotation`);
|
|
789
824
|
return { rotated: 0, oldVersion: vault.keyVersion, newVersion: vault.keyVersion, file: configPath };
|
|
790
825
|
}
|
|
791
|
-
const counter = { n: 0 };
|
|
826
|
+
const counter = { n: 0, failed: [] };
|
|
792
827
|
const decrypted = walkDecryptCount(parsed, vault, counter);
|
|
828
|
+
if (counter.failed.length > 0) {
|
|
829
|
+
throw new Error(
|
|
830
|
+
`[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.`
|
|
831
|
+
);
|
|
832
|
+
}
|
|
793
833
|
if (counter.n === 0) {
|
|
794
834
|
const { oldVersion: oldVersion2, newVersion: newVersion2 } = vault.rotateKey();
|
|
795
835
|
log(`[secret-vault] Key rotated (v${oldVersion2} \u2192 v${newVersion2}) \u2014 no encrypted fields to re-encrypt`);
|
|
@@ -802,23 +842,27 @@ async function rotateConfigKeys(configPath, vault, logger) {
|
|
|
802
842
|
log(`[secret-vault] Key rotated (v${oldVersion} \u2192 v${newVersion}) \u2014 re-encrypted ${counter.n} field(s)`);
|
|
803
843
|
return { rotated: counter.n, oldVersion, newVersion, file: configPath };
|
|
804
844
|
}
|
|
805
|
-
function walkDecryptCount(node, vault, counter) {
|
|
845
|
+
function walkDecryptCount(node, vault, counter, pathPrefix = "") {
|
|
806
846
|
if (node === null || node === void 0) return node;
|
|
807
847
|
if (typeof node !== "object") return node;
|
|
808
848
|
if (Array.isArray(node)) {
|
|
809
|
-
return node.map(
|
|
849
|
+
return node.map(
|
|
850
|
+
(item, i) => walkDecryptCount(item, vault, counter, `${pathPrefix}[${i}]`)
|
|
851
|
+
);
|
|
810
852
|
}
|
|
811
853
|
const out = /* @__PURE__ */ Object.create(null);
|
|
812
854
|
for (const [k, v] of Object.entries(node)) {
|
|
855
|
+
const keyPath = pathPrefix ? `${pathPrefix}.${k}` : k;
|
|
813
856
|
if (typeof v === "string" && vault.isEncrypted(v)) {
|
|
814
857
|
try {
|
|
815
858
|
out[k] = vault.decrypt(v);
|
|
816
859
|
counter.n++;
|
|
817
860
|
} catch {
|
|
861
|
+
counter.failed.push(keyPath);
|
|
818
862
|
out[k] = v;
|
|
819
863
|
}
|
|
820
864
|
} else if (typeof v === "object" && v !== null) {
|
|
821
|
-
out[k] = walkDecryptCount(v, vault, counter);
|
|
865
|
+
out[k] = walkDecryptCount(v, vault, counter, keyPath);
|
|
822
866
|
} else {
|
|
823
867
|
out[k] = v;
|
|
824
868
|
}
|
|
@@ -930,6 +974,14 @@ var DANGEROUS_FOR_SUBAGENTS = [
|
|
|
930
974
|
ToolCapabilities.CONFIG_MUTATE,
|
|
931
975
|
ToolCapabilities.PACKAGE_INSTALL
|
|
932
976
|
];
|
|
977
|
+
[
|
|
978
|
+
ToolCapabilities.FS_READ,
|
|
979
|
+
ToolCapabilities.FS_WRITE,
|
|
980
|
+
ToolCapabilities.NET_OUTBOUND,
|
|
981
|
+
ToolCapabilities.SHELL_ARBITRARY,
|
|
982
|
+
ToolCapabilities.SHELL_RESTRICTED,
|
|
983
|
+
ToolCapabilities.PACKAGE_INSTALL
|
|
984
|
+
];
|
|
933
985
|
function hasDangerousCapabilityForSubagents(toolOrCaps) {
|
|
934
986
|
if (!toolOrCaps) return false;
|
|
935
987
|
const input = toolOrCaps;
|
|
@@ -1150,7 +1202,7 @@ var DefaultPermissionPolicy = class {
|
|
|
1150
1202
|
if (!this.loaded) await this.reload();
|
|
1151
1203
|
const namespaceEntry = this.findNamespaceEntry(tool.name);
|
|
1152
1204
|
const entry = this.policy[tool.name] ?? namespaceEntry;
|
|
1153
|
-
const subject =
|
|
1205
|
+
const subject = subjectForToolInput(tool.name, input, tool.subjectKey);
|
|
1154
1206
|
const cacheKey = `${tool.name}::${subject ?? tool.name}`;
|
|
1155
1207
|
if (tool.name !== "write") {
|
|
1156
1208
|
const cached = this._evalCache.get(cacheKey);
|
|
@@ -1332,32 +1384,6 @@ var DefaultPermissionPolicy = class {
|
|
|
1332
1384
|
this.sessionAllowed.set(`${rule.tool}::${rule.pattern}`, true);
|
|
1333
1385
|
this._evalCache.clear();
|
|
1334
1386
|
}
|
|
1335
|
-
subjectFor(toolName, input, subjectKey) {
|
|
1336
|
-
if (!input || typeof input !== "object") return void 0;
|
|
1337
|
-
const obj = input;
|
|
1338
|
-
const globChars = /[*?[\]]/g;
|
|
1339
|
-
const escapeGlob = (s) => s.replace(globChars, (c) => `\\${c}`);
|
|
1340
|
-
const normalizePath = (s) => escapeGlob(s.replace(/\\/g, "/"));
|
|
1341
|
-
if (subjectKey) {
|
|
1342
|
-
const v = obj[subjectKey];
|
|
1343
|
-
if (typeof v === "string") {
|
|
1344
|
-
return subjectKey === "path" || subjectKey === "file" || subjectKey === "files" ? normalizePath(v) : escapeGlob(v);
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
if (toolName === "bash" && typeof obj.command === "string") {
|
|
1348
|
-
return escapeGlob(obj.command);
|
|
1349
|
-
}
|
|
1350
|
-
if (typeof obj.path === "string") {
|
|
1351
|
-
return normalizePath(obj.path);
|
|
1352
|
-
}
|
|
1353
|
-
if (typeof obj.url === "string") {
|
|
1354
|
-
return escapeGlob(obj.url);
|
|
1355
|
-
}
|
|
1356
|
-
if (typeof obj.name === "string") {
|
|
1357
|
-
return escapeGlob(obj.name);
|
|
1358
|
-
}
|
|
1359
|
-
return void 0;
|
|
1360
|
-
}
|
|
1361
1387
|
findNamespaceEntry(toolName) {
|
|
1362
1388
|
for (const { pattern, value } of this.wildcardEntries) {
|
|
1363
1389
|
if (matchGlob(pattern, toolName)) return value;
|
|
@@ -1380,9 +1406,13 @@ var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
|
|
|
1380
1406
|
const caps = tool.capabilities ?? [];
|
|
1381
1407
|
const hasAllowedCap = caps.some((c) => this.allowedCapabilities.includes(c));
|
|
1382
1408
|
const isMcp = _AutoApprovePermissionPolicy.isMcpTool(tool.name);
|
|
1383
|
-
const
|
|
1409
|
+
const mcpProxyAllowed = this.allowedCapabilities.includes(ToolCapabilities.MCP_PROXY);
|
|
1410
|
+
const dangerousNotAllowed = getDangerousCapabilities(tool).filter(
|
|
1411
|
+
(c) => !this.allowedCapabilities.includes(c)
|
|
1412
|
+
);
|
|
1413
|
+
const blocked = tool.permission === "deny" || isMcp && !mcpProxyAllowed || !hasAllowedCap || dangerousNotAllowed.length > 0;
|
|
1384
1414
|
if (blocked) {
|
|
1385
|
-
const reason = isMcp ? `MCP tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow
|
|
1415
|
+
const reason = isMcp && !mcpProxyAllowed ? `MCP tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow mcp.proxy 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
1416
|
return {
|
|
1387
1417
|
permission: "deny",
|
|
1388
1418
|
source: "subagent_guard",
|