From 4f7d641a30c258d12ab39dd2ef5b5a22073b015f Mon Sep 17 00:00:00 2001 From: Scott Pfister Date: Thu, 16 Jul 2026 07:52:35 -0500 Subject: [PATCH 1/4] docs: add AGENTS.md guidance; fix claude-usage-report plugin source Add AGENTS.md as the canonical agent guidance (CLAUDE.md points to it), covering the skill-vs-plugin install duality, the .claude/skills symlink, the two-tier pricing design, and the PR-only workflow on protected main. Fix the claude-usage-report marketplace entry: a bare relative-string source combined with a skills array trips Claude Code's plugin resolver into a misleading "update Claude Code" error. Switch to the git-subdir object form used by other skill-bearing plugins. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude-plugin/marketplace.json | 7 +++- AGENTS.md | 73 +++++++++++++++++++++++++++++++++ CLAUDE.md | 5 +++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index e1792f6..0ce7918 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,7 +6,12 @@ "plugins": [ { "name": "claude-usage-report", - "source": "./skills/claude-usage-report", + "source": { + "source": "git-subdir", + "url": "https://github.com/7Factor/skills.git", + "path": "skills/claude-usage-report", + "ref": "main" + }, "skills": [ "." ], diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..d869d38 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,73 @@ +# AGENTS.md + +This file provides guidance to coding agents (Claude Code, Codex, and others) when working with code in this repository. + +## Workflow + +`main` is protected: you **cannot push directly to `main`**. All changes land via a pull request — +branch, push the branch, and open a PR (only when the user directs a push). + +## What this repo is + +A catalog of company-maintained **agent skills** for 7Factor. Each skill is a directory under `skills/` +containing a `SKILL.md` (frontmatter + instructions) plus any bundled scripts/reference files it needs. +Skills are consumed two ways, which are **not** equivalent: + +- **Skills CLI** (`npx skills add 7Factor/skills --skill `) — copies skill files only. It does + **not** install hooks, MCP servers, or agents. Cross-agent (Claude Code, Codex, etc.). +- **Claude Code plugin** (`/plugin marketplace add 7Factor/skills` → `/plugin install @7factor`) — + installs the skill **and** its hooks. Required whenever a skill depends on a hook. + +`.claude-plugin/marketplace.json` is the plugin manifest that drives the second path. + +## Repo layout gotchas + +- `.claude/skills` is a **symlink** to `.agents/skills`. The repo-local `write-a-skill` skill lives at + `.agents/skills/write-a-skill/` and is the authoring guide/checklist — use it when adding or changing a skill. +- `skills/` holds the published skills; `.agents/skills/` holds repo-local tooling skills. Don't confuse them. +- Some skills bundle Python scripts and a `tests/` dir alongside `SKILL.md` (e.g. the meta-repo skill on its + feature branch). The SKILL.md stays concise; heavy logic and reference material live in adjacent files. + +## marketplace.json: source format matters + +A plugin entry that ships skills must **not** combine a bare relative-string `source` with a `skills` array — +that specific combination trips Claude Code's plugin resolver into a misleading "update Claude Code" error. +Use the `git-subdir` object form for skill-bearing plugins: + +```json +"source": { + "source": "git-subdir", + "url": "https://github.com/7Factor/skills.git", + "path": "skills/", + "ref": "main" +} +``` + +After editing `marketplace.json`, changes only take effect once pushed and the marketplace is re-pulled +(`/plugin marketplace update 7factor`); the copy under `~/.claude/plugins/marketplaces/7factor` is a cache. + +## claude-usage-report skill + +Two-tier, date-aware Claude Code cost reporting from local transcripts. Python 3, no third-party deps. + +- `usage_report.py [today | YYYY-MM-DD | start end | 7d|week|month] [--top N]` — parses transcripts and prints + cost aggregates (BY MODEL/DAY/PROJECT/SESSION) plus the human prompts of the costliest sessions. The **skill** + turns this output into the report and derives no numbers itself. +- Pricing is **date-aware**: each message is costed at the rate in effect on its UTC day, read from + `prices.json` next to the script. +- `update_pricing.py` is the **deterministic tier**: it fetches Anthropic's pricing page, parses the table, + and only syncs `prices.json` if a sanity gate passes (appends effective-dated records, never clobbers known + future ones). If the parse fails the gate it writes nothing and errors, so the skill can fall back to an + **agent-repair tier** (fetch the page, fix the parser). +- Per-account attribution requires the plugin's `SessionStart` hook (`hooks/hooks.json` → + `record_account.sh` → `record_account.py`). Transcripts don't record which account was active, so without the + hook the "By account" table shows `unknown`. `record_account.sh` resolves a Python 3 interpreter defensively + and **always exits 0** — a session must never be blocked by attribution. + +## Conventions when adding/changing a skill + +1. Follow the `write-a-skill` skill's structure and review checklist. +2. Frontmatter needs a short `name` and a trigger-focused `description` (this is what decides when the skill + loads). Add `compatibility:` when the skill assumes a specific agent/runtime. +3. Keep `SKILL.md` concise enough to load quickly; move long examples/reference into adjacent files. +4. If a skill needs a hook/MCP/agent, remember Skills-CLI installs won't get it — document the plugin path. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..debc328 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +See [AGENTS.md](AGENTS.md) for all repository guidance. From 61c27aa3a0b6e546a648f5fa70799072a49642b8 Mon Sep 17 00:00:00 2001 From: Scott Pfister Date: Thu, 16 Jul 2026 12:09:20 -0500 Subject: [PATCH 2/4] docs: trim AGENTS.md to mistake-preventing guidance Cut content that duplicated the README, the write-a-skill skill, or skill-local detail per PR #6 review. Keeps the three things that actually correct errant agent behavior: protected-main workflow, skill-vs-plugin install duality, and the marketplace.json source trap. Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENTS.md | 47 +++++------------------------------------------ 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d869d38..22e0b81 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,29 +4,18 @@ This file provides guidance to coding agents (Claude Code, Codex, and others) wh ## Workflow -`main` is protected: you **cannot push directly to `main`**. All changes land via a pull request — -branch, push the branch, and open a PR (only when the user directs a push). +`main` is protected: you **cannot push directly to `main`**. All changes land via a pull request to main (push only when the user directs it). -## What this repo is +## Skill install paths are not equivalent -A catalog of company-maintained **agent skills** for 7Factor. Each skill is a directory under `skills/` -containing a `SKILL.md` (frontmatter + instructions) plus any bundled scripts/reference files it needs. -Skills are consumed two ways, which are **not** equivalent: +Skills in this repo are consumed two ways, and they install different things: -- **Skills CLI** (`npx skills add 7Factor/skills --skill `) — copies skill files only. It does +- **skills.sh** (`npx skills add 7Factor/skills --skill `) — copies skill files only. It does **not** install hooks, MCP servers, or agents. Cross-agent (Claude Code, Codex, etc.). - **Claude Code plugin** (`/plugin marketplace add 7Factor/skills` → `/plugin install @7factor`) — installs the skill **and** its hooks. Required whenever a skill depends on a hook. -`.claude-plugin/marketplace.json` is the plugin manifest that drives the second path. - -## Repo layout gotchas - -- `.claude/skills` is a **symlink** to `.agents/skills`. The repo-local `write-a-skill` skill lives at - `.agents/skills/write-a-skill/` and is the authoring guide/checklist — use it when adding or changing a skill. -- `skills/` holds the published skills; `.agents/skills/` holds repo-local tooling skills. Don't confuse them. -- Some skills bundle Python scripts and a `tests/` dir alongside `SKILL.md` (e.g. the meta-repo skill on its - feature branch). The SKILL.md stays concise; heavy logic and reference material live in adjacent files. +If a skill needs a hook/MCP/agent, remember skills.sh installs won't get it — document the plugin path. ## marketplace.json: source format matters @@ -45,29 +34,3 @@ Use the `git-subdir` object form for skill-bearing plugins: After editing `marketplace.json`, changes only take effect once pushed and the marketplace is re-pulled (`/plugin marketplace update 7factor`); the copy under `~/.claude/plugins/marketplaces/7factor` is a cache. - -## claude-usage-report skill - -Two-tier, date-aware Claude Code cost reporting from local transcripts. Python 3, no third-party deps. - -- `usage_report.py [today | YYYY-MM-DD | start end | 7d|week|month] [--top N]` — parses transcripts and prints - cost aggregates (BY MODEL/DAY/PROJECT/SESSION) plus the human prompts of the costliest sessions. The **skill** - turns this output into the report and derives no numbers itself. -- Pricing is **date-aware**: each message is costed at the rate in effect on its UTC day, read from - `prices.json` next to the script. -- `update_pricing.py` is the **deterministic tier**: it fetches Anthropic's pricing page, parses the table, - and only syncs `prices.json` if a sanity gate passes (appends effective-dated records, never clobbers known - future ones). If the parse fails the gate it writes nothing and errors, so the skill can fall back to an - **agent-repair tier** (fetch the page, fix the parser). -- Per-account attribution requires the plugin's `SessionStart` hook (`hooks/hooks.json` → - `record_account.sh` → `record_account.py`). Transcripts don't record which account was active, so without the - hook the "By account" table shows `unknown`. `record_account.sh` resolves a Python 3 interpreter defensively - and **always exits 0** — a session must never be blocked by attribution. - -## Conventions when adding/changing a skill - -1. Follow the `write-a-skill` skill's structure and review checklist. -2. Frontmatter needs a short `name` and a trigger-focused `description` (this is what decides when the skill - loads). Add `compatibility:` when the skill assumes a specific agent/runtime. -3. Keep `SKILL.md` concise enough to load quickly; move long examples/reference into adjacent files. -4. If a skill needs a hook/MCP/agent, remember Skills-CLI installs won't get it — document the plugin path. From f44aac5a928a4305051055f58ef5fd32efdc499d Mon Sep 17 00:00:00 2001 From: Scott Pfister Date: Thu, 16 Jul 2026 19:42:15 -0500 Subject: [PATCH 3/4] docs: drop marketplace.json fix (moved to #7) The git-subdir source fix is being handled in its own PR (#7) so it can merge without waiting on this AGENTS.md review. This branch now carries only the AGENTS.md/CLAUDE.md docs. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude-plugin/marketplace.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 0ce7918..e1792f6 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,12 +6,7 @@ "plugins": [ { "name": "claude-usage-report", - "source": { - "source": "git-subdir", - "url": "https://github.com/7Factor/skills.git", - "path": "skills/claude-usage-report", - "ref": "main" - }, + "source": "./skills/claude-usage-report", "skills": [ "." ], From 1562b221c34509317cf7b5482d3d29bb89164afc Mon Sep 17 00:00:00 2001 From: Scott Pfister Date: Fri, 17 Jul 2026 09:13:48 -0500 Subject: [PATCH 4/4] docs: re-add explanation about symlinked skills and extend --- AGENTS.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 22e0b81..2bc4b24 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,6 +6,13 @@ This file provides guidance to coding agents (Claude Code, Codex, and others) wh `main` is protected: you **cannot push directly to `main`**. All changes land via a pull request to main (push only when the user directs it). +## Organization + +- `.claude/skills` is a **symlink** to `.agents/skills`. The repo-local `write-a-skill` skill lives at + `.agents/skills/write-a-skill/` and is the authoring guide/checklist — use it when adding or changing a skill. +- Some skills in `.agents/skills` may be **symlinks** to skills in `skills` to guarantee the version of a skill + used is the latest one in the repository. + ## Skill install paths are not equivalent Skills in this repo are consumed two ways, and they install different things: