linkshell-cli 0.3.14 → 0.3.16

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 (28) hide show
  1. package/dist/cli/src/index.js +0 -0
  2. package/dist/cli/src/runtime/acp/agent-workspace.d.ts +4 -0
  3. package/dist/cli/src/runtime/acp/agent-workspace.js +65 -7
  4. package/dist/cli/src/runtime/acp/agent-workspace.js.map +1 -1
  5. package/dist/cli/src/runtime/acp/claude-sdk-client.d.ts +1 -0
  6. package/dist/cli/src/runtime/acp/claude-sdk-client.js +45 -7
  7. package/dist/cli/src/runtime/acp/claude-sdk-client.js.map +1 -1
  8. package/dist/cli/src/runtime/acp/claude-stream-json-client.js +22 -2
  9. package/dist/cli/src/runtime/acp/claude-stream-json-client.js.map +1 -1
  10. package/dist/cli/src/runtime/acp/codex-rpc-bridge.d.ts +16 -0
  11. package/dist/cli/src/runtime/acp/codex-rpc-bridge.js +53 -0
  12. package/dist/cli/src/runtime/acp/codex-rpc-bridge.js.map +1 -0
  13. package/dist/cli/src/runtime/acp/json-rpc.d.ts +25 -1
  14. package/dist/cli/src/runtime/acp/json-rpc.js +9 -1
  15. package/dist/cli/src/runtime/acp/json-rpc.js.map +1 -1
  16. package/dist/cli/src/runtime/bridge-session.js +25 -0
  17. package/dist/cli/src/runtime/bridge-session.js.map +1 -1
  18. package/dist/cli/tsconfig.tsbuildinfo +1 -1
  19. package/dist/shared-protocol/src/index.d.ts +939 -459
  20. package/dist/shared-protocol/src/index.js +56 -0
  21. package/dist/shared-protocol/src/index.js.map +1 -1
  22. package/package.json +13 -13
  23. package/src/runtime/acp/agent-workspace.ts +66 -7
  24. package/src/runtime/acp/claude-sdk-client.ts +50 -7
  25. package/src/runtime/acp/claude-stream-json-client.ts +25 -2
  26. package/src/runtime/acp/codex-rpc-bridge.ts +70 -0
  27. package/src/runtime/acp/json-rpc.ts +13 -4
  28. package/src/runtime/bridge-session.ts +27 -0
@@ -0,0 +1,70 @@
1
+ import { createEnvelope } from "@linkshell/protocol";
2
+ import type { Envelope } from "@linkshell/protocol";
3
+ import { JsonRpcStdioTransport, type JsonRpcMessage } from "./json-rpc.js";
4
+ import { resolveAgentCommand } from "./provider-resolver.js";
5
+
6
+ export class CodexRpcBridge {
7
+ private transport: JsonRpcStdioTransport | undefined;
8
+
9
+ constructor(
10
+ private readonly input: {
11
+ command?: string;
12
+ cwd: string;
13
+ hostDeviceId: string;
14
+ send: (envelope: Envelope) => void;
15
+ verbose?: boolean;
16
+ },
17
+ ) {}
18
+
19
+ send(message: unknown): void {
20
+ this.ensureTransport();
21
+ this.transport?.send(message as JsonRpcMessage);
22
+ }
23
+
24
+ stop(): void {
25
+ this.transport?.stop();
26
+ this.transport = undefined;
27
+ }
28
+
29
+ private ensureTransport(): void {
30
+ if (this.transport) return;
31
+ const config = resolveAgentCommand({
32
+ provider: "codex",
33
+ command: this.input.command,
34
+ });
35
+ if (!config || config.protocol !== "codex-app-server") {
36
+ throw new Error("Codex app-server command is unavailable.");
37
+ }
38
+ this.transport = new JsonRpcStdioTransport(
39
+ config.command,
40
+ config.framing,
41
+ () => {},
42
+ () => ({}),
43
+ (message) => this.emitError(message),
44
+ (message) => {
45
+ this.input.send(createEnvelope({
46
+ type: "agent.codex.rpc",
47
+ hostDeviceId: this.input.hostDeviceId,
48
+ payload: message,
49
+ }));
50
+ return true;
51
+ },
52
+ );
53
+ this.transport.start(this.input.cwd);
54
+ if (this.input.verbose) {
55
+ process.stderr.write(`[agent:codex-rpc] started ${config.command}\n`);
56
+ }
57
+ }
58
+
59
+ private emitError(message: string): void {
60
+ this.input.send(createEnvelope({
61
+ type: "agent.codex.rpc",
62
+ hostDeviceId: this.input.hostDeviceId,
63
+ payload: {
64
+ jsonrpc: "2.0",
65
+ id: "linkshell-codex-rpc-error",
66
+ error: { code: -32000, message },
67
+ },
68
+ }));
69
+ }
70
+ }
@@ -1,27 +1,27 @@
1
1
  import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
2
2
  import type { AgentFraming } from "./provider-resolver.js";
3
3
 
4
- interface JsonRpcRequest {
4
+ export interface JsonRpcRequest {
5
5
  jsonrpc: "2.0";
6
6
  id: number | string;
7
7
  method: string;
8
8
  params?: unknown;
9
9
  }
10
10
 
11
- interface JsonRpcResponse {
11
+ export interface JsonRpcResponse {
12
12
  jsonrpc: "2.0";
13
13
  id: number | string;
14
14
  result?: unknown;
15
15
  error?: { code: number; message: string; data?: unknown };
16
16
  }
17
17
 
18
- interface JsonRpcNotification {
18
+ export interface JsonRpcNotification {
19
19
  jsonrpc: "2.0";
20
20
  method: string;
21
21
  params?: unknown;
22
22
  }
23
23
 
24
- type JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;
24
+ export type JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;
25
25
 
26
26
  export class JsonRpcStdioTransport {
27
27
  private child: ChildProcessWithoutNullStreams | undefined;
@@ -42,6 +42,7 @@ export class JsonRpcStdioTransport {
42
42
  private readonly onNotification: (method: string, params: unknown) => void,
43
43
  private readonly onRequest: (method: string, params: unknown) => Promise<unknown> | unknown,
44
44
  private readonly onExit: (message: string) => void,
45
+ private readonly onMessage?: (message: JsonRpcMessage) => boolean | void,
45
46
  ) {}
46
47
 
47
48
  start(cwd: string): void {
@@ -87,6 +88,10 @@ export class JsonRpcStdioTransport {
87
88
  this.write({ jsonrpc: "2.0", method, params });
88
89
  }
89
90
 
91
+ send(message: JsonRpcMessage): void {
92
+ this.write(message);
93
+ }
94
+
90
95
  stop(): void {
91
96
  const child = this.child;
92
97
  this.child = undefined;
@@ -136,6 +141,10 @@ export class JsonRpcStdioTransport {
136
141
  return;
137
142
  }
138
143
 
144
+ if (this.onMessage?.(message)) {
145
+ return;
146
+ }
147
+
139
148
  if ("id" in message && ("result" in message || "error" in message)) {
140
149
  const pending = this.pending.get(message.id);
141
150
  if (!pending) return;
@@ -603,6 +603,33 @@ export class BridgeSession {
603
603
  this.screenShare?.handleIceCandidate(p.candidate, p.sdpMid, p.sdpMLineIndex);
604
604
  break;
605
605
  }
606
+ case "agent.codex.rpc": {
607
+ if (!this.agentWorkspace) {
608
+ const payload = parseTypedPayload("agent.codex.rpc", envelope.payload);
609
+ const idValue = payload && typeof payload === "object" && "id" in payload
610
+ ? (payload as { id?: unknown }).id
611
+ : undefined;
612
+ if (typeof idValue === "string" || typeof idValue === "number") {
613
+ this.send(
614
+ createEnvelope({
615
+ type: "agent.codex.rpc",
616
+ hostDeviceId: this.sessionId,
617
+ payload: {
618
+ jsonrpc: "2.0",
619
+ id: idValue,
620
+ error: {
621
+ code: -32000,
622
+ message: "Codex RPC is not enabled. Start CLI with --agent-ui.",
623
+ },
624
+ },
625
+ }),
626
+ );
627
+ }
628
+ break;
629
+ }
630
+ await this.agentWorkspace.handleEnvelope(envelope);
631
+ break;
632
+ }
606
633
  case "agent.v2.capabilities.request":
607
634
  case "agent.v2.conversation.open":
608
635
  case "agent.v2.conversation.list":