@wrongstack/core 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/agent-bridge-6KPqsFx6.d.ts +33 -0
  2. package/dist/compactor-B4mQZXf2.d.ts +17 -0
  3. package/dist/config-BU9f_5yH.d.ts +193 -0
  4. package/dist/{provider-txgB0Oq9.d.ts → context-BmM2xGUZ.d.ts} +532 -472
  5. package/dist/coordination/index.d.ts +694 -0
  6. package/dist/coordination/index.js +1995 -0
  7. package/dist/coordination/index.js.map +1 -0
  8. package/dist/defaults/index.d.ts +34 -2309
  9. package/dist/defaults/index.js +3893 -3803
  10. package/dist/defaults/index.js.map +1 -1
  11. package/dist/events-BMNaEFZl.d.ts +218 -0
  12. package/dist/execution/index.d.ts +260 -0
  13. package/dist/execution/index.js +1625 -0
  14. package/dist/execution/index.js.map +1 -0
  15. package/dist/index.d.ts +47 -10
  16. package/dist/index.js +6617 -6093
  17. package/dist/index.js.map +1 -1
  18. package/dist/infrastructure/index.d.ts +10 -0
  19. package/dist/infrastructure/index.js +575 -0
  20. package/dist/infrastructure/index.js.map +1 -0
  21. package/dist/input-reader-E-ffP2ee.d.ts +12 -0
  22. package/dist/kernel/index.d.ts +15 -4
  23. package/dist/kernel/index.js.map +1 -1
  24. package/dist/logger-BH6AE0W9.d.ts +24 -0
  25. package/dist/logger-BMQgxvdy.d.ts +12 -0
  26. package/dist/mcp-servers-Dzgg4x1w.d.ts +100 -0
  27. package/dist/memory-CEXuo7sz.d.ts +16 -0
  28. package/dist/mode-CV077NjV.d.ts +27 -0
  29. package/dist/models/index.d.ts +60 -0
  30. package/dist/models/index.js +621 -0
  31. package/dist/models/index.js.map +1 -0
  32. package/dist/models-registry-DqzwpBQy.d.ts +46 -0
  33. package/dist/models-registry-Y2xbog0E.d.ts +95 -0
  34. package/dist/multi-agent-fmkRHtof.d.ts +283 -0
  35. package/dist/observability/index.d.ts +353 -0
  36. package/dist/observability/index.js +691 -0
  37. package/dist/observability/index.js.map +1 -0
  38. package/dist/observability-BhnVLBLS.d.ts +67 -0
  39. package/dist/path-resolver-CPRj4bFY.d.ts +10 -0
  40. package/dist/path-resolver-DBjaoXFq.d.ts +54 -0
  41. package/dist/plugin-DJk6LL8B.d.ts +434 -0
  42. package/dist/renderer-rk_1Swwc.d.ts +158 -0
  43. package/dist/sdd/index.d.ts +206 -0
  44. package/dist/sdd/index.js +864 -0
  45. package/dist/sdd/index.js.map +1 -0
  46. package/dist/secret-scrubber-CicHLN4G.d.ts +31 -0
  47. package/dist/secret-scrubber-DF88luOe.d.ts +54 -0
  48. package/dist/secret-vault-DoISxaKO.d.ts +19 -0
  49. package/dist/security/index.d.ts +30 -0
  50. package/dist/security/index.js +524 -0
  51. package/dist/security/index.js.map +1 -0
  52. package/dist/selector-BbJqiEP4.d.ts +51 -0
  53. package/dist/session-reader-Drq8RvJu.d.ts +150 -0
  54. package/dist/skill-DhfSizKv.d.ts +72 -0
  55. package/dist/storage/index.d.ts +382 -0
  56. package/dist/storage/index.js +1530 -0
  57. package/dist/storage/index.js.map +1 -0
  58. package/dist/{system-prompt-vAB0F54-.d.ts → system-prompt-BC_8ypCG.d.ts} +1 -1
  59. package/dist/task-graph-BITvWt4t.d.ts +160 -0
  60. package/dist/tool-executor-CpuJPYm9.d.ts +97 -0
  61. package/dist/types/index.d.ts +26 -4
  62. package/dist/types/index.js +1787 -4
  63. package/dist/types/index.js.map +1 -1
  64. package/dist/utils/index.d.ts +49 -2
  65. package/dist/utils/index.js +100 -2
  66. package/dist/utils/index.js.map +1 -1
  67. package/package.json +34 -2
  68. package/dist/mode-Pjt5vMS6.d.ts +0 -815
  69. package/dist/session-reader-9sOTgmeC.d.ts +0 -1087
@@ -1,815 +0,0 @@
1
- import { U as Usage, a0 as Context, z as ToolProgressEvent, v as Tool, P as Permission, T as TextBlock, c as ContentBlock, k as Response, i as ProviderError } from './provider-txgB0Oq9.js';
2
-
3
- /**
4
- * Container — dependency injection with explicit bind / override / decorate.
5
- *
6
- * Invariants:
7
- * bind() — throws if token already bound
8
- * override() — throws if nothing to replace
9
- * decorate() — stacks; cached value cleared on register
10
- */
11
- type Token<T> = symbol & {
12
- readonly __type?: T;
13
- };
14
- type Factory<T> = (c: Container) => T;
15
- type Decorator<T> = (inner: T, c: Container) => T;
16
- interface BindOptions {
17
- singleton?: boolean;
18
- owner?: string;
19
- }
20
- declare class Container {
21
- private readonly entries;
22
- bind<T>(token: Token<T>, factory: Factory<T>, opts?: BindOptions): void;
23
- override<T>(token: Token<T>, factory: Factory<T>, opts?: BindOptions): void;
24
- decorate<T>(token: Token<T>, decorator: Decorator<T>, owner?: string): void;
25
- resolve<T>(token: Token<T>): T;
26
- has<T>(token: Token<T>): boolean;
27
- ownerOf<T>(token: Token<T>): string | undefined;
28
- /**
29
- * Remove a token's binding (along with any decorators stacked on it).
30
- * Returns true if the token existed. Use this to withdraw temporary
31
- * bindings installed by a short-lived run or plugin — without it, the
32
- * entry persists in the map forever.
33
- */
34
- unbind<T>(token: Token<T>): boolean;
35
- /**
36
- * Drop every binding. Intended for tests and short-lived CLI invocations
37
- * that rebuild the container from scratch. Production code should prefer
38
- * `unbind` on the specific tokens it owns.
39
- */
40
- clear(): void;
41
- list(): Array<{
42
- token: symbol;
43
- owner: string;
44
- }>;
45
- /**
46
- * Inspect a binding's full shape, including decorator count and whether
47
- * a singleton value is cached. Returns null if the token is unbound.
48
- * Decorator and factory function references are not exposed — only counts
49
- * and metadata, to keep internal state hidden.
50
- */
51
- inspect<T>(token: Token<T>): {
52
- owner: string;
53
- singleton: boolean;
54
- decoratorCount: number;
55
- cached: boolean;
56
- } | null;
57
- }
58
-
59
- /**
60
- * Pipeline — Koa-style middleware chain with named middleware
61
- * and position-aware insertion. Generic over input type T.
62
- */
63
- type NextFn<T> = (value: T) => Promise<T>;
64
- type MiddlewareHandler<T> = (value: T, next: NextFn<T>) => Promise<T>;
65
- /**
66
- * Called when a middleware crashes (throws or rejects). Used by the
67
- * Pipeline's error boundary to log the offender without aborting the run.
68
- *
69
- * Return `'rethrow'` to propagate the error (default for core middleware),
70
- * or `'swallow'` to skip past the crashing middleware and continue with the
71
- * value the previous one produced. Plugin middleware should usually be
72
- * swallowed so one bad plugin can't kill an agent run.
73
- */
74
- type PipelineErrorPolicy = 'rethrow' | 'swallow';
75
- interface PipelineErrorEvent {
76
- middleware: string;
77
- owner?: string;
78
- err: unknown;
79
- }
80
- type PipelineErrorHandler = (ev: PipelineErrorEvent) => PipelineErrorPolicy | Promise<PipelineErrorPolicy>;
81
- interface Middleware<T> {
82
- name: string;
83
- handler: MiddlewareHandler<T>;
84
- owner?: string;
85
- }
86
- interface PipelineOptions {
87
- /** When true and the target middleware is not found, operations silently no-op instead of throwing. */
88
- optional?: boolean;
89
- }
90
- /**
91
- * Read-only view of a pipeline. Returned to consumers (plugins, hooks)
92
- * so they can inspect but not mutate the chain.
93
- */
94
- interface ReadonlyPipeline<T> {
95
- readonly size: number;
96
- list(): readonly string[];
97
- run(input: T): Promise<T>;
98
- }
99
- declare class Pipeline<T> {
100
- private readonly chain;
101
- private errorHandler?;
102
- /**
103
- * Install an error boundary. When a middleware throws or rejects, the
104
- * handler is called and decides whether to swallow (continue with the
105
- * pre-handler value) or rethrow. Without a handler, errors propagate.
106
- *
107
- * Wire one per pipeline at boot — the host CLI typically installs a
108
- * single boundary that logs to the operational log and emits a
109
- * `pipeline.error` event for /diag.
110
- */
111
- setErrorHandler(handler: PipelineErrorHandler | undefined): this;
112
- use(mw: Middleware<T> | Middleware<unknown>): this;
113
- prepend(mw: Middleware<T>): this;
114
- /**
115
- * Insert middleware at an explicit index. Out-of-range indices are clamped.
116
- * Use this when insertBefore/insertAfter are insufficient (e.g. to place
117
- * a middleware at a known position regardless of named targets).
118
- */
119
- insertAt(index: number, mw: Middleware<T>): this;
120
- /**
121
- * Insert mw immediately before the first occurrence of target.
122
- * If called multiple times with the same target, each call inserts
123
- * before the target's current position — so after insertBefore('B', X)
124
- * then insertBefore('B', Y), the order is Y → X → B.
125
- */
126
- insertBefore(target: string, mw: Middleware<T>, opts?: PipelineOptions): this;
127
- /**
128
- * Insert mw immediately after the first occurrence of target.
129
- * If called multiple times with the same target, each call inserts
130
- * after the target's current position — so after insertAfter('B', X)
131
- * then insertAfter('B', Y), the order is B → X → Y.
132
- */
133
- insertAfter(target: string, mw: Middleware<T>, opts?: PipelineOptions): this;
134
- replace(target: string, mw: Middleware<T>, opts?: PipelineOptions): this;
135
- remove(name: string, opts?: PipelineOptions): this;
136
- list(): readonly string[];
137
- size(): number;
138
- /** Return a read-only view suitable for passing to plugins. */
139
- asReadonly(): ReadonlyPipeline<T>;
140
- run(input: T): Promise<T>;
141
- private indexOf;
142
- private ensureUnique;
143
- }
144
-
145
- /**
146
- * EventBus — observe-only typed event bus.
147
- * Subscribers cannot modify or cancel. Subscriber exceptions are caught.
148
- */
149
-
150
- interface EventMap {
151
- 'session.started': {
152
- id: string;
153
- };
154
- 'session.ended': {
155
- id: string;
156
- usage: Usage;
157
- };
158
- 'session.damaged': {
159
- sessionId: string;
160
- detail: string;
161
- };
162
- 'iteration.started': {
163
- ctx: Context;
164
- index: number;
165
- };
166
- 'iteration.completed': {
167
- ctx: Context;
168
- index: number;
169
- };
170
- /**
171
- * Fired when the agent hits its iteration limit. Listeners (CLI/TUI) can
172
- * call `grant(extra)` to allow more iterations, or `deny()` to stop.
173
- * If no listener responds within 30s the run ends with 'max_iterations'.
174
- */
175
- 'iteration.limit_reached': {
176
- currentIterations: number;
177
- currentLimit: number;
178
- grant: (extraIterations: number) => void;
179
- deny: () => void;
180
- };
181
- 'provider.response': {
182
- ctx: Context;
183
- usage: Usage;
184
- stopReason: string;
185
- };
186
- 'provider.text_delta': {
187
- ctx: Context;
188
- text: string;
189
- };
190
- 'provider.tool_use_start': {
191
- ctx: Context;
192
- id: string;
193
- name: string;
194
- };
195
- 'provider.tool_use_stop': {
196
- ctx: Context;
197
- id: string;
198
- };
199
- /**
200
- * Fired before each retry of a failed provider call. `attempt` is 1-based
201
- * (the first retry is attempt 1, etc.). `description` is the human-readable
202
- * one-liner from `ProviderError.describe()` — render this in the CLI/TUI
203
- * instead of grepping logger output for the raw JSON body.
204
- */
205
- 'provider.retry': {
206
- providerId: string;
207
- attempt: number;
208
- delayMs: number;
209
- status: number;
210
- description: string;
211
- };
212
- /**
213
- * Fired once when a provider call ultimately fails (retries exhausted, or
214
- * non-retryable error). Same shape as `provider.retry` minus the delay.
215
- */
216
- 'provider.error': {
217
- providerId: string;
218
- status: number;
219
- description: string;
220
- retryable: boolean;
221
- };
222
- 'tool.started': {
223
- name: string;
224
- id: string;
225
- input?: unknown;
226
- };
227
- /**
228
- * Fired for each ToolProgressEvent yielded by `Tool.executeStream`. UIs
229
- * subscribe to render incremental progress (streaming bash output, file
230
- * tree counts, etc.) without the tool having to know about the UI.
231
- */
232
- 'tool.progress': {
233
- name: string;
234
- id: string;
235
- event: ToolProgressEvent;
236
- };
237
- /**
238
- * Fired when a tool call needs user confirmation and no confirmHandler
239
- * is registered on the executor. The TUI renders a confirmation dialog
240
- * from this event. Resolution is driven by calling the resolve function
241
- * passed in the payload with a decision string ('yes' | 'no' | 'always' | 'deny').
242
- */
243
- 'tool.confirm_needed': {
244
- tool: Tool;
245
- input: unknown;
246
- toolUseId: string;
247
- suggestedPattern: string;
248
- resolve: (decision: 'yes' | 'no' | 'always' | 'deny') => void;
249
- };
250
- /**
251
- * `output` is a truncated preview of the tool's serialized result text
252
- * (capped at ~400 chars by the emitter). UIs render this inline in the
253
- * tool history line without re-fetching from the session log.
254
- */
255
- 'tool.executed': {
256
- /**
257
- * The tool_use id (e.g. "toolu_…") issued by the provider for this call.
258
- * Pairs with `tool.started.id` so subscribers can correlate start/finish
259
- * even when the model fires multiple tools in parallel with identical
260
- * inputs. Optional only for legacy emit sites — new code should always
261
- * set it.
262
- */
263
- id?: string;
264
- name: string;
265
- durationMs: number;
266
- ok: boolean;
267
- input?: unknown;
268
- output?: string;
269
- };
270
- 'token.threshold': {
271
- used: number;
272
- limit: number;
273
- };
274
- 'compaction.fired': {
275
- before: number;
276
- after: number;
277
- };
278
- /**
279
- * Fired when the auto-compaction middleware's compactor.compact() call
280
- * throws. Compaction is best-effort by design so we don't crash the agent
281
- * loop, but a persistent failure (misconfigured summarizer model, network
282
- * outage) means the next iteration may hit context overflow. Observability
283
- * layers / dashboards subscribe to this to surface the silent regression.
284
- */
285
- 'compaction.failed': {
286
- err: Error;
287
- aggressive: boolean;
288
- level: 'warn' | 'soft' | 'hard';
289
- tokens: number;
290
- maxContext: number;
291
- load: number;
292
- fatal: boolean;
293
- };
294
- 'mcp.server.connected': {
295
- name: string;
296
- toolCount: number;
297
- };
298
- 'mcp.server.reconnected': {
299
- name: string;
300
- toolCount: number;
301
- };
302
- 'mcp.server.disconnected': {
303
- name: string;
304
- reason: string;
305
- };
306
- 'token.cost_estimate_unavailable': {
307
- model: string;
308
- };
309
- error: {
310
- err: Error;
311
- phase: string;
312
- };
313
- }
314
- type EventName = keyof EventMap;
315
- type Listener<E extends EventName> = (payload: EventMap[E]) => void;
316
- interface EventLogger {
317
- error(msg: string, ctx?: unknown): void;
318
- }
319
- declare class EventBus {
320
- private readonly listeners;
321
- private logger?;
322
- setLogger(logger: EventLogger): void;
323
- on<E extends EventName>(event: E, fn: Listener<E>): () => void;
324
- off<E extends EventName>(event: E, fn: Listener<E>): void;
325
- once<E extends EventName>(event: E, fn: Listener<E>): () => void;
326
- emit<E extends EventName>(event: E, payload: EventMap[E]): void;
327
- clear(): void;
328
- /**
329
- * V2-D: introspection helper. Pass an `event` to count handlers for a
330
- * single key, or omit to get the total across every event. Used by the
331
- * leak-detection smoke test to flag handler accumulation across runs.
332
- */
333
- listenerCount(event?: EventName): number;
334
- }
335
-
336
- type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace';
337
- interface Logger {
338
- level: LogLevel;
339
- error(msg: string, ctx?: unknown): void;
340
- warn(msg: string, ctx?: unknown): void;
341
- info(msg: string, ctx?: unknown): void;
342
- debug(msg: string, ctx?: unknown): void;
343
- trace(msg: string, ctx?: unknown): void;
344
- child(bindings: Record<string, unknown>): Logger;
345
- }
346
-
347
- type MemoryScope = 'project-agents' | 'project-memory' | 'user-memory';
348
- interface MemoryEntry {
349
- scope: MemoryScope;
350
- text: string;
351
- ts: string;
352
- }
353
- interface MemoryStore {
354
- readAll(): Promise<string>;
355
- read(scope: MemoryScope): Promise<string>;
356
- remember(text: string, scope?: MemoryScope): Promise<void>;
357
- forget(query: string, scope?: MemoryScope): Promise<number>;
358
- consolidate(scope: MemoryScope): Promise<void>;
359
- clear(scope?: MemoryScope): Promise<void>;
360
- }
361
-
362
- interface TrustPolicy {
363
- [toolNameOrPattern: string]: {
364
- allow?: string[];
365
- deny?: string[];
366
- auto?: boolean;
367
- trustWorkdir?: boolean;
368
- denyPrivate?: boolean;
369
- };
370
- }
371
- interface PermissionDecision {
372
- permission: Permission;
373
- reason?: string;
374
- source: 'default' | 'trust' | 'yolo' | 'user' | 'deny';
375
- }
376
- interface PermissionPolicy {
377
- evaluate(tool: Tool, input: unknown, ctx: Context): Promise<PermissionDecision>;
378
- trust(rule: {
379
- tool: string;
380
- pattern: string;
381
- }): Promise<void>;
382
- reload(): Promise<void>;
383
- }
384
-
385
- interface CompactReport {
386
- before: number;
387
- after: number;
388
- reductions: {
389
- phase: 'elision' | 'summary' | 'selective';
390
- saved: number;
391
- }[];
392
- }
393
- interface Compactor {
394
- compact(ctx: Context, opts?: {
395
- aggressive?: boolean;
396
- }): Promise<CompactReport>;
397
- }
398
-
399
- interface PathResolver {
400
- readonly projectRoot: string;
401
- readonly cwd: string;
402
- resolve(input: string): string;
403
- isInsideRoot(absPath: string): boolean;
404
- ensureInsideRoot(absPath: string): string;
405
- detectProjectRoot(start: string): string;
406
- }
407
-
408
- /**
409
- * Mirror of the models.dev/api.json schema. Top-level is keyed by provider id.
410
- * We keep `unknown` for fields we don't read so the cached payload stays faithful.
411
- */
412
- interface ModelsDevModel {
413
- id: string;
414
- name: string;
415
- family?: string;
416
- attachment?: boolean;
417
- reasoning?: boolean;
418
- tool_call?: boolean;
419
- temperature?: boolean;
420
- knowledge?: string;
421
- release_date?: string;
422
- last_updated?: string;
423
- open_weights?: boolean;
424
- modalities?: {
425
- input?: string[];
426
- output?: string[];
427
- };
428
- cost?: {
429
- input?: number;
430
- output?: number;
431
- cache_read?: number;
432
- cache_write?: number;
433
- [k: string]: number | undefined;
434
- };
435
- limit?: {
436
- context?: number;
437
- output?: number;
438
- };
439
- [k: string]: unknown;
440
- }
441
- interface ModelsDevProvider {
442
- id: string;
443
- name: string;
444
- /** Env vars that hold the API key, in priority order. */
445
- env?: string[];
446
- /** Identifies the wire format family (e.g. @ai-sdk/anthropic). */
447
- npm?: string;
448
- /** Default base URL when not provided by SDK defaults. */
449
- api?: string;
450
- /** Documentation URL. */
451
- doc?: string;
452
- models: Record<string, ModelsDevModel>;
453
- }
454
- type ModelsDevPayload = Record<string, ModelsDevProvider>;
455
- /**
456
- * Canonical wire-format families WrongStack knows how to speak natively.
457
- * Used by the provider registry to pick a transport.
458
- */
459
- type WireFamily = 'anthropic' | 'openai' | 'openai-compatible' | 'google' | 'unsupported';
460
- interface ResolvedProvider {
461
- id: string;
462
- name: string;
463
- family: WireFamily;
464
- apiBase?: string;
465
- envVars: string[];
466
- doc?: string;
467
- models: ModelsDevModel[];
468
- npm?: string;
469
- }
470
- interface ResolvedModel {
471
- providerId: string;
472
- modelId: string;
473
- capabilities: {
474
- tools: boolean;
475
- vision: boolean;
476
- reasoning: boolean;
477
- maxContext: number;
478
- maxOutput?: number;
479
- knowledge?: string;
480
- };
481
- cost?: ModelsDevModel['cost'];
482
- }
483
- interface ModelsRegistry {
484
- /** Load (from cache or network). Idempotent; second call returns cached value. */
485
- load(opts?: {
486
- force?: boolean;
487
- }): Promise<ModelsDevPayload>;
488
- /** Force-refresh from network and overwrite cache. */
489
- refresh(): Promise<ModelsDevPayload>;
490
- /** All providers, classified by wire family. */
491
- listProviders(): Promise<ResolvedProvider[]>;
492
- /** A single provider by id, or undefined. */
493
- getProvider(id: string): Promise<ResolvedProvider | undefined>;
494
- /** A model lookup with capabilities + cost. */
495
- getModel(providerId: string, modelId: string): Promise<ResolvedModel | undefined>;
496
- /** Suggest a default model for the given provider (latest by release_date). */
497
- suggestModel(providerId: string): Promise<string | undefined>;
498
- /** Cache freshness in seconds since last successful network fetch (Infinity if never). */
499
- ageSeconds(): Promise<number>;
500
- }
501
-
502
- interface ContextConfig {
503
- warnThreshold: number;
504
- softThreshold: number;
505
- hardThreshold: number;
506
- /** Enable automatic compaction when thresholds are crossed (default: true). */
507
- autoCompact?: boolean;
508
- /**
509
- * Model used for LLM-assisted summarization in IntelligentCompactor.
510
- * Falls back to the main model when omitted.
511
- */
512
- summarizerModel?: string;
513
- /**
514
- * Override the effective context window size (in tokens). Use this when
515
- * you want the compactor to trigger earlier than the provider's actual
516
- * maxContext. Defaults to the provider's reported maxContext.
517
- */
518
- effectiveMaxContext?: number;
519
- maxSessionTokens?: number;
520
- maxDailyTokens?: number;
521
- preserveK: number;
522
- eliseThreshold: number;
523
- /** Compactor strategy: 'hybrid' (default, fast rules), 'intelligent' (LLM summarization), 'selective' (LLM-driven selection). */
524
- strategy?: 'hybrid' | 'intelligent' | 'selective';
525
- /** Enable LLM-driven selective compaction (default: false for backward compat). */
526
- llmSelector?: boolean;
527
- }
528
- interface ToolsConfig {
529
- defaultExecutionStrategy: 'parallel' | 'sequential' | 'smart';
530
- maxIterations: number;
531
- iterationTimeoutMs: number;
532
- sessionTimeoutMs: number;
533
- perIterationOutputCapBytes: number;
534
- /**
535
- * When true (default), the agent automatically extends its iteration
536
- * limit by 100 when hit. Set to false to require user confirmation.
537
- */
538
- autoExtendLimit?: boolean;
539
- }
540
- interface ProviderApiKey {
541
- /** Short human-readable label (e.g. "personal", "work", "rate-limit-backup"). */
542
- label: string;
543
- /**
544
- * The key itself. The field name contains `apiKey` so the secret-vault
545
- * walker will encrypt it on write and decrypt it on read.
546
- */
547
- apiKey: string;
548
- /** ISO-8601 timestamp the key was added. */
549
- createdAt: string;
550
- }
551
- interface ProviderConfig {
552
- type: string;
553
- /**
554
- * Legacy single-key field. Still honored as a fallback when `apiKeys`
555
- * is empty. When `apiKeys`/`activeKey` are present, the config loader
556
- * mirrors the active entry into this field so downstream consumers
557
- * (provider construction, wire adapters) need no changes.
558
- */
559
- apiKey?: string;
560
- /** Multiple keys for the same provider — pick one with `activeKey`. */
561
- apiKeys?: ProviderApiKey[];
562
- /** Label of the entry in `apiKeys` to use. Defaults to the first one. */
563
- activeKey?: string;
564
- baseUrl?: string;
565
- headers?: Record<string, string>;
566
- model?: string;
567
- quirks?: Record<string, unknown>;
568
- capabilities?: Record<string, unknown>;
569
- /**
570
- * Optional wire-family override. When present, the provider can be
571
- * constructed without consulting the models.dev catalog — useful for
572
- * self-hosted endpoints, internal proxies, or for working offline.
573
- */
574
- family?: WireFamily;
575
- /** Custom env var names to probe when `apiKey` is missing. */
576
- envVars?: string[];
577
- /** Optional list of models the user wants visible for this provider. */
578
- models?: string[];
579
- }
580
- interface MCPServerConfig {
581
- /** Human-readable description shown in `wstack mcp list`. */
582
- description?: string;
583
- name: string;
584
- transport: 'stdio' | 'sse' | 'streamable-http';
585
- command?: string;
586
- args?: string[];
587
- env?: Record<string, string>;
588
- url?: string;
589
- headers?: Record<string, string>;
590
- enabled?: boolean;
591
- allowedTools?: string[];
592
- permission?: Permission;
593
- startupTimeoutMs?: number;
594
- }
595
- interface LogConfig {
596
- level: 'error' | 'warn' | 'info' | 'debug' | 'trace';
597
- file?: string;
598
- }
599
- interface PluginConfig {
600
- name: string;
601
- enabled?: boolean;
602
- options?: Record<string, unknown>;
603
- }
604
- /**
605
- * Optional subsystems that the CLI can boot without. The core flow
606
- * (provider + agent loop + bundled tools + session) always works; these
607
- * just add capabilities. `--no-features` flips all of these off, which
608
- * is the minimum viable WrongStack: a single provider, a fixed config,
609
- * no network calls at startup.
610
- */
611
- interface FeaturesConfig {
612
- /** Load MCP servers declared in `mcpServers`. */
613
- mcp: boolean;
614
- /** Load + initialise npm plugins declared in `plugins`. */
615
- plugins: boolean;
616
- /** Register `remember` / `forget` tools backed by memory store. */
617
- memory: boolean;
618
- /** Fetch the models.dev catalog at startup. When false, the provider
619
- * must declare its `family` explicitly in `providers[<id>]`. */
620
- modelsRegistry: boolean;
621
- /** Discover + load skills from disk. */
622
- skills: boolean;
623
- }
624
- interface Config {
625
- version: 1;
626
- provider: string;
627
- model: string;
628
- apiKey?: string;
629
- baseUrl?: string;
630
- providers?: Record<string, ProviderConfig>;
631
- context: ContextConfig;
632
- tools: ToolsConfig;
633
- mcpServers?: Record<string, MCPServerConfig>;
634
- plugins?: (string | PluginConfig)[];
635
- log: LogConfig;
636
- features: FeaturesConfig;
637
- yolo?: boolean;
638
- cwd?: string;
639
- /**
640
- * Per-plugin namespaced config sections. Each plugin reads its own
641
- * subtree via `ConfigStore.getExtension(pluginName)`. Plugins should
642
- * declare a `configSchema` so the loader validates this section
643
- * automatically before `setup()` runs.
644
- *
645
- * Example:
646
- * extensions: {
647
- * 'wstack-auth': { tokenUrl: 'https://...', refreshBefore: 300 },
648
- * 'wstack-metrics': { sink: 'prometheus', port: 9090 },
649
- * }
650
- */
651
- extensions?: Record<string, Record<string, unknown>>;
652
- }
653
- interface ConfigLoader {
654
- load(opts?: {
655
- cliFlags?: Partial<Config>;
656
- cwd?: string;
657
- }): Promise<Config>;
658
- }
659
- /**
660
- * Subscribable view over Config. Plugins and CLI subsystems use this instead
661
- * of holding a frozen Config reference, so they can react to runtime updates
662
- * (e.g. `/model` switching the active provider, secrets rotation, dynamic
663
- * extension reload).
664
- *
665
- * The store enforces immutability — `get()` always returns a frozen object.
666
- * Updates happen through `update(partial)`, which produces a new Config
667
- * (structurally cloned, then frozen) and notifies watchers.
668
- */
669
- interface ConfigStore {
670
- get(): Readonly<Config>;
671
- /**
672
- * Get a typed top-level section. Convenience for consumers that only
673
- * care about one slice (e.g. `tools` or `context`).
674
- */
675
- getSection<K extends keyof Config>(key: K): Readonly<Config[K]>;
676
- /**
677
- * Return the extension namespace for `pluginName`, or an empty record
678
- * when none is configured. The returned object is frozen.
679
- */
680
- getExtension(pluginName: string): Readonly<Record<string, unknown>>;
681
- /**
682
- * Apply a partial update. Returns the new Config. Watchers are notified
683
- * synchronously after the update completes. Throws if the result fails
684
- * any registered invariants (currently: version must stay 1).
685
- */
686
- update(partial: Partial<Config>): Readonly<Config>;
687
- /** Subscribe to changes. Returns an unsubscribe function. */
688
- watch(cb: (next: Readonly<Config>, prev: Readonly<Config>) => void): () => void;
689
- }
690
-
691
- interface Renderer {
692
- write(text: string | TextBlock): void;
693
- writeLine(text?: string): void;
694
- writeBlock(block: ContentBlock): void;
695
- writeToolCall(name: string, input: unknown): void;
696
- writeToolResult(name: string, content: unknown, isError: boolean): void;
697
- writeDiff(unifiedDiff: string): void;
698
- writeWarning(text: string): void;
699
- writeError(text: string): void;
700
- writeInfo(text: string): void;
701
- clear(): void;
702
- }
703
-
704
- interface PromptOption {
705
- key: string;
706
- label: string;
707
- value: string;
708
- }
709
- interface InputReader {
710
- readLine(prompt?: string): Promise<string>;
711
- readKey(prompt: string, options: PromptOption[]): Promise<string>;
712
- close(): Promise<void>;
713
- }
714
-
715
- type RecoveryDecision = {
716
- /**
717
- * Recovery mutated state or waited for capacity and the agent should
718
- * rebuild the provider request and try the turn again.
719
- */
720
- action: 'retry';
721
- reason: string;
722
- model?: string;
723
- } | {
724
- /**
725
- * Recovery produced a substitute provider response that should be
726
- * processed exactly like a normal model response.
727
- */
728
- action: 'continue';
729
- response: Response;
730
- reason?: string;
731
- } | {
732
- /** Recovery inspected the error and decided the agent must fail. */
733
- action: 'fail';
734
- reason: string;
735
- error?: unknown;
736
- };
737
- interface ErrorHandler {
738
- /**
739
- * Attempt to recover from an unretried provider/tool boundary error.
740
- *
741
- * `null` means "no strategy matched". Non-null decisions are explicit:
742
- * retry the current turn, continue with a substitute response, or fail
743
- * deliberately. Callers should not infer control flow from truthiness.
744
- */
745
- recover(err: unknown, ctx: Context): Promise<RecoveryDecision | null>;
746
- classify(err: unknown): {
747
- kind: 'rate_limit' | 'overloaded' | 'server' | 'client' | 'network' | 'abort' | 'context_overflow' | 'unknown';
748
- retryable: boolean;
749
- };
750
- }
751
-
752
- interface RetryPolicy {
753
- shouldRetry(err: ProviderError | Error, attempt: number): boolean;
754
- delayMs(attempt: number): number;
755
- maxAttempts(err: ProviderError | Error): number;
756
- }
757
-
758
- interface SkillManifest {
759
- name: string;
760
- description: string;
761
- version?: string;
762
- path: string;
763
- source: 'project' | 'user' | 'bundled';
764
- }
765
- /** Parsed skill entry for structured rendering in system prompt. */
766
- interface SkillEntry {
767
- name: string;
768
- /** "Use when..." trigger condition — one-liner */
769
- trigger: string;
770
- /** Comma-separated scope items */
771
- scope: string[];
772
- source: SkillManifest['source'];
773
- path: string;
774
- }
775
- interface SkillLoader {
776
- list(): Promise<SkillManifest[]>;
777
- /** Structured entries with trigger/scope for system prompt rendering. */
778
- listEntries(): Promise<SkillEntry[]>;
779
- find(name: string): Promise<SkillManifest | undefined>;
780
- manifestText(): Promise<string>;
781
- readBody(name: string): Promise<string>;
782
- }
783
-
784
- interface SecretScrubber {
785
- scrub(text: string): string;
786
- scrubObject<T>(obj: T): T;
787
- }
788
-
789
- interface Mode {
790
- id: string;
791
- name: string;
792
- description: string;
793
- /** Additional prompt text injected into system prompt when mode is active */
794
- prompt: string;
795
- /** Tags for tool_search filtering */
796
- tags?: string[];
797
- /** Tools that should be prioritized/highlighted when this mode is active */
798
- toolPreferences?: string[];
799
- }
800
- interface ModeManifest {
801
- modes: Mode[];
802
- defaultMode?: string;
803
- }
804
- interface ModeStore {
805
- getActiveMode(): Promise<Mode | null>;
806
- setActiveMode(modeId: string | null): Promise<void>;
807
- listModes(): Promise<Mode[]>;
808
- getMode(modeId: string): Promise<Mode | null>;
809
- }
810
- interface ModeConfig {
811
- directory: string;
812
- }
813
- declare const DEFAULT_MODES: Mode[];
814
-
815
- export { type Middleware as $, type ResolvedProvider as A, type RetryPolicy as B, type CompactReport as C, DEFAULT_MODES as D, type ErrorHandler as E, type FeaturesConfig as F, type SkillEntry as G, type SkillLoader as H, type InputReader as I, type SkillManifest as J, type TrustPolicy as K, type LogConfig as L, type MCPServerConfig as M, Container as N, EventBus as O, type PathResolver as P, type EventName as Q, type RecoveryDecision as R, type SecretScrubber as S, type ToolsConfig as T, type Listener as U, type BindOptions as V, type WireFamily as W, type Decorator as X, type EventLogger as Y, type EventMap as Z, type Factory as _, type Compactor as a, type MiddlewareHandler as a0, type NextFn as a1, Pipeline as a2, type PipelineOptions as a3, type Token as a4, type ReadonlyPipeline as a5, type Config as b, type ConfigLoader as c, type ConfigStore as d, type ContextConfig as e, type LogLevel as f, type Logger as g, type MemoryEntry as h, type MemoryScope as i, type MemoryStore as j, type Mode as k, type ModeConfig as l, type ModeManifest as m, type ModeStore as n, type ModelsDevModel as o, type ModelsDevPayload as p, type ModelsDevProvider as q, type ModelsRegistry as r, type PermissionDecision as s, type PermissionPolicy as t, type PluginConfig as u, type PromptOption as v, type ProviderApiKey as w, type ProviderConfig as x, type Renderer as y, type ResolvedModel as z };