@wrongstack/core 0.275.1 → 0.276.2

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 (83) hide show
  1. package/dist/{agent-bridge-D9JkPvJ0.d.ts → agent-bridge-D7A-eu3C.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-CArSFKFl.d.ts → agent-subagent-runner-CEuw4ATz.d.ts} +16 -10
  3. package/dist/{brain-DCkB5_e7.d.ts → brain-BLOyN5ZP.d.ts} +127 -1
  4. package/dist/{compactor-CzSvxM1g.d.ts → compactor-DcBpaJsI.d.ts} +1 -1
  5. package/dist/{config-BzFRKkg7.d.ts → config-Bf5mj-ad.d.ts} +20 -2
  6. package/dist/{context-BrLe8pJy.d.ts → context-CLnUMW5g.d.ts} +40 -2
  7. package/dist/coordination/index.d.ts +43 -24
  8. package/dist/coordination/index.js +849 -648
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +28 -28
  11. package/dist/defaults/index.js +1636 -845
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +16 -16
  14. package/dist/execution/index.js +218 -49
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/execution/prompt-enhancer.d.ts +1 -1
  17. package/dist/extension/index.d.ts +7 -7
  18. package/dist/extension/index.js.map +1 -1
  19. package/dist/{global-mailbox-CXkugtNQ.d.ts → global-mailbox-Iqfkgmwu.d.ts} +3 -3
  20. package/dist/{goal-store-DUwdbdoY.d.ts → goal-store-DGb6b5Ed.d.ts} +1 -1
  21. package/dist/hq/index.d.ts +6 -6
  22. package/dist/hq/index.js +178 -75
  23. package/dist/hq/index.js.map +1 -1
  24. package/dist/{index-CtlizLTK.d.ts → index-Cn0NOshr.d.ts} +10 -5
  25. package/dist/{index-neOCEy6q.d.ts → index-L4RZN9jJ.d.ts} +2 -2
  26. package/dist/index.d.ts +56 -48
  27. package/dist/index.js +2789 -1546
  28. package/dist/index.js.map +1 -1
  29. package/dist/infrastructure/index.d.ts +6 -6
  30. package/dist/infrastructure/index.js +26 -7
  31. package/dist/infrastructure/index.js.map +1 -1
  32. package/dist/kernel/index.d.ts +20 -12
  33. package/dist/kernel/index.js +55 -9
  34. package/dist/kernel/index.js.map +1 -1
  35. package/dist/{mailbox-types-_7gaY0Rl.d.ts → mailbox-types-DTl7bRH3.d.ts} +3 -1
  36. package/dist/{mcp-servers-MLL6bMlv.d.ts → mcp-servers-CuZGf9fI.d.ts} +4 -4
  37. package/dist/models/index.d.ts +5 -5
  38. package/dist/models/index.js +223 -139
  39. package/dist/models/index.js.map +1 -1
  40. package/dist/{models-registry-CrkcxQ-g.d.ts → models-registry-8XOdxWQu.d.ts} +16 -1
  41. package/dist/{multi-agent-coordinator-Dc_HuG9p.d.ts → multi-agent-coordinator-CiRtKVTk.d.ts} +8 -1
  42. package/dist/{null-fleet-bus-BMZwMin7.d.ts → null-fleet-bus-d9G-bVy9.d.ts} +26 -22
  43. package/dist/observability/index.d.ts +2 -2
  44. package/dist/{path-resolver-uVK4BatM.d.ts → path-resolver-BhIb6mtd.d.ts} +8 -3
  45. package/dist/{permission-CJR1qfOi.d.ts → permission-BCbQDR2s.d.ts} +1 -1
  46. package/dist/{permission-policy-DLVKKk4w.d.ts → permission-policy-C0ikndX_.d.ts} +2 -18
  47. package/dist/{pipeline-BYR-Vdau.d.ts → pipeline-Dl6XbfE7.d.ts} +10 -6
  48. package/dist/{provider-model-resolve-iREK_1lG.d.ts → provider-model-resolve-B70epO19.d.ts} +3 -3
  49. package/dist/{provider-runner-i7SQXZuC.d.ts → provider-runner-DZ808MSM.d.ts} +3 -3
  50. package/dist/{retry-policy-BmY5ooh3.d.ts → retry-policy-Dt3_z8Aj.d.ts} +1 -1
  51. package/dist/sdd/index.d.ts +19 -10
  52. package/dist/sdd/index.js +411 -240
  53. package/dist/sdd/index.js.map +1 -1
  54. package/dist/{secret-vault-C9leEMzr.d.ts → secret-vault-BUJ2d1gB.d.ts} +1 -1
  55. package/dist/security/index.d.ts +5 -5
  56. package/dist/security/index.js +30 -6
  57. package/dist/security/index.js.map +1 -1
  58. package/dist/{selector-qjpee9BF.d.ts → selector-BCkWgdwy.d.ts} +1 -1
  59. package/dist/{session-event-bridge-m7y--I-H.d.ts → session-event-bridge-CMvIO59_.d.ts} +1 -1
  60. package/dist/{session-reader-BjLH4V9n.d.ts → session-reader-C8aiChUu.d.ts} +1 -1
  61. package/dist/skills/index.js +1 -0
  62. package/dist/skills/index.js.map +1 -1
  63. package/dist/storage/index.d.ts +68 -30
  64. package/dist/storage/index.js +839 -528
  65. package/dist/storage/index.js.map +1 -1
  66. package/dist/{strategy-compactor-C2bmlWYg.d.ts → strategy-compactor-DI1OHVbB.d.ts} +10 -10
  67. package/dist/{todos-checkpoint-oDS9IBNS.d.ts → todos-checkpoint-Ddd2CGr0.d.ts} +56 -9
  68. package/dist/{tool-executor-D4YdaJ-M.d.ts → tool-executor-Bmd5Ygoo.d.ts} +45 -10
  69. package/dist/tools/index.d.ts +2 -2
  70. package/dist/tools/index.js.map +1 -1
  71. package/dist/types/index.d.ts +20 -20
  72. package/dist/types/index.js +331 -98
  73. package/dist/types/index.js.map +1 -1
  74. package/dist/utils/index.d.ts +16 -3
  75. package/dist/utils/index.js +159 -83
  76. package/dist/utils/index.js.map +1 -1
  77. package/dist/{worktree-manager-A1Efnvs0.d.ts → worktree-manager-DBdl_5rs.d.ts} +4 -1
  78. package/instructions/agents/shadow-agent.md +3 -3
  79. package/instructions/coordination/director-preamble.md +3 -3
  80. package/instructions/modes/research-web.md +4 -4
  81. package/package.json +1 -1
  82. package/skills/research-web/SKILL.md +26 -26
  83. package/skills/research-web/SKILL.save.md +1 -1
@@ -1,6 +1,6 @@
1
- import { C as Compactor } from './compactor-CzSvxM1g.js';
2
- import { M as Message, T as Tool } from './context-BrLe8pJy.js';
3
- import { c as MCPServerConfig } from './config-BzFRKkg7.js';
1
+ import { C as Compactor } from './compactor-DcBpaJsI.js';
2
+ import { M as Message, T as Tool } from './context-CLnUMW5g.js';
3
+ import { c as MCPServerConfig } from './config-Bf5mj-ad.js';
4
4
 
5
5
  type ContextManagerAction = 'check' | 'summary' | 'prune' | 'add_note' | 'compact' | 'repair';
6
6
  interface ContextManagerInput {
@@ -149,7 +149,7 @@ declare const zaiVisionServer: () => MCPServerConfig;
149
149
  */
150
150
  declare const playwrightServer: () => MCPServerConfig;
151
151
  /**
152
- * MiniMax Token Plan MCP — web_search + understand_image.
152
+ * MiniMax Token Plan MCP — search + understand_image.
153
153
  * This preset exposes only the read-only image understanding tool by default.
154
154
  * Requires MINIMAX_API_KEY and uvx on PATH.
155
155
  */
@@ -1,8 +1,8 @@
1
- export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-CrkcxQ-g.js';
2
- export { C as CODEX_MODELS, a as CodexModelMeta, D as DefaultModeStore, L as LLMSelector, b as LLMSelectorOptions, M as ModeLoaderOptions, P as ProviderModelDescriptor, c as codexModelMeta, d as describeCatalogModel, l as loadProjectModes, e as loadUserModes, r as resolveProviderModelList } from '../provider-model-resolve-iREK_1lG.js';
3
- import { d as ModelMatrixEntry, P as ProviderConfig } from '../config-BzFRKkg7.js';
4
- import '../context-BrLe8pJy.js';
5
- import '../selector-qjpee9BF.js';
1
+ export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-8XOdxWQu.js';
2
+ export { C as CODEX_MODELS, a as CodexModelMeta, D as DefaultModeStore, L as LLMSelector, b as LLMSelectorOptions, M as ModeLoaderOptions, P as ProviderModelDescriptor, c as codexModelMeta, d as describeCatalogModel, l as loadProjectModes, e as loadUserModes, r as resolveProviderModelList } from '../provider-model-resolve-B70epO19.js';
3
+ import { d as ModelMatrixEntry, P as ProviderConfig } from '../config-Bf5mj-ad.js';
4
+ import '../context-CLnUMW5g.js';
5
+ import '../selector-BCkWgdwy.js';
6
6
  import '../mode-CZlO9iU1.js';
7
7
 
8
8
  /**
@@ -5,79 +5,22 @@ import { readFileSync, statSync } from 'fs';
5
5
  import { fileURLToPath } from 'url';
6
6
 
7
7
  // src/models/models-registry.ts
8
- async function atomicWrite(targetPath, content, opts = {}) {
9
- const dir = path4.dirname(targetPath);
10
- await fs.mkdir(dir, { recursive: true });
11
- const tmp = path4.join(dir, `.${path4.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
12
- try {
13
- if (typeof content === "string") {
14
- await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
15
- } else {
16
- await fs.writeFile(tmp, content, { flag: "wx" });
17
- }
18
- try {
19
- const fh = await fs.open(tmp, "r+");
20
- try {
21
- await fh.sync();
22
- } finally {
23
- await fh.close();
24
- }
25
- } catch {
26
- }
27
- let mode;
28
- try {
29
- const stat3 = await fs.stat(targetPath);
30
- mode = stat3.mode & 511;
31
- } catch {
32
- mode = opts.mode;
33
- }
34
- if (mode !== void 0) {
35
- await fs.chmod(tmp, mode);
36
- }
37
- await renameWithRetry(tmp, targetPath);
38
- if (mode !== void 0 && process.platform === "win32") {
39
- try {
40
- await fs.chmod(targetPath, mode);
41
- } catch {
42
- }
43
- }
44
- } catch (err) {
45
- try {
46
- await fs.unlink(tmp);
47
- } catch {
48
- }
49
- throw err;
50
- }
51
- }
52
- var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
53
- async function renameWithRetry(from, to) {
54
- if (process.platform !== "win32") {
55
- await fs.rename(from, to);
56
- return;
57
- }
58
- const delays = [10, 25, 60, 120, 250];
59
- let lastErr;
60
- for (let i = 0; i <= delays.length; i++) {
61
- try {
62
- await fs.rename(from, to);
63
- return;
64
- } catch (err) {
65
- lastErr = err;
66
- const code = err?.code;
67
- if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
68
- throw err;
69
- }
70
- await new Promise((resolve4) => setTimeout(resolve4, delays[i]));
71
- }
72
- }
73
- throw lastErr;
74
- }
75
8
 
76
9
  // src/utils/error.ts
77
10
  function toErrorMessage(err) {
78
11
  return err instanceof Error ? err.message : String(err);
79
12
  }
80
13
 
14
+ // src/utils/expect-defined.ts
15
+ function expectDefined(value, label) {
16
+ if (value === null || value === void 0) {
17
+ const err = new Error("Expected value to be defined");
18
+ err.name = "ExpectDefinedError";
19
+ throw err;
20
+ }
21
+ return value;
22
+ }
23
+
81
24
  // src/utils/merge-models-payload.ts
82
25
  function mergeModelsPayload(base, overlay) {
83
26
  const out = {};
@@ -141,6 +84,180 @@ function stripUndefined(obj) {
141
84
  return out;
142
85
  }
143
86
 
87
+ // src/utils/token-estimate.ts
88
+ var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
89
+ var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
90
+ var _estimateCacheOrder = [];
91
+ var ESTIMATE_CACHE_MAX_SIZE = 5e4;
92
+ function getCachedEstimate(key, compute) {
93
+ const existing = ESTIMATE_CACHE.get(key);
94
+ if (existing !== void 0) return existing;
95
+ if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {
96
+ while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {
97
+ const oldest = _estimateCacheOrder.shift();
98
+ if (oldest !== void 0) ESTIMATE_CACHE.delete(oldest);
99
+ }
100
+ }
101
+ const estimate = compute(key);
102
+ ESTIMATE_CACHE.set(key, estimate);
103
+ _estimateCacheOrder.push(key);
104
+ return estimate;
105
+ }
106
+ function estimateToolInputTokens(input) {
107
+ if (typeof input === "string") return RoughTokenEstimate(input);
108
+ if (input === null || typeof input !== "object") {
109
+ return RoughTokenEstimate(String(input));
110
+ }
111
+ return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));
112
+ }
113
+ function estimateToolResultTokens(content) {
114
+ if (typeof content === "string") return RoughTokenEstimate(content);
115
+ return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));
116
+ }
117
+ function estimateTextTokens(text) {
118
+ return RoughTokenEstimate(text);
119
+ }
120
+ function computeMessageTokens(msg) {
121
+ if (typeof msg.content === "string") return estimateTextTokens(msg.content);
122
+ let total = 0;
123
+ for (const b of msg.content) {
124
+ if (b.type === "text") total += estimateTextTokens(b.text);
125
+ else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
126
+ else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
127
+ else total += RoughTokenEstimate(JSON.stringify(b));
128
+ }
129
+ return total;
130
+ }
131
+ function estimateMessageTokens(messages) {
132
+ let total = 0;
133
+ for (const m of messages) {
134
+ if (typeof m._estTokens === "number" && m._estTokens > 0) {
135
+ total += m._estTokens;
136
+ continue;
137
+ }
138
+ total += computeMessageTokens(m);
139
+ }
140
+ return total;
141
+ }
142
+
143
+ // src/types/errors.ts
144
+ var ERROR_CODES = {
145
+ // General
146
+ VALIDATION_ERROR: "VALIDATION_ERROR"};
147
+ var WrongStackError = class extends Error {
148
+ code;
149
+ subsystem;
150
+ severity;
151
+ recoverable;
152
+ context;
153
+ constructor(opts) {
154
+ super(opts.message, { cause: opts.cause });
155
+ this.name = "WrongStackError";
156
+ this.code = opts.code;
157
+ this.subsystem = opts.subsystem;
158
+ this.severity = opts.severity ?? "error";
159
+ this.recoverable = opts.recoverable ?? false;
160
+ this.context = opts.context;
161
+ }
162
+ /**
163
+ * Render a one-line user-facing description.
164
+ * Subclasses should override for domain-specific formatting.
165
+ */
166
+ describe() {
167
+ const ctx = this.context ? ` ${formatContext(this.context)}` : "";
168
+ return `${this.code}: ${this.message}${ctx}`;
169
+ }
170
+ };
171
+ function formatContext(ctx) {
172
+ const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
173
+ return parts.length > 0 ? `[${parts.join(" ")}]` : "";
174
+ }
175
+ var FetchError = class extends WrongStackError {
176
+ status;
177
+ constructor(opts) {
178
+ super({
179
+ message: opts.message,
180
+ code: ERROR_CODES.VALIDATION_ERROR,
181
+ subsystem: "general",
182
+ severity: "error",
183
+ recoverable: opts.status === 429 || opts.status >= 500,
184
+ context: { status: opts.status, ...opts.context },
185
+ cause: opts.cause
186
+ });
187
+ this.name = "FetchError";
188
+ this.status = opts.status;
189
+ }
190
+ };
191
+
192
+ // src/utils/atomic-write.ts
193
+ async function atomicWrite(targetPath, content, opts = {}) {
194
+ const dir = path4.dirname(targetPath);
195
+ await fs.mkdir(dir, { recursive: true });
196
+ const tmp = path4.join(dir, `.${path4.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
197
+ try {
198
+ if (typeof content === "string") {
199
+ await fs.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
200
+ } else {
201
+ await fs.writeFile(tmp, content, { flag: "wx" });
202
+ }
203
+ try {
204
+ const fh = await fs.open(tmp, "r+");
205
+ try {
206
+ await fh.sync();
207
+ } finally {
208
+ await fh.close();
209
+ }
210
+ } catch {
211
+ }
212
+ let mode;
213
+ try {
214
+ const stat3 = await fs.stat(targetPath);
215
+ mode = stat3.mode & 511;
216
+ } catch {
217
+ mode = opts.mode;
218
+ }
219
+ if (mode !== void 0) {
220
+ await fs.chmod(tmp, mode);
221
+ }
222
+ await renameWithRetry(tmp, targetPath);
223
+ if (mode !== void 0 && process.platform === "win32") {
224
+ try {
225
+ await fs.chmod(targetPath, mode);
226
+ } catch {
227
+ }
228
+ }
229
+ } catch (err) {
230
+ try {
231
+ await fs.unlink(tmp);
232
+ } catch {
233
+ }
234
+ throw err;
235
+ }
236
+ }
237
+ var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
238
+ async function renameWithRetry(from, to) {
239
+ if (process.platform !== "win32") {
240
+ await fs.rename(from, to);
241
+ return;
242
+ }
243
+ const delays = [10, 25, 60, 120, 250];
244
+ let lastErr;
245
+ for (let i = 0; i <= delays.length; i++) {
246
+ try {
247
+ await fs.rename(from, to);
248
+ return;
249
+ } catch (err) {
250
+ lastErr = err;
251
+ const code = err?.code;
252
+ if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
253
+ throw err;
254
+ }
255
+ await new Promise((resolve4) => setTimeout(resolve4, delays[i]));
256
+ }
257
+ }
258
+ throw lastErr;
259
+ }
260
+
144
261
  // src/models/models-registry.ts
145
262
  var DEFAULT_URL = "https://models.dev/api.json";
146
263
  var ENV_URL_KEY = "WRONGSTACK_MODELS_DEV_URL";
@@ -175,6 +292,14 @@ var DefaultModelsRegistry = class {
175
292
  payload;
176
293
  /** Memoised overlay payload (in-memory / fetched / file). */
177
294
  overlayPayload;
295
+ /**
296
+ * Extra providers injected at runtime via `mergeOverlay()` — e.g. an
297
+ * openai-compatible server (omniroute, LiteLLM, …) auto-discovered from its
298
+ * `/v1/models` endpoint at boot. Applied LAST (on top of base + curated
299
+ * overlay) and re-applied across `refresh()` so the discovered catalog
300
+ * survives a models.dev refetch.
301
+ */
302
+ extraOverlay;
178
303
  fetchedAt;
179
304
  cacheFile;
180
305
  url;
@@ -210,9 +335,22 @@ var DefaultModelsRegistry = class {
210
335
  }
211
336
  const overlay = await this.loadOverlay(opts);
212
337
  const base = await this.loadBase(opts, Object.keys(overlay).length > 0);
213
- this.payload = mergeModelsPayload(base, overlay);
338
+ this.payload = this.withExtraOverlay(mergeModelsPayload(base, overlay));
214
339
  return this.payload;
215
340
  }
341
+ /**
342
+ * Merge an additional provider payload on top of the resolved catalog. Used
343
+ * for runtime-discovered openai-compatible providers. Remembered so it is
344
+ * re-applied across `refresh()`. A no-op for an empty payload.
345
+ */
346
+ mergeOverlay(payload) {
347
+ if (!hasEntries(payload)) return;
348
+ this.extraOverlay = this.extraOverlay ? mergeModelsPayload(this.extraOverlay, payload) : payload;
349
+ if (this.payload) this.payload = mergeModelsPayload(this.payload, this.extraOverlay);
350
+ }
351
+ withExtraOverlay(payload) {
352
+ return this.extraOverlay ? mergeModelsPayload(payload, this.extraOverlay) : payload;
353
+ }
216
354
  /**
217
355
  * Load the models.dev base payload: fresh cache → network → stale cache.
218
356
  * On total failure, degrade to `{}` (so a non-empty overlay still drives
@@ -261,7 +399,11 @@ var DefaultModelsRegistry = class {
261
399
  });
262
400
  clearTimeout(timeout);
263
401
  if (!res.ok) {
264
- throw new Error(`ModelsRegistry: HTTP ${res.status} fetching ${this.url}`);
402
+ throw new FetchError({
403
+ message: `ModelsRegistry: HTTP ${res.status} fetching ${this.url}`,
404
+ status: res.status,
405
+ context: { url: this.url, op: "refreshModels" }
406
+ });
265
407
  }
266
408
  const json = await res.json();
267
409
  this.fetchedAt = /* @__PURE__ */ new Date();
@@ -275,7 +417,11 @@ var DefaultModelsRegistry = class {
275
417
  } catch (err) {
276
418
  clearTimeout(timeout);
277
419
  if (err instanceof Error && err.name === "AbortError") {
278
- throw new Error(`ModelsRegistry: fetch timed out after ${this.refreshTimeoutMs}ms`);
420
+ throw new FetchError({
421
+ message: `ModelsRegistry: fetch timed out after ${this.refreshTimeoutMs}ms`,
422
+ status: 408,
423
+ context: { url: this.url, op: "refreshModels", timedOut: true }
424
+ });
279
425
  }
280
426
  throw err;
281
427
  }
@@ -311,7 +457,11 @@ var DefaultModelsRegistry = class {
311
457
  method: "GET",
312
458
  headers: { accept: "application/json" }
313
459
  });
314
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
460
+ if (!res.ok) throw new FetchError({
461
+ message: `HTTP ${res.status}`,
462
+ status: res.status,
463
+ context: { url: this.url, op: "refreshModels" }
464
+ });
315
465
  const json = await res.json();
316
466
  const envelope = {
317
467
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -345,7 +495,7 @@ var DefaultModelsRegistry = class {
345
495
  async refresh() {
346
496
  const base = await this.refreshBase();
347
497
  const overlay = await this.loadOverlay({ force: true });
348
- this.payload = mergeModelsPayload(base, overlay);
498
+ this.payload = this.withExtraOverlay(mergeModelsPayload(base, overlay));
349
499
  return this.payload;
350
500
  }
351
501
  async listProviders() {
@@ -570,7 +720,7 @@ var DEFAULT_MODES = [
570
720
  description: "Current-data research \u2014 search web, verify, inject findings into context",
571
721
  prompt: modePrompt("research-web"),
572
722
  tags: ["research", "web", "current-data", "up-to-date"],
573
- toolPreferences: ["web_search", "web_fetch", "search", "fetch", "context_manager"],
723
+ toolPreferences: ["search/fetch", "search/fetch", "search", "fetch", "context_manager"],
574
724
  suggestedSkills: ["research-web", "tech-stack", "node-modern", "security-scanner", "react-modern"]
575
725
  }
576
726
  ];
@@ -679,72 +829,6 @@ async function loadUserModes(modesDir) {
679
829
  return modes;
680
830
  }
681
831
 
682
- // src/utils/expect-defined.ts
683
- function expectDefined(value, label) {
684
- if (value === null || value === void 0) {
685
- const err = new Error("Expected value to be defined");
686
- err.name = "ExpectDefinedError";
687
- throw err;
688
- }
689
- return value;
690
- }
691
-
692
- // src/utils/token-estimate.ts
693
- var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
694
- var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
695
- var _estimateCacheOrder = [];
696
- var ESTIMATE_CACHE_MAX_SIZE = 5e4;
697
- function getCachedEstimate(key, compute) {
698
- const existing = ESTIMATE_CACHE.get(key);
699
- if (existing !== void 0) return existing;
700
- if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {
701
- while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {
702
- const oldest = _estimateCacheOrder.shift();
703
- if (oldest !== void 0) ESTIMATE_CACHE.delete(oldest);
704
- }
705
- }
706
- const estimate = compute(key);
707
- ESTIMATE_CACHE.set(key, estimate);
708
- _estimateCacheOrder.push(key);
709
- return estimate;
710
- }
711
- function estimateToolInputTokens(input) {
712
- if (typeof input === "string") return RoughTokenEstimate(input);
713
- if (input === null || typeof input !== "object") {
714
- return RoughTokenEstimate(String(input));
715
- }
716
- return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));
717
- }
718
- function estimateToolResultTokens(content) {
719
- if (typeof content === "string") return RoughTokenEstimate(content);
720
- return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));
721
- }
722
- function estimateTextTokens(text) {
723
- return RoughTokenEstimate(text);
724
- }
725
- function computeMessageTokens(msg) {
726
- if (typeof msg.content === "string") return estimateTextTokens(msg.content);
727
- let total = 0;
728
- for (const b of msg.content) {
729
- if (b.type === "text") total += estimateTextTokens(b.text);
730
- else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
731
- else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
732
- else total += RoughTokenEstimate(JSON.stringify(b));
733
- }
734
- return total;
735
- }
736
- function estimateMessageTokens(messages) {
737
- let total = 0;
738
- for (const m of messages) {
739
- if (typeof m._estTokens === "number" && m._estTokens > 0) {
740
- total += m._estTokens;
741
- continue;
742
- }
743
- total += computeMessageTokens(m);
744
- }
745
- return total;
746
- }
747
-
748
832
  // src/types/blocks.ts
749
833
  function isTextBlock(b) {
750
834
  return b.type === "text";