@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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { ReadStream, WriteStream } from "node:tty";
2
+ /**
3
+ * 单选菜单项。
4
+ * value 是程序内部使用的稳定值,label 是展示给用户看的文案。
5
+ */
6
+ export interface SelectOption<T extends string> {
7
+ value: T;
8
+ label: string;
9
+ }
10
+ /**
11
+ * 多选菜单项。
12
+ * checked 表示当前是否启用,通常用于功能开关列表。
13
+ */
14
+ export interface MultiSelectOption<T extends string> extends SelectOption<T> {
15
+ checked: boolean;
16
+ }
17
+ /**
18
+ * 多选菜单结果。
19
+ * cancelled 表示用户按 Esc 返回,不保存任何更改。
20
+ */
21
+ export interface MultiSelectResult<T extends string> {
22
+ options: Array<MultiSelectOption<T>>;
23
+ cancelled: boolean;
24
+ }
25
+ /**
26
+ * 判断当前进程是否支持原始按键交互。
27
+ * 非 TTY 环境例如 CI、管道输入或日志采集场景,应回退到普通文本输入。
28
+ */
29
+ export declare function canUseInteractiveKeys(input: NodeJS.ReadStream, output: NodeJS.WriteStream): input is ReadStream;
30
+ /**
31
+ * 渲染单选菜单,并通过方向键移动、空格或回车确认。
32
+ * 该函数不依赖第三方包,便于 code-helper 保持轻量安装体积。
33
+ */
34
+ export declare function promptSelect<T extends string>(input: ReadStream, output: WriteStream, title: string, options: Array<SelectOption<T>>): Promise<T>;
35
+ /**
36
+ * 渲染多选菜单。
37
+ * 空格切换当前项,回车保存所有选择,适合功能开关批量修改。
38
+ */
39
+ export declare function promptMultiSelect<T extends string>(input: ReadStream, output: WriteStream, title: string, options: Array<MultiSelectOption<T>>): Promise<MultiSelectResult<T>>;
40
+ /**
41
+ * 等待用户确认后继续。
42
+ * 用于菜单动作结束后暂停,避免下一次菜单重绘把执行结果立即清掉。
43
+ */
44
+ export declare function promptContinue(input: ReadStream, output: WriteStream, message?: string): Promise<void>;
@@ -0,0 +1,189 @@
1
+ import { clearScreenDown, cursorTo, emitKeypressEvents } from "node:readline";
2
+ /**
3
+ * 判断当前进程是否支持原始按键交互。
4
+ * 非 TTY 环境例如 CI、管道输入或日志采集场景,应回退到普通文本输入。
5
+ */
6
+ export function canUseInteractiveKeys(input, output) {
7
+ return Boolean(input.isTTY && output.isTTY && typeof input.setRawMode === "function");
8
+ }
9
+ /**
10
+ * 渲染单选菜单,并通过方向键移动、空格或回车确认。
11
+ * 该函数不依赖第三方包,便于 code-helper 保持轻量安装体积。
12
+ */
13
+ export async function promptSelect(input, output, title, options) {
14
+ let selectedIndex = 0;
15
+ return withRawMode(input, output, () => {
16
+ return new Promise((resolve) => {
17
+ /**
18
+ * 重新绘制菜单。
19
+ * 每次按键后清空当前屏幕区域,避免列表残影。
20
+ */
21
+ const render = () => {
22
+ cursorTo(output, 0, 0);
23
+ clearScreenDown(output);
24
+ output.write(`${title}\n`);
25
+ output.write("使用 ↑/↓ 移动,空格或回车确认,Ctrl+C 退出。\n\n");
26
+ for (const [index, option] of options.entries()) {
27
+ const pointer = index === selectedIndex ? ">" : " ";
28
+ output.write(`${pointer} ${option.label}\n`);
29
+ }
30
+ };
31
+ /**
32
+ * 处理键盘输入。
33
+ * 支持方向键,也支持 j/k,方便不同终端习惯。
34
+ */
35
+ const onKeypress = (_text, key) => {
36
+ if (key.ctrl && key.name === "c") {
37
+ cleanup();
38
+ process.exit(130);
39
+ }
40
+ if (key.name === "up" || key.name === "k") {
41
+ selectedIndex = (selectedIndex - 1 + options.length) % options.length;
42
+ render();
43
+ return;
44
+ }
45
+ if (key.name === "down" || key.name === "j") {
46
+ selectedIndex = (selectedIndex + 1) % options.length;
47
+ render();
48
+ return;
49
+ }
50
+ if (key.name === "return" || key.name === "space") {
51
+ const selectedValue = options[selectedIndex]?.value;
52
+ cleanup();
53
+ resolve(selectedValue);
54
+ }
55
+ };
56
+ /**
57
+ * 清理按键监听并把光标放到菜单下方。
58
+ */
59
+ const cleanup = () => {
60
+ input.off("keypress", onKeypress);
61
+ cursorTo(output, 0, options.length + 4);
62
+ };
63
+ input.on("keypress", onKeypress);
64
+ render();
65
+ });
66
+ });
67
+ }
68
+ /**
69
+ * 渲染多选菜单。
70
+ * 空格切换当前项,回车保存所有选择,适合功能开关批量修改。
71
+ */
72
+ export async function promptMultiSelect(input, output, title, options) {
73
+ let selectedIndex = 0;
74
+ const nextOptions = options.map((option) => ({ ...option }));
75
+ return withRawMode(input, output, () => {
76
+ return new Promise((resolve) => {
77
+ /**
78
+ * 重新绘制多选菜单。
79
+ * checked 用 [x] / [ ] 展示,用户可以直接看到切换结果。
80
+ */
81
+ const render = () => {
82
+ cursorTo(output, 0, 0);
83
+ clearScreenDown(output);
84
+ output.write(`${title}\n`);
85
+ output.write("使用 ↑/↓ 移动,空格切换,回车保存,Esc 返回,Ctrl+C 退出。\n\n");
86
+ for (const [index, option] of nextOptions.entries()) {
87
+ const pointer = index === selectedIndex ? ">" : " ";
88
+ const marker = option.checked ? "[x]" : "[ ]";
89
+ output.write(`${pointer} ${marker} ${option.label}\n`);
90
+ }
91
+ };
92
+ /**
93
+ * 处理多选菜单键盘输入。
94
+ * 回车只保存,不切换当前项,避免误操作。
95
+ */
96
+ const onKeypress = (_text, key) => {
97
+ if (key.ctrl && key.name === "c") {
98
+ cleanup();
99
+ process.exit(130);
100
+ }
101
+ if (key.name === "up" || key.name === "k") {
102
+ selectedIndex = (selectedIndex - 1 + nextOptions.length) % nextOptions.length;
103
+ render();
104
+ return;
105
+ }
106
+ if (key.name === "down" || key.name === "j") {
107
+ selectedIndex = (selectedIndex + 1) % nextOptions.length;
108
+ render();
109
+ return;
110
+ }
111
+ if (key.name === "space") {
112
+ nextOptions[selectedIndex].checked = !nextOptions[selectedIndex].checked;
113
+ render();
114
+ return;
115
+ }
116
+ if (key.name === "return") {
117
+ cleanup();
118
+ resolve({ options: nextOptions, cancelled: false });
119
+ return;
120
+ }
121
+ if (key.name === "escape") {
122
+ cleanup();
123
+ resolve({ options, cancelled: true });
124
+ }
125
+ };
126
+ /**
127
+ * 清理按键监听并把光标放到菜单下方。
128
+ */
129
+ const cleanup = () => {
130
+ input.off("keypress", onKeypress);
131
+ cursorTo(output, 0, nextOptions.length + 4);
132
+ };
133
+ input.on("keypress", onKeypress);
134
+ render();
135
+ });
136
+ });
137
+ }
138
+ /**
139
+ * 等待用户确认后继续。
140
+ * 用于菜单动作结束后暂停,避免下一次菜单重绘把执行结果立即清掉。
141
+ */
142
+ export async function promptContinue(input, output, message = "按回车返回菜单...") {
143
+ return withRawMode(input, output, () => {
144
+ return new Promise((resolve) => {
145
+ output.write(`\n${message}`);
146
+ /**
147
+ * 处理继续按键。
148
+ * 回车、空格或 Esc 都视为确认返回菜单。
149
+ */
150
+ const onKeypress = (_text, key) => {
151
+ if (key.ctrl && key.name === "c") {
152
+ cleanup();
153
+ process.exit(130);
154
+ }
155
+ if (key.name === "return" || key.name === "space" || key.name === "escape") {
156
+ cleanup();
157
+ resolve();
158
+ }
159
+ };
160
+ /**
161
+ * 清理按键监听并换行,避免下一次菜单贴在提示后面。
162
+ */
163
+ const cleanup = () => {
164
+ input.off("keypress", onKeypress);
165
+ output.write("\n");
166
+ };
167
+ input.on("keypress", onKeypress);
168
+ });
169
+ });
170
+ }
171
+ /**
172
+ * 在 raw mode 下执行交互函数,并确保结束时恢复终端状态。
173
+ * 这样即使交互中抛错,也不会让用户终端停留在不可输入状态。
174
+ */
175
+ async function withRawMode(input, output, action) {
176
+ emitKeypressEvents(input);
177
+ const wasRaw = input.isRaw;
178
+ input.setRawMode(true);
179
+ input.resume();
180
+ output.write("\x1B[?25l");
181
+ try {
182
+ return await action();
183
+ }
184
+ finally {
185
+ output.write("\x1B[?25h");
186
+ input.setRawMode(wasRaw);
187
+ }
188
+ }
189
+ //# sourceMappingURL=terminal-ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-ui.js","sourceRoot":"","sources":["../src/terminal-ui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * code-helper 支持的功能开关名称。
3
+ * 这些 key 会直接写入 `.code-helper/config.json`,因此需要保持稳定。
4
+ */
5
+ export type FeatureKey = "memoryTuning" | "planWorkbench" | "resultSummary" | "testingPolicy" | "documentArchive" | "checks" | "gitHooks" | "skillRegistration";
6
+ /**
7
+ * 单个功能开关的配置。
8
+ * 使用对象而不是布尔值,是为了后续能无破坏扩展更多元数据。
9
+ */
10
+ export interface FeatureToggle {
11
+ enabled: boolean;
12
+ }
13
+ /**
14
+ * code-helper 的项目级配置文件结构。
15
+ * 该配置只描述 code-helper 自己的行为,不承载业务项目配置。
16
+ */
17
+ export interface CodeHelperConfig {
18
+ version: number;
19
+ entryFiles: {
20
+ agents: boolean;
21
+ claude: boolean;
22
+ };
23
+ directories: {
24
+ workspace: string;
25
+ userRules: string;
26
+ planDoc: string;
27
+ resultDoc: string;
28
+ statusDoc: string;
29
+ };
30
+ features: Record<FeatureKey, FeatureToggle>;
31
+ }
32
+ /**
33
+ * 一次文件写入或跳过操作的结构化结果。
34
+ * CLI 用它统一输出初始化摘要,测试也用它验证非覆盖行为。
35
+ */
36
+ export interface OperationResult {
37
+ path: string;
38
+ action: "created" | "updated" | "skipped";
39
+ message: string;
40
+ }
41
+ /**
42
+ * 项目规则检查的严重程度。
43
+ * error 会让 `code-helper check` 返回非 0,warning 只提示修复建议。
44
+ */
45
+ export type CheckLevel = "error" | "warning";
46
+ /**
47
+ * 单条检查结果。
48
+ * 每条结果都带有可读建议,避免用户只看到失败而不知道下一步。
49
+ */
50
+ export interface CheckIssue {
51
+ level: CheckLevel;
52
+ code: string;
53
+ message: string;
54
+ path?: string;
55
+ suggestion: string;
56
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import type { OperationResult } from "./types.js";
2
+ /**
3
+ * 新版生成文档固定使用中文文件名。
4
+ * 目录名仍沿用配置路径,避免破坏既有 .agent 目录约定。
5
+ */
6
+ export declare const RESULT_RECORD_FILE_NAME = "\u5B9E\u65BD\u8BB0\u5F55.md";
7
+ export declare const MANUAL_TEST_FILE_NAME = "\u624B\u5DE5\u6D4B\u8BD5.md";
8
+ /**
9
+ * 计划文档生成参数。
10
+ * requirementPath 指向用户准备好的完整需求文档。
11
+ */
12
+ export interface PlanWorkbenchOptions {
13
+ projectRoot: string;
14
+ requirementPath: string;
15
+ featureName?: string;
16
+ }
17
+ /**
18
+ * 手工测试文档生成参数。
19
+ * featureName 用于决定输出目录,title 用于文档标题。
20
+ * 新生成的文档路径会强制使用中文名称,避免 docs 区域继续出现英文任务文档。
21
+ */
22
+ export interface ManualTestOptions {
23
+ projectRoot: string;
24
+ featureName: string;
25
+ title?: string;
26
+ }
27
+ /**
28
+ * 根据需求文档生成计划文档的三类产物。
29
+ * 这里生成的是可编辑模板,真正的任务细拆仍由 agent 根据需求内容继续完善。
30
+ */
31
+ export declare function createPlanWorkbench(options: PlanWorkbenchOptions): Promise<OperationResult[]>;
32
+ /**
33
+ * 生成独立手工测试文档。
34
+ * 页面测试默认交给用户手工执行,因此此函数不启动浏览器自动化。
35
+ */
36
+ export declare function createManualTestDocument(options: ManualTestOptions): Promise<OperationResult>;
37
+ /**
38
+ * 把用户输入转换成稳定路径片段。
39
+ * 仅保留字母、数字、中文、下划线和短横线,避免生成不可预期路径。
40
+ */
41
+ export declare function normalizeFeatureName(value: string): string;
42
+ /**
43
+ * 把功能名转换成中文文档名。
44
+ * 如果输入没有中文字符,则使用中文兜底名,避免新生成的 docs 文档继续使用英文命名。
45
+ */
46
+ export declare function normalizeDocumentName(value: string, fallbackName: string): string;
@@ -0,0 +1,284 @@
1
+ import { basename, isAbsolute, join } from "node:path";
2
+ import { loadConfig } from "./config.js";
3
+ import { projectPath, readTextIfExists, writeTextIfMissing } from "./fs-utils.js";
4
+ /**
5
+ * 新版生成文档固定使用中文文件名。
6
+ * 目录名仍沿用配置路径,避免破坏既有 .agent 目录约定。
7
+ */
8
+ export const RESULT_RECORD_FILE_NAME = "实施记录.md";
9
+ export const MANUAL_TEST_FILE_NAME = "手工测试.md";
10
+ /**
11
+ * 根据需求文档生成计划文档的三类产物。
12
+ * 这里生成的是可编辑模板,真正的任务细拆仍由 agent 根据需求内容继续完善。
13
+ */
14
+ export async function createPlanWorkbench(options) {
15
+ const config = await loadConfig(options.projectRoot);
16
+ const requirementAbsolutePath = isAbsolute(options.requirementPath)
17
+ ? options.requirementPath
18
+ : projectPath(options.projectRoot, options.requirementPath);
19
+ const requirement = await readTextIfExists(requirementAbsolutePath);
20
+ if (requirement === undefined) {
21
+ throw new Error(`需求文档不存在:${options.requirementPath}`);
22
+ }
23
+ const featureName = inferChineseFeatureName(options.featureName, options.requirementPath, requirement);
24
+ const planPath = projectPath(options.projectRoot, join(config.directories.planDoc, `${featureName}.md`));
25
+ const resultPath = projectPath(options.projectRoot, join(config.directories.resultDoc, featureName, RESULT_RECORD_FILE_NAME));
26
+ const statusPath = projectPath(options.projectRoot, join(config.directories.statusDoc, `${featureName}-状态.md`));
27
+ const manualTestPath = projectPath(options.projectRoot, join(config.directories.resultDoc, featureName, MANUAL_TEST_FILE_NAME));
28
+ return [
29
+ await writeTextIfMissing(planPath, renderPlanDocument(featureName, options.requirementPath, requirement)),
30
+ await writeTextIfMissing(resultPath, renderResultDocument(featureName)),
31
+ await writeTextIfMissing(statusPath, renderStatusDocument(featureName)),
32
+ await writeTextIfMissing(manualTestPath, renderManualTestDocument(featureName, `${featureName} 页面回归测试`))
33
+ ];
34
+ }
35
+ /**
36
+ * 生成独立手工测试文档。
37
+ * 页面测试默认交给用户手工执行,因此此函数不启动浏览器自动化。
38
+ */
39
+ export async function createManualTestDocument(options) {
40
+ const config = await loadConfig(options.projectRoot);
41
+ const featureName = normalizeDocumentName(options.featureName, "页面功能");
42
+ const targetPath = projectPath(options.projectRoot, join(config.directories.resultDoc, featureName, MANUAL_TEST_FILE_NAME));
43
+ return writeTextIfMissing(targetPath, renderManualTestDocument(featureName, options.title ?? `${featureName} 手工测试`));
44
+ }
45
+ /**
46
+ * 把用户输入转换成稳定路径片段。
47
+ * 仅保留字母、数字、中文、下划线和短横线,避免生成不可预期路径。
48
+ */
49
+ export function normalizeFeatureName(value) {
50
+ const normalized = value
51
+ .trim()
52
+ .replace(/\s+/gu, "-")
53
+ .replace(/[^\p{L}\p{N}_-]/gu, "")
54
+ .replace(/-+/gu, "-")
55
+ .replace(/^-|-$/gu, "");
56
+ return normalized.length > 0 ? normalized : "feature";
57
+ }
58
+ /**
59
+ * 把功能名转换成中文文档名。
60
+ * 如果输入没有中文字符,则使用中文兜底名,避免新生成的 docs 文档继续使用英文命名。
61
+ */
62
+ export function normalizeDocumentName(value, fallbackName) {
63
+ const normalized = value
64
+ .trim()
65
+ .replace(/\s+/gu, "-")
66
+ .replace(/[^\p{Script=Han}\p{N}_-]/gu, "")
67
+ .replace(/-+/gu, "-")
68
+ .replace(/^-|-$/gu, "");
69
+ if (normalized !== "" && containsChinese(normalized)) {
70
+ return normalized;
71
+ }
72
+ return fallbackName;
73
+ }
74
+ /**
75
+ * 推断中文功能名。
76
+ * 优先使用用户输入的中文功能名,其次使用需求文档中的中文一级标题,最后用中文兜底名。
77
+ */
78
+ function inferChineseFeatureName(featureName, requirementPath, requirement) {
79
+ const titleFallback = extractChineseMarkdownTitle(requirement) ?? normalizeDocumentName(basename(requirementPath, ".md"), "功能计划");
80
+ if (featureName !== undefined && featureName.trim() !== "") {
81
+ return normalizeDocumentName(featureName, titleFallback);
82
+ }
83
+ return titleFallback;
84
+ }
85
+ /**
86
+ * 从 Markdown 文档中提取第一个中文标题。
87
+ * 这让用户拖拽英文文件名的需求文档时,也能生成中文功能文档名。
88
+ */
89
+ function extractChineseMarkdownTitle(content) {
90
+ const lines = content.split("\n");
91
+ for (const line of lines) {
92
+ const match = line.match(/^#\s+(.+)$/u);
93
+ if (!match) {
94
+ continue;
95
+ }
96
+ const title = normalizeDocumentName(match[1], "");
97
+ if (title !== "") {
98
+ return title;
99
+ }
100
+ }
101
+ return undefined;
102
+ }
103
+ /**
104
+ * 判断字符串中是否包含中文字符。
105
+ */
106
+ function containsChinese(value) {
107
+ return /\p{Script=Han}/u.test(value);
108
+ }
109
+ /**
110
+ * 渲染计划文档模板。
111
+ * 模板把示例 SOP 的关键结构固化成可持续推进的计划文档。
112
+ */
113
+ function renderPlanDocument(featureName, requirementPath, requirement) {
114
+ const excerpt = requirement.trim().slice(0, 2000);
115
+ return `# ${featureName} 执行计划
116
+
117
+ ## 需求来源
118
+
119
+ - 原始需求文档:\`${requirementPath}\`
120
+
121
+ ## 下一步建议
122
+
123
+ 1. 先确认目标、阶段边界和验收标准。
124
+ 2. 再按依赖顺序拆分基础能力、核心实现、集成验收和复查任务。
125
+ 3. 涉及页面、可视化或浏览器链路时,只生成手工测试文档,由用户执行。
126
+ 4. 工具执行测试时只运行纯逻辑测试,例如函数单元测试或非浏览器集成测试。
127
+
128
+ ## 需求摘要
129
+
130
+ > 以下内容来自原始需求文档的前 2000 个字符,后续拆分时以原文为准。
131
+
132
+ \`\`\`text
133
+ ${excerpt}
134
+ \`\`\`
135
+
136
+ ## 阶段边界
137
+
138
+ | 子任务 | 已完成 | 未完成 | 备注 |
139
+ |---|---|---|---|
140
+ | 目标与约束确认 | | 明确目标、范围、验收标准 | 状态:未开始;先完成需求澄清 |
141
+ | 依赖顺序拆分 | | 按基础能力、数据模型、核心模块、集成验收、复查范围排序 | 状态:未开始;不要按文档顺序或界面直觉直接实现 |
142
+ | 执行批次规划 | | 拆成可交接的小节点 | 状态:未开始;每个节点完成后写 result-doc |
143
+
144
+ ## 子任务拆分
145
+
146
+ | 子任务 | 已完成 | 未完成 | 备注 |
147
+ |---|---|---|---|
148
+ | 基础能力 | | 待根据需求细化 | 状态:未开始 |
149
+ | 数据与接口 | | 待根据需求细化 | 状态:未开始 |
150
+ | 核心实现 | | 待根据需求细化模块、服务、命令、任务、页面或数据流 | 状态:未开始 |
151
+ | 集成验收 | | 待根据需求细化联调、复查、发布和人工验收环节 | 状态:未开始 |
152
+ | 自动化验证 | | 待根据纯逻辑模块补单元或集成测试 | 状态:未开始 |
153
+ | 手工验收 | | 涉及页面、可视化、浏览器链路或人工业务验收时写 ${MANUAL_TEST_FILE_NAME} | 状态:未开始 |
154
+
155
+ ## 验收标准
156
+
157
+ - 计划中的每个子任务都有完成定义。
158
+ - 纯逻辑改动有自动化测试或明确无法测试说明。
159
+ - 页面、可视化、浏览器链路或人工业务验收有手工测试文档。
160
+ - 阻塞点和后续风险同步到 status-doc。
161
+
162
+ ## 状态记录
163
+
164
+ - 当前状态文件:\`code-helper-docs/status-doc/${featureName}-状态.md\`
165
+ - 执行记录目录:\`code-helper-docs/result-doc/${featureName}/\`
166
+ - 手工测试文档:\`code-helper-docs/result-doc/${featureName}/${MANUAL_TEST_FILE_NAME}\`
167
+ `;
168
+ }
169
+ /**
170
+ * 渲染执行结果文档模板。
171
+ * 小节点完成后可以直接在该模板上补充真实实施内容。
172
+ */
173
+ function renderResultDocument(featureName) {
174
+ return `# ${featureName} 实施记录
175
+
176
+ ## 背景
177
+
178
+ - 待补充任务背景、用户反馈或需求来源。
179
+
180
+ ## 实施总结
181
+
182
+ - 待用中文总结本节点完成了什么、未完成什么、下一步是什么。
183
+
184
+ ## 实现
185
+
186
+ - 待记录本节点实际改动。
187
+
188
+ ## 验证
189
+
190
+ - 纯逻辑测试:待记录命令和结论。
191
+ - 人工验收:涉及页面、可视化、浏览器链路或人工业务验收时,见 \`${MANUAL_TEST_FILE_NAME}\`。
192
+
193
+ ## 风险与后续
194
+
195
+ - 待记录阻塞点、后续检查点和注意事项。
196
+ `;
197
+ }
198
+ /**
199
+ * 渲染当前状态记录模板。
200
+ * 该文件只保留当前仍影响决策的信息,不做流水账。
201
+ */
202
+ function renderStatusDocument(featureName) {
203
+ return `# ${featureName} 状态
204
+
205
+ ## 当前状态
206
+
207
+ 1. 状态:未开始;已创建计划文档,等待拆分和执行。
208
+
209
+ ## 下一步
210
+
211
+ 1. 完成需求目标、阶段边界和验收标准确认。
212
+ 2. 按依赖顺序细化计划文档。
213
+ 3. 开始第一个可交接小节点。
214
+
215
+ ## 阶段进度
216
+
217
+ - 计划初始化:已创建。
218
+
219
+ ## 关键结论
220
+
221
+ - 页面、可视化和浏览器链路只生成手工测试文档。
222
+ - 工具只执行纯逻辑测试。
223
+
224
+ ## 关键索引
225
+
226
+ - 执行计划:\`code-helper-docs/plan-doc/${featureName}.md\`
227
+ - 实施记录:\`code-helper-docs/result-doc/${featureName}/${RESULT_RECORD_FILE_NAME}\`
228
+ - 手工测试:\`code-helper-docs/result-doc/${featureName}/${MANUAL_TEST_FILE_NAME}\`
229
+
230
+ ## 仍会影响后续判断的风险点
231
+
232
+ 1. 需求尚未拆成可执行小节点。
233
+
234
+ ## 最近一次更新
235
+
236
+ - ${new Date().toISOString().slice(0, 10)}:创建 code-helper 状态记录。
237
+ `;
238
+ }
239
+ /**
240
+ * 渲染页面手工测试文档模板。
241
+ * 文档要求用户执行真实页面测试,避免工具默认跑慢且不稳定的浏览器自动化。
242
+ */
243
+ function renderManualTestDocument(featureName, title) {
244
+ return `# ${title}
245
+
246
+ ## 测试策略
247
+
248
+ - 本文档用于页面、组件交互、视觉和真实浏览器链路的手工测试。
249
+ - code-helper 不默认执行 Playwright、截图对比或浏览器自动化。
250
+ - 工具侧只执行纯逻辑测试,例如函数单元测试或非浏览器集成测试。
251
+
252
+ ## 测试环境
253
+
254
+ - 环境地址:待填写
255
+ - 测试账号:待填写
256
+ - 浏览器与设备:待填写
257
+ - 分支或版本:待填写
258
+
259
+ ## 前置数据
260
+
261
+ - 待填写页面所需账号、订单、商品、权限、配置或其他业务数据。
262
+
263
+ ## 操作步骤
264
+
265
+ | 步骤 | 操作 | 预期结果 | 实际结果 | 状态 |
266
+ |---|---|---|---|---|
267
+ | 1 | 打开目标页面 | 页面正常加载,无阻塞错误 | | 未测试 |
268
+ | 2 | 执行核心交互 | 交互结果符合需求 | | 未测试 |
269
+ | 3 | 验证异常或空状态 | 展示符合设计和业务预期 | | 未测试 |
270
+
271
+ ## 回归范围
272
+
273
+ - 功能范围:${featureName}
274
+ - UI 验收:待补充关键视觉和布局点。
275
+ - 功能验收:待补充数据提交、跳转、权限和错误处理。
276
+
277
+ ## 阻塞记录
278
+
279
+ | 问题 | 影响 | 处理人 | 当前状态 |
280
+ |---|---|---|---|
281
+ | | | | |
282
+ `;
283
+ }
284
+ //# sourceMappingURL=workflows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../src/workflows.ts"],"names":[],"mappings":"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"}