vibe-me 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # vibes
2
+
3
+ **Every repository should contain a continuously maintained, AI-readable and human-readable model of itself.**
4
+
5
+ `vibes` creates a `.vibe/` folder in your project — 6 files that let any human or AI understand your codebase without reading the source code.
6
+
7
+ ```
8
+ .vibe/
9
+ ├── purpose.md — What is this? Who is it for? What does it NOT do?
10
+ ├── architecture.md — Systems and how they connect (not files — systems)
11
+ ├── flows.md — User journeys, step by step
12
+ ├── entities.md — Important nouns and their relationships
13
+ ├── decisions.md — Why things exist the way they do
14
+ └── state.json — Machine-readable project health snapshot
15
+ ```
16
+
17
+ ## Why?
18
+
19
+ Most repositories are impossible to understand without reading the source code. Documentation describes *how* things work but never captures:
20
+
21
+ - **Why** things exist (what alternatives were rejected?)
22
+ - **What** users actually do (step-by-step journeys, not component descriptions)
23
+ - **What** the important nouns are (domain entities, not class hierarchies)
24
+ - **What** the system *is* (intent, not implementation)
25
+
26
+ The `.vibe/` folder answers these questions. It describes **intent rather than implementation** — which means it's language-agnostic, framework-agnostic, and survives complete rewrites.
27
+
28
+ ## Quick Start
29
+
30
+ ### Option 1: npx (no install)
31
+
32
+ ```bash
33
+ npx vibes init
34
+ ```
35
+
36
+ ### Option 2: Global install
37
+
38
+ ```bash
39
+ npm install -g vibes
40
+ vibes init
41
+ ```
42
+
43
+ ### Option 3: Clone and run
44
+
45
+ ```bash
46
+ git clone https://github.com/unlimitedinfinit/Vibes.git
47
+ cd your-project
48
+ node /path/to/Vibes/bin/vibes.js init
49
+ ```
50
+
51
+ This creates a `.vibe/` folder with skeleton templates and a `VIBE_GUIDE.md` instruction file.
52
+
53
+ ## Usage
54
+
55
+ ### Initialize
56
+
57
+ ```bash
58
+ cd your-project
59
+ vibes init
60
+ ```
61
+
62
+ Creates `.vibe/` with 6 skeleton files + the full guide. Auto-detects your project name from `package.json`, `Cargo.toml`, `go.mod`, or `pyproject.toml`.
63
+
64
+ ### Fill it out (with your AI agent)
65
+
66
+ Point your AI coding agent at the project and tell it:
67
+
68
+ > "Read `.vibe/VIBE_GUIDE.md`, then analyze this codebase and fill out all the skeleton files in `.vibe/`. Ask me any questions you can't answer from the code."
69
+
70
+ The guide contains detailed instructions, examples across 6+ project types, anti-patterns, and a quality checklist.
71
+
72
+ ### Validate
73
+
74
+ ```bash
75
+ vibes check
76
+ ```
77
+
78
+ Checks that all 6 files exist, are non-empty, and pass quality heuristics:
79
+ - `purpose.md` has a "NOT do" section
80
+ - `decisions.md` has 2+ decisions
81
+ - `entities.md` has "What depends on it?" fields
82
+ - `flows.md` has 2+ user flows
83
+ - `state.json` is valid JSON and not stale (>30 days)
84
+
85
+ ### Reset
86
+
87
+ ```bash
88
+ vibes reset
89
+ ```
90
+
91
+ Deletes and recreates `.vibe/` with fresh skeletons.
92
+
93
+ ## The Core Principle
94
+
95
+ > **Describe intent, not implementation.**
96
+
97
+ Every line in `.vibe/` should pass this test: *"Would this still be true if we rewrote the entire codebase in a different language?"*
98
+
99
+ - ✅ "We chose SQLite because the access pattern is <100 writes/hour"
100
+ - ❌ "The `DatabaseService` class has a `connect()` method"
101
+ - ✅ "User uploads document → AI analyzes → results displayed"
102
+ - ❌ "POST /api/documents calls `processDocument()` in `services/ai.ts`"
103
+
104
+ ## The AI Update Protocol
105
+
106
+ Every time an AI agent touches a repository with `.vibe/`, the workflow is:
107
+
108
+ ```
109
+ Read .vibe/ to understand the project
110
+
111
+ Make code changes
112
+
113
+ Update relevant .vibe/ files to reflect new understanding
114
+
115
+ Commit code + .vibe changes together
116
+ ```
117
+
118
+ The semantic model is a first-class citizen — not an afterthought.
119
+
120
+ ## Works With
121
+
122
+ `.vibe/` is language-agnostic. It works for:
123
+
124
+ - Python, TypeScript, Go, Rust, C#, Java, C++, Swift
125
+ - React, Next.js, Django, FastAPI, Spring, Rails
126
+ - Unity, Unreal, Godot
127
+ - Embedded firmware, CLI tools, mobile apps, libraries
128
+ - Monorepos, microservices, serverless
129
+
130
+ Because it describes **what** and **why**, not **how**.
131
+
132
+ ## Repository Structure
133
+
134
+ ```
135
+ Vibes/
136
+ ├── bin/vibes.js — CLI entry point (zero dependencies)
137
+ ├── templates/ — Skeleton files copied into .vibe/
138
+ │ ├── purpose.md
139
+ │ ├── architecture.md
140
+ │ ├── flows.md
141
+ │ ├── entities.md
142
+ │ ├── decisions.md
143
+ │ └── state.json
144
+ ├── spec/
145
+ │ └── VIBE_GUIDE.md — Full spec with examples and instructions
146
+ ├── QUICK_START_PROMPT.md — Copy-paste prompt for AI agents
147
+ ├── VIBE_GUIDE.md — Full spec (also at root for easy reading)
148
+ ├── package.json
149
+ ├── LICENSE — MIT
150
+ └── README.md — This file
151
+ ```
152
+
153
+ ## License
154
+
155
+ MIT — use it, fork it, build on it.
156
+
157
+ ## Contributing
158
+
159
+ The `.vibe` spec is version 1.0. After testing across 20+ repositories, we'll refine which information is always useful, which is noise, what AI can extract automatically, and what humans must provide.
160
+
161
+ If you create `.vibe/` for your project, open an issue and share what you learned.
package/bin/vibes.js ADDED
@@ -0,0 +1,349 @@
1
+ #!/usr/bin/env node
2
+
3
+ // vibes — Create a .vibe/ semantic layer for any project
4
+ // Zero dependencies. Single file. Works with npx.
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ // ─────────────────────────────────────────────
10
+ // Config
11
+ // ─────────────────────────────────────────────
12
+
13
+ const VIBE_DIR = '.vibe';
14
+ const TEMPLATES_DIR = path.join(__dirname, '..', 'templates');
15
+ const SPEC_DIR = path.join(__dirname, '..', 'spec');
16
+
17
+ const TEMPLATE_FILES = [
18
+ 'purpose.md',
19
+ 'architecture.md',
20
+ 'flows.md',
21
+ 'entities.md',
22
+ 'decisions.md',
23
+ 'state.json'
24
+ ];
25
+
26
+ const SPEC_FILE = 'VIBE_GUIDE.md';
27
+
28
+ // ─────────────────────────────────────────────
29
+ // Colors (no dependencies — raw ANSI)
30
+ // ─────────────────────────────────────────────
31
+
32
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
33
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
34
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
35
+ const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
36
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
37
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
38
+
39
+ // ─────────────────────────────────────────────
40
+ // Helpers
41
+ // ─────────────────────────────────────────────
42
+
43
+ function fileExists(filePath) {
44
+ try {
45
+ fs.accessSync(filePath);
46
+ return true;
47
+ } catch {
48
+ return false;
49
+ }
50
+ }
51
+
52
+ function copyFile(src, dest) {
53
+ const content = fs.readFileSync(src, 'utf-8');
54
+ fs.writeFileSync(dest, content, 'utf-8');
55
+ }
56
+
57
+ function getProjectName(dir) {
58
+ // Try package.json
59
+ const pkgPath = path.join(dir, 'package.json');
60
+ if (fileExists(pkgPath)) {
61
+ try {
62
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
63
+ if (pkg.name) return pkg.name;
64
+ } catch {}
65
+ }
66
+ // Try Cargo.toml
67
+ const cargoPath = path.join(dir, 'Cargo.toml');
68
+ if (fileExists(cargoPath)) {
69
+ try {
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];
91
+ } catch {}
92
+ }
93
+ // Fallback to directory name
94
+ return path.basename(dir);
95
+ }
96
+
97
+ function getNow() {
98
+ return new Date().toISOString();
99
+ }
100
+
101
+ // ─────────────────────────────────────────────
102
+ // Commands
103
+ // ─────────────────────────────────────────────
104
+
105
+ function cmdInit(targetDir) {
106
+ const vibeDir = path.join(targetDir, VIBE_DIR);
107
+ const projectName = getProjectName(targetDir);
108
+
109
+ // Check if .vibe already exists
110
+ if (fileExists(vibeDir)) {
111
+ console.log(red('\n ✖ .vibe/ already exists in this directory.'));
112
+ console.log(dim(' Use "vibes reset" to overwrite, or edit files directly.\n'));
113
+ process.exit(1);
114
+ }
115
+
116
+ console.log('');
117
+ console.log(bold(' ⚡ vibes init'));
118
+ console.log(dim(` Creating .vibe/ semantic layer for ${cyan(projectName)}`));
119
+ console.log('');
120
+
121
+ // Create .vibe directory
122
+ fs.mkdirSync(vibeDir, { recursive: true });
123
+
124
+ // Copy template files
125
+ let created = 0;
126
+ for (const file of TEMPLATE_FILES) {
127
+ const src = path.join(TEMPLATES_DIR, file);
128
+ const dest = path.join(vibeDir, file);
129
+
130
+ if (file === 'state.json') {
131
+ // Inject project name and timestamp into state.json
132
+ let content = fs.readFileSync(src, 'utf-8');
133
+ content = content.replace('PROJECT_NAME', projectName);
134
+ content = content.replace('TIMESTAMP', getNow());
135
+ fs.writeFileSync(dest, content, 'utf-8');
136
+ } else {
137
+ // Copy markdown templates as-is
138
+ copyFile(src, dest);
139
+ }
140
+
141
+ console.log(green(' ✔ ') + dim('.vibe/') + file);
142
+ created++;
143
+ }
144
+
145
+ // Copy the guide as a hidden instruction file inside .vibe
146
+ const guideSrc = path.join(SPEC_DIR, SPEC_FILE);
147
+ const guideDest = path.join(vibeDir, SPEC_FILE);
148
+ copyFile(guideSrc, guideDest);
149
+ console.log(green(' ✔ ') + dim('.vibe/') + SPEC_FILE + dim(' (agent instructions)'));
150
+ created++;
151
+
152
+ console.log('');
153
+ console.log(green(` ✔ Created ${created} files in .vibe/`));
154
+ console.log('');
155
+ console.log(bold(' Next steps:'));
156
+ console.log('');
157
+ console.log(' 1. Point your AI coding agent at this project');
158
+ console.log(' 2. Tell it:');
159
+ console.log('');
160
+ console.log(cyan(' "Read .vibe/VIBE_GUIDE.md, then analyze this codebase'));
161
+ console.log(cyan(' and fill out all the skeleton files in .vibe/'));
162
+ console.log(cyan(' Ask me any questions you can\'t answer from the code."'));
163
+ console.log('');
164
+ console.log(' 3. Review the output, commit to version control');
165
+ console.log('');
166
+ console.log(dim(' The guide contains full instructions, examples, and'));
167
+ console.log(dim(' quality checklists for the AI to follow.'));
168
+ console.log('');
169
+ }
170
+
171
+ function cmdCheck(targetDir) {
172
+ const vibeDir = path.join(targetDir, VIBE_DIR);
173
+
174
+ if (!fileExists(vibeDir)) {
175
+ console.log(red('\n ✖ No .vibe/ folder found. Run "vibes init" first.\n'));
176
+ process.exit(1);
177
+ }
178
+
179
+ console.log('');
180
+ console.log(bold(' 🔍 vibes check'));
181
+ console.log('');
182
+
183
+ let passed = 0;
184
+ let failed = 0;
185
+ let warnings = 0;
186
+
187
+ // Check each file exists and is non-empty
188
+ for (const file of TEMPLATE_FILES) {
189
+ const filePath = path.join(vibeDir, file);
190
+ if (!fileExists(filePath)) {
191
+ console.log(red(' ✖ ') + `${file} — missing`);
192
+ failed++;
193
+ continue;
194
+ }
195
+
196
+ const content = fs.readFileSync(filePath, 'utf-8').trim();
197
+ const lines = content.split('\n').length;
198
+
199
+ if (lines < 5) {
200
+ console.log(yellow(' ⚠ ') + `${file} — exists but looks empty (${lines} lines)`);
201
+ warnings++;
202
+ continue;
203
+ }
204
+
205
+ // File-specific checks
206
+ if (file === 'purpose.md') {
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
+ }
213
+
214
+ if (file === 'decisions.md') {
215
+ // Check for at least 2 "## Why" headings
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
+ }
222
+ }
223
+
224
+ if (file === 'entities.md') {
225
+ if (!content.includes('What depends on it')) {
226
+ console.log(yellow(' ⚠ ') + `${file} — entities missing "What depends on it?" field`);
227
+ warnings++;
228
+ continue;
229
+ }
230
+ }
231
+
232
+ if (file === 'state.json') {
233
+ try {
234
+ const state = JSON.parse(content);
235
+ if (!state.vibe_updated) {
236
+ console.log(yellow(' ⚠ ') + `${file} — missing vibe_updated timestamp`);
237
+ warnings++;
238
+ continue;
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;
247
+ }
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
+ }
262
+ }
263
+
264
+ console.log(green(' ✔ ') + `${file} — ${lines} lines`);
265
+ passed++;
266
+ }
267
+
268
+ console.log('');
269
+ if (failed > 0) {
270
+ console.log(red(` Result: ${failed} failed, ${warnings} warnings, ${passed} passed`));
271
+ } else if (warnings > 0) {
272
+ console.log(yellow(` Result: ${warnings} warnings, ${passed} passed`));
273
+ } else {
274
+ console.log(green(` Result: All ${passed} files pass ✔`));
275
+ }
276
+ console.log('');
277
+ }
278
+
279
+ function cmdReset(targetDir) {
280
+ const vibeDir = path.join(targetDir, VIBE_DIR);
281
+
282
+ if (fileExists(vibeDir)) {
283
+ // Remove existing .vibe
284
+ fs.rmSync(vibeDir, { recursive: true, force: true });
285
+ console.log(yellow('\n ⚠ Removed existing .vibe/ folder'));
286
+ }
287
+
288
+ cmdInit(targetDir);
289
+ }
290
+
291
+ function printHelp() {
292
+ console.log('');
293
+ console.log(bold(' vibes') + ' — Semantic repository layers for humans and AI');
294
+ console.log('');
295
+ console.log(' ' + bold('Usage:'));
296
+ console.log('');
297
+ console.log(' vibes init Create .vibe/ skeleton in the current directory');
298
+ console.log(' vibes check Validate .vibe/ files for completeness');
299
+ console.log(' vibes reset Delete and recreate .vibe/ skeleton');
300
+ console.log(' vibes help Show this help message');
301
+ console.log('');
302
+ console.log(' ' + bold('What is .vibe?'));
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/'));
308
+ console.log(' ' + dim('├── purpose.md — What is this? Who is it for?'));
309
+ console.log(' ' + dim('├── architecture.md — Systems and how they connect'));
310
+ console.log(' ' + dim('├── flows.md — User journeys, step by step'));
311
+ console.log(' ' + dim('├── entities.md — Important nouns and relationships'));
312
+ console.log(' ' + dim('├── decisions.md — Why things exist the way they do'));
313
+ console.log(' ' + dim('└── state.json — Machine-readable project health'));
314
+ console.log('');
315
+ console.log(' After running ' + cyan('vibes init') + ', point your AI coding agent');
316
+ console.log(' at the project and tell it to read ' + cyan('.vibe/VIBE_GUIDE.md') + '.');
317
+ console.log(' The guide contains everything the agent needs to analyze');
318
+ console.log(' your codebase and fill out the semantic layer.');
319
+ console.log('');
320
+ }
321
+
322
+ // ─────────────────────────────────────────────
323
+ // Main
324
+ // ─────────────────────────────────────────────
325
+
326
+ const args = process.argv.slice(2);
327
+ const command = args[0] || 'help';
328
+ const targetDir = path.resolve(args[1] || '.');
329
+
330
+ switch (command) {
331
+ case 'init':
332
+ cmdInit(targetDir);
333
+ break;
334
+ case 'check':
335
+ cmdCheck(targetDir);
336
+ break;
337
+ case 'reset':
338
+ cmdReset(targetDir);
339
+ break;
340
+ case 'help':
341
+ case '--help':
342
+ case '-h':
343
+ printHelp();
344
+ break;
345
+ default:
346
+ console.log(red(`\n Unknown command: ${command}`));
347
+ printHelp();
348
+ process.exit(1);
349
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "vibe-me",
3
+ "version": "1.0.0",
4
+ "description": "Create a .vibe/ semantic repository layer for any project. Helps humans and AI agents understand your codebase without reading the source.",
5
+ "keywords": [
6
+ "vibes",
7
+ "vibe",
8
+ "documentation",
9
+ "ai",
10
+ "semantic",
11
+ "repository",
12
+ "context",
13
+ "coding-agent",
14
+ "vibe-coding",
15
+ "developer-tools"
16
+ ],
17
+ "author": "Joshua M. Abrams",
18
+ "license": "MIT",
19
+ "bin": {
20
+ "vibes": "bin/vibes.js"
21
+ },
22
+ "files": [
23
+ "bin/",
24
+ "templates/",
25
+ "spec/"
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/unlimitedinfinit/Vibes.git"
30
+ },
31
+ "engines": {
32
+ "node": ">=16.0.0"
33
+ }
34
+ }