@theokit/sdk 5.12.0 → 5.13.0

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 (139) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/dist/{agent-IG7BP6GN.js → agent-5DSDDH7K.js} +5 -5
  3. package/dist/{agent-IG7BP6GN.js.map → agent-5DSDDH7K.js.map} +1 -1
  4. package/dist/{agent-CVzDy_Oj.d.ts → agent-DSMuwADp.d.ts} +9 -2
  5. package/dist/{agent-BVKIUP7F.cjs → agent-WOMRT3KX.cjs} +6 -6
  6. package/dist/{agent-BVKIUP7F.cjs.map → agent-WOMRT3KX.cjs.map} +1 -1
  7. package/dist/{agent-Cn0sphpA.d.cts → agent-iW5kPpfT.d.cts} +9 -2
  8. package/dist/{chunk-XJ4C4NFX.js → chunk-2PRGRYEQ.js} +61 -47
  9. package/dist/chunk-2PRGRYEQ.js.map +1 -0
  10. package/dist/{chunk-HN4IKB6X.cjs → chunk-2XWAYCFM.cjs} +15 -13
  11. package/dist/chunk-2XWAYCFM.cjs.map +1 -0
  12. package/dist/{chunk-VVGFZQZC.js → chunk-3LMVJTNJ.js} +9 -5
  13. package/dist/chunk-3LMVJTNJ.js.map +1 -0
  14. package/dist/{chunk-IO4RI5ZJ.cjs → chunk-47EACDOC.cjs} +4 -4
  15. package/dist/{chunk-IO4RI5ZJ.cjs.map → chunk-47EACDOC.cjs.map} +1 -1
  16. package/dist/{chunk-LSWHDOCL.cjs → chunk-4UYHP6NF.cjs} +64 -48
  17. package/dist/chunk-4UYHP6NF.cjs.map +1 -0
  18. package/dist/{chunk-ZLFFDPXC.js → chunk-73IITAF7.js} +36 -14
  19. package/dist/chunk-73IITAF7.js.map +1 -0
  20. package/dist/{chunk-XRPMZ7TO.js → chunk-CYWOJA6B.js} +6 -4
  21. package/dist/chunk-CYWOJA6B.js.map +1 -0
  22. package/dist/{chunk-AQW54OWQ.js → chunk-DFBWYETS.js} +5 -3
  23. package/dist/chunk-DFBWYETS.js.map +1 -0
  24. package/dist/{chunk-YOVZMN4P.cjs → chunk-DVP3YMDA.cjs} +3 -3
  25. package/dist/{chunk-YOVZMN4P.cjs.map → chunk-DVP3YMDA.cjs.map} +1 -1
  26. package/dist/{chunk-BRWI4HLK.cjs → chunk-FLDHYF5C.cjs} +13 -3
  27. package/dist/chunk-FLDHYF5C.cjs.map +1 -0
  28. package/dist/{chunk-BJ7BPLQK.js → chunk-JX4LB6XO.js} +124 -13
  29. package/dist/chunk-JX4LB6XO.js.map +1 -0
  30. package/dist/{chunk-Q6WT5535.cjs → chunk-KL7ZUMK3.cjs} +161 -50
  31. package/dist/chunk-KL7ZUMK3.cjs.map +1 -0
  32. package/dist/{chunk-FEAWEBWN.cjs → chunk-PDOXYXWX.cjs} +6 -4
  33. package/dist/chunk-PDOXYXWX.cjs.map +1 -0
  34. package/dist/{chunk-EEK7S77K.js → chunk-QGDPMM3C.js} +13 -3
  35. package/dist/chunk-QGDPMM3C.js.map +1 -0
  36. package/dist/{chunk-ZWLFHSON.cjs → chunk-R35ZJAYT.cjs} +38 -15
  37. package/dist/chunk-R35ZJAYT.cjs.map +1 -0
  38. package/dist/{chunk-4YD2WI57.cjs → chunk-R427EOZE.cjs} +19 -15
  39. package/dist/chunk-R427EOZE.cjs.map +1 -0
  40. package/dist/{chunk-TLVI2OQK.cjs → chunk-SETHRLQS.cjs} +18 -2
  41. package/dist/chunk-SETHRLQS.cjs.map +1 -0
  42. package/dist/{chunk-BO3PV3OP.js → chunk-TDED5XES.js} +18 -3
  43. package/dist/chunk-TDED5XES.js.map +1 -0
  44. package/dist/{chunk-4GUFNDZR.js → chunk-XOYNB3YN.js} +3 -3
  45. package/dist/{chunk-4GUFNDZR.js.map → chunk-XOYNB3YN.js.map} +1 -1
  46. package/dist/{chunk-NJBJ3CUG.js → chunk-ZTP6ZACR.js} +3 -3
  47. package/dist/{chunk-NJBJ3CUG.js.map → chunk-ZTP6ZACR.js.map} +1 -1
  48. package/dist/{compact-session-3U2JYTVG.js → compact-session-5HMX6KYT.js} +3 -3
  49. package/dist/{compact-session-3U2JYTVG.js.map → compact-session-5HMX6KYT.js.map} +1 -1
  50. package/dist/{compact-session-NM56BREJ.cjs → compact-session-B7P6EU3Z.cjs} +12 -12
  51. package/dist/{compact-session-NM56BREJ.cjs.map → compact-session-B7P6EU3Z.cjs.map} +1 -1
  52. package/dist/{cron-BWDYetbq.d.cts → cron-BvxrLW5J.d.cts} +1 -1
  53. package/dist/{cron-CHn-F0fC.d.ts → cron-DdKzwJqK.d.ts} +1 -1
  54. package/dist/cron.cjs +5 -5
  55. package/dist/cron.d.cts +2 -2
  56. package/dist/cron.d.ts +2 -2
  57. package/dist/cron.js +4 -4
  58. package/dist/eval.cjs +9 -9
  59. package/dist/eval.js +4 -4
  60. package/dist/{executor-HKHT4CWS.cjs → executor-5QL5AXIZ.cjs} +18 -15
  61. package/dist/executor-5QL5AXIZ.cjs.map +1 -0
  62. package/dist/{executor-3D2UDJHW.js → executor-THUXNAFR.js} +6 -3
  63. package/dist/executor-THUXNAFR.js.map +1 -0
  64. package/dist/generate-object-A5F576IT.cjs +20 -0
  65. package/dist/{generate-object-XBWD2PU7.cjs.map → generate-object-A5F576IT.cjs.map} +1 -1
  66. package/dist/{generate-object-S7MNVF2V.js → generate-object-TBDOBBYW.js} +4 -4
  67. package/dist/{generate-object-S7MNVF2V.js.map → generate-object-TBDOBBYW.js.map} +1 -1
  68. package/dist/generate-object.d.ts +14 -1
  69. package/dist/index.cjs +43 -43
  70. package/dist/index.d.cts +30 -4
  71. package/dist/index.d.ts +30 -4
  72. package/dist/index.js +13 -13
  73. package/dist/{inject-session-THABTKJY.js → inject-session-75L3NCNL.js} +3 -3
  74. package/dist/{inject-session-THABTKJY.js.map → inject-session-75L3NCNL.js.map} +1 -1
  75. package/dist/{inject-session-JVTZNQF6.cjs → inject-session-WOH7TPDX.cjs} +4 -4
  76. package/dist/{inject-session-JVTZNQF6.cjs.map → inject-session-WOH7TPDX.cjs.map} +1 -1
  77. package/dist/internal/providers/discovery.d.ts +2 -2
  78. package/dist/internal/providers/trust-gate.d.ts +35 -0
  79. package/dist/internal/runtime/plugin-loader/manifest-entry-import.d.ts +17 -0
  80. package/dist/internal/runtime/plugin-loader/workspace-plugin-trust.d.ts +16 -0
  81. package/dist/internal/structured-output-helpers.d.ts +5 -2
  82. package/dist/sandbox/bwrap.d.cts +10 -8
  83. package/dist/sandbox/bwrap.d.ts +10 -8
  84. package/dist/sandbox/deny-read.d.cts +24 -0
  85. package/dist/sandbox/deny-read.d.ts +24 -0
  86. package/dist/sandbox/index.cjs +198 -46
  87. package/dist/sandbox/index.cjs.map +1 -1
  88. package/dist/sandbox/index.d.cts +2 -1
  89. package/dist/sandbox/index.d.ts +2 -1
  90. package/dist/sandbox/index.js +184 -36
  91. package/dist/sandbox/index.js.map +1 -1
  92. package/dist/sandbox/linux-sandbox.d.cts +40 -5
  93. package/dist/sandbox/linux-sandbox.d.ts +40 -5
  94. package/dist/sandbox/local-sandbox.d.cts +3 -1
  95. package/dist/sandbox/local-sandbox.d.ts +3 -1
  96. package/dist/sandbox/seccomp-delivery.d.cts +49 -0
  97. package/dist/sandbox/seccomp-delivery.d.ts +49 -0
  98. package/dist/sandbox/shell-escape.d.cts +14 -2
  99. package/dist/sandbox/shell-escape.d.ts +14 -2
  100. package/dist/sandbox/types.d.cts +45 -0
  101. package/dist/sandbox/types.d.ts +45 -0
  102. package/dist/stream-object-AS4YYM4B.cjs +20 -0
  103. package/dist/{stream-object-TEEK3CAX.cjs.map → stream-object-AS4YYM4B.cjs.map} +1 -1
  104. package/dist/stream-object-EKM4WGTI.js +7 -0
  105. package/dist/{stream-object-R6SMYV4R.js.map → stream-object-EKM4WGTI.js.map} +1 -1
  106. package/dist/stream-object.d.ts +14 -1
  107. package/dist/subagents-loader.d.cts +1 -1
  108. package/dist/subagents-loader.d.ts +1 -1
  109. package/dist/types/agent.d.ts +8 -1
  110. package/dist/workflow-as-tool.d.ts +39 -5
  111. package/dist/workflow-errors.d.ts +16 -0
  112. package/dist/workflow.cjs +31 -23
  113. package/dist/workflow.d.cts +54 -4
  114. package/dist/workflow.d.ts +54 -4
  115. package/dist/workflow.js +2 -2
  116. package/docs/error-codes.md +16 -13
  117. package/docs/harness-capability-map.md +51 -5
  118. package/package.json +1 -1
  119. package/dist/chunk-4YD2WI57.cjs.map +0 -1
  120. package/dist/chunk-AQW54OWQ.js.map +0 -1
  121. package/dist/chunk-BJ7BPLQK.js.map +0 -1
  122. package/dist/chunk-BO3PV3OP.js.map +0 -1
  123. package/dist/chunk-BRWI4HLK.cjs.map +0 -1
  124. package/dist/chunk-EEK7S77K.js.map +0 -1
  125. package/dist/chunk-FEAWEBWN.cjs.map +0 -1
  126. package/dist/chunk-HN4IKB6X.cjs.map +0 -1
  127. package/dist/chunk-LSWHDOCL.cjs.map +0 -1
  128. package/dist/chunk-Q6WT5535.cjs.map +0 -1
  129. package/dist/chunk-TLVI2OQK.cjs.map +0 -1
  130. package/dist/chunk-VVGFZQZC.js.map +0 -1
  131. package/dist/chunk-XJ4C4NFX.js.map +0 -1
  132. package/dist/chunk-XRPMZ7TO.js.map +0 -1
  133. package/dist/chunk-ZLFFDPXC.js.map +0 -1
  134. package/dist/chunk-ZWLFHSON.cjs.map +0 -1
  135. package/dist/executor-3D2UDJHW.js.map +0 -1
  136. package/dist/executor-HKHT4CWS.cjs.map +0 -1
  137. package/dist/generate-object-XBWD2PU7.cjs +0 -20
  138. package/dist/stream-object-R6SMYV4R.js +0 -7
  139. package/dist/stream-object-TEEK3CAX.cjs +0 -20
@@ -0,0 +1,49 @@
1
+ import { type SandboxMode } from "./bwrap.js";
2
+ /** The warning both arch guards print, the path route's and this one: one text, two latches. */
3
+ export declare function nonX64SeccompWarning(arch: string): string;
4
+ /**
5
+ * The restricted-network program for `arch`, or `undefined` where it must not be installed.
6
+ *
7
+ * Same ARCH GUARD as `seccompPathForArch`: the program is x86_64 and KILLs every syscall from
8
+ * another architecture, so on any other arch it is refused with one warning. The latch is this
9
+ * function's own, so a process that also calls the deprecated path helper warns once from each.
10
+ */
11
+ export declare function seccompProgramForArch(arch: string, warn: (m: string) => void): Buffer | undefined;
12
+ /** The restricted-network program, built once per process and x64-gated. Never mutated. */
13
+ export declare function restrictedSeccompProgram(warn: (m: string) => void): Buffer | undefined;
14
+ /**
15
+ * Wrap `command` so bwrap reads `program` on fd 3 from a pipe:
16
+ *
17
+ * exec /bin/sh -c '<PIPE_SCRIPT>' sh <octal> <bwrap...> --seccomp 3 -- /bin/sh -c <cmd>
18
+ *
19
+ * The pipeline's grammar is always `/bin/sh`'s, whatever shell runs the outer words.
20
+ * `bwrapArgv` is the binary and flags, unescaped, without `--seccomp` and the trailing `--`.
21
+ */
22
+ export declare function wrapWithSeccompProgram(bwrapArgv: readonly string[], command: string, program: Uint8Array): string;
23
+ /**
24
+ * Remember that `path` was written with `program`, so a wrap naming that file pipes the program
25
+ * from memory: a sandbox that does not load the filter mounts `/tmp` writable and can replace it.
26
+ */
27
+ export declare function rememberSeccompFile(path: string, program: Buffer): void;
28
+ /**
29
+ * Remove `dir` when the process exits or is told to stop. A SIGINT or SIGTERM listener cancels
30
+ * Node's default termination, so once the directory is gone the signal is raised again when no other
31
+ * listener remains: the process ends as it would have, and a host's own handler still decides.
32
+ * The signal listener is prepended (B-648): run first, it still counts a host's `process.once`
33
+ * handler, which Node unregisters before calling it, whether the host registered before or after.
34
+ * A host that itself prepends a `once` handler after the filter still runs first and is not counted.
35
+ */
36
+ export declare function removeDirOnExit(dir: string): void;
37
+ /**
38
+ * The deprecated path route, with the filter bound read-only on top of every writable bind so the
39
+ * confined command can neither overwrite it nor rename its directory away (B-600). A path
40
+ * `seccompPathForArch` wrote is piped from memory instead of read, because another sandbox, one with
41
+ * no filter, can still replace that file; any other path is read through `3< <path>`.
42
+ *
43
+ * `bwrapArgv` is the binary followed by `buildBwrapArgv`'s output, which ends `--chdir <cwd> --`;
44
+ * the bind goes before `--chdir`, after every writable bind.
45
+ */
46
+ export declare function wrapWithSeccompPath(bwrapArgv: readonly string[], policy: {
47
+ mode: SandboxMode;
48
+ cwd: string;
49
+ }, command: string, seccompPath: string): string;
@@ -0,0 +1,49 @@
1
+ import { type SandboxMode } from "./bwrap.js";
2
+ /** The warning both arch guards print, the path route's and this one: one text, two latches. */
3
+ export declare function nonX64SeccompWarning(arch: string): string;
4
+ /**
5
+ * The restricted-network program for `arch`, or `undefined` where it must not be installed.
6
+ *
7
+ * Same ARCH GUARD as `seccompPathForArch`: the program is x86_64 and KILLs every syscall from
8
+ * another architecture, so on any other arch it is refused with one warning. The latch is this
9
+ * function's own, so a process that also calls the deprecated path helper warns once from each.
10
+ */
11
+ export declare function seccompProgramForArch(arch: string, warn: (m: string) => void): Buffer | undefined;
12
+ /** The restricted-network program, built once per process and x64-gated. Never mutated. */
13
+ export declare function restrictedSeccompProgram(warn: (m: string) => void): Buffer | undefined;
14
+ /**
15
+ * Wrap `command` so bwrap reads `program` on fd 3 from a pipe:
16
+ *
17
+ * exec /bin/sh -c '<PIPE_SCRIPT>' sh <octal> <bwrap...> --seccomp 3 -- /bin/sh -c <cmd>
18
+ *
19
+ * The pipeline's grammar is always `/bin/sh`'s, whatever shell runs the outer words.
20
+ * `bwrapArgv` is the binary and flags, unescaped, without `--seccomp` and the trailing `--`.
21
+ */
22
+ export declare function wrapWithSeccompProgram(bwrapArgv: readonly string[], command: string, program: Uint8Array): string;
23
+ /**
24
+ * Remember that `path` was written with `program`, so a wrap naming that file pipes the program
25
+ * from memory: a sandbox that does not load the filter mounts `/tmp` writable and can replace it.
26
+ */
27
+ export declare function rememberSeccompFile(path: string, program: Buffer): void;
28
+ /**
29
+ * Remove `dir` when the process exits or is told to stop. A SIGINT or SIGTERM listener cancels
30
+ * Node's default termination, so once the directory is gone the signal is raised again when no other
31
+ * listener remains: the process ends as it would have, and a host's own handler still decides.
32
+ * The signal listener is prepended (B-648): run first, it still counts a host's `process.once`
33
+ * handler, which Node unregisters before calling it, whether the host registered before or after.
34
+ * A host that itself prepends a `once` handler after the filter still runs first and is not counted.
35
+ */
36
+ export declare function removeDirOnExit(dir: string): void;
37
+ /**
38
+ * The deprecated path route, with the filter bound read-only on top of every writable bind so the
39
+ * confined command can neither overwrite it nor rename its directory away (B-600). A path
40
+ * `seccompPathForArch` wrote is piped from memory instead of read, because another sandbox, one with
41
+ * no filter, can still replace that file; any other path is read through `3< <path>`.
42
+ *
43
+ * `bwrapArgv` is the binary followed by `buildBwrapArgv`'s output, which ends `--chdir <cwd> --`;
44
+ * the bind goes before `--chdir`, after every writable bind.
45
+ */
46
+ export declare function wrapWithSeccompPath(bwrapArgv: readonly string[], policy: {
47
+ mode: SandboxMode;
48
+ cwd: string;
49
+ }, command: string, seccompPath: string): string;
@@ -2,7 +2,19 @@
2
2
  * POSIX shell escaping for values interpolated into a `SandboxBackend.execute`
3
3
  * command string. `execute` runs via `/bin/sh -c`, so any untrusted value
4
4
  * (repo URL, ref, path) MUST be quoted to prevent command injection.
5
+ */
6
+ /**
7
+ * Quotes `arg` as one word for POSIX `sh`, for a command line you build yourself and hand to
8
+ * `SandboxBackend.execute`. A value from outside cannot end the word and start another command,
9
+ * whatever it holds: quotes, `$()`, backticks, newlines, backslashes. An empty string comes back as
10
+ * `''`. Quoting does not stop the program you call from reading a leading dash as an option, so put
11
+ * `--` before the value for one that parses options. The derived helpers and `provisionRepo` use this
12
+ * same quoter.
5
13
  *
6
- * @internal
14
+ * Wrap `arg` in single quotes, escaping embedded single quotes (`'\''`). A backslash before a quote,
15
+ * a backslash or the end is written outside the quotes too (`'\\'`), so the word parses the same
16
+ * under fish, which reads `\'` and `\\` inside single quotes as escapes, as under sh (B-600): the PTY
17
+ * runs the sandbox wrap under the user's `$SHELL`. After the first pass an original quote reads
18
+ * `'\''`, whose own backslash is always followed by `''`, so the second pass never matches it.
7
19
  */
8
- export {};
20
+ export declare function shellEscapePosix(arg: string): string;
@@ -2,7 +2,19 @@
2
2
  * POSIX shell escaping for values interpolated into a `SandboxBackend.execute`
3
3
  * command string. `execute` runs via `/bin/sh -c`, so any untrusted value
4
4
  * (repo URL, ref, path) MUST be quoted to prevent command injection.
5
+ */
6
+ /**
7
+ * Quotes `arg` as one word for POSIX `sh`, for a command line you build yourself and hand to
8
+ * `SandboxBackend.execute`. A value from outside cannot end the word and start another command,
9
+ * whatever it holds: quotes, `$()`, backticks, newlines, backslashes. An empty string comes back as
10
+ * `''`. Quoting does not stop the program you call from reading a leading dash as an option, so put
11
+ * `--` before the value for one that parses options. The derived helpers and `provisionRepo` use this
12
+ * same quoter.
5
13
  *
6
- * @internal
14
+ * Wrap `arg` in single quotes, escaping embedded single quotes (`'\''`). A backslash before a quote,
15
+ * a backslash or the end is written outside the quotes too (`'\\'`), so the word parses the same
16
+ * under fish, which reads `\'` and `\\` inside single quotes as escapes, as under sh (B-600): the PTY
17
+ * runs the sandbox wrap under the user's `$SHELL`. After the first pass an original quote reads
18
+ * `'\''`, whose own backslash is always followed by `''`, so the second pass never matches it.
7
19
  */
8
- export {};
20
+ export declare function shellEscapePosix(arg: string): string;
@@ -52,6 +52,21 @@ export interface SandboxConfig {
52
52
  */
53
53
  env?: EnvPolicy;
54
54
  }
55
+ /**
56
+ * What a {@link SandboxBackend} states about its outbound network. It is a statement the backend
57
+ * makes about itself, for a caller that wants to ask before it trusts: this package enforces nothing
58
+ * from it, and a custom backend is responsible for the claim being true.
59
+ *
60
+ * `"unrestricted"` means a command can reach whatever the host can. `"none"` means it cannot reach
61
+ * the network at all. `"allowlist"` means it can reach only the destinations in `allow`, written as
62
+ * the backend's own firewall spells them (usually domain names); the field is meaningful only with
63
+ * that mode. A backend that says nothing leaves `networkPolicy` undefined, which is not the same as
64
+ * `"unrestricted"`: it means the backend makes no claim either way.
65
+ */
66
+ export interface SandboxNetworkPolicy {
67
+ readonly mode: "unrestricted" | "allowlist" | "none";
68
+ readonly allow?: readonly string[];
69
+ }
55
70
  /**
56
71
  * A backend refused a command on policy grounds — the environment works, and it said no. Carries a
57
72
  * stable `code: "sandbox_security"` for callers that prefer not to match on the class.
@@ -98,16 +113,36 @@ export declare class SandboxNotAvailableError extends TheokitAgentError {
98
113
  * a reason to pin one. For genuinely untrusted code you want a container or VM backend, which this
99
114
  * package does not ship — write it against these two methods.
100
115
  *
116
+ * Two optional members let a backend say more about itself. {@link SandboxBackend.networkPolicy}
117
+ * states its egress: `LocalSandbox` declares `"unrestricted"`, `LinuxSandbox` declares `"none"` when
118
+ * bubblewrap unshares the network, and a backend that does not override it states nothing. Nothing in
119
+ * this package enforces an allowlist, so `"allowlist"` is only ever a claim a custom backend makes
120
+ * for itself. {@link SandboxBackend.dispose} releases what the backend holds, and the owner of the
121
+ * backend calls it.
122
+ *
101
123
  * Because the derived helpers assemble shell command lines (arguments escaped for POSIX `sh`), a
102
124
  * backend whose `execute` is not a POSIX shell must override them as well.
103
125
  */
104
126
  export declare abstract class SandboxBackend {
105
127
  protected config: SandboxConfig;
128
+ /**
129
+ * What this backend states about its outbound network, or `undefined` when it states nothing.
130
+ * Read it to check an isolation claim before trusting a backend; do not read `undefined` as
131
+ * "unrestricted". A subclass sets it as a field, and it is a statement only: the backend must
132
+ * enforce it itself.
133
+ */
134
+ readonly networkPolicy?: SandboxNetworkPolicy;
106
135
  constructor(config?: SandboxConfig);
107
136
  abstract execute(command: string, opts?: {
108
137
  timeoutMs?: number;
109
138
  }): Promise<ExecuteResult>;
110
139
  abstract uploadFile(path: string, content: string | Buffer): Promise<void>;
140
+ /**
141
+ * Releases whatever the backend holds, such as a VM or a container. The default does nothing,
142
+ * which is correct for a backend that holds nothing, so existing subclasses need no change. Safe
143
+ * to call more than once. The owner of the backend calls it; nothing in this package does.
144
+ */
145
+ dispose(): Promise<void>;
111
146
  readFile(path: string): Promise<string>;
112
147
  writeFile(path: string, content: string): Promise<void>;
113
148
  glob(pattern: string, cwd?: string): Promise<string[]>;
@@ -141,3 +176,13 @@ export declare abstract class SandboxBackend {
141
176
  export type SandboxProvider<Ctx = unknown> = SandboxBackend | ((ctx: Ctx) => SandboxBackend | Promise<SandboxBackend>);
142
177
  /** Resolve a {@link SandboxProvider} to a concrete backend for `ctx`. */
143
178
  export declare function resolveSandbox<Ctx>(provider: SandboxProvider<Ctx>, ctx: Ctx): Promise<SandboxBackend>;
179
+ /** Codex's three canonical sandbox modes; lives in this leaf module so bwrap.ts and deny-read.ts need not import each other. */
180
+ export type SandboxMode = "read-only" | "workspace-write" | "danger-full-access";
181
+ /** Result of probing for bubblewrap. Detection never throws. */
182
+ export type BwrapDetection = {
183
+ ok: true;
184
+ bin: string;
185
+ } | {
186
+ ok: false;
187
+ reason: string;
188
+ };
@@ -52,6 +52,21 @@ export interface SandboxConfig {
52
52
  */
53
53
  env?: EnvPolicy;
54
54
  }
55
+ /**
56
+ * What a {@link SandboxBackend} states about its outbound network. It is a statement the backend
57
+ * makes about itself, for a caller that wants to ask before it trusts: this package enforces nothing
58
+ * from it, and a custom backend is responsible for the claim being true.
59
+ *
60
+ * `"unrestricted"` means a command can reach whatever the host can. `"none"` means it cannot reach
61
+ * the network at all. `"allowlist"` means it can reach only the destinations in `allow`, written as
62
+ * the backend's own firewall spells them (usually domain names); the field is meaningful only with
63
+ * that mode. A backend that says nothing leaves `networkPolicy` undefined, which is not the same as
64
+ * `"unrestricted"`: it means the backend makes no claim either way.
65
+ */
66
+ export interface SandboxNetworkPolicy {
67
+ readonly mode: "unrestricted" | "allowlist" | "none";
68
+ readonly allow?: readonly string[];
69
+ }
55
70
  /**
56
71
  * A backend refused a command on policy grounds — the environment works, and it said no. Carries a
57
72
  * stable `code: "sandbox_security"` for callers that prefer not to match on the class.
@@ -98,16 +113,36 @@ export declare class SandboxNotAvailableError extends TheokitAgentError {
98
113
  * a reason to pin one. For genuinely untrusted code you want a container or VM backend, which this
99
114
  * package does not ship — write it against these two methods.
100
115
  *
116
+ * Two optional members let a backend say more about itself. {@link SandboxBackend.networkPolicy}
117
+ * states its egress: `LocalSandbox` declares `"unrestricted"`, `LinuxSandbox` declares `"none"` when
118
+ * bubblewrap unshares the network, and a backend that does not override it states nothing. Nothing in
119
+ * this package enforces an allowlist, so `"allowlist"` is only ever a claim a custom backend makes
120
+ * for itself. {@link SandboxBackend.dispose} releases what the backend holds, and the owner of the
121
+ * backend calls it.
122
+ *
101
123
  * Because the derived helpers assemble shell command lines (arguments escaped for POSIX `sh`), a
102
124
  * backend whose `execute` is not a POSIX shell must override them as well.
103
125
  */
104
126
  export declare abstract class SandboxBackend {
105
127
  protected config: SandboxConfig;
128
+ /**
129
+ * What this backend states about its outbound network, or `undefined` when it states nothing.
130
+ * Read it to check an isolation claim before trusting a backend; do not read `undefined` as
131
+ * "unrestricted". A subclass sets it as a field, and it is a statement only: the backend must
132
+ * enforce it itself.
133
+ */
134
+ readonly networkPolicy?: SandboxNetworkPolicy;
106
135
  constructor(config?: SandboxConfig);
107
136
  abstract execute(command: string, opts?: {
108
137
  timeoutMs?: number;
109
138
  }): Promise<ExecuteResult>;
110
139
  abstract uploadFile(path: string, content: string | Buffer): Promise<void>;
140
+ /**
141
+ * Releases whatever the backend holds, such as a VM or a container. The default does nothing,
142
+ * which is correct for a backend that holds nothing, so existing subclasses need no change. Safe
143
+ * to call more than once. The owner of the backend calls it; nothing in this package does.
144
+ */
145
+ dispose(): Promise<void>;
111
146
  readFile(path: string): Promise<string>;
112
147
  writeFile(path: string, content: string): Promise<void>;
113
148
  glob(pattern: string, cwd?: string): Promise<string[]>;
@@ -141,3 +176,13 @@ export declare abstract class SandboxBackend {
141
176
  export type SandboxProvider<Ctx = unknown> = SandboxBackend | ((ctx: Ctx) => SandboxBackend | Promise<SandboxBackend>);
142
177
  /** Resolve a {@link SandboxProvider} to a concrete backend for `ctx`. */
143
178
  export declare function resolveSandbox<Ctx>(provider: SandboxProvider<Ctx>, ctx: Ctx): Promise<SandboxBackend>;
179
+ /** Codex's three canonical sandbox modes; lives in this leaf module so bwrap.ts and deny-read.ts need not import each other. */
180
+ export type SandboxMode = "read-only" | "workspace-write" | "danger-full-access";
181
+ /** Result of probing for bubblewrap. Detection never throws. */
182
+ export type BwrapDetection = {
183
+ ok: true;
184
+ bin: string;
185
+ } | {
186
+ ok: false;
187
+ reason: string;
188
+ };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var chunk2XWAYCFM_cjs = require('./chunk-2XWAYCFM.cjs');
4
+ require('./chunk-PDOXYXWX.cjs');
5
+ require('./chunk-AA27GEYS.cjs');
6
+ require('./chunk-CEGU5AVD.cjs');
7
+ require('./chunk-RNXXYF22.cjs');
8
+
9
+
10
+
11
+ Object.defineProperty(exports, "StreamObjectError", {
12
+ enumerable: true,
13
+ get: function () { return chunk2XWAYCFM_cjs.StreamObjectError; }
14
+ });
15
+ Object.defineProperty(exports, "streamObjectImpl", {
16
+ enumerable: true,
17
+ get: function () { return chunk2XWAYCFM_cjs.streamObjectImpl; }
18
+ });
19
+ //# sourceMappingURL=stream-object-AS4YYM4B.cjs.map
20
+ //# sourceMappingURL=stream-object-AS4YYM4B.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"stream-object-TEEK3CAX.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"stream-object-AS4YYM4B.cjs"}
@@ -0,0 +1,7 @@
1
+ export { StreamObjectError, streamObjectImpl } from './chunk-CYWOJA6B.js';
2
+ import './chunk-DFBWYETS.js';
3
+ import './chunk-7I5Z3UBJ.js';
4
+ import './chunk-TNFOU6SB.js';
5
+ import './chunk-3OY6H3I7.js';
6
+ //# sourceMappingURL=stream-object-EKM4WGTI.js.map
7
+ //# sourceMappingURL=stream-object-EKM4WGTI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"stream-object-R6SMYV4R.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"stream-object-EKM4WGTI.js"}
@@ -1,6 +1,6 @@
1
1
  import type { ZodType } from "zod";
2
2
  import { StructuredOutputError } from "./errors.js";
3
- import type { LocalOptions, ModelSelection } from "./types/agent.js";
3
+ import type { BuiltinToolName, LocalOptions, MemorySettings, ModelSelection } from "./types/agent.js";
4
4
  import type { ProviderRoutingSettings } from "./types/providers.js";
5
5
  /**
6
6
  * Options accepted by {@link Agent.streamObject}. Same shape as
@@ -26,6 +26,19 @@ export interface StreamObjectOptions<T extends ZodType> {
26
26
  * when the right env key is set under a different provider name.
27
27
  */
28
28
  providers?: ProviderRoutingSettings;
29
+ /**
30
+ * Builtin tools removed from the transient agent's catalogue, forwarded to
31
+ * {@link AgentOptions.withheldBuiltinTools}. Absent ⇒ unchanged default: the agent holds
32
+ * `shell`. Pass `["shell"]` for a step that must only produce JSON. The `output` tool is
33
+ * never withheld.
34
+ */
35
+ withheldBuiltinTools?: readonly BuiltinToolName[];
36
+ /**
37
+ * Memory settings for the transient agent, forwarded to {@link AgentOptions.memory}.
38
+ * Absent ⇒ unchanged default (a session transcript is written). Pass `{ enabled: false }`
39
+ * for a step that must leave no transcript.
40
+ */
41
+ memory?: MemorySettings;
29
42
  }
30
43
  /**
31
44
  * Recursive partial — `T` where every nested field becomes optional.
@@ -1,4 +1,4 @@
1
- import { a as AgentDefinition } from './agent-Cn0sphpA.cjs';
1
+ import { a as AgentDefinition } from './agent-iW5kPpfT.cjs';
2
2
  import './sdk-agent-4-dXI2GS.cjs';
3
3
  import './agent-prims-CZyxfCmS.cjs';
4
4
  import 'zod';
@@ -1,4 +1,4 @@
1
- import { a as AgentDefinition } from './agent-CVzDy_Oj.js';
1
+ import { a as AgentDefinition } from './agent-DSMuwADp.js';
2
2
  import './sdk-agent-CTOJlWA_.js';
3
3
  import './agent-prims-CZyxfCmS.js';
4
4
  import 'zod';
@@ -581,7 +581,14 @@ export interface AgentOptions {
581
581
  *
582
582
  * - **Named-enable settings** — `{ enabled: ["name", ...] }`. Selects which
583
583
  * file-discovered plugin providers (under `.theokit/plugins/`) are active.
584
- * Plugin sources must also be active via `local.settingSources`.
584
+ * Plugin sources must also be active via `local.settingSources`. A folder
585
+ * under `<cwd>/.theokit/plugins/` whose `PLUGIN.md` names an `entry` has
586
+ * that entry imported and its default export (a `kind: "general"` plugin)
587
+ * registered, but only when the folder's absolute realpath is listed in
588
+ * `~/.theokit/plugins/trusted-workspace-plugins.json` (a JSON array, read on
589
+ * each `Agent.create`). The provider trust list never authorizes a workspace
590
+ * folder. An untrusted folder is listed and never imported; foreign roots
591
+ * are never imported.
585
592
  * - **Code `Plugin` objects** — an array of `Plugin` instances, e.g.
586
593
  * `plugins: [Handoff.asPlugin({ ... })]`. These are registered directly by
587
594
  * the runtime (`extractCodePlugins`); no `settingSources` entry is needed.
@@ -14,13 +14,14 @@
14
14
  * Measured twice on this file on 2026-09-01: once with the tag, and again when the comment
15
15
  * EXPLAINING the trap quoted the tag verbatim and re-armed it.
16
16
  */
17
- import type { ZodType, z } from "zod";
17
+ import { type ZodType, z } from "zod";
18
18
  import { TheokitAgentError } from "./errors.js";
19
19
  import type { CustomTool } from "./types/agent.js";
20
- import type { WorkflowRun } from "./types/workflow.js";
20
+ import type { WorkflowResumeOptions, WorkflowRun } from "./types/workflow.js";
21
21
  /**
22
- * Raised by a {@link workflowAsTool} tool when the wrapped workflow run does not
23
- * reach `status: "completed"` (a step failed, the run was cancelled/suspended).
22
+ * Raised by a {@link workflowAsTool} or {@link workflowResumeTool} tool when the
23
+ * run does not reach `status: "completed"` (a step failed, the run was cancelled,
24
+ * or it suspended without `reportSuspended`, which returns a report instead).
24
25
  * The dispatch converts it to a `tool_result(isError)`.
25
26
  *
26
27
  * @public
@@ -47,6 +48,22 @@ export interface WorkflowAsToolSpec<T extends ZodType> {
47
48
  description: string;
48
49
  /** Zod schema for the workflow's input (a `Workflow` carries no top-level schema). */
49
50
  inputSchema: T;
51
+ /**
52
+ * When `true`, a run that suspends returns `{"status":"suspended","runId":…,"stepId":…}` instead of
53
+ * raising {@link WorkflowToolError}, so the model can hand the run id to a
54
+ * {@link workflowResumeTool}. The report carries ids only, never the suspended payload; `stepId` is
55
+ * `null` for a run that carries no step result. Default `false`.
56
+ */
57
+ reportSuspended?: boolean;
58
+ }
59
+ /** Spec for {@link workflowResumeTool}. */
60
+ export interface WorkflowResumeToolSpec {
61
+ /** Tool name surfaced to the LLM. Same constraints as a `CustomTool.name`. */
62
+ name: string;
63
+ /** Description surfaced to the LLM — when the agent should resume a suspended run. */
64
+ description: string;
65
+ /** Report a run that suspends again instead of raising, as in {@link WorkflowAsToolSpec}. */
66
+ reportSuspended?: boolean;
50
67
  }
51
68
  /**
52
69
  * SE19 — expose a {@link Workflow} as an agent {@link CustomTool}, completing the
@@ -54,7 +71,8 @@ export interface WorkflowAsToolSpec<T extends ZodType> {
54
71
  * The handler validates the model's args against `spec.inputSchema`, runs the
55
72
  * workflow, and returns its output (a string as-is, else JSON). A run that does not
56
73
  * reach `status: "completed"` raises a typed {@link WorkflowToolError} (workflow
57
- * step errors do NOT throw — they surface via `run.status === "failed"`).
74
+ * step errors do NOT throw — they surface via `run.status === "failed"`), except a
75
+ * suspended run with `spec.reportSuspended`, which returns the suspended report.
58
76
  *
59
77
  * Accepts any `{ run }`-shaped workflow (structural), so it never imports the
60
78
  * `Workflow` class directly.
@@ -64,3 +82,19 @@ export interface WorkflowAsToolSpec<T extends ZodType> {
64
82
  export declare function workflowAsTool<T extends ZodType, TOutput = unknown>(workflow: {
65
83
  run: (input: z.infer<T>) => Promise<WorkflowRun<TOutput>>;
66
84
  }, spec: WorkflowAsToolSpec<T>): CustomTool;
85
+ /**
86
+ * B-677 — a {@link CustomTool} that resumes a suspended run of `workflow` by its run id, with an
87
+ * optional payload validated against the suspend step's schema. It returns the run's output like
88
+ * {@link workflowAsTool}; a run that suspends again keeps the same run id and is reported or raised
89
+ * per `spec.reportSuspended`. Snapshot errors (`WorkflowSnapshotNotFoundError` for an unknown or
90
+ * already-resumed id, `WorkflowResumeWorkflowMismatchError` for a run another workflow suspended,
91
+ * `WorkflowResumeStepNotFoundError` when `workflow` lacks the suspended step) and payload validation
92
+ * errors propagate to the dispatch.
93
+ *
94
+ * `workflow` must be the committed instance from `Workflow.create().commit()`. The default snapshot
95
+ * store is in memory and process-local: a host that resumes across processes configures a persistent
96
+ * backend. This tool resumes any run id it is given; deciding who may approve a run is the host's job.
97
+ *
98
+ * @public
99
+ */
100
+ export declare function workflowResumeTool(workflow: WorkflowResumeOptions["workflow"], spec: WorkflowResumeToolSpec): CustomTool;
@@ -137,6 +137,22 @@ export declare class WorkflowResumeStepNotFoundError extends TheokitAgentError {
137
137
  readonly name = "WorkflowResumeStepNotFoundError";
138
138
  constructor(stepId: string, workflowName: string);
139
139
  }
140
+ /**
141
+ * Thrown by `Workflow.resume()` (and so by a `workflowResumeTool` tool) when the snapshot for the run
142
+ * id was written by a workflow of another name. The snapshot is left in the store, so the workflow
143
+ * that suspended the run can still resume it.
144
+ *
145
+ * Without this check the default store, one process-global memory store, would let workflow B run
146
+ * its own tail on workflow A's accumulated input whenever both declare a step with the suspended id.
147
+ * `name` is a label, not an identity: two workflows that share a name are not told apart here.
148
+ */
149
+ export declare class WorkflowResumeWorkflowMismatchError extends TheokitAgentError {
150
+ readonly runId: string;
151
+ readonly snapshotWorkflowName: string;
152
+ readonly workflowName: string;
153
+ readonly name = "WorkflowResumeWorkflowMismatchError";
154
+ constructor(runId: string, snapshotWorkflowName: string, workflowName: string);
155
+ }
140
156
  /**
141
157
  * Aggregate failure from parallel branches.
142
158
  *
package/dist/workflow.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkZWLFHSON_cjs = require('./chunk-ZWLFHSON.cjs');
4
- var chunkTLVI2OQK_cjs = require('./chunk-TLVI2OQK.cjs');
3
+ var chunkR35ZJAYT_cjs = require('./chunk-R35ZJAYT.cjs');
4
+ var chunkSETHRLQS_cjs = require('./chunk-SETHRLQS.cjs');
5
5
  require('./chunk-VTYY7XL5.cjs');
6
6
  require('./chunk-AA27GEYS.cjs');
7
7
  require('./chunk-3KIUY67P.cjs');
@@ -14,87 +14,95 @@ require('./chunk-RNXXYF22.cjs');
14
14
 
15
15
  Object.defineProperty(exports, "Workflow", {
16
16
  enumerable: true,
17
- get: function () { return chunkZWLFHSON_cjs.Workflow; }
17
+ get: function () { return chunkR35ZJAYT_cjs.Workflow; }
18
18
  });
19
19
  Object.defineProperty(exports, "WorkflowBuilder", {
20
20
  enumerable: true,
21
- get: function () { return chunkZWLFHSON_cjs.WorkflowBuilder; }
21
+ get: function () { return chunkR35ZJAYT_cjs.WorkflowBuilder; }
22
22
  });
23
23
  Object.defineProperty(exports, "WorkflowToolError", {
24
24
  enumerable: true,
25
- get: function () { return chunkZWLFHSON_cjs.WorkflowToolError; }
25
+ get: function () { return chunkR35ZJAYT_cjs.WorkflowToolError; }
26
26
  });
27
27
  Object.defineProperty(exports, "agentStep", {
28
28
  enumerable: true,
29
- get: function () { return chunkZWLFHSON_cjs.agentStep; }
29
+ get: function () { return chunkR35ZJAYT_cjs.agentStep; }
30
30
  });
31
31
  Object.defineProperty(exports, "cloneWorkflow", {
32
32
  enumerable: true,
33
- get: function () { return chunkZWLFHSON_cjs.cloneWorkflow; }
33
+ get: function () { return chunkR35ZJAYT_cjs.cloneWorkflow; }
34
34
  });
35
35
  Object.defineProperty(exports, "fn", {
36
36
  enumerable: true,
37
- get: function () { return chunkZWLFHSON_cjs.fn; }
37
+ get: function () { return chunkR35ZJAYT_cjs.fn; }
38
38
  });
39
39
  Object.defineProperty(exports, "workflowAsTool", {
40
40
  enumerable: true,
41
- get: function () { return chunkZWLFHSON_cjs.workflowAsTool; }
41
+ get: function () { return chunkR35ZJAYT_cjs.workflowAsTool; }
42
+ });
43
+ Object.defineProperty(exports, "workflowResumeTool", {
44
+ enumerable: true,
45
+ get: function () { return chunkR35ZJAYT_cjs.workflowResumeTool; }
42
46
  });
43
47
  Object.defineProperty(exports, "workflowStep", {
44
48
  enumerable: true,
45
- get: function () { return chunkZWLFHSON_cjs.workflowStep; }
49
+ get: function () { return chunkR35ZJAYT_cjs.workflowStep; }
46
50
  });
47
51
  Object.defineProperty(exports, "WorkflowAlreadyRunningError", {
48
52
  enumerable: true,
49
- get: function () { return chunkTLVI2OQK_cjs.WorkflowAlreadyRunningError; }
53
+ get: function () { return chunkSETHRLQS_cjs.WorkflowAlreadyRunningError; }
50
54
  });
51
55
  Object.defineProperty(exports, "WorkflowCompensateNotImplementedError", {
52
56
  enumerable: true,
53
- get: function () { return chunkTLVI2OQK_cjs.WorkflowCompensateNotImplementedError; }
57
+ get: function () { return chunkSETHRLQS_cjs.WorkflowCompensateNotImplementedError; }
54
58
  });
55
59
  Object.defineProperty(exports, "WorkflowDuplicateStepIdError", {
56
60
  enumerable: true,
57
- get: function () { return chunkTLVI2OQK_cjs.WorkflowDuplicateStepIdError; }
61
+ get: function () { return chunkSETHRLQS_cjs.WorkflowDuplicateStepIdError; }
58
62
  });
59
63
  Object.defineProperty(exports, "WorkflowInputError", {
60
64
  enumerable: true,
61
- get: function () { return chunkTLVI2OQK_cjs.WorkflowInputError; }
65
+ get: function () { return chunkSETHRLQS_cjs.WorkflowInputError; }
62
66
  });
63
67
  Object.defineProperty(exports, "WorkflowMaxIterationsExceededError", {
64
68
  enumerable: true,
65
- get: function () { return chunkTLVI2OQK_cjs.WorkflowMaxIterationsExceededError; }
69
+ get: function () { return chunkSETHRLQS_cjs.WorkflowMaxIterationsExceededError; }
66
70
  });
67
71
  Object.defineProperty(exports, "WorkflowNestedError", {
68
72
  enumerable: true,
69
- get: function () { return chunkTLVI2OQK_cjs.WorkflowNestedError; }
73
+ get: function () { return chunkSETHRLQS_cjs.WorkflowNestedError; }
70
74
  });
71
75
  Object.defineProperty(exports, "WorkflowNotSerializableError", {
72
76
  enumerable: true,
73
- get: function () { return chunkTLVI2OQK_cjs.WorkflowNotSerializableError; }
77
+ get: function () { return chunkSETHRLQS_cjs.WorkflowNotSerializableError; }
74
78
  });
75
79
  Object.defineProperty(exports, "WorkflowOutputError", {
76
80
  enumerable: true,
77
- get: function () { return chunkTLVI2OQK_cjs.WorkflowOutputError; }
81
+ get: function () { return chunkSETHRLQS_cjs.WorkflowOutputError; }
78
82
  });
79
83
  Object.defineProperty(exports, "WorkflowParallelError", {
80
84
  enumerable: true,
81
- get: function () { return chunkTLVI2OQK_cjs.WorkflowParallelError; }
85
+ get: function () { return chunkSETHRLQS_cjs.WorkflowParallelError; }
82
86
  });
83
87
  Object.defineProperty(exports, "WorkflowResumeStepNotFoundError", {
84
88
  enumerable: true,
85
- get: function () { return chunkTLVI2OQK_cjs.WorkflowResumeStepNotFoundError; }
89
+ get: function () { return chunkSETHRLQS_cjs.WorkflowResumeStepNotFoundError; }
90
+ });
91
+ Object.defineProperty(exports, "WorkflowResumeWorkflowMismatchError", {
92
+ enumerable: true,
93
+ get: function () { return chunkSETHRLQS_cjs.WorkflowResumeWorkflowMismatchError; }
86
94
  });
87
95
  Object.defineProperty(exports, "WorkflowSnapshotNotFoundError", {
88
96
  enumerable: true,
89
- get: function () { return chunkTLVI2OQK_cjs.WorkflowSnapshotNotFoundError; }
97
+ get: function () { return chunkSETHRLQS_cjs.WorkflowSnapshotNotFoundError; }
90
98
  });
91
99
  Object.defineProperty(exports, "WorkflowStateError", {
92
100
  enumerable: true,
93
- get: function () { return chunkTLVI2OQK_cjs.WorkflowStateError; }
101
+ get: function () { return chunkSETHRLQS_cjs.WorkflowStateError; }
94
102
  });
95
103
  Object.defineProperty(exports, "__resetSnapshotStoresForTests", {
96
104
  enumerable: true,
97
- get: function () { return chunkTLVI2OQK_cjs.__resetSnapshotStoresForTests; }
105
+ get: function () { return chunkSETHRLQS_cjs.__resetSnapshotStoresForTests; }
98
106
  });
99
107
  //# sourceMappingURL=workflow.cjs.map
100
108
  //# sourceMappingURL=workflow.cjs.map