@wrongstack/core 0.5.7 → 0.6.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 (38) hide show
  1. package/dist/coordination/index.d.ts +2 -2
  2. package/dist/coordination/index.js +40 -24
  3. package/dist/coordination/index.js.map +1 -1
  4. package/dist/defaults/index.d.ts +6 -5
  5. package/dist/defaults/index.js +608 -120
  6. package/dist/defaults/index.js.map +1 -1
  7. package/dist/execution/index.d.ts +136 -3
  8. package/dist/execution/index.js +455 -2
  9. package/dist/execution/index.js.map +1 -1
  10. package/dist/extension/index.d.ts +1 -1
  11. package/dist/extension/index.js +2 -1
  12. package/dist/extension/index.js.map +1 -1
  13. package/dist/goal-store-BQ3YX1h1.d.ts +75 -0
  14. package/dist/{index-j2WyAyML.d.ts → index-B0qTujQW.d.ts} +33 -1
  15. package/dist/{index-Bf9Bpkdc.d.ts → index-DkdRz6yK.d.ts} +1 -1
  16. package/dist/index.d.ts +8 -7
  17. package/dist/index.js +739 -163
  18. package/dist/index.js.map +1 -1
  19. package/dist/models/index.js +2 -3
  20. package/dist/models/index.js.map +1 -1
  21. package/dist/{plan-templates-Bveo2W8n.d.ts → plan-templates-CKJs_sYh.d.ts} +5 -4
  22. package/dist/sdd/index.d.ts +3 -1
  23. package/dist/sdd/index.js +102 -68
  24. package/dist/sdd/index.js.map +1 -1
  25. package/dist/security/index.js +82 -82
  26. package/dist/security/index.js.map +1 -1
  27. package/dist/skills/index.js +102 -38
  28. package/dist/skills/index.js.map +1 -1
  29. package/dist/storage/index.d.ts +2 -1
  30. package/dist/storage/index.js +131 -22
  31. package/dist/storage/index.js.map +1 -1
  32. package/dist/{tool-executor-DbAFkHdP.d.ts → tool-executor-B03CRwu-.d.ts} +1 -1
  33. package/dist/types/index.d.ts +2 -2
  34. package/dist/types/index.js +100 -102
  35. package/dist/types/index.js.map +1 -1
  36. package/dist/utils/index.js +5 -0
  37. package/dist/utils/index.js.map +1 -1
  38. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,23 +1,109 @@
1
1
  import * as crypto2 from 'crypto';
2
2
  import { randomBytes, createCipheriv, createDecipheriv, randomUUID, createHash } from 'crypto';
3
- import * as fs from 'fs';
4
3
  import * as fsp2 from 'fs/promises';
5
- import { readFile, readdir, writeFile, stat, mkdir } from 'fs/promises';
4
+ import { readFile, readdir, stat, mkdir } from 'fs/promises';
6
5
  import * as path6 from 'path';
7
6
  import { join, extname, relative } from 'path';
7
+ import * as fs2 from 'fs';
8
8
  import * as os4 from 'os';
9
+ import { execFile, spawn } from 'child_process';
10
+ import { promisify } from 'util';
9
11
  import { EventEmitter } from 'events';
10
12
  import { createGunzip } from 'zlib';
11
13
  import { Readable } from 'stream';
12
14
  import { pipeline } from 'stream/promises';
13
- import { spawn } from 'child_process';
14
15
 
16
+ var __defProp = Object.defineProperty;
17
+ var __getOwnPropNames = Object.getOwnPropertyNames;
15
18
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
16
19
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
17
20
  }) : x)(function(x) {
18
21
  if (typeof require !== "undefined") return require.apply(this, arguments);
19
22
  throw Error('Dynamic require of "' + x + '" is not supported');
20
23
  });
24
+ var __esm = (fn, res) => function __init() {
25
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
26
+ };
27
+ var __export = (target, all) => {
28
+ for (var name in all)
29
+ __defProp(target, name, { get: all[name], enumerable: true });
30
+ };
31
+
32
+ // src/utils/atomic-write.ts
33
+ var atomic_write_exports = {};
34
+ __export(atomic_write_exports, {
35
+ atomicWrite: () => atomicWrite,
36
+ ensureDir: () => ensureDir
37
+ });
38
+ async function atomicWrite(targetPath, content, opts = {}) {
39
+ const dir = path6.dirname(targetPath);
40
+ await fsp2.mkdir(dir, { recursive: true });
41
+ const tmp = path6.join(dir, `.${path6.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
42
+ try {
43
+ if (typeof content === "string") {
44
+ await fsp2.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
45
+ } else {
46
+ await fsp2.writeFile(tmp, content, { flag: "wx" });
47
+ }
48
+ try {
49
+ const fh = await fsp2.open(tmp, "r+");
50
+ try {
51
+ await fh.sync();
52
+ } finally {
53
+ await fh.close();
54
+ }
55
+ } catch {
56
+ }
57
+ let mode;
58
+ try {
59
+ const stat8 = await fsp2.stat(targetPath);
60
+ mode = stat8.mode & 511;
61
+ } catch {
62
+ mode = opts.mode;
63
+ }
64
+ if (mode !== void 0) {
65
+ await fsp2.chmod(tmp, mode);
66
+ }
67
+ await renameWithRetry(tmp, targetPath);
68
+ } catch (err) {
69
+ try {
70
+ await fsp2.unlink(tmp);
71
+ } catch {
72
+ }
73
+ throw err;
74
+ }
75
+ }
76
+ async function ensureDir(dir) {
77
+ await fsp2.mkdir(dir, { recursive: true });
78
+ }
79
+ async function renameWithRetry(from, to) {
80
+ if (process.platform !== "win32") {
81
+ await fsp2.rename(from, to);
82
+ return;
83
+ }
84
+ const delays = [10, 25, 60, 120, 250];
85
+ let lastErr;
86
+ for (let i = 0; i <= delays.length; i++) {
87
+ try {
88
+ await fsp2.rename(from, to);
89
+ return;
90
+ } catch (err) {
91
+ lastErr = err;
92
+ const code = err?.code;
93
+ if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
94
+ throw err;
95
+ }
96
+ await new Promise((resolve5) => setTimeout(resolve5, delays[i]));
97
+ }
98
+ }
99
+ throw lastErr;
100
+ }
101
+ var TRANSIENT_RENAME_CODES;
102
+ var init_atomic_write = __esm({
103
+ "src/utils/atomic-write.ts"() {
104
+ TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
105
+ }
106
+ });
21
107
 
22
108
  // src/types/errors.ts
23
109
  var WrongStackError = class extends Error {
@@ -823,6 +909,7 @@ function providerStatusToCode(status, type) {
823
909
  var ENCRYPTED_PREFIX = "enc:v1:";
824
910
 
825
911
  // src/security/secret-vault.ts
912
+ init_atomic_write();
826
913
  var KEY_BYTES = 32;
827
914
  var IV_BYTES = 12;
828
915
  var TAG_BYTES = 16;
@@ -867,7 +954,7 @@ var DefaultSecretVault = class {
867
954
  loadOrCreateKey() {
868
955
  if (this.key) return this.key;
869
956
  try {
870
- const buf = fs.readFileSync(this.keyFile);
957
+ const buf = fs2.readFileSync(this.keyFile);
871
958
  if (buf.length !== KEY_BYTES) {
872
959
  throw new Error(`SecretVault: key file ${this.keyFile} has wrong size`);
873
960
  }
@@ -876,13 +963,13 @@ var DefaultSecretVault = class {
876
963
  } catch (err) {
877
964
  if (err.code !== "ENOENT") throw err;
878
965
  }
879
- fs.mkdirSync(path6.dirname(this.keyFile), { recursive: true });
966
+ fs2.mkdirSync(path6.dirname(this.keyFile), { recursive: true });
880
967
  const key = randomBytes(KEY_BYTES);
881
968
  try {
882
- fs.writeFileSync(this.keyFile, key, { mode: 384, flag: "wx" });
969
+ fs2.writeFileSync(this.keyFile, key, { mode: 384, flag: "wx" });
883
970
  } catch (err) {
884
971
  if (err.code !== "EEXIST") throw err;
885
- const buf = fs.readFileSync(this.keyFile);
972
+ const buf = fs2.readFileSync(this.keyFile);
886
973
  if (buf.length !== KEY_BYTES) {
887
974
  throw new Error(`SecretVault: key file ${this.keyFile} has wrong size`);
888
975
  }
@@ -944,7 +1031,7 @@ async function rewriteConfigEncrypted(configPath, vault, patch) {
944
1031
  const merged = deepMerge(current, patch ?? {});
945
1032
  const encrypted = encryptConfigSecrets(merged, vault);
946
1033
  await fsp2.mkdir(path6.dirname(configPath), { recursive: true });
947
- await fsp2.writeFile(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
1034
+ await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
948
1035
  try {
949
1036
  await fsp2.chmod(configPath, 384);
950
1037
  } catch {
@@ -966,7 +1053,7 @@ async function migratePlaintextSecrets(configPath, vault) {
966
1053
  const counter = { n: 0 };
967
1054
  const migrated = walkCount(parsed, vault, counter);
968
1055
  if (counter.n === 0) return { migrated: 0, file: configPath };
969
- await fsp2.writeFile(configPath, JSON.stringify(migrated, null, 2), { mode: 384 });
1056
+ await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 384 });
970
1057
  try {
971
1058
  await fsp2.chmod(configPath, 384);
972
1059
  } catch {
@@ -1076,7 +1163,7 @@ var DefaultLogger = class _DefaultLogger {
1076
1163
  this.pretty = opts.pretty ?? true;
1077
1164
  if (this.file) {
1078
1165
  try {
1079
- fs.mkdirSync(path6.dirname(this.file), { recursive: true });
1166
+ fs2.mkdirSync(path6.dirname(this.file), { recursive: true });
1080
1167
  } catch {
1081
1168
  }
1082
1169
  }
@@ -1115,7 +1202,7 @@ var DefaultLogger = class _DefaultLogger {
1115
1202
  }
1116
1203
  if (this.file) {
1117
1204
  try {
1118
- fs.appendFileSync(this.file, `${JSON.stringify(entry)}
1205
+ fs2.appendFileSync(this.file, `${JSON.stringify(entry)}
1119
1206
  `);
1120
1207
  } catch {
1121
1208
  }
@@ -1597,7 +1684,7 @@ var DefaultPathResolver = class {
1597
1684
  while (dir !== root) {
1598
1685
  for (const marker of PROJECT_MARKERS) {
1599
1686
  try {
1600
- fs.accessSync(path6.join(dir, marker));
1687
+ fs2.accessSync(path6.join(dir, marker));
1601
1688
  return dir;
1602
1689
  } catch {
1603
1690
  }
@@ -1612,7 +1699,7 @@ var DefaultPathResolver = class {
1612
1699
  const abs = path6.isAbsolute(input) ? input : path6.resolve(this.cwd, input);
1613
1700
  let real;
1614
1701
  try {
1615
- real = fs.realpathSync(abs);
1702
+ real = fs2.realpathSync(abs);
1616
1703
  } catch {
1617
1704
  real = path6.normalize(abs);
1618
1705
  }
@@ -1666,7 +1753,7 @@ function buildRecoveryStrategies(opts) {
1666
1753
  async attempt(err) {
1667
1754
  if (!(err instanceof ProviderError) || err.status !== 429) return null;
1668
1755
  const delayMs = err.body?.retryAfterMs ?? 5e3;
1669
- const delay = Math.max(1e3, Math.min(delayMs, 6e4));
1756
+ const delay = Math.min(6e4, Math.max(1e3, delayMs));
1670
1757
  await new Promise((r) => setTimeout(r, delay));
1671
1758
  return { action: "retry", reason: "rate_limit_backoff" };
1672
1759
  }
@@ -1819,15 +1906,15 @@ var PATTERNS = [
1819
1906
  { type: "redis_uri", regex: /redis:\/\/[^\s"'`]+/g },
1820
1907
  {
1821
1908
  type: "bearer_token",
1822
- // Bounded at 512 chars to prevent catastrophic backtracking on adversarial input.
1823
- // Negative lookahead is a simple single-char check no backtracking risk.
1824
- regex: /(?<![A-Za-z0-9_.~+/-])Bearer\s+[A-Za-z0-9._~+/-]{20,512}=*(?![A-Za-z0-9_.~+/-])/g
1909
+ // Anchored with alternation instead of negative lookahead avoids V8
1910
+ // backtracking risk on adversarial input. Bounded at 512 chars.
1911
+ regex: /(?:^|[^A-Za-z0-9_.~+/-])Bearer\s+[A-Za-z0-9._~+/-]{20,512}=*(?:$|[^A-Za-z0-9_.~+/-])/g
1825
1912
  },
1826
1913
  {
1827
1914
  type: "high_entropy_env",
1828
- // Value bounded at 512 chars; negative lookahead simplified to avoid
1829
- // nested quantifier backtracking on adversarial input.
1830
- regex: /\b([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\s*[:=]\s*['"]?([A-Za-z0-9_/+=-]{20,512})['"]?/g
1915
+ // Anchored with alternation instead of lookbehind to avoid backtracking.
1916
+ // Value bounded at 512 chars.
1917
+ regex: /(?:^|\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\s*[:=]\s*['"]?([A-Za-z0-9_/+=-]{20,512})['"]?(?:\s|$)/g
1831
1918
  }
1832
1919
  ];
1833
1920
  var SCRUB_CHUNK_BYTES = 64 * 1024;
@@ -1879,72 +1966,9 @@ var DefaultSecretScrubber = class {
1879
1966
  return visit(obj);
1880
1967
  }
1881
1968
  };
1882
- async function atomicWrite(targetPath, content, opts = {}) {
1883
- const dir = path6.dirname(targetPath);
1884
- await fsp2.mkdir(dir, { recursive: true });
1885
- const tmp = path6.join(dir, `.${path6.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
1886
- try {
1887
- if (typeof content === "string") {
1888
- await fsp2.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
1889
- } else {
1890
- await fsp2.writeFile(tmp, content, { flag: "wx" });
1891
- }
1892
- try {
1893
- const fh = await fsp2.open(tmp, "r+");
1894
- try {
1895
- await fh.sync();
1896
- } finally {
1897
- await fh.close();
1898
- }
1899
- } catch {
1900
- }
1901
- let mode;
1902
- try {
1903
- const stat8 = await fsp2.stat(targetPath);
1904
- mode = stat8.mode & 511;
1905
- } catch {
1906
- mode = opts.mode;
1907
- }
1908
- if (mode !== void 0) {
1909
- await fsp2.chmod(tmp, mode);
1910
- }
1911
- await renameWithRetry(tmp, targetPath);
1912
- } catch (err) {
1913
- try {
1914
- await fsp2.unlink(tmp);
1915
- } catch {
1916
- }
1917
- throw err;
1918
- }
1919
- }
1920
- async function ensureDir(dir) {
1921
- await fsp2.mkdir(dir, { recursive: true });
1922
- }
1923
- var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
1924
- async function renameWithRetry(from, to) {
1925
- if (process.platform !== "win32") {
1926
- await fsp2.rename(from, to);
1927
- return;
1928
- }
1929
- const delays = [10, 25, 60, 120, 250];
1930
- let lastErr;
1931
- for (let i = 0; i <= delays.length; i++) {
1932
- try {
1933
- await fsp2.rename(from, to);
1934
- return;
1935
- } catch (err) {
1936
- lastErr = err;
1937
- const code = err?.code;
1938
- if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
1939
- throw err;
1940
- }
1941
- await new Promise((resolve5) => setTimeout(resolve5, delays[i]));
1942
- }
1943
- }
1944
- throw lastErr;
1945
- }
1946
1969
 
1947
1970
  // src/models/models-registry.ts
1971
+ init_atomic_write();
1948
1972
  var DEFAULT_URL = "https://models.dev/api.json";
1949
1973
  var DEFAULT_TTL_SECONDS = 24 * 3600;
1950
1974
  var FAMILY_BY_NPM = {
@@ -3297,6 +3321,9 @@ function renderPlainText(meta, events) {
3297
3321
  return lines.join("\n");
3298
3322
  }
3299
3323
 
3324
+ // src/utils/index.ts
3325
+ init_atomic_write();
3326
+
3300
3327
  // src/utils/safe-json.ts
3301
3328
  function safeParse(input, maxBytes = 5e6) {
3302
3329
  if (input.length > maxBytes) {
@@ -3725,6 +3752,11 @@ function looksSecret(name) {
3725
3752
  function buildChildEnv(optsOrSessionId) {
3726
3753
  const opts = typeof optsOrSessionId === "string" ? { sessionId: optsOrSessionId } : optsOrSessionId ?? {};
3727
3754
  const passthrough = process.env["WRONGSTACK_CHILD_ENV_PASSTHROUGH"] === "1" || process.env["WRONGSTACK_BASH_ENV_PASSTHROUGH"] === "1";
3755
+ if (passthrough && !process.env["CI"]) {
3756
+ console.warn(
3757
+ "[WrongStack] WARNING: WRONGSTACK_*_ENV_PASSTHROUGH=1 is active \u2014\n all parent env vars (including API keys) forwarded to child processes.\n Do not use on shared or multi-tenant systems."
3758
+ );
3759
+ }
3728
3760
  const out = {};
3729
3761
  for (const [k, v] of Object.entries(process.env)) {
3730
3762
  if (v === void 0) continue;
@@ -3755,11 +3787,11 @@ function validateAgainstSchema(value, schema) {
3755
3787
  walk2(value, schema, "", errors);
3756
3788
  return { ok: errors.length === 0, errors };
3757
3789
  }
3758
- function walk2(value, schema, path25, errors) {
3790
+ function walk2(value, schema, path26, errors) {
3759
3791
  if (schema.enum !== void 0) {
3760
3792
  if (!schema.enum.some((e) => deepEqual(e, value))) {
3761
3793
  errors.push({
3762
- path: path25 || "<root>",
3794
+ path: path26 || "<root>",
3763
3795
  message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
3764
3796
  });
3765
3797
  return;
@@ -3768,7 +3800,7 @@ function walk2(value, schema, path25, errors) {
3768
3800
  if (typeof schema.type === "string") {
3769
3801
  if (!checkType(value, schema.type)) {
3770
3802
  errors.push({
3771
- path: path25 || "<root>",
3803
+ path: path26 || "<root>",
3772
3804
  message: `expected ${schema.type}, got ${describeType(value)}`
3773
3805
  });
3774
3806
  return;
@@ -3778,19 +3810,19 @@ function walk2(value, schema, path25, errors) {
3778
3810
  const obj = value;
3779
3811
  for (const req of schema.required ?? []) {
3780
3812
  if (!(req in obj)) {
3781
- errors.push({ path: joinPath(path25, req), message: "required property missing" });
3813
+ errors.push({ path: joinPath(path26, req), message: "required property missing" });
3782
3814
  }
3783
3815
  }
3784
3816
  if (schema.properties) {
3785
3817
  for (const [key, subSchema] of Object.entries(schema.properties)) {
3786
3818
  if (key in obj) {
3787
- walk2(obj[key], subSchema, joinPath(path25, key), errors);
3819
+ walk2(obj[key], subSchema, joinPath(path26, key), errors);
3788
3820
  }
3789
3821
  }
3790
3822
  }
3791
3823
  }
3792
3824
  if (schema.type === "array" && Array.isArray(value) && schema.items) {
3793
- value.forEach((item, i) => walk2(item, schema.items, `${path25}[${i}]`, errors));
3825
+ value.forEach((item, i) => walk2(item, schema.items, `${path26}[${i}]`, errors));
3794
3826
  }
3795
3827
  }
3796
3828
  function checkType(value, type) {
@@ -3842,6 +3874,9 @@ function deepEqual(a, b) {
3842
3874
  }
3843
3875
  return false;
3844
3876
  }
3877
+
3878
+ // src/storage/session-store.ts
3879
+ init_atomic_write();
3845
3880
  var DefaultSessionStore = class {
3846
3881
  dir;
3847
3882
  events;
@@ -3885,19 +3920,25 @@ var DefaultSessionStore = class {
3885
3920
  { cause: err }
3886
3921
  );
3887
3922
  }
3888
- const writer = new FileSessionWriter(
3889
- id,
3890
- handle,
3891
- (/* @__PURE__ */ new Date()).toISOString(),
3892
- {
3923
+ try {
3924
+ const writer = new FileSessionWriter(
3893
3925
  id,
3894
- model: data.metadata.model,
3895
- provider: data.metadata.provider
3896
- },
3897
- this.events,
3898
- { resumed: true, dir: this.dir, filePath: file }
3899
- );
3900
- return { writer, data };
3926
+ handle,
3927
+ (/* @__PURE__ */ new Date()).toISOString(),
3928
+ {
3929
+ id,
3930
+ model: data.metadata.model,
3931
+ provider: data.metadata.provider
3932
+ },
3933
+ this.events,
3934
+ { resumed: true, dir: this.dir, filePath: file }
3935
+ );
3936
+ return { writer, data };
3937
+ } catch (err) {
3938
+ await handle.close().catch(() => {
3939
+ });
3940
+ throw err;
3941
+ }
3901
3942
  }
3902
3943
  async load(id) {
3903
3944
  const file = path6.join(this.dir, `${id}.jsonl`);
@@ -3943,7 +3984,7 @@ var DefaultSessionStore = class {
3943
3984
  const full = path6.join(this.dir, `${id}.jsonl`);
3944
3985
  const stat8 = await fsp2.stat(full);
3945
3986
  const summary = await this.summarize(id, stat8.mtime.toISOString());
3946
- await fsp2.writeFile(manifest, JSON.stringify(summary), { mode: 384 }).catch((err) => {
3987
+ await atomicWrite(manifest, JSON.stringify(summary), { mode: 384 }).catch((err) => {
3947
3988
  console.warn(
3948
3989
  `[session-store] Failed to write manifest for "${id}":`,
3949
3990
  err instanceof Error ? err.message : String(err)
@@ -4171,7 +4212,7 @@ var FileSessionWriter = class {
4171
4212
  this.closed = true;
4172
4213
  if (this.manifestFile) {
4173
4214
  try {
4174
- await fsp2.writeFile(this.manifestFile, JSON.stringify(this.summary), { mode: 384 });
4215
+ await atomicWrite(this.manifestFile, JSON.stringify(this.summary), { mode: 384 });
4175
4216
  } catch {
4176
4217
  }
4177
4218
  }
@@ -4267,6 +4308,9 @@ function userInputTitle(content) {
4267
4308
  const text = content.filter((b) => b.type === "text").map((b) => b.text).join(" ");
4268
4309
  return (text || "(non-text input)").slice(0, 60);
4269
4310
  }
4311
+
4312
+ // src/storage/queue-store.ts
4313
+ init_atomic_write();
4270
4314
  var QueueStore = class {
4271
4315
  file;
4272
4316
  constructor(opts) {
@@ -4317,6 +4361,9 @@ function isPersistedQueueItem(v) {
4317
4361
  const o = v;
4318
4362
  return typeof o["displayText"] === "string" && Array.isArray(o["blocks"]);
4319
4363
  }
4364
+
4365
+ // src/storage/attachment-store.ts
4366
+ init_atomic_write();
4320
4367
  var DEFAULT_SPOOL_THRESHOLD = 256 * 1024;
4321
4368
  var PLACEHOLDER_RE = /\[(pasted|image|file) #(\d+)\]/g;
4322
4369
  var DefaultAttachmentStore = class {
@@ -4338,7 +4385,9 @@ var DefaultAttachmentStore = class {
4338
4385
  if (this.spoolDir && bytes >= this.spoolThreshold) {
4339
4386
  await fsp2.mkdir(this.spoolDir, { recursive: true });
4340
4387
  spooledPath = path6.join(this.spoolDir, `${id}.bin`);
4341
- await fsp2.writeFile(spooledPath, input.data, input.kind === "image" ? "base64" : "utf8");
4388
+ await atomicWrite(spooledPath, input.data, {
4389
+ encoding: input.kind === "image" ? "base64" : "utf8"
4390
+ });
4342
4391
  data = void 0;
4343
4392
  }
4344
4393
  const att = {
@@ -4437,6 +4486,9 @@ function mergeAdjacentText(blocks) {
4437
4486
  }
4438
4487
  return out;
4439
4488
  }
4489
+
4490
+ // src/storage/memory-store.ts
4491
+ init_atomic_write();
4440
4492
  var MAX_BYTES_TOTAL = 32e3;
4441
4493
  var DefaultMemoryStore = class {
4442
4494
  files;
@@ -4449,12 +4501,13 @@ var DefaultMemoryStore = class {
4449
4501
  * issue order. Different scopes still proceed in parallel.
4450
4502
  *
4451
4503
  * The chain tracks only the last pending write. If a write fails, its
4452
- * error is caught and swallowed (line 43) so the chain stays alive for
4453
- * subsequent calls. A crash between atomicWrite() and backup copy leaves
4454
- * the file at its new content with no backup — acceptable for an optional
4455
- * backup whose worst case is losing a memory consolidation pass.
4504
+ * error is caught and swallowed so the chain stays alive for subsequent
4505
+ * calls. The error is stored in `writeErrors` so callers can learn about
4506
+ * it on the next read operation.
4456
4507
  */
4457
4508
  writeChain = /* @__PURE__ */ new Map();
4509
+ /** Last write error per scope — surfaced as warnings on the next readAll(). */
4510
+ writeErrors = /* @__PURE__ */ new Map();
4458
4511
  constructor(opts) {
4459
4512
  this.files = {
4460
4513
  "project-agents": opts.paths.inProjectAgentsFile,
@@ -4464,10 +4517,16 @@ var DefaultMemoryStore = class {
4464
4517
  }
4465
4518
  async runSerialized(scope, work) {
4466
4519
  const prior = this.writeChain.get(scope) ?? Promise.resolve();
4520
+ prior.catch((err) => {
4521
+ this.writeErrors.set(scope, err);
4522
+ });
4467
4523
  const next = prior.catch(() => void 0).then(work);
4468
4524
  this.writeChain.set(scope, next);
4469
4525
  try {
4470
4526
  return await next;
4527
+ } catch (err) {
4528
+ this.writeErrors.set(scope, err);
4529
+ throw err;
4471
4530
  } finally {
4472
4531
  if (this.writeChain.get(scope) === next) {
4473
4532
  this.writeChain.delete(scope);
@@ -4477,6 +4536,10 @@ var DefaultMemoryStore = class {
4477
4536
  async readAll() {
4478
4537
  const parts = [];
4479
4538
  for (const scope of ["project-agents", "project-memory", "user-memory"]) {
4539
+ const writeErr = this.writeErrors.get(scope);
4540
+ if (writeErr) {
4541
+ parts.push(`> \u26A0\uFE0F Memory write error (${labelOf(scope)}): ${writeErr.message}`);
4542
+ }
4480
4543
  const body = await this.read(scope);
4481
4544
  if (body.trim()) parts.push(`## ${labelOf(scope)}
4482
4545
 
@@ -4969,6 +5032,9 @@ function runConfigMigrations(input, targetVersion, migrations) {
4969
5032
  return { config: current, applied, shouldPersist };
4970
5033
  }
4971
5034
  var DEFAULT_CONFIG_MIGRATIONS = [];
5035
+
5036
+ // src/storage/recovery-lock.ts
5037
+ init_atomic_write();
4972
5038
  var LOCK_FILE = "active.json";
4973
5039
  var DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
4974
5040
  var RecoveryLock = class {
@@ -5189,6 +5255,9 @@ var SessionAnalyzer = class {
5189
5255
  return last - first;
5190
5256
  }
5191
5257
  };
5258
+
5259
+ // src/storage/todos-checkpoint.ts
5260
+ init_atomic_write();
5192
5261
  async function loadTodosCheckpoint(filePath) {
5193
5262
  let raw;
5194
5263
  try {
@@ -5257,6 +5326,9 @@ function attachTodosCheckpoint(state, filePath, sessionId) {
5257
5326
  }
5258
5327
  };
5259
5328
  }
5329
+
5330
+ // src/storage/plan-store.ts
5331
+ init_atomic_write();
5260
5332
  async function loadPlan(filePath) {
5261
5333
  let raw;
5262
5334
  try {
@@ -5491,6 +5563,9 @@ ${cat}:`);
5491
5563
  }
5492
5564
  return lines.join("\n");
5493
5565
  }
5566
+
5567
+ // src/storage/director-state.ts
5568
+ init_atomic_write();
5494
5569
  async function loadDirectorState(filePath) {
5495
5570
  let raw;
5496
5571
  try {
@@ -5669,6 +5744,9 @@ var DirectorStateCheckpoint = class {
5669
5744
  }
5670
5745
  }
5671
5746
  };
5747
+
5748
+ // src/security/permission-policy.ts
5749
+ init_atomic_write();
5672
5750
  var DefaultPermissionPolicy = class {
5673
5751
  policy = {};
5674
5752
  loaded = false;
@@ -7190,6 +7268,452 @@ var AutonomousRunner = class {
7190
7268
  }
7191
7269
  };
7192
7270
 
7271
+ // src/storage/goal-store.ts
7272
+ init_atomic_write();
7273
+ var MAX_JOURNAL_ENTRIES = 500;
7274
+ function goalFilePath(projectRoot) {
7275
+ return path6.join(projectRoot, ".wrongstack", "goal.json");
7276
+ }
7277
+ async function loadGoal(filePath) {
7278
+ let raw;
7279
+ try {
7280
+ raw = await fsp2.readFile(filePath, "utf8");
7281
+ } catch {
7282
+ return null;
7283
+ }
7284
+ try {
7285
+ const parsed = JSON.parse(raw);
7286
+ if (parsed?.version !== 1 || typeof parsed.goal !== "string" || !Array.isArray(parsed.journal)) {
7287
+ return null;
7288
+ }
7289
+ return parsed;
7290
+ } catch {
7291
+ return null;
7292
+ }
7293
+ }
7294
+ async function saveGoal(filePath, goal) {
7295
+ await atomicWrite(filePath, JSON.stringify(goal, null, 2), { mode: 384 });
7296
+ }
7297
+ function emptyGoal(goal) {
7298
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7299
+ return {
7300
+ version: 1,
7301
+ goal,
7302
+ setAt: now,
7303
+ lastActivityAt: now,
7304
+ iterations: 0,
7305
+ engineState: "idle",
7306
+ journal: []
7307
+ };
7308
+ }
7309
+ function appendJournal(goal, entry) {
7310
+ const iteration = goal.iterations + 1;
7311
+ const at = (/* @__PURE__ */ new Date()).toISOString();
7312
+ const full = { ...entry, iteration, at };
7313
+ const journal = [...goal.journal, full];
7314
+ const trimmed = journal.length > MAX_JOURNAL_ENTRIES ? journal.slice(journal.length - MAX_JOURNAL_ENTRIES) : journal;
7315
+ return {
7316
+ ...goal,
7317
+ iterations: iteration,
7318
+ lastActivityAt: at,
7319
+ journal: trimmed
7320
+ };
7321
+ }
7322
+ function summarizeUsage(goal) {
7323
+ let totalCostUsd = 0;
7324
+ let totalInputTokens = 0;
7325
+ let totalOutputTokens = 0;
7326
+ let iterationsWithUsage = 0;
7327
+ for (const e of goal.journal) {
7328
+ if (typeof e.costUsd === "number") totalCostUsd += e.costUsd;
7329
+ if (e.tokens) {
7330
+ totalInputTokens += e.tokens.input;
7331
+ totalOutputTokens += e.tokens.output;
7332
+ }
7333
+ if (typeof e.costUsd === "number" || e.tokens) iterationsWithUsage++;
7334
+ }
7335
+ return { totalCostUsd, totalInputTokens, totalOutputTokens, iterationsWithUsage };
7336
+ }
7337
+ function formatGoal(goal, journalLimit = 10) {
7338
+ const lines = [];
7339
+ lines.push(`Goal: ${goal.goal}`);
7340
+ lines.push(`Set: ${goal.setAt}`);
7341
+ lines.push(`Last activity: ${goal.lastActivityAt}`);
7342
+ lines.push(`Iterations: ${goal.iterations}`);
7343
+ lines.push(`Engine: ${goal.engineState}`);
7344
+ const usage = summarizeUsage(goal);
7345
+ if (usage.iterationsWithUsage > 0) {
7346
+ lines.push(
7347
+ `Spent: $${usage.totalCostUsd.toFixed(4)} (in ${usage.totalInputTokens} / out ${usage.totalOutputTokens} tokens across ${usage.iterationsWithUsage} iterations)`
7348
+ );
7349
+ }
7350
+ if (goal.journal.length > 0) {
7351
+ lines.push("");
7352
+ lines.push(`Recent journal (last ${Math.min(journalLimit, goal.journal.length)}):`);
7353
+ const tail = goal.journal.slice(-journalLimit);
7354
+ for (const e of tail) {
7355
+ const mark = e.status === "success" ? "\u2713" : e.status === "failure" ? "\u2717" : e.status === "aborted" ? "\u2298" : "\xB7";
7356
+ const note = e.note ? ` \u2014 ${e.note}` : "";
7357
+ const cost = typeof e.costUsd === "number" ? ` ($${e.costUsd.toFixed(4)})` : "";
7358
+ lines.push(` #${e.iteration} ${mark} [${e.source}] ${e.task}${cost}${note}`);
7359
+ }
7360
+ }
7361
+ return lines.join("\n");
7362
+ }
7363
+
7364
+ // src/execution/eternal-autonomy.ts
7365
+ var execFileP = promisify(execFile);
7366
+ var EternalAutonomyEngine = class {
7367
+ constructor(opts) {
7368
+ this.opts = opts;
7369
+ this.goalPath = goalFilePath(opts.projectRoot);
7370
+ }
7371
+ opts;
7372
+ state = "idle";
7373
+ stopRequested = false;
7374
+ consecutiveFailures = 0;
7375
+ currentCtrl = null;
7376
+ iterationsSinceCompact = 0;
7377
+ goalPath;
7378
+ /** Current engine state — readable for UIs. */
7379
+ get currentState() {
7380
+ return this.state;
7381
+ }
7382
+ /** Synchronously request stop. Resolves once the running iteration aborts. */
7383
+ stop() {
7384
+ this.stopRequested = true;
7385
+ this.currentCtrl?.abort();
7386
+ void this.persistEngineState("stopped").catch(() => {
7387
+ });
7388
+ this.state = "stopped";
7389
+ }
7390
+ /**
7391
+ * Mark the engine as 'running' on disk + reset stop state so a new
7392
+ * batch of `runOneIteration()` calls can proceed. Called by the REPL
7393
+ * when the user invokes `/autonomy eternal`. Idempotent.
7394
+ */
7395
+ async prime() {
7396
+ this.stopRequested = false;
7397
+ this.state = "running";
7398
+ await this.persistEngineState("running").catch(() => {
7399
+ });
7400
+ }
7401
+ /**
7402
+ * Main loop. Returns when stop() is called or the goal file is removed.
7403
+ * Does NOT throw — every iteration is wrapped to keep the loop alive.
7404
+ */
7405
+ async run() {
7406
+ this.state = "running";
7407
+ await this.persistEngineState("running");
7408
+ try {
7409
+ while (!this.stopRequested) {
7410
+ let iterationOk = false;
7411
+ try {
7412
+ iterationOk = await this.runOneIteration();
7413
+ } catch (err) {
7414
+ this.consecutiveFailures++;
7415
+ this.opts.onError?.(err instanceof Error ? err : new Error(String(err)), this.consecutiveFailures);
7416
+ await this.appendFailure("engine error", err instanceof Error ? err.message : String(err));
7417
+ }
7418
+ if (iterationOk) {
7419
+ this.consecutiveFailures = 0;
7420
+ }
7421
+ if (this.stopRequested) break;
7422
+ await sleep(this.opts.cycleGapMs ?? 1e3);
7423
+ }
7424
+ } finally {
7425
+ this.state = "stopped";
7426
+ await this.persistEngineState("stopped").catch(() => {
7427
+ });
7428
+ }
7429
+ }
7430
+ /**
7431
+ * Execute a single sense-decide-execute-reflect cycle.
7432
+ * Returns true on success, false on handled failure / no-op.
7433
+ *
7434
+ * Exposed publicly so the REPL can pace iterations from its main loop
7435
+ * — running the engine and the REPL as a single sequential consumer of
7436
+ * `agent.run()` avoids race conditions on the shared Context.
7437
+ */
7438
+ async runOneIteration() {
7439
+ const goal = await loadGoal(this.goalPath);
7440
+ if (!goal) {
7441
+ this.stopRequested = true;
7442
+ return false;
7443
+ }
7444
+ const action = await this.decide(goal);
7445
+ if (!action) {
7446
+ await sleep(5e3);
7447
+ return false;
7448
+ }
7449
+ const ctrl = new AbortController();
7450
+ this.currentCtrl = ctrl;
7451
+ const timer = setTimeout(
7452
+ () => ctrl.abort(),
7453
+ this.opts.iterationTimeoutMs ?? 5 * 6e4
7454
+ );
7455
+ let status = "success";
7456
+ let note;
7457
+ const tc = this.opts.agent.ctx?.tokenCounter;
7458
+ const beforeUsage = tc?.total?.();
7459
+ const beforeCost = tc?.estimateCost?.().total;
7460
+ try {
7461
+ const result = await this.opts.agent.run(
7462
+ [{ type: "text", text: action.directive }],
7463
+ { signal: ctrl.signal }
7464
+ );
7465
+ if (result.status === "aborted") {
7466
+ status = "aborted";
7467
+ note = "stopped by user";
7468
+ } else if (result.status === "failed") {
7469
+ status = "failure";
7470
+ note = result.error?.describe?.() ?? "agent run failed";
7471
+ } else if (result.status === "max_iterations") {
7472
+ status = "failure";
7473
+ note = `max iterations (${result.iterations})`;
7474
+ } else {
7475
+ status = "success";
7476
+ const tail = (result.finalText ?? "").slice(0, 240).replace(/\s+/g, " ").trim();
7477
+ if (tail) note = tail;
7478
+ }
7479
+ } catch (err) {
7480
+ const isAbort = err instanceof Error && (err.name === "AbortError" || err.message.includes("abort"));
7481
+ status = isAbort ? "aborted" : "failure";
7482
+ note = err instanceof Error ? err.message : String(err);
7483
+ } finally {
7484
+ clearTimeout(timer);
7485
+ this.currentCtrl = null;
7486
+ }
7487
+ const afterUsage = tc?.total?.();
7488
+ const afterCost = tc?.estimateCost?.().total;
7489
+ const tokens = beforeUsage && afterUsage ? {
7490
+ input: Math.max(0, afterUsage.input - beforeUsage.input),
7491
+ output: Math.max(0, afterUsage.output - beforeUsage.output)
7492
+ } : void 0;
7493
+ const costUsd = typeof beforeCost === "number" && typeof afterCost === "number" ? Math.max(0, afterCost - beforeCost) : void 0;
7494
+ await this.appendIterationEntry({
7495
+ source: action.source,
7496
+ task: action.task,
7497
+ status,
7498
+ note,
7499
+ tokens,
7500
+ costUsd
7501
+ });
7502
+ let iterationIndex = 0;
7503
+ try {
7504
+ const reloaded = await loadGoal(this.goalPath);
7505
+ iterationIndex = reloaded?.iterations ?? 0;
7506
+ } catch {
7507
+ }
7508
+ this.opts.onIteration?.({
7509
+ at: (this.opts.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
7510
+ iteration: iterationIndex,
7511
+ source: action.source,
7512
+ task: action.task,
7513
+ status,
7514
+ note,
7515
+ tokens,
7516
+ costUsd
7517
+ });
7518
+ if (status === "failure") {
7519
+ this.consecutiveFailures++;
7520
+ return false;
7521
+ }
7522
+ if (status === "aborted") {
7523
+ if (this.stopRequested) return false;
7524
+ this.consecutiveFailures++;
7525
+ return false;
7526
+ }
7527
+ this.iterationsSinceCompact++;
7528
+ await this.maybeCompact().catch((err) => {
7529
+ this.opts.onError?.(
7530
+ err instanceof Error ? err : new Error(String(err)),
7531
+ this.consecutiveFailures
7532
+ );
7533
+ });
7534
+ return true;
7535
+ }
7536
+ /**
7537
+ * Run compaction when either trigger fires:
7538
+ * - We've done >= compactEveryNIterations since the last compact.
7539
+ * - Current request tokens exceed aggressiveCompactRatio * maxContext.
7540
+ *
7541
+ * The second check uses *aggressive* mode to free more headroom; the
7542
+ * cadence check uses non-aggressive (cheaper).
7543
+ */
7544
+ async maybeCompact() {
7545
+ const compactor = this.opts.compactor;
7546
+ if (!compactor) return;
7547
+ const ctx = this.opts.agent.ctx;
7548
+ if (!ctx) return;
7549
+ const cadence = this.opts.compactEveryNIterations ?? 25;
7550
+ const threshold = this.opts.aggressiveCompactRatio ?? 0.85;
7551
+ const maxCtx = this.opts.maxContextTokens;
7552
+ let aggressive = false;
7553
+ let shouldRun = false;
7554
+ if (this.iterationsSinceCompact >= cadence) {
7555
+ shouldRun = true;
7556
+ }
7557
+ if (maxCtx && maxCtx > 0) {
7558
+ const used = ctx.tokenCounter?.currentRequestTokens?.();
7559
+ if (used) {
7560
+ const total = used.input + used.cacheRead;
7561
+ if (total / maxCtx >= threshold) {
7562
+ shouldRun = true;
7563
+ aggressive = true;
7564
+ }
7565
+ }
7566
+ }
7567
+ if (!shouldRun) return;
7568
+ const report = await compactor.compact(ctx, { aggressive });
7569
+ this.iterationsSinceCompact = 0;
7570
+ const saved = report.before - report.after;
7571
+ await this.appendIterationEntry({
7572
+ source: "manual",
7573
+ task: `compaction (${aggressive ? "aggressive" : "cadence"})`,
7574
+ status: "success",
7575
+ note: `saved ~${saved} tokens (${report.before}\u2192${report.after})`
7576
+ });
7577
+ }
7578
+ /**
7579
+ * Hybrid idea source.
7580
+ * 1. Pending todos on the agent's context.
7581
+ * 2. Dirty git working tree → propose a "review and finish this" task.
7582
+ * 3. Otherwise: brainstorm via the LLM against the goal.
7583
+ *
7584
+ * After failureBudget consecutive failures, force brainstorm so the
7585
+ * engine doesn't loop on the same broken todo or stuck git state.
7586
+ */
7587
+ async decide(goal) {
7588
+ const forceBrainstorm = this.consecutiveFailures >= (this.opts.failureBudget ?? 3);
7589
+ if (!forceBrainstorm) {
7590
+ const todo = this.pickPendingTodo();
7591
+ if (todo) {
7592
+ return {
7593
+ source: "todo",
7594
+ task: todo.content,
7595
+ directive: this.buildDirective(goal, "todo", todo.content)
7596
+ };
7597
+ }
7598
+ const gitTask = await this.pickGitTask();
7599
+ if (gitTask) {
7600
+ return {
7601
+ source: "git",
7602
+ task: gitTask,
7603
+ directive: this.buildDirective(goal, "git", gitTask)
7604
+ };
7605
+ }
7606
+ }
7607
+ const brainstormed = await this.brainstormTask(goal);
7608
+ if (!brainstormed) return null;
7609
+ return {
7610
+ source: "brainstorm",
7611
+ task: brainstormed,
7612
+ directive: this.buildDirective(goal, "brainstorm", brainstormed)
7613
+ };
7614
+ }
7615
+ pickPendingTodo() {
7616
+ const todos = this.opts.agent.ctx.todos;
7617
+ if (!Array.isArray(todos)) return null;
7618
+ return todos.find((t2) => t2.status === "pending") ?? null;
7619
+ }
7620
+ async pickGitTask() {
7621
+ let out;
7622
+ try {
7623
+ out = await (this.opts.gitStatusReader?.() ?? this.readGitStatus());
7624
+ } catch {
7625
+ return null;
7626
+ }
7627
+ const dirty = out.trim();
7628
+ if (!dirty) return null;
7629
+ const lines = dirty.split("\n").slice(0, 8);
7630
+ const preview = lines.join(", ");
7631
+ return `Inspect the dirty working tree and either finish the in-progress work or revert it. Files: ${preview}`;
7632
+ }
7633
+ async readGitStatus() {
7634
+ const { stdout } = await execFileP("git", ["status", "--porcelain"], {
7635
+ cwd: this.opts.projectRoot,
7636
+ timeout: 5e3
7637
+ });
7638
+ return stdout;
7639
+ }
7640
+ async brainstormTask(goal) {
7641
+ const lastFew = goal.journal.slice(-5).map((e) => ` - [${e.status}] ${e.task}`).join("\n");
7642
+ const directive = [
7643
+ "You are deciding the next action in an autonomous loop pursuing a long-running goal.",
7644
+ "",
7645
+ `Goal: ${goal.goal}`,
7646
+ "",
7647
+ lastFew ? `Recent iterations:
7648
+ ${lastFew}` : "No prior iterations yet.",
7649
+ "",
7650
+ "Output ONE concrete, immediately-actionable task that advances the goal.",
7651
+ "Constraints:",
7652
+ "- One sentence, imperative form, under 200 chars.",
7653
+ "- No preamble, no explanation, no markdown \u2014 just the task line.",
7654
+ "- If recent iterations show repeated failures on the same target, pivot.",
7655
+ "- If the goal appears fully accomplished, output exactly: DONE"
7656
+ ].join("\n");
7657
+ try {
7658
+ const ctrl = new AbortController();
7659
+ const timer = setTimeout(() => ctrl.abort(), 6e4);
7660
+ try {
7661
+ const result = await this.opts.agent.run(
7662
+ [{ type: "text", text: directive }],
7663
+ { signal: ctrl.signal, maxIterations: 1 }
7664
+ );
7665
+ if (result.status !== "done") return null;
7666
+ const text = (result.finalText ?? "").trim();
7667
+ if (!text || text === "DONE") return null;
7668
+ const firstLine = text.split("\n").find((l) => l.trim().length > 0)?.trim();
7669
+ if (!firstLine) return null;
7670
+ return firstLine.slice(0, 240);
7671
+ } finally {
7672
+ clearTimeout(timer);
7673
+ }
7674
+ } catch {
7675
+ return null;
7676
+ }
7677
+ }
7678
+ buildDirective(goal, source, task) {
7679
+ return [
7680
+ "[ETERNAL AUTONOMY \u2014 iteration directive]",
7681
+ "",
7682
+ `Goal: ${goal.goal}`,
7683
+ `Source: ${source}`,
7684
+ `Task: ${task}`,
7685
+ "",
7686
+ "Execute this task end-to-end using the tools available to you. Make the",
7687
+ "changes, run tests if relevant, and commit / push as appropriate. Do not",
7688
+ "ask for confirmation \u2014 YOLO mode is active. When the task is done, stop;",
7689
+ "the loop will pick the next action."
7690
+ ].join("\n");
7691
+ }
7692
+ async appendIterationEntry(entry) {
7693
+ const current = await loadGoal(this.goalPath);
7694
+ if (!current) {
7695
+ return;
7696
+ }
7697
+ const updated = appendJournal(current, entry);
7698
+ await saveGoal(this.goalPath, updated);
7699
+ }
7700
+ async appendFailure(task, note) {
7701
+ await this.appendIterationEntry({ source: "manual", task, status: "failure", note });
7702
+ }
7703
+ async persistEngineState(state) {
7704
+ const current = await loadGoal(this.goalPath);
7705
+ if (!current) return;
7706
+ if (current.engineState === state) return;
7707
+ await saveGoal(this.goalPath, { ...current, engineState: state });
7708
+ }
7709
+ };
7710
+ function sleep(ms) {
7711
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
7712
+ }
7713
+
7714
+ // src/coordination/director.ts
7715
+ init_atomic_write();
7716
+
7193
7717
  // src/coordination/director-prompts.ts
7194
7718
  var DEFAULT_DIRECTOR_PREAMBLE = `You are the Director of a multi-agent fleet. You orchestrate worker
7195
7719
  subagents by spawning them, assigning tasks, awaiting completions, and
@@ -8685,7 +9209,9 @@ var Director = class {
8685
9209
  }, opts.checkpointDebounceMs ?? 250) : null;
8686
9210
  this.fleetManager = opts.fleetManager;
8687
9211
  if (this.sharedScratchpadPath) {
8688
- void fsp2.mkdir(this.sharedScratchpadPath, { recursive: true }).catch(() => void 0);
9212
+ void fsp2.mkdir(this.sharedScratchpadPath, { recursive: true }).catch(
9213
+ (err) => this.logShutdownError("shared_scratchpad_mkdir", err)
9214
+ );
8689
9215
  }
8690
9216
  this.transport = new InMemoryBridgeTransport();
8691
9217
  this.bridge = new InMemoryAgentBridge(
@@ -8791,7 +9317,9 @@ var Director = class {
8791
9317
  if (this.manifestTimer) return;
8792
9318
  this.manifestTimer = setTimeout(() => {
8793
9319
  this.manifestTimer = null;
8794
- void this.writeManifest().catch(() => void 0);
9320
+ void this.writeManifest().catch(
9321
+ (err) => this.logShutdownError("manifest_write_debounced", err)
9322
+ );
8795
9323
  }, this.manifestDebounceMs);
8796
9324
  }
8797
9325
  /**
@@ -8982,7 +9510,7 @@ var Director = class {
8982
9510
  usage: this.usage.snapshot()
8983
9511
  };
8984
9512
  await fsp2.mkdir(path6.dirname(this.manifestPath), { recursive: true });
8985
- await fsp2.writeFile(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
9513
+ await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
8986
9514
  return this.manifestPath;
8987
9515
  }
8988
9516
  /**
@@ -9511,9 +10039,11 @@ async function readSubagentPartial(opts, subagentId) {
9511
10039
  candidates.push(path6.join(opts.sessionsRoot, opts.directorRunId, `${subagentId}.jsonl`));
9512
10040
  } else {
9513
10041
  try {
9514
- const runDirs = await fsp2.readdir(opts.sessionsRoot);
9515
- for (const r of runDirs) {
9516
- candidates.push(path6.join(opts.sessionsRoot, r, `${subagentId}.jsonl`));
10042
+ const entries = await fsp2.readdir(opts.sessionsRoot, { withFileTypes: true });
10043
+ for (const entry of entries) {
10044
+ if (entry.isDirectory()) {
10045
+ candidates.push(path6.join(opts.sessionsRoot, entry.name, `${subagentId}.jsonl`));
10046
+ }
9517
10047
  }
9518
10048
  } catch {
9519
10049
  return void 0;
@@ -9711,6 +10241,9 @@ function makeDirectorSessionFactory(opts) {
9711
10241
 
9712
10242
  // src/coordination/null-fleet-bus.ts
9713
10243
  var NULL_FLEET_BUS = new FleetBus();
10244
+
10245
+ // src/models/mode-store.ts
10246
+ init_atomic_write();
9714
10247
  var DefaultModeStore = class {
9715
10248
  activeModeId = null;
9716
10249
  modes;
@@ -9769,10 +10302,9 @@ var DefaultModeStore = class {
9769
10302
  try {
9770
10303
  await fsp2.mkdir(this.configDir, { recursive: true });
9771
10304
  const configPath = path6.join(this.configDir, "mode.json");
9772
- await fsp2.writeFile(
10305
+ await atomicWrite(
9773
10306
  configPath,
9774
- JSON.stringify({ activeMode: this.activeModeId }, null, 2),
9775
- "utf8"
10307
+ JSON.stringify({ activeMode: this.activeModeId }, null, 2)
9776
10308
  );
9777
10309
  } catch {
9778
10310
  }
@@ -10626,6 +11158,9 @@ var SpecDrivenDev = class {
10626
11158
  }));
10627
11159
  }
10628
11160
  };
11161
+
11162
+ // src/sdd/spec-store.ts
11163
+ init_atomic_write();
10629
11164
  var SpecStore = class {
10630
11165
  baseDir;
10631
11166
  indexPath;
@@ -10735,6 +11270,9 @@ var SpecStore = class {
10735
11270
  await atomicWrite(this.indexPath, JSON.stringify(index, null, 2), { mode: 384 });
10736
11271
  }
10737
11272
  };
11273
+
11274
+ // src/sdd/task-graph-store.ts
11275
+ init_atomic_write();
10738
11276
  function graphToJSON(graph) {
10739
11277
  const serialisable = {
10740
11278
  ...graph,
@@ -11036,10 +11574,11 @@ var AISpecBuilder = class {
11036
11574
  async saveSession() {
11037
11575
  if (!this.sessionPath) return;
11038
11576
  try {
11039
- const fsp15 = await import('fs/promises');
11040
- const path25 = await import('path');
11041
- await fsp15.mkdir(path25.dirname(this.sessionPath), { recursive: true });
11042
- await fsp15.writeFile(this.sessionPath, JSON.stringify(this.session, null, 2), "utf8");
11577
+ const fsp16 = await import('fs/promises');
11578
+ const path26 = await import('path');
11579
+ const { atomicWrite: atomicWrite2 } = await Promise.resolve().then(() => (init_atomic_write(), atomic_write_exports));
11580
+ await fsp16.mkdir(path26.dirname(this.sessionPath), { recursive: true });
11581
+ await atomicWrite2(this.sessionPath, JSON.stringify(this.session, null, 2));
11043
11582
  } catch {
11044
11583
  }
11045
11584
  }
@@ -11047,8 +11586,8 @@ var AISpecBuilder = class {
11047
11586
  async loadSession() {
11048
11587
  if (!this.sessionPath) return false;
11049
11588
  try {
11050
- const fsp15 = await import('fs/promises');
11051
- const raw = await fsp15.readFile(this.sessionPath, "utf8");
11589
+ const fsp16 = await import('fs/promises');
11590
+ const raw = await fsp16.readFile(this.sessionPath, "utf8");
11052
11591
  const loaded = JSON.parse(raw);
11053
11592
  if (loaded?.id && loaded?.phase && loaded?.title) {
11054
11593
  this.session = loaded;
@@ -11062,14 +11601,21 @@ var AISpecBuilder = class {
11062
11601
  async deleteSession() {
11063
11602
  if (!this.sessionPath) return;
11064
11603
  try {
11065
- const fsp15 = await import('fs/promises');
11066
- await fsp15.unlink(this.sessionPath);
11604
+ const fsp16 = await import('fs/promises');
11605
+ await fsp16.unlink(this.sessionPath);
11067
11606
  } catch {
11068
11607
  }
11069
11608
  }
11070
- /** Auto-save helper — calls saveSession() but never throws. */
11609
+ /** Auto-save helper — calls saveSession() but never throws.
11610
+ * Failures are surfaced via process.emitWarning so a persistent
11611
+ * ENOSPC / EACCES doesn't silently strand session edits in memory. */
11071
11612
  autoSave() {
11072
- this.saveSession().catch(() => {
11613
+ this.saveSession().catch((err) => {
11614
+ const detail = err instanceof Error ? err.message : String(err);
11615
+ process.emitWarning(
11616
+ `SpecBuilder autoSave failed: ${detail}`,
11617
+ "SpecBuilderWarning"
11618
+ );
11073
11619
  });
11074
11620
  }
11075
11621
  // ── Session Lifecycle ─────────────────────────────────────────────────────
@@ -11741,15 +12287,15 @@ function computeCriticalPath(graph, topoOrder, blockedByMap) {
11741
12287
  maxId = id;
11742
12288
  }
11743
12289
  }
11744
- const path25 = [];
12290
+ const path26 = [];
11745
12291
  let current = maxId;
11746
12292
  const visited = /* @__PURE__ */ new Set();
11747
12293
  while (current && !visited.has(current)) {
11748
12294
  visited.add(current);
11749
- path25.unshift(current);
12295
+ path26.unshift(current);
11750
12296
  current = prev.get(current) ?? null;
11751
12297
  }
11752
- return path25;
12298
+ return path26;
11753
12299
  }
11754
12300
  function computeParallelGroups(graph, blockedByMap) {
11755
12301
  const groups = [];
@@ -12459,7 +13005,7 @@ async function startMetricsServer(opts) {
12459
13005
  const tls = opts.tls;
12460
13006
  const useHttps = !!(tls?.cert && tls?.key);
12461
13007
  const host = opts.host ?? "127.0.0.1";
12462
- const path25 = opts.path ?? "/metrics";
13008
+ const path26 = opts.path ?? "/metrics";
12463
13009
  const healthPath = opts.healthPath ?? "/healthz";
12464
13010
  const healthRegistry = opts.healthRegistry;
12465
13011
  const listener = (req, res) => {
@@ -12469,7 +13015,7 @@ async function startMetricsServer(opts) {
12469
13015
  return;
12470
13016
  }
12471
13017
  const url = req.url.split("?")[0];
12472
- if (url === path25) {
13018
+ if (url === path26) {
12473
13019
  let body;
12474
13020
  try {
12475
13021
  body = renderPrometheus(opts.sink.snapshot());
@@ -12533,7 +13079,7 @@ async function startMetricsServer(opts) {
12533
13079
  const protocol = useHttps ? "https" : "http";
12534
13080
  return {
12535
13081
  port: boundPort,
12536
- url: `${protocol}://${host}:${boundPort}${path25}`,
13082
+ url: `${protocol}://${host}:${boundPort}${path26}`,
12537
13083
  close: () => new Promise((resolve5, reject) => {
12538
13084
  server.close((err) => err ? reject(err) : resolve5());
12539
13085
  })
@@ -13260,6 +13806,9 @@ function stripTopDir(p) {
13260
13806
  if (idx === -1) return "";
13261
13807
  return p.slice(idx + 1);
13262
13808
  }
13809
+
13810
+ // src/skills/manifest-store.ts
13811
+ init_atomic_write();
13263
13812
  var SkillManifestStore = class {
13264
13813
  manifestPath;
13265
13814
  cache;
@@ -13284,7 +13833,7 @@ var SkillManifestStore = class {
13284
13833
  async write(data) {
13285
13834
  const dir = path6.dirname(this.manifestPath);
13286
13835
  await fsp2.mkdir(dir, { recursive: true });
13287
- await fsp2.writeFile(this.manifestPath, JSON.stringify(data, null, 2) + "\n", "utf8");
13836
+ await atomicWrite(this.manifestPath, JSON.stringify(data, null, 2) + "\n");
13288
13837
  this.cache = data;
13289
13838
  }
13290
13839
  async addEntry(entry) {
@@ -13615,6 +14164,9 @@ async function collectFiles(dir, baseDir) {
13615
14164
  }
13616
14165
  return results;
13617
14166
  }
14167
+
14168
+ // src/storage/session-rewinder.ts
14169
+ init_atomic_write();
13618
14170
  var DefaultSessionRewinder = class {
13619
14171
  constructor(sessionsDir) {
13620
14172
  this.sessionsDir = sessionsDir;
@@ -13748,7 +14300,7 @@ async function revertSnapshots(snapshots) {
13748
14300
  try {
13749
14301
  if (file.action === "deleted") {
13750
14302
  if (file.before !== null) {
13751
- await fsp2.writeFile(file.path, file.before, { mode: 420 });
14303
+ await atomicWrite(file.path, file.before, { mode: 420 });
13752
14304
  revertedFiles.push(file.path);
13753
14305
  }
13754
14306
  } else if (file.action === "created") {
@@ -13756,7 +14308,7 @@ async function revertSnapshots(snapshots) {
13756
14308
  revertedFiles.push(file.path);
13757
14309
  } else if (file.action === "modified") {
13758
14310
  if (file.before !== null) {
13759
- await fsp2.writeFile(file.path, file.before, { mode: 420 });
14311
+ await atomicWrite(file.path, file.before, { mode: 420 });
13760
14312
  revertedFiles.push(file.path);
13761
14313
  }
13762
14314
  }
@@ -14542,10 +15094,10 @@ var SecurityScanner = class {
14542
15094
  for (const pattern of patterns) {
14543
15095
  if (!this.matchesCategory(pattern)) continue;
14544
15096
  for (const regex of pattern.patterns) {
14545
- regex.lastIndex = 0;
14546
15097
  for (let lineNum = 0; lineNum < lines.length; lineNum++) {
14547
15098
  const line = lines[lineNum];
14548
15099
  if (!line) continue;
15100
+ regex.lastIndex = 0;
14549
15101
  if (regex.test(line)) {
14550
15102
  if (this.isFalsePositive(line, pattern.falsePositiveMarkers)) {
14551
15103
  continue;
@@ -14607,6 +15159,9 @@ var SecurityScanner = class {
14607
15159
  }
14608
15160
  };
14609
15161
  var defaultSecurityScanner = new SecurityScanner();
15162
+
15163
+ // src/security-scanner/report-generator.ts
15164
+ init_atomic_write();
14610
15165
  var DEFAULT_REPORT_OPTIONS = {
14611
15166
  outputDir: "security-reports",
14612
15167
  format: "markdown",
@@ -14634,7 +15189,7 @@ var ReportGenerator = class {
14634
15189
  default:
14635
15190
  content = this.generateMarkdown(scanResult);
14636
15191
  }
14637
- await writeFile(filepath, content, "utf-8");
15192
+ await atomicWrite(filepath, content);
14638
15193
  return filepath;
14639
15194
  }
14640
15195
  async ensureOutputDir() {
@@ -14826,6 +15381,9 @@ var ReportGenerator = class {
14826
15381
  }
14827
15382
  };
14828
15383
  var defaultReportGenerator = new ReportGenerator();
15384
+
15385
+ // src/security-scanner/gitignore-updater.ts
15386
+ init_atomic_write();
14829
15387
  var DEFAULT_OPTIONS2 = {
14830
15388
  gitignorePath: ".gitignore",
14831
15389
  entries: ["security-reports/", "security-reports/*"]
@@ -14852,12 +15410,12 @@ var GitignoreUpdater = class {
14852
15410
  }
14853
15411
  if (added.length > 0) {
14854
15412
  const newContent = [...lines].filter(Boolean).join("\n") + "\n";
14855
- await writeFile(this.options.gitignorePath, newContent, "utf-8");
15413
+ await atomicWrite(this.options.gitignorePath, newContent);
14856
15414
  }
14857
15415
  } catch (err) {
14858
15416
  if (err.code === "ENOENT") {
14859
15417
  const content = this.options.entries.join("\n") + "\n";
14860
- await writeFile(this.options.gitignorePath, content, "utf-8");
15418
+ await atomicWrite(this.options.gitignorePath, content);
14861
15419
  added.push(...this.options.entries);
14862
15420
  } else {
14863
15421
  errors.push(`Failed to update .gitignore: ${err}`);
@@ -14876,6 +15434,9 @@ var GitignoreUpdater = class {
14876
15434
  }
14877
15435
  };
14878
15436
  var defaultGitignoreUpdater = new GitignoreUpdater();
15437
+
15438
+ // src/security-scanner/orchestrator.ts
15439
+ init_atomic_write();
14879
15440
  var NETWORK_ERR_RE2 = /ECONN|ETIMEDOUT|ETIME|ENOTFOUND|EAI_AGAIN|fetch failed/i;
14880
15441
  var SecurityScannerOrchestrator = class {
14881
15442
  constructor(retryPolicy, errorHandler) {
@@ -14921,7 +15482,7 @@ var SecurityScannerOrchestrator = class {
14921
15482
  */
14922
15483
  async run(ctx, options) {
14923
15484
  const { projectRoot, reportOptions, skipGitignore, model: explicitModel } = options;
14924
- const provider = "provider" in ctx ? ctx.provider : ctx;
15485
+ const provider = "provider" in ctx && ctx.provider ? ctx.provider : ctx;
14925
15486
  const model = explicitModel ?? ("model" in ctx ? ctx.model : void 0);
14926
15487
  const detectionResult = await this.detector.detect(projectRoot);
14927
15488
  if (detectionResult.detectedStacks.length === 0) {
@@ -15260,7 +15821,7 @@ Be specific about the vulnerabilities found and how to fix them.`;
15260
15821
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
15261
15822
  const filename = `security-report-${timestamp}.${format}`;
15262
15823
  const filepath = join(outputDir, filename);
15263
- await writeFile(filepath, content, "utf-8");
15824
+ await atomicWrite(filepath, content);
15264
15825
  return filepath;
15265
15826
  }
15266
15827
  /**
@@ -15434,11 +15995,21 @@ Show a previous security report.
15434
15995
  }
15435
15996
  };
15436
15997
  }
15998
+ function getProviderFromContext(ctx) {
15999
+ if (ctx.provider && typeof ctx.provider.complete === "function") {
16000
+ return { provider: ctx.provider, model: ctx.model };
16001
+ }
16002
+ return null;
16003
+ }
15437
16004
  async function handleScan(args, ctx) {
15438
16005
  const options = parseArgs(args);
15439
16006
  const projectRoot = ctx.projectRoot || ctx.cwd || process.cwd();
15440
16007
  try {
15441
- const result = await defaultOrchestrator.run(ctx, {
16008
+ const providerInfo = getProviderFromContext(ctx);
16009
+ if (!providerInfo) {
16010
+ return { message: "\u274C Security scan requires an active LLM provider. No provider configured." };
16011
+ }
16012
+ const result = await defaultOrchestrator.run(providerInfo, {
15442
16013
  projectRoot,
15443
16014
  scanOptions: {
15444
16015
  depth: options.depth || "standard",
@@ -15487,7 +16058,11 @@ async function handleScan(args, ctx) {
15487
16058
  async function handleAudit(ctx) {
15488
16059
  const projectRoot = ctx.projectRoot || ctx.cwd || process.cwd();
15489
16060
  try {
15490
- const result = await defaultOrchestrator.run(ctx, {
16061
+ const providerInfo = getProviderFromContext(ctx);
16062
+ if (!providerInfo) {
16063
+ return { message: "\u274C Security audit requires an active LLM provider. No provider configured." };
16064
+ }
16065
+ const result = await defaultOrchestrator.run(providerInfo, {
15491
16066
  projectRoot,
15492
16067
  reportOptions: { format: "markdown" }
15493
16068
  });
@@ -15543,16 +16118,16 @@ Use \`/security report <number>\` to view a specific report.` };
15543
16118
  }
15544
16119
  const index = parseInt(reportId, 10) - 1;
15545
16120
  if (!isNaN(index) && reports[index]) {
15546
- const { readFile: readFile28 } = await import('fs/promises');
15547
- const content = await readFile28(join(reportsDir, reports[index]), "utf-8");
16121
+ const { readFile: readFile29 } = await import('fs/promises');
16122
+ const content = await readFile29(join(reportsDir, reports[index]), "utf-8");
15548
16123
  return { message: `# Security Report
15549
16124
 
15550
16125
  ${content}` };
15551
16126
  }
15552
16127
  const match = reports.find((r) => r.includes(reportId));
15553
16128
  if (match) {
15554
- const { readFile: readFile28 } = await import('fs/promises');
15555
- const content = await readFile28(join(reportsDir, match), "utf-8");
16129
+ const { readFile: readFile29 } = await import('fs/promises');
16130
+ const content = await readFile29(join(reportsDir, match), "utf-8");
15556
16131
  return { message: `# Security Report
15557
16132
 
15558
16133
  ${content}` };
@@ -15602,6 +16177,9 @@ function getHelpMessage() {
15602
16177
  `;
15603
16178
  }
15604
16179
  var securitySlashCommand = createSecuritySlashCommand();
16180
+
16181
+ // src/coordination/fleet-manager.ts
16182
+ init_atomic_write();
15605
16183
  var FleetManager = class {
15606
16184
  /** The fleet-wide event bus. */
15607
16185
  fleet;
@@ -15749,7 +16327,7 @@ var FleetManager = class {
15749
16327
  usage: this.usage.snapshot()
15750
16328
  };
15751
16329
  await fsp2.mkdir(path6.dirname(this.manifestPath), { recursive: true });
15752
- await fsp2.writeFile(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
16330
+ await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
15753
16331
  return this.manifestPath;
15754
16332
  }
15755
16333
  /**
@@ -15769,7 +16347,13 @@ var FleetManager = class {
15769
16347
  if (this.manifestTimer) return;
15770
16348
  this.manifestTimer = setTimeout(() => {
15771
16349
  this.manifestTimer = null;
15772
- void this.writeManifest().catch(() => void 0);
16350
+ void this.writeManifest().catch((err) => {
16351
+ const detail = err instanceof Error ? err.message : String(err);
16352
+ process.emitWarning(
16353
+ `FleetManager manifest write failed: ${detail}`,
16354
+ "FleetManagerWarning"
16355
+ );
16356
+ });
15773
16357
  }, this.manifestDebounceMs);
15774
16358
  }
15775
16359
  /** Best-effort session event writer. Swallows failures. */
@@ -15827,7 +16411,8 @@ var ExtensionRegistry = class {
15827
16411
  */
15828
16412
  async buildSystemPromptContributions(ctx) {
15829
16413
  const blocks = [];
15830
- for (const c of this.promptContributors) {
16414
+ const snapshot = [...this.promptContributors];
16415
+ for (const c of snapshot) {
15831
16416
  try {
15832
16417
  const contributed = await c(ctx);
15833
16418
  blocks.push(...contributed);
@@ -16149,16 +16734,7 @@ var Agent = class {
16149
16734
  this.tracer = init.tracer;
16150
16735
  this.extensions = init.extensions ?? new ExtensionRegistry();
16151
16736
  this.extensions.setLogger(this.container.resolve(TOKENS.Logger));
16152
- this.toolExecutor = new ToolExecutor(this.tools, {
16153
- permissionPolicy: init.permissionPolicy ?? this.permission,
16154
- secretScrubber: this.scrubber,
16155
- renderer: this.renderer,
16156
- events: this.events,
16157
- confirmAwaiter: init.confirmAwaiter,
16158
- iterationTimeoutMs: this.iterationTimeoutMs,
16159
- perIterationOutputCapBytes: this.perIterationOutputCapBytes,
16160
- tracer: this.tracer
16161
- });
16737
+ this.toolExecutor = init.toolExecutor;
16162
16738
  }
16163
16739
  get logger() {
16164
16740
  return this.container.resolve(TOKENS.Logger);
@@ -18082,6 +18658,6 @@ function wrapApiForCapabilityCheck(plugin, api, log, enforce = false) {
18082
18658
  });
18083
18659
  }
18084
18660
 
18085
- export { AISpecBuilder, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, Agent, AgentError, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolError, ToolExecutor, ToolRegistry, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, applyRosterBudget, asBlocks, asText, atomicWrite, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildChildEnv, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, color, compileGlob, compileUserRegex, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, context7Server, contextManagerTool, createAutoExecutor, createContextManagerTool, createDefaultPipelines, createDelegateTool, createMessage, createSecuritySlashCommand, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, downloadGitHubTarball, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatPlan, formatPlanTemplates, formatTodosList, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, googleMapsServer, isAgentError, isConfigError, isContextWindowModeId, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeContinueToNextIterationTool, makeDirectorSessionFactory, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, safeParse, safeStringify, sanitizeJsonString, savePlan, saveTodosCheckpoint, securitySlashCommand, sentinelServer, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
18661
+ export { AISpecBuilder, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, Agent, AgentError, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolError, ToolExecutor, ToolRegistry, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, atomicWrite, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildChildEnv, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, color, compileGlob, compileUserRegex, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, context7Server, contextManagerTool, createAutoExecutor, createContextManagerTool, createDefaultPipelines, createDelegateTool, createMessage, createSecuritySlashCommand, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, isAgentError, isConfigError, isContextWindowModeId, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeContinueToNextIterationTool, makeDirectorSessionFactory, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, securitySlashCommand, sentinelServer, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
18086
18662
  //# sourceMappingURL=index.js.map
18087
18663
  //# sourceMappingURL=index.js.map