@ordewell/core 0.5.4 → 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 (56) 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-Dkig8ghQ.d.ts → ModeResolver--16lh7dS.d.mts} +1 -1
  4. package/dist/{ModeResolver-DVJ7HV3k.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-JVMDEHRQ.mjs → chunk-EDGUFCIR.mjs} +77 -37
  10. package/dist/chunk-EDGUFCIR.mjs.map +1 -0
  11. package/dist/{chunk-XWOUIA6A.mjs → chunk-JBEFAJ2W.mjs} +2 -2
  12. package/dist/chunk-ROVYWEBI.mjs +2115 -0
  13. package/dist/chunk-ROVYWEBI.mjs.map +1 -0
  14. package/dist/index.d.mts +1647 -758
  15. package/dist/index.d.ts +1647 -758
  16. package/dist/index.js +9301 -4857
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +6222 -2968
  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-DRp4dPC0.d.mts → parsing-DPEpAszP.d.mts} +11 -3
  23. package/dist/{parsing-CF_grC29.d.ts → parsing-EcmCsF1y.d.ts} +11 -3
  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-BAvW3hvl.d.mts +877 -0
  29. package/dist/plan-utils-BMyEiDKv.d.ts +877 -0
  30. package/dist/plan-utils.d.mts +5 -4
  31. package/dist/plan-utils.d.ts +5 -4
  32. package/dist/plan-utils.js +956 -8
  33. package/dist/plan-utils.js.map +1 -1
  34. package/dist/plan-utils.mjs +47 -7
  35. package/dist/testing.d.mts +57 -5
  36. package/dist/testing.d.ts +57 -5
  37. package/dist/testing.js +96 -2
  38. package/dist/testing.js.map +1 -1
  39. package/dist/testing.mjs +94 -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-Bd-vAJnw.d.ts +0 -561
  47. package/dist/ITerminalRunner-ByeoLF57.d.mts +0 -561
  48. package/dist/Task-BxQkPlXO.d.mts +0 -664
  49. package/dist/Task-BxQkPlXO.d.ts +0 -664
  50. package/dist/chunk-GWPIYDQW.mjs +0 -945
  51. package/dist/chunk-GWPIYDQW.mjs.map +0 -1
  52. package/dist/chunk-JVMDEHRQ.mjs.map +0 -1
  53. package/dist/chunk-T2S5O36I.mjs.map +0 -1
  54. package/dist/plan-utils-CkNbqAmS.d.ts +0 -329
  55. package/dist/plan-utils-CtB3_Ovf.d.mts +0 -329
  56. /package/dist/{chunk-XWOUIA6A.mjs.map → chunk-JBEFAJ2W.mjs.map} +0 -0
@@ -1,561 +0,0 @@
1
- import { I as IApproval, a as ApprovalMode } from './ApprovalPolicy-BVhGdECT.mjs';
2
- import { F as RunnerId } from './Task-BxQkPlXO.mjs';
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
- }
125
-
126
- interface FetchAllProviderModelsOptions {
127
- apiKeys: Record<string, string>;
128
- baseUrls: Record<string, string>;
129
- fetchImpl?: typeof fetch;
130
- }
131
- type AllProviderModels = Record<string, CatalogModel[]>;
132
- /**
133
- * Result of a picker-catalog fetch fan-out: the per-provider model lists plus
134
- * the per-provider failures. `errors` is keyed by provider id and holds the
135
- * failure message for any provider whose catalog fetch rejected — the seam the
136
- * surfaces (CLI, VS Code) use to flag "this configured provider didn't work"
137
- * rather than silently showing a short list.
138
- */
139
- interface ProviderModelsResult {
140
- models: AllProviderModels;
141
- errors: Record<string, string>;
142
- }
143
- /** The provider config fields the discovery fan-out needs. */
144
- interface ProviderCredentialSource {
145
- getProviderApiKey(provider: AiProvider): string;
146
- getProviderBaseUrl(provider: AiProvider): string;
147
- openaiCompatibleBaseUrl: string;
148
- }
149
- /**
150
- * Collect the API keys and base URLs the picker fan-out should probe, applying
151
- * the single "configured" policy shared by every surface (CLI + VS Code):
152
- * - a preset is discovered only when it has an API key (OpenRouter included —
153
- * its public catalog is not probed keyless, matching the product rule that
154
- * only key-configured providers appear);
155
- * - `openai_compatible` is discovered only when an explicit endpoint is set
156
- * (keyless local servers like ollama / LM Studio).
157
- * Base URLs are handed through only for providers that pass the gate, so the
158
- * fan-out never touches an unconfigured third-party endpoint.
159
- */
160
- declare function collectProviderCredentials(config: ProviderCredentialSource): {
161
- apiKeys: Record<string, string>;
162
- baseUrls: Record<string, string>;
163
- };
164
- declare function fetchAllProviderModels(opts: FetchAllProviderModelsOptions): Promise<ProviderModelsResult>;
165
- declare function resolveProvider(modelId: string, providerModelLists: Record<string, string[]>): AiProvider | null;
166
- declare function toOrchestratorOptions(providerModels: AllProviderModels, shortcuts: ModelShortcut[]): OrchestratorOption[];
167
-
168
- /**
169
- * Who plans. Mostly LLM vendors reached over HTTP; the last three are *harness
170
- * planners* (ADR-0009) — a coding agent CLI already installed on the machine,
171
- * driven as the planner over its own programmatic transport and authenticated
172
- * by the subscription the user already holds. They are runners in the provider
173
- * axis, deliberately: "what plans for me?" is one question, and it belongs in
174
- * one setting. `isCliProvider` is the single guard that tells the two kinds
175
- * apart.
176
- */
177
- 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';
178
- interface IConfig {
179
- aiProvider: AiProvider;
180
- apiKey: string;
181
- planningModel: string;
182
- enabledRunners: string[];
183
- maxParallelSessions: number;
184
- researchEnabled: boolean;
185
- researchMaxSteps: number;
186
- researchMaxFileSize: number;
187
- openAiBaseUrl: string;
188
- openAiApiKey: string;
189
- /** Provider keys + base URL the ModelResolver uses to fetch the picker catalogs. */
190
- openrouterKey: string;
191
- geminiKey: string;
192
- geminiBaseUrl?: string;
193
- /** Base URL + API key for a user-provided OpenAI-compatible endpoint (ollama, vLLM, LM Studio, etc.). */
194
- openaiCompatibleBaseUrl: string;
195
- openaiCompatibleApiKey: string;
196
- orchestratorModel: string;
197
- geminiModel: string;
198
- /** Model for research subagents (issue #34); defaults to the (cheap) planner model. */
199
- researchSubagentModel: string;
200
- /**
201
- * Thinking effort / model variant for a harness planner (ADR-0009), chosen
202
- * from the agent's own discovered variants. Separate from the per-task
203
- * efforts the plan carries — this one is the planner's own dial.
204
- */
205
- plannerThinkingEffort?: string;
206
- planMapEnabled: boolean;
207
- autonomousMode: boolean;
208
- /**
209
- * Run each AI task in its own git worktree and integrate the results on a
210
- * per-run branch (ADR-0013). Non-git workspaces fall back to the shared
211
- * workspace root regardless of this flag.
212
- */
213
- worktreeIsolation: boolean;
214
- /**
215
- * Shell command run in a fresh task worktree instead of symlinking ignored
216
- * artifacts from the main worktree — for repos where sharing `node_modules`
217
- * or a virtualenv is wrong.
218
- */
219
- worktreeSetupCommand?: string;
220
- /**
221
- * Repositories of the repo group listed by hand, relative to the workspace
222
- * (ADR-0014). When non-empty the group is exactly these, replacing the
223
- * repositories auto-detected directly inside the folder; needed for ones
224
- * deeper than that, which are never auto-detected.
225
- */
226
- workspaceRepos: string[];
227
- /**
228
- * Extra paths or globs, relative to each repo root, linked from the real repo
229
- * into its task worktree where they exist — gitignored local state such as
230
- * `*.tfstate` that a task must use, not a copy of.
231
- */
232
- worktreeLinks: string[];
233
- /**
234
- * How many conflict repairs one task may go through before its conflict is
235
- * left for a person (ADR-0015); 0 turns repair off.
236
- */
237
- conflictRepairAttempts: number;
238
- /**
239
- * What to do when planner research reaches outside its default envelope — an
240
- * out-of-workspace path, or a shell command beyond the auto-allowed read-only
241
- * set. `ask` prompts the user (and denies where no surface can prompt, such as
242
- * headless runs); `allow` and `deny` skip the prompt entirely.
243
- */
244
- approvalMode: ApprovalMode;
245
- /** Scopes granted up front, so CI and power users never see a prompt. Trailing `*` matches by prefix. */
246
- approvalPreApproved: string[];
247
- /** Get the base URL for an OpenAI-compatible provider. */
248
- getProviderBaseUrl(provider: AiProvider): string;
249
- /** Get the API key for a provider. */
250
- getProviderApiKey(provider: AiProvider): string;
251
- /**
252
- * Push the canonical provider routing lists in (sole producer: ModelResolver).
253
- * Config consumes them when resolving a chosen model id to its serving API.
254
- */
255
- setProviderModelLists(lists: ProviderModelLists): void;
256
- }
257
- declare function enabledRunners(cfg: IConfig): RunnerId[];
258
-
259
- interface RunnerPluginManifest {
260
- name: string;
261
- displayName: string;
262
- description: string;
263
- version: string;
264
- author?: string;
265
- homepage?: string;
266
- runner: PluginRunnerDef;
267
- features: PluginFeatures;
268
- modelDiscovery: PluginModelDiscovery;
269
- contextFile?: string;
270
- contextFileAltPath?: string;
271
- modes?: PluginMode[];
272
- }
273
- interface PluginRunnerDef {
274
- command: string;
275
- argsTemplate: string[];
276
- promptInArgs: boolean;
277
- env?: Record<string, string>;
278
- /** When true, the runner requires a PTY. HeadlessRunner wraps with `script` to allocate one. */
279
- requiresTty?: boolean;
280
- /**
281
- * True when this runner's interactive prompt flag (e.g. opencode's
282
- * `--prompt`) only pre-fills its TUI's composer instead of running it, so a
283
- * surface driving that TUI unattended must send an explicit Enter after
284
- * launch. Only takes effect while the resolved invocation is interactive —
285
- * see `RunnerInvocation.submitPromptKey`.
286
- */
287
- submitPromptKey?: boolean;
288
- /**
289
- * Screens the agent can stop on before starting the task, waiting for a
290
- * human — a folder-trust or permission-mode confirmation. Ordewell never
291
- * answers one; seeing it, the task's user is told where to.
292
- */
293
- blockingPrompts?: BlockingPrompt[];
294
- }
295
- interface BlockingPrompt {
296
- /** Text the prompt shows; matched ignoring case and whitespace. */
297
- phrase: string;
298
- /** Completes "<runner> is asking …", e.g. "whether to trust this folder". */
299
- asks: string;
300
- }
301
- interface PluginFeatures {
302
- modelSelection: boolean;
303
- thinkingEffort: boolean;
304
- planMode: boolean;
305
- planModeFlag: string;
306
- buildModeFlag?: string;
307
- /** Flag appended when headless mode is on, so the agent never prompts for permission (e.g. Claude's --dangerously-skip-permissions). */
308
- headlessFlag?: string;
309
- thinkingFlag?: string;
310
- thinkingValueEnabled?: string;
311
- thinkingValueDisabled?: string;
312
- thinkingValueAdaptive?: string;
313
- /** Maps mode IDs to the CLI --permission-mode value. Used by {{feature:permissionModeVal}}. */
314
- permissionModeValues?: Record<string, string>;
315
- }
316
- type PluginParser = 'claude-help' | 'opencode-models' | 'opencode-models-verbose' | 'anthropic-models' | 'line-by-line' | 'json' | 'json-table';
317
- interface DiscoveryCommand {
318
- command: string;
319
- args: string[];
320
- parser?: PluginParser;
321
- }
322
- type ApiAuthMethod = {
323
- type: 'env';
324
- varName: string;
325
- header: string;
326
- prefix?: string;
327
- } | {
328
- type: 'file';
329
- path: string;
330
- jsonPath: string;
331
- header: string;
332
- prefix?: string;
333
- };
334
- interface ApiDiscoveryConfig {
335
- url: string;
336
- headers?: Record<string, string>;
337
- auth: ApiAuthMethod[];
338
- parser: PluginParser;
339
- }
340
- interface PluginModelDiscovery {
341
- method: 'command' | 'hardcoded';
342
- command?: string;
343
- args?: string[];
344
- parser?: PluginParser;
345
- jsonPath?: string;
346
- /**
347
- * Stdio JSON-RPC discovery (Codex `app-server`): spawn the command, send
348
- * `initialize` then `model/list`, and read the catalog from the response.
349
- * Tried BEFORE apiDiscovery and command discovery. When the call fails,
350
- * `cacheFile` (the runner's own on-disk catalog cache, `~` expanded) is
351
- * read before falling through to the remaining discovery methods.
352
- */
353
- appServer?: {
354
- command: string;
355
- args: string[];
356
- cacheFile?: string;
357
- };
358
- /**
359
- * Optional last-resort list for user plugins whose CLI cannot enumerate
360
- * models. Used only when command discovery fails entirely or the CLI is
361
- * unavailable. Built-in manifests must NOT use this: anything listed here is
362
- * shown to the user as available even when it isn't.
363
- */
364
- fallbackModels?: {
365
- modelId: string;
366
- modelLabel: string;
367
- }[];
368
- /**
369
- * Stable `--model` aliases that the runner's CLI always accepts but its help
370
- * text may omit (e.g. Claude's 'haiku'). Merged into successful discovery
371
- * results to fill gaps — discovered models take precedence, missing aliases
372
- * are appended — and used as the last resort when discovery fails entirely.
373
- * Unlike `fallbackModels`, entries must be stable CLI-accepted aliases
374
- * (contracts that always resolve), not arbitrary model IDs.
375
- */
376
- canonicalAliases?: {
377
- modelId: string;
378
- modelLabel: string;
379
- }[];
380
- /**
381
- * HTTP API discovery — tried BEFORE command discovery. When the runner's CLI
382
- * has no model-listing subcommand (Claude Code), an API endpoint can serve as
383
- * the authoritative source. Auth methods are tried in order; the first that
384
- * yields a token is used. If no auth method yields a token or the request
385
- * fails, discovery falls through to `discoveryCommands` + `canonicalAliases`.
386
- */
387
- apiDiscovery?: ApiDiscoveryConfig;
388
- preferredPatterns?: {
389
- id: string;
390
- label: string;
391
- }[];
392
- variants?: {
393
- id: string;
394
- label: string;
395
- }[];
396
- discoveryCommands?: DiscoveryCommand[];
397
- }
398
- interface PluginMode {
399
- id: string;
400
- label: string;
401
- description: string;
402
- /** CLI value passed to the runner's permission/mode flag. Defaults to id if omitted. */
403
- cliValue?: string;
404
- /** Marks this mode as the runner's most permissive mode — the resolved default when autonomous mode is ON. */
405
- autonomous?: boolean;
406
- /** Marks this mode as the runner's conservative build mode — the resolved default when autonomous mode is OFF. */
407
- safe?: boolean;
408
- }
409
- interface PluginEntry {
410
- manifest: RunnerPluginManifest;
411
- source: 'builtin' | 'user';
412
- installPath?: string;
413
- }
414
- interface ResolveContext {
415
- prompt: string;
416
- model?: string;
417
- thinkingEffort?: string;
418
- /** All variant ids the assigned model offers — lets {{opencodeVariantConfig}} disable the non-chosen ones. */
419
- modelVariants?: string[];
420
- mode: string;
421
- /**
422
- * Autonomy axis: when true, resolve {{if headless}} blocks and the
423
- * {{feature:headless}} token so the agent never stops to ask for permission.
424
- * True for every orchestrated task run — nobody is watching the terminal on
425
- * Ordewell's behalf — independently of the session *shape* below.
426
- */
427
- headless?: boolean;
428
- /**
429
- * Session-shape axis: true when the runner is launched onto a real TTY the
430
- * user can attach to (a tmux window, a VS Code pseudoterminal), so the
431
- * runner's own TUI should come up rather than its non-interactive
432
- * subcommand. Defaults to `!headless` for callers that predate the split.
433
- */
434
- interactive?: boolean;
435
- /** The task's working directory — needed by runners whose autonomy flags name a path. */
436
- cwd?: string;
437
- }
438
- interface RunnerInvocation {
439
- command: string;
440
- args: string[];
441
- env: Record<string, string>;
442
- promptInArgs: boolean;
443
- /** True when a surface running this invocation on a real TTY must send an explicit Enter once the process starts. */
444
- submitPromptKey: boolean;
445
- }
446
- /**
447
- * Persistent storage seam for plugin manifests. The RunnerRegistry delegates
448
- * all filesystem operations to this interface so the plugin lifecycle is
449
- * testable without real I/O.
450
- */
451
- interface IPluginStore {
452
- /** Path to the user plugins directory (~/.ordewell/plugins/). */
453
- getUserPluginsDir(): string;
454
- /** List subdirectory names inside the user plugins directory. */
455
- listUserPluginDirs(): string[];
456
- /** List entry names directly inside a directory. Returns [] when unreadable. */
457
- listDir(dir: string): string[];
458
- /** Read and parse a manifest.json from pluginDir. Returns null on failure. */
459
- loadManifest(pluginDir: string): RunnerPluginManifest | null;
460
- /** Recursively copy sourceDir to destDir. */
461
- copyDir(sourceDir: string, destDir: string): void;
462
- /** Recursively remove a directory. */
463
- removeDir(dir: string): void;
464
- /** Ensure a directory exists (mkdir -p). */
465
- ensureDir(dir: string): void;
466
- /** Write a text file. */
467
- writeFile(filePath: string, content: string): void;
468
- /** Read a UTF-8 text file. Returns null on ENOENT or read error. */
469
- readFile(filePath: string): string | null;
470
- /** True if path exists and is a directory. */
471
- dirExists(path: string): boolean;
472
- /** True if path exists. */
473
- exists(path: string): boolean;
474
- }
475
-
476
- /** True when a name belongs to a built-in runner and is therefore not installable. */
477
- declare function isReservedRunnerName(name: string): boolean;
478
- /** Clone seam: takes a validated URL and a destination, or throws. */
479
- type PluginCloneFn = (url: string, destDir: string) => void;
480
- declare class RunnerRegistry {
481
- private plugins;
482
- private store;
483
- private clone;
484
- constructor(store?: IPluginStore, clone?: PluginCloneFn);
485
- private loadBuiltins;
486
- loadUserPlugins(): void;
487
- get(id: string): PluginEntry | undefined;
488
- getManifest(id: string): RunnerPluginManifest | undefined;
489
- list(): PluginEntry[];
490
- listEnabled(config: IConfig): PluginEntry[];
491
- listEnabledIds(config: IConfig): string[];
492
- isBuiltIn(id: string): boolean;
493
- installFromPath(sourcePath: string): RunnerPluginManifest;
494
- installFromGit(url: string): RunnerPluginManifest;
495
- /**
496
- * The single destination-building step both install routes share: the name is
497
- * constrained to a plain segment and the resolved destination is asserted to
498
- * be inside the plugins directory before anything is copied.
499
- */
500
- private registerInstalled;
501
- remove(name: string): void;
502
- createSkeleton(name: string, outputDir: string): string;
503
- }
504
-
505
- interface ITerminalSession {
506
- id: string;
507
- taskId: string;
508
- onOutput(callback: (text: string) => void): void;
509
- onExit(callback: (code: number) => void): void;
510
- kill(): void;
511
- getOutput(): string;
512
- write(text: string): void;
513
- /**
514
- * True when the session runs the agent as a raw-mode TUI (a real PTY for the
515
- * VS Code terminal, a tmux window). Such a surface submits an input line on
516
- * the Enter keystroke (`\r`), so a synchronized resume token terminated with
517
- * `\n` only types the line and never sends it. A line-oriented piped session
518
- * (`defaultInteractive = false`) leaves this false and accepts `\n`.
519
- */
520
- readonly interactive?: boolean;
521
- /**
522
- * Optional transport-level control channel: PTY resize requests for a session
523
- * whose runner renders a TUI. Absent on transports without a resizable PTY
524
- * (a plain piped subprocess); surfaces must feature-detect before calling.
525
- */
526
- writeControl?(text: string): void;
527
- }
528
-
529
- interface ITerminalRunner {
530
- spawn(opts: {
531
- taskId: string;
532
- runner: string;
533
- prompt: string;
534
- modelId?: string;
535
- thinkingEffort?: string;
536
- modelVariants?: string[];
537
- mode?: string;
538
- headless?: boolean;
539
- cwd: string;
540
- registry?: RunnerRegistry;
541
- /** Task order and title — surfaces use these to label task_started/output events. */
542
- order?: number;
543
- title?: string;
544
- /**
545
- * The owning plan session. Task ids are only unique within one plan, so
546
- * transports that key OS resources by task (tmux windows, log files) need
547
- * this to keep two plans' identically named tasks apart.
548
- */
549
- planSessionId?: string;
550
- /**
551
- * The workspace's own variables (ADR-0016), under the runner's: a
552
- * manifest's env still wins over them.
553
- */
554
- env?: Record<string, string>;
555
- }): Promise<ITerminalSession>;
556
- stop(sessionId: string): void;
557
- stopAll(): void;
558
- activeCount: number;
559
- }
560
-
561
- 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 };