paseo-req-kit 1.13.0-beta.2 → 1.13.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 (86) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/docs/guide//344/275/277/347/224/250/350/200/205/346/214/207/345/215/227.md +1 -1
  3. 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 +2 -2
  4. package/engine/src/messages.ts +7 -2
  5. package/engine/src/review.ts +14 -3
  6. package/package.json +1 -1
  7. package/paseo-plugin/client/detail.tsx +4 -5
  8. package/paseo-plugin/client/inbox.tsx +4 -3
  9. package/paseo-plugin/client/nav.ts +12 -0
  10. package/paseo-plugin/client/review.tsx +46 -0
  11. package/paseo-plugin/client/web.ts +17 -0
  12. package/paseo-plugin/index.client.tsx +4 -0
  13. package/paseo-plugin/package.json +1 -1
  14. package/site-dist/404.html +2 -2
  15. package/site-dist/assets/{app.DWPPPhFm.js → app.8viPUf6o.js} +1 -1
  16. package/site-dist/assets/changelog.md.fsAikR0t.js +1 -0
  17. package/site-dist/assets/chunks/@localSearchIndexroot.D_9Dq76F.js +1 -0
  18. package/site-dist/assets/chunks/{VPLocalSearchBox.D3_9dRGY.js → VPLocalSearchBox.C-itfeI3.js} +1 -1
  19. package/site-dist/assets/chunks/{theme.Bm8aLiLN.js → theme.CmA1-Qwc.js} +2 -2
  20. package/site-dist/assets/{guide_getting-started.md.B4GJeoPz.js → guide_getting-started.md.DU5hdLl6.js} +1 -1
  21. package/site-dist/assets/{guide_project.md.nGlTCo4D.js → guide_project.md.Cc6JFJ5R.js} +1 -1
  22. package/site-dist/assets/{guide_project.md.nGlTCo4D.lean.js → guide_project.md.Cc6JFJ5R.lean.js} +1 -1
  23. package/site-dist/assets/{guide_user.md.tiHFxIsQ.js → guide_user.md.8tCspVEK.js} +1 -1
  24. package/site-dist/changelog.html +5 -5
  25. package/site-dist/guide/getting-started.html +5 -5
  26. package/site-dist/guide/how-it-works.html +4 -4
  27. package/site-dist/guide/index.html +4 -4
  28. package/site-dist/guide/install.html +4 -4
  29. package/site-dist/guide/maintainer.html +4 -4
  30. package/site-dist/guide/phases.html +4 -4
  31. package/site-dist/guide/project.html +5 -5
  32. package/site-dist/guide/user.html +5 -5
  33. package/site-dist/hashmap.json +1 -1
  34. package/site-dist/index.html +4 -4
  35. package/site-dist/reference/adr/0001-step-agents-under-origin-chat.html +4 -4
  36. package/site-dist/reference/adr/0002-no-directory-switch-in-chat.html +4 -4
  37. package/site-dist/reference/adr/0003-script-engine-not-hub.html +4 -4
  38. package/site-dist/reference/adr/0004-result-files.html +4 -4
  39. package/site-dist/reference/adr/0005-no-default-branch-local-commits-only.html +4 -4
  40. package/site-dist/reference/adr/0006-skill-install-targets.html +4 -4
  41. package/site-dist/reference/adr/0007-own-interview-skill.html +4 -4
  42. package/site-dist/reference/adr/0008-entries-do-not-call-entries.html +4 -4
  43. package/site-dist/reference/adr/0009-versioned-install-layout.html +4 -4
  44. package/site-dist/reference/adr/0010-generated-feature-overview.html +4 -4
  45. package/site-dist/reference/adr/0011-resume-after-completion.html +4 -4
  46. package/site-dist/reference/adr/0012-review-panel.html +4 -4
  47. package/site-dist/reference/adr/0013-no-release-tooling.html +4 -4
  48. package/site-dist/reference/adr/0014-notifier-slot.html +4 -4
  49. package/site-dist/reference/adr/0015-incremental-continue.html +4 -4
  50. package/site-dist/reference/adr/0016-upgrade-from-tags.html +4 -4
  51. package/site-dist/reference/adr/0017-use-paseo-capabilities.html +4 -4
  52. package/site-dist/reference/adr/0018-own-worktree-option.html +4 -4
  53. package/site-dist/reference/adr/0019-parallel-orchestration.html +4 -4
  54. package/site-dist/reference/adr/0020-scheduling-through-the-chat.html +4 -4
  55. package/site-dist/reference/adr/0021-npm-version-manager.html +4 -4
  56. package/site-dist/reference/adr/0022-develop-and-verify-phases.html +4 -4
  57. package/site-dist/reference/adr/0023-types-gate-slices.html +4 -4
  58. package/site-dist/reference/adr/0024-confirm-early-review-axes.html +4 -4
  59. package/site-dist/reference/adr/0025-joint-requirements.html +4 -4
  60. package/site-dist/reference/adr/0026-machine-records-and-api.html +4 -4
  61. package/site-dist/reference/adr/0027-paseo-plugin.html +4 -4
  62. package/site-dist/reference/adr/0028-external-integrations.html +4 -4
  63. package/site-dist/reference/adr/0029-requirements-from-cards.html +4 -4
  64. package/site-dist/reference/adr/0030-card-intake-process.html +4 -4
  65. package/site-dist/reference/adr/0031-fewer-interventions.html +4 -4
  66. package/site-dist/reference/adr/0032-npm-only-install.html +4 -4
  67. package/site-dist/reference/adr/0033-prototype-review-and-ui-check.html +4 -4
  68. package/site-dist/reference/adr/index.html +4 -4
  69. package/site-dist/reference/commands.html +4 -4
  70. package/site-dist/reference/config.html +4 -4
  71. package/site-dist/reference/contracts/cli-json.html +4 -4
  72. package/site-dist/reference/contracts/feature-files.html +4 -4
  73. package/site-dist/reference/contracts/index.html +4 -4
  74. package/site-dist/reference/contracts/notifier-event.html +4 -4
  75. package/site-dist/reference/contracts/result-file.html +4 -4
  76. package/site-dist/reference/contracts/spec.html +4 -4
  77. package/site-dist/reference/contracts/state.html +4 -4
  78. package/site-dist/reference/contracts/usage-record.html +4 -4
  79. package/site-dist/reference/contracts/verify.html +4 -4
  80. package/site-dist/reference/scope.html +4 -4
  81. package/paseo-plugin/client/review-link.tsx +0 -29
  82. package/site-dist/assets/changelog.md.CoelFFCL.js +0 -1
  83. package/site-dist/assets/chunks/@localSearchIndexroot.Hdq0-4L3.js +0 -1
  84. /package/site-dist/assets/{changelog.md.CoelFFCL.lean.js → changelog.md.fsAikR0t.lean.js} +0 -0
  85. /package/site-dist/assets/{guide_getting-started.md.B4GJeoPz.lean.js → guide_getting-started.md.DU5hdLl6.lean.js} +0 -0
  86. /package/site-dist/assets/{guide_user.md.tiHFxIsQ.lean.js → guide_user.md.8tCspVEK.lean.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  每个版本分为"使用者会看到的变化"和"升级须知"。升级步骤见 [docs/guide/安装与升级.md](docs/guide/安装与升级.md)。
4
4
 
5
+ ## 1.13.0-beta.3
6
+
7
+ ### 使用者会看到的变化
8
+
9
+ - **原型审查页在 Paseo 里打开**:网页端和桌面端不再跳到单独的浏览器窗口,审查页嵌在插件的"审查原型"页面中;手机上仍在浏览器中打开,页面右上角也可以"在新窗口打开"。
10
+ - **按钮更醒目**:"等你处理"和需求页面最上面,有原型的方案确认显示为主按钮"审查原型并确认方案"("确认方案"变为次要按钮);没在等确认时也有"审查原型"按钮。请你确认方案的对话消息也会告诉你去点这个按钮。
11
+
12
+ ### 升级须知
13
+
14
+ - 审查页现在允许被本机地址上的页面嵌入(`frame-ancestors`);从别的电脑访问时(设了 `REQ_KIT_REVIEW_HOST`)允许任何页面嵌入,地址中的令牌仍是访问的唯一凭证。可以用 `REQ_KIT_REVIEW_FRAME_ANCESTORS` 指定。
15
+
5
16
  ## 1.13.0-beta.2
6
17
 
7
18
  在 Paseo 网页端审查原型,界面验证不再依赖桌面端和模型的视觉能力。见 [ADR 0033](docs/adr/0033-prototype-review-and-ui-check.md)。
@@ -64,7 +64,7 @@ req-kit 帮你把一个需求从"我想要……"做到"可以验收":你在 P
64
64
 
65
65
  1.12 起,首页最上面是"等你处理":所有等你确认方案、回答问题、中断了的需求,等得最久的在前,每条写明要做什么、等了多久。方案可以直接确认,也可以写修改意见;方案审核的问题可以直接写回答,插件会转给这个需求的对话,效果和在对话里回答一样。首页的"配置"列出 req-kit 的全部设置:每一项是什么、现在的值、来自本机、团队还是项目的配置文件,可以按项目查看、搜索、只看改过的。
66
66
 
67
- **在原型上提意见(1.13 起)。** 界面改动的需求,在请你确认方案时会有一份界面原型。在插件的需求页面或"等你处理"里点"打开原型审查页"(或在终端运行 `req review <需求>`),会在浏览器里打开它:
67
+ **在原型上提意见(1.13 起)。** 界面改动的需求,在请你确认方案时会有一份界面原型。在插件首页的"等你处理"或需求页面最上面,点**"审查原型并确认方案"**按钮(终端里是 `req review <需求>`),原型审查页就在 Paseo 里打开(手机上会在浏览器中打开;嫌窗口小时点右上角"在新窗口打开"):
68
68
 
69
69
  - 标着 ①②③ 的是这次要改的地方,右边写着各自对应的验收标准,顺着看就不会漏。
70
70
  - 想改哪里就**点哪里**,选一种改法(文字改成…、大一点、换颜色、换位置、删掉、这里加东西……),再用自己的话补一句。不用想专业词汇,你点的是哪个按钮、原来是什么颜色和大小,页面会自动记下来交给 AI。
@@ -43,11 +43,11 @@ spec 头部的 `- 类型:` 决定流水线走哪种做法(1.8 起)。缺
43
43
 
44
44
  等待确认时进度显示"等待需求方确认方案",需求总览归入"需要处理",外部通知收到 `approval` 事件。评估类需求不写代码,不经过确认点。
45
45
 
46
- **原型审查页(1.13 起)。** 有 `prototype/` 的需求,插件的需求页面和"等你处理"里有"打开原型审查页",终端里是 `req review <需求>`。需求方在原型上点选要改的地方(页面记下元素、文字、颜色、大小和位置)、双击直接改文字,切换状态和电脑、手机宽度,然后提交:意见整理成带位置信息的清单转给需求会话(与插件中写修改意见的效果相同),或者直接确认方案。草稿和提交记录在功能目录的 `.pipeline/review/` 中,每一版原型也存在那里,原型改过后页面会标出这一版改了哪里。
46
+ **原型审查页(1.13 起)。** 有 `prototype/` 的需求,插件的需求页面和"等你处理"里有"审查原型"按钮(等待确认方案时是最醒目的"审查原型并确认方案"),审查页嵌在 Paseo 的网页端和桌面端里打开,手机上在浏览器中打开;终端里是 `req review <需求>`。需求方在原型上点选要改的地方(页面记下元素、文字、颜色、大小和位置)、双击直接改文字,切换状态和电脑、手机宽度,然后提交:意见整理成带位置信息的清单转给需求会话(与插件中写修改意见的效果相同),或者直接确认方案。草稿和提交记录在功能目录的 `.pipeline/review/` 中,每一版原型也存在那里,原型改过后页面会标出这一版改了哪里。
47
47
 
48
48
  为了让审查页能用,方案设计按约定写原型:每个改动区域标 `data-ac`(对应的 AC)和 `data-label`(用需求方的话说是什么),各种状态包在 `<section data-state="状态名">` 中,按钮、标题、字段名写最终的文字。原型里的脚本不会运行。
49
49
 
50
- 审查页由一个本机服务提供:用到时在后台启动,空闲 4 小时后自己退出,只监听 `127.0.0.1`,地址中带随机令牌(插件设为只读时给只读的地址)。需求方在别的电脑上用浏览器访问 Paseo 网页端时,在运行 Paseo daemon 的机器上设置环境变量 `REQ_KIT_REVIEW_HOST`(例如 `0.0.0.0`)、`REQ_KIT_REVIEW_PUBLIC_URL`(别人访问这台机器用的地址,例如 `http://10.1.2.3:6781`),需要时用 `REQ_KIT_REVIEW_PORT` 换端口(默认 6781),然后重启 Paseo daemon 让插件拿到新的环境变量。
50
+ 审查页由一个本机服务提供:用到时在后台启动,空闲 4 小时后自己退出,只监听 `127.0.0.1`,地址中带随机令牌(插件设为只读时给只读的地址)。审查页允许被本机地址上的页面(Paseo 网页端)嵌入;要限定或放开,设 `REQ_KIT_REVIEW_FRAME_ANCESTORS`(CSP `frame-ancestors` 的值)。需求方在别的电脑上用浏览器访问 Paseo 网页端时,在运行 Paseo daemon 的机器上设置环境变量 `REQ_KIT_REVIEW_HOST`(例如 `0.0.0.0`)、`REQ_KIT_REVIEW_PUBLIC_URL`(别人访问这台机器用的地址,例如 `http://10.1.2.3:6781`),需要时用 `REQ_KIT_REVIEW_PORT` 换端口(默认 6781),然后重启 Paseo daemon 让插件拿到新的环境变量。
51
51
 
52
52
  ## 代码评审分两个方向
53
53
 
@@ -352,10 +352,15 @@ export function approvalMessage(input: {
352
352
  `功能目录:${input.featureDir}`,
353
353
  "情况:方案已经通过审核,还没有开始写代码。开发前请需求方确认\"做完之后会看到什么\",这时调整的成本最低。",
354
354
  `- 做完后你会看到什么:${input.previewPath}`,
355
- ...(input.prototypePath ? [`- 界面原型:${input.prototypePath}(静态页面,可以在浏览器中打开)`] : []),
355
+ ...(input.prototypePath
356
+ ? [
357
+ `- 界面原型:${input.prototypePath}`,
358
+ `- 原型审查页:在 Paseo 侧边栏的"需求"中打开这个需求,点"审查原型"("等你处理"里也有),可以直接在原型上点选要改的地方、双击改文字,提交意见或确认方案;终端里是 req review ${input.featureDir.split("/").pop()}`,
359
+ ]
360
+ : []),
356
361
  "",
357
362
  "请这样处理:",
358
- "1. 读 preview.md,用几句话把要点讲给用户:会看到的变化、主要的假设(尤其是影响界面、数据、权限的),有原型就告诉用户在哪里看。",
363
+ "1. 读 preview.md,用几句话把要点讲给用户:会看到的变化、主要的假设(尤其是影响界面、数据、权限的)。有原型时,请用户点 Paseo 侧边栏\"需求\"里这个需求的\"审查原型\"按钮去看:在原型上点选提意见比用文字描述准确,提交的意见会转回这个对话。",
359
364
  "2. 问用户:按这个做,还是有要改的地方?",
360
365
  `3. 用户确认后,执行下面的命令继续开发:\n\n${input.approveCommand}`,
361
366
  "4. 用户要改的:按需求对齐时的方式问清楚,把结论记入 alignment.md,更新 spec.md(顶部\"版本\"加 1,在 changes.md 中记一节,原因写\"方案确认时的修改\"),请用户再次确认需求说明,然后执行下面的命令,流水线会从方案设计开始按修改后的需求调整方案,再请用户确认一次:",
@@ -237,11 +237,22 @@ function inside(base: string, rel: string): string | null {
237
237
  return target === base || target.startsWith(base + path.sep) ? target : null;
238
238
  }
239
239
 
240
+ // The page may be shown inside Paseo (the req-kit plugin embeds it): Paseo's web UI on this
241
+ // machine, or, with REQ_KIT_REVIEW_HOST set for other computers, any page that has the token.
242
+ function appCsp(): string {
243
+ const host = process.env.REQ_KIT_REVIEW_HOST?.trim();
244
+ const local = !host || host === "127.0.0.1" || host === "localhost" || host === "::1";
245
+ const custom = process.env.REQ_KIT_REVIEW_FRAME_ANCESTORS?.trim();
246
+ // 'self' always: the page shows the prototype in a frame of its own.
247
+ const ancestors = custom ? (custom.includes("'self'") || custom === "*" ? custom : `'self' ${custom}`) : local ? "'self' http://127.0.0.1:* http://localhost:* http://[::1]:*" : "*";
248
+ return `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors ${ancestors}`;
249
+ }
250
+ const APP_CSP = appCsp();
240
251
  // Prototypes are written by an agent (from text the requester or a card supplied) and are served
241
252
  // next to the page's own API, so nothing in them may run: the page reads them from outside.
242
- const PROTOTYPE_CSP =
243
- "default-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; media-src 'self' data:; script-src 'none'; form-action 'none'; frame-ancestors 'self'";
244
- const APP_CSP = "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'";
253
+ // frame-ancestors is checked against every page above, so the prototype allows the same ones as
254
+ // the review page (Paseo around it).
255
+ const PROTOTYPE_CSP = `default-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; media-src 'self' data:; script-src 'none'; form-action 'none'; ${APP_CSP.slice(APP_CSP.indexOf("frame-ancestors"))}`;
245
256
 
246
257
  function send(res: http.ServerResponse, status: number, body: string | Buffer, type = "text/plain; charset=utf-8", csp = APP_CSP) {
247
258
  res.writeHead(status, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paseo-req-kit",
3
- "version": "1.13.0-beta.2",
3
+ "version": "1.13.0-beta.3",
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",
@@ -9,7 +9,7 @@ import type { Action, RequirementDetail, Step } from "../shared/contracts";
9
9
  import { useAction, useDocument, usePreferences, useRequirement, useRequirements } from "./data";
10
10
  import { ACTION_TEXT, actionsFor, ago, ATTENTION_LABELS, facts, FILE_LABELS, minutes, tokens } from "./format";
11
11
  import { Markdown, tsvToMarkdown } from "./markdown";
12
- import { ReviewLink } from "./review-link";
12
+ import { ReviewButton } from "./review";
13
13
  import { Badge, Button, Chip, Status, useStyles } from "./ui";
14
14
 
15
15
  type Theme = PluginHostProps["theme"];
@@ -185,16 +185,15 @@ export function RequirementView({
185
185
  {d.attention === "business" ? <Text style={s.muted}>需求方的决定请在发起需求的对话中回答,回答后再继续。</Text> : null}
186
186
  </View>
187
187
 
188
- {actions.length > 0 ? (
188
+ {actions.length > 0 || d.hasPrototype ? (
189
189
  <View style={s.row}>
190
+ {d.hasPrototype ? <ReviewButton theme={theme} repo={d.sourceRepo ?? d.repo} featureDir={d.featureDir} title={d.title} waiting={d.attention === "approval"} /> : null}
190
191
  {actions.map((a) => (
191
- <Button key={a} theme={theme} primary={a !== "stop"} label={ACTION_TEXT[a].label} onPress={() => setAction(a)} />
192
+ <Button key={a} theme={theme} primary={a !== "stop" && !(a === "approve" && d.hasPrototype)} label={ACTION_TEXT[a].label} onPress={() => setAction(a)} />
192
193
  ))}
193
194
  </View>
194
195
  ) : null}
195
196
 
196
- {d.hasPrototype ? <ReviewLink theme={theme} compact={layout.compact} repo={d.sourceRepo ?? d.repo} featureDir={d.featureDir} waiting={d.attention === "approval"} /> : null}
197
-
198
197
  {d.files.length > 0 ? (
199
198
  <View style={{ gap: 6 }}>
200
199
  <Text style={s.heading}>文档</Text>
@@ -8,7 +8,7 @@ import { Text, View } from "react-native";
8
8
  import type { Attention, Requirement } from "../shared/contracts";
9
9
  import { useAction, usePreferences } from "./data";
10
10
  import { facts } from "./format";
11
- import { ReviewLink } from "./review-link";
11
+ import { ReviewButton } from "./review";
12
12
  import { Badge, Button, useStyles } from "./ui";
13
13
 
14
14
  type Theme = PluginHostProps["theme"];
@@ -99,7 +99,7 @@ function InboxCard({ theme, layout, item, open, readOnly }: { theme: Theme; layo
99
99
  </View>
100
100
  ) : (
101
101
  <>
102
- {item.attention === "approval" && item.hasPrototype ? <ReviewLink theme={theme} compact={layout.compact} repo={repo} featureDir={item.featureDir} waiting /> : null}
102
+ {item.attention === "approval" && item.hasPrototype ? <Text style={s.text}>这个方案有界面原型:在原型上点选要改的地方,比写文字说得清楚。</Text> : null}
103
103
  {writing && w?.canReply ? (
104
104
  <View style={{ gap: 8 }}>
105
105
  <TextInput
@@ -126,7 +126,8 @@ function InboxCard({ theme, layout, item, open, readOnly }: { theme: Theme; layo
126
126
  <View style={s.row}>
127
127
  {item.attention === "approval" ? (
128
128
  <>
129
- <Button theme={theme} primary label={run.isPending ? "正在执行…" : "确认方案"} disabled={run.isPending} onPress={() => void act("approve")} />
129
+ {item.hasPrototype ? <ReviewButton theme={theme} repo={repo} featureDir={item.featureDir} title={item.title} waiting /> : null}
130
+ <Button theme={theme} primary={!item.hasPrototype} label={run.isPending ? "正在执行…" : "确认方案"} disabled={run.isPending} onPress={() => void act("approve")} />
130
131
  {w?.canReply ? (
131
132
  writing ? (
132
133
  <Button theme={theme} label="发送修改意见" disabled={run.isPending || !text.trim()} onPress={() => void act("reply")} />
@@ -0,0 +1,12 @@
1
+ // Opening the plugin's screens from anywhere in it (screens themselves are not handed an opener).
2
+ type Opener = (input: { screenId: string; params?: Record<string, string> }) => void;
3
+
4
+ let opener: Opener | null = null;
5
+
6
+ export function setScreenOpener(open: Opener): void {
7
+ opener = open;
8
+ }
9
+
10
+ export function openReview(input: { repo: string; featureDir: string; title: string }): void {
11
+ opener?.({ screenId: "review", params: { repo: input.repo, featureDir: input.featureDir, title: input.title } });
12
+ }
@@ -0,0 +1,46 @@
1
+ // "审查原型" (1.13): the prototype review page inside Paseo. On the web and desktop apps it is
2
+ // embedded in this screen; on phones (and as a fallback) it opens in the browser.
3
+ import type { PluginHostProps, PluginScreenProps } from "@getpaseo/plugin/client";
4
+ import { ExternalLink } from "@getpaseo/plugin/client/ui";
5
+ import { Text, View } from "react-native";
6
+ import { useReviewUrl } from "./data";
7
+ import { openReview } from "./nav";
8
+ import { Button, Status, useStyles } from "./ui";
9
+ import { canEmbedPages, embeddedPage } from "./web";
10
+
11
+ type Theme = PluginHostProps["theme"];
12
+
13
+ /** The button on a requirement with a prototype: primary while the design waits for confirmation. */
14
+ export function ReviewButton({ theme, repo, featureDir, title, waiting }: { theme: Theme; repo: string; featureDir: string; title: string; waiting: boolean }) {
15
+ return <Button theme={theme} primary={waiting} label={waiting ? "审查原型并确认方案" : "审查原型"} onPress={() => openReview({ repo, featureDir, title })} />;
16
+ }
17
+
18
+ export function ReviewScreen({ theme, layout, params }: PluginScreenProps) {
19
+ const s = useStyles(theme, layout.compact);
20
+ const repo = params.repo ?? "";
21
+ const featureDir = params.featureDir ?? "";
22
+ const review = useReviewUrl(repo, featureDir, true);
23
+ if (!review.data) {
24
+ return (
25
+ <View style={[s.screen, { padding: 16 }]}>
26
+ <Status theme={theme} loading={review.isPending} error={review.error} />
27
+ </View>
28
+ );
29
+ }
30
+ const { url, readOnly } = review.data;
31
+ const frame = canEmbedPages ? embeddedPage(url, `原型审查:${params.title ?? featureDir}`) : null;
32
+ return (
33
+ <View style={[s.screen, { gap: 6 }]}>
34
+ <View style={[s.row, { paddingHorizontal: 12, paddingTop: 8, justifyContent: "space-between" }]}>
35
+ <Text style={s.muted}>{readOnly ? "插件设为只读:可以看原型,不能提交意见或确认。" : "点原型上要改的地方提意见,双击文字直接改字;看完在右下角提交或确认方案。"}</Text>
36
+ <ExternalLink href={url}>在新窗口打开</ExternalLink>
37
+ </View>
38
+ {frame ?? (
39
+ <View style={[s.card, { margin: 12, gap: 8 }]}>
40
+ <Text style={s.text}>原型审查页在浏览器中打开效果最好(手机上屏幕较小,建议用电脑)。</Text>
41
+ <ExternalLink href={url}>打开原型审查页</ExternalLink>
42
+ </View>
43
+ )}
44
+ </View>
45
+ );
46
+ }
@@ -0,0 +1,17 @@
1
+ // The only file that uses web-only things (Paseo's rule for plugins): the prototype review page
2
+ // shown inside Paseo, in an iframe, on the web app and the desktop app. Phones get null and
3
+ // the screen offers a link instead.
4
+ import { createElement, type ReactElement } from "react";
5
+ import { Platform } from "react-native";
6
+
7
+ export const canEmbedPages = Platform.OS === "web";
8
+
9
+ export function embeddedPage(url: string, title: string): ReactElement | null {
10
+ if (Platform.OS !== "web") return null;
11
+ return createElement("iframe" as string, {
12
+ src: url,
13
+ title,
14
+ allow: "clipboard-read; clipboard-write",
15
+ style: { border: 0, width: "100%", height: "calc(100vh - 120px)", minHeight: 560, display: "block", background: "transparent" },
16
+ } as Record<string, unknown>);
17
+ }
@@ -2,7 +2,9 @@ import type { PluginClientContext, PluginScreenProps } from "@getpaseo/plugin/cl
2
2
  import { ConfigScreen } from "./client/config";
3
3
  import { RequirementScreen } from "./client/detail";
4
4
  import { contributeLive } from "./client/live";
5
+ import { setScreenOpener } from "./client/nav";
5
6
  import { OverviewScreen } from "./client/overview";
7
+ import { ReviewScreen } from "./client/review";
6
8
  import { WorkspacePanel } from "./client/panel";
7
9
  import { SettingsScreen } from "./client/settings";
8
10
  import { RequirementsItem } from "./client/sidebar";
@@ -10,11 +12,13 @@ import { StatsScreen } from "./client/stats";
10
12
 
11
13
  export default function contribute(client: PluginClientContext) {
12
14
  const openScreen = (input: { screenId: string; params?: Record<string, string> }) => client.openScreen(input);
15
+ setScreenOpener(openScreen);
13
16
  const Overview = (props: PluginScreenProps) => <OverviewScreen {...props} openScreen={openScreen} />;
14
17
 
15
18
  client.addScreen({ id: "overview", title: "需求", Component: Overview });
16
19
  client.addScreen({ id: "requirement", title: (params) => params.title || params.name || "需求", Component: RequirementScreen });
17
20
  client.addScreen({ id: "stats", title: "需求统计", Component: StatsScreen });
21
+ client.addScreen({ id: "review", title: (params) => `审查原型:${params.title || params.featureDir?.split("/").pop() || ""}`, Component: ReviewScreen });
18
22
  client.addScreen({ id: "config", title: "req-kit 配置", Component: ConfigScreen });
19
23
  client.addSidebarHeaderItem({ id: "requirements", title: "需求(req-kit)", Component: RequirementsItem });
20
24
  client.addWorkspacePanel({
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "req-kit-paseo-plugin",
3
- "version": "1.13.0-beta.2",
3
+ "version": "1.13.0-beta.3",
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",
@@ -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.DWPPPhFm.js"></script>
12
+ <script type="module" src="/assets/app.8viPUf6o.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\":\"CoelFFCL\",\"guide_getting-started.md\":\"B4GJeoPz\",\"guide_how-it-works.md\":\"D-kQsF1t\",\"guide_index.md\":\"CLnGCmGW\",\"guide_install.md\":\"DkCyZsOU\",\"guide_maintainer.md\":\"RZIzyCTV\",\"guide_phases.md\":\"BpGAb1re\",\"guide_project.md\":\"nGlTCo4D\",\"guide_user.md\":\"tiHFxIsQ\",\"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\":\"N-v2HNUd\",\"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\":\"5bNTC3ow\",\"reference_contracts_usage-record.md\":\"_C0OXWeq\",\"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-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>
24
+ <script>window.__VP_HASH_MAP__=JSON.parse("{\"changelog.md\":\"fsAikR0t\",\"guide_getting-started.md\":\"DU5hdLl6\",\"guide_how-it-works.md\":\"D-kQsF1t\",\"guide_index.md\":\"CLnGCmGW\",\"guide_install.md\":\"DkCyZsOU\",\"guide_maintainer.md\":\"RZIzyCTV\",\"guide_phases.md\":\"BpGAb1re\",\"guide_project.md\":\"Cc6JFJ5R\",\"guide_user.md\":\"8tCspVEK\",\"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\":\"N-v2HNUd\",\"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\":\"5bNTC3ow\",\"reference_contracts_usage-record.md\":\"_C0OXWeq\",\"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-beta.3\",\"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.Bm8aLiLN.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.CmA1-Qwc.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};