shiva-code 0.7.3 → 0.7.5

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
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  hookCommand,
4
4
  packageScanner
5
- } from "./chunk-UAP4ZKEJ.js";
5
+ } from "./chunk-RQ75X32M.js";
6
6
  import {
7
7
  copyToClipboard,
8
8
  getClipboardInstallInstructions,
@@ -17,7 +17,7 @@ import {
17
17
  getPackageLaunchConfig,
18
18
  getPackageStats,
19
19
  removeProjectFromPackage
20
- } from "./chunk-LBTCSQAX.js";
20
+ } from "./chunk-KUA6TMQJ.js";
21
21
  import {
22
22
  deviceTrustService,
23
23
  displayBackupCodes,
@@ -26,14 +26,15 @@ import {
26
26
  loginCommand,
27
27
  logout,
28
28
  twoFactorService
29
- } from "./chunk-UZKDLLPA.js";
29
+ } from "./chunk-KW3LP3K3.js";
30
30
  import {
31
31
  colors,
32
32
  log
33
33
  } from "./chunk-Z6NXFC4Q.js";
34
34
  import {
35
- api
36
- } from "./chunk-QQZRCJZK.js";
35
+ api,
36
+ enableDebug
37
+ } from "./chunk-J5IS642F.js";
37
38
  import {
38
39
  CONFIG_PATH,
39
40
  clearAuth,
@@ -42,6 +43,7 @@ import {
42
43
  getClaudeLaunchArgs,
43
44
  getClaudeSkipPermissions,
44
45
  getConfig,
46
+ getConfigPath,
45
47
  getDefaultTerminal,
46
48
  getExtendedConfig,
47
49
  getToken,
@@ -93,6 +95,7 @@ import {
93
95
  updateTimeControl
94
96
  } from "./chunk-PMA6MGQW.js";
95
97
  import {
98
+ containsShellMetacharacters,
96
99
  encodeProjectPath,
97
100
  findProject,
98
101
  findProjectForCurrentDir,
@@ -114,7 +117,7 @@ import {
114
117
  maskSecret,
115
118
  sanitizeForLog,
116
119
  saveRecoveredContext
117
- } from "./chunk-H5OFO4VS.js";
120
+ } from "./chunk-W3DKHCXB.js";
118
121
  import {
119
122
  cache
120
123
  } from "./chunk-HIQO2DBA.js";
@@ -123,7 +126,7 @@ import {
123
126
  } from "./chunk-3RG5ZIWI.js";
124
127
 
125
128
  // src/index.ts
126
- import { Command as Command38 } from "commander";
129
+ import { Command as Command39 } from "commander";
127
130
  import * as readline from "readline";
128
131
 
129
132
  // src/services/onboarding/welcome.ts
@@ -261,7 +264,7 @@ async function promptLogin() {
261
264
  log.newline();
262
265
  log.info("\xD6ffne Browser f\xFCr Anmeldung...");
263
266
  log.newline();
264
- const { loginCommand: loginCommand2 } = await import("./login-ZEKMSKVH.js");
267
+ const { loginCommand: loginCommand2 } = await import("./login-Y6EJABSP.js");
265
268
  await loginCommand2.parseAsync(["login"], { from: "user" });
266
269
  return isAuthenticated();
267
270
  }
@@ -333,7 +336,7 @@ async function promptHooks() {
333
336
  if (installHooks) {
334
337
  log.newline();
335
338
  log.info("Installiere Hooks...");
336
- const { hookCommand: hookCommand2 } = await import("./hook-SZAVQGEA.js");
339
+ const { hookCommand: hookCommand2 } = await import("./hook-GIK5RFRC.js");
337
340
  await hookCommand2.parseAsync(["hook", "install", "--all"], { from: "user" });
338
341
  onboardingStore.set("hooksInstalled", true);
339
342
  return true;
@@ -388,6 +391,86 @@ function getStartupStatus() {
388
391
  };
389
392
  }
390
393
 
394
+ // src/utils/fuzzy.ts
395
+ function levenshtein(a, b) {
396
+ const matrix = [];
397
+ for (let i = 0; i <= b.length; i++) {
398
+ matrix[i] = [i];
399
+ }
400
+ for (let j = 0; j <= a.length; j++) {
401
+ matrix[0][j] = j;
402
+ }
403
+ for (let i = 1; i <= b.length; i++) {
404
+ for (let j = 1; j <= a.length; j++) {
405
+ if (b[i - 1] === a[j - 1]) {
406
+ matrix[i][j] = matrix[i - 1][j - 1];
407
+ } else {
408
+ matrix[i][j] = Math.min(
409
+ matrix[i - 1][j - 1] + 1,
410
+ // substitution
411
+ matrix[i][j - 1] + 1,
412
+ // insertion
413
+ matrix[i - 1][j] + 1
414
+ // deletion
415
+ );
416
+ }
417
+ }
418
+ }
419
+ return matrix[b.length][a.length];
420
+ }
421
+ function findSimilarCommands(input, commands, maxDistance = 3) {
422
+ return commands.map((cmd) => ({
423
+ cmd,
424
+ distance: levenshtein(input.toLowerCase(), cmd.toLowerCase())
425
+ })).filter(({ distance }) => distance <= maxDistance).sort((a, b) => a.distance - b.distance).slice(0, 3).map(({ cmd }) => cmd);
426
+ }
427
+
428
+ // src/commands/aliases.ts
429
+ var COMMAND_ALIASES = {
430
+ // Session management
431
+ sessions: ["ss", "sess"],
432
+ resume: ["res"],
433
+ restore: ["rst"],
434
+ start: ["st"],
435
+ // Memory commands
436
+ remember: ["rem", "r"],
437
+ search: ["s", "find", "f"],
438
+ forget: ["fg"],
439
+ // Project commands
440
+ init: ["i"],
441
+ sync: ["sy"],
442
+ status: ["stat"],
443
+ projects: ["proj", "p"],
444
+ config: ["cfg", "conf"],
445
+ // GitHub commands
446
+ github: ["gh"],
447
+ issues: ["iss"],
448
+ prs: ["pr"],
449
+ // Security
450
+ secrets: ["sec"],
451
+ scan: ["sc"],
452
+ // Advanced
453
+ package: ["pkg"],
454
+ docker: ["dk"],
455
+ sandbox: ["sb"],
456
+ workflow: ["wf"],
457
+ hook: ["hk"],
458
+ // System
459
+ doctor: ["doc", "dr"],
460
+ stats: ["analytics"],
461
+ upgrade: ["up"],
462
+ user: ["u"]
463
+ };
464
+ var aliasToCommand = /* @__PURE__ */ new Map();
465
+ for (const [command, aliases] of Object.entries(COMMAND_ALIASES)) {
466
+ for (const alias of aliases) {
467
+ aliasToCommand.set(alias, command);
468
+ }
469
+ }
470
+ function getCommandFromAlias(alias) {
471
+ return aliasToCommand.get(alias.toLowerCase()) || null;
472
+ }
473
+
391
474
  // src/commands/auth/logout.ts
392
475
  import { Command } from "commander";
393
476
  var logoutCommand = new Command("logout").description("Abmelden").action(() => {
@@ -1185,14 +1268,49 @@ import { resolve as resolve4 } from "path";
1185
1268
  import ora2 from "ora";
1186
1269
 
1187
1270
  // src/utils/errors.ts
1271
+ var ERROR_SUGGESTIONS = {
1272
+ // Network errors
1273
+ ENOTFOUND: "Netzwerkfehler. Pr\xFCfe deine Internetverbindung.",
1274
+ ECONNREFUSED: "Server nicht erreichbar. Versuche es sp\xE4ter erneut.",
1275
+ ETIMEDOUT: "Anfrage Timeout. Server antwortet nicht.",
1276
+ ECONNRESET: "Verbindung abgebrochen. Versuche es erneut.",
1277
+ CERT_HAS_EXPIRED: "SSL-Zertifikat abgelaufen. Pr\xFCfe die Systemzeit.",
1278
+ // HTTP errors
1279
+ "401": "Nicht autorisiert. Versuche: shiva login",
1280
+ "403": "Zugriff verweigert. Pr\xFCfe deine Berechtigungen.",
1281
+ "404": "Nicht gefunden. Pr\xFCfe ob die Resource existiert.",
1282
+ "429": "Rate Limit erreicht. Warte einen Moment.",
1283
+ "500": "Server Fehler. Versuche es sp\xE4ter erneut.",
1284
+ "502": "Bad Gateway. Server tempor\xE4r nicht erreichbar.",
1285
+ "503": "Service nicht verf\xFCgbar. Wartungsarbeiten m\xF6glich.",
1286
+ "504": "Gateway Timeout. Server \xFCberlastet.",
1287
+ // File system errors
1288
+ ENOENT: "Datei oder Verzeichnis nicht gefunden.",
1289
+ EACCES: "Keine Berechtigung. Pr\xFCfe die Dateirechte.",
1290
+ EPERM: "Operation nicht erlaubt.",
1291
+ EEXIST: "Datei oder Verzeichnis existiert bereits.",
1292
+ ENOSPC: "Kein Speicherplatz mehr verf\xFCgbar.",
1293
+ EMFILE: "Zu viele offene Dateien. Schlie\xDFe andere Programme."
1294
+ };
1295
+ function getErrorSuggestion(error) {
1296
+ const errorStr = error instanceof Error ? error.message : error;
1297
+ for (const [key, suggestion] of Object.entries(ERROR_SUGGESTIONS)) {
1298
+ if (errorStr.includes(key)) {
1299
+ return suggestion;
1300
+ }
1301
+ }
1302
+ return null;
1303
+ }
1188
1304
  var ShivaError = class _ShivaError extends Error {
1189
1305
  code;
1190
1306
  suggestion;
1191
- constructor(code, message, suggestion) {
1307
+ context;
1308
+ constructor(code, message, suggestion, context) {
1192
1309
  super(message);
1193
1310
  this.name = "ShivaError";
1194
1311
  this.code = code;
1195
- this.suggestion = suggestion;
1312
+ this.suggestion = suggestion || getErrorSuggestion(message) || void 0;
1313
+ this.context = context;
1196
1314
  Object.setPrototypeOf(this, _ShivaError.prototype);
1197
1315
  }
1198
1316
  /**
@@ -1206,6 +1324,18 @@ var ShivaError = class _ShivaError extends Error {
1206
1324
  }
1207
1325
  return result;
1208
1326
  }
1327
+ /**
1328
+ * Convert to a user-friendly message
1329
+ */
1330
+ toUserMessage() {
1331
+ let msg = this.message;
1332
+ if (this.suggestion) {
1333
+ msg += `
1334
+
1335
+ ${this.suggestion}`;
1336
+ }
1337
+ return msg;
1338
+ }
1209
1339
  };
1210
1340
  var Errors = {
1211
1341
  // Authentication errors
@@ -2116,13 +2246,13 @@ claudeConfig.command("terminal").description("Standard-Terminal f\xFCr Multi-Pro
2116
2246
  setDefaultTerminal(type2);
2117
2247
  log.success(`Default Terminal: ${type2}`);
2118
2248
  });
2119
- claudeConfig.command("args").description("Custom Claude Argumente verwalten").argument("[args...]", "Argumente zum Hinzuf\xFCgen").option("--clear", "Alle Custom Args entfernen").option("--list", "Aktuelle Args anzeigen").action((args, options) => {
2249
+ claudeConfig.command("args").description("Custom Claude Argumente verwalten").argument("[args...]", "Argumente zum Hinzuf\xFCgen").option("--clear", "Alle Custom Args entfernen").option("--list", "Aktuelle Args anzeigen").action((args2, options) => {
2120
2250
  if (options.clear) {
2121
2251
  setClaudeArgs([]);
2122
2252
  log.success("Custom Args entfernt");
2123
2253
  return;
2124
2254
  }
2125
- if (options.list || !args || args.length === 0) {
2255
+ if (options.list || !args2 || args2.length === 0) {
2126
2256
  const current2 = getClaudeArgs();
2127
2257
  if (current2.length === 0) {
2128
2258
  log.dim("Keine Custom Args gesetzt");
@@ -2135,7 +2265,7 @@ claudeConfig.command("args").description("Custom Claude Argumente verwalten").ar
2135
2265
  return;
2136
2266
  }
2137
2267
  const current = getClaudeArgs();
2138
- const newArgs = [...current, ...args];
2268
+ const newArgs = [...current, ...args2];
2139
2269
  setClaudeArgs(newArgs);
2140
2270
  log.success("Args hinzugef\xFCgt");
2141
2271
  log.keyValue("Custom Args", newArgs.join(" "));
@@ -3620,30 +3750,30 @@ var DockerService = class {
3620
3750
  */
3621
3751
  async createContainer(config) {
3622
3752
  const cmd = this.getCommand();
3623
- const args = ["create"];
3753
+ const args2 = ["create"];
3624
3754
  if (config.name) {
3625
3755
  if (!this.isValidContainerNameInternal(config.name)) {
3626
3756
  throw new Error(`Invalid container name: ${sanitizeForLog(config.name)}`);
3627
3757
  }
3628
- args.push("--name", config.name);
3758
+ args2.push("--name", config.name);
3629
3759
  }
3630
3760
  if (!isValidProjectPath(config.workdir)) {
3631
3761
  throw new Error(`Invalid workdir: ${sanitizeForLog(config.workdir)}`);
3632
3762
  }
3633
- args.push("--workdir", config.workdir);
3763
+ args2.push("--workdir", config.workdir);
3634
3764
  for (const mount of config.mounts) {
3635
3765
  if (!isValidProjectPath(mount.host)) {
3636
3766
  log.warn(`Skipping invalid mount path: ${sanitizeForLog(mount.host)}`);
3637
3767
  continue;
3638
3768
  }
3639
- args.push("-v", `${mount.host}:${mount.container}:${mount.mode}`);
3769
+ args2.push("-v", `${mount.host}:${mount.container}:${mount.mode}`);
3640
3770
  }
3641
3771
  for (const [key, value] of Object.entries(config.env)) {
3642
3772
  if (!/^[A-Z_][A-Z0-9_]*$/i.test(key)) {
3643
3773
  log.warn(`Skipping invalid env var name: ${sanitizeForLog(key)}`);
3644
3774
  continue;
3645
3775
  }
3646
- args.push("-e", `${key}=${value}`);
3776
+ args2.push("-e", `${key}=${value}`);
3647
3777
  }
3648
3778
  if (config.ports) {
3649
3779
  for (const [host, container] of Object.entries(config.ports)) {
@@ -3651,21 +3781,21 @@ var DockerService = class {
3651
3781
  log.warn(`Skipping invalid port mapping: ${host}:${container}`);
3652
3782
  continue;
3653
3783
  }
3654
- args.push("-p", `${host}:${container}`);
3784
+ args2.push("-p", `${host}:${container}`);
3655
3785
  }
3656
3786
  }
3657
3787
  if (config.interactive) {
3658
- args.push("-it");
3788
+ args2.push("-it");
3659
3789
  }
3660
3790
  if (config.autoRemove) {
3661
- args.push("--rm");
3791
+ args2.push("--rm");
3662
3792
  }
3663
3793
  if (!this.isValidImage(config.image)) {
3664
3794
  throw new Error(`Invalid image: ${sanitizeForLog(config.image)}`);
3665
3795
  }
3666
- args.push(config.image);
3796
+ args2.push(config.image);
3667
3797
  try {
3668
- const result = spawnSync(cmd, args, {
3798
+ const result = spawnSync(cmd, args2, {
3669
3799
  encoding: "utf8",
3670
3800
  stdio: ["pipe", "pipe", "pipe"]
3671
3801
  });
@@ -3746,13 +3876,13 @@ var DockerService = class {
3746
3876
  return "";
3747
3877
  }
3748
3878
  const cmd = this.getCommand();
3749
- const args = ["logs"];
3879
+ const args2 = ["logs"];
3750
3880
  if (tail && tail > 0) {
3751
- args.push("--tail", String(tail));
3881
+ args2.push("--tail", String(tail));
3752
3882
  }
3753
- args.push(containerId);
3883
+ args2.push(containerId);
3754
3884
  try {
3755
- const result = spawnSync(cmd, args, {
3885
+ const result = spawnSync(cmd, args2, {
3756
3886
  encoding: "utf8",
3757
3887
  stdio: ["pipe", "pipe", "pipe"]
3758
3888
  });
@@ -3796,7 +3926,7 @@ var DockerService = class {
3796
3926
  secrets = await api.getSecretsForInjection();
3797
3927
  } catch {
3798
3928
  }
3799
- const args = [
3929
+ const args2 = [
3800
3930
  "run",
3801
3931
  "-it",
3802
3932
  "--rm",
@@ -3816,22 +3946,22 @@ var DockerService = class {
3816
3946
  ];
3817
3947
  for (const [host, container] of Object.entries(settings.volumeMounts || {})) {
3818
3948
  if (isValidProjectPath(host)) {
3819
- args.push("-v", `${host}:${container}:rw`);
3949
+ args2.push("-v", `${host}:${container}:rw`);
3820
3950
  }
3821
3951
  }
3822
3952
  for (const [key, value] of Object.entries(settings.environment || {})) {
3823
3953
  if (/^[A-Z_][A-Z0-9_]*$/i.test(key)) {
3824
- args.push("-e", `${key}=${value}`);
3954
+ args2.push("-e", `${key}=${value}`);
3825
3955
  }
3826
3956
  }
3827
3957
  for (const [key, value] of Object.entries(secrets)) {
3828
3958
  if (/^[A-Z_][A-Z0-9_]*$/i.test(key)) {
3829
- args.push("-e", `${key}=${value}`);
3959
+ args2.push("-e", `${key}=${value}`);
3830
3960
  }
3831
3961
  }
3832
- args.push(image);
3833
- args.push("claude", ...claudeArgs);
3834
- const dockerProcess = spawn(cmd, args, {
3962
+ args2.push(image);
3963
+ args2.push("claude", ...claudeArgs);
3964
+ const dockerProcess = spawn(cmd, args2, {
3835
3965
  stdio: "inherit"
3836
3966
  });
3837
3967
  return dockerProcess;
@@ -4110,7 +4240,7 @@ var DockerService = class {
4110
4240
  secrets = await api.getSecretsForInjection();
4111
4241
  } catch {
4112
4242
  }
4113
- const args = [
4243
+ const args2 = [
4114
4244
  "run",
4115
4245
  "-it",
4116
4246
  "--rm",
@@ -4120,42 +4250,42 @@ var DockerService = class {
4120
4250
  "/workspace"
4121
4251
  ];
4122
4252
  if (effectiveConfig.network === "none") {
4123
- args.push("--network", "none");
4253
+ args2.push("--network", "none");
4124
4254
  } else if (effectiveConfig.network === "host") {
4125
- args.push("--network", "host");
4255
+ args2.push("--network", "host");
4126
4256
  }
4127
4257
  if (effectiveConfig.resources.cpuLimit && /^[\d.]+$/.test(effectiveConfig.resources.cpuLimit)) {
4128
- args.push("--cpus", effectiveConfig.resources.cpuLimit);
4258
+ args2.push("--cpus", effectiveConfig.resources.cpuLimit);
4129
4259
  }
4130
4260
  if (effectiveConfig.resources.memoryLimit && /^[\d]+[kmgKMG]?$/.test(effectiveConfig.resources.memoryLimit)) {
4131
- args.push("--memory", effectiveConfig.resources.memoryLimit);
4261
+ args2.push("--memory", effectiveConfig.resources.memoryLimit);
4132
4262
  }
4133
4263
  for (const opt of effectiveConfig.securityOpts) {
4134
4264
  if (/^[a-z:=_-]+$/i.test(opt)) {
4135
- args.push("--security-opt", opt);
4265
+ args2.push("--security-opt", opt);
4136
4266
  }
4137
4267
  }
4138
- args.push("-v", `${launch.projectPath}:/workspace:rw`);
4139
- args.push("-v", `${path.join(os.homedir(), ".claude")}:/root/.claude:rw`);
4140
- args.push("-v", `${path.join(os.homedir(), ".config", "shiva-code")}:/root/.config/shiva-code:rw`);
4268
+ args2.push("-v", `${launch.projectPath}:/workspace:rw`);
4269
+ args2.push("-v", `${path.join(os.homedir(), ".claude")}:/root/.claude:rw`);
4270
+ args2.push("-v", `${path.join(os.homedir(), ".config", "shiva-code")}:/root/.config/shiva-code:rw`);
4141
4271
  for (const mount of effectiveConfig.mounts) {
4142
4272
  if (isValidProjectPath(mount.host)) {
4143
- args.push("-v", `${mount.host}:${mount.container}:${mount.mode}`);
4273
+ args2.push("-v", `${mount.host}:${mount.container}:${mount.mode}`);
4144
4274
  }
4145
4275
  }
4146
4276
  for (const [key, value] of Object.entries(effectiveConfig.environment)) {
4147
4277
  if (/^[A-Z_][A-Z0-9_]*$/i.test(key)) {
4148
- args.push("-e", `${key}=${value}`);
4278
+ args2.push("-e", `${key}=${value}`);
4149
4279
  }
4150
4280
  }
4151
4281
  for (const [key, value] of Object.entries(secrets)) {
4152
4282
  if (/^[A-Z_][A-Z0-9_]*$/i.test(key)) {
4153
- args.push("-e", `${key}=${value}`);
4283
+ args2.push("-e", `${key}=${value}`);
4154
4284
  }
4155
4285
  }
4156
- args.push(effectiveConfig.image);
4157
- args.push("claude", ...claudeArgs);
4158
- const dockerProcess = spawn(cmd, args, {
4286
+ args2.push(effectiveConfig.image);
4287
+ args2.push("claude", ...claudeArgs);
4288
+ const dockerProcess = spawn(cmd, args2, {
4159
4289
  stdio: "inherit"
4160
4290
  });
4161
4291
  return dockerProcess;
@@ -4224,13 +4354,13 @@ function validateProject(project) {
4224
4354
  return { valid: true };
4225
4355
  }
4226
4356
  function buildClaudeArgs(project) {
4227
- const args = [];
4357
+ const args2 = [];
4228
4358
  if (!project.newSession && project.sessionId) {
4229
- args.push("--resume", project.sessionId);
4359
+ args2.push("--resume", project.sessionId);
4230
4360
  }
4231
4361
  const launchArgs = getClaudeLaunchArgs();
4232
- args.push(...launchArgs);
4233
- return args;
4362
+ args2.push(...launchArgs);
4363
+ return args2;
4234
4364
  }
4235
4365
  function sanitizeProjectName(name) {
4236
4366
  return name.replace(/[^a-zA-Z0-9_.-]/g, "-").substring(0, 50);
@@ -4301,7 +4431,7 @@ async function spawnInTmux(projects, sessionName) {
4301
4431
  }
4302
4432
  }
4303
4433
  async function spawnInGnomeTerminal(projects) {
4304
- const args = [];
4434
+ const args2 = [];
4305
4435
  for (const project of projects) {
4306
4436
  const validation = validateProject(project);
4307
4437
  if (!validation.valid) {
@@ -4311,7 +4441,7 @@ async function spawnInGnomeTerminal(projects) {
4311
4441
  const claudeArgs = buildClaudeArgs(project);
4312
4442
  const safeName = sanitizeProjectName(project.projectName);
4313
4443
  const wrapperScript = `cd ${escapeShellArg(project.projectPath)} && exec claude ${claudeArgs.map(escapeShellArg).join(" ")}`;
4314
- args.push(
4444
+ args2.push(
4315
4445
  "--tab",
4316
4446
  "--title",
4317
4447
  safeName,
@@ -4321,8 +4451,8 @@ async function spawnInGnomeTerminal(projects) {
4321
4451
  wrapperScript
4322
4452
  );
4323
4453
  }
4324
- if (args.length > 0) {
4325
- spawn2("gnome-terminal", args, {
4454
+ if (args2.length > 0) {
4455
+ spawn2("gnome-terminal", args2, {
4326
4456
  stdio: "ignore",
4327
4457
  detached: true
4328
4458
  }).unref();
@@ -4493,7 +4623,7 @@ Attaching to: ${sanitizeForLog(firstProject.projectName)}`);
4493
4623
  function buildSecureDockerArgs(project, settings, containerName) {
4494
4624
  const cmd = dockerService.getDockerInfo().runtime === "podman" ? "podman" : "docker";
4495
4625
  const homeDir = os2.homedir();
4496
- const args = [
4626
+ const args2 = [
4497
4627
  cmd,
4498
4628
  "run",
4499
4629
  "-it",
@@ -4511,19 +4641,19 @@ function buildSecureDockerArgs(project, settings, containerName) {
4511
4641
  ];
4512
4642
  for (const [hostPath, containerPath] of Object.entries(settings.volumeMounts || {})) {
4513
4643
  if (isValidProjectPath(hostPath)) {
4514
- args.push("-v", `${hostPath}:${containerPath}:rw`);
4644
+ args2.push("-v", `${hostPath}:${containerPath}:rw`);
4515
4645
  }
4516
4646
  }
4517
4647
  for (const [key, value] of Object.entries(settings.environment || {})) {
4518
4648
  if (/^[A-Z_][A-Z0-9_]*$/.test(key)) {
4519
- args.push("-e", `${key}=${value}`);
4649
+ args2.push("-e", `${key}=${value}`);
4520
4650
  }
4521
4651
  }
4522
- args.push(settings.defaultImage, "claude");
4652
+ args2.push(settings.defaultImage, "claude");
4523
4653
  if (project.sessionId && !project.newSession) {
4524
- args.push("--resume", project.sessionId);
4654
+ args2.push("--resume", project.sessionId);
4525
4655
  }
4526
- return args;
4656
+ return args2;
4527
4657
  }
4528
4658
  function escapeShellArg(arg) {
4529
4659
  return `'${arg.replace(/'/g, "'\\''")}'`;
@@ -4574,11 +4704,119 @@ function getTerminalName(terminal) {
4574
4704
  }
4575
4705
 
4576
4706
  // src/services/sandbox/sandbox.ts
4577
- import { execSync as execSync2 } from "child_process";
4578
4707
  import { existsSync as existsSync8, mkdirSync, rmSync, readdirSync as readdirSync2, copyFileSync, readFileSync as readFileSync4 } from "fs";
4579
4708
  import { join as join4, dirname } from "path";
4580
4709
  import { randomUUID } from "crypto";
4581
4710
  import Conf3 from "conf";
4711
+
4712
+ // src/utils/secure-exec.ts
4713
+ import { spawnSync as spawnSync3, spawn as spawn3 } from "child_process";
4714
+ var ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
4715
+ // Git commands
4716
+ "git",
4717
+ // Docker commands
4718
+ "docker",
4719
+ "podman",
4720
+ // System commands
4721
+ "which",
4722
+ "tar",
4723
+ "claude",
4724
+ "gh",
4725
+ // Terminal emulators
4726
+ "tmux",
4727
+ "gnome-terminal",
4728
+ "kitty",
4729
+ "kitten",
4730
+ "alacritty",
4731
+ // Clipboard tools
4732
+ "wl-copy",
4733
+ "xclip",
4734
+ "xsel",
4735
+ "pbcopy",
4736
+ // Package managers (for version check)
4737
+ "npm",
4738
+ "yarn",
4739
+ "pnpm",
4740
+ "node"
4741
+ ]);
4742
+ function isAllowedCommand(command) {
4743
+ return ALLOWED_COMMANDS.has(command);
4744
+ }
4745
+ function validateArgs(args2) {
4746
+ for (const arg of args2) {
4747
+ if (arg.includes("\0")) {
4748
+ return false;
4749
+ }
4750
+ if (!arg.startsWith("-") && !arg.startsWith("--")) {
4751
+ const sanitized = arg.replace(/[a-zA-Z0-9_\-./@ ]/g, "");
4752
+ if (sanitized.length > 0 && containsShellMetacharacters(sanitized)) {
4753
+ return false;
4754
+ }
4755
+ }
4756
+ }
4757
+ return true;
4758
+ }
4759
+ function secureExecSync(command, args2, options = {}) {
4760
+ if (!isAllowedCommand(command)) {
4761
+ return {
4762
+ success: false,
4763
+ stdout: "",
4764
+ stderr: `Command not allowed: ${command}`,
4765
+ exitCode: -1
4766
+ };
4767
+ }
4768
+ if (options.cwd && !isValidProjectPath(options.cwd)) {
4769
+ return {
4770
+ success: false,
4771
+ stdout: "",
4772
+ stderr: `Invalid working directory: ${options.cwd}`,
4773
+ exitCode: -1
4774
+ };
4775
+ }
4776
+ if (!validateArgs(args2)) {
4777
+ return {
4778
+ success: false,
4779
+ stdout: "",
4780
+ stderr: "Invalid arguments detected",
4781
+ exitCode: -1
4782
+ };
4783
+ }
4784
+ try {
4785
+ const result = spawnSync3(command, args2, {
4786
+ cwd: options.cwd,
4787
+ timeout: options.timeout || 3e4,
4788
+ encoding: options.encoding || "utf-8",
4789
+ env: options.env || process.env,
4790
+ stdio: ["pipe", "pipe", "pipe"],
4791
+ // CRITICAL: shell: false is the default, but we explicitly set it
4792
+ shell: false
4793
+ });
4794
+ return {
4795
+ success: result.status === 0,
4796
+ stdout: result.stdout?.toString() || "",
4797
+ stderr: result.stderr?.toString() || "",
4798
+ exitCode: result.status
4799
+ };
4800
+ } catch (error) {
4801
+ return {
4802
+ success: false,
4803
+ stdout: "",
4804
+ stderr: error instanceof Error ? error.message : "Unknown error",
4805
+ exitCode: -1
4806
+ };
4807
+ }
4808
+ }
4809
+ function gitExec(args2, cwd) {
4810
+ return secureExecSync("git", args2, { cwd });
4811
+ }
4812
+ function tarExec(args2, cwd) {
4813
+ return secureExecSync("tar", args2, { cwd });
4814
+ }
4815
+ function containerExec(runtime, args2, cwd) {
4816
+ return secureExecSync(runtime, args2, { cwd });
4817
+ }
4818
+
4819
+ // src/services/sandbox/sandbox.ts
4582
4820
  var DEFAULT_SANDBOX_CONFIG = {
4583
4821
  enabled: false,
4584
4822
  defaultMode: "worktree",
@@ -4616,31 +4854,19 @@ var SandboxService = class {
4616
4854
  * Check if a path is a git repository
4617
4855
  */
4618
4856
  isGitRepo(path15) {
4619
- try {
4620
- execSync2("git rev-parse --git-dir", {
4621
- cwd: path15,
4622
- stdio: "pipe"
4623
- });
4624
- return true;
4625
- } catch {
4626
- return false;
4627
- }
4857
+ const result = gitExec(["rev-parse", "--git-dir"], path15);
4858
+ return result.success;
4628
4859
  }
4629
4860
  /**
4630
4861
  * Check if Docker is available
4631
4862
  */
4632
4863
  isDockerAvailable() {
4633
- try {
4634
- execSync2("docker info", { stdio: "pipe" });
4864
+ const dockerResult = containerExec("docker", ["info"]);
4865
+ if (dockerResult.success) {
4635
4866
  return true;
4636
- } catch {
4637
- try {
4638
- execSync2("podman info", { stdio: "pipe" });
4639
- return true;
4640
- } catch {
4641
- return false;
4642
- }
4643
4867
  }
4868
+ const podmanResult = containerExec("podman", ["info"]);
4869
+ return podmanResult.success;
4644
4870
  }
4645
4871
  /**
4646
4872
  * Detect the best sandbox mode for the current environment
@@ -4722,14 +4948,15 @@ var SandboxService = class {
4722
4948
  const sandboxDir = this.getSandboxDir(projectPath);
4723
4949
  const sandboxPath = join4(sandboxDir, `session-${sessionId}`);
4724
4950
  mkdirSync(dirname(sandboxPath), { recursive: true });
4725
- const currentRef = execSync2("git rev-parse HEAD", {
4726
- cwd: projectPath,
4727
- encoding: "utf-8"
4728
- }).trim();
4729
- execSync2(`git worktree add --detach "${sandboxPath}" ${currentRef}`, {
4730
- cwd: projectPath,
4731
- stdio: "pipe"
4732
- });
4951
+ const headResult = gitExec(["rev-parse", "HEAD"], projectPath);
4952
+ if (!headResult.success) {
4953
+ throw new Error("Failed to get current HEAD");
4954
+ }
4955
+ const currentRef = headResult.stdout.trim();
4956
+ const worktreeResult = gitExec(["worktree", "add", "--detach", sandboxPath, currentRef], projectPath);
4957
+ if (!worktreeResult.success) {
4958
+ throw new Error(`Failed to create worktree: ${worktreeResult.stderr}`);
4959
+ }
4733
4960
  await this.copyUntrackedFiles(projectPath, sandboxPath);
4734
4961
  return sandboxPath;
4735
4962
  }
@@ -4738,10 +4965,8 @@ var SandboxService = class {
4738
4965
  */
4739
4966
  async copyUntrackedFiles(projectPath, sandboxPath) {
4740
4967
  try {
4741
- const untrackedOutput = execSync2("git ls-files --others --exclude-standard", {
4742
- cwd: projectPath,
4743
- encoding: "utf-8"
4744
- });
4968
+ const untrackedResult = gitExec(["ls-files", "--others", "--exclude-standard"], projectPath);
4969
+ const untrackedOutput = untrackedResult.stdout;
4745
4970
  const untrackedFiles = untrackedOutput.split("\n").filter((f) => f.trim().length > 0);
4746
4971
  for (const file of untrackedFiles) {
4747
4972
  const srcPath = join4(projectPath, file);
@@ -4865,22 +5090,12 @@ var SandboxService = class {
4865
5090
  throw new Error(`Sandbox ${sessionId} not found`);
4866
5091
  }
4867
5092
  if (session.mode === "worktree") {
4868
- try {
4869
- execSync2(`git worktree remove "${session.sandboxPath}" --force`, {
4870
- cwd: session.projectPath,
4871
- stdio: "pipe"
4872
- });
4873
- } catch {
5093
+ const removeResult = gitExec(["worktree", "remove", session.sandboxPath, "--force"], session.projectPath);
5094
+ if (!removeResult.success) {
4874
5095
  if (existsSync8(session.sandboxPath)) {
4875
5096
  rmSync(session.sandboxPath, { recursive: true, force: true });
4876
5097
  }
4877
- try {
4878
- execSync2("git worktree prune", {
4879
- cwd: session.projectPath,
4880
- stdio: "pipe"
4881
- });
4882
- } catch {
4883
- }
5098
+ gitExec(["worktree", "prune"], session.projectPath);
4884
5099
  }
4885
5100
  } else {
4886
5101
  if (existsSync8(session.sandboxPath)) {
@@ -4904,14 +5119,10 @@ var SandboxService = class {
4904
5119
  }
4905
5120
  const changes = [];
4906
5121
  if (session.mode === "worktree") {
4907
- const diffOutput = execSync2("git diff --stat --numstat HEAD", {
4908
- cwd: session.sandboxPath,
4909
- encoding: "utf-8"
4910
- });
4911
- const untrackedOutput = execSync2("git ls-files --others --exclude-standard", {
4912
- cwd: session.sandboxPath,
4913
- encoding: "utf-8"
4914
- });
5122
+ const diffResult = gitExec(["diff", "--stat", "--numstat", "HEAD"], session.sandboxPath);
5123
+ const diffOutput = diffResult.stdout;
5124
+ const untrackedResult = gitExec(["ls-files", "--others", "--exclude-standard"], session.sandboxPath);
5125
+ const untrackedOutput = untrackedResult.stdout;
4915
5126
  const lines = diffOutput.split("\n").filter((l) => l.trim().length > 0);
4916
5127
  for (const line of lines) {
4917
5128
  const match = line.match(/^(\d+)\t(\d+)\t(.+)$/);
@@ -5107,21 +5318,17 @@ var SandboxService = class {
5107
5318
  throw new Error(`Sandbox ${sessionId} not found`);
5108
5319
  }
5109
5320
  if (session.mode === "worktree") {
5110
- try {
5111
- const diff = execSync2(`git diff HEAD -- "${filePath}"`, {
5112
- cwd: session.sandboxPath,
5113
- encoding: "utf-8"
5114
- });
5115
- return diff || "(no changes)";
5116
- } catch {
5117
- const sandboxFilePath2 = join4(session.sandboxPath, filePath);
5118
- if (existsSync8(sandboxFilePath2)) {
5119
- const content = readFileSync4(sandboxFilePath2, "utf-8");
5120
- return `+++ ${filePath} (new file)
5321
+ const diffResult = gitExec(["diff", "HEAD", "--", filePath], session.sandboxPath);
5322
+ if (diffResult.success && diffResult.stdout) {
5323
+ return diffResult.stdout;
5324
+ }
5325
+ const sandboxFilePath2 = join4(session.sandboxPath, filePath);
5326
+ if (existsSync8(sandboxFilePath2)) {
5327
+ const content = readFileSync4(sandboxFilePath2, "utf-8");
5328
+ return `+++ ${filePath} (new file)
5121
5329
  ${content.split("\n").map((l) => `+ ${l}`).join("\n")}`;
5122
- }
5123
- return "(file not found)";
5124
5330
  }
5331
+ return "(no changes)";
5125
5332
  }
5126
5333
  const originalPath = join4(session.projectPath, filePath);
5127
5334
  const sandboxFilePath = join4(session.sandboxPath, filePath);
@@ -5687,7 +5894,7 @@ function generatePRReviewContext(pr, repo) {
5687
5894
 
5688
5895
  // src/commands/session/resume.ts
5689
5896
  import { Command as Command11 } from "commander";
5690
- import { spawn as spawn3 } from "child_process";
5897
+ import { spawn as spawn4 } from "child_process";
5691
5898
  import inquirer3 from "inquirer";
5692
5899
  import ora8 from "ora";
5693
5900
  import * as fs2 from "fs";
@@ -5891,8 +6098,8 @@ function truncatePrompt(prompt, maxLength) {
5891
6098
  }
5892
6099
  function launchClaudeResume(projectPath, sessionId) {
5893
6100
  const launchArgs = getClaudeLaunchArgs();
5894
- const args = ["--resume", sessionId, ...launchArgs];
5895
- const child = spawn3("claude", args, {
6101
+ const args2 = ["--resume", sessionId, ...launchArgs];
6102
+ const child = spawn4("claude", args2, {
5896
6103
  cwd: projectPath,
5897
6104
  stdio: "inherit",
5898
6105
  shell: true
@@ -5910,7 +6117,7 @@ function launchClaudeResume(projectPath, sessionId) {
5910
6117
 
5911
6118
  // src/commands/session/restore.ts
5912
6119
  import { Command as Command12 } from "commander";
5913
- import { spawn as spawn4 } from "child_process";
6120
+ import { spawn as spawn5 } from "child_process";
5914
6121
  import inquirer4 from "inquirer";
5915
6122
  import ora9 from "ora";
5916
6123
  import * as fs3 from "fs";
@@ -6043,7 +6250,7 @@ var restoreCommand = new Command12("restore").description("Context aus crashed S
6043
6250
  log.info("F\xFCge den Context am Anfang der neuen Session ein:");
6044
6251
  log.dim(` cat "${outputPath}" | head -100`);
6045
6252
  log.newline();
6046
- const child = spawn4("claude", [], {
6253
+ const child = spawn5("claude", [], {
6047
6254
  cwd: project.absolutePath,
6048
6255
  stdio: "inherit",
6049
6256
  shell: true
@@ -6223,9 +6430,9 @@ function sessionHasAnyTag(sessionId, tags) {
6223
6430
 
6224
6431
  // src/utils/command-wrapper.ts
6225
6432
  function withCommandErrorHandling(commandName, fn) {
6226
- return async (...args) => {
6433
+ return async (...args2) => {
6227
6434
  try {
6228
- await fn(...args);
6435
+ await fn(...args2);
6229
6436
  } catch (error) {
6230
6437
  const shivaError = fromError(error);
6231
6438
  logErrorWithSuggestion(shivaError, commandName);
@@ -6348,7 +6555,7 @@ async function checkProjectExists(path15) {
6348
6555
  }
6349
6556
  }
6350
6557
  sessionsCommand.command("push").description("Sessions in Cloud sichern").option("-p, --project <pfad>", "Nur Sessions eines Projekts").action(async (options) => {
6351
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6558
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6352
6559
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6353
6560
  const { getProjectConfig: getProjectConfig2 } = await import("./config-D6M6LI6U.js");
6354
6561
  if (!isAuthenticated2()) {
@@ -6408,7 +6615,7 @@ sessionsCommand.command("push").description("Sessions in Cloud sichern").option(
6408
6615
  }
6409
6616
  });
6410
6617
  sessionsCommand.command("pull").description("Sessions aus Cloud laden").option("--json", "JSON Output").action(async (options) => {
6411
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6618
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6412
6619
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6413
6620
  if (!isAuthenticated2()) {
6414
6621
  log.error("Nicht angemeldet");
@@ -6455,7 +6662,7 @@ sessionsCommand.command("pull").description("Sessions aus Cloud laden").option("
6455
6662
  }
6456
6663
  });
6457
6664
  sessionsCommand.command("sync").description("Sessions mit Cloud synchronisieren").option("-p, --project <pfad>", "Nur Sessions eines Projekts").action(async (options) => {
6458
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6665
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6459
6666
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6460
6667
  const { getProjectConfig: getProjectConfig2 } = await import("./config-D6M6LI6U.js");
6461
6668
  if (!isAuthenticated2()) {
@@ -6508,7 +6715,7 @@ sessionsCommand.command("sync").description("Sessions mit Cloud synchronisieren"
6508
6715
  log.dim("Sessions werden automatisch mit lokalen Claude Sessions verkn\xFCpft");
6509
6716
  });
6510
6717
  sessionsCommand.command("delete <sessionId>").description("Session aus Cloud l\xF6schen").action(async (sessionId) => {
6511
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6718
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6512
6719
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6513
6720
  if (!isAuthenticated2()) {
6514
6721
  log.error("Nicht angemeldet");
@@ -6527,7 +6734,7 @@ sessionsCommand.command("delete <sessionId>").description("Session aus Cloud l\x
6527
6734
  }
6528
6735
  });
6529
6736
  sessionsCommand.command("active").description("Aktive Cloud-Sessions anzeigen").option("--json", "JSON Output").action(async (options) => {
6530
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6737
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6531
6738
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6532
6739
  if (!isAuthenticated2()) {
6533
6740
  log.error("Nicht angemeldet");
@@ -6564,7 +6771,7 @@ sessionsCommand.command("active").description("Aktive Cloud-Sessions anzeigen").
6564
6771
  }
6565
6772
  });
6566
6773
  sessionsCommand.command("stats").description("Cloud-Session-Statistiken anzeigen").option("--json", "JSON Output").action(async (options) => {
6567
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6774
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6568
6775
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6569
6776
  if (!isAuthenticated2()) {
6570
6777
  log.error("Nicht angemeldet");
@@ -6596,7 +6803,7 @@ sessionsCommand.command("stats").description("Cloud-Session-Statistiken anzeigen
6596
6803
  }
6597
6804
  });
6598
6805
  sessionsCommand.command("resume <sessionId>").description("Cloud-Session fortsetzen").action(async (sessionId) => {
6599
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6806
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6600
6807
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6601
6808
  if (!isAuthenticated2()) {
6602
6809
  log.error("Nicht angemeldet");
@@ -6620,7 +6827,7 @@ sessionsCommand.command("resume <sessionId>").description("Cloud-Session fortset
6620
6827
  }
6621
6828
  });
6622
6829
  sessionsCommand.command("export <sessionId>").description("Cloud-Session exportieren").option("-o, --output <file>", "Ausgabedatei").action(async (sessionId, options) => {
6623
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6830
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6624
6831
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6625
6832
  const { writeFileSync: writeFileSync11 } = await import("fs");
6626
6833
  if (!isAuthenticated2()) {
@@ -6644,7 +6851,7 @@ sessionsCommand.command("export <sessionId>").description("Cloud-Session exporti
6644
6851
  }
6645
6852
  });
6646
6853
  sessionsCommand.command("update <sessionId>").description("Cloud-Session aktualisieren").option("--summary <text>", "Session-Zusammenfassung").option("--branch <name>", "Git Branch").action(async (sessionId, options) => {
6647
- const { api: api2 } = await import("./client-GIGZFXT5.js");
6854
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
6648
6855
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
6649
6856
  if (!isAuthenticated2()) {
6650
6857
  log.error("Nicht angemeldet");
@@ -7124,7 +7331,7 @@ sessionCommand.command("config").description("Sandbox-Konfiguration verwalten").
7124
7331
 
7125
7332
  // src/commands/github/github-cmd.ts
7126
7333
  import { Command as Command15 } from "commander";
7127
- import { spawn as spawn5, spawnSync as spawnSync5 } from "child_process";
7334
+ import { spawn as spawn6, spawnSync as spawnSync5 } from "child_process";
7128
7335
  import * as fs5 from "fs";
7129
7336
  import * as path5 from "path";
7130
7337
  import inquirer5 from "inquirer";
@@ -7203,7 +7410,7 @@ function loginWithGh() {
7203
7410
  log.newline();
7204
7411
  log.info("\xD6ffne GitHub Login...");
7205
7412
  log.newline();
7206
- const child = spawn5("gh", ["auth", "login"], {
7413
+ const child = spawn6("gh", ["auth", "login"], {
7207
7414
  stdio: "inherit"
7208
7415
  });
7209
7416
  child.on("error", (error) => {
@@ -7624,13 +7831,13 @@ githubCommand.command("map").description("Aktuellen Branch mit einer Session ver
7624
7831
  initShivaDir(cwd);
7625
7832
  }
7626
7833
  if (!sessionId) {
7627
- const { findProject: findProject3 } = await import("./manager-ZPQWG7E6.js");
7834
+ const { findProject: findProject3 } = await import("./manager-CCRAV6A5.js");
7628
7835
  const project = await findProject3(cwd);
7629
7836
  if (!project || project.sessions.length === 0) {
7630
7837
  log.error("Keine Sessions f\xFCr dieses Projekt gefunden");
7631
7838
  return;
7632
7839
  }
7633
- const { formatDate: formatDate2 } = await import("./manager-ZPQWG7E6.js");
7840
+ const { formatDate: formatDate2 } = await import("./manager-CCRAV6A5.js");
7634
7841
  const choices = project.sessions.slice(0, 10).map((s) => {
7635
7842
  const time = formatDate2(s.modified);
7636
7843
  const msgs = `${s.messageCount} msgs`;
@@ -10220,7 +10427,7 @@ async function resolveSessionId(input) {
10220
10427
  return null;
10221
10428
  }
10222
10429
  tagsCommand.command("cloud").description("Memory-Tags aus Cloud laden").option("--json", "JSON Output").action(async (options) => {
10223
- const { api: api2 } = await import("./client-GIGZFXT5.js");
10430
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
10224
10431
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
10225
10432
  if (!isAuthenticated2()) {
10226
10433
  log.error("Nicht angemeldet");
@@ -10264,7 +10471,6 @@ import inquirer10 from "inquirer";
10264
10471
  // src/services/session/export.ts
10265
10472
  import * as fs9 from "fs";
10266
10473
  import * as path10 from "path";
10267
- import { execSync as execSync3 } from "child_process";
10268
10474
  async function exportSession(sessionId, options = {}) {
10269
10475
  const projects = await getAllClaudeProjects();
10270
10476
  for (const project of projects) {
@@ -10375,11 +10581,9 @@ function createBackupArchive(outputPath, projectPaths) {
10375
10581
  if (includePaths.length === 0) {
10376
10582
  return false;
10377
10583
  }
10378
- const tarArgs = includePaths.join(" ");
10379
- execSync3(`tar -czf "${outputPath}" -C "${claudeDir}" ${tarArgs}`, {
10380
- stdio: "ignore"
10381
- });
10382
- return true;
10584
+ const args2 = ["-czf", outputPath, "-C", claudeDir, ...includePaths];
10585
+ const result = tarExec(args2);
10586
+ return result.success;
10383
10587
  } catch {
10384
10588
  return false;
10385
10589
  }
@@ -10484,9 +10688,10 @@ function restoreFromArchive(archivePath, targetDir) {
10484
10688
  if (!fs9.existsSync(extractTo)) {
10485
10689
  fs9.mkdirSync(extractTo, { recursive: true });
10486
10690
  }
10487
- execSync3(`tar -xzf "${archivePath}" -C "${extractTo}"`, {
10488
- stdio: "ignore"
10489
- });
10691
+ const extractResult = tarExec(["-xzf", archivePath, "-C", extractTo]);
10692
+ if (!extractResult.success) {
10693
+ return false;
10694
+ }
10490
10695
  return true;
10491
10696
  } catch {
10492
10697
  return false;
@@ -10786,20 +10991,20 @@ var rememberCommand = new Command26("remember").description("Memory in der Cloud
10786
10991
 
10787
10992
  // src/commands/system/doctor.ts
10788
10993
  import { Command as Command27 } from "commander";
10789
- import { execSync as execSync4 } from "child_process";
10994
+ import { execSync as execSync2 } from "child_process";
10790
10995
  import * as fs11 from "fs";
10791
10996
  import * as path12 from "path";
10792
10997
  import * as os5 from "os";
10793
10998
  function tryExec(command) {
10794
10999
  try {
10795
- return execSync4(command, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
11000
+ return execSync2(command, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
10796
11001
  } catch {
10797
11002
  return null;
10798
11003
  }
10799
11004
  }
10800
11005
  function commandExists2(cmd) {
10801
11006
  try {
10802
- execSync4(`which ${cmd}`, { stdio: ["pipe", "pipe", "pipe"] });
11007
+ execSync2(`which ${cmd}`, { stdio: ["pipe", "pipe", "pipe"] });
10803
11008
  return true;
10804
11009
  } catch {
10805
11010
  return false;
@@ -11113,7 +11318,7 @@ var doctorCommand = new Command27("doctor").description("System-Check f\xFCr SHI
11113
11318
 
11114
11319
  // src/commands/system/upgrade.ts
11115
11320
  import { Command as Command28 } from "commander";
11116
- import { execSync as execSync5, spawn as spawn6 } from "child_process";
11321
+ import { execSync as execSync3, spawn as spawn7 } from "child_process";
11117
11322
  import * as fs12 from "fs";
11118
11323
  import * as path13 from "path";
11119
11324
  import * as os6 from "os";
@@ -11133,17 +11338,17 @@ function detectInstallationType() {
11133
11338
  }
11134
11339
  }
11135
11340
  try {
11136
- const npmGlobal = execSync5("npm list -g --depth=0 2>/dev/null", { encoding: "utf-8" });
11341
+ const npmGlobal = execSync3("npm list -g --depth=0 2>/dev/null", { encoding: "utf-8" });
11137
11342
  if (npmGlobal.includes(PACKAGE_NAME)) return "npm";
11138
11343
  } catch {
11139
11344
  }
11140
11345
  try {
11141
- const yarnGlobal = execSync5("yarn global list 2>/dev/null", { encoding: "utf-8" });
11346
+ const yarnGlobal = execSync3("yarn global list 2>/dev/null", { encoding: "utf-8" });
11142
11347
  if (yarnGlobal.includes(PACKAGE_NAME)) return "yarn";
11143
11348
  } catch {
11144
11349
  }
11145
11350
  try {
11146
- const pnpmGlobal = execSync5("pnpm list -g 2>/dev/null", { encoding: "utf-8" });
11351
+ const pnpmGlobal = execSync3("pnpm list -g 2>/dev/null", { encoding: "utf-8" });
11147
11352
  if (pnpmGlobal.includes(PACKAGE_NAME)) return "pnpm";
11148
11353
  } catch {
11149
11354
  }
@@ -11159,7 +11364,7 @@ function getCurrentVersion() {
11159
11364
  } catch {
11160
11365
  }
11161
11366
  try {
11162
- const output = execSync5(`"${process.execPath}" --version 2>/dev/null`, { encoding: "utf-8" }).trim();
11367
+ const output = execSync3(`"${process.execPath}" --version 2>/dev/null`, { encoding: "utf-8" }).trim();
11163
11368
  return output || "0.0.0";
11164
11369
  } catch {
11165
11370
  return "0.7.0";
@@ -11332,7 +11537,7 @@ del "${backupBinary}" 2>nul
11332
11537
  del "%~f0"
11333
11538
  `;
11334
11539
  fs12.writeFileSync(updateScript, scriptContent);
11335
- spawn6("cmd", ["/c", updateScript], { detached: true, stdio: "ignore" }).unref();
11540
+ spawn7("cmd", ["/c", updateScript], { detached: true, stdio: "ignore" }).unref();
11336
11541
  log.success("Update wird nach Beenden angewendet");
11337
11542
  log.info("Bitte starte SHIVA neu.");
11338
11543
  } else {
@@ -11375,11 +11580,11 @@ function getUpgradeCommand(pm) {
11375
11580
  }
11376
11581
  async function runPackageManagerUpgrade(pm) {
11377
11582
  const command = getUpgradeCommand(pm);
11378
- const [cmd, ...args] = command.split(" ");
11583
+ const [cmd, ...args2] = command.split(" ");
11379
11584
  return new Promise((resolve14) => {
11380
11585
  log.info(`F\xFChre aus: ${command}`);
11381
11586
  log.newline();
11382
- const proc = spawn6(cmd, args, {
11587
+ const proc = spawn7(cmd, args2, {
11383
11588
  stdio: "inherit",
11384
11589
  shell: true
11385
11590
  });
@@ -11458,6 +11663,7 @@ var selfUpdateCommand = new Command28("self-update").description('Alias f\xFCr "
11458
11663
 
11459
11664
  // src/commands/system/telemetry.ts
11460
11665
  import { Command as Command29 } from "commander";
11666
+ import { randomUUID as randomUUID2 } from "crypto";
11461
11667
  import Conf4 from "conf";
11462
11668
  var telemetryConfig = new Conf4({
11463
11669
  projectName: "shiva-code",
@@ -11473,11 +11679,7 @@ var telemetryConfig = new Conf4({
11473
11679
  }
11474
11680
  });
11475
11681
  function generateAnonymousId() {
11476
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
11477
- const r = Math.random() * 16 | 0;
11478
- const v = c === "x" ? r : r & 3 | 8;
11479
- return v.toString(16);
11480
- });
11682
+ return randomUUID2();
11481
11683
  }
11482
11684
  var DATA_COLLECTED = [
11483
11685
  'Verwendete Commands (z.B. "shiva sessions", "shiva start")',
@@ -12137,7 +12339,7 @@ function formatNumber(n) {
12137
12339
  return String(n);
12138
12340
  }
12139
12341
  statsCommand.command("sessions").description("Session Analytics (Pro Feature)").option("--json", "JSON Output").action(async (options) => {
12140
- const { api: api2 } = await import("./client-GIGZFXT5.js");
12342
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
12141
12343
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
12142
12344
  if (!isAuthenticated2()) {
12143
12345
  log.error("Nicht angemeldet");
@@ -12189,7 +12391,7 @@ statsCommand.command("sessions").description("Session Analytics (Pro Feature)").
12189
12391
  }
12190
12392
  });
12191
12393
  statsCommand.command("tokens").description("Token Usage Analytics (Pro Feature)").option("--json", "JSON Output").action(async (options) => {
12192
- const { api: api2 } = await import("./client-GIGZFXT5.js");
12394
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
12193
12395
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
12194
12396
  if (!isAuthenticated2()) {
12195
12397
  log.error("Nicht angemeldet");
@@ -12237,7 +12439,7 @@ statsCommand.command("tokens").description("Token Usage Analytics (Pro Feature)"
12237
12439
  }
12238
12440
  });
12239
12441
  statsCommand.command("tools").description("Tool Usage Analytics (Pro Feature)").option("--json", "JSON Output").action(async (options) => {
12240
- const { api: api2 } = await import("./client-GIGZFXT5.js");
12442
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
12241
12443
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
12242
12444
  if (!isAuthenticated2()) {
12243
12445
  log.error("Nicht angemeldet");
@@ -12281,7 +12483,7 @@ statsCommand.command("tools").description("Tool Usage Analytics (Pro Feature)").
12281
12483
  }
12282
12484
  });
12283
12485
  statsCommand.command("export").description("Analytics-Daten exportieren (Pro Feature)").option("--start <date>", "Start-Datum (YYYY-MM-DD)").option("--end <date>", "End-Datum (YYYY-MM-DD)").option("--format <format>", "Format: json, csv", "json").option("-o, --output <file>", "Ausgabedatei").action(async (options) => {
12284
- const { api: api2 } = await import("./client-GIGZFXT5.js");
12486
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
12285
12487
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
12286
12488
  const { writeFileSync: writeFileSync11 } = await import("fs");
12287
12489
  if (!isAuthenticated2()) {
@@ -12316,7 +12518,7 @@ statsCommand.command("export").description("Analytics-Daten exportieren (Pro Fea
12316
12518
  }
12317
12519
  });
12318
12520
  statsCommand.command("track").description("Analytics Event tracken").argument("<type>", "Event-Typ").argument("[data]", "Event-Daten als JSON").action(async (type2, data) => {
12319
- const { api: api2 } = await import("./client-GIGZFXT5.js");
12521
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
12320
12522
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
12321
12523
  if (!isAuthenticated2()) {
12322
12524
  log.error("Nicht angemeldet");
@@ -12648,10 +12850,218 @@ var welcomeCommand = new Command33("welcome").description("Onboarding erneut sta
12648
12850
  await runOnboarding();
12649
12851
  });
12650
12852
 
12651
- // src/commands/advanced/docker.ts
12853
+ // src/commands/system/validate.ts
12652
12854
  import { Command as Command34 } from "commander";
12855
+ import { existsSync as existsSync22, readFileSync as readFileSync11 } from "fs";
12856
+ import { homedir as homedir7 } from "os";
12857
+ import { join as join13 } from "path";
12858
+ async function checkConfigFile() {
12859
+ try {
12860
+ const configPath = getConfigPath();
12861
+ if (!existsSync22(configPath)) {
12862
+ return {
12863
+ ok: false,
12864
+ message: "Konfigurationsdatei nicht gefunden",
12865
+ suggestion: "shiva init um Projekt zu initialisieren"
12866
+ };
12867
+ }
12868
+ const content = readFileSync11(configPath, "utf-8");
12869
+ JSON.parse(content);
12870
+ return {
12871
+ ok: true,
12872
+ message: "Konfigurationsdatei OK"
12873
+ };
12874
+ } catch (error) {
12875
+ return {
12876
+ ok: false,
12877
+ message: "Konfigurationsdatei besch\xE4digt",
12878
+ suggestion: "shiva config reset um zur\xFCckzusetzen"
12879
+ };
12880
+ }
12881
+ }
12882
+ async function checkAuth() {
12883
+ const token = getToken();
12884
+ if (!token) {
12885
+ return {
12886
+ ok: false,
12887
+ message: "Nicht angemeldet",
12888
+ suggestion: "shiva login um dich anzumelden"
12889
+ };
12890
+ }
12891
+ return {
12892
+ ok: true,
12893
+ message: "Authentifiziert"
12894
+ };
12895
+ }
12896
+ async function checkClaude2() {
12897
+ if (!isClaudeInstalled()) {
12898
+ return {
12899
+ ok: false,
12900
+ message: "Claude Code nicht installiert",
12901
+ suggestion: "curl -fsSL https://claude.ai/install.sh | bash"
12902
+ };
12903
+ }
12904
+ return {
12905
+ ok: true,
12906
+ message: "Claude Code installiert"
12907
+ };
12908
+ }
12909
+ async function checkHooks() {
12910
+ try {
12911
+ const claudeDir = join13(homedir7(), ".claude");
12912
+ const settingsPath = join13(claudeDir, "settings.json");
12913
+ if (!existsSync22(settingsPath)) {
12914
+ return {
12915
+ ok: true,
12916
+ message: "Keine Hooks konfiguriert (optional)"
12917
+ };
12918
+ }
12919
+ const content = readFileSync11(settingsPath, "utf-8");
12920
+ const settings = JSON.parse(content);
12921
+ if (settings.hooks && Object.keys(settings.hooks).length > 0) {
12922
+ const hookCount = Object.values(settings.hooks).flat().length;
12923
+ return {
12924
+ ok: true,
12925
+ message: `${hookCount} Hook(s) konfiguriert`
12926
+ };
12927
+ }
12928
+ return {
12929
+ ok: true,
12930
+ message: "Keine Hooks konfiguriert (optional)"
12931
+ };
12932
+ } catch (error) {
12933
+ return {
12934
+ ok: false,
12935
+ message: "Hooks-Konfiguration fehlerhaft",
12936
+ suggestion: "shiva hook list um Hooks zu pr\xFCfen"
12937
+ };
12938
+ }
12939
+ }
12940
+ async function checkNetwork() {
12941
+ try {
12942
+ const controller = new AbortController();
12943
+ const timeout = setTimeout(() => controller.abort(), 5e3);
12944
+ const response = await fetch("https://api.shiva.li/health", {
12945
+ signal: controller.signal
12946
+ });
12947
+ clearTimeout(timeout);
12948
+ if (response.ok) {
12949
+ return {
12950
+ ok: true,
12951
+ message: "Server erreichbar"
12952
+ };
12953
+ }
12954
+ return {
12955
+ ok: false,
12956
+ message: `Server antwortet mit ${response.status}`,
12957
+ suggestion: "Sp\xE4ter erneut versuchen"
12958
+ };
12959
+ } catch (error) {
12960
+ return {
12961
+ ok: false,
12962
+ message: "Server nicht erreichbar",
12963
+ suggestion: "Internetverbindung pr\xFCfen"
12964
+ };
12965
+ }
12966
+ }
12967
+ async function checkProject() {
12968
+ const shivaDir = join13(process.cwd(), ".shiva");
12969
+ const claudeMd = join13(process.cwd(), "CLAUDE.md");
12970
+ if (!existsSync22(shivaDir)) {
12971
+ return {
12972
+ ok: false,
12973
+ message: "Kein SHIVA-Projekt",
12974
+ suggestion: "shiva init um Projekt zu initialisieren"
12975
+ };
12976
+ }
12977
+ if (!existsSync22(claudeMd)) {
12978
+ return {
12979
+ ok: false,
12980
+ message: "CLAUDE.md fehlt",
12981
+ suggestion: "shiva sync um CLAUDE.md zu generieren"
12982
+ };
12983
+ }
12984
+ return {
12985
+ ok: true,
12986
+ message: "Projekt konfiguriert"
12987
+ };
12988
+ }
12989
+ async function checkNodeVersion() {
12990
+ const version = process.version;
12991
+ const major = parseInt(version.slice(1).split(".")[0], 10);
12992
+ if (major < 18) {
12993
+ return {
12994
+ ok: false,
12995
+ message: `Node.js ${version} (min. v18 erforderlich)`,
12996
+ suggestion: "Node.js aktualisieren: https://nodejs.org"
12997
+ };
12998
+ }
12999
+ return {
13000
+ ok: true,
13001
+ message: `Node.js ${version}`
13002
+ };
13003
+ }
13004
+ var validateCommand = new Command34("validate").description("Konfiguration und System validieren").option("--json", "Ausgabe als JSON").action(async (options) => {
13005
+ const checks = [
13006
+ { name: "Node.js", check: checkNodeVersion },
13007
+ { name: "Konfiguration", check: checkConfigFile },
13008
+ { name: "Authentifizierung", check: checkAuth },
13009
+ { name: "Claude Code", check: checkClaude2 },
13010
+ { name: "Hooks", check: checkHooks },
13011
+ { name: "Netzwerk", check: checkNetwork },
13012
+ { name: "Projekt", check: checkProject }
13013
+ ];
13014
+ const results = [];
13015
+ let allPassed = true;
13016
+ if (!options.json) {
13017
+ log.header("SHIVA Configuration Check");
13018
+ log.newline();
13019
+ }
13020
+ for (const { name, check } of checks) {
13021
+ const result = await check();
13022
+ results.push({ name, result });
13023
+ if (!result.ok) {
13024
+ allPassed = false;
13025
+ }
13026
+ if (!options.json) {
13027
+ const icon = result.ok ? colors.green("\u2713") : colors.red("\u2717");
13028
+ console.log(` ${icon} ${name}: ${result.message}`);
13029
+ if (!result.ok && result.suggestion) {
13030
+ console.log(colors.dim(` \u2192 ${result.suggestion}`));
13031
+ }
13032
+ }
13033
+ }
13034
+ if (options.json) {
13035
+ console.log(
13036
+ JSON.stringify(
13037
+ {
13038
+ success: allPassed,
13039
+ checks: results.map(({ name, result }) => ({
13040
+ name,
13041
+ ok: result.ok,
13042
+ message: result.message,
13043
+ suggestion: result.suggestion
13044
+ }))
13045
+ },
13046
+ null,
13047
+ 2
13048
+ )
13049
+ );
13050
+ } else {
13051
+ log.newline();
13052
+ if (allPassed) {
13053
+ log.success("Alle Checks bestanden!");
13054
+ } else {
13055
+ log.warn("Einige Checks fehlgeschlagen");
13056
+ }
13057
+ }
13058
+ process.exit(allPassed ? 0 : 1);
13059
+ });
13060
+
13061
+ // src/commands/advanced/docker.ts
13062
+ import { Command as Command35 } from "commander";
12653
13063
  import ora21 from "ora";
12654
- var dockerCommand = new Command34("docker").description("Docker-Integration verwalten");
13064
+ var dockerCommand = new Command35("docker").description("Docker-Integration verwalten");
12655
13065
  dockerCommand.command("status").description("Docker-Verf\xFCgbarkeit pr\xFCfen").action(() => {
12656
13066
  log.brand();
12657
13067
  log.header("Docker Status");
@@ -12881,7 +13291,7 @@ dockerCommand.action(() => {
12881
13291
  });
12882
13292
 
12883
13293
  // src/commands/advanced/workflow.ts
12884
- import { Command as Command35 } from "commander";
13294
+ import { Command as Command36 } from "commander";
12885
13295
  import * as fs13 from "fs";
12886
13296
  import * as path14 from "path";
12887
13297
  import * as os7 from "os";
@@ -12905,7 +13315,7 @@ var builtInWorkflows = {
12905
13315
  ]
12906
13316
  }
12907
13317
  };
12908
- var workflowCommand = new Command35("workflow").description("Automatisierte Workflows ausf\xFChren").action(async () => {
13318
+ var workflowCommand = new Command36("workflow").description("Automatisierte Workflows ausf\xFChren").action(async () => {
12909
13319
  await listWorkflows();
12910
13320
  });
12911
13321
  workflowCommand.command("list").alias("ls").description("Verf\xFCgbare Workflows anzeigen").action(async () => {
@@ -13160,11 +13570,11 @@ async function executeStep(step) {
13160
13570
  }
13161
13571
 
13162
13572
  // src/commands/advanced/package.ts
13163
- import { Command as Command36 } from "commander";
13573
+ import { Command as Command37 } from "commander";
13164
13574
  import * as fs14 from "fs";
13165
13575
  import inquirer12 from "inquirer";
13166
13576
  import ora23 from "ora";
13167
- var packageCommand = new Command36("package").description("Projekt-Gruppen (Packages) verwalten").action(() => {
13577
+ var packageCommand = new Command37("package").description("Projekt-Gruppen (Packages) verwalten").action(() => {
13168
13578
  listPackages();
13169
13579
  });
13170
13580
  packageCommand.command("list").description("Alle Packages auflisten").option("--json", "JSON Output").action((options) => {
@@ -13309,7 +13719,7 @@ packageCommand.command("start <name>").description("Alle Projekte eines Packages
13309
13719
  }
13310
13720
  });
13311
13721
  packageCommand.command("push").description("Packages in Cloud sichern").option("-n, --name <name>", "Nur ein bestimmtes Package").action(async (options) => {
13312
- const { api: api2 } = await import("./client-GIGZFXT5.js");
13722
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
13313
13723
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
13314
13724
  if (!isAuthenticated2()) {
13315
13725
  log.error("Nicht angemeldet");
@@ -13355,7 +13765,7 @@ packageCommand.command("push").description("Packages in Cloud sichern").option("
13355
13765
  }
13356
13766
  });
13357
13767
  packageCommand.command("pull").description("Packages aus Cloud laden").option("-f, --force", "Lokale Packages \xFCberschreiben").option("--json", "JSON Output").action(async (options) => {
13358
- const { api: api2 } = await import("./client-GIGZFXT5.js");
13768
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
13359
13769
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
13360
13770
  if (!isAuthenticated2()) {
13361
13771
  log.error("Nicht angemeldet");
@@ -13417,7 +13827,7 @@ packageCommand.command("pull").description("Packages aus Cloud laden").option("-
13417
13827
  }
13418
13828
  });
13419
13829
  packageCommand.command("sync").description("Packages mit Cloud synchronisieren").action(async () => {
13420
- const { api: api2 } = await import("./client-GIGZFXT5.js");
13830
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
13421
13831
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
13422
13832
  if (!isAuthenticated2()) {
13423
13833
  log.error("Nicht angemeldet");
@@ -13470,7 +13880,7 @@ packageCommand.command("sync").description("Packages mit Cloud synchronisieren")
13470
13880
  log.tree.item(`${localPackages.length + pulledCount} Packages total`);
13471
13881
  });
13472
13882
  packageCommand.command("cloud-delete <name>").description("Package aus Cloud l\xF6schen").action(async (name) => {
13473
- const { api: api2 } = await import("./client-GIGZFXT5.js");
13883
+ const { api: api2 } = await import("./client-RPSJP4Z5.js");
13474
13884
  const { isAuthenticated: isAuthenticated2 } = await import("./config-FGMZONWV.js");
13475
13885
  if (!isAuthenticated2()) {
13476
13886
  log.error("Nicht angemeldet");
@@ -13527,9 +13937,9 @@ function listPackages() {
13527
13937
  }
13528
13938
 
13529
13939
  // src/commands/advanced/sandbox.ts
13530
- import { Command as Command37 } from "commander";
13940
+ import { Command as Command38 } from "commander";
13531
13941
  import ora24 from "ora";
13532
- var sandboxCommand = new Command37("sandbox").description("Sandbox-Management mit Cloud-Sync");
13942
+ var sandboxCommand = new Command38("sandbox").description("Sandbox-Management mit Cloud-Sync");
13533
13943
  sandboxCommand.command("list").description("Alle Sandboxes auflisten").option("--local", "Nur lokale Sandboxes").option("--cloud", "Nur Cloud Sandboxes").option("--status <status>", "Nach Status filtern: active, pending-review, applied, discarded").option("--json", "JSON Output").action(async (options) => {
13534
13944
  const spinner = ora24("Lade Sandboxes...").start();
13535
13945
  try {
@@ -13880,8 +14290,13 @@ sandboxCommand.command("delete <id>").description("Sandbox l\xF6schen").option("
13880
14290
  });
13881
14291
 
13882
14292
  // src/index.ts
13883
- var program = new Command38();
13884
- program.name("shiva").description("SHIVA Code - Control Station for Claude Code").version("0.7.0");
14293
+ var program = new Command39();
14294
+ program.name("shiva").description("SHIVA Code - Control Station for Claude Code").version("0.7.5").option("--debug", "Debug-Modus aktivieren").hook("preAction", (thisCommand) => {
14295
+ const opts = thisCommand.opts();
14296
+ if (opts.debug) {
14297
+ enableDebug();
14298
+ }
14299
+ });
13885
14300
  program.addCommand(loginCommand);
13886
14301
  program.addCommand(logoutCommand);
13887
14302
  program.addCommand(sessionsCommand);
@@ -13924,6 +14339,7 @@ program.addCommand(packageCommand);
13924
14339
  program.addCommand(sandboxCommand);
13925
14340
  program.addCommand(userCommand);
13926
14341
  program.addCommand(welcomeCommand);
14342
+ program.addCommand(validateCommand);
13927
14343
  program.action(async () => {
13928
14344
  if (needsOnboarding()) {
13929
14345
  await runOnboarding();
@@ -14108,7 +14524,7 @@ async function showDashboard() {
14108
14524
  const packageName = selected.data;
14109
14525
  log.newline();
14110
14526
  log.success(`Starte Package ${packageName}...`);
14111
- const { getPackageLaunchConfig: getPackageLaunchConfig2 } = await import("./package-manager-NHNQATBH.js");
14527
+ const { getPackageLaunchConfig: getPackageLaunchConfig2 } = await import("./package-manager-UORON74F.js");
14112
14528
  const launches = await getPackageLaunchConfig2(packageName);
14113
14529
  if (launches.length > 0) {
14114
14530
  await spawnProjects(launches, detectTerminal());
@@ -14195,5 +14611,27 @@ program.exitOverride((err) => {
14195
14611
  }
14196
14612
  process.exit(1);
14197
14613
  });
14614
+ program.on("command:*", (operands) => {
14615
+ const unknown = operands[0];
14616
+ const allCommands = program.commands.map((c) => c.name());
14617
+ const suggestions = findSimilarCommands(unknown, allCommands);
14618
+ log.error(`Unbekannter Befehl: ${unknown}`);
14619
+ if (suggestions.length > 0) {
14620
+ log.newline();
14621
+ log.info("Meintest du vielleicht:");
14622
+ suggestions.forEach((s) => log.plain(` shiva ${s}`));
14623
+ }
14624
+ log.newline();
14625
+ log.dim("Hilfe: shiva --help");
14626
+ process.exit(1);
14627
+ });
14198
14628
  migrateConfig();
14629
+ var args = process.argv.slice(2);
14630
+ if (args.length > 0 && !args[0].startsWith("-")) {
14631
+ const firstArg = args[0];
14632
+ const resolved = getCommandFromAlias(firstArg);
14633
+ if (resolved) {
14634
+ process.argv[2] = resolved;
14635
+ }
14636
+ }
14199
14637
  program.parse();