Sign In

dev-like

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dev-like - npm Package Compare versions

Comparing version
0.1.1
to
0.2.0
+26
registry/every/ski...op-like-every/agents/every-developer.md
---
name: every-developer
description: >-
Reviews diffs and plans against Every's engineering principles. Use for code
review or pairing in Every's voice.
---
# Every-developer
Critique diffs and plans against the principles in [../SKILL.md](../SKILL.md) — read it
first, every time.
## How to review
- Check the diff/plan against each numbered principle in ../SKILL.md's Principles section.
- When flagging an issue, cite the principle number it violates or should apply, e.g.
"Principle 3: this change skips the simplify step."
- Respect the Tensions section in ../SKILL.md — don't overclaim beyond what it admits.
- Never invent claims about Every beyond what's cited in ../SKILL.md and its
references/. If you're unsure whether something reflects Every's practice, say so
instead of asserting it.
## Output
Give concrete, principle-tied feedback — not vibes. If nothing violates a principle, say
so plainly rather than manufacturing a critique.
# Sources — Every
Consent tier: self-published · profiled 2026-07-11.
- https://github.com/EveryInc/compound-engineering-plugin — fetched 2026-07-11 · tier: self-published, CEP - their culture, already codified
- https://every.to/chain-of-thought/compound-engineering-how-every-codes-with-agents — fetched 2026-07-11 · tier: stated, Dan Shipper canonical essay
- https://every.to/source-code/my-ai-had-already-fixed-the-code-before-i-saw-it — fetched 2026-07-11 · tier: stated, Kieran Klaassen origin story
- https://every.to/guides/compound-engineering — fetched 2026-07-11 · tier: stated, verified: 80/20 split, four-step core loop, agent-native parity, safety nets
- https://every.to/podcast/transcript-how-two-engineers-ship-like-a-team-of-15-with-ai-agents — fetched 2026-07-11 · tier: stated
- https://sfruby.com/ — fetched 2026-07-11 · tier: stated, Kieran Klaassen SF Ruby keynote: Rails + AI stack for Cora
- https://github.com/EveryInc/compound-engineering-plugin/blob/main/AGENTS.md — fetched 2026-07-11 · tier: self-published, canonical repo instruction file, provenance rules
- https://github.com/EveryInc/compound-engineering-plugin/blob/main/docs/skills/ce-compound.md — fetched 2026-07-11 · tier: self-published, /ce-compound writes docs/solutions/
- https://github.com/EveryInc/compound-engineering-plugin/blob/main/skills/ce-compound-refresh/SKILL.md — fetched 2026-07-11 · tier: self-published, docs/solutions/ discoverability discipline
- https://www.lennysnewsletter.com/p/inside-every-dan-shipper — fetched 2026-07-11 · tier: social, third-party interview; verified 15 people / 5 products / 'virtually zero code'
- https://github.com/kieranklaassen — fetched 2026-07-11 · tier: observed, profile page thin; stack signal better carried by SF Ruby keynote
# Stack — Every
> Profiled as of 2026-07-11 · consent tier: self-published · full bibliography in [sources.md](sources.md).
"Boring Rails": Ruby on Rails + Turbo/Stimulus/ERB + Tailwind; RubyLLM, StepperMotor, Ahoy,
pgvector for the AI layer (Cora)
[[SF Ruby keynote]](https://sfruby.com/). Boring, well-understood building blocks under
aggressive AI leverage.
# Workflow — Every
> Profiled as of 2026-07-11 · consent tier: self-published · full bibliography in [sources.md](sources.md).
The CEP plugin ships a six-step loop: **brainstorm → plan → work → simplify → review →
compound** [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Every's own guide
describes the core cycle in four beats — **plan → work → review → compound → repeat** — with
`simplify` being the extra gate the plugin inserts
[[guide]](https://every.to/guides/compound-engineering). The compound step (`/ce-compound`)
writes learnings to `docs/solutions/`, which ground the next loop — knowledge accretes in the
repo, not in heads
[[ce-compound]](https://github.com/EveryInc/compound-engineering-plugin/blob/main/docs/skills/ce-compound.md).
Fully autonomous pipeline (`/lfg`): plan → work → review → PR → watch CI until green. Reviewer
personas live as skill-local prompt assets (29 skills, 0 standalone agents post-migration)
[[CEP]](https://github.com/EveryInc/compound-engineering-plugin).
---
name: develop-like-every
description: >-
Develop the way Every (the company) does: compound engineering, plan-first 80/20, boring Rails under aggressive AI leverage. Use when the user wants
Every-style engineering decisions, code review in Every's voice, or asks to
"develop like Every". Profiled 2026-07-11 from public sources.
license: MIT
metadata:
author: marcusrbrown
generator: dev-like
profiled: "2026-07-11"
consent-tier: "self-published"
source: https://github.com/marcusrbrown/dev-like/tree/main/registry/every
---
# Develop like Every
> Profiled as of 2026-07-11 · consent tier: self-published · full bibliography in [references/sources.md](references/sources.md). Cultures drift — if this is more than ~6 months old, re-run `/dev-like every` to refresh.
## Core principle
"Each unit of engineering work should make subsequent units easier — not harder"
[[CEP README]](https://github.com/EveryInc/compound-engineering-plugin). Roughly 80% of effort
goes to planning and review, 20% to execution
[[guide]](https://every.to/guides/compound-engineering).
## Principles
1. Plan-first, 80/20 — most effort before code [[guide]](https://every.to/guides/compound-engineering)
2. Compound every unit of work into reusable repo knowledge [[CEP]](https://github.com/EveryInc/compound-engineering-plugin)
3. Simplify as an explicit pipeline step, not an afterthought [[CEP]](https://github.com/EveryInc/compound-engineering-plugin)
4. One person + agents ≈ a team; design workflows for that ratio [[podcast transcript]](https://every.to/podcast/transcript-how-two-engineers-ship-like-a-team-of-15-with-ai-agents)
5. Boring stack, radical process [[SF Ruby keynote]](https://sfruby.com/)
6. Agent-native parity — if a human can run tests, read logs, or open a PR, the agent should be able to as well [[guide]](https://every.to/guides/compound-engineering)
7. Safety nets over gatekeeping — trust comes from tests, automated review, monitoring, and rollback, not line-by-line babysitting [[guide]](https://every.to/guides/compound-engineering)
8. Make institutional knowledge discoverable — solved problems live in `docs/solutions/`, and instruction files must surface that store so future agents find it [[ce-compound-refresh]](https://github.com/EveryInc/compound-engineering-plugin/blob/main/skills/ce-compound-refresh/SKILL.md)
## Workflow
The CEP plugin ships a six-step loop: **brainstorm → plan → work → simplify → review →
compound** [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Every's own guide
describes the core cycle in four beats — **plan → work → review → compound → repeat** — with
`simplify` being the extra gate the plugin inserts
[[guide]](https://every.to/guides/compound-engineering). The compound step (`/ce-compound`)
writes learnings to `docs/solutions/`, which ground the next loop — knowledge accretes in the
repo, not in heads
[[ce-compound]](https://github.com/EveryInc/compound-engineering-plugin/blob/main/docs/skills/ce-compound.md).
Fully autonomous pipeline (`/lfg`): plan → work → review → PR → watch CI until green. Reviewer
personas live as skill-local prompt assets (29 skills, 0 standalone agents post-migration)
[[CEP]](https://github.com/EveryInc/compound-engineering-plugin).
See [references/stack.md](references/stack.md) for the stack and [references/workflow.md](references/workflow.md) for workflow detail.
## Tensions
- CEP's layout migrated twice in ~6 months (agents folded into skills) — mimic the
*principles*, expect the mechanics to drift.
- "Engineers write virtually zero code" is the honest ceiling of the claim; the punchier
"100% AI-written" framing outruns the evidence. Repo history shows human review is the
load-bearing step. Treat the ratio as directional.
Want a reviewer/pair persona in Every's voice? See [agents/every-developer.md](agents/every-developer.md).
#!/usr/bin/env node
// Deterministic skill generator: registry/<slug>/{profile.md,entry.json} + assets templates
// -> develop-like-<slug>/ skill tree. Zero deps by design (mirrors scripts/validate.mjs).
//
// Usage: node scripts/generate-skill.mjs <slug> [--out <dir>] [--check] [--registry <dir>]
import { readFile, mkdir, writeFile } from 'node:fs/promises';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
const ASSETS = join(ROOT, 'skills', 'dev-like', 'assets');
const REQUIRED_SECTIONS = ['Core principle', 'Workflow shape', 'Stack', 'Principles (cited)', 'Tensions'];
function parseArgs(argv) {
const args = { slug: null, out: null, check: false, registry: null };
const rest = [...argv];
while (rest.length) {
const tok = rest.shift();
if (tok === '--out') args.out = rest.shift();
else if (tok === '--check') args.check = true;
else if (tok === '--registry') args.registry = rest.shift();
else if (!args.slug) args.slug = tok;
}
return args;
}
// Split profile.md on `## ` headings into a map of heading text -> trimmed body.
function parseSections(text) {
const sections = {};
const parts = text.split(/^## /m).slice(1); // drop content before first '## '
for (const part of parts) {
const nl = part.indexOf('\n');
const heading = (nl === -1 ? part : part.slice(0, nl)).trim();
const body = (nl === -1 ? '' : part.slice(nl + 1)).trim();
sections[heading] = body;
}
return sections;
}
function render(template, vars) {
let out = template;
for (const [key, value] of Object.entries(vars)) {
out = out.split(`{{${key}}}`).join(value);
}
return out;
}
function withTrailingNewline(text) {
return text.replace(/\n*$/, '\n');
}
function renderSourcesRows(sources) {
return sources
.map((s) => {
const note = s.note ? `, ${s.note}` : '';
return `- ${s.url} — fetched ${s.fetched} · tier: ${s.tier}${note}`;
})
.join('\n');
}
async function loadTemplates() {
const [skill, reference, sourcesTpl, persona] = await Promise.all([
readFile(join(ASSETS, 'skill-template.md'), 'utf8'),
readFile(join(ASSETS, 'reference-template.md'), 'utf8'),
readFile(join(ASSETS, 'sources-template.md'), 'utf8'),
readFile(join(ASSETS, 'persona-template.md'), 'utf8'),
]);
return { skill, reference, sourcesTpl, persona };
}
// Build the in-memory file map for develop-like-<slug>/. Throws with a FAIL-prefixed
// message (caller decides how to report) if profile.md is missing a required section.
export async function renderSkill(slug, registryDir) {
const entry = JSON.parse(await readFile(join(registryDir, slug, 'entry.json'), 'utf8'));
const profileText = await readFile(join(registryDir, slug, 'profile.md'), 'utf8');
const sections = parseSections(profileText);
for (const name of REQUIRED_SECTIONS) {
if (sections[name] === undefined) {
const err = new Error(`FAIL ${slug}: profile.md missing section '${name}'`);
err.isSectionError = true;
throw err;
}
}
const { skill, reference, sourcesTpl, persona } = await loadTemplates();
const vars = {
slug,
name: entry.name,
summary: entry.summary ?? '',
kindLabel: entry.kind === 'person' ? 'the developer' : 'the company',
profiled: entry.updated,
consentTier: entry.consentTier,
corePrinciple: sections['Core principle'],
workflowShape: sections['Workflow shape'],
principlesCited: sections['Principles (cited)'],
tensions: sections['Tensions'],
};
const skillMd = withTrailingNewline(render(skill, vars));
const stackMd = withTrailingNewline(
render(reference, { title: 'Stack', name: vars.name, profiled: vars.profiled, consentTier: vars.consentTier, body: sections['Stack'] }),
);
const workflowMd = withTrailingNewline(
render(reference, { title: 'Workflow', name: vars.name, profiled: vars.profiled, consentTier: vars.consentTier, body: sections['Workflow shape'] }),
);
const sourcesMd = withTrailingNewline(
render(sourcesTpl, { name: vars.name, profiled: vars.profiled, consentTier: vars.consentTier, rows: renderSourcesRows(entry.sources ?? []) }),
);
const personaMd = withTrailingNewline(render(persona, { slug, name: vars.name }));
return {
'SKILL.md': skillMd,
'references/stack.md': stackMd,
'references/workflow.md': workflowMd,
'references/sources.md': sourcesMd,
[`agents/${slug}-developer.md`]: personaMd,
};
}
async function writeFiles(baseDir, files) {
for (const [rel, content] of Object.entries(files)) {
const full = join(baseDir, rel);
await mkdir(dirname(full), { recursive: true });
await writeFile(full, content, 'utf8');
}
}
async function readCommitted(baseDir, files) {
const out = {};
for (const rel of Object.keys(files)) {
out[rel] = await readFile(join(baseDir, rel), 'utf8').catch(() => null);
}
return out;
}
async function main() {
const args = parseArgs(process.argv.slice(2));
if (!args.slug) {
console.error('Usage: node scripts/generate-skill.mjs <slug> [--out <dir>] [--check] [--registry <dir>]');
process.exitCode = 1;
return;
}
const registryDir = args.registry ? args.registry : join(ROOT, 'registry');
const dirName = `develop-like-${args.slug}`;
let files;
try {
files = await renderSkill(args.slug, registryDir);
} catch (err) {
console.error(err.message);
process.exitCode = 1;
return;
}
if (args.check) {
const committedBase = join(registryDir, args.slug, 'skill', dirName);
const committed = await readCommitted(committedBase, files);
const offending = [];
for (const [rel, content] of Object.entries(files)) {
if (committed[rel] === null) offending.push(`${rel} (missing)`);
else if (committed[rel] !== content) offending.push(`${rel} (drift)`);
}
if (offending.length) {
console.error(`FAIL ${args.slug}: generated output does not match committed skill:`);
for (const o of offending) console.error(` ${o}`);
process.exitCode = 1;
return;
}
console.log(`ok ${args.slug}: generated output matches committed skill`);
return;
}
const outRoot = args.out ? args.out : join(registryDir, args.slug, 'skill');
const baseDir = join(outRoot, dirName);
await writeFiles(baseDir, files);
console.log(`Wrote ${baseDir}`);
}
if (process.argv[1] === fileURLToPath(import.meta.url)) {
main();
}
#!/usr/bin/env node
// Deterministic repo validation: skill frontmatter, registry entries, index sync,
// provenance (every profile claim-link resolves to a sources[] URL is v0.2; here: presence).
// Zero deps by design — this doubles as the contributor pre-PR check and the CI gate.
import { readFile, readdir, stat } from 'node:fs/promises';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
const TIERS = ['self-published', 'stated', 'observed', 'social'];
const PERSON_TIERS = ['self-published', 'stated'];
const SLUG_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
let failures = 0;
const fail = (msg) => { failures++; console.error(`FAIL ${msg}`); };
const ok = (msg) => console.log(` ok ${msg}`);
function parseFrontmatter(text) {
const m = text.match(/^---\n([\s\S]*?)\n---/);
if (!m) return null;
// Minimal YAML subset: top-level scalar keys only (enough for name/description checks).
const fm = {};
let currentKey = null;
for (const line of m[1].split('\n')) {
const kv = line.match(/^([A-Za-z-]+):\s*(.*)$/);
if (kv) {
currentKey = kv[1];
fm[currentKey] = kv[2].replace(/^>-?\s*$/, '');
} else if (currentKey && /^\s+\S/.test(line)) {
fm[currentKey] = ((fm[currentKey] ?? '') + ' ' + line.trim()).trim();
}
}
return fm;
}
async function validateSkills() {
const skillsDir = join(ROOT, 'skills');
for (const name of await readdir(skillsDir)) {
const dir = join(skillsDir, name);
if (!(await stat(dir)).isDirectory()) continue;
const path = join(dir, 'SKILL.md');
const text = await readFile(path, 'utf8').catch(() => null);
if (text === null) { fail(`${name}: missing SKILL.md`); continue; }
const fm = parseFrontmatter(text);
if (!fm) { fail(`${name}: no YAML frontmatter`); continue; }
if (fm.name !== name) fail(`${name}: frontmatter name '${fm.name}' != directory name`);
if (!fm.description || fm.description.length < 20) fail(`${name}: description missing/too short`);
if (fm.description && fm.description.length > 1024) fail(`${name}: description > 1024 chars`);
if (!SLUG_RE.test(fm.name ?? '')) fail(`${name}: name violates spec pattern`);
const body = text.replace(/^---\n[\s\S]*?\n---/, '');
if (body.split('\n').length > 500) fail(`${name}: SKILL.md > 500 lines (spec guidance)`);
ok(`skill ${name}`);
}
}
async function validateRegistry() {
const regDir = join(ROOT, 'registry');
const index = JSON.parse(await readFile(join(regDir, 'index.json'), 'utf8'));
const dirs = [];
for (const name of await readdir(regDir)) {
const p = join(regDir, name);
if ((await stat(p)).isDirectory() && name !== 'schema') dirs.push(name);
}
for (const slug of dirs) {
const entryPath = join(regDir, slug, 'entry.json');
const entry = JSON.parse(await readFile(entryPath, 'utf8').catch(() => 'null'));
if (!entry) { fail(`${slug}: missing entry.json`); continue; }
if (entry.slug !== slug) fail(`${slug}: entry.slug mismatch`);
if (!SLUG_RE.test(slug)) fail(`${slug}: invalid slug`);
if (!['org', 'person'].includes(entry.kind)) fail(`${slug}: bad kind`);
if (!TIERS.includes(entry.consentTier)) fail(`${slug}: bad consentTier`);
if (entry.kind === 'person' && !PERSON_TIERS.includes(entry.consentTier))
fail(`${slug}: persons require consentTier stated or better`);
if (!DATE_RE.test(entry.updated ?? '')) fail(`${slug}: bad updated date`);
if (!Array.isArray(entry.sources) || entry.sources.length === 0)
fail(`${slug}: sources[] required`);
for (const s of entry.sources ?? []) {
if (!s.url?.startsWith('http')) fail(`${slug}: bad source url ${s.url}`);
if (!DATE_RE.test(s.fetched ?? '')) fail(`${slug}: source missing fetched date`);
if (!TIERS.includes(s.tier)) fail(`${slug}: bad source tier`);
}
const profile = await readFile(join(regDir, slug, 'profile.md'), 'utf8').catch(() => null);
if (!profile) fail(`${slug}: missing profile.md`);
else if (!/\[\[?.+?\]?\]\(https?:\/\//.test(profile)) fail(`${slug}: profile.md has no source links`);
if (!index.entries[slug]) fail(`${slug}: not in index.json`);
else {
const ie = index.entries[slug];
if (ie.consentTier !== entry.consentTier) fail(`${slug}: index/entry consentTier drift`);
if (ie.updated !== entry.updated) fail(`${slug}: index/entry updated drift`);
}
ok(`registry ${slug}`);
}
for (const slug of Object.keys(index.entries)) {
if (!dirs.includes(slug)) fail(`index.json references missing dir registry/${slug}/`);
}
}
export async function validate() {
await validateSkills();
await validateRegistry();
if (failures) console.error(`\n${failures} failure(s)`);
else console.log('\nAll checks passed.');
return failures === 0;
}
if (process.argv[1] === fileURLToPath(import.meta.url)) {
validate().then((passed) => { process.exitCode = passed ? 0 : 1; });
}
---
name: {{slug}}-developer
description: >-
Reviews diffs and plans against {{name}}'s engineering principles. Use for code
review or pairing in {{name}}'s voice.
---
# {{name}}-developer
Critique diffs and plans against the principles in [../SKILL.md](../SKILL.md) — read it
first, every time.
## How to review
- Check the diff/plan against each numbered principle in ../SKILL.md's Principles section.
- When flagging an issue, cite the principle number it violates or should apply, e.g.
"Principle 3: this change skips the simplify step."
- Respect the Tensions section in ../SKILL.md — don't overclaim beyond what it admits.
- Never invent claims about {{name}} beyond what's cited in ../SKILL.md and its
references/. If you're unsure whether something reflects {{name}}'s practice, say so
instead of asserting it.
## Output
Give concrete, principle-tied feedback — not vibes. If nothing violates a principle, say
so plainly rather than manufacturing a critique.
# {{title}} — {{name}}
> Profiled as of {{profiled}} · consent tier: {{consentTier}} · full bibliography in [sources.md](sources.md).
{{body}}
---
name: develop-like-{{slug}}
description: >-
Develop the way {{name}} ({{kindLabel}}) does: {{summary}}. Use when the user wants
{{name}}-style engineering decisions, code review in {{name}}'s voice, or asks to
"develop like {{name}}". Profiled {{profiled}} from public sources.
license: MIT
metadata:
author: marcusrbrown
generator: dev-like
profiled: "{{profiled}}"
consent-tier: "{{consentTier}}"
source: https://github.com/marcusrbrown/dev-like/tree/main/registry/{{slug}}
---
# Develop like {{name}}
> Profiled as of {{profiled}} · consent tier: {{consentTier}} · full bibliography in [references/sources.md](references/sources.md). Cultures drift — if this is more than ~6 months old, re-run `/dev-like {{slug}}` to refresh.
## Core principle
{{corePrinciple}}
## Principles
{{principlesCited}}
## Workflow
{{workflowShape}}
See [references/stack.md](references/stack.md) for the stack and [references/workflow.md](references/workflow.md) for workflow detail.
## Tensions
{{tensions}}
Want a reviewer/pair persona in {{name}}'s voice? See [agents/{{slug}}-developer.md](agents/{{slug}}-developer.md).
# Sources — {{name}}
Consent tier: {{consentTier}} · profiled {{profiled}}.
{{rows}}
+243
-12
#!/usr/bin/env node
// dev-like CLI — thin, deterministic plumbing. The agent skill does the smart work.
//
// v0.1: resolve + install from the registry. No telemetry, no postinstall, no network
// v0.2: resolve + install from the registry. No telemetry, no postinstall, no network
// beyond raw.githubusercontent.com. See DESIGN.md §3.4.
import { parseArgs } from 'node:util';
import { readFile, mkdir, writeFile, readdir, lstat, stat, symlink, realpath, rm, cp } from 'node:fs/promises';
import { join, dirname, relative, sep } from 'node:path';
import { fileURLToPath } from 'node:url';
const RAW = 'https://raw.githubusercontent.com/marcusrbrown/dev-like/main';
const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');

@@ -14,3 +18,4 @@ const HELP = `dev-like — develop like the shops you admire, with receipts.

Usage:
npx dev-like <target> Install develop-like-<target> from the registry
npx dev-like <target> [--dry-run] [--force] [--dir <projectRoot>] [--registry <dir>]
Install develop-like-<target> from the registry
npx dev-like list List registry entries

@@ -20,2 +25,8 @@ npx dev-like validate Validate local registry + skill (contributors/CI)

Options:
--dry-run Show the install plan without writing anything
--force Overwrite an installed skill that has drifted from the registry
--dir <path> Project root to install into (default: cwd)
--registry <path> Use a local registry directory instead of the packaged/remote one
Uncached targets: run /dev-like <target> in your agent instead — live profiling

@@ -30,2 +41,8 @@ needs an LLM. This CLI only installs cached profiles.`;

async function fetchText(path) {
const res = await fetch(`${RAW}/${path}`);
if (!res.ok) throw new Error(`fetch ${path}: ${res.status}`);
return res.text();
}
function resolve(index, query) {

@@ -39,6 +56,199 @@ const q = query.toLowerCase().trim();

async function pathExists(p) {
try {
await stat(p);
return true;
} catch {
return false;
}
}
async function readLocalIndex(registryRoot) {
try {
return JSON.parse(await readFile(join(registryRoot, 'index.json'), 'utf8'));
} catch {
return null;
}
}
// Read a directory tree recursively into a map of relPath -> Buffer content.
async function readTree(dir) {
const out = {};
async function rec(base, rel) {
const entries = await readdir(base, { withFileTypes: true });
for (const e of entries) {
const relPath = rel ? join(rel, e.name) : e.name;
const full = join(base, e.name);
if (e.isDirectory()) await rec(full, relPath);
else out[relPath] = await readFile(full);
}
}
await rec(dir, '');
return out;
}
const REMOTE_SKILL_FILES = (slug) => [
'SKILL.md',
join('references', 'stack.md'),
join('references', 'workflow.md'),
join('references', 'sources.md'),
join('agents', `${slug}-developer.md`),
];
// Resolve which files to install for `slug`, and where the registry/data came from.
// Returns { files: { relPath: Buffer } }.
async function loadSkillFiles({ slug, registryRoot, remote }) {
if (remote) {
const files = {};
for (const rel of REMOTE_SKILL_FILES(slug)) {
const text = await fetchText(`registry/${slug}/skill/develop-like-${slug}/${rel}`);
files[rel] = Buffer.from(text, 'utf8');
}
return files;
}
const prebuiltDir = join(registryRoot, slug, 'skill', `develop-like-${slug}`);
if (await pathExists(prebuiltDir)) {
return readTree(prebuiltDir);
}
// Fall back to in-memory generation from profile.md + entry.json.
const { renderSkill } = await import('../scripts/generate-skill.mjs');
const rendered = await renderSkill(slug, registryRoot);
const files = {};
for (const [rel, content] of Object.entries(rendered)) {
files[rel] = Buffer.from(content, 'utf8');
}
return files;
}
function toPosix(relPath) {
return relPath.split(sep).join('/');
}
// Compare the on-disk target dir against the desired file set.
// Returns { status: 'missing' | 'match' | 'drift', differing: string[] }.
async function diffInstalled(targetDir, files) {
if (!(await pathExists(targetDir))) return { status: 'missing', differing: [] };
const differing = [];
for (const [rel, content] of Object.entries(files)) {
const full = join(targetDir, rel);
let existing;
try {
existing = await readFile(full);
} catch {
differing.push(toPosix(rel));
continue;
}
if (!existing.equals(content)) differing.push(toPosix(rel));
}
return { status: differing.length ? 'drift' : 'match', differing };
}
async function writeFiles(targetDir, files) {
for (const [rel, content] of Object.entries(files)) {
const full = join(targetDir, rel);
await mkdir(dirname(full), { recursive: true });
await writeFile(full, content);
console.log(`write ${toPosix(relative(process.cwd(), full))}`);
}
}
async function ensureClaudeLink(projectRoot, dirName, dryRun) {
const claudeDir = join(projectRoot, '.claude');
if (!(await pathExists(claudeDir))) return;
const linkPath = join(claudeDir, 'skills', dirName);
const targetPath = join(projectRoot, '.agents', 'skills', dirName);
const relTarget = relative(dirname(linkPath), targetPath);
if (await pathExists(linkPath)) {
try {
const lst = await lstat(linkPath);
if (lst.isSymbolicLink()) {
const real = await realpath(linkPath).catch(() => null);
const expectedReal = await realpath(targetPath).catch(() => null);
if (real && expectedReal && real === expectedReal) return; // already correct
}
} catch {
// fall through to recreate
}
}
const relLabel = toPosix(join('.claude', 'skills', dirName));
const relTargetLabel = toPosix(relTarget);
if (dryRun) {
console.log(`symlink ${relLabel} -> ${relTargetLabel}`);
return;
}
await mkdir(dirname(linkPath), { recursive: true });
await rm(linkPath, { recursive: true, force: true });
try {
await symlink(relTarget, linkPath, 'dir');
console.log(`symlink ${relLabel} -> ${relTargetLabel}`);
} catch {
await cp(targetPath, linkPath, { recursive: true });
console.log(`copy ${relLabel} <- ${toPosix(relative(process.cwd(), targetPath))}`);
}
}
async function install({ slug, registryRoot, remote, projectRoot, dryRun, force }) {
const files = await loadSkillFiles({ slug, registryRoot, remote });
const dirName = `develop-like-${slug}`;
const targetDir = join(projectRoot, '.agents', 'skills', dirName);
const { status, differing } = await diffInstalled(targetDir, files);
if (status === 'match') {
if (dryRun) {
console.log(`${dirName} already installed (up to date) — no changes planned`);
} else {
console.log(`${dirName} already installed (up to date)`);
}
await ensureClaudeLink(projectRoot, dirName, dryRun);
printNextSteps(slug);
return 0;
}
if (status === 'drift' && !force) {
const label = dryRun ? 'would refuse' : 'refusing to overwrite';
console.error(`${dirName} is installed but differs from the registry (${label} without --force):`);
for (const rel of differing) console.error(` ${rel}`);
if (!dryRun) return 1;
// dry-run still prints the plan then exits 0 as spec'd, but we must not proceed to write.
return 0;
}
if (dryRun) {
for (const rel of Object.keys(files)) {
console.log(`write ${toPosix(join('.agents', 'skills', dirName, rel))}`);
}
await ensureClaudeLink(projectRoot, dirName, true);
printNextSteps(slug);
return 0;
}
await writeFiles(targetDir, files);
await ensureClaudeLink(projectRoot, dirName, false);
printNextSteps(slug);
return 0;
}
function printNextSteps(slug) {
console.log(`Done. Invoke /develop-like-${slug} or let it trigger implicitly in your agent.`);
}
async function main() {
const { positionals, values } = parseArgs({
allowPositionals: true,
options: { help: { type: 'boolean', short: 'h' } },
options: {
help: { type: 'boolean', short: 'h' },
'dry-run': { type: 'boolean' },
force: { type: 'boolean' },
dir: { type: 'string' },
registry: { type: 'string' },
},
});

@@ -50,3 +260,5 @@ if (values.help || positionals.length === 0) return console.log(HELP);

if (cmd === 'list') {
const index = await fetchJson('registry/index.json');
const index = values.registry
? await readLocalIndex(values.registry)
: await fetchJson('registry/index.json');
for (const [slug, e] of Object.entries(index.entries)) {

@@ -60,10 +272,26 @@ console.log(`${slug.padEnd(16)} ${e.kind.padEnd(7)} ${e.consentTier.padEnd(15)} ${e.name}`);

const { validate } = await import('../scripts/validate.mjs');
process.exitCode = await validate() ? 0 : 1;
process.exitCode = (await validate()) ? 0 : 1;
return;
}
// TODO(v0.2): install path — resolve alias, fetch registry/<slug>/skill/ or generate from
// profile.md template, write to .agents/skills/, symlink .claude/skills/. See DESIGN.md.
const index = await fetchJson('registry/index.json');
const slug = resolve(index, cmd);
const projectRoot = values.dir ? values.dir : process.cwd();
const dryRun = Boolean(values['dry-run']);
const force = Boolean(values.force);
let registryRoot = values.registry ? values.registry : join(PKG_ROOT, 'registry');
let remote = false;
let index = await readLocalIndex(registryRoot);
let slug = index ? resolve(index, cmd) : null;
if (!slug && !values.registry) {
// Local miss without an explicit --registry override: try the remote index.
try {
index = await fetchJson('registry/index.json');
slug = resolve(index, cmd);
if (slug) remote = true;
} catch {
// network unavailable or fetch failed — fall through to the not-found error.
}
}
if (!slug) {

@@ -74,6 +302,9 @@ console.error(`'${cmd}' is not in the registry. Run /dev-like ${cmd} in your agent to profile it live.`);

}
console.log(`Resolved '${cmd}' -> ${slug} (${index.entries[slug].consentTier}, updated ${index.entries[slug].updated})`);
console.log('Install path lands in v0.2 — for now: npx skills add marcusrbrown/dev-like');
process.exitCode = await install({ slug, registryRoot, remote, projectRoot, dryRun, force });
}
main().catch((err) => { console.error(err.message); process.exitCode = 1; });
main().catch((err) => {
console.error(err.message);
process.exitCode = 1;
});
+2
-1
{
"name": "dev-like",
"version": "0.1.1",
"version": "0.2.0",
"description": "Profile a shop's engineering culture from public sources and install develop-like-<target> agent skills. /dev-like Every",

@@ -27,2 +27,3 @@ "keywords": [

"bin",
"scripts",
"skills",

@@ -29,0 +30,0 @@ "registry",

@@ -9,2 +9,3 @@ {

"homepage": "https://every.to",
"summary": "compound engineering, plan-first 80/20, boring Rails under aggressive AI leverage",
"sources": [

@@ -14,7 +15,11 @@ { "url": "https://github.com/EveryInc/compound-engineering-plugin", "fetched": "2026-07-11", "tier": "self-published", "note": "CEP - their culture, already codified" },

{ "url": "https://every.to/source-code/my-ai-had-already-fixed-the-code-before-i-saw-it", "fetched": "2026-07-11", "tier": "stated", "note": "Kieran Klaassen origin story" },
{ "url": "https://every.to/guides/compound-engineering", "fetched": "2026-07-11", "tier": "stated" },
{ "url": "https://every.to/guides/compound-engineering", "fetched": "2026-07-11", "tier": "stated", "note": "verified: 80/20 split, four-step core loop, agent-native parity, safety nets" },
{ "url": "https://every.to/podcast/transcript-how-two-engineers-ship-like-a-team-of-15-with-ai-agents", "fetched": "2026-07-11", "tier": "stated" },
{ "url": "https://www.lennysnewsletter.com/p/inside-every-dan-shipper", "fetched": "2026-07-11", "tier": "social", "note": "third-party interview" },
{ "url": "https://github.com/kieranklaassen", "fetched": "2026-07-11", "tier": "observed", "note": "Ruby AI gems, Cora stack signals" }
{ "url": "https://sfruby.com/", "fetched": "2026-07-11", "tier": "stated", "note": "Kieran Klaassen SF Ruby keynote: Rails + AI stack for Cora" },
{ "url": "https://github.com/EveryInc/compound-engineering-plugin/blob/main/AGENTS.md", "fetched": "2026-07-11", "tier": "self-published", "note": "canonical repo instruction file, provenance rules" },
{ "url": "https://github.com/EveryInc/compound-engineering-plugin/blob/main/docs/skills/ce-compound.md", "fetched": "2026-07-11", "tier": "self-published", "note": "/ce-compound writes docs/solutions/" },
{ "url": "https://github.com/EveryInc/compound-engineering-plugin/blob/main/skills/ce-compound-refresh/SKILL.md", "fetched": "2026-07-11", "tier": "self-published", "note": "docs/solutions/ discoverability discipline" },
{ "url": "https://www.lennysnewsletter.com/p/inside-every-dan-shipper", "fetched": "2026-07-11", "tier": "social", "note": "third-party interview; verified 15 people / 5 products / 'virtually zero code'" },
{ "url": "https://github.com/kieranklaassen", "fetched": "2026-07-11", "tier": "observed", "note": "profile page thin; stack signal better carried by SF Ruby keynote" }
]
}

@@ -9,3 +9,3 @@ # Every — dev culture profile

~15-person company running five products (Cora, Monologue, Sparkle, Spiral, every.to), each
with roughly one-person engineering teams and ~"100% AI-written code"
with roughly one-person engineering teams whose engineers "write virtually zero code"
[[Lenny's]](https://www.lennysnewsletter.com/p/inside-every-dan-shipper). Their practice is

@@ -18,13 +18,19 @@ codified in the Compound Engineering Plugin (CEP), ~23k stars

"Each unit of engineering work should make subsequent units easier — not harder"
[[CEP README]](https://github.com/EveryInc/compound-engineering-plugin). 80% planning/review,
20% execution
[[essay]](https://every.to/chain-of-thought/compound-engineering-how-every-codes-with-agents).
[[CEP README]](https://github.com/EveryInc/compound-engineering-plugin). Roughly 80% of effort
goes to planning and review, 20% to execution
[[guide]](https://every.to/guides/compound-engineering).
## Workflow shape
Six-step loop: **brainstorm → plan → work → simplify → review → compound**. The compound step
The CEP plugin ships a six-step loop: **brainstorm → plan → work → simplify → review →
compound** [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Every's own guide
describes the core cycle in four beats — **plan → work → review → compound → repeat** — with
`simplify` being the extra gate the plugin inserts
[[guide]](https://every.to/guides/compound-engineering). The compound step (`/ce-compound`)
writes learnings to `docs/solutions/`, which ground the next loop — knowledge accretes in the
repo, not in heads [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Fully
autonomous pipeline (`/lfg`): plan → work → review → PR → watch CI until green. Reviewer
personas live as skill-local prompt assets (29 skills, 0 standalone agents post-migration).
repo, not in heads
[[ce-compound]](https://github.com/EveryInc/compound-engineering-plugin/blob/main/docs/skills/ce-compound.md).
Fully autonomous pipeline (`/lfg`): plan → work → review → PR → watch CI until green. Reviewer
personas live as skill-local prompt assets (29 skills, 0 standalone agents post-migration)
[[CEP]](https://github.com/EveryInc/compound-engineering-plugin).

@@ -35,3 +41,2 @@ ## Stack

pgvector for the AI layer (Cora)
[[Kieran's GitHub]](https://github.com/kieranklaassen)
[[SF Ruby keynote]](https://sfruby.com/). Boring, well-understood building blocks under

@@ -42,7 +47,10 @@ aggressive AI leverage.

1. Plan-first, 80/20 — most effort before code [[essay]](https://every.to/chain-of-thought/compound-engineering-how-every-codes-with-agents)
1. Plan-first, 80/20 — most effort before code [[guide]](https://every.to/guides/compound-engineering)
2. Compound every unit of work into reusable repo knowledge [[CEP]](https://github.com/EveryInc/compound-engineering-plugin)
3. Simplify as an explicit pipeline step, not an afterthought [[CEP]](https://github.com/EveryInc/compound-engineering-plugin)
4. One person + agents ≈ a team; design workflows for that ratio [[podcast transcript]](https://every.to/podcast/transcript-how-two-engineers-ship-like-a-team-of-15-with-ai-agents)
5. Boring stack, radical process [[Kieran's GitHub]](https://github.com/kieranklaassen)
5. Boring stack, radical process [[SF Ruby keynote]](https://sfruby.com/)
6. Agent-native parity — if a human can run tests, read logs, or open a PR, the agent should be able to as well [[guide]](https://every.to/guides/compound-engineering)
7. Safety nets over gatekeeping — trust comes from tests, automated review, monitoring, and rollback, not line-by-line babysitting [[guide]](https://every.to/guides/compound-engineering)
8. Make institutional knowledge discoverable — solved problems live in `docs/solutions/`, and instruction files must surface that store so future agents find it [[ce-compound-refresh]](https://github.com/EveryInc/compound-engineering-plugin/blob/main/skills/ce-compound-refresh/SKILL.md)

@@ -53,3 +61,4 @@ ## Tensions

*principles*, expect the mechanics to drift.
- "100% AI-written" is a podcast soundbite; repo history shows human review is the load-bearing
step. Treat the claim as directional.
- "Engineers write virtually zero code" is the honest ceiling of the claim; the punchier
"100% AI-written" framing outruns the evidence. Repo history shows human review is the
load-bearing step. Treat the ratio as directional.

@@ -16,2 +16,3 @@ {

"homepage": { "type": "string", "format": "uri" },
"summary": { "type": "string", "maxLength": 160, "description": "three-phrase culture summary used in generated skill descriptions" },
"contributors": { "type": "array", "items": { "type": "string" } },

@@ -18,0 +19,0 @@ "sources": {

@@ -10,8 +10,12 @@ {

"sources": [
{ "url": "https://create.t3.gg/", "fetched": "2026-07-11", "tier": "stated", "note": "T3 stack axioms incl. 'bleed responsibly'" },
{ "url": "https://create.t3.gg/en/introduction/", "fetched": "2026-07-11", "tier": "stated", "note": "T3 stack axioms incl. 'bleed responsibly', typesafety" },
{ "url": "https://t3.gg/blog/post/types-and-nextjs", "fetched": "2026-07-11", "tier": "stated", "note": "full-stack typesafety, inference over hand-written types" },
{ "url": "https://t3.gg/blog/post/2023-tech", "fetched": "2026-07-11", "tier": "stated", "note": "delivery/iteration/DX priorities, preferred stack" },
{ "url": "https://create.t3.gg/en/usage/drizzle", "fetched": "2026-07-11", "tier": "stated", "note": "Drizzle officially supported in create-t3-app" },
{ "url": "https://github.com/t3-oss", "fetched": "2026-07-11", "tier": "observed", "note": "create-t3-app, t3-env" },
{ "url": "https://github.com/t3dotgg", "fetched": "2026-07-11", "tier": "observed" },
{ "url": "https://github.com/pingdotgg/t3code", "fetched": "2026-07-11", "tier": "stated", "note": "T3 Code: current agent GUI product" },
{ "url": "https://www.youtube.com/@t3dotgg", "fetched": "2026-07-11", "tier": "stated", "note": "primary publishing channel" },
{ "url": "https://betterstack.com/community/guides/ai/t3-code/", "fetched": "2026-07-11", "tier": "stated", "note": "T3 Code: parallel agents over worktrees" }
{ "url": "https://betterstack.com/community/guides/ai/t3-code/", "fetched": "2026-07-11", "tier": "social", "note": "third-party; sole current source for 'prompts are tech debt' attribution" }
]
}

@@ -8,31 +8,42 @@ # Theo Browne (t3.gg) — dev culture profile

Creator/founder (Ping.gg, UploadThing, T3 Chat, T3 Code), ~1M-subscriber YouTube channel
Creator/founder (Ping.gg, UploadThing, T3 Chat, T3 Code), prolific developer-YouTuber
[[@t3dotgg]](https://www.youtube.com/@t3dotgg), author of the T3 Stack
[[create.t3.gg]](https://create.t3.gg/), ex-Twitch video infra.
[[create.t3.gg]](https://create.t3.gg/en/introduction/), ex-Twitch video infra.
## Principles (cited)
1. **Typesafety absolutism** — full-stack TypeScript; typesafety is non-negotiable
[[create.t3.gg]](https://create.t3.gg/)
2. **"Bleed responsibly"** — adopt bleeding-edge only where you can afford the cost
[[T3 axioms]](https://create.t3.gg/)
1. **Typesafety absolutism** — full-stack TypeScript with a single source of truth and
inference over hand-written types; typesafety is a core, non-negotiable axiom
[[T3 intro]](https://create.t3.gg/en/introduction/)
[[types & Next.js]](https://t3.gg/blog/post/types-and-nextjs)
2. **"Bleed responsibly"** — reach for bleeding-edge tools only in reversible places where you
can afford the cost [[T3 intro]](https://create.t3.gg/en/introduction/)
3. **Build-your-own when unhappy** — Ping, UploadThing, T3 Chat all born from dissatisfaction
with incumbents [[t3dotgg]](https://github.com/t3dotgg)
4. **Ship-speed and performance obsession** — speed-first product ethos
[[T3 Chat / Mux interview]](https://www.mux.com/blog/theobrowne)
5. **Prompts are technical debt** — prefer minimally-configured, third-party-maintained agent
tooling over bespoke prompt piles; terminal-first, parallel agents over git worktrees
(T3 Code) [[T3 Code guide]](https://betterstack.com/community/guides/ai/t3-code/)
4. **Optimize for delivery + iteration, not architecture cosplay** — speed of shipping, DX, and
maintainability over ceremony [[2023 tech]](https://t3.gg/blog/post/2023-tech)
5. **Defaults are opinions** — create-t3-app's shipped choices (Next.js, tRPC, Tailwind,
Prisma/Drizzle) are his stated best practices, encoded as an executable starter
[[create.t3.gg]](https://create.t3.gg/en/introduction/)
[[Drizzle support]](https://create.t3.gg/en/usage/drizzle)
## Stack
TypeScript everywhere; T3 Stack = Next.js + tRPC + Tailwind (+ Drizzle in current community
practice) [[create.t3.gg]](https://create.t3.gg/) [[t3-oss]](https://github.com/t3-oss).
TypeScript everywhere; T3 Stack = Next.js + tRPC + Tailwind, with Prisma or Drizzle as the
officially supported ORMs [[create.t3.gg]](https://create.t3.gg/en/introduction/)
[[Drizzle]](https://create.t3.gg/en/usage/drizzle) [[t3-oss]](https://github.com/t3-oss).
Agent tooling: T3 Code, a web GUI for coding agents, is a current Ping product
[[t3code]](https://github.com/pingdotgg/t3code).
## Tensions — read before installing
**This skill is self-contradicting by its subject's own standards.** Theo's stated position is
that accumulated prompt configuration is technical debt. A `develop-like-theo` prompt artifact
is exactly that. Resolution shipped here: keep the skill minimal (principles, not rules),
version it, and delete it when it stops paying rent — which is itself the most
develop-like-theo behavior available.
**This skill is self-contradicting by its subject's own standards.** Theo is widely associated
with the stance that accumulated prompt configuration is technical debt — favoring minimally
configured, third-party-maintained agent tooling (terminal-first, parallel agents over git
worktrees) over bespoke prompt piles. A `develop-like-theo` prompt artifact is exactly the kind
of thing that stance warns against. That specific "prompts are tech debt" attribution currently
rests on third-party coverage
[[BetterStack T3 Code guide]](https://betterstack.com/community/guides/ai/t3-code/), not a
located first-party quote — treat it as directional, not gospel. Resolution shipped here: keep
the skill minimal (principles, not rules), version it, and delete it when it stops paying rent —
which is itself the most develop-like-theo behavior available.