feique 1.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.
Files changed (227) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +220 -0
  3. package/README.md +265 -0
  4. package/dist/backend/claude.d.ts +36 -0
  5. package/dist/backend/claude.js +358 -0
  6. package/dist/backend/claude.js.map +1 -0
  7. package/dist/backend/codex.d.ts +31 -0
  8. package/dist/backend/codex.js +100 -0
  9. package/dist/backend/codex.js.map +1 -0
  10. package/dist/backend/factory.d.ts +9 -0
  11. package/dist/backend/factory.js +56 -0
  12. package/dist/backend/factory.js.map +1 -0
  13. package/dist/backend/types.d.ts +54 -0
  14. package/dist/backend/types.js +2 -0
  15. package/dist/backend/types.js.map +1 -0
  16. package/dist/bridge/commands.d.ts +135 -0
  17. package/dist/bridge/commands.js +860 -0
  18. package/dist/bridge/commands.js.map +1 -0
  19. package/dist/bridge/service.d.ts +160 -0
  20. package/dist/bridge/service.js +3785 -0
  21. package/dist/bridge/service.js.map +1 -0
  22. package/dist/bridge/task-queue.d.ts +14 -0
  23. package/dist/bridge/task-queue.js +81 -0
  24. package/dist/bridge/task-queue.js.map +1 -0
  25. package/dist/bridge/types.d.ts +39 -0
  26. package/dist/bridge/types.js +2 -0
  27. package/dist/bridge/types.js.map +1 -0
  28. package/dist/cli.d.ts +2 -0
  29. package/dist/cli.js +1199 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/codex/capabilities.d.ts +20 -0
  32. package/dist/codex/capabilities.js +41 -0
  33. package/dist/codex/capabilities.js.map +1 -0
  34. package/dist/codex/runner.d.ts +47 -0
  35. package/dist/codex/runner.js +294 -0
  36. package/dist/codex/runner.js.map +1 -0
  37. package/dist/codex/session-index.d.ts +22 -0
  38. package/dist/codex/session-index.js +205 -0
  39. package/dist/codex/session-index.js.map +1 -0
  40. package/dist/collaboration/awareness.d.ts +36 -0
  41. package/dist/collaboration/awareness.js +107 -0
  42. package/dist/collaboration/awareness.js.map +1 -0
  43. package/dist/collaboration/digest.d.ts +65 -0
  44. package/dist/collaboration/digest.js +178 -0
  45. package/dist/collaboration/digest.js.map +1 -0
  46. package/dist/collaboration/handoff.d.ts +66 -0
  47. package/dist/collaboration/handoff.js +94 -0
  48. package/dist/collaboration/handoff.js.map +1 -0
  49. package/dist/collaboration/insights.d.ts +24 -0
  50. package/dist/collaboration/insights.js +243 -0
  51. package/dist/collaboration/insights.js.map +1 -0
  52. package/dist/collaboration/knowledge.d.ts +26 -0
  53. package/dist/collaboration/knowledge.js +105 -0
  54. package/dist/collaboration/knowledge.js.map +1 -0
  55. package/dist/collaboration/timeline.d.ts +31 -0
  56. package/dist/collaboration/timeline.js +150 -0
  57. package/dist/collaboration/timeline.js.map +1 -0
  58. package/dist/collaboration/trust.d.ts +49 -0
  59. package/dist/collaboration/trust.js +176 -0
  60. package/dist/collaboration/trust.js.map +1 -0
  61. package/dist/config/codex-skill.d.ts +7 -0
  62. package/dist/config/codex-skill.js +44 -0
  63. package/dist/config/codex-skill.js.map +1 -0
  64. package/dist/config/doctor.d.ts +12 -0
  65. package/dist/config/doctor.js +314 -0
  66. package/dist/config/doctor.js.map +1 -0
  67. package/dist/config/init.d.ts +3 -0
  68. package/dist/config/init.js +123 -0
  69. package/dist/config/init.js.map +1 -0
  70. package/dist/config/load.d.ts +33 -0
  71. package/dist/config/load.js +252 -0
  72. package/dist/config/load.js.map +1 -0
  73. package/dist/config/mutate.d.ts +21 -0
  74. package/dist/config/mutate.js +86 -0
  75. package/dist/config/mutate.js.map +1 -0
  76. package/dist/config/paths.d.ts +3 -0
  77. package/dist/config/paths.js +33 -0
  78. package/dist/config/paths.js.map +1 -0
  79. package/dist/config/schema.d.ts +308 -0
  80. package/dist/config/schema.js +250 -0
  81. package/dist/config/schema.js.map +1 -0
  82. package/dist/control-plane/project-session.d.ts +67 -0
  83. package/dist/control-plane/project-session.js +234 -0
  84. package/dist/control-plane/project-session.js.map +1 -0
  85. package/dist/feishu/base.d.ts +19 -0
  86. package/dist/feishu/base.js +93 -0
  87. package/dist/feishu/base.js.map +1 -0
  88. package/dist/feishu/cards.d.ts +22 -0
  89. package/dist/feishu/cards.js +144 -0
  90. package/dist/feishu/cards.js.map +1 -0
  91. package/dist/feishu/client.d.ts +61 -0
  92. package/dist/feishu/client.js +315 -0
  93. package/dist/feishu/client.js.map +1 -0
  94. package/dist/feishu/diagnostics.d.ts +42 -0
  95. package/dist/feishu/diagnostics.js +194 -0
  96. package/dist/feishu/diagnostics.js.map +1 -0
  97. package/dist/feishu/doc.d.ts +13 -0
  98. package/dist/feishu/doc.js +59 -0
  99. package/dist/feishu/doc.js.map +1 -0
  100. package/dist/feishu/extractors.d.ts +7 -0
  101. package/dist/feishu/extractors.js +215 -0
  102. package/dist/feishu/extractors.js.map +1 -0
  103. package/dist/feishu/long-connection.d.ts +12 -0
  104. package/dist/feishu/long-connection.js +41 -0
  105. package/dist/feishu/long-connection.js.map +1 -0
  106. package/dist/feishu/message-resource.d.ts +14 -0
  107. package/dist/feishu/message-resource.js +309 -0
  108. package/dist/feishu/message-resource.js.map +1 -0
  109. package/dist/feishu/replay.d.ts +37 -0
  110. package/dist/feishu/replay.js +114 -0
  111. package/dist/feishu/replay.js.map +1 -0
  112. package/dist/feishu/task.d.ts +18 -0
  113. package/dist/feishu/task.js +86 -0
  114. package/dist/feishu/task.js.map +1 -0
  115. package/dist/feishu/text.d.ts +23 -0
  116. package/dist/feishu/text.js +155 -0
  117. package/dist/feishu/text.js.map +1 -0
  118. package/dist/feishu/webhook.d.ts +23 -0
  119. package/dist/feishu/webhook.js +130 -0
  120. package/dist/feishu/webhook.js.map +1 -0
  121. package/dist/feishu/wiki.d.ts +52 -0
  122. package/dist/feishu/wiki.js +300 -0
  123. package/dist/feishu/wiki.js.map +1 -0
  124. package/dist/index.d.ts +9 -0
  125. package/dist/index.js +9 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/knowledge/search.d.ts +11 -0
  128. package/dist/knowledge/search.js +83 -0
  129. package/dist/knowledge/search.js.map +1 -0
  130. package/dist/logging.d.ts +3 -0
  131. package/dist/logging.js +40 -0
  132. package/dist/logging.js.map +1 -0
  133. package/dist/mcp/server.d.ts +34 -0
  134. package/dist/mcp/server.js +1196 -0
  135. package/dist/mcp/server.js.map +1 -0
  136. package/dist/memory/embedding-factory.d.ts +6 -0
  137. package/dist/memory/embedding-factory.js +20 -0
  138. package/dist/memory/embedding-factory.js.map +1 -0
  139. package/dist/memory/embeddings.d.ts +40 -0
  140. package/dist/memory/embeddings.js +150 -0
  141. package/dist/memory/embeddings.js.map +1 -0
  142. package/dist/memory/ollama-embeddings.d.ts +63 -0
  143. package/dist/memory/ollama-embeddings.js +215 -0
  144. package/dist/memory/ollama-embeddings.js.map +1 -0
  145. package/dist/memory/retrieve.d.ts +17 -0
  146. package/dist/memory/retrieve.js +29 -0
  147. package/dist/memory/retrieve.js.map +1 -0
  148. package/dist/memory/summarize.d.ts +13 -0
  149. package/dist/memory/summarize.js +58 -0
  150. package/dist/memory/summarize.js.map +1 -0
  151. package/dist/observability/cost.d.ts +12 -0
  152. package/dist/observability/cost.js +22 -0
  153. package/dist/observability/cost.js.map +1 -0
  154. package/dist/observability/dashboard-html.d.ts +5 -0
  155. package/dist/observability/dashboard-html.js +304 -0
  156. package/dist/observability/dashboard-html.js.map +1 -0
  157. package/dist/observability/metrics.d.ts +36 -0
  158. package/dist/observability/metrics.js +230 -0
  159. package/dist/observability/metrics.js.map +1 -0
  160. package/dist/observability/readiness.d.ts +31 -0
  161. package/dist/observability/readiness.js +57 -0
  162. package/dist/observability/readiness.js.map +1 -0
  163. package/dist/observability/server.d.ts +84 -0
  164. package/dist/observability/server.js +181 -0
  165. package/dist/observability/server.js.map +1 -0
  166. package/dist/projects/paths.d.ts +9 -0
  167. package/dist/projects/paths.js +30 -0
  168. package/dist/projects/paths.js.map +1 -0
  169. package/dist/runtime/instance-lock.d.ts +12 -0
  170. package/dist/runtime/instance-lock.js +99 -0
  171. package/dist/runtime/instance-lock.js.map +1 -0
  172. package/dist/runtime/process.d.ts +2 -0
  173. package/dist/runtime/process.js +43 -0
  174. package/dist/runtime/process.js.map +1 -0
  175. package/dist/runtime/shutdown.d.ts +11 -0
  176. package/dist/runtime/shutdown.js +38 -0
  177. package/dist/runtime/shutdown.js.map +1 -0
  178. package/dist/security/access.d.ts +13 -0
  179. package/dist/security/access.js +160 -0
  180. package/dist/security/access.js.map +1 -0
  181. package/dist/service/install.d.ts +19 -0
  182. package/dist/service/install.js +35 -0
  183. package/dist/service/install.js.map +1 -0
  184. package/dist/service/templates.d.ts +22 -0
  185. package/dist/service/templates.js +118 -0
  186. package/dist/service/templates.js.map +1 -0
  187. package/dist/state/audit-log.d.ts +33 -0
  188. package/dist/state/audit-log.js +116 -0
  189. package/dist/state/audit-log.js.map +1 -0
  190. package/dist/state/config-history-store.d.ts +27 -0
  191. package/dist/state/config-history-store.js +65 -0
  192. package/dist/state/config-history-store.js.map +1 -0
  193. package/dist/state/handoff-store.d.ts +20 -0
  194. package/dist/state/handoff-store.js +97 -0
  195. package/dist/state/handoff-store.js.map +1 -0
  196. package/dist/state/idempotency-store.d.ts +19 -0
  197. package/dist/state/idempotency-store.js +84 -0
  198. package/dist/state/idempotency-store.js.map +1 -0
  199. package/dist/state/memory-store.d.ts +137 -0
  200. package/dist/state/memory-store.js +713 -0
  201. package/dist/state/memory-store.js.map +1 -0
  202. package/dist/state/pending-command-store.d.ts +30 -0
  203. package/dist/state/pending-command-store.js +108 -0
  204. package/dist/state/pending-command-store.js.map +1 -0
  205. package/dist/state/run-state-store.d.ts +58 -0
  206. package/dist/state/run-state-store.js +269 -0
  207. package/dist/state/run-state-store.js.map +1 -0
  208. package/dist/state/session-store.d.ts +56 -0
  209. package/dist/state/session-store.js +275 -0
  210. package/dist/state/session-store.js.map +1 -0
  211. package/dist/state/trust-store.d.ts +15 -0
  212. package/dist/state/trust-store.js +53 -0
  213. package/dist/state/trust-store.js.map +1 -0
  214. package/dist/utils/fs.d.ts +4 -0
  215. package/dist/utils/fs.js +26 -0
  216. package/dist/utils/fs.js.map +1 -0
  217. package/dist/utils/json.d.ts +1 -0
  218. package/dist/utils/json.js +9 -0
  219. package/dist/utils/json.js.map +1 -0
  220. package/dist/utils/path.d.ts +3 -0
  221. package/dist/utils/path.js +22 -0
  222. package/dist/utils/path.js.map +1 -0
  223. package/dist/utils/serial-executor.d.ts +5 -0
  224. package/dist/utils/serial-executor.js +12 -0
  225. package/dist/utils/serial-executor.js.map +1 -0
  226. package/package.json +71 -0
  227. package/skills/feique-session/SKILL.md +27 -0
@@ -0,0 +1,358 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ import fs from 'node:fs/promises';
4
+ import { spawn } from 'node:child_process';
5
+ export class ClaudeBackend {
6
+ config;
7
+ claudeHomeDir;
8
+ name = 'claude';
9
+ constructor(config, claudeHomeDir = resolveClaudeHomeDir()) {
10
+ this.config = config;
11
+ this.claudeHomeDir = claudeHomeDir;
12
+ }
13
+ async run(options) {
14
+ const args = this.buildArgs(options);
15
+ const spawnSpec = this.buildSpawnSpec(args);
16
+ options.logger.info({ command: spawnSpec.command, args: spawnSpec.args, workdir: options.workdir }, 'Starting Claude turn');
17
+ return await new Promise((resolve, reject) => {
18
+ const processRef = spawn(spawnSpec.command, spawnSpec.args, {
19
+ cwd: options.workdir,
20
+ env: {
21
+ ...process.env,
22
+ NO_COLOR: '1',
23
+ },
24
+ stdio: ['ignore', 'pipe', 'pipe'],
25
+ });
26
+ let stderr = '';
27
+ let stdoutBuffer = '';
28
+ let sessionId = options.sessionId;
29
+ let finalMessage = '';
30
+ let inputTokens;
31
+ let outputTokens;
32
+ let settled = false;
33
+ let timeoutHandle;
34
+ let abortCleanup;
35
+ const finishReject = (error) => {
36
+ if (settled)
37
+ return;
38
+ settled = true;
39
+ cleanup();
40
+ reject(error);
41
+ };
42
+ const finishResolve = (result) => {
43
+ if (settled)
44
+ return;
45
+ settled = true;
46
+ cleanup();
47
+ resolve(result);
48
+ };
49
+ const cleanup = () => {
50
+ if (timeoutHandle)
51
+ clearTimeout(timeoutHandle);
52
+ abortCleanup?.();
53
+ abortCleanup = undefined;
54
+ };
55
+ const abortRun = (reason) => {
56
+ if (processRef.killed)
57
+ return;
58
+ const message = typeof reason === 'string' ? reason : reason instanceof Error ? reason.message : 'Claude run aborted';
59
+ const error = new Error(message);
60
+ error.name = 'AbortError';
61
+ processRef.kill('SIGTERM');
62
+ setTimeout(() => {
63
+ if (!processRef.killed)
64
+ processRef.kill('SIGKILL');
65
+ }, 3000).unref();
66
+ finishReject(error);
67
+ };
68
+ if (options.timeoutMs && options.timeoutMs > 0) {
69
+ timeoutHandle = setTimeout(() => {
70
+ abortRun(`Claude timed out after ${options.timeoutMs}ms`);
71
+ }, options.timeoutMs);
72
+ timeoutHandle.unref();
73
+ }
74
+ if (options.signal) {
75
+ const onAbort = () => abortRun(options.signal?.reason ?? 'Claude run aborted');
76
+ if (options.signal.aborted) {
77
+ onAbort();
78
+ return;
79
+ }
80
+ options.signal.addEventListener('abort', onAbort, { once: true });
81
+ abortCleanup = () => options.signal?.removeEventListener('abort', onAbort);
82
+ }
83
+ if (typeof processRef.pid === 'number') {
84
+ void options.onSpawn?.(processRef.pid);
85
+ }
86
+ processRef.stdout.on('data', async (chunk) => {
87
+ stdoutBuffer += chunk.toString('utf8');
88
+ const lines = stdoutBuffer.split(/\r?\n/);
89
+ stdoutBuffer = lines.pop() ?? '';
90
+ for (const line of lines) {
91
+ const trimmed = line.trim();
92
+ if (!trimmed.startsWith('{'))
93
+ continue;
94
+ try {
95
+ const event = JSON.parse(trimmed);
96
+ // Extract session_id from result event
97
+ if (event.type === 'result' && event.session_id) {
98
+ sessionId = event.session_id;
99
+ }
100
+ // Extract final text and token usage from result event
101
+ if (event.type === 'result' && typeof event.result === 'string') {
102
+ finalMessage = event.result;
103
+ }
104
+ if (event.type === 'result') {
105
+ if (typeof event.total_input_tokens === 'number')
106
+ inputTokens = event.total_input_tokens;
107
+ if (typeof event.total_output_tokens === 'number')
108
+ outputTokens = event.total_output_tokens;
109
+ }
110
+ // Extract assistant text from assistant messages
111
+ if (event.type === 'assistant' && event.message?.content) {
112
+ const texts = event.message.content
113
+ .filter(c => c.type === 'text' && typeof c.text === 'string')
114
+ .map(c => c.text)
115
+ .join('\n');
116
+ if (texts) {
117
+ finalMessage = texts;
118
+ }
119
+ }
120
+ // Forward as unified BackendEvent
121
+ const backendEvent = {
122
+ type: event.type,
123
+ session_id: event.session_id ?? sessionId,
124
+ message: typeof event.result === 'string' ? event.result : undefined,
125
+ };
126
+ await options.onEvent?.(backendEvent);
127
+ }
128
+ catch {
129
+ options.logger.debug({ line }, 'Ignoring unparsable Claude line');
130
+ }
131
+ }
132
+ });
133
+ processRef.stderr.on('data', (chunk) => {
134
+ stderr += chunk.toString('utf8');
135
+ });
136
+ processRef.on('error', (error) => {
137
+ finishReject(error instanceof Error ? error : new Error(String(error)));
138
+ });
139
+ processRef.on('close', (exitCode) => {
140
+ if (settled)
141
+ return;
142
+ if ((exitCode ?? 1) !== 0 && !finalMessage) {
143
+ finishReject(new Error(`Claude exited with code ${exitCode ?? 1}: ${stderr.trim() || 'no stderr output'}`));
144
+ return;
145
+ }
146
+ finishResolve({
147
+ sessionId,
148
+ finalMessage: finalMessage.trim(),
149
+ stderr: stderr.trim(),
150
+ exitCode: exitCode ?? 0,
151
+ inputTokens,
152
+ outputTokens,
153
+ });
154
+ });
155
+ });
156
+ }
157
+ summarizeEvent(event) {
158
+ if (event.type === 'error' && typeof event.message === 'string') {
159
+ return `Claude 错误:${event.message}`;
160
+ }
161
+ return null;
162
+ }
163
+ async listProjectSessions(projectRoot, limit = 10) {
164
+ const sessions = await this.scanSessions();
165
+ const matches = [];
166
+ for (const session of sessions) {
167
+ const match = scoreSessionMatch(projectRoot, session.cwd);
168
+ if (!match)
169
+ continue;
170
+ matches.push({
171
+ ...session,
172
+ matchKind: match.kind,
173
+ matchScore: match.score,
174
+ });
175
+ }
176
+ return matches
177
+ .sort((a, b) => {
178
+ const scoreDelta = (b.matchScore ?? 0) - (a.matchScore ?? 0);
179
+ if (scoreDelta !== 0)
180
+ return scoreDelta;
181
+ return b.updatedAt.localeCompare(a.updatedAt);
182
+ })
183
+ .slice(0, limit);
184
+ }
185
+ async findLatestSession(projectRoot) {
186
+ const [session] = await this.listProjectSessions(projectRoot, 1);
187
+ return session ?? null;
188
+ }
189
+ async findSessionById(projectRoot, sessionId) {
190
+ const sessions = await this.scanSessions();
191
+ const candidate = sessions.find(s => s.sessionId === sessionId);
192
+ if (!candidate)
193
+ return null;
194
+ const match = scoreSessionMatch(projectRoot, candidate.cwd);
195
+ if (!match)
196
+ return null;
197
+ return { ...candidate, matchKind: match.kind, matchScore: match.score };
198
+ }
199
+ buildArgs(options) {
200
+ const args = ['-p'];
201
+ args.push('--output-format', 'stream-json');
202
+ const permissionMode = options.projectConfig?.permissionMode ?? this.config.defaultPermissionMode;
203
+ args.push('--permission-mode', permissionMode);
204
+ const model = options.projectConfig?.model ?? this.config.defaultModel;
205
+ if (model) {
206
+ args.push('--model', model);
207
+ }
208
+ const maxBudget = options.projectConfig?.maxBudgetUsd ?? this.config.maxBudgetUsd;
209
+ if (maxBudget !== undefined && maxBudget > 0) {
210
+ args.push('--max-budget-usd', String(maxBudget));
211
+ }
212
+ const allowedTools = options.projectConfig?.allowedTools ?? this.config.allowedTools;
213
+ if (allowedTools && allowedTools.length > 0) {
214
+ args.push('--allowedTools', ...allowedTools);
215
+ }
216
+ const systemPromptAppend = options.projectConfig?.systemPromptAppend ?? this.config.systemPromptAppend;
217
+ if (systemPromptAppend) {
218
+ args.push('--append-system-prompt', systemPromptAppend);
219
+ }
220
+ if (options.sessionId) {
221
+ args.push('--resume', options.sessionId);
222
+ }
223
+ args.push(options.prompt);
224
+ return args;
225
+ }
226
+ buildSpawnSpec(claudeArgs) {
227
+ if (!this.config.preExec) {
228
+ return { command: this.config.bin, args: claudeArgs };
229
+ }
230
+ const shell = this.config.shell ?? process.env.SHELL ?? '/bin/zsh';
231
+ const chainedCommand = `${this.config.preExec} && ${quoteShellCommand([this.config.bin, ...claudeArgs])}`;
232
+ return { command: shell, args: ['-ic', chainedCommand] };
233
+ }
234
+ async scanSessions() {
235
+ const sessionsDir = path.join(this.claudeHomeDir, 'sessions');
236
+ const sessions = new Map();
237
+ let entries;
238
+ try {
239
+ entries = await fs.readdir(sessionsDir);
240
+ }
241
+ catch {
242
+ return [];
243
+ }
244
+ for (const entry of entries) {
245
+ const sessionDir = path.join(sessionsDir, entry);
246
+ const stat = await fs.stat(sessionDir).catch(() => null);
247
+ if (!stat?.isDirectory())
248
+ continue;
249
+ // Claude sessions are stored as directories with session files inside
250
+ // The directory name is the session ID
251
+ const sessionId = entry;
252
+ const sessionFiles = await fs.readdir(sessionDir).catch(() => []);
253
+ // Look for session metadata - Claude stores conversation.jsonl or similar
254
+ let cwd = '';
255
+ let updatedAt = new Date(stat.mtimeMs).toISOString();
256
+ let createdAt;
257
+ // Try to read session metadata from the first jsonl file
258
+ for (const file of sessionFiles) {
259
+ if (!file.endsWith('.jsonl'))
260
+ continue;
261
+ const filePath = path.join(sessionDir, file);
262
+ try {
263
+ const content = await fs.readFile(filePath, 'utf8');
264
+ const firstLine = content.split(/\r?\n/, 1)[0]?.trim();
265
+ if (!firstLine)
266
+ continue;
267
+ const parsed = JSON.parse(firstLine);
268
+ if (parsed.cwd || parsed.working_directory) {
269
+ cwd = parsed.cwd ?? parsed.working_directory ?? '';
270
+ }
271
+ if (parsed.timestamp) {
272
+ createdAt = parsed.timestamp;
273
+ }
274
+ break;
275
+ }
276
+ catch {
277
+ continue;
278
+ }
279
+ }
280
+ // If no cwd found from jsonl, try reading from session config
281
+ if (!cwd) {
282
+ try {
283
+ const configPath = path.join(sessionDir, 'config.json');
284
+ const config = JSON.parse(await fs.readFile(configPath, 'utf8'));
285
+ cwd = config.cwd ?? config.working_directory ?? '';
286
+ }
287
+ catch {
288
+ // ignore
289
+ }
290
+ }
291
+ if (!cwd)
292
+ continue;
293
+ const existing = sessions.get(sessionId);
294
+ if (!existing || existing.updatedAt < updatedAt) {
295
+ sessions.set(sessionId, {
296
+ sessionId,
297
+ cwd,
298
+ updatedAt,
299
+ createdAt,
300
+ filePath: sessionDir,
301
+ source: 'sessions',
302
+ backend: 'claude',
303
+ });
304
+ }
305
+ }
306
+ return [...sessions.values()].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
307
+ }
308
+ }
309
+ function resolveClaudeHomeDir() {
310
+ const configured = process.env.CLAUDE_HOME?.trim();
311
+ if (!configured)
312
+ return path.join(os.homedir(), '.claude');
313
+ if (configured === '~')
314
+ return os.homedir();
315
+ if (configured.startsWith('~/'))
316
+ return path.join(os.homedir(), configured.slice(2));
317
+ return path.resolve(configured);
318
+ }
319
+ function quoteShellArg(value) {
320
+ if (value.length === 0)
321
+ return "''";
322
+ return `'${value.replace(/'/g, `'"'"'`)}'`;
323
+ }
324
+ function quoteShellCommand(parts) {
325
+ return parts.map(quoteShellArg).join(' ');
326
+ }
327
+ const FUZZY_SUFFIX_TOKENS = new Set(['bridge', 'repo', 'project', 'workspace']);
328
+ function scoreSessionMatch(projectRoot, sessionCwd) {
329
+ const normalizedProjectRoot = path.resolve(projectRoot).replace(/\/+$/, '').toLowerCase();
330
+ const normalizedSessionRoot = path.resolve(sessionCwd).replace(/\/+$/, '').toLowerCase();
331
+ if (normalizedProjectRoot === normalizedSessionRoot) {
332
+ return { kind: 'exact-root', score: 100 };
333
+ }
334
+ const projectBase = path.basename(normalizedProjectRoot);
335
+ const sessionBase = path.basename(normalizedSessionRoot);
336
+ if (projectBase === sessionBase) {
337
+ return { kind: 'basename', score: 80 };
338
+ }
339
+ const normalizedProjectName = normalizeProjectName(projectBase);
340
+ const normalizedSessionName = normalizeProjectName(sessionBase);
341
+ if (normalizedProjectName && normalizedProjectName === normalizedSessionName) {
342
+ return { kind: 'normalized-name', score: 60 };
343
+ }
344
+ if (normalizedProjectName.length >= 5 && normalizedSessionName.includes(normalizedProjectName)) {
345
+ return { kind: 'basename-contains', score: 40 };
346
+ }
347
+ return null;
348
+ }
349
+ function normalizeProjectName(input) {
350
+ const tokens = input
351
+ .toLowerCase()
352
+ .replace(/\.git$/, '')
353
+ .split(/[^a-z0-9]+/)
354
+ .filter(Boolean);
355
+ const filtered = tokens.filter(token => !FUZZY_SUFFIX_TOKENS.has(token));
356
+ return (filtered.length > 0 ? filtered : tokens).join('-');
357
+ }
358
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/backend/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { Backend, BackendRunOptions, BackendRunResult, BackendEvent, IndexedSession } from './types.js';
2
+ import { CodexSessionIndex } from '../codex/session-index.js';
3
+ import type { SandboxMode } from '../config/schema.js';
4
+ export interface CodexBackendConfig {
5
+ bin: string;
6
+ shell?: string;
7
+ preExec?: string;
8
+ defaultProfile?: string;
9
+ defaultSandbox: SandboxMode;
10
+ skipGitRepoCheck: boolean;
11
+ runTimeoutMs: number;
12
+ }
13
+ export interface CodexProjectConfig {
14
+ profile?: string;
15
+ sandbox?: SandboxMode;
16
+ tempDir?: string;
17
+ cacheDir?: string;
18
+ }
19
+ export declare class CodexBackend implements Backend {
20
+ private readonly config;
21
+ private readonly sessionIndex;
22
+ readonly name: "codex";
23
+ constructor(config: CodexBackendConfig, sessionIndex?: CodexSessionIndex);
24
+ run(options: BackendRunOptions & {
25
+ projectConfig?: CodexProjectConfig;
26
+ }): Promise<BackendRunResult>;
27
+ summarizeEvent(event: BackendEvent): string | null;
28
+ listProjectSessions(projectRoot: string, limit?: number): Promise<IndexedSession[]>;
29
+ findLatestSession(projectRoot: string): Promise<IndexedSession | null>;
30
+ findSessionById(projectRoot: string, sessionId: string): Promise<IndexedSession | null>;
31
+ }
@@ -0,0 +1,100 @@
1
+ import { runCodexTurn, summarizeCodexEvent } from '../codex/runner.js';
2
+ import { CodexSessionIndex } from '../codex/session-index.js';
3
+ export class CodexBackend {
4
+ config;
5
+ sessionIndex;
6
+ name = 'codex';
7
+ constructor(config, sessionIndex = new CodexSessionIndex()) {
8
+ this.config = config;
9
+ this.sessionIndex = sessionIndex;
10
+ }
11
+ async run(options) {
12
+ const result = await runCodexTurn({
13
+ bin: this.config.bin,
14
+ shell: this.config.shell,
15
+ preExec: this.config.preExec,
16
+ workdir: options.workdir,
17
+ prompt: options.prompt,
18
+ sessionId: options.sessionId,
19
+ profile: options.projectConfig?.profile ?? this.config.defaultProfile,
20
+ sandbox: options.projectConfig?.sandbox ?? this.config.defaultSandbox,
21
+ tempDir: options.projectConfig?.tempDir,
22
+ cacheDir: options.projectConfig?.cacheDir,
23
+ skipGitRepoCheck: this.config.skipGitRepoCheck,
24
+ timeoutMs: options.timeoutMs ?? this.config.runTimeoutMs,
25
+ signal: options.signal,
26
+ logger: options.logger,
27
+ onEvent: options.onEvent ? async (event) => {
28
+ await options.onEvent?.({
29
+ type: event.type,
30
+ session_id: event.thread_id,
31
+ item: event.item,
32
+ message: event.message,
33
+ ...event,
34
+ });
35
+ } : undefined,
36
+ onSpawn: options.onSpawn,
37
+ });
38
+ return {
39
+ sessionId: result.sessionId,
40
+ finalMessage: result.finalMessage,
41
+ stderr: result.stderr,
42
+ exitCode: result.exitCode,
43
+ };
44
+ }
45
+ summarizeEvent(event) {
46
+ return summarizeCodexEvent({
47
+ type: event.type,
48
+ thread_id: event.session_id,
49
+ item: event.item,
50
+ message: event.message,
51
+ });
52
+ }
53
+ async listProjectSessions(projectRoot, limit) {
54
+ const sessions = await this.sessionIndex.listProjectSessions(projectRoot, limit);
55
+ return sessions.map(s => ({
56
+ sessionId: s.threadId,
57
+ cwd: s.cwd,
58
+ updatedAt: s.updatedAt,
59
+ createdAt: s.createdAt,
60
+ filePath: s.filePath,
61
+ source: s.source,
62
+ backend: 'codex',
63
+ matchKind: s.matchKind,
64
+ matchScore: s.matchScore,
65
+ }));
66
+ }
67
+ async findLatestSession(projectRoot) {
68
+ const session = await this.sessionIndex.findLatestProjectSession(projectRoot);
69
+ if (!session)
70
+ return null;
71
+ return {
72
+ sessionId: session.threadId,
73
+ cwd: session.cwd,
74
+ updatedAt: session.updatedAt,
75
+ createdAt: session.createdAt,
76
+ filePath: session.filePath,
77
+ source: session.source,
78
+ backend: 'codex',
79
+ matchKind: session.matchKind,
80
+ matchScore: session.matchScore,
81
+ };
82
+ }
83
+ async findSessionById(projectRoot, sessionId) {
84
+ const session = await this.sessionIndex.findProjectSessionById(projectRoot, sessionId);
85
+ if (!session)
86
+ return null;
87
+ return {
88
+ sessionId: session.threadId,
89
+ cwd: session.cwd,
90
+ updatedAt: session.updatedAt,
91
+ createdAt: session.createdAt,
92
+ filePath: session.filePath,
93
+ source: session.source,
94
+ backend: 'codex',
95
+ matchKind: session.matchKind,
96
+ matchScore: session.matchScore,
97
+ };
98
+ }
99
+ }
100
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/backend/codex.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAoB9D,MAAM,OAAO,YAAY;IAIJ;IACA;IAJH,IAAI,GAAG,OAAgB,CAAC;IAExC,YACmB,MAA0B,EAC1B,eAAkC,IAAI,iBAAiB,EAAE;QADzD,WAAM,GAAN,MAAM,CAAoB;QAC1B,iBAAY,GAAZ,YAAY,CAA6C;IACzE,CAAC;IAEJ,KAAK,CAAC,GAAG,CAAC,OAAmE;QAC3E,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;YAChC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG;YACpB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YACxB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc;YACrE,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc;YACrE,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO;YACvC,QAAQ,EAAE,OAAO,CAAC,aAAa,EAAE,QAAQ;YACzC,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAC9C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY;YACxD,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBACzC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;oBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,UAAU,EAAE,KAAK,CAAC,SAAS;oBAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,GAAG,KAAK;iBACT,CAAC,CAAC;YACL,CAAC,CAAC,CAAC,CAAC,SAAS;YACb,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;QAEH,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,KAAmB;QAChC,OAAO,mBAAmB,CAAC;YACzB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,KAAK,CAAC,UAAU;YAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,WAAmB,EAAE,KAAc;QAC3D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACjF,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxB,SAAS,EAAE,CAAC,CAAC,QAAQ;YACrB,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,OAAgB;YACzB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,WAAmB;QACzC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC;QAC9E,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO;YACL,SAAS,EAAE,OAAO,CAAC,QAAQ;YAC3B,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAgB;YACzB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,WAAmB,EAAE,SAAiB;QAC1D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,sBAAsB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACvF,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO;YACL,SAAS,EAAE,OAAO,CAAC,QAAQ;YAC3B,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAgB;YACzB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import type { BridgeConfig } from '../config/schema.js';
2
+ import type { Backend, BackendName } from './types.js';
3
+ import { CodexSessionIndex } from '../codex/session-index.js';
4
+ export declare function createBackend(config: BridgeConfig, codexSessionIndex?: CodexSessionIndex): Backend;
5
+ export declare function createBackendByName(name: BackendName, config: BridgeConfig, codexSessionIndex?: CodexSessionIndex): Backend;
6
+ export declare function resolveDefaultBackend(config: BridgeConfig): BackendName;
7
+ export declare function resolveProjectBackend(config: BridgeConfig, projectAlias: string, codexSessionIndex?: CodexSessionIndex): Backend;
8
+ export declare function resolveProjectBackendWithOverride(config: BridgeConfig, projectAlias: string, sessionOverride?: BackendName, codexSessionIndex?: CodexSessionIndex): Backend;
9
+ export declare function resolveProjectBackendName(config: BridgeConfig, projectAlias: string, sessionOverride?: BackendName): BackendName;
@@ -0,0 +1,56 @@
1
+ import { CodexBackend } from './codex.js';
2
+ import { ClaudeBackend } from './claude.js';
3
+ import { CodexSessionIndex } from '../codex/session-index.js';
4
+ export function createBackend(config, codexSessionIndex) {
5
+ const backendName = resolveDefaultBackend(config);
6
+ return createBackendByName(backendName, config, codexSessionIndex);
7
+ }
8
+ export function createBackendByName(name, config, codexSessionIndex) {
9
+ switch (name) {
10
+ case 'codex':
11
+ return new CodexBackend({
12
+ bin: config.codex.bin,
13
+ shell: config.codex.shell,
14
+ preExec: config.codex.pre_exec,
15
+ defaultProfile: config.codex.default_profile,
16
+ defaultSandbox: config.codex.default_sandbox,
17
+ skipGitRepoCheck: config.codex.skip_git_repo_check,
18
+ runTimeoutMs: config.codex.run_timeout_ms,
19
+ }, codexSessionIndex ?? new CodexSessionIndex());
20
+ case 'claude':
21
+ return new ClaudeBackend({
22
+ bin: config.claude?.bin ?? 'claude',
23
+ shell: config.claude?.shell ?? config.codex.shell,
24
+ preExec: config.claude?.pre_exec ?? config.codex.pre_exec,
25
+ defaultPermissionMode: config.claude?.default_permission_mode ?? 'auto',
26
+ defaultModel: config.claude?.default_model,
27
+ maxBudgetUsd: config.claude?.max_budget_usd,
28
+ allowedTools: config.claude?.allowed_tools,
29
+ systemPromptAppend: config.claude?.system_prompt_append,
30
+ runTimeoutMs: config.claude?.run_timeout_ms ?? config.codex.run_timeout_ms,
31
+ });
32
+ default:
33
+ throw new Error(`Unknown backend: ${name}`);
34
+ }
35
+ }
36
+ export function resolveDefaultBackend(config) {
37
+ return config.backend?.default ?? 'codex';
38
+ }
39
+ export function resolveProjectBackend(config, projectAlias, codexSessionIndex) {
40
+ const project = config.projects[projectAlias];
41
+ const backendName = project?.backend ?? resolveDefaultBackend(config);
42
+ return createBackendByName(backendName, config, codexSessionIndex);
43
+ }
44
+ export function resolveProjectBackendWithOverride(config, projectAlias, sessionOverride, codexSessionIndex) {
45
+ if (sessionOverride) {
46
+ return createBackendByName(sessionOverride, config, codexSessionIndex);
47
+ }
48
+ return resolveProjectBackend(config, projectAlias, codexSessionIndex);
49
+ }
50
+ export function resolveProjectBackendName(config, projectAlias, sessionOverride) {
51
+ if (sessionOverride)
52
+ return sessionOverride;
53
+ const project = config.projects[projectAlias];
54
+ return project?.backend ?? resolveDefaultBackend(config);
55
+ }
56
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/backend/factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { Logger } from '../logging.js';
2
+ export type BackendName = 'codex' | 'claude';
3
+ export interface BackendEvent {
4
+ type?: string;
5
+ session_id?: string;
6
+ item?: {
7
+ type?: string;
8
+ text?: string;
9
+ content?: unknown;
10
+ };
11
+ message?: string;
12
+ [key: string]: unknown;
13
+ }
14
+ export interface BackendRunOptions {
15
+ workdir: string;
16
+ prompt: string;
17
+ sessionId?: string;
18
+ timeoutMs?: number;
19
+ signal?: AbortSignal;
20
+ logger: Logger;
21
+ onEvent?: (event: BackendEvent) => Promise<void> | void;
22
+ onSpawn?: (pid: number) => Promise<void> | void;
23
+ /** Backend-specific project config (CodexProjectConfig or ClaudeProjectConfig). */
24
+ projectConfig?: Record<string, unknown>;
25
+ }
26
+ export interface BackendRunResult {
27
+ sessionId?: string;
28
+ finalMessage: string;
29
+ stderr: string;
30
+ exitCode: number;
31
+ inputTokens?: number;
32
+ outputTokens?: number;
33
+ }
34
+ export type SessionSource = 'sessions' | 'archived';
35
+ export type SessionMatchKind = 'exact-root' | 'basename' | 'normalized-name' | 'basename-contains';
36
+ export interface IndexedSession {
37
+ sessionId: string;
38
+ cwd: string;
39
+ updatedAt: string;
40
+ createdAt?: string;
41
+ filePath: string;
42
+ source: SessionSource;
43
+ backend: BackendName;
44
+ matchKind?: SessionMatchKind;
45
+ matchScore?: number;
46
+ }
47
+ export interface Backend {
48
+ readonly name: BackendName;
49
+ run(options: BackendRunOptions): Promise<BackendRunResult>;
50
+ listProjectSessions(projectRoot: string, limit?: number): Promise<IndexedSession[]>;
51
+ findLatestSession(projectRoot: string): Promise<IndexedSession | null>;
52
+ findSessionById(projectRoot: string, sessionId: string): Promise<IndexedSession | null>;
53
+ summarizeEvent(event: BackendEvent): string | null;
54
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/backend/types.ts"],"names":[],"mappings":""}