@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/openprd.js
CHANGED
|
@@ -33,7 +33,7 @@ import { doctorOpenPrdAgentIntegration, setupOpenPrdAgentIntegration, updateOpen
|
|
|
33
33
|
import { finishLoopWorkspace, initLoopWorkspace, nextLoopWorkspace, planLoopWorkspace, promptLoopWorkspace, runLoopWorkspace, statusLoopWorkspace, verifyLoopWorkspace } from './loop.js';
|
|
34
34
|
import { timestamp } from './time.js';
|
|
35
35
|
import { parseCommandArgs, usage } from './cli/args.js';
|
|
36
|
-
import { printAcceptedSpecsResult, printAgentIntegrationResult, printBenchmarkResult, printCaptureResult, printClarifyResult, printClassifyResult, printDevelopmentStandardsResult, printDiagramResult, printDiffResult, printDoctorResult, printFleetResult, printFreezeResult, printGrowthResult, printHandoffResult, printHistoryResult, printInitResult, printInterviewResult, printKnowledgeResult, printLearningResult, printLoopResult, printNextResult, printOpenPrdChangeActionResult, printOpenPrdChangesResult, printOpenSpecChangeValidationResult, printOpenSpecDiscoveryResult, printOpenSpecGenerateResult, printOpenSpecTaskResult, printPlaygroundResult, printQualityResult, printReleaseResult, printReviewResult, printRunResult, printSelfUpdateResult, printStandardsResult, printStatus, printSynthesizeResult, printUpgradeResult, printValidation, printVisualCompareResult } from './cli/print.js';
|
|
36
|
+
import { printAcceptedSpecsResult, printAgentIntegrationResult, printBenchmarkResult, printBrainstormResult, printCaptureResult, printClarifyResult, printClassifyResult, printDesignStarterResult, printDevelopmentStandardsResult, printDiagramResult, printDiffResult, printDoctorResult, printFleetResult, printFreezeResult, printGrowthResult, printHandoffResult, printHistoryResult, printInitResult, printInterviewResult, printKnowledgeResult, printLearningResult, printLoopResult, printNextResult, printOpenPrdChangeActionResult, printOpenPrdChangesResult, printOpenSpecChangeValidationResult, printOpenSpecDiscoveryResult, printOpenSpecGenerateResult, printOpenSpecTaskResult, printPlaygroundResult, printQualityResult, printReleaseResult, printReviewResult, printRunResult, printSelfUpdateResult, printStandardsResult, printStatus, printSynthesizeResult, printUpgradeResult, printValidation, printVisualCompareResult, printVisualPrepareResult } from './cli/print.js';
|
|
37
37
|
import { cjoin, exists, readJson, writeJson, writeText, writeYaml } from './fs-utils.js';
|
|
38
38
|
import { diagramWorkspace } from './diagram-workspace.js';
|
|
39
39
|
import { createOpenSpecDiscoveryWorkspace } from './discovery.js';
|
|
@@ -61,11 +61,15 @@ import {
|
|
|
61
61
|
rejectGrowthCandidateWorkspace,
|
|
62
62
|
reviewGrowthWorkspace,
|
|
63
63
|
} from './growth.js';
|
|
64
|
+
import { brainstormWorkspace } from './brainstorm.js';
|
|
65
|
+
import { buildBrainstormPresentationTemplatePayload, brainstormPresentationWorkspace } from './brainstorm-presentation.js';
|
|
66
|
+
import { designStarterWorkspace } from './design-starter.js';
|
|
64
67
|
import { buildReviewPresentationTemplatePayload, reviewPresentationWorkspace } from './review-presentation.js';
|
|
65
68
|
import { analyzeWorkspaceRegistryHygiene } from './registry-hygiene.js';
|
|
66
69
|
import { syncSessionBindingFromChange } from './session-binding.js';
|
|
67
70
|
import { readSessionRegistry } from './session-registry.js';
|
|
68
71
|
import { visualCompareWorkspace } from './visual-compare.js';
|
|
72
|
+
import { visualPrepareWorkspace } from './visual-prepare.js';
|
|
69
73
|
import { captureWorkspace, clarifyWorkspace, classifyWorkspace, computeWorkspaceGuidance, diffWorkspace, historyWorkspace, interviewWorkspace, nextWorkspace, playgroundWorkspace, reviewWorkspace, synthesizeWorkspace } from './workspace-workflow.js';
|
|
70
74
|
import { appendDecision, appendProgress, appendVerification, appendWorkflowEvent, buildCurrentStateSnapshot, buildWorkflowTaskGraph, computeWorkspaceDigest, CORE_TEMPLATE_FILES, ensureWorkspaceSkeleton, isSupportedProductType, loadCurrentLaneSnapshot, loadLatestVersionSnapshot, loadWorkspace, migrateWorkspaceSkeleton, normalizeVersionId, persistWorkspaceCurrentState, readVersionIndex, resolveActiveTemplatePack, resolveCurrentProductType, validateWorkspace } from './workspace-core.js';
|
|
71
75
|
import { readWorkspaceRegistry } from './workspace-registry.js';
|
|
@@ -784,8 +788,10 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
784
788
|
|
|
785
789
|
if (command === 'self-update') {
|
|
786
790
|
const result = await selfUpdateWorkspace({
|
|
791
|
+
check: flags.check,
|
|
787
792
|
dryRun: flags.dryRun,
|
|
788
793
|
json: flags.json,
|
|
794
|
+
openprdHome: flags.openprdHome,
|
|
789
795
|
});
|
|
790
796
|
printSelfUpdateResult(result, flags.json);
|
|
791
797
|
return result.ok ? 0 : 1;
|
|
@@ -866,6 +872,9 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
866
872
|
evidence: flags.evidence,
|
|
867
873
|
notes: flags.notes,
|
|
868
874
|
repairAgent: flags.repairAgent,
|
|
875
|
+
worktree: flags.worktree,
|
|
876
|
+
branch: flags.branch,
|
|
877
|
+
allowDirtyMain: flags.allowDirtyMain,
|
|
869
878
|
};
|
|
870
879
|
if (flags.init) {
|
|
871
880
|
result = await initLoopWorkspace(projectPath, options);
|
|
@@ -944,6 +953,20 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
944
953
|
return result.ok ? 0 : 1;
|
|
945
954
|
}
|
|
946
955
|
|
|
956
|
+
if (command === 'visual-prepare') {
|
|
957
|
+
const result = await visualPrepareWorkspace(projectPath, {
|
|
958
|
+
reference: flags.reference,
|
|
959
|
+
grid: flags.grid,
|
|
960
|
+
boxes: flags.boxes,
|
|
961
|
+
include: flags.include,
|
|
962
|
+
id: flags.id,
|
|
963
|
+
title: flags.title,
|
|
964
|
+
out: flags.out,
|
|
965
|
+
});
|
|
966
|
+
printVisualPrepareResult(result, flags.json);
|
|
967
|
+
return result.ok ? 0 : 1;
|
|
968
|
+
}
|
|
969
|
+
|
|
947
970
|
if (command === 'visual-compare') {
|
|
948
971
|
const result = await visualCompareWorkspace(projectPath, {
|
|
949
972
|
reference: flags.reference,
|
|
@@ -962,6 +985,22 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
962
985
|
return result.ok ? 0 : 1;
|
|
963
986
|
}
|
|
964
987
|
|
|
988
|
+
if (command === 'design-starter') {
|
|
989
|
+
const result = await designStarterWorkspace(projectPath, {
|
|
990
|
+
starter: flags.starter,
|
|
991
|
+
out: flags.out,
|
|
992
|
+
title: flags.title,
|
|
993
|
+
brief: flags.brief,
|
|
994
|
+
sections: flags.sections,
|
|
995
|
+
noExternalFacts: flags.noExternalFacts,
|
|
996
|
+
noBrandAssets: flags.noBrandAssets,
|
|
997
|
+
noRealImages: flags.noRealImages,
|
|
998
|
+
force: flags.force,
|
|
999
|
+
});
|
|
1000
|
+
printDesignStarterResult(result, flags.json);
|
|
1001
|
+
return result.ok ? 0 : 1;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
965
1004
|
if (command === 'grow') {
|
|
966
1005
|
const firstArgIsProjectPath = !flags.path && positionals.length > 0 && await isDirectoryPath(positionals[0]);
|
|
967
1006
|
const growthProjectPath = path.resolve(flags.path ?? (firstArgIsProjectPath ? positionals[0] : process.cwd()));
|
|
@@ -1073,6 +1112,16 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
1073
1112
|
return 0;
|
|
1074
1113
|
}
|
|
1075
1114
|
|
|
1115
|
+
if (command === 'brainstorm') {
|
|
1116
|
+
const result = await brainstormWorkspace(projectPath, {
|
|
1117
|
+
topic: flags.topic,
|
|
1118
|
+
open: flags.open || !flags.json,
|
|
1119
|
+
json: flags.json,
|
|
1120
|
+
});
|
|
1121
|
+
printBrainstormResult(result, flags.json);
|
|
1122
|
+
return 0;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1076
1125
|
if (command === 'learn') {
|
|
1077
1126
|
if (flags.enable || flags.disable) {
|
|
1078
1127
|
const enabled = flags.enable ? true : false;
|
|
@@ -1163,6 +1212,38 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
1163
1212
|
return flags.failOnViolation && !result.ok ? 1 : 0;
|
|
1164
1213
|
}
|
|
1165
1214
|
|
|
1215
|
+
if (command === 'brainstorm-presentation') {
|
|
1216
|
+
if (flags.template) {
|
|
1217
|
+
console.log(JSON.stringify(buildBrainstormPresentationTemplatePayload(), null, 2));
|
|
1218
|
+
return 0;
|
|
1219
|
+
}
|
|
1220
|
+
const result = await brainstormPresentationWorkspace(projectPath, {
|
|
1221
|
+
presentationPath: flags.presentation,
|
|
1222
|
+
write: flags.write,
|
|
1223
|
+
});
|
|
1224
|
+
if (flags.json) {
|
|
1225
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1226
|
+
} else {
|
|
1227
|
+
console.log(`展示文案校验: ${result.ok ? '通过' : '需要重写'}`);
|
|
1228
|
+
console.log(`主题: ${result.topic}`);
|
|
1229
|
+
console.log(`超限或格式问题: ${result.presentationFeedback.length}`);
|
|
1230
|
+
if (result.presentationFeedback.length > 0) {
|
|
1231
|
+
for (const item of result.presentationFeedback.slice(0, 6)) {
|
|
1232
|
+
const pathHint = item.jsonPath ? `${item.jsonPath}: ` : '';
|
|
1233
|
+
const sizeHint = item.maxChars ? ` 当前 ${item.currentChars} 字,限制 ${item.maxChars} 字。` : '';
|
|
1234
|
+
console.log(`- ${item.area} / ${item.target}: ${pathHint}${item.action}${sizeHint}`);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
if (result.written) {
|
|
1238
|
+
console.log(`已写入: ${result.written}`);
|
|
1239
|
+
}
|
|
1240
|
+
if (result.htmlPath) {
|
|
1241
|
+
console.log(`已更新脑暴页面: ${result.htmlPath}`);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
return flags.failOnViolation && !result.ok ? 1 : 0;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1166
1247
|
if (command === 'diagram') {
|
|
1167
1248
|
const result = await diagramWorkspace(projectPath, { open: flags.open, type: flags.type, input: flags.input, mark: flags.mark });
|
|
1168
1249
|
printDiagramResult(result, flags.json);
|
|
@@ -1384,6 +1465,7 @@ export {
|
|
|
1384
1465
|
clarifyWorkspace,
|
|
1385
1466
|
captureWorkspace,
|
|
1386
1467
|
playgroundWorkspace,
|
|
1468
|
+
brainstormWorkspace,
|
|
1387
1469
|
generateLearningReviewWorkspace,
|
|
1388
1470
|
setLearningReviewModeWorkspace,
|
|
1389
1471
|
synthesizeWorkspace,
|
|
@@ -1392,6 +1474,7 @@ export {
|
|
|
1392
1474
|
historyWorkspace,
|
|
1393
1475
|
releaseWorkspace,
|
|
1394
1476
|
reviewWorkspace,
|
|
1477
|
+
brainstormPresentationWorkspace,
|
|
1395
1478
|
reviewPresentationWorkspace,
|
|
1396
1479
|
freezeWorkspace,
|
|
1397
1480
|
handoffWorkspace,
|
|
@@ -1409,6 +1492,7 @@ export {
|
|
|
1409
1492
|
archiveOpenPrdChangeWorkspace,
|
|
1410
1493
|
listAcceptedSpecsWorkspace,
|
|
1411
1494
|
diagramWorkspace,
|
|
1495
|
+
designStarterWorkspace,
|
|
1412
1496
|
classifyWorkspace,
|
|
1413
1497
|
interviewWorkspace,
|
|
1414
1498
|
loadWorkspace,
|
|
@@ -1423,6 +1507,7 @@ export {
|
|
|
1423
1507
|
rejectKnowledgeCandidate,
|
|
1424
1508
|
archiveKnowledgeCandidate,
|
|
1425
1509
|
restoreKnowledgeCandidate,
|
|
1510
|
+
visualPrepareWorkspace,
|
|
1426
1511
|
visualCompareWorkspace,
|
|
1427
1512
|
checkDevelopmentStandardsWorkspace,
|
|
1428
1513
|
initGrowthWorkspace,
|
|
@@ -210,6 +210,7 @@ export async function validateOpenSpecChangeWorkspace(projectRoot, options = {})
|
|
|
210
210
|
optional: !(await exists(cjoin(projectRoot, '.openprd'))),
|
|
211
211
|
sourceManuals: options.sourceManuals,
|
|
212
212
|
docsContent: options.docsContent,
|
|
213
|
+
folderManualModuleName: options.folderManualModuleName,
|
|
213
214
|
});
|
|
214
215
|
if (!standards.skipped) {
|
|
215
216
|
errors.push(...standards.errors);
|
package/src/prd-core.js
CHANGED
|
@@ -239,6 +239,15 @@ export function buildPrdSnapshot(ws, options = {}) {
|
|
|
239
239
|
successMetrics: normalizeArray(pickValue(options.successMetrics, state.successMetrics)),
|
|
240
240
|
acceptanceGoals: normalizeArray(pickValue(options.acceptanceGoals, state.acceptanceGoals)),
|
|
241
241
|
},
|
|
242
|
+
validation: {
|
|
243
|
+
community: normalizeArray(pickValue(options.community, state.community)),
|
|
244
|
+
seedUsers: normalizeArray(pickValue(options.seedUsers, state.seedUsers)),
|
|
245
|
+
currentAlternative: pickValue(options.currentAlternative, state.currentAlternative, state.asIs),
|
|
246
|
+
manualPath: normalizeArray(pickValue(options.manualPath, state.manualPath)),
|
|
247
|
+
commitmentSignals: normalizeArray(pickValue(options.commitmentSignals, state.commitmentSignals)),
|
|
248
|
+
firstValidationStep: pickValue(options.firstValidationStep, state.firstValidationStep, state.nextStep),
|
|
249
|
+
defaultAlivePlan: normalizeArray(pickValue(options.defaultAlivePlan, state.defaultAlivePlan)),
|
|
250
|
+
},
|
|
242
251
|
scope: {
|
|
243
252
|
inScope: normalizeArray(pickValue(options.inScope, state.inScope)),
|
|
244
253
|
outOfScope: normalizeArray(pickValue(options.outOfScope, state.outOfScope)),
|
|
@@ -367,6 +376,15 @@ export function renderPrdMarkdown(snapshot) {
|
|
|
367
376
|
['成功指标', sections.goals.successMetrics],
|
|
368
377
|
['验收目标', sections.goals.acceptanceGoals],
|
|
369
378
|
]),
|
|
379
|
+
renderSection('验证与创业闭环', [
|
|
380
|
+
['可触达社区', sections.validation.community],
|
|
381
|
+
['第一批种子用户', sections.validation.seedUsers],
|
|
382
|
+
['当前替代方案', sections.validation.currentAlternative],
|
|
383
|
+
['手工交付路径', sections.validation.manualPath],
|
|
384
|
+
['承诺信号', sections.validation.commitmentSignals],
|
|
385
|
+
['首个低成本验证', sections.validation.firstValidationStep],
|
|
386
|
+
['先活下来方案', sections.validation.defaultAlivePlan],
|
|
387
|
+
]),
|
|
370
388
|
renderSection('范围与非目标', [
|
|
371
389
|
['范围内', sections.scope.inScope],
|
|
372
390
|
['范围外', sections.scope.outOfScope],
|
package/src/quality-learning.js
CHANGED
|
@@ -575,9 +575,24 @@ function renderList(items, fallback) {
|
|
|
575
575
|
return list.map((item) => `- ${item}`).join('\n')
|
|
576
576
|
}
|
|
577
577
|
|
|
578
|
-
function
|
|
578
|
+
function describeEvidenceSource(source, options = {}) {
|
|
579
|
+
if (!options.genericPaths) {
|
|
580
|
+
return `${source.kind}: \`${source.path}\``;
|
|
581
|
+
}
|
|
582
|
+
const genericLabel = {
|
|
583
|
+
'quality-report': '当前项目里最新一轮相关的质量报告与 HTML 评估页',
|
|
584
|
+
'diagnostic-bundle': '当前任务对应的诊断目录',
|
|
585
|
+
'diagnostic-report': '当前任务对应的 diagnostic-report',
|
|
586
|
+
'runtime-events': '当前任务对应的 runtime-events',
|
|
587
|
+
timeline: '当前任务对应的 timeline',
|
|
588
|
+
'root-cause-candidates': '当前任务对应的 root-cause-candidates',
|
|
589
|
+
}[source.kind] ?? '当前任务对应的相关证据';
|
|
590
|
+
return `${source.kind}: ${genericLabel}`;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
function renderEvidenceSources(evidenceSources, options = {}) {
|
|
579
594
|
return renderList(
|
|
580
|
-
evidenceSources.map((source) =>
|
|
595
|
+
evidenceSources.map((source) => describeEvidenceSource(source, options)),
|
|
581
596
|
'当前来源没有显式证据清单,后续应补齐标准诊断目录。',
|
|
582
597
|
)
|
|
583
598
|
}
|
|
@@ -608,6 +623,18 @@ function renderCorrelationSection({ correlationFields, extraContextFields, missi
|
|
|
608
623
|
}
|
|
609
624
|
|
|
610
625
|
export function renderExperienceSkill({ skillName, source }) {
|
|
626
|
+
const stableProblemSummary = source.kind === 'quality-report'
|
|
627
|
+
? (
|
|
628
|
+
source.attentionGates.length > 0
|
|
629
|
+
? `当前任务的质量收口与门禁闭环(${source.attentionGates.slice(0, 4).join(', ')})`
|
|
630
|
+
: '当前任务的质量收口与门禁闭环'
|
|
631
|
+
)
|
|
632
|
+
: (
|
|
633
|
+
source.rootCauseCandidates[0]?.title
|
|
634
|
+
?? source.eventNames[0]
|
|
635
|
+
?? source.symptoms[0]
|
|
636
|
+
?? '当前任务对应的问题症状'
|
|
637
|
+
);
|
|
611
638
|
const triggers = source.kind === 'quality-report'
|
|
612
639
|
? [
|
|
613
640
|
'某项任务改动了前端、后端、agent 工作流或错误处理行为。',
|
|
@@ -626,9 +653,9 @@ export function renderExperienceSkill({ skillName, source }) {
|
|
|
626
653
|
: '适用于已经拿到 runtime-events、timeline、root-cause-candidates 或 diagnostic-report 的排查任务。',
|
|
627
654
|
]
|
|
628
655
|
const typicalInputs = [
|
|
629
|
-
|
|
656
|
+
stableProblemSummary ? `问题摘要: ${stableProblemSummary}` : null,
|
|
630
657
|
source.evidenceSources.length > 0
|
|
631
|
-
?
|
|
658
|
+
? `可直接使用的证据类型: ${source.evidenceSources.slice(0, 4).map((item) => item.kind).join(';')}`
|
|
632
659
|
: null,
|
|
633
660
|
source.eventNames.length > 0 ? `关键事件: ${source.eventNames.join(' -> ')}` : null,
|
|
634
661
|
]
|
|
@@ -637,10 +664,23 @@ export function renderExperienceSkill({ skillName, source }) {
|
|
|
637
664
|
source.verificationSteps.length > 0 ? `最小验证链路: ${source.verificationSteps[0]}` : null,
|
|
638
665
|
'可复用的项目级 knowledge skill 或后续 candidate / incident / pattern 记录。',
|
|
639
666
|
]
|
|
667
|
+
const useWhen = source.kind === 'quality-report'
|
|
668
|
+
? 'Use when the current task is entering quality closeout and you should reuse a proven evidence and gate-check path instead of rebuilding the checklist from scratch.'
|
|
669
|
+
: 'Use when the current task overlaps this verified diagnosis pattern, symptoms, or touched files and you should reuse proven evidence before starting from scratch.'
|
|
670
|
+
const antiPatterns = [
|
|
671
|
+
source.kind === 'quality-report'
|
|
672
|
+
? '如果当前任务还没进入验证或收尾阶段,不要把这条经验当成通用实现模板直接套用。'
|
|
673
|
+
: '如果当前问题没有出现相似症状、关键事件或证据入口,不要只因为改到相似文件就直接套用这条经验。',
|
|
674
|
+
'如果只是文件名、路径或个别词相似,但当前目标、阶段或验证方式不同,不要直接照搬。',
|
|
675
|
+
source.evidenceSources.length > 0
|
|
676
|
+
? '如果本轮已经拿到更新的现场证据,先核对新证据,再决定是否复用这条经验。'
|
|
677
|
+
: null,
|
|
678
|
+
]
|
|
640
679
|
|
|
641
680
|
return `---
|
|
642
681
|
name: ${skillName}
|
|
643
|
-
description:
|
|
682
|
+
description: ${useWhen}
|
|
683
|
+
use_when: ${useWhen}
|
|
644
684
|
---
|
|
645
685
|
|
|
646
686
|
# ${skillName}
|
|
@@ -663,7 +703,11 @@ ${renderList(typicalOutputs, '至少产出可复用结论、验证链路和后
|
|
|
663
703
|
|
|
664
704
|
## 先看哪些证据
|
|
665
705
|
|
|
666
|
-
${renderEvidenceSources(source.evidenceSources)}
|
|
706
|
+
${renderEvidenceSources(source.evidenceSources, { genericPaths: true })}
|
|
707
|
+
|
|
708
|
+
## 不要直接套用
|
|
709
|
+
|
|
710
|
+
${renderList(antiPatterns, '如果只是表面相似,但目标和验证方式不一致,不要直接套用。')}
|
|
667
711
|
|
|
668
712
|
## 关联字段
|
|
669
713
|
|
package/src/quality.js
CHANGED
|
@@ -1019,7 +1019,7 @@ function detectKnowledge({ config, knowledgeFiles, candidateState, knowledgeInde
|
|
|
1019
1019
|
warnings.push('本次已经达到可交付状态,但还没有自动生成 knowledge candidate;收工前至少保留一条可审查的项目经验草案。');
|
|
1020
1020
|
}
|
|
1021
1021
|
if (config.knowledge.enabled && skills.length > 0 && adoption.totals.referenced === 0) {
|
|
1022
|
-
warnings.push('项目级经验 skill 已产出,但还没有任何 run-context
|
|
1022
|
+
warnings.push('项目级经验 skill 已产出,但还没有任何 run-context 引用记录;优先接入候选召回与判断注入链路。');
|
|
1023
1023
|
}
|
|
1024
1024
|
return {
|
|
1025
1025
|
status: !config.knowledge.enabled || hasReusableArtifact ? 'pass' : 'needs-attention',
|
|
@@ -1444,7 +1444,7 @@ export async function learnQualityWorkspace(projectRoot, options = {}) {
|
|
|
1444
1444
|
};
|
|
1445
1445
|
}
|
|
1446
1446
|
const source = resolved.source;
|
|
1447
|
-
const { incidentId, patternId, skillName } = deriveKnowledgeNames(source);
|
|
1447
|
+
const { incidentId, patternId, skillName } = deriveKnowledgeNames(source, { stablePattern: true });
|
|
1448
1448
|
const incidentPath = qualityPath(projectRoot, cjoin(KNOWLEDGE_DIR, 'incidents', `${incidentId}.json`));
|
|
1449
1449
|
const patternPath = qualityPath(projectRoot, cjoin(KNOWLEDGE_DIR, 'patterns', `${patternId}.json`));
|
|
1450
1450
|
const skillDir = qualityPath(projectRoot, cjoin(KNOWLEDGE_DIR, 'skills', skillName));
|