@agent-link/agent 0.1.204 → 0.1.207

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,90 @@
1
+ /**
2
+ * ClaudeBackend — adapter implementing AgentBackend over the existing
3
+ * agent/src/claude.ts subprocess driver and agent/src/history.ts JSONL reader.
4
+ *
5
+ * Design (locked decisions, see docs/2026-05-09-pr3-claude-backend.md):
6
+ * - claude.ts is unchanged; this class wraps it.
7
+ * - For Claude, `backendThreadId === backendSessionId` (single-thread sessions).
8
+ * - Emits NormalizedEvents only via on(listener). In PR3 the runtime
9
+ * facade does NOT yet subscribe to these events or translate them back
10
+ * to legacy wire frames — connection.ts still uses the re-exported
11
+ * claude.ts surface directly. PR4 wires the runtime to call
12
+ * getBackend().on(...) and routes outbound traffic through the
13
+ * translation pipeline; the NormalizedEvents emitted here are currently
14
+ * consumed only by the contract tests.
15
+ * - listSessions / readSession / deleteSession / renameSession delegate
16
+ * to history.ts directly.
17
+ *
18
+ * The class subscribes to claude.ts's outbound traffic via the multi-listener
19
+ * `addSendFn` / `addOnSessionStarted` hooks (returning unsubscribe handles
20
+ * stored on the instance). Because these hooks support fanout, multiple
21
+ * ClaudeBackend instances can coexist with the legacy connection.ts
22
+ * subscribers without clobbering each other; shutdown() detaches cleanly.
23
+ */
24
+ import { type AgentBackend, type ApprovalAnswer, type BackendCapabilities, type BackendHistoryMessage, type BackendRestartResult, type BackendSessionInfo, type BackendSessionRef, type EnsureSessionOpts, type EventListener, type RestartOpts, type StartOpts, type UserInputAnswer, type UserTurnInput } from './types.js';
25
+ export declare class ClaudeBackend implements AgentBackend {
26
+ readonly type: "claude";
27
+ readonly capabilities: BackendCapabilities;
28
+ private readonly listeners;
29
+ /** Map from conversationId → most-recent backendSessionId we've observed.
30
+ * Lets us tag events that don't carry a session id (e.g. turn_completed). */
31
+ private readonly convToSession;
32
+ /** Map from placeholder ref id (e.g. 'pending:c1') → conversationId. Used
33
+ * to resolve startTurn() before session_started has populated convToSession. */
34
+ private readonly pendingRefToConv;
35
+ /** Map from conversationId → workDir provided to ensureSession(). Used as a
36
+ * fallback in startTurn() when claude.ts has no live ConversationState yet
37
+ * (e.g. first turn before session_started). */
38
+ private readonly convToWorkDir;
39
+ /** Unsubscribe handles for the multi-subscriber claude.ts hooks. */
40
+ private readonly unsubSend;
41
+ private readonly unsubSessionStarted;
42
+ readonly compact?: undefined;
43
+ readonly fork?: undefined;
44
+ readonly listModels?: undefined;
45
+ readonly renameSession: (workDir: string, session: BackendSessionRef, title: string) => Promise<boolean>;
46
+ readonly deleteSession: (workDir: string, session: BackendSessionRef) => Promise<boolean>;
47
+ constructor(_opts?: StartOpts);
48
+ on(listener: EventListener): () => void;
49
+ private emit;
50
+ start(_opts: StartOpts): Promise<void>;
51
+ shutdown(): Promise<void>;
52
+ ensureSession(opts: EnsureSessionOpts): Promise<BackendSessionRef>;
53
+ startTurn(session: BackendSessionRef, input: UserTurnInput): Promise<void>;
54
+ interruptTurn(session: BackendSessionRef): Promise<void>;
55
+ answerUserInput(answer: UserInputAnswer): void;
56
+ answerApproval(answer: ApprovalAnswer): void;
57
+ setModel(conversationId: string | null, model: string | null): void;
58
+ getEffectiveModel(conversationId?: string): string | null;
59
+ isCompacting(conversationId?: string): boolean;
60
+ hasConversation(conversationId: string): boolean;
61
+ restartSession(conversationId: string, opts?: RestartOpts): BackendRestartResult | null;
62
+ createPlaceholderSession(conversationId: string, _workDir: string, opts?: RestartOpts): void;
63
+ listSessions(workDir: string): Promise<BackendSessionInfo[]>;
64
+ readSession(workDir: string, session: BackendSessionRef): Promise<BackendHistoryMessage[]>;
65
+ /** Reverse-lookup: find the conversationId we associated with a session ref. */
66
+ private findConvId;
67
+ /**
68
+ * Translate a legacy outbound wire frame (as produced by claude.ts via the
69
+ * SendFn closure) into a NormalizedEvent and fan out to listeners.
70
+ *
71
+ * In PR3 the runtime facade does NOT yet perform the reverse translation
72
+ * back to legacy frames — connection.ts still uses the re-exported claude.ts
73
+ * surface directly (see runtime.ts header comment). The NormalizedEvents
74
+ * emitted here are currently consumed only by the contract tests; the raw
75
+ * frame fanout below preserves wire fidelity for when PR4 wires the runtime
76
+ * to translate. The `runtime.test.ts` suite verifies only that runtime.ts
77
+ * re-exports the expected surface, not round-trip correctness.
78
+ *
79
+ * For frames that don't have a NormalizedEvent equivalent (or that the
80
+ * runtime should pass through unchanged), we emit a `process_output`-shaped
81
+ * event carrying the raw frame so the runtime can forward it verbatim.
82
+ */
83
+ private onClaudeSend;
84
+ /**
85
+ * Special-purpose event used internally to ferry untranslated/raw frames
86
+ * through to the runtime facade without losing fidelity. Encoded as a
87
+ * `process_output` NormalizedEvent for now; PR4+ may add a dedicated kind.
88
+ */
89
+ private emitRawFrame;
90
+ }
@@ -0,0 +1,356 @@
1
+ /**
2
+ * ClaudeBackend — adapter implementing AgentBackend over the existing
3
+ * agent/src/claude.ts subprocess driver and agent/src/history.ts JSONL reader.
4
+ *
5
+ * Design (locked decisions, see docs/2026-05-09-pr3-claude-backend.md):
6
+ * - claude.ts is unchanged; this class wraps it.
7
+ * - For Claude, `backendThreadId === backendSessionId` (single-thread sessions).
8
+ * - Emits NormalizedEvents only via on(listener). In PR3 the runtime
9
+ * facade does NOT yet subscribe to these events or translate them back
10
+ * to legacy wire frames — connection.ts still uses the re-exported
11
+ * claude.ts surface directly. PR4 wires the runtime to call
12
+ * getBackend().on(...) and routes outbound traffic through the
13
+ * translation pipeline; the NormalizedEvents emitted here are currently
14
+ * consumed only by the contract tests.
15
+ * - listSessions / readSession / deleteSession / renameSession delegate
16
+ * to history.ts directly.
17
+ *
18
+ * The class subscribes to claude.ts's outbound traffic via the multi-listener
19
+ * `addSendFn` / `addOnSessionStarted` hooks (returning unsubscribe handles
20
+ * stored on the instance). Because these hooks support fanout, multiple
21
+ * ClaudeBackend instances can coexist with the legacy connection.ts
22
+ * subscribers without clobbering each other; shutdown() detaches cleanly.
23
+ */
24
+ import * as claude from '../claude.js';
25
+ import * as history from '../history.js';
26
+ import { claudeCapabilities, } from './types.js';
27
+ /** Internal: wrap a claudeSessionId into a BackendSessionRef. */
28
+ function refFor(sessionId) {
29
+ const id = sessionId ?? '';
30
+ return {
31
+ backendType: 'claude',
32
+ backendSessionId: id,
33
+ backendThreadId: id,
34
+ providerSessionId: id || null,
35
+ };
36
+ }
37
+ export class ClaudeBackend {
38
+ type = 'claude';
39
+ // claudeCapabilities() now reflects this adapter's actual surface (fork &
40
+ // compaction = false, since claude.ts has no programmatic compact API and
41
+ // restartConversation's signature doesn't match AgentBackend.fork). No need
42
+ // to override the capability flags here.
43
+ capabilities = claudeCapabilities();
44
+ listeners = new Set();
45
+ /** Map from conversationId → most-recent backendSessionId we've observed.
46
+ * Lets us tag events that don't carry a session id (e.g. turn_completed). */
47
+ convToSession = new Map();
48
+ /** Map from placeholder ref id (e.g. 'pending:c1') → conversationId. Used
49
+ * to resolve startTurn() before session_started has populated convToSession. */
50
+ pendingRefToConv = new Map();
51
+ /** Map from conversationId → workDir provided to ensureSession(). Used as a
52
+ * fallback in startTurn() when claude.ts has no live ConversationState yet
53
+ * (e.g. first turn before session_started). */
54
+ convToWorkDir = new Map();
55
+ /** Unsubscribe handles for the multi-subscriber claude.ts hooks. */
56
+ unsubSend;
57
+ unsubSessionStarted;
58
+ // Optional methods from AgentBackend — only present if capability declares it.
59
+ compact; // claude.ts has no programmatic compact API
60
+ fork; // restartConversation acts as fork but signature differs
61
+ listModels; // capability says no
62
+ renameSession;
63
+ deleteSession;
64
+ constructor(_opts) {
65
+ // Wire interceptors. claude.ts now supports multi-subscriber fanout; we
66
+ // capture the unsubscribe handles so shutdown() can detach cleanly without
67
+ // racing the legacy connection.ts subscribers.
68
+ this.unsubSend = claude.addSendFn((msg) => this.onClaudeSend(msg));
69
+ this.unsubSessionStarted = claude.addOnSessionStarted((conversationId, claudeSessionId) => {
70
+ if (conversationId) {
71
+ this.convToSession.set(conversationId, claudeSessionId);
72
+ // Keep pendingRefToConv entry alive until shutdown so callers that
73
+ // still hold the original placeholder ref can resolve it later.
74
+ }
75
+ this.emit({ type: 'session_started', session: refFor(claudeSessionId) });
76
+ });
77
+ // Bind capability-gated methods.
78
+ this.renameSession = async (workDir, session, title) => {
79
+ // PR4-D: forward history.renameSession's boolean so AgentRuntime /
80
+ // connection.ts can drive the BRAIN_DATA_DIR fallback + retry on false.
81
+ return history.renameSession(workDir, session.backendSessionId, title);
82
+ };
83
+ this.deleteSession = async (workDir, session) => {
84
+ return history.deleteSession(workDir, session.backendSessionId);
85
+ };
86
+ }
87
+ // ── Event subscription ─────────────────────────────────────────────────
88
+ on(listener) {
89
+ this.listeners.add(listener);
90
+ return () => { this.listeners.delete(listener); };
91
+ }
92
+ emit(event) {
93
+ for (const fn of this.listeners) {
94
+ try {
95
+ fn(event);
96
+ }
97
+ catch (e) {
98
+ console.error('[ClaudeBackend] listener threw', e);
99
+ }
100
+ }
101
+ }
102
+ // ── Lifecycle ──────────────────────────────────────────────────────────
103
+ async start(_opts) {
104
+ // claude.ts has no global start step — process spawn is lazy per-conversation.
105
+ }
106
+ async shutdown() {
107
+ claude.abortAll();
108
+ try {
109
+ this.unsubSend();
110
+ }
111
+ catch { /* ignore */ }
112
+ try {
113
+ this.unsubSessionStarted();
114
+ }
115
+ catch { /* ignore */ }
116
+ this.listeners.clear();
117
+ this.convToSession.clear();
118
+ this.pendingRefToConv.clear();
119
+ this.convToWorkDir.clear();
120
+ }
121
+ // ── Session lifecycle ──────────────────────────────────────────────────
122
+ async ensureSession(opts) {
123
+ // Remember workDir so startTurn() can spawn Claude in the right directory
124
+ // even before claude.ts has a live ConversationState for this conversation.
125
+ if (opts.workDir) {
126
+ this.convToWorkDir.set(opts.conversationId, opts.workDir);
127
+ }
128
+ // Claude's session is established lazily on the first chat message via
129
+ // handleChat → startQuery. We can return a placeholder ref that carries
130
+ // the resumeSessionId if provided; otherwise an empty ref that gets
131
+ // filled in by the session_started event.
132
+ const existing = claude.getConversation(opts.conversationId);
133
+ const sid = opts.resumeSessionId ?? existing?.claudeSessionId ?? existing?.lastClaudeSessionId ?? '';
134
+ if (sid) {
135
+ this.convToSession.set(opts.conversationId, sid);
136
+ return refFor(sid);
137
+ }
138
+ // No real session yet — emit a placeholder ref and remember the mapping
139
+ // so startTurn() can recover the original conversationId from it.
140
+ const placeholder = `pending:${opts.conversationId}`;
141
+ this.pendingRefToConv.set(placeholder, opts.conversationId);
142
+ return refFor(placeholder);
143
+ }
144
+ async startTurn(session, input) {
145
+ // The conversationId is the AgentLink convId; we don't have it on
146
+ // BackendSessionRef directly. For backwards compat we use backendSessionId
147
+ // as the conversationId fallback when the runtime didn't supply a mapping.
148
+ // (The runtime facade will pass a richer call signature in PR3 follow-up;
149
+ // for the contract test the placeholder ref convention is sufficient.)
150
+ const convId = this.findConvId(session) ?? session.backendSessionId;
151
+ // Plumb resumeSessionId when the ref carries a real (non-placeholder) session
152
+ // id and claude.ts has no live ConversationState yet — that's the only
153
+ // scenario where we actually need to ask the CLI to resume. If a live
154
+ // ConversationState already exists, claude.ts will reuse it and the
155
+ // resumeSessionId would be ignored anyway. Placeholder ids ('pending:*')
156
+ // are explicitly excluded so we never pass them to the CLI as a resume target.
157
+ const sid = session.backendSessionId;
158
+ const isPlaceholder = !sid || sid.startsWith('pending:');
159
+ const hasLive = !!claude.getConversation(convId);
160
+ const baseOptions = !isPlaceholder && !hasLive
161
+ ? { resumeSessionId: sid }
162
+ : undefined;
163
+ // Merge per-turn metadata (brainMode, recapId, briefingDate, devops*,
164
+ // projectName, icmId, extraArgs) into HandleChatOptions. The runtime
165
+ // passes these through opaquely; only ClaudeBackend interprets them.
166
+ const meta = input.metadata;
167
+ const options = (baseOptions || meta)
168
+ ? { ...(meta ?? {}), ...(baseOptions ?? {}) }
169
+ : undefined;
170
+ claude.handleChat(convId, input.text,
171
+ // workDir must come from existing conversation state; if absent, claude.ts
172
+ // will throw when it tries to spawn — caller must ensureSession first.
173
+ claude.getConversation(convId)?.workDir ?? this.convToWorkDir.get(convId) ?? process.cwd(), options, input.files);
174
+ this.emit({ type: 'turn_started', session });
175
+ }
176
+ async interruptTurn(session) {
177
+ const convId = this.findConvId(session) ?? session.backendSessionId;
178
+ claude.cancelExecution(convId);
179
+ }
180
+ // ── User input / approval ──────────────────────────────────────────────
181
+ answerUserInput(answer) {
182
+ claude.handleUserAnswer(answer.requestId, answer.answers);
183
+ }
184
+ answerApproval(answer) {
185
+ claude.handleToolPermissionResponse(answer.requestId, answer.decision);
186
+ }
187
+ // ── PR4-C user-action surface (keyed by conversationId) ────────────────
188
+ setModel(conversationId, model) {
189
+ // claude.setModel takes (conversationId | undefined, model). null convId
190
+ // means "global default"; null model means clear/default — claude.setModel
191
+ // expects a string for model, so coerce null to '' (claude.ts treats empty
192
+ // as "no override").
193
+ claude.setModel(conversationId ?? undefined, model ?? '');
194
+ }
195
+ getEffectiveModel(conversationId) {
196
+ return claude.getEffectiveModel(conversationId);
197
+ }
198
+ isCompacting(conversationId) {
199
+ return claude.getIsCompacting(conversationId);
200
+ }
201
+ hasConversation(conversationId) {
202
+ return claude.getConversation(conversationId) != null;
203
+ }
204
+ restartSession(conversationId, opts) {
205
+ // claude.restartConversation returns { claudeSessionId: null, wasTurnActive: false }
206
+ // when there's no live conversation. Map that to null per AgentBackend
207
+ // contract (caller falls back to createPlaceholderSession).
208
+ if (!claude.getConversation(conversationId))
209
+ return null;
210
+ const result = claude.restartConversation(conversationId, opts);
211
+ return {
212
+ claudeSessionId: result.claudeSessionId,
213
+ wasTurnActive: result.wasTurnActive,
214
+ history: result.history,
215
+ };
216
+ }
217
+ createPlaceholderSession(conversationId, _workDir, opts) {
218
+ // Claude ignores workDir — claude.ts:898 sets workDir: '' and the next
219
+ // handleChat overrides it. The param is kept in the AgentBackend API for
220
+ // future backends that need it (e.g. CodexBackend).
221
+ claude.createPlaceholderConversation(conversationId, opts);
222
+ }
223
+ // ── History ────────────────────────────────────────────────────────────
224
+ async listSessions(workDir) {
225
+ const items = history.listSessions(workDir);
226
+ return items.map((s) => ({
227
+ session: refFor(s.sessionId),
228
+ title: s.title,
229
+ customTitle: s.customTitle,
230
+ preview: s.preview,
231
+ lastModified: s.lastModified,
232
+ }));
233
+ }
234
+ async readSession(workDir, session) {
235
+ const msgs = history.readSessionMessages(workDir, session.backendSessionId);
236
+ return msgs;
237
+ }
238
+ // ── Internals ──────────────────────────────────────────────────────────
239
+ /** Reverse-lookup: find the conversationId we associated with a session ref. */
240
+ findConvId(session) {
241
+ const sid = session.backendSessionId;
242
+ if (!sid)
243
+ return null;
244
+ // Placeholder refs (returned by ensureSession before session_started) carry
245
+ // the conversationId in pendingRefToConv. Resolve them first so we don't
246
+ // accidentally pass 'pending:c1' as a conversationId to claude.handleChat.
247
+ if (sid.startsWith('pending:')) {
248
+ return this.pendingRefToConv.get(sid) ?? null;
249
+ }
250
+ for (const [conv, observedSid] of this.convToSession) {
251
+ if (observedSid === sid)
252
+ return conv;
253
+ }
254
+ return null;
255
+ }
256
+ /**
257
+ * Translate a legacy outbound wire frame (as produced by claude.ts via the
258
+ * SendFn closure) into a NormalizedEvent and fan out to listeners.
259
+ *
260
+ * In PR3 the runtime facade does NOT yet perform the reverse translation
261
+ * back to legacy frames — connection.ts still uses the re-exported claude.ts
262
+ * surface directly (see runtime.ts header comment). The NormalizedEvents
263
+ * emitted here are currently consumed only by the contract tests; the raw
264
+ * frame fanout below preserves wire fidelity for when PR4 wires the runtime
265
+ * to translate. The `runtime.test.ts` suite verifies only that runtime.ts
266
+ * re-exports the expected surface, not round-trip correctness.
267
+ *
268
+ * For frames that don't have a NormalizedEvent equivalent (or that the
269
+ * runtime should pass through unchanged), we emit a `process_output`-shaped
270
+ * event carrying the raw frame so the runtime can forward it verbatim.
271
+ */
272
+ onClaudeSend(msg) {
273
+ const t = String(msg.type ?? '');
274
+ const convId = typeof msg.conversationId === 'string' ? msg.conversationId : undefined;
275
+ const sid = (convId && this.convToSession.get(convId)) || '';
276
+ const session = refFor(sid);
277
+ switch (t) {
278
+ case 'session_started':
279
+ // Already emitted via setOnSessionStarted callback; skip to avoid double-fire.
280
+ return;
281
+ case 'turn_completed':
282
+ this.emit({ type: 'turn_completed', session });
283
+ // Also forward the raw frame so the runtime can preserve fields like
284
+ // conversationId / usage that connection.ts expects on the wire.
285
+ this.emitRawFrame(msg);
286
+ return;
287
+ case 'execution_cancelled':
288
+ this.emit({ type: 'turn_cancelled', session });
289
+ this.emitRawFrame(msg);
290
+ return;
291
+ case 'context_compaction': {
292
+ const status = msg.status === 'started' ? 'compact_started' : 'compact_completed';
293
+ this.emit({ type: status, session });
294
+ this.emitRawFrame(msg);
295
+ return;
296
+ }
297
+ case 'ask_user_question': {
298
+ const requestId = String(msg.requestId ?? '');
299
+ const questions = msg.questions ?? [];
300
+ this.emit({
301
+ type: 'user_input_requested',
302
+ session,
303
+ requestId,
304
+ request: {
305
+ source: 'ask_user_question',
306
+ questions: questions.map((q) => ({
307
+ question: String(q.question ?? ''),
308
+ header: q.header ? String(q.header) : undefined,
309
+ options: q.options ?? [],
310
+ multiSelect: Boolean(q.multiSelect),
311
+ })),
312
+ },
313
+ });
314
+ this.emitRawFrame(msg);
315
+ return;
316
+ }
317
+ case 'tool_permission_request': {
318
+ const requestId = String(msg.requestId ?? '');
319
+ const toolName = String(msg.toolName ?? '');
320
+ this.emit({
321
+ type: 'approval_requested',
322
+ session,
323
+ requestId,
324
+ request: { kind: 'tool', toolName, input: msg.input },
325
+ });
326
+ this.emitRawFrame(msg);
327
+ return;
328
+ }
329
+ case 'error':
330
+ this.emit({ type: 'error', session, message: String(msg.message ?? '') });
331
+ this.emitRawFrame(msg);
332
+ return;
333
+ default:
334
+ // Pass-through for everything else (claude_output, plan_mode_changed,
335
+ // permission_mode_changed, btw_answer, etc). The runtime forwards raw.
336
+ this.emitRawFrame(msg);
337
+ return;
338
+ }
339
+ }
340
+ /**
341
+ * Special-purpose event used internally to ferry untranslated/raw frames
342
+ * through to the runtime facade without losing fidelity. Encoded as a
343
+ * `process_output` NormalizedEvent for now; PR4+ may add a dedicated kind.
344
+ */
345
+ emitRawFrame(msg) {
346
+ const convId = typeof msg.conversationId === 'string' ? msg.conversationId : undefined;
347
+ const sid = (convId && this.convToSession.get(convId)) || '';
348
+ this.emit({
349
+ type: 'process_output',
350
+ session: refFor(sid),
351
+ processId: '__raw__',
352
+ chunk: JSON.stringify(msg),
353
+ });
354
+ }
355
+ }
356
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/backends/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Backend factory.
3
+ *
4
+ * `'claude'` is wired to `ClaudeBackend` (a thin adapter over the existing
5
+ * `agent/src/claude.ts` driver). `'codex'` is recognized but not implemented
6
+ * yet (PR4).
7
+ */
8
+ import { type BackendType, type AgentBackend, type StartOpts } from './types.js';
9
+ export * from './types.js';
10
+ export { ClaudeBackend } from './claude.js';
11
+ export declare class UnknownBackendError extends Error {
12
+ constructor(type: string);
13
+ }
14
+ export declare class BackendNotImplementedError extends Error {
15
+ constructor(type: BackendType);
16
+ }
17
+ /**
18
+ * Validate that a string is a known BackendType.
19
+ * Throws UnknownBackendError for unknown values.
20
+ */
21
+ export declare function assertKnownBackendType(type: string): asserts type is BackendType;
22
+ /**
23
+ * Factory entry point. For recognized-but-not-yet-implemented backends
24
+ * (currently: codex), throws BackendNotImplementedError. Throws
25
+ * UnknownBackendError for unknown types.
26
+ */
27
+ export declare function createBackend(type: string, _opts?: StartOpts): AgentBackend;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Backend factory.
3
+ *
4
+ * `'claude'` is wired to `ClaudeBackend` (a thin adapter over the existing
5
+ * `agent/src/claude.ts` driver). `'codex'` is recognized but not implemented
6
+ * yet (PR4).
7
+ */
8
+ import { KNOWN_BACKEND_TYPES } from './types.js';
9
+ import { ClaudeBackend } from './claude.js';
10
+ export * from './types.js';
11
+ export { ClaudeBackend } from './claude.js';
12
+ export class UnknownBackendError extends Error {
13
+ constructor(type) {
14
+ super(`Unknown backend type: "${type}". Known types: ${KNOWN_BACKEND_TYPES.join(', ')}.`);
15
+ this.name = 'UnknownBackendError';
16
+ }
17
+ }
18
+ export class BackendNotImplementedError extends Error {
19
+ constructor(type) {
20
+ super(`Backend "${type}" is recognized but not yet implemented in this version.`);
21
+ this.name = 'BackendNotImplementedError';
22
+ }
23
+ }
24
+ /**
25
+ * Validate that a string is a known BackendType.
26
+ * Throws UnknownBackendError for unknown values.
27
+ */
28
+ export function assertKnownBackendType(type) {
29
+ if (!KNOWN_BACKEND_TYPES.includes(type)) {
30
+ throw new UnknownBackendError(type);
31
+ }
32
+ }
33
+ /**
34
+ * Factory entry point. For recognized-but-not-yet-implemented backends
35
+ * (currently: codex), throws BackendNotImplementedError. Throws
36
+ * UnknownBackendError for unknown types.
37
+ */
38
+ export function createBackend(type, _opts) {
39
+ assertKnownBackendType(type);
40
+ switch (type) {
41
+ case 'claude':
42
+ return new ClaudeBackend(_opts);
43
+ case 'codex':
44
+ throw new BackendNotImplementedError('codex');
45
+ default: {
46
+ // exhaustiveness guard
47
+ const _exhaustive = type;
48
+ throw new UnknownBackendError(_exhaustive);
49
+ }
50
+ }
51
+ }
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAuD,MAAM,YAAY,CAAC;AACtG,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,IAAY;QACtB,KAAK,CACH,0BAA0B,IAAI,mBAAmB,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACnF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,YAAY,IAAiB;QAC3B,KAAK,CACH,YAAY,IAAI,0DAA0D,CAC3E,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,IAAI,CAAE,mBAAyC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAiB;IAC3D,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC7B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,OAAO;YACV,MAAM,IAAI,0BAA0B,CAAC,OAAO,CAAC,CAAC;QAChD,OAAO,CAAC,CAAC,CAAC;YACR,uBAAuB;YACvB,MAAM,WAAW,GAAU,IAAI,CAAC;YAChC,MAAM,IAAI,mBAAmB,CAAC,WAAW,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;AACH,CAAC"}