Skip to content
Open
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
6 changes: 6 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
"source": "./plugins/swarm",
"description": "Local mixture-of-agents code review for Claude Code. Fans a diff across Claude lenses plus the codex and grok CLIs (grok-4.5), merges by mechanism with cross-family consensus, verifies solo findings and all design suggestions, and presents one ranked report. Optional --fix / --loop applies the findings you agreed with; --pr reviews a GitHub PR diff and posts the result. Skills: /swarm:review, /swarm:agents.",
"version": "0.5.0"
},
{
"name": "settings",
"source": "./plugins/settings",
"description": "Plugin settings system for Claude Code marketplaces. Per-plugin TOML config resolved over schema defaults: list, show, get, set, validate. Each plugin owns its config file, defaults, and validation schema.",
"version": "0.1.0"
}
]
}
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,8 @@ entries are grouped per plugin, newest first.

### 0.1.0 — 2026-07-03
- Initial swarm plugin: local mixture-of-agents review adapter (P1).

## settings

### 0.1.0 — 2026-07-16
- Initial settings plugin (phase 1: config surface). Per-plugin TOML config resolved over schema defaults, with `list` / `show [--overrides]` / `get` / `set` / `unset` / `validate` / `defaults` via `scripts/settings.py` (Python 3.11+ stdlib) and the `/settings` skill. Each plugin owns a `schema/settings.schema.json` (types, enums, defaults, config filename); work-system, knowledge-system, and pr-flow ship schemas whose defaults match current behavior. Includes a `[related_projects]` sibling-project address book (path-existence warnings, not errors). Consumer wiring lands in a follow-up.
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This is a **Claude Code plugin marketplace** (monorepo) containing plugins that
- **work-system** (v1.8.x) — Task and worktree workflow. Skills: `/define`, `/kickoff`, `/adopt`, `/continue`, `/status`, `/close`, `/list`, `/statusline`
- **pr-flow** (v1.3.x) — PR review feedback loop. Skills: `/open`, `/cycle`, `/check`, `/fix`, `/rebase`, `/merge`
- **swarm** (v0.5.x) — Local mixture-of-agents code review (external `codex`/`grok` CLIs — grok-4.5 — plus Claude lenses: 11 in 4 clusters). P2: `/swarm:review` pipeline (scope→fan-out→merge→verify); P5: `--fix`/`--loop` apply the findings you agreed with. Skills: `/swarm:review`, `/swarm:agents`
- **settings** (v0.1.x) — Per-plugin TOML config resolved over schema defaults; each plugin owns its `schema/settings.schema.json`. Skill: `/settings` (list/show/get/set/validate). Phase 1: config surface only.

## Plugin Anatomy

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ Local mixture-of-agents code review. Fans out one review across Claude lens suba

[Documentation →](plugins/swarm/)

### Settings

Plugin settings system: per-plugin TOML config resolved over schema defaults. Each plugin owns its config file (`.work-system.toml`, `.knowledge-system.toml`, `.pr-flow.toml`), defaults, and validation schema; users override only what they need. `list`, `show`, `get`, `set`, `validate` via one script and skill. Includes a `[related_projects]` sibling-project address book for cross-project orchestration. *(Phase 1: config surface only — consumer wiring lands next.)*

**Commands:** `/settings` *(subcommands: `list`, `show`, `get`, `set`, `unset`, `validate`, `defaults`)*

[Documentation →](plugins/settings/)

## Installation

### 1. Add the marketplace
Expand All @@ -51,6 +59,7 @@ Local mixture-of-agents code review. Fans out one review across Claude lens suba
/plugin install work-system
/plugin install pr-flow
/plugin install swarm
/plugin install settings
```

### 3. Reload plugins
Expand Down
57 changes: 57 additions & 0 deletions plugins/knowledge-system/schema/settings.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "knowledge-system settings",
"x-plugin": "knowledge-system",
"x-config-file": ".knowledge-system.toml",
"type": "object",
"properties": {
"paths": {
"type": "object",
"description": "Where knowledge-system stores rules, knowledge, and the index. Defaults match today's Claude-specific layout.",
"properties": {
"knowledge_dir": {
"type": "string",
"default": ".claude/knowledge",
"description": "Directory holding knowledge entries."
},
"rules_dir": {
"type": "string",
"default": ".claude/rules",
"description": "Directory holding auto-loaded rule files."
},
"index_file": {
"type": "string",
"default": "_index.md",
"description": "Index filename inside knowledge_dir."
},
"claude_md": {
"type": "string",
"default": "CLAUDE.md",
"description": "Project instructions file the index is injected into."
}
}
},
"behavior": {
"type": "object",
"properties": {
"auto_prime_via_claude_md": {
"type": "boolean",
"default": true,
"description": "Inject the knowledge index into claude_md so it auto-loads each session."
}
}
},
"mode": {
"type": "object",
"description": "How knowledge storage binds to the host tool.",
"properties": {
"knowledge_mode": {
"type": "string",
"enum": ["claude", "neutral", "symlinked"],
"default": "claude",
"description": "claude = .claude/* paths; neutral = tool-agnostic paths; symlinked = neutral store with .claude/* symlinks. Storage only in this phase."
}
}
}
}
}
45 changes: 45 additions & 0 deletions plugins/pr-flow/schema/settings.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "pr-flow settings",
"x-plugin": "pr-flow",
"x-config-file": ".pr-flow.toml",
"type": "object",
"properties": {
"checks": {
"type": "object",
"description": "Readiness checks run before opening a PR. All on by default (current behavior).",
"properties": {
"knowledge_check_enabled": {
"type": "boolean",
"default": true,
"description": "Prompt to curate knowledge from the diff before opening a PR."
},
"readme_check_enabled": {
"type": "boolean",
"default": true,
"description": "Verify READMEs are updated for added/renamed/removed features."
},
"changelog_check_enabled": {
"type": "boolean",
"default": true,
"description": "Verify CHANGELOG is updated."
},
"version_bump_check_enabled": {
"type": "boolean",
"default": true,
"description": "Verify plugin versions are bumped and in sync."
}
}
},
"review": {
"type": "object",
"properties": {
"review_bot": {
"type": "string",
"default": "@claude",
"description": "Mention that triggers the automated PR review."
}
}
}
}
}
11 changes: 11 additions & 0 deletions plugins/settings/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "settings",
"description": "Plugin settings system for Claude Code marketplaces. Per-plugin TOML config resolved over schema defaults: list, show, get, set, validate. Each plugin owns its config file, defaults, and validation schema.",
"version": "0.1.0",
"author": {
"name": "gering"
},
"repository": "https://github.com/gering/claude-plugins",
"license": "MIT",
"keywords": ["settings", "config", "toml", "schema", "plugins"]
}
158 changes: 158 additions & 0 deletions plugins/settings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# settings

A plugin settings system for the `gering-plugins` marketplace. Each plugin
declares a small schema with defaults; users override only what they need in a
plugin-local TOML file; the resolver merges the two. One skill (`/settings`) and
one script (`scripts/settings.py`, Python 3.11+ stdlib only) expose the whole
surface.

## Why

The plugins hardcode conventions — `tasks/`, `.claude/worktrees/`, `task/<name>`
branches, `.claude/knowledge/`, `CLAUDE.md`. This makes those conventions
**explicit, readable, overrideable, and validatable** without duplicating
defaults into every repo. It also prepares a future neutral / Codex layout: the
schema carries a migration path (`[compat]`, `mode.knowledge_mode`) as storage
today, behavior later.

## Ownership model

Each plugin owns its settings, the settings plugin owns only the infrastructure:

| Owned by each plugin | Owned by `settings` |
|----------------------|---------------------|
| `schema/settings.schema.json` (types, enums, defaults, config filename) | discovery, resolve, validate, read/write CLI |
| the semantic meaning of its keys | the merge + validation engine |

A plugin adds settings by dropping a `schema/settings.schema.json` into its own
directory. No change to the settings plugin is needed.

## Config files

One TOML file per plugin at the **repo root**, holding only overrides:

```
.work-system.toml
.knowledge-system.toml
.pr-flow.toml
```

A missing file is fully valid — the plugin resolves to its schema defaults.

## Commands

```sh
python3 plugins/settings/scripts/settings.py <subcommand>
```

| Command | Does |
|---------|------|
| `list` | plugins + config filenames, whether an override file exists |
| `show [plugin]` | effective config: defaults merged with overrides |
| `show [plugin] --overrides` | only the user overrides (raw) |
| `defaults [plugin]` | schema defaults only |
| `get <plugin>.<section>.<key>` | one resolved value |
| `set <plugin>.<section>.<key> <value>` | write one override (type-coerced, enum-checked) |
| `unset <plugin>.<section>.<key>` | remove one override, pruning emptied sections |
| `validate [plugin]` | check TOML syntax + schema semantics; non-zero exit on errors |

Add `--json` to any read command for machine output. Discovery of schemas and
config location can be overridden with `SETTINGS_PLUGINS_DIR` (os.pathsep-
separated roots to scan for `*/schema/settings.schema.json`) and
`SETTINGS_PROJECT_ROOT` (where config files live).

## Schema format

A `settings.schema.json` is a **subset of JSON Schema** plus two custom keys.
The subset the validator understands: `type` (`string` / `integer` / `number` /
`boolean` / `array` / `object`), `properties`, `items`, `enum`, `required`, and
`default`. Defaults live here — never in the config TOML.

```jsonc
{
"x-plugin": "work-system", // plugin name (defaults to the dir name)
"x-config-file": ".work-system.toml", // override file at the repo root
"type": "object",
"properties": {
"paths": {
"type": "object",
"properties": {
"tasks_dir": { "type": "string", "default": "tasks" }
}
},
"mode": {
"type": "object",
"properties": {
"knowledge_mode": {
"type": "string",
"enum": ["claude", "neutral", "symlinked"],
"default": "claude"
}
}
}
}
}
```

### Dynamic sections (`related_projects`)

A section annotated `"x-semantic": "related-projects"` is a free-form map of
sibling projects this repo coordinates with — the address book cross-project
orchestration consumes. Entries take either form:

```toml
[related_projects]
backend = "/abs/path/to/backend" # shorthand: name = path

[related_projects.frontend] # table: adds role/tags
path = "/abs/path/to/frontend"
role = "ui"
tags = ["web", "spa"]
```

Validation checks the shape (a `path` string is required in the table form) and
**warns** — never errors — when a path doesn't exist locally, since machines
differ. `normalize_related_projects()` resolves both forms to
`{name: {path, role?, tags?}}` for consumers. Storage/resolve only for now; no
plugin acts on it yet.

## How plugins should consume resolved settings (contract)

Consumer wiring lands in a follow-up. When a plugin adopts settings, it should:

1. **Read once, resolved.** Call
`settings.py get <plugin>.<section>.<key> --json` (or `show <plugin> --json`
for the whole effective config) and use the value. Never read the TOML file
directly — that skips defaults and validation.
2. **Fall back to the default, always.** The resolver guarantees a value even
with no config file. A consumer must not require the file to exist.
3. **Don't hardcode the old constant beside the lookup.** Replace
`tasks/` with the resolved `paths.tasks_dir`; the schema default (`"tasks"`)
preserves today's behavior.
4. **Change behavior via defaults, not code.** To migrate a convention (e.g. to
a neutral worktrees dir), flip the schema default and the `[compat]` toggle
in one deliberate step — consumers keep reading the same key.

## Defaults reflect current behavior

Per the task's guiding rule, defaults are **what the plugins assume today**, not
a speculative redesign — e.g. `worktrees_dir` defaults to `.claude/worktrees`
(current) with the neutral `.worktrees` target gated behind
`[compat].prefer_neutral_worktrees` (off). Migrations change defaults
deliberately, later.

## Limitations (phase 1)

- `set` / `unset` rewrite the override file from parsed values — **TOML comments
and formatting are not preserved**. Files are small, so this stays readable.
- Schema discovery targets the **monorepo `plugins/` layout**. For an installed
marketplace (versioned cache dirs), point `SETTINGS_PLUGINS_DIR` at the plugin
roots. A discovery story for installed marketplaces is a follow-up.
- No config-version field yet — added only when versioned migrations exist.

## Tests

`scripts/test_settings.py` (run by `scripts/check-structure.py` in CI) covers
default extraction, resolve merge, validation (type / enum / unknown key /
related-project paths), TOML round-trip, value coercion, and the `set`/`get`/
`unset` CLI cycle against a throwaway schema and project root.
Loading
Loading