claude-skills
CLAUDE.md0 starsChanged 2 months agoMITView on GitHub
A curated marketplace of Claude Code plugins for AI/ML engineering workflows. Contains:
- Reads credentials
- Commits and pushes
In this repository5 other files it gives its agents.
- acli-managerSkill
- jira-managerSkill
- nemo-builderSkill
- pdf-design-systemSkill
- ste-writingSkill
The file
We split this CLAUDE.md into the rules it gives an agent
6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 91
Design constraint: No SMTP. Drafts are APPENDed to the IMAP Drafts folder with the \Draft flag.
- Distinctive: line 95
Mandatory for every Rust plugin in this repo: Every Rust crate that ships as a user-installable binary plugin MUST have:
- Distinctive: line 108
Commit with a message referencing the version.
- Very specific: line 114
All third-party actions in both workflows are pinned to commit SHAs (not tags) with a human-readable version comment, per supply-chain …
- Very specific: line 347
Every Rust crate in this repo must pass cargo fmt, cargo clippy, and cargo test before commit:
- Very specific: line 358
Run cargo fmt after any code change.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
Project Overview
A curated marketplace of Claude Code plugins for AI/ML engineering workflows. Contains:
- NeMo Builder (
nemo-builder/) -- NVIDIA NeMo 2.0 framework skill for AI development lifecycle (data prep, training, deployment). Documentation-only skill with reference guides and Python examples. - Jira Manager (
jira-manager/) -- Jira ticket generation and Server API integration. Hybrid skill with both text generation templates and Python API tools. - ACLI Manager (
acli-manager/) -- Atlassian CLI (acli) skill for managing Jira Cloud and Confluence Cloud from the command line. Documentation-only skill with command reference and workflow guides. - Python Dev (
hooks/) -- PreToolUse pre-commit hook: ruff (lint, format, import sort) + ty (type check) for Python, yamllint for YAML. Runs on staged files beforegit commit. - PR Reviewer (
pr-reviewer/) -- PR/MR code review with GitHub and GitLab support (including self-hosted). Command (review-pr) + 7 agents. Fetches existing discussion and Jira/Linear context, validates findings with file:line enforcement, posts inline or single comments with user permission. - Autoresearch (
autoresearch/) -- Autonomous hyperparameter/model optimization with parallel GPU researchers using Agent Teams. Command (autoresearch) + lead skill + researcher agent. Coordinates worktree-isolated experiments across multiple GPUs, tracks metrics, broadcasts learnings. - PDF Design System (
pdf-design-system/) -- Skill + command for converting markdown to PDF using a canonical editorial design (navy/gold/cream, Fraunces + Source Serif 4 + JetBrains Mono). Default path uses only the skill's canonical stylesheet. Per-project customization (wordmark, palette) is opt-in via/pdf-design-system:init, which scaffoldsdocs/pdf-overrides.csswith:roottoken redeclarations only. - iCloud MCP (
icloud-mcp/) -- Local Rust MCP server for Apple iCloud Calendar (CalDAV vialibdav) and Mail (IMAP viaasync-imap+tokio-rustls). Read + create-only: events can be created; mail can only be saved as drafts via IMAP APPEND (no SMTP). Credentials viaAPPLE_ID/APPLE_APP_PASSWORDenv vars with macOS Keychain fallback. - Monobank MCP (
monobank-mcp/) -- Local Rust MCP server + CLI for the Monobank Personal API. Ingest plugin in the personal-finance design: ownsmono_*tables in the shared~/finances/data.dbSQLite store. Tool surface, CLI, and configuration are documented in the "Monobank MCP Development" section below. - Privat24 Skill (
privat24-skill/) --uv-managed Python skill that imports Privat24 web-cabinet XLSX statement exports into the shared~/finances/data.db. Ownsprivat_*tables. Standalone (works without monobank-mcp or the personal-finance umbrella). Package layout and conventions are in the "Privat24 Skill Development" section below. - Personal Finance (
personal-finance/) --uv-managed Python umbrella skill for query / report / categorize / budget over the shared~/finances/data.db. Owns thepf_*family of tables (categorization rules + overrides, budgets + drafts, category registry, import audit). Reads<bank>_transactionsvia runtime UNION ALL discovery so it works with any subset of ingest plugins installed. Budget planning is conversation-driven - DB is source of truth, Google Sheets is an on-demand rendered view. Five CLI entry points (pf-query,pf-report,pf-categorize,pf-rules,pf-budget) follow the same JSON-output contract as the ingest plugins. Layout and rule-loading conventions are in the "Personal Finance Umbrella Development" section below. - STE Writing (
ste-writing/) -- Prose rewriting into a controlled plain technical style for English (ASD-STE100) and Ukrainian (adapted STE + DSTU 3966:2009), with symmetric strict and STE-flavored modes. Documentation-only skill with per-language rule references. - PCB Design (
pcb-design/) -- Hardware design for boards whose copper is part of the circuit (RF, controlled impedance, antennas). Three skills (sim-loop,pcb-design,rf-frontend) + 4 read-only reviewer agents +/pcb-design:initscaffolder + spec templates. Documentation-only; extracted from a Ku-band receive antenna project with every project-specific number left behind in that project'sspec/. Boundary rule and layout are in the "PCB Design Development" section below.
Cross-plugin contract: docs/transactions-schema.md (v1.0) is the row-shape contract that monobank-mcp and privat24-skill follow for their <bank>_transactions tables; personal-finance reads through it.
Plugin Architecture
Most plugins use skills with the same structure:
SKILL.md-- Main entry point that Claude reads when the skill activatesreferences/-- Detailed guides loaded on-demand (referenced from SKILL.md)examples/-- Code examples and sample outputs
PR Reviewer uses a different pattern - command + agents:
commands/review-pr.md-- Orchestrator command invoked via/pr-reviewer:review-pragents/-- 7 specialized review agents launched by the command
Autoresearch uses command + skill + agent:
commands/autoresearch.md-- Entry point invoked via/autoresearch:autoresearch, parses YAML config and validates environmentskills/autoresearch/SKILL.md-- Lead agent coordination program (worktree creation, researcher spawning, experiment loop)agents/researcher.md-- GPU researcher agent that runs experiments in isolated worktreesskills/autoresearch/scripts/-- Shell/Python utilities (worktree-setup.sh, harvest.py, cleanup.sh)
PCB Design uses multiple skills + agents + command in one plugin directory:
skills/<name>/SKILL.md-- three sibling skills, each with its ownreferences/agents/-- 4 reviewer agents, auto-discovered (not listed inmarketplace.json)commands/init.md--/pcb-design:initassets/spec/-- YAML templates the command copies into a target project
Agents are only discovered under the plugin root. A plugin whose source is "./" has the repo root as its plugin root, so <plugin>/agents/*.md sits one level too deep. Observed 2026-10-18: pr-reviewer is installed at user scope and none of its 7 agents appear as agent types; autoresearch/agents/researcher.md has the same layout. Any new plugin shipping agents therefore uses a subdirectory source ("source": "./pcb-design"), like the newer plugins do. Worth re-checking against pr-reviewer before relying on it, since that command launches its agents by name.
The marketplace is configured in .claude-plugin/marketplace.json.
Personal Finance Architecture
Three plugins share ~/finances/data.db (SQLite, WAL) by partitioning the table namespace:
| Plugin | Language | Owns | Touches |
monobank-mcp | Rust | mono_* | only mono_* |
privat24-skill | Python | privat_* | only privat_* |
personal-finance | Python (uv) | pf_* (categorization rules / overrides) | reads mono_* + privat_* via runtime UNION ALL discovery |
Each ingest plugin migrates only its own tables. The umbrella plugin auto-detects available <bank>_transactions tables via sqlite_master and builds a UNION ALL view at query time. The shared row shape (signed minor units, ISO 4217 numeric currency codes, <bank>_<native_id> ids) is documented in docs/transactions-schema.md and enforced by convention - not by code.
Atomicity contracts that every store implementation must hold:
- INSERTs and sync-cursor / version-row updates share one explicit
BEGIN/COMMITtransaction. A kill mid-chunk never leaves a half-applied state. - Migrations run inside an explicit transaction; PRAGMAs that can't live in a transaction (
journal_mode) are set on the connection before the migration. Python: avoidsqlite3.Connection.executescript- it issues an implicit COMMIT first. - IDs are globally unique with a per-bank prefix (
mono_<api_id>,privat_h_<sha16>), and ingests useINSERT OR IGNOREso re-pulling / re-importing is idempotent.
iCloud MCP Development
Rust binary plugin. Not a skill - it ships as a standalone MCP server registered via icloud-mcp/.mcp.json, which spawns scripts/launch.sh (a thin wrapper that ensures the binary is on disk via install-binary.sh, then execs it). The wrapper exists because SessionStart hooks fire only on new sessions, not on /reload-plugins, so the MCP transport could otherwise race the hook and surface ENOENT.
Build:
cd icloud-mcp && cargo build --releaseThe binary lands at icloud-mcp/target/release/icloud-mcp. For plugin users it ships prebuilt from GitHub Releases; .mcp.json resolves to it indirectly through scripts/launch.sh.
Key files:
src/main.rs-- entry point,IcloudServerstruct with#[tool_router], 10 tools (incl.auth_status),--probeCLI mode, stdio transportsrc/caldav.rs-- thin wrapper aroundlibdav::CalDavClient(list_calendars, list_events, get_event, search_events, create_event)src/imap_client.rs--async-imapovertokio-rustls(list_folders, search, get_message, create_draft via APPEND)src/config.rs-- env-or-Keychain credential loadingsrc/error.rs-- McpError helpersscripts/launch.sh-- runsinstall-binary.shthenexecs the binary; referenced by.mcp.jsonscripts/install-binary.sh-- idempotent: downloads release tarball matchingCargo.tomlversion, verifies SHA256, falls back tocargo buildif no prebuilt artifact for the platform. It short-circuits ONLY when the binary already on disk answers--versionwith theCargo.tomlversion; anything else is deleted and re-fetched. Do not weaken that back to a bare[[ -x ]]test - see the gotcha below.hooks/hooks.json--SessionStarthook that pre-warms the binary so the first MCP tool call is not the one paying the download costcommands/setup.md--/icloud-mcp:setupinteractive wizard for first-time credential capture
Configuration: Environment variables APPLE_ID and APPLE_APP_PASSWORD (a 16-char app-specific password from account.apple.com). On macOS, password can also live in Keychain under service icloud-mcp, account $APPLE_ID.
Design constraint: No SMTP. Drafts are APPENDed to the IMAP Drafts folder with the \Draft flag; the user reviews and sends them manually in iCloud Mail. This keeps the server from producing external side-effects.
Rust binary plugin releases
Mandatory for every Rust plugin in this repo. Every Rust crate that ships as a user-installable binary plugin MUST have:
- A
.github/workflows/release-<plugin>.ymlworkflow modeled onrelease-icloud-mcp.yml(the canonical template). Copy it whole-file when adding a new plugin and only change the plugin name + crate path; never invent a new release shape. - A
<plugin>/scripts/install-binary.shthat downloads from the matchinghttps://github.com/<owner>/<repo>/releases/download/<plugin>-v${version}/URL and verifies SHA256. - A
<plugin>/scripts/launch.shreferenced from<plugin>/.mcp.jsonthat runsinstall-binary.shthenexecs the binary. - Prebuilt artifacts for all 4 standard targets (darwin arm64/x64, linux x64/arm64) on every released version - i.e. a release tag pushed for every
<plugin>/Cargo.tomlversion bump. A cargo-build fallback ininstall-binary.shis for unsupported platforms, NOT a substitute for missing prebuilt artifacts. - The marketplace entry's
versionfield in.claude-plugin/marketplace.jsonalways matches<plugin>/Cargo.toml'sversion. The workflow's tag assertion catches drift; the matching marketplace entry is the user-facing contract.
Both existing Rust plugins (icloud-mcp, monobank-mcp) follow this pattern. There are two workflows - .github/workflows/release-icloud-mcp.yml and release-monobank-mcp.yml - that are structural copies; bug fixes to one usually apply to the other.
To cut a new version of <plugin>:
- Bump
<plugin>/Cargo.toml,<plugin>/Cargo.lock, and.claude-plugin/marketplace.json(matching entry) to the same version. - Commit with a message referencing the version.
git tag <plugin>-v<X.Y.Z> && git push origin <plugin>-v<X.Y.Z>.- Workflow builds 4 targets in parallel (macos-26 host cross-compiles to both darwin arches, ubuntu-24.04 + ubuntu-24.04-arm for Linux), packages tar.gz, publishes Release with SHA256SUMS.
The workflow asserts that the pushed tag equals <plugin>-v${CRATE_VERSION} and fails fast otherwise, so a version-marker drift between Cargo.toml and the tag is caught immediately rather than producing artifacts under the wrong name.
All third-party actions in both workflows are pinned to commit SHAs (not tags) with a human-readable version comment, per supply-chain hardening. Dependabot (.github/dependabot.yml) opens weekly PRs to bump SHAs as upstream cuts releases.
Monobank MCP Development
Rust binary plugin. Same shipping pattern as icloud-mcp (.mcp.json -> scripts/launch.sh -> scripts/install-binary.sh -> binary). 4-target prebuilt artifacts plus cargo fallback for other platforms.
Build:
cd monobank-mcp && cargo build --release
cargo fmt --check && cargo clippy --all-targets -- -D warnings
cargo test # 33 unit + 44 integration testsKey files:
src/main.rs-- clap dispatch overinit/accounts/backfill/sync/serve/--probe; defaults toserve(MCP stdio) when no subcommandsrc/api.rs-- thin reqwest wrapper aroundapi.monobank.uawithX-Tokenauth; UTF-8-safe error-body truncationsrc/store.rs--rusqlitestore; per-chunk atomic INSERT OR IGNORE + sync-cursor UPSERTsrc/sync.rs-- shared engine for CLIsyncand MCPensure_synced; deadline-bounded, configurableretry_backoffsrc/backfill.rs-- cold-start backfill, resumable on Ctrl-Csrc/migrations.rs-- embeds the numberedschema/mono_00N_*.sqlfiles viainclude_str!; applies inside explicitBEGIN/COMMIT(NOTexecute_batch- it auto-commits)src/mcp/tools.rs-- 3#[tool]methods + setup-required error wiringsrc/util/ratelimit.rs-- shared 1 req / 60s token bucket viatokio::sync::Mutexschema/mono_001_initial.sql--mono_accounts,mono_transactions,mono_sync_state,mono_import_runs,mono_schema_version. PRAGMAs live instore.rs::init, NOT here (journal_mode can't change inside a tx)schema/mono_002_account_balance.sql/mono_003_account_closed.sql-- balance + credit limit columns;closed_atfor accounts client-info no longer lists
Configuration: MONOBANK_TOKEN env var primary, OS keychain fallback (service monobank-mcp, account api-token) via the keyring crate. Optional ~/finances/config.toml overrides data_dir, api_base, api_min_interval_seconds, ensure_synced_default_budget, sync_freshness_skip_seconds.
Behavioural notes worth knowing:
monobank-mcp syncagainst a fresh account (no prior backfill) auto-seeds the cursor atnowrather than erroring. Runbackfill --from <date>explicitly for historical rows.ensure_syncedreturnspartial: truewhen the wall-clock budget expires; Claude is expected to re-invoke or tell the user to run the CLI.- Only
caught_up: truemeans the DB is current (0.4.0+).rows_added: 0is emitted both for "fetched the window, nothing new" and for "never fetched this account"; the per-accountstatus(synced/partial/unattempted/failed/skipped_fresh/up_to_date/seeded) andchunks_fetchedare what separate them. Before 0.4.0caught_upused a 24h cursor-lag tolerance and ignored unfetched chunks, which let a budget-starved run report a missing day of spending as up to date. - Accounts are synced stalest-cursor-first (
Store::list_account_ids_by_staleness), not by id. The ~2-API-callensure_syncedbudget would otherwise serve the same first two accounts forever. - Closed accounts (0.5.0+):
accountsand backfill apply client-info throughStore::reconcile_accounts, which stampsmono_accounts.closed_aton any live row the response no longer lists and clears it if the account comes back. Sync and balance checks skip closed rows; an explicit--accountstill reaches them. Rows are never deleted - transactions reference them. An empty client-info closes nothing. Before 0.5.0 a card closed in the app stayed in the queue, got HTTP 400 "invalid 'account'" on every sync, and pinnedcaught_upat false. suspected_missing_rowscomparesmono_accounts.balance_minoragainst the running balance on the newest stored transaction. A mismatch means rows are missing inside an already-walked window -synccannot fix it, onlybackfill --from. It is deliberately NOT part ofcaught_up. The snapshot is refreshed byaccounts/backfill only, so a snapshot older than the newest row reports "unknown", never "matches".- The "newest row" balance is derived, not picked (0.5.1+,
store::closing_balance): rows sharing a second carry no stored order, so it takes the newest row that is alone in its second as the anchor and adds every newer amount. Before 0.5.1ORDER BY ts, idcould land on the inbound leg of a same-second transfer pair (FOP-UAH pass-through) and raisesuspected_missing_rowson a complete account. With no anchor in the tail the verdict isambiguous_order(not comparable). --probeexits non-zero on any failure (auth / config / connectivity) so shell wrappers can detect failure via$?without re-parsing JSON.
Privat24 Skill Development
Python skill, uv-managed. Imports XLSX exports from privat24.ua/statement into the shared store. Owns privat_* tables.
Build / test:
cd privat24-skill && uv sync
uv run pytest -q # 35 tests
uv run ruff check src tests fixtures
uv run python fixtures/generate.py # regenerate synthetic XLSX fixturePackage layout (matters because of importlib.resources):
privat24-skill/
pyproject.toml # uv-managed; deps: openpyxl, tzdata
skills/privat24-import/SKILL.md # how Claude invokes the CLI
src/privat24_import/
__main__.py # CLI entry; `uv run privat24-import import <file>`
parsers/{detect, web_xlsx}.py
core/{store, dedup, currencies}.py # NOTE: named `core/` not `lib/` because the
# root .gitignore drops `lib/` (Python venv pattern)
schema/privat_001_initial.sql # in-package; loaded via importlib.resources so
# the wheel layout works too. pyproject.toml has
# [tool.setuptools.package-data] for *.sql.
fixtures/{generate.py, sample_web.xlsx} # seeded RNG; never edit XLSX by hand
tests/ # detect / parse / dedup / store / migrations /
# integration / currenciesConventions specific to this skill:
- Migration applies via individual
conn.execute(stmt)calls inside aBEGIN/COMMIT. DO NOT switch toexecutescript- per the stdlib docs it issues an implicit COMMIT first and silently closes the explicitBEGIN. - Naive Privat24 timestamps are Europe/Kyiv; the parser attaches
ZoneInfo("Europe/Kyiv")so stored unix is true UTC.tzdata>=2024.1is a hard runtime dep for Windows / slim Linux containers. - Account upsert and tx INSERTs share one transaction via
insert_transactions(account=AccountSpec). A failure rolls back both - no dangling account rows. ImportResultis aTypedDictwithLiteral["imported", "skipped", "unsupported", "error"]status. Pre-flight I/O failures (missing file, unwritable data dir) land asstatus: errorJSON, not as a traceback escaping stdout.- Fixture file is regenerated via
fixtures/generate.py; the committedsample_web.xlsxis the canonical reference for tests.
Personal Finance Umbrella Development
Python skill, uv-managed. Read-and-write side of the personal-finance loop: owns the pf_* family of tables (categorization rules + overrides, budgets + drafts, category registry, import audit), reads ingest plugins' <bank>_transactions tables through a runtime-discovered UNION ALL view. Five CLI entry points exposed via [project.scripts]; SKILL.md tells Claude which one to invoke for each user phrase.
Build / test:
cd personal-finance && uv sync
uv sync --extra sheets # add openpyxl for XLSX paths
uv run pytest -q
uv run ruff check src testsPackage layout:
personal-finance/
pyproject.toml # uv-managed; deps: pyyaml;
# optional [sheets] extra: openpyxl.
# Python >= 3.13
skills/personal-finance/SKILL.md # trigger phrases + invocation cookbook
commands/categorize.md # /personal-finance:categorize workflow
commands/status.md # /personal-finance:status workflow
# (sync -> categorize -> gate -> diff -> report)
src/pf_skill/
query.py report.py # read-only CLI entry points
categorize.py rules_cli.py
budget_cli.py # write CLI entry points
schema/ # pf_001 .. pf_005 .sql migrations,
# in-package via importlib.resources
rules/{mcc.json,description.yaml} # bundled seed rules, importlib.resources
common/
store.py view.py # SQLite + runtime UNION discovery +
# state-machine SQL splitter
queries.py reports.py # read helpers + report bundle
# (with auto-attached budget block)
rules.py categorizer.py # 4-source rule loader + apply pass
budget.py # planning + lifecycle + scanner +
# CSV/XLSX parsing + family view
cli.py currencies.py types.py
tests/ # store / view / queries / reports /
# rules / categorizer / budget
# (schema, import, planning, signals,
# family, export, lifecycle) +
# end-to-end CLIConventions specific to this skill:
- Same atomicity contract as the ingest plugins:
isolation_level = None, explicitBEGIN/COMMIT, individualconn.executecalls (NEVERexecutescript). Rule pass + overrides import are two SEPARATE transactions insideapply_rules- both idempotent (INSERT OR IGNOREontx_category,INSERT OR REPLACEoncategory_overrides) so a crash between them is safe to retry. - Rule priority is unified in
common/rules.py::DEFAULT_PRIORITY_BY_FIELD(counterparty 100 < description 200 < mcc 300 < explicit DB priority). Lower wins; ties broken by source then pattern.pf-rules addvalidates regex viare.compileBEFORE the INSERT (MCC patterns skipped - they are exact integer matches).Rule.matchesswallowsre.errorso a single bad rule does not break the wholepf-categorizepass. - Local YAMLs at
$DATA_DIR/rules/counterparty.local.yamland$DATA_DIR/rules/overrides.local.yamlare gitignored and silently optional. Overrides are UPSERTed intocategory_overrideson everypf-categorizerun. common/store.py::_split_statementsis a state-machine SQL splitter that tracksBEGIN ... ENDblock depth and single-quoted string literals. It's used by every migration; new migrations with triggers or string-embedded;ride on the same code path.- Budget data lives in
budget(one row per(period, currency_code, status)),budget_line,budget_draft_edit(per-draft undo log),category_registry,budget_import_run. Closed-budget triggers blockbudget_lineINSERT/UPDATE/DELETE while parentstatus='closed'. Drafts and active budgets coexist for the same(period, currency_code)during planning;commit_draftswaps them atomically. - Because drafts and actives coexist, anything reading
fetch_budgetoutput must filter blocks bystatus.pf-budget showreturns the active AND the draft block side by side while planning is in flight; an unfiltered consumer double-counts every draft line as an active one. start_drafthas two modes and picks by whetherperiodalready has an active budget (0.7.1+). Own active budget -> copy it in full, everykind,in_place: true(editing the current month;commit_draftreplaces the active budget, so a partial copy deletes the omitted lines). No active budget -> new month: most recent prior active period,kind='baseline'only,in_place: false(one_time belongs to the month it was planned for).--copy-fromoverrides the source;--copy-from ''starts blank.- Currency semantics:
amount_minoris in the account currency. The summary path joins to<bank>_accounts.currency_coderather than reading<bank>_transactions.currency_code(which is the operation currency). Foreign-merchant rows on a UAH card stay in UAH totals. - Output contract is shared across every
pf-*script: success → JSON stdout exit 0;CliError→{"ok": false, "error": ..., "type": ..., "details": {...}}stderr exit 1; uncaught → traceback + structured error stderr exit 2.common/cli.py::run_subcommandis the gate.detailscarries structured payloads (e.g. unknown-category suggestions on budget import) for callers to render rich error messages. - Budget status reporting leads with coverage: can the money cover the plan. That block is the ONE place currencies are combined - converted at the NBU rate fetched per report (
bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json, matched onr030), labelled as converted, with unconvertible currencies named rather than dropped. Every other section stays in its native currency.pf-budget diffhas no conversion flag; the report layer does it. - Planned spend is NOT
totals.target_minor(that mixes in plannedДохід/*rows). Derive it asreal_spend_minor + remaining_minor. - Budget planning is conversation-driven. The CLI emits structured signals (
pf-budget plan suggest) for Claude to phrase; Claude records each user decision as a singleplan add/update/removecall.pf-budget importexists as a side-door for bulk migration but is NOT the conversation path - the planning loop uses single-line edits exclusively.
Jira Manager Development
The only skill with executable code. Python package in jira-manager/.
Dependencies: Python >=3.10, jira>=3.10.0
Package management: Uses uv. Install with:
cd jira-manager && uv syncRun tools directly:
uv run jira-manager/tools/create_ticket.py
uv run jira-manager/tools/update_ticket.pyKey files:
tools/jira_client.py-- Core JiraManager class with full CRUD operationstools/create_ticket.py-- CLI entry point for ticket creation (reads JSON from stdin)tools/update_ticket.py-- CLI entry point for search/update operations
Configuration: Environment variables JIRA_SERVER_URL and JIRA_API_KEY (Personal Access Token).
PCB Design Development
Documentation-only plugin, three sibling skills plus agents, a command and YAML templates:
pcb-design/
├── skills/sim-loop/ run contract, validation gates, optimizer, openems
├── skills/pcb-design/ fab-profiles, kicad-cli, stackup-impedance,
│ dfm-order, ua-sourcing
├── skills/rf-frontend/ noise-budget, freq-plan, antenna-cp, filters
├── agents/ rf-engineer, sim-auditor, circuit-reviewer,
│ manufacturing-engineer
├── commands/init.md /pcb-design:init
└── assets/spec/ targets / substrates / mesh_rules templates,
fab_profiles (conservative, prototype_cn, ua_local)The boundary rule, which is the whole point of the plugin: the skills hold method, never a project's numbers. No band, no acceptance threshold, no material choice, no decision-log id. Those live in the consuming project's spec/*.yaml, which the skills declare authoritative. Any measured figure that stays in a reference is there as provenance for a mechanism ("measured on openEMS v0.37 on one Ku project"), is labelled as such, and must not read as a default.
Conventions specific to this plugin:
sim-loopis solver-agnostic; openEMS specifics live in exactly one reference (references/openems.md), so a SPICE or FEM project can use the skill without reading them.- Agents are read-only reviewers with a blocking verdict each (FAIL / NOT TRUSTED / NOT READY). They never edit project files and write only to their own agent-memory directory. Keep that contract when editing them - the consuming projects' review gates depend on it.
- Agents reference the skills by path (
references/<file>.md), not by inlining their content. When a reference is renamed, grepagents/too. - Templates in
assets/spec/ship with placeholders (0.0,null,unknown). A placeholder is honest; a plausible default becomes an unexamined design assumption in every project scaffolded from it.
Structural checks stand in for a test suite:
# skill names vs directories, orphan and dangling references, agent and
# command frontmatter, the agents' read-only contract, template typography
python3 pcb-design/scripts/check-structure.py
# the YAML leg of the same script needs pyyaml; with it, templates are parsed
uv run --with pyyaml python pcb-design/scripts/check-structure.pyExit code 1 lists one line per problem. Run it after editing any SKILL.md, agent or template, and before a release tag.
Hooks
Hooks live in hooks/ with config in hooks/hooks.json. The python-dev plugin uses a single PreToolUse hook on Bash that intercepts git commit commands:
hooks/pre-commit.sh-- Readstool_input.commandfrom stdin JSON, matches*git*commit*, then for staged files: auto-fixes Python with ruff, runs final ruff lint + ty type check, validates YAML with yamllint. Blocks commit (exit 2) if issues remain.- Pattern
*git*commit*(not*"git commit"*) to matchgit -C <path> committhat Claude Code generates.
Each plugin with hooks must be registered separately in marketplace.json -- do not bundle unrelated hooks with skill-only plugins.
Plugin Development
This repository is a Claude Code plugin. When creating or modifying skills, commands, hooks, agents, or plugin structure, prefer using skills from the plugin-dev plugin (e.g., /skill-development, /plugin-structure, /hook-development, /agent-development, /command-development).
Release Workflow
- Plugin version lives in two places: the plugin-internal file (
Cargo.toml/pyproject.toml) AND the matching entry in.claude-plugin/marketplace.json. Bump both in the SAME commit. The marketplace JSON is what/pluginreports as "latest"; if it lags,/plugin updateshows stale versions and re-runs of the cached install don't pick up new code.
Conventions
- SKILL.md files use YAML frontmatter for skill metadata
- Python code uses full type annotations;
jira-managertools return(success: bool, message: str, data: Optional)tuples on stdin/stdout JSON - CLI tools communicate via JSON on stdin/stdout
- Each plugin owns its own test suite where the language supports it:
- Rust plugins:
cargo test(icloud-mcp, monobank-mcp) - Python
uvplugins:uv run pytest -q(privat24-skill, personal-finance; jira-manager has atests/dir but most of its testing is manual via example scripts) - Documentation-only skills (nemo-builder, acli-manager, pdf-design-system, ste-writing, pcb-design) have no test suite; for those, the checks are structural (see
docs/pre-publish-checklist.md)
- Rust plugins:
Developer gotchas
.mcp.jsonplugin-vs-project duplication: Claude Code discovers<rust-plugin>/.mcp.jsontwice when a contributor has the repo cloned AND the plugin installed - once as plugin (CLAUDE_PLUGIN_ROOT defined, works) and once as project config (variable unset, fails). The plugin instance is the working one. To silence the noise for each affected plugin, extenddisabledMcpjsonServersin.claude/settings.local.json(e.g.["icloud", "monobank"]).- A stale binary can outlive a
/plugin update:/plugin updatecopies the plugin directory out of~/.claude/plugins/marketplaces/<mp>/<plugin>/including git-ignored files, so atarget/release/<plugin>left behind by an oldcargo buildfallback rides along into the NEW version directory.git pullnever removes it. Before 0.4.1 / 0.3.5install-binary.shexited on a bare[[ -x "$BIN_PATH" ]], so a directory labelled0.4.0happily ran 0.2.1 code, and icloud-mcp kept a Linux aarch64 ELF installed on a mac where it could not exec at all. Both scripts now compare--versionoutput againstCargo.toml. If you ever hit a plugin behaving like an older release, check<cache>/<version>/target/release/<plugin> --versionfirst, and clear the copy in the marketplace clone too. - gh CLI auth is ephemeral in dev containers: pushing to main with workflow file changes requires
workflowscope on the gh token (gh auth refresh -h github.com -s workflow). Plaingh auth loginonly givesgist, read:org, repo. - Privat24 timezones require
tzdata:ZoneInfo("Europe/Kyiv")would raiseZoneInfoNotFoundErroron Windows / slim Linux containers without the OS tz database, soprivat24-skill/pyproject.tomlpinstzdata>=2024.1. If you ever drop the dep, the CLI fails at module import, before any JSON output - the SKILL.md stdout contract relies on this. - Shared SQLite store is single-machine, single-user:
~/finances/data.dbmust not live on shared / cloud storage when more than one process can write. WAL is enabled defensively but cross-machine concurrent writes still corrupt SQLite.
Rust projects
Every Rust crate in this repo must pass cargo fmt, cargo clippy, and cargo test before commit:
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo testRules:
- Each Rust crate has a
rustfmt.toml(or inherits sensible defaults) and pins lint policy inCargo.tomlunder[lints]-- at minimumunsafe_code = "forbid"under[lints.rust]andclippy::all = warn(withpriority = -1) under[lints.clippy]. - Fix clippy warnings rather than suppressing them. Use
#[allow(...)]only with a comment explaining why. - Run
cargo fmtafter any code change. Do not hand-format -- let rustfmt own layout. cargo build --release --lockedmust succeed warning-free before pushing.- New test files for critical invariants (atomicity, retry behaviour, schema migrations) belong in
tests/(integration) rather than#[cfg(test)] mod testsblocks - integration tests are also what the release workflow runs.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

