@wrongstack/core 0.54.1 → 0.63.4

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 (54) hide show
  1. package/dist/{agent-bridge-Dnhw4tnM.d.ts → agent-bridge-B5rxWrg3.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-By7jruZ_.d.ts → agent-subagent-runner-Zc3f37Sg.d.ts} +3 -3
  3. package/dist/{compactor-Duhsf0ge.d.ts → compactor-0vjZ8KTk.d.ts} +1 -1
  4. package/dist/{config-bht0txXS.d.ts → config-BdDuaZmB.d.ts} +112 -2
  5. package/dist/{context-DtPKqKYV.d.ts → context-iFMEO2rN.d.ts} +8 -8
  6. package/dist/coordination/index.d.ts +12 -12
  7. package/dist/defaults/index.d.ts +21 -21
  8. package/dist/defaults/index.js +254 -92
  9. package/dist/defaults/index.js.map +1 -1
  10. package/dist/{events-CbHTS4ZZ.d.ts → events-k8CHjcrN.d.ts} +20 -1
  11. package/dist/execution/index.d.ts +14 -14
  12. package/dist/execution/index.js +70 -10
  13. package/dist/execution/index.js.map +1 -1
  14. package/dist/extension/index.d.ts +7 -7
  15. package/dist/{goal-store-DwcTDDiX.d.ts → goal-store-iHltMi5n.d.ts} +1 -1
  16. package/dist/{index-CI271MjL.d.ts → index-Bc6BiP5q.d.ts} +77 -6
  17. package/dist/{index-ge5F2dnc.d.ts → index-CWdW_CJt.d.ts} +10 -8
  18. package/dist/index.d.ts +56 -32
  19. package/dist/index.js +520 -85
  20. package/dist/index.js.map +1 -1
  21. package/dist/infrastructure/index.d.ts +6 -6
  22. package/dist/infrastructure/index.js +1 -1
  23. package/dist/infrastructure/index.js.map +1 -1
  24. package/dist/kernel/index.d.ts +9 -9
  25. package/dist/kernel/index.js +3 -1
  26. package/dist/kernel/index.js.map +1 -1
  27. package/dist/{mcp-servers-DE6gzBry.d.ts → mcp-servers-CwqQDMYy.d.ts} +3 -3
  28. package/dist/models/index.d.ts +2 -2
  29. package/dist/{multi-agent-BmC_xiog.d.ts → multi-agent-SASYOrWA.d.ts} +2 -2
  30. package/dist/{multi-agent-coordinator-CjNX4uBD.d.ts → multi-agent-coordinator-CNUJYq7U.d.ts} +2 -2
  31. package/dist/{null-fleet-bus-BNiSlTna.d.ts → null-fleet-bus-DRoJ0uOY.d.ts} +7 -7
  32. package/dist/observability/index.d.ts +2 -2
  33. package/dist/{path-resolver-Bax85amb.d.ts → path-resolver-C5sPVne8.d.ts} +2 -2
  34. package/dist/{permission-Drm7LpPo.d.ts → permission-Ld-i5ugf.d.ts} +13 -1
  35. package/dist/{permission-policy-CU6sqWxF.d.ts → permission-policy-CL-mPufp.d.ts} +14 -7
  36. package/dist/{plan-templates-CLRcurWN.d.ts → plan-templates-ThBHOjaM.d.ts} +4 -4
  37. package/dist/{provider-runner-BikCxGCx.d.ts → provider-runner-DJQa211J.d.ts} +3 -3
  38. package/dist/{retry-policy-Chtlvr5b.d.ts → retry-policy-BfBScewS.d.ts} +1 -1
  39. package/dist/sdd/index.d.ts +9 -9
  40. package/dist/sdd/index.js +1 -1
  41. package/dist/sdd/index.js.map +1 -1
  42. package/dist/security/index.d.ts +3 -3
  43. package/dist/security/index.js +115 -13
  44. package/dist/security/index.js.map +1 -1
  45. package/dist/{selector-BvSPdJj6.d.ts → selector-DxhW7ML3.d.ts} +1 -1
  46. package/dist/{session-reader-BGhzMir4.d.ts → session-reader-q2ThszgG.d.ts} +1 -1
  47. package/dist/storage/index.d.ts +6 -6
  48. package/dist/{system-prompt-dtzV_mLm.d.ts → system-prompt-7LHyBbIf.d.ts} +32 -2
  49. package/dist/{tool-executor-CgU0yWpB.d.ts → tool-executor-CIjpGaRA.d.ts} +5 -4
  50. package/dist/types/index.d.ts +14 -14
  51. package/dist/types/index.js +62 -6
  52. package/dist/types/index.js.map +1 -1
  53. package/dist/utils/index.d.ts +2 -2
  54. package/package.json +1 -1
@@ -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-CL-mPufp.js';
3
3
  import '../secret-vault-DoISxaKO.js';
4
4
  import '../secret-scrubber-3MHDDAtm.js';
5
- import '../context-DtPKqKYV.js';
5
+ import '../context-iFMEO2rN.js';
6
6
  import '../input-reader-E-ffP2ee.js';
7
- import '../permission-Drm7LpPo.js';
7
+ import '../permission-Ld-i5ugf.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,7 @@ var DefaultPermissionPolicy = class {
542
623
  loaded = false;
543
624
  trustFile;
544
625
  yolo;
545
- forceAllYolo;
626
+ yoloDestructive;
546
627
  /**
547
628
  * Session-scoped "soft deny" map. When the user presses 'n' (block once),
548
629
  * the tool+pattern is added here. If the LLM retries in the same session,
@@ -575,7 +656,7 @@ var DefaultPermissionPolicy = class {
575
656
  constructor(opts) {
576
657
  this.trustFile = opts.trustFile;
577
658
  this.yolo = opts.yolo ?? false;
578
- this.forceAllYolo = opts.forceAllYolo ?? false;
659
+ this.yoloDestructive = opts.yoloDestructive ?? opts.forceAllYolo ?? false;
579
660
  this.promptDelegate = opts.promptDelegate;
580
661
  }
581
662
  /**
@@ -595,13 +676,21 @@ var DefaultPermissionPolicy = class {
595
676
  getYolo() {
596
677
  return this.yolo;
597
678
  }
598
- /** Toggle force-all-YOLO at runtime. */
679
+ /** Toggle the destructive YOLO override at runtime. */
680
+ setYoloDestructive(enabled) {
681
+ this.yoloDestructive = enabled;
682
+ }
683
+ /** Check whether the destructive YOLO override is active. */
684
+ getYoloDestructive() {
685
+ return this.yoloDestructive;
686
+ }
687
+ /** @deprecated Use `setYoloDestructive`. */
599
688
  setForceAllYolo(enabled) {
600
- this.forceAllYolo = enabled;
689
+ this.setYoloDestructive(enabled);
601
690
  }
602
- /** Check whether force-all-YOLO is active. */
691
+ /** @deprecated Use `getYoloDestructive`. */
603
692
  getForceAllYolo() {
604
- return this.forceAllYolo;
693
+ return this.getYoloDestructive();
605
694
  }
606
695
  async reload() {
607
696
  try {
@@ -648,7 +737,8 @@ var DefaultPermissionPolicy = class {
648
737
  return { permission: "auto", source: "trust" };
649
738
  }
650
739
  if (this.yolo) {
651
- if (tool.riskTier === "destructive" && !this.forceAllYolo) {
740
+ const destructive = this.isDestructiveYoloCall(tool, input, ctx);
741
+ if (destructive && !this.yoloDestructive) {
652
742
  if (this.promptDelegate) {
653
743
  const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
654
744
  if (decision === "always") {
@@ -700,6 +790,18 @@ var DefaultPermissionPolicy = class {
700
790
  }
701
791
  return { permission: "confirm", source: "default" };
702
792
  }
793
+ isDestructiveYoloCall(tool, input, ctx) {
794
+ if (tool.name === "bash") {
795
+ const command = getInputString(input, "command");
796
+ return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;
797
+ }
798
+ if (tool.name === "write" || tool.name === "edit" || tool.name === "replace" || tool.name === "patch") {
799
+ const targetPath = getInputString(input, "path") ?? getInputString(input, "file");
800
+ if (!targetPath || !ctx.projectRoot) return false;
801
+ return !pathLooksInsideProject(targetPath, ctx.projectRoot);
802
+ }
803
+ return tool.riskTier === "destructive";
804
+ }
703
805
  async trust(rule) {
704
806
  if (!this.loaded) await this.reload();
705
807
  const entry = this.policy[rule.tool] ?? {};