shiva-code 0.7.8 → 0.7.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-NM3RPOAT.js → chunk-4OT4OY7L.js} +167 -17
- package/dist/chunk-GGNOX6DN.js +195 -0
- package/dist/{chunk-3BM2KHD4.js → chunk-IWDZCN4S.js} +1 -1
- package/dist/chunk-UABU5VVI.js +246 -0
- package/dist/{hook-YNVEHNHZ.js → hook-CCATCFG7.js} +2 -2
- package/dist/index.js +434 -227
- package/dist/{logger-E7SC5KUO.js → logger-VVWOD6AA.js} +5 -3
- package/dist/{login-DE2U23GS.js → login-DBN2L25M.js} +2 -2
- package/dist/token-detection-K6KCIWAU.js +19 -0
- package/package.json +1 -1
- package/dist/chunk-Z6NXFC4Q.js +0 -118
package/dist/index.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
TOKEN_PATTERNS,
|
|
4
|
+
detectTokens,
|
|
5
|
+
getPatternByName,
|
|
6
|
+
getSupportedServices,
|
|
7
|
+
maskToken
|
|
8
|
+
} from "./chunk-GGNOX6DN.js";
|
|
2
9
|
import {
|
|
3
10
|
hookCommand,
|
|
4
11
|
packageScanner
|
|
5
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-4OT4OY7L.js";
|
|
6
13
|
import {
|
|
7
14
|
copyToClipboard,
|
|
8
15
|
getClipboardInstallInstructions,
|
|
@@ -26,11 +33,11 @@ import {
|
|
|
26
33
|
loginCommand,
|
|
27
34
|
logout,
|
|
28
35
|
twoFactorService
|
|
29
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-IWDZCN4S.js";
|
|
30
37
|
import {
|
|
31
38
|
colors,
|
|
32
39
|
log
|
|
33
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-UABU5VVI.js";
|
|
34
41
|
import {
|
|
35
42
|
api,
|
|
36
43
|
enableDebug
|
|
@@ -126,7 +133,7 @@ import {
|
|
|
126
133
|
} from "./chunk-3RG5ZIWI.js";
|
|
127
134
|
|
|
128
135
|
// src/index.ts
|
|
129
|
-
import { Command as
|
|
136
|
+
import { Command as Command40 } from "commander";
|
|
130
137
|
import * as readline from "readline";
|
|
131
138
|
|
|
132
139
|
// src/services/onboarding/welcome.ts
|
|
@@ -264,7 +271,7 @@ async function promptLogin() {
|
|
|
264
271
|
log.newline();
|
|
265
272
|
log.info("\xD6ffne Browser f\xFCr Anmeldung...");
|
|
266
273
|
log.newline();
|
|
267
|
-
const { loginCommand: loginCommand2 } = await import("./login-
|
|
274
|
+
const { loginCommand: loginCommand2 } = await import("./login-DBN2L25M.js");
|
|
268
275
|
await loginCommand2.parseAsync(["login"], { from: "user" });
|
|
269
276
|
return isAuthenticated();
|
|
270
277
|
}
|
|
@@ -336,7 +343,7 @@ async function promptHooks() {
|
|
|
336
343
|
if (installHooks) {
|
|
337
344
|
log.newline();
|
|
338
345
|
log.info("Installiere Hooks...");
|
|
339
|
-
const { hookCommand: hookCommand2 } = await import("./hook-
|
|
346
|
+
const { hookCommand: hookCommand2 } = await import("./hook-CCATCFG7.js");
|
|
340
347
|
await hookCommand2.parseAsync(["hook", "install", "--all"], { from: "user" });
|
|
341
348
|
onboardingStore.set("hooksInstalled", true);
|
|
342
349
|
return true;
|
|
@@ -1488,133 +1495,35 @@ function fromError(error, fallbackCode = "UNKNOWN") {
|
|
|
1488
1495
|
// src/commands/project/sync.ts
|
|
1489
1496
|
var syncCommand = new Command4("sync").description("Projekt mit Cloud synchronisieren").option("-d, --dir <directory>", "Projektverzeichnis", ".").option("--pull", "Nur von Cloud herunterladen").option("--push", "Nur zu Cloud hochladen").option("-a, --all", "Alle Projekte synchronisieren").option("-q, --quiet", "Keine Ausgabe (f\xFCr Hooks)").action(async (options) => {
|
|
1490
1497
|
const quiet = options.quiet;
|
|
1491
|
-
if (!isAuthenticated()) {
|
|
1492
|
-
if (!quiet) log.errorWithSuggestion(Errors.NOT_AUTHENTICATED());
|
|
1493
|
-
process.exit(quiet ? 0 : 1);
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
if (options.all) {
|
|
1497
|
-
await syncAllProjects(options);
|
|
1498
|
-
return;
|
|
1499
|
-
}
|
|
1500
|
-
const projectDir = resolve4(options.dir);
|
|
1501
|
-
if (!existsSync5(projectDir)) {
|
|
1502
|
-
if (!quiet) log.error(`Verzeichnis nicht gefunden: ${projectDir}`);
|
|
1503
|
-
process.exit(quiet ? 0 : 1);
|
|
1504
|
-
return;
|
|
1505
|
-
}
|
|
1506
|
-
const spinner = quiet ? null : ora2("Synchronisiere...").start();
|
|
1507
|
-
let scanned;
|
|
1508
1498
|
try {
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
spinner?.fail("Fehler beim Scannen");
|
|
1512
|
-
process.exit(quiet ? 0 : 1);
|
|
1513
|
-
return;
|
|
1514
|
-
}
|
|
1515
|
-
let project = await api.findProjectByPath(scanned.path);
|
|
1516
|
-
if (!project) {
|
|
1517
|
-
if (spinner) spinner.text = "Erstelle Projekt...";
|
|
1518
|
-
try {
|
|
1519
|
-
const result = await api.createOrUpdateProject({
|
|
1520
|
-
name: scanned.name,
|
|
1521
|
-
path: scanned.path,
|
|
1522
|
-
description: scanned.description,
|
|
1523
|
-
metadata: {
|
|
1524
|
-
language: scanned.language,
|
|
1525
|
-
framework: scanned.framework,
|
|
1526
|
-
packageManager: scanned.packageManager
|
|
1527
|
-
},
|
|
1528
|
-
claude_md_content: scanned.claudeMdContent
|
|
1529
|
-
});
|
|
1530
|
-
project = await api.getProject(result.projectId);
|
|
1531
|
-
} catch (error) {
|
|
1532
|
-
spinner?.fail("Fehler beim Erstellen");
|
|
1533
|
-
if (!quiet) log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
|
|
1499
|
+
if (!isAuthenticated()) {
|
|
1500
|
+
if (!quiet) log.errorWithSuggestion(Errors.NOT_AUTHENTICATED());
|
|
1534
1501
|
process.exit(quiet ? 0 : 1);
|
|
1535
1502
|
return;
|
|
1536
1503
|
}
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
const
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
if (!options.pull) {
|
|
1545
|
-
if (spinner) spinner.text = "Hochladen...";
|
|
1546
|
-
try {
|
|
1547
|
-
await api.syncProject(project.id, {
|
|
1548
|
-
claude_md_content: scanned.claudeMdContent,
|
|
1549
|
-
metadata: {
|
|
1550
|
-
language: scanned.language,
|
|
1551
|
-
framework: scanned.framework,
|
|
1552
|
-
packageManager: scanned.packageManager
|
|
1553
|
-
},
|
|
1554
|
-
memories
|
|
1555
|
-
});
|
|
1556
|
-
} catch (error) {
|
|
1557
|
-
spinner?.fail("Fehler beim Hochladen");
|
|
1558
|
-
if (!quiet) log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
|
|
1504
|
+
if (options.all) {
|
|
1505
|
+
await syncAllProjects(options);
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
const projectDir = resolve4(options.dir);
|
|
1509
|
+
if (!existsSync5(projectDir)) {
|
|
1510
|
+
if (!quiet) log.error(`Verzeichnis nicht gefunden: ${projectDir}`);
|
|
1559
1511
|
process.exit(quiet ? 0 : 1);
|
|
1560
1512
|
return;
|
|
1561
1513
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
if (spinner) spinner.text = "Aktualisiere CLAUDE.md...";
|
|
1514
|
+
const spinner = quiet ? null : ora2("Synchronisiere...").start();
|
|
1515
|
+
let scanned;
|
|
1565
1516
|
try {
|
|
1566
|
-
|
|
1567
|
-
const newClaudeMd = generateClaudeMd(scanned, project);
|
|
1568
|
-
const claudeMdPath = resolve4(projectDir, "CLAUDE.md");
|
|
1569
|
-
writeFileSync2(claudeMdPath, newClaudeMd);
|
|
1517
|
+
scanned = await scanProject(projectDir);
|
|
1570
1518
|
} catch (error) {
|
|
1571
|
-
spinner?.fail("Fehler beim
|
|
1572
|
-
if (!quiet) log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
|
|
1519
|
+
spinner?.fail("Fehler beim Scannen");
|
|
1573
1520
|
process.exit(quiet ? 0 : 1);
|
|
1574
1521
|
return;
|
|
1575
1522
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
log.tree.item("CLAUDE.md aktualisiert");
|
|
1581
|
-
log.tree.item(`${project.memories?.length || 0} Memories synchronisiert`);
|
|
1582
|
-
log.tree.item("Metadata aktualisiert", true);
|
|
1583
|
-
log.newline();
|
|
1584
|
-
log.success(`Sync erfolgreich (${(/* @__PURE__ */ new Date()).toLocaleTimeString()})`);
|
|
1585
|
-
}
|
|
1586
|
-
});
|
|
1587
|
-
async function syncAllProjects(options) {
|
|
1588
|
-
const quiet = options.quiet;
|
|
1589
|
-
const allProjects = await getAllClaudeProjects();
|
|
1590
|
-
const validProjects = allProjects.filter((p) => existsSync5(p.absolutePath));
|
|
1591
|
-
if (validProjects.length === 0) {
|
|
1592
|
-
if (!quiet) {
|
|
1593
|
-
log.warn("Keine synchronisierbaren Projekte gefunden");
|
|
1594
|
-
log.info("Projekte m\xFCssen lokal existieren");
|
|
1595
|
-
}
|
|
1596
|
-
return;
|
|
1597
|
-
}
|
|
1598
|
-
if (!quiet) {
|
|
1599
|
-
log.newline();
|
|
1600
|
-
console.log(colors.orange.bold("SHIVA Code - Batch Sync"));
|
|
1601
|
-
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"));
|
|
1602
|
-
log.newline();
|
|
1603
|
-
log.dim(`${validProjects.length} Projekte gefunden`);
|
|
1604
|
-
log.newline();
|
|
1605
|
-
}
|
|
1606
|
-
const results = [];
|
|
1607
|
-
const spinner = quiet ? null : ora2("Synchronisiere...").start();
|
|
1608
|
-
for (let i = 0; i < validProjects.length; i++) {
|
|
1609
|
-
const project = validProjects[i];
|
|
1610
|
-
const projectDir = project.absolutePath;
|
|
1611
|
-
if (spinner) {
|
|
1612
|
-
spinner.text = `Synchronisiere ${project.projectName} (${i + 1}/${validProjects.length})...`;
|
|
1613
|
-
}
|
|
1614
|
-
try {
|
|
1615
|
-
const scanned = await scanProject(projectDir);
|
|
1616
|
-
let cloudProject = await api.findProjectByPath(scanned.path);
|
|
1617
|
-
if (!cloudProject) {
|
|
1523
|
+
let project = await api.findProjectByPath(scanned.path);
|
|
1524
|
+
if (!project) {
|
|
1525
|
+
if (spinner) spinner.text = "Erstelle Projekt...";
|
|
1526
|
+
try {
|
|
1618
1527
|
const result = await api.createOrUpdateProject({
|
|
1619
1528
|
name: scanned.name,
|
|
1620
1529
|
path: scanned.path,
|
|
@@ -1626,16 +1535,24 @@ async function syncAllProjects(options) {
|
|
|
1626
1535
|
},
|
|
1627
1536
|
claude_md_content: scanned.claudeMdContent
|
|
1628
1537
|
});
|
|
1629
|
-
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
memories = parsed.memories;
|
|
1538
|
+
project = await api.getProject(result.projectId);
|
|
1539
|
+
} catch (error) {
|
|
1540
|
+
spinner?.fail("Fehler beim Erstellen");
|
|
1541
|
+
if (!quiet) log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
|
|
1542
|
+
process.exit(quiet ? 0 : 1);
|
|
1543
|
+
return;
|
|
1636
1544
|
}
|
|
1637
|
-
|
|
1638
|
-
|
|
1545
|
+
}
|
|
1546
|
+
updateProjectConfig(projectDir, { projectId: project.id });
|
|
1547
|
+
let memories = [];
|
|
1548
|
+
if (scanned.claudeMdContent) {
|
|
1549
|
+
const parsed = parseClaudeMd(scanned.claudeMdContent);
|
|
1550
|
+
memories = parsed.memories;
|
|
1551
|
+
}
|
|
1552
|
+
if (!options.pull) {
|
|
1553
|
+
if (spinner) spinner.text = "Hochladen...";
|
|
1554
|
+
try {
|
|
1555
|
+
await api.syncProject(project.id, {
|
|
1639
1556
|
claude_md_content: scanned.claudeMdContent,
|
|
1640
1557
|
metadata: {
|
|
1641
1558
|
language: scanned.language,
|
|
@@ -1644,43 +1561,147 @@ async function syncAllProjects(options) {
|
|
|
1644
1561
|
},
|
|
1645
1562
|
memories
|
|
1646
1563
|
});
|
|
1564
|
+
} catch (error) {
|
|
1565
|
+
spinner?.fail("Fehler beim Hochladen");
|
|
1566
|
+
if (!quiet) log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
|
|
1567
|
+
process.exit(quiet ? 0 : 1);
|
|
1568
|
+
return;
|
|
1647
1569
|
}
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1570
|
+
}
|
|
1571
|
+
if (!options.push) {
|
|
1572
|
+
if (spinner) spinner.text = "Aktualisiere CLAUDE.md...";
|
|
1573
|
+
try {
|
|
1574
|
+
project = await api.getProject(project.id);
|
|
1575
|
+
const newClaudeMd = generateClaudeMd(scanned, project);
|
|
1651
1576
|
const claudeMdPath = resolve4(projectDir, "CLAUDE.md");
|
|
1652
1577
|
writeFileSync2(claudeMdPath, newClaudeMd);
|
|
1578
|
+
} catch (error) {
|
|
1579
|
+
spinner?.fail("Fehler beim Aktualisieren");
|
|
1580
|
+
if (!quiet) log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
|
|
1581
|
+
process.exit(quiet ? 0 : 1);
|
|
1582
|
+
return;
|
|
1653
1583
|
}
|
|
1654
|
-
results.push({ project: project.projectName, success: true });
|
|
1655
|
-
} catch (error) {
|
|
1656
|
-
const shivaError = fromError(error);
|
|
1657
|
-
results.push({
|
|
1658
|
-
project: project.projectName,
|
|
1659
|
-
success: false,
|
|
1660
|
-
error: shivaError.message
|
|
1661
|
-
});
|
|
1662
1584
|
}
|
|
1585
|
+
spinner?.succeed("Synchronisiert");
|
|
1586
|
+
if (!quiet) {
|
|
1587
|
+
log.newline();
|
|
1588
|
+
log.tree.item("CLAUDE.md aktualisiert");
|
|
1589
|
+
log.tree.item(`${project.memories?.length || 0} Memories synchronisiert`);
|
|
1590
|
+
log.tree.item("Metadata aktualisiert", true);
|
|
1591
|
+
log.newline();
|
|
1592
|
+
log.success(`Sync erfolgreich (${(/* @__PURE__ */ new Date()).toLocaleTimeString()})`);
|
|
1593
|
+
}
|
|
1594
|
+
} catch (error) {
|
|
1595
|
+
if (quiet) {
|
|
1596
|
+
process.exit(0);
|
|
1597
|
+
}
|
|
1598
|
+
throw error;
|
|
1663
1599
|
}
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
const
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1600
|
+
});
|
|
1601
|
+
async function syncAllProjects(options) {
|
|
1602
|
+
const quiet = options.quiet;
|
|
1603
|
+
try {
|
|
1604
|
+
const allProjects = await getAllClaudeProjects();
|
|
1605
|
+
const validProjects = allProjects.filter((p) => existsSync5(p.absolutePath));
|
|
1606
|
+
if (validProjects.length === 0) {
|
|
1607
|
+
if (!quiet) {
|
|
1608
|
+
log.warn("Keine synchronisierbaren Projekte gefunden");
|
|
1609
|
+
log.info("Projekte m\xFCssen lokal existieren");
|
|
1610
|
+
}
|
|
1611
|
+
return;
|
|
1612
|
+
}
|
|
1613
|
+
if (!quiet) {
|
|
1614
|
+
log.newline();
|
|
1615
|
+
console.log(colors.orange.bold("SHIVA Code - Batch Sync"));
|
|
1616
|
+
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"));
|
|
1617
|
+
log.newline();
|
|
1618
|
+
log.dim(`${validProjects.length} Projekte gefunden`);
|
|
1619
|
+
log.newline();
|
|
1620
|
+
}
|
|
1621
|
+
const results = [];
|
|
1622
|
+
const spinner = quiet ? null : ora2("Synchronisiere...").start();
|
|
1623
|
+
for (let i = 0; i < validProjects.length; i++) {
|
|
1624
|
+
const project = validProjects[i];
|
|
1625
|
+
const projectDir = project.absolutePath;
|
|
1626
|
+
if (spinner) {
|
|
1627
|
+
spinner.text = `Synchronisiere ${project.projectName} (${i + 1}/${validProjects.length})...`;
|
|
1628
|
+
}
|
|
1629
|
+
try {
|
|
1630
|
+
const scanned = await scanProject(projectDir);
|
|
1631
|
+
let cloudProject = await api.findProjectByPath(scanned.path);
|
|
1632
|
+
if (!cloudProject) {
|
|
1633
|
+
const result = await api.createOrUpdateProject({
|
|
1634
|
+
name: scanned.name,
|
|
1635
|
+
path: scanned.path,
|
|
1636
|
+
description: scanned.description,
|
|
1637
|
+
metadata: {
|
|
1638
|
+
language: scanned.language,
|
|
1639
|
+
framework: scanned.framework,
|
|
1640
|
+
packageManager: scanned.packageManager
|
|
1641
|
+
},
|
|
1642
|
+
claude_md_content: scanned.claudeMdContent
|
|
1643
|
+
});
|
|
1644
|
+
cloudProject = await api.getProject(result.projectId);
|
|
1645
|
+
}
|
|
1646
|
+
updateProjectConfig(projectDir, { projectId: cloudProject.id });
|
|
1647
|
+
let memories = [];
|
|
1648
|
+
if (scanned.claudeMdContent) {
|
|
1649
|
+
const parsed = parseClaudeMd(scanned.claudeMdContent);
|
|
1650
|
+
memories = parsed.memories;
|
|
1651
|
+
}
|
|
1652
|
+
if (!options.pull) {
|
|
1653
|
+
await api.syncProject(cloudProject.id, {
|
|
1654
|
+
claude_md_content: scanned.claudeMdContent,
|
|
1655
|
+
metadata: {
|
|
1656
|
+
language: scanned.language,
|
|
1657
|
+
framework: scanned.framework,
|
|
1658
|
+
packageManager: scanned.packageManager
|
|
1659
|
+
},
|
|
1660
|
+
memories
|
|
1661
|
+
});
|
|
1662
|
+
}
|
|
1663
|
+
if (!options.push) {
|
|
1664
|
+
cloudProject = await api.getProject(cloudProject.id);
|
|
1665
|
+
const newClaudeMd = generateClaudeMd(scanned, cloudProject);
|
|
1666
|
+
const claudeMdPath = resolve4(projectDir, "CLAUDE.md");
|
|
1667
|
+
writeFileSync2(claudeMdPath, newClaudeMd);
|
|
1668
|
+
}
|
|
1669
|
+
results.push({ project: project.projectName, success: true });
|
|
1670
|
+
} catch (error) {
|
|
1671
|
+
const shivaError = fromError(error);
|
|
1672
|
+
results.push({
|
|
1673
|
+
project: project.projectName,
|
|
1674
|
+
success: false,
|
|
1675
|
+
error: shivaError.message
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
spinner?.stop();
|
|
1680
|
+
if (!quiet) {
|
|
1681
|
+
log.newline();
|
|
1682
|
+
const successCount = results.filter((r) => r.success).length;
|
|
1683
|
+
const failCount = results.filter((r) => !r.success).length;
|
|
1684
|
+
for (const result of results) {
|
|
1685
|
+
if (result.success) {
|
|
1686
|
+
console.log(` ${colors.green("\u2713")} ${result.project}`);
|
|
1687
|
+
} else {
|
|
1688
|
+
console.log(` ${colors.red("\u2717")} ${result.project}: ${result.error}`);
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
log.newline();
|
|
1692
|
+
log.separator("\u2500", 40);
|
|
1693
|
+
if (failCount === 0) {
|
|
1694
|
+
log.success(`Alle ${successCount} Projekte synchronisiert`);
|
|
1672
1695
|
} else {
|
|
1673
|
-
|
|
1696
|
+
log.warn(`${successCount} erfolgreich, ${failCount} fehlgeschlagen`);
|
|
1674
1697
|
}
|
|
1698
|
+
log.newline();
|
|
1675
1699
|
}
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
log.success(`Alle ${successCount} Projekte synchronisiert`);
|
|
1680
|
-
} else {
|
|
1681
|
-
log.warn(`${successCount} erfolgreich, ${failCount} fehlgeschlagen`);
|
|
1700
|
+
} catch (error) {
|
|
1701
|
+
if (quiet) {
|
|
1702
|
+
process.exit(0);
|
|
1682
1703
|
}
|
|
1683
|
-
|
|
1704
|
+
throw error;
|
|
1684
1705
|
}
|
|
1685
1706
|
}
|
|
1686
1707
|
|
|
@@ -8944,7 +8965,19 @@ var tfaCommand = new Command19("2fa").description("Zwei-Faktor-Authentifizierung
|
|
|
8944
8965
|
log.error("Ung\xFCltiger Code. 2FA wurde nicht aktiviert.");
|
|
8945
8966
|
}
|
|
8946
8967
|
} catch (error) {
|
|
8947
|
-
|
|
8968
|
+
const message = error instanceof Error ? error.message : "";
|
|
8969
|
+
if (message.toLowerCase().includes("passkey")) {
|
|
8970
|
+
log.error("Passkey erforderlich!");
|
|
8971
|
+
log.newline();
|
|
8972
|
+
log.info("2FA erfordert zuerst einen registrierten Passkey.");
|
|
8973
|
+
log.info("Registriere einen Passkey auf: https://shiva.li/settings/security");
|
|
8974
|
+
log.newline();
|
|
8975
|
+
} else {
|
|
8976
|
+
log.error("2FA-Setup fehlgeschlagen");
|
|
8977
|
+
if (message) {
|
|
8978
|
+
log.dim(message);
|
|
8979
|
+
}
|
|
8980
|
+
}
|
|
8948
8981
|
}
|
|
8949
8982
|
return;
|
|
8950
8983
|
}
|
|
@@ -9431,8 +9464,181 @@ secretsCommand.command("export").description("Secrets exportieren").option("-p,
|
|
|
9431
9464
|
}
|
|
9432
9465
|
});
|
|
9433
9466
|
|
|
9434
|
-
// src/commands/
|
|
9467
|
+
// src/commands/security/secure-token.ts
|
|
9435
9468
|
import { Command as Command21 } from "commander";
|
|
9469
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
9470
|
+
import inquirer8 from "inquirer";
|
|
9471
|
+
var secureTokenCommand = new Command21("secure-token").description("Token sicher speichern und konfigurieren").argument("[service]", "Service-Name (npm, github, openai, etc.)").argument("[token]", "Der Token (wird im Secrets Vault gespeichert)").option("-l, --list", "Unterst\xFCtzte Services auflisten").option("--no-configure", "Token nur speichern, nicht konfigurieren").option("--detect <text>", "Tokens in Text erkennen").addHelpText("after", `
|
|
9472
|
+
Beispiele:
|
|
9473
|
+
$ shiva secure-token npm npm_abc123... # NPM Token speichern & konfigurieren
|
|
9474
|
+
$ shiva secure-token github ghp_xxx... # GitHub Token speichern
|
|
9475
|
+
$ shiva secure-token openai sk-xxx... # OpenAI Key speichern
|
|
9476
|
+
$ shiva secure-token --list # Alle unterst\xFCtzten Services
|
|
9477
|
+
$ shiva secure-token --detect "text..." # Tokens in Text finden
|
|
9478
|
+
|
|
9479
|
+
Unterst\xFCtzte Services:
|
|
9480
|
+
npm, github, openai, anthropic, aws, gcp, stripe, slack, discord, twilio, sendgrid
|
|
9481
|
+
|
|
9482
|
+
Sicherheit:
|
|
9483
|
+
- Tokens werden mit AES-256-GCM verschl\xFCsselt
|
|
9484
|
+
- Tokens werden NICHT in der Chat-History gespeichert
|
|
9485
|
+
- Automatische Konfiguration wo m\xF6glich (z.B. npm config)
|
|
9486
|
+
`).action(async (service, token, options) => {
|
|
9487
|
+
if (options.list) {
|
|
9488
|
+
log.newline();
|
|
9489
|
+
console.log(colors.orange.bold("Unterst\xFCtzte Token-Typen"));
|
|
9490
|
+
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"));
|
|
9491
|
+
log.newline();
|
|
9492
|
+
for (const pattern2 of TOKEN_PATTERNS) {
|
|
9493
|
+
const configurable = pattern2.configCommand ? colors.green(" [Auto-Config]") : "";
|
|
9494
|
+
console.log(` ${colors.cyan(pattern2.name.padEnd(15))} ${pattern2.description}${configurable}`);
|
|
9495
|
+
}
|
|
9496
|
+
log.newline();
|
|
9497
|
+
log.dim("Services mit [Auto-Config] werden automatisch konfiguriert.");
|
|
9498
|
+
log.newline();
|
|
9499
|
+
return;
|
|
9500
|
+
}
|
|
9501
|
+
if (options.detect) {
|
|
9502
|
+
const detected = detectTokens(options.detect);
|
|
9503
|
+
if (detected.length === 0) {
|
|
9504
|
+
log.info("Keine Tokens erkannt.");
|
|
9505
|
+
return;
|
|
9506
|
+
}
|
|
9507
|
+
log.newline();
|
|
9508
|
+
log.warn(`${detected.length} Token(s) erkannt:`);
|
|
9509
|
+
log.newline();
|
|
9510
|
+
for (const d of detected) {
|
|
9511
|
+
console.log(` ${colors.red("!")} ${d.pattern.description}: ${colors.dim(maskToken(d.token))}`);
|
|
9512
|
+
}
|
|
9513
|
+
log.newline();
|
|
9514
|
+
log.info('Verwende "shiva secure-token <service> <token>" um sie sicher zu speichern.');
|
|
9515
|
+
log.newline();
|
|
9516
|
+
return;
|
|
9517
|
+
}
|
|
9518
|
+
if (!isAuthenticated()) {
|
|
9519
|
+
log.errorWithSuggestion(Errors.NOT_AUTHENTICATED());
|
|
9520
|
+
process.exit(1);
|
|
9521
|
+
return;
|
|
9522
|
+
}
|
|
9523
|
+
if (!service || !token) {
|
|
9524
|
+
const result = await interactiveSecureToken();
|
|
9525
|
+
if (!result) {
|
|
9526
|
+
process.exit(1);
|
|
9527
|
+
}
|
|
9528
|
+
return;
|
|
9529
|
+
}
|
|
9530
|
+
const pattern = getPatternByName(service);
|
|
9531
|
+
if (!pattern) {
|
|
9532
|
+
log.error(`Unbekannter Service: ${service}`);
|
|
9533
|
+
log.newline();
|
|
9534
|
+
log.info("Unterst\xFCtzte Services:");
|
|
9535
|
+
console.log(` ${getSupportedServices().join(", ")}`);
|
|
9536
|
+
log.newline();
|
|
9537
|
+
log.dim('Oder verwende "shiva secure-token --list" f\xFCr Details.');
|
|
9538
|
+
process.exit(1);
|
|
9539
|
+
return;
|
|
9540
|
+
}
|
|
9541
|
+
pattern.pattern.lastIndex = 0;
|
|
9542
|
+
if (!pattern.pattern.test(token)) {
|
|
9543
|
+
log.warn(`Token-Format sieht nicht wie ein ${pattern.description} aus.`);
|
|
9544
|
+
const { proceed } = await inquirer8.prompt([{
|
|
9545
|
+
type: "confirm",
|
|
9546
|
+
name: "proceed",
|
|
9547
|
+
message: "Trotzdem fortfahren?",
|
|
9548
|
+
default: false
|
|
9549
|
+
}]);
|
|
9550
|
+
if (!proceed) {
|
|
9551
|
+
return;
|
|
9552
|
+
}
|
|
9553
|
+
}
|
|
9554
|
+
await storeAndConfigureToken(service, token, pattern, options.configure);
|
|
9555
|
+
});
|
|
9556
|
+
async function interactiveSecureToken() {
|
|
9557
|
+
log.newline();
|
|
9558
|
+
console.log(colors.orange.bold("SHIVA Secure Token"));
|
|
9559
|
+
console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
9560
|
+
log.newline();
|
|
9561
|
+
const serviceChoices = TOKEN_PATTERNS.filter((p, i, arr) => arr.findIndex((x) => x.name === p.name) === i).map((p) => ({
|
|
9562
|
+
name: `${p.name} - ${p.description}${p.configCommand ? " [Auto-Config]" : ""}`,
|
|
9563
|
+
value: p.name
|
|
9564
|
+
}));
|
|
9565
|
+
const { service } = await inquirer8.prompt([{
|
|
9566
|
+
type: "list",
|
|
9567
|
+
name: "service",
|
|
9568
|
+
message: "Welcher Service?",
|
|
9569
|
+
choices: serviceChoices
|
|
9570
|
+
}]);
|
|
9571
|
+
const { token } = await inquirer8.prompt([{
|
|
9572
|
+
type: "password",
|
|
9573
|
+
name: "token",
|
|
9574
|
+
message: "Token eingeben:",
|
|
9575
|
+
mask: "*",
|
|
9576
|
+
validate: (input) => input.length > 0 || "Token darf nicht leer sein"
|
|
9577
|
+
}]);
|
|
9578
|
+
const pattern = getPatternByName(service);
|
|
9579
|
+
let configure = true;
|
|
9580
|
+
if (pattern.configCommand) {
|
|
9581
|
+
const { shouldConfigure } = await inquirer8.prompt([{
|
|
9582
|
+
type: "confirm",
|
|
9583
|
+
name: "shouldConfigure",
|
|
9584
|
+
message: `${pattern.service} automatisch konfigurieren?`,
|
|
9585
|
+
default: true
|
|
9586
|
+
}]);
|
|
9587
|
+
configure = shouldConfigure;
|
|
9588
|
+
}
|
|
9589
|
+
return storeAndConfigureToken(service, token, pattern, configure);
|
|
9590
|
+
}
|
|
9591
|
+
async function storeAndConfigureToken(service, token, pattern, configure) {
|
|
9592
|
+
const secretKey = `${service.toUpperCase()}_TOKEN`;
|
|
9593
|
+
log.newline();
|
|
9594
|
+
try {
|
|
9595
|
+
log.info("Speichere Token im Secrets Vault...");
|
|
9596
|
+
await api.addSecret({
|
|
9597
|
+
key: secretKey,
|
|
9598
|
+
value: token,
|
|
9599
|
+
description: pattern.description
|
|
9600
|
+
});
|
|
9601
|
+
log.success(`Token als "${secretKey}" gespeichert`);
|
|
9602
|
+
} catch (error) {
|
|
9603
|
+
const message = error instanceof Error ? error.message : "Unbekannter Fehler";
|
|
9604
|
+
log.error(`Fehler beim Speichern: ${message}`);
|
|
9605
|
+
return false;
|
|
9606
|
+
}
|
|
9607
|
+
if (configure && pattern.configCommand) {
|
|
9608
|
+
log.newline();
|
|
9609
|
+
log.info(`Konfiguriere ${pattern.service}...`);
|
|
9610
|
+
try {
|
|
9611
|
+
const [cmd, ...args2] = pattern.configCommand(token);
|
|
9612
|
+
const result = spawnSync6(cmd, args2, {
|
|
9613
|
+
encoding: "utf-8",
|
|
9614
|
+
timeout: 3e4
|
|
9615
|
+
});
|
|
9616
|
+
if (result.status === 0) {
|
|
9617
|
+
log.success(`${pattern.service} konfiguriert`);
|
|
9618
|
+
} else {
|
|
9619
|
+
log.warn(`Konfiguration fehlgeschlagen: ${result.stderr || "Unbekannter Fehler"}`);
|
|
9620
|
+
log.dim(`Manuell konfigurieren: ${pattern.configCommand("{TOKEN}").join(" ")}`);
|
|
9621
|
+
}
|
|
9622
|
+
} catch (error) {
|
|
9623
|
+
log.warn("Automatische Konfiguration fehlgeschlagen");
|
|
9624
|
+
log.dim(`Manuell konfigurieren: ${pattern.configCommand("{TOKEN}").join(" ")}`);
|
|
9625
|
+
}
|
|
9626
|
+
}
|
|
9627
|
+
log.newline();
|
|
9628
|
+
console.log(colors.green("\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\u2500\u2500\u2500"));
|
|
9629
|
+
log.success("Token sicher gespeichert!");
|
|
9630
|
+
log.newline();
|
|
9631
|
+
log.dim(`Service: ${pattern.service}`);
|
|
9632
|
+
log.dim(`Secret: ${secretKey}`);
|
|
9633
|
+
log.dim(`Token: ${maskToken(token)}`);
|
|
9634
|
+
log.newline();
|
|
9635
|
+
log.info("Der Token ist jetzt sicher und wurde NICHT in der Chat-History gespeichert.");
|
|
9636
|
+
log.newline();
|
|
9637
|
+
return true;
|
|
9638
|
+
}
|
|
9639
|
+
|
|
9640
|
+
// src/commands/memory/search.ts
|
|
9641
|
+
import { Command as Command22 } from "commander";
|
|
9436
9642
|
import ora15 from "ora";
|
|
9437
9643
|
|
|
9438
9644
|
// src/services/data/memory.ts
|
|
@@ -9720,7 +9926,7 @@ function escapeRegex(str) {
|
|
|
9720
9926
|
}
|
|
9721
9927
|
|
|
9722
9928
|
// src/commands/memory/search.ts
|
|
9723
|
-
var searchCommand = new
|
|
9929
|
+
var searchCommand = new Command22("search").description("Memories \xFCber alle Projekte durchsuchen").argument("<query>", "Suchbegriff").option("-c, --category <category>", "Nach Kategorie filtern (general, preference, decision, context)").option("-p, --project <name>", "In bestimmtem Projekt suchen").option("-s, --source <source>", "Quelle: local, cloud, all (default: all)").option("-l, --limit <n>", "Max. Ergebnisse (default: 50)", "50").option("--case-sensitive", "Gro\xDF-/Kleinschreibung beachten").option("--json", "JSON Ausgabe").action(async (query, options) => {
|
|
9724
9930
|
const spinner = ora15("Durchsuche Memories...").start();
|
|
9725
9931
|
try {
|
|
9726
9932
|
const result = await searchMemories(query, {
|
|
@@ -9793,11 +9999,11 @@ function escapeRegex2(str) {
|
|
|
9793
9999
|
}
|
|
9794
10000
|
|
|
9795
10001
|
// src/commands/memory/forget.ts
|
|
9796
|
-
import { Command as
|
|
10002
|
+
import { Command as Command23 } from "commander";
|
|
9797
10003
|
import * as path8 from "path";
|
|
9798
|
-
import
|
|
10004
|
+
import inquirer9 from "inquirer";
|
|
9799
10005
|
import ora16 from "ora";
|
|
9800
|
-
var forgetCommand = new
|
|
10006
|
+
var forgetCommand = new Command23("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) => {
|
|
9801
10007
|
log.newline();
|
|
9802
10008
|
console.log(colors.orange.bold("SHIVA Code - Forget"));
|
|
9803
10009
|
console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
@@ -9830,7 +10036,7 @@ async function handleDeleteAll(projectPath, options) {
|
|
|
9830
10036
|
return;
|
|
9831
10037
|
}
|
|
9832
10038
|
if (!options.force) {
|
|
9833
|
-
const { confirm } = await
|
|
10039
|
+
const { confirm } = await inquirer9.prompt([{
|
|
9834
10040
|
type: "confirm",
|
|
9835
10041
|
name: "confirm",
|
|
9836
10042
|
message: "Wirklich ALLE Memories l\xF6schen?",
|
|
@@ -9840,7 +10046,7 @@ async function handleDeleteAll(projectPath, options) {
|
|
|
9840
10046
|
log.dim("Abgebrochen");
|
|
9841
10047
|
return;
|
|
9842
10048
|
}
|
|
9843
|
-
const { confirmAgain } = await
|
|
10049
|
+
const { confirmAgain } = await inquirer9.prompt([{
|
|
9844
10050
|
type: "input",
|
|
9845
10051
|
name: "confirmAgain",
|
|
9846
10052
|
message: `Zur Best\xE4tigung "${projectName}" eingeben:`
|
|
@@ -9888,7 +10094,7 @@ async function handleDeleteBySearch(query, projectPath, options) {
|
|
|
9888
10094
|
return;
|
|
9889
10095
|
}
|
|
9890
10096
|
if (!options.force) {
|
|
9891
|
-
const { confirm } = await
|
|
10097
|
+
const { confirm } = await inquirer9.prompt([{
|
|
9892
10098
|
type: "confirm",
|
|
9893
10099
|
name: "confirm",
|
|
9894
10100
|
message: `${result.totalCount} Memories l\xF6schen?`,
|
|
@@ -9931,7 +10137,7 @@ async function handleDeleteKey(key, projectPath, options) {
|
|
|
9931
10137
|
return;
|
|
9932
10138
|
}
|
|
9933
10139
|
if (!options.force) {
|
|
9934
|
-
const { confirm } = await
|
|
10140
|
+
const { confirm } = await inquirer9.prompt([{
|
|
9935
10141
|
type: "confirm",
|
|
9936
10142
|
name: "confirm",
|
|
9937
10143
|
message: `Memory "${key}" l\xF6schen?`,
|
|
@@ -9976,7 +10182,7 @@ async function handleInteractiveDelete(projectPath, options) {
|
|
|
9976
10182
|
name: `${memory.projectName.padEnd(20)} ${colors.bold(memory.key.padEnd(25))} ${colors.dim(truncate(memory.value, 30))}`,
|
|
9977
10183
|
value: memory
|
|
9978
10184
|
}));
|
|
9979
|
-
const { selected } = await
|
|
10185
|
+
const { selected } = await inquirer9.prompt([{
|
|
9980
10186
|
type: "checkbox",
|
|
9981
10187
|
name: "selected",
|
|
9982
10188
|
message: "Memories zum L\xF6schen ausw\xE4hlen:",
|
|
@@ -9998,7 +10204,7 @@ async function handleInteractiveDelete(projectPath, options) {
|
|
|
9998
10204
|
return;
|
|
9999
10205
|
}
|
|
10000
10206
|
if (!options.force) {
|
|
10001
|
-
const { confirm } = await
|
|
10207
|
+
const { confirm } = await inquirer9.prompt([{
|
|
10002
10208
|
type: "confirm",
|
|
10003
10209
|
name: "confirm",
|
|
10004
10210
|
message: "Diese Memories l\xF6schen?",
|
|
@@ -10038,11 +10244,11 @@ function truncate(str, maxLen) {
|
|
|
10038
10244
|
}
|
|
10039
10245
|
|
|
10040
10246
|
// src/commands/memory/context.ts
|
|
10041
|
-
import { Command as
|
|
10247
|
+
import { Command as Command24 } from "commander";
|
|
10042
10248
|
import * as path9 from "path";
|
|
10043
10249
|
import * as fs8 from "fs";
|
|
10044
10250
|
import ora17 from "ora";
|
|
10045
|
-
var contextCommand = new
|
|
10251
|
+
var contextCommand = new Command24("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) => {
|
|
10046
10252
|
const projectPath = options.dir ? path9.resolve(options.dir) : process.cwd();
|
|
10047
10253
|
const projectName = path9.basename(projectPath);
|
|
10048
10254
|
if (!fs8.existsSync(projectPath)) {
|
|
@@ -10233,9 +10439,9 @@ function formatGitHubContext(context) {
|
|
|
10233
10439
|
}
|
|
10234
10440
|
|
|
10235
10441
|
// src/commands/memory/tags.ts
|
|
10236
|
-
import { Command as
|
|
10237
|
-
import
|
|
10238
|
-
var tagsCommand = new
|
|
10442
|
+
import { Command as Command25 } from "commander";
|
|
10443
|
+
import inquirer10 from "inquirer";
|
|
10444
|
+
var tagsCommand = new Command25("tags").description("Session-Tags verwalten").action(async () => {
|
|
10239
10445
|
await listTags();
|
|
10240
10446
|
});
|
|
10241
10447
|
tagsCommand.command("list").alias("ls").description("Alle Tags anzeigen").action(async () => {
|
|
@@ -10346,7 +10552,7 @@ tagsCommand.command("delete").description("Tag komplett l\xF6schen").argument("<
|
|
|
10346
10552
|
return;
|
|
10347
10553
|
}
|
|
10348
10554
|
if (!options.force) {
|
|
10349
|
-
const { confirm } = await
|
|
10555
|
+
const { confirm } = await inquirer10.prompt([{
|
|
10350
10556
|
type: "confirm",
|
|
10351
10557
|
name: "confirm",
|
|
10352
10558
|
message: `Tag "${tag}" von ${count} Sessions entfernen?`,
|
|
@@ -10462,11 +10668,11 @@ tagsCommand.command("cloud").description("Memory-Tags aus Cloud laden").option("
|
|
|
10462
10668
|
});
|
|
10463
10669
|
|
|
10464
10670
|
// src/commands/memory/export.ts
|
|
10465
|
-
import { Command as
|
|
10671
|
+
import { Command as Command26 } from "commander";
|
|
10466
10672
|
import * as path11 from "path";
|
|
10467
10673
|
import * as fs10 from "fs";
|
|
10468
10674
|
import ora18 from "ora";
|
|
10469
|
-
import
|
|
10675
|
+
import inquirer11 from "inquirer";
|
|
10470
10676
|
|
|
10471
10677
|
// src/services/session/export.ts
|
|
10472
10678
|
import * as fs9 from "fs";
|
|
@@ -10715,7 +10921,7 @@ function previewExportFile(filepath) {
|
|
|
10715
10921
|
}
|
|
10716
10922
|
|
|
10717
10923
|
// src/commands/memory/export.ts
|
|
10718
|
-
var exportCommand = new
|
|
10924
|
+
var exportCommand = new Command26("export").description("Sessions exportieren").argument("[session-id]", "Session ID (optional)").option("-o, --output <path>", "Ausgabedatei/-verzeichnis").option("-p, --project <name>", "Alle Sessions eines Projekts exportieren").option("-t, --transcript", "Transkript einschlie\xDFen").option("-c, --conversation", "Parsed Conversation einschlie\xDFen").option("--backup", "Vollst\xE4ndiges Backup erstellen (tar.gz)").option("--all", "Alle Sessions exportieren").action(async (sessionId, options) => {
|
|
10719
10925
|
log.newline();
|
|
10720
10926
|
console.log(colors.orange.bold("SHIVA Code - Export"));
|
|
10721
10927
|
console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
@@ -10742,7 +10948,7 @@ var exportCommand = new Command25("export").description("Sessions exportieren").
|
|
|
10742
10948
|
}
|
|
10743
10949
|
await handleInteractiveExport(exportOptions);
|
|
10744
10950
|
});
|
|
10745
|
-
var importCommand = new
|
|
10951
|
+
var importCommand = new Command26("import").description("Sessions importieren").argument("<path>", "Import-Datei oder Verzeichnis").option("-p, --project <path>", "Ziel-Projektpfad").option("--preview", "Nur Vorschau, nicht importieren").option("--restore", "Backup-Archiv wiederherstellen").action(async (inputPath, options) => {
|
|
10746
10952
|
log.newline();
|
|
10747
10953
|
console.log(colors.orange.bold("SHIVA Code - Import"));
|
|
10748
10954
|
console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
@@ -10850,7 +11056,7 @@ async function handleInteractiveExport(options = {}) {
|
|
|
10850
11056
|
value: session.sessionId
|
|
10851
11057
|
};
|
|
10852
11058
|
});
|
|
10853
|
-
const { selectedSession } = await
|
|
11059
|
+
const { selectedSession } = await inquirer11.prompt([{
|
|
10854
11060
|
type: "list",
|
|
10855
11061
|
name: "selectedSession",
|
|
10856
11062
|
message: "Session ausw\xE4hlen:",
|
|
@@ -10884,7 +11090,7 @@ async function handleImportDirectory(dirPath, targetProject) {
|
|
|
10884
11090
|
}
|
|
10885
11091
|
}
|
|
10886
11092
|
async function handleRestore(archivePath, targetDir) {
|
|
10887
|
-
const { confirm } = await
|
|
11093
|
+
const { confirm } = await inquirer11.prompt([{
|
|
10888
11094
|
type: "confirm",
|
|
10889
11095
|
name: "confirm",
|
|
10890
11096
|
message: "Backup wiederherstellen? Bestehende Sessions k\xF6nnen \xFCberschrieben werden.",
|
|
@@ -10934,9 +11140,9 @@ async function handlePreview(filepath) {
|
|
|
10934
11140
|
}
|
|
10935
11141
|
|
|
10936
11142
|
// src/commands/memory/remember.ts
|
|
10937
|
-
import { Command as
|
|
11143
|
+
import { Command as Command27 } from "commander";
|
|
10938
11144
|
var VALID_CATEGORIES = ["identity", "preference", "convention", "solution", "task", "context", "general"];
|
|
10939
|
-
var rememberCommand = new
|
|
11145
|
+
var rememberCommand = new Command27("remember").description("Memory in der Cloud speichern").argument("<text>", "Der Text der gespeichert werden soll").option("-t, --title <title>", "Titel f\xFCr die Memory").option("-c, --category <category>", "Kategorie: identity, preference, convention, solution, task, context, general", "general").option("-g, --global", "Global speichern (nicht projektgebunden)").option("--tags <tags>", "Komma-separierte Tags").option("--ttl <days>", "Time-to-live in Tagen (auto-delete nach Ablauf)").action(async (text, options) => {
|
|
10940
11146
|
if (!isAuthenticated()) {
|
|
10941
11147
|
log.error("Nicht angemeldet");
|
|
10942
11148
|
log.info("Anmelden mit: shiva login");
|
|
@@ -10990,7 +11196,7 @@ var rememberCommand = new Command26("remember").description("Memory in der Cloud
|
|
|
10990
11196
|
});
|
|
10991
11197
|
|
|
10992
11198
|
// src/commands/system/doctor.ts
|
|
10993
|
-
import { Command as
|
|
11199
|
+
import { Command as Command28 } from "commander";
|
|
10994
11200
|
import { execSync as execSync2 } from "child_process";
|
|
10995
11201
|
import * as fs11 from "fs";
|
|
10996
11202
|
import * as path12 from "path";
|
|
@@ -11248,7 +11454,7 @@ function printResult(result) {
|
|
|
11248
11454
|
console.log(` ${colors.dim("\u2192")} ${colors.dim(result.hint)}`);
|
|
11249
11455
|
}
|
|
11250
11456
|
}
|
|
11251
|
-
var doctorCommand = new
|
|
11457
|
+
var doctorCommand = new Command28("doctor").description("System-Check f\xFCr SHIVA und Claude Code").option("-v, --verbose", "Zeige zus\xE4tzliche Details").option("-j, --json", "Ausgabe als JSON").action(async (options) => {
|
|
11252
11458
|
if (!options.json) {
|
|
11253
11459
|
log.newline();
|
|
11254
11460
|
console.log(colors.orange.bold("\u{1F3E5} SHIVA Doctor - System Health Check"));
|
|
@@ -11317,7 +11523,7 @@ var doctorCommand = new Command27("doctor").description("System-Check f\xFCr SHI
|
|
|
11317
11523
|
});
|
|
11318
11524
|
|
|
11319
11525
|
// src/commands/system/upgrade.ts
|
|
11320
|
-
import { Command as
|
|
11526
|
+
import { Command as Command29 } from "commander";
|
|
11321
11527
|
import { execSync as execSync3, spawn as spawn7 } from "child_process";
|
|
11322
11528
|
import * as fs12 from "fs";
|
|
11323
11529
|
import * as path13 from "path";
|
|
@@ -11596,7 +11802,7 @@ async function runPackageManagerUpgrade(pm) {
|
|
|
11596
11802
|
});
|
|
11597
11803
|
});
|
|
11598
11804
|
}
|
|
11599
|
-
var upgradeCommand = new
|
|
11805
|
+
var upgradeCommand = new Command29("upgrade").description("SHIVA CLI aktualisieren").option("-c, --check", "Nur auf Updates pr\xFCfen, nicht installieren").option("-f, --force", "Update erzwingen, auch wenn aktuell").option("--npm", "npm verwenden (f\xFCr npm-Installationen)").option("--yarn", "yarn verwenden").option("--pnpm", "pnpm verwenden").option("--native", "Native Binary Update erzwingen").action(async (options) => {
|
|
11600
11806
|
log.newline();
|
|
11601
11807
|
console.log(colors.orange.bold("\u{1F680} SHIVA Upgrade"));
|
|
11602
11808
|
log.newline();
|
|
@@ -11657,12 +11863,12 @@ var upgradeCommand = new Command28("upgrade").description("SHIVA CLI aktualisier
|
|
|
11657
11863
|
}
|
|
11658
11864
|
}
|
|
11659
11865
|
});
|
|
11660
|
-
var selfUpdateCommand = new
|
|
11866
|
+
var selfUpdateCommand = new Command29("self-update").description('Alias f\xFCr "shiva upgrade"').action(async () => {
|
|
11661
11867
|
await upgradeCommand.parseAsync(["upgrade"], { from: "user" });
|
|
11662
11868
|
});
|
|
11663
11869
|
|
|
11664
11870
|
// src/commands/system/telemetry.ts
|
|
11665
|
-
import { Command as
|
|
11871
|
+
import { Command as Command30 } from "commander";
|
|
11666
11872
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
11667
11873
|
import Conf4 from "conf";
|
|
11668
11874
|
var telemetryConfig = new Conf4({
|
|
@@ -11695,7 +11901,7 @@ var DATA_NOT_COLLECTED = [
|
|
|
11695
11901
|
"Pers\xF6nliche Daten oder IP-Adressen",
|
|
11696
11902
|
"Code oder Datei-Inhalte"
|
|
11697
11903
|
];
|
|
11698
|
-
var telemetryCommand = new
|
|
11904
|
+
var telemetryCommand = new Command30("telemetry").description("Telemetrie/Analytics verwalten").option("--enable", "Telemetrie aktivieren (opt-in)").option("--disable", "Telemetrie deaktivieren (opt-out)").option("--status", "Aktuellen Status anzeigen").option("-j, --json", "Ausgabe als JSON").action((options) => {
|
|
11699
11905
|
const isEnabled = telemetryConfig.get("enabled");
|
|
11700
11906
|
const optInAt = telemetryConfig.get("optInAt");
|
|
11701
11907
|
const optOutAt = telemetryConfig.get("optOutAt");
|
|
@@ -11786,8 +11992,8 @@ var telemetryCommand = new Command29("telemetry").description("Telemetrie/Analyt
|
|
|
11786
11992
|
});
|
|
11787
11993
|
|
|
11788
11994
|
// src/commands/system/completions.ts
|
|
11789
|
-
import { Command as
|
|
11790
|
-
var completionsCommand = new
|
|
11995
|
+
import { Command as Command31 } from "commander";
|
|
11996
|
+
var completionsCommand = new Command31("completions").description("Shell-Completion-Skripte generieren").argument("[shell]", "Shell-Typ: bash, zsh, fish").option("--install", "Direkt installieren (nur bash/zsh)").action(async (shell, options) => {
|
|
11791
11997
|
if (!shell) {
|
|
11792
11998
|
log.newline();
|
|
11793
11999
|
console.log(colors.orange.bold("SHIVA Code - Shell Completions"));
|
|
@@ -12182,9 +12388,9 @@ async function installFishCompletion() {
|
|
|
12182
12388
|
}
|
|
12183
12389
|
|
|
12184
12390
|
// src/commands/system/stats.ts
|
|
12185
|
-
import { Command as
|
|
12391
|
+
import { Command as Command32 } from "commander";
|
|
12186
12392
|
import ora19 from "ora";
|
|
12187
|
-
var statsCommand = new
|
|
12393
|
+
var statsCommand = new Command32("stats").description("Session-Statistiken und Analytics anzeigen").option("-d, --days <n>", "Zeitraum in Tagen", "30").option("--json", "JSON Output").action(async (options) => {
|
|
12188
12394
|
const spinner = ora19("Sammle Statistiken...").start();
|
|
12189
12395
|
try {
|
|
12190
12396
|
const projects = await getAllClaudeProjects();
|
|
@@ -12542,9 +12748,9 @@ statsCommand.command("track").description("Analytics Event tracken").argument("<
|
|
|
12542
12748
|
});
|
|
12543
12749
|
|
|
12544
12750
|
// src/commands/system/user.ts
|
|
12545
|
-
import { Command as
|
|
12751
|
+
import { Command as Command33 } from "commander";
|
|
12546
12752
|
import ora20 from "ora";
|
|
12547
|
-
var userCommand = new
|
|
12753
|
+
var userCommand = new Command33("user").description("User Account Verwaltung");
|
|
12548
12754
|
userCommand.command("profile").description("User-Profil anzeigen").option("--json", "JSON Output").action(async (options) => {
|
|
12549
12755
|
if (!isAuthenticated()) {
|
|
12550
12756
|
log.error("Nicht angemeldet");
|
|
@@ -12701,8 +12907,8 @@ userCommand.command("token").description("Neuen CLI-Token generieren").option("-
|
|
|
12701
12907
|
log.info("Anmelden mit: shiva login");
|
|
12702
12908
|
return;
|
|
12703
12909
|
}
|
|
12704
|
-
const { default:
|
|
12705
|
-
const { confirm } = await
|
|
12910
|
+
const { default: inquirer14 } = await import("inquirer");
|
|
12911
|
+
const { confirm } = await inquirer14.prompt([{
|
|
12706
12912
|
type: "confirm",
|
|
12707
12913
|
name: "confirm",
|
|
12708
12914
|
message: "Neuen Token generieren? Der alte Token wird ung\xFCltig.",
|
|
@@ -12757,8 +12963,8 @@ userCommand.command("delete").description("Account unwiderruflich l\xF6schen").a
|
|
|
12757
12963
|
log.plain(" \u2022 Alle Secrets und Einstellungen");
|
|
12758
12964
|
log.plain(" \u2022 Subscription und Zahlungsdaten");
|
|
12759
12965
|
log.newline();
|
|
12760
|
-
const { default:
|
|
12761
|
-
const { confirm1 } = await
|
|
12966
|
+
const { default: inquirer14 } = await import("inquirer");
|
|
12967
|
+
const { confirm1 } = await inquirer14.prompt([{
|
|
12762
12968
|
type: "confirm",
|
|
12763
12969
|
name: "confirm1",
|
|
12764
12970
|
message: "Bist du sicher, dass du deinen Account l\xF6schen m\xF6chtest?",
|
|
@@ -12768,7 +12974,7 @@ userCommand.command("delete").description("Account unwiderruflich l\xF6schen").a
|
|
|
12768
12974
|
log.dim("Abgebrochen");
|
|
12769
12975
|
return;
|
|
12770
12976
|
}
|
|
12771
|
-
const { confirmText } = await
|
|
12977
|
+
const { confirmText } = await inquirer14.prompt([{
|
|
12772
12978
|
type: "input",
|
|
12773
12979
|
name: "confirmText",
|
|
12774
12980
|
message: 'Tippe "DELETE" um zu best\xE4tigen:'
|
|
@@ -12819,8 +13025,8 @@ userCommand.command("whoami").description("Aktuelle Anmeldung anzeigen").action(
|
|
|
12819
13025
|
});
|
|
12820
13026
|
|
|
12821
13027
|
// src/commands/system/welcome.ts
|
|
12822
|
-
import { Command as
|
|
12823
|
-
var welcomeCommand = new
|
|
13028
|
+
import { Command as Command34 } from "commander";
|
|
13029
|
+
var welcomeCommand = new Command34("welcome").description("Onboarding erneut starten").option("--status", "Nur Status anzeigen").action(async (options) => {
|
|
12824
13030
|
if (options.status) {
|
|
12825
13031
|
const status = getStartupStatus();
|
|
12826
13032
|
log.newline();
|
|
@@ -12851,7 +13057,7 @@ var welcomeCommand = new Command33("welcome").description("Onboarding erneut sta
|
|
|
12851
13057
|
});
|
|
12852
13058
|
|
|
12853
13059
|
// src/commands/system/validate.ts
|
|
12854
|
-
import { Command as
|
|
13060
|
+
import { Command as Command35 } from "commander";
|
|
12855
13061
|
import { existsSync as existsSync22, readFileSync as readFileSync11 } from "fs";
|
|
12856
13062
|
import { homedir as homedir7 } from "os";
|
|
12857
13063
|
import { join as join13 } from "path";
|
|
@@ -13001,7 +13207,7 @@ async function checkNodeVersion() {
|
|
|
13001
13207
|
message: `Node.js ${version}`
|
|
13002
13208
|
};
|
|
13003
13209
|
}
|
|
13004
|
-
var validateCommand = new
|
|
13210
|
+
var validateCommand = new Command35("validate").description("Konfiguration und System validieren").option("--json", "Ausgabe als JSON").action(async (options) => {
|
|
13005
13211
|
const checks = [
|
|
13006
13212
|
{ name: "Node.js", check: checkNodeVersion },
|
|
13007
13213
|
{ name: "Konfiguration", check: checkConfigFile },
|
|
@@ -13059,9 +13265,9 @@ var validateCommand = new Command34("validate").description("Konfiguration und S
|
|
|
13059
13265
|
});
|
|
13060
13266
|
|
|
13061
13267
|
// src/commands/advanced/docker.ts
|
|
13062
|
-
import { Command as
|
|
13268
|
+
import { Command as Command36 } from "commander";
|
|
13063
13269
|
import ora21 from "ora";
|
|
13064
|
-
var dockerCommand = new
|
|
13270
|
+
var dockerCommand = new Command36("docker").description("Docker-Integration verwalten");
|
|
13065
13271
|
dockerCommand.command("status").description("Docker-Verf\xFCgbarkeit pr\xFCfen").action(() => {
|
|
13066
13272
|
log.brand();
|
|
13067
13273
|
log.header("Docker Status");
|
|
@@ -13291,12 +13497,12 @@ dockerCommand.action(() => {
|
|
|
13291
13497
|
});
|
|
13292
13498
|
|
|
13293
13499
|
// src/commands/advanced/workflow.ts
|
|
13294
|
-
import { Command as
|
|
13500
|
+
import { Command as Command37 } from "commander";
|
|
13295
13501
|
import * as fs13 from "fs";
|
|
13296
13502
|
import * as path14 from "path";
|
|
13297
13503
|
import * as os7 from "os";
|
|
13298
13504
|
import ora22 from "ora";
|
|
13299
|
-
import
|
|
13505
|
+
import inquirer12 from "inquirer";
|
|
13300
13506
|
var builtInWorkflows = {
|
|
13301
13507
|
morning: {
|
|
13302
13508
|
name: "Morning Routine",
|
|
@@ -13315,7 +13521,7 @@ var builtInWorkflows = {
|
|
|
13315
13521
|
]
|
|
13316
13522
|
}
|
|
13317
13523
|
};
|
|
13318
|
-
var workflowCommand = new
|
|
13524
|
+
var workflowCommand = new Command37("workflow").description("Automatisierte Workflows ausf\xFChren").action(async () => {
|
|
13319
13525
|
await listWorkflows();
|
|
13320
13526
|
});
|
|
13321
13527
|
workflowCommand.command("list").alias("ls").description("Verf\xFCgbare Workflows anzeigen").action(async () => {
|
|
@@ -13384,7 +13590,7 @@ workflowCommand.command("run").description("Workflow ausf\xFChren").argument("<n
|
|
|
13384
13590
|
}
|
|
13385
13591
|
});
|
|
13386
13592
|
workflowCommand.command("create").description("Neuen Workflow erstellen").argument("<name>", "Workflow-Name").action(async (name) => {
|
|
13387
|
-
const { description } = await
|
|
13593
|
+
const { description } = await inquirer12.prompt([{
|
|
13388
13594
|
type: "input",
|
|
13389
13595
|
name: "description",
|
|
13390
13596
|
message: "Beschreibung:"
|
|
@@ -13392,7 +13598,7 @@ workflowCommand.command("create").description("Neuen Workflow erstellen").argume
|
|
|
13392
13598
|
const steps = [];
|
|
13393
13599
|
let addMore = true;
|
|
13394
13600
|
while (addMore) {
|
|
13395
|
-
const { stepType } = await
|
|
13601
|
+
const { stepType } = await inquirer12.prompt([{
|
|
13396
13602
|
type: "list",
|
|
13397
13603
|
name: "stepType",
|
|
13398
13604
|
message: "Schritt-Typ:",
|
|
@@ -13403,7 +13609,7 @@ workflowCommand.command("create").description("Neuen Workflow erstellen").argume
|
|
|
13403
13609
|
{ name: "Sync ausf\xFChren", value: "sync" }
|
|
13404
13610
|
]
|
|
13405
13611
|
}]);
|
|
13406
|
-
const { stepName } = await
|
|
13612
|
+
const { stepName } = await inquirer12.prompt([{
|
|
13407
13613
|
type: "input",
|
|
13408
13614
|
name: "stepName",
|
|
13409
13615
|
message: "Schritt-Name:",
|
|
@@ -13413,7 +13619,7 @@ workflowCommand.command("create").description("Neuen Workflow erstellen").argume
|
|
|
13413
13619
|
name: stepName,
|
|
13414
13620
|
type: stepType
|
|
13415
13621
|
});
|
|
13416
|
-
const { more } = await
|
|
13622
|
+
const { more } = await inquirer12.prompt([{
|
|
13417
13623
|
type: "confirm",
|
|
13418
13624
|
name: "more",
|
|
13419
13625
|
message: "Weiteren Schritt hinzuf\xFCgen?",
|
|
@@ -13439,7 +13645,7 @@ workflowCommand.command("delete").alias("rm").description("Workflow l\xF6schen")
|
|
|
13439
13645
|
log.error(`Workflow nicht gefunden: ${name}`);
|
|
13440
13646
|
return;
|
|
13441
13647
|
}
|
|
13442
|
-
const { confirm } = await
|
|
13648
|
+
const { confirm } = await inquirer12.prompt([{
|
|
13443
13649
|
type: "confirm",
|
|
13444
13650
|
name: "confirm",
|
|
13445
13651
|
message: `Workflow "${name}" wirklich l\xF6schen?`,
|
|
@@ -13570,11 +13776,11 @@ async function executeStep(step) {
|
|
|
13570
13776
|
}
|
|
13571
13777
|
|
|
13572
13778
|
// src/commands/advanced/package.ts
|
|
13573
|
-
import { Command as
|
|
13779
|
+
import { Command as Command38 } from "commander";
|
|
13574
13780
|
import * as fs14 from "fs";
|
|
13575
|
-
import
|
|
13781
|
+
import inquirer13 from "inquirer";
|
|
13576
13782
|
import ora23 from "ora";
|
|
13577
|
-
var packageCommand = new
|
|
13783
|
+
var packageCommand = new Command38("package").description("Projekt-Gruppen (Packages) verwalten").action(() => {
|
|
13578
13784
|
listPackages();
|
|
13579
13785
|
});
|
|
13580
13786
|
packageCommand.command("list").description("Alle Packages auflisten").option("--json", "JSON Output").action((options) => {
|
|
@@ -13609,7 +13815,7 @@ packageCommand.command("delete <name>").description("Package l\xF6schen").option
|
|
|
13609
13815
|
return;
|
|
13610
13816
|
}
|
|
13611
13817
|
if (!options.force) {
|
|
13612
|
-
const { confirm } = await
|
|
13818
|
+
const { confirm } = await inquirer13.prompt([{
|
|
13613
13819
|
type: "confirm",
|
|
13614
13820
|
name: "confirm",
|
|
13615
13821
|
message: `Package "${pkg.name}" (${pkg.projects.length} Projekte) wirklich l\xF6schen?`,
|
|
@@ -13937,9 +14143,9 @@ function listPackages() {
|
|
|
13937
14143
|
}
|
|
13938
14144
|
|
|
13939
14145
|
// src/commands/advanced/sandbox.ts
|
|
13940
|
-
import { Command as
|
|
14146
|
+
import { Command as Command39 } from "commander";
|
|
13941
14147
|
import ora24 from "ora";
|
|
13942
|
-
var sandboxCommand = new
|
|
14148
|
+
var sandboxCommand = new Command39("sandbox").description("Sandbox-Management mit Cloud-Sync");
|
|
13943
14149
|
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) => {
|
|
13944
14150
|
const spinner = ora24("Lade Sandboxes...").start();
|
|
13945
14151
|
try {
|
|
@@ -14138,8 +14344,8 @@ sandboxCommand.command("sync").description("Sandbox mit Cloud synchronisieren").
|
|
|
14138
14344
|
sandboxCommand.command("cleanup").description("Alte Sandboxes aufr\xE4umen").option("--days <days>", "\xC4lter als X Tage", "30").option("--local", "Nur lokal aufr\xE4umen").option("--cloud", "Nur Cloud aufr\xE4umen").option("-y, --yes", "Ohne Best\xE4tigung").action(async (options) => {
|
|
14139
14345
|
const days = parseInt(options.days);
|
|
14140
14346
|
if (!options.yes) {
|
|
14141
|
-
const { default:
|
|
14142
|
-
const { confirm } = await
|
|
14347
|
+
const { default: inquirer14 } = await import("inquirer");
|
|
14348
|
+
const { confirm } = await inquirer14.prompt([{
|
|
14143
14349
|
type: "confirm",
|
|
14144
14350
|
name: "confirm",
|
|
14145
14351
|
message: `Sandboxes \xE4lter als ${days} Tage l\xF6schen?`,
|
|
@@ -14254,8 +14460,8 @@ sandboxCommand.command("config").description("Sandbox-Konfiguration verwalten").
|
|
|
14254
14460
|
});
|
|
14255
14461
|
sandboxCommand.command("delete <id>").description("Sandbox l\xF6schen").option("--cloud", "Auch aus Cloud l\xF6schen").option("-y, --yes", "Ohne Best\xE4tigung").action(async (id, options) => {
|
|
14256
14462
|
if (!options.yes) {
|
|
14257
|
-
const { default:
|
|
14258
|
-
const { confirm } = await
|
|
14463
|
+
const { default: inquirer14 } = await import("inquirer");
|
|
14464
|
+
const { confirm } = await inquirer14.prompt([{
|
|
14259
14465
|
type: "confirm",
|
|
14260
14466
|
name: "confirm",
|
|
14261
14467
|
message: `Sandbox ${id} l\xF6schen?`,
|
|
@@ -14290,8 +14496,8 @@ sandboxCommand.command("delete <id>").description("Sandbox l\xF6schen").option("
|
|
|
14290
14496
|
});
|
|
14291
14497
|
|
|
14292
14498
|
// src/index.ts
|
|
14293
|
-
var program = new
|
|
14294
|
-
program.name("shiva").description("SHIVA Code - Control Station for Claude Code").version("0.7.
|
|
14499
|
+
var program = new Command40();
|
|
14500
|
+
program.name("shiva").description("SHIVA Code - Control Station for Claude Code").version("0.7.10").option("--debug", "Debug-Modus aktivieren").hook("preAction", (thisCommand) => {
|
|
14295
14501
|
const opts = thisCommand.opts();
|
|
14296
14502
|
if (opts.debug) {
|
|
14297
14503
|
enableDebug();
|
|
@@ -14319,6 +14525,7 @@ program.addCommand(prsCommand);
|
|
|
14319
14525
|
program.addCommand(secretsCommand);
|
|
14320
14526
|
program.addCommand(scanCommand);
|
|
14321
14527
|
program.addCommand(securityCommand);
|
|
14528
|
+
program.addCommand(secureTokenCommand);
|
|
14322
14529
|
program.addCommand(searchCommand);
|
|
14323
14530
|
program.addCommand(forgetCommand);
|
|
14324
14531
|
program.addCommand(contextCommand);
|