paseo-req-kit 1.13.0 → 1.14.0-beta.2

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 (106) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/contracts/cli-json.md +4 -4
  3. package/contracts/usage-record.md +5 -1
  4. package/docs/guide//344/275/277/347/224/250/350/200/205/346/214/207/345/215/227.md +2 -0
  5. 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 +5 -0
  6. package/engine/src/api.ts +106 -5
  7. package/engine/src/cli-args.ts +3 -0
  8. package/engine/src/features.ts +43 -4
  9. package/engine/src/launch.ts +25 -4
  10. package/engine/src/paseo-runtime.ts +5 -0
  11. package/engine/src/preflight.ts +2 -0
  12. package/engine/src/records.ts +24 -2
  13. package/engine/src/runtime.ts +2 -0
  14. package/engine/src/worktree.ts +180 -25
  15. package/package.json +1 -1
  16. package/paseo-plugin/client/format.ts +6 -2
  17. package/paseo-plugin/client/inbox.tsx +6 -1
  18. package/paseo-plugin/package.json +1 -1
  19. package/paseo-plugin/shared/contracts.ts +4 -2
  20. package/site-dist/404.html +2 -2
  21. package/site-dist/assets/{app.C6QQarr3.js → app.gI1JF182.js} +1 -1
  22. package/site-dist/assets/changelog.md.2xf690VW.js +1 -0
  23. package/site-dist/assets/chunks/@localSearchIndexroot.CiFeI6qC.js +1 -0
  24. package/site-dist/assets/chunks/{VPLocalSearchBox.NZKA1cjk.js → VPLocalSearchBox.DNmhkkfS.js} +1 -1
  25. package/site-dist/assets/chunks/{theme.BP9XiatK.js → theme.CZzkCOAC.js} +2 -2
  26. package/site-dist/assets/{guide_getting-started.md.CA-aS0r_.js → guide_getting-started.md.zmtXv15G.js} +1 -1
  27. package/site-dist/assets/guide_project.md.Csi5wiyt.js +77 -0
  28. package/site-dist/assets/guide_project.md.Csi5wiyt.lean.js +77 -0
  29. package/site-dist/assets/{guide_user.md.Cenm9vlN.js → guide_user.md.2v7b_fzd.js} +1 -1
  30. package/site-dist/assets/{guide_user.md.Cenm9vlN.lean.js → guide_user.md.2v7b_fzd.lean.js} +1 -1
  31. package/site-dist/assets/reference_contracts_cli-json.md.BR6gwq-e.js +1 -0
  32. package/site-dist/assets/reference_contracts_cli-json.md.BR6gwq-e.lean.js +1 -0
  33. package/site-dist/assets/reference_contracts_usage-record.md.D5krNLW7.js +10 -0
  34. package/site-dist/assets/reference_contracts_usage-record.md.D5krNLW7.lean.js +10 -0
  35. package/site-dist/changelog.html +5 -5
  36. package/site-dist/guide/getting-started.html +5 -5
  37. package/site-dist/guide/how-it-works.html +4 -4
  38. package/site-dist/guide/index.html +4 -4
  39. package/site-dist/guide/install.html +4 -4
  40. package/site-dist/guide/maintainer.html +4 -4
  41. package/site-dist/guide/phases.html +4 -4
  42. package/site-dist/guide/project.html +6 -6
  43. package/site-dist/guide/user.html +5 -5
  44. package/site-dist/hashmap.json +1 -1
  45. package/site-dist/index.html +4 -4
  46. package/site-dist/reference/adr/0001-step-agents-under-origin-chat.html +4 -4
  47. package/site-dist/reference/adr/0002-no-directory-switch-in-chat.html +4 -4
  48. package/site-dist/reference/adr/0003-script-engine-not-hub.html +4 -4
  49. package/site-dist/reference/adr/0004-result-files.html +4 -4
  50. package/site-dist/reference/adr/0005-no-default-branch-local-commits-only.html +4 -4
  51. package/site-dist/reference/adr/0006-skill-install-targets.html +4 -4
  52. package/site-dist/reference/adr/0007-own-interview-skill.html +4 -4
  53. package/site-dist/reference/adr/0008-entries-do-not-call-entries.html +4 -4
  54. package/site-dist/reference/adr/0009-versioned-install-layout.html +4 -4
  55. package/site-dist/reference/adr/0010-generated-feature-overview.html +4 -4
  56. package/site-dist/reference/adr/0011-resume-after-completion.html +4 -4
  57. package/site-dist/reference/adr/0012-review-panel.html +4 -4
  58. package/site-dist/reference/adr/0013-no-release-tooling.html +4 -4
  59. package/site-dist/reference/adr/0014-notifier-slot.html +4 -4
  60. package/site-dist/reference/adr/0015-incremental-continue.html +4 -4
  61. package/site-dist/reference/adr/0016-upgrade-from-tags.html +4 -4
  62. package/site-dist/reference/adr/0017-use-paseo-capabilities.html +4 -4
  63. package/site-dist/reference/adr/0018-own-worktree-option.html +4 -4
  64. package/site-dist/reference/adr/0019-parallel-orchestration.html +4 -4
  65. package/site-dist/reference/adr/0020-scheduling-through-the-chat.html +4 -4
  66. package/site-dist/reference/adr/0021-npm-version-manager.html +4 -4
  67. package/site-dist/reference/adr/0022-develop-and-verify-phases.html +4 -4
  68. package/site-dist/reference/adr/0023-types-gate-slices.html +4 -4
  69. package/site-dist/reference/adr/0024-confirm-early-review-axes.html +4 -4
  70. package/site-dist/reference/adr/0025-joint-requirements.html +4 -4
  71. package/site-dist/reference/adr/0026-machine-records-and-api.html +4 -4
  72. package/site-dist/reference/adr/0027-paseo-plugin.html +4 -4
  73. package/site-dist/reference/adr/0028-external-integrations.html +4 -4
  74. package/site-dist/reference/adr/0029-requirements-from-cards.html +4 -4
  75. package/site-dist/reference/adr/0030-card-intake-process.html +4 -4
  76. package/site-dist/reference/adr/0031-fewer-interventions.html +4 -4
  77. package/site-dist/reference/adr/0032-npm-only-install.html +4 -4
  78. package/site-dist/reference/adr/0033-prototype-review-and-ui-check.html +4 -4
  79. package/site-dist/reference/adr/index.html +4 -4
  80. package/site-dist/reference/commands.html +4 -4
  81. package/site-dist/reference/config.html +4 -4
  82. package/site-dist/reference/contracts/cli-json.html +5 -5
  83. package/site-dist/reference/contracts/feature-files.html +4 -4
  84. package/site-dist/reference/contracts/index.html +4 -4
  85. package/site-dist/reference/contracts/notifier-event.html +4 -4
  86. package/site-dist/reference/contracts/result-file.html +4 -4
  87. package/site-dist/reference/contracts/spec.html +4 -4
  88. package/site-dist/reference/contracts/state.html +4 -4
  89. package/site-dist/reference/contracts/usage-record.html +6 -6
  90. package/site-dist/reference/contracts/verify.html +4 -4
  91. package/site-dist/reference/scope.html +4 -4
  92. package/skills/req/SKILL.md +1 -0
  93. package/skills/req/playbooks/incident.md +3 -3
  94. package/skills/req/playbooks/new.md +1 -1
  95. package/skills/req/playbooks/small.md +1 -1
  96. package/skills/spec-writing/SKILL.md +3 -1
  97. package/site-dist/assets/changelog.md.BzAEYWi7.js +0 -1
  98. package/site-dist/assets/chunks/@localSearchIndexroot.BjRGqGQa.js +0 -1
  99. package/site-dist/assets/guide_project.md.qQLH2fWy.js +0 -77
  100. package/site-dist/assets/guide_project.md.qQLH2fWy.lean.js +0 -77
  101. package/site-dist/assets/reference_contracts_cli-json.md.B7o8deSY.js +0 -1
  102. package/site-dist/assets/reference_contracts_cli-json.md.B7o8deSY.lean.js +0 -1
  103. package/site-dist/assets/reference_contracts_usage-record.md.DBMNY4OP.js +0 -10
  104. package/site-dist/assets/reference_contracts_usage-record.md.DBMNY4OP.lean.js +0 -10
  105. /package/site-dist/assets/{changelog.md.BzAEYWi7.lean.js → changelog.md.2xf690VW.lean.js} +0 -0
  106. /package/site-dist/assets/{guide_getting-started.md.CA-aS0r_.lean.js → guide_getting-started.md.zmtXv15G.lean.js} +0 -0
@@ -2,71 +2,226 @@
2
2
  // The chat stays where it is (its working directory never changes); the spec moves
3
3
  // to the new worktree, is committed there on its own branch, and the step agents are
4
4
  // placed in that workspace while remaining subagents of the chat. See ADR 0018.
5
+ //
6
+ // 1.14: the move can be done again. What was created is written down first
7
+ // (~/.req-kit/worktrees/<key>.json), so a start that failed after the worktree existed (the
8
+ // launcher gave up waiting, the check before starting failed) continues in that worktree the
9
+ // next time instead of stopping at "the branch already exists" and leaving a branch with only
10
+ // the spec on it. The alignment's other files (GLOSSARY.md, docs/adr/) go along with the spec.
5
11
 
6
12
  import { execFileSync } from "node:child_process";
7
13
  import fs from "node:fs";
8
14
  import path from "node:path";
15
+ import { kitHome } from "./locations.js";
16
+ import { registerRequirement, requirementKey } from "./records.js";
9
17
  import type { AgentRuntime } from "./runtime.js";
10
18
 
11
19
  function git(cwd: string, ...args: string[]): string {
12
20
  return execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
13
21
  }
14
22
 
23
+ /** `git status --porcelain` lines as they are (a leading space is part of the format). */
24
+ function porcelain(cwd: string, ...args: string[]): string[] {
25
+ try {
26
+ return execFileSync("git", ["status", "--porcelain", ...args], { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] })
27
+ .split("\n")
28
+ .filter((l) => l.length > 3);
29
+ } catch {
30
+ return [];
31
+ }
32
+ }
33
+
34
+ function gitOrNull(cwd: string, ...args: string[]): string | null {
35
+ try {
36
+ return git(cwd, ...args);
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+
15
42
  export interface OwnWorktree {
16
43
  repo: string;
17
44
  workspaceId: string;
18
45
  branch: string;
19
46
  /** Whether the uncommitted copy in the chat's checkout was removed after moving. */
20
47
  removedSource: boolean;
48
+ /** 1.14: an earlier start had created this worktree already; it is used again. */
49
+ reused: boolean;
50
+ /** 1.14: files outside the feature directory the alignment changed, carried over (relative paths). */
51
+ carried: string[];
52
+ /** 1.14: things the person should know about where the branch starts. */
53
+ warnings: string[];
54
+ }
55
+
56
+ /** What a start created, written before anything else is done in the new worktree. */
57
+ export interface WorktreeRecord {
58
+ schema: 1;
59
+ sourceRepo: string;
60
+ featureDir: string;
61
+ repo: string;
62
+ workspaceId: string;
63
+ branch: string;
64
+ baseRef: string;
65
+ createdAt: string;
66
+ originAgentId: string | null;
67
+ }
68
+
69
+ export function worktreeRecordsDir(env: NodeJS.ProcessEnv = process.env): string {
70
+ return path.join(kitHome(env), "worktrees");
71
+ }
72
+
73
+ function recordFile(sourceRepo: string, featureDir: string, env: NodeJS.ProcessEnv): string {
74
+ return path.join(worktreeRecordsDir(env), `${requirementKey(sourceRepo, featureDir)}.json`);
75
+ }
76
+
77
+ export function readWorktreeRecord(sourceRepo: string, featureDir: string, env: NodeJS.ProcessEnv = process.env): WorktreeRecord | null {
78
+ try {
79
+ return JSON.parse(fs.readFileSync(recordFile(sourceRepo, featureDir, env), "utf8")) as WorktreeRecord;
80
+ } catch {
81
+ return null;
82
+ }
83
+ }
84
+
85
+ /** Every recorded worktree whose directory still exists. */
86
+ export function listWorktreeRecords(env: NodeJS.ProcessEnv = process.env): WorktreeRecord[] {
87
+ const dir = worktreeRecordsDir(env);
88
+ if (!fs.existsSync(dir)) return [];
89
+ const out: WorktreeRecord[] = [];
90
+ for (const name of fs.readdirSync(dir)) {
91
+ if (!name.endsWith(".json")) continue;
92
+ try {
93
+ const r = JSON.parse(fs.readFileSync(path.join(dir, name), "utf8")) as WorktreeRecord;
94
+ if (r.repo && fs.existsSync(r.repo)) out.push(r);
95
+ } catch {
96
+ // A broken record is skipped.
97
+ }
98
+ }
99
+ return out;
100
+ }
101
+
102
+ function writeRecord(record: WorktreeRecord, env: NodeJS.ProcessEnv): void {
103
+ const file = recordFile(record.sourceRepo, record.featureDir, env);
104
+ fs.mkdirSync(path.dirname(file), { recursive: true });
105
+ fs.writeFileSync(file, `${JSON.stringify(record, null, 2)}\n`);
106
+ }
107
+
108
+ /** The directory of the git worktree that has `branch` checked out, if any. */
109
+ function worktreeOfBranch(sourceRepo: string, branch: string): string | null {
110
+ const list = gitOrNull(sourceRepo, "worktree", "list", "--porcelain") ?? "";
111
+ let current: string | null = null;
112
+ for (const line of list.split("\n")) {
113
+ if (line.startsWith("worktree ")) current = line.slice("worktree ".length).trim();
114
+ else if (line.trim() === `branch refs/heads/${branch}` && current) return current;
115
+ }
116
+ return null;
117
+ }
118
+
119
+ /** Files the requirement interview may change outside the feature directory. */
120
+ const ALIGNMENT_FILES = ["GLOSSARY.md", "CONTEXT.md", "docs/adr"];
121
+
122
+ /** Uncommitted alignment changes in the chat's checkout (new or modified files, relative paths). */
123
+ export function alignmentChanges(sourceRepo: string): string[] {
124
+ return porcelain(sourceRepo, "--untracked-files=all", "--", ...ALIGNMENT_FILES)
125
+ .filter((l) => !l.startsWith(" D") && !l.startsWith("D "))
126
+ .map((l) => l.slice(3).trim().replace(/^"|"$/g, ""))
127
+ .filter((p) => p && !p.includes(" -> "));
128
+ }
129
+
130
+ /** Where the new branch starts and what is left behind, in plain words. */
131
+ export function baseWarnings(sourceRepo: string, featureDir: string, head: string): string[] {
132
+ const warnings: string[] = [];
133
+ if (gitOrNull(sourceRepo, "ls-files", "--", featureDir)) {
134
+ warnings.push(`需求文件已经提交在 ${head} 上(应该只提交在需求自己的分支上)。新分支照样从这里开始;${head} 上的这个提交请开发同事看一下,还没推送的话可以撤掉,流水线不会改动它。`);
135
+ }
136
+ const behind = Number(gitOrNull(sourceRepo, "rev-list", "--count", "HEAD..@{upstream}") ?? "0");
137
+ if (behind > 0) warnings.push(`本地的 ${head} 比远端落后 ${behind} 个提交(按上次拉取的结果),新分支从本地的 ${head} 开始;需要最新代码时,先拉取再重新开始。`);
138
+ const others = porcelain(sourceRepo, "--untracked-files=all")
139
+ .map((l) => l.slice(3).trim().replace(/^"|"$/g, ""))
140
+ .filter((p) => p && !p.startsWith(featureDir.split(path.sep).join("/")) && !ALIGNMENT_FILES.some((a) => p === a || p.startsWith(`${a}/`)));
141
+ if (others.length > 0) warnings.push(`这个目录里还有 ${others.length} 处未提交的改动和这个需求无关,没有带到新工作区(例如 ${others.slice(0, 3).join("、")})。`);
142
+ return warnings;
21
143
  }
22
144
 
23
145
  export async function moveToOwnWorktree(input: {
24
- runtime: Pick<AgentRuntime, "createWorktree">;
146
+ runtime: Pick<AgentRuntime, "createWorktree"> & Partial<Pick<AgentRuntime, "openWorkspace">>;
25
147
  sourceRepo: string;
26
148
  featureDir: string;
27
149
  originAgentId: string | null;
28
150
  title: string;
151
+ env?: NodeJS.ProcessEnv;
29
152
  }): Promise<OwnWorktree> {
153
+ const env = input.env ?? process.env;
30
154
  const { sourceRepo, featureDir } = input;
31
155
  const branch = `feature/${path.basename(featureDir)}`;
32
- try {
33
- git(sourceRepo, "show-ref", "--verify", "--quiet", `refs/heads/${branch}`);
34
- throw new Error(`分支 ${branch} 已经存在。这个需求可能已经有自己的工作区了:用 --list 查看,或在那个工作区的对话中继续。`);
35
- } catch (error) {
36
- if ((error as Error).message.startsWith("分支")) throw error;
37
- // show-ref failed: the branch does not exist yet, as expected.
38
- }
156
+ const branchExists = gitOrNull(sourceRepo, "show-ref", "--verify", "--quiet", `refs/heads/${branch}`) !== null;
39
157
  const head = git(sourceRepo, "rev-parse", "--abbrev-ref", "HEAD");
40
158
  const baseRef = head === "HEAD" ? git(sourceRepo, "rev-parse", "HEAD") : head;
41
159
 
42
- const created = await input.runtime.createWorktree({
43
- sourceRepo,
44
- baseRef,
45
- branchName: branch,
46
- title: input.title,
47
- callerAgentId: input.originAgentId,
48
- });
49
- const repo = fs.realpathSync(created.directory);
160
+ let repo: string;
161
+ let workspaceId: string;
162
+ let reused = false;
163
+ let warnings: string[] = [];
164
+ const record = readWorktreeRecord(sourceRepo, featureDir, env);
165
+ if (branchExists && record && fs.existsSync(record.repo) && worktreeOfBranch(sourceRepo, branch)) {
166
+ // An earlier start made it and stopped before the pipeline ran there.
167
+ repo = fs.realpathSync(record.repo);
168
+ workspaceId = record.workspaceId;
169
+ reused = true;
170
+ } else if (branchExists) {
171
+ const dir = worktreeOfBranch(sourceRepo, branch);
172
+ if (!dir) {
173
+ throw new Error(
174
+ `分支 ${branch} 已经存在,但没有对应的工作区目录。如果它是以前没有启动成功留下的空分支,请开发同事确认后删除它(git branch -D ${branch})再重新开始;否则请把功能目录换一个名字。`,
175
+ );
176
+ }
177
+ if (!input.runtime.openWorkspace) throw new Error(`分支 ${branch} 已经有工作区 ${dir},但这个 Paseo 版本不能接手已有的目录。请在 Paseo 中打开那个工作区,在那里的对话中开始开发。`);
178
+ // A worktree made by an older version (no record): let Paseo take the directory as a workspace.
179
+ workspaceId = (await input.runtime.openWorkspace(dir)).workspaceId;
180
+ repo = fs.realpathSync(dir);
181
+ reused = true;
182
+ } else {
183
+ warnings = baseWarnings(sourceRepo, featureDir, head);
184
+ const created = await input.runtime.createWorktree({ sourceRepo, baseRef, branchName: branch, title: input.title, callerAgentId: input.originAgentId });
185
+ repo = fs.realpathSync(created.directory);
186
+ workspaceId = created.workspaceId;
187
+ }
188
+ // Written down before anything else happens there, so a failure after this point can be continued.
189
+ writeRecord({ schema: 1, sourceRepo: fs.realpathSync(sourceRepo), featureDir, repo, workspaceId, branch, baseRef: record?.baseRef ?? baseRef, createdAt: record?.createdAt ?? new Date().toISOString(), originAgentId: input.originAgentId }, env);
190
+
191
+ // The plugin lists it where it now lives, still under the chat's project.
192
+ registerRequirement({ repo, featureDir, worktree: { workspaceId, sourceRepo: fs.realpathSync(sourceRepo) } }, env, input.originAgentId);
50
193
 
51
194
  // The spec and interview notes were written in the chat's checkout; move them over.
52
195
  const from = path.join(sourceRepo, featureDir);
53
196
  const to = path.join(repo, featureDir);
54
- fs.mkdirSync(to, { recursive: true });
55
- fs.cpSync(from, to, { recursive: true, filter: (src) => path.basename(src) !== ".pipeline" });
56
- git(repo, "add", "--", featureDir);
57
- const staged = git(repo, "diff", "--cached", "--name-only", "--", featureDir);
197
+ if (fs.existsSync(from)) {
198
+ fs.mkdirSync(to, { recursive: true });
199
+ fs.cpSync(from, to, { recursive: true, filter: (src) => path.basename(src) !== ".pipeline" });
200
+ }
201
+ if (!fs.existsSync(path.join(to, "spec.md"))) throw new Error(`新工作区 ${repo} 中没有找到需求说明 ${featureDir}/spec.md`);
202
+ // The terms and decisions the interview wrote down belong to the requirement too.
203
+ const carried = alignmentChanges(sourceRepo);
204
+ for (const rel of carried) {
205
+ const src = path.join(sourceRepo, rel);
206
+ if (!fs.existsSync(src) || fs.statSync(src).isDirectory()) continue;
207
+ fs.mkdirSync(path.dirname(path.join(repo, rel)), { recursive: true });
208
+ fs.copyFileSync(src, path.join(repo, rel));
209
+ }
210
+ git(repo, "add", "--", featureDir, ...carried);
211
+ const staged = git(repo, "diff", "--cached", "--name-only", "--", featureDir, ...carried);
58
212
  if (staged) {
59
213
  try {
60
- git(repo, "commit", "-q", "-m", `docs(req): ${input.title} 需求说明`, "--", featureDir);
214
+ git(repo, "commit", "-q", "-m", `docs(req): ${input.title} 需求说明`, "--", featureDir, ...carried);
61
215
  } catch (error) {
62
216
  const stderr = (error as { stderr?: Buffer | string }).stderr?.toString().trim();
63
217
  throw new Error(`在新工作区 ${repo} 中提交需求说明失败:${stderr || (error as Error).message}`);
64
218
  }
65
219
  }
66
220
 
67
- // Leave nothing behind in the chat's checkout unless it was already committed there.
68
- const tracked = git(sourceRepo, "ls-files", "--", featureDir);
69
- const removedSource = tracked === "";
221
+ // Leave nothing behind in the chat's checkout unless it was already committed there. The
222
+ // carried GLOSSARY.md / ADR changes stay: they may sit next to edits that are not ours.
223
+ const tracked = gitOrNull(sourceRepo, "ls-files", "--", featureDir) ?? "";
224
+ const removedSource = tracked === "" && fs.existsSync(from);
70
225
  if (removedSource) fs.rmSync(from, { recursive: true, force: true });
71
- return { repo, workspaceId: created.workspaceId, branch, removedSource };
226
+ return { repo, workspaceId, branch, removedSource: removedSource || (tracked === "" && !fs.existsSync(from)), reused, carried, warnings };
72
227
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paseo-req-kit",
3
- "version": "1.13.0",
3
+ "version": "1.14.0-beta.2",
4
4
  "description": "req-kit: a requirement-development workflow for Paseo. /req aligns a requirement in chat; the engine runs design, implementation, review and verification as Paseo agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -7,6 +7,7 @@ export const ATTENTION_LABELS: Record<Exclude<Attention, null>, string> = {
7
7
  permission: "等待批准权限",
8
8
  interrupted: "已中断,可以继续",
9
9
  not_completed: "结束但未完成",
10
+ not_started: "已确认,未开始开发",
10
11
  };
11
12
 
12
13
  export const TYPE_LABELS: Record<string, string> = { defect: "缺陷", refactor: "重构", assessment: "评估" };
@@ -88,13 +89,15 @@ export function facts(r: Requirement): string {
88
89
  /** What a person can do from here, by the requirement's state. */
89
90
  export function actionsFor(
90
91
  r: Pick<Requirement, "attention" | "running" | "status"> & { external?: Array<{ pending: number; id: string | null }> },
91
- ): Array<"approve" | "stop" | "resume" | "verify" | "sync"> {
92
- const base: Array<"approve" | "stop" | "resume" | "verify" | "sync"> = r.running
92
+ ): Array<"approve" | "stop" | "resume" | "verify" | "sync" | "start"> {
93
+ const base: Array<"approve" | "stop" | "resume" | "verify" | "sync" | "start"> = r.running
93
94
  ? ["stop"]
94
95
  : r.attention === "approval"
95
96
  ? ["approve"]
96
97
  : r.attention === "interrupted" || r.attention === "business"
97
98
  ? ["resume"]
99
+ : r.attention === "not_started"
100
+ ? ["start"]
98
101
  : r.status === "phase_done"
99
102
  ? ["verify"]
100
103
  : [];
@@ -106,6 +109,7 @@ export function actionsFor(
106
109
  export const ACTION_TEXT = {
107
110
  approve: { label: "确认方案", confirm: "确认 preview.md 中的方案,开始写代码?请先看过确认预览和原型。" },
108
111
  stop: { label: "停止", confirm: "停止这个需求的流水线?正在运行的步骤会被中断,之后可以继续。" },
112
+ start: { label: "开始开发", confirm: "按已确认的需求说明开始开发?在项目主目录中的需求会新建自己的工作区;进展发回谈需求的那个对话。" },
109
113
  resume: { label: "继续", confirm: "从中断处继续?需求说明改过的话,只处理变化的部分。" },
110
114
  verify: { label: "开始测试验证", confirm: "开始测试验证?选择在哪里验证。" },
111
115
  sync: { label: "同步到外部系统", confirm: "把这个需求同步到对接的外部系统:补发没有成功的调用、补建卡片、更新状态。" },
@@ -20,6 +20,7 @@ const KIND: Record<Exclude<Attention, null>, { label: string; tone: "warning" |
20
20
  permission: { label: "批准权限", tone: "warning", todo: "有一个步骤在等你允许它做一项操作,批准前会一直停在这里。打开这个 agent,在它的对话里选择允许或拒绝;拿不准时请开发同事看一下。" },
21
21
  interrupted: { label: "已中断", tone: "danger", todo: "开发中断了,自动处理没能解决。看一下原因,能继续就继续。" },
22
22
  not_completed: { label: "没有完成", tone: "muted", todo: "流水线结束了,但有部分没有做完。完成报告里写了原因和建议。" },
23
+ not_started: { label: "还没开始开发", tone: "warning", todo: "需求说明已经确认,但开发没有开始。确认无误就点“开始开发”,进展会发回谈需求的那个对话。" },
23
24
  };
24
25
 
25
26
  /** Plain waiting time: "等了 3 小时". */
@@ -48,7 +49,7 @@ function InboxCard({ theme, layout, item, open, readOnly, openAgent }: { theme:
48
49
  const w = item.waiting;
49
50
  const repo = item.sourceRepo ?? item.repo;
50
51
 
51
- const act = async (action: "approve" | "resume" | "reply") => {
52
+ const act = async (action: "approve" | "resume" | "reply" | "start") => {
52
53
  try {
53
54
  const result = await run.mutateAsync({ action, repo, featureDir: item.featureDir, ...(action === "reply" ? { text } : {}) });
54
55
  const first = result.message.split("\n").find((l) => l.trim()) ?? "";
@@ -93,6 +94,7 @@ function InboxCard({ theme, layout, item, open, readOnly, openAgent }: { theme:
93
94
  {w.reason}
94
95
  </Text>
95
96
  ) : null}
97
+ {item.attention === "not_started" && w?.reason ? <Text style={s.text}>{w.reason}</Text> : null}
96
98
 
97
99
  {readOnly ? (
98
100
  <View style={s.row}>
@@ -146,6 +148,9 @@ function InboxCard({ theme, layout, item, open, readOnly, openAgent }: { theme:
146
148
  {item.attention === "interrupted" ? (
147
149
  <Button theme={theme} primary label={run.isPending ? "正在执行…" : "继续"} disabled={run.isPending} onPress={() => void act("resume")} />
148
150
  ) : null}
151
+ {item.attention === "not_started" && w?.canStart ? (
152
+ <Button theme={theme} primary label={run.isPending ? "正在开始…" : "开始开发"} disabled={run.isPending} onPress={() => void act("start")} />
153
+ ) : null}
149
154
  <Button theme={theme} label={item.attention === "approval" ? "看方案和确认预览" : item.attention === "not_completed" ? "看完成报告" : "查看详情"} onPress={open} />
150
155
  </View>
151
156
  </>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "req-kit-paseo-plugin",
3
- "version": "1.13.0",
3
+ "version": "1.14.0-beta.2",
4
4
  "private": true,
5
5
  "description": "The req-kit plugin for Paseo. Ships inside the paseo-req-kit package; installed with req plugin install.",
6
6
  "type": "module",
@@ -3,7 +3,7 @@
3
3
  import { defineRpc, defineSettings } from "@getpaseo/plugin";
4
4
  import { z } from "zod";
5
5
 
6
- export type Attention = "approval" | "business" | "permission" | "interrupted" | "not_completed" | null;
6
+ export type Attention = "approval" | "business" | "permission" | "interrupted" | "not_completed" | "not_started" | null;
7
7
 
8
8
  export interface Usage {
9
9
  steps: number;
@@ -45,6 +45,8 @@ export interface Requirement {
45
45
  canReply: boolean;
46
46
  /** req-kit 1.13+, attention "permission": the step agent waiting for an approval. */
47
47
  agentId?: string;
48
+ /** req-kit 1.14+, attention "not_started": development can be started from here. */
49
+ canStart?: boolean;
48
50
  } | null;
49
51
  }
50
52
 
@@ -171,7 +173,7 @@ export const statsRpc = defineRpc({
171
173
  output: z.custom<StatsSummary>(),
172
174
  });
173
175
 
174
- export const ACTIONS = ["approve", "stop", "resume", "verify", "sync", "reply"] as const;
176
+ export const ACTIONS = ["approve", "stop", "resume", "verify", "sync", "reply", "start"] as const;
175
177
  export type Action = (typeof ACTIONS)[number];
176
178
 
177
179
  export const runRpc = defineRpc({
@@ -9,7 +9,7 @@
9
9
  <link rel="preload stylesheet" href="/assets/style.Dwsa4SMe.css" as="style">
10
10
  <link rel="preload stylesheet" href="/vp-icons.css" as="style">
11
11
 
12
- <script type="module" src="/assets/app.C6QQarr3.js"></script>
12
+ <script type="module" src="/assets/app.gI1JF182.js"></script>
13
13
  <link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
14
14
  <link rel="icon" type="image/svg+xml" href="/logo.svg">
15
15
  <meta name="theme-color" content="#3f6fd8">
@@ -21,7 +21,7 @@
21
21
  </head>
22
22
  <body>
23
23
  <div id="app"></div>
24
- <script>window.__VP_HASH_MAP__=JSON.parse("{\"changelog.md\":\"BzAEYWi7\",\"guide_getting-started.md\":\"CA-aS0r_\",\"guide_how-it-works.md\":\"D-kQsF1t\",\"guide_index.md\":\"CLnGCmGW\",\"guide_install.md\":\"DkCyZsOU\",\"guide_maintainer.md\":\"C1v7EpSY\",\"guide_phases.md\":\"BpGAb1re\",\"guide_project.md\":\"qQLH2fWy\",\"guide_user.md\":\"Cenm9vlN\",\"index.md\":\"Cf_sSf_f\",\"reference_adr_0001-step-agents-under-origin-chat.md\":\"RtRTq7oi\",\"reference_adr_0002-no-directory-switch-in-chat.md\":\"BxtN-Aa2\",\"reference_adr_0003-script-engine-not-hub.md\":\"66EgZtqx\",\"reference_adr_0004-result-files.md\":\"DbqcCozI\",\"reference_adr_0005-no-default-branch-local-commits-only.md\":\"CkImA4s6\",\"reference_adr_0006-skill-install-targets.md\":\"CwY8YepV\",\"reference_adr_0007-own-interview-skill.md\":\"CryhxRyG\",\"reference_adr_0008-entries-do-not-call-entries.md\":\"DsRWAgeA\",\"reference_adr_0009-versioned-install-layout.md\":\"CSg1VqlW\",\"reference_adr_0010-generated-feature-overview.md\":\"D8F3MK-h\",\"reference_adr_0011-resume-after-completion.md\":\"BCrZrKjf\",\"reference_adr_0012-review-panel.md\":\"k9rrHFFc\",\"reference_adr_0013-no-release-tooling.md\":\"BQeJ8dEI\",\"reference_adr_0014-notifier-slot.md\":\"C23QR1xO\",\"reference_adr_0015-incremental-continue.md\":\"Buy7wwO8\",\"reference_adr_0016-upgrade-from-tags.md\":\"qfIW-tqJ\",\"reference_adr_0017-use-paseo-capabilities.md\":\"CjcGli87\",\"reference_adr_0018-own-worktree-option.md\":\"fVDpgGSE\",\"reference_adr_0019-parallel-orchestration.md\":\"DrfrV0To\",\"reference_adr_0020-scheduling-through-the-chat.md\":\"BqSemGFG\",\"reference_adr_0021-npm-version-manager.md\":\"CU3PG6y5\",\"reference_adr_0022-develop-and-verify-phases.md\":\"C6fQDLq4\",\"reference_adr_0023-types-gate-slices.md\":\"D2E6yyYQ\",\"reference_adr_0024-confirm-early-review-axes.md\":\"FmK_ke0x\",\"reference_adr_0025-joint-requirements.md\":\"ChoKvMUx\",\"reference_adr_0026-machine-records-and-api.md\":\"veybjBPq\",\"reference_adr_0027-paseo-plugin.md\":\"BMX33ZNU\",\"reference_adr_0028-external-integrations.md\":\"DtdMe8RK\",\"reference_adr_0029-requirements-from-cards.md\":\"BHd1SQPe\",\"reference_adr_0030-card-intake-process.md\":\"kLc-DG9_\",\"reference_adr_0031-fewer-interventions.md\":\"BDnQcz8g\",\"reference_adr_0032-npm-only-install.md\":\"C-3L1FkX\",\"reference_adr_0033-prototype-review-and-ui-check.md\":\"hFcQzmaa\",\"reference_adr_index.md\":\"BYF-Ofor\",\"reference_commands.md\":\"ClKbS-t8\",\"reference_config.md\":\"CRe27LaA\",\"reference_contracts_cli-json.md\":\"B7o8deSY\",\"reference_contracts_feature-files.md\":\"DSiA8OEH\",\"reference_contracts_index.md\":\"Bkznz4px\",\"reference_contracts_notifier-event.md\":\"CCfrkm_A\",\"reference_contracts_result-file.md\":\"DmR4fjB-\",\"reference_contracts_spec.md\":\"BwwS0L_j\",\"reference_contracts_state.md\":\"EEBd_l2P\",\"reference_contracts_usage-record.md\":\"DBMNY4OP\",\"reference_contracts_verify.md\":\"CbA88u6S\",\"reference_scope.md\":\"Kzqw8U_f\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"req-kit\",\"titleTemplate\":\":title · req-kit\",\"description\":\"在 Paseo 中用对话对齐需求,由一组 AI agent 在后台完成设计、实现、评审和验证。给测试、产品、项目经理用的需求开发体系。\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"logo\":\"/logo.svg\",\"siteTitle\":\"req-kit\",\"nav\":[{\"text\":\"指南\",\"link\":\"/guide/\",\"activeMatch\":\"^/guide/\"},{\"text\":\"参考\",\"link\":\"/reference/commands\",\"activeMatch\":\"^/reference/\"},{\"text\":\"更新记录\",\"link\":\"/changelog\"},{\"text\":\"v1.13.0\",\"items\":[{\"text\":\"更新记录\",\"link\":\"/changelog\"},{\"text\":\"GitHub Releases\",\"link\":\"https://github.com/yiyisf/paseo-req-kit/releases\"},{\"text\":\"范围与取舍\",\"link\":\"/reference/scope\"}]}],\"sidebar\":{\"/guide/\":[{\"text\":\"开始\",\"items\":[{\"text\":\"req-kit 是什么\",\"link\":\"/guide/\"},{\"text\":\"快速开始\",\"link\":\"/guide/getting-started\"},{\"text\":\"工作原理\",\"link\":\"/guide/how-it-works\"}]},{\"text\":\"使用\",\"items\":[{\"text\":\"使用者指南\",\"link\":\"/guide/user\"},{\"text\":\"分阶段执行与提测\",\"link\":\"/guide/phases\"}]},{\"text\":\"安装与维护\",\"items\":[{\"text\":\"安装与升级\",\"link\":\"/guide/install\"},{\"text\":\"项目定制与运行规则\",\"link\":\"/guide/project\"},{\"text\":\"维护者指南\",\"link\":\"/guide/maintainer\"}]}],\"/reference/\":[{\"text\":\"参考\",\"items\":[{\"text\":\"命令\",\"link\":\"/reference/commands\"},{\"text\":\"配置项\",\"link\":\"/reference/config\"},{\"text\":\"范围与取舍\",\"link\":\"/reference/scope\"}]},{\"text\":\"文件格式约定\",\"collapsed\":false,\"items\":[{\"text\":\"总览\",\"link\":\"/reference/contracts/\"},{\"text\":\"需求说明 spec.md\",\"link\":\"/reference/contracts/spec\"},{\"text\":\"状态文件 state.json\",\"link\":\"/reference/contracts/state\"},{\"text\":\"结果文件\",\"link\":\"/reference/contracts/result-file\"},{\"text\":\"功能目录中的文件\",\"link\":\"/reference/contracts/feature-files\"},{\"text\":\"验证方法 verify.md\",\"link\":\"/reference/contracts/verify\"},{\"text\":\"外部通知事件\",\"link\":\"/reference/contracts/notifier-event\"},{\"text\":\"req api 的 JSON 输出\",\"link\":\"/reference/contracts/cli-json\"},{\"text\":\"需求索引与使用记录\",\"link\":\"/reference/contracts/usage-record\"}]},{\"text\":\"设计决定(ADR)\",\"collapsed\":true,\"items\":[{\"text\":\"总览\",\"link\":\"/reference/adr/\"},{\"text\":\"0001 步骤 agent 挂在发起的对话下\",\"link\":\"/reference/adr/0001-step-agents-under-origin-chat\"},{\"text\":\"0002 对话过程中不切换工作目录\",\"link\":\"/reference/adr/0002-no-directory-switch-in-chat\"},{\"text\":\"0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流\",\"link\":\"/reference/adr/0003-script-engine-not-hub\"},{\"text\":\"0004 步骤结论只看结果文件\",\"link\":\"/reference/adr/0004-result-files\"},{\"text\":\"0005 不在默认分支上运行,只做本地提交\",\"link\":\"/reference/adr/0005-no-default-branch-local-commits-only\"},{\"text\":\"0006 只安装到 ~/.agents/skills 和 ~/.claude/skills\",\"link\":\"/reference/adr/0006-skill-install-targets\"},{\"text\":\"0007 自带需求访谈 skill,不依赖外部 skill 包\",\"link\":\"/reference/adr/0007-own-interview-skill\"},{\"text\":\"0008 入口 skill 之间不互相调用\",\"link\":\"/reference/adr/0008-entries-do-not-call-entries\"},{\"text\":\"0009 程序与本机配置分开存放,按版本目录并存\",\"link\":\"/reference/adr/0009-versioned-install-layout\"},{\"text\":\"0010 需求总览现场生成,不维护 INDEX.md\",\"link\":\"/reference/adr/0010-generated-feature-overview\"},{\"text\":\"0011 完成后修改 spec 可以继续开发\",\"link\":\"/reference/adr/0011-resume-after-completion\"},{\"text\":\"0012 评审小组:首轮并行评审,评审者核实汇总\",\"link\":\"/reference/adr/0012-review-panel\"},{\"text\":\"0013 发布不使用 changesets 等工具\",\"link\":\"/reference/adr/0013-no-release-tooling\"},{\"text\":\"0014 外部通知只留接口,不内置任何 IM\",\"link\":\"/reference/adr/0014-notifier-slot\"},{\"text\":\"0015 需求变更后增量继续,而不是从零重做\",\"link\":\"/reference/adr/0015-incremental-continue\"},{\"text\":\"0016 一键升级:从 git 标签下载到 versions/ 再切换\",\"link\":\"/reference/adr/0016-upgrade-from-tags\"},{\"text\":\"0017 用好 Paseo 自身的能力:profile、工作区脚本、用量和时间线\",\"link\":\"/reference/adr/0017-use-paseo-capabilities\"},{\"text\":\"0018 可选:流水线为需求新建 worktree 工作区\",\"link\":\"/reference/adr/0018-own-worktree-option\"},{\"text\":\"0019 用 Paseo 的并行子 agent:确认前独立审阅、方案提案\",\"link\":\"/reference/adr/0019-parallel-orchestration\"},{\"text\":\"0020 调度:用 Paseo 定时任务把消息发回对话,排队在本机进行\",\"link\":\"/reference/adr/0020-scheduling-through-the-chat\"},{\"text\":\"0021 npm 分发:全局包是版本管理器,各版本仍装在 versions/ 下\",\"link\":\"/reference/adr/0021-npm-version-manager\"},{\"text\":\"0022 分阶段执行:研发阶段、闸口、测试验证阶段\",\"link\":\"/reference/adr/0022-develop-and-verify-phases\"},{\"text\":\"0023 需求类型、质量门、按切片实现\",\"link\":\"/reference/adr/0023-types-gate-slices\"},{\"text\":\"0024 让分歧更早暴露:验收例子、方案确认点、两个方向的评审、反复的问题变成规则\",\"link\":\"/reference/adr/0024-confirm-early-review-axes\"},{\"text\":\"0025 联合需求:一个需求同时改几个仓库\",\"link\":\"/reference/adr/0025-joint-requirements\"},{\"text\":\"0026 本机的需求索引、使用记录和 req api\",\"link\":\"/reference/adr/0026-machine-records-and-api\"},{\"text\":\"0027 Paseo 插件:随 req-kit 一起发布,只通过 req api 工作\",\"link\":\"/reference/adr/0027-paseo-plugin\"},{\"text\":\"0028 外部系统对接:命令写法在配置里,内容由 AI 整理,调用是确定的\",\"link\":\"/reference/adr/0028-external-integrations\"},{\"text\":\"0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话\",\"link\":\"/reference/adr/0029-requirements-from-cards\"},{\"text\":\"0030 接单器:共享机器上定时接卡片、转达回复\",\"link\":\"/reference/adr/0030-card-intake-process\"},{\"text\":\"0031 少等人:每种中断都有自动的下一步\",\"link\":\"/reference/adr/0031-fewer-interventions\"},{\"text\":\"0032 安装、升级和文档只依赖 npm 源\",\"link\":\"/reference/adr/0032-npm-only-install\"},{\"text\":\"0033 原型审查页和不靠看图的界面检查\",\"link\":\"/reference/adr/0033-prototype-review-and-ui-check\"}]}]},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/yiyisf/paseo-req-kit\"}],\"editLink\":{\"pattern\":\"https://github.com/yiyisf/paseo-req-kit/edit/main/site/:path\",\"text\":\"在 GitHub 上编辑此页\"},\"footer\":{\"message\":\"以 MIT 许可发布。req-kit 是运行在 Paseo 上的社区项目。\",\"copyright\":\"Copyright © 2026 yiyisf\"},\"search\":{\"provider\":\"local\",\"options\":{\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"noResultsText\":\"没有找到相关结果\",\"resetButtonTitle\":\"清除\",\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\",\"closeText\":\"关闭\"}}}}},\"outline\":{\"level\":[2,3],\"label\":\"本页内容\"},\"docFooter\":{\"prev\":\"上一页\",\"next\":\"下一页\"},\"lastUpdated\":{\"text\":\"最后更新\"},\"returnToTopLabel\":\"回到顶部\",\"sidebarMenuLabel\":\"目录\",\"darkModeSwitchLabel\":\"外观\",\"lightModeSwitchTitle\":\"切换到浅色\",\"darkModeSwitchTitle\":\"切换到深色\",\"externalLinkIcon\":true,\"notFound\":{\"title\":\"页面不存在\",\"quote\":\"这个页面可能已经移动或删除。\",\"linkText\":\"回到首页\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":true}");</script>
24
+ <script>window.__VP_HASH_MAP__=JSON.parse("{\"changelog.md\":\"2xf690VW\",\"guide_getting-started.md\":\"zmtXv15G\",\"guide_how-it-works.md\":\"D-kQsF1t\",\"guide_index.md\":\"CLnGCmGW\",\"guide_install.md\":\"DkCyZsOU\",\"guide_maintainer.md\":\"C1v7EpSY\",\"guide_phases.md\":\"BpGAb1re\",\"guide_project.md\":\"Csi5wiyt\",\"guide_user.md\":\"2v7b_fzd\",\"index.md\":\"Cf_sSf_f\",\"reference_adr_0001-step-agents-under-origin-chat.md\":\"RtRTq7oi\",\"reference_adr_0002-no-directory-switch-in-chat.md\":\"BxtN-Aa2\",\"reference_adr_0003-script-engine-not-hub.md\":\"66EgZtqx\",\"reference_adr_0004-result-files.md\":\"DbqcCozI\",\"reference_adr_0005-no-default-branch-local-commits-only.md\":\"CkImA4s6\",\"reference_adr_0006-skill-install-targets.md\":\"CwY8YepV\",\"reference_adr_0007-own-interview-skill.md\":\"CryhxRyG\",\"reference_adr_0008-entries-do-not-call-entries.md\":\"DsRWAgeA\",\"reference_adr_0009-versioned-install-layout.md\":\"CSg1VqlW\",\"reference_adr_0010-generated-feature-overview.md\":\"D8F3MK-h\",\"reference_adr_0011-resume-after-completion.md\":\"BCrZrKjf\",\"reference_adr_0012-review-panel.md\":\"k9rrHFFc\",\"reference_adr_0013-no-release-tooling.md\":\"BQeJ8dEI\",\"reference_adr_0014-notifier-slot.md\":\"C23QR1xO\",\"reference_adr_0015-incremental-continue.md\":\"Buy7wwO8\",\"reference_adr_0016-upgrade-from-tags.md\":\"qfIW-tqJ\",\"reference_adr_0017-use-paseo-capabilities.md\":\"CjcGli87\",\"reference_adr_0018-own-worktree-option.md\":\"fVDpgGSE\",\"reference_adr_0019-parallel-orchestration.md\":\"DrfrV0To\",\"reference_adr_0020-scheduling-through-the-chat.md\":\"BqSemGFG\",\"reference_adr_0021-npm-version-manager.md\":\"CU3PG6y5\",\"reference_adr_0022-develop-and-verify-phases.md\":\"C6fQDLq4\",\"reference_adr_0023-types-gate-slices.md\":\"D2E6yyYQ\",\"reference_adr_0024-confirm-early-review-axes.md\":\"FmK_ke0x\",\"reference_adr_0025-joint-requirements.md\":\"ChoKvMUx\",\"reference_adr_0026-machine-records-and-api.md\":\"veybjBPq\",\"reference_adr_0027-paseo-plugin.md\":\"BMX33ZNU\",\"reference_adr_0028-external-integrations.md\":\"DtdMe8RK\",\"reference_adr_0029-requirements-from-cards.md\":\"BHd1SQPe\",\"reference_adr_0030-card-intake-process.md\":\"kLc-DG9_\",\"reference_adr_0031-fewer-interventions.md\":\"BDnQcz8g\",\"reference_adr_0032-npm-only-install.md\":\"C-3L1FkX\",\"reference_adr_0033-prototype-review-and-ui-check.md\":\"hFcQzmaa\",\"reference_adr_index.md\":\"BYF-Ofor\",\"reference_commands.md\":\"ClKbS-t8\",\"reference_config.md\":\"CRe27LaA\",\"reference_contracts_cli-json.md\":\"BR6gwq-e\",\"reference_contracts_feature-files.md\":\"DSiA8OEH\",\"reference_contracts_index.md\":\"Bkznz4px\",\"reference_contracts_notifier-event.md\":\"CCfrkm_A\",\"reference_contracts_result-file.md\":\"DmR4fjB-\",\"reference_contracts_spec.md\":\"BwwS0L_j\",\"reference_contracts_state.md\":\"EEBd_l2P\",\"reference_contracts_usage-record.md\":\"D5krNLW7\",\"reference_contracts_verify.md\":\"CbA88u6S\",\"reference_scope.md\":\"Kzqw8U_f\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"req-kit\",\"titleTemplate\":\":title · req-kit\",\"description\":\"在 Paseo 中用对话对齐需求,由一组 AI agent 在后台完成设计、实现、评审和验证。给测试、产品、项目经理用的需求开发体系。\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"logo\":\"/logo.svg\",\"siteTitle\":\"req-kit\",\"nav\":[{\"text\":\"指南\",\"link\":\"/guide/\",\"activeMatch\":\"^/guide/\"},{\"text\":\"参考\",\"link\":\"/reference/commands\",\"activeMatch\":\"^/reference/\"},{\"text\":\"更新记录\",\"link\":\"/changelog\"},{\"text\":\"v1.14.0-beta.2\",\"items\":[{\"text\":\"更新记录\",\"link\":\"/changelog\"},{\"text\":\"GitHub Releases\",\"link\":\"https://github.com/yiyisf/paseo-req-kit/releases\"},{\"text\":\"范围与取舍\",\"link\":\"/reference/scope\"}]}],\"sidebar\":{\"/guide/\":[{\"text\":\"开始\",\"items\":[{\"text\":\"req-kit 是什么\",\"link\":\"/guide/\"},{\"text\":\"快速开始\",\"link\":\"/guide/getting-started\"},{\"text\":\"工作原理\",\"link\":\"/guide/how-it-works\"}]},{\"text\":\"使用\",\"items\":[{\"text\":\"使用者指南\",\"link\":\"/guide/user\"},{\"text\":\"分阶段执行与提测\",\"link\":\"/guide/phases\"}]},{\"text\":\"安装与维护\",\"items\":[{\"text\":\"安装与升级\",\"link\":\"/guide/install\"},{\"text\":\"项目定制与运行规则\",\"link\":\"/guide/project\"},{\"text\":\"维护者指南\",\"link\":\"/guide/maintainer\"}]}],\"/reference/\":[{\"text\":\"参考\",\"items\":[{\"text\":\"命令\",\"link\":\"/reference/commands\"},{\"text\":\"配置项\",\"link\":\"/reference/config\"},{\"text\":\"范围与取舍\",\"link\":\"/reference/scope\"}]},{\"text\":\"文件格式约定\",\"collapsed\":false,\"items\":[{\"text\":\"总览\",\"link\":\"/reference/contracts/\"},{\"text\":\"需求说明 spec.md\",\"link\":\"/reference/contracts/spec\"},{\"text\":\"状态文件 state.json\",\"link\":\"/reference/contracts/state\"},{\"text\":\"结果文件\",\"link\":\"/reference/contracts/result-file\"},{\"text\":\"功能目录中的文件\",\"link\":\"/reference/contracts/feature-files\"},{\"text\":\"验证方法 verify.md\",\"link\":\"/reference/contracts/verify\"},{\"text\":\"外部通知事件\",\"link\":\"/reference/contracts/notifier-event\"},{\"text\":\"req api 的 JSON 输出\",\"link\":\"/reference/contracts/cli-json\"},{\"text\":\"需求索引与使用记录\",\"link\":\"/reference/contracts/usage-record\"}]},{\"text\":\"设计决定(ADR)\",\"collapsed\":true,\"items\":[{\"text\":\"总览\",\"link\":\"/reference/adr/\"},{\"text\":\"0001 步骤 agent 挂在发起的对话下\",\"link\":\"/reference/adr/0001-step-agents-under-origin-chat\"},{\"text\":\"0002 对话过程中不切换工作目录\",\"link\":\"/reference/adr/0002-no-directory-switch-in-chat\"},{\"text\":\"0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流\",\"link\":\"/reference/adr/0003-script-engine-not-hub\"},{\"text\":\"0004 步骤结论只看结果文件\",\"link\":\"/reference/adr/0004-result-files\"},{\"text\":\"0005 不在默认分支上运行,只做本地提交\",\"link\":\"/reference/adr/0005-no-default-branch-local-commits-only\"},{\"text\":\"0006 只安装到 ~/.agents/skills 和 ~/.claude/skills\",\"link\":\"/reference/adr/0006-skill-install-targets\"},{\"text\":\"0007 自带需求访谈 skill,不依赖外部 skill 包\",\"link\":\"/reference/adr/0007-own-interview-skill\"},{\"text\":\"0008 入口 skill 之间不互相调用\",\"link\":\"/reference/adr/0008-entries-do-not-call-entries\"},{\"text\":\"0009 程序与本机配置分开存放,按版本目录并存\",\"link\":\"/reference/adr/0009-versioned-install-layout\"},{\"text\":\"0010 需求总览现场生成,不维护 INDEX.md\",\"link\":\"/reference/adr/0010-generated-feature-overview\"},{\"text\":\"0011 完成后修改 spec 可以继续开发\",\"link\":\"/reference/adr/0011-resume-after-completion\"},{\"text\":\"0012 评审小组:首轮并行评审,评审者核实汇总\",\"link\":\"/reference/adr/0012-review-panel\"},{\"text\":\"0013 发布不使用 changesets 等工具\",\"link\":\"/reference/adr/0013-no-release-tooling\"},{\"text\":\"0014 外部通知只留接口,不内置任何 IM\",\"link\":\"/reference/adr/0014-notifier-slot\"},{\"text\":\"0015 需求变更后增量继续,而不是从零重做\",\"link\":\"/reference/adr/0015-incremental-continue\"},{\"text\":\"0016 一键升级:从 git 标签下载到 versions/ 再切换\",\"link\":\"/reference/adr/0016-upgrade-from-tags\"},{\"text\":\"0017 用好 Paseo 自身的能力:profile、工作区脚本、用量和时间线\",\"link\":\"/reference/adr/0017-use-paseo-capabilities\"},{\"text\":\"0018 可选:流水线为需求新建 worktree 工作区\",\"link\":\"/reference/adr/0018-own-worktree-option\"},{\"text\":\"0019 用 Paseo 的并行子 agent:确认前独立审阅、方案提案\",\"link\":\"/reference/adr/0019-parallel-orchestration\"},{\"text\":\"0020 调度:用 Paseo 定时任务把消息发回对话,排队在本机进行\",\"link\":\"/reference/adr/0020-scheduling-through-the-chat\"},{\"text\":\"0021 npm 分发:全局包是版本管理器,各版本仍装在 versions/ 下\",\"link\":\"/reference/adr/0021-npm-version-manager\"},{\"text\":\"0022 分阶段执行:研发阶段、闸口、测试验证阶段\",\"link\":\"/reference/adr/0022-develop-and-verify-phases\"},{\"text\":\"0023 需求类型、质量门、按切片实现\",\"link\":\"/reference/adr/0023-types-gate-slices\"},{\"text\":\"0024 让分歧更早暴露:验收例子、方案确认点、两个方向的评审、反复的问题变成规则\",\"link\":\"/reference/adr/0024-confirm-early-review-axes\"},{\"text\":\"0025 联合需求:一个需求同时改几个仓库\",\"link\":\"/reference/adr/0025-joint-requirements\"},{\"text\":\"0026 本机的需求索引、使用记录和 req api\",\"link\":\"/reference/adr/0026-machine-records-and-api\"},{\"text\":\"0027 Paseo 插件:随 req-kit 一起发布,只通过 req api 工作\",\"link\":\"/reference/adr/0027-paseo-plugin\"},{\"text\":\"0028 外部系统对接:命令写法在配置里,内容由 AI 整理,调用是确定的\",\"link\":\"/reference/adr/0028-external-integrations\"},{\"text\":\"0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话\",\"link\":\"/reference/adr/0029-requirements-from-cards\"},{\"text\":\"0030 接单器:共享机器上定时接卡片、转达回复\",\"link\":\"/reference/adr/0030-card-intake-process\"},{\"text\":\"0031 少等人:每种中断都有自动的下一步\",\"link\":\"/reference/adr/0031-fewer-interventions\"},{\"text\":\"0032 安装、升级和文档只依赖 npm 源\",\"link\":\"/reference/adr/0032-npm-only-install\"},{\"text\":\"0033 原型审查页和不靠看图的界面检查\",\"link\":\"/reference/adr/0033-prototype-review-and-ui-check\"}]}]},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/yiyisf/paseo-req-kit\"}],\"editLink\":{\"pattern\":\"https://github.com/yiyisf/paseo-req-kit/edit/main/site/:path\",\"text\":\"在 GitHub 上编辑此页\"},\"footer\":{\"message\":\"以 MIT 许可发布。req-kit 是运行在 Paseo 上的社区项目。\",\"copyright\":\"Copyright © 2026 yiyisf\"},\"search\":{\"provider\":\"local\",\"options\":{\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"noResultsText\":\"没有找到相关结果\",\"resetButtonTitle\":\"清除\",\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\",\"closeText\":\"关闭\"}}}}},\"outline\":{\"level\":[2,3],\"label\":\"本页内容\"},\"docFooter\":{\"prev\":\"上一页\",\"next\":\"下一页\"},\"lastUpdated\":{\"text\":\"最后更新\"},\"returnToTopLabel\":\"回到顶部\",\"sidebarMenuLabel\":\"目录\",\"darkModeSwitchLabel\":\"外观\",\"lightModeSwitchTitle\":\"切换到浅色\",\"darkModeSwitchTitle\":\"切换到深色\",\"externalLinkIcon\":true,\"notFound\":{\"title\":\"页面不存在\",\"quote\":\"这个页面可能已经移动或删除。\",\"linkText\":\"回到首页\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":true}");</script>
25
25
 
26
26
  </body>
27
27
  </html>
@@ -1 +1 @@
1
- import{R as p}from"./chunks/theme.BP9XiatK.js";import{R as s,a4 as i,a5 as u,a6 as c,a7 as l,a8 as f,a9 as d,aa as m,ab as h,ac as g,ad as A,d as v,u as R,v as w,s as y,ae as C,af as P,ag as b,a2 as E}from"./chunks/framework.B9qR_F1m.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),P(),b(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};
1
+ import{R as p}from"./chunks/theme.CZzkCOAC.js";import{R as s,a4 as i,a5 as u,a6 as c,a7 as l,a8 as f,a9 as d,aa as m,ab as h,ac as g,ad as A,d as v,u as R,v as w,s as y,ae as C,af as P,ag as b,a2 as E}from"./chunks/framework.B9qR_F1m.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),P(),b(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};