@shardworks/claude-code-apparatus 0.1.274 → 0.1.275

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/README.md CHANGED
@@ -55,18 +55,27 @@ import {
55
55
 
56
56
  ### Rate-Limit Detection
57
57
 
58
- The provider runs a **two-branch NDJSON detector** to identify rate-limited terminations and attach a structured `terminationTag` to the session result. The Animator's back-off state machine consumes the tag and transitions its pause-state doc accordingly.
58
+ The provider runs a **single-branch, evidence-driven NDJSON detector** to identify rate-limited terminations and attach a structured `terminationTag` to the session result. The Animator's back-off state machine consumes the tag and transitions its pause-state doc accordingly.
59
59
 
60
60
  ```typescript
61
61
  import { detectRateLimitFromNdjson } from '@shardworks/claude-code-apparatus';
62
62
  ```
63
63
 
64
- Active detector branches (first-wins):
64
+ The active branch matches the rate-limit pattern against the **top-level `error` field** (peer of `message`) on every NDJSON message — the shape claude actually emits on rate-limited assistant termination:
65
65
 
66
- 1. **Structural `subtype`** — `parseStreamJsonMessage` inspects every NDJSON message whose `subtype` contains `rate_limit` / `rate-limit` and emits a tag with `source: 'ndjson-result'`.
67
- 2. **Structural `is_error`** if `msg.is_error === true` and the carried error text matches the rate-limit phrasing regex, the same tag is produced.
66
+ ```json
67
+ { "type": "assistant", "message": { "...": "..." }, "error": "rate_limit" }
68
+ ```
69
+
70
+ When the regex matches, a tag with `source: 'ndjson-result'` is emitted. The detector is intentionally narrow: branches are added only when a real provider emission is observed, not pre-emptively.
71
+
72
+ **Retired branches** (do not re-introduce without a live observation):
73
+
74
+ - `subtype` — earlier speculative branch that emitted a tag when `msg.subtype` contained `rate_limit` / `rate-limit`. Retired because no live provider emission ever fired it.
75
+ - `is_error` — earlier speculative branch that emitted a tag when `msg.is_error === true` and the carried error text matched the rate-limit pattern. Retired for the same reason.
76
+ - `result`-text and stderr/exit-code cascades — retired earlier for false-positive pauses (an assistant's prose summary of a prior rate-limit / a generic non-zero exit code each tripped a false-positive pause once in production).
68
77
 
69
- Everything else surfaces as plain `failed`. The previous stderr-pattern and exit-code branches were retired after two production incidents where an assistant's prose summary / a generic non-zero exit code tripped a false-positive pause. Generic non-zero exit codes surface as `'failed'`; the babysitter no longer samples claude's stderr for pattern matches, only forwards it to the per-session log file.
78
+ Everything else surfaces as plain `failed`. Generic non-zero exit codes do not produce a rate-limit tag; the babysitter no longer samples claude's stderr for pattern matches, only forwards it to the per-session log file.
70
79
 
71
80
  When a non-zero exit arrives without an NDJSON termination tag, the babysitter captures a `terminationDiagnostic: { exitCode, stderrExcerpt? }` on the session-record payload so operators can review the signal that fell through — without the Animator widening its pause gate on it.
72
81
 
@@ -15,45 +15,31 @@
15
15
  *
16
16
  * The single-purpose primitives (stdin parsing, retrying HTTP, DLQ writes,
17
17
  * the SQLite trio, lifecycle reporters, stderr redirect) live in
18
- * `runtime.ts`. This file owns the orchestrator (`runBabysitter`), the
19
- * MCP/SSE proxy, and the script entry point. The previously-exported
20
- * primitives are re-exported below to preserve the package's public
21
- * surface.
18
+ * `runtime.ts`. The MCP/SSE proxy lives in `mcp-proxy.ts`. This file owns
19
+ * the orchestrator (`runBabysitter`) and the script entry point. The
20
+ * previously-exported primitives are re-exported below to preserve the
21
+ * package's public surface.
22
22
  *
23
23
  * See: docs/architecture/detached-sessions.md
24
24
  */
25
25
  import { spawn } from 'node:child_process';
26
- import { type BabysitterConfig, type SerializedTool, type TranscriptDb } from './runtime.ts';
26
+ import { type BabysitterConfig, type TranscriptDb } from './runtime.ts';
27
27
  export { callGuildHttpApi, findRetryableCode, initTranscriptDb, openTranscriptDb, readConfigFromStdin, redirectStderrToFile, reportResult, reportRunning, resolveTerminalStatus, STDERR_DIAGNOSTIC_TAIL_LIMIT, writeToDlq, writeTranscript, } from './runtime.ts';
28
28
  export type { BabysitterConfig, SerializedTool, TranscriptDb, } from './runtime.ts';
29
- export interface McpProxyHandle {
30
- /** URL for --mcp-config (e.g. "http://127.0.0.1:PORT/sse"). */
31
- url: string;
32
- /** Shut down the HTTP server and MCP transport. */
33
- close(): Promise<void>;
34
- }
35
- /**
36
- * Create an MCP/SSE HTTP server that proxies tool calls to the guild.
37
- *
38
- * For each tool in the config, registers an MCP tool whose handler
39
- * forwards the call to the guild's Tool HTTP API via HTTP POST.
40
- *
41
- * Uses the low-level MCP Server class to register tools with raw
42
- * JSON Schema (the serialized params from the config).
43
- */
44
- export declare function createProxyMcpHttpServer(tools: SerializedTool[], guildToolUrl: string, sessionId: string): Promise<McpProxyHandle>;
29
+ export { createProxyMcpHttpServer, type McpProxyHandle } from './mcp-proxy.ts';
45
30
  /**
46
31
  * Run the session babysitter.
47
32
  *
48
- * This is the main orchestration function. It:
49
- * 1. Opens SQLite for transcript streaming
50
- * 2. Starts the MCP proxy server
51
- * 3. Prepares session files (tmpDir, system prompt, mcp-config)
52
- * 4. Spawns claude
53
- * 5. Reports "running" status
54
- * 6. Streams transcript to SQLite
55
- * 7. Reports result on exit
56
- * 8. Cleans up
33
+ * Three-phase orchestrator threading a {@link BabysitterRuntimeContext}:
34
+ * `runInitPhase` allocates resources, `runSteadyStatePhase` reports
35
+ * lifecycle events and consumes claude's NDJSON stream, `runTerminalPhase`
36
+ * builds and submits the final result. The shared try/catch/finally
37
+ * funnels all error and cleanup handling.
38
+ *
39
+ * The orchestrator-error path goes through `reportResult` via the
40
+ * `StatusOverride` contract (no hand-rolled session-record + DLQ
41
+ * cascade) `reportResult` is the single sink for both the normal
42
+ * `'failed'` path and the orchestrator-caught error path.
57
43
  */
58
44
  export declare function runBabysitter(config: BabysitterConfig, deps?: {
59
45
  /** Injected TranscriptDb for testing (avoids loading better-sqlite3). */
@@ -1 +1 @@
1
- {"version":3,"file":"babysitter.d.ts","sourceRoot":"","sources":["../src/babysitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAwB9D,OAAO,EAUL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,4BAA4B,EAC5B,UAAU,EACV,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC;AAItB,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,cAAc,EAAE,EACvB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAmLzB;AAID;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,gBAAgB,EACxB,IAAI,CAAC,EAAE;IACL,yEAAyE;IACzE,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAAC,IAAI,CAAC,CAqOf"}
1
+ {"version":3,"file":"babysitter.d.ts","sourceRoot":"","sources":["../src/babysitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAgB9D,OAAO,EAUL,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAStB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,4BAA4B,EAC5B,UAAU,EACV,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,wBAAwB,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAgR/E;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,gBAAgB,EACxB,IAAI,CAAC,EAAE;IACL,yEAAyE;IACzE,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAAC,IAAI,CAAC,CA2Ef"}