paseo-req-kit 1.12.1 → 1.13.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +8 -3
- package/bin/bootstrap.d.mts +13 -0
- package/bin/bootstrap.mjs +444 -0
- package/bin/req-docs.d.mts +5 -0
- package/bin/req-docs.mjs +169 -0
- package/bin/req.mjs +21 -1
- package/contracts/cli-json.md +2 -0
- package/docs/adr/0032-npm-only-install.md +27 -0
- package/docs/adr/0033-prototype-review-and-ui-check.md +28 -0
- package/docs/adr/README.md +2 -0
- package/docs/guide//344/275/277/347/224/250/350/200/205/346/214/207/345/215/227.md +8 -0
- package/docs/guide//345/256/211/350/243/205/344/270/216/345/215/207/347/272/247.md +22 -2
- package/docs/guide//347/273/264/346/212/244/350/200/205/346/214/207/345/215/227.md +1 -1
- package/docs/guide//351/241/271/347/233/256/345/256/232/345/210/266/344/270/216/350/277/220/350/241/214/350/247/204/345/210/231.md +7 -1
- package/engine/prompts/03-design.md +5 -1
- package/engine/prompts/04b-design-revise.md +1 -1
- package/engine/prompts/browser-verify.md +2 -2
- package/engine/prompts/ui-check.md +15 -0
- package/engine/src/api.ts +17 -2
- package/engine/src/config-view.ts +1 -1
- package/engine/src/pipeline.ts +15 -7
- package/engine/src/review-assets/app.css +420 -0
- package/engine/src/review-assets/app.html +95 -0
- package/engine/src/review-assets/app.js +954 -0
- package/engine/src/review.ts +570 -0
- package/engine/src/ui-check-page.js +208 -0
- package/engine/src/ui-check.ts +366 -0
- package/package.json +3 -1
- package/paseo-plugin/client/data.ts +12 -1
- package/paseo-plugin/client/detail.tsx +3 -0
- package/paseo-plugin/client/inbox.tsx +2 -0
- package/paseo-plugin/client/review-link.tsx +29 -0
- package/paseo-plugin/index.server.ts +2 -1
- package/paseo-plugin/package.json +1 -1
- package/paseo-plugin/server/handlers.ts +7 -1
- package/paseo-plugin/shared/contracts.ts +9 -0
- package/site-dist/404.html +27 -0
- package/site-dist/assets/app.DWPPPhFm.js +1 -0
- package/site-dist/assets/changelog.md.CoelFFCL.js +1 -0
- package/site-dist/assets/changelog.md.CoelFFCL.lean.js +1 -0
- package/site-dist/assets/chunks/@localSearchIndexroot.Hdq0-4L3.js +1 -0
- package/site-dist/assets/chunks/VPLocalSearchBox.D3_9dRGY.js +9 -0
- package/site-dist/assets/chunks/framework.B9qR_F1m.js +20 -0
- package/site-dist/assets/chunks/theme.Bm8aLiLN.js +2 -0
- package/site-dist/assets/guide_getting-started.md.B4GJeoPz.js +6 -0
- package/site-dist/assets/guide_getting-started.md.B4GJeoPz.lean.js +1 -0
- package/site-dist/assets/guide_how-it-works.md.D-kQsF1t.js +25 -0
- package/site-dist/assets/guide_how-it-works.md.D-kQsF1t.lean.js +1 -0
- package/site-dist/assets/guide_index.md.CLnGCmGW.js +1 -0
- package/site-dist/assets/guide_index.md.CLnGCmGW.lean.js +1 -0
- package/site-dist/assets/guide_install.md.DkCyZsOU.js +42 -0
- package/site-dist/assets/guide_install.md.DkCyZsOU.lean.js +42 -0
- package/site-dist/assets/guide_maintainer.md.RZIzyCTV.js +1 -0
- package/site-dist/assets/guide_maintainer.md.RZIzyCTV.lean.js +1 -0
- package/site-dist/assets/guide_phases.md.BpGAb1re.js +1 -0
- package/site-dist/assets/guide_phases.md.BpGAb1re.lean.js +1 -0
- package/site-dist/assets/guide_project.md.nGlTCo4D.js +77 -0
- package/site-dist/assets/guide_project.md.nGlTCo4D.lean.js +77 -0
- package/site-dist/assets/guide_user.md.tiHFxIsQ.js +1 -0
- package/site-dist/assets/guide_user.md.tiHFxIsQ.lean.js +1 -0
- package/site-dist/assets/index.md.Cf_sSf_f.js +1 -0
- package/site-dist/assets/index.md.Cf_sSf_f.lean.js +1 -0
- package/site-dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/site-dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/site-dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/site-dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/site-dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/site-dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/site-dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/site-dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/site-dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/site-dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/site-dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/site-dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/site-dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/site-dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/site-dist/assets/reference_adr_0001-step-agents-under-origin-chat.md.RtRTq7oi.js +1 -0
- package/site-dist/assets/reference_adr_0001-step-agents-under-origin-chat.md.RtRTq7oi.lean.js +1 -0
- package/site-dist/assets/reference_adr_0002-no-directory-switch-in-chat.md.BxtN-Aa2.js +1 -0
- package/site-dist/assets/reference_adr_0002-no-directory-switch-in-chat.md.BxtN-Aa2.lean.js +1 -0
- package/site-dist/assets/reference_adr_0003-script-engine-not-hub.md.66EgZtqx.js +1 -0
- package/site-dist/assets/reference_adr_0003-script-engine-not-hub.md.66EgZtqx.lean.js +1 -0
- package/site-dist/assets/reference_adr_0004-result-files.md.DbqcCozI.js +1 -0
- package/site-dist/assets/reference_adr_0004-result-files.md.DbqcCozI.lean.js +1 -0
- package/site-dist/assets/reference_adr_0005-no-default-branch-local-commits-only.md.CkImA4s6.js +1 -0
- package/site-dist/assets/reference_adr_0005-no-default-branch-local-commits-only.md.CkImA4s6.lean.js +1 -0
- package/site-dist/assets/reference_adr_0006-skill-install-targets.md.CwY8YepV.js +1 -0
- package/site-dist/assets/reference_adr_0006-skill-install-targets.md.CwY8YepV.lean.js +1 -0
- package/site-dist/assets/reference_adr_0007-own-interview-skill.md.CryhxRyG.js +1 -0
- package/site-dist/assets/reference_adr_0007-own-interview-skill.md.CryhxRyG.lean.js +1 -0
- package/site-dist/assets/reference_adr_0008-entries-do-not-call-entries.md.DsRWAgeA.js +1 -0
- package/site-dist/assets/reference_adr_0008-entries-do-not-call-entries.md.DsRWAgeA.lean.js +1 -0
- package/site-dist/assets/reference_adr_0009-versioned-install-layout.md.CSg1VqlW.js +1 -0
- package/site-dist/assets/reference_adr_0009-versioned-install-layout.md.CSg1VqlW.lean.js +1 -0
- package/site-dist/assets/reference_adr_0010-generated-feature-overview.md.D8F3MK-h.js +1 -0
- package/site-dist/assets/reference_adr_0010-generated-feature-overview.md.D8F3MK-h.lean.js +1 -0
- package/site-dist/assets/reference_adr_0011-resume-after-completion.md.BCrZrKjf.js +1 -0
- package/site-dist/assets/reference_adr_0011-resume-after-completion.md.BCrZrKjf.lean.js +1 -0
- package/site-dist/assets/reference_adr_0012-review-panel.md.k9rrHFFc.js +1 -0
- package/site-dist/assets/reference_adr_0012-review-panel.md.k9rrHFFc.lean.js +1 -0
- package/site-dist/assets/reference_adr_0013-no-release-tooling.md.BQeJ8dEI.js +1 -0
- package/site-dist/assets/reference_adr_0013-no-release-tooling.md.BQeJ8dEI.lean.js +1 -0
- package/site-dist/assets/reference_adr_0014-notifier-slot.md.C23QR1xO.js +1 -0
- package/site-dist/assets/reference_adr_0014-notifier-slot.md.C23QR1xO.lean.js +1 -0
- package/site-dist/assets/reference_adr_0015-incremental-continue.md.Buy7wwO8.js +1 -0
- package/site-dist/assets/reference_adr_0015-incremental-continue.md.Buy7wwO8.lean.js +1 -0
- package/site-dist/assets/reference_adr_0016-upgrade-from-tags.md.qfIW-tqJ.js +1 -0
- package/site-dist/assets/reference_adr_0016-upgrade-from-tags.md.qfIW-tqJ.lean.js +1 -0
- package/site-dist/assets/reference_adr_0017-use-paseo-capabilities.md.CjcGli87.js +1 -0
- package/site-dist/assets/reference_adr_0017-use-paseo-capabilities.md.CjcGli87.lean.js +1 -0
- package/site-dist/assets/reference_adr_0018-own-worktree-option.md.fVDpgGSE.js +1 -0
- package/site-dist/assets/reference_adr_0018-own-worktree-option.md.fVDpgGSE.lean.js +1 -0
- package/site-dist/assets/reference_adr_0019-parallel-orchestration.md.DrfrV0To.js +1 -0
- package/site-dist/assets/reference_adr_0019-parallel-orchestration.md.DrfrV0To.lean.js +1 -0
- package/site-dist/assets/reference_adr_0020-scheduling-through-the-chat.md.BqSemGFG.js +1 -0
- package/site-dist/assets/reference_adr_0020-scheduling-through-the-chat.md.BqSemGFG.lean.js +1 -0
- package/site-dist/assets/reference_adr_0021-npm-version-manager.md.CU3PG6y5.js +1 -0
- package/site-dist/assets/reference_adr_0021-npm-version-manager.md.CU3PG6y5.lean.js +1 -0
- package/site-dist/assets/reference_adr_0022-develop-and-verify-phases.md.C6fQDLq4.js +1 -0
- package/site-dist/assets/reference_adr_0022-develop-and-verify-phases.md.C6fQDLq4.lean.js +1 -0
- package/site-dist/assets/reference_adr_0023-types-gate-slices.md.D2E6yyYQ.js +1 -0
- package/site-dist/assets/reference_adr_0023-types-gate-slices.md.D2E6yyYQ.lean.js +1 -0
- package/site-dist/assets/reference_adr_0024-confirm-early-review-axes.md.FmK_ke0x.js +1 -0
- package/site-dist/assets/reference_adr_0024-confirm-early-review-axes.md.FmK_ke0x.lean.js +1 -0
- package/site-dist/assets/reference_adr_0025-joint-requirements.md.ChoKvMUx.js +1 -0
- package/site-dist/assets/reference_adr_0025-joint-requirements.md.ChoKvMUx.lean.js +1 -0
- package/site-dist/assets/reference_adr_0026-machine-records-and-api.md.veybjBPq.js +1 -0
- package/site-dist/assets/reference_adr_0026-machine-records-and-api.md.veybjBPq.lean.js +1 -0
- package/site-dist/assets/reference_adr_0027-paseo-plugin.md.BMX33ZNU.js +1 -0
- package/site-dist/assets/reference_adr_0027-paseo-plugin.md.BMX33ZNU.lean.js +1 -0
- package/site-dist/assets/reference_adr_0028-external-integrations.md.DtdMe8RK.js +1 -0
- package/site-dist/assets/reference_adr_0028-external-integrations.md.DtdMe8RK.lean.js +1 -0
- package/site-dist/assets/reference_adr_0029-requirements-from-cards.md.BHd1SQPe.js +1 -0
- package/site-dist/assets/reference_adr_0029-requirements-from-cards.md.BHd1SQPe.lean.js +1 -0
- package/site-dist/assets/reference_adr_0030-card-intake-process.md.kLc-DG9_.js +1 -0
- package/site-dist/assets/reference_adr_0030-card-intake-process.md.kLc-DG9_.lean.js +1 -0
- package/site-dist/assets/reference_adr_0031-fewer-interventions.md.BDnQcz8g.js +1 -0
- package/site-dist/assets/reference_adr_0031-fewer-interventions.md.BDnQcz8g.lean.js +1 -0
- package/site-dist/assets/reference_adr_0032-npm-only-install.md.C-3L1FkX.js +1 -0
- package/site-dist/assets/reference_adr_0032-npm-only-install.md.C-3L1FkX.lean.js +1 -0
- package/site-dist/assets/reference_adr_0033-prototype-review-and-ui-check.md.hFcQzmaa.js +1 -0
- package/site-dist/assets/reference_adr_0033-prototype-review-and-ui-check.md.hFcQzmaa.lean.js +1 -0
- package/site-dist/assets/reference_adr_index.md.BYF-Ofor.js +1 -0
- package/site-dist/assets/reference_adr_index.md.BYF-Ofor.lean.js +1 -0
- package/site-dist/assets/reference_commands.md.ClKbS-t8.js +1 -0
- package/site-dist/assets/reference_commands.md.ClKbS-t8.lean.js +1 -0
- package/site-dist/assets/reference_config.md.CRe27LaA.js +6 -0
- package/site-dist/assets/reference_config.md.CRe27LaA.lean.js +1 -0
- package/site-dist/assets/reference_contracts_cli-json.md.N-v2HNUd.js +1 -0
- package/site-dist/assets/reference_contracts_cli-json.md.N-v2HNUd.lean.js +1 -0
- package/site-dist/assets/reference_contracts_feature-files.md.DSiA8OEH.js +26 -0
- package/site-dist/assets/reference_contracts_feature-files.md.DSiA8OEH.lean.js +26 -0
- package/site-dist/assets/reference_contracts_index.md.Bkznz4px.js +1 -0
- package/site-dist/assets/reference_contracts_index.md.Bkznz4px.lean.js +1 -0
- package/site-dist/assets/reference_contracts_notifier-event.md.CCfrkm_A.js +24 -0
- package/site-dist/assets/reference_contracts_notifier-event.md.CCfrkm_A.lean.js +24 -0
- package/site-dist/assets/reference_contracts_result-file.md.DmR4fjB-.js +1 -0
- package/site-dist/assets/reference_contracts_result-file.md.DmR4fjB-.lean.js +1 -0
- package/site-dist/assets/reference_contracts_spec.md.BwwS0L_j.js +8 -0
- package/site-dist/assets/reference_contracts_spec.md.BwwS0L_j.lean.js +8 -0
- package/site-dist/assets/reference_contracts_state.md.5bNTC3ow.js +1 -0
- package/site-dist/assets/reference_contracts_state.md.5bNTC3ow.lean.js +1 -0
- package/site-dist/assets/reference_contracts_usage-record.md._C0OXWeq.js +10 -0
- package/site-dist/assets/reference_contracts_usage-record.md._C0OXWeq.lean.js +10 -0
- package/site-dist/assets/reference_contracts_verify.md.CbA88u6S.js +29 -0
- package/site-dist/assets/reference_contracts_verify.md.CbA88u6S.lean.js +29 -0
- package/site-dist/assets/reference_scope.md.Kzqw8U_f.js +1 -0
- package/site-dist/assets/reference_scope.md.Kzqw8U_f.lean.js +1 -0
- package/site-dist/assets/style.Dwsa4SMe.css +1 -0
- package/site-dist/changelog.html +30 -0
- package/site-dist/guide/getting-started.html +35 -0
- package/site-dist/guide/how-it-works.html +54 -0
- package/site-dist/guide/index.html +30 -0
- package/site-dist/guide/install.html +71 -0
- package/site-dist/guide/maintainer.html +30 -0
- package/site-dist/guide/phases.html +30 -0
- package/site-dist/guide/project.html +106 -0
- package/site-dist/guide/user.html +30 -0
- package/site-dist/hashmap.json +1 -0
- package/site-dist/icons/agents.svg +1 -0
- package/site-dist/icons/chat.svg +1 -0
- package/site-dist/icons/paseo.svg +1 -0
- package/site-dist/icons/phases.svg +1 -0
- package/site-dist/icons/review.svg +1 -0
- package/site-dist/icons/safe.svg +1 -0
- package/site-dist/index.html +30 -0
- package/site-dist/install.ps1 +118 -0
- package/site-dist/install.sh +198 -0
- package/site-dist/logo.svg +11 -0
- package/site-dist/reference/adr/0001-step-agents-under-origin-chat.html +30 -0
- package/site-dist/reference/adr/0002-no-directory-switch-in-chat.html +30 -0
- package/site-dist/reference/adr/0003-script-engine-not-hub.html +30 -0
- package/site-dist/reference/adr/0004-result-files.html +30 -0
- package/site-dist/reference/adr/0005-no-default-branch-local-commits-only.html +30 -0
- package/site-dist/reference/adr/0006-skill-install-targets.html +30 -0
- package/site-dist/reference/adr/0007-own-interview-skill.html +30 -0
- package/site-dist/reference/adr/0008-entries-do-not-call-entries.html +30 -0
- package/site-dist/reference/adr/0009-versioned-install-layout.html +30 -0
- package/site-dist/reference/adr/0010-generated-feature-overview.html +30 -0
- package/site-dist/reference/adr/0011-resume-after-completion.html +30 -0
- package/site-dist/reference/adr/0012-review-panel.html +30 -0
- package/site-dist/reference/adr/0013-no-release-tooling.html +30 -0
- package/site-dist/reference/adr/0014-notifier-slot.html +30 -0
- package/site-dist/reference/adr/0015-incremental-continue.html +30 -0
- package/site-dist/reference/adr/0016-upgrade-from-tags.html +30 -0
- package/site-dist/reference/adr/0017-use-paseo-capabilities.html +30 -0
- package/site-dist/reference/adr/0018-own-worktree-option.html +30 -0
- package/site-dist/reference/adr/0019-parallel-orchestration.html +30 -0
- package/site-dist/reference/adr/0020-scheduling-through-the-chat.html +30 -0
- package/site-dist/reference/adr/0021-npm-version-manager.html +30 -0
- package/site-dist/reference/adr/0022-develop-and-verify-phases.html +30 -0
- package/site-dist/reference/adr/0023-types-gate-slices.html +30 -0
- package/site-dist/reference/adr/0024-confirm-early-review-axes.html +30 -0
- package/site-dist/reference/adr/0025-joint-requirements.html +30 -0
- package/site-dist/reference/adr/0026-machine-records-and-api.html +30 -0
- package/site-dist/reference/adr/0027-paseo-plugin.html +30 -0
- package/site-dist/reference/adr/0028-external-integrations.html +30 -0
- package/site-dist/reference/adr/0029-requirements-from-cards.html +30 -0
- package/site-dist/reference/adr/0030-card-intake-process.html +30 -0
- package/site-dist/reference/adr/0031-fewer-interventions.html +30 -0
- package/site-dist/reference/adr/0032-npm-only-install.html +30 -0
- package/site-dist/reference/adr/0033-prototype-review-and-ui-check.html +30 -0
- package/site-dist/reference/adr/index.html +30 -0
- package/site-dist/reference/commands.html +30 -0
- package/site-dist/reference/config.html +35 -0
- package/site-dist/reference/contracts/cli-json.html +30 -0
- package/site-dist/reference/contracts/feature-files.html +55 -0
- package/site-dist/reference/contracts/index.html +30 -0
- package/site-dist/reference/contracts/notifier-event.html +53 -0
- package/site-dist/reference/contracts/result-file.html +30 -0
- package/site-dist/reference/contracts/spec.html +37 -0
- package/site-dist/reference/contracts/state.html +30 -0
- package/site-dist/reference/contracts/usage-record.html +39 -0
- package/site-dist/reference/contracts/verify.html +58 -0
- package/site-dist/reference/scope.html +30 -0
- package/site-dist/vp-icons.css +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o,o as t,c as r,a3 as d}from"./chunks/framework.B9qR_F1m.js";const m=JSON.parse('{"title":"0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0029-requirements-from-cards.md","filePath":"reference/adr/0029-requirements-from-cards.md","lastUpdated":null}'),c={name:"reference/adr/0029-requirements-from-cards.md"};function a(i,e,s,l,n,u){return t(),r("div",null,[...e[0]||(e[0]=[d('<div><h1 id="_0029-从卡片开始的需求-需求会话代替人-卡片描述代替对话" tabindex="-1">0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话 <a class="header-anchor" href="#_0029-从卡片开始的需求-需求会话代替人-卡片描述代替对话" aria-label="Permalink to "0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话""></a></h1><ul><li>状态:已采纳(1.10.0-beta.2;建在 <a href="./0028-external-integrations">0028</a> 的外部系统对接之上)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to "背景""></a></h2><p>团队希望需求不必有人坐在 Paseo 对话前发起:需求方在需求管理系统(ALM)中写好一张卡片、标题加上约定的标识,就由一台共享的研发机器接手,整理需求、请需求方确认、开发、提测,结果回到卡片上。人只在确认需求、确认方案、验收这几个点介入("软件工厂")。</p><p>约束:</p><ul><li>ALM 不支持评论,状态只有新建、开发中、待测试等,没有"待补充""待确认"。</li><li>现有规则:步骤 agent 挂在发起需求的对话下,对话的工作目录不变;流水线只在本地提交。</li><li>卡片描述可能已经是一份完整的需求文档,也可能只有一句话;内容来自需求方,不能当作给 agent 的指令。</li></ul><p>另评估过 Paseo Hub:它的事件来源(GitHub、Slack、Discord、Linear)是编译在 Hub 代码里的,没有插件或通用 webhook;可用的扩展口只有开放 API 的 <code>manual.run</code> 和定时触发。代码在内部 GitLab、IM 是内部工具、Hub 只能内网自建,所以不用 Hub 接单;以后一台机器不够用时,再用内网 Hub 的 <code>manual.run</code> 把需求派到多台机器。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to "决定""></a></h2><ul><li><strong>需求会话代替人</strong>:<code>req start --from <系统>:<卡号></code> 读卡片、建功能目录(<code>docs/features/<日期>-<卡号简称>/</code>),然后在 Paseo 中为这个需求建一个顶层 agent(需求会话),工作目录是仓库,第一条消息以 <code>/req 无人值守</code> 开头。它按 <code>unattended.md</code> 手册整理需求说明,确认后用现有的"启动(自动新建工作区)"命令启动流水线,所以它就是流水线的发起对话:步骤 agent 挂在它下面,进度通知发给它,现有的启动、继续、确认方案命令都不变。人在 Paseo 中打开这个会话就能看到全部过程。</li><li><strong>卡片描述代替对话</strong>:描述末尾由 req-kit 维护两个区块:<code>## req-kit AI 区(自动维护,请勿修改)</code> 每次整块替换(进度一行 + 会话写的 <code>card-ai.md</code> + 必要时的方案摘要),<code>## 需求方回复(请在下方填写)</code> 只由需求方填写,req-kit 只读、只补空行(每个问题一行 <code>- Q1:</code>,以及 <code>- 确认:</code>、方案待确认时的 <code>- 方案确认:</code>)。区块以上需求方自己写的内容从不改动。每次写入前重新读取卡片。</li><li><strong>轮询而不是回调</strong>:<code>req card check</code> 读卡片,把新内容(回答、补充、描述的修改、"确认:同意""方案确认:同意")转给需求会话;只看有意义的内容(空的模板行不算),同样的内容只转一次。1.11 的接单器定时调用它。会话自己执行启动和确认方案的命令,req-kit 不替它决定。</li><li><strong>卡片状态少,确认放在描述里</strong>:澄清和确认期间卡片停在"新建",需求方确认后改为"开发中",研发完成后改为"待测试"(都由 <code>statusMap</code> 配置)。"只做研发"的需求在研发完成时发 <code>phase_done</code> 事件,而不是 <code>completed</code>:对外部系统来说,这就是"研发完成,待测试"。</li><li><strong>默认只做研发</strong>:从卡片开始的需求,项目没有指定执行方式时,默认研发完成、写好提测说明后停下,测试由测试同事做。</li><li><strong>卡片内容是数据</strong>:会话读到的卡片描述和回复放在 <code><card-description></code>、<code><card-reply></code> 中并注明不是指令;其中要求执行命令、推送、访问生产环境的一律不做。</li><li><strong>用这张卡片,不另建</strong>:功能目录的 <code>source.json</code> 记下来源;外部系统对接遇到它时直接使用这张卡片的编号,不再建卡。</li></ul><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to "影响""></a></h2><ul><li>对接配置新增 <code>query</code>(读一张卡片:参数 + 输出 JSON 中各值的位置)和 <code>describe</code>(改描述:<code>{description}</code> 是完整的新描述)。</li><li>新命令:<code>req start --from</code>、<code>req card publish | check | list</code>。本机新增 <code>~/.req-kit/cards/</code>(从卡片开始的需求的登记)。</li><li>功能目录新增 <code>source.json</code>、<code>card-source.md</code>、<code>card-ai.md</code>。</li><li>运行时新增 <code>startSessionAgent</code>:建一个不挂在任何对话下的 agent,工作目录是仓库。</li><li><strong>按子系统选仓库</strong>(beta.3):仓库在项目配置的 <code>cardSource</code> 中写明接哪个系统、空间和子系统,<code>/req-setup</code> 写入并在本机登记(<code>~/.req-kit/card-repos.json</code>);同一子系统有几个仓库时用 <code>titleKeywords</code> 区分。匹配不到或分不清时报错说明,不猜。</li><li><strong>工厂模式可以推送分支</strong>(beta.3,放宽"只在本地提交"):配置 <code>push.enabled</code> 后,只对从卡片开始的需求,在研发完成、写好提测说明后推送到 <code><remote>/req/<卡号简称></code>。只推这个前缀,不强推、不合并、不建合并请求;只能在本机或团队配置中打开。理由:接单的是共享机器,测试同事拿不到它的本地分支;合并这道人工关口不变。个人电脑上从对话发起的需求仍只在本地提交。</li><li>使用记录带上需求方(卡片的提出人)和卡号,统计可以按需求方汇总。1.11:接单器 <code>req factory</code>。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0029-requirements-from-cards.md">docs/adr/0029-requirements-from-cards.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0029-requirements-from-cards.md">在 GitHub 上编辑</a></p>',2)])])}const g=o(c,[["render",a]]);export{m as __pageData,g as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o,o as t,c as r,a3 as d}from"./chunks/framework.B9qR_F1m.js";const m=JSON.parse('{"title":"0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0029-requirements-from-cards.md","filePath":"reference/adr/0029-requirements-from-cards.md","lastUpdated":null}'),c={name:"reference/adr/0029-requirements-from-cards.md"};function a(i,e,s,l,n,u){return t(),r("div",null,[...e[0]||(e[0]=[d("",2)])])}const g=o(c,[["render",a]]);export{m as __pageData,g as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o,o as a,c,a3 as r}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"0030 接单器:共享机器上定时接卡片、转达回复","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0030-card-intake-process.md","filePath":"reference/adr/0030-card-intake-process.md","lastUpdated":null}'),t={name:"reference/adr/0030-card-intake-process.md"};function d(s,e,i,l,n,u){return a(),c("div",null,[...e[0]||(e[0]=[r('<div><h1 id="_0030-接单器-共享机器上定时接卡片、转达回复" tabindex="-1">0030 接单器:共享机器上定时接卡片、转达回复 <a class="header-anchor" href="#_0030-接单器-共享机器上定时接卡片、转达回复" aria-label="Permalink to "0030 接单器:共享机器上定时接卡片、转达回复""></a></h1><ul><li>状态:已采纳(1.11.0-beta.1;建在 <a href="./0029-requirements-from-cards">0029</a> 之上)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to "背景""></a></h2><p>1.10 已经可以从一张卡片开始需求(<code>req start --from</code>)、把需求方在卡片中的回复转给需求会话(<code>req card check</code>),但这两步都要有人运行。"软件工厂"要求需求方只在卡片上操作:写好卡片、标题加上约定的标识,就有一台共享研发机器接手。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to "决定""></a></h2><ul><li><strong>一个常驻进程,两件事</strong>:<code>req factory run</code> 每隔 <code>factory.pollMinutes</code>(默认 5 分钟)检查一次:先用对接配置的 <code>list</code> 命令列出各空间(本机登记仓库的 <code>cardSource.projectId</code>)中的卡片,标题以 <code>factory.titleTags</code>(默认 <code>[AI]</code>、<code>【AI】</code>)开头、本机还没开始过的,按 1.10 的 <code>req start --from</code> 开始(按子系统选仓库、建需求会话);再按 <code>req card check --all</code> 转达回复,跳过流水线已完成的需求。同一台机器上一次只做一次检查(<code>~/.req-kit/factory/poll.lock</code>)。</li><li><strong>轮询外部系统,不用回调</strong>:需求管理系统没有我们能用的事件推送;轮询的间隔是几分钟,对需求开发足够,失败了下次再来。卡片状态、条件(例如只查"新建"的用户故事)写在 <code>list</code> 的参数里,由团队配置决定。</li><li><strong>克制地接单</strong>:每次最多开始 <code>factory.maxNewPerPoll</code>(默认 3)个需求,其余下次再接;流水线本身仍受 <code>maxConcurrentPipelines</code> 限制。接不了的卡片(例如子系统没有对应的仓库)记下原因,卡片的标题和子系统不变就一天内不再试,<code>req factory status</code> 中可以看到。</li><li><strong>只读卡片、不改卡片状态来"占位"</strong>:本机的登记(<code>~/.req-kit/cards/</code>)就是去重的依据。卡片状态仍只由流水线事件改(开发中、待测试)。将来多台机器同时接单时再引入占位(例如改状态或经内网 Hub 派工),见 <a href="./0029-requirements-from-cards">0029</a>。</li><li><strong>运行方式交给系统</strong>:<code>req factory start</code> / <code>stop</code> 在后台运行,适合先试;长期运行用系统服务(<code>req factory service</code> 给出 systemd 用户服务或 Windows 计划任务的写法),机器重启后自动恢复。接单器通过 Paseo daemon 创建需求会话,daemon 需要同时运行。</li><li><strong>配置只在本机或团队配置中</strong>:<code>factory</code> 和 <code>integrations</code> 一样会让机器做事,写在项目配置中会被忽略。</li></ul><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to "影响""></a></h2><ul><li>对接配置新增 <code>list</code>(参数可用 <code>{projectId}</code>、<code>{page}</code>、<code>{pageSize}</code>、<code>{titleTag}</code>;<code>fields</code> 写每张卡片中 id、title 等的位置;<code>items</code> 写输出中列表的位置,不写时依次找 data.list、data.records、data.items、data.rows、data)。</li><li>新增配置 <code>factory</code>(<code>pollMinutes</code>、<code>titleTags</code>、<code>maxNewPerPoll</code>)、命令 <code>req factory once | run | start | stop | status | service</code>、本机目录 <code>~/.req-kit/factory/</code>(日志、状态、没能接的卡片)。</li><li><code>req start --from</code> 中途失败(例如 Paseo 没在运行,会话没建成)时,再次运行会补建会话,而不是当作已经开始过。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0030-card-intake-process.md">docs/adr/0030-card-intake-process.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0030-card-intake-process.md">在 GitHub 上编辑</a></p>',2)])])}const m=o(t,[["render",d]]);export{p as __pageData,m as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o,o as a,c,a3 as r}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"0030 接单器:共享机器上定时接卡片、转达回复","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0030-card-intake-process.md","filePath":"reference/adr/0030-card-intake-process.md","lastUpdated":null}'),t={name:"reference/adr/0030-card-intake-process.md"};function d(s,e,i,l,n,u){return a(),c("div",null,[...e[0]||(e[0]=[r("",2)])])}const m=o(t,[["render",d]]);export{p as __pageData,m as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o,o as t,c as r,a3 as i}from"./chunks/framework.B9qR_F1m.js";const q=JSON.parse('{"title":"0031 少等人:每种中断都有自动的下一步","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0031-fewer-interventions.md","filePath":"reference/adr/0031-fewer-interventions.md","lastUpdated":null}'),a={name:"reference/adr/0031-fewer-interventions.md"};function n(s,e,l,d,c,u){return t(),r("div",null,[...e[0]||(e[0]=[i('<div><h1 id="_0031-少等人-每种中断都有自动的下一步" tabindex="-1">0031 少等人:每种中断都有自动的下一步 <a class="header-anchor" href="#_0031-少等人-每种中断都有自动的下一步" aria-label="Permalink to "0031 少等人:每种中断都有自动的下一步""></a></h1><ul><li>状态:已采纳(1.12.0-beta.1)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to "背景""></a></h2><p>目标是需求方只在三处介入:确认需求、确认方案(只有界面改动时)、验收合并。核对代码、默认配置和 <code>/req</code> 手册后,现在要人的地方共 16 处,其中只有这 3 处是必要的决定;其余多数来自两类:</p><ul><li><strong>中断等人继续</strong>:步骤超时、agent 报错、结果文件无效直接中断;限流重试用完只按固定间隔自动继续两次;后台进程意外退出的定时检查默认关闭。</li><li><strong>可以有默认值的选择题</strong>:是否新建工作区、档位、执行方式、现在开始还是预约;装好后要运行配置向导选模型;方案审核提出的问题不加筛选地交给需求方。</li></ul><p>另外,过去没有记录每次停下等人的原因,无法用数据判断先改哪里。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to "决定""></a></h2><ul><li><strong>先记录</strong>:状态文件和使用记录加上 <code>stopKind</code>(停下等人的原因代码)和 <code>recoveries</code>(自己处理掉的问题),<code>req stats</code> 新增"人工介入"一节。用两周的真实数据复核后续的优先级。</li><li><strong>自愈</strong>(<code>selfHeal</code>,默认开): <ul><li>超时:agent 还在做就再等同样长的时间,不打断它;仍未完成才中断(1.11 已保证继续时不会另起一个 agent)。</li><li>agent 报错、结果文件无效:新开一个 agent 重做一次。只重做一次,避免一个确实做不了的步骤反复消耗额度。</li></ul></li><li><strong>备用模型</strong>(<code>agents.fallback</code>,可选):报错重做、限流重试用完时换它做一次。只用一次、只在这一步,下一步仍用主模型。</li><li><strong>按额度恢复时间预约</strong>:限流中断时,读 Paseo 报告的额度恢复时间,预约在恢复后 5 分钟自动继续;读不到时仍按 <code>autoResumeMinutes</code>。</li><li><strong>后台进程退出后续跑</strong>:个人机器的定时检查默认打开(60 分钟);接单器每次检查时发现"运行中但进程已不在"的流水线,请它的对话检查并继续,每个进程只提醒一次。</li><li><strong>方案审核的问题先自答</strong>(<code>answerQuestionsFirst</code>,默认开):审核结论为"需要需求方决定"时,先让 builder 在方案修订中从代码、文档和需求说明里找答案;只把真正的业务取舍连同推荐答案交给需求方,都能回答时不停下。</li><li><strong>装好就能用</strong>:安装时 <code>req configure --auto</code> 不提问,按推荐选好已登录的 agent(两个不同厂商分别做 builder、reviewer,再选一个做备用,都用免确认模式)。插件新增"模型"设置页,列出 Paseo 中已登录的 agent,选择后写回本机配置,与 <code>req configure</code> 用同一套逻辑。</li><li><strong>默认值代替选择题</strong>:<code>/req</code> 不再问是否新建工作区、档位、执行方式、现在开始还是预约,按推荐值直接走,在确认摘要的最后一行写明,想改再说;确认需求说明就是同意开始。</li><li><strong>卡片回复更宽松</strong>:回复区写"好的""没问题""按你说的来"也算同意;只写了这样一句、没有别的内容时,按正在等待的确认(需求说明或方案)处理。卡片已经写清需求时,需求会话不为提问而提问。</li></ul><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to "影响""></a></h2><ul><li>新配置:<code>selfHeal</code>、<code>answerQuestionsFirst</code>、<code>agents.fallback</code>;<code>watchdogMinutes</code> 默认从 0 改为 60。想保持以前行为的,把它们设为 <code>false</code> / <code>0</code>。</li><li>方案修订的结果文件可以带 <code>business_questions</code>。</li><li>新命令:<code>req configure --auto</code>、<code>req api models</code>、<code>req api set-agents</code>。</li><li>自动处理会多用一些额度(多等一轮、重做一次);每次都写进进度日志和使用记录,可以查到。</li></ul><h2 id="补充-1-12-0-beta-3-接单机器的运维和插件中的处理" tabindex="-1">补充(1.12.0-beta.3):接单机器的运维和插件中的处理 <a class="header-anchor" href="#补充-1-12-0-beta-3-接单机器的运维和插件中的处理" aria-label="Permalink to "补充(1.12.0-beta.3):接单机器的运维和插件中的处理""></a></h2><ul><li><strong>接单器自检</strong>:每次检查前确认 Paseo、agent 登录、额度和需求管理系统的命令。不正常就整次跳过(不接新单、不转达),因为这时接下来的需求也跑不起来;告警走外部通知的新事件 <code>alert</code>,按"问题的内容"去重,只在出现、变化和恢复时各发一次,避免刷屏。</li><li><strong>草稿合并请求</strong>:和对接配置一样,命令写在配置里、参数用占位符,req-kit 不内置 GitLab 接口、不保存令牌;只建草稿、每个仓库只建一次,合并仍由人做。</li><li><strong>自动确认</strong>:只对快速档、没有待答问题的卡片,默认关闭;需求方写了任何内容就不自动确认,每次摘要更新重新计时。确认仍然发生在需求会话里,req-kit 只是在到时转达"按自动确认处理"。</li><li><strong>按人通知</strong>:事件带上 <code>people</code>(发给需求方还是群、需求方的账号),账号来自本机或团队配置的 <code>people</code>,内部 IM 的适配器拿到接口后只需要读它。</li><li><strong>插件"等你处理"和配置页</strong>:回答和方案意见用 <code>req reply</code> 转给需求的对话,由对话按原来的做法更新需求说明并继续,插件不直接改需求文件或状态;配置页只读,展示 <code>req api config</code> 的结果,密钥和个人账号不显示。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0031-fewer-interventions.md">docs/adr/0031-fewer-interventions.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0031-fewer-interventions.md">在 GitHub 上编辑</a></p>',2)])])}const f=o(a,[["render",n]]);export{q as __pageData,f as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o,o as t,c as r,a3 as i}from"./chunks/framework.B9qR_F1m.js";const q=JSON.parse('{"title":"0031 少等人:每种中断都有自动的下一步","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0031-fewer-interventions.md","filePath":"reference/adr/0031-fewer-interventions.md","lastUpdated":null}'),a={name:"reference/adr/0031-fewer-interventions.md"};function n(s,e,l,d,c,u){return t(),r("div",null,[...e[0]||(e[0]=[i("",2)])])}const f=o(a,[["render",n]]);export{q as __pageData,f as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as t,o as a,c as l,a3 as o}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"0032 安装、升级和文档只依赖 npm 源","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0032-npm-only-install.md","filePath":"reference/adr/0032-npm-only-install.md","lastUpdated":null}'),i={name:"reference/adr/0032-npm-only-install.md"};function n(s,e,d,r,c,p){return a(),l("div",null,[...e[0]||(e[0]=[o('<div><h1 id="_0032-安装、升级和文档只依赖-npm-源" tabindex="-1">0032 安装、升级和文档只依赖 npm 源 <a class="header-anchor" href="#_0032-安装、升级和文档只依赖-npm-源" aria-label="Permalink to "0032 安装、升级和文档只依赖 npm 源""></a></h1><ul><li>状态:已采纳(1.13.0-beta.1)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to "背景""></a></h2><p>req-kit 要分发给公司内网的使用者。内网有 npm 镜像,但打不开 GitHub 和部署在 Vercel、GitHub Pages 上的文档站点。过去的一键安装依赖三样外网资源:</p><ul><li>安装脚本 <code>install.sh</code> / <code>install.ps1</code> 放在文档站点上;</li><li>npm 上没有某个版本时,脚本去 GitHub 的 Release 列表找安装包;</li><li>文档只在线上站点。</li></ul><p>另外,两份脚本各自实现了检查环境、安装 Paseo、启用、配置 agent、插件这些步骤,改一处要改两处,Windows 和其他系统的行为也容易不一致。</p><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to "决定""></a></h2><ul><li><strong>安装逻辑放进包里</strong>:新增 <code>req install</code>(<code>bin/bootstrap.mjs</code>,Node.js 实现),包含原来脚本的全部步骤。包新增同名命令 <code>paseo-req-kit</code>,所以任何能访问 npm 源的机器都可以直接运行 <code>npx -y paseo-req-kit@latest install</code>。</li><li><strong>镜像地址只说一次</strong>:<code>npx -y --registry=<镜像> … install</code>(或 <code>--registry <镜像></code>)会把镜像保存为本机的 npm 源,之后的升级和 Paseo 命令行安装都走镜像;<code>--no-save-registry</code> 只用这一次。指定了镜像而镜像上没有这个版本时,直接说明可能还没同步,不再尝试 GitHub。</li><li><strong>安装脚本变薄</strong>:<code>install.sh</code> / <code>install.ps1</code> 只检查 Node.js 和 npm、选版本(npm 优先,GitHub Release 兜底),然后用 <code>npm exec</code> 运行那个版本自带的 <code>install</code>。外网用户的用法不变。</li><li><strong>文档随包发布</strong>:发布流程把文档站点构建进 npm 包(<code>site-dist/</code>),<code>req docs</code> 在本机起一个只监听 127.0.0.1 的服务并打开浏览器。文档和装的版本一致,不需要外网。</li><li>内网的共享文档站点(例如内网 Git Pages)是可选的,可以从镜像中的 npm 包取出 <code>site-dist/</code> 部署,另行实现。</li></ul><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to "影响""></a></h2><ul><li>1.13 之前的版本没有 <code>install</code> 命令:新的安装脚本只能安装 1.13 及以后的版本。要装更早的版本,用那个版本标签下的旧脚本,或 <code>npm i -g paseo-req-kit@<版本> && req setup</code>。</li><li>npm 包增加了构建好的文档站点(约几 MB)。</li><li>内网只支持 npm 方式安装和升级;git 方式仍需访问 GitHub。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0032-npm-only-install.md">docs/adr/0032-npm-only-install.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0032-npm-only-install.md">在 GitHub 上编辑</a></p>',2)])])}const h=t(i,[["render",n]]);export{u as __pageData,h as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as t,o as a,c as l,a3 as o}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"0032 安装、升级和文档只依赖 npm 源","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0032-npm-only-install.md","filePath":"reference/adr/0032-npm-only-install.md","lastUpdated":null}'),i={name:"reference/adr/0032-npm-only-install.md"};function n(s,e,d,r,c,p){return a(),l("div",null,[...e[0]||(e[0]=[o("",2)])])}const h=t(i,[["render",n]]);export{u as __pageData,h as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o,o as a,c as t,a3 as i}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"0033 原型审查页和不靠看图的界面检查","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0033-prototype-review-and-ui-check.md","filePath":"reference/adr/0033-prototype-review-and-ui-check.md","lastUpdated":null}'),r={name:"reference/adr/0033-prototype-review-and-ui-check.md"};function d(c,e,l,n,s,u){return a(),t("div",null,[...e[0]||(e[0]=[i('<div><h1 id="_0033-原型审查页和不靠看图的界面检查" tabindex="-1">0033 原型审查页和不靠看图的界面检查 <a class="header-anchor" href="#_0033-原型审查页和不靠看图的界面检查" aria-label="Permalink to "0033 原型审查页和不靠看图的界面检查""></a></h1><ul><li>状态:已采纳(1.13.0-beta.2)</li></ul><h2 id="背景" tabindex="-1">背景 <a class="header-anchor" href="#背景" aria-label="Permalink to "背景""></a></h2><p>内网的使用者有三个限制:</p><ul><li>只能用 Paseo 网页端(桌面端有安装限制),所以 Paseo 内置浏览器和它的 <code>browser_*</code> 工具用不了,1.8 起的"浏览器验证"实际上从不运行。</li><li>内网模型看图能力弱:截图交给它判断界面对不对,效果差,每张图还要消耗不少 token。</li><li>需求方多数不是开发者,确认方案时看得出"不对",但说不清哪里不对、要改成什么;插件里只有一个文本框写修改意见。插件页面也不能显示 HTML,原型只能在功能目录里自己找文件打开。</li></ul><h2 id="决定" tabindex="-1">决定 <a class="header-anchor" href="#决定" aria-label="Permalink to "决定""></a></h2><ul><li><strong>原型审查页</strong>:一个本机网页(<code>engine/src/review.ts</code>),插件和 <code>req review</code> 打开它。需求方在原型上点选、选改法、补一句话,页面记下被点元素的文字、颜色、字号、大小、所在区域和对应的 AC;双击可以直接改文字。提交时整理成一份带位置信息的清单,经已有的 <code>req reply</code> 转给需求会话,确认方案经 <code>req approve</code>:不增加新的流程分支。 <ul><li>原型由 agent 生成,内容可能来自卡片等外部文字,和提交接口同源。所以原型以 <code>script-src 'none'</code> 返回,里面的脚本不运行,审查页从外面读写它的 DOM。</li><li>服务只监听 <code>127.0.0.1</code>,地址带随机令牌;另有一个只读令牌。远程访问要显式设置环境变量。</li><li>每次打开时保存原型的版本,改过后用文字差异标出变化,需求方不用自己找改了哪里。</li><li>方案设计的提示词规定原型的写法(<code>data-ac</code>、<code>data-label</code>、<code>data-state</code>、真实文字),审查页和界面检查都依赖它。</li></ul></li><li><strong>界面检查 <code>req ui-check</code></strong>:用 <code>playwright-core</code> 驱动本机的 Edge 或 Chrome(不下载浏览器,驱动在第一次使用时从 npm 源装到 <code>~/.req-kit/tools</code>),在页面里运行一段固定的脚本,用文字报告看得出的版面问题,并拿原型里的标题、按钮、字段名、表头和页面对文字。结果是确定的,不依赖模型看图。截图只存文件给人看。验证类步骤总是附上它;有 Paseo 浏览器时,同一段脚本也可以用 <code>browser_evaluate</code> 运行。</li><li>对比度只报明显看不清的(低于 3:1,大字 2.5:1),不报 WCAG 4.5:1 的边缘情况:常见组件库的主按钮正好在这个边缘,全报会淹没真正的问题。</li></ul><h2 id="影响" tabindex="-1">影响 <a class="header-anchor" href="#影响" aria-label="Permalink to "影响""></a></h2><ul><li>需求方确认方案的方式从"写一段话"变成"在原型上点",修改意见能直接定位到元素。效果要看原型是否按约定标了区域。</li><li>验证不再依赖桌面端和模型的视觉能力;需要本机有 Edge 或 Chrome(Windows 自带 Edge)。</li><li><code>req ui-check</code> 第一次运行要能从 npm 源取到 <code>playwright-core</code>,内网走镜像。</li><li>只检查"看得出的"问题,不判断设计是否好看;"和原型对文字"只比较标签类文字,原型中的示例数据不比较。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/0033-prototype-review-and-ui-check.md">docs/adr/0033-prototype-review-and-ui-check.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/0033-prototype-review-and-ui-check.md">在 GitHub 上编辑</a></p>',2)])])}const q=o(r,[["render",d]]);export{p as __pageData,q as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o,o as a,c as t,a3 as i}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"0033 原型审查页和不靠看图的界面检查","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/0033-prototype-review-and-ui-check.md","filePath":"reference/adr/0033-prototype-review-and-ui-check.md","lastUpdated":null}'),r={name:"reference/adr/0033-prototype-review-and-ui-check.md"};function d(c,e,l,n,s,u){return a(),t("div",null,[...e[0]||(e[0]=[i("",2)])])}const q=o(r,[["render",d]]);export{p as __pageData,q as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as a,o as i,c as r,a3 as l}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"设计决定(ADR)","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/index.md","filePath":"reference/adr/index.md","lastUpdated":null}'),t={name:"reference/adr/index.md"};function n(s,e,o,f,h,d){return i(),r("div",null,[...e[0]||(e[0]=[l('<div><h1 id="设计决定-adr" tabindex="-1">设计决定(ADR) <a class="header-anchor" href="#设计决定-adr" aria-label="Permalink to "设计决定(ADR)""></a></h1><p>req-kit 自身的设计决定。修改其中任何一条,请新增一条 ADR 说明理由,并在旧的一条中注明被哪条取代。</p><ul><li><a href="./0001-step-agents-under-origin-chat">0001 步骤 agent 挂在发起的对话下</a></li><li><a href="./0002-no-directory-switch-in-chat">0002 对话过程中不切换工作目录</a></li><li><a href="./0003-script-engine-not-hub">0003 第 3–11 步由脚本引擎驱动,不用 Hub 多步骤工作流</a></li><li><a href="./0004-result-files">0004 步骤结论只看结果文件</a></li><li><a href="./0005-no-default-branch-local-commits-only">0005 不在默认分支上运行,只做本地提交</a></li><li><a href="./0006-skill-install-targets">0006 只安装到 ~/.agents/skills 和 ~/.claude/skills</a></li><li><a href="./0007-own-interview-skill">0007 自带需求访谈 skill,不依赖外部 skill 包</a></li><li><a href="./0008-entries-do-not-call-entries">0008 入口 skill 之间不互相调用</a></li><li><a href="./0009-versioned-install-layout">0009 程序与本机配置分开存放,按版本目录并存</a></li><li><a href="./0010-generated-feature-overview">0010 需求总览现场生成,不维护 INDEX.md</a></li><li><a href="./0011-resume-after-completion">0011 完成后修改 spec 可以继续开发</a></li><li><a href="./0012-review-panel">0012 评审小组:首轮并行评审,评审者核实汇总</a></li><li><a href="./0013-no-release-tooling">0013 发布不使用 changesets 等工具</a></li><li><a href="./0014-notifier-slot">0014 外部通知只留接口,不内置任何 IM</a></li><li><a href="./0015-incremental-continue">0015 需求变更后增量继续,而不是从零重做</a></li><li><a href="./0016-upgrade-from-tags">0016 一键升级:从 git 标签下载到 versions/ 再切换</a></li><li><a href="./0017-use-paseo-capabilities">0017 用好 Paseo 自身的能力:profile、工作区脚本、用量和时间线</a></li><li><a href="./0018-own-worktree-option">0018 可选:流水线为需求新建 worktree 工作区</a></li><li><a href="./0019-parallel-orchestration">0019 用 Paseo 的并行子 agent:确认前独立审阅、方案提案</a></li><li><a href="./0020-scheduling-through-the-chat">0020 调度:用 Paseo 定时任务把消息发回对话,排队在本机进行</a></li><li><a href="./0021-npm-version-manager">0021 npm 分发:全局包是版本管理器,各版本仍装在 versions/ 下</a></li><li><a href="./0022-develop-and-verify-phases">0022 分阶段执行:研发阶段、闸口、测试验证阶段</a></li><li><a href="./0023-types-gate-slices">0023 需求类型、质量门、按切片实现</a></li><li><a href="./0024-confirm-early-review-axes">0024 让分歧更早暴露:验收例子、方案确认点、两个方向的评审、反复的问题变成规则</a></li><li><a href="./0025-joint-requirements">0025 联合需求:一个需求同时改几个仓库</a></li><li><a href="./0026-machine-records-and-api">0026 本机的需求索引、使用记录和 req api</a></li><li><a href="./0027-paseo-plugin">0027 Paseo 插件:随 req-kit 一起发布,只通过 req api 工作</a></li><li><a href="./0028-external-integrations">0028 外部系统对接:命令写法在配置里,内容由 AI 整理,调用是确定的</a></li><li><a href="./0029-requirements-from-cards">0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话</a></li><li><a href="./0030-card-intake-process">0030 接单器:共享机器上定时接卡片、转达回复</a></li><li><a href="./0031-fewer-interventions">0031 少等人:每种中断都有自动的下一步</a></li><li><a href="./0032-npm-only-install">0032 安装、升级和文档只依赖 npm 源</a></li><li><a href="./0033-prototype-review-and-ui-check">0033 原型审查页和不靠看图的界面检查</a></li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/docs/adr/README.md">docs/adr/README.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/docs/adr/README.md">在 GitHub 上编辑</a></p>',2)])])}const m=a(t,[["render",n]]);export{p as __pageData,m as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as a,o as i,c as r,a3 as l}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"设计决定(ADR)","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/adr/index.md","filePath":"reference/adr/index.md","lastUpdated":null}'),t={name:"reference/adr/index.md"};function n(s,e,o,f,h,d){return i(),r("div",null,[...e[0]||(e[0]=[l("",2)])])}const m=a(t,[["render",n]]);export{p as __pageData,m as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e,o as d,c as o,a3 as r}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"命令","description":"","frontmatter":{},"headers":[],"relativePath":"reference/commands.md","filePath":"reference/commands.md","lastUpdated":1792362729000}'),c={name:"reference/commands.md"};function a(s,t,l,i,n,q){return d(),o("div",null,[...t[0]||(t[0]=[r('<h1 id="命令" tabindex="-1">命令 <a class="header-anchor" href="#命令" aria-label="Permalink to "命令""></a></h1><p>req-kit 有三类入口:在 Paseo 对话中使用的 <strong>skill</strong>,终端中的 <strong><code>req</code> 命令</strong>,以及 skill 在背后调用的<strong>流水线启动器</strong>。日常使用只需要第一类。</p><h2 id="对话中的-skill" tabindex="-1">对话中的 skill <a class="header-anchor" href="#对话中的-skill" aria-label="Permalink to "对话中的 skill""></a></h2><table tabindex="0"><thead><tr><th>输入</th><th>作用</th><th>通常谁用</th></tr></thead><tbody><tr><td><code>/req <一句话></code></td><td>需求开发入口:新需求、小改动、查看进度、暂停或继续、修改需求、开始测试验证、验收、上线后问题、接手。由它判断走哪本手册</td><td>使用者</td></tr><tr><td><code>/req-setup</code></td><td>项目接入:生成项目说明、验证方法、<code>paseo.json</code>,确认后提交</td><td>开发或熟悉项目的测试同事</td></tr><tr><td><code>/req-doctor</code></td><td>体检:安装、配置、daemon、当前项目</td><td>任何人</td></tr><tr><td><code>/req-retro</code></td><td>复盘:需求做完后回顾返工、中断和变更,把改进落到 CI、配置、项目说明或提示词</td><td>开发同事</td></tr></tbody></table><p>Pi 中写作 <code>/skill:req</code>。同一个对话里,之后的"做到哪了""先停一下""继续开发""开始测试验证""我要验收"不需要再带 <code>/req</code>。</p><h2 id="req-命令" tabindex="-1">req 命令 <a class="header-anchor" href="#req-命令" aria-label="Permalink to "req 命令""></a></h2><p>安装后提供 <code>req</code>(同名命令 <code>req-kit</code>,避免和其他工具冲突)。Windows PowerShell 受执行策略限制时用 <code>req.cmd</code>。</p><h3 id="在项目目录中" tabindex="-1">在项目目录中 <a class="header-anchor" href="#在项目目录中" aria-label="Permalink to "在项目目录中""></a></h3><table tabindex="0"><thead><tr><th>命令</th><th>作用</th></tr></thead><tbody><tr><td><code>req list</code></td><td>列出这个项目所有工作区中的需求和阶段</td></tr><tr><td><code>req status [需求]</code></td><td>查看进度;只有一个需求运行过时可以不写</td></tr><tr><td><code>req stop <需求></code></td><td>停止流水线(之后可以继续);同时取消预约的开始、提醒、自动继续</td></tr><tr><td><code>req resume <需求></code></td><td>从上次中断处继续;需求改过时只处理变化的部分</td></tr><tr><td><code>req approve <需求></code></td><td>需求方看过 <code>preview.md</code> 并确认后,从方案确认点继续开发</td></tr><tr><td><code>req verify <需求> [--verify-env local|deployed] [--defects fix|handback|report]</code></td><td>研发完成后开始测试验证(分阶段执行时)</td></tr><tr><td><code>req start <需求> [--profile quick|standard] [--phases gated] [--at 22:00]</code></td><td>启动流水线(通常由 <code>/req</code> 在对话中启动)</td></tr><tr><td><code>req digest [--notify]</code></td><td>项目的需求总览;<code>--notify</code> 同时发到外部通知</td></tr><tr><td><code>req digest --schedule "0 9 * * 1"</code></td><td>让 Paseo 按时间表发送需求总览;取消:<code>req digest --cancel <ID></code></td></tr><tr><td><code>req sync <需求></code></td><td>把需求同步到对接的外部系统:补发没有成功的调用、补建卡片、更新状态</td></tr><tr><td><code>req integration test [需求]</code></td><td>显示对接外部系统时每个事件会执行的命令,不真正调用</td></tr><tr><td><code>req start --from <系统>:<卡号> [--repo <仓库>]</code></td><td>从需求管理系统中的一张卡片开始需求:建功能目录和需求会话,问题和确认通过卡片描述;不写 <code>--repo</code> 时按子系统选仓库</td></tr><tr><td><code>req card check [<卡号> | --all]</code></td><td>读取需求方在卡片中的回复,把新内容转给需求会话</td></tr><tr><td><code>req card publish <卡号></code></td><td>需求会话使用:把 <code>card-ai.md</code> 写进卡片的 AI 区</td></tr><tr><td><code>req card list</code></td><td>本机从卡片开始的需求和各自的进展</td></tr><tr><td><code>req card route [--add <仓库> | --remove <仓库>]</code></td><td>本机接收卡片的仓库和各自的子系统;<code>req start --from</code> 不写 <code>--repo</code> 时按它选仓库</td></tr><tr><td><code>req factory once | run | start | stop | status | service</code></td><td>接单器:定时为标题带 <code>[AI]</code> 的新卡片开始需求、转达需求方的回复;<code>once</code> 检查一次,<code>start</code>/<code>stop</code> 后台运行,<code>service</code> 给出作为系统服务运行的写法</td></tr><tr><td><code>req index --rebuild [目录…]</code></td><td>把这些仓库中运行过的需求登记进本机的需求索引(1.9 之前运行过的需求用)</td></tr></tbody></table><h3 id="使用统计-任何目录" tabindex="-1">使用统计(任何目录) <a class="header-anchor" href="#使用统计-任何目录" aria-label="Permalink to "使用统计(任何目录)""></a></h3><table tabindex="0"><thead><tr><th>命令</th><th>作用</th></tr></thead><tbody><tr><td><code>req stats [--since 30d] [--month 2026-10]</code></td><td>本机的使用统计:需求数、交付周期、返工、等待、各步骤用时、用量;<code>--json</code>、<code>--csv</code></td></tr><tr><td><code>req stats --report [--out 目录]</code></td><td>生成汇报用的 <code>.md</code> 汇总和 <code>.csv</code> 明细</td></tr><tr><td><code>req stats --export [文件]</code></td><td>导出本机的运行记录</td></tr><tr><td><code>req stats --merge <文件…> --report</code></td><td>汇总几台机器的导出</td></tr><tr><td><code>req index [--prune]</code></td><td>本机记录的需求;<code>--prune</code> 移除目录已不在的</td></tr><tr><td><code>req api <命令> …</code></td><td>给程序用的 JSON 输出,见 <a href="./contracts/cli-json">req api</a></td></tr></tbody></table><h3 id="paseo-插件" tabindex="-1">Paseo 插件 <a class="header-anchor" href="#paseo-插件" aria-label="Permalink to "Paseo 插件""></a></h3><table tabindex="0"><thead><tr><th>命令</th><th>作用</th></tr></thead><tbody><tr><td><code>req plugin install [--yes]</code></td><td>安装或更新 req-kit 的 Paseo 插件;需要时询问是否打开 Paseo 的插件总开关</td></tr><tr><td><code>req plugin status</code></td><td>插件是否在运行</td></tr><tr><td><code>req plugin remove</code></td><td>从 Paseo 移除插件</td></tr></tbody></table><p><code><需求></code> 可以写功能目录(<code>docs/features/20261012-sms-login</code>)、目录名,或名称中能唯一确定的一部分(<code>sms-login</code>)。</p><h3 id="本机维护" tabindex="-1">本机维护 <a class="header-anchor" href="#本机维护" aria-label="Permalink to "本机维护""></a></h3><table tabindex="0"><thead><tr><th>命令</th><th>作用</th></tr></thead><tbody><tr><td><code>req install [--registry <地址>]</code></td><td>安装或升级(与 <code>npx -y paseo-req-kit@latest install</code> 相同),见下面的"安装脚本"</td></tr><tr><td><code>req docs [--port <端口>] [--no-open]</code></td><td>在本机打开这个版本的文档站点(不需要外网)</td></tr><tr><td><code>req doctor [--no-project]</code></td><td>体检:安装、配置、daemon、当前项目</td></tr><tr><td><code>req configure</code></td><td>配置向导:为 builder、reviewer 和备用模型选择 agent</td></tr><tr><td><code>req configure --auto</code></td><td>不提问,按推荐选好(1.12;安装时自动运行)</td></tr><tr><td><code>req reply <需求> <回复></code></td><td>把回答或方案意见转给需求的对话(1.12;插件"等你处理"用它)</td></tr><tr><td><code>req setup</code></td><td>启用 npm 安装的这个版本、安装 skill(安装脚本会自动运行)</td></tr><tr><td><code>req upgrade [版本] [--beta]</code></td><td>升级到最新版本(或指定版本),自动选能支持本机 Paseo 的版本;<code>--check</code> 只看有没有新版本</td></tr><tr><td><code>req versions</code></td><td>已安装的版本和可用的版本</td></tr><tr><td><code>req use <版本></code></td><td>切换到已安装的另一个版本(回滚)</td></tr><tr><td><code>req check</code></td><td>检查安装状态</td></tr><tr><td><code>req notify-test [--type …]</code></td><td>给配置的外部通知(如企业 IM)发一条测试消息</td></tr><tr><td><code>req version</code></td><td>显示版本和安装位置</td></tr></tbody></table><h2 id="流水线启动器" tabindex="-1">流水线启动器 <a class="header-anchor" href="#流水线启动器" aria-label="Permalink to "流水线启动器""></a></h2><p><code>/req</code> 在对话中执行的是 <code>node <安装目录>/bin/start-pipeline.mjs</code>,在 bash、PowerShell、cmd 中写法相同。在 Paseo 对话中运行时,它自动识别当前对话(<code>PASEO_AGENT_ID</code>)和工作目录(<code>PASEO_AGENT_CWD</code>)。</p><table tabindex="0"><thead><tr><th>选项</th><th>作用</th></tr></thead><tbody><tr><td><code>--feature <功能目录></code></td><td>要操作的需求;可以只写名称的一部分</td></tr><tr><td><code>--status</code> / <code>--stop</code> / <code>--list</code></td><td>查看进度 / 停止 / 列出需求</td></tr><tr><td><code>--resume</code> / <code>--restart</code></td><td>从中断处继续 / 丢弃结果从零开始</td></tr><tr><td><code>--profile quick|standard</code></td><td>档位;不传时读需求说明中的"档位",再用配置的 <code>defaultProfile</code></td></tr><tr><td><code>--phases continuous|gated|develop-only</code></td><td>执行方式;不传时读需求说明中的"执行方式",再用配置的 <code>phases.mode</code></td></tr><tr><td><code>--approve</code></td><td>方案确认点:需求方确认了方案,继续开发(等待确认时单独的 <code>--resume</code> 会被拒绝;要修改就先更新需求说明再 <code>--resume</code>)</td></tr><tr><td><code>--phase verify</code></td><td>开始(或继续)测试验证阶段;研发完成、待测试时单独的 <code>--resume</code> 效果相同</td></tr><tr><td><code>--verify-env local|deployed</code>、<code>--defects fix|handback|report</code></td><td>开始测试验证时临时指定环境和缺陷处理方式</td></tr><tr><td><code>--verify-at <时间></code></td><td>分阶段时,研发完成后在这个时间自动开始测试验证</td></tr><tr><td><code>--at <时间></code></td><td>预约开始:<code>22:00</code>、<code>明天 8:30</code>、<code>2026-10-14 08:30</code>、<code>+2h</code></td></tr><tr><td><code>--worktree</code></td><td>为这个需求新建 Paseo worktree 工作区并在那里开发(对话目录不变)</td></tr><tr><td><code>--spec-review</code></td><td>确认前请另一个模型独立审阅需求说明草稿</td></tr><tr><td><code>--repo</code>、<code>--origin-agent</code>、<code>--config</code></td><td>仓库目录、发起对话、配置文件(通常不需要写)</td></tr></tbody></table><h2 id="安装脚本" tabindex="-1">安装脚本 <a class="header-anchor" href="#安装脚本" aria-label="Permalink to "安装脚本""></a></h2><table tabindex="0"><thead><tr><th>系统</th><th>命令</th></tr></thead><tbody><tr><td>任何系统(1.13 起)</td><td><code>npx -y paseo-req-kit@latest install</code>;公司内网:<code>npx -y --registry=<镜像地址> paseo-req-kit@latest install</code></td></tr><tr><td>macOS、Linux、Git Bash、WSL</td><td><code>curl -fsSL https://paseo-req-kit.vercel.app/install.sh | sh</code></td></tr><tr><td>Windows PowerShell</td><td><code>irm https://paseo-req-kit.vercel.app/install.ps1 | iex</code></td></tr></tbody></table><p><code>req install</code>(即 <code>npx … install</code>)的选项:<code>--registry <地址></code>(使用并保存这个 npm 源)、<code>--no-save-registry</code>、<code>--no-configure</code>、<code>--skip-paseo</code>、<code>--with-plugin</code>、<code>--no-plugin</code>;版本写在包名后(<code>paseo-req-kit@beta</code>、<code>paseo-req-kit@1.13.0</code>)。</p><p><code>install.sh</code> 的选项写在 <code>sh -s --</code> 之后:<code>--beta</code>、<code>--version <版本></code>、<code>--from npm|release</code>、<code>--registry <地址></code>、<code>--no-save-registry</code>、<code>--no-configure</code>、<code>--skip-paseo</code>(不检查、不安装 Paseo)、<code>--with-plugin</code>(直接安装 Paseo 插件)、<code>--no-plugin</code>。<code>install.ps1</code> 的选项用变量:<code>$ReqKitBeta = $true</code>、<code>$ReqKitVersion = "1.9.1"</code>、<code>$ReqKitFrom = "release"</code>、<code>$ReqKitRegistry = "<地址>"</code>、<code>$ReqKitNoSaveRegistry = $true</code>、<code>$ReqKitNoConfigure = $true</code>、<code>$ReqKitSkipPaseo = $true</code>、<code>$ReqKitPlugin = "yes"</code>(或 <code>"no"</code>)。没有 Paseo 时脚本会安装 Paseo 命令行、开启它的网页界面并启动 daemon。</p>',23)])])}const u=e(c,[["render",a]]);export{p as __pageData,u as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e,o as d,c as o,a3 as r}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"命令","description":"","frontmatter":{},"headers":[],"relativePath":"reference/commands.md","filePath":"reference/commands.md","lastUpdated":1792362729000}'),c={name:"reference/commands.md"};function a(s,t,l,i,n,q){return d(),o("div",null,[...t[0]||(t[0]=[r("",23)])])}const u=e(c,[["render",a]]);export{p as __pageData,u as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{_ as d,o as e,c as o,a3 as a}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"配置项","description":"","frontmatter":{},"headers":[],"relativePath":"reference/config.md","filePath":"reference/config.md","lastUpdated":1792212140000}'),c={name:"reference/config.md"};function r(s,t,i,n,l,h){return e(),o("div",null,[...t[0]||(t[0]=[a(`<h1 id="配置项" tabindex="-1">配置项 <a class="header-anchor" href="#配置项" aria-label="Permalink to "配置项""></a></h1><p>配置分三层,后者覆盖前者:</p><ol><li><strong>本机配置</strong> <code>~/.req-kit/config.json</code>(<code>REQ_KIT_HOME</code> 可以改变目录)——<code>req configure</code> 生成;</li><li><strong>团队配置</strong>:本机配置的 <code>teamConfig</code> 指向的文件,适合放进团队共用的仓库;</li><li><strong>项目配置</strong>:仓库根目录的 <code>.requirement-pipeline.json</code>,只写和本机不同的部分。</li></ol><p><code>daemonUrl</code>、<code>daemonPasswordEnv</code>、<code>teamConfig</code> 只能写在本机配置中;<code>notifiers</code>、<code>integrations</code>、<code>push</code>、<code>factory</code>、<code>people</code> 不能写在项目配置中(会运行命令、推送或发消息)。在 Paseo 插件首页的"配置"中可以看到每一项现在的值和来自哪个文件。写错时,流水线启动前会说明哪一项、为什么。完整的示例见仓库的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/config.example.json" target="_blank" rel="noreferrer">config.example.json</a>。</p><h2 id="agent" tabindex="-1">agent <a class="header-anchor" href="#agent" aria-label="Permalink to "agent""></a></h2><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>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "agents"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "builder"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">"paseoProfile"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"实现"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "reviewer"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">"provider"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"codex/<模型 ID>"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">"modeId"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"full-access"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><table tabindex="0"><thead><tr><th>字段</th><th>说明</th></tr></thead><tbody><tr><td><code>paseoProfile</code></td><td>Paseo 中 agent profile 的名称;写在它旁边的字段优先</td></tr><tr><td><code>provider</code></td><td><code>provider/model</code>,例如 <code>claude/claude-sonnet-5</code>、<code>pi/anthropic/claude-sonnet-5</code></td></tr><tr><td><code>modeId</code></td><td>必须是不会停下来请求批准的模式:Claude Code <code>bypassPermissions</code>、Codex <code>full-access</code>、OpenCode <code>build</code>(加 <code>featureValues: { "auto_accept": true }</code>)、Pi 不写</td></tr><tr><td><code>thinkingOptionId</code>、<code>featureValues</code>、<code>options</code></td><td>原样传给 provider</td></tr></tbody></table><h2 id="流程" tabindex="-1">流程 <a class="header-anchor" href="#流程" aria-label="Permalink to "流程""></a></h2><table tabindex="0"><thead><tr><th>配置</th><th>默认</th><th>说明</th></tr></thead><tbody><tr><td><code>defaultProfile</code></td><td><code>standard</code></td><td>需求说明没写档位时用的档位</td></tr><tr><td><code>profiles.<档位>.rounds</code></td><td>快速 1/1/1,标准 2/3/3</td><td>方案审核、代码评审、缺陷修复的最多轮数</td></tr><tr><td><code>profiles.<档位>.serviceStart</code></td><td>快速 false,标准 true</td><td>是否做服务启动验证</td></tr><tr><td><code>phases</code></td><td>连续</td><td>执行方式和测试阶段的选项,见 <a href="/guide/phases">分阶段执行与提测</a></td></tr><tr><td><code>specReview</code></td><td><code>standard</code></td><td>确认前独立审阅需求说明:<code>standard</code>(标准档)、<code>always</code>、<code>off</code></td></tr><tr><td><code>designProposals</code></td><td>关闭</td><td><code>{"enabled": true}</code>:方案设计前由几个 agent 并行各提一份方案</td></tr><tr><td><code>reviewPanel</code></td><td>关闭</td><td>评审小组:首轮方案审核和代码评审由多位成员并行评审,再由 reviewer 核实汇总</td></tr><tr><td><code>stepTimeoutMinutes.<步骤></code></td><td>20–240 分钟</td><td>每个步骤的总时限</td></tr><tr><td><code>resultFollowUps</code></td><td>2</td><td>结果文件缺失或不合格时提醒补写的次数</td></tr><tr><td><code>retry</code></td><td>2 次,等 60/300 秒</td><td>临时错误(限流、网络)后自动重做这一步</td></tr><tr><td><code>selfHeal</code></td><td><code>true</code></td><td>1.12:超时时 agent 还在做就再等一轮;agent 报错、结果文件无效时新开 agent 重做一次</td></tr><tr><td><code>answerQuestionsFirst</code></td><td><code>true</code></td><td>1.12:方案审核要需求方决定的问题,先由 builder 从代码和文档中自答</td></tr><tr><td><code>agents.fallback</code></td><td>无</td><td>1.12:备用模型,报错重做、限流重试用完时换它做这一步</td></tr></tbody></table><h2 id="质量与范围" tabindex="-1">质量与范围 <a class="header-anchor" href="#质量与范围" aria-label="Permalink to "质量与范围""></a></h2><p>通常写在项目配置 <code>.requirement-pipeline.json</code> 中,见 <a href="/guide/project">项目定制与运行规则</a>。</p><table tabindex="0"><thead><tr><th>配置</th><th>默认</th><th>说明</th></tr></thead><tbody><tr><td><code>checks</code></td><td><code>[]</code></td><td>质量门:流水线自己运行的检查,<code>[{ "name", "command", "cwd"?, "paths"?, "timeoutMinutes"? }]</code>;只拦改动前通过、现在失败的检查</td></tr><tr><td><code>qualityGate.fixAttempts</code></td><td>2</td><td>新失败发回 agent 修复的次数,用完照常继续并写进报告</td></tr><tr><td><code>qualityGate.timeoutMinutes</code></td><td>20</td><td>单项检查的默认时限</td></tr><tr><td><code>slices</code></td><td>标准档,最多 6 片</td><td>按切片实现:<code>profiles</code> 哪些档位,<code>max</code> 最多几片</td></tr><tr><td><code>requirementTypes</code></td><td>缺陷、重构、评估</td><td>哪些需求类型按自己的做法运行;去掉的按新需求处理</td></tr><tr><td><code>relatedRepos</code></td><td><code>[]</code></td><td>只读参考的其他仓库,<code>[{ "name", "path", "role"? }]</code>,<code>path</code> 相对项目目录</td></tr><tr><td><code>designApproval</code></td><td>界面改动,标准档</td><td>方案确认点:<code>mode</code>(<code>ui</code> / <code>always</code> / <code>off</code>)、<code>profiles</code>、<code>autoContinueHours</code>(超时按方案继续,0 一直等)</td></tr><tr><td><code>reviewAxes</code></td><td>开启,标准档</td><td>第一轮代码评审由规格评审和规范评审并行,再汇总:<code>enabled</code>、<code>profiles</code></td></tr></tbody></table><h2 id="paseo-能力" tabindex="-1">Paseo 能力 <a class="header-anchor" href="#paseo-能力" aria-label="Permalink to "Paseo 能力""></a></h2><table tabindex="0"><thead><tr><th>配置</th><th>默认</th><th>说明</th></tr></thead><tbody><tr><td><code>attachToOriginChat</code></td><td><code>true</code></td><td>步骤 agent 作为子 agent 挂在发起的对话下</td></tr><tr><td><code>archiveStepAgents</code></td><td><code>false</code></td><td>步骤完成后归档它的 agent</td></tr><tr><td><code>paseoServices</code></td><td><code>auto</code></td><td>用 <code>paseo.json</code> 中的服务(由 Paseo 启动、分配端口);<code>off</code> 由步骤 agent 自己启动</td></tr><tr><td><code>serviceReadySeconds</code></td><td>120</td><td>等待服务就绪的时间</td></tr><tr><td><code>browserVerify</code></td><td><code>auto</code></td><td>有 Paseo 浏览器工具时,验证步骤在浏览器中实际操作</td></tr><tr><td><code>quotaWarnPercent</code></td><td>85</td><td>开始时额度用到这个比例以上就提醒;0 关闭</td></tr></tbody></table><h2 id="通知与调度" tabindex="-1">通知与调度 <a class="header-anchor" href="#通知与调度" aria-label="Permalink to "通知与调度""></a></h2><table tabindex="0"><thead><tr><th>配置</th><th>默认</th><th>说明</th></tr></thead><tbody><tr><td><code>notifyMilestones</code></td><td><code>true</code></td><td>关键节点(方案确定、开始验证、修复缺陷)在对话里说一句</td></tr><tr><td><code>notifiers</code></td><td><code>[]</code></td><td>外部通知模块(企业 IM 等),见 <a href="/reference/contracts/notifier-event">外部通知事件</a></td></tr><tr><td><code>people</code></td><td><code>{}</code></td><td>1.12:需求方姓名到 IM 账号的对应,按人通知时用;只能写在本机或团队配置中</td></tr><tr><td><code>push.mergeRequest</code></td><td>无</td><td>1.12:推送后用 <code>glab</code> 等命令建草稿合并请求,参数可用 <code>{branch}</code> <code>{target}</code> <code>{title}</code> <code>{description}</code></td></tr><tr><td><code>autoConfirm.hours</code></td><td>0(关闭)</td><td>1.12:快速档、没有待答问题的卡片,过这么久没有异议就开始</td></tr><tr><td><code>waitingReminderHours</code></td><td>24</td><td>等待需求方回答、或研发完成待测试超过这么久,提醒一次;0 关闭</td></tr><tr><td><code>autoResumeMinutes</code> / <code>autoResumeMax</code></td><td>30 / 2</td><td>临时错误中断后自动继续的等待时间和次数;0 关闭</td></tr><tr><td><code>watchdogMinutes</code></td><td>60</td><td>运行期间定时检查,进程意外退出时自动继续;0 关闭(1.12 起默认 60)</td></tr><tr><td><code>maxConcurrentPipelines</code></td><td>0</td><td>本机同时运行的流水线上限,满了排队;0 不限</td></tr><tr><td><code>queuePollSeconds</code></td><td>60</td><td>排队时检查空位的间隔</td></tr></tbody></table><h2 id="本机与团队" tabindex="-1">本机与团队 <a class="header-anchor" href="#本机与团队" aria-label="Permalink to "本机与团队""></a></h2><table tabindex="0"><thead><tr><th>配置</th><th>默认</th><th>说明</th></tr></thead><tbody><tr><td><code>daemonUrl</code></td><td><code>ws://127.0.0.1:6767/ws</code></td><td>Paseo daemon 地址</td></tr><tr><td><code>daemonPasswordEnv</code></td><td><code>PASEO_DAEMON_PASSWORD</code></td><td>存放 daemon 密码的环境变量名</td></tr><tr><td><code>teamConfig</code></td><td><code>null</code></td><td>团队配置文件的路径</td></tr><tr><td><code>requiredVersion</code></td><td><code>null</code></td><td>团队或项目期望的 req-kit 版本范围,例如 <code>">=1.7.0 <2"</code>;只提醒不阻止</td></tr><tr><td><code>waitChunkSeconds</code>、<code>permissionPollSeconds</code></td><td>600、30</td><td>等待步骤 agent 的分段长度、检查权限批准的间隔</td></tr></tbody></table>`,18)])])}const k=d(c,[["render",r]]);export{u as __pageData,k as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as d,o as e,c as o,a3 as a}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"配置项","description":"","frontmatter":{},"headers":[],"relativePath":"reference/config.md","filePath":"reference/config.md","lastUpdated":1792212140000}'),c={name:"reference/config.md"};function r(s,t,i,n,l,h){return e(),o("div",null,[...t[0]||(t[0]=[a("",18)])])}const k=d(c,[["render",r]]);export{u as __pageData,k as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as t,o as d,c as s,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"给程序用的 JSON 输出:req api","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/cli-json.md","filePath":"reference/contracts/cli-json.md","lastUpdated":null}'),u={name:"reference/contracts/cli-json.md"};function i(o,n,a,r,c,p){return d(),s("div",null,[...n[0]||(n[0]=[l("div",null,[l("h1",{id:"给程序用的-json-输出-req-api",tabindex:"-1"},[e("给程序用的 JSON 输出:"),l("code",null,"req api"),e(),l("a",{class:"header-anchor",href:"#给程序用的-json-输出-req-api","aria-label":'Permalink to "给程序用的 JSON 输出:`req api`"'},"")]),l("p",null,[e("1.9.0 起。Paseo 插件和其他程序通过 "),l("code",null,"req api"),e(" 读取需求、执行管理操作,不直接读写状态文件。每个命令输出一行 JSON:")]),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"}},"{ "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"schema"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"1"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"kitVersion"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"1.9.0"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"data"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#B31D28","--shiki-light-font-style":"italic","--shiki-dark":"#FDAEB7","--shiki-dark-font-style":"italic"}},"…"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")])])])]),l("p",null,"出错时退出码为 1:"),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"}},"{ "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"schema"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"1"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"kitVersion"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"1.9.0"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"error"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"code"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"not_found"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"message"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"没有找到需求……"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }")])])])]),l("p",null,[l("code",null,"code"),e(":"),l("code",null,"bad_arguments"),e("(参数不对)、"),l("code",null,"not_found"),e("(目录或需求不存在)、"),l("code",null,"not_allowed"),e("(不允许的文件或命令)、"),l("code",null,"failed"),e("(其他错误)。")]),l("p",null,[l("code",null,"schema"),e(" 只在不兼容的修改时增加;新增字段不改变 "),l("code",null,"schema"),e(",读取方应忽略不认识的字段。")]),l("h2",{id:"命令",tabindex:"-1"},[e("命令 "),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("code",null,"data")])])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"req api version")]),l("td",null,[l("code",null,"{ kitVersion, kitRoot, apiSchema, paseo, featuresDir }"),e(":"),l("code",null,"paseo"),e(" 是这个版本支持的 Paseo 范围")])]),l("tr",null,[l("td",null,[l("code",null,"req api list [--repo <目录>]")]),l("td",null,'这个仓库所有工作区中的需求,数组,每项见下面的"需求"')]),l("tr",null,[l("td",null,[l("code",null,"req api list --all")]),l("td",null,[e("本机记录过的所有需求("),l("a",{href:"./usage-record"},"需求索引"),e("),同上;目录已不在的 "),l("code",null,"present: false")])]),l("tr",null,[l("td",null,[l("code",null,"req api status <需求> [--repo <目录>]")]),l("td",null,'一个需求的详情,见下面的"详情"')]),l("tr",null,[l("td",null,[l("code",null,"req api file <需求> <文件> [--repo <目录>]")]),l("td",null,[l("code",null,"{ featureDir, file, size, truncated, content }"),e(";只能读取功能目录中的文档(见下),最多 512 KB")])]),l("tr",null,[l("td",null,[l("code",null,"req api stats [--since 30d] [--month 2026-10]")]),l("td",null,[l("code",null,"req stats --json"),e(" 的内容,见 "),l("a",{href:"./usage-record"},"使用记录")])]),l("tr",null,[l("td",null,[l("code",null,"req api index [--rebuild <目录>…] [--prune]")]),l("td",null,[e("不带选项:索引的全部条目;"),l("code",null,"--rebuild"),e(":"),l("code",null,"{ scanned, registered, pruned, total }")])]),l("tr",null,[l("td",null,[l("code",null,"req api run <approve|stop|resume|verify|sync|reply> <需求> [--repo <目录>] [选项]")]),l("td",null,[l("code",null,"{ command, featureDir, ok, exitCode, message }"),e("。在 "),l("code",null,"--repo"),e("(默认当前目录)中执行与 "),l("code",null,"req <命令> <需求>"),e(" 完全相同的操作;"),l("code",null,"ok"),e(" 为 false 时退出码为 1")])]),l("tr",null,[l("td",null,[l("code",null,"req api models")]),l("td",null,[e("1.12 起。"),l("code",null,"{ current, choices, recommended }"),e(":本机配置中现在的 "),l("code",null,"agents"),e(";daemon 上能无人值守运行的选择("),l("code",null,"{ id, label, provider, profile }"),e(",Paseo profile 在前);按推荐的 "),l("code",null,"agents"),e("。连不上 daemon 时报错")])]),l("tr",null,[l("td",null,[l("code",null,"req api config [--repo <目录>] [--machine]")]),l("td",null,[e("1.12 起。"),l("code",null,"{ sources, ignored, error, repo, groups }"),e(":"),l("code",null,"sources"),e(" 是生效的配置文件("),l("code",null,"layer"),e(" 为 "),l("code",null,"machine"),e(" / "),l("code",null,"team"),e(" / "),l("code",null,"project"),e(",按叠加顺序);"),l("code",null,"groups"),e(" 按主题分组,每项 "),l("code",null,"{ key, label, description, display, value, setBy, scope, changed }"),e(":"),l("code",null,"display"),e(" 是用大白话写的值,"),l("code",null,"value"),e(" 中看起来像密钥的值和个人账号替换为 "),l("code",null,"••••"),e(","),l("code",null,"setBy"),e(" 是写了它的文件,"),l("code",null,"changed"),e(" 表示与默认值不同。配置有错误时 "),l("code",null,"error"),e(" 写明原因,值按各文件所写。"),l("code",null,"--machine"),e(" 不看项目配置")])]),l("tr",null,[l("td",null,[l("code",null,"req api set-agents --json <设置>")]),l("td",null,[e("1.12 起。"),l("code",null,"{ ok, message }"),e("。"),l("code",null,"<设置>"),e(" 是 "),l("code",null,"{ builder, reviewer, fallback }"),e("("),l("code",null,"fallback"),e(" 可以为 null),检查后写入本机配置的 "),l("code",null,"agents"),e(",原文件备份")])]),l("tr",null,[l("td",null,[l("code",null,"req api review-url <需求> [--repo <目录>] [--read-only]")]),l("td",null,[e("1.13 起。"),l("code",null,"{ url, readOnly }"),e(":这个需求的原型审查页地址(需要时在后台启动审查页的服务)。"),l("code",null,"--read-only"),e(" 的地址只能看,不能提交意见或确认方案。需求不在本机的需求索引中或还没有 "),l("code",null,"prototype/"),e(" 时报 "),l("code",null,"not_found")])])])]),l("p",null,[l("code",null,"<需求>"),e(" 的写法与 "),l("code",null,"req status"),e(" 相同:功能目录、目录名或名称中能唯一确定的一部分。需求在为它新建的工作区中开发时,"),l("code",null,"--repo"),e(" 写对话所在的目录或那个工作区都可以。")]),l("p",null,[l("code",null,"req api file"),e(" 能读取的文件:"),l("code",null,"spec.md"),e("、"),l("code",null,"alignment.md"),e("、"),l("code",null,"spec-review.md"),e("、"),l("code",null,"changes.md"),e("、"),l("code",null,"decisions.tsv"),e("、"),l("code",null,"design.md"),e("、"),l("code",null,"design-review.md"),e("、"),l("code",null,"preview.md"),e("、"),l("code",null,"contract.md"),e("、"),l("code",null,"diagnosis.md"),e("、"),l("code",null,"assessment.md"),e("、"),l("code",null,"implementation.md"),e("、"),l("code",null,"progress.md"),e("、"),l("code",null,"code-review.md"),e("、"),l("code",null,"handoff.md"),e("、"),l("code",null,"service-start.md"),e("、"),l("code",null,"verification.md"),e("、"),l("code",null,"report.md"),e("、"),l("code",null,"acceptance.md"),e("、"),l("code",null,"lessons.tsv"),e("。")]),l("h2",{id:"需求-list-的每一项",tabindex:"-1"},[e("需求("),l("code",null,"list"),e(" 的每一项) "),l("a",{class:"header-anchor",href:"#需求-list-的每一项","aria-label":'Permalink to "需求(`list` 的每一项)"'},"")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"字段"),l("th",null,"含义")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"key")]),l("td",null,"需求在本机的标识(对话所在目录 + 功能目录)")]),l("tr",null,[l("td",null,[l("code",null,"project")]),l("td",null,"项目名:对话所在目录的目录名")]),l("tr",null,[l("td",null,[l("code",null,"repo")]),l("td",null,"需求所在的目录(有自己的工作区时是那个工作区)")]),l("tr",null,[l("td",null,[l("code",null,"sourceRepo"),e(" / "),l("code",null,"workspaceId")]),l("td",null,"有自己的工作区时:对话所在的目录、Paseo 工作区 ID;否则 null")]),l("tr",null,[l("td",null,[l("code",null,"featureDir"),e(" / "),l("code",null,"name"),e(" / "),l("code",null,"title")]),l("td",null,"功能目录、目录名、需求标题")]),l("tr",null,[l("td",null,[l("code",null,"type"),e(" / "),l("code",null,"profile"),e(" / "),l("code",null,"branch")]),l("td",null,[e("需求类型("),l("code",null,"defect"),e("、"),l("code",null,"refactor"),e("、"),l("code",null,"assessment"),e(" 或 null)、档位、分支")])]),l("tr",null,[l("td",null,[l("code",null,"stage")]),l("td",null,[e("与 "),l("code",null,"req list"),e(' 相同的阶段说明,如"开发中""等待确认方案""待验收"')])]),l("tr",null,[l("td",null,[l("code",null,"status")]),l("td",null,[e("状态文件的 "),l("code",null,"status"),e(";还没运行过为 null")])]),l("tr",null,[l("td",null,[l("code",null,"running")]),l("td",null,"后台进程是否在运行")]),l("tr",null,[l("td",null,[l("code",null,"phase")]),l("td",null,[l("code",null,"develop"),e(" / "),l("code",null,"verify")])]),l("tr",null,[l("td",null,[l("code",null,"attention")]),l("td",null,[e("需要人处理的事:"),l("code",null,"approval"),e("(确认方案)、"),l("code",null,"business"),e("(需求方决定)、"),l("code",null,"interrupted"),e("(中断,可以继续)、"),l("code",null,"not_completed"),e("(结束但未完成);没有为 null")])]),l("tr",null,[l("td",null,[l("code",null,"waiting")]),l("td",null,[e("1.12 起。"),l("code",null,"attention"),e(" 不为 null 时:"),l("code",null,"since"),e("(从什么时候开始等)、"),l("code",null,"questions"),e("(需求方要回答的问题)、"),l("code",null,"reason"),e("(停止原因)、"),l("code",null,"card"),e("("),l("code",null,"{ system, id, url, requester }"),e(",从卡片开始的需求)、"),l("code",null,"canReply"),e("(能否用 "),l("code",null,"req api run reply <需求> <回复>"),e(" 把回复转给需求的对话);否则为 null")])]),l("tr",null,[l("td",null,[l("code",null,"current")]),l("td",null,[e("正在运行的步骤 "),l("code",null,"[{ key, title, agentId }]")])]),l("tr",null,[l("td",null,[l("code",null,"updatedAt")]),l("td",null,"最近一次变化的时间")]),l("tr",null,[l("td",null,[l("code",null,"usage")]),l("td",null,[l("code",null,"{ steps, agentMinutes, inputTokens, outputTokens, costUsd }"),e(";没运行过为 null")])]),l("tr",null,[l("td",null,[l("code",null,"present")]),l("td",null,"目录是否还在")]),l("tr",null,[l("td",null,[l("code",null,"hasPrototype")]),l("td",null,[e("1.13 起。功能目录中有界面原型("),l("code",null,"prototype/"),e("),可以用原型审查页查看")])])])]),l("h2",{id:"详情-status",tabindex:"-1"},[e("详情("),l("code",null,"status"),e(") "),l("a",{class:"header-anchor",href:"#详情-status","aria-label":'Permalink to "详情(`status`)"'},"")]),l("p",null,'"需求"的全部字段,另加:'),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"字段"),l("th",null,"含义")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"files")]),l("td",null,[e("功能目录中存在的、可以用 "),l("code",null,"req api file"),e(" 读取的文件")])]),l("tr",null,[l("td",null,[l("code",null,"run")]),l("td",null,[l("code",null,"{ attempt, startedAt, updatedAt, pid, phaseMode, stopReason, outcome, queuedSince, verifyAt, approval, originAgentId }"),e(";没运行过为 null")])]),l("tr",null,[l("td",null,[l("code",null,"steps")]),l("td",null,[e("每个步骤一项:"),l("code",null,"{ key, stepId, title, phase, attempt, round, agentId, startedAt, endedAt, minutes, outcome, result, error, usage }"),e(";"),l("code",null,"title"),e(' 是给人看的名称(如"代码评审(第 2 轮)"),'),l("code",null,"result"),e(' 是结论的文字(如"需要修改")')])]),l("tr",null,[l("td",null,[l("code",null,"gate")]),l("td",null,[e("质量门:状态文件中的 "),l("code",null,"gate")])]),l("tr",null,[l("td",null,[l("code",null,"joint")]),l("td",null,[e("联合需求的其他仓库:"),l("code",null,"[{ name, slug, repo, sourceRepo, branch, workspaceId, gate }]")])]),l("tr",null,[l("td",null,[l("code",null,"external")]),l("td",null,[e("外部系统中的卡片(1.9.0 起):"),l("code",null,"[{ name, id, url, status, syncedAt, pending, lastError }]"),e(";"),l("code",null,"pending"),e(" 是等待补发的调用数")])])])])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/cli-json.md"},"contracts/cli-json.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/cli-json.md"},"在 GitHub 上编辑")],-1)])])}const g=t(u,[["render",i]]);export{k as __pageData,g as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as t,o as d,c as s,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"给程序用的 JSON 输出:req api","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/cli-json.md","filePath":"reference/contracts/cli-json.md","lastUpdated":null}'),u={name:"reference/contracts/cli-json.md"};function i(o,n,a,r,c,p){return d(),s("div",null,[...n[0]||(n[0]=[l("div",null,[l("h1",{id:"给程序用的-json-输出-req-api",tabindex:"-1"},[e("给程序用的 JSON 输出:"),l("code",null,"req api"),e(),l("a",{class:"header-anchor",href:"#给程序用的-json-输出-req-api","aria-label":'Permalink to "给程序用的 JSON 输出:`req api`"'},"")]),l("p",null,[e("1.9.0 起。Paseo 插件和其他程序通过 "),l("code",null,"req api"),e(" 读取需求、执行管理操作,不直接读写状态文件。每个命令输出一行 JSON:")]),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"}},"{ "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"schema"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"1"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"kitVersion"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"1.9.0"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"data"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#B31D28","--shiki-light-font-style":"italic","--shiki-dark":"#FDAEB7","--shiki-dark-font-style":"italic"}},"…"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")])])])]),l("p",null,"出错时退出码为 1:"),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"}},"{ "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"schema"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"1"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"kitVersion"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"1.9.0"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"error"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"code"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"not_found"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"message"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"没有找到需求……"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }")])])])]),l("p",null,[l("code",null,"code"),e(":"),l("code",null,"bad_arguments"),e("(参数不对)、"),l("code",null,"not_found"),e("(目录或需求不存在)、"),l("code",null,"not_allowed"),e("(不允许的文件或命令)、"),l("code",null,"failed"),e("(其他错误)。")]),l("p",null,[l("code",null,"schema"),e(" 只在不兼容的修改时增加;新增字段不改变 "),l("code",null,"schema"),e(",读取方应忽略不认识的字段。")]),l("h2",{id:"命令",tabindex:"-1"},[e("命令 "),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("code",null,"data")])])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"req api version")]),l("td",null,[l("code",null,"{ kitVersion, kitRoot, apiSchema, paseo, featuresDir }"),e(":"),l("code",null,"paseo"),e(" 是这个版本支持的 Paseo 范围")])]),l("tr",null,[l("td",null,[l("code",null,"req api list [--repo <目录>]")]),l("td",null,'这个仓库所有工作区中的需求,数组,每项见下面的"需求"')]),l("tr",null,[l("td",null,[l("code",null,"req api list --all")]),l("td",null,[e("本机记录过的所有需求("),l("a",{href:"./usage-record"},"需求索引"),e("),同上;目录已不在的 "),l("code",null,"present: false")])]),l("tr",null,[l("td",null,[l("code",null,"req api status <需求> [--repo <目录>]")]),l("td",null,'一个需求的详情,见下面的"详情"')]),l("tr",null,[l("td",null,[l("code",null,"req api file <需求> <文件> [--repo <目录>]")]),l("td",null,[l("code",null,"{ featureDir, file, size, truncated, content }"),e(";只能读取功能目录中的文档(见下),最多 512 KB")])]),l("tr",null,[l("td",null,[l("code",null,"req api stats [--since 30d] [--month 2026-10]")]),l("td",null,[l("code",null,"req stats --json"),e(" 的内容,见 "),l("a",{href:"./usage-record"},"使用记录")])]),l("tr",null,[l("td",null,[l("code",null,"req api index [--rebuild <目录>…] [--prune]")]),l("td",null,[e("不带选项:索引的全部条目;"),l("code",null,"--rebuild"),e(":"),l("code",null,"{ scanned, registered, pruned, total }")])]),l("tr",null,[l("td",null,[l("code",null,"req api run <approve|stop|resume|verify|sync|reply> <需求> [--repo <目录>] [选项]")]),l("td",null,[l("code",null,"{ command, featureDir, ok, exitCode, message }"),e("。在 "),l("code",null,"--repo"),e("(默认当前目录)中执行与 "),l("code",null,"req <命令> <需求>"),e(" 完全相同的操作;"),l("code",null,"ok"),e(" 为 false 时退出码为 1")])]),l("tr",null,[l("td",null,[l("code",null,"req api models")]),l("td",null,[e("1.12 起。"),l("code",null,"{ current, choices, recommended }"),e(":本机配置中现在的 "),l("code",null,"agents"),e(";daemon 上能无人值守运行的选择("),l("code",null,"{ id, label, provider, profile }"),e(",Paseo profile 在前);按推荐的 "),l("code",null,"agents"),e("。连不上 daemon 时报错")])]),l("tr",null,[l("td",null,[l("code",null,"req api config [--repo <目录>] [--machine]")]),l("td",null,[e("1.12 起。"),l("code",null,"{ sources, ignored, error, repo, groups }"),e(":"),l("code",null,"sources"),e(" 是生效的配置文件("),l("code",null,"layer"),e(" 为 "),l("code",null,"machine"),e(" / "),l("code",null,"team"),e(" / "),l("code",null,"project"),e(",按叠加顺序);"),l("code",null,"groups"),e(" 按主题分组,每项 "),l("code",null,"{ key, label, description, display, value, setBy, scope, changed }"),e(":"),l("code",null,"display"),e(" 是用大白话写的值,"),l("code",null,"value"),e(" 中看起来像密钥的值和个人账号替换为 "),l("code",null,"••••"),e(","),l("code",null,"setBy"),e(" 是写了它的文件,"),l("code",null,"changed"),e(" 表示与默认值不同。配置有错误时 "),l("code",null,"error"),e(" 写明原因,值按各文件所写。"),l("code",null,"--machine"),e(" 不看项目配置")])]),l("tr",null,[l("td",null,[l("code",null,"req api set-agents --json <设置>")]),l("td",null,[e("1.12 起。"),l("code",null,"{ ok, message }"),e("。"),l("code",null,"<设置>"),e(" 是 "),l("code",null,"{ builder, reviewer, fallback }"),e("("),l("code",null,"fallback"),e(" 可以为 null),检查后写入本机配置的 "),l("code",null,"agents"),e(",原文件备份")])]),l("tr",null,[l("td",null,[l("code",null,"req api review-url <需求> [--repo <目录>] [--read-only]")]),l("td",null,[e("1.13 起。"),l("code",null,"{ url, readOnly }"),e(":这个需求的原型审查页地址(需要时在后台启动审查页的服务)。"),l("code",null,"--read-only"),e(" 的地址只能看,不能提交意见或确认方案。需求不在本机的需求索引中或还没有 "),l("code",null,"prototype/"),e(" 时报 "),l("code",null,"not_found")])])])]),l("p",null,[l("code",null,"<需求>"),e(" 的写法与 "),l("code",null,"req status"),e(" 相同:功能目录、目录名或名称中能唯一确定的一部分。需求在为它新建的工作区中开发时,"),l("code",null,"--repo"),e(" 写对话所在的目录或那个工作区都可以。")]),l("p",null,[l("code",null,"req api file"),e(" 能读取的文件:"),l("code",null,"spec.md"),e("、"),l("code",null,"alignment.md"),e("、"),l("code",null,"spec-review.md"),e("、"),l("code",null,"changes.md"),e("、"),l("code",null,"decisions.tsv"),e("、"),l("code",null,"design.md"),e("、"),l("code",null,"design-review.md"),e("、"),l("code",null,"preview.md"),e("、"),l("code",null,"contract.md"),e("、"),l("code",null,"diagnosis.md"),e("、"),l("code",null,"assessment.md"),e("、"),l("code",null,"implementation.md"),e("、"),l("code",null,"progress.md"),e("、"),l("code",null,"code-review.md"),e("、"),l("code",null,"handoff.md"),e("、"),l("code",null,"service-start.md"),e("、"),l("code",null,"verification.md"),e("、"),l("code",null,"report.md"),e("、"),l("code",null,"acceptance.md"),e("、"),l("code",null,"lessons.tsv"),e("。")]),l("h2",{id:"需求-list-的每一项",tabindex:"-1"},[e("需求("),l("code",null,"list"),e(" 的每一项) "),l("a",{class:"header-anchor",href:"#需求-list-的每一项","aria-label":'Permalink to "需求(`list` 的每一项)"'},"")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"字段"),l("th",null,"含义")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"key")]),l("td",null,"需求在本机的标识(对话所在目录 + 功能目录)")]),l("tr",null,[l("td",null,[l("code",null,"project")]),l("td",null,"项目名:对话所在目录的目录名")]),l("tr",null,[l("td",null,[l("code",null,"repo")]),l("td",null,"需求所在的目录(有自己的工作区时是那个工作区)")]),l("tr",null,[l("td",null,[l("code",null,"sourceRepo"),e(" / "),l("code",null,"workspaceId")]),l("td",null,"有自己的工作区时:对话所在的目录、Paseo 工作区 ID;否则 null")]),l("tr",null,[l("td",null,[l("code",null,"featureDir"),e(" / "),l("code",null,"name"),e(" / "),l("code",null,"title")]),l("td",null,"功能目录、目录名、需求标题")]),l("tr",null,[l("td",null,[l("code",null,"type"),e(" / "),l("code",null,"profile"),e(" / "),l("code",null,"branch")]),l("td",null,[e("需求类型("),l("code",null,"defect"),e("、"),l("code",null,"refactor"),e("、"),l("code",null,"assessment"),e(" 或 null)、档位、分支")])]),l("tr",null,[l("td",null,[l("code",null,"stage")]),l("td",null,[e("与 "),l("code",null,"req list"),e(' 相同的阶段说明,如"开发中""等待确认方案""待验收"')])]),l("tr",null,[l("td",null,[l("code",null,"status")]),l("td",null,[e("状态文件的 "),l("code",null,"status"),e(";还没运行过为 null")])]),l("tr",null,[l("td",null,[l("code",null,"running")]),l("td",null,"后台进程是否在运行")]),l("tr",null,[l("td",null,[l("code",null,"phase")]),l("td",null,[l("code",null,"develop"),e(" / "),l("code",null,"verify")])]),l("tr",null,[l("td",null,[l("code",null,"attention")]),l("td",null,[e("需要人处理的事:"),l("code",null,"approval"),e("(确认方案)、"),l("code",null,"business"),e("(需求方决定)、"),l("code",null,"interrupted"),e("(中断,可以继续)、"),l("code",null,"not_completed"),e("(结束但未完成);没有为 null")])]),l("tr",null,[l("td",null,[l("code",null,"waiting")]),l("td",null,[e("1.12 起。"),l("code",null,"attention"),e(" 不为 null 时:"),l("code",null,"since"),e("(从什么时候开始等)、"),l("code",null,"questions"),e("(需求方要回答的问题)、"),l("code",null,"reason"),e("(停止原因)、"),l("code",null,"card"),e("("),l("code",null,"{ system, id, url, requester }"),e(",从卡片开始的需求)、"),l("code",null,"canReply"),e("(能否用 "),l("code",null,"req api run reply <需求> <回复>"),e(" 把回复转给需求的对话);否则为 null")])]),l("tr",null,[l("td",null,[l("code",null,"current")]),l("td",null,[e("正在运行的步骤 "),l("code",null,"[{ key, title, agentId }]")])]),l("tr",null,[l("td",null,[l("code",null,"updatedAt")]),l("td",null,"最近一次变化的时间")]),l("tr",null,[l("td",null,[l("code",null,"usage")]),l("td",null,[l("code",null,"{ steps, agentMinutes, inputTokens, outputTokens, costUsd }"),e(";没运行过为 null")])]),l("tr",null,[l("td",null,[l("code",null,"present")]),l("td",null,"目录是否还在")]),l("tr",null,[l("td",null,[l("code",null,"hasPrototype")]),l("td",null,[e("1.13 起。功能目录中有界面原型("),l("code",null,"prototype/"),e("),可以用原型审查页查看")])])])]),l("h2",{id:"详情-status",tabindex:"-1"},[e("详情("),l("code",null,"status"),e(") "),l("a",{class:"header-anchor",href:"#详情-status","aria-label":'Permalink to "详情(`status`)"'},"")]),l("p",null,'"需求"的全部字段,另加:'),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"字段"),l("th",null,"含义")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"files")]),l("td",null,[e("功能目录中存在的、可以用 "),l("code",null,"req api file"),e(" 读取的文件")])]),l("tr",null,[l("td",null,[l("code",null,"run")]),l("td",null,[l("code",null,"{ attempt, startedAt, updatedAt, pid, phaseMode, stopReason, outcome, queuedSince, verifyAt, approval, originAgentId }"),e(";没运行过为 null")])]),l("tr",null,[l("td",null,[l("code",null,"steps")]),l("td",null,[e("每个步骤一项:"),l("code",null,"{ key, stepId, title, phase, attempt, round, agentId, startedAt, endedAt, minutes, outcome, result, error, usage }"),e(";"),l("code",null,"title"),e(' 是给人看的名称(如"代码评审(第 2 轮)"),'),l("code",null,"result"),e(' 是结论的文字(如"需要修改")')])]),l("tr",null,[l("td",null,[l("code",null,"gate")]),l("td",null,[e("质量门:状态文件中的 "),l("code",null,"gate")])]),l("tr",null,[l("td",null,[l("code",null,"joint")]),l("td",null,[e("联合需求的其他仓库:"),l("code",null,"[{ name, slug, repo, sourceRepo, branch, workspaceId, gate }]")])]),l("tr",null,[l("td",null,[l("code",null,"external")]),l("td",null,[e("外部系统中的卡片(1.9.0 起):"),l("code",null,"[{ name, id, url, status, syncedAt, pending, lastError }]"),e(";"),l("code",null,"pending"),e(" 是等待补发的调用数")])])])])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/cli-json.md"},"contracts/cli-json.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/cli-json.md"},"在 GitHub 上编辑")],-1)])])}const g=t(u,[["render",i]]);export{k as __pageData,g as default};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import{_ as i,o as n,c as a,j as l,a as s}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"功能目录中由人和 /req 维护的文件","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/feature-files.md","filePath":"reference/contracts/feature-files.md","lastUpdated":null}'),t={name:"reference/contracts/feature-files.md"};function d(r,e,h,c,o,u){return n(),a("div",null,[...e[0]||(e[0]=[l("div",null,[l("h1",{id:"功能目录中由人和-req-维护的文件",tabindex:"-1"},[s("功能目录中由人和 /req 维护的文件 "),l("a",{class:"header-anchor",href:"#功能目录中由人和-req-维护的文件","aria-label":'Permalink to "功能目录中由人和 /req 维护的文件"'},"")]),l("p",null,[s("除 spec.md(见 "),l("a",{href:"./spec"},"spec.md"),s(")外,功能目录 "),l("code",null,"docs/features/<日期>-<名称>/"),s(" 中还有以下约定格式的文件。")]),l("h2",{id:"decisions-tsv",tabindex:"-1"},[s("decisions.tsv "),l("a",{class:"header-anchor",href:"#decisions-tsv","aria-label":'Permalink to "decisions.tsv"'},"")]),l("p",null,"决策记录,由流水线各步骤追加。制表符分隔,UTF-8,第一行为表头:"),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,"time step ref decision alternatives reason kind needs_human")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"列"),l("th",null,"内容")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"time")]),l("td",null,[l("code",null,"YYYY-MM-DD HH:MM")])]),l("tr",null,[l("td",null,[l("code",null,"step")]),l("td",null,[s("步骤名和轮次,如 "),l("code",null,"代码评审 第2轮")])]),l("tr",null,[l("td",null,[l("code",null,"ref")]),l("td",null,[s("相关的 FR / AC / CR 编号或文件,没有写 "),l("code",null,"-")])]),l("tr",null,[l("td",null,[l("code",null,"decision"),s(" / "),l("code",null,"alternatives"),s(" / "),l("code",null,"reason")]),l("td",null,"各一句话,不含换行和制表符")]),l("tr",null,[l("td",null,[l("code",null,"kind")]),l("td",null,[l("code",null,"假设"),s(" / "),l("code",null,"取舍"),s(" / "),l("code",null,"偏离方案"),s(" / "),l("code",null,"驳回意见"),s(" / "),l("code",null,"不修复")])]),l("tr",null,[l("td",null,[l("code",null,"needs_human")]),l("td",null,[l("code",null,"yes"),s(" / "),l("code",null,"no"),s("。"),l("code",null,"yes"),s(' 的行会被完成报告列入"需要你确认的决定"')])])])]),l("h2",{id:"changes-md",tabindex:"-1"},[s("changes.md "),l("a",{class:"header-anchor",href:"#changes-md","aria-label":'Permalink to "changes.md"'},"")]),l("p",null,[s("需求变更记录,由 "),l("code",null,"/req"),s(' 的"修改需求"手册追加,每次修改一节,新的在后:')]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),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":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 第 2 版(2026-10-14)")]),s(`
|
|
2
|
+
`),l("span",{class:"line"}),s(`
|
|
3
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 变更内容:<改了哪些 FR / AC,新增或删除了什么>")]),s(`
|
|
4
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 原因:<需求方给出的原因>")]),s(`
|
|
5
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 对进度的影响:<流水线当时的状态;继续后从方案设计重新开始 / 尚未开始开发>")]),s(`
|
|
6
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 提出人:<姓名或角色>")])])])]),l("p",null,'spec.md 头部的"版本"与最新一节一致。'),l("h2",{id:"handoff-md-提测说明",tabindex:"-1"},[s("handoff.md(提测说明) "),l("a",{class:"header-anchor",href:"#handoff-md-提测说明","aria-label":'Permalink to "handoff.md(提测说明)"'},"")]),l("p",null,'1.7.0 起由流水线研发阶段的最后一步("提测说明")写入并提交。分阶段执行时它是交给测试的单据,连续执行时是功能验证的输入,"只做研发"时是人工测试的依据。六节:这次改了什么(按 FR,附分支和提交范围)、怎么跑起来、自测结果、建议重点测试、已知问题和未完成项、测试需要的准备(只写在哪里取,不写口令)。测试退回后修复时追加"第 N 次提测"一节。'),l("h2",{id:"test-env-md-测试环境说明",tabindex:"-1"},[s("test-env.md(测试环境说明) "),l("a",{class:"header-anchor",href:"#test-env-md-测试环境说明","aria-label":'Permalink to "test-env.md(测试环境说明)"'},"")]),l("p",null,[s("1.7.0 起。在已部署的测试环境中做测试验证("),l("code",null,"--verify-env deployed"),s(" 或配置 "),l("code",null,"phases.verify.environment"),s(")时必须有,由 "),l("code",null,"/req"),s(' 的"开始测试验证"手册和用户一起写。流水线只使用其中列出的环境、账号和数据:')]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),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":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# 测试环境:<需求名称>")]),s(`
|
|
7
|
+
`),l("span",{class:"line"}),s(`
|
|
8
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 地址:https://<测试环境地址>")]),s(`
|
|
9
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 被测版本怎么确认:<版本号接口 / 页面底部的提交号 / 部署平台上的记录>")]),s(`
|
|
10
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 账号:<测试账号>,口令在 <环境变量 TEST_PASSWORD / 本机文件 ~/.config/xxx>(不写口令本身)")]),s(`
|
|
11
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 可以使用的测试数据:<数据范围、可以新建和删除的数据>")]),s(`
|
|
12
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 不能碰的:<共享数据、会触发外部通知的操作等>")]),s(`
|
|
13
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 清理方式:<测试数据如何清理>")])])])]),l("p",null,"只能是测试用途的环境;不写任何生产环境的地址和凭据。"),l("h2",{id:"changes-md-中的-测试验证退回",tabindex:"-1"},[s('changes.md 中的"测试验证退回" '),l("a",{class:"header-anchor",href:"#changes-md-中的-测试验证退回","aria-label":'Permalink to "changes.md 中的"测试验证退回""'},"")]),l("p",null,[s("1.7.0 起,测试验证按 "),l("code",null,"defects: handback"),s(" 把缺陷退回研发阶段时,流水线在 "),l("code",null,"changes.md"),s(' 末尾追加一节"<日期> 测试验证退回(第 N 次)",来源为"测试验证",缺陷清单在 '),l("code",null,"verification.md"),s(" 最后一轮。研发阶段随后从方案设计开始只处理这些缺陷。")]),l("h2",{id:"preview-md-与-prototype-给需求方确认的预览",tabindex:"-1"},[s("preview.md 与 prototype/(给需求方确认的预览) "),l("a",{class:"header-anchor",href:"#preview-md-与-prototype-给需求方确认的预览","aria-label":'Permalink to "preview.md 与 prototype/(给需求方确认的预览)"'},"")]),l("p",null,[s("1.8.0 起,方案确认点开启时("),l("code",null,"designApproval"),s(",默认标准档的界面改动)由方案设计写入,方案修订时同步更新。"),l("code",null,"preview.md"),s(" 五节:做完后你会看到什么(按操作顺序,注明 AC)、界面原型(列出 "),l("code",null,"prototype/"),s(" 中的文件和对应的状态)、接口示例(改接口时)、需要你确认的假设(影响界面、数据、权限的)、不会变的。"),l("code",null,"prototype/"),s(" 中是静态 HTML 页面,只用内联的 HTML 和 CSS,不引用外部文件、不连接服务,只用于确认,不是产品代码。需求方确认后,实现和功能验证都以它们为准。")]),l("h2",{id:"diagnosis-md、assessment-md",tabindex:"-1"},[s("diagnosis.md、assessment.md "),l("a",{class:"header-anchor",href:"#diagnosis-md、assessment-md","aria-label":'Permalink to "diagnosis.md、assessment.md"'},"")]),l("p",null,[s('1.8.0 起。缺陷类型的"复现与定位"写 '),l("code",null,"diagnosis.md"),s(':现象与复现(复现测试或脚本的位置、命令、修复前的失败输出)、根因(带代码位置)、排除的其他原因、影响面、修复思路。评估类型的"调研评估"写 '),l("code",null,"assessment.md"),s("(代替 "),l("code",null,"design.md"),s("):结论摘要、现状、可选方案(含工作量的大小和主要工作项)、推荐、风险与未知、如果要做(需求草稿)。")]),l("h2",{id:"card-json-外部系统的卡片字段",tabindex:"-1"},[s("card.json(外部系统的卡片字段) "),l("a",{class:"header-anchor",href:"#card-json-外部系统的卡片字段","aria-label":'Permalink to "card.json(外部系统的卡片字段)"'},"")]),l("p",null,[s("1.9.0 起。团队配置了外部系统对接("),l("code",null,"integrations"),s(")、且其中写了 "),l("code",null,"cardFields"),s(" 时,由 "),l("code",null,"/req"),s(" 在需求说明确认时和需求方一起确认后写入,与 "),l("code",null,"spec.md"),s(" 一起提交:")]),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"}},"{ "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"title"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"<卡片标题,可省略,默认用需求说明的标题>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"body"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"<卡片描述,可省略,默认用 spec.md 全文>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"fields"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"<字段>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"<值>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }")])])])]),l("p",null,[l("code",null,"fields"),s(" 的名称来自 "),l("code",null,"cardFields"),s(",在命令参数中写作 "),l("code",null,"{card.<字段>}"),s("。没有写的字段用 "),l("code",null,"defaults"),s(" / "),l("code",null,"integrationDefaults"),s(" 中同名的值,都没有时这个参数和它前面的选项一起省略。")]),l("h2",{id:"source-json、card-source-md、card-ai-md-从卡片开始的需求",tabindex:"-1"},[s("source.json、card-source.md、card-ai.md(从卡片开始的需求) "),l("a",{class:"header-anchor",href:"#source-json、card-source-md、card-ai-md-从卡片开始的需求","aria-label":'Permalink to "source.json、card-source.md、card-ai.md(从卡片开始的需求)"'},"")]),l("p",null,[s("1.10.0 起。用 "),l("code",null,"req start --from <系统>:<卡号>"),s(" 从卡片开始的需求才有。")]),l("p",null,[l("code",null,"source.json"),s(" 由引擎维护:")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"字段"),l("th",null,"含义")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"v")]),l("td",null,"格式版本,1")]),l("tr",null,[l("td",null,[l("code",null,"system"),s("、"),l("code",null,"id"),s("、"),l("code",null,"url")]),l("td",null,"对接配置中的系统名称、卡号、链接(没有时为 null)")]),l("tr",null,[l("td",null,[l("code",null,"title"),s("、"),l("code",null,"author"),s("、"),l("code",null,"subsystem"),s("、"),l("code",null,"state")]),l("td",null,"卡片的标题、提出人、子系统、状态(最近一次读取时)")]),l("tr",null,[l("td",null,[l("code",null,"fetchedAt")]),l("td",null,"开始时读取卡片的时间")]),l("tr",null,[l("td",null,[l("code",null,"sourceRepo")]),l("td",null,"需求开始时所在的仓库(流水线之后可能把它移到自己的工作区)")]),l("tr",null,[l("td",null,[l("code",null,"sessionAgentId")]),l("td",null,"需求会话的 agent ID")]),l("tr",null,[l("td",null,[l("code",null,"originalHash"),s("、"),l("code",null,"replyHash")]),l("td",null,"最近一次转给需求会话时,需求方的描述和回复的摘要;用来判断有没有新内容")]),l("tr",null,[l("td",null,[l("code",null,"confirmedAt"),s("、"),l("code",null,"planConfirmedAt")]),l("td",null,'需求方的"确认:同意""方案确认:同意"转给需求会话的时间')]),l("tr",null,[l("td",null,[l("code",null,"progress"),s("、"),l("code",null,"publishedAt")]),l("td",null,"AI 区中的进度和最近一次写入卡片的时间")])])]),l("p",null,[l("code",null,"card-source.md"),s(" 是卡片的副本(标题、卡号、状态、提出人、子系统,需求方的描述放在 "),l("code",null,"<card-description>"),s(" 中),由引擎在开始时和需求方修改描述后写入。"),l("code",null,"card-ai.md"),s(" 由需求会话写,是卡片 AI 区的正文(Markdown;问题用 "),l("code",null,"- Q1"),s("、"),l("code",null,"- Q2"),s(" 编号),"),l("code",null,"req card publish"),s(" 把它写进卡片。")]),l("h2",{id:"contract-md-联合需求的接口约定",tabindex:"-1"},[s("contract.md(联合需求的接口约定) "),l("a",{class:"header-anchor",href:"#contract-md-联合需求的接口约定","aria-label":'Permalink to "contract.md(联合需求的接口约定)"'},"")]),l("p",null,[s("1.8.0 起,联合需求(spec 的 "),l("code",null,"- 联合开发:"),s(")的方案设计在主仓库写入:每个接口一节,路径和方法、请求字段(类型、是否必填、取值范围)、响应字段、错误码和提示、一两组真实的请求和响应示例。方案审核通过后冻结,各仓库按它同时开发:提供接口的一边用示例写接口测试,调用的一边用示例做测试替身。主仓库的需求说明、访谈记录、方案、接口约定和预览在实现前同步到其他仓库工作区的同名功能目录并提交;其他仓库的实现、评审和缺陷处理记录写在它们自己的功能目录中。")]),l("h2",{id:"lessons-tsv-可以变成规则的问题",tabindex:"-1"},[s("lessons.tsv(可以变成规则的问题) "),l("a",{class:"header-anchor",href:"#lessons-tsv-可以变成规则的问题","aria-label":'Permalink to "lessons.tsv(可以变成规则的问题)"'},"")]),l("p",null,"1.8.0 起,完成报告从评审意见、质量门和缺陷中挑出一条项目规则就能挡住的问题写入,没有就不写。制表符分隔,UTF-8,第一行为表头:"),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,"category finding source rule layer")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"列"),l("th",null,"内容")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"category")]),l("td",null,'问题的类别,两到六个字,如"SQL 拼接"。同类问题在各个需求中沿用同一个名字')]),l("tr",null,[l("td",null,[l("code",null,"finding")]),l("td",null,"这次的问题,一句话")]),l("tr",null,[l("td",null,[l("code",null,"source")]),l("td",null,[s("出处,如 "),l("code",null,"CR-3"),s("、"),l("code",null,"缺陷 D-2"),s("、"),l("code",null,"质量门 lint")])]),l("tr",null,[l("td",null,[l("code",null,"rule")]),l("td",null,"建议的规则,一句话")]),l("tr",null,[l("td",null,[l("code",null,"layer")]),l("td",null,[l("code",null,"lint"),s(" / "),l("code",null,"类型"),s(" / "),l("code",null,"测试"),s(" / "),l("code",null,"项目说明")])])])]),l("p",null,[l("code",null,"req digest"),s(' 把在两个以上需求中出现的类别列为"反复出现的问题"。已经变成规则(或决定不做)的类别写在仓库的 '),l("code",null,".requirement-pipeline/lessons-handled.txt"),s(" 中,一行一个,"),l("code",null,"#"),s(" 之后是注释,总览不再提示它们。")]),l("h2",{id:"acceptance-md",tabindex:"-1"},[s("acceptance.md "),l("a",{class:"header-anchor",href:"#acceptance-md","aria-label":'Permalink to "acceptance.md"'},"")]),l("p",null,[s("验收记录,由 "),l("code",null,"/req"),s(' 的"验收"手册写。验收标准本身只在 spec.md 中维护,这里只记录结果:')]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),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":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# 验收记录:<需求名称>")]),s(`
|
|
14
|
+
`),l("span",{class:"line"}),s(`
|
|
15
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 验收结论:通过(2026-10-15) / 不通过(2026-10-15) / 进行中")]),s(`
|
|
16
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 验收人:<姓名或角色>")]),s(`
|
|
17
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 对照的需求版本:2")]),s(`
|
|
18
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 对照的报告:report.md(流水线结论:已完成,可以验收)")]),s(`
|
|
19
|
+
`),l("span",{class:"line"}),s(`
|
|
20
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"| AC | 结果 | 怎么验证的 | 备注 |")]),s(`
|
|
21
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"| --- | --- | --- | --- |")]),s(`
|
|
22
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"| AC-1.1 | 通过 / 不通过 / 未验 | <亲自操作 / 执行的命令> | <现象、截图路径> |")]),s(`
|
|
23
|
+
`),l("span",{class:"line"}),s(`
|
|
24
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 不通过的处理")]),s(`
|
|
25
|
+
`),l("span",{class:"line"}),s(`
|
|
26
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," AC-2.3:<现象> → 作为缺陷处理 / 作为需求修改 / 接受现状(理由)")])])])]),l("p",null,[l("code",null,"start-pipeline --list"),s(' 读取"验收结论"一行来显示"已验收"或"验收未通过"。')]),l("h2",{id:"需求总览",tabindex:"-1"},[s("需求总览 "),l("a",{class:"header-anchor",href:"#需求总览","aria-label":'Permalink to "需求总览"'},"")]),l("p",null,[s("需求总览不是一个提交进仓库的文件。每个需求在自己的工作区和分支上,共用的索引文件会在合并时冲突,所以总览由 "),l("code",null,"start-pipeline --list"),s(" 现场生成:扫描这个仓库所有 worktree 中的 "),l("code",null,"docs/features/*/spec.md"),s("、状态文件和验收记录。")])],-1),l("p",{class:"source-note"},[s("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/feature-files.md"},"contracts/feature-files.md"),s(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/feature-files.md"},"在 GitHub 上编辑")],-1)])])}const g=i(t,[["render",d]]);export{k as __pageData,g as default};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import{_ as i,o as n,c as a,j as l,a as s}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"功能目录中由人和 /req 维护的文件","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/feature-files.md","filePath":"reference/contracts/feature-files.md","lastUpdated":null}'),t={name:"reference/contracts/feature-files.md"};function d(r,e,h,c,o,u){return n(),a("div",null,[...e[0]||(e[0]=[l("div",null,[l("h1",{id:"功能目录中由人和-req-维护的文件",tabindex:"-1"},[s("功能目录中由人和 /req 维护的文件 "),l("a",{class:"header-anchor",href:"#功能目录中由人和-req-维护的文件","aria-label":'Permalink to "功能目录中由人和 /req 维护的文件"'},"")]),l("p",null,[s("除 spec.md(见 "),l("a",{href:"./spec"},"spec.md"),s(")外,功能目录 "),l("code",null,"docs/features/<日期>-<名称>/"),s(" 中还有以下约定格式的文件。")]),l("h2",{id:"decisions-tsv",tabindex:"-1"},[s("decisions.tsv "),l("a",{class:"header-anchor",href:"#decisions-tsv","aria-label":'Permalink to "decisions.tsv"'},"")]),l("p",null,"决策记录,由流水线各步骤追加。制表符分隔,UTF-8,第一行为表头:"),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,"time step ref decision alternatives reason kind needs_human")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"列"),l("th",null,"内容")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"time")]),l("td",null,[l("code",null,"YYYY-MM-DD HH:MM")])]),l("tr",null,[l("td",null,[l("code",null,"step")]),l("td",null,[s("步骤名和轮次,如 "),l("code",null,"代码评审 第2轮")])]),l("tr",null,[l("td",null,[l("code",null,"ref")]),l("td",null,[s("相关的 FR / AC / CR 编号或文件,没有写 "),l("code",null,"-")])]),l("tr",null,[l("td",null,[l("code",null,"decision"),s(" / "),l("code",null,"alternatives"),s(" / "),l("code",null,"reason")]),l("td",null,"各一句话,不含换行和制表符")]),l("tr",null,[l("td",null,[l("code",null,"kind")]),l("td",null,[l("code",null,"假设"),s(" / "),l("code",null,"取舍"),s(" / "),l("code",null,"偏离方案"),s(" / "),l("code",null,"驳回意见"),s(" / "),l("code",null,"不修复")])]),l("tr",null,[l("td",null,[l("code",null,"needs_human")]),l("td",null,[l("code",null,"yes"),s(" / "),l("code",null,"no"),s("。"),l("code",null,"yes"),s(' 的行会被完成报告列入"需要你确认的决定"')])])])]),l("h2",{id:"changes-md",tabindex:"-1"},[s("changes.md "),l("a",{class:"header-anchor",href:"#changes-md","aria-label":'Permalink to "changes.md"'},"")]),l("p",null,[s("需求变更记录,由 "),l("code",null,"/req"),s(' 的"修改需求"手册追加,每次修改一节,新的在后:')]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),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":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 第 2 版(2026-10-14)")]),s(`
|
|
2
|
+
`),l("span",{class:"line"}),s(`
|
|
3
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 变更内容:<改了哪些 FR / AC,新增或删除了什么>")]),s(`
|
|
4
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 原因:<需求方给出的原因>")]),s(`
|
|
5
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 对进度的影响:<流水线当时的状态;继续后从方案设计重新开始 / 尚未开始开发>")]),s(`
|
|
6
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 提出人:<姓名或角色>")])])])]),l("p",null,'spec.md 头部的"版本"与最新一节一致。'),l("h2",{id:"handoff-md-提测说明",tabindex:"-1"},[s("handoff.md(提测说明) "),l("a",{class:"header-anchor",href:"#handoff-md-提测说明","aria-label":'Permalink to "handoff.md(提测说明)"'},"")]),l("p",null,'1.7.0 起由流水线研发阶段的最后一步("提测说明")写入并提交。分阶段执行时它是交给测试的单据,连续执行时是功能验证的输入,"只做研发"时是人工测试的依据。六节:这次改了什么(按 FR,附分支和提交范围)、怎么跑起来、自测结果、建议重点测试、已知问题和未完成项、测试需要的准备(只写在哪里取,不写口令)。测试退回后修复时追加"第 N 次提测"一节。'),l("h2",{id:"test-env-md-测试环境说明",tabindex:"-1"},[s("test-env.md(测试环境说明) "),l("a",{class:"header-anchor",href:"#test-env-md-测试环境说明","aria-label":'Permalink to "test-env.md(测试环境说明)"'},"")]),l("p",null,[s("1.7.0 起。在已部署的测试环境中做测试验证("),l("code",null,"--verify-env deployed"),s(" 或配置 "),l("code",null,"phases.verify.environment"),s(")时必须有,由 "),l("code",null,"/req"),s(' 的"开始测试验证"手册和用户一起写。流水线只使用其中列出的环境、账号和数据:')]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),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":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# 测试环境:<需求名称>")]),s(`
|
|
7
|
+
`),l("span",{class:"line"}),s(`
|
|
8
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 地址:https://<测试环境地址>")]),s(`
|
|
9
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 被测版本怎么确认:<版本号接口 / 页面底部的提交号 / 部署平台上的记录>")]),s(`
|
|
10
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 账号:<测试账号>,口令在 <环境变量 TEST_PASSWORD / 本机文件 ~/.config/xxx>(不写口令本身)")]),s(`
|
|
11
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 可以使用的测试数据:<数据范围、可以新建和删除的数据>")]),s(`
|
|
12
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 不能碰的:<共享数据、会触发外部通知的操作等>")]),s(`
|
|
13
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 清理方式:<测试数据如何清理>")])])])]),l("p",null,"只能是测试用途的环境;不写任何生产环境的地址和凭据。"),l("h2",{id:"changes-md-中的-测试验证退回",tabindex:"-1"},[s('changes.md 中的"测试验证退回" '),l("a",{class:"header-anchor",href:"#changes-md-中的-测试验证退回","aria-label":'Permalink to "changes.md 中的"测试验证退回""'},"")]),l("p",null,[s("1.7.0 起,测试验证按 "),l("code",null,"defects: handback"),s(" 把缺陷退回研发阶段时,流水线在 "),l("code",null,"changes.md"),s(' 末尾追加一节"<日期> 测试验证退回(第 N 次)",来源为"测试验证",缺陷清单在 '),l("code",null,"verification.md"),s(" 最后一轮。研发阶段随后从方案设计开始只处理这些缺陷。")]),l("h2",{id:"preview-md-与-prototype-给需求方确认的预览",tabindex:"-1"},[s("preview.md 与 prototype/(给需求方确认的预览) "),l("a",{class:"header-anchor",href:"#preview-md-与-prototype-给需求方确认的预览","aria-label":'Permalink to "preview.md 与 prototype/(给需求方确认的预览)"'},"")]),l("p",null,[s("1.8.0 起,方案确认点开启时("),l("code",null,"designApproval"),s(",默认标准档的界面改动)由方案设计写入,方案修订时同步更新。"),l("code",null,"preview.md"),s(" 五节:做完后你会看到什么(按操作顺序,注明 AC)、界面原型(列出 "),l("code",null,"prototype/"),s(" 中的文件和对应的状态)、接口示例(改接口时)、需要你确认的假设(影响界面、数据、权限的)、不会变的。"),l("code",null,"prototype/"),s(" 中是静态 HTML 页面,只用内联的 HTML 和 CSS,不引用外部文件、不连接服务,只用于确认,不是产品代码。需求方确认后,实现和功能验证都以它们为准。")]),l("h2",{id:"diagnosis-md、assessment-md",tabindex:"-1"},[s("diagnosis.md、assessment.md "),l("a",{class:"header-anchor",href:"#diagnosis-md、assessment-md","aria-label":'Permalink to "diagnosis.md、assessment.md"'},"")]),l("p",null,[s('1.8.0 起。缺陷类型的"复现与定位"写 '),l("code",null,"diagnosis.md"),s(':现象与复现(复现测试或脚本的位置、命令、修复前的失败输出)、根因(带代码位置)、排除的其他原因、影响面、修复思路。评估类型的"调研评估"写 '),l("code",null,"assessment.md"),s("(代替 "),l("code",null,"design.md"),s("):结论摘要、现状、可选方案(含工作量的大小和主要工作项)、推荐、风险与未知、如果要做(需求草稿)。")]),l("h2",{id:"card-json-外部系统的卡片字段",tabindex:"-1"},[s("card.json(外部系统的卡片字段) "),l("a",{class:"header-anchor",href:"#card-json-外部系统的卡片字段","aria-label":'Permalink to "card.json(外部系统的卡片字段)"'},"")]),l("p",null,[s("1.9.0 起。团队配置了外部系统对接("),l("code",null,"integrations"),s(")、且其中写了 "),l("code",null,"cardFields"),s(" 时,由 "),l("code",null,"/req"),s(" 在需求说明确认时和需求方一起确认后写入,与 "),l("code",null,"spec.md"),s(" 一起提交:")]),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"}},"{ "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"title"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"<卡片标题,可省略,默认用需求说明的标题>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"body"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"<卡片描述,可省略,默认用 spec.md 全文>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"fields"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"<字段>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"<值>"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }")])])])]),l("p",null,[l("code",null,"fields"),s(" 的名称来自 "),l("code",null,"cardFields"),s(",在命令参数中写作 "),l("code",null,"{card.<字段>}"),s("。没有写的字段用 "),l("code",null,"defaults"),s(" / "),l("code",null,"integrationDefaults"),s(" 中同名的值,都没有时这个参数和它前面的选项一起省略。")]),l("h2",{id:"source-json、card-source-md、card-ai-md-从卡片开始的需求",tabindex:"-1"},[s("source.json、card-source.md、card-ai.md(从卡片开始的需求) "),l("a",{class:"header-anchor",href:"#source-json、card-source-md、card-ai-md-从卡片开始的需求","aria-label":'Permalink to "source.json、card-source.md、card-ai.md(从卡片开始的需求)"'},"")]),l("p",null,[s("1.10.0 起。用 "),l("code",null,"req start --from <系统>:<卡号>"),s(" 从卡片开始的需求才有。")]),l("p",null,[l("code",null,"source.json"),s(" 由引擎维护:")]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"字段"),l("th",null,"含义")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"v")]),l("td",null,"格式版本,1")]),l("tr",null,[l("td",null,[l("code",null,"system"),s("、"),l("code",null,"id"),s("、"),l("code",null,"url")]),l("td",null,"对接配置中的系统名称、卡号、链接(没有时为 null)")]),l("tr",null,[l("td",null,[l("code",null,"title"),s("、"),l("code",null,"author"),s("、"),l("code",null,"subsystem"),s("、"),l("code",null,"state")]),l("td",null,"卡片的标题、提出人、子系统、状态(最近一次读取时)")]),l("tr",null,[l("td",null,[l("code",null,"fetchedAt")]),l("td",null,"开始时读取卡片的时间")]),l("tr",null,[l("td",null,[l("code",null,"sourceRepo")]),l("td",null,"需求开始时所在的仓库(流水线之后可能把它移到自己的工作区)")]),l("tr",null,[l("td",null,[l("code",null,"sessionAgentId")]),l("td",null,"需求会话的 agent ID")]),l("tr",null,[l("td",null,[l("code",null,"originalHash"),s("、"),l("code",null,"replyHash")]),l("td",null,"最近一次转给需求会话时,需求方的描述和回复的摘要;用来判断有没有新内容")]),l("tr",null,[l("td",null,[l("code",null,"confirmedAt"),s("、"),l("code",null,"planConfirmedAt")]),l("td",null,'需求方的"确认:同意""方案确认:同意"转给需求会话的时间')]),l("tr",null,[l("td",null,[l("code",null,"progress"),s("、"),l("code",null,"publishedAt")]),l("td",null,"AI 区中的进度和最近一次写入卡片的时间")])])]),l("p",null,[l("code",null,"card-source.md"),s(" 是卡片的副本(标题、卡号、状态、提出人、子系统,需求方的描述放在 "),l("code",null,"<card-description>"),s(" 中),由引擎在开始时和需求方修改描述后写入。"),l("code",null,"card-ai.md"),s(" 由需求会话写,是卡片 AI 区的正文(Markdown;问题用 "),l("code",null,"- Q1"),s("、"),l("code",null,"- Q2"),s(" 编号),"),l("code",null,"req card publish"),s(" 把它写进卡片。")]),l("h2",{id:"contract-md-联合需求的接口约定",tabindex:"-1"},[s("contract.md(联合需求的接口约定) "),l("a",{class:"header-anchor",href:"#contract-md-联合需求的接口约定","aria-label":'Permalink to "contract.md(联合需求的接口约定)"'},"")]),l("p",null,[s("1.8.0 起,联合需求(spec 的 "),l("code",null,"- 联合开发:"),s(")的方案设计在主仓库写入:每个接口一节,路径和方法、请求字段(类型、是否必填、取值范围)、响应字段、错误码和提示、一两组真实的请求和响应示例。方案审核通过后冻结,各仓库按它同时开发:提供接口的一边用示例写接口测试,调用的一边用示例做测试替身。主仓库的需求说明、访谈记录、方案、接口约定和预览在实现前同步到其他仓库工作区的同名功能目录并提交;其他仓库的实现、评审和缺陷处理记录写在它们自己的功能目录中。")]),l("h2",{id:"lessons-tsv-可以变成规则的问题",tabindex:"-1"},[s("lessons.tsv(可以变成规则的问题) "),l("a",{class:"header-anchor",href:"#lessons-tsv-可以变成规则的问题","aria-label":'Permalink to "lessons.tsv(可以变成规则的问题)"'},"")]),l("p",null,"1.8.0 起,完成报告从评审意见、质量门和缺陷中挑出一条项目规则就能挡住的问题写入,没有就不写。制表符分隔,UTF-8,第一行为表头:"),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,"category finding source rule layer")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"列"),l("th",null,"内容")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"category")]),l("td",null,'问题的类别,两到六个字,如"SQL 拼接"。同类问题在各个需求中沿用同一个名字')]),l("tr",null,[l("td",null,[l("code",null,"finding")]),l("td",null,"这次的问题,一句话")]),l("tr",null,[l("td",null,[l("code",null,"source")]),l("td",null,[s("出处,如 "),l("code",null,"CR-3"),s("、"),l("code",null,"缺陷 D-2"),s("、"),l("code",null,"质量门 lint")])]),l("tr",null,[l("td",null,[l("code",null,"rule")]),l("td",null,"建议的规则,一句话")]),l("tr",null,[l("td",null,[l("code",null,"layer")]),l("td",null,[l("code",null,"lint"),s(" / "),l("code",null,"类型"),s(" / "),l("code",null,"测试"),s(" / "),l("code",null,"项目说明")])])])]),l("p",null,[l("code",null,"req digest"),s(' 把在两个以上需求中出现的类别列为"反复出现的问题"。已经变成规则(或决定不做)的类别写在仓库的 '),l("code",null,".requirement-pipeline/lessons-handled.txt"),s(" 中,一行一个,"),l("code",null,"#"),s(" 之后是注释,总览不再提示它们。")]),l("h2",{id:"acceptance-md",tabindex:"-1"},[s("acceptance.md "),l("a",{class:"header-anchor",href:"#acceptance-md","aria-label":'Permalink to "acceptance.md"'},"")]),l("p",null,[s("验收记录,由 "),l("code",null,"/req"),s(' 的"验收"手册写。验收标准本身只在 spec.md 中维护,这里只记录结果:')]),l("div",{class:"language-markdown vp-adaptive-theme"},[l("button",{title:"Copy Code",class:"copy"}),l("span",{class:"lang"},"markdown"),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":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# 验收记录:<需求名称>")]),s(`
|
|
14
|
+
`),l("span",{class:"line"}),s(`
|
|
15
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 验收结论:通过(2026-10-15) / 不通过(2026-10-15) / 进行中")]),s(`
|
|
16
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 验收人:<姓名或角色>")]),s(`
|
|
17
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 对照的需求版本:2")]),s(`
|
|
18
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 对照的报告:report.md(流水线结论:已完成,可以验收)")]),s(`
|
|
19
|
+
`),l("span",{class:"line"}),s(`
|
|
20
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"| AC | 结果 | 怎么验证的 | 备注 |")]),s(`
|
|
21
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"| --- | --- | --- | --- |")]),s(`
|
|
22
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"| AC-1.1 | 通过 / 不通过 / 未验 | <亲自操作 / 执行的命令> | <现象、截图路径> |")]),s(`
|
|
23
|
+
`),l("span",{class:"line"}),s(`
|
|
24
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 不通过的处理")]),s(`
|
|
25
|
+
`),l("span",{class:"line"}),s(`
|
|
26
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," AC-2.3:<现象> → 作为缺陷处理 / 作为需求修改 / 接受现状(理由)")])])])]),l("p",null,[l("code",null,"start-pipeline --list"),s(' 读取"验收结论"一行来显示"已验收"或"验收未通过"。')]),l("h2",{id:"需求总览",tabindex:"-1"},[s("需求总览 "),l("a",{class:"header-anchor",href:"#需求总览","aria-label":'Permalink to "需求总览"'},"")]),l("p",null,[s("需求总览不是一个提交进仓库的文件。每个需求在自己的工作区和分支上,共用的索引文件会在合并时冲突,所以总览由 "),l("code",null,"start-pipeline --list"),s(" 现场生成:扫描这个仓库所有 worktree 中的 "),l("code",null,"docs/features/*/spec.md"),s("、状态文件和验收记录。")])],-1),l("p",{class:"source-note"},[s("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/feature-files.md"},"contracts/feature-files.md"),s(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/feature-files.md"},"在 GitHub 上编辑")],-1)])])}const g=i(t,[["render",d]]);export{k as __pageData,g as default};
|