linkshell-cli 0.2.93 → 0.2.95

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,314 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createInterface } from "node:readline";
3
+ import { homedir } from "node:os";
4
+ import { readdirSync, existsSync } from "node:fs";
5
+ import { join, resolve } from "node:path";
6
+ // Hash a directory path the same way Claude Code does for project storage
7
+ function projectHash(cwd) {
8
+ return ("-" +
9
+ resolve(cwd)
10
+ .replace(/\/$/, "")
11
+ .replace(/\//g, "-"));
12
+ }
13
+ function id(prefix) {
14
+ return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
15
+ }
16
+ export class ClaudeStreamJsonClient {
17
+ input;
18
+ child;
19
+ claudeSessionId;
20
+ pendingCancel = false;
21
+ constructor(input) {
22
+ this.input = input;
23
+ }
24
+ async initialize() {
25
+ // No persistent process to start — we'll capture session on first prompt.
26
+ // But we can verify the binary exists by running a quick --help.
27
+ try {
28
+ const { execSync } = await import("node:child_process");
29
+ execSync("claude --version", { stdio: "ignore", timeout: 5000 });
30
+ }
31
+ catch {
32
+ throw new Error("Claude Code CLI not found or not executable");
33
+ }
34
+ return { status: "ok" };
35
+ }
36
+ async newSession(input) {
37
+ // Start a dry-run prompt to get a session_id, then cancel.
38
+ // Actually, we just store that there's no session yet — the real session
39
+ // will be created on the first prompt() call.
40
+ this.claudeSessionId = undefined;
41
+ return { sessionId: undefined, status: "ready" };
42
+ }
43
+ async loadSession(input) {
44
+ this.claudeSessionId = input.sessionId;
45
+ return { sessionId: input.sessionId, status: "loaded" };
46
+ }
47
+ async prompt(input) {
48
+ if (this.child) {
49
+ this.stop();
50
+ }
51
+ this.pendingCancel = false;
52
+ // Build Claude args
53
+ const args = [
54
+ "--print",
55
+ "--output-format", "stream-json",
56
+ "--input-format", "stream-json",
57
+ "--verbose",
58
+ "--permission-mode", "bypassPermissions",
59
+ ];
60
+ // Use stored session for --resume (only when we have a real session ID from system.init)
61
+ if (this.claudeSessionId) {
62
+ args.push("--resume", this.claudeSessionId);
63
+ }
64
+ // Prevent autonomous multi-turn tool loops in headless mode
65
+ args.push("--max-turns", "1");
66
+ if (input.model) {
67
+ args.push("--model", input.model);
68
+ }
69
+ // Build the user message
70
+ const contentBlocks = input.content.map((block) => {
71
+ if (block.type === "image" && block.data) {
72
+ return { type: "image", source: { type: "base64", media_type: block.mimeType ?? "image/png", data: block.data } };
73
+ }
74
+ return { type: "text", text: block.text ?? "" };
75
+ });
76
+ const userMessage = {
77
+ type: "user",
78
+ message: {
79
+ role: "user",
80
+ content: contentBlocks,
81
+ },
82
+ };
83
+ return new Promise((resolve, reject) => {
84
+ const cwd = input.cwd ?? this.input.cwd;
85
+ const child = spawn("claude", args, {
86
+ cwd,
87
+ env: process.env,
88
+ stdio: ["pipe", "pipe", "pipe"],
89
+ });
90
+ this.child = child;
91
+ let settled = false;
92
+ const finish = (err, result) => {
93
+ if (settled)
94
+ return;
95
+ settled = true;
96
+ // Only clear reference if this child is still the active one
97
+ if (this.child === child) {
98
+ this.child = undefined;
99
+ }
100
+ if (err) {
101
+ // Don't call onExit for per-prompt failures — the client can still accept new prompts.
102
+ // onExit is reserved for fatal errors (e.g. binary not found in initialize()).
103
+ reject(err);
104
+ }
105
+ else {
106
+ resolve(result);
107
+ }
108
+ };
109
+ // Send the prompt
110
+ try {
111
+ child.stdin.write(JSON.stringify(userMessage) + "\n");
112
+ child.stdin.end();
113
+ }
114
+ catch (err) {
115
+ child.kill("SIGTERM");
116
+ finish(err instanceof Error ? err : new Error(String(err)), undefined);
117
+ return child;
118
+ }
119
+ // Read stdout line by line (stream-json is newline-delimited)
120
+ const rl = createInterface({ input: child.stdout, crlfDelay: Infinity });
121
+ let currentToolId;
122
+ let currentToolName;
123
+ rl.on("line", (line) => {
124
+ if (this.pendingCancel) {
125
+ child.kill("SIGTERM");
126
+ return;
127
+ }
128
+ let event;
129
+ try {
130
+ event = JSON.parse(line);
131
+ }
132
+ catch {
133
+ return; // skip unparseable lines
134
+ }
135
+ switch (event.type) {
136
+ case "system": {
137
+ if (event.subtype === "init") {
138
+ // Capture session ID
139
+ if (event.session_id) {
140
+ this.claudeSessionId = event.session_id;
141
+ }
142
+ // Emit thread/started so workspace/session proxies update their agentSessionId
143
+ this.input.onNotification("thread/started", {
144
+ sessionId: event.session_id,
145
+ threadId: event.session_id,
146
+ });
147
+ // Also send initialized with full metadata
148
+ const initParams = {
149
+ sessionId: event.session_id,
150
+ threadId: event.session_id,
151
+ cwd: event.cwd ?? cwd,
152
+ model: event.model,
153
+ };
154
+ if (event.tools)
155
+ initParams.tools = event.tools;
156
+ if (event.mcp_servers)
157
+ initParams.mcpServers = event.mcp_servers;
158
+ this.input.onNotification("initialized", initParams);
159
+ }
160
+ // Hook events and other system messages are informational, skip
161
+ break;
162
+ }
163
+ case "assistant": {
164
+ const message = event.message;
165
+ if (!message)
166
+ break;
167
+ const content = (message.content ?? []);
168
+ for (const block of content) {
169
+ switch (block.type) {
170
+ case "thinking":
171
+ this.input.onNotification("item/started", {
172
+ sessionId: this.claudeSessionId,
173
+ item: {
174
+ id: event.uuid ?? id("thinking"),
175
+ type: "thinking",
176
+ text: block.thinking,
177
+ status: "completed",
178
+ },
179
+ });
180
+ break;
181
+ case "text":
182
+ this.input.onNotification("item/agentMessage/delta", {
183
+ sessionId: this.claudeSessionId,
184
+ itemId: message.id ?? event.uuid ?? id("msg"),
185
+ delta: block.text,
186
+ });
187
+ break;
188
+ case "tool_use": {
189
+ currentToolId = block.id;
190
+ currentToolName = block.name ?? "tool";
191
+ const toolName = block.name ?? "tool";
192
+ this.input.onNotification("item/started", {
193
+ sessionId: this.claudeSessionId,
194
+ item: {
195
+ id: block.id ?? id("tool"),
196
+ type: toolName === "Bash" ? "commandExecution" : toolName === "Write" || toolName === "Edit" ? "fileChange" : "toolCall",
197
+ toolName: block.name,
198
+ tool: block.name,
199
+ input: block.input,
200
+ command: block.input?.command,
201
+ cwd: block.input?.cwd ?? cwd,
202
+ status: "running",
203
+ },
204
+ });
205
+ break;
206
+ }
207
+ case "tool_result":
208
+ // tool_result comes in user messages, not assistant
209
+ break;
210
+ }
211
+ }
212
+ break;
213
+ }
214
+ case "user": {
215
+ // User messages in stream-json contain tool results
216
+ const message = event.message;
217
+ if (!message)
218
+ break;
219
+ const content = (message.content ?? []);
220
+ for (const block of content) {
221
+ if (block.type === "tool_result") {
222
+ const toolId = block.tool_use_id ?? currentToolId;
223
+ const isError = block.is_error === true;
224
+ this.input.onNotification("item/completed", {
225
+ sessionId: this.claudeSessionId,
226
+ item: {
227
+ id: toolId ?? id("tool"),
228
+ type: "toolCall",
229
+ toolName: currentToolName,
230
+ tool: currentToolName,
231
+ status: isError ? "failed" : "completed",
232
+ output: typeof block.content === "string" ? block.content : JSON.stringify(block.content),
233
+ aggregatedOutput: typeof block.content === "string" ? block.content : undefined,
234
+ isError,
235
+ },
236
+ });
237
+ }
238
+ }
239
+ break;
240
+ }
241
+ case "result": {
242
+ // Turn complete
243
+ const isError = event.subtype === "error" || event.is_error === true;
244
+ this.input.onNotification("turn/completed", {
245
+ sessionId: this.claudeSessionId,
246
+ stopReason: event.stop_reason ?? (isError ? "error" : "end_turn"),
247
+ durationMs: event.duration_ms,
248
+ totalCostUsd: event.total_cost_usd,
249
+ usage: event.usage,
250
+ isError,
251
+ });
252
+ finish(null, { sessionId: this.claudeSessionId, status: isError ? "error" : "completed" });
253
+ break;
254
+ }
255
+ }
256
+ });
257
+ child.stderr.on("data", (chunk) => {
258
+ const trimmed = chunk.toString().trim();
259
+ if (trimmed)
260
+ process.stderr.write(`[claude:stderr] ${trimmed}\n`);
261
+ });
262
+ child.on("error", (err) => {
263
+ finish(err, undefined);
264
+ });
265
+ child.on("exit", (code, signal) => {
266
+ if (!settled) {
267
+ finish(new Error(`Claude exited unexpectedly (code=${code ?? "null"}, signal=${signal ?? "null"})`), undefined);
268
+ }
269
+ });
270
+ });
271
+ }
272
+ cancel(input) {
273
+ this.pendingCancel = true;
274
+ if (this.child && !this.child.killed) {
275
+ this.child.kill("SIGTERM");
276
+ }
277
+ this.child = undefined;
278
+ }
279
+ respondPermission(input) {
280
+ // In bypassPermissions mode, permission requests don't occur.
281
+ // If we later switch to hook-based permissions, we'd send the response via a hook.
282
+ }
283
+ async listSessions() {
284
+ const home = homedir();
285
+ const projectDir = join(home, ".claude", "projects", projectHash(this.input.cwd));
286
+ if (!existsSync(projectDir)) {
287
+ return { sessions: [] };
288
+ }
289
+ const sessions = [];
290
+ try {
291
+ for (const entry of readdirSync(projectDir)) {
292
+ if (entry.endsWith(".jsonl")) {
293
+ const sessionId = entry.replace(".jsonl", "");
294
+ sessions.push({
295
+ id: sessionId,
296
+ cwd: this.input.cwd,
297
+ lastModified: 0, // would need fs.statSync for accurate time
298
+ });
299
+ }
300
+ }
301
+ }
302
+ catch {
303
+ // directory read failed
304
+ }
305
+ return { sessions };
306
+ }
307
+ stop() {
308
+ if (this.child && !this.child.killed) {
309
+ this.child.kill("SIGTERM");
310
+ }
311
+ this.child = undefined;
312
+ }
313
+ }
314
+ //# sourceMappingURL=claude-stream-json-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-stream-json-client.js","sourceRoot":"","sources":["../../../../../src/runtime/acp/claude-stream-json-client.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export type AgentProvider = "codex" | "claude" | "custom";
2
- export type AgentProtocol = "acp" | "codex-app-server";
2
+ export type AgentProtocol = "acp" | "codex-app-server" | "claude-stream-json";
3
3
  export type AgentFraming = "content-length" | "newline";
4
4
  export interface AgentCommandConfig {
5
5
  command: string;
@@ -23,9 +23,9 @@ export function resolveAgentCommand(input) {
23
23
  if (input.provider === "claude") {
24
24
  return {
25
25
  provider: "claude",
26
- command: "claude --acp",
27
- protocol: "acp",
28
- framing: "content-length",
26
+ command: "claude --print --output-format stream-json --input-format stream-json --verbose --permission-mode bypassPermissions",
27
+ protocol: "claude-stream-json",
28
+ framing: "newline",
29
29
  };
30
30
  }
31
31
  // custom: caller must provide --agent-command
@@ -66,37 +66,12 @@ function resolveBinary(bin) {
66
66
  }
67
67
  return null;
68
68
  }
69
- function supportsAcpFlag(bin) {
70
- try {
71
- const result = execSync(`${bin} --acp 2>&1 || true`, {
72
- encoding: "utf8",
73
- stdio: ["ignore", "pipe", "pipe"],
74
- timeout: 5000,
75
- });
76
- // If stderr contains "unknown option", this version doesn't support --acp
77
- return !result.includes("unknown option");
78
- }
79
- catch {
80
- // Timeout or other error — assume not supported
81
- return false;
82
- }
83
- }
84
69
  export function detectAvailableProviders() {
85
70
  const available = [];
86
- const claudeBin = resolveBinary("claude");
87
- if (claudeBin) {
88
- if (supportsAcpFlag(claudeBin)) {
89
- available.push("claude");
90
- }
91
- else {
92
- process.stderr.write(`[provider] Claude Code detected but --acp flag not supported (version too old?)\n`);
93
- }
94
- }
71
+ if (resolveBinary("claude"))
72
+ available.push("claude");
95
73
  if (resolveBinary("codex"))
96
74
  available.push("codex");
97
- if (available.length === 0) {
98
- process.stderr.write(`[provider] no agent providers detected\n`);
99
- }
100
75
  return available;
101
76
  }
102
77
  //# sourceMappingURL=provider-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-resolver.js","sourceRoot":"","sources":["../../../../../src/runtime/acp/provider-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider-resolver.js","sourceRoot":"","sources":["../../../../../src/runtime/acp/provider-resolver.ts"],"names":[],"mappings":"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"}