@jgiox/goodvibes 1.2.0 → 1.6.1
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/dist/index.js +190 -38
- package/package.json +6 -3
- package/templates/.amazonq/rules/goodvibes.md +28 -0
- package/templates/.bolt/prompt +11 -0
- package/templates/.claude/skills/goodvibes-hygiene/SKILL.md +8 -1
- package/templates/.clinerules/goodvibes.md +28 -0
- package/templates/.continue/rules/goodvibes.md +28 -0
- package/templates/.cursor/rules/goodvibes.mdc +28 -0
- package/templates/.devin/rules/goodvibes.md +28 -0
- package/templates/.github/copilot-instructions.md +28 -0
- package/templates/.kiro/steering/goodvibes.md +28 -0
- package/templates/.windsurfrules +28 -0
- package/templates/AGENTS.md +28 -0
- package/templates/CLAUDE.md +8 -1
- package/templates/GEMINI.md +28 -0
- package/templates/docs/getting-started.md +31 -0
- package/templates/docs/onboarding.md +18 -0
- package/templates/docs/platform-setup/base44.md +40 -0
- package/templates/docs/platform-setup/bolt.md +22 -0
- package/templates/docs/platform-setup/chatgpt.md +38 -0
- package/templates/docs/platform-setup/cursor.md +23 -0
- package/templates/docs/platform-setup/kiro.md +19 -0
- package/templates/docs/platform-setup/replit.md +26 -0
- package/templates/docs/platform-setup/windsurf.md +19 -0
- package/templates/replit.md +32 -0
package/dist/index.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
+
import { createRequire as createRequire2 } from "module";
|
|
4
5
|
import { Command } from "commander";
|
|
5
6
|
|
|
6
7
|
// src/commands/init.ts
|
|
7
|
-
import {
|
|
8
|
+
import { readdirSync } from "fs";
|
|
9
|
+
import { intro, outro, note, tasks, cancel } from "@clack/prompts";
|
|
8
10
|
|
|
9
11
|
// src/steps/copy-templates.ts
|
|
10
12
|
import { copy } from "fs-extra";
|
|
11
13
|
import { readFile as readFile2, rename } from "fs/promises";
|
|
12
14
|
import { readdir } from "fs/promises";
|
|
13
15
|
import { existsSync } from "fs";
|
|
14
|
-
import { join, relative } from "path";
|
|
16
|
+
import { join, relative, sep } from "path";
|
|
15
17
|
import { fileURLToPath } from "url";
|
|
16
18
|
|
|
17
19
|
// src/utils/sentinel-merge.ts
|
|
@@ -104,26 +106,51 @@ async function copyTemplates(templateDir, destDir, dryRun, minimal, projectType
|
|
|
104
106
|
const selectedVariant = `ci-${projectType}.yml`;
|
|
105
107
|
if (dryRun) {
|
|
106
108
|
const all = await listTemplateFiles(templateDir);
|
|
107
|
-
return all.filter((p) => !ciVariants.some((v) => p.endsWith(v) && v !== selectedVariant));
|
|
109
|
+
return { written: all.filter((p) => !ciVariants.some((v) => p.endsWith(v) && v !== selectedVariant)), skipped: [] };
|
|
108
110
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
const existingBefore = /* @__PURE__ */ new Set();
|
|
112
|
+
if (existsSync(destDir)) {
|
|
113
|
+
const beforeFiles = await walkDir(destDir, destDir).catch(() => []);
|
|
114
|
+
for (const f of beforeFiles) existingBefore.add(f);
|
|
115
|
+
}
|
|
116
|
+
const skippedFiles = [];
|
|
117
|
+
const destCiYml = join(destDir, ".github", "workflows", "ci.yml");
|
|
118
|
+
const workflowPrefix = join(".github", "workflows") + sep;
|
|
119
|
+
const destHasWorkflows = [...existingBefore].some(
|
|
120
|
+
(f) => f.startsWith(workflowPrefix) && f.endsWith(".yml")
|
|
121
|
+
);
|
|
122
|
+
try {
|
|
123
|
+
await copy(templateDir, destDir, {
|
|
124
|
+
overwrite: false,
|
|
125
|
+
errorOnExist: false,
|
|
126
|
+
filter: (src) => {
|
|
127
|
+
if (src.endsWith("CLAUDE.md")) return false;
|
|
128
|
+
const rel = relative(templateDir, src);
|
|
129
|
+
if (minimal && (rel.startsWith(".github") || rel.startsWith("docs"))) return false;
|
|
130
|
+
if (rel.includes("..")) return false;
|
|
131
|
+
if (src.endsWith(selectedVariant) && existsSync(destCiYml)) return false;
|
|
132
|
+
for (const variant of ciVariants) {
|
|
133
|
+
if (src.endsWith(variant) && variant !== selectedVariant) return false;
|
|
134
|
+
}
|
|
135
|
+
if (destHasWorkflows && rel.startsWith(workflowPrefix) && src.endsWith(".yml")) return false;
|
|
136
|
+
return true;
|
|
118
137
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
138
|
+
});
|
|
139
|
+
} catch (e) {
|
|
140
|
+
const err = e;
|
|
141
|
+
const hint = err.code === "EACCES" || err.code === "EPERM" ? "Check directory permissions." : "Check available disk space.";
|
|
142
|
+
err.message = `Cannot copy template files: ${err.message}. ${hint}`;
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
122
145
|
if (!minimal) {
|
|
123
146
|
const variantPath = join(destDir, ".github", "workflows", selectedVariant);
|
|
124
147
|
const ciPath = join(destDir, ".github", "workflows", "ci.yml");
|
|
125
148
|
if (existsSync(variantPath)) {
|
|
126
|
-
|
|
149
|
+
if (existsSync(ciPath)) {
|
|
150
|
+
skippedFiles.push(".github/workflows/ci.yml");
|
|
151
|
+
} else {
|
|
152
|
+
await rename(variantPath, ciPath);
|
|
153
|
+
}
|
|
127
154
|
}
|
|
128
155
|
}
|
|
129
156
|
const claudeSrc = join(templateDir, "CLAUDE.md");
|
|
@@ -131,7 +158,11 @@ async function copyTemplates(templateDir, destDir, dryRun, minimal, projectType
|
|
|
131
158
|
const templateContent = await readFile2(claudeSrc, "utf-8");
|
|
132
159
|
await mergeClaude(claudeDest, templateContent);
|
|
133
160
|
const destFiles = await walkDir(destDir, destDir);
|
|
134
|
-
|
|
161
|
+
const allDestFiles = destFiles.sort();
|
|
162
|
+
const written = allDestFiles.filter((f) => !existingBefore.has(f));
|
|
163
|
+
const writtenWithClaude = written.includes("CLAUDE.md") ? written : ["CLAUDE.md", ...written];
|
|
164
|
+
const skipped = [...allDestFiles.filter((f) => existingBefore.has(f) && f !== "CLAUDE.md"), ...skippedFiles];
|
|
165
|
+
return { written: writtenWithClaude.sort(), skipped: skipped.sort() };
|
|
135
166
|
}
|
|
136
167
|
|
|
137
168
|
// src/steps/install-headroom.ts
|
|
@@ -173,6 +204,16 @@ async function installHeadroom(log) {
|
|
|
173
204
|
log("Python 3.10+ not found \u2014 skipping headroom install. Install Python 3.10+ and run `goodvibes init` again.");
|
|
174
205
|
return;
|
|
175
206
|
}
|
|
207
|
+
log("headroom compresses AI context to save tokens \u2014 this keeps your costs down and sessions faster.");
|
|
208
|
+
try {
|
|
209
|
+
await execa2("headroom", ["--version"]);
|
|
210
|
+
log("headroom already installed \u2014 skipping");
|
|
211
|
+
return;
|
|
212
|
+
} catch (e) {
|
|
213
|
+
if (e.code !== "ENOENT") {
|
|
214
|
+
log(`headroom probe failed: ${e.message?.split("\n")[0] ?? "unknown"}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
176
217
|
log("Note: headroom will download its compression model on first use \u2014 this may take 1\u20133 minutes on a slow connection.");
|
|
177
218
|
const installers = [
|
|
178
219
|
{ cmd: "uv", args: ["tool", "install", "headroom-ai[all]"] },
|
|
@@ -262,15 +303,24 @@ function registerInitCommand(program2) {
|
|
|
262
303
|
const cwd = process.cwd();
|
|
263
304
|
const projectType = detectProjectType(cwd);
|
|
264
305
|
const templateDir = resolveTemplatesDir();
|
|
306
|
+
const ciVariants = ["ci-node.yml", "ci-python.yml", "ci-both.yml"];
|
|
307
|
+
const selectedVariant = `ci-${projectType}.yml`;
|
|
265
308
|
intro("goodvibes init");
|
|
309
|
+
const existingEntries = readdirSync(cwd).filter((e) => e !== ".git" && e !== ".DS_Store");
|
|
310
|
+
if (existingEntries.length > 0) {
|
|
311
|
+
note("Existing files will not be overwritten.", "Non-empty project detected");
|
|
312
|
+
}
|
|
266
313
|
if (dryRun) {
|
|
267
|
-
const
|
|
314
|
+
const allFiles = await listTemplateFiles(templateDir);
|
|
315
|
+
const files = minimal ? allFiles.filter((f) => !f.startsWith(".github") && !f.startsWith("docs")) : allFiles.filter((f) => !ciVariants.some((v) => f.endsWith(v) && v !== selectedVariant));
|
|
268
316
|
note(files.map((f) => ` Would write: ${f}`).join("\n"), "Dry run \u2014 no files written");
|
|
269
317
|
note(
|
|
270
318
|
[
|
|
271
|
-
"1. Open this project in
|
|
272
|
-
"2.
|
|
273
|
-
"
|
|
319
|
+
"1. Open this project in your AI coding tool",
|
|
320
|
+
"2. Claude Code users: /plugin marketplace add DietrichGebert/ponytail",
|
|
321
|
+
" Other IDEs (Cursor, Windsurf, Kiro, Antigravity, etc.): rules already active",
|
|
322
|
+
"3. Start coding \u2014 CLAUDE.md rules are already active",
|
|
323
|
+
...minimal ? ["4. Run without --minimal to also add CI workflows and docs."] : []
|
|
274
324
|
].join("\n"),
|
|
275
325
|
"Next steps"
|
|
276
326
|
);
|
|
@@ -278,13 +328,15 @@ function registerInitCommand(program2) {
|
|
|
278
328
|
return;
|
|
279
329
|
}
|
|
280
330
|
const createdFiles = [];
|
|
331
|
+
const skippedFiles = [];
|
|
281
332
|
const taskList = [
|
|
282
333
|
{
|
|
283
334
|
title: "Copying template files",
|
|
284
335
|
task: async (message) => {
|
|
285
|
-
const
|
|
286
|
-
createdFiles.push(...
|
|
287
|
-
|
|
336
|
+
const { written, skipped } = await copyTemplates(templateDir, cwd, false, minimal, projectType);
|
|
337
|
+
createdFiles.push(...written);
|
|
338
|
+
skippedFiles.push(...skipped);
|
|
339
|
+
return `Copied ${written.length} files`;
|
|
288
340
|
}
|
|
289
341
|
}
|
|
290
342
|
];
|
|
@@ -306,14 +358,34 @@ function registerInitCommand(program2) {
|
|
|
306
358
|
}
|
|
307
359
|
);
|
|
308
360
|
}
|
|
309
|
-
|
|
310
|
-
|
|
361
|
+
try {
|
|
362
|
+
await tasks(taskList);
|
|
363
|
+
} catch (e) {
|
|
364
|
+
const err = e;
|
|
365
|
+
const msg = err.code === "EACCES" || err.code === "EPERM" ? `Cannot write files to ${cwd}.
|
|
366
|
+
Why: You do not have write permission here.
|
|
367
|
+
Fix: Make sure you are inside your project directory before running this command.
|
|
368
|
+
If permissions are the issue: chmod u+w ${cwd} (macOS/Linux) or check folder properties (Windows)` : `Setup failed: ${err.message ?? String(e)}`;
|
|
369
|
+
cancel(msg);
|
|
370
|
+
process.exit(1);
|
|
371
|
+
}
|
|
372
|
+
note(createdFiles.join("\n") || "(none)", `Files written (${createdFiles.length})`);
|
|
373
|
+
if (skippedFiles.length > 0) {
|
|
374
|
+
note(skippedFiles.join("\n"), `Files skipped (${skippedFiles.length})`);
|
|
375
|
+
}
|
|
311
376
|
const nextSteps = [
|
|
312
|
-
"1. Open this project in
|
|
313
|
-
"2.
|
|
377
|
+
"1. Open this project in your AI coding tool",
|
|
378
|
+
"2. Claude Code users: /plugin marketplace add DietrichGebert/ponytail",
|
|
379
|
+
" Other IDEs (Cursor, Windsurf, Kiro, Antigravity, etc.): rules already active",
|
|
314
380
|
"3. Start coding \u2014 CLAUDE.md rules are already active"
|
|
315
381
|
].join("\n");
|
|
316
382
|
note(nextSteps, "Next steps");
|
|
383
|
+
if (minimal) {
|
|
384
|
+
note(
|
|
385
|
+
"CI workflows and docs were skipped.\nRun goodvibes init without --minimal to add them.",
|
|
386
|
+
"Skipped layers"
|
|
387
|
+
);
|
|
388
|
+
}
|
|
317
389
|
outro("You're all set!");
|
|
318
390
|
});
|
|
319
391
|
}
|
|
@@ -360,13 +432,6 @@ async function detectInstalledVersion(cwd) {
|
|
|
360
432
|
const content = await readFile3(claudePath, "utf-8");
|
|
361
433
|
return extractVersion(content);
|
|
362
434
|
}
|
|
363
|
-
async function detectBundledVersion(templateDir) {
|
|
364
|
-
if (!templateDir) return null;
|
|
365
|
-
const claudeSrc = join3(templateDir, "CLAUDE.md");
|
|
366
|
-
if (!await pathExists2(claudeSrc)) return null;
|
|
367
|
-
const content = await readFile3(claudeSrc, "utf-8");
|
|
368
|
-
return extractVersion(content);
|
|
369
|
-
}
|
|
370
435
|
async function computeChanges(templateDir, destDir, projectType) {
|
|
371
436
|
const allFiles = await listTemplateFiles(templateDir) ?? [];
|
|
372
437
|
const managedFiles = allFiles.filter(
|
|
@@ -423,7 +488,7 @@ async function upgradeTemplates(templateDir, destDir, projectType) {
|
|
|
423
488
|
return allDest.filter((f) => f.startsWith(".claude/skills/") || f.startsWith(".github/workflows/") || f === "CLAUDE.md").sort();
|
|
424
489
|
}
|
|
425
490
|
function registerUpgradeCommand(program2) {
|
|
426
|
-
program2.command("upgrade").description("Update goodvibes-managed files to the latest version").option("--dry-run", "Preview what would change without writing").action(async (options) => {
|
|
491
|
+
program2.command("upgrade").alias("update").description("Update goodvibes-managed files to the latest version").option("--dry-run", "Preview what would change without writing").action(async (options) => {
|
|
427
492
|
const dryRun = options.dryRun ?? false;
|
|
428
493
|
const cwd = process.cwd();
|
|
429
494
|
intro2("goodvibes upgrade");
|
|
@@ -446,7 +511,7 @@ function registerUpgradeCommand(program2) {
|
|
|
446
511
|
const templateDir = resolveTemplatesDir();
|
|
447
512
|
const projectType = detectProjectType(cwd);
|
|
448
513
|
const installedVersion = await detectInstalledVersion(cwd);
|
|
449
|
-
const bundledVersion =
|
|
514
|
+
const bundledVersion = getInstalledVersion();
|
|
450
515
|
if (installedVersion && bundledVersion && versionGte(installedVersion, bundledVersion)) {
|
|
451
516
|
outro2(`Already up to date (v${installedVersion})`);
|
|
452
517
|
return;
|
|
@@ -473,6 +538,90 @@ function registerUpgradeCommand(program2) {
|
|
|
473
538
|
});
|
|
474
539
|
}
|
|
475
540
|
|
|
541
|
+
// src/commands/doctor.ts
|
|
542
|
+
import { note as note3, outro as outro3 } from "@clack/prompts";
|
|
543
|
+
import { existsSync as existsSync4, readFileSync } from "fs";
|
|
544
|
+
import { join as join4 } from "path";
|
|
545
|
+
import { execa as execa5 } from "execa";
|
|
546
|
+
var SENTINEL_START2 = "<!-- goodvibes:start -->";
|
|
547
|
+
var SENTINEL_END2 = "<!-- goodvibes:end -->";
|
|
548
|
+
async function checkHeadroom() {
|
|
549
|
+
try {
|
|
550
|
+
await execa5("headroom", ["--version"]);
|
|
551
|
+
return { label: "headroom on PATH", pass: true };
|
|
552
|
+
} catch (e) {
|
|
553
|
+
if (e.code === "ENOENT") {
|
|
554
|
+
return {
|
|
555
|
+
label: "headroom on PATH",
|
|
556
|
+
pass: false,
|
|
557
|
+
remedy: 'Run: uv tool install "headroom-ai[all]" (or re-run goodvibes init)'
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
throw e;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
async function checkGit() {
|
|
564
|
+
const keys = ["user.name", "user.email"];
|
|
565
|
+
const results = [];
|
|
566
|
+
for (const key of keys) {
|
|
567
|
+
try {
|
|
568
|
+
const { stdout } = await execa5("git", ["config", key]);
|
|
569
|
+
results.push({
|
|
570
|
+
label: `git ${key}`,
|
|
571
|
+
pass: stdout.trim().length > 0,
|
|
572
|
+
remedy: stdout.trim().length > 0 ? void 0 : `Run: git config --global ${key} "Your Value"`
|
|
573
|
+
});
|
|
574
|
+
} catch {
|
|
575
|
+
results.push({
|
|
576
|
+
label: `git ${key}`,
|
|
577
|
+
pass: false,
|
|
578
|
+
remedy: `Run: git config --global ${key} "Your Value"`
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return results;
|
|
583
|
+
}
|
|
584
|
+
function checkClaudeMd(cwd) {
|
|
585
|
+
const present = existsSync4(join4(cwd, "CLAUDE.md"));
|
|
586
|
+
return {
|
|
587
|
+
label: "CLAUDE.md present",
|
|
588
|
+
pass: present,
|
|
589
|
+
remedy: present ? void 0 : "Run: goodvibes init"
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
function checkSentinel(cwd) {
|
|
593
|
+
const path = join4(cwd, "CLAUDE.md");
|
|
594
|
+
if (!existsSync4(path)) {
|
|
595
|
+
return { label: "goodvibes sentinel block", pass: false, remedy: "Run: goodvibes init" };
|
|
596
|
+
}
|
|
597
|
+
const content = readFileSync(path, "utf-8");
|
|
598
|
+
const ok = content.includes(SENTINEL_START2) && content.includes(SENTINEL_END2);
|
|
599
|
+
return {
|
|
600
|
+
label: "goodvibes sentinel block",
|
|
601
|
+
pass: ok,
|
|
602
|
+
remedy: ok ? void 0 : "Run: goodvibes init (will merge sentinel block)"
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
function registerDoctorCommand(program2) {
|
|
606
|
+
program2.command("doctor").description("Check goodvibes setup is complete").action(async () => {
|
|
607
|
+
const cwd = process.cwd();
|
|
608
|
+
const headroomResult = await checkHeadroom();
|
|
609
|
+
const gitResults = await checkGit();
|
|
610
|
+
const claudeMdResult = checkClaudeMd(cwd);
|
|
611
|
+
const sentinelResult = checkSentinel(cwd);
|
|
612
|
+
const all = [headroomResult, ...gitResults, claudeMdResult, sentinelResult];
|
|
613
|
+
const lines = all.map((r) => `${r.pass ? "\u2713" : "\u2717"} ${r.label}`);
|
|
614
|
+
note3(lines.join("\n"), "goodvibes doctor");
|
|
615
|
+
const failures = all.filter((r) => !r.pass);
|
|
616
|
+
if (failures.length > 0) {
|
|
617
|
+
const remediation = failures.filter((r) => r.remedy).map((r) => r.remedy).join("\n");
|
|
618
|
+
note3(remediation, "How to fix");
|
|
619
|
+
process.exit(1);
|
|
620
|
+
}
|
|
621
|
+
outro3("All checks passed.");
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
|
|
476
625
|
// src/index.ts
|
|
477
626
|
var [major] = process.version.replace("v", "").split(".").map(Number);
|
|
478
627
|
if (major < 20) {
|
|
@@ -484,8 +633,11 @@ Install the latest LTS from https://nodejs.org
|
|
|
484
633
|
);
|
|
485
634
|
process.exit(1);
|
|
486
635
|
}
|
|
636
|
+
var _require2 = createRequire2(import.meta.url);
|
|
637
|
+
var _pkg = _require2("../package.json");
|
|
487
638
|
var program = new Command();
|
|
488
|
-
program.name("goodvibes").version(
|
|
639
|
+
program.name("goodvibes").version(_pkg.version).description("One-command bootstrap for vibe coding projects");
|
|
489
640
|
registerInitCommand(program);
|
|
490
641
|
registerUpgradeCommand(program);
|
|
642
|
+
registerDoctorCommand(program);
|
|
491
643
|
await program.parseAsync(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jgiox/goodvibes",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "One-command bootstrap for vibe coding projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,7 +24,10 @@
|
|
|
24
24
|
"claude",
|
|
25
25
|
"llm",
|
|
26
26
|
"starter-kit",
|
|
27
|
-
"cli"
|
|
27
|
+
"cli",
|
|
28
|
+
"ai-coding",
|
|
29
|
+
"claude-code",
|
|
30
|
+
"copilot"
|
|
28
31
|
],
|
|
29
32
|
"publishConfig": {
|
|
30
33
|
"access": "public"
|
|
@@ -37,7 +40,7 @@
|
|
|
37
40
|
"test:watch": "vitest"
|
|
38
41
|
},
|
|
39
42
|
"dependencies": {
|
|
40
|
-
"commander": "^
|
|
43
|
+
"commander": "^15",
|
|
41
44
|
"@clack/prompts": "^1",
|
|
42
45
|
"fs-extra": "^11",
|
|
43
46
|
"execa": "^9"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Engineering Rules — goodvibes
|
|
2
|
+
|
|
3
|
+
### Think before coding
|
|
4
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
5
|
+
|
|
6
|
+
### Simplicity first
|
|
7
|
+
Stop at the first rung that holds:
|
|
8
|
+
|
|
9
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
10
|
+
2. Already in this codebase? Reuse it.
|
|
11
|
+
3. Stdlib does it? Use it.
|
|
12
|
+
4. Native platform feature covers it? Use it.
|
|
13
|
+
5. Already-installed dependency solves it? Use it.
|
|
14
|
+
6. Can it be one line? One line.
|
|
15
|
+
7. Only then: the minimum code that works.
|
|
16
|
+
|
|
17
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
18
|
+
|
|
19
|
+
### Surgical changes
|
|
20
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
21
|
+
|
|
22
|
+
### Fail loud
|
|
23
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege.
|
|
27
|
+
|
|
28
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Engineering Rules for this project (goodvibes).
|
|
2
|
+
|
|
3
|
+
Think before coding. State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
4
|
+
|
|
5
|
+
Simplicity first. Stop at the first option that works: Does this need to exist at all? Already in the codebase? Use it. Stdlib covers it? Use it. Can it be one line? One line. Only then write new code. No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
6
|
+
|
|
7
|
+
Surgical changes. Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
8
|
+
|
|
9
|
+
Fail loud. No empty catch blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable and specific.
|
|
10
|
+
|
|
11
|
+
Security. Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege. Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -17,7 +17,14 @@ explicit on-demand audits.
|
|
|
17
17
|
|
|
18
18
|
## Setup
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
> **Using Cursor, Windsurf, Kiro, Copilot, Antigravity, Amazon Q, Cline, Continue.dev, Devin Desktop, or another IDE?**
|
|
21
|
+
> The minimalism rules are already embedded in your project's IDE rule file
|
|
22
|
+
> (`.cursor/rules/goodvibes.mdc`, `GEMINI.md`, `.windsurfrules`, `.kiro/steering/goodvibes.md`, `AGENTS.md`, `.clinerules/goodvibes.md`, `.amazonq/rules/goodvibes.md`, `.continue/rules/goodvibes.md`, `.devin/rules/goodvibes.md`)
|
|
23
|
+
> and activate automatically — no plugin setup needed. The `/ponytail-review` and
|
|
24
|
+
> `/ponytail-audit` commands below are **Claude Code CLI terminal only** and are not
|
|
25
|
+
> available in other IDEs.
|
|
26
|
+
|
|
27
|
+
Ponytail commands require the ponytail plugin. Install it in **Claude Code CLI terminal**:
|
|
21
28
|
|
|
22
29
|
```
|
|
23
30
|
/plugin marketplace add DietrichGebert/ponytail
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Engineering Rules — goodvibes
|
|
2
|
+
|
|
3
|
+
### Think before coding
|
|
4
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
5
|
+
|
|
6
|
+
### Simplicity first
|
|
7
|
+
Stop at the first rung that holds:
|
|
8
|
+
|
|
9
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
10
|
+
2. Already in this codebase? Reuse it.
|
|
11
|
+
3. Stdlib does it? Use it.
|
|
12
|
+
4. Native platform feature covers it? Use it.
|
|
13
|
+
5. Already-installed dependency solves it? Use it.
|
|
14
|
+
6. Can it be one line? One line.
|
|
15
|
+
7. Only then: the minimum code that works.
|
|
16
|
+
|
|
17
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
18
|
+
|
|
19
|
+
### Surgical changes
|
|
20
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
21
|
+
|
|
22
|
+
### Fail loud
|
|
23
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege.
|
|
27
|
+
|
|
28
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Engineering Rules — goodvibes
|
|
2
|
+
|
|
3
|
+
### Think before coding
|
|
4
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
5
|
+
|
|
6
|
+
### Simplicity first
|
|
7
|
+
Stop at the first rung that holds:
|
|
8
|
+
|
|
9
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
10
|
+
2. Already in this codebase? Reuse it.
|
|
11
|
+
3. Stdlib does it? Use it.
|
|
12
|
+
4. Native platform feature covers it? Use it.
|
|
13
|
+
5. Already-installed dependency solves it? Use it.
|
|
14
|
+
6. Can it be one line? One line.
|
|
15
|
+
7. Only then: the minimum code that works.
|
|
16
|
+
|
|
17
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
18
|
+
|
|
19
|
+
### Surgical changes
|
|
20
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
21
|
+
|
|
22
|
+
### Fail loud
|
|
23
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege.
|
|
27
|
+
|
|
28
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: true
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Engineering Rules — goodvibes
|
|
6
|
+
|
|
7
|
+
### Think before coding
|
|
8
|
+
State assumptions explicitly before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
9
|
+
|
|
10
|
+
### Simplicity first
|
|
11
|
+
Stop at the first rung that holds:
|
|
12
|
+
|
|
13
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
14
|
+
2. Already in this codebase? Reuse it.
|
|
15
|
+
3. Stdlib does it? Use it.
|
|
16
|
+
4. Native platform feature covers it? Use it.
|
|
17
|
+
5. Already-installed dependency solves it? Use it.
|
|
18
|
+
6. Can it be one line? One line.
|
|
19
|
+
7. Only then: the minimum code that works.
|
|
20
|
+
|
|
21
|
+
### Surgical changes
|
|
22
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless required. Only remove what your change made unused.
|
|
23
|
+
|
|
24
|
+
### Fail loud
|
|
25
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
26
|
+
|
|
27
|
+
### Security
|
|
28
|
+
Validate input at the boundary. Keep secrets out of code and logs. Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Engineering Rules — goodvibes
|
|
2
|
+
|
|
3
|
+
### Think before coding
|
|
4
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
5
|
+
|
|
6
|
+
### Simplicity first
|
|
7
|
+
Stop at the first rung that holds:
|
|
8
|
+
|
|
9
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
10
|
+
2. Already in this codebase? Reuse it.
|
|
11
|
+
3. Stdlib does it? Use it.
|
|
12
|
+
4. Native platform feature covers it? Use it.
|
|
13
|
+
5. Already-installed dependency solves it? Use it.
|
|
14
|
+
6. Can it be one line? One line.
|
|
15
|
+
7. Only then: the minimum code that works.
|
|
16
|
+
|
|
17
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
18
|
+
|
|
19
|
+
### Surgical changes
|
|
20
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
21
|
+
|
|
22
|
+
### Fail loud
|
|
23
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege.
|
|
27
|
+
|
|
28
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Engineering Rules — goodvibes
|
|
2
|
+
|
|
3
|
+
### Think before coding
|
|
4
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
5
|
+
|
|
6
|
+
### Simplicity first
|
|
7
|
+
Stop at the first rung that holds:
|
|
8
|
+
|
|
9
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
10
|
+
2. Already in this codebase? Reuse it.
|
|
11
|
+
3. Stdlib does it? Use it.
|
|
12
|
+
4. Native platform feature covers it? Use it.
|
|
13
|
+
5. Already-installed dependency solves it? Use it.
|
|
14
|
+
6. Can it be one line? One line.
|
|
15
|
+
7. Only then: the minimum code that works.
|
|
16
|
+
|
|
17
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
18
|
+
|
|
19
|
+
### Surgical changes
|
|
20
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove imports, variables, or functions that your change made unused.
|
|
21
|
+
|
|
22
|
+
### Fail loud
|
|
23
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable and specific enough to debug.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
Validate input at the boundary. Keep secrets out of code, commits, and logs. Apply least privilege for tokens and permissions.
|
|
27
|
+
|
|
28
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets, unsafe dependency additions.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: always
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Engineering Rules — goodvibes
|
|
6
|
+
|
|
7
|
+
### Think before coding
|
|
8
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
9
|
+
|
|
10
|
+
### Simplicity first
|
|
11
|
+
Stop at the first rung that holds:
|
|
12
|
+
|
|
13
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
14
|
+
2. Already in this codebase? Reuse it.
|
|
15
|
+
3. Stdlib does it? Use it.
|
|
16
|
+
4. Native platform feature covers it? Use it.
|
|
17
|
+
5. Already-installed dependency solves it? Use it.
|
|
18
|
+
6. Can it be one line? One line.
|
|
19
|
+
7. Only then: the minimum code that works.
|
|
20
|
+
|
|
21
|
+
### Surgical changes
|
|
22
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless required. Only remove what your change made unused.
|
|
23
|
+
|
|
24
|
+
### Fail loud
|
|
25
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
26
|
+
|
|
27
|
+
### Security
|
|
28
|
+
Validate input at the boundary. Keep secrets out of code and logs. Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Engineering Rules — goodvibes
|
|
2
|
+
|
|
3
|
+
### Think before coding
|
|
4
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
5
|
+
|
|
6
|
+
### Simplicity first
|
|
7
|
+
Stop at the first rung that holds:
|
|
8
|
+
|
|
9
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
10
|
+
2. Already in this codebase? Reuse it.
|
|
11
|
+
3. Stdlib does it? Use it.
|
|
12
|
+
4. Native platform feature covers it? Use it.
|
|
13
|
+
5. Already-installed dependency solves it? Use it.
|
|
14
|
+
6. Can it be one line? One line.
|
|
15
|
+
7. Only then: the minimum code that works.
|
|
16
|
+
|
|
17
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
18
|
+
|
|
19
|
+
### Surgical changes
|
|
20
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
21
|
+
|
|
22
|
+
### Fail loud
|
|
23
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege.
|
|
27
|
+
|
|
28
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Engineering Rules — goodvibes
|
|
2
|
+
|
|
3
|
+
### Think before coding
|
|
4
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
5
|
+
|
|
6
|
+
### Simplicity first
|
|
7
|
+
Stop at the first rung that holds:
|
|
8
|
+
|
|
9
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
10
|
+
2. Already in this codebase? Reuse it.
|
|
11
|
+
3. Stdlib does it? Use it.
|
|
12
|
+
4. Native platform feature covers it? Use it.
|
|
13
|
+
5. Already-installed dependency solves it? Use it.
|
|
14
|
+
6. Can it be one line? One line.
|
|
15
|
+
7. Only then: the minimum code that works.
|
|
16
|
+
|
|
17
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
18
|
+
|
|
19
|
+
### Surgical changes
|
|
20
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
21
|
+
|
|
22
|
+
### Fail loud
|
|
23
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege.
|
|
27
|
+
|
|
28
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
package/templates/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# CLAUDE.md
|
|
2
2
|
|
|
3
3
|
<!-- goodvibes:start -->
|
|
4
|
-
# goodvibes: v1.
|
|
4
|
+
# goodvibes: v1.6.1
|
|
5
5
|
|
|
6
6
|
## Engineering Rules
|
|
7
7
|
|
|
@@ -53,6 +53,13 @@ Rules: do not rewrite history. Additive entries only. Keep it short, factual, an
|
|
|
53
53
|
**Push to GitHub after every completed task or end of session.**
|
|
54
54
|
A commit that only exists locally is one machine failure away from being lost. Run `git push origin <branch>` after each commit, or at minimum before stopping for the day. Never leave completed work unpushed for more than one session.
|
|
55
55
|
|
|
56
|
+
### Tools and environment
|
|
57
|
+
**IDE plugin commands are surface-specific.**
|
|
58
|
+
A slash command or plugin install that works in Claude Code terminal will not work in the
|
|
59
|
+
VS Code extension, Cursor, Windsurf, Kiro, or any other IDE. Before referencing a tool
|
|
60
|
+
command in shared docs, prompts, or instructions, confirm which surface it runs on. If it
|
|
61
|
+
only works in one place, say so explicitly — do not leave users to discover it silently fails.
|
|
62
|
+
|
|
56
63
|
## Ponytail — Minimalism Ruleset
|
|
57
64
|
|
|
58
65
|
You are a lazy senior developer. Lazy means efficient, not careless. You have
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Engineering Rules — goodvibes
|
|
2
|
+
|
|
3
|
+
### Think before coding
|
|
4
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
5
|
+
|
|
6
|
+
### Simplicity first
|
|
7
|
+
Stop at the first rung that holds:
|
|
8
|
+
|
|
9
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
10
|
+
2. Already in this codebase? Reuse it.
|
|
11
|
+
3. Stdlib does it? Use it.
|
|
12
|
+
4. Native platform feature covers it? Use it.
|
|
13
|
+
5. Already-installed dependency solves it? Use it.
|
|
14
|
+
6. Can it be one line? One line.
|
|
15
|
+
7. Only then: the minimum code that works.
|
|
16
|
+
|
|
17
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
18
|
+
|
|
19
|
+
### Surgical changes
|
|
20
|
+
Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
21
|
+
|
|
22
|
+
### Fail loud
|
|
23
|
+
No empty `catch` blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege.
|
|
27
|
+
|
|
28
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Getting started with goodvibes
|
|
2
|
+
|
|
3
|
+
You ran `goodvibes init`. Here is what happens next.
|
|
4
|
+
|
|
5
|
+
## What was set up
|
|
6
|
+
|
|
7
|
+
goodvibes wrote several files into your project: `CLAUDE.md` with engineering rules and the ponytail minimalism ruleset, AI rule files for your coding tool (Cursor, Windsurf, Kiro, GitHub Copilot, and others), CI workflows for automated quality checks, and docs templates including this one. Everything runs automatically — no configuration needed.
|
|
8
|
+
|
|
9
|
+
## Your first change
|
|
10
|
+
|
|
11
|
+
1. **Open your project in your AI coding tool.** Cursor, Windsurf, Kiro, and GitHub Copilot all pick up the goodvibes rules automatically. The AI will follow minimal-code and fail-loud principles from the first message.
|
|
12
|
+
2. **Tell the AI what you want to build.** Describe the feature in plain language — the rules guide the AI to keep code simple and surgical.
|
|
13
|
+
3. **Review the diff before you commit.** Check that the AI only changed what you asked. The rules encourage narrow diffs — if the change looks too large, ask the AI to trim it.
|
|
14
|
+
4. **Run `git add . && git commit -m "feat: your change here"`.** This saves a checkpoint in your project history so you can always go back.
|
|
15
|
+
5. **Run `git push`.** This sends your work to GitHub, where it is safe even if your machine breaks.
|
|
16
|
+
|
|
17
|
+
## Check your setup
|
|
18
|
+
|
|
19
|
+
Run `goodvibes doctor` to verify everything is working. It checks that headroom is installed, your git identity is configured, and the goodvibes rules are in place.
|
|
20
|
+
|
|
21
|
+
## Useful commands
|
|
22
|
+
|
|
23
|
+
| Command | What it does |
|
|
24
|
+
|---------|--------------|
|
|
25
|
+
| `goodvibes update` | Re-sync goodvibes files to the latest version |
|
|
26
|
+
| `goodvibes doctor` | Check that headroom, git, and rules are all working |
|
|
27
|
+
| `goodvibes upgrade --dry-run` | Preview what `goodvibes update` would change |
|
|
28
|
+
|
|
29
|
+
## What is headroom?
|
|
30
|
+
|
|
31
|
+
headroom compresses the AI's memory of your project so you spend fewer tokens per session. It runs automatically in the background when Claude Code is active — you do not need to invoke it manually.
|
|
@@ -93,3 +93,21 @@ A maintainer will look at your PR and either approve it, request changes, or ask
|
|
|
93
93
|
---
|
|
94
94
|
|
|
95
95
|
That is the full loop: clone → branch → commit → push → pull request. Every contribution, large or small, follows this same pattern.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Troubleshooting IDE rules
|
|
100
|
+
|
|
101
|
+
**Cursor — rules appear inactive in agent mode**
|
|
102
|
+
|
|
103
|
+
Cursor 3.0.x has a known bug where `alwaysApply: true` rules are silently downgraded in agent mode. If your goodvibes rules seem to have no effect in Cursor:
|
|
104
|
+
|
|
105
|
+
1. Open Settings (Cmd/Ctrl + ,) and search for "Rules".
|
|
106
|
+
2. Verify that `goodvibes` is listed under "Always Active" rules.
|
|
107
|
+
3. If it appears as "Requestable" instead, toggle it to "Always Active" manually.
|
|
108
|
+
|
|
109
|
+
This is an upstream Cursor issue — the `goodvibes.mdc` file format is correct.
|
|
110
|
+
|
|
111
|
+
**Using multiple AI coding tools?**
|
|
112
|
+
|
|
113
|
+
`goodvibes init` writes an `AGENTS.md` file at your project root. This is a cross-tool standard natively read by Zed, Aider, JetBrains Junie (IntelliJ, PyCharm, WebStorm), Jules, Amp, Codex CLI, and many others — without any extra setup. If you switch to a new AI coding tool, check whether it reads `AGENTS.md` before creating a separate rules file.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Base44 — goodvibes setup
|
|
2
|
+
|
|
3
|
+
Base44 does not read files from your project. Instead, you paste your rules into the AI controls panel, and Base44 applies them to every AI interaction in that project.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. Go to [base44.com](https://base44.com) and sign in.
|
|
8
|
+
2. Open your project.
|
|
9
|
+
3. Find the **AI controls** panel — it is usually in the top-right corner or under project Settings.
|
|
10
|
+
4. Click **Custom Instructions**.
|
|
11
|
+
5. Paste the text below into the box.
|
|
12
|
+
6. Click **Save**.
|
|
13
|
+
|
|
14
|
+
That is it. From now on, every AI action in this project follows the goodvibes engineering rules.
|
|
15
|
+
|
|
16
|
+
> If the steps above do not match what you see, look for **Custom Instructions** or **AI controls** in the project settings. The UI may change — the paste text stays the same.
|
|
17
|
+
|
|
18
|
+
> **Base44 Skills** is a separate feature for saving reusable instruction sets. goodvibes does not require it — pasting into Custom Instructions is enough.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Paste this text
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Engineering Rules — goodvibes
|
|
26
|
+
|
|
27
|
+
Think before coding. State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
28
|
+
|
|
29
|
+
Simplicity first. Stop at the first option that works: Does this need to exist at all? Already in the codebase? Use it. Stdlib covers it? Use it. Can it be one line? One line. Only then write new code. No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
30
|
+
|
|
31
|
+
Surgical changes. Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
32
|
+
|
|
33
|
+
Fail loud. No empty catch blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable and specific.
|
|
34
|
+
|
|
35
|
+
Security. Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege. Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Last verified: 2026-07-01
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Bolt.new — goodvibes setup
|
|
2
|
+
|
|
3
|
+
Bolt.new does not read project files for AI rules. You activate ponytail discipline by pasting the rules into the chat as a one-time instruction.
|
|
4
|
+
|
|
5
|
+
## One-time setup
|
|
6
|
+
|
|
7
|
+
1. Open your Bolt.new project.
|
|
8
|
+
2. In the chat, paste: "Please follow these engineering rules for all code you write:" then copy the text from `CLAUDE.md` between `<!-- goodvibes:start -->` and `<!-- goodvibes:end -->`.
|
|
9
|
+
3. Bolt.new will acknowledge and apply the rules for the rest of the session.
|
|
10
|
+
4. Repeat this at the start of each new session, or save it as a pinned message if Bolt.new supports it.
|
|
11
|
+
|
|
12
|
+
## Ponytail on Bolt.new
|
|
13
|
+
|
|
14
|
+
Once the rules are in the chat context, Bolt.new follows the ponytail minimalism rules: minimal code, surgical changes, fail loud. The AI will tell you when it is skipping something that is not needed yet.
|
|
15
|
+
|
|
16
|
+
## Headroom
|
|
17
|
+
|
|
18
|
+
Headroom is not applicable inside Bolt.new — context is managed by the Bolt.new platform itself.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Last verified: 2026-07-01
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# ChatGPT Projects — goodvibes setup
|
|
2
|
+
|
|
3
|
+
ChatGPT does not read files from your project. Instead, you paste your rules directly into the project's custom instructions, and ChatGPT applies them to every conversation in that project.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. Go to [chatgpt.com](https://chatgpt.com) and sign in.
|
|
8
|
+
2. Click **Projects** in the left sidebar. Create a new project or open an existing one.
|
|
9
|
+
3. Click the project name at the top of the page. A panel opens on the right.
|
|
10
|
+
4. Click **Project Instructions**.
|
|
11
|
+
5. Paste the text below into the box.
|
|
12
|
+
6. Click **Save**.
|
|
13
|
+
|
|
14
|
+
That is it. From now on, every conversation in this project follows the goodvibes engineering rules.
|
|
15
|
+
|
|
16
|
+
> If the steps above do not match what you see, look for **Project Instructions** or **Custom Instructions** in the project settings panel. The UI may change — the paste text stays the same.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Paste this text
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Engineering Rules — goodvibes
|
|
24
|
+
|
|
25
|
+
Think before coding. State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
26
|
+
|
|
27
|
+
Simplicity first. Stop at the first option that works: Does this need to exist at all? Already in the codebase? Use it. Stdlib covers it? Use it. Can it be one line? One line. Only then write new code. No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
28
|
+
|
|
29
|
+
Surgical changes. Keep diffs narrow. No opportunistic reformats. No renames unless the task requires it. Only remove what your change made unused.
|
|
30
|
+
|
|
31
|
+
Fail loud. No empty catch blocks. No silent retries. No returning fake success on real failure. Error messages must be actionable and specific.
|
|
32
|
+
|
|
33
|
+
Security. Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege. Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Last verified: 2026-07-01
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Cursor — goodvibes setup
|
|
2
|
+
|
|
3
|
+
goodvibes init wrote `.cursor/rules/goodvibes.mdc` into your project. This file activates the ponytail minimalism rules automatically when you open the project in Cursor.
|
|
4
|
+
|
|
5
|
+
## Ponytail is already active
|
|
6
|
+
|
|
7
|
+
The rules enforce simplicity-first coding, fail-loud error handling, and surgical changes — no file you did not touch, no code you did not need. You do not need to paste anything. The rules are in `.cursor/rules/goodvibes.mdc` and Cursor loads them for every AI chat in this project.
|
|
8
|
+
|
|
9
|
+
## Verify activation
|
|
10
|
+
|
|
11
|
+
Open Cursor. In the AI chat, ask: "What are your active rules?" You should see a reference to goodvibes or ponytail in the response.
|
|
12
|
+
|
|
13
|
+
## If you use .cursorrules (legacy)
|
|
14
|
+
|
|
15
|
+
If your project has a `.cursorrules` file from before goodvibes, the `.cursor/rules/goodvibes.mdc` file is independent. Both will apply. You may want to merge them to avoid duplication.
|
|
16
|
+
|
|
17
|
+
## Headroom (context compression)
|
|
18
|
+
|
|
19
|
+
Cursor does not use Claude Code's MCP protocol. If you want context compression, install headroom separately and use it via its CLI. See [headroom docs](https://headroom-docs.vercel.app/).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Last verified: 2026-07-01
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Kiro — goodvibes setup
|
|
2
|
+
|
|
3
|
+
goodvibes init wrote `.kiro/steering/goodvibes.md` into your project. Kiro applies steering files automatically to all AI interactions in the project.
|
|
4
|
+
|
|
5
|
+
## Ponytail is already active
|
|
6
|
+
|
|
7
|
+
The ponytail rules in `.kiro/steering/goodvibes.md` enforce simplicity-first coding, fail-loud error handling, and surgical changes. You do not need to paste anything or configure anything — the steering file is active as soon as you open the project in Kiro.
|
|
8
|
+
|
|
9
|
+
## Verify activation
|
|
10
|
+
|
|
11
|
+
Open Kiro and check the steering files panel in your project settings. You should see `goodvibes.md` listed as an always-on steering file.
|
|
12
|
+
|
|
13
|
+
## Headroom (context compression)
|
|
14
|
+
|
|
15
|
+
Kiro does not use Claude Code's MCP protocol. If you want context compression, install headroom separately and use it via its CLI. See [headroom docs](https://headroom-docs.vercel.app/).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Last verified: 2026-07-01
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Replit Agent — goodvibes setup
|
|
2
|
+
|
|
3
|
+
Replit Agent does not read files from your project automatically. Instead, you provide the rules as a system prompt for the Agent.
|
|
4
|
+
|
|
5
|
+
## One-time setup
|
|
6
|
+
|
|
7
|
+
1. Open your Repl.
|
|
8
|
+
2. Find **System prompt** or **AI instructions** in the Agent settings panel.
|
|
9
|
+
3. Copy the text from `CLAUDE.md` — specifically the section between `<!-- goodvibes:start -->` and `<!-- goodvibes:end -->`.
|
|
10
|
+
4. Paste into the system prompt field and click **Save**.
|
|
11
|
+
|
|
12
|
+
That is it. Replit Agent will follow the goodvibes rules for every task in this project.
|
|
13
|
+
|
|
14
|
+
> If you do not see a system prompt field, look for **Agent instructions** or **Custom rules** in the project settings.
|
|
15
|
+
|
|
16
|
+
## Ponytail on Replit
|
|
17
|
+
|
|
18
|
+
Once the system prompt is set, Replit Agent follows the ponytail rules for every task: minimal code, no over-engineering, and explicit error handling. The AI will tell you if it is skipping something because it is not needed yet.
|
|
19
|
+
|
|
20
|
+
## Headroom
|
|
21
|
+
|
|
22
|
+
Replit manages its own context. Headroom is not applicable inside Replit — skip the headroom install step if you are Replit-only.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Last verified: 2026-07-01
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Windsurf — goodvibes setup
|
|
2
|
+
|
|
3
|
+
goodvibes init wrote `.windsurfrules` into your project. Windsurf reads this file automatically and applies the goodvibes engineering rules to every AI interaction.
|
|
4
|
+
|
|
5
|
+
## Ponytail is already active
|
|
6
|
+
|
|
7
|
+
The rules in `.windsurfrules` enforce simplicity-first coding, fail-loud error handling, and surgical changes. You do not need to paste anything — Windsurf picks up the file on its own.
|
|
8
|
+
|
|
9
|
+
## Verify activation
|
|
10
|
+
|
|
11
|
+
Open Windsurf. In the Cascade AI panel, ask: "What are your active rules?" You should see a reference to goodvibes or ponytail in the response.
|
|
12
|
+
|
|
13
|
+
## Headroom (context compression)
|
|
14
|
+
|
|
15
|
+
Windsurf does not use Claude Code's MCP protocol. If you want context compression, install headroom separately and use it via its CLI. See [headroom docs](https://headroom-docs.vercel.app/).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Last verified: 2026-07-01
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Engineering Rules — goodvibes
|
|
2
|
+
<!-- Replit Agent may regenerate this file. Commit it to git to preserve your edits. -->
|
|
3
|
+
|
|
4
|
+
## Project Overview
|
|
5
|
+
This project uses goodvibes engineering rules. Apply them to every task.
|
|
6
|
+
|
|
7
|
+
## Coding Style
|
|
8
|
+
State assumptions before implementing. Stop if an assumption is security-sensitive, schema-sensitive, or has multiple materially different interpretations.
|
|
9
|
+
|
|
10
|
+
## Simplicity First
|
|
11
|
+
Stop at the first rung that holds:
|
|
12
|
+
|
|
13
|
+
1. Does this need to exist at all? Speculative need → skip it. (YAGNI)
|
|
14
|
+
2. Already in this codebase? Reuse it.
|
|
15
|
+
3. Stdlib does it? Use it.
|
|
16
|
+
4. Native platform feature covers it? Use it.
|
|
17
|
+
5. Already-installed dependency solves it? Use it.
|
|
18
|
+
6. Can it be one line? One line.
|
|
19
|
+
7. Only then: the minimum code that works.
|
|
20
|
+
|
|
21
|
+
No unrequested abstractions. No boilerplate for later. Deletion over addition.
|
|
22
|
+
|
|
23
|
+
## Surgical Changes
|
|
24
|
+
Keep diffs narrow. No opportunistic reformats. Only remove what your change made unused.
|
|
25
|
+
|
|
26
|
+
## Fail Loud
|
|
27
|
+
No empty catch blocks. No silent retries. No fake success on real failure. Error messages must be actionable.
|
|
28
|
+
|
|
29
|
+
## Security
|
|
30
|
+
Validate input at the boundary. Keep secrets out of code and logs. Apply least privilege.
|
|
31
|
+
|
|
32
|
+
Flag immediately: SQL injection, XSS, command injection, path traversal, broken auth, leaked secrets.
|