@mclawnet/claude-adapter 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.
@@ -0,0 +1,32 @@
1
+ import type { BackendAdapter, BackendProcess, SpawnOptions } from "@mclawnet/agent";
2
+ import { ClaudeProcess } from "./claude-process.js";
3
+ /**
4
+ * ClaudeCodeAdapter — BackendAdapter for Claude Code CLI.
5
+ *
6
+ * Spawns `claude` with `--output-format stream-json --input-format stream-json`
7
+ * for bidirectional NDJSON communication over stdin/stdout.
8
+ */
9
+ export declare class ClaudeCodeAdapter implements BackendAdapter {
10
+ readonly type = "claude-code";
11
+ private claudeBin;
12
+ private permissionMode;
13
+ constructor(options?: {
14
+ claudeBin?: string;
15
+ permissionMode?: string;
16
+ });
17
+ spawn(options: SpawnOptions): Promise<ClaudeProcess>;
18
+ stop(process: BackendProcess): Promise<void>;
19
+ send(process: BackendProcess, input: string): void;
20
+ onOutput(process: BackendProcess, handler: (msg: unknown) => void): void;
21
+ onTurnComplete(process: BackendProcess, handler: (info: {
22
+ claudeSessionId?: string;
23
+ cost?: number;
24
+ duration?: number;
25
+ contextUsage?: {
26
+ used: number;
27
+ total: number;
28
+ };
29
+ }) => void): void;
30
+ onError(process: BackendProcess, handler: (error: Error) => void): void;
31
+ }
32
+ //# sourceMappingURL=claude-code-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-adapter.d.ts","sourceRoot":"","sources":["../src/claude-code-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,cAAc;IACtD,QAAQ,CAAC,IAAI,iBAAiB;IAE9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE;IAK/D,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA8CpD,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAMlD,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAMxE,cAAc,CACZ,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,CAAC,IAAI,EAAE;QACd,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAChD,KAAK,IAAI,GACT,IAAI;IAMP,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;CAKxE"}
@@ -0,0 +1,80 @@
1
+ import { spawn } from "node:child_process";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { ClaudeProcess } from "./claude-process.js";
5
+ /**
6
+ * ClaudeCodeAdapter — BackendAdapter for Claude Code CLI.
7
+ *
8
+ * Spawns `claude` with `--output-format stream-json --input-format stream-json`
9
+ * for bidirectional NDJSON communication over stdin/stdout.
10
+ */
11
+ export class ClaudeCodeAdapter {
12
+ type = "claude-code";
13
+ claudeBin;
14
+ permissionMode;
15
+ constructor(options) {
16
+ this.claudeBin = options?.claudeBin ?? "claude";
17
+ this.permissionMode = options?.permissionMode ?? "bypassPermissions";
18
+ }
19
+ async spawn(options) {
20
+ const args = [
21
+ "--output-format", "stream-json",
22
+ "--input-format", "stream-json",
23
+ "--verbose",
24
+ "--permission-mode", this.permissionMode,
25
+ ];
26
+ if (options.resumeId) {
27
+ args.push("--resume", options.resumeId);
28
+ }
29
+ if (options.systemPrompt) {
30
+ args.push("--append-system-prompt", options.systemPrompt);
31
+ }
32
+ if (options.useBrainCore) {
33
+ const brainDir = join(homedir(), ".brain");
34
+ args.push("--add-dir", join(brainDir, "BrainCore"));
35
+ args.push("--add-dir", join(brainDir, "CoreSkill"));
36
+ }
37
+ const proc = spawn(this.claudeBin, args, {
38
+ cwd: options.workDir || process.cwd(),
39
+ stdio: ["pipe", "pipe", "pipe"],
40
+ env: { ...process.env },
41
+ });
42
+ // Wait for process to be ready (or fail to start)
43
+ await new Promise((resolve, reject) => {
44
+ const timeout = setTimeout(() => resolve(), 2000);
45
+ proc.on("error", (err) => {
46
+ clearTimeout(timeout);
47
+ reject(new Error(`Failed to spawn claude CLI: ${err.message}`));
48
+ });
49
+ proc.on("spawn", () => {
50
+ clearTimeout(timeout);
51
+ resolve();
52
+ });
53
+ });
54
+ return new ClaudeProcess(options.sessionId, proc);
55
+ }
56
+ async stop(process) {
57
+ await process.kill();
58
+ }
59
+ send(process, input) {
60
+ if (process instanceof ClaudeProcess) {
61
+ process.sendInput(input);
62
+ }
63
+ }
64
+ onOutput(process, handler) {
65
+ if (process instanceof ClaudeProcess) {
66
+ process.on("output", handler);
67
+ }
68
+ }
69
+ onTurnComplete(process, handler) {
70
+ if (process instanceof ClaudeProcess) {
71
+ process.on("turn_complete", handler);
72
+ }
73
+ }
74
+ onError(process, handler) {
75
+ if (process instanceof ClaudeProcess) {
76
+ process.on("error", handler);
77
+ }
78
+ }
79
+ }
80
+ //# sourceMappingURL=claude-code-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-adapter.js","sourceRoot":"","sources":["../src/claude-code-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ import { EventEmitter } from "node:events";
3
+ import type { BackendProcess } from "@mclawnet/agent";
4
+ /**
5
+ * Wraps a single Claude CLI process with stdin/stdout NDJSON communication.
6
+ *
7
+ * Persistent between turns: the process is kept alive across conversation
8
+ * turns and only killed on explicit close.
9
+ */
10
+ export declare class ClaudeProcess extends EventEmitter implements BackendProcess {
11
+ id: string;
12
+ workDir: string;
13
+ private proc;
14
+ private parser;
15
+ private killed;
16
+ private log;
17
+ constructor(sessionId: string, proc: ChildProcess);
18
+ /** Send user input to Claude CLI stdin as NDJSON */
19
+ sendInput(content: string): void;
20
+ kill(): Promise<void>;
21
+ private handleEvent;
22
+ }
23
+ //# sourceMappingURL=claude-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-process.d.ts","sourceRoot":"","sources":["../src/claude-process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtD;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,YAAa,YAAW,cAAc;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,GAAG,CAAC;gBAEA,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY;IAuCjD,oDAAoD;IACpD,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAa1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B,OAAO,CAAC,WAAW;CAoBpB"}
@@ -0,0 +1,95 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { StreamParser } from "./stream-parser.js";
3
+ import { createLogger } from "@mclawnet/logger";
4
+ /**
5
+ * Wraps a single Claude CLI process with stdin/stdout NDJSON communication.
6
+ *
7
+ * Persistent between turns: the process is kept alive across conversation
8
+ * turns and only killed on explicit close.
9
+ */
10
+ export class ClaudeProcess extends EventEmitter {
11
+ id;
12
+ workDir;
13
+ proc;
14
+ parser;
15
+ killed = false;
16
+ log;
17
+ constructor(sessionId, proc) {
18
+ super();
19
+ this.id = sessionId;
20
+ this.log = createLogger({ module: "claude", sessionId });
21
+ this.workDir = proc.spawnargs.includes("--cwd")
22
+ ? proc.spawnargs[proc.spawnargs.indexOf("--cwd") + 1]
23
+ : process.cwd();
24
+ this.proc = proc;
25
+ this.parser = new StreamParser((event) => this.handleEvent(event), (error) => this.emit("error", error));
26
+ // Wire stdout
27
+ proc.stdout?.on("data", (chunk) => {
28
+ this.parser.feed(chunk.toString());
29
+ });
30
+ // Log stderr but don't treat as fatal
31
+ proc.stderr?.on("data", (chunk) => {
32
+ const text = chunk.toString().trim();
33
+ if (text) {
34
+ this.log.warn({ stderr: text }, "claude stderr output");
35
+ }
36
+ });
37
+ proc.on("close", (code) => {
38
+ this.parser.flush();
39
+ if (!this.killed) {
40
+ this.emit("exit", code);
41
+ }
42
+ });
43
+ proc.on("error", (err) => {
44
+ this.emit("error", err);
45
+ });
46
+ }
47
+ /** Send user input to Claude CLI stdin as NDJSON */
48
+ sendInput(content) {
49
+ if (!this.proc.stdin?.writable) {
50
+ this.emit("error", new Error("Process stdin is not writable"));
51
+ return;
52
+ }
53
+ // Claude CLI with --input-format stream-json expects this format
54
+ const message = JSON.stringify({
55
+ type: "user",
56
+ message: { role: "user", content },
57
+ }) + "\n";
58
+ this.proc.stdin.write(message);
59
+ }
60
+ async kill() {
61
+ this.killed = true;
62
+ if (this.proc.exitCode !== null)
63
+ return;
64
+ return new Promise((resolve) => {
65
+ this.proc.once("close", () => resolve());
66
+ this.proc.kill("SIGTERM");
67
+ // Force kill after 5s
68
+ setTimeout(() => {
69
+ if (this.proc.exitCode === null) {
70
+ this.proc.kill("SIGKILL");
71
+ }
72
+ resolve();
73
+ }, 5000);
74
+ });
75
+ }
76
+ handleEvent(event) {
77
+ this.emit("output", event);
78
+ if (event.type === "result") {
79
+ const resultEvent = event;
80
+ // Update session ID from Claude's response
81
+ if (resultEvent.session_id) {
82
+ this.id = resultEvent.session_id;
83
+ }
84
+ this.emit("turn_complete", {
85
+ claudeSessionId: resultEvent.session_id,
86
+ cost: resultEvent.cost_usd,
87
+ duration: resultEvent.duration_ms,
88
+ });
89
+ }
90
+ if (event.type === "system" && event.session_id) {
91
+ this.id = event.session_id;
92
+ }
93
+ }
94
+ }
95
+ //# sourceMappingURL=claude-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-process.js","sourceRoot":"","sources":["../src/claude-process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { ClaudeCodeAdapter } from "./claude-code-adapter.js";
2
+ export { ClaudeProcess } from "./claude-process.js";
3
+ export { StreamParser } from "./stream-parser.js";
4
+ export type { ClaudeStreamEvent, ClaudeAssistantEvent, ClaudeResultEvent, ClaudeSystemEvent, ClaudeContentBlock, } from "./types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { ClaudeCodeAdapter } from "./claude-code-adapter.js";
2
+ export { ClaudeProcess } from "./claude-process.js";
3
+ export { StreamParser } from "./stream-parser.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ClaudeStreamEvent } from "./types.js";
2
+ /**
3
+ * Parses NDJSON (newline-delimited JSON) from Claude CLI stdout.
4
+ *
5
+ * Each line is a complete JSON object. Non-JSON lines (e.g., stderr
6
+ * leaks, empty lines) are silently ignored.
7
+ */
8
+ export declare class StreamParser {
9
+ private buffer;
10
+ private handler;
11
+ private errorHandler?;
12
+ constructor(handler: (event: ClaudeStreamEvent) => void, errorHandler?: (error: Error) => void);
13
+ /** Feed raw data from stdout. May contain partial or multiple lines. */
14
+ feed(chunk: string): void;
15
+ /** Flush any remaining data in the buffer */
16
+ flush(): void;
17
+ }
18
+ //# sourceMappingURL=stream-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-parser.d.ts","sourceRoot":"","sources":["../src/stream-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAAC,CAAyB;gBAG5C,OAAO,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,EAC3C,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;IAMvC,wEAAwE;IACxE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAkBzB,6CAA6C;IAC7C,KAAK,IAAI,IAAI;CAWd"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Parses NDJSON (newline-delimited JSON) from Claude CLI stdout.
3
+ *
4
+ * Each line is a complete JSON object. Non-JSON lines (e.g., stderr
5
+ * leaks, empty lines) are silently ignored.
6
+ */
7
+ export class StreamParser {
8
+ buffer = "";
9
+ handler;
10
+ errorHandler;
11
+ constructor(handler, errorHandler) {
12
+ this.handler = handler;
13
+ this.errorHandler = errorHandler;
14
+ }
15
+ /** Feed raw data from stdout. May contain partial or multiple lines. */
16
+ feed(chunk) {
17
+ this.buffer += chunk;
18
+ const lines = this.buffer.split("\n");
19
+ // Keep last potentially incomplete line in buffer
20
+ this.buffer = lines.pop() ?? "";
21
+ for (const line of lines) {
22
+ const trimmed = line.trim();
23
+ if (!trimmed)
24
+ continue;
25
+ try {
26
+ const event = JSON.parse(trimmed);
27
+ this.handler(event);
28
+ }
29
+ catch {
30
+ // Non-JSON line — skip silently (could be stderr leak or debug output)
31
+ }
32
+ }
33
+ }
34
+ /** Flush any remaining data in the buffer */
35
+ flush() {
36
+ if (this.buffer.trim()) {
37
+ try {
38
+ const event = JSON.parse(this.buffer.trim());
39
+ this.handler(event);
40
+ }
41
+ catch {
42
+ // ignore
43
+ }
44
+ }
45
+ this.buffer = "";
46
+ }
47
+ }
48
+ //# sourceMappingURL=stream-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-parser.js","sourceRoot":"","sources":["../src/stream-parser.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IACf,MAAM,GAAG,EAAE,CAAC;IACZ,OAAO,CAAqC;IAC5C,YAAY,CAA0B;IAE9C,YACE,OAA2C,EAC3C,YAAqC;QAErC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,wEAAwE;IACxE,IAAI,CAAC,KAAa;QAChB,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,kDAAkD;QAClD,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;YACvB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAsB,CAAC;gBACvD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,uEAAuE;YACzE,CAAC;QACH,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,KAAK;QACH,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAsB,CAAC;gBAClE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Claude Code CLI stream-json output types.
3
+ *
4
+ * When spawned with `--output-format stream-json`, Claude CLI emits
5
+ * one JSON object per line on stdout.
6
+ */
7
+ export interface ClaudeContentBlock {
8
+ type: "text" | "tool_use" | "tool_result" | "thinking";
9
+ text?: string;
10
+ id?: string;
11
+ name?: string;
12
+ input?: Record<string, unknown>;
13
+ content?: string;
14
+ }
15
+ export interface ClaudeAssistantEvent {
16
+ type: "assistant";
17
+ message: {
18
+ id: string;
19
+ content: ClaudeContentBlock[];
20
+ model: string;
21
+ stop_reason: string | null;
22
+ usage?: {
23
+ input_tokens: number;
24
+ output_tokens: number;
25
+ };
26
+ };
27
+ session_id?: string;
28
+ }
29
+ export interface ClaudeResultEvent {
30
+ type: "result";
31
+ result: unknown;
32
+ subtype: string;
33
+ session_id: string;
34
+ cost_usd: number;
35
+ duration_ms: number;
36
+ duration_api_ms: number;
37
+ num_turns: number;
38
+ is_error: boolean;
39
+ total_cost_usd?: number;
40
+ }
41
+ export interface ClaudeSystemEvent {
42
+ type: "system";
43
+ subtype: string;
44
+ message: string;
45
+ session_id?: string;
46
+ }
47
+ export type ClaudeStreamEvent = ClaudeAssistantEvent | ClaudeResultEvent | ClaudeSystemEvent;
48
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,CAAC;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,kBAAkB,EAAE,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,KAAK,CAAC,EAAE;YACN,YAAY,EAAE,MAAM,CAAC;YACrB,aAAa,EAAE,MAAM,CAAC;SACvB,CAAC;KACH,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,iBAAiB,GACzB,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Claude Code CLI stream-json output types.
3
+ *
4
+ * When spawned with `--output-format stream-json`, Claude CLI emits
5
+ * one JSON object per line on stdout.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@mclawnet/claude-adapter",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "default": "./dist/index.js"
9
+ }
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "dependencies": {
18
+ "@mclawnet/shared": "0.1.0",
19
+ "@mclawnet/agent": "0.2.1",
20
+ "@mclawnet/logger": "0.1.0"
21
+ },
22
+ "peerDependencies": {
23
+ "@mclawnet/agent": "0.2.1"
24
+ },
25
+ "peerDependenciesMeta": {
26
+ "@mclawnet/agent": {
27
+ "optional": false
28
+ }
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^22",
32
+ "typescript": "^5.8.3",
33
+ "vitest": "^4.0.18"
34
+ },
35
+ "scripts": {
36
+ "build": "tsc",
37
+ "clean": "rm -rf dist"
38
+ }
39
+ }