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.
- package/LICENSE +201 -0
- package/NOTICE +9 -0
- package/README.ja.md +448 -0
- package/README.md +520 -0
- package/agent-instructions/codex/AGENTS.vibepro.md +45 -0
- package/bin/vibepro.js +9 -0
- package/docs/assets/vibepro-header.png +0 -0
- package/package.json +51 -0
- package/skills/vibepro-diagnosis-packages/SKILL.md +133 -0
- package/skills/vibepro-human-review/SKILL.md +73 -0
- package/skills/vibepro-story-refactor/SKILL.md +89 -0
- package/skills/vibepro-workflow/SKILL.md +139 -0
- package/src/agent-harness-map.js +230 -0
- package/src/agent-harness-scanner.js +337 -0
- package/src/agent-review.js +2180 -0
- package/src/api-boundary-scanner.js +452 -0
- package/src/architecture-profiler.js +423 -0
- package/src/authorization-scoring.js +149 -0
- package/src/brainbase-importer.js +534 -0
- package/src/change-risk-classifier.js +195 -0
- package/src/check-packs.js +605 -0
- package/src/checkpoint-manager.js +233 -0
- package/src/cli.js +2213 -0
- package/src/code-quality-scanner.js +310 -0
- package/src/codex-manager.js +143 -0
- package/src/component-style-scanner.js +336 -0
- package/src/coverage-report.js +99 -0
- package/src/database-access-scanner.js +163 -0
- package/src/decision-records.js +315 -0
- package/src/design-modernize.js +1435 -0
- package/src/design-system.js +1732 -0
- package/src/diagnostic-engine.js +1945 -0
- package/src/diagram-requirement-resolver.js +194 -0
- package/src/doctor.js +677 -0
- package/src/environment-graph.js +424 -0
- package/src/execution-state.js +849 -0
- package/src/explore-evidence.js +425 -0
- package/src/flow-design-scanner.js +896 -0
- package/src/flow-verifier.js +887 -0
- package/src/gesture-interaction-scanner.js +330 -0
- package/src/graph-context.js +263 -0
- package/src/graphify-adapter.js +189 -0
- package/src/html-report.js +1035 -0
- package/src/journey-map.js +1299 -0
- package/src/language.js +48 -0
- package/src/lazy-pattern-detector.js +182 -0
- package/src/local-dev-scanner.js +135 -0
- package/src/managed-worktree-gate.js +187 -0
- package/src/managed-worktree.js +766 -0
- package/src/merge-manager.js +501 -0
- package/src/network-contract-scanner.js +442 -0
- package/src/nocodb-story-sync.js +386 -0
- package/src/oss-readiness-scanner.js +417 -0
- package/src/performance-evidence.js +756 -0
- package/src/performance-measurer.js +591 -0
- package/src/pr-manager.js +8220 -0
- package/src/presets.js +682 -0
- package/src/public-discovery-scanner.js +519 -0
- package/src/refactoring-delta-reporter.js +367 -0
- package/src/refactoring-opportunity-generator.js +797 -0
- package/src/regression-risk-scanner.js +146 -0
- package/src/repo-status.js +266 -0
- package/src/report-fingerprint.js +188 -0
- package/src/report-pr-body-prompt-template.md +108 -0
- package/src/report-pr-body-schema.json +95 -0
- package/src/report-store.js +135 -0
- package/src/report-validator.js +192 -0
- package/src/requirement-consistency.js +1066 -0
- package/src/runtime-info.js +134 -0
- package/src/self-dogfood-scanner.js +476 -0
- package/src/session-learning.js +164 -0
- package/src/skills-manager.js +157 -0
- package/src/spec-drift.js +378 -0
- package/src/spec-fingerprint.js +445 -0
- package/src/spec-prompt-template.md +155 -0
- package/src/spec-schema.json +219 -0
- package/src/spec-store.js +258 -0
- package/src/spec-validator.js +459 -0
- package/src/static-site-scanner.js +316 -0
- package/src/story-candidate-generator.js +85 -0
- package/src/story-catalog-generator.js +2813 -0
- package/src/story-html.js +156 -0
- package/src/story-manager.js +2144 -0
- package/src/story-task-generator.js +522 -0
- package/src/task-manager.js +1029 -0
- package/src/terminal-link-scanner.js +238 -0
- package/src/usage-report.js +417 -0
- package/src/verification-evidence.js +284 -0
- package/src/workspace.js +126 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { constants as fsConstants } from 'node:fs';
|
|
2
|
+
import { access, copyFile, mkdir, rm, stat } from 'node:fs/promises';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
|
|
7
|
+
import { getWorkspaceDir, initWorkspace, readManifest, toWorkspaceRelative, writeManifest } from './workspace.js';
|
|
8
|
+
|
|
9
|
+
const GRAPHIFY_FILES = ['graph.json', 'GRAPH_REPORT.md', 'graph.html'];
|
|
10
|
+
|
|
11
|
+
export async function importGraphifyArtifacts(repoRoot, options = {}) {
|
|
12
|
+
await initWorkspace(repoRoot);
|
|
13
|
+
const root = path.resolve(repoRoot);
|
|
14
|
+
const sourceArg = options.sourceDir ?? 'graphify-out';
|
|
15
|
+
const sourceDir = path.resolve(root, sourceArg);
|
|
16
|
+
|
|
17
|
+
let execution = null;
|
|
18
|
+
const cleanupGeneratedGraphifyOutput = Boolean(options.runGraphify);
|
|
19
|
+
try {
|
|
20
|
+
if (options.runGraphify) {
|
|
21
|
+
execution = await runGraphify(root, sourceArg, options.env);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const graphifyDir = path.join(getWorkspaceDir(root), 'graphify');
|
|
25
|
+
await mkdir(graphifyDir, { recursive: true });
|
|
26
|
+
|
|
27
|
+
await ensureFile(path.join(sourceDir, 'graph.json'));
|
|
28
|
+
await ensureFile(path.join(sourceDir, 'GRAPH_REPORT.md'));
|
|
29
|
+
|
|
30
|
+
for (const fileName of GRAPHIFY_FILES) {
|
|
31
|
+
const sourceFile = path.join(sourceDir, fileName);
|
|
32
|
+
try {
|
|
33
|
+
await copyFile(sourceFile, path.join(graphifyDir, fileName));
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (error.code !== 'ENOENT') throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const manifest = await readManifest(root);
|
|
40
|
+
manifest.artifacts = {
|
|
41
|
+
...manifest.artifacts,
|
|
42
|
+
graphify_json: toWorkspaceRelative(root, path.join(graphifyDir, 'graph.json')),
|
|
43
|
+
graphify_report: toWorkspaceRelative(root, path.join(graphifyDir, 'GRAPH_REPORT.md'))
|
|
44
|
+
};
|
|
45
|
+
if (execution) {
|
|
46
|
+
manifest.graphify = {
|
|
47
|
+
...(manifest.graphify ?? {}),
|
|
48
|
+
last_execution: execution
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
await writeManifest(root, manifest);
|
|
52
|
+
|
|
53
|
+
return { graphifyDir, graphifyExecuted: Boolean(execution) };
|
|
54
|
+
} finally {
|
|
55
|
+
if (cleanupGeneratedGraphifyOutput) {
|
|
56
|
+
await cleanupDefaultGraphifyOutput(root);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function runGraphify(repoRoot, outputArg, env) {
|
|
62
|
+
const args = ['update', '.'];
|
|
63
|
+
const command = `graphify ${args.join(' ')}`;
|
|
64
|
+
const startedAt = new Date().toISOString();
|
|
65
|
+
|
|
66
|
+
const result = await runProcess('graphify', args, {
|
|
67
|
+
cwd: repoRoot,
|
|
68
|
+
env: env ?? process.env
|
|
69
|
+
}).catch(async (error) => {
|
|
70
|
+
if (error.code === 'ENOENT') {
|
|
71
|
+
throw new Error(await buildGraphifyNotFoundMessage(env ?? process.env));
|
|
72
|
+
}
|
|
73
|
+
throw error;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (result.exitCode !== 0) {
|
|
77
|
+
throw new Error(`graphify failed with exit code ${result.exitCode}: ${result.stderr.trim()}`);
|
|
78
|
+
}
|
|
79
|
+
if (outputArg !== 'graphify-out') {
|
|
80
|
+
await mirrorGraphifyOutput(repoRoot, outputArg);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
command,
|
|
85
|
+
started_at: startedAt,
|
|
86
|
+
finished_at: new Date().toISOString(),
|
|
87
|
+
exit_code: result.exitCode
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function buildGraphifyNotFoundMessage(env) {
|
|
92
|
+
const candidates = await findGraphifyPathCandidates(env);
|
|
93
|
+
const pathValue = env?.PATH ?? '';
|
|
94
|
+
const lines = [
|
|
95
|
+
'graphify command was not found on PATH. Graphify is optional but recommended for impact-scope discovery.',
|
|
96
|
+
`Current PATH: ${pathValue || '(empty)'}`,
|
|
97
|
+
'You can continue without --run-graphify.'
|
|
98
|
+
];
|
|
99
|
+
if (candidates.length > 0) {
|
|
100
|
+
lines.push(`Found graphify outside PATH: ${candidates.join(', ')}`);
|
|
101
|
+
lines.push('Retry by adding the directory to PATH, for example: PATH="$HOME/.local/bin:$PATH" <your vibepro command> --run-graphify');
|
|
102
|
+
} else {
|
|
103
|
+
lines.push('No graphify executable was found in common install locations.');
|
|
104
|
+
lines.push('Install it with: uv tool install graphifyy');
|
|
105
|
+
}
|
|
106
|
+
return lines.join(' ');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function findGraphifyPathCandidates(env) {
|
|
110
|
+
const homeDir = env?.HOME || os.homedir();
|
|
111
|
+
const candidateDirs = [
|
|
112
|
+
homeDir ? path.join(homeDir, '.local', 'bin') : null,
|
|
113
|
+
homeDir ? path.join(homeDir, '.cargo', 'bin') : null,
|
|
114
|
+
'/opt/homebrew/bin',
|
|
115
|
+
'/usr/local/bin'
|
|
116
|
+
].filter(Boolean);
|
|
117
|
+
const pathDirs = new Set(String(env?.PATH ?? '').split(path.delimiter).filter(Boolean).map((dir) => path.resolve(dir)));
|
|
118
|
+
const candidates = [];
|
|
119
|
+
for (const dir of candidateDirs) {
|
|
120
|
+
const resolvedDir = path.resolve(dir);
|
|
121
|
+
if (pathDirs.has(resolvedDir)) continue;
|
|
122
|
+
const candidate = path.join(resolvedDir, graphifyExecutableName());
|
|
123
|
+
try {
|
|
124
|
+
await access(candidate, fsConstants.X_OK);
|
|
125
|
+
candidates.push(candidate);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (!['ENOENT', 'EACCES', 'ENOTDIR'].includes(error.code)) throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return [...new Set(candidates)];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function graphifyExecutableName() {
|
|
134
|
+
return process.platform === 'win32' ? 'graphify.exe' : 'graphify';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function mirrorGraphifyOutput(repoRoot, outputArg) {
|
|
138
|
+
const defaultOutputDir = path.join(repoRoot, 'graphify-out');
|
|
139
|
+
const requestedOutputDir = path.resolve(repoRoot, outputArg);
|
|
140
|
+
await mkdir(requestedOutputDir, { recursive: true });
|
|
141
|
+
await ensureFile(path.join(defaultOutputDir, 'graph.json'));
|
|
142
|
+
await ensureFile(path.join(defaultOutputDir, 'GRAPH_REPORT.md'));
|
|
143
|
+
for (const fileName of GRAPHIFY_FILES) {
|
|
144
|
+
const sourceFile = path.join(defaultOutputDir, fileName);
|
|
145
|
+
try {
|
|
146
|
+
await copyFile(sourceFile, path.join(requestedOutputDir, fileName));
|
|
147
|
+
} catch (error) {
|
|
148
|
+
if (error.code !== 'ENOENT') throw error;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async function cleanupDefaultGraphifyOutput(repoRoot) {
|
|
154
|
+
await rm(path.join(repoRoot, 'graphify-out'), {
|
|
155
|
+
recursive: true,
|
|
156
|
+
force: true
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function runProcess(command, args, options) {
|
|
161
|
+
return new Promise((resolve, reject) => {
|
|
162
|
+
const child = spawn(command, args, options);
|
|
163
|
+
let stdout = '';
|
|
164
|
+
let stderr = '';
|
|
165
|
+
|
|
166
|
+
child.stdout.on('data', (chunk) => {
|
|
167
|
+
stdout += chunk.toString();
|
|
168
|
+
});
|
|
169
|
+
child.stderr.on('data', (chunk) => {
|
|
170
|
+
stderr += chunk.toString();
|
|
171
|
+
});
|
|
172
|
+
child.on('error', reject);
|
|
173
|
+
child.on('close', (exitCode) => {
|
|
174
|
+
resolve({ exitCode, stdout, stderr });
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function ensureFile(filePath) {
|
|
180
|
+
try {
|
|
181
|
+
const fileStat = await stat(filePath);
|
|
182
|
+
if (!fileStat.isFile()) throw new Error(`${filePath} is not a file`);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
if (error.code === 'ENOENT') {
|
|
185
|
+
throw new Error(`graphify artifact not found: ${filePath}`);
|
|
186
|
+
}
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|