diff --git a/docs/concepts.md b/docs/concepts.md index 94d8742..8aaca8e 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -184,7 +184,7 @@ cr/normalize/extract/... ← normalize extraction cr/normalize/reuse/... ← source patching ``` -Branches are auto-merged or held for review depending on your workflow config. +Branches are auto-merged or held for review depending on your workflow config. When a review branch is merged or rejected, its remote copy is deleted too, so merged branches don't linger as phantom pending reviews — run `contentrain prune` to drain any existing backlog, or set `remoteBranchCleanup: false` to opt out. ## How It Compares diff --git a/docs/packages/cli.md b/docs/packages/cli.md index 4e73540..d3ee6fc 100644 --- a/docs/packages/cli.md +++ b/docs/packages/cli.md @@ -60,14 +60,15 @@ Example: `contentrain --debug status` or `CONTENTRAIN_DEBUG=1 contentrain status |---------|--------| | `contentrain init` | Initialize `.contentrain/`, git workflow, templates, and IDE rules | | `contentrain status` | Show project overview, models, branch pressure, and validation summary | -| `contentrain doctor` | Check setup health, SDK freshness, orphan content, and branch limits | +| `contentrain doctor` | Check setup health, SDK freshness, orphan content, local branch limits, and remote `cr/*` count | | `contentrain validate` | Validate content against schemas, optionally create review-branch fixes | | `contentrain generate` | Generate `.contentrain/client/` and `#contentrain` package imports | | `contentrain describe` | Display full model schema and sample data | | `contentrain describe-format` | Show file format specification and storage conventions | | `contentrain scaffold` | Apply starter templates (blog, landing, docs, SaaS, ...) | -| `contentrain diff` | Review and merge or reject pending `cr/*` branches interactively | -| `contentrain merge ` | Merge one pending `cr/*` branch non-interactively | +| `contentrain diff` | Review and merge or reject pending `cr/*` branches interactively (deletes the remote copy on merge/reject) | +| `contentrain merge ` | Merge one pending `cr/*` branch non-interactively (deletes the remote copy) | +| `contentrain prune` | Delete merged `cr/*` branches locally and on the remote (drain the backlog) | | `contentrain setup` | Configure MCP server and AI rules for your IDE | | `contentrain skills` | Install, update, or list AI skills and rules for your IDE | | `contentrain serve` | Start the local review UI, the MCP stdio server, or the MCP HTTP server | @@ -238,7 +239,20 @@ contentrain merge cr/content/faq/1234-abcd contentrain merge cr/content/faq/1234-abcd --yes # Skip confirm (CI) ``` -Non-interactive single-branch sibling of `contentrain diff`. Delegates to MCP's `mergeBranch` so dirty-file protections + selective sync warnings behave identically. +Non-interactive single-branch sibling of `contentrain diff`. Delegates to MCP's `mergeBranch` so dirty-file protections + selective sync warnings behave identically. After a successful merge it also deletes the branch's copy on the remote — best-effort, so an offline or permission failure only prints a warning. Opt out with `remoteBranchCleanup: false` in `config.json`. + +--- + +### `contentrain prune` + +```bash +contentrain prune --dry-run # Preview merged cr/* branches (local + remote) +contentrain prune # Confirm, then delete them +contentrain prune --yes # Skip confirm (CI) +contentrain prune --json # Machine-readable output (mutates only with --yes) +``` + +Drains already-merged `cr/*` branches: local ones past their retention period plus every merged copy left on the remote. This is the operator-facing cleanup for backlogs the per-merge deletion could not remove — e.g. branches merged before remote cleanup shipped, or after an offline/permission failure. Merged detection uses the same ancestry + patch-id classification as the rest of the toolchain, so branches orphaned by a base-history rewrite are still recognised. Governed by `remoteBranchCleanup` in `config.json`; exits non-zero if any remote deletion fails. --- diff --git a/docs/packages/mcp.md b/docs/packages/mcp.md index e05622f..16fb14a 100644 --- a/docs/packages/mcp.md +++ b/docs/packages/mcp.md @@ -76,7 +76,7 @@ The MCP server exposes **19 tools** organized by function. Each tool includes [M | `contentrain_status` | Project overview | Config, models, branch health, context, validation summary | | `contentrain_describe` | Model deep-dive | Full schema, sample data, field types for any model | | `contentrain_describe_format` | Format reference | File structure, JSON formats, markdown conventions, locale strategies | -| `contentrain_doctor` | Health diagnostics | Setup validation, SDK freshness, orphan content, branch limits, unused keys, missing translations | +| `contentrain_doctor` | Health diagnostics | Setup validation, SDK freshness, orphan content, local branch limits, remote `cr/*` count, unused keys, missing translations | | `contentrain_content_list` | Read content | List and filter content entries with optional relation resolution | ### Write Tools (Git-Backed, Branch-Isolated) @@ -90,10 +90,10 @@ The MCP server exposes **19 tools** organized by function. Each tool includes [M | `contentrain_content_save` | Write content | Save entries for any model kind (collection, singleton, dictionary, document) | | `contentrain_content_delete` | Remove content | Delete specific content entries | | `contentrain_validate` | Check & fix | Validate content against schemas, optionally auto-fix structural issues | -| `contentrain_submit` | Push branches | Push `cr/*` review branches to remote | -| `contentrain_merge` | Merge branches | Merge a review-mode branch into contentrain locally (by exact branch or model; no external platform needed) | -| `contentrain_branch_list` | Inspect branches | List pending `cr/*` branches with merge status and branch-health pressure | -| `contentrain_branch_delete` | Clean up branches | Delete a stale/failed `cr/*` branch (the contentrain branch is protected) | +| `contentrain_submit` | Push branches | Push `cr/*` review branches to remote, then lazily prune merged local + remote leftovers | +| `contentrain_merge` | Merge branches | Merge a review-mode branch into contentrain locally (by exact branch or model; no external platform needed); deletes the branch's remote copy | +| `contentrain_branch_list` | Inspect branches | List pending `cr/*` branches with merge status and branch-health pressure (`remote: true` adds a remote view + remote-only leftovers) | +| `contentrain_branch_delete` | Clean up branches | Delete a stale/failed `cr/*` branch locally and on the remote (the contentrain branch is protected; supports remote-only deletion) | ### Normalize Tools (Scan + Apply) @@ -133,7 +133,9 @@ All write operations create or update `cr/*` branches: - Content changes go to isolated branches (`cr/{scope}/{target}[/{locale}]/{timestamp}-{suffix}`) - Humans review via `contentrain diff` or the serve UI - Approved changes merge into the `contentrain` branch, baseBranch is advanced via update-ref -- Branch health is tracked and surfaced via `contentrain_status` (warning at 50, blocked at 80 active branches) +- Merging (or deleting) a branch also removes its copy on the remote, so merged branches don't pile up as phantom pending reviews — best-effort, opt out with `remoteBranchCleanup: false` in `config.json`. Drain an existing backlog with `contentrain prune` +- Merged-branch detection survives base-history rewrites (ancestry check with a patch-id fallback) +- Branch health is tracked and surfaced via `contentrain_status` (warning at 50, blocked at 80 active branches); `contentrain_doctor` adds a remote `cr/*` count - Legacy `contentrain/*` branches are auto-migrated on first init ### 4. Local-First by Default, Remote Providers Opt-In