@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.
- package/.openprd/changes/adaptive-project-framing/.openprd.yaml +2 -0
- package/.openprd/changes/adaptive-project-framing/design.md +47 -0
- package/.openprd/changes/adaptive-project-framing/proposal.md +35 -0
- package/.openprd/changes/adaptive-project-framing/specs/agent-requirements/spec.md +16 -0
- package/.openprd/changes/adaptive-project-framing/task-events.jsonl +20 -0
- package/.openprd/changes/adaptive-project-framing/tasks.md +340 -0
- package/.openprd/changes/docs-anti-pollution-and-design-direction-review/.openprd.yaml +2 -0
- package/.openprd/changes/docs-anti-pollution-and-design-direction-review/design.md +34 -0
- package/.openprd/changes/docs-anti-pollution-and-design-direction-review/proposal.md +23 -0
- package/.openprd/changes/docs-anti-pollution-and-design-direction-review/specs/agent-requirements/spec.md +16 -0
- package/.openprd/changes/docs-anti-pollution-and-design-direction-review/task-events.jsonl +14 -0
- package/.openprd/changes/docs-anti-pollution-and-design-direction-review/tasks.md +238 -0
- package/.openprd/changes/loop-isolated-worktree-commit/.openprd.yaml +2 -0
- package/.openprd/changes/loop-isolated-worktree-commit/design.md +53 -0
- package/.openprd/changes/loop-isolated-worktree-commit/proposal.md +38 -0
- package/.openprd/changes/loop-isolated-worktree-commit/specs/agent-requirements/spec.md +16 -0
- package/.openprd/changes/loop-isolated-worktree-commit/task-events.jsonl +22 -0
- package/.openprd/changes/loop-isolated-worktree-commit/tasks.md +357 -0
- package/.openprd/changes/openprd/.openprd.yaml +2 -0
- package/.openprd/changes/openprd/design.md +46 -0
- package/.openprd/changes/openprd/proposal.md +36 -0
- package/.openprd/changes/openprd/specs/agent-requirements/spec.md +16 -0
- package/.openprd/changes/openprd/task-events.jsonl +23 -0
- package/.openprd/changes/openprd/tasks.md +242 -0
- package/.openprd/changes/pm-human-in-the-loop/.openprd.yaml +2 -0
- package/.openprd/changes/pm-human-in-the-loop/design.md +38 -0
- package/.openprd/changes/pm-human-in-the-loop/proposal.md +29 -0
- package/.openprd/changes/pm-human-in-the-loop/specs/agent-requirements/spec.md +16 -0
- package/.openprd/changes/pm-human-in-the-loop/task-events.jsonl +18 -0
- package/.openprd/changes/pm-human-in-the-loop/tasks.md +306 -0
- package/.openprd/changes/test-strategy-router/.openprd.yaml +2 -0
- package/.openprd/changes/test-strategy-router/design.md +65 -0
- package/.openprd/changes/test-strategy-router/proposal.md +45 -0
- package/.openprd/changes/test-strategy-router/specs/agent-requirements/spec.md +16 -0
- package/.openprd/changes/test-strategy-router/task-events.jsonl +1 -0
- package/.openprd/changes/test-strategy-router/tasks.md +132 -0
- package/.openprd/changes/verify-boundaries-and-historical-refresh/.openprd.yaml +2 -0
- package/.openprd/changes/verify-boundaries-and-historical-refresh/design.md +28 -0
- package/.openprd/changes/verify-boundaries-and-historical-refresh/proposal.md +23 -0
- package/.openprd/changes/verify-boundaries-and-historical-refresh/specs/agent-requirements/spec.md +16 -0
- package/.openprd/changes/verify-boundaries-and-historical-refresh/task-events.jsonl +11 -0
- package/.openprd/changes/verify-boundaries-and-historical-refresh/tasks.md +66 -0
- package/.openprd/changes/vibe-coding-dev-check/.openprd.yaml +2 -0
- package/.openprd/changes/vibe-coding-dev-check/design.md +37 -0
- package/.openprd/changes/vibe-coding-dev-check/proposal.md +28 -0
- package/.openprd/changes/vibe-coding-dev-check/specs/agent-requirements/spec.md +16 -0
- package/.openprd/changes/vibe-coding-dev-check/task-events.jsonl +18 -0
- package/.openprd/changes/vibe-coding-dev-check/tasks.md +306 -0
- package/.openprd/design/README.md +11 -6
- package/.openprd/design/README_EN.md +4 -1
- package/.openprd/design/active/asset-spec.md +6 -0
- package/.openprd/design/active/direction-plan.md +5 -5
- package/.openprd/design/active/selected-direction.md +2 -0
- package/.openprd/design/anti-slop.md +26 -1
- package/.openprd/design/assets/surface-presets.md +6 -0
- package/.openprd/design/checklists/ui-quality-gate.md +7 -0
- package/.openprd/design/lenses/frontend-lenses.md +28 -0
- package/.openprd/design/recipes/content-experience.md +8 -1
- package/.openprd/design/recipes/operational-tool.md +7 -0
- package/.openprd/design/recipes/product-launch.md +8 -1
- package/.openprd/design/templates/README.md +6 -3
- package/.openprd/design/templates/README_EN.md +6 -3
- package/.openprd/design/templates/ops-dashboard.html +8 -1
- package/.openprd/design/templates/product-launch.html +2 -1
- package/.openprd/design/themes/theme-catalog.json +23 -5
- package/.openprd/engagements/active/prd.md +103 -100
- package/.openprd/standards/config.json +7 -1
- package/AGENTS.md +13 -3
- package/README.md +107 -14
- package/README_EN.md +131 -13
- package/package.json +1 -1
- package/scripts/dev-check-wrapup-copy.mjs +46 -21
- package/skills/openprd-diagram-review/SKILL.md +27 -2
- package/skills/openprd-diagram-review/references/explanation-svg-patterns.md +131 -0
- package/skills/openprd-discovery-loop/SKILL.md +2 -2
- package/skills/openprd-frontend-design/SKILL.md +44 -20
- package/skills/openprd-frontend-design/references/design-asset-contract.md +6 -0
- package/skills/openprd-frontend-design/references/direction-engine.md +29 -4
- package/skills/openprd-harness/SKILL.md +22 -16
- package/skills/openprd-quality/SKILL.md +10 -8
- package/skills/openprd-requirement-intake/SKILL.md +2 -0
- package/skills/openprd-router/SKILL.md +2 -1
- package/skills/openprd-shared/SKILL.md +26 -16
- package/skills/openprd-standards/SKILL.md +4 -2
- package/src/agent-canonical-content.js +808 -0
- package/src/agent-integration.js +258 -777
- package/src/canvas-app.html.js +2910 -0
- package/src/canvas-i18n.js +274 -0
- package/src/canvas-workspace.js +2271 -0
- package/src/cli/args.js +72 -4
- package/src/cli/basic-print.js +3 -0
- package/src/cli/canvas-print.js +106 -0
- package/src/cli/doctor-print.js +20 -0
- package/src/cli/print.js +2 -0
- package/src/cli/quality-commands.js +222 -0
- package/src/cli/quality-print.js +28 -2
- package/src/cli/run-print.js +5 -0
- package/src/cli/workflow-print.js +3 -0
- package/src/codex-app-server-relay.js +251 -0
- package/src/codex-hook-runner-template.mjs +957 -59
- package/src/design-starter-support.js +2 -2
- package/src/design-starter.js +39 -3
- package/src/dev-standards.js +125 -10
- package/src/diagram-core.js +6 -20
- package/src/discovery.js +2 -8
- package/src/docs-compact.js +125 -0
- package/src/execution-strategy.js +1 -1
- package/src/fleet.js +9 -3
- package/src/guide.js +227 -0
- package/src/html-artifacts.js +428 -7
- package/src/knowledge.js +45 -11
- package/src/language-policy.js +63 -3
- package/src/learning-review.js +1 -1
- package/src/loop.js +1 -1
- package/src/openprd.js +68 -131
- package/src/openspec/change-validate.js +2 -2
- package/src/openspec/constants.js +6 -7
- package/src/openspec/execute.js +2 -2
- package/src/openspec/generate.js +318 -102
- package/src/openspec/migration.js +168 -0
- package/src/openspec/paths.js +1 -22
- package/src/prd-core.js +1 -1
- package/src/quality-visual-review.js +257 -14
- package/src/quality.js +46 -8
- package/src/review-presentation.js +60 -0
- package/src/run-harness.js +41 -3
- package/src/session-evidence.js +363 -0
- package/src/standards.js +64 -0
- package/src/test-strategy.js +7 -4
- package/src/visual-compare-centering.js +622 -0
- package/src/visual-compare-core.js +1123 -0
- package/src/visual-compare.js +620 -698
- package/src/workspace-core.js +94 -4
- 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
|

|
|
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
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
588
|
-
|
|
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,8 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
export const DEV_CHECK_WRAPUP_COPY_LIMIT = 20;
|
|
4
|
-
|
|
5
|
-
const
|
|
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
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
17
|
-
throw new Error(
|
|
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(
|
|
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')
|
|
61
|
-
|
|
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')
|
|
69
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
3
|
+
description: 生成并迭代 OpenPrd 图示产物,供用户确认或理解。适用于解释型 SVG、架构图、产品流程图、用户旅程、流程图、系统边界图、依赖图,以及 freeze 前的可视化评审场景。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OpenPrd Diagram Review
|
|
7
7
|
|
|
8
8
|
## 概览
|
|
9
9
|
|
|
10
|
-
这份 skill
|
|
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 推进到
|
|
177
|
-
- 使用 `openprd change <path> --archive --change <id>` 把完成的 change 文件移动到
|
|
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;不要人工跳过依赖顺序
|