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 e,o as d,c as a,a3 as r}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"文件格式约定","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/index.md","filePath":"reference/contracts/index.md","lastUpdated":null}'),o={name:"reference/contracts/index.md"};function c(s,t,i,n,l,f){return d(),a("div",null,[...t[0]||(t[0]=[r('<div><h1 id="文件格式约定" tabindex="-1">文件格式约定 <a class="header-anchor" href="#文件格式约定" aria-label="Permalink to "文件格式约定""></a></h1><p>这些文件同时被聊天中的 skill、流水线引擎和步骤 agent 读写。改动格式时,同时更新这里、相关代码和测试,并在 <code>CHANGELOG.md</code> 的"升级须知"中说明。</p><table tabindex="0"><thead><tr><th>文件</th><th>约定</th><th>格式版本</th></tr></thead><tbody><tr><td><code>docs/features/<目录>/spec.md</code></td><td><a href="./spec">spec.md</a></td><td><code>req-kit/spec@1</code></td></tr><tr><td><code>docs/features/<目录>/.pipeline/state.json</code></td><td><a href="./state">state.md</a></td><td><code>version: 1</code></td></tr><tr><td><code>docs/features/<目录>/.pipeline/results/<步骤>.json</code></td><td><a href="./result-file">result-file.md</a></td><td>按步骤固定字段</td></tr><tr><td><code>decisions.tsv</code>、<code>changes.md</code>、<code>acceptance.md</code> 与需求总览</td><td><a href="./feature-files">feature-files.md</a></td><td>见各文件说明</td></tr><tr><td><code>.requirement-pipeline/verify.md</code></td><td><a href="./verify">verify.md</a></td><td>自由格式,建议结构见文件</td></tr><tr><td>外部通知(企业 IM 等)收到的事件</td><td><a href="./notifier-event">notifier-event.md</a></td><td><code>schema: 1</code></td></tr><tr><td><code>req api</code> 的输出(Paseo 插件等程序读取)</td><td><a href="./cli-json">cli-json.md</a></td><td><code>schema: 1</code></td></tr><tr><td><code>~/.req-kit/index/</code>、<code>~/.req-kit/usage/runs.jsonl</code></td><td><a href="./usage-record">usage-record.md</a></td><td><code>schema: 1</code></td></tr></tbody></table><p>格式版本的规则:</p><ul><li>同一主版本内只做可以自动迁移的变更。</li><li>引擎读到旧版本的状态文件时自动迁移,原文件保留为 <code>state.json.bak-v<旧版本></code>。</li><li>读到比自己新的版本时拒绝运行,提示升级 req-kit 或恢复备份。</li></ul></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/README.md">contracts/README.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/README.md">在 GitHub 上编辑</a></p>',2)])])}const h=e(o,[["render",c]]);export{p as __pageData,h as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e,o as d,c as a,a3 as r}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"文件格式约定","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/index.md","filePath":"reference/contracts/index.md","lastUpdated":null}'),o={name:"reference/contracts/index.md"};function c(s,t,i,n,l,f){return d(),a("div",null,[...t[0]||(t[0]=[r("",2)])])}const h=e(o,[["render",c]]);export{p as __pageData,h as default};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import{_ as e,o as t,c as n,j as i,a as s}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"外部通知事件(notifier)","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/notifier-event.md","filePath":"reference/contracts/notifier-event.md","lastUpdated":null}'),a={name:"reference/contracts/notifier-event.md"};function h(k,l,d,r,E,o){return t(),n("div",null,[...l[0]||(l[0]=[i("div",null,[i("h1",{id:"外部通知事件-notifier",tabindex:"-1"},[s("外部通知事件(notifier) "),i("a",{class:"header-anchor",href:"#外部通知事件-notifier","aria-label":'Permalink to "外部通知事件(notifier)"'},"")]),i("p",null,[s("流水线除了把消息发回发起的对话,还可以在关键时刻调用本机的通知模块,例如把消息转发到企业内部 IM。req-kit 只定义调用方式和事件格式,不包含任何 IM 的实现;模板见 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/notifiers/im-template.mjs",target:"_blank",rel:"noreferrer"},"notifiers/im-template.mjs"),s("。")]),i("h2",{id:"配置",tabindex:"-1"},[s("配置 "),i("a",{class:"header-anchor",href:"#配置","aria-label":'Permalink to "配置"'},"")]),i("p",null,[s("只能写在本机配置("),i("code",null,"~/.req-kit/config.json"),s(")或团队配置中,项目配置中的 "),i("code",null,"notifiers"),s(" 会被忽略(项目仓库里的代码不应该决定往哪里发消息)。")]),i("div",{class:"language-json vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"json"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"notifiers"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": [")]),s(`
|
|
2
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," {")]),s(`
|
|
3
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "module"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"~/.req-kit/notifiers/im.mjs"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
4
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "events"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"blocked"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"failed"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"completed"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"],")]),s(`
|
|
5
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "options"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"webhook"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"https://im.example.internal/hook/xxx"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"tokenEnv"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"IM_TOKEN"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")]),s(`
|
|
6
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")]),s(`
|
|
7
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"]")])])])]),i("table",{tabindex:"0"},[i("thead",null,[i("tr",null,[i("th",null,"字段"),i("th",null,"说明")])]),i("tbody",null,[i("tr",null,[i("td",null,[i("code",null,"module")]),i("td",null,[s("通知模块的路径。相对路径相对于声明它的配置文件;"),i("code",null,"~/"),s(" 表示用户目录。")])]),i("tr",null,[i("td",null,[i("code",null,"events")]),i("td",null,"要接收的事件类型,省略时接收全部(包括以后新增的类型)。")]),i("tr",null,[i("td",null,[i("code",null,"options")]),i("td",null,"原样传给模块的第二个参数。密钥不要直接写在这里,写环境变量的名字,由模块读取。")])])]),i("h2",{id:"模块",tabindex:"-1"},[s("模块 "),i("a",{class:"header-anchor",href:"#模块","aria-label":'Permalink to "模块"'},"")]),i("p",null,[s("ES 模块,默认导出(或导出名为 "),i("code",null,"notify"),s(" 的)函数:")]),i("div",{class:"language-js vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"js"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"}},"export"),i("span",{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"}}," default"),i("span",{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"}}," async"),i("span",{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"}}," function"),i("span",{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"}}," notify"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"("),i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"event"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"options"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},") { "),i("span",{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"}},"/* 发送 */"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")])])])]),i("ul",null,[i("li",null,"每个事件调用一次,可以返回 Promise。超过 15 秒没有完成按失败处理。"),i("li",null,'抛出的错误和超时只记入流水线日志("外部通知失败……不影响流水线"),不会让流水线停下或重试。'),i("li",null,"模块在一次流水线运行中只加载一次;修改模块后,对之后启动或继续的流水线生效。"),i("li",null,[s("测试:"),i("code",null,"req notify-test [--type blocked|failed|completed|milestone|permission|phase_done|approval|digest|alert]"),s(' 发一条带"【测试】"字样的示例事件,不需要运行流水线。')])]),i("h2",{id:"事件格式-schema-1",tabindex:"-1"},[s("事件格式(schema 1) "),i("a",{class:"header-anchor",href:"#事件格式-schema-1","aria-label":'Permalink to "事件格式(schema 1)"'},"")]),i("div",{class:"language-json vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"json"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"{")]),s(`
|
|
8
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "schema"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"1"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
9
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "type"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"blocked"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
10
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "at"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"2026-10-13T08:30:00.000Z"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
11
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "kitVersion"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"1.3.0-beta.1"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
12
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "feature"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"dir"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"docs/features/20261012-sms-login"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"20261012-sms-login"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"title"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"短信验证码登录"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),s(`
|
|
13
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "repo"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"D:'),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"\\\\"),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},"work"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"\\\\"),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'shop"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
14
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "branch"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"feature/20261012-sms-login"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
15
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "profile"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"standard"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
16
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "originAgentId"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"agent-id 或 null"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
17
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "text"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"方案审核发现 1 个需要需求方决定的问题,流水线已暂停,请到发起的对话中回答。"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
18
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "details"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"questions"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"……"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"], "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"resumeCommand"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"node '),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'\\"'),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},"…/start-pipeline.mjs"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'\\"'),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},' … --resume"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")]),s(`
|
|
19
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),i("p",null,[i("code",null,"text"),s(" 是一两句可以直接发出的话;需要自己排版时用 "),i("code",null,"details"),s("。")]),i("p",null,[i("strong",null,"发给谁"),s("(1.12 起,"),i("code",null,"people"),s("):")]),i("div",{class:"language-json vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"json"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"people"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": {")]),s(`
|
|
20
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "audience"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"requester"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
21
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "requester"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"张广祥"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
22
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "card"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"system"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ALM"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"id"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"CMASTER-BUSINESS#9902"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"url"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"null"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),s(`
|
|
23
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "recipients"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": [{ "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"张广祥"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"accounts"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"um"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ZHANGGX001"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }]")]),s(`
|
|
24
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),i("ul",null,[i("li",null,[i("code",null,"audience"),s(":"),i("code",null,"requester"),s(" 表示这件事要需求方处理或是给他的结果("),i("code",null,"blocked"),s("、"),i("code",null,"approval"),s("、"),i("code",null,"phase_done"),s("、"),i("code",null,"completed"),s(",而且需求从卡片开始、知道提出人);其余为 "),i("code",null,"team"),s(",发到群里即可。")]),i("li",null,[i("code",null,"requester"),s("、"),i("code",null,"card"),s(":从卡片开始的需求的提出人和卡片;其他需求为 null。")]),i("li",null,[i("code",null,"recipients"),s(":"),i("code",null,"audience"),s(" 为 "),i("code",null,"requester"),s(" 时是需求方本人;"),i("code",null,"accounts"),s(" 来自本机或团队配置的 "),i("code",null,"people"),s("(姓名 → 各种账号),没有写时为 "),i("code",null,"{}"),s(",模块可以改发到群。")])]),i("table",{tabindex:"0"},[i("thead",null,[i("tr",null,[i("th",null,"type"),i("th",null,"什么时候"),i("th",null,"details")])]),i("tbody",null,[i("tr",null,[i("td",null,[i("code",null,"milestone")]),i("td",null,[s("方案确定、开始验证、开始修复缺陷(配置 "),i("code",null,"notifyMilestones"),s(" 为 true 时,每次尝试各一次)")]),i("td",null,[i("code",null,"milestone"),s(":"),i("code",null,"design-settled"),s("、"),i("code",null,"code-reviewed"),s("、"),i("code",null,"fixing-defects"),s("、"),i("code",null,"handback-<n>"),s("(1.7.0 起,测试验证第 n 次把缺陷退回研发)")])]),i("tr",null,[i("td",null,[i("code",null,"blocked")]),i("td",null,"方案审核发现需要需求方决定的问题,流水线已暂停"),i("td",null,[i("code",null,"questions"),s("(字符串数组)、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"permission")]),i("td",null,"步骤 agent 在等待权限批准"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"agentTitle"),s("、"),i("code",null,"requests"),s("(字符串数组)")])]),i("tr",null,[i("td",null,[i("code",null,"failed")]),i("td",null,"流水线因错误中断(已自动重试过的临时错误除外)"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"reason"),s("、"),i("code",null,"logPath"),s("、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"completed")]),i("td",null,"流水线结束,报告已生成"),i("td",null,[i("code",null,"outcome"),s("("),i("code",null,"completed"),s("、"),i("code",null,"completed_with_issues"),s("、"),i("code",null,"not_completed"),s(")、"),i("code",null,"summary"),s("、"),i("code",null,"reportPath"),s('。"只做研发"时另有 '),i("code",null,"mode"),s("("),i("code",null,"develop-only"),s(")和 "),i("code",null,"handoffPath"),s(",报告是研发报告,需要人工测试")])]),i("tr",null,[i("td",null,[i("code",null,"approval")]),i("td",null,[s("1.8.0 起。方案确认点("),i("code",null,"designApproval"),s('):方案已通过审核,等待需求方确认"做完后会看到什么",还没有开始写代码')]),i("td",null,[i("code",null,"previewPath"),s("(要确认的内容)、"),i("code",null,"approveCommand"),s("(确认后继续的命令)、"),i("code",null,"resumeCommand"),s("(修改需求后继续的命令),都在发起的对话中执行")])]),i("tr",null,[i("td",null,[i("code",null,"phase_done")]),i("td",null,"1.7.0 起。分阶段执行时研发阶段已完成(代码已通过评审、提测说明已写好),流水线停在闸口等待测试验证。测试退回后再次修完也会发"),i("td",null,[i("code",null,"handoffPath"),s("(提测说明)、"),i("code",null,"mode"),s("("),i("code",null,"gated"),s(")、"),i("code",null,"verifyCommand"),s("(开始测试验证的命令,在发起的对话中执行)、"),i("code",null,"verifyAt"),s("(预约的开始时间,ISO 格式,没有为 null)、"),i("code",null,"handbacks"),s("(已退回的次数)")])]),i("tr",null,[i("td",null,[i("code",null,"alert")]),i("td",null,[s("1.12 起。接单器("),i("code",null,"req factory"),s(")自检没有通过(Paseo 连不上、agent 没有登录、额度用完、需求管理系统的命令不可用),暂停接新卡片;或者恢复正常。同样的问题只发一次。"),i("code",null,"feature.title"),s(' 为"接单器",'),i("code",null,"feature.dir"),s("、"),i("code",null,"repo"),s(" 为空")]),i("td",null,[i("code",null,"source"),s("("),i("code",null,"factory"),s(")、"),i("code",null,"machine"),s("、"),i("code",null,"problems"),s("(字符串数组,恢复时为空)、"),i("code",null,"recovered")])]),i("tr",null,[i("td",null,[i("code",null,"digest")]),i("td",null,[i("code",null,"req digest --notify"),s("(或由 "),i("code",null,"req digest --schedule"),s(" 创建的 Paseo 定时任务)发送项目的需求总览,1.6.0 起。"),i("code",null,"feature.title"),s(' 为"<项目> 需求总览",'),i("code",null,"text"),s(" 是完整的多行总览")]),i("td",null,[i("code",null,"features"),s(":每个需求的 "),i("code",null,"name"),s("、"),i("code",null,"title"),s("、"),i("code",null,"stage"),s("、"),i("code",null,"branch"),s("、"),i("code",null,"updatedAt"),s("、"),i("code",null,"usage"),s(";"),i("code",null,"recurringLessons"),s("(1.8.0 起):在两个以上需求的 "),i("code",null,"lessons.tsv"),s(" 中出现的问题类别,每项 "),i("code",null,"category"),s("、"),i("code",null,"features"),s("、"),i("code",null,"rules")])])])]),i("h2",{id:"兼容性",tabindex:"-1"},[s("兼容性 "),i("a",{class:"header-anchor",href:"#兼容性","aria-label":'Permalink to "兼容性"'},"")]),i("ul",null,[i("li",null,[s("同一 "),i("code",null,"schema"),s(" 内只增加字段,不删除、不改含义;模块应忽略不认识的字段和事件类型。")]),i("li",null,[s("不兼容的变化会提升 "),i("code",null,"schema"),s(",并在 "),i("code",null,"CHANGELOG.md"),s(' 的"升级须知"中说明。')])])],-1),i("p",{class:"source-note"},[s("本页由仓库中的 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/notifier-event.md"},"contracts/notifier-event.md"),s(" 生成。"),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/notifier-event.md"},"在 GitHub 上编辑")],-1)])])}const c=e(a,[["render",h]]);export{u as __pageData,c as default};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import{_ as e,o as t,c as n,j as i,a as s}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"外部通知事件(notifier)","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/notifier-event.md","filePath":"reference/contracts/notifier-event.md","lastUpdated":null}'),a={name:"reference/contracts/notifier-event.md"};function h(k,l,d,r,E,o){return t(),n("div",null,[...l[0]||(l[0]=[i("div",null,[i("h1",{id:"外部通知事件-notifier",tabindex:"-1"},[s("外部通知事件(notifier) "),i("a",{class:"header-anchor",href:"#外部通知事件-notifier","aria-label":'Permalink to "外部通知事件(notifier)"'},"")]),i("p",null,[s("流水线除了把消息发回发起的对话,还可以在关键时刻调用本机的通知模块,例如把消息转发到企业内部 IM。req-kit 只定义调用方式和事件格式,不包含任何 IM 的实现;模板见 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/notifiers/im-template.mjs",target:"_blank",rel:"noreferrer"},"notifiers/im-template.mjs"),s("。")]),i("h2",{id:"配置",tabindex:"-1"},[s("配置 "),i("a",{class:"header-anchor",href:"#配置","aria-label":'Permalink to "配置"'},"")]),i("p",null,[s("只能写在本机配置("),i("code",null,"~/.req-kit/config.json"),s(")或团队配置中,项目配置中的 "),i("code",null,"notifiers"),s(" 会被忽略(项目仓库里的代码不应该决定往哪里发消息)。")]),i("div",{class:"language-json vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"json"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"notifiers"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": [")]),s(`
|
|
2
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," {")]),s(`
|
|
3
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "module"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"~/.req-kit/notifiers/im.mjs"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
4
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "events"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"blocked"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"failed"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"completed"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"],")]),s(`
|
|
5
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "options"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"webhook"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"https://im.example.internal/hook/xxx"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"tokenEnv"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"IM_TOKEN"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")]),s(`
|
|
6
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")]),s(`
|
|
7
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"]")])])])]),i("table",{tabindex:"0"},[i("thead",null,[i("tr",null,[i("th",null,"字段"),i("th",null,"说明")])]),i("tbody",null,[i("tr",null,[i("td",null,[i("code",null,"module")]),i("td",null,[s("通知模块的路径。相对路径相对于声明它的配置文件;"),i("code",null,"~/"),s(" 表示用户目录。")])]),i("tr",null,[i("td",null,[i("code",null,"events")]),i("td",null,"要接收的事件类型,省略时接收全部(包括以后新增的类型)。")]),i("tr",null,[i("td",null,[i("code",null,"options")]),i("td",null,"原样传给模块的第二个参数。密钥不要直接写在这里,写环境变量的名字,由模块读取。")])])]),i("h2",{id:"模块",tabindex:"-1"},[s("模块 "),i("a",{class:"header-anchor",href:"#模块","aria-label":'Permalink to "模块"'},"")]),i("p",null,[s("ES 模块,默认导出(或导出名为 "),i("code",null,"notify"),s(" 的)函数:")]),i("div",{class:"language-js vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"js"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"}},"export"),i("span",{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"}}," default"),i("span",{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"}}," async"),i("span",{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"}}," function"),i("span",{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"}}," notify"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"("),i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"event"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"options"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},") { "),i("span",{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"}},"/* 发送 */"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")])])])]),i("ul",null,[i("li",null,"每个事件调用一次,可以返回 Promise。超过 15 秒没有完成按失败处理。"),i("li",null,'抛出的错误和超时只记入流水线日志("外部通知失败……不影响流水线"),不会让流水线停下或重试。'),i("li",null,"模块在一次流水线运行中只加载一次;修改模块后,对之后启动或继续的流水线生效。"),i("li",null,[s("测试:"),i("code",null,"req notify-test [--type blocked|failed|completed|milestone|permission|phase_done|approval|digest|alert]"),s(' 发一条带"【测试】"字样的示例事件,不需要运行流水线。')])]),i("h2",{id:"事件格式-schema-1",tabindex:"-1"},[s("事件格式(schema 1) "),i("a",{class:"header-anchor",href:"#事件格式-schema-1","aria-label":'Permalink to "事件格式(schema 1)"'},"")]),i("div",{class:"language-json vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"json"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"{")]),s(`
|
|
8
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "schema"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"1"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
9
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "type"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"blocked"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
10
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "at"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"2026-10-13T08:30:00.000Z"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
11
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "kitVersion"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"1.3.0-beta.1"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
12
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "feature"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"dir"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"docs/features/20261012-sms-login"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"20261012-sms-login"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"title"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"短信验证码登录"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),s(`
|
|
13
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "repo"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"D:'),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"\\\\"),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},"work"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"\\\\"),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'shop"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
14
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "branch"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"feature/20261012-sms-login"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
15
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "profile"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"standard"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
16
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "originAgentId"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"agent-id 或 null"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
17
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "text"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"方案审核发现 1 个需要需求方决定的问题,流水线已暂停,请到发起的对话中回答。"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
18
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "details"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"questions"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": ["),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"……"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"], "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"resumeCommand"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"node '),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'\\"'),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},"…/start-pipeline.mjs"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'\\"'),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},' … --resume"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," }")]),s(`
|
|
19
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),i("p",null,[i("code",null,"text"),s(" 是一两句可以直接发出的话;需要自己排版时用 "),i("code",null,"details"),s("。")]),i("p",null,[i("strong",null,"发给谁"),s("(1.12 起,"),i("code",null,"people"),s("):")]),i("div",{class:"language-json vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"json"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"people"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": {")]),s(`
|
|
20
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "audience"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"requester"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
21
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "requester"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"张广祥"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),s(`
|
|
22
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "card"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"system"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ALM"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"id"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"CMASTER-BUSINESS#9902"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"url"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"null"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," },")]),s(`
|
|
23
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "recipients"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": [{ "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"name"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"张广祥"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},", "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"accounts"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": { "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},'"um"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),i("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ZHANGGX001"'),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," } }]")]),s(`
|
|
24
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),i("ul",null,[i("li",null,[i("code",null,"audience"),s(":"),i("code",null,"requester"),s(" 表示这件事要需求方处理或是给他的结果("),i("code",null,"blocked"),s("、"),i("code",null,"approval"),s("、"),i("code",null,"phase_done"),s("、"),i("code",null,"completed"),s(",而且需求从卡片开始、知道提出人);其余为 "),i("code",null,"team"),s(",发到群里即可。")]),i("li",null,[i("code",null,"requester"),s("、"),i("code",null,"card"),s(":从卡片开始的需求的提出人和卡片;其他需求为 null。")]),i("li",null,[i("code",null,"recipients"),s(":"),i("code",null,"audience"),s(" 为 "),i("code",null,"requester"),s(" 时是需求方本人;"),i("code",null,"accounts"),s(" 来自本机或团队配置的 "),i("code",null,"people"),s("(姓名 → 各种账号),没有写时为 "),i("code",null,"{}"),s(",模块可以改发到群。")])]),i("table",{tabindex:"0"},[i("thead",null,[i("tr",null,[i("th",null,"type"),i("th",null,"什么时候"),i("th",null,"details")])]),i("tbody",null,[i("tr",null,[i("td",null,[i("code",null,"milestone")]),i("td",null,[s("方案确定、开始验证、开始修复缺陷(配置 "),i("code",null,"notifyMilestones"),s(" 为 true 时,每次尝试各一次)")]),i("td",null,[i("code",null,"milestone"),s(":"),i("code",null,"design-settled"),s("、"),i("code",null,"code-reviewed"),s("、"),i("code",null,"fixing-defects"),s("、"),i("code",null,"handback-<n>"),s("(1.7.0 起,测试验证第 n 次把缺陷退回研发)")])]),i("tr",null,[i("td",null,[i("code",null,"blocked")]),i("td",null,"方案审核发现需要需求方决定的问题,流水线已暂停"),i("td",null,[i("code",null,"questions"),s("(字符串数组)、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"permission")]),i("td",null,"步骤 agent 在等待权限批准"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"agentTitle"),s("、"),i("code",null,"requests"),s("(字符串数组)")])]),i("tr",null,[i("td",null,[i("code",null,"failed")]),i("td",null,"流水线因错误中断(已自动重试过的临时错误除外)"),i("td",null,[i("code",null,"stepTitle"),s("、"),i("code",null,"reason"),s("、"),i("code",null,"logPath"),s("、"),i("code",null,"resumeCommand")])]),i("tr",null,[i("td",null,[i("code",null,"completed")]),i("td",null,"流水线结束,报告已生成"),i("td",null,[i("code",null,"outcome"),s("("),i("code",null,"completed"),s("、"),i("code",null,"completed_with_issues"),s("、"),i("code",null,"not_completed"),s(")、"),i("code",null,"summary"),s("、"),i("code",null,"reportPath"),s('。"只做研发"时另有 '),i("code",null,"mode"),s("("),i("code",null,"develop-only"),s(")和 "),i("code",null,"handoffPath"),s(",报告是研发报告,需要人工测试")])]),i("tr",null,[i("td",null,[i("code",null,"approval")]),i("td",null,[s("1.8.0 起。方案确认点("),i("code",null,"designApproval"),s('):方案已通过审核,等待需求方确认"做完后会看到什么",还没有开始写代码')]),i("td",null,[i("code",null,"previewPath"),s("(要确认的内容)、"),i("code",null,"approveCommand"),s("(确认后继续的命令)、"),i("code",null,"resumeCommand"),s("(修改需求后继续的命令),都在发起的对话中执行")])]),i("tr",null,[i("td",null,[i("code",null,"phase_done")]),i("td",null,"1.7.0 起。分阶段执行时研发阶段已完成(代码已通过评审、提测说明已写好),流水线停在闸口等待测试验证。测试退回后再次修完也会发"),i("td",null,[i("code",null,"handoffPath"),s("(提测说明)、"),i("code",null,"mode"),s("("),i("code",null,"gated"),s(")、"),i("code",null,"verifyCommand"),s("(开始测试验证的命令,在发起的对话中执行)、"),i("code",null,"verifyAt"),s("(预约的开始时间,ISO 格式,没有为 null)、"),i("code",null,"handbacks"),s("(已退回的次数)")])]),i("tr",null,[i("td",null,[i("code",null,"alert")]),i("td",null,[s("1.12 起。接单器("),i("code",null,"req factory"),s(")自检没有通过(Paseo 连不上、agent 没有登录、额度用完、需求管理系统的命令不可用),暂停接新卡片;或者恢复正常。同样的问题只发一次。"),i("code",null,"feature.title"),s(' 为"接单器",'),i("code",null,"feature.dir"),s("、"),i("code",null,"repo"),s(" 为空")]),i("td",null,[i("code",null,"source"),s("("),i("code",null,"factory"),s(")、"),i("code",null,"machine"),s("、"),i("code",null,"problems"),s("(字符串数组,恢复时为空)、"),i("code",null,"recovered")])]),i("tr",null,[i("td",null,[i("code",null,"digest")]),i("td",null,[i("code",null,"req digest --notify"),s("(或由 "),i("code",null,"req digest --schedule"),s(" 创建的 Paseo 定时任务)发送项目的需求总览,1.6.0 起。"),i("code",null,"feature.title"),s(' 为"<项目> 需求总览",'),i("code",null,"text"),s(" 是完整的多行总览")]),i("td",null,[i("code",null,"features"),s(":每个需求的 "),i("code",null,"name"),s("、"),i("code",null,"title"),s("、"),i("code",null,"stage"),s("、"),i("code",null,"branch"),s("、"),i("code",null,"updatedAt"),s("、"),i("code",null,"usage"),s(";"),i("code",null,"recurringLessons"),s("(1.8.0 起):在两个以上需求的 "),i("code",null,"lessons.tsv"),s(" 中出现的问题类别,每项 "),i("code",null,"category"),s("、"),i("code",null,"features"),s("、"),i("code",null,"rules")])])])]),i("h2",{id:"兼容性",tabindex:"-1"},[s("兼容性 "),i("a",{class:"header-anchor",href:"#兼容性","aria-label":'Permalink to "兼容性"'},"")]),i("ul",null,[i("li",null,[s("同一 "),i("code",null,"schema"),s(" 内只增加字段,不删除、不改含义;模块应忽略不认识的字段和事件类型。")]),i("li",null,[s("不兼容的变化会提升 "),i("code",null,"schema"),s(",并在 "),i("code",null,"CHANGELOG.md"),s(' 的"升级须知"中说明。')])])],-1),i("p",{class:"source-note"},[s("本页由仓库中的 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/notifier-event.md"},"contracts/notifier-event.md"),s(" 生成。"),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/notifier-event.md"},"在 GitHub 上编辑")],-1)])])}const c=e(a,[["render",h]]);export{u as __pageData,c as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as d,o,c,a3 as t}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"步骤结果文件","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/result-file.md","filePath":"reference/contracts/result-file.md","lastUpdated":null}'),r={name:"reference/contracts/result-file.md"};function s(a,e,i,l,n,p){return o(),c("div",null,[...e[0]||(e[0]=[t('<div><h1 id="步骤结果文件" tabindex="-1">步骤结果文件 <a class="header-anchor" href="#步骤结果文件" aria-label="Permalink to "步骤结果文件""></a></h1><p>每个步骤结束时写一个 JSON 对象到 <code>.pipeline/results/<步骤键>.json</code>(路径在提示词的 <code><pipeline-context></code> 中给出)。引擎只根据它决定下一步,不读 agent 的回复文字。缺失或格式不对时,引擎会在同一个会话里提醒补写,最多 <code>resultFollowUps</code> 次(默认 2),仍不对则判定该步骤失败。</p><table tabindex="0"><thead><tr><th>步骤 ID</th><th>字段</th></tr></thead><tbody><tr><td><code>design</code></td><td><code>has_runnable_service</code>: boolean。可选(1.8 起):<code>slices</code>: 字符串数组(实施计划的切片,按实现顺序;两片以上时按片逐个实现);<code>files</code>: 字符串数组(预计改动的文件和目录,目录以 <code>/</code> 结尾,可用 <code>*</code>,用于范围检查);缺陷类型的 <code>reproduced</code>: boolean,为 <code>false</code> 时 <code>questions</code>: 非空字符串数组(需要需求方补充的信息);<code>ui_change</code>: boolean(改动是否改变使用者看到的界面或操作方式,方案确认点按它决定是否停下)</td></tr><tr><td><code>design_review</code></td><td><code>verdict</code>: <code>approved</code> | <code>changes_required</code> | <code>blocked</code>;为 <code>blocked</code> 时 <code>questions</code>: 非空字符串数组</td></tr><tr><td><code>design_revise</code></td><td><code>status</code>: <code>done</code> | <code>partial</code>。可选(1.8 起):<code>slices</code>、<code>files</code>、<code>ui_change</code>,修订改变了它们时写新的值</td></tr><tr><td><code>implement</code></td><td><code>status</code>: <code>done</code> | <code>partial</code>。按切片实现时,每片的键为 <code>implement-s<序号></code>。可选(1.8 起):<code>acceptance_tests</code>: 字符串数组(从验收标准的例子写出、先单独提交的测试文件),<code>acceptance_tests_commit</code>: string(那次提交);代码评审前引擎核对它们之后有没有被改过</td></tr><tr><td><code>review_fix</code>、<code>defect_fix</code></td><td><code>status</code>: <code>done</code> | <code>partial</code></td></tr><tr><td><code>code_review</code></td><td><code>verdict</code>: <code>pass</code> | <code>changes_required</code></td></tr><tr><td><code>service_start</code></td><td><code>started</code>: boolean</td></tr><tr><td><code>verify</code></td><td><code>result</code>: <code>pass</code> | <code>defects_found</code> | <code>blocked</code>。可选(1.8 起,联合需求):<code>defect_repos</code>: 字符串数组,缺陷所在的仓库(<code>本仓库</code> 或 <code>relatedRepos</code> 中的名称);没有时每个仓库都做一轮缺陷修复</td></tr><tr><td><code>reverify</code></td><td><code>result</code>: <code>pass</code> | <code>defects_remaining</code>。可选:<code>defect_repos</code>,同上</td></tr><tr><td><code>report</code></td><td><code>outcome</code>: <code>completed</code> | <code>completed_with_issues</code> | <code>not_completed</code>;<code>summary</code>: string</td></tr><tr><td><code>panel_review</code>(评审小组成员,键为 <code><评审步骤>-r<轮次>-p<序号></code>)</td><td><code>status</code>: <code>done</code> | <code>partial</code>;意见写在 <code><功能目录>/review-panel/<键>.md</code></td></tr></tbody></table><p>联合需求中,其他仓库的步骤的键带 <code>@<仓库后缀></code>(如 <code>implement@backend</code>、<code>code_review-r2@backend</code>),结果文件写在那个仓库工作区的功能目录中。</p><p>字段定义以 <code>engine/src/steps.ts</code> 为准;改动时同步更新各步骤提示词末尾的"结果文件"一节。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/result-file.md">contracts/result-file.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/result-file.md">在 GitHub 上编辑</a></p>',2)])])}const f=d(r,[["render",s]]);export{u as __pageData,f as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as d,o,c,a3 as t}from"./chunks/framework.B9qR_F1m.js";const u=JSON.parse('{"title":"步骤结果文件","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/result-file.md","filePath":"reference/contracts/result-file.md","lastUpdated":null}'),r={name:"reference/contracts/result-file.md"};function s(a,e,i,l,n,p){return o(),c("div",null,[...e[0]||(e[0]=[t("",2)])])}const f=d(r,[["render",s]]);export{u as __pageData,f as default};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{_ as s,o as t,c as i,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"spec.md","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/spec.md","filePath":"reference/contracts/spec.md","lastUpdated":null}'),a={name:"reference/contracts/spec.md"};function d(c,n,r,u,o,h){return t(),i("div",null,[...n[0]||(n[0]=[l("div",null,[l("h1",{id:"spec-md",tabindex:"-1"},[e("spec.md "),l("a",{class:"header-anchor",href:"#spec-md","aria-label":'Permalink to "spec.md"'},"")]),l("p",null,[e("需求说明,由 "),l("code",null,"/req"),e("("),l("code",null,"spec-writing"),e(" skill)按模板 "),l("code",null,"skills/spec-writing/spec-template.md"),e(" 写成,需求方确认后交给流水线。")]),l("h2",{id:"头部",tabindex:"-1"},[e("头部 "),l("a",{class:"header-anchor",href:"#头部","aria-label":'Permalink to "头部"'},"")]),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"}},"# <需求名称>")]),e(`
|
|
2
|
+
`),l("span",{class:"line"}),e(`
|
|
3
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 状态:已确认(2026-10-12)")]),e(`
|
|
4
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 档位:标准")]),e(`
|
|
5
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 执行方式:连续")]),e(`
|
|
6
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 类型:新需求")]),e(`
|
|
7
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 版本:1")]),e(`
|
|
8
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 格式:req-kit/spec@1")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"行"),l("th",null,"谁读"),l("th",null,"规则")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"- 状态:")]),l("td",null,"引擎"),l("td",null,[e('以"已确认"开头才能启动流水线。正则:'),l("code",null,"^\\s*-\\s*状态\\s*[::]\\s*已确认")])]),l("tr",null,[l("td",null,[l("code",null,"- 档位:")]),l("td",null,"引擎"),l("td",null,[e('"快速"或"标准"(也接受 '),l("code",null,"quick"),e(" / "),l("code",null,"standard"),e(")。没有时用配置中的 "),l("code",null,"defaultProfile")])]),l("tr",null,[l("td",null,[l("code",null,"- 执行方式:")]),l("td",null,"引擎"),l("td",null,[e('"连续"、"分阶段"或"只做研发"(也接受 '),l("code",null,"continuous"),e(" / "),l("code",null,"gated"),e(" / "),l("code",null,"develop-only"),e(")。可以没有;没有时用配置中的 "),l("code",null,"phases.mode"),e(",启动参数 "),l("code",null,"--phases"),e(" 优先(1.7 起)")])]),l("tr",null,[l("td",null,[l("code",null,"- 类型:")]),l("td",null,[e("引擎(1.8 起)、"),l("code",null,"/req")]),l("td",null,[e("新需求 / 小改动 / 缺陷 / 重构 / 评估(也接受 "),l("code",null,"defect"),e("、"),l("code",null,"bug"),e("、"),l("code",null,"refactor"),e("、"),l("code",null,"assessment"),e(';"技术改进"同重构,"调研"同评估)。缺陷、重构、评估按各自的做法运行('),l("code",null,"engine/prompts/types/"),e("),配置 "),l("code",null,"requirementTypes"),e(" 可以关掉某个类型;其他写法按新需求处理")])]),l("tr",null,[l("td",null,[l("code",null,"- 联合开发:")]),l("td",null,"引擎(1.8 起)"),l("td",null,[e("这个需求还要改的其他仓库,写项目配置 "),l("code",null,"relatedRepos"),e(" 中的名称,最多两个,用顿号分开。可以没有。见 ADR 0025")])]),l("tr",null,[l("td",null,[l("code",null,"- 版本:")]),l("td",null,[l("code",null,"/req")]),l("td",null,"从 1 开始,每次修改需求加 1")]),l("tr",null,[l("td",null,[l("code",null,"- 格式:")]),l("td",null,[l("code",null,"/req"),e("、引擎(将来)")]),l("td",null,[l("code",null,"req-kit/spec@<n>"),e("。没有这一行的旧 spec 按 "),l("code",null,"req-kit/spec@1"),e(" 处理")])])])]),l("h2",{id:"正文中被引用的编号",tabindex:"-1"},[e("正文中被引用的编号 "),l("a",{class:"header-anchor",href:"#正文中被引用的编号","aria-label":'Permalink to "正文中被引用的编号"'},"")]),l("ul",null,[l("li",null,[e("功能需求 "),l("code",null,"FR-<n>"),e(",验收标准 "),l("code",null,"AC-<n>.<m>"),e(",规则 "),l("code",null,"BR-<n>"),e(",假设 "),l("code",null,"A-<n>"),e("。")]),l("li",null,[e("每条验收标准至少带一组具体的输入和期望输出(1.8 起由 "),l("code",null,"acceptance-criteria"),e("、需求说明审阅检查);方案的测试直接用这些例子作为期望值。")]),l("li",null,'流水线各步骤和最终报告按这些编号引用,编号一旦确认就不要重排;删除的需求保留编号并注明"已取消"。')]),l("h2",{id:"变更",tabindex:"-1"},[e("变更 "),l("a",{class:"header-anchor",href:"#变更","aria-label":'Permalink to "变更"'},"")]),l("ul",null,[l("li",null,"spec 的内容哈希记录在状态文件中。spec 在流水线中断后被修改,续跑时从方案设计重新开始。")])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/spec.md"},"contracts/spec.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/spec.md"},"在 GitHub 上编辑")],-1)])])}const m=s(a,[["render",d]]);export{k as __pageData,m as default};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{_ as s,o as t,c as i,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const k=JSON.parse('{"title":"spec.md","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/spec.md","filePath":"reference/contracts/spec.md","lastUpdated":null}'),a={name:"reference/contracts/spec.md"};function d(c,n,r,u,o,h){return t(),i("div",null,[...n[0]||(n[0]=[l("div",null,[l("h1",{id:"spec-md",tabindex:"-1"},[e("spec.md "),l("a",{class:"header-anchor",href:"#spec-md","aria-label":'Permalink to "spec.md"'},"")]),l("p",null,[e("需求说明,由 "),l("code",null,"/req"),e("("),l("code",null,"spec-writing"),e(" skill)按模板 "),l("code",null,"skills/spec-writing/spec-template.md"),e(" 写成,需求方确认后交给流水线。")]),l("h2",{id:"头部",tabindex:"-1"},[e("头部 "),l("a",{class:"header-anchor",href:"#头部","aria-label":'Permalink to "头部"'},"")]),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"}},"# <需求名称>")]),e(`
|
|
2
|
+
`),l("span",{class:"line"}),e(`
|
|
3
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 状态:已确认(2026-10-12)")]),e(`
|
|
4
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 档位:标准")]),e(`
|
|
5
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 执行方式:连续")]),e(`
|
|
6
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 类型:新需求")]),e(`
|
|
7
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 版本:1")]),e(`
|
|
8
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 格式:req-kit/spec@1")])])])]),l("table",{tabindex:"0"},[l("thead",null,[l("tr",null,[l("th",null,"行"),l("th",null,"谁读"),l("th",null,"规则")])]),l("tbody",null,[l("tr",null,[l("td",null,[l("code",null,"- 状态:")]),l("td",null,"引擎"),l("td",null,[e('以"已确认"开头才能启动流水线。正则:'),l("code",null,"^\\s*-\\s*状态\\s*[::]\\s*已确认")])]),l("tr",null,[l("td",null,[l("code",null,"- 档位:")]),l("td",null,"引擎"),l("td",null,[e('"快速"或"标准"(也接受 '),l("code",null,"quick"),e(" / "),l("code",null,"standard"),e(")。没有时用配置中的 "),l("code",null,"defaultProfile")])]),l("tr",null,[l("td",null,[l("code",null,"- 执行方式:")]),l("td",null,"引擎"),l("td",null,[e('"连续"、"分阶段"或"只做研发"(也接受 '),l("code",null,"continuous"),e(" / "),l("code",null,"gated"),e(" / "),l("code",null,"develop-only"),e(")。可以没有;没有时用配置中的 "),l("code",null,"phases.mode"),e(",启动参数 "),l("code",null,"--phases"),e(" 优先(1.7 起)")])]),l("tr",null,[l("td",null,[l("code",null,"- 类型:")]),l("td",null,[e("引擎(1.8 起)、"),l("code",null,"/req")]),l("td",null,[e("新需求 / 小改动 / 缺陷 / 重构 / 评估(也接受 "),l("code",null,"defect"),e("、"),l("code",null,"bug"),e("、"),l("code",null,"refactor"),e("、"),l("code",null,"assessment"),e(';"技术改进"同重构,"调研"同评估)。缺陷、重构、评估按各自的做法运行('),l("code",null,"engine/prompts/types/"),e("),配置 "),l("code",null,"requirementTypes"),e(" 可以关掉某个类型;其他写法按新需求处理")])]),l("tr",null,[l("td",null,[l("code",null,"- 联合开发:")]),l("td",null,"引擎(1.8 起)"),l("td",null,[e("这个需求还要改的其他仓库,写项目配置 "),l("code",null,"relatedRepos"),e(" 中的名称,最多两个,用顿号分开。可以没有。见 ADR 0025")])]),l("tr",null,[l("td",null,[l("code",null,"- 版本:")]),l("td",null,[l("code",null,"/req")]),l("td",null,"从 1 开始,每次修改需求加 1")]),l("tr",null,[l("td",null,[l("code",null,"- 格式:")]),l("td",null,[l("code",null,"/req"),e("、引擎(将来)")]),l("td",null,[l("code",null,"req-kit/spec@<n>"),e("。没有这一行的旧 spec 按 "),l("code",null,"req-kit/spec@1"),e(" 处理")])])])]),l("h2",{id:"正文中被引用的编号",tabindex:"-1"},[e("正文中被引用的编号 "),l("a",{class:"header-anchor",href:"#正文中被引用的编号","aria-label":'Permalink to "正文中被引用的编号"'},"")]),l("ul",null,[l("li",null,[e("功能需求 "),l("code",null,"FR-<n>"),e(",验收标准 "),l("code",null,"AC-<n>.<m>"),e(",规则 "),l("code",null,"BR-<n>"),e(",假设 "),l("code",null,"A-<n>"),e("。")]),l("li",null,[e("每条验收标准至少带一组具体的输入和期望输出(1.8 起由 "),l("code",null,"acceptance-criteria"),e("、需求说明审阅检查);方案的测试直接用这些例子作为期望值。")]),l("li",null,'流水线各步骤和最终报告按这些编号引用,编号一旦确认就不要重排;删除的需求保留编号并注明"已取消"。')]),l("h2",{id:"变更",tabindex:"-1"},[e("变更 "),l("a",{class:"header-anchor",href:"#变更","aria-label":'Permalink to "变更"'},"")]),l("ul",null,[l("li",null,"spec 的内容哈希记录在状态文件中。spec 在流水线中断后被修改,续跑时从方案设计重新开始。")])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/spec.md"},"contracts/spec.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/spec.md"},"在 GitHub 上编辑")],-1)])])}const m=s(a,[["render",d]]);export{k as __pageData,m as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as d,o,c as t,a3 as c}from"./chunks/framework.B9qR_F1m.js";const m=JSON.parse('{"title":"state.json","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/state.md","filePath":"reference/contracts/state.md","lastUpdated":null}'),r={name:"reference/contracts/state.md"};function a(s,e,n,i,l,p){return o(),t("div",null,[...e[0]||(e[0]=[c('<div><h1 id="state-json" tabindex="-1">state.json <a class="header-anchor" href="#state-json" aria-label="Permalink to "state.json""></a></h1><p>流水线的运行状态,位于 <code>docs/features/<目录>/.pipeline/state.json</code>,只由引擎写入,不提交。</p><h2 id="当前格式-version-1" tabindex="-1">当前格式:version 1 <a class="header-anchor" href="#当前格式-version-1" aria-label="Permalink to "当前格式:version 1""></a></h2><table tabindex="0"><thead><tr><th>字段</th><th>类型</th><th>含义</th></tr></thead><tbody><tr><td><code>version</code></td><td>number</td><td>格式版本。没有这个字段的文件按 1 处理</td></tr><tr><td><code>repo</code></td><td>string</td><td>仓库目录(绝对路径)</td></tr><tr><td><code>featureDir</code></td><td>string</td><td>功能目录(相对路径,<code>/</code> 分隔)</td></tr><tr><td><code>status</code></td><td><code>running</code> | <code>waiting_for_business</code> | <code>failed</code> | <code>completed</code> | <code>phase_done</code> | <code>waiting_for_approval</code></td><td>当前状态。<code>waiting_for_business</code> 表示等待需求方决定;<code>phase_done</code>(1.7.0 起)表示研发阶段已完成、停在闸口等待测试验证;<code>waiting_for_approval</code>(1.8.0 起)表示方案已通过审核、等待需求方确认 <code>preview.md</code>,<code>--approve</code> 继续。旧引擎把不认识的状态当作可以继续的中断:<code>phase_done</code> 继续时直接做验证,<code>waiting_for_approval</code> 继续时不经确认直接写代码</td></tr><tr><td><code>attempt</code></td><td>number</td><td>第几次从方案设计开始</td></tr><tr><td><code>specHash</code></td><td>string</td><td>启动时 spec.md 的 sha256</td></tr><tr><td><code>originAgentId</code></td><td>string | null</td><td>发起对话的 agent,通知发往这里</td></tr><tr><td><code>pid</code></td><td>number</td><td>流水线进程</td></tr><tr><td><code>startedAt</code> / <code>updatedAt</code></td><td>ISO 时间</td><td></td></tr><tr><td><code>results</code></td><td>object</td><td>已完成步骤的结果,键为步骤键(如 <code>code_review-r2</code>)</td></tr><tr><td><code>history</code></td><td>array</td><td>每次步骤执行的记录:agent、起止时间、结果、错误;<code>usage</code>(可选,1.3.0 起)为 agent 报告的用量:<code>inputTokens</code>、<code>cachedInputTokens</code>、<code>outputTokens</code>、<code>totalCostUsd</code>,agent 没有报告时为 null 或缺少;<code>leftRunning</code>(可选,1.11 起)为 true 表示失败时 agent 可能还在运行,下一次运行这一步时先看它;<code>reattached</code>(可选,1.11 起)为接着等上一次 agent 的次数</td></tr><tr><td><code>stopReason</code> / <code>outcome</code></td><td>string | null</td><td>停止原因;最终结论</td></tr><tr><td><code>stopKind</code></td><td>string | null</td><td>可选,1.12 起。停下等人的原因代码:必要的决定 <code>approval</code>(确认方案)、<code>phase_gate</code>(研发完成,等待测试)、<code>business</code>(需求方决定)、<code>reproduce</code>(缺陷复现不了);中断 <code>timeout</code>、<code>agent_error</code>、<code>invalid_result</code>、<code>transient</code>、<code>stopped</code>、<code>process_exit</code>、<code>other</code>。运行中或完成时为 null</td></tr><tr><td><code>recoveries</code></td><td>array</td><td>可选,1.12 起。流水线自己处理掉的问题(最多保留 200 条):<code>at</code>、<code>key</code>(步骤键)、<code>kind</code>(<code>retry</code> 重试 / <code>reattach</code> 接着等上一次的 agent / <code>reuse_result</code> 沿用上一次 agent 的结果 / <code>extend_timeout</code> 超时后多等一轮 / <code>redo</code> 新开 agent 重做 / <code>fallback</code> 换备用模型 / <code>auto_resume</code> 预约自动继续 / <code>quota_wait</code> 预约在额度恢复后继续 / <code>self_answer</code> 方案审核的问题由 builder 自答)、<code>detail</code></td></tr><tr><td><code>profile</code></td><td><code>quick</code> | <code>standard</code></td><td>档位</td></tr><tr><td><code>branch</code></td><td>string | null</td><td>工作分支,启动时确定</td></tr><tr><td><code>milestones</code></td><td>string[]</td><td>已发送的进展通知,续跑时不重复发送</td></tr><tr><td><code>incremental</code></td><td>object | null</td><td>可选,1.3.0 起。需求变更或回答问题后的继续:<code>fromAttempt</code>(接着哪一次)、<code>reason</code>、<code>baseCommit</code>(本次开始时的提交,评审看这之后的改动)、<code>hadImplementation</code>(上一次是否已写过代码)。第一次运行和 <code>--restart</code> 为 null</td></tr><tr><td><code>worktree</code></td><td>object | null</td><td>可选,1.5.0 起。用 <code>--worktree</code> 启动、在为需求新建的工作区中开发时:<code>workspaceId</code>(Paseo 工作区)、<code>sourceRepo</code>(对话所在的目录)。此时 <code>repo</code> 是新工作区的目录</td></tr><tr><td><code>schedules</code></td><td>array</td><td>可选,1.6.0 起。这次运行创建的 Paseo 定时任务:<code>id</code>、<code>kind</code>(<code>reminder</code> 提醒 / <code>auto-resume</code> 自动继续 / <code>watchdog</code> 定时检查)、<code>at</code>。下一次运行或暂停命令会取消它们</td></tr><tr><td><code>autoResumes</code></td><td>object | null</td><td>可选,1.6.0 起。<code>attempt</code>、<code>count</code>:这次尝试已经预约过几次自动继续</td></tr><tr><td><code>queuedSince</code></td><td>string | null</td><td>可选,1.6.0 起。正在排队(<code>maxConcurrentPipelines</code>)时为开始排队的时间</td></tr><tr><td><code>phases</code></td><td>object | null</td><td>可选,1.7.0 起。这次运行的执行方式:<code>mode</code>(<code>continuous</code> / <code>gated</code> / <code>develop-only</code>)、<code>environment</code>(<code>local</code> / <code>deployed</code>)、<code>defects</code>(<code>fix</code> / <code>handback</code> / <code>report</code>)。没有时按 <code>continuous</code>、<code>local</code>、<code>fix</code> 处理</td></tr><tr><td><code>phase</code></td><td><code>develop</code> | <code>verify</code></td><td>可选,1.7.0 起。当前阶段。用字符串而不是编号,以后增加阶段不用改格式</td></tr><tr><td><code>verifyAt</code></td><td>string | null</td><td>可选,1.7.0 起。<code>--verify-at</code>:研发完成后在这个时间开始测试验证</td></tr><tr><td><code>handbacks</code></td><td>number</td><td>可选,1.7.0 起。测试验证把缺陷退回研发阶段的次数(<code>defects</code> 为 <code>handback</code>),上限为档位的 <code>defectFix</code> 轮数</td></tr><tr><td><code>type</code></td><td><code>defect</code> | <code>refactor</code> | <code>assessment</code> | null</td><td>可选,1.8.0 起。spec 中"类型"对应的做法;新需求、小改动和配置关掉的类型为 null</td></tr><tr><td><code>codeBase</code></td><td>object | null</td><td>可选,1.8.0 起。<code>attempt</code>、<code>commit</code>:这次尝试在改动任何代码之前的提交,质量门的基线和范围检查从这里比较。尝试开始时就已经写过代码的旧记录为 <code>commit: null</code></td></tr><tr><td><code>joint</code></td><td>array | null</td><td>可选,1.8.0 起。联合需求(spec 的 <code>- 联合开发:</code>)中其他仓库的工作区:<code>name</code>(<code>relatedRepos</code> 中的名称)、<code>slug</code>(步骤键的后缀,如 <code>implement@backend</code>)、<code>sourceRepo</code>(切出工作区的那份检出)、<code>repo</code>(工作区目录)、<code>workspaceId</code>、<code>branch</code>、<code>specHash</code>(最近一次同步过去的 spec),以及这个仓库自己的 <code>codeBase</code> 和 <code>gate</code>(格式同顶层)。见 ADR 0025</td></tr><tr><td><code>approval</code></td><td>object | null</td><td>可选,1.8.0 起。方案确认点:<code>attempt</code>(哪一次尝试的方案)、<code>status</code>(<code>waiting</code> / <code>approved</code>)、<code>at</code>。需求变更后的新尝试需要重新确认</td></tr><tr><td><code>external</code></td><td>object | null</td><td>可选,1.9.0 起。外部系统中的卡片,按集成名称:<code>id</code>(卡片编号)、<code>url</code>、<code>status</code>(最近设置的状态)、<code>syncedAt</code>、<code>pending</code>(没有成功、等待补发的调用:<code>action</code> 为 <code>create</code> / <code>status</code>、<code>event</code>、<code>status</code>、<code>at</code>、<code>attempts</code>、<code>error</code>)。见 ADR 0028</td></tr><tr><td><code>pushed</code></td><td>array | null</td><td>可选,1.10 起。从卡片开始、配置了 <code>push</code> 的需求推送过的分支,每个仓库一条(主仓库在前):<code>repo</code>、<code>remote</code>、<code>branch</code>、<code>at</code>、<code>error</code>(成功时为 null)。见 ADR 0029</td></tr><tr><td><code>gate</code></td><td>object | null</td><td>可选,1.8.0 起。质量门:<code>baseline</code>(<code>attempt</code>、<code>commit</code>、<code>at</code>、<code>results</code>:每项检查改动前 <code>pass</code> / <code>fail</code>),<code>runs</code>(每次运行:<code>key</code> 步骤键、<code>attempt</code>、<code>at</code>、<code>checks</code>(<code>name</code>、<code>result</code>:<code>pass</code> / <code>fail</code> / <code>skipped</code>、<code>failedBefore</code>)、<code>newFailures</code>、<code>fixRounds</code>、<code>passed</code>)。各次运行的完整输出在 <code>.pipeline/checks/<步骤键>/</code></td></tr></tbody></table><p><code>schedules[].kind</code> 在 1.7.0 起还可能是 <code>verify-start</code>(<code>--verify-at</code> 预约的测试验证开始),1.8.0 起还可能是 <code>approval-continue</code>(方案确认超时后按方案继续,<code>designApproval.autoContinueHours</code>)。<code>history</code> 中每条步骤记录在 1.7.0 起有可选的 <code>phase</code>(<code>develop</code> / <code>verify</code>),用于按阶段统计用时与用量;没有时按研发阶段统计。</p><h2 id="迁移" tabindex="-1">迁移 <a class="header-anchor" href="#迁移" aria-label="Permalink to "迁移""></a></h2><p>只增加可选字段(缺少时按默认值处理,旧版本引擎读到也不出错)时不提升版本,以便回滚到旧版本后仍能继续已有的流水线;在上表中注明"可选"和起始版本即可。</p><p>引擎(<code>engine/src/state.ts</code>)中 <code>STATE_VERSION</code> 是当前版本,<code>STATE_MIGRATIONS[n]</code> 把第 n 版升级到第 n+1 版。增加必需字段或改变已有字段的含义时:</p><ol><li><code>STATE_VERSION</code> 加 1。</li><li>在 <code>STATE_MIGRATIONS</code> 中加一个从旧版本到新版本的函数,为旧文件补上默认值。</li><li>在 <code>engine/test/state.test.ts</code> 中加一条迁移测试,更新本文件。</li></ol></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/state.md">contracts/state.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/state.md">在 GitHub 上编辑</a></p>',2)])])}const h=d(r,[["render",a]]);export{m as __pageData,h as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as d,o,c as t,a3 as c}from"./chunks/framework.B9qR_F1m.js";const m=JSON.parse('{"title":"state.json","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/state.md","filePath":"reference/contracts/state.md","lastUpdated":null}'),r={name:"reference/contracts/state.md"};function a(s,e,n,i,l,p){return o(),t("div",null,[...e[0]||(e[0]=[c("",2)])])}const h=d(r,[["render",a]]);export{m as __pageData,h as default};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{_ as i,o as n,c as t,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"本机的需求索引与使用记录","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/usage-record.md","filePath":"reference/contracts/usage-record.md","lastUpdated":null}'),a={name:"reference/contracts/usage-record.md"};function d(r,s,o,u,h,c){return n(),t("div",null,[...s[0]||(s[0]=[l("div",null,[l("h1",{id:"本机的需求索引与使用记录",tabindex:"-1"},[e("本机的需求索引与使用记录 "),l("a",{class:"header-anchor",href:"#本机的需求索引与使用记录","aria-label":'Permalink to "本机的需求索引与使用记录"'},"")]),l("p",null,[e("1.9.0 起,引擎在本机配置目录(默认 "),l("code",null,"~/.req-kit"),e(",可用 "),l("code",null,"REQ_KIT_HOME"),e(" 改变)下记两样东西。它们只在这台机器上,不提交进任何仓库,也不会自动发往任何地方。环境变量 "),l("code",null,"REQ_KIT_NO_RECORD=1"),e(" 时两样都不记(评估运行就是这样)。")]),l("h2",{id:"需求索引-index-key-json",tabindex:"-1"},[e("需求索引 "),l("code",null,"index/<key>.json"),e(),l("a",{class:"header-anchor",href:"#需求索引-index-key-json","aria-label":'Permalink to "需求索引 `index/<key>.json`"'},"")]),l("p",null,[e("每个在本机运行过的需求一个文件,记录它在哪里,供 "),l("code",null,"req api list --all"),e(" 和 Paseo 插件找到本机所有的需求。需求的阶段、进度仍然现场从功能目录读取(ADR 0010)。")]),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"}},"{")]),e(`
|
|
2
|
+
`),l("span",{class:"line"},[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"}},",")]),e(`
|
|
3
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "key"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"3f2a9c1e5b7d4e8a"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
4
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "repo"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"/home/me/work/shop-sms-login"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
5
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "featureDir"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"docs/features/20261012-sms-login"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
6
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "sourceRepo"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"/home/me/work/shop"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
7
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "workspaceId"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ws_123"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
8
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "project"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"shop"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
9
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "registeredAt"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"2026-10-12T09:00:00.000Z"')]),e(`
|
|
10
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),l("p",null,[l("code",null,"key"),e(" 由对话所在的目录(没有自己的工作区时即 "),l("code",null,"repo"),e(")和功能目录算出。"),l("code",null,"req index --rebuild"),e(" 为 1.9 之前运行过的需求补登,"),l("code",null,"req index --prune"),e(" 移除目录已不在的。")]),l("h2",{id:"使用记录-usage-runs-jsonl",tabindex:"-1"},[e("使用记录 "),l("code",null,"usage/runs.jsonl"),e(),l("a",{class:"header-anchor",href:"#使用记录-usage-runs-jsonl","aria-label":'Permalink to "使用记录 `usage/runs.jsonl`"'},"")]),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,"schema"),e(" / "),l("code",null,"kind")]),l("td",null,[l("code",null,"1"),e(" / "),l("code",null,'"run"')])]),l("tr",null,[l("td",null,[l("code",null,"machine"),e(" / "),l("code",null,"kitVersion")]),l("td",null,"主机名、req-kit 版本")]),l("tr",null,[l("td",null,[l("code",null,"requirement")]),l("td",null,[l("code",null,"{ key, project, name, title, type, profile }"),e(";从卡片开始的需求(1.10 起)另有 "),l("code",null,"requester"),e("(卡片的提出人)和 "),l("code",null,"source"),e("("),l("code",null,"{ system, id }"),e(")")])]),l("tr",null,[l("td",null,[l("code",null,"run")]),l("td",null,[l("code",null,"{ startedAt, endedAt, attempt, phase, phaseMode, status, outcome, stopReason, stopKind, recoveries }"),e(";"),l("code",null,"status"),e(" 是运行结束时的状态,"),l("code",null,"outcome"),e(" 是完成时报告的结论;"),l("code",null,"stopKind"),e("(1.12 起)是停下等人的原因代码(见 "),l("a",{href:"./state"},"state.md"),e("),"),l("code",null,"recoveries"),e("(1.12 起)是这次运行中自动处理的次数,按种类,如 "),l("code",null,'{ "retry": 2 }'),e("。更早的记录没有这两项")])]),l("tr",null,[l("td",null,[l("code",null,"agents")]),l("td",null,[l("code",null,"{ builder, reviewer }"),e(":当时配置的 agent(如 "),l("code",null,"claude/opus(bypassPermissions)"),e(")")])]),l("tr",null,[l("td",null,[l("code",null,"steps")]),l("td",null,[e("这次运行中开始的步骤:"),l("code",null,"{ key, stepId, phase, attempt, round, startedAt, endedAt, minutes, outcome, inputTokens, outputTokens, costUsd }"),e(";agent 没有报告的用量为 null")])]),l("tr",null,[l("td",null,[l("code",null,"gate")]),l("td",null,[l("code",null,"{ runs, failed }"),e(":这次运行中质量门运行的次数、发现新失败的次数")])])])]),l("p",null,"不记录需求内容、代码和对话。"),l("h2",{id:"统计口径-req-stats",tabindex:"-1"},[e("统计口径("),l("code",null,"req stats"),e(") "),l("a",{class:"header-anchor",href:"#统计口径-req-stats","aria-label":'Permalink to "统计口径(`req stats`)"'},"")]),l("ul",null,[l("li",null,"一段时间的用量、步骤用时:结束时间在这段时间内的运行。"),l("li",null,'交付周期:需求第一次开始到完成(最后一次运行以"已完成"结束)的小时数,用这个需求的全部运行,算在完成的那段时间。'),l("li",null,"代码评审轮数、缺陷修复轮数:不同的(尝试、轮次、仓库)个数;评审分方向或评审小组的几个成员算一轮。"),l("li",null,"等待:相邻两次运行之间的间隔,按前一次结束时的状态归类:等待确认方案、等待需求方决定、研发完成到开始测试验证、中断到继续。"),l("li",null,[e("停下等人的原因(1.12 起):这段时间结束的运行按 "),l("code",null,"stopKind"),e(" 计数;更早的记录按结束时的状态推断。确认方案、研发完成等待测试是必要的决定。")]),l("li",null,"无人工到提测的比例(1.12 起):这段时间有进展、已经研发完成或完成的需求中,所有运行都只停在必要决定处的比例。"),l("li",null,"自动处理的比例(1.12 起):自动处理的次数 ÷(自动处理的次数 + 以中断结束的运行数);需求方决定、缺陷复现不了不算中断。"),l("li",null,"合并多台机器的导出时,同一机器、同一需求、同一开始时间的运行只算一次。")]),l("p",null,[l("code",null,"req stats --json"),e(" 和 "),l("code",null,"req api stats"),e(" 输出同样的对象("),l("code",null,"schema: 1"),e("):"),l("code",null,"period"),e("、"),l("code",null,"machines"),e("、"),l("code",null,"active"),e("、"),l("code",null,"completed"),e("、"),l("code",null,"byType"),e("、"),l("code",null,"cycleHours"),e("、"),l("code",null,"steps"),e("、"),l("code",null,"rework"),e("、"),l("code",null,"waits"),e("、"),l("code",null,"usage"),e("、"),l("code",null,"byBuilder"),e("、"),l("code",null,"requirements"),e("(每个需求一项,字段与 "),l("code",null,"req stats --csv"),e(" 的列对应)。")])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/usage-record.md"},"contracts/usage-record.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/usage-record.md"},"在 GitHub 上编辑")],-1)])])}const E=i(a,[["render",d]]);export{p as __pageData,E as default};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{_ as i,o as n,c as t,j as l,a as e}from"./chunks/framework.B9qR_F1m.js";const p=JSON.parse('{"title":"本机的需求索引与使用记录","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/usage-record.md","filePath":"reference/contracts/usage-record.md","lastUpdated":null}'),a={name:"reference/contracts/usage-record.md"};function d(r,s,o,u,h,c){return n(),t("div",null,[...s[0]||(s[0]=[l("div",null,[l("h1",{id:"本机的需求索引与使用记录",tabindex:"-1"},[e("本机的需求索引与使用记录 "),l("a",{class:"header-anchor",href:"#本机的需求索引与使用记录","aria-label":'Permalink to "本机的需求索引与使用记录"'},"")]),l("p",null,[e("1.9.0 起,引擎在本机配置目录(默认 "),l("code",null,"~/.req-kit"),e(",可用 "),l("code",null,"REQ_KIT_HOME"),e(" 改变)下记两样东西。它们只在这台机器上,不提交进任何仓库,也不会自动发往任何地方。环境变量 "),l("code",null,"REQ_KIT_NO_RECORD=1"),e(" 时两样都不记(评估运行就是这样)。")]),l("h2",{id:"需求索引-index-key-json",tabindex:"-1"},[e("需求索引 "),l("code",null,"index/<key>.json"),e(),l("a",{class:"header-anchor",href:"#需求索引-index-key-json","aria-label":'Permalink to "需求索引 `index/<key>.json`"'},"")]),l("p",null,[e("每个在本机运行过的需求一个文件,记录它在哪里,供 "),l("code",null,"req api list --all"),e(" 和 Paseo 插件找到本机所有的需求。需求的阶段、进度仍然现场从功能目录读取(ADR 0010)。")]),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"}},"{")]),e(`
|
|
2
|
+
`),l("span",{class:"line"},[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"}},",")]),e(`
|
|
3
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "key"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"3f2a9c1e5b7d4e8a"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
4
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "repo"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"/home/me/work/shop-sms-login"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
5
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "featureDir"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"docs/features/20261012-sms-login"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
6
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "sourceRepo"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"/home/me/work/shop"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
7
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "workspaceId"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"ws_123"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
8
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "project"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"shop"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},",")]),e(`
|
|
9
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},' "registeredAt"'),l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},": "),l("span",{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}},'"2026-10-12T09:00:00.000Z"')]),e(`
|
|
10
|
+
`),l("span",{class:"line"},[l("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"}")])])])]),l("p",null,[l("code",null,"key"),e(" 由对话所在的目录(没有自己的工作区时即 "),l("code",null,"repo"),e(")和功能目录算出。"),l("code",null,"req index --rebuild"),e(" 为 1.9 之前运行过的需求补登,"),l("code",null,"req index --prune"),e(" 移除目录已不在的。")]),l("h2",{id:"使用记录-usage-runs-jsonl",tabindex:"-1"},[e("使用记录 "),l("code",null,"usage/runs.jsonl"),e(),l("a",{class:"header-anchor",href:"#使用记录-usage-runs-jsonl","aria-label":'Permalink to "使用记录 `usage/runs.jsonl`"'},"")]),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,"schema"),e(" / "),l("code",null,"kind")]),l("td",null,[l("code",null,"1"),e(" / "),l("code",null,'"run"')])]),l("tr",null,[l("td",null,[l("code",null,"machine"),e(" / "),l("code",null,"kitVersion")]),l("td",null,"主机名、req-kit 版本")]),l("tr",null,[l("td",null,[l("code",null,"requirement")]),l("td",null,[l("code",null,"{ key, project, name, title, type, profile }"),e(";从卡片开始的需求(1.10 起)另有 "),l("code",null,"requester"),e("(卡片的提出人)和 "),l("code",null,"source"),e("("),l("code",null,"{ system, id }"),e(")")])]),l("tr",null,[l("td",null,[l("code",null,"run")]),l("td",null,[l("code",null,"{ startedAt, endedAt, attempt, phase, phaseMode, status, outcome, stopReason, stopKind, recoveries }"),e(";"),l("code",null,"status"),e(" 是运行结束时的状态,"),l("code",null,"outcome"),e(" 是完成时报告的结论;"),l("code",null,"stopKind"),e("(1.12 起)是停下等人的原因代码(见 "),l("a",{href:"./state"},"state.md"),e("),"),l("code",null,"recoveries"),e("(1.12 起)是这次运行中自动处理的次数,按种类,如 "),l("code",null,'{ "retry": 2 }'),e("。更早的记录没有这两项")])]),l("tr",null,[l("td",null,[l("code",null,"agents")]),l("td",null,[l("code",null,"{ builder, reviewer }"),e(":当时配置的 agent(如 "),l("code",null,"claude/opus(bypassPermissions)"),e(")")])]),l("tr",null,[l("td",null,[l("code",null,"steps")]),l("td",null,[e("这次运行中开始的步骤:"),l("code",null,"{ key, stepId, phase, attempt, round, startedAt, endedAt, minutes, outcome, inputTokens, outputTokens, costUsd }"),e(";agent 没有报告的用量为 null")])]),l("tr",null,[l("td",null,[l("code",null,"gate")]),l("td",null,[l("code",null,"{ runs, failed }"),e(":这次运行中质量门运行的次数、发现新失败的次数")])])])]),l("p",null,"不记录需求内容、代码和对话。"),l("h2",{id:"统计口径-req-stats",tabindex:"-1"},[e("统计口径("),l("code",null,"req stats"),e(") "),l("a",{class:"header-anchor",href:"#统计口径-req-stats","aria-label":'Permalink to "统计口径(`req stats`)"'},"")]),l("ul",null,[l("li",null,"一段时间的用量、步骤用时:结束时间在这段时间内的运行。"),l("li",null,'交付周期:需求第一次开始到完成(最后一次运行以"已完成"结束)的小时数,用这个需求的全部运行,算在完成的那段时间。'),l("li",null,"代码评审轮数、缺陷修复轮数:不同的(尝试、轮次、仓库)个数;评审分方向或评审小组的几个成员算一轮。"),l("li",null,"等待:相邻两次运行之间的间隔,按前一次结束时的状态归类:等待确认方案、等待需求方决定、研发完成到开始测试验证、中断到继续。"),l("li",null,[e("停下等人的原因(1.12 起):这段时间结束的运行按 "),l("code",null,"stopKind"),e(" 计数;更早的记录按结束时的状态推断。确认方案、研发完成等待测试是必要的决定。")]),l("li",null,"无人工到提测的比例(1.12 起):这段时间有进展、已经研发完成或完成的需求中,所有运行都只停在必要决定处的比例。"),l("li",null,"自动处理的比例(1.12 起):自动处理的次数 ÷(自动处理的次数 + 以中断结束的运行数);需求方决定、缺陷复现不了不算中断。"),l("li",null,"合并多台机器的导出时,同一机器、同一需求、同一开始时间的运行只算一次。")]),l("p",null,[l("code",null,"req stats --json"),e(" 和 "),l("code",null,"req api stats"),e(" 输出同样的对象("),l("code",null,"schema: 1"),e("):"),l("code",null,"period"),e("、"),l("code",null,"machines"),e("、"),l("code",null,"active"),e("、"),l("code",null,"completed"),e("、"),l("code",null,"byType"),e("、"),l("code",null,"cycleHours"),e("、"),l("code",null,"steps"),e("、"),l("code",null,"rework"),e("、"),l("code",null,"waits"),e("、"),l("code",null,"usage"),e("、"),l("code",null,"byBuilder"),e("、"),l("code",null,"requirements"),e("(每个需求一项,字段与 "),l("code",null,"req stats --csv"),e(" 的列对应)。")])],-1),l("p",{class:"source-note"},[e("本页由仓库中的 "),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/usage-record.md"},"contracts/usage-record.md"),e(" 生成。"),l("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/usage-record.md"},"在 GitHub 上编辑")],-1)])])}const E=i(a,[["render",d]]);export{p as __pageData,E as default};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import{_ as e,o as t,c as a,j as i,a as s}from"./chunks/framework.B9qR_F1m.js";const o=JSON.parse('{"title":".requirement-pipeline/verify.md","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/verify.md","filePath":"reference/contracts/verify.md","lastUpdated":null}'),n={name:"reference/contracts/verify.md"};function h(k,l,p,r,d,E){return t(),a("div",null,[...l[0]||(l[0]=[i("div",null,[i("h1",{id:"requirement-pipeline-verify-md",tabindex:"-1"},[s(".requirement-pipeline/verify.md "),i("a",{class:"header-anchor",href:"#requirement-pipeline-verify-md","aria-label":'Permalink to ".requirement-pipeline/verify.md"'},"")]),i("p",null,[s("项目的验证方法:怎么安装依赖、启动服务、运行测试、准备测试数据。由 "),i("code",null,"/req-setup"),s(' 生成,其中的命令要实际运行过。流水线把它追加到实现、评审修复、服务启动、功能验证、缺陷修复、复验这几个步骤的提示词中("本项目的验证方法"一节)。')]),i("p",null,"格式自由,建议按下面的结构写,每节给出可以直接复制执行的命令:"),i("div",{class:"language-markdown vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"markdown"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# 验证方法")]),s(`
|
|
2
|
+
`),i("span",{class:"line"}),s(`
|
|
3
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"最后核对:2026-10-13(/req-setup,全部命令已运行)")]),s(`
|
|
4
|
+
`),i("span",{class:"line"}),s(`
|
|
5
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 环境准备")]),s(`
|
|
6
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," Node.js 22,pnpm 9")]),s(`
|
|
7
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 安装依赖:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm install`")]),s(`
|
|
8
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 依赖的本地服务:PostgreSQL("),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`docker compose up -d db`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"),Redis 不需要")]),s(`
|
|
9
|
+
`),i("span",{class:"line"}),s(`
|
|
10
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 构建与静态检查")]),s(`
|
|
11
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 类型检查:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm typecheck`")]),s(`
|
|
12
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 代码检查:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm lint`")]),s(`
|
|
13
|
+
`),i("span",{class:"line"}),s(`
|
|
14
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 单元与集成测试")]),s(`
|
|
15
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 全部:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm test`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"(约 2 分钟,基线 412 个用例全部通过)")]),s(`
|
|
16
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 单个文件:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm test path/to/file.test.ts`")]),s(`
|
|
17
|
+
`),i("span",{class:"line"}),s(`
|
|
18
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 启动服务")]),s(`
|
|
19
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 命令:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm dev`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"(在仓库根目录)")]),s(`
|
|
20
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 就绪判断:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`GET http://localhost:3000/health`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 返回 200,通常 10 秒内")]),s(`
|
|
21
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 停止:结束该进程;端口 3000")]),s(`
|
|
22
|
+
`),i("span",{class:"line"}),s(`
|
|
23
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 端到端验证")]),s(`
|
|
24
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 工具:Playwright,"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm e2e`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},";或手工用浏览器访问 http://localhost:3000")]),s(`
|
|
25
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 测试账号:见 docs/test-accounts.md(不要写入真实口令)")]),s(`
|
|
26
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 测试替身:短信、支付走 "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`MOCK_EXTERNAL=1`")]),s(`
|
|
27
|
+
`),i("span",{class:"line"}),s(`
|
|
28
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 已知问题")]),s(`
|
|
29
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}}," `pnpm test`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 中 "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`report.test.ts`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 偶发超时,与需求无关")])])])]),i("p",null,[s("其中几分钟内能跑完的检查(格式、lint、类型检查、单元测试、构建)同时写进项目配置 "),i("code",null,".requirement-pipeline.json"),s(" 的 "),i("code",null,"checks"),s("(1.8 起):流水线会在写代码和修复的步骤之后自己运行它们,作为质量门。"),i("code",null,"verify.md"),s(" 写给 agent 看,"),i("code",null,"checks"),s(" 由流水线执行,两处的命令保持一致。")]),i("p",null,[s("步骤 agent 发现它过时或不准确时,会在 "),i("code",null,"service-start.md"),s(" 或 "),i("code",null,"verification.md"),s(' 的"建议写入 verify.md 的内容"一节给出实际可行的做法;'),i("code",null,"/req-setup"),s(" 再次运行时会参考这些建议更新本文件。")])],-1),i("p",{class:"source-note"},[s("本页由仓库中的 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/verify.md"},"contracts/verify.md"),s(" 生成。"),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/verify.md"},"在 GitHub 上编辑")],-1)])])}const g=e(n,[["render",h]]);export{o as __pageData,g as default};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import{_ as e,o as t,c as a,j as i,a as s}from"./chunks/framework.B9qR_F1m.js";const o=JSON.parse('{"title":".requirement-pipeline/verify.md","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/contracts/verify.md","filePath":"reference/contracts/verify.md","lastUpdated":null}'),n={name:"reference/contracts/verify.md"};function h(k,l,p,r,d,E){return t(),a("div",null,[...l[0]||(l[0]=[i("div",null,[i("h1",{id:"requirement-pipeline-verify-md",tabindex:"-1"},[s(".requirement-pipeline/verify.md "),i("a",{class:"header-anchor",href:"#requirement-pipeline-verify-md","aria-label":'Permalink to ".requirement-pipeline/verify.md"'},"")]),i("p",null,[s("项目的验证方法:怎么安装依赖、启动服务、运行测试、准备测试数据。由 "),i("code",null,"/req-setup"),s(' 生成,其中的命令要实际运行过。流水线把它追加到实现、评审修复、服务启动、功能验证、缺陷修复、复验这几个步骤的提示词中("本项目的验证方法"一节)。')]),i("p",null,"格式自由,建议按下面的结构写,每节给出可以直接复制执行的命令:"),i("div",{class:"language-markdown vp-adaptive-theme"},[i("button",{title:"Copy Code",class:"copy"}),i("span",{class:"lang"},"markdown"),i("pre",{class:"shiki shiki-themes github-light github-dark vp-code",tabindex:"0","v-pre":""},[i("code",null,[i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"# 验证方法")]),s(`
|
|
2
|
+
`),i("span",{class:"line"}),s(`
|
|
3
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"最后核对:2026-10-13(/req-setup,全部命令已运行)")]),s(`
|
|
4
|
+
`),i("span",{class:"line"}),s(`
|
|
5
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 环境准备")]),s(`
|
|
6
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," Node.js 22,pnpm 9")]),s(`
|
|
7
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 安装依赖:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm install`")]),s(`
|
|
8
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 依赖的本地服务:PostgreSQL("),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`docker compose up -d db`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"),Redis 不需要")]),s(`
|
|
9
|
+
`),i("span",{class:"line"}),s(`
|
|
10
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 构建与静态检查")]),s(`
|
|
11
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 类型检查:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm typecheck`")]),s(`
|
|
12
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 代码检查:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm lint`")]),s(`
|
|
13
|
+
`),i("span",{class:"line"}),s(`
|
|
14
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 单元与集成测试")]),s(`
|
|
15
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 全部:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm test`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"(约 2 分钟,基线 412 个用例全部通过)")]),s(`
|
|
16
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 单个文件:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm test path/to/file.test.ts`")]),s(`
|
|
17
|
+
`),i("span",{class:"line"}),s(`
|
|
18
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 启动服务")]),s(`
|
|
19
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 命令:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm dev`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"(在仓库根目录)")]),s(`
|
|
20
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 就绪判断:"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`GET http://localhost:3000/health`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 返回 200,通常 10 秒内")]),s(`
|
|
21
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 停止:结束该进程;端口 3000")]),s(`
|
|
22
|
+
`),i("span",{class:"line"}),s(`
|
|
23
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 端到端验证")]),s(`
|
|
24
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 工具:Playwright,"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`pnpm e2e`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},";或手工用浏览器访问 http://localhost:3000")]),s(`
|
|
25
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 测试账号:见 docs/test-accounts.md(不要写入真实口令)")]),s(`
|
|
26
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 测试替身:短信、支付走 "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`MOCK_EXTERNAL=1`")]),s(`
|
|
27
|
+
`),i("span",{class:"line"}),s(`
|
|
28
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"}},"## 已知问题")]),s(`
|
|
29
|
+
`),i("span",{class:"line"},[i("span",{style:{"--shiki-light":"#E36209","--shiki-dark":"#FFAB70"}},"-"),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}}," `pnpm test`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 中 "),i("span",{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"}},"`report.test.ts`"),i("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}}," 偶发超时,与需求无关")])])])]),i("p",null,[s("其中几分钟内能跑完的检查(格式、lint、类型检查、单元测试、构建)同时写进项目配置 "),i("code",null,".requirement-pipeline.json"),s(" 的 "),i("code",null,"checks"),s("(1.8 起):流水线会在写代码和修复的步骤之后自己运行它们,作为质量门。"),i("code",null,"verify.md"),s(" 写给 agent 看,"),i("code",null,"checks"),s(" 由流水线执行,两处的命令保持一致。")]),i("p",null,[s("步骤 agent 发现它过时或不准确时,会在 "),i("code",null,"service-start.md"),s(" 或 "),i("code",null,"verification.md"),s(' 的"建议写入 verify.md 的内容"一节给出实际可行的做法;'),i("code",null,"/req-setup"),s(" 再次运行时会参考这些建议更新本文件。")])],-1),i("p",{class:"source-note"},[s("本页由仓库中的 "),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/blob/main/contracts/verify.md"},"contracts/verify.md"),s(" 生成。"),i("a",{href:"https://github.com/yiyisf/paseo-req-kit/edit/main/contracts/verify.md"},"在 GitHub 上编辑")],-1)])])}const g=e(n,[["render",h]]);export{o as __pageData,g as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as t,o,c as r,a3 as a}from"./chunks/framework.B9qR_F1m.js";const m=JSON.parse('{"title":"范围","description":"","frontmatter":{"editLink":false},"headers":[],"relativePath":"reference/scope.md","filePath":"reference/scope.md","lastUpdated":null}'),i={name:"reference/scope.md"};function s(c,e,n,p,d,l){return o(),r("div",null,[...e[0]||(e[0]=[a('<div><h1 id="范围" tabindex="-1">范围 <a class="header-anchor" href="#范围" aria-label="Permalink to "范围""></a></h1><p><strong>req-kit 帮助非专职开发的同事(测试、产品、项目经理等),在本地仓库中,把一个需求从对齐做到可验收。</strong></p><p>新的提议须同时满足下面三条才会考虑:</p><ol><li>服务于上面这个目标,而不是通用的编码提效。</li><li>至少有两个真实的使用场景。</li><li>无法通过项目配置(<code>.requirement-pipeline.json</code>)或项目说明(<code>.requirement-pipeline/project-notes.md</code>、<code>verify.md</code>)解决。</li></ol><p>被拒绝的提议记录在 <a href="https://github.com/yiyisf/paseo-req-kit/tree/main/.out-of-scope" target="_blank" rel="noreferrer"><code>.out-of-scope/</code></a> 中,避免反复讨论。</p></div><p class="source-note">本页由仓库中的 <a href="https://github.com/yiyisf/paseo-req-kit/blob/main/SCOPE.md">SCOPE.md</a> 生成。<a href="https://github.com/yiyisf/paseo-req-kit/edit/main/SCOPE.md">在 GitHub 上编辑</a></p>',2)])])}const _=t(i,[["render",s]]);export{m as __pageData,_ as default};
|