hypercore-cli 1.1.2 → 1.3.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/LICENSE +92 -21
- package/README.md +8 -1
- package/dist/App-YMX7FSXR.js +1 -0
- package/dist/api-Q2TX5JJL.js +1 -0
- package/dist/auth-X6CUT3DW.js +1 -0
- package/dist/background-ACODXSUG.js +1 -0
- package/dist/backlog-JD2IM336.js +1 -0
- package/dist/chunk-2QI2IU2V.js +1 -0
- package/dist/chunk-3KFRDIPQ.js +1 -0
- package/dist/chunk-42C5J7PN.js +1 -0
- package/dist/chunk-4D7XVJ7Q.js +1 -0
- package/dist/chunk-545IGTXV.js +1 -0
- package/dist/chunk-5KUSGQP2.js +1 -0
- package/dist/chunk-AUQ64BK2.js +1 -0
- package/dist/chunk-AV244H5C.js +1 -0
- package/dist/chunk-BQVBEFS4.js +1 -0
- package/dist/chunk-BYWQLFP2.js +1 -0
- package/dist/chunk-COITWWZJ.js +1 -0
- package/dist/chunk-CR7UUJVX.js +1 -0
- package/dist/chunk-E3MULLBX.js +1 -0
- package/dist/chunk-EWBV7YPP.js +1 -0
- package/dist/chunk-EZHYVJGQ.js +1 -0
- package/dist/chunk-FAKXBY7Q.js +1 -0
- package/dist/chunk-FHGATV5B.js +1 -0
- package/dist/chunk-I2G27Y5P.js +1 -0
- package/dist/chunk-IKF43TX2.js +1 -0
- package/dist/chunk-INSPHCBN.js +1 -0
- package/dist/chunk-LQMDUKIE.js +1 -0
- package/dist/chunk-M3MTKGA5.js +1 -0
- package/dist/chunk-MPO54FU3.js +1 -0
- package/dist/chunk-PVKCZI6A.js +1 -0
- package/dist/chunk-Q7KEPCYL.js +1 -0
- package/dist/chunk-R5XD3NT2.js +1 -0
- package/dist/chunk-ROBZ6PAL.js +1 -0
- package/dist/chunk-RXB5BS2N.js +1 -0
- package/dist/chunk-RZ3HNYMT.js +1 -0
- package/dist/chunk-UCGLRMTG.js +1 -0
- package/dist/chunk-UEHJVRKB.js +1 -0
- package/dist/chunk-UZYX5GGF.js +1 -0
- package/dist/chunk-XQJBB725.js +1 -0
- package/dist/chunk-ZB5ZQSXH.js +1 -0
- package/dist/claude-US2QPRBA.js +1 -0
- package/dist/commands-5TFN74MD.js +1 -0
- package/dist/commands-EKPWCB3T.js +1 -0
- package/dist/commands-QHJLREPM.js +1 -0
- package/dist/config-2OUL5FLS.js +1 -0
- package/dist/config-loader-N7IBWN2P.js +1 -0
- package/dist/diagnose-NLHN4SAJ.js +1 -0
- package/dist/display-TB5YACJV.js +1 -0
- package/dist/extractor-3KTM2IUL.js +1 -0
- package/dist/feature-flag-VVIF5FJG.js +1 -0
- package/dist/history-GVNDPXXQ.js +1 -0
- package/dist/index.js +1 -402
- package/dist/instance-registry-I5AIVJE2.js +1 -0
- package/dist/keybindings-RN3A7CRW.js +1 -0
- package/dist/loader-3IKPXP4R.js +1 -0
- package/dist/network-GI2F3IDE.js +1 -0
- package/dist/notify-O6FNVHC4.js +1 -0
- package/dist/openai-compat-IPCMINVF.js +1 -0
- package/dist/permissions-5O7KVAXU.js +1 -0
- package/dist/prompt-VWFPFM4N.js +1 -0
- package/dist/quality-GPQD25UL.js +1 -0
- package/dist/repl-YNXCDVU4.js +1 -0
- package/dist/roadmap-QRZODSNJ.js +1 -0
- package/dist/server-USQP4GC4.js +1 -0
- package/dist/session-5HDDQQP6.js +1 -0
- package/dist/skills-DXWSVJSU.js +1 -0
- package/dist/store-WXXTKTTL.js +1 -0
- package/dist/team-VTPJ3WRT.js +1 -0
- package/dist/telemetry-NT4UZLBS.js +1 -0
- package/dist/test-runner-F6B6RH3S.js +1 -0
- package/dist/theme-JJJ6ABR2.js +1 -0
- package/dist/upgrade-RUG3R7R5.js +1 -0
- package/dist/verify-6OGRY2PR.js +1 -0
- package/dist/version-DLROA5JN.js +1 -0
- package/dist/web/static/app.js +1 -562
- package/dist/web/static/index.html +114 -126
- package/dist/web/static/mirror.css +1 -1001
- package/dist/web/static/mirror.html +155 -178
- package/dist/web/static/mirror.js +1 -1125
- package/dist/web/static/onboard.css +1 -302
- package/dist/web/static/onboard.html +121 -145
- package/dist/web/static/onboard.js +1 -300
- package/dist/web/static/style.css +1 -602
- package/dist/web/static/utils.js +1 -0
- package/dist/web/static/workspace.css +1 -1568
- package/dist/web/static/workspace.html +369 -402
- package/dist/web/static/workspace.js +1 -1683
- package/dist/web-P5YUKEAU.js +1 -0
- package/package.json +25 -4
- package/dist/api-JHHOZTL6.js +0 -162
- package/dist/auth-5QFJLW7J.js +0 -21
- package/dist/background-2EGCAAQH.js +0 -14
- package/dist/backlog-Q2NZCLNY.js +0 -24
- package/dist/chunk-2CMSCWQW.js +0 -162
- package/dist/chunk-4DVYJAJL.js +0 -57
- package/dist/chunk-5GDYH676.js +0 -271
- package/dist/chunk-5NLVGLD7.js +0 -66
- package/dist/chunk-6XTEAFZQ.js +0 -575
- package/dist/chunk-AQBSMYLT.js +0 -2025
- package/dist/chunk-BE46C7JW.js +0 -46
- package/dist/chunk-CLKIMCXZ.js +0 -139
- package/dist/chunk-DN4ASQ26.js +0 -167
- package/dist/chunk-DUWREZXK.js +0 -173
- package/dist/chunk-FCW3K6F2.js +0 -263
- package/dist/chunk-GFORWAMW.js +0 -251
- package/dist/chunk-GH7E2OJE.js +0 -223
- package/dist/chunk-GU2FZQ6A.js +0 -69
- package/dist/chunk-I7WI3BMB.js +0 -161
- package/dist/chunk-IOPKN5GD.js +0 -190
- package/dist/chunk-LBVHDGZE.js +0 -133
- package/dist/chunk-MGLJ53QN.js +0 -219
- package/dist/chunk-NETIY5UB.js +0 -134
- package/dist/chunk-NP47L7LG.js +0 -288
- package/dist/chunk-O6MG7TOH.js +0 -58
- package/dist/chunk-OPZYEVYR.js +0 -150
- package/dist/chunk-R3GPQC7I.js +0 -393
- package/dist/chunk-R5T3A2NQ.js +0 -166
- package/dist/chunk-RKB2JOV2.js +0 -43
- package/dist/chunk-RNG3K465.js +0 -80
- package/dist/chunk-TGTYKBGC.js +0 -86
- package/dist/chunk-UCX4VZCT.js +0 -681
- package/dist/chunk-WHLVZCQY.js +0 -245
- package/dist/chunk-Y6HMJZDJ.js +0 -1505
- package/dist/chunk-ZSBHUGWR.js +0 -262
- package/dist/claude-4BX3MJSK.js +0 -12
- package/dist/commands-2X4OB5RF.js +0 -128
- package/dist/commands-GLBCEVQK.js +0 -1044
- package/dist/commands-IINRNBYX.js +0 -232
- package/dist/config-RSNQJQPS.js +0 -8
- package/dist/config-loader-SXO674TF.js +0 -24
- package/dist/diagnose-7UPLS7I4.js +0 -12
- package/dist/display-IIUBEYWN.js +0 -58
- package/dist/extractor-D3XWOAXI.js +0 -129
- package/dist/history-6I6FADAU.js +0 -180
- package/dist/index.d.ts +0 -1
- package/dist/instance-registry-J7UJ7U4Z.js +0 -15
- package/dist/keybindings-PDXIOV3O.js +0 -15
- package/dist/loader-GKEYT6Y7.js +0 -58
- package/dist/network-JYGHQXAR.js +0 -279
- package/dist/notify-HPTALZDC.js +0 -14
- package/dist/openai-compat-R7EKWG6Z.js +0 -12
- package/dist/permissions-JUKXMNDH.js +0 -10
- package/dist/prompt-UWHSZU4P.js +0 -166
- package/dist/quality-ST7PPNFR.js +0 -16
- package/dist/repl-QHIZ2JGF.js +0 -3374
- package/dist/roadmap-5OBEKROY.js +0 -17
- package/dist/server-HCNIP7ZQ.js +0 -57
- package/dist/session-5EBECDUP.js +0 -21
- package/dist/skills-HBQQTYO4.js +0 -175
- package/dist/store-FKUTR7GW.js +0 -25
- package/dist/team-7BBBP5YQ.js +0 -385
- package/dist/telemetry-6R4EIE6O.js +0 -30
- package/dist/test-runner-AUAGIBNM.js +0 -619
- package/dist/theme-3SYJ3UQA.js +0 -14
- package/dist/upgrade-MZFH7OCN.js +0 -83
- package/dist/verify-JUDKTPKZ.js +0 -14
- package/dist/web-KS3FUGJA.js +0 -39
|
@@ -1,1044 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
activateMilestone,
|
|
3
|
-
addMilestone,
|
|
4
|
-
doneMilestone,
|
|
5
|
-
getRoadmap,
|
|
6
|
-
listMilestones
|
|
7
|
-
} from "./chunk-OPZYEVYR.js";
|
|
8
|
-
import {
|
|
9
|
-
checkBuild,
|
|
10
|
-
checkDeps,
|
|
11
|
-
checkPackageSize,
|
|
12
|
-
checkTests,
|
|
13
|
-
checkTodos,
|
|
14
|
-
runQualityReport
|
|
15
|
-
} from "./chunk-ZSBHUGWR.js";
|
|
16
|
-
import {
|
|
17
|
-
findingsToBacklog,
|
|
18
|
-
runAIDiagnosis,
|
|
19
|
-
runRuleDiagnosis
|
|
20
|
-
} from "./chunk-NP47L7LG.js";
|
|
21
|
-
import {
|
|
22
|
-
recordBaseline,
|
|
23
|
-
verifyCompletedItems
|
|
24
|
-
} from "./chunk-IOPKN5GD.js";
|
|
25
|
-
import {
|
|
26
|
-
getEventsSummary
|
|
27
|
-
} from "./chunk-2CMSCWQW.js";
|
|
28
|
-
import {
|
|
29
|
-
addItem,
|
|
30
|
-
archiveItem,
|
|
31
|
-
doneItem,
|
|
32
|
-
getItem,
|
|
33
|
-
getStats,
|
|
34
|
-
listItems,
|
|
35
|
-
pickItem,
|
|
36
|
-
reopenItem,
|
|
37
|
-
updateItem
|
|
38
|
-
} from "./chunk-MGLJ53QN.js";
|
|
39
|
-
|
|
40
|
-
// src/admin/commands.ts
|
|
41
|
-
import chalk from "chalk";
|
|
42
|
-
|
|
43
|
-
// src/admin/version.ts
|
|
44
|
-
import { execSync } from "child_process";
|
|
45
|
-
import { join } from "path";
|
|
46
|
-
import { readFile } from "fs/promises";
|
|
47
|
-
import { existsSync } from "fs";
|
|
48
|
-
function git(cmd, cwd) {
|
|
49
|
-
try {
|
|
50
|
-
return execSync(`git ${cmd}`, {
|
|
51
|
-
cwd: cwd || process.cwd(),
|
|
52
|
-
encoding: "utf-8",
|
|
53
|
-
timeout: 1e4,
|
|
54
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
55
|
-
}).trim();
|
|
56
|
-
} catch {
|
|
57
|
-
return "";
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
function isGitRepo(cwd) {
|
|
61
|
-
return git("rev-parse --is-inside-work-tree", cwd) === "true";
|
|
62
|
-
}
|
|
63
|
-
async function getVersionInfo(projectRoot) {
|
|
64
|
-
const pkgPath = join(projectRoot, "package.json");
|
|
65
|
-
let currentVersion = "unknown";
|
|
66
|
-
if (existsSync(pkgPath)) {
|
|
67
|
-
try {
|
|
68
|
-
const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
|
|
69
|
-
currentVersion = pkg.version || "unknown";
|
|
70
|
-
} catch {
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (!isGitRepo(projectRoot)) {
|
|
74
|
-
return {
|
|
75
|
-
currentVersion,
|
|
76
|
-
lastTag: "",
|
|
77
|
-
lastTagDate: "",
|
|
78
|
-
daysSinceTag: 0,
|
|
79
|
-
pendingCommits: 0,
|
|
80
|
-
filesChanged: 0,
|
|
81
|
-
insertions: 0,
|
|
82
|
-
deletions: 0,
|
|
83
|
-
commitsByType: {},
|
|
84
|
-
recentCommits: []
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
const lastTag = git("describe --tags --abbrev=0 2>/dev/null", projectRoot) || "";
|
|
88
|
-
let lastTagDate = "";
|
|
89
|
-
let daysSinceTag = 0;
|
|
90
|
-
if (lastTag) {
|
|
91
|
-
lastTagDate = git(`log -1 --format=%ai ${lastTag}`, projectRoot).slice(0, 10);
|
|
92
|
-
const tagTime = new Date(lastTagDate).getTime();
|
|
93
|
-
daysSinceTag = Math.floor((Date.now() - tagTime) / 864e5);
|
|
94
|
-
}
|
|
95
|
-
const range = lastTag ? `${lastTag}..HEAD` : "HEAD";
|
|
96
|
-
const logRaw = git(`log ${range} --oneline`, projectRoot);
|
|
97
|
-
const pendingCommits = logRaw ? logRaw.split("\n").filter((l) => l.trim()).length : 0;
|
|
98
|
-
let filesChanged = 0;
|
|
99
|
-
let insertions = 0;
|
|
100
|
-
let deletions = 0;
|
|
101
|
-
if (lastTag) {
|
|
102
|
-
const diffStat = git(`diff --stat ${lastTag}..HEAD`, projectRoot);
|
|
103
|
-
const summaryLine = diffStat.split("\n").pop() || "";
|
|
104
|
-
const filesMatch = summaryLine.match(/(\d+) files? changed/);
|
|
105
|
-
const insMatch = summaryLine.match(/(\d+) insertions?/);
|
|
106
|
-
const delMatch = summaryLine.match(/(\d+) deletions?/);
|
|
107
|
-
filesChanged = filesMatch ? parseInt(filesMatch[1]) : 0;
|
|
108
|
-
insertions = insMatch ? parseInt(insMatch[1]) : 0;
|
|
109
|
-
deletions = delMatch ? parseInt(delMatch[1]) : 0;
|
|
110
|
-
}
|
|
111
|
-
const commitsByType = {};
|
|
112
|
-
const recentCommits = [];
|
|
113
|
-
if (pendingCommits > 0) {
|
|
114
|
-
const detailedLog = git(`log ${range} --format=%h|%s|%ai`, projectRoot);
|
|
115
|
-
for (const line of detailedLog.split("\n")) {
|
|
116
|
-
if (!line.trim()) continue;
|
|
117
|
-
const [hash, message, date] = line.split("|");
|
|
118
|
-
const typeMatch = message?.match(/^(\w+)[\(:]/);
|
|
119
|
-
const type = typeMatch ? typeMatch[1] : "other";
|
|
120
|
-
commitsByType[type] = (commitsByType[type] || 0) + 1;
|
|
121
|
-
if (recentCommits.length < 20) {
|
|
122
|
-
recentCommits.push({ hash, type, message: message || "", date: (date || "").slice(0, 10) });
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return {
|
|
127
|
-
currentVersion,
|
|
128
|
-
lastTag,
|
|
129
|
-
lastTagDate,
|
|
130
|
-
daysSinceTag,
|
|
131
|
-
pendingCommits,
|
|
132
|
-
filesChanged,
|
|
133
|
-
insertions,
|
|
134
|
-
deletions,
|
|
135
|
-
commitsByType,
|
|
136
|
-
recentCommits
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
async function runReleaseChecks(projectRoot) {
|
|
140
|
-
const checks = [];
|
|
141
|
-
try {
|
|
142
|
-
execSync("npm run build", { cwd: projectRoot, stdio: "pipe", timeout: 6e4 });
|
|
143
|
-
checks.push({ name: "Build", ok: true, detail: "\u901A\u8FC7" });
|
|
144
|
-
} catch {
|
|
145
|
-
checks.push({ name: "Build", ok: false, detail: "\u6784\u5EFA\u5931\u8D25" });
|
|
146
|
-
}
|
|
147
|
-
try {
|
|
148
|
-
const testOutput = execSync("npm test", { cwd: projectRoot, encoding: "utf-8", stdio: "pipe", timeout: 6e4 });
|
|
149
|
-
const passMatch = testOutput.match(/(\d+) passed/);
|
|
150
|
-
const passCount = passMatch ? passMatch[1] : "?";
|
|
151
|
-
checks.push({ name: "Test", ok: true, detail: `${passCount} \u901A\u8FC7` });
|
|
152
|
-
} catch {
|
|
153
|
-
checks.push({ name: "Test", ok: false, detail: "\u6D4B\u8BD5\u5931\u8D25" });
|
|
154
|
-
}
|
|
155
|
-
const status = git("status --porcelain", projectRoot);
|
|
156
|
-
const uncommitted = status ? status.split("\n").filter((l) => l.trim()).length : 0;
|
|
157
|
-
if (uncommitted === 0) {
|
|
158
|
-
checks.push({ name: "Git Status", ok: true, detail: "\u5DE5\u4F5C\u533A\u5E72\u51C0" });
|
|
159
|
-
} else {
|
|
160
|
-
checks.push({ name: "Git Status", ok: false, detail: `${uncommitted} \u4E2A\u672A\u63D0\u4EA4\u53D8\u66F4` });
|
|
161
|
-
}
|
|
162
|
-
const changelogExists = existsSync(join(projectRoot, "CHANGELOG.md"));
|
|
163
|
-
checks.push({ name: "CHANGELOG", ok: changelogExists, detail: changelogExists ? "\u5B58\u5728" : "\u672A\u521B\u5EFA" });
|
|
164
|
-
try {
|
|
165
|
-
const packOutput = execSync("npm pack --dry-run 2>&1", { cwd: projectRoot, encoding: "utf-8", timeout: 3e4 });
|
|
166
|
-
const sizeMatch = packOutput.match(/total files:\s*(\d+)/i) || packOutput.match(/(\d+)\s*files/i);
|
|
167
|
-
const bytesMatch = packOutput.match(/(\d+\.?\d*\s*[kKmM]?B)/);
|
|
168
|
-
const detail = `${bytesMatch ? bytesMatch[1] : "?"}, ${sizeMatch ? sizeMatch[1] : "?"} files`;
|
|
169
|
-
checks.push({ name: "Package", ok: true, detail });
|
|
170
|
-
} catch {
|
|
171
|
-
checks.push({ name: "Package", ok: false, detail: "pack \u5931\u8D25" });
|
|
172
|
-
}
|
|
173
|
-
const pkgPath = join(projectRoot, "package.json");
|
|
174
|
-
if (existsSync(pkgPath)) {
|
|
175
|
-
try {
|
|
176
|
-
const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
|
|
177
|
-
const tagName = `v${pkg.version}`;
|
|
178
|
-
const existingTag = git(`tag -l ${tagName}`, projectRoot);
|
|
179
|
-
if (existingTag) {
|
|
180
|
-
checks.push({ name: "Version", ok: false, detail: `tag ${tagName} \u5DF2\u5B58\u5728` });
|
|
181
|
-
} else {
|
|
182
|
-
checks.push({ name: "Version", ok: true, detail: `${tagName} \u53EF\u7528` });
|
|
183
|
-
}
|
|
184
|
-
} catch {
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return checks;
|
|
188
|
-
}
|
|
189
|
-
function getReleaseHistory(projectRoot) {
|
|
190
|
-
if (!isGitRepo(projectRoot)) return [];
|
|
191
|
-
const raw = git("tag -l --sort=-version:refname --format=%(refname:short)|%(creatordate:short)|%(subject)", projectRoot);
|
|
192
|
-
if (!raw) return [];
|
|
193
|
-
return raw.split("\n").filter((l) => l.trim()).map((line) => {
|
|
194
|
-
const [tag, date, ...msgParts] = line.split("|");
|
|
195
|
-
return { tag, date: date || "", message: msgParts.join("|") || "" };
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// src/admin/commands.ts
|
|
200
|
-
var WUXING_EMOJI = {
|
|
201
|
-
"\u6728": "\u{1F333}",
|
|
202
|
-
"\u706B": "\u{1F525}",
|
|
203
|
-
"\u6C34": "\u{1F30A}",
|
|
204
|
-
"\u91D1": "\u2699\uFE0F",
|
|
205
|
-
"\u571F": "\u{1F3D4}\uFE0F"
|
|
206
|
-
};
|
|
207
|
-
var STATUS_EMOJI = {
|
|
208
|
-
idea: "\u{1F4A1}",
|
|
209
|
-
planned: "\u2B1A",
|
|
210
|
-
developing: "\u{1F504}",
|
|
211
|
-
done: "\u2705",
|
|
212
|
-
archived: "\u{1F4E6}"
|
|
213
|
-
};
|
|
214
|
-
var TYPE_LABEL = {
|
|
215
|
-
feature: "\u529F\u80FD",
|
|
216
|
-
improvement: "\u6539\u8FDB",
|
|
217
|
-
idea: "\u60F3\u6CD5",
|
|
218
|
-
bugfix: "\u4FEE\u590D"
|
|
219
|
-
};
|
|
220
|
-
function parseOpts(args) {
|
|
221
|
-
const positional = [];
|
|
222
|
-
const opts = {};
|
|
223
|
-
for (let i = 0; i < args.length; i++) {
|
|
224
|
-
if (args[i].startsWith("--") && i + 1 < args.length) {
|
|
225
|
-
const key = args[i].slice(2);
|
|
226
|
-
opts[key] = args[++i];
|
|
227
|
-
} else if (args[i].startsWith("-") && args[i].length === 2 && i + 1 < args.length) {
|
|
228
|
-
const shortMap = { t: "type", w: "wuxing", p: "priority", v: "version", d: "desc" };
|
|
229
|
-
const key = shortMap[args[i][1]] || args[i][1];
|
|
230
|
-
opts[key] = args[++i];
|
|
231
|
-
} else {
|
|
232
|
-
positional.push(args[i]);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return { positional, opts };
|
|
236
|
-
}
|
|
237
|
-
async function handleAdd(args, _ctx) {
|
|
238
|
-
const { positional, opts } = parseOpts(args);
|
|
239
|
-
const title = positional.join(" ").trim();
|
|
240
|
-
if (!title) {
|
|
241
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin add <\u6807\u9898> [--type feature] [--wuxing \u6728] [--priority B] [--version v1.2] [--desc \u63CF\u8FF0]\n"));
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
const type = opts.type || "feature";
|
|
245
|
-
if (!["feature", "improvement", "idea", "bugfix"].includes(type)) {
|
|
246
|
-
console.log(chalk.red(`
|
|
247
|
-
type \u65E0\u6548: ${type}\uFF08\u53EF\u9009: feature/improvement/idea/bugfix\uFF09
|
|
248
|
-
`));
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
const wuxing = opts.wuxing || "\u6728";
|
|
252
|
-
if (!["\u6728", "\u706B", "\u6C34", "\u91D1", "\u571F"].includes(wuxing)) {
|
|
253
|
-
console.log(chalk.red(`
|
|
254
|
-
wuxing \u65E0\u6548: ${wuxing}\uFF08\u53EF\u9009: \u6728/\u706B/\u6C34/\u91D1/\u571F\uFF09
|
|
255
|
-
`));
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
const priority = opts.priority || "B";
|
|
259
|
-
if (!["S", "A", "B", "C"].includes(priority)) {
|
|
260
|
-
console.log(chalk.red(`
|
|
261
|
-
priority \u65E0\u6548: ${priority}\uFF08\u53EF\u9009: S/A/B/C\uFF09
|
|
262
|
-
`));
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
const item = await addItem({
|
|
266
|
-
title,
|
|
267
|
-
description: opts.desc || "",
|
|
268
|
-
type,
|
|
269
|
-
wuxing,
|
|
270
|
-
priority,
|
|
271
|
-
targetVersion: opts.version || "",
|
|
272
|
-
tags: opts.tag ? opts.tag.split(",") : []
|
|
273
|
-
});
|
|
274
|
-
const wx = WUXING_EMOJI[item.wuxing] || "";
|
|
275
|
-
console.log(chalk.green(`
|
|
276
|
-
\u2705 #${item.id} \u5DF2\u521B\u5EFA`));
|
|
277
|
-
console.log(chalk.dim(` ${wx} [${item.priority}\u7EA7] [${TYPE_LABEL[item.type] || item.type}] ${item.title}`));
|
|
278
|
-
if (item.targetVersion) console.log(chalk.dim(` \u76EE\u6807\u7248\u672C: ${item.targetVersion}`));
|
|
279
|
-
console.log();
|
|
280
|
-
}
|
|
281
|
-
async function handleLs(args) {
|
|
282
|
-
const { opts } = parseOpts(args);
|
|
283
|
-
const items = await listItems({
|
|
284
|
-
status: opts.status,
|
|
285
|
-
wuxing: opts.wuxing,
|
|
286
|
-
priority: opts.priority,
|
|
287
|
-
version: opts.version,
|
|
288
|
-
type: opts.type
|
|
289
|
-
});
|
|
290
|
-
const stats = await getStats();
|
|
291
|
-
console.log();
|
|
292
|
-
console.log(chalk.bold(` \u{1F4CB} \u9700\u6C42\u6C60`) + chalk.dim(` (${stats.total} \u6761` + (stats.byStatus["developing"] ? `, ${stats.byStatus["developing"]} developing` : "") + (stats.byStatus["planned"] ? `, ${stats.byStatus["planned"]} planned` : "") + (stats.byStatus["idea"] ? `, ${stats.byStatus["idea"]} idea` : "") + ")"));
|
|
293
|
-
console.log();
|
|
294
|
-
if (items.length === 0) {
|
|
295
|
-
console.log(chalk.dim(" \u6682\u65E0\u9700\u6C42\u3002\u4F7F\u7528 /admin add <\u6807\u9898> \u6DFB\u52A0"));
|
|
296
|
-
console.log();
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
let currentPriority = "";
|
|
300
|
-
for (const item of items) {
|
|
301
|
-
if (item.priority !== currentPriority) {
|
|
302
|
-
currentPriority = item.priority;
|
|
303
|
-
console.log(chalk.dim(` \u2500\u2500 ${currentPriority}\u7EA7 \u2500\u2500`));
|
|
304
|
-
}
|
|
305
|
-
const wx = WUXING_EMOJI[item.wuxing] || "";
|
|
306
|
-
const st = STATUS_EMOJI[item.status] || "";
|
|
307
|
-
const ver = item.targetVersion ? chalk.dim(` ${item.targetVersion}`) : "";
|
|
308
|
-
console.log(` ${chalk.dim("#" + item.id)} ${wx} ${st} ${item.title}${ver}`);
|
|
309
|
-
}
|
|
310
|
-
console.log();
|
|
311
|
-
}
|
|
312
|
-
async function handleShow(args) {
|
|
313
|
-
const id = parseInt(args[0]);
|
|
314
|
-
if (!id) {
|
|
315
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin show <id>\n"));
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
const item = await getItem(id);
|
|
319
|
-
if (!item) {
|
|
320
|
-
console.log(chalk.red(`
|
|
321
|
-
\u672A\u627E\u5230 #${id}
|
|
322
|
-
`));
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
const wx = WUXING_EMOJI[item.wuxing] || "";
|
|
326
|
-
console.log();
|
|
327
|
-
console.log(chalk.bold(` #${item.id} ${item.title}`));
|
|
328
|
-
console.log();
|
|
329
|
-
console.log(` ${chalk.dim("\u7C7B\u578B:")} ${TYPE_LABEL[item.type] || item.type} ${chalk.dim("\u4E94\u884C:")} ${wx}${item.wuxing} ${chalk.dim("\u4F18\u5148\u7EA7:")} ${item.priority} ${chalk.dim("\u72B6\u6001:")} ${item.status}`);
|
|
330
|
-
if (item.targetVersion) console.log(` ${chalk.dim("\u7248\u672C:")} ${item.targetVersion}`);
|
|
331
|
-
if (item.tags.length) console.log(` ${chalk.dim("\u6807\u7B7E:")} ${item.tags.join(", ")}`);
|
|
332
|
-
if (item.description) console.log(` ${chalk.dim("\u63CF\u8FF0:")} ${item.description}`);
|
|
333
|
-
if (item.evidence) console.log(` ${chalk.dim("\u8BC1\u636E:")} ${item.evidence}`);
|
|
334
|
-
console.log(` ${chalk.dim("\u6765\u6E90:")} ${item.source} ${chalk.dim("\u521B\u5EFA:")} ${item.createdAt.slice(0, 10)}`);
|
|
335
|
-
if (item.startedAt) console.log(` ${chalk.dim("\u5F00\u59CB:")} ${item.startedAt.slice(0, 10)}`);
|
|
336
|
-
if (item.resolvedAt) console.log(` ${chalk.dim("\u5B8C\u6210:")} ${item.resolvedAt.slice(0, 10)}`);
|
|
337
|
-
console.log();
|
|
338
|
-
}
|
|
339
|
-
async function handleEdit(args) {
|
|
340
|
-
const { positional, opts } = parseOpts(args);
|
|
341
|
-
const id = parseInt(positional[0]);
|
|
342
|
-
if (!id) {
|
|
343
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin edit <id> [--priority S] [--wuxing \u706B] [--version v1.3] [--type bugfix]\n"));
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
const updates = {};
|
|
347
|
-
if (opts.priority) {
|
|
348
|
-
if (!["S", "A", "B", "C"].includes(opts.priority)) {
|
|
349
|
-
console.log(chalk.red(`
|
|
350
|
-
priority \u65E0\u6548: ${opts.priority}\uFF08\u53EF\u9009: S/A/B/C\uFF09
|
|
351
|
-
`));
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
updates.priority = opts.priority;
|
|
355
|
-
}
|
|
356
|
-
if (opts.wuxing) {
|
|
357
|
-
if (!["\u6728", "\u706B", "\u6C34", "\u91D1", "\u571F"].includes(opts.wuxing)) {
|
|
358
|
-
console.log(chalk.red(`
|
|
359
|
-
wuxing \u65E0\u6548: ${opts.wuxing}\uFF08\u53EF\u9009: \u6728/\u706B/\u6C34/\u91D1/\u571F\uFF09
|
|
360
|
-
`));
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
updates.wuxing = opts.wuxing;
|
|
364
|
-
}
|
|
365
|
-
if (opts.type) {
|
|
366
|
-
if (!["feature", "improvement", "idea", "bugfix"].includes(opts.type)) {
|
|
367
|
-
console.log(chalk.red(`
|
|
368
|
-
type \u65E0\u6548: ${opts.type}\uFF08\u53EF\u9009: feature/improvement/idea/bugfix\uFF09
|
|
369
|
-
`));
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
updates.type = opts.type;
|
|
373
|
-
}
|
|
374
|
-
if (opts.status) {
|
|
375
|
-
if (!["idea", "planned", "developing", "done", "archived"].includes(opts.status)) {
|
|
376
|
-
console.log(chalk.red(`
|
|
377
|
-
status \u65E0\u6548: ${opts.status}\uFF08\u53EF\u9009: idea/planned/developing/done/archived\uFF09
|
|
378
|
-
`));
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
updates.status = opts.status;
|
|
382
|
-
}
|
|
383
|
-
if (opts.version) updates.targetVersion = opts.version;
|
|
384
|
-
if (opts.title) updates.title = opts.title;
|
|
385
|
-
if (Object.keys(updates).length === 0) {
|
|
386
|
-
console.log(chalk.dim("\n \u65E0\u4FEE\u6539\u9879\n"));
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
const item = await updateItem(id, updates);
|
|
390
|
-
if (!item) {
|
|
391
|
-
console.log(chalk.red(`
|
|
392
|
-
\u672A\u627E\u5230 #${id}
|
|
393
|
-
`));
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
console.log(chalk.green(`
|
|
397
|
-
\u2705 #${id} \u5DF2\u66F4\u65B0
|
|
398
|
-
`));
|
|
399
|
-
}
|
|
400
|
-
async function handlePick(args, _ctx) {
|
|
401
|
-
const id = parseInt(args[0]);
|
|
402
|
-
if (!id) {
|
|
403
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin pick <id>\n"));
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
const item = await pickItem(id);
|
|
407
|
-
if (!item) {
|
|
408
|
-
console.log(chalk.red(`
|
|
409
|
-
\u672A\u627E\u5230 #${id}
|
|
410
|
-
`));
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
const wx = WUXING_EMOJI[item.wuxing] || "";
|
|
414
|
-
console.log();
|
|
415
|
-
console.log(chalk.cyan(` \u{1F504} #${item.id} ${item.title} \u2192 developing`));
|
|
416
|
-
console.log();
|
|
417
|
-
console.log(` ${chalk.dim("\u7C7B\u578B:")} ${TYPE_LABEL[item.type] || item.type} ${chalk.dim("\u4E94\u884C:")} ${wx}${item.wuxing} ${chalk.dim("\u4F18\u5148\u7EA7:")} ${item.priority}`);
|
|
418
|
-
if (item.description) console.log(` ${chalk.dim("\u63CF\u8FF0:")} ${item.description}`);
|
|
419
|
-
if (item.targetVersion) console.log(` ${chalk.dim("\u7248\u672C:")} ${item.targetVersion}`);
|
|
420
|
-
console.log();
|
|
421
|
-
console.log(chalk.dim(" \u9700\u6C42\u5DF2\u52A0\u8F7D\u3002\u544A\u8BC9\u6211\u600E\u4E48\u505A\u3002"));
|
|
422
|
-
console.log();
|
|
423
|
-
}
|
|
424
|
-
async function handleDone(args) {
|
|
425
|
-
const id = parseInt(args[0]);
|
|
426
|
-
if (!id) {
|
|
427
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin done <id>\n"));
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
const item = await doneItem(id);
|
|
431
|
-
if (!item) {
|
|
432
|
-
console.log(chalk.red(`
|
|
433
|
-
\u672A\u627E\u5230 #${id}
|
|
434
|
-
`));
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
console.log(chalk.green(`
|
|
438
|
-
\u2705 #${item.id} ${item.title} \u2192 done`));
|
|
439
|
-
console.log(chalk.dim(` \u5B8C\u6210\u4E8E: ${item.resolvedAt?.slice(0, 10)}`));
|
|
440
|
-
try {
|
|
441
|
-
const baseline = await recordBaseline(id);
|
|
442
|
-
if (baseline) {
|
|
443
|
-
console.log(chalk.dim(` \u{1F4CF} \u57FA\u7EBF: ${baseline.key} = ${baseline.value}`));
|
|
444
|
-
console.log(chalk.dim(` \u4E0B\u6B21 /admin verify \u65F6\u5C06\u81EA\u52A8\u68C0\u6D4B\u6539\u5584\u6548\u679C`));
|
|
445
|
-
}
|
|
446
|
-
} catch {
|
|
447
|
-
}
|
|
448
|
-
console.log();
|
|
449
|
-
}
|
|
450
|
-
async function handleArchive(args) {
|
|
451
|
-
const id = parseInt(args[0]);
|
|
452
|
-
if (!id) {
|
|
453
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin archive <id>\n"));
|
|
454
|
-
return;
|
|
455
|
-
}
|
|
456
|
-
const item = await archiveItem(id);
|
|
457
|
-
if (!item) {
|
|
458
|
-
console.log(chalk.red(`
|
|
459
|
-
\u672A\u627E\u5230 #${id}
|
|
460
|
-
`));
|
|
461
|
-
return;
|
|
462
|
-
}
|
|
463
|
-
console.log(chalk.dim(`
|
|
464
|
-
\u{1F4E6} #${item.id} ${item.title} \u2192 archived
|
|
465
|
-
`));
|
|
466
|
-
}
|
|
467
|
-
async function handleReopen(args) {
|
|
468
|
-
const id = parseInt(args[0]);
|
|
469
|
-
if (!id) {
|
|
470
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin reopen <id>\n"));
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
const item = await reopenItem(id);
|
|
474
|
-
if (!item) {
|
|
475
|
-
console.log(chalk.red(`
|
|
476
|
-
\u672A\u627E\u5230 #${id}
|
|
477
|
-
`));
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
console.log(chalk.green(`
|
|
481
|
-
\u{1F504} #${item.id} ${item.title} \u2192 planned
|
|
482
|
-
`));
|
|
483
|
-
}
|
|
484
|
-
async function handleVersion() {
|
|
485
|
-
const info = await getVersionInfo(process.cwd());
|
|
486
|
-
console.log();
|
|
487
|
-
console.log(chalk.bold(` \u{1F3D7}\uFE0F \u7248\u672C\u4E2D\u5FC3`));
|
|
488
|
-
console.log();
|
|
489
|
-
console.log(` ${chalk.dim("\u5F53\u524D:")} v${info.currentVersion}`);
|
|
490
|
-
if (info.lastTag) {
|
|
491
|
-
console.log(` ${chalk.dim("\u4E0A\u6B21\u53D1\u5E03:")} ${info.lastTag} (${info.lastTagDate}, ${info.daysSinceTag}\u5929\u524D)`);
|
|
492
|
-
} else {
|
|
493
|
-
console.log(chalk.dim(" \u5C1A\u65E0\u53D1\u5E03 tag"));
|
|
494
|
-
}
|
|
495
|
-
console.log(` ${chalk.dim("\u5F85\u53D1\u5E03:")} ${info.pendingCommits} commits, ${info.filesChanged} files (+${info.insertions}/-${info.deletions})`);
|
|
496
|
-
if (Object.keys(info.commitsByType).length > 0) {
|
|
497
|
-
console.log();
|
|
498
|
-
console.log(chalk.dim(" \u53D8\u66F4\u5206\u7C7B:"));
|
|
499
|
-
const typeEmoji = {
|
|
500
|
-
feat: "\u{1F333}",
|
|
501
|
-
fix: "\u{1F333}",
|
|
502
|
-
docs: "\u{1F525}",
|
|
503
|
-
style: "\u{1F525}",
|
|
504
|
-
refactor: "\u2699\uFE0F",
|
|
505
|
-
perf: "\u{1F30A}",
|
|
506
|
-
test: "\u2699\uFE0F",
|
|
507
|
-
chore: "\u{1F3D4}\uFE0F"
|
|
508
|
-
};
|
|
509
|
-
for (const [type, count] of Object.entries(info.commitsByType)) {
|
|
510
|
-
console.log(` ${typeEmoji[type] || "\xB7"} ${type}: ${count} commits`);
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
if (info.recentCommits.length > 0) {
|
|
514
|
-
console.log();
|
|
515
|
-
console.log(chalk.dim(" \u6700\u8FD1\u63D0\u4EA4:"));
|
|
516
|
-
for (const c of info.recentCommits.slice(0, 8)) {
|
|
517
|
-
console.log(chalk.dim(` ${c.hash} ${c.message}`));
|
|
518
|
-
}
|
|
519
|
-
if (info.recentCommits.length > 8) {
|
|
520
|
-
console.log(chalk.dim(` ... \u8FD8\u6709 ${info.recentCommits.length - 8} \u6761`));
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
console.log();
|
|
524
|
-
}
|
|
525
|
-
async function handleReleaseCheck() {
|
|
526
|
-
console.log(chalk.dim("\n \u{1F680} \u53D1\u5E03\u68C0\u67E5\u4E2D...\n"));
|
|
527
|
-
const checks = await runReleaseChecks(process.cwd());
|
|
528
|
-
let allPassed = true;
|
|
529
|
-
for (const c of checks) {
|
|
530
|
-
const icon = c.ok ? chalk.green("\u2705") : chalk.red("\u274C");
|
|
531
|
-
console.log(` ${icon} ${chalk.bold(c.name)} ${chalk.dim(c.detail)}`);
|
|
532
|
-
if (!c.ok) allPassed = false;
|
|
533
|
-
}
|
|
534
|
-
console.log();
|
|
535
|
-
if (allPassed) {
|
|
536
|
-
console.log(chalk.green(" \u7ED3\u8BBA: \u{1F7E2} \u53EF\u4EE5\u53D1\u5E03"));
|
|
537
|
-
} else {
|
|
538
|
-
const failCount = checks.filter((c) => !c.ok).length;
|
|
539
|
-
console.log(chalk.yellow(` \u7ED3\u8BBA: \u{1F7E1} \u6682\u4E0D\u53EF\u53D1\u5E03 (${failCount} \u9879\u672A\u901A\u8FC7)`));
|
|
540
|
-
}
|
|
541
|
-
console.log();
|
|
542
|
-
}
|
|
543
|
-
async function handleReleaseHistory() {
|
|
544
|
-
const history = getReleaseHistory(process.cwd());
|
|
545
|
-
console.log();
|
|
546
|
-
if (history.length === 0) {
|
|
547
|
-
console.log(chalk.dim(" \u5C1A\u65E0\u53D1\u5E03\u5386\u53F2 (\u65E0 git tag)"));
|
|
548
|
-
} else {
|
|
549
|
-
console.log(chalk.bold(" \u{1F4DC} \u53D1\u5E03\u5386\u53F2"));
|
|
550
|
-
console.log();
|
|
551
|
-
for (const h of history) {
|
|
552
|
-
console.log(` ${chalk.cyan(h.tag)} ${chalk.dim(h.date)} ${h.message || ""}`);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
console.log();
|
|
556
|
-
}
|
|
557
|
-
var SEVERITY_EMOJI = {
|
|
558
|
-
high: "\u{1F534}",
|
|
559
|
-
warning: "\u{1F7E1}",
|
|
560
|
-
opportunity: "\u{1F7E2}"
|
|
561
|
-
};
|
|
562
|
-
async function handleDiagnose(args, ctx) {
|
|
563
|
-
const { opts } = parseOpts(args);
|
|
564
|
-
const days = parseInt(opts.days || "7") || 7;
|
|
565
|
-
const useAI = args.includes("--ai");
|
|
566
|
-
console.log(chalk.dim(`
|
|
567
|
-
\u{1F50D} \u8BCA\u65AD\u4E2D (\u8FD1 ${days} \u5929)${useAI ? " [AI \u589E\u5F3A]" : " [\u89C4\u5219\u5F15\u64CE]"}...
|
|
568
|
-
`));
|
|
569
|
-
if (useAI) {
|
|
570
|
-
const { ruleFindings, aiFindings, aiRawText } = await runAIDiagnosis(ctx, days);
|
|
571
|
-
console.log("\n");
|
|
572
|
-
if (ruleFindings.length > 0) {
|
|
573
|
-
console.log(chalk.dim(" \u2500\u2500 \u89C4\u5219\u5F15\u64CE\u53D1\u73B0 \u2500\u2500"));
|
|
574
|
-
for (const f of ruleFindings) {
|
|
575
|
-
console.log(` ${SEVERITY_EMOJI[f.severity] || "\xB7"} ${chalk.bold(f.title)}`);
|
|
576
|
-
console.log(chalk.dim(` ${f.detail}`));
|
|
577
|
-
console.log(chalk.dim(` \u2192 ${f.suggestion}`));
|
|
578
|
-
}
|
|
579
|
-
console.log();
|
|
580
|
-
}
|
|
581
|
-
if (aiFindings.length > 0) {
|
|
582
|
-
console.log(chalk.dim(" \u2500\u2500 AI \u8865\u5145\u53D1\u73B0 \u2500\u2500"));
|
|
583
|
-
for (const f of aiFindings) {
|
|
584
|
-
console.log(` ${SEVERITY_EMOJI[f.severity] || "\xB7"} ${chalk.bold(f.title)}`);
|
|
585
|
-
console.log(chalk.dim(` ${f.detail}`));
|
|
586
|
-
console.log(chalk.dim(` \u2192 ${f.suggestion}`));
|
|
587
|
-
}
|
|
588
|
-
console.log();
|
|
589
|
-
}
|
|
590
|
-
const total = ruleFindings.length + aiFindings.length;
|
|
591
|
-
if (total === 0) {
|
|
592
|
-
console.log(chalk.green(" \u2705 \u672A\u53D1\u73B0\u95EE\u9898\n"));
|
|
593
|
-
} else {
|
|
594
|
-
console.log(chalk.dim(` \u5171 ${total} \u6761\u53D1\u73B0 (\u89C4\u5219 ${ruleFindings.length} + AI ${aiFindings.length})`));
|
|
595
|
-
console.log(chalk.dim(` \u4F7F\u7528 /admin diagnose-to-backlog \u5C06\u53D1\u73B0\u8F6C\u4E3A\u9700\u6C42
|
|
596
|
-
`));
|
|
597
|
-
}
|
|
598
|
-
} else {
|
|
599
|
-
const findings = await runRuleDiagnosis(days);
|
|
600
|
-
if (findings.length === 0) {
|
|
601
|
-
console.log(chalk.green(" \u2705 \u672A\u53D1\u73B0\u95EE\u9898\n"));
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
for (const f of findings) {
|
|
605
|
-
console.log(` ${SEVERITY_EMOJI[f.severity] || "\xB7"} ${chalk.bold(f.title)}`);
|
|
606
|
-
console.log(chalk.dim(` ${f.detail}`));
|
|
607
|
-
console.log(chalk.dim(` \u2192 ${f.suggestion}`));
|
|
608
|
-
}
|
|
609
|
-
console.log();
|
|
610
|
-
console.log(chalk.dim(` \u5171 ${findings.length} \u6761\u53D1\u73B0`));
|
|
611
|
-
console.log(chalk.dim(` \u4F7F\u7528 /admin diagnose --ai \u542F\u7528 AI \u589E\u5F3A\u8BCA\u65AD`));
|
|
612
|
-
console.log(chalk.dim(` \u4F7F\u7528 /admin diagnose-to-backlog \u5C06\u53D1\u73B0\u8F6C\u4E3A\u9700\u6C42
|
|
613
|
-
`));
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
async function handleDiagnoseToBacklog(args) {
|
|
617
|
-
const { opts } = parseOpts(args);
|
|
618
|
-
const days = parseInt(opts.days || "7") || 7;
|
|
619
|
-
const version = opts.version || "";
|
|
620
|
-
console.log(chalk.dim(`
|
|
621
|
-
\u{1F504} \u6B63\u5728\u5C06\u8BCA\u65AD\u53D1\u73B0\u8F6C\u4E3A\u9700\u6C42 (\u8FD1 ${days} \u5929)...
|
|
622
|
-
`));
|
|
623
|
-
const findings = await runRuleDiagnosis(days);
|
|
624
|
-
if (findings.length === 0) {
|
|
625
|
-
console.log(chalk.dim(" \u65E0\u53D1\u73B0\u53EF\u8F6C\u5316\n"));
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
const createdIds = await findingsToBacklog(findings, version);
|
|
629
|
-
if (createdIds.length === 0) {
|
|
630
|
-
console.log(chalk.dim(" \u6240\u6709\u53D1\u73B0\u5DF2\u5B58\u5728\u4E8E\u9700\u6C42\u6C60\u4E2D\uFF08\u5DF2\u53BB\u91CD\uFF09\n"));
|
|
631
|
-
} else {
|
|
632
|
-
console.log(chalk.green(` \u2705 \u5DF2\u521B\u5EFA ${createdIds.length} \u6761\u9700\u6C42: ${createdIds.map((id) => "#" + id).join(", ")}`));
|
|
633
|
-
if (findings.length > createdIds.length) {
|
|
634
|
-
console.log(chalk.dim(` \u8DF3\u8FC7 ${findings.length - createdIds.length} \u6761\u91CD\u590D`));
|
|
635
|
-
}
|
|
636
|
-
console.log(chalk.dim(` \u4F7F\u7528 /admin ls \u67E5\u770B\u9700\u6C42\u6C60
|
|
637
|
-
`));
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
async function handleQuality(args) {
|
|
641
|
-
const subCmd = args[0];
|
|
642
|
-
if (subCmd === "test" || subCmd === "tests") {
|
|
643
|
-
return handleQualitySingle("test");
|
|
644
|
-
}
|
|
645
|
-
if (subCmd === "todos" || subCmd === "todo") {
|
|
646
|
-
return handleQualitySingle("todos");
|
|
647
|
-
}
|
|
648
|
-
if (subCmd === "deps" || subCmd === "dep") {
|
|
649
|
-
return handleQualitySingle("deps");
|
|
650
|
-
}
|
|
651
|
-
if (subCmd === "size") {
|
|
652
|
-
return handleQualitySingle("size");
|
|
653
|
-
}
|
|
654
|
-
if (subCmd === "build") {
|
|
655
|
-
return handleQualitySingle("build");
|
|
656
|
-
}
|
|
657
|
-
const skipTests = args.includes("--skip-tests");
|
|
658
|
-
const skipBuild = args.includes("--skip-build");
|
|
659
|
-
console.log(chalk.dim("\n \u{1F3E5} \u8D28\u91CF\u770B\u677F \xB7 \u68C0\u67E5\u4E2D...\n"));
|
|
660
|
-
const report = await runQualityReport(process.cwd(), { skipTests, skipBuild });
|
|
661
|
-
for (const c of report.checks) {
|
|
662
|
-
const icon = c.ok ? chalk.green("\u2705") : chalk.red("\u274C");
|
|
663
|
-
const valueStr = c.value !== void 0 && c.unit ? chalk.dim(` (${c.value}${c.unit})`) : "";
|
|
664
|
-
console.log(` ${icon} ${chalk.bold(c.name)} ${c.detail}${valueStr}`);
|
|
665
|
-
}
|
|
666
|
-
console.log();
|
|
667
|
-
const scoreColor = report.score >= 80 ? chalk.green : report.score >= 60 ? chalk.yellow : chalk.red;
|
|
668
|
-
console.log(` \u7EFC\u5408\u5065\u5EB7\u5EA6: ${scoreColor(report.score + "/100")}`);
|
|
669
|
-
console.log();
|
|
670
|
-
}
|
|
671
|
-
async function handleQualitySingle(which) {
|
|
672
|
-
const projectRoot = process.cwd();
|
|
673
|
-
console.log(chalk.dim(`
|
|
674
|
-
\u68C0\u67E5\u4E2D...
|
|
675
|
-
`));
|
|
676
|
-
let result;
|
|
677
|
-
switch (which) {
|
|
678
|
-
case "test":
|
|
679
|
-
result = await checkTests(projectRoot);
|
|
680
|
-
break;
|
|
681
|
-
case "todos":
|
|
682
|
-
result = await checkTodos(projectRoot);
|
|
683
|
-
break;
|
|
684
|
-
case "deps":
|
|
685
|
-
result = await checkDeps(projectRoot);
|
|
686
|
-
break;
|
|
687
|
-
case "size":
|
|
688
|
-
result = await checkPackageSize(projectRoot);
|
|
689
|
-
break;
|
|
690
|
-
case "build":
|
|
691
|
-
result = await checkBuild(projectRoot);
|
|
692
|
-
break;
|
|
693
|
-
default:
|
|
694
|
-
console.log(chalk.red(` \u672A\u77E5\u68C0\u67E5\u9879: ${which}
|
|
695
|
-
`));
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
const icon = result.ok ? chalk.green("\u2705") : chalk.red("\u274C");
|
|
699
|
-
console.log(` ${icon} ${chalk.bold(result.name)} ${result.detail}`);
|
|
700
|
-
if (result.value !== void 0 && result.unit) {
|
|
701
|
-
console.log(chalk.dim(` \u503C: ${result.value} ${result.unit}`));
|
|
702
|
-
}
|
|
703
|
-
console.log();
|
|
704
|
-
}
|
|
705
|
-
var VERDICT_EMOJI = {
|
|
706
|
-
effective: "\u2705",
|
|
707
|
-
ineffective: "\u274C",
|
|
708
|
-
pending: "\u23F3",
|
|
709
|
-
"no-data": "\u2753"
|
|
710
|
-
};
|
|
711
|
-
var VERDICT_LABEL = {
|
|
712
|
-
effective: "\u6709\u6548",
|
|
713
|
-
ineffective: "\u65E0\u6548",
|
|
714
|
-
pending: "\u5F85\u89C2\u5BDF",
|
|
715
|
-
"no-data": "\u65E0\u6570\u636E"
|
|
716
|
-
};
|
|
717
|
-
async function handleVerify() {
|
|
718
|
-
console.log(chalk.dim("\n \u{1F52C} \u6548\u679C\u9A8C\u8BC1\u4E2D...\n"));
|
|
719
|
-
const report = await verifyCompletedItems();
|
|
720
|
-
if (report.results.length === 0) {
|
|
721
|
-
console.log(chalk.dim(" \u6682\u65E0\u53EF\u9A8C\u8BC1\u7684\u9700\u6C42"));
|
|
722
|
-
console.log(chalk.dim(" \u63D0\u793A: \u4F7F\u7528 /admin done <id> \u5B8C\u6210\u9700\u6C42\u540E\uFF0C\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u8BB0\u5F55\u57FA\u7EBF"));
|
|
723
|
-
console.log();
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
for (const r of report.results) {
|
|
727
|
-
const icon = VERDICT_EMOJI[r.verdict] || "\xB7";
|
|
728
|
-
const label = VERDICT_LABEL[r.verdict] || r.verdict;
|
|
729
|
-
console.log(` ${icon} ${chalk.bold(`#${r.itemId} ${r.title}`)} \u2192 ${label}`);
|
|
730
|
-
console.log(chalk.dim(` \u6307\u6807: ${r.baselineKey} \u57FA\u7EBF: ${r.baselineValue}${r.afterValue !== null ? ` \u5F53\u524D: ${r.afterValue}` : ""}`));
|
|
731
|
-
if (r.changePercent !== null) {
|
|
732
|
-
const changeColor = r.verdict === "effective" ? chalk.green : r.verdict === "ineffective" ? chalk.red : chalk.yellow;
|
|
733
|
-
console.log(chalk.dim(" ") + changeColor(r.detail));
|
|
734
|
-
} else {
|
|
735
|
-
console.log(chalk.dim(` ${r.detail}`));
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
console.log();
|
|
739
|
-
console.log(chalk.dim(` \u603B\u8BA1: ${report.summary.total} \u9879 | \u2705 ${report.summary.effective} \u6709\u6548 \u274C ${report.summary.ineffective} \u65E0\u6548 \u23F3 ${report.summary.pending} \u5F85\u89C2\u5BDF \u2753 ${report.summary.noData} \u65E0\u6570\u636E`));
|
|
740
|
-
console.log();
|
|
741
|
-
}
|
|
742
|
-
async function handleRoadmap(args) {
|
|
743
|
-
const { positional, opts } = parseOpts(args);
|
|
744
|
-
if (opts.set) {
|
|
745
|
-
const id = parseInt(opts.set);
|
|
746
|
-
const ver = positional[0] || opts.version || "";
|
|
747
|
-
if (!id || !ver) {
|
|
748
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin roadmap --set <id> <version>\n"));
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
|
-
const item = await updateItem(id, { targetVersion: ver });
|
|
752
|
-
if (!item) {
|
|
753
|
-
console.log(chalk.red(`
|
|
754
|
-
\u672A\u627E\u5230 #${id}
|
|
755
|
-
`));
|
|
756
|
-
return;
|
|
757
|
-
}
|
|
758
|
-
console.log(chalk.green(`
|
|
759
|
-
\u2705 #${id} \u2192 ${ver}
|
|
760
|
-
`));
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
const roadmap = await getRoadmap();
|
|
764
|
-
if (roadmap.length === 0) {
|
|
765
|
-
console.log(chalk.dim("\n \u6682\u65E0\u7248\u672C\u89C4\u5212"));
|
|
766
|
-
console.log(chalk.dim(" \u4F7F\u7528 /admin add <\u6807\u9898> --version v1.2 \u6DFB\u52A0\u7248\u672C\u9700\u6C42"));
|
|
767
|
-
console.log(chalk.dim(" \u4F7F\u7528 /admin milestone add <\u7248\u672C> <\u540D\u79F0> \u5B9A\u4E49\u91CC\u7A0B\u7891\n"));
|
|
768
|
-
return;
|
|
769
|
-
}
|
|
770
|
-
console.log();
|
|
771
|
-
console.log(chalk.bold(" \u{1F5FA}\uFE0F \u8DEF\u7EBF\u56FE"));
|
|
772
|
-
console.log();
|
|
773
|
-
for (const ver of roadmap) {
|
|
774
|
-
const msLabel = ver.milestone ? ver.milestone.status === "done" ? chalk.green(" \u2713") : ver.milestone.status === "active" ? chalk.cyan(" \u2B24") : "" : "";
|
|
775
|
-
const msName = ver.milestone ? chalk.dim(` \u2014 ${ver.milestone.name}`) : "";
|
|
776
|
-
const barWidth = 20;
|
|
777
|
-
const filled = Math.round(ver.stats.progress / 100 * barWidth);
|
|
778
|
-
const bar = "\u2588".repeat(filled) + "\u2591".repeat(barWidth - filled);
|
|
779
|
-
const progressColor = ver.stats.progress === 100 ? chalk.green : ver.stats.progress >= 50 ? chalk.cyan : chalk.yellow;
|
|
780
|
-
console.log(` ${chalk.bold(ver.version)}${msLabel}${msName} ${progressColor(bar)} ${ver.stats.progress}%`);
|
|
781
|
-
console.log(chalk.dim(` ${ver.stats.total} \u9700\u6C42: ${ver.stats.done} done, ${ver.stats.developing} dev, ${ver.stats.planned} planned, ${ver.stats.idea} idea`));
|
|
782
|
-
const activeItems = ver.items.filter((i) => i.status === "developing" || i.status === "planned").slice(0, 5);
|
|
783
|
-
for (const item of activeItems) {
|
|
784
|
-
const wx = WUXING_EMOJI[item.wuxing] || "";
|
|
785
|
-
const st = STATUS_EMOJI[item.status] || "";
|
|
786
|
-
console.log(chalk.dim(` ${st} #${item.id} ${wx} ${item.title}`));
|
|
787
|
-
}
|
|
788
|
-
const remaining = ver.items.filter((i) => i.status === "developing" || i.status === "planned").length - activeItems.length;
|
|
789
|
-
if (remaining > 0) {
|
|
790
|
-
console.log(chalk.dim(` ... \u8FD8\u6709 ${remaining} \u6761`));
|
|
791
|
-
}
|
|
792
|
-
console.log();
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
async function handleMilestone(args) {
|
|
796
|
-
const subCmd = args[0];
|
|
797
|
-
const subArgs = args.slice(1);
|
|
798
|
-
if (subCmd === "add") {
|
|
799
|
-
const ver = subArgs[0];
|
|
800
|
-
const name = subArgs.slice(1).join(" ");
|
|
801
|
-
if (!ver || !name) {
|
|
802
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin milestone add <\u7248\u672C\u53F7> <\u540D\u79F0>\n"));
|
|
803
|
-
return;
|
|
804
|
-
}
|
|
805
|
-
try {
|
|
806
|
-
const ms = await addMilestone(ver, name);
|
|
807
|
-
console.log(chalk.green(`
|
|
808
|
-
\u2705 \u91CC\u7A0B\u7891 ${ms.version} "${ms.name}" \u5DF2\u521B\u5EFA
|
|
809
|
-
`));
|
|
810
|
-
} catch (err) {
|
|
811
|
-
console.log(chalk.red(`
|
|
812
|
-
${err instanceof Error ? err.message : String(err)}
|
|
813
|
-
`));
|
|
814
|
-
}
|
|
815
|
-
return;
|
|
816
|
-
}
|
|
817
|
-
if (subCmd === "done") {
|
|
818
|
-
const ver = subArgs[0];
|
|
819
|
-
if (!ver) {
|
|
820
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin milestone done <\u7248\u672C\u53F7>\n"));
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
const ms = await doneMilestone(ver);
|
|
824
|
-
if (!ms) {
|
|
825
|
-
console.log(chalk.red(`
|
|
826
|
-
\u672A\u627E\u5230\u91CC\u7A0B\u7891 ${ver}
|
|
827
|
-
`));
|
|
828
|
-
return;
|
|
829
|
-
}
|
|
830
|
-
console.log(chalk.green(`
|
|
831
|
-
\u2705 \u91CC\u7A0B\u7891 ${ms.version} "${ms.name}" \u2192 done
|
|
832
|
-
`));
|
|
833
|
-
return;
|
|
834
|
-
}
|
|
835
|
-
if (subCmd === "activate") {
|
|
836
|
-
const ver = subArgs[0];
|
|
837
|
-
if (!ver) {
|
|
838
|
-
console.log(chalk.red("\n \u7528\u6CD5: /admin milestone activate <\u7248\u672C\u53F7>\n"));
|
|
839
|
-
return;
|
|
840
|
-
}
|
|
841
|
-
const ms = await activateMilestone(ver);
|
|
842
|
-
if (!ms) {
|
|
843
|
-
console.log(chalk.red(`
|
|
844
|
-
\u672A\u627E\u5230\u91CC\u7A0B\u7891 ${ver}
|
|
845
|
-
`));
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
console.log(chalk.cyan(`
|
|
849
|
-
\u2B24 \u91CC\u7A0B\u7891 ${ms.version} "${ms.name}" \u2192 active
|
|
850
|
-
`));
|
|
851
|
-
return;
|
|
852
|
-
}
|
|
853
|
-
const milestones = await listMilestones();
|
|
854
|
-
if (milestones.length === 0) {
|
|
855
|
-
console.log(chalk.dim("\n \u6682\u65E0\u91CC\u7A0B\u7891"));
|
|
856
|
-
console.log(chalk.dim(" \u4F7F\u7528 /admin milestone add <\u7248\u672C\u53F7> <\u540D\u79F0> \u521B\u5EFA\n"));
|
|
857
|
-
return;
|
|
858
|
-
}
|
|
859
|
-
console.log();
|
|
860
|
-
console.log(chalk.bold(" \u{1F3C1} \u91CC\u7A0B\u7891"));
|
|
861
|
-
console.log();
|
|
862
|
-
const msStatusIcon = {
|
|
863
|
-
planning: "\u{1F4DD}",
|
|
864
|
-
active: "\u2B24",
|
|
865
|
-
done: "\u2705",
|
|
866
|
-
cancelled: "\u26D4"
|
|
867
|
-
};
|
|
868
|
-
for (const ms of milestones) {
|
|
869
|
-
const icon = msStatusIcon[ms.status] || "\xB7";
|
|
870
|
-
const doneInfo = ms.doneAt ? chalk.dim(` (${ms.doneAt.slice(0, 10)})`) : "";
|
|
871
|
-
console.log(` ${icon} ${chalk.bold(ms.version)} ${ms.name}${doneInfo}`);
|
|
872
|
-
if (ms.description) console.log(chalk.dim(` ${ms.description}`));
|
|
873
|
-
}
|
|
874
|
-
console.log();
|
|
875
|
-
}
|
|
876
|
-
async function handleStatus() {
|
|
877
|
-
const stats = await getStats();
|
|
878
|
-
const summary = await getEventsSummary(7);
|
|
879
|
-
console.log();
|
|
880
|
-
console.log(chalk.bold(" \u{1FA9E} \u5185\u89C2 \xB7 HyperMirror \u72B6\u6001"));
|
|
881
|
-
console.log();
|
|
882
|
-
console.log(chalk.dim(" \u2500\u2500 \u9700\u6C42\u6C60 \u2500\u2500"));
|
|
883
|
-
console.log(` \u603B\u8BA1: ${stats.total} \u6761 | ${STATUS_EMOJI["developing"]} developing: ${stats.byStatus["developing"] || 0} ${STATUS_EMOJI["planned"]} planned: ${stats.byStatus["planned"] || 0} ${STATUS_EMOJI["idea"]} idea: ${stats.byStatus["idea"] || 0} ${STATUS_EMOJI["done"]} done: ${stats.byStatus["done"] || 0}`);
|
|
884
|
-
console.log();
|
|
885
|
-
console.log(chalk.dim(" \u2500\u2500 \u4E8B\u4EF6\u91C7\u96C6 (\u8FD17\u5929) \u2500\u2500"));
|
|
886
|
-
console.log(` \u4E8B\u4EF6\u603B\u6570: ${summary.totalEvents} | \u4F1A\u8BDD: ${summary.totalSessions} | \u5E73\u5747\u8F6E\u6B21: ${summary.avgSessionRounds}`);
|
|
887
|
-
if (Object.keys(summary.cmdCounts).length > 0) {
|
|
888
|
-
const topCmds = Object.entries(summary.cmdCounts).sort((a, b) => b[1].total - a[1].total).slice(0, 5);
|
|
889
|
-
console.log(chalk.dim(" \u70ED\u95E8\u547D\u4EE4:"));
|
|
890
|
-
for (const [cmd, c] of topCmds) {
|
|
891
|
-
const failPart = c.fail > 0 ? chalk.red(` (${c.fail} \u5931\u8D25)`) : "";
|
|
892
|
-
console.log(chalk.dim(` ${cmd}: ${c.total}\u6B21${failPart}`));
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
if (summary.errors.length > 0) {
|
|
896
|
-
console.log(chalk.dim(" \u8FD1\u671F\u9519\u8BEF:"));
|
|
897
|
-
for (const e of summary.errors.slice(0, 3)) {
|
|
898
|
-
console.log(chalk.dim(` ${e.type}: ${e.count}\u6B21`));
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
console.log();
|
|
902
|
-
}
|
|
903
|
-
function showHelp() {
|
|
904
|
-
console.log(`
|
|
905
|
-
${chalk.bold("\u{1FA9E} /admin \u2014 \u5185\u89C2\u5F15\u64CE \xB7 HyperMirror")}
|
|
906
|
-
|
|
907
|
-
${chalk.dim("\u9700\u6C42\u6C60:")}
|
|
908
|
-
/admin add <\u6807\u9898> [opts] \u65B0\u589E\u9700\u6C42
|
|
909
|
-
/admin ls [filters] \u5217\u8868\u7B5B\u9009
|
|
910
|
-
/admin show <id> \u67E5\u770B\u8BE6\u60C5
|
|
911
|
-
/admin edit <id> [opts] \u4FEE\u6539\u5B57\u6BB5
|
|
912
|
-
/admin pick <id> \u5F00\u59CB\u5F00\u53D1
|
|
913
|
-
/admin done <id> \u6807\u8BB0\u5B8C\u6210
|
|
914
|
-
/admin archive <id> \u5F52\u6863
|
|
915
|
-
/admin reopen <id> \u91CD\u65B0\u6253\u5F00
|
|
916
|
-
|
|
917
|
-
${chalk.dim("\u7248\u672C\u4E2D\u5FC3:")}
|
|
918
|
-
/admin version \u7248\u672C\u6982\u89C8
|
|
919
|
-
/admin release-check \u53D1\u5E03\u524D\u68C0\u67E5
|
|
920
|
-
/admin release-history \u5386\u53F2\u7248\u672C
|
|
921
|
-
|
|
922
|
-
${chalk.dim("\u8BCA\u65AD\u5F15\u64CE (Phase 1):")}
|
|
923
|
-
/admin diagnose [--days 7] \u89C4\u5219\u8BCA\u65AD
|
|
924
|
-
/admin diagnose --ai AI \u589E\u5F3A\u8BCA\u65AD
|
|
925
|
-
/admin diagnose-to-backlog \u53D1\u73B0\u2192\u9700\u6C42\u8F6C\u5316
|
|
926
|
-
|
|
927
|
-
${chalk.dim("\u8D28\u91CF\u770B\u677F (Phase 1):")}
|
|
928
|
-
/admin quality \u5B8C\u6574\u8D28\u91CF\u62A5\u544A
|
|
929
|
-
/admin quality test \u6D4B\u8BD5\u901A\u8FC7\u7387
|
|
930
|
-
/admin quality todos TODO/FIXME \u626B\u63CF
|
|
931
|
-
/admin quality deps \u4F9D\u8D56\u5B89\u5168\u68C0\u67E5
|
|
932
|
-
/admin quality size \u5305\u4F53\u79EF
|
|
933
|
-
/admin quality build \u7F16\u8BD1\u68C0\u67E5
|
|
934
|
-
|
|
935
|
-
${chalk.dim("\u6548\u679C\u9A8C\u8BC1 (Phase 2):")}
|
|
936
|
-
/admin verify \u68C0\u6D4B\u5DF2\u5B8C\u6210\u9700\u6C42\u7684\u6539\u5584\u6548\u679C
|
|
937
|
-
|
|
938
|
-
${chalk.dim("\u8DEF\u7EBF\u56FE (Phase 2):")}
|
|
939
|
-
/admin roadmap \u6309\u7248\u672C\u5206\u7EC4\u5C55\u793A\u9700\u6C42+\u8FDB\u5EA6
|
|
940
|
-
/admin roadmap --set <id> <ver> \u5206\u914D\u9700\u6C42\u5230\u7248\u672C
|
|
941
|
-
/admin milestone \u91CC\u7A0B\u7891\u5217\u8868
|
|
942
|
-
/admin milestone add <ver> <name> \u65B0\u589E\u91CC\u7A0B\u7891
|
|
943
|
-
/admin milestone done <ver> \u6807\u8BB0\u91CC\u7A0B\u7891\u5B8C\u6210
|
|
944
|
-
/admin milestone activate <ver> \u6FC0\u6D3B\u91CC\u7A0B\u7891
|
|
945
|
-
|
|
946
|
-
${chalk.dim("\u603B\u89C8:")}
|
|
947
|
-
/admin status \u5185\u89C2\u72B6\u6001\u6982\u89C8
|
|
948
|
-
/admin help \u663E\u793A\u5E2E\u52A9
|
|
949
|
-
|
|
950
|
-
${chalk.dim("\u9009\u9879 (\u7528\u4E8E add/edit/ls):")}
|
|
951
|
-
--type, -t feature|improvement|idea|bugfix
|
|
952
|
-
--wuxing, -w \u6728|\u706B|\u6C34|\u91D1|\u571F
|
|
953
|
-
--priority, -p S|A|B|C
|
|
954
|
-
--version, -v \u76EE\u6807\u7248\u672C\u53F7
|
|
955
|
-
--desc, -d \u63CF\u8FF0\u6587\u672C
|
|
956
|
-
--status idea|planned|developing|done
|
|
957
|
-
`);
|
|
958
|
-
}
|
|
959
|
-
function createAdminSlashCommands() {
|
|
960
|
-
return [
|
|
961
|
-
{
|
|
962
|
-
name: "admin",
|
|
963
|
-
aliases: ["mirror"],
|
|
964
|
-
description: "\u5185\u89C2\u5F15\u64CE \xB7 \u9879\u76EE\u81EA\u7BA1\u7406 (/admin help \u67E5\u770B\u5B50\u547D\u4EE4)",
|
|
965
|
-
category: "admin",
|
|
966
|
-
handler: async (args, ctx) => {
|
|
967
|
-
const subCmd = args[0]?.toLowerCase();
|
|
968
|
-
const subArgs = args.slice(1);
|
|
969
|
-
switch (subCmd) {
|
|
970
|
-
// 需求池
|
|
971
|
-
case "add":
|
|
972
|
-
return handleAdd(subArgs, ctx);
|
|
973
|
-
case "ls":
|
|
974
|
-
case "list":
|
|
975
|
-
return handleLs(subArgs);
|
|
976
|
-
case "show":
|
|
977
|
-
return handleShow(subArgs);
|
|
978
|
-
case "edit":
|
|
979
|
-
return handleEdit(subArgs);
|
|
980
|
-
case "pick":
|
|
981
|
-
return handlePick(subArgs, ctx);
|
|
982
|
-
case "done":
|
|
983
|
-
return handleDone(subArgs);
|
|
984
|
-
case "archive":
|
|
985
|
-
return handleArchive(subArgs);
|
|
986
|
-
case "reopen":
|
|
987
|
-
return handleReopen(subArgs);
|
|
988
|
-
// 版本中心
|
|
989
|
-
case "version":
|
|
990
|
-
case "ver":
|
|
991
|
-
return handleVersion();
|
|
992
|
-
case "release-check":
|
|
993
|
-
case "rc":
|
|
994
|
-
return handleReleaseCheck();
|
|
995
|
-
case "release-history":
|
|
996
|
-
case "rh":
|
|
997
|
-
return handleReleaseHistory();
|
|
998
|
-
// 诊断 (Phase 1)
|
|
999
|
-
case "diagnose":
|
|
1000
|
-
case "diag":
|
|
1001
|
-
return handleDiagnose(subArgs, ctx);
|
|
1002
|
-
case "diagnose-to-backlog":
|
|
1003
|
-
case "dtb":
|
|
1004
|
-
return handleDiagnoseToBacklog(subArgs);
|
|
1005
|
-
// 质量看板 (Phase 1)
|
|
1006
|
-
case "quality":
|
|
1007
|
-
case "q":
|
|
1008
|
-
return handleQuality(subArgs);
|
|
1009
|
-
// 效果验证 (Phase 2)
|
|
1010
|
-
case "verify":
|
|
1011
|
-
case "v":
|
|
1012
|
-
return handleVerify();
|
|
1013
|
-
// 路线图 (Phase 2)
|
|
1014
|
-
case "roadmap":
|
|
1015
|
-
case "rm":
|
|
1016
|
-
return handleRoadmap(subArgs);
|
|
1017
|
-
case "milestone":
|
|
1018
|
-
case "ms":
|
|
1019
|
-
return handleMilestone(subArgs);
|
|
1020
|
-
// changelog (Phase 2)
|
|
1021
|
-
case "changelog":
|
|
1022
|
-
console.log(chalk.dim("\n /admin changelog \u2014 AI \u751F\u6210 CHANGELOG\uFF0C\u5C1A\u672A\u5B9E\u73B0\n"));
|
|
1023
|
-
return;
|
|
1024
|
-
// 总览
|
|
1025
|
-
case "status":
|
|
1026
|
-
case "st":
|
|
1027
|
-
return handleStatus();
|
|
1028
|
-
// 帮助
|
|
1029
|
-
case "help":
|
|
1030
|
-
case void 0:
|
|
1031
|
-
showHelp();
|
|
1032
|
-
return;
|
|
1033
|
-
default:
|
|
1034
|
-
console.log(chalk.red(`
|
|
1035
|
-
\u672A\u77E5\u5B50\u547D\u4EE4: ${subCmd}`));
|
|
1036
|
-
showHelp();
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
];
|
|
1041
|
-
}
|
|
1042
|
-
export {
|
|
1043
|
-
createAdminSlashCommands
|
|
1044
|
-
};
|