@cloudcli-ai/cloudcli 1.29.1 → 1.29.3
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.
- package/dist/assets/{index-ByHZ8-LL.css → index-D-9h5kNf.css} +1 -1
- package/dist/assets/{index-BOWaxSnV.js → index-y8yqvoLv.js} +229 -229
- package/dist/index.html +2 -2
- package/dist-server/server/claude-sdk.js +694 -0
- package/dist-server/server/claude-sdk.js.map +1 -0
- package/dist-server/server/cli.js +642 -0
- package/dist-server/server/cli.js.map +1 -0
- package/dist-server/server/constants/config.js +6 -0
- package/dist-server/server/constants/config.js.map +1 -0
- package/dist-server/server/cursor-cli.js +271 -0
- package/dist-server/server/cursor-cli.js.map +1 -0
- package/dist-server/server/database/db.js +535 -0
- package/dist-server/server/database/db.js.map +1 -0
- package/dist-server/server/database/schema.js +97 -0
- package/dist-server/server/database/schema.js.map +1 -0
- package/dist-server/server/gemini-cli.js +394 -0
- package/dist-server/server/gemini-cli.js.map +1 -0
- package/dist-server/server/gemini-response-handler.js +72 -0
- package/dist-server/server/gemini-response-handler.js.map +1 -0
- package/dist-server/server/index.js +2244 -0
- package/dist-server/server/index.js.map +1 -0
- package/dist-server/server/load-env.js +32 -0
- package/dist-server/server/load-env.js.map +1 -0
- package/dist-server/server/middleware/auth.js +111 -0
- package/dist-server/server/middleware/auth.js.map +1 -0
- package/dist-server/server/openai-codex.js +367 -0
- package/dist-server/server/openai-codex.js.map +1 -0
- package/dist-server/server/projects.js +2331 -0
- package/dist-server/server/projects.js.map +1 -0
- package/dist-server/server/providers/claude/adapter.js +266 -0
- package/dist-server/server/providers/claude/adapter.js.map +1 -0
- package/dist-server/server/providers/codex/adapter.js +232 -0
- package/dist-server/server/providers/codex/adapter.js.map +1 -0
- package/dist-server/server/providers/cursor/adapter.js +347 -0
- package/dist-server/server/providers/cursor/adapter.js.map +1 -0
- package/dist-server/server/providers/gemini/adapter.js +174 -0
- package/dist-server/server/providers/gemini/adapter.js.map +1 -0
- package/dist-server/server/providers/registry.js +39 -0
- package/dist-server/server/providers/registry.js.map +1 -0
- package/dist-server/server/providers/types.js +106 -0
- package/dist-server/server/providers/types.js.map +1 -0
- package/dist-server/server/providers/utils.js +28 -0
- package/dist-server/server/providers/utils.js.map +1 -0
- package/dist-server/server/routes/agent.js +1147 -0
- package/dist-server/server/routes/agent.js.map +1 -0
- package/dist-server/server/routes/auth.js +117 -0
- package/dist-server/server/routes/auth.js.map +1 -0
- package/dist-server/server/routes/cli-auth.js +406 -0
- package/dist-server/server/routes/cli-auth.js.map +1 -0
- package/dist-server/server/routes/codex.js +294 -0
- package/dist-server/server/routes/codex.js.map +1 -0
- package/dist-server/server/routes/commands.js +531 -0
- package/dist-server/server/routes/commands.js.map +1 -0
- package/dist-server/server/routes/cursor.js +545 -0
- package/dist-server/server/routes/cursor.js.map +1 -0
- package/dist-server/server/routes/gemini.js +21 -0
- package/dist-server/server/routes/gemini.js.map +1 -0
- package/dist-server/server/routes/git.js +1259 -0
- package/dist-server/server/routes/git.js.map +1 -0
- package/dist-server/server/routes/mcp-utils.js +46 -0
- package/dist-server/server/routes/mcp-utils.js.map +1 -0
- package/dist-server/server/routes/mcp.js +480 -0
- package/dist-server/server/routes/mcp.js.map +1 -0
- package/dist-server/server/routes/messages.js +56 -0
- package/dist-server/server/routes/messages.js.map +1 -0
- package/dist-server/server/routes/plugins.js +266 -0
- package/dist-server/server/routes/plugins.js.map +1 -0
- package/dist-server/server/routes/projects.js +505 -0
- package/dist-server/server/routes/projects.js.map +1 -0
- package/dist-server/server/routes/settings.js +249 -0
- package/dist-server/server/routes/settings.js.map +1 -0
- package/dist-server/server/routes/taskmaster.js +1832 -0
- package/dist-server/server/routes/taskmaster.js.map +1 -0
- package/dist-server/server/routes/user.js +115 -0
- package/dist-server/server/routes/user.js.map +1 -0
- package/dist-server/server/services/notification-orchestrator.js +177 -0
- package/dist-server/server/services/notification-orchestrator.js.map +1 -0
- package/dist-server/server/services/vapid-keys.js +26 -0
- package/dist-server/server/services/vapid-keys.js.map +1 -0
- package/dist-server/server/sessionManager.js +194 -0
- package/dist-server/server/sessionManager.js.map +1 -0
- package/dist-server/server/utils/commandParser.js +255 -0
- package/dist-server/server/utils/commandParser.js.map +1 -0
- package/dist-server/server/utils/frontmatter.js +16 -0
- package/dist-server/server/utils/frontmatter.js.map +1 -0
- package/dist-server/server/utils/gitConfig.js +36 -0
- package/dist-server/server/utils/gitConfig.js.map +1 -0
- package/dist-server/server/utils/mcp-detector.js +183 -0
- package/dist-server/server/utils/mcp-detector.js.map +1 -0
- package/dist-server/server/utils/plugin-loader.js +413 -0
- package/dist-server/server/utils/plugin-loader.js.map +1 -0
- package/dist-server/server/utils/plugin-process-manager.js +163 -0
- package/dist-server/server/utils/plugin-process-manager.js.map +1 -0
- package/dist-server/server/utils/runtime-paths.js +30 -0
- package/dist-server/server/utils/runtime-paths.js.map +1 -0
- package/dist-server/server/utils/taskmaster-websocket.js +118 -0
- package/dist-server/server/utils/taskmaster-websocket.js.map +1 -0
- package/dist-server/shared/modelConstants.js +87 -0
- package/dist-server/shared/modelConstants.js.map +1 -0
- package/dist-server/shared/networkHosts.js +20 -0
- package/dist-server/shared/networkHosts.js.map +1 -0
- package/package.json +21 -10
- package/server/cli.js +35 -33
- package/server/database/db.js +24 -61
- package/server/database/schema.js +102 -0
- package/server/index.js +12 -12
- package/server/load-env.js +11 -6
- package/server/routes/commands.js +6 -4
- package/server/routes/cursor.js +0 -218
- package/server/tsconfig.json +33 -0
- package/server/utils/runtime-paths.js +37 -0
- package/shared/modelConstants.js +4 -2
- package/server/database/init.sql +0 -99
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini provider adapter.
|
|
3
|
+
*
|
|
4
|
+
* Normalizes Gemini CLI session history into NormalizedMessage format.
|
|
5
|
+
* @module adapters/gemini
|
|
6
|
+
*/
|
|
7
|
+
import sessionManager from '../../sessionManager.js';
|
|
8
|
+
import { getGeminiCliSessionMessages } from '../../projects.js';
|
|
9
|
+
import { createNormalizedMessage, generateMessageId } from '../types.js';
|
|
10
|
+
const PROVIDER = 'gemini';
|
|
11
|
+
/**
|
|
12
|
+
* Normalize a realtime NDJSON event from Gemini CLI into NormalizedMessage(s).
|
|
13
|
+
* Handles: message (delta/final), tool_use, tool_result, result, error.
|
|
14
|
+
* @param {object} raw - A parsed NDJSON event
|
|
15
|
+
* @param {string} sessionId
|
|
16
|
+
* @returns {import('../types.js').NormalizedMessage[]}
|
|
17
|
+
*/
|
|
18
|
+
export function normalizeMessage(raw, sessionId) {
|
|
19
|
+
const ts = raw.timestamp || new Date().toISOString();
|
|
20
|
+
const baseId = raw.uuid || generateMessageId('gemini');
|
|
21
|
+
if (raw.type === 'message' && raw.role === 'assistant') {
|
|
22
|
+
const content = raw.content || '';
|
|
23
|
+
const msgs = [];
|
|
24
|
+
if (content) {
|
|
25
|
+
msgs.push(createNormalizedMessage({ id: baseId, sessionId, timestamp: ts, provider: PROVIDER, kind: 'stream_delta', content }));
|
|
26
|
+
}
|
|
27
|
+
// If not a delta, also send stream_end
|
|
28
|
+
if (raw.delta !== true) {
|
|
29
|
+
msgs.push(createNormalizedMessage({ sessionId, timestamp: ts, provider: PROVIDER, kind: 'stream_end' }));
|
|
30
|
+
}
|
|
31
|
+
return msgs;
|
|
32
|
+
}
|
|
33
|
+
if (raw.type === 'tool_use') {
|
|
34
|
+
return [createNormalizedMessage({
|
|
35
|
+
id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
|
|
36
|
+
kind: 'tool_use', toolName: raw.tool_name, toolInput: raw.parameters || {},
|
|
37
|
+
toolId: raw.tool_id || baseId,
|
|
38
|
+
})];
|
|
39
|
+
}
|
|
40
|
+
if (raw.type === 'tool_result') {
|
|
41
|
+
return [createNormalizedMessage({
|
|
42
|
+
id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
|
|
43
|
+
kind: 'tool_result', toolId: raw.tool_id || '',
|
|
44
|
+
content: raw.output === undefined ? '' : String(raw.output),
|
|
45
|
+
isError: raw.status === 'error',
|
|
46
|
+
})];
|
|
47
|
+
}
|
|
48
|
+
if (raw.type === 'result') {
|
|
49
|
+
const msgs = [createNormalizedMessage({ sessionId, timestamp: ts, provider: PROVIDER, kind: 'stream_end' })];
|
|
50
|
+
if (raw.stats?.total_tokens) {
|
|
51
|
+
msgs.push(createNormalizedMessage({
|
|
52
|
+
sessionId, timestamp: ts, provider: PROVIDER,
|
|
53
|
+
kind: 'status', text: 'Complete', tokens: raw.stats.total_tokens, canInterrupt: false,
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
return msgs;
|
|
57
|
+
}
|
|
58
|
+
if (raw.type === 'error') {
|
|
59
|
+
return [createNormalizedMessage({
|
|
60
|
+
id: baseId, sessionId, timestamp: ts, provider: PROVIDER,
|
|
61
|
+
kind: 'error', content: raw.error || raw.message || 'Unknown Gemini streaming error',
|
|
62
|
+
})];
|
|
63
|
+
}
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @type {import('../types.js').ProviderAdapter}
|
|
68
|
+
*/
|
|
69
|
+
export const geminiAdapter = {
|
|
70
|
+
normalizeMessage,
|
|
71
|
+
/**
|
|
72
|
+
* Fetch session history for Gemini.
|
|
73
|
+
* First tries in-memory session manager, then falls back to CLI sessions on disk.
|
|
74
|
+
*/
|
|
75
|
+
async fetchHistory(sessionId, opts = {}) {
|
|
76
|
+
let rawMessages;
|
|
77
|
+
try {
|
|
78
|
+
rawMessages = sessionManager.getSessionMessages(sessionId);
|
|
79
|
+
// Fallback to Gemini CLI sessions on disk
|
|
80
|
+
if (rawMessages.length === 0) {
|
|
81
|
+
rawMessages = await getGeminiCliSessionMessages(sessionId);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.warn(`[GeminiAdapter] Failed to load session ${sessionId}:`, error.message);
|
|
86
|
+
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
|
|
87
|
+
}
|
|
88
|
+
const normalized = [];
|
|
89
|
+
for (let i = 0; i < rawMessages.length; i++) {
|
|
90
|
+
const raw = rawMessages[i];
|
|
91
|
+
const ts = raw.timestamp || new Date().toISOString();
|
|
92
|
+
const baseId = raw.uuid || generateMessageId('gemini');
|
|
93
|
+
// sessionManager format: { type: 'message', message: { role, content }, timestamp }
|
|
94
|
+
// CLI format: { role: 'user'|'gemini'|'assistant', content: string|array }
|
|
95
|
+
const role = raw.message?.role || raw.role;
|
|
96
|
+
const content = raw.message?.content || raw.content;
|
|
97
|
+
if (!role || !content)
|
|
98
|
+
continue;
|
|
99
|
+
const normalizedRole = (role === 'user') ? 'user' : 'assistant';
|
|
100
|
+
if (Array.isArray(content)) {
|
|
101
|
+
for (let partIdx = 0; partIdx < content.length; partIdx++) {
|
|
102
|
+
const part = content[partIdx];
|
|
103
|
+
if (part.type === 'text' && part.text) {
|
|
104
|
+
normalized.push(createNormalizedMessage({
|
|
105
|
+
id: `${baseId}_${partIdx}`,
|
|
106
|
+
sessionId,
|
|
107
|
+
timestamp: ts,
|
|
108
|
+
provider: PROVIDER,
|
|
109
|
+
kind: 'text',
|
|
110
|
+
role: normalizedRole,
|
|
111
|
+
content: part.text,
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
else if (part.type === 'tool_use') {
|
|
115
|
+
normalized.push(createNormalizedMessage({
|
|
116
|
+
id: `${baseId}_${partIdx}`,
|
|
117
|
+
sessionId,
|
|
118
|
+
timestamp: ts,
|
|
119
|
+
provider: PROVIDER,
|
|
120
|
+
kind: 'tool_use',
|
|
121
|
+
toolName: part.name,
|
|
122
|
+
toolInput: part.input,
|
|
123
|
+
toolId: part.id || generateMessageId('gemini_tool'),
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
else if (part.type === 'tool_result') {
|
|
127
|
+
normalized.push(createNormalizedMessage({
|
|
128
|
+
id: `${baseId}_${partIdx}`,
|
|
129
|
+
sessionId,
|
|
130
|
+
timestamp: ts,
|
|
131
|
+
provider: PROVIDER,
|
|
132
|
+
kind: 'tool_result',
|
|
133
|
+
toolId: part.tool_use_id || '',
|
|
134
|
+
content: part.content === undefined ? '' : String(part.content),
|
|
135
|
+
isError: Boolean(part.is_error),
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else if (typeof content === 'string' && content.trim()) {
|
|
141
|
+
normalized.push(createNormalizedMessage({
|
|
142
|
+
id: baseId,
|
|
143
|
+
sessionId,
|
|
144
|
+
timestamp: ts,
|
|
145
|
+
provider: PROVIDER,
|
|
146
|
+
kind: 'text',
|
|
147
|
+
role: normalizedRole,
|
|
148
|
+
content,
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Attach tool results to tool_use messages
|
|
153
|
+
const toolResultMap = new Map();
|
|
154
|
+
for (const msg of normalized) {
|
|
155
|
+
if (msg.kind === 'tool_result' && msg.toolId) {
|
|
156
|
+
toolResultMap.set(msg.toolId, msg);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const msg of normalized) {
|
|
160
|
+
if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
|
|
161
|
+
const tr = toolResultMap.get(msg.toolId);
|
|
162
|
+
msg.toolResult = { content: tr.content, isError: tr.isError };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
messages: normalized,
|
|
167
|
+
total: normalized.length,
|
|
168
|
+
hasMore: false,
|
|
169
|
+
offset: 0,
|
|
170
|
+
limit: null,
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../../server/providers/gemini/adapter.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Registry
|
|
3
|
+
*
|
|
4
|
+
* Centralizes provider adapter lookup. All code that needs a provider adapter
|
|
5
|
+
* should go through this registry instead of importing individual adapters directly.
|
|
6
|
+
*
|
|
7
|
+
* @module providers/registry
|
|
8
|
+
*/
|
|
9
|
+
import { claudeAdapter } from './claude/adapter.js';
|
|
10
|
+
import { cursorAdapter } from './cursor/adapter.js';
|
|
11
|
+
import { codexAdapter } from './codex/adapter.js';
|
|
12
|
+
import { geminiAdapter } from './gemini/adapter.js';
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {import('./types.js').ProviderAdapter} ProviderAdapter
|
|
15
|
+
* @typedef {import('./types.js').SessionProvider} SessionProvider
|
|
16
|
+
*/
|
|
17
|
+
/** @type {Map<string, ProviderAdapter>} */
|
|
18
|
+
const providers = new Map();
|
|
19
|
+
// Register built-in providers
|
|
20
|
+
providers.set('claude', claudeAdapter);
|
|
21
|
+
providers.set('cursor', cursorAdapter);
|
|
22
|
+
providers.set('codex', codexAdapter);
|
|
23
|
+
providers.set('gemini', geminiAdapter);
|
|
24
|
+
/**
|
|
25
|
+
* Get a provider adapter by name.
|
|
26
|
+
* @param {string} name - Provider name (e.g., 'claude', 'cursor', 'codex', 'gemini')
|
|
27
|
+
* @returns {ProviderAdapter | undefined}
|
|
28
|
+
*/
|
|
29
|
+
export function getProvider(name) {
|
|
30
|
+
return providers.get(name);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get all registered provider names.
|
|
34
|
+
* @returns {string[]}
|
|
35
|
+
*/
|
|
36
|
+
export function getAllProviders() {
|
|
37
|
+
return Array.from(providers.keys());
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../server/providers/registry.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;GAGG;AAEH,2CAA2C;AAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;AAE5B,8BAA8B;AAC9B,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AACvC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AACvC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AACrC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAI;IAC9B,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Types & Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the normalized message format and the provider adapter interface.
|
|
5
|
+
* All providers normalize their native formats into NormalizedMessage
|
|
6
|
+
* before sending over REST or WebSocket.
|
|
7
|
+
*
|
|
8
|
+
* @module providers/types
|
|
9
|
+
*/
|
|
10
|
+
// ─── Session Provider ────────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {'claude' | 'cursor' | 'codex' | 'gemini'} SessionProvider
|
|
13
|
+
*/
|
|
14
|
+
// ─── Message Kind ────────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {'text' | 'tool_use' | 'tool_result' | 'thinking' | 'stream_delta' | 'stream_end'
|
|
17
|
+
* | 'error' | 'complete' | 'status' | 'permission_request' | 'permission_cancelled'
|
|
18
|
+
* | 'session_created' | 'interactive_prompt' | 'task_notification'} MessageKind
|
|
19
|
+
*/
|
|
20
|
+
// ─── NormalizedMessage ───────────────────────────────────────────────────────
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {Object} NormalizedMessage
|
|
23
|
+
* @property {string} id - Unique message id (for dedup between server + realtime)
|
|
24
|
+
* @property {string} sessionId
|
|
25
|
+
* @property {string} timestamp - ISO 8601
|
|
26
|
+
* @property {SessionProvider} provider
|
|
27
|
+
* @property {MessageKind} kind
|
|
28
|
+
*
|
|
29
|
+
* Additional fields depending on kind:
|
|
30
|
+
* - text: role ('user'|'assistant'), content, images?
|
|
31
|
+
* - tool_use: toolName, toolInput, toolId
|
|
32
|
+
* - tool_result: toolId, content, isError
|
|
33
|
+
* - thinking: content
|
|
34
|
+
* - stream_delta: content
|
|
35
|
+
* - stream_end: (no extra fields)
|
|
36
|
+
* - error: content
|
|
37
|
+
* - complete: (no extra fields)
|
|
38
|
+
* - status: text, tokens?, canInterrupt?
|
|
39
|
+
* - permission_request: requestId, toolName, input, context?
|
|
40
|
+
* - permission_cancelled: requestId
|
|
41
|
+
* - session_created: newSessionId
|
|
42
|
+
* - interactive_prompt: content
|
|
43
|
+
* - task_notification: status, summary
|
|
44
|
+
*/
|
|
45
|
+
// ─── Fetch History ───────────────────────────────────────────────────────────
|
|
46
|
+
/**
|
|
47
|
+
* @typedef {Object} FetchHistoryOptions
|
|
48
|
+
* @property {string} [projectName] - Project name (required for Claude)
|
|
49
|
+
* @property {string} [projectPath] - Absolute project path (required for Cursor cwdId hash)
|
|
50
|
+
* @property {number|null} [limit] - Page size (null = all messages)
|
|
51
|
+
* @property {number} [offset] - Pagination offset (default: 0)
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* @typedef {Object} FetchHistoryResult
|
|
55
|
+
* @property {NormalizedMessage[]} messages - Normalized messages
|
|
56
|
+
* @property {number} total - Total number of messages in the session
|
|
57
|
+
* @property {boolean} hasMore - Whether more messages exist before the current page
|
|
58
|
+
* @property {number} offset - Current offset
|
|
59
|
+
* @property {number|null} limit - Page size used
|
|
60
|
+
* @property {object} [tokenUsage] - Token usage data (provider-specific)
|
|
61
|
+
*/
|
|
62
|
+
// ─── Provider Adapter Interface ──────────────────────────────────────────────
|
|
63
|
+
/**
|
|
64
|
+
* Every provider adapter MUST implement this interface.
|
|
65
|
+
*
|
|
66
|
+
* @typedef {Object} ProviderAdapter
|
|
67
|
+
*
|
|
68
|
+
* @property {(sessionId: string, opts?: FetchHistoryOptions) => Promise<FetchHistoryResult>} fetchHistory
|
|
69
|
+
* Read persisted session messages from disk/database and return them as NormalizedMessage[].
|
|
70
|
+
* The backend calls this from the unified GET /api/sessions/:id/messages endpoint.
|
|
71
|
+
*
|
|
72
|
+
* Provider implementations:
|
|
73
|
+
* - Claude: reads ~/.claude/projects/{projectName}/*.jsonl
|
|
74
|
+
* - Cursor: reads from SQLite store.db (via normalizeCursorBlobs helper)
|
|
75
|
+
* - Codex: reads ~/.codex/sessions/*.jsonl
|
|
76
|
+
* - Gemini: reads from in-memory sessionManager or ~/.gemini/tmp/ JSON files
|
|
77
|
+
*
|
|
78
|
+
* @property {(raw: any, sessionId: string) => NormalizedMessage[]} normalizeMessage
|
|
79
|
+
* Normalize a provider-specific event (JSONL entry or live SDK event) into NormalizedMessage[].
|
|
80
|
+
* Used by provider files to convert both history and realtime events.
|
|
81
|
+
*/
|
|
82
|
+
// ─── Runtime Helpers ─────────────────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Generate a unique message ID.
|
|
85
|
+
* Uses crypto.randomUUID() to avoid collisions across server restarts and workers.
|
|
86
|
+
* @param {string} [prefix='msg'] - Optional prefix
|
|
87
|
+
* @returns {string}
|
|
88
|
+
*/
|
|
89
|
+
export function generateMessageId(prefix = 'msg') {
|
|
90
|
+
return `${prefix}_${crypto.randomUUID()}`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create a NormalizedMessage with common fields pre-filled.
|
|
94
|
+
* @param {Partial<NormalizedMessage> & {kind: MessageKind, provider: SessionProvider}} fields
|
|
95
|
+
* @returns {NormalizedMessage}
|
|
96
|
+
*/
|
|
97
|
+
export function createNormalizedMessage(fields) {
|
|
98
|
+
return {
|
|
99
|
+
...fields,
|
|
100
|
+
id: fields.id || generateMessageId(fields.kind),
|
|
101
|
+
sessionId: fields.sessionId || '',
|
|
102
|
+
timestamp: fields.timestamp || new Date().toISOString(),
|
|
103
|
+
provider: fields.provider,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../server/providers/types.js"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,gFAAgF;AAEhF;;GAEG;AAEH,gFAAgF;AAEhF;;;;GAIG;AAEH,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,gFAAgF;AAEhF;;;;;;GAMG;AAEH;;;;;;;;GAQG;AAEH,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;GAkBG;AAEH,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAM,GAAG,KAAK;IAC9C,OAAO,GAAG,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAM;IAC5C,OAAO;QACL,GAAG,MAAM;QACT,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC;QAC/C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACvD,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared provider utilities.
|
|
3
|
+
*
|
|
4
|
+
* @module providers/utils
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Prefixes that indicate internal/system content which should be hidden from the UI.
|
|
8
|
+
* @type {readonly string[]}
|
|
9
|
+
*/
|
|
10
|
+
export const INTERNAL_CONTENT_PREFIXES = Object.freeze([
|
|
11
|
+
'<command-name>',
|
|
12
|
+
'<command-message>',
|
|
13
|
+
'<command-args>',
|
|
14
|
+
'<local-command-stdout>',
|
|
15
|
+
'<system-reminder>',
|
|
16
|
+
'Caveat:',
|
|
17
|
+
'This session is being continued from a previous',
|
|
18
|
+
'[Request interrupted',
|
|
19
|
+
]);
|
|
20
|
+
/**
|
|
21
|
+
* Check if user text content is internal/system that should be skipped.
|
|
22
|
+
* @param {string} content
|
|
23
|
+
* @returns {boolean}
|
|
24
|
+
*/
|
|
25
|
+
export function isInternalContent(content) {
|
|
26
|
+
return INTERNAL_CONTENT_PREFIXES.some(prefix => content.startsWith(prefix));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../server/providers/utils.js"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrD,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;IAChB,wBAAwB;IACxB,mBAAmB;IACnB,SAAS;IACT,iDAAiD;IACjD,sBAAsB;CACvB,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAO;IACvC,OAAO,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9E,CAAC"}
|