agentstudio 0.1.8 → 0.1.10

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 (182) hide show
  1. package/README.md +481 -37
  2. package/README.zh-CN.md +525 -0
  3. package/{dist → backend/dist}/bin/agentstudio.js +7 -5
  4. package/backend/dist/bin/agentstudio.js.map +1 -0
  5. package/backend/dist/index.d.ts +3 -0
  6. package/backend/dist/index.d.ts.map +1 -0
  7. package/{dist → backend/dist}/index.js +9 -28
  8. package/{dist → backend/dist}/index.js.map +1 -1
  9. package/{dist → backend/dist}/routes/settings.js +1 -1
  10. package/{dist → backend/dist}/routes/settings.js.map +1 -1
  11. package/package.json +35 -43
  12. package/.cc-sessions/ppt-editor/session_1756253549429_uau1hm6lh.json +0 -665
  13. package/.cc-sessions/ppt-editor/session_1756257240855_v0wa26mde.json +0 -394
  14. package/.env +0 -15
  15. package/dist/bin/agentstudio.js.map +0 -1
  16. package/dist/index.d.ts +0 -2
  17. package/dist/index.d.ts.map +0 -1
  18. package/docs/chat-clean-1.svg +0 -1
  19. package/docs/chat-clean.md +0 -60
  20. package/docs/chat-comprehensive-1.svg +0 -1
  21. package/docs/chat-comprehensive.md +0 -166
  22. package/docs/chat_api_sequence_diagram.md +0 -58
  23. package/docs/command-detection-logic.md +0 -306
  24. package/docs/command-detection-sequence.md +0 -186
  25. package/frontend/dist/assets/AgentsPage-Dqb_aqAA.js +0 -1
  26. package/frontend/dist/assets/ChatPage-BvQmXfcP.css +0 -1
  27. package/frontend/dist/assets/ChatPage-L8Paywyc.js +0 -91
  28. package/frontend/dist/assets/CommandForm-DLl7EIMS.js +0 -7
  29. package/frontend/dist/assets/CommandsPage-Bzavq0Ec.js +0 -1
  30. package/frontend/dist/assets/DashboardPage-B3o4AYFT.js +0 -15
  31. package/frontend/dist/assets/FileBrowser-DL3ayaqb.js +0 -1
  32. package/frontend/dist/assets/GeneralSettingsPage-CBN_de-V.js +0 -1
  33. package/frontend/dist/assets/LandingPage-Dl4ioKos.js +0 -1
  34. package/frontend/dist/assets/LoginPage-4QqRdiSi.js +0 -12
  35. package/frontend/dist/assets/McpPage-CY3tYiqj.js +0 -39
  36. package/frontend/dist/assets/MemorySettingsPage-DGxrok5K.js +0 -1
  37. package/frontend/dist/assets/ProjectSelector-hgmGYVFh.js +0 -1
  38. package/frontend/dist/assets/ProjectsPage-D399IM0c.js +0 -14
  39. package/frontend/dist/assets/SettingsLayout-CL_K-lzJ.js +0 -1
  40. package/frontend/dist/assets/SubagentForm-DXtTTIKg.js +0 -7
  41. package/frontend/dist/assets/SubagentsPage-Chbhj8p2.js +0 -1
  42. package/frontend/dist/assets/ToastTestPage-DT4wuN5C.js +0 -1
  43. package/frontend/dist/assets/UnifiedToolSelector-CsM9qBvs.js +0 -1
  44. package/frontend/dist/assets/VersionSettingsPage-74Q-LVgA.js +0 -5
  45. package/frontend/dist/assets/agents-ClAzIJTw.js +0 -1
  46. package/frontend/dist/assets/agents-DwCY2K8p.css +0 -1
  47. package/frontend/dist/assets/authFetch-BATQyPG5.js +0 -1
  48. package/frontend/dist/assets/data-structures-DLJedtzx.js +0 -27
  49. package/frontend/dist/assets/dateFormat-CXa8VnEC.js +0 -1
  50. package/frontend/dist/assets/index-B9YHa7XT.css +0 -1
  51. package/frontend/dist/assets/index-B_CTNvca.js +0 -268
  52. package/frontend/dist/assets/monaco-editor-C7Z4sOhS.js +0 -19
  53. package/frontend/dist/assets/syntax-highlighting-YWvMU4Hm.js +0 -24
  54. package/frontend/dist/assets/tabManager-DV8urRBM.js +0 -30
  55. package/frontend/dist/assets/table-D6q1rytw.js +0 -1
  56. package/frontend/dist/assets/tools-C4EPanYi.js +0 -1
  57. package/frontend/dist/assets/ui-components-Cw21Epuw.js +0 -481
  58. package/frontend/dist/assets/useAgents-DwnOE1_k.js +0 -2
  59. package/frontend/dist/assets/useClaudeVersions-CQdGnCqv.js +0 -1
  60. package/frontend/dist/assets/useCommands-CCVaurbt.js +0 -1
  61. package/frontend/dist/cc-studio.png +0 -0
  62. package/frontend/dist/index.html +0 -70
  63. package/frontend/dist/vite.svg +0 -1
  64. package/scripts/README.md +0 -76
  65. package/scripts/fix-project-names.js +0 -113
  66. package/scripts/migrate-projects.js +0 -159
  67. package/shared/index.d.ts +0 -6
  68. package/shared/index.d.ts.map +0 -1
  69. package/shared/index.js +0 -7
  70. package/shared/types/agents.d.ts +0 -80
  71. package/shared/types/agents.d.ts.map +0 -1
  72. package/shared/types/agents.js +0 -145
  73. package/shared/types/claude-history.d.ts +0 -61
  74. package/shared/types/claude-history.d.ts.map +0 -1
  75. package/shared/types/claude-history.js +0 -2
  76. package/shared/types/claude-versions.d.ts +0 -40
  77. package/shared/types/claude-versions.d.ts.map +0 -1
  78. package/shared/types/claude-versions.js +0 -1
  79. package/shared/types/commands.d.ts +0 -48
  80. package/shared/types/commands.d.ts.map +0 -1
  81. package/shared/types/commands.js +0 -19
  82. package/shared/types/projects.d.ts +0 -35
  83. package/shared/types/projects.d.ts.map +0 -1
  84. package/shared/types/projects.js +0 -2
  85. package/shared/types/subagents.d.ts +0 -26
  86. package/shared/types/subagents.d.ts.map +0 -1
  87. package/shared/types/subagents.js +0 -1
  88. package/shared/utils/agentStorage.d.ts +0 -27
  89. package/shared/utils/agentStorage.d.ts.map +0 -1
  90. package/shared/utils/agentStorage.js +0 -392
  91. package/shared/utils/claudeVersionStorage.d.ts +0 -16
  92. package/shared/utils/claudeVersionStorage.d.ts.map +0 -1
  93. package/shared/utils/claudeVersionStorage.js +0 -230
  94. package/shared/utils/projectMetadataStorage.d.ts +0 -94
  95. package/shared/utils/projectMetadataStorage.d.ts.map +0 -1
  96. package/shared/utils/projectMetadataStorage.js +0 -422
  97. package/shared/utils/toolMapping.d.ts +0 -56
  98. package/shared/utils/toolMapping.d.ts.map +0 -1
  99. package/shared/utils/toolMapping.js +0 -71
  100. package/src/bin/agentstudio.ts +0 -130
  101. package/src/index.ts +0 -183
  102. package/src/middleware/auth.ts +0 -26
  103. package/src/routes/agents.ts +0 -884
  104. package/src/routes/auth.ts +0 -73
  105. package/src/routes/commands.ts +0 -441
  106. package/src/routes/files.ts +0 -352
  107. package/src/routes/mcp.ts +0 -751
  108. package/src/routes/media.ts +0 -140
  109. package/src/routes/projects.ts +0 -601
  110. package/src/routes/sessions.ts +0 -809
  111. package/src/routes/settings.ts +0 -718
  112. package/src/routes/slides.ts +0 -170
  113. package/src/routes/subagents.ts +0 -364
  114. package/src/services/claudeSession.ts +0 -293
  115. package/src/services/messageQueue.ts +0 -71
  116. package/src/services/sessionManager.ts +0 -532
  117. package/src/utils/jwt.ts +0 -36
  118. package/tsconfig.json +0 -27
  119. /package/{dist → backend/dist}/bin/agentstudio.d.ts +0 -0
  120. /package/{dist → backend/dist}/bin/agentstudio.d.ts.map +0 -0
  121. /package/{dist → backend/dist}/middleware/auth.d.ts +0 -0
  122. /package/{dist → backend/dist}/middleware/auth.d.ts.map +0 -0
  123. /package/{dist → backend/dist}/middleware/auth.js +0 -0
  124. /package/{dist → backend/dist}/middleware/auth.js.map +0 -0
  125. /package/{dist → backend/dist}/routes/agents.d.ts +0 -0
  126. /package/{dist → backend/dist}/routes/agents.d.ts.map +0 -0
  127. /package/{dist → backend/dist}/routes/agents.js +0 -0
  128. /package/{dist → backend/dist}/routes/agents.js.map +0 -0
  129. /package/{dist → backend/dist}/routes/auth.d.ts +0 -0
  130. /package/{dist → backend/dist}/routes/auth.d.ts.map +0 -0
  131. /package/{dist → backend/dist}/routes/auth.js +0 -0
  132. /package/{dist → backend/dist}/routes/auth.js.map +0 -0
  133. /package/{dist → backend/dist}/routes/commands.d.ts +0 -0
  134. /package/{dist → backend/dist}/routes/commands.d.ts.map +0 -0
  135. /package/{dist → backend/dist}/routes/commands.js +0 -0
  136. /package/{dist → backend/dist}/routes/commands.js.map +0 -0
  137. /package/{dist → backend/dist}/routes/files.d.ts +0 -0
  138. /package/{dist → backend/dist}/routes/files.d.ts.map +0 -0
  139. /package/{dist → backend/dist}/routes/files.js +0 -0
  140. /package/{dist → backend/dist}/routes/files.js.map +0 -0
  141. /package/{dist → backend/dist}/routes/mcp.d.ts +0 -0
  142. /package/{dist → backend/dist}/routes/mcp.d.ts.map +0 -0
  143. /package/{dist → backend/dist}/routes/mcp.js +0 -0
  144. /package/{dist → backend/dist}/routes/mcp.js.map +0 -0
  145. /package/{dist → backend/dist}/routes/media.d.ts +0 -0
  146. /package/{dist → backend/dist}/routes/media.d.ts.map +0 -0
  147. /package/{dist → backend/dist}/routes/media.js +0 -0
  148. /package/{dist → backend/dist}/routes/media.js.map +0 -0
  149. /package/{dist → backend/dist}/routes/projects.d.ts +0 -0
  150. /package/{dist → backend/dist}/routes/projects.d.ts.map +0 -0
  151. /package/{dist → backend/dist}/routes/projects.js +0 -0
  152. /package/{dist → backend/dist}/routes/projects.js.map +0 -0
  153. /package/{dist → backend/dist}/routes/sessions.d.ts +0 -0
  154. /package/{dist → backend/dist}/routes/sessions.d.ts.map +0 -0
  155. /package/{dist → backend/dist}/routes/sessions.js +0 -0
  156. /package/{dist → backend/dist}/routes/sessions.js.map +0 -0
  157. /package/{dist → backend/dist}/routes/settings.d.ts +0 -0
  158. /package/{dist → backend/dist}/routes/settings.d.ts.map +0 -0
  159. /package/{dist → backend/dist}/routes/slides.d.ts +0 -0
  160. /package/{dist → backend/dist}/routes/slides.d.ts.map +0 -0
  161. /package/{dist → backend/dist}/routes/slides.js +0 -0
  162. /package/{dist → backend/dist}/routes/slides.js.map +0 -0
  163. /package/{dist → backend/dist}/routes/subagents.d.ts +0 -0
  164. /package/{dist → backend/dist}/routes/subagents.d.ts.map +0 -0
  165. /package/{dist → backend/dist}/routes/subagents.js +0 -0
  166. /package/{dist → backend/dist}/routes/subagents.js.map +0 -0
  167. /package/{dist → backend/dist}/services/claudeSession.d.ts +0 -0
  168. /package/{dist → backend/dist}/services/claudeSession.d.ts.map +0 -0
  169. /package/{dist → backend/dist}/services/claudeSession.js +0 -0
  170. /package/{dist → backend/dist}/services/claudeSession.js.map +0 -0
  171. /package/{dist → backend/dist}/services/messageQueue.d.ts +0 -0
  172. /package/{dist → backend/dist}/services/messageQueue.d.ts.map +0 -0
  173. /package/{dist → backend/dist}/services/messageQueue.js +0 -0
  174. /package/{dist → backend/dist}/services/messageQueue.js.map +0 -0
  175. /package/{dist → backend/dist}/services/sessionManager.d.ts +0 -0
  176. /package/{dist → backend/dist}/services/sessionManager.d.ts.map +0 -0
  177. /package/{dist → backend/dist}/services/sessionManager.js +0 -0
  178. /package/{dist → backend/dist}/services/sessionManager.js.map +0 -0
  179. /package/{dist → backend/dist}/utils/jwt.d.ts +0 -0
  180. /package/{dist → backend/dist}/utils/jwt.d.ts.map +0 -0
  181. /package/{dist → backend/dist}/utils/jwt.js +0 -0
  182. /package/{dist → backend/dist}/utils/jwt.js.map +0 -0
@@ -1,392 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- import * as os from 'os';
4
- import { BUILTIN_AGENTS } from '../types/agents.js';
5
- import { query } from '@anthropic-ai/claude-code';
6
- export class AgentStorage {
7
- agentsDir;
8
- workingDir;
9
- constructor(workingDir = process.cwd()) {
10
- const baseDir = path.join(os.homedir(), '.claude-agent');
11
- this.agentsDir = path.join(baseDir, 'agents');
12
- this.workingDir = workingDir;
13
- // Ensure directories exist
14
- this.ensureDirectoriesExist();
15
- // Initialize built-in agents if not exists
16
- this.initializeBuiltinAgents();
17
- }
18
- ensureDirectoriesExist() {
19
- // Ensure global agents directory exists
20
- if (!fs.existsSync(this.agentsDir)) {
21
- fs.mkdirSync(this.agentsDir, { recursive: true });
22
- }
23
- }
24
- getSessionsDir() {
25
- const sessionsDir = path.join(this.workingDir, '.cc-sessions');
26
- // console.log('AgentStorage getSessionsDir - workingDir:', this.workingDir, 'sessionsDir:', sessionsDir);
27
- if (!fs.existsSync(sessionsDir)) {
28
- fs.mkdirSync(sessionsDir, { recursive: true });
29
- }
30
- return sessionsDir;
31
- }
32
- initializeBuiltinAgents() {
33
- BUILTIN_AGENTS.forEach(agentTemplate => {
34
- const agentPath = path.join(this.agentsDir, `${agentTemplate.id}.json`);
35
- if (!fs.existsSync(agentPath)) {
36
- const now = new Date().toISOString();
37
- const fullAgent = {
38
- version: '1.0.0',
39
- maxTurns: 25,
40
- permissionMode: 'acceptEdits',
41
- author: 'Claude Agent System',
42
- createdAt: now,
43
- updatedAt: now,
44
- ...agentTemplate
45
- };
46
- this.saveAgent(fullAgent);
47
- }
48
- });
49
- }
50
- // Agent management
51
- getAllAgents() {
52
- const agentFiles = fs.readdirSync(this.agentsDir)
53
- .filter(file => file.endsWith('.json'));
54
- const agents = [];
55
- for (const file of agentFiles) {
56
- try {
57
- const filePath = path.join(this.agentsDir, file);
58
- const agentData = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
59
- agents.push(agentData);
60
- }
61
- catch (error) {
62
- console.error(`Failed to read agent file ${file}:`, error);
63
- }
64
- }
65
- return agents.sort((a, b) => a.name.localeCompare(b.name));
66
- }
67
- getAgent(agentId) {
68
- try {
69
- const filePath = path.join(this.agentsDir, `${agentId}.json`);
70
- if (!fs.existsSync(filePath)) {
71
- return null;
72
- }
73
- return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
74
- }
75
- catch (error) {
76
- console.error(`Failed to read agent ${agentId}:`, error);
77
- return null;
78
- }
79
- }
80
- saveAgent(agent) {
81
- try {
82
- agent.updatedAt = new Date().toISOString();
83
- const filePath = path.join(this.agentsDir, `${agent.id}.json`);
84
- fs.writeFileSync(filePath, JSON.stringify(agent, null, 2), 'utf-8');
85
- }
86
- catch (error) {
87
- console.error(`Failed to save agent ${agent.id}:`, error);
88
- throw error;
89
- }
90
- }
91
- deleteAgent(agentId) {
92
- try {
93
- const filePath = path.join(this.agentsDir, `${agentId}.json`);
94
- if (fs.existsSync(filePath)) {
95
- // Don't delete built-in agents, just disable them
96
- const agent = this.getAgent(agentId);
97
- if (agent && BUILTIN_AGENTS.some(builtin => builtin.id === agentId)) {
98
- agent.enabled = false;
99
- this.saveAgent(agent);
100
- return true;
101
- }
102
- fs.unlinkSync(filePath);
103
- // Also delete all sessions for this agent
104
- this.deleteAgentSessions(agentId);
105
- return true;
106
- }
107
- return false;
108
- }
109
- catch (error) {
110
- console.error(`Failed to delete agent ${agentId}:`, error);
111
- return false;
112
- }
113
- }
114
- createAgent(agentData) {
115
- const now = new Date().toISOString();
116
- const agent = {
117
- ...agentData,
118
- createdAt: now,
119
- updatedAt: now
120
- };
121
- this.saveAgent(agent);
122
- return agent;
123
- }
124
- // Session management
125
- getAgentSessionsDir(agentId) {
126
- const dir = path.join(this.getSessionsDir(), agentId);
127
- if (!fs.existsSync(dir)) {
128
- fs.mkdirSync(dir, { recursive: true });
129
- }
130
- return dir;
131
- }
132
- getAgentSessions(agentId, searchTerm) {
133
- const sessionsDir = this.getAgentSessionsDir(agentId);
134
- const sessionFiles = fs.readdirSync(sessionsDir)
135
- .filter(file => file.endsWith('.json'));
136
- const sessions = [];
137
- for (const file of sessionFiles) {
138
- try {
139
- const filePath = path.join(sessionsDir, file);
140
- const sessionData = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
141
- sessions.push(sessionData);
142
- }
143
- catch (error) {
144
- console.error(`Failed to read session file ${file}:`, error);
145
- }
146
- }
147
- let filteredSessions = sessions;
148
- // Filter by search term if provided
149
- if (searchTerm && searchTerm.trim()) {
150
- const searchTermLower = searchTerm.trim().toLowerCase();
151
- filteredSessions = sessions.filter(session => {
152
- if (session.title.toLowerCase().includes(searchTermLower)) {
153
- return true;
154
- }
155
- return session.messages.some(message => {
156
- if (message.content && message.content.toLowerCase().includes(searchTermLower)) {
157
- return true;
158
- }
159
- if (message.messageParts) {
160
- return message.messageParts.some(part => {
161
- if (part.type === 'text' && part.content && part.content.toLowerCase().includes(searchTermLower)) {
162
- return true;
163
- }
164
- if (part.type === 'tool' && part.toolData) {
165
- if (part.toolData.toolName.toLowerCase().includes(searchTermLower)) {
166
- return true;
167
- }
168
- const inputStr = JSON.stringify(part.toolData.toolInput).toLowerCase();
169
- if (inputStr.includes(searchTermLower)) {
170
- return true;
171
- }
172
- }
173
- return false;
174
- });
175
- }
176
- return false;
177
- });
178
- });
179
- }
180
- return filteredSessions.sort((a, b) => b.lastUpdated - a.lastUpdated);
181
- }
182
- getSession(agentId, sessionId) {
183
- try {
184
- const sessionsDir = this.getAgentSessionsDir(agentId);
185
- const filePath = path.join(sessionsDir, `${sessionId}.json`);
186
- if (!fs.existsSync(filePath)) {
187
- return null;
188
- }
189
- return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
190
- }
191
- catch (error) {
192
- console.error(`Failed to read session ${sessionId} for agent ${agentId}:`, error);
193
- return null;
194
- }
195
- }
196
- createSession(agentId, title) {
197
- const sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
198
- const agent = this.getAgent(agentId);
199
- const session = {
200
- id: sessionId,
201
- agentId,
202
- title: title || `${agent?.name || 'Agent'} 会话 ${new Date().toLocaleString()}`,
203
- createdAt: Date.now(),
204
- lastUpdated: Date.now(),
205
- messages: []
206
- };
207
- this.saveSession(session);
208
- return session;
209
- }
210
- createSessionWithId(agentId, sessionId, title) {
211
- const agent = this.getAgent(agentId);
212
- const session = {
213
- id: sessionId, // Use AI-provided session_id
214
- agentId,
215
- title: title || `${agent?.name || 'Agent'} 会话 ${new Date().toLocaleString()}`,
216
- createdAt: Date.now(),
217
- lastUpdated: Date.now(),
218
- messages: []
219
- // claudeSessionId will be set when AI returns it in init message
220
- };
221
- this.saveSession(session);
222
- return session;
223
- }
224
- saveSession(session) {
225
- try {
226
- const sessionsDir = this.getAgentSessionsDir(session.agentId);
227
- const filePath = path.join(sessionsDir, `${session.id}.json`);
228
- fs.writeFileSync(filePath, JSON.stringify(session, null, 2), 'utf-8');
229
- }
230
- catch (error) {
231
- console.error(`Failed to save session ${session.id}:`, error);
232
- throw error;
233
- }
234
- }
235
- deleteSession(agentId, sessionId) {
236
- try {
237
- const sessionsDir = this.getAgentSessionsDir(agentId);
238
- const filePath = path.join(sessionsDir, `${sessionId}.json`);
239
- if (fs.existsSync(filePath)) {
240
- fs.unlinkSync(filePath);
241
- return true;
242
- }
243
- return false;
244
- }
245
- catch (error) {
246
- console.error(`Failed to delete session ${sessionId}:`, error);
247
- return false;
248
- }
249
- }
250
- deleteAgentSessions(agentId) {
251
- try {
252
- const sessionsDir = this.getAgentSessionsDir(agentId);
253
- const sessionFiles = fs.readdirSync(sessionsDir);
254
- for (const file of sessionFiles) {
255
- if (file.endsWith('.json')) {
256
- fs.unlinkSync(path.join(sessionsDir, file));
257
- }
258
- }
259
- }
260
- catch (error) {
261
- console.error(`Failed to delete sessions for agent ${agentId}:`, error);
262
- }
263
- }
264
- // Helper method to check if session title should be updated
265
- shouldUpdateTitle(title) {
266
- return title.includes('会话') && title.includes(new Date().toLocaleString().split(' ')[0]);
267
- }
268
- // Generate intelligent session title based on first user message using Claude Code SDK
269
- async updateSessionTitle(session) {
270
- // Only update if it's still the default title
271
- if (!this.shouldUpdateTitle(session.title)) {
272
- return;
273
- }
274
- // Find the first user message
275
- const firstUserMessage = session.messages.find(msg => msg.role === 'user');
276
- if (!firstUserMessage) {
277
- return;
278
- }
279
- let userQuestion = '';
280
- // Extract text content from the message
281
- if (firstUserMessage.content) {
282
- userQuestion = firstUserMessage.content;
283
- }
284
- else if (firstUserMessage.messageParts) {
285
- userQuestion = firstUserMessage.messageParts
286
- .filter(part => part.type === 'text')
287
- .map(part => part.content)
288
- .join(' ');
289
- }
290
- if (userQuestion) {
291
- try {
292
- // Use Claude Code SDK to generate a concise title
293
- const titlePrompt = `请为以下用户问题生成一个简洁的标题(不超过25个字符),用于会话列表显示:
294
-
295
- 用户问题:${userQuestion}
296
-
297
- 要求:
298
- 1. 提取问题的核心要点
299
- 2. 使用简洁明了的中文
300
- 3. 不超过25个字符
301
- 4. 不需要引号或其他标点符号
302
- 5. 直接输出标题内容,不要任何前缀或后缀`;
303
- const queryOptions = {
304
- customSystemPrompt: "你是一个专门生成简洁标题的助手。请直接输出标题内容,不要任何解释或格式化。",
305
- allowedTools: [], // No tools needed for title generation
306
- maxTurns: 1,
307
- cwd: process.cwd()
308
- };
309
- let generatedTitle = '';
310
- for await (const sdkMessage of query({
311
- prompt: titlePrompt,
312
- options: queryOptions
313
- })) {
314
- if (sdkMessage.type === 'assistant' && sdkMessage.message?.content) {
315
- for (const block of sdkMessage.message.content) {
316
- if (block.type === 'text') {
317
- generatedTitle += block.text;
318
- }
319
- }
320
- }
321
- }
322
- if (generatedTitle.trim()) {
323
- // Clean the generated title
324
- let cleanTitle = generatedTitle.trim()
325
- .replace(/^["'"']|["'"']$/g, '') // Remove quotes
326
- .replace(/\n/g, ' ') // Replace newlines
327
- .replace(/\s+/g, ' '); // Collapse spaces
328
- // Ensure it's not too long
329
- if (cleanTitle.length > 30) {
330
- cleanTitle = cleanTitle.substring(0, 27) + '...';
331
- }
332
- session.title = cleanTitle;
333
- console.log(`Generated title for session ${session.id}: "${cleanTitle}"`);
334
- }
335
- else {
336
- // Fallback to simple truncation if AI generation fails
337
- this.fallbackTitleGeneration(session, userQuestion);
338
- }
339
- }
340
- catch (error) {
341
- console.error('Failed to update session title with Claude SDK:', error);
342
- // Fallback to simple truncation
343
- this.fallbackTitleGeneration(session, userQuestion);
344
- }
345
- }
346
- }
347
- // Fallback title generation when Claude SDK fails
348
- fallbackTitleGeneration(session, userQuestion) {
349
- let fallbackTitle = userQuestion.trim()
350
- .replace(/\n/g, ' ')
351
- .replace(/\s+/g, ' ')
352
- .substring(0, 25);
353
- // Take first sentence if it's reasonable
354
- const firstSentence = fallbackTitle.split(/[.!?。!?]/)[0];
355
- if (firstSentence.length > 8 && firstSentence.length < 25) {
356
- fallbackTitle = firstSentence;
357
- }
358
- if (fallbackTitle.length > 22) {
359
- fallbackTitle = fallbackTitle.substring(0, 22) + '...';
360
- }
361
- session.title = fallbackTitle;
362
- console.log(`Fallback title for session ${session.id}: "${fallbackTitle}"`);
363
- }
364
- addMessageToSession(agentId, sessionId, message) {
365
- const session = this.getSession(agentId, sessionId);
366
- if (!session) {
367
- return null;
368
- }
369
- const newMessage = {
370
- ...message,
371
- id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
372
- timestamp: Date.now(),
373
- messageParts: message.messageParts || [],
374
- agentId
375
- };
376
- session.messages.push(newMessage);
377
- session.lastUpdated = Date.now();
378
- // Save session first, then update title asynchronously
379
- this.saveSession(session);
380
- // Update session title based on first user message (async, doesn't block)
381
- if (message.role === 'user' && this.shouldUpdateTitle(session.title)) {
382
- this.updateSessionTitle(session).then(() => {
383
- // Save again after title is updated
384
- this.saveSession(session);
385
- console.log(`Session title updated to: "${session.title}"`);
386
- }).catch(err => {
387
- console.error('Failed to update session title:', err);
388
- });
389
- }
390
- return newMessage;
391
- }
392
- }
@@ -1,16 +0,0 @@
1
- import { ClaudeVersion, ClaudeVersionCreate, ClaudeVersionUpdate } from '../types/claude-versions.js';
2
- interface VersionStorage {
3
- versions: ClaudeVersion[];
4
- defaultVersionId: string | null;
5
- }
6
- export declare function loadClaudeVersions(): Promise<VersionStorage>;
7
- export declare function saveClaudeVersions(storage: VersionStorage): Promise<void>;
8
- export declare function getAllVersions(): Promise<ClaudeVersion[]>;
9
- export declare function getDefaultVersionId(): Promise<string | null>;
10
- export declare function setDefaultVersion(versionId: string): Promise<void>;
11
- export declare function createVersion(data: ClaudeVersionCreate): Promise<ClaudeVersion>;
12
- export declare function updateVersion(versionId: string, data: ClaudeVersionUpdate): Promise<ClaudeVersion>;
13
- export declare function deleteVersion(versionId: string): Promise<void>;
14
- export declare function initializeSystemVersion(executablePath: string): Promise<ClaudeVersion>;
15
- export {};
16
- //# sourceMappingURL=claudeVersionStorage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claudeVersionStorage.d.ts","sourceRoot":"","sources":["../../src/utils/claudeVersionStorage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAe,MAAM,6BAA6B,CAAC;AAqBnH,UAAU,cAAc;IACtB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAuCD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,cAAc,CAAC,CAwBlE;AAGD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAK/E;AAQD,wBAAsB,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAG/D;AAGD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGlE;AAGD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWxE;AAGD,wBAAsB,aAAa,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiCrF;AAGD,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA6CxG;AAGD,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBpE;AAGD,wBAAsB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAyC5F"}
@@ -1,230 +0,0 @@
1
- import { readFile, writeFile, mkdir } from 'fs/promises';
2
- import { join } from 'path';
3
- import { homedir } from 'os';
4
- // 默认模型配置(用于Claude系统版本)
5
- const DEFAULT_MODELS = [
6
- {
7
- id: 'sonnet',
8
- name: 'Sonnet',
9
- isVision: true,
10
- description: 'Claude 3.5 Sonnet - 平衡性能和成本的模型'
11
- },
12
- {
13
- id: 'opus',
14
- name: 'Opus',
15
- isVision: true,
16
- description: 'Claude 3 Opus - 最强大的模型'
17
- }
18
- ];
19
- const CLAUDE_AGENT_DIR = join(homedir(), '.claude-agent');
20
- const VERSIONS_FILE = join(CLAUDE_AGENT_DIR, 'claude-versions.json');
21
- // 确保目录存在
22
- async function ensureClaudeAgentDir() {
23
- try {
24
- await mkdir(CLAUDE_AGENT_DIR, { recursive: true });
25
- }
26
- catch (error) {
27
- // 忽略目录已存在的错误
28
- }
29
- }
30
- // 数据迁移:为旧版本添加models字段
31
- function migrateVersionData(storage) {
32
- let needsSave = false;
33
- const migratedVersions = storage.versions.map(version => {
34
- // 如果版本没有models字段,添加默认模型
35
- if (!version.models || version.models.length === 0) {
36
- needsSave = true;
37
- return {
38
- ...version,
39
- models: DEFAULT_MODELS
40
- };
41
- }
42
- return version;
43
- });
44
- const result = {
45
- ...storage,
46
- versions: migratedVersions
47
- };
48
- // 标记是否需要保存
49
- result._needsSave = needsSave;
50
- return result;
51
- }
52
- // 读取版本配置
53
- export async function loadClaudeVersions() {
54
- await ensureClaudeAgentDir();
55
- try {
56
- const content = await readFile(VERSIONS_FILE, 'utf-8');
57
- const storage = JSON.parse(content);
58
- // 执行数据迁移
59
- const migrated = migrateVersionData(storage);
60
- // 如果数据有变化,保存回文件
61
- if (migrated._needsSave) {
62
- delete migrated._needsSave;
63
- await saveClaudeVersions(migrated);
64
- }
65
- return migrated;
66
- }
67
- catch (error) {
68
- // 文件不存在或解析失败,返回默认配置
69
- return {
70
- versions: [],
71
- defaultVersionId: null
72
- };
73
- }
74
- }
75
- // 保存版本配置
76
- export async function saveClaudeVersions(storage) {
77
- await ensureClaudeAgentDir();
78
- const content = JSON.stringify(storage, null, 2);
79
- await writeFile(VERSIONS_FILE, content, 'utf-8');
80
- }
81
- // 生成唯一ID
82
- function generateId() {
83
- return Date.now().toString(36) + Math.random().toString(36).substr(2);
84
- }
85
- // 获取所有版本
86
- export async function getAllVersions() {
87
- const storage = await loadClaudeVersions();
88
- return storage.versions;
89
- }
90
- // 获取默认版本ID
91
- export async function getDefaultVersionId() {
92
- const storage = await loadClaudeVersions();
93
- return storage.defaultVersionId;
94
- }
95
- // 设置默认版本
96
- export async function setDefaultVersion(versionId) {
97
- const storage = await loadClaudeVersions();
98
- // 检查版本是否存在
99
- const version = storage.versions.find(v => v.id === versionId);
100
- if (!version) {
101
- throw new Error('版本不存在');
102
- }
103
- storage.defaultVersionId = versionId;
104
- await saveClaudeVersions(storage);
105
- }
106
- // 创建新版本
107
- export async function createVersion(data) {
108
- const storage = await loadClaudeVersions();
109
- // 检查别名是否已存在
110
- const existingAlias = storage.versions.find(v => v.alias === data.alias);
111
- if (existingAlias) {
112
- throw new Error('别名已存在');
113
- }
114
- const now = new Date().toISOString();
115
- const newVersion = {
116
- id: generateId(),
117
- name: data.name,
118
- alias: data.alias,
119
- description: data.description,
120
- executablePath: data.executablePath,
121
- isDefault: storage.versions.length === 0, // 第一个版本默认为默认版本
122
- isSystem: false,
123
- environmentVariables: data.environmentVariables || {},
124
- models: data.models || DEFAULT_MODELS, // 使用提供的模型或默认模型
125
- createdAt: now,
126
- updatedAt: now
127
- };
128
- storage.versions.push(newVersion);
129
- // 如果这是第一个版本,设置为默认版本
130
- if (storage.versions.length === 1) {
131
- storage.defaultVersionId = newVersion.id;
132
- }
133
- await saveClaudeVersions(storage);
134
- return newVersion;
135
- }
136
- // 更新版本
137
- export async function updateVersion(versionId, data) {
138
- const storage = await loadClaudeVersions();
139
- const versionIndex = storage.versions.findIndex(v => v.id === versionId);
140
- if (versionIndex === -1) {
141
- throw new Error('版本不存在');
142
- }
143
- const version = storage.versions[versionIndex];
144
- // 检查别名冲突(如果修改了别名)
145
- if (data.alias && data.alias !== version.alias) {
146
- const existingAlias = storage.versions.find(v => v.alias === data.alias && v.id !== versionId);
147
- if (existingAlias) {
148
- throw new Error('别名已存在');
149
- }
150
- }
151
- // 不允许修改系统版本的某些属性
152
- if (version.isSystem) {
153
- if (data.executablePath && data.executablePath !== version.executablePath) {
154
- throw new Error('不允许修改系统版本的可执行路径');
155
- }
156
- }
157
- // 合并更新数据,允许 undefined 值以便删除字段
158
- const updatedVersion = {
159
- ...version,
160
- ...data,
161
- updatedAt: new Date().toISOString()
162
- };
163
- // 对于明确设置为 undefined 的可选字段,从对象中删除
164
- // 这样 JSON.stringify 就不会保存这些字段
165
- if (data.executablePath === undefined) {
166
- delete updatedVersion.executablePath;
167
- }
168
- if (data.description === undefined) {
169
- delete updatedVersion.description;
170
- }
171
- storage.versions[versionIndex] = updatedVersion;
172
- await saveClaudeVersions(storage);
173
- return updatedVersion;
174
- }
175
- // 删除版本
176
- export async function deleteVersion(versionId) {
177
- const storage = await loadClaudeVersions();
178
- const versionIndex = storage.versions.findIndex(v => v.id === versionId);
179
- if (versionIndex === -1) {
180
- throw new Error('版本不存在');
181
- }
182
- const version = storage.versions[versionIndex];
183
- // 不允许删除系统版本
184
- if (version.isSystem) {
185
- throw new Error('不允许删除系统版本');
186
- }
187
- storage.versions.splice(versionIndex, 1);
188
- // 如果删除的是默认版本,选择一个新的默认版本
189
- if (storage.defaultVersionId === versionId) {
190
- storage.defaultVersionId = storage.versions.length > 0 ? storage.versions[0].id : null;
191
- }
192
- await saveClaudeVersions(storage);
193
- }
194
- // 初始化系统版本(在启动时调用)
195
- export async function initializeSystemVersion(executablePath) {
196
- const storage = await loadClaudeVersions();
197
- // 检查是否已存在系统版本
198
- let systemVersion = storage.versions.find(v => v.isSystem);
199
- if (systemVersion) {
200
- // 更新系统版本的路径(如果有变化)
201
- if (systemVersion.executablePath !== executablePath) {
202
- systemVersion.executablePath = executablePath;
203
- systemVersion.updatedAt = new Date().toISOString();
204
- await saveClaudeVersions(storage);
205
- }
206
- return systemVersion;
207
- }
208
- // 创建系统版本
209
- const now = new Date().toISOString();
210
- systemVersion = {
211
- id: 'system',
212
- name: 'System Claude',
213
- alias: 'system',
214
- description: '系统默认的 Claude Code 版本(通过 which claude 查找)',
215
- executablePath,
216
- isDefault: storage.versions.length === 0,
217
- isSystem: true,
218
- environmentVariables: {},
219
- models: DEFAULT_MODELS, // 系统版本使用默认模型
220
- createdAt: now,
221
- updatedAt: now
222
- };
223
- storage.versions.unshift(systemVersion); // 系统版本放在最前面
224
- // 如果这是第一个版本,设置为默认版本
225
- if (storage.versions.length === 1) {
226
- storage.defaultVersionId = systemVersion.id;
227
- }
228
- await saveClaudeVersions(storage);
229
- return systemVersion;
230
- }