@wrongstack/core 0.54.1 → 0.66.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/{agent-bridge-Dnhw4tnM.d.ts → agent-bridge-D-j6OOBT.d.ts} +1 -1
  2. package/dist/agent-subagent-runner-DRZ9-NnR.d.ts +1042 -0
  3. package/dist/{compactor-Duhsf0ge.d.ts → compactor-D_ExJajC.d.ts} +1 -1
  4. package/dist/{config-bht0txXS.d.ts → config--86aHSln.d.ts} +112 -2
  5. package/dist/{context-DtPKqKYV.d.ts → context-y87Jc5ei.d.ts} +8 -8
  6. package/dist/coordination/index.d.ts +12 -12
  7. package/dist/coordination/index.js +87 -69
  8. package/dist/coordination/index.js.map +1 -1
  9. package/dist/defaults/index.d.ts +22 -22
  10. package/dist/defaults/index.js +365 -174
  11. package/dist/defaults/index.js.map +1 -1
  12. package/dist/{events-CbHTS4ZZ.d.ts → events-CIplI98R.d.ts} +20 -1
  13. package/dist/execution/index.d.ts +16 -385
  14. package/dist/execution/index.js +129 -61
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/extension/index.d.ts +7 -7
  17. package/dist/goal-store-C7jcumEh.d.ts +96 -0
  18. package/dist/index-DKUvyTvV.d.ts +560 -0
  19. package/dist/{index-ge5F2dnc.d.ts → index-b5uhfTSl.d.ts} +10 -8
  20. package/dist/index.d.ts +59 -33
  21. package/dist/index.js +1138 -733
  22. package/dist/index.js.map +1 -1
  23. package/dist/infrastructure/index.d.ts +6 -6
  24. package/dist/infrastructure/index.js +1 -1
  25. package/dist/infrastructure/index.js.map +1 -1
  26. package/dist/kernel/index.d.ts +9 -9
  27. package/dist/kernel/index.js +3 -1
  28. package/dist/kernel/index.js.map +1 -1
  29. package/dist/{mcp-servers-DE6gzBry.d.ts → mcp-servers-DwoNBf6r.d.ts} +3 -3
  30. package/dist/models/index.d.ts +2 -2
  31. package/dist/{multi-agent-coordinator-CjNX4uBD.d.ts → multi-agent-coordinator-CWnH-CiX.d.ts} +10 -2
  32. package/dist/{null-fleet-bus-BNiSlTna.d.ts → null-fleet-bus-VApKRxcp.d.ts} +6 -7
  33. package/dist/observability/index.d.ts +2 -2
  34. package/dist/parallel-eternal-engine-0UwotoSx.d.ts +483 -0
  35. package/dist/{path-resolver-Bax85amb.d.ts → path-resolver-DVkEcIw8.d.ts} +2 -2
  36. package/dist/{permission-Drm7LpPo.d.ts → permission-C1A5whY5.d.ts} +17 -1
  37. package/dist/{permission-policy-CU6sqWxF.d.ts → permission-policy-B2dK-T5N.d.ts} +28 -7
  38. package/dist/{plan-templates-CLRcurWN.d.ts → plan-templates-Bprrzhbu.d.ts} +4 -4
  39. package/dist/{provider-runner-BikCxGCx.d.ts → provider-runner-mXvXGSIw.d.ts} +3 -3
  40. package/dist/{retry-policy-Chtlvr5b.d.ts → retry-policy-CG3qvH_e.d.ts} +1 -1
  41. package/dist/sdd/index.d.ts +9 -9
  42. package/dist/sdd/index.js +59 -52
  43. package/dist/sdd/index.js.map +1 -1
  44. package/dist/security/index.d.ts +3 -3
  45. package/dist/security/index.js +144 -33
  46. package/dist/security/index.js.map +1 -1
  47. package/dist/{selector-BvSPdJj6.d.ts → selector-RvBR_YRW.d.ts} +1 -1
  48. package/dist/session-event-bridge-CDHxcmQU.d.ts +93 -0
  49. package/dist/{session-reader-BGhzMir4.d.ts → session-reader-BIpwM60D.d.ts} +1 -1
  50. package/dist/storage/index.d.ts +7 -6
  51. package/dist/{system-prompt-dtzV_mLm.d.ts → system-prompt-b61lOd49.d.ts} +32 -2
  52. package/dist/types/index.d.ts +23 -14
  53. package/dist/types/index.js +62 -6
  54. package/dist/types/index.js.map +1 -1
  55. package/dist/utils/index.d.ts +2 -2
  56. package/dist/utils/index.js.map +1 -1
  57. package/package.json +1 -1
  58. package/skills/multi-agent/SKILL.md +0 -2
  59. package/dist/agent-subagent-runner-By7jruZ_.d.ts +0 -182
  60. package/dist/goal-store-DwcTDDiX.d.ts +0 -188
  61. package/dist/index-CI271MjL.d.ts +0 -903
  62. package/dist/multi-agent-BmC_xiog.d.ts +0 -554
  63. package/dist/tool-executor-CgU0yWpB.d.ts +0 -110
@@ -1,10 +1,10 @@
1
1
  export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-scrubber-7rSC_emZ.js';
2
- export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-CU6sqWxF.js';
2
+ export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-B2dK-T5N.js';
3
3
  import '../secret-vault-DoISxaKO.js';
4
4
  import '../secret-scrubber-3MHDDAtm.js';
5
- import '../context-DtPKqKYV.js';
5
+ import '../context-y87Jc5ei.js';
6
6
  import '../input-reader-E-ffP2ee.js';
7
- import '../permission-Drm7LpPo.js';
7
+ import '../permission-C1A5whY5.js';
8
8
 
9
9
  declare function isSecretField(name: string): boolean;
10
10
 
@@ -1,7 +1,7 @@
1
1
  import { randomBytes, createCipheriv, createDecipheriv } from 'crypto';
2
2
  import * as fs2 from 'fs';
3
3
  import * as fs from 'fs/promises';
4
- import * as path from 'path';
4
+ import * as path3 from 'path';
5
5
 
6
6
  // src/security/secret-scrubber.ts
7
7
  var PATTERNS = [
@@ -113,9 +113,9 @@ var DefaultSecretScrubber = class {
113
113
  // src/types/secret-vault.ts
114
114
  var ENCRYPTED_PREFIX = "enc:v1:";
115
115
  async function atomicWrite(targetPath, content, opts = {}) {
116
- const dir = path.dirname(targetPath);
116
+ const dir = path3.dirname(targetPath);
117
117
  await fs.mkdir(dir, { recursive: true });
118
- const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
118
+ const tmp = path3.join(dir, `.${path3.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
119
119
  try {
120
120
  if (typeof content === "string") {
121
121
  await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
@@ -168,7 +168,7 @@ async function renameWithRetry(from, to) {
168
168
  if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
169
169
  throw err;
170
170
  }
171
- await new Promise((resolve) => setTimeout(resolve, delays[i]));
171
+ await new Promise((resolve2) => setTimeout(resolve2, delays[i]));
172
172
  }
173
173
  }
174
174
  throw lastErr;
@@ -230,7 +230,7 @@ var DefaultSecretVault = class {
230
230
  } catch (err) {
231
231
  if (err.code !== "ENOENT") throw err;
232
232
  }
233
- fs2.mkdirSync(path.dirname(this.keyFile), { recursive: true });
233
+ fs2.mkdirSync(path3.dirname(this.keyFile), { recursive: true });
234
234
  const key = randomBytes(KEY_BYTES);
235
235
  try {
236
236
  fs2.writeFileSync(this.keyFile, key, { mode: 384, flag: "wx" });
@@ -299,7 +299,7 @@ async function rewriteConfigEncrypted(configPath, vault, patch) {
299
299
  }
300
300
  const merged = deepMerge(current, patch ?? {});
301
301
  const encrypted = encryptConfigSecrets(merged, vault);
302
- await fs.mkdir(path.dirname(configPath), { recursive: true });
302
+ await fs.mkdir(path3.dirname(configPath), { recursive: true });
303
303
  await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
304
304
  await restrictFilePermissions(configPath);
305
305
  }
@@ -535,6 +535,87 @@ function safeParse(input, maxBytes = 5e6) {
535
535
  };
536
536
  }
537
537
  }
538
+ var DESTRUCTIVE_BASH_PATTERNS = [
539
+ /\bgit\s+(?:clean\s+-[^\s]*[xdf]|reset\s+--hard)\b/i,
540
+ /\b(?:drop|truncate)\s+(?:table|database|schema)\b/i,
541
+ /\bdelete\s+from\b/i,
542
+ /\b(?:mkfs|format|diskpart|shutdown|reboot)\b/i,
543
+ /\bchmod\s+-R\s+777\b/i,
544
+ /\bchown\s+-R\b/i,
545
+ /\b(?:curl|wget)\b.*\|\s*(?:sh|bash|zsh|pwsh|powershell)\b/i,
546
+ /\b(?:powershell|pwsh)\b.*(?:-encodedcommand|-enc)\b/i,
547
+ /:\(\)\s*\{\s*:\|:&\s*}\s*;/
548
+ ];
549
+ var PROJECT_ESCAPE_PATTERN = /(?:^|[\s"'])\.\.(?:[\\/]|$)/;
550
+ var ABSOLUTE_PATH_PATTERN = /(?:^|[\s"'])(?:~[\\/]|\/[A-Za-z0-9_.-]|[A-Za-z]:[\\/])/;
551
+ var SHELL_OPERATORS = /* @__PURE__ */ new Set(["&&", "||", "|", ";", ">", ">>", "<", "2>", "2>>"]);
552
+ function getInputString(input, key) {
553
+ if (!input || typeof input !== "object") return void 0;
554
+ const value = input[key];
555
+ return typeof value === "string" ? value : void 0;
556
+ }
557
+ function pathLooksInsideProject(rawPath, projectRoot) {
558
+ if (!projectRoot) return false;
559
+ if (rawPath === "~" || rawPath.startsWith("~/") || rawPath.startsWith("~\\")) return false;
560
+ const resolved = path3.resolve(projectRoot, rawPath);
561
+ const relative2 = path3.relative(projectRoot, resolved);
562
+ return !!relative2 && !relative2.startsWith("..") && !path3.isAbsolute(relative2);
563
+ }
564
+ function tokenizeShell(command) {
565
+ return command.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, "")) ?? [];
566
+ }
567
+ function pathTokenIsOutsideProject(token, projectRoot) {
568
+ if (!token || SHELL_OPERATORS.has(token) || token.startsWith("-")) return false;
569
+ if (token === "/" || token === "~" || token === "." || token === "..") return token !== ".";
570
+ if (token.includes("*")) return true;
571
+ if (token.startsWith("..") || token.includes("../") || token.includes("..\\")) return true;
572
+ if (path3.isAbsolute(token) || token.startsWith("~/")) return !pathLooksInsideProject(token, projectRoot);
573
+ return false;
574
+ }
575
+ function hasDangerousDeleteTarget(tokens, start, projectRoot) {
576
+ const targets = tokens.slice(start).filter((token) => !token.startsWith("-") && !SHELL_OPERATORS.has(token));
577
+ if (targets.length === 0) return true;
578
+ return targets.some((target) => pathTokenIsOutsideProject(target, projectRoot));
579
+ }
580
+ function hasDestructiveDelete(command, projectRoot) {
581
+ const tokens = tokenizeShell(command);
582
+ for (let i = 0; i < tokens.length; i++) {
583
+ const token = tokens[i]?.toLowerCase();
584
+ if (!token) continue;
585
+ if (token === "rm") {
586
+ const args = tokens.slice(i + 1);
587
+ const recursiveOrForce = args.some(
588
+ (arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force"
589
+ );
590
+ if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
591
+ }
592
+ if (token === "rmdir" || token === "rd") {
593
+ const args = tokens.slice(i + 1);
594
+ const recursive = args.some((arg) => arg.toLowerCase() === "/s");
595
+ if (recursive && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
596
+ }
597
+ if (token === "del" || token === "erase") {
598
+ if (hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
599
+ }
600
+ if (token === "remove-item") {
601
+ const args = tokens.slice(i + 1).map((arg) => arg.toLowerCase());
602
+ const recursiveOrForce = args.includes("-recurse") || args.includes("-force");
603
+ if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
604
+ }
605
+ }
606
+ return false;
607
+ }
608
+ function isClearlyDestructiveBashCommand(command, projectRoot) {
609
+ const trimmed = command.trim();
610
+ if (!trimmed) return false;
611
+ if (hasDestructiveDelete(trimmed, projectRoot)) return true;
612
+ if (DESTRUCTIVE_BASH_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
613
+ if (/\bcd\s+(?:\.\.|~|\/|[A-Za-z]:[\\/])/i.test(trimmed)) return true;
614
+ if (PROJECT_ESCAPE_PATTERN.test(trimmed)) return true;
615
+ const absolute = trimmed.match(ABSOLUTE_PATH_PATTERN)?.[0]?.trim().replace(/^['"]|['"]$/g, "");
616
+ if (absolute && !pathLooksInsideProject(absolute, projectRoot)) return true;
617
+ return false;
618
+ }
538
619
 
539
620
  // src/security/permission-policy.ts
540
621
  var DefaultPermissionPolicy = class {
@@ -542,7 +623,9 @@ var DefaultPermissionPolicy = class {
542
623
  loaded = false;
543
624
  trustFile;
544
625
  yolo;
545
- forceAllYolo;
626
+ yoloDestructive;
627
+ /** When true, destructive ops still require confirmation even in YOLO mode. */
628
+ confirmDestructive;
546
629
  /**
547
630
  * Session-scoped "soft deny" map. When the user presses 'n' (block once),
548
631
  * the tool+pattern is added here. If the LLM retries in the same session,
@@ -575,7 +658,8 @@ var DefaultPermissionPolicy = class {
575
658
  constructor(opts) {
576
659
  this.trustFile = opts.trustFile;
577
660
  this.yolo = opts.yolo ?? false;
578
- this.forceAllYolo = opts.forceAllYolo ?? false;
661
+ this.yoloDestructive = opts.yoloDestructive ?? opts.forceAllYolo ?? false;
662
+ this.confirmDestructive = opts.confirmDestructive ?? false;
579
663
  this.promptDelegate = opts.promptDelegate;
580
664
  }
581
665
  /**
@@ -595,13 +679,29 @@ var DefaultPermissionPolicy = class {
595
679
  getYolo() {
596
680
  return this.yolo;
597
681
  }
598
- /** Toggle force-all-YOLO at runtime. */
682
+ /** Toggle the destructive YOLO override at runtime. */
683
+ setYoloDestructive(enabled) {
684
+ this.yoloDestructive = enabled;
685
+ }
686
+ /** Check whether the destructive YOLO override is active. */
687
+ getYoloDestructive() {
688
+ return this.yoloDestructive;
689
+ }
690
+ /** Toggle destructive confirmation gate (only meaningful when yolo is active). */
691
+ setConfirmDestructive(enabled) {
692
+ this.confirmDestructive = enabled;
693
+ }
694
+ /** Check whether destructive confirmation gate is active. */
695
+ getConfirmDestructive() {
696
+ return this.confirmDestructive;
697
+ }
698
+ /** @deprecated Use `setYoloDestructive`. */
599
699
  setForceAllYolo(enabled) {
600
- this.forceAllYolo = enabled;
700
+ this.setYoloDestructive(enabled);
601
701
  }
602
- /** Check whether force-all-YOLO is active. */
702
+ /** @deprecated Use `getYoloDestructive`. */
603
703
  getForceAllYolo() {
604
- return this.forceAllYolo;
704
+ return this.getYoloDestructive();
605
705
  }
606
706
  async reload() {
607
707
  try {
@@ -648,29 +748,28 @@ var DefaultPermissionPolicy = class {
648
748
  return { permission: "auto", source: "trust" };
649
749
  }
650
750
  if (this.yolo) {
651
- if (tool.riskTier === "destructive" && !this.forceAllYolo) {
652
- if (this.promptDelegate) {
653
- const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
654
- if (decision === "always") {
655
- await this.trust({ tool: tool.name, pattern: subject ?? tool.name });
656
- return {
657
- permission: "auto",
658
- source: "user",
659
- reason: "destructive yolo always-allowed"
660
- };
751
+ if (this.confirmDestructive) {
752
+ const destructive = this.isDestructiveYoloCall(tool, input, ctx);
753
+ if (destructive) {
754
+ if (this.promptDelegate) {
755
+ const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
756
+ if (decision === "always") {
757
+ await this.trust({ tool: tool.name, pattern: subject ?? tool.name });
758
+ return { permission: "auto", source: "user", reason: "destructive yolo always-allowed" };
759
+ }
760
+ if (decision === "deny") {
761
+ await this.deny({ tool: tool.name, pattern: subject ?? tool.name });
762
+ return { permission: "deny", source: "user", reason: "user denied destructive yolo" };
763
+ }
764
+ return { permission: decision === "yes" ? "auto" : "deny", source: "user" };
661
765
  }
662
- if (decision === "deny") {
663
- await this.deny({ tool: tool.name, pattern: subject ?? tool.name });
664
- return { permission: "deny", source: "user", reason: "user denied destructive yolo" };
665
- }
666
- return { permission: decision === "yes" ? "auto" : "deny", source: "user" };
766
+ return {
767
+ permission: "confirm",
768
+ source: "yolo_destructive",
769
+ riskTier: "destructive",
770
+ reason: "destructive tool needs explicit approval (confirmDestructive is on)"
771
+ };
667
772
  }
668
- return {
669
- permission: "confirm",
670
- source: "yolo_destructive",
671
- riskTier: "destructive",
672
- reason: "destructive tool needs explicit approval even in yolo mode"
673
- };
674
773
  }
675
774
  return { permission: "auto", source: "yolo" };
676
775
  }
@@ -700,6 +799,18 @@ var DefaultPermissionPolicy = class {
700
799
  }
701
800
  return { permission: "confirm", source: "default" };
702
801
  }
802
+ isDestructiveYoloCall(tool, input, ctx) {
803
+ if (tool.name === "bash") {
804
+ const command = getInputString(input, "command");
805
+ return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;
806
+ }
807
+ if (tool.name === "write" || tool.name === "edit" || tool.name === "replace" || tool.name === "patch") {
808
+ const targetPath = getInputString(input, "path") ?? getInputString(input, "file");
809
+ if (!targetPath || !ctx.projectRoot) return false;
810
+ return !pathLooksInsideProject(targetPath, ctx.projectRoot);
811
+ }
812
+ return tool.riskTier === "destructive";
813
+ }
703
814
  async trust(rule) {
704
815
  if (!this.loaded) await this.reload();
705
816
  const entry = this.policy[rule.tool] ?? {};