@wrongstack/core 0.1.1 → 0.1.3

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.
@@ -1,6 +1,7 @@
1
- import { ay as Token, j as Logger, a1 as TokenCounter, V as SessionStore, m as MemoryStore, v as PermissionPolicy, c as Compactor, P as PathResolver, e as ConfigLoader, R as Renderer, h as InputReader, E as ErrorHandler, O as RetryPolicy, Y as SkillLoader, S as SecretScrubber, s as ModelsRegistry } from '../secret-scrubber-Dax_Ou_o.js';
2
- export { al as BindOptions, ah as Container, an as Decorator, ai as EventBus, ao as EventLogger, ap as EventMap, aj as EventName, aq as Factory, ak as Listener, ar as Middleware, as as MiddlewareHandler, at as NextFn, au as Pipeline, av as PipelineOptions } from '../secret-scrubber-Dax_Ou_o.js';
3
- import { S as SystemPromptBuilder } from '../system-prompt-BG3nks8P.js';
1
+ import { Z as Token, g as Logger, j as MemoryStore, p as PermissionPolicy, a as Compactor, P as PathResolver, c as ConfigLoader, d as ConfigStore, R as Renderer, I as InputReader, E as ErrorHandler, w as RetryPolicy, x as SkillLoader, S as SecretScrubber, n as ModelsRegistry } from '../secret-scrubber-qU3AwEiI.js';
2
+ export { H as BindOptions, A as Container, J as Decorator, B as EventBus, K as EventLogger, N as EventMap, D as EventName, O as Factory, G as Listener, Q as Middleware, U as MiddlewareHandler, V as NextFn, X as Pipeline, Y as PipelineOptions } from '../secret-scrubber-qU3AwEiI.js';
3
+ import { u as TokenCounter, p as SessionStore } from '../provider-DovtyuM8.js';
4
+ import { S as SystemPromptBuilder } from '../system-prompt--mzZnenv.js';
4
5
 
5
6
  declare const TOKENS: {
6
7
  readonly Logger: Token<Logger>;
@@ -11,6 +12,7 @@ declare const TOKENS: {
11
12
  readonly Compactor: Token<Compactor>;
12
13
  readonly PathResolver: Token<PathResolver>;
13
14
  readonly ConfigLoader: Token<ConfigLoader>;
15
+ readonly ConfigStore: Token<ConfigStore>;
14
16
  readonly Renderer: Token<Renderer>;
15
17
  readonly InputReader: Token<InputReader>;
16
18
  readonly ErrorHandler: Token<ErrorHandler>;
@@ -1,9 +1,44 @@
1
+ // src/types/errors.ts
2
+ var WrongStackError = class extends Error {
3
+ code;
4
+ subsystem;
5
+ severity;
6
+ recoverable;
7
+ context;
8
+ constructor(opts) {
9
+ super(opts.message, { cause: opts.cause });
10
+ this.name = "WrongStackError";
11
+ this.code = opts.code;
12
+ this.subsystem = opts.subsystem;
13
+ this.severity = opts.severity ?? "error";
14
+ this.recoverable = opts.recoverable ?? false;
15
+ this.context = opts.context;
16
+ }
17
+ /**
18
+ * Render a one-line user-facing description.
19
+ * Subclasses should override for domain-specific formatting.
20
+ */
21
+ describe() {
22
+ const ctx = this.context ? ` ${formatContext(this.context)}` : "";
23
+ return `${this.code}: ${this.message}${ctx}`;
24
+ }
25
+ };
26
+ function formatContext(ctx) {
27
+ const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
28
+ return parts.length > 0 ? `[${parts.join(" ")}]` : "";
29
+ }
30
+
1
31
  // src/kernel/container.ts
2
32
  var Container = class {
3
33
  entries = /* @__PURE__ */ new Map();
4
34
  bind(token, factory, opts = {}) {
5
35
  if (this.entries.has(token)) {
6
- throw new Error(`Container: token "${token.description ?? "unknown"}" already bound`);
36
+ throw new WrongStackError({
37
+ message: `Container: token "${token.description ?? "unknown"}" already bound`,
38
+ code: "CONTAINER_TOKEN_ALREADY_BOUND",
39
+ subsystem: "container",
40
+ context: { token: token.description }
41
+ });
7
42
  }
8
43
  this.entries.set(token, {
9
44
  factory,
@@ -15,9 +50,12 @@ var Container = class {
15
50
  override(token, factory, opts = {}) {
16
51
  const existing = this.entries.get(token);
17
52
  if (!existing) {
18
- throw new Error(
19
- `Container: cannot override "${token.description ?? "unknown"}" \u2014 not bound`
20
- );
53
+ throw new WrongStackError({
54
+ message: `Container: cannot override "${token.description ?? "unknown"}" \u2014 not bound`,
55
+ code: "CONTAINER_TOKEN_NOT_BOUND",
56
+ subsystem: "container",
57
+ context: { token: token.description }
58
+ });
21
59
  }
22
60
  this.entries.set(token, {
23
61
  factory,
@@ -29,9 +67,12 @@ var Container = class {
29
67
  decorate(token, decorator, owner = "core") {
30
68
  const existing = this.entries.get(token);
31
69
  if (!existing) {
32
- throw new Error(
33
- `Container: cannot decorate "${token.description ?? "unknown"}" \u2014 not bound`
34
- );
70
+ throw new WrongStackError({
71
+ message: `Container: cannot decorate "${token.description ?? "unknown"}" \u2014 not bound`,
72
+ code: "CONTAINER_TOKEN_NOT_BOUND",
73
+ subsystem: "container",
74
+ context: { token: token.description }
75
+ });
35
76
  }
36
77
  existing.decorators.push(decorator);
37
78
  existing.cache = void 0;
@@ -40,9 +81,12 @@ var Container = class {
40
81
  resolve(token) {
41
82
  const entry = this.entries.get(token);
42
83
  if (!entry) {
43
- throw new Error(
44
- `Container: token "${token.description ?? "unknown"}" not bound`
45
- );
84
+ throw new WrongStackError({
85
+ message: `Container: token "${token.description ?? "unknown"}" not bound`,
86
+ code: "CONTAINER_TOKEN_NOT_BOUND",
87
+ subsystem: "container",
88
+ context: { token: token.description }
89
+ });
46
90
  }
47
91
  if (entry.singleton && entry.cache !== void 0) {
48
92
  return entry.cache;
@@ -106,6 +150,20 @@ var Container = class {
106
150
  // src/kernel/pipeline.ts
107
151
  var Pipeline = class {
108
152
  chain = [];
153
+ errorHandler;
154
+ /**
155
+ * Install an error boundary. When a middleware throws or rejects, the
156
+ * handler is called and decides whether to swallow (continue with the
157
+ * pre-handler value) or rethrow. Without a handler, errors propagate.
158
+ *
159
+ * Wire one per pipeline at boot — the host CLI typically installs a
160
+ * single boundary that logs to the operational log and emits a
161
+ * `pipeline.error` event for /diag.
162
+ */
163
+ setErrorHandler(handler) {
164
+ this.errorHandler = handler;
165
+ return this;
166
+ }
109
167
  use(mw) {
110
168
  this.ensureUnique(mw.name);
111
169
  this.chain.push(mw);
@@ -190,6 +248,7 @@ var Pipeline = class {
190
248
  async run(input) {
191
249
  let index = -1;
192
250
  const chain = this.chain;
251
+ const errorHandler = this.errorHandler;
193
252
  const dispatch = async (i, value) => {
194
253
  if (i <= index) {
195
254
  throw new Error(`Pipeline: next() called multiple times in "${chain[index]?.name}"`);
@@ -197,7 +256,14 @@ var Pipeline = class {
197
256
  index = i;
198
257
  const mw = chain[i];
199
258
  if (!mw) return value;
200
- return mw.handler(value, (v) => dispatch(i + 1, v));
259
+ try {
260
+ return await mw.handler(value, (v) => dispatch(i + 1, v));
261
+ } catch (err) {
262
+ if (!errorHandler) throw err;
263
+ const policy = await errorHandler({ middleware: mw.name, owner: mw.owner, err });
264
+ if (policy === "rethrow") throw err;
265
+ return value;
266
+ }
201
267
  };
202
268
  return dispatch(0, input);
203
269
  }
@@ -258,6 +324,17 @@ var EventBus = class {
258
324
  clear() {
259
325
  this.listeners.clear();
260
326
  }
327
+ /**
328
+ * V2-D: introspection helper. Pass an `event` to count handlers for a
329
+ * single key, or omit to get the total across every event. Used by the
330
+ * leak-detection smoke test to flag handler accumulation across runs.
331
+ */
332
+ listenerCount(event) {
333
+ if (event !== void 0) return this.listeners.get(event)?.size ?? 0;
334
+ let total = 0;
335
+ for (const set of this.listeners.values()) total += set.size;
336
+ return total;
337
+ }
261
338
  };
262
339
 
263
340
  // src/kernel/tokens.ts
@@ -271,6 +348,7 @@ var TOKENS = {
271
348
  Compactor: t("Compactor"),
272
349
  PathResolver: t("PathResolver"),
273
350
  ConfigLoader: t("ConfigLoader"),
351
+ ConfigStore: t("ConfigStore"),
274
352
  Renderer: t("Renderer"),
275
353
  InputReader: t("InputReader"),
276
354
  ErrorHandler: t("ErrorHandler"),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/kernel/container.ts","../../src/kernel/pipeline.ts","../../src/kernel/events.ts","../../src/kernel/tokens.ts","../../src/kernel/run-controller.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Container — dependency injection with explicit bind / override / decorate.\n *\n * Invariants:\n * bind() — throws if token already bound\n * override() — throws if nothing to replace\n * decorate() — stacks; cached value cleared on register\n */\n\nexport type Token<T> = symbol & { readonly __type?: T };\nexport type Factory<T> = (c: Container) => T;\nexport type Decorator<T> = (inner: T, c: Container) => T;\n\ninterface Entry<T = unknown> {\n factory: Factory<T>;\n singleton: boolean;\n decorators: Decorator<T>[];\n cache?: T;\n owner: string;\n}\n\nexport interface BindOptions {\n singleton?: boolean;\n owner?: string;\n}\n\nexport class Container {\n private readonly entries = new Map<symbol, Entry>();\n\n bind<T>(token: Token<T>, factory: Factory<T>, opts: BindOptions = {}): void {\n if (this.entries.has(token)) {\n throw new Error(`Container: token \"${token.description ?? 'unknown'}\" already bound`);\n }\n this.entries.set(token, {\n factory: factory as Factory<unknown>,\n singleton: opts.singleton ?? true,\n decorators: [],\n owner: opts.owner ?? 'core',\n });\n }\n\n override<T>(token: Token<T>, factory: Factory<T>, opts: BindOptions = {}): void {\n const existing = this.entries.get(token);\n if (!existing) {\n throw new Error(\n `Container: cannot override \"${token.description ?? 'unknown'}\" — not bound`,\n );\n }\n this.entries.set(token, {\n factory: factory as Factory<unknown>,\n singleton: opts.singleton ?? existing.singleton,\n decorators: existing.decorators,\n owner: opts.owner ?? existing.owner,\n });\n }\n\n decorate<T>(token: Token<T>, decorator: Decorator<T>, owner = 'core'): void {\n const existing = this.entries.get(token);\n if (!existing) {\n throw new Error(\n `Container: cannot decorate \"${token.description ?? 'unknown'}\" — not bound`,\n );\n }\n existing.decorators.push(decorator as Decorator<unknown>);\n existing.cache = undefined;\n existing.owner = `${existing.owner}+${owner}`;\n }\n\n resolve<T>(token: Token<T>): T {\n const entry = this.entries.get(token);\n if (!entry) {\n throw new Error(\n `Container: token \"${token.description ?? 'unknown'}\" not bound`,\n );\n }\n if (entry.singleton && entry.cache !== undefined) {\n return entry.cache as T;\n }\n let value: unknown = entry.factory(this);\n for (const d of entry.decorators) {\n value = d(value, this);\n }\n if (entry.singleton) {\n entry.cache = value;\n }\n return value as T;\n }\n\n has<T>(token: Token<T>): boolean {\n return this.entries.has(token);\n }\n\n ownerOf<T>(token: Token<T>): string | undefined {\n return this.entries.get(token)?.owner;\n }\n\n /**\n * Remove a token's binding (along with any decorators stacked on it).\n * Returns true if the token existed. Use this to withdraw temporary\n * bindings installed by a short-lived run or plugin — without it, the\n * entry persists in the map forever.\n */\n unbind<T>(token: Token<T>): boolean {\n return this.entries.delete(token);\n }\n\n /**\n * Drop every binding. Intended for tests and short-lived CLI invocations\n * that rebuild the container from scratch. Production code should prefer\n * `unbind` on the specific tokens it owns.\n */\n clear(): void {\n this.entries.clear();\n }\n\n list(): Array<{ token: symbol; owner: string }> {\n return Array.from(this.entries.entries()).map(([token, entry]) => ({\n token,\n owner: entry.owner,\n }));\n }\n\n /**\n * Inspect a binding's full shape, including decorator count and whether\n * a singleton value is cached. Returns null if the token is unbound.\n * Decorator and factory function references are not exposed — only counts\n * and metadata, to keep internal state hidden.\n */\n inspect<T>(token: Token<T>): {\n owner: string;\n singleton: boolean;\n decoratorCount: number;\n cached: boolean;\n } | null {\n const entry = this.entries.get(token);\n if (!entry) return null;\n return {\n owner: entry.owner,\n singleton: entry.singleton,\n decoratorCount: entry.decorators.length,\n cached: entry.cache !== undefined,\n };\n }\n}\n","/**\n * Pipeline — Koa-style middleware chain with named middleware\n * and position-aware insertion. Generic over input type T.\n */\n\nexport type NextFn<T> = (value: T) => Promise<T>;\nexport type MiddlewareHandler<T> = (value: T, next: NextFn<T>) => Promise<T>;\n\nexport interface Middleware<T> {\n name: string;\n handler: MiddlewareHandler<T>;\n owner?: string;\n}\n\nexport interface PipelineOptions {\n /** When true and the target middleware is not found, operations silently no-op instead of throwing. */\n optional?: boolean;\n}\n\n/**\n * Read-only view of a pipeline. Returned to consumers (plugins, hooks)\n * so they can inspect but not mutate the chain.\n */\nexport interface ReadonlyPipeline<T> {\n readonly size: number;\n list(): readonly string[];\n run(input: T): Promise<T>;\n}\n\nexport class Pipeline<T> {\n private readonly chain: Middleware<T>[] = [];\n\n use(mw: Middleware<T> | Middleware<unknown>): this {\n this.ensureUnique(mw.name);\n this.chain.push(mw as Middleware<T>);\n return this;\n }\n\n prepend(mw: Middleware<T>): this {\n this.ensureUnique(mw.name);\n this.chain.unshift(mw);\n return this;\n }\n\n /**\n * Insert middleware at an explicit index. Out-of-range indices are clamped.\n * Use this when insertBefore/insertAfter are insufficient (e.g. to place\n * a middleware at a known position regardless of named targets).\n */\n insertAt(index: number, mw: Middleware<T>): this {\n this.ensureUnique(mw.name);\n const idx = Math.max(0, Math.min(index, this.chain.length));\n this.chain.splice(idx, 0, mw);\n return this;\n }\n\n /**\n * Insert mw immediately before the first occurrence of target.\n * If called multiple times with the same target, each call inserts\n * before the target's current position — so after insertBefore('B', X)\n * then insertBefore('B', Y), the order is Y → X → B.\n */\n insertBefore(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\n this.ensureUnique(mw.name);\n const idx = this.indexOf(target, opts?.optional);\n if (idx === -1) return this;\n this.chain.splice(idx, 0, mw);\n return this;\n }\n\n /**\n * Insert mw immediately after the first occurrence of target.\n * If called multiple times with the same target, each call inserts\n * after the target's current position — so after insertAfter('B', X)\n * then insertAfter('B', Y), the order is B → X → Y.\n */\n insertAfter(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\n this.ensureUnique(mw.name);\n const idx = this.indexOf(target, opts?.optional);\n if (idx === -1) return this;\n this.chain.splice(idx + 1, 0, mw);\n return this;\n }\n\n replace(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\n if (mw.name !== target) this.ensureUnique(mw.name);\n const idx = this.indexOf(target, opts?.optional);\n if (idx === -1) return this;\n this.chain[idx] = mw;\n return this;\n }\n\n remove(name: string, opts?: PipelineOptions): this {\n const idx = this.indexOf(name, opts?.optional);\n if (idx === -1) return this;\n this.chain.splice(idx, 1);\n return this;\n }\n\n list(): readonly string[] {\n return this.chain.map((m) => m.name);\n }\n\n size(): number {\n return this.chain.length;\n }\n\n /** Return a read-only view suitable for passing to plugins. */\n asReadonly(): ReadonlyPipeline<T> {\n // The returned object's methods close over `this`, so it always sees the live chain.\n // `list()` returns a frozen snapshot to prevent external mutation of the chain.\n const self = this;\n return Object.freeze({\n get size() { return self.size(); },\n list() { return Object.freeze(self.list()); },\n run(input: T) { return self.run(input); },\n });\n }\n\n async run(input: T): Promise<T> {\n let index = -1;\n const chain = this.chain;\n\n const dispatch = async (i: number, value: T): Promise<T> => {\n if (i <= index) {\n throw new Error(`Pipeline: next() called multiple times in \"${chain[index]?.name}\"`);\n }\n index = i;\n const mw = chain[i];\n if (!mw) return value;\n return mw.handler(value, (v) => dispatch(i + 1, v));\n };\n\n return dispatch(0, input);\n }\n\n private indexOf(name: string, optional = false): number {\n const idx = this.chain.findIndex((m) => m.name === name);\n if (idx === -1 && !optional) {\n throw new Error(`Pipeline: middleware \"${name}\" not found`);\n }\n return idx;\n }\n\n private ensureUnique(name: string): void {\n if (this.chain.some((m) => m.name === name)) {\n throw new Error(`Pipeline: middleware \"${name}\" already registered`);\n }\n }\n}\n","/**\n * EventBus — observe-only typed event bus.\n * Subscribers cannot modify or cancel. Subscriber exceptions are caught.\n */\n\nimport type { Usage } from '../types/provider.js';\nimport type { Context } from '../core/context.js';\n\nexport interface EventMap {\n 'session.started': { id: string };\n 'session.ended': { id: string; usage: Usage };\n 'session.damaged': { sessionId: string; detail: string };\n 'iteration.started': { ctx: Context; index: number };\n 'iteration.completed': { ctx: Context; index: number };\n /**\n * Fired when the agent hits its iteration limit. Listeners (CLI/TUI) can\n * call `grant(extra)` to allow more iterations, or `deny()` to stop.\n * If no listener responds within 30s the run ends with 'max_iterations'.\n */\n 'iteration.limit_reached': {\n currentIterations: number;\n currentLimit: number;\n grant: (extraIterations: number) => void;\n deny: () => void;\n };\n 'provider.response': { ctx: Context; usage: Usage; stopReason: string };\n 'provider.text_delta': { ctx: Context; text: string };\n 'provider.tool_use_start': { ctx: Context; id: string; name: string };\n 'provider.tool_use_stop': { ctx: Context; id: string };\n /**\n * Fired before each retry of a failed provider call. `attempt` is 1-based\n * (the first retry is attempt 1, etc.). `description` is the human-readable\n * one-liner from `ProviderError.describe()` — render this in the CLI/TUI\n * instead of grepping logger output for the raw JSON body.\n */\n 'provider.retry': {\n providerId: string;\n attempt: number;\n delayMs: number;\n status: number;\n description: string;\n };\n /**\n * Fired once when a provider call ultimately fails (retries exhausted, or\n * non-retryable error). Same shape as `provider.retry` minus the delay.\n */\n 'provider.error': {\n providerId: string;\n status: number;\n description: string;\n retryable: boolean;\n };\n 'tool.started': { name: string; id: string; input?: unknown };\n /**\n * `output` is a truncated preview of the tool's serialized result text\n * (capped at ~400 chars by the emitter). UIs render this inline in the\n * tool history line without re-fetching from the session log.\n */\n 'tool.executed': {\n name: string;\n durationMs: number;\n ok: boolean;\n input?: unknown;\n output?: string;\n };\n 'token.threshold': { used: number; limit: number };\n 'compaction.fired': { before: number; after: number };\n 'mcp.server.connected': { name: string; toolCount: number };\n 'mcp.server.reconnected': { name: string; toolCount: number };\n 'mcp.server.disconnected': { name: string; reason: string };\n 'token.cost_estimate_unavailable': { model: string };\n error: { err: Error; phase: string };\n}\n\nexport type EventName = keyof EventMap;\nexport type Listener<E extends EventName> = (payload: EventMap[E]) => void;\n\nexport interface EventLogger {\n error(msg: string, ctx?: unknown): void;\n}\n\nexport class EventBus {\n private readonly listeners = new Map<EventName, Set<Listener<EventName>>>();\n private logger?: EventLogger;\n\n setLogger(logger: EventLogger): void {\n this.logger = logger;\n }\n\n on<E extends EventName>(event: E, fn: Listener<E>): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(fn as Listener<EventName>);\n return () => this.off(event, fn);\n }\n\n off<E extends EventName>(event: E, fn: Listener<E>): void {\n this.listeners.get(event)?.delete(fn as Listener<EventName>);\n }\n\n once<E extends EventName>(event: E, fn: Listener<E>): () => void {\n const wrapper: Listener<E> = (payload) => {\n this.off(event, wrapper as Listener<EventName>);\n (fn as Listener<E>)(payload);\n };\n this.on(event, wrapper as Listener<E>);\n return () => {\n this.off(event, wrapper as Listener<EventName>);\n };\n }\n\n emit<E extends EventName>(event: E, payload: EventMap[E]): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const fn of set) {\n try {\n (fn as Listener<E>)(payload);\n } catch (err) {\n this.logger?.error(`EventBus listener for \"${event}\" threw`, err);\n }\n }\n }\n\n clear(): void {\n this.listeners.clear();\n }\n}\n","import type { Token } from './container.js';\nimport type { Logger } from '../types/logger.js';\nimport type { TokenCounter } from '../types/token-counter.js';\nimport type { SessionStore } from '../types/session.js';\nimport type { MemoryStore } from '../types/memory.js';\nimport type { PermissionPolicy } from '../types/permission.js';\nimport type { Compactor } from '../types/compactor.js';\nimport type { PathResolver } from '../types/path-resolver.js';\nimport type { ConfigLoader } from '../types/config.js';\nimport type { Renderer } from '../types/renderer.js';\nimport type { InputReader } from '../types/input-reader.js';\nimport type { ErrorHandler } from '../types/error-handler.js';\nimport type { RetryPolicy } from '../types/retry-policy.js';\nimport type { SkillLoader } from '../types/skill.js';\nimport type { SystemPromptBuilder } from '../types/system-prompt.js';\nimport type { SecretScrubber } from '../types/secret-scrubber.js';\nimport type { ModelsRegistry } from '../types/models-registry.js';\n\nconst t = <T>(name: string): Token<T> => Symbol(name) as Token<T>;\n\nexport const TOKENS = {\n Logger: t<Logger>('Logger'),\n TokenCounter: t<TokenCounter>('TokenCounter'),\n SessionStore: t<SessionStore>('SessionStore'),\n MemoryStore: t<MemoryStore>('MemoryStore'),\n PermissionPolicy: t<PermissionPolicy>('PermissionPolicy'),\n Compactor: t<Compactor>('Compactor'),\n PathResolver: t<PathResolver>('PathResolver'),\n ConfigLoader: t<ConfigLoader>('ConfigLoader'),\n Renderer: t<Renderer>('Renderer'),\n InputReader: t<InputReader>('InputReader'),\n ErrorHandler: t<ErrorHandler>('ErrorHandler'),\n RetryPolicy: t<RetryPolicy>('RetryPolicy'),\n SkillLoader: t<SkillLoader>('SkillLoader'),\n SystemPromptBuilder: t<SystemPromptBuilder>('SystemPromptBuilder'),\n SecretScrubber: t<SecretScrubber>('SecretScrubber'),\n ModelsRegistry: t<ModelsRegistry>('ModelsRegistry'),\n} as const;\n","/**\n * RunController centralises abort + cleanup for a single agent run. It\n * wraps a single AbortController and exposes a registry of teardown\n * hooks that fire (LIFO, exactly once) when the run aborts OR ends\n * normally. Anyone holding the controller can:\n *\n * - read `signal` to bail out cooperatively\n * - call `abort(reason?)` to abort the run\n * - call `onAbort(fn)` to register a cleanup hook\n * - call `dispose()` when the run ends normally — this fires the\n * hooks too, so cleanup runs regardless of outcome\n *\n * Hooks must be idempotent and synchronous-or-quick. Errors thrown\n * inside hooks are caught and surfaced through `errorSink` (or the\n * console as a last resort) so one bad hook can't block the others.\n */\nexport interface RunControllerOptions {\n /** Optional parent signal — abort propagates from parent → this. */\n parentSignal?: AbortSignal;\n /** Receives errors thrown by cleanup hooks. Defaults to console.warn. */\n errorSink?: (err: unknown, where: string) => void;\n}\n\nexport class RunController {\n private readonly ctrl = new AbortController();\n private readonly hooks: Array<() => void | Promise<void>> = [];\n private disposed = false;\n private hooksDrained = false;\n private readonly errorSink: (err: unknown, where: string) => void;\n\n constructor(opts: RunControllerOptions = {}) {\n this.errorSink =\n opts.errorSink ??\n ((err, where) => {\n console.warn(`[run] cleanup hook failed in ${where}:`, err);\n });\n if (opts.parentSignal) {\n const parent = opts.parentSignal;\n if (parent.aborted) {\n this.ctrl.abort(parent.reason);\n } else {\n const onParentAbort = () => this.ctrl.abort(parent.reason);\n parent.addEventListener('abort', onParentAbort, { once: true });\n // When this run finishes normally, stop listening on the parent.\n this.onAbort(() => parent.removeEventListener('abort', onParentAbort));\n }\n }\n this.ctrl.signal.addEventListener(\n 'abort',\n () => {\n void this.runHooks();\n },\n { once: true },\n );\n }\n\n get signal(): AbortSignal {\n return this.ctrl.signal;\n }\n\n get aborted(): boolean {\n return this.ctrl.signal.aborted;\n }\n\n abort(reason?: unknown): void {\n if (this.ctrl.signal.aborted) return;\n this.ctrl.abort(reason);\n }\n\n /**\n * Register a teardown hook. Returns an unsubscribe function so callers\n * can opt out before the hook fires (e.g. when a tool finishes cleanly\n * before abort happens).\n */\n onAbort(fn: () => void | Promise<void>): () => void {\n this.hooks.push(fn);\n return () => {\n const idx = this.hooks.indexOf(fn);\n if (idx !== -1) this.hooks.splice(idx, 1);\n };\n }\n\n /**\n * Fire cleanup hooks and tear down listeners — called when the run\n * ends *normally* so cleanup happens regardless of outcome. Subsequent\n * aborts become no-ops.\n */\n async dispose(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n await this.runHooks();\n }\n\n private async runHooks(): Promise<void> {\n if (this.hooksDrained) return;\n this.hooksDrained = true;\n // Snapshot + clear so hooks added during cleanup don't re-fire.\n const snapshot = this.hooks.splice(0, this.hooks.length).reverse();\n for (const hook of snapshot) {\n try {\n await hook();\n } catch (err) {\n this.errorSink(err, 'RunController.dispose');\n }\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/errors.ts","../../src/kernel/container.ts","../../src/kernel/pipeline.ts","../../src/kernel/events.ts","../../src/kernel/tokens.ts","../../src/kernel/run-controller.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * WrongStack error hierarchy.\r\n *\r\n * Every error thrown by the framework is a `WrongStackError` with a\r\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\r\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\r\n * data instead of parsing error messages.\r\n */\r\n\r\n// ── Error codes ──────────────────────────────────────────────────────\r\n\r\nexport type ErrorCode =\r\n // Provider\r\n | 'PROVIDER_RATE_LIMITED'\r\n | 'PROVIDER_AUTH_FAILED'\r\n | 'PROVIDER_OVERLOADED'\r\n | 'PROVIDER_INVALID_REQUEST'\r\n | 'PROVIDER_SERVER_ERROR'\r\n | 'PROVIDER_NETWORK_ERROR'\r\n | 'PROVIDER_CONTEXT_OVERFLOW'\r\n // Tool\r\n | 'TOOL_NOT_FOUND'\r\n | 'TOOL_PERMISSION_DENIED'\r\n | 'TOOL_EXECUTION_FAILED'\r\n | 'TOOL_TIMEOUT'\r\n | 'TOOL_INPUT_INVALID'\r\n // Config\r\n | 'CONFIG_INVALID'\r\n | 'CONFIG_NOT_FOUND'\r\n | 'CONFIG_PARSE_FAILED'\r\n | 'CONFIG_MIGRATION_NEEDED'\r\n // Plugin\r\n | 'PLUGIN_LOAD_FAILED'\r\n | 'PLUGIN_API_MISMATCH'\r\n | 'PLUGIN_MISSING_DEPENDENCY'\r\n // Agent\r\n | 'AGENT_ITERATION_LIMIT'\r\n | 'AGENT_CONTEXT_OVERFLOW'\r\n | 'AGENT_ABORTED'\r\n | 'AGENT_RUN_FAILED'\r\n // Session\r\n | 'SESSION_NOT_FOUND'\r\n | 'SESSION_CORRUPTED'\r\n | 'SESSION_WRITE_FAILED'\r\n // Container / Registry\r\n | 'CONTAINER_TOKEN_ALREADY_BOUND'\r\n | 'CONTAINER_TOKEN_NOT_BOUND'\r\n | 'REGISTRY_DUPLICATE'\r\n | 'REGISTRY_NOT_FOUND'\r\n // General\r\n | 'UNKNOWN';\r\n\r\nexport type ErrorSubsystem = 'provider' | 'tool' | 'config' | 'plugin' | 'agent' | 'session' | 'container' | 'general';\r\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\r\n\r\n// ── Base error class ─────────────────────────────────────────────────\r\n\r\nexport class WrongStackError extends Error {\r\n readonly code: ErrorCode;\r\n readonly subsystem: ErrorSubsystem;\r\n readonly severity: ErrorSeverity;\r\n readonly recoverable: boolean;\r\n readonly context?: Record<string, unknown>;\r\n\r\n constructor(opts: {\r\n message: string;\r\n code: ErrorCode;\r\n subsystem: ErrorSubsystem;\r\n severity?: ErrorSeverity;\r\n recoverable?: boolean;\r\n context?: Record<string, unknown>;\r\n cause?: unknown;\r\n }) {\r\n super(opts.message, { cause: opts.cause });\r\n this.name = 'WrongStackError';\r\n this.code = opts.code;\r\n this.subsystem = opts.subsystem;\r\n this.severity = opts.severity ?? 'error';\r\n this.recoverable = opts.recoverable ?? false;\r\n this.context = opts.context;\r\n }\r\n\r\n /**\r\n * Render a one-line user-facing description.\r\n * Subclasses should override for domain-specific formatting.\r\n */\r\n describe(): string {\r\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\r\n return `${this.code}: ${this.message}${ctx}`;\r\n }\r\n}\r\n\r\nfunction formatContext(ctx: Record<string, unknown>): string {\r\n const parts = Object.entries(ctx)\r\n .filter(([, v]) => v !== undefined)\r\n .slice(0, 3)\r\n .map(([k, v]) => `${k}=${String(v)}`);\r\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\r\n}\r\n\r\n// ── Specific error classes ───────────────────────────────────────────\r\n\r\n/**\r\n * Tool execution errors — thrown by ToolExecutor and individual tools.\r\n */\r\nexport class ToolError extends WrongStackError {\r\n readonly toolName: string;\r\n\r\n constructor(opts: {\r\n message: string;\r\n code: Extract<ErrorCode, 'TOOL_NOT_FOUND' | 'TOOL_PERMISSION_DENIED' | 'TOOL_EXECUTION_FAILED' | 'TOOL_TIMEOUT' | 'TOOL_INPUT_INVALID'>;\r\n toolName: string;\r\n recoverable?: boolean;\r\n context?: Record<string, unknown>;\r\n cause?: unknown;\r\n }) {\r\n super({\r\n message: opts.message,\r\n code: opts.code,\r\n subsystem: 'tool',\r\n recoverable: opts.recoverable,\r\n context: { tool: opts.toolName, ...opts.context },\r\n cause: opts.cause,\r\n });\r\n this.name = 'ToolError';\r\n this.toolName = opts.toolName;\r\n }\r\n}\r\n\r\n/**\r\n * Config loading / validation errors.\r\n */\r\nexport class ConfigError extends WrongStackError {\r\n constructor(opts: {\r\n message: string;\r\n code: Extract<ErrorCode, 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'>;\r\n context?: Record<string, unknown>;\r\n cause?: unknown;\r\n }) {\r\n super({\r\n message: opts.message,\r\n code: opts.code,\r\n subsystem: 'config',\r\n severity: 'fatal',\r\n recoverable: false,\r\n context: opts.context,\r\n cause: opts.cause,\r\n });\r\n this.name = 'ConfigError';\r\n }\r\n}\r\n\r\n/**\r\n * Plugin loading / lifecycle errors.\r\n */\r\nexport class PluginError extends WrongStackError {\r\n readonly pluginName: string;\r\n\r\n constructor(opts: {\r\n message: string;\r\n code: Extract<ErrorCode, 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'>;\r\n pluginName: string;\r\n context?: Record<string, unknown>;\r\n cause?: unknown;\r\n }) {\r\n super({\r\n message: opts.message,\r\n code: opts.code,\r\n subsystem: 'plugin',\r\n severity: 'error',\r\n recoverable: opts.code === 'PLUGIN_MISSING_DEPENDENCY',\r\n context: { plugin: opts.pluginName, ...opts.context },\r\n cause: opts.cause,\r\n });\r\n this.name = 'PluginError';\r\n this.pluginName = opts.pluginName;\r\n }\r\n}\r\n\r\n/**\r\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\r\n * escapes the inner loop, so callers always see a structured error.\r\n */\r\nexport class AgentError extends WrongStackError {\r\n constructor(opts: {\r\n message: string;\r\n code: Extract<ErrorCode, 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'>;\r\n recoverable?: boolean;\r\n context?: Record<string, unknown>;\r\n cause?: unknown;\r\n }) {\r\n super({\r\n message: opts.message,\r\n code: opts.code,\r\n subsystem: 'agent',\r\n severity: opts.code === 'AGENT_ABORTED' ? 'warning' : 'error',\r\n recoverable: opts.recoverable ?? opts.code === 'AGENT_ITERATION_LIMIT',\r\n context: opts.context,\r\n cause: opts.cause,\r\n });\r\n this.name = 'AgentError';\r\n }\r\n}\r\n\r\n/**\r\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\r\n * always gets a structured error. Pass-throughs WrongStackError instances\r\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\r\n * with the original preserved as `cause`.\r\n */\r\nexport function toWrongStackError(err: unknown, code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = 'AGENT_RUN_FAILED'): WrongStackError {\r\n if (err instanceof WrongStackError) return err;\r\n const message = err instanceof Error ? err.message : String(err);\r\n return new AgentError({\r\n message,\r\n code: code === 'UNKNOWN' ? 'AGENT_RUN_FAILED' : code,\r\n cause: err,\r\n });\r\n}\r\n\r\n/**\r\n * Session storage errors.\r\n */\r\nexport class SessionError extends WrongStackError {\r\n readonly sessionId?: string;\r\n\r\n constructor(opts: {\r\n message: string;\r\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\r\n sessionId?: string;\r\n context?: Record<string, unknown>;\r\n cause?: unknown;\r\n }) {\r\n super({\r\n message: opts.message,\r\n code: opts.code,\r\n subsystem: 'session',\r\n severity: opts.code === 'SESSION_WRITE_FAILED' ? 'error' : 'warning',\r\n recoverable: opts.code !== 'SESSION_CORRUPTED',\r\n context: { sessionId: opts.sessionId, ...opts.context },\r\n cause: opts.cause,\r\n });\r\n this.name = 'SessionError';\r\n this.sessionId = opts.sessionId;\r\n }\r\n}\r\n\r\n// ── Type guards ──────────────────────────────────────────────────────\r\n\r\nexport function isWrongStackError(err: unknown): err is WrongStackError {\r\n return err instanceof WrongStackError;\r\n}\r\n\r\nexport function isToolError(err: unknown): err is ToolError {\r\n return err instanceof ToolError;\r\n}\r\n\r\nexport function isConfigError(err: unknown): err is ConfigError {\r\n return err instanceof ConfigError;\r\n}\r\n\r\nexport function isPluginError(err: unknown): err is PluginError {\r\n return err instanceof PluginError;\r\n}\r\n\r\nexport function isSessionError(err: unknown): err is SessionError {\r\n return err instanceof SessionError;\r\n}\r\n\r\nexport function isAgentError(err: unknown): err is AgentError {\r\n return err instanceof AgentError;\r\n}\r\n","import { WrongStackError } from '../types/errors.js';\r\n\r\n/**\r\n * Container — dependency injection with explicit bind / override / decorate.\r\n *\r\n * Invariants:\r\n * bind() — throws if token already bound\r\n * override() — throws if nothing to replace\r\n * decorate() — stacks; cached value cleared on register\r\n */\r\n\r\nexport type Token<T> = symbol & { readonly __type?: T };\r\nexport type Factory<T> = (c: Container) => T;\r\nexport type Decorator<T> = (inner: T, c: Container) => T;\r\n\r\ninterface Entry<T = unknown> {\r\n factory: Factory<T>;\r\n singleton: boolean;\r\n decorators: Decorator<T>[];\r\n cache?: T;\r\n owner: string;\r\n}\r\n\r\nexport interface BindOptions {\r\n singleton?: boolean;\r\n owner?: string;\r\n}\r\n\r\nexport class Container {\r\n private readonly entries = new Map<symbol, Entry>();\r\n\r\n bind<T>(token: Token<T>, factory: Factory<T>, opts: BindOptions = {}): void {\r\n if (this.entries.has(token)) {\r\n throw new WrongStackError({\r\n message: `Container: token \"${token.description ?? 'unknown'}\" already bound`,\r\n code: 'CONTAINER_TOKEN_ALREADY_BOUND',\r\n subsystem: 'container',\r\n context: { token: token.description },\r\n });\r\n }\r\n this.entries.set(token, {\r\n factory: factory as Factory<unknown>,\r\n singleton: opts.singleton ?? true,\r\n decorators: [],\r\n owner: opts.owner ?? 'core',\r\n });\r\n }\r\n\r\n override<T>(token: Token<T>, factory: Factory<T>, opts: BindOptions = {}): void {\r\n const existing = this.entries.get(token);\r\n if (!existing) {\r\n throw new WrongStackError({\r\n message: `Container: cannot override \"${token.description ?? 'unknown'}\" — not bound`,\r\n code: 'CONTAINER_TOKEN_NOT_BOUND',\r\n subsystem: 'container',\r\n context: { token: token.description },\r\n });\r\n }\r\n this.entries.set(token, {\r\n factory: factory as Factory<unknown>,\r\n singleton: opts.singleton ?? existing.singleton,\r\n decorators: existing.decorators,\r\n owner: opts.owner ?? existing.owner,\r\n });\r\n }\r\n\r\n decorate<T>(token: Token<T>, decorator: Decorator<T>, owner = 'core'): void {\r\n const existing = this.entries.get(token);\r\n if (!existing) {\r\n throw new WrongStackError({\r\n message: `Container: cannot decorate \"${token.description ?? 'unknown'}\" — not bound`,\r\n code: 'CONTAINER_TOKEN_NOT_BOUND',\r\n subsystem: 'container',\r\n context: { token: token.description },\r\n });\r\n }\r\n existing.decorators.push(decorator as Decorator<unknown>);\r\n existing.cache = undefined;\r\n existing.owner = `${existing.owner}+${owner}`;\r\n }\r\n\r\n resolve<T>(token: Token<T>): T {\r\n const entry = this.entries.get(token);\r\n if (!entry) {\r\n throw new WrongStackError({\r\n message: `Container: token \"${token.description ?? 'unknown'}\" not bound`,\r\n code: 'CONTAINER_TOKEN_NOT_BOUND',\r\n subsystem: 'container',\r\n context: { token: token.description },\r\n });\r\n }\r\n if (entry.singleton && entry.cache !== undefined) {\r\n return entry.cache as T;\r\n }\r\n let value: unknown = entry.factory(this);\r\n for (const d of entry.decorators) {\r\n value = d(value, this);\r\n }\r\n if (entry.singleton) {\r\n entry.cache = value;\r\n }\r\n return value as T;\r\n }\r\n\r\n has<T>(token: Token<T>): boolean {\r\n return this.entries.has(token);\r\n }\r\n\r\n ownerOf<T>(token: Token<T>): string | undefined {\r\n return this.entries.get(token)?.owner;\r\n }\r\n\r\n /**\r\n * Remove a token's binding (along with any decorators stacked on it).\r\n * Returns true if the token existed. Use this to withdraw temporary\r\n * bindings installed by a short-lived run or plugin — without it, the\r\n * entry persists in the map forever.\r\n */\r\n unbind<T>(token: Token<T>): boolean {\r\n return this.entries.delete(token);\r\n }\r\n\r\n /**\r\n * Drop every binding. Intended for tests and short-lived CLI invocations\r\n * that rebuild the container from scratch. Production code should prefer\r\n * `unbind` on the specific tokens it owns.\r\n */\r\n clear(): void {\r\n this.entries.clear();\r\n }\r\n\r\n list(): Array<{ token: symbol; owner: string }> {\r\n return Array.from(this.entries.entries()).map(([token, entry]) => ({\r\n token,\r\n owner: entry.owner,\r\n }));\r\n }\r\n\r\n /**\r\n * Inspect a binding's full shape, including decorator count and whether\r\n * a singleton value is cached. Returns null if the token is unbound.\r\n * Decorator and factory function references are not exposed — only counts\r\n * and metadata, to keep internal state hidden.\r\n */\r\n inspect<T>(token: Token<T>): {\r\n owner: string;\r\n singleton: boolean;\r\n decoratorCount: number;\r\n cached: boolean;\r\n } | null {\r\n const entry = this.entries.get(token);\r\n if (!entry) return null;\r\n return {\r\n owner: entry.owner,\r\n singleton: entry.singleton,\r\n decoratorCount: entry.decorators.length,\r\n cached: entry.cache !== undefined,\r\n };\r\n }\r\n}\r\n","/**\r\n * Pipeline — Koa-style middleware chain with named middleware\r\n * and position-aware insertion. Generic over input type T.\r\n */\r\n\r\nexport type NextFn<T> = (value: T) => Promise<T>;\r\nexport type MiddlewareHandler<T> = (value: T, next: NextFn<T>) => Promise<T>;\r\n\r\n/**\r\n * Called when a middleware crashes (throws or rejects). Used by the\r\n * Pipeline's error boundary to log the offender without aborting the run.\r\n *\r\n * Return `'rethrow'` to propagate the error (default for core middleware),\r\n * or `'swallow'` to skip past the crashing middleware and continue with the\r\n * value the previous one produced. Plugin middleware should usually be\r\n * swallowed so one bad plugin can't kill an agent run.\r\n */\r\nexport type PipelineErrorPolicy = 'rethrow' | 'swallow';\r\n\r\nexport interface PipelineErrorEvent {\r\n middleware: string;\r\n owner?: string;\r\n err: unknown;\r\n}\r\n\r\nexport type PipelineErrorHandler = (\r\n ev: PipelineErrorEvent,\r\n) => PipelineErrorPolicy | Promise<PipelineErrorPolicy>;\r\n\r\nexport interface Middleware<T> {\r\n name: string;\r\n handler: MiddlewareHandler<T>;\r\n owner?: string;\r\n}\r\n\r\nexport interface PipelineOptions {\r\n /** When true and the target middleware is not found, operations silently no-op instead of throwing. */\r\n optional?: boolean;\r\n}\r\n\r\n/**\r\n * Read-only view of a pipeline. Returned to consumers (plugins, hooks)\r\n * so they can inspect but not mutate the chain.\r\n */\r\nexport interface ReadonlyPipeline<T> {\r\n readonly size: number;\r\n list(): readonly string[];\r\n run(input: T): Promise<T>;\r\n}\r\n\r\nexport class Pipeline<T> {\r\n private readonly chain: Middleware<T>[] = [];\r\n private errorHandler?: PipelineErrorHandler;\r\n\r\n /**\r\n * Install an error boundary. When a middleware throws or rejects, the\r\n * handler is called and decides whether to swallow (continue with the\r\n * pre-handler value) or rethrow. Without a handler, errors propagate.\r\n *\r\n * Wire one per pipeline at boot — the host CLI typically installs a\r\n * single boundary that logs to the operational log and emits a\r\n * `pipeline.error` event for /diag.\r\n */\r\n setErrorHandler(handler: PipelineErrorHandler | undefined): this {\r\n this.errorHandler = handler;\r\n return this;\r\n }\r\n\r\n use(mw: Middleware<T> | Middleware<unknown>): this {\r\n this.ensureUnique(mw.name);\r\n this.chain.push(mw as Middleware<T>);\r\n return this;\r\n }\r\n\r\n prepend(mw: Middleware<T>): this {\r\n this.ensureUnique(mw.name);\r\n this.chain.unshift(mw);\r\n return this;\r\n }\r\n\r\n /**\r\n * Insert middleware at an explicit index. Out-of-range indices are clamped.\r\n * Use this when insertBefore/insertAfter are insufficient (e.g. to place\r\n * a middleware at a known position regardless of named targets).\r\n */\r\n insertAt(index: number, mw: Middleware<T>): this {\r\n this.ensureUnique(mw.name);\r\n const idx = Math.max(0, Math.min(index, this.chain.length));\r\n this.chain.splice(idx, 0, mw);\r\n return this;\r\n }\r\n\r\n /**\r\n * Insert mw immediately before the first occurrence of target.\r\n * If called multiple times with the same target, each call inserts\r\n * before the target's current position — so after insertBefore('B', X)\r\n * then insertBefore('B', Y), the order is Y → X → B.\r\n */\r\n insertBefore(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\r\n this.ensureUnique(mw.name);\r\n const idx = this.indexOf(target, opts?.optional);\r\n if (idx === -1) return this;\r\n this.chain.splice(idx, 0, mw);\r\n return this;\r\n }\r\n\r\n /**\r\n * Insert mw immediately after the first occurrence of target.\r\n * If called multiple times with the same target, each call inserts\r\n * after the target's current position — so after insertAfter('B', X)\r\n * then insertAfter('B', Y), the order is B → X → Y.\r\n */\r\n insertAfter(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\r\n this.ensureUnique(mw.name);\r\n const idx = this.indexOf(target, opts?.optional);\r\n if (idx === -1) return this;\r\n this.chain.splice(idx + 1, 0, mw);\r\n return this;\r\n }\r\n\r\n replace(target: string, mw: Middleware<T>, opts?: PipelineOptions): this {\r\n if (mw.name !== target) this.ensureUnique(mw.name);\r\n const idx = this.indexOf(target, opts?.optional);\r\n if (idx === -1) return this;\r\n this.chain[idx] = mw;\r\n return this;\r\n }\r\n\r\n remove(name: string, opts?: PipelineOptions): this {\r\n const idx = this.indexOf(name, opts?.optional);\r\n if (idx === -1) return this;\r\n this.chain.splice(idx, 1);\r\n return this;\r\n }\r\n\r\n list(): readonly string[] {\r\n return this.chain.map((m) => m.name);\r\n }\r\n\r\n size(): number {\r\n return this.chain.length;\r\n }\r\n\r\n /** Return a read-only view suitable for passing to plugins. */\r\n asReadonly(): ReadonlyPipeline<T> {\r\n // The returned object's methods close over `this`, so it always sees the live chain.\r\n // `list()` returns a frozen snapshot to prevent external mutation of the chain.\r\n const self = this;\r\n return Object.freeze({\r\n get size() { return self.size(); },\r\n list() { return Object.freeze(self.list()); },\r\n run(input: T) { return self.run(input); },\r\n });\r\n }\r\n\r\n async run(input: T): Promise<T> {\r\n let index = -1;\r\n const chain = this.chain;\r\n const errorHandler = this.errorHandler;\r\n\r\n const dispatch = async (i: number, value: T): Promise<T> => {\r\n if (i <= index) {\r\n throw new Error(`Pipeline: next() called multiple times in \"${chain[index]?.name}\"`);\r\n }\r\n index = i;\r\n const mw = chain[i];\r\n if (!mw) return value;\r\n try {\r\n return await mw.handler(value, (v) => dispatch(i + 1, v));\r\n } catch (err) {\r\n if (!errorHandler) throw err;\r\n const policy = await errorHandler({ middleware: mw.name, owner: mw.owner, err });\r\n if (policy === 'rethrow') throw err;\r\n // Swallow: continue with the value that was about to flow into this\r\n // middleware. Subsequent middleware after the crashed one is skipped\r\n // — error boundary is \"skip the broken layer\", not \"skip the rest\".\r\n return value;\r\n }\r\n };\r\n\r\n return dispatch(0, input);\r\n }\r\n\r\n private indexOf(name: string, optional = false): number {\r\n const idx = this.chain.findIndex((m) => m.name === name);\r\n if (idx === -1 && !optional) {\r\n throw new Error(`Pipeline: middleware \"${name}\" not found`);\r\n }\r\n return idx;\r\n }\r\n\r\n private ensureUnique(name: string): void {\r\n if (this.chain.some((m) => m.name === name)) {\r\n throw new Error(`Pipeline: middleware \"${name}\" already registered`);\r\n }\r\n }\r\n}\r\n","/**\r\n * EventBus — observe-only typed event bus.\r\n * Subscribers cannot modify or cancel. Subscriber exceptions are caught.\r\n */\r\n\r\nimport type { Usage } from '../types/provider.js';\r\nimport type { Context } from '../core/context.js';\r\nimport type { Tool, ToolProgressEvent } from '../types/tool.js';\r\n\r\nexport interface EventMap {\r\n 'session.started': { id: string };\r\n 'session.ended': { id: string; usage: Usage };\r\n 'session.damaged': { sessionId: string; detail: string };\r\n 'iteration.started': { ctx: Context; index: number };\r\n 'iteration.completed': { ctx: Context; index: number };\r\n /**\r\n * Fired when the agent hits its iteration limit. Listeners (CLI/TUI) can\r\n * call `grant(extra)` to allow more iterations, or `deny()` to stop.\r\n * If no listener responds within 30s the run ends with 'max_iterations'.\r\n */\r\n 'iteration.limit_reached': {\r\n currentIterations: number;\r\n currentLimit: number;\r\n grant: (extraIterations: number) => void;\r\n deny: () => void;\r\n };\r\n 'provider.response': { ctx: Context; usage: Usage; stopReason: string };\r\n 'provider.text_delta': { ctx: Context; text: string };\r\n 'provider.tool_use_start': { ctx: Context; id: string; name: string };\r\n 'provider.tool_use_stop': { ctx: Context; id: string };\r\n /**\r\n * Fired before each retry of a failed provider call. `attempt` is 1-based\r\n * (the first retry is attempt 1, etc.). `description` is the human-readable\r\n * one-liner from `ProviderError.describe()` — render this in the CLI/TUI\r\n * instead of grepping logger output for the raw JSON body.\r\n */\r\n 'provider.retry': {\r\n providerId: string;\r\n attempt: number;\r\n delayMs: number;\r\n status: number;\r\n description: string;\r\n };\r\n /**\r\n * Fired once when a provider call ultimately fails (retries exhausted, or\r\n * non-retryable error). Same shape as `provider.retry` minus the delay.\r\n */\r\n 'provider.error': {\r\n providerId: string;\r\n status: number;\r\n description: string;\r\n retryable: boolean;\r\n };\r\n 'tool.started': { name: string; id: string; input?: unknown };\r\n /**\r\n * Fired for each ToolProgressEvent yielded by `Tool.executeStream`. UIs\r\n * subscribe to render incremental progress (streaming bash output, file\r\n * tree counts, etc.) without the tool having to know about the UI.\r\n */\r\n 'tool.progress': { name: string; id: string; event: ToolProgressEvent };\r\n /**\r\n * Fired when a tool call needs user confirmation and no confirmHandler\r\n * is registered on the executor. The TUI renders a confirmation dialog\r\n * from this event. Resolution is driven by calling the resolve function\r\n * passed in the payload with a decision string ('yes' | 'no' | 'always' | 'deny').\r\n */\r\n 'tool.confirm_needed': {\r\n tool: Tool;\r\n input: unknown;\r\n toolUseId: string;\r\n suggestedPattern: string;\r\n resolve: (decision: 'yes' | 'no' | 'always' | 'deny') => void;\r\n };\r\n /**\r\n * `output` is a truncated preview of the tool's serialized result text\r\n * (capped at ~400 chars by the emitter). UIs render this inline in the\r\n * tool history line without re-fetching from the session log.\r\n */\r\n 'tool.executed': {\r\n name: string;\r\n durationMs: number;\r\n ok: boolean;\r\n input?: unknown;\r\n output?: string;\r\n };\r\n 'token.threshold': { used: number; limit: number };\r\n 'compaction.fired': { before: number; after: number };\r\n 'mcp.server.connected': { name: string; toolCount: number };\r\n 'mcp.server.reconnected': { name: string; toolCount: number };\r\n 'mcp.server.disconnected': { name: string; reason: string };\r\n 'token.cost_estimate_unavailable': { model: string };\r\n error: { err: Error; phase: string };\r\n}\r\n\r\nexport type EventName = keyof EventMap;\r\nexport type Listener<E extends EventName> = (payload: EventMap[E]) => void;\r\n\r\nexport interface EventLogger {\r\n error(msg: string, ctx?: unknown): void;\r\n}\r\n\r\nexport class EventBus {\r\n private readonly listeners = new Map<EventName, Set<Listener<EventName>>>();\r\n private logger?: EventLogger;\r\n\r\n setLogger(logger: EventLogger): void {\r\n this.logger = logger;\r\n }\r\n\r\n on<E extends EventName>(event: E, fn: Listener<E>): () => void {\r\n let set = this.listeners.get(event);\r\n if (!set) {\r\n set = new Set();\r\n this.listeners.set(event, set);\r\n }\r\n set.add(fn as Listener<EventName>);\r\n return () => this.off(event, fn);\r\n }\r\n\r\n off<E extends EventName>(event: E, fn: Listener<E>): void {\r\n this.listeners.get(event)?.delete(fn as Listener<EventName>);\r\n }\r\n\r\n once<E extends EventName>(event: E, fn: Listener<E>): () => void {\r\n const wrapper: Listener<E> = (payload) => {\r\n this.off(event, wrapper as Listener<EventName>);\r\n (fn as Listener<E>)(payload);\r\n };\r\n this.on(event, wrapper as Listener<E>);\r\n return () => {\r\n this.off(event, wrapper as Listener<EventName>);\r\n };\r\n }\r\n\r\n emit<E extends EventName>(event: E, payload: EventMap[E]): void {\r\n const set = this.listeners.get(event);\r\n if (!set) return;\r\n for (const fn of set) {\r\n try {\r\n (fn as Listener<E>)(payload);\r\n } catch (err) {\r\n this.logger?.error(`EventBus listener for \"${event}\" threw`, err);\r\n }\r\n }\r\n }\r\n\r\n clear(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * V2-D: introspection helper. Pass an `event` to count handlers for a\r\n * single key, or omit to get the total across every event. Used by the\r\n * leak-detection smoke test to flag handler accumulation across runs.\r\n */\r\n listenerCount(event?: EventName): number {\r\n if (event !== undefined) return this.listeners.get(event)?.size ?? 0;\r\n let total = 0;\r\n for (const set of this.listeners.values()) total += set.size;\r\n return total;\r\n }\r\n}\r\n","import type { Token } from './container.js';\r\nimport type { Logger } from '../types/logger.js';\r\nimport type { TokenCounter } from '../types/token-counter.js';\r\nimport type { SessionStore } from '../types/session.js';\r\nimport type { MemoryStore } from '../types/memory.js';\r\nimport type { PermissionPolicy } from '../types/permission.js';\r\nimport type { Compactor } from '../types/compactor.js';\r\nimport type { PathResolver } from '../types/path-resolver.js';\r\nimport type { ConfigLoader, ConfigStore } from '../types/config.js';\r\nimport type { Renderer } from '../types/renderer.js';\r\nimport type { InputReader } from '../types/input-reader.js';\r\nimport type { ErrorHandler } from '../types/error-handler.js';\r\nimport type { RetryPolicy } from '../types/retry-policy.js';\r\nimport type { SkillLoader } from '../types/skill.js';\r\nimport type { SystemPromptBuilder } from '../types/system-prompt.js';\r\nimport type { SecretScrubber } from '../types/secret-scrubber.js';\r\nimport type { ModelsRegistry } from '../types/models-registry.js';\r\n\r\nconst t = <T>(name: string): Token<T> => Symbol(name) as Token<T>;\r\n\r\nexport const TOKENS = {\r\n Logger: t<Logger>('Logger'),\r\n TokenCounter: t<TokenCounter>('TokenCounter'),\r\n SessionStore: t<SessionStore>('SessionStore'),\r\n MemoryStore: t<MemoryStore>('MemoryStore'),\r\n PermissionPolicy: t<PermissionPolicy>('PermissionPolicy'),\r\n Compactor: t<Compactor>('Compactor'),\r\n PathResolver: t<PathResolver>('PathResolver'),\r\n ConfigLoader: t<ConfigLoader>('ConfigLoader'),\r\n ConfigStore: t<ConfigStore>('ConfigStore'),\r\n Renderer: t<Renderer>('Renderer'),\r\n InputReader: t<InputReader>('InputReader'),\r\n ErrorHandler: t<ErrorHandler>('ErrorHandler'),\r\n RetryPolicy: t<RetryPolicy>('RetryPolicy'),\r\n SkillLoader: t<SkillLoader>('SkillLoader'),\r\n SystemPromptBuilder: t<SystemPromptBuilder>('SystemPromptBuilder'),\r\n SecretScrubber: t<SecretScrubber>('SecretScrubber'),\r\n ModelsRegistry: t<ModelsRegistry>('ModelsRegistry'),\r\n} as const;\r\n","/**\n * RunController centralises abort + cleanup for a single agent run. It\n * wraps a single AbortController and exposes a registry of teardown\n * hooks that fire (LIFO, exactly once) when the run aborts OR ends\n * normally. Anyone holding the controller can:\n *\n * - read `signal` to bail out cooperatively\n * - call `abort(reason?)` to abort the run\n * - call `onAbort(fn)` to register a cleanup hook\n * - call `dispose()` when the run ends normally — this fires the\n * hooks too, so cleanup runs regardless of outcome\n *\n * Hooks must be idempotent and synchronous-or-quick. Errors thrown\n * inside hooks are caught and surfaced through `errorSink` (or the\n * console as a last resort) so one bad hook can't block the others.\n */\nexport interface RunControllerOptions {\n /** Optional parent signal — abort propagates from parent → this. */\n parentSignal?: AbortSignal;\n /** Receives errors thrown by cleanup hooks. Defaults to console.warn. */\n errorSink?: (err: unknown, where: string) => void;\n}\n\nexport class RunController {\n private readonly ctrl = new AbortController();\n private readonly hooks: Array<() => void | Promise<void>> = [];\n private disposed = false;\n private hooksDrained = false;\n private readonly errorSink: (err: unknown, where: string) => void;\n\n constructor(opts: RunControllerOptions = {}) {\n this.errorSink =\n opts.errorSink ??\n ((err, where) => {\n console.warn(`[run] cleanup hook failed in ${where}:`, err);\n });\n if (opts.parentSignal) {\n const parent = opts.parentSignal;\n if (parent.aborted) {\n this.ctrl.abort(parent.reason);\n } else {\n const onParentAbort = () => this.ctrl.abort(parent.reason);\n parent.addEventListener('abort', onParentAbort, { once: true });\n // When this run finishes normally, stop listening on the parent.\n this.onAbort(() => parent.removeEventListener('abort', onParentAbort));\n }\n }\n this.ctrl.signal.addEventListener(\n 'abort',\n () => {\n void this.runHooks();\n },\n { once: true },\n );\n }\n\n get signal(): AbortSignal {\n return this.ctrl.signal;\n }\n\n get aborted(): boolean {\n return this.ctrl.signal.aborted;\n }\n\n abort(reason?: unknown): void {\n if (this.ctrl.signal.aborted) return;\n this.ctrl.abort(reason);\n }\n\n /**\n * Register a teardown hook. Returns an unsubscribe function so callers\n * can opt out before the hook fires (e.g. when a tool finishes cleanly\n * before abort happens).\n */\n onAbort(fn: () => void | Promise<void>): () => void {\n this.hooks.push(fn);\n return () => {\n const idx = this.hooks.indexOf(fn);\n if (idx !== -1) this.hooks.splice(idx, 1);\n };\n }\n\n /**\n * Fire cleanup hooks and tear down listeners — called when the run\n * ends *normally* so cleanup happens regardless of outcome. Subsequent\n * aborts become no-ops.\n */\n async dispose(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n await this.runHooks();\n }\n\n private async runHooks(): Promise<void> {\n if (this.hooksDrained) return;\n this.hooksDrained = true;\n // Snapshot + clear so hooks added during cleanup don't re-fire.\n const snapshot = this.hooks.splice(0, this.hooks.length).reverse();\n for (const hook of snapshot) {\n try {\n await hook();\n } catch (err) {\n this.errorSink(err, 'RunController.dispose');\n }\n }\n }\n}\n"]}