-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcoding-process.ts
More file actions
138 lines (119 loc) · 4.82 KB
/
Copy pathcoding-process.ts
File metadata and controls
138 lines (119 loc) · 4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* Abstract interface for AI coding assistant processes.
*
* Both ClaudeProcess (Claude Code CLI via stdin/stdout NDJSON) and
* OpenCodeProcess (OpenCode server via HTTP/SSE) implement this interface,
* allowing SessionManager to work with either provider transparently.
*
* The event interface mirrors ClaudeProcessEvents — all providers emit the
* same set of typed events so the session layer and frontend need no
* provider-specific branching for event handling.
*/
import type { EventEmitter } from 'events'
import type { ClaudeProcessEvents } from './claude-process.js'
import type { TaskItem } from './types.js'
/**
* Supported AI coding assistant providers.
* - 'claude': Claude Code CLI (subprocess, NDJSON on stdin/stdout)
* - 'opencode': OpenCode server (HTTP REST + SSE)
* - 'codex': OpenAI Codex CLI (subprocess, `codex app-server` JSON-RPC on stdin/stdout)
*/
export type CodingProvider = 'claude' | 'opencode' | 'codex'
/**
* Capabilities that differ between providers. SessionManager and frontend
* use this to gate features that aren't universally available.
*/
export interface ProviderCapabilities {
/** Provider supports bidirectional streaming (true for both Claude and OpenCode). */
streaming: boolean
/** Provider supports multi-turn conversations within a single process. */
multiTurn: boolean
/** Provider supports programmatic permission control. */
permissionControl: boolean
/** Provider emits tool_active/tool_done events for real-time tool indicators. */
toolEvents: boolean
/** Provider emits thinking/reasoning deltas. */
thinkingDisplay: boolean
/** Provider supports multiple LLM backends (not just Anthropic). */
multiProvider: boolean
/** Provider supports plan mode (read-only agent). */
planMode: boolean
}
/**
* Minimum process interface consumed by SessionManager.
*
* Any provider process must:
* 1. Emit typed events from ClaudeProcessEvents
* 2. Accept user messages via sendMessage()
* 3. Support lifecycle management (start/stop/isAlive)
* 4. Respond to permission requests via sendControlResponse()
*
* ClaudeProcess already satisfies this (it extends EventEmitter<ClaudeProcessEvents>).
* OpenCodeProcess implements it via HTTP/SSE under the hood.
*/
export interface CodingProcess extends EventEmitter<ClaudeProcessEvents> {
/** Start the underlying process or connection. */
start(): void
/** Gracefully stop the process (SIGTERM then SIGKILL, or HTTP disconnect). */
stop(): void
/** Send a user message to the AI assistant. */
sendMessage(content: string): void
/** Write raw protocol data (used for control_response in Claude, no-op in OpenCode). */
sendRaw(data: string): void
/**
* Respond to a permission/control request.
* Claude: writes control_response JSON to stdin ('allow_always' = 'allow').
* OpenCode: POSTs to /permission/:requestId/reply (once/always/reject).
*/
sendControlResponse(requestId: string, behavior: 'allow' | 'deny' | 'allow_always', updatedInput?: Record<string, unknown>, message?: string): void
/**
* Optionally change the permission mode in-place without a restart.
* Resolves true if the provider acknowledged the change. Providers that
* don't support runtime mode changes omit this — callers fall back to restart.
*/
setPermissionMode?(mode: import('./types.js').PermissionMode): Promise<boolean>
/** Seed task/todo state from a previous process's last known list (session restore). */
seedTasks(tasks: TaskItem[]): void
/** Whether the process is currently running and accepting input. */
isAlive(): boolean
/** Whether the process is fully initialized and ready to accept messages immediately. */
isReady(): boolean
/** The provider's internal session ID (used for resume). */
getSessionId(): string
/** Returns a promise that resolves when the process exits. */
waitForExit(timeoutMs?: number): Promise<void>
/** Which provider this process belongs to. */
readonly provider: CodingProvider
/** Provider capability flags. */
readonly capabilities: ProviderCapabilities
}
/** Default capabilities for the Claude Code CLI provider. */
export const CLAUDE_CAPABILITIES: ProviderCapabilities = {
streaming: true,
multiTurn: true,
permissionControl: true,
toolEvents: true,
thinkingDisplay: true,
multiProvider: false,
planMode: true,
}
/** Default capabilities for the OpenCode provider. */
export const OPENCODE_CAPABILITIES: ProviderCapabilities = {
streaming: true,
multiTurn: true,
permissionControl: true,
toolEvents: true,
thinkingDisplay: true,
multiProvider: true,
planMode: true,
}
/** Default capabilities for the OpenAI Codex CLI provider. */
export const CODEX_CAPABILITIES: ProviderCapabilities = {
streaming: true,
multiTurn: true,
permissionControl: true,
toolEvents: true,
thinkingDisplay: true,
multiProvider: false,
planMode: false,
}