scenri 0.7.2 → 0.7.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.4](https://github.com/tonygorb/Scenri/compare/v0.7.3...v0.7.4) (2026-08-31)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * report why codex failed instead of the banner in front of it ([41b19d9](https://github.com/tonygorb/Scenri/commit/41b19d93a53a759656759b5a5ac4a8093966c117))
9
+ * report why codex failed instead of the banner in front of it ([65518e7](https://github.com/tonygorb/Scenri/commit/65518e765eb1ffff99d35311ebcdc31973c90f93))
10
+
11
+ ## [0.7.3](https://github.com/tonygorb/Scenri/compare/v0.7.2...v0.7.3) (2026-08-30)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * a node is done only after its rendered record exists ([88fbfb7](https://github.com/tonygorb/Scenri/commit/88fbfb7b53001e6f4bda12cc61258dbb21e353a4))
17
+ * a node is done only after its rendered record exists ([2e31d09](https://github.com/tonygorb/Scenri/commit/2e31d098ab78a22138e99aa463cae41199e51b6d))
18
+
3
19
  ## [0.7.2](https://github.com/tonygorb/Scenri/compare/v0.7.1...v0.7.2) (2026-08-30)
4
20
 
5
21
 
package/dist/serve.js CHANGED
@@ -2037,6 +2037,36 @@ function execArgs(dir, effort = "low") {
2037
2037
  "-"
2038
2038
  ];
2039
2039
  }
2040
+ var TAIL_BYTES = 4096;
2041
+ var DETAIL_CHARS = 800;
2042
+ function keepTail(buf, chunk) {
2043
+ const next = buf + chunk;
2044
+ return next.length > TAIL_BYTES ? next.slice(next.length - TAIL_BYTES) : next;
2045
+ }
2046
+ var BANNER_RULE = /^-{3,}\s*$/;
2047
+ var BANNER_LINE = /^(OpenAI Codex v|workdir:|model:|provider:|approval:|sandbox:|reasoning |-{3,}\s*$|\s*$)/;
2048
+ function afterBanner(stderr) {
2049
+ const lines = stderr.split(/\r?\n/);
2050
+ const rules = [];
2051
+ for (const [i2, line] of lines.entries()) if (BANNER_RULE.test(line)) rules.push(i2);
2052
+ if (rules.length >= 2)
2053
+ return lines.slice(rules[1] + 1).join("\n").trim();
2054
+ let i = 0;
2055
+ while (i < lines.length && BANNER_LINE.test(lines[i])) i++;
2056
+ return lines.slice(i).join("\n").trim();
2057
+ }
2058
+ function tailOf(text) {
2059
+ if (text.length <= DETAIL_CHARS) return text;
2060
+ const cut = text.slice(text.length - DETAIL_CHARS);
2061
+ const nl = cut.indexOf("\n");
2062
+ return (nl >= 0 ? cut.slice(nl + 1) : cut).trim();
2063
+ }
2064
+ function codexFailureDetail(stderr, stdout) {
2065
+ const body = afterBanner(stderr);
2066
+ const errorAt = body.lastIndexOf("\nERROR:");
2067
+ const marked = body.startsWith("ERROR:") ? body : errorAt >= 0 ? body.slice(errorAt + 1) : "";
2068
+ return tailOf(marked) || tailOf(body) || tailOf(stdout.trim()) || tailOf(stderr.trim());
2069
+ }
2040
2070
  function killTree(child, platform, spawnImpl) {
2041
2071
  if (platform === "win32" && child.pid) {
2042
2072
  try {
@@ -2098,6 +2128,7 @@ function createRunner(opts = {}) {
2098
2128
  }
2099
2129
  let settled = false;
2100
2130
  let stderr = "";
2131
+ let stdout = "";
2101
2132
  const spawnedAt = Date.now();
2102
2133
  let firstByteAt = 0;
2103
2134
  let lastByteAt = 0;
@@ -2124,9 +2155,12 @@ function createRunner(opts = {}) {
2124
2155
  }
2125
2156
  lastByteAt = now;
2126
2157
  }
2127
- child.stdout?.on("data", sawActivity);
2158
+ child.stdout?.on("data", (d) => {
2159
+ stdout = keepTail(stdout, String(d));
2160
+ sawActivity();
2161
+ });
2128
2162
  child.stderr?.on("data", (d) => {
2129
- stderr += String(d);
2163
+ stderr = keepTail(stderr, String(d));
2130
2164
  sawActivity();
2131
2165
  });
2132
2166
  if (io?.stdin != null) {
@@ -2183,7 +2217,7 @@ function createRunner(opts = {}) {
2183
2217
  );
2184
2218
  return;
2185
2219
  }
2186
- const snippet2 = stderr.trim().slice(0, 200);
2220
+ const snippet2 = codexFailureDetail(stderr, stdout);
2187
2221
  finish(
2188
2222
  `exit-${code ?? "unknown"}`,
2189
2223
  () => reject(new Error(`codex exited with code ${code ?? "unknown"}${snippet2 ? `: ${snippet2}` : ""}`))
@@ -8726,6 +8760,26 @@ function registerImageRoutes(app, deps) {
8726
8760
 
8727
8761
  // src/release/notes.data.ts
8728
8762
  var RELEASES = [
8763
+ {
8764
+ version: "0.7.4",
8765
+ date: "2026-08-31",
8766
+ sections: [
8767
+ {
8768
+ heading: "Fixes",
8769
+ body: "A shot that Codex could not finish now says why it failed. Failures used to quote the banner Codex prints as it starts, which names the working folder and the model but never the reason. A Windows machine that cannot start the Codex tool host is now told which setting to change."
8770
+ }
8771
+ ]
8772
+ },
8773
+ {
8774
+ version: "0.7.3",
8775
+ date: "2026-08-31",
8776
+ sections: [
8777
+ {
8778
+ heading: "Fixes",
8779
+ body: "A finished shot now reports done only after its delivered size is on record, so a tile can no longer guess its shape for a moment while the record catches up."
8780
+ }
8781
+ ]
8782
+ },
8729
8783
  {
8730
8784
  version: "0.7.2",
8731
8785
  date: "2026-08-30",
@@ -10105,7 +10159,6 @@ function buildServer(opts) {
10105
10159
  result.images = await normalizePngs(result.images);
10106
10160
  if (post) result.images = await post(result.images);
10107
10161
  if (expect) await assertAspect(result.images, expect);
10108
- core.store.completeNode(nodeId, { ...result, durationMs: Date.now() - startedAt });
10109
10162
  try {
10110
10163
  const sizes = [];
10111
10164
  for (const h of result.images) {
@@ -10127,6 +10180,7 @@ function buildServer(opts) {
10127
10180
  }
10128
10181
  } catch {
10129
10182
  }
10183
+ core.store.completeNode(nodeId, { ...result, durationMs: Date.now() - startedAt });
10130
10184
  core.ledger.recordCost(engineId, nodeId, result.costUsd);
10131
10185
  } catch (err) {
10132
10186
  if (watchdogFired)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scenri",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "author": "Tony Gorb <hello@scenri.co>",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",