@cloudcli-ai/cloudcli 1.29.5 → 1.30.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 (179) hide show
  1. package/README.de.md +1 -1
  2. package/README.ja.md +1 -1
  3. package/README.ko.md +1 -1
  4. package/README.md +1 -1
  5. package/README.ru.md +1 -1
  6. package/README.tr.md +252 -0
  7. package/README.zh-CN.md +1 -1
  8. package/dist/assets/index-DI22MZMb.css +32 -0
  9. package/dist/assets/index-RX-W_g_Q.js +1262 -0
  10. package/dist/index.html +2 -2
  11. package/dist-server/server/claude-sdk.js +13 -8
  12. package/dist-server/server/claude-sdk.js.map +1 -1
  13. package/dist-server/server/cursor-cli.js +7 -7
  14. package/dist-server/server/cursor-cli.js.map +1 -1
  15. package/dist-server/server/gemini-cli.js +5 -5
  16. package/dist-server/server/gemini-cli.js.map +1 -1
  17. package/dist-server/server/gemini-response-handler.js +2 -2
  18. package/dist-server/server/gemini-response-handler.js.map +1 -1
  19. package/dist-server/server/index.js +27 -25
  20. package/dist-server/server/index.js.map +1 -1
  21. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +103 -0
  22. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -0
  23. package/dist-server/server/modules/providers/list/claude/claude-mcp.provider.js +103 -0
  24. package/dist-server/server/modules/providers/list/claude/claude-mcp.provider.js.map +1 -0
  25. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +266 -0
  26. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -0
  27. package/dist-server/server/modules/providers/list/claude/claude.provider.js +13 -0
  28. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -0
  29. package/dist-server/server/modules/providers/list/codex/codex-auth.provider.js +84 -0
  30. package/dist-server/server/modules/providers/list/codex/codex-auth.provider.js.map +1 -0
  31. package/dist-server/server/modules/providers/list/codex/codex-mcp.provider.js +107 -0
  32. package/dist-server/server/modules/providers/list/codex/codex-mcp.provider.js.map +1 -0
  33. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +282 -0
  34. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -0
  35. package/dist-server/server/modules/providers/list/codex/codex.provider.js +13 -0
  36. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -0
  37. package/dist-server/server/modules/providers/list/cursor/cursor-auth.provider.js +118 -0
  38. package/dist-server/server/modules/providers/list/cursor/cursor-auth.provider.js.map +1 -0
  39. package/dist-server/server/modules/providers/list/cursor/cursor-mcp.provider.js +80 -0
  40. package/dist-server/server/modules/providers/list/cursor/cursor-mcp.provider.js.map +1 -0
  41. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +369 -0
  42. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -0
  43. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +13 -0
  44. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -0
  45. package/dist-server/server/modules/providers/list/gemini/gemini-auth.provider.js +131 -0
  46. package/dist-server/server/modules/providers/list/gemini/gemini-auth.provider.js.map +1 -0
  47. package/dist-server/server/modules/providers/list/gemini/gemini-mcp.provider.js +82 -0
  48. package/dist-server/server/modules/providers/list/gemini/gemini-mcp.provider.js.map +1 -0
  49. package/dist-server/server/modules/providers/list/gemini/gemini-sessions.provider.js +207 -0
  50. package/dist-server/server/modules/providers/list/gemini/gemini-sessions.provider.js.map +1 -0
  51. package/dist-server/server/modules/providers/list/gemini/gemini.provider.js +13 -0
  52. package/dist-server/server/modules/providers/list/gemini/gemini.provider.js.map +1 -0
  53. package/dist-server/server/modules/providers/provider.registry.js +31 -0
  54. package/dist-server/server/modules/providers/provider.registry.js.map +1 -0
  55. package/dist-server/server/modules/providers/provider.routes.js +159 -0
  56. package/dist-server/server/modules/providers/provider.routes.js.map +1 -0
  57. package/dist-server/server/modules/providers/services/mcp.service.js +69 -0
  58. package/dist-server/server/modules/providers/services/mcp.service.js.map +1 -0
  59. package/dist-server/server/modules/providers/services/provider-auth.service.js +25 -0
  60. package/dist-server/server/modules/providers/services/provider-auth.service.js.map +1 -0
  61. package/dist-server/server/modules/providers/services/sessions.service.js +29 -0
  62. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -0
  63. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +14 -0
  64. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -0
  65. package/dist-server/server/modules/providers/shared/mcp/mcp.provider.js +102 -0
  66. package/dist-server/server/modules/providers/shared/mcp/mcp.provider.js.map +1 -0
  67. package/dist-server/server/modules/providers/tests/mcp.test.js +250 -0
  68. package/dist-server/server/modules/providers/tests/mcp.test.js.map +1 -0
  69. package/dist-server/server/openai-codex.js +5 -5
  70. package/dist-server/server/openai-codex.js.map +1 -1
  71. package/dist-server/server/routes/codex.js +2 -278
  72. package/dist-server/server/routes/codex.js.map +1 -1
  73. package/dist-server/server/routes/commands.js +0 -44
  74. package/dist-server/server/routes/commands.js.map +1 -1
  75. package/dist-server/server/routes/cursor.js +9 -489
  76. package/dist-server/server/routes/cursor.js.map +1 -1
  77. package/dist-server/server/routes/mcp-utils.js +1 -18
  78. package/dist-server/server/routes/mcp-utils.js.map +1 -1
  79. package/dist-server/server/routes/messages.js +6 -6
  80. package/dist-server/server/routes/messages.js.map +1 -1
  81. package/dist-server/server/routes/settings.js +10 -0
  82. package/dist-server/server/routes/settings.js.map +1 -1
  83. package/dist-server/server/routes/taskmaster.js +0 -459
  84. package/dist-server/server/routes/taskmaster.js.map +1 -1
  85. package/dist-server/server/shared/interfaces.js +2 -0
  86. package/dist-server/server/shared/interfaces.js.map +1 -0
  87. package/dist-server/server/shared/types.js +3 -0
  88. package/dist-server/server/shared/types.js.map +1 -0
  89. package/dist-server/server/shared/utils.js +150 -0
  90. package/dist-server/server/shared/utils.js.map +1 -0
  91. package/dist-server/server/utils/mcp-detector.js +0 -49
  92. package/dist-server/server/utils/mcp-detector.js.map +1 -1
  93. package/dist-server/shared/modelConstants.js +1 -0
  94. package/dist-server/shared/modelConstants.js.map +1 -1
  95. package/package.json +5 -2
  96. package/server/claude-sdk.js +14 -8
  97. package/server/cursor-cli.js +7 -7
  98. package/server/gemini-cli.js +5 -5
  99. package/server/gemini-response-handler.js +2 -2
  100. package/server/index.js +33 -29
  101. package/server/modules/providers/list/claude/claude-auth.provider.ts +123 -0
  102. package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -0
  103. package/server/modules/providers/list/claude/claude-sessions.provider.ts +306 -0
  104. package/server/modules/providers/list/claude/claude.provider.ts +15 -0
  105. package/server/modules/providers/list/codex/codex-auth.provider.ts +100 -0
  106. package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -0
  107. package/server/modules/providers/list/codex/codex-sessions.provider.ts +319 -0
  108. package/server/modules/providers/list/codex/codex.provider.ts +15 -0
  109. package/server/modules/providers/list/cursor/cursor-auth.provider.ts +143 -0
  110. package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -0
  111. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +421 -0
  112. package/server/modules/providers/list/cursor/cursor.provider.ts +15 -0
  113. package/server/modules/providers/list/gemini/gemini-auth.provider.ts +151 -0
  114. package/server/modules/providers/list/gemini/gemini-mcp.provider.ts +110 -0
  115. package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +227 -0
  116. package/server/modules/providers/list/gemini/gemini.provider.ts +15 -0
  117. package/server/modules/providers/provider.registry.ts +36 -0
  118. package/server/modules/providers/provider.routes.ts +217 -0
  119. package/server/modules/providers/services/mcp.service.ts +94 -0
  120. package/server/modules/providers/services/provider-auth.service.ts +26 -0
  121. package/server/modules/providers/services/sessions.service.ts +45 -0
  122. package/server/modules/providers/shared/base/abstract.provider.ts +20 -0
  123. package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -0
  124. package/server/modules/providers/tests/mcp.test.ts +293 -0
  125. package/server/openai-codex.js +5 -5
  126. package/server/routes/codex.js +2 -312
  127. package/server/routes/commands.js +0 -49
  128. package/server/routes/cursor.js +15 -527
  129. package/server/routes/mcp-utils.js +2 -19
  130. package/server/routes/messages.js +6 -6
  131. package/server/routes/settings.js +10 -0
  132. package/server/routes/taskmaster.js +0 -492
  133. package/server/shared/interfaces.ts +54 -0
  134. package/server/shared/types.ts +172 -0
  135. package/server/shared/utils.ts +193 -0
  136. package/server/tsconfig.json +6 -3
  137. package/server/utils/mcp-detector.js +0 -51
  138. package/shared/modelConstants.js +1 -0
  139. package/dist/assets/index-BBAE1OJ_.css +0 -32
  140. package/dist/assets/index-Ci1GOyV7.js +0 -1262
  141. package/dist-server/server/providers/claude/adapter.js +0 -266
  142. package/dist-server/server/providers/claude/adapter.js.map +0 -1
  143. package/dist-server/server/providers/claude/status.js +0 -121
  144. package/dist-server/server/providers/claude/status.js.map +0 -1
  145. package/dist-server/server/providers/codex/adapter.js +0 -232
  146. package/dist-server/server/providers/codex/adapter.js.map +0 -1
  147. package/dist-server/server/providers/codex/status.js +0 -70
  148. package/dist-server/server/providers/codex/status.js.map +0 -1
  149. package/dist-server/server/providers/cursor/adapter.js +0 -342
  150. package/dist-server/server/providers/cursor/adapter.js.map +0 -1
  151. package/dist-server/server/providers/cursor/status.js +0 -118
  152. package/dist-server/server/providers/cursor/status.js.map +0 -1
  153. package/dist-server/server/providers/gemini/adapter.js +0 -174
  154. package/dist-server/server/providers/gemini/adapter.js.map +0 -1
  155. package/dist-server/server/providers/gemini/status.js +0 -104
  156. package/dist-server/server/providers/gemini/status.js.map +0 -1
  157. package/dist-server/server/providers/registry.js +0 -58
  158. package/dist-server/server/providers/registry.js.map +0 -1
  159. package/dist-server/server/providers/types.js +0 -117
  160. package/dist-server/server/providers/types.js.map +0 -1
  161. package/dist-server/server/providers/utils.js +0 -28
  162. package/dist-server/server/providers/utils.js.map +0 -1
  163. package/dist-server/server/routes/cli-auth.js +0 -25
  164. package/dist-server/server/routes/cli-auth.js.map +0 -1
  165. package/dist-server/server/routes/mcp.js +0 -480
  166. package/dist-server/server/routes/mcp.js.map +0 -1
  167. package/server/providers/claude/adapter.js +0 -278
  168. package/server/providers/claude/status.js +0 -136
  169. package/server/providers/codex/adapter.js +0 -248
  170. package/server/providers/codex/status.js +0 -78
  171. package/server/providers/cursor/adapter.js +0 -348
  172. package/server/providers/cursor/status.js +0 -128
  173. package/server/providers/gemini/adapter.js +0 -186
  174. package/server/providers/gemini/status.js +0 -111
  175. package/server/providers/registry.js +0 -67
  176. package/server/providers/types.js +0 -132
  177. package/server/providers/utils.js +0 -29
  178. package/server/routes/cli-auth.js +0 -27
  179. package/server/routes/mcp.js +0 -552
@@ -1,278 +0,0 @@
1
- /**
2
- * Claude provider adapter.
3
- *
4
- * Normalizes Claude SDK session history into NormalizedMessage format.
5
- * @module adapters/claude
6
- */
7
-
8
- import { getSessionMessages } from '../../projects.js';
9
- import { createNormalizedMessage, generateMessageId } from '../types.js';
10
- import { isInternalContent } from '../utils.js';
11
-
12
- const PROVIDER = 'claude';
13
-
14
- /**
15
- * Normalize a raw JSONL message or realtime SDK event into NormalizedMessage(s).
16
- * Handles both history entries (JSONL `{ message: { role, content } }`) and
17
- * realtime streaming events (`content_block_delta`, `content_block_stop`, etc.).
18
- * @param {object} raw - A single entry from JSONL or a live SDK event
19
- * @param {string} sessionId
20
- * @returns {import('../types.js').NormalizedMessage[]}
21
- */
22
- export function normalizeMessage(raw, sessionId) {
23
- // ── Streaming events (realtime) ──────────────────────────────────────────
24
- if (raw.type === 'content_block_delta' && raw.delta?.text) {
25
- return [createNormalizedMessage({ kind: 'stream_delta', content: raw.delta.text, sessionId, provider: PROVIDER })];
26
- }
27
- if (raw.type === 'content_block_stop') {
28
- return [createNormalizedMessage({ kind: 'stream_end', sessionId, provider: PROVIDER })];
29
- }
30
-
31
- // ── History / full-message events ────────────────────────────────────────
32
- const messages = [];
33
- const ts = raw.timestamp || new Date().toISOString();
34
- const baseId = raw.uuid || generateMessageId('claude');
35
-
36
- // User message
37
- if (raw.message?.role === 'user' && raw.message?.content) {
38
- if (Array.isArray(raw.message.content)) {
39
- // Handle tool_result parts
40
- for (const part of raw.message.content) {
41
- if (part.type === 'tool_result') {
42
- messages.push(createNormalizedMessage({
43
- id: `${baseId}_tr_${part.tool_use_id}`,
44
- sessionId,
45
- timestamp: ts,
46
- provider: PROVIDER,
47
- kind: 'tool_result',
48
- toolId: part.tool_use_id,
49
- content: typeof part.content === 'string' ? part.content : JSON.stringify(part.content),
50
- isError: Boolean(part.is_error),
51
- subagentTools: raw.subagentTools,
52
- toolUseResult: raw.toolUseResult,
53
- }));
54
- } else if (part.type === 'text') {
55
- // Regular text parts from user
56
- const text = part.text || '';
57
- if (text && !isInternalContent(text)) {
58
- messages.push(createNormalizedMessage({
59
- id: `${baseId}_text`,
60
- sessionId,
61
- timestamp: ts,
62
- provider: PROVIDER,
63
- kind: 'text',
64
- role: 'user',
65
- content: text,
66
- }));
67
- }
68
- }
69
- }
70
-
71
- // If no text parts were found, check if it's a pure user message
72
- if (messages.length === 0) {
73
- const textParts = raw.message.content
74
- .filter(p => p.type === 'text')
75
- .map(p => p.text)
76
- .filter(Boolean)
77
- .join('\n');
78
- if (textParts && !isInternalContent(textParts)) {
79
- messages.push(createNormalizedMessage({
80
- id: `${baseId}_text`,
81
- sessionId,
82
- timestamp: ts,
83
- provider: PROVIDER,
84
- kind: 'text',
85
- role: 'user',
86
- content: textParts,
87
- }));
88
- }
89
- }
90
- } else if (typeof raw.message.content === 'string') {
91
- const text = raw.message.content;
92
- if (text && !isInternalContent(text)) {
93
- messages.push(createNormalizedMessage({
94
- id: baseId,
95
- sessionId,
96
- timestamp: ts,
97
- provider: PROVIDER,
98
- kind: 'text',
99
- role: 'user',
100
- content: text,
101
- }));
102
- }
103
- }
104
- return messages;
105
- }
106
-
107
- // Thinking message
108
- if (raw.type === 'thinking' && raw.message?.content) {
109
- messages.push(createNormalizedMessage({
110
- id: baseId,
111
- sessionId,
112
- timestamp: ts,
113
- provider: PROVIDER,
114
- kind: 'thinking',
115
- content: raw.message.content,
116
- }));
117
- return messages;
118
- }
119
-
120
- // Tool use result (codex-style in Claude)
121
- if (raw.type === 'tool_use' && raw.toolName) {
122
- messages.push(createNormalizedMessage({
123
- id: baseId,
124
- sessionId,
125
- timestamp: ts,
126
- provider: PROVIDER,
127
- kind: 'tool_use',
128
- toolName: raw.toolName,
129
- toolInput: raw.toolInput,
130
- toolId: raw.toolCallId || baseId,
131
- }));
132
- return messages;
133
- }
134
-
135
- if (raw.type === 'tool_result') {
136
- messages.push(createNormalizedMessage({
137
- id: baseId,
138
- sessionId,
139
- timestamp: ts,
140
- provider: PROVIDER,
141
- kind: 'tool_result',
142
- toolId: raw.toolCallId || '',
143
- content: raw.output || '',
144
- isError: false,
145
- }));
146
- return messages;
147
- }
148
-
149
- // Assistant message
150
- if (raw.message?.role === 'assistant' && raw.message?.content) {
151
- if (Array.isArray(raw.message.content)) {
152
- let partIndex = 0;
153
- for (const part of raw.message.content) {
154
- if (part.type === 'text' && part.text) {
155
- messages.push(createNormalizedMessage({
156
- id: `${baseId}_${partIndex}`,
157
- sessionId,
158
- timestamp: ts,
159
- provider: PROVIDER,
160
- kind: 'text',
161
- role: 'assistant',
162
- content: part.text,
163
- }));
164
- } else if (part.type === 'tool_use') {
165
- messages.push(createNormalizedMessage({
166
- id: `${baseId}_${partIndex}`,
167
- sessionId,
168
- timestamp: ts,
169
- provider: PROVIDER,
170
- kind: 'tool_use',
171
- toolName: part.name,
172
- toolInput: part.input,
173
- toolId: part.id,
174
- }));
175
- } else if (part.type === 'thinking' && part.thinking) {
176
- messages.push(createNormalizedMessage({
177
- id: `${baseId}_${partIndex}`,
178
- sessionId,
179
- timestamp: ts,
180
- provider: PROVIDER,
181
- kind: 'thinking',
182
- content: part.thinking,
183
- }));
184
- }
185
- partIndex++;
186
- }
187
- } else if (typeof raw.message.content === 'string') {
188
- messages.push(createNormalizedMessage({
189
- id: baseId,
190
- sessionId,
191
- timestamp: ts,
192
- provider: PROVIDER,
193
- kind: 'text',
194
- role: 'assistant',
195
- content: raw.message.content,
196
- }));
197
- }
198
- return messages;
199
- }
200
-
201
- return messages;
202
- }
203
-
204
- /**
205
- * @type {import('../types.js').ProviderAdapter}
206
- */
207
- export const claudeAdapter = {
208
- normalizeMessage,
209
-
210
- /**
211
- * Fetch session history from JSONL files, returning normalized messages.
212
- */
213
- async fetchHistory(sessionId, opts = {}) {
214
- const { projectName, limit = null, offset = 0 } = opts;
215
- if (!projectName) {
216
- return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
217
- }
218
-
219
- let result;
220
- try {
221
- result = await getSessionMessages(projectName, sessionId, limit, offset);
222
- } catch (error) {
223
- console.warn(`[ClaudeAdapter] Failed to load session ${sessionId}:`, error.message);
224
- return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
225
- }
226
-
227
- // getSessionMessages returns either an array (no limit) or { messages, total, hasMore }
228
- const rawMessages = Array.isArray(result) ? result : (result.messages || []);
229
- const total = Array.isArray(result) ? rawMessages.length : (result.total || 0);
230
- const hasMore = Array.isArray(result) ? false : Boolean(result.hasMore);
231
-
232
- // First pass: collect tool results for attachment to tool_use messages
233
- const toolResultMap = new Map();
234
- for (const raw of rawMessages) {
235
- if (raw.message?.role === 'user' && Array.isArray(raw.message?.content)) {
236
- for (const part of raw.message.content) {
237
- if (part.type === 'tool_result') {
238
- toolResultMap.set(part.tool_use_id, {
239
- content: part.content,
240
- isError: Boolean(part.is_error),
241
- timestamp: raw.timestamp,
242
- subagentTools: raw.subagentTools,
243
- toolUseResult: raw.toolUseResult,
244
- });
245
- }
246
- }
247
- }
248
- }
249
-
250
- // Second pass: normalize all messages
251
- const normalized = [];
252
- for (const raw of rawMessages) {
253
- const entries = normalizeMessage(raw, sessionId);
254
- normalized.push(...entries);
255
- }
256
-
257
- // Attach tool results to their corresponding tool_use messages
258
- for (const msg of normalized) {
259
- if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
260
- const tr = toolResultMap.get(msg.toolId);
261
- msg.toolResult = {
262
- content: typeof tr.content === 'string' ? tr.content : JSON.stringify(tr.content),
263
- isError: tr.isError,
264
- toolUseResult: tr.toolUseResult,
265
- };
266
- msg.subagentTools = tr.subagentTools;
267
- }
268
- }
269
-
270
- return {
271
- messages: normalized,
272
- total,
273
- hasMore,
274
- offset,
275
- limit,
276
- };
277
- },
278
- };
@@ -1,136 +0,0 @@
1
- /**
2
- * Claude Provider Status
3
- *
4
- * Checks whether Claude Code CLI is installed and whether the user
5
- * has valid authentication credentials.
6
- *
7
- * @module providers/claude/status
8
- */
9
-
10
- import { execFileSync } from 'child_process';
11
- import { promises as fs } from 'fs';
12
- import path from 'path';
13
- import os from 'os';
14
-
15
- /**
16
- * Check if Claude Code CLI is installed and available.
17
- * Uses CLAUDE_CLI_PATH env var if set, otherwise looks for 'claude' in PATH.
18
- * @returns {boolean}
19
- */
20
- export function checkInstalled() {
21
- const cliPath = process.env.CLAUDE_CLI_PATH || 'claude';
22
- try {
23
- execFileSync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 });
24
- return true;
25
- } catch {
26
- return false;
27
- }
28
- }
29
-
30
- /**
31
- * Full status check: installation + authentication.
32
- * @returns {Promise<import('../types.js').ProviderStatus>}
33
- */
34
- export async function checkStatus() {
35
- const installed = checkInstalled();
36
-
37
- if (!installed) {
38
- return {
39
- installed,
40
- authenticated: false,
41
- email: null,
42
- method: null,
43
- error: 'Claude Code CLI is not installed'
44
- };
45
- }
46
-
47
- const credentialsResult = await checkCredentials();
48
-
49
- if (credentialsResult.authenticated) {
50
- return {
51
- installed,
52
- authenticated: true,
53
- email: credentialsResult.email || 'Authenticated',
54
- method: credentialsResult.method || null,
55
- error: null
56
- };
57
- }
58
-
59
- return {
60
- installed,
61
- authenticated: false,
62
- email: credentialsResult.email || null,
63
- method: credentialsResult.method || null,
64
- error: credentialsResult.error || 'Not authenticated'
65
- };
66
- }
67
-
68
- // ─── Internal helpers ───────────────────────────────────────────────────────
69
-
70
- async function loadSettingsEnv() {
71
- try {
72
- const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
73
- const content = await fs.readFile(settingsPath, 'utf8');
74
- const settings = JSON.parse(content);
75
-
76
- if (settings?.env && typeof settings.env === 'object') {
77
- return settings.env;
78
- }
79
- } catch {
80
- // Ignore missing or malformed settings.
81
- }
82
-
83
- return {};
84
- }
85
-
86
- /**
87
- * Checks Claude authentication credentials.
88
- *
89
- * Priority 1: ANTHROPIC_API_KEY environment variable
90
- * Priority 1b: ~/.claude/settings.json env values
91
- * Priority 2: ~/.claude/.credentials.json OAuth tokens
92
- */
93
- async function checkCredentials() {
94
- if (process.env.ANTHROPIC_API_KEY && process.env.ANTHROPIC_API_KEY.trim()) {
95
- return { authenticated: true, email: 'API Key Auth', method: 'api_key' };
96
- }
97
-
98
- const settingsEnv = await loadSettingsEnv();
99
-
100
- if (typeof settingsEnv.ANTHROPIC_API_KEY === 'string' && settingsEnv.ANTHROPIC_API_KEY.trim()) {
101
- return { authenticated: true, email: 'API Key Auth', method: 'api_key' };
102
- }
103
-
104
- if (typeof settingsEnv.ANTHROPIC_AUTH_TOKEN === 'string' && settingsEnv.ANTHROPIC_AUTH_TOKEN.trim()) {
105
- return { authenticated: true, email: 'Configured via settings.json', method: 'api_key' };
106
- }
107
-
108
- try {
109
- const credPath = path.join(os.homedir(), '.claude', '.credentials.json');
110
- const content = await fs.readFile(credPath, 'utf8');
111
- const creds = JSON.parse(content);
112
-
113
- const oauth = creds.claudeAiOauth;
114
- if (oauth && oauth.accessToken) {
115
- const isExpired = oauth.expiresAt && Date.now() >= oauth.expiresAt;
116
- if (!isExpired) {
117
- return {
118
- authenticated: true,
119
- email: creds.email || creds.user || null,
120
- method: 'credentials_file'
121
- };
122
- }
123
-
124
- return {
125
- authenticated: false,
126
- email: creds.email || creds.user || null,
127
- method: 'credentials_file',
128
- error: 'OAuth token has expired. Please re-authenticate with claude login'
129
- };
130
- }
131
-
132
- return { authenticated: false, email: null, method: null };
133
- } catch {
134
- return { authenticated: false, email: null, method: null };
135
- }
136
- }
@@ -1,248 +0,0 @@
1
- /**
2
- * Codex (OpenAI) provider adapter.
3
- *
4
- * Normalizes Codex SDK session history into NormalizedMessage format.
5
- * @module adapters/codex
6
- */
7
-
8
- import { getCodexSessionMessages } from '../../projects.js';
9
- import { createNormalizedMessage, generateMessageId } from '../types.js';
10
-
11
- const PROVIDER = 'codex';
12
-
13
- /**
14
- * Normalize a raw Codex JSONL message into NormalizedMessage(s).
15
- * @param {object} raw - A single parsed message from Codex JSONL
16
- * @param {string} sessionId
17
- * @returns {import('../types.js').NormalizedMessage[]}
18
- */
19
- function normalizeCodexHistoryEntry(raw, sessionId) {
20
- const ts = raw.timestamp || new Date().toISOString();
21
- const baseId = raw.uuid || generateMessageId('codex');
22
-
23
- // User message
24
- if (raw.message?.role === 'user') {
25
- const content = typeof raw.message.content === 'string'
26
- ? raw.message.content
27
- : Array.isArray(raw.message.content)
28
- ? raw.message.content.map(p => typeof p === 'string' ? p : p?.text || '').filter(Boolean).join('\n')
29
- : String(raw.message.content || '');
30
- if (!content.trim()) return [];
31
- return [createNormalizedMessage({
32
- id: baseId,
33
- sessionId,
34
- timestamp: ts,
35
- provider: PROVIDER,
36
- kind: 'text',
37
- role: 'user',
38
- content,
39
- })];
40
- }
41
-
42
- // Assistant message
43
- if (raw.message?.role === 'assistant') {
44
- const content = typeof raw.message.content === 'string'
45
- ? raw.message.content
46
- : Array.isArray(raw.message.content)
47
- ? raw.message.content.map(p => typeof p === 'string' ? p : p?.text || '').filter(Boolean).join('\n')
48
- : '';
49
- if (!content.trim()) return [];
50
- return [createNormalizedMessage({
51
- id: baseId,
52
- sessionId,
53
- timestamp: ts,
54
- provider: PROVIDER,
55
- kind: 'text',
56
- role: 'assistant',
57
- content,
58
- })];
59
- }
60
-
61
- // Thinking/reasoning
62
- if (raw.type === 'thinking' || raw.isReasoning) {
63
- return [createNormalizedMessage({
64
- id: baseId,
65
- sessionId,
66
- timestamp: ts,
67
- provider: PROVIDER,
68
- kind: 'thinking',
69
- content: raw.message?.content || '',
70
- })];
71
- }
72
-
73
- // Tool use
74
- if (raw.type === 'tool_use' || raw.toolName) {
75
- return [createNormalizedMessage({
76
- id: baseId,
77
- sessionId,
78
- timestamp: ts,
79
- provider: PROVIDER,
80
- kind: 'tool_use',
81
- toolName: raw.toolName || 'Unknown',
82
- toolInput: raw.toolInput,
83
- toolId: raw.toolCallId || baseId,
84
- })];
85
- }
86
-
87
- // Tool result
88
- if (raw.type === 'tool_result') {
89
- return [createNormalizedMessage({
90
- id: baseId,
91
- sessionId,
92
- timestamp: ts,
93
- provider: PROVIDER,
94
- kind: 'tool_result',
95
- toolId: raw.toolCallId || '',
96
- content: raw.output || '',
97
- isError: Boolean(raw.isError),
98
- })];
99
- }
100
-
101
- return [];
102
- }
103
-
104
- /**
105
- * Normalize a raw Codex event (history JSONL or transformed SDK event) into NormalizedMessage(s).
106
- * @param {object} raw - A history entry (has raw.message.role) or transformed SDK event (has raw.type)
107
- * @param {string} sessionId
108
- * @returns {import('../types.js').NormalizedMessage[]}
109
- */
110
- export function normalizeMessage(raw, sessionId) {
111
- // History format: has message.role
112
- if (raw.message?.role) {
113
- return normalizeCodexHistoryEntry(raw, sessionId);
114
- }
115
-
116
- const ts = raw.timestamp || new Date().toISOString();
117
- const baseId = raw.uuid || generateMessageId('codex');
118
-
119
- // SDK event format (output of transformCodexEvent)
120
- if (raw.type === 'item') {
121
- switch (raw.itemType) {
122
- case 'agent_message':
123
- return [createNormalizedMessage({
124
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
125
- kind: 'text', role: 'assistant', content: raw.message?.content || '',
126
- })];
127
- case 'reasoning':
128
- return [createNormalizedMessage({
129
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
130
- kind: 'thinking', content: raw.message?.content || '',
131
- })];
132
- case 'command_execution':
133
- return [createNormalizedMessage({
134
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
135
- kind: 'tool_use', toolName: 'Bash', toolInput: { command: raw.command },
136
- toolId: baseId,
137
- output: raw.output, exitCode: raw.exitCode, status: raw.status,
138
- })];
139
- case 'file_change':
140
- return [createNormalizedMessage({
141
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
142
- kind: 'tool_use', toolName: 'FileChanges', toolInput: raw.changes,
143
- toolId: baseId, status: raw.status,
144
- })];
145
- case 'mcp_tool_call':
146
- return [createNormalizedMessage({
147
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
148
- kind: 'tool_use', toolName: raw.tool || 'MCP', toolInput: raw.arguments,
149
- toolId: baseId, server: raw.server, result: raw.result,
150
- error: raw.error, status: raw.status,
151
- })];
152
- case 'web_search':
153
- return [createNormalizedMessage({
154
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
155
- kind: 'tool_use', toolName: 'WebSearch', toolInput: { query: raw.query },
156
- toolId: baseId,
157
- })];
158
- case 'todo_list':
159
- return [createNormalizedMessage({
160
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
161
- kind: 'tool_use', toolName: 'TodoList', toolInput: { items: raw.items },
162
- toolId: baseId,
163
- })];
164
- case 'error':
165
- return [createNormalizedMessage({
166
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
167
- kind: 'error', content: raw.message?.content || 'Unknown error',
168
- })];
169
- default:
170
- // Unknown item type — pass through as generic tool_use
171
- return [createNormalizedMessage({
172
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
173
- kind: 'tool_use', toolName: raw.itemType || 'Unknown',
174
- toolInput: raw.item || raw, toolId: baseId,
175
- })];
176
- }
177
- }
178
-
179
- if (raw.type === 'turn_complete') {
180
- return [createNormalizedMessage({
181
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
182
- kind: 'complete',
183
- })];
184
- }
185
- if (raw.type === 'turn_failed') {
186
- return [createNormalizedMessage({
187
- id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
188
- kind: 'error', content: raw.error?.message || 'Turn failed',
189
- })];
190
- }
191
-
192
- return [];
193
- }
194
-
195
- /**
196
- * @type {import('../types.js').ProviderAdapter}
197
- */
198
- export const codexAdapter = {
199
- normalizeMessage,
200
- /**
201
- * Fetch session history from Codex JSONL files.
202
- */
203
- async fetchHistory(sessionId, opts = {}) {
204
- const { limit = null, offset = 0 } = opts;
205
-
206
- let result;
207
- try {
208
- result = await getCodexSessionMessages(sessionId, limit, offset);
209
- } catch (error) {
210
- console.warn(`[CodexAdapter] Failed to load session ${sessionId}:`, error.message);
211
- return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
212
- }
213
-
214
- const rawMessages = Array.isArray(result) ? result : (result.messages || []);
215
- const total = Array.isArray(result) ? rawMessages.length : (result.total || 0);
216
- const hasMore = Array.isArray(result) ? false : Boolean(result.hasMore);
217
- const tokenUsage = result.tokenUsage || null;
218
-
219
- const normalized = [];
220
- for (const raw of rawMessages) {
221
- const entries = normalizeCodexHistoryEntry(raw, sessionId);
222
- normalized.push(...entries);
223
- }
224
-
225
- // Attach tool results to tool_use messages
226
- const toolResultMap = new Map();
227
- for (const msg of normalized) {
228
- if (msg.kind === 'tool_result' && msg.toolId) {
229
- toolResultMap.set(msg.toolId, msg);
230
- }
231
- }
232
- for (const msg of normalized) {
233
- if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
234
- const tr = toolResultMap.get(msg.toolId);
235
- msg.toolResult = { content: tr.content, isError: tr.isError };
236
- }
237
- }
238
-
239
- return {
240
- messages: normalized,
241
- total,
242
- hasMore,
243
- offset,
244
- limit,
245
- tokenUsage,
246
- };
247
- },
248
- };