@jentrix/runner 0.5.21 → 0.5.23

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.
@@ -0,0 +1,7 @@
1
+ // lib/version.ts
2
+ var RUNNER_VERSION = "0.5.23";
3
+
4
+ export {
5
+ RUNNER_VERSION
6
+ };
7
+ //# sourceMappingURL=chunk-7Q7SYUSG.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../lib/version.ts"],
4
- "sourcesContent": ["export const RUNNER_VERSION = \"0.5.21\";\n"],
4
+ "sourcesContent": ["export const RUNNER_VERSION = \"0.5.23\";\n"],
5
5
  "mappings": ";AAAO,IAAM,iBAAiB;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  RUNNER_VERSION
4
- } from "./chunk-UN63BYMS.js";
4
+ } from "./chunk-7Q7SYUSG.js";
5
5
 
6
6
  // runner-cli.ts
7
7
  import { fileURLToPath } from "node:url";
@@ -219,7 +219,7 @@ async function main(args = process.argv.slice(2)) {
219
219
  return runConfiguredRunner(args.includes("--once"));
220
220
  }
221
221
  if (command === "session-run" && (args.includes("--plan-stdin") || args.includes("--plan-file"))) {
222
- const { runSessionHost } = await import("./session-host-L6XF4T2P.js");
222
+ const { runSessionHost } = await import("./session-host-SGFO345X.js");
223
223
  let raw;
224
224
  const planFile = valueAfter(args, "--plan-file");
225
225
  if (planFile) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RUNNER_VERSION
3
- } from "./chunk-UN63BYMS.js";
3
+ } from "./chunk-7Q7SYUSG.js";
4
4
  import {
5
5
  appendHookEvent,
6
6
  readHookLines,
@@ -953,6 +953,8 @@ var SessionBridge = class {
953
953
  endHead: opts.end.head,
954
954
  endDirty: opts.end.dirty,
955
955
  captureError,
956
+ ...opts.acknowledgeEvidenceGaps ? { acknowledgeEvidenceGaps: true } : {},
957
+ ...typeof opts.commitCount === "number" ? { commitCount: opts.commitCount } : {},
956
958
  ...manifest ? { manifest } : {},
957
959
  usage: {
958
960
  inputTokens: rollup.inputTokens,
@@ -1737,6 +1739,22 @@ function sessionCallTool(mcpUrl, bearerSource, sessionId) {
1737
1739
  }
1738
1740
  };
1739
1741
  }
1742
+ function evidenceFloorRefusalOf(error) {
1743
+ const raw = error instanceof Error ? error.message : String(error ?? "");
1744
+ if (!raw.includes("EVIDENCE_FLOOR")) return null;
1745
+ const start = raw.indexOf("{");
1746
+ if (start >= 0) {
1747
+ try {
1748
+ const envelope = JSON.parse(raw.slice(start));
1749
+ const message = envelope.error?.message;
1750
+ if (typeof message === "string" && message.includes("EVIDENCE_FLOOR")) {
1751
+ return message;
1752
+ }
1753
+ } catch {
1754
+ }
1755
+ }
1756
+ return raw;
1757
+ }
1740
1758
  function claudeHookSettings(runnerBin, sessionDir) {
1741
1759
  const hook = (event) => [
1742
1760
  {
@@ -1901,6 +1919,8 @@ async function runClaudeSessionHost(plan, deps = {}) {
1901
1919
  }
1902
1920
  let bound = watch;
1903
1921
  let sessionEnded = false;
1922
+ let endAcknowledgeGaps = false;
1923
+ let endCommitCount = null;
1904
1924
  let lastPeriodicFlushAt = 0;
1905
1925
  let lastPromptAttemptAt = 0;
1906
1926
  const promptRedactor = createSessionRedactor({ homedir: homedir() });
@@ -1978,6 +1998,14 @@ async function runClaudeSessionHost(plan, deps = {}) {
1978
1998
  const poll = async () => {
1979
1999
  const endRequestPath = join3(sessionDir, "end-request.json");
1980
2000
  if (!sessionEnded && existsSync(endRequestPath)) {
2001
+ try {
2002
+ const request = JSON.parse(readFileSync3(endRequestPath, "utf8"));
2003
+ endAcknowledgeGaps = request.acknowledgeEvidenceGaps === true;
2004
+ endCommitCount = typeof request.commitCount === "number" ? request.commitCount : null;
2005
+ } catch {
2006
+ endAcknowledgeGaps = false;
2007
+ endCommitCount = null;
2008
+ }
1981
2009
  try {
1982
2010
  unlinkSync3(endRequestPath);
1983
2011
  } catch {
@@ -2144,49 +2172,77 @@ async function runClaudeSessionHost(plan, deps = {}) {
2144
2172
  }
2145
2173
  await bridge.maybeHeartbeat();
2146
2174
  };
2147
- const timer = setInterval(() => {
2175
+ let timer = setInterval(() => {
2148
2176
  void poll();
2149
2177
  }, 2e3);
2150
- const exitCode = await (watch ? (
2151
- // Watch mode: live capture beside the operator's own provider process.
2152
- // End signals: the SessionEnd lifecycle hook, an end request from
2153
- // `jentrix session end`, or a heartbeat 409 (session terminal
2154
- // server-side the out-of-band case the hooks can never deliver).
2155
- new Promise((resolve) => {
2156
- const check = setInterval(() => {
2157
- if (sessionEnded || bridge.sessionInactive) {
2158
- clearInterval(check);
2159
- resolve(0);
2160
- }
2161
- }, 1e3);
2162
- })
2163
- ) : new Promise((resolve) => {
2164
- child.once("error", () => resolve(1));
2165
- child.once(
2166
- "exit",
2167
- (code, signal) => resolve(code ?? (signal ? 130 : 0))
2168
- );
2169
- }));
2170
- clearInterval(timer);
2171
- await poll().catch(() => void 0);
2172
- await bridge.flushParts().catch(() => void 0);
2173
- for (const id of timing.unclosedToolIds()) {
2174
- bridge.recordUnclosedInterval("tool", id);
2175
- }
2176
- for (const id of codexRolloutTurnStarts.keys()) {
2177
- bridge.recordUnclosedInterval("turn", id);
2178
- }
2179
- const end = await endRepoState(plan.repoRoot);
2180
- const result = await bridge.complete({
2181
- outcome: exitCode === 0 ? "COMPLETED" : "INTERRUPTED",
2182
- end
2183
- }).catch((error) => {
2178
+ let exitCode = 0;
2179
+ let result = null;
2180
+ for (; ; ) {
2181
+ exitCode = await (watch ? (
2182
+ // Watch mode: live capture beside the operator's own provider process.
2183
+ // End signals: the SessionEnd lifecycle hook, an end request from
2184
+ // `jentrix session end`, or a heartbeat 409 (session terminal
2185
+ // server-side the out-of-band case the hooks can never deliver).
2186
+ new Promise((resolve) => {
2187
+ const check = setInterval(() => {
2188
+ if (sessionEnded || bridge.sessionInactive) {
2189
+ clearInterval(check);
2190
+ resolve(0);
2191
+ }
2192
+ }, 1e3);
2193
+ })
2194
+ ) : new Promise((resolve) => {
2195
+ child.once("error", () => resolve(1));
2196
+ child.once(
2197
+ "exit",
2198
+ (code, signal) => resolve(code ?? (signal ? 130 : 0))
2199
+ );
2200
+ }));
2201
+ clearInterval(timer);
2202
+ await poll().catch(() => void 0);
2203
+ await bridge.flushParts().catch(() => void 0);
2204
+ for (const id of timing.unclosedToolIds()) {
2205
+ bridge.recordUnclosedInterval("tool", id);
2206
+ }
2207
+ for (const id of codexRolloutTurnStarts.keys()) {
2208
+ bridge.recordUnclosedInterval("turn", id);
2209
+ }
2210
+ const end = await endRepoState(plan.repoRoot);
2211
+ let failure = null;
2212
+ result = await bridge.complete({
2213
+ outcome: exitCode === 0 ? "COMPLETED" : "INTERRUPTED",
2214
+ end,
2215
+ acknowledgeEvidenceGaps: endAcknowledgeGaps,
2216
+ commitCount: endCommitCount
2217
+ }).catch((error) => {
2218
+ failure = error;
2219
+ return null;
2220
+ });
2221
+ if (result) break;
2222
+ const refusal = watch ? evidenceFloorRefusalOf(failure) : null;
2223
+ if (refusal) {
2224
+ writeFileSync4(
2225
+ join3(sessionDir, "end-refusal.json"),
2226
+ JSON.stringify({
2227
+ refusedAt: (/* @__PURE__ */ new Date()).toISOString(),
2228
+ message: refusal
2229
+ }),
2230
+ { mode: 384 }
2231
+ );
2232
+ log(
2233
+ `capture: the close was refused by the evidence floor \u2014 this host (pid ${process.pid}) stays up; push the named evidence and re-run \`jentrix session end ${plan.sessionId}\``
2234
+ );
2235
+ sessionEnded = false;
2236
+ endAcknowledgeGaps = false;
2237
+ endCommitCount = null;
2238
+ timer = setInterval(() => {
2239
+ void poll();
2240
+ }, 2e3);
2241
+ continue;
2242
+ }
2184
2243
  log(
2185
- `capture: completion failed (${error instanceof Error ? error.message : "unknown"}) \u2014 spool retained for retry`
2244
+ `capture: completion failed (${failure instanceof Error ? failure.message : "unknown"}) \u2014 spool retained for retry`
2186
2245
  );
2187
- return null;
2188
- });
2189
- if (!result) {
2190
2246
  markHostExited(sessionDir, 1);
2191
2247
  return 1;
2192
2248
  }
@@ -2350,6 +2406,7 @@ export {
2350
2406
  appendHookEvent,
2351
2407
  claudeHookSettings,
2352
2408
  defaultSpoolRoot,
2409
+ evidenceFloorRefusalOf,
2353
2410
  readHookLines,
2354
2411
  readTranscriptTail,
2355
2412
  runClaudeSessionHost,
@@ -2358,4 +2415,4 @@ export {
2358
2415
  safeParse,
2359
2416
  sessionCallTool
2360
2417
  };
2361
- //# sourceMappingURL=session-host-L6XF4T2P.js.map
2418
+ //# sourceMappingURL=session-host-SGFO345X.js.map