@ordewell/core 0.10.12 → 0.11.1

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 (50) hide show
  1. package/AUTHORS.md +37 -0
  2. package/NOTICE +71 -0
  3. package/README.md +1 -1
  4. package/dist/{IFileSystem-1PqRCjhu.d.mts → IRunner-B5l9PCTv.d.ts} +926 -102
  5. package/dist/{IFileSystem-lTRL_G9Z.d.ts → IRunner-DBgDx_Mr.d.mts} +926 -102
  6. package/dist/{ModeResolver-CoJAJD-f.d.ts → ModeResolver-BDAgouuE.d.mts} +9 -2
  7. package/dist/{ModeResolver-6TQXVsde.d.mts → ModeResolver-DyXeZ9ib.d.ts} +9 -2
  8. package/dist/{Task-CfBM0wkV.d.mts → Task-BL4Idm9r.d.mts} +656 -26
  9. package/dist/{Task-CfBM0wkV.d.ts → Task-BL4Idm9r.d.ts} +656 -26
  10. package/dist/{chunk-ESKK5I4F.mjs → chunk-4QXOWEGC.mjs} +1888 -334
  11. package/dist/chunk-4QXOWEGC.mjs.map +1 -0
  12. package/dist/{chunk-KWS3VEER.mjs → chunk-MYXMIVWA.mjs} +6 -6
  13. package/dist/chunk-MYXMIVWA.mjs.map +1 -0
  14. package/dist/{chunk-PFH7WFIB.mjs → chunk-QTZ5XTBY.mjs} +228 -15
  15. package/dist/chunk-QTZ5XTBY.mjs.map +1 -0
  16. package/dist/{chunk-24EL4Z2W.mjs → chunk-YAFNYNFX.mjs} +342 -36
  17. package/dist/chunk-YAFNYNFX.mjs.map +1 -0
  18. package/dist/index.d.mts +1488 -769
  19. package/dist/index.d.ts +1488 -769
  20. package/dist/index.js +32003 -20350
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +29380 -19553
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/parsing.d.mts +2 -2
  25. package/dist/parsing.d.ts +2 -2
  26. package/dist/parsing.js +232 -25
  27. package/dist/parsing.js.map +1 -1
  28. package/dist/parsing.mjs +3 -3
  29. package/dist/plan-utils.d.mts +4 -4
  30. package/dist/plan-utils.d.ts +4 -4
  31. package/dist/plan-utils.js +1156 -96
  32. package/dist/plan-utils.js.map +1 -1
  33. package/dist/plan-utils.mjs +144 -8
  34. package/dist/{runSettingsText-Jb_efnI4.d.mts → runSettingsText-BKwWs052.d.mts} +2882 -621
  35. package/dist/{runSettingsText-C5uv2axI.d.ts → runSettingsText-CAXiTpsj.d.ts} +2882 -621
  36. package/dist/testing.d.mts +10 -4
  37. package/dist/testing.d.ts +10 -4
  38. package/dist/testing.js +30 -7
  39. package/dist/testing.js.map +1 -1
  40. package/dist/testing.mjs +26 -7
  41. package/dist/testing.mjs.map +1 -1
  42. package/package.json +7 -3
  43. package/skills/diagnose/SKILL.md +52 -0
  44. package/skills/explore/SKILL.md +65 -0
  45. package/dist/chunk-24EL4Z2W.mjs.map +0 -1
  46. package/dist/chunk-ESKK5I4F.mjs.map +0 -1
  47. package/dist/chunk-KWS3VEER.mjs.map +0 -1
  48. package/dist/chunk-NJGID6BG.mjs +0 -115
  49. package/dist/chunk-NJGID6BG.mjs.map +0 -1
  50. package/dist/chunk-PFH7WFIB.mjs.map +0 -1
@@ -1,7 +1,47 @@
1
1
  import { ChildProcess } from 'child_process';
2
- import { a7 as RunnerId, az as UsageRecord, ak as SubagentOutcome, a8 as RunnerSessionCost, f as DiscoveredModel, at as TaskSkillSnapshot } from './Task-CfBM0wkV.mjs';
2
+ import { aS as Task, az as RunnerId, b6 as UsageRecord, aQ as SubagentOutcome, aA as RunnerSessionCost, i as DiscoveredModel, a$ as TaskSkillSnapshot, p as HandoffCheck } from './Task-BL4Idm9r.js';
3
3
  import { z } from 'zod/v4';
4
4
 
5
+ /** A script task's time limit when it sets none. */
6
+ declare const DEFAULT_SCRIPT_TIMEOUT_MS: number;
7
+ /** What a script task runs, its time limit filled in. */
8
+ type ScriptBody =
9
+ /** Argument vectors run in order with no shell, stopping at the first that fails. */
10
+ {
11
+ commands: string[][];
12
+ timeoutMs: number;
13
+ }
14
+ /** One script, run by the research shell's interpreter. */
15
+ | {
16
+ script: string;
17
+ timeoutMs: number;
18
+ };
19
+ type BodyFields = Pick<Task, 'type' | 'commands' | 'script' | 'timeoutMs'>;
20
+ /** The body a script task runs; null for any other task, or one whose body the plan's rules refuse. */
21
+ declare function scriptBodyOf(task: BodyFields): ScriptBody | null;
22
+ /**
23
+ * An argument vector as a reader would type it in a shell: a word is quoted
24
+ * only where it needs to be, and one holding a character a reader cannot see
25
+ * is written with escapes (`$'…'`), so a command is always one line and reads
26
+ * as what runs. For reading only; nothing runs it.
27
+ */
28
+ declare function commandLine(argv: readonly string[]): string;
29
+ /**
30
+ * A script task's body as the approval card shows it (ADR-0035), so the
31
+ * consent is to what will run: each command on a line of its own, or the
32
+ * script as written, then the time limit. A character a reader cannot see in
33
+ * a script, but for its line breaks and tabs, is shown as its code.
34
+ */
35
+ declare function scriptBodyText(body: ScriptBody): string;
36
+ /**
37
+ * A script task as a row shows it: the body {@link scriptBodyText} gives the
38
+ * approval card, so what the user read when consenting is what the plan lists.
39
+ * A task whose body the plan's rules refuse says so rather than showing nothing.
40
+ */
41
+ declare function scriptTaskText(task: BodyFields): string;
42
+ /** A time limit in the largest units it is a whole number of: "10 minutes", "90 seconds". */
43
+ declare function timeLimitText(ms: number): string;
44
+
5
45
  /**
6
46
  * The planner's standing approvals (ADR-0026): what runs without asking
7
47
  * anyone, under every approval mode.
@@ -118,6 +158,23 @@ interface ResearchShell {
118
158
  */
119
159
  utilsDir: string | null;
120
160
  }
161
+ /**
162
+ * How one command starts: the research shell itself, or the sandbox launcher
163
+ * around it (ADR-0011 B6). Either way the command string is appended after
164
+ * `args`, and `file: null` means `shell: true`.
165
+ */
166
+ interface ShellLaunch {
167
+ file: string | null;
168
+ args: readonly string[];
169
+ /** Undefined inherits the host's environment. */
170
+ env?: NodeJS.ProcessEnv;
171
+ /**
172
+ * A sealed run's wall-time limit (ADR-0036 S1): the adapter kills the
173
+ * launch with SIGKILL once it has run this long, in place of its own
174
+ * timeout, and stops waiting for output a moment after it exits.
175
+ */
176
+ wallTimeMs?: number;
177
+ }
121
178
  interface ResearchShellDeps {
122
179
  platform?: NodeJS.Platform;
123
180
  exists?: (candidate: string) => boolean;
@@ -401,6 +458,12 @@ interface ApprovalRequest {
401
458
  scopes?: string[];
402
459
  /** One-line context for the prompt. */
403
460
  detail?: string;
461
+ /**
462
+ * For a `task_start` of a script task: what it runs, verbatim, one command
463
+ * to a line, and its time limit (ADR-0035). Shown in full, since the
464
+ * consent is to it, not to a description.
465
+ */
466
+ body?: string;
404
467
  /** The task whose runner asked; absent for the planner's own requests. */
405
468
  taskId?: string;
406
469
  /** "Allow for this task" can be offered: the runner proposed its own session-scoped grant. */
@@ -472,6 +535,8 @@ interface CatalogModel {
472
535
  completion: string;
473
536
  };
474
537
  contextLength: number;
538
+ /** The longest reply the catalog says the model is served with, when it says. */
539
+ maxOutputTokens?: number;
475
540
  }
476
541
  declare class ModelCatalog {
477
542
  static fetchModels(apiKey: string, baseUrl?: string, fetchImpl?: typeof fetch): Promise<CatalogModel[]>;
@@ -512,6 +577,8 @@ interface OrchestratorOption {
512
577
  pricing?: string;
513
578
  /** The model's context window when the catalog reports one (#49). */
514
579
  contextWindow?: number;
580
+ /** The longest reply the catalog says the model is served with, when it says. */
581
+ maxOutputTokens?: number;
515
582
  }
516
583
 
517
584
  interface FetchAllProviderModelsOptions {
@@ -641,8 +708,16 @@ interface IConfig {
641
708
  approvalPreApproved: string[];
642
709
  /** Whether the built-in allowlist of read-only command families and MCP tools applies. */
643
710
  approvalDefaults: boolean;
711
+ /** The user's effect allowlist rules (ADR-0035, `effectAllowlist.ts`), read on every request. It has no defaults. */
712
+ effectAllowlist: string[];
644
713
  /** How many fetches and searches one planner turn may make (ADR-0027). User-only, like the approval settings. */
645
714
  webReadBudget: number;
715
+ /**
716
+ * Let a harness planner use its own shell beside `run_command` (ADR-0036
717
+ * N1), where the installed version passed the live checks (N2, N4). Off by
718
+ * default, and never a workspace's to choose.
719
+ */
720
+ plannerNativeShell: boolean;
646
721
  /** Get the base URL for an OpenAI-compatible provider. */
647
722
  getProviderBaseUrl(provider: AiProvider): string;
648
723
  /** Get the API key for a provider. */
@@ -655,23 +730,205 @@ interface IConfig {
655
730
  }
656
731
  declare function enabledRunners(cfg: IConfig): RunnerId[];
657
732
 
733
+ interface ToolOutcome {
734
+ success: boolean;
735
+ output: string;
736
+ truncated: boolean;
737
+ /**
738
+ * The child was killed at its time limit, so what it had not finished did
739
+ * not happen (ADR-0036 S1). The adapters set it, and a sealed run's result
740
+ * names the limit it ran out of rather than blaming the command.
741
+ */
742
+ timedOut?: boolean;
743
+ }
744
+ interface ReadFileOpts {
745
+ maxBytes?: number;
746
+ offset?: number;
747
+ limit?: number;
748
+ }
658
749
  /**
659
- * The tools of the Ordewell MCP server, per token role (ADR-0022), and the
660
- * handler interfaces the session side implements to answer them.
661
- *
662
- * Every handler method is optional so each tool can be wired on its own; one
663
- * left unset answers its call with a "not available" error rather than
664
- * disappearing from `tools/list`, so the list a runner sees never depends on
665
- * how far the wiring has got.
750
+ * `content` returns matching lines, `files` only the paths that matched, and
751
+ * `count` a per-file tally. Cheap models otherwise grep and then read whole
752
+ * files to answer "which files touch this", burning rounds against the budget.
753
+ */
754
+ type GrepOutputMode = 'content' | 'files' | 'count';
755
+ interface GrepOptions {
756
+ /** File glob filter, e.g. `*.ts`. */
757
+ include?: string;
758
+ /** Search root. Relative to the workspace unless approved as external. */
759
+ path?: string;
760
+ outputMode?: GrepOutputMode;
761
+ /** Lines of context around each match (`content` mode only). */
762
+ contextBefore?: number;
763
+ contextAfter?: number;
764
+ /** Treat the pattern as a literal string rather than a regex. */
765
+ literal?: boolean;
766
+ caseInsensitive?: boolean;
767
+ /** Global cap on returned rows. Defaults to {@link GREP_DEFAULT_HEAD_LIMIT}. */
768
+ headLimit?: number;
769
+ }
770
+ interface GlobOptions {
771
+ /** Search root. Relative to the workspace unless approved as external. */
772
+ path?: string;
773
+ headLimit?: number;
774
+ }
775
+ interface FindSymbolOptions {
776
+ /** Language id or file extension, e.g. `typescript` or `.go`. Narrows the keyword set. */
777
+ language?: string;
778
+ /** Search root. Relative to the workspace unless approved as external. */
779
+ path?: string;
780
+ }
781
+ /** Global row cap for grep. A per-file cap is not a budget — see PoolFileSystem. */
782
+ declare const GREP_DEFAULT_HEAD_LIMIT = 100;
783
+ /**
784
+ * Directories that are never interesting to a planner and would otherwise eat
785
+ * the result budget. Applied by every search entry point, not just `glob` —
786
+ * `dist/` and `.ordewell/` are frequently not gitignored.
666
787
  */
788
+ declare const SEARCH_EXCLUSIONS: string[];
789
+ interface BashOptions {
790
+ /**
791
+ * Run the command sealed (ADR-0036 S2): no network, no home directory,
792
+ * nothing written reaching the workspace, and nobody asked. Refused where
793
+ * the host has no sandbox to seal it in.
794
+ */
795
+ sealed?: boolean;
796
+ }
797
+ /** Where a read-only task's commands run (ADR-0046). */
798
+ interface TaskShellSite {
799
+ /** Where its commands start, and what their paths are confined to: the task's worktree, or the workspace root when the run does not isolate. */
800
+ cwd: string;
801
+ /** The task's own worktree, the one directory but scratch a sealed run may write; absent without one. */
802
+ writable?: string;
803
+ /**
804
+ * The git worktree roots inside `writable` whose `.git` a sealed run must
805
+ * not rewrite into a repository of its own (ADR-0046): one per repo in a
806
+ * group. Left out, the single `writable` worktree's `.git` is protected.
807
+ */
808
+ worktrees?: readonly string[];
809
+ }
810
+ /**
811
+ * Sealed runs of Ordewell's own scripts in a read-only task's shell, while
812
+ * the shell is held for them (ADR-0050). They are judged by no command rule,
813
+ * since the task did not write them, but run under the task's sealed profile
814
+ * and are checked after as each of its sealed runs is: Ordewell runs no git
815
+ * in a worktree a sealed run wrote anywhere but inside the seal (ADR-0046).
816
+ */
817
+ interface OwnSealedRuns {
818
+ /** The repository roots the task's sealed runs may write: one per repo, none without a worktree. */
819
+ readonly worktrees: readonly string[];
820
+ /** Whether a sealed run has started in the shell: until one has, its worktree holds only what Ordewell checked out. */
821
+ readonly touched: boolean;
822
+ /** The attempt's scratch directory, which a sealed run has as `$TMPDIR` and `$HOME`. */
823
+ readonly scratch: string;
824
+ /** `script` run sealed from `cwd`, one of {@link worktrees}; refused once the shell is stopped, or where no sandbox can seal. */
825
+ run(script: string, cwd: string): Promise<ToolOutcome>;
826
+ }
827
+ /**
828
+ * A read-only task's `run_command` (ADR-0046): the planner's command rules at
829
+ * the task's working directory, with nobody to ask. One per attempt, with a
830
+ * scratch directory of its own; once one of its commands has run sealed,
831
+ * every later one does.
832
+ */
833
+ interface TaskShell {
834
+ run(command: string, signal?: AbortSignal): Promise<ToolOutcome>;
835
+ /**
836
+ * Hold the shell for Ordewell's own `work` (ADR-0050): no command of the
837
+ * task runs until it settles, so nothing changes the worktree between the
838
+ * sealed runs it makes. `signal` stops those runs.
839
+ */
840
+ hold?<T>(work: (runs: OwnSealedRuns) => Promise<T>, signal?: AbortSignal): Promise<T>;
841
+ /** The attempt ended: its scratch directory goes. */
842
+ end(): void;
843
+ }
844
+ interface IFileSystem {
845
+ readFile(path: string, opts?: ReadFileOpts): Promise<ToolOutcome>;
846
+ readFiles(paths: string[]): Promise<ToolOutcome>;
847
+ glob(pattern: string, opts?: GlobOptions): Promise<ToolOutcome>;
848
+ grep(pattern: string, opts?: GrepOptions): Promise<ToolOutcome>;
849
+ listDir(path: string, depth?: number): Promise<ToolOutcome>;
850
+ /**
851
+ * `signal` stops the planning turn this command belongs to: adapters kill
852
+ * the spawned child rather than let it run out its own timeout. The other
853
+ * tools here are short enough that the loop's between-call abort check is
854
+ * indistinguishable from cancelling them mid-flight; a `bash` call is not.
855
+ */
856
+ bash(command: string, signal?: AbortSignal, opts?: BashOptions): Promise<ToolOutcome>;
857
+ /** Definition-first lookup for one symbol. See `symbolPatterns.ts`. */
858
+ findSymbol(symbol: string, opts?: FindSymbolOptions): Promise<ToolOutcome>;
859
+ getWorkspaceRoot(): string;
860
+ /**
861
+ * Inject the human-approval channel for out-of-envelope access. Optional so
862
+ * test doubles stay small; every adapter extending `BaseFileSystem` has it.
863
+ */
864
+ setApproval?(approval: IApproval): void;
865
+ /** Held credentials read live by the outbound secret check. */
866
+ setOutboundSecrets?(secrets: () => Iterable<string>): void;
867
+ /** Where the filesystem tells the session, once, that the planner's shell runs without an OS sandbox here (ADR-0011 B5). */
868
+ setNotice?(notice: (message: string) => void): void;
869
+ /** The session ended: its scratch directory is removed, and the next command starts a fresh one (ADR-0011 B2). */
870
+ endSession?(): void;
871
+ /** Whether a command can run sealed on this host (ADR-0036 S6); where it cannot, the session's one notice says so. */
872
+ canSeal?(): Promise<boolean>;
873
+ /** A read-only task's shell at `site`, held to this session's allowlist and never asking (ADR-0046). */
874
+ taskShell?(site: TaskShellSite): TaskShell;
875
+ }
876
+
667
877
  declare const taskCompleteInput: z.ZodObject<{
668
878
  status: z.ZodEnum<{
669
879
  failed: "failed";
670
- blocked: "blocked";
671
880
  done: "done";
881
+ blocked: "blocked";
672
882
  }>;
673
883
  summary: z.ZodString;
674
884
  reason: z.ZodOptional<z.ZodString>;
885
+ commit: z.ZodOptional<z.ZodObject<{
886
+ subject: z.ZodString;
887
+ body: z.ZodOptional<z.ZodString>;
888
+ }, z.core.$strip>>;
889
+ findings: z.ZodOptional<z.ZodArray<z.ZodObject<{
890
+ severity: z.ZodEnum<{
891
+ blocker: "blocker";
892
+ major: "major";
893
+ minor: "minor";
894
+ info: "info";
895
+ }>;
896
+ title: z.ZodString;
897
+ detail: z.ZodOptional<z.ZodString>;
898
+ evidence: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
899
+ kind: z.ZodLiteral<"file">;
900
+ path: z.ZodString;
901
+ line: z.ZodOptional<z.ZodNumber>;
902
+ }, z.core.$strip>, z.ZodObject<{
903
+ kind: z.ZodLiteral<"commit">;
904
+ sha: z.ZodString;
905
+ repo: z.ZodOptional<z.ZodString>;
906
+ }, z.core.$strip>, z.ZodObject<{
907
+ kind: z.ZodLiteral<"task">;
908
+ task: z.ZodPipe<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodString>;
909
+ finding: z.ZodOptional<z.ZodString>;
910
+ }, z.core.$strip>, z.ZodObject<{
911
+ kind: z.ZodLiteral<"url">;
912
+ url: z.ZodString;
913
+ }, z.core.$strip>]>>>;
914
+ }, z.core.$strip>>>;
915
+ artifacts: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
916
+ kind: z.ZodLiteral<"file">;
917
+ path: z.ZodString;
918
+ line: z.ZodOptional<z.ZodNumber>;
919
+ }, z.core.$strip>, z.ZodObject<{
920
+ kind: z.ZodLiteral<"commit">;
921
+ sha: z.ZodString;
922
+ repo: z.ZodOptional<z.ZodString>;
923
+ }, z.core.$strip>, z.ZodObject<{
924
+ kind: z.ZodLiteral<"task">;
925
+ task: z.ZodPipe<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodString>;
926
+ finding: z.ZodOptional<z.ZodString>;
927
+ }, z.core.$strip>, z.ZodObject<{
928
+ kind: z.ZodLiteral<"url">;
929
+ url: z.ZodString;
930
+ }, z.core.$strip>]>>>;
931
+ report: z.ZodOptional<z.ZodString>;
675
932
  }, z.core.$strip>;
676
933
  declare const checkpointInput: z.ZodObject<{
677
934
  question: z.ZodString;
@@ -682,6 +939,10 @@ declare const listModelsInput: z.ZodObject<{
682
939
  }, z.core.$strip>;
683
940
  declare const runCommandInput: z.ZodObject<{
684
941
  command: z.ZodString;
942
+ sealed: z.ZodOptional<z.ZodBoolean>;
943
+ }, z.core.$strip>;
944
+ declare const taskRunCommandInput: z.ZodObject<{
945
+ command: z.ZodString;
685
946
  }, z.core.$strip>;
686
947
  declare const fetchInput: z.ZodObject<{
687
948
  url: z.ZodString;
@@ -692,6 +953,16 @@ declare const webSearchInput: z.ZodObject<{
692
953
  declare const loadSkillInput: z.ZodObject<{
693
954
  name: z.ZodString;
694
955
  }, z.core.$strip>;
956
+ declare const readTaskInput: z.ZodObject<{
957
+ task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
958
+ attempt: z.ZodOptional<z.ZodNumber>;
959
+ include_report: z.ZodOptional<z.ZodBoolean>;
960
+ }, z.core.$strip>;
961
+ declare const savePatchInput: z.ZodObject<{}, z.core.$strip>;
962
+ declare const applyPatchInput: z.ZodObject<{
963
+ task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
964
+ attempt: z.ZodOptional<z.ZodNumber>;
965
+ }, z.core.$strip>;
695
966
  declare const submitPlanInput: z.ZodObject<{
696
967
  tasks: z.ZodArray<z.ZodObject<{
697
968
  id: z.ZodOptional<z.ZodString>;
@@ -699,8 +970,9 @@ declare const submitPlanInput: z.ZodObject<{
699
970
  title: z.ZodString;
700
971
  description: z.ZodOptional<z.ZodString>;
701
972
  type: z.ZodOptional<z.ZodEnum<{
702
- user: "user";
703
973
  ai: "ai";
974
+ user: "user";
975
+ script: "script";
704
976
  }>>;
705
977
  dependencies: z.ZodOptional<z.ZodArray<z.ZodString>>;
706
978
  prompt: z.ZodOptional<z.ZodString>;
@@ -727,6 +999,14 @@ declare const submitPlanInput: z.ZodObject<{
727
999
  userStoriesCovered: z.ZodOptional<z.ZodArray<z.ZodString>>;
728
1000
  skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
729
1001
  subtasks: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
1002
+ commands: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
1003
+ script: z.ZodOptional<z.ZodString>;
1004
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
1005
+ research: z.ZodOptional<z.ZodBoolean>;
1006
+ loop: z.ZodOptional<z.ZodObject<{
1007
+ body: z.ZodArray<z.ZodString>;
1008
+ maxRounds: z.ZodOptional<z.ZodNumber>;
1009
+ }, z.core.$loose>>;
730
1010
  }, z.core.$loose>>;
731
1011
  }, z.core.$strip>;
732
1012
  declare const editPlanInput: z.ZodObject<{
@@ -763,46 +1043,51 @@ declare const editPlanInput: z.ZodObject<{
763
1043
  declare const taskQueryInput: z.ZodObject<{
764
1044
  tasks: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
765
1045
  fields: z.ZodOptional<z.ZodArray<z.ZodEnum<{
766
- skills: "skills";
1046
+ verdict: "verdict";
767
1047
  description: "description";
768
1048
  prompt: "prompt";
769
1049
  userSteps: "userSteps";
770
- verdict: "verdict";
771
1050
  outputSummary: "outputSummary";
1051
+ handoff: "handoff";
772
1052
  userStoriesCovered: "userStoriesCovered";
1053
+ skills: "skills";
773
1054
  }>>>;
774
1055
  catalog: z.ZodOptional<z.ZodBoolean>;
775
1056
  }, z.core.$strip>;
776
1057
  declare const taskOutputInput: z.ZodObject<{
777
1058
  attempt: z.ZodOptional<z.ZodNumber>;
778
1059
  kinds: z.ZodOptional<z.ZodArray<z.ZodEnum<{
779
- text: "text";
780
1060
  error: "error";
1061
+ handoff: "handoff";
1062
+ text: "text";
781
1063
  command: "command";
782
- thinking: "thinking";
1064
+ task_skills: "task_skills";
1065
+ turn_start: "turn_start";
1066
+ command_output: "command_output";
1067
+ compaction: "compaction";
1068
+ model_switched: "model_switched";
1069
+ runner_loaded: "runner_loaded";
1070
+ turn_end: "turn_end";
1071
+ text_delta: "text_delta";
783
1072
  thinking_delta: "thinking_delta";
1073
+ thinking: "thinking";
784
1074
  tool_call: "tool_call";
785
1075
  tool_result: "tool_result";
786
- usage: "usage";
787
1076
  subagent_started: "subagent_started";
788
1077
  subagent_finished: "subagent_finished";
789
- turn_end: "turn_end";
790
- message_delivered: "message_delivered";
791
- runner_loaded: "runner_loaded";
792
- compaction: "compaction";
793
- command_output: "command_output";
794
- model_switched: "model_switched";
795
- text_delta: "text_delta";
796
- turn_start: "turn_start";
1078
+ usage: "usage";
797
1079
  message_queued: "message_queued";
798
1080
  message_removed: "message_removed";
799
1081
  message_undelivered: "message_undelivered";
800
1082
  message_handed_over: "message_handed_over";
801
- task_skills: "task_skills";
1083
+ message_delivered: "message_delivered";
802
1084
  approval_requested: "approval_requested";
803
1085
  approval_decided: "approval_decided";
804
1086
  approval_withdrawn: "approval_withdrawn";
805
1087
  runner_ended: "runner_ended";
1088
+ script_run: "script_run";
1089
+ script_output: "script_output";
1090
+ script_exit: "script_exit";
806
1091
  }>>>;
807
1092
  task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
808
1093
  lines: z.ZodOptional<z.ZodNumber>;
@@ -835,18 +1120,37 @@ declare const messageTaskInput: z.ZodObject<{
835
1120
  task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
836
1121
  text: z.ZodString;
837
1122
  }, z.core.$strip>;
1123
+ declare const runScriptInput: z.ZodObject<{
1124
+ title: z.ZodString;
1125
+ commands: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
1126
+ script: z.ZodOptional<z.ZodString>;
1127
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
1128
+ dependencies: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
1129
+ }, z.core.$strip>;
838
1130
  declare const answerApprovalInput: z.ZodObject<{
839
1131
  task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
840
1132
  approval: z.ZodOptional<z.ZodString>;
841
1133
  answer: z.ZodString;
842
1134
  note: z.ZodOptional<z.ZodString>;
843
1135
  }, z.core.$strip>;
1136
+ declare const answerCheckpointInput: z.ZodObject<{
1137
+ task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
1138
+ answer: z.ZodEnum<{
1139
+ approve: "approve";
1140
+ reject: "reject";
1141
+ }>;
1142
+ reason: z.ZodOptional<z.ZodString>;
1143
+ }, z.core.$strip>;
844
1144
  type TaskCompleteArgs = z.infer<typeof taskCompleteInput>;
845
1145
  type CheckpointArgs = z.infer<typeof checkpointInput>;
1146
+ type ReadTaskArgs = z.infer<typeof readTaskInput>;
1147
+ type SavePatchArgs = z.infer<typeof savePatchInput>;
1148
+ type ApplyPatchArgs = z.infer<typeof applyPatchInput>;
846
1149
  type ListRunnersArgs = z.infer<typeof listRunnersInput>;
847
1150
  type ListModelsArgs = z.infer<typeof listModelsInput>;
848
1151
  type LoadSkillArgs = z.infer<typeof loadSkillInput>;
849
1152
  type RunCommandArgs = z.infer<typeof runCommandInput>;
1153
+ type TaskRunCommandArgs = z.infer<typeof taskRunCommandInput>;
850
1154
  type FetchArgs = z.infer<typeof fetchInput>;
851
1155
  type WebSearchArgs = z.infer<typeof webSearchInput>;
852
1156
  type SubmitPlanArgs = z.infer<typeof submitPlanInput>;
@@ -860,6 +1164,8 @@ type RetryTaskArgs = z.infer<typeof retryTaskInput>;
860
1164
  type MessageTaskArgs = z.infer<typeof messageTaskInput>;
861
1165
  type SkipTaskArgs = z.infer<typeof skipTaskInput>;
862
1166
  type AnswerApprovalArgs = z.infer<typeof answerApprovalInput>;
1167
+ type AnswerCheckpointArgs = z.infer<typeof answerCheckpointInput>;
1168
+ type RunScriptArgs = z.infer<typeof runScriptInput>;
863
1169
  /** What a handler answers with. `isError` marks a refusal the caller should act on. */
864
1170
  interface McpToolReply {
865
1171
  text: string;
@@ -887,6 +1193,17 @@ type Run<A> = (args: A, context: McpToolContext) => Promise<McpToolReply>;
887
1193
  interface TaskToolHandler {
888
1194
  taskComplete?: Run<TaskCompleteArgs>;
889
1195
  checkpoint?: Run<CheckpointArgs>;
1196
+ /** A handoff the task may read (ADR-0047), from its attempt's log. */
1197
+ readTask?: Run<ReadTaskArgs>;
1198
+ /** A read-only task's shell (ADR-0046); only its token lists `run_command`. */
1199
+ runCommand?: Run<TaskRunCommandArgs>;
1200
+ /** A read-only task's prototype kept as a patch (ADR-0050); only its token lists `save_patch`. */
1201
+ savePatch?: Run<SavePatchArgs>;
1202
+ /** A saved patch applied into the task's own worktree (ADR-0050); a read-only task's token does not list `apply_patch`. */
1203
+ applyPatch?: Run<ApplyPatchArgs>;
1204
+ /** A read-only task's web reads, decided by the session's web-read policy (ADR-0046, ADR-0027); only its token lists `fetch` and `web_search`. */
1205
+ fetch?: Run<FetchArgs>;
1206
+ webSearch?: Run<WebSearchArgs>;
890
1207
  }
891
1208
  interface PlannerToolHandler {
892
1209
  loadSkill?: Run<LoadSkillArgs>;
@@ -908,7 +1225,9 @@ interface PlannerToolHandler {
908
1225
  skipTask?: Run<SkipTaskArgs>;
909
1226
  messageTask?: Run<MessageTaskArgs>;
910
1227
  answerApproval?: Run<AnswerApprovalArgs>;
1228
+ answerCheckpoint?: Run<AnswerCheckpointArgs>;
911
1229
  mergeAll?: Run<RunPlanArgs>;
1230
+ runScript?: Run<RunScriptArgs>;
912
1231
  }
913
1232
  interface McpTool<H> {
914
1233
  name: string;
@@ -931,7 +1250,24 @@ declare const TASK_COMPLETE_TOOL = "task_complete";
931
1250
  * message into a summary, while its instructions are re-applied whole.
932
1251
  */
933
1252
  declare const TASK_COMPLETION_CONTRACT: string;
1253
+ /** The completion contract for one attempt: only one whose work lands as a commit is asked for its message (ADR-0047). */
1254
+ declare function taskCompletionContract(opts: {
1255
+ commits?: true;
1256
+ }): string;
1257
+ /**
1258
+ * A task that works in the tree: the shared tools, and `apply_patch`, which
1259
+ * brings a prototype a read-only task saved (ADR-0050) into its worktree.
1260
+ */
934
1261
  declare const TASK_TOOLS: readonly McpTool<TaskToolHandler>[];
1262
+ /**
1263
+ * A read-only task's tools (ADR-0046): the task tools, `run_command`, its
1264
+ * only shell, `save_patch`, which keeps what that shell changed as a patch
1265
+ * (ADR-0050), and `fetch` and `web_search`, its only web reads, which the
1266
+ * host carries under the session's web-read policy (ADR-0027). Their hints
1267
+ * describe their landing effects: nothing any of them changes reaches the
1268
+ * plan's branches.
1269
+ */
1270
+ declare const READ_ONLY_TASK_TOOLS: readonly McpTool<TaskToolHandler>[];
935
1271
  /**
936
1272
  * The planner's execution tools (ADR-0029, #91): each call goes to the
937
1273
  * session's command seam, which checks it, asks the user where consent needs
@@ -955,6 +1291,8 @@ interface TaskTokenScope {
955
1291
  taskId: string;
956
1292
  /** The attempt generation the token is good for; a later attempt gets a new token. */
957
1293
  attempt: number;
1294
+ /** A read-only task's attempt (ADR-0046): its token lists `run_command`, `fetch` and `web_search` too, and no other task's does. */
1295
+ readOnly?: boolean;
958
1296
  }
959
1297
  interface PlannerTokenScope {
960
1298
  sessionId: string;
@@ -971,9 +1309,22 @@ interface McpCredential {
971
1309
  token: string;
972
1310
  /** The planner tools the token hides ({@link PlannerTokenScope.hidden}), so the runner is told of and pre-allows only what it is served. */
973
1311
  hidden?: readonly string[];
1312
+ /** The token serves a read-only task's tools ({@link TaskTokenScope.readOnly}), so the runner is told of and pre-allows `run_command`, `fetch` and `web_search`. */
1313
+ readOnly?: true;
974
1314
  }
1315
+ /**
1316
+ * Why the server refused a request before any tool ran, kept apart in the
1317
+ * count so a planner that lost its link can be told from one that never had
1318
+ * one: an unknown token is a stale URL or a client that was never issued one,
1319
+ * a revoked token is a session that ended or a process that was respawned, and
1320
+ * a wrong path is a client pointed somewhere other than `/mcp`.
1321
+ */
1322
+ type McpRefusal = 'unknownToken' | 'revokedToken' | 'wrongPath';
975
1323
  declare class OrdewellMcpServer {
976
1324
  private readonly grants;
1325
+ /** Recently revoked tokens, so a request carrying one is told from a token that never existed. */
1326
+ private readonly revokedTokens;
1327
+ private readonly refused;
977
1328
  private http;
978
1329
  private listening;
979
1330
  private boundUrl;
@@ -982,6 +1333,12 @@ declare class OrdewellMcpServer {
982
1333
  constructor(options?: OrdewellMcpServerOptions);
983
1334
  /** The listener's URL, once the first token has started it. */
984
1335
  get url(): string | undefined;
1336
+ /**
1337
+ * How many requests this server refused, by reason, since it started. What
1338
+ * makes a planner whose tools went dead visible after the fact; no token,
1339
+ * path or header is kept here.
1340
+ */
1341
+ refusals(): Readonly<Record<McpRefusal, number>>;
985
1342
  issueTaskToken(scope: TaskTokenScope, handler?: TaskToolHandler): Promise<McpCredential>;
986
1343
  issuePlannerToken(scope: PlannerTokenScope, handler?: PlannerToolHandler): Promise<McpCredential>;
987
1344
  /** Every token still good here: secrets the outbound check keeps out of a URL (ADR-0027). */
@@ -992,6 +1349,8 @@ declare class OrdewellMcpServer {
992
1349
  private issue;
993
1350
  private start;
994
1351
  private handle;
1352
+ /** Count one refusal, and say the first of its kind once: a runner retrying a dead token must not flood the log. */
1353
+ private refuse;
995
1354
  }
996
1355
  /** The process's one server, which the daemon and the extension host hand to every session they build. */
997
1356
  declare function sharedMcpServer(): OrdewellMcpServer;
@@ -1004,6 +1363,8 @@ interface McpClientConfig {
1004
1363
  headers: Record<string, string>;
1005
1364
  /** Planner tools the token hides: a runner must neither pre-allow nor mention them. */
1006
1365
  hidden?: readonly string[];
1366
+ /** A read-only task's token (ADR-0046): `run_command`, `fetch` and `web_search` are among its tools, for the runner to pre-allow and name. */
1367
+ readOnly?: true;
1007
1368
  }
1008
1369
  /**
1009
1370
  * The one shape every runner adapter renders its own MCP configuration from.
@@ -1074,6 +1435,328 @@ interface RunnerMcpServer {
1074
1435
  /** The command `name` names, by its own name or an alias. */
1075
1436
  declare function findRunnerCommand(commands: readonly RunnerCommand[], name: string): RunnerCommand | undefined;
1076
1437
 
1438
+ /**
1439
+ * The one seam an OS sandbox sits behind (ADR-0011 B6). A backend turns "run
1440
+ * this POSIX shell" into "run this launcher, which runs the shell under a
1441
+ * policy": the launcher and its policy become the `file` and the leading
1442
+ * `args`, and the caller appends the command string last, exactly as it would
1443
+ * to the bare shell. The string the classifier read is the string that runs.
1444
+ *
1445
+ * A sandbox shares nothing with another: no daemon, no image, no state beyond
1446
+ * what its profile names. A container, microVM or hosted backend for an
1447
+ * execution lease (#97) is another implementation of this interface, and its
1448
+ * callers do not change.
1449
+ */
1450
+ /**
1451
+ * A `.git` entry the checkout brought, which a sealed run may not change
1452
+ * (ADR-0046). Whether it is a directory decides how a backend refuses a write
1453
+ * into it: its whole subtree, or just the file.
1454
+ */
1455
+ interface SandboxGitEntry {
1456
+ path: string;
1457
+ directory: boolean;
1458
+ }
1459
+ /**
1460
+ * What one command may touch. Every path is absolute, and canonical
1461
+ * (symlinks resolved) wherever the backend matches the path the kernel
1462
+ * resolves, as Seatbelt does.
1463
+ */
1464
+ interface SandboxProfile {
1465
+ /** Directories the command may write, recursively. Nothing else can be written. */
1466
+ write: readonly string[];
1467
+ /**
1468
+ * Of `write`, those the command may not put a symbolic link in, nor move
1469
+ * one into: what is read there outside the sandbox, as the user, would
1470
+ * follow it (ADR-0046). A backend that cannot refuse a link by its type
1471
+ * refuses the profile.
1472
+ */
1473
+ linkless?: readonly string[];
1474
+ /**
1475
+ * Of `write`, the worktree roots whose own `.git` a command may neither
1476
+ * write, replace, rename nor remove (ADR-0046). A worktree's `.git` is a
1477
+ * file pointing into its repository; a command that rewrote it would make
1478
+ * git load a repository of the command's own when it runs there outside the
1479
+ * sandbox, as the user. The root itself is held still too: a command that
1480
+ * renamed it could plant a `.git` outside the profile and move it back.
1481
+ */
1482
+ gitWorktrees?: readonly string[];
1483
+ /**
1484
+ * Of `write`, every `.git` entry the checkout brought — a submodule's file, a
1485
+ * vendored repository — which a command may not change either: the literal
1486
+ * path for a file, everything under it for a directory (ADR-0046).
1487
+ */
1488
+ gitEntries?: readonly SandboxGitEntry[];
1489
+ /**
1490
+ * Of `write`, directories in which a command may not create a `.git`, at
1491
+ * their root or beneath it, for the same reason (ADR-0046). A backend that
1492
+ * cannot refuse a name being created refuses the profile.
1493
+ */
1494
+ gitless?: readonly string[];
1495
+ /**
1496
+ * What the command may read besides `write`. `'host'` is the whole
1497
+ * filesystem: the planner's reads are confined by ADR-0008's path check,
1498
+ * not here (ADR-0011 B2). A list confines reads to those paths, for a
1499
+ * profile that must not see the user's files (ADR-0036 S1). Bubblewrap
1500
+ * mounts a listed link where it is named, so `/bin` still starts programs
1501
+ * on a system where it links to `/usr/bin`.
1502
+ */
1503
+ read: 'host' | readonly string[];
1504
+ /**
1505
+ * Listed directories mounted with a throwaway overlay: a write there
1506
+ * succeeds and is gone when the command ends, so a tool that writes a cache
1507
+ * beside the code still runs (ADR-0036 S1). A backend without one refuses
1508
+ * the profile, a host too old for one fails its probe, and either way the
1509
+ * caller asks again with the directory read-only.
1510
+ */
1511
+ throwaway?: readonly string[];
1512
+ /** Directories the command cannot see into although `read` covers them: where local services listen that would write on its behalf. */
1513
+ masked?: readonly string[];
1514
+ network: boolean;
1515
+ /** The host's `/tmp` out of the command's sight: an empty one of its own where the backend can mount one, none at all where it cannot. */
1516
+ privateTmp?: boolean;
1517
+ /**
1518
+ * Whether a networked command reaches the keychain, where `gh` and git's
1519
+ * credential helpers keep the user's tokens (B3). Defaults to true for an
1520
+ * approved command; a native shell must not have it (ADR-0036 N2.2).
1521
+ */
1522
+ keychain?: boolean;
1523
+ /**
1524
+ * Whether a networked command reaches what listens on this machine itself:
1525
+ * loopback addresses and Unix sockets. Defaults to true. A native shell must
1526
+ * not: the harness's own server and Ordewell's daemon listen there and act
1527
+ * outside the sandbox for whoever holds their password, which a macOS
1528
+ * command can read from their environments (ADR-0036 N2).
1529
+ */
1530
+ localNetwork?: boolean;
1531
+ /** Set over the environment the command inherits. */
1532
+ env: Readonly<Record<string, string>>;
1533
+ /** The variables the command keeps from the host's environment; absent keeps them all. Its credentials live there too. */
1534
+ inheritEnv?: readonly string[];
1535
+ limits?: SandboxLimits;
1536
+ }
1537
+ /**
1538
+ * Held by the kernel's resource limits, set before the launcher starts, and
1539
+ * by the caller's clock (ADR-0036 S1).
1540
+ */
1541
+ interface SandboxLimits {
1542
+ /** Processes the command may start beyond those its user already runs, which the kernel's limit counts too. */
1543
+ processes: number;
1544
+ /**
1545
+ * Bytes of address space any one of its processes may map. On macOS, where
1546
+ * every program maps hundreds of gigabytes as it starts, it is counted on
1547
+ * top of that.
1548
+ */
1549
+ memoryBytes: number;
1550
+ /** Milliseconds before the caller kills the command, and with it every process it started. */
1551
+ wallTimeMs: number;
1552
+ }
1553
+ /** The unsandboxed shell: a POSIX shell that takes the command string after `shellArgs`. */
1554
+ interface SandboxInvocation {
1555
+ shell: string;
1556
+ shellArgs: readonly string[];
1557
+ /** The environment the shell would have run with. */
1558
+ env: NodeJS.ProcessEnv;
1559
+ }
1560
+ /** What to spawn instead. The command string is appended after `args`. */
1561
+ interface SandboxLaunch {
1562
+ file: string;
1563
+ args: string[];
1564
+ env: NodeJS.ProcessEnv;
1565
+ /** The profile's wall-time limit: the caller kills the launch with SIGKILL once it has run this long. */
1566
+ wallTimeMs?: number;
1567
+ }
1568
+ type SandboxProbe = {
1569
+ ok: true;
1570
+ } | {
1571
+ ok: false;
1572
+ detail: string;
1573
+ };
1574
+ interface SandboxBackend {
1575
+ /** How the notice and a skipped test name it. */
1576
+ readonly name: string;
1577
+ /** Start a trivial command under `profile`: whether this host can run the sandbox at all (ADR-0011 B5). */
1578
+ probe(profile: SandboxProfile): Promise<SandboxProbe>;
1579
+ /** Builds the launch without starting anything, and throws {@link SandboxUnsupportedError} for a profile it cannot enforce. */
1580
+ wrap(invocation: SandboxInvocation, profile: SandboxProfile): SandboxLaunch;
1581
+ }
1582
+ type ProbeExec = (file: string, args: string[], env: NodeJS.ProcessEnv) => Promise<{
1583
+ code: number | null;
1584
+ output: string;
1585
+ }>;
1586
+
1587
+ /**
1588
+ * The planner's shell inside an OS sandbox (ADR-0011): every command the
1589
+ * planner's `bash` tool, its research subagents and a harness planner's
1590
+ * `run_command` start runs where nothing outside one scratch directory per
1591
+ * session can be written. It sits underneath the classifier and changes
1592
+ * nothing about which commands are `auto`, `ask` or `refuse` (B1). Where it
1593
+ * runs, a command the envelope would refuse without asking can run sealed
1594
+ * instead, under a stricter profile of its own (ADR-0036 S1, S2).
1595
+ */
1596
+ declare const PLANNER_SANDBOX_DOCS = "https://github.com/ordewell/ordewell/blob/main/docs/troubleshooting.md#planner-shell-not-sandboxed";
1597
+ /** Where a sealed run starts: the workspace it reads, and the one other directory, if any, it may write (ADR-0036 S1). */
1598
+ interface SealedRunOptions {
1599
+ workspace: string;
1600
+ /** None by default, so the workspace stays read-only. A read-only task passes its own throwaway worktree (ADR-0046). */
1601
+ writable?: string;
1602
+ /**
1603
+ * The git worktree roots inside `writable` whose own `.git` a sealed run
1604
+ * must not rewrite into a repository of its own (ADR-0046). A repo group
1605
+ * passes one per repo; left out, the single `writable` worktree is used.
1606
+ */
1607
+ worktrees?: readonly string[];
1608
+ /**
1609
+ * Every `.git` entry the writable directory held before the task's first
1610
+ * sealed run, which a sealed run may not change (ADR-0046). The worktree
1611
+ * roots above cover their own `.git`; this covers a submodule's file and a
1612
+ * vendored repository, whose content a run could otherwise rearm.
1613
+ */
1614
+ gitEntries?: readonly SandboxGitEntry[];
1615
+ /**
1616
+ * A harness's short per-session temporary directory, writable besides the
1617
+ * scratch one (ADR-0036 N2). A native shell needs it: Claude Code writes the
1618
+ * shell's working directory there after every command.
1619
+ */
1620
+ tmpdir?: string;
1621
+ /**
1622
+ * The network the harness gives its own shell (ADR-0036 N3). A sealed run has
1623
+ * none (S1); only the native-shell opt-in asks for this profile with one.
1624
+ */
1625
+ network?: boolean;
1626
+ /**
1627
+ * Whether the keychain is in reach with that network. Defaults to true, as
1628
+ * for an approved command; a native shell passes false (N2.2).
1629
+ */
1630
+ keychain?: boolean;
1631
+ /** Whether that network reaches loopback and this machine's Unix sockets. Defaults to true; a native shell passes false (N2). */
1632
+ localNetwork?: boolean;
1633
+ /**
1634
+ * The limits the sealed run is held to (ADR-0036 S1). {@link SEALED_LIMITS}
1635
+ * by default; a read-only task passes {@link TASK_SEALED_LIMITS}, since its
1636
+ * one shell is where it runs the project's tests (ADR-0046).
1637
+ */
1638
+ limits?: SandboxLimits;
1639
+ }
1640
+ type SealedAvailability = {
1641
+ available: true;
1642
+ /** The sealed profile on this host; without a scratch directory, nothing is writable. */
1643
+ profile: (opts: SealedRunOptions & {
1644
+ scratch?: string;
1645
+ }) => SandboxProfile;
1646
+ }
1647
+ /** The session's one notice where the sandbox runs but cannot start a sealed run (S6). */
1648
+ | {
1649
+ available: false;
1650
+ notice: string;
1651
+ };
1652
+ type PlannerSandboxAvailability = {
1653
+ available: true;
1654
+ backend: SandboxBackend;
1655
+ /** The planner's profile on this host; without a scratch directory, nothing is writable. */
1656
+ profile: (opts: {
1657
+ scratch?: string;
1658
+ network: boolean;
1659
+ }) => SandboxProfile;
1660
+ sealed: SealedAvailability;
1661
+ }
1662
+ /** The one notice the planner surface shows a session (B5). */
1663
+ | {
1664
+ available: false;
1665
+ notice: string;
1666
+ };
1667
+ interface PlannerSandboxDeps {
1668
+ platform?: NodeJS.Platform;
1669
+ /** An existing directory a sealed probe can mount as its workspace. */
1670
+ probeWorkspace?: string;
1671
+ env?: NodeJS.ProcessEnv;
1672
+ exists?: (file: string) => boolean;
1673
+ /** An existing path's canonical form and whether it is a directory, or null. */
1674
+ stat?: (p: string) => {
1675
+ canonical: string;
1676
+ directory: boolean;
1677
+ } | null;
1678
+ uid?: number;
1679
+ exec?: ProbeExec;
1680
+ }
1681
+ /** Enough for a loop over a repository's files, a pipeline or a short script; not for a build. */
1682
+ declare const SEALED_LIMITS: SandboxLimits;
1683
+ /**
1684
+ * A read-only task's sealed runs (ADR-0046): the same resources, with the ten
1685
+ * minutes a script task gets by default, since its one shell is where the task
1686
+ * runs the project's tests and a suite does not fit in a minute.
1687
+ */
1688
+ declare const TASK_SEALED_LIMITS: SandboxLimits;
1689
+ /**
1690
+ * Whether this host can sandbox the planner's shell, and how. Probed once per
1691
+ * process with a trivial command (B5): the answer cannot change while
1692
+ * Ordewell runs, and concurrent first commands share one probe. Injected
1693
+ * dependencies bypass the cache, as {@link resolveResearchShell}'s do.
1694
+ */
1695
+ declare function resolvePlannerSandbox(deps?: PlannerSandboxDeps): Promise<PlannerSandboxAvailability>;
1696
+ /** Test seam: drop the per-process probe so the next call probes again. */
1697
+ declare function clearPlannerSandboxCache(): void;
1698
+ /** The research shell as one command should start, and whether that is inside the sandbox. */
1699
+ interface PlannerShellLaunch {
1700
+ launch: ShellLaunch;
1701
+ sandboxed: boolean;
1702
+ }
1703
+ /**
1704
+ * One session's view of the sandbox: its scratch directory, made on the first
1705
+ * command and removed when the session ends, and its one notice when the
1706
+ * sandbox, or a sealed run in it, cannot run here.
1707
+ */
1708
+ declare class PlannerShellSandbox {
1709
+ private readonly resolve;
1710
+ private scratch;
1711
+ private noticed;
1712
+ private notice;
1713
+ constructor(resolve?: () => Promise<PlannerSandboxAvailability>);
1714
+ setNotice(notice: (message: string) => void): void;
1715
+ /** The same host's sandbox for another caller, with a scratch directory of its own: a read-only task's (ADR-0046). */
1716
+ withOwnScratch(): PlannerShellSandbox;
1717
+ /**
1718
+ * The launch for one command (B6): the research shell wrapped in the
1719
+ * sandbox, with the network as the caller's tier allows (B3), or the shell
1720
+ * itself where no sandbox runs, after saying so once (B5). Throws when the
1721
+ * sandbox runs here but this command cannot be put in it, so a command is
1722
+ * never run outside a sandbox that exists.
1723
+ */
1724
+ launch(shell: ResearchShell, opts: {
1725
+ network: boolean;
1726
+ }): Promise<PlannerShellLaunch>;
1727
+ /** Whether a command can run sealed here (ADR-0036 S6). Where it cannot, the session's one notice says so. */
1728
+ canSeal(): Promise<boolean>;
1729
+ /**
1730
+ * The launch for one sealed run (S1), in this session's scratch directory.
1731
+ * Throws where sealed runs are unavailable, which {@link canSeal} answers
1732
+ * first, and for a shell the sandbox cannot wrap.
1733
+ */
1734
+ launchSealed(shell: ResearchShell, opts: SealedRunOptions): Promise<ShellLaunch>;
1735
+ /**
1736
+ * The launch for a harness's own shell (ADR-0036 N2): the same sealed profile
1737
+ * as a sealed run, with the network the harness gives it (N3), plus the
1738
+ * harness's short temporary directory. The workspace stays read-only. Throws
1739
+ * where the sandbox cannot run, so a caller never falls back to the bare shell.
1740
+ */
1741
+ launchNativeShell(opts: {
1742
+ workspace: string;
1743
+ tmpdir: string;
1744
+ shell: string;
1745
+ shellArgs?: readonly string[];
1746
+ env?: NodeJS.ProcessEnv;
1747
+ }): Promise<SandboxLaunch>;
1748
+ /** The scratch directory every launch here gets as `$TMPDIR` and `$HOME`, made if it is not there. */
1749
+ scratchPath(): string;
1750
+ /** The session ended: its scratch directory goes, and a next session starts with a fresh one and its own notice. */
1751
+ end(): void;
1752
+ private say;
1753
+ private invocation;
1754
+ private scratchDir;
1755
+ }
1756
+
1757
+ /** A runner's report on the Ordewell server's connection, in one vocabulary for every runner. */
1758
+ type AttachState = 'connected' | 'pending' | 'failed';
1759
+
1077
1760
  /**
1078
1761
  * The harness-planner transport contract (ADR-0009).
1079
1762
  *
@@ -1322,6 +2005,12 @@ type PlannerAsk =
1322
2005
  path: string;
1323
2006
  directory: boolean;
1324
2007
  }
2008
+ /** A command through the harness's own shell, allowed by the user's opt-in and held in Ordewell's sandbox (ADR-0036 N2, N3). */
2009
+ | {
2010
+ kind: 'native-shell';
2011
+ tool: string;
2012
+ command?: string;
2013
+ }
1325
2014
  /** `note` is why, for a tool the runner knows the planner must not use, in place of the envelope's generic refusal. */
1326
2015
  | {
1327
2016
  kind: 'other';
@@ -1358,6 +2047,13 @@ interface PlannerStartOptions extends AgentStartCommon {
1358
2047
  * means off.
1359
2048
  */
1360
2049
  nativeSearch?: boolean;
2050
+ /**
2051
+ * Whether the user let this planner use its harness's own shell beside
2052
+ * Ordewell's tools (ADR-0036 N1). The caller sets it only for a version that
2053
+ * passed N2's live checks (see `nativeShellOffer`); absent means off. When
2054
+ * true, the adapter puts every command in Ordewell's sealed profile (N2).
2055
+ */
2056
+ nativeShell?: boolean;
1361
2057
  /**
1362
2058
  * The repository's own MCP servers this planner may start, as approved
1363
2059
  * (ADR-0028). The runner is launched without the repository's config, so
@@ -1371,6 +2067,8 @@ interface PlannerStartOptions extends AgentStartCommon {
1371
2067
  * The adapter adds only its protocol flags around these.
1372
2068
  */
1373
2069
  interface TaskRunnerFlags {
2070
+ /** Ordewell's read-only profile, independent of the runner's native modes (ADR-0046). */
2071
+ readOnly?: true;
1374
2072
  /** The runner's own permission-mode value for the task's mode. */
1375
2073
  permissionMode: string;
1376
2074
  /** The task's raw effort id, present only alongside a model. Each adapter maps it to its own protocol. */
@@ -1381,9 +2079,13 @@ interface TaskRunnerFlags {
1381
2079
  /** A plan task driven over the runner's programmatic protocol (ADR-0018, C1). */
1382
2080
  interface TaskStartOptions extends AgentStartCommon {
1383
2081
  kind: 'task';
2082
+ /** The session workspace, also readable when cwd is an isolated task worktree (ADR-0046). */
2083
+ workspaceRoot?: string;
1384
2084
  /** The task's runner mode id, as the plan names it. */
1385
2085
  mode: string;
1386
2086
  flags: TaskRunnerFlags;
2087
+ /** The attempt's work lands as a commit (ADR-0047): its completion contract asks for the message. */
2088
+ commits?: true;
1387
2089
  /**
1388
2090
  * The Ordewell MCP server and this attempt's token (ADR-0022), injected
1389
2091
  * with its tools pre-approved. A task is never started without it: its
@@ -1423,6 +2125,13 @@ interface AgentAdapter {
1423
2125
  send(message: string, onEvent: (event: AgentEvent) => void, signal?: AbortSignal, onActivity?: () => void): Promise<void>;
1424
2126
  /** The agent's native session id once it has announced one. Resumption hint only. */
1425
2127
  nativeSessionId(): string | null;
2128
+ /**
2129
+ * The installed version the agent reported, once it has (ADR-0036 N2):
2130
+ * Claude Code's `claude_code_version` on its first `init`, an OpenCode 2.x
2131
+ * server's `/api/info`. Null while unknown, and on OpenCode 1.x, which does
2132
+ * not report one.
2133
+ */
2134
+ version?(): string | null;
1426
2135
  /** What has been counted of the session's running cost, for a runner that reports one; null while unknown. */
1427
2136
  sessionCost?(): RunnerSessionCost | null;
1428
2137
  /** Kill the process and release its resources. Idempotent. */
@@ -1433,8 +2142,17 @@ interface AgentAdapter {
1433
2142
  * Whether the Ordewell MCP server passed in the start options' `mcp` is
1434
2143
  * connected, as the runner itself reports it (ADR-0022, S4). Absent on an
1435
2144
  * adapter that cannot inject the server at all, which cannot run tasks.
2145
+ * `false` is the old boolean answer for "not attached"; a real adapter says
2146
+ * `pending` while its process is still starting, or `failed` when the
2147
+ * runner reports the server cannot connect.
1436
2148
  */
1437
- mcpAttached?(): Promise<boolean>;
2149
+ mcpAttached?(): Promise<boolean | AttachState>;
2150
+ /**
2151
+ * Registers a listener for the process ending, for any reason; a planner
2152
+ * reads it to tell a runner that exited while it started. Fires at most
2153
+ * once. `lastWords` is how it ended, with its stderr tail.
2154
+ */
2155
+ onProcessExit?(listener: (code: number, lastWords?: string) => void): void;
1438
2156
  /**
1439
2157
  * The approved project servers (ADR-0028) this runner started but cannot
1440
2158
  * give the planner as tools of their own, known once `start` resolved.
@@ -1458,7 +2176,7 @@ interface AgentAdapter {
1458
2176
  }
1459
2177
  /** What an adapter adds to run a task rather than a planner (ADR-0018). */
1460
2178
  interface TaskModeAgentAdapter extends AgentAdapter {
1461
- mcpAttached(): Promise<boolean>;
2179
+ mcpAttached(): Promise<boolean | AttachState>;
1462
2180
  /**
1463
2181
  * Ask the running turn to stop, keeping the process and its session. Resolves
1464
2182
  * true once the agent acknowledged it; the turn then ends with
@@ -1537,6 +2255,8 @@ interface AgentProcessDeps {
1537
2255
  exists?: (candidate: string) => boolean;
1538
2256
  /** The workspace's own variables for a cwd (ADR-0016). Defaults to {@link resolveWorkspaceEnv}. */
1539
2257
  workspaceEnv?: (cwd: string) => Promise<Record<string, string>>;
2258
+ /** Builds the sandbox around a planner's own shell (ADR-0036 N2). Defaults to the host's probe. */
2259
+ nativeShellSandbox?: () => PlannerShellSandbox;
1540
2260
  }
1541
2261
  /** Builds the adapter for one runner id, or null when that runner cannot plan. */
1542
2262
  type AgentAdapterFactory = (runner: string, deps: AgentProcessDeps) => AgentAdapter | null;
@@ -1563,6 +2283,54 @@ interface RunnerManifest {
1563
2283
  contextFile?: string;
1564
2284
  contextFileAltPath?: string;
1565
2285
  modes?: RunnerMode[];
2286
+ /** How to ask whether the user is signed in. Absent when the runner offers no status command. */
2287
+ auth?: RunnerAuthSpec;
2288
+ }
2289
+ /** What a runner's status command answered, with both streams kept apart. */
2290
+ interface RunnerAuthStatus {
2291
+ /** The exit status; never negative, since a timeout or a failed spawn is not an answer. */
2292
+ code: number;
2293
+ stdout: string;
2294
+ stderr: string;
2295
+ /** stdout and stderr together, for a reader that matches a line on either. */
2296
+ output: string;
2297
+ /** The merged probe environment, so a reader can consult the config the command read. */
2298
+ env: NodeJS.ProcessEnv;
2299
+ /**
2300
+ * What the answer is: the status command's output, or a failed turn's own
2301
+ * words. A reader that parses the status output (JSON, say) cannot parse
2302
+ * the turn's message, and one that judges a turn's words by the runner's
2303
+ * config must not let the probe's exit code guess for it.
2304
+ */
2305
+ kind: 'status' | 'turn';
2306
+ }
2307
+ /**
2308
+ * A runner's own answer to "is the user signed in?" — the CLI args that ask,
2309
+ * the args that log in, and how to read the answer. Declared here because a
2310
+ * surface must run the same login the runner's own CLI would, with no second
2311
+ * table to drift.
2312
+ */
2313
+ interface RunnerAuthSpec {
2314
+ /** The CLI args that answer whether the user is signed in, e.g. `auth status`. */
2315
+ statusArgs: string[];
2316
+ /** The CLI args that run the login, e.g. `auth login`. */
2317
+ loginArgs: string[];
2318
+ /**
2319
+ * Matched against the status command's stdout+stderr when it exits non-zero,
2320
+ * and against a failed turn's own words to tell a signed-out failure from an
2321
+ * unrelated one.
2322
+ */
2323
+ signedOut?: RegExp;
2324
+ /**
2325
+ * A runner-specific reader that overrides the exit-code/regex rule. `null`
2326
+ * means the answer said nothing about the login, which stays `unknown`
2327
+ * rather than guessing from an exit code or from a line meant for another
2328
+ * credential route. The reader owns both kinds of answer — the status
2329
+ * command's output and a failed turn's own words — told apart by
2330
+ * {@link RunnerAuthStatus.kind}; where the reader exists, it is the only
2331
+ * judge of either.
2332
+ */
2333
+ read?: (answer: RunnerAuthStatus) => 'signed-in' | 'signed-out' | null;
1566
2334
  }
1567
2335
  interface RunnerFeatures {
1568
2336
  permissionModeValues?: Record<string, string>;
@@ -1695,6 +2463,16 @@ declare class RunnerRegistry {
1695
2463
  listEnabledIds(config: IConfig): string[];
1696
2464
  }
1697
2465
 
2466
+ /**
2467
+ * What a read-only attempt's `fetch` and `web_search` calls are answered from
2468
+ * (ADR-0046). `signal` is the call's: it aborts when the token is revoked or
2469
+ * the caller cancels.
2470
+ */
2471
+ interface TaskWebReads {
2472
+ fetch(url: string, signal: AbortSignal): Promise<McpToolReply>;
2473
+ search(query: string, signal: AbortSignal): Promise<McpToolReply>;
2474
+ }
2475
+
1698
2476
  /** How a structured turn ended. `failed` carries the agent's own words in the preceding `error` event. */
1699
2477
  type StructuredTurnEnd = 'completed' | 'interrupted' | 'failed';
1700
2478
  /**
@@ -1771,7 +2549,80 @@ type StructuredEvent = Exclude<AgentEvent, {
1771
2549
  | {
1772
2550
  type: 'permission_withdrawn';
1773
2551
  id: string;
2552
+ }
2553
+ /**
2554
+ * The runner's `task_complete` call was accepted on the attempt's token, with
2555
+ * the status it reported (ADR-0018, L1). A receipt, not evidence: the report
2556
+ * reaches {@link IRunnerSession.onTaskComplete} once its turn closes or the
2557
+ * interrupt grace runs out, and a turn or message the runner reads first voids it.
2558
+ */
2559
+ | {
2560
+ type: 'completion_received';
2561
+ status: TaskCompleteArgs['status'];
2562
+ }
2563
+ /** A script task's command as it starts (ADR-0035): its argument vector, or its script, once. */
2564
+ | ({
2565
+ type: 'script_run';
2566
+ } & ScriptRun)
2567
+ /**
2568
+ * What the running command printed, its stdout and stderr as they came.
2569
+ * `omittedChars` is set on the tail of an output too long to keep whole: that
2570
+ * much of its middle was left out.
2571
+ */
2572
+ | {
2573
+ type: 'script_output';
2574
+ text: string;
2575
+ omittedChars?: number;
2576
+ }
2577
+ /** How the command ended, and after how long; `timedOut` when the task's time limit ended it. */
2578
+ | ({
2579
+ type: 'script_exit';
2580
+ durationMs: number;
2581
+ timedOut?: true;
2582
+ } & ScriptStatus);
2583
+ /** What one step of a script task runs: an argument vector of its `commands`, or its `script`. */
2584
+ type ScriptRun = {
2585
+ argv: string[];
2586
+ } | {
2587
+ script: string;
2588
+ };
2589
+ /** How a script task's process ended: its exit code, or the signal that ended it; `error` when it could not start. */
2590
+ interface ScriptStatus {
2591
+ code: number | null;
2592
+ signal: string | null;
2593
+ error?: string;
2594
+ }
2595
+ /**
2596
+ * How a script task's body ended (ADR-0035): the evidence its session hands
2597
+ * `VerdictEngine`, as a runner's `task_complete` call is handed to it.
2598
+ * `command` names the command of `commands` it ended on, as a reader would
2599
+ * type it; a `script` body is one step and names none. `errorTail` is the end
2600
+ * of what that step wrote to stderr. `fullOutput` is the file that holds all
2601
+ * of the attempt's output, since the task log keeps only its ends.
2602
+ */
2603
+ type ScriptExit = ({
2604
+ outcome: 'passed';
2605
+ } | {
2606
+ outcome: 'failed';
2607
+ command?: string;
2608
+ status: ScriptStatus;
2609
+ errorTail: string;
2610
+ } | {
2611
+ outcome: 'timed-out';
2612
+ command?: string;
2613
+ timeoutMs: number;
2614
+ errorTail: string;
2615
+ } | {
2616
+ outcome: 'stopped';
2617
+ command?: string;
2618
+ }) & {
2619
+ fullOutput?: ScriptFullOutput;
1774
2620
  };
2621
+ /** Where a script task attempt's whole output was saved, and how much of it a hard cap did not keep. */
2622
+ interface ScriptFullOutput {
2623
+ file: string;
2624
+ droppedChars: number;
2625
+ }
1775
2626
  /** A runner command a user invoked, with its arguments as typed. */
1776
2627
  interface InvokedCommand {
1777
2628
  name: string;
@@ -1873,6 +2724,13 @@ interface IRunnerSession {
1873
2724
  * `signal` aborts when the caller goes away.
1874
2725
  */
1875
2726
  onToolCheckpoint(handler: (question: string, signal: AbortSignal) => Promise<CheckpointAnswer>): void;
2727
+ /**
2728
+ * A script task's end (ADR-0035): its exit status, the attempt's evidence in
2729
+ * place of a `task_complete` call, for `VerdictEngine` to weigh. Handed once,
2730
+ * before the session exits. A runner's session never hands one: its model
2731
+ * reports through `task_complete`.
2732
+ */
2733
+ onScriptExit(listener: (exit: ScriptExit) => void): void;
1876
2734
  }
1877
2735
  interface IRunner {
1878
2736
  spawn(opts: {
@@ -1884,6 +2742,8 @@ interface IRunner {
1884
2742
  modelVariants?: string[];
1885
2743
  mode?: string;
1886
2744
  cwd: string;
2745
+ /** The session workspace, also readable by an isolated read-only task (ADR-0046). */
2746
+ workspaceRoot?: string;
1887
2747
  registry?: RunnerRegistry;
1888
2748
  /** Task order and title — surfaces use these to label task_started/output events. */
1889
2749
  order?: number;
@@ -1925,6 +2785,45 @@ interface IRunner {
1925
2785
  skills?: readonly TaskSkillSnapshot[];
1926
2786
  /** Something the user should know about how the spawn went that did not stop it — a respawn, most often. */
1927
2787
  onNotice?: (message: string) => void;
2788
+ /** The attempt's work lands as a commit (ADR-0047): its runner is told to write the message in `task_complete`. */
2789
+ commits?: true;
2790
+ /** A script task's body (ADR-0035): only the script runner reads it, and it runs nothing else. */
2791
+ script?: ScriptBody;
2792
+ /**
2793
+ * A read-only attempt's shell (ADR-0046): its token serves `run_command`
2794
+ * from it, and only an attempt that has one is given that tool.
2795
+ */
2796
+ shell?: TaskShell;
2797
+ /**
2798
+ * Checks a `task_complete` call's handoff against the plan as the call
2799
+ * arrives (ADR-0047): a refusal is the call's result, and nothing is
2800
+ * recorded. Without one, a `task` reference resolves against no plan.
2801
+ */
2802
+ checkHandoff?: (completion: TaskCompleteArgs) => HandoffCheck<TaskCompleteArgs>;
2803
+ /**
2804
+ * Answers the attempt's `read_task` calls (ADR-0047), against the plan
2805
+ * and the session's task logs. Without one the call says it is not available.
2806
+ */
2807
+ readTask?: (args: ReadTaskArgs) => McpToolReply;
2808
+ /**
2809
+ * Answers a read-only attempt's `save_patch` calls (ADR-0050): its shell
2810
+ * captures the worktree's changes and the attempt keeps them. Without one
2811
+ * the call says it is not available.
2812
+ */
2813
+ savePatch?: (signal: AbortSignal) => Promise<McpToolReply>;
2814
+ /**
2815
+ * Answers a change attempt's `apply_patch` calls (ADR-0050): a saved patch
2816
+ * of a task it may read, applied into its worktree. Without one the call
2817
+ * says it is not available.
2818
+ */
2819
+ applyPatch?: (args: ApplyPatchArgs) => Promise<McpToolReply>;
2820
+ /**
2821
+ * Answers a read-only attempt's `fetch` and `web_search` calls (ADR-0046)
2822
+ * through the session's web-read policy, apart from its shell. Only a
2823
+ * read-only attempt's token lists them; without one they say they are
2824
+ * not available.
2825
+ */
2826
+ webReads?: TaskWebReads;
1928
2827
  }): Promise<IRunnerSession>;
1929
2828
  /** Wind one session down ({@link IRunnerSession.stop}); resolves once its process is gone. */
1930
2829
  stop(sessionId: string): Promise<void>;
@@ -1933,79 +2832,4 @@ interface IRunner {
1933
2832
  activeCount: number;
1934
2833
  }
1935
2834
 
1936
- interface ToolOutcome {
1937
- success: boolean;
1938
- output: string;
1939
- truncated: boolean;
1940
- }
1941
- interface ReadFileOpts {
1942
- maxBytes?: number;
1943
- offset?: number;
1944
- limit?: number;
1945
- }
1946
- /**
1947
- * `content` returns matching lines, `files` only the paths that matched, and
1948
- * `count` a per-file tally. Cheap models otherwise grep and then read whole
1949
- * files to answer "which files touch this", burning rounds against the budget.
1950
- */
1951
- type GrepOutputMode = 'content' | 'files' | 'count';
1952
- interface GrepOptions {
1953
- /** File glob filter, e.g. `*.ts`. */
1954
- include?: string;
1955
- /** Search root. Relative to the workspace unless approved as external. */
1956
- path?: string;
1957
- outputMode?: GrepOutputMode;
1958
- /** Lines of context around each match (`content` mode only). */
1959
- contextBefore?: number;
1960
- contextAfter?: number;
1961
- /** Treat the pattern as a literal string rather than a regex. */
1962
- literal?: boolean;
1963
- caseInsensitive?: boolean;
1964
- /** Global cap on returned rows. Defaults to {@link GREP_DEFAULT_HEAD_LIMIT}. */
1965
- headLimit?: number;
1966
- }
1967
- interface GlobOptions {
1968
- /** Search root. Relative to the workspace unless approved as external. */
1969
- path?: string;
1970
- headLimit?: number;
1971
- }
1972
- interface FindSymbolOptions {
1973
- /** Language id or file extension, e.g. `typescript` or `.go`. Narrows the keyword set. */
1974
- language?: string;
1975
- /** Search root. Relative to the workspace unless approved as external. */
1976
- path?: string;
1977
- }
1978
- /** Global row cap for grep. A per-file cap is not a budget — see PoolFileSystem. */
1979
- declare const GREP_DEFAULT_HEAD_LIMIT = 100;
1980
- /**
1981
- * Directories that are never interesting to a planner and would otherwise eat
1982
- * the result budget. Applied by every search entry point, not just `glob` —
1983
- * `dist/` and `.ordewell/` are frequently not gitignored.
1984
- */
1985
- declare const SEARCH_EXCLUSIONS: string[];
1986
- interface IFileSystem {
1987
- readFile(path: string, opts?: ReadFileOpts): Promise<ToolOutcome>;
1988
- readFiles(paths: string[]): Promise<ToolOutcome>;
1989
- glob(pattern: string, opts?: GlobOptions): Promise<ToolOutcome>;
1990
- grep(pattern: string, opts?: GrepOptions): Promise<ToolOutcome>;
1991
- listDir(path: string, depth?: number): Promise<ToolOutcome>;
1992
- /**
1993
- * `signal` stops the planning turn this command belongs to: adapters kill
1994
- * the spawned child rather than let it run out its own timeout. The other
1995
- * tools here are short enough that the loop's between-call abort check is
1996
- * indistinguishable from cancelling them mid-flight; a `bash` call is not.
1997
- */
1998
- bash(command: string, signal?: AbortSignal): Promise<ToolOutcome>;
1999
- /** Definition-first lookup for one symbol. See `symbolPatterns.ts`. */
2000
- findSymbol(symbol: string, opts?: FindSymbolOptions): Promise<ToolOutcome>;
2001
- getWorkspaceRoot(): string;
2002
- /**
2003
- * Inject the human-approval channel for out-of-envelope access. Optional so
2004
- * test doubles stay small; every adapter extending `BaseFileSystem` has it.
2005
- */
2006
- setApproval?(approval: IApproval): void;
2007
- /** Held credentials read live by the outbound secret check. */
2008
- setOutboundSecrets?(secrets: () => Iterable<string>): void;
2009
- }
2010
-
2011
- export { ORCHESTRATOR_SHORTCUTS as $, AUTO_COMMANDS as A, type GlobOptions as B, type CatalogModel as C, DEFAULT_PLANNER_ALLOWLIST as D, type EditPlanArgs as E, type FetchAllProviderModelsOptions as F, GIT_READONLY_SUBCOMMANDS as G, type GrepOptions as H, type GrepOutputMode as I, type IApproval as J, type IConfig as K, type IFileSystem as L, type IRunner as M, type IRunnerSession as N, type InvokedCommand as O, LineBuffer as P, type ListModelsArgs as Q, type ListRunnersArgs as R, type LoadSkillArgs as S, type McpClientConfig as T, type McpCredential as U, type McpTool as V, type McpToolContext as W, type McpToolReply as X, type MessageTaskArgs as Y, ModelCatalog as Z, type ModelShortcut as _, type AgentAdapter as a, effectiveApprovalMode as a$, ORDEWELL_MCP_PATH as a0, ORDEWELL_MCP_SERVER_NAME as a1, type OneTaskArgs as a2, type OrchestratorOption as a3, OrdewellMcpServer as a4, type OwnerOnlyFile as a5, PLANNER_EXECUTION_TOOLS as a6, PLANNER_TOOLS as a7, type PlannerAllowlist as a8, type PlannerBackendId as a9, type ShellDialect as aA, type SpawnFn as aB, type StandingDecision as aC, type StructuredEvent as aD, type StructuredTurnEnd as aE, type SubmitPlanArgs as aF, TASK_COMPLETE_TOOL as aG, TASK_COMPLETION_CONTRACT as aH, TASK_TOOLS as aI, type TaskCompleteArgs as aJ, type TaskDiffArgs as aK, type TaskMessageFrom as aL, type TaskModeAgentAdapter as aM, TaskModeUnsupportedError as aN, type TaskOutputArgs as aO, type TaskQueryArgs as aP, type TaskRunnerFlags as aQ, type TaskStartOptions as aR, type TaskTokenScope as aS, type TaskToolHandler as aT, type ToolOutcome as aU, type UsageLimitSignal as aV, approvalScopes as aW, classifyCommand as aX, clearResearchShellCache as aY, collectProviderCredentials as aZ, commandAllowedBy as a_, type PlannerStartOptions as aa, type PlannerTokenScope as ab, type PlannerToolHandler as ac, type ProjectMcpServer as ad, type ProviderCredentialSource as ae, type ProviderModelLists as af, type ProviderModelsResult as ag, type QueuedTaskMessage as ah, REFUSED_COMMANDS as ai, type ReadFileOpts as aj, type ResearchShell as ak, type ResearchShellDeps as al, type RetryTaskArgs as am, type RunCommandArgs as an, type RunPlanArgs as ao, type RunnerCommand as ap, type RunnerCommandKind as aq, type RunnerEntry as ar, type RunnerFeatures as as, type RunnerManifest as at, type RunnerMcpServer as au, type RunnerMode as av, type RunnerModelDiscovery as aw, type RunnerModelRef as ax, RunnerRegistry as ay, SEARCH_EXCLUSIONS as az, type AgentAdapterFactory as b, enabledRunners as b0, fetchAllProviderModels as b1, findRunnerCommand as b2, isGranted as b3, isRunnerApproval as b4, knownModelId as b5, mcpClientConfig as b6, ownerOnlyConfigFile as b7, parseAllowlist as b8, parseApprovalModeSetting as b9, researchShellWarning as ba, researchToolsPath as bb, resolveModelShortcut as bc, resolveProvider as bd, resolveResearchShell as be, scopeAllowed as bf, sharedMcpServer as bg, toApprovalDecision as bh, toOrchestratorOptions as bi, toolAllowed as bj, type AgentEvent as c, type AgentProcessDeps as d, type AgentStartOptions as e, type AiProvider as f, type AllProviderModels as g, type AnswerApprovalArgs as h, type ApprovalAnswer as i, type ApprovalDecision as j, type ApprovalKind as k, type ApprovalMode as l, type ApprovalModeSetting as m, ApprovalPolicy as n, type ApprovalPolicyOptions as o, type ApprovalRequest as p, type ApprovalSource as q, type CheckpointAnswer as r, type CheckpointArgs as s, type CommandClassification as t, type CommandTier as u, type CommandWords as v, DENY_ALL as w, type DiscoveryCommand as x, type FindSymbolOptions as y, GREP_DEFAULT_HEAD_LIMIT as z };
2835
+ export { type McpToolContext as $, AUTO_COMMANDS as A, type BashOptions as B, type CatalogModel as C, DEFAULT_PLANNER_ALLOWLIST as D, type DiscoveryCommand as E, type EditPlanArgs as F, type FetchAllProviderModelsOptions as G, type FindSymbolOptions as H, GIT_READONLY_SUBCOMMANDS as I, GREP_DEFAULT_HEAD_LIMIT as J, type GlobOptions as K, type GrepOptions as L, type GrepOutputMode as M, type IApproval as N, type IConfig as O, type IFileSystem as P, type IRunner as Q, type IRunnerSession as R, type InvokedCommand as S, LineBuffer as T, type ListModelsArgs as U, type ListRunnersArgs as V, type LoadSkillArgs as W, type McpClientConfig as X, type McpCredential as Y, type McpRefusal as Z, type McpTool as _, type AgentAdapter as a, type SealedRunOptions as a$, type McpToolReply as a0, type MessageTaskArgs as a1, ModelCatalog as a2, type ModelShortcut as a3, ORCHESTRATOR_SHORTCUTS as a4, ORDEWELL_MCP_PATH as a5, ORDEWELL_MCP_SERVER_NAME as a6, type OneTaskArgs as a7, type OrchestratorOption as a8, OrdewellMcpServer as a9, type RunCommandArgs as aA, type RunPlanArgs as aB, type RunnerAuthSpec as aC, type RunnerAuthStatus as aD, type RunnerCommand as aE, type RunnerCommandKind as aF, type RunnerEntry as aG, type RunnerFeatures as aH, type RunnerManifest as aI, type RunnerMcpServer as aJ, type RunnerMode as aK, type RunnerModelDiscovery as aL, type RunnerModelRef as aM, RunnerRegistry as aN, SEALED_LIMITS as aO, SEARCH_EXCLUSIONS as aP, type SandboxBackend as aQ, type SandboxInvocation as aR, type SandboxLaunch as aS, type SandboxLimits as aT, type SandboxProfile as aU, type ScriptBody as aV, type ScriptExit as aW, type ScriptFullOutput as aX, type ScriptRun as aY, type ScriptStatus as aZ, type SealedAvailability as a_, type OwnSealedRuns as aa, type OwnerOnlyFile as ab, PLANNER_EXECUTION_TOOLS as ac, PLANNER_SANDBOX_DOCS as ad, PLANNER_TOOLS as ae, type PlannerAllowlist as af, type PlannerBackendId as ag, type PlannerSandboxAvailability as ah, type PlannerSandboxDeps as ai, PlannerShellSandbox as aj, type PlannerStartOptions as ak, type PlannerTokenScope as al, type PlannerToolHandler as am, type ProjectMcpServer as an, type ProviderCredentialSource as ao, type ProviderModelLists as ap, type ProviderModelsResult as aq, type QueuedTaskMessage as ar, READ_ONLY_TASK_TOOLS as as, REFUSED_COMMANDS as at, type ReadFileOpts as au, type ReadTaskArgs as av, type ResearchShell as aw, type ResearchShellDeps as ax, type RetryTaskArgs as ay, type RuleWord as az, type AgentAdapterFactory as b, type ShellDialect as b0, type ShellLaunch as b1, type SpawnFn as b2, type StandingDecision as b3, type StructuredEvent as b4, type StructuredTurnEnd as b5, type SubmitPlanArgs as b6, TASK_COMPLETE_TOOL as b7, TASK_COMPLETION_CONTRACT as b8, TASK_SEALED_LIMITS as b9, enabledRunners as bA, fetchAllProviderModels as bB, findRunnerCommand as bC, isGranted as bD, isRunnerApproval as bE, knownModelId as bF, mcpClientConfig as bG, ownerOnlyConfigFile as bH, parseAllowlist as bI, parseApprovalModeSetting as bJ, researchShellWarning as bK, researchToolsPath as bL, resolveModelShortcut as bM, resolvePlannerSandbox as bN, resolveProvider as bO, resolveResearchShell as bP, scopeAllowed as bQ, scriptBodyOf as bR, scriptBodyText as bS, scriptTaskText as bT, sharedMcpServer as bU, taskCompletionContract as bV, timeLimitText as bW, toApprovalDecision as bX, toOrchestratorOptions as bY, toolAllowed as bZ, TASK_TOOLS as ba, type TaskCompleteArgs as bb, type TaskDiffArgs as bc, type TaskMessageFrom as bd, type TaskModeAgentAdapter as be, TaskModeUnsupportedError as bf, type TaskOutputArgs as bg, type TaskQueryArgs as bh, type TaskRunCommandArgs as bi, type TaskRunnerFlags as bj, type TaskShell as bk, type TaskShellSite as bl, type TaskStartOptions as bm, type TaskTokenScope as bn, type TaskToolHandler as bo, type TaskWebReads as bp, type ToolOutcome as bq, type UsageLimitSignal as br, approvalScopes as bs, classifyCommand as bt, clearPlannerSandboxCache as bu, clearResearchShellCache as bv, collectProviderCredentials as bw, commandAllowedBy as bx, commandLine as by, effectiveApprovalMode as bz, type AgentEvent as c, type AgentProcessDeps as d, type AgentStartOptions as e, type AiProvider as f, type AllProviderModels as g, type AnswerApprovalArgs as h, type ApplyPatchArgs as i, type ApprovalAnswer as j, type ApprovalDecision as k, type ApprovalKind as l, type ApprovalMode as m, type ApprovalModeSetting as n, ApprovalPolicy as o, type ApprovalPolicyOptions as p, type ApprovalRequest as q, type ApprovalSource as r, type AttachState as s, type CheckpointAnswer as t, type CheckpointArgs as u, type CommandClassification as v, type CommandTier as w, type CommandWords as x, DEFAULT_SCRIPT_TIMEOUT_MS as y, DENY_ALL as z };