@openprd/cli 0.1.9 → 0.1.10
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/benchmarks/index.md +15 -1
- package/.openprd/config.yaml +10 -0
- package/.openprd/design/README.md +47 -0
- package/.openprd/design/README_EN.md +25 -0
- package/.openprd/design/active/asset-spec.md +15 -0
- package/.openprd/design/active/direction-plan.md +7 -0
- package/.openprd/design/active/facts-sheet.md +13 -0
- package/.openprd/design/active/image-preflight.md +9 -0
- package/.openprd/design/active/selected-direction.md +11 -0
- package/.openprd/design/anti-slop.md +16 -0
- package/.openprd/design/assets/dark-mesh.svg +14 -0
- package/.openprd/design/assets/paper-grid.svg +14 -0
- package/.openprd/design/assets/surface-presets.md +21 -0
- package/.openprd/design/assets/workbench-grid.svg +16 -0
- package/.openprd/design/checklists/ui-quality-gate.md +22 -0
- package/.openprd/design/components/component-catalog.md +42 -0
- package/.openprd/design/layouts/layout-catalog.json +45 -0
- package/.openprd/design/lenses/frontend-lenses.md +31 -0
- package/.openprd/design/recipes/content-experience.md +26 -0
- package/.openprd/design/recipes/operational-tool.md +25 -0
- package/.openprd/design/recipes/product-launch.md +26 -0
- package/.openprd/design/templates/README.md +36 -0
- package/.openprd/design/templates/README_EN.md +31 -0
- package/.openprd/design/templates/content-home.html +415 -0
- package/.openprd/design/templates/ops-dashboard.html +340 -0
- package/.openprd/design/templates/product-launch.html +360 -0
- package/.openprd/design/themes/theme-catalog.json +77 -0
- package/.openprd/engagements/active/prd.md +111 -100
- package/.openprd/schema/prd.schema.yaml +10 -0
- package/.openprd/templates/base/intake.md +4 -0
- package/.openprd/templates/base/prd.md +16 -6
- package/AGENTS.md +10 -7
- package/README.md +26 -28
- package/README_EN.md +3 -3
- package/package.json +41 -2
- package/scripts/openprd-codex-isolated-worker.mjs +799 -0
- package/skills/openprd-benchmark-router/SKILL.md +4 -0
- package/skills/openprd-frontend-design/SKILL.md +161 -0
- package/skills/openprd-frontend-design/references/design-asset-contract.md +34 -0
- package/skills/openprd-frontend-design/references/direction-engine.md +46 -0
- package/skills/openprd-harness/SKILL.md +37 -20
- package/skills/openprd-learning-review/SKILL.md +2 -1
- package/skills/openprd-learning-review/references/style-packs/xianxia-cultivation.prompt.md +1 -1
- package/skills/openprd-quality/SKILL.md +5 -3
- package/skills/openprd-requirement-intake/SKILL.md +27 -5
- package/skills/openprd-requirement-intake/references/prd-template-lenses.md +6 -3
- package/skills/openprd-requirement-intake/references/routing-rubric.md +9 -5
- package/skills/openprd-requirement-intake/references/startup-validation-lens.md +23 -0
- package/skills/openprd-router/SKILL.md +13 -5
- package/skills/openprd-shared/SKILL.md +38 -25
- package/src/agent-integration.js +120 -69
- package/src/brainstorm-artifacts.js +1657 -0
- package/src/brainstorm-presentation.js +223 -0
- package/src/brainstorm.js +603 -0
- package/src/cli/args.js +51 -3
- package/src/cli/doctor-print.js +34 -8
- package/src/cli/print.js +6 -0
- package/src/cli/quality-print.js +70 -0
- package/src/cli/run-print.js +43 -1
- package/src/cli/shared-print.js +33 -2
- package/src/cli/workflow-print.js +21 -0
- package/src/codex-hook-runner-template.mjs +838 -58
- package/src/design-starter-support.js +462 -0
- package/src/design-starter.js +1207 -0
- package/src/knowledge.js +232 -20
- package/src/learning-review.js +3 -3
- package/src/loop.js +839 -101
- package/src/openprd.js +86 -1
- package/src/openspec/change-validate.js +1 -0
- package/src/prd-core.js +18 -0
- package/src/quality-learning.js +50 -6
- package/src/quality.js +2 -2
- package/src/run-harness.js +191 -29
- package/src/self-update.js +301 -4
- package/src/standards.js +46 -5
- package/src/visual-prepare.js +940 -0
- package/src/workspace-core.js +137 -0
- package/src/workspace-workflow.js +190 -7
- package/.openprd/benchmarks/evidence/milvus-io-ai-code-review-gets-better-when-models-debate-claude-vs-gemini-vs-code.md +0 -14
- package/.openprd/benchmarks/evidence/nolanlawson-com-using-ai-to-write-better-code-more-slowly.md +0 -14
- package/.openprd/discovery/config.json +0 -35
- package/.openprd/engagements/active/flows.md +0 -35
- package/.openprd/engagements/active/handoff.md +0 -16
- package/.openprd/engagements/active/review.html +0 -61
- package/.openprd/engagements/active/roles.md +0 -22
- package/.openprd/engagements/work-units/wu-20260524015648-6d33ded7.json +0 -23
- package/.openprd/engagements/work-units/wu-20260602113956-a99b5b88.json +0 -18
- package/.openprd/engagements/work-units/wu-20260602122244-78656aaf.json +0 -18
- package/.openprd/engagements/work-units/wu-20260602122442-e96489e2.json +0 -18
- package/.openprd/engagements/work-units/wu-20260602132835-695429e8.json +0 -18
- package/.openprd/exports/.gitkeep +0 -0
- package/.openprd/knowledge/candidates/candidate-turn-1780116203372-5f266a79e968c758/candidate.json +0 -78
- package/.openprd/knowledge/candidates/candidate-turn-1780116203372-5f266a79e968c758/diagnostic-report.json +0 -129
- package/.openprd/knowledge/candidates/candidate-turn-1780116203372-5f266a79e968c758/root-cause-candidates.json +0 -41
- package/.openprd/knowledge/candidates/candidate-turn-1780116203372-5f266a79e968c758/timeline.json +0 -14
- package/.openprd/knowledge/drafts/openprd-experience-diagnostic-candidate-turn-1780116203372-5f266a79e968c758/SKILL.md +0 -49
- package/.openprd/knowledge/index.json +0 -47
- package/.openprd/reviews/v0001.html +0 -1322
- package/.openprd/reviews/v0002.html +0 -1150
- package/.openprd/reviews/v0003.html +0 -1150
- package/.openprd/reviews/v0004.html +0 -1150
- package/.openprd/reviews/v0005.html +0 -1150
- package/.openprd/sessions/.gitkeep +0 -0
- package/.openprd/state/changes.json +0 -27
- package/.openprd/state/current.json +0 -505
- package/.openprd/state/release-ledger.json +0 -387
- package/.openprd/state/version-index.json +0 -67
- package/.openprd/state/versions/.gitkeep +0 -0
- package/.openprd/state/versions/v0001.json +0 -121
- package/.openprd/state/versions/v0001.md +0 -161
- package/.openprd/state/versions/v0002.json +0 -264
- package/.openprd/state/versions/v0002.md +0 -183
- package/.openprd/state/versions/v0003.json +0 -269
- package/.openprd/state/versions/v0003.md +0 -188
- package/.openprd/state/versions/v0004.json +0 -274
- package/.openprd/state/versions/v0004.md +0 -193
- package/.openprd/state/versions/v0005.json +0 -299
- package/.openprd/state/versions/v0005.md +0 -189
- package/docs/assets/openprd-capability-overview-en.png +0 -0
- package/docs/assets/openprd-capability-overview-zh.png +0 -0
- package/docs/assets/openprd-learning-html.png +0 -0
- package/docs/assets/openprd-quality-html.png +0 -0
- package/docs/assets/openprd-requirement-routing-en.png +0 -0
- package/docs/assets/openprd-requirement-routing-en.svg +0 -102
- package/docs/assets/openprd-requirement-routing-zh-refined.png +0 -0
- package/docs/assets/openprd-requirement-routing-zh.png +0 -0
- package/docs/assets/openprd-requirement-routing-zh.svg +0 -102
- package/docs/assets/openprd-review-html.png +0 -0
- package/docs/assets/openprd-scenario-overview.png +0 -0
- package/docs/assets/openprd-scenario-overview.svg +0 -114
- package/docs/assets/openprd-self-evolving-mechanisms-en.png +0 -0
- package/docs/assets/openprd-self-evolving-mechanisms-zh.png +0 -0
- package/docs/assets/openprd-visual-compare-case-study-en.png +0 -0
- package/docs/assets/openprd-visual-compare-case-study-zh.png +0 -0
package/src/cli/args.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
function parseCommandArgs(argv) {
|
|
21
21
|
const args = [...argv];
|
|
22
|
-
const flags = { json: false, force: false, fix: false, open: false, append: false, init: false, check: false, review: false, reject: false, resume: false, advance: false, verify: false, evidenceRequired: false, next: false, generate: false, validate: false, apply: false, archive: false, activate: false, close: false, keep: false, write: false, dryRun: false, repairAgent: false, fleet: false, updateOpenprd: false, backfillWorkUnits: false, syncRegistry: false, setupMissing: false, doctor: false, context: false, recordHook: false, hookInject: false, plan: false, prompt: false, loopRun: false, finish: false, commit: false, html: false, template: false, failOnViolation: false, mark: null, type: 'architecture', mode: 'auto', input: null, field: null, value: null, set: null, jsonFile: null, artifactMarkdown: null, contentJson: null, presentation: null, source: null, reference: null, actual: null, before: null, after: null, board: null, out: null, format: null, quality: null, maxPanelWidth: null, referenceLabel: null, actualLabel: null, classifyExternal: null, maxIterations: null, maxDepth: null, include: null, exclude: null, report: null, item: null, id: null, status: null, claim: null, notes: null, reason: null, confidence: null, threshold: null, change: null, tools: 'all', hookProfile: null, templatePack: null, target: 'openprd', targetRoot: null, path: null, productType: null, title: null, owner: null, problem: null, whyNow: null, evidence: null, from: null, to: null, version: null, digest: null, workUnit: null, event: null, risk: null, outcome: null, preview: null, learn: null, genre: null, style: null, topic: null, enable: false, disable: false, agent: 'codex', agentCommand: null, message: null };
|
|
22
|
+
const flags = { json: false, force: false, fix: false, open: false, append: false, init: false, check: false, review: false, reject: false, resume: false, advance: false, verify: false, evidenceRequired: false, next: false, generate: false, validate: false, apply: false, archive: false, activate: false, close: false, keep: false, write: false, dryRun: false, repairAgent: false, allowDirtyMain: false, fleet: false, updateOpenprd: false, backfillWorkUnits: false, syncRegistry: false, setupMissing: false, doctor: false, context: false, recordHook: false, hookInject: false, plan: false, prompt: false, loopRun: false, finish: false, commit: false, html: false, template: false, failOnViolation: false, noExternalFacts: false, noBrandAssets: false, noRealImages: false, mark: null, type: 'architecture', mode: 'auto', input: null, field: null, value: null, set: null, jsonFile: null, artifactMarkdown: null, contentJson: null, presentation: null, source: null, reference: null, actual: null, before: null, after: null, board: null, grid: null, boxes: null, out: null, format: null, quality: null, maxPanelWidth: null, referenceLabel: null, actualLabel: null, classifyExternal: null, maxIterations: null, maxDepth: null, include: null, exclude: null, report: null, item: null, id: null, status: null, claim: null, notes: null, reason: null, confidence: null, threshold: null, change: null, starter: null, sections: null, brief: null, tools: 'all', hookProfile: null, templatePack: null, target: 'openprd', targetRoot: null, path: null, productType: null, title: null, owner: null, problem: null, whyNow: null, evidence: null, from: null, to: null, version: null, digest: null, workUnit: null, event: null, risk: null, outcome: null, preview: null, learn: null, genre: null, style: null, topic: null, enable: false, disable: false, agent: 'codex', agentCommand: null, worktree: null, branch: null, message: null };
|
|
23
23
|
const positionals = [];
|
|
24
24
|
|
|
25
25
|
while (args.length > 0) {
|
|
@@ -120,6 +120,10 @@ function parseCommandArgs(argv) {
|
|
|
120
120
|
flags.repairAgent = true;
|
|
121
121
|
continue;
|
|
122
122
|
}
|
|
123
|
+
if (arg === '--allow-dirty-main') {
|
|
124
|
+
flags.allowDirtyMain = true;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
123
127
|
if (arg === '--fleet') {
|
|
124
128
|
flags.fleet = true;
|
|
125
129
|
continue;
|
|
@@ -220,6 +224,14 @@ function parseCommandArgs(argv) {
|
|
|
220
224
|
flags.agentCommand = args.shift() ?? null;
|
|
221
225
|
continue;
|
|
222
226
|
}
|
|
227
|
+
if (arg === '--worktree') {
|
|
228
|
+
flags.worktree = args.shift() ?? null;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (arg === '--branch') {
|
|
232
|
+
flags.branch = args.shift() ?? null;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
223
235
|
if (arg === '--product-type' || arg === '-P') {
|
|
224
236
|
flags.productType = args.shift() ?? null;
|
|
225
237
|
continue;
|
|
@@ -288,6 +300,14 @@ function parseCommandArgs(argv) {
|
|
|
288
300
|
flags.board = args.shift() ?? null;
|
|
289
301
|
continue;
|
|
290
302
|
}
|
|
303
|
+
if (arg === '--grid') {
|
|
304
|
+
flags.grid = args.shift() ?? null;
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
if (arg === '--boxes') {
|
|
308
|
+
flags.boxes = args.shift() ?? null;
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
291
311
|
if (arg === '--out') {
|
|
292
312
|
flags.out = args.shift() ?? null;
|
|
293
313
|
continue;
|
|
@@ -372,6 +392,30 @@ function parseCommandArgs(argv) {
|
|
|
372
392
|
flags.change = args.shift() ?? null;
|
|
373
393
|
continue;
|
|
374
394
|
}
|
|
395
|
+
if (arg === '--starter') {
|
|
396
|
+
flags.starter = args.shift() ?? null;
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
if (arg === '--brief') {
|
|
400
|
+
flags.brief = args.shift() ?? null;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (arg === '--sections') {
|
|
404
|
+
flags.sections = args.shift() ?? null;
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (arg === '--no-external-facts') {
|
|
408
|
+
flags.noExternalFacts = true;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (arg === '--no-brand-assets') {
|
|
412
|
+
flags.noBrandAssets = true;
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
if (arg === '--no-real-images') {
|
|
416
|
+
flags.noRealImages = true;
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
375
419
|
if (arg === '--title') {
|
|
376
420
|
flags.title = args.shift() ?? null;
|
|
377
421
|
continue;
|
|
@@ -478,26 +522,30 @@ function usage() {
|
|
|
478
522
|
' openprd init [path] [--template-pack <base|consumer|b2b|agent>] [--tools <all|codex,claude,cursor>] [--hook-profile <lite|guarded|full>] [--force]',
|
|
479
523
|
' openprd setup [path] [--tools <all|codex,claude,cursor>] [--hook-profile <lite|guarded|full>] [--force] [--json]',
|
|
480
524
|
' openprd update [path] [--tools <all|codex,claude,cursor>] [--hook-profile <lite|guarded|full>] [--force] [--json]',
|
|
481
|
-
' openprd self-update [--dry-run] [--json]',
|
|
525
|
+
' openprd self-update [--check] [--dry-run] [--json]',
|
|
482
526
|
' openprd upgrade [path] [--fleet] [--dry-run] [--tools <all|codex,claude,cursor>] [--hook-profile <lite|guarded|full>] [--max-depth <n>] [--include <csv>] [--exclude <csv>] [--report <file>] [--force] [--json]',
|
|
483
527
|
' openprd doctor [path] [--tools <all|codex,claude,cursor>] [--hook-profile <lite|guarded|full>] [--fix] [--json]',
|
|
484
528
|
' openprd fleet <root> [--dry-run|--doctor|--update-openprd|--backfill-work-units|--sync-registry|--setup-missing] [--hook-profile <lite|guarded|full>] [--max-depth <n>] [--include <csv>] [--exclude <csv>] [--report <file>] [--json]',
|
|
485
529
|
' openprd run [path] [--context|--verify|--record-hook --event <name> --risk <level> --outcome <text> --preview <text>] [--message <text>] [--json]',
|
|
486
|
-
' openprd loop [path] [--init|--plan|--next|--prompt|--run|--verify|--finish] [--change <id>] [--item <task-id-or-handle>] [--agent <codex|claude>] [--agent-command <cmd>] [--repair-agent] [--commit] [--dry-run] [--message <text>] [--json]',
|
|
530
|
+
' openprd loop [path] [--init|--plan|--next|--prompt|--run|--verify|--finish] [--change <id>] [--item <task-id-or-handle>] [--agent <codex|claude>] [--agent-command <cmd>] [--repair-agent] [--worktree <path>] [--branch <name>] [--allow-dirty-main] [--commit] [--dry-run] [--message <text>] [--json]',
|
|
487
531
|
' openprd classify [path] <consumer|b2b|agent>',
|
|
488
532
|
' openprd clarify [path] [--mode <auto|inline|inline-with-checklist>] [--json]',
|
|
489
533
|
' openprd capture [path] (--field <section.path> --value <text|json> | --json-file <answers.json> | --artifact-markdown <artifact.md>) [--source <user-confirmed|project-derived|agent-inferred|agent-normalized>] [--append] [--json]',
|
|
490
534
|
' openprd interview [path] [--product-type <consumer|b2b|agent>]',
|
|
491
535
|
' openprd playground [path] [--open] [--json]',
|
|
536
|
+
' openprd brainstorm [path] [--topic <text>] [--open] [--json]',
|
|
492
537
|
' openprd learn [path] [--topic <text>] [--genre <internet-product|scientific|fairy-tale|web-novel|xianxia>] [--style <substyle>] [--source <workspace|docs|loop|all>] [--content-json <file>] [--open] [--enable|--disable] [--json]',
|
|
493
538
|
' openprd quality [path] [--init|--verify|--report --html|--learn [--review] --from <report-id-or-json-or-diagnostics-or-turn-state>] [--force] [--json]',
|
|
494
539
|
' openprd knowledge <candidates|reject|archive|restore> [path-or-id] [--status <pending-review|all|rejected|archived|promoted|merged>] [--id <candidate-id>] [--reason <text>] [--json]',
|
|
540
|
+
' openprd visual-prepare [path] --reference <effect-image> ((--grid <columns>x<rows>) | (--boxes <plan.json>)) [--include <csv>] [--id <reference-set-id>] [--title <text>] [--out <dir>] [--json]',
|
|
495
541
|
' openprd visual-compare [path] ((--reference <effect-image> --actual <screenshot-image>) | (--before <before-screenshot> --after <after-screenshot>) | --board <board.json>) [--out <file.jpg>] [--format <jpg|png|webp>] [--quality <1..100>] [--max-panel-width <px>] [--json]',
|
|
542
|
+
' openprd design-starter [path] [--starter <content-home|product-launch|ops-dashboard>] [--out <index.html>] [--title <name>] [--brief <text>] [--sections <a|b|c>] [--no-external-facts] [--no-brand-assets] [--no-real-images] [--force] [--json]',
|
|
496
543
|
' openprd dev-check [path] <file...> [--json]',
|
|
497
544
|
' openprd grow [path] [--review|--apply --id <candidate-id>|--reject --id <candidate-id>|--init|--check] [--notes <text>] [--json]',
|
|
498
545
|
' openprd benchmark <add|observe|list|approve|verify> [target-or-id] [path-for-list-or-verify] [--path <project>] [--notes <text>] [--threshold <n>] [--id <benchmark-id>] [--json]',
|
|
499
546
|
' openprd synthesize [path] [--title <text>] [--owner <text>] [--problem <text>] [--why-now <text>] [--work-unit <id>] [--target-root <path>] [--open] [--json]',
|
|
500
547
|
' openprd review [path] [--open] [--mark <pending-confirmation|confirmed|needs-revision>] [--version <id>] [--digest <sha256>] [--work-unit <id>] [--notes <text>] [--json]',
|
|
548
|
+
' openprd brainstorm-presentation [path] [--template] [--presentation <json>] [--write] [--fail-on-violation] [--json]',
|
|
501
549
|
' openprd review-presentation [path] [--template] [--version <id>] [--presentation <json>] [--write] [--fail-on-violation] [--json]',
|
|
502
550
|
' openprd diagram [path] [--type <architecture|product-flow>] [--input <contract.json>] [--mark <pending-confirmation|confirmed|needs-revision>] [--open] [--json]',
|
|
503
551
|
' openprd diff [path] [--from <version>] [--to <version>]',
|
package/src/cli/doctor-print.js
CHANGED
|
@@ -200,17 +200,32 @@ function printSelfUpdateResult(result, json) {
|
|
|
200
200
|
return;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
const status = result.
|
|
204
|
-
? '
|
|
205
|
-
: result.
|
|
206
|
-
? '
|
|
207
|
-
: result.
|
|
208
|
-
? '
|
|
209
|
-
:
|
|
203
|
+
const status = result.checkOnly
|
|
204
|
+
? result.ok ? '检查完成' : '检查失败'
|
|
205
|
+
: result.dryRun
|
|
206
|
+
? '预演'
|
|
207
|
+
: result.ok
|
|
208
|
+
? '完成'
|
|
209
|
+
: result.skipped
|
|
210
|
+
? '已跳过'
|
|
211
|
+
: '失败';
|
|
210
212
|
console.log(`OpenPrd self-update: ${status}`);
|
|
211
213
|
console.log(`当前版本: ${result.package?.version ?? 'unknown'}`);
|
|
214
|
+
if (result.publishedVersion) {
|
|
215
|
+
console.log(`已发布版本: ${result.publishedVersion}`);
|
|
216
|
+
}
|
|
217
|
+
if (result.comparison === 'behind') {
|
|
218
|
+
console.log('版本关系: 当前安装版本落后于 npm 已发布版本');
|
|
219
|
+
} else if (result.comparison === 'same') {
|
|
220
|
+
console.log('版本关系: 当前安装版本已经是 npm 最新版本');
|
|
221
|
+
} else if (result.comparison === 'ahead') {
|
|
222
|
+
console.log('版本关系: 当前安装版本高于 npm 已发布版本');
|
|
223
|
+
}
|
|
212
224
|
console.log(`安装源: ${result.source}`);
|
|
213
|
-
|
|
225
|
+
if (result.versionCheck?.command?.display) {
|
|
226
|
+
console.log(`检查命令: ${result.versionCheck.command.display}`);
|
|
227
|
+
}
|
|
228
|
+
console.log(`计划命令: ${result.installCommand?.display ?? 'N/A'}`);
|
|
214
229
|
if (result.localCheckout) {
|
|
215
230
|
console.log('运行环境: 本地源码 checkout');
|
|
216
231
|
}
|
|
@@ -223,6 +238,17 @@ function printSelfUpdateResult(result, json) {
|
|
|
223
238
|
if (result.resolvedExecutable?.executable) {
|
|
224
239
|
console.log(`OpenPrd 可执行文件: ${result.resolvedExecutable.executable}`);
|
|
225
240
|
}
|
|
241
|
+
if (result.installedVersion?.version) {
|
|
242
|
+
console.log(`安装后版本: ${result.installedVersion.version}`);
|
|
243
|
+
}
|
|
244
|
+
if ((result.refreshCandidates?.total ?? 0) > 0) {
|
|
245
|
+
console.log(`旧项目刷新候选: ${result.refreshCandidates.total}`);
|
|
246
|
+
for (const project of result.refreshCandidates.projects ?? []) {
|
|
247
|
+
console.log(`- ${project.workspaceRoot} (${project.currentVersion} -> ${project.targetVersion}; ${project.note})`);
|
|
248
|
+
}
|
|
249
|
+
} else if (result.refreshCandidates?.ok && result.checkOnly) {
|
|
250
|
+
console.log('旧项目刷新候选: 0');
|
|
251
|
+
}
|
|
226
252
|
for (const action of result.nextActions ?? []) {
|
|
227
253
|
console.log(`下一步: ${action}`);
|
|
228
254
|
}
|
package/src/cli/print.js
CHANGED
|
@@ -48,9 +48,11 @@ import {
|
|
|
48
48
|
} from './doctor-print.js';
|
|
49
49
|
import { printGrowthResult } from './growth-print.js';
|
|
50
50
|
import {
|
|
51
|
+
printDesignStarterResult,
|
|
51
52
|
printDevelopmentStandardsResult,
|
|
52
53
|
printKnowledgeResult,
|
|
53
54
|
printQualityResult,
|
|
55
|
+
printVisualPrepareResult,
|
|
54
56
|
printStandardsResult,
|
|
55
57
|
printVisualCompareResult,
|
|
56
58
|
} from './quality-print.js';
|
|
@@ -59,6 +61,7 @@ import {
|
|
|
59
61
|
printRunResult,
|
|
60
62
|
} from './run-print.js';
|
|
61
63
|
import {
|
|
64
|
+
printBrainstormResult,
|
|
62
65
|
printDiagramResult,
|
|
63
66
|
printDiffResult,
|
|
64
67
|
printFreezeResult,
|
|
@@ -80,6 +83,7 @@ export {
|
|
|
80
83
|
printLearningResult,
|
|
81
84
|
printReleaseResult,
|
|
82
85
|
printSynthesizeResult,
|
|
86
|
+
printBrainstormResult,
|
|
83
87
|
printReviewResult,
|
|
84
88
|
printHistoryResult,
|
|
85
89
|
printDiffResult,
|
|
@@ -94,9 +98,11 @@ export {
|
|
|
94
98
|
printLoopResult,
|
|
95
99
|
printStandardsResult,
|
|
96
100
|
printDevelopmentStandardsResult,
|
|
101
|
+
printDesignStarterResult,
|
|
97
102
|
printGrowthResult,
|
|
98
103
|
printQualityResult,
|
|
99
104
|
printKnowledgeResult,
|
|
105
|
+
printVisualPrepareResult,
|
|
100
106
|
printVisualCompareResult,
|
|
101
107
|
printFreezeResult,
|
|
102
108
|
printDiagramResult,
|
package/src/cli/quality-print.js
CHANGED
|
@@ -275,10 +275,80 @@ function printVisualCompareResult(result, json) {
|
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
function printVisualPrepareResult(result, json) {
|
|
279
|
+
if (json) {
|
|
280
|
+
console.log(JSON.stringify(result, null, 2));
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const modeLabel = result.mode === 'grid' ? '规则网格切片' : '手工裁剪计划';
|
|
285
|
+
console.log('OpenPrd visual prepare: 已生成');
|
|
286
|
+
console.log(`reference-set: ${result.referenceSetPath}`);
|
|
287
|
+
console.log(`输出目录: ${result.outputDir}`);
|
|
288
|
+
console.log(`模式: ${modeLabel}`);
|
|
289
|
+
console.log(`参考对象: ${result.itemCount}`);
|
|
290
|
+
if (result.source?.metadata) {
|
|
291
|
+
console.log(`参考整板: ${result.source.metadata.width}x${result.source.metadata.height}`);
|
|
292
|
+
}
|
|
293
|
+
console.log(`Contact sheet: ${result.contactSheetPath}`);
|
|
294
|
+
console.log(`Focus 模板: ${result.focusBoardTemplatePath}`);
|
|
295
|
+
console.log(`Parallel 模板: ${result.parallelBoardTemplatePath}`);
|
|
296
|
+
console.log(`对比计划: ${result.comparePlanPath}`);
|
|
297
|
+
for (const action of result.nextActions ?? []) {
|
|
298
|
+
console.log(`- 下一步: ${action}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function printDesignStarterResult(result, json) {
|
|
303
|
+
if (json) {
|
|
304
|
+
console.log(JSON.stringify(result, null, 2));
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (!result.ok) {
|
|
309
|
+
console.log('OpenPrd design starter: 失败');
|
|
310
|
+
for (const error of result.errors ?? []) {
|
|
311
|
+
console.log(`- ${error}`);
|
|
312
|
+
}
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
console.log('OpenPrd design starter: 已生成');
|
|
317
|
+
console.log(`模板: ${result.starterId} (${result.relativeTemplatePath})`);
|
|
318
|
+
console.log(`输出: ${result.relativeOutputPath}`);
|
|
319
|
+
if (result.defaults?.lens || result.defaults?.theme || result.defaults?.layout) {
|
|
320
|
+
console.log(`默认组合: lens=${result.defaults.lens ?? '待补'} theme=${result.defaults.theme ?? '待补'} layout=${result.defaults.layout ?? '待补'}`);
|
|
321
|
+
}
|
|
322
|
+
if (result.overwritten) {
|
|
323
|
+
console.log('覆盖: 是');
|
|
324
|
+
}
|
|
325
|
+
if (result.hydrated) {
|
|
326
|
+
console.log('active design contracts: 已同步写实');
|
|
327
|
+
if (Array.isArray(result.docsHydrated) && result.docsHydrated.length > 0) {
|
|
328
|
+
console.log(`docs/basic: 已同步写实 (${result.docsHydrated.length} 份)`);
|
|
329
|
+
}
|
|
330
|
+
if (result.sourceManualFilled) {
|
|
331
|
+
console.log(`文件说明书: 已补到 ${result.relativeOutputPath}`);
|
|
332
|
+
}
|
|
333
|
+
if (result.folderManualCreated && result.folderManualPath) {
|
|
334
|
+
console.log(`文件夹 README: 已补到 ${result.folderManualPath}`);
|
|
335
|
+
}
|
|
336
|
+
console.log(`页面主题: ${result.title ?? result.brief ?? '已补'}`);
|
|
337
|
+
if (Array.isArray(result.sections) && result.sections.length > 0) {
|
|
338
|
+
console.log(`模块: ${result.sections.join(' / ')}`);
|
|
339
|
+
}
|
|
340
|
+
console.log('下一步: 直接在生成的入口文件上继续细化结构和样式,不要回到 pending 合同;禁止删除这个入口文件后另起新稿。如果题目更像导览、旅行、展览或馆藏内容页,保持真实图片路线,不要再把它改回 `--no-real-images`。');
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
console.log('下一步: 立即替换入口文件里的标题、CTA 和所有占位文案,并同步把 active design contracts 写实;只有确认当前页不依赖外部事实、品牌素材或真实图片时,才直接写清无依赖。若题目更像导览、旅行、展览或馆藏内容页,先不要急着加 `--no-real-images`。后续必须继续在生成的入口文件上改,禁止删除后重起。');
|
|
344
|
+
}
|
|
345
|
+
|
|
278
346
|
export {
|
|
279
347
|
printStandardsResult,
|
|
280
348
|
printDevelopmentStandardsResult,
|
|
281
349
|
printQualityResult,
|
|
282
350
|
printKnowledgeResult,
|
|
351
|
+
printVisualPrepareResult,
|
|
283
352
|
printVisualCompareResult,
|
|
353
|
+
printDesignStarterResult,
|
|
284
354
|
};
|
package/src/cli/run-print.js
CHANGED
|
@@ -21,6 +21,20 @@ import { labelExecutionMode } from '../execution-strategy.js';
|
|
|
21
21
|
import { printCodexRuntimeResult } from './doctor-print.js';
|
|
22
22
|
import { printKnowledgeReview, printKnowledgeSkillMatches } from './shared-print.js';
|
|
23
23
|
|
|
24
|
+
function printLoopWorkspaceMeta(result, fallbackProjectRoot = null) {
|
|
25
|
+
const workspacePath = result.workspace?.path ?? result.commit?.worktreePath ?? fallbackProjectRoot;
|
|
26
|
+
const branch = result.workspace?.branch ?? result.commit?.branch ?? null;
|
|
27
|
+
if (workspacePath) {
|
|
28
|
+
console.log(`工作区: ${workspacePath}`);
|
|
29
|
+
}
|
|
30
|
+
if (branch) {
|
|
31
|
+
console.log(`分支: ${branch}`);
|
|
32
|
+
}
|
|
33
|
+
if (result.workspace?.created) {
|
|
34
|
+
console.log('隔离 worktree: 已创建');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
function printExecutionConfirmationChecklist(checklist) {
|
|
25
39
|
if (!checklist?.required) {
|
|
26
40
|
return;
|
|
@@ -152,6 +166,31 @@ function printRunResult(result, json) {
|
|
|
152
166
|
console.log(`协作建议: ${result.recommendation.parallelPlan.summary}`);
|
|
153
167
|
}
|
|
154
168
|
console.log(`这样安排的原因: ${result.recommendation.reason}`);
|
|
169
|
+
if (
|
|
170
|
+
result.recommendation.command
|
|
171
|
+
&& !result.recommendation.preparationCommand
|
|
172
|
+
&& !result.recommendation.executionCommand
|
|
173
|
+
&& !result.recommendation.commitCommand
|
|
174
|
+
) {
|
|
175
|
+
console.log(`内部下一步参考: ${result.recommendation.command}`);
|
|
176
|
+
}
|
|
177
|
+
if (
|
|
178
|
+
result.recommendation.nextAction === 'brainstorm'
|
|
179
|
+
|| result.recommendation.title === '先进入脑暴模式收敛方向'
|
|
180
|
+
|| result.recommendation.command === 'openprd brainstorm . --open'
|
|
181
|
+
) {
|
|
182
|
+
console.log('当前回复目标: 先进入脑暴模式,把核心诉求、目标结果、当前替代方案、推荐方向和验证重点整理成脑暴页;不要只停在 requirement 摘要。');
|
|
183
|
+
} else if (result.recommendation.nextAction === 'lightweight-l1') {
|
|
184
|
+
console.log('当前回复目标: 先用 3-5 行 mini-plan 收一下目标、范围内、范围外和验证方式;如果用户已经明确不需要确认,就按这个轻量路径继续实现,不要再回到 clarify-user。空白工作区先补 `.openprd/design/active/`,再从 `.openprd/design/templates/` 选最近模板;若页面主题和模块范围已经明确,优先把它们带进 `openprd design-starter --brief/--sections`,让 starter 一次落合同和首版内容。只有确认这个页面本来就不依赖外部事实、品牌素材或真实图片时,才在 active design artifacts 写清无依赖;如果题目更像旅游、导览、展览、博物馆、城市或自然观察内容页,先不要急着加 `--no-real-images`。后续必须继续在生成的入口文件上补丁修改;即使结构要大改,也不要删除 `index.html` 后重起。');
|
|
185
|
+
} else if (result.recommendation.nextAction === 'lightweight-l0') {
|
|
186
|
+
console.log('当前回复目标: 直接处理这次局部改动,做最小足够验证,并在完成后用人话说明本次调整。');
|
|
187
|
+
} else if (
|
|
188
|
+
result.recommendation.nextAction === 'clarify-user'
|
|
189
|
+
|| result.recommendation.title === 'clarify-user'
|
|
190
|
+
|| result.recommendation.title === '继续本轮需求入口澄清'
|
|
191
|
+
) {
|
|
192
|
+
console.log('当前回复目标: 先在对话里输出 requirement 摘要或只追问 1 个最高价值澄清点;不要承诺“按默认方案直接实现”,也不要把“请帮我实现/继续实现”当成跳过 requirement 摘要确认的依据。');
|
|
193
|
+
}
|
|
155
194
|
if (result.recommendation.preparationCommand || result.recommendation.executionCommand || result.recommendation.commitCommand) {
|
|
156
195
|
console.log('开始动手前提: 只有在用户明确要求继续落地、实现、修复、深挖或提交时,才继续往下做;如果还缺这一步,就先用人话说明范围和影响。');
|
|
157
196
|
}
|
|
@@ -165,7 +204,7 @@ function printRunResult(result, json) {
|
|
|
165
204
|
if (result.recommendation.commitCommand) {
|
|
166
205
|
console.log(`内部提交参考: ${result.recommendation.commitCommand}`);
|
|
167
206
|
}
|
|
168
|
-
if (result.recommendation.loop?.worktreeRecommended) {
|
|
207
|
+
if (result.recommendation.loop?.worktreeRecommended || result.recommendation.isolation?.worktreeRecommended) {
|
|
169
208
|
console.log('环境建议: 最好放到单独环境里继续,避免和别的事项串线。');
|
|
170
209
|
}
|
|
171
210
|
console.log(`内部检查参考: ${result.recommendation.verifyCommand}`);
|
|
@@ -184,6 +223,7 @@ function printLoopResult(result, json) {
|
|
|
184
223
|
console.log(`任务: ${result.task.id} ${result.task.title}`);
|
|
185
224
|
if (result.task.taskHandle) console.log(`任务句柄: ${result.task.taskHandle}`);
|
|
186
225
|
}
|
|
226
|
+
printLoopWorkspaceMeta(result, result.projectRoot);
|
|
187
227
|
if (result.promptPath) {
|
|
188
228
|
console.log(`提示词: ${result.promptPath}`);
|
|
189
229
|
}
|
|
@@ -200,6 +240,7 @@ function printLoopResult(result, json) {
|
|
|
200
240
|
console.log(`OpenPrd loop 运行: ${result.ok ? '通过' : '失败'}${result.dryRun ? ' (dry-run)' : ''}`);
|
|
201
241
|
if (result.task) console.log(`任务: ${result.task.id} ${result.task.title}`);
|
|
202
242
|
if (result.task?.taskHandle) console.log(`任务句柄: ${result.task.taskHandle}`);
|
|
243
|
+
printLoopWorkspaceMeta(result, result.projectRoot);
|
|
203
244
|
if (result.promptPath) console.log(`提示词: ${result.promptPath}`);
|
|
204
245
|
if (result.invocation?.display) console.log(`执行: ${result.invocation.display}`);
|
|
205
246
|
if (result.codexRuntime || result.preflight) {
|
|
@@ -233,6 +274,7 @@ function printLoopResult(result, json) {
|
|
|
233
274
|
console.log(`OpenPrd loop finish: ${result.ok ? '通过' : '失败'}`);
|
|
234
275
|
if (result.task) console.log(`任务: ${result.task.id} ${result.task.title}`);
|
|
235
276
|
if (result.task?.taskHandle) console.log(`任务句柄: ${result.task.taskHandle}`);
|
|
277
|
+
printLoopWorkspaceMeta(result, result.projectRoot);
|
|
236
278
|
if (result.commit) console.log(`提交: ${result.commit.skipped ? '跳过' : result.commit.sha}`);
|
|
237
279
|
if (result.projectRelease?.version) {
|
|
238
280
|
console.log(`项目版本: ${result.projectRelease.version}`);
|
package/src/cli/shared-print.js
CHANGED
|
@@ -29,6 +29,12 @@ function printKnowledgeReview(knowledgeReview) {
|
|
|
29
29
|
console.log(`项目经验回顾: 失败 (${knowledgeReview.errors?.[0] ?? 'unknown'})`);
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
+
const userFacingMessage = String(knowledgeReview.userFacingExperience?.message ?? '').trim();
|
|
33
|
+
if (userFacingMessage) {
|
|
34
|
+
console.log('项目经验回顾:');
|
|
35
|
+
console.log(userFacingMessage);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
32
38
|
console.log(`项目经验草案: ${knowledgeReview.candidateId}`);
|
|
33
39
|
if (knowledgeReview.summary) {
|
|
34
40
|
console.log(`摘要: ${knowledgeReview.summary}`);
|
|
@@ -51,18 +57,43 @@ function knowledgeAdoptionLabel(adoption = {}) {
|
|
|
51
57
|
return `命中 ${adoption.hitCount ?? 0} / 引用 ${adoption.referencedCount ?? 0} / 注入 ${adoption.injectedCount ?? 0}`;
|
|
52
58
|
}
|
|
53
59
|
|
|
60
|
+
function formatUseWhenLabel(value) {
|
|
61
|
+
return String(value ?? '').trim().replace(/^use when\b[::]?\s*/i, '').trim();
|
|
62
|
+
}
|
|
63
|
+
|
|
54
64
|
function printKnowledgeSkillMatches(knowledgeSkills) {
|
|
55
65
|
const matched = Array.isArray(knowledgeSkills?.matched) ? knowledgeSkills.matched : [];
|
|
56
66
|
if (matched.length === 0) {
|
|
57
67
|
return;
|
|
58
68
|
}
|
|
59
69
|
const summary = knowledgeSkills?.summary ?? {};
|
|
60
|
-
|
|
70
|
+
const mandatoryCheck = knowledgeSkills?.mandatoryCheck ?? null;
|
|
71
|
+
if (mandatoryCheck?.required) {
|
|
72
|
+
console.log(`项目级经验候选: 找到 ${matched.length} 条${summary.hookInjected ? ',已加入当前上下文供判断' : ''}`);
|
|
73
|
+
console.log(`${mandatoryCheck.title}: ${mandatoryCheck.summary}`);
|
|
74
|
+
for (const instruction of (mandatoryCheck.instructions ?? []).slice(0, 3)) {
|
|
75
|
+
console.log(`- ${instruction}`);
|
|
76
|
+
}
|
|
77
|
+
if (Array.isArray(mandatoryCheck.focusSignals) && mandatoryCheck.focusSignals.length > 0) {
|
|
78
|
+
console.log(`当前判断线索: ${mandatoryCheck.focusSignals.join(';')}`);
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
console.log(`项目级 Skill: 命中 ${matched.length} 个${summary.hookInjected ? ',已自动注入当前上下文' : ''}`);
|
|
82
|
+
}
|
|
61
83
|
for (const skill of matched.slice(0, 3)) {
|
|
62
84
|
console.log(`- ${skill.skillName}: ${skill.matchSummary ?? '命中当前上下文'}`);
|
|
63
|
-
|
|
85
|
+
const useWhen = formatUseWhenLabel(skill.useWhen ?? skill.description);
|
|
86
|
+
if (useWhen) {
|
|
87
|
+
console.log(` 适用时机: ${useWhen}`);
|
|
88
|
+
} else if (skill.description) {
|
|
64
89
|
console.log(` 说明: ${skill.description}`);
|
|
65
90
|
}
|
|
91
|
+
if (Array.isArray(skill.reviewFirst) && skill.reviewFirst.length > 0) {
|
|
92
|
+
console.log(` 先看: ${skill.reviewFirst.slice(0, 3).join(';')}`);
|
|
93
|
+
}
|
|
94
|
+
if (Array.isArray(skill.antiPatterns) && skill.antiPatterns.length > 0) {
|
|
95
|
+
console.log(` 不要直接套用: ${skill.antiPatterns.slice(0, 2).join(';')}`);
|
|
96
|
+
}
|
|
66
97
|
if (Array.isArray(skill.touchedFiles) && skill.touchedFiles.length > 0) {
|
|
67
98
|
console.log(` 相关文件: ${skill.touchedFiles.slice(0, 4).join(';')}`);
|
|
68
99
|
}
|
|
@@ -76,6 +76,22 @@ function printReviewResult(result, json) {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
function printBrainstormResult(result, json) {
|
|
80
|
+
if (json) {
|
|
81
|
+
console.log(JSON.stringify(result, null, 2));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log('脑暴工作台已生成');
|
|
86
|
+
console.log(`主题: ${result.record.topic}`);
|
|
87
|
+
console.log(`推荐方向: ${result.record.summary?.recommendedDirection ?? '待补充'}`);
|
|
88
|
+
console.log(`脑暴页面: ${result.htmlPath}`);
|
|
89
|
+
console.log(`Markdown 数据源: ${result.markdownPath}`);
|
|
90
|
+
console.log(`Capture Patch: ${result.patchPath}`);
|
|
91
|
+
console.log(`状态文件: ${result.statePath}`);
|
|
92
|
+
console.log(`已自动打开: ${result.opened ? '是' : '否'}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
79
95
|
function printHistoryResult(result, json) {
|
|
80
96
|
if (json) {
|
|
81
97
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -121,6 +137,10 @@ function printNextResult(result, json) {
|
|
|
121
137
|
if (taskGraph?.nextReadyNode) {
|
|
122
138
|
console.log(`下一个就绪节点: ${taskGraph.nextReadyNode}`);
|
|
123
139
|
}
|
|
140
|
+
if (result.brainstormSuggestion?.recommended) {
|
|
141
|
+
console.log(`脑暴模式建议: ${result.brainstormSuggestion.reason}`);
|
|
142
|
+
console.log(`脑暴命令: ${result.brainstormSuggestion.suggestedCommand}`);
|
|
143
|
+
}
|
|
124
144
|
if (result.diagramState?.needed) {
|
|
125
145
|
console.log(`图表门禁: ${result.diagramState.shouldGateFreeze ? '激活' : '已满足'}`);
|
|
126
146
|
console.log(`建议图表: ${result.diagramState.preferredType}`);
|
|
@@ -184,6 +204,7 @@ function printHandoffResult(result, json) {
|
|
|
184
204
|
}
|
|
185
205
|
|
|
186
206
|
export {
|
|
207
|
+
printBrainstormResult,
|
|
187
208
|
printSynthesizeResult,
|
|
188
209
|
printReviewResult,
|
|
189
210
|
printHistoryResult,
|