@ordewell/core 0.5.5 → 0.5.6

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 (53) hide show
  1. package/dist/IFileSystem-BkPX7mLD.d.mts +76 -0
  2. package/dist/IFileSystem-C0l-4MGT.d.ts +76 -0
  3. package/dist/{ModeResolver-D3XO0fT9.d.ts → ModeResolver--16lh7dS.d.mts} +1 -1
  4. package/dist/{ModeResolver-D-SUFRNF.d.mts → ModeResolver-CjpG5Wli.d.ts} +1 -1
  5. package/dist/Task-Dyxp67s2.d.mts +2086 -0
  6. package/dist/Task-Dyxp67s2.d.ts +2086 -0
  7. package/dist/{chunk-T2S5O36I.mjs → chunk-C44UWIAD.mjs} +6 -6
  8. package/dist/chunk-C44UWIAD.mjs.map +1 -0
  9. package/dist/{chunk-HD2FWPRV.mjs → chunk-EDGUFCIR.mjs} +6 -1
  10. package/dist/chunk-EDGUFCIR.mjs.map +1 -0
  11. package/dist/{chunk-UUBGVCGJ.mjs → chunk-JBEFAJ2W.mjs} +2 -2
  12. package/dist/{chunk-KLN7ELXO.mjs → chunk-ROVYWEBI.mjs} +1560 -1269
  13. package/dist/chunk-ROVYWEBI.mjs.map +1 -0
  14. package/dist/index.d.mts +1414 -785
  15. package/dist/index.d.ts +1414 -785
  16. package/dist/index.js +7008 -4389
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +6075 -3767
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/order-labels.d.mts +3 -1
  21. package/dist/order-labels.d.ts +3 -1
  22. package/dist/{parsing-CDtRSxBY.d.mts → parsing-DPEpAszP.d.mts} +2 -2
  23. package/dist/{parsing-BTP4bwkk.d.ts → parsing-EcmCsF1y.d.ts} +2 -2
  24. package/dist/parsing.d.mts +5 -3
  25. package/dist/parsing.d.ts +5 -3
  26. package/dist/parsing.js.map +1 -1
  27. package/dist/parsing.mjs +2 -2
  28. package/dist/{plan-utils-pE4TBwxl.d.mts → plan-utils-BAvW3hvl.d.mts} +212 -43
  29. package/dist/{plan-utils-BFaPo-IT.d.ts → plan-utils-BMyEiDKv.d.ts} +212 -43
  30. package/dist/plan-utils.d.mts +5 -4
  31. package/dist/plan-utils.d.ts +5 -4
  32. package/dist/plan-utils.js +351 -64
  33. package/dist/plan-utils.js.map +1 -1
  34. package/dist/plan-utils.mjs +11 -5
  35. package/dist/testing.d.mts +54 -4
  36. package/dist/testing.d.ts +54 -4
  37. package/dist/testing.js +93 -2
  38. package/dist/testing.js.map +1 -1
  39. package/dist/testing.mjs +91 -2
  40. package/dist/testing.mjs.map +1 -1
  41. package/package.json +2 -1
  42. package/skills/grilling/SKILL.md +6 -16
  43. package/skills/improve-codebase-architecture/SKILL.md +1 -1
  44. package/dist/ApprovalPolicy-BVhGdECT.d.mts +0 -79
  45. package/dist/ApprovalPolicy-BVhGdECT.d.ts +0 -79
  46. package/dist/ITerminalRunner-BV9Rd2o9.d.ts +0 -563
  47. package/dist/ITerminalRunner-C77ZNZS9.d.mts +0 -563
  48. package/dist/Task-Vl5Zq_D-.d.mts +0 -825
  49. package/dist/Task-Vl5Zq_D-.d.ts +0 -825
  50. package/dist/chunk-HD2FWPRV.mjs.map +0 -1
  51. package/dist/chunk-KLN7ELXO.mjs.map +0 -1
  52. package/dist/chunk-T2S5O36I.mjs.map +0 -1
  53. /package/dist/{chunk-UUBGVCGJ.mjs.map → chunk-JBEFAJ2W.mjs.map} +0 -0
@@ -1,563 +0,0 @@
1
- import { I as IApproval, a as ApprovalMode } from './ApprovalPolicy-BVhGdECT.js';
2
- import { H as RunnerId } from './Task-Vl5Zq_D-.js';
3
-
4
- interface ToolOutcome {
5
- success: boolean;
6
- output: string;
7
- truncated: boolean;
8
- }
9
- interface ReadFileOpts {
10
- maxBytes?: number;
11
- offset?: number;
12
- limit?: number;
13
- }
14
- /**
15
- * `content` returns matching lines, `files` only the paths that matched, and
16
- * `count` a per-file tally. Cheap models otherwise grep and then read whole
17
- * files to answer "which files touch this", burning rounds against the budget.
18
- */
19
- type GrepOutputMode = 'content' | 'files' | 'count';
20
- interface GrepOptions {
21
- /** File glob filter, e.g. `*.ts`. */
22
- include?: string;
23
- /** Search root. Relative to the workspace unless approved as external. */
24
- path?: string;
25
- outputMode?: GrepOutputMode;
26
- /** Lines of context around each match (`content` mode only). */
27
- contextBefore?: number;
28
- contextAfter?: number;
29
- /** Treat the pattern as a literal string rather than a regex. */
30
- literal?: boolean;
31
- caseInsensitive?: boolean;
32
- /** Global cap on returned rows. Defaults to {@link GREP_DEFAULT_HEAD_LIMIT}. */
33
- headLimit?: number;
34
- }
35
- interface GlobOptions {
36
- /** Search root. Relative to the workspace unless approved as external. */
37
- path?: string;
38
- headLimit?: number;
39
- }
40
- interface FindSymbolOptions {
41
- /** Language id or file extension, e.g. `typescript` or `.go`. Narrows the keyword set. */
42
- language?: string;
43
- /** Search root. Relative to the workspace unless approved as external. */
44
- path?: string;
45
- }
46
- /** Global row cap for grep. A per-file cap is not a budget — see PoolFileSystem. */
47
- declare const GREP_DEFAULT_HEAD_LIMIT = 100;
48
- /**
49
- * Directories that are never interesting to a planner and would otherwise eat
50
- * the result budget. Applied by every search entry point, not just `glob` —
51
- * `dist/` and `.ordewell/` are frequently not gitignored.
52
- */
53
- declare const SEARCH_EXCLUSIONS: string[];
54
- interface IFileSystem {
55
- readFile(path: string, opts?: ReadFileOpts): Promise<ToolOutcome>;
56
- readFiles(paths: string[]): Promise<ToolOutcome>;
57
- glob(pattern: string, opts?: GlobOptions): Promise<ToolOutcome>;
58
- grep(pattern: string, opts?: GrepOptions): Promise<ToolOutcome>;
59
- listDir(path: string, depth?: number): Promise<ToolOutcome>;
60
- /**
61
- * `signal` stops the planning turn this command belongs to: adapters kill
62
- * the spawned child rather than let it run out its own timeout. The other
63
- * tools here are short enough that the loop's between-call abort check is
64
- * indistinguishable from cancelling them mid-flight; a `bash` call is not.
65
- */
66
- bash(command: string, signal?: AbortSignal): Promise<ToolOutcome>;
67
- /** Definition-first lookup for one symbol. See `symbolPatterns.ts`. */
68
- findSymbol(symbol: string, opts?: FindSymbolOptions): Promise<ToolOutcome>;
69
- getWorkspaceRoot(): string;
70
- /**
71
- * Inject the human-approval channel for out-of-envelope access. Optional so
72
- * test doubles stay small; every adapter extending `BaseFileSystem` has it.
73
- */
74
- setApproval?(approval: IApproval): void;
75
- }
76
-
77
- interface CatalogModel {
78
- id: string;
79
- name: string;
80
- description: string;
81
- pricing: {
82
- prompt: string;
83
- completion: string;
84
- };
85
- contextLength: number;
86
- }
87
- declare class ModelCatalog {
88
- static fetchModels(apiKey: string, baseUrl?: string, fetchImpl?: typeof fetch): Promise<CatalogModel[]>;
89
- /**
90
- * Delete the on-disk catalog cache for a base URL so the next fetch re-runs.
91
- * Used by the resolver's `invalidate()` in production (no injected fetch);
92
- * best-effort — a missing file or unreadable dir is a no-op.
93
- */
94
- static clearCache(baseUrl?: string): void;
95
- private static readCache;
96
- private static writeCache;
97
- }
98
-
99
- interface ModelShortcut {
100
- label: string;
101
- id: string;
102
- provider: string;
103
- description: string;
104
- pricing?: string;
105
- }
106
- declare const ORCHESTRATOR_SHORTCUTS: ModelShortcut[];
107
- declare function resolveModelShortcut(input: string, shortcuts: ModelShortcut[]): string | null;
108
- /**
109
- * Resolves a value to a model id ONLY when it is in the supplied catalog
110
- * option list — either directly or via a shortcut label. Free-typed, unknown,
111
- * or not-currently-available values return null, so callers never store an id
112
- * the user couldn't have selected from the list. Keeps model-setting list-only.
113
- */
114
- declare function knownModelId(value: string, optionIds: string[], shortcuts: ModelShortcut[]): string | null;
115
-
116
- type ProviderModelLists = Record<string, string[]>;
117
- interface OrchestratorOption {
118
- id: string;
119
- label: string;
120
- provider: string;
121
- apiProvider: AiProvider;
122
- description?: string;
123
- pricing?: string;
124
- /** The model's context window when the catalog reports one (#49). */
125
- contextWindow?: number;
126
- }
127
-
128
- interface FetchAllProviderModelsOptions {
129
- apiKeys: Record<string, string>;
130
- baseUrls: Record<string, string>;
131
- fetchImpl?: typeof fetch;
132
- }
133
- type AllProviderModels = Record<string, CatalogModel[]>;
134
- /**
135
- * Result of a picker-catalog fetch fan-out: the per-provider model lists plus
136
- * the per-provider failures. `errors` is keyed by provider id and holds the
137
- * failure message for any provider whose catalog fetch rejected — the seam the
138
- * surfaces (CLI, VS Code) use to flag "this configured provider didn't work"
139
- * rather than silently showing a short list.
140
- */
141
- interface ProviderModelsResult {
142
- models: AllProviderModels;
143
- errors: Record<string, string>;
144
- }
145
- /** The provider config fields the discovery fan-out needs. */
146
- interface ProviderCredentialSource {
147
- getProviderApiKey(provider: AiProvider): string;
148
- getProviderBaseUrl(provider: AiProvider): string;
149
- openaiCompatibleBaseUrl: string;
150
- }
151
- /**
152
- * Collect the API keys and base URLs the picker fan-out should probe, applying
153
- * the single "configured" policy shared by every surface (CLI + VS Code):
154
- * - a preset is discovered only when it has an API key (OpenRouter included —
155
- * its public catalog is not probed keyless, matching the product rule that
156
- * only key-configured providers appear);
157
- * - `openai_compatible` is discovered only when an explicit endpoint is set
158
- * (keyless local servers like ollama / LM Studio).
159
- * Base URLs are handed through only for providers that pass the gate, so the
160
- * fan-out never touches an unconfigured third-party endpoint.
161
- */
162
- declare function collectProviderCredentials(config: ProviderCredentialSource): {
163
- apiKeys: Record<string, string>;
164
- baseUrls: Record<string, string>;
165
- };
166
- declare function fetchAllProviderModels(opts: FetchAllProviderModelsOptions): Promise<ProviderModelsResult>;
167
- declare function resolveProvider(modelId: string, providerModelLists: Record<string, string[]>): AiProvider | null;
168
- declare function toOrchestratorOptions(providerModels: AllProviderModels, shortcuts: ModelShortcut[]): OrchestratorOption[];
169
-
170
- /**
171
- * Who plans. Mostly LLM vendors reached over HTTP; the last three are *harness
172
- * planners* (ADR-0009) — a coding agent CLI already installed on the machine,
173
- * driven as the planner over its own programmatic transport and authenticated
174
- * by the subscription the user already holds. They are runners in the provider
175
- * axis, deliberately: "what plans for me?" is one question, and it belongs in
176
- * one setting. `isCliProvider` is the single guard that tells the two kinds
177
- * apart.
178
- */
179
- type AiProvider = 'google' | 'openrouter' | 'openai_compatible' | 'openai' | 'xai' | 'groq' | 'deepseek' | 'together' | 'mistral' | 'anthropic' | 'fireworks' | 'perplexity' | 'zhipu' | 'kimi' | 'cerebras' | 'deepinfra' | 'doubao' | 'qwen' | 'hunyuan' | 'baichuan' | 'minimax' | 'yi' | 'stepfun' | 'siliconflow' | 'cohere' | 'novita' | 'claude-code' | 'codex' | 'opencode';
180
- interface IConfig {
181
- aiProvider: AiProvider;
182
- apiKey: string;
183
- planningModel: string;
184
- enabledRunners: string[];
185
- maxParallelSessions: number;
186
- researchEnabled: boolean;
187
- researchMaxSteps: number;
188
- researchMaxFileSize: number;
189
- openAiBaseUrl: string;
190
- openAiApiKey: string;
191
- /** Provider keys + base URL the ModelResolver uses to fetch the picker catalogs. */
192
- openrouterKey: string;
193
- geminiKey: string;
194
- geminiBaseUrl?: string;
195
- /** Base URL + API key for a user-provided OpenAI-compatible endpoint (ollama, vLLM, LM Studio, etc.). */
196
- openaiCompatibleBaseUrl: string;
197
- openaiCompatibleApiKey: string;
198
- orchestratorModel: string;
199
- geminiModel: string;
200
- /** Model for research subagents (issue #34); defaults to the (cheap) planner model. */
201
- researchSubagentModel: string;
202
- /**
203
- * Thinking effort / model variant for a harness planner (ADR-0009), chosen
204
- * from the agent's own discovered variants. Separate from the per-task
205
- * efforts the plan carries — this one is the planner's own dial.
206
- */
207
- plannerThinkingEffort?: string;
208
- planMapEnabled: boolean;
209
- autonomousMode: boolean;
210
- /**
211
- * Run each AI task in its own git worktree and integrate the results on a
212
- * per-run branch (ADR-0013). Non-git workspaces fall back to the shared
213
- * workspace root regardless of this flag.
214
- */
215
- worktreeIsolation: boolean;
216
- /**
217
- * Shell command run in a fresh task worktree instead of symlinking ignored
218
- * artifacts from the main worktree — for repos where sharing `node_modules`
219
- * or a virtualenv is wrong.
220
- */
221
- worktreeSetupCommand?: string;
222
- /**
223
- * Repositories of the repo group listed by hand, relative to the workspace
224
- * (ADR-0014). When non-empty the group is exactly these, replacing the
225
- * repositories auto-detected directly inside the folder; needed for ones
226
- * deeper than that, which are never auto-detected.
227
- */
228
- workspaceRepos: string[];
229
- /**
230
- * Extra paths or globs, relative to each repo root, linked from the real repo
231
- * into its task worktree where they exist — gitignored local state such as
232
- * `*.tfstate` that a task must use, not a copy of.
233
- */
234
- worktreeLinks: string[];
235
- /**
236
- * How many conflict repairs one task may go through before its conflict is
237
- * left for a person (ADR-0015); 0 turns repair off.
238
- */
239
- conflictRepairAttempts: number;
240
- /**
241
- * What to do when planner research reaches outside its default envelope — an
242
- * out-of-workspace path, or a shell command beyond the auto-allowed read-only
243
- * set. `ask` prompts the user (and denies where no surface can prompt, such as
244
- * headless runs); `allow` and `deny` skip the prompt entirely.
245
- */
246
- approvalMode: ApprovalMode;
247
- /** Scopes granted up front, so CI and power users never see a prompt. Trailing `*` matches by prefix. */
248
- approvalPreApproved: string[];
249
- /** Get the base URL for an OpenAI-compatible provider. */
250
- getProviderBaseUrl(provider: AiProvider): string;
251
- /** Get the API key for a provider. */
252
- getProviderApiKey(provider: AiProvider): string;
253
- /**
254
- * Push the canonical provider routing lists in (sole producer: ModelResolver).
255
- * Config consumes them when resolving a chosen model id to its serving API.
256
- */
257
- setProviderModelLists(lists: ProviderModelLists): void;
258
- }
259
- declare function enabledRunners(cfg: IConfig): RunnerId[];
260
-
261
- interface RunnerPluginManifest {
262
- name: string;
263
- displayName: string;
264
- description: string;
265
- version: string;
266
- author?: string;
267
- homepage?: string;
268
- runner: PluginRunnerDef;
269
- features: PluginFeatures;
270
- modelDiscovery: PluginModelDiscovery;
271
- contextFile?: string;
272
- contextFileAltPath?: string;
273
- modes?: PluginMode[];
274
- }
275
- interface PluginRunnerDef {
276
- command: string;
277
- argsTemplate: string[];
278
- promptInArgs: boolean;
279
- env?: Record<string, string>;
280
- /** When true, the runner requires a PTY. HeadlessRunner wraps with `script` to allocate one. */
281
- requiresTty?: boolean;
282
- /**
283
- * True when this runner's interactive prompt flag (e.g. opencode's
284
- * `--prompt`) only pre-fills its TUI's composer instead of running it, so a
285
- * surface driving that TUI unattended must send an explicit Enter after
286
- * launch. Only takes effect while the resolved invocation is interactive —
287
- * see `RunnerInvocation.submitPromptKey`.
288
- */
289
- submitPromptKey?: boolean;
290
- /**
291
- * Screens the agent can stop on before starting the task, waiting for a
292
- * human — a folder-trust or permission-mode confirmation. Ordewell never
293
- * answers one; seeing it, the task's user is told where to.
294
- */
295
- blockingPrompts?: BlockingPrompt[];
296
- }
297
- interface BlockingPrompt {
298
- /** Text the prompt shows; matched ignoring case and whitespace. */
299
- phrase: string;
300
- /** Completes "<runner> is asking …", e.g. "whether to trust this folder". */
301
- asks: string;
302
- }
303
- interface PluginFeatures {
304
- modelSelection: boolean;
305
- thinkingEffort: boolean;
306
- planMode: boolean;
307
- planModeFlag: string;
308
- buildModeFlag?: string;
309
- /** Flag appended when headless mode is on, so the agent never prompts for permission (e.g. Claude's --dangerously-skip-permissions). */
310
- headlessFlag?: string;
311
- thinkingFlag?: string;
312
- thinkingValueEnabled?: string;
313
- thinkingValueDisabled?: string;
314
- thinkingValueAdaptive?: string;
315
- /** Maps mode IDs to the CLI --permission-mode value. Used by {{feature:permissionModeVal}}. */
316
- permissionModeValues?: Record<string, string>;
317
- }
318
- type PluginParser = 'claude-help' | 'opencode-models' | 'opencode-models-verbose' | 'anthropic-models' | 'line-by-line' | 'json' | 'json-table';
319
- interface DiscoveryCommand {
320
- command: string;
321
- args: string[];
322
- parser?: PluginParser;
323
- }
324
- type ApiAuthMethod = {
325
- type: 'env';
326
- varName: string;
327
- header: string;
328
- prefix?: string;
329
- } | {
330
- type: 'file';
331
- path: string;
332
- jsonPath: string;
333
- header: string;
334
- prefix?: string;
335
- };
336
- interface ApiDiscoveryConfig {
337
- url: string;
338
- headers?: Record<string, string>;
339
- auth: ApiAuthMethod[];
340
- parser: PluginParser;
341
- }
342
- interface PluginModelDiscovery {
343
- method: 'command' | 'hardcoded';
344
- command?: string;
345
- args?: string[];
346
- parser?: PluginParser;
347
- jsonPath?: string;
348
- /**
349
- * Stdio JSON-RPC discovery (Codex `app-server`): spawn the command, send
350
- * `initialize` then `model/list`, and read the catalog from the response.
351
- * Tried BEFORE apiDiscovery and command discovery. When the call fails,
352
- * `cacheFile` (the runner's own on-disk catalog cache, `~` expanded) is
353
- * read before falling through to the remaining discovery methods.
354
- */
355
- appServer?: {
356
- command: string;
357
- args: string[];
358
- cacheFile?: string;
359
- };
360
- /**
361
- * Optional last-resort list for user plugins whose CLI cannot enumerate
362
- * models. Used only when command discovery fails entirely or the CLI is
363
- * unavailable. Built-in manifests must NOT use this: anything listed here is
364
- * shown to the user as available even when it isn't.
365
- */
366
- fallbackModels?: {
367
- modelId: string;
368
- modelLabel: string;
369
- }[];
370
- /**
371
- * Stable `--model` aliases that the runner's CLI always accepts but its help
372
- * text may omit (e.g. Claude's 'haiku'). Merged into successful discovery
373
- * results to fill gaps — discovered models take precedence, missing aliases
374
- * are appended — and used as the last resort when discovery fails entirely.
375
- * Unlike `fallbackModels`, entries must be stable CLI-accepted aliases
376
- * (contracts that always resolve), not arbitrary model IDs.
377
- */
378
- canonicalAliases?: {
379
- modelId: string;
380
- modelLabel: string;
381
- }[];
382
- /**
383
- * HTTP API discovery — tried BEFORE command discovery. When the runner's CLI
384
- * has no model-listing subcommand (Claude Code), an API endpoint can serve as
385
- * the authoritative source. Auth methods are tried in order; the first that
386
- * yields a token is used. If no auth method yields a token or the request
387
- * fails, discovery falls through to `discoveryCommands` + `canonicalAliases`.
388
- */
389
- apiDiscovery?: ApiDiscoveryConfig;
390
- preferredPatterns?: {
391
- id: string;
392
- label: string;
393
- }[];
394
- variants?: {
395
- id: string;
396
- label: string;
397
- }[];
398
- discoveryCommands?: DiscoveryCommand[];
399
- }
400
- interface PluginMode {
401
- id: string;
402
- label: string;
403
- description: string;
404
- /** CLI value passed to the runner's permission/mode flag. Defaults to id if omitted. */
405
- cliValue?: string;
406
- /** Marks this mode as the runner's most permissive mode — the resolved default when autonomous mode is ON. */
407
- autonomous?: boolean;
408
- /** Marks this mode as the runner's conservative build mode — the resolved default when autonomous mode is OFF. */
409
- safe?: boolean;
410
- }
411
- interface PluginEntry {
412
- manifest: RunnerPluginManifest;
413
- source: 'builtin' | 'user';
414
- installPath?: string;
415
- }
416
- interface ResolveContext {
417
- prompt: string;
418
- model?: string;
419
- thinkingEffort?: string;
420
- /** All variant ids the assigned model offers — lets {{opencodeVariantConfig}} disable the non-chosen ones. */
421
- modelVariants?: string[];
422
- mode: string;
423
- /**
424
- * Autonomy axis: when true, resolve {{if headless}} blocks and the
425
- * {{feature:headless}} token so the agent never stops to ask for permission.
426
- * True for every orchestrated task run — nobody is watching the terminal on
427
- * Ordewell's behalf — independently of the session *shape* below.
428
- */
429
- headless?: boolean;
430
- /**
431
- * Session-shape axis: true when the runner is launched onto a real TTY the
432
- * user can attach to (a tmux window, a VS Code pseudoterminal), so the
433
- * runner's own TUI should come up rather than its non-interactive
434
- * subcommand. Defaults to `!headless` for callers that predate the split.
435
- */
436
- interactive?: boolean;
437
- /** The task's working directory — needed by runners whose autonomy flags name a path. */
438
- cwd?: string;
439
- }
440
- interface RunnerInvocation {
441
- command: string;
442
- args: string[];
443
- env: Record<string, string>;
444
- promptInArgs: boolean;
445
- /** True when a surface running this invocation on a real TTY must send an explicit Enter once the process starts. */
446
- submitPromptKey: boolean;
447
- }
448
- /**
449
- * Persistent storage seam for plugin manifests. The RunnerRegistry delegates
450
- * all filesystem operations to this interface so the plugin lifecycle is
451
- * testable without real I/O.
452
- */
453
- interface IPluginStore {
454
- /** Path to the user plugins directory (~/.ordewell/plugins/). */
455
- getUserPluginsDir(): string;
456
- /** List subdirectory names inside the user plugins directory. */
457
- listUserPluginDirs(): string[];
458
- /** List entry names directly inside a directory. Returns [] when unreadable. */
459
- listDir(dir: string): string[];
460
- /** Read and parse a manifest.json from pluginDir. Returns null on failure. */
461
- loadManifest(pluginDir: string): RunnerPluginManifest | null;
462
- /** Recursively copy sourceDir to destDir. */
463
- copyDir(sourceDir: string, destDir: string): void;
464
- /** Recursively remove a directory. */
465
- removeDir(dir: string): void;
466
- /** Ensure a directory exists (mkdir -p). */
467
- ensureDir(dir: string): void;
468
- /** Write a text file. */
469
- writeFile(filePath: string, content: string): void;
470
- /** Read a UTF-8 text file. Returns null on ENOENT or read error. */
471
- readFile(filePath: string): string | null;
472
- /** True if path exists and is a directory. */
473
- dirExists(path: string): boolean;
474
- /** True if path exists. */
475
- exists(path: string): boolean;
476
- }
477
-
478
- /** True when a name belongs to a built-in runner and is therefore not installable. */
479
- declare function isReservedRunnerName(name: string): boolean;
480
- /** Clone seam: takes a validated URL and a destination, or throws. */
481
- type PluginCloneFn = (url: string, destDir: string) => void;
482
- declare class RunnerRegistry {
483
- private plugins;
484
- private store;
485
- private clone;
486
- constructor(store?: IPluginStore, clone?: PluginCloneFn);
487
- private loadBuiltins;
488
- loadUserPlugins(): void;
489
- get(id: string): PluginEntry | undefined;
490
- getManifest(id: string): RunnerPluginManifest | undefined;
491
- list(): PluginEntry[];
492
- listEnabled(config: IConfig): PluginEntry[];
493
- listEnabledIds(config: IConfig): string[];
494
- isBuiltIn(id: string): boolean;
495
- installFromPath(sourcePath: string): RunnerPluginManifest;
496
- installFromGit(url: string): RunnerPluginManifest;
497
- /**
498
- * The single destination-building step both install routes share: the name is
499
- * constrained to a plain segment and the resolved destination is asserted to
500
- * be inside the plugins directory before anything is copied.
501
- */
502
- private registerInstalled;
503
- remove(name: string): void;
504
- createSkeleton(name: string, outputDir: string): string;
505
- }
506
-
507
- interface ITerminalSession {
508
- id: string;
509
- taskId: string;
510
- onOutput(callback: (text: string) => void): void;
511
- onExit(callback: (code: number) => void): void;
512
- kill(): void;
513
- getOutput(): string;
514
- write(text: string): void;
515
- /**
516
- * True when the session runs the agent as a raw-mode TUI (a real PTY for the
517
- * VS Code terminal, a tmux window). Such a surface submits an input line on
518
- * the Enter keystroke (`\r`), so a synchronized resume token terminated with
519
- * `\n` only types the line and never sends it. A line-oriented piped session
520
- * (`defaultInteractive = false`) leaves this false and accepts `\n`.
521
- */
522
- readonly interactive?: boolean;
523
- /**
524
- * Optional transport-level control channel: PTY resize requests for a session
525
- * whose runner renders a TUI. Absent on transports without a resizable PTY
526
- * (a plain piped subprocess); surfaces must feature-detect before calling.
527
- */
528
- writeControl?(text: string): void;
529
- }
530
-
531
- interface ITerminalRunner {
532
- spawn(opts: {
533
- taskId: string;
534
- runner: string;
535
- prompt: string;
536
- modelId?: string;
537
- thinkingEffort?: string;
538
- modelVariants?: string[];
539
- mode?: string;
540
- headless?: boolean;
541
- cwd: string;
542
- registry?: RunnerRegistry;
543
- /** Task order and title — surfaces use these to label task_started/output events. */
544
- order?: number;
545
- title?: string;
546
- /**
547
- * The owning plan session. Task ids are only unique within one plan, so
548
- * transports that key OS resources by task (tmux windows, log files) need
549
- * this to keep two plans' identically named tasks apart.
550
- */
551
- planSessionId?: string;
552
- /**
553
- * The workspace's own variables (ADR-0016), under the runner's: a
554
- * manifest's env still wins over them.
555
- */
556
- env?: Record<string, string>;
557
- }): Promise<ITerminalSession>;
558
- stop(sessionId: string): void;
559
- stopAll(): void;
560
- activeCount: number;
561
- }
562
-
563
- export { type AiProvider as A, type BlockingPrompt as B, type CatalogModel as C, type DiscoveryCommand as D, isReservedRunnerName as E, type FetchAllProviderModelsOptions as F, GREP_DEFAULT_HEAD_LIMIT as G, knownModelId as H, type IConfig as I, resolveModelShortcut as J, resolveProvider as K, toOrchestratorOptions as L, ModelCatalog as M, ORCHESTRATOR_SHORTCUTS as O, type PluginCloneFn as P, type ReadFileOpts as R, SEARCH_EXCLUSIONS as S, type ToolOutcome as T, type AllProviderModels as a, type FindSymbolOptions as b, type GlobOptions as c, type GrepOptions as d, type GrepOutputMode as e, type IFileSystem as f, type IPluginStore as g, type ITerminalRunner as h, type ITerminalSession as i, type ModelShortcut as j, type OrchestratorOption as k, type PluginEntry as l, type PluginFeatures as m, type PluginMode as n, type PluginModelDiscovery as o, type PluginRunnerDef as p, type ProviderCredentialSource as q, type ProviderModelLists as r, type ProviderModelsResult as s, type ResolveContext as t, type RunnerInvocation as u, type RunnerPluginManifest as v, RunnerRegistry as w, collectProviderCredentials as x, enabledRunners as y, fetchAllProviderModels as z };