vibe-me 1.0.0 → 2.0.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/Vibe.bat +39 -0
- package/bin/vibes.js +276 -204
- package/package.json +3 -2
- package/templates/docs/README.md +34 -0
- package/templates/docs/api.md +36 -0
- package/templates/docs/architecture.md +28 -0
- package/templates/docs/decisions/0001-template.md +21 -0
- package/templates/docs/developer_guide.md +46 -0
- package/templates/docs/glossary.md +13 -0
- package/templates/docs/issues.md +25 -0
- package/templates/docs/resolved.md +20 -0
- package/templates/docs/roadmap.md +27 -0
- package/templates/docs/topology.md +30 -0
- package/templates/docs/troubleshooting.md +32 -0
package/Vibe.bat
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
:: ──────────────────────────────────────────────
|
|
3
|
+
:: Vibe.bat — One-click project setup
|
|
4
|
+
:: Drop this file in any project root and double-click.
|
|
5
|
+
:: Creates .vibe/ semantic layer + docs/ operational docs.
|
|
6
|
+
:: ──────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
echo.
|
|
9
|
+
echo ⚡ Vibe.bat — Setting up semantic layer + docs
|
|
10
|
+
echo ─────────────────────────────────────────────────
|
|
11
|
+
echo.
|
|
12
|
+
|
|
13
|
+
:: Check if Node.js is installed
|
|
14
|
+
where node >nul 2>nul
|
|
15
|
+
if %ERRORLEVEL% neq 0 (
|
|
16
|
+
echo ✖ Node.js is not installed.
|
|
17
|
+
echo Download it from https://nodejs.org
|
|
18
|
+
echo.
|
|
19
|
+
pause
|
|
20
|
+
exit /b 1
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
:: Run vibes all (init + docs) in the current directory
|
|
24
|
+
echo Running: npx vibe-me@latest all
|
|
25
|
+
echo.
|
|
26
|
+
call npx -y vibe-me@latest all
|
|
27
|
+
|
|
28
|
+
echo.
|
|
29
|
+
echo ─────────────────────────────────────────────────
|
|
30
|
+
echo ✔ Done! Now tell your AI agent:
|
|
31
|
+
echo.
|
|
32
|
+
echo "Read .vibe/VIBE_GUIDE.md, then analyze this
|
|
33
|
+
echo codebase and fill out all skeleton files in
|
|
34
|
+
echo .vibe/ and docs/. Ask me any questions you
|
|
35
|
+
echo can't answer from the code."
|
|
36
|
+
echo.
|
|
37
|
+
echo ─────────────────────────────────────────────────
|
|
38
|
+
echo.
|
|
39
|
+
pause
|
package/bin/vibes.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// vibes —
|
|
3
|
+
// vibes — Semantic repository layers + standardized docs for humans and AI
|
|
4
4
|
// Zero dependencies. Single file. Works with npx.
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
@@ -11,18 +11,23 @@ const path = require('path');
|
|
|
11
11
|
// ─────────────────────────────────────────────
|
|
12
12
|
|
|
13
13
|
const VIBE_DIR = '.vibe';
|
|
14
|
+
const DOCS_DIR = 'docs';
|
|
14
15
|
const TEMPLATES_DIR = path.join(__dirname, '..', 'templates');
|
|
15
16
|
const SPEC_DIR = path.join(__dirname, '..', 'spec');
|
|
16
17
|
|
|
17
|
-
const
|
|
18
|
-
'purpose.md',
|
|
19
|
-
'
|
|
20
|
-
'flows.md',
|
|
21
|
-
'entities.md',
|
|
22
|
-
'decisions.md',
|
|
23
|
-
'state.json'
|
|
18
|
+
const VIBE_FILES = [
|
|
19
|
+
'purpose.md', 'architecture.md', 'flows.md',
|
|
20
|
+
'entities.md', 'decisions.md', 'state.json'
|
|
24
21
|
];
|
|
25
22
|
|
|
23
|
+
const DOCS_FILES = [
|
|
24
|
+
'README.md', 'topology.md', 'architecture.md', 'api.md',
|
|
25
|
+
'issues.md', 'resolved.md', 'roadmap.md', 'developer_guide.md',
|
|
26
|
+
'troubleshooting.md', 'glossary.md'
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const DOCS_DIRS = ['decisions'];
|
|
30
|
+
const DOCS_EXTRA = ['decisions/0001-template.md'];
|
|
26
31
|
const SPEC_FILE = 'VIBE_GUIDE.md';
|
|
27
32
|
|
|
28
33
|
// ─────────────────────────────────────────────
|
|
@@ -35,68 +40,44 @@ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
|
|
|
35
40
|
const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
|
|
36
41
|
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
37
42
|
const red = (s) => `\x1b[31m${s}\x1b[0m`;
|
|
43
|
+
const magenta = (s) => `\x1b[35m${s}\x1b[0m`;
|
|
38
44
|
|
|
39
45
|
// ─────────────────────────────────────────────
|
|
40
46
|
// Helpers
|
|
41
47
|
// ─────────────────────────────────────────────
|
|
42
48
|
|
|
43
|
-
function
|
|
44
|
-
try {
|
|
45
|
-
fs.accessSync(filePath);
|
|
46
|
-
return true;
|
|
47
|
-
} catch {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
49
|
+
function exists(p) {
|
|
50
|
+
try { fs.accessSync(p); return true; } catch { return false; }
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
fs.writeFileSync(dest, content, 'utf-8');
|
|
53
|
+
function copy(src, dest) {
|
|
54
|
+
fs.writeFileSync(dest, fs.readFileSync(src, 'utf-8'), 'utf-8');
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
function getProjectName(dir) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
for (const [file, regex] of [
|
|
59
|
+
['package.json', null],
|
|
60
|
+
['Cargo.toml', /^name\s*=\s*"(.+)"/m],
|
|
61
|
+
['go.mod', /^module\s+(.+)/m],
|
|
62
|
+
['pyproject.toml', /^name\s*=\s*"(.+)"/m],
|
|
63
|
+
]) {
|
|
64
|
+
const p = path.join(dir, file);
|
|
65
|
+
if (!exists(p)) continue;
|
|
61
66
|
try {
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const cargo = fs.readFileSync(cargoPath, 'utf-8');
|
|
71
|
-
const match = cargo.match(/^name\s*=\s*"(.+)"/m);
|
|
72
|
-
if (match) return match[1];
|
|
73
|
-
} catch {}
|
|
74
|
-
}
|
|
75
|
-
// Try go.mod
|
|
76
|
-
const goModPath = path.join(dir, 'go.mod');
|
|
77
|
-
if (fileExists(goModPath)) {
|
|
78
|
-
try {
|
|
79
|
-
const goMod = fs.readFileSync(goModPath, 'utf-8');
|
|
80
|
-
const match = goMod.match(/^module\s+(.+)/m);
|
|
81
|
-
if (match) return match[1].split('/').pop();
|
|
82
|
-
} catch {}
|
|
83
|
-
}
|
|
84
|
-
// Try pyproject.toml
|
|
85
|
-
const pyPath = path.join(dir, 'pyproject.toml');
|
|
86
|
-
if (fileExists(pyPath)) {
|
|
87
|
-
try {
|
|
88
|
-
const py = fs.readFileSync(pyPath, 'utf-8');
|
|
89
|
-
const match = py.match(/^name\s*=\s*"(.+)"/m);
|
|
90
|
-
if (match) return match[1];
|
|
67
|
+
const content = fs.readFileSync(p, 'utf-8');
|
|
68
|
+
if (file === 'package.json') {
|
|
69
|
+
const pkg = JSON.parse(content);
|
|
70
|
+
if (pkg.name) return pkg.name;
|
|
71
|
+
} else {
|
|
72
|
+
const m = content.match(regex);
|
|
73
|
+
if (m) return file === 'go.mod' ? m[1].split('/').pop() : m[1];
|
|
74
|
+
}
|
|
91
75
|
} catch {}
|
|
92
76
|
}
|
|
93
|
-
// Fallback to directory name
|
|
94
77
|
return path.basename(dir);
|
|
95
78
|
}
|
|
96
79
|
|
|
97
|
-
function
|
|
98
|
-
return new Date().toISOString();
|
|
99
|
-
}
|
|
80
|
+
function now() { return new Date().toISOString(); }
|
|
100
81
|
|
|
101
82
|
// ─────────────────────────────────────────────
|
|
102
83
|
// Commands
|
|
@@ -104,207 +85,297 @@ function getNow() {
|
|
|
104
85
|
|
|
105
86
|
function cmdInit(targetDir) {
|
|
106
87
|
const vibeDir = path.join(targetDir, VIBE_DIR);
|
|
107
|
-
const
|
|
88
|
+
const name = getProjectName(targetDir);
|
|
108
89
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
console.log(
|
|
112
|
-
console.log(dim(' Use "vibes reset" to overwrite, or edit files directly.\n'));
|
|
90
|
+
if (exists(vibeDir)) {
|
|
91
|
+
console.log(red('\n ✖ .vibe/ already exists.'));
|
|
92
|
+
console.log(dim(' Use "vibes reset" to overwrite.\n'));
|
|
113
93
|
process.exit(1);
|
|
114
94
|
}
|
|
115
95
|
|
|
116
96
|
console.log('');
|
|
117
97
|
console.log(bold(' ⚡ vibes init'));
|
|
118
|
-
console.log(dim(` Creating .vibe/ semantic layer for ${cyan(
|
|
98
|
+
console.log(dim(` Creating .vibe/ semantic layer for ${cyan(name)}`));
|
|
119
99
|
console.log('');
|
|
120
100
|
|
|
121
|
-
// Create .vibe directory
|
|
122
101
|
fs.mkdirSync(vibeDir, { recursive: true });
|
|
123
102
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
for (const file of TEMPLATE_FILES) {
|
|
103
|
+
let count = 0;
|
|
104
|
+
for (const file of VIBE_FILES) {
|
|
127
105
|
const src = path.join(TEMPLATES_DIR, file);
|
|
128
106
|
const dest = path.join(vibeDir, file);
|
|
129
|
-
|
|
130
107
|
if (file === 'state.json') {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
content = content.replace('TIMESTAMP', getNow());
|
|
135
|
-
fs.writeFileSync(dest, content, 'utf-8');
|
|
108
|
+
let c = fs.readFileSync(src, 'utf-8');
|
|
109
|
+
c = c.replace('PROJECT_NAME', name).replace(/TIMESTAMP/g, now());
|
|
110
|
+
fs.writeFileSync(dest, c, 'utf-8');
|
|
136
111
|
} else {
|
|
137
|
-
|
|
138
|
-
copyFile(src, dest);
|
|
112
|
+
copy(src, dest);
|
|
139
113
|
}
|
|
140
|
-
|
|
141
114
|
console.log(green(' ✔ ') + dim('.vibe/') + file);
|
|
142
|
-
|
|
115
|
+
count++;
|
|
143
116
|
}
|
|
144
117
|
|
|
145
|
-
// Copy
|
|
146
|
-
|
|
147
|
-
const guideDest = path.join(vibeDir, SPEC_FILE);
|
|
148
|
-
copyFile(guideSrc, guideDest);
|
|
118
|
+
// Copy guide
|
|
119
|
+
copy(path.join(SPEC_DIR, SPEC_FILE), path.join(vibeDir, SPEC_FILE));
|
|
149
120
|
console.log(green(' ✔ ') + dim('.vibe/') + SPEC_FILE + dim(' (agent instructions)'));
|
|
150
|
-
|
|
121
|
+
count++;
|
|
151
122
|
|
|
152
123
|
console.log('');
|
|
153
|
-
console.log(green(` ✔ Created ${
|
|
124
|
+
console.log(green(` ✔ Created ${count} files in .vibe/`));
|
|
125
|
+
printNextSteps();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function cmdDocs(targetDir) {
|
|
129
|
+
const docsDir = path.join(targetDir, DOCS_DIR);
|
|
130
|
+
const name = getProjectName(targetDir);
|
|
131
|
+
|
|
132
|
+
if (exists(docsDir)) {
|
|
133
|
+
// Check if it has content already
|
|
134
|
+
const contents = fs.readdirSync(docsDir);
|
|
135
|
+
if (contents.length > 0) {
|
|
136
|
+
console.log(yellow('\n ⚠ docs/ already exists with ' + contents.length + ' items.'));
|
|
137
|
+
console.log(dim(' Skipping files that already exist. Adding missing ones only.\n'));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
154
141
|
console.log('');
|
|
155
|
-
console.log(bold('
|
|
142
|
+
console.log(bold(' 📄 vibes docs'));
|
|
143
|
+
console.log(dim(` Creating docs/ structure for ${cyan(name)}`));
|
|
156
144
|
console.log('');
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
|
|
146
|
+
// Create docs dir and subdirs
|
|
147
|
+
fs.mkdirSync(docsDir, { recursive: true });
|
|
148
|
+
for (const sub of DOCS_DIRS) {
|
|
149
|
+
fs.mkdirSync(path.join(docsDir, sub), { recursive: true });
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
let created = 0;
|
|
153
|
+
let skipped = 0;
|
|
154
|
+
|
|
155
|
+
// Copy doc files (skip if they already exist)
|
|
156
|
+
for (const file of [...DOCS_FILES, ...DOCS_EXTRA]) {
|
|
157
|
+
const src = path.join(TEMPLATES_DIR, 'docs', file);
|
|
158
|
+
const dest = path.join(docsDir, file);
|
|
159
|
+
if (exists(dest)) {
|
|
160
|
+
console.log(yellow(' ⊘ ') + dim('docs/') + file + dim(' (exists, skipped)'));
|
|
161
|
+
skipped++;
|
|
162
|
+
} else {
|
|
163
|
+
copy(src, dest);
|
|
164
|
+
console.log(green(' ✔ ') + dim('docs/') + file);
|
|
165
|
+
created++;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
159
169
|
console.log('');
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
170
|
+
if (skipped > 0) {
|
|
171
|
+
console.log(green(` ✔ Created ${created} files`) + dim(`, skipped ${skipped} existing`));
|
|
172
|
+
} else {
|
|
173
|
+
console.log(green(` ✔ Created ${created} files in docs/`));
|
|
174
|
+
}
|
|
175
|
+
console.log('');
|
|
176
|
+
console.log(bold(' Next steps:'));
|
|
163
177
|
console.log('');
|
|
164
|
-
console.log('
|
|
178
|
+
console.log(' Tell your AI agent:');
|
|
165
179
|
console.log('');
|
|
166
|
-
console.log(
|
|
167
|
-
console.log(
|
|
180
|
+
console.log(cyan(' "Read .vibe/VIBE_GUIDE.md for context, then analyze'));
|
|
181
|
+
console.log(cyan(' the codebase and fill out all skeleton files in docs/.'));
|
|
182
|
+
console.log(cyan(' Ask me any questions you can\'t answer from the code."'));
|
|
168
183
|
console.log('');
|
|
169
184
|
}
|
|
170
185
|
|
|
171
186
|
function cmdCheck(targetDir) {
|
|
172
187
|
const vibeDir = path.join(targetDir, VIBE_DIR);
|
|
188
|
+
const docsDir = path.join(targetDir, DOCS_DIR);
|
|
189
|
+
const hasVibe = exists(vibeDir);
|
|
190
|
+
const hasDocs = exists(docsDir);
|
|
173
191
|
|
|
174
|
-
if (!
|
|
175
|
-
console.log(red('\n ✖ No .vibe/
|
|
192
|
+
if (!hasVibe && !hasDocs) {
|
|
193
|
+
console.log(red('\n ✖ No .vibe/ or docs/ found. Run "vibes init" first.\n'));
|
|
176
194
|
process.exit(1);
|
|
177
195
|
}
|
|
178
196
|
|
|
179
197
|
console.log('');
|
|
180
198
|
console.log(bold(' 🔍 vibes check'));
|
|
181
|
-
console.log('');
|
|
182
199
|
|
|
183
|
-
let passed = 0;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
continue;
|
|
200
|
+
let passed = 0, failed = 0, warnings = 0;
|
|
201
|
+
|
|
202
|
+
// Check .vibe/
|
|
203
|
+
if (hasVibe) {
|
|
204
|
+
console.log('');
|
|
205
|
+
console.log(dim(' ── .vibe/ (semantic layer) ──'));
|
|
206
|
+
console.log('');
|
|
207
|
+
|
|
208
|
+
for (const file of VIBE_FILES) {
|
|
209
|
+
const fp = path.join(vibeDir, file);
|
|
210
|
+
if (!exists(fp)) { console.log(red(' ✖ ') + file + ' — missing'); failed++; continue; }
|
|
211
|
+
|
|
212
|
+
const content = fs.readFileSync(fp, 'utf-8').trim();
|
|
213
|
+
const lines = content.split('\n').length;
|
|
214
|
+
|
|
215
|
+
if (lines < 5) { console.log(yellow(' ⚠ ') + file + ` — looks empty (${lines} lines)`); warnings++; continue; }
|
|
216
|
+
|
|
217
|
+
// File-specific quality checks
|
|
218
|
+
let warn = null;
|
|
219
|
+
if (file === 'purpose.md' && !content.toLowerCase().includes('not do')) warn = 'missing "NOT do" section';
|
|
220
|
+
if (file === 'decisions.md' && (content.match(/^## Why /gm) || []).length < 2) warn = 'fewer than 2 decisions';
|
|
221
|
+
if (file === 'entities.md' && !content.includes('What depends on it')) warn = 'missing "What depends on it?" fields';
|
|
222
|
+
if (file === 'flows.md' && (content.match(/^## \d+\./gm) || []).length < 2) warn = 'fewer than 2 flows';
|
|
223
|
+
if (file === 'state.json') {
|
|
224
|
+
try {
|
|
225
|
+
const s = JSON.parse(content);
|
|
226
|
+
if (!s.vibe_updated) warn = 'missing vibe_updated timestamp';
|
|
227
|
+
else {
|
|
228
|
+
const days = (Date.now() - new Date(s.vibe_updated).getTime()) / 86400000;
|
|
229
|
+
if (days > 30) warn = `last updated ${Math.floor(days)} days ago`;
|
|
230
|
+
}
|
|
231
|
+
} catch { console.log(red(' ✖ ') + file + ' — invalid JSON'); failed++; continue; }
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (warn) { console.log(yellow(' ⚠ ') + file + ` — ${warn}`); warnings++; }
|
|
235
|
+
else { console.log(green(' ✔ ') + file + ` — ${lines} lines`); passed++; }
|
|
194
236
|
}
|
|
237
|
+
}
|
|
195
238
|
|
|
196
|
-
|
|
197
|
-
|
|
239
|
+
// Check docs/
|
|
240
|
+
if (hasDocs) {
|
|
241
|
+
console.log('');
|
|
242
|
+
console.log(dim(' ── docs/ (operational docs) ──'));
|
|
243
|
+
console.log('');
|
|
198
244
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
warnings++;
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
245
|
+
for (const file of DOCS_FILES) {
|
|
246
|
+
const fp = path.join(docsDir, file);
|
|
247
|
+
if (!exists(fp)) { console.log(yellow(' ⚠ ') + file + ' — missing'); warnings++; continue; }
|
|
204
248
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if (!content.includes('NOT do') && !content.includes('not do') && !content.includes('NOT Do')) {
|
|
208
|
-
console.log(yellow(' ⚠ ') + `${file} — missing "What does it explicitly NOT do?" section`);
|
|
209
|
-
warnings++;
|
|
210
|
-
continue;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
249
|
+
const content = fs.readFileSync(fp, 'utf-8').trim();
|
|
250
|
+
const lines = content.split('\n').length;
|
|
213
251
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const decisionCount = (content.match(/^## Why /gm) || []).length;
|
|
217
|
-
if (decisionCount < 2) {
|
|
218
|
-
console.log(yellow(' ⚠ ') + `${file} — only ${decisionCount} decision(s). Most projects have 3+.`);
|
|
219
|
-
warnings++;
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
252
|
+
if (lines < 5) { console.log(yellow(' ⚠ ') + file + ` — looks empty (${lines} lines)`); warnings++; }
|
|
253
|
+
else { console.log(green(' ✔ ') + file + ` — ${lines} lines`); passed++; }
|
|
222
254
|
}
|
|
255
|
+
}
|
|
223
256
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
257
|
+
console.log('');
|
|
258
|
+
if (failed > 0) console.log(red(` Result: ${failed} failed, ${warnings} warnings, ${passed} passed`));
|
|
259
|
+
else if (warnings > 0) console.log(yellow(` Result: ${warnings} warnings, ${passed} passed`));
|
|
260
|
+
else console.log(green(` Result: All ${passed} files pass ✔`));
|
|
261
|
+
console.log('');
|
|
262
|
+
}
|
|
231
263
|
|
|
232
|
-
|
|
264
|
+
function cmdStatus(targetDir) {
|
|
265
|
+
const vibeDir = path.join(targetDir, VIBE_DIR);
|
|
266
|
+
const docsDir = path.join(targetDir, DOCS_DIR);
|
|
267
|
+
const name = getProjectName(targetDir);
|
|
268
|
+
|
|
269
|
+
console.log('');
|
|
270
|
+
console.log(bold(` 📊 ${name}`));
|
|
271
|
+
console.log('');
|
|
272
|
+
|
|
273
|
+
// .vibe status
|
|
274
|
+
if (exists(vibeDir)) {
|
|
275
|
+
const filled = VIBE_FILES.filter(f => {
|
|
276
|
+
const fp = path.join(vibeDir, f);
|
|
277
|
+
if (!exists(fp)) return false;
|
|
278
|
+
return fs.readFileSync(fp, 'utf-8').trim().split('\n').length >= 10;
|
|
279
|
+
}).length;
|
|
280
|
+
const icon = filled === VIBE_FILES.length ? green('✔') : filled > 0 ? yellow('◐') : red('✖');
|
|
281
|
+
console.log(` ${icon} .vibe/ ${filled}/${VIBE_FILES.length} files filled`);
|
|
282
|
+
|
|
283
|
+
// Show state.json health if available
|
|
284
|
+
const statePath = path.join(vibeDir, 'state.json');
|
|
285
|
+
if (exists(statePath)) {
|
|
233
286
|
try {
|
|
234
|
-
const
|
|
235
|
-
if (
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
// Check staleness
|
|
241
|
-
const updated = new Date(state.vibe_updated);
|
|
242
|
-
const daysOld = (Date.now() - updated.getTime()) / (1000 * 60 * 60 * 24);
|
|
243
|
-
if (daysOld > 30) {
|
|
244
|
-
console.log(yellow(' ⚠ ') + `${file} — last updated ${Math.floor(daysOld)} days ago. Consider refreshing.`);
|
|
245
|
-
warnings++;
|
|
246
|
-
continue;
|
|
287
|
+
const s = JSON.parse(fs.readFileSync(statePath, 'utf-8'));
|
|
288
|
+
if (s.health) console.log(dim(` health: ${s.health}`));
|
|
289
|
+
if (s.version) console.log(dim(` version: ${s.version}`));
|
|
290
|
+
if (s.vibe_updated) {
|
|
291
|
+
const days = Math.floor((Date.now() - new Date(s.vibe_updated).getTime()) / 86400000);
|
|
292
|
+
console.log(dim(` updated: ${days === 0 ? 'today' : days + ' days ago'}`));
|
|
247
293
|
}
|
|
248
|
-
} catch {
|
|
249
|
-
console.log(red(' ✖ ') + `${file} — invalid JSON`);
|
|
250
|
-
failed++;
|
|
251
|
-
continue;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (file === 'flows.md') {
|
|
256
|
-
const flowCount = (content.match(/^## \d+\./gm) || []).length;
|
|
257
|
-
if (flowCount < 2) {
|
|
258
|
-
console.log(yellow(' ⚠ ') + `${file} — only ${flowCount} flow(s). Most projects have 2+.`);
|
|
259
|
-
warnings++;
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
294
|
+
} catch {}
|
|
262
295
|
}
|
|
263
|
-
|
|
264
|
-
console.log(
|
|
265
|
-
passed++;
|
|
296
|
+
} else {
|
|
297
|
+
console.log(red(' ✖') + ' .vibe/ not initialized');
|
|
266
298
|
}
|
|
267
299
|
|
|
268
|
-
|
|
269
|
-
if (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
300
|
+
// docs status
|
|
301
|
+
if (exists(docsDir)) {
|
|
302
|
+
const filled = DOCS_FILES.filter(f => {
|
|
303
|
+
const fp = path.join(docsDir, f);
|
|
304
|
+
if (!exists(fp)) return false;
|
|
305
|
+
return fs.readFileSync(fp, 'utf-8').trim().split('\n').length >= 10;
|
|
306
|
+
}).length;
|
|
307
|
+
const icon = filled === DOCS_FILES.length ? green('✔') : filled > 0 ? yellow('◐') : red('✖');
|
|
308
|
+
console.log(` ${icon} docs/ ${filled}/${DOCS_FILES.length} files filled`);
|
|
273
309
|
} else {
|
|
274
|
-
console.log(
|
|
310
|
+
console.log(red(' ✖') + ' docs/ not initialized');
|
|
275
311
|
}
|
|
312
|
+
|
|
276
313
|
console.log('');
|
|
277
314
|
}
|
|
278
315
|
|
|
279
|
-
function
|
|
316
|
+
function cmdAll(targetDir) {
|
|
317
|
+
console.log('');
|
|
318
|
+
console.log(bold(' 🚀 vibes all'));
|
|
319
|
+
console.log(dim(' Full setup — semantic layer + operational docs'));
|
|
320
|
+
|
|
280
321
|
const vibeDir = path.join(targetDir, VIBE_DIR);
|
|
322
|
+
const docsDir = path.join(targetDir, DOCS_DIR);
|
|
323
|
+
|
|
324
|
+
if (!exists(vibeDir)) {
|
|
325
|
+
cmdInit(targetDir);
|
|
326
|
+
} else {
|
|
327
|
+
console.log(yellow('\n ⊘ .vibe/ already exists, skipping init'));
|
|
328
|
+
}
|
|
281
329
|
|
|
282
|
-
if (
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
330
|
+
if (!exists(docsDir) || fs.readdirSync(docsDir).length === 0) {
|
|
331
|
+
cmdDocs(targetDir);
|
|
332
|
+
} else {
|
|
333
|
+
cmdDocs(targetDir); // docs command already handles existing files gracefully
|
|
286
334
|
}
|
|
335
|
+
}
|
|
287
336
|
|
|
288
|
-
|
|
337
|
+
function cmdReset(targetDir) {
|
|
338
|
+
for (const dir of [VIBE_DIR, DOCS_DIR]) {
|
|
339
|
+
const p = path.join(targetDir, dir);
|
|
340
|
+
if (exists(p)) {
|
|
341
|
+
fs.rmSync(p, { recursive: true, force: true });
|
|
342
|
+
console.log(yellow(`\n ⚠ Removed ${dir}/`));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
cmdAll(targetDir);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function printNextSteps() {
|
|
349
|
+
console.log('');
|
|
350
|
+
console.log(bold(' Next steps:'));
|
|
351
|
+
console.log('');
|
|
352
|
+
console.log(' 1. Point your AI coding agent at this project');
|
|
353
|
+
console.log(' 2. Tell it:');
|
|
354
|
+
console.log('');
|
|
355
|
+
console.log(cyan(' "Read .vibe/VIBE_GUIDE.md, then analyze this codebase'));
|
|
356
|
+
console.log(cyan(' and fill out all the skeleton files in .vibe/'));
|
|
357
|
+
console.log(cyan(' Ask me any questions you can\'t answer from the code."'));
|
|
358
|
+
console.log('');
|
|
359
|
+
console.log(' 3. Run ' + cyan('vibes docs') + ' to scaffold operational docs too');
|
|
360
|
+
console.log(' 4. Review the output, commit to version control');
|
|
361
|
+
console.log('');
|
|
289
362
|
}
|
|
290
363
|
|
|
291
364
|
function printHelp() {
|
|
292
365
|
console.log('');
|
|
293
|
-
console.log(bold(' vibes') + ' — Semantic
|
|
366
|
+
console.log(bold(' vibes') + ' — Semantic layers + standardized docs for humans and AI');
|
|
294
367
|
console.log('');
|
|
295
368
|
console.log(' ' + bold('Usage:'));
|
|
296
369
|
console.log('');
|
|
297
|
-
console.log(' vibes init Create .vibe/
|
|
298
|
-
console.log(' vibes
|
|
299
|
-
console.log(' vibes
|
|
370
|
+
console.log(' vibes init Create .vibe/ semantic layer (6 files)');
|
|
371
|
+
console.log(' vibes docs Create docs/ operational documentation (11 files)');
|
|
372
|
+
console.log(' vibes all Create both .vibe/ and docs/ at once');
|
|
373
|
+
console.log(' vibes check Validate all files for completeness');
|
|
374
|
+
console.log(' vibes status Quick health overview');
|
|
375
|
+
console.log(' vibes reset Delete and recreate everything');
|
|
300
376
|
console.log(' vibes help Show this help message');
|
|
301
377
|
console.log('');
|
|
302
|
-
console.log(' ' + bold('
|
|
303
|
-
console.log('');
|
|
304
|
-
console.log(' A small set of 6 files that lets any human or AI understand');
|
|
305
|
-
console.log(' a project without reading the source code.');
|
|
306
|
-
console.log('');
|
|
307
|
-
console.log(' ' + dim('.vibe/'));
|
|
378
|
+
console.log(' ' + bold('.vibe/') + dim(' — Semantic layer (intent, decisions, flows)'));
|
|
308
379
|
console.log(' ' + dim('├── purpose.md — What is this? Who is it for?'));
|
|
309
380
|
console.log(' ' + dim('├── architecture.md — Systems and how they connect'));
|
|
310
381
|
console.log(' ' + dim('├── flows.md — User journeys, step by step'));
|
|
@@ -312,10 +383,18 @@ function printHelp() {
|
|
|
312
383
|
console.log(' ' + dim('├── decisions.md — Why things exist the way they do'));
|
|
313
384
|
console.log(' ' + dim('└── state.json — Machine-readable project health'));
|
|
314
385
|
console.log('');
|
|
315
|
-
console.log('
|
|
316
|
-
console.log('
|
|
317
|
-
console.log('
|
|
318
|
-
console.log('
|
|
386
|
+
console.log(' ' + bold('docs/') + dim(' — Operational docs (topology, API, issues, guides)'));
|
|
387
|
+
console.log(' ' + dim('├── README.md — Executive summary'));
|
|
388
|
+
console.log(' ' + dim('├── topology.md — File/folder map'));
|
|
389
|
+
console.log(' ' + dim('├── architecture.md — Component-level details'));
|
|
390
|
+
console.log(' ' + dim('├── api.md — API endpoints'));
|
|
391
|
+
console.log(' ' + dim('├── issues.md — Open bugs and blockers'));
|
|
392
|
+
console.log(' ' + dim('├── resolved.md — Closed issues archive'));
|
|
393
|
+
console.log(' ' + dim('├── roadmap.md — Milestones and priorities'));
|
|
394
|
+
console.log(' ' + dim('├── developer_guide.md — Setup, build, test, deploy'));
|
|
395
|
+
console.log(' ' + dim('├── troubleshooting.md — Common errors and fixes'));
|
|
396
|
+
console.log(' ' + dim('├── glossary.md — Project-specific terms'));
|
|
397
|
+
console.log(' ' + dim('└── decisions/ — Architecture decision records'));
|
|
319
398
|
console.log('');
|
|
320
399
|
}
|
|
321
400
|
|
|
@@ -328,20 +407,13 @@ const command = args[0] || 'help';
|
|
|
328
407
|
const targetDir = path.resolve(args[1] || '.');
|
|
329
408
|
|
|
330
409
|
switch (command) {
|
|
331
|
-
case 'init':
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
case 'check':
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
case '
|
|
338
|
-
cmdReset(targetDir);
|
|
339
|
-
break;
|
|
340
|
-
case 'help':
|
|
341
|
-
case '--help':
|
|
342
|
-
case '-h':
|
|
343
|
-
printHelp();
|
|
344
|
-
break;
|
|
410
|
+
case 'init': cmdInit(targetDir); break;
|
|
411
|
+
case 'docs': cmdDocs(targetDir); break;
|
|
412
|
+
case 'all': cmdAll(targetDir); break;
|
|
413
|
+
case 'check': cmdCheck(targetDir); break;
|
|
414
|
+
case 'status': cmdStatus(targetDir); break;
|
|
415
|
+
case 'reset': cmdReset(targetDir); break;
|
|
416
|
+
case 'help': case '--help': case '-h': printHelp(); break;
|
|
345
417
|
default:
|
|
346
418
|
console.log(red(`\n Unknown command: ${command}`));
|
|
347
419
|
printHelp();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibe-me",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Create a .vibe/ semantic repository layer for any project. Helps humans and AI agents understand your codebase without reading the source.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vibes",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"bin/",
|
|
24
24
|
"templates/",
|
|
25
|
-
"spec/"
|
|
25
|
+
"spec/",
|
|
26
|
+
"Vibe.bat"
|
|
26
27
|
],
|
|
27
28
|
"repository": {
|
|
28
29
|
"type": "git",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Executive Summary
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
This is the landing page for the project's operational documentation.
|
|
6
|
+
Write a 1-2 paragraph executive summary, then auto-link to every doc below.
|
|
7
|
+
Keep this under 100 lines. It's a table of contents, not a novel.
|
|
8
|
+
Delete these instruction comments when done.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
[1-2 paragraphs: what this project is, its current status, and what's active right now]
|
|
14
|
+
|
|
15
|
+
## Documentation Map
|
|
16
|
+
|
|
17
|
+
| Document | Description |
|
|
18
|
+
|---|---|
|
|
19
|
+
| [topology.md](topology.md) | File and folder structure with descriptions |
|
|
20
|
+
| [architecture.md](architecture.md) | Systems, components, and data flow |
|
|
21
|
+
| [api.md](api.md) | API endpoints, request/response formats |
|
|
22
|
+
| [issues.md](issues.md) | Open bugs, blockers, known problems |
|
|
23
|
+
| [resolved.md](resolved.md) | Closed issues and their resolutions |
|
|
24
|
+
| [roadmap.md](roadmap.md) | Milestones, priorities, what's next |
|
|
25
|
+
| [developer_guide.md](developer_guide.md) | Setup, build, test, deploy instructions |
|
|
26
|
+
| [troubleshooting.md](troubleshooting.md) | Common errors and how to fix them |
|
|
27
|
+
| [glossary.md](glossary.md) | Project-specific terms defined |
|
|
28
|
+
| [decisions/](decisions/) | Architecture decision records |
|
|
29
|
+
|
|
30
|
+
## Quick Links
|
|
31
|
+
|
|
32
|
+
- **Current Milestone:** [see roadmap](roadmap.md)
|
|
33
|
+
- **Active Blockers:** [see issues](issues.md)
|
|
34
|
+
- **Semantic Layer:** [.vibe/](../.vibe/) — purpose, architecture intent, decisions rationale
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
Document every API endpoint, WebSocket event, IPC command, or CLI interface.
|
|
6
|
+
If this is a library, document the public API surface.
|
|
7
|
+
If there's no API, write "N/A — this project has no API surface" and describe
|
|
8
|
+
how it's invoked instead (CLI args, config files, etc.)
|
|
9
|
+
Delete these instruction comments when done.
|
|
10
|
+
-->
|
|
11
|
+
|
|
12
|
+
## Base URL / Connection
|
|
13
|
+
|
|
14
|
+
- **Base URL:** `http://localhost:PORT`
|
|
15
|
+
- **Auth:** [none / Bearer token / API key / etc.]
|
|
16
|
+
|
|
17
|
+
## Endpoints
|
|
18
|
+
|
|
19
|
+
### `METHOD /path`
|
|
20
|
+
|
|
21
|
+
**Description:**
|
|
22
|
+
|
|
23
|
+
**Request:**
|
|
24
|
+
```json
|
|
25
|
+
{}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Response:**
|
|
29
|
+
```json
|
|
30
|
+
{}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Errors:**
|
|
34
|
+
| Code | Meaning |
|
|
35
|
+
|---|---|
|
|
36
|
+
| | |
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
This is the IMPLEMENTATION-LEVEL architecture — specific components,
|
|
6
|
+
data flow, and technical details. Different from .vibe/architecture.md
|
|
7
|
+
which describes intent-level systems.
|
|
8
|
+
Include diagrams, component breakdowns, and data flow.
|
|
9
|
+
Delete these instruction comments when done.
|
|
10
|
+
-->
|
|
11
|
+
|
|
12
|
+
## Components
|
|
13
|
+
|
|
14
|
+
<!-- List each major component/module with its responsibility -->
|
|
15
|
+
|
|
16
|
+
### [Component Name]
|
|
17
|
+
- **Responsibility:**
|
|
18
|
+
- **Key Files:**
|
|
19
|
+
- **Depends On:**
|
|
20
|
+
- **Depended On By:**
|
|
21
|
+
|
|
22
|
+
## Data Flow
|
|
23
|
+
|
|
24
|
+
<!-- How does data move through the system? Request lifecycle, event flow, etc. -->
|
|
25
|
+
|
|
26
|
+
## Infrastructure
|
|
27
|
+
|
|
28
|
+
<!-- Hosting, CI/CD, databases, external services, environment config -->
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# ADR-0001: [Decision Title]
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
[Proposed / Accepted / Deprecated / Superseded]
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
[What is the issue or question that prompted this decision?]
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
[What was decided?]
|
|
14
|
+
|
|
15
|
+
## Alternatives Considered
|
|
16
|
+
|
|
17
|
+
[What other options were evaluated and why were they rejected?]
|
|
18
|
+
|
|
19
|
+
## Consequences
|
|
20
|
+
|
|
21
|
+
[What are the positive and negative outcomes of this decision?]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Developer Guide
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
Write this for a developer who just cloned the repo and needs to:
|
|
6
|
+
1. Set up their environment
|
|
7
|
+
2. Build the project
|
|
8
|
+
3. Run tests
|
|
9
|
+
4. Make changes safely
|
|
10
|
+
Be specific — exact commands, exact versions, exact paths.
|
|
11
|
+
Delete these instruction comments when done.
|
|
12
|
+
-->
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
<!-- What must be installed before anything else? Include version numbers. -->
|
|
17
|
+
|
|
18
|
+
| Tool | Version | Install |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| | | |
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Step-by-step commands to get from fresh clone to running
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Build
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# How to build the project
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Test
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# How to run the test suite
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Project Rules
|
|
41
|
+
|
|
42
|
+
<!-- Coding conventions, file size limits, naming conventions, banned patterns -->
|
|
43
|
+
|
|
44
|
+
## Deployment
|
|
45
|
+
|
|
46
|
+
<!-- How to ship to production. If not applicable, say so. -->
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
Define every project-specific term, acronym, or concept that a new
|
|
6
|
+
contributor wouldn't immediately understand.
|
|
7
|
+
Sort alphabetically. Keep definitions to 1-2 sentences.
|
|
8
|
+
Delete these instruction comments when done.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
| Term | Definition |
|
|
12
|
+
|---|---|
|
|
13
|
+
| | |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Open Issues
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
Track all known bugs, blockers, incomplete features, and tech debt.
|
|
6
|
+
Use priority tags: 🔴 Critical, 🟡 Medium, 🟢 Low
|
|
7
|
+
When an issue is resolved, move it to resolved.md with the date and fix description.
|
|
8
|
+
Delete these instruction comments when done.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
## 🔴 Critical
|
|
12
|
+
|
|
13
|
+
<!-- Issues that block core functionality or cause data loss -->
|
|
14
|
+
|
|
15
|
+
## 🟡 Medium
|
|
16
|
+
|
|
17
|
+
<!-- Issues that affect user experience but have workarounds -->
|
|
18
|
+
|
|
19
|
+
## 🟢 Low / Tech Debt
|
|
20
|
+
|
|
21
|
+
<!-- Nice-to-haves, cleanup tasks, future improvements -->
|
|
22
|
+
|
|
23
|
+
## Backlog
|
|
24
|
+
|
|
25
|
+
<!-- Ideas and enhancements not yet prioritized -->
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Resolved Issues
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
When closing an issue from issues.md, move it here with:
|
|
6
|
+
- The date it was resolved
|
|
7
|
+
- How it was fixed (1-2 sentences)
|
|
8
|
+
- Link to the relevant commit/PR if available
|
|
9
|
+
This file is append-only. Never delete entries.
|
|
10
|
+
Delete these instruction comments when done.
|
|
11
|
+
-->
|
|
12
|
+
|
|
13
|
+
## Resolved
|
|
14
|
+
|
|
15
|
+
<!--
|
|
16
|
+
Format:
|
|
17
|
+
### [Issue Title]
|
|
18
|
+
- **Resolved:** YYYY-MM-DD
|
|
19
|
+
- **Fix:** [Brief description of what was done]
|
|
20
|
+
-->
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
Organize by milestones. Each milestone has a goal and a list of deliverables.
|
|
6
|
+
Use checkboxes to track progress.
|
|
7
|
+
Delete these instruction comments when done.
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
## Current Milestone: [Name]
|
|
11
|
+
|
|
12
|
+
**Goal:** [What does completing this milestone achieve?]
|
|
13
|
+
|
|
14
|
+
- [ ] [Deliverable 1]
|
|
15
|
+
- [ ] [Deliverable 2]
|
|
16
|
+
- [ ] [Deliverable 3]
|
|
17
|
+
|
|
18
|
+
## Next Milestone: [Name]
|
|
19
|
+
|
|
20
|
+
**Goal:**
|
|
21
|
+
|
|
22
|
+
- [ ] [Deliverable 1]
|
|
23
|
+
- [ ] [Deliverable 2]
|
|
24
|
+
|
|
25
|
+
## Completed Milestones
|
|
26
|
+
|
|
27
|
+
<!-- Move milestones here when done, with completion date -->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Codebase Topology
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
Map every top-level directory and key file. For each, include:
|
|
6
|
+
- Path, description, language, and approximate line count
|
|
7
|
+
Group by component or feature area.
|
|
8
|
+
Update this whenever files are added, removed, or significantly restructured.
|
|
9
|
+
Delete these instruction comments when done.
|
|
10
|
+
-->
|
|
11
|
+
|
|
12
|
+
## Directory Structure
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
project-root/
|
|
16
|
+
├── [folder]/ — [description]
|
|
17
|
+
│ ├── [file] — [description]
|
|
18
|
+
│ └── ...
|
|
19
|
+
└── ...
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## File Inventory
|
|
23
|
+
|
|
24
|
+
| File | Lines | Language | Description |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| | | | |
|
|
27
|
+
|
|
28
|
+
## Dependency Map
|
|
29
|
+
|
|
30
|
+
<!-- Which modules depend on which? Show the import/call graph at a high level. -->
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
INSTRUCTIONS FOR AI AGENT:
|
|
5
|
+
Document every error a developer or user might encounter.
|
|
6
|
+
Format: Symptom → Cause → Fix.
|
|
7
|
+
Add to this file every time you debug something non-obvious.
|
|
8
|
+
Delete these instruction comments when done.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
## Common Issues
|
|
12
|
+
|
|
13
|
+
### [Error message or symptom]
|
|
14
|
+
|
|
15
|
+
**Cause:** [Why this happens]
|
|
16
|
+
|
|
17
|
+
**Fix:**
|
|
18
|
+
```bash
|
|
19
|
+
# Exact commands or steps to resolve
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<!-- Copy the template above for each issue. Aim for 5+ entries. -->
|
|
25
|
+
|
|
26
|
+
## Diagnostic Commands
|
|
27
|
+
|
|
28
|
+
<!-- Quick commands to check system health, versions, connectivity, etc. -->
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Example: check versions
|
|
32
|
+
```
|