shiva-code 0.4.3 → 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 +367 -345
- 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,11 +66,12 @@ 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";
|
|
@@ -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,60 +14654,59 @@ 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
|
});
|
|
14676
14683
|
async function interactiveMenu(choices, shortcuts) {
|
|
14684
|
+
const write = (str) => process.stdout.write(str);
|
|
14685
|
+
const totalLines = 1 + choices.length + 1;
|
|
14677
14686
|
return new Promise((resolve13) => {
|
|
14678
14687
|
let selectedIndex = 0;
|
|
14679
14688
|
let resolved = false;
|
|
14689
|
+
let firstRender = true;
|
|
14680
14690
|
const renderMenu = () => {
|
|
14681
|
-
if (
|
|
14682
|
-
|
|
14691
|
+
if (!firstRender) {
|
|
14692
|
+
write(`\x1B[${totalLines}A`);
|
|
14683
14693
|
}
|
|
14684
|
-
|
|
14694
|
+
firstRender = false;
|
|
14695
|
+
write("\x1B[?25l");
|
|
14696
|
+
write(`\x1B[K${colors.green("?")} ${colors.bold("Auswahl:")}
|
|
14697
|
+
`);
|
|
14685
14698
|
for (let i = 0; i < choices.length; i++) {
|
|
14686
|
-
const
|
|
14687
|
-
const
|
|
14688
|
-
|
|
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
|
+
`);
|
|
14689
14704
|
}
|
|
14690
|
-
|
|
14705
|
+
write(`\x1B[K${colors.dim("\u2191\u2193 navigate \u2022 \u21B5 select")}
|
|
14706
|
+
`);
|
|
14707
|
+
write("\x1B[?25h");
|
|
14691
14708
|
};
|
|
14692
|
-
|
|
14693
|
-
for (let i = 0; i < choices.length; i++) {
|
|
14694
|
-
const prefix = i === selectedIndex ? colors.cyan("\u276F ") : " ";
|
|
14695
|
-
const name = i === selectedIndex ? colors.cyan(choices[i].name) : choices[i].name;
|
|
14696
|
-
console.log(prefix + name);
|
|
14697
|
-
}
|
|
14698
|
-
console.log(colors.dim("\u2191\u2193 navigate \u2022 \u21B5 select"));
|
|
14709
|
+
renderMenu();
|
|
14699
14710
|
if (process.stdin.isTTY) {
|
|
14700
14711
|
readline.emitKeypressEvents(process.stdin);
|
|
14701
14712
|
process.stdin.setRawMode(true);
|
|
@@ -14706,6 +14717,12 @@ async function interactiveMenu(choices, shortcuts) {
|
|
|
14706
14717
|
if (process.stdin.isTTY) {
|
|
14707
14718
|
process.stdin.setRawMode(false);
|
|
14708
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)}`);
|
|
14709
14726
|
};
|
|
14710
14727
|
const handler = (_str, key) => {
|
|
14711
14728
|
if (resolved) return;
|
|
@@ -14713,14 +14730,14 @@ async function interactiveMenu(choices, shortcuts) {
|
|
|
14713
14730
|
const keyChar = key?.sequence?.toLowerCase() || "";
|
|
14714
14731
|
if (key?.ctrl && keyName === "c") {
|
|
14715
14732
|
cleanup();
|
|
14733
|
+
console.log("");
|
|
14716
14734
|
process.exit(0);
|
|
14717
14735
|
}
|
|
14718
|
-
|
|
14719
|
-
|
|
14736
|
+
const shortcutType = shortcuts[keyChar] || shortcuts[keyName];
|
|
14737
|
+
if (shortcutType) {
|
|
14720
14738
|
resolved = true;
|
|
14721
14739
|
cleanup();
|
|
14722
|
-
|
|
14723
|
-
console.log(colors.green("?") + " " + colors.bold("Auswahl:") + " " + colors.cyan(shortcutType));
|
|
14740
|
+
showSelection(shortcutType);
|
|
14724
14741
|
resolve13({ type: shortcutType });
|
|
14725
14742
|
return;
|
|
14726
14743
|
}
|
|
@@ -14733,13 +14750,12 @@ async function interactiveMenu(choices, shortcuts) {
|
|
|
14733
14750
|
} else if (keyName === "return") {
|
|
14734
14751
|
resolved = true;
|
|
14735
14752
|
cleanup();
|
|
14736
|
-
|
|
14737
|
-
console.log(colors.green("?") + " " + colors.bold("Auswahl:") + " " + colors.cyan(choices[selectedIndex].value.type));
|
|
14753
|
+
showSelection(choices[selectedIndex].name);
|
|
14738
14754
|
resolve13(choices[selectedIndex].value);
|
|
14739
14755
|
} else if (keyName === "escape") {
|
|
14740
14756
|
resolved = true;
|
|
14741
14757
|
cleanup();
|
|
14742
|
-
|
|
14758
|
+
showSelection("Beenden");
|
|
14743
14759
|
resolve13({ type: "quit" });
|
|
14744
14760
|
}
|
|
14745
14761
|
};
|
|
@@ -14836,7 +14852,7 @@ async function showDashboard() {
|
|
|
14836
14852
|
const packageName = selected.data;
|
|
14837
14853
|
log.newline();
|
|
14838
14854
|
log.success(`Starte Package ${packageName}...`);
|
|
14839
|
-
const { getPackageLaunchConfig: getPackageLaunchConfig2 } = await import("./package-manager-
|
|
14855
|
+
const { getPackageLaunchConfig: getPackageLaunchConfig2 } = await import("./package-manager-WF3UW2J4.js");
|
|
14840
14856
|
const launches = await getPackageLaunchConfig2(packageName);
|
|
14841
14857
|
if (launches.length > 0) {
|
|
14842
14858
|
await spawnProjects(launches, detectTerminal());
|
|
@@ -14872,7 +14888,7 @@ async function showDashboard() {
|
|
|
14872
14888
|
function showHelpMenu() {
|
|
14873
14889
|
log.plain("Verf\xFCgbare Befehle:");
|
|
14874
14890
|
log.newline();
|
|
14875
|
-
console.log(colors.dim("
|
|
14891
|
+
console.log(colors.dim(" Session-Verwaltung:"));
|
|
14876
14892
|
log.plain(" shiva sessions Alle Claude Sessions auflisten");
|
|
14877
14893
|
log.plain(" shiva resume Session fortsetzen");
|
|
14878
14894
|
log.plain(" shiva restore Crashed Session wiederherstellen");
|
|
@@ -14884,27 +14900,33 @@ function showHelpMenu() {
|
|
|
14884
14900
|
log.plain(" shiva issues GitHub Issues anzeigen");
|
|
14885
14901
|
log.plain(" shiva prs Pull Requests anzeigen");
|
|
14886
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();
|
|
14887
14910
|
console.log(colors.dim(" Docker Integration:"));
|
|
14888
14911
|
log.plain(" shiva docker Docker-Modus verwalten");
|
|
14889
14912
|
log.plain(" shiva start -d In Docker starten");
|
|
14890
14913
|
log.newline();
|
|
14891
|
-
console.log(colors.dim(" Security
|
|
14914
|
+
console.log(colors.dim(" Security:"));
|
|
14892
14915
|
log.plain(" shiva scan Package auf Sicherheit pr\xFCfen");
|
|
14916
|
+
log.plain(" shiva secrets Secrets verwalten");
|
|
14893
14917
|
log.plain(" shiva start -s In Sandbox starten");
|
|
14894
|
-
log.plain(" shiva session Sandbox-Session verwalten");
|
|
14895
14918
|
log.newline();
|
|
14896
|
-
console.log(colors.dim("
|
|
14897
|
-
log.plain(" shiva login Anmelden");
|
|
14919
|
+
console.log(colors.dim(" Projekt-Verwaltung:"));
|
|
14898
14920
|
log.plain(" shiva init Projekt initialisieren");
|
|
14899
14921
|
log.plain(" shiva sync Mit Cloud synchronisieren");
|
|
14900
14922
|
log.plain(" shiva status Status anzeigen");
|
|
14901
14923
|
log.plain(" shiva projects Alle Projekte auflisten");
|
|
14902
|
-
log.plain(" shiva config
|
|
14924
|
+
log.plain(" shiva config Settings verwalten");
|
|
14903
14925
|
log.newline();
|
|
14904
|
-
console.log(colors.dim("
|
|
14926
|
+
console.log(colors.dim(" System:"));
|
|
14905
14927
|
log.plain(" shiva doctor System-Check");
|
|
14906
14928
|
log.plain(" shiva upgrade SHIVA aktualisieren");
|
|
14907
|
-
log.plain(" shiva
|
|
14929
|
+
log.plain(" shiva stats Analytics anzeigen");
|
|
14908
14930
|
log.newline();
|
|
14909
14931
|
log.dim("Hilfe: shiva <befehl> --help");
|
|
14910
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,
|