Engineering instructions and skill content for OpenCode, Claude Code, Codex, and Kiro. Portable practice only: no product context, no credentials, no machine-specific paths.
global engineering instructions
-> project instructions
-> nested directory instructions
-> current task
AGENTS.md shared global instructions
CLAUDE.md Claude wrapper around AGENTS.md
.agents/
skills/engineering/ portable engineering practice
skills/productivity/ portable general workflows
skills/product/ product framework skills and chains
skills/design/ UI/UX design skills and chains
skills/business/ business and operations skills
skills/calibrated/minh/ skills containing Minh-calibrated context
licenses/ upstream license notices
src/
cli/ apm CLI entrypoint (main.ts) and smoke tests
core/ shared infrastructure (commands, paths, reporter)
providers/ provider modules + apm helpers (link, doctor, mcp, sync)
skills/ inventory, integrity, ingest, review subdomains
dist/ compiled output (gitignored)
config/
providers/ mcp.json, opencode.json
skills/ manifest.json, lock.json, semgrep.yml
pyproject.toml uv project: pins skillspector and Python tooling dependencies
uv.lock locked dependency graph (committed, reproducible installs)
.python-version Python version pin (3.12)
Makefile convenience targets for install, deps, check, test
Requirements: Git, Node.js, uv, OpenCode, Claude Code, and/or Codex.
git clone git@github.com:mihado/agents.git ~/path/to/repo
cd ~/path/to/repo
make install
./apm checkmake install builds TypeScript sources, then runs ./apm install to set up local links, MCP config, and provider config. ./apm check runs the full integrity suite (doctor, MCP, providers, skills). Run make deps separately to install Python tooling (skillspector, semgrep) via uv sync.
To run individual steps:
make deps # set up Python venv (skillspector, semgrep) via uv sync
./apm install # link + mcp + providers
./apm doctor # quick local sanity check
./apm check # full integrity sweepThe link script creates these symlinks:
# skills
~/.codex/AGENTS.md -> <repo>/AGENTS.md
~/.claude/AGENTS.md -> <repo>/AGENTS.md
~/.claude/CLAUDE.md -> <repo>/CLAUDE.md
~/.codex/skills/<name> -> <repo>/.agents/skills/<name>
~/.claude/skills/<name> -> <repo>/.agents/skills/<name>
~/.agents/skills/<name> -> <repo>/.agents/skills/<name>
~/.kiro/skills/<name> -> <repo>/.agents/skills/<name>
# agents
~/.claude/agents/<name>.md -> <repo>/config/providers/claude/agents/<name>.md
~/.config/opencode/agents/<name>.md -> <repo>/config/providers/opencode/agents/<name>.md
~/.agents/skills/ is the universal skills path: OpenCode and Zed discover skills here. ~/.kiro/skills/ is Kiro's global skills path. If ~/.kiro doesn't exist yet (Kiro not installed on this machine), the link script creates it so skills are ready the moment Kiro is installed.
Each entry is linked individually. Existing unrelated skills survive. A file, directory, or foreign symlink at the same path causes installation to stop rather than overwrite.
CODEX_HOME, CLAUDE_HOME, AGENTS_HOME, and KIRO_HOME may be set to install into alternate locations.
apm (Agent Package Manager) is the canonical command-line interface. It is a Commander-based CLI built from src/cli/main.ts; the in-repo shim ./apm runs the built entrypoint until a global install puts the binary on PATH. Run ./apm --help to see the live surface.
make keeps install (the multi-step orchestrator that runs ./apm install) plus build/test/lint targets. Individual actions go through apm.
apm install install local agent setup (links + mcp + providers)
apm doctor read-only local sanity check (git, node, lock shape, symlinks, duplicates)
apm check full integrity sweep (doctor + mcp check + providers check + skills check)
apm skills fetch fetch declared third-party skills into .stage/skills
apm skills check verify live lock matches the working copy
apm skills review review staged skill content before accept/reject
apm skills accept promote stage to live
apm skills reject <name> remove a staged skill from stage
apm skills remove <name> remove a live skill from live tree and lock
apm skills audit audit entire live skill tree
apm skills audit --accept accept current live findings into the review baseline
apm skills audit --json emit audit findings as JSON
apm mcp install install MCP server entries from config/providers/mcp.json
apm mcp check verify MCP server entries
apm providers install install provider configuration
apm providers check verify provider configuration
./apm doctor # quick local sanity check (git, node, lock shape, symlinks, duplicates)
./apm check # full integrity sweep: doctor + mcp check + providers check + skills check./apm doctor is the fast local pass. ./apm check runs the full sweep: symlink validation, MCP config verification, provider config verification, and vendored skill hash checks. Nothing changes on your machine.
The skills lifecycle:
- Fetch declared skills from upstream into
.stage/skills/: inert, not loaded by any agent - Review the staged diff against prose injection and code execution risk patterns
- Reject any staged skill you don't want: remove it from stage, keep everything else intact
- Accept whatever remains in stage, promoting it into
.agents/skills/and updating the lock - Audit the live tree after promotion, optionally recording accepted findings into the baseline with
apm skills audit --accept
Reject operates on individual skills: if you approve three out of four staged skills, reject the fourth and accept the rest. The lock always reflects only what is live. For the full security model and scanner details, see docs/SECURITY.md.
config/providers/mcp.json declares shared MCP servers (Context7, Chrome DevTools, Better Auth). The installer configures whichever of OpenCode, Claude Code, and Codex are present on your machine.
./apm mcp install # install all MCP config
./apm mcp check # verify without changing anythingEnvironment variable names may be documented in config/providers/mcp.json; values stay in the machine environment and are never stored here.
chrome-devtools drives a real Chrome session. The installer renders it headed on macOS and appends --headless on every other platform (Linux VMs, SSH sessions), where there is no display for Chrome to attach to. The platform check lives in src/providers/opencode/config.ts; a Linux desktop with a real display that wants a visible browser would need to gate it there.
Chrome must be installed on the machine before OpenCode starts the MCP server. On headless Linux:
wget -q -O /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt-get update && sudo apt-get install -y /tmp/chrome.debRestart OpenCode after installing so the MCP server picks up the change.
Skills are copied unchanged from upstream repositories declared in config/skills/manifest.json:
- addyosmani/agent-skills
- lguz/humanize-writing-skill
- mattpocock/skills
- nutlope/hallmark
- pbakaus/impeccable
- shadcn/improve
- tw93/kami
- wondelai/skills
See CLI Reference for all available commands (fetch, review, accept, reject, remove, audit, check).
The lifecycle: fetch, review, reject anything you don't want, then accept what's left. Fetched content lands in .stage/skills/ first (inert, not loaded by any agent) until ./apm skills accept promotes it into .agents/skills/. Baseline acceptance is optional and happens separately via ./apm skills audit --accept against already-live content.
First-party skills can live directly in .agents/skills/ without being listed in the manifest. If you want them in the managed supply chain, add them to config/skills/manifest.json.
apm skills review scans the staged diff for two things hashing can't catch:
- Prompt injection in prose. Regex patterns for instruction overrides, concealment, credential access, and exfiltration phrasing in markdown and text files.
- Code execution risk in scripts. Semgrep rules for
curl | sh,eval,subprocess,child_process,rm -rf /, and dynamicprocess.envaccess.
Findings are fingerprinted and filtered against the skills-review baseline so only genuinely new hits surface. This is advisory: a human reads the findings and the actual diff.
apm skills audit walks the entire live tree with the same prose and Semgrep scan, plus optional SkillSpector (AST/taint/YARA, static-only --no-llm). Use it to inspect accepted content, or after a staged accept to decide whether current live findings should be recorded into the baseline.
Both tools share patterns from src/skills/review/. semgrep and skillspector are installed in the repo-local venv via make deps. The venv needs Python 3.12+ (uv sync installs it), so review and audit won't work without it. The other commands: fetch, check, accept, reject, remove, doctor. They work with just pnpm.
No skill content leaves the machine.
Skills are grouped by portability and calibration:
engineering/- portable engineering practice and ship chainsproductivity/- portable workflows useful beyond a single personproduct/- product framework skills and discovery chainsdesign/- UI/UX design skills and review chainsbusiness/- business and operations skillscalibrated/minh/- skills calibrated to Minh's voice, judgment, and preferences
Chain skills compose multiple vendored skills into a single workflow (e.g., design-review chains refactoring-ui, ux-heuristics, and microinteractions). They live next to the skills they compose.
The directory structure documents ownership and portability, not runtime profiles. Skill directory names must be globally unique across all installed repositories. Review calibrated material before pushing to a public repo.
OpenCode supports custom providers through config/providers/opencode.json. You can point it directly at your own provider accounts, or route requests through a local proxy if you want an extra control layer.
I use 9Router as one example of that second setup, but it is optional. Adjust the provider endpoints, proxy layer, and account layout to fit your own OpenCode configuration.
# Direct setup
Your CLI tool ──► OpenCode config ──► your provider
# Custom routed setup
Your CLI tool ──► OpenCode config ──► your proxy/router ──► provider A
(providers.json) └─► provider B
└─► provider C
config/providers/opencode.json- defines the providers and models exposed to OpenCode./apm providers install- syncs that config into~/.config/opencode/opencode.jsonc- Custom routing layer - optional; useful if you want centralized quota handling, fallback, model shaping, or account management outside OpenCode itself
- Fusion models - optional routed models that can combine capabilities behind a single OpenCode-facing model ID
Apache-2.0 - see LICENSE.