@skrupellose/code-helper 0.1.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/README.md +64 -0
- package/dist/archive.d.ts +26 -0
- package/dist/archive.js +289 -0
- package/dist/archive.js.map +1 -0
- package/dist/checks.d.ts +6 -0
- package/dist/checks.js +351 -0
- package/dist/checks.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +651 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.js +84 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +27 -0
- package/dist/constants.js +68 -0
- package/dist/constants.js.map +1 -0
- package/dist/fs-utils.d.ts +46 -0
- package/dist/fs-utils.js +188 -0
- package/dist/fs-utils.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +21 -0
- package/dist/init.js +279 -0
- package/dist/init.js.map +1 -0
- package/dist/input-utils.d.ts +5 -0
- package/dist/input-utils.js +94 -0
- package/dist/input-utils.js.map +1 -0
- package/dist/skills.d.ts +41 -0
- package/dist/skills.js +201 -0
- package/dist/skills.js.map +1 -0
- package/dist/templates.d.ts +35 -0
- package/dist/templates.js +750 -0
- package/dist/templates.js.map +1 -0
- package/dist/terminal-ui.d.ts +44 -0
- package/dist/terminal-ui.js +189 -0
- package/dist/terminal-ui.js.map +1 -0
- package/dist/types.d.ts +56 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/workflows.d.ts +46 -0
- package/dist/workflows.js +284 -0
- package/dist/workflows.js.map +1 -0
- package/package.json +34 -0
package/dist/checks.js
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import { ENTRY_BLOCK_END, ENTRY_BLOCK_START, FEATURE_KEYS } from "./constants.js";
|
|
3
|
+
import { listTasks } from "./archive.js";
|
|
4
|
+
import { loadConfig } from "./config.js";
|
|
5
|
+
import { portablePath, projectPath, readTextIfExists, writeText } from "./fs-utils.js";
|
|
6
|
+
/**
|
|
7
|
+
* 运行项目协作规则检查。
|
|
8
|
+
* 检查只读项目结构,并把结果写入 `.code-helper/checks/latest.json`。
|
|
9
|
+
*/
|
|
10
|
+
export async function runChecks(projectRoot) {
|
|
11
|
+
const config = await loadConfig(projectRoot);
|
|
12
|
+
const issues = [];
|
|
13
|
+
if (!config.features.checks.enabled) {
|
|
14
|
+
return issues;
|
|
15
|
+
}
|
|
16
|
+
issues.push(...(await checkConfig(config)));
|
|
17
|
+
issues.push(...(await checkEntryDocuments(projectRoot, config)));
|
|
18
|
+
issues.push(...(await checkRuleDocuments(projectRoot, config)));
|
|
19
|
+
issues.push(...(await checkPlanDirectories(projectRoot, config)));
|
|
20
|
+
issues.push(...(await checkChineseWorkbenchDocuments(projectRoot, config)));
|
|
21
|
+
issues.push(...(await checkTestingPolicy(projectRoot, config)));
|
|
22
|
+
issues.push(...(await checkArchiveState(projectRoot, config)));
|
|
23
|
+
await writeText(projectPath(projectRoot, `${config.directories.workspace}/checks/latest.json`), `${JSON.stringify({ checkedAt: new Date().toISOString(), issues }, null, 2)}\n`);
|
|
24
|
+
return issues;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 检查计划、结果、状态和测试文档是否遵守中文命名规则。
|
|
28
|
+
* 生成端已经强制中文命名;检查端负责发现用户手动创建或旧文档残留。
|
|
29
|
+
*/
|
|
30
|
+
async function checkChineseWorkbenchDocuments(projectRoot, config) {
|
|
31
|
+
const issues = [];
|
|
32
|
+
if (!config.features.planWorkbench.enabled && !config.features.resultSummary.enabled) {
|
|
33
|
+
return issues;
|
|
34
|
+
}
|
|
35
|
+
issues.push(...(await checkPlanDocumentNames(projectRoot, config, config.directories.planDoc)));
|
|
36
|
+
issues.push(...(await checkPlanDocumentNames(projectRoot, config, portablePath(config.directories.planDoc, "archive"))));
|
|
37
|
+
issues.push(...(await checkResultDocumentNames(projectRoot, config, config.directories.resultDoc)));
|
|
38
|
+
issues.push(...(await checkResultDocumentNames(projectRoot, config, portablePath(config.directories.resultDoc, "archive"))));
|
|
39
|
+
issues.push(...(await checkStatusDocumentNames(projectRoot, config, config.directories.statusDoc)));
|
|
40
|
+
issues.push(...(await checkStatusDocumentNames(projectRoot, config, portablePath(config.directories.statusDoc, "archive"))));
|
|
41
|
+
return issues;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 检查 plan-doc 下的计划文件名。
|
|
45
|
+
* 计划文件必须是 `<中文功能名>.md`,archive 目录本身会跳过。
|
|
46
|
+
*/
|
|
47
|
+
async function checkPlanDocumentNames(projectRoot, config, relativeDirectory) {
|
|
48
|
+
const issues = [];
|
|
49
|
+
const files = await safeReadDirectory(projectPath(projectRoot, relativeDirectory));
|
|
50
|
+
if (files === undefined) {
|
|
51
|
+
return issues;
|
|
52
|
+
}
|
|
53
|
+
for (const file of files) {
|
|
54
|
+
if (file === "archive" || file === ".code-helper-keep" || !file.endsWith(".md")) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const featureName = file.slice(0, -".md".length);
|
|
58
|
+
if (!containsChinese(featureName)) {
|
|
59
|
+
issues.push(createChineseNameIssue(portablePath(relativeDirectory, file), "计划文档必须使用中文功能名,例如 订单管理升级.md。"));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return issues;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 检查 result-doc 下的任务目录和结果文件。
|
|
66
|
+
* 任务目录必须是中文功能名,目录内固定使用 实施记录.md 与 手工测试.md。
|
|
67
|
+
*/
|
|
68
|
+
async function checkResultDocumentNames(projectRoot, config, relativeDirectory) {
|
|
69
|
+
const issues = [];
|
|
70
|
+
const entries = await safeReadDirectory(projectPath(projectRoot, relativeDirectory));
|
|
71
|
+
if (entries === undefined) {
|
|
72
|
+
return issues;
|
|
73
|
+
}
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
if (entry === "archive" || entry === ".code-helper-keep" || entry.startsWith(".")) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const taskDirectory = portablePath(relativeDirectory, entry);
|
|
79
|
+
if (!containsChinese(entry)) {
|
|
80
|
+
issues.push(createChineseNameIssue(taskDirectory, "结果目录必须使用中文功能名,例如 订单管理升级/。"));
|
|
81
|
+
}
|
|
82
|
+
const files = await safeReadDirectory(projectPath(projectRoot, taskDirectory));
|
|
83
|
+
if (files === undefined) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
for (const file of files) {
|
|
87
|
+
if (file.startsWith(".") || !file.endsWith(".md")) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (file !== "实施记录.md" && file !== "手工测试.md") {
|
|
91
|
+
issues.push(createChineseNameIssue(portablePath(taskDirectory, file), "结果文件必须使用中文命名,固定使用 实施记录.md 或 手工测试.md。"));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return issues;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 检查 status-doc 下的状态文件名。
|
|
99
|
+
* 状态文件必须是 `<中文功能名>-状态.md`,旧版 `-status.md` 会被识别为不合规。
|
|
100
|
+
*/
|
|
101
|
+
async function checkStatusDocumentNames(projectRoot, config, relativeDirectory) {
|
|
102
|
+
const issues = [];
|
|
103
|
+
const files = await safeReadDirectory(projectPath(projectRoot, relativeDirectory));
|
|
104
|
+
if (files === undefined) {
|
|
105
|
+
return issues;
|
|
106
|
+
}
|
|
107
|
+
for (const file of files) {
|
|
108
|
+
if (file === "archive" || file === ".code-helper-keep" || !file.endsWith(".md")) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (!file.endsWith("-状态.md")) {
|
|
112
|
+
issues.push(createChineseNameIssue(portablePath(relativeDirectory, file), "状态文档必须使用 <中文功能名>-状态.md。"));
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const featureName = file.slice(0, -"-状态.md".length);
|
|
116
|
+
if (!containsChinese(featureName)) {
|
|
117
|
+
issues.push(createChineseNameIssue(portablePath(relativeDirectory, file), "状态文档的功能名必须包含中文。"));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return issues;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 构造中文命名违规问题。
|
|
124
|
+
* 集中创建可保持 code、message 和修复建议一致。
|
|
125
|
+
*/
|
|
126
|
+
function createChineseNameIssue(path, suggestion) {
|
|
127
|
+
return {
|
|
128
|
+
level: "error",
|
|
129
|
+
code: "non-chinese-document-name",
|
|
130
|
+
message: `文档未使用中文命名:${path}`,
|
|
131
|
+
path,
|
|
132
|
+
suggestion
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 判断字符串是否包含中文字符。
|
|
137
|
+
* 文档命名规则要求任务名至少包含一个中文字符。
|
|
138
|
+
*/
|
|
139
|
+
function containsChinese(value) {
|
|
140
|
+
return /\p{Script=Han}/u.test(value);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 检查文档归档目录和任务状态。
|
|
144
|
+
* archive 中的任务视为已结束;同名任务同时存在 active 与 archive 时提示人工确认。
|
|
145
|
+
*/
|
|
146
|
+
async function checkArchiveState(projectRoot, config) {
|
|
147
|
+
const issues = [];
|
|
148
|
+
if (!config.features.documentArchive.enabled) {
|
|
149
|
+
return issues;
|
|
150
|
+
}
|
|
151
|
+
for (const directory of [
|
|
152
|
+
`${config.directories.planDoc}/archive`,
|
|
153
|
+
`${config.directories.resultDoc}/archive`,
|
|
154
|
+
`${config.directories.statusDoc}/archive`
|
|
155
|
+
]) {
|
|
156
|
+
const files = await safeReadDirectory(projectPath(projectRoot, directory));
|
|
157
|
+
if (files === undefined) {
|
|
158
|
+
issues.push({
|
|
159
|
+
level: "error",
|
|
160
|
+
code: "missing-archive-directory",
|
|
161
|
+
message: `归档目录不存在:${directory}`,
|
|
162
|
+
path: directory,
|
|
163
|
+
suggestion: "运行 `npx @skrupellose/code-helper init` 创建文档归档目录。"
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
for (const task of await listTasks(projectRoot)) {
|
|
168
|
+
if (task.status === "mixed") {
|
|
169
|
+
issues.push({
|
|
170
|
+
level: "warning",
|
|
171
|
+
code: "mixed-task-archive-state",
|
|
172
|
+
message: `任务同时存在活动文档和归档文档:${task.featureName}`,
|
|
173
|
+
suggestion: "确认该任务是否已经结束;如果已结束,运行 `npx @skrupellose/code-helper archive <中文功能名>` 或手动补齐归档。"
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return issues;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* 检查配置本身是否保持完整。
|
|
181
|
+
* 这能发现用户手工编辑 config.json 时误删功能项的问题。
|
|
182
|
+
*/
|
|
183
|
+
async function checkConfig(config) {
|
|
184
|
+
const issues = [];
|
|
185
|
+
for (const feature of FEATURE_KEYS) {
|
|
186
|
+
if (config.features[feature] === undefined) {
|
|
187
|
+
issues.push({
|
|
188
|
+
level: "error",
|
|
189
|
+
code: "missing-feature-toggle",
|
|
190
|
+
message: `配置缺少功能开关:${feature}`,
|
|
191
|
+
path: ".code-helper/config.json",
|
|
192
|
+
suggestion: "重新运行 `npx @skrupellose/code-helper init`,让工具补齐默认配置。"
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return issues;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* 检查入口文档是否存在 code-helper 管理区块。
|
|
200
|
+
* 入口文档是 agent 发现专题规则的第一站,因此缺失时给 error。
|
|
201
|
+
*/
|
|
202
|
+
async function checkEntryDocuments(projectRoot, config) {
|
|
203
|
+
const issues = [];
|
|
204
|
+
const entryFiles = [
|
|
205
|
+
config.entryFiles.agents ? "AGENTS.md" : undefined,
|
|
206
|
+
config.entryFiles.claude ? "CLAUDE.md" : undefined
|
|
207
|
+
].filter((file) => file !== undefined);
|
|
208
|
+
for (const entryFile of entryFiles) {
|
|
209
|
+
const content = await readTextIfExists(projectPath(projectRoot, entryFile));
|
|
210
|
+
if (content === undefined) {
|
|
211
|
+
issues.push({
|
|
212
|
+
level: "error",
|
|
213
|
+
code: "missing-entry-document",
|
|
214
|
+
message: `入口文档不存在:${entryFile}`,
|
|
215
|
+
path: entryFile,
|
|
216
|
+
suggestion: "运行 `npx @skrupellose/code-helper init` 创建入口文档。"
|
|
217
|
+
});
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (!content.includes(ENTRY_BLOCK_START) || !content.includes(ENTRY_BLOCK_END)) {
|
|
221
|
+
issues.push({
|
|
222
|
+
level: "error",
|
|
223
|
+
code: "missing-managed-block",
|
|
224
|
+
message: `入口文档缺少 code-helper 受控区块:${entryFile}`,
|
|
225
|
+
path: entryFile,
|
|
226
|
+
suggestion: "运行 `npx @skrupellose/code-helper init` 追加受控索引区块。"
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return issues;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* 检查专题规则文档结构。
|
|
234
|
+
* 每份规则都要包含固定四段,这样 agent 可以稳定读取和执行。
|
|
235
|
+
*/
|
|
236
|
+
async function checkRuleDocuments(projectRoot, config) {
|
|
237
|
+
const issues = [];
|
|
238
|
+
const rulesDirectory = projectPath(projectRoot, config.directories.userRules);
|
|
239
|
+
const requiredSections = ["## 功能描述", "## 调用时机", "## 调用入口文件", "## 规则"];
|
|
240
|
+
let files = [];
|
|
241
|
+
try {
|
|
242
|
+
files = await readdir(rulesDirectory);
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
issues.push({
|
|
246
|
+
level: "error",
|
|
247
|
+
code: "missing-user-rules-directory",
|
|
248
|
+
message: "专题规则目录不存在",
|
|
249
|
+
path: config.directories.userRules,
|
|
250
|
+
suggestion: "运行 `npx @skrupellose/code-helper init` 创建专题规则目录和默认规则。"
|
|
251
|
+
});
|
|
252
|
+
return issues;
|
|
253
|
+
}
|
|
254
|
+
const markdownFiles = files.filter((file) => file.endsWith(".md"));
|
|
255
|
+
if (markdownFiles.length === 0) {
|
|
256
|
+
issues.push({
|
|
257
|
+
level: "error",
|
|
258
|
+
code: "empty-user-rules-directory",
|
|
259
|
+
message: "专题规则目录中没有 Markdown 规则文件",
|
|
260
|
+
path: config.directories.userRules,
|
|
261
|
+
suggestion: "运行 `npx @skrupellose/code-helper init` 安装默认专题规则。"
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
for (const file of markdownFiles) {
|
|
265
|
+
const relativePath = portablePath(config.directories.userRules, file);
|
|
266
|
+
const content = await readTextIfExists(projectPath(projectRoot, relativePath));
|
|
267
|
+
for (const section of requiredSections) {
|
|
268
|
+
if (!content?.includes(section)) {
|
|
269
|
+
issues.push({
|
|
270
|
+
level: "error",
|
|
271
|
+
code: "invalid-rule-document",
|
|
272
|
+
message: `专题规则缺少小节 ${section}:${file}`,
|
|
273
|
+
path: relativePath,
|
|
274
|
+
suggestion: "补齐“功能描述 / 调用时机 / 调用入口文件 / 规则”四个小节。"
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return issues;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* 检查计划、结果和状态目录是否存在。
|
|
283
|
+
* 这些目录是项目计划文档的固定落点。
|
|
284
|
+
*/
|
|
285
|
+
async function checkPlanDirectories(projectRoot, config) {
|
|
286
|
+
const issues = [];
|
|
287
|
+
if (!config.features.planWorkbench.enabled && !config.features.resultSummary.enabled) {
|
|
288
|
+
return issues;
|
|
289
|
+
}
|
|
290
|
+
for (const directory of [config.directories.planDoc, config.directories.resultDoc, config.directories.statusDoc]) {
|
|
291
|
+
const marker = await readTextIfExists(projectPath(projectRoot, `${directory}/.code-helper-keep`));
|
|
292
|
+
const files = await safeReadDirectory(projectPath(projectRoot, directory));
|
|
293
|
+
if (marker === undefined && files === undefined) {
|
|
294
|
+
issues.push({
|
|
295
|
+
level: "error",
|
|
296
|
+
code: "missing-workbench-directory",
|
|
297
|
+
message: `计划文档目录不存在:${directory}`,
|
|
298
|
+
path: directory,
|
|
299
|
+
suggestion: "运行 `npx @skrupellose/code-helper init` 创建计划、结果和状态目录。"
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return issues;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* 检查测试策略是否已经安装。
|
|
307
|
+
* 如果用户关闭 testingPolicy,则跳过该检查。
|
|
308
|
+
*/
|
|
309
|
+
async function checkTestingPolicy(projectRoot, config) {
|
|
310
|
+
if (!config.features.testingPolicy.enabled) {
|
|
311
|
+
return [];
|
|
312
|
+
}
|
|
313
|
+
const policyPath = `${config.directories.userRules}/测试策略规范.md`;
|
|
314
|
+
const content = await readTextIfExists(projectPath(projectRoot, policyPath));
|
|
315
|
+
if (content === undefined) {
|
|
316
|
+
return [
|
|
317
|
+
{
|
|
318
|
+
level: "error",
|
|
319
|
+
code: "missing-testing-policy",
|
|
320
|
+
message: "缺少测试策略规范",
|
|
321
|
+
path: policyPath,
|
|
322
|
+
suggestion: "运行 `npx @skrupellose/code-helper init` 安装默认测试策略规范。"
|
|
323
|
+
}
|
|
324
|
+
];
|
|
325
|
+
}
|
|
326
|
+
if (!content.includes("页面相关测试全部生成严格手工测试文档")) {
|
|
327
|
+
return [
|
|
328
|
+
{
|
|
329
|
+
level: "warning",
|
|
330
|
+
code: "testing-policy-weakened",
|
|
331
|
+
message: "测试策略规范可能缺少页面手工测试约束",
|
|
332
|
+
path: policyPath,
|
|
333
|
+
suggestion: "补充页面测试只生成手工测试文档、工具只执行纯逻辑测试的规则。"
|
|
334
|
+
}
|
|
335
|
+
];
|
|
336
|
+
}
|
|
337
|
+
return [];
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* 安全读取目录。
|
|
341
|
+
* 不存在时返回 undefined,避免检查流程因单个目录缺失中断。
|
|
342
|
+
*/
|
|
343
|
+
async function safeReadDirectory(path) {
|
|
344
|
+
try {
|
|
345
|
+
return await readdir(path);
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"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"}
|