@ordewell/core 0.10.2 → 0.10.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.
Files changed (45) hide show
  1. package/dist/{IFileSystem-j0naIoAQ.d.mts → IFileSystem-B8Nkgg4e.d.mts} +1 -1
  2. package/dist/{IFileSystem-CyTIoiSn.d.ts → IFileSystem-DCd-rkeH.d.ts} +1 -1
  3. package/dist/{IRunner-WwL-Bjqq.d.ts → IRunner-CXdYyIZo.d.mts} +202 -196
  4. package/dist/{IRunner---PfQVdc.d.mts → IRunner-QBdYcatb.d.ts} +202 -196
  5. package/dist/{ModeResolver-DrMU-5lw.d.ts → ModeResolver-BOU90Nn-.d.ts} +1 -1
  6. package/dist/{ModeResolver-CjQ7zqTN.d.mts → ModeResolver-geqjKkLY.d.mts} +1 -1
  7. package/dist/{Task-AfA1m4qW.d.mts → Task-CRVIqSfy.d.mts} +24 -5
  8. package/dist/{Task-AfA1m4qW.d.ts → Task-CRVIqSfy.d.ts} +24 -5
  9. package/dist/{chunk-4FEARWTS.mjs → chunk-645FALZX.mjs} +5 -5
  10. package/dist/chunk-645FALZX.mjs.map +1 -0
  11. package/dist/{chunk-3LNZDBCX.mjs → chunk-A57ITQE7.mjs} +35 -16
  12. package/dist/chunk-A57ITQE7.mjs.map +1 -0
  13. package/dist/{chunk-UQGR3UCA.mjs → chunk-FH6M5QZG.mjs} +136 -122
  14. package/dist/chunk-FH6M5QZG.mjs.map +1 -0
  15. package/dist/{chunk-CIL3BQIF.mjs → chunk-SM6BV6XS.mjs} +17 -3
  16. package/dist/chunk-SM6BV6XS.mjs.map +1 -0
  17. package/dist/index.d.mts +417 -39
  18. package/dist/index.d.ts +417 -39
  19. package/dist/index.js +2478 -1473
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +10702 -9753
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/parsing.d.mts +2 -2
  24. package/dist/parsing.d.ts +2 -2
  25. package/dist/parsing.js +12 -12
  26. package/dist/parsing.js.map +1 -1
  27. package/dist/parsing.mjs +3 -3
  28. package/dist/{plan-utils-DL7yOuJs.d.mts → plan-utils-KU1Rse82.d.mts} +1292 -1147
  29. package/dist/{plan-utils-gpeqV-Lp.d.ts → plan-utils-oC8bO4pN.d.ts} +1292 -1147
  30. package/dist/plan-utils.d.mts +4 -4
  31. package/dist/plan-utils.d.ts +4 -4
  32. package/dist/plan-utils.js +16 -0
  33. package/dist/plan-utils.js.map +1 -1
  34. package/dist/plan-utils.mjs +7 -3
  35. package/dist/testing.d.mts +3 -3
  36. package/dist/testing.d.ts +3 -3
  37. package/dist/testing.js +3 -1
  38. package/dist/testing.js.map +1 -1
  39. package/dist/testing.mjs +4 -2
  40. package/dist/testing.mjs.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/chunk-3LNZDBCX.mjs.map +0 -1
  43. package/dist/chunk-4FEARWTS.mjs.map +0 -1
  44. package/dist/chunk-CIL3BQIF.mjs.map +0 -1
  45. package/dist/chunk-UQGR3UCA.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { ChildProcess } from 'child_process';
2
- import { aq as UsageRecord, ac as SubagentOutcome, c as DiscoveredModel, a1 as RunnerId, al as TaskSkillSnapshot } from './Task-AfA1m4qW.mjs';
2
+ import { a2 as RunnerId, ar as UsageRecord, ad as SubagentOutcome, d as DiscoveredModel, am as TaskSkillSnapshot } from './Task-CRVIqSfy.js';
3
3
  import { z } from 'zod/v4';
4
4
 
5
5
  /**
@@ -463,6 +463,198 @@ interface IApproval {
463
463
  /** Denies everything. The safe default when a surface wires no approval channel. */
464
464
  declare const DENY_ALL: IApproval;
465
465
 
466
+ interface CatalogModel {
467
+ id: string;
468
+ name: string;
469
+ description: string;
470
+ pricing: {
471
+ prompt: string;
472
+ completion: string;
473
+ };
474
+ contextLength: number;
475
+ }
476
+ declare class ModelCatalog {
477
+ static fetchModels(apiKey: string, baseUrl?: string, fetchImpl?: typeof fetch): Promise<CatalogModel[]>;
478
+ /**
479
+ * Delete the on-disk catalog cache for a base URL so the next fetch re-runs.
480
+ * Used by the resolver's `invalidate()` in production (no injected fetch);
481
+ * best-effort — a missing file or unreadable dir is a no-op.
482
+ */
483
+ static clearCache(baseUrl?: string): void;
484
+ private static readCache;
485
+ private static writeCache;
486
+ }
487
+
488
+ interface ModelShortcut {
489
+ label: string;
490
+ id: string;
491
+ provider: string;
492
+ description: string;
493
+ pricing?: string;
494
+ }
495
+ declare const ORCHESTRATOR_SHORTCUTS: ModelShortcut[];
496
+ declare function resolveModelShortcut(input: string, shortcuts: ModelShortcut[]): string | null;
497
+ /**
498
+ * Resolves a value to a model id ONLY when it is in the supplied catalog
499
+ * option list — either directly or via a shortcut label. Free-typed, unknown,
500
+ * or not-currently-available values return null, so callers never store an id
501
+ * the user couldn't have selected from the list. Keeps model-setting list-only.
502
+ */
503
+ declare function knownModelId(value: string, optionIds: string[], shortcuts: ModelShortcut[]): string | null;
504
+
505
+ type ProviderModelLists = Record<string, string[]>;
506
+ interface OrchestratorOption {
507
+ id: string;
508
+ label: string;
509
+ provider: string;
510
+ apiProvider: AiProvider;
511
+ description?: string;
512
+ pricing?: string;
513
+ /** The model's context window when the catalog reports one (#49). */
514
+ contextWindow?: number;
515
+ }
516
+
517
+ interface FetchAllProviderModelsOptions {
518
+ apiKeys: Record<string, string>;
519
+ baseUrls: Record<string, string>;
520
+ fetchImpl?: typeof fetch;
521
+ }
522
+ type AllProviderModels = Record<string, CatalogModel[]>;
523
+ /**
524
+ * Result of a picker-catalog fetch fan-out: the per-provider model lists plus
525
+ * the per-provider failures. `errors` is keyed by provider id and holds the
526
+ * failure message for any provider whose catalog fetch rejected — the seam the
527
+ * surfaces (CLI, VS Code) use to flag "this configured provider didn't work"
528
+ * rather than silently showing a short list.
529
+ */
530
+ interface ProviderModelsResult {
531
+ models: AllProviderModels;
532
+ errors: Record<string, string>;
533
+ }
534
+ /** The provider config fields the discovery fan-out needs. */
535
+ interface ProviderCredentialSource {
536
+ getProviderApiKey(provider: AiProvider): string;
537
+ getProviderBaseUrl(provider: AiProvider): string;
538
+ openaiCompatibleBaseUrl: string;
539
+ }
540
+ /**
541
+ * Collect the API keys and base URLs the picker fan-out should probe, applying
542
+ * the single "configured" policy shared by every surface (CLI + VS Code):
543
+ * - a preset is discovered only when it has an API key (OpenRouter included —
544
+ * its public catalog is not probed keyless, matching the product rule that
545
+ * only key-configured providers appear);
546
+ * - `openai_compatible` is discovered only when an explicit endpoint is set
547
+ * (keyless local servers like ollama / LM Studio).
548
+ * Base URLs are handed through only for providers that pass the gate, so the
549
+ * fan-out never touches an unconfigured third-party endpoint.
550
+ */
551
+ declare function collectProviderCredentials(config: ProviderCredentialSource): {
552
+ apiKeys: Record<string, string>;
553
+ baseUrls: Record<string, string>;
554
+ };
555
+ declare function fetchAllProviderModels(opts: FetchAllProviderModelsOptions): Promise<ProviderModelsResult>;
556
+ declare function resolveProvider(modelId: string, providerModelLists: Record<string, string[]>): AiProvider | null;
557
+ declare function toOrchestratorOptions(providerModels: AllProviderModels, shortcuts: ModelShortcut[]): OrchestratorOption[];
558
+
559
+ /** An LLM vendor reached over HTTP. A closed set: each one has its own registration in `ProviderRegistry`. */
560
+ 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';
561
+ /**
562
+ * Who plans: an API vendor, or the id of a runner serving as a *harness
563
+ * planner* (ADR-0009) — a coding agent CLI already installed on the machine,
564
+ * driven as the planner over its own programmatic transport and authenticated
565
+ * by the subscription the user already holds. Runners sit in the provider axis
566
+ * deliberately: "what plans for me?" is one question, and it belongs in one
567
+ * setting. The runner half is open — any built-in runner with a connector can
568
+ * plan — so it is checked against the registry, not by the type:
569
+ * `isApiProvider` narrows to a vendor, `isCliProvider` tells a harness planner.
570
+ */
571
+ type PlannerBackendId = AiProvider | RunnerId;
572
+ interface IConfig {
573
+ aiProvider: PlannerBackendId;
574
+ apiKey: string;
575
+ planningModel: string;
576
+ enabledRunners: string[];
577
+ maxParallelSessions: number;
578
+ researchEnabled: boolean;
579
+ researchMaxSteps: number;
580
+ researchMaxFileSize: number;
581
+ openAiBaseUrl: string;
582
+ openAiApiKey: string;
583
+ /** Provider keys + base URL the ModelResolver uses to fetch the picker catalogs. */
584
+ openrouterKey: string;
585
+ geminiKey: string;
586
+ geminiBaseUrl?: string;
587
+ /** Base URL + API key for a user-provided OpenAI-compatible endpoint (ollama, vLLM, LM Studio, etc.). */
588
+ openaiCompatibleBaseUrl: string;
589
+ openaiCompatibleApiKey: string;
590
+ orchestratorModel: string;
591
+ geminiModel: string;
592
+ /** Model for research subagents (issue #34); defaults to the (cheap) planner model. */
593
+ researchSubagentModel: string;
594
+ /**
595
+ * Thinking effort / model variant for a harness planner (ADR-0009), chosen
596
+ * from the agent's own discovered variants. Separate from the per-task
597
+ * efforts the plan carries — this one is the planner's own dial.
598
+ */
599
+ plannerThinkingEffort?: string;
600
+ planMapEnabled: boolean;
601
+ autonomousMode: boolean;
602
+ /**
603
+ * Run each AI task in its own git worktree and integrate the results on a
604
+ * per-run branch (ADR-0013). Non-git workspaces fall back to the shared
605
+ * workspace root regardless of this flag.
606
+ */
607
+ worktreeIsolation: boolean;
608
+ /**
609
+ * Shell command run in a fresh task worktree instead of symlinking ignored
610
+ * artifacts from the main worktree — for repos where sharing `node_modules`
611
+ * or a virtualenv is wrong.
612
+ */
613
+ worktreeSetupCommand?: string;
614
+ /**
615
+ * Repositories of the repo group listed by hand, relative to the workspace
616
+ * (ADR-0014). When non-empty the group is exactly these, replacing the
617
+ * repositories auto-detected directly inside the folder; needed for ones
618
+ * deeper than that, which are never auto-detected.
619
+ */
620
+ workspaceRepos: string[];
621
+ /**
622
+ * Extra paths or globs, relative to each repo root, linked from the real repo
623
+ * into its task worktree where they exist — gitignored local state such as
624
+ * `*.tfstate` that a task must use, not a copy of.
625
+ */
626
+ worktreeLinks: string[];
627
+ /**
628
+ * How many conflict repairs one task may go through before its conflict is
629
+ * left for a person (ADR-0015); 0 turns repair off.
630
+ */
631
+ conflictRepairAttempts: number;
632
+ /**
633
+ * What to do when planner research reaches outside its default envelope — an
634
+ * out-of-workspace path, a shell command beyond the auto-allowed read-only
635
+ * set, an MCP tool. `ask` prompts the user (and denies where no surface can
636
+ * prompt, such as headless runs); `allow` and `deny` skip the prompt
637
+ * entirely; `auto` follows {@link autonomousMode} (ADR-0026).
638
+ */
639
+ approvalMode: ApprovalModeSetting;
640
+ /** Allowlist entries granted up front, beside the defaults (ADR-0026, `plannerAllowlist.ts`). */
641
+ approvalPreApproved: string[];
642
+ /** Whether the built-in allowlist of read-only command families and MCP tools applies. */
643
+ approvalDefaults: boolean;
644
+ /** How many fetches and searches one planner turn may make (ADR-0027). User-only, like the approval settings. */
645
+ webReadBudget: number;
646
+ /** Get the base URL for an OpenAI-compatible provider. */
647
+ getProviderBaseUrl(provider: AiProvider): string;
648
+ /** Get the API key for a provider. */
649
+ getProviderApiKey(provider: AiProvider): string;
650
+ /**
651
+ * Push the canonical provider routing lists in (sole producer: ModelResolver).
652
+ * Config consumes them when resolving a chosen model id to its serving API.
653
+ */
654
+ setProviderModelLists(lists: ProviderModelLists): void;
655
+ }
656
+ declare function enabledRunners(cfg: IConfig): RunnerId[];
657
+
466
658
  /**
467
659
  * The tools of the Ordewell MCP server, per token role (ADR-0022), and the
468
660
  * handler interfaces the session side implements to answer them.
@@ -588,24 +780,24 @@ declare const taskOutputInput: z.ZodObject<{
588
780
  error: "error";
589
781
  command: "command";
590
782
  thinking: "thinking";
591
- turn_end: "turn_end";
592
- message_delivered: "message_delivered";
593
783
  thinking_delta: "thinking_delta";
594
784
  tool_call: "tool_call";
595
785
  tool_result: "tool_result";
596
786
  usage: "usage";
597
787
  subagent_started: "subagent_started";
598
788
  subagent_finished: "subagent_finished";
789
+ turn_end: "turn_end";
790
+ message_delivered: "message_delivered";
599
791
  runner_loaded: "runner_loaded";
600
792
  compaction: "compaction";
601
793
  command_output: "command_output";
794
+ text_delta: "text_delta";
602
795
  turn_start: "turn_start";
603
796
  message_queued: "message_queued";
604
797
  message_removed: "message_removed";
605
798
  message_undelivered: "message_undelivered";
606
799
  message_handed_over: "message_handed_over";
607
800
  task_skills: "task_skills";
608
- text_delta: "text_delta";
609
801
  approval_requested: "approval_requested";
610
802
  approval_decided: "approval_decided";
611
803
  approval_withdrawn: "approval_withdrawn";
@@ -1380,6 +1572,12 @@ interface RunnerModelDiscovery {
1380
1572
  modelId: string;
1381
1573
  modelLabel: string;
1382
1574
  }[];
1575
+ /**
1576
+ * The runner names its models `provider/model` (OpenCode), so an id of that
1577
+ * shape can be its own rather than an OpenRouter slug left from a vendor
1578
+ * planner.
1579
+ */
1580
+ providerQualifiedIds?: boolean;
1383
1581
  /**
1384
1582
  * HTTP API discovery — tried BEFORE command discovery. When the runner's CLI
1385
1583
  * has no model-listing subcommand (Claude Code), an API endpoint can serve as
@@ -1423,198 +1621,6 @@ interface RunnerEntry {
1423
1621
  manifest: RunnerManifest;
1424
1622
  }
1425
1623
 
1426
- interface CatalogModel {
1427
- id: string;
1428
- name: string;
1429
- description: string;
1430
- pricing: {
1431
- prompt: string;
1432
- completion: string;
1433
- };
1434
- contextLength: number;
1435
- }
1436
- declare class ModelCatalog {
1437
- static fetchModels(apiKey: string, baseUrl?: string, fetchImpl?: typeof fetch): Promise<CatalogModel[]>;
1438
- /**
1439
- * Delete the on-disk catalog cache for a base URL so the next fetch re-runs.
1440
- * Used by the resolver's `invalidate()` in production (no injected fetch);
1441
- * best-effort — a missing file or unreadable dir is a no-op.
1442
- */
1443
- static clearCache(baseUrl?: string): void;
1444
- private static readCache;
1445
- private static writeCache;
1446
- }
1447
-
1448
- interface ModelShortcut {
1449
- label: string;
1450
- id: string;
1451
- provider: string;
1452
- description: string;
1453
- pricing?: string;
1454
- }
1455
- declare const ORCHESTRATOR_SHORTCUTS: ModelShortcut[];
1456
- declare function resolveModelShortcut(input: string, shortcuts: ModelShortcut[]): string | null;
1457
- /**
1458
- * Resolves a value to a model id ONLY when it is in the supplied catalog
1459
- * option list — either directly or via a shortcut label. Free-typed, unknown,
1460
- * or not-currently-available values return null, so callers never store an id
1461
- * the user couldn't have selected from the list. Keeps model-setting list-only.
1462
- */
1463
- declare function knownModelId(value: string, optionIds: string[], shortcuts: ModelShortcut[]): string | null;
1464
-
1465
- type ProviderModelLists = Record<string, string[]>;
1466
- interface OrchestratorOption {
1467
- id: string;
1468
- label: string;
1469
- provider: string;
1470
- apiProvider: AiProvider;
1471
- description?: string;
1472
- pricing?: string;
1473
- /** The model's context window when the catalog reports one (#49). */
1474
- contextWindow?: number;
1475
- }
1476
-
1477
- interface FetchAllProviderModelsOptions {
1478
- apiKeys: Record<string, string>;
1479
- baseUrls: Record<string, string>;
1480
- fetchImpl?: typeof fetch;
1481
- }
1482
- type AllProviderModels = Record<string, CatalogModel[]>;
1483
- /**
1484
- * Result of a picker-catalog fetch fan-out: the per-provider model lists plus
1485
- * the per-provider failures. `errors` is keyed by provider id and holds the
1486
- * failure message for any provider whose catalog fetch rejected — the seam the
1487
- * surfaces (CLI, VS Code) use to flag "this configured provider didn't work"
1488
- * rather than silently showing a short list.
1489
- */
1490
- interface ProviderModelsResult {
1491
- models: AllProviderModels;
1492
- errors: Record<string, string>;
1493
- }
1494
- /** The provider config fields the discovery fan-out needs. */
1495
- interface ProviderCredentialSource {
1496
- getProviderApiKey(provider: AiProvider): string;
1497
- getProviderBaseUrl(provider: AiProvider): string;
1498
- openaiCompatibleBaseUrl: string;
1499
- }
1500
- /**
1501
- * Collect the API keys and base URLs the picker fan-out should probe, applying
1502
- * the single "configured" policy shared by every surface (CLI + VS Code):
1503
- * - a preset is discovered only when it has an API key (OpenRouter included —
1504
- * its public catalog is not probed keyless, matching the product rule that
1505
- * only key-configured providers appear);
1506
- * - `openai_compatible` is discovered only when an explicit endpoint is set
1507
- * (keyless local servers like ollama / LM Studio).
1508
- * Base URLs are handed through only for providers that pass the gate, so the
1509
- * fan-out never touches an unconfigured third-party endpoint.
1510
- */
1511
- declare function collectProviderCredentials(config: ProviderCredentialSource): {
1512
- apiKeys: Record<string, string>;
1513
- baseUrls: Record<string, string>;
1514
- };
1515
- declare function fetchAllProviderModels(opts: FetchAllProviderModelsOptions): Promise<ProviderModelsResult>;
1516
- declare function resolveProvider(modelId: string, providerModelLists: Record<string, string[]>): AiProvider | null;
1517
- declare function toOrchestratorOptions(providerModels: AllProviderModels, shortcuts: ModelShortcut[]): OrchestratorOption[];
1518
-
1519
- /** An LLM vendor reached over HTTP. A closed set: each one has its own registration in `ProviderRegistry`. */
1520
- 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';
1521
- /**
1522
- * Who plans: an API vendor, or the id of a runner serving as a *harness
1523
- * planner* (ADR-0009) — a coding agent CLI already installed on the machine,
1524
- * driven as the planner over its own programmatic transport and authenticated
1525
- * by the subscription the user already holds. Runners sit in the provider axis
1526
- * deliberately: "what plans for me?" is one question, and it belongs in one
1527
- * setting. The runner half is open — any built-in runner with a connector can
1528
- * plan — so it is checked against the registry, not by the type:
1529
- * `isApiProvider` narrows to a vendor, `isCliProvider` tells a harness planner.
1530
- */
1531
- type PlannerBackendId = AiProvider | RunnerId;
1532
- interface IConfig {
1533
- aiProvider: PlannerBackendId;
1534
- apiKey: string;
1535
- planningModel: string;
1536
- enabledRunners: string[];
1537
- maxParallelSessions: number;
1538
- researchEnabled: boolean;
1539
- researchMaxSteps: number;
1540
- researchMaxFileSize: number;
1541
- openAiBaseUrl: string;
1542
- openAiApiKey: string;
1543
- /** Provider keys + base URL the ModelResolver uses to fetch the picker catalogs. */
1544
- openrouterKey: string;
1545
- geminiKey: string;
1546
- geminiBaseUrl?: string;
1547
- /** Base URL + API key for a user-provided OpenAI-compatible endpoint (ollama, vLLM, LM Studio, etc.). */
1548
- openaiCompatibleBaseUrl: string;
1549
- openaiCompatibleApiKey: string;
1550
- orchestratorModel: string;
1551
- geminiModel: string;
1552
- /** Model for research subagents (issue #34); defaults to the (cheap) planner model. */
1553
- researchSubagentModel: string;
1554
- /**
1555
- * Thinking effort / model variant for a harness planner (ADR-0009), chosen
1556
- * from the agent's own discovered variants. Separate from the per-task
1557
- * efforts the plan carries — this one is the planner's own dial.
1558
- */
1559
- plannerThinkingEffort?: string;
1560
- planMapEnabled: boolean;
1561
- autonomousMode: boolean;
1562
- /**
1563
- * Run each AI task in its own git worktree and integrate the results on a
1564
- * per-run branch (ADR-0013). Non-git workspaces fall back to the shared
1565
- * workspace root regardless of this flag.
1566
- */
1567
- worktreeIsolation: boolean;
1568
- /**
1569
- * Shell command run in a fresh task worktree instead of symlinking ignored
1570
- * artifacts from the main worktree — for repos where sharing `node_modules`
1571
- * or a virtualenv is wrong.
1572
- */
1573
- worktreeSetupCommand?: string;
1574
- /**
1575
- * Repositories of the repo group listed by hand, relative to the workspace
1576
- * (ADR-0014). When non-empty the group is exactly these, replacing the
1577
- * repositories auto-detected directly inside the folder; needed for ones
1578
- * deeper than that, which are never auto-detected.
1579
- */
1580
- workspaceRepos: string[];
1581
- /**
1582
- * Extra paths or globs, relative to each repo root, linked from the real repo
1583
- * into its task worktree where they exist — gitignored local state such as
1584
- * `*.tfstate` that a task must use, not a copy of.
1585
- */
1586
- worktreeLinks: string[];
1587
- /**
1588
- * How many conflict repairs one task may go through before its conflict is
1589
- * left for a person (ADR-0015); 0 turns repair off.
1590
- */
1591
- conflictRepairAttempts: number;
1592
- /**
1593
- * What to do when planner research reaches outside its default envelope — an
1594
- * out-of-workspace path, a shell command beyond the auto-allowed read-only
1595
- * set, an MCP tool. `ask` prompts the user (and denies where no surface can
1596
- * prompt, such as headless runs); `allow` and `deny` skip the prompt
1597
- * entirely; `auto` follows {@link autonomousMode} (ADR-0026).
1598
- */
1599
- approvalMode: ApprovalModeSetting;
1600
- /** Allowlist entries granted up front, beside the defaults (ADR-0026, `plannerAllowlist.ts`). */
1601
- approvalPreApproved: string[];
1602
- /** Whether the built-in allowlist of read-only command families and MCP tools applies. */
1603
- approvalDefaults: boolean;
1604
- /** How many fetches and searches one planner turn may make (ADR-0027). User-only, like the approval settings. */
1605
- webReadBudget: number;
1606
- /** Get the base URL for an OpenAI-compatible provider. */
1607
- getProviderBaseUrl(provider: AiProvider): string;
1608
- /** Get the API key for a provider. */
1609
- getProviderApiKey(provider: AiProvider): string;
1610
- /**
1611
- * Push the canonical provider routing lists in (sole producer: ModelResolver).
1612
- * Config consumes them when resolving a chosen model id to its serving API.
1613
- */
1614
- setProviderModelLists(lists: ProviderModelLists): void;
1615
- }
1616
- declare function enabledRunners(cfg: IConfig): RunnerId[];
1617
-
1618
1624
  declare class RunnerRegistry {
1619
1625
  private readonly runners;
1620
1626
  private readonly unavailableModes;
@@ -1,4 +1,4 @@
1
- import { a1 as RunnerId } from './Task-AfA1m4qW.js';
1
+ import { a2 as RunnerId } from './Task-CRVIqSfy.js';
2
2
 
3
3
  interface RunnerModeInfo {
4
4
  id: string;
@@ -1,4 +1,4 @@
1
- import { a1 as RunnerId } from './Task-AfA1m4qW.mjs';
1
+ import { a2 as RunnerId } from './Task-CRVIqSfy.mjs';
2
2
 
3
3
  interface RunnerModeInfo {
4
4
  id: string;
@@ -932,7 +932,8 @@ interface TaskOutputSummary {
932
932
  type TaskType = 'ai' | 'user';
933
933
  /**
934
934
  * `skipped` is terminal and verdict-less: the task will not be waited for, and
935
- * nothing it did lands. Its dependents go ahead without it.
935
+ * nothing it did lands. Its dependents go ahead without it once the work it
936
+ * waited on is done.
936
937
  */
937
938
  type TaskStatus = 'pending' | 'approved' | 'in_progress' | 'completed' | 'failed' | 'blocked' | 'awaiting_user' | 'skipped';
938
939
  type TaskMode = string;
@@ -1298,9 +1299,17 @@ interface LegacyPlanState {
1298
1299
  * The tasks the user approved to run: every task when they executed the
1299
1300
  * plan, and each one they started or retried themselves since. A command
1300
1301
  * from anyone else starts only these (ADR-0029); a task the planner added
1301
- * after the approval waits for the user's.
1302
+ * after the approval waits for the user's. Only tasks still in the plan: a
1303
+ * task that leaves takes its approval with it.
1302
1304
  */
1303
1305
  approvedTasks?: string[];
1306
+ /**
1307
+ * The user approved the plan to run: Execute plan, signing off a review, or
1308
+ * autorun's start (ADR-0029, ADR-0030). Kept apart from {@link status},
1309
+ * which surfaces rewrite for display; a user's start of one task approves
1310
+ * that task, not the plan.
1311
+ */
1312
+ approved?: boolean;
1304
1313
  }
1305
1314
  interface Message {
1306
1315
  id: string;
@@ -1314,7 +1323,8 @@ interface TaskSnapshot extends Task {
1314
1323
  retryCount: number;
1315
1324
  finalized: boolean;
1316
1325
  }
1317
- type PlanState = {
1326
+ /** The plan a surface reads whole carries the approval record, so it can tell which tasks wait for the user (ADR-0035). */
1327
+ type PlanState = ({
1318
1328
  phase: 'planning';
1319
1329
  history: Message[];
1320
1330
  message: string;
@@ -1328,7 +1338,7 @@ type PlanState = {
1328
1338
  goal: string;
1329
1339
  runners: string[];
1330
1340
  status: PlanStatus;
1331
- };
1341
+ }) & ApprovalRecord;
1332
1342
  declare function migratePlanState(raw: unknown): PlanState;
1333
1343
 
1334
1344
  declare function createTask(overrides?: Partial<Task>): Task;
@@ -1365,5 +1375,14 @@ interface TaskWithParent {
1365
1375
  declare function flattenTasksWithParents(tasks: readonly Task[]): TaskWithParent[];
1366
1376
  /** A task paused on its runner's usage limit, whether it resumes on its own or waits for the user (#84). */
1367
1377
  declare function pausedOnLimit(task: Readonly<Task>): boolean;
1378
+ /** The user's approval record, as a plan carries it (ADR-0029). */
1379
+ type ApprovalRecord = Pick<LegacyPlanState, 'approved' | 'approvedTasks'>;
1380
+ /**
1381
+ * A task the scheduler leaves for the user (ADR-0035): an AI task not started
1382
+ * yet, in a plan they approved, outside their approval record — the planner
1383
+ * added it since. It starts once they start it or execute the plan. In a plan
1384
+ * they never approved nothing is theirs yet, so nothing is singled out.
1385
+ */
1386
+ declare function waitsForApproval(task: Pick<Task, 'id' | 'type' | 'status'>, record: ApprovalRecord): boolean;
1368
1387
 
1369
- export { type ResearchToolType as $, type AttemptUsage as A, BUILTIN_SKILL_NAMES as B, type ConversationMessage as C, DEFAULT_RUNNERS as D, type ExecutionActor as E, type IsolationView as F, type GuardTarget as G, type PlanIsolation as H, type IWorktreeIsolation as I, type PlanState as J, type PlanStatus as K, type LegacyPlanState as L, type ModelUsage as M, type PlanUsage as N, type PlannerUsage as O, type PendingPlanTurn as P, type PrepareIntent as Q, type PreparedTask as R, type PreservedWork as S, type PreviousWork as T, type RefusedRemoval as U, type RepairEvidence as V, type RepoGroupLayout as W, type ResearchLogEntry as X, type ResearchProgress as Y, type ResearchStep as Z, type ResearchStepOutcome as _, type AwaitingReason as a, type RunSettings as a0, type RunnerId as a1, type SetupFailure as a2, type ShadowedSkill as a3, type SkillAppliesTo as a4, type SkillCatalog as a5, type SkillInfo as a6, type SkillLoad as a7, type SkillLoadNotice as a8, type SkillMetadata as a9, createSkillsService as aA, createTask as aB, endAttemptUsage as aC, flattenTasks as aD, flattenTasksWithParents as aE, isAwaitingReason as aF, isMeasured as aG, isSupervisorLevel as aH, isUserMessage as aI, migratePlanState as aJ, partedPromptUsage as aK, pausedOnLimit as aL, planUsage as aM, plannerContextFill as aN, rejoinPlanTree as aO, startAttemptUsage as aP, usageLine as aQ, type SkillSource as aa, SkillsService as ab, type SubagentOutcome as ac, type SupervisorLevel as ad, type Task as ae, type TaskDiffRead as af, type TaskDiffResult as ag, type TaskIsolation as ah, type TaskIsolationState as ai, type TaskModelAssignment as aj, type TaskSkillNotice as ak, type TaskSkillSnapshot as al, type TaskSnapshot as am, type TaskStatus as an, type TreeSnapshot as ao, type UsageLine as ap, type UsageRecord as aq, type UsageTotals as ar, type Verdict as as, type VerificationCheck as at, addAttemptUsage as au, addModelUsage as av, addPlannerUsage as aw, addUsage as ax, addUsageTotals as ay, createEmptyPlan as az, DEFAULT_SUPERVISOR_RETRY_LIMIT as b, type DiscoveredModel as c, type ExecutionCommandName as d, type ExecutionRecord as e, type GuardTrip as f, type IntegrationDisposal as g, type InvalidSkill as h, type IsolationAvailability as i, type IsolationHandoff as j, type IsolationHandoffRepo as k, type IsolationInactiveReason as l, type IsolationLandedTask as m, type IsolationLanding as n, type IsolationMergeBlock as o, type IsolationMergeBlockReason as p, type IsolationMergeResult as q, type IsolationOutcome as r, type IsolationPruneResult as s, type IsolationRemoval as t, type IsolationRepo as u, type IsolationRun as v, type IsolationTaskRecord as w, type IsolationTaskRef as x, type IsolationTaskRepo as y, type IsolationTaskStatus as z };
1388
+ export { type ResearchStepOutcome as $, type ApprovalRecord as A, BUILTIN_SKILL_NAMES as B, type ConversationMessage as C, DEFAULT_RUNNERS as D, type ExecutionActor as E, type IsolationTaskStatus as F, type GuardTarget as G, type IsolationView as H, type IWorktreeIsolation as I, type PlanIsolation as J, type PlanState as K, type LegacyPlanState as L, type ModelUsage as M, type PlanStatus as N, type PlanUsage as O, type PendingPlanTurn as P, type PlannerUsage as Q, type PrepareIntent as R, type PreparedTask as S, type PreservedWork as T, type PreviousWork as U, type RefusedRemoval as V, type RepairEvidence as W, type RepoGroupLayout as X, type ResearchLogEntry as Y, type ResearchProgress as Z, type ResearchStep as _, type AttemptUsage as a, type ResearchToolType as a0, type RunSettings as a1, type RunnerId as a2, type SetupFailure as a3, type ShadowedSkill as a4, type SkillAppliesTo as a5, type SkillCatalog as a6, type SkillInfo as a7, type SkillLoad as a8, type SkillLoadNotice as a9, createEmptyPlan as aA, createSkillsService as aB, createTask as aC, endAttemptUsage as aD, flattenTasks as aE, flattenTasksWithParents as aF, isAwaitingReason as aG, isMeasured as aH, isSupervisorLevel as aI, isUserMessage as aJ, migratePlanState as aK, partedPromptUsage as aL, pausedOnLimit as aM, planUsage as aN, plannerContextFill as aO, rejoinPlanTree as aP, startAttemptUsage as aQ, usageLine as aR, waitsForApproval as aS, type SkillMetadata as aa, type SkillSource as ab, SkillsService as ac, type SubagentOutcome as ad, type SupervisorLevel as ae, type Task as af, type TaskDiffRead as ag, type TaskDiffResult as ah, type TaskIsolation as ai, type TaskIsolationState as aj, type TaskModelAssignment as ak, type TaskSkillNotice as al, type TaskSkillSnapshot as am, type TaskSnapshot as an, type TaskStatus as ao, type TreeSnapshot as ap, type UsageLine as aq, type UsageRecord as ar, type UsageTotals as as, type Verdict as at, type VerificationCheck as au, addAttemptUsage as av, addModelUsage as aw, addPlannerUsage as ax, addUsage as ay, addUsageTotals as az, type AwaitingReason as b, DEFAULT_SUPERVISOR_RETRY_LIMIT as c, type DiscoveredModel as d, type ExecutionCommandName as e, type ExecutionRecord as f, type GuardTrip as g, type IntegrationDisposal as h, type InvalidSkill as i, type IsolationAvailability as j, type IsolationHandoff as k, type IsolationHandoffRepo as l, type IsolationInactiveReason as m, type IsolationLandedTask as n, type IsolationLanding as o, type IsolationMergeBlock as p, type IsolationMergeBlockReason as q, type IsolationMergeResult as r, type IsolationOutcome as s, type IsolationPruneResult as t, type IsolationRemoval as u, type IsolationRepo as v, type IsolationRun as w, type IsolationTaskRecord as x, type IsolationTaskRef as y, type IsolationTaskRepo as z };
@@ -932,7 +932,8 @@ interface TaskOutputSummary {
932
932
  type TaskType = 'ai' | 'user';
933
933
  /**
934
934
  * `skipped` is terminal and verdict-less: the task will not be waited for, and
935
- * nothing it did lands. Its dependents go ahead without it.
935
+ * nothing it did lands. Its dependents go ahead without it once the work it
936
+ * waited on is done.
936
937
  */
937
938
  type TaskStatus = 'pending' | 'approved' | 'in_progress' | 'completed' | 'failed' | 'blocked' | 'awaiting_user' | 'skipped';
938
939
  type TaskMode = string;
@@ -1298,9 +1299,17 @@ interface LegacyPlanState {
1298
1299
  * The tasks the user approved to run: every task when they executed the
1299
1300
  * plan, and each one they started or retried themselves since. A command
1300
1301
  * from anyone else starts only these (ADR-0029); a task the planner added
1301
- * after the approval waits for the user's.
1302
+ * after the approval waits for the user's. Only tasks still in the plan: a
1303
+ * task that leaves takes its approval with it.
1302
1304
  */
1303
1305
  approvedTasks?: string[];
1306
+ /**
1307
+ * The user approved the plan to run: Execute plan, signing off a review, or
1308
+ * autorun's start (ADR-0029, ADR-0030). Kept apart from {@link status},
1309
+ * which surfaces rewrite for display; a user's start of one task approves
1310
+ * that task, not the plan.
1311
+ */
1312
+ approved?: boolean;
1304
1313
  }
1305
1314
  interface Message {
1306
1315
  id: string;
@@ -1314,7 +1323,8 @@ interface TaskSnapshot extends Task {
1314
1323
  retryCount: number;
1315
1324
  finalized: boolean;
1316
1325
  }
1317
- type PlanState = {
1326
+ /** The plan a surface reads whole carries the approval record, so it can tell which tasks wait for the user (ADR-0035). */
1327
+ type PlanState = ({
1318
1328
  phase: 'planning';
1319
1329
  history: Message[];
1320
1330
  message: string;
@@ -1328,7 +1338,7 @@ type PlanState = {
1328
1338
  goal: string;
1329
1339
  runners: string[];
1330
1340
  status: PlanStatus;
1331
- };
1341
+ }) & ApprovalRecord;
1332
1342
  declare function migratePlanState(raw: unknown): PlanState;
1333
1343
 
1334
1344
  declare function createTask(overrides?: Partial<Task>): Task;
@@ -1365,5 +1375,14 @@ interface TaskWithParent {
1365
1375
  declare function flattenTasksWithParents(tasks: readonly Task[]): TaskWithParent[];
1366
1376
  /** A task paused on its runner's usage limit, whether it resumes on its own or waits for the user (#84). */
1367
1377
  declare function pausedOnLimit(task: Readonly<Task>): boolean;
1378
+ /** The user's approval record, as a plan carries it (ADR-0029). */
1379
+ type ApprovalRecord = Pick<LegacyPlanState, 'approved' | 'approvedTasks'>;
1380
+ /**
1381
+ * A task the scheduler leaves for the user (ADR-0035): an AI task not started
1382
+ * yet, in a plan they approved, outside their approval record — the planner
1383
+ * added it since. It starts once they start it or execute the plan. In a plan
1384
+ * they never approved nothing is theirs yet, so nothing is singled out.
1385
+ */
1386
+ declare function waitsForApproval(task: Pick<Task, 'id' | 'type' | 'status'>, record: ApprovalRecord): boolean;
1368
1387
 
1369
- export { type ResearchToolType as $, type AttemptUsage as A, BUILTIN_SKILL_NAMES as B, type ConversationMessage as C, DEFAULT_RUNNERS as D, type ExecutionActor as E, type IsolationView as F, type GuardTarget as G, type PlanIsolation as H, type IWorktreeIsolation as I, type PlanState as J, type PlanStatus as K, type LegacyPlanState as L, type ModelUsage as M, type PlanUsage as N, type PlannerUsage as O, type PendingPlanTurn as P, type PrepareIntent as Q, type PreparedTask as R, type PreservedWork as S, type PreviousWork as T, type RefusedRemoval as U, type RepairEvidence as V, type RepoGroupLayout as W, type ResearchLogEntry as X, type ResearchProgress as Y, type ResearchStep as Z, type ResearchStepOutcome as _, type AwaitingReason as a, type RunSettings as a0, type RunnerId as a1, type SetupFailure as a2, type ShadowedSkill as a3, type SkillAppliesTo as a4, type SkillCatalog as a5, type SkillInfo as a6, type SkillLoad as a7, type SkillLoadNotice as a8, type SkillMetadata as a9, createSkillsService as aA, createTask as aB, endAttemptUsage as aC, flattenTasks as aD, flattenTasksWithParents as aE, isAwaitingReason as aF, isMeasured as aG, isSupervisorLevel as aH, isUserMessage as aI, migratePlanState as aJ, partedPromptUsage as aK, pausedOnLimit as aL, planUsage as aM, plannerContextFill as aN, rejoinPlanTree as aO, startAttemptUsage as aP, usageLine as aQ, type SkillSource as aa, SkillsService as ab, type SubagentOutcome as ac, type SupervisorLevel as ad, type Task as ae, type TaskDiffRead as af, type TaskDiffResult as ag, type TaskIsolation as ah, type TaskIsolationState as ai, type TaskModelAssignment as aj, type TaskSkillNotice as ak, type TaskSkillSnapshot as al, type TaskSnapshot as am, type TaskStatus as an, type TreeSnapshot as ao, type UsageLine as ap, type UsageRecord as aq, type UsageTotals as ar, type Verdict as as, type VerificationCheck as at, addAttemptUsage as au, addModelUsage as av, addPlannerUsage as aw, addUsage as ax, addUsageTotals as ay, createEmptyPlan as az, DEFAULT_SUPERVISOR_RETRY_LIMIT as b, type DiscoveredModel as c, type ExecutionCommandName as d, type ExecutionRecord as e, type GuardTrip as f, type IntegrationDisposal as g, type InvalidSkill as h, type IsolationAvailability as i, type IsolationHandoff as j, type IsolationHandoffRepo as k, type IsolationInactiveReason as l, type IsolationLandedTask as m, type IsolationLanding as n, type IsolationMergeBlock as o, type IsolationMergeBlockReason as p, type IsolationMergeResult as q, type IsolationOutcome as r, type IsolationPruneResult as s, type IsolationRemoval as t, type IsolationRepo as u, type IsolationRun as v, type IsolationTaskRecord as w, type IsolationTaskRef as x, type IsolationTaskRepo as y, type IsolationTaskStatus as z };
1388
+ export { type ResearchStepOutcome as $, type ApprovalRecord as A, BUILTIN_SKILL_NAMES as B, type ConversationMessage as C, DEFAULT_RUNNERS as D, type ExecutionActor as E, type IsolationTaskStatus as F, type GuardTarget as G, type IsolationView as H, type IWorktreeIsolation as I, type PlanIsolation as J, type PlanState as K, type LegacyPlanState as L, type ModelUsage as M, type PlanStatus as N, type PlanUsage as O, type PendingPlanTurn as P, type PlannerUsage as Q, type PrepareIntent as R, type PreparedTask as S, type PreservedWork as T, type PreviousWork as U, type RefusedRemoval as V, type RepairEvidence as W, type RepoGroupLayout as X, type ResearchLogEntry as Y, type ResearchProgress as Z, type ResearchStep as _, type AttemptUsage as a, type ResearchToolType as a0, type RunSettings as a1, type RunnerId as a2, type SetupFailure as a3, type ShadowedSkill as a4, type SkillAppliesTo as a5, type SkillCatalog as a6, type SkillInfo as a7, type SkillLoad as a8, type SkillLoadNotice as a9, createEmptyPlan as aA, createSkillsService as aB, createTask as aC, endAttemptUsage as aD, flattenTasks as aE, flattenTasksWithParents as aF, isAwaitingReason as aG, isMeasured as aH, isSupervisorLevel as aI, isUserMessage as aJ, migratePlanState as aK, partedPromptUsage as aL, pausedOnLimit as aM, planUsage as aN, plannerContextFill as aO, rejoinPlanTree as aP, startAttemptUsage as aQ, usageLine as aR, waitsForApproval as aS, type SkillMetadata as aa, type SkillSource as ab, SkillsService as ac, type SubagentOutcome as ad, type SupervisorLevel as ae, type Task as af, type TaskDiffRead as ag, type TaskDiffResult as ah, type TaskIsolation as ai, type TaskIsolationState as aj, type TaskModelAssignment as ak, type TaskSkillNotice as al, type TaskSkillSnapshot as am, type TaskSnapshot as an, type TaskStatus as ao, type TreeSnapshot as ap, type UsageLine as aq, type UsageRecord as ar, type UsageTotals as as, type Verdict as at, type VerificationCheck as au, addAttemptUsage as av, addModelUsage as aw, addPlannerUsage as ax, addUsage as ay, addUsageTotals as az, type AwaitingReason as b, DEFAULT_SUPERVISOR_RETRY_LIMIT as c, type DiscoveredModel as d, type ExecutionCommandName as e, type ExecutionRecord as f, type GuardTrip as g, type IntegrationDisposal as h, type InvalidSkill as i, type IsolationAvailability as j, type IsolationHandoff as k, type IsolationHandoffRepo as l, type IsolationInactiveReason as m, type IsolationLandedTask as n, type IsolationLanding as o, type IsolationMergeBlock as p, type IsolationMergeBlockReason as q, type IsolationMergeResult as r, type IsolationOutcome as s, type IsolationPruneResult as t, type IsolationRemoval as u, type IsolationRepo as v, type IsolationRun as w, type IsolationTaskRecord as x, type IsolationTaskRef as y, type IsolationTaskRepo as z };
@@ -7,10 +7,10 @@ import {
7
7
  plannedTask,
8
8
  stripTrailingCommas,
9
9
  taskWhere
10
- } from "./chunk-3LNZDBCX.mjs";
10
+ } from "./chunk-A57ITQE7.mjs";
11
11
  import {
12
12
  flattenTasksWithParents
13
- } from "./chunk-CIL3BQIF.mjs";
13
+ } from "./chunk-SM6BV6XS.mjs";
14
14
 
15
15
  // src/services/PlanValidator.ts
16
16
  function parsePlanJson(raw, runners, runnerModes, autonomousDefault = true) {
@@ -27,7 +27,7 @@ function parsePlanJson(raw, runners, runnerModes, autonomousDefault = true) {
27
27
  }
28
28
  if (matches.length === 0 && sawUnbalanced) {
29
29
  throw new PlanParseError(
30
- "Plan response appears truncated \u2014 the model likely hit its output length limit before finishing the JSON.",
30
+ "Plan response appears truncated: the model likely hit its output length limit before finishing the JSON.",
31
31
  raw,
32
32
  { truncated: true }
33
33
  );
@@ -67,7 +67,7 @@ function validatePlanTasks(obj, runners, runnerModes, autonomousDefault = true)
67
67
  const ignored = planned.flatMap((p) => p.ignored);
68
68
  const warnings = [
69
69
  ...ignored.some((i) => i.field === "taskMode") ? [`"taskMode" is not yours to set and was ignored: each task runs in its runner's mode for the user's autonomy level, or its read-only mode when you set "readOnly": true.`] : [],
70
- ...ignored.filter((i) => i.field === "readOnly").map((i) => `${i.message} \u2014 it was ignored.`)
70
+ ...ignored.filter((i) => i.field === "readOnly").map((i) => `${i.message}: it was ignored.`)
71
71
  ];
72
72
  return warnings.length > 0 ? { ok: true, tasks, warnings } : { ok: true, tasks };
73
73
  }
@@ -94,4 +94,4 @@ export {
94
94
  validatePlanTasks,
95
95
  looksLikePlanAttempt
96
96
  };
97
- //# sourceMappingURL=chunk-4FEARWTS.mjs.map
97
+ //# sourceMappingURL=chunk-645FALZX.mjs.map