@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pcoliveira90/pdd",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Patch-Driven Development CLI — safe, resilient and guided code changes",
5
5
  "type": "module",
6
6
  "bin": {
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 { runAutomaticGapCheck, formatGapCheckSummary } from '../core/gap-checker.js';
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({
@@ -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. Present a concise proposal and ask the user to edit if needed.
388
- 7. Ask explicit approval before any file edits.
389
- 8. After approval, implement and validate.
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) Pending approval (explicit question)
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. Present concise proposal and allow user edits.
454
- 10. Ask explicit approval before editing files.
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
- 11. Propose minimal safe delta and alternatives considered.
458
- 12. Define verification plan (tests + manual checks + rollback).
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
- 13. Implement approved minimal change.
462
- 14. Validate and report residual risks.
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) Pending approval (explicit question)
493
+ 9) Best-practices suggestions (proposal-only)
494
+ 10) Pending approval (explicit question)
476
495
 
477
496
  After approval:
478
- 10) Files changed
479
- 11) Validation results
480
- 12) Residual risks
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. Present concise proposal and allow user edits.
507
- 9. Ask explicit approval before editing files.
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
- 10. Define smallest safe extension and non-goals.
511
- 11. Propose verification and rollback strategy.
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
- 12. Implement approved scope.
515
- 13. Validate compatibility and report residual risks.
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) Pending approval (explicit question)
547
+ 8) Best-practices suggestions (proposal-only)
548
+ 9) Pending approval (explicit question)
528
549
 
529
550
  After approval:
530
- 9) Files changed
531
- 10) Validation results
532
- 11) Residual risks
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)"