@myassis/gateway 1.0.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 (65) hide show
  1. package/README.md +194 -0
  2. package/dist/.env +6 -0
  3. package/dist/api/index.js +182 -0
  4. package/dist/config/index.js +41 -0
  5. package/dist/index.js +183 -0
  6. package/dist/middleware/auth.js +53 -0
  7. package/dist/middleware/errorHandler.js +20 -0
  8. package/dist/routes/agent.js +513 -0
  9. package/dist/routes/auth.js +172 -0
  10. package/dist/routes/chat.js +45 -0
  11. package/dist/routes/config.js +21 -0
  12. package/dist/routes/models.js +123 -0
  13. package/dist/routes/service.js +240 -0
  14. package/dist/routes/settings.js +101 -0
  15. package/dist/routes/skillHub.js +126 -0
  16. package/dist/routes/skills.js +159 -0
  17. package/dist/routes/tasks.js +149 -0
  18. package/dist/routes/upload.js +129 -0
  19. package/dist/routes/version.js +66 -0
  20. package/dist/services/HMSPushService.js +24 -0
  21. package/dist/services/LocalTaskService.js +223 -0
  22. package/dist/services/NotificationService.js +242 -0
  23. package/dist/services/ServiceManager.js +348 -0
  24. package/dist/services/TaskSchedulerService.js +195 -0
  25. package/dist/services/TaskService.js +240 -0
  26. package/dist/services/WebSocketService.js +236 -0
  27. package/dist/services/agent/Agent.js +120 -0
  28. package/dist/services/agent/AgentManager.js +265 -0
  29. package/dist/services/agent/AgentStore.js +73 -0
  30. package/dist/services/dataService.js +293 -0
  31. package/dist/services/index.js +15 -0
  32. package/dist/services/llm/LLMClient.js +724 -0
  33. package/dist/services/memory/MemoryManager.js +117 -0
  34. package/dist/services/model/ModelCapabilities.js +141 -0
  35. package/dist/services/model/index.js +4 -0
  36. package/dist/services/models.js +16 -0
  37. package/dist/services/session/MigrationManager.js +176 -0
  38. package/dist/services/session/Session.js +733 -0
  39. package/dist/services/session/SessionManager.js +255 -0
  40. package/dist/services/session/SessionStore.js +186 -0
  41. package/dist/services/session/index.js +3 -0
  42. package/dist/services/skills.js +34 -0
  43. package/dist/services/systemPrompt.js +150 -0
  44. package/dist/services/task/PushTokenStore.js +124 -0
  45. package/dist/services/task/TaskStore.js +143 -0
  46. package/dist/services/tools/calculator.js +27 -0
  47. package/dist/services/tools/edit.js +318 -0
  48. package/dist/services/tools/exec.js +119 -0
  49. package/dist/services/tools/fetch.js +155 -0
  50. package/dist/services/tools/file.js +315 -0
  51. package/dist/services/tools/index.js +48 -0
  52. package/dist/services/tools/keyboard.js +145 -0
  53. package/dist/services/tools/model.js +86 -0
  54. package/dist/services/tools/mouse.js +55 -0
  55. package/dist/services/tools/screenshot.js +19 -0
  56. package/dist/services/tools/search.js +53 -0
  57. package/dist/services/tools/skill.js +108 -0
  58. package/dist/services/tools/task.js +110 -0
  59. package/dist/services/tools/types.js +1 -0
  60. package/dist/services/tools/webFetch.js +34 -0
  61. package/dist/stores/authStore.js +178 -0
  62. package/dist/stores/index.js +6 -0
  63. package/dist/stores/memoryStore.js +191 -0
  64. package/dist/stores/persistStore.js +317 -0
  65. package/package.json +94 -0
@@ -0,0 +1,265 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { Agent } from './Agent';
3
+ import { sessionManager } from '../session/SessionManager';
4
+ import { authStore } from '@/stores/authStore';
5
+ import { getLogger } from '@pocketclaw/shared';
6
+ import appConfig from '@/config';
7
+ const logger = getLogger('AgentManager');
8
+ /**
9
+ * AgentManager - Business logic layer
10
+ * Manages multiple agents in memory
11
+ */
12
+ export class AgentManager {
13
+ store;
14
+ agents = null;
15
+ initialized = false;
16
+ constructor(store) {
17
+ this.store = store;
18
+ }
19
+ /**
20
+ * Initialize - Load all agents from database on startup
21
+ */
22
+ initialize() {
23
+ if (this.initialized) {
24
+ logger.warn('Already initialized');
25
+ return;
26
+ }
27
+ const userId = this.getCurrentUserId();
28
+ if (!userId) {
29
+ logger.info('No user logged in, skipping initialization');
30
+ this.initialized = true;
31
+ return;
32
+ }
33
+ this.agents = new Map();
34
+ // Load all agents from database
35
+ const agentDataList = this.store.findByUserId(userId);
36
+ for (const agentData of agentDataList) {
37
+ const agent = new Agent(agentData, this.store, this);
38
+ this.agents.set(agent.id, agent);
39
+ }
40
+ // If no agents exist, create default "MyClaw" agent
41
+ if (this.agents.size === 0) {
42
+ logger.info('No agents found, creating default "MyClaw" agent');
43
+ this.createDefaultAgent(userId);
44
+ }
45
+ // Ensure exactly one agent has isCurrent=true
46
+ const hasCurrent = Array.from(this.agents.values()).some(a => a.isCurrent);
47
+ if (!hasCurrent) {
48
+ const first = Array.from(this.agents.values())[0];
49
+ if (first) {
50
+ first.isCurrent = true;
51
+ first.save();
52
+ }
53
+ }
54
+ this.initialized = true;
55
+ logger.info(`Initialized with ${this.agents.size} agents for user ${userId}`);
56
+ }
57
+ /**
58
+ * Get current user ID
59
+ */
60
+ getCurrentUserId() {
61
+ const user = authStore.getUser();
62
+ return user ? String(user.id) : null;
63
+ }
64
+ /**
65
+ * Create default "MyClaw" agent
66
+ */
67
+ createDefaultAgent(userId) {
68
+ const agentData = {
69
+ id: uuidv4(),
70
+ userId,
71
+ name: appConfig.appName,
72
+ description: '默认 AI 助手',
73
+ systemPrompt: undefined,
74
+ avatar: undefined,
75
+ config: undefined,
76
+ createdAt: Date.now(),
77
+ updatedAt: Date.now(),
78
+ isCurrent: true,
79
+ };
80
+ this.store.insert(agentData);
81
+ const agent = new Agent(agentData, this.store, this);
82
+ this.agents.set(agent.id, agent);
83
+ // Create default session
84
+ agent.createSession({ title: '新会话' });
85
+ logger.info(`Created default agent: ${agent.id}`);
86
+ return agent;
87
+ }
88
+ /**
89
+ * Get agent list summary
90
+ */
91
+ getAgentList() {
92
+ this.ensureInitialized();
93
+ const userId = this.getCurrentUserId();
94
+ if (!userId)
95
+ return [];
96
+ const agentDataList = this.store.findByUserId(userId);
97
+ return agentDataList.map(data => {
98
+ const sessions = sessionManager.getUserSessions();
99
+ const agentSessions = sessions
100
+ .filter(s => s.agentId === data.id)
101
+ .map(s => ({
102
+ id: s.id,
103
+ title: s.title,
104
+ createdAt: s.createdAt,
105
+ updatedAt: s.updatedAt,
106
+ isCurrent: s.isCurrent,
107
+ unreadCount: s.unreadCount
108
+ }));
109
+ return {
110
+ ...data,
111
+ sessionCount: agentSessions.length,
112
+ sessions: agentSessions,
113
+ unreadCount: agentSessions.reduce((sum, item) => sum + item.unreadCount, 0)
114
+ };
115
+ });
116
+ }
117
+ /**
118
+ * Get agent by ID
119
+ */
120
+ getAgent(agentId) {
121
+ this.ensureInitialized();
122
+ return this.agents.get(agentId) || null;
123
+ }
124
+ /**
125
+ * Create new agent
126
+ */
127
+ createAgent(config) {
128
+ const userId = this.getCurrentUserId();
129
+ if (!userId) {
130
+ throw new Error('No user logged in, cannot create agent');
131
+ }
132
+ // Check if name already exists
133
+ const existing = this.store.findByName(userId, config.name);
134
+ if (existing) {
135
+ throw new Error(`Agent with name "${config.name}" already exists`);
136
+ }
137
+ const agentData = {
138
+ id: uuidv4(),
139
+ userId,
140
+ name: config.name,
141
+ description: config.description,
142
+ systemPrompt: config.systemPrompt,
143
+ avatar: config.avatar,
144
+ config: config.config,
145
+ createdAt: Date.now(),
146
+ updatedAt: Date.now(),
147
+ };
148
+ this.store.insert(agentData);
149
+ const agent = new Agent(agentData, this.store, this);
150
+ this.agents.set(agent.id, agent);
151
+ // Create default session
152
+ agent.createSession({ title: '新会话' });
153
+ logger.info(`Created agent: ${agent.name} (${agent.id})`);
154
+ return agent;
155
+ }
156
+ /**
157
+ * Update agent
158
+ */
159
+ updateAgent(agentId, updates) {
160
+ const agent = this.agents.get(agentId);
161
+ if (!agent)
162
+ return null;
163
+ // Check name conflict
164
+ if (updates.name && updates.name !== agent.name) {
165
+ const userId = this.getCurrentUserId();
166
+ const existing = this.store.findByName(userId, updates.name);
167
+ if (existing && existing.id !== agentId) {
168
+ throw new Error(`Agent with name "${updates.name}" already exists`);
169
+ }
170
+ }
171
+ agent.update(updates);
172
+ return agent;
173
+ }
174
+ /**
175
+ * Delete agent
176
+ */
177
+ deleteAgent(agentId) {
178
+ const agent = this.agents.get(agentId);
179
+ if (!agent)
180
+ return false;
181
+ // Cannot delete the last agent
182
+ if (this.agents.size <= 1) {
183
+ throw new Error('Cannot delete the last agent');
184
+ }
185
+ const wasCurrent = agent.isCurrent;
186
+ // Delete all sessions under this agent
187
+ const sessions = agent.getSessions();
188
+ for (const session of sessions) {
189
+ sessionManager.deleteSession(session.id);
190
+ }
191
+ // Delete agent
192
+ this.store.delete(agentId);
193
+ this.agents.delete(agentId);
194
+ // If deleted agent was current, set first remaining as current
195
+ if (wasCurrent && this.agents.size > 0) {
196
+ const first = Array.from(this.agents.values())[0];
197
+ if (first) {
198
+ first.isCurrent = true;
199
+ first.save();
200
+ }
201
+ }
202
+ logger.info(`Deleted agent: ${agentId}`);
203
+ return true;
204
+ }
205
+ /**
206
+ * Set current agent (when user views it)
207
+ */
208
+ setCurrentAgent(agentId) {
209
+ this.ensureInitialized();
210
+ // 清除旧当前 Agent 的 isCurrent 标记
211
+ const old = Array.from(this.agents.values()).find(a => a.isCurrent);
212
+ if (old) {
213
+ old.isCurrent = false;
214
+ old.save();
215
+ }
216
+ // 设置新当前 Agent
217
+ if (agentId) {
218
+ const next = this.agents.get(agentId);
219
+ if (next) {
220
+ next.isCurrent = true;
221
+ next.save();
222
+ }
223
+ }
224
+ }
225
+ /**
226
+ * Get current agent
227
+ */
228
+ getCurrentAgent() {
229
+ this.ensureInitialized();
230
+ return Array.from(this.agents.values()).find(a => a.isCurrent) || null;
231
+ }
232
+ /**
233
+ * Get sessions under an agent
234
+ */
235
+ getAgentSessions(agentId) {
236
+ const sessions = sessionManager.getUserSessions();
237
+ return sessions
238
+ .filter(s => s.agentId === agentId)
239
+ .map(s => ({
240
+ id: s.id,
241
+ title: s.title,
242
+ createdAt: s.createdAt,
243
+ updatedAt: s.updatedAt,
244
+ }));
245
+ }
246
+ /**
247
+ * Reload (for login switch)
248
+ */
249
+ reload() {
250
+ this.initialized = false;
251
+ this.agents = null;
252
+ this.initialize();
253
+ }
254
+ ensureInitialized() {
255
+ if (!this.initialized) {
256
+ this.initialize();
257
+ }
258
+ }
259
+ }
260
+ // Export singleton
261
+ export let agentManager;
262
+ export function initAgentManager(store) {
263
+ agentManager = new AgentManager(store);
264
+ return agentManager;
265
+ }
@@ -0,0 +1,73 @@
1
+ import { getLogger } from '@pocketclaw/shared';
2
+ const logger = getLogger('AgentStore');
3
+ /**
4
+ * AgentStore - Data access layer
5
+ * Operates on SQLite database
6
+ */
7
+ export class AgentStore {
8
+ db;
9
+ constructor(db) {
10
+ this.db = db;
11
+ this.initTable();
12
+ }
13
+ initTable() {
14
+ // Ensure agents table exists
15
+ this.db.exec(`
16
+ CREATE TABLE IF NOT EXISTS agents (
17
+ id TEXT PRIMARY KEY,
18
+ user_id TEXT NOT NULL,
19
+ name TEXT NOT NULL,
20
+ description TEXT,
21
+ system_prompt TEXT,
22
+ avatar TEXT,
23
+ config TEXT,
24
+ created_at INTEGER NOT NULL,
25
+ updated_at INTEGER NOT NULL
26
+ )
27
+ `);
28
+ logger.info('Tables initialized');
29
+ }
30
+ // ========== Agent Operations ==========
31
+ insert(agent) {
32
+ this.db.prepare(`
33
+ INSERT INTO agents (id, user_id, name, description, system_prompt, avatar, config, created_at, updated_at, is_current)
34
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
35
+ `).run(agent.id, agent.userId, agent.name, agent.description || null, agent.systemPrompt || null, agent.avatar || null, agent.config || null, agent.createdAt, agent.updatedAt, agent.isCurrent ? 1 : 0);
36
+ }
37
+ update(agent) {
38
+ this.db.prepare(`
39
+ UPDATE agents
40
+ SET name = ?, description = ?, system_prompt = ?, avatar = ?, config = ?, updated_at = ?, is_current = ?
41
+ WHERE id = ?
42
+ `).run(agent.name, agent.description || null, agent.systemPrompt || null, agent.avatar || null, agent.config || null, agent.updatedAt, agent.isCurrent ? 1 : 0, agent.id);
43
+ }
44
+ delete(id) {
45
+ this.db.prepare('DELETE FROM agents WHERE id = ?').run(id);
46
+ }
47
+ findById(id) {
48
+ const row = this.db.prepare('SELECT * FROM agents WHERE id = ?').get(id);
49
+ return row ? this.rowToData(row) : null;
50
+ }
51
+ findByUserId(userId) {
52
+ const rows = this.db.prepare('SELECT * FROM agents WHERE user_id = ? ORDER BY updated_at DESC').all(userId);
53
+ return rows.map(row => this.rowToData(row));
54
+ }
55
+ findByName(userId, name) {
56
+ const row = this.db.prepare('SELECT * FROM agents WHERE user_id = ? AND name = ?').get(userId, name);
57
+ return row ? this.rowToData(row) : null;
58
+ }
59
+ rowToData(row) {
60
+ return {
61
+ id: row.id,
62
+ userId: row.user_id,
63
+ name: row.name,
64
+ description: row.description || undefined,
65
+ systemPrompt: row.system_prompt || undefined,
66
+ avatar: row.avatar || undefined,
67
+ config: row.config || undefined,
68
+ createdAt: row.created_at,
69
+ updatedAt: row.updated_at,
70
+ isCurrent: !!row.is_current,
71
+ };
72
+ }
73
+ }
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Gateway 数据服务层
3
+ * 直接转发服务端数据,不做二次包装
4
+ *
5
+ * 服务端路由结构:
6
+ * - /api/v1/auth/* - 认证路由 (login, register, logout, me, profile, password, account)
7
+ * - /api/v1/data/* - 用户数据路由 (models, skills, tasks, settings)
8
+ * - /api/v1/skill-hubs/* - 技能库路由
9
+ */
10
+ import { authApi, skillsApi, skillHubApi, modelsApi, settingsApi } from '../api';
11
+ import { authStore, memoryStore, persistStore } from '../stores';
12
+ import { taskService } from './TaskService';
13
+ import { getLogger } from '@pocketclaw/shared';
14
+ const logger = getLogger('DataService');
15
+ // ============ 认证服务 ============
16
+ export const authService = {
17
+ // 登录
18
+ login: async (account, password, platform) => {
19
+ const response = await authApi.login({ account, password, platform });
20
+ if (response.success && response.data) {
21
+ const expiresIn = response.data.expiresIn || 86400;
22
+ authStore.save({
23
+ token: response.data.accessToken,
24
+ refreshToken: response.data.refreshToken,
25
+ expiresIn,
26
+ expiresAt: Date.now() + expiresIn * 1000,
27
+ user: response.data.user
28
+ });
29
+ }
30
+ return response;
31
+ },
32
+ // 注册
33
+ register: async (account, password, platform) => {
34
+ const response = await authApi.register({
35
+ account,
36
+ password,
37
+ nickname: account,
38
+ platform
39
+ });
40
+ if (response.success && response.data) {
41
+ const expiresIn = response.data.expiresIn || 86400;
42
+ authStore.save({
43
+ token: response.data.accessToken,
44
+ refreshToken: response.data.refreshToken,
45
+ expiresIn,
46
+ expiresAt: Date.now() + expiresIn * 1000,
47
+ user: response.data.user
48
+ });
49
+ }
50
+ return response;
51
+ },
52
+ // 登出
53
+ logout: async () => {
54
+ try {
55
+ await authApi.logout();
56
+ }
57
+ catch (e) {
58
+ // 忽略错误
59
+ }
60
+ authStore.clear();
61
+ return { success: true };
62
+ },
63
+ // 获取当前用户
64
+ me: () => authApi.me(),
65
+ // 更新资料
66
+ updateProfile: (data) => authApi.updateProfile(data),
67
+ // 修改密码
68
+ changePassword: (oldPassword, newPassword) => authApi.changePassword({ oldPassword, newPassword }),
69
+ // 删除账号
70
+ deleteAccount: (password) => authApi.deleteAccount({ password }),
71
+ // 获取认证状态
72
+ isAuthenticated: () => authStore.isAuthenticated(),
73
+ // 获取当前用户(从内存)
74
+ getUser: () => authStore.get()?.user || null,
75
+ // 获取 Token
76
+ getToken: () => authStore.getToken(),
77
+ // 刷新 Token
78
+ refresh: async (refreshToken) => {
79
+ const response = await authApi.refresh(refreshToken);
80
+ if (response.success && response.accessToken) {
81
+ authStore.updateToken(response.accessToken, response.refreshToken);
82
+ }
83
+ return response;
84
+ },
85
+ // 检查认证(供 Desktop 使用)
86
+ checkAuth: async () => {
87
+ const isAuth = authStore.isAuthenticated();
88
+ const user = authStore.get()?.user || null;
89
+ return { success: true, authenticated: isAuth, user };
90
+ }
91
+ };
92
+ // ============ 技能服务 (用户已安装的技能) ============
93
+ export const skillsService = {
94
+ list: async () => await skillsApi.list(),
95
+ get: (skillId) => skillsApi.get(skillId),
96
+ install: async (skillHubId) => {
97
+ // 1. 从技能库获取技能详情
98
+ const hubResult = await skillHubApi.get(skillHubId);
99
+ if (!hubResult.success || !hubResult.data) {
100
+ return { success: false, error: '获取技能详情失败' };
101
+ }
102
+ const hub = hubResult.data;
103
+ // 2. 创建用户技能记录
104
+ const skillData = {
105
+ name: hub.name,
106
+ description: hub.description || '',
107
+ content: hub.content || '',
108
+ icon: hub.icon,
109
+ templateId: skillHubId,
110
+ isActive: true,
111
+ apiKeyRequired: hub.apiKeyRequired || false,
112
+ };
113
+ const response = await skillsApi.create(skillData);
114
+ if (response.success) {
115
+ // 3. 增加安装计数
116
+ await skillHubApi.install(skillHubId);
117
+ }
118
+ return response;
119
+ },
120
+ update: (skillId, data) => skillsApi.update(skillId, data),
121
+ uninstall: async (skillId) => await skillsApi.uninstall(skillId),
122
+ setApiKey: (skillId, apiKey) => {
123
+ persistStore.setSkillApiKey(skillId, apiKey);
124
+ return { success: true };
125
+ },
126
+ getApiKey: async (skillId) => {
127
+ const apikey = persistStore.getSkillApiKey(skillId);
128
+ if (!apikey) {
129
+ // 判断是否有内置 apikey
130
+ const skill = (await skillsService.get(skillId)).data;
131
+ if (skill.templateId) {
132
+ const skillHub = (await skillHubService.get(skill.templateId)).data;
133
+ if (skillHub?.builtinApikey) {
134
+ persistStore.setSkillApiKey(skillId, skillHub.builtinApikey);
135
+ return { success: true, apiKey: skillHub.builtinApikey };
136
+ }
137
+ }
138
+ }
139
+ return { success: true, apiKey: apikey?.apiKey };
140
+ },
141
+ rate: (skillId, score) => skillsApi.rate(skillId, { score }),
142
+ parse: (content) => skillsApi.parse({ content }),
143
+ create: async (data) => {
144
+ const response = await skillsApi.create(data);
145
+ if (response.success) {
146
+ // 创建成功后更新技能列表缓存
147
+ const listResponse = await skillsApi.list();
148
+ if (listResponse.success) {
149
+ memoryStore.set('skills', listResponse.data);
150
+ }
151
+ }
152
+ return response;
153
+ },
154
+ };
155
+ // ============ 技能库服务 (可安装的技能) ============
156
+ export const skillHubService = {
157
+ list: (params) => skillHubApi.list(params),
158
+ get: (hubId) => skillHubApi.get(hubId),
159
+ categories: () => skillHubApi.categories(),
160
+ preinstalled: () => skillHubApi.preinstalled(),
161
+ user: () => skillHubApi.user(),
162
+ checkUsed: (hubId) => skillHubApi.checkUsed(hubId),
163
+ rate: (hubId, rating) => skillHubApi.rate(hubId, rating),
164
+ userRating: (hubId) => skillHubApi.userRating(hubId),
165
+ install: (hubId) => skillHubApi.install(hubId),
166
+ use: (hubId) => skillHubApi.use(hubId),
167
+ };
168
+ // ============ 模型服务 ============
169
+ export const modelsService = {
170
+ list: () => modelsApi.list(),
171
+ get: (modelId) => modelsApi.get(modelId),
172
+ create: (data) => modelsApi.create(data),
173
+ update: (modelId, data) => modelsApi.update(modelId, data),
174
+ delete: (modelId) => modelsApi.delete(modelId),
175
+ setPrimary: (modelId) => modelsApi.setPrimary(modelId),
176
+ };
177
+ export const tasksService = {
178
+ list: async (params, userId) => {
179
+ const result = await taskService.listTasks({
180
+ status: params?.status,
181
+ userId,
182
+ page: params?.page ? parseInt(params.page) : undefined,
183
+ pageSize: params?.pageSize ? parseInt(params.pageSize) : undefined,
184
+ });
185
+ return { success: true, data: result.tasks, total: result.total };
186
+ },
187
+ get: async (taskId) => {
188
+ const task = await taskService.getTask(taskId);
189
+ if (!task)
190
+ return { success: false, error: 'Task not found' };
191
+ return { success: true, data: task };
192
+ },
193
+ create: async (data, userId) => {
194
+ const uid = userId || data?.userId || 'local';
195
+ try {
196
+ const result = await taskService.createTask({
197
+ userId: uid,
198
+ title: data.title,
199
+ description: data.description,
200
+ taskType: data.taskType,
201
+ recurrenceRule: data.recurrenceRule,
202
+ intervalValue: data.intervalValue,
203
+ intervalUnit: data.intervalUnit,
204
+ scheduledAt: data.scheduledAt,
205
+ startTime: data.startTime,
206
+ endTime: data.endTime,
207
+ platformApply: data.platformApply,
208
+ pushToken: data.pushToken,
209
+ });
210
+ return { success: true, data: { id: result.id, isLocal: result.isLocal } };
211
+ }
212
+ catch (error) {
213
+ logger.error('[tasksService] Create failed', { error });
214
+ return { success: false, error: error.message };
215
+ }
216
+ },
217
+ update: async (taskId, data) => {
218
+ try {
219
+ const result = await taskService.updateTask(taskId, {
220
+ title: data.title,
221
+ description: data.description,
222
+ taskType: data.taskType,
223
+ recurrenceRule: data.recurrenceRule,
224
+ intervalValue: data.intervalValue,
225
+ intervalUnit: data.intervalUnit,
226
+ scheduledAt: data.scheduledAt,
227
+ startTime: data.startTime,
228
+ endTime: data.endTime,
229
+ status: data.status,
230
+ platformApply: data.platformApply,
231
+ pushToken: data.pushToken,
232
+ });
233
+ return { success: result };
234
+ }
235
+ catch (error) {
236
+ logger.error('[tasksService] Update failed', { taskId, error });
237
+ return { success: false, error: error.message };
238
+ }
239
+ },
240
+ delete: async (taskId) => {
241
+ try {
242
+ const result = await taskService.deleteTask(taskId);
243
+ return { success: result };
244
+ }
245
+ catch (error) {
246
+ logger.error('[tasksService] Delete failed', { taskId, error });
247
+ return { success: false, error: error.message };
248
+ }
249
+ },
250
+ cancel: async (taskId) => {
251
+ try {
252
+ const result = await taskService.cancelTask(taskId);
253
+ return { success: result };
254
+ }
255
+ catch (error) {
256
+ logger.error('[tasksService] Cancel failed', { taskId, error });
257
+ return { success: false, error: error.message };
258
+ }
259
+ },
260
+ updateStatus: async (taskId, status) => {
261
+ try {
262
+ const result = await taskService.updateTaskStatus(taskId, status);
263
+ return { success: result };
264
+ }
265
+ catch (error) {
266
+ logger.error('[tasksService] UpdateStatus failed', { taskId, status, error });
267
+ return { success: false, error: error.message };
268
+ }
269
+ },
270
+ };
271
+ // ============ 设置服务 ============
272
+ export const settingsService = {
273
+ get: async () => {
274
+ const settings = memoryStore.get('settings'); // 预热缓存
275
+ if (settings) {
276
+ return { success: true, data: settings };
277
+ }
278
+ else {
279
+ const response = await settingsApi.get();
280
+ if (response.success) {
281
+ memoryStore.set('settings', response.data); // 更新缓存
282
+ }
283
+ return response;
284
+ }
285
+ },
286
+ update: async (data) => {
287
+ const response = await settingsApi.update(data);
288
+ if (response.success) {
289
+ memoryStore.set('settings', response.data); // 更新缓存
290
+ }
291
+ return response;
292
+ },
293
+ };
@@ -0,0 +1,15 @@
1
+ // Re-export all services from dataService
2
+ export { authService, skillsService, skillHubService, modelsService, settingsService, } from './dataService';
3
+ // Re-export tasksService from dataService (server-only tasks)
4
+ export { tasksService } from './dataService';
5
+ // Re-export session manager
6
+ export { sessionManager } from './session';
7
+ // Re-export task services
8
+ export { taskSchedulerService } from './TaskSchedulerService';
9
+ export { taskService } from './TaskService';
10
+ export { localTaskService } from './LocalTaskService';
11
+ // Re-export notification and holiday services
12
+ export { notificationService } from './NotificationService';
13
+ // Re-export task stores
14
+ export { TaskStore } from './task/TaskStore';
15
+ export { PushTokenStore } from './task/PushTokenStore';