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.
package/dist/index.js CHANGED
@@ -1,4 +1,26 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ api
4
+ } from "./chunk-XVFDKDRZ.js";
5
+ import {
6
+ CONFIG_PATH,
7
+ clearAuth,
8
+ clearConfig,
9
+ getClaudeArgs,
10
+ getClaudeLaunchArgs,
11
+ getClaudeSkipPermissions,
12
+ getConfig,
13
+ getDefaultTerminal,
14
+ getExtendedConfig,
15
+ getToken,
16
+ isAuthenticated,
17
+ migrateConfig,
18
+ setAuth,
19
+ setClaudeArgs,
20
+ setClaudeSkipPermissions,
21
+ setConfig,
22
+ setDefaultTerminal
23
+ } from "./chunk-OP4HYQZZ.js";
2
24
  import {
3
25
  SECURITY_PRESETS,
4
26
  addDockerMount,
@@ -88,597 +110,6 @@ import * as readline from "readline";
88
110
  import { Command } from "commander";
89
111
  import inquirer2 from "inquirer";
90
112
 
91
- // src/utils/config.ts
92
- import Conf from "conf";
93
- import * as os from "os";
94
- import * as path from "path";
95
- var DEFAULT_API_ENDPOINT = "https://shiva.li/api";
96
- var OLD_API_ENDPOINTS = [
97
- "https://shiva-ai-api.slither-mutiplayer.workers.dev/api",
98
- "https://shiva-ai-api.slither-multiplayer.workers.dev/api"
99
- ];
100
- var DEFAULT_CLAUDE_PROJECTS_PATH = path.join(os.homedir(), ".claude", "projects");
101
- var config = new Conf({
102
- projectName: "shiva-code",
103
- defaults: {
104
- apiEndpoint: DEFAULT_API_ENDPOINT,
105
- token: null,
106
- tokenExpiry: null,
107
- userId: null,
108
- email: null,
109
- tier: null,
110
- // Control Station defaults
111
- packages: {},
112
- defaultTerminal: "auto",
113
- claudeProjectsPath: DEFAULT_CLAUDE_PROJECTS_PATH,
114
- // Claude Code launch settings
115
- claudeArgs: [],
116
- claudeSkipPermissions: true
117
- // Default: skip permissions for smoother workflow
118
- }
119
- });
120
- function getConfig() {
121
- return {
122
- apiEndpoint: config.get("apiEndpoint"),
123
- token: config.get("token"),
124
- tokenExpiry: config.get("tokenExpiry"),
125
- userId: config.get("userId"),
126
- email: config.get("email"),
127
- tier: config.get("tier")
128
- };
129
- }
130
- function setConfig(key, value) {
131
- config.set(key, value);
132
- }
133
- function getToken() {
134
- const token = config.get("token");
135
- const expiry = config.get("tokenExpiry");
136
- if (token && expiry && Date.now() > expiry) {
137
- clearAuth();
138
- return null;
139
- }
140
- return token;
141
- }
142
- function setAuth(token, user) {
143
- let expiry;
144
- try {
145
- const payload = JSON.parse(atob(token.includes(".") ? token.split(".")[1] : token));
146
- expiry = payload.exp > 1e12 ? payload.exp : payload.exp * 1e3;
147
- } catch {
148
- expiry = Date.now() + 7 * 24 * 60 * 60 * 1e3;
149
- }
150
- config.set("token", token);
151
- config.set("tokenExpiry", expiry);
152
- config.set("userId", user.id);
153
- config.set("email", user.email);
154
- config.set("tier", user.tier);
155
- }
156
- function clearAuth() {
157
- config.set("token", null);
158
- config.set("tokenExpiry", null);
159
- config.set("userId", null);
160
- config.set("email", null);
161
- config.set("tier", null);
162
- }
163
- function isAuthenticated() {
164
- return getToken() !== null;
165
- }
166
- function getApiEndpoint() {
167
- return config.get("apiEndpoint");
168
- }
169
- var CONFIG_PATH = config.path;
170
- function clearConfig() {
171
- config.clear();
172
- config.set("apiEndpoint", DEFAULT_API_ENDPOINT);
173
- }
174
- function getExtendedConfig() {
175
- return {
176
- ...getConfig(),
177
- packages: config.get("packages") || {},
178
- defaultTerminal: config.get("defaultTerminal") || "auto",
179
- claudeProjectsPath: config.get("claudeProjectsPath") || DEFAULT_CLAUDE_PROJECTS_PATH,
180
- claudeArgs: config.get("claudeArgs") || [],
181
- claudeSkipPermissions: config.get("claudeSkipPermissions") ?? true
182
- };
183
- }
184
- function getDefaultTerminal() {
185
- return config.get("defaultTerminal") || "auto";
186
- }
187
- function setDefaultTerminal(terminal) {
188
- config.set("defaultTerminal", terminal);
189
- }
190
- function getClaudeSkipPermissions() {
191
- return config.get("claudeSkipPermissions") ?? true;
192
- }
193
- function setClaudeSkipPermissions(skip) {
194
- config.set("claudeSkipPermissions", skip);
195
- }
196
- function getClaudeArgs() {
197
- return config.get("claudeArgs") || [];
198
- }
199
- function setClaudeArgs(args) {
200
- config.set("claudeArgs", args);
201
- }
202
- function getClaudeLaunchArgs() {
203
- const args = [];
204
- if (config.get("claudeSkipPermissions") ?? true) {
205
- args.push("--dangerously-skip-permissions");
206
- }
207
- const customArgs = config.get("claudeArgs") || [];
208
- args.push(...customArgs);
209
- return args;
210
- }
211
- function migrateConfig() {
212
- const currentEndpoint = config.get("apiEndpoint");
213
- if (currentEndpoint && OLD_API_ENDPOINTS.includes(currentEndpoint)) {
214
- config.set("apiEndpoint", DEFAULT_API_ENDPOINT);
215
- }
216
- }
217
-
218
- // src/services/api/client.ts
219
- var ApiClient = class {
220
- getHeaders() {
221
- const headers = {
222
- "Content-Type": "application/json"
223
- };
224
- const token = getToken();
225
- if (token) {
226
- headers["Authorization"] = `Bearer ${token}`;
227
- }
228
- return headers;
229
- }
230
- async request(endpoint, options = {}) {
231
- const baseUrl = getApiEndpoint();
232
- const url = `${baseUrl}${endpoint}`;
233
- const response = await fetch(url, {
234
- ...options,
235
- headers: {
236
- ...this.getHeaders(),
237
- ...options.headers
238
- }
239
- });
240
- if (!response.ok) {
241
- const error = await response.json().catch(() => ({ error: "Unknown error" }));
242
- throw new Error(error.error || error.message || `HTTP ${response.status}`);
243
- }
244
- return response.json();
245
- }
246
- // Auth endpoints
247
- async requestOtp(email) {
248
- return this.request("/auth/otp/request", {
249
- method: "POST",
250
- body: JSON.stringify({ email })
251
- });
252
- }
253
- async verifyOtp(token, otp) {
254
- return this.request("/auth/otp/verify", {
255
- method: "POST",
256
- body: JSON.stringify({ token, otp })
257
- });
258
- }
259
- async getCurrentUser() {
260
- return this.request("/auth/me");
261
- }
262
- // Project endpoints
263
- async getProjects() {
264
- return this.request("/projects");
265
- }
266
- async getProject(id) {
267
- return this.request(`/projects/${id}`);
268
- }
269
- async createOrUpdateProject(data) {
270
- return this.request("/projects", {
271
- method: "POST",
272
- body: JSON.stringify(data)
273
- });
274
- }
275
- async syncProject(id, data) {
276
- return this.request(`/projects/${id}/sync`, {
277
- method: "POST",
278
- body: JSON.stringify(data)
279
- });
280
- }
281
- async deleteProject(id) {
282
- return this.request(`/projects/${id}`, {
283
- method: "DELETE"
284
- });
285
- }
286
- async addMemory(projectId, memory) {
287
- return this.request(`/projects/${projectId}/memories`, {
288
- method: "POST",
289
- body: JSON.stringify(memory)
290
- });
291
- }
292
- async deleteMemory(projectId, memoryId) {
293
- return this.request(`/projects/${projectId}/memories/${memoryId}`, {
294
- method: "DELETE"
295
- });
296
- }
297
- async connectProjects(projectA, projectB, connectionType) {
298
- return this.request("/projects/connect", {
299
- method: "POST",
300
- body: JSON.stringify({
301
- projectA,
302
- projectB,
303
- connectionType: connectionType || "related"
304
- })
305
- });
306
- }
307
- async disconnectProjects(projectA, projectB) {
308
- return this.request("/projects/disconnect", {
309
- method: "DELETE",
310
- body: JSON.stringify({ projectA, projectB })
311
- });
312
- }
313
- async getStats() {
314
- return this.request("/projects/stats");
315
- }
316
- // Find project by path
317
- async findProjectByPath(path16) {
318
- const projects = await this.getProjects();
319
- return projects.find((p) => p.path === path16) || null;
320
- }
321
- // ============================================
322
- // Secrets Vault Endpoints
323
- // ============================================
324
- /**
325
- * List all secrets (metadata only, no values)
326
- */
327
- async listSecrets(projectId) {
328
- const params = projectId ? `?projectId=${projectId}` : "";
329
- return this.request(`/secrets${params}`);
330
- }
331
- /**
332
- * Add a new secret
333
- */
334
- async addSecret(data) {
335
- return this.request("/secrets", {
336
- method: "POST",
337
- body: JSON.stringify(data)
338
- });
339
- }
340
- /**
341
- * Get a secret value (decrypted)
342
- */
343
- async getSecret(key, projectId) {
344
- const params = projectId ? `?projectId=${projectId}` : "";
345
- return this.request(`/secrets/${encodeURIComponent(key)}${params}`);
346
- }
347
- /**
348
- * Delete a secret
349
- */
350
- async deleteSecret(key, projectId) {
351
- const params = projectId ? `?projectId=${projectId}` : "";
352
- return this.request(`/secrets/${encodeURIComponent(key)}${params}`, {
353
- method: "DELETE"
354
- });
355
- }
356
- /**
357
- * Get all secrets for injection (decrypted values)
358
- * Used by session start hook
359
- */
360
- async getSecretsForInjection(projectId) {
361
- const params = projectId ? `?projectId=${projectId}` : "";
362
- return this.request(`/secrets/inject${params}`);
363
- }
364
- // ============================================
365
- // Settings Sync Endpoints (Phase 10)
366
- // Pfad: /api/settings (nicht /api/user/settings)
367
- // ============================================
368
- /**
369
- * Get current user settings from cloud
370
- */
371
- async getUserSettings() {
372
- return this.request("/settings");
373
- }
374
- /**
375
- * Update user settings in cloud
376
- */
377
- async updateUserSettings(data) {
378
- return this.request("/settings", {
379
- method: "PUT",
380
- body: JSON.stringify(data)
381
- });
382
- }
383
- /**
384
- * Sync settings with conflict detection
385
- */
386
- async syncUserSettings(data) {
387
- return this.request("/settings/sync", {
388
- method: "POST",
389
- body: JSON.stringify(data)
390
- });
391
- }
392
- /**
393
- * Get settings change history
394
- */
395
- async getSettingsHistory() {
396
- return this.request("/settings/history");
397
- }
398
- /**
399
- * Export settings
400
- */
401
- async exportSettings() {
402
- return this.request("/settings/export");
403
- }
404
- /**
405
- * Import settings
406
- */
407
- async importSettings(data) {
408
- return this.request("/settings/import", {
409
- method: "POST",
410
- body: JSON.stringify(data)
411
- });
412
- }
413
- // ============================================
414
- // Dashboard/Analytics Endpoints (Phase 12)
415
- // Pfad: /api/analytics (nicht /api/dashboard)
416
- // ============================================
417
- /**
418
- * Get dashboard overview data (Pro Feature)
419
- */
420
- async getDashboardOverview() {
421
- return this.request("/analytics/overview");
422
- }
423
- /**
424
- * Get usage statistics (Pro Feature)
425
- */
426
- async getUsageStats() {
427
- return this.request("/analytics/usage");
428
- }
429
- /**
430
- * Get project analytics (Pro Feature)
431
- */
432
- async getProjectAnalytics() {
433
- return this.request("/analytics/projects");
434
- }
435
- /**
436
- * Get activity feed (Pro Feature)
437
- */
438
- async getActivityFeed() {
439
- return this.request("/analytics/activity");
440
- }
441
- // Legacy aliases for backwards compatibility
442
- async getDashboardProjects() {
443
- return this.getProjectAnalytics();
444
- }
445
- async getDashboardAnalytics(days) {
446
- return this.getUsageStats();
447
- }
448
- // ============================================
449
- // Sessions Endpoints (Cloud-synced sessions)
450
- // ============================================
451
- /**
452
- * Get all sessions from cloud
453
- */
454
- async getSessions() {
455
- return this.request("/sessions");
456
- }
457
- /**
458
- * Sync a session to cloud
459
- */
460
- async syncSession(data) {
461
- return this.request("/sessions", {
462
- method: "POST",
463
- body: JSON.stringify(data)
464
- });
465
- }
466
- /**
467
- * Get a specific session from cloud
468
- */
469
- async getSession(sessionId) {
470
- return this.request(`/sessions/${sessionId}`);
471
- }
472
- /**
473
- * Delete a session from cloud
474
- */
475
- async deleteSession(sessionId) {
476
- return this.request(`/sessions/${sessionId}`, {
477
- method: "DELETE"
478
- });
479
- }
480
- // ============================================
481
- // Memories Endpoints (standalone)
482
- // ============================================
483
- /**
484
- * Get all memories across projects
485
- */
486
- async getAllMemories() {
487
- return this.request("/memories");
488
- }
489
- /**
490
- * Search memories
491
- */
492
- async searchMemories(query) {
493
- return this.request(`/memories/search?q=${encodeURIComponent(query)}`);
494
- }
495
- // ============================================
496
- // Hooks Endpoints (Cloud-managed hooks)
497
- // ============================================
498
- /**
499
- * Get hook configuration from cloud
500
- */
501
- async getHooks() {
502
- return this.request("/hooks");
503
- }
504
- /**
505
- * Update hook configuration
506
- */
507
- async updateHooks(hooks) {
508
- return this.request("/hooks", {
509
- method: "PUT",
510
- body: JSON.stringify({ hooks })
511
- });
512
- }
513
- // ============================================
514
- // Two-Factor Authentication Endpoints (Phase 15)
515
- // ============================================
516
- /**
517
- * Initialize 2FA setup
518
- */
519
- async setup2FA() {
520
- return this.request("/auth/2fa/setup", {
521
- method: "POST"
522
- });
523
- }
524
- /**
525
- * Verify 2FA setup with code
526
- */
527
- async verify2FA(code) {
528
- return this.request("/auth/2fa/verify", {
529
- method: "POST",
530
- body: JSON.stringify({ code })
531
- });
532
- }
533
- /**
534
- * Verify 2FA code during login
535
- */
536
- async verify2FACode(code) {
537
- return this.request("/auth/2fa/check", {
538
- method: "POST",
539
- body: JSON.stringify({ code })
540
- });
541
- }
542
- /**
543
- * Verify backup code
544
- */
545
- async verifyBackupCode(code) {
546
- return this.request("/auth/2fa/backup", {
547
- method: "POST",
548
- body: JSON.stringify({ code })
549
- });
550
- }
551
- /**
552
- * Get 2FA status
553
- */
554
- async get2FAStatus() {
555
- return this.request("/auth/2fa/status");
556
- }
557
- /**
558
- * Disable 2FA
559
- */
560
- async disable2FA(code) {
561
- return this.request("/auth/2fa", {
562
- method: "DELETE",
563
- body: JSON.stringify({ code })
564
- });
565
- }
566
- /**
567
- * Regenerate backup codes
568
- */
569
- async regenerateBackupCodes() {
570
- return this.request("/auth/2fa/backup-codes", {
571
- method: "POST"
572
- });
573
- }
574
- // ============================================
575
- // Trusted Devices Endpoints (Phase 15)
576
- // ============================================
577
- /**
578
- * Get all trusted devices
579
- */
580
- async getDevices() {
581
- return this.request("/auth/devices");
582
- }
583
- /**
584
- * Trust a device
585
- */
586
- async trustDevice(data) {
587
- return this.request("/auth/devices", {
588
- method: "POST",
589
- body: JSON.stringify(data)
590
- });
591
- }
592
- /**
593
- * Revoke a device
594
- */
595
- async revokeDevice(deviceId) {
596
- return this.request(`/auth/devices/${deviceId}`, {
597
- method: "DELETE"
598
- });
599
- }
600
- /**
601
- * Revoke all devices
602
- */
603
- async revokeAllDevices() {
604
- return this.request("/auth/devices/all", {
605
- method: "DELETE"
606
- });
607
- }
608
- // ============================================
609
- // Project Security Endpoints (Phase 15)
610
- // ============================================
611
- /**
612
- * Get project security config
613
- */
614
- async getProjectSecurity(projectId) {
615
- return this.request(`/projects/${projectId}/security`);
616
- }
617
- /**
618
- * Update project security config
619
- */
620
- async updateProjectSecurity(projectId, security) {
621
- return this.request(`/projects/${projectId}/security`, {
622
- method: "PUT",
623
- body: JSON.stringify({ security })
624
- });
625
- }
626
- // ============================================
627
- // Project Team/Collaborators Endpoints (Phase 15)
628
- // ============================================
629
- /**
630
- * Get project team
631
- */
632
- async getProjectTeam(projectId) {
633
- return this.request(`/projects/${projectId}/team`);
634
- }
635
- /**
636
- * Add collaborator
637
- */
638
- async addCollaborator(projectId, email, role) {
639
- return this.request(`/projects/${projectId}/team`, {
640
- method: "POST",
641
- body: JSON.stringify({ email, role })
642
- });
643
- }
644
- /**
645
- * Remove collaborator
646
- */
647
- async removeCollaborator(projectId, userId) {
648
- return this.request(`/projects/${projectId}/team/${userId}`, {
649
- method: "DELETE"
650
- });
651
- }
652
- /**
653
- * Update collaborator role
654
- */
655
- async updateCollaboratorRole(projectId, userId, role) {
656
- return this.request(`/projects/${projectId}/team/${userId}`, {
657
- method: "PATCH",
658
- body: JSON.stringify({ role })
659
- });
660
- }
661
- /**
662
- * Send project invitation
663
- */
664
- async sendProjectInvite(projectId, email, role) {
665
- return this.request(`/projects/${projectId}/invite`, {
666
- method: "POST",
667
- body: JSON.stringify({ email, role })
668
- });
669
- }
670
- /**
671
- * Transfer project ownership
672
- */
673
- async transferProjectOwnership(projectId, newOwnerEmail) {
674
- return this.request(`/projects/${projectId}/transfer`, {
675
- method: "POST",
676
- body: JSON.stringify({ email: newOwnerEmail })
677
- });
678
- }
679
- };
680
- var api = new ApiClient();
681
-
682
113
  // src/utils/logger.ts
683
114
  import chalk from "chalk";
684
115
  var log = {
@@ -893,21 +324,21 @@ function generateBackupCodes(count = 10) {
893
324
  return codes;
894
325
  }
895
326
  function generateDeviceFingerprint() {
896
- const os8 = __require("os");
327
+ const os7 = __require("os");
897
328
  const components = [
898
- os8.hostname(),
899
- os8.platform(),
900
- os8.arch(),
901
- os8.cpus()[0]?.model || "unknown",
902
- os8.userInfo().username
329
+ os7.hostname(),
330
+ os7.platform(),
331
+ os7.arch(),
332
+ os7.cpus()[0]?.model || "unknown",
333
+ os7.userInfo().username
903
334
  ];
904
335
  const fingerprint = crypto.createHash("sha256").update(components.join("|")).digest("hex").slice(0, 32);
905
336
  return fingerprint;
906
337
  }
907
338
  function getDeviceName() {
908
- const os8 = __require("os");
909
- const hostname = os8.hostname();
910
- const platform = os8.platform();
339
+ const os7 = __require("os");
340
+ const hostname = os7.hostname();
341
+ const platform = os7.platform();
911
342
  const platformNames = {
912
343
  darwin: "macOS",
913
344
  linux: "Linux",
@@ -1457,11 +888,11 @@ function startCallbackServer(port) {
1457
888
  });
1458
889
  }
1459
890
  async function loginWithBrowser() {
1460
- const config2 = getConfig();
891
+ const config = getConfig();
1461
892
  try {
1462
893
  const port = await findAvailablePort();
1463
894
  const callbackUrl = `http://127.0.0.1:${port}/callback`;
1464
- const baseUrl = config2.apiEndpoint.replace("/api", "");
895
+ const baseUrl = config.apiEndpoint.replace("/api", "");
1465
896
  const loginUrl = `${baseUrl}/auth/cli-login?callback=${encodeURIComponent(callbackUrl)}`;
1466
897
  const serverPromise = startCallbackServer(port);
1467
898
  log.newline();
@@ -1519,7 +950,7 @@ async function loginWithBrowser() {
1519
950
  log.error(`Login fehlgeschlagen: ${message}`);
1520
951
  log.newline();
1521
952
  log.info("Fallback: Manueller Token-Eintrag");
1522
- const loginUrl = `${config2.apiEndpoint.replace("/api", "")}/auth/cli-login`;
953
+ const loginUrl = `${config.apiEndpoint.replace("/api", "")}/auth/cli-login`;
1523
954
  log.dim(`URL: ${loginUrl}`);
1524
955
  log.newline();
1525
956
  const { useManual } = await inquirer.prompt([{
@@ -1615,8 +1046,8 @@ async function prompt2FAVerification() {
1615
1046
  // src/commands/auth/login.ts
1616
1047
  var loginCommand = new Command("login").description("Mit shiva.li anmelden").option("-e, --email <email>", "Email-Adresse f\xFCr OTP-Login").option("--otp", "OTP-Login statt Browser verwenden").action(async (options) => {
1617
1048
  if (isAuthenticated()) {
1618
- const config2 = getConfig();
1619
- log.info(`Bereits angemeldet als ${config2.email}`);
1049
+ const config = getConfig();
1050
+ log.info(`Bereits angemeldet als ${config.email}`);
1620
1051
  const { relogin } = await inquirer2.prompt([
1621
1052
  {
1622
1053
  type: "confirm",
@@ -2292,10 +1723,10 @@ var statusCommand = new Command4("status").description("Status des aktuellen Pro
2292
1723
  }
2293
1724
  log.newline();
2294
1725
  const stats = await api.getStats();
2295
- const config2 = getConfig();
1726
+ const config = getConfig();
2296
1727
  log.keyValue(
2297
1728
  "Tier",
2298
- `${config2.tier?.toUpperCase() || "FREE"} (${stats.projects.total}/${stats.projects.limit} Projekte)`
1729
+ `${config.tier?.toUpperCase() || "FREE"} (${stats.projects.total}/${stats.projects.limit} Projekte)`
2299
1730
  );
2300
1731
  } catch (error) {
2301
1732
  process.stdout.write("\x1B[1A\x1B[2K");
@@ -2405,9 +1836,9 @@ var Errors = {
2405
1836
  "Bitte sp\xE4ter erneut versuchen"
2406
1837
  ),
2407
1838
  // File/Path errors
2408
- PATH_NOT_FOUND: (path16) => new ShivaError(
1839
+ PATH_NOT_FOUND: (path15) => new ShivaError(
2409
1840
  "PATH_404",
2410
- path16 ? `Pfad nicht gefunden: ${path16}` : "Pfad nicht gefunden",
1841
+ path15 ? `Pfad nicht gefunden: ${path15}` : "Pfad nicht gefunden",
2411
1842
  "Pfad \xFCberpr\xFCfen und erneut versuchen"
2412
1843
  ),
2413
1844
  FILE_NOT_FOUND: (file) => new ShivaError(
@@ -2415,9 +1846,9 @@ var Errors = {
2415
1846
  file ? `Datei nicht gefunden: ${file}` : "Datei nicht gefunden",
2416
1847
  void 0
2417
1848
  ),
2418
- PERMISSION_DENIED: (path16) => new ShivaError(
1849
+ PERMISSION_DENIED: (path15) => new ShivaError(
2419
1850
  "PERMISSION_DENIED",
2420
- path16 ? `Keine Berechtigung: ${path16}` : "Keine Berechtigung",
1851
+ path15 ? `Keine Berechtigung: ${path15}` : "Keine Berechtigung",
2421
1852
  "Berechtigungen pr\xFCfen oder mit sudo ausf\xFChren"
2422
1853
  ),
2423
1854
  // Package errors
@@ -2684,8 +2115,8 @@ import ora3 from "ora";
2684
2115
 
2685
2116
  // src/services/data/settings-sync.ts
2686
2117
  import * as crypto2 from "crypto";
2687
- import Conf2 from "conf";
2688
- var settingsStore = new Conf2({
2118
+ import Conf from "conf";
2119
+ var settingsStore = new Conf({
2689
2120
  projectName: "shiva-code-settings",
2690
2121
  defaults: {
2691
2122
  syncableSettings: {
@@ -3092,7 +2523,7 @@ var configCommand = new Command6("config").description("Konfiguration anzeigen o
3092
2523
  log.success("Konfiguration zur\xFCckgesetzt");
3093
2524
  return;
3094
2525
  }
3095
- const config2 = getConfig();
2526
+ const config = getConfig();
3096
2527
  if (options.list || !key && !value) {
3097
2528
  log.brand();
3098
2529
  log.header("Konfiguration");
@@ -3100,9 +2531,9 @@ var configCommand = new Command6("config").description("Konfiguration anzeigen o
3100
2531
  log.keyValue("Config Pfad", CONFIG_PATH);
3101
2532
  log.newline();
3102
2533
  console.log(colors.dim("Cloud:"));
3103
- log.keyValue(" API Endpoint", config2.apiEndpoint || "https://shiva-ai-api.slither-mutiplayer.workers.dev");
3104
- log.keyValue(" User", config2.email || colors.dim("nicht angemeldet"));
3105
- log.keyValue(" Tier", config2.tier?.toUpperCase() || "FREE");
2534
+ log.keyValue(" API Endpoint", config.apiEndpoint || "https://shiva-ai-api.slither-mutiplayer.workers.dev");
2535
+ log.keyValue(" User", config.email || colors.dim("nicht angemeldet"));
2536
+ log.keyValue(" Tier", config.tier?.toUpperCase() || "FREE");
3106
2537
  const token = getToken();
3107
2538
  if (token) {
3108
2539
  const masked = token.slice(0, 8) + "..." + token.slice(-4);
@@ -3129,7 +2560,7 @@ var configCommand = new Command6("config").description("Konfiguration anzeigen o
3129
2560
  log.info(`G\xFCltige Schl\xFCssel: ${validKeys.join(", ")}`);
3130
2561
  return;
3131
2562
  }
3132
- const configValue = key === "token" ? getToken() : config2[key];
2563
+ const configValue = key === "token" ? getToken() : config[key];
3133
2564
  if (configValue) {
3134
2565
  if (key === "token") {
3135
2566
  const masked = String(configValue).slice(0, 8) + "..." + String(configValue).slice(-4);
@@ -3164,13 +2595,13 @@ var configCommand = new Command6("config").description("Konfiguration anzeigen o
3164
2595
  }
3165
2596
  });
3166
2597
  configCommand.command("get <key>").description("Konfigurationswert anzeigen").action((key) => {
3167
- const config2 = getConfig();
2598
+ const config = getConfig();
3168
2599
  const validKeys = ["apiEndpoint", "email", "userId", "tier"];
3169
2600
  if (!validKeys.includes(key)) {
3170
2601
  log.error(`Unbekannter Schl\xFCssel: ${key}`);
3171
2602
  return;
3172
2603
  }
3173
- const value = config2[key];
2604
+ const value = config[key];
3174
2605
  if (value) {
3175
2606
  console.log(value);
3176
2607
  } else {
@@ -3640,11 +3071,11 @@ var projectsCommand = new Command8("projects").description("Alle Projekte auflis
3640
3071
  }
3641
3072
  }
3642
3073
  log.newline();
3643
- const config2 = getConfig();
3074
+ const config = getConfig();
3644
3075
  const usagePercent = stats.projects.total / stats.projects.limit * 100;
3645
3076
  if (usagePercent >= 80) {
3646
3077
  log.warn(`Du nutzt ${Math.round(usagePercent)}% deines Projekt-Limits.`);
3647
- if (config2.tier === "free") {
3078
+ if (config.tier === "free") {
3648
3079
  log.info("Upgrade auf Pro f\xFCr mehr Projekte: https://shiva.li/pricing");
3649
3080
  }
3650
3081
  }
@@ -3688,45 +3119,45 @@ function getCurrentTimeInMinutes(timezone) {
3688
3119
  const timeStr = now.toLocaleTimeString("de-DE", options);
3689
3120
  return parseTime(timeStr);
3690
3121
  }
3691
- function checkTimeRestrictions(config2) {
3692
- if (!config2.enabled) {
3122
+ function checkTimeRestrictions(config) {
3123
+ if (!config.enabled) {
3693
3124
  return { allowed: true };
3694
3125
  }
3695
- const currentDay = getCurrentDayOfWeek(config2.timezone);
3696
- const currentMinutes = getCurrentTimeInMinutes(config2.timezone);
3697
- if (!config2.allowedDays.includes(currentDay)) {
3126
+ const currentDay = getCurrentDayOfWeek(config.timezone);
3127
+ const currentMinutes = getCurrentTimeInMinutes(config.timezone);
3128
+ if (!config.allowedDays.includes(currentDay)) {
3698
3129
  const dayNames = ["", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"];
3699
- const allowedDayNames = config2.allowedDays.map((d) => dayNames[d]).join(", ");
3130
+ const allowedDayNames = config.allowedDays.map((d) => dayNames[d]).join(", ");
3700
3131
  return {
3701
3132
  allowed: false,
3702
3133
  reason: `Sessions sind nur an folgenden Tagen erlaubt: ${allowedDayNames}`,
3703
- nextAllowedTime: `${dayNames[config2.allowedDays[0]]} ${config2.allowedHours.start}`
3134
+ nextAllowedTime: `${dayNames[config.allowedDays[0]]} ${config.allowedHours.start}`
3704
3135
  };
3705
3136
  }
3706
- const startMinutes = parseTime(config2.allowedHours.start);
3707
- const endMinutes = parseTime(config2.allowedHours.end);
3137
+ const startMinutes = parseTime(config.allowedHours.start);
3138
+ const endMinutes = parseTime(config.allowedHours.end);
3708
3139
  if (currentMinutes < startMinutes) {
3709
3140
  return {
3710
3141
  allowed: false,
3711
- reason: `Sessions sind erst ab ${config2.allowedHours.start} erlaubt`,
3712
- nextAllowedTime: config2.allowedHours.start
3142
+ reason: `Sessions sind erst ab ${config.allowedHours.start} erlaubt`,
3143
+ nextAllowedTime: config.allowedHours.start
3713
3144
  };
3714
3145
  }
3715
3146
  if (currentMinutes >= endMinutes) {
3716
3147
  return {
3717
3148
  allowed: false,
3718
- reason: `Sessions sind nur bis ${config2.allowedHours.end} erlaubt`,
3719
- nextAllowedTime: `Morgen ${config2.allowedHours.start}`
3149
+ reason: `Sessions sind nur bis ${config.allowedHours.end} erlaubt`,
3150
+ nextAllowedTime: `Morgen ${config.allowedHours.start}`
3720
3151
  };
3721
3152
  }
3722
3153
  return { allowed: true };
3723
3154
  }
3724
- function getRemainingSessionTime(config2) {
3725
- if (!config2.enabled) {
3155
+ function getRemainingSessionTime(config) {
3156
+ if (!config.enabled) {
3726
3157
  return null;
3727
3158
  }
3728
- const currentMinutes = getCurrentTimeInMinutes(config2.timezone);
3729
- const endMinutes = parseTime(config2.allowedHours.end);
3159
+ const currentMinutes = getCurrentTimeInMinutes(config.timezone);
3160
+ const endMinutes = parseTime(config.allowedHours.end);
3730
3161
  if (currentMinutes >= endMinutes) {
3731
3162
  return 0;
3732
3163
  }
@@ -3857,9 +3288,9 @@ function checkSessionLimits(limits, currentDuration = 0, currentTokens = 0) {
3857
3288
  var SessionController = class {
3858
3289
  projectPath;
3859
3290
  config;
3860
- constructor(projectPath, config2) {
3291
+ constructor(projectPath, config) {
3861
3292
  this.projectPath = projectPath;
3862
- this.config = config2;
3293
+ this.config = config;
3863
3294
  }
3864
3295
  /**
3865
3296
  * Check all session restrictions before starting
@@ -3965,8 +3396,8 @@ var SessionController = class {
3965
3396
  return lines;
3966
3397
  }
3967
3398
  };
3968
- function createSessionController(projectPath, config2) {
3969
- return new SessionController(projectPath, config2);
3399
+ function createSessionController(projectPath, config) {
3400
+ return new SessionController(projectPath, config);
3970
3401
  }
3971
3402
  function parseHoursString(hoursStr) {
3972
3403
  const match = hoursStr.match(/^(\d{2}:\d{2})-(\d{2}:\d{2})$/);
@@ -4012,9 +3443,9 @@ var timeCommand = new Command9("time").description("Session-Zeitfenster konfigur
4012
3443
  if (!hasShivaDir(projectPath)) {
4013
3444
  initShivaDir(projectPath);
4014
3445
  }
4015
- const config2 = getSessionConfig(projectPath);
3446
+ const config = getSessionConfig(projectPath);
4016
3447
  if (options.status || Object.keys(options).length === 0) {
4017
- displayTimeStatus(config2.timeControl);
3448
+ displayTimeStatus(config.timeControl);
4018
3449
  return;
4019
3450
  }
4020
3451
  if (options.enable) {
@@ -4052,17 +3483,17 @@ var timeCommand = new Command9("time").description("Session-Zeitfenster konfigur
4052
3483
  const updated = getSessionConfig(projectPath);
4053
3484
  displayTimeStatus(updated.timeControl);
4054
3485
  });
4055
- function displayTimeStatus(config2) {
3486
+ function displayTimeStatus(config) {
4056
3487
  log.newline();
4057
3488
  console.log(colors.orange.bold("Session-Zeitkontrolle"));
4058
3489
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4059
3490
  log.newline();
4060
- log.keyValue("Status", config2.enabled ? colors.green("Aktiv") : colors.dim("Inaktiv"));
4061
- log.keyValue("Arbeitszeiten", `${config2.allowedHours.start} - ${config2.allowedHours.end}`);
3491
+ log.keyValue("Status", config.enabled ? colors.green("Aktiv") : colors.dim("Inaktiv"));
3492
+ log.keyValue("Arbeitszeiten", `${config.allowedHours.start} - ${config.allowedHours.end}`);
4062
3493
  const dayNames = ["", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];
4063
- const days = config2.allowedDays.map((d) => dayNames[d]).join(", ");
3494
+ const days = config.allowedDays.map((d) => dayNames[d]).join(", ");
4064
3495
  log.keyValue("Erlaubte Tage", days);
4065
- log.keyValue("Zeitzone", config2.timezone);
3496
+ log.keyValue("Zeitzone", config.timezone);
4066
3497
  log.newline();
4067
3498
  }
4068
3499
  projectCommand.addCommand(timeCommand);
@@ -4071,9 +3502,9 @@ var limitsCommand = new Command9("limits").description("Session-Limits konfiguri
4071
3502
  if (!hasShivaDir(projectPath)) {
4072
3503
  initShivaDir(projectPath);
4073
3504
  }
4074
- const config2 = getSessionConfig(projectPath);
3505
+ const config = getSessionConfig(projectPath);
4075
3506
  if (options.status || Object.keys(options).length === 0) {
4076
- displayLimitsStatus(config2.limits);
3507
+ displayLimitsStatus(config.limits);
4077
3508
  return;
4078
3509
  }
4079
3510
  if (options.reset) {
@@ -4115,14 +3546,14 @@ var limitsCommand = new Command9("limits").description("Session-Limits konfiguri
4115
3546
  }
4116
3547
  displayLimitsStatus(getSessionConfig(projectPath).limits);
4117
3548
  });
4118
- function displayLimitsStatus(config2) {
3549
+ function displayLimitsStatus(config) {
4119
3550
  log.newline();
4120
3551
  console.log(colors.orange.bold("Session-Limits"));
4121
3552
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4122
3553
  log.newline();
4123
- log.keyValue("Max. Dauer", config2.maxDurationMinutes ? `${config2.maxDurationMinutes} Minuten` : colors.dim("Unbegrenzt"));
4124
- log.keyValue("Max. Tokens", config2.maxTokens ? formatTokens(config2.maxTokens) : colors.dim("Unbegrenzt"));
4125
- log.keyValue("Warnschwelle", `${(config2.warningThreshold * 100).toFixed(0)}%`);
3554
+ log.keyValue("Max. Dauer", config.maxDurationMinutes ? `${config.maxDurationMinutes} Minuten` : colors.dim("Unbegrenzt"));
3555
+ log.keyValue("Max. Tokens", config.maxTokens ? formatTokens(config.maxTokens) : colors.dim("Unbegrenzt"));
3556
+ log.keyValue("Warnschwelle", `${(config.warningThreshold * 100).toFixed(0)}%`);
4126
3557
  log.newline();
4127
3558
  }
4128
3559
  projectCommand.addCommand(limitsCommand);
@@ -4131,9 +3562,9 @@ var budgetCommand = new Command9("budget").description("Token-Budget verwalten")
4131
3562
  if (!hasShivaDir(projectPath)) {
4132
3563
  initShivaDir(projectPath);
4133
3564
  }
4134
- const config2 = getSessionConfig(projectPath);
3565
+ const config = getSessionConfig(projectPath);
4135
3566
  if (options.status || Object.keys(options).length === 0) {
4136
- displayBudgetStatus(config2.budget);
3567
+ displayBudgetStatus(config.budget);
4137
3568
  return;
4138
3569
  }
4139
3570
  if (options.reset) {
@@ -4181,31 +3612,31 @@ var budgetCommand = new Command9("budget").description("Token-Budget verwalten")
4181
3612
  }
4182
3613
  displayBudgetStatus(getSessionConfig(projectPath).budget);
4183
3614
  });
4184
- function displayBudgetStatus(config2) {
3615
+ function displayBudgetStatus(config) {
4185
3616
  log.newline();
4186
3617
  console.log(colors.orange.bold("Token-Budget"));
4187
3618
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4188
3619
  log.newline();
4189
- if (config2.dailyTokenLimit) {
4190
- const pct = (config2.currentUsage.daily / config2.dailyTokenLimit * 100).toFixed(0);
4191
- const bar = createProgressBar(config2.currentUsage.daily, config2.dailyTokenLimit);
4192
- log.keyValue("T\xE4glich", `${formatTokens(config2.currentUsage.daily)}/${formatTokens(config2.dailyTokenLimit)} (${pct}%)`);
3620
+ if (config.dailyTokenLimit) {
3621
+ const pct = (config.currentUsage.daily / config.dailyTokenLimit * 100).toFixed(0);
3622
+ const bar = createProgressBar(config.currentUsage.daily, config.dailyTokenLimit);
3623
+ log.keyValue("T\xE4glich", `${formatTokens(config.currentUsage.daily)}/${formatTokens(config.dailyTokenLimit)} (${pct}%)`);
4193
3624
  console.log(` ${bar}`);
4194
3625
  } else {
4195
3626
  log.keyValue("T\xE4glich", colors.dim("Kein Limit"));
4196
3627
  }
4197
- if (config2.weeklyTokenLimit) {
4198
- const pct = (config2.currentUsage.weekly / config2.weeklyTokenLimit * 100).toFixed(0);
4199
- const bar = createProgressBar(config2.currentUsage.weekly, config2.weeklyTokenLimit);
4200
- log.keyValue("W\xF6chentl.", `${formatTokens(config2.currentUsage.weekly)}/${formatTokens(config2.weeklyTokenLimit)} (${pct}%)`);
3628
+ if (config.weeklyTokenLimit) {
3629
+ const pct = (config.currentUsage.weekly / config.weeklyTokenLimit * 100).toFixed(0);
3630
+ const bar = createProgressBar(config.currentUsage.weekly, config.weeklyTokenLimit);
3631
+ log.keyValue("W\xF6chentl.", `${formatTokens(config.currentUsage.weekly)}/${formatTokens(config.weeklyTokenLimit)} (${pct}%)`);
4201
3632
  console.log(` ${bar}`);
4202
3633
  } else {
4203
3634
  log.keyValue("W\xF6chentl.", colors.dim("Kein Limit"));
4204
3635
  }
4205
- if (config2.monthlyTokenLimit) {
4206
- const pct = (config2.currentUsage.monthly / config2.monthlyTokenLimit * 100).toFixed(0);
4207
- const bar = createProgressBar(config2.currentUsage.monthly, config2.monthlyTokenLimit);
4208
- log.keyValue("Monatl.", `${formatTokens(config2.currentUsage.monthly)}/${formatTokens(config2.monthlyTokenLimit)} (${pct}%)`);
3636
+ if (config.monthlyTokenLimit) {
3637
+ const pct = (config.currentUsage.monthly / config.monthlyTokenLimit * 100).toFixed(0);
3638
+ const bar = createProgressBar(config.currentUsage.monthly, config.monthlyTokenLimit);
3639
+ log.keyValue("Monatl.", `${formatTokens(config.currentUsage.monthly)}/${formatTokens(config.monthlyTokenLimit)} (${pct}%)`);
4209
3640
  console.log(` ${bar}`);
4210
3641
  } else {
4211
3642
  log.keyValue("Monatl.", colors.dim("Kein Limit"));
@@ -4225,9 +3656,9 @@ var dockerSubCommand = new Command9("docker").description("Projekt-spezifische D
4225
3656
  if (!hasShivaDir(projectPath)) {
4226
3657
  initShivaDir(projectPath);
4227
3658
  }
4228
- const config2 = getProjectConfigV2(projectPath);
3659
+ const config = getProjectConfigV2(projectPath);
4229
3660
  if (options.status || Object.keys(options).length === 0) {
4230
- displayDockerStatus(config2.docker);
3661
+ displayDockerStatus(config.docker);
4231
3662
  return;
4232
3663
  }
4233
3664
  if (options.enable) {
@@ -4256,11 +3687,11 @@ var dockerSubCommand = new Command9("docker").description("Projekt-spezifische D
4256
3687
  log.success(`Netzwerk-Modus: ${options.network}`);
4257
3688
  }
4258
3689
  if (options.cpu) {
4259
- updateProjectDockerConfig(projectPath, { resources: { cpuLimit: options.cpu, memoryLimit: config2.docker.resources.memoryLimit } });
3690
+ updateProjectDockerConfig(projectPath, { resources: { cpuLimit: options.cpu, memoryLimit: config.docker.resources.memoryLimit } });
4260
3691
  log.success(`CPU-Limit: ${options.cpu}`);
4261
3692
  }
4262
3693
  if (options.memory) {
4263
- updateProjectDockerConfig(projectPath, { resources: { cpuLimit: config2.docker.resources.cpuLimit, memoryLimit: options.memory } });
3694
+ updateProjectDockerConfig(projectPath, { resources: { cpuLimit: config.docker.resources.cpuLimit, memoryLimit: options.memory } });
4264
3695
  log.success(`Memory-Limit: ${options.memory}`);
4265
3696
  }
4266
3697
  if (options.mount) {
@@ -4283,22 +3714,22 @@ var dockerSubCommand = new Command9("docker").description("Projekt-spezifische D
4283
3714
  }
4284
3715
  displayDockerStatus(getProjectConfigV2(projectPath).docker);
4285
3716
  });
4286
- function displayDockerStatus(config2) {
3717
+ function displayDockerStatus(config) {
4287
3718
  log.newline();
4288
3719
  console.log(colors.orange.bold("Docker-Konfiguration (Projekt)"));
4289
3720
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4290
3721
  log.newline();
4291
- const enabled = config2.enabled === "inherit" ? colors.dim("(erbt von global)") : config2.enabled ? colors.green("Aktiviert") : colors.dim("Deaktiviert");
3722
+ const enabled = config.enabled === "inherit" ? colors.dim("(erbt von global)") : config.enabled ? colors.green("Aktiviert") : colors.dim("Deaktiviert");
4292
3723
  log.keyValue("Status", enabled);
4293
- log.keyValue("Image", config2.image === "default" ? colors.dim("(Standard)") : config2.image);
4294
- log.keyValue("Netzwerk", config2.network);
4295
- if (config2.resources.cpuLimit || config2.resources.memoryLimit) {
4296
- log.keyValue("Ressourcen", `CPU: ${config2.resources.cpuLimit || "-"}, Memory: ${config2.resources.memoryLimit || "-"}`);
3724
+ log.keyValue("Image", config.image === "default" ? colors.dim("(Standard)") : config.image);
3725
+ log.keyValue("Netzwerk", config.network);
3726
+ if (config.resources.cpuLimit || config.resources.memoryLimit) {
3727
+ log.keyValue("Ressourcen", `CPU: ${config.resources.cpuLimit || "-"}, Memory: ${config.resources.memoryLimit || "-"}`);
4297
3728
  }
4298
- if (config2.mounts.length > 0) {
3729
+ if (config.mounts.length > 0) {
4299
3730
  log.newline();
4300
3731
  log.plain("Mounts:");
4301
- for (const mount of config2.mounts) {
3732
+ for (const mount of config.mounts) {
4302
3733
  log.plain(` ${mount.host} -> ${mount.container} (${mount.mode})`);
4303
3734
  }
4304
3735
  }
@@ -4310,9 +3741,9 @@ var analyticsCommand = new Command9("analytics").description("Projekt-Analytics
4310
3741
  if (!hasShivaDir(projectPath)) {
4311
3742
  initShivaDir(projectPath);
4312
3743
  }
4313
- const config2 = getAnalyticsConfig(projectPath);
3744
+ const config = getAnalyticsConfig(projectPath);
4314
3745
  if (options.status || Object.keys(options).length === 0) {
4315
- displayAnalyticsStatus(config2);
3746
+ displayAnalyticsStatus(config);
4316
3747
  return;
4317
3748
  }
4318
3749
  if (options.enable) {
@@ -4342,15 +3773,15 @@ var analyticsCommand = new Command9("analytics").description("Projekt-Analytics
4342
3773
  }
4343
3774
  displayAnalyticsStatus(getAnalyticsConfig(projectPath));
4344
3775
  });
4345
- function displayAnalyticsStatus(config2) {
3776
+ function displayAnalyticsStatus(config) {
4346
3777
  log.newline();
4347
3778
  console.log(colors.orange.bold("Analytics-Konfiguration"));
4348
3779
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4349
3780
  log.newline();
4350
- log.keyValue("Status", config2.enabled ? colors.green("Aktiviert") : colors.dim("Deaktiviert"));
4351
- log.keyValue("Token-Tracking", config2.collectTokenUsage ? "Ja" : "Nein");
4352
- log.keyValue("Session-Historie", config2.collectSessionHistory ? "Ja" : "Nein");
4353
- log.keyValue("Aufbewahrung", `${config2.retentionDays} Tage`);
3781
+ log.keyValue("Status", config.enabled ? colors.green("Aktiviert") : colors.dim("Deaktiviert"));
3782
+ log.keyValue("Token-Tracking", config.collectTokenUsage ? "Ja" : "Nein");
3783
+ log.keyValue("Session-Historie", config.collectSessionHistory ? "Ja" : "Nein");
3784
+ log.keyValue("Aufbewahrung", `${config.retentionDays} Tage`);
4354
3785
  log.newline();
4355
3786
  }
4356
3787
  projectCommand.addCommand(analyticsCommand);
@@ -4371,15 +3802,15 @@ projectCommand.command("status").description("Projekt-Status anzeigen").action(a
4371
3802
  log.info("Initialisiere mit: shiva project time --enable");
4372
3803
  return;
4373
3804
  }
4374
- const config2 = getProjectConfigV2(projectPath);
4375
- const controller = createSessionController(projectPath, config2.session);
3805
+ const config = getProjectConfigV2(projectPath);
3806
+ const controller = createSessionController(projectPath, config.session);
4376
3807
  log.newline();
4377
3808
  console.log(colors.orange.bold("SHIVA Projekt-Status"));
4378
3809
  console.log(colors.dim("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
4379
3810
  log.newline();
4380
3811
  log.keyValue("Pfad", projectPath);
4381
- log.keyValue("Config-Version", String(config2.version));
4382
- log.keyValue("Security-Tier", config2.security.tier);
3812
+ log.keyValue("Config-Version", String(config.version));
3813
+ log.keyValue("Security-Tier", config.security.tier);
4383
3814
  log.newline();
4384
3815
  const guard = controller.checkSessionStart();
4385
3816
  if (guard.allowed) {
@@ -4405,19 +3836,19 @@ projectCommand.command("status").description("Projekt-Status anzeigen").action(a
4405
3836
  // src/commands/session/start.ts
4406
3837
  import { Command as Command10 } from "commander";
4407
3838
  import * as fs from "fs";
4408
- import * as path4 from "path";
3839
+ import * as path3 from "path";
4409
3840
  import ora6 from "ora";
4410
3841
  import { spawnSync as spawnSync4 } from "child_process";
4411
3842
 
4412
3843
  // src/services/infrastructure/terminal.ts
4413
3844
  import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
4414
- import * as path3 from "path";
4415
- import * as os3 from "os";
3845
+ import * as path2 from "path";
3846
+ import * as os2 from "os";
4416
3847
 
4417
3848
  // src/services/infrastructure/docker.ts
4418
3849
  import { spawn, spawnSync } from "child_process";
4419
- import * as path2 from "path";
4420
- import * as os2 from "os";
3850
+ import * as path from "path";
3851
+ import * as os from "os";
4421
3852
  var DockerService = class {
4422
3853
  cachedInfo = null;
4423
3854
  /**
@@ -4482,7 +3913,7 @@ var DockerService = class {
4482
3913
  findDockerSocket(runtime) {
4483
3914
  const possiblePaths = runtime === "docker" ? [
4484
3915
  "/var/run/docker.sock",
4485
- `${os2.homedir()}/.docker/run/docker.sock`
3916
+ `${os.homedir()}/.docker/run/docker.sock`
4486
3917
  ] : [
4487
3918
  `${process.env.XDG_RUNTIME_DIR || `/run/user/${process.getuid?.() || 1e3}`}/podman/podman.sock`,
4488
3919
  "/var/run/podman/podman.sock"
@@ -4614,35 +4045,35 @@ var DockerService = class {
4614
4045
  * Create a new container
4615
4046
  * SECURITY: Uses spawnSync with array args, validates all inputs
4616
4047
  */
4617
- async createContainer(config2) {
4048
+ async createContainer(config) {
4618
4049
  const cmd = this.getCommand();
4619
4050
  const args = ["create"];
4620
- if (config2.name) {
4621
- if (!this.isValidContainerNameInternal(config2.name)) {
4622
- throw new Error(`Invalid container name: ${sanitizeForLog(config2.name)}`);
4051
+ if (config.name) {
4052
+ if (!this.isValidContainerNameInternal(config.name)) {
4053
+ throw new Error(`Invalid container name: ${sanitizeForLog(config.name)}`);
4623
4054
  }
4624
- args.push("--name", config2.name);
4055
+ args.push("--name", config.name);
4625
4056
  }
4626
- if (!isValidProjectPath(config2.workdir)) {
4627
- throw new Error(`Invalid workdir: ${sanitizeForLog(config2.workdir)}`);
4057
+ if (!isValidProjectPath(config.workdir)) {
4058
+ throw new Error(`Invalid workdir: ${sanitizeForLog(config.workdir)}`);
4628
4059
  }
4629
- args.push("--workdir", config2.workdir);
4630
- for (const mount of config2.mounts) {
4060
+ args.push("--workdir", config.workdir);
4061
+ for (const mount of config.mounts) {
4631
4062
  if (!isValidProjectPath(mount.host)) {
4632
4063
  log.warn(`Skipping invalid mount path: ${sanitizeForLog(mount.host)}`);
4633
4064
  continue;
4634
4065
  }
4635
4066
  args.push("-v", `${mount.host}:${mount.container}:${mount.mode}`);
4636
4067
  }
4637
- for (const [key, value] of Object.entries(config2.env)) {
4068
+ for (const [key, value] of Object.entries(config.env)) {
4638
4069
  if (!/^[A-Z_][A-Z0-9_]*$/i.test(key)) {
4639
4070
  log.warn(`Skipping invalid env var name: ${sanitizeForLog(key)}`);
4640
4071
  continue;
4641
4072
  }
4642
4073
  args.push("-e", `${key}=${value}`);
4643
4074
  }
4644
- if (config2.ports) {
4645
- for (const [host, container] of Object.entries(config2.ports)) {
4075
+ if (config.ports) {
4076
+ for (const [host, container] of Object.entries(config.ports)) {
4646
4077
  if (!/^\d+$/.test(String(host)) || !/^\d+$/.test(String(container))) {
4647
4078
  log.warn(`Skipping invalid port mapping: ${host}:${container}`);
4648
4079
  continue;
@@ -4650,16 +4081,16 @@ var DockerService = class {
4650
4081
  args.push("-p", `${host}:${container}`);
4651
4082
  }
4652
4083
  }
4653
- if (config2.interactive) {
4084
+ if (config.interactive) {
4654
4085
  args.push("-it");
4655
4086
  }
4656
- if (config2.autoRemove) {
4087
+ if (config.autoRemove) {
4657
4088
  args.push("--rm");
4658
4089
  }
4659
- if (!this.isValidImage(config2.image)) {
4660
- throw new Error(`Invalid image: ${sanitizeForLog(config2.image)}`);
4090
+ if (!this.isValidImage(config.image)) {
4091
+ throw new Error(`Invalid image: ${sanitizeForLog(config.image)}`);
4661
4092
  }
4662
- args.push(config2.image);
4093
+ args.push(config.image);
4663
4094
  try {
4664
4095
  const result = spawnSync(cmd, args, {
4665
4096
  encoding: "utf8",
@@ -4805,10 +4236,10 @@ var DockerService = class {
4805
4236
  `${launch.projectPath}:/workspace:rw`,
4806
4237
  // Mount Claude config
4807
4238
  "-v",
4808
- `${path2.join(os2.homedir(), ".claude")}:/root/.claude:rw`,
4239
+ `${path.join(os.homedir(), ".claude")}:/root/.claude:rw`,
4809
4240
  // Mount SHIVA config
4810
4241
  "-v",
4811
- `${path2.join(os2.homedir(), ".config", "shiva-code")}:/root/.config/shiva-code:rw`
4242
+ `${path.join(os.homedir(), ".config", "shiva-code")}:/root/.config/shiva-code:rw`
4812
4243
  ];
4813
4244
  for (const [host, container] of Object.entries(settings.volumeMounts || {})) {
4814
4245
  if (isValidProjectPath(host)) {
@@ -4916,8 +4347,8 @@ var DockerService = class {
4916
4347
  const settings = settingsSync.getDockerSettings();
4917
4348
  return {
4918
4349
  [projectPath]: "/workspace",
4919
- [path2.join(os2.homedir(), ".claude")]: "/root/.claude",
4920
- [path2.join(os2.homedir(), ".config", "shiva-code")]: "/root/.config/shiva-code",
4350
+ [path.join(os.homedir(), ".claude")]: "/root/.claude",
4351
+ [path.join(os.homedir(), ".config", "shiva-code")]: "/root/.config/shiva-code",
4921
4352
  ...settings.volumeMounts
4922
4353
  };
4923
4354
  }
@@ -5132,8 +4563,8 @@ var DockerService = class {
5132
4563
  }
5133
4564
  }
5134
4565
  args.push("-v", `${launch.projectPath}:/workspace:rw`);
5135
- args.push("-v", `${path2.join(os2.homedir(), ".claude")}:/root/.claude:rw`);
5136
- args.push("-v", `${path2.join(os2.homedir(), ".config", "shiva-code")}:/root/.config/shiva-code:rw`);
4566
+ args.push("-v", `${path.join(os.homedir(), ".claude")}:/root/.claude:rw`);
4567
+ args.push("-v", `${path.join(os.homedir(), ".config", "shiva-code")}:/root/.config/shiva-code:rw`);
5137
4568
  for (const mount of effectiveConfig.mounts) {
5138
4569
  if (isValidProjectPath(mount.host)) {
5139
4570
  args.push("-v", `${mount.host}:${mount.container}:${mount.mode}`);
@@ -5488,7 +4919,7 @@ Attaching to: ${sanitizeForLog(firstProject.projectName)}`);
5488
4919
  }
5489
4920
  function buildSecureDockerArgs(project, settings, containerName) {
5490
4921
  const cmd = dockerService.getDockerInfo().runtime === "podman" ? "podman" : "docker";
5491
- const homeDir = os3.homedir();
4922
+ const homeDir = os2.homedir();
5492
4923
  const args = [
5493
4924
  cmd,
5494
4925
  "run",
@@ -5501,9 +4932,9 @@ function buildSecureDockerArgs(project, settings, containerName) {
5501
4932
  "-v",
5502
4933
  `${project.projectPath}:/workspace:rw`,
5503
4934
  "-v",
5504
- `${path3.join(homeDir, ".claude")}:/root/.claude:rw`,
4935
+ `${path2.join(homeDir, ".claude")}:/root/.claude:rw`,
5505
4936
  "-v",
5506
- `${path3.join(homeDir, ".config", "shiva-code")}:/root/.config/shiva-code:rw`
4937
+ `${path2.join(homeDir, ".config", "shiva-code")}:/root/.config/shiva-code:rw`
5507
4938
  ];
5508
4939
  for (const [hostPath, containerPath] of Object.entries(settings.volumeMounts || {})) {
5509
4940
  if (isValidProjectPath(hostPath)) {
@@ -5572,9 +5003,9 @@ function getTerminalName(terminal) {
5572
5003
  // src/services/sandbox/sandbox.ts
5573
5004
  import { execSync } from "child_process";
5574
5005
  import { existsSync as existsSync6, mkdirSync, rmSync, readdirSync as readdirSync2, copyFileSync, readFileSync as readFileSync2 } from "fs";
5575
- import { join as join4, dirname } from "path";
5006
+ import { join as join3, dirname } from "path";
5576
5007
  import { randomUUID } from "crypto";
5577
- import Conf3 from "conf";
5008
+ import Conf2 from "conf";
5578
5009
  var DEFAULT_SANDBOX_CONFIG = {
5579
5010
  enabled: false,
5580
5011
  defaultMode: "worktree",
@@ -5597,7 +5028,7 @@ var DEFAULT_SANDBOX_CONFIG = {
5597
5028
  ],
5598
5029
  maxSandboxes: 5
5599
5030
  };
5600
- var store = new Conf3({
5031
+ var store = new Conf2({
5601
5032
  projectName: "shiva-code",
5602
5033
  defaults: {
5603
5034
  sandboxConfig: DEFAULT_SANDBOX_CONFIG,
@@ -5611,10 +5042,10 @@ var SandboxService = class {
5611
5042
  /**
5612
5043
  * Check if a path is a git repository
5613
5044
  */
5614
- isGitRepo(path16) {
5045
+ isGitRepo(path15) {
5615
5046
  try {
5616
5047
  execSync("git rev-parse --git-dir", {
5617
- cwd: path16,
5048
+ cwd: path15,
5618
5049
  stdio: "pipe"
5619
5050
  });
5620
5051
  return true;
@@ -5654,7 +5085,7 @@ var SandboxService = class {
5654
5085
  * Get the .shiva/sandbox directory path
5655
5086
  */
5656
5087
  getSandboxDir(projectPath) {
5657
- return join4(projectPath, ".shiva", "sandbox");
5088
+ return join3(projectPath, ".shiva", "sandbox");
5658
5089
  }
5659
5090
  /**
5660
5091
  * Generate a unique session ID
@@ -5669,13 +5100,13 @@ var SandboxService = class {
5669
5100
  * Create a new sandbox session
5670
5101
  */
5671
5102
  async createSandbox(projectPath, mode) {
5672
- const config2 = this.getConfig();
5673
- const actualMode = mode || config2.defaultMode;
5103
+ const config = this.getConfig();
5104
+ const actualMode = mode || config.defaultMode;
5674
5105
  const sessionId = this.generateSessionId();
5675
5106
  const existingSandboxes = this.listSandboxes(projectPath);
5676
- if (existingSandboxes.length >= config2.maxSandboxes) {
5107
+ if (existingSandboxes.length >= config.maxSandboxes) {
5677
5108
  throw new Error(
5678
- `Maximum sandbox limit (${config2.maxSandboxes}) reached. Clean up old sandboxes first.`
5109
+ `Maximum sandbox limit (${config.maxSandboxes}) reached. Clean up old sandboxes first.`
5679
5110
  );
5680
5111
  }
5681
5112
  let sandboxPath;
@@ -5687,7 +5118,7 @@ var SandboxService = class {
5687
5118
  sandboxPath = await this.createWorktreeSandbox(projectPath, sessionId);
5688
5119
  break;
5689
5120
  case "copy":
5690
- sandboxPath = await this.createCopySandbox(projectPath, sessionId, config2.excludePaths);
5121
+ sandboxPath = await this.createCopySandbox(projectPath, sessionId, config.excludePaths);
5691
5122
  break;
5692
5123
  case "docker-overlay":
5693
5124
  if (!this.isDockerAvailable()) {
@@ -5716,7 +5147,7 @@ var SandboxService = class {
5716
5147
  */
5717
5148
  async createWorktreeSandbox(projectPath, sessionId) {
5718
5149
  const sandboxDir = this.getSandboxDir(projectPath);
5719
- const sandboxPath = join4(sandboxDir, `session-${sessionId}`);
5150
+ const sandboxPath = join3(sandboxDir, `session-${sessionId}`);
5720
5151
  mkdirSync(dirname(sandboxPath), { recursive: true });
5721
5152
  const currentRef = execSync("git rev-parse HEAD", {
5722
5153
  cwd: projectPath,
@@ -5740,11 +5171,11 @@ var SandboxService = class {
5740
5171
  });
5741
5172
  const untrackedFiles = untrackedOutput.split("\n").filter((f) => f.trim().length > 0);
5742
5173
  for (const file of untrackedFiles) {
5743
- const srcPath = join4(projectPath, file);
5744
- const destPath = join4(sandboxPath, file);
5174
+ const srcPath = join3(projectPath, file);
5175
+ const destPath = join3(sandboxPath, file);
5745
5176
  if (!existsSync6(srcPath)) continue;
5746
- const config2 = this.getConfig();
5747
- if (config2.excludePaths.some((excluded) => file.startsWith(excluded))) {
5177
+ const config = this.getConfig();
5178
+ if (config.excludePaths.some((excluded) => file.startsWith(excluded))) {
5748
5179
  continue;
5749
5180
  }
5750
5181
  const destDir = dirname(destPath);
@@ -5761,7 +5192,7 @@ var SandboxService = class {
5761
5192
  */
5762
5193
  async createCopySandbox(projectPath, sessionId, excludePaths) {
5763
5194
  const sandboxDir = this.getSandboxDir(projectPath);
5764
- const sandboxPath = join4(sandboxDir, `session-${sessionId}`);
5195
+ const sandboxPath = join3(sandboxDir, `session-${sessionId}`);
5765
5196
  mkdirSync(sandboxPath, { recursive: true });
5766
5197
  this.copyDirectory(projectPath, sandboxPath, excludePaths);
5767
5198
  return sandboxPath;
@@ -5772,8 +5203,8 @@ var SandboxService = class {
5772
5203
  copyDirectory(src, dest, excludePaths) {
5773
5204
  const entries = readdirSync2(src, { withFileTypes: true });
5774
5205
  for (const entry of entries) {
5775
- const srcPath = join4(src, entry.name);
5776
- const destPath = join4(dest, entry.name);
5206
+ const srcPath = join3(src, entry.name);
5207
+ const destPath = join3(dest, entry.name);
5777
5208
  if (excludePaths.includes(entry.name)) {
5778
5209
  continue;
5779
5210
  }
@@ -5793,14 +5224,14 @@ var SandboxService = class {
5793
5224
  */
5794
5225
  async createDockerOverlaySandbox(projectPath, sessionId) {
5795
5226
  const sandboxDir = this.getSandboxDir(projectPath);
5796
- const sandboxPath = join4(sandboxDir, `session-${sessionId}`);
5797
- const upperDir = join4(sandboxDir, `upper-${sessionId}`);
5798
- const workDir = join4(sandboxDir, `work-${sessionId}`);
5227
+ const sandboxPath = join3(sandboxDir, `session-${sessionId}`);
5228
+ const upperDir = join3(sandboxDir, `upper-${sessionId}`);
5229
+ const workDir = join3(sandboxDir, `work-${sessionId}`);
5799
5230
  mkdirSync(sandboxPath, { recursive: true });
5800
5231
  mkdirSync(upperDir, { recursive: true });
5801
5232
  mkdirSync(workDir, { recursive: true });
5802
- const config2 = this.getConfig();
5803
- this.copyDirectory(projectPath, sandboxPath, config2.excludePaths);
5233
+ const config = this.getConfig();
5234
+ this.copyDirectory(projectPath, sandboxPath, config.excludePaths);
5804
5235
  return sandboxPath;
5805
5236
  }
5806
5237
  /**
@@ -5923,7 +5354,7 @@ var SandboxService = class {
5923
5354
  }
5924
5355
  const untrackedFiles = untrackedOutput.split("\n").filter((f) => f.trim().length > 0);
5925
5356
  for (const file of untrackedFiles) {
5926
- const filePath = join4(session.sandboxPath, file);
5357
+ const filePath = join3(session.sandboxPath, file);
5927
5358
  if (existsSync6(filePath)) {
5928
5359
  const content = readFileSync2(filePath, "utf-8");
5929
5360
  const lineCount = content.split("\n").length;
@@ -5956,19 +5387,19 @@ var SandboxService = class {
5956
5387
  * Compare two directories and find changes
5957
5388
  */
5958
5389
  async compareDirectories(originalPath, sandboxPath, relativePath, changes) {
5959
- const config2 = this.getConfig();
5390
+ const config = this.getConfig();
5960
5391
  const sandboxEntries = /* @__PURE__ */ new Set();
5961
- const sandboxFullPath = join4(sandboxPath, relativePath);
5392
+ const sandboxFullPath = join3(sandboxPath, relativePath);
5962
5393
  if (existsSync6(sandboxFullPath)) {
5963
5394
  const entries = readdirSync2(sandboxFullPath, { withFileTypes: true });
5964
5395
  for (const entry of entries) {
5965
- if (config2.excludePaths.includes(entry.name) || entry.name === ".shiva") {
5396
+ if (config.excludePaths.includes(entry.name) || entry.name === ".shiva") {
5966
5397
  continue;
5967
5398
  }
5968
5399
  sandboxEntries.add(entry.name);
5969
- const entryRelPath = relativePath ? join4(relativePath, entry.name) : entry.name;
5970
- const originalEntryPath = join4(originalPath, entryRelPath);
5971
- const sandboxEntryPath = join4(sandboxPath, entryRelPath);
5400
+ const entryRelPath = relativePath ? join3(relativePath, entry.name) : entry.name;
5401
+ const originalEntryPath = join3(originalPath, entryRelPath);
5402
+ const sandboxEntryPath = join3(sandboxPath, entryRelPath);
5972
5403
  if (entry.isDirectory()) {
5973
5404
  if (!existsSync6(originalEntryPath)) {
5974
5405
  await this.countNewDirectoryChanges(sandboxEntryPath, entryRelPath, changes);
@@ -6002,16 +5433,16 @@ var SandboxService = class {
6002
5433
  }
6003
5434
  }
6004
5435
  }
6005
- const originalFullPath = join4(originalPath, relativePath);
5436
+ const originalFullPath = join3(originalPath, relativePath);
6006
5437
  if (existsSync6(originalFullPath)) {
6007
5438
  const entries = readdirSync2(originalFullPath, { withFileTypes: true });
6008
5439
  for (const entry of entries) {
6009
- if (config2.excludePaths.includes(entry.name) || entry.name === ".shiva") {
5440
+ if (config.excludePaths.includes(entry.name) || entry.name === ".shiva") {
6010
5441
  continue;
6011
5442
  }
6012
5443
  if (!sandboxEntries.has(entry.name)) {
6013
- const entryRelPath = relativePath ? join4(relativePath, entry.name) : entry.name;
6014
- const originalEntryPath = join4(originalPath, entryRelPath);
5444
+ const entryRelPath = relativePath ? join3(relativePath, entry.name) : entry.name;
5445
+ const originalEntryPath = join3(originalPath, entryRelPath);
6015
5446
  if (entry.isDirectory()) {
6016
5447
  await this.countDeletedDirectoryChanges(originalEntryPath, entryRelPath, changes);
6017
5448
  } else {
@@ -6051,11 +5482,11 @@ var SandboxService = class {
6051
5482
  */
6052
5483
  async countNewDirectoryChanges(dirPath, relativePath, changes) {
6053
5484
  const entries = readdirSync2(dirPath, { withFileTypes: true });
6054
- const config2 = this.getConfig();
5485
+ const config = this.getConfig();
6055
5486
  for (const entry of entries) {
6056
- if (config2.excludePaths.includes(entry.name)) continue;
6057
- const entryRelPath = join4(relativePath, entry.name);
6058
- const entryPath = join4(dirPath, entry.name);
5487
+ if (config.excludePaths.includes(entry.name)) continue;
5488
+ const entryRelPath = join3(relativePath, entry.name);
5489
+ const entryPath = join3(dirPath, entry.name);
6059
5490
  if (entry.isDirectory()) {
6060
5491
  await this.countNewDirectoryChanges(entryPath, entryRelPath, changes);
6061
5492
  } else {
@@ -6075,11 +5506,11 @@ var SandboxService = class {
6075
5506
  */
6076
5507
  async countDeletedDirectoryChanges(dirPath, relativePath, changes) {
6077
5508
  const entries = readdirSync2(dirPath, { withFileTypes: true });
6078
- const config2 = this.getConfig();
5509
+ const config = this.getConfig();
6079
5510
  for (const entry of entries) {
6080
- if (config2.excludePaths.includes(entry.name)) continue;
6081
- const entryRelPath = join4(relativePath, entry.name);
6082
- const entryPath = join4(dirPath, entry.name);
5511
+ if (config.excludePaths.includes(entry.name)) continue;
5512
+ const entryRelPath = join3(relativePath, entry.name);
5513
+ const entryPath = join3(dirPath, entry.name);
6083
5514
  if (entry.isDirectory()) {
6084
5515
  await this.countDeletedDirectoryChanges(entryPath, entryRelPath, changes);
6085
5516
  } else {
@@ -6110,7 +5541,7 @@ var SandboxService = class {
6110
5541
  });
6111
5542
  return diff || "(no changes)";
6112
5543
  } catch {
6113
- const sandboxFilePath2 = join4(session.sandboxPath, filePath);
5544
+ const sandboxFilePath2 = join3(session.sandboxPath, filePath);
6114
5545
  if (existsSync6(sandboxFilePath2)) {
6115
5546
  const content = readFileSync2(sandboxFilePath2, "utf-8");
6116
5547
  return `+++ ${filePath} (new file)
@@ -6119,8 +5550,8 @@ ${content.split("\n").map((l) => `+ ${l}`).join("\n")}`;
6119
5550
  return "(file not found)";
6120
5551
  }
6121
5552
  }
6122
- const originalPath = join4(session.projectPath, filePath);
6123
- const sandboxFilePath = join4(session.sandboxPath, filePath);
5553
+ const originalPath = join3(session.projectPath, filePath);
5554
+ const sandboxFilePath = join3(session.sandboxPath, filePath);
6124
5555
  const originalExists = existsSync6(originalPath);
6125
5556
  const sandboxExists = existsSync6(sandboxFilePath);
6126
5557
  if (!originalExists && sandboxExists) {
@@ -6178,8 +5609,8 @@ ${content.split("\n").map((l) => `- ${l}`).join("\n")}`;
6178
5609
  for (const filePath of pathsToApply) {
6179
5610
  const change = diff.changes.find((c) => c.path === filePath);
6180
5611
  if (!change) continue;
6181
- const srcPath = join4(session.sandboxPath, filePath);
6182
- const destPath = join4(session.projectPath, filePath);
5612
+ const srcPath = join3(session.sandboxPath, filePath);
5613
+ const destPath = join3(session.projectPath, filePath);
6183
5614
  if (change.type === "deleted") {
6184
5615
  if (existsSync6(destPath)) {
6185
5616
  rmSync(destPath, { force: true });
@@ -6195,8 +5626,8 @@ ${content.split("\n").map((l) => `- ${l}`).join("\n")}`;
6195
5626
  }
6196
5627
  }
6197
5628
  this.updateSandboxStatus(sessionId, "applied");
6198
- const config2 = this.getConfig();
6199
- if (config2.autoCleanup) {
5629
+ const config = this.getConfig();
5630
+ if (config.autoCleanup) {
6200
5631
  await this.deleteSandbox(sessionId);
6201
5632
  }
6202
5633
  }
@@ -6216,8 +5647,8 @@ ${content.split("\n").map((l) => `- ${l}`).join("\n")}`;
6216
5647
  throw new Error(`Sandbox ${sessionId} not found`);
6217
5648
  }
6218
5649
  for (const filePath of filePaths) {
6219
- const sandboxFilePath = join4(session.sandboxPath, filePath);
6220
- const originalPath = join4(session.projectPath, filePath);
5650
+ const sandboxFilePath = join3(session.sandboxPath, filePath);
5651
+ const originalPath = join3(session.projectPath, filePath);
6221
5652
  if (existsSync6(originalPath)) {
6222
5653
  copyFileSync(originalPath, sandboxFilePath);
6223
5654
  } else {
@@ -6234,8 +5665,8 @@ ${content.split("\n").map((l) => `- ${l}`).join("\n")}`;
6234
5665
  * Clean up old sandboxes
6235
5666
  */
6236
5667
  async cleanupOldSandboxes(maxAgeDays) {
6237
- const config2 = this.getConfig();
6238
- const maxAge = maxAgeDays || config2.keepDays;
5668
+ const config = this.getConfig();
5669
+ const maxAge = maxAgeDays || config.keepDays;
6239
5670
  const cutoffDate = /* @__PURE__ */ new Date();
6240
5671
  cutoffDate.setDate(cutoffDate.getDate() - maxAge);
6241
5672
  const sessions = store.get("sessions");
@@ -6279,9 +5710,9 @@ ${content.split("\n").map((l) => `- ${l}`).join("\n")}`;
6279
5710
  /**
6280
5711
  * Update configuration
6281
5712
  */
6282
- updateConfig(config2) {
5713
+ updateConfig(config) {
6283
5714
  const current = this.getConfig();
6284
- store.set("sandboxConfig", { ...current, ...config2 });
5715
+ store.set("sandboxConfig", { ...current, ...config });
6285
5716
  }
6286
5717
  /**
6287
5718
  * Reset configuration to defaults
@@ -6314,7 +5745,7 @@ var startCommand = new Command10("start").description("Projekte starten (mit Git
6314
5745
  const allProjects = await getAllClaudeProjects();
6315
5746
  const launches = [];
6316
5747
  for (const projektArg of projekte) {
6317
- const absolutePath = path4.resolve(projektArg);
5748
+ const absolutePath = path3.resolve(projektArg);
6318
5749
  if (fs.existsSync(absolutePath) && fs.statSync(absolutePath).isDirectory()) {
6319
5750
  const project = findProjectFromArray(allProjects, absolutePath);
6320
5751
  const latestSession = project?.latestSession;
@@ -7064,10 +6495,10 @@ import ora9 from "ora";
7064
6495
 
7065
6496
  // src/services/data/tags.ts
7066
6497
  import * as fs4 from "fs";
7067
- import * as path5 from "path";
7068
- import * as os4 from "os";
6498
+ import * as path4 from "path";
6499
+ import * as os3 from "os";
7069
6500
  function getTagsPath() {
7070
- return path5.join(os4.homedir(), ".shiva", "tags.json");
6501
+ return path4.join(os3.homedir(), ".shiva", "tags.json");
7071
6502
  }
7072
6503
  function loadTagsData() {
7073
6504
  const filepath = getTagsPath();
@@ -7083,7 +6514,7 @@ function loadTagsData() {
7083
6514
  }
7084
6515
  function saveTagsData(data) {
7085
6516
  const filepath = getTagsPath();
7086
- const dir = path5.dirname(filepath);
6517
+ const dir = path4.dirname(filepath);
7087
6518
  if (!fs4.existsSync(dir)) {
7088
6519
  fs4.mkdirSync(dir, { recursive: true });
7089
6520
  }
@@ -7290,59 +6721,238 @@ var sessionsCommand = new Command13("sessions").description("Alle Claude Code Se
7290
6721
  if (!projectExists) {
7291
6722
  console.log(colors.dim(` Pfad existiert nicht mehr: ${project.absolutePath}`));
7292
6723
  }
7293
- if (project.sessions.length === 0) {
7294
- log.dim(" Keine Sessions");
7295
- log.newline();
7296
- continue;
6724
+ if (project.sessions.length === 0) {
6725
+ log.dim(" Keine Sessions");
6726
+ log.newline();
6727
+ continue;
6728
+ }
6729
+ const displaySessions = project.sessions.slice(0, 5);
6730
+ for (let i = 0; i < displaySessions.length; i++) {
6731
+ const session = displaySessions[i];
6732
+ const num = String(i + 1).padStart(2, " ");
6733
+ let statusIcon = "";
6734
+ if (isSessionActive(session)) {
6735
+ statusIcon = colors.green(" [aktiv]");
6736
+ } else if (isSessionCorruptedQuick(session)) {
6737
+ statusIcon = colors.red(" [corrupted]");
6738
+ }
6739
+ const branch = session.gitBranch || "main";
6740
+ const msgs = `${session.messageCount} msgs`.padEnd(10);
6741
+ const time = formatRelativeTime(session.modified);
6742
+ let prompt = session.firstPrompt || "";
6743
+ if (prompt.length > 40) {
6744
+ prompt = prompt.substring(0, 37) + "...";
6745
+ }
6746
+ prompt = `"${prompt}"`;
6747
+ const tags = getSessionTags(session.sessionId);
6748
+ const tagsDisplay = tags.length > 0 ? " " + tags.map((t) => colors.magenta(`[${t}]`)).join(" ") : "";
6749
+ const line = [
6750
+ colors.dim(`${num}.`),
6751
+ branch.padEnd(15),
6752
+ colors.dim(`(${msgs})`),
6753
+ formatDate(session.modified).padEnd(14),
6754
+ colors.cyan(prompt),
6755
+ statusIcon,
6756
+ tagsDisplay
6757
+ ].join(" ");
6758
+ console.log(` ${line}`);
6759
+ }
6760
+ if (project.sessions.length > 5) {
6761
+ log.dim(` ... und ${project.sessions.length - 5} weitere Sessions`);
6762
+ }
6763
+ log.newline();
6764
+ }
6765
+ const stats = await getSessionStats();
6766
+ log.dim(`Total: ${stats.activeProjects} Projekte, ${stats.totalSessions} Sessions`);
6767
+ log.newline();
6768
+ }));
6769
+ async function checkProjectExists(path15) {
6770
+ try {
6771
+ const fs15 = await import("fs");
6772
+ return fs15.existsSync(path15);
6773
+ } catch {
6774
+ return false;
6775
+ }
6776
+ }
6777
+ sessionsCommand.command("push").description("Sessions in Cloud sichern").option("-p, --project <pfad>", "Nur Sessions eines Projekts").action(async (options) => {
6778
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
6779
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6780
+ const { getProjectConfig: getProjectConfig2 } = await import("./config-D6M6LI6U.js");
6781
+ if (!isAuthenticated2()) {
6782
+ log.error("Nicht angemeldet");
6783
+ log.info("Anmelden mit: shiva login");
6784
+ return;
6785
+ }
6786
+ let projects = await getAllClaudeProjects();
6787
+ if (options.project) {
6788
+ const found = await findProject(options.project);
6789
+ if (found) {
6790
+ projects = [found];
6791
+ } else {
6792
+ log.error(`Projekt nicht gefunden: ${options.project}`);
6793
+ return;
6794
+ }
6795
+ }
6796
+ projects = projects.filter((p) => p.sessions.length > 0);
6797
+ if (projects.length === 0) {
6798
+ log.warn("Keine Sessions zum Synchronisieren gefunden");
6799
+ return;
6800
+ }
6801
+ const spinner = ora9("Synchronisiere Sessions...").start();
6802
+ let syncedCount = 0;
6803
+ let errorCount = 0;
6804
+ for (const project of projects) {
6805
+ const config = getProjectConfig2(project.absolutePath);
6806
+ if (!config.projectId) {
6807
+ continue;
6808
+ }
6809
+ for (const session of project.sessions) {
6810
+ try {
6811
+ await api2.syncSession({
6812
+ sessionId: session.sessionId,
6813
+ projectId: config.projectId,
6814
+ summary: session.firstPrompt,
6815
+ messageCount: session.messageCount,
6816
+ firstPrompt: session.firstPrompt,
6817
+ gitBranch: session.gitBranch
6818
+ });
6819
+ syncedCount++;
6820
+ } catch {
6821
+ errorCount++;
6822
+ }
6823
+ }
6824
+ }
6825
+ spinner.stop();
6826
+ if (syncedCount > 0) {
6827
+ log.success(`${syncedCount} Sessions in Cloud gesichert`);
6828
+ }
6829
+ if (errorCount > 0) {
6830
+ log.warn(`${errorCount} Sessions konnten nicht gesichert werden`);
6831
+ }
6832
+ if (syncedCount === 0 && errorCount === 0) {
6833
+ log.info("Keine Projekte mit Cloud verbunden");
6834
+ log.dim("Verbinden mit: shiva init && shiva sync");
6835
+ }
6836
+ });
6837
+ sessionsCommand.command("pull").description("Sessions aus Cloud laden").option("--json", "JSON Output").action(async (options) => {
6838
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
6839
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6840
+ if (!isAuthenticated2()) {
6841
+ log.error("Nicht angemeldet");
6842
+ log.info("Anmelden mit: shiva login");
6843
+ return;
6844
+ }
6845
+ const spinner = ora9("Lade Sessions aus Cloud...").start();
6846
+ try {
6847
+ const cloudSessions = await api2.getSessions();
6848
+ spinner.stop();
6849
+ if (options.json) {
6850
+ console.log(JSON.stringify(cloudSessions, null, 2));
6851
+ return;
6852
+ }
6853
+ if (cloudSessions.length === 0) {
6854
+ log.info("Keine Sessions in Cloud gefunden");
6855
+ log.dim("Hochladen mit: shiva sessions push");
6856
+ return;
6857
+ }
6858
+ log.success(`${cloudSessions.length} Sessions in Cloud gefunden`);
6859
+ log.newline();
6860
+ const byProject = /* @__PURE__ */ new Map();
6861
+ for (const session of cloudSessions) {
6862
+ const existing = byProject.get(session.projectId) || [];
6863
+ existing.push(session);
6864
+ byProject.set(session.projectId, existing);
7297
6865
  }
7298
- const displaySessions = project.sessions.slice(0, 5);
7299
- for (let i = 0; i < displaySessions.length; i++) {
7300
- const session = displaySessions[i];
7301
- const num = String(i + 1).padStart(2, " ");
7302
- let statusIcon = "";
7303
- if (isSessionActive(session)) {
7304
- statusIcon = colors.green(" [aktiv]");
7305
- } else if (isSessionCorruptedQuick(session)) {
7306
- statusIcon = colors.red(" [corrupted]");
6866
+ for (const [projectId, sessions] of byProject.entries()) {
6867
+ console.log(colors.bold(`Projekt ID: ${projectId}`));
6868
+ for (const session of sessions.slice(0, 5)) {
6869
+ const data = session.data;
6870
+ const branch = data.gitBranch || "main";
6871
+ const msgs = data.messageCount || 0;
6872
+ log.dim(` ${session.sessionId.substring(0, 8)}... ${branch.padEnd(15)} ${msgs} msgs`);
7307
6873
  }
7308
- const branch = session.gitBranch || "main";
7309
- const msgs = `${session.messageCount} msgs`.padEnd(10);
7310
- const time = formatRelativeTime(session.modified);
7311
- let prompt = session.firstPrompt || "";
7312
- if (prompt.length > 40) {
7313
- prompt = prompt.substring(0, 37) + "...";
6874
+ if (sessions.length > 5) {
6875
+ log.dim(` ... und ${sessions.length - 5} weitere`);
7314
6876
  }
7315
- prompt = `"${prompt}"`;
7316
- const tags = getSessionTags(session.sessionId);
7317
- const tagsDisplay = tags.length > 0 ? " " + tags.map((t) => colors.magenta(`[${t}]`)).join(" ") : "";
7318
- const line = [
7319
- colors.dim(`${num}.`),
7320
- branch.padEnd(15),
7321
- colors.dim(`(${msgs})`),
7322
- formatDate(session.modified).padEnd(14),
7323
- colors.cyan(prompt),
7324
- statusIcon,
7325
- tagsDisplay
7326
- ].join(" ");
7327
- console.log(` ${line}`);
6877
+ log.newline();
7328
6878
  }
7329
- if (project.sessions.length > 5) {
7330
- log.dim(` ... und ${project.sessions.length - 5} weitere Sessions`);
6879
+ } catch (error) {
6880
+ spinner.stop();
6881
+ log.error(error instanceof Error ? error.message : "Fehler beim Laden");
6882
+ }
6883
+ });
6884
+ sessionsCommand.command("sync").description("Sessions mit Cloud synchronisieren").option("-p, --project <pfad>", "Nur Sessions eines Projekts").action(async (options) => {
6885
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
6886
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6887
+ const { getProjectConfig: getProjectConfig2 } = await import("./config-D6M6LI6U.js");
6888
+ if (!isAuthenticated2()) {
6889
+ log.error("Nicht angemeldet");
6890
+ log.info("Anmelden mit: shiva login");
6891
+ return;
6892
+ }
6893
+ let projects = await getAllClaudeProjects();
6894
+ if (options.project) {
6895
+ const found = await findProject(options.project);
6896
+ if (found) {
6897
+ projects = [found];
6898
+ } else {
6899
+ log.error(`Projekt nicht gefunden: ${options.project}`);
6900
+ return;
7331
6901
  }
7332
- log.newline();
7333
6902
  }
7334
- const stats = await getSessionStats();
7335
- log.dim(`Total: ${stats.activeProjects} Projekte, ${stats.totalSessions} Sessions`);
7336
- log.newline();
7337
- }));
7338
- async function checkProjectExists(path16) {
6903
+ const spinner = ora9("Synchronisiere Sessions...").start();
6904
+ let pushedCount = 0;
6905
+ for (const project of projects.filter((p) => p.sessions.length > 0)) {
6906
+ const config = getProjectConfig2(project.absolutePath);
6907
+ if (!config.projectId) continue;
6908
+ for (const session of project.sessions) {
6909
+ try {
6910
+ await api2.syncSession({
6911
+ sessionId: session.sessionId,
6912
+ projectId: config.projectId,
6913
+ summary: session.firstPrompt,
6914
+ messageCount: session.messageCount,
6915
+ firstPrompt: session.firstPrompt,
6916
+ gitBranch: session.gitBranch
6917
+ });
6918
+ pushedCount++;
6919
+ } catch {
6920
+ }
6921
+ }
6922
+ }
6923
+ let cloudCount = 0;
7339
6924
  try {
7340
- const fs15 = await import("fs");
7341
- return fs15.existsSync(path16);
6925
+ const cloudSessions = await api2.getSessions();
6926
+ cloudCount = cloudSessions.length;
7342
6927
  } catch {
7343
- return false;
7344
6928
  }
7345
- }
6929
+ spinner.stop();
6930
+ log.success("Sessions synchronisiert");
6931
+ log.newline();
6932
+ log.tree.item(`${pushedCount} Sessions \u2192 Cloud`);
6933
+ log.tree.item(`${cloudCount} Sessions in Cloud`);
6934
+ log.newline();
6935
+ log.dim("Sessions werden automatisch mit lokalen Claude Sessions verkn\xFCpft");
6936
+ });
6937
+ sessionsCommand.command("delete <sessionId>").description("Session aus Cloud l\xF6schen").action(async (sessionId) => {
6938
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
6939
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6940
+ if (!isAuthenticated2()) {
6941
+ log.error("Nicht angemeldet");
6942
+ log.info("Anmelden mit: shiva login");
6943
+ return;
6944
+ }
6945
+ try {
6946
+ const result = await api2.deleteSession(sessionId);
6947
+ if (result.success) {
6948
+ log.success("Session aus Cloud gel\xF6scht");
6949
+ } else {
6950
+ log.error(result.message || "Fehler beim L\xF6schen");
6951
+ }
6952
+ } catch (error) {
6953
+ log.error(error instanceof Error ? error.message : "Fehler beim L\xF6schen");
6954
+ }
6955
+ });
7346
6956
 
7347
6957
  // src/commands/session/session.ts
7348
6958
  import { Command as Command14 } from "commander";
@@ -7599,10 +7209,10 @@ sessionCommand.command("apply").description("Sandbox-\xC4nderungen \xFCbernehmen
7599
7209
  log.header("Folgende \xC4nderungen werden \xFCbernommen:");
7600
7210
  log.newline();
7601
7211
  const pathsToApply = selectedPaths || diff.changes.map((c) => c.path);
7602
- for (const path16 of pathsToApply) {
7603
- const change = diff.changes.find((c) => c.path === path16);
7212
+ for (const path15 of pathsToApply) {
7213
+ const change = diff.changes.find((c) => c.path === path15);
7604
7214
  if (change) {
7605
- console.log(` ${formatChangeType(change.type)} ${path16}`);
7215
+ console.log(` ${formatChangeType(change.type)} ${path15}`);
7606
7216
  }
7607
7217
  }
7608
7218
  log.newline();
@@ -7759,18 +7369,18 @@ sessionCommand.command("config").description("Sandbox-Konfiguration verwalten").
7759
7369
  log.success("Konfiguration zur\xFCckgesetzt");
7760
7370
  return;
7761
7371
  }
7762
- const config2 = sandboxService.getConfig();
7372
+ const config = sandboxService.getConfig();
7763
7373
  if (options.show || Object.keys(options).length === 0) {
7764
7374
  log.newline();
7765
7375
  log.header("Sandbox Configuration");
7766
7376
  log.newline();
7767
- log.keyValue("Enabled", config2.enabled ? colors.green("Yes") : colors.red("No"));
7768
- log.keyValue("Default Mode", config2.defaultMode);
7769
- log.keyValue("Auto Cleanup", config2.autoCleanup ? "Yes" : "No");
7770
- log.keyValue("Keep Days", String(config2.keepDays));
7771
- log.keyValue("Max Sandboxes", String(config2.maxSandboxes));
7377
+ log.keyValue("Enabled", config.enabled ? colors.green("Yes") : colors.red("No"));
7378
+ log.keyValue("Default Mode", config.defaultMode);
7379
+ log.keyValue("Auto Cleanup", config.autoCleanup ? "Yes" : "No");
7380
+ log.keyValue("Keep Days", String(config.keepDays));
7381
+ log.keyValue("Max Sandboxes", String(config.maxSandboxes));
7772
7382
  log.newline();
7773
- log.keyValue("Exclude Paths", config2.excludePaths.join(", "));
7383
+ log.keyValue("Exclude Paths", config.excludePaths.join(", "));
7774
7384
  return;
7775
7385
  }
7776
7386
  const updates = {};
@@ -7797,7 +7407,7 @@ sessionCommand.command("config").description("Sandbox-Konfiguration verwalten").
7797
7407
  import { Command as Command15 } from "commander";
7798
7408
  import { spawn as spawn5, spawnSync as spawnSync5 } from "child_process";
7799
7409
  import * as fs5 from "fs";
7800
- import * as path6 from "path";
7410
+ import * as path5 from "path";
7801
7411
  import inquirer6 from "inquirer";
7802
7412
  var githubCommand = new Command15("github").description("GitHub Integration verwalten").action(() => {
7803
7413
  showStatus();
@@ -7861,9 +7471,9 @@ function showStatus() {
7861
7471
  console.log(colors.dim("SHIVA Integration:"));
7862
7472
  if (hasShivaDir(cwd)) {
7863
7473
  log.success(".shiva/ Ordner existiert");
7864
- const config2 = getProjectConfig(cwd);
7865
- log.keyValue(" Context Injection", config2.autoInjectContext ? "aktiviert" : "deaktiviert");
7866
- log.keyValue(" Branch Sessions", String(Object.keys(config2.branchSessions).length));
7474
+ const config = getProjectConfig(cwd);
7475
+ log.keyValue(" Context Injection", config.autoInjectContext ? "aktiviert" : "deaktiviert");
7476
+ log.keyValue(" Branch Sessions", String(Object.keys(config.branchSessions).length));
7867
7477
  } else {
7868
7478
  log.warn(".shiva/ nicht initialisiert");
7869
7479
  log.info("Initialisieren mit: shiva github init");
@@ -7902,9 +7512,9 @@ function initProject(projectPath, skipGitignore) {
7902
7512
  }
7903
7513
  if (hasShivaDir(projectPath)) {
7904
7514
  log.warn(".shiva/ existiert bereits");
7905
- const config2 = getProjectConfig(projectPath);
7906
- log.keyValue("Version", String(config2.version));
7907
- log.keyValue("Branch Sessions", String(Object.keys(config2.branchSessions).length));
7515
+ const config = getProjectConfig(projectPath);
7516
+ log.keyValue("Version", String(config.version));
7517
+ log.keyValue("Branch Sessions", String(Object.keys(config.branchSessions).length));
7908
7518
  log.newline();
7909
7519
  log.info('Nutze "shiva github status" f\xFCr Details');
7910
7520
  return;
@@ -8219,9 +7829,9 @@ githubCommand.command("git-hook").description("Git Hooks f\xFCr Branch-Session I
8219
7829
  log.error("Kein Git Repository");
8220
7830
  return;
8221
7831
  }
8222
- const gitDir = path6.join(cwd, ".git");
8223
- const hooksDir = path6.join(gitDir, "hooks");
8224
- const hookFile = path6.join(hooksDir, "post-checkout");
7832
+ const gitDir = path5.join(cwd, ".git");
7833
+ const hooksDir = path5.join(gitDir, "hooks");
7834
+ const hookFile = path5.join(hooksDir, "post-checkout");
8225
7835
  if (options.uninstall) {
8226
7836
  if (fs5.existsSync(hookFile)) {
8227
7837
  const content = fs5.readFileSync(hookFile, "utf-8");
@@ -8610,10 +8220,10 @@ var prsCommand = new Command17("prs").description("GitHub Pull Requests \xFCber
8610
8220
  import { Command as Command18 } from "commander";
8611
8221
  import { readFile } from "fs/promises";
8612
8222
  import { existsSync as existsSync12 } from "fs";
8613
- import { join as join7, resolve as resolve7 } from "path";
8223
+ import { join as join6, resolve as resolve7 } from "path";
8614
8224
 
8615
8225
  // src/services/security/package-scanner.ts
8616
- import Conf4 from "conf";
8226
+ import Conf3 from "conf";
8617
8227
 
8618
8228
  // src/types/package.ts
8619
8229
  var DEFAULT_PACKAGE_SCAN_CONFIG = {
@@ -8900,7 +8510,7 @@ var KNOWN_MALICIOUS_PACKAGES = [
8900
8510
  // src/services/security/package-scanner.ts
8901
8511
  var CACHE_TTL = 60 * 60 * 1e3;
8902
8512
  var packageInfoCache = /* @__PURE__ */ new Map();
8903
- var configStore = new Conf4({
8513
+ var configStore = new Conf3({
8904
8514
  projectName: "shiva-code",
8905
8515
  defaults: {
8906
8516
  packageSecurity: DEFAULT_PACKAGE_SCAN_CONFIG
@@ -9171,8 +8781,8 @@ var PackageScannerService = class {
9171
8781
  * Check download count
9172
8782
  */
9173
8783
  checkDownloadCount(weeklyDownloads, manager) {
9174
- const config2 = this.getConfig();
9175
- const minDownloads = config2.minDownloads;
8784
+ const config = this.getConfig();
8785
+ const minDownloads = config.minDownloads;
9176
8786
  if (weeklyDownloads < 10) {
9177
8787
  return {
9178
8788
  name: "Downloads",
@@ -9208,7 +8818,7 @@ var PackageScannerService = class {
9208
8818
  * Check package age
9209
8819
  */
9210
8820
  checkPublishAge(publishedAt) {
9211
- const config2 = this.getConfig();
8821
+ const config = this.getConfig();
9212
8822
  const publishDate = new Date(publishedAt);
9213
8823
  const now = /* @__PURE__ */ new Date();
9214
8824
  const ageInDays = Math.floor((now.getTime() - publishDate.getTime()) / (1e3 * 60 * 60 * 24));
@@ -9220,11 +8830,11 @@ var PackageScannerService = class {
9220
8830
  severity: "critical"
9221
8831
  };
9222
8832
  }
9223
- if (ageInDays < config2.maxAgeDays) {
8833
+ if (ageInDays < config.maxAgeDays) {
9224
8834
  return {
9225
8835
  name: "Age",
9226
8836
  status: "fail",
9227
- message: `${ageInDays} days old (< ${config2.maxAgeDays} days)`,
8837
+ message: `${ageInDays} days old (< ${config.maxAgeDays} days)`,
9228
8838
  severity: "high"
9229
8839
  };
9230
8840
  }
@@ -9257,8 +8867,8 @@ var PackageScannerService = class {
9257
8867
  * Check for typosquatting
9258
8868
  */
9259
8869
  checkTyposquatting(name, manager) {
9260
- const config2 = this.getConfig();
9261
- if (!config2.checkTyposquatting) {
8870
+ const config = this.getConfig();
8871
+ if (!config.checkTyposquatting) {
9262
8872
  return {
9263
8873
  name: "Typosquatting",
9264
8874
  status: "pass",
@@ -9286,8 +8896,8 @@ var PackageScannerService = class {
9286
8896
  * Check install scripts for suspicious patterns
9287
8897
  */
9288
8898
  checkScripts(scripts) {
9289
- const config2 = this.getConfig();
9290
- if (!config2.checkScripts || !scripts) {
8899
+ const config = this.getConfig();
8900
+ if (!config.checkScripts || !scripts) {
9291
8901
  return {
9292
8902
  name: "Scripts",
9293
8903
  status: "pass",
@@ -9388,8 +8998,8 @@ var PackageScannerService = class {
9388
8998
  * Check blocklist
9389
8999
  */
9390
9000
  checkBlocklist(name, manager) {
9391
- const config2 = this.getConfig();
9392
- const blocked = config2.blocklist.find((entry) => entry.package === name && entry.manager === manager);
9001
+ const config = this.getConfig();
9002
+ const blocked = config.blocklist.find((entry) => entry.package === name && entry.manager === manager);
9393
9003
  if (blocked) {
9394
9004
  return {
9395
9005
  name: "Blocklist",
@@ -9420,8 +9030,8 @@ var PackageScannerService = class {
9420
9030
  * Check allowlist
9421
9031
  */
9422
9032
  isAllowlisted(name) {
9423
- const config2 = this.getConfig();
9424
- return config2.allowlist.includes(name);
9033
+ const config = this.getConfig();
9034
+ return config.allowlist.includes(name);
9425
9035
  }
9426
9036
  // ─────────────────────────────────────────────────────────────────────────────
9427
9037
  // Typosquatting Detection
@@ -9733,7 +9343,7 @@ var PackageScannerService = class {
9733
9343
  * Generate hook output for Claude Code
9734
9344
  */
9735
9345
  generateHookOutput(results) {
9736
- const config2 = this.getConfig();
9346
+ const config = this.getConfig();
9737
9347
  const blockedPackages = results.filter((r) => r.recommendation === "block");
9738
9348
  const warnPackages = results.filter((r) => r.recommendation === "warn");
9739
9349
  if (blockedPackages.length > 0) {
@@ -9750,7 +9360,7 @@ var PackageScannerService = class {
9750
9360
 
9751
9361
  Did you mean: ${pkg.suggestion}?`;
9752
9362
  }
9753
- if (config2.autoBlock) {
9363
+ if (config.autoBlock) {
9754
9364
  return {
9755
9365
  decision: "block",
9756
9366
  reason
@@ -9790,64 +9400,64 @@ Continue with caution.`
9790
9400
  * Add a package to the blocklist
9791
9401
  */
9792
9402
  addToBlocklist(entry) {
9793
- const config2 = this.getConfig();
9794
- const existing = config2.blocklist.find(
9403
+ const config = this.getConfig();
9404
+ const existing = config.blocklist.find(
9795
9405
  (e) => e.package === entry.package && e.manager === entry.manager
9796
9406
  );
9797
9407
  if (existing) {
9798
9408
  existing.reason = entry.reason;
9799
9409
  existing.source = entry.source;
9800
9410
  } else {
9801
- config2.blocklist.push({
9411
+ config.blocklist.push({
9802
9412
  ...entry,
9803
9413
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9804
9414
  });
9805
9415
  }
9806
- this.updateConfig(config2);
9416
+ this.updateConfig(config);
9807
9417
  }
9808
9418
  /**
9809
9419
  * Remove a package from the blocklist
9810
9420
  */
9811
9421
  removeFromBlocklist(packageName, manager) {
9812
- const config2 = this.getConfig();
9813
- const index = config2.blocklist.findIndex(
9422
+ const config = this.getConfig();
9423
+ const index = config.blocklist.findIndex(
9814
9424
  (e) => e.package === packageName && e.manager === manager
9815
9425
  );
9816
9426
  if (index === -1) {
9817
9427
  return false;
9818
9428
  }
9819
- config2.blocklist.splice(index, 1);
9820
- this.updateConfig(config2);
9429
+ config.blocklist.splice(index, 1);
9430
+ this.updateConfig(config);
9821
9431
  return true;
9822
9432
  }
9823
9433
  /**
9824
9434
  * Check if a package is blocked
9825
9435
  */
9826
9436
  isBlocked(name, manager) {
9827
- const config2 = this.getConfig();
9828
- return config2.blocklist.some((e) => e.package === name && e.manager === manager) || KNOWN_MALICIOUS_PACKAGES.some((e) => e.package === name && e.manager === manager);
9437
+ const config = this.getConfig();
9438
+ return config.blocklist.some((e) => e.package === name && e.manager === manager) || KNOWN_MALICIOUS_PACKAGES.some((e) => e.package === name && e.manager === manager);
9829
9439
  }
9830
9440
  /**
9831
9441
  * Add a package to the allowlist
9832
9442
  */
9833
9443
  addToAllowlist(packageName) {
9834
- const config2 = this.getConfig();
9835
- if (!config2.allowlist.includes(packageName)) {
9836
- config2.allowlist.push(packageName);
9837
- this.updateConfig(config2);
9444
+ const config = this.getConfig();
9445
+ if (!config.allowlist.includes(packageName)) {
9446
+ config.allowlist.push(packageName);
9447
+ this.updateConfig(config);
9838
9448
  }
9839
9449
  }
9840
9450
  /**
9841
9451
  * Remove a package from the allowlist
9842
9452
  */
9843
9453
  removeFromAllowlist(packageName) {
9844
- const config2 = this.getConfig();
9845
- const index = config2.allowlist.indexOf(packageName);
9454
+ const config = this.getConfig();
9455
+ const index = config.allowlist.indexOf(packageName);
9846
9456
  if (index === -1) {
9847
9457
  return false;
9848
9458
  }
9849
- config2.allowlist.splice(index, 1);
9850
- this.updateConfig(config2);
9459
+ config.allowlist.splice(index, 1);
9460
+ this.updateConfig(config);
9851
9461
  return true;
9852
9462
  }
9853
9463
  // ─────────────────────────────────────────────────────────────────────────────
@@ -9862,9 +9472,9 @@ Continue with caution.`
9862
9472
  /**
9863
9473
  * Update configuration
9864
9474
  */
9865
- updateConfig(config2) {
9475
+ updateConfig(config) {
9866
9476
  const current = this.getConfig();
9867
- configStore.set("packageSecurity", { ...current, ...config2 });
9477
+ configStore.set("packageSecurity", { ...current, ...config });
9868
9478
  }
9869
9479
  /**
9870
9480
  * Reset configuration to defaults
@@ -9963,9 +9573,9 @@ async function parsePackageJson(filePath) {
9963
9573
  }
9964
9574
  const dir = resolve7(filePath, "..");
9965
9575
  let manager = "npm";
9966
- if (existsSync12(join7(dir, "pnpm-lock.yaml"))) {
9576
+ if (existsSync12(join6(dir, "pnpm-lock.yaml"))) {
9967
9577
  manager = "pnpm";
9968
- } else if (existsSync12(join7(dir, "yarn.lock"))) {
9578
+ } else if (existsSync12(join6(dir, "yarn.lock"))) {
9969
9579
  manager = "yarn";
9970
9580
  }
9971
9581
  return { packages, manager };
@@ -10006,22 +9616,22 @@ async function parseCargoToml(filePath) {
10006
9616
  }
10007
9617
  return packages;
10008
9618
  }
10009
- function displayConfig(config2) {
9619
+ function displayConfig(config) {
10010
9620
  log.header("Package Security Config");
10011
9621
  log.newline();
10012
- log.keyValue("Enabled", config2.enabled ? colors.green("Yes") : colors.red("No"));
10013
- log.keyValue("Auto-block", config2.autoBlock ? colors.red("Yes") : colors.green("No"));
10014
- log.keyValue("Min downloads", `${config2.minDownloads}/week`);
10015
- log.keyValue("Max age", `${config2.maxAgeDays} days`);
10016
- log.keyValue("Typosquatting check", config2.checkTyposquatting ? "Yes" : "No");
10017
- log.keyValue("Script check", config2.checkScripts ? "Yes" : "No");
9622
+ log.keyValue("Enabled", config.enabled ? colors.green("Yes") : colors.red("No"));
9623
+ log.keyValue("Auto-block", config.autoBlock ? colors.red("Yes") : colors.green("No"));
9624
+ log.keyValue("Min downloads", `${config.minDownloads}/week`);
9625
+ log.keyValue("Max age", `${config.maxAgeDays} days`);
9626
+ log.keyValue("Typosquatting check", config.checkTyposquatting ? "Yes" : "No");
9627
+ log.keyValue("Script check", config.checkScripts ? "Yes" : "No");
10018
9628
  log.newline();
10019
- log.keyValue("Blocklist entries", `${config2.blocklist.length}`);
10020
- log.keyValue("Allowlist entries", `${config2.allowlist.length}`);
9629
+ log.keyValue("Blocklist entries", `${config.blocklist.length}`);
9630
+ log.keyValue("Allowlist entries", `${config.allowlist.length}`);
10021
9631
  }
10022
9632
  var scanCommand = new Command18("scan").description("Scanne Packages auf Sicherheitsrisiken").argument("[packages...]", "Package names to scan").option("-m, --manager <manager>", "Package manager (npm, pip, cargo)", "npm").option("-f, --file <file>", "Scan dependencies from file (package.json, requirements.txt, Cargo.toml)").option("-c, --command <command>", "Scan packages from install command").option("--project", "Scan all dependencies in current project").option("--hook-mode", "Output in hook format (JSON)").option("-j, --json", "Output as JSON").option("-v, --verbose", "Show detailed output").action(async (packages, options) => {
10023
- const config2 = packageScanner.getConfig();
10024
- if (!config2.enabled && !options.hookMode) {
9633
+ const config = packageScanner.getConfig();
9634
+ if (!config.enabled && !options.hookMode) {
10025
9635
  log.warn("Package scanning is disabled. Enable it with: shiva scan config --enable");
10026
9636
  return;
10027
9637
  }
@@ -10066,15 +9676,15 @@ var scanCommand = new Command18("scan").description("Scanne Packages auf Sicherh
10066
9676
  }
10067
9677
  if (options.project) {
10068
9678
  const cwd = process.cwd();
10069
- if (existsSync12(join7(cwd, "package.json"))) {
10070
- const parsed = await parsePackageJson(join7(cwd, "package.json"));
9679
+ if (existsSync12(join6(cwd, "package.json"))) {
9680
+ const parsed = await parsePackageJson(join6(cwd, "package.json"));
10071
9681
  packagesToScan = parsed.packages;
10072
9682
  manager = parsed.manager;
10073
- } else if (existsSync12(join7(cwd, "requirements.txt"))) {
10074
- packagesToScan = await parseRequirementsTxt(join7(cwd, "requirements.txt"));
9683
+ } else if (existsSync12(join6(cwd, "requirements.txt"))) {
9684
+ packagesToScan = await parseRequirementsTxt(join6(cwd, "requirements.txt"));
10075
9685
  manager = "pip";
10076
- } else if (existsSync12(join7(cwd, "Cargo.toml"))) {
10077
- packagesToScan = await parseCargoToml(join7(cwd, "Cargo.toml"));
9686
+ } else if (existsSync12(join6(cwd, "Cargo.toml"))) {
9687
+ packagesToScan = await parseCargoToml(join6(cwd, "Cargo.toml"));
10078
9688
  manager = "cargo";
10079
9689
  } else {
10080
9690
  log.error("No dependency file found in current directory");
@@ -10138,14 +9748,14 @@ var blocklistCommand = new Command18("blocklist").description("Verwalte Package-
10138
9748
  }
10139
9749
  return;
10140
9750
  }
10141
- const config2 = packageScanner.getConfig();
10142
- if (config2.blocklist.length === 0) {
9751
+ const config = packageScanner.getConfig();
9752
+ if (config.blocklist.length === 0) {
10143
9753
  log.info("Blocklist is empty");
10144
9754
  return;
10145
9755
  }
10146
9756
  log.header("Blocked Packages");
10147
9757
  log.newline();
10148
- for (const entry of config2.blocklist) {
9758
+ for (const entry of config.blocklist) {
10149
9759
  log.plain(`${colors.red("\u2717")} ${entry.package} (${entry.manager})`);
10150
9760
  log.plain(colors.dim(` Reason: ${entry.reason}`));
10151
9761
  log.plain(colors.dim(` Added: ${entry.addedAt} (${entry.source})`));
@@ -10166,14 +9776,14 @@ var allowlistCommand = new Command18("allowlist").description("Verwalte Package-
10166
9776
  }
10167
9777
  return;
10168
9778
  }
10169
- const config2 = packageScanner.getConfig();
10170
- if (config2.allowlist.length === 0) {
9779
+ const config = packageScanner.getConfig();
9780
+ if (config.allowlist.length === 0) {
10171
9781
  log.info("Allowlist is empty");
10172
9782
  return;
10173
9783
  }
10174
9784
  log.header("Allowed Packages");
10175
9785
  log.newline();
10176
- for (const pkg of config2.allowlist) {
9786
+ for (const pkg of config.allowlist) {
10177
9787
  log.plain(`${colors.green("\u2713")} ${pkg}`);
10178
9788
  }
10179
9789
  });
@@ -10230,9 +9840,9 @@ var permissionsCommand = new Command19("permissions").description("Permission-By
10230
9840
  if (!hasShivaDir(projectPath)) {
10231
9841
  initShivaDir(projectPath);
10232
9842
  }
10233
- const config2 = getSecurityConfig(projectPath);
9843
+ const config = getSecurityConfig(projectPath);
10234
9844
  if (options.status || Object.keys(options).filter((k) => k !== "noSkip").length === 0) {
10235
- displayPermissionsStatus(config2.permissions);
9845
+ displayPermissionsStatus(config.permissions);
10236
9846
  return;
10237
9847
  }
10238
9848
  if (options.skip) {
@@ -10248,7 +9858,7 @@ var permissionsCommand = new Command19("permissions").description("Permission-By
10248
9858
  log.success("Permissions werden von global geerbt");
10249
9859
  }
10250
9860
  if (options.blockTool) {
10251
- const current = config2.permissions.blockedTools;
9861
+ const current = config.permissions.blockedTools;
10252
9862
  if (!current.includes(options.blockTool)) {
10253
9863
  updatePermissions(projectPath, { blockedTools: [...current, options.blockTool] });
10254
9864
  log.success(`Tool blockiert: ${options.blockTool}`);
@@ -10257,21 +9867,21 @@ var permissionsCommand = new Command19("permissions").description("Permission-By
10257
9867
  }
10258
9868
  }
10259
9869
  if (options.unblockTool) {
10260
- const current = config2.permissions.blockedTools;
9870
+ const current = config.permissions.blockedTools;
10261
9871
  updatePermissions(projectPath, {
10262
9872
  blockedTools: current.filter((t) => t !== options.unblockTool)
10263
9873
  });
10264
9874
  log.success(`Tool-Block aufgehoben: ${options.unblockTool}`);
10265
9875
  }
10266
9876
  if (options.allowPath) {
10267
- const current = config2.permissions.allowedPaths;
9877
+ const current = config.permissions.allowedPaths;
10268
9878
  if (!current.includes(options.allowPath)) {
10269
9879
  updatePermissions(projectPath, { allowedPaths: [...current, options.allowPath] });
10270
9880
  log.success(`Pfad erlaubt: ${options.allowPath}`);
10271
9881
  }
10272
9882
  }
10273
9883
  if (options.blockPath) {
10274
- const current = config2.permissions.blockedPaths;
9884
+ const current = config.permissions.blockedPaths;
10275
9885
  if (!current.includes(options.blockPath)) {
10276
9886
  updatePermissions(projectPath, { blockedPaths: [...current, options.blockPath] });
10277
9887
  log.success(`Pfad blockiert: ${options.blockPath}`);
@@ -10279,7 +9889,7 @@ var permissionsCommand = new Command19("permissions").description("Permission-By
10279
9889
  }
10280
9890
  displayPermissionsStatus(getSecurityConfig(projectPath).permissions);
10281
9891
  });
10282
- function displayPermissionsStatus(config2) {
9892
+ function displayPermissionsStatus(config) {
10283
9893
  log.newline();
10284
9894
  console.log(colors.orange.bold("Permission-Einstellungen"));
10285
9895
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
@@ -10289,11 +9899,11 @@ function displayPermissionsStatus(config2) {
10289
9899
  "no-skip": colors.green("Aktiv (Permission-Prompts)"),
10290
9900
  "inherit": colors.dim("(erbt von global)")
10291
9901
  };
10292
- log.keyValue("Modus", modeDisplay[config2.skipPermissions]);
10293
- log.keyValue("Erlaubte Tools", config2.allowedTools === "all" ? "Alle" : config2.allowedTools.join(", ") || "Keine");
10294
- log.keyValue("Blockierte Tools", config2.blockedTools.length > 0 ? config2.blockedTools.join(", ") : colors.dim("Keine"));
10295
- log.keyValue("Erlaubte Pfade", config2.allowedPaths.length > 0 ? config2.allowedPaths.join(", ") : colors.dim("Alle"));
10296
- log.keyValue("Blockierte Pfade", config2.blockedPaths.length > 0 ? config2.blockedPaths.join(", ") : colors.dim("Keine"));
9902
+ log.keyValue("Modus", modeDisplay[config.skipPermissions]);
9903
+ log.keyValue("Erlaubte Tools", config.allowedTools === "all" ? "Alle" : config.allowedTools.join(", ") || "Keine");
9904
+ log.keyValue("Blockierte Tools", config.blockedTools.length > 0 ? config.blockedTools.join(", ") : colors.dim("Keine"));
9905
+ log.keyValue("Erlaubte Pfade", config.allowedPaths.length > 0 ? config.allowedPaths.join(", ") : colors.dim("Alle"));
9906
+ log.keyValue("Blockierte Pfade", config.blockedPaths.length > 0 ? config.blockedPaths.join(", ") : colors.dim("Keine"));
10297
9907
  log.newline();
10298
9908
  }
10299
9909
  securityCommand.addCommand(permissionsCommand);
@@ -10302,9 +9912,9 @@ var approvalCommand = new Command19("approval").description("Plan-Approval-Strat
10302
9912
  if (!hasShivaDir(projectPath)) {
10303
9913
  initShivaDir(projectPath);
10304
9914
  }
10305
- const config2 = getSecurityConfig(projectPath);
9915
+ const config = getSecurityConfig(projectPath);
10306
9916
  if (options.status || !strategy && Object.keys(options).length === 0) {
10307
- displayApprovalStatus(config2.approval);
9917
+ displayApprovalStatus(config.approval);
10308
9918
  return;
10309
9919
  }
10310
9920
  if (strategy) {
@@ -10323,7 +9933,7 @@ var approvalCommand = new Command19("approval").description("Plan-Approval-Strat
10323
9933
  log.error("Ung\xFCltige Zahl");
10324
9934
  return;
10325
9935
  }
10326
- updateApproval(projectPath, { thresholds: { ...config2.approval.thresholds, autoApproveMaxFiles: n } });
9936
+ updateApproval(projectPath, { thresholds: { ...config.approval.thresholds, autoApproveMaxFiles: n } });
10327
9937
  log.success(`Max. Dateien f\xFCr Auto-Approval: ${n}`);
10328
9938
  }
10329
9939
  if (options.maxLines) {
@@ -10332,15 +9942,15 @@ var approvalCommand = new Command19("approval").description("Plan-Approval-Strat
10332
9942
  log.error("Ung\xFCltige Zahl");
10333
9943
  return;
10334
9944
  }
10335
- updateApproval(projectPath, { thresholds: { ...config2.approval.thresholds, autoApproveMaxLines: n } });
9945
+ updateApproval(projectPath, { thresholds: { ...config.approval.thresholds, autoApproveMaxLines: n } });
10336
9946
  log.success(`Max. Zeilen f\xFCr Auto-Approval: ${n}`);
10337
9947
  }
10338
9948
  if (options.require) {
10339
- const current = config2.approval.thresholds.requireApprovalPatterns;
9949
+ const current = config.approval.thresholds.requireApprovalPatterns;
10340
9950
  if (!current.includes(options.require)) {
10341
9951
  updateApproval(projectPath, {
10342
9952
  thresholds: {
10343
- ...config2.approval.thresholds,
9953
+ ...config.approval.thresholds,
10344
9954
  requireApprovalPatterns: [...current, options.require]
10345
9955
  }
10346
9956
  });
@@ -10348,11 +9958,11 @@ var approvalCommand = new Command19("approval").description("Plan-Approval-Strat
10348
9958
  }
10349
9959
  }
10350
9960
  if (options.skip) {
10351
- const current = config2.approval.thresholds.skipApprovalPatterns;
9961
+ const current = config.approval.thresholds.skipApprovalPatterns;
10352
9962
  if (!current.includes(options.skip)) {
10353
9963
  updateApproval(projectPath, {
10354
9964
  thresholds: {
10355
- ...config2.approval.thresholds,
9965
+ ...config.approval.thresholds,
10356
9966
  skipApprovalPatterns: [...current, options.skip]
10357
9967
  }
10358
9968
  });
@@ -10360,20 +9970,20 @@ var approvalCommand = new Command19("approval").description("Plan-Approval-Strat
10360
9970
  }
10361
9971
  }
10362
9972
  if (options.removeRequire) {
10363
- const current = config2.approval.thresholds.requireApprovalPatterns;
9973
+ const current = config.approval.thresholds.requireApprovalPatterns;
10364
9974
  updateApproval(projectPath, {
10365
9975
  thresholds: {
10366
- ...config2.approval.thresholds,
9976
+ ...config.approval.thresholds,
10367
9977
  requireApprovalPatterns: current.filter((p) => p !== options.removeRequire)
10368
9978
  }
10369
9979
  });
10370
9980
  log.success(`Require-Pattern entfernt: ${options.removeRequire}`);
10371
9981
  }
10372
9982
  if (options.removeSkip) {
10373
- const current = config2.approval.thresholds.skipApprovalPatterns;
9983
+ const current = config.approval.thresholds.skipApprovalPatterns;
10374
9984
  updateApproval(projectPath, {
10375
9985
  thresholds: {
10376
- ...config2.approval.thresholds,
9986
+ ...config.approval.thresholds,
10377
9987
  skipApprovalPatterns: current.filter((p) => p !== options.removeSkip)
10378
9988
  }
10379
9989
  });
@@ -10381,7 +9991,7 @@ var approvalCommand = new Command19("approval").description("Plan-Approval-Strat
10381
9991
  }
10382
9992
  displayApprovalStatus(getSecurityConfig(projectPath).approval);
10383
9993
  });
10384
- function displayApprovalStatus(config2) {
9994
+ function displayApprovalStatus(config) {
10385
9995
  log.newline();
10386
9996
  console.log(colors.orange.bold("Approval-Einstellungen"));
10387
9997
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
@@ -10391,12 +10001,12 @@ function displayApprovalStatus(config2) {
10391
10001
  "manual": colors.green("Manuell"),
10392
10002
  "hybrid": colors.cyan("Hybrid")
10393
10003
  };
10394
- log.keyValue("Strategie", strategyDisplay[config2.strategy]);
10395
- if (config2.strategy === "hybrid") {
10396
- log.keyValue("Max. Dateien", String(config2.thresholds.autoApproveMaxFiles));
10397
- log.keyValue("Max. Zeilen", String(config2.thresholds.autoApproveMaxLines));
10398
- log.keyValue("Require-Patterns", config2.thresholds.requireApprovalPatterns.join(", ") || colors.dim("Keine"));
10399
- log.keyValue("Skip-Patterns", config2.thresholds.skipApprovalPatterns.join(", ") || colors.dim("Keine"));
10004
+ log.keyValue("Strategie", strategyDisplay[config.strategy]);
10005
+ if (config.strategy === "hybrid") {
10006
+ log.keyValue("Max. Dateien", String(config.thresholds.autoApproveMaxFiles));
10007
+ log.keyValue("Max. Zeilen", String(config.thresholds.autoApproveMaxLines));
10008
+ log.keyValue("Require-Patterns", config.thresholds.requireApprovalPatterns.join(", ") || colors.dim("Keine"));
10009
+ log.keyValue("Skip-Patterns", config.thresholds.skipApprovalPatterns.join(", ") || colors.dim("Keine"));
10400
10010
  }
10401
10011
  log.newline();
10402
10012
  }
@@ -10430,16 +10040,16 @@ securityCommand.command("set-tier <tier>").description("Security-Tier setzen (be
10430
10040
  log.newline();
10431
10041
  displayTierInfo(tier, preset);
10432
10042
  });
10433
- function displayTierInfo(tier, config2) {
10043
+ function displayTierInfo(tier, config) {
10434
10044
  console.log(colors.orange.bold(`Tier: ${tier}`));
10435
10045
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
10436
10046
  log.newline();
10437
10047
  const check = (value) => value ? colors.green("\u2713") : colors.dim("\u2717");
10438
- log.plain(` ${check(config2.skipPermissions)} Skip Permissions`);
10439
- log.plain(` ${check(config2.dockerIsolation)} Docker Isolation`);
10440
- log.plain(` ${check(config2.require2FA)} 2FA erforderlich`);
10441
- log.plain(` ${check(config2.timeRestrictions)} Zeit-Einschr\xE4nkungen`);
10442
- log.plain(` Approval: ${config2.approvalStrategy}`);
10048
+ log.plain(` ${check(config.skipPermissions)} Skip Permissions`);
10049
+ log.plain(` ${check(config.dockerIsolation)} Docker Isolation`);
10050
+ log.plain(` ${check(config.require2FA)} 2FA erforderlich`);
10051
+ log.plain(` ${check(config.timeRestrictions)} Zeit-Einschr\xE4nkungen`);
10052
+ log.plain(` Approval: ${config.approvalStrategy}`);
10443
10053
  log.newline();
10444
10054
  }
10445
10055
  securityCommand.command("audit").description("Sicherheits-Audit durchf\xFChren").action(async () => {
@@ -10449,15 +10059,15 @@ securityCommand.command("audit").description("Sicherheits-Audit durchf\xFChren")
10449
10059
  log.info("Initialisiere mit: shiva project time --enable");
10450
10060
  return;
10451
10061
  }
10452
- const config2 = getProjectConfigV2(projectPath);
10453
- const audit = performSecurityAudit(config2);
10062
+ const config = getProjectConfigV2(projectPath);
10063
+ const audit = performSecurityAudit(config);
10454
10064
  displaySecurityAudit(audit);
10455
10065
  });
10456
- function performSecurityAudit(config2) {
10066
+ function performSecurityAudit(config) {
10457
10067
  const checks = [];
10458
10068
  const recommendations = [];
10459
10069
  let score = 10;
10460
- if (config2.security.permissions.skipPermissions === "skip") {
10070
+ if (config.security.permissions.skipPermissions === "skip") {
10461
10071
  checks.push({
10462
10072
  name: "Permissions",
10463
10073
  status: "warn",
@@ -10465,7 +10075,7 @@ function performSecurityAudit(config2) {
10465
10075
  });
10466
10076
  recommendations.push("Deaktiviere Skip-Permissions f\xFCr erh\xF6hte Sicherheit");
10467
10077
  score -= 2;
10468
- } else if (config2.security.permissions.skipPermissions === "no-skip") {
10078
+ } else if (config.security.permissions.skipPermissions === "no-skip") {
10469
10079
  checks.push({
10470
10080
  name: "Permissions",
10471
10081
  status: "pass",
@@ -10478,11 +10088,11 @@ function performSecurityAudit(config2) {
10478
10088
  message: "Erbt von global"
10479
10089
  });
10480
10090
  }
10481
- if (config2.security.permissions.blockedPaths.length > 0) {
10091
+ if (config.security.permissions.blockedPaths.length > 0) {
10482
10092
  checks.push({
10483
10093
  name: "Pfad-Blocking",
10484
10094
  status: "pass",
10485
- message: `${config2.security.permissions.blockedPaths.length} Pfade blockiert`
10095
+ message: `${config.security.permissions.blockedPaths.length} Pfade blockiert`
10486
10096
  });
10487
10097
  } else {
10488
10098
  checks.push({
@@ -10493,13 +10103,13 @@ function performSecurityAudit(config2) {
10493
10103
  recommendations.push("Blockiere sensible Pfade wie .env oder secrets/");
10494
10104
  score -= 1;
10495
10105
  }
10496
- if (config2.security.approval.strategy === "manual") {
10106
+ if (config.security.approval.strategy === "manual") {
10497
10107
  checks.push({
10498
10108
  name: "Approval",
10499
10109
  status: "pass",
10500
10110
  message: "Manuelle Genehmigung"
10501
10111
  });
10502
- } else if (config2.security.approval.strategy === "hybrid") {
10112
+ } else if (config.security.approval.strategy === "hybrid") {
10503
10113
  checks.push({
10504
10114
  name: "Approval",
10505
10115
  status: "pass",
@@ -10514,7 +10124,7 @@ function performSecurityAudit(config2) {
10514
10124
  recommendations.push("Wechsle zu hybrid oder manual Approval");
10515
10125
  score -= 1;
10516
10126
  }
10517
- if (config2.docker.enabled === true) {
10127
+ if (config.docker.enabled === true) {
10518
10128
  checks.push({
10519
10129
  name: "Docker",
10520
10130
  status: "pass",
@@ -10529,24 +10139,24 @@ function performSecurityAudit(config2) {
10529
10139
  recommendations.push("Aktiviere Docker f\xFCr isolierte Ausf\xFChrung");
10530
10140
  score -= 1;
10531
10141
  }
10532
- if (config2.docker.enabled && config2.docker.network === "none") {
10142
+ if (config.docker.enabled && config.docker.network === "none") {
10533
10143
  checks.push({
10534
10144
  name: "Netzwerk",
10535
10145
  status: "pass",
10536
10146
  message: "Netzwerk-Isolation aktiv"
10537
10147
  });
10538
- } else if (config2.docker.enabled && config2.docker.network === "bridge") {
10148
+ } else if (config.docker.enabled && config.docker.network === "bridge") {
10539
10149
  checks.push({
10540
10150
  name: "Netzwerk",
10541
10151
  status: "warn",
10542
10152
  message: "Bridge-Netzwerk"
10543
10153
  });
10544
10154
  }
10545
- if (config2.session.timeControl.enabled) {
10155
+ if (config.session.timeControl.enabled) {
10546
10156
  checks.push({
10547
10157
  name: "Zeitkontrolle",
10548
10158
  status: "pass",
10549
- message: `${config2.session.timeControl.allowedHours.start}-${config2.session.timeControl.allowedHours.end}`
10159
+ message: `${config.session.timeControl.allowedHours.start}-${config.session.timeControl.allowedHours.end}`
10550
10160
  });
10551
10161
  } else {
10552
10162
  checks.push({
@@ -10556,7 +10166,7 @@ function performSecurityAudit(config2) {
10556
10166
  });
10557
10167
  score -= 0.5;
10558
10168
  }
10559
- const hasBudget = config2.session.budget.dailyTokenLimit || config2.session.budget.weeklyTokenLimit || config2.session.budget.monthlyTokenLimit;
10169
+ const hasBudget = config.session.budget.dailyTokenLimit || config.session.budget.weeklyTokenLimit || config.session.budget.monthlyTokenLimit;
10560
10170
  if (hasBudget) {
10561
10171
  checks.push({
10562
10172
  name: "Token-Budget",
@@ -10571,7 +10181,7 @@ function performSecurityAudit(config2) {
10571
10181
  });
10572
10182
  score -= 0.5;
10573
10183
  }
10574
- if (config2.security.require2FA) {
10184
+ if (config.security.require2FA) {
10575
10185
  checks.push({
10576
10186
  name: "2FA",
10577
10187
  status: "pass",
@@ -10587,7 +10197,7 @@ function performSecurityAudit(config2) {
10587
10197
  score -= 1;
10588
10198
  }
10589
10199
  return {
10590
- tier: config2.security.tier,
10200
+ tier: config.security.tier,
10591
10201
  checks,
10592
10202
  recommendations,
10593
10203
  score: Math.max(0, Math.round(score))
@@ -10623,23 +10233,23 @@ securityCommand.command("status").description("Sicherheitsstatus anzeigen").acti
10623
10233
  log.info("Initialisiere mit: shiva project time --enable");
10624
10234
  return;
10625
10235
  }
10626
- const config2 = getProjectConfigV2(projectPath);
10236
+ const config = getProjectConfigV2(projectPath);
10627
10237
  log.newline();
10628
10238
  console.log(colors.orange.bold("SHIVA Security Status"));
10629
10239
  console.log(colors.dim("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
10630
10240
  log.newline();
10631
- log.keyValue("Security-Tier", config2.security.tier);
10632
- log.keyValue("2FA erforderlich", config2.security.require2FA ? "Ja" : "Nein");
10241
+ log.keyValue("Security-Tier", config.security.tier);
10242
+ log.keyValue("2FA erforderlich", config.security.require2FA ? "Ja" : "Nein");
10633
10243
  log.newline();
10634
- displayPermissionsStatus(config2.security.permissions);
10635
- displayApprovalStatus(config2.security.approval);
10244
+ displayPermissionsStatus(config.security.permissions);
10245
+ displayApprovalStatus(config.security.approval);
10636
10246
  });
10637
10247
  var tfaCommand = new Command19("2fa").description("Zwei-Faktor-Authentifizierung").option("--enable", "2FA aktivieren").option("--disable", "2FA deaktivieren").option("--status", "Status anzeigen").option("--backup", "Neue Backup-Codes generieren").action(async (options) => {
10638
10248
  if (!isAuthenticated()) {
10639
10249
  log.error("Nicht angemeldet. Verwende: shiva login");
10640
10250
  return;
10641
10251
  }
10642
- const config2 = getConfig();
10252
+ const config = getConfig();
10643
10253
  if (options.status || Object.keys(options).length === 0) {
10644
10254
  try {
10645
10255
  const status = await twoFactorService.getStatus();
@@ -10661,7 +10271,7 @@ var tfaCommand = new Command19("2fa").description("Zwei-Faktor-Authentifizierung
10661
10271
  if (options.enable) {
10662
10272
  try {
10663
10273
  log.info("Initialisiere 2FA-Setup...");
10664
- const setup = await twoFactorService.startSetup(config2.email || "");
10274
+ const setup = await twoFactorService.startSetup(config.email || "");
10665
10275
  displayQRCode(setup.qrCodeDataUrl);
10666
10276
  log.plain(`Oder manuell eingeben: ${colors.cyan(setup.secret)}`);
10667
10277
  log.newline();
@@ -10778,7 +10388,7 @@ import { Command as Command20 } from "commander";
10778
10388
  import inquirer8 from "inquirer";
10779
10389
  import ora13 from "ora";
10780
10390
  import * as fs6 from "fs";
10781
- import * as path7 from "path";
10391
+ import * as path6 from "path";
10782
10392
 
10783
10393
  // src/utils/clipboard.ts
10784
10394
  import { execSync as execSync2, spawnSync as spawnSync6 } from "child_process";
@@ -11103,7 +10713,7 @@ secretsCommand.command("import").description(".env Datei in Vault importieren").
11103
10713
  log.errorWithSuggestion(Errors.NOT_AUTHENTICATED());
11104
10714
  return;
11105
10715
  }
11106
- const filePath = path7.resolve(file);
10716
+ const filePath = path6.resolve(file);
11107
10717
  if (!fs6.existsSync(filePath)) {
11108
10718
  log.errorWithSuggestion(Errors.FILE_NOT_FOUND(file));
11109
10719
  return;
@@ -11136,7 +10746,7 @@ secretsCommand.command("import").description(".env Datei in Vault importieren").
11136
10746
  log.listItem(`${secret.key} = ${preview}`);
11137
10747
  }
11138
10748
  log.newline();
11139
- log.dim(`${secrets.length} Secret(s) aus ${path7.basename(file)}`);
10749
+ log.dim(`${secrets.length} Secret(s) aus ${path6.basename(file)}`);
11140
10750
  log.newline();
11141
10751
  if (options.dryRun) {
11142
10752
  log.info("Dry-run: Keine \xC4nderungen vorgenommen");
@@ -11233,22 +10843,22 @@ import ora14 from "ora";
11233
10843
 
11234
10844
  // src/services/data/memory.ts
11235
10845
  import * as fs7 from "fs";
11236
- import * as path8 from "path";
11237
- import * as os5 from "os";
10846
+ import * as path7 from "path";
10847
+ import * as os4 from "os";
11238
10848
  function findAllClaudeMdFiles() {
11239
10849
  const results = [];
11240
- const sessionsPath = path8.join(os5.homedir(), ".claude", "projects");
10850
+ const sessionsPath = path7.join(os4.homedir(), ".claude", "projects");
11241
10851
  if (fs7.existsSync(sessionsPath)) {
11242
10852
  const dirs = fs7.readdirSync(sessionsPath);
11243
10853
  for (const dir of dirs) {
11244
10854
  const projectPath = decodeProjectPath(dir);
11245
10855
  if (projectPath && fs7.existsSync(projectPath)) {
11246
- const claudeMdPath = path8.join(projectPath, "CLAUDE.md");
10856
+ const claudeMdPath = path7.join(projectPath, "CLAUDE.md");
11247
10857
  if (fs7.existsSync(claudeMdPath)) {
11248
10858
  results.push({
11249
10859
  path: claudeMdPath,
11250
10860
  projectPath,
11251
- projectName: path8.basename(projectPath)
10861
+ projectName: path7.basename(projectPath)
11252
10862
  });
11253
10863
  }
11254
10864
  }
@@ -11326,7 +10936,6 @@ async function getAllMemories() {
11326
10936
  return Array.from(memoryMap.values());
11327
10937
  }
11328
10938
  async function searchMemories(query, options = {}) {
11329
- const allMemories = await getAllMemories();
11330
10939
  const {
11331
10940
  caseSensitive = false,
11332
10941
  category,
@@ -11335,24 +10944,57 @@ async function searchMemories(query, options = {}) {
11335
10944
  limit = 100
11336
10945
  } = options;
11337
10946
  const searchQuery = caseSensitive ? query : query.toLowerCase();
11338
- const filtered = allMemories.filter((memory) => {
11339
- if (source !== "all" && memory.source !== source) {
11340
- return false;
10947
+ let allMemories = [];
10948
+ if (source === "local" || source === "all") {
10949
+ const localMemories = getLocalMemories();
10950
+ allMemories.push(...localMemories);
10951
+ }
10952
+ if ((source === "cloud" || source === "all") && isAuthenticated()) {
10953
+ try {
10954
+ const cloudResults = await api.searchMemories(query);
10955
+ const cloudMemories = cloudResults.map((m) => ({
10956
+ key: m.key,
10957
+ value: m.value,
10958
+ category: m.category,
10959
+ source: "cloud",
10960
+ projectName: m.projectName,
10961
+ projectPath: "",
10962
+ // Not returned by search API
10963
+ projectId: m.projectId,
10964
+ memoryId: m.id
10965
+ }));
10966
+ allMemories.push(...cloudMemories);
10967
+ } catch {
10968
+ const cloudMemories = await getCloudMemories();
10969
+ allMemories.push(...cloudMemories);
10970
+ }
10971
+ }
10972
+ const memoryMap = /* @__PURE__ */ new Map();
10973
+ for (const memory of allMemories) {
10974
+ const key = `${memory.projectName}:${memory.key}`;
10975
+ if (!memoryMap.has(key) || memory.source === "cloud") {
10976
+ memoryMap.set(key, memory);
11341
10977
  }
10978
+ }
10979
+ allMemories = Array.from(memoryMap.values());
10980
+ const filtered = allMemories.filter((memory) => {
11342
10981
  if (category && memory.category !== category) {
11343
10982
  return false;
11344
10983
  }
11345
10984
  if (project) {
11346
- const projectMatch = caseSensitive ? memory.projectName.includes(project) || memory.projectPath.includes(project) : memory.projectName.toLowerCase().includes(project.toLowerCase()) || memory.projectPath.toLowerCase().includes(project.toLowerCase());
10985
+ const projectMatch = caseSensitive ? memory.projectName.includes(project) : memory.projectName.toLowerCase().includes(project.toLowerCase());
11347
10986
  if (!projectMatch) {
11348
10987
  return false;
11349
10988
  }
11350
10989
  }
11351
- const searchFields = [memory.key, memory.value, memory.category];
11352
- const haystack = caseSensitive ? searchFields.join(" ") : searchFields.join(" ").toLowerCase();
11353
- return haystack.includes(searchQuery);
10990
+ if (memory.source === "local") {
10991
+ const searchFields = [memory.key, memory.value, memory.category];
10992
+ const haystack = caseSensitive ? searchFields.join(" ") : searchFields.join(" ").toLowerCase();
10993
+ return haystack.includes(searchQuery);
10994
+ }
10995
+ return true;
11354
10996
  });
11355
- const projectSet = new Set(filtered.map((m) => m.projectPath));
10997
+ const projectSet = new Set(filtered.map((m) => m.projectName));
11356
10998
  return {
11357
10999
  memories: filtered.slice(0, limit),
11358
11000
  totalCount: filtered.length,
@@ -11360,7 +11002,7 @@ async function searchMemories(query, options = {}) {
11360
11002
  };
11361
11003
  }
11362
11004
  function deleteLocalMemory(projectPath, key) {
11363
- const claudeMdPath = path8.join(projectPath, "CLAUDE.md");
11005
+ const claudeMdPath = path7.join(projectPath, "CLAUDE.md");
11364
11006
  if (!fs7.existsSync(claudeMdPath)) {
11365
11007
  return false;
11366
11008
  }
@@ -11410,7 +11052,7 @@ async function deleteMemory(projectPath, key, options = {}) {
11410
11052
  }
11411
11053
  async function deleteAllProjectMemories(projectPath) {
11412
11054
  const result = { local: 0, cloud: 0 };
11413
- const claudeMdPath = path8.join(projectPath, "CLAUDE.md");
11055
+ const claudeMdPath = path7.join(projectPath, "CLAUDE.md");
11414
11056
  if (fs7.existsSync(claudeMdPath)) {
11415
11057
  try {
11416
11058
  let content = fs7.readFileSync(claudeMdPath, "utf-8");
@@ -11439,8 +11081,8 @@ async function deleteAllProjectMemories(projectPath) {
11439
11081
  return result;
11440
11082
  }
11441
11083
  async function getContextPreview(projectPath) {
11442
- const projectName = path8.basename(projectPath);
11443
- const claudeMdPath = path8.join(projectPath, "CLAUDE.md");
11084
+ const projectName = path7.basename(projectPath);
11085
+ const claudeMdPath = path7.join(projectPath, "CLAUDE.md");
11444
11086
  const preview = {
11445
11087
  projectName,
11446
11088
  projectPath,
@@ -11462,8 +11104,8 @@ async function getContextPreview(projectPath) {
11462
11104
  projectPath
11463
11105
  }));
11464
11106
  }
11465
- const shivaDir = path8.join(projectPath, ".shiva");
11466
- const contextPath = path8.join(shivaDir, "github-context.md");
11107
+ const shivaDir = path7.join(projectPath, ".shiva");
11108
+ const contextPath = path7.join(shivaDir, "github-context.md");
11467
11109
  if (fs7.existsSync(contextPath)) {
11468
11110
  const content = fs7.readFileSync(contextPath, "utf-8");
11469
11111
  preview.githubContext = content;
@@ -11557,7 +11199,7 @@ function escapeRegex2(str) {
11557
11199
 
11558
11200
  // src/commands/memory/forget.ts
11559
11201
  import { Command as Command22 } from "commander";
11560
- import * as path9 from "path";
11202
+ import * as path8 from "path";
11561
11203
  import inquirer9 from "inquirer";
11562
11204
  import ora15 from "ora";
11563
11205
  var forgetCommand = new Command22("forget").description("Memories l\xF6schen (GDPR)").argument("[key]", "Memory-Key zum L\xF6schen").option("-p, --project <path>", "Projekt-Pfad").option("--all", "Alle Memories eines Projekts l\xF6schen").option("--search <query>", "Memories nach Suchbegriff l\xF6schen").option("--local-only", "Nur lokal l\xF6schen").option("--cloud-only", "Nur aus Cloud l\xF6schen").option("-f, --force", "Ohne Best\xE4tigung l\xF6schen").option("--dry-run", "Nur anzeigen, was gel\xF6scht w\xFCrde").action(async (key, options) => {
@@ -11565,7 +11207,7 @@ var forgetCommand = new Command22("forget").description("Memories l\xF6schen (GD
11565
11207
  console.log(colors.orange.bold("SHIVA Code - Forget"));
11566
11208
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
11567
11209
  log.newline();
11568
- const projectPath = options.project ? path9.resolve(options.project) : process.cwd();
11210
+ const projectPath = options.project ? path8.resolve(options.project) : process.cwd();
11569
11211
  if (options.all) {
11570
11212
  await handleDeleteAll(projectPath, options);
11571
11213
  return;
@@ -11581,7 +11223,7 @@ var forgetCommand = new Command22("forget").description("Memories l\xF6schen (GD
11581
11223
  await handleInteractiveDelete(projectPath, options);
11582
11224
  });
11583
11225
  async function handleDeleteAll(projectPath, options) {
11584
- const projectName = path9.basename(projectPath);
11226
+ const projectName = path8.basename(projectPath);
11585
11227
  console.log(colors.red.bold("\u26A0\uFE0F WARNUNG: Alle Memories l\xF6schen"));
11586
11228
  console.log(colors.dim(`Projekt: ${projectName}`));
11587
11229
  console.log(colors.dim(`Pfad: ${projectPath}`));
@@ -11687,7 +11329,7 @@ async function handleDeleteBySearch(query, projectPath, options) {
11687
11329
  }
11688
11330
  async function handleDeleteKey(key, projectPath, options) {
11689
11331
  console.log(colors.bold(`Memory l\xF6schen: ${key}`));
11690
- console.log(colors.dim(`Projekt: ${path9.basename(projectPath)}`));
11332
+ console.log(colors.dim(`Projekt: ${path8.basename(projectPath)}`));
11691
11333
  log.newline();
11692
11334
  if (options.dryRun) {
11693
11335
  log.info("Dry-run: Keine \xC4nderungen werden vorgenommen");
@@ -11802,12 +11444,12 @@ function truncate(str, maxLen) {
11802
11444
 
11803
11445
  // src/commands/memory/context.ts
11804
11446
  import { Command as Command23 } from "commander";
11805
- import * as path10 from "path";
11447
+ import * as path9 from "path";
11806
11448
  import * as fs8 from "fs";
11807
11449
  import ora16 from "ora";
11808
11450
  var contextCommand = new Command23("context").description("Zeigt was in Claude injected w\xFCrde").option("-d, --dir <path>", "Projektverzeichnis").option("--github", "GitHub Context einschlie\xDFen").option("--secrets", "Secret-Keys anzeigen").option("--raw", "Rohe CLAUDE.md Ausgabe").option("--json", "JSON Ausgabe").option("-s, --size", "Nur Gr\xF6\xDFe anzeigen").action(async (options) => {
11809
- const projectPath = options.dir ? path10.resolve(options.dir) : process.cwd();
11810
- const projectName = path10.basename(projectPath);
11451
+ const projectPath = options.dir ? path9.resolve(options.dir) : process.cwd();
11452
+ const projectName = path9.basename(projectPath);
11811
11453
  if (!fs8.existsSync(projectPath)) {
11812
11454
  log.error(`Verzeichnis nicht gefunden: ${projectPath}`);
11813
11455
  return;
@@ -12191,14 +11833,14 @@ async function resolveSessionId(input) {
12191
11833
 
12192
11834
  // src/commands/memory/export.ts
12193
11835
  import { Command as Command25 } from "commander";
12194
- import * as path12 from "path";
11836
+ import * as path11 from "path";
12195
11837
  import * as fs10 from "fs";
12196
11838
  import ora17 from "ora";
12197
11839
  import inquirer11 from "inquirer";
12198
11840
 
12199
11841
  // src/services/session/export.ts
12200
11842
  import * as fs9 from "fs";
12201
- import * as path11 from "path";
11843
+ import * as path10 from "path";
12202
11844
  import { execSync as execSync3 } from "child_process";
12203
11845
  async function exportSession(sessionId, options = {}) {
12204
11846
  const projects = await getAllClaudeProjects();
@@ -12214,7 +11856,7 @@ async function exportSession(sessionId, options = {}) {
12214
11856
  tags: getSessionTags(sessionId)
12215
11857
  };
12216
11858
  if (options.includeTranscript) {
12217
- const transcriptPath = path11.join(
11859
+ const transcriptPath = path10.join(
12218
11860
  getClaudeProjectsPath(),
12219
11861
  encodeProjectPath(project.absolutePath),
12220
11862
  session.sessionId + ".jsonl"
@@ -12224,7 +11866,7 @@ async function exportSession(sessionId, options = {}) {
12224
11866
  }
12225
11867
  }
12226
11868
  if (options.includeConversation && options.includeTranscript) {
12227
- const transcriptPath = path11.join(
11869
+ const transcriptPath = path10.join(
12228
11870
  getClaudeProjectsPath(),
12229
11871
  encodeProjectPath(project.absolutePath),
12230
11872
  session.sessionId + ".jsonl"
@@ -12265,7 +11907,7 @@ async function exportSessions(sessionIds, outputDir, options = {}) {
12265
11907
  const exported = await exportSession(sessionId, options);
12266
11908
  if (exported) {
12267
11909
  const filename = `${exported.projectName}-${sessionId.slice(0, 8)}.json`;
12268
- const filepath = path11.join(outputDir, filename);
11910
+ const filepath = path10.join(outputDir, filename);
12269
11911
  fs9.writeFileSync(filepath, JSON.stringify(exported, null, 2));
12270
11912
  success++;
12271
11913
  } else {
@@ -12295,7 +11937,7 @@ function createBackupArchive(outputPath, projectPaths) {
12295
11937
  if (projectPaths && projectPaths.length > 0) {
12296
11938
  for (const p of projectPaths) {
12297
11939
  const encoded = encodeProjectPath(p);
12298
- const fullPath = path11.join(claudeDir, encoded);
11940
+ const fullPath = path10.join(claudeDir, encoded);
12299
11941
  if (fs9.existsSync(fullPath)) {
12300
11942
  includePaths.push(encoded);
12301
11943
  }
@@ -12303,7 +11945,7 @@ function createBackupArchive(outputPath, projectPaths) {
12303
11945
  } else {
12304
11946
  const entries = fs9.readdirSync(claudeDir);
12305
11947
  includePaths = entries.filter((e) => {
12306
- const stat = fs9.statSync(path11.join(claudeDir, e));
11948
+ const stat = fs9.statSync(path10.join(claudeDir, e));
12307
11949
  return stat.isDirectory();
12308
11950
  });
12309
11951
  }
@@ -12323,11 +11965,11 @@ async function importSession(data, targetProjectPath) {
12323
11965
  try {
12324
11966
  const projectPath = targetProjectPath || data.projectPath;
12325
11967
  const encodedPath = encodeProjectPath(projectPath);
12326
- const sessionDir = path11.join(getClaudeProjectsPath(), encodedPath);
11968
+ const sessionDir = path10.join(getClaudeProjectsPath(), encodedPath);
12327
11969
  if (!fs9.existsSync(sessionDir)) {
12328
11970
  fs9.mkdirSync(sessionDir, { recursive: true });
12329
11971
  }
12330
- const sessionFile = path11.join(sessionDir, data.session.sessionId + ".jsonl");
11972
+ const sessionFile = path10.join(sessionDir, data.session.sessionId + ".jsonl");
12331
11973
  if (fs9.existsSync(sessionFile)) {
12332
11974
  return {
12333
11975
  success: false,
@@ -12399,7 +12041,7 @@ async function importSessionsFromDirectory(dirPath, targetProjectPath) {
12399
12041
  let success = 0;
12400
12042
  let failed = 0;
12401
12043
  for (const file of files) {
12402
- const filepath = path11.join(dirPath, file);
12044
+ const filepath = path10.join(dirPath, file);
12403
12045
  const result = await importSessionFromFile(filepath, targetProjectPath);
12404
12046
  results.push(result);
12405
12047
  if (result.success) {
@@ -12477,7 +12119,7 @@ var importCommand = new Command25("import").description("Sessions importieren").
12477
12119
  console.log(colors.orange.bold("SHIVA Code - Import"));
12478
12120
  console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
12479
12121
  log.newline();
12480
- const absolutePath = path12.resolve(inputPath);
12122
+ const absolutePath = path11.resolve(inputPath);
12481
12123
  if (!fs10.existsSync(absolutePath)) {
12482
12124
  log.error(`Datei nicht gefunden: ${absolutePath}`);
12483
12125
  return;
@@ -12500,7 +12142,7 @@ var importCommand = new Command25("import").description("Sessions importieren").
12500
12142
  async function handleBackup(outputPath) {
12501
12143
  const spinner = ora17("Erstelle Backup...").start();
12502
12144
  const filename = `shiva-backup-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.tar.gz`;
12503
- const output = outputPath || path12.join(process.cwd(), filename);
12145
+ const output = outputPath || path11.join(process.cwd(), filename);
12504
12146
  const success = createBackupArchive(output);
12505
12147
  if (success) {
12506
12148
  spinner.succeed(`Backup erstellt: ${output}`);
@@ -12519,7 +12161,7 @@ async function handleExportAll(outputDir, options = {}) {
12519
12161
  return;
12520
12162
  }
12521
12163
  spinner.text = `Exportiere ${allSessionIds.length} Sessions...`;
12522
- const output = outputDir || path12.join(process.cwd(), "shiva-export");
12164
+ const output = outputDir || path11.join(process.cwd(), "shiva-export");
12523
12165
  const result = await exportSessions(allSessionIds, output, options);
12524
12166
  spinner.succeed(`Export abgeschlossen`);
12525
12167
  log.info(`${result.success} Sessions exportiert`);
@@ -12543,7 +12185,7 @@ async function handleExportProject(projectName, outputDir, options = {}) {
12543
12185
  return;
12544
12186
  }
12545
12187
  spinner.text = `Exportiere ${project.sessions.length} Sessions aus ${project.projectName}...`;
12546
- const output = outputDir || path12.join(process.cwd(), `${project.projectName}-export`);
12188
+ const output = outputDir || path11.join(process.cwd(), `${project.projectName}-export`);
12547
12189
  const result = await exportProjectSessions(project.absolutePath, output, options);
12548
12190
  spinner.succeed(`Export abgeschlossen`);
12549
12191
  log.info(`${result.success} Sessions exportiert`);
@@ -12672,15 +12314,15 @@ var rememberCommand = new Command26("remember").description("Memory in der Cloud
12672
12314
  return;
12673
12315
  }
12674
12316
  const projectPath = process.cwd();
12675
- const config2 = getProjectConfig(projectPath);
12676
- if (!config2.projectId) {
12317
+ const config = getProjectConfig(projectPath);
12318
+ if (!config.projectId) {
12677
12319
  log.error("Projekt nicht mit Cloud verbunden");
12678
12320
  log.info("Verbinden mit: shiva init && shiva sync");
12679
12321
  return;
12680
12322
  }
12681
12323
  const key = options.key || text.substring(0, 50).replace(/[^a-zA-Z0-9]/g, "_");
12682
12324
  try {
12683
- const result = await api.addMemory(config2.projectId, {
12325
+ const result = await api.addMemory(config.projectId, {
12684
12326
  key,
12685
12327
  value: text,
12686
12328
  category: options.category
@@ -12700,8 +12342,8 @@ var rememberCommand = new Command26("remember").description("Memory in der Cloud
12700
12342
  import { Command as Command27 } from "commander";
12701
12343
  import { execSync as execSync4 } from "child_process";
12702
12344
  import * as fs11 from "fs";
12703
- import * as path13 from "path";
12704
- import * as os6 from "os";
12345
+ import * as path12 from "path";
12346
+ import * as os5 from "os";
12705
12347
  function tryExec(command) {
12706
12348
  try {
12707
12349
  return execSync4(command, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
@@ -12862,8 +12504,8 @@ function checkNpm() {
12862
12504
  };
12863
12505
  }
12864
12506
  function checkShivaConfig() {
12865
- const configDir = path13.join(os6.homedir(), ".config", "shiva-code");
12866
- const configFile = path13.join(configDir, "config.json");
12507
+ const configDir = path12.join(os5.homedir(), ".config", "shiva-code");
12508
+ const configFile = path12.join(configDir, "config.json");
12867
12509
  if (!fs11.existsSync(configDir)) {
12868
12510
  return {
12869
12511
  name: "SHIVA Config",
@@ -12887,7 +12529,7 @@ function checkShivaConfig() {
12887
12529
  };
12888
12530
  }
12889
12531
  function checkClaudeProjects() {
12890
- const claudeDir = path13.join(os6.homedir(), ".claude", "projects");
12532
+ const claudeDir = path12.join(os5.homedir(), ".claude", "projects");
12891
12533
  if (!fs11.existsSync(claudeDir)) {
12892
12534
  return {
12893
12535
  name: "Claude Projects",
@@ -12898,7 +12540,7 @@ function checkClaudeProjects() {
12898
12540
  }
12899
12541
  try {
12900
12542
  const projects = fs11.readdirSync(claudeDir).filter(
12901
- (f) => fs11.statSync(path13.join(claudeDir, f)).isDirectory()
12543
+ (f) => fs11.statSync(path12.join(claudeDir, f)).isDirectory()
12902
12544
  );
12903
12545
  return {
12904
12546
  name: "Claude Projects",
@@ -12931,11 +12573,11 @@ function checkTmux() {
12931
12573
  };
12932
12574
  }
12933
12575
  function getSystemInfo() {
12934
- const totalMem = os6.totalmem();
12576
+ const totalMem = os5.totalmem();
12935
12577
  const memGB = (totalMem / (1024 * 1024 * 1024)).toFixed(1);
12936
12578
  return {
12937
- os: `${os6.type()} ${os6.release()}`,
12938
- arch: os6.arch(),
12579
+ os: `${os5.type()} ${os5.release()}`,
12580
+ arch: os5.arch(),
12939
12581
  memory: `${memGB} GB`
12940
12582
  };
12941
12583
  }
@@ -13027,14 +12669,14 @@ var doctorCommand = new Command27("doctor").description("System-Check f\xFCr SHI
13027
12669
  import { Command as Command28 } from "commander";
13028
12670
  import { execSync as execSync5, spawn as spawn6 } from "child_process";
13029
12671
  import * as fs12 from "fs";
13030
- import * as path14 from "path";
12672
+ import * as path13 from "path";
13031
12673
  import { fileURLToPath } from "url";
13032
12674
  var __filename = fileURLToPath(import.meta.url);
13033
- var __dirname = path14.dirname(__filename);
12675
+ var __dirname = path13.dirname(__filename);
13034
12676
  var PACKAGE_NAME = "shiva-code";
13035
12677
  function getCurrentVersion() {
13036
12678
  try {
13037
- const packageJsonPath = path14.resolve(__dirname, "../../package.json");
12679
+ const packageJsonPath = path13.resolve(__dirname, "../../package.json");
13038
12680
  if (fs12.existsSync(packageJsonPath)) {
13039
12681
  const packageJson = JSON.parse(fs12.readFileSync(packageJsonPath, "utf-8"));
13040
12682
  return packageJson.version || "0.0.0";
@@ -13179,8 +12821,8 @@ var selfUpdateCommand = new Command28("self-update").description('Alias f\xFCr "
13179
12821
 
13180
12822
  // src/commands/system/telemetry.ts
13181
12823
  import { Command as Command29 } from "commander";
13182
- import Conf5 from "conf";
13183
- var telemetryConfig = new Conf5({
12824
+ import Conf4 from "conf";
12825
+ var telemetryConfig = new Conf4({
13184
12826
  projectName: "shiva-code",
13185
12827
  projectSuffix: "",
13186
12828
  configName: "telemetry",
@@ -13434,9 +13076,9 @@ complete -F _shiva_completions shiva
13434
13076
  }
13435
13077
  async function installBashCompletion() {
13436
13078
  const fs15 = await import("fs");
13437
- const os8 = await import("os");
13438
- const path16 = await import("path");
13439
- const bashrcPath = path16.join(os8.homedir(), ".bashrc");
13079
+ const os7 = await import("os");
13080
+ const path15 = await import("path");
13081
+ const bashrcPath = path15.join(os7.homedir(), ".bashrc");
13440
13082
  const completionScript = generateBashCompletion();
13441
13083
  const marker = "# SHIVA Code Bash Completion";
13442
13084
  try {
@@ -13577,9 +13219,9 @@ compdef _shiva shiva
13577
13219
  }
13578
13220
  async function installZshCompletion() {
13579
13221
  const fs15 = await import("fs");
13580
- const os8 = await import("os");
13581
- const path16 = await import("path");
13582
- const zshrcPath = path16.join(os8.homedir(), ".zshrc");
13222
+ const os7 = await import("os");
13223
+ const path15 = await import("path");
13224
+ const zshrcPath = path15.join(os7.homedir(), ".zshrc");
13583
13225
  const completionScript = generateZshCompletion();
13584
13226
  const marker = "# SHIVA Code Zsh Completion";
13585
13227
  try {
@@ -13682,10 +13324,10 @@ complete -c shiva -n "__fish_seen_subcommand_from stats" -l json -d "JSON Output
13682
13324
  }
13683
13325
  async function installFishCompletion() {
13684
13326
  const fs15 = await import("fs");
13685
- const os8 = await import("os");
13686
- const path16 = await import("path");
13687
- const fishCompletionsDir = path16.join(os8.homedir(), ".config", "fish", "completions");
13688
- const fishCompletionPath = path16.join(fishCompletionsDir, "shiva.fish");
13327
+ const os7 = await import("os");
13328
+ const path15 = await import("path");
13329
+ const fishCompletionsDir = path15.join(os7.homedir(), ".config", "fish", "completions");
13330
+ const fishCompletionPath = path15.join(fishCompletionsDir, "shiva.fish");
13689
13331
  const completionScript = generateFishCompletion();
13690
13332
  try {
13691
13333
  if (!fs15.existsSync(fishCompletionsDir)) {
@@ -14093,8 +13735,8 @@ dockerCommand.action(() => {
14093
13735
  // src/commands/advanced/workflow.ts
14094
13736
  import { Command as Command33 } from "commander";
14095
13737
  import * as fs13 from "fs";
14096
- import * as path15 from "path";
14097
- import * as os7 from "os";
13738
+ import * as path14 from "path";
13739
+ import * as os6 from "os";
14098
13740
  import ora20 from "ora";
14099
13741
  import inquirer12 from "inquirer";
14100
13742
  var builtInWorkflows = {
@@ -14253,7 +13895,7 @@ workflowCommand.command("delete").alias("rm").description("Workflow l\xF6schen")
14253
13895
  log.success(`Workflow "${name}" gel\xF6scht`);
14254
13896
  });
14255
13897
  function getWorkflowsPath() {
14256
- return path15.join(os7.homedir(), ".shiva", "workflows.json");
13898
+ return path14.join(os6.homedir(), ".shiva", "workflows.json");
14257
13899
  }
14258
13900
  function loadCustomWorkflows() {
14259
13901
  const filepath = getWorkflowsPath();
@@ -14269,7 +13911,7 @@ function loadCustomWorkflows() {
14269
13911
  }
14270
13912
  function saveCustomWorkflow(name, workflow) {
14271
13913
  const filepath = getWorkflowsPath();
14272
- const dir = path15.dirname(filepath);
13914
+ const dir = path14.dirname(filepath);
14273
13915
  if (!fs13.existsSync(dir)) {
14274
13916
  fs13.mkdirSync(dir, { recursive: true });
14275
13917
  }
@@ -14372,9 +14014,9 @@ async function executeStep(step) {
14372
14014
  // src/commands/advanced/hook.ts
14373
14015
  import { Command as Command34 } from "commander";
14374
14016
  import { existsSync as existsSync21, readFileSync as readFileSync10, writeFileSync as writeFileSync10, mkdirSync as mkdirSync6 } from "fs";
14375
- import { homedir as homedir8 } from "os";
14376
- import { join as join13 } from "path";
14377
- var CLAUDE_SETTINGS_PATH = join13(homedir8(), ".claude", "settings.json");
14017
+ import { homedir as homedir7 } from "os";
14018
+ import { join as join12 } from "path";
14019
+ var CLAUDE_SETTINGS_PATH = join12(homedir7(), ".claude", "settings.json");
14378
14020
  function getClaudeSettings() {
14379
14021
  if (!existsSync21(CLAUDE_SETTINGS_PATH)) {
14380
14022
  return {};
@@ -14387,7 +14029,7 @@ function getClaudeSettings() {
14387
14029
  }
14388
14030
  }
14389
14031
  function saveClaudeSettings(settings) {
14390
- const dir = join13(homedir8(), ".claude");
14032
+ const dir = join12(homedir7(), ".claude");
14391
14033
  if (!existsSync21(dir)) {
14392
14034
  mkdirSync6(dir, { recursive: true });
14393
14035
  }
@@ -14408,7 +14050,7 @@ function removeShivaHooks(eventHooks) {
14408
14050
  var hookCommand = new Command34("hook").description("Claude Code Hook Integration verwalten");
14409
14051
  hookCommand.command("install").description("SHIVA Hooks in Claude Code installieren").option("--github", "GitHub Context Injection aktivieren").option("--sync", "Cloud Sync Hooks aktivieren (Standard)").option("--scan", "Package Security Scanning aktivieren").option("--all", "Alle Hooks aktivieren").action((options) => {
14410
14052
  log.brand();
14411
- const claudePath = join13(homedir8(), ".claude");
14053
+ const claudePath = join12(homedir7(), ".claude");
14412
14054
  if (!existsSync21(claudePath)) {
14413
14055
  log.error("Claude Code nicht gefunden");
14414
14056
  log.newline();
@@ -14646,8 +14288,8 @@ hookCommand.command("inject-context").description("GitHub Context in Session inj
14646
14288
  return;
14647
14289
  }
14648
14290
  if (hasShivaDir(projectPath)) {
14649
- const config2 = getProjectConfig(projectPath);
14650
- if (!config2.autoInjectContext) {
14291
+ const config = getProjectConfig(projectPath);
14292
+ if (!config.autoInjectContext) {
14651
14293
  console.log(JSON.stringify({}));
14652
14294
  return;
14653
14295
  }
@@ -14718,8 +14360,8 @@ hookCommand.command("branch-switch").description("Branch-Wechsel behandeln (f\xF
14718
14360
  }
14719
14361
  });
14720
14362
  hookCommand.command("scan-command").description("Scanne Bash-Befehle auf Package-Installationen (f\xFCr Hook)").argument("<command>", "Der zu scannende Befehl").action(async (command) => {
14721
- const config2 = packageScanner.getConfig();
14722
- if (!config2.enabled) {
14363
+ const config = packageScanner.getConfig();
14364
+ if (!config.enabled) {
14723
14365
  console.log(JSON.stringify({ hookSpecificOutput: null }));
14724
14366
  return;
14725
14367
  }
@@ -14739,6 +14381,85 @@ hookCommand.command("scan-command").description("Scanne Bash-Befehle auf Package
14739
14381
  console.log(JSON.stringify({ hookSpecificOutput: null }));
14740
14382
  }
14741
14383
  });
14384
+ hookCommand.command("push").description("Hooks in Cloud sichern").action(async () => {
14385
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
14386
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
14387
+ if (!isAuthenticated2()) {
14388
+ log.error("Nicht angemeldet");
14389
+ log.info("Anmelden mit: shiva login");
14390
+ return;
14391
+ }
14392
+ const settings = getClaudeSettings();
14393
+ if (!settings.hooks) {
14394
+ log.warn("Keine lokalen Hooks konfiguriert");
14395
+ return;
14396
+ }
14397
+ try {
14398
+ await api2.updateHooks(settings.hooks);
14399
+ log.success("Hooks in Cloud gesichert");
14400
+ } catch (error) {
14401
+ log.error(error instanceof Error ? error.message : "Fehler beim Sichern");
14402
+ }
14403
+ });
14404
+ hookCommand.command("pull").description("Hooks aus Cloud laden").option("-f, --force", "Lokale Hooks \xFCberschreiben").action(async (options) => {
14405
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
14406
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
14407
+ if (!isAuthenticated2()) {
14408
+ log.error("Nicht angemeldet");
14409
+ log.info("Anmelden mit: shiva login");
14410
+ return;
14411
+ }
14412
+ const settings = getClaudeSettings();
14413
+ if (settings.hooks && !options.force) {
14414
+ log.warn("Lokale Hooks existieren bereits");
14415
+ log.info("Mit --force \xFCberschreiben");
14416
+ return;
14417
+ }
14418
+ try {
14419
+ const result = await api2.getHooks();
14420
+ if (!result.hooks || Object.keys(result.hooks).length === 0) {
14421
+ log.info("Keine Hooks in Cloud gefunden");
14422
+ return;
14423
+ }
14424
+ settings.hooks = result.hooks;
14425
+ saveClaudeSettings(settings);
14426
+ log.success("Hooks aus Cloud geladen");
14427
+ log.newline();
14428
+ log.info("Aktive Hooks:");
14429
+ for (const [event, hooks] of Object.entries(result.hooks)) {
14430
+ log.tree.item(`${event}: ${Array.isArray(hooks) ? hooks.length : 1} Hook(s)`);
14431
+ }
14432
+ } catch (error) {
14433
+ log.error(error instanceof Error ? error.message : "Fehler beim Laden");
14434
+ }
14435
+ });
14436
+ hookCommand.command("sync").description("Hooks mit Cloud synchronisieren").action(async () => {
14437
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
14438
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
14439
+ if (!isAuthenticated2()) {
14440
+ log.error("Nicht angemeldet");
14441
+ log.info("Anmelden mit: shiva login");
14442
+ return;
14443
+ }
14444
+ const settings = getClaudeSettings();
14445
+ try {
14446
+ if (settings.hooks) {
14447
+ await api2.updateHooks(settings.hooks);
14448
+ log.success("Lokale Hooks \u2192 Cloud");
14449
+ }
14450
+ const result = await api2.getHooks();
14451
+ if (result.hooks && Object.keys(result.hooks).length > 0) {
14452
+ const merged = { ...result.hooks, ...settings.hooks };
14453
+ settings.hooks = merged;
14454
+ saveClaudeSettings(settings);
14455
+ log.success("Cloud Hooks \u2192 Lokal (merged)");
14456
+ }
14457
+ log.newline();
14458
+ log.success("Hooks synchronisiert");
14459
+ } catch (error) {
14460
+ log.error(error instanceof Error ? error.message : "Fehler beim Synchronisieren");
14461
+ }
14462
+ });
14742
14463
 
14743
14464
  // src/commands/advanced/package.ts
14744
14465
  import { Command as Command35 } from "commander";
@@ -14889,6 +14610,186 @@ packageCommand.command("start <name>").description("Alle Projekte eines Packages
14889
14610
  log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
14890
14611
  }
14891
14612
  });
14613
+ packageCommand.command("push").description("Packages in Cloud sichern").option("-n, --name <name>", "Nur ein bestimmtes Package").action(async (options) => {
14614
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
14615
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
14616
+ if (!isAuthenticated2()) {
14617
+ log.error("Nicht angemeldet");
14618
+ log.info("Anmelden mit: shiva login");
14619
+ return;
14620
+ }
14621
+ let packages = getAllPackages();
14622
+ if (options.name) {
14623
+ const found = getPackage(options.name);
14624
+ if (found) {
14625
+ packages = [found];
14626
+ } else {
14627
+ log.error(`Package nicht gefunden: ${options.name}`);
14628
+ return;
14629
+ }
14630
+ }
14631
+ if (packages.length === 0) {
14632
+ log.warn("Keine Packages zum Synchronisieren gefunden");
14633
+ return;
14634
+ }
14635
+ const spinner = ora21("Synchronisiere Packages...").start();
14636
+ let syncedCount = 0;
14637
+ let errorCount = 0;
14638
+ for (const pkg of packages) {
14639
+ try {
14640
+ await api2.syncPackage({
14641
+ name: pkg.name,
14642
+ description: pkg.description,
14643
+ projects: pkg.projects,
14644
+ launchOrder: pkg.launchOrder
14645
+ });
14646
+ syncedCount++;
14647
+ } catch {
14648
+ errorCount++;
14649
+ }
14650
+ }
14651
+ spinner.stop();
14652
+ if (syncedCount > 0) {
14653
+ log.success(`${syncedCount} Packages in Cloud gesichert`);
14654
+ }
14655
+ if (errorCount > 0) {
14656
+ log.warn(`${errorCount} Packages konnten nicht gesichert werden`);
14657
+ }
14658
+ });
14659
+ packageCommand.command("pull").description("Packages aus Cloud laden").option("-f, --force", "Lokale Packages \xFCberschreiben").option("--json", "JSON Output").action(async (options) => {
14660
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
14661
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
14662
+ if (!isAuthenticated2()) {
14663
+ log.error("Nicht angemeldet");
14664
+ log.info("Anmelden mit: shiva login");
14665
+ return;
14666
+ }
14667
+ const spinner = ora21("Lade Packages aus Cloud...").start();
14668
+ try {
14669
+ const cloudPackages = await api2.getPackages();
14670
+ spinner.stop();
14671
+ if (options.json) {
14672
+ console.log(JSON.stringify(cloudPackages, null, 2));
14673
+ return;
14674
+ }
14675
+ if (cloudPackages.length === 0) {
14676
+ log.info("Keine Packages in Cloud gefunden");
14677
+ log.dim("Hochladen mit: shiva package push");
14678
+ return;
14679
+ }
14680
+ log.success(`${cloudPackages.length} Packages in Cloud gefunden`);
14681
+ log.newline();
14682
+ const localPackages = getAllPackages();
14683
+ let importedCount = 0;
14684
+ let skippedCount = 0;
14685
+ for (const cloudPkg of cloudPackages) {
14686
+ const localPkg = localPackages.find((p) => p.name.toLowerCase() === cloudPkg.name.toLowerCase());
14687
+ if (localPkg && !options.force) {
14688
+ log.dim(` \u23ED ${cloudPkg.name} (lokal vorhanden, --force zum \xDCberschreiben)`);
14689
+ skippedCount++;
14690
+ continue;
14691
+ }
14692
+ try {
14693
+ if (localPkg) {
14694
+ deletePackage(localPkg.name);
14695
+ }
14696
+ createPackage(cloudPkg.name, cloudPkg.description, cloudPkg.launchOrder);
14697
+ for (const projectPath of cloudPkg.projects) {
14698
+ try {
14699
+ addProjectToPackage(cloudPkg.name, projectPath);
14700
+ } catch {
14701
+ }
14702
+ }
14703
+ log.success(` \u2713 ${cloudPkg.name} importiert`);
14704
+ importedCount++;
14705
+ } catch (error) {
14706
+ log.warn(` \u2717 ${cloudPkg.name}: ${error instanceof Error ? error.message : "Fehler"}`);
14707
+ }
14708
+ }
14709
+ log.newline();
14710
+ if (importedCount > 0) {
14711
+ log.success(`${importedCount} Packages importiert`);
14712
+ }
14713
+ if (skippedCount > 0) {
14714
+ log.dim(`${skippedCount} \xFCbersprungen (bereits lokal vorhanden)`);
14715
+ }
14716
+ } catch (error) {
14717
+ spinner.stop();
14718
+ log.error(error instanceof Error ? error.message : "Fehler beim Laden");
14719
+ }
14720
+ });
14721
+ packageCommand.command("sync").description("Packages mit Cloud synchronisieren").action(async () => {
14722
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
14723
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
14724
+ if (!isAuthenticated2()) {
14725
+ log.error("Nicht angemeldet");
14726
+ log.info("Anmelden mit: shiva login");
14727
+ return;
14728
+ }
14729
+ const spinner = ora21("Synchronisiere Packages...").start();
14730
+ const localPackages = getAllPackages();
14731
+ let pushedCount = 0;
14732
+ for (const pkg of localPackages) {
14733
+ try {
14734
+ await api2.syncPackage({
14735
+ name: pkg.name,
14736
+ description: pkg.description,
14737
+ projects: pkg.projects,
14738
+ launchOrder: pkg.launchOrder
14739
+ });
14740
+ pushedCount++;
14741
+ } catch {
14742
+ }
14743
+ }
14744
+ let pulledCount = 0;
14745
+ try {
14746
+ const cloudPackages = await api2.getPackages();
14747
+ for (const cloudPkg of cloudPackages) {
14748
+ const localPkg = localPackages.find((p) => p.name.toLowerCase() === cloudPkg.name.toLowerCase());
14749
+ if (!localPkg) {
14750
+ try {
14751
+ createPackage(cloudPkg.name, cloudPkg.description, cloudPkg.launchOrder);
14752
+ for (const projectPath of cloudPkg.projects) {
14753
+ try {
14754
+ addProjectToPackage(cloudPkg.name, projectPath);
14755
+ } catch {
14756
+ }
14757
+ }
14758
+ pulledCount++;
14759
+ } catch {
14760
+ }
14761
+ }
14762
+ }
14763
+ } catch {
14764
+ }
14765
+ spinner.stop();
14766
+ log.success("Packages synchronisiert");
14767
+ log.newline();
14768
+ log.tree.item(`${pushedCount} lokale Packages \u2192 Cloud`);
14769
+ if (pulledCount > 0) {
14770
+ log.tree.item(`${pulledCount} neue Packages \u2190 Cloud`);
14771
+ }
14772
+ log.tree.item(`${localPackages.length + pulledCount} Packages total`);
14773
+ });
14774
+ packageCommand.command("cloud-delete <name>").description("Package aus Cloud l\xF6schen").action(async (name) => {
14775
+ const { api: api2 } = await import("./client-2L7NWNCZ.js");
14776
+ const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
14777
+ if (!isAuthenticated2()) {
14778
+ log.error("Nicht angemeldet");
14779
+ log.info("Anmelden mit: shiva login");
14780
+ return;
14781
+ }
14782
+ try {
14783
+ const result = await api2.deleteCloudPackage(name);
14784
+ if (result.success) {
14785
+ log.success(`Package "${name}" aus Cloud gel\xF6scht`);
14786
+ } else {
14787
+ log.error(result.message || "Fehler beim L\xF6schen");
14788
+ }
14789
+ } catch (error) {
14790
+ log.error(error instanceof Error ? error.message : "Fehler beim L\xF6schen");
14791
+ }
14792
+ });
14892
14793
  function listPackages() {
14893
14794
  const packages = getAllPackages();
14894
14795
  const stats = getPackageStats();
@@ -14929,7 +14830,7 @@ function listPackages() {
14929
14830
 
14930
14831
  // src/index.ts
14931
14832
  var program = new Command36();
14932
- program.name("shiva").description("SHIVA Code - Control Station for Claude Code").version("0.5.2");
14833
+ program.name("shiva").description("SHIVA Code - Control Station for Claude Code").version("0.5.4");
14933
14834
  program.addCommand(loginCommand);
14934
14835
  program.addCommand(logoutCommand);
14935
14836
  program.addCommand(sessionsCommand);