paseo-req-kit 0.0.0-stage → 1.8.0-beta.3

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.
Files changed (144) hide show
  1. package/CHANGELOG.md +283 -0
  2. package/LICENSE +21 -0
  3. package/README.md +146 -2
  4. package/SCOPE.md +11 -0
  5. package/bin/locate.mjs +46 -0
  6. package/bin/req-doctor.mjs +21 -0
  7. package/bin/req.mjs +179 -0
  8. package/bin/start-pipeline +21 -0
  9. package/bin/start-pipeline.mjs +22 -0
  10. package/config.example.json +132 -0
  11. package/contracts/README.md +18 -0
  12. package/contracts/feature-files.md +117 -0
  13. package/contracts/notifier-event.md +72 -0
  14. package/contracts/result-file.md +21 -0
  15. package/contracts/spec.md +36 -0
  16. package/contracts/state.md +49 -0
  17. package/contracts/verify.md +41 -0
  18. package/docs/adr/0001-step-agents-under-origin-chat.md +15 -0
  19. package/docs/adr/0002-no-directory-switch-in-chat.md +15 -0
  20. package/docs/adr/0003-script-engine-not-hub.md +15 -0
  21. package/docs/adr/0004-result-files.md +15 -0
  22. package/docs/adr/0005-no-default-branch-local-commits-only.md +15 -0
  23. package/docs/adr/0006-skill-install-targets.md +15 -0
  24. package/docs/adr/0007-own-interview-skill.md +15 -0
  25. package/docs/adr/0008-entries-do-not-call-entries.md +15 -0
  26. package/docs/adr/0009-versioned-install-layout.md +15 -0
  27. package/docs/adr/0010-generated-feature-overview.md +15 -0
  28. package/docs/adr/0011-resume-after-completion.md +15 -0
  29. package/docs/adr/0012-review-panel.md +18 -0
  30. package/docs/adr/0013-no-release-tooling.md +15 -0
  31. package/docs/adr/0014-notifier-slot.md +19 -0
  32. package/docs/adr/0015-incremental-continue.md +17 -0
  33. package/docs/adr/0016-upgrade-from-tags.md +19 -0
  34. package/docs/adr/0017-use-paseo-capabilities.md +18 -0
  35. package/docs/adr/0018-own-worktree-option.md +21 -0
  36. package/docs/adr/0019-parallel-orchestration.md +21 -0
  37. package/docs/adr/0020-scheduling-through-the-chat.md +21 -0
  38. package/docs/adr/0021-npm-version-manager.md +19 -0
  39. package/docs/adr/0022-develop-and-verify-phases.md +32 -0
  40. package/docs/adr/0023-types-gate-slices.md +54 -0
  41. package/docs/adr/0024-confirm-early-review-axes.md +27 -0
  42. package/docs/adr/0025-joint-requirements.md +27 -0
  43. package/docs/adr/README.md +29 -0
  44. package/docs/guide//344/275/277/347/224/250/350/200/205/346/214/207/345/215/227.md +96 -0
  45. package/docs/guide//345/256/211/350/243/205/344/270/216/345/215/207/347/272/247.md +348 -0
  46. package/docs/guide//347/273/264/346/212/244/350/200/205/346/214/207/345/215/227.md +85 -0
  47. package/docs/guide//351/241/271/347/233/256/345/256/232/345/210/266/344/270/216/350/277/220/350/241/214/350/247/204/345/210/231.md +356 -0
  48. package/engine/prompts/00-shared-context.md +104 -0
  49. package/engine/prompts/02-spec-review.md +46 -0
  50. package/engine/prompts/03-design.md +73 -0
  51. package/engine/prompts/03a-design-proposal.md +30 -0
  52. package/engine/prompts/04-design-review.md +73 -0
  53. package/engine/prompts/04b-design-revise.md +41 -0
  54. package/engine/prompts/05-implement.md +72 -0
  55. package/engine/prompts/06-code-review.md +70 -0
  56. package/engine/prompts/07-review-fix.md +41 -0
  57. package/engine/prompts/07b-handoff.md +45 -0
  58. package/engine/prompts/08-service-start.md +59 -0
  59. package/engine/prompts/09-verify.md +90 -0
  60. package/engine/prompts/10-defect-fix.md +41 -0
  61. package/engine/prompts/10b-reverify.md +43 -0
  62. package/engine/prompts/11-report.md +112 -0
  63. package/engine/prompts/browser-verify.md +13 -0
  64. package/engine/prompts/incremental.md +22 -0
  65. package/engine/prompts/joint.md +55 -0
  66. package/engine/prompts/panel-member.md +38 -0
  67. package/engine/prompts/paseo-services.md +9 -0
  68. package/engine/prompts/related-repos.md +7 -0
  69. package/engine/prompts/review-axis-spec.md +10 -0
  70. package/engine/prompts/review-axis-standards.md +11 -0
  71. package/engine/prompts/types/assessment.md +41 -0
  72. package/engine/prompts/types/defect.md +55 -0
  73. package/engine/prompts/types/refactor.md +39 -0
  74. package/engine/prompts/verify-deployed.md +14 -0
  75. package/engine/src/activity.ts +87 -0
  76. package/engine/src/cli-args.ts +217 -0
  77. package/engine/src/config.ts +619 -0
  78. package/engine/src/configure.ts +237 -0
  79. package/engine/src/control.ts +246 -0
  80. package/engine/src/daemon-check.ts +104 -0
  81. package/engine/src/daemon-version.ts +66 -0
  82. package/engine/src/digest.ts +142 -0
  83. package/engine/src/doctor.ts +462 -0
  84. package/engine/src/eval.ts +324 -0
  85. package/engine/src/features.ts +270 -0
  86. package/engine/src/gate.ts +157 -0
  87. package/engine/src/git.ts +30 -0
  88. package/engine/src/joint.ts +173 -0
  89. package/engine/src/launch.ts +405 -0
  90. package/engine/src/lessons.ts +72 -0
  91. package/engine/src/locations.ts +55 -0
  92. package/engine/src/main.ts +346 -0
  93. package/engine/src/messages.ts +394 -0
  94. package/engine/src/notifiers.ts +76 -0
  95. package/engine/src/notify-test.ts +101 -0
  96. package/engine/src/paseo-json.ts +73 -0
  97. package/engine/src/paseo-profiles.ts +133 -0
  98. package/engine/src/paseo-runtime.ts +437 -0
  99. package/engine/src/paths.ts +10 -0
  100. package/engine/src/pipeline.ts +1840 -0
  101. package/engine/src/playbooks.ts +46 -0
  102. package/engine/src/preflight.ts +337 -0
  103. package/engine/src/prompts.ts +72 -0
  104. package/engine/src/queue.ts +61 -0
  105. package/engine/src/runtime-loader.ts +14 -0
  106. package/engine/src/runtime.ts +155 -0
  107. package/engine/src/schedule-time.ts +51 -0
  108. package/engine/src/smoke-test.ts +202 -0
  109. package/engine/src/spec-review.ts +100 -0
  110. package/engine/src/state.ts +333 -0
  111. package/engine/src/steps.ts +266 -0
  112. package/engine/src/usage.ts +67 -0
  113. package/engine/src/worktree.ts +72 -0
  114. package/install.mjs +928 -0
  115. package/notifiers/im-template.mjs +60 -0
  116. package/package.json +67 -4
  117. package/principles/INDEX.md +11 -0
  118. package/skills/acceptance-criteria/SKILL.md +61 -0
  119. package/skills/principle-delete-before-add/SKILL.md +33 -0
  120. package/skills/principle-dont-block-on-humans/SKILL.md +35 -0
  121. package/skills/principle-fix-root-cause/SKILL.md +33 -0
  122. package/skills/principle-prove-it-works/SKILL.md +33 -0
  123. package/skills/principle-report-honestly/SKILL.md +33 -0
  124. package/skills/principle-speak-to-reader/SKILL.md +33 -0
  125. package/skills/principle-this-requirement-only/SKILL.md +33 -0
  126. package/skills/req/SKILL.md +101 -0
  127. package/skills/req/playbooks/accept.md +65 -0
  128. package/skills/req/playbooks/change.md +51 -0
  129. package/skills/req/playbooks/incident.md +55 -0
  130. package/skills/req/playbooks/new.md +94 -0
  131. package/skills/req/playbooks/small.md +48 -0
  132. package/skills/req/playbooks/status.md +41 -0
  133. package/skills/req/playbooks/takeover.md +51 -0
  134. package/skills/req/playbooks/verify.md +57 -0
  135. package/skills/req-doctor/SKILL.md +36 -0
  136. package/skills/req-retro/SKILL.md +81 -0
  137. package/skills/req-setup/SKILL.md +118 -0
  138. package/skills/req-setup/templates/paseo/copy-local-files.mjs +32 -0
  139. package/skills/req-setup/templates/paseo/with-port.mjs +36 -0
  140. package/skills/requirement-interview/SKILL.md +97 -0
  141. package/skills/requirement-kickoff/SKILL.md +17 -0
  142. package/skills/result-report/SKILL.md +34 -0
  143. package/skills/spec-writing/SKILL.md +55 -0
  144. package/skills/spec-writing/spec-template.md +109 -0
package/bin/req.mjs ADDED
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env node
2
+ // The `req` command: short names for the things people do in a terminal.
3
+ // install.mjs writes ~/.req-kit/bin/req (and req.cmd on Windows) pointing here.
4
+ // Everything it does is also available through the full commands it prints in `req help`.
5
+ import { spawnSync } from "node:child_process";
6
+ import fs from "node:fs";
7
+ import os from "node:os";
8
+ import path from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+ import { findTsxCli, layoutOf } from "./locate.mjs";
11
+
12
+ const kitRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
13
+ const version = JSON.parse(fs.readFileSync(path.join(kitRoot, "package.json"), "utf8")).version;
14
+ const tsxCli = findTsxCli(kitRoot) ?? path.join(kitRoot, "node_modules", "tsx", "dist", "cli.mjs");
15
+ const launcher = path.join(kitRoot, "bin", "start-pipeline.mjs");
16
+
17
+ const HELP = `req-kit ${version}(${kitRoot})
18
+
19
+ 在项目目录(或它的工作区)中运行:
20
+ req list 列出这个项目的所有需求和阶段
21
+ req status [需求] 查看进度;只有一个需求运行过时可以不写
22
+ req stop <需求> 停止流水线(之后可以继续)
23
+ req resume <需求> 从上次中断处继续;需求改过时只处理变化的部分
24
+ req approve <需求> 需求方确认了方案(方案确认点,见 preview.md),继续开发
25
+ req verify <需求> [--verify-env local|deployed] [--defects fix|handback|report]
26
+ 研发完成后开始测试验证(分阶段执行时)
27
+ req start <需求> [--profile quick|standard] [--phases gated] [--at 22:00]
28
+ 启动流水线(通常由 /req 在对话中启动,这里用于终端中手工启动)
29
+ req digest [--notify] 项目的需求总览;--notify 同时发到外部通知(如企业 IM)
30
+ req digest --schedule "0 9 * * 1"
31
+ 让 Paseo 按时间表发送需求总览(例子为每周一 9:00);取消:req digest --cancel <ID>
32
+
33
+ 本机维护:
34
+ req doctor [--no-project] 体检:安装、配置、daemon、当前项目
35
+ req configure 配置向导:选择 builder 和 reviewer 用的 agent
36
+ req upgrade [版本] [--beta] 升级到最新版本(或指定版本),自动选能支持本机 Paseo 的版本;
37
+ req upgrade --check 只看有没有新版本
38
+ req versions 已安装的版本和 npm 上的版本
39
+ req use <版本> 切换到已安装的另一个版本(回滚)
40
+ req check 检查安装状态
41
+ req notify-test [--type blocked|failed|completed|milestone|permission]
42
+ 给配置的外部通知(如企业 IM)发一条测试消息
43
+ req version 显示版本和安装位置
44
+
45
+ <需求> 可以写功能目录(docs/features/20261012-sms-login)、目录名,或名称中能唯一确定的一部分(sms-login)。
46
+ 在对话中的用法见 /req;完整说明见 ${path.join(kitRoot, "docs", "guide")}。`;
47
+
48
+ function readJson(file) {
49
+ try {
50
+ return JSON.parse(fs.readFileSync(file, "utf8"));
51
+ } catch {
52
+ return null;
53
+ }
54
+ }
55
+
56
+ function node(args) {
57
+ const result = spawnSync(process.execPath, args, { stdio: "inherit", windowsHide: true });
58
+ if (result.error) {
59
+ console.error(result.error.message);
60
+ return 1;
61
+ }
62
+ return result.status ?? 1;
63
+ }
64
+
65
+ function needTsx() {
66
+ if (fs.existsSync(tsxCli)) return true;
67
+ console.error(`依赖未安装:在 ${kitRoot} 中执行 npm install,然后运行 node install.mjs`);
68
+ return false;
69
+ }
70
+
71
+ /** Takes the first argument as the requirement, unless it is an option. */
72
+ function feature(rest, required) {
73
+ if (rest[0] && !rest[0].startsWith("-")) return ["--feature", rest[0], ...rest.slice(1)];
74
+ if (required) {
75
+ console.error(`请写出是哪个需求,例如:req ${command} sms-login(用 req list 查看全部需求)`);
76
+ process.exit(2);
77
+ }
78
+ return rest;
79
+ }
80
+
81
+ const [command = "help", ...rest] = process.argv.slice(2);
82
+ const installer = path.join(kitRoot, "install.mjs");
83
+ const MANAGED = { setup: ["--setup"], upgrade: ["--upgrade"], use: ["--use"], versions: ["--versions"] };
84
+
85
+ // Installed with `npm i -g`: this copy manages the versions under ~/tools/req-kit/versions
86
+ // and hands every other command to the version in use.
87
+ if (layoutOf(kitRoot).kind === "manager") {
88
+ if (command in MANAGED) {
89
+ const flags = command === "upgrade" && rest.includes("--check") ? ["--latest"] : MANAGED[command];
90
+ process.exit(node([installer, ...flags, ...rest.filter((a) => a !== "--check")]));
91
+ }
92
+ const kitHome = process.env.REQ_KIT_HOME?.trim() ? path.resolve(process.env.REQ_KIT_HOME.trim()) : path.join(os.homedir(), ".req-kit");
93
+ const active = readJson(path.join(kitHome, "active.json"));
94
+ const activeReq = active?.root ? path.join(active.root, "bin", "req.mjs") : null;
95
+ if (command === "version" || command === "--version" || command === "-v") {
96
+ console.log(`req-kit 管理器 ${version}(${kitRoot})`);
97
+ console.log(active ? `当前启用的版本:${active.version}(${active.root})` : "还没有启用任何版本:运行 req setup");
98
+ process.exit(0);
99
+ }
100
+ if (!activeReq || !fs.existsSync(activeReq)) {
101
+ if (["help", "--help", "-h"].includes(command)) {
102
+ console.log(`req-kit 管理器 ${version}\n\n还没有安装任何版本。先运行:req setup\n\n其他命令:req versions、req upgrade、req use <版本>`);
103
+ process.exit(0);
104
+ }
105
+ console.error(active ? `当前启用的版本 ${active.version} 不在了(${active.root})。运行 req versions 查看已安装的版本,再 req use <版本>。` : "还没有安装任何 req-kit 版本。先运行:req setup");
106
+ process.exit(1);
107
+ }
108
+ process.exit(node([activeReq, command, ...rest]));
109
+ }
110
+
111
+ let code;
112
+ switch (command) {
113
+ case "list":
114
+ case "ls":
115
+ code = node([launcher, "--list", ...rest]);
116
+ break;
117
+ case "status":
118
+ case "st":
119
+ code = node([launcher, "--status", ...feature(rest, false)]);
120
+ break;
121
+ case "stop":
122
+ code = node([launcher, "--stop", ...feature(rest, true)]);
123
+ break;
124
+ case "resume":
125
+ code = node([launcher, "--resume", ...feature(rest, true)]);
126
+ break;
127
+ case "verify":
128
+ code = node([launcher, "--phase", "verify", ...feature(rest, true)]);
129
+ break;
130
+ case "approve":
131
+ code = node([launcher, "--approve", ...feature(rest, true)]);
132
+ break;
133
+ case "start":
134
+ code = node([launcher, ...feature(rest, true)]);
135
+ break;
136
+ case "doctor":
137
+ code = node([path.join(kitRoot, "bin", "req-doctor.mjs"), ...rest]);
138
+ break;
139
+ case "configure":
140
+ case "config":
141
+ code = node([path.join(kitRoot, "install.mjs"), "--configure", ...rest]);
142
+ break;
143
+ case "upgrade":
144
+ code = rest.includes("--check")
145
+ ? node([path.join(kitRoot, "install.mjs"), "--latest", ...rest.filter((a) => a !== "--check")])
146
+ : node([path.join(kitRoot, "install.mjs"), "--upgrade", ...rest]);
147
+ break;
148
+ case "setup":
149
+ case "use":
150
+ case "versions":
151
+ code = node([installer, ...MANAGED[command], ...rest]);
152
+ break;
153
+ case "check":
154
+ code = node([path.join(kitRoot, "install.mjs"), "--check", ...rest]);
155
+ break;
156
+ case "digest":
157
+ code = needTsx() ? node([tsxCli, path.join(kitRoot, "engine", "src", "digest.ts"), ...rest]) : 1;
158
+ break;
159
+ case "notify-test":
160
+ code = needTsx() ? node([tsxCli, path.join(kitRoot, "engine", "src", "notify-test.ts"), ...rest]) : 1;
161
+ break;
162
+ case "version":
163
+ case "--version":
164
+ case "-v":
165
+ console.log(`req-kit ${version}(${kitRoot})`);
166
+ code = 0;
167
+ break;
168
+ case "help":
169
+ case "--help":
170
+ case "-h":
171
+ console.log(HELP);
172
+ code = 0;
173
+ break;
174
+ default:
175
+ console.error(`没有 "${command}" 这个命令。\n`);
176
+ console.error(HELP);
177
+ code = 2;
178
+ }
179
+ process.exit(code);
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+ # Starts the requirement pipeline in the background and returns immediately.
3
+ # Same as bin/start-pipeline.mjs, for bash users. The skill uses the .mjs launcher,
4
+ # which also works from PowerShell and cmd.
5
+ set -euo pipefail
6
+ SOURCE="${BASH_SOURCE[0]}"
7
+ while [ -L "$SOURCE" ]; do
8
+ DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
9
+ SOURCE="$(readlink "$SOURCE")"
10
+ [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE"
11
+ done
12
+ TOOL_DIR="$(cd -P "$(dirname "$SOURCE")/.." && pwd)"
13
+ TSX="$TOOL_DIR/node_modules/.bin/tsx"
14
+ if [ ! -x "$TSX" ]; then
15
+ TSX="$(command -v tsx || true)"
16
+ fi
17
+ if [ -z "$TSX" ]; then
18
+ echo "未启动:找不到 tsx。请先在 $TOOL_DIR 中执行 npm install。" >&2
19
+ exit 2
20
+ fi
21
+ exec "$TSX" "$TOOL_DIR/engine/src/launch.ts" "$@"
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ // Shell-independent launcher: works the same from bash, PowerShell and cmd, so any
3
+ // Paseo chat agent (Claude Code, Codex, ...) can run it with plain `node "<path>" ...`.
4
+ // Inside a Paseo chat it reads the chat's agent ID and working directory from the
5
+ // environment Paseo provides (PASEO_AGENT_ID, PASEO_AGENT_CWD).
6
+ import { spawnSync } from "node:child_process";
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+ import { findTsxCli } from "./locate.mjs";
11
+
12
+ const toolDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
13
+ const tsxCli = findTsxCli(toolDir) ?? path.join(toolDir, "node_modules", "tsx", "dist", "cli.mjs");
14
+ if (!fs.existsSync(tsxCli)) {
15
+ console.error(`未启动:找不到 tsx。请先在 ${toolDir} 中执行 npm install。`);
16
+ process.exit(2);
17
+ }
18
+ const result = spawnSync(process.execPath, [tsxCli, path.join(toolDir, "engine", "src", "launch.ts"), ...process.argv.slice(2)], {
19
+ stdio: "inherit",
20
+ windowsHide: true,
21
+ });
22
+ process.exit(result.status ?? 1);
@@ -0,0 +1,132 @@
1
+ {
2
+ "daemonUrl": "ws://127.0.0.1:6767/ws",
3
+ "daemonPasswordEnv": "PASEO_DAEMON_PASSWORD",
4
+ "teamConfig": null,
5
+ "agents": {
6
+ "builder": {
7
+ "provider": "claude/CHANGE-ME",
8
+ "modeId": "bypassPermissions"
9
+ },
10
+ "reviewer": {
11
+ "provider": "codex/CHANGE-ME",
12
+ "modeId": "full-access"
13
+ }
14
+ },
15
+ "defaultProfile": "standard",
16
+ "profiles": {
17
+ "quick": {
18
+ "rounds": {
19
+ "designReview": 1,
20
+ "codeReview": 1,
21
+ "defectFix": 1
22
+ },
23
+ "serviceStart": false
24
+ },
25
+ "standard": {
26
+ "rounds": {
27
+ "designReview": 2,
28
+ "codeReview": 3,
29
+ "defectFix": 3
30
+ },
31
+ "serviceStart": true
32
+ }
33
+ },
34
+ "notifyMilestones": true,
35
+ "notifiers": [],
36
+ "stepTimeoutMinutes": {
37
+ "design": 60,
38
+ "design_review": 30,
39
+ "design_revise": 30,
40
+ "implement": 240,
41
+ "code_review": 45,
42
+ "review_fix": 90,
43
+ "service_start": 30,
44
+ "verify": 120,
45
+ "defect_fix": 120,
46
+ "reverify": 90,
47
+ "report": 30,
48
+ "panel_review": 45,
49
+ "spec_review": 20,
50
+ "design_proposal": 45,
51
+ "handoff": 30
52
+ },
53
+ "waitChunkSeconds": 600,
54
+ "permissionPollSeconds": 30,
55
+ "resultFollowUps": 2,
56
+ "attachToOriginChat": true,
57
+ "archiveStepAgents": false,
58
+ "retry": {
59
+ "attempts": 2,
60
+ "backoffSeconds": [
61
+ 60,
62
+ 300
63
+ ]
64
+ },
65
+ "paseoServices": "auto",
66
+ "serviceReadySeconds": 120,
67
+ "quotaWarnPercent": 85,
68
+ "specReview": "standard",
69
+ "designProposals": {
70
+ "enabled": false,
71
+ "profiles": [
72
+ "standard"
73
+ ],
74
+ "members": []
75
+ },
76
+ "browserVerify": "auto",
77
+ "reviewPanel": {
78
+ "enabled": false,
79
+ "steps": [
80
+ "design_review",
81
+ "code_review"
82
+ ],
83
+ "profiles": [
84
+ "standard"
85
+ ],
86
+ "members": []
87
+ },
88
+ "maxConcurrentPipelines": 0,
89
+ "waitingReminderHours": 24,
90
+ "autoResumeMinutes": 30,
91
+ "autoResumeMax": 2,
92
+ "watchdogMinutes": 0,
93
+ "phases": {
94
+ "mode": "continuous",
95
+ "verify": {
96
+ "environment": "local",
97
+ "agents": {},
98
+ "defects": "fix",
99
+ "serviceStart": null
100
+ }
101
+ },
102
+ "requirementTypes": [
103
+ "defect",
104
+ "refactor",
105
+ "assessment"
106
+ ],
107
+ "checks": [],
108
+ "qualityGate": {
109
+ "fixAttempts": 2,
110
+ "timeoutMinutes": 20
111
+ },
112
+ "slices": {
113
+ "profiles": [
114
+ "standard"
115
+ ],
116
+ "max": 6
117
+ },
118
+ "relatedRepos": [],
119
+ "designApproval": {
120
+ "mode": "ui",
121
+ "profiles": [
122
+ "standard"
123
+ ],
124
+ "autoContinueHours": 0
125
+ },
126
+ "reviewAxes": {
127
+ "enabled": true,
128
+ "profiles": [
129
+ "standard"
130
+ ]
131
+ }
132
+ }
@@ -0,0 +1,18 @@
1
+ # 文件格式约定
2
+
3
+ 这些文件同时被聊天中的 skill、流水线引擎和步骤 agent 读写。改动格式时,同时更新这里、相关代码和测试,并在 `CHANGELOG.md` 的"升级须知"中说明。
4
+
5
+ | 文件 | 约定 | 格式版本 |
6
+ | --- | --- | --- |
7
+ | `docs/features/<目录>/spec.md` | [spec.md](spec.md) | `req-kit/spec@1` |
8
+ | `docs/features/<目录>/.pipeline/state.json` | [state.md](state.md) | `version: 1` |
9
+ | `docs/features/<目录>/.pipeline/results/<步骤>.json` | [result-file.md](result-file.md) | 按步骤固定字段 |
10
+ | `decisions.tsv`、`changes.md`、`acceptance.md` 与需求总览 | [feature-files.md](feature-files.md) | 见各文件说明 |
11
+ | `.requirement-pipeline/verify.md` | [verify.md](verify.md) | 自由格式,建议结构见文件 |
12
+ | 外部通知(企业 IM 等)收到的事件 | [notifier-event.md](notifier-event.md) | `schema: 1` |
13
+
14
+ 格式版本的规则:
15
+
16
+ - 同一主版本内只做可以自动迁移的变更。
17
+ - 引擎读到旧版本的状态文件时自动迁移,原文件保留为 `state.json.bak-v<旧版本>`。
18
+ - 读到比自己新的版本时拒绝运行,提示升级 req-kit 或恢复备份。
@@ -0,0 +1,117 @@
1
+ # 功能目录中由人和 /req 维护的文件
2
+
3
+ 除 spec.md(见 [spec.md](spec.md))外,功能目录 `docs/features/<日期>-<名称>/` 中还有以下约定格式的文件。
4
+
5
+ ## decisions.tsv
6
+
7
+ 决策记录,由流水线各步骤追加。制表符分隔,UTF-8,第一行为表头:
8
+
9
+ ```text
10
+ time step ref decision alternatives reason kind needs_human
11
+ ```
12
+
13
+ | 列 | 内容 |
14
+ | --- | --- |
15
+ | `time` | `YYYY-MM-DD HH:MM` |
16
+ | `step` | 步骤名和轮次,如 `代码评审 第2轮` |
17
+ | `ref` | 相关的 FR / AC / CR 编号或文件,没有写 `-` |
18
+ | `decision` / `alternatives` / `reason` | 各一句话,不含换行和制表符 |
19
+ | `kind` | `假设` / `取舍` / `偏离方案` / `驳回意见` / `不修复` |
20
+ | `needs_human` | `yes` / `no`。`yes` 的行会被完成报告列入"需要你确认的决定" |
21
+
22
+ ## changes.md
23
+
24
+ 需求变更记录,由 `/req` 的"修改需求"手册追加,每次修改一节,新的在后:
25
+
26
+ ```markdown
27
+ ## 第 2 版(2026-10-14)
28
+
29
+ - 变更内容:<改了哪些 FR / AC,新增或删除了什么>
30
+ - 原因:<需求方给出的原因>
31
+ - 对进度的影响:<流水线当时的状态;继续后从方案设计重新开始 / 尚未开始开发>
32
+ - 提出人:<姓名或角色>
33
+ ```
34
+
35
+ spec.md 头部的"版本"与最新一节一致。
36
+
37
+ ## handoff.md(提测说明)
38
+
39
+ 1.7.0 起由流水线研发阶段的最后一步("提测说明")写入并提交。分阶段执行时它是交给测试的单据,连续执行时是功能验证的输入,"只做研发"时是人工测试的依据。六节:这次改了什么(按 FR,附分支和提交范围)、怎么跑起来、自测结果、建议重点测试、已知问题和未完成项、测试需要的准备(只写在哪里取,不写口令)。测试退回后修复时追加"第 N 次提测"一节。
40
+
41
+ ## test-env.md(测试环境说明)
42
+
43
+ 1.7.0 起。在已部署的测试环境中做测试验证(`--verify-env deployed` 或配置 `phases.verify.environment`)时必须有,由 `/req` 的"开始测试验证"手册和用户一起写。流水线只使用其中列出的环境、账号和数据:
44
+
45
+ ```markdown
46
+ # 测试环境:<需求名称>
47
+
48
+ - 地址:https://<测试环境地址>
49
+ - 被测版本怎么确认:<版本号接口 / 页面底部的提交号 / 部署平台上的记录>
50
+ - 账号:<测试账号>,口令在 <环境变量 TEST_PASSWORD / 本机文件 ~/.config/xxx>(不写口令本身)
51
+ - 可以使用的测试数据:<数据范围、可以新建和删除的数据>
52
+ - 不能碰的:<共享数据、会触发外部通知的操作等>
53
+ - 清理方式:<测试数据如何清理>
54
+ ```
55
+
56
+ 只能是测试用途的环境;不写任何生产环境的地址和凭据。
57
+
58
+ ## changes.md 中的"测试验证退回"
59
+
60
+ 1.7.0 起,测试验证按 `defects: handback` 把缺陷退回研发阶段时,流水线在 `changes.md` 末尾追加一节"<日期> 测试验证退回(第 N 次)",来源为"测试验证",缺陷清单在 `verification.md` 最后一轮。研发阶段随后从方案设计开始只处理这些缺陷。
61
+
62
+ ## preview.md 与 prototype/(给需求方确认的预览)
63
+
64
+ 1.8.0 起,方案确认点开启时(`designApproval`,默认标准档的界面改动)由方案设计写入,方案修订时同步更新。`preview.md` 五节:做完后你会看到什么(按操作顺序,注明 AC)、界面原型(列出 `prototype/` 中的文件和对应的状态)、接口示例(改接口时)、需要你确认的假设(影响界面、数据、权限的)、不会变的。`prototype/` 中是静态 HTML 页面,只用内联的 HTML 和 CSS,不引用外部文件、不连接服务,只用于确认,不是产品代码。需求方确认后,实现和功能验证都以它们为准。
65
+
66
+ ## diagnosis.md、assessment.md
67
+
68
+ 1.8.0 起。缺陷类型的"复现与定位"写 `diagnosis.md`:现象与复现(复现测试或脚本的位置、命令、修复前的失败输出)、根因(带代码位置)、排除的其他原因、影响面、修复思路。评估类型的"调研评估"写 `assessment.md`(代替 `design.md`):结论摘要、现状、可选方案(含工作量的大小和主要工作项)、推荐、风险与未知、如果要做(需求草稿)。
69
+
70
+ ## contract.md(联合需求的接口约定)
71
+
72
+ 1.8.0 起,联合需求(spec 的 `- 联合开发:`)的方案设计在主仓库写入:每个接口一节,路径和方法、请求字段(类型、是否必填、取值范围)、响应字段、错误码和提示、一两组真实的请求和响应示例。方案审核通过后冻结,各仓库按它同时开发:提供接口的一边用示例写接口测试,调用的一边用示例做测试替身。主仓库的需求说明、访谈记录、方案、接口约定和预览在实现前同步到其他仓库工作区的同名功能目录并提交;其他仓库的实现、评审和缺陷处理记录写在它们自己的功能目录中。
73
+
74
+ ## lessons.tsv(可以变成规则的问题)
75
+
76
+ 1.8.0 起,完成报告从评审意见、质量门和缺陷中挑出一条项目规则就能挡住的问题写入,没有就不写。制表符分隔,UTF-8,第一行为表头:
77
+
78
+ ```text
79
+ category finding source rule layer
80
+ ```
81
+
82
+ | 列 | 内容 |
83
+ | --- | --- |
84
+ | `category` | 问题的类别,两到六个字,如"SQL 拼接"。同类问题在各个需求中沿用同一个名字 |
85
+ | `finding` | 这次的问题,一句话 |
86
+ | `source` | 出处,如 `CR-3`、`缺陷 D-2`、`质量门 lint` |
87
+ | `rule` | 建议的规则,一句话 |
88
+ | `layer` | `lint` / `类型` / `测试` / `项目说明` |
89
+
90
+ `req digest` 把在两个以上需求中出现的类别列为"反复出现的问题"。已经变成规则(或决定不做)的类别写在仓库的 `.requirement-pipeline/lessons-handled.txt` 中,一行一个,`#` 之后是注释,总览不再提示它们。
91
+
92
+ ## acceptance.md
93
+
94
+ 验收记录,由 `/req` 的"验收"手册写。验收标准本身只在 spec.md 中维护,这里只记录结果:
95
+
96
+ ```markdown
97
+ # 验收记录:<需求名称>
98
+
99
+ - 验收结论:通过(2026-10-15) / 不通过(2026-10-15) / 进行中
100
+ - 验收人:<姓名或角色>
101
+ - 对照的需求版本:2
102
+ - 对照的报告:report.md(流水线结论:已完成,可以验收)
103
+
104
+ | AC | 结果 | 怎么验证的 | 备注 |
105
+ | --- | --- | --- | --- |
106
+ | AC-1.1 | 通过 / 不通过 / 未验 | <亲自操作 / 执行的命令> | <现象、截图路径> |
107
+
108
+ ## 不通过的处理
109
+
110
+ - AC-2.3:<现象> → 作为缺陷处理 / 作为需求修改 / 接受现状(理由)
111
+ ```
112
+
113
+ `start-pipeline --list` 读取"验收结论"一行来显示"已验收"或"验收未通过"。
114
+
115
+ ## 需求总览
116
+
117
+ 需求总览不是一个提交进仓库的文件。每个需求在自己的工作区和分支上,共用的索引文件会在合并时冲突,所以总览由 `start-pipeline --list` 现场生成:扫描这个仓库所有 worktree 中的 `docs/features/*/spec.md`、状态文件和验收记录。
@@ -0,0 +1,72 @@
1
+ # 外部通知事件(notifier)
2
+
3
+ 流水线除了把消息发回发起的对话,还可以在关键时刻调用本机的通知模块,例如把消息转发到企业内部 IM。req-kit 只定义调用方式和事件格式,不包含任何 IM 的实现;模板见 [notifiers/im-template.mjs](../notifiers/im-template.mjs)。
4
+
5
+ ## 配置
6
+
7
+ 只能写在本机配置(`~/.req-kit/config.json`)或团队配置中,项目配置中的 `notifiers` 会被忽略(项目仓库里的代码不应该决定往哪里发消息)。
8
+
9
+ ```json
10
+ "notifiers": [
11
+ {
12
+ "module": "~/.req-kit/notifiers/im.mjs",
13
+ "events": ["blocked", "failed", "completed"],
14
+ "options": { "webhook": "https://im.example.internal/hook/xxx", "tokenEnv": "IM_TOKEN" }
15
+ }
16
+ ]
17
+ ```
18
+
19
+ | 字段 | 说明 |
20
+ | --- | --- |
21
+ | `module` | 通知模块的路径。相对路径相对于声明它的配置文件;`~/` 表示用户目录。 |
22
+ | `events` | 要接收的事件类型,省略时接收全部(包括以后新增的类型)。 |
23
+ | `options` | 原样传给模块的第二个参数。密钥不要直接写在这里,写环境变量的名字,由模块读取。 |
24
+
25
+ ## 模块
26
+
27
+ ES 模块,默认导出(或导出名为 `notify` 的)函数:
28
+
29
+ ```js
30
+ export default async function notify(event, options) { /* 发送 */ }
31
+ ```
32
+
33
+ - 每个事件调用一次,可以返回 Promise。超过 15 秒没有完成按失败处理。
34
+ - 抛出的错误和超时只记入流水线日志("外部通知失败……不影响流水线"),不会让流水线停下或重试。
35
+ - 模块在一次流水线运行中只加载一次;修改模块后,对之后启动或继续的流水线生效。
36
+ - 测试:`req notify-test [--type blocked|failed|completed|milestone|permission|phase_done|approval|digest]` 发一条带"【测试】"字样的示例事件,不需要运行流水线。
37
+
38
+ ## 事件格式(schema 1)
39
+
40
+ ```json
41
+ {
42
+ "schema": 1,
43
+ "type": "blocked",
44
+ "at": "2026-10-13T08:30:00.000Z",
45
+ "kitVersion": "1.3.0-beta.1",
46
+ "feature": { "dir": "docs/features/20261012-sms-login", "name": "20261012-sms-login", "title": "短信验证码登录" },
47
+ "repo": "D:\\work\\shop",
48
+ "branch": "feature/20261012-sms-login",
49
+ "profile": "standard",
50
+ "originAgentId": "agent-id 或 null",
51
+ "text": "方案审核发现 1 个需要需求方决定的问题,流水线已暂停,请到发起的对话中回答。",
52
+ "details": { "questions": ["……"], "resumeCommand": "node \"…/start-pipeline.mjs\" … --resume" }
53
+ }
54
+ ```
55
+
56
+ `text` 是一两句可以直接发出的话;需要自己排版时用 `details`。
57
+
58
+ | type | 什么时候 | details |
59
+ | --- | --- | --- |
60
+ | `milestone` | 方案确定、开始验证、开始修复缺陷(配置 `notifyMilestones` 为 true 时,每次尝试各一次) | `milestone`:`design-settled`、`code-reviewed`、`fixing-defects`、`handback-<n>`(1.7.0 起,测试验证第 n 次把缺陷退回研发) |
61
+ | `blocked` | 方案审核发现需要需求方决定的问题,流水线已暂停 | `questions`(字符串数组)、`resumeCommand` |
62
+ | `permission` | 步骤 agent 在等待权限批准 | `stepTitle`、`agentTitle`、`requests`(字符串数组) |
63
+ | `failed` | 流水线因错误中断(已自动重试过的临时错误除外) | `stepTitle`、`reason`、`logPath`、`resumeCommand` |
64
+ | `completed` | 流水线结束,报告已生成 | `outcome`(`completed`、`completed_with_issues`、`not_completed`)、`summary`、`reportPath`。"只做研发"时另有 `mode`(`develop-only`)和 `handoffPath`,报告是研发报告,需要人工测试 |
65
+ | `approval` | 1.8.0 起。方案确认点(`designApproval`):方案已通过审核,等待需求方确认"做完后会看到什么",还没有开始写代码 | `previewPath`(要确认的内容)、`approveCommand`(确认后继续的命令)、`resumeCommand`(修改需求后继续的命令),都在发起的对话中执行 |
66
+ | `phase_done` | 1.7.0 起。分阶段执行时研发阶段已完成(代码已通过评审、提测说明已写好),流水线停在闸口等待测试验证。测试退回后再次修完也会发 | `handoffPath`(提测说明)、`mode`(`gated`)、`verifyCommand`(开始测试验证的命令,在发起的对话中执行)、`verifyAt`(预约的开始时间,ISO 格式,没有为 null)、`handbacks`(已退回的次数) |
67
+ | `digest` | `req digest --notify`(或由 `req digest --schedule` 创建的 Paseo 定时任务)发送项目的需求总览,1.6.0 起。`feature.title` 为"<项目> 需求总览",`text` 是完整的多行总览 | `features`:每个需求的 `name`、`title`、`stage`、`branch`、`updatedAt`、`usage`;`recurringLessons`(1.8.0 起):在两个以上需求的 `lessons.tsv` 中出现的问题类别,每项 `category`、`features`、`rules` |
68
+
69
+ ## 兼容性
70
+
71
+ - 同一 `schema` 内只增加字段,不删除、不改含义;模块应忽略不认识的字段和事件类型。
72
+ - 不兼容的变化会提升 `schema`,并在 `CHANGELOG.md` 的"升级须知"中说明。
@@ -0,0 +1,21 @@
1
+ # 步骤结果文件
2
+
3
+ 每个步骤结束时写一个 JSON 对象到 `.pipeline/results/<步骤键>.json`(路径在提示词的 `<pipeline-context>` 中给出)。引擎只根据它决定下一步,不读 agent 的回复文字。缺失或格式不对时,引擎会在同一个会话里提醒补写,最多 `resultFollowUps` 次(默认 2),仍不对则判定该步骤失败。
4
+
5
+ | 步骤 ID | 字段 |
6
+ | --- | --- |
7
+ | `design` | `has_runnable_service`: boolean。可选(1.8 起):`slices`: 字符串数组(实施计划的切片,按实现顺序;两片以上时按片逐个实现);`files`: 字符串数组(预计改动的文件和目录,目录以 `/` 结尾,可用 `*`,用于范围检查);缺陷类型的 `reproduced`: boolean,为 `false` 时 `questions`: 非空字符串数组(需要需求方补充的信息);`ui_change`: boolean(改动是否改变使用者看到的界面或操作方式,方案确认点按它决定是否停下) |
8
+ | `design_review` | `verdict`: `approved` \| `changes_required` \| `blocked`;为 `blocked` 时 `questions`: 非空字符串数组 |
9
+ | `design_revise` | `status`: `done` \| `partial`。可选(1.8 起):`slices`、`files`、`ui_change`,修订改变了它们时写新的值 |
10
+ | `implement` | `status`: `done` \| `partial`。按切片实现时,每片的键为 `implement-s<序号>`。可选(1.8 起):`acceptance_tests`: 字符串数组(从验收标准的例子写出、先单独提交的测试文件),`acceptance_tests_commit`: string(那次提交);代码评审前引擎核对它们之后有没有被改过 |
11
+ | `review_fix`、`defect_fix` | `status`: `done` \| `partial` |
12
+ | `code_review` | `verdict`: `pass` \| `changes_required` |
13
+ | `service_start` | `started`: boolean |
14
+ | `verify` | `result`: `pass` \| `defects_found` \| `blocked`。可选(1.8 起,联合需求):`defect_repos`: 字符串数组,缺陷所在的仓库(`本仓库` 或 `relatedRepos` 中的名称);没有时每个仓库都做一轮缺陷修复 |
15
+ | `reverify` | `result`: `pass` \| `defects_remaining`。可选:`defect_repos`,同上 |
16
+ | `report` | `outcome`: `completed` \| `completed_with_issues` \| `not_completed`;`summary`: string |
17
+ | `panel_review`(评审小组成员,键为 `<评审步骤>-r<轮次>-p<序号>`) | `status`: `done` \| `partial`;意见写在 `<功能目录>/review-panel/<键>.md` |
18
+
19
+ 联合需求中,其他仓库的步骤的键带 `@<仓库后缀>`(如 `implement@backend`、`code_review-r2@backend`),结果文件写在那个仓库工作区的功能目录中。
20
+
21
+ 字段定义以 `engine/src/steps.ts` 为准;改动时同步更新各步骤提示词末尾的"结果文件"一节。
@@ -0,0 +1,36 @@
1
+ # spec.md
2
+
3
+ 需求说明,由 `/req`(`spec-writing` skill)按模板 `skills/spec-writing/spec-template.md` 写成,需求方确认后交给流水线。
4
+
5
+ ## 头部
6
+
7
+ ```markdown
8
+ # <需求名称>
9
+
10
+ - 状态:已确认(2026-10-12)
11
+ - 档位:标准
12
+ - 执行方式:连续
13
+ - 类型:新需求
14
+ - 版本:1
15
+ - 格式:req-kit/spec@1
16
+ ```
17
+
18
+ | 行 | 谁读 | 规则 |
19
+ | --- | --- | --- |
20
+ | `- 状态:` | 引擎 | 以"已确认"开头才能启动流水线。正则:`^\s*-\s*状态\s*[::]\s*已确认` |
21
+ | `- 档位:` | 引擎 | "快速"或"标准"(也接受 `quick` / `standard`)。没有时用配置中的 `defaultProfile` |
22
+ | `- 执行方式:` | 引擎 | "连续"、"分阶段"或"只做研发"(也接受 `continuous` / `gated` / `develop-only`)。可以没有;没有时用配置中的 `phases.mode`,启动参数 `--phases` 优先(1.7 起) |
23
+ | `- 类型:` | 引擎(1.8 起)、`/req` | 新需求 / 小改动 / 缺陷 / 重构 / 评估(也接受 `defect`、`bug`、`refactor`、`assessment`;"技术改进"同重构,"调研"同评估)。缺陷、重构、评估按各自的做法运行(`engine/prompts/types/`),配置 `requirementTypes` 可以关掉某个类型;其他写法按新需求处理 |
24
+ | `- 联合开发:` | 引擎(1.8 起) | 这个需求还要改的其他仓库,写项目配置 `relatedRepos` 中的名称,最多两个,用顿号分开。可以没有。见 ADR 0025 |
25
+ | `- 版本:` | `/req` | 从 1 开始,每次修改需求加 1 |
26
+ | `- 格式:` | `/req`、引擎(将来) | `req-kit/spec@<n>`。没有这一行的旧 spec 按 `req-kit/spec@1` 处理 |
27
+
28
+ ## 正文中被引用的编号
29
+
30
+ - 功能需求 `FR-<n>`,验收标准 `AC-<n>.<m>`,规则 `BR-<n>`,假设 `A-<n>`。
31
+ - 每条验收标准至少带一组具体的输入和期望输出(1.8 起由 `acceptance-criteria`、需求说明审阅检查);方案的测试直接用这些例子作为期望值。
32
+ - 流水线各步骤和最终报告按这些编号引用,编号一旦确认就不要重排;删除的需求保留编号并注明"已取消"。
33
+
34
+ ## 变更
35
+
36
+ - spec 的内容哈希记录在状态文件中。spec 在流水线中断后被修改,续跑时从方案设计重新开始。