@telora/daemon-core 0.2.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.
Files changed (81) hide show
  1. package/dist/activity-tracker.d.ts +69 -0
  2. package/dist/activity-tracker.d.ts.map +1 -0
  3. package/dist/activity-tracker.js +155 -0
  4. package/dist/activity-tracker.js.map +1 -0
  5. package/dist/api-client.d.ts +94 -0
  6. package/dist/api-client.d.ts.map +1 -0
  7. package/dist/api-client.js +145 -0
  8. package/dist/api-client.js.map +1 -0
  9. package/dist/config.d.ts +117 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +348 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/engine.d.ts +120 -0
  14. package/dist/engine.d.ts.map +1 -0
  15. package/dist/engine.js +18 -0
  16. package/dist/engine.js.map +1 -0
  17. package/dist/escalation-types.d.ts +31 -0
  18. package/dist/escalation-types.d.ts.map +1 -0
  19. package/dist/escalation-types.js +24 -0
  20. package/dist/escalation-types.js.map +1 -0
  21. package/dist/event-logger.d.ts +13 -0
  22. package/dist/event-logger.d.ts.map +1 -0
  23. package/dist/event-logger.js +82 -0
  24. package/dist/event-logger.js.map +1 -0
  25. package/dist/git.d.ts +39 -0
  26. package/dist/git.d.ts.map +1 -0
  27. package/dist/git.js +72 -0
  28. package/dist/git.js.map +1 -0
  29. package/dist/index.d.ts +20 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +36 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/lifecycle.d.ts +104 -0
  34. package/dist/lifecycle.d.ts.map +1 -0
  35. package/dist/lifecycle.js +192 -0
  36. package/dist/lifecycle.js.map +1 -0
  37. package/dist/log-manager.d.ts +83 -0
  38. package/dist/log-manager.d.ts.map +1 -0
  39. package/dist/log-manager.js +217 -0
  40. package/dist/log-manager.js.map +1 -0
  41. package/dist/otel-env.d.ts +29 -0
  42. package/dist/otel-env.d.ts.map +1 -0
  43. package/dist/otel-env.js +44 -0
  44. package/dist/otel-env.js.map +1 -0
  45. package/dist/resilience.d.ts +127 -0
  46. package/dist/resilience.d.ts.map +1 -0
  47. package/dist/resilience.js +300 -0
  48. package/dist/resilience.js.map +1 -0
  49. package/dist/resource-governor.d.ts +83 -0
  50. package/dist/resource-governor.d.ts.map +1 -0
  51. package/dist/resource-governor.js +184 -0
  52. package/dist/resource-governor.js.map +1 -0
  53. package/dist/spawn.d.ts +72 -0
  54. package/dist/spawn.d.ts.map +1 -0
  55. package/dist/spawn.js +82 -0
  56. package/dist/spawn.js.map +1 -0
  57. package/dist/stream-json.d.ts +885 -0
  58. package/dist/stream-json.d.ts.map +1 -0
  59. package/dist/stream-json.js +298 -0
  60. package/dist/stream-json.js.map +1 -0
  61. package/dist/token-usage.d.ts +67 -0
  62. package/dist/token-usage.d.ts.map +1 -0
  63. package/dist/token-usage.js +150 -0
  64. package/dist/token-usage.js.map +1 -0
  65. package/dist/transforms.d.ts +64 -0
  66. package/dist/transforms.d.ts.map +1 -0
  67. package/dist/transforms.js +78 -0
  68. package/dist/transforms.js.map +1 -0
  69. package/dist/unified-config.d.ts +62 -0
  70. package/dist/unified-config.d.ts.map +1 -0
  71. package/dist/unified-config.js +155 -0
  72. package/dist/unified-config.js.map +1 -0
  73. package/dist/workflow-types.d.ts +202 -0
  74. package/dist/workflow-types.d.ts.map +1 -0
  75. package/dist/workflow-types.js +15 -0
  76. package/dist/workflow-types.js.map +1 -0
  77. package/dist/worktree.d.ts +92 -0
  78. package/dist/worktree.d.ts.map +1 -0
  79. package/dist/worktree.js +221 -0
  80. package/dist/worktree.js.map +1 -0
  81. package/package.json +57 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-json.d.ts","sourceRoot":"","sources":["../src/stream-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2LxB,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAWrB,CAAC;AAGH,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAI7B,kDAAkD;AAClD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,kBAAkB,GAAG,eAAe,GAAG,oBAAoB,CAAC;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,4EAA4E;AAC5E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,+FAA+F;AAC/F,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChD,CAAC;IACF,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,yCAAyC;AACzC,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAA;CAAE,GAClG;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,SAAS,GAAG,YAAY,GAAG,aAAa,CAAA;CAAE,GACvG;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,cAAc,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAAC,KAAK,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAChI;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,MAAM,WAAW,SAAS;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACzD,MAAM,WAAW,YAAY;IAAG,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AAC5G,MAAM,WAAW,aAAa;IAAG,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;AACxF,MAAM,WAAW,SAAS;IAAG,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC/D,MAAM,WAAW,cAAc;IAAG,IAAI,EAAE,kBAAkB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE;AAElF,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,SAAS,CAAC;QAChB,IAAI,EAAE,WAAW,CAAC;QAClB,OAAO,EAAE,KAAK,CAAC,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC,CAAC;QACzD,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,KAAK,EAAE,UAAU,CAAC;KACnB,CAAC;IACF,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,IAAI,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,oFAAoF;AACpF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,aAAa,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;SAAE,CAAC,CAAC;KAChH,CAAC;IACF,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;IACzB,eAAe,EAAE;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtC,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,aAAa,GACb,kBAAkB,GAClB,WAAW,GACX,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,GACpB,aAAa,GACb,WAAW,GACX,cAAc,CAAC;AAInB,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAID,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACpC,MAAM,EAAE,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,KAAK,IAAI,CAAC;IACtD,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,cAAc,CAAoB;IAC1C,OAAO,CAAC,mBAAmB,CAAK;IAEhC,IAAI,SAAS,IAAI,MAAM,GAAG,IAAI,CAA4B;IAC1D,IAAI,aAAa,IAAI,IAAI,CAAgC;IACzD,oEAAoE;IACpE,IAAI,kBAAkB,IAAI,MAAM,CAAqC;IAErE;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAc9B,OAAO,CAAC,aAAa;IAsCrB,OAAO,CAAC,UAAU;CAoCnB;AAID;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAWrE"}
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Stream-JSON protocol module -- shared core for Claude Code interactive sessions.
3
+ *
4
+ * This is the canonical implementation used by both the Telora daemon and factory
5
+ * engines. It handles parsing NDJSON output from `--output-format stream-json`
6
+ * and writing messages for `--input-format stream-json`.
7
+ *
8
+ * Wire format: newline-delimited JSON (one JSON object per line).
9
+ *
10
+ * All inbound events are validated against Zod schemas before routing.
11
+ * Malformed events are logged, counted, and skipped -- never crash the parser.
12
+ */
13
+ import { EventEmitter } from 'node:events';
14
+ import { z } from 'zod';
15
+ // ── Zod Schemas ──────────────────────────────────────────────────────────────
16
+ const TokenUsageSchema = z.object({
17
+ input_tokens: z.number(),
18
+ output_tokens: z.number(),
19
+ cache_creation_input_tokens: z.number().optional(),
20
+ cache_read_input_tokens: z.number().optional(),
21
+ });
22
+ const TextBlockSchema = z.object({ type: z.literal('text'), text: z.string() });
23
+ const ToolUseBlockSchema = z.object({
24
+ type: z.literal('tool_use'),
25
+ id: z.string(),
26
+ name: z.string(),
27
+ input: z.record(z.string(), z.unknown()),
28
+ });
29
+ const ThinkingBlockSchema = z.object({
30
+ type: z.literal('thinking'),
31
+ thinking: z.string(),
32
+ signature: z.string(),
33
+ });
34
+ const TextDeltaSchema = z.object({ type: z.literal('text_delta'), text: z.string() });
35
+ const InputJsonDeltaSchema = z.object({ type: z.literal('input_json_delta'), partial_json: z.string() });
36
+ const ContentBlockSchema = z.discriminatedUnion('type', [TextBlockSchema, ToolUseBlockSchema, ThinkingBlockSchema]);
37
+ // ── System Events ────────────────────────────────────────────────────────────
38
+ const SystemInitEventSchema = z.object({
39
+ type: z.literal('system'),
40
+ subtype: z.literal('init'),
41
+ uuid: z.string(),
42
+ session_id: z.string(),
43
+ cwd: z.string(),
44
+ model: z.string(),
45
+ tools: z.array(z.string()),
46
+ mcp_servers: z.array(z.object({ name: z.string(), status: z.string() })),
47
+ permissionMode: z.string(),
48
+ });
49
+ const TeammateEventSchema = z.object({
50
+ type: z.literal('system'),
51
+ subtype: z.enum(['teammate_spawned', 'teammate_idle', 'teammate_completed']),
52
+ uuid: z.string(),
53
+ session_id: z.string(),
54
+ agent_id: z.string(),
55
+ agent_name: z.string(),
56
+ team_id: z.string(),
57
+ agent_type: z.string().optional(),
58
+ result: z.string().optional(),
59
+ is_error: z.boolean().optional(),
60
+ });
61
+ // ── Generic System Events (compact_boundary, status, etc.) ──────────────────
62
+ //
63
+ // System events beyond init and teammate lifecycle. Uses passthrough to
64
+ // accommodate varying payloads per subtype (compact_metadata, status info, etc.).
65
+ const GenericSystemEventSchema = z.object({
66
+ type: z.literal('system'),
67
+ subtype: z.string(),
68
+ uuid: z.string(),
69
+ session_id: z.string(),
70
+ }).passthrough();
71
+ // ── User Text Messages (compaction summaries, etc.) ─────────────────────────
72
+ //
73
+ // User messages with text content (not tool_result). These appear during
74
+ // context compaction and other system-generated user messages.
75
+ const UserTextContentSchema = z.object({
76
+ type: z.literal('text'),
77
+ text: z.string(),
78
+ });
79
+ const UserTextMessageSchema = z.object({
80
+ type: z.literal('user'),
81
+ uuid: z.string(),
82
+ session_id: z.string(),
83
+ message: z.object({
84
+ role: z.literal('user'),
85
+ content: z.array(UserTextContentSchema),
86
+ }),
87
+ parent_tool_use_id: z.string().nullable().optional(),
88
+ });
89
+ // ── Stream Events (loosely validated) ────────────────────────────────────────
90
+ // Raw stream events from the Claude API are high-volume and may add fields
91
+ // across versions. We validate the outer envelope strictly but use passthrough
92
+ // on the inner event to avoid breaking on new API fields.
93
+ const RawStreamEventSchema = z.object({ type: z.string() }).passthrough();
94
+ const StreamEventSchema = z.object({
95
+ type: z.literal('stream_event'),
96
+ event: RawStreamEventSchema,
97
+ parent_tool_use_id: z.string().nullable(),
98
+ uuid: z.string(),
99
+ session_id: z.string(),
100
+ });
101
+ // ── Assistant Message ────────────────────────────────────────────────────────
102
+ const AssistantMessageSchema = z.object({
103
+ type: z.literal('assistant'),
104
+ uuid: z.string(),
105
+ session_id: z.string(),
106
+ message: z.object({
107
+ id: z.string(),
108
+ type: z.literal('message'),
109
+ role: z.literal('assistant'),
110
+ content: z.array(ContentBlockSchema),
111
+ model: z.string(),
112
+ stop_reason: z.string().nullable(),
113
+ usage: TokenUsageSchema,
114
+ }),
115
+ parent_tool_use_id: z.string().nullable(),
116
+ });
117
+ // ── Result Events ────────────────────────────────────────────────────────────
118
+ // Result schema accepts both success and error results. Claude Code emits
119
+ // API errors (500s, rate limits) as subtype:"success" + is_error:true, which
120
+ // doesn't fit a strict success/error split. Use a single permissive schema
121
+ // and let downstream code branch on is_error.
122
+ const ResultSchema = z.object({
123
+ type: z.literal('result'),
124
+ subtype: z.string(),
125
+ is_error: z.boolean(),
126
+ duration_ms: z.number(),
127
+ duration_api_ms: z.number(),
128
+ num_turns: z.number(),
129
+ total_cost_usd: z.number().optional(),
130
+ usage: TokenUsageSchema.optional(),
131
+ result: z.string().optional(),
132
+ errors: z.array(z.string()).optional(),
133
+ }).passthrough();
134
+ // Keep named aliases for backward compatibility in the union
135
+ const ResultSuccessSchema = ResultSchema;
136
+ const ResultErrorSchema = ResultSchema;
137
+ // ── User Messages (tool_result) ─────────────────────────────────────────────
138
+ const ToolResultContentSchema = z.object({
139
+ type: z.literal('tool_result'),
140
+ tool_use_id: z.string(),
141
+ content: z.union([z.string(), z.array(z.record(z.string(), z.unknown()))]),
142
+ });
143
+ const UserToolResultSchema = z.object({
144
+ type: z.literal('user'),
145
+ uuid: z.string(),
146
+ session_id: z.string(),
147
+ message: z.object({
148
+ role: z.literal('user'),
149
+ content: z.array(ToolResultContentSchema),
150
+ }),
151
+ parent_tool_use_id: z.string().nullable().optional(),
152
+ });
153
+ // ── Rate Limit Events ─────────────────────────────────────────────────────────
154
+ const RateLimitInfoSchema = z.object({
155
+ status: z.string(),
156
+ resetsAt: z.union([z.string(), z.number()]).optional(),
157
+ rateLimitType: z.string().optional(),
158
+ overageStatus: z.string().optional(),
159
+ overageDisabledReason: z.string().nullable().optional(),
160
+ isUsingOverage: z.boolean().optional(),
161
+ }).passthrough();
162
+ const RateLimitEventSchema = z.object({
163
+ type: z.literal('rate_limit_event'),
164
+ rate_limit_info: RateLimitInfoSchema,
165
+ uuid: z.string(),
166
+ session_id: z.string(),
167
+ });
168
+ // ── Top-level discriminated union ────────────────────────────────────────────
169
+ //
170
+ // We cannot use z.discriminatedUnion across both 'type' and 'subtype' in a
171
+ // single call, so we use z.union with the most specific schemas first.
172
+ // System events split on subtype, result events split on subtype.
173
+ const OutputEventSchema = z.union([
174
+ SystemInitEventSchema,
175
+ TeammateEventSchema,
176
+ GenericSystemEventSchema,
177
+ StreamEventSchema,
178
+ AssistantMessageSchema,
179
+ UserToolResultSchema,
180
+ UserTextMessageSchema,
181
+ ResultSuccessSchema,
182
+ ResultErrorSchema,
183
+ RateLimitEventSchema,
184
+ ]);
185
+ // Export the schema for testing
186
+ export { OutputEventSchema };
187
+ /**
188
+ * Line-buffered NDJSON parser for Claude Code stream-json output.
189
+ *
190
+ * Reads from a Readable stream, validates each line against Zod schemas,
191
+ * and emits typed events. Malformed events are logged, counted, and skipped.
192
+ */
193
+ export class StreamJsonParser extends EventEmitter {
194
+ buffer = '';
195
+ _sessionId = null;
196
+ _lastEventTime = new Date();
197
+ _unparsedEventCount = 0;
198
+ get sessionId() { return this._sessionId; }
199
+ get lastEventTime() { return this._lastEventTime; }
200
+ /** Number of events that failed Zod validation and were skipped. */
201
+ get unparsedEventCount() { return this._unparsedEventCount; }
202
+ /**
203
+ * Attach the parser to a readable stream (typically process.stdout).
204
+ */
205
+ attach(stream) {
206
+ stream.on('data', (chunk) => {
207
+ this.buffer += chunk.toString();
208
+ this.processBuffer();
209
+ });
210
+ stream.on('end', () => {
211
+ // Process any remaining data in the buffer
212
+ if (this.buffer.trim()) {
213
+ this.processBuffer();
214
+ }
215
+ });
216
+ }
217
+ processBuffer() {
218
+ const lines = this.buffer.split('\n');
219
+ // Keep last incomplete line in buffer
220
+ this.buffer = lines.pop() ?? '';
221
+ for (const line of lines) {
222
+ const trimmed = line.trim();
223
+ if (!trimmed)
224
+ continue;
225
+ // Step 1: Parse raw JSON
226
+ let raw;
227
+ try {
228
+ raw = JSON.parse(trimmed);
229
+ }
230
+ catch (err) {
231
+ this.emit('error', err instanceof Error ? err : new Error(String(err)), trimmed);
232
+ continue;
233
+ }
234
+ // Step 2: Validate against Zod schema
235
+ const result = OutputEventSchema.safeParse(raw);
236
+ if (!result.success) {
237
+ this._unparsedEventCount++;
238
+ // Format Zod issues into a concise message
239
+ const issues = result.error.issues
240
+ .map(i => `${i.path.join('.')}: ${i.message}`)
241
+ .join('; ');
242
+ console.warn(`[stream-json] Validation failed (${this._unparsedEventCount} total): ${issues} ` +
243
+ `-- raw: ${trimmed.slice(0, 300)}`);
244
+ continue;
245
+ }
246
+ this._lastEventTime = new Date();
247
+ this.routeEvent(result.data);
248
+ }
249
+ }
250
+ routeEvent(event) {
251
+ // Emit the generic event for all listeners
252
+ this.emit('event', event);
253
+ // Extract session ID from first event that has one
254
+ if ('session_id' in event && event.session_id && !this._sessionId) {
255
+ this._sessionId = event.session_id;
256
+ }
257
+ switch (event.type) {
258
+ case 'system':
259
+ if (event.subtype === 'init') {
260
+ this.emit('init', event);
261
+ }
262
+ else if (event.subtype === 'teammate_spawned' ||
263
+ event.subtype === 'teammate_idle' ||
264
+ event.subtype === 'teammate_completed') {
265
+ this.emit('teammate', event);
266
+ }
267
+ // Other system subtypes (compact_boundary, status, etc.) are emitted
268
+ // via the generic 'event' handler above -- no dedicated named event.
269
+ break;
270
+ case 'assistant':
271
+ this.emit('assistant', event);
272
+ break;
273
+ case 'result':
274
+ this.emit('result', event);
275
+ break;
276
+ // stream_event is emitted via the generic 'event' handler above
277
+ // but individual stream deltas are too granular for named events
278
+ }
279
+ }
280
+ }
281
+ // ── Writer ───────────────────────────────────────────────────────────────────
282
+ /**
283
+ * Send a user message to Claude Code via stdin (stream-json format).
284
+ *
285
+ * Each message is serialized as a single JSON line followed by a newline.
286
+ */
287
+ export function sendMessage(stdin, content) {
288
+ const message = {
289
+ type: 'user',
290
+ message: {
291
+ role: 'user',
292
+ content,
293
+ },
294
+ };
295
+ const line = JSON.stringify(message) + '\n';
296
+ return stdin.write(line);
297
+ }
298
+ //# sourceMappingURL=stream-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-json.js","sourceRoot":"","sources":["../src/stream-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gFAAgF;AAEhF,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,2BAA2B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClD,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/C,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAChF,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAC3B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;CACzC,CAAC,CAAC;AACH,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAC3B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AACH,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACtF,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAEzG,MAAM,kBAAkB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAEpH,gFAAgF;AAEhF,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACzB,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;CAC3B,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACzB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,CAAC,CAAC;IAC5E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,EAAE;AACF,wEAAwE;AACxE,kFAAkF;AAElF,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;CACvB,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,+EAA+E;AAC/E,EAAE;AACF,yEAAyE;AACzE,+DAA+D;AAE/D,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACvB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;KACxC,CAAC;IACF,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACrD,CAAC,CAAC;AAEH,gFAAgF;AAEhF,2EAA2E;AAC3E,+EAA+E;AAC/E,0DAA0D;AAC1D,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAE1E,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IAC/B,KAAK,EAAE,oBAAoB;IAC3B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;CACvB,CAAC,CAAC;AAEH,gFAAgF;AAEhF,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;QACd,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;QAC1B,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;QAC5B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;QACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAClC,KAAK,EAAE,gBAAgB;KACxB,CAAC;IACF,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAEH,gFAAgF;AAEhF,0EAA0E;AAC1E,6EAA6E;AAC7E,2EAA2E;AAC3E,8CAA8C;AAC9C,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,6DAA6D;AAC7D,MAAM,mBAAmB,GAAG,YAAY,CAAC;AACzC,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAEvC,+EAA+E;AAE/E,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAC9B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;CAC3E,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACvB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC;KAC1C,CAAC;IACF,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACrD,CAAC,CAAC;AAEH,iFAAiF;AAEjF,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE;IACtD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACvD,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;IACnC,eAAe,EAAE,mBAAmB;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;CACvB,CAAC,CAAC;AAEH,gFAAgF;AAChF,EAAE;AACF,2EAA2E;AAC3E,uEAAuE;AACvE,kEAAkE;AAElE,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC;IAChC,qBAAqB;IACrB,mBAAmB;IACnB,wBAAwB;IACxB,iBAAiB;IACjB,sBAAsB;IACtB,oBAAoB;IACpB,qBAAqB;IACrB,mBAAmB;IACnB,iBAAiB;IACjB,oBAAoB;CACrB,CAAC,CAAC;AAEH,gCAAgC;AAChC,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAiM7B;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IACxC,MAAM,GAAG,EAAE,CAAC;IACZ,UAAU,GAAkB,IAAI,CAAC;IACjC,cAAc,GAAS,IAAI,IAAI,EAAE,CAAC;IAClC,mBAAmB,GAAG,CAAC,CAAC;IAEhC,IAAI,SAAS,KAAoB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,IAAI,aAAa,KAAW,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IACzD,oEAAoE;IACpE,IAAI,kBAAkB,KAAa,OAAO,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAErE;;OAEG;IACH,MAAM,CAAC,MAAgB;QACrB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAClC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACpB,2CAA2C;YAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,sCAAsC;QACtC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QAEhC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,yBAAyB;YACzB,IAAI,GAAY,CAAC;YACjB,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;gBACjF,SAAS;YACX,CAAC;YAED,sCAAsC;YACtC,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,2CAA2C;gBAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM;qBAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;qBAC7C,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,OAAO,CAAC,IAAI,CACV,oCAAoC,IAAI,CAAC,mBAAmB,YAAY,MAAM,GAAG;oBACjF,WAAW,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACnC,CAAC;gBACF,SAAS;YACX,CAAC;YAED,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC;YACjC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAmB,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,KAAkB;QACnC,2CAA2C;QAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAE1B,mDAAmD;QACnD,IAAI,YAAY,IAAI,KAAK,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAClE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAoB,CAAC;QAC/C,CAAC;QAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,QAAQ;gBACX,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;oBAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAwB,CAAC,CAAC;gBAC9C,CAAC;qBAAM,IACL,KAAK,CAAC,OAAO,KAAK,kBAAkB;oBACpC,KAAK,CAAC,OAAO,KAAK,eAAe;oBACjC,KAAK,CAAC,OAAO,KAAK,oBAAoB,EACtC,CAAC;oBACD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAsB,CAAC,CAAC;gBAChD,CAAC;gBACD,qEAAqE;gBACrE,qEAAqE;gBACrE,MAAM;YAER,KAAK,WAAW;gBACd,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAyB,CAAC,CAAC;gBAClD,MAAM;YAER,KAAK,QAAQ;gBACX,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAoC,CAAC,CAAC;gBAC1D,MAAM;YAER,gEAAgE;YAChE,iEAAiE;QACnE,CAAC;IACH,CAAC;CACF;AAED,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAe,EAAE,OAAe;IAC1D,MAAM,OAAO,GAAgB;QAC3B,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE;YACP,IAAI,EAAE,MAAM;YACZ,OAAO;SACR;KACF,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5C,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Shared token usage parsing utilities for Telora daemon and factory.
3
+ *
4
+ * Provides a Transform stream that passes all data through (for log files)
5
+ * while sniffing each NDJSON line for `result` events containing token usage
6
+ * stats. Also provides standalone parsing and aggregation functions for cases
7
+ * where the output is already captured as a string.
8
+ *
9
+ * This is the canonical location for token-usage parsing -- both the daemon
10
+ * and the factory builder import from here.
11
+ */
12
+ import { Transform, type TransformCallback } from 'node:stream';
13
+ /** Accumulated token usage from a Claude Code result event. */
14
+ export interface ParsedTokenUsage {
15
+ /** Total input tokens used. */
16
+ inputTokens: number;
17
+ /** Total output tokens used. */
18
+ outputTokens: number;
19
+ /** Total cost in USD (null if not reported). */
20
+ totalCostUsd: number | null;
21
+ }
22
+ /**
23
+ * Parse token usage from a raw NDJSON output string (e.g. from execFileSync).
24
+ *
25
+ * Scans all lines for `"type":"result"` events and extracts the last one's
26
+ * usage stats. Returns null if no result event is found.
27
+ */
28
+ export declare function parseTokenUsageFromOutput(output: string): ParsedTokenUsage | null;
29
+ /**
30
+ * Sum multiple ParsedTokenUsage values into a single aggregate.
31
+ * Useful for accumulating cost across retries or multiple planning phases.
32
+ */
33
+ export declare function sumTokenUsage(usages: (ParsedTokenUsage | null)[]): ParsedTokenUsage | null;
34
+ /**
35
+ * A passthrough Transform stream that sniffs NDJSON lines for result events.
36
+ *
37
+ * All data flows through unchanged (so it can be piped to a log file).
38
+ * Internally, the stream buffers partial lines and inspects each complete
39
+ * line for `"type":"result"` events. When found, it extracts
40
+ * `usage.input_tokens`, `usage.output_tokens`, and `total_cost_usd`.
41
+ *
42
+ * Usage:
43
+ * ```
44
+ * const parser = new TokenSniffingTransform();
45
+ * proc.stdout.pipe(parser).pipe(logFileStream);
46
+ * // ... after process exits:
47
+ * const usage = parser.usage; // { inputTokens, outputTokens, totalCostUsd }
48
+ * ```
49
+ */
50
+ export declare class TokenSniffingTransform extends Transform {
51
+ private lineBuffer;
52
+ private _usage;
53
+ /** The last parsed result event's token usage, or null if none seen. */
54
+ get usage(): ParsedTokenUsage | null;
55
+ /** Total token count (input + output), or 0 if no result event was parsed. */
56
+ get totalTokens(): number;
57
+ _transform(chunk: Buffer, _encoding: BufferEncoding, callback: TransformCallback): void;
58
+ _flush(callback: TransformCallback): void;
59
+ /**
60
+ * Attempt to parse a line as a result event with token usage.
61
+ *
62
+ * Uses a fast string check before attempting JSON.parse to avoid
63
+ * the overhead of parsing every line (most are stream_event or assistant).
64
+ */
65
+ private tryParseResultLine;
66
+ }
67
+ //# sourceMappingURL=token-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-usage.d.ts","sourceRoot":"","sources":["../src/token-usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAMhE,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAMD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CA6BjF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,CAAC,gBAAgB,GAAG,IAAI,CAAC,EAAE,GAAG,gBAAgB,GAAG,IAAI,CAW1F;AAMD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACnD,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,MAAM,CAAiC;IAE/C,wEAAwE;IACxE,IAAI,KAAK,IAAI,gBAAgB,GAAG,IAAI,CAEnC;IAED,8EAA8E;IAC9E,IAAI,WAAW,IAAI,MAAM,CAGxB;IAED,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAoBvF,MAAM,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IASzC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;CA4B3B"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Shared token usage parsing utilities for Telora daemon and factory.
3
+ *
4
+ * Provides a Transform stream that passes all data through (for log files)
5
+ * while sniffing each NDJSON line for `result` events containing token usage
6
+ * stats. Also provides standalone parsing and aggregation functions for cases
7
+ * where the output is already captured as a string.
8
+ *
9
+ * This is the canonical location for token-usage parsing -- both the daemon
10
+ * and the factory builder import from here.
11
+ */
12
+ import { Transform } from 'node:stream';
13
+ // ============================================================================
14
+ // Parsing functions
15
+ // ============================================================================
16
+ /**
17
+ * Parse token usage from a raw NDJSON output string (e.g. from execFileSync).
18
+ *
19
+ * Scans all lines for `"type":"result"` events and extracts the last one's
20
+ * usage stats. Returns null if no result event is found.
21
+ */
22
+ export function parseTokenUsageFromOutput(output) {
23
+ let lastUsage = null;
24
+ const lines = output.split('\n');
25
+ for (const line of lines) {
26
+ const trimmed = line.trim();
27
+ if (!trimmed || !trimmed.includes('"result"'))
28
+ continue;
29
+ try {
30
+ const parsed = JSON.parse(trimmed);
31
+ if (parsed.type !== 'result')
32
+ continue;
33
+ const usage = parsed.usage;
34
+ if (!usage)
35
+ continue;
36
+ lastUsage = {
37
+ inputTokens: typeof usage.input_tokens === 'number' ? usage.input_tokens : 0,
38
+ outputTokens: typeof usage.output_tokens === 'number' ? usage.output_tokens : 0,
39
+ totalCostUsd: typeof parsed.total_cost_usd === 'number' ? parsed.total_cost_usd : null,
40
+ };
41
+ }
42
+ catch {
43
+ // Not valid JSON -- ignore
44
+ }
45
+ }
46
+ return lastUsage;
47
+ }
48
+ /**
49
+ * Sum multiple ParsedTokenUsage values into a single aggregate.
50
+ * Useful for accumulating cost across retries or multiple planning phases.
51
+ */
52
+ export function sumTokenUsage(usages) {
53
+ const nonNull = usages.filter((u) => u !== null);
54
+ if (nonNull.length === 0)
55
+ return null;
56
+ return {
57
+ inputTokens: nonNull.reduce((sum, u) => sum + u.inputTokens, 0),
58
+ outputTokens: nonNull.reduce((sum, u) => sum + u.outputTokens, 0),
59
+ totalCostUsd: nonNull.some((u) => u.totalCostUsd !== null)
60
+ ? nonNull.reduce((sum, u) => sum + (u.totalCostUsd ?? 0), 0)
61
+ : null,
62
+ };
63
+ }
64
+ // ============================================================================
65
+ // Transform stream
66
+ // ============================================================================
67
+ /**
68
+ * A passthrough Transform stream that sniffs NDJSON lines for result events.
69
+ *
70
+ * All data flows through unchanged (so it can be piped to a log file).
71
+ * Internally, the stream buffers partial lines and inspects each complete
72
+ * line for `"type":"result"` events. When found, it extracts
73
+ * `usage.input_tokens`, `usage.output_tokens`, and `total_cost_usd`.
74
+ *
75
+ * Usage:
76
+ * ```
77
+ * const parser = new TokenSniffingTransform();
78
+ * proc.stdout.pipe(parser).pipe(logFileStream);
79
+ * // ... after process exits:
80
+ * const usage = parser.usage; // { inputTokens, outputTokens, totalCostUsd }
81
+ * ```
82
+ */
83
+ export class TokenSniffingTransform extends Transform {
84
+ lineBuffer = '';
85
+ _usage = null;
86
+ /** The last parsed result event's token usage, or null if none seen. */
87
+ get usage() {
88
+ return this._usage;
89
+ }
90
+ /** Total token count (input + output), or 0 if no result event was parsed. */
91
+ get totalTokens() {
92
+ if (!this._usage)
93
+ return 0;
94
+ return this._usage.inputTokens + this._usage.outputTokens;
95
+ }
96
+ _transform(chunk, _encoding, callback) {
97
+ // Pass all data through unchanged
98
+ this.push(chunk);
99
+ // Buffer and process lines
100
+ this.lineBuffer += chunk.toString();
101
+ const lines = this.lineBuffer.split('\n');
102
+ // Keep the last (potentially incomplete) line in the buffer
103
+ this.lineBuffer = lines.pop() ?? '';
104
+ for (const line of lines) {
105
+ const trimmed = line.trim();
106
+ if (trimmed) {
107
+ this.tryParseResultLine(trimmed);
108
+ }
109
+ }
110
+ callback();
111
+ }
112
+ _flush(callback) {
113
+ // Process any remaining data in the buffer
114
+ const trimmed = this.lineBuffer.trim();
115
+ if (trimmed) {
116
+ this.tryParseResultLine(trimmed);
117
+ }
118
+ callback();
119
+ }
120
+ /**
121
+ * Attempt to parse a line as a result event with token usage.
122
+ *
123
+ * Uses a fast string check before attempting JSON.parse to avoid
124
+ * the overhead of parsing every line (most are stream_event or assistant).
125
+ */
126
+ tryParseResultLine(line) {
127
+ // Fast check: skip lines that definitely aren't result events
128
+ if (!line.includes('"result"')) {
129
+ return;
130
+ }
131
+ try {
132
+ const parsed = JSON.parse(line);
133
+ if (parsed.type !== 'result')
134
+ return;
135
+ const usage = parsed.usage;
136
+ if (!usage)
137
+ return;
138
+ this._usage = {
139
+ inputTokens: typeof usage.input_tokens === 'number' ? usage.input_tokens : 0,
140
+ outputTokens: typeof usage.output_tokens === 'number' ? usage.output_tokens : 0,
141
+ totalCostUsd: typeof parsed.total_cost_usd === 'number' ? parsed.total_cost_usd : null,
142
+ };
143
+ this.emit('result', parsed);
144
+ }
145
+ catch {
146
+ // Not valid JSON despite matching the string check -- ignore
147
+ }
148
+ }
149
+ }
150
+ //# sourceMappingURL=token-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-usage.js","sourceRoot":"","sources":["../src/token-usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Declarative key mapping utilities for camelCase <-> snake_case transforms.
3
+ *
4
+ * These utilities are used by query modules in both the daemon and factory
5
+ * engines to transform API response objects (snake_case DB columns) into
6
+ * application types (camelCase TypeScript interfaces).
7
+ *
8
+ * Extracted from packages/daemon/src/queries/shared.ts.
9
+ */
10
+ /**
11
+ * Mapping specification for each target key.
12
+ *
13
+ * Each target key maps to either:
14
+ * - A source key name (direct copy)
15
+ * - `{ from: sourceKey, default: fallback }` (copy with default if null/undefined)
16
+ * - `{ value: literal }` (hardcoded constant)
17
+ */
18
+ type KeyMapping<TSource, TTarget> = {
19
+ [K in keyof TTarget]: keyof TSource | {
20
+ from: keyof TSource;
21
+ default: TTarget[K];
22
+ } | {
23
+ value: TTarget[K];
24
+ };
25
+ };
26
+ /**
27
+ * Transform an object's keys using a declarative mapping config.
28
+ *
29
+ * Each target key maps to either:
30
+ * - A source key name (direct copy)
31
+ * - `{ from: sourceKey, default: fallback }` (copy with default if null/undefined)
32
+ * - `{ value: literal }` (hardcoded constant)
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const toAppType = createTransform<ApiRole, AgentRole>({
37
+ * id: 'id',
38
+ * organization_id: 'organizationId',
39
+ * allowed_tools: { from: 'allowedTools', default: [] as string[] },
40
+ * });
41
+ * const role = toAppType(apiRole);
42
+ * ```
43
+ */
44
+ export declare function createTransform<TSource, TTarget>(mapping: KeyMapping<TSource, TTarget>): (source: TSource) => TTarget;
45
+ /**
46
+ * Transform an updates object by mapping keys (e.g. snake_case -> camelCase).
47
+ * Only includes keys that are present and not undefined in the source.
48
+ *
49
+ * This is useful for building partial update payloads where you only want
50
+ * to include fields that were actually provided.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * const fields = mapDefinedKeys(updates, {
55
+ * exit_reason: 'exitReason',
56
+ * started_at: 'startedAt',
57
+ * });
58
+ * // If updates = { exit_reason: 'done', started_at: undefined }
59
+ * // Result = { exitReason: 'done' } (started_at omitted because undefined)
60
+ * ```
61
+ */
62
+ export declare function mapDefinedKeys(source: Record<string, unknown>, keyMap: Record<string, string>): Record<string, unknown>;
63
+ export {};
64
+ //# sourceMappingURL=transforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../src/transforms.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;;;;;GAOG;AACH,KAAK,UAAU,CAAC,OAAO,EAAE,OAAO,IAAI;KACjC,CAAC,IAAI,MAAM,OAAO,GAAG,MAAM,OAAO,GAAG;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE;CAC3G,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAC9C,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,GACpC,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAkB9B;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB"}