@openprd/cli 0.1.11 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/.openprd/changes/adaptive-project-framing/.openprd.yaml +2 -0
  2. package/.openprd/changes/adaptive-project-framing/design.md +47 -0
  3. package/.openprd/changes/adaptive-project-framing/proposal.md +35 -0
  4. package/.openprd/changes/adaptive-project-framing/specs/agent-requirements/spec.md +16 -0
  5. package/.openprd/changes/adaptive-project-framing/task-events.jsonl +20 -0
  6. package/.openprd/changes/adaptive-project-framing/tasks.md +340 -0
  7. package/.openprd/changes/docs-anti-pollution-and-design-direction-review/.openprd.yaml +2 -0
  8. package/.openprd/changes/docs-anti-pollution-and-design-direction-review/design.md +34 -0
  9. package/.openprd/changes/docs-anti-pollution-and-design-direction-review/proposal.md +23 -0
  10. package/.openprd/changes/docs-anti-pollution-and-design-direction-review/specs/agent-requirements/spec.md +16 -0
  11. package/.openprd/changes/docs-anti-pollution-and-design-direction-review/task-events.jsonl +14 -0
  12. package/.openprd/changes/docs-anti-pollution-and-design-direction-review/tasks.md +238 -0
  13. package/.openprd/changes/loop-isolated-worktree-commit/.openprd.yaml +2 -0
  14. package/.openprd/changes/loop-isolated-worktree-commit/design.md +53 -0
  15. package/.openprd/changes/loop-isolated-worktree-commit/proposal.md +38 -0
  16. package/.openprd/changes/loop-isolated-worktree-commit/specs/agent-requirements/spec.md +16 -0
  17. package/.openprd/changes/loop-isolated-worktree-commit/task-events.jsonl +22 -0
  18. package/.openprd/changes/loop-isolated-worktree-commit/tasks.md +357 -0
  19. package/.openprd/changes/openprd/.openprd.yaml +2 -0
  20. package/.openprd/changes/openprd/design.md +46 -0
  21. package/.openprd/changes/openprd/proposal.md +36 -0
  22. package/.openprd/changes/openprd/specs/agent-requirements/spec.md +16 -0
  23. package/.openprd/changes/openprd/task-events.jsonl +23 -0
  24. package/.openprd/changes/openprd/tasks.md +242 -0
  25. package/.openprd/changes/pm-human-in-the-loop/.openprd.yaml +2 -0
  26. package/.openprd/changes/pm-human-in-the-loop/design.md +38 -0
  27. package/.openprd/changes/pm-human-in-the-loop/proposal.md +29 -0
  28. package/.openprd/changes/pm-human-in-the-loop/specs/agent-requirements/spec.md +16 -0
  29. package/.openprd/changes/pm-human-in-the-loop/task-events.jsonl +18 -0
  30. package/.openprd/changes/pm-human-in-the-loop/tasks.md +306 -0
  31. package/.openprd/changes/test-strategy-router/.openprd.yaml +2 -0
  32. package/.openprd/changes/test-strategy-router/design.md +65 -0
  33. package/.openprd/changes/test-strategy-router/proposal.md +45 -0
  34. package/.openprd/changes/test-strategy-router/specs/agent-requirements/spec.md +16 -0
  35. package/.openprd/changes/test-strategy-router/task-events.jsonl +1 -0
  36. package/.openprd/changes/test-strategy-router/tasks.md +132 -0
  37. package/.openprd/changes/verify-boundaries-and-historical-refresh/.openprd.yaml +2 -0
  38. package/.openprd/changes/verify-boundaries-and-historical-refresh/design.md +28 -0
  39. package/.openprd/changes/verify-boundaries-and-historical-refresh/proposal.md +23 -0
  40. package/.openprd/changes/verify-boundaries-and-historical-refresh/specs/agent-requirements/spec.md +16 -0
  41. package/.openprd/changes/verify-boundaries-and-historical-refresh/task-events.jsonl +11 -0
  42. package/.openprd/changes/verify-boundaries-and-historical-refresh/tasks.md +66 -0
  43. package/.openprd/changes/vibe-coding-dev-check/.openprd.yaml +2 -0
  44. package/.openprd/changes/vibe-coding-dev-check/design.md +37 -0
  45. package/.openprd/changes/vibe-coding-dev-check/proposal.md +28 -0
  46. package/.openprd/changes/vibe-coding-dev-check/specs/agent-requirements/spec.md +16 -0
  47. package/.openprd/changes/vibe-coding-dev-check/task-events.jsonl +18 -0
  48. package/.openprd/changes/vibe-coding-dev-check/tasks.md +306 -0
  49. package/.openprd/design/README.md +11 -6
  50. package/.openprd/design/README_EN.md +4 -1
  51. package/.openprd/design/active/asset-spec.md +6 -0
  52. package/.openprd/design/active/direction-plan.md +5 -5
  53. package/.openprd/design/active/selected-direction.md +2 -0
  54. package/.openprd/design/anti-slop.md +26 -1
  55. package/.openprd/design/assets/surface-presets.md +6 -0
  56. package/.openprd/design/checklists/ui-quality-gate.md +7 -0
  57. package/.openprd/design/lenses/frontend-lenses.md +28 -0
  58. package/.openprd/design/recipes/content-experience.md +8 -1
  59. package/.openprd/design/recipes/operational-tool.md +7 -0
  60. package/.openprd/design/recipes/product-launch.md +8 -1
  61. package/.openprd/design/templates/README.md +6 -3
  62. package/.openprd/design/templates/README_EN.md +6 -3
  63. package/.openprd/design/templates/ops-dashboard.html +8 -1
  64. package/.openprd/design/templates/product-launch.html +2 -1
  65. package/.openprd/design/themes/theme-catalog.json +23 -5
  66. package/.openprd/engagements/active/prd.md +103 -100
  67. package/.openprd/standards/config.json +7 -1
  68. package/AGENTS.md +13 -3
  69. package/README.md +107 -14
  70. package/README_EN.md +131 -13
  71. package/package.json +1 -1
  72. package/scripts/dev-check-wrapup-copy.mjs +46 -21
  73. package/skills/openprd-diagram-review/SKILL.md +27 -2
  74. package/skills/openprd-diagram-review/references/explanation-svg-patterns.md +131 -0
  75. package/skills/openprd-discovery-loop/SKILL.md +2 -2
  76. package/skills/openprd-frontend-design/SKILL.md +44 -20
  77. package/skills/openprd-frontend-design/references/design-asset-contract.md +6 -0
  78. package/skills/openprd-frontend-design/references/direction-engine.md +29 -4
  79. package/skills/openprd-harness/SKILL.md +22 -16
  80. package/skills/openprd-quality/SKILL.md +10 -8
  81. package/skills/openprd-requirement-intake/SKILL.md +2 -0
  82. package/skills/openprd-router/SKILL.md +2 -1
  83. package/skills/openprd-shared/SKILL.md +26 -16
  84. package/skills/openprd-standards/SKILL.md +4 -2
  85. package/src/agent-canonical-content.js +808 -0
  86. package/src/agent-integration.js +258 -777
  87. package/src/canvas-app.html.js +2910 -0
  88. package/src/canvas-i18n.js +274 -0
  89. package/src/canvas-workspace.js +2271 -0
  90. package/src/cli/args.js +72 -4
  91. package/src/cli/basic-print.js +3 -0
  92. package/src/cli/canvas-print.js +106 -0
  93. package/src/cli/doctor-print.js +20 -0
  94. package/src/cli/print.js +2 -0
  95. package/src/cli/quality-commands.js +222 -0
  96. package/src/cli/quality-print.js +28 -2
  97. package/src/cli/run-print.js +5 -0
  98. package/src/cli/workflow-print.js +3 -0
  99. package/src/codex-app-server-relay.js +251 -0
  100. package/src/codex-hook-runner-template.mjs +957 -59
  101. package/src/design-starter-support.js +2 -2
  102. package/src/design-starter.js +39 -3
  103. package/src/dev-standards.js +125 -10
  104. package/src/diagram-core.js +6 -20
  105. package/src/discovery.js +2 -8
  106. package/src/docs-compact.js +125 -0
  107. package/src/execution-strategy.js +1 -1
  108. package/src/fleet.js +9 -3
  109. package/src/guide.js +227 -0
  110. package/src/html-artifacts.js +428 -7
  111. package/src/knowledge.js +45 -11
  112. package/src/language-policy.js +63 -3
  113. package/src/learning-review.js +1 -1
  114. package/src/loop.js +1 -1
  115. package/src/openprd.js +68 -131
  116. package/src/openspec/change-validate.js +2 -2
  117. package/src/openspec/constants.js +6 -7
  118. package/src/openspec/execute.js +2 -2
  119. package/src/openspec/generate.js +318 -102
  120. package/src/openspec/migration.js +168 -0
  121. package/src/openspec/paths.js +1 -22
  122. package/src/prd-core.js +1 -1
  123. package/src/quality-visual-review.js +257 -14
  124. package/src/quality.js +46 -8
  125. package/src/review-presentation.js +60 -0
  126. package/src/run-harness.js +41 -3
  127. package/src/session-evidence.js +363 -0
  128. package/src/standards.js +64 -0
  129. package/src/test-strategy.js +7 -4
  130. package/src/visual-compare-centering.js +622 -0
  131. package/src/visual-compare-core.js +1123 -0
  132. package/src/visual-compare.js +620 -698
  133. package/src/workspace-core.js +94 -4
  134. package/src/workspace-workflow.js +46 -1
package/README_EN.md CHANGED
@@ -130,9 +130,18 @@ one human-readable quality surface before handoff, release, or publish.
130
130
  Put the reference and implementation into one side-by-side artifact for staged
131
131
  UI review, especially for auth-entry redesign, localized legal pages, and modal
132
132
  replication work.
133
+ Visual evidence follows the current task language by default: Chinese requests
134
+ produce Chinese labels, English requests produce English labels, and
135
+ `--locale zh-CN` or `--locale en` can pin the output language for side-by-side labels,
136
+ board titles, summaries, and checks.
133
137
 
134
138
  ![Auto-optimized reference-to-screenshot comparison](https://raw.githubusercontent.com/mileson/openprd/main/docs/assets/openprd-visual-compare-case-study-en.png)
135
139
 
140
+ ```bash
141
+ openprd visual-compare . --reference ref.png --actual actual.png --locale zh-CN
142
+ openprd visual-compare . --board verification-board.json --locale en
143
+ ```
144
+
136
145
  ## Self-Evolving Collaboration
137
146
 
138
147
  OpenPrd gets easier to work with over time through two visible loops. One loop
@@ -172,6 +181,7 @@ automatically.
172
181
  - **Project-level benchmark registry**: support `benchmark add / observe / approve / verify` so repeatedly adopted external sources can become durable project references
173
182
  - **Diagram review artifacts**: generate both architecture and product-flow diagrams
174
183
  - **UI visual comparison artifacts**: combine reference images and implementation screenshots into side-by-side JPG reviews for visual replication work
184
+ - **Language-aware visual evidence**: localize comparison labels and board copy from the active request language, with `--locale` / `--lang` overrides when a project needs a fixed output language
175
185
  - **Contract-driven diagrams**: render from validated JSON contracts
176
186
  - **Review status tracking**: use `pending-confirmation`, `confirmed`, and `needs-revision`
177
187
  - **Project release/version ledger**: optionally track project versions such as `0.1.23`, version-scoped change items, and local git tag coordination without mixing them with internal PRD `v000x` versions
@@ -355,16 +365,23 @@ openprd review /path/to/project --mark confirmed --version <id> --digest <sha256
355
365
 
356
366
  `review.html` is the stable review artifact for the current PRD, but the default
357
367
  approval policy is `decision-points`, not “always stop here”. In a normal lane,
358
- the user reviews that stable artifact first and then the exact copied
359
- `--version`, `--digest`, and `--work-unit` tuple is recorded. In a
360
- `silent-record` lane, OpenPrd can record the exact current artifact without an
361
- extra stop only when the user already made direct execution intent explicit and
362
- explicitly opted out of additional review confirmation. Do not treat
363
- implementation approval as permission to mark a different review artifact, and
364
- do not treat review recording as execution authorization. After the current
365
- artifact is recorded, generate the OpenPrd change and task breakdown. If the
366
- user originally asked to implement, execution can continue once tasks are ready;
367
- otherwise wait for an explicit execution request:
368
+ one plain natural-language confirmation (for example “确认这版,继续”, including
369
+ wording with an inline version id such as “确认 v0276 评审稿”) is enough: the
370
+ hook binds it to the exact current `--version`, `--digest`, and `--work-unit`
371
+ tuple automatically, and the agent must never ask the user to paste a digest,
372
+ work-unit id, or a full command. When that confirmation also carries a
373
+ continue-execution intent, or a requirement summary was already confirmed
374
+ earlier, one confirmation authorizes the whole chain: review recording, change,
375
+ tasks, and implementation proceed without further stops (the one-time
376
+ confirmation contract). In a `silent-record` lane, OpenPrd can record the exact
377
+ current artifact without an extra stop only when the user already made direct
378
+ execution intent explicit and explicitly opted out of additional review
379
+ confirmation. Do not treat implementation approval as permission to mark a
380
+ different review artifact, and do not treat review recording as execution
381
+ authorization. After the current artifact is recorded, generate the OpenPrd
382
+ change and task breakdown. If the user originally asked to implement, execution
383
+ can continue once tasks are ready; otherwise wait for an explicit execution
384
+ request:
368
385
 
369
386
  ```bash
370
387
  openprd change /path/to/project --generate --change <change-id>
@@ -501,6 +518,25 @@ the change affects responsibilities, flows, structure, dependencies, or product
501
518
  behavior. If no documentation update is needed, agents should say the check was
502
519
  performed and why the existing docs still match the code.
503
520
 
521
+ ## Image-generation routing: pick the right free tool automatically
522
+
523
+ Image requests (covers, mockups, icons, effect images) follow a three-layer
524
+ routing protocol, so users never have to specify a provider:
525
+
526
+ 1. **Surface built-ins first**: Codex uses native `imagegen` (Image 2), Cursor
527
+ uses the built-in `GenerateImage` tool — both are free inside their surfaces.
528
+ 2. **Persisted preference**: when no built-in tool is available, OpenPrd reads
529
+ the user-confirmed preference from
530
+ `.openprd/harness/image-generation-preference.json` and reuses it silently.
531
+ 3. **Ask once, persist**: only when no preference exists does OpenPrd ask the
532
+ user once, then writes the answer back with a `user-confirmed` source as the
533
+ future default.
534
+
535
+ Cost guardrail: OpenPrd never silently calls the user’s own paid image APIs
536
+ (for example OpenAI or Stability keys) unless the user explicitly picked one.
537
+ The routing contract ships in the install manifest and
538
+ `.openprd/harness/runtime-environment.json` under `imageGenerationRouting`.
539
+
504
540
  ## Auto-optimized reference-to-screenshot comparison
505
541
 
506
542
  When UI work already has a reference effect image, design image, user-provided
@@ -547,6 +583,71 @@ obvious visual differences. The final response for reference-driven UI work
547
583
  should include the generated review image path and note whether differences
548
584
  remain.
549
585
 
586
+ When a new feature or visible change contains repeated homogeneous lists, cards,
587
+ grids, or tables, or when the user reports misalignment, the agent should also
588
+ capture the real UI, overlay guide lines, and measure both container-track and
589
+ internal content-slot coordinate spread in one alignment evidence board:
590
+
591
+ ```bash
592
+ openprd visual-compare /path/to/project \
593
+ --board alignment-board.json
594
+ ```
595
+
596
+ Use `mode: "alignment-board"` in the board JSON. Include the screenshot, guide
597
+ lines, container groups, content-slot groups, and x/y/width/height/baseline
598
+ spread. Container tracks include card edges, columns, row tops, and gaps.
599
+ Internal content slots include titles, subtitles, tags, descriptions, status,
600
+ prices, buttons, icons, and action areas. Repeated card lists, card grids, and
601
+ tables are default triggers even when the user did not explicitly complain
602
+ about alignment; measuring only outer frames, columns, or row tops is not enough.
603
+
604
+ When a single logo, icon, avatar, badge, button graphic, or image crop needs
605
+ internal centering review, or when the user reports that its visual weight feels
606
+ off-center, crop the target if needed and generate a centering evidence board:
607
+
608
+ ```bash
609
+ openprd visual-compare /path/to/project \
610
+ --board centering-board.json
611
+ ```
612
+
613
+ Minimal syntax:
614
+
615
+ ```json
616
+ {
617
+ "mode": "centering-board",
618
+ "title": "Logo internal centering check",
619
+ "image": ".openprd/harness/screenshots/logo.png",
620
+ "thresholdPx": 8,
621
+ "subject": {
622
+ "mode": "auto",
623
+ "weight": "contrast"
624
+ }
625
+ }
626
+ ```
627
+
628
+ If the automatic mask includes background, shadow, or transparent padding, use
629
+ explicit color ranges:
630
+
631
+ ```json
632
+ {
633
+ "mode": "centering-board",
634
+ "image": ".openprd/harness/screenshots/logo.png",
635
+ "subject": {
636
+ "mode": "range",
637
+ "ranges": [
638
+ { "r": [180, 255], "g": [140, 255], "b": [0, 120] },
639
+ { "r": [210, 255], "g": [210, 255], "b": [200, 255] }
640
+ ],
641
+ "weight": "luma"
642
+ }
643
+ }
644
+ ```
645
+
646
+ `centering-board` draws the red canvas center, green active subject bounds, and
647
+ yellow visual centroid, then stores bounding-box center offset and
648
+ visual-centroid offset in metadata. A raw screenshot or subjective “looks
649
+ centered” note is not a substitute for this board.
650
+
550
651
  ## Quality Regression Reports
551
652
 
552
653
  `openprd init` also creates a quality contract:
@@ -584,8 +685,14 @@ scope for the scenario.
584
685
 
585
686
  For UI work with an existing reference image, visual readiness also requires a
586
687
  current `openprd visual-compare` artifact under `.openprd/harness/visual-reviews/`.
587
- If the combined image still shows obvious differences, the task should return to
588
- implementation instead of treating the gap as ready.
688
+ Before/after UI changes require a before/after artifact, screenshot-based
689
+ runtime checks require a verification board, and homogeneous lists, cards,
690
+ grids, or tables require an alignment board that covers both container tracks
691
+ and internal content slots. Single-logo, icon, avatar, badge, button graphic, or
692
+ image-crop internal-centering reviews require a centering board. If the combined image still shows
693
+ obvious differences, coordinate drift, or layout spread beyond the intended
694
+ threshold, the task should return to implementation instead of treating the gap
695
+ as ready.
589
696
 
590
697
  After a fix has been verified and reviewed, promote the abstract pattern into
591
698
  project knowledge:
@@ -688,7 +795,11 @@ task, and can commit that task before moving on.
688
795
  For UI tasks, the loop prompt and generated guidance require the agent to run
689
796
  `openprd visual-compare` before finishing: use `--reference/--actual` when a
690
797
  reference image exists, or `--before/--after` when the agent must verify a UI
691
- change without an explicit reference image.
798
+ change without an explicit reference image. Use `--board <verification-board.json>`
799
+ for screenshot-based runtime evidence, and `--board <alignment-board.json>` for
800
+ homogeneous lists, cards, grids, or tables; the alignment board must cover both
801
+ outer tracks and internal content slots. Use `--board <centering-board.json>` for
802
+ single-element internal-centering or visual-centroid checks.
692
803
 
693
804
  `openprd run --context` may surface loop commands as execution commands, but they
694
805
  are not automatic instructions. Agents should run `openprd loop --run`,
@@ -736,6 +847,13 @@ without launching an agent. Use `--agent codex` or `--agent claude` for the defa
736
847
  CLI integrations. Use `--agent-command "<custom command>"` only when you want to
737
848
  pipe the OpenPrd prompt into a project-specific wrapper.
738
849
 
850
+ User-facing generated docs, progress logs, proposals, prompts, test reports, and
851
+ agent-produced specs/tasks follow the primary language of the current request
852
+ and PRD snapshot. Chinese contexts use Simplified Chinese, English contexts stay
853
+ English, and ambiguous contexts fall back to `zh-CN`; command names, field names,
854
+ paths, APIs, product names, and explicitly `zh-CN` diagram contracts remain
855
+ unchanged.
856
+
739
857
  For historical projects, use `fleet` instead of hand-writing shell loops. By
740
858
  default it scans and reports only, while also telling you how many known
741
859
  OpenPrd workspaces already exist in the global registry and how many are outside
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openprd/cli",
3
- "version": "0.1.11",
3
+ "version": "0.1.18",
4
4
  "description": "AI-native PRD workspace and lifecycle CLI",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,8 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  export const DEV_CHECK_WRAPUP_COPY_LIMIT = 20;
4
- const WRAPUP_FIELDS = ['规模信号', '预警原因', '本次处理结果', '后续建议'];
5
- const VALIDATE_USAGE = 'Usage: echo \'{"rows":[{"影响对象":"src/example.js","规模信号":"701 行(> 700 行/文件)","预警原因":"文件偏大,维护成本升","本次处理结果":"本轮小改,未扩职责","后续建议":"继续改前先拆小"}]}\' | node scripts/dev-check-wrapup-copy.mjs --validate';
4
+ // 自动优化模式(默认)与仅推荐模式使用不同表头;字段别名成对等价。
5
+ const WRAPUP_FIELD_ALIASES = [
6
+ ['源文件规模', '规模信号'],
7
+ ['优化原因', '预警原因'],
8
+ ['本次处理结果'],
9
+ ['后续建议'],
10
+ ];
11
+ const VALIDATE_USAGE = 'Usage: echo \'{"rows":[{"影响对象":"src/example.js","源文件规模":"701 行(> 700 行/文件)","优化原因":"文件偏大,维护成本升","本次处理结果":"本轮小改,未扩职责","后续建议":"继续改前先拆小"}]}\' | node scripts/dev-check-wrapup-copy.mjs --validate(仅推荐模式对应字段为“规模信号 / 预警原因”)';
6
12
 
7
13
  function countChars(value) {
8
14
  return Array.from(String(value ?? ''));
@@ -11,14 +17,15 @@ function countChars(value) {
11
17
  function validateCompactRows(rows = [], limit = DEV_CHECK_WRAPUP_COPY_LIMIT) {
12
18
  for (const [index, row] of rows.entries()) {
13
19
  const rowLabel = row?.影响对象 ? String(row.影响对象) : (row?.影响位置 ? String(row.影响位置) : `第 ${index + 1} 行`);
14
- for (const field of WRAPUP_FIELDS) {
15
- const value = row?.[field];
16
- if (typeof value !== 'string') {
17
- throw new Error(`后续建议校验失败:${rowLabel} 缺少字段“${field}”。${VALIDATE_USAGE}`);
20
+ for (const aliases of WRAPUP_FIELD_ALIASES) {
21
+ const field = aliases.find((name) => typeof row?.[name] === 'string');
22
+ if (!field) {
23
+ throw new Error(`收口表格校验失败:${rowLabel} 缺少字段“${aliases.join('/')}”。${VALIDATE_USAGE}`);
18
24
  }
25
+ const value = row[field];
19
26
  const actual = countChars(value).length;
20
27
  if (actual > limit) {
21
- throw new Error(`后续建议校验失败:${rowLabel} 的“${field}”有 ${actual} 个字,超过 ${limit} 字上限。当前内容:“${value}”。请缩短后重试。`);
28
+ throw new Error(`收口表格校验失败:${rowLabel} 的“${field}”有 ${actual} 个字,超过 ${limit} 字上限。当前内容:“${value}”。请缩短后重试。`);
22
29
  }
23
30
  }
24
31
  }
@@ -56,29 +63,45 @@ function reasonText(file) {
56
63
  return '待补充';
57
64
  }
58
65
 
59
- function currentResultText(file) {
60
- if (file.status === 'warning') return '这次先完成需求,暂不拆分';
61
- if (file.status === 'attention') return '本轮小改,未扩职责';
66
+ function currentResultText(file, autoRefactor) {
67
+ if (file.status === 'warning') {
68
+ return autoRefactor ? '本轮执行拆分后回填' : '这次先完成需求,暂不拆分';
69
+ }
70
+ if (file.status === 'attention') {
71
+ return autoRefactor ? '按需小步拆分后回填' : '本轮小改,未扩职责';
72
+ }
62
73
  if (file.status === 'error') return '本轮失败,未收口';
63
74
  if (file.status === 'ok') return '本轮已回顾';
64
75
  return '待确认';
65
76
  }
66
77
 
67
- function followUpText(file) {
68
- if (file.status === 'warning') return '优先拆出独立职责';
69
- if (file.status === 'attention') return '继续改前先拆小';
78
+ function followUpText(file, autoRefactor) {
79
+ if (file.status === 'warning') {
80
+ return autoRefactor ? '拆完重跑测试验证' : '优先拆出独立职责';
81
+ }
82
+ if (file.status === 'attention') {
83
+ return autoRefactor ? '保持职责边界清晰' : '继续改前先拆小';
84
+ }
70
85
  if (file.status === 'error') return '先修复后重跑';
71
86
  if (file.status === 'ok') return '无需额外动作';
72
87
  return '待确认';
73
88
  }
74
89
 
75
- export function buildCompactDevCheckWrapUpRows(files = []) {
76
- return files.map((file) => ({
77
- 规模信号: thresholdText(file),
78
- 预警原因: reasonText(file),
79
- 本次处理结果: currentResultText(file),
80
- 后续建议: followUpText(file),
81
- }));
90
+ export function buildCompactDevCheckWrapUpRows(files = [], options = {}) {
91
+ const autoRefactor = Boolean(options.autoRefactor);
92
+ return files.map((file) => (autoRefactor
93
+ ? {
94
+ 源文件规模: thresholdText(file),
95
+ 优化原因: reasonText(file),
96
+ 本次处理结果: currentResultText(file, autoRefactor),
97
+ 后续建议: followUpText(file, autoRefactor),
98
+ }
99
+ : {
100
+ 规模信号: thresholdText(file),
101
+ 预警原因: reasonText(file),
102
+ 本次处理结果: currentResultText(file, autoRefactor),
103
+ 后续建议: followUpText(file, autoRefactor),
104
+ }));
82
105
  }
83
106
 
84
107
  async function readStdin() {
@@ -95,7 +118,9 @@ async function main() {
95
118
  const payload = raw.trim() ? JSON.parse(raw) : {};
96
119
  const rows = validateOnly
97
120
  ? (Array.isArray(payload.rows) ? payload.rows : [])
98
- : buildCompactDevCheckWrapUpRows(Array.isArray(payload.files) ? payload.files : []);
121
+ : buildCompactDevCheckWrapUpRows(Array.isArray(payload.files) ? payload.files : [], {
122
+ autoRefactor: Boolean(payload.autoRefactor),
123
+ });
99
124
  validateCompactRows(rows);
100
125
  process.stdout.write(JSON.stringify({
101
126
  ok: true,
@@ -1,25 +1,37 @@
1
1
  ---
2
2
  name: openprd-diagram-review
3
- description: 生成并迭代 OpenPrd 图示产物,供用户确认。适用于架构图、产品流程图、用户旅程、流程图、系统边界图、依赖图,以及 freeze 前的可视化评审场景。
3
+ description: 生成并迭代 OpenPrd 图示产物,供用户确认或理解。适用于解释型 SVG、架构图、产品流程图、用户旅程、流程图、系统边界图、依赖图,以及 freeze 前的可视化评审场景。
4
4
  ---
5
5
 
6
6
  # OpenPrd Diagram Review
7
7
 
8
8
  ## 概览
9
9
 
10
- 这份 skill 用来判断当前需要哪种图、生成可渲染的 diagram contract、调用 OpenPrd 当前支持的渲染能力,并把结果变成和用户往返确认的评审循环,而不是一次性出图。
10
+ 这份 skill 用来判断当前需要哪种图:轻量解释图、正式 diagram contract,或需要用户往返确认的评审循环。不要把所有图都当成 freeze 前评审图;很多时候用户只是需要先看懂问题。
11
11
 
12
12
  ## 动手前
13
13
 
14
14
  1. 读取 `skills/openprd-shared/SKILL.md`
15
15
  2. 重建当前工作区状态,判断用户究竟想确认什么
16
16
  3. 决定用户需要的是:
17
+ - `explanation-svg` 轻量解释图
17
18
  - `architecture` 视图
18
19
  - `product-flow` 视图
19
20
  4. 不要虚构今天还不存在的 OpenPrd diagram 命令
20
21
 
21
22
  ## 图示类型选择
22
23
 
24
+ 当用户在问这些内容时,优先选 `explanation-svg`:
25
+
26
+ - 为什么会这样
27
+ - 这两个方案差在哪里
28
+ - 当前状态怎么走到目标状态
29
+ - 过去、现在、未来的关系
30
+ - 因果、依赖、边界、风险传播
31
+ - Agent 要向用户解释需求场景、问题结构、决策取舍或下一步路径
32
+
33
+ `explanation-svg` 是对话辅助。它可以用内联 SVG、HTML 片段或 Markdown 中的 SVG 代码块表达;它不需要写入 `.openprd/engagements/active/`,也不替代 `openprd diagram`、`review.html`、`visual-compare` 或测试证据。
34
+
23
35
  当用户在问这些内容时,选 `architecture`:
24
36
 
25
37
  - 模块
@@ -41,6 +53,17 @@ description: 生成并迭代 OpenPrd 图示产物,供用户确认。适用于
41
53
 
42
54
  - 当用户行为和流程仍不清楚时,先做 `product-flow` contract
43
55
  - 流程清楚后,再做架构评审
56
+ - 如果只是为了让用户先理解取舍,不进入定稿评审,先给 `explanation-svg`
57
+
58
+ ## 解释型 SVG 规则
59
+
60
+ - 输出顺序优先是:一句结论、SVG 图、最多 3 条补充说明或开放问题。
61
+ - 图中每个节点只放短标签和 1 行例子;正文解释放到图下,不要把 SVG 变成文字墙截图。
62
+ - 优先使用 2 到 5 个节点、明确箭头、颜色分组、虚线边界、少量图例;避免复杂渐变、装饰背景和难读小字。
63
+ - 适合的图形包括:双栏对比、时间线、状态转移、边界/责任图、决策树、风险传播、因果反推。
64
+ - 图中用户可见文案跟随用户当前主语言;中文语境用简体中文,专有名词可保留,但不要在中文语境下整句英文。
65
+ - 如果没有足够事实支撑图中的节点或箭头,先把缺口写成“待确认”,不要把推测画成事实。
66
+ - 需要模板时读取 `references/explanation-svg-patterns.md`。
44
67
 
45
68
  ## 当前工具能力
46
69
 
@@ -52,6 +75,7 @@ description: 生成并迭代 OpenPrd 图示产物,供用户确认。适用于
52
75
 
53
76
  因此:
54
77
 
78
+ - 对 `explanation-svg`,直接在对话或临时 HTML/SVG artifact 中生成轻量图,不声称已进入正式 diagram 评审
55
79
  - 对 `architecture`,直接调用内置命令
56
80
  - 对 `product-flow`,即使还没有专门渲染器,也先生成结构化 contract 和评审清单
57
81
  - 如果工具还没有专用流程渲染器,就不要假装它已经存在
@@ -87,5 +111,6 @@ description: 生成并迭代 OpenPrd 图示产物,供用户确认。适用于
87
111
  ## 需要时阅读这些参考资料
88
112
 
89
113
  - `references/diagram-contracts.md`:架构图和产品流程图 contract
114
+ - `references/explanation-svg-patterns.md`:解释型 SVG 的触发场景、图形模板和文案边界
90
115
  - `references/review-checklist.md`:渲染后应该问用户什么
91
116
  - `references/cocoon-patterns.md`:从 `Cocoon-AI/architecture-diagram-generator` 借来的可复用模式
@@ -0,0 +1,131 @@
1
+ # Explanation SVG Patterns
2
+
3
+ ## Purpose
4
+
5
+ Use explanation SVGs when the user needs to understand a relationship before they need a formal artifact. These diagrams are optimized for comprehension in the conversation, not for approval gates.
6
+
7
+ An explanation SVG should reduce text. The preferred shape is:
8
+
9
+ 1. One sentence conclusion
10
+ 2. One compact SVG
11
+ 3. Up to three short notes or open questions
12
+
13
+ ## When To Use
14
+
15
+ Use an explanation SVG for:
16
+
17
+ - state transitions
18
+ - before / after comparisons
19
+ - current state to target state paths
20
+ - cause and effect chains
21
+ - responsibility or boundary splits
22
+ - risk propagation
23
+ - decision trees
24
+ - trade-off comparisons
25
+ - requirement scenarios with multiple actors or steps
26
+
27
+ Do not use an explanation SVG for:
28
+
29
+ - a single factual answer
30
+ - exact command output or error text
31
+ - legal, security, or compliance wording that must be precise
32
+ - proof of implementation
33
+ - visual acceptance evidence
34
+ - formal PRD review sign-off
35
+
36
+ ## Visual Grammar
37
+
38
+ - Keep the canvas compact, usually 900 to 1200 px wide.
39
+ - Use 2 to 5 main nodes.
40
+ - Put short labels inside nodes; keep supporting text outside the SVG.
41
+ - Use arrows to show direction, not paragraphs.
42
+ - Use dashed outlines for scope or uncertainty.
43
+ - Use muted gray for background or irrelevant history.
44
+ - Use green/teal for target, current, or healthy path.
45
+ - Use amber/red only for risk, blockage, or failure.
46
+ - Keep labels in the user's language. For zh-CN, use Simplified Chinese.
47
+
48
+ ## Pattern Library
49
+
50
+ ### Two-Side Comparison
51
+
52
+ Use when explaining why two approaches feel different.
53
+
54
+ ```svg
55
+ <svg viewBox="0 0 980 360" role="img" aria-label="两种方案对比">
56
+ <rect x="24" y="28" width="440" height="290" rx="18" fill="#f8fafc" stroke="#cbd5e1" stroke-dasharray="8 6"/>
57
+ <rect x="516" y="28" width="440" height="290" rx="18" fill="#ecfdf5" stroke="#14b8a6" stroke-dasharray="8 6"/>
58
+ <text x="52" y="76" font-size="24" font-weight="700" fill="#1f2937">文字优先</text>
59
+ <text x="544" y="76" font-size="24" font-weight="700" fill="#065f46">图解优先</text>
60
+ <rect x="76" y="132" width="280" height="76" rx="12" fill="#fff7ed" stroke="#fdba74"/>
61
+ <text x="216" y="164" text-anchor="middle" font-size="20" font-weight="700" fill="#7c2d12">先解释很多概念</text>
62
+ <text x="216" y="192" text-anchor="middle" font-size="16" fill="#9a3412">用户自己拼结构</text>
63
+ <rect x="568" y="132" width="280" height="76" rx="12" fill="#d1fae5" stroke="#10b981"/>
64
+ <text x="708" y="164" text-anchor="middle" font-size="20" font-weight="700" fill="#065f46">先看到关系</text>
65
+ <text x="708" y="192" text-anchor="middle" font-size="16" fill="#047857">文字只补结论</text>
66
+ <path d="M356 170 H568" stroke="#64748b" stroke-width="3" marker-end="url(#arrow)"/>
67
+ <defs>
68
+ <marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto">
69
+ <path d="M0,0 L0,6 L9,3 z" fill="#64748b"/>
70
+ </marker>
71
+ </defs>
72
+ </svg>
73
+ ```
74
+
75
+ ### State Transition
76
+
77
+ Use when explaining how the current state moves to a future state, and whether history matters.
78
+
79
+ ```svg
80
+ <svg viewBox="0 0 1080 360" role="img" aria-label="状态转移说明">
81
+ <rect x="34" y="40" width="1012" height="250" rx="22" fill="#ffffff" stroke="#cbd5e1" stroke-dasharray="8 6"/>
82
+ <rect x="90" y="130" width="230" height="88" rx="14" fill="#f1f5f9" stroke="#cbd5e1"/>
83
+ <text x="205" y="164" text-anchor="middle" font-size="21" font-weight="700" fill="#64748b">过去状态</text>
84
+ <text x="205" y="194" text-anchor="middle" font-size="16" fill="#94a3b8">不一定重要</text>
85
+ <rect x="424" y="130" width="230" height="88" rx="14" fill="#ccfbf1" stroke="#14b8a6"/>
86
+ <text x="539" y="164" text-anchor="middle" font-size="21" font-weight="700" fill="#0f766e">当前状态</text>
87
+ <text x="539" y="194" text-anchor="middle" font-size="16" fill="#0f766e">决策起点</text>
88
+ <rect x="758" y="130" width="230" height="88" rx="14" fill="#dcfce7" stroke="#22c55e"/>
89
+ <text x="873" y="164" text-anchor="middle" font-size="21" font-weight="700" fill="#166534">未来状态</text>
90
+ <text x="873" y="194" text-anchor="middle" font-size="16" fill="#15803d">下一步结果</text>
91
+ <path d="M320 174 H424" stroke="#cbd5e1" stroke-width="3" marker-end="url(#mutedArrow)"/>
92
+ <path d="M654 174 H758" stroke="#0f766e" stroke-width="5" marker-end="url(#greenArrow)"/>
93
+ <text x="706" y="214" text-anchor="middle" font-size="17" fill="#0f766e">关键转移</text>
94
+ <defs>
95
+ <marker id="mutedArrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto">
96
+ <path d="M0,0 L0,6 L9,3 z" fill="#cbd5e1"/>
97
+ </marker>
98
+ <marker id="greenArrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto">
99
+ <path d="M0,0 L0,6 L9,3 z" fill="#0f766e"/>
100
+ </marker>
101
+ </defs>
102
+ </svg>
103
+ ```
104
+
105
+ ### Boundary Map
106
+
107
+ Use when explaining what belongs in scope, what is adjacent, and what remains outside.
108
+
109
+ ```svg
110
+ <svg viewBox="0 0 980 420" role="img" aria-label="范围边界说明">
111
+ <rect x="46" y="44" width="888" height="310" rx="24" fill="#f8fafc" stroke="#94a3b8" stroke-dasharray="9 7"/>
112
+ <text x="76" y="90" font-size="24" font-weight="700" fill="#334155">本次范围</text>
113
+ <rect x="120" y="142" width="220" height="92" rx="14" fill="#dbeafe" stroke="#3b82f6"/>
114
+ <text x="230" y="178" text-anchor="middle" font-size="20" font-weight="700" fill="#1d4ed8">核心问题</text>
115
+ <text x="230" y="207" text-anchor="middle" font-size="16" fill="#2563eb">必须解决</text>
116
+ <rect x="380" y="142" width="220" height="92" rx="14" fill="#dcfce7" stroke="#22c55e"/>
117
+ <text x="490" y="178" text-anchor="middle" font-size="20" font-weight="700" fill="#166534">可执行动作</text>
118
+ <text x="490" y="207" text-anchor="middle" font-size="16" fill="#15803d">这轮落地</text>
119
+ <rect x="640" y="142" width="220" height="92" rx="14" fill="#fff7ed" stroke="#f59e0b"/>
120
+ <text x="750" y="178" text-anchor="middle" font-size="20" font-weight="700" fill="#92400e">开放问题</text>
121
+ <text x="750" y="207" text-anchor="middle" font-size="16" fill="#b45309">需要确认</text>
122
+ <text x="490" y="300" text-anchor="middle" font-size="18" fill="#64748b">边界外内容只记录,不混成本次失败</text>
123
+ </svg>
124
+ ```
125
+
126
+ ## Copy Rules
127
+
128
+ - The sentence before the diagram should state the takeaway, not repeat every label.
129
+ - The notes after the diagram should explain only what the user must decide or notice.
130
+ - Avoid file names, function names, raw route codes, schema names, and internal gate names unless the user asked for implementation detail.
131
+ - Do not hide uncertainty inside the diagram. Use "待确认" or a dashed node when a claim is inferred.
@@ -173,8 +173,8 @@ hook harness 还会写入:
173
173
 
174
174
  - 使用 `openprd tasks <path> --change <id>` 查看进度和下一个依赖已满足的任务
175
175
  - 当某项任务已经可以通过自己的 `verify` 命令完成时,使用 `openprd tasks <path> --change <id> --advance --verify --item <task-id>`
176
- - 使用 `openprd change <path> --apply --change <id>` 把完成的 change specs 推进到 `openprd/specs`
177
- - 使用 `openprd change <path> --archive --change <id>` 把完成的 change 文件移动到 `openprd/archive/changes`
176
+ - 使用 `openprd change <path> --apply --change <id>` 把完成的 change specs 推进到 `.openprd/specs`
177
+ - 使用 `openprd change <path> --archive --change <id>` 把完成的 change 文件移动到 `.openprd/archive/changes`
178
178
  - 当任务或 discovery pass 改动了基线文档、文件说明书或文件夹 README 时,运行 `openprd standards <path> --verify`
179
179
  - 在声明单个任务完成前,运行本任务最小足够验证并留下 evidence;在阶段收口或声明整体实现就绪前,运行 `openprd quality <path> --verify`;当某个已验证修复应该沉淀为项目级复用经验时,运行 `openprd quality <path> --learn --from <report>`
180
180
  - 如果任务被依赖阻塞,先完成更早的任务 id;不要人工跳过依赖顺序