@pcoliveira90/pdd 0.5.1 → 0.6.0
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/package.json +1 -1
- package/src/cli/index.js +6 -1
- package/src/core/gap-checker.js +98 -0
- package/src/core/patch-generator.js +37 -0
- package/src/core/template-registry.js +45 -24
package/package.json
CHANGED
package/src/cli/index.js
CHANGED
|
@@ -13,7 +13,11 @@ import {
|
|
|
13
13
|
formatRiskSummary,
|
|
14
14
|
enforceStructuralRiskAck
|
|
15
15
|
} from '../core/structural-risk-guard.js';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
runAutomaticGapCheck,
|
|
18
|
+
formatGapCheckSummary,
|
|
19
|
+
formatBestPracticesSummary
|
|
20
|
+
} from '../core/gap-checker.js';
|
|
17
21
|
import { maybeAutoRelocateToWorktree } from '../core/worktree-guard.js';
|
|
18
22
|
|
|
19
23
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -112,6 +116,7 @@ export async function runCli(argv = process.argv.slice(2)) {
|
|
|
112
116
|
minCoverage
|
|
113
117
|
});
|
|
114
118
|
console.log(formatGapCheckSummary(gapCheck));
|
|
119
|
+
console.log(formatBestPracticesSummary(gapCheck));
|
|
115
120
|
|
|
116
121
|
try {
|
|
117
122
|
await enforceStructuralRiskAck({
|
package/src/core/gap-checker.js
CHANGED
|
@@ -17,6 +17,74 @@ function mapTasks(issue, riskAssessment) {
|
|
|
17
17
|
return tasks;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function runBestPracticesSuggestions({ normalizedIssue, riskAssessment, minCoverage }) {
|
|
21
|
+
const suggestions = [];
|
|
22
|
+
|
|
23
|
+
const hasRollback = hasAny(normalizedIssue, [
|
|
24
|
+
/\brollback\b/i,
|
|
25
|
+
/\broll back\b/i,
|
|
26
|
+
/\bplano de volta\b/i,
|
|
27
|
+
/\bconting[eê]ncia\b/i
|
|
28
|
+
]);
|
|
29
|
+
if (!hasRollback) {
|
|
30
|
+
suggestions.push({
|
|
31
|
+
id: 'bp-rollback-plan',
|
|
32
|
+
title: 'Define rollback plan before implementation',
|
|
33
|
+
proposal: 'Add a short rollback/contingency plan and get user approval before applying changes.',
|
|
34
|
+
requiresApproval: true
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const hasMonitoring = hasAny(normalizedIssue, [
|
|
39
|
+
/\bmonitor(a[cç][aã]o|ing)\b/i,
|
|
40
|
+
/\bobservability\b/i,
|
|
41
|
+
/\blog(s)?\b/i,
|
|
42
|
+
/\bmetric(s)?\b/i,
|
|
43
|
+
/\btelemetry\b/i
|
|
44
|
+
]);
|
|
45
|
+
if (!hasMonitoring) {
|
|
46
|
+
suggestions.push({
|
|
47
|
+
id: 'bp-observability',
|
|
48
|
+
title: 'Add observability checks',
|
|
49
|
+
proposal: 'Propose minimal logs/metrics verification for post-change validation and ask user approval.',
|
|
50
|
+
requiresApproval: true
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (riskAssessment?.hasHighRisk) {
|
|
55
|
+
const hasGradualRollout = hasAny(normalizedIssue, [
|
|
56
|
+
/\bfeature flag\b/i,
|
|
57
|
+
/\bcanary\b/i,
|
|
58
|
+
/\bgradual\b/i,
|
|
59
|
+
/\bstaged\b/i
|
|
60
|
+
]);
|
|
61
|
+
if (!hasGradualRollout) {
|
|
62
|
+
suggestions.push({
|
|
63
|
+
id: 'bp-gradual-rollout',
|
|
64
|
+
title: 'Consider gradual rollout for structural-risk changes',
|
|
65
|
+
proposal: 'Propose feature-flag/canary rollout strategy and wait for explicit user agreement.',
|
|
66
|
+
requiresApproval: true
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const hasCoverageTarget = hasAny(normalizedIssue, [
|
|
72
|
+
/\bcoverage\b/i,
|
|
73
|
+
/\bcobertura\b/i,
|
|
74
|
+
new RegExp(String(minCoverage))
|
|
75
|
+
]);
|
|
76
|
+
if (!hasCoverageTarget) {
|
|
77
|
+
suggestions.push({
|
|
78
|
+
id: 'bp-coverage-target',
|
|
79
|
+
title: 'Set explicit coverage target in proposal',
|
|
80
|
+
proposal: `Propose explicit coverage target (minimum ${minCoverage}%) and confirm with user before implementation.`,
|
|
81
|
+
requiresApproval: true
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return suggestions;
|
|
86
|
+
}
|
|
87
|
+
|
|
20
88
|
export function runAutomaticGapCheck({ issue = '', riskAssessment = null, minCoverage = 80 }) {
|
|
21
89
|
const normalized = String(issue || '').toLowerCase();
|
|
22
90
|
const mappedTasks = mapTasks(normalized, riskAssessment);
|
|
@@ -106,10 +174,23 @@ export function runAutomaticGapCheck({ issue = '', riskAssessment = null, minCov
|
|
|
106
174
|
|
|
107
175
|
const criticalCount = gaps.filter(gap => gap.severity === 'critical').length;
|
|
108
176
|
const highCount = gaps.filter(gap => gap.severity === 'high').length;
|
|
177
|
+
const bestPracticeSuggestions = runBestPracticesSuggestions({
|
|
178
|
+
normalizedIssue: normalized,
|
|
179
|
+
riskAssessment,
|
|
180
|
+
minCoverage
|
|
181
|
+
});
|
|
109
182
|
|
|
110
183
|
return {
|
|
111
184
|
mappedTasks,
|
|
112
185
|
gaps,
|
|
186
|
+
bestPractices: {
|
|
187
|
+
mode: 'suggestion-only',
|
|
188
|
+
requiresApproval: true,
|
|
189
|
+
suggestions: bestPracticeSuggestions,
|
|
190
|
+
summary: {
|
|
191
|
+
total: bestPracticeSuggestions.length
|
|
192
|
+
}
|
|
193
|
+
},
|
|
113
194
|
summary: {
|
|
114
195
|
total: gaps.length,
|
|
115
196
|
critical: criticalCount,
|
|
@@ -126,3 +207,20 @@ export function formatGapCheckSummary(gapCheck) {
|
|
|
126
207
|
|
|
127
208
|
return `Automatic gap check: ${gapCheck.summary.total} gap(s) detected (${gapCheck.summary.critical} critical, ${gapCheck.summary.high} high).`;
|
|
128
209
|
}
|
|
210
|
+
|
|
211
|
+
export function formatBestPracticesSummary(gapCheck) {
|
|
212
|
+
const bestPractices = gapCheck?.bestPractices;
|
|
213
|
+
if (!bestPractices) {
|
|
214
|
+
return 'Best-practices check: unavailable.';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const count = bestPractices.summary?.total || 0;
|
|
218
|
+
if (count === 0) {
|
|
219
|
+
return 'Best-practices check (suggestion-only): no additional suggestions.';
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return [
|
|
223
|
+
`Best-practices check (suggestion-only): ${count} suggestion(s).`,
|
|
224
|
+
'No suggestion should be applied automatically without explicit user approval.'
|
|
225
|
+
].join('\n');
|
|
226
|
+
}
|
|
@@ -49,6 +49,34 @@ function renderGapCheckSection(gapCheck) {
|
|
|
49
49
|
return lines.join('\n');
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
function renderBestPracticesSection(gapCheck) {
|
|
53
|
+
const bestPractices = gapCheck?.bestPractices;
|
|
54
|
+
if (!bestPractices) {
|
|
55
|
+
return '- status: unavailable';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const suggestions = Array.isArray(bestPractices.suggestions)
|
|
59
|
+
? bestPractices.suggestions
|
|
60
|
+
: [];
|
|
61
|
+
|
|
62
|
+
if (suggestions.length === 0) {
|
|
63
|
+
return '- mode: suggestion-only\n- suggestions: none';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const lines = [
|
|
67
|
+
'- mode: suggestion-only',
|
|
68
|
+
`- total suggestions: ${suggestions.length}`,
|
|
69
|
+
'- policy: do not apply any suggestion without explicit user approval'
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
for (const item of suggestions) {
|
|
73
|
+
lines.push(`- ${item.title} (${item.id})`);
|
|
74
|
+
lines.push(` proposal: ${item.proposal}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return lines.join('\n');
|
|
78
|
+
}
|
|
79
|
+
|
|
52
80
|
function renderMappedTasksSection(gapCheck) {
|
|
53
81
|
if (!gapCheck || !Array.isArray(gapCheck.mappedTasks) || gapCheck.mappedTasks.length === 0) {
|
|
54
82
|
return '- not available';
|
|
@@ -184,6 +212,9 @@ ${renderStructuralRiskSection(riskAssessment)}
|
|
|
184
212
|
## Automatic Gap Check
|
|
185
213
|
${renderGapCheckSection(gapCheck)}
|
|
186
214
|
|
|
215
|
+
## Best-Practices Suggestions (Approval Required)
|
|
216
|
+
${renderBestPracticesSection(gapCheck)}
|
|
217
|
+
|
|
187
218
|
## Minimal Safe Delta
|
|
188
219
|
|
|
189
220
|
## Alternatives Considered
|
|
@@ -226,6 +257,9 @@ ${renderStructuralRiskSection(riskAssessment)}
|
|
|
226
257
|
## Automatic Gap Check
|
|
227
258
|
${renderGapCheckSection(gapCheck)}
|
|
228
259
|
|
|
260
|
+
## Best-Practices Suggestions (Approval Required)
|
|
261
|
+
${renderBestPracticesSection(gapCheck)}
|
|
262
|
+
|
|
229
263
|
## Rollback Strategy
|
|
230
264
|
`
|
|
231
265
|
);
|
|
@@ -276,6 +310,9 @@ ${renderMappedTasksSection(gapCheck)}
|
|
|
276
310
|
## Automatic Gap Check Summary
|
|
277
311
|
${renderGapCheckSection(gapCheck)}
|
|
278
312
|
|
|
313
|
+
## Best-Practices Suggestions (Approval Required)
|
|
314
|
+
${renderBestPracticesSection(gapCheck)}
|
|
315
|
+
|
|
279
316
|
## Reviewer Decision
|
|
280
317
|
- approved: yes | no
|
|
281
318
|
- notes:
|
|
@@ -68,6 +68,11 @@ bugfix | feature | refactor-safe | hotfix
|
|
|
68
68
|
- API/event contract compatibility impact
|
|
69
69
|
- rollout/rollback complexity impact
|
|
70
70
|
|
|
71
|
+
## Best-Practices Suggestions (Approval Required)
|
|
72
|
+
- suggestion-only mode
|
|
73
|
+
- proposal first
|
|
74
|
+
- explicit user approval required before applying
|
|
75
|
+
|
|
71
76
|
## Minimal Safe Delta
|
|
72
77
|
|
|
73
78
|
## Alternatives Considered
|
|
@@ -102,6 +107,11 @@ bugfix | feature | refactor-safe | hotfix
|
|
|
102
107
|
- API/event contract compatibility impact
|
|
103
108
|
- rollout/rollback complexity impact
|
|
104
109
|
|
|
110
|
+
## Best-Practices Suggestions (Approval Required)
|
|
111
|
+
- suggestion-only mode
|
|
112
|
+
- proposal first
|
|
113
|
+
- explicit user approval required before applying
|
|
114
|
+
|
|
105
115
|
## Rollback Strategy
|
|
106
116
|
`,
|
|
107
117
|
'.pdd/templates/verification-report.md': `# Verification Report
|
|
@@ -136,6 +146,11 @@ approved | needs-review | partial
|
|
|
136
146
|
|
|
137
147
|
## Automatic Gap Check Summary
|
|
138
148
|
|
|
149
|
+
## Best-Practices Suggestions (Approval Required)
|
|
150
|
+
- suggestion-only mode
|
|
151
|
+
- proposals:
|
|
152
|
+
- approved to apply: yes | no
|
|
153
|
+
|
|
139
154
|
## Gaps by Severity
|
|
140
155
|
- critical:
|
|
141
156
|
- high:
|
|
@@ -384,9 +399,10 @@ $ARGUMENTS
|
|
|
384
399
|
3. Map context + business rules (only essential points).
|
|
385
400
|
4. Map key risks (regression, structural, usability, security).
|
|
386
401
|
5. Run automatic gap check after task mapping.
|
|
387
|
-
6.
|
|
388
|
-
7.
|
|
389
|
-
8.
|
|
402
|
+
6. Run best-practices check in suggestion-only mode.
|
|
403
|
+
7. Present concise proposal (including selected suggestions) and ask the user to edit if needed.
|
|
404
|
+
8. Ask explicit approval before any file edits or suggestions application.
|
|
405
|
+
9. After approval, implement and validate.
|
|
390
406
|
|
|
391
407
|
## Output
|
|
392
408
|
|
|
@@ -398,7 +414,8 @@ Use this exact structure:
|
|
|
398
414
|
5) Concise proposal (editable by user)
|
|
399
415
|
6) Verification plan
|
|
400
416
|
7) Automatic gap check
|
|
401
|
-
8)
|
|
417
|
+
8) Best-practices suggestions (proposal-only)
|
|
418
|
+
9) Pending approval (explicit question)
|
|
402
419
|
`,
|
|
403
420
|
'.cursor/commands/pdd-recon.md': `---
|
|
404
421
|
description: "PDD — recon (explore before editing)"
|
|
@@ -450,16 +467,17 @@ $ARGUMENTS
|
|
|
450
467
|
7. Build risk map (regression, data/contract, performance/ops, usability, security).
|
|
451
468
|
- Flag structural-impact actions explicitly (database/schema/migrations/contracts).
|
|
452
469
|
8. Run automatic gap check immediately after task mapping and risk mapping.
|
|
453
|
-
9.
|
|
454
|
-
10.
|
|
470
|
+
9. Run best-practices check in suggestion-only mode.
|
|
471
|
+
10. Present concise proposal and allow user edits.
|
|
472
|
+
11. Ask explicit approval before editing files or applying suggestions.
|
|
455
473
|
|
|
456
474
|
### Phase 2 — Plan (no edits)
|
|
457
|
-
|
|
458
|
-
|
|
475
|
+
12. Propose minimal safe delta and alternatives considered.
|
|
476
|
+
13. Define verification plan (tests + manual checks + rollback).
|
|
459
477
|
|
|
460
478
|
### Phase 3 — Execution (after approval)
|
|
461
|
-
|
|
462
|
-
|
|
479
|
+
14. Implement approved minimal change.
|
|
480
|
+
15. Validate and report residual risks.
|
|
463
481
|
|
|
464
482
|
## Output
|
|
465
483
|
|
|
@@ -472,12 +490,13 @@ Use this exact structure:
|
|
|
472
490
|
6) Concise proposal (editable by user)
|
|
473
491
|
7) Verification + coverage plan
|
|
474
492
|
8) Automatic gap check
|
|
475
|
-
9)
|
|
493
|
+
9) Best-practices suggestions (proposal-only)
|
|
494
|
+
10) Pending approval (explicit question)
|
|
476
495
|
|
|
477
496
|
After approval:
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
497
|
+
11) Files changed
|
|
498
|
+
12) Validation results
|
|
499
|
+
13) Residual risks
|
|
481
500
|
`,
|
|
482
501
|
'.cursor/commands/pdd-feature.md': `---
|
|
483
502
|
description: "PDD — feature (safe extension)"
|
|
@@ -503,16 +522,17 @@ $ARGUMENTS
|
|
|
503
522
|
6. Build risk map (compatibility, regression, data, performance, operational, usability, security).
|
|
504
523
|
- Flag structural-impact actions explicitly (database/schema/migrations/contracts).
|
|
505
524
|
7. Run automatic gap check immediately after task mapping and risk mapping.
|
|
506
|
-
8.
|
|
507
|
-
9.
|
|
525
|
+
8. Run best-practices check in suggestion-only mode.
|
|
526
|
+
9. Present concise proposal and allow user edits.
|
|
527
|
+
10. Ask explicit approval before editing files or applying suggestions.
|
|
508
528
|
|
|
509
529
|
### Phase 2 — Plan (no edits)
|
|
510
|
-
|
|
511
|
-
|
|
530
|
+
11. Define smallest safe extension and non-goals.
|
|
531
|
+
12. Propose verification and rollback strategy.
|
|
512
532
|
|
|
513
533
|
### Phase 3 — Execution (after approval)
|
|
514
|
-
|
|
515
|
-
|
|
534
|
+
13. Implement approved scope.
|
|
535
|
+
14. Validate compatibility and report residual risks.
|
|
516
536
|
|
|
517
537
|
## Output
|
|
518
538
|
|
|
@@ -524,12 +544,13 @@ Use this exact structure:
|
|
|
524
544
|
5) Concise proposal (editable by user)
|
|
525
545
|
6) Verification + coverage + rollback plan
|
|
526
546
|
7) Automatic gap check
|
|
527
|
-
8)
|
|
547
|
+
8) Best-practices suggestions (proposal-only)
|
|
548
|
+
9) Pending approval (explicit question)
|
|
528
549
|
|
|
529
550
|
After approval:
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
551
|
+
10) Files changed
|
|
552
|
+
11) Validation results
|
|
553
|
+
12) Residual risks
|
|
533
554
|
`,
|
|
534
555
|
'.cursor/commands/pdd-verify.md': `---
|
|
535
556
|
description: "PDD — verify (validation checklist)"
|