claude-code-parser 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # claude-code-parser
2
+
3
+ [![npm version](https://img.shields.io/npm/v/claude-code-parser)](https://www.npmjs.com/package/claude-code-parser)
4
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/claude-code-parser)](https://bundlephobia.com/package/claude-code-parser)
5
+
6
+ Parse Claude Code's `--output-format stream-json` NDJSON output into fully typed TypeScript events. Zero dependencies. 9 kB.
7
+
8
+ **[Documentation](https://udhaykumarbala.github.io/claude-code-parser/)** | **[Protocol Reference](https://udhaykumarbala.github.io/claude-code-parser/protocol/overview)**
9
+
10
+ > Includes the first standalone documentation of Claude Code's undocumented `stream-json` protocol.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install claude-code-parser
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```typescript
21
+ import { spawn } from 'child_process'
22
+ import { createInterface } from 'readline'
23
+ import { parseLine, Translator, createMessage } from 'claude-code-parser'
24
+
25
+ const claude = spawn('claude', [
26
+ '-p', '--input-format', 'stream-json',
27
+ '--output-format', 'stream-json', '--verbose',
28
+ ], { stdio: ['pipe', 'pipe', 'inherit'] })
29
+
30
+ const translator = new Translator()
31
+
32
+ const rl = createInterface({ input: claude.stdout! })
33
+ rl.on('line', (line) => {
34
+ const event = parseLine(line)
35
+ if (!event) return
36
+
37
+ for (const relay of translator.translate(event)) {
38
+ switch (relay.type) {
39
+ case 'text_delta': process.stdout.write(relay.content); break
40
+ case 'tool_use': console.log(`\n[tool] ${relay.toolName}`); break
41
+ case 'turn_complete': console.log(`\n[done] $${relay.costUsd?.toFixed(4)}`); break
42
+ }
43
+ }
44
+ })
45
+
46
+ claude.stdin!.write(createMessage.user('What is 2 + 2?'))
47
+ ```
48
+
49
+ ## API
50
+
51
+ | Export | Description |
52
+ |---|---|
53
+ | `parseLine(line)` | NDJSON line → `ClaudeEvent \| null` |
54
+ | `Translator` | Stateful dedup translator → `RelayEvent[]` |
55
+ | `createMessage.user(text)` | Construct stdin user message |
56
+ | `createMessage.approve(id)` | Approve pending tool execution |
57
+ | `createMessage.deny(id)` | Deny pending tool execution |
58
+ | `createMessage.toolResult(id, content)` | Send tool result |
59
+ | `extractContent(raw)` | Normalize polymorphic tool_result content |
60
+
61
+ ### RelayEvent Types
62
+
63
+ `text_delta` | `thinking_delta` | `tool_use` | `tool_result` | `session_meta` | `turn_complete` | `error`
64
+
65
+ [Full API docs](https://udhaykumarbala.github.io/claude-code-parser/guide/api)
66
+
67
+ ## Why This Exists
68
+
69
+ The official SDK (`@anthropic-ai/claude-code`) couples parsing with subprocess management. This library **only parses** — for developers building custom relays, dashboards, CI tools, or browser viewers who need raw event access.
70
+
71
+ Key problems it solves:
72
+ - **`--verbose` deduplication** — cumulative snapshots require stateful content tracking
73
+ - **Multi-agent interleaving** — sub-agents produce interleaved events on the same stdout
74
+ - **Polymorphic content** — `tool_result.content` can be string, array, or null
75
+ - **Double-encoded results** — the `result` field is JSON inside JSON
76
+
77
+ ## Documentation
78
+
79
+ - [Getting Started](https://udhaykumarbala.github.io/claude-code-parser/guide/getting-started)
80
+ - [API Reference](https://udhaykumarbala.github.io/claude-code-parser/guide/api)
81
+ - [Examples](https://udhaykumarbala.github.io/claude-code-parser/guide/examples) — WS relay, log viewer, CI tracker, tool approval
82
+ - [Protocol Overview](https://udhaykumarbala.github.io/claude-code-parser/protocol/overview)
83
+ - [Output Events](https://udhaykumarbala.github.io/claude-code-parser/protocol/output-events) — Full event catalog
84
+ - [Input Messages](https://udhaykumarbala.github.io/claude-code-parser/protocol/input-messages) — Undocumented stdin protocol
85
+ - [Deduplication](https://udhaykumarbala.github.io/claude-code-parser/protocol/deduplication)
86
+ - [Multi-Agent](https://udhaykumarbala.github.io/claude-code-parser/protocol/multi-agent)
87
+ - [Gotchas](https://udhaykumarbala.github.io/claude-code-parser/protocol/gotchas) — Double encoding, polymorphic content, thinking field names
88
+
89
+ ## License
90
+
91
+ MIT
92
+
93
+ > This is an unofficial community package. Not affiliated with or endorsed by Anthropic.
@@ -0,0 +1,6 @@
1
+ export { parseLine } from './parser.js';
2
+ export { Translator, extractContent } from './translator.js';
3
+ export { createMessage } from './writer.js';
4
+ export type { ClaudeEvent, ClaudeMessage, ClaudeContent, ModelUsageEntry, } from './types/protocol.js';
5
+ export type { RelayEvent, TextDeltaEvent, ThinkingDeltaEvent, ToolUseEvent, ToolResultEvent, SessionMetaEvent, TurnCompleteEvent, ErrorEvent, } from './types/events.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAGvC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAG3C,YAAY,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,eAAe,GAChB,MAAM,qBAAqB,CAAA;AAG5B,YAAY,EACV,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,GACX,MAAM,mBAAmB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ // Core parser
2
+ export { parseLine } from './parser.js';
3
+ // Stateful translator with dedup
4
+ export { Translator, extractContent } from './translator.js';
5
+ // Stdin message constructors
6
+ export { createMessage } from './writer.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC,iCAAiC;AACjC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAE5D,6BAA6B;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,12 @@
1
+ import type { ClaudeEvent } from './types/protocol.js';
2
+ /**
3
+ * Parse a single NDJSON line from Claude Code's stdout into a typed event.
4
+ *
5
+ * Returns `null` for empty lines or unparseable JSON (matching the Go
6
+ * reference which logs and skips bad lines).
7
+ *
8
+ * @param line - One line of NDJSON from Claude Code's stdout
9
+ * @returns Typed ClaudeEvent, or null if the line is empty/invalid
10
+ */
11
+ export declare function parseLine(line: string): ClaudeEvent | null;
12
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAS1D"}
package/dist/parser.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Parse a single NDJSON line from Claude Code's stdout into a typed event.
3
+ *
4
+ * Returns `null` for empty lines or unparseable JSON (matching the Go
5
+ * reference which logs and skips bad lines).
6
+ *
7
+ * @param line - One line of NDJSON from Claude Code's stdout
8
+ * @returns Typed ClaudeEvent, or null if the line is empty/invalid
9
+ */
10
+ export function parseLine(line) {
11
+ const trimmed = line.trim();
12
+ if (trimmed.length === 0)
13
+ return null;
14
+ try {
15
+ return JSON.parse(trimmed);
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAErC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAA;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { ClaudeEvent } from './types/protocol.js';
2
+ import type { RelayEvent } from './types/events.js';
3
+ /**
4
+ * Translates raw ClaudeEvents into deduplicated RelayEvents.
5
+ *
6
+ * Tracks content block index to avoid re-emitting blocks that were
7
+ * already sent in previous `assistant` events (the `--verbose` mode
8
+ * cumulative snapshot problem).
9
+ *
10
+ * Port of the Go Translator in mobile-code/translator.go.
11
+ */
12
+ export declare class Translator {
13
+ private lastContentIndex;
14
+ private lastFirstBlockKey;
15
+ private _sessionId;
16
+ private _model;
17
+ /** The session ID captured from the most recent `system/init` event. */
18
+ get sessionId(): string | undefined;
19
+ /** The model name captured from the most recent `system/init` event. */
20
+ get model(): string | undefined;
21
+ /** Reset content index tracking. Call on new turn/session. */
22
+ reset(): void;
23
+ /** Convert a raw ClaudeEvent into zero or more RelayEvents. */
24
+ translate(raw: ClaudeEvent): RelayEvent[];
25
+ private translateSystem;
26
+ private translateResult;
27
+ private translateAssistant;
28
+ private translateUser;
29
+ private translateContentBlock;
30
+ }
31
+ /**
32
+ * Handle the polymorphic `content` field in tool_result blocks.
33
+ *
34
+ * Three possible shapes:
35
+ * 1. `string` — plain text
36
+ * 2. `Array<{ type: string; text: string }>` — structured text blocks, joined with newline
37
+ * 3. `null` / `undefined` — empty string
38
+ */
39
+ export declare function extractContent(raw: unknown): string;
40
+ //# sourceMappingURL=translator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator.d.ts","sourceRoot":"","sources":["../src/translator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAgC,MAAM,qBAAqB,CAAA;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD;;;;;;;;GAQG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,MAAM,CAAoB;IAElC,wEAAwE;IACxE,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,wEAAwE;IACxE,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAED,8DAA8D;IAC9D,KAAK,IAAI,IAAI;IAKb,+DAA+D;IAC/D,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,UAAU,EAAE;IAgBzC,OAAO,CAAC,eAAe;IAgCvB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,kBAAkB;IA+B1B,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,qBAAqB;CAsC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAiBnD"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Translates raw ClaudeEvents into deduplicated RelayEvents.
3
+ *
4
+ * Tracks content block index to avoid re-emitting blocks that were
5
+ * already sent in previous `assistant` events (the `--verbose` mode
6
+ * cumulative snapshot problem).
7
+ *
8
+ * Port of the Go Translator in mobile-code/translator.go.
9
+ */
10
+ export class Translator {
11
+ lastContentIndex = 0;
12
+ lastFirstBlockKey;
13
+ _sessionId;
14
+ _model;
15
+ /** The session ID captured from the most recent `system/init` event. */
16
+ get sessionId() {
17
+ return this._sessionId;
18
+ }
19
+ /** The model name captured from the most recent `system/init` event. */
20
+ get model() {
21
+ return this._model;
22
+ }
23
+ /** Reset content index tracking. Call on new turn/session. */
24
+ reset() {
25
+ this.lastContentIndex = 0;
26
+ this.lastFirstBlockKey = undefined;
27
+ }
28
+ /** Convert a raw ClaudeEvent into zero or more RelayEvents. */
29
+ translate(raw) {
30
+ switch (raw.type) {
31
+ case 'system':
32
+ return this.translateSystem(raw);
33
+ case 'result':
34
+ return this.translateResult(raw);
35
+ case 'assistant':
36
+ return this.translateAssistant(raw);
37
+ case 'user':
38
+ return this.translateUser(raw);
39
+ default:
40
+ // progress, rate_limit_event, and unknown types are ignored
41
+ return [];
42
+ }
43
+ }
44
+ translateSystem(raw) {
45
+ switch (raw.subtype) {
46
+ case 'init':
47
+ if (raw.session_id)
48
+ this._sessionId = raw.session_id;
49
+ if (raw.model)
50
+ this._model = raw.model;
51
+ return [{
52
+ type: 'session_meta',
53
+ model: raw.model ?? 'unknown',
54
+ }];
55
+ case 'result': {
56
+ const resultText = parseDoubleEncodedResult(raw.result);
57
+ if (raw.is_error) {
58
+ this.reset();
59
+ return [{
60
+ type: 'error',
61
+ message: resultText,
62
+ sessionId: raw.session_id,
63
+ }];
64
+ }
65
+ this.reset();
66
+ return [{
67
+ type: 'turn_complete',
68
+ sessionId: raw.session_id,
69
+ }];
70
+ }
71
+ default:
72
+ return [];
73
+ }
74
+ }
75
+ translateResult(raw) {
76
+ const resultText = parseDoubleEncodedResult(raw.result);
77
+ if (raw.subtype === 'error' || raw.is_error) {
78
+ this.reset();
79
+ return [{
80
+ type: 'error',
81
+ message: resultText,
82
+ sessionId: raw.session_id,
83
+ }];
84
+ }
85
+ const ev = {
86
+ type: 'turn_complete',
87
+ sessionId: raw.session_id,
88
+ costUsd: raw.total_cost_usd,
89
+ };
90
+ // Extract usage from modelUsage (take first model entry)
91
+ if (raw.modelUsage) {
92
+ for (const usage of Object.values(raw.modelUsage)) {
93
+ ev.inputTokens =
94
+ usage.inputTokens + usage.cacheReadInputTokens + usage.cacheCreationInputTokens;
95
+ ev.outputTokens = usage.outputTokens;
96
+ ev.contextWindow = usage.contextWindow;
97
+ break; // Take the first (usually only) model
98
+ }
99
+ }
100
+ this.reset();
101
+ return [ev];
102
+ }
103
+ translateAssistant(raw) {
104
+ const msg = raw.message;
105
+ if (!msg?.content || msg.content.length === 0)
106
+ return [];
107
+ // Detect context switches (new turn, different sub-agent, etc.)
108
+ // by fingerprinting the first content block. If it doesn't match
109
+ // what we were tracking, this is a different message stream → reset.
110
+ const firstKey = blockFingerprint(msg.content[0]);
111
+ if (firstKey !== this.lastFirstBlockKey) {
112
+ this.lastContentIndex = 0;
113
+ this.lastFirstBlockKey = firstKey;
114
+ }
115
+ // Safety: if content shrank below our index for any other reason, reset.
116
+ if (msg.content.length < this.lastContentIndex) {
117
+ this.lastContentIndex = 0;
118
+ }
119
+ const events = [];
120
+ // Only process content blocks we haven't sent yet (dedup)
121
+ for (let i = this.lastContentIndex; i < msg.content.length; i++) {
122
+ const block = msg.content[i];
123
+ const ev = this.translateContentBlock(block);
124
+ if (ev)
125
+ events.push(ev);
126
+ }
127
+ this.lastContentIndex = msg.content.length;
128
+ return events;
129
+ }
130
+ translateUser(raw) {
131
+ const msg = raw.message;
132
+ if (!msg?.content)
133
+ return [];
134
+ const events = [];
135
+ for (const block of msg.content) {
136
+ if (block.type === 'tool_result') {
137
+ events.push({
138
+ type: 'tool_result',
139
+ toolUseId: block.tool_use_id ?? '',
140
+ output: extractContent(block.content),
141
+ isError: block.is_error ?? false,
142
+ });
143
+ }
144
+ }
145
+ return events;
146
+ }
147
+ translateContentBlock(block) {
148
+ switch (block.type) {
149
+ case 'text':
150
+ return {
151
+ type: 'text_delta',
152
+ content: block.text ?? '',
153
+ };
154
+ case 'thinking': {
155
+ const text = block.thinking ?? block.text ?? '';
156
+ if (!text)
157
+ return null;
158
+ return {
159
+ type: 'thinking_delta',
160
+ content: text,
161
+ };
162
+ }
163
+ case 'tool_use':
164
+ return {
165
+ type: 'tool_use',
166
+ toolUseId: block.id ?? '',
167
+ toolName: block.name ?? '',
168
+ input: block.input != null ? JSON.stringify(block.input) : '',
169
+ };
170
+ case 'tool_result':
171
+ return {
172
+ type: 'tool_result',
173
+ toolUseId: block.tool_use_id ?? '',
174
+ output: extractContent(block.content),
175
+ isError: block.is_error ?? false,
176
+ };
177
+ default:
178
+ // Unknown block types are silently skipped
179
+ return null;
180
+ }
181
+ }
182
+ }
183
+ /**
184
+ * Handle the polymorphic `content` field in tool_result blocks.
185
+ *
186
+ * Three possible shapes:
187
+ * 1. `string` — plain text
188
+ * 2. `Array<{ type: string; text: string }>` — structured text blocks, joined with newline
189
+ * 3. `null` / `undefined` — empty string
190
+ */
191
+ export function extractContent(raw) {
192
+ if (raw == null)
193
+ return '';
194
+ if (typeof raw === 'string')
195
+ return raw;
196
+ if (Array.isArray(raw)) {
197
+ const parts = [];
198
+ for (const block of raw) {
199
+ if (block && typeof block === 'object' && 'text' in block && typeof block.text === 'string') {
200
+ if (block.text)
201
+ parts.push(block.text);
202
+ }
203
+ }
204
+ return parts.join('\n');
205
+ }
206
+ // Fallback: stringify whatever we got
207
+ return String(raw);
208
+ }
209
+ /**
210
+ * Create a fingerprint for a content block to detect context switches.
211
+ *
212
+ * Uses the block's stable identity: tool_use blocks have unique IDs,
213
+ * text/thinking blocks use a prefix of their content. This lets the
214
+ * translator detect when interleaved sub-agent events switch context.
215
+ */
216
+ function blockFingerprint(block) {
217
+ // tool_use blocks have unique IDs — best signal
218
+ if (block.id)
219
+ return `${block.type}:${block.id}`;
220
+ // thinking/text blocks — use first 64 chars as fingerprint
221
+ const text = block.thinking ?? block.text ?? '';
222
+ if (text)
223
+ return `${block.type}:${text.slice(0, 64)}`;
224
+ // Fallback for exotic blocks
225
+ return `${block.type}:${block.tool_use_id ?? 'unknown'}`;
226
+ }
227
+ /**
228
+ * Parse the double-encoded `result` field.
229
+ * Claude Code's result field is a JSON-encoded string (e.g., `"\"actual text\""`).
230
+ */
231
+ function parseDoubleEncodedResult(result) {
232
+ if (result == null)
233
+ return '';
234
+ if (typeof result === 'string') {
235
+ try {
236
+ const parsed = JSON.parse(result);
237
+ if (typeof parsed === 'string')
238
+ return parsed;
239
+ }
240
+ catch {
241
+ // Not double-encoded, use as-is
242
+ }
243
+ return result;
244
+ }
245
+ return String(result);
246
+ }
247
+ //# sourceMappingURL=translator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator.js","sourceRoot":"","sources":["../src/translator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Translated relay events — the normalized output of the Translator.
3
+ *
4
+ * This is a discriminated union on the `type` field. Consumers can
5
+ * switch on `event.type` to get full type narrowing.
6
+ */
7
+ export type RelayEvent = TextDeltaEvent | ThinkingDeltaEvent | ToolUseEvent | ToolResultEvent | SessionMetaEvent | TurnCompleteEvent | ErrorEvent;
8
+ export interface TextDeltaEvent {
9
+ type: 'text_delta';
10
+ content: string;
11
+ }
12
+ export interface ThinkingDeltaEvent {
13
+ type: 'thinking_delta';
14
+ content: string;
15
+ }
16
+ export interface ToolUseEvent {
17
+ type: 'tool_use';
18
+ toolUseId: string;
19
+ toolName: string;
20
+ /** Tool input as a JSON string. */
21
+ input: string;
22
+ }
23
+ export interface ToolResultEvent {
24
+ type: 'tool_result';
25
+ toolUseId: string;
26
+ output: string;
27
+ isError: boolean;
28
+ }
29
+ export interface SessionMetaEvent {
30
+ type: 'session_meta';
31
+ model: string;
32
+ }
33
+ export interface TurnCompleteEvent {
34
+ type: 'turn_complete';
35
+ sessionId?: string;
36
+ costUsd?: number;
37
+ inputTokens?: number;
38
+ outputTokens?: number;
39
+ contextWindow?: number;
40
+ }
41
+ export interface ErrorEvent {
42
+ type: 'error';
43
+ message: string;
44
+ sessionId?: string;
45
+ }
46
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAClB,cAAc,GACd,kBAAkB,GAClB,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,UAAU,CAAA;AAEd,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,aAAa,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Raw NDJSON types from Claude Code's `--output-format stream-json`.
3
+ *
4
+ * These mirror the wire format exactly. Fields use snake_case to match
5
+ * the JSON keys Claude Code emits. Types are intentionally loose —
6
+ * the protocol is undocumented and can add fields/types without notice.
7
+ */
8
+ /** Per-model token usage breakdown, keyed by model ID in ClaudeEvent.modelUsage. */
9
+ export interface ModelUsageEntry {
10
+ inputTokens: number;
11
+ outputTokens: number;
12
+ cacheReadInputTokens: number;
13
+ cacheCreationInputTokens: number;
14
+ contextWindow: number;
15
+ }
16
+ /** Raw NDJSON envelope from Claude Code's stdout. */
17
+ export interface ClaudeEvent {
18
+ type: string;
19
+ subtype?: string;
20
+ message?: ClaudeMessage;
21
+ /** Double-encoded JSON string — must be JSON.parse()'d to get actual text. */
22
+ result?: unknown;
23
+ session_id?: string;
24
+ model?: string;
25
+ tools?: string[];
26
+ duration_ms?: number;
27
+ duration_api_ms?: number;
28
+ cost_usd?: number;
29
+ total_cost_usd?: number;
30
+ is_error?: boolean;
31
+ num_turns?: number;
32
+ modelUsage?: Record<string, ModelUsageEntry>;
33
+ usage?: unknown;
34
+ }
35
+ /** Message payload within a ClaudeEvent. */
36
+ export interface ClaudeMessage {
37
+ content: ClaudeContent[];
38
+ role?: string;
39
+ stop_reason?: string;
40
+ }
41
+ /**
42
+ * Polymorphic content block.
43
+ *
44
+ * `type` is deliberately `string` (not a union) because Claude Code
45
+ * can add new block types in any release. The translator handles
46
+ * known types and silently skips unknown ones.
47
+ */
48
+ export interface ClaudeContent {
49
+ type: string;
50
+ /** Text content (for `text` blocks, also fallback for `thinking` blocks in some formats). */
51
+ text?: string;
52
+ /** Thinking content (primary field for `thinking` blocks). */
53
+ thinking?: string;
54
+ /** Tool use ID (for `tool_use` blocks). */
55
+ id?: string;
56
+ /** Tool name (for `tool_use` blocks). */
57
+ name?: string;
58
+ /** Tool input — kept as unknown since shapes vary by tool. */
59
+ input?: unknown;
60
+ /**
61
+ * Tool result content — polymorphic:
62
+ * - `string` — plain text
63
+ * - `Array<{ type: string; text: string }>` — structured text blocks
64
+ * - `null` — no content
65
+ */
66
+ content?: unknown;
67
+ /** Back-reference to the tool_use block (for `tool_result` blocks). */
68
+ tool_use_id?: string;
69
+ /** Whether the tool result is an error (for `tool_result` blocks). */
70
+ is_error?: boolean;
71
+ }
72
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/types/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,wBAAwB,EAAE,MAAM,CAAA;IAChC,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,6FAA6F;IAC7F,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2CAA2C;IAC3C,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Raw NDJSON types from Claude Code's `--output-format stream-json`.
3
+ *
4
+ * These mirror the wire format exactly. Fields use snake_case to match
5
+ * the JSON keys Claude Code emits. Types are intentionally loose —
6
+ * the protocol is undocumented and can add fields/types without notice.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/types/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Construct NDJSON messages for Claude Code's `--input-format stream-json` stdin.
3
+ *
4
+ * Each function returns a single NDJSON line (JSON + newline) ready to be
5
+ * written to the Claude Code process's stdin.
6
+ *
7
+ * Port of Go WriteToStdin, WriteToolResult, WriteToolResultWithContent
8
+ * from mobile-code/session.go.
9
+ */
10
+ export declare const createMessage: {
11
+ /**
12
+ * Construct a user chat message.
13
+ *
14
+ * @param content - The message text to send to Claude
15
+ * @returns NDJSON line to write to stdin
16
+ */
17
+ readonly user: (content: string) => string;
18
+ /**
19
+ * Approve a pending tool execution.
20
+ *
21
+ * @param toolUseId - The tool_use block ID to approve
22
+ * @returns NDJSON line to write to stdin
23
+ */
24
+ readonly approve: (toolUseId: string) => string;
25
+ /**
26
+ * Deny a pending tool execution.
27
+ *
28
+ * @param toolUseId - The tool_use block ID to deny
29
+ * @returns NDJSON line to write to stdin
30
+ */
31
+ readonly deny: (toolUseId: string) => string;
32
+ /**
33
+ * Send a tool result with custom content (for interactive tools like AskUserQuestion).
34
+ *
35
+ * @param toolUseId - The tool_use block ID this result is for
36
+ * @param content - The result content to send
37
+ * @returns NDJSON line to write to stdin
38
+ */
39
+ readonly toolResult: (toolUseId: string, content: string) => string;
40
+ };
41
+ //# sourceMappingURL=writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa;IACxB;;;;;OAKG;6BACW,MAAM,KAAG,MAAM;IAO7B;;;;;OAKG;kCACgB,MAAM,KAAG,MAAM;IAOlC;;;;;OAKG;+BACa,MAAM,KAAG,MAAM;IAO/B;;;;;;OAMG;qCACmB,MAAM,WAAW,MAAM,KAAG,MAAM;CAO9C,CAAA"}
package/dist/writer.js ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Construct NDJSON messages for Claude Code's `--input-format stream-json` stdin.
3
+ *
4
+ * Each function returns a single NDJSON line (JSON + newline) ready to be
5
+ * written to the Claude Code process's stdin.
6
+ *
7
+ * Port of Go WriteToStdin, WriteToolResult, WriteToolResultWithContent
8
+ * from mobile-code/session.go.
9
+ */
10
+ export const createMessage = {
11
+ /**
12
+ * Construct a user chat message.
13
+ *
14
+ * @param content - The message text to send to Claude
15
+ * @returns NDJSON line to write to stdin
16
+ */
17
+ user(content) {
18
+ return JSON.stringify({
19
+ type: 'user',
20
+ message: { role: 'user', content },
21
+ }) + '\n';
22
+ },
23
+ /**
24
+ * Approve a pending tool execution.
25
+ *
26
+ * @param toolUseId - The tool_use block ID to approve
27
+ * @returns NDJSON line to write to stdin
28
+ */
29
+ approve(toolUseId) {
30
+ return JSON.stringify({
31
+ type: 'approve',
32
+ tool_use_id: toolUseId,
33
+ }) + '\n';
34
+ },
35
+ /**
36
+ * Deny a pending tool execution.
37
+ *
38
+ * @param toolUseId - The tool_use block ID to deny
39
+ * @returns NDJSON line to write to stdin
40
+ */
41
+ deny(toolUseId) {
42
+ return JSON.stringify({
43
+ type: 'deny',
44
+ tool_use_id: toolUseId,
45
+ }) + '\n';
46
+ },
47
+ /**
48
+ * Send a tool result with custom content (for interactive tools like AskUserQuestion).
49
+ *
50
+ * @param toolUseId - The tool_use block ID this result is for
51
+ * @param content - The result content to send
52
+ * @returns NDJSON line to write to stdin
53
+ */
54
+ toolResult(toolUseId, content) {
55
+ return JSON.stringify({
56
+ type: 'tool_result',
57
+ tool_use_id: toolUseId,
58
+ content,
59
+ }) + '\n';
60
+ },
61
+ };
62
+ //# sourceMappingURL=writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B;;;;;OAKG;IACH,IAAI,CAAC,OAAe;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;SACnC,CAAC,GAAG,IAAI,CAAA;IACX,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,SAAiB;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,SAAS;SACvB,CAAC,GAAG,IAAI,CAAA;IACX,CAAC;IAED;;;;;OAKG;IACH,IAAI,CAAC,SAAiB;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,SAAS;SACvB,CAAC,GAAG,IAAI,CAAA;IACX,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,SAAiB,EAAE,OAAe;QAC3C,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,SAAS;YACtB,OAAO;SACR,CAAC,GAAG,IAAI,CAAA;IACX,CAAC;CACO,CAAA"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "claude-code-parser",
3
+ "version": "0.1.0",
4
+ "description": "Parse Claude Code's --output-format stream-json into fully typed TypeScript events",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ }
11
+ },
12
+ "types": "./dist/index.d.ts",
13
+ "files": [
14
+ "dist",
15
+ "LICENSE",
16
+ "README.md"
17
+ ],
18
+ "sideEffects": false,
19
+ "engines": {
20
+ "node": ">=18"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "typecheck": "tsc --noEmit",
27
+ "prepublishOnly": "npm run build",
28
+ "docs:dev": "vitepress dev docs",
29
+ "docs:build": "vitepress build docs",
30
+ "docs:preview": "vitepress preview docs"
31
+ },
32
+ "keywords": [
33
+ "claude",
34
+ "claude-code",
35
+ "anthropic",
36
+ "stream-json",
37
+ "ndjson",
38
+ "parser",
39
+ "cli",
40
+ "streaming",
41
+ "typescript"
42
+ ],
43
+ "author": "",
44
+ "license": "MIT",
45
+ "devDependencies": {
46
+ "@types/node": "^25.5.0",
47
+ "typescript": "^5.9.3",
48
+ "vitepress": "^1.6.4",
49
+ "vitest": "^4.1.0"
50
+ }
51
+ }