shiva-code 0.5.2 → 0.5.4

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.
@@ -0,0 +1,163 @@
1
+ // src/utils/config.ts
2
+ import Conf from "conf";
3
+ import * as os from "os";
4
+ import * as path from "path";
5
+ var DEFAULT_API_ENDPOINT = "https://shiva.li/api";
6
+ var OLD_API_ENDPOINTS = [
7
+ "https://shiva-ai-api.slither-mutiplayer.workers.dev/api",
8
+ "https://shiva-ai-api.slither-multiplayer.workers.dev/api"
9
+ ];
10
+ var DEFAULT_CLAUDE_PROJECTS_PATH = path.join(os.homedir(), ".claude", "projects");
11
+ var config = new Conf({
12
+ projectName: "shiva-code",
13
+ defaults: {
14
+ apiEndpoint: DEFAULT_API_ENDPOINT,
15
+ token: null,
16
+ tokenExpiry: null,
17
+ userId: null,
18
+ email: null,
19
+ tier: null,
20
+ // Control Station defaults
21
+ packages: {},
22
+ defaultTerminal: "auto",
23
+ claudeProjectsPath: DEFAULT_CLAUDE_PROJECTS_PATH,
24
+ // Claude Code launch settings
25
+ claudeArgs: [],
26
+ claudeSkipPermissions: true
27
+ // Default: skip permissions for smoother workflow
28
+ }
29
+ });
30
+ function getConfig() {
31
+ return {
32
+ apiEndpoint: config.get("apiEndpoint"),
33
+ token: config.get("token"),
34
+ tokenExpiry: config.get("tokenExpiry"),
35
+ userId: config.get("userId"),
36
+ email: config.get("email"),
37
+ tier: config.get("tier")
38
+ };
39
+ }
40
+ function setConfig(key, value) {
41
+ config.set(key, value);
42
+ }
43
+ function getToken() {
44
+ const token = config.get("token");
45
+ const expiry = config.get("tokenExpiry");
46
+ if (token && expiry && Date.now() > expiry) {
47
+ clearAuth();
48
+ return null;
49
+ }
50
+ return token;
51
+ }
52
+ function setAuth(token, user) {
53
+ let expiry;
54
+ try {
55
+ const payload = JSON.parse(atob(token.includes(".") ? token.split(".")[1] : token));
56
+ expiry = payload.exp > 1e12 ? payload.exp : payload.exp * 1e3;
57
+ } catch {
58
+ expiry = Date.now() + 7 * 24 * 60 * 60 * 1e3;
59
+ }
60
+ config.set("token", token);
61
+ config.set("tokenExpiry", expiry);
62
+ config.set("userId", user.id);
63
+ config.set("email", user.email);
64
+ config.set("tier", user.tier);
65
+ }
66
+ function clearAuth() {
67
+ config.set("token", null);
68
+ config.set("tokenExpiry", null);
69
+ config.set("userId", null);
70
+ config.set("email", null);
71
+ config.set("tier", null);
72
+ }
73
+ function isAuthenticated() {
74
+ return getToken() !== null;
75
+ }
76
+ function getApiEndpoint() {
77
+ return config.get("apiEndpoint");
78
+ }
79
+ function setApiEndpoint(endpoint) {
80
+ config.set("apiEndpoint", endpoint);
81
+ }
82
+ function getConfigPath() {
83
+ return config.path;
84
+ }
85
+ var CONFIG_PATH = config.path;
86
+ function clearConfig() {
87
+ config.clear();
88
+ config.set("apiEndpoint", DEFAULT_API_ENDPOINT);
89
+ }
90
+ function getExtendedConfig() {
91
+ return {
92
+ ...getConfig(),
93
+ packages: config.get("packages") || {},
94
+ defaultTerminal: config.get("defaultTerminal") || "auto",
95
+ claudeProjectsPath: config.get("claudeProjectsPath") || DEFAULT_CLAUDE_PROJECTS_PATH,
96
+ claudeArgs: config.get("claudeArgs") || [],
97
+ claudeSkipPermissions: config.get("claudeSkipPermissions") ?? true
98
+ };
99
+ }
100
+ function getDefaultTerminal() {
101
+ return config.get("defaultTerminal") || "auto";
102
+ }
103
+ function setDefaultTerminal(terminal) {
104
+ config.set("defaultTerminal", terminal);
105
+ }
106
+ function getClaudeProjectsPath() {
107
+ return config.get("claudeProjectsPath") || DEFAULT_CLAUDE_PROJECTS_PATH;
108
+ }
109
+ function setClaudeProjectsPath(path2) {
110
+ config.set("claudeProjectsPath", path2);
111
+ }
112
+ function getClaudeSkipPermissions() {
113
+ return config.get("claudeSkipPermissions") ?? true;
114
+ }
115
+ function setClaudeSkipPermissions(skip) {
116
+ config.set("claudeSkipPermissions", skip);
117
+ }
118
+ function getClaudeArgs() {
119
+ return config.get("claudeArgs") || [];
120
+ }
121
+ function setClaudeArgs(args) {
122
+ config.set("claudeArgs", args);
123
+ }
124
+ function getClaudeLaunchArgs() {
125
+ const args = [];
126
+ if (config.get("claudeSkipPermissions") ?? true) {
127
+ args.push("--dangerously-skip-permissions");
128
+ }
129
+ const customArgs = config.get("claudeArgs") || [];
130
+ args.push(...customArgs);
131
+ return args;
132
+ }
133
+ function migrateConfig() {
134
+ const currentEndpoint = config.get("apiEndpoint");
135
+ if (currentEndpoint && OLD_API_ENDPOINTS.includes(currentEndpoint)) {
136
+ config.set("apiEndpoint", DEFAULT_API_ENDPOINT);
137
+ }
138
+ }
139
+
140
+ export {
141
+ getConfig,
142
+ setConfig,
143
+ getToken,
144
+ setAuth,
145
+ clearAuth,
146
+ isAuthenticated,
147
+ getApiEndpoint,
148
+ setApiEndpoint,
149
+ getConfigPath,
150
+ CONFIG_PATH,
151
+ clearConfig,
152
+ getExtendedConfig,
153
+ getDefaultTerminal,
154
+ setDefaultTerminal,
155
+ getClaudeProjectsPath,
156
+ setClaudeProjectsPath,
157
+ getClaudeSkipPermissions,
158
+ setClaudeSkipPermissions,
159
+ getClaudeArgs,
160
+ setClaudeArgs,
161
+ getClaudeLaunchArgs,
162
+ migrateConfig
163
+ };
@@ -0,0 +1,504 @@
1
+ import {
2
+ getApiEndpoint,
3
+ getToken
4
+ } from "./chunk-OP4HYQZZ.js";
5
+
6
+ // src/services/api/client.ts
7
+ var ApiClient = class {
8
+ getHeaders() {
9
+ const headers = {
10
+ "Content-Type": "application/json"
11
+ };
12
+ const token = getToken();
13
+ if (token) {
14
+ headers["Authorization"] = `Bearer ${token}`;
15
+ }
16
+ return headers;
17
+ }
18
+ async request(endpoint, options = {}) {
19
+ const baseUrl = getApiEndpoint();
20
+ const url = `${baseUrl}${endpoint}`;
21
+ const response = await fetch(url, {
22
+ ...options,
23
+ headers: {
24
+ ...this.getHeaders(),
25
+ ...options.headers
26
+ }
27
+ });
28
+ if (!response.ok) {
29
+ const error = await response.json().catch(() => ({ error: "Unknown error" }));
30
+ throw new Error(error.error || error.message || `HTTP ${response.status}`);
31
+ }
32
+ return response.json();
33
+ }
34
+ // Auth endpoints
35
+ async requestOtp(email) {
36
+ return this.request("/auth/otp/request", {
37
+ method: "POST",
38
+ body: JSON.stringify({ email })
39
+ });
40
+ }
41
+ async verifyOtp(token, otp) {
42
+ return this.request("/auth/otp/verify", {
43
+ method: "POST",
44
+ body: JSON.stringify({ token, otp })
45
+ });
46
+ }
47
+ async getCurrentUser() {
48
+ return this.request("/auth/me");
49
+ }
50
+ // Project endpoints
51
+ async getProjects() {
52
+ return this.request("/projects");
53
+ }
54
+ async getProject(id) {
55
+ return this.request(`/projects/${id}`);
56
+ }
57
+ async createOrUpdateProject(data) {
58
+ return this.request("/projects", {
59
+ method: "POST",
60
+ body: JSON.stringify(data)
61
+ });
62
+ }
63
+ async syncProject(id, data) {
64
+ return this.request(`/projects/${id}/sync`, {
65
+ method: "POST",
66
+ body: JSON.stringify(data)
67
+ });
68
+ }
69
+ async deleteProject(id) {
70
+ return this.request(`/projects/${id}`, {
71
+ method: "DELETE"
72
+ });
73
+ }
74
+ async addMemory(projectId, memory) {
75
+ return this.request(`/projects/${projectId}/memories`, {
76
+ method: "POST",
77
+ body: JSON.stringify(memory)
78
+ });
79
+ }
80
+ async deleteMemory(projectId, memoryId) {
81
+ return this.request(`/projects/${projectId}/memories/${memoryId}`, {
82
+ method: "DELETE"
83
+ });
84
+ }
85
+ async connectProjects(projectA, projectB, connectionType) {
86
+ return this.request("/projects/connect", {
87
+ method: "POST",
88
+ body: JSON.stringify({
89
+ projectA,
90
+ projectB,
91
+ connectionType: connectionType || "related"
92
+ })
93
+ });
94
+ }
95
+ async disconnectProjects(projectA, projectB) {
96
+ return this.request("/projects/disconnect", {
97
+ method: "DELETE",
98
+ body: JSON.stringify({ projectA, projectB })
99
+ });
100
+ }
101
+ async getStats() {
102
+ return this.request("/projects/stats");
103
+ }
104
+ // Find project by path
105
+ async findProjectByPath(path) {
106
+ const projects = await this.getProjects();
107
+ return projects.find((p) => p.path === path) || null;
108
+ }
109
+ // ============================================
110
+ // Secrets Vault Endpoints
111
+ // ============================================
112
+ /**
113
+ * List all secrets (metadata only, no values)
114
+ */
115
+ async listSecrets(projectId) {
116
+ const params = projectId ? `?projectId=${projectId}` : "";
117
+ return this.request(`/secrets${params}`);
118
+ }
119
+ /**
120
+ * Add a new secret
121
+ */
122
+ async addSecret(data) {
123
+ return this.request("/secrets", {
124
+ method: "POST",
125
+ body: JSON.stringify(data)
126
+ });
127
+ }
128
+ /**
129
+ * Get a secret value (decrypted)
130
+ */
131
+ async getSecret(key, projectId) {
132
+ const params = projectId ? `?projectId=${projectId}` : "";
133
+ return this.request(`/secrets/${encodeURIComponent(key)}${params}`);
134
+ }
135
+ /**
136
+ * Delete a secret
137
+ */
138
+ async deleteSecret(key, projectId) {
139
+ const params = projectId ? `?projectId=${projectId}` : "";
140
+ return this.request(`/secrets/${encodeURIComponent(key)}${params}`, {
141
+ method: "DELETE"
142
+ });
143
+ }
144
+ /**
145
+ * Get all secrets for injection (decrypted values)
146
+ * Used by session start hook
147
+ */
148
+ async getSecretsForInjection(projectId) {
149
+ const params = projectId ? `?projectId=${projectId}` : "";
150
+ return this.request(`/secrets/inject${params}`);
151
+ }
152
+ // ============================================
153
+ // Settings Sync Endpoints (Phase 10)
154
+ // Pfad: /api/settings (nicht /api/user/settings)
155
+ // ============================================
156
+ /**
157
+ * Get current user settings from cloud
158
+ */
159
+ async getUserSettings() {
160
+ return this.request("/settings");
161
+ }
162
+ /**
163
+ * Update user settings in cloud
164
+ */
165
+ async updateUserSettings(data) {
166
+ return this.request("/settings", {
167
+ method: "PUT",
168
+ body: JSON.stringify(data)
169
+ });
170
+ }
171
+ /**
172
+ * Sync settings with conflict detection
173
+ */
174
+ async syncUserSettings(data) {
175
+ return this.request("/settings/sync", {
176
+ method: "POST",
177
+ body: JSON.stringify(data)
178
+ });
179
+ }
180
+ /**
181
+ * Get settings change history
182
+ */
183
+ async getSettingsHistory() {
184
+ return this.request("/settings/history");
185
+ }
186
+ /**
187
+ * Export settings
188
+ */
189
+ async exportSettings() {
190
+ return this.request("/settings/export");
191
+ }
192
+ /**
193
+ * Import settings
194
+ */
195
+ async importSettings(data) {
196
+ return this.request("/settings/import", {
197
+ method: "POST",
198
+ body: JSON.stringify(data)
199
+ });
200
+ }
201
+ // ============================================
202
+ // Dashboard/Analytics Endpoints (Phase 12)
203
+ // Pfad: /api/analytics (nicht /api/dashboard)
204
+ // ============================================
205
+ /**
206
+ * Get dashboard overview data (Pro Feature)
207
+ */
208
+ async getDashboardOverview() {
209
+ return this.request("/analytics/overview");
210
+ }
211
+ /**
212
+ * Get usage statistics (Pro Feature)
213
+ */
214
+ async getUsageStats() {
215
+ return this.request("/analytics/usage");
216
+ }
217
+ /**
218
+ * Get project analytics (Pro Feature)
219
+ */
220
+ async getProjectAnalytics() {
221
+ return this.request("/analytics/projects");
222
+ }
223
+ /**
224
+ * Get activity feed (Pro Feature)
225
+ */
226
+ async getActivityFeed() {
227
+ return this.request("/analytics/activity");
228
+ }
229
+ // Legacy aliases for backwards compatibility
230
+ async getDashboardProjects() {
231
+ return this.getProjectAnalytics();
232
+ }
233
+ async getDashboardAnalytics(days) {
234
+ return this.getUsageStats();
235
+ }
236
+ // ============================================
237
+ // Sessions Endpoints (Cloud-synced sessions)
238
+ // ============================================
239
+ /**
240
+ * Get all sessions from cloud
241
+ */
242
+ async getSessions() {
243
+ return this.request("/sessions");
244
+ }
245
+ /**
246
+ * Sync a session to cloud
247
+ */
248
+ async syncSession(data) {
249
+ return this.request("/sessions", {
250
+ method: "POST",
251
+ body: JSON.stringify(data)
252
+ });
253
+ }
254
+ /**
255
+ * Get a specific session from cloud
256
+ */
257
+ async getSession(sessionId) {
258
+ return this.request(`/sessions/${sessionId}`);
259
+ }
260
+ /**
261
+ * Delete a session from cloud
262
+ */
263
+ async deleteSession(sessionId) {
264
+ return this.request(`/sessions/${sessionId}`, {
265
+ method: "DELETE"
266
+ });
267
+ }
268
+ // ============================================
269
+ // Memories Endpoints (standalone)
270
+ // ============================================
271
+ /**
272
+ * Get all memories across projects
273
+ */
274
+ async getAllMemories() {
275
+ return this.request("/memories");
276
+ }
277
+ /**
278
+ * Search memories
279
+ */
280
+ async searchMemories(query) {
281
+ return this.request(`/memories/search?q=${encodeURIComponent(query)}`);
282
+ }
283
+ // ============================================
284
+ // Hooks Endpoints (Cloud-managed hooks)
285
+ // ============================================
286
+ /**
287
+ * Get hook configuration from cloud
288
+ */
289
+ async getHooks() {
290
+ return this.request("/hooks");
291
+ }
292
+ /**
293
+ * Update hook configuration
294
+ */
295
+ async updateHooks(hooks) {
296
+ return this.request("/hooks", {
297
+ method: "PUT",
298
+ body: JSON.stringify({ hooks })
299
+ });
300
+ }
301
+ // ============================================
302
+ // Packages Endpoints (Cloud-synced packages)
303
+ // ============================================
304
+ /**
305
+ * Get all packages from cloud
306
+ */
307
+ async getPackages() {
308
+ return this.request("/packages");
309
+ }
310
+ /**
311
+ * Sync a package to cloud
312
+ */
313
+ async syncPackage(data) {
314
+ return this.request("/packages", {
315
+ method: "POST",
316
+ body: JSON.stringify(data)
317
+ });
318
+ }
319
+ /**
320
+ * Get a specific package from cloud
321
+ */
322
+ async getPackage(name) {
323
+ return this.request(`/packages/${encodeURIComponent(name)}`);
324
+ }
325
+ /**
326
+ * Delete a package from cloud
327
+ */
328
+ async deleteCloudPackage(name) {
329
+ return this.request(`/packages/${encodeURIComponent(name)}`, {
330
+ method: "DELETE"
331
+ });
332
+ }
333
+ // ============================================
334
+ // Two-Factor Authentication Endpoints (Phase 15)
335
+ // ============================================
336
+ /**
337
+ * Initialize 2FA setup
338
+ */
339
+ async setup2FA() {
340
+ return this.request("/auth/2fa/setup", {
341
+ method: "POST"
342
+ });
343
+ }
344
+ /**
345
+ * Verify 2FA setup with code
346
+ */
347
+ async verify2FA(code) {
348
+ return this.request("/auth/2fa/verify", {
349
+ method: "POST",
350
+ body: JSON.stringify({ code })
351
+ });
352
+ }
353
+ /**
354
+ * Verify 2FA code during login
355
+ */
356
+ async verify2FACode(code) {
357
+ return this.request("/auth/2fa/check", {
358
+ method: "POST",
359
+ body: JSON.stringify({ code })
360
+ });
361
+ }
362
+ /**
363
+ * Verify backup code
364
+ */
365
+ async verifyBackupCode(code) {
366
+ return this.request("/auth/2fa/backup", {
367
+ method: "POST",
368
+ body: JSON.stringify({ code })
369
+ });
370
+ }
371
+ /**
372
+ * Get 2FA status
373
+ */
374
+ async get2FAStatus() {
375
+ return this.request("/auth/2fa/status");
376
+ }
377
+ /**
378
+ * Disable 2FA
379
+ */
380
+ async disable2FA(code) {
381
+ return this.request("/auth/2fa", {
382
+ method: "DELETE",
383
+ body: JSON.stringify({ code })
384
+ });
385
+ }
386
+ /**
387
+ * Regenerate backup codes
388
+ */
389
+ async regenerateBackupCodes() {
390
+ return this.request("/auth/2fa/backup-codes", {
391
+ method: "POST"
392
+ });
393
+ }
394
+ // ============================================
395
+ // Trusted Devices Endpoints (Phase 15)
396
+ // ============================================
397
+ /**
398
+ * Get all trusted devices
399
+ */
400
+ async getDevices() {
401
+ return this.request("/auth/devices");
402
+ }
403
+ /**
404
+ * Trust a device
405
+ */
406
+ async trustDevice(data) {
407
+ return this.request("/auth/devices", {
408
+ method: "POST",
409
+ body: JSON.stringify(data)
410
+ });
411
+ }
412
+ /**
413
+ * Revoke a device
414
+ */
415
+ async revokeDevice(deviceId) {
416
+ return this.request(`/auth/devices/${deviceId}`, {
417
+ method: "DELETE"
418
+ });
419
+ }
420
+ /**
421
+ * Revoke all devices
422
+ */
423
+ async revokeAllDevices() {
424
+ return this.request("/auth/devices/all", {
425
+ method: "DELETE"
426
+ });
427
+ }
428
+ // ============================================
429
+ // Project Security Endpoints (Phase 15)
430
+ // ============================================
431
+ /**
432
+ * Get project security config
433
+ */
434
+ async getProjectSecurity(projectId) {
435
+ return this.request(`/projects/${projectId}/security`);
436
+ }
437
+ /**
438
+ * Update project security config
439
+ */
440
+ async updateProjectSecurity(projectId, security) {
441
+ return this.request(`/projects/${projectId}/security`, {
442
+ method: "PUT",
443
+ body: JSON.stringify({ security })
444
+ });
445
+ }
446
+ // ============================================
447
+ // Project Team/Collaborators Endpoints (Phase 15)
448
+ // ============================================
449
+ /**
450
+ * Get project team
451
+ */
452
+ async getProjectTeam(projectId) {
453
+ return this.request(`/projects/${projectId}/team`);
454
+ }
455
+ /**
456
+ * Add collaborator
457
+ */
458
+ async addCollaborator(projectId, email, role) {
459
+ return this.request(`/projects/${projectId}/team`, {
460
+ method: "POST",
461
+ body: JSON.stringify({ email, role })
462
+ });
463
+ }
464
+ /**
465
+ * Remove collaborator
466
+ */
467
+ async removeCollaborator(projectId, userId) {
468
+ return this.request(`/projects/${projectId}/team/${userId}`, {
469
+ method: "DELETE"
470
+ });
471
+ }
472
+ /**
473
+ * Update collaborator role
474
+ */
475
+ async updateCollaboratorRole(projectId, userId, role) {
476
+ return this.request(`/projects/${projectId}/team/${userId}`, {
477
+ method: "PATCH",
478
+ body: JSON.stringify({ role })
479
+ });
480
+ }
481
+ /**
482
+ * Send project invitation
483
+ */
484
+ async sendProjectInvite(projectId, email, role) {
485
+ return this.request(`/projects/${projectId}/invite`, {
486
+ method: "POST",
487
+ body: JSON.stringify({ email, role })
488
+ });
489
+ }
490
+ /**
491
+ * Transfer project ownership
492
+ */
493
+ async transferProjectOwnership(projectId, newOwnerEmail) {
494
+ return this.request(`/projects/${projectId}/transfer`, {
495
+ method: "POST",
496
+ body: JSON.stringify({ email: newOwnerEmail })
497
+ });
498
+ }
499
+ };
500
+ var api = new ApiClient();
501
+
502
+ export {
503
+ api
504
+ };
@@ -0,0 +1,8 @@
1
+ import {
2
+ api
3
+ } from "./chunk-XVFDKDRZ.js";
4
+ import "./chunk-OP4HYQZZ.js";
5
+ import "./chunk-3RG5ZIWI.js";
6
+ export {
7
+ api
8
+ };
@@ -0,0 +1,49 @@
1
+ import {
2
+ CONFIG_PATH,
3
+ clearAuth,
4
+ clearConfig,
5
+ getApiEndpoint,
6
+ getClaudeArgs,
7
+ getClaudeLaunchArgs,
8
+ getClaudeProjectsPath,
9
+ getClaudeSkipPermissions,
10
+ getConfig,
11
+ getConfigPath,
12
+ getDefaultTerminal,
13
+ getExtendedConfig,
14
+ getToken,
15
+ isAuthenticated,
16
+ migrateConfig,
17
+ setApiEndpoint,
18
+ setAuth,
19
+ setClaudeArgs,
20
+ setClaudeProjectsPath,
21
+ setClaudeSkipPermissions,
22
+ setConfig,
23
+ setDefaultTerminal
24
+ } from "./chunk-OP4HYQZZ.js";
25
+ import "./chunk-3RG5ZIWI.js";
26
+ export {
27
+ CONFIG_PATH,
28
+ clearAuth,
29
+ clearConfig,
30
+ getApiEndpoint,
31
+ getClaudeArgs,
32
+ getClaudeLaunchArgs,
33
+ getClaudeProjectsPath,
34
+ getClaudeSkipPermissions,
35
+ getConfig,
36
+ getConfigPath,
37
+ getDefaultTerminal,
38
+ getExtendedConfig,
39
+ getToken,
40
+ isAuthenticated,
41
+ migrateConfig,
42
+ setApiEndpoint,
43
+ setAuth,
44
+ setClaudeArgs,
45
+ setClaudeProjectsPath,
46
+ setClaudeSkipPermissions,
47
+ setConfig,
48
+ setDefaultTerminal
49
+ };