@atolis-hq/wake 0.3.3 → 0.3.5

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.
@@ -24,8 +24,9 @@ execution:
24
24
  fake: { kind: fake }
25
25
  claude-haiku: { kind: claude-cli, command: claude, model: haiku, timeoutMs: 1800000 }
26
26
  claude-opus: { kind: claude-cli, command: claude, model: claude-opus-4-8, timeoutMs: 1800000 }
27
- codex-mini: { kind: codex-cli, command: codex, model: gpt-5.4-mini, timeoutMs: 1800000 }
28
- codex-flagship: { kind: codex-cli, command: codex, model: gpt-5.5, timeoutMs: 1800000 }
27
+ codex-luna: { kind: codex-cli, command: codex, model: gpt-5.6-luna, timeoutMs: 1800000 }
28
+ codex-terra: { kind: codex-cli, command: codex, model: gpt-5.6-terra, timeoutMs: 1800000 }
29
+ codex-sol: { kind: codex-cli, command: codex, model: gpt-5.6-sol, timeoutMs: 1800000 }
29
30
  cursor-composer: { kind: cursor-cli, command: cursor, model: composer-2.5, timeoutMs: 1800000 }
30
31
  runnerPools:
31
32
  light: [fake]
@@ -210,7 +211,7 @@ Ask the user which agent CLI(s) they have authenticated on this host:
210
211
  Claude, Codex, and/or Cursor.
211
212
 
212
213
  \`config.yaml\` already has example \`execution.agentRunners\` entries for
213
- \`claude-haiku\`, \`claude-opus\`, \`codex-mini\`, \`codex-flagship\`, and
214
+ \`claude-haiku\`, \`claude-opus\`, \`codex-luna\`, \`codex-terra\`, \`codex-sol\`, and
214
215
  \`cursor-composer\`, but every runnerPool (\`light\`/\`standard\`/\`deep\`, with
215
216
  \`defaultRunnerPool: standard\`) still points only at the placeholder
216
217
  \`fake\` runner — none of them route to a real runner yet. Don't rewrite
@@ -620,7 +620,7 @@ function createSandboxEntrypointDependencies(root) {
620
620
  resolve();
621
621
  });
622
622
  });
623
- const drained = drainProcessOutput(child, sink, (error) => {
623
+ const drained = drainProcessOutput(child, sink, (value) => process.stderr.write(value), (error) => {
624
624
  process.stderr.write(`Wake detached start log failure: ${error instanceof Error ? error.message : String(error)}\n`);
625
625
  });
626
626
  const completion = closed.then(() => drained).then(() => closeStatus);
@@ -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 = "g5c03d4d";
111
+ export const wakeVersion = "ga20cb24";
@@ -20,6 +20,7 @@ export function createGitHubWakeLabelReconciler(input) {
20
20
  }
21
21
  return open;
22
22
  };
23
+ const onError = input.onError ?? defaultOnError;
23
24
  return {
24
25
  async runOnce() {
25
26
  const workflows = await input.orchestration.listAll();
@@ -49,15 +50,27 @@ export function createGitHubWakeLabelReconciler(input) {
49
50
  const locator = parseGitHubIssueKey(resource.externalKey.key);
50
51
  if (locator === null)
51
52
  continue;
52
- const current = await input.getLabels(locator.owner, locator.repo, locator.number);
53
- const next = reconcileGitHubWakeLabels(current, desired);
54
- if (!sameLabels(current, next))
55
- await input.setLabels(locator.owner, locator.repo, locator.number, next);
53
+ // One issue's persistent failure (rate limit, permissions, a stale
54
+ // resource) must not stop every other open work item from being
55
+ // reconciled this pass — each correlation is an independent GitHub
56
+ // call with no ordering dependency on the others.
57
+ try {
58
+ const current = await input.getLabels(locator.owner, locator.repo, locator.number);
59
+ const next = reconcileGitHubWakeLabels(current, desired);
60
+ if (!sameLabels(current, next))
61
+ await input.setLabels(locator.owner, locator.repo, locator.number, next);
62
+ }
63
+ catch (error) {
64
+ onError({ workItemId: workflow.workItemId, ...locator }, error);
65
+ }
56
66
  }
57
67
  }
58
68
  },
59
69
  };
60
70
  }
71
+ function defaultOnError(failure, error) {
72
+ process.stderr.write(`GitHub label reconcile failed for ${failure.owner}/${failure.repo}#${failure.number}: ${error instanceof Error ? error.message : String(error)}\n`);
73
+ }
61
74
  function desiredWakeLabels(workflow, watching) {
62
75
  return [
63
76
  `wake:status.${statusLabel(workflow.status)}`,
@@ -41,8 +41,14 @@ export function createProcessLogSink(path, output, options = {}) {
41
41
  * Serializes detached child output into a sink and resolves only after Node's
42
42
  * `close` event confirms its stdio streams have closed. Sink failures are
43
43
  * reported rather than becoming detached, unhandled promise rejections.
44
+ *
45
+ * The child's full stdout+stderr always reaches the sink (durable file), but
46
+ * only stderr is also handed to `onStderr` — the child already writes its
47
+ * actionable failures there (GitHub request failures, tick failures) and
48
+ * routine detail to stdout, so this lets a detached supervisor surface just
49
+ * the actionable half on its own stderr without re-deriving severity here.
44
50
  */
45
- export function drainProcessOutput(process, sink, reportError) {
51
+ export function drainProcessOutput(process, sink, onStderr, reportError) {
46
52
  let writes = Promise.resolve();
47
53
  const report = (error) => {
48
54
  try {
@@ -52,12 +58,18 @@ export function drainProcessOutput(process, sink, reportError) {
52
58
  // A reporting failure must not make a detached child unhandled.
53
59
  }
54
60
  };
55
- const enqueue = (chunk) => {
61
+ const enqueue = (chunk, escalate) => {
56
62
  const value = chunk.toString();
57
- writes = writes.then(() => sink.write(value)).catch(report);
63
+ writes = writes
64
+ .then(() => sink.write(value))
65
+ .then(() => {
66
+ if (escalate)
67
+ onStderr(scrubProcessLog(value));
68
+ })
69
+ .catch(report);
58
70
  };
59
- process.stdout?.on('data', enqueue);
60
- process.stderr?.on('data', enqueue);
71
+ process.stdout?.on('data', (chunk) => enqueue(chunk, false));
72
+ process.stderr?.on('data', (chunk) => enqueue(chunk, true));
61
73
  process.on('error', report);
62
74
  return new Promise((resolve) => {
63
75
  process.once('close', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atolis-hq/wake",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Local autonomous agent control plane for software development",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {