@relayflows/sdk 2.0.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 (231) hide show
  1. package/dist/authored-flow-error.d.ts +9 -0
  2. package/dist/authored-flow-error.d.ts.map +1 -0
  3. package/dist/authored-flow-error.js +13 -0
  4. package/dist/authored-flow-error.js.map +1 -0
  5. package/dist/authored-flow-executor.d.ts +28 -0
  6. package/dist/authored-flow-executor.d.ts.map +1 -0
  7. package/dist/authored-flow-executor.js +203 -0
  8. package/dist/authored-flow-executor.js.map +1 -0
  9. package/dist/authored-flow-lifecycle.d.ts +61 -0
  10. package/dist/authored-flow-lifecycle.d.ts.map +1 -0
  11. package/dist/authored-flow-lifecycle.js +284 -0
  12. package/dist/authored-flow-lifecycle.js.map +1 -0
  13. package/dist/authored-flow-loader.d.ts +7 -0
  14. package/dist/authored-flow-loader.d.ts.map +1 -0
  15. package/dist/authored-flow-loader.js +39 -0
  16. package/dist/authored-flow-loader.js.map +1 -0
  17. package/dist/authored-flow-operation.d.ts +43 -0
  18. package/dist/authored-flow-operation.d.ts.map +1 -0
  19. package/dist/authored-flow-operation.js +176 -0
  20. package/dist/authored-flow-operation.js.map +1 -0
  21. package/dist/authored-flow.d.ts +12 -0
  22. package/dist/authored-flow.d.ts.map +1 -0
  23. package/dist/authored-flow.js +13 -0
  24. package/dist/authored-flow.js.map +1 -0
  25. package/dist/authored-promise-graph.d.ts +67 -0
  26. package/dist/authored-promise-graph.d.ts.map +1 -0
  27. package/dist/authored-promise-graph.js +206 -0
  28. package/dist/authored-promise-graph.js.map +1 -0
  29. package/dist/backlog-picker.d.ts +55 -0
  30. package/dist/backlog-picker.d.ts.map +1 -0
  31. package/dist/backlog-picker.js +117 -0
  32. package/dist/backlog-picker.js.map +1 -0
  33. package/dist/canonical.d.ts +18 -0
  34. package/dist/canonical.d.ts.map +1 -0
  35. package/dist/canonical.js +55 -0
  36. package/dist/canonical.js.map +1 -0
  37. package/dist/cli/check.d.ts +30 -0
  38. package/dist/cli/check.d.ts.map +1 -0
  39. package/dist/cli/check.js +324 -0
  40. package/dist/cli/check.js.map +1 -0
  41. package/dist/cli/direct-run.d.ts +3 -0
  42. package/dist/cli/direct-run.d.ts.map +1 -0
  43. package/dist/cli/direct-run.js +69 -0
  44. package/dist/cli/direct-run.js.map +1 -0
  45. package/dist/cli/hn-monitor.d.ts +107 -0
  46. package/dist/cli/hn-monitor.d.ts.map +1 -0
  47. package/dist/cli/hn-monitor.js +220 -0
  48. package/dist/cli/hn-monitor.js.map +1 -0
  49. package/dist/cli/interruptible-sleep.d.ts +13 -0
  50. package/dist/cli/interruptible-sleep.d.ts.map +1 -0
  51. package/dist/cli/interruptible-sleep.js +31 -0
  52. package/dist/cli/interruptible-sleep.js.map +1 -0
  53. package/dist/cli/run.d.ts +54 -0
  54. package/dist/cli/run.d.ts.map +1 -0
  55. package/dist/cli/run.js +316 -0
  56. package/dist/cli/run.js.map +1 -0
  57. package/dist/cli/tick-runner.d.ts +151 -0
  58. package/dist/cli/tick-runner.d.ts.map +1 -0
  59. package/dist/cli/tick-runner.js +258 -0
  60. package/dist/cli/tick-runner.js.map +1 -0
  61. package/dist/cli-adapter.d.ts +29 -0
  62. package/dist/cli-adapter.d.ts.map +1 -0
  63. package/dist/cli-adapter.js +92 -0
  64. package/dist/cli-adapter.js.map +1 -0
  65. package/dist/cli-executable.d.ts +3 -0
  66. package/dist/cli-executable.d.ts.map +1 -0
  67. package/dist/cli-executable.js +10 -0
  68. package/dist/cli-executable.js.map +1 -0
  69. package/dist/cli.d.ts +9 -0
  70. package/dist/cli.d.ts.map +1 -0
  71. package/dist/cli.js +348 -0
  72. package/dist/cli.js.map +1 -0
  73. package/dist/compile.d.ts +42 -0
  74. package/dist/compile.d.ts.map +1 -0
  75. package/dist/compile.js +515 -0
  76. package/dist/compile.js.map +1 -0
  77. package/dist/demo-hn-monitor.d.ts +2 -0
  78. package/dist/demo-hn-monitor.d.ts.map +1 -0
  79. package/dist/demo-hn-monitor.js +118 -0
  80. package/dist/demo-hn-monitor.js.map +1 -0
  81. package/dist/dir-watcher-poller.d.ts +73 -0
  82. package/dist/dir-watcher-poller.d.ts.map +1 -0
  83. package/dist/dir-watcher-poller.js +80 -0
  84. package/dist/dir-watcher-poller.js.map +1 -0
  85. package/dist/direct-input.d.ts +10 -0
  86. package/dist/direct-input.d.ts.map +1 -0
  87. package/dist/direct-input.js +61 -0
  88. package/dist/direct-input.js.map +1 -0
  89. package/dist/failure-kinds.d.ts +25 -0
  90. package/dist/failure-kinds.d.ts.map +1 -0
  91. package/dist/failure-kinds.js +64 -0
  92. package/dist/failure-kinds.js.map +1 -0
  93. package/dist/gate-contract.d.ts +24 -0
  94. package/dist/gate-contract.d.ts.map +1 -0
  95. package/dist/gate-contract.js +50 -0
  96. package/dist/gate-contract.js.map +1 -0
  97. package/dist/hn-poller.d.ts +50 -0
  98. package/dist/hn-poller.d.ts.map +1 -0
  99. package/dist/hn-poller.js +79 -0
  100. package/dist/hn-poller.js.map +1 -0
  101. package/dist/index.d.ts +21 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +30 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/journal-client.d.ts +122 -0
  106. package/dist/journal-client.d.ts.map +1 -0
  107. package/dist/journal-client.js +277 -0
  108. package/dist/journal-client.js.map +1 -0
  109. package/dist/json-schema-bound.d.ts +7 -0
  110. package/dist/json-schema-bound.d.ts.map +1 -0
  111. package/dist/json-schema-bound.js +353 -0
  112. package/dist/json-schema-bound.js.map +1 -0
  113. package/dist/json-schema.d.ts +5 -0
  114. package/dist/json-schema.d.ts.map +1 -0
  115. package/dist/json-schema.js +72 -0
  116. package/dist/json-schema.js.map +1 -0
  117. package/dist/json-value.d.ts +6 -0
  118. package/dist/json-value.d.ts.map +1 -0
  119. package/dist/json-value.js +94 -0
  120. package/dist/json-value.js.map +1 -0
  121. package/dist/model-name.d.ts +7 -0
  122. package/dist/model-name.d.ts.map +1 -0
  123. package/dist/model-name.js +21 -0
  124. package/dist/model-name.js.map +1 -0
  125. package/dist/output-schema.d.ts +8 -0
  126. package/dist/output-schema.d.ts.map +1 -0
  127. package/dist/output-schema.js +28 -0
  128. package/dist/output-schema.js.map +1 -0
  129. package/dist/preflight.d.ts +80 -0
  130. package/dist/preflight.d.ts.map +1 -0
  131. package/dist/preflight.js +361 -0
  132. package/dist/preflight.js.map +1 -0
  133. package/dist/protocol.d.ts +359 -0
  134. package/dist/protocol.d.ts.map +1 -0
  135. package/dist/protocol.js +15 -0
  136. package/dist/protocol.js.map +1 -0
  137. package/dist/spec.d.ts +294 -0
  138. package/dist/spec.d.ts.map +1 -0
  139. package/dist/spec.js +13 -0
  140. package/dist/spec.js.map +1 -0
  141. package/dist/step-dependencies.d.ts +2 -0
  142. package/dist/step-dependencies.d.ts.map +1 -0
  143. package/dist/step-dependencies.js +88 -0
  144. package/dist/step-dependencies.js.map +1 -0
  145. package/dist/step-fields.d.ts +17 -0
  146. package/dist/step-fields.d.ts.map +1 -0
  147. package/dist/step-fields.js +32 -0
  148. package/dist/step-fields.js.map +1 -0
  149. package/dist/tick-source.d.ts +205 -0
  150. package/dist/tick-source.d.ts.map +1 -0
  151. package/dist/tick-source.js +234 -0
  152. package/dist/tick-source.js.map +1 -0
  153. package/dist/unknown-keys.d.ts +7 -0
  154. package/dist/unknown-keys.d.ts.map +1 -0
  155. package/dist/unknown-keys.js +47 -0
  156. package/dist/unknown-keys.js.map +1 -0
  157. package/dist/validate.d.ts +7 -0
  158. package/dist/validate.d.ts.map +1 -0
  159. package/dist/validate.js +458 -0
  160. package/dist/validate.js.map +1 -0
  161. package/dist/work-package-consumer.d.ts +33 -0
  162. package/dist/work-package-consumer.d.ts.map +1 -0
  163. package/dist/work-package-consumer.js +44 -0
  164. package/dist/work-package-consumer.js.map +1 -0
  165. package/dist/work-package-validator.d.ts +15 -0
  166. package/dist/work-package-validator.d.ts.map +1 -0
  167. package/dist/work-package-validator.js +72 -0
  168. package/dist/work-package-validator.js.map +1 -0
  169. package/dist/worker-cli.d.ts +16 -0
  170. package/dist/worker-cli.d.ts.map +1 -0
  171. package/dist/worker-cli.js +77 -0
  172. package/dist/worker-cli.js.map +1 -0
  173. package/dist/worker.d.ts +57 -0
  174. package/dist/worker.d.ts.map +1 -0
  175. package/dist/worker.js +129 -0
  176. package/dist/worker.js.map +1 -0
  177. package/dist/wrapper-runtime.d.ts +10 -0
  178. package/dist/wrapper-runtime.d.ts.map +1 -0
  179. package/dist/wrapper-runtime.js +83 -0
  180. package/dist/wrapper-runtime.js.map +1 -0
  181. package/dist/wrapper-session.d.ts +16 -0
  182. package/dist/wrapper-session.d.ts.map +1 -0
  183. package/dist/wrapper-session.js +244 -0
  184. package/dist/wrapper-session.js.map +1 -0
  185. package/package.json +50 -0
  186. package/src/authored-flow-error.ts +31 -0
  187. package/src/authored-flow-executor.ts +365 -0
  188. package/src/authored-flow-lifecycle.ts +344 -0
  189. package/src/authored-flow-loader.ts +44 -0
  190. package/src/authored-flow-operation.ts +252 -0
  191. package/src/authored-flow.ts +21 -0
  192. package/src/authored-promise-graph.ts +196 -0
  193. package/src/backlog-picker.ts +153 -0
  194. package/src/canonical.ts +57 -0
  195. package/src/cli/check.ts +391 -0
  196. package/src/cli/direct-run.ts +86 -0
  197. package/src/cli/hn-monitor.ts +286 -0
  198. package/src/cli/interruptible-sleep.ts +27 -0
  199. package/src/cli/run.ts +439 -0
  200. package/src/cli/tick-runner.ts +378 -0
  201. package/src/cli-adapter.ts +115 -0
  202. package/src/cli-executable.ts +12 -0
  203. package/src/cli.ts +364 -0
  204. package/src/compile.ts +573 -0
  205. package/src/demo-hn-monitor.ts +132 -0
  206. package/src/dir-watcher-poller.ts +122 -0
  207. package/src/direct-input.ts +69 -0
  208. package/src/failure-kinds.ts +77 -0
  209. package/src/gate-contract.ts +72 -0
  210. package/src/hn-poller.ts +104 -0
  211. package/src/index.ts +195 -0
  212. package/src/journal-client.ts +379 -0
  213. package/src/json-schema-bound.ts +357 -0
  214. package/src/json-schema.ts +65 -0
  215. package/src/json-value.ts +110 -0
  216. package/src/model-name.ts +20 -0
  217. package/src/output-schema.ts +33 -0
  218. package/src/preflight.ts +482 -0
  219. package/src/protocol.ts +364 -0
  220. package/src/spec.ts +343 -0
  221. package/src/step-dependencies.ts +100 -0
  222. package/src/step-fields.ts +36 -0
  223. package/src/tick-source.ts +334 -0
  224. package/src/unknown-keys.ts +52 -0
  225. package/src/validate.ts +503 -0
  226. package/src/work-package-consumer.ts +73 -0
  227. package/src/work-package-validator.ts +90 -0
  228. package/src/worker-cli.ts +110 -0
  229. package/src/worker.ts +150 -0
  230. package/src/wrapper-runtime.ts +93 -0
  231. package/src/wrapper-session.ts +287 -0
@@ -0,0 +1,15 @@
1
+ export type NextWorkPackageRefusalReason = 'nonexistent_repo_path' | 'test_claim_without_evidence';
2
+ export type NextWorkPackageValidation = {
3
+ accepted: true;
4
+ } | {
5
+ accepted: false;
6
+ reason: NextWorkPackageRefusalReason;
7
+ };
8
+ /** Resolve a referenced path. Injectable so validation is deterministic in tests. */
9
+ export type WorkPackagePathExists = (path: string) => boolean;
10
+ /**
11
+ * Validate claims and repository references in an ops/NEXT.md work package.
12
+ * Refusals are values so a caller cannot mistake an unchecked package for work.
13
+ */
14
+ export declare function validateNextWorkPackage(markdown: string, pathExists?: WorkPackagePathExists): NextWorkPackageValidation;
15
+ //# sourceMappingURL=work-package-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-package-validator.d.ts","sourceRoot":"","sources":["../src/work-package-validator.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,4BAA4B,GACpC,uBAAuB,GACvB,6BAA6B,CAAC;AAElC,MAAM,MAAM,yBAAyB,GACjC;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAClB;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,4BAA4B,CAAA;CAAE,CAAC;AAE9D,qFAAqF;AACrF,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;AAQ9D;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,qBAAyC,GACpD,yBAAyB,CA4B3B"}
@@ -0,0 +1,72 @@
1
+ import { existsSync } from 'node:fs';
2
+ const defaultPathExists = (path) => existsSync(path);
3
+ const INLINE_CODE = /(?<!`)`([^`\n]+)`(?!`)/g;
4
+ const REPO_PATH = /^[A-Za-z_][A-Za-z0-9._-]*(?:\/[A-Za-z0-9._-]+)+$/;
5
+ const TEST_RESULT_CLAIM = /(?:\b(?:all|both|one|two|three|four|five|six|seven|eight|nine|ten|\d+|tests?|test suite|checks?|build)\b[^\n]{0,60}\b(?:green|pass(?:ed|es|ing)?|succeed(?:ed|s)?|tested)\b|\b(?:is|are|was|were|has been|have been)\b[^\n]{0,60}\btested\b)/i;
6
+ /**
7
+ * Validate claims and repository references in an ops/NEXT.md work package.
8
+ * Refusals are values so a caller cannot mistake an unchecked package for work.
9
+ */
10
+ export function validateNextWorkPackage(markdown, pathExists = defaultPathExists) {
11
+ for (const path of referencedRepoPaths(markdown)) {
12
+ if (!pathExists(path))
13
+ return { accepted: false, reason: 'nonexistent_repo_path' };
14
+ }
15
+ const lines = markdown.split(/\r?\n/);
16
+ const fencedLines = findFencedLines(lines);
17
+ for (const [index, line] of lines.entries()) {
18
+ if (fencedLines.has(index) || !TEST_RESULT_CLAIM.test(line))
19
+ continue;
20
+ // A REQUIREMENT is not a CLAIM. "npm test must be green" states what has to
21
+ // become true; "All three tests pass" asserts it already is. Only the
22
+ // second needs evidence (review, PR #50).
23
+ //
24
+ // The discriminator is MODALITY, not location. A first attempt at this
25
+ // exempted every line under a "Definition of done" heading, which let the
26
+ // PR #19 artifact through — its claim "All three tests pass." sits under
27
+ // exactly that heading and is precisely what this must catch.
28
+ //
29
+ // The modal check was already here but keyed only on "pass", so "must be
30
+ // green" and "must be clean" still tripped it.
31
+ if (/\b(?:must|should|will|needs? to|has to)\b[^\n]{0,40}\b(?:pass|passing|green|clean|succeed)\b/i.test(line)) {
32
+ continue;
33
+ }
34
+ if (!hasNearbyTranscript(lines, fencedLines, index)) {
35
+ return { accepted: false, reason: 'test_claim_without_evidence' };
36
+ }
37
+ }
38
+ return { accepted: true };
39
+ }
40
+ function referencedRepoPaths(markdown) {
41
+ return [...markdown.matchAll(INLINE_CODE)]
42
+ .map((match) => match[1] ?? '')
43
+ .filter((candidate) => REPO_PATH.test(candidate));
44
+ }
45
+ function findFencedLines(lines) {
46
+ const fenced = new Set();
47
+ let open = false;
48
+ for (const [index, line] of lines.entries()) {
49
+ if (/^\s*```/.test(line)) {
50
+ fenced.add(index);
51
+ open = !open;
52
+ }
53
+ else if (open) {
54
+ fenced.add(index);
55
+ }
56
+ }
57
+ return fenced;
58
+ }
59
+ function hasNearbyTranscript(lines, fenced, claimIndex) {
60
+ const nearby = lines
61
+ .map((line, index) => ({ line, index }))
62
+ .filter(({ index }) => fenced.has(index) && Math.abs(index - claimIndex) <= 10)
63
+ .map(({ line }) => line.trim())
64
+ .filter((line) => line.length > 0 && !line.startsWith('```'));
65
+ const commandIndex = nearby.findIndex(isCommandLine);
66
+ return commandIndex >= 0 && nearby.some((line, index) => index > commandIndex && !isCommandLine(line));
67
+ }
68
+ function isCommandLine(line) {
69
+ const command = line.startsWith('$ ') ? line.slice(2) : line;
70
+ return /^(?:cd\s+\S+\s*&&\s*)?(?:npm|node|cargo|sh|pnpm|yarn|pytest|go)\b/.test(command);
71
+ }
72
+ //# sourceMappingURL=work-package-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-package-validator.js","sourceRoot":"","sources":["../src/work-package-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type WrapperSessionLimits } from './wrapper-session.js';
2
+ /** Present only when a dispatched agent step carries a journaled wake context. */
3
+ export declare const WAKE_CONTEXT_ENV = "RELAYFLOW_WAKE_CONTEXT";
4
+ /**
5
+ * Private wrapper model variable name. Ambient values are scrubbed; a wrapper
6
+ * may set it inside the already-identified process from the session request.
7
+ * Raw Claude/Codex adapters receive provider-native model flags.
8
+ */
9
+ export declare const MODEL_ENV = "RELAYFLOW_MODEL";
10
+ export interface WorkerCliResult {
11
+ exit_code: number | null;
12
+ stdout_tail: string;
13
+ stderr_tail: string;
14
+ }
15
+ export declare function runAgentCli(cli: string, instruction: string, wakeContext: unknown, model?: string, wrapperLimits?: Partial<WrapperSessionLimits>): Promise<WorkerCliResult>;
16
+ //# sourceMappingURL=worker-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-cli.d.ts","sourceRoot":"","sources":["../src/worker-cli.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAG9B,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,SAAS,oBAAoB,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,OAAO,EACpB,KAAK,CAAC,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAC5C,OAAO,CAAC,eAAe,CAAC,CAiC1B"}
@@ -0,0 +1,77 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { agentExecution, cliAdapterKind, } from './cli-adapter.js';
3
+ import { runWrapperSession, } from './wrapper-session.js';
4
+ import { wrapperEnvironment } from './wrapper-runtime.js';
5
+ /** Present only when a dispatched agent step carries a journaled wake context. */
6
+ export const WAKE_CONTEXT_ENV = 'RELAYFLOW_WAKE_CONTEXT';
7
+ /**
8
+ * Private wrapper model variable name. Ambient values are scrubbed; a wrapper
9
+ * may set it inside the already-identified process from the session request.
10
+ * Raw Claude/Codex adapters receive provider-native model flags.
11
+ */
12
+ export const MODEL_ENV = 'RELAYFLOW_MODEL';
13
+ export async function runAgentCli(cli, instruction, wakeContext, model, wrapperLimits) {
14
+ const kind = cliAdapterKind(cli);
15
+ if (kind === 'relayflows-wrapper-v1') {
16
+ return runWrapperSession(cli, instruction, wakeContext, model, wrapperEnvironment(process.env), wrapperLimits);
17
+ }
18
+ const env = { ...process.env };
19
+ delete env[WAKE_CONTEXT_ENV];
20
+ delete env[MODEL_ENV];
21
+ const invocation = agentExecution(kind, instruction, model);
22
+ if (wakeContext !== undefined) {
23
+ try {
24
+ env[WAKE_CONTEXT_ENV] = JSON.stringify(wakeContext);
25
+ }
26
+ catch (error) {
27
+ return {
28
+ exit_code: null,
29
+ stdout_tail: '',
30
+ stderr_tail: `wake_context could not be JSON-serialized for the CLI: ${String(error)}`,
31
+ };
32
+ }
33
+ }
34
+ if (invocation.modelEnv !== undefined)
35
+ env[MODEL_ENV] = invocation.modelEnv;
36
+ return spawnInvocation(cli, invocation, env);
37
+ }
38
+ function spawnInvocation(cli, invocation, env) {
39
+ return new Promise((resolve) => {
40
+ const child = spawn(cli, invocation.args, { stdio: ['ignore', 'pipe', 'pipe'], env });
41
+ const stdout = [];
42
+ const stderr = [];
43
+ let settled = false;
44
+ let timer;
45
+ const finish = (result) => {
46
+ if (settled)
47
+ return;
48
+ settled = true;
49
+ if (timer !== undefined)
50
+ clearTimeout(timer);
51
+ resolve(result);
52
+ };
53
+ child.stdout.on('data', (chunk) => stdout.push(chunk));
54
+ child.stderr.on('data', (chunk) => stderr.push(chunk));
55
+ child.once('error', (error) => finish({
56
+ exit_code: null,
57
+ stdout_tail: Buffer.concat(stdout).toString('utf8'),
58
+ stderr_tail: error.message,
59
+ }));
60
+ child.once('close', (code) => finish({
61
+ exit_code: code,
62
+ stdout_tail: Buffer.concat(stdout).toString('utf8'),
63
+ stderr_tail: Buffer.concat(stderr).toString('utf8'),
64
+ }));
65
+ if (invocation.timeoutMs > 0) {
66
+ timer = setTimeout(() => {
67
+ child.kill('SIGTERM');
68
+ finish({
69
+ exit_code: null,
70
+ stdout_tail: Buffer.concat(stdout).toString('utf8'),
71
+ stderr_tail: `CLI invocation timed out after ${invocation.timeoutMs}ms.`,
72
+ });
73
+ }, invocation.timeoutMs);
74
+ }
75
+ });
76
+ }
77
+ //# sourceMappingURL=worker-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-cli.js","sourceRoot":"","sources":["../src/worker-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { JournalClient } from './journal-client.js';
3
+ import type { Pins } from './protocol.js';
4
+ export { MODEL_ENV, WAKE_CONTEXT_ENV } from './worker-cli.js';
5
+ export interface AgentWorkerOptions {
6
+ workerId: string;
7
+ pins: Pins;
8
+ capacity?: number;
9
+ }
10
+ /**
11
+ * Executes dispatched agent steps using their declared CLI.
12
+ *
13
+ * Shutdown contract (close): async and drain-aware. The caller may await
14
+ * close() to guarantee every dispatch this worker started before close
15
+ * was called has either completed its stepComplete journal write or
16
+ * thrown out through the worker's `error` event. Dispatches that arrive
17
+ * AFTER close begins are ignored. Idempotent.
18
+ *
19
+ * Not implemented: releasing the worker registration with the kernel.
20
+ * `sdk/src/protocol.ts` has no `workerRelease` verb today, so on close()
21
+ * the kernel keeps this workerId in its registry until its lease expires.
22
+ * When workerRelease lands, add a client call at the top of close()
23
+ * (before the drain) so the kernel stops routing dispatches during
24
+ * shutdown.
25
+ */
26
+ export declare class AgentWorker extends EventEmitter {
27
+ private readonly client;
28
+ private readonly options;
29
+ private attached;
30
+ private closing;
31
+ private readonly inFlight;
32
+ constructor(client: JournalClient, options: AgentWorkerOptions);
33
+ attach(): Promise<void>;
34
+ /**
35
+ * Async, drain-aware shutdown. Awaits every dispatch in-flight; ignores
36
+ * dispatches that arrive after close() begins. Idempotent.
37
+ *
38
+ * A prior synchronous close() did NOT drain, so a caller shutting
39
+ * mid-dispatch could silently lose an in-flight step's stepComplete
40
+ * journal write when the socket was immediately shut. This closes
41
+ * that hole.
42
+ */
43
+ close(): Promise<void>;
44
+ private readonly onDispatch;
45
+ private execute;
46
+ }
47
+ /**
48
+ * Return an object-shaped JSON payload parsed from `stdout`, or
49
+ * `null` when stdout is empty, non-JSON, or JSON-of-a-scalar/array.
50
+ * The object-only restriction matches how `json_schema` gates are
51
+ * authored — a scalar or array sneaking through would confuse both
52
+ * the schema and downstream readers who expect field lookups on
53
+ * `output`. Text-emitting tools and non-object JSON both fall
54
+ * through to the CliResult wrapper preserved by the caller.
55
+ */
56
+ export declare function parseJsonOutput(stdout: string): Record<string, unknown> | null;
57
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,eAAe,CAAC;AAI7D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAMzC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;gBAGvC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,kBAAkB;IAKxC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB7B;;;;;;;;OAQG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAQzB;YAEY,OAAO;CAmCtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAa9E"}
package/dist/worker.js ADDED
@@ -0,0 +1,129 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { runAgentCli } from './worker-cli.js';
3
+ export { MODEL_ENV, WAKE_CONTEXT_ENV } from './worker-cli.js';
4
+ /**
5
+ * Executes dispatched agent steps using their declared CLI.
6
+ *
7
+ * Shutdown contract (close): async and drain-aware. The caller may await
8
+ * close() to guarantee every dispatch this worker started before close
9
+ * was called has either completed its stepComplete journal write or
10
+ * thrown out through the worker's `error` event. Dispatches that arrive
11
+ * AFTER close begins are ignored. Idempotent.
12
+ *
13
+ * Not implemented: releasing the worker registration with the kernel.
14
+ * `sdk/src/protocol.ts` has no `workerRelease` verb today, so on close()
15
+ * the kernel keeps this workerId in its registry until its lease expires.
16
+ * When workerRelease lands, add a client call at the top of close()
17
+ * (before the drain) so the kernel stops routing dispatches during
18
+ * shutdown.
19
+ */
20
+ export class AgentWorker extends EventEmitter {
21
+ client;
22
+ options;
23
+ attached = false;
24
+ closing = false;
25
+ inFlight = new Set();
26
+ constructor(client, options) {
27
+ super();
28
+ this.client = client;
29
+ this.options = options;
30
+ }
31
+ async attach() {
32
+ if (this.attached)
33
+ throw new Error('agent worker: already attached');
34
+ if (this.closing)
35
+ throw new Error('agent worker: cannot attach a closed worker (construct a new one)');
36
+ this.client.on('step.dispatch', this.onDispatch);
37
+ try {
38
+ await this.client.workerAttach(this.options.workerId, ['agent'], this.options.pins, this.options.capacity);
39
+ this.attached = true;
40
+ }
41
+ catch (error) {
42
+ this.client.off('step.dispatch', this.onDispatch);
43
+ throw error;
44
+ }
45
+ }
46
+ /**
47
+ * Async, drain-aware shutdown. Awaits every dispatch in-flight; ignores
48
+ * dispatches that arrive after close() begins. Idempotent.
49
+ *
50
+ * A prior synchronous close() did NOT drain, so a caller shutting
51
+ * mid-dispatch could silently lose an in-flight step's stepComplete
52
+ * journal write when the socket was immediately shut. This closes
53
+ * that hole.
54
+ */
55
+ async close() {
56
+ if (this.closing)
57
+ return;
58
+ this.closing = true;
59
+ this.client.off('step.dispatch', this.onDispatch);
60
+ const pending = Array.from(this.inFlight);
61
+ if (pending.length > 0) {
62
+ await Promise.allSettled(pending);
63
+ }
64
+ this.attached = false;
65
+ }
66
+ onDispatch = (dispatch) => {
67
+ if (this.closing)
68
+ return;
69
+ if (dispatch.step_type !== 'agent')
70
+ return;
71
+ const running = this.execute(dispatch).catch((error) => {
72
+ this.emit('error', error);
73
+ });
74
+ this.inFlight.add(running);
75
+ void running.finally(() => { this.inFlight.delete(running); });
76
+ };
77
+ async execute(dispatch) {
78
+ const spec = dispatch.spec;
79
+ const result = typeof spec.cli === 'string' && typeof spec.instruction === 'string'
80
+ ? await runAgentCli(spec.cli, spec.instruction, dispatch.wake_context, spec.model)
81
+ : { exit_code: null, stdout_tail: '', stderr_tail: 'agent step has no declared CLI' };
82
+ const completionReason = result.exit_code === 0 ? 'success' : 'worker_error';
83
+ // Output shape: if the CLI's stdout parses as JSON, promote THAT
84
+ // as the step's `output` value so `json_schema` verification
85
+ // validates the analysis payload, not a wrapper around stdout.
86
+ // On the JSON path the CliResult (exit_code / stdout_tail /
87
+ // stderr_tail) is DISCARDED from `output` — the schema author
88
+ // wrote a shape for the analysis, not for the process wrapper.
89
+ // Non-JSON stdout falls back to the wrapper so text-emitting
90
+ // tools still round-trip usefully.
91
+ //
92
+ // Implicit contract: CLIs signal errors via non-zero exit, not by
93
+ // emitting an error JSON with exit 0. `completionReason` is
94
+ // derived from exit code, so a CLI that exits 0 while emitting
95
+ // `{"error":...}` will report success with an error payload.
96
+ const output = parseJsonOutput(result.stdout_tail) ?? result;
97
+ await this.client.stepComplete(dispatch.run_id, dispatch.step_id, dispatch.attempt, dispatch.idempotency_key, completionReason, {
98
+ output,
99
+ started_pins: dispatch.pins,
100
+ end_pins: dispatch.pins,
101
+ });
102
+ }
103
+ }
104
+ /**
105
+ * Return an object-shaped JSON payload parsed from `stdout`, or
106
+ * `null` when stdout is empty, non-JSON, or JSON-of-a-scalar/array.
107
+ * The object-only restriction matches how `json_schema` gates are
108
+ * authored — a scalar or array sneaking through would confuse both
109
+ * the schema and downstream readers who expect field lookups on
110
+ * `output`. Text-emitting tools and non-object JSON both fall
111
+ * through to the CliResult wrapper preserved by the caller.
112
+ */
113
+ export function parseJsonOutput(stdout) {
114
+ const trimmed = stdout.trim();
115
+ if (trimmed === '')
116
+ return null;
117
+ let parsed;
118
+ try {
119
+ parsed = JSON.parse(trimmed);
120
+ }
121
+ catch {
122
+ return null;
123
+ }
124
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
125
+ return null;
126
+ }
127
+ return parsed;
128
+ }
129
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQ9D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,WAAY,SAAQ,YAAY;IAMxB;IACA;IANX,QAAQ,GAAG,KAAK,CAAC;IACjB,OAAO,GAAG,KAAK,CAAC;IACP,QAAQ,GAAuB,IAAI,GAAG,EAAE,CAAC;IAE1D,YACmB,MAAqB,EACrB,OAA2B;QAE5C,KAAK,EAAE,CAAC;QAHS,WAAM,GAAN,MAAM,CAAe;QACrB,YAAO,GAAP,OAAO,CAAoB;IAG9C,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACvG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAC5B,IAAI,CAAC,OAAO,CAAC,QAAQ,EACrB,CAAC,OAAO,CAAC,EACT,IAAI,CAAC,OAAO,CAAC,IAAI,EACjB,IAAI,CAAC,OAAO,CAAC,QAAQ,CACtB,CAAC;YACF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YAClD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IAEgB,UAAU,GAAG,CAAC,QAA2B,EAAQ,EAAE;QAClE,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,QAAQ,CAAC,SAAS,KAAK,OAAO;YAAE,OAAO;QAC3C,MAAM,OAAO,GAAkB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YAC7E,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3B,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,QAA2B;QAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAgC,CAAC;QACvD,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;YACjF,CAAC,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC;YAClF,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;QACxF,MAAM,gBAAgB,GAAG,MAAM,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC;QAE7E,iEAAiE;QACjE,6DAA6D;QAC7D,+DAA+D;QAC/D,4DAA4D;QAC5D,8DAA8D;QAC9D,+DAA+D;QAC/D,6DAA6D;QAC7D,mCAAmC;QACnC,EAAE;QACF,kEAAkE;QAClE,4DAA4D;QAC5D,+DAA+D;QAC/D,6DAA6D;QAC7D,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC;QAE7D,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAC5B,QAAQ,CAAC,MAAM,EACf,QAAQ,CAAC,OAAO,EAChB,QAAQ,CAAC,OAAO,EAChB,QAAQ,CAAC,eAAe,EACxB,gBAAgB,EAChB;YACE,MAAM;YACN,YAAY,EAAE,QAAQ,CAAC,IAAI;YAC3B,QAAQ,EAAE,QAAQ,CAAC,IAAI;SACxB,CACF,CAAC;IACJ,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAiC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface WrapperIdentity {
2
+ executable: string;
3
+ fingerprint: string;
4
+ }
5
+ /** Build a wrapper environment from a closed list; ambient credentials never cross. */
6
+ export declare function wrapperEnvironment(source: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
7
+ /** Resolve and fingerprint the exact executable that will enter the private protocol. */
8
+ export declare function captureWrapperIdentity(cli: string, env: NodeJS.ProcessEnv): WrapperIdentity;
9
+ export declare function sameWrapperIdentity(cli: string, env: NodeJS.ProcessEnv, expected: WrapperIdentity): boolean;
10
+ //# sourceMappingURL=wrapper-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper-runtime.d.ts","sourceRoot":"","sources":["../src/wrapper-runtime.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAO/E;AAED,yFAAyF;AACzF,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,eAAe,CAgBjB;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAQT"}
@@ -0,0 +1,83 @@
1
+ import { accessSync, constants, realpathSync, statSync } from 'node:fs';
2
+ import { delimiter, isAbsolute, join, resolve } from 'node:path';
3
+ const WRAPPER_ENV_ALLOWLIST = [
4
+ 'PATH',
5
+ 'HOME',
6
+ 'TMPDIR',
7
+ 'TMP',
8
+ 'TEMP',
9
+ 'SHELL',
10
+ 'LANG',
11
+ 'LC_ALL',
12
+ 'LC_CTYPE',
13
+ 'TZ',
14
+ 'USER',
15
+ 'LOGNAME',
16
+ 'SystemRoot',
17
+ 'ComSpec',
18
+ 'PATHEXT',
19
+ 'WINDIR',
20
+ ];
21
+ /** Build a wrapper environment from a closed list; ambient credentials never cross. */
22
+ export function wrapperEnvironment(source) {
23
+ const env = {};
24
+ for (const name of WRAPPER_ENV_ALLOWLIST) {
25
+ const value = source[name];
26
+ if (value !== undefined)
27
+ env[name] = value;
28
+ }
29
+ return env;
30
+ }
31
+ /** Resolve and fingerprint the exact executable that will enter the private protocol. */
32
+ export function captureWrapperIdentity(cli, env) {
33
+ const executable = realpathSync(resolveWrapperExecutable(cli, env));
34
+ accessSync(executable, constants.X_OK);
35
+ const stat = statSync(executable, { bigint: true });
36
+ if (!stat.isFile())
37
+ throw new Error('resolved wrapper is not a regular file');
38
+ return {
39
+ executable,
40
+ fingerprint: [
41
+ stat.dev,
42
+ stat.ino,
43
+ stat.mode,
44
+ stat.size,
45
+ stat.mtimeNs,
46
+ stat.ctimeNs,
47
+ ].join(':'),
48
+ };
49
+ }
50
+ export function sameWrapperIdentity(cli, env, expected) {
51
+ try {
52
+ const current = captureWrapperIdentity(cli, env);
53
+ return current.executable === expected.executable
54
+ && current.fingerprint === expected.fingerprint;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ function resolveWrapperExecutable(cli, env) {
61
+ if (isAbsolute(cli) || cli.includes('/') || cli.includes('\\'))
62
+ return resolve(cli);
63
+ const path = env.PATH;
64
+ if (path === undefined)
65
+ throw new Error('PATH is unavailable while resolving the wrapper');
66
+ const extensions = process.platform === 'win32'
67
+ ? (env.PATHEXT ?? '.EXE;.CMD;.BAT;.COM').split(';')
68
+ : [''];
69
+ for (const directory of path.split(delimiter)) {
70
+ for (const extension of extensions) {
71
+ const candidate = join(directory || '.', `${cli}${extension}`);
72
+ try {
73
+ accessSync(candidate, constants.X_OK);
74
+ return candidate;
75
+ }
76
+ catch {
77
+ // Continue through the deterministic PATH candidate list.
78
+ }
79
+ }
80
+ }
81
+ throw new Error(`wrapper executable ${JSON.stringify(cli)} was not found on PATH`);
82
+ }
83
+ //# sourceMappingURL=wrapper-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper-runtime.js","sourceRoot":"","sources":["../src/wrapper-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface WrapperSessionLimits {
2
+ handshakeTimeoutMs: number;
3
+ executionTimeoutMs: number;
4
+ maxOutputBytes: number;
5
+ }
6
+ export interface WrapperSessionResult {
7
+ exit_code: number | null;
8
+ stdout_tail: string;
9
+ stderr_tail: string;
10
+ }
11
+ /**
12
+ * Identify and execute a custom wrapper in one pinned process. No private
13
+ * request is written until its declared path still names the captured file.
14
+ */
15
+ export declare function runWrapperSession(cli: string, instruction: string, wakeContext: unknown, model: string | undefined, env: NodeJS.ProcessEnv, overrides?: Partial<WrapperSessionLimits>): Promise<WrapperSessionResult>;
16
+ //# sourceMappingURL=wrapper-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper-session.d.ts","sourceRoot":"","sources":["../src/wrapper-session.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAiBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,OAAO,EACpB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC5C,OAAO,CAAC,oBAAoB,CAAC,CAyB/B"}