Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "debussy",
"owner": {
"name": "André Polykanine",
"email": "ap@oire.me"
},
"metadata": {
"description": "André's Claude Code customizations — planning, review, documentation, .NET tooling, and opt-in coding-convention hooks.",
"version": "0.1.0"
},
"plugins": [
{
"name": "planning",
"source": "./plugins/planning",
"description": "Idea-to-execution pipeline: brainstorm, plan-make, plan-review, plan-exec."
},
{
"name": "review",
"source": "./plugins/review",
"description": "Project review and release-readiness auditing (Nigel + Codex)."
},
{
"name": "write-manual",
"source": "./plugins/write-manual",
"description": "Multi-agent pipeline for accessible, WCAG 2.2 AA desktop-app user manuals."
},
{
"name": "dotnet-tools",
"source": "./plugins/dotnet-tools",
"description": "Oire .NET coding-standards style corrector."
},
{
"name": "conventions",
"source": "./plugins/conventions",
"description": "Opt-in convention hooks: American English and no Claude-side git writes."
}
]
}
71 changes: 71 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: CI

on:
push:
branches: [master]
pull_request:

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Validate YAML frontmatter in markdown
run: |
python3 -c "
import yaml, sys, os
failed = False
for root, _dirs, files in os.walk('.'):
if '.git' in root:
continue
for f in files:
if not f.endswith('.md'):
continue
path = os.path.join(root, f)
with open(path, encoding='utf-8') as fh:
content = fh.read()
if not content.startswith('---\n'):
continue
end = content.find('\n---\n', 4)
if end == -1:
continue
try:
yaml.safe_load(content[4:end])
except yaml.YAMLError as e:
print(f'FAIL: {path}\n {e}')
failed = True
sys.exit(1 if failed else 0)
print('All markdown frontmatter is valid YAML')
"

- name: Validate JSON manifests
run: |
python3 -c "
import json, sys, glob
patterns = ['.claude-plugin/marketplace.json',
'plugins/*/.claude-plugin/plugin.json',
'plugins/*/hooks/hooks.json',
'settings/*.json']
failed = False
for pat in patterns:
for path in glob.glob(pat):
try:
json.load(open(path, encoding='utf-8'))
print('ok:', path)
except Exception as e:
print('FAIL:', path, e); failed = True
sys.exit(1 if failed else 0)
"

- name: ShellCheck
run: |
sudo apt-get update -qq && sudo apt-get install -y -qq shellcheck
find . -name '*.sh' -not -path './.git/*' -print0 | xargs -0 shellcheck

- name: Run hook tests
run: |
for t in tests/test-*.sh; do
echo "== $t =="
bash "$t"
done
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# OS / editor cruft
.DS_Store
Thumbs.db
desktop.ini
*.swp
*~
.idea/
.vscode/

# Windows null-device files (the very thing check-no-null-redirect prevents,
# committed here as a belt-and-braces guard in case one slips through)
nul
**/nul

# Local-only Claude Code state that must never be committed from this repo
.credentials.json
settings.local.json
52 changes: 52 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Changelog

All notable changes to this repo are recorded here. Format loosely follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Added
- Plugin marketplace (`.claude-plugin/marketplace.json`) exposing five plugins:
- **planning** — brainstorm, plan-make, plan-review, plan-exec.
- **review** — project-analyst (Nigel) + project-audit.
- **write-manual** — accessible user-manual pipeline.
- **dotnet-tools** — Oire .NET style corrector.
- **conventions** — opt-in convention hooks with a `hooks/hooks.json`.
- Hooks (in the conventions plugin), organized by applicability:
- `cross-platform/check-american-english` — PowerShell + Bash runners sharing
one word map (the Bash map is generated from the PowerShell source).
- `cross-platform/check-git-guard` — blocks `git commit`/`add`/`stage` and
`git mv`/`git rm` (PowerShell + Bash).
- `windows-only/check-no-null-redirect` — Windows-only; not ported to Unix.
- Manual hook path: `settings/` snippets (Windows + Unix) and
`install.* / sync.* / uninstall.*` helpers that copy the convention hooks
into/out of `~/.claude/hooks`.
- `CLAUDE.md`, human-facing `README.md`, `.gitignore`, and
`docs/marketplace-plan.md` (the packaging rationale).
- LICENSE attribution filled in (Apache-2.0, Copyright 2026 André Polykanine).
- Attribution to [cc-thingz by Umputun](https://github.com/umputun/cc-thingz):
the `planning` plugin is adapted from his MIT-licensed work. Added `NOTICE`
(retaining his MIT notice; Apache-2.0 and MIT are compatible), README credits,
and a per-plugin attribution note.
- CI workflow (`.github/workflows/ci.yml`): YAML-frontmatter validation, JSON
manifest validation, ShellCheck, and the hook test suite.
- `tests/` — bash tests for the cross-platform convention hooks
(`test-american-english.sh`, `test-git-guard.sh`).
- `plugin.json` polish: `homepage`, `repository`, `license` on every plugin.

### Fixed
- **Plugins now work when installed.** Skills referenced scripts at
`~/.claude/skills/...` (the old file-copy path), which broke under plugin
install; switched to `${CLAUDE_PLUGIN_ROOT}` across planning/review/
write-manual, and moved user-level custom rules to `${CLAUDE_PLUGIN_DATA}`
(plugin-aware `resolve-rules.sh`, adapted from cc-thingz).
- `plan-review` agent: quoted its YAML frontmatter (was invalid strict YAML) and
corrected a stale `/action:plan` reference to `/planning:plan-make`.

### Notes
- This repo enforces its own conventions on itself (American English; no
null-device redirects on Windows; no Claude-side git commits/staging or
`git mv`/`git rm`), so authoring sometimes works around the very hooks it
ships — see `plugins/conventions/hooks/README.md`.
- `check-no-null-redirect` is intentionally Windows-only and is not auto-wired
by the conventions plugin (a plugin `hooks.json` can't branch on OS).
110 changes: 110 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# CLAUDE.md

Guidance for Claude Code working inside the **debussy** repo.

## What this repo is

A Claude Code **plugin marketplace** and the source of truth for André's Claude
Code customizations. Features ship as plugins under `plugins/`, listed in
`.claude-plugin/marketplace.json`. The convention hooks also have a manual
install path (file copy into `~/.claude/hooks` + `settings.json` wiring) for
people who want the PowerShell runners or always-on use without enabling a
plugin.

## Layout

- `.claude-plugin/marketplace.json` — marketplace manifest; lists every plugin.
- `plugins/<name>/` — one plugin each. Every plugin has
`.claude-plugin/plugin.json` and auto-discovers `agents/`, `commands/`,
`skills/`, and `hooks/hooks.json` beneath it.
- `planning` — brainstorm, plan-make, plan-review, plan-exec.
- `review` — project-analyst (Nigel) + project-audit.
- `write-manual` — the manual-writing pipeline.
- `dotnet-tools` — the .NET style corrector.
- `conventions` — the convention hooks (+ their `hooks/hooks.json`).
- `settings/` — `settings.{windows,unix}.example.json` for the manual hook path.
- `docs/` — design notes (`marketplace-plan.md`).
- `install.* / sync.* / uninstall.*` — helpers for the manual hook path only
(copy `plugins/conventions/hooks` ↔ `~/.claude/hooks`). Features install via
`/plugin`, not these scripts.

## Conventions this repo enforces (on itself)

The convention hooks are active on the author's machine, so this repo obeys its
own rules. Three will bite you while editing:

1. **American English everywhere** — the `check-american-english` hook blocks
`Write`/`Edit` containing non-American spellings.
2. **No null-device redirects** (Windows) — `check-no-null-redirect` blocks
`Bash`/`PowerShell` commands containing `/dev/null`, `>nul`, etc. Redirect to
a real file, drop it, or close a descriptor with `2>&-`.
3. **No Claude-side git writes** — `check-git-guard` blocks
`git commit`/`add`/`stage` and `git mv`/`git rm`. See the Git section.

### Authoring gotchas (important)

These hooks match on **content**, so they cannot tell prose from quotation:

- Documentation that *quotes* a non-American spelling trips the English hook.
Describe the spelling family instead of spelling it out, assemble it from
fragments, or toggle with `/hooks` while authoring.
- A `Bash`/`PowerShell` command that *contains* `/dev/null` (e.g. a script you're
writing) trips the null hook. Author such files with the `Write` tool (the
hook only matches `Bash|PowerShell`), or use `2>&-`.

## Editing rules

- **Keep the two American-English runners in sync.** The `.sh` word map is
generated from the `.ps1`; if you change spellings, update
`plugins/conventions/hooks/cross-platform/check-american-english.ps1` and
regenerate the `.sh` map (procedure in that directory's `README.md`), or edit
both identically.
- **Copy skills wholesale.** A skill is its whole `SKILL.md` + `references/` +
`scripts/` tree, not just the `SKILL.md`.
- **Respect the windows-only vs cross-platform hook split.** A hook that only
makes sense on Windows lives in `windows-only/` and gets no `.sh`; the plugin
`hooks.json` only auto-wires cross-platform hooks (it can't branch on OS).
- **Don't auto-edit `~/.claude/settings.json`.** Wiring hooks manually is a
deliberate step; the install scripts copy files but never touch settings.
- **New artifact?** Decide which plugin it belongs to (by cohesion), drop it
under that plugin's `agents/`/`commands/`/`skills/`, and add the plugin to
`marketplace.json` if it's new. Faithful extraction: copy verbatim and flag,
rather than silently rewrite, any origin-project references in comments.

## Plugin authoring notes

- **Use `${CLAUDE_PLUGIN_ROOT}`** for in-plugin script/reference paths in
SKILL.md, commands, and prompts — never `~/.claude/...`. The plugin framework
text-substitutes it to the install location; hardcoded home paths break for
anyone who installs the plugin. User-writable state goes under
`${CLAUDE_PLUGIN_DATA}`; project-relative paths (e.g. `.claude/…`,
`docs/plans/…`) stay as-is (they resolve in the user's working repo).
- **Version each plugin independently** in its `plugin.json` (semver: patch =
fix, minor = new component, major = breaking). The marketplace has its own
version in `metadata`.
- **Cross-references** use the plugin prefix: `/planning:plan-make`,
`/planning:plan-exec`, etc.

### Known Claude Code limitations (manage expectations)

- Skills under `skills/*/SKILL.md` don't appear in the `/` autocomplete dropdown
— only `commands/*.md` do. Skills are still invocable by full name
(`/planning:plan-exec`) or natural-language intent.
- A plugin `hooks.json` can't branch on OS (hence `check-no-null-redirect` stays
Windows-only and unwired in the conventions plugin).

## The planning trio

`plan-make` (command, writes a plan to `docs/plans/`) → `plan-review` (agent,
vets it read-only) → `plan-exec` (skill, executes it task by task). All in the
`planning` plugin, sharing the `docs/plans/<number>-<task>.md` scheme.
`brainstorm` is the design step that precedes them.

## Git

**Never commit, stage, or push** — not even as the natural last step. The user
does all git writes manually; leave changes uncommitted for review.
`check-git-guard` enforces this, but don't rely on the hook — just don't.

**Never use `git mv` or `git rm`.** Use plain `mv` / `rm` / rename (or
`Move-Item` / `Remove-Item`) so file operations aren't coupled to git's index.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2026 André Polykanine (Oire)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
45 changes: 45 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
debussy
Copyright 2026 André Polykanine (Oire)

This product is licensed under the Apache License, Version 2.0 (see LICENSE),
with the exception noted below.

================================================================================
Third-party material
================================================================================

The "planning" plugin (plugins/planning/ — the brainstorm and plan-exec skills,
the plan-make command, the plan-review agent, and their bundled scripts and
reference prompts) is adapted from cc-thingz by Umputun:

https://github.com/umputun/cc-thingz

cc-thingz is distributed under the MIT License. The MIT and Apache-2.0 licenses
are compatible, so debussy is distributed as a whole under Apache-2.0; the
original MIT copyright and permission notice for the adapted material is
retained below, as the MIT License requires. debussy's adaptations diverge from
upstream (simplified flows, different naming, packaging changes).

--------------------------------------------------------------------------------
MIT License

Copyright (c) 2026 Umputun

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Loading
Loading