AGENTS.md · diff
git:20260723.0c7dab2 to git:20260726.41b5756
41 added, 42 removed. Audit A to A.
# AGENTS.md
- This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
+ Canonical guidance for coding agents working in this repository. Claude Code additions live in `CLAUDE.md`; everything here applies to every agent.
## Project Overview
**Repository:** https://github.com/tartinerlabs/skills
**Package:** `@tartinerlabs/skills`
- A collection of agent skills distributed via Codex, Claude Code, Cursor, Antigravity, and [skills.sh](https://skills.sh). Each skill is a markdown file with YAML frontmatter following the [Agent Skills spec](https://agentskills.io).
+ A collection of agent skills distributed via Claude Code, Codex, Cursor, Antigravity, and [skills.sh](https://skills.sh). Each skill is a markdown file with YAML frontmatter following the [Agent Skills spec](https://agentskills.io).
## Development
- **Tooling:** stdlib-only Go plus plain shell git hooks — the repo deliberately avoids npm dependencies to keep the supply-chain surface minimal
- **Git hooks:** plain shell hooks in `.githooks/` (enable with `git config core.hooksPath .githooks`) — `commit-msg` enforces conventional commits (no scope, max 50-char header), `pre-commit` runs GitLeaks secrets detection
- - **Checks:** `go run ./scripts/validate-skills` and `go test ./...` (stdlib-only Go — no module dependencies)
+ - **Checks:** `go run ./scripts/validate-skills` and `go test ./...`
- **Releases:** Automated via release-please on push to `main` — maintains a release PR from conventional commits; merging it bumps versions, updates `CHANGELOG.md`, and creates the GitHub release
## Skill Format
- Each skill lives in `skills/<name>/SKILL.md` with this structure:
+ Each skill lives in `skills/<name>/SKILL.md`:
```markdown
---
name: skill-name
description: What it does and when to use it
+ license: MIT
allowed-tools: Space-delimited list of permitted tools
model: sonnet
effort: medium
+ compatibility: What the skill really requires
+ metadata:
+ short-description: Short display name for Codex
---
- [Instructions Codex follows when the skill is active]
+ [Instructions the agent follows when the skill is active]
```
### Frontmatter Fields
- - `name` — Skill identifier, invoked as `/skill-name` in Codex
- - `description` — Purpose and trigger conditions
- - `allowed-tools` — Scoped tool permissions (e.g., `Bash(git status)` for specific commands, `Read` for full tool access)
+ Fields split into two groups. **Portable** fields (`name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools`) come from the [Agent Skills spec](https://agentskills.io/specification) and are the only ones non-Claude channels can act on. **Claude-Code-only** fields (`model`, `effort`, `context`, `agent`) are ignored gracefully everywhere else. `go run ./scripts/validate-skills` enforces the portable group — every skill must carry `name`, `description`, `license`, `compatibility`, and `metadata.short-description`.
+
+ - `name` — Skill identifier. Must match the directory name
+ - `description` — Purpose and trigger conditions. This is the routing key agents match against, so it is written for retrieval rather than display
+ - `license` — SPDX identifier; `MIT` across the collection, matching the repo licence
+ - `compatibility` — The skill's real requirements (e.g. `Requires git`, `Any language project; detects the ecosystem`). Max 500 characters. Every skill carries one
+ - `metadata` — Spec-sanctioned extension point (arbitrary string map). We set `metadata.short-description`, a human-readable display string — the only field beyond `name`/`description` that Codex's skill loader parses, so it is what Codex surfaces in its UI instead of the retrieval-optimised `description`
+ - `allowed-tools` — Scoped tool permissions (e.g. `Bash(git status)` for specific commands, `Read` for full tool access). Spec-optional and marked experimental; Claude Code honours it, Cursor and Codex ignore it
- `model` — Model preference. Low/medium-effort skills default to `haiku` (cheaper, separate rate-limit bucket); high-effort skills that need deeper reasoning (forked subagents, complex audits) use `sonnet`
- `effort` — Reasoning effort level (`low`, `medium`, `high`, `max`). Overrides the session effort level while the skill is active
-
- ### Rules Pattern
+ - `context: fork` + `agent` — Runs the skill as an isolated subagent with its own context window. Used by the high-effort audit skills (`refactor`, `security`, `github-actions`)
- Skills with multiple checks use a `rules/` subdirectory alongside `SKILL.md`. The main skill file references rules via a table and tells Codex to read them at runtime. Each rule file is a standalone markdown document with severity, examples, and fix instructions. This keeps skills modular — rules can be added, removed, or edited independently.
+ ### Language-aware, JS/TS-first model
- ## Distribution
+ Every skill is **language-aware with JS/TS as the first-class default** — no skill assumes React or a single framework/host. Skills **detect, don't assume**: read the project's manifest (`package.json`/`pyproject.toml`/`go.mod`/…) as prose (never `!`-shell-injection, which is Claude-Code-only) and adapt. The general workflow/audit skills work in any language, gating framework-specific rules behind detection. The ecosystem tooling (`setup`, `deps`, `testing`) is polyglot. `tailwind` is the one inherent JS/CSS specialist. Secret scanning is abstracted: `commit`/`security`/`setup`/`deps` accept any scanner (GitLeaks default, TruffleHog accepted), not a hard-coded tool.
- The skills ship as four themed **collection plugins** — `workflow` (commit, create-branch, create-pr, github-actions, github-issues), `quality` (refactor, naming-format, project-structure, tailwind), `security` (security, deps), and `tooling` (setup, testing, update-project). The original all-in-one `tartinerlabs` plugin is **deprecated** but still published for a transition period. The collection assignment is the `collections` table in `scripts/validate-skills/main.go` — every skill must belong to exactly one collection (validated in CI).
+ ### Rules and References Pattern
- Skills are distributed through six channels:
- - **Codex plugin** — plugin metadata in `plugins/<collection>/.codex-plugin/plugin.json` with marketplace metadata in `.agents/plugins/marketplace.json`
- - **Claude Code plugin** — `claude plugin marketplace add tartinerlabs/skills`, then `claude plugin install <collection>@tartinerlabs`
- - **Cursor plugin** — plugin metadata in `plugins/<collection>/.cursor-plugin/plugin.json` with marketplace metadata in `.cursor-plugin/marketplace.json`
- - **Antigravity plugin** — plugin metadata in `plugins/<collection>/.antigravity-plugin/plugin.json`
- - **[skills.sh](https://skills.sh)** — `pnpm dlx skills add tartinerlabs/skills`
- - **[Context7](https://context7.com)** — `pnpm dlx ctx7 skills install /tartinerlabs/skills --all --universal`
+ Skills with multiple checks use a `rules/` subdirectory alongside `SKILL.md`, referenced from a table and read at runtime. Each rule file is standalone, with severity, examples, and fix instructions — so rules can be added, removed, or edited independently.
- The `Skills` CI workflow validates skills.sh and Context7 distribution on push to `main`.
+ Polyglot skills add a `references/` subdirectory for **progressive disclosure**: SKILL.md detects the language and loads **only** the matching `references/<lang>.md`, so a JS project never loads Go content. The asymmetry is intentional — the first-class JS/TS path stays in modular `rules/`; other ecosystems live in `references/<lang>.md`; truly universal checks stay in `rules/` and are cross-linked from each language guide. `references/` is also the most portable component across distribution channels. The validator enforces the same existence + orphan discipline on both (template placeholders like `references/<lang>.md` are ignored).
- ## Plugin Metadata
+ ### House style
- Plugin metadata is maintained manually by design. Every plugin lives in its own `plugins/<name>/` wrapper holding the four per-channel manifests plus a `skills` entry exposing its skill source. Two wrapper shapes exist:
+ Skills are lightweight guides, not procedures. State a preference and its reason, then license the exception — an absolute ban on a legitimate tool or utility will be wrong somewhere. `skills/setup/` is the reference for this: every rule file pairs `### Why This Matters` with `### Alternatives`, and the skill explicitly says you may decline any tool while a deliberately-configured alternative is kept, not swapped. Over-specify only where the cost of being wrong is high — `skills/commit/`'s refusal to commit when a secret scanner reports a leak is the one place hard `STOP` language is correct.
- - **Collection wrappers** — `plugins/workflow/`, `plugins/quality/`, `plugins/security/`, `plugins/tooling/` each have a real `skills/` directory containing one symlink per member skill (`skills/<skill>` → `../../../skills/<skill>`)
- - **Whole-directory wrappers** — `plugins/tartinerlabs/` (deprecated monolith, `skills` → `../../skills`) and `plugins/xcode-skills/` (`skills` → `../../xcode-skills`) expose an entire source directory through a single dir symlink
+ ## Distribution
- Per-channel metadata for every plugin:
+ The skills ship as four themed **collection plugins** — `workflow`, `quality`, `security`, and `tooling`. The original all-in-one `tartinerlabs` plugin is **deprecated** but still published for a transition period; its removal is a future release. The `collections` table in `scripts/validate-skills/main.go` is the source of truth for membership — every skill must belong to exactly one collection (validated in CI).
- - `plugins/<name>/.codex-plugin/plugin.json` is the Codex plugin manifest; `plugins/<name>/assets/icon.svg` is its Codex `composerIcon`
- - `.agents/plugins/marketplace.json` is the repo-scoped Codex marketplace entry
- - `plugins/<name>/.claude-plugin/plugin.json` is the Claude plugin manifest; the root `.claude-plugin/marketplace.json` is the Claude marketplace
- - `plugins/<name>/.cursor-plugin/plugin.json` is the Cursor plugin manifest; the root `.cursor-plugin/marketplace.json` is the Cursor marketplace
- - `plugins/<name>/.antigravity-plugin/plugin.json` is the Antigravity plugin manifest
- - Each marketplace references every plugin as `./plugins/<name>`. Keep every plugin subdirectory-sourced — the Claude Code loader silently drops a plugin sourced at the marketplace root (`source: "./"`) when another plugin exists
- - `.release-please-manifest.json` is the canonical version source; release-please (`extra-files` in `release-please-config.json`) syncs the `plugins/**/plugin.json` manifest versions in the release PR
+ Six channels: Claude Code, Codex, Cursor, and Antigravity plugins (each reading `plugins/<collection>/.<channel>-plugin/plugin.json`), plus [skills.sh](https://skills.sh) and [Context7](https://context7.com). `README.md` has the install commands. The `Skills` CI workflow validates skills.sh and Context7 distribution on push to `main`.
- When plugin copy changes, update Codex, Claude, Cursor, and Antigravity plugin manifests intentionally. Do not expose Claude-only hooks in Cursor metadata unless they have been ported to Cursor's runtime.
+ ## Plugins
- ## Xcode Skill Export
+ Plugin metadata is hand-maintained by design — there is no generator. Every plugin lives in its own `plugins/<name>/` wrapper holding its four per-channel manifests plus a `skills` entry exposing its skill source. Two wrapper shapes exist: **collection wrappers** with a real `skills/` directory of per-skill symlinks, and **whole-directory wrappers** (`tartinerlabs`, `xcode-skills`) exposing a source directory through one dir symlink. The validator checks every symlink target.
- The root-level `xcode-skills/` directory is generated exclusively by `xcrun agent skills export`. After an export, do not edit, add, remove, rename, move, reformat, or manually clean up anything inside that directory. Future exports must write directly to the same `xcode-skills/` path and remain untouched afterward.
+ - Each marketplace references every plugin as `./plugins/<name>`. **Keep every plugin subdirectory-sourced** — the Claude Code loader silently drops a plugin sourced at the marketplace root (`source: "./"`) when another plugin exists
+ - `.release-please-manifest.json` is the canonical version source; release-please (`extra-files` in `release-please-config.json`) syncs the `plugins/**/plugin.json` versions in the release PR. Never bump a version by hand
+ - When plugin copy changes, update all four channels intentionally. Do not expose Claude-only hooks in Cursor or Codex metadata unless they have been ported to that runtime
- All Codex, Claude, and Cursor metadata for this collection belongs in `plugins/xcode-skills/`. Its `skills` symlink points to `../../xcode-skills`; wrapper metadata and documentation may change, but the exported directory may not.
+ ## Xcode Skill Export
- ## GitHub Actions
+ The root-level `xcode-skills/` directory is generated exclusively by `xcrun agent skills export`, and holds Apple-authored skills unrelated to `skills/`. After an export, do not edit, add, remove, rename, move, reformat, or manually clean up anything inside it. Future exports must write directly to the same path and remain untouched afterward.
- - All actions: pin to a full commit SHA with a version or source-ref comment (e.g., `@9fd676a... # v4.2.0`), including GitHub-owned `actions/*`
+ All plugin metadata for this collection belongs in `plugins/xcode-skills/`, whose `skills` symlink points to `../../xcode-skills`. Wrapper metadata and documentation may change; the exported directory may not.
## Conventions
- - GitHub-related skills auto-assign to current user via `@me` or `get_me`
+ - **Commit type for skill content:** skill markdown (`skills/**/*.md`) is the product, not documentation. Changes to skill behaviour use `feat`/`fix`/`refactor` — never `docs`. Reserve `docs:` for `README.md`, `AGENTS.md`, `CLAUDE.md`, `CHANGELOG.md`, and similar meta-documentation
+ - Commit subjects are max 50 characters with no scope, enforced by `.githooks/commit-msg`
- PR and issue titles use natural language, NOT conventional commit prefixes
- - The `/commit` skill enforces max 50-character commit messages, detects commitlint to choose conventional vs plain format, and ensures GitLeaks is configured before committing
+ - GitHub-related skills auto-assign to the current user via `@me` or `get_me`
- Skills can use both CLI tools (`gh`, `git`) and MCP tools (`mcp__github__*`) depending on the operation
-
+ - Use `pnpm dlx` in documentation, not `pnx` — readers do not share this repo's tooling, and the repo has no `package.json` of its own
+ - Grant the minimum `allowed-tools` a skill needs; prefer specific commands (`Bash(git status)`) over blanket tool access