@jiraacp/cli 2026.405.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +283 -0
- package/dist/abort-GQE4OI5S.js +103 -0
- package/dist/abort-GQE4OI5S.js.map +1 -0
- package/dist/abort-VMRQOADY.js +96 -0
- package/dist/abort-VMRQOADY.js.map +1 -0
- package/dist/bot-WOTETAJY.js +13 -0
- package/dist/bot-WOTETAJY.js.map +1 -0
- package/dist/cancel-clarification-4G5S2HJZ.js +64 -0
- package/dist/cancel-clarification-4G5S2HJZ.js.map +1 -0
- package/dist/chunk-3U373M37.js +67 -0
- package/dist/chunk-3U373M37.js.map +1 -0
- package/dist/chunk-3YHD4SIN.js +97 -0
- package/dist/chunk-3YHD4SIN.js.map +1 -0
- package/dist/chunk-6IY6CRUJ.js +690 -0
- package/dist/chunk-6IY6CRUJ.js.map +1 -0
- package/dist/chunk-B6OA3XJK.js +1167 -0
- package/dist/chunk-B6OA3XJK.js.map +1 -0
- package/dist/chunk-BM4R6NST.js +191 -0
- package/dist/chunk-BM4R6NST.js.map +1 -0
- package/dist/chunk-FLPIU2QO.js +77 -0
- package/dist/chunk-FLPIU2QO.js.map +1 -0
- package/dist/chunk-H7YXX4UA.js +86 -0
- package/dist/chunk-H7YXX4UA.js.map +1 -0
- package/dist/chunk-IT74N3UH.js +19 -0
- package/dist/chunk-IT74N3UH.js.map +1 -0
- package/dist/chunk-JOT4UVSO.js +186 -0
- package/dist/chunk-JOT4UVSO.js.map +1 -0
- package/dist/chunk-KSJKCLEJ.js +222 -0
- package/dist/chunk-KSJKCLEJ.js.map +1 -0
- package/dist/chunk-LIEW4ULF.js +139 -0
- package/dist/chunk-LIEW4ULF.js.map +1 -0
- package/dist/chunk-M4V3YOCY.js +82 -0
- package/dist/chunk-M4V3YOCY.js.map +1 -0
- package/dist/chunk-MMWQHH25.js +207 -0
- package/dist/chunk-MMWQHH25.js.map +1 -0
- package/dist/chunk-OJ4CNF73.js +78 -0
- package/dist/chunk-OJ4CNF73.js.map +1 -0
- package/dist/chunk-PFJAC3RO.js +137 -0
- package/dist/chunk-PFJAC3RO.js.map +1 -0
- package/dist/chunk-PVKVCUNR.js +159 -0
- package/dist/chunk-PVKVCUNR.js.map +1 -0
- package/dist/chunk-RXT4WSIY.js +35 -0
- package/dist/chunk-RXT4WSIY.js.map +1 -0
- package/dist/chunk-RZK74PDF.js +34 -0
- package/dist/chunk-RZK74PDF.js.map +1 -0
- package/dist/chunk-UDTWVKRX.js +68 -0
- package/dist/chunk-UDTWVKRX.js.map +1 -0
- package/dist/chunk-VCEONSWJ.js +307 -0
- package/dist/chunk-VCEONSWJ.js.map +1 -0
- package/dist/chunk-VWBCDZWQ.js +119 -0
- package/dist/chunk-VWBCDZWQ.js.map +1 -0
- package/dist/chunk-WEJCTFQB.js +228 -0
- package/dist/chunk-WEJCTFQB.js.map +1 -0
- package/dist/chunk-YJK7IRPI.js +223 -0
- package/dist/chunk-YJK7IRPI.js.map +1 -0
- package/dist/claude-md-HQ6L4CRP.js +8 -0
- package/dist/claude-md-HQ6L4CRP.js.map +1 -0
- package/dist/cli.js +276 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands-RG45VBTZ.js +407 -0
- package/dist/commands-RG45VBTZ.js.map +1 -0
- package/dist/commands-WYVRVE5Z.js +400 -0
- package/dist/commands-WYVRVE5Z.js.map +1 -0
- package/dist/config-edit-G7O56HXO.js +50 -0
- package/dist/config-edit-G7O56HXO.js.map +1 -0
- package/dist/config-set-QN3JRNZL.js +63 -0
- package/dist/config-set-QN3JRNZL.js.map +1 -0
- package/dist/daemon-CGBV55JK.js +104 -0
- package/dist/daemon-CGBV55JK.js.map +1 -0
- package/dist/dashboard-YVFJ5DXR.js +143 -0
- package/dist/dashboard-YVFJ5DXR.js.map +1 -0
- package/dist/doctor-BPTLVLTD.js +98 -0
- package/dist/doctor-BPTLVLTD.js.map +1 -0
- package/dist/human-loop-RBTA2TYK.js +16 -0
- package/dist/human-loop-RBTA2TYK.js.map +1 -0
- package/dist/human-loop-XGWXUNCS.js +18 -0
- package/dist/human-loop-XGWXUNCS.js.map +1 -0
- package/dist/index.d.ts +583 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/loader-DGW7HCJ5.js +21 -0
- package/dist/loader-DGW7HCJ5.js.map +1 -0
- package/dist/logs-JUVQWN6C.js +93 -0
- package/dist/logs-JUVQWN6C.js.map +1 -0
- package/dist/mcp.js +132 -0
- package/dist/mcp.js.map +1 -0
- package/dist/orchestrator-3MGXX3QW.js +22 -0
- package/dist/orchestrator-3MGXX3QW.js.map +1 -0
- package/dist/orchestrator-BVUKN5N3.js +13 -0
- package/dist/orchestrator-BVUKN5N3.js.map +1 -0
- package/dist/pause-FLDZ3OD6.js +62 -0
- package/dist/pause-FLDZ3OD6.js.map +1 -0
- package/dist/projects-QMIGNW7U.js +129 -0
- package/dist/projects-QMIGNW7U.js.map +1 -0
- package/dist/replay-M4JEG4Z4.js +151 -0
- package/dist/replay-M4JEG4Z4.js.map +1 -0
- package/dist/schedule-CDHD77VZ.js +17 -0
- package/dist/schedule-CDHD77VZ.js.map +1 -0
- package/dist/serve-XI7JTIPZ.js +231 -0
- package/dist/serve-XI7JTIPZ.js.map +1 -0
- package/dist/sprint-KZZWVNK6.js +200 -0
- package/dist/sprint-KZZWVNK6.js.map +1 -0
- package/dist/status-I6GU2LWE.js +48 -0
- package/dist/status-I6GU2LWE.js.map +1 -0
- package/dist/topic-manager-4AMEPMFI.js +12 -0
- package/dist/topic-manager-4AMEPMFI.js.map +1 -0
- package/dist/triage-WNHGPVZQ.js +251 -0
- package/dist/triage-WNHGPVZQ.js.map +1 -0
- package/dist/usage-AWWBI37F.js +155 -0
- package/dist/usage-AWWBI37F.js.map +1 -0
- package/dist/wizard-CYEJJLNF.js +190 -0
- package/dist/wizard-CYEJJLNF.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/utils/daemon.ts
|
|
4
|
+
import { spawn } from "child_process";
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import os from "os";
|
|
8
|
+
var HOME_DIR = path.join(os.homedir(), ".jira-acp");
|
|
9
|
+
var PID_FILE = path.join(HOME_DIR, "jira-acp.pid");
|
|
10
|
+
var LOG_FILE = path.join(HOME_DIR, "logs", "jira-acp.log");
|
|
11
|
+
function getPidFile() {
|
|
12
|
+
return PID_FILE;
|
|
13
|
+
}
|
|
14
|
+
function getLogFile() {
|
|
15
|
+
return LOG_FILE;
|
|
16
|
+
}
|
|
17
|
+
function readPid() {
|
|
18
|
+
try {
|
|
19
|
+
const pid = parseInt(fs.readFileSync(PID_FILE, "utf8").trim(), 10);
|
|
20
|
+
return isNaN(pid) ? null : pid;
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function writePid(pid) {
|
|
26
|
+
fs.mkdirSync(path.dirname(PID_FILE), { recursive: true });
|
|
27
|
+
fs.writeFileSync(PID_FILE, String(pid));
|
|
28
|
+
}
|
|
29
|
+
function removePid() {
|
|
30
|
+
try {
|
|
31
|
+
fs.unlinkSync(PID_FILE);
|
|
32
|
+
} catch {
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function isAlive(pid) {
|
|
36
|
+
try {
|
|
37
|
+
process.kill(pid, 0);
|
|
38
|
+
return true;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function getStatus() {
|
|
44
|
+
const pid = readPid();
|
|
45
|
+
if (pid === null) return { running: false };
|
|
46
|
+
if (isAlive(pid)) return { running: true, pid };
|
|
47
|
+
removePid();
|
|
48
|
+
return { running: false };
|
|
49
|
+
}
|
|
50
|
+
function startDaemon(port) {
|
|
51
|
+
const status = getStatus();
|
|
52
|
+
if (status.running) {
|
|
53
|
+
return { error: `Already running (PID ${status.pid})` };
|
|
54
|
+
}
|
|
55
|
+
const logDir = path.dirname(LOG_FILE);
|
|
56
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
57
|
+
const cliPath = path.resolve(process.argv[1]);
|
|
58
|
+
const out = fs.openSync(LOG_FILE, "a");
|
|
59
|
+
const err = fs.openSync(LOG_FILE, "a");
|
|
60
|
+
const child = spawn(
|
|
61
|
+
process.execPath,
|
|
62
|
+
[cliPath, "--daemon-child", String(port)],
|
|
63
|
+
{
|
|
64
|
+
detached: true,
|
|
65
|
+
stdio: ["ignore", out, err]
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
fs.closeSync(out);
|
|
69
|
+
fs.closeSync(err);
|
|
70
|
+
if (!child.pid) return { error: "Failed to spawn daemon" };
|
|
71
|
+
writePid(child.pid);
|
|
72
|
+
child.unref();
|
|
73
|
+
return { pid: child.pid };
|
|
74
|
+
}
|
|
75
|
+
async function stopDaemon() {
|
|
76
|
+
const pid = readPid();
|
|
77
|
+
if (pid === null) return { stopped: false, error: "Not running" };
|
|
78
|
+
if (!isAlive(pid)) {
|
|
79
|
+
removePid();
|
|
80
|
+
return { stopped: false, error: "Not running (stale PID removed)" };
|
|
81
|
+
}
|
|
82
|
+
process.kill(pid, "SIGTERM");
|
|
83
|
+
for (let i = 0; i < 50; i++) {
|
|
84
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
85
|
+
if (!isAlive(pid)) {
|
|
86
|
+
removePid();
|
|
87
|
+
return { stopped: true, pid };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
process.kill(pid, "SIGKILL");
|
|
92
|
+
} catch {
|
|
93
|
+
}
|
|
94
|
+
removePid();
|
|
95
|
+
return { stopped: true, pid };
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
getLogFile,
|
|
99
|
+
getPidFile,
|
|
100
|
+
getStatus,
|
|
101
|
+
startDaemon,
|
|
102
|
+
stopDaemon
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=daemon-CGBV55JK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/daemon.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nconst HOME_DIR = path.join(os.homedir(), \".jira-acp\");\nconst PID_FILE = path.join(HOME_DIR, \"jira-acp.pid\");\nconst LOG_FILE = path.join(HOME_DIR, \"logs\", \"jira-acp.log\");\n\nexport function getPidFile(): string {\n return PID_FILE;\n}\n\nexport function getLogFile(): string {\n return LOG_FILE;\n}\n\nfunction readPid(): number | null {\n try {\n const pid = parseInt(fs.readFileSync(PID_FILE, \"utf8\").trim(), 10);\n return isNaN(pid) ? null : pid;\n } catch {\n return null;\n }\n}\n\nfunction writePid(pid: number): void {\n fs.mkdirSync(path.dirname(PID_FILE), { recursive: true });\n fs.writeFileSync(PID_FILE, String(pid));\n}\n\nfunction removePid(): void {\n try {\n fs.unlinkSync(PID_FILE);\n } catch {\n // already gone\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getStatus(): { running: boolean; pid?: number } {\n const pid = readPid();\n if (pid === null) return { running: false };\n if (isAlive(pid)) return { running: true, pid };\n removePid();\n return { running: false };\n}\n\nexport function startDaemon(port: number): { pid: number } | { error: string } {\n const status = getStatus();\n if (status.running) {\n return { error: `Already running (PID ${status.pid})` };\n }\n\n const logDir = path.dirname(LOG_FILE);\n fs.mkdirSync(logDir, { recursive: true });\n\n const cliPath = path.resolve(process.argv[1]!);\n const out = fs.openSync(LOG_FILE, \"a\");\n const err = fs.openSync(LOG_FILE, \"a\");\n\n const child = spawn(\n process.execPath,\n [cliPath, \"--daemon-child\", String(port)],\n {\n detached: true,\n stdio: [\"ignore\", out, err],\n },\n );\n\n fs.closeSync(out);\n fs.closeSync(err);\n\n if (!child.pid) return { error: \"Failed to spawn daemon\" };\n\n writePid(child.pid);\n child.unref();\n\n return { pid: child.pid };\n}\n\nexport async function stopDaemon(): Promise<{\n stopped: boolean;\n pid?: number;\n error?: string;\n}> {\n const pid = readPid();\n if (pid === null) return { stopped: false, error: \"Not running\" };\n if (!isAlive(pid)) {\n removePid();\n return { stopped: false, error: \"Not running (stale PID removed)\" };\n }\n\n process.kill(pid, \"SIGTERM\");\n\n // Wait up to 5s for clean exit\n for (let i = 0; i < 50; i++) {\n await new Promise((r) => setTimeout(r, 100));\n if (!isAlive(pid)) {\n removePid();\n return { stopped: true, pid };\n }\n }\n\n // Force kill\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {\n // ignore\n }\n removePid();\n return { stopped: true, pid };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
StateManager
|
|
4
|
+
} from "./chunk-VWBCDZWQ.js";
|
|
5
|
+
import {
|
|
6
|
+
listProjects
|
|
7
|
+
} from "./chunk-3YHD4SIN.js";
|
|
8
|
+
import "./chunk-LIEW4ULF.js";
|
|
9
|
+
|
|
10
|
+
// src/commands/dashboard.ts
|
|
11
|
+
import fs from "fs";
|
|
12
|
+
import path from "path";
|
|
13
|
+
import os from "os";
|
|
14
|
+
import pc from "picocolors";
|
|
15
|
+
var RUNS_DIR = path.join(os.homedir(), ".jira-acp", "runs");
|
|
16
|
+
var REFRESH_MS = 5e3;
|
|
17
|
+
var STALE_AFTER_MS = 24 * 60 * 60 * 1e3;
|
|
18
|
+
function collectRuns() {
|
|
19
|
+
const projects = listProjects();
|
|
20
|
+
const rows = [];
|
|
21
|
+
const cutoff = Date.now() - STALE_AFTER_MS;
|
|
22
|
+
for (const project of projects) {
|
|
23
|
+
const projectRunsDir = path.join(RUNS_DIR, project);
|
|
24
|
+
if (!fs.existsSync(projectRunsDir)) continue;
|
|
25
|
+
const tickets = fs.readdirSync(projectRunsDir).filter((f) => fs.statSync(path.join(projectRunsDir, f)).isDirectory()).filter((f) => f !== "__triage__");
|
|
26
|
+
for (const ticketKey of tickets) {
|
|
27
|
+
const runDir = path.join(projectRunsDir, ticketKey);
|
|
28
|
+
const stateFile = path.join(runDir, "state.json");
|
|
29
|
+
if (!fs.existsSync(stateFile)) continue;
|
|
30
|
+
try {
|
|
31
|
+
const state = new StateManager(runDir).current;
|
|
32
|
+
if ((state.isCompleted || state.isAborted) && state.startedAt) {
|
|
33
|
+
if (new Date(state.startedAt).getTime() < cutoff) continue;
|
|
34
|
+
}
|
|
35
|
+
const stage = state.currentStage ?? (state.isCompleted ? "done" : state.failedStage ?? "\u2014");
|
|
36
|
+
let statusRaw;
|
|
37
|
+
let statusLabel;
|
|
38
|
+
if (state.isCompleted) {
|
|
39
|
+
statusRaw = "completed";
|
|
40
|
+
statusLabel = pc.green("completed");
|
|
41
|
+
} else if (state.isAborted) {
|
|
42
|
+
statusRaw = "aborted";
|
|
43
|
+
statusLabel = pc.red("aborted");
|
|
44
|
+
} else if (state.failedStage) {
|
|
45
|
+
statusRaw = "failed";
|
|
46
|
+
statusLabel = pc.red("failed");
|
|
47
|
+
} else if (state.pendingClarification || state.pendingHumanApproval) {
|
|
48
|
+
statusRaw = "waiting";
|
|
49
|
+
statusLabel = pc.yellow("waiting");
|
|
50
|
+
} else {
|
|
51
|
+
statusRaw = "running";
|
|
52
|
+
statusLabel = pc.cyan("running");
|
|
53
|
+
}
|
|
54
|
+
const elapsed = state.startedAt ? formatElapsed(state.startedAt) : "\u2014";
|
|
55
|
+
rows.push({
|
|
56
|
+
project,
|
|
57
|
+
ticketKey,
|
|
58
|
+
stage: String(stage),
|
|
59
|
+
status: statusLabel,
|
|
60
|
+
statusRaw,
|
|
61
|
+
elapsed,
|
|
62
|
+
startedAt: state.startedAt
|
|
63
|
+
});
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return rows.sort((a, b) => {
|
|
69
|
+
const order = {
|
|
70
|
+
running: 0,
|
|
71
|
+
waiting: 1,
|
|
72
|
+
failed: 2,
|
|
73
|
+
aborted: 3,
|
|
74
|
+
completed: 4
|
|
75
|
+
};
|
|
76
|
+
const diff = order[a.statusRaw] - order[b.statusRaw];
|
|
77
|
+
if (diff !== 0) return diff;
|
|
78
|
+
return (b.startedAt ?? "").localeCompare(a.startedAt ?? "");
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function formatElapsed(startedAt) {
|
|
82
|
+
const ms = Date.now() - new Date(startedAt).getTime();
|
|
83
|
+
const secs = Math.floor(ms / 1e3);
|
|
84
|
+
if (secs < 60) return `${secs}s`;
|
|
85
|
+
const mins = Math.floor(secs / 60);
|
|
86
|
+
if (mins < 60) return `${mins}m ${secs % 60}s`;
|
|
87
|
+
const hours = Math.floor(mins / 60);
|
|
88
|
+
return `${hours}h ${mins % 60}m`;
|
|
89
|
+
}
|
|
90
|
+
function render(watch) {
|
|
91
|
+
if (watch) {
|
|
92
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
93
|
+
}
|
|
94
|
+
const rows = collectRuns();
|
|
95
|
+
const now = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
96
|
+
process.stdout.write(
|
|
97
|
+
`
|
|
98
|
+
${pc.bold(" jiraACP dashboard")}${watch ? ` ${pc.gray(`(refreshes every ${REFRESH_MS / 1e3}s \u2014 updated ${now})`)}` : ""}
|
|
99
|
+
|
|
100
|
+
`
|
|
101
|
+
);
|
|
102
|
+
if (rows.length === 0) {
|
|
103
|
+
process.stdout.write(
|
|
104
|
+
pc.gray(" No active or recent pipeline runs found.\n")
|
|
105
|
+
);
|
|
106
|
+
process.stdout.write(
|
|
107
|
+
pc.gray(" Start one with: jiraACP run <ticketKey>\n\n")
|
|
108
|
+
);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const col = { project: 18, ticket: 14, stage: 12, elapsed: 10, status: 22 };
|
|
112
|
+
process.stdout.write(
|
|
113
|
+
pc.bold(
|
|
114
|
+
` ${"Project".padEnd(col.project)} ${"Ticket".padEnd(col.ticket)} ${"Stage".padEnd(col.stage)} ${"Elapsed".padEnd(col.elapsed)} Status`
|
|
115
|
+
) + "\n"
|
|
116
|
+
);
|
|
117
|
+
process.stdout.write(
|
|
118
|
+
" " + "\u2500".repeat(
|
|
119
|
+
col.project + col.ticket + col.stage + col.elapsed + col.status + 4
|
|
120
|
+
) + "\n"
|
|
121
|
+
);
|
|
122
|
+
for (const row of rows) {
|
|
123
|
+
process.stdout.write(
|
|
124
|
+
` ${row.project.padEnd(col.project)} ${row.ticketKey.padEnd(col.ticket)} ${row.stage.padEnd(col.stage)} ${row.elapsed.padEnd(col.elapsed)} ${row.status}
|
|
125
|
+
`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
process.stdout.write("\n");
|
|
129
|
+
}
|
|
130
|
+
function runDashboard(watch) {
|
|
131
|
+
render(watch);
|
|
132
|
+
if (!watch) return;
|
|
133
|
+
const interval = setInterval(() => render(true), REFRESH_MS);
|
|
134
|
+
process.once("SIGINT", () => {
|
|
135
|
+
clearInterval(interval);
|
|
136
|
+
process.stdout.write("\n");
|
|
137
|
+
process.exit(0);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
export {
|
|
141
|
+
runDashboard
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=dashboard-YVFJ5DXR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/dashboard.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport pc from \"picocolors\";\nimport { StateManager } from \"../pipeline/state.js\";\nimport { listProjects } from \"../config/loader.js\";\n\nconst RUNS_DIR = path.join(os.homedir(), \".jira-acp\", \"runs\");\nconst REFRESH_MS = 5_000;\nconst STALE_AFTER_MS = 24 * 60 * 60 * 1_000; // 24h\n\ninterface RunRow {\n project: string;\n ticketKey: string;\n stage: string;\n status: string;\n statusRaw: \"running\" | \"waiting\" | \"completed\" | \"aborted\" | \"failed\";\n elapsed: string;\n startedAt: string | null;\n}\n\nfunction collectRuns(): RunRow[] {\n const projects = listProjects();\n const rows: RunRow[] = [];\n const cutoff = Date.now() - STALE_AFTER_MS;\n\n for (const project of projects) {\n const projectRunsDir = path.join(RUNS_DIR, project);\n if (!fs.existsSync(projectRunsDir)) continue;\n\n const tickets = fs\n .readdirSync(projectRunsDir)\n .filter((f) => fs.statSync(path.join(projectRunsDir, f)).isDirectory())\n .filter((f) => f !== \"__triage__\");\n\n for (const ticketKey of tickets) {\n const runDir = path.join(projectRunsDir, ticketKey);\n const stateFile = path.join(runDir, \"state.json\");\n if (!fs.existsSync(stateFile)) continue;\n\n try {\n const state = new StateManager(runDir).current;\n\n // Skip stale completed/aborted runs older than 24h\n if ((state.isCompleted || state.isAborted) && state.startedAt) {\n if (new Date(state.startedAt).getTime() < cutoff) continue;\n }\n\n const stage =\n state.currentStage ??\n (state.isCompleted ? \"done\" : (state.failedStage ?? \"—\"));\n\n let statusRaw: RunRow[\"statusRaw\"];\n let statusLabel: string;\n\n if (state.isCompleted) {\n statusRaw = \"completed\";\n statusLabel = pc.green(\"completed\");\n } else if (state.isAborted) {\n statusRaw = \"aborted\";\n statusLabel = pc.red(\"aborted\");\n } else if (state.failedStage) {\n statusRaw = \"failed\";\n statusLabel = pc.red(\"failed\");\n } else if (state.pendingClarification || state.pendingHumanApproval) {\n statusRaw = \"waiting\";\n statusLabel = pc.yellow(\"waiting\");\n } else {\n statusRaw = \"running\";\n statusLabel = pc.cyan(\"running\");\n }\n\n const elapsed = state.startedAt ? formatElapsed(state.startedAt) : \"—\";\n\n rows.push({\n project,\n ticketKey,\n stage: String(stage),\n status: statusLabel,\n statusRaw,\n elapsed,\n startedAt: state.startedAt,\n });\n } catch {\n // Corrupted state file — skip\n }\n }\n }\n\n // Sort: running first, then by startedAt desc\n return rows.sort((a, b) => {\n const order: Record<RunRow[\"statusRaw\"], number> = {\n running: 0,\n waiting: 1,\n failed: 2,\n aborted: 3,\n completed: 4,\n };\n const diff = order[a.statusRaw] - order[b.statusRaw];\n if (diff !== 0) return diff;\n return (b.startedAt ?? \"\").localeCompare(a.startedAt ?? \"\");\n });\n}\n\nfunction formatElapsed(startedAt: string): string {\n const ms = Date.now() - new Date(startedAt).getTime();\n const secs = Math.floor(ms / 1_000);\n if (secs < 60) return `${secs}s`;\n const mins = Math.floor(secs / 60);\n if (mins < 60) return `${mins}m ${secs % 60}s`;\n const hours = Math.floor(mins / 60);\n return `${hours}h ${mins % 60}m`;\n}\n\nfunction render(watch: boolean): void {\n if (watch) {\n process.stdout.write(\"\\x1b[2J\\x1b[H\"); // clear screen + move cursor to top\n }\n\n const rows = collectRuns();\n const now = new Date().toLocaleTimeString();\n\n process.stdout.write(\n `\\n${pc.bold(\" jiraACP dashboard\")}${watch ? ` ${pc.gray(`(refreshes every ${REFRESH_MS / 1000}s — updated ${now})`)}` : \"\"}\\n\\n`,\n );\n\n if (rows.length === 0) {\n process.stdout.write(\n pc.gray(\" No active or recent pipeline runs found.\\n\"),\n );\n process.stdout.write(\n pc.gray(\" Start one with: jiraACP run <ticketKey>\\n\\n\"),\n );\n return;\n }\n\n const col = { project: 18, ticket: 14, stage: 12, elapsed: 10, status: 22 };\n process.stdout.write(\n pc.bold(\n ` ${\"Project\".padEnd(col.project)} ${\"Ticket\".padEnd(col.ticket)} ${\"Stage\".padEnd(col.stage)} ${\"Elapsed\".padEnd(col.elapsed)} Status`,\n ) + \"\\n\",\n );\n process.stdout.write(\n \" \" +\n \"─\".repeat(\n col.project + col.ticket + col.stage + col.elapsed + col.status + 4,\n ) +\n \"\\n\",\n );\n\n for (const row of rows) {\n process.stdout.write(\n ` ${row.project.padEnd(col.project)} ${row.ticketKey.padEnd(col.ticket)} ${row.stage.padEnd(col.stage)} ${row.elapsed.padEnd(col.elapsed)} ${row.status}\\n`,\n );\n }\n process.stdout.write(\"\\n\");\n}\n\nexport function runDashboard(watch: boolean): void {\n render(watch);\n\n if (!watch) return;\n\n // Keep refreshing until Ctrl+C\n const interval = setInterval(() => render(true), REFRESH_MS);\n\n process.once(\"SIGINT\", () => {\n clearInterval(interval);\n process.stdout.write(\"\\n\");\n process.exit(0);\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
spawnSafe
|
|
4
|
+
} from "./chunk-UDTWVKRX.js";
|
|
5
|
+
import {
|
|
6
|
+
configExists,
|
|
7
|
+
loadConfig
|
|
8
|
+
} from "./chunk-3YHD4SIN.js";
|
|
9
|
+
import "./chunk-LIEW4ULF.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/doctor.ts
|
|
12
|
+
import pc from "picocolors";
|
|
13
|
+
import axios from "axios";
|
|
14
|
+
async function runDoctor(projectName, _fix) {
|
|
15
|
+
console.log(pc.bold(`
|
|
16
|
+
jiraACP doctor \u2014 ${projectName}
|
|
17
|
+
`));
|
|
18
|
+
const results = [];
|
|
19
|
+
const nodeVersion = process.version;
|
|
20
|
+
results.push({
|
|
21
|
+
name: "Node.js >= 20",
|
|
22
|
+
ok: parseInt(nodeVersion.slice(1)) >= 20,
|
|
23
|
+
message: nodeVersion
|
|
24
|
+
});
|
|
25
|
+
const claudeResult = await spawnSafe("claude", ["--version"], {
|
|
26
|
+
timeoutMs: 5e3
|
|
27
|
+
});
|
|
28
|
+
results.push({
|
|
29
|
+
name: "claude CLI installed",
|
|
30
|
+
ok: claudeResult.exitCode === 0,
|
|
31
|
+
message: claudeResult.stdout.trim() || claudeResult.stderr.trim() || "not found"
|
|
32
|
+
});
|
|
33
|
+
const hasConfig = configExists(projectName);
|
|
34
|
+
results.push({
|
|
35
|
+
name: "project config exists",
|
|
36
|
+
ok: hasConfig,
|
|
37
|
+
message: hasConfig ? `~/.jira-acp/projects/${projectName}.json` : `Run: jiraACP init --name ${projectName}`
|
|
38
|
+
});
|
|
39
|
+
if (!hasConfig) {
|
|
40
|
+
printResults(results);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const config = loadConfig(projectName);
|
|
45
|
+
try {
|
|
46
|
+
await axios.get(`${config.jira.url}/rest/api/3/myself`, {
|
|
47
|
+
headers: {
|
|
48
|
+
Authorization: `Basic ${Buffer.from(`${config.jira.email}:${config.jira.token}`).toString("base64")}`
|
|
49
|
+
},
|
|
50
|
+
timeout: 5e3
|
|
51
|
+
});
|
|
52
|
+
results.push({
|
|
53
|
+
name: "Jira connectivity",
|
|
54
|
+
ok: true,
|
|
55
|
+
message: `${config.jira.url} \u2713`
|
|
56
|
+
});
|
|
57
|
+
} catch {
|
|
58
|
+
results.push({
|
|
59
|
+
name: "Jira connectivity",
|
|
60
|
+
ok: false,
|
|
61
|
+
message: `${config.jira.url} \u2014 connection failed`
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
results.push({
|
|
65
|
+
name: "GitHub token",
|
|
66
|
+
ok: Boolean(config.github.token),
|
|
67
|
+
message: config.github.token ? "set" : "empty \u2014 run: jiraACP config set github.token <token>"
|
|
68
|
+
});
|
|
69
|
+
results.push({
|
|
70
|
+
name: "Telegram bot token",
|
|
71
|
+
ok: Boolean(config.telegram.botToken),
|
|
72
|
+
message: config.telegram.botToken ? "set" : "empty"
|
|
73
|
+
});
|
|
74
|
+
} catch (err) {
|
|
75
|
+
results.push({ name: "Config load", ok: false, message: String(err) });
|
|
76
|
+
}
|
|
77
|
+
printResults(results);
|
|
78
|
+
}
|
|
79
|
+
function printResults(results) {
|
|
80
|
+
for (const r of results) {
|
|
81
|
+
const icon = r.ok ? pc.green("\u2713") : pc.red("\u2717");
|
|
82
|
+
const name = r.ok ? pc.green(r.name) : pc.red(r.name);
|
|
83
|
+
console.log(` ${icon} ${name} ${pc.gray(r.message)}`);
|
|
84
|
+
}
|
|
85
|
+
const failed = results.filter((r) => !r.ok);
|
|
86
|
+
console.log();
|
|
87
|
+
if (failed.length === 0) {
|
|
88
|
+
console.log(pc.green(" All checks passed.\n"));
|
|
89
|
+
} else {
|
|
90
|
+
console.log(pc.red(` ${failed.length} check(s) failed.
|
|
91
|
+
`));
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export {
|
|
96
|
+
runDoctor
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=doctor-BPTLVLTD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/doctor.ts"],"sourcesContent":["import pc from \"picocolors\";\nimport { spawnSafe } from \"../utils/process.js\";\nimport { configExists, loadConfig } from \"../config/loader.js\";\nimport axios from \"axios\";\n\ninterface CheckResult {\n name: string;\n ok: boolean;\n message: string;\n}\n\nexport async function runDoctor(\n projectName: string,\n _fix: boolean,\n): Promise<void> {\n console.log(pc.bold(`\\n jiraACP doctor — ${projectName}\\n`));\n\n const results: CheckResult[] = [];\n\n // 1. Node version\n const nodeVersion = process.version;\n results.push({\n name: \"Node.js >= 20\",\n ok: parseInt(nodeVersion.slice(1)) >= 20,\n message: nodeVersion,\n });\n\n // 2. claude CLI (subscription-based, no API key needed)\n const claudeResult = await spawnSafe(\"claude\", [\"--version\"], {\n timeoutMs: 5_000,\n });\n results.push({\n name: \"claude CLI installed\",\n ok: claudeResult.exitCode === 0,\n message:\n claudeResult.stdout.trim() || claudeResult.stderr.trim() || \"not found\",\n });\n\n // 3. Project config\n const hasConfig = configExists(projectName);\n results.push({\n name: \"project config exists\",\n ok: hasConfig,\n message: hasConfig\n ? `~/.jira-acp/projects/${projectName}.json`\n : `Run: jiraACP init --name ${projectName}`,\n });\n\n if (!hasConfig) {\n printResults(results);\n return;\n }\n\n try {\n const config = loadConfig(projectName);\n\n // 4. Jira connectivity (using tokens from config)\n try {\n await axios.get(`${config.jira.url}/rest/api/3/myself`, {\n headers: {\n Authorization: `Basic ${Buffer.from(`${config.jira.email}:${config.jira.token}`).toString(\"base64\")}`,\n },\n timeout: 5_000,\n });\n results.push({\n name: \"Jira connectivity\",\n ok: true,\n message: `${config.jira.url} ✓`,\n });\n } catch {\n results.push({\n name: \"Jira connectivity\",\n ok: false,\n message: `${config.jira.url} — connection failed`,\n });\n }\n\n // 5. GitHub token\n results.push({\n name: \"GitHub token\",\n ok: Boolean(config.github.token),\n message: config.github.token\n ? \"set\"\n : \"empty — run: jiraACP config set github.token <token>\",\n });\n\n // 6. Telegram bot token\n results.push({\n name: \"Telegram bot token\",\n ok: Boolean(config.telegram.botToken),\n message: config.telegram.botToken ? \"set\" : \"empty\",\n });\n } catch (err) {\n results.push({ name: \"Config load\", ok: false, message: String(err) });\n }\n\n printResults(results);\n}\n\nfunction printResults(results: CheckResult[]): void {\n for (const r of results) {\n const icon = r.ok ? pc.green(\"✓\") : pc.red(\"✗\");\n const name = r.ok ? pc.green(r.name) : pc.red(r.name);\n console.log(` ${icon} ${name} ${pc.gray(r.message)}`);\n }\n\n const failed = results.filter((r) => !r.ok);\n console.log();\n if (failed.length === 0) {\n console.log(pc.green(\" All checks passed.\\n\"));\n } else {\n console.log(pc.red(` ${failed.length} check(s) failed.\\n`));\n process.exitCode = 1;\n }\n}\n"],"mappings":";;;;;;;;;;;AAAA,OAAO,QAAQ;AAGf,OAAO,WAAW;AAQlB,eAAsB,UACpB,aACA,MACe;AACf,UAAQ,IAAI,GAAG,KAAK;AAAA,0BAAwB,WAAW;AAAA,CAAI,CAAC;AAE5D,QAAM,UAAyB,CAAC;AAGhC,QAAM,cAAc,QAAQ;AAC5B,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI,SAAS,YAAY,MAAM,CAAC,CAAC,KAAK;AAAA,IACtC,SAAS;AAAA,EACX,CAAC;AAGD,QAAM,eAAe,MAAM,UAAU,UAAU,CAAC,WAAW,GAAG;AAAA,IAC5D,WAAW;AAAA,EACb,CAAC;AACD,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI,aAAa,aAAa;AAAA,IAC9B,SACE,aAAa,OAAO,KAAK,KAAK,aAAa,OAAO,KAAK,KAAK;AAAA,EAChE,CAAC;AAGD,QAAM,YAAY,aAAa,WAAW;AAC1C,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,SAAS,YACL,wBAAwB,WAAW,UACnC,4BAA4B,WAAW;AAAA,EAC7C,CAAC;AAED,MAAI,CAAC,WAAW;AACd,iBAAa,OAAO;AACpB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,SAAS,WAAW,WAAW;AAGrC,QAAI;AACF,YAAM,MAAM,IAAI,GAAG,OAAO,KAAK,GAAG,sBAAsB;AAAA,QACtD,SAAS;AAAA,UACP,eAAe,SAAS,OAAO,KAAK,GAAG,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,KAAK,EAAE,EAAE,SAAS,QAAQ,CAAC;AAAA,QACrG;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AACD,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,SAAS,GAAG,OAAO,KAAK,GAAG;AAAA,MAC7B,CAAC;AAAA,IACH,QAAQ;AACN,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,SAAS,GAAG,OAAO,KAAK,GAAG;AAAA,MAC7B,CAAC;AAAA,IACH;AAGA,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,IAAI,QAAQ,OAAO,OAAO,KAAK;AAAA,MAC/B,SAAS,OAAO,OAAO,QACnB,QACA;AAAA,IACN,CAAC;AAGD,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,IAAI,QAAQ,OAAO,SAAS,QAAQ;AAAA,MACpC,SAAS,OAAO,SAAS,WAAW,QAAQ;AAAA,IAC9C,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,KAAK,EAAE,MAAM,eAAe,IAAI,OAAO,SAAS,OAAO,GAAG,EAAE,CAAC;AAAA,EACvE;AAEA,eAAa,OAAO;AACtB;AAEA,SAAS,aAAa,SAA8B;AAClD,aAAW,KAAK,SAAS;AACvB,UAAM,OAAO,EAAE,KAAK,GAAG,MAAM,QAAG,IAAI,GAAG,IAAI,QAAG;AAC9C,UAAM,OAAO,EAAE,KAAK,GAAG,MAAM,EAAE,IAAI,IAAI,GAAG,IAAI,EAAE,IAAI;AACpD,YAAQ,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,KAAK,EAAE,OAAO,CAAC,EAAE;AAAA,EACzD;AAEA,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE;AAC1C,UAAQ,IAAI;AACZ,MAAI,OAAO,WAAW,GAAG;AACvB,YAAQ,IAAI,GAAG,MAAM,wBAAwB,CAAC;AAAA,EAChD,OAAO;AACL,YAAQ,IAAI,GAAG,IAAI,KAAK,OAAO,MAAM;AAAA,CAAqB,CAAC;AAC3D,YAAQ,WAAW;AAAA,EACrB;AACF;","names":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadPendingStore,
|
|
3
|
+
registerAnswerHandler,
|
|
4
|
+
registerApprovalHandlers,
|
|
5
|
+
requestApproval,
|
|
6
|
+
requestClarification
|
|
7
|
+
} from "./chunk-KSJKCLEJ.js";
|
|
8
|
+
import "./chunk-M4V3YOCY.js";
|
|
9
|
+
export {
|
|
10
|
+
loadPendingStore,
|
|
11
|
+
registerAnswerHandler,
|
|
12
|
+
registerApprovalHandlers,
|
|
13
|
+
requestApproval,
|
|
14
|
+
requestClarification
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=human-loop-RBTA2TYK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadPendingStore,
|
|
4
|
+
registerAnswerHandler,
|
|
5
|
+
registerApprovalHandlers,
|
|
6
|
+
requestApproval,
|
|
7
|
+
requestClarification
|
|
8
|
+
} from "./chunk-YJK7IRPI.js";
|
|
9
|
+
import "./chunk-OJ4CNF73.js";
|
|
10
|
+
import "./chunk-IT74N3UH.js";
|
|
11
|
+
export {
|
|
12
|
+
loadPendingStore,
|
|
13
|
+
registerAnswerHandler,
|
|
14
|
+
registerApprovalHandlers,
|
|
15
|
+
requestApproval,
|
|
16
|
+
requestClarification
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=human-loop-XGWXUNCS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|