@akinlabs/ai-engineering
v0.2.0
Published
Compile tool-agnostic .ai workspaces into AI coding assistant runtimes.
Maintainers
Readme
AI Engineering Compiler
Keep AI assistant instructions in one reviewable source tree. Compile them for Claude Code and Codex.
The problem
AI coding assistants each want instructions in a different place and format.
Copying a few rules into CLAUDE.md and AGENTS.md is simple at first. It stops
being simple when the same policy lives in five generated places, because the
failure is quiet: someone tightens a rule in one file, nothing errors, and the
assistants start giving different advice depending on which one you opened.
This compiler keeps project intent in .ai/ and generates the runtime files
from it. Generated files stay visible and commit-ready — they are just never
edited by hand.
Most repositories do not need this. If one prose file covers your
instructions, symlink CLAUDE.md to AGENTS.md and stop there. See
docs/comparison.md for honest comparisons against
symlinks, the AGENTS.md standard, rulesync, and doing nothing.
Quick start
npm install --save-dev @akinlabs/ai-engineering
npx aie init
npx aie syncaie init creates a .ai/ workspace with a starter rule, without overwriting
anything. aie sync compiles it:
.ai/ CLAUDE.md
├── manifest.yaml ──► AGENTS.md
├── rules/ .claude/agents/
├── agents/ .claude/commands/
└── commands/Both runtimes load their instructions from the repository root, so CLAUDE.md
and AGENTS.md are the files that actually get read.
In CI, fail the build when generated files drift from their source:
npx aie checkIt will not overwrite your work
aie sync may only delete or replace a file it can prove it generated: one
listed in its ownership record (.ai/state/targets/), one whose bytes still
match the source it was copied from, or one carrying the generated banner.
Anything else is reported and the sync stops before writing:
Refusing to overwrite files this workspace does not own:
CLAUDE.md (claude)
Move them aside, or run with --force to overwrite them and take ownership.Your existing .claude/settings.json and hand-written commands survive every
sync. Nothing is skipped silently either — a source a runtime cannot express
produces a diagnostic naming it, on every run.
Already have CLAUDE.md and AGENTS.md?
Import them instead of starting over:
npx aie adoptAdopt is a dry run by default. It splits your existing instruction files into
.ai/ sources, flags pairs that look like the same policy written twice, and
never modifies the originals. --write applies the plan. See
examples/adopt-existing for the walkthrough.
Commands
| Command | Behavior | Exit codes |
| --- | --- | --- |
| aie init | Create a .ai workspace with a starter rule | 0 |
| aie adopt | Import existing assistant files (dry run by default) | 0 |
| aie sync | Compile enabled targets | 0, 1 on failure |
| aie check | Report drift without writing | 0 clean, 1 drift, 2 broken workspace |
| aie validate | Validate the workspace without comparing output | 0, 1 on failure |
| aie explain | Show what a workflow contributed and where it lands | 0 |
Options: --strict (warnings become errors), --force (overwrite unowned
files), --write (apply an adoption), --blueprint, --dry-run, --json.
In CI
- uses: akin-oz/ai-engineering@v0The action runs aie check, annotates the drifted files on the pull request,
and fails the job. It writes nothing.
Supported runtimes
| Runtime | Rules | Agents | Commands | Hooks |
| --- | --- | --- | --- | --- |
| Claude Code | CLAUDE.md | .claude/agents/ | .claude/commands/ | .claude/hooks/ + settings.json |
| Codex | AGENTS.md | inlined | — | — |
| Cursor | .cursor/rules/*.mdc | — | — | — |
A dash means the runtime has no format for it. The compiler says so on every run rather than dropping the source silently.
Hooks are declared in the manifest with a normalized event
(pre-edit, post-edit, session-start, session-end) and wired into
.claude/settings.json — the compiler owns only the entries it wrote there and
preserves the rest of your settings.
Compiling a workflow instead of listing files
aie init --blueprint writes a .ai/blueprint.yaml that names an engineering
workflow rather than individual files:
schema: 2
project:
type: library
workflow:
development: spec-driven
ai:
runtimes: [claude, codex]aie sync composes that workflow into .ai/generated/ — agents, rules,
commands, and templates, committed and reviewable — then compiles it for each
runtime. aie explain shows what came from where. Your own files in .ai/
compile alongside it.
One workflow ships today (spec-driven). More arrive when this one has proven
useful in real repositories, not before.
Examples
- examples/basic — smallest complete workspace
- examples/typescript-library — the case where hand-maintenance actually fails
- examples/adopt-existing — a repository already carrying drifted instruction files, and how to import it
This repository compiles itself: CLAUDE.md and AGENTS.md are generated from .ai/, and CI fails if they drift or if any source file is empty.
Documentation
- docs/ — shipped behavior: architecture, public API, adapter contract, writing an adapter, comparisons
- specs/ — scoped work that is committed but not finished
- rfcs/ — design that may never be built
That split is deliberate: 0.1 documented features that did not exist, which made the real claims harder to trust.
Contributing
Read CONTRIBUTING.md. Report security concerns per SECURITY.md.
