shiva-code 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{api-MT23KCO3.js → api-OEHQTBH7.js} +2 -2
- package/dist/{chunk-TQ6O4QB6.js → chunk-5RCSFT5F.js} +1 -1
- package/dist/{chunk-6RAACMKF.js → chunk-HIQO2DBA.js} +2 -2
- package/dist/{chunk-TI6Y3VT4.js → chunk-IDM6KY2R.js} +46 -11
- package/dist/{chunk-ZDLLPNCK.js → chunk-IVFCZLBX.js} +1 -1
- package/dist/index.js +436 -338
- package/dist/{manager-TQIASXKY.js → manager-LXNF7QWT.js} +8 -2
- package/dist/{package-manager-NARG55B5.js → package-manager-WF3UW2J4.js} +3 -3
- package/package.json +1 -1
|
@@ -21,8 +21,8 @@ import {
|
|
|
21
21
|
parseGitHubUrl,
|
|
22
22
|
runGh,
|
|
23
23
|
runGhRaw
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-IVFCZLBX.js";
|
|
25
|
+
import "./chunk-HIQO2DBA.js";
|
|
26
26
|
import "./chunk-3RG5ZIWI.js";
|
|
27
27
|
export {
|
|
28
28
|
findMentionedIssueNumbers,
|
|
@@ -3,8 +3,8 @@ var CacheService = class _CacheService {
|
|
|
3
3
|
cache;
|
|
4
4
|
// Default TTLs in milliseconds
|
|
5
5
|
static TTL = {
|
|
6
|
-
SESSIONS:
|
|
7
|
-
//
|
|
6
|
+
SESSIONS: 5 * 60 * 1e3,
|
|
7
|
+
// 5 minutes for sessions (optimized for better cache hit rate)
|
|
8
8
|
GITHUB_ISSUES: 5 * 60 * 1e3,
|
|
9
9
|
// 5 minutes for GitHub issues
|
|
10
10
|
GITHUB_PRS: 5 * 60 * 1e3,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cache
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HIQO2DBA.js";
|
|
4
4
|
|
|
5
5
|
// src/services/session/manager.ts
|
|
6
6
|
import * as fs from "fs";
|
|
7
|
+
import * as fsPromises from "fs/promises";
|
|
7
8
|
import * as path from "path";
|
|
8
9
|
import * as os from "os";
|
|
9
10
|
import * as readline from "readline";
|
|
@@ -31,26 +32,25 @@ async function getAllClaudeProjects(skipCache = false) {
|
|
|
31
32
|
if (!fs.existsSync(projectsPath)) {
|
|
32
33
|
return [];
|
|
33
34
|
}
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
for (const entry of entries) {
|
|
37
|
-
if (!entry.isDirectory()) continue;
|
|
35
|
+
const entries = await fsPromises.readdir(projectsPath, { withFileTypes: true });
|
|
36
|
+
const projectPromises = entries.filter((entry) => entry.isDirectory()).map(async (entry) => {
|
|
38
37
|
const encodedPath = entry.name;
|
|
39
38
|
const absolutePath = decodeProjectPath(encodedPath);
|
|
40
39
|
const projectName = getProjectName(absolutePath);
|
|
41
|
-
const sessionIndex =
|
|
40
|
+
const sessionIndex = await getSessionIndexAsync(encodedPath);
|
|
42
41
|
const sessions = sessionIndex?.entries || [];
|
|
43
42
|
sessions.sort(
|
|
44
43
|
(a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime()
|
|
45
44
|
);
|
|
46
|
-
|
|
45
|
+
return {
|
|
47
46
|
encodedPath,
|
|
48
47
|
absolutePath,
|
|
49
48
|
projectName,
|
|
50
49
|
sessions,
|
|
51
50
|
latestSession: sessions[0]
|
|
52
|
-
}
|
|
53
|
-
}
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
const projects = await Promise.all(projectPromises);
|
|
54
54
|
projects.sort((a, b) => {
|
|
55
55
|
const aTime = a.latestSession ? new Date(a.latestSession.modified).getTime() : 0;
|
|
56
56
|
const bTime = b.latestSession ? new Date(b.latestSession.modified).getTime() : 0;
|
|
@@ -78,8 +78,31 @@ function getSessionIndex(encodedPath) {
|
|
|
78
78
|
return null;
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
async function
|
|
82
|
-
const
|
|
81
|
+
async function getSessionIndexAsync(encodedPath) {
|
|
82
|
+
const indexPath = path.join(
|
|
83
|
+
getClaudeProjectsPath(),
|
|
84
|
+
encodedPath,
|
|
85
|
+
"sessions-index.json"
|
|
86
|
+
);
|
|
87
|
+
try {
|
|
88
|
+
const content = await fsPromises.readFile(indexPath, "utf-8");
|
|
89
|
+
return JSON.parse(content);
|
|
90
|
+
} catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function findProject(nameOrPath, useCache = true) {
|
|
95
|
+
const projects = await getAllClaudeProjects(!useCache);
|
|
96
|
+
const absolutePath = path.resolve(nameOrPath);
|
|
97
|
+
const byPath = projects.find((p) => p.absolutePath === absolutePath);
|
|
98
|
+
if (byPath) return byPath;
|
|
99
|
+
const lowerName = nameOrPath.toLowerCase();
|
|
100
|
+
const byName = projects.find(
|
|
101
|
+
(p) => p.projectName.toLowerCase() === lowerName || p.projectName.toLowerCase().includes(lowerName)
|
|
102
|
+
);
|
|
103
|
+
return byName || null;
|
|
104
|
+
}
|
|
105
|
+
function findProjectFromArray(projects, nameOrPath) {
|
|
83
106
|
const absolutePath = path.resolve(nameOrPath);
|
|
84
107
|
const byPath = projects.find((p) => p.absolutePath === absolutePath);
|
|
85
108
|
if (byPath) return byPath;
|
|
@@ -103,6 +126,15 @@ async function findProjectForCurrentDir() {
|
|
|
103
126
|
function getSessionFilePath(session) {
|
|
104
127
|
return session.fullPath;
|
|
105
128
|
}
|
|
129
|
+
function isSessionCorruptedQuick(session) {
|
|
130
|
+
const filePath = getSessionFilePath(session);
|
|
131
|
+
try {
|
|
132
|
+
const stats = fs.statSync(filePath);
|
|
133
|
+
return stats.size > 100 * 1024 * 1024;
|
|
134
|
+
} catch {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
106
138
|
function isSessionCorrupted(session) {
|
|
107
139
|
const filePath = getSessionFilePath(session);
|
|
108
140
|
if (!fs.existsSync(filePath)) {
|
|
@@ -288,10 +320,13 @@ export {
|
|
|
288
320
|
getAllClaudeProjects,
|
|
289
321
|
invalidateSessionsCache,
|
|
290
322
|
getSessionIndex,
|
|
323
|
+
getSessionIndexAsync,
|
|
291
324
|
findProject,
|
|
325
|
+
findProjectFromArray,
|
|
292
326
|
findSessionByBranch,
|
|
293
327
|
findProjectForCurrentDir,
|
|
294
328
|
getSessionFilePath,
|
|
329
|
+
isSessionCorruptedQuick,
|
|
295
330
|
isSessionCorrupted,
|
|
296
331
|
isSessionActive,
|
|
297
332
|
parseSessionFile,
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
isGhAuthenticated,
|
|
40
40
|
isGhInstalled,
|
|
41
41
|
isGitRepo
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-IVFCZLBX.js";
|
|
43
43
|
import {
|
|
44
44
|
addProjectToPackage,
|
|
45
45
|
createPackage,
|
|
@@ -49,11 +49,12 @@ import {
|
|
|
49
49
|
getPackageLaunchConfig,
|
|
50
50
|
getPackageStats,
|
|
51
51
|
removeProjectFromPackage
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-5RCSFT5F.js";
|
|
53
53
|
import {
|
|
54
54
|
encodeProjectPath,
|
|
55
55
|
findProject,
|
|
56
56
|
findProjectForCurrentDir,
|
|
57
|
+
findProjectFromArray,
|
|
57
58
|
findSessionByBranch,
|
|
58
59
|
formatDate,
|
|
59
60
|
formatRelativeTime,
|
|
@@ -65,18 +66,19 @@ import {
|
|
|
65
66
|
invalidateSessionsCache,
|
|
66
67
|
isSessionActive,
|
|
67
68
|
isSessionCorrupted,
|
|
69
|
+
isSessionCorruptedQuick,
|
|
68
70
|
saveRecoveredContext
|
|
69
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-IDM6KY2R.js";
|
|
70
72
|
import {
|
|
71
73
|
cache
|
|
72
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-HIQO2DBA.js";
|
|
73
75
|
import {
|
|
74
76
|
__require
|
|
75
77
|
} from "./chunk-3RG5ZIWI.js";
|
|
76
78
|
|
|
77
79
|
// src/index.ts
|
|
78
80
|
import { Command as Command35 } from "commander";
|
|
79
|
-
import
|
|
81
|
+
import * as readline from "readline";
|
|
80
82
|
|
|
81
83
|
// src/commands/auth/login.ts
|
|
82
84
|
import { Command } from "commander";
|
|
@@ -6059,11 +6061,12 @@ var startCommand = new Command10("start").description("Projekte starten (mit Git
|
|
|
6059
6061
|
return;
|
|
6060
6062
|
}
|
|
6061
6063
|
const spinner = ora6("Bereite Projekte vor...").start();
|
|
6064
|
+
const allProjects = await getAllClaudeProjects();
|
|
6062
6065
|
const launches = [];
|
|
6063
6066
|
for (const projektArg of projekte) {
|
|
6064
6067
|
const absolutePath = path3.resolve(projektArg);
|
|
6065
6068
|
if (fs.existsSync(absolutePath) && fs.statSync(absolutePath).isDirectory()) {
|
|
6066
|
-
const project =
|
|
6069
|
+
const project = findProjectFromArray(allProjects, absolutePath);
|
|
6067
6070
|
const latestSession = project?.latestSession;
|
|
6068
6071
|
launches.push({
|
|
6069
6072
|
projectPath: absolutePath,
|
|
@@ -6072,7 +6075,7 @@ var startCommand = new Command10("start").description("Projekte starten (mit Git
|
|
|
6072
6075
|
newSession: options.new || !latestSession
|
|
6073
6076
|
});
|
|
6074
6077
|
} else {
|
|
6075
|
-
const project =
|
|
6078
|
+
const project = findProjectFromArray(allProjects, projektArg);
|
|
6076
6079
|
if (project) {
|
|
6077
6080
|
if (!fs.existsSync(project.absolutePath)) {
|
|
6078
6081
|
spinner.warn(`Projektpfad existiert nicht: ${project.absolutePath}`);
|
|
@@ -6964,106 +6967,124 @@ function sessionHasAnyTag(sessionId, tags) {
|
|
|
6964
6967
|
return sessionTags.some((t) => normalizedTags.includes(t));
|
|
6965
6968
|
}
|
|
6966
6969
|
|
|
6970
|
+
// src/utils/command-wrapper.ts
|
|
6971
|
+
function withCommandErrorHandling(commandName, fn) {
|
|
6972
|
+
return async (...args) => {
|
|
6973
|
+
try {
|
|
6974
|
+
await fn(...args);
|
|
6975
|
+
} catch (error) {
|
|
6976
|
+
const shivaError = fromError(error);
|
|
6977
|
+
logErrorWithSuggestion(shivaError, commandName);
|
|
6978
|
+
process.exit(1);
|
|
6979
|
+
}
|
|
6980
|
+
};
|
|
6981
|
+
}
|
|
6982
|
+
function logErrorWithSuggestion(error, commandName) {
|
|
6983
|
+
if (commandName) {
|
|
6984
|
+
log.error(`[${commandName}] ${error.message}`);
|
|
6985
|
+
} else {
|
|
6986
|
+
log.error(error.message);
|
|
6987
|
+
}
|
|
6988
|
+
if (error.suggestion) {
|
|
6989
|
+
log.info(`\u2192 ${error.suggestion}`);
|
|
6990
|
+
}
|
|
6991
|
+
}
|
|
6992
|
+
|
|
6967
6993
|
// src/commands/session/sessions.ts
|
|
6968
|
-
var sessionsCommand = new Command13("sessions").description("Alle Claude Code Sessions auflisten").option("-a, --all", "Auch leere Projekte zeigen").option("-p, --project <pfad>", "Nur ein bestimmtes Projekt").option("-t, --tag <tag>", "Nach Tag filtern (Komma-getrennt f\xFCr mehrere)").option("-r, --refresh", "Cache invalidieren und neu laden").option("--json", "JSON Output").action(async (options) => {
|
|
6994
|
+
var sessionsCommand = new Command13("sessions").description("Alle Claude Code Sessions auflisten").option("-a, --all", "Auch leere Projekte zeigen").option("-p, --project <pfad>", "Nur ein bestimmtes Projekt").option("-t, --tag <tag>", "Nach Tag filtern (Komma-getrennt f\xFCr mehrere)").option("-r, --refresh", "Cache invalidieren und neu laden").option("--json", "JSON Output").action(withCommandErrorHandling("sessions", async (options) => {
|
|
6969
6995
|
if (options.refresh) {
|
|
6970
6996
|
invalidateSessionsCache();
|
|
6971
6997
|
}
|
|
6972
6998
|
const spinner = ora9("Lade Sessions...").start();
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
spinner.fail(`Projekt nicht gefunden: ${options.project}`);
|
|
6981
|
-
return;
|
|
6982
|
-
}
|
|
6983
|
-
}
|
|
6984
|
-
if (options.tag) {
|
|
6985
|
-
const filterTags = options.tag.split(",").map((t) => t.trim());
|
|
6986
|
-
projects = projects.map((project) => ({
|
|
6987
|
-
...project,
|
|
6988
|
-
sessions: project.sessions.filter(
|
|
6989
|
-
(session) => sessionHasAnyTag(session.sessionId, filterTags)
|
|
6990
|
-
)
|
|
6991
|
-
})).filter((p) => p.sessions.length > 0);
|
|
6992
|
-
}
|
|
6993
|
-
if (!options.all) {
|
|
6994
|
-
projects = projects.filter((p) => p.sessions.length > 0);
|
|
6995
|
-
}
|
|
6996
|
-
spinner.stop();
|
|
6997
|
-
if (options.json) {
|
|
6998
|
-
console.log(JSON.stringify(projects, null, 2));
|
|
6999
|
+
let projects = await getAllClaudeProjects(options.refresh);
|
|
7000
|
+
if (options.project) {
|
|
7001
|
+
const found = await findProject(options.project);
|
|
7002
|
+
if (found) {
|
|
7003
|
+
projects = [found];
|
|
7004
|
+
} else {
|
|
7005
|
+
spinner.fail(`Projekt nicht gefunden: ${options.project}`);
|
|
6999
7006
|
return;
|
|
7000
7007
|
}
|
|
7008
|
+
}
|
|
7009
|
+
if (options.tag) {
|
|
7010
|
+
const filterTags = options.tag.split(",").map((t) => t.trim());
|
|
7011
|
+
projects = projects.map((project) => ({
|
|
7012
|
+
...project,
|
|
7013
|
+
sessions: project.sessions.filter(
|
|
7014
|
+
(session) => sessionHasAnyTag(session.sessionId, filterTags)
|
|
7015
|
+
)
|
|
7016
|
+
})).filter((p) => p.sessions.length > 0);
|
|
7017
|
+
}
|
|
7018
|
+
if (!options.all) {
|
|
7019
|
+
projects = projects.filter((p) => p.sessions.length > 0);
|
|
7020
|
+
}
|
|
7021
|
+
spinner.stop();
|
|
7022
|
+
if (options.json) {
|
|
7023
|
+
console.log(JSON.stringify(projects, null, 2));
|
|
7024
|
+
return;
|
|
7025
|
+
}
|
|
7026
|
+
log.newline();
|
|
7027
|
+
console.log(colors.orange.bold("SHIVA Code - Sessions"));
|
|
7028
|
+
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"));
|
|
7029
|
+
log.newline();
|
|
7030
|
+
if (projects.length === 0) {
|
|
7031
|
+
log.dim("Keine Sessions gefunden.");
|
|
7001
7032
|
log.newline();
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7033
|
+
log.info("Claude Code Sessions werden automatisch erkannt.");
|
|
7034
|
+
return;
|
|
7035
|
+
}
|
|
7036
|
+
for (const project of projects) {
|
|
7037
|
+
const projectExists = await checkProjectExists(project.absolutePath);
|
|
7038
|
+
const projectIcon = projectExists ? "" : colors.yellow(" \u26A0");
|
|
7039
|
+
console.log(colors.bold(`Projekt: ${project.projectName}`) + projectIcon);
|
|
7040
|
+
if (!projectExists) {
|
|
7041
|
+
console.log(colors.dim(` Pfad existiert nicht mehr: ${project.absolutePath}`));
|
|
7010
7042
|
}
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
const projectIcon = projectExists ? "" : colors.yellow(" \u26A0");
|
|
7014
|
-
console.log(colors.bold(`Projekt: ${project.projectName}`) + projectIcon);
|
|
7015
|
-
if (!projectExists) {
|
|
7016
|
-
console.log(colors.dim(` Pfad existiert nicht mehr: ${project.absolutePath}`));
|
|
7017
|
-
}
|
|
7018
|
-
if (project.sessions.length === 0) {
|
|
7019
|
-
log.dim(" Keine Sessions");
|
|
7020
|
-
log.newline();
|
|
7021
|
-
continue;
|
|
7022
|
-
}
|
|
7023
|
-
const displaySessions = project.sessions.slice(0, 5);
|
|
7024
|
-
for (let i = 0; i < displaySessions.length; i++) {
|
|
7025
|
-
const session = displaySessions[i];
|
|
7026
|
-
const num = String(i + 1).padStart(2, " ");
|
|
7027
|
-
let statusIcon = "";
|
|
7028
|
-
if (isSessionActive(session)) {
|
|
7029
|
-
statusIcon = colors.green(" [aktiv]");
|
|
7030
|
-
} else if (isSessionCorrupted(session)) {
|
|
7031
|
-
statusIcon = colors.red(" [corrupted]");
|
|
7032
|
-
}
|
|
7033
|
-
const branch = session.gitBranch || "main";
|
|
7034
|
-
const msgs = `${session.messageCount} msgs`.padEnd(10);
|
|
7035
|
-
const time = formatRelativeTime(session.modified);
|
|
7036
|
-
let prompt = session.firstPrompt || "";
|
|
7037
|
-
if (prompt.length > 40) {
|
|
7038
|
-
prompt = prompt.substring(0, 37) + "...";
|
|
7039
|
-
}
|
|
7040
|
-
prompt = `"${prompt}"`;
|
|
7041
|
-
const tags = getSessionTags(session.sessionId);
|
|
7042
|
-
const tagsDisplay = tags.length > 0 ? " " + tags.map((t) => colors.magenta(`[${t}]`)).join(" ") : "";
|
|
7043
|
-
const line = [
|
|
7044
|
-
colors.dim(`${num}.`),
|
|
7045
|
-
branch.padEnd(15),
|
|
7046
|
-
colors.dim(`(${msgs})`),
|
|
7047
|
-
formatDate(session.modified).padEnd(14),
|
|
7048
|
-
colors.cyan(prompt),
|
|
7049
|
-
statusIcon,
|
|
7050
|
-
tagsDisplay
|
|
7051
|
-
].join(" ");
|
|
7052
|
-
console.log(` ${line}`);
|
|
7053
|
-
}
|
|
7054
|
-
if (project.sessions.length > 5) {
|
|
7055
|
-
log.dim(` ... und ${project.sessions.length - 5} weitere Sessions`);
|
|
7056
|
-
}
|
|
7043
|
+
if (project.sessions.length === 0) {
|
|
7044
|
+
log.dim(" Keine Sessions");
|
|
7057
7045
|
log.newline();
|
|
7046
|
+
continue;
|
|
7058
7047
|
}
|
|
7059
|
-
const
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
})
|
|
7048
|
+
const displaySessions = project.sessions.slice(0, 5);
|
|
7049
|
+
for (let i = 0; i < displaySessions.length; i++) {
|
|
7050
|
+
const session = displaySessions[i];
|
|
7051
|
+
const num = String(i + 1).padStart(2, " ");
|
|
7052
|
+
let statusIcon = "";
|
|
7053
|
+
if (isSessionActive(session)) {
|
|
7054
|
+
statusIcon = colors.green(" [aktiv]");
|
|
7055
|
+
} else if (isSessionCorruptedQuick(session)) {
|
|
7056
|
+
statusIcon = colors.red(" [corrupted]");
|
|
7057
|
+
}
|
|
7058
|
+
const branch = session.gitBranch || "main";
|
|
7059
|
+
const msgs = `${session.messageCount} msgs`.padEnd(10);
|
|
7060
|
+
const time = formatRelativeTime(session.modified);
|
|
7061
|
+
let prompt = session.firstPrompt || "";
|
|
7062
|
+
if (prompt.length > 40) {
|
|
7063
|
+
prompt = prompt.substring(0, 37) + "...";
|
|
7064
|
+
}
|
|
7065
|
+
prompt = `"${prompt}"`;
|
|
7066
|
+
const tags = getSessionTags(session.sessionId);
|
|
7067
|
+
const tagsDisplay = tags.length > 0 ? " " + tags.map((t) => colors.magenta(`[${t}]`)).join(" ") : "";
|
|
7068
|
+
const line = [
|
|
7069
|
+
colors.dim(`${num}.`),
|
|
7070
|
+
branch.padEnd(15),
|
|
7071
|
+
colors.dim(`(${msgs})`),
|
|
7072
|
+
formatDate(session.modified).padEnd(14),
|
|
7073
|
+
colors.cyan(prompt),
|
|
7074
|
+
statusIcon,
|
|
7075
|
+
tagsDisplay
|
|
7076
|
+
].join(" ");
|
|
7077
|
+
console.log(` ${line}`);
|
|
7078
|
+
}
|
|
7079
|
+
if (project.sessions.length > 5) {
|
|
7080
|
+
log.dim(` ... und ${project.sessions.length - 5} weitere Sessions`);
|
|
7081
|
+
}
|
|
7082
|
+
log.newline();
|
|
7083
|
+
}
|
|
7084
|
+
const stats = await getSessionStats();
|
|
7085
|
+
log.dim(`Total: ${stats.activeProjects} Projekte, ${stats.totalSessions} Sessions`);
|
|
7086
|
+
log.newline();
|
|
7087
|
+
}));
|
|
7067
7088
|
async function checkProjectExists(path15) {
|
|
7068
7089
|
try {
|
|
7069
7090
|
const fs15 = await import("fs");
|
|
@@ -8024,13 +8045,13 @@ githubCommand.command("map").description("Aktuellen Branch mit einer Session ver
|
|
|
8024
8045
|
initShivaDir(cwd);
|
|
8025
8046
|
}
|
|
8026
8047
|
if (!sessionId) {
|
|
8027
|
-
const { findProject:
|
|
8028
|
-
const project = await
|
|
8048
|
+
const { findProject: findProject3 } = await import("./manager-LXNF7QWT.js");
|
|
8049
|
+
const project = await findProject3(cwd);
|
|
8029
8050
|
if (!project || project.sessions.length === 0) {
|
|
8030
8051
|
log.error("Keine Sessions f\xFCr dieses Projekt gefunden");
|
|
8031
8052
|
return;
|
|
8032
8053
|
}
|
|
8033
|
-
const { formatDate: formatDate2 } = await import("./manager-
|
|
8054
|
+
const { formatDate: formatDate2 } = await import("./manager-LXNF7QWT.js");
|
|
8034
8055
|
const choices = project.sessions.slice(0, 10).map((s) => {
|
|
8035
8056
|
const time = formatDate2(s.modified);
|
|
8036
8057
|
const msgs = `${s.messageCount} msgs`;
|
|
@@ -8120,234 +8141,220 @@ githubCommand.command("mappings").description("Alle Branch-Session Mappings anze
|
|
|
8120
8141
|
// src/commands/github/issues.ts
|
|
8121
8142
|
import { Command as Command16 } from "commander";
|
|
8122
8143
|
import ora11 from "ora";
|
|
8123
|
-
var issuesCommand = new Command16("issues").description("GitHub Issues \xFCber alle Projekte anzeigen").option("-m, --mine", "Nur mir zugewiesene Issues").option("-p, --project <name>", "Nur Issues eines Projekts").option("-a, --all", "Auch geschlossene Issues").option("-l, --limit <n>", "Maximale Anzahl pro Projekt", "10").option("--json", "JSON Output").action(async (options) => {
|
|
8144
|
+
var issuesCommand = new Command16("issues").description("GitHub Issues \xFCber alle Projekte anzeigen").option("-m, --mine", "Nur mir zugewiesene Issues").option("-p, --project <name>", "Nur Issues eines Projekts").option("-a, --all", "Auch geschlossene Issues").option("-l, --limit <n>", "Maximale Anzahl pro Projekt", "10").option("--json", "JSON Output").action(withCommandErrorHandling("issues", async (options) => {
|
|
8124
8145
|
if (!isGhInstalled()) {
|
|
8125
|
-
|
|
8126
|
-
log.info("Installiere: https://cli.github.com/");
|
|
8127
|
-
return;
|
|
8146
|
+
throw Errors.GITHUB_NOT_INSTALLED();
|
|
8128
8147
|
}
|
|
8129
8148
|
if (!isGhAuthenticated()) {
|
|
8130
|
-
|
|
8131
|
-
log.info("Anmelden mit: shiva github login");
|
|
8132
|
-
return;
|
|
8149
|
+
throw Errors.GITHUB_NOT_AUTHENTICATED();
|
|
8133
8150
|
}
|
|
8134
8151
|
const currentUser = getGhUser();
|
|
8135
8152
|
const spinner = ora11("Lade Issues...").start();
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
spinner.fail(`Projekt nicht gefunden: ${options.project}`);
|
|
8145
|
-
return;
|
|
8146
|
-
}
|
|
8147
|
-
}
|
|
8148
|
-
const projectsWithIssues = [];
|
|
8149
|
-
const limit = parseInt(options.limit, 10) || 10;
|
|
8150
|
-
for (const project of projects) {
|
|
8151
|
-
const repo = getRepoInfo(project.absolutePath);
|
|
8152
|
-
if (!repo) continue;
|
|
8153
|
-
const issueOptions = { limit };
|
|
8154
|
-
if (options.mine && currentUser) {
|
|
8155
|
-
issueOptions.assignee = currentUser;
|
|
8156
|
-
}
|
|
8157
|
-
const issues = getOpenIssues(repo.fullName, issueOptions);
|
|
8158
|
-
if (issues.length > 0 || options.all) {
|
|
8159
|
-
const assignedCount = currentUser ? issues.filter((i) => i.assignees.includes(currentUser)).length : 0;
|
|
8160
|
-
projectsWithIssues.push({
|
|
8161
|
-
project,
|
|
8162
|
-
repo: repo.fullName,
|
|
8163
|
-
issues,
|
|
8164
|
-
assignedCount
|
|
8165
|
-
});
|
|
8166
|
-
}
|
|
8167
|
-
}
|
|
8168
|
-
spinner.stop();
|
|
8169
|
-
if (options.json) {
|
|
8170
|
-
const output = projectsWithIssues.map((p) => ({
|
|
8171
|
-
project: p.project.projectName,
|
|
8172
|
-
repo: p.repo,
|
|
8173
|
-
issues: p.issues
|
|
8174
|
-
}));
|
|
8175
|
-
console.log(JSON.stringify(output, null, 2));
|
|
8153
|
+
const allProjects = await getAllClaudeProjects();
|
|
8154
|
+
let projects = allProjects;
|
|
8155
|
+
if (options.project) {
|
|
8156
|
+
const found = await findProject(options.project);
|
|
8157
|
+
if (found) {
|
|
8158
|
+
projects = [found];
|
|
8159
|
+
} else {
|
|
8160
|
+
spinner.fail(`Projekt nicht gefunden: ${options.project}`);
|
|
8176
8161
|
return;
|
|
8177
8162
|
}
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8163
|
+
}
|
|
8164
|
+
const projectsWithIssues = [];
|
|
8165
|
+
const limit = parseInt(options.limit, 10) || 10;
|
|
8166
|
+
for (const project of projects) {
|
|
8167
|
+
const repo = getRepoInfo(project.absolutePath);
|
|
8168
|
+
if (!repo) continue;
|
|
8169
|
+
const issueOptions = { limit };
|
|
8170
|
+
if (options.mine && currentUser) {
|
|
8171
|
+
issueOptions.assignee = currentUser;
|
|
8172
|
+
}
|
|
8173
|
+
const issues = getOpenIssues(repo.fullName, issueOptions);
|
|
8174
|
+
if (issues.length > 0 || options.all) {
|
|
8175
|
+
const assignedCount = currentUser ? issues.filter((i) => i.assignees.includes(currentUser)).length : 0;
|
|
8176
|
+
projectsWithIssues.push({
|
|
8177
|
+
project,
|
|
8178
|
+
repo: repo.fullName,
|
|
8179
|
+
issues,
|
|
8180
|
+
assignedCount
|
|
8181
|
+
});
|
|
8182
|
+
}
|
|
8183
|
+
}
|
|
8184
|
+
spinner.stop();
|
|
8185
|
+
if (options.json) {
|
|
8186
|
+
const output = projectsWithIssues.map((p) => ({
|
|
8187
|
+
project: p.project.projectName,
|
|
8188
|
+
repo: p.repo,
|
|
8189
|
+
issues: p.issues
|
|
8190
|
+
}));
|
|
8191
|
+
console.log(JSON.stringify(output, null, 2));
|
|
8192
|
+
return;
|
|
8193
|
+
}
|
|
8194
|
+
log.newline();
|
|
8195
|
+
console.log(colors.orange.bold("SHIVA Code - GitHub Issues"));
|
|
8196
|
+
console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
8197
|
+
log.newline();
|
|
8198
|
+
if (projectsWithIssues.length === 0) {
|
|
8199
|
+
log.dim("Keine Issues gefunden.");
|
|
8200
|
+
if (!options.mine) {
|
|
8201
|
+
log.info("Versuche: shiva issues --mine");
|
|
8188
8202
|
}
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8203
|
+
return;
|
|
8204
|
+
}
|
|
8205
|
+
let totalIssues = 0;
|
|
8206
|
+
let totalAssigned = 0;
|
|
8207
|
+
for (const { project, repo, issues, assignedCount } of projectsWithIssues) {
|
|
8208
|
+
totalIssues += issues.length;
|
|
8209
|
+
totalAssigned += assignedCount;
|
|
8210
|
+
const assignedText = assignedCount > 0 ? colors.green(`, ${assignedCount} assigned`) : "";
|
|
8211
|
+
console.log(
|
|
8212
|
+
colors.bold(`\u{1F4E6} ${project.projectName}`) + colors.dim(` (${issues.length} open${assignedText})`)
|
|
8213
|
+
);
|
|
8214
|
+
for (const issue of issues) {
|
|
8215
|
+
const isAssigned = currentUser && issue.assignees.includes(currentUser);
|
|
8216
|
+
const assigneeText = isAssigned ? colors.green(" [you]") : issue.assignees.length > 0 ? colors.dim(` [@${issue.assignees[0]}]`) : "";
|
|
8217
|
+
let icon = "\u{1F7E1}";
|
|
8218
|
+
if (issue.labels.some((l) => l.toLowerCase().includes("bug"))) {
|
|
8219
|
+
icon = "\u{1F534}";
|
|
8220
|
+
} else if (issue.labels.some((l) => l.toLowerCase().includes("doc"))) {
|
|
8221
|
+
icon = "\u{1F7E2}";
|
|
8222
|
+
} else if (issue.labels.some((l) => l.toLowerCase().includes("feature"))) {
|
|
8223
|
+
icon = "\u{1F7E1}";
|
|
8224
|
+
}
|
|
8225
|
+
const labelsText = issue.labels.length > 0 ? colors.dim(` [${issue.labels.slice(0, 3).join(", ")}]`) : "";
|
|
8195
8226
|
console.log(
|
|
8196
|
-
|
|
8227
|
+
` ${icon} #${issue.number} ${issue.title.substring(0, 50)}${issue.title.length > 50 ? "..." : ""}${assigneeText}${labelsText}`
|
|
8197
8228
|
);
|
|
8198
|
-
for (const issue of issues) {
|
|
8199
|
-
const isAssigned = currentUser && issue.assignees.includes(currentUser);
|
|
8200
|
-
const assigneeText = isAssigned ? colors.green(" [you]") : issue.assignees.length > 0 ? colors.dim(` [@${issue.assignees[0]}]`) : "";
|
|
8201
|
-
let icon = "\u{1F7E1}";
|
|
8202
|
-
if (issue.labels.some((l) => l.toLowerCase().includes("bug"))) {
|
|
8203
|
-
icon = "\u{1F534}";
|
|
8204
|
-
} else if (issue.labels.some((l) => l.toLowerCase().includes("doc"))) {
|
|
8205
|
-
icon = "\u{1F7E2}";
|
|
8206
|
-
} else if (issue.labels.some((l) => l.toLowerCase().includes("feature"))) {
|
|
8207
|
-
icon = "\u{1F7E1}";
|
|
8208
|
-
}
|
|
8209
|
-
const labelsText = issue.labels.length > 0 ? colors.dim(` [${issue.labels.slice(0, 3).join(", ")}]`) : "";
|
|
8210
|
-
console.log(
|
|
8211
|
-
` ${icon} #${issue.number} ${issue.title.substring(0, 50)}${issue.title.length > 50 ? "..." : ""}${assigneeText}${labelsText}`
|
|
8212
|
-
);
|
|
8213
|
-
}
|
|
8214
|
-
log.newline();
|
|
8215
8229
|
}
|
|
8216
|
-
const summaryText = options.mine ? `Total: ${totalIssues} Issues (dir zugewiesen)` : `Total: ${totalIssues} Issues offen (${totalAssigned} dir zugewiesen)`;
|
|
8217
|
-
log.dim(summaryText);
|
|
8218
8230
|
log.newline();
|
|
8219
|
-
log.dim("Session f\xFCr Issue starten: shiva start --issue <nummer>");
|
|
8220
|
-
} catch (error) {
|
|
8221
|
-
spinner.fail("Fehler beim Laden der Issues");
|
|
8222
|
-
log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
|
|
8223
8231
|
}
|
|
8224
|
-
})
|
|
8232
|
+
const summaryText = options.mine ? `Total: ${totalIssues} Issues (dir zugewiesen)` : `Total: ${totalIssues} Issues offen (${totalAssigned} dir zugewiesen)`;
|
|
8233
|
+
log.dim(summaryText);
|
|
8234
|
+
log.newline();
|
|
8235
|
+
log.dim("Session f\xFCr Issue starten: shiva start --issue <nummer>");
|
|
8236
|
+
}));
|
|
8225
8237
|
|
|
8226
8238
|
// src/commands/github/prs.ts
|
|
8227
8239
|
import { Command as Command17 } from "commander";
|
|
8228
8240
|
import ora12 from "ora";
|
|
8229
|
-
var prsCommand = new Command17("prs").description("GitHub Pull Requests \xFCber alle Projekte anzeigen").option("-m, --mine", "Nur meine PRs").option("-r, --review", "PRs wo ich Reviewer bin").option("-p, --project <name>", "Nur PRs eines Projekts").option("-l, --limit <n>", "Maximale Anzahl pro Projekt", "10").option("--json", "JSON Output").action(async (options) => {
|
|
8241
|
+
var prsCommand = new Command17("prs").description("GitHub Pull Requests \xFCber alle Projekte anzeigen").option("-m, --mine", "Nur meine PRs").option("-r, --review", "PRs wo ich Reviewer bin").option("-p, --project <name>", "Nur PRs eines Projekts").option("-l, --limit <n>", "Maximale Anzahl pro Projekt", "10").option("--json", "JSON Output").action(withCommandErrorHandling("prs", async (options) => {
|
|
8230
8242
|
if (!isGhInstalled()) {
|
|
8231
|
-
|
|
8232
|
-
log.info("Installiere: https://cli.github.com/");
|
|
8233
|
-
return;
|
|
8243
|
+
throw Errors.GITHUB_NOT_INSTALLED();
|
|
8234
8244
|
}
|
|
8235
8245
|
if (!isGhAuthenticated()) {
|
|
8236
|
-
|
|
8237
|
-
log.info("Anmelden mit: shiva github login");
|
|
8238
|
-
return;
|
|
8246
|
+
throw Errors.GITHUB_NOT_AUTHENTICATED();
|
|
8239
8247
|
}
|
|
8240
8248
|
const currentUser = getGhUser();
|
|
8241
8249
|
const spinner = ora12("Lade Pull Requests...").start();
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
spinner.fail(`Projekt nicht gefunden: ${options.project}`);
|
|
8251
|
-
return;
|
|
8252
|
-
}
|
|
8253
|
-
}
|
|
8254
|
-
const projectsWithPRs = [];
|
|
8255
|
-
const limit = parseInt(options.limit, 10) || 10;
|
|
8256
|
-
for (const project of projects) {
|
|
8257
|
-
const repo = getRepoInfo(project.absolutePath);
|
|
8258
|
-
if (!repo) continue;
|
|
8259
|
-
const prOptions = { limit };
|
|
8260
|
-
if (options.mine && currentUser) {
|
|
8261
|
-
prOptions.author = currentUser;
|
|
8262
|
-
}
|
|
8263
|
-
let prs = getOpenPRs(repo.fullName, prOptions);
|
|
8264
|
-
if (options.review && currentUser) {
|
|
8265
|
-
prs = prs.filter((pr) => pr.author !== currentUser);
|
|
8266
|
-
}
|
|
8267
|
-
if (prs.length > 0) {
|
|
8268
|
-
const myPRsCount = currentUser ? prs.filter((pr) => pr.author === currentUser).length : 0;
|
|
8269
|
-
projectsWithPRs.push({
|
|
8270
|
-
project,
|
|
8271
|
-
repo: repo.fullName,
|
|
8272
|
-
prs,
|
|
8273
|
-
myPRsCount
|
|
8274
|
-
});
|
|
8275
|
-
}
|
|
8276
|
-
}
|
|
8277
|
-
spinner.stop();
|
|
8278
|
-
if (options.json) {
|
|
8279
|
-
const output = projectsWithPRs.map((p) => ({
|
|
8280
|
-
project: p.project.projectName,
|
|
8281
|
-
repo: p.repo,
|
|
8282
|
-
prs: p.prs
|
|
8283
|
-
}));
|
|
8284
|
-
console.log(JSON.stringify(output, null, 2));
|
|
8250
|
+
const allProjects = await getAllClaudeProjects();
|
|
8251
|
+
let projects = allProjects;
|
|
8252
|
+
if (options.project) {
|
|
8253
|
+
const found = await findProject(options.project);
|
|
8254
|
+
if (found) {
|
|
8255
|
+
projects = [found];
|
|
8256
|
+
} else {
|
|
8257
|
+
spinner.fail(`Projekt nicht gefunden: ${options.project}`);
|
|
8285
8258
|
return;
|
|
8286
8259
|
}
|
|
8287
|
-
|
|
8288
|
-
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8260
|
+
}
|
|
8261
|
+
const limit = parseInt(options.limit, 10) || 10;
|
|
8262
|
+
const projectsWithRepos = projects.map((project) => ({
|
|
8263
|
+
project,
|
|
8264
|
+
repo: getRepoInfo(project.absolutePath)
|
|
8265
|
+
})).filter((p) => p.repo !== null);
|
|
8266
|
+
const prPromises = projectsWithRepos.map(async ({ project, repo }) => {
|
|
8267
|
+
const prOptions = { limit };
|
|
8268
|
+
if (options.mine && currentUser) {
|
|
8269
|
+
prOptions.author = currentUser;
|
|
8270
|
+
}
|
|
8271
|
+
let prs = getOpenPRs(repo.fullName, prOptions);
|
|
8272
|
+
if (options.review && currentUser) {
|
|
8273
|
+
prs = prs.filter((pr) => pr.author !== currentUser);
|
|
8274
|
+
}
|
|
8275
|
+
if (prs.length > 0) {
|
|
8276
|
+
const myPRsCount = currentUser ? prs.filter((pr) => pr.author === currentUser).length : 0;
|
|
8277
|
+
return {
|
|
8278
|
+
project,
|
|
8279
|
+
repo: repo.fullName,
|
|
8280
|
+
prs,
|
|
8281
|
+
myPRsCount
|
|
8282
|
+
};
|
|
8297
8283
|
}
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8284
|
+
return null;
|
|
8285
|
+
});
|
|
8286
|
+
const results = await Promise.all(prPromises);
|
|
8287
|
+
const projectsWithPRs = results.filter((p) => p !== null);
|
|
8288
|
+
spinner.stop();
|
|
8289
|
+
if (options.json) {
|
|
8290
|
+
const output = projectsWithPRs.map((p) => ({
|
|
8291
|
+
project: p.project.projectName,
|
|
8292
|
+
repo: p.repo,
|
|
8293
|
+
prs: p.prs
|
|
8294
|
+
}));
|
|
8295
|
+
console.log(JSON.stringify(output, null, 2));
|
|
8296
|
+
return;
|
|
8297
|
+
}
|
|
8298
|
+
log.newline();
|
|
8299
|
+
console.log(colors.orange.bold("SHIVA Code - Pull Requests"));
|
|
8300
|
+
console.log(colors.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
8301
|
+
log.newline();
|
|
8302
|
+
if (projectsWithPRs.length === 0) {
|
|
8303
|
+
log.dim("Keine Pull Requests gefunden.");
|
|
8304
|
+
if (!options.mine) {
|
|
8305
|
+
log.info("Versuche: shiva prs --mine");
|
|
8306
|
+
}
|
|
8307
|
+
return;
|
|
8308
|
+
}
|
|
8309
|
+
let totalPRs = 0;
|
|
8310
|
+
let totalMyPRs = 0;
|
|
8311
|
+
for (const { project, repo, prs, myPRsCount } of projectsWithPRs) {
|
|
8312
|
+
totalPRs += prs.length;
|
|
8313
|
+
totalMyPRs += myPRsCount;
|
|
8314
|
+
console.log(
|
|
8315
|
+
colors.bold(`\u{1F4E6} ${project.projectName}`) + colors.dim(` (${prs.length} open)`)
|
|
8316
|
+
);
|
|
8317
|
+
for (const pr of prs) {
|
|
8318
|
+
const isMine = currentUser && pr.author === currentUser;
|
|
8319
|
+
let statusIcon = "\u{1F7E1}";
|
|
8320
|
+
if (pr.checksStatus === "success" && pr.reviewDecision === "approved") {
|
|
8321
|
+
statusIcon = "\u{1F7E2}";
|
|
8322
|
+
} else if (pr.checksStatus === "failure") {
|
|
8323
|
+
statusIcon = "\u{1F534}";
|
|
8324
|
+
}
|
|
8325
|
+
const ciIcons = {
|
|
8326
|
+
success: colors.green("\u2713"),
|
|
8327
|
+
failure: colors.red("\u2717"),
|
|
8328
|
+
pending: colors.yellow("\u23F3")
|
|
8329
|
+
};
|
|
8330
|
+
const ciText = pr.checksStatus ? ciIcons[pr.checksStatus] || "\u25CB" : "\u25CB";
|
|
8331
|
+
const reviewIcons = {
|
|
8332
|
+
approved: colors.green("\u2713 Approved"),
|
|
8333
|
+
changes_requested: colors.red("\u274C Changes"),
|
|
8334
|
+
review_required: colors.yellow("\u{1F440} Review pending")
|
|
8335
|
+
};
|
|
8336
|
+
const reviewText = pr.reviewDecision ? reviewIcons[pr.reviewDecision] : "";
|
|
8337
|
+
const authorText = isMine ? colors.green("@you") : colors.dim(`@${pr.author}`);
|
|
8338
|
+
const draftText = pr.isDraft ? colors.dim(" [draft]") : "";
|
|
8339
|
+
const title = pr.title.length > 35 ? pr.title.substring(0, 32) + "..." : pr.title;
|
|
8340
|
+
const branchInfo = colors.dim(`${pr.headBranch} \u2192 ${pr.baseBranch}`);
|
|
8303
8341
|
console.log(
|
|
8304
|
-
|
|
8342
|
+
` ${statusIcon} #${pr.number} ${title}${draftText}`
|
|
8343
|
+
);
|
|
8344
|
+
console.log(
|
|
8345
|
+
` ${branchInfo}`
|
|
8346
|
+
);
|
|
8347
|
+
console.log(
|
|
8348
|
+
` ${ciText} CI ${reviewText} ${authorText}`
|
|
8305
8349
|
);
|
|
8306
|
-
for (const pr of prs) {
|
|
8307
|
-
const isMine = currentUser && pr.author === currentUser;
|
|
8308
|
-
let statusIcon = "\u{1F7E1}";
|
|
8309
|
-
if (pr.checksStatus === "success" && pr.reviewDecision === "approved") {
|
|
8310
|
-
statusIcon = "\u{1F7E2}";
|
|
8311
|
-
} else if (pr.checksStatus === "failure") {
|
|
8312
|
-
statusIcon = "\u{1F534}";
|
|
8313
|
-
}
|
|
8314
|
-
const ciIcons = {
|
|
8315
|
-
success: colors.green("\u2713"),
|
|
8316
|
-
failure: colors.red("\u2717"),
|
|
8317
|
-
pending: colors.yellow("\u23F3")
|
|
8318
|
-
};
|
|
8319
|
-
const ciText = pr.checksStatus ? ciIcons[pr.checksStatus] || "\u25CB" : "\u25CB";
|
|
8320
|
-
const reviewIcons = {
|
|
8321
|
-
approved: colors.green("\u2713 Approved"),
|
|
8322
|
-
changes_requested: colors.red("\u274C Changes"),
|
|
8323
|
-
review_required: colors.yellow("\u{1F440} Review pending")
|
|
8324
|
-
};
|
|
8325
|
-
const reviewText = pr.reviewDecision ? reviewIcons[pr.reviewDecision] : "";
|
|
8326
|
-
const authorText = isMine ? colors.green("@you") : colors.dim(`@${pr.author}`);
|
|
8327
|
-
const draftText = pr.isDraft ? colors.dim(" [draft]") : "";
|
|
8328
|
-
const title = pr.title.length > 35 ? pr.title.substring(0, 32) + "..." : pr.title;
|
|
8329
|
-
const branchInfo = colors.dim(`${pr.headBranch} \u2192 ${pr.baseBranch}`);
|
|
8330
|
-
console.log(
|
|
8331
|
-
` ${statusIcon} #${pr.number} ${title}${draftText}`
|
|
8332
|
-
);
|
|
8333
|
-
console.log(
|
|
8334
|
-
` ${branchInfo}`
|
|
8335
|
-
);
|
|
8336
|
-
console.log(
|
|
8337
|
-
` ${ciText} CI ${reviewText} ${authorText}`
|
|
8338
|
-
);
|
|
8339
|
-
}
|
|
8340
|
-
log.newline();
|
|
8341
8350
|
}
|
|
8342
|
-
const summaryText = options.mine ? `Total: ${totalPRs} PRs (deine)` : `Total: ${totalPRs} PRs offen (${totalMyPRs} deine)`;
|
|
8343
|
-
log.dim(summaryText);
|
|
8344
8351
|
log.newline();
|
|
8345
|
-
log.dim("PR Session starten: shiva start --pr <nummer>");
|
|
8346
|
-
} catch (error) {
|
|
8347
|
-
spinner.fail("Fehler beim Laden der PRs");
|
|
8348
|
-
log.error(error instanceof Error ? error.message : "Unbekannter Fehler");
|
|
8349
8352
|
}
|
|
8350
|
-
})
|
|
8353
|
+
const summaryText = options.mine ? `Total: ${totalPRs} PRs (deine)` : `Total: ${totalPRs} PRs offen (${totalMyPRs} deine)`;
|
|
8354
|
+
log.dim(summaryText);
|
|
8355
|
+
log.newline();
|
|
8356
|
+
log.dim("PR Session starten: shiva start --pr <nummer>");
|
|
8357
|
+
}));
|
|
8351
8358
|
|
|
8352
8359
|
// src/commands/security/scan.ts
|
|
8353
8360
|
import { Command as Command18 } from "commander";
|
|
@@ -14378,9 +14385,9 @@ hookCommand.command("branch-switch").description("Branch-Wechsel behandeln (f\xF
|
|
|
14378
14385
|
if (options.quiet) {
|
|
14379
14386
|
return;
|
|
14380
14387
|
}
|
|
14381
|
-
const { getCurrentBranch: getCurrentBranch2 } = await import("./api-
|
|
14388
|
+
const { getCurrentBranch: getCurrentBranch2 } = await import("./api-OEHQTBH7.js");
|
|
14382
14389
|
const { getSessionForBranch: getSessionForBranch2, hasShivaDir: hasShivaDir2 } = await import("./config-D6M6LI6U.js");
|
|
14383
|
-
const { findProject:
|
|
14390
|
+
const { findProject: findProject3, findSessionByBranch: findSessionByBranch2, formatRelativeTime: formatRelativeTime3 } = await import("./manager-LXNF7QWT.js");
|
|
14384
14391
|
const projectPath = process.cwd();
|
|
14385
14392
|
const newBranch = getCurrentBranch2(projectPath);
|
|
14386
14393
|
let sessionInfo = null;
|
|
@@ -14394,7 +14401,7 @@ hookCommand.command("branch-switch").description("Branch-Wechsel behandeln (f\xF
|
|
|
14394
14401
|
}
|
|
14395
14402
|
}
|
|
14396
14403
|
if (!sessionInfo) {
|
|
14397
|
-
const project = await
|
|
14404
|
+
const project = await findProject3(projectPath);
|
|
14398
14405
|
if (project) {
|
|
14399
14406
|
const indexSession = findSessionByBranch2(project, newBranch);
|
|
14400
14407
|
if (indexSession) {
|
|
@@ -14632,9 +14639,14 @@ function listPackages() {
|
|
|
14632
14639
|
|
|
14633
14640
|
// src/index.ts
|
|
14634
14641
|
var program = new Command35();
|
|
14635
|
-
program.name("shiva").description("SHIVA Code - Control Station for Claude Code").version("0.
|
|
14642
|
+
program.name("shiva").description("SHIVA Code - Control Station for Claude Code").version("0.5.0");
|
|
14636
14643
|
program.addCommand(loginCommand);
|
|
14637
14644
|
program.addCommand(logoutCommand);
|
|
14645
|
+
program.addCommand(sessionsCommand);
|
|
14646
|
+
program.addCommand(resumeCommand);
|
|
14647
|
+
program.addCommand(restoreCommand);
|
|
14648
|
+
program.addCommand(startCommand);
|
|
14649
|
+
program.addCommand(sessionCommand);
|
|
14638
14650
|
program.addCommand(initCommand);
|
|
14639
14651
|
program.addCommand(syncCommand);
|
|
14640
14652
|
program.addCommand(statusCommand);
|
|
@@ -14642,37 +14654,114 @@ program.addCommand(projectsCommand);
|
|
|
14642
14654
|
program.addCommand(connectCommand);
|
|
14643
14655
|
program.addCommand(disconnectCommand);
|
|
14644
14656
|
program.addCommand(configCommand);
|
|
14645
|
-
program.addCommand(
|
|
14646
|
-
program.addCommand(sessionsCommand);
|
|
14647
|
-
program.addCommand(resumeCommand);
|
|
14648
|
-
program.addCommand(restoreCommand);
|
|
14649
|
-
program.addCommand(startCommand);
|
|
14650
|
-
program.addCommand(packageCommand);
|
|
14657
|
+
program.addCommand(projectCommand);
|
|
14651
14658
|
program.addCommand(githubCommand);
|
|
14652
14659
|
program.addCommand(issuesCommand);
|
|
14653
14660
|
program.addCommand(prsCommand);
|
|
14654
14661
|
program.addCommand(secretsCommand);
|
|
14655
|
-
program.addCommand(
|
|
14656
|
-
program.addCommand(
|
|
14657
|
-
program.addCommand(completionsCommand);
|
|
14658
|
-
program.addCommand(tagsCommand);
|
|
14659
|
-
program.addCommand(exportCommand);
|
|
14660
|
-
program.addCommand(importCommand);
|
|
14662
|
+
program.addCommand(scanCommand);
|
|
14663
|
+
program.addCommand(securityCommand);
|
|
14661
14664
|
program.addCommand(searchCommand);
|
|
14662
14665
|
program.addCommand(forgetCommand);
|
|
14663
14666
|
program.addCommand(contextCommand);
|
|
14664
|
-
program.addCommand(
|
|
14665
|
-
program.addCommand(
|
|
14666
|
-
program.addCommand(
|
|
14667
|
-
program.addCommand(
|
|
14668
|
-
program.addCommand(sessionCommand);
|
|
14667
|
+
program.addCommand(tagsCommand);
|
|
14668
|
+
program.addCommand(exportCommand);
|
|
14669
|
+
program.addCommand(importCommand);
|
|
14670
|
+
program.addCommand(statsCommand);
|
|
14669
14671
|
program.addCommand(doctorCommand);
|
|
14670
14672
|
program.addCommand(upgradeCommand);
|
|
14671
14673
|
program.addCommand(selfUpdateCommand);
|
|
14672
14674
|
program.addCommand(telemetryCommand);
|
|
14675
|
+
program.addCommand(completionsCommand);
|
|
14676
|
+
program.addCommand(dockerCommand);
|
|
14677
|
+
program.addCommand(workflowCommand);
|
|
14678
|
+
program.addCommand(hookCommand);
|
|
14679
|
+
program.addCommand(packageCommand);
|
|
14673
14680
|
program.action(async () => {
|
|
14674
14681
|
await showDashboard();
|
|
14675
14682
|
});
|
|
14683
|
+
async function interactiveMenu(choices, shortcuts) {
|
|
14684
|
+
const write = (str) => process.stdout.write(str);
|
|
14685
|
+
const totalLines = 1 + choices.length + 1;
|
|
14686
|
+
return new Promise((resolve13) => {
|
|
14687
|
+
let selectedIndex = 0;
|
|
14688
|
+
let resolved = false;
|
|
14689
|
+
let firstRender = true;
|
|
14690
|
+
const renderMenu = () => {
|
|
14691
|
+
if (!firstRender) {
|
|
14692
|
+
write(`\x1B[${totalLines}A`);
|
|
14693
|
+
}
|
|
14694
|
+
firstRender = false;
|
|
14695
|
+
write("\x1B[?25l");
|
|
14696
|
+
write(`\x1B[K${colors.green("?")} ${colors.bold("Auswahl:")}
|
|
14697
|
+
`);
|
|
14698
|
+
for (let i = 0; i < choices.length; i++) {
|
|
14699
|
+
const isSelected = i === selectedIndex;
|
|
14700
|
+
const prefix = isSelected ? colors.cyan("\u276F ") : " ";
|
|
14701
|
+
const name = isSelected ? colors.cyan(choices[i].name) : choices[i].name;
|
|
14702
|
+
write(`\x1B[K${prefix}${name}
|
|
14703
|
+
`);
|
|
14704
|
+
}
|
|
14705
|
+
write(`\x1B[K${colors.dim("\u2191\u2193 navigate \u2022 \u21B5 select")}
|
|
14706
|
+
`);
|
|
14707
|
+
write("\x1B[?25h");
|
|
14708
|
+
};
|
|
14709
|
+
renderMenu();
|
|
14710
|
+
if (process.stdin.isTTY) {
|
|
14711
|
+
readline.emitKeypressEvents(process.stdin);
|
|
14712
|
+
process.stdin.setRawMode(true);
|
|
14713
|
+
}
|
|
14714
|
+
process.stdin.resume();
|
|
14715
|
+
const cleanup = () => {
|
|
14716
|
+
process.stdin.removeListener("keypress", handler);
|
|
14717
|
+
if (process.stdin.isTTY) {
|
|
14718
|
+
process.stdin.setRawMode(false);
|
|
14719
|
+
}
|
|
14720
|
+
write("\x1B[?25h");
|
|
14721
|
+
};
|
|
14722
|
+
const showSelection = (label) => {
|
|
14723
|
+
write(`\x1B[${totalLines}A`);
|
|
14724
|
+
write("\x1B[J");
|
|
14725
|
+
console.log(`${colors.green("?")} ${colors.bold("Auswahl:")} ${colors.cyan(label)}`);
|
|
14726
|
+
};
|
|
14727
|
+
const handler = (_str, key) => {
|
|
14728
|
+
if (resolved) return;
|
|
14729
|
+
const keyName = key?.name?.toLowerCase() || "";
|
|
14730
|
+
const keyChar = key?.sequence?.toLowerCase() || "";
|
|
14731
|
+
if (key?.ctrl && keyName === "c") {
|
|
14732
|
+
cleanup();
|
|
14733
|
+
console.log("");
|
|
14734
|
+
process.exit(0);
|
|
14735
|
+
}
|
|
14736
|
+
const shortcutType = shortcuts[keyChar] || shortcuts[keyName];
|
|
14737
|
+
if (shortcutType) {
|
|
14738
|
+
resolved = true;
|
|
14739
|
+
cleanup();
|
|
14740
|
+
showSelection(shortcutType);
|
|
14741
|
+
resolve13({ type: shortcutType });
|
|
14742
|
+
return;
|
|
14743
|
+
}
|
|
14744
|
+
if (keyName === "up") {
|
|
14745
|
+
selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : choices.length - 1;
|
|
14746
|
+
renderMenu();
|
|
14747
|
+
} else if (keyName === "down") {
|
|
14748
|
+
selectedIndex = selectedIndex < choices.length - 1 ? selectedIndex + 1 : 0;
|
|
14749
|
+
renderMenu();
|
|
14750
|
+
} else if (keyName === "return") {
|
|
14751
|
+
resolved = true;
|
|
14752
|
+
cleanup();
|
|
14753
|
+
showSelection(choices[selectedIndex].name);
|
|
14754
|
+
resolve13(choices[selectedIndex].value);
|
|
14755
|
+
} else if (keyName === "escape") {
|
|
14756
|
+
resolved = true;
|
|
14757
|
+
cleanup();
|
|
14758
|
+
showSelection("Beenden");
|
|
14759
|
+
resolve13({ type: "quit" });
|
|
14760
|
+
}
|
|
14761
|
+
};
|
|
14762
|
+
process.stdin.on("keypress", handler);
|
|
14763
|
+
});
|
|
14764
|
+
}
|
|
14676
14765
|
async function showDashboard() {
|
|
14677
14766
|
console.clear();
|
|
14678
14767
|
log.newline();
|
|
@@ -14727,20 +14816,23 @@ async function showDashboard() {
|
|
|
14727
14816
|
value: { type: "separator" }
|
|
14728
14817
|
});
|
|
14729
14818
|
choices.push(
|
|
14730
|
-
{ name: "
|
|
14731
|
-
{ name: "
|
|
14732
|
-
{ name: "
|
|
14733
|
-
{ name: "
|
|
14734
|
-
{ name: "
|
|
14735
|
-
{ name: "
|
|
14819
|
+
{ name: colors.green("[S]") + " Alle Sessions anzeigen", value: { type: "sessions" } },
|
|
14820
|
+
{ name: colors.green("[P]") + " Packages verwalten", value: { type: "packages" } },
|
|
14821
|
+
{ name: colors.green("[G]") + " GitHub Issues", value: { type: "issues" } },
|
|
14822
|
+
{ name: colors.green("[R]") + " Pull Requests", value: { type: "prs" } },
|
|
14823
|
+
{ name: colors.green("[C]") + " Config", value: { type: "config" } },
|
|
14824
|
+
{ name: colors.green("[Q]") + " Beenden", value: { type: "quit" } }
|
|
14736
14825
|
);
|
|
14737
|
-
const
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14826
|
+
const shortcuts = {
|
|
14827
|
+
"s": "sessions",
|
|
14828
|
+
"p": "packages",
|
|
14829
|
+
"g": "issues",
|
|
14830
|
+
"r": "prs",
|
|
14831
|
+
"c": "config",
|
|
14832
|
+
"q": "quit"
|
|
14833
|
+
};
|
|
14834
|
+
const menuChoices = choices.filter((c) => c.value.type !== "separator");
|
|
14835
|
+
const selected = await interactiveMenu(menuChoices, shortcuts);
|
|
14744
14836
|
switch (selected.type) {
|
|
14745
14837
|
case "resume": {
|
|
14746
14838
|
const project = selected.data;
|
|
@@ -14760,7 +14852,7 @@ async function showDashboard() {
|
|
|
14760
14852
|
const packageName = selected.data;
|
|
14761
14853
|
log.newline();
|
|
14762
14854
|
log.success(`Starte Package ${packageName}...`);
|
|
14763
|
-
const { getPackageLaunchConfig: getPackageLaunchConfig2 } = await import("./package-manager-
|
|
14855
|
+
const { getPackageLaunchConfig: getPackageLaunchConfig2 } = await import("./package-manager-WF3UW2J4.js");
|
|
14764
14856
|
const launches = await getPackageLaunchConfig2(packageName);
|
|
14765
14857
|
if (launches.length > 0) {
|
|
14766
14858
|
await spawnProjects(launches, detectTerminal());
|
|
@@ -14796,7 +14888,7 @@ async function showDashboard() {
|
|
|
14796
14888
|
function showHelpMenu() {
|
|
14797
14889
|
log.plain("Verf\xFCgbare Befehle:");
|
|
14798
14890
|
log.newline();
|
|
14799
|
-
console.log(colors.dim("
|
|
14891
|
+
console.log(colors.dim(" Session-Verwaltung:"));
|
|
14800
14892
|
log.plain(" shiva sessions Alle Claude Sessions auflisten");
|
|
14801
14893
|
log.plain(" shiva resume Session fortsetzen");
|
|
14802
14894
|
log.plain(" shiva restore Crashed Session wiederherstellen");
|
|
@@ -14808,27 +14900,33 @@ function showHelpMenu() {
|
|
|
14808
14900
|
log.plain(" shiva issues GitHub Issues anzeigen");
|
|
14809
14901
|
log.plain(" shiva prs Pull Requests anzeigen");
|
|
14810
14902
|
log.newline();
|
|
14903
|
+
console.log(colors.dim(" Memory & Context:"));
|
|
14904
|
+
log.plain(" shiva search In Memories suchen");
|
|
14905
|
+
log.plain(" shiva context Context anzeigen");
|
|
14906
|
+
log.plain(" shiva tags Session-Tags verwalten");
|
|
14907
|
+
log.plain(" shiva export Sessions exportieren");
|
|
14908
|
+
log.plain(" shiva import Sessions importieren");
|
|
14909
|
+
log.newline();
|
|
14811
14910
|
console.log(colors.dim(" Docker Integration:"));
|
|
14812
14911
|
log.plain(" shiva docker Docker-Modus verwalten");
|
|
14813
14912
|
log.plain(" shiva start -d In Docker starten");
|
|
14814
14913
|
log.newline();
|
|
14815
|
-
console.log(colors.dim(" Security
|
|
14914
|
+
console.log(colors.dim(" Security:"));
|
|
14816
14915
|
log.plain(" shiva scan Package auf Sicherheit pr\xFCfen");
|
|
14916
|
+
log.plain(" shiva secrets Secrets verwalten");
|
|
14817
14917
|
log.plain(" shiva start -s In Sandbox starten");
|
|
14818
|
-
log.plain(" shiva session Sandbox-Session verwalten");
|
|
14819
14918
|
log.newline();
|
|
14820
|
-
console.log(colors.dim("
|
|
14821
|
-
log.plain(" shiva login Anmelden");
|
|
14919
|
+
console.log(colors.dim(" Projekt-Verwaltung:"));
|
|
14822
14920
|
log.plain(" shiva init Projekt initialisieren");
|
|
14823
14921
|
log.plain(" shiva sync Mit Cloud synchronisieren");
|
|
14824
14922
|
log.plain(" shiva status Status anzeigen");
|
|
14825
14923
|
log.plain(" shiva projects Alle Projekte auflisten");
|
|
14826
|
-
log.plain(" shiva config
|
|
14924
|
+
log.plain(" shiva config Settings verwalten");
|
|
14827
14925
|
log.newline();
|
|
14828
|
-
console.log(colors.dim("
|
|
14926
|
+
console.log(colors.dim(" System:"));
|
|
14829
14927
|
log.plain(" shiva doctor System-Check");
|
|
14830
14928
|
log.plain(" shiva upgrade SHIVA aktualisieren");
|
|
14831
|
-
log.plain(" shiva
|
|
14929
|
+
log.plain(" shiva stats Analytics anzeigen");
|
|
14832
14930
|
log.newline();
|
|
14833
14931
|
log.dim("Hilfe: shiva <befehl> --help");
|
|
14834
14932
|
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
encodeProjectPath,
|
|
4
4
|
findProject,
|
|
5
5
|
findProjectForCurrentDir,
|
|
6
|
+
findProjectFromArray,
|
|
6
7
|
findSessionByBranch,
|
|
7
8
|
formatDate,
|
|
8
9
|
formatRecoveredContextAsMarkdown,
|
|
@@ -13,20 +14,23 @@ import {
|
|
|
13
14
|
getRecoveredContext,
|
|
14
15
|
getSessionFilePath,
|
|
15
16
|
getSessionIndex,
|
|
17
|
+
getSessionIndexAsync,
|
|
16
18
|
getSessionStats,
|
|
17
19
|
invalidateSessionsCache,
|
|
18
20
|
isSessionActive,
|
|
19
21
|
isSessionCorrupted,
|
|
22
|
+
isSessionCorruptedQuick,
|
|
20
23
|
parseSessionFile,
|
|
21
24
|
saveRecoveredContext
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-IDM6KY2R.js";
|
|
26
|
+
import "./chunk-HIQO2DBA.js";
|
|
24
27
|
import "./chunk-3RG5ZIWI.js";
|
|
25
28
|
export {
|
|
26
29
|
decodeProjectPath,
|
|
27
30
|
encodeProjectPath,
|
|
28
31
|
findProject,
|
|
29
32
|
findProjectForCurrentDir,
|
|
33
|
+
findProjectFromArray,
|
|
30
34
|
findSessionByBranch,
|
|
31
35
|
formatDate,
|
|
32
36
|
formatRecoveredContextAsMarkdown,
|
|
@@ -37,10 +41,12 @@ export {
|
|
|
37
41
|
getRecoveredContext,
|
|
38
42
|
getSessionFilePath,
|
|
39
43
|
getSessionIndex,
|
|
44
|
+
getSessionIndexAsync,
|
|
40
45
|
getSessionStats,
|
|
41
46
|
invalidateSessionsCache,
|
|
42
47
|
isSessionActive,
|
|
43
48
|
isSessionCorrupted,
|
|
49
|
+
isSessionCorruptedQuick,
|
|
44
50
|
parseSessionFile,
|
|
45
51
|
saveRecoveredContext
|
|
46
52
|
};
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
getPackageStats,
|
|
10
10
|
removeProjectFromPackage,
|
|
11
11
|
updatePackage
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-5RCSFT5F.js";
|
|
13
|
+
import "./chunk-IDM6KY2R.js";
|
|
14
|
+
import "./chunk-HIQO2DBA.js";
|
|
15
15
|
import "./chunk-3RG5ZIWI.js";
|
|
16
16
|
export {
|
|
17
17
|
addProjectToPackage,
|