cc-devflow 4.5.0 → 4.5.2

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.
Files changed (75) hide show
  1. package/.claude/skills/cc-act/CHANGELOG.md +14 -0
  2. package/.claude/skills/cc-act/PLAYBOOK.md +26 -1
  3. package/.claude/skills/cc-act/SKILL.md +36 -7
  4. package/.claude/skills/cc-act/assets/PR_BRIEF_TEMPLATE.md +20 -0
  5. package/.claude/skills/cc-act/references/closure-contract.md +8 -0
  6. package/.claude/skills/cc-act/scripts/cc-act-common.sh +6 -1
  7. package/.claude/skills/cc-act/scripts/render-pr-brief.sh +99 -0
  8. package/.claude/skills/cc-act/scripts/verify-act-gate.sh +17 -1
  9. package/.claude/skills/cc-check/CHANGELOG.md +14 -0
  10. package/.claude/skills/cc-check/PLAYBOOK.md +101 -1
  11. package/.claude/skills/cc-check/SKILL.md +128 -7
  12. package/.claude/skills/cc-check/assets/REPORT_CARD_TEMPLATE.json +121 -1
  13. package/.claude/skills/cc-check/references/review-contract.md +88 -0
  14. package/.claude/skills/cc-check/scripts/render-report-card.js +172 -5
  15. package/.claude/skills/cc-check/scripts/verify-gate.sh +21 -0
  16. package/.claude/skills/cc-investigate/CHANGELOG.md +13 -0
  17. package/.claude/skills/cc-investigate/PLAYBOOK.md +105 -4
  18. package/.claude/skills/cc-investigate/SKILL.md +185 -8
  19. package/.claude/skills/cc-investigate/assets/ANALYSIS_TEMPLATE.md +77 -3
  20. package/.claude/skills/cc-investigate/assets/TASKS_TEMPLATE.md +10 -3
  21. package/.claude/skills/cc-investigate/assets/TASK_MANIFEST_TEMPLATE.json +102 -1
  22. package/.claude/skills/cc-investigate/references/investigation-contract.md +146 -0
  23. package/.claude/skills/cc-plan/CHANGELOG.md +14 -0
  24. package/.claude/skills/cc-plan/PLAYBOOK.md +19 -2
  25. package/.claude/skills/cc-plan/SKILL.md +52 -20
  26. package/.claude/skills/cc-plan/assets/DESIGN_TEMPLATE.md +70 -1
  27. package/.claude/skills/cc-plan/assets/TASKS_TEMPLATE.md +13 -0
  28. package/.claude/skills/cc-plan/assets/TASK_MANIFEST_TEMPLATE.json +3 -1
  29. package/.claude/skills/cc-plan/assets/TINY_DESIGN_TEMPLATE.md +22 -0
  30. package/.claude/skills/cc-roadmap/CHANGELOG.md +12 -0
  31. package/.claude/skills/cc-roadmap/PLAYBOOK.md +24 -1
  32. package/.claude/skills/cc-roadmap/SKILL.md +50 -15
  33. package/.claude/skills/cc-roadmap/assets/BACKLOG_TEMPLATE.md +15 -0
  34. package/.claude/skills/cc-roadmap/assets/ROADMAP_TEMPLATE.md +37 -0
  35. package/.claude/skills/cc-roadmap/assets/TRACKING_TEMPLATE.json +2 -1
  36. package/.claude/skills/cc-simplify/CHANGELOG.md +15 -0
  37. package/.claude/skills/cc-simplify/SKILL.md +255 -35
  38. package/CHANGELOG.md +36 -0
  39. package/CODE_OF_CONDUCT.md +39 -0
  40. package/CODE_OF_CONDUCT.zh-CN.md +39 -0
  41. package/CONTRIBUTING.md +195 -0
  42. package/CONTRIBUTING.zh-CN.md +195 -0
  43. package/README.md +141 -150
  44. package/README.zh-CN.md +144 -148
  45. package/SECURITY.md +56 -0
  46. package/SECURITY.zh-CN.md +56 -0
  47. package/docs/examples/example-bindings.json +6 -6
  48. package/docs/examples/full-design-blocked/BACKLOG.md +1 -1
  49. package/docs/examples/full-design-blocked/README.md +1 -1
  50. package/docs/examples/full-design-blocked/ROADMAP.md +1 -1
  51. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/design.md +1 -1
  52. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/tasks.md +1 -1
  53. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/review/report-card.json +140 -3
  54. package/docs/examples/full-design-blocked/roadmap-tracking.json +1 -1
  55. package/docs/examples/local-handoff/BACKLOG.md +1 -1
  56. package/docs/examples/local-handoff/README.md +1 -1
  57. package/docs/examples/local-handoff/ROADMAP.md +1 -1
  58. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/design.md +1 -1
  59. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/tasks.md +1 -1
  60. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/review/report-card.json +92 -0
  61. package/docs/examples/local-handoff/roadmap-tracking.json +1 -1
  62. package/docs/examples/pdca-loop/BACKLOG.md +1 -1
  63. package/docs/examples/pdca-loop/README.md +1 -1
  64. package/docs/examples/pdca-loop/ROADMAP.md +1 -1
  65. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/pr-brief.md +20 -0
  66. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/design.md +1 -1
  67. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json +2 -2
  68. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/tasks.md +1 -1
  69. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/review/report-card.json +92 -0
  70. package/docs/examples/pdca-loop/roadmap-tracking.json +1 -1
  71. package/docs/guides/getting-started.md +5 -0
  72. package/docs/guides/getting-started.zh-CN.md +5 -0
  73. package/lib/skill-runtime/review.js +64 -1
  74. package/lib/skill-runtime/schemas.js +150 -3
  75. package/package.json +7 -1
@@ -79,6 +79,7 @@ function makeFinding({
79
79
  status = 'open',
80
80
  fingerprint
81
81
  }) {
82
+ const confidenceScore = severityRank(severity) >= severityRank('important') ? 8 : 6;
82
83
  return {
83
84
  id,
84
85
  source,
@@ -91,7 +92,12 @@ function makeFinding({
91
92
  ...(typeof line === 'number' ? { line } : {}),
92
93
  action,
93
94
  status,
94
- ...(fingerprint ? { fingerprint } : {})
95
+ confidenceScore,
96
+ fingerprint: fingerprint || `${source}:${category}:${id}`,
97
+ displayTier: status === 'informational'
98
+ ? 'info'
99
+ : (severityRank(severity) >= severityRank('important') ? 'blocking' : 'warning'),
100
+ suppressionReason: null
95
101
  };
96
102
  }
97
103
 
@@ -231,6 +237,14 @@ async function detectBaseRef(repoRoot) {
231
237
  return 'HEAD~1';
232
238
  }
233
239
 
240
+ async function detectCurrentCommit(repoRoot) {
241
+ const result = await runCommand('git rev-parse --short HEAD', { cwd: repoRoot });
242
+ if (result.code === 0 && result.stdout.trim()) {
243
+ return result.stdout.trim();
244
+ }
245
+ return 'working-tree';
246
+ }
247
+
234
248
  async function runCodexStructuredReview({ repoRoot, baseRef }) {
235
249
  const command = [
236
250
  'codex review',
@@ -530,6 +544,7 @@ async function runReviewSuite({ repoRoot, changeId, manifest, strict, skipReview
530
544
  const diffReview = await runDiffReviewSection({ repoRoot, strict, skipReview });
531
545
  const findings = flattenFindings(taskReviews, diffReview);
532
546
  const status = deriveReviewStatus(taskReviews, diffReview);
547
+ const currentCommit = await detectCurrentCommit(repoRoot);
533
548
  const details = [
534
549
  taskReviews.summary,
535
550
  diffReview.summary
@@ -539,6 +554,54 @@ async function runReviewSuite({ repoRoot, changeId, manifest, strict, skipReview
539
554
  status,
540
555
  summary: `Task review: ${taskReviews.status}. Diff review: ${diffReview.status}.`,
541
556
  details,
557
+ freshness: {
558
+ status: 'fresh',
559
+ reviewedCommit: currentCommit,
560
+ currentCommit,
561
+ commitsSinceReview: 0,
562
+ staleReason: ''
563
+ },
564
+ qualityScore: status === 'pass' ? 9 : (status === 'blocked' ? 5 : 3),
565
+ specialistReviews: [
566
+ {
567
+ name: 'testing',
568
+ status: taskReviews.status,
569
+ required: true,
570
+ summary: taskReviews.summary,
571
+ skipReason: '',
572
+ findings: []
573
+ }
574
+ ],
575
+ runtime: {
576
+ status: status === 'pass' ? 'pass' : (status === 'fail' ? 'fail' : 'blocked'),
577
+ failureOwnership: []
578
+ },
579
+ qa: {
580
+ status: 'pass',
581
+ regressionProof: [],
582
+ testQuality: [],
583
+ coverageAudit: {
584
+ status: 'pass',
585
+ coveragePct: null,
586
+ pathMap: [],
587
+ gaps: [],
588
+ testsAdded: [],
589
+ e2eRequired: false,
590
+ evalRequired: false,
591
+ qualityStars: ''
592
+ },
593
+ browserEvidence: {
594
+ status: 'skipped',
595
+ mode: 'not-applicable',
596
+ affectedRoutes: [],
597
+ screenshots: [],
598
+ consoleErrors: [],
599
+ healthScore: null,
600
+ issues: [],
601
+ skipReason: 'runtime verify did not identify a UI browser QA target'
602
+ },
603
+ tddException: null
604
+ },
542
605
  taskReviews,
543
606
  diffReview,
544
607
  findings
@@ -269,8 +269,26 @@ const GateResultSchema = z.object({
269
269
  });
270
270
 
271
271
  const ReviewSeveritySchema = z.enum(['critical', 'important', 'minor', 'info']);
272
- const ReviewActionSchema = z.enum(['fix_now', 'follow_up', 'cc-investigate', 'none']);
273
- const ReviewFindingStatusSchema = z.enum(['open', 'resolved', 'accepted', 'informational']);
272
+ const ReviewActionSchema = z.enum([
273
+ 'fix_now',
274
+ 'follow_up',
275
+ 'cc-investigate',
276
+ 'reroute-cc-do',
277
+ 'reroute-cc-plan',
278
+ 'reroute-cc-investigate',
279
+ 'document-follow-up',
280
+ 'none'
281
+ ]);
282
+ const ReviewFindingStatusSchema = z.enum([
283
+ 'open',
284
+ 'resolved',
285
+ 'accepted',
286
+ 'informational',
287
+ 'accepted-fixed',
288
+ 'rejected-with-evidence',
289
+ 'deferred-minor',
290
+ 'clarification-needed'
291
+ ]);
274
292
 
275
293
  const ReviewEvidenceSchema = z.object({
276
294
  kind: z.enum(['command', 'file', 'note']),
@@ -291,7 +309,11 @@ const ReviewFindingSchema = z.object({
291
309
  line: z.number().int().min(1).optional(),
292
310
  action: ReviewActionSchema.default('none'),
293
311
  status: ReviewFindingStatusSchema.default('open'),
294
- fingerprint: z.string().optional()
312
+ fingerprint: z.string().optional(),
313
+ confidence: z.enum(['high', 'medium', 'low']).optional(),
314
+ confidenceScore: z.number().min(1).max(10).optional(),
315
+ displayTier: z.enum(['blocking', 'warning', 'info', 'suppressed']).optional(),
316
+ suppressionReason: z.string().nullable().optional()
295
317
  });
296
318
 
297
319
  const ReviewerResultSchema = z.object({
@@ -317,6 +339,28 @@ const ReportReviewSchema = z.object({
317
339
  status: ReviewDecisionStatusSchema.default('skipped'),
318
340
  summary: z.string().default(''),
319
341
  details: z.string().default(''),
342
+ freshness: z.object({
343
+ status: z.enum(['fresh', 'stale', 'unknown', 'not-applicable']).default('unknown'),
344
+ reviewedCommit: z.string().default(''),
345
+ currentCommit: z.string().default(''),
346
+ commitsSinceReview: z.number().int().min(0).nullable().default(null),
347
+ staleReason: z.string().default('')
348
+ }).default({
349
+ status: 'unknown',
350
+ reviewedCommit: '',
351
+ currentCommit: '',
352
+ commitsSinceReview: null,
353
+ staleReason: ''
354
+ }),
355
+ qualityScore: z.number().min(0).max(10).nullable().default(null),
356
+ specialistReviews: z.array(z.object({
357
+ name: z.string().min(1),
358
+ status: ReviewDecisionStatusSchema,
359
+ required: z.boolean().default(false),
360
+ summary: z.string().default(''),
361
+ skipReason: z.string().default(''),
362
+ findings: z.array(ReviewFindingSchema).default([])
363
+ })).default([]),
320
364
  taskReviews: ReviewSectionSchema.default({
321
365
  status: 'skipped',
322
366
  required: false,
@@ -334,15 +378,118 @@ const ReportReviewSchema = z.object({
334
378
  findings: z.array(ReviewFindingSchema).default([])
335
379
  });
336
380
 
381
+ const ClaimEvidenceSchema = z.object({
382
+ claim: z.string().min(1),
383
+ requiredProof: z.string().min(1),
384
+ commandOrArtifact: z.string().min(1),
385
+ exitStatus: z.number().int().nullable().optional(),
386
+ keyObservation: z.string().default(''),
387
+ status: ReviewDecisionStatusSchema
388
+ });
389
+
390
+ const RuntimeFailureOwnershipSchema = z.object({
391
+ failure: z.string().min(1),
392
+ classification: z.enum(['in-branch', 'pre-existing', 'environment', 'ambiguous']),
393
+ touchedByDiff: z.boolean().optional(),
394
+ evidence: z.string().default(''),
395
+ action: z.string().default(''),
396
+ status: z.string().default('open')
397
+ });
398
+
399
+ const ReportRuntimeSchema = z.object({
400
+ status: ReviewDecisionStatusSchema.default('skipped'),
401
+ failureOwnership: z.array(RuntimeFailureOwnershipSchema).default([])
402
+ }).default({
403
+ status: 'skipped',
404
+ failureOwnership: []
405
+ });
406
+
407
+ const QaSchema = z.object({
408
+ status: ReviewDecisionStatusSchema.default('skipped'),
409
+ regressionProof: z.array(z.record(z.any())).default([]),
410
+ testQuality: z.array(z.record(z.any())).default([]),
411
+ coverageAudit: z.object({
412
+ status: ReviewDecisionStatusSchema.default('skipped'),
413
+ coveragePct: z.number().nullable().default(null),
414
+ pathMap: z.array(z.string()).default([]),
415
+ gaps: z.array(z.string()).default([]),
416
+ testsAdded: z.array(z.string()).default([]),
417
+ e2eRequired: z.boolean().default(false),
418
+ evalRequired: z.boolean().default(false),
419
+ qualityStars: z.string().default('')
420
+ }).default({
421
+ status: 'skipped',
422
+ coveragePct: null,
423
+ pathMap: [],
424
+ gaps: [],
425
+ testsAdded: [],
426
+ e2eRequired: false,
427
+ evalRequired: false,
428
+ qualityStars: ''
429
+ }),
430
+ browserEvidence: z.object({
431
+ status: ReviewDecisionStatusSchema.default('skipped'),
432
+ mode: z.string().default('not-applicable'),
433
+ affectedRoutes: z.array(z.string()).default([]),
434
+ screenshots: z.array(z.string()).default([]),
435
+ consoleErrors: z.array(z.string()).default([]),
436
+ healthScore: z.number().nullable().default(null),
437
+ issues: z.array(z.record(z.any())).default([]),
438
+ skipReason: z.string().default('')
439
+ }).default({
440
+ status: 'skipped',
441
+ mode: 'not-applicable',
442
+ affectedRoutes: [],
443
+ screenshots: [],
444
+ consoleErrors: [],
445
+ healthScore: null,
446
+ issues: [],
447
+ skipReason: ''
448
+ }),
449
+ tddException: z.string().nullable().default(null)
450
+ }).default({
451
+ status: 'skipped',
452
+ regressionProof: [],
453
+ testQuality: [],
454
+ coverageAudit: {
455
+ status: 'skipped',
456
+ coveragePct: null,
457
+ pathMap: [],
458
+ gaps: [],
459
+ testsAdded: [],
460
+ e2eRequired: false,
461
+ evalRequired: false,
462
+ qualityStars: ''
463
+ },
464
+ browserEvidence: {
465
+ status: 'skipped',
466
+ mode: 'not-applicable',
467
+ affectedRoutes: [],
468
+ screenshots: [],
469
+ consoleErrors: [],
470
+ healthScore: null,
471
+ issues: [],
472
+ skipReason: ''
473
+ },
474
+ tddException: null
475
+ });
476
+
337
477
  const ReportCardSchema = z.object({
338
478
  changeId: ChangeIdSchema,
339
479
  verdict: z.enum(['pass', 'fail', 'blocked']).optional(),
340
480
  overall: z.enum(['pass', 'fail']),
341
481
  summary: z.string().default(''),
482
+ specAlignment: z.enum(['pass', 'fail', 'blocked']).default('blocked'),
483
+ specDeltaVerified: z.boolean().default(false),
484
+ specSyncReady: z.boolean().default(false),
485
+ runtime: ReportRuntimeSchema,
486
+ claimEvidence: z.array(ClaimEvidenceSchema).default([]),
487
+ qa: QaSchema,
342
488
  quickGates: z.array(GateResultSchema),
343
489
  strictGates: z.array(GateResultSchema),
344
490
  review: ReportReviewSchema,
345
491
  blockingFindings: z.array(z.string()),
492
+ gaps: z.array(z.string()).default([]),
346
493
  reroute: z.enum(['none', 'cc-do', 'cc-investigate', 'cc-plan']).default('none'),
347
494
  timestamp: z.string().datetime()
348
495
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-devflow",
3
- "version": "4.5.0",
3
+ "version": "4.5.2",
4
4
  "description": "Multi-platform CLI and skill pack for agent coding",
5
5
  "main": "bin/cc-devflow.js",
6
6
  "bin": {
@@ -21,6 +21,12 @@
21
21
  "docs/",
22
22
  "README.md",
23
23
  "README.zh-CN.md",
24
+ "CONTRIBUTING.md",
25
+ "CONTRIBUTING.zh-CN.md",
26
+ "CODE_OF_CONDUCT.md",
27
+ "CODE_OF_CONDUCT.zh-CN.md",
28
+ "SECURITY.md",
29
+ "SECURITY.zh-CN.md",
24
30
  "CHANGELOG.md",
25
31
  "LICENSE",
26
32
  "package.json"