paseo-req-kit 1.14.0 → 1.15.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 (219) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/docs/guide//347/273/264/346/212/244/350/200/205/346/214/207/345/215/227.md +2 -0
  3. package/engine/src/review-assets/app.css +153 -234
  4. package/engine/src/review-assets/app.html +44 -32
  5. package/engine/src/review-assets/app.js +11 -7
  6. package/engine/src/review-assets/check.css +11 -56
  7. package/engine/src/review-assets/check.html +48 -22
  8. package/engine/src/review-assets/check.js +169 -86
  9. package/engine/src/review-assets/code.css +15 -92
  10. package/engine/src/review-assets/code.html +41 -26
  11. package/engine/src/review-assets/code.js +196 -101
  12. package/engine/src/review-assets/rk-icons.js +98 -0
  13. package/engine/src/review-assets/rk-tokens.css +252 -0
  14. package/engine/src/review-assets/rk.css +252 -0
  15. package/engine/src/review.ts +6 -4
  16. package/package.json +1 -1
  17. package/paseo-plugin/client/detail.tsx +31 -11
  18. package/paseo-plugin/client/format.ts +56 -0
  19. package/paseo-plugin/client/inbox.tsx +26 -20
  20. package/paseo-plugin/client/markdown.tsx +2 -1
  21. package/paseo-plugin/client/overview.tsx +21 -11
  22. package/paseo-plugin/client/review.tsx +3 -3
  23. package/paseo-plugin/client/row.tsx +38 -15
  24. package/paseo-plugin/client/stats.tsx +5 -4
  25. package/paseo-plugin/client/ui.tsx +196 -29
  26. package/paseo-plugin/package.json +1 -1
  27. package/paseo-plugin/shared/rk-colors.ts +35 -0
  28. package/site-dist/404.html +5 -5
  29. package/site-dist/assets/{app.VQ-QxRPH.js → app.Ny0BZHeG.js} +1 -1
  30. package/site-dist/assets/changelog.md.CUwudFS5.js +1 -0
  31. package/site-dist/assets/{changelog.md.CIKYJXpF.lean.js → changelog.md.CUwudFS5.lean.js} +1 -1
  32. package/site-dist/assets/chunks/@localSearchIndexroot.BmFA3hqY.js +1 -0
  33. package/site-dist/assets/chunks/{VPLocalSearchBox.CT4Vlj76.js → VPLocalSearchBox.BCWGSI0L.js} +1 -1
  34. package/site-dist/assets/chunks/{framework.B9qR_F1m.js → framework.BetZR81g.js} +1 -1
  35. package/site-dist/assets/chunks/theme.BeEUWcJI.js +2 -0
  36. package/site-dist/assets/{guide_getting-started.md.CZM53rO_.js → guide_getting-started.md.DBJ0aMgy.js} +1 -1
  37. package/site-dist/assets/{guide_getting-started.md.CZM53rO_.lean.js → guide_getting-started.md.DBJ0aMgy.lean.js} +1 -1
  38. package/site-dist/assets/{guide_how-it-works.md.D-kQsF1t.js → guide_how-it-works.md.Rn-g0Um8.js} +1 -1
  39. package/site-dist/assets/{guide_how-it-works.md.D-kQsF1t.lean.js → guide_how-it-works.md.Rn-g0Um8.lean.js} +1 -1
  40. package/site-dist/assets/{guide_index.md.CLnGCmGW.js → guide_index.md.BIF6VPBE.js} +1 -1
  41. package/site-dist/assets/{guide_index.md.CLnGCmGW.lean.js → guide_index.md.BIF6VPBE.lean.js} +1 -1
  42. package/site-dist/assets/{guide_install.md.DkCyZsOU.js → guide_install.md.kIsj5oWc.js} +1 -1
  43. package/site-dist/assets/{guide_install.md.DkCyZsOU.lean.js → guide_install.md.kIsj5oWc.lean.js} +1 -1
  44. package/site-dist/assets/guide_maintainer.md.SWALpGR5.js +1 -0
  45. package/site-dist/assets/guide_maintainer.md.SWALpGR5.lean.js +1 -0
  46. package/site-dist/assets/{guide_phases.md.BpGAb1re.js → guide_phases.md.Bnd9FQ27.js} +1 -1
  47. package/site-dist/assets/{guide_phases.md.BpGAb1re.lean.js → guide_phases.md.Bnd9FQ27.lean.js} +1 -1
  48. package/site-dist/assets/{guide_project.md.DIjDRoAq.js → guide_project.md.CzS92KTI.js} +1 -1
  49. package/site-dist/assets/{guide_project.md.DIjDRoAq.lean.js → guide_project.md.CzS92KTI.lean.js} +1 -1
  50. package/site-dist/assets/{guide_user.md.UV0WxdJa.js → guide_user.md.REc1nK8f.js} +1 -1
  51. package/site-dist/assets/{guide_user.md.UV0WxdJa.lean.js → guide_user.md.REc1nK8f.lean.js} +1 -1
  52. package/site-dist/assets/index.md.CpaGRB2c.js +1 -0
  53. package/site-dist/assets/index.md.CpaGRB2c.lean.js +1 -0
  54. package/site-dist/assets/{reference_adr_0001-step-agents-under-origin-chat.md.RtRTq7oi.js → reference_adr_0001-step-agents-under-origin-chat.md.CPq0ZVSs.js} +1 -1
  55. package/site-dist/assets/{reference_adr_0001-step-agents-under-origin-chat.md.RtRTq7oi.lean.js → reference_adr_0001-step-agents-under-origin-chat.md.CPq0ZVSs.lean.js} +1 -1
  56. package/site-dist/assets/{reference_adr_0002-no-directory-switch-in-chat.md.BxtN-Aa2.js → reference_adr_0002-no-directory-switch-in-chat.md.BZD1j8xZ.js} +1 -1
  57. package/site-dist/assets/{reference_adr_0002-no-directory-switch-in-chat.md.BxtN-Aa2.lean.js → reference_adr_0002-no-directory-switch-in-chat.md.BZD1j8xZ.lean.js} +1 -1
  58. package/site-dist/assets/{reference_adr_0003-script-engine-not-hub.md.66EgZtqx.js → reference_adr_0003-script-engine-not-hub.md.Bi4uZZaE.js} +1 -1
  59. package/site-dist/assets/{reference_adr_0003-script-engine-not-hub.md.66EgZtqx.lean.js → reference_adr_0003-script-engine-not-hub.md.Bi4uZZaE.lean.js} +1 -1
  60. package/site-dist/assets/{reference_adr_0004-result-files.md.DbqcCozI.js → reference_adr_0004-result-files.md.CNQMSs4R.js} +1 -1
  61. package/site-dist/assets/{reference_adr_0004-result-files.md.DbqcCozI.lean.js → reference_adr_0004-result-files.md.CNQMSs4R.lean.js} +1 -1
  62. package/site-dist/assets/{reference_adr_0005-no-default-branch-local-commits-only.md.CkImA4s6.js → reference_adr_0005-no-default-branch-local-commits-only.md.DeXnMAyg.js} +1 -1
  63. package/site-dist/assets/{reference_adr_0005-no-default-branch-local-commits-only.md.CkImA4s6.lean.js → reference_adr_0005-no-default-branch-local-commits-only.md.DeXnMAyg.lean.js} +1 -1
  64. package/site-dist/assets/{reference_adr_0006-skill-install-targets.md.CwY8YepV.js → reference_adr_0006-skill-install-targets.md.CwqvB8NW.js} +1 -1
  65. package/site-dist/assets/{reference_adr_0006-skill-install-targets.md.CwY8YepV.lean.js → reference_adr_0006-skill-install-targets.md.CwqvB8NW.lean.js} +1 -1
  66. package/site-dist/assets/{reference_adr_0007-own-interview-skill.md.CryhxRyG.js → reference_adr_0007-own-interview-skill.md.HlLp78db.js} +1 -1
  67. package/site-dist/assets/{reference_adr_0007-own-interview-skill.md.CryhxRyG.lean.js → reference_adr_0007-own-interview-skill.md.HlLp78db.lean.js} +1 -1
  68. package/site-dist/assets/{reference_adr_0008-entries-do-not-call-entries.md.DsRWAgeA.js → reference_adr_0008-entries-do-not-call-entries.md.D2VH2uQV.js} +1 -1
  69. package/site-dist/assets/{reference_adr_0008-entries-do-not-call-entries.md.DsRWAgeA.lean.js → reference_adr_0008-entries-do-not-call-entries.md.D2VH2uQV.lean.js} +1 -1
  70. package/site-dist/assets/{reference_adr_0009-versioned-install-layout.md.CSg1VqlW.js → reference_adr_0009-versioned-install-layout.md.D9g3dWr-.js} +1 -1
  71. package/site-dist/assets/{reference_adr_0009-versioned-install-layout.md.CSg1VqlW.lean.js → reference_adr_0009-versioned-install-layout.md.D9g3dWr-.lean.js} +1 -1
  72. package/site-dist/assets/{reference_adr_0010-generated-feature-overview.md.D8F3MK-h.js → reference_adr_0010-generated-feature-overview.md.CHOwcV4c.js} +1 -1
  73. package/site-dist/assets/{reference_adr_0010-generated-feature-overview.md.D8F3MK-h.lean.js → reference_adr_0010-generated-feature-overview.md.CHOwcV4c.lean.js} +1 -1
  74. package/site-dist/assets/{reference_adr_0011-resume-after-completion.md.BCrZrKjf.js → reference_adr_0011-resume-after-completion.md.CqdSPi49.js} +1 -1
  75. package/site-dist/assets/{reference_adr_0011-resume-after-completion.md.BCrZrKjf.lean.js → reference_adr_0011-resume-after-completion.md.CqdSPi49.lean.js} +1 -1
  76. package/site-dist/assets/{reference_adr_0012-review-panel.md.k9rrHFFc.js → reference_adr_0012-review-panel.md.d4wmLrNF.js} +1 -1
  77. package/site-dist/assets/{reference_adr_0012-review-panel.md.k9rrHFFc.lean.js → reference_adr_0012-review-panel.md.d4wmLrNF.lean.js} +1 -1
  78. package/site-dist/assets/{reference_adr_0013-no-release-tooling.md.BQeJ8dEI.js → reference_adr_0013-no-release-tooling.md.BOROmwvq.js} +1 -1
  79. package/site-dist/assets/{reference_adr_0013-no-release-tooling.md.BQeJ8dEI.lean.js → reference_adr_0013-no-release-tooling.md.BOROmwvq.lean.js} +1 -1
  80. package/site-dist/assets/{reference_adr_0014-notifier-slot.md.C23QR1xO.js → reference_adr_0014-notifier-slot.md.BAqt1Xj1.js} +1 -1
  81. package/site-dist/assets/{reference_adr_0014-notifier-slot.md.C23QR1xO.lean.js → reference_adr_0014-notifier-slot.md.BAqt1Xj1.lean.js} +1 -1
  82. package/site-dist/assets/{reference_adr_0015-incremental-continue.md.Buy7wwO8.js → reference_adr_0015-incremental-continue.md.BiUdpeq5.js} +1 -1
  83. package/site-dist/assets/{reference_adr_0015-incremental-continue.md.Buy7wwO8.lean.js → reference_adr_0015-incremental-continue.md.BiUdpeq5.lean.js} +1 -1
  84. package/site-dist/assets/{reference_adr_0016-upgrade-from-tags.md.qfIW-tqJ.js → reference_adr_0016-upgrade-from-tags.md.D48PfEFP.js} +1 -1
  85. package/site-dist/assets/{reference_adr_0016-upgrade-from-tags.md.qfIW-tqJ.lean.js → reference_adr_0016-upgrade-from-tags.md.D48PfEFP.lean.js} +1 -1
  86. package/site-dist/assets/{reference_adr_0017-use-paseo-capabilities.md.CjcGli87.js → reference_adr_0017-use-paseo-capabilities.md.CAMkamzJ.js} +1 -1
  87. package/site-dist/assets/{reference_adr_0017-use-paseo-capabilities.md.CjcGli87.lean.js → reference_adr_0017-use-paseo-capabilities.md.CAMkamzJ.lean.js} +1 -1
  88. package/site-dist/assets/{reference_adr_0018-own-worktree-option.md.fVDpgGSE.js → reference_adr_0018-own-worktree-option.md.DgkWjYL-.js} +1 -1
  89. package/site-dist/assets/{reference_adr_0018-own-worktree-option.md.fVDpgGSE.lean.js → reference_adr_0018-own-worktree-option.md.DgkWjYL-.lean.js} +1 -1
  90. package/site-dist/assets/{reference_adr_0019-parallel-orchestration.md.DrfrV0To.js → reference_adr_0019-parallel-orchestration.md.B9xqQidw.js} +1 -1
  91. package/site-dist/assets/{reference_adr_0019-parallel-orchestration.md.DrfrV0To.lean.js → reference_adr_0019-parallel-orchestration.md.B9xqQidw.lean.js} +1 -1
  92. package/site-dist/assets/{reference_adr_0020-scheduling-through-the-chat.md.BqSemGFG.js → reference_adr_0020-scheduling-through-the-chat.md.Dh81be7G.js} +1 -1
  93. package/site-dist/assets/{reference_adr_0020-scheduling-through-the-chat.md.BqSemGFG.lean.js → reference_adr_0020-scheduling-through-the-chat.md.Dh81be7G.lean.js} +1 -1
  94. package/site-dist/assets/{reference_adr_0021-npm-version-manager.md.CU3PG6y5.js → reference_adr_0021-npm-version-manager.md.Pz4vZbkE.js} +1 -1
  95. package/site-dist/assets/{reference_adr_0021-npm-version-manager.md.CU3PG6y5.lean.js → reference_adr_0021-npm-version-manager.md.Pz4vZbkE.lean.js} +1 -1
  96. package/site-dist/assets/{reference_adr_0022-develop-and-verify-phases.md.C6fQDLq4.js → reference_adr_0022-develop-and-verify-phases.md.35MxNOuj.js} +1 -1
  97. package/site-dist/assets/{reference_adr_0022-develop-and-verify-phases.md.C6fQDLq4.lean.js → reference_adr_0022-develop-and-verify-phases.md.35MxNOuj.lean.js} +1 -1
  98. package/site-dist/assets/{reference_adr_0023-types-gate-slices.md.D2E6yyYQ.js → reference_adr_0023-types-gate-slices.md.Bjufr5EK.js} +1 -1
  99. package/site-dist/assets/{reference_adr_0023-types-gate-slices.md.D2E6yyYQ.lean.js → reference_adr_0023-types-gate-slices.md.Bjufr5EK.lean.js} +1 -1
  100. package/site-dist/assets/{reference_adr_0024-confirm-early-review-axes.md.FmK_ke0x.js → reference_adr_0024-confirm-early-review-axes.md.BRxVXJa4.js} +1 -1
  101. package/site-dist/assets/{reference_adr_0024-confirm-early-review-axes.md.FmK_ke0x.lean.js → reference_adr_0024-confirm-early-review-axes.md.BRxVXJa4.lean.js} +1 -1
  102. package/site-dist/assets/{reference_adr_0025-joint-requirements.md.ChoKvMUx.js → reference_adr_0025-joint-requirements.md.ClCFyIiN.js} +1 -1
  103. package/site-dist/assets/{reference_adr_0025-joint-requirements.md.ChoKvMUx.lean.js → reference_adr_0025-joint-requirements.md.ClCFyIiN.lean.js} +1 -1
  104. package/site-dist/assets/{reference_adr_0026-machine-records-and-api.md.veybjBPq.js → reference_adr_0026-machine-records-and-api.md.Bv1k_WjT.js} +1 -1
  105. package/site-dist/assets/{reference_adr_0026-machine-records-and-api.md.veybjBPq.lean.js → reference_adr_0026-machine-records-and-api.md.Bv1k_WjT.lean.js} +1 -1
  106. package/site-dist/assets/{reference_adr_0027-paseo-plugin.md.BMX33ZNU.js → reference_adr_0027-paseo-plugin.md.CcpaKksi.js} +1 -1
  107. package/site-dist/assets/{reference_adr_0027-paseo-plugin.md.BMX33ZNU.lean.js → reference_adr_0027-paseo-plugin.md.CcpaKksi.lean.js} +1 -1
  108. package/site-dist/assets/{reference_adr_0028-external-integrations.md.DtdMe8RK.js → reference_adr_0028-external-integrations.md.CrGqXJux.js} +1 -1
  109. package/site-dist/assets/{reference_adr_0028-external-integrations.md.DtdMe8RK.lean.js → reference_adr_0028-external-integrations.md.CrGqXJux.lean.js} +1 -1
  110. package/site-dist/assets/{reference_adr_0029-requirements-from-cards.md.BHd1SQPe.js → reference_adr_0029-requirements-from-cards.md.BUVah9hV.js} +1 -1
  111. package/site-dist/assets/{reference_adr_0029-requirements-from-cards.md.BHd1SQPe.lean.js → reference_adr_0029-requirements-from-cards.md.BUVah9hV.lean.js} +1 -1
  112. package/site-dist/assets/{reference_adr_0030-card-intake-process.md.kLc-DG9_.js → reference_adr_0030-card-intake-process.md.DKMkIFXw.js} +1 -1
  113. package/site-dist/assets/{reference_adr_0030-card-intake-process.md.kLc-DG9_.lean.js → reference_adr_0030-card-intake-process.md.DKMkIFXw.lean.js} +1 -1
  114. package/site-dist/assets/{reference_adr_0031-fewer-interventions.md.BDnQcz8g.js → reference_adr_0031-fewer-interventions.md.C8e2jpbC.js} +1 -1
  115. package/site-dist/assets/{reference_adr_0031-fewer-interventions.md.BDnQcz8g.lean.js → reference_adr_0031-fewer-interventions.md.C8e2jpbC.lean.js} +1 -1
  116. package/site-dist/assets/{reference_adr_0032-npm-only-install.md.C-3L1FkX.js → reference_adr_0032-npm-only-install.md.5tFsGLKz.js} +1 -1
  117. package/site-dist/assets/{reference_adr_0032-npm-only-install.md.C-3L1FkX.lean.js → reference_adr_0032-npm-only-install.md.5tFsGLKz.lean.js} +1 -1
  118. package/site-dist/assets/{reference_adr_0033-prototype-review-and-ui-check.md.hFcQzmaa.js → reference_adr_0033-prototype-review-and-ui-check.md.CW5Soqvp.js} +1 -1
  119. package/site-dist/assets/{reference_adr_0033-prototype-review-and-ui-check.md.hFcQzmaa.lean.js → reference_adr_0033-prototype-review-and-ui-check.md.CW5Soqvp.lean.js} +1 -1
  120. package/site-dist/assets/{reference_adr_index.md.BYF-Ofor.js → reference_adr_index.md.DgUVrHoO.js} +1 -1
  121. package/site-dist/assets/{reference_adr_index.md.BYF-Ofor.lean.js → reference_adr_index.md.DgUVrHoO.lean.js} +1 -1
  122. package/site-dist/assets/{reference_commands.md.ClKbS-t8.js → reference_commands.md.BAQ8FugP.js} +1 -1
  123. package/site-dist/assets/{reference_commands.md.ClKbS-t8.lean.js → reference_commands.md.BAQ8FugP.lean.js} +1 -1
  124. package/site-dist/assets/{reference_config.md.CRe27LaA.js → reference_config.md.DoQUxHQ2.js} +1 -1
  125. package/site-dist/assets/{reference_config.md.CRe27LaA.lean.js → reference_config.md.DoQUxHQ2.lean.js} +1 -1
  126. package/site-dist/assets/{reference_contracts_cli-json.md.CCvKLasM.js → reference_contracts_cli-json.md.nRuTayON.js} +1 -1
  127. package/site-dist/assets/{reference_contracts_cli-json.md.CCvKLasM.lean.js → reference_contracts_cli-json.md.nRuTayON.lean.js} +1 -1
  128. package/site-dist/assets/{reference_contracts_feature-files.md.DSiA8OEH.lean.js → reference_contracts_feature-files.md.CgiSHFpq.js} +1 -1
  129. package/site-dist/assets/{reference_contracts_feature-files.md.DSiA8OEH.js → reference_contracts_feature-files.md.CgiSHFpq.lean.js} +1 -1
  130. package/site-dist/assets/{reference_contracts_index.md.Bkznz4px.js → reference_contracts_index.md.3h253qSo.js} +1 -1
  131. package/site-dist/assets/{reference_contracts_index.md.Bkznz4px.lean.js → reference_contracts_index.md.3h253qSo.lean.js} +1 -1
  132. package/site-dist/assets/{reference_contracts_notifier-event.md.B9WqeZdO.js → reference_contracts_notifier-event.md.DVrifpjH.js} +1 -1
  133. package/site-dist/assets/{reference_contracts_notifier-event.md.B9WqeZdO.lean.js → reference_contracts_notifier-event.md.DVrifpjH.lean.js} +1 -1
  134. package/site-dist/assets/{reference_contracts_result-file.md.DmR4fjB-.js → reference_contracts_result-file.md.CiZCk_r-.js} +1 -1
  135. package/site-dist/assets/{reference_contracts_result-file.md.DmR4fjB-.lean.js → reference_contracts_result-file.md.CiZCk_r-.lean.js} +1 -1
  136. package/site-dist/assets/{reference_contracts_spec.md.Dh5XczZL.js → reference_contracts_spec.md.B04OndF4.js} +1 -1
  137. package/site-dist/assets/{reference_contracts_spec.md.Dh5XczZL.lean.js → reference_contracts_spec.md.B04OndF4.lean.js} +1 -1
  138. package/site-dist/assets/{reference_contracts_state.md.STlqkPPS.js → reference_contracts_state.md.Xu63sMWH.js} +1 -1
  139. package/site-dist/assets/{reference_contracts_state.md.STlqkPPS.lean.js → reference_contracts_state.md.Xu63sMWH.lean.js} +1 -1
  140. package/site-dist/assets/{reference_contracts_usage-record.md.MjVps4CA.js → reference_contracts_usage-record.md.gd7f8fyb.js} +1 -1
  141. package/site-dist/assets/{reference_contracts_usage-record.md.MjVps4CA.lean.js → reference_contracts_usage-record.md.gd7f8fyb.lean.js} +1 -1
  142. package/site-dist/assets/{reference_contracts_verify.md.CbA88u6S.js → reference_contracts_verify.md.D_bAWUcP.js} +1 -1
  143. package/site-dist/assets/{reference_contracts_verify.md.CbA88u6S.lean.js → reference_contracts_verify.md.D_bAWUcP.lean.js} +1 -1
  144. package/site-dist/assets/{reference_scope.md.Kzqw8U_f.js → reference_scope.md.B7JBceSf.js} +1 -1
  145. package/site-dist/assets/{reference_scope.md.Kzqw8U_f.lean.js → reference_scope.md.B7JBceSf.lean.js} +1 -1
  146. package/site-dist/assets/{style.Dwsa4SMe.css → style.2G3zLS3c.css} +1 -1
  147. package/site-dist/changelog.html +9 -9
  148. package/site-dist/favicon.svg +10 -0
  149. package/site-dist/guide/getting-started.html +9 -9
  150. package/site-dist/guide/how-it-works.html +9 -9
  151. package/site-dist/guide/index.html +9 -9
  152. package/site-dist/guide/install.html +9 -9
  153. package/site-dist/guide/maintainer.html +9 -9
  154. package/site-dist/guide/phases.html +9 -9
  155. package/site-dist/guide/project.html +9 -9
  156. package/site-dist/guide/user.html +9 -9
  157. package/site-dist/hashmap.json +1 -1
  158. package/site-dist/index.html +9 -9
  159. package/site-dist/logo-light.svg +6 -0
  160. package/site-dist/logo.svg +5 -10
  161. package/site-dist/reference/adr/0001-step-agents-under-origin-chat.html +9 -9
  162. package/site-dist/reference/adr/0002-no-directory-switch-in-chat.html +9 -9
  163. package/site-dist/reference/adr/0003-script-engine-not-hub.html +9 -9
  164. package/site-dist/reference/adr/0004-result-files.html +9 -9
  165. package/site-dist/reference/adr/0005-no-default-branch-local-commits-only.html +9 -9
  166. package/site-dist/reference/adr/0006-skill-install-targets.html +9 -9
  167. package/site-dist/reference/adr/0007-own-interview-skill.html +9 -9
  168. package/site-dist/reference/adr/0008-entries-do-not-call-entries.html +9 -9
  169. package/site-dist/reference/adr/0009-versioned-install-layout.html +9 -9
  170. package/site-dist/reference/adr/0010-generated-feature-overview.html +9 -9
  171. package/site-dist/reference/adr/0011-resume-after-completion.html +9 -9
  172. package/site-dist/reference/adr/0012-review-panel.html +9 -9
  173. package/site-dist/reference/adr/0013-no-release-tooling.html +9 -9
  174. package/site-dist/reference/adr/0014-notifier-slot.html +9 -9
  175. package/site-dist/reference/adr/0015-incremental-continue.html +9 -9
  176. package/site-dist/reference/adr/0016-upgrade-from-tags.html +9 -9
  177. package/site-dist/reference/adr/0017-use-paseo-capabilities.html +9 -9
  178. package/site-dist/reference/adr/0018-own-worktree-option.html +9 -9
  179. package/site-dist/reference/adr/0019-parallel-orchestration.html +9 -9
  180. package/site-dist/reference/adr/0020-scheduling-through-the-chat.html +9 -9
  181. package/site-dist/reference/adr/0021-npm-version-manager.html +9 -9
  182. package/site-dist/reference/adr/0022-develop-and-verify-phases.html +9 -9
  183. package/site-dist/reference/adr/0023-types-gate-slices.html +9 -9
  184. package/site-dist/reference/adr/0024-confirm-early-review-axes.html +9 -9
  185. package/site-dist/reference/adr/0025-joint-requirements.html +9 -9
  186. package/site-dist/reference/adr/0026-machine-records-and-api.html +9 -9
  187. package/site-dist/reference/adr/0027-paseo-plugin.html +9 -9
  188. package/site-dist/reference/adr/0028-external-integrations.html +9 -9
  189. package/site-dist/reference/adr/0029-requirements-from-cards.html +9 -9
  190. package/site-dist/reference/adr/0030-card-intake-process.html +9 -9
  191. package/site-dist/reference/adr/0031-fewer-interventions.html +9 -9
  192. package/site-dist/reference/adr/0032-npm-only-install.html +9 -9
  193. package/site-dist/reference/adr/0033-prototype-review-and-ui-check.html +9 -9
  194. package/site-dist/reference/adr/index.html +9 -9
  195. package/site-dist/reference/commands.html +9 -9
  196. package/site-dist/reference/config.html +9 -9
  197. package/site-dist/reference/contracts/cli-json.html +9 -9
  198. package/site-dist/reference/contracts/feature-files.html +9 -9
  199. package/site-dist/reference/contracts/index.html +9 -9
  200. package/site-dist/reference/contracts/notifier-event.html +9 -9
  201. package/site-dist/reference/contracts/result-file.html +9 -9
  202. package/site-dist/reference/contracts/spec.html +9 -9
  203. package/site-dist/reference/contracts/state.html +9 -9
  204. package/site-dist/reference/contracts/usage-record.html +9 -9
  205. package/site-dist/reference/contracts/verify.html +9 -9
  206. package/site-dist/reference/scope.html +9 -9
  207. package/site-dist/assets/changelog.md.CIKYJXpF.js +0 -1
  208. package/site-dist/assets/chunks/@localSearchIndexroot.h7oQE_np.js +0 -1
  209. package/site-dist/assets/chunks/theme.B_UmHHou.js +0 -2
  210. package/site-dist/assets/guide_maintainer.md.C1v7EpSY.js +0 -1
  211. package/site-dist/assets/guide_maintainer.md.C1v7EpSY.lean.js +0 -1
  212. package/site-dist/assets/index.md.Cf_sSf_f.js +0 -1
  213. package/site-dist/assets/index.md.Cf_sSf_f.lean.js +0 -1
  214. package/site-dist/icons/agents.svg +0 -1
  215. package/site-dist/icons/chat.svg +0 -1
  216. package/site-dist/icons/paseo.svg +0 -1
  217. package/site-dist/icons/phases.svg +0 -1
  218. package/site-dist/icons/review.svg +0 -1
  219. package/site-dist/icons/safe.svg +0 -1
@@ -1,4 +1,4 @@
1
- import{_ as e,o as n,c as t,j as l,a as i}from"./chunks/framework.B9qR_F1m.js";const c=JSON.parse('{"title":"安装与升级","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/install.md","filePath":"guide/install.md","lastUpdated":null}'),a={name:"guide/install.md"};function d(h,s,u,o,k,r){return n(),t("div",null,[...s[0]||(s[0]=[l("div",null,[l("h1",{id:"安装与升级",tabindex:"-1"},[i("安装与升级 "),l("a",{class:"header-anchor",href:"#安装与升级","aria-label":'Permalink to "安装与升级"'},"​")]),l("p",null,[i("本文面向负责安装的人:通常是开发同事,有经验的测试或产品同事也可以按步骤完成。安装在"),l("strong",null,"运行 Paseo daemon 的那台机器"),i("上做一次,之后这台机器上所有项目的 Paseo 对话都能使用 "),l("code",null,"/req"),i("。")]),l("h2",{id:"_1-安装布局",tabindex:"-1"},[i("1. 安装布局 "),l("a",{class:"header-anchor",href:"#_1-安装布局","aria-label":'Permalink to "1. 安装布局"'},"​")]),l("p",null,"程序和本机配置分开存放。升级时只替换程序,配置不动;旧版本目录保留,可以随时回滚。"),l("div",{class:"language-text vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"text"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",null,"<npm 全局目录>/paseo-req-kit/ 版本管理器(npm i -g 安装,提供 req 命令)")]),i(`
1
+ import{_ as e,o as n,c as t,j as l,a as i}from"./chunks/framework.BetZR81g.js";const c=JSON.parse('{"title":"安装与升级","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/install.md","filePath":"guide/install.md","lastUpdated":null}'),a={name:"guide/install.md"};function d(h,s,u,o,k,r){return n(),t("div",null,[...s[0]||(s[0]=[l("div",null,[l("h1",{id:"安装与升级",tabindex:"-1"},[i("安装与升级 "),l("a",{class:"header-anchor",href:"#安装与升级","aria-label":'Permalink to "安装与升级"'},"​")]),l("p",null,[i("本文面向负责安装的人:通常是开发同事,有经验的测试或产品同事也可以按步骤完成。安装在"),l("strong",null,"运行 Paseo daemon 的那台机器"),i("上做一次,之后这台机器上所有项目的 Paseo 对话都能使用 "),l("code",null,"/req"),i("。")]),l("h2",{id:"_1-安装布局",tabindex:"-1"},[i("1. 安装布局 "),l("a",{class:"header-anchor",href:"#_1-安装布局","aria-label":'Permalink to "1. 安装布局"'},"​")]),l("p",null,"程序和本机配置分开存放。升级时只替换程序,配置不动;旧版本目录保留,可以随时回滚。"),l("div",{class:"language-text vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"text"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",null,"<npm 全局目录>/paseo-req-kit/ 版本管理器(npm i -g 安装,提供 req 命令)")]),i(`
2
2
  `),l("span",{class:"line"},[l("span",null,"~/tools/req-kit/versions/")]),i(`
3
3
  `),l("span",{class:"line"},[l("span",null,"├── 1.7.0/node_modules/paseo-req-kit/ 一个版本的程序(npm 安装;依赖在 1.7.0/node_modules 下)")]),i(`
4
4
  `),l("span",{class:"line"},[l("span",null,"├── 1.6.0/ git 方式安装的版本(含 node_modules),继续可用")]),i(`
@@ -0,0 +1 @@
1
+ import{_ as o,o as t,c as d,a2 as c}from"./chunks/framework.BetZR81g.js";const m=JSON.parse('{"title":"维护者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/maintainer.md","filePath":"guide/maintainer.md","lastUpdated":null}'),a={name:"guide/maintainer.md"};function r(s,e,n,i,l,p){return t(),d("div",null,[...e[0]||(e[0]=[c('<div><h1 id="维护者指南" tabindex="-1">维护者指南 <a class="header-anchor" href="#维护者指南" aria-label="Permalink to &quot;维护者指南&quot;">​</a></h1><p>面向维护 req-kit 本身的人:改提示词和 skill、发布新版本、处理复盘提交的问题。</p><h2 id="_1-改动之前" tabindex="-1">1. 改动之前 <a class="header-anchor" href="#_1-改动之前" aria-label="Permalink to &quot;1. 改动之前&quot;">​</a></h2><ul><li>先看 <a href="./../reference/scope">SCOPE.md</a> 和 <a href="https://github.com/yiyisf/paseo-req-kit/tree/main/.out-of-scope" target="_blank" rel="noreferrer">.out-of-scope/</a>:新提议须服务于&quot;帮助非专职开发的同事把一个需求从对齐做到可验收&quot;,至少有两个真实场景,并且无法通过项目配置或项目说明解决。</li><li>改动已有的设计决定(<a href="./../reference/adr/">docs/adr/</a>)时,新增一条 ADR 说明理由,并在旧的一条中注明被哪条取代。</li><li>界面的颜色、字体、组件按 <code>design/</code>(设计规范,见其中的 README)来;改了 <code>design/tokens.json</code>、<code>design/reference/components.css</code> 或 <code>design/examples/icons.js</code>,运行 <code>node scripts/tokens-build.mjs</code> 更新审查网页里的副本。</li><li>改动文件格式(spec、状态文件、结果文件、决策记录等)时,同时更新 <a href="./../reference/contracts/">contracts/</a>、代码和测试;状态文件的格式变化要加迁移(见 <code>contracts/state.md</code>)。</li></ul><h2 id="_2-改-skill-和提示词的规则" tabindex="-1">2. 改 skill 和提示词的规则 <a class="header-anchor" href="#_2-改-skill-和提示词的规则" aria-label="Permalink to &quot;2. 改 skill 和提示词的规则&quot;">​</a></h2><ul><li><strong>入口不调用入口</strong>(ADR 0008)。<code>/req</code>、<code>/req-setup</code>、<code>/req-doctor</code>、<code>/req-retro</code> 之间只能&quot;告诉用户去运行&quot;,不能互相加载。</li><li><strong>路径用占位符</strong>:skill 中引用安装目录内的文件写 <code>{{REQ_KIT_ROOT}}/...</code>,启动命令写 <code>{{PIPELINE_LAUNCHER}}</code>,版本号写 <code>{{REQ_KIT_VERSION}}</code>。安装器会替换它们;<code>npm test</code> 会检查引用的文件都存在。</li><li><strong>frontmatter</strong> 只用 <code>name</code>、<code>description</code>,agent 专属的放在 <code>metadata</code> 下;<code>description</code> 中不要出现半角的 <code>: </code>。</li><li><strong>手册</strong>(<code>skills/req/playbooks/*.md</code>)开头必须有&quot;## 步骤&quot;编号列表,<code>/req</code> 会把它原样放进待办列表;新增手册要加进 <code>/req</code> 的路由表。</li><li><strong>原则</strong>:增加一条原则需要至少两次真实失误作为依据,并且无法用 CI 或配置解决;总数不超过 10 条。原则的一句话版本写进 <code>principles/INDEX.md</code>,它同时被聊天和每个步骤的提示词使用。</li><li><strong>措辞</strong>:读者是有技术背景、但不读代码的使用者(测试、产品、项目经理)。讲需求和结果,不讲代码实现。</li></ul><h2 id="_3-验证改动" tabindex="-1">3. 验证改动 <a class="header-anchor" href="#_3-验证改动" aria-label="Permalink to &quot;3. 验证改动&quot;">​</a></h2><table tabindex="0"><thead><tr><th>改了什么</th><th>至少要做</th></tr></thead><tbody><tr><td>引擎代码</td><td><code>npm test</code>、<code>npm run typecheck</code></td></tr><tr><td>步骤提示词</td><td>上面两项 + <code>npm run eval</code>(至少跑受影响的用例),与上一次的结果对比</td></tr><tr><td>入口、手册、方法 skill、原则</td><td><code>npm test</code> + 对话评估中受影响的剧本(<code>evals/conversation/</code>)</td></tr><tr><td>安装器</td><td><code>npm test</code>(在临时 HOME 中测试),并在 Windows 上实际装一次</td></tr><tr><td>评估用例</td><td><code>npm run eval:self-check</code>(参考实现必须通过隐藏验收)</td></tr><tr><td>Paseo 插件(<code>paseo-plugin/</code>)</td><td><code>npm test</code>(插件后台和 <code>req plugin</code>);在 <code>paseo-plugin/</code> 中 <code>npm install &amp;&amp; npm run typecheck</code>(CI 的 plugin 任务也会做);用 <code>req plugin install</code> 装到一台 Paseo 上,在网页端和手机宽度下看一遍,切换一次深色主题</td></tr></tbody></table><p>提示词改动以评估结果为准:如实率(不夸大)不能下降;隐藏验收通过率、用时、轮次与上一次对比,变差时说明原因。</p><h2 id="_4-发布" tabindex="-1">4. 发布 <a class="header-anchor" href="#_4-发布" aria-label="Permalink to &quot;4. 发布&quot;">​</a></h2><p>版本号遵循语义化版本,标签<strong>不带 <code>v</code> 前缀</strong>(例如 <code>1.2.0</code>、<code>1.3.0-beta.1</code>)。</p><ol><li><strong>确定版本号</strong>:修订号(修复、措辞调整)、次版本号(新手册、新配置项,完全兼容)、主版本号(文件格式、配置字段或入口名称的不兼容变化)。同一主版本内,配置字段只增不删(废弃的继续生效并在 <code>/req-doctor</code> 中提示),文件格式只做可以自动迁移的变更。</li><li><strong>更新 <code>package.json</code> 的 <code>version</code></strong>;Paseo 支持范围有变化时同时更新 <code>reqKit.paseo</code>,并复查 <code>engine/src/paseo-runtime.ts</code> 开头列出的 SDK 用法(其中工作区脚本用的是内部接口,见 ADR 0017)。</li><li><strong>写 <code>CHANGELOG.md</code></strong>:新增一节,分&quot;使用者会看到的变化&quot;和&quot;升级须知&quot;两部分。升级须知写清:要不要重跑 <code>/req-setup</code>、提示词有哪些变化(影响用 <code>prompts.local/</code> 覆盖过的人)、文件格式有没有变化、旧行为的兼容方式。</li><li><strong>验证</strong>:<code>npm test</code>、<code>npm run typecheck</code>、<code>npm run eval:self-check</code>;步骤提示词或引擎有改动时跑 <code>npm run eval</code>,把 <code>summary.md</code> 复制到 <code>evals/baselines/&lt;版本&gt;.md</code>;入口或手册有改动时跑对话评估,记入记分表。主版本发布前,在一个真实项目里试运行一周。</li><li><strong>冒烟测试</strong>:在一台干净的机器(或临时的 <code>REQ_KIT_HOME</code> 和 HOME)上按 <a href="./install">安装与升级</a> 安装,跑冒烟测试第 1–4 项;至少有一台是 Windows。</li><li><strong>合并到 <code>main</code>,标签自动打上</strong>:<code>main</code> 收到 <code>package.json</code> 版本号还没有标签的提交时,<code>.github/workflows/release.yml</code> 先在这个提交上跑测试(Linux 和 Windows 各一遍,1.13 起)、类型检查和评估自检,通过后才打上同名标签(不用自己打,也不需要推送标签的权限),接着在同一次运行里发布。测试没通过时不会留下标签,把修复合到 <code>main</code> 就会用同一个版本号重新发布(1.12.1 起;1.13 起任何推到 <code>main</code> 的提交都会检查,不必再改 <code>package.json</code>)。也可以照旧自己打:在 GitHub 上建 Release 并新建标签 <code>&lt;版本&gt;</code>,或推送 <code>git tag -a &lt;版本&gt;</code>,同样会触发发布。发布流程:跑测试、类型检查和评估自检,核对标签与 <code>package.json</code> 版本一致,然后发布到 npm(预发布版用 <code>beta</code> 标签,正式版用 <code>latest</code>),正式版再设置 <code>paseo-&lt;小版本&gt;</code> 标签,把 <code>npm pack</code> 的安装包附在 Release 上,Release 正文取自 CHANGELOG 的这一节。标签同时也是 git 方式安装的版本列表,所以改版本号的提交要在验证完成后再合到 <code>main</code>(自动打标签的时机就是它);打错了尽快删除标签,npm 上发布错的版本用 <code>npm deprecate</code> 标注(npm 不允许重新发布同一版本号)。</li><li><strong>通知</strong>:把&quot;使用者会看到的变化&quot;发给使用者,把&quot;升级须知&quot;发给各台机器的安装者;团队配置的 <code>requiredVersion</code> 需要提高时,在团队配置仓库中修改。</li></ol><p><strong>npm 发布的一次性设置</strong>:可信发布(trusted publisher)要在 npm 上已有的包的设置页里配置,所以第一个版本在本机手工发布一次,不需要生成任何口令:</p><ol><li>npmjs.com 账号开启双重验证(2FA);本机 <code>npm login</code>。</li><li>等版本标签的工作流跑到&quot;Publish&quot;(第一次会因为包不存在而失败,前面的测试已经通过),从仓库取出这个标签:<code>git checkout &lt;版本&gt;</code>,执行 <code>npm publish --tag beta --provenance=false</code>(正式版去掉 <code>--tag beta</code>)。本机不能生成来源证明,所以要关掉 provenance;以后由工作流发布的版本会自动带上。</li><li>在 npmjs.com 打开包的 Settings → Trusted publishing,选 GitHub Actions:Organization or user 填 <code>yiyisf</code>,Repository 填 <code>paseo-req-kit</code>,Workflow filename 填 <code>release.yml</code>,Environment 留空,允许的操作勾上 <code>npm publish</code>(和 <code>npm dist-tag</code>)。保存后 2 天内要有一次成功的发布,否则配置失效需要重建。</li><li>到 GitHub Actions 中重新运行这个标签的 release 工作流:版本已经在 npm 上,会跳过发布,只建 GitHub Release。之后的版本推送标签即可自动发布。</li></ol><p>不建议为发布生成长期口令:npm 正在收紧可以跳过 2FA 的口令,计划 2027 年 1 月起不再允许它们直接发布。工作流仍然支持仓库 Secrets 中的 <code>NPM_TOKEN</code>(有就用),供无法用可信发布的内网仓库使用。</p><p><strong>重新发布已有的标签</strong>:GitHub → Actions → release → Run workflow,填版本标签(如 <code>1.7.0-beta.2</code>)。用的是当前 main 上的流程、标签上的代码;手机网页也能操作。npm 发布失败时仍会建好 Release 和 <code>.tgz</code>,最后再报错。</p><p><strong>检查</strong>:<code>ci.yml</code> 在每次推送到 main 和每个 PR 时运行测试、类型检查、评估自检和打包检查。推送版本标签前先确认它是绿的。<code>paseo-&lt;小版本&gt;</code> 标签的设置需要一个口令:在仓库的 Secrets 中加 <code>NPM_TOKEN</code>(自动化口令);不加时工作流会提示手工执行 <code>npm dist-tag add</code>。<code>req upgrade</code> 按各版本声明的 <code>reqKit.paseo</code> 选择版本,不依赖这个标签。</p><p><strong>维护分支</strong>:Paseo 出了新的小版本、<code>main</code> 跟进之后,从上一个支持线的最后版本拉出 <code>release/paseo-&lt;小版本&gt;</code> 分支,只合修复,在那里打补丁版本的标签(工作流会把它标成 <code>paseo-&lt;小版本&gt;</code>);同时在 <code>package.json</code> 中加 <code>&quot;publishConfig&quot;: { &quot;tag&quot;: &quot;paseo-&lt;小版本&gt;&quot; }</code>,避免补丁版本抢走 <code>latest</code>。只维护最新和上一条支持线。</p><p><strong>企业私有仓库</strong>:只代理 npmjs 的不用做什么。需要单独发布到内网仓库时,下载 Release 上的 <code>.tgz</code>,执行 <code>npm publish paseo-req-kit-&lt;版本&gt;.tgz --registry &lt;内网地址&gt; --tag &lt;同名标签&gt;</code>,再在内网仓库设置相同的 <code>paseo-&lt;小版本&gt;</code> 标签。</p><p>没有使用 changesets 等发布工具(见 ADR 0013):发布频率低,CHANGELOG 由人写更贴近使用者。</p><p><strong>对外约定</strong>:通知事件(<code>contracts/notifier-event.md</code>)由各团队自己的 IM 模块读取,同一 <code>schema</code> 内只增加字段;<code>req</code> 的子命令和参数会被写进各团队的使用说明,改名时保留旧名一个主版本。<code>req api</code> 的输出(<code>contracts/cli-json.md</code>)是插件和脚本读取的格式,同一 <code>schema</code> 内只增加字段。</p><h2 id="_5-处理复盘提交的问题" tabindex="-1">5. 处理复盘提交的问题 <a class="header-anchor" href="#_5-处理复盘提交的问题" aria-label="Permalink to &quot;5. 处理复盘提交的问题&quot;">​</a></h2><p><code>/req-retro</code> 会把 req-kit 本身的问题写成报告草稿交给用户。收到后:</p><ol><li>能复现的,先加一个评估用例或对话剧本,确认它在当前版本失败。</li><li>修改后跑同一个评估,确认修好,并且其他用例没有变差。</li><li>在 CHANGELOG 中记录。</li></ol><h2 id="_6-目录速查" tabindex="-1">6. 目录速查 <a class="header-anchor" href="#_6-目录速查" aria-label="Permalink to &quot;6. 目录速查&quot;">​</a></h2><table tabindex="0"><thead><tr><th>目录</th><th>内容</th></tr></thead><tbody><tr><td><code>skills/</code></td><td>安装到各 agent 的 skill:入口、手册、方法、原则、旧入口的引导</td></tr><tr><td><code>principles/INDEX.md</code></td><td>原则索引</td></tr><tr><td><code>engine/src/</code></td><td>引擎:启动器、主流程、配置、状态与迁移、体检、评估运行器</td></tr><tr><td><code>engine/prompts/</code></td><td>步骤提示词(含 <code>00-shared-context.md</code> 和评审小组成员的 <code>panel-member.md</code>)</td></tr><tr><td><code>engine/test/</code></td><td>引擎测试,<code>fake-runtime.ts</code> 是模拟的 Paseo</td></tr><tr><td><code>test/</code></td><td>安装器、体检、skill 的测试</td></tr><tr><td><code>evals/</code></td><td>评估:样例仓库、用例、对话剧本</td></tr><tr><td><code>contracts/</code></td><td>文件格式约定</td></tr><tr><td><code>docs/adr/</code></td><td>设计决定</td></tr><tr><td><code>design/</code></td><td>界面设计规范:tokens、品牌手册、各界面规范、组件、效果图</td></tr><tr><td><code>paseo-plugin/</code></td><td>Paseo 插件:<code>client/</code>(界面,React Native)、<code>server/</code>(daemon 侧,运行 <code>req api</code>)、<code>shared/</code>(RPC 约定)。版本号与根目录的 <code>package.json</code> 相同,升版本时两处一起改</td></tr></tbody></table></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/guide/维护者指南.md">docs/guide/维护者指南.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/guide/维护者指南.md">在 GitHub 上编辑</a></p>',2)])])}const u=o(a,[["render",r]]);export{m as __pageData,u as default};
@@ -0,0 +1 @@
1
+ import{_ as o,o as t,c as d,a2 as c}from"./chunks/framework.BetZR81g.js";const m=JSON.parse('{"title":"维护者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/maintainer.md","filePath":"guide/maintainer.md","lastUpdated":null}'),a={name:"guide/maintainer.md"};function r(s,e,n,i,l,p){return t(),d("div",null,[...e[0]||(e[0]=[c("",2)])])}const u=o(a,[["render",r]]);export{m as __pageData,u as default};
@@ -1 +1 @@
1
- import{_ as e,o as d,c as o,a3 as a}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"分阶段执行与提测","description":"","frontmatter":{},"headers":[],"relativePath":"guide/phases.md","filePath":"guide/phases.md","lastUpdated":1791966569000}'),s={name:"guide/phases.md"};function i(r,t,n,l,c,h){return d(),o("div",null,[...t[0]||(t[0]=[a('<h1 id="分阶段执行与提测" tabindex="-1">分阶段执行与提测 <a class="header-anchor" href="#分阶段执行与提测" aria-label="Permalink to &quot;分阶段执行与提测&quot;">​</a></h1><p>研发和测试常常是两拨人、两个节奏:研发完成要&quot;提测&quot;,测试同事先部署测试环境、准备数据,再验证,或者干脆人工测试。req-kit 把第 3–11 步分成<strong>研发</strong>和<strong>测试验证</strong>两个阶段,中间一个闸口。</p><h2 id="三种执行方式" tabindex="-1">三种执行方式 <a class="header-anchor" href="#三种执行方式" aria-label="Permalink to &quot;三种执行方式&quot;">​</a></h2><table tabindex="0"><thead><tr><th>执行方式</th><th>研发完成时</th><th>适合</th></tr></thead><tbody><tr><td><strong>连续</strong>(默认)</td><td>写好提测说明后直接进入测试验证</td><td>本地就能验证的项目</td></tr><tr><td><strong>分阶段</strong></td><td>停下来通知&quot;研发完成,可以提测&quot;,等人说&quot;开始测试验证&quot;或到预约的时间</td><td>有专门测试、需要先部署测试环境</td></tr><tr><td><strong>只做研发</strong></td><td>写提测说明和研发报告后结束,测试由人完成</td><td>测试必须由人完成</td></tr></tbody></table><p>标准档的需求在确定档位时,<code>/req</code> 会问执行方式(项目配置里定好了就不问),写进需求说明头部:<code>- 执行方式:分阶段</code>。团队可以在项目配置中统一设置:</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;phases&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;mode&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;gated&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } }</span></span></code></pre></div><h2 id="提测说明" tabindex="-1">提测说明 <a class="header-anchor" href="#提测说明" aria-label="Permalink to &quot;提测说明&quot;">​</a></h2><p>研发阶段的最后一步写 <code>handoff.md</code>,三种方式都写:</p><ol><li>这次改了什么(按功能需求列出,附分支和提交范围)</li><li>怎么跑起来(依赖、迁移、配置项、启动命令)</li><li>自测结果(测试、代码评审结论、哪些验收标准已有自动化测试)</li><li>建议重点测试(风险最高的验收标准、回归范围)</li><li>已知问题和未完成项</li><li>测试需要的准备(数据、账号、开关——只写在哪里取,不写口令)</li></ol><h2 id="开始测试验证" tabindex="-1">开始测试验证 <a class="header-anchor" href="#开始测试验证" aria-label="Permalink to &quot;开始测试验证&quot;">​</a></h2><p>收到&quot;研发完成,可以提测&quot;后,在对话中说&quot;开始测试验证&quot;。AI 会讲一遍提测说明,然后确定:</p><ul><li><strong>在哪里验证</strong>:本地启动服务,或<strong>已部署的测试环境</strong>。后者需要和你一起写 <code>test-env.md</code>(地址、如何确认被测版本、账号和口令从哪里取、可用的测试数据)。</li><li><strong>发现缺陷怎么办</strong>:当场修复并复验;<strong>退回研发</strong>(只记录缺陷,回到研发阶段修复、经过代码评审后重新提测);或只记录。</li></ul><p>也可以预约:启动时加 <code>--verify-at 22:00</code>,研发完成后到时自动开始;或在开始命令后加 <code>--at</code>。</p><h2 id="测试同事接手" tabindex="-1">测试同事接手 <a class="header-anchor" href="#测试同事接手" aria-label="Permalink to &quot;测试同事接手&quot;">​</a></h2><p>用&quot;开发时自动新建工作区&quot;开发的需求,研发完成后,测试同事可以在这个项目<strong>任何工作区</strong>的对话中输入:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>/req 开始测试验证 sms-login</span></span></code></pre></div><p>之后的通知发到测试同事的对话,步骤仍在需求自己的工作区中运行。研发阶段仍然只能从发起的对话操作。</p><h2 id="相关配置" tabindex="-1">相关配置 <a class="header-anchor" href="#相关配置" aria-label="Permalink to &quot;相关配置&quot;">​</a></h2><table tabindex="0"><thead><tr><th>配置</th><th>默认</th><th>作用</th></tr></thead><tbody><tr><td><code>phases.mode</code></td><td><code>continuous</code></td><td>执行方式:<code>continuous</code> / <code>gated</code> / <code>develop-only</code></td></tr><tr><td><code>phases.verify.environment</code></td><td><code>local</code></td><td><code>deployed</code>:对已部署的测试环境验证</td></tr><tr><td><code>phases.verify.agents</code></td><td><code>{}</code></td><td>测试阶段用的 agent,例如 <code>{ &quot;reviewer&quot;: { &quot;paseoProfile&quot;: &quot;测试&quot; } }</code></td></tr><tr><td><code>phases.verify.defects</code></td><td><code>fix</code></td><td><code>fix</code> / <code>handback</code> / <code>report</code></td></tr><tr><td><code>phases.verify.serviceStart</code></td><td><code>null</code></td><td>测试阶段是否做服务启动验证;<code>null</code> 按档位</td></tr></tbody></table><p>设计决定见 <a href="/reference/adr/0022-develop-and-verify-phases">ADR 0022</a>。</p>',20)])])}const g=e(s,[["render",i]]);export{u as __pageData,g as default};
1
+ import{_ as e,o as d,c as o,a2 as a}from"./chunks/framework.BetZR81g.js";const u=JSON.parse('{"title":"分阶段执行与提测","description":"","frontmatter":{},"headers":[],"relativePath":"guide/phases.md","filePath":"guide/phases.md","lastUpdated":1791966569000}'),s={name:"guide/phases.md"};function i(r,t,n,l,c,h){return d(),o("div",null,[...t[0]||(t[0]=[a('<h1 id="分阶段执行与提测" tabindex="-1">分阶段执行与提测 <a class="header-anchor" href="#分阶段执行与提测" aria-label="Permalink to &quot;分阶段执行与提测&quot;">​</a></h1><p>研发和测试常常是两拨人、两个节奏:研发完成要&quot;提测&quot;,测试同事先部署测试环境、准备数据,再验证,或者干脆人工测试。req-kit 把第 3–11 步分成<strong>研发</strong>和<strong>测试验证</strong>两个阶段,中间一个闸口。</p><h2 id="三种执行方式" tabindex="-1">三种执行方式 <a class="header-anchor" href="#三种执行方式" aria-label="Permalink to &quot;三种执行方式&quot;">​</a></h2><table tabindex="0"><thead><tr><th>执行方式</th><th>研发完成时</th><th>适合</th></tr></thead><tbody><tr><td><strong>连续</strong>(默认)</td><td>写好提测说明后直接进入测试验证</td><td>本地就能验证的项目</td></tr><tr><td><strong>分阶段</strong></td><td>停下来通知&quot;研发完成,可以提测&quot;,等人说&quot;开始测试验证&quot;或到预约的时间</td><td>有专门测试、需要先部署测试环境</td></tr><tr><td><strong>只做研发</strong></td><td>写提测说明和研发报告后结束,测试由人完成</td><td>测试必须由人完成</td></tr></tbody></table><p>标准档的需求在确定档位时,<code>/req</code> 会问执行方式(项目配置里定好了就不问),写进需求说明头部:<code>- 执行方式:分阶段</code>。团队可以在项目配置中统一设置:</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;phases&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;mode&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;gated&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } }</span></span></code></pre></div><h2 id="提测说明" tabindex="-1">提测说明 <a class="header-anchor" href="#提测说明" aria-label="Permalink to &quot;提测说明&quot;">​</a></h2><p>研发阶段的最后一步写 <code>handoff.md</code>,三种方式都写:</p><ol><li>这次改了什么(按功能需求列出,附分支和提交范围)</li><li>怎么跑起来(依赖、迁移、配置项、启动命令)</li><li>自测结果(测试、代码评审结论、哪些验收标准已有自动化测试)</li><li>建议重点测试(风险最高的验收标准、回归范围)</li><li>已知问题和未完成项</li><li>测试需要的准备(数据、账号、开关——只写在哪里取,不写口令)</li></ol><h2 id="开始测试验证" tabindex="-1">开始测试验证 <a class="header-anchor" href="#开始测试验证" aria-label="Permalink to &quot;开始测试验证&quot;">​</a></h2><p>收到&quot;研发完成,可以提测&quot;后,在对话中说&quot;开始测试验证&quot;。AI 会讲一遍提测说明,然后确定:</p><ul><li><strong>在哪里验证</strong>:本地启动服务,或<strong>已部署的测试环境</strong>。后者需要和你一起写 <code>test-env.md</code>(地址、如何确认被测版本、账号和口令从哪里取、可用的测试数据)。</li><li><strong>发现缺陷怎么办</strong>:当场修复并复验;<strong>退回研发</strong>(只记录缺陷,回到研发阶段修复、经过代码评审后重新提测);或只记录。</li></ul><p>也可以预约:启动时加 <code>--verify-at 22:00</code>,研发完成后到时自动开始;或在开始命令后加 <code>--at</code>。</p><h2 id="测试同事接手" tabindex="-1">测试同事接手 <a class="header-anchor" href="#测试同事接手" aria-label="Permalink to &quot;测试同事接手&quot;">​</a></h2><p>用&quot;开发时自动新建工作区&quot;开发的需求,研发完成后,测试同事可以在这个项目<strong>任何工作区</strong>的对话中输入:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>/req 开始测试验证 sms-login</span></span></code></pre></div><p>之后的通知发到测试同事的对话,步骤仍在需求自己的工作区中运行。研发阶段仍然只能从发起的对话操作。</p><h2 id="相关配置" tabindex="-1">相关配置 <a class="header-anchor" href="#相关配置" aria-label="Permalink to &quot;相关配置&quot;">​</a></h2><table tabindex="0"><thead><tr><th>配置</th><th>默认</th><th>作用</th></tr></thead><tbody><tr><td><code>phases.mode</code></td><td><code>continuous</code></td><td>执行方式:<code>continuous</code> / <code>gated</code> / <code>develop-only</code></td></tr><tr><td><code>phases.verify.environment</code></td><td><code>local</code></td><td><code>deployed</code>:对已部署的测试环境验证</td></tr><tr><td><code>phases.verify.agents</code></td><td><code>{}</code></td><td>测试阶段用的 agent,例如 <code>{ &quot;reviewer&quot;: { &quot;paseoProfile&quot;: &quot;测试&quot; } }</code></td></tr><tr><td><code>phases.verify.defects</code></td><td><code>fix</code></td><td><code>fix</code> / <code>handback</code> / <code>report</code></td></tr><tr><td><code>phases.verify.serviceStart</code></td><td><code>null</code></td><td>测试阶段是否做服务启动验证;<code>null</code> 按档位</td></tr></tbody></table><p>设计决定见 <a href="/reference/adr/0022-develop-and-verify-phases">ADR 0022</a>。</p>',20)])])}const g=e(s,[["render",i]]);export{u as __pageData,g as default};
@@ -1 +1 @@
1
- import{_ as e,o as d,c as o,a3 as a}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"分阶段执行与提测","description":"","frontmatter":{},"headers":[],"relativePath":"guide/phases.md","filePath":"guide/phases.md","lastUpdated":1791966569000}'),s={name:"guide/phases.md"};function i(r,t,n,l,c,h){return d(),o("div",null,[...t[0]||(t[0]=[a("",20)])])}const g=e(s,[["render",i]]);export{u as __pageData,g as default};
1
+ import{_ as e,o as d,c as o,a2 as a}from"./chunks/framework.BetZR81g.js";const u=JSON.parse('{"title":"分阶段执行与提测","description":"","frontmatter":{},"headers":[],"relativePath":"guide/phases.md","filePath":"guide/phases.md","lastUpdated":1791966569000}'),s={name:"guide/phases.md"};function i(r,t,n,l,c,h){return d(),o("div",null,[...t[0]||(t[0]=[a("",20)])])}const g=e(s,[["render",i]]);export{u as __pageData,g as default};
@@ -1,4 +1,4 @@
1
- import{_ as e,o as n,c as a,j as l,a as i}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"项目定制与运行规则","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/project.md","filePath":"guide/project.md","lastUpdated":null}'),t={name:"guide/project.md"};function h(k,s,d,r,E,u){return n(),a("div",null,[...s[0]||(s[0]=[l("div",null,[l("h1",{id:"项目定制与运行规则",tabindex:"-1"},[i("项目定制与运行规则 "),l("a",{class:"header-anchor",href:"#项目定制与运行规则","aria-label":'Permalink to "项目定制与运行规则"'},"​")]),l("h2",{id:"每个需求一个-worktree-工作区",tabindex:"-1"},[i("每个需求一个 worktree 工作区 "),l("a",{class:"header-anchor",href:"#每个需求一个-worktree-工作区","aria-label":'Permalink to "每个需求一个 worktree 工作区"'},"​")]),l("p",null,[i("在 Paseo 中为每个需求新建工作区:"),l("strong",null,"New workspace"),i(" → 选择项目 → "),l("strong",null,"Isolation"),i(" 选 "),l("strong",null,"New worktree"),i(" → 起点选主分支,然后在这个工作区的对话里输入 "),l("code",null,"/req"),i("。")]),l("ul",null,[l("li",null,"流水线在这个工作区自己的目录和分支上运行、提交,不影响项目主目录。"),l("li",null,"同一个目录一次只能运行一条流水线;用了 worktree,几个需求可以同时进行。"),l("li",null,[i("在主目录发起时,"),l("code",null,"/req"),i(" 会先建议改用 worktree;使用者坚持的话,它会新建 "),l("code",null,"feature/<功能目录名>"),i(" 分支再继续。")])]),l("p",null,[l("strong",null,"分支规则"),i(":流水线把启动时检出的分支作为本次需求的工作分支,所有步骤都提交到这里,不切换、不新建分支。它拒绝在默认分支("),l("code",null,"main"),i("、"),l("code",null,"master"),i(" 或 "),l("code",null,"origin/HEAD"),i(" 指向的分支)或 detached HEAD 上启动;续跑时分支变了也会拒绝。")]),l("h2",{id:"档位",tabindex:"-1"},[i("档位 "),l("a",{class:"header-anchor",href:"#档位","aria-label":'Permalink to "档位"'},"​")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"档位"),l("th",null,"适用"),l("th",null,"访谈"),l("th",null,"流程")])]),l("tbody",null,[l("tr",null,[l("td",null,[i("快速("),l("code",null,"quick"),i(")")]),l("td",null,"小改动:文案、样式、配置项、字段显示等,不涉及数据结构、权限、对外接口"),l("td",null,"只问要改什么、改成什么样、不改什么、验收标准"),l("td",null,"审核、评审、缺陷修复各一轮;不做服务启动验证;产物从简")]),l("tr",null,[l("td",null,[i("标准("),l("code",null,"standard"),i(")")]),l("td",null,"其他情况"),l("td",null,"完整访谈"),l("td",null,"审核最多 2 轮、评审最多 3 轮、缺陷修复最多 3 轮")])])]),l("p",null,[l("code",null,"/req"),i(" 会根据需求推荐档位,用户确认后写进 spec("),l("code",null,"- 档位:快速"),i(")。流水线按以下顺序决定档位:"),l("code",null,"--profile"),i(" 参数 → 续跑时沿用上次的档位 → spec 中的档位 → 配置中的 "),l("code",null,"defaultProfile"),i("。各档的轮数和是否做服务启动验证可以在配置的 "),l("code",null,"profiles"),i(" 中调整。")]),l("h2",{id:"需求类型",tabindex:"-1"},[i("需求类型 "),l("a",{class:"header-anchor",href:"#需求类型","aria-label":'Permalink to "需求类型"'},"​")]),l("p",null,[i("spec 头部的 "),l("code",null,"- 类型:"),i(" 决定流水线走哪种做法(1.8 起)。缺陷、重构、评估有自己的做法,新需求和小改动走通常的流程:")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"类型"),l("th",null,"做法"),l("th",null,"关键证据")])]),l("tbody",null,[l("tr",null,[l("td",null,[i("缺陷("),l("code",null,"缺陷"),i("、"),l("code",null,"bug"),i(")")]),l("td",null,[i('方案设计改为"复现与定位":先提交一个修复前失败的复现测试或脚本,写 '),l("code",null,"diagnosis.md"),i("(根因、影响面);复现不了就暂停,把需要补充的信息发回对话。修复要让复现转绿,评审实际确认它修复前失败")]),l("td",null,"同一个复现,修复前失败、修复后通过")]),l("tr",null,[l("td",null,[i("重构("),l("code",null,"重构"),i("、"),l("code",null,"技术改进"),i(")")]),l("td",null,'先补特征测试锁住现有行为并单独提交,再小步改动、每步全绿;评审的首要问题是"行为有没有变"'),l("td",null,"重构前后同一组测试一致")]),l("tr",null,[l("td",null,[i("评估("),l("code",null,"评估"),i("、"),l("code",null,"调研"),i(")")]),l("td",null,[i("只读:调研评估("),l("code",null,"assessment.md"),i(")→ 评估审阅 ⇄ 修订 → 评估报告;没有实现、评审、提测和验证,执行方式按连续")]),l("td",null,"引用的代码位置和实际运行的命令")])])]),l("p",null,[i("各类型的做法写在 "),l("code",null,"engine/prompts/types/<类型>.md"),i(",按步骤分节,接在每一步的任务之后;可以用 "),l("code",null,"prompts.local/types/"),i(" 覆盖。不想用某个类型的做法时,从配置 "),l("code",null,"requirementTypes"),i("(默认 "),l("code",null,'["defect", "refactor", "assessment"]'),i(")中去掉它,这个类型就按新需求处理。设计决定见 ADR 0023。")]),l("h2",{id:"方案确认点-开工前请需求方确认-做完后会看到什么",tabindex:"-1"},[i('方案确认点:开工前请需求方确认"做完后会看到什么" '),l("a",{class:"header-anchor",href:"#方案确认点-开工前请需求方确认-做完后会看到什么","aria-label":'Permalink to "方案确认点:开工前请需求方确认"做完后会看到什么""'},"​")]),l("p",null,[i("方案审核通过后、写代码之前,流水线可以停下来请需求方确认(1.8 起)。方案设计写 "),l("code",null,"preview.md"),i("(按操作顺序描述做完后会看到什么、需要确认的假设、不会变的地方),界面改动还在 "),l("code",null,"prototype/"),i(" 中画出静态的原型页面。对话里的 AI 把要点讲给需求方:确认后执行 "),l("code",null,"--approve"),i("(终端里 "),l("code",null,"req approve <需求>"),i(")开始写代码;要改的,更新需求说明后 "),l("code",null,"--resume"),i(",方案调整后再确认一次。需求方确认过的预览和原型,实现和功能验证都以它为准:界面与原型不一致按缺陷处理。")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"配置"),l("th",null,"默认"),l("th",null,"说明")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"designApproval.mode")]),l("td",null,[l("code",null,"ui")]),l("td",null,[l("code",null,"ui"),i(":方案判断这次是界面改动(结果文件 "),l("code",null,"ui_change"),i(")时才停;"),l("code",null,"always"),i(":每次都停;"),l("code",null,"off"),i(":不停")])]),l("tr",null,[l("td",null,[l("code",null,"designApproval.profiles")]),l("td",null,[l("code",null,'["standard"]')]),l("td",null,"哪些档位使用;快速档默认不停")]),l("tr",null,[l("td",null,[l("code",null,"designApproval.autoContinueHours")]),l("td",null,"0"),l("td",null,[i("大于 0 时,等了这么久还没确认就按方案继续(通过对话执行);0 表示一直等待。等待超过 "),l("code",null,"waitingReminderHours"),i(" 会提醒一次")])])])]),l("p",null,[i('等待确认时进度显示"等待需求方确认方案",需求总览归入"需要处理",外部通知收到 '),l("code",null,"approval"),i(" 事件。评估类需求不写代码,不经过确认点。")]),l("p",null,[l("strong",null,"原型审查页(1.13 起)。"),i(" 有 "),l("code",null,"prototype/"),i(' 的需求,插件的需求页面和"等你处理"里有"审查原型"按钮(等待确认方案时是最醒目的"审查原型并确认方案"),审查页嵌在 Paseo 的网页端和桌面端里打开,手机上在浏览器中打开;终端里是 '),l("code",null,"req review <需求>"),i("。需求方在原型上点选要改的地方(页面记下元素、文字、颜色、大小和位置)、双击直接改文字,切换状态和电脑、手机宽度,然后提交:意见整理成带位置信息的清单转给需求会话(与插件中写修改意见的效果相同),或者直接确认方案。草稿和提交记录在功能目录的 "),l("code",null,".pipeline/review/"),i(" 中,每一版原型也存在那里,原型改过后页面会标出这一版改了哪里。")]),l("p",null,[i("为了让审查页能用,方案设计按约定写原型:每个改动区域标 "),l("code",null,"data-ac"),i("(对应的 AC)和 "),l("code",null,"data-label"),i("(用需求方的话说是什么),各种状态包在 "),l("code",null,'<section data-state="状态名">'),i(" 中,按钮、标题、字段名写最终的文字。原型里的脚本不会运行。")]),l("p",null,[i("审查页由一个本机服务提供:用到时在后台启动,空闲 4 小时后自己退出,只监听 "),l("code",null,"127.0.0.1"),i(",地址中带随机令牌(插件设为只读时给只读的地址)。审查页允许被本机地址上的页面(Paseo 网页端)嵌入;要限定或放开,设 "),l("code",null,"REQ_KIT_REVIEW_FRAME_ANCESTORS"),i("(CSP "),l("code",null,"frame-ancestors"),i(" 的值)。需求方在别的电脑上用浏览器访问 Paseo 网页端时,在运行 Paseo daemon 的机器上设置环境变量 "),l("code",null,"REQ_KIT_REVIEW_HOST"),i("(例如 "),l("code",null,"0.0.0.0"),i(")、"),l("code",null,"REQ_KIT_REVIEW_PUBLIC_URL"),i("(别人访问这台机器用的地址,例如 "),l("code",null,"http://10.1.2.3:6781"),i("),需要时用 "),l("code",null,"REQ_KIT_REVIEW_PORT"),i(" 换端口(默认 6781),然后重启 Paseo daemon 让插件拿到新的环境变量(只设 "),l("code",null,"REQ_KIT_REVIEW_HOST"),i(' 时,地址用这台电脑的计算机名)。没有设置时从别的电脑打开 Paseo 网页、点"审查原型",页面会说明为什么打不开、该怎么设置(1.13)。')]),l("h2",{id:"代码评审分两个方向",tabindex:"-1"},[i("代码评审分两个方向 "),l("a",{class:"header-anchor",href:"#代码评审分两个方向","aria-label":'Permalink to "代码评审分两个方向"'},"​")]),l("p",null,"标准档第一轮代码评审由两位评审者同时进行(1.8 起),各自写意见,再由 reviewer 核实、汇总成一份结论:"),l("ul",null,[l("li",null,[l("strong",null,"规格评审"),i(":每条验收标准是否真的实现并有测试、测试的期望值是否与验收标准的例子一致、有没有做需求之外的事、与确认过的预览是否一致。")]),l("li",null,[l("strong",null,"规范评审"),i(":项目惯例和范例文件、术语表中的代码名称、测试质量、安全与数据、简单性,以及可以变成规则的问题。")])]),l("p",null,[i("两位都用配置的 reviewer agent,相当于多两次评审的用量;之后的轮次只核对修复,仍由一位评审。"),l("code",null,"reviewAxes.enabled"),i(" 设为 "),l("code",null,"false"),i(" 关闭,"),l("code",null,"reviewAxes.profiles"),i(" 选择档位(默认只有标准档)。配置了评审小组("),l("code",null,"reviewPanel"),i(")时,以评审小组为准。")]),l("h2",{id:"验收测试先提交",tabindex:"-1"},[i("验收测试先提交 "),l("a",{class:"header-anchor",href:"#验收测试先提交","aria-label":'Permalink to "验收测试先提交"'},"​")]),l("p",null,"方案判断适合测试先行时,代码实现先把从验收标准的例子写出的测试单独提交一次(这时它们是失败的),在结果文件中写明这些测试文件和那次提交。代码评审前,流水线核对它们之后有没有被改过,被改过的交给评审逐个确认有没有依据:为了让测试通过而放宽断言的,按阻塞提出。"),l("h2",{id:"术语表和范例文件",tabindex:"-1"},[i("术语表和范例文件 "),l("a",{class:"header-anchor",href:"#术语表和范例文件","aria-label":'Permalink to "术语表和范例文件"'},"​")]),l("ul",null,[l("li",null,[l("strong",null,[l("code",null,"GLOSSARY.md")]),i("(仓库根目录):业务词、含义、代码中的名字。"),l("code",null,"/req-setup"),i(" 第一次整理,访谈遇到新词时补充,方案设计为新概念补上代码中的名字;各步骤按它命名,规范评审检查是否一致。")]),l("li",null,[l("strong",null,"范例文件"),i(":"),l("code",null,"/req-setup"),i(" 在 "),l("code",null,"project-notes.md"),i(" 中列出各类代码(接口、页面、测试、迁移脚本)写得最好的文件。方案的每个任务写明参照哪个文件,实现照它的结构、命名、错误处理和测试写法来。")])]),l("h2",{id:"反复出现的问题变成规则",tabindex:"-1"},[i("反复出现的问题变成规则 "),l("a",{class:"header-anchor",href:"#反复出现的问题变成规则","aria-label":'Permalink to "反复出现的问题变成规则"'},"​")]),l("p",null,[i('完成报告把这次评审、质量门、缺陷中"一条项目规则就能挡住"的问题写进功能目录的 '),l("code",null,"lessons.tsv"),i("(类别、问题、出处、建议的规则、放在哪一层)。同一个类别在两个以上的需求里出现时,"),l("code",null,"req digest"),i(' 的需求总览会列在"反复出现的问题"中,'),l("code",null,"/req-retro"),i(" 会建议把它变成 lint 规则、类型约束、测试或项目说明里的一行,批准后落地。已经处理的类别写进 "),l("code",null,".requirement-pipeline/lessons-handled.txt"),i("(一行一个),总览不再提示。")]),l("h2",{id:"质量门-流水线自己运行的检查",tabindex:"-1"},[i("质量门:流水线自己运行的检查 "),l("a",{class:"header-anchor",href:"#质量门-流水线自己运行的检查","aria-label":'Permalink to "质量门:流水线自己运行的检查"'},"​")]),l("p",null,[i("项目配置 "),l("code",null,".requirement-pipeline.json"),i(" 的 "),l("code",null,"checks"),i(" 列出流水线"),l("strong",null,"自己运行"),i("的检查,通常由 "),l("code",null,"/req-setup"),i(" 从实际跑通的命令写入:")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"{")]),i(`
1
+ import{_ as e,o as n,c as a,j as l,a as i}from"./chunks/framework.BetZR81g.js";const p=JSON.parse('{"title":"项目定制与运行规则","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/project.md","filePath":"guide/project.md","lastUpdated":null}'),t={name:"guide/project.md"};function h(k,s,d,r,E,u){return n(),a("div",null,[...s[0]||(s[0]=[l("div",null,[l("h1",{id:"项目定制与运行规则",tabindex:"-1"},[i("项目定制与运行规则 "),l("a",{class:"header-anchor",href:"#项目定制与运行规则","aria-label":'Permalink to "项目定制与运行规则"'},"​")]),l("h2",{id:"每个需求一个-worktree-工作区",tabindex:"-1"},[i("每个需求一个 worktree 工作区 "),l("a",{class:"header-anchor",href:"#每个需求一个-worktree-工作区","aria-label":'Permalink to "每个需求一个 worktree 工作区"'},"​")]),l("p",null,[i("在 Paseo 中为每个需求新建工作区:"),l("strong",null,"New workspace"),i(" → 选择项目 → "),l("strong",null,"Isolation"),i(" 选 "),l("strong",null,"New worktree"),i(" → 起点选主分支,然后在这个工作区的对话里输入 "),l("code",null,"/req"),i("。")]),l("ul",null,[l("li",null,"流水线在这个工作区自己的目录和分支上运行、提交,不影响项目主目录。"),l("li",null,"同一个目录一次只能运行一条流水线;用了 worktree,几个需求可以同时进行。"),l("li",null,[i("在主目录发起时,"),l("code",null,"/req"),i(" 会先建议改用 worktree;使用者坚持的话,它会新建 "),l("code",null,"feature/<功能目录名>"),i(" 分支再继续。")])]),l("p",null,[l("strong",null,"分支规则"),i(":流水线把启动时检出的分支作为本次需求的工作分支,所有步骤都提交到这里,不切换、不新建分支。它拒绝在默认分支("),l("code",null,"main"),i("、"),l("code",null,"master"),i(" 或 "),l("code",null,"origin/HEAD"),i(" 指向的分支)或 detached HEAD 上启动;续跑时分支变了也会拒绝。")]),l("h2",{id:"档位",tabindex:"-1"},[i("档位 "),l("a",{class:"header-anchor",href:"#档位","aria-label":'Permalink to "档位"'},"​")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"档位"),l("th",null,"适用"),l("th",null,"访谈"),l("th",null,"流程")])]),l("tbody",null,[l("tr",null,[l("td",null,[i("快速("),l("code",null,"quick"),i(")")]),l("td",null,"小改动:文案、样式、配置项、字段显示等,不涉及数据结构、权限、对外接口"),l("td",null,"只问要改什么、改成什么样、不改什么、验收标准"),l("td",null,"审核、评审、缺陷修复各一轮;不做服务启动验证;产物从简")]),l("tr",null,[l("td",null,[i("标准("),l("code",null,"standard"),i(")")]),l("td",null,"其他情况"),l("td",null,"完整访谈"),l("td",null,"审核最多 2 轮、评审最多 3 轮、缺陷修复最多 3 轮")])])]),l("p",null,[l("code",null,"/req"),i(" 会根据需求推荐档位,用户确认后写进 spec("),l("code",null,"- 档位:快速"),i(")。流水线按以下顺序决定档位:"),l("code",null,"--profile"),i(" 参数 → 续跑时沿用上次的档位 → spec 中的档位 → 配置中的 "),l("code",null,"defaultProfile"),i("。各档的轮数和是否做服务启动验证可以在配置的 "),l("code",null,"profiles"),i(" 中调整。")]),l("h2",{id:"需求类型",tabindex:"-1"},[i("需求类型 "),l("a",{class:"header-anchor",href:"#需求类型","aria-label":'Permalink to "需求类型"'},"​")]),l("p",null,[i("spec 头部的 "),l("code",null,"- 类型:"),i(" 决定流水线走哪种做法(1.8 起)。缺陷、重构、评估有自己的做法,新需求和小改动走通常的流程:")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"类型"),l("th",null,"做法"),l("th",null,"关键证据")])]),l("tbody",null,[l("tr",null,[l("td",null,[i("缺陷("),l("code",null,"缺陷"),i("、"),l("code",null,"bug"),i(")")]),l("td",null,[i('方案设计改为"复现与定位":先提交一个修复前失败的复现测试或脚本,写 '),l("code",null,"diagnosis.md"),i("(根因、影响面);复现不了就暂停,把需要补充的信息发回对话。修复要让复现转绿,评审实际确认它修复前失败")]),l("td",null,"同一个复现,修复前失败、修复后通过")]),l("tr",null,[l("td",null,[i("重构("),l("code",null,"重构"),i("、"),l("code",null,"技术改进"),i(")")]),l("td",null,'先补特征测试锁住现有行为并单独提交,再小步改动、每步全绿;评审的首要问题是"行为有没有变"'),l("td",null,"重构前后同一组测试一致")]),l("tr",null,[l("td",null,[i("评估("),l("code",null,"评估"),i("、"),l("code",null,"调研"),i(")")]),l("td",null,[i("只读:调研评估("),l("code",null,"assessment.md"),i(")→ 评估审阅 ⇄ 修订 → 评估报告;没有实现、评审、提测和验证,执行方式按连续")]),l("td",null,"引用的代码位置和实际运行的命令")])])]),l("p",null,[i("各类型的做法写在 "),l("code",null,"engine/prompts/types/<类型>.md"),i(",按步骤分节,接在每一步的任务之后;可以用 "),l("code",null,"prompts.local/types/"),i(" 覆盖。不想用某个类型的做法时,从配置 "),l("code",null,"requirementTypes"),i("(默认 "),l("code",null,'["defect", "refactor", "assessment"]'),i(")中去掉它,这个类型就按新需求处理。设计决定见 ADR 0023。")]),l("h2",{id:"方案确认点-开工前请需求方确认-做完后会看到什么",tabindex:"-1"},[i('方案确认点:开工前请需求方确认"做完后会看到什么" '),l("a",{class:"header-anchor",href:"#方案确认点-开工前请需求方确认-做完后会看到什么","aria-label":'Permalink to "方案确认点:开工前请需求方确认"做完后会看到什么""'},"​")]),l("p",null,[i("方案审核通过后、写代码之前,流水线可以停下来请需求方确认(1.8 起)。方案设计写 "),l("code",null,"preview.md"),i("(按操作顺序描述做完后会看到什么、需要确认的假设、不会变的地方),界面改动还在 "),l("code",null,"prototype/"),i(" 中画出静态的原型页面。对话里的 AI 把要点讲给需求方:确认后执行 "),l("code",null,"--approve"),i("(终端里 "),l("code",null,"req approve <需求>"),i(")开始写代码;要改的,更新需求说明后 "),l("code",null,"--resume"),i(",方案调整后再确认一次。需求方确认过的预览和原型,实现和功能验证都以它为准:界面与原型不一致按缺陷处理。")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"配置"),l("th",null,"默认"),l("th",null,"说明")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"designApproval.mode")]),l("td",null,[l("code",null,"ui")]),l("td",null,[l("code",null,"ui"),i(":方案判断这次是界面改动(结果文件 "),l("code",null,"ui_change"),i(")时才停;"),l("code",null,"always"),i(":每次都停;"),l("code",null,"off"),i(":不停")])]),l("tr",null,[l("td",null,[l("code",null,"designApproval.profiles")]),l("td",null,[l("code",null,'["standard"]')]),l("td",null,"哪些档位使用;快速档默认不停")]),l("tr",null,[l("td",null,[l("code",null,"designApproval.autoContinueHours")]),l("td",null,"0"),l("td",null,[i("大于 0 时,等了这么久还没确认就按方案继续(通过对话执行);0 表示一直等待。等待超过 "),l("code",null,"waitingReminderHours"),i(" 会提醒一次")])])])]),l("p",null,[i('等待确认时进度显示"等待需求方确认方案",需求总览归入"需要处理",外部通知收到 '),l("code",null,"approval"),i(" 事件。评估类需求不写代码,不经过确认点。")]),l("p",null,[l("strong",null,"原型审查页(1.13 起)。"),i(" 有 "),l("code",null,"prototype/"),i(' 的需求,插件的需求页面和"等你处理"里有"审查原型"按钮(等待确认方案时是最醒目的"审查原型并确认方案"),审查页嵌在 Paseo 的网页端和桌面端里打开,手机上在浏览器中打开;终端里是 '),l("code",null,"req review <需求>"),i("。需求方在原型上点选要改的地方(页面记下元素、文字、颜色、大小和位置)、双击直接改文字,切换状态和电脑、手机宽度,然后提交:意见整理成带位置信息的清单转给需求会话(与插件中写修改意见的效果相同),或者直接确认方案。草稿和提交记录在功能目录的 "),l("code",null,".pipeline/review/"),i(" 中,每一版原型也存在那里,原型改过后页面会标出这一版改了哪里。")]),l("p",null,[i("为了让审查页能用,方案设计按约定写原型:每个改动区域标 "),l("code",null,"data-ac"),i("(对应的 AC)和 "),l("code",null,"data-label"),i("(用需求方的话说是什么),各种状态包在 "),l("code",null,'<section data-state="状态名">'),i(" 中,按钮、标题、字段名写最终的文字。原型里的脚本不会运行。")]),l("p",null,[i("审查页由一个本机服务提供:用到时在后台启动,空闲 4 小时后自己退出,只监听 "),l("code",null,"127.0.0.1"),i(",地址中带随机令牌(插件设为只读时给只读的地址)。审查页允许被本机地址上的页面(Paseo 网页端)嵌入;要限定或放开,设 "),l("code",null,"REQ_KIT_REVIEW_FRAME_ANCESTORS"),i("(CSP "),l("code",null,"frame-ancestors"),i(" 的值)。需求方在别的电脑上用浏览器访问 Paseo 网页端时,在运行 Paseo daemon 的机器上设置环境变量 "),l("code",null,"REQ_KIT_REVIEW_HOST"),i("(例如 "),l("code",null,"0.0.0.0"),i(")、"),l("code",null,"REQ_KIT_REVIEW_PUBLIC_URL"),i("(别人访问这台机器用的地址,例如 "),l("code",null,"http://10.1.2.3:6781"),i("),需要时用 "),l("code",null,"REQ_KIT_REVIEW_PORT"),i(" 换端口(默认 6781),然后重启 Paseo daemon 让插件拿到新的环境变量(只设 "),l("code",null,"REQ_KIT_REVIEW_HOST"),i(' 时,地址用这台电脑的计算机名)。没有设置时从别的电脑打开 Paseo 网页、点"审查原型",页面会说明为什么打不开、该怎么设置(1.13)。')]),l("h2",{id:"代码评审分两个方向",tabindex:"-1"},[i("代码评审分两个方向 "),l("a",{class:"header-anchor",href:"#代码评审分两个方向","aria-label":'Permalink to "代码评审分两个方向"'},"​")]),l("p",null,"标准档第一轮代码评审由两位评审者同时进行(1.8 起),各自写意见,再由 reviewer 核实、汇总成一份结论:"),l("ul",null,[l("li",null,[l("strong",null,"规格评审"),i(":每条验收标准是否真的实现并有测试、测试的期望值是否与验收标准的例子一致、有没有做需求之外的事、与确认过的预览是否一致。")]),l("li",null,[l("strong",null,"规范评审"),i(":项目惯例和范例文件、术语表中的代码名称、测试质量、安全与数据、简单性,以及可以变成规则的问题。")])]),l("p",null,[i("两位都用配置的 reviewer agent,相当于多两次评审的用量;之后的轮次只核对修复,仍由一位评审。"),l("code",null,"reviewAxes.enabled"),i(" 设为 "),l("code",null,"false"),i(" 关闭,"),l("code",null,"reviewAxes.profiles"),i(" 选择档位(默认只有标准档)。配置了评审小组("),l("code",null,"reviewPanel"),i(")时,以评审小组为准。")]),l("h2",{id:"验收测试先提交",tabindex:"-1"},[i("验收测试先提交 "),l("a",{class:"header-anchor",href:"#验收测试先提交","aria-label":'Permalink to "验收测试先提交"'},"​")]),l("p",null,"方案判断适合测试先行时,代码实现先把从验收标准的例子写出的测试单独提交一次(这时它们是失败的),在结果文件中写明这些测试文件和那次提交。代码评审前,流水线核对它们之后有没有被改过,被改过的交给评审逐个确认有没有依据:为了让测试通过而放宽断言的,按阻塞提出。"),l("h2",{id:"术语表和范例文件",tabindex:"-1"},[i("术语表和范例文件 "),l("a",{class:"header-anchor",href:"#术语表和范例文件","aria-label":'Permalink to "术语表和范例文件"'},"​")]),l("ul",null,[l("li",null,[l("strong",null,[l("code",null,"GLOSSARY.md")]),i("(仓库根目录):业务词、含义、代码中的名字。"),l("code",null,"/req-setup"),i(" 第一次整理,访谈遇到新词时补充,方案设计为新概念补上代码中的名字;各步骤按它命名,规范评审检查是否一致。")]),l("li",null,[l("strong",null,"范例文件"),i(":"),l("code",null,"/req-setup"),i(" 在 "),l("code",null,"project-notes.md"),i(" 中列出各类代码(接口、页面、测试、迁移脚本)写得最好的文件。方案的每个任务写明参照哪个文件,实现照它的结构、命名、错误处理和测试写法来。")])]),l("h2",{id:"反复出现的问题变成规则",tabindex:"-1"},[i("反复出现的问题变成规则 "),l("a",{class:"header-anchor",href:"#反复出现的问题变成规则","aria-label":'Permalink to "反复出现的问题变成规则"'},"​")]),l("p",null,[i('完成报告把这次评审、质量门、缺陷中"一条项目规则就能挡住"的问题写进功能目录的 '),l("code",null,"lessons.tsv"),i("(类别、问题、出处、建议的规则、放在哪一层)。同一个类别在两个以上的需求里出现时,"),l("code",null,"req digest"),i(' 的需求总览会列在"反复出现的问题"中,'),l("code",null,"/req-retro"),i(" 会建议把它变成 lint 规则、类型约束、测试或项目说明里的一行,批准后落地。已经处理的类别写进 "),l("code",null,".requirement-pipeline/lessons-handled.txt"),i("(一行一个),总览不再提示。")]),l("h2",{id:"质量门-流水线自己运行的检查",tabindex:"-1"},[i("质量门:流水线自己运行的检查 "),l("a",{class:"header-anchor",href:"#质量门-流水线自己运行的检查","aria-label":'Permalink to "质量门:流水线自己运行的检查"'},"​")]),l("p",null,[i("项目配置 "),l("code",null,".requirement-pipeline.json"),i(" 的 "),l("code",null,"checks"),i(" 列出流水线"),l("strong",null,"自己运行"),i("的检查,通常由 "),l("code",null,"/req-setup"),i(" 从实际跑通的命令写入:")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"{")]),i(`
2
2
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "checks"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": [")]),i(`
3
3
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"lint"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"command"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"npm run lint"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),i(`
4
4
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"web 测试"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"command"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"npm test"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"cwd"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"web"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),i(`
@@ -1,4 +1,4 @@
1
- import{_ as e,o as n,c as a,j as l,a as i}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"项目定制与运行规则","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/project.md","filePath":"guide/project.md","lastUpdated":null}'),t={name:"guide/project.md"};function h(k,s,d,r,E,u){return n(),a("div",null,[...s[0]||(s[0]=[l("div",null,[l("h1",{id:"项目定制与运行规则",tabindex:"-1"},[i("项目定制与运行规则 "),l("a",{class:"header-anchor",href:"#项目定制与运行规则","aria-label":'Permalink to "项目定制与运行规则"'},"​")]),l("h2",{id:"每个需求一个-worktree-工作区",tabindex:"-1"},[i("每个需求一个 worktree 工作区 "),l("a",{class:"header-anchor",href:"#每个需求一个-worktree-工作区","aria-label":'Permalink to "每个需求一个 worktree 工作区"'},"​")]),l("p",null,[i("在 Paseo 中为每个需求新建工作区:"),l("strong",null,"New workspace"),i(" → 选择项目 → "),l("strong",null,"Isolation"),i(" 选 "),l("strong",null,"New worktree"),i(" → 起点选主分支,然后在这个工作区的对话里输入 "),l("code",null,"/req"),i("。")]),l("ul",null,[l("li",null,"流水线在这个工作区自己的目录和分支上运行、提交,不影响项目主目录。"),l("li",null,"同一个目录一次只能运行一条流水线;用了 worktree,几个需求可以同时进行。"),l("li",null,[i("在主目录发起时,"),l("code",null,"/req"),i(" 会先建议改用 worktree;使用者坚持的话,它会新建 "),l("code",null,"feature/<功能目录名>"),i(" 分支再继续。")])]),l("p",null,[l("strong",null,"分支规则"),i(":流水线把启动时检出的分支作为本次需求的工作分支,所有步骤都提交到这里,不切换、不新建分支。它拒绝在默认分支("),l("code",null,"main"),i("、"),l("code",null,"master"),i(" 或 "),l("code",null,"origin/HEAD"),i(" 指向的分支)或 detached HEAD 上启动;续跑时分支变了也会拒绝。")]),l("h2",{id:"档位",tabindex:"-1"},[i("档位 "),l("a",{class:"header-anchor",href:"#档位","aria-label":'Permalink to "档位"'},"​")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"档位"),l("th",null,"适用"),l("th",null,"访谈"),l("th",null,"流程")])]),l("tbody",null,[l("tr",null,[l("td",null,[i("快速("),l("code",null,"quick"),i(")")]),l("td",null,"小改动:文案、样式、配置项、字段显示等,不涉及数据结构、权限、对外接口"),l("td",null,"只问要改什么、改成什么样、不改什么、验收标准"),l("td",null,"审核、评审、缺陷修复各一轮;不做服务启动验证;产物从简")]),l("tr",null,[l("td",null,[i("标准("),l("code",null,"standard"),i(")")]),l("td",null,"其他情况"),l("td",null,"完整访谈"),l("td",null,"审核最多 2 轮、评审最多 3 轮、缺陷修复最多 3 轮")])])]),l("p",null,[l("code",null,"/req"),i(" 会根据需求推荐档位,用户确认后写进 spec("),l("code",null,"- 档位:快速"),i(")。流水线按以下顺序决定档位:"),l("code",null,"--profile"),i(" 参数 → 续跑时沿用上次的档位 → spec 中的档位 → 配置中的 "),l("code",null,"defaultProfile"),i("。各档的轮数和是否做服务启动验证可以在配置的 "),l("code",null,"profiles"),i(" 中调整。")]),l("h2",{id:"需求类型",tabindex:"-1"},[i("需求类型 "),l("a",{class:"header-anchor",href:"#需求类型","aria-label":'Permalink to "需求类型"'},"​")]),l("p",null,[i("spec 头部的 "),l("code",null,"- 类型:"),i(" 决定流水线走哪种做法(1.8 起)。缺陷、重构、评估有自己的做法,新需求和小改动走通常的流程:")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"类型"),l("th",null,"做法"),l("th",null,"关键证据")])]),l("tbody",null,[l("tr",null,[l("td",null,[i("缺陷("),l("code",null,"缺陷"),i("、"),l("code",null,"bug"),i(")")]),l("td",null,[i('方案设计改为"复现与定位":先提交一个修复前失败的复现测试或脚本,写 '),l("code",null,"diagnosis.md"),i("(根因、影响面);复现不了就暂停,把需要补充的信息发回对话。修复要让复现转绿,评审实际确认它修复前失败")]),l("td",null,"同一个复现,修复前失败、修复后通过")]),l("tr",null,[l("td",null,[i("重构("),l("code",null,"重构"),i("、"),l("code",null,"技术改进"),i(")")]),l("td",null,'先补特征测试锁住现有行为并单独提交,再小步改动、每步全绿;评审的首要问题是"行为有没有变"'),l("td",null,"重构前后同一组测试一致")]),l("tr",null,[l("td",null,[i("评估("),l("code",null,"评估"),i("、"),l("code",null,"调研"),i(")")]),l("td",null,[i("只读:调研评估("),l("code",null,"assessment.md"),i(")→ 评估审阅 ⇄ 修订 → 评估报告;没有实现、评审、提测和验证,执行方式按连续")]),l("td",null,"引用的代码位置和实际运行的命令")])])]),l("p",null,[i("各类型的做法写在 "),l("code",null,"engine/prompts/types/<类型>.md"),i(",按步骤分节,接在每一步的任务之后;可以用 "),l("code",null,"prompts.local/types/"),i(" 覆盖。不想用某个类型的做法时,从配置 "),l("code",null,"requirementTypes"),i("(默认 "),l("code",null,'["defect", "refactor", "assessment"]'),i(")中去掉它,这个类型就按新需求处理。设计决定见 ADR 0023。")]),l("h2",{id:"方案确认点-开工前请需求方确认-做完后会看到什么",tabindex:"-1"},[i('方案确认点:开工前请需求方确认"做完后会看到什么" '),l("a",{class:"header-anchor",href:"#方案确认点-开工前请需求方确认-做完后会看到什么","aria-label":'Permalink to "方案确认点:开工前请需求方确认"做完后会看到什么""'},"​")]),l("p",null,[i("方案审核通过后、写代码之前,流水线可以停下来请需求方确认(1.8 起)。方案设计写 "),l("code",null,"preview.md"),i("(按操作顺序描述做完后会看到什么、需要确认的假设、不会变的地方),界面改动还在 "),l("code",null,"prototype/"),i(" 中画出静态的原型页面。对话里的 AI 把要点讲给需求方:确认后执行 "),l("code",null,"--approve"),i("(终端里 "),l("code",null,"req approve <需求>"),i(")开始写代码;要改的,更新需求说明后 "),l("code",null,"--resume"),i(",方案调整后再确认一次。需求方确认过的预览和原型,实现和功能验证都以它为准:界面与原型不一致按缺陷处理。")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"配置"),l("th",null,"默认"),l("th",null,"说明")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"designApproval.mode")]),l("td",null,[l("code",null,"ui")]),l("td",null,[l("code",null,"ui"),i(":方案判断这次是界面改动(结果文件 "),l("code",null,"ui_change"),i(")时才停;"),l("code",null,"always"),i(":每次都停;"),l("code",null,"off"),i(":不停")])]),l("tr",null,[l("td",null,[l("code",null,"designApproval.profiles")]),l("td",null,[l("code",null,'["standard"]')]),l("td",null,"哪些档位使用;快速档默认不停")]),l("tr",null,[l("td",null,[l("code",null,"designApproval.autoContinueHours")]),l("td",null,"0"),l("td",null,[i("大于 0 时,等了这么久还没确认就按方案继续(通过对话执行);0 表示一直等待。等待超过 "),l("code",null,"waitingReminderHours"),i(" 会提醒一次")])])])]),l("p",null,[i('等待确认时进度显示"等待需求方确认方案",需求总览归入"需要处理",外部通知收到 '),l("code",null,"approval"),i(" 事件。评估类需求不写代码,不经过确认点。")]),l("p",null,[l("strong",null,"原型审查页(1.13 起)。"),i(" 有 "),l("code",null,"prototype/"),i(' 的需求,插件的需求页面和"等你处理"里有"审查原型"按钮(等待确认方案时是最醒目的"审查原型并确认方案"),审查页嵌在 Paseo 的网页端和桌面端里打开,手机上在浏览器中打开;终端里是 '),l("code",null,"req review <需求>"),i("。需求方在原型上点选要改的地方(页面记下元素、文字、颜色、大小和位置)、双击直接改文字,切换状态和电脑、手机宽度,然后提交:意见整理成带位置信息的清单转给需求会话(与插件中写修改意见的效果相同),或者直接确认方案。草稿和提交记录在功能目录的 "),l("code",null,".pipeline/review/"),i(" 中,每一版原型也存在那里,原型改过后页面会标出这一版改了哪里。")]),l("p",null,[i("为了让审查页能用,方案设计按约定写原型:每个改动区域标 "),l("code",null,"data-ac"),i("(对应的 AC)和 "),l("code",null,"data-label"),i("(用需求方的话说是什么),各种状态包在 "),l("code",null,'<section data-state="状态名">'),i(" 中,按钮、标题、字段名写最终的文字。原型里的脚本不会运行。")]),l("p",null,[i("审查页由一个本机服务提供:用到时在后台启动,空闲 4 小时后自己退出,只监听 "),l("code",null,"127.0.0.1"),i(",地址中带随机令牌(插件设为只读时给只读的地址)。审查页允许被本机地址上的页面(Paseo 网页端)嵌入;要限定或放开,设 "),l("code",null,"REQ_KIT_REVIEW_FRAME_ANCESTORS"),i("(CSP "),l("code",null,"frame-ancestors"),i(" 的值)。需求方在别的电脑上用浏览器访问 Paseo 网页端时,在运行 Paseo daemon 的机器上设置环境变量 "),l("code",null,"REQ_KIT_REVIEW_HOST"),i("(例如 "),l("code",null,"0.0.0.0"),i(")、"),l("code",null,"REQ_KIT_REVIEW_PUBLIC_URL"),i("(别人访问这台机器用的地址,例如 "),l("code",null,"http://10.1.2.3:6781"),i("),需要时用 "),l("code",null,"REQ_KIT_REVIEW_PORT"),i(" 换端口(默认 6781),然后重启 Paseo daemon 让插件拿到新的环境变量(只设 "),l("code",null,"REQ_KIT_REVIEW_HOST"),i(' 时,地址用这台电脑的计算机名)。没有设置时从别的电脑打开 Paseo 网页、点"审查原型",页面会说明为什么打不开、该怎么设置(1.13)。')]),l("h2",{id:"代码评审分两个方向",tabindex:"-1"},[i("代码评审分两个方向 "),l("a",{class:"header-anchor",href:"#代码评审分两个方向","aria-label":'Permalink to "代码评审分两个方向"'},"​")]),l("p",null,"标准档第一轮代码评审由两位评审者同时进行(1.8 起),各自写意见,再由 reviewer 核实、汇总成一份结论:"),l("ul",null,[l("li",null,[l("strong",null,"规格评审"),i(":每条验收标准是否真的实现并有测试、测试的期望值是否与验收标准的例子一致、有没有做需求之外的事、与确认过的预览是否一致。")]),l("li",null,[l("strong",null,"规范评审"),i(":项目惯例和范例文件、术语表中的代码名称、测试质量、安全与数据、简单性,以及可以变成规则的问题。")])]),l("p",null,[i("两位都用配置的 reviewer agent,相当于多两次评审的用量;之后的轮次只核对修复,仍由一位评审。"),l("code",null,"reviewAxes.enabled"),i(" 设为 "),l("code",null,"false"),i(" 关闭,"),l("code",null,"reviewAxes.profiles"),i(" 选择档位(默认只有标准档)。配置了评审小组("),l("code",null,"reviewPanel"),i(")时,以评审小组为准。")]),l("h2",{id:"验收测试先提交",tabindex:"-1"},[i("验收测试先提交 "),l("a",{class:"header-anchor",href:"#验收测试先提交","aria-label":'Permalink to "验收测试先提交"'},"​")]),l("p",null,"方案判断适合测试先行时,代码实现先把从验收标准的例子写出的测试单独提交一次(这时它们是失败的),在结果文件中写明这些测试文件和那次提交。代码评审前,流水线核对它们之后有没有被改过,被改过的交给评审逐个确认有没有依据:为了让测试通过而放宽断言的,按阻塞提出。"),l("h2",{id:"术语表和范例文件",tabindex:"-1"},[i("术语表和范例文件 "),l("a",{class:"header-anchor",href:"#术语表和范例文件","aria-label":'Permalink to "术语表和范例文件"'},"​")]),l("ul",null,[l("li",null,[l("strong",null,[l("code",null,"GLOSSARY.md")]),i("(仓库根目录):业务词、含义、代码中的名字。"),l("code",null,"/req-setup"),i(" 第一次整理,访谈遇到新词时补充,方案设计为新概念补上代码中的名字;各步骤按它命名,规范评审检查是否一致。")]),l("li",null,[l("strong",null,"范例文件"),i(":"),l("code",null,"/req-setup"),i(" 在 "),l("code",null,"project-notes.md"),i(" 中列出各类代码(接口、页面、测试、迁移脚本)写得最好的文件。方案的每个任务写明参照哪个文件,实现照它的结构、命名、错误处理和测试写法来。")])]),l("h2",{id:"反复出现的问题变成规则",tabindex:"-1"},[i("反复出现的问题变成规则 "),l("a",{class:"header-anchor",href:"#反复出现的问题变成规则","aria-label":'Permalink to "反复出现的问题变成规则"'},"​")]),l("p",null,[i('完成报告把这次评审、质量门、缺陷中"一条项目规则就能挡住"的问题写进功能目录的 '),l("code",null,"lessons.tsv"),i("(类别、问题、出处、建议的规则、放在哪一层)。同一个类别在两个以上的需求里出现时,"),l("code",null,"req digest"),i(' 的需求总览会列在"反复出现的问题"中,'),l("code",null,"/req-retro"),i(" 会建议把它变成 lint 规则、类型约束、测试或项目说明里的一行,批准后落地。已经处理的类别写进 "),l("code",null,".requirement-pipeline/lessons-handled.txt"),i("(一行一个),总览不再提示。")]),l("h2",{id:"质量门-流水线自己运行的检查",tabindex:"-1"},[i("质量门:流水线自己运行的检查 "),l("a",{class:"header-anchor",href:"#质量门-流水线自己运行的检查","aria-label":'Permalink to "质量门:流水线自己运行的检查"'},"​")]),l("p",null,[i("项目配置 "),l("code",null,".requirement-pipeline.json"),i(" 的 "),l("code",null,"checks"),i(" 列出流水线"),l("strong",null,"自己运行"),i("的检查,通常由 "),l("code",null,"/req-setup"),i(" 从实际跑通的命令写入:")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"{")]),i(`
1
+ import{_ as e,o as n,c as a,j as l,a as i}from"./chunks/framework.BetZR81g.js";const p=JSON.parse('{"title":"项目定制与运行规则","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/project.md","filePath":"guide/project.md","lastUpdated":null}'),t={name:"guide/project.md"};function h(k,s,d,r,E,u){return n(),a("div",null,[...s[0]||(s[0]=[l("div",null,[l("h1",{id:"项目定制与运行规则",tabindex:"-1"},[i("项目定制与运行规则 "),l("a",{class:"header-anchor",href:"#项目定制与运行规则","aria-label":'Permalink to "项目定制与运行规则"'},"​")]),l("h2",{id:"每个需求一个-worktree-工作区",tabindex:"-1"},[i("每个需求一个 worktree 工作区 "),l("a",{class:"header-anchor",href:"#每个需求一个-worktree-工作区","aria-label":'Permalink to "每个需求一个 worktree 工作区"'},"​")]),l("p",null,[i("在 Paseo 中为每个需求新建工作区:"),l("strong",null,"New workspace"),i(" → 选择项目 → "),l("strong",null,"Isolation"),i(" 选 "),l("strong",null,"New worktree"),i(" → 起点选主分支,然后在这个工作区的对话里输入 "),l("code",null,"/req"),i("。")]),l("ul",null,[l("li",null,"流水线在这个工作区自己的目录和分支上运行、提交,不影响项目主目录。"),l("li",null,"同一个目录一次只能运行一条流水线;用了 worktree,几个需求可以同时进行。"),l("li",null,[i("在主目录发起时,"),l("code",null,"/req"),i(" 会先建议改用 worktree;使用者坚持的话,它会新建 "),l("code",null,"feature/<功能目录名>"),i(" 分支再继续。")])]),l("p",null,[l("strong",null,"分支规则"),i(":流水线把启动时检出的分支作为本次需求的工作分支,所有步骤都提交到这里,不切换、不新建分支。它拒绝在默认分支("),l("code",null,"main"),i("、"),l("code",null,"master"),i(" 或 "),l("code",null,"origin/HEAD"),i(" 指向的分支)或 detached HEAD 上启动;续跑时分支变了也会拒绝。")]),l("h2",{id:"档位",tabindex:"-1"},[i("档位 "),l("a",{class:"header-anchor",href:"#档位","aria-label":'Permalink to "档位"'},"​")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"档位"),l("th",null,"适用"),l("th",null,"访谈"),l("th",null,"流程")])]),l("tbody",null,[l("tr",null,[l("td",null,[i("快速("),l("code",null,"quick"),i(")")]),l("td",null,"小改动:文案、样式、配置项、字段显示等,不涉及数据结构、权限、对外接口"),l("td",null,"只问要改什么、改成什么样、不改什么、验收标准"),l("td",null,"审核、评审、缺陷修复各一轮;不做服务启动验证;产物从简")]),l("tr",null,[l("td",null,[i("标准("),l("code",null,"standard"),i(")")]),l("td",null,"其他情况"),l("td",null,"完整访谈"),l("td",null,"审核最多 2 轮、评审最多 3 轮、缺陷修复最多 3 轮")])])]),l("p",null,[l("code",null,"/req"),i(" 会根据需求推荐档位,用户确认后写进 spec("),l("code",null,"- 档位:快速"),i(")。流水线按以下顺序决定档位:"),l("code",null,"--profile"),i(" 参数 → 续跑时沿用上次的档位 → spec 中的档位 → 配置中的 "),l("code",null,"defaultProfile"),i("。各档的轮数和是否做服务启动验证可以在配置的 "),l("code",null,"profiles"),i(" 中调整。")]),l("h2",{id:"需求类型",tabindex:"-1"},[i("需求类型 "),l("a",{class:"header-anchor",href:"#需求类型","aria-label":'Permalink to "需求类型"'},"​")]),l("p",null,[i("spec 头部的 "),l("code",null,"- 类型:"),i(" 决定流水线走哪种做法(1.8 起)。缺陷、重构、评估有自己的做法,新需求和小改动走通常的流程:")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"类型"),l("th",null,"做法"),l("th",null,"关键证据")])]),l("tbody",null,[l("tr",null,[l("td",null,[i("缺陷("),l("code",null,"缺陷"),i("、"),l("code",null,"bug"),i(")")]),l("td",null,[i('方案设计改为"复现与定位":先提交一个修复前失败的复现测试或脚本,写 '),l("code",null,"diagnosis.md"),i("(根因、影响面);复现不了就暂停,把需要补充的信息发回对话。修复要让复现转绿,评审实际确认它修复前失败")]),l("td",null,"同一个复现,修复前失败、修复后通过")]),l("tr",null,[l("td",null,[i("重构("),l("code",null,"重构"),i("、"),l("code",null,"技术改进"),i(")")]),l("td",null,'先补特征测试锁住现有行为并单独提交,再小步改动、每步全绿;评审的首要问题是"行为有没有变"'),l("td",null,"重构前后同一组测试一致")]),l("tr",null,[l("td",null,[i("评估("),l("code",null,"评估"),i("、"),l("code",null,"调研"),i(")")]),l("td",null,[i("只读:调研评估("),l("code",null,"assessment.md"),i(")→ 评估审阅 ⇄ 修订 → 评估报告;没有实现、评审、提测和验证,执行方式按连续")]),l("td",null,"引用的代码位置和实际运行的命令")])])]),l("p",null,[i("各类型的做法写在 "),l("code",null,"engine/prompts/types/<类型>.md"),i(",按步骤分节,接在每一步的任务之后;可以用 "),l("code",null,"prompts.local/types/"),i(" 覆盖。不想用某个类型的做法时,从配置 "),l("code",null,"requirementTypes"),i("(默认 "),l("code",null,'["defect", "refactor", "assessment"]'),i(")中去掉它,这个类型就按新需求处理。设计决定见 ADR 0023。")]),l("h2",{id:"方案确认点-开工前请需求方确认-做完后会看到什么",tabindex:"-1"},[i('方案确认点:开工前请需求方确认"做完后会看到什么" '),l("a",{class:"header-anchor",href:"#方案确认点-开工前请需求方确认-做完后会看到什么","aria-label":'Permalink to "方案确认点:开工前请需求方确认"做完后会看到什么""'},"​")]),l("p",null,[i("方案审核通过后、写代码之前,流水线可以停下来请需求方确认(1.8 起)。方案设计写 "),l("code",null,"preview.md"),i("(按操作顺序描述做完后会看到什么、需要确认的假设、不会变的地方),界面改动还在 "),l("code",null,"prototype/"),i(" 中画出静态的原型页面。对话里的 AI 把要点讲给需求方:确认后执行 "),l("code",null,"--approve"),i("(终端里 "),l("code",null,"req approve <需求>"),i(")开始写代码;要改的,更新需求说明后 "),l("code",null,"--resume"),i(",方案调整后再确认一次。需求方确认过的预览和原型,实现和功能验证都以它为准:界面与原型不一致按缺陷处理。")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"配置"),l("th",null,"默认"),l("th",null,"说明")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"designApproval.mode")]),l("td",null,[l("code",null,"ui")]),l("td",null,[l("code",null,"ui"),i(":方案判断这次是界面改动(结果文件 "),l("code",null,"ui_change"),i(")时才停;"),l("code",null,"always"),i(":每次都停;"),l("code",null,"off"),i(":不停")])]),l("tr",null,[l("td",null,[l("code",null,"designApproval.profiles")]),l("td",null,[l("code",null,'["standard"]')]),l("td",null,"哪些档位使用;快速档默认不停")]),l("tr",null,[l("td",null,[l("code",null,"designApproval.autoContinueHours")]),l("td",null,"0"),l("td",null,[i("大于 0 时,等了这么久还没确认就按方案继续(通过对话执行);0 表示一直等待。等待超过 "),l("code",null,"waitingReminderHours"),i(" 会提醒一次")])])])]),l("p",null,[i('等待确认时进度显示"等待需求方确认方案",需求总览归入"需要处理",外部通知收到 '),l("code",null,"approval"),i(" 事件。评估类需求不写代码,不经过确认点。")]),l("p",null,[l("strong",null,"原型审查页(1.13 起)。"),i(" 有 "),l("code",null,"prototype/"),i(' 的需求,插件的需求页面和"等你处理"里有"审查原型"按钮(等待确认方案时是最醒目的"审查原型并确认方案"),审查页嵌在 Paseo 的网页端和桌面端里打开,手机上在浏览器中打开;终端里是 '),l("code",null,"req review <需求>"),i("。需求方在原型上点选要改的地方(页面记下元素、文字、颜色、大小和位置)、双击直接改文字,切换状态和电脑、手机宽度,然后提交:意见整理成带位置信息的清单转给需求会话(与插件中写修改意见的效果相同),或者直接确认方案。草稿和提交记录在功能目录的 "),l("code",null,".pipeline/review/"),i(" 中,每一版原型也存在那里,原型改过后页面会标出这一版改了哪里。")]),l("p",null,[i("为了让审查页能用,方案设计按约定写原型:每个改动区域标 "),l("code",null,"data-ac"),i("(对应的 AC)和 "),l("code",null,"data-label"),i("(用需求方的话说是什么),各种状态包在 "),l("code",null,'<section data-state="状态名">'),i(" 中,按钮、标题、字段名写最终的文字。原型里的脚本不会运行。")]),l("p",null,[i("审查页由一个本机服务提供:用到时在后台启动,空闲 4 小时后自己退出,只监听 "),l("code",null,"127.0.0.1"),i(",地址中带随机令牌(插件设为只读时给只读的地址)。审查页允许被本机地址上的页面(Paseo 网页端)嵌入;要限定或放开,设 "),l("code",null,"REQ_KIT_REVIEW_FRAME_ANCESTORS"),i("(CSP "),l("code",null,"frame-ancestors"),i(" 的值)。需求方在别的电脑上用浏览器访问 Paseo 网页端时,在运行 Paseo daemon 的机器上设置环境变量 "),l("code",null,"REQ_KIT_REVIEW_HOST"),i("(例如 "),l("code",null,"0.0.0.0"),i(")、"),l("code",null,"REQ_KIT_REVIEW_PUBLIC_URL"),i("(别人访问这台机器用的地址,例如 "),l("code",null,"http://10.1.2.3:6781"),i("),需要时用 "),l("code",null,"REQ_KIT_REVIEW_PORT"),i(" 换端口(默认 6781),然后重启 Paseo daemon 让插件拿到新的环境变量(只设 "),l("code",null,"REQ_KIT_REVIEW_HOST"),i(' 时,地址用这台电脑的计算机名)。没有设置时从别的电脑打开 Paseo 网页、点"审查原型",页面会说明为什么打不开、该怎么设置(1.13)。')]),l("h2",{id:"代码评审分两个方向",tabindex:"-1"},[i("代码评审分两个方向 "),l("a",{class:"header-anchor",href:"#代码评审分两个方向","aria-label":'Permalink to "代码评审分两个方向"'},"​")]),l("p",null,"标准档第一轮代码评审由两位评审者同时进行(1.8 起),各自写意见,再由 reviewer 核实、汇总成一份结论:"),l("ul",null,[l("li",null,[l("strong",null,"规格评审"),i(":每条验收标准是否真的实现并有测试、测试的期望值是否与验收标准的例子一致、有没有做需求之外的事、与确认过的预览是否一致。")]),l("li",null,[l("strong",null,"规范评审"),i(":项目惯例和范例文件、术语表中的代码名称、测试质量、安全与数据、简单性,以及可以变成规则的问题。")])]),l("p",null,[i("两位都用配置的 reviewer agent,相当于多两次评审的用量;之后的轮次只核对修复,仍由一位评审。"),l("code",null,"reviewAxes.enabled"),i(" 设为 "),l("code",null,"false"),i(" 关闭,"),l("code",null,"reviewAxes.profiles"),i(" 选择档位(默认只有标准档)。配置了评审小组("),l("code",null,"reviewPanel"),i(")时,以评审小组为准。")]),l("h2",{id:"验收测试先提交",tabindex:"-1"},[i("验收测试先提交 "),l("a",{class:"header-anchor",href:"#验收测试先提交","aria-label":'Permalink to "验收测试先提交"'},"​")]),l("p",null,"方案判断适合测试先行时,代码实现先把从验收标准的例子写出的测试单独提交一次(这时它们是失败的),在结果文件中写明这些测试文件和那次提交。代码评审前,流水线核对它们之后有没有被改过,被改过的交给评审逐个确认有没有依据:为了让测试通过而放宽断言的,按阻塞提出。"),l("h2",{id:"术语表和范例文件",tabindex:"-1"},[i("术语表和范例文件 "),l("a",{class:"header-anchor",href:"#术语表和范例文件","aria-label":'Permalink to "术语表和范例文件"'},"​")]),l("ul",null,[l("li",null,[l("strong",null,[l("code",null,"GLOSSARY.md")]),i("(仓库根目录):业务词、含义、代码中的名字。"),l("code",null,"/req-setup"),i(" 第一次整理,访谈遇到新词时补充,方案设计为新概念补上代码中的名字;各步骤按它命名,规范评审检查是否一致。")]),l("li",null,[l("strong",null,"范例文件"),i(":"),l("code",null,"/req-setup"),i(" 在 "),l("code",null,"project-notes.md"),i(" 中列出各类代码(接口、页面、测试、迁移脚本)写得最好的文件。方案的每个任务写明参照哪个文件,实现照它的结构、命名、错误处理和测试写法来。")])]),l("h2",{id:"反复出现的问题变成规则",tabindex:"-1"},[i("反复出现的问题变成规则 "),l("a",{class:"header-anchor",href:"#反复出现的问题变成规则","aria-label":'Permalink to "反复出现的问题变成规则"'},"​")]),l("p",null,[i('完成报告把这次评审、质量门、缺陷中"一条项目规则就能挡住"的问题写进功能目录的 '),l("code",null,"lessons.tsv"),i("(类别、问题、出处、建议的规则、放在哪一层)。同一个类别在两个以上的需求里出现时,"),l("code",null,"req digest"),i(' 的需求总览会列在"反复出现的问题"中,'),l("code",null,"/req-retro"),i(" 会建议把它变成 lint 规则、类型约束、测试或项目说明里的一行,批准后落地。已经处理的类别写进 "),l("code",null,".requirement-pipeline/lessons-handled.txt"),i("(一行一个),总览不再提示。")]),l("h2",{id:"质量门-流水线自己运行的检查",tabindex:"-1"},[i("质量门:流水线自己运行的检查 "),l("a",{class:"header-anchor",href:"#质量门-流水线自己运行的检查","aria-label":'Permalink to "质量门:流水线自己运行的检查"'},"​")]),l("p",null,[i("项目配置 "),l("code",null,".requirement-pipeline.json"),i(" 的 "),l("code",null,"checks"),i(" 列出流水线"),l("strong",null,"自己运行"),i("的检查,通常由 "),l("code",null,"/req-setup"),i(" 从实际跑通的命令写入:")]),l("div",{class:"language-json vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"json"),l("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[l("code",null,[l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"{")]),i(`
2
2
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "checks"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": [")]),i(`
3
3
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"lint"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"command"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"npm run lint"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),i(`
4
4
  `),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"web 测试"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"command"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"npm test"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"cwd"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"web"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),i(`
@@ -1 +1 @@
1
- import{_ as o,o as e,c as d,a3 as r}from"./chunks/framework.B9qR_F1m.js";const g=JSON.parse('{"title":"使用者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/user.md","filePath":"guide/user.md","lastUpdated":null}'),u={name:"guide/user.md"};function q(s,t,l,i,a,n){return e(),d("div",null,[...t[0]||(t[0]=[r('<div><h1 id="使用者指南" tabindex="-1">使用者指南 <a class="header-anchor" href="#使用者指南" aria-label="Permalink to &quot;使用者指南&quot;">​</a></h1><p>req-kit 帮你把一个需求从&quot;我想要……&quot;做到&quot;可以验收&quot;:你在 Paseo 的对话里把需求讲清楚、确认一份需求说明,之后的方案设计、写代码、评审、测试和报告由一组 AI agent 在后台完成,结果发回同一个对话。</p><p>适合测试、产品经理、项目经理等不写代码、但熟悉需求和测试的同事。你不需要读代码,但可以随时查看每一步的产物,也可以亲自执行测试命令核对结果。</p><h2 id="第一次使用之前" tabindex="-1">第一次使用之前 <a class="header-anchor" href="#第一次使用之前" aria-label="Permalink to &quot;第一次使用之前&quot;">​</a></h2><p>请开发同事确认这台机器已经装好 req-kit(<code>/req-doctor</code> 全部正常),并且项目已经接入:在项目根目录的对话中运行过 <code>/req-setup</code>,生成了项目说明和验证方法。测试同事熟悉项目的话,也可以自己运行 <code>/req-setup</code>。</p><h2 id="提一个需求" tabindex="-1">提一个需求 <a class="header-anchor" href="#提一个需求" aria-label="Permalink to &quot;提一个需求&quot;">​</a></h2><ol><li><strong>准备工作区</strong>:每个需求最好有自己的 worktree 工作区,几个需求可以同时进行,互不影响。两种方式任选: <ul><li>直接在项目的对话里开始,AI 问到时选&quot;开发时自动新建工作区&quot;:照常谈需求,启动开发时流水线会自动新建工作区并在那里开发,这个对话不用动。</li><li>自己新建:在 Paseo 中点 <strong>New workspace</strong> → 选择项目 → <strong>Isolation</strong> 选 <strong>New worktree</strong> → 起点选主分支,然后在新工作区的对话里开始。</li></ul></li><li><strong>输入 <code>/req</code> 和一句话</strong>:例如 <code>/req 登录页增加短信验证码登录</code>。用 Pi 时输入 <code>/skill:req ……</code>。</li><li><strong>回答问题</strong>:AI 会先复述它的理解,然后一次问一个问题,给出选项和推荐。它会问到异常情况、权限、已有数据、测试数据和验证环境,这些往往是你最清楚的。拿不准时可以说&quot;你定&quot;,它会采用推荐项并记为假设,最后请你过目。</li><li><strong>独立审阅</strong>(标准档):确认之前,AI 会请另一个模型把需求说明独立审一遍,几分钟后把发现的问题(歧义、遗漏、没法验证的验收标准)逐个问你。这一步常常能省掉开发之后的返工。</li><li><strong>确认需求说明</strong>:AI 给出一份 10 行以内的摘要,完整的需求说明在 <code>docs/features/&lt;日期&gt;-&lt;名称&gt;/spec.md</code>。确认后它会问是否开始开发。</li><li><strong>等待</strong>:开发在后台进行,通常需要几个小时,不需要盯着。期间你会收到几句进展(方案定了、开始验证等)。</li></ol><p>小改动(改文案、样式、一个配置项)会走快速流程:只问 2–3 个问题,开发环节各做一轮。</p><p><strong>需求的类型</strong>:AI 复述时会和你确认这是哪一类,流水线按类型走不同的做法:</p><table tabindex="0"><thead><tr><th>类型</th><th>说法举例</th><th>流水线怎么做</th><th>你需要讲清楚的</th></tr></thead><tbody><tr><td>新需求</td><td>&quot;加一个……&quot;</td><td>方案、实现、评审、验证</td><td>要什么、怎么算做对</td></tr><tr><td>缺陷</td><td>&quot;……不对&quot;&quot;报错了&quot;</td><td>先复现、找到原因再修;复现不了会回来问你</td><td>复现步骤:环境、账号或数据、操作、看到的、应有的</td></tr><tr><td>重构</td><td>&quot;整理一下……&quot;&quot;升级依赖&quot;</td><td>先用测试锁住现有行为,再小步改,确认行为没变</td><td>改进目标,以及哪些行为必须保持不变</td></tr><tr><td>评估</td><td>&quot;能不能做……&quot;&quot;影响多大&quot;</td><td>只调研、写评估报告,由另一个模型审阅,不写代码</td><td>要回答的问题,结论用来做什么决定</td></tr></tbody></table><p>评估做完后,可以直接说&quot;按评估结果提一个新需求&quot;。</p><p><strong>前端和后端都要改</strong>:另一个仓库已经由开发同事登记过(<code>/req-setup</code> 时登记)的,AI 会问是否作为联合需求一起做:流水线先设计整体方案和双方的接口约定,再在每个仓库各开一个工作区同时开发,最后一起验证,报告里写明每个仓库的分支和合并顺序。</p><p><strong>验收标准带例子</strong>:AI 写验收标准时会给每条配上具体的数据(&quot;输入 13800000000,60 秒内再点发送,提示&#39;请 45 秒后重试&#39;&quot;)。请认真看这些例子:它们会直接变成测试检查的期望值,你确认的就是测试会检查的东西。</p><p><strong>开工前先看一眼&quot;做完后会看到什么&quot;</strong>(标准档的界面改动):方案审核通过后、写代码之前,流水线会停下来,AI 把 <code>preview.md</code> 的要点讲给你听:会看到什么变化、有哪些需要你确认的假设;界面改动还会有静态的原型页面(功能目录的 <code>prototype/</code> 中),可以在浏览器里打开看。说&quot;可以&quot;就开始写代码;想改的直接说,AI 会更新需求说明,方案调整后再请你看一次。这时调整的成本最低。</p><p><strong>研发和测试分开做</strong>(标准档,确定档位时 AI 会问,团队配置里定好了就不问):</p><ul><li><strong>连续</strong>(默认):研发完成后流水线接着做测试验证,一次跑完。</li><li><strong>分阶段</strong>:研发完成、写好提测说明(<code>handoff.md</code>)后停下来通知你:&quot;研发完成,可以提测&quot;。你或测试同事准备好之后说&quot;开始测试验证&quot;,AI 会讲一遍提测说明,问清在哪里测(本地,或已部署的测试环境)、发现缺陷怎么办(当场修复、退回研发修复后再提测,或只记录),然后开始;也可以预约时间。用&quot;开发时自动新建工作区&quot;开发的需求,测试同事可以在自己的对话里输入 <code>/req 开始测试验证 &lt;需求名称&gt;</code> 接手。</li><li><strong>只做研发</strong>:做到提测说明和研发报告为止,测试由人完成,验收时 AI 会按提测说明带你逐条测试。</li></ul><h2 id="过程中" tabindex="-1">过程中 <a class="header-anchor" href="#过程中" aria-label="Permalink to &quot;过程中&quot;">​</a></h2><table tabindex="0"><thead><tr><th>你想做的</th><th>在对话里说</th></tr></thead><tbody><tr><td>看进度</td><td>&quot;做到哪了&quot;(会说明当前在哪一步、agent 最近在做什么,例如正在运行测试)</td></tr><tr><td>暂停</td><td>&quot;先停一下&quot;(当前步骤做到一半的工作不保留,已完成的步骤保留)</td></tr><tr><td>继续</td><td>&quot;继续开发&quot;</td></tr><tr><td>确认方案</td><td>收到&quot;请确认方案&quot;时,看过之后说&quot;可以,按这个做&quot;,或者说要改哪里</td></tr><tr><td>改需求</td><td>&quot;我想改一下……&quot;:先暂停,谈清变化的部分,更新需求说明(版本加 1,记入 <code>changes.md</code>)后继续,开发会在已有方案和代码的基础上只处理变化的部分。开发已经完成的也可以改</td></tr><tr><td>看看项目里有哪些需求</td><td>&quot;现在有哪些需求&quot;:列出所有工作区中的需求和各自的阶段</td></tr><tr><td>研发完成后提测</td><td>&quot;开始测试验证&quot;(分阶段执行时);想晚点开始就说&quot;等测试环境部署好,明早 9 点开始测试&quot;</td></tr><tr><td>晚点再开始</td><td>确认需求后说&quot;今晚 10 点开始&quot;&quot;明天早上开始&quot;:到时会在这个对话里自动开始,说&quot;先停一下&quot;可以取消</td></tr><tr><td>接手别人的需求</td><td>&quot;这个需求之前是同事提的,现在什么情况&quot;:讲清现状、待决事项和下一步</td></tr></tbody></table><p>也可以不进对话,在终端里用 <code>req</code> 命令(需要开发同事装好并加入 PATH,见 <a href="./install">安装与升级</a>):在项目目录中 <code>req list</code> 看所有需求,<code>req status</code> 看进度(多个需求时写名称的一部分,如 <code>req status sms-login</code>),<code>req stop</code>、<code>req resume</code> 暂停和继续。</p><p>装了 req-kit 插件的话(见 <a href="./install">安装与升级</a> 第 13 节),在 Paseo 侧边栏点&quot;需求&quot;:本机所有项目的需求一页看完,&quot;需要你处理&quot;的排在最前;点开一个需求能看到每一步的进度和用时、读需求说明、方案、确认预览和完成报告,也可以直接确认方案、停止、继续或开始测试验证。网页端、桌面版和手机上都能用。</p><p>1.14 起,需求从开始谈的时候就出现在插件里(状态&quot;对齐中&quot;);需求说明确认了却还没开始开发(超过 30 分钟),或者上次启动没成功的,会出现在&quot;等你处理&quot;里,点&quot;开始开发&quot;就能开始,进展照常发回谈需求的那个对话。</p><p>1.12 起,首页最上面是&quot;等你处理&quot;:所有等你确认方案、回答问题、中断了的需求,等得最久的在前,每条写明要做什么、等了多久。方案可以直接确认,也可以写修改意见;方案审核的问题可以直接写回答,插件会转给这个需求的对话,效果和在对话里回答一样。首页的&quot;配置&quot;列出 req-kit 的全部设置:每一项是什么、现在的值、来自本机、团队还是项目的配置文件,可以按项目查看、搜索、只看改过的。</p><p><strong>在原型上提意见(1.13 起)。</strong> 界面改动的需求,在请你确认方案时会有一份界面原型。在插件首页的&quot;等你处理&quot;或需求页面最上面,点**&quot;审查原型并确认方案&quot;**按钮(终端里是 <code>req review &lt;需求&gt;</code>),原型审查页就在 Paseo 里打开(手机上会在浏览器中打开;嫌窗口小时点右上角&quot;在新窗口打开&quot;):</p><ul><li>标着 ①②③ 的是这次要改的地方,右边写着各自对应的验收标准,顺着看就不会漏。</li><li>想改哪里就<strong>点哪里</strong>,选一种改法(文字改成…、大一点、换颜色、换位置、删掉、这里加东西……),再用自己的话补一句。不用想专业词汇,你点的是哪个按钮、原来是什么颜色和大小,页面会自动记下来交给 AI。</li><li>想换文字就<strong>双击文字</strong>,直接改成你想要的字。</li><li>正常、出错、空数据这些状态,以及电脑、手机宽度,在页面上方切换。</li><li>写的意见会自动保存。看完后点&quot;提交修改意见&quot;,需求会话会据此改需求说明,改好后请你再确认;改过的原型再打开时,会用绿色框标出这一版改了哪里。没有要改的,点&quot;同意开始写代码&quot;。</li></ul><p><strong>还要多久(1.13 起)。</strong> 本机做完过 3 个以上同档位的需求后,开始开发时会告诉你这类需求通常要多久、用多少 token;问&quot;做到哪了&quot;或在插件的需求页面里,会看到&quot;预计还要约多久&quot;(不含等人确认的时间)。</p><p>每个步骤都会出现在这个对话的子 agent 列表里(名字形如&quot;[20261012-sms-login] 6-代码评审 第2轮&quot;),点开可以看到它在做什么。功能目录下的 <code>progress.md</code> 按时间记录了每一步的结果。</p><p>可能收到的通知(团队接入了企业 IM 的话,这些通知也会发到 IM):</p><ul><li><strong>需要你决定</strong>:方案审核发现只有你能回答的问题。AI 会逐个问你,然后继续。一天没有回答的话,会在对话里提醒一次。</li><li><strong>研发完成,可以提测</strong>(分阶段执行时):代码已写完并通过评审,提测说明在 <code>handoff.md</code>。一天没有开始测试验证的话,会在对话里提醒一次。</li><li><strong>等待批准</strong>:某一步在等权限批准,按提示打开对应的 agent 处理,或请开发同事处理。1.13 起插件的&quot;等你处理&quot;里也会显示,列出要批准的操作,点&quot;打开这个 agent&quot;直接去处理。</li><li><strong>token 用量提醒</strong>(团队设了 token 预算时):用到预算的一定比例时告知一次,开发照常进行;用完时做完当前步骤就停下,AI 会告诉你用了多少、问你是否继续。继续会再给一份预算。</li><li><strong>中断</strong>:限流、网络中断这类临时问题会先自动等待重试,仍然不行才中断,并预约半小时后自动继续(说&quot;先停一下&quot;可以取消)。AI 会说明原因和日志位置。环境类问题(例如测试服务没启动)你可以自己处理;涉及配置或代码的请开发同事处理。处理后说&quot;继续开发&quot;。</li></ul><h2 id="验收" tabindex="-1">验收 <a class="header-anchor" href="#验收" aria-label="Permalink to &quot;验收&quot;">​</a></h2><p>完成后你会收到结论和摘要,完整报告在功能目录的 <code>report.md</code>:</p><ul><li><strong>验收对照表</strong>:每条验收标准的结果,以及是怎么确认的(运行了什么命令、看到了什么、截图在哪里)。</li><li><strong>需要你确认的决定</strong>:开发过程中替你做的假设和取舍,以及被驳回的评审意见里会影响结果的那些。请逐条表态。</li><li><strong>遗留问题</strong>和<strong>需要你做的事</strong>。</li><li><strong>用时与用量</strong>:各步骤 agent 合计用了多长时间、多少 token、大约多少费用,便于估算后续需求的成本。</li></ul><p>然后说&quot;我要验收&quot;。AI 会按验收标准一条一条带你核对:告诉你怎么操作、应该看到什么;能用命令验证的给出命令,你可以自己执行。每条结果记入功能目录的 <code>acceptance.md</code>。</p><p><strong>代码审查(1.14 起,给开发同事和评审人)。</strong> 需求页面上点**&quot;代码审查&quot;**(终端里是 <code>req code-review &lt;需求&gt;</code>),代码审查页在 Paseo 里打开:</p><ul><li>列出这次改动的全部文件(相对需求分支的起点,需求文档排在最后、默认折叠),上面是提测说明里&quot;这次改了什么&quot;。</li><li>AI 代码评审的每条意见放在它说的那一行旁边,标着级别(阻塞 / 重要 / 建议)和修复步骤的处理结果(已修复、判为不成立、决定不修复);可以标<strong>要改</strong>或<strong>不用改</strong>,补一句话。</li><li>点任意一行代码写意见;最下面可以写总体意见。</li><li><strong>审核人</strong>默认取自仓库的 <code>CODEOWNERS</code>(按改动的文件),提交前可以改;以后建合并请求时会用它。</li><li><strong>退回修改</strong>:意见写进 <code>code-review.md</code> 的&quot;人工评审&quot;一节(HR-1 起)和 <code>changes.md</code>,流水线随即开始新的一次尝试,需求说明不变,从方案设计开始只处理这些意见,改完再经过 AI 代码评审和验证,进展发回需求的对话。<strong>评审通过</strong>:记下评审人和审核人;之后代码又有改动时,页面会提示需要重新评审。</li></ul><p><strong>在插件里自己验收(1.14 起)。</strong> 需求页面上点**&quot;验收清单(可一键试用)&quot;**(终端里是 <code>req checklist &lt;需求&gt;</code>),验收清单在 Paseo 里打开:</p><ul><li><p>每条验收标准写着前置条件、怎么操作、应该看到什么,以及流水线的验证结果;流水线没验证或没通过的排在最前面,报告里&quot;需要你确认的决定&quot;也列在后面请你表态。</p></li><li><p>右上角**&quot;把它跑起来试用&quot;**(终端里是 <code>req try &lt;需求&gt;</code>):用项目的 Paseo 服务脚本(<code>paseo.json</code>)在这个需求自己的工作区里把它启动起来,给出访问地址和提测说明里的测试账号、数据;用完点&quot;停止试用&quot;。项目没有服务脚本时,会给出提测说明里写的启动方法,也可以在需求的对话里说&quot;帮我把它跑起来&quot;。</p></li><li><p>每条点&quot;通过&quot;、&quot;不对&quot;(写下看到了什么)或&quot;先不验&quot;,进度自动保存。必须验的都核对完才能提交&quot;通过&quot;;有&quot;不对&quot;的就提交&quot;不通过&quot;。</p></li><li><p>提交后写成 <code>acceptance.md</code> 并提交。不通过时,不对的地方会转给这个需求的对话,它会和你一起确定怎么处理。</p></li><li><p><strong>全部通过</strong>:请开发同事审阅代码并合并上线。流水线只做本地提交,不会自己合并或上线。</p></li><li><p><strong>有不通过的</strong>:逐项决定怎么处理:做得不对的,补进需求说明后继续开发;发现想要的不是这样的,按改需求处理;也可以接受现状并记下理由。</p></li></ul><p>测试同事可以把验收标准直接转成测试用例:每条都写成了&quot;前置条件 / 操作 / 预期结果&quot;。</p><p><strong>记录会留下来(1.14 起)。</strong> 代码审查和验收的结论、评审人、每条意见都写在需求目录的 <code>code-review.md</code>、<code>acceptance.md</code>(退回修改的原因在 <code>changes.md</code>)里,随需求分支提交,合并后在主干上也能查。结论和数量另外记在本机的使用记录里,<code>req stats</code> 能看到人工评审退回了几次、验收通过率、合并进主干的需求和合并后发现的问题。</p><h2 id="上线后发现问题" tabindex="-1">上线后发现问题 <a class="header-anchor" href="#上线后发现问题" aria-label="Permalink to &quot;上线后发现问题&quot;">​</a></h2><p>说&quot;线上发现……不对&quot;。AI 会先问这个问题是否正在影响真实用户:是的话,请马上联系开发同事或值班人员处理线上情况(req-kit 不碰生产环境)。然后它会问清现象、复现步骤、影响范围,关联到原来的需求,生成一份缺陷说明,按快速流程修复,修复后照常验收。缺陷说明里写明是哪个需求引入的问题,<code>req stats</code> 会把它算作那个需求&quot;合并后发现的问题&quot;;也可以在终端里手动记一笔:<code>req outcome &lt;需求&gt; --issue &quot;&lt;问题&gt;&quot;</code>。</p><h2 id="注意" tabindex="-1">注意 <a class="header-anchor" href="#注意" aria-label="Permalink to &quot;注意&quot;">​</a></h2><ul><li>一个对话只谈一个需求;对话过程中不要切换工作目录。</li><li>需求属于另一个项目时,到那个项目里新开对话。</li><li>遇到&quot;未启动&quot;或其他看不懂的情况,输入 <code>/req-doctor</code> 做一次体检,或请开发同事看一下。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/guide/使用者指南.md">docs/guide/使用者指南.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/guide/使用者指南.md">在 GitHub 上编辑</a></p>',2)])])}const p=o(u,[["render",q]]);export{g as __pageData,p as default};
1
+ import{_ as o,o as e,c as d,a2 as r}from"./chunks/framework.BetZR81g.js";const g=JSON.parse('{"title":"使用者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/user.md","filePath":"guide/user.md","lastUpdated":null}'),u={name:"guide/user.md"};function q(s,t,l,i,a,n){return e(),d("div",null,[...t[0]||(t[0]=[r('<div><h1 id="使用者指南" tabindex="-1">使用者指南 <a class="header-anchor" href="#使用者指南" aria-label="Permalink to &quot;使用者指南&quot;">​</a></h1><p>req-kit 帮你把一个需求从&quot;我想要……&quot;做到&quot;可以验收&quot;:你在 Paseo 的对话里把需求讲清楚、确认一份需求说明,之后的方案设计、写代码、评审、测试和报告由一组 AI agent 在后台完成,结果发回同一个对话。</p><p>适合测试、产品经理、项目经理等不写代码、但熟悉需求和测试的同事。你不需要读代码,但可以随时查看每一步的产物,也可以亲自执行测试命令核对结果。</p><h2 id="第一次使用之前" tabindex="-1">第一次使用之前 <a class="header-anchor" href="#第一次使用之前" aria-label="Permalink to &quot;第一次使用之前&quot;">​</a></h2><p>请开发同事确认这台机器已经装好 req-kit(<code>/req-doctor</code> 全部正常),并且项目已经接入:在项目根目录的对话中运行过 <code>/req-setup</code>,生成了项目说明和验证方法。测试同事熟悉项目的话,也可以自己运行 <code>/req-setup</code>。</p><h2 id="提一个需求" tabindex="-1">提一个需求 <a class="header-anchor" href="#提一个需求" aria-label="Permalink to &quot;提一个需求&quot;">​</a></h2><ol><li><strong>准备工作区</strong>:每个需求最好有自己的 worktree 工作区,几个需求可以同时进行,互不影响。两种方式任选: <ul><li>直接在项目的对话里开始,AI 问到时选&quot;开发时自动新建工作区&quot;:照常谈需求,启动开发时流水线会自动新建工作区并在那里开发,这个对话不用动。</li><li>自己新建:在 Paseo 中点 <strong>New workspace</strong> → 选择项目 → <strong>Isolation</strong> 选 <strong>New worktree</strong> → 起点选主分支,然后在新工作区的对话里开始。</li></ul></li><li><strong>输入 <code>/req</code> 和一句话</strong>:例如 <code>/req 登录页增加短信验证码登录</code>。用 Pi 时输入 <code>/skill:req ……</code>。</li><li><strong>回答问题</strong>:AI 会先复述它的理解,然后一次问一个问题,给出选项和推荐。它会问到异常情况、权限、已有数据、测试数据和验证环境,这些往往是你最清楚的。拿不准时可以说&quot;你定&quot;,它会采用推荐项并记为假设,最后请你过目。</li><li><strong>独立审阅</strong>(标准档):确认之前,AI 会请另一个模型把需求说明独立审一遍,几分钟后把发现的问题(歧义、遗漏、没法验证的验收标准)逐个问你。这一步常常能省掉开发之后的返工。</li><li><strong>确认需求说明</strong>:AI 给出一份 10 行以内的摘要,完整的需求说明在 <code>docs/features/&lt;日期&gt;-&lt;名称&gt;/spec.md</code>。确认后它会问是否开始开发。</li><li><strong>等待</strong>:开发在后台进行,通常需要几个小时,不需要盯着。期间你会收到几句进展(方案定了、开始验证等)。</li></ol><p>小改动(改文案、样式、一个配置项)会走快速流程:只问 2–3 个问题,开发环节各做一轮。</p><p><strong>需求的类型</strong>:AI 复述时会和你确认这是哪一类,流水线按类型走不同的做法:</p><table tabindex="0"><thead><tr><th>类型</th><th>说法举例</th><th>流水线怎么做</th><th>你需要讲清楚的</th></tr></thead><tbody><tr><td>新需求</td><td>&quot;加一个……&quot;</td><td>方案、实现、评审、验证</td><td>要什么、怎么算做对</td></tr><tr><td>缺陷</td><td>&quot;……不对&quot;&quot;报错了&quot;</td><td>先复现、找到原因再修;复现不了会回来问你</td><td>复现步骤:环境、账号或数据、操作、看到的、应有的</td></tr><tr><td>重构</td><td>&quot;整理一下……&quot;&quot;升级依赖&quot;</td><td>先用测试锁住现有行为,再小步改,确认行为没变</td><td>改进目标,以及哪些行为必须保持不变</td></tr><tr><td>评估</td><td>&quot;能不能做……&quot;&quot;影响多大&quot;</td><td>只调研、写评估报告,由另一个模型审阅,不写代码</td><td>要回答的问题,结论用来做什么决定</td></tr></tbody></table><p>评估做完后,可以直接说&quot;按评估结果提一个新需求&quot;。</p><p><strong>前端和后端都要改</strong>:另一个仓库已经由开发同事登记过(<code>/req-setup</code> 时登记)的,AI 会问是否作为联合需求一起做:流水线先设计整体方案和双方的接口约定,再在每个仓库各开一个工作区同时开发,最后一起验证,报告里写明每个仓库的分支和合并顺序。</p><p><strong>验收标准带例子</strong>:AI 写验收标准时会给每条配上具体的数据(&quot;输入 13800000000,60 秒内再点发送,提示&#39;请 45 秒后重试&#39;&quot;)。请认真看这些例子:它们会直接变成测试检查的期望值,你确认的就是测试会检查的东西。</p><p><strong>开工前先看一眼&quot;做完后会看到什么&quot;</strong>(标准档的界面改动):方案审核通过后、写代码之前,流水线会停下来,AI 把 <code>preview.md</code> 的要点讲给你听:会看到什么变化、有哪些需要你确认的假设;界面改动还会有静态的原型页面(功能目录的 <code>prototype/</code> 中),可以在浏览器里打开看。说&quot;可以&quot;就开始写代码;想改的直接说,AI 会更新需求说明,方案调整后再请你看一次。这时调整的成本最低。</p><p><strong>研发和测试分开做</strong>(标准档,确定档位时 AI 会问,团队配置里定好了就不问):</p><ul><li><strong>连续</strong>(默认):研发完成后流水线接着做测试验证,一次跑完。</li><li><strong>分阶段</strong>:研发完成、写好提测说明(<code>handoff.md</code>)后停下来通知你:&quot;研发完成,可以提测&quot;。你或测试同事准备好之后说&quot;开始测试验证&quot;,AI 会讲一遍提测说明,问清在哪里测(本地,或已部署的测试环境)、发现缺陷怎么办(当场修复、退回研发修复后再提测,或只记录),然后开始;也可以预约时间。用&quot;开发时自动新建工作区&quot;开发的需求,测试同事可以在自己的对话里输入 <code>/req 开始测试验证 &lt;需求名称&gt;</code> 接手。</li><li><strong>只做研发</strong>:做到提测说明和研发报告为止,测试由人完成,验收时 AI 会按提测说明带你逐条测试。</li></ul><h2 id="过程中" tabindex="-1">过程中 <a class="header-anchor" href="#过程中" aria-label="Permalink to &quot;过程中&quot;">​</a></h2><table tabindex="0"><thead><tr><th>你想做的</th><th>在对话里说</th></tr></thead><tbody><tr><td>看进度</td><td>&quot;做到哪了&quot;(会说明当前在哪一步、agent 最近在做什么,例如正在运行测试)</td></tr><tr><td>暂停</td><td>&quot;先停一下&quot;(当前步骤做到一半的工作不保留,已完成的步骤保留)</td></tr><tr><td>继续</td><td>&quot;继续开发&quot;</td></tr><tr><td>确认方案</td><td>收到&quot;请确认方案&quot;时,看过之后说&quot;可以,按这个做&quot;,或者说要改哪里</td></tr><tr><td>改需求</td><td>&quot;我想改一下……&quot;:先暂停,谈清变化的部分,更新需求说明(版本加 1,记入 <code>changes.md</code>)后继续,开发会在已有方案和代码的基础上只处理变化的部分。开发已经完成的也可以改</td></tr><tr><td>看看项目里有哪些需求</td><td>&quot;现在有哪些需求&quot;:列出所有工作区中的需求和各自的阶段</td></tr><tr><td>研发完成后提测</td><td>&quot;开始测试验证&quot;(分阶段执行时);想晚点开始就说&quot;等测试环境部署好,明早 9 点开始测试&quot;</td></tr><tr><td>晚点再开始</td><td>确认需求后说&quot;今晚 10 点开始&quot;&quot;明天早上开始&quot;:到时会在这个对话里自动开始,说&quot;先停一下&quot;可以取消</td></tr><tr><td>接手别人的需求</td><td>&quot;这个需求之前是同事提的,现在什么情况&quot;:讲清现状、待决事项和下一步</td></tr></tbody></table><p>也可以不进对话,在终端里用 <code>req</code> 命令(需要开发同事装好并加入 PATH,见 <a href="./install">安装与升级</a>):在项目目录中 <code>req list</code> 看所有需求,<code>req status</code> 看进度(多个需求时写名称的一部分,如 <code>req status sms-login</code>),<code>req stop</code>、<code>req resume</code> 暂停和继续。</p><p>装了 req-kit 插件的话(见 <a href="./install">安装与升级</a> 第 13 节),在 Paseo 侧边栏点&quot;需求&quot;:本机所有项目的需求一页看完,&quot;需要你处理&quot;的排在最前;点开一个需求能看到每一步的进度和用时、读需求说明、方案、确认预览和完成报告,也可以直接确认方案、停止、继续或开始测试验证。网页端、桌面版和手机上都能用。</p><p>1.14 起,需求从开始谈的时候就出现在插件里(状态&quot;对齐中&quot;);需求说明确认了却还没开始开发(超过 30 分钟),或者上次启动没成功的,会出现在&quot;等你处理&quot;里,点&quot;开始开发&quot;就能开始,进展照常发回谈需求的那个对话。</p><p>1.12 起,首页最上面是&quot;等你处理&quot;:所有等你确认方案、回答问题、中断了的需求,等得最久的在前,每条写明要做什么、等了多久。方案可以直接确认,也可以写修改意见;方案审核的问题可以直接写回答,插件会转给这个需求的对话,效果和在对话里回答一样。首页的&quot;配置&quot;列出 req-kit 的全部设置:每一项是什么、现在的值、来自本机、团队还是项目的配置文件,可以按项目查看、搜索、只看改过的。</p><p><strong>在原型上提意见(1.13 起)。</strong> 界面改动的需求,在请你确认方案时会有一份界面原型。在插件首页的&quot;等你处理&quot;或需求页面最上面,点**&quot;审查原型并确认方案&quot;**按钮(终端里是 <code>req review &lt;需求&gt;</code>),原型审查页就在 Paseo 里打开(手机上会在浏览器中打开;嫌窗口小时点右上角&quot;在新窗口打开&quot;):</p><ul><li>标着 ①②③ 的是这次要改的地方,右边写着各自对应的验收标准,顺着看就不会漏。</li><li>想改哪里就<strong>点哪里</strong>,选一种改法(文字改成…、大一点、换颜色、换位置、删掉、这里加东西……),再用自己的话补一句。不用想专业词汇,你点的是哪个按钮、原来是什么颜色和大小,页面会自动记下来交给 AI。</li><li>想换文字就<strong>双击文字</strong>,直接改成你想要的字。</li><li>正常、出错、空数据这些状态,以及电脑、手机宽度,在页面上方切换。</li><li>写的意见会自动保存。看完后点&quot;提交修改意见&quot;,需求会话会据此改需求说明,改好后请你再确认;改过的原型再打开时,会用绿色框标出这一版改了哪里。没有要改的,点&quot;同意开始写代码&quot;。</li></ul><p><strong>还要多久(1.13 起)。</strong> 本机做完过 3 个以上同档位的需求后,开始开发时会告诉你这类需求通常要多久、用多少 token;问&quot;做到哪了&quot;或在插件的需求页面里,会看到&quot;预计还要约多久&quot;(不含等人确认的时间)。</p><p>每个步骤都会出现在这个对话的子 agent 列表里(名字形如&quot;[20261012-sms-login] 6-代码评审 第2轮&quot;),点开可以看到它在做什么。功能目录下的 <code>progress.md</code> 按时间记录了每一步的结果。</p><p>可能收到的通知(团队接入了企业 IM 的话,这些通知也会发到 IM):</p><ul><li><strong>需要你决定</strong>:方案审核发现只有你能回答的问题。AI 会逐个问你,然后继续。一天没有回答的话,会在对话里提醒一次。</li><li><strong>研发完成,可以提测</strong>(分阶段执行时):代码已写完并通过评审,提测说明在 <code>handoff.md</code>。一天没有开始测试验证的话,会在对话里提醒一次。</li><li><strong>等待批准</strong>:某一步在等权限批准,按提示打开对应的 agent 处理,或请开发同事处理。1.13 起插件的&quot;等你处理&quot;里也会显示,列出要批准的操作,点&quot;打开这个 agent&quot;直接去处理。</li><li><strong>token 用量提醒</strong>(团队设了 token 预算时):用到预算的一定比例时告知一次,开发照常进行;用完时做完当前步骤就停下,AI 会告诉你用了多少、问你是否继续。继续会再给一份预算。</li><li><strong>中断</strong>:限流、网络中断这类临时问题会先自动等待重试,仍然不行才中断,并预约半小时后自动继续(说&quot;先停一下&quot;可以取消)。AI 会说明原因和日志位置。环境类问题(例如测试服务没启动)你可以自己处理;涉及配置或代码的请开发同事处理。处理后说&quot;继续开发&quot;。</li></ul><h2 id="验收" tabindex="-1">验收 <a class="header-anchor" href="#验收" aria-label="Permalink to &quot;验收&quot;">​</a></h2><p>完成后你会收到结论和摘要,完整报告在功能目录的 <code>report.md</code>:</p><ul><li><strong>验收对照表</strong>:每条验收标准的结果,以及是怎么确认的(运行了什么命令、看到了什么、截图在哪里)。</li><li><strong>需要你确认的决定</strong>:开发过程中替你做的假设和取舍,以及被驳回的评审意见里会影响结果的那些。请逐条表态。</li><li><strong>遗留问题</strong>和<strong>需要你做的事</strong>。</li><li><strong>用时与用量</strong>:各步骤 agent 合计用了多长时间、多少 token、大约多少费用,便于估算后续需求的成本。</li></ul><p>然后说&quot;我要验收&quot;。AI 会按验收标准一条一条带你核对:告诉你怎么操作、应该看到什么;能用命令验证的给出命令,你可以自己执行。每条结果记入功能目录的 <code>acceptance.md</code>。</p><p><strong>代码审查(1.14 起,给开发同事和评审人)。</strong> 需求页面上点**&quot;代码审查&quot;**(终端里是 <code>req code-review &lt;需求&gt;</code>),代码审查页在 Paseo 里打开:</p><ul><li>列出这次改动的全部文件(相对需求分支的起点,需求文档排在最后、默认折叠),上面是提测说明里&quot;这次改了什么&quot;。</li><li>AI 代码评审的每条意见放在它说的那一行旁边,标着级别(阻塞 / 重要 / 建议)和修复步骤的处理结果(已修复、判为不成立、决定不修复);可以标<strong>要改</strong>或<strong>不用改</strong>,补一句话。</li><li>点任意一行代码写意见;最下面可以写总体意见。</li><li><strong>审核人</strong>默认取自仓库的 <code>CODEOWNERS</code>(按改动的文件),提交前可以改;以后建合并请求时会用它。</li><li><strong>退回修改</strong>:意见写进 <code>code-review.md</code> 的&quot;人工评审&quot;一节(HR-1 起)和 <code>changes.md</code>,流水线随即开始新的一次尝试,需求说明不变,从方案设计开始只处理这些意见,改完再经过 AI 代码评审和验证,进展发回需求的对话。<strong>评审通过</strong>:记下评审人和审核人;之后代码又有改动时,页面会提示需要重新评审。</li></ul><p><strong>在插件里自己验收(1.14 起)。</strong> 需求页面上点**&quot;验收清单(可一键试用)&quot;**(终端里是 <code>req checklist &lt;需求&gt;</code>),验收清单在 Paseo 里打开:</p><ul><li><p>每条验收标准写着前置条件、怎么操作、应该看到什么,以及流水线的验证结果;流水线没验证或没通过的排在最前面,报告里&quot;需要你确认的决定&quot;也列在后面请你表态。</p></li><li><p>右上角**&quot;把它跑起来试用&quot;**(终端里是 <code>req try &lt;需求&gt;</code>):用项目的 Paseo 服务脚本(<code>paseo.json</code>)在这个需求自己的工作区里把它启动起来,给出访问地址和提测说明里的测试账号、数据;用完点&quot;停止试用&quot;。项目没有服务脚本时,会给出提测说明里写的启动方法,也可以在需求的对话里说&quot;帮我把它跑起来&quot;。</p></li><li><p>每条点&quot;通过&quot;、&quot;不对&quot;(写下看到了什么)或&quot;先不验&quot;,进度自动保存。必须验的都核对完才能提交&quot;通过&quot;;有&quot;不对&quot;的就提交&quot;不通过&quot;。</p></li><li><p>提交后写成 <code>acceptance.md</code> 并提交。不通过时,不对的地方会转给这个需求的对话,它会和你一起确定怎么处理。</p></li><li><p><strong>全部通过</strong>:请开发同事审阅代码并合并上线。流水线只做本地提交,不会自己合并或上线。</p></li><li><p><strong>有不通过的</strong>:逐项决定怎么处理:做得不对的,补进需求说明后继续开发;发现想要的不是这样的,按改需求处理;也可以接受现状并记下理由。</p></li></ul><p>测试同事可以把验收标准直接转成测试用例:每条都写成了&quot;前置条件 / 操作 / 预期结果&quot;。</p><p><strong>记录会留下来(1.14 起)。</strong> 代码审查和验收的结论、评审人、每条意见都写在需求目录的 <code>code-review.md</code>、<code>acceptance.md</code>(退回修改的原因在 <code>changes.md</code>)里,随需求分支提交,合并后在主干上也能查。结论和数量另外记在本机的使用记录里,<code>req stats</code> 能看到人工评审退回了几次、验收通过率、合并进主干的需求和合并后发现的问题。</p><h2 id="上线后发现问题" tabindex="-1">上线后发现问题 <a class="header-anchor" href="#上线后发现问题" aria-label="Permalink to &quot;上线后发现问题&quot;">​</a></h2><p>说&quot;线上发现……不对&quot;。AI 会先问这个问题是否正在影响真实用户:是的话,请马上联系开发同事或值班人员处理线上情况(req-kit 不碰生产环境)。然后它会问清现象、复现步骤、影响范围,关联到原来的需求,生成一份缺陷说明,按快速流程修复,修复后照常验收。缺陷说明里写明是哪个需求引入的问题,<code>req stats</code> 会把它算作那个需求&quot;合并后发现的问题&quot;;也可以在终端里手动记一笔:<code>req outcome &lt;需求&gt; --issue &quot;&lt;问题&gt;&quot;</code>。</p><h2 id="注意" tabindex="-1">注意 <a class="header-anchor" href="#注意" aria-label="Permalink to &quot;注意&quot;">​</a></h2><ul><li>一个对话只谈一个需求;对话过程中不要切换工作目录。</li><li>需求属于另一个项目时,到那个项目里新开对话。</li><li>遇到&quot;未启动&quot;或其他看不懂的情况,输入 <code>/req-doctor</code> 做一次体检,或请开发同事看一下。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/guide/使用者指南.md">docs/guide/使用者指南.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/guide/使用者指南.md">在 GitHub 上编辑</a></p>',2)])])}const p=o(u,[["render",q]]);export{g as __pageData,p as default};
@@ -1 +1 @@
1
- import{_ as o,o as e,c as d,a3 as r}from"./chunks/framework.B9qR_F1m.js";const g=JSON.parse('{"title":"使用者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/user.md","filePath":"guide/user.md","lastUpdated":null}'),u={name:"guide/user.md"};function q(s,t,l,i,a,n){return e(),d("div",null,[...t[0]||(t[0]=[r("",2)])])}const p=o(u,[["render",q]]);export{g as __pageData,p as default};
1
+ import{_ as o,o as e,c as d,a2 as r}from"./chunks/framework.BetZR81g.js";const g=JSON.parse('{"title":"使用者指南","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"guide/user.md","filePath":"guide/user.md","lastUpdated":null}'),u={name:"guide/user.md"};function q(s,t,l,i,a,n){return e(),d("div",null,[...t[0]||(t[0]=[r("",2)])])}const p=o(u,[["render",q]]);export{g as __pageData,p as default};
@@ -0,0 +1 @@
1
+ import{_ as e,o as t,c as a}from"./chunks/framework.BetZR81g.js";const m=JSON.parse('{"title":"req-kit","titleTemplate":"从一句需求,到可验收的功能","description":"","frontmatter":{"layout":"home","title":"req-kit","titleTemplate":"从一句需求,到可验收的功能"},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1792916468000}'),r={name:"index.md"};function i(n,o,s,d,c,l){return t(),a("div")}const _=e(r,[["render",i]]);export{m as __pageData,_ as default};
@@ -0,0 +1 @@
1
+ import{_ as e,o as t,c as a}from"./chunks/framework.BetZR81g.js";const m=JSON.parse('{"title":"req-kit","titleTemplate":"从一句需求,到可验收的功能","description":"","frontmatter":{"layout":"home","title":"req-kit","titleTemplate":"从一句需求,到可验收的功能"},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1792916468000}'),r={name:"index.md"};function i(n,o,s,d,c,l){return t(),a("div")}const _=e(r,[["render",i]]);export{m as __pageData,_ as default};
@@ -1 +1 @@
1
- import{_ as a,o as t,c as r,a3 as n}from"./chunks/framework.B9qR_F1m.js";const g=JSON.parse('{"title":"0001 步骤 agent 挂在发起的对话下","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0001-step-agents-under-origin-chat.md","filePath":"reference/adr/0001-step-agents-under-origin-chat.md","lastUpdated":null}'),i={name:"reference/adr/0001-step-agents-under-origin-chat.md"};function o(s,e,d,c,h,l){return t(),r("div",null,[...e[0]||(e[0]=[n('<div><h1 id="_0001-步骤-agent-挂在发起的对话下" tabindex="-1">0001 步骤 agent 挂在发起的对话下 <a class="header-anchor" href="#_0001-步骤-agent-挂在发起的对话下" aria-label="Permalink to &quot;0001 步骤 agent 挂在发起的对话下&quot;">​</a></h1><ul><li>状态:已采纳(<a href="./0018-own-worktree-option">0018</a> 增加了一种可选方式:步骤放在为需求新建的工作区中,仍挂在对话下,对话目录不变)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to &quot;背景&quot;">​</a></h2><p>Paseo 在创建子 agent 时,如果传了 parent,会使用 parent 的工作目录而不是传入的 cwd。早期版本在两者不一致时改为创建独立 agent,结果步骤的产物写到了别处。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to &quot;决定&quot;">​</a></h2><p>步骤 agent 一律作为子 agent 挂在发起的对话下;仓库目录就是这个对话的工作目录。启动前核对两者,不一致时拒绝启动;创建后再核对 agent 的工作目录,不对就归档并报错。</p><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to &quot;影响&quot;">​</a></h2><p>使用者在对话的子 agent 列表里就能看到每一步;不会出现产物写错目录的情况。代价是必须在需求所在项目的对话中发起。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0001-step-agents-under-origin-chat.md">docs/adr/0001-step-agents-under-origin-chat.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0001-step-agents-under-origin-chat.md">在 GitHub 上编辑</a></p>',2)])])}const u=a(i,[["render",o]]);export{g as __pageData,u as default};
1
+ import{_ as a,o as t,c as r,a2 as n}from"./chunks/framework.BetZR81g.js";const g=JSON.parse('{"title":"0001 步骤 agent 挂在发起的对话下","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0001-step-agents-under-origin-chat.md","filePath":"reference/adr/0001-step-agents-under-origin-chat.md","lastUpdated":null}'),i={name:"reference/adr/0001-step-agents-under-origin-chat.md"};function o(s,e,d,c,h,l){return t(),r("div",null,[...e[0]||(e[0]=[n('<div><h1 id="_0001-步骤-agent-挂在发起的对话下" tabindex="-1">0001 步骤 agent 挂在发起的对话下 <a class="header-anchor" href="#_0001-步骤-agent-挂在发起的对话下" aria-label="Permalink to &quot;0001 步骤 agent 挂在发起的对话下&quot;">​</a></h1><ul><li>状态:已采纳(<a href="./0018-own-worktree-option">0018</a> 增加了一种可选方式:步骤放在为需求新建的工作区中,仍挂在对话下,对话目录不变)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to &quot;背景&quot;">​</a></h2><p>Paseo 在创建子 agent 时,如果传了 parent,会使用 parent 的工作目录而不是传入的 cwd。早期版本在两者不一致时改为创建独立 agent,结果步骤的产物写到了别处。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to &quot;决定&quot;">​</a></h2><p>步骤 agent 一律作为子 agent 挂在发起的对话下;仓库目录就是这个对话的工作目录。启动前核对两者,不一致时拒绝启动;创建后再核对 agent 的工作目录,不对就归档并报错。</p><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to &quot;影响&quot;">​</a></h2><p>使用者在对话的子 agent 列表里就能看到每一步;不会出现产物写错目录的情况。代价是必须在需求所在项目的对话中发起。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0001-step-agents-under-origin-chat.md">docs/adr/0001-step-agents-under-origin-chat.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0001-step-agents-under-origin-chat.md">在 GitHub 上编辑</a></p>',2)])])}const u=a(i,[["render",o]]);export{g as __pageData,u as default};
@@ -1 +1 @@
1
- import{_ as a,o as t,c as r,a3 as n}from"./chunks/framework.B9qR_F1m.js";const g=JSON.parse('{"title":"0001 步骤 agent 挂在发起的对话下","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0001-step-agents-under-origin-chat.md","filePath":"reference/adr/0001-step-agents-under-origin-chat.md","lastUpdated":null}'),i={name:"reference/adr/0001-step-agents-under-origin-chat.md"};function o(s,e,d,c,h,l){return t(),r("div",null,[...e[0]||(e[0]=[n("",2)])])}const u=a(i,[["render",o]]);export{g as __pageData,u as default};
1
+ import{_ as a,o as t,c as r,a2 as n}from"./chunks/framework.BetZR81g.js";const g=JSON.parse('{"title":"0001 步骤 agent 挂在发起的对话下","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0001-step-agents-under-origin-chat.md","filePath":"reference/adr/0001-step-agents-under-origin-chat.md","lastUpdated":null}'),i={name:"reference/adr/0001-step-agents-under-origin-chat.md"};function o(s,e,d,c,h,l){return t(),r("div",null,[...e[0]||(e[0]=[n("",2)])])}const u=a(i,[["render",o]]);export{g as __pageData,u as default};
@@ -1 +1 @@
1
- import{_ as e,o as t,c as r,a3 as i}from"./chunks/framework.B9qR_F1m.js";const _=JSON.parse('{"title":"0002 对话过程中不切换工作目录","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0002-no-directory-switch-in-chat.md","filePath":"reference/adr/0002-no-directory-switch-in-chat.md","lastUpdated":null}'),o={name:"reference/adr/0002-no-directory-switch-in-chat.md"};function c(n,a,d,s,h,l){return t(),r("div",null,[...a[0]||(a[0]=[i('<div><h1 id="_0002-对话过程中不切换工作目录" tabindex="-1">0002 对话过程中不切换工作目录 <a class="header-anchor" href="#_0002-对话过程中不切换工作目录" aria-label="Permalink to &quot;0002 对话过程中不切换工作目录&quot;">​</a></h1><ul><li>状态:已采纳(<a href="./0018-own-worktree-option">0018</a> 增加了一种可选方式:步骤放在为需求新建的工作区中,仍挂在对话下,对话目录不变)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to &quot;背景&quot;">​</a></h2><p>一个对话对应一个需求的工作现场。中途切换目录会让功能目录、分支和流水线的仓库目录对不上。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to &quot;决定&quot;">​</a></h2><p>skill 明确要求不 cd 到别的目录执行命令,功能目录必须建在当前工作目录之内;需求属于其他项目时,到那个项目新开对话。</p><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to &quot;影响&quot;">​</a></h2><p>规则简单、可检查。跨项目的需求需要分别发起。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0002-no-directory-switch-in-chat.md">docs/adr/0002-no-directory-switch-in-chat.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0002-no-directory-switch-in-chat.md">在 GitHub 上编辑</a></p>',2)])])}const f=e(o,[["render",c]]);export{_ as __pageData,f as default};
1
+ import{_ as e,o as t,c as r,a2 as i}from"./chunks/framework.BetZR81g.js";const _=JSON.parse('{"title":"0002 对话过程中不切换工作目录","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0002-no-directory-switch-in-chat.md","filePath":"reference/adr/0002-no-directory-switch-in-chat.md","lastUpdated":null}'),o={name:"reference/adr/0002-no-directory-switch-in-chat.md"};function c(n,a,d,s,h,l){return t(),r("div",null,[...a[0]||(a[0]=[i('<div><h1 id="_0002-对话过程中不切换工作目录" tabindex="-1">0002 对话过程中不切换工作目录 <a class="header-anchor" href="#_0002-对话过程中不切换工作目录" aria-label="Permalink to &quot;0002 对话过程中不切换工作目录&quot;">​</a></h1><ul><li>状态:已采纳(<a href="./0018-own-worktree-option">0018</a> 增加了一种可选方式:步骤放在为需求新建的工作区中,仍挂在对话下,对话目录不变)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to &quot;背景&quot;">​</a></h2><p>一个对话对应一个需求的工作现场。中途切换目录会让功能目录、分支和流水线的仓库目录对不上。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to &quot;决定&quot;">​</a></h2><p>skill 明确要求不 cd 到别的目录执行命令,功能目录必须建在当前工作目录之内;需求属于其他项目时,到那个项目新开对话。</p><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to &quot;影响&quot;">​</a></h2><p>规则简单、可检查。跨项目的需求需要分别发起。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0002-no-directory-switch-in-chat.md">docs/adr/0002-no-directory-switch-in-chat.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0002-no-directory-switch-in-chat.md">在 GitHub 上编辑</a></p>',2)])])}const f=e(o,[["render",c]]);export{_ as __pageData,f as default};
@@ -1 +1 @@
1
- import{_ as e,o as t,c as r,a3 as i}from"./chunks/framework.B9qR_F1m.js";const _=JSON.parse('{"title":"0002 对话过程中不切换工作目录","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0002-no-directory-switch-in-chat.md","filePath":"reference/adr/0002-no-directory-switch-in-chat.md","lastUpdated":null}'),o={name:"reference/adr/0002-no-directory-switch-in-chat.md"};function c(n,a,d,s,h,l){return t(),r("div",null,[...a[0]||(a[0]=[i("",2)])])}const f=e(o,[["render",c]]);export{_ as __pageData,f as default};
1
+ import{_ as e,o as t,c as r,a2 as i}from"./chunks/framework.BetZR81g.js";const _=JSON.parse('{"title":"0002 对话过程中不切换工作目录","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0002-no-directory-switch-in-chat.md","filePath":"reference/adr/0002-no-directory-switch-in-chat.md","lastUpdated":null}'),o={name:"reference/adr/0002-no-directory-switch-in-chat.md"};function c(n,a,d,s,h,l){return t(),r("div",null,[...a[0]||(a[0]=[i("",2)])])}const f=e(o,[["render",c]]);export{_ as __pageData,f as default};
@@ -1 +1 @@
1
- import{_ as a,o as t,c as r,a3 as i}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0003-script-engine-not-hub.md","filePath":"reference/adr/0003-script-engine-not-hub.md","lastUpdated":null}'),n={name:"reference/adr/0003-script-engine-not-hub.md"};function o(s,e,d,c,h,l){return t(),r("div",null,[...e[0]||(e[0]=[i('<div><h1 id="_0003-第-3–11-步由脚本引擎驱动-不用-hub-多步骤工作流" tabindex="-1">0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流 <a class="header-anchor" href="#_0003-第-3–11-步由脚本引擎驱动-不用-hub-多步骤工作流" aria-label="Permalink to &quot;0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流&quot;">​</a></h1><ul><li>状态:已采纳</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to &quot;背景&quot;">​</a></h2><p>Paseo Hub 的多步骤格式在文档中属于旧格式,不支持循环(审核 ⇄ 修订)、断点续跑,也不能把进展发回发起的对话。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to &quot;决定&quot;">​</a></h2><p>用 Node/TypeScript 编写确定性的引擎,通过 SDK 创建步骤 agent、等待结果、发通知。Hub 版本移到 legacy/,不再维护。</p><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to &quot;影响&quot;">​</a></h2><p>流程顺序、轮数、续跑由程序保证,可测试。需要在本机安装 Node.js 和依赖。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0003-script-engine-not-hub.md">docs/adr/0003-script-engine-not-hub.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0003-script-engine-not-hub.md">在 GitHub 上编辑</a></p>',2)])])}const b=a(n,[["render",o]]);export{p as __pageData,b as default};
1
+ import{_ as a,o as t,c as r,a2 as i}from"./chunks/framework.BetZR81g.js";const p=JSON.parse('{"title":"0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0003-script-engine-not-hub.md","filePath":"reference/adr/0003-script-engine-not-hub.md","lastUpdated":null}'),n={name:"reference/adr/0003-script-engine-not-hub.md"};function o(s,e,d,c,h,l){return t(),r("div",null,[...e[0]||(e[0]=[i('<div><h1 id="_0003-第-3–11-步由脚本引擎驱动-不用-hub-多步骤工作流" tabindex="-1">0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流 <a class="header-anchor" href="#_0003-第-3–11-步由脚本引擎驱动-不用-hub-多步骤工作流" aria-label="Permalink to &quot;0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流&quot;">​</a></h1><ul><li>状态:已采纳</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to &quot;背景&quot;">​</a></h2><p>Paseo Hub 的多步骤格式在文档中属于旧格式,不支持循环(审核 ⇄ 修订)、断点续跑,也不能把进展发回发起的对话。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to &quot;决定&quot;">​</a></h2><p>用 Node/TypeScript 编写确定性的引擎,通过 SDK 创建步骤 agent、等待结果、发通知。Hub 版本移到 legacy/,不再维护。</p><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to &quot;影响&quot;">​</a></h2><p>流程顺序、轮数、续跑由程序保证,可测试。需要在本机安装 Node.js 和依赖。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0003-script-engine-not-hub.md">docs/adr/0003-script-engine-not-hub.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0003-script-engine-not-hub.md">在 GitHub 上编辑</a></p>',2)])])}const b=a(n,[["render",o]]);export{p as __pageData,b as default};
@@ -1 +1 @@
1
- import{_ as a,o as t,c as r,a3 as i}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0003-script-engine-not-hub.md","filePath":"reference/adr/0003-script-engine-not-hub.md","lastUpdated":null}'),n={name:"reference/adr/0003-script-engine-not-hub.md"};function o(s,e,d,c,h,l){return t(),r("div",null,[...e[0]||(e[0]=[i("",2)])])}const b=a(n,[["render",o]]);export{p as __pageData,b as default};
1
+ import{_ as a,o as t,c as r,a2 as i}from"./chunks/framework.BetZR81g.js";const p=JSON.parse('{"title":"0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0003-script-engine-not-hub.md","filePath":"reference/adr/0003-script-engine-not-hub.md","lastUpdated":null}'),n={name:"reference/adr/0003-script-engine-not-hub.md"};function o(s,e,d,c,h,l){return t(),r("div",null,[...e[0]||(e[0]=[i("",2)])])}const b=a(n,[["render",o]]);export{p as __pageData,b as default};
@@ -1 +1 @@
1
- import{_ as a,o as t,c as r,a3 as s}from"./chunks/framework.B9qR_F1m.js";const f=JSON.parse('{"title":"0004 步骤结论只看结果文件","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0004-result-files.md","filePath":"reference/adr/0004-result-files.md","lastUpdated":null}'),i={name:"reference/adr/0004-result-files.md"};function l(o,e,d,n,c,h){return t(),r("div",null,[...e[0]||(e[0]=[s('<div><h1 id="_0004-步骤结论只看结果文件" tabindex="-1">0004 步骤结论只看结果文件 <a class="header-anchor" href="#_0004-步骤结论只看结果文件" aria-label="Permalink to &quot;0004 步骤结论只看结果文件&quot;">​</a></h1><ul><li>状态:已采纳</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to &quot;背景&quot;">​</a></h2><p>模型最后一条回复的格式不稳定,无法可靠解析。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to &quot;决定&quot;">​</a></h2><p>每个步骤写一个 JSON 结果文件,字段由引擎校验;缺失或无效时在同一会话中追问,次数有上限。</p><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to &quot;影响&quot;">​</a></h2><p>引擎的分支判断可靠、可测试。提示词需要说明结果文件的写法。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0004-result-files.md">docs/adr/0004-result-files.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0004-result-files.md">在 GitHub 上编辑</a></p>',2)])])}const p=a(i,[["render",l]]);export{f as __pageData,p as default};
1
+ import{_ as a,o as t,c as r,a2 as s}from"./chunks/framework.BetZR81g.js";const f=JSON.parse('{"title":"0004 步骤结论只看结果文件","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0004-result-files.md","filePath":"reference/adr/0004-result-files.md","lastUpdated":null}'),i={name:"reference/adr/0004-result-files.md"};function l(o,e,d,n,c,h){return t(),r("div",null,[...e[0]||(e[0]=[s('<div><h1 id="_0004-步骤结论只看结果文件" tabindex="-1">0004 步骤结论只看结果文件 <a class="header-anchor" href="#_0004-步骤结论只看结果文件" aria-label="Permalink to &quot;0004 步骤结论只看结果文件&quot;">​</a></h1><ul><li>状态:已采纳</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to &quot;背景&quot;">​</a></h2><p>模型最后一条回复的格式不稳定,无法可靠解析。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to &quot;决定&quot;">​</a></h2><p>每个步骤写一个 JSON 结果文件,字段由引擎校验;缺失或无效时在同一会话中追问,次数有上限。</p><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to &quot;影响&quot;">​</a></h2><p>引擎的分支判断可靠、可测试。提示词需要说明结果文件的写法。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0004-result-files.md">docs/adr/0004-result-files.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0004-result-files.md">在 GitHub 上编辑</a></p>',2)])])}const p=a(i,[["render",l]]);export{f as __pageData,p as default};
@@ -1 +1 @@
1
- import{_ as a,o as t,c as r,a3 as s}from"./chunks/framework.B9qR_F1m.js";const f=JSON.parse('{"title":"0004 步骤结论只看结果文件","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0004-result-files.md","filePath":"reference/adr/0004-result-files.md","lastUpdated":null}'),i={name:"reference/adr/0004-result-files.md"};function l(o,e,d,n,c,h){return t(),r("div",null,[...e[0]||(e[0]=[s("",2)])])}const p=a(i,[["render",l]]);export{f as __pageData,p as default};
1
+ import{_ as a,o as t,c as r,a2 as s}from"./chunks/framework.BetZR81g.js";const f=JSON.parse('{"title":"0004 步骤结论只看结果文件","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0004-result-files.md","filePath":"reference/adr/0004-result-files.md","lastUpdated":null}'),i={name:"reference/adr/0004-result-files.md"};function l(o,e,d,n,c,h){return t(),r("div",null,[...e[0]||(e[0]=[s("",2)])])}const p=a(i,[["render",l]]);export{f as __pageData,p as default};