Custom configurations for Claude Code — skills, statusline, and an interactive installer. Also a plugin marketplace for easy one-command skill installation.
Install skills directly using Claude Code's built-in plugin system:
/plugin marketplace add cjthompson/claude-code-config
Then browse and install individual plugins from the /plugin UI.
This repository has host-specific plugin catalogs. Add the Codex catalog from this checkout with codex plugin marketplace add .agents/plugins, then install a listed plugin with codex plugin add <name>@cjthompson. The Codex and Cursor catalogs list these eight skill-bundle plugins: project-tasks, python-scripting, python-development, typescript-development, agent-team-development, orchestration-strategy, rust-coding, and textual. The Codex catalog also lists the hook plugins command-watchdog and worktree-guard, which share their hooks with Claude Code. For Cursor, import this repository's .cursor-plugin/marketplace.json from the Plugins settings.
lean-agents and output-styles are not listed in the Codex or Cursor catalogs because their host-specific runtime components are unavailable there. command-watchdog and worktree-guard are not listed in the Cursor catalog because Cursor runtime support is unavailable. See the watchdog section below for Codex installation, hook trust, and execution limitations.
| Plugin | Description |
|---|---|
| project-tasks | Capture tasks with task:/fix:/todo: prefixes, group them under plan: epics, dispatch to subagents, auto-generate changelogs |
| lean-agents | Reduced-toolset sub-agent profiles (read-only, lean-executor, standard-executor, main, full-executor) that lower System-tools token overhead vs. spawning the default agent; pairs with project-tasks, which dispatches by name |
| output-styles | Custom output styles (output-styles:Concise, output-styles:Terse) selectable via /output-style |
| orchestration-strategy | Select cost-efficient orchestration: solo, parallel, sequential, or Agent Teams |
| agent-team-development | End-to-end Agent Teams orchestration with worktree isolation and cherry-pick integration |
| rust-coding | Idiomatic Rust guidance: data modeling, traits, macros, build-speed best practices |
| textual | Reference skills for the Textual Python TUI framework — valid CSS properties and complete widget API with reactive attributes |
| command-watchdog | Idle-hang detection for every Bash command — kills silently-stuck runs after a configurable timeout, and wait loops whose targets stop progressing |
| python-scripting | One-off Python helpers, practical typing, standalone-file quality checks, and standard-library macOS automation |
| python-development | Deep Python standards, testing, repository tooling and quality checks, concurrency, the full typing specification, and focused type tightening |
| typescript-development | Deep TypeScript standards, testing, project tooling, modules and packaging, focused official references, and low-churn type tightening |
| worktree-guard | Asks before any Edit/Write/NotebookEdit that targets a repository's main checkout (Codex: blocks the apply_patch), and tells the agent at session start to work in a git worktree |
For packages that aren't available as plugins (statusline, claude-optin, git-utils), use the interactive TUI installer (implemented in packages/installer/):
npm install
npm run install-packagesUses a flat checklist. Navigate with ↑↓, toggle with space, view details with i, apply with enter. Only packages/ entries are shown — plugins are installed via the Claude Code marketplace.
enter applies whatever is pending — installs, removals, or both. With nothing selected it re-applies the packages already installed, so it doubles as a repair/confirm pass: unchanged files report already up to date and are not rewritten.
To install one or more packages by name without the TUI (fully non-interactive):
npm run install-package statuslineNames are matched case-insensitively against package IDs, package labels, and individual item names. Exits non-zero if any name is not found or if any install fails.
Plugins are installed by invoking the Claude Code CLI, never by copying their files into ~/.claude/:
npm run install-pluginsThis runs claude plugin install <plugin>@cjthompson-claude-code-config --scope user for every plugin under plugins/. It is idempotent — a plugin already at the version declared in .claude-plugin/marketplace.json runs no command and reports Already installed.
Two things to know:
- It installs the marketplace's published catalog, not your working tree. The marketplace resolves to the GitHub repo, so local uncommitted plugin edits are not what gets installed. Commit and publish first, or run
claude plugin marketplace update cjthompson-claude-code-config. - A restart (or
/reload-plugins) is required before a plugin change takes effect.
If the claude binary is not on PATH, the installer reports the manual /plugin marketplace add and /plugin install commands and installs nothing — it never falls back to copying files, because a copy publishes the plugin's assets a second time under unprefixed names (a plugin style output-styles:Terse would also appear as a bare Terse).
Custom skills for Claude Code, located in plugins/<name>/skills/. Each skill is a standalone Claude Code plugin with its own .claude-plugin/plugin.json.
Capture tasks inline with task:, fix:, or todo: prefixes. Claude and Codex share one agent-neutral database by default: ~/Library/Application Support/project-tasks/tasks.db on macOS, ${XDG_DATA_HOME:-$HOME/.local/share}/project-tasks/tasks.db on Linux, and %LOCALAPPDATA%\project-tasks\tasks.db on Windows (falling back to %APPDATA%). PROJECT_TASKS_HOME overrides the directory containing tasks.db. On first use, legacy Claude or Codex databases are detected but never migrated without explicit user approval. Any migration must be dry-run and backed up before its applying step; legacy stores remain unchanged until then. Tasks are dispatched to subagents for execution so the lead agent stays available. Completed tasks auto-update CHANGELOG.md.
Commands: task: <desc>, fix: <desc>, todo: <desc>, list tasks, run task #N, run all tasks, update changelog
Slash commands (Claude Code only): /project-tasks:init (initialize the DB and load the skill), /project-tasks:task-add, task-update, task-read, task-list, task-run, and the plan-* equivalents, plus /project-tasks:menu for a guided picker with a "More actions" reference of everything else.
Project identity: the task list is keyed by a per-project name. Create .claude/project-tasks.json at the project root with {"projectName": "github.com/owner/repo"} to lock in a stable identifier (recommended — keeps the list consistent across agents, worktrees, and clones). Without it, the skill falls back to the git remote URL or directory basename and prompts you to create the file the first time.
Plans (v2): a plan is an epic — one document plus the tasks derived from it. plan: <description> writes the document into the database; plan: /abs/path/to/doc.md offers to either import the file (and delete it) or link to it, leaving it authoritative on disk.
Plans use the P### ID space (for example, P001); ordinary tasks use the separate #NNN ID space (for example, #001).
Tasks created from a plan carry an anchor, a slug of the step heading they came from, so the document and the task list stay joined. When the document changes, plan propose re-reads it and stages the candidate, printing a diff; plan apply commits it or plan discard drops it. Staging is what makes review trustworthy — a command that diffed and committed at once could commit a document that changed after you read the diff, so plan apply verifies the bytes it promotes still hash to what was reviewed.
plan status renders the document annotated with each step's progress; plan progress is a standalone report (table plus a short written summary, or --counts for a machine-readable line). Plans are global, so a single plan can own tasks in several repositories.
Commands: plan: <desc|path>, list plans, show plan P00N, run plan P00N, update plan P00N, close plan P00N, cancel plan P00N
Upgrading to 2.0: the
task-dbhelper moved from 13 flat commands to a nested surface (task add,task deps blocked,plan note add, …). There are no aliases — every old name errors with a message naming its replacement. The database itself migrates additively in place; no task is renumbered and nothing is rebuilt. Only the skill invokes the helper directly, so this matters only if you scripted against it.
Output formats: read commands (
task get,task list,task deps blocked,plan get,plan list,plan tasks,plan note list, …) accept--format md|json|pipe. The default ispipe, sotask get,plan get, andplan note listno longer print JSON unless you pass--format json. JSON output is always one object keyed by part name, for example{"task":[{…}]}.
Evaluates multi-task workloads and selects the most cost-efficient orchestration approach: solo, parallel agents, sequential subagents, or Agent Teams. Analyzes file overlap and dependency graphs to determine isolation strategy, then hands off to the appropriate execution skill.
End-to-end Agent Teams orchestration for cross-cutting work requiring inter-agent communication. Manages team creation, worktree isolation, cherry-pick integration, and shutdown ordering. Requires CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS to be enabled.
Guides Claude in writing idiomatic Rust code with proper data modeling, traits, impl organization, macros, and build-speed best practices. Automatically triggers when working on .rs files or projects with a Cargo.toml.
Concise guidance for one-off helpers and standalone Python scripts. It loads before shell-based Python invocations, keeps incidental coding-session helpers standard-library-only and proportionate, covers practical type safety and Ruff and ty checks for standalone files without a governing repository toolchain, and supports macOS utilities that run with /usr/bin/python3 using only Python 3.9-compatible standard-library imports. Stable macOS command-line utilities may be invoked through subprocess when Python has no suitable API.
Deeper project-level guidance for production Python design, pytest strategy, existing and new repository toolchains, repository-scoped formatting, linting and type checking, asyncio and concurrency, and systematic annotation tightening. It vendors a commit-pinned copy of the complete Python typing specification and Honnibal's tighten-types workflow; run node plugins/python-development/scripts/sync-typing-references.mjs --check to verify the offline snapshot.
Framework-neutral, project-level guidance for production TypeScript design, runtime-boundary validation, runtime and compile-time testing, repository-first tool configuration, ESM/CJS and package compatibility, difficult type-system questions, and focused annotation tightening. It vendors a commit-pinned, curated subset of Microsoft's official Handbook, modules, declaration-file, and TSConfig documentation; run node plugins/typescript-development/scripts/sync-typescript-references.mjs --check to verify the offline snapshot.
The plugin ships a TypeScript 7 language server at .lsp.json for .ts/.tsx/.mts/.cts. The config launches ${CLAUDE_PLUGIN_ROOT}/scripts/typescript-lsp.mjs, an LSP-aware recovery proxy. It delegates all executable discovery to the unchanged scripts/typescript-lsp.sh --check control path: $TS_LSP_BIN → project ./node_modules/.bin/tsc (only if it reports TypeScript 7) → $PATH → common Homebrew paths. That project-local lookup is intentional. Install TypeScript 7 globally (npm i -g typescript@7), in the project, or set $TS_LSP_BIN.
Unlike a generic restart loop, the Node proxy retains current open-document text, configuration, and workspace changes. If native tsc crashes, it retries five times with a 250 ms–4 s exponential backoff, internally initializes a replacement, replays that state, and then releases up to 10 seconds/1 MiB of queued client traffic. Diagnostics go only to stderr; after recovery is exhausted, it exits nonzero so Claude Code's maxRestarts: 3 creates a fully fresh session. The Bash script remains directly runnable as the lower-complexity comparison launcher.
Custom Claude Code hooks, located in plugins/<name>/hooks/. Like skills, each is a standalone plugin with its own .claude-plugin/plugin.json.
A PreToolUse hook on the Bash tool. Every command runs under an idle-hang watchdog: it tees output live and kills the command if both stdout/stderr and the process group's cumulative CPU time stay flat for a configurable window (default 90s; hooks/watchdog-patterns.txt sets per-command overrides, e.g. rspec and .sh scripts). A slow-but-working command (silent, but burning CPU) is left alone; a true hang (silent and CPU-flat) gets killed and dumps a diagnostic (ps tree + a sample stack trace) before doing so. Wrapped commands always start at the lowest CPU priority (nice 20 on macOS, 19 elsewhere), which their descendants inherit, so long builds and test runs don't bog the machine down. WATCHDOG_NICE is ignored, including for RTK rewrite decisions. If priority cannot be set, the watchdog exits with code 125 without running the command. It also kills the command immediately if the watchdog's parent process exits. If rtk is installed, its token-saving rewrite is applied first. RTK uses the same lowest priority and retains its 15-second runtime cap; CPU contention can cause it to time out and skip rewriting.
The same plugin and watchdog engine support Claude Code and Codex. Codex maps both shell commands and exec_command to the Bash hook protocol, including nested tool calls from code mode. The hook supervises those shell tasks; it does not change the priority of Codex itself or independently running services. Packaging was verified with Codex CLI 0.159.3.
macOS sandbox limitation: Codex CLI 0.159.3's workspace sandbox denies setpriority. In that context, wrapped commands exit 125 without executing the task. Retry only through Codex's normal approval flow for an execution context that permits priority changes and process inspection. The plugin does not request escalation or disable sandboxing automatically, and never falls back to normal priority. This permission requirement also applies to any other restricted execution environment that denies the watchdog's process operations.
Interactive sessions are unsupported: The watchdog pipes task stdout and stderr even when Codex requests tty: true, so terminal UI behavior, colors, and buffering can change. Under a controlling terminal the task runs in a separate background process group; reading terminal stdin can stop it with SIGTTIN, and later write_stdin input does not move it to the foreground. Such a stopped task or a prompt waiting without output/CPU progress is still killed by the idle timeout (90 seconds by default). Use this plugin for noninteractive tasks; it does not preserve full terminal behavior or exempt interactive sessions from supervision.
From the repository root, install in Codex with:
codex plugin marketplace add .agents/plugins
codex plugin add command-watchdog@cjthompsonOpen /hooks in Codex to review and trust the plugin's hook before using it. Installation alone does not trust hooks; changed definitions require another review. See Codex hooks and plugin packaging.
Interrupting or terminating the watchdog (SIGINT, SIGTERM, or SIGHUP) forwards that signal to the task group, forces remaining group members to stop, and reaps its direct child before exiting with 128 + signal. SIGKILL cannot be caught and cannot trigger this cleanup. Command stdout and stderr are streamed together on the watchdog's stdout; normal task exit codes are preserved.
Wait loops. A sleeping until or while loop with a simple pgrep, grep -q, or file-test condition is judged by what it waits on, not by its own echo -n . output or the CPU of its checks. Ordinary work loops such as while read …; do curl …; sleep 1; done retain normal output based idle detection:
pgrep [OPTIONS] PATTERN— PIDs selected bypgrepitself, so filters such as-uand-Papply. Other watchdogs, wait-loop shells, and their checker processes are ignored; an unrelatedtail,find, orrgcan still be a target. Abash -cwrapper running real work counts, including its children's CPU. CPU already accrued by a newly observed worker also counts. In a direct wait-for-exit condition (until ! pgreporwhile pgrep, including/usr/bin/pgrep), no real match for longer than onesleepcycle triggerstarget-gone. A failingpgrepquery does not count as activity. Shell-expanded arguments and unsupported options are skipped;-qis supported.- File paths (
/…,~/…,./…, relative ones resolved through an earliercd) — growth or mtime changes count, as does CPU of processes holding the file open. Files the loop writes itself (>,>>,tee) and anything the shell would expand ($var, backticks) are ignored. - Work inside the loop — a long-lived non-shell, non-helper process (e.g.
bin/rspecrun by the loop body). Loop output counts only while one exists.
If none move for the idle window the loop is killed (poll-idle). A loop with no parseable target keeps the normal rules plus a 30-minute cap (WATCHDOG_POLL_CAP). Tests: /usr/bin/python3 -m unittest discover -s plugins/command-watchdog/tests -v.
To add a pattern, edit plugins/command-watchdog/hooks/watchdog-patterns.txt — one <regex> [idle_seconds] per line. See the file's header comment for the exact matching rules.
Keeps agent file edits out of a repository's main checkout so parallel sessions and agents don't tangle uncommitted work. Supports Claude Code and Codex from one hooks/hooks.json. Two hooks:
PreToolUseonEdit|Write|NotebookEdit|apply_patch— resolves the repository containing each edited file (not the session's working directory). A file is gated when it is in a main checkout (the working tree whose git dir equals the common dir). Files in a linked worktree, outside any repository, or in a bare repository pass silently. Any internal error fails open.- Claude Code — returns
permissionDecision: "ask", so you approve or reject the edit. Approving is the per-edit bypass. - Codex — returns
permissionDecision: "deny". Codex parses"ask"but does not support it yet (it logs a hook failure and lets the edit through), so blocking is the only effective gate. Every path in the patch's*** Add File:,*** Update File:,*** Delete File:, and*** Move to:headers is checked.
- Claude Code — returns
SessionStart— injectshooks/worktree-rule.mdas context: work in a worktree, treat the prompt or denial as the cue to create one, and honor user bypass phrases such as "edit main directly".
To disable the guard for a whole session — the only bypass in Codex — launch claude or codex with WORKTREE_GUARD_DISABLE=1. Shell-based writes (sed -i, redirects) are not intercepted.
Install in Codex from the repository root with codex plugin marketplace add .agents/plugins and codex plugin add worktree-guard@cjthompson, then review and trust the hooks in /hooks.
Tests: /usr/bin/python3 -m unittest discover -s plugins/worktree-guard/tests -v.
Custom Claude Code output styles, located in plugins/output-styles/. They ship with the output-styles plugin — installing it via the Plugin Marketplace is all that's needed. There is no package install step, and nothing is copied into ~/.claude/output-styles/.
Because they are plugin-provided, the style names are namespaced with the plugin name. The prefix is required — a bare Terse matches no style, and Claude Code does not report an error when a configured style name fails to resolve; it silently falls back to default behavior.
| Style | Name to use | Description |
|---|---|---|
| Concise | output-styles:Concise |
Terse one-or-two-sentence answers; action lists are captured as tasks rather than buried in prose |
| Terse | output-styles:Terse |
Headline-and-bullet answers with all process narration stripped; every reply reporting work closes with a Result status block; detail loads only on request |
Select one for the current project:
/output-style output-styles:Terse
That writes to the project's .claude/settings.local.json. To change the user-level default instead, edit ~/.claude/settings.json by hand — /output-style and /config always write project-local, and there is no scope flag:
{
"outputStyle": "output-styles:Terse"
}Run /output-style with no argument to list the available styles; the configured value must match one of the listed names exactly.
A two-line powerline-style statusline for Claude Code showing session metrics and API quota usage. Located in packages/statusline/. Install via the TUI installer.
8/12 3:45 PM ▶ Opus 4.6 │ $2.10 │ $12.60/hr │ 45% ████░░░░ │ ~1h1m left │ +100 -30 │ 10m ▶ ~/d/my-project ▶ improve-auth ▶
5h 33% ████░░░░░░░░ 1h57m (2:00PM) │ 7d 16% ██░░░░░░░░░░ Fri 10:00AM │ (3m old) ▶
Both lines are width-aware — segments drop progressively as the terminal narrows.
Workspace-level git status and sync tools. Located in packages/git-utils/. Install via the TUI installer or npm run install-package git-utils (installs repos to ~/.local/bin/).
repos scans every sub-repo in a workspace directory and reports branch, ahead/behind status, local changes, and open PRs for each. Run repos --sync to non-interactively pull/push repos that are in sync range. Requires git, gh, and jq.
A curses TUI to manage per-repo Claude Code opt-ins across four tabs: Plugins (with their skills and agents), MCP servers (every server Claude Code loads from disk — .mcp.json files up the directory chain, ~/.claude.json user and local scope, managed settings, and enabled plugins — grouped by source file), individual Skills (personal, project, and active-plugin, each with its own on/name-only/user-invocable-only/off state), and Trust (Claude Code's per-project trust flag in ~/.claude.json, also scriptable via --trust, --untrust, and --trust-status). Shows the effective state and where it comes from (user / project / local settings, with project settings taken from the git root) and lets you toggle a local override. Located in packages/claude-optin/. Install via the TUI installer or npm run install-package claude-optin (installs to ~/.local/bin/), then run claude-optin from inside a repo (assuming ~/.local/bin is on your PATH).
Toggles are written to <repo>/.claude/settings.local.json (gitignored, personal); with --global/-g/--user they edit the user-level defaults in ~/.claude/settings.json instead.