@refactco/refact-os
v2.9.0
Published
Installable scaffolder for the agent-first repo standard: minimum-seed substrate + canonical agent/ skill catalog with generated tool adapters
Maintainers
Readme
refact-os
refact-os sets up a project so AI coding agents (Cursor, Claude Code) can work in it reliably. It drops in a fixed folder layout (the substrate) plus a set of agent skills (the move set) — all generated from one source of truth.
The full standard is written up in
docs/agent-first-repo-best-practices.md. Read it before changing what gets scaffolded.
You only ever edit one canonical folder, agent/. The tool generates the tool-specific folders (.cursor/, .claude/) from it — you never edit those by hand.
Installation
refact-os is published on npm as @refactco/refact-os (scoped, public). You need Node.js ≥ 18 and npm (or any npm-compatible runner).
Quick start — new project
mkdir my-project && cd my-project
npm i -D @refactco/refact-os@latest && npx refact-os initAdd to an existing repo
cd your-repo
npm i -D @refactco/refact-os@latest && npx refact-os initinit detects whether the repo is empty or not and adapts:
| Repo state | What init does |
|---|---|
| Empty | Lays the full substrate seed, base agent/ skills, and generated adapters. |
| Existing | Adds the agent layer plus the docs/ substrate seed. Existing docs/ files are never overwritten; no apps/ structure is imposed. Then run the adopt skill (/adopt) to survey the repo, write a transition plan, and reconcile your structure with the standard. |
After init you can add project-specific capability on demand — packs ship inside the package, so they work offline:
npx refact-os get-skill wordpress # or: nextjs, code, client, seoSee Packs for the full list.
Three ways to run commands
init adds @refactco/refact-os as a dev-dependency and wires up npm scripts. After npm install, you can invoke any command in whichever style you prefer — they are all equivalent:
| Style | Example | When to use |
|---|---|---|
| npm scripts (recommended) | npm run refact:sync | Day-to-day inside your project — shortest to type. |
| npx | npx @refactco/refact-os sync | One-off use or before the package is installed locally. |
| Direct binary | refact-os sync | After a global install or when the package is in your PATH. |
The npm scripts added to your package.json:
"scripts": {
"refact:sync": "refact-os sync", // rebuild .cursor/ + .claude/ after editing agent/
"refact:validate": "refact-os validate", // check the project follows the standard
"refact:migrate": "refact-os migrate", // move an old layout to the current one
"refact:update": "refact-os init" // pull the latest refact-os files
}Staying current
npm run refact:update (= refact-os init) refreshes the package-managed agent/ payload (new + edited skills/hooks/scripts), prunes skills the package has since removed or renamed (only ones it previously shipped — never your own), regenerates .cursor/ + .claude/, and prints the version transition (old → new).
A normal npm install is safe — it never overwrites your files. Refreshing only happens when you explicitly run npm run refact:update.
The version last applied is recorded in .refact-os.json (_scaffold.version). After updating, scan CHANGELOG.md for anything needing manual action and run npm run refact:validate. Your agent/AGENTS.md is never overwritten — if the upstream template changed, the update flags it so you can merge by hand.
Packs
init ships only the universal base. Project-specific capability lives in packs you get on demand with get-skill <pack> — they ship inside the package (offline, version-locked). Getting a pack records it in .refact-os.json (so init/update keep re-applying it) and, for wordpress/nextjs, sets the stack entry so deploy config and the /refact preflight reflect the type.
| Pack | Get it | Skills it adds |
|---|---|---|
| wordpress | get-skill wordpress | wp-env, install-wp-skills, setup-kinsta-deploy, setup-wpengine-deploy |
| nextjs | get-skill nextjs | setup-nextjs-app, nextjs-dev, setup-vercel-deploy, setup-netlify-deploy |
| code | get-skill code | code-development, add-codebase — code-specific gates (tests/lint/build, green CI) layered on the base git-workflow skill, for sustained product code |
| client | get-skill client | create-deliverable + the docs/deliverables/ folder |
| seo | get-skill seo | gsc — Google Search Console toolkit (connect, performance reports, sitemaps, URL inspection); pagespeed — Core Web Vitals (CrUX field data) + Lighthouse audits (PageSpeed Insights). Stack-agnostic. |
Run list-skills to see what's installed and what's gettable. Each runnable app lives under apps/ (e.g. apps/web/, apps/wordpress/). After getting a pack, ask the agent for the flow you need — the steps live in the pack's skills:
/refact wp-env setup
/refact setup nextjs app
/refact setup vercel deployCommands
refact-os init [--target <dir>] [--no-force] [--dry-run] # lay/refresh the universal base
refact-os get-skill <pack> [--target <dir>] # add a capability pack on demand
refact-os list-skills [--target <dir>] # installed skills + the gettable catalog
refact-os sync [--target <dir>] # regenerate .cursor/ + .claude/ from agent/
refact-os sync company [--target <dir>] # pull company context into docs/context/company/
refact-os validate [--target <dir>] # check structure + skills against the spec
refact-os migrate [--target <dir>] # move an older layout into the current oneinit— lay the universal base (thin seed + baseagent/skills + adapters) and re-apply any packs already recorded.--no-forcenever overwrites existing files.--dry-runpreviews what would be created, updated, or pruned without writing anything — useful for understanding what an update will do before committing. Re-runninginitis also the update path (see Staying current) — it preserves gotten packs and your own skills.get-skill <pack>— add a capability pack (wordpress,nextjs,code,client,seo) on demand: copies its skills, records it, re-syncs, and sets the stack entry for type-packs. Idempotent.list-skills— list installed skills and the gettable pack catalog (provenance-aware).sync— after editingagent/, regenerate.cursor/and.claude/. Never edit those by hand.validate— checks the required folders/files exist, every skill declares its resolver frontmatter (name,pattern,description,when_to_use,when_not_to_use,next_skills), the generated skill index isn't stale, the adapters are in sync, and recorded packs aren't missing skills (pack drift).migrate— moves an old-layout repo into the current one and tops up thepackage.jsonscripts. Safe: it never overwrites an existing file, and merges old chat folders into the new location.sync company— pulls Refact's shared company context (brand, team, pitch) fromrefactco/refact-hqintodocs/context/company/. Re-syncable, so it never drifts permanently. Source + SHA are recorded in.refact-os.json.
What gets generated
<project-root>/
├── AGENTS.md CLAUDE.md ← thin pointers to agent/
├── README.md package.json .env.example .gitignore .refact-os.json
├── agent/ ← CANONICAL (the source of truth — you edit here)
│ ├── AGENTS.md ← the engagement contract (kept if it already exists)
│ ├── CLAUDE.md
│ ├── hooks.json hooks/ scripts/ references/
│ ├── agent-surface-map.json ← generated map of canonical → adapters
│ └── skills/ ← the skill catalog (ingest-input, open-ticket, …)
├── docs/ ← your working docs
│ ├── index.md decisions.md
│ ├── sources/raw/{email,call-transcripts,agent-transcripts}/ ← inbound material
│ ├── context/{project,people,open-decisions,learnings}.md ← curated knowledge
│ ├── task/{open,closed}/ ← work tracking
│ └── deliverables/ ← finished output
├── apps/ ← your product code (apps/web, apps/wordpress, …)
├── .cursor/ ← GENERATED from agent/ (do not edit)
└── .claude/ ← GENERATED from agent/ (do not edit)agent/ is the source of truth. .cursor/ and .claude/ are throwaway copies — change agent/ and run npm run refact:sync.
The generated .claude/settings.json ships a shared, team-wide permission allowlist (git commit, git push, gh pr create) so agents don't re-prompt for the common commit/push/PR flow — edit the source in agent/claude-hooks.json, and put personal tweaks in the gitignored .claude/settings.local.json. (Claude Code only — Cursor's allowlist is global per-user at ~/.cursor/permissions.json with no per-repo option.)
Skills
Skills live in agent/skills/<name>/SKILL.md. They are loaded lazily: the agent reads each skill's short resolver frontmatter (name, pattern, description, when_to_use, when_not_to_use, next_skills) to decide what to use, and only opens the full skill when it picks it.
The base is deliberately thin — only what every repo needs (an internal ops or research repo with no codebase and no customer deliverables still wants all of it):
| Skill | What it does |
|---|---|
| ingest-input | Classify + save any inbound material to docs/sources/raw/. The entry point for new input. |
| open-ticket / close-ticket | Track work in docs/task/. |
| update-canonical-record | Make a careful, cited edit to the project's main truth file. |
| extract-learnings | Capture non-obvious learnings into docs/context/. |
| git-workflow | Handle git for every committed change (code, docs, content, deliverables) in plain language — branch, commit, open the PR — so anyone, technical or not, contributes safely without touching the base branch. |
| adopt | Bring an existing, non-conformant repo up to the standard (survey → phased plan → reconcile). |
| refact | The /refact … command router that dispatches to the operational skills. |
| list-skills / get-skill / create-skill / contribute-skill | The skill lifecycle: see installed + catalog skills, get a pack on demand, author a local skill, promote a portable one to refact-os. |
Refact operational skills, also in base (run via /refact <action>, or picked on their own): setup-project, sync-env-vars, update-package, import-chat-history, process-docs, project-status, git-it, sync-asana.
Everything project-specific ships as a pack you get on demand with get-skill <pack> — so a repo with no code and no deliverables never sees code or delivery skills (see Packs):
code—code-development,add-codebase— code-specific gates (tests/lint/build, green CI) layered on the basegit-workflowskill, for sustained product code.get-skill code.client—create-deliverable+ thedocs/deliverables/folder.get-skill client.wordpress—wp-env,install-wp-skills,setup-kinsta-deploy,setup-wpengine-deploy.get-skill wordpress.nextjs—setup-nextjs-app,nextjs-dev,setup-vercel-deploy,setup-netlify-deploy.get-skill nextjs.
Engagement-shaped skills (draft-quote, draft-proposal, draft-email, design-asset, …) are not pre-shipped — author them with create-skill when a real engagement needs them, and contribute-skill to promote a portable one into the catalog.
Releasing a new version
Publishing is fully automated — you just need to be on the right branch.
- Switch to
mainand pull the latest:
git checkout main && git pull- Tell the AI agent:
publish a new version- The agent bumps the version, updates the changelog, commits, tags, and pushes.
- GitHub Actions publishes to npm and creates a GitHub Release automatically.
- Monitor the run at github.com/refactco/refact-os/actions.
For the full release protocol, see
agent/skills/release/SKILL.md.
Repository layout (this package)
bin/refact-os.js # CLI: init | get-skill | list-skills | sync | validate | migrate (no postinstall — scaffolding is always explicit)
lib/
scaffold.js # copies templates/base into the target, then generates adapters
adapters.js # generate .cursor/ + .claude/ from agent/
validate.js # check structure + skill frontmatter
migrate.js # old layout → current layout
project-utils.js # project-type detection; package.json scripts + dev-dependency
refact-config.js # .refact-os.json (stack: types/hosting/runtime/environments, Asana id)
templates/base/ # the universal base copied into every project (universal + Refact tooling)
templates/packs/ # capability packs gotten on demand: code/, client/, wordpress/, nextjs/ (each with pack.json)
docs/agent-first-repo-best-practices.md # the spec this tool implementsPublished package contents: bin/, lib/, templates/, README.md (see package.json files).
For this scaffolder's own agent map, see AGENTS.md.
