@wrongstack/core 0.77.0 → 0.84.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-bridge-EWdqs8v6.d.ts → agent-bridge-C9P_HPez.d.ts} +2 -2
- package/dist/{agent-subagent-runner-D8qW8OSC.d.ts → agent-subagent-runner-2Aq0jOSj.d.ts} +107 -102
- package/dist/{compactor-D_ExJajC.d.ts → compactor-CJq7LQev.d.ts} +3 -3
- package/dist/{config-Dy0CK_o6.d.ts → config-_DZ7dN-T.d.ts} +77 -75
- package/dist/{context-y87Jc5ei.d.ts → context-ToHAp4-U.d.ts} +119 -90
- package/dist/coordination/index.d.ts +16 -16
- package/dist/coordination/index.js +318 -37
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +32 -32
- package/dist/defaults/index.js +433 -81
- package/dist/defaults/index.js.map +1 -1
- package/dist/{director-state-BmYi3DGA.d.ts → director-state-CgIc30qi.d.ts} +19 -19
- package/dist/{events-CYaoLN5_.d.ts → events-DnRqXaZ3.d.ts} +43 -42
- package/dist/execution/index.d.ts +53 -53
- package/dist/execution/index.js +72 -29
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +9 -9
- package/dist/extension/index.js +8 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/{goal-store-C7jcumEh.d.ts → goal-store-DvWLNu52.d.ts} +4 -4
- package/dist/{index-DIxjTOga.d.ts → index-BNOLadHw.d.ts} +28 -28
- package/dist/{index-Dsda0uCn.d.ts → index-N0_c4bHQ.d.ts} +45 -45
- package/dist/index.d.ts +167 -167
- package/dist/index.js +617 -155
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +9 -9
- package/dist/infrastructure/index.js +13 -5
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +14 -14
- package/dist/kernel/index.js +7 -0
- package/dist/kernel/index.js.map +1 -1
- package/dist/logger-B72yyPc6.d.ts +12 -0
- package/dist/{logger-BppKxDqZ.d.ts → logger-C_27pj9i.d.ts} +6 -7
- package/dist/{mcp-servers-T0O6UN_w.d.ts → mcp-servers-Dck3T85_.d.ts} +20 -20
- package/dist/{mode-BO4SEUIv.d.ts → mode-CHo2XtHs.d.ts} +4 -4
- package/dist/models/index.d.ts +10 -10
- package/dist/models/index.js +8 -2
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-BcYJDKLm.d.ts → models-registry-Be3osGt5.d.ts} +28 -28
- package/dist/{models-registry-Cuq1C8V9.d.ts → models-registry-Boz639EI.d.ts} +12 -12
- package/dist/{multi-agent-coordinator-DpbG3wiy.d.ts → multi-agent-coordinator-DllpCVkF.d.ts} +12 -12
- package/dist/{null-fleet-bus-u5ys3lW_.d.ts → null-fleet-bus-BY0AN-sr.d.ts} +121 -121
- package/dist/observability/index.d.ts +41 -41
- package/dist/observability/index.js.map +1 -1
- package/dist/{observability-BhnVLBLS.d.ts → observability-CoSNZdhX.d.ts} +4 -4
- package/dist/{parallel-eternal-engine-Dn0P8Pbj.d.ts → parallel-eternal-engine-D402RASp.d.ts} +49 -49
- package/dist/{path-resolver-B32v2JIq.d.ts → path-resolver-UPFTsDyD.d.ts} +6 -6
- package/dist/{permission-V5BLOrY6.d.ts → permission-14CChMmO.d.ts} +10 -8
- package/dist/{permission-policy-CBVx-d-8.d.ts → permission-policy-gW5htOo1.d.ts} +7 -7
- package/dist/{plan-templates-BcUwLlMQ.d.ts → plan-templates-DRvPgkfZ.d.ts} +65 -32
- package/dist/{provider-runner-CSi_7l0h.d.ts → provider-runner-COAJM8tC.d.ts} +6 -6
- package/dist/{retry-policy-CG3qvH_e.d.ts → retry-policy-DSu6O6rD.d.ts} +4 -4
- package/dist/sdd/index.d.ts +47 -47
- package/dist/sdd/index.js +47 -22
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-scrubber-7rSC_emZ.d.ts → secret-scrubber-yGBFQYju.d.ts} +10 -2
- package/dist/security/index.d.ts +7 -7
- package/dist/security/index.js +15 -8
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-RvBR_YRW.d.ts → selector-11-fm95U.d.ts} +2 -2
- package/dist/{session-event-bridge-CDHxcmQU.d.ts → session-event-bridge-D0u-x576.d.ts} +7 -7
- package/dist/{session-reader-BIpwM60D.d.ts → session-reader-BQU-toaN.d.ts} +23 -23
- package/dist/{skill-CxuWrsKK.d.ts → skill-BJeF2DwY.d.ts} +1 -1
- package/dist/skills/index.d.ts +9 -9
- package/dist/skills/index.js +15 -3
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +15 -15
- package/dist/storage/index.js +378 -76
- package/dist/storage/index.js.map +1 -1
- package/dist/{system-prompt-CA11g6Jo.d.ts → system-prompt-C0rLCeyn.d.ts} +16 -11
- package/dist/{task-graph-D1YQbpxF.d.ts → task-graph-CikNdRTG.d.ts} +22 -22
- package/dist/types/index.d.ts +26 -26
- package/dist/types/index.js +53 -17
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +57 -45
- package/dist/utils/index.js +66 -12
- package/dist/utils/index.js.map +1 -1
- package/dist/{wstack-paths-D7evAFWM.d.ts → wstack-paths-BQMvEllz.d.ts} +2 -2
- package/package.json +1 -1
- package/dist/logger-DDd5C--Z.d.ts +0 -12
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { D as DefaultLogger, a as DefaultLoggerOptions } from '../logger-
|
|
2
|
-
export { D as DefaultPathResolver, a as DefaultTokenCounter } from '../path-resolver-
|
|
3
|
-
export { C as ContextManagerAction, a as ContextManagerInput, b as ContextManagerResult, c as ContextManagerToolOptions, d as allServers, e as awsServer, f as blockServer, g as braveSearchServer, h as context7Server, i as contextManagerTool, j as createContextManagerTool, k as everArtServer, l as filesystemServer, m as githubServer, n as googleMapsServer, o as miniMaxVisionServer, s as sentinelServer, p as slackServer, z as zaiVisionServer } from '../mcp-servers-
|
|
4
|
-
import '../logger-
|
|
5
|
-
import '../events-
|
|
6
|
-
import '../context-
|
|
7
|
-
import '../models-registry-
|
|
1
|
+
export { D as DefaultLogger, a as DefaultLoggerOptions } from '../logger-C_27pj9i.js';
|
|
2
|
+
export { D as DefaultPathResolver, a as DefaultTokenCounter } from '../path-resolver-UPFTsDyD.js';
|
|
3
|
+
export { C as ContextManagerAction, a as ContextManagerInput, b as ContextManagerResult, c as ContextManagerToolOptions, d as allServers, e as awsServer, f as blockServer, g as braveSearchServer, h as context7Server, i as contextManagerTool, j as createContextManagerTool, k as everArtServer, l as filesystemServer, m as githubServer, n as googleMapsServer, o as miniMaxVisionServer, s as sentinelServer, p as slackServer, z as zaiVisionServer } from '../mcp-servers-Dck3T85_.js';
|
|
4
|
+
import '../logger-B72yyPc6.js';
|
|
5
|
+
import '../events-DnRqXaZ3.js';
|
|
6
|
+
import '../context-ToHAp4-U.js';
|
|
7
|
+
import '../models-registry-Be3osGt5.js';
|
|
8
8
|
import '../path-resolver-CPRj4bFY.js';
|
|
9
|
-
import '../compactor-
|
|
10
|
-
import '../config-
|
|
9
|
+
import '../compactor-CJq7LQev.js';
|
|
10
|
+
import '../config-_DZ7dN-T.js';
|
|
@@ -11,8 +11,10 @@ function isStdoutTTY() {
|
|
|
11
11
|
}
|
|
12
12
|
function writeTo(s, stream) {
|
|
13
13
|
if (!stream || typeof stream.write !== "function") return false;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
{
|
|
15
|
+
stream.write(s);
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
16
18
|
}
|
|
17
19
|
function writeErr(s, stream = process.stderr) {
|
|
18
20
|
return writeTo(s, stream);
|
|
@@ -247,7 +249,7 @@ var DefaultTokenCounter = class {
|
|
|
247
249
|
} else if (this.registry && this.providerId && model) {
|
|
248
250
|
if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {
|
|
249
251
|
const keys = [...this.priceCache.keys()];
|
|
250
|
-
this.priceCache.delete(keys[0]);
|
|
252
|
+
this.priceCache.delete(keys[0] ?? "");
|
|
251
253
|
}
|
|
252
254
|
void this.registry.getModel(this.providerId, model).then((m) => {
|
|
253
255
|
if (m) {
|
|
@@ -272,7 +274,7 @@ var DefaultTokenCounter = class {
|
|
|
272
274
|
const price = priceFromModel(resolved);
|
|
273
275
|
if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {
|
|
274
276
|
const keys = [...this.priceCache.keys()];
|
|
275
|
-
this.priceCache.delete(keys[0]);
|
|
277
|
+
this.priceCache.delete(keys[0] ?? "");
|
|
276
278
|
}
|
|
277
279
|
this.priceCache.set(resolved.modelId, price);
|
|
278
280
|
this.applyPrice(usage, price);
|
|
@@ -466,6 +468,12 @@ var allServers = () => ({
|
|
|
466
468
|
});
|
|
467
469
|
|
|
468
470
|
// src/utils/message-invariants.ts
|
|
471
|
+
function expectDefined(value) {
|
|
472
|
+
if (value === null || value === void 0) {
|
|
473
|
+
throw new Error("Expected value to be defined");
|
|
474
|
+
}
|
|
475
|
+
return value;
|
|
476
|
+
}
|
|
469
477
|
function repairToolUseAdjacency(messages) {
|
|
470
478
|
const removedToolUses = [];
|
|
471
479
|
const removedToolResults = [];
|
|
@@ -473,7 +481,7 @@ function repairToolUseAdjacency(messages) {
|
|
|
473
481
|
let changed = false;
|
|
474
482
|
const out = [];
|
|
475
483
|
for (let i = 0; i < messages.length; i++) {
|
|
476
|
-
const original = messages[i];
|
|
484
|
+
const original = expectDefined(messages[i]);
|
|
477
485
|
let msg = original;
|
|
478
486
|
if (hasToolUse(msg)) {
|
|
479
487
|
const nextIds = toolResultIds(messages[i + 1]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/term.ts","../../src/utils/color.ts","../../src/infrastructure/logger.ts","../../src/infrastructure/path-resolver.ts","../../src/infrastructure/token-counter.ts","../../src/infrastructure/mcp-servers.ts","../../src/utils/message-invariants.ts","../../src/utils/token-estimate.ts","../../src/infrastructure/context-manager.ts"],"names":["path","fs2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TTY detection helpers — the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, …) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top — keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24×80 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener — leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (!input || input.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument — the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n stream.write(s);\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** — stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** — routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** — closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story — just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" — which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n","import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (process.env.NO_COLOR) return false;\n if (process.env.FORCE_COLOR) return true;\n return isStdoutTTY();\n};\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape regex\n /\\x1b\\[[0-9;]*[A-Za-z]/g,\n '',\n );\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { LogLevel, Logger } from '../types/logger.js';\nimport { color } from '../utils/color.js';\nimport { writeErr } from '../utils/term.js';\n\nconst LEVEL_RANK: Record<LogLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n};\n\nconst COLORS: Record<LogLevel, (s: string) => string> = {\n error: color.red,\n warn: color.yellow,\n info: color.cyan,\n debug: color.gray,\n trace: color.dim,\n};\n\nexport interface DefaultLoggerOptions {\n level?: LogLevel;\n file?: string;\n pretty?: boolean;\n bindings?: Record<string, unknown>;\n /**\n * When false, suppress stderr output entirely — only write to the log\n * file (if configured). Use this in TUI mode so plugin/library log\n * messages don't interleave with Ink's terminal rendering and break\n * the Static/live boundary in non-altScreen mode.\n * Default: true (stderr output is enabled).\n */\n stderr?: boolean;\n}\n\nexport class DefaultLogger implements Logger {\n level: LogLevel;\n private readonly file?: string;\n private readonly bindings: Record<string, unknown>;\n private readonly pretty: boolean;\n private readonly stderr: boolean;\n\n constructor(opts: DefaultLoggerOptions = {}) {\n this.level = opts.level ?? (process.env.WRONGSTACK_LOG_LEVEL as LogLevel) ?? 'info';\n this.file = opts.file;\n this.bindings = opts.bindings ?? {};\n this.pretty = opts.pretty ?? true;\n this.stderr = opts.stderr !== false; // default true\n if (this.file) {\n try {\n fs.mkdirSync(path.dirname(this.file), { recursive: true });\n } catch {\n // best-effort\n }\n }\n }\n\n error(msg: string, ctx?: unknown): void {\n this.log('error', msg, ctx);\n }\n warn(msg: string, ctx?: unknown): void {\n this.log('warn', msg, ctx);\n }\n info(msg: string, ctx?: unknown): void {\n this.log('info', msg, ctx);\n }\n debug(msg: string, ctx?: unknown): void {\n this.log('debug', msg, ctx);\n }\n trace(msg: string, ctx?: unknown): void {\n this.log('trace', msg, ctx);\n }\n\n child(bindings: Record<string, unknown>): Logger {\n return new DefaultLogger({\n level: this.level,\n file: this.file,\n pretty: this.pretty,\n stderr: this.stderr,\n bindings: { ...this.bindings, ...bindings },\n });\n }\n\n private log(level: LogLevel, msg: string, ctx?: unknown): void {\n const r = LEVEL_RANK[level];\n const allowed = LEVEL_RANK[this.level];\n if (r > allowed) return;\n const ts = new Date().toISOString();\n const entry: Record<string, unknown> = { ts, level, msg, ...this.bindings };\n if (ctx !== undefined) {\n entry.ctx = ctx instanceof Error ? { message: ctx.message, stack: ctx.stack } : ctx;\n }\n // Disk: JSON line\n if (this.file) {\n try {\n fs.appendFileSync(this.file, `${JSON.stringify(entry)}\\n`);\n } catch {\n // ignore\n }\n }\n // Stderr: pretty or json. Suppressed when this.stderr is false (TUI mode)\n // so plugin/library log messages don't interleave with Ink's rendering.\n if (!this.stderr) return;\n if (r <= LEVEL_RANK.warn || this.level === 'debug' || this.level === 'trace') {\n const head = `${color.dim(ts)} ${COLORS[level](level.toUpperCase().padEnd(5))} ${msg}`;\n if (ctx !== undefined) {\n writeErr(`${head} ${formatCtx(ctx)}\\n`);\n } else {\n writeErr(`${head}\\n`);\n }\n }\n }\n}\n\nfunction formatCtx(ctx: unknown): string {\n if (ctx instanceof Error) return color.dim(ctx.message);\n if (typeof ctx === 'string') return color.dim(ctx);\n try {\n return color.dim(JSON.stringify(ctx));\n } catch {\n return color.dim(String(ctx));\n }\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { PathResolver } from '../types/path-resolver.js';\n\nconst PROJECT_MARKERS = [\n '.git',\n 'package.json',\n 'pnpm-workspace.yaml',\n 'go.mod',\n 'Cargo.toml',\n 'pyproject.toml',\n // Use AGENTS.md, not the bare .wrongstack directory. A bare .wrongstack/\n // directory can be the global config directory (~/.wrongstack), which is\n // NOT a project marker. Only .wrongstack/AGENTS.md signals a real\n // WrongStack project.\n '.wrongstack/AGENTS.md',\n];\n\nexport class DefaultPathResolver implements PathResolver {\n readonly projectRoot: string;\n readonly cwd: string;\n\n constructor(cwd: string = process.cwd()) {\n this.cwd = path.resolve(cwd);\n this.projectRoot = this.detectProjectRoot(this.cwd);\n }\n\n detectProjectRoot(start: string): string {\n let dir = path.resolve(start);\n const root = path.parse(dir).root;\n const home = path.resolve(os.homedir());\n const startPath = path.resolve(start);\n while (dir !== root) {\n // Don't walk past the user home directory. Home often has stray\n // markers (.git for dotfile tracking, package.json from global\n // tooling) that are unrelated to the actual working directory.\n // When cwd IS home we still check markers there — this guard\n // only fires during the upward walk from a subdirectory.\n if (dir === home && dir !== startPath) {\n break;\n }\n for (const marker of PROJECT_MARKERS) {\n try {\n fs.accessSync(path.join(dir, marker));\n return dir;\n } catch {\n // continue\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startPath;\n }\n\n resolve(input: string): string {\n const abs = path.isAbsolute(input) ? input : path.resolve(this.cwd, input);\n let real: string;\n try {\n real = fs.realpathSync(abs);\n } catch {\n // path doesn't exist yet; normalize without resolving symlinks\n real = path.normalize(abs);\n }\n return real;\n }\n\n isInsideRoot(absPath: string): boolean {\n const normalized = path.normalize(absPath);\n const root = path.normalize(this.projectRoot);\n if (normalized === root) return true;\n const rel = path.relative(root, normalized);\n return !rel.startsWith('..') && !path.isAbsolute(rel);\n }\n\n ensureInsideRoot(absPath: string): string {\n const resolved = this.resolve(absPath);\n if (!this.isInsideRoot(resolved)) {\n // Render the input as a project-relative-looking string when possible\n // so the error message can flow through telemetry / LLM transcripts\n // without leaking the absolute project root layout.\n const display = path.isAbsolute(absPath) ? path.basename(absPath) : absPath;\n const err = new Error(`Path \"${display}\" resolves outside the project root`);\n // Keep the full information available to programmatic callers; only\n // the user-facing `message` is sanitized.\n (err as Error & { fullPath?: string; projectRoot?: string }).fullPath = absPath;\n (err as Error & { fullPath?: string; projectRoot?: string }).projectRoot = this.projectRoot;\n throw err;\n }\n return resolved;\n }\n}\n","import type { EventBus } from '../kernel/events.js';\nimport type { ModelsRegistry, ResolvedModel } from '../types/models-registry.js';\nimport type { Usage } from '../types/provider.js';\nimport type { CacheStats, TokenCounter } from '../types/token-counter.js';\n\ninterface PriceEntry {\n input?: number;\n output?: number;\n cacheRead?: number;\n cacheWrite?: number;\n}\n\nconst PRICE_CACHE_MAX_SIZE = 100;\n\n/**\n * Token counter that derives pricing from the ModelsRegistry instead of a\n * hardcoded table. If a model is unknown to the registry (or the registry is\n * unavailable) the counter still tracks token totals but reports zero cost.\n */\nexport class DefaultTokenCounter implements TokenCounter {\n private input = 0;\n private output = 0;\n private cacheRead = 0;\n private cacheWrite = 0;\n private costInput = 0;\n private costOutput = 0;\n private readonly registry?: ModelsRegistry;\n private readonly providerId?: string;\n private readonly events?: EventBus;\n private priceCache = new Map<string, PriceEntry>();\n /** Most recently accounted request's tokens. Used for per-request context pressure. */\n private lastInput = 0;\n private lastCacheRead = 0;\n\n constructor(opts: { registry?: ModelsRegistry; providerId?: string; events?: EventBus } = {}) {\n this.registry = opts.registry;\n this.providerId = opts.providerId;\n this.events = opts.events;\n }\n\n account(usage: Usage, model?: string): void {\n this.input += usage.input;\n this.output += usage.output;\n this.cacheRead += usage.cacheRead ?? 0;\n this.cacheWrite += usage.cacheWrite ?? 0;\n // Snapshot per-request tokens for context pressure tracking.\n this.lastInput = usage.input;\n this.lastCacheRead = usage.cacheRead ?? 0;\n\n const price = model ? this.priceCache.get(model) : undefined;\n if (price) {\n this.applyPrice(usage, price);\n } else if (this.registry && this.providerId && model) {\n // Evict oldest entry when cache is full before async lookup.\n if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {\n const keys = [...this.priceCache.keys()];\n this.priceCache.delete(keys[0]!);\n }\n // Async lookup — populate cache, but don't block this call.\n void this.registry\n .getModel(this.providerId, model)\n .then((m) => {\n if (m) {\n const p = priceFromModel(m);\n this.priceCache.set(model, p);\n this.applyPrice(usage, p);\n }\n })\n .catch(() => {\n // Emit so observability tooling can detect unknown models.\n this.events?.emit('token.cost_estimate_unavailable', { model: model ?? '<unknown>' });\n return undefined;\n });\n }\n }\n\n /** Synchronous variant for code paths that have already resolved the model. */\n accountWithModel(usage: Usage, resolved: ResolvedModel): void {\n this.input += usage.input;\n this.output += usage.output;\n this.cacheRead += usage.cacheRead ?? 0;\n this.cacheWrite += usage.cacheWrite ?? 0;\n // Snapshot per-request tokens for context pressure tracking.\n this.lastInput = usage.input;\n this.lastCacheRead = usage.cacheRead ?? 0;\n const price = priceFromModel(resolved);\n if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {\n const keys = [...this.priceCache.keys()];\n this.priceCache.delete(keys[0]!);\n }\n this.priceCache.set(resolved.modelId, price);\n this.applyPrice(usage, price);\n }\n\n total(): Usage {\n return {\n input: this.input,\n output: this.output,\n cacheRead: this.cacheRead,\n cacheWrite: this.cacheWrite,\n };\n }\n\n currentRequestTokens(): { input: number; cacheRead: number } {\n return { input: this.lastInput, cacheRead: this.lastCacheRead };\n }\n\n estimateCost(): { input: number; output: number; total: number; currency: 'USD' } {\n return {\n input: round4(this.costInput),\n output: round4(this.costOutput),\n total: round4(this.costInput + this.costOutput),\n currency: 'USD',\n };\n }\n\n cacheStats(): CacheStats {\n // Hit ratio: cacheRead / (cacheRead + input). `input` from the provider\n // is the count of fresh-token reads, so this answers \"what fraction of\n // the prompt did we get for the cache price?\"\n const denom = this.cacheRead + this.input;\n return {\n readTokens: this.cacheRead,\n writeTokens: this.cacheWrite,\n hitRatio: denom === 0 ? 0 : this.cacheRead / denom,\n };\n }\n\n /** Invalidate cached prices so the next account() call fetches fresh data. */\n invalidateCache(): void {\n this.priceCache.clear();\n }\n\n reset(): void {\n this.input = 0;\n this.output = 0;\n this.cacheRead = 0;\n this.cacheWrite = 0;\n this.costInput = 0;\n this.costOutput = 0;\n }\n\n private applyPrice(usage: Usage, price: PriceEntry): void {\n if (price.input) this.costInput += (usage.input / 1_000_000) * price.input;\n if (price.output) this.costOutput += (usage.output / 1_000_000) * price.output;\n if (usage.cacheRead && price.cacheRead) {\n this.costInput += (usage.cacheRead / 1_000_000) * price.cacheRead;\n }\n if (usage.cacheWrite && price.cacheWrite) {\n this.costInput += (usage.cacheWrite / 1_000_000) * price.cacheWrite;\n }\n }\n}\n\nfunction priceFromModel(m: ResolvedModel): PriceEntry {\n return {\n input: m.cost?.input,\n output: m.cost?.output,\n cacheRead: m.cost?.cache_read,\n cacheWrite: m.cost?.cache_write,\n };\n}\n\nfunction round4(n: number): number {\n return Math.round(n * 10_000) / 10_000;\n}\n","import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config — see notes below.\n *\n * Transport types:\n * stdio — spawns a local npm package binary via child_process\n * sse — HTTP SSE endpoint (client POSTs requests)\n * streamable-http — session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API — issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n permission: 'confirm',\n});\n\n/**\n * Context7 — codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search — web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY — free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) — Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt — AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n permission: 'confirm',\n});\n\n/**\n * Slack — messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack — messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base — EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS — EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps — directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps — directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n permission: 'confirm',\n});\n\n/** Sentinel — security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool — require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP — image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP — image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * MiniMax Token Plan MCP — web_search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP — image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/** Everything bundled — full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n});\n","import type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\n\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = messages[i]!;\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(\n msg: Message,\n fn: (blocks: ContentBlock[]) => ContentBlock[],\n): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n if (typeof msg.content === 'string') return msg.content.trim().length === 0;\n return msg.content.length === 0;\n}\n","/**\n * Shared token estimation with JSON.stringify caching.\n * Avoids repeated stringification of tool input objects.\n *\n * ## Calibration\n *\n * `estimateRequestTokens` uses a fixed 3.5 chars/token heuristic — a\n * conservative overestimate that prevents underestimation but reduces\n * accuracy. After each API call, call `recordActualUsage()` with the\n * real `usage.input` from the provider response. The module maintains a\n * rolling average of `actual / estimated` ratio (EWM, α=0.3) and\n * applies it to subsequent calls via `estimateRequestTokensCalibrated`.\n *\n * Calibration is per-module (shared across all callers), which is\n * sufficient: the chars/token ratio is a property of the tokenizer,\n * not the model. Uncalibrated calls (before any samples, or when\n * `recordActualUsage` is not called) fall back to the uncalibrated\n * estimate so nothing breaks.\n */\n\nconst RoughTokenEstimate = (text: string, charsPerToken = 3.5): number =>\n Math.max(1, Math.ceil(text.length / charsPerToken));\n\n/** Calibration state: actual/estimated ratio via exponential weighted moving average. */\nconst _cal = {\n ratio: 1.0, // current calibration multiplier (actual / estimated)\n count: 0, // number of samples recorded\n prevEst: 0, // estimated tokens from the most recent estimateRequestTokens call\n /** EWM α — higher = faster adaptation, more volatile */\n alpha: 0.3,\n};\n\nconst MIN_SAMPLES_FOR_CALIBRATION = 3;\n\n/**\n * Cache of computed estimates keyed by the stringified input — not the\n * input object itself. Previously the cache was keyed by the input object\n * via WeakMap, but JSON.stringify() produces a new object reference each\n * call so the cache never hit. Now we use a Map with string keys so that\n * repeated stringifications of the same structure share a single entry.\n */\nconst ESTIMATE_CACHE = new Map<string, number>();\n\nconst ESTIMATE_CACHE_MAX_SIZE = 10_000;\n\nfunction getCachedEstimate(key: string, compute: () => number): number {\n const existing = ESTIMATE_CACHE.get(key);\n if (existing !== undefined) return existing;\n if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {\n // Evict oldest quarter when at capacity — simple LRU-ish policy.\n const keys = [...ESTIMATE_CACHE.keys()];\n for (let i = 0; i < Math.floor(ESTIMATE_CACHE_MAX_SIZE / 4); i++) {\n ESTIMATE_CACHE.delete(keys[i]!);\n }\n }\n const estimate = compute();\n ESTIMATE_CACHE.set(key, estimate);\n return estimate;\n}\n\n/**\n * Estimate tokens for a tool_use block input.\n * Caches the stringified result keyed by the stable string representation\n * to avoid repeated JSON.stringify calls during context window checks.\n */\nexport function estimateToolInputTokens(input: unknown): number {\n if (typeof input === 'string') return RoughTokenEstimate(input);\n if (input === null || typeof input !== 'object') {\n return RoughTokenEstimate(String(input));\n }\n const key = JSON.stringify(input);\n return getCachedEstimate(key, () => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a tool_result content.\n */\nexport function estimateToolResultTokens(content: string | unknown): number {\n if (typeof content === 'string') return RoughTokenEstimate(content);\n const key = JSON.stringify(content);\n return getCachedEstimate(key, () => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a text block.\n */\nexport function estimateTextTokens(text: string): number {\n return RoughTokenEstimate(text);\n}\n\n/**\n * Rough estimate of tokens in a tool definition (name + description + schema).\n * Accounts for the JSON-serialized inputSchema which is sent to the API\n * but NOT included in roughEstimate(content).\n */\nexport function estimateToolDefTokens(tool: { name: string; description?: string; inputSchema: unknown }): number {\n return RoughTokenEstimate(tool.name) +\n RoughTokenEstimate(tool.description ?? '') +\n RoughTokenEstimate(JSON.stringify(tool.inputSchema));\n}\n\n/**\n * Estimate the total API request token count: system prompt + tool definitions\n * + conversation messages. Use this for context-window bar calculations\n * instead of roughEstimate (which only counts messages).\n *\n * The overhead ratio (overhead / messages) varies by conversation length:\n * - Short conversations (< 10 messages): ~30-50% overhead (large system+tools)\n * - Medium (10-50 messages): ~15-30%\n * - Long (> 50 messages): ~5-15%\n *\n * Returns { messages, systemPrompt, tools, total } for debugging display.\n */\nexport interface RequestTokenBreakdown {\n messages: number;\n systemPrompt: number;\n tools: number;\n total: number;\n}\n\nexport function estimateRequestTokens(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string; inputSchema: unknown }[],\n): RequestTokenBreakdown {\n // Messages: apply the same logic as roughEstimate\n let messagesTokens = 0;\n if (typeof messages === 'string') {\n messagesTokens = RoughTokenEstimate(messages);\n } else if (Array.isArray(messages)) {\n for (const m of messages) {\n if (typeof m === 'object' && m !== null && 'content' in m) {\n const content = (m as { content: unknown }).content;\n if (typeof content === 'string') {\n messagesTokens += RoughTokenEstimate(content);\n } else if (Array.isArray(content)) {\n for (const b of content) {\n if (typeof b === 'object' && b !== null) {\n if ((b as { type?: string }).type === 'text') {\n messagesTokens += RoughTokenEstimate((b as { text: string }).text);\n } else {\n messagesTokens += RoughTokenEstimate(JSON.stringify(b));\n }\n }\n }\n }\n }\n }\n }\n\n // System prompt\n let systemTokens = 0;\n if (typeof systemPrompt === 'string') {\n systemTokens = RoughTokenEstimate(systemPrompt);\n } else if (Array.isArray(systemPrompt)) {\n for (const b of systemPrompt) {\n if (typeof b === 'object' && b !== null && (b as { type?: string }).type === 'text') {\n systemTokens += RoughTokenEstimate((b as { text: string }).text);\n }\n }\n }\n\n // Tool definitions\n let toolsTokens = 0;\n for (const t of tools) {\n toolsTokens += estimateToolDefTokens(t);\n }\n\n const total = messagesTokens + systemTokens + toolsTokens;\n\n // Record the raw estimate for calibration: the next recordActualUsage()\n // call will pair this against the actual API usage so the rolling ratio\n // stays in sync with the real chars/token ratio of the content.\n _cal.prevEst = total;\n\n return {\n messages: messagesTokens,\n systemPrompt: systemTokens,\n tools: toolsTokens,\n total,\n };\n}\n\n/**\n * Record the actual API input token count after a provider call so\n * `estimateRequestTokensCalibrated` can self-correct on subsequent calls.\n *\n * Prefer passing `estimatedInputTokens` explicitly (the calibrated pre-flight\n * estimate from the middleware) — this avoids race conditions when other code\n * also calls `estimateRequestTokens` between the pre-flight and this call\n * (e.g. audit logging in agent.ts).\n *\n * When `estimatedInputTokens` is omitted, falls back to `_cal.prevEst`\n * for backward compatibility with callers that don't have the pre-flight value.\n */\nexport function recordActualUsage(actualInputTokens: number, estimatedInputTokens?: number): void {\n if (actualInputTokens <= 0) return;\n const est = estimatedInputTokens ?? _cal.prevEst;\n if (est <= 0) return;\n\n const sampleRatio = actualInputTokens / est;\n if (_cal.count === 0) {\n _cal.ratio = sampleRatio;\n } else {\n // EWM: new = α * sample + (1-α) * old → α=0.3 = fast initial converge\n _cal.ratio = _cal.alpha * sampleRatio + (1 - _cal.alpha) * _cal.ratio;\n }\n // Sanity bound: keep the rolling ratio within [0.5, 1.5] so a sequence\n // of bad samples can't blow up the calibration for everyone.\n _cal.ratio = Math.min(1.5, Math.max(0.5, _cal.ratio));\n _cal.count++;\n}\n\n/**\n * Returns the current calibration state. Exposed for debugging and\n * tests — not needed by normal callers.\n */\nexport function getCalibrationState(): { ratio: number; count: number; calibrated: boolean } {\n return {\n ratio: _cal.ratio,\n count: _cal.count,\n calibrated: _cal.count >= MIN_SAMPLES_FOR_CALIBRATION,\n };\n}\n\n/**\n * Like `estimateRequestTokens` but applies the rolling calibration factor\n * so context pressure readings converge on reality within a few iterations.\n *\n * Before any `recordActualUsage` samples are collected, returns the same\n * result as `estimateRequestTokens` (ratio = 1.0, no distortion).\n * After `MIN_SAMPLES_FOR_CALIBRATION` samples, applies the calibrated\n * multiplier capped to the range [0.5, 1.5] as a sanity bound.\n */\nexport function estimateRequestTokensCalibrated(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string; inputSchema: unknown }[],\n): RequestTokenBreakdown {\n const result = estimateRequestTokens(messages, systemPrompt, tools);\n\n if (_cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {\n const safeRatio = Math.min(1.5, Math.max(0.5, _cal.ratio));\n return {\n messages: Math.round(result.messages * safeRatio),\n systemPrompt: Math.round(result.systemPrompt * safeRatio),\n tools: Math.round(result.tools * safeRatio),\n total: Math.round(result.total * safeRatio),\n };\n }\n\n return result;\n}\n\n/**\n * Resets calibration state. Primarily for tests that run in the same\n * process and need a clean slate between suites.\n */\nexport function resetCalibration(): void {\n _cal.ratio = 1.0;\n _cal.count = 0;\n _cal.prevEst = 0;\n}\n","import type { Context } from '../core/context.js';\nimport type { Compactor } from '../types/compactor.js';\nimport type { Message } from '../types/messages.js';\nimport type { Tool } from '../types/tool.js';\nimport { repairToolUseAdjacency } from '../utils/message-invariants.js';\nimport { estimateRequestTokens } from '../utils/token-estimate.js';\n\n/**\n * Context introspection and management tool.\n * Allows the model to:\n * - \"check\" → see token budget and message counts\n * - \"summary\" → summarize and replace a range of messages\n * - \"prune\" → remove specific message indices\n * - \"add_note\" → inject a summary note at a specific point\n * - \"compact\" → run compaction via the injected compactor\n */\nexport const CONTEXT_MANAGER_TOOL_NAME = 'context_manager';\n\nexport type ContextManagerAction =\n | 'check'\n | 'summary'\n | 'prune'\n | 'add_note'\n | 'compact'\n | 'repair';\n\nexport interface ContextManagerInput {\n action: ContextManagerAction;\n /** 0-based message indices for prune/summary (inclusive). */\n from?: number;\n to?: number;\n /** Text for add_note / summary actions. For summary, this is the LLM-provided summary text. */\n text?: string;\n /** Inject after which index (for add_note). Defaults to prepend (0). */\n afterIndex?: number;\n /**\n * System prompt blocks for accurate total token estimation in check action.\n * When provided, check returns the full API request estimate\n * (messages + system + tools) instead of just message tokens.\n */\n systemPrompt?: unknown;\n /**\n * Registered tools for accurate total token estimation in check action.\n * Each tool's name + description + inputSchema is counted.\n */\n tools?: { name: string; description?: string; inputSchema: unknown }[];\n}\n\nexport interface ContextManagerResult {\n action: ContextManagerAction;\n beforeTokens: number;\n afterTokens?: number;\n removedCount?: number;\n messageCount: number;\n summary?: string;\n notes?: string;\n repaired?: {\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n };\n}\n\n/**\n * Options for creating a context manager tool.\n * `compactor` is required for the \"compact\" action; without it the action returns an error.\n */\nexport interface ContextManagerToolOptions {\n compactor?: Compactor;\n /**\n * Optional sub-LLM summarizer. When provided, the \"summary\" action calls this\n * to produce real summaries of message ranges instead of placeholder text.\n * (signature matches Provider.complete — return the summary text in result.content[0].text)\n */\n summarizer?: (messages: Message[]) => Promise<string>;\n /**\n * Minimum full-request token count before the compact action is allowed to run.\n * Prevents unnecessary compaction calls when context is small.\n * Default: 0 (always allow). Set to ~5000 for meaningful compaction targets.\n */\n minCompactThreshold?: number;\n /**\n * Minimum token growth required before retrying after a NOOP compaction.\n * A NOOP is when compaction saved nothing (preserveK protects everything,\n * no oversized tool_results). Default: 2000.\n */\n noopRetryDeltaTokens?: number;\n /**\n * Provider's max context window in tokens. Used to compute a relative\n * threshold when `minCompactThreshold` is not set. Default: 128_000.\n */\n maxContext?: number;\n /**\n * Fraction of maxContext that triggers compaction. Only used when\n * `minCompactThreshold` is not set. Default: 0.5 (50% of maxContext).\n */\n compactThresholdFraction?: number;\n}\n\nfunction roughEstimate(messages: Message[]): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m.content === 'string') {\n total += Math.ceil(m.content.length / 4);\n } else if (Array.isArray(m.content)) {\n for (const b of m.content) {\n if (b.type === 'text') total += Math.ceil(b.text.length / 4);\n else if (b.type === 'tool_use' || b.type === 'tool_result') {\n total += Math.ceil(JSON.stringify(b).length / 4);\n }\n }\n }\n }\n return total;\n}\n\nexport function createContextManagerTool(\n opts: ContextManagerToolOptions = {},\n): Tool<ContextManagerInput, ContextManagerResult> {\n const minCompactThreshold = opts.minCompactThreshold ?? 0;\n const noopRetryDeltaTokens = opts.noopRetryDeltaTokens ?? 2_000;\n const maxContext = opts.maxContext ?? 128_000;\n const compactThresholdFraction = opts.compactThresholdFraction ?? 0.5;\n const effectiveThreshold = minCompactThreshold > 0\n ? minCompactThreshold\n : Math.floor(maxContext * compactThresholdFraction);\n\n // Tracks the most recent NOOP attempt so we can skip retry until context grows.\n let lastNoopTokens = 0;\n\n return {\n name: CONTEXT_MANAGER_TOOL_NAME,\n description:\n 'Inspect or reorganize the conversation context window. ' +\n 'Use \"check\" to see token budget. ' +\n 'Use \"summary\" to collapse a message range into a concise note (provide \"text\" for custom summary). ' +\n 'Use \"prune\" to remove specific messages by index. ' +\n 'Use \"add_note\" to inject a summary note. ' +\n 'Use \"compact\" to run aggressive compaction. ' +\n 'Use \"repair\" to remove orphan tool_use/tool_result blocks after manual context surgery.',\n inputSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['check', 'summary', 'prune', 'add_note', 'compact', 'repair'],\n description: 'The context operation to perform.',\n },\n from: {\n type: 'number',\n description: 'Start index (inclusive) for summary/prune operations.',\n },\n to: {\n type: 'number',\n description: 'End index (inclusive) for summary/prune operations.',\n },\n text: {\n type: 'string',\n description:\n 'Summary or note text. For \"summary\": the model-provided summary of the removed range. ' +\n 'For \"add_note\": the note to inject.',\n },\n afterIndex: {\n type: 'number',\n description: 'Insert after this index (for add_note). Defaults to prepend (0).',\n },\n },\n required: ['action'],\n },\n permission: 'auto',\n mutating: true,\n\n async execute(input: ContextManagerInput, ctx: Context): Promise<ContextManagerResult> {\n const messages = ctx.messages;\n const beforeTokens = roughEstimate(messages);\n\n // When ctx.state is available, route mutations through the observer\n // layer so subscribers stay in sync. Fall back to direct splice for\n // tests and environments that haven't wired ConversationState.\n const applyMessages = (next: Message[]) => {\n const repaired = repairToolUseAdjacency(next);\n const finalMessages = repaired.messages;\n if (ctx.state) {\n ctx.state.replaceMessages(finalMessages);\n } else {\n messages.length = 0;\n messages.splice(0, 0, ...finalMessages);\n }\n return repaired.report;\n };\n\n switch (input.action) {\n case 'check': {\n // Prefer the full API request estimate when systemPrompt + tools are available.\n // This is the accurate number for context-window bar display.\n // Falls back to roughEstimate (messages-only) for backward compat and test environments.\n const estimate = (input.systemPrompt != null && Array.isArray(input.tools))\n ? estimateRequestTokens(messages, input.systemPrompt, input.tools)\n : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };\n return {\n action: 'check',\n beforeTokens: estimate.total,\n messageCount: messages.length,\n notes: JSON.stringify({\n messages: messages.length,\n tokens: estimate.total,\n msgTokens: estimate.messages,\n sysTokens: estimate.systemPrompt,\n toolTokens: estimate.tools,\n readFiles: ctx.readFiles.size,\n todos: ctx.todos.length,\n inProgress: ctx.todos.filter((t) => t.status === 'in_progress').length,\n }),\n };\n }\n\n case 'repair': {\n const repair = applyMessages([...messages]);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'repair',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n notes: repair.changed\n ? 'Context tool-call adjacency repaired.'\n : 'Context tool-call adjacency already valid.',\n };\n }\n\n case 'compact': {\n if (!opts.compactor) {\n return {\n action: 'compact',\n beforeTokens,\n messageCount: messages.length,\n notes: 'No compactor registered. Use /compact aggressive via slash command instead.',\n };\n }\n // Compute full request tokens for threshold check.\n const fullEstimate = (input.systemPrompt != null && Array.isArray(input.tools))\n ? estimateRequestTokens(messages, input.systemPrompt, input.tools)\n : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };\n const currentTokens = fullEstimate.total;\n\n // NOOP retry prevention: skip if the previous compaction saved nothing\n // and context hasn't grown enough to make another attempt worthwhile.\n if (lastNoopTokens > 0) {\n const delta = currentTokens - lastNoopTokens;\n if (delta < noopRetryDeltaTokens) {\n return {\n action: 'compact',\n beforeTokens,\n afterTokens: beforeTokens,\n messageCount: messages.length,\n notes: `Compact is a NOOP retry: context grew only ${delta} tokens since the last no-op attempt (threshold: ${noopRetryDeltaTokens}). Skip until more content accumulates.`,\n };\n }\n }\n\n // Minimum threshold check: skip if context is too small to benefit.\n if (currentTokens < effectiveThreshold) {\n return {\n action: 'compact',\n beforeTokens,\n afterTokens: beforeTokens,\n messageCount: messages.length,\n notes: `Context tokens (${currentTokens}) below compact threshold (${effectiveThreshold}). Skipping.`,\n };\n }\n\n const report = await opts.compactor.compact(ctx);\n ctx.clearFileTracking();\n const repair = applyMessages([...ctx.messages]);\n const afterTokens = repair.changed ? roughEstimate(ctx.messages) : report.after;\n const repaired = report.repaired ?? (repair.changed ? repair : undefined);\n\n // Record NOOP state: did compaction actually reduce tokens?\n const reduced = report.fullRequestTokensBefore > report.fullRequestTokensAfter;\n const repairedSomething = !!report.repaired;\n if (reduced || repairedSomething) {\n lastNoopTokens = 0;\n } else {\n lastNoopTokens = currentTokens;\n }\n\n return {\n action: 'compact',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n repaired: repaired\n ? {\n removedToolUses: repaired.removedToolUses,\n removedToolResults: repaired.removedToolResults,\n removedMessages: repaired.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'prune': {\n const from = input.from ?? 0;\n const to = input.to ?? messages.length - 1;\n if (from < 0 || to >= messages.length || from > to) {\n return {\n action: 'prune',\n beforeTokens,\n messageCount: messages.length,\n notes: `Invalid range [${from}, ${to}] for ${messages.length} messages.`,\n };\n }\n const copy = [...messages];\n const removed = copy.splice(from, to - from + 1);\n ctx.clearFileTracking();\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'prune',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n removedCount: removed.length,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'add_note': {\n const noteText = input.text ?? '(no summary)';\n const afterIdx = Math.min(input.afterIndex ?? 0, messages.length);\n const noteMsg: Message = {\n role: 'system',\n content: `[note: ${noteText}]`,\n };\n const copy = [...messages];\n copy.splice(afterIdx, 0, noteMsg);\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'add_note',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n summary: noteText,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'summary': {\n const from = input.from ?? 0;\n const to = input.to ?? messages.length - 1;\n if (from < 0 || to >= messages.length || from > to) {\n return {\n action: 'summary',\n beforeTokens,\n messageCount: messages.length,\n notes: `Invalid range [${from}, ${to}] for ${messages.length} messages.`,\n };\n }\n const summaryText =\n input.text ?? '[summary placeholder — provide \"text\" to record the summary]';\n const summaryMsg: Message = {\n role: 'system',\n content: `[summary of messages ${from}–${to}]: ${summaryText}`,\n };\n const copy = [...messages];\n copy.splice(from, to - from + 1, summaryMsg);\n ctx.clearFileTracking();\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'summary',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n summary: summaryText,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n default:\n return {\n action: input.action,\n beforeTokens,\n messageCount: messages.length,\n notes: `Unknown action: ${input.action}`,\n };\n }\n },\n };\n}\n\n/** Pre-built instance with no compactor — compact action will return an error. */\nexport const contextManagerTool: Tool<ContextManagerInput, ContextManagerResult> =\n createContextManagerTool();\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/term.ts","../../src/utils/color.ts","../../src/infrastructure/logger.ts","../../src/infrastructure/path-resolver.ts","../../src/infrastructure/token-counter.ts","../../src/infrastructure/mcp-servers.ts","../../src/utils/message-invariants.ts","../../src/utils/token-estimate.ts","../../src/infrastructure/context-manager.ts"],"names":["path","fs2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TTY detection helpers — the single source of truth for \"is this process\n * running against a real terminal?\". Replaces ad-hoc `process.stdin.isTTY`\n * / `process.stdout.isTTY` checks scattered across the codebase so that:\n *\n * 1. test code can mock a single module instead of stubbing `isTTY` on\n * every ReadStream/WriteStream the test happens to touch;\n * 2. a future TTY-detection source (an env var override, a Windows\n * ConPTY workaround, …) lands in one place;\n * 3. `isInteractive()` encodes the rule the project already used inline\n * (\"both streams are TTYs AND we're not running under CI\") in one\n * testable helper instead of the same 3-condition check in two\n * different files.\n *\n * Scope: detection only. Raw-mode control (`setRawMode`), resize\n * subscriptions, and write-injection belong to a future, larger TTY\n * abstraction; this module is the smallest pull that gives us a\n * testable seam and dedups 20+ call sites.\n */\n\nconst hasStdout = (): boolean => typeof process !== 'undefined' && !!process.stdout;\nconst hasStdin = (): boolean => typeof process !== 'undefined' && !!process.stdin;\n\n/** True when `process.stdout` is attached to a terminal (not a pipe/file). */\nexport function isStdoutTTY(): boolean {\n return hasStdout() && Boolean(process.stdout.isTTY);\n}\n\n/** True when `process.stdin` is attached to a terminal (not a pipe/file). */\nexport function isStdinTTY(): boolean {\n return hasStdin() && Boolean(process.stdin.isTTY);\n}\n\n/**\n * True when the current process is an interactive session: both stdin and\n * stdout are TTYs. Callers that also need a \"not a single-shot invocation\"\n * or \"not under CI\" check should layer that on top — keeping this helper\n * minimal preserves the original inline checks it replaces.\n */\nexport function isInteractive(): boolean {\n return isStdinTTY() && isStdoutTTY();\n}\n\n/** Current terminal size in characters, with a 24×80 fallback for non-TTYs. */\nexport function getTermSize(): { rows: number; cols: number } {\n if (!hasStdout()) return { rows: 24, cols: 80 };\n return {\n rows: process.stdout.rows ?? 24,\n cols: process.stdout.columns ?? 80,\n };\n}\n\n/**\n * Subscribe to terminal resize events. `cb` is called with the new size each\n * time the underlying stream emits `resize`. Returns a cleanup function the\n * caller MUST call on dispose to remove the listener — leaving a stale\n * `resize` listener on a disposed component leaks the closure (and the\n * component itself, transitively) until the process exits.\n *\n * The stream argument defaults to `process.stdout`. Pass an explicit\n * `NodeJS.WriteStream` when the caller already owns one (e.g. a status line\n * that targets an injected `out` for testability). For non-TTY streams no\n * listener is registered and the returned cleanup is a no-op.\n */\nexport function onResize(\n cb: (size: { rows: number; cols: number }) => void,\n stream: NodeJS.WriteStream = process.stdout,\n): () => void {\n if (!stream || typeof stream.on !== 'function') return () => {};\n const handler = (): void => {\n cb({\n rows: stream.rows ?? 24,\n cols: stream.columns ?? 80,\n });\n };\n stream.on('resize', handler);\n return () => {\n stream.off('resize', handler);\n };\n}\n\n/**\n * Toggle raw mode on a TTY stdin stream. Returns `true` when the toggle was\n * applied, `false` when the stream is null, not a TTY, or doesn't expose\n * `setRawMode` (pipes, file descriptors, Windows ConPTY edge cases). Callers\n * that need to restore the previous mode should snapshot `input.isRaw`\n * BEFORE the call and pass the value to a second call to flip back.\n *\n * Use this helper to drop the now-redundant\n * `if (input.isTTY) input.setRawMode(...)` ceremony at every call site.\n */\nexport function setRawMode(input: NodeJS.ReadStream, mode: boolean): boolean {\n if (!input || input.isTTY !== true) return false;\n if (typeof input.setRawMode !== 'function') return false;\n input.setRawMode(mode);\n return true;\n}\n\n/**\n * Bracket installed by the interactive input reader while a `readline`\n * prompt is on screen. Out-of-band terminal writes — logger WARN/INFO\n * lines, async activity from the Telegram bridge, etc. — go to the same\n * physical terminal as the half-typed prompt but readline has no idea they\n * happened, so it never repaints. The result is the classic corruption the\n * user sees: every async line strands the in-progress draft as a fresh\n * scrollback row (sometimes with its cursor underline).\n *\n * The guard closes that gap. `suspend()` wipes the draft row so the message\n * prints clean; `resume()` repaints the prompt + draft (cursor preserved).\n * When no prompt is active the guard is `null` and writes pass straight\n * through — so agent-turn output (spinner, renderer) is untouched.\n */\nexport interface OutputLineGuard {\n /** Clear the current input row right before an out-of-band write. */\n suspend(): void;\n /** Repaint the prompt + in-progress draft right after the write. */\n resume(): void;\n}\n\nlet activeOutputGuard: OutputLineGuard | null = null;\n\n/**\n * Register (or clear, with `null`) the guard that brackets out-of-band\n * writes. Installed by {@link writeOut}/{@link writeErr} consumers — in\n * practice the CLI's readline input reader — only while a prompt is live.\n * Idempotent; the most recent caller wins.\n */\nexport function setOutputLineGuard(guard: OutputLineGuard | null): void {\n activeOutputGuard = guard;\n}\n\n/**\n * Stream-agnostic write primitive. Returns `false` when the stream is\n * missing or doesn't expose `write` so callers can degrade silently under\n * hostile host environments (closed pipe, mock injects `null`, test\n * replaces the stream with a stub).\n *\n * When an {@link OutputLineGuard} is installed (a readline prompt is on\n * screen) the write is bracketed by `suspend()`/`resume()` so the user's\n * half-typed input survives the interruption instead of being stranded in\n * scrollback. The guard's own redraw uses raw stream writes — never\n * `writeOut`/`writeErr` — so there is no re-entrancy here.\n *\n * **Not exported in the public API.** Exposed only inside `term.ts` for\n * `writeOut` / `writeErr` to share a single implementation. If a caller\n * needs to write to an arbitrary stream, they should call `writeOut` (or\n * `writeErr`) with an explicit `stream` argument — the named functions\n * are the public surface so the \"this is the standard error stream\"\n * intent stays visible at every call site.\n */\nfunction writeTo(\n s: string,\n stream: NodeJS.WriteStream | undefined,\n): boolean {\n if (!stream || typeof stream.write !== 'function') return false;\n const guard = activeOutputGuard;\n if (!guard) {\n stream.write(s);\n return true;\n }\n // A prompt is live — wipe the draft row, emit the message, repaint.\n guard.suspend();\n stream.write(s);\n guard.resume();\n return true;\n}\n\n/**\n * Write `s` to `stream` (defaults to `process.stdout`). Returns `false`\n * when the stream is missing or doesn't expose `write` so callers can\n * degrade silently under hostile host environments (closed pipe, mock\n * injects `null`, test replaces the stream with a stub).\n *\n * Why a helper:\n * 1. **Single seam for output capture in tests** — stub `writeOut` once\n * and assert on what the rest of the codebase intended to print,\n * without spying on `process.stdout.write` (which is brittle and\n * leaks across parallel test files).\n * 2. **Stream swap without grep** — routing the CLI's output to a\n * logger or `out.log` becomes a one-line change at process boot.\n * 3. **Defensive default** — closes the \"what if `process.stdout` is\n * `null`\" gap that currently exists at ~50 call sites that just\n * call `process.stdout.write(s)` and crash on certain Windows\n * redirect invocations.\n *\n * Call-site migration is staged: this commit introduces the helper, a\n * follow-up commit replaces the 50+ `process.stdout.write(...)` sites\n * with `writeOut(...)`. Until that migration lands, both forms coexist\n * and `writeOut` is the preferred form for new code.\n */\nexport function writeOut(\n s: string,\n stream: NodeJS.WriteStream = process.stdout,\n): boolean {\n return writeTo(s, stream);\n}\n\n/**\n * Symmetric partner of `writeOut` for the standard error stream. Same shape,\n * same defensive contract, same single-seam-for-tests story — just defaults to\n * `process.stderr` instead of `process.stdout`.\n *\n * Use this in code paths that emit error/diagnostic/warning text. Keeping\n * these two helpers split (rather than a single `writeTo(s, stream)`) means\n * the call site reads as a clear intent signal: \"I am writing an error\" vs.\n * \"I am writing a result\" — which matters for callers that decide between\n * stdout/stderr routing (e.g. `--quiet` flags, log-level filtering,\n * structured-log rewriters that fork on stream).\n *\n * Stderr writes from the core logger (see `infrastructure/logger.ts`) and from\n * the TUI guard (see `tui/run-tui.ts`) used to call `process.stderr.write`\n * directly. Routing them through this helper lets tests stub the stream at\n * one boundary and lets future logging middleware (e.g. a JSON-line rewriter)\n * swap the destination for the entire process in one place.\n */\nexport function writeErr(\n s: string,\n stream: NodeJS.WriteStream = process.stderr,\n): boolean {\n return writeTo(s, stream);\n}\n","import { isStdoutTTY } from './term.js';\n\nconst isColorTty = (): boolean => {\n if (process.env.NO_COLOR) return false;\n if (process.env.FORCE_COLOR) return true;\n return isStdoutTTY();\n};\n\nconst COLOR = isColorTty();\n\nconst wrap =\n (open: string, close: string) =>\n (s: string): string =>\n COLOR ? `\\x1b[${open}m${s}\\x1b[${close}m` : s;\n\nexport const color = {\n reset: wrap('0', '0'),\n bold: wrap('1', '22'),\n dim: wrap('2', '22'),\n italic: wrap('3', '23'),\n underline: wrap('4', '24'),\n red: wrap('31', '39'),\n green: wrap('32', '39'),\n yellow: wrap('33', '39'),\n blue: wrap('34', '39'),\n magenta: wrap('35', '39'),\n cyan: wrap('36', '39'),\n gray: wrap('90', '39'),\n amber: wrap('38;5;214', '39'),\n pink: wrap('38;5;205', '39'),\n bgRed: wrap('41', '49'),\n bgGreen: wrap('42', '49'),\n};\n\nexport function stripAnsi(s: string): string {\n return s.replace(\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape regex\n /\\x1b\\[[0-9;]*[A-Za-z]/g,\n '',\n );\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { LogLevel, Logger } from '../types/logger.js';\nimport { color } from '../utils/color.js';\nimport { writeErr } from '../utils/term.js';\n\nconst LEVEL_RANK: Record<LogLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n};\n\nconst COLORS: Record<LogLevel, (s: string) => string> = {\n error: color.red,\n warn: color.yellow,\n info: color.cyan,\n debug: color.gray,\n trace: color.dim,\n};\n\nexport interface DefaultLoggerOptions {\n level?: LogLevel | undefined;\n file?: string | undefined;\n pretty?: boolean | undefined;\n bindings?: Record<string, unknown>;\n /**\n * When false, suppress stderr output entirely — only write to the log\n * file (if configured). Use this in TUI mode so plugin/library log\n * messages don't interleave with Ink's terminal rendering.\n * Default: true (stderr output is enabled).\n */\n stderr?: boolean | undefined;\n}\n\nexport class DefaultLogger implements Logger {\n level: LogLevel;\n private readonly file?: string | undefined;\n private readonly bindings: Record<string, unknown>;\n private readonly pretty: boolean;\n private readonly stderr: boolean;\n\n constructor(opts: DefaultLoggerOptions = {}) {\n this.level = opts.level ?? (process.env.WRONGSTACK_LOG_LEVEL as LogLevel) ?? 'info';\n this.file = opts.file;\n this.bindings = opts.bindings ?? {};\n this.pretty = opts.pretty ?? true;\n this.stderr = opts.stderr !== false; // default true\n if (this.file) {\n try {\n fs.mkdirSync(path.dirname(this.file), { recursive: true });\n } catch {\n // best-effort\n }\n }\n }\n\n error(msg: string, ctx?: unknown): void {\n this.log('error', msg, ctx);\n }\n warn(msg: string, ctx?: unknown): void {\n this.log('warn', msg, ctx);\n }\n info(msg: string, ctx?: unknown): void {\n this.log('info', msg, ctx);\n }\n debug(msg: string, ctx?: unknown): void {\n this.log('debug', msg, ctx);\n }\n trace(msg: string, ctx?: unknown): void {\n this.log('trace', msg, ctx);\n }\n\n child(bindings: Record<string, unknown>): Logger {\n return new DefaultLogger({\n level: this.level,\n file: this.file,\n pretty: this.pretty,\n stderr: this.stderr,\n bindings: { ...this.bindings, ...bindings },\n });\n }\n\n private log(level: LogLevel, msg: string, ctx?: unknown): void {\n const r = LEVEL_RANK[level];\n const allowed = LEVEL_RANK[this.level];\n if (r > allowed) return;\n const ts = new Date().toISOString();\n const entry: Record<string, unknown> = { ts, level, msg, ...this.bindings };\n if (ctx !== undefined) {\n entry.ctx = ctx instanceof Error ? { message: ctx.message, stack: ctx.stack } : ctx;\n }\n // Disk: JSON line\n if (this.file) {\n try {\n fs.appendFileSync(this.file, `${JSON.stringify(entry)}\\n`);\n } catch {\n // ignore\n }\n }\n // Stderr: pretty or json. Suppressed when this.stderr is false (TUI mode)\n // so plugin/library log messages don't interleave with Ink's rendering.\n if (!this.stderr) return;\n if (r <= LEVEL_RANK.warn || this.level === 'debug' || this.level === 'trace') {\n const head = `${color.dim(ts)} ${COLORS[level](level.toUpperCase().padEnd(5))} ${msg}`;\n if (ctx !== undefined) {\n writeErr(`${head} ${formatCtx(ctx)}\\n`);\n } else {\n writeErr(`${head}\\n`);\n }\n }\n }\n}\n\nfunction formatCtx(ctx: unknown): string {\n if (ctx instanceof Error) return color.dim(ctx.message);\n if (typeof ctx === 'string') return color.dim(ctx);\n try {\n return color.dim(JSON.stringify(ctx));\n } catch {\n return color.dim(String(ctx));\n }\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { PathResolver } from '../types/path-resolver.js';\n\nconst PROJECT_MARKERS = [\n '.git',\n 'package.json',\n 'pnpm-workspace.yaml',\n 'go.mod',\n 'Cargo.toml',\n 'pyproject.toml',\n // Use AGENTS.md, not the bare .wrongstack directory. A bare .wrongstack/\n // directory can be the global config directory (~/.wrongstack), which is\n // NOT a project marker. Only .wrongstack/AGENTS.md signals a real\n // WrongStack project.\n '.wrongstack/AGENTS.md',\n];\n\nexport class DefaultPathResolver implements PathResolver {\n readonly projectRoot: string;\n readonly cwd: string;\n\n constructor(cwd: string = process.cwd()) {\n this.cwd = path.resolve(cwd);\n this.projectRoot = this.detectProjectRoot(this.cwd);\n }\n\n detectProjectRoot(start: string): string {\n let dir = path.resolve(start);\n const root = path.parse(dir).root;\n const home = path.resolve(os.homedir());\n const startPath = path.resolve(start);\n while (dir !== root) {\n // Don't walk past the user home directory. Home often has stray\n // markers (.git for dotfile tracking, package.json from global\n // tooling) that are unrelated to the actual working directory.\n // When cwd IS home we still check markers there — this guard\n // only fires during the upward walk from a subdirectory.\n if (dir === home && dir !== startPath) {\n break;\n }\n for (const marker of PROJECT_MARKERS) {\n try {\n fs.accessSync(path.join(dir, marker));\n return dir;\n } catch {\n // continue\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startPath;\n }\n\n resolve(input: string): string {\n const abs = path.isAbsolute(input) ? input : path.resolve(this.cwd, input);\n let real: string;\n try {\n real = fs.realpathSync(abs);\n } catch {\n // path doesn't exist yet; normalize without resolving symlinks\n real = path.normalize(abs);\n }\n return real;\n }\n\n isInsideRoot(absPath: string): boolean {\n const normalized = path.normalize(absPath);\n const root = path.normalize(this.projectRoot);\n if (normalized === root) return true;\n const rel = path.relative(root, normalized);\n return !rel.startsWith('..') && !path.isAbsolute(rel);\n }\n\n ensureInsideRoot(absPath: string): string {\n const resolved = this.resolve(absPath);\n if (!this.isInsideRoot(resolved)) {\n // Render the input as a project-relative-looking string when possible\n // so the error message can flow through telemetry / LLM transcripts\n // without leaking the absolute project root layout.\n const display = path.isAbsolute(absPath) ? path.basename(absPath) : absPath;\n const err = new Error(`Path \"${display}\" resolves outside the project root`);\n // Keep the full information available to programmatic callers; only\n // the user-facing `message` is sanitized.\n (err as Error & { fullPath?: string | undefined; projectRoot?: string | undefined }).fullPath = absPath;\n (err as Error & { fullPath?: string | undefined; projectRoot?: string | undefined }).projectRoot = this.projectRoot;\n throw err;\n }\n return resolved;\n }\n}\n","import type { EventBus } from '../kernel/events.js';\nimport type { ModelsRegistry, ResolvedModel } from '../types/models-registry.js';\nimport type { Usage } from '../types/provider.js';\nimport type { CacheStats, TokenCounter } from '../types/token-counter.js';\n\ninterface PriceEntry {\n input?: number | undefined;\n output?: number | undefined;\n cacheRead?: number | undefined;\n cacheWrite?: number | undefined;\n}\n\nconst PRICE_CACHE_MAX_SIZE = 100;\n\n/**\n * Token counter that derives pricing from the ModelsRegistry instead of a\n * hardcoded table. If a model is unknown to the registry (or the registry is\n * unavailable) the counter still tracks token totals but reports zero cost.\n */\nexport class DefaultTokenCounter implements TokenCounter {\n private input = 0;\n private output = 0;\n private cacheRead = 0;\n private cacheWrite = 0;\n private costInput = 0;\n private costOutput = 0;\n private readonly registry?: ModelsRegistry | undefined;\n private readonly providerId?: string | undefined;\n private readonly events?: EventBus | undefined;\n private priceCache = new Map<string, PriceEntry>();\n /** Most recently accounted request's tokens. Used for per-request context pressure. */\n private lastInput = 0;\n private lastCacheRead = 0;\n\n constructor(opts: { registry?: ModelsRegistry | undefined; providerId?: string | undefined; events?: EventBus | undefined } = {}) {\n this.registry = opts.registry;\n this.providerId = opts.providerId;\n this.events = opts.events;\n }\n\n account(usage: Usage, model?: string): void {\n this.input += usage.input;\n this.output += usage.output;\n this.cacheRead += usage.cacheRead ?? 0;\n this.cacheWrite += usage.cacheWrite ?? 0;\n // Snapshot per-request tokens for context pressure tracking.\n this.lastInput = usage.input;\n this.lastCacheRead = usage.cacheRead ?? 0;\n\n const price = model ? this.priceCache.get(model) : undefined;\n if (price) {\n this.applyPrice(usage, price);\n } else if (this.registry && this.providerId && model) {\n // Evict oldest entry when cache is full before async lookup.\n if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {\n const keys = [...this.priceCache.keys()];\n this.priceCache.delete(keys[0] ?? '');\n }\n // Async lookup — populate cache, but don't block this call.\n void this.registry\n .getModel(this.providerId, model)\n .then((m) => {\n if (m) {\n const p = priceFromModel(m);\n this.priceCache.set(model, p);\n this.applyPrice(usage, p);\n }\n })\n .catch(() => {\n // Emit so observability tooling can detect unknown models.\n this.events?.emit('token.cost_estimate_unavailable', { model: model ?? '<unknown>' });\n return undefined;\n });\n }\n }\n\n /** Synchronous variant for code paths that have already resolved the model. */\n accountWithModel(usage: Usage, resolved: ResolvedModel): void {\n this.input += usage.input;\n this.output += usage.output;\n this.cacheRead += usage.cacheRead ?? 0;\n this.cacheWrite += usage.cacheWrite ?? 0;\n // Snapshot per-request tokens for context pressure tracking.\n this.lastInput = usage.input;\n this.lastCacheRead = usage.cacheRead ?? 0;\n const price = priceFromModel(resolved);\n if (this.priceCache.size >= PRICE_CACHE_MAX_SIZE) {\n const keys = [...this.priceCache.keys()];\n this.priceCache.delete(keys[0] ?? '');\n }\n this.priceCache.set(resolved.modelId, price);\n this.applyPrice(usage, price);\n }\n\n total(): Usage {\n return {\n input: this.input,\n output: this.output,\n cacheRead: this.cacheRead,\n cacheWrite: this.cacheWrite,\n };\n }\n\n currentRequestTokens(): { input: number; cacheRead: number } {\n return { input: this.lastInput, cacheRead: this.lastCacheRead };\n }\n\n estimateCost(): { input: number; output: number; total: number; currency: 'USD' } {\n return {\n input: round4(this.costInput),\n output: round4(this.costOutput),\n total: round4(this.costInput + this.costOutput),\n currency: 'USD',\n };\n }\n\n cacheStats(): CacheStats {\n // Hit ratio: cacheRead / (cacheRead + input). `input` from the provider\n // is the count of fresh-token reads, so this answers \"what fraction of\n // the prompt did we get for the cache price?\"\n const denom = this.cacheRead + this.input;\n return {\n readTokens: this.cacheRead,\n writeTokens: this.cacheWrite,\n hitRatio: denom === 0 ? 0 : this.cacheRead / denom,\n };\n }\n\n /** Invalidate cached prices so the next account() call fetches fresh data. */\n invalidateCache(): void {\n this.priceCache.clear();\n }\n\n reset(): void {\n this.input = 0;\n this.output = 0;\n this.cacheRead = 0;\n this.cacheWrite = 0;\n this.costInput = 0;\n this.costOutput = 0;\n }\n\n private applyPrice(usage: Usage, price: PriceEntry): void {\n if (price.input) this.costInput += (usage.input / 1_000_000) * price.input;\n if (price.output) this.costOutput += (usage.output / 1_000_000) * price.output;\n if (usage.cacheRead && price.cacheRead) {\n this.costInput += (usage.cacheRead / 1_000_000) * price.cacheRead;\n }\n if (usage.cacheWrite && price.cacheWrite) {\n this.costInput += (usage.cacheWrite / 1_000_000) * price.cacheWrite;\n }\n }\n}\n\nfunction priceFromModel(m: ResolvedModel): PriceEntry {\n return {\n input: m.cost?.input,\n output: m.cost?.output,\n cacheRead: m.cost?.cache_read,\n cacheWrite: m.cost?.cache_write,\n };\n}\n\nfunction round4(n: number): number {\n return Math.round(n * 10_000) / 10_000;\n}\n","import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config — see notes below.\n *\n * Transport types:\n * stdio — spawns a local npm package binary via child_process\n * sse — HTTP SSE endpoint (client POSTs requests)\n * streamable-http — session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API — issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n permission: 'confirm',\n});\n\n/**\n * Context7 — codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search — web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY — free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) — Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt — AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n permission: 'confirm',\n});\n\n/**\n * Slack — messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack — messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base — EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS — EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps — directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps — directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n permission: 'confirm',\n});\n\n/** Sentinel — security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool — require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP — image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP — image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * MiniMax Token Plan MCP — web_search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP — image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/** Everything bundled — full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n});\n","import type { ContentBlock, ToolResultBlock, ToolUseBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\n\n\n\nfunction expectDefined<T>(value: T | null | undefined): T {\n if (value === null || value === undefined) {\n throw new Error('Expected value to be defined');\n }\n return value;\n}\n\nexport interface MessageRepairReport {\n changed: boolean;\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n}\n\nexport interface MessageRepairResult {\n messages: Message[];\n report: MessageRepairReport;\n}\n\n/**\n * Repair provider-level tool-call adjacency invariants.\n *\n * Anthropic requires every assistant `tool_use` block to have a matching\n * `tool_result` block in the immediately following user message. Manual\n * context surgery (summary/prune) can cut through the middle of such an\n * exchange. This function removes only the now-orphaned protocol blocks,\n * preserving surrounding text/images/thinking blocks where possible.\n */\nexport function repairToolUseAdjacency(messages: Message[]): MessageRepairResult {\n const removedToolUses: string[] = [];\n const removedToolResults: string[] = [];\n let removedMessages = 0;\n let changed = false;\n const out: Message[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const original = expectDefined(messages[i]);\n let msg = original;\n\n if (hasToolUse(msg)) {\n const nextIds = toolResultIds(messages[i + 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_use' && !nextIds.has(block.id)) {\n removedToolUses.push(block.id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (hasToolResult(msg)) {\n const allowed = toolUseIds(out[out.length - 1]);\n const filtered = mapContent(msg, (blocks) => {\n const next: ContentBlock[] = [];\n for (const block of blocks) {\n if (block.type === 'tool_result' && !allowed.has(block.tool_use_id)) {\n removedToolResults.push(block.tool_use_id);\n changed = true;\n continue;\n }\n next.push(block);\n }\n return next;\n });\n msg = filtered ?? msg;\n }\n\n if (isEmptyMessage(msg)) {\n removedMessages++;\n changed = true;\n continue;\n }\n out.push(msg);\n }\n\n return {\n messages: changed ? out : messages,\n report: { changed, removedToolUses, removedToolResults, removedMessages },\n };\n}\n\nfunction hasToolUse(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolUseBlock => b.type === 'tool_use');\n}\n\nfunction hasToolResult(msg: Message | undefined): boolean {\n return contentBlocks(msg).some((b): b is ToolResultBlock => b.type === 'tool_result');\n}\n\nfunction toolUseIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'assistant') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_use') ids.add(block.id);\n }\n return ids;\n}\n\nfunction toolResultIds(msg: Message | undefined): Set<string> {\n const ids = new Set<string>();\n if (!msg || msg.role !== 'user') return ids;\n for (const block of contentBlocks(msg)) {\n if (block.type === 'tool_result') ids.add(block.tool_use_id);\n }\n return ids;\n}\n\nfunction contentBlocks(msg: Message | undefined): ContentBlock[] {\n return msg && Array.isArray(msg.content) ? msg.content : [];\n}\n\nfunction mapContent(\n msg: Message,\n fn: (blocks: ContentBlock[]) => ContentBlock[],\n): Message | null {\n if (!Array.isArray(msg.content)) return msg;\n const next = fn(msg.content);\n if (next.length === msg.content.length && next.every((b, idx) => b === msg.content[idx])) {\n return msg;\n }\n return { ...msg, content: next };\n}\n\nfunction isEmptyMessage(msg: Message): boolean {\n if (typeof msg.content === 'string') return msg.content.trim().length === 0;\n return msg.content.length === 0;\n}\n","function expectDefined<T>(value: T | null | undefined): T {\n if (value === null || value === undefined) {\n throw new Error('Expected value to be defined');\n }\n return value;\n}\n\n/**\n * Shared token estimation with JSON.stringify caching.\n * Avoids repeated stringification of tool input objects.\n *\n * ## Calibration\n *\n * `estimateRequestTokens` uses a fixed 3.5 chars/token heuristic — a\n * conservative overestimate that prevents underestimation but reduces\n * accuracy. After each API call, call `recordActualUsage()` with the\n * real `usage.input` from the provider response. The module maintains a\n * rolling average of `actual / estimated` ratio (EWM, α=0.3) and\n * applies it to subsequent calls via `estimateRequestTokensCalibrated`.\n *\n * Calibration is per-module (shared across all callers), which is\n * sufficient: the chars/token ratio is a property of the tokenizer,\n * not the model. Uncalibrated calls (before any samples, or when\n * `recordActualUsage` is not called) fall back to the uncalibrated\n * estimate so nothing breaks.\n */\n\nconst RoughTokenEstimate = (text: string, charsPerToken = 3.5): number =>\n Math.max(1, Math.ceil(text.length / charsPerToken));\n\n/** Calibration state: actual/estimated ratio via exponential weighted moving average. */\nconst _cal = {\n ratio: 1.0, // current calibration multiplier (actual / estimated)\n count: 0, // number of samples recorded\n prevEst: 0, // estimated tokens from the most recent estimateRequestTokens call\n /** EWM α — higher = faster adaptation, more volatile */\n alpha: 0.3,\n};\n\nconst MIN_SAMPLES_FOR_CALIBRATION = 3;\n\n/**\n * Cache of computed estimates keyed by the stringified input — not the\n * input object itself. Previously the cache was keyed by the input object\n * via WeakMap, but JSON.stringify() produces a new object reference each\n * call so the cache never hit. Now we use a Map with string keys so that\n * repeated stringifications of the same structure share a single entry.\n */\nconst ESTIMATE_CACHE = new Map<string, number>();\n\nconst ESTIMATE_CACHE_MAX_SIZE = 10_000;\n\nfunction getCachedEstimate(key: string, compute: () => number): number {\n const existing = ESTIMATE_CACHE.get(key);\n if (existing !== undefined) return existing;\n if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {\n // Evict oldest quarter when at capacity — simple LRU-ish policy.\n const keys = [...ESTIMATE_CACHE.keys()];\n for (let i = 0; i < Math.floor(ESTIMATE_CACHE_MAX_SIZE / 4); i++) {\n ESTIMATE_CACHE.delete(expectDefined(keys[i]));\n }\n }\n const estimate = compute();\n ESTIMATE_CACHE.set(key, estimate);\n return estimate;\n}\n\n/**\n * Estimate tokens for a tool_use block input.\n * Caches the stringified result keyed by the stable string representation\n * to avoid repeated JSON.stringify calls during context window checks.\n */\nexport function estimateToolInputTokens(input: unknown): number {\n if (typeof input === 'string') return RoughTokenEstimate(input);\n if (input === null || typeof input !== 'object') {\n return RoughTokenEstimate(String(input));\n }\n const key = JSON.stringify(input);\n return getCachedEstimate(key, () => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a tool_result content.\n */\nexport function estimateToolResultTokens(content: string | unknown): number {\n if (typeof content === 'string') return RoughTokenEstimate(content);\n const key = JSON.stringify(content);\n return getCachedEstimate(key, () => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a text block.\n */\nexport function estimateTextTokens(text: string): number {\n return RoughTokenEstimate(text);\n}\n\n/**\n * Rough estimate of tokens in a tool definition (name + description + schema).\n * Accounts for the JSON-serialized inputSchema which is sent to the API\n * but NOT included in roughEstimate(content).\n */\nexport function estimateToolDefTokens(tool: { name: string; description?: string | undefined; inputSchema: unknown }): number {\n return RoughTokenEstimate(tool.name) +\n RoughTokenEstimate(tool.description ?? '') +\n RoughTokenEstimate(JSON.stringify(tool.inputSchema));\n}\n\n/**\n * Estimate the total API request token count: system prompt + tool definitions\n * + conversation messages. Use this for context-window bar calculations\n * instead of roughEstimate (which only counts messages).\n *\n * The overhead ratio (overhead / messages) varies by conversation length:\n * - Short conversations (< 10 messages): ~30-50% overhead (large system+tools)\n * - Medium (10-50 messages): ~15-30%\n * - Long (> 50 messages): ~5-15%\n *\n * Returns { messages, systemPrompt, tools, total } for debugging display.\n */\nexport interface RequestTokenBreakdown {\n messages: number;\n systemPrompt: number;\n tools: number;\n total: number;\n}\n\nexport function estimateRequestTokens(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n): RequestTokenBreakdown {\n // Messages: apply the same logic as roughEstimate\n let messagesTokens = 0;\n if (typeof messages === 'string') {\n messagesTokens = RoughTokenEstimate(messages);\n } else if (Array.isArray(messages)) {\n for (const m of messages) {\n if (typeof m === 'object' && m !== null && 'content' in m) {\n const content = (m as { content: unknown }).content;\n if (typeof content === 'string') {\n messagesTokens += RoughTokenEstimate(content);\n } else if (Array.isArray(content)) {\n for (const b of content) {\n if (typeof b === 'object' && b !== null) {\n if ((b as { type?: string | undefined }).type === 'text') {\n messagesTokens += RoughTokenEstimate((b as { text: string }).text);\n } else {\n messagesTokens += RoughTokenEstimate(JSON.stringify(b));\n }\n }\n }\n }\n }\n }\n }\n\n // System prompt\n let systemTokens = 0;\n if (typeof systemPrompt === 'string') {\n systemTokens = RoughTokenEstimate(systemPrompt);\n } else if (Array.isArray(systemPrompt)) {\n for (const b of systemPrompt) {\n if (typeof b === 'object' && b !== null && (b as { type?: string | undefined }).type === 'text') {\n systemTokens += RoughTokenEstimate((b as { text: string }).text);\n }\n }\n }\n\n // Tool definitions\n let toolsTokens = 0;\n for (const t of tools) {\n toolsTokens += estimateToolDefTokens(t);\n }\n\n const total = messagesTokens + systemTokens + toolsTokens;\n\n // Record the raw estimate for calibration: the next recordActualUsage()\n // call will pair this against the actual API usage so the rolling ratio\n // stays in sync with the real chars/token ratio of the content.\n _cal.prevEst = total;\n\n return {\n messages: messagesTokens,\n systemPrompt: systemTokens,\n tools: toolsTokens,\n total,\n };\n}\n\n/**\n * Record the actual API input token count after a provider call so\n * `estimateRequestTokensCalibrated` can self-correct on subsequent calls.\n *\n * Prefer passing `estimatedInputTokens` explicitly (the calibrated pre-flight\n * estimate from the middleware) — this avoids race conditions when other code\n * also calls `estimateRequestTokens` between the pre-flight and this call\n * (e.g. audit logging in agent.ts).\n *\n * When `estimatedInputTokens` is omitted, falls back to `_cal.prevEst`\n * for backward compatibility with callers that don't have the pre-flight value.\n */\nexport function recordActualUsage(actualInputTokens: number, estimatedInputTokens?: number): void {\n if (actualInputTokens <= 0) return;\n const est = estimatedInputTokens ?? _cal.prevEst;\n if (est <= 0) return;\n\n const sampleRatio = actualInputTokens / est;\n if (_cal.count === 0) {\n _cal.ratio = sampleRatio;\n } else {\n // EWM: new = α * sample + (1-α) * old → α=0.3 = fast initial converge\n _cal.ratio = _cal.alpha * sampleRatio + (1 - _cal.alpha) * _cal.ratio;\n }\n // Sanity bound: keep the rolling ratio within [0.5, 1.5] so a sequence\n // of bad samples can't blow up the calibration for everyone.\n _cal.ratio = Math.min(1.5, Math.max(0.5, _cal.ratio));\n _cal.count++;\n}\n\n/**\n * Returns the current calibration state. Exposed for debugging and\n * tests — not needed by normal callers.\n */\nexport function getCalibrationState(): { ratio: number; count: number; calibrated: boolean } {\n return {\n ratio: _cal.ratio,\n count: _cal.count,\n calibrated: _cal.count >= MIN_SAMPLES_FOR_CALIBRATION,\n };\n}\n\n/**\n * Like `estimateRequestTokens` but applies the rolling calibration factor\n * so context pressure readings converge on reality within a few iterations.\n *\n * Before any `recordActualUsage` samples are collected, returns the same\n * result as `estimateRequestTokens` (ratio = 1.0, no distortion).\n * After `MIN_SAMPLES_FOR_CALIBRATION` samples, applies the calibrated\n * multiplier capped to the range [0.5, 1.5] as a sanity bound.\n */\nexport function estimateRequestTokensCalibrated(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n): RequestTokenBreakdown {\n const result = estimateRequestTokens(messages, systemPrompt, tools);\n\n if (_cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {\n const safeRatio = Math.min(1.5, Math.max(0.5, _cal.ratio));\n return {\n messages: Math.round(result.messages * safeRatio),\n systemPrompt: Math.round(result.systemPrompt * safeRatio),\n tools: Math.round(result.tools * safeRatio),\n total: Math.round(result.total * safeRatio),\n };\n }\n\n return result;\n}\n\n/**\n * Resets calibration state. Primarily for tests that run in the same\n * process and need a clean slate between suites.\n */\nexport function resetCalibration(): void {\n _cal.ratio = 1.0;\n _cal.count = 0;\n _cal.prevEst = 0;\n}\n","import type { Context } from '../core/context.js';\nimport type { Compactor } from '../types/compactor.js';\nimport type { Message } from '../types/messages.js';\nimport type { Tool } from '../types/tool.js';\nimport { repairToolUseAdjacency } from '../utils/message-invariants.js';\nimport { estimateRequestTokens } from '../utils/token-estimate.js';\n\n/**\n * Context introspection and management tool.\n * Allows the model to:\n * - \"check\" → see token budget and message counts\n * - \"summary\" → summarize and replace a range of messages\n * - \"prune\" → remove specific message indices\n * - \"add_note\" → inject a summary note at a specific point\n * - \"compact\" → run compaction via the injected compactor\n */\nexport const CONTEXT_MANAGER_TOOL_NAME = 'context_manager';\n\nexport type ContextManagerAction =\n | 'check'\n | 'summary'\n | 'prune'\n | 'add_note'\n | 'compact'\n | 'repair';\n\nexport interface ContextManagerInput {\n action: ContextManagerAction;\n /** 0-based message indices for prune/summary (inclusive). */\n from?: number | undefined;\n to?: number | undefined;\n /** Text for add_note / summary actions. For summary, this is the LLM-provided summary text. */\n text?: string | undefined;\n /** Inject after which index (for add_note). Defaults to prepend (0). */\n afterIndex?: number | undefined;\n /**\n * System prompt blocks for accurate total token estimation in check action.\n * When provided, check returns the full API request estimate\n * (messages + system + tools) instead of just message tokens.\n */\n systemPrompt?: unknown | undefined;\n /**\n * Registered tools for accurate total token estimation in check action.\n * Each tool's name + description + inputSchema is counted.\n */\n tools?: { name: string; description?: string | undefined; inputSchema: unknown }[];\n}\n\nexport interface ContextManagerResult {\n action: ContextManagerAction;\n beforeTokens: number;\n afterTokens?: number | undefined;\n removedCount?: number | undefined;\n messageCount: number;\n summary?: string | undefined;\n notes?: string | undefined;\n repaired?: {\n removedToolUses: string[];\n removedToolResults: string[];\n removedMessages: number;\n } | undefined;\n}\n\n/**\n * Options for creating a context manager tool.\n * `compactor` is required for the \"compact\" action; without it the action returns an error.\n */\nexport interface ContextManagerToolOptions {\n compactor?: Compactor | undefined;\n /**\n * Optional sub-LLM summarizer. When provided, the \"summary\" action calls this\n * to produce real summaries of message ranges instead of placeholder text.\n * (signature matches Provider.complete — return the summary text in result.content[0].text)\n */\n summarizer?: (((messages: Message[]) => Promise<string>)) | undefined;\n /**\n * Minimum full-request token count before the compact action is allowed to run.\n * Prevents unnecessary compaction calls when context is small.\n * Default: 0 (always allow). Set to ~5000 for meaningful compaction targets.\n */\n minCompactThreshold?: number | undefined;\n /**\n * Minimum token growth required before retrying after a NOOP compaction.\n * A NOOP is when compaction saved nothing (preserveK protects everything,\n * no oversized tool_results). Default: 2000.\n */\n noopRetryDeltaTokens?: number | undefined;\n /**\n * Provider's max context window in tokens. Used to compute a relative\n * threshold when `minCompactThreshold` is not set. Default: 128_000.\n */\n maxContext?: number | undefined;\n /**\n * Fraction of maxContext that triggers compaction. Only used when\n * `minCompactThreshold` is not set. Default: 0.5 (50% of maxContext).\n */\n compactThresholdFraction?: number | undefined;\n}\n\nfunction roughEstimate(messages: Message[]): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m.content === 'string') {\n total += Math.ceil(m.content.length / 4);\n } else if (Array.isArray(m.content)) {\n for (const b of m.content) {\n if (b.type === 'text') total += Math.ceil(b.text.length / 4);\n else if (b.type === 'tool_use' || b.type === 'tool_result') {\n total += Math.ceil(JSON.stringify(b).length / 4);\n }\n }\n }\n }\n return total;\n}\n\nexport function createContextManagerTool(\n opts: ContextManagerToolOptions = {},\n): Tool<ContextManagerInput, ContextManagerResult> {\n const minCompactThreshold = opts.minCompactThreshold ?? 0;\n const noopRetryDeltaTokens = opts.noopRetryDeltaTokens ?? 2_000;\n const maxContext = opts.maxContext ?? 128_000;\n const compactThresholdFraction = opts.compactThresholdFraction ?? 0.5;\n const effectiveThreshold = minCompactThreshold > 0\n ? minCompactThreshold\n : Math.floor(maxContext * compactThresholdFraction);\n\n // Tracks the most recent NOOP attempt so we can skip retry until context grows.\n let lastNoopTokens = 0;\n\n return {\n name: CONTEXT_MANAGER_TOOL_NAME,\n description:\n 'Inspect or reorganize the conversation context window. ' +\n 'Use \"check\" to see token budget. ' +\n 'Use \"summary\" to collapse a message range into a concise note (provide \"text\" for custom summary). ' +\n 'Use \"prune\" to remove specific messages by index. ' +\n 'Use \"add_note\" to inject a summary note. ' +\n 'Use \"compact\" to run aggressive compaction. ' +\n 'Use \"repair\" to remove orphan tool_use/tool_result blocks after manual context surgery.',\n inputSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['check', 'summary', 'prune', 'add_note', 'compact', 'repair'],\n description: 'The context operation to perform.',\n },\n from: {\n type: 'number',\n description: 'Start index (inclusive) for summary/prune operations.',\n },\n to: {\n type: 'number',\n description: 'End index (inclusive) for summary/prune operations.',\n },\n text: {\n type: 'string',\n description:\n 'Summary or note text. For \"summary\": the model-provided summary of the removed range. ' +\n 'For \"add_note\": the note to inject.',\n },\n afterIndex: {\n type: 'number',\n description: 'Insert after this index (for add_note). Defaults to prepend (0).',\n },\n },\n required: ['action'],\n },\n permission: 'auto',\n mutating: true,\n\n async execute(input: ContextManagerInput, ctx: Context): Promise<ContextManagerResult> {\n const messages = ctx.messages;\n const beforeTokens = roughEstimate(messages);\n\n // When ctx.state is available, route mutations through the observer\n // layer so subscribers stay in sync. Fall back to direct splice for\n // tests and environments that haven't wired ConversationState.\n const applyMessages = (next: Message[]) => {\n const repaired = repairToolUseAdjacency(next);\n const finalMessages = repaired.messages;\n if (ctx.state) {\n ctx.state.replaceMessages(finalMessages);\n } else {\n messages.length = 0;\n messages.splice(0, 0, ...finalMessages);\n }\n return repaired.report;\n };\n\n switch (input.action) {\n case 'check': {\n // Prefer the full API request estimate when systemPrompt + tools are available.\n // This is the accurate number for context-window bar display.\n // Falls back to roughEstimate (messages-only) for backward compat and test environments.\n const estimate = (input.systemPrompt != null && Array.isArray(input.tools))\n ? estimateRequestTokens(messages, input.systemPrompt, input.tools)\n : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };\n return {\n action: 'check',\n beforeTokens: estimate.total,\n messageCount: messages.length,\n notes: JSON.stringify({\n messages: messages.length,\n tokens: estimate.total,\n msgTokens: estimate.messages,\n sysTokens: estimate.systemPrompt,\n toolTokens: estimate.tools,\n readFiles: ctx.readFiles.size,\n todos: ctx.todos.length,\n inProgress: ctx.todos.filter((t) => t.status === 'in_progress').length,\n }),\n };\n }\n\n case 'repair': {\n const repair = applyMessages([...messages]);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'repair',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n notes: repair.changed\n ? 'Context tool-call adjacency repaired.'\n : 'Context tool-call adjacency already valid.',\n };\n }\n\n case 'compact': {\n if (!opts.compactor) {\n return {\n action: 'compact',\n beforeTokens,\n messageCount: messages.length,\n notes: 'No compactor registered. Use /compact aggressive via slash command instead.',\n };\n }\n // Compute full request tokens for threshold check.\n const fullEstimate = (input.systemPrompt != null && Array.isArray(input.tools))\n ? estimateRequestTokens(messages, input.systemPrompt, input.tools)\n : { total: beforeTokens, messages: beforeTokens, systemPrompt: 0, tools: 0 };\n const currentTokens = fullEstimate.total;\n\n // NOOP retry prevention: skip if the previous compaction saved nothing\n // and context hasn't grown enough to make another attempt worthwhile.\n if (lastNoopTokens > 0) {\n const delta = currentTokens - lastNoopTokens;\n if (delta < noopRetryDeltaTokens) {\n return {\n action: 'compact',\n beforeTokens,\n afterTokens: beforeTokens,\n messageCount: messages.length,\n notes: `Compact is a NOOP retry: context grew only ${delta} tokens since the last no-op attempt (threshold: ${noopRetryDeltaTokens}). Skip until more content accumulates.`,\n };\n }\n }\n\n // Minimum threshold check: skip if context is too small to benefit.\n if (currentTokens < effectiveThreshold) {\n return {\n action: 'compact',\n beforeTokens,\n afterTokens: beforeTokens,\n messageCount: messages.length,\n notes: `Context tokens (${currentTokens}) below compact threshold (${effectiveThreshold}). Skipping.`,\n };\n }\n\n const report = await opts.compactor.compact(ctx);\n ctx.clearFileTracking();\n const repair = applyMessages([...ctx.messages]);\n const afterTokens = repair.changed ? roughEstimate(ctx.messages) : report.after;\n const repaired = report.repaired ?? (repair.changed ? repair : undefined);\n\n // Record NOOP state: did compaction actually reduce tokens?\n const reduced = report.fullRequestTokensBefore > report.fullRequestTokensAfter;\n const repairedSomething = !!report.repaired;\n if (reduced || repairedSomething) {\n lastNoopTokens = 0;\n } else {\n lastNoopTokens = currentTokens;\n }\n\n return {\n action: 'compact',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n repaired: repaired\n ? {\n removedToolUses: repaired.removedToolUses,\n removedToolResults: repaired.removedToolResults,\n removedMessages: repaired.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'prune': {\n const from = input.from ?? 0;\n const to = input.to ?? messages.length - 1;\n if (from < 0 || to >= messages.length || from > to) {\n return {\n action: 'prune',\n beforeTokens,\n messageCount: messages.length,\n notes: `Invalid range [${from}, ${to}] for ${messages.length} messages.`,\n };\n }\n const copy = [...messages];\n const removed = copy.splice(from, to - from + 1);\n ctx.clearFileTracking();\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'prune',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n removedCount: removed.length,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'add_note': {\n const noteText = input.text ?? '(no summary)';\n const afterIdx = Math.min(input.afterIndex ?? 0, messages.length);\n const noteMsg: Message = {\n role: 'system',\n content: `[note: ${noteText}]`,\n };\n const copy = [...messages];\n copy.splice(afterIdx, 0, noteMsg);\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'add_note',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n summary: noteText,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n case 'summary': {\n const from = input.from ?? 0;\n const to = input.to ?? messages.length - 1;\n if (from < 0 || to >= messages.length || from > to) {\n return {\n action: 'summary',\n beforeTokens,\n messageCount: messages.length,\n notes: `Invalid range [${from}, ${to}] for ${messages.length} messages.`,\n };\n }\n const summaryText =\n input.text ?? '[summary placeholder — provide \"text\" to record the summary]';\n const summaryMsg: Message = {\n role: 'system',\n content: `[summary of messages ${from}–${to}]: ${summaryText}`,\n };\n const copy = [...messages];\n copy.splice(from, to - from + 1, summaryMsg);\n ctx.clearFileTracking();\n const repair = applyMessages(copy);\n const afterTokens = roughEstimate(ctx.messages);\n return {\n action: 'summary',\n beforeTokens,\n afterTokens,\n messageCount: ctx.messages.length,\n summary: summaryText,\n repaired: repair.changed\n ? {\n removedToolUses: repair.removedToolUses,\n removedToolResults: repair.removedToolResults,\n removedMessages: repair.removedMessages,\n }\n : undefined,\n };\n }\n\n default:\n return {\n action: input.action,\n beforeTokens,\n messageCount: messages.length,\n notes: `Unknown action: ${input.action}`,\n };\n }\n },\n };\n}\n\n/** Pre-built instance with no compactor — compact action will return an error. */\nexport const contextManagerTool: Tool<ContextManagerInput, ContextManagerResult> =\n createContextManagerTool();\n"]}
|
package/dist/kernel/index.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
export { B as BindOptions, C as Container, D as Decorator, F as Factory, M as Middleware, b as MiddlewareHandler, N as NextFn, P as Pipeline, d as PipelineOptions, T as Token } from '../system-prompt-
|
|
2
|
-
export { E as EventBus, i as EventLogger, j as EventMap, k as EventName, L as Listener, S as ScopedEventBus } from '../events-
|
|
3
|
-
export { R as RunController, b as RunControllerOptions, T as TOKENS } from '../index-
|
|
4
|
-
import '../config-
|
|
5
|
-
import '../models-registry-
|
|
6
|
-
import '../context-
|
|
7
|
-
import '../compactor-
|
|
8
|
-
import '../retry-policy-
|
|
1
|
+
export { B as BindOptions, C as Container, D as Decorator, F as Factory, M as Middleware, b as MiddlewareHandler, N as NextFn, P as Pipeline, d as PipelineOptions, T as Token } from '../system-prompt-C0rLCeyn.js';
|
|
2
|
+
export { E as EventBus, i as EventLogger, j as EventMap, k as EventName, L as Listener, S as ScopedEventBus } from '../events-DnRqXaZ3.js';
|
|
3
|
+
export { R as RunController, b as RunControllerOptions, T as TOKENS } from '../index-BNOLadHw.js';
|
|
4
|
+
import '../config-_DZ7dN-T.js';
|
|
5
|
+
import '../models-registry-Be3osGt5.js';
|
|
6
|
+
import '../context-ToHAp4-U.js';
|
|
7
|
+
import '../compactor-CJq7LQev.js';
|
|
8
|
+
import '../retry-policy-DSu6O6rD.js';
|
|
9
9
|
import '../input-reader-E-ffP2ee.js';
|
|
10
|
-
import '../logger-
|
|
10
|
+
import '../logger-B72yyPc6.js';
|
|
11
11
|
import '../memory-CEXuo7sz.js';
|
|
12
|
-
import '../mode-
|
|
12
|
+
import '../mode-CHo2XtHs.js';
|
|
13
13
|
import '../path-resolver-CPRj4bFY.js';
|
|
14
|
-
import '../permission-
|
|
15
|
-
import '../provider-runner-
|
|
16
|
-
import '../observability-
|
|
14
|
+
import '../permission-14CChMmO.js';
|
|
15
|
+
import '../provider-runner-COAJM8tC.js';
|
|
16
|
+
import '../observability-CoSNZdhX.js';
|
|
17
17
|
import '../secret-scrubber-3MHDDAtm.js';
|
|
18
|
-
import '../skill-
|
|
18
|
+
import '../skill-BJeF2DwY.js';
|
package/dist/kernel/index.js
CHANGED
|
@@ -147,6 +147,13 @@ var Container = class {
|
|
|
147
147
|
has(token) {
|
|
148
148
|
return this.entries.has(token);
|
|
149
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Resolve a token if it is bound, otherwise return undefined.
|
|
152
|
+
* Unlike resolve(), this does not throw if the token is unbound.
|
|
153
|
+
*/
|
|
154
|
+
safeResolve(token) {
|
|
155
|
+
return this.has(token) ? this.resolve(token) : void 0;
|
|
156
|
+
}
|
|
150
157
|
ownerOf(token) {
|
|
151
158
|
return this.entries.get(token)?.owner;
|
|
152
159
|
}
|