@atolis-hq/wake 0.3.62 → 0.3.63

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.
@@ -108,4 +108,4 @@ export function resolveWakeVersion(options = {}) {
108
108
  return `g${headHash.slice(0, 7)}`;
109
109
  return '0.1.0-dev';
110
110
  }
111
- export const wakeVersion = "g8095980";
111
+ export const wakeVersion = "gb19302c";
@@ -1,34 +1,82 @@
1
- import { execa } from 'execa';
2
- // Agent CLIs can emit arbitrarily large machine-readable transcripts. Wake
3
- // retains their complete result only after the process exits, so cap capture
4
- // below the resident's heap limit and surface the existing output-limit failure.
1
+ import { spawn } from 'node:child_process';
2
+ // Agent CLIs can emit arbitrarily large machine-readable transcripts. Capture
3
+ // raw bytes ourselves so overflow never enters a third-party string buffer.
5
4
  const maximumCapturedProcessOutputBytes = 1024 * 1024;
6
5
  export function runProcess(command, args, cwd, signal, timeoutMs) {
7
- const child = execa(command, args, {
6
+ const child = spawn(command, args, {
8
7
  ...(cwd === undefined ? {} : { cwd }),
9
8
  shell: false,
10
- stdin: 'ignore',
11
- stdout: 'pipe',
12
- stderr: 'pipe',
13
- maxBuffer: maximumCapturedProcessOutputBytes,
14
- cancelSignal: signal,
15
- ...(timeoutMs === undefined ? {} : { timeout: timeoutMs }),
16
- reject: false,
17
- stripFinalNewline: false,
9
+ stdio: ['ignore', 'pipe', 'pipe'],
18
10
  });
11
+ const result = captureProcessOutput(child, signal, timeoutMs);
19
12
  return {
20
- result: child.then((result) => ({
21
- stdout: result.stdout,
22
- stderr: result.stderr,
23
- exitCode: result.exitCode,
24
- timedOut: result.timedOut,
25
- ...(result.isMaxBuffer
26
- ? {
27
- failureKind: 'output-limit',
28
- ...(result.shortMessage === undefined ? {} : { failureMessage: result.shortMessage }),
29
- }
30
- : {}),
31
- })),
32
- cancel: async () => void child.kill(),
13
+ result,
14
+ cancel: async () => {
15
+ terminate(child);
16
+ },
33
17
  };
34
18
  }
19
+ function captureProcessOutput(child, signal, timeoutMs) {
20
+ return new Promise((resolve) => {
21
+ const stdout = [];
22
+ const stderr = [];
23
+ let capturedBytes = 0;
24
+ let timedOut = false;
25
+ let overflowed = false;
26
+ let error;
27
+ const terminateForOverflow = () => {
28
+ overflowed = true;
29
+ child.stdout?.destroy();
30
+ child.stderr?.destroy();
31
+ terminate(child);
32
+ };
33
+ const capture = (destination) => (chunk) => {
34
+ if (overflowed)
35
+ return;
36
+ const remaining = maximumCapturedProcessOutputBytes - capturedBytes;
37
+ if (remaining <= 0 || chunk.length > remaining) {
38
+ if (remaining > 0)
39
+ destination.push(chunk.subarray(0, remaining));
40
+ capturedBytes = maximumCapturedProcessOutputBytes;
41
+ terminateForOverflow();
42
+ return;
43
+ }
44
+ destination.push(chunk);
45
+ capturedBytes += chunk.length;
46
+ };
47
+ child.stdout?.on('data', capture(stdout));
48
+ child.stderr?.on('data', capture(stderr));
49
+ const timeout = timeoutMs === undefined
50
+ ? undefined
51
+ : setTimeout(() => {
52
+ timedOut = true;
53
+ terminate(child);
54
+ }, timeoutMs);
55
+ const onAbort = () => terminate(child);
56
+ signal.addEventListener('abort', onAbort, { once: true });
57
+ child.once('error', (caught) => {
58
+ error = caught;
59
+ });
60
+ child.once('close', (exitCode) => {
61
+ if (timeout !== undefined)
62
+ clearTimeout(timeout);
63
+ signal.removeEventListener('abort', onAbort);
64
+ resolve({
65
+ stdout: Buffer.concat(stdout).toString('utf8'),
66
+ stderr: error?.message ?? Buffer.concat(stderr).toString('utf8'),
67
+ exitCode: exitCode ?? undefined,
68
+ timedOut,
69
+ ...(overflowed
70
+ ? {
71
+ failureKind: 'output-limit',
72
+ failureMessage: `Process output exceeded ${maximumCapturedProcessOutputBytes} bytes`,
73
+ }
74
+ : {}),
75
+ });
76
+ });
77
+ });
78
+ }
79
+ function terminate(child) {
80
+ if (!child.killed && child.exitCode === null)
81
+ child.kill();
82
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atolis-hq/wake",
3
- "version": "0.3.62",
3
+ "version": "0.3.63",
4
4
  "description": "Local autonomous agent control plane for software development",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -73,7 +73,6 @@
73
73
  "dependencies": {
74
74
  "@octokit/rest": "^22.0.0",
75
75
  "cron-parser": "^5.10.0",
76
- "execa": "^10.0.1",
77
76
  "handlebars": "^4.7.9",
78
77
  "ulid": "^3.0.2",
79
78
  "yaml": "^2.9.0",