vibepro 0.1.0-alpha.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.
Files changed (89) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +9 -0
  3. package/README.ja.md +448 -0
  4. package/README.md +520 -0
  5. package/agent-instructions/codex/AGENTS.vibepro.md +45 -0
  6. package/bin/vibepro.js +9 -0
  7. package/docs/assets/vibepro-header.png +0 -0
  8. package/package.json +51 -0
  9. package/skills/vibepro-diagnosis-packages/SKILL.md +133 -0
  10. package/skills/vibepro-human-review/SKILL.md +73 -0
  11. package/skills/vibepro-story-refactor/SKILL.md +89 -0
  12. package/skills/vibepro-workflow/SKILL.md +139 -0
  13. package/src/agent-harness-map.js +230 -0
  14. package/src/agent-harness-scanner.js +337 -0
  15. package/src/agent-review.js +2180 -0
  16. package/src/api-boundary-scanner.js +452 -0
  17. package/src/architecture-profiler.js +423 -0
  18. package/src/authorization-scoring.js +149 -0
  19. package/src/brainbase-importer.js +534 -0
  20. package/src/change-risk-classifier.js +195 -0
  21. package/src/check-packs.js +605 -0
  22. package/src/checkpoint-manager.js +233 -0
  23. package/src/cli.js +2213 -0
  24. package/src/code-quality-scanner.js +310 -0
  25. package/src/codex-manager.js +143 -0
  26. package/src/component-style-scanner.js +336 -0
  27. package/src/coverage-report.js +99 -0
  28. package/src/database-access-scanner.js +163 -0
  29. package/src/decision-records.js +315 -0
  30. package/src/design-modernize.js +1435 -0
  31. package/src/design-system.js +1732 -0
  32. package/src/diagnostic-engine.js +1945 -0
  33. package/src/diagram-requirement-resolver.js +194 -0
  34. package/src/doctor.js +677 -0
  35. package/src/environment-graph.js +424 -0
  36. package/src/execution-state.js +849 -0
  37. package/src/explore-evidence.js +425 -0
  38. package/src/flow-design-scanner.js +896 -0
  39. package/src/flow-verifier.js +887 -0
  40. package/src/gesture-interaction-scanner.js +330 -0
  41. package/src/graph-context.js +263 -0
  42. package/src/graphify-adapter.js +189 -0
  43. package/src/html-report.js +1035 -0
  44. package/src/journey-map.js +1299 -0
  45. package/src/language.js +48 -0
  46. package/src/lazy-pattern-detector.js +182 -0
  47. package/src/local-dev-scanner.js +135 -0
  48. package/src/managed-worktree-gate.js +187 -0
  49. package/src/managed-worktree.js +766 -0
  50. package/src/merge-manager.js +501 -0
  51. package/src/network-contract-scanner.js +442 -0
  52. package/src/nocodb-story-sync.js +386 -0
  53. package/src/oss-readiness-scanner.js +417 -0
  54. package/src/performance-evidence.js +756 -0
  55. package/src/performance-measurer.js +591 -0
  56. package/src/pr-manager.js +8220 -0
  57. package/src/presets.js +682 -0
  58. package/src/public-discovery-scanner.js +519 -0
  59. package/src/refactoring-delta-reporter.js +367 -0
  60. package/src/refactoring-opportunity-generator.js +797 -0
  61. package/src/regression-risk-scanner.js +146 -0
  62. package/src/repo-status.js +266 -0
  63. package/src/report-fingerprint.js +188 -0
  64. package/src/report-pr-body-prompt-template.md +108 -0
  65. package/src/report-pr-body-schema.json +95 -0
  66. package/src/report-store.js +135 -0
  67. package/src/report-validator.js +192 -0
  68. package/src/requirement-consistency.js +1066 -0
  69. package/src/runtime-info.js +134 -0
  70. package/src/self-dogfood-scanner.js +476 -0
  71. package/src/session-learning.js +164 -0
  72. package/src/skills-manager.js +157 -0
  73. package/src/spec-drift.js +378 -0
  74. package/src/spec-fingerprint.js +445 -0
  75. package/src/spec-prompt-template.md +155 -0
  76. package/src/spec-schema.json +219 -0
  77. package/src/spec-store.js +258 -0
  78. package/src/spec-validator.js +459 -0
  79. package/src/static-site-scanner.js +316 -0
  80. package/src/story-candidate-generator.js +85 -0
  81. package/src/story-catalog-generator.js +2813 -0
  82. package/src/story-html.js +156 -0
  83. package/src/story-manager.js +2144 -0
  84. package/src/story-task-generator.js +522 -0
  85. package/src/task-manager.js +1029 -0
  86. package/src/terminal-link-scanner.js +238 -0
  87. package/src/usage-report.js +417 -0
  88. package/src/verification-evidence.js +284 -0
  89. package/src/workspace.js +126 -0
@@ -0,0 +1,195 @@
1
+ const WORKFLOW_KEYWORDS = [
2
+ /workflow/i,
3
+ /preflight/i,
4
+ /poll(?:ing)?/i,
5
+ /retry/i,
6
+ /queue/i,
7
+ /worker/i,
8
+ /\bstate\b/i,
9
+ /\bstatus\b/i,
10
+ /resume/i,
11
+ /legacy/i,
12
+ /\bv1\b/i,
13
+ /auth/i,
14
+ /認証/,
15
+ /状態/,
16
+ /再開/,
17
+ /検出/,
18
+ /キュー/
19
+ ];
20
+
21
+ export function classifyChangeRisk({ fileGroups = {}, storySource = {}, networkContracts = null, regressionRisk = null } = {}) {
22
+ const sourceFiles = fileGroups.source?.files ?? [];
23
+ const testFiles = fileGroups.tests?.files ?? [];
24
+ const allFiles = [
25
+ ...sourceFiles,
26
+ ...testFiles,
27
+ ...(fileGroups.repo_control?.files ?? []),
28
+ ...(fileGroups.story_docs?.files ?? []),
29
+ ...(fileGroups.specifications?.files ?? [])
30
+ ];
31
+ const storyText = [
32
+ storySource?.title,
33
+ storySource?.requirement_title,
34
+ storySource?.background,
35
+ storySource?.policy,
36
+ ...(storySource?.acceptance_criteria ?? [])
37
+ ].filter(Boolean).join(' ');
38
+ // Regression-risk hotspots that the diff actually touches. A changed module
39
+ // with a large call-graph blast radius (and, when coverage is known, a thin
40
+ // safety net) warrants heavier gates than its file paths alone would suggest.
41
+ const regressionHits = resolveRegressionHits({ sourceFiles, regressionRisk });
42
+ const criticalRegressionHits = regressionHits.filter((hit) => hit.priority === 'critical');
43
+ const highRegressionHits = regressionHits.filter((hit) => hit.risk_tier === 'high' || hit.priority === 'critical');
44
+ const riskSurfaces = detectRiskSurfaces({
45
+ sourceFiles,
46
+ allFiles,
47
+ storyText,
48
+ networkContracts,
49
+ hasRegressionBlastRadius: highRegressionHits.length > 0
50
+ });
51
+ const reasons = buildReasons({ riskSurfaces, sourceFiles, allFiles, storyText, networkContracts });
52
+ appendRegressionReasons(reasons, { criticalRegressionHits, highRegressionHits });
53
+ const hasWorkflowSignal = WORKFLOW_KEYWORDS.some((pattern) => pattern.test(storyText) || allFiles.some((file) => pattern.test(file)));
54
+ const crossSurface = riskSurfaces.filter((surface) => surface !== 'test_coverage').length >= 3;
55
+ const coreWorkflowHeavy = riskSurfaces.includes('core_workflow_state') && hasWorkflowSignal;
56
+ const baseProfile = (crossSurface && hasWorkflowSignal) || coreWorkflowHeavy
57
+ ? 'workflow_heavy'
58
+ : riskSurfaces.includes('frontend_interaction')
59
+ ? 'ui_interaction'
60
+ : (riskSurfaces.includes('server_api') || riskSurfaces.includes('auth_boundary') || riskSurfaces.includes('legacy_v1_compatibility'))
61
+ ? 'api_contract'
62
+ : 'light';
63
+ // A changed critical hotspot (large blast radius + low coverage) is the
64
+ // genuine regression trap, so it forces the heaviest gate profile outright.
65
+ const profile = criticalRegressionHits.length > 0 ? 'workflow_heavy' : baseProfile;
66
+ const changeType = profile === 'workflow_heavy'
67
+ ? 'cross_surface_workflow_change'
68
+ : profile === 'ui_interaction'
69
+ ? 'ui_interaction_change'
70
+ : profile === 'api_contract'
71
+ ? 'api_contract_change'
72
+ : 'simple_code_change';
73
+ return {
74
+ schema_version: '0.1.0',
75
+ profile,
76
+ change_type: changeType,
77
+ risk_surfaces: riskSurfaces,
78
+ reasons,
79
+ required_gate_profile: profile,
80
+ regression_hotspots: regressionHits,
81
+ regression_escalated: criticalRegressionHits.length > 0
82
+ };
83
+ }
84
+
85
+ function resolveRegressionHits({ sourceFiles, regressionRisk }) {
86
+ const hotspots = regressionRisk?.hotspots ?? [];
87
+ if (!Array.isArray(hotspots) || hotspots.length === 0) return [];
88
+ const changedSource = new Set(sourceFiles);
89
+ return hotspots
90
+ .filter((hotspot) => hotspot && changedSource.has(hotspot.file))
91
+ .map((hotspot) => ({
92
+ file: hotspot.file,
93
+ fan_in: hotspot.fan_in,
94
+ coverage_pct: hotspot.coverage_pct ?? null,
95
+ risk_tier: hotspot.risk_tier,
96
+ priority: hotspot.priority ?? hotspot.risk_tier
97
+ }));
98
+ }
99
+
100
+ function appendRegressionReasons(reasons, { criticalRegressionHits, highRegressionHits }) {
101
+ if (criticalRegressionHits.length > 0) {
102
+ const files = criticalRegressionHits.map((hit) => hit.file).join(', ');
103
+ reasons.push(`critical regression hotspot changed (large blast radius + low coverage): ${files}`);
104
+ } else if (highRegressionHits.length > 0) {
105
+ const files = highRegressionHits.map((hit) => hit.file).join(', ');
106
+ reasons.push(`high blast-radius module changed (many call-graph dependents): ${files}`);
107
+ }
108
+ }
109
+
110
+ function detectRiskSurfaces({ sourceFiles, allFiles, storyText, networkContracts, hasRegressionBlastRadius = false }) {
111
+ const surfaces = new Set();
112
+ if (hasRegressionBlastRadius) surfaces.add('regression_blast_radius');
113
+ if (sourceFiles.some(isUiPath)) surfaces.add('frontend_interaction');
114
+ if (sourceFiles.some(isApiPath) || (networkContracts?.introduced_api_client_call_count ?? 0) > 0) surfaces.add('server_api');
115
+ if (sourceFiles.some(isServicePath)) surfaces.add('service_orchestration');
116
+ if (sourceFiles.some(isCoreWorkflowPath)) surfaces.add('core_workflow_state');
117
+ if (sourceFiles.some(isGateOrchestrationPath)) surfaces.add('gate_orchestration');
118
+ if (sourceFiles.some(isVerificationEvidencePath)) surfaces.add('verification_evidence');
119
+ if (sourceFiles.some(isReviewLifecyclePath)) surfaces.add('review_lifecycle');
120
+ if (sourceFiles.some(isDatabasePath)) surfaces.add('database_state');
121
+ if (sourceFiles.some((file) => !isUiPath(file) && isQueueWorkerPath(file))) surfaces.add('queue_worker');
122
+ if (sourceFiles.some((file) => !isUiPath(file) && /retry|poll|status|state/i.test(file))) {
123
+ surfaces.add('polling_retry');
124
+ }
125
+ if (sourceFiles.some((file) => /auth|session|permission|middleware/i.test(file))) {
126
+ surfaces.add('auth_boundary');
127
+ }
128
+ if (sourceFiles.some((file) => /\/v1\/|legacy/i.test(file))) surfaces.add('legacy_v1_compatibility');
129
+ if (allFiles.some((file) => /\.(test|spec)\.[cm]?[jt]sx?$/.test(file))) surfaces.add('test_coverage');
130
+ return [...surfaces].sort();
131
+ }
132
+
133
+ function buildReasons({ riskSurfaces, sourceFiles, allFiles, storyText, networkContracts }) {
134
+ const reasons = [];
135
+ if (riskSurfaces.includes('regression_blast_radius')) reasons.push('changed module has a large call-graph blast radius');
136
+ if (riskSurfaces.includes('frontend_interaction')) reasons.push('UI-facing source files changed');
137
+ if (riskSurfaces.includes('server_api')) reasons.push('API/server boundary changed');
138
+ if (riskSurfaces.includes('service_orchestration')) reasons.push('service/orchestration layer changed');
139
+ if (riskSurfaces.includes('core_workflow_state')) reasons.push('core workflow/state orchestration source changed');
140
+ if (riskSurfaces.includes('gate_orchestration')) reasons.push('PR/gate orchestration source changed');
141
+ if (riskSurfaces.includes('verification_evidence')) reasons.push('verification evidence binding source changed');
142
+ if (riskSurfaces.includes('review_lifecycle')) reasons.push('agent review lifecycle source changed');
143
+ if (riskSurfaces.includes('database_state')) reasons.push('database/state persistence surface detected');
144
+ if (riskSurfaces.includes('queue_worker')) reasons.push('queue/worker/job surface detected');
145
+ if (riskSurfaces.includes('polling_retry')) reasons.push('polling/retry/status workflow signal detected');
146
+ if (riskSurfaces.includes('auth_boundary')) reasons.push('auth/permission boundary signal detected');
147
+ if (riskSurfaces.includes('legacy_v1_compatibility')) reasons.push('legacy/v1 compatibility surface detected');
148
+ if ((networkContracts?.introduced_api_client_call_count ?? 0) > 0) reasons.push('new API client calls detected by network contract scanner');
149
+ if (WORKFLOW_KEYWORDS.some((pattern) => pattern.test(storyText) || allFiles.some((file) => pattern.test(file)))) {
150
+ reasons.push('Story or diff contains workflow/state transition keywords');
151
+ }
152
+ if (sourceFiles.length === 0) reasons.push('no runtime source files changed');
153
+ return reasons;
154
+ }
155
+
156
+ function isUiPath(file) {
157
+ if (/\/api\//.test(file) || file.startsWith('api/')) return false;
158
+ return file.startsWith('src/app/')
159
+ || file.startsWith('src/pages/')
160
+ || file.startsWith('src/components/')
161
+ || file.startsWith('components/')
162
+ || /\.(tsx|jsx|css|scss|sass|less|vue|svelte)$/.test(file);
163
+ }
164
+
165
+ function isApiPath(file) {
166
+ return /\/api\//.test(file) || file.startsWith('api/') || file.startsWith('server/');
167
+ }
168
+
169
+ function isServicePath(file) {
170
+ return /\/services?\//.test(file) || /\/actions?\//.test(file) || /orchestr/i.test(file);
171
+ }
172
+
173
+ function isDatabasePath(file) {
174
+ return /prisma|db|database|repository|model|schema/i.test(file);
175
+ }
176
+
177
+ function isQueueWorkerPath(file) {
178
+ return /queue|worker|job|scheduled-task|background-task/i.test(file);
179
+ }
180
+
181
+ function isCoreWorkflowPath(file) {
182
+ return /workflow|preflight|orchestrat|state-machine|statemachine|execution-state|transition|resume|replay/i.test(file);
183
+ }
184
+
185
+ function isGateOrchestrationPath(file) {
186
+ return /(^|\/)(pr-manager|change-risk-classifier)\.[cm]?js$/.test(file);
187
+ }
188
+
189
+ function isVerificationEvidencePath(file) {
190
+ return /(^|\/)(verification-evidence|flow-verifier)\.[cm]?js$/.test(file);
191
+ }
192
+
193
+ function isReviewLifecyclePath(file) {
194
+ return /(^|\/)agent-review\.[cm]?js$/.test(file);
195
+ }