diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json index 8e50acd..889ec41 100644 --- a/.agents/plugins/marketplace.json +++ b/.agents/plugins/marketplace.json @@ -1,5 +1,5 @@ { - "name": "beyond10x", + "name": "b10x", "interface": { "displayName": "Beyond10x" }, @@ -41,22 +41,16 @@ "category": "Productivity" }, { - "name": "workspace-hygiene", + "name": "connectors", "source": { "source": "local", - "path": "./plugins/workspace-hygiene" + "path": "./plugins/connectors" }, "policy": { "installation": "AVAILABLE", "authentication": "ON_INSTALL" }, "category": "Productivity" - }, - { - "name": "connectors", - "source": { "source": "local", "path": "./plugins/connectors" }, - "policy": { "installation": "AVAILABLE", "authentication": "ON_INSTALL" }, - "category": "Productivity" } ] } diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a77b003..448c54a 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,6 +1,11 @@ { - "name": "beyond10x", - "owner": { "name": "beyond10x" }, + "name": "b10x", + "owner": { + "name": "beyond10x" + }, + "metadata": { + "description": "Beyond10x agent plugins: the plugins this repository carries, and product plugins pinned at their own releases." + }, "plugins": [ { "name": "beyond10x", @@ -17,15 +22,21 @@ "source": "./plugins/aep-drive", "description": "Coordinate AEP development waves, story scoping, implementation, and adversarial review." }, - { - "name": "workspace-hygiene", - "source": "./plugins/workspace-hygiene", - "description": "Manage isolated Git worktrees with explicit ownership and safe cleanup proof." - }, { "name": "connectors", "source": "./plugins/connectors", "description": "Set up, inspect, and invoke governed integrations through the connectors CLI." + }, + { + "name": "worktree", + "source": { + "source": "git-subdir", + "url": "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/beyond10x/worktree.git", + "path": "plugins/worktree", + "ref": "0.6.0", + "sha": "3d4954b7f0cde907a5b8a27a6c3d095368d4a1cf" + }, + "description": "Manage isolated Git worktrees with explicit ownership and safe cleanup proof, released with the worktree binary." } ] } diff --git a/.engineering/planning/journal.jsonl b/.engineering/planning/journal.jsonl index bebebeb..f344b8f 100644 --- a/.engineering/planning/journal.jsonl +++ b/.engineering/planning/journal.jsonl @@ -180,3 +180,4 @@ {"entity":"story","version":1,"id":"shared-docs-toolchain","revision":1,"type":"aep.entity.create/v1","from_state":null,"to_state":"draft","changed":{"body":"## Outcome\n\nUse the reviewed shared documentation runtime for this repository's passive source bundle producer as part of the coordinated Mandate contract viewer publication.\n\n## Acceptance\n\nThe Atlas-generated producer caller pins Docs System commit 1d4c0262911761118ffdd7037890f541a0688714. Source allowlists, credential-free execution and repository-owned validation remain intact. Atlas reconciliation reports no caller drift. Required source and common checks pass on the exact published commit, and its passive producer yields a valid immutable source bundle.\n\n## Scope\n\n.github/workflows/b10x-docs-bundle.yml and this planning record. The coordinating authority is the shared documentation rollout; this repository's product/runtime contracts do not change.\n","title":"Align the passive producer with the shared contract viewer runtime"},"args":{"command":"create-entity","data":{"body":"## Outcome\n\nUse the reviewed shared documentation runtime for this repository's passive source bundle producer as part of the coordinated Mandate contract viewer publication.\n\n## Acceptance\n\nThe Atlas-generated producer caller pins Docs System commit 1d4c0262911761118ffdd7037890f541a0688714. Source allowlists, credential-free execution and repository-owned validation remain intact. Atlas reconciliation reports no caller drift. Required source and common checks pass on the exact published commit, and its passive producer yields a valid immutable source bundle.\n\n## Scope\n\n.github/workflows/b10x-docs-bundle.yml and this planning record. The coordinating authority is the shared documentation rollout; this repository's product/runtime contracts do not change.\n","status":"draft","title":"Align the passive producer with the shared contract viewer runtime"},"entity_type":"aep.story/v1","locator":"ep://planning/store/story/shared-docs-toolchain"},"payload":{"actor":"agent:mandate-docs-toolchain","at":1789627861573,"causation":"cmd-new-story-shared-docs-toolchain","change":{"change":"created","status":"draft"},"correlation":"protocol-artifact-new","event_id":"story:shared-docs-toolchain@1#0~db0fa97c13705108","executor":null,"recorded_at":"2026-09-17T06:51:01Z"}} {"entity":"story","version":1,"id":"shared-docs-toolchain","revision":2,"type":"aep.entity.update/v1","from_state":"draft","to_state":"draft","changed":{"scope":[{"confidence":"cited","path":".github/workflows/b10x-docs-bundle.yml"}]},"args":{"changes":{"scope":[{"confidence":"cited","path":".github/workflows/b10x-docs-bundle.yml"}]},"command":"update-entity","target":"01MEM0000000000000067"},"payload":{"actor":"agent:mandate-docs-toolchain","at":1789627861652,"causation":"cmd-protocol-artifact-scope-story-shared-docs-toolchain-1789627861652","change":{"change":"body_replaced"},"correlation":"protocol-artifact-scope","event_id":"story:shared-docs-toolchain@2#0~27ac65189db9b60f","executor":null,"recorded_at":"2026-09-17T06:51:01Z"}} {"entity":"story","version":1,"id":"retire-ess-specify","revision":1,"type":"aep.entity.create/v1","from_state":null,"to_state":"draft","changed":{"body":"# Retire `ess-specify`; spec-driven work routes to the ESS repository's own plugin\n\n## Why\n\nESS now ships its agent plugin from `beyond10x/ess` (`plugins/ess/`, marketplace `ess`), at the\nsame version as the `ess` binary, and the binary prints the same skills through `ess skill`. The\ncopy here released on its own cadence and drifted: `0.9.2` told adopters to install ESS `0.22.1`\nwhile ESS was at `0.29.0`.\n\n## Acceptance\n\n`plugins/ess-specify` and its marketplace entries are gone; `task check` prints\n`valid: marketplace beyond10x, 5 focused plugin(s)`; `ess-specify` is a retired name the gate\nrefuses in authored files; the `beyond10x` front door and the install guide send spec-driven work to\nthe ESS marketplace and `ess skill`.\n\n## Scope\n\n- `plugins/ess-specify/**` (deleted), `.claude-plugin/marketplace.json`, `.agents/plugins/marketplace.json`\n- `crates/agentplugins-check/src/{main.rs,evals.rs}`\n- `evals/ess-specify-new-entity/**` (deleted), `evals/golden-path-end-to-end/**`, `evals/README.md`\n- `plugins/beyond10x/skills/beyond10x/**`, `plugins/aep-plan/skills/planning/SKILL.md`\n- `README.md`, `website/**`, `CHANGELOG.md`\n\n## Not in scope\n\n- An eval case for the ESS plugin. ESS runs no eval corpus; the dropped case is not re-homed.\n","title":"Retire ess-specify; spec-driven work routes to the ESS repository's own plugin"},"args":{"command":"create-entity","data":{"body":"# Retire `ess-specify`; spec-driven work routes to the ESS repository's own plugin\n\n## Why\n\nESS now ships its agent plugin from `beyond10x/ess` (`plugins/ess/`, marketplace `ess`), at the\nsame version as the `ess` binary, and the binary prints the same skills through `ess skill`. The\ncopy here released on its own cadence and drifted: `0.9.2` told adopters to install ESS `0.22.1`\nwhile ESS was at `0.29.0`.\n\n## Acceptance\n\n`plugins/ess-specify` and its marketplace entries are gone; `task check` prints\n`valid: marketplace beyond10x, 5 focused plugin(s)`; `ess-specify` is a retired name the gate\nrefuses in authored files; the `beyond10x` front door and the install guide send spec-driven work to\nthe ESS marketplace and `ess skill`.\n\n## Scope\n\n- `plugins/ess-specify/**` (deleted), `.claude-plugin/marketplace.json`, `.agents/plugins/marketplace.json`\n- `crates/agentplugins-check/src/{main.rs,evals.rs}`\n- `evals/ess-specify-new-entity/**` (deleted), `evals/golden-path-end-to-end/**`, `evals/README.md`\n- `plugins/beyond10x/skills/beyond10x/**`, `plugins/aep-plan/skills/planning/SKILL.md`\n- `README.md`, `website/**`, `CHANGELOG.md`\n\n## Not in scope\n\n- An eval case for the ESS plugin. ESS runs no eval corpus; the dropped case is not re-homed.\n","status":"draft","title":"Retire ess-specify; spec-driven work routes to the ESS repository's own plugin"},"entity_type":"aep.story/v1","locator":"ep://planning/store/story/retire-ess-specify"},"payload":{"actor":"human:timo","at":1790167587226,"causation":"cmd-new-story-retire-ess-specify","change":{"change":"created","status":"draft"},"correlation":"protocol-artifact-new","event_id":"story:retire-ess-specify@1#0~73af7ee8bf239901","executor":null,"recorded_at":"2026-09-23T12:46:27Z"}} +{"args":{"command":"create-entity","data":{"body":"# Story: the b10x catalog lists worktree by pin, not by copy\n\n## Goal\nThe marketplace is renamed `b10x` and lists the `worktree` plugin as a `git-subdir` entry pinned\nto a Worktree release tag and its full commit, replacing the `workspace-hygiene` copy. The copy\nhere shipped on this repository's cadence: `workspace-hygiene` 0.10.0 lacked the\n`patch-equivalent` recovery-proof guidance that Worktree 0.5.0 generates.\n\n## Acceptance\n`task check` refuses a `worktree` entry that is not a `git-subdir` at\n`https://github.com/beyond10x/worktree.git` path `plugins/worktree` with a bare release tag and a\n40-hex commit; `agentplugins-check remote` refuses a commit that is not the tag's, manifests at\nthat commit that declare another version, and a tag that is not Worktree's newest release, and\nruns on every pull request, `main` push and daily.\n\n## Scope\n- `.claude-plugin/marketplace.json`, `.agents/plugins/marketplace.json`\n- `crates/agentplugins-check/src/{main,remote,evals}.rs`, `.github/workflows/remote-plugins.yml`\n- `plugins/workspace-hygiene/` (removed), routing skill, wave skill, README, AGENTS.md, website\n","status":"draft","summary":"Rename the marketplace to b10x and replace the workspace-hygiene copy with a git-subdir entry pinned to a Worktree release, checked offline for shape and online for tag, commit, version and recency.","title":"The b10x catalog lists worktree by pin, not by copy"},"entity_type":"aep.story/v1","locator":"ep://planning/store/story/worktree-plugin-by-pin"},"changed":{"body":"# Story: the b10x catalog lists worktree by pin, not by copy\n\n## Goal\nThe marketplace is renamed `b10x` and lists the `worktree` plugin as a `git-subdir` entry pinned\nto a Worktree release tag and its full commit, replacing the `workspace-hygiene` copy. The copy\nhere shipped on this repository's cadence: `workspace-hygiene` 0.10.0 lacked the\n`patch-equivalent` recovery-proof guidance that Worktree 0.5.0 generates.\n\n## Acceptance\n`task check` refuses a `worktree` entry that is not a `git-subdir` at\n`https://github.com/beyond10x/worktree.git` path `plugins/worktree` with a bare release tag and a\n40-hex commit; `agentplugins-check remote` refuses a commit that is not the tag's, manifests at\nthat commit that declare another version, and a tag that is not Worktree's newest release, and\nruns on every pull request, `main` push and daily.\n\n## Scope\n- `.claude-plugin/marketplace.json`, `.agents/plugins/marketplace.json`\n- `crates/agentplugins-check/src/{main,remote,evals}.rs`, `.github/workflows/remote-plugins.yml`\n- `plugins/workspace-hygiene/` (removed), routing skill, wave skill, README, AGENTS.md, website\n","summary":"Rename the marketplace to b10x and replace the workspace-hygiene copy with a git-subdir entry pinned to a Worktree release, checked offline for shape and online for tag, commit, version and recency.","title":"The b10x catalog lists worktree by pin, not by copy"},"entity":"story","entry_hash":"374497c1e8d86a98c468032fcf4dc86351e5711b2375b32c0d1438b3a61734b5","from_state":null,"id":"worktree-plugin-by-pin","parent_hash":"0e5fd9db0bb58243744cd0404562223549dc236f614221abf79f8add2fd9a4ac","payload":{"actor":"human:timo","at":1790247637626,"causation":"cmd-new-story-worktree-plugin-by-pin","change":{"change":"created","status":"draft"},"correlation":"protocol-artifact-new","event_id":"story:worktree-plugin-by-pin@1#0~a2165dda3a96e504","executor":null,"recorded_at":"2026-09-24T11:00:37Z"},"revision":1,"to_state":"draft","type":"aep.entity.create/v1","version":1} diff --git a/.engineering/planning/story/worktree-plugin-by-pin.md b/.engineering/planning/story/worktree-plugin-by-pin.md new file mode 100644 index 0000000..2bc82c5 --- /dev/null +++ b/.engineering/planning/story/worktree-plugin-by-pin.md @@ -0,0 +1,28 @@ +--- +format: aep.planning-md/1 +id: story:worktree-plugin-by-pin +kind: story +status: draft +title: The b10x catalog lists worktree by pin, not by copy +summary: Rename the marketplace to b10x and replace the workspace-hygiene copy with a git-subdir entry pinned to a Worktree release, checked offline for shape and online for tag, commit, version and recency. +revision: 1 +--- +# Story: the b10x catalog lists worktree by pin, not by copy + +## Goal +The marketplace is renamed `b10x` and lists the `worktree` plugin as a `git-subdir` entry pinned +to a Worktree release tag and its full commit, replacing the `workspace-hygiene` copy. The copy +here shipped on this repository's cadence: `workspace-hygiene` 0.10.0 lacked the +`patch-equivalent` recovery-proof guidance that Worktree 0.5.0 generates. + +## Acceptance +`task check` refuses a `worktree` entry that is not a `git-subdir` at +`https://github.com/beyond10x/worktree.git` path `plugins/worktree` with a bare release tag and a +40-hex commit; `agentplugins-check remote` refuses a commit that is not the tag's, manifests at +that commit that declare another version, and a tag that is not Worktree's newest release, and +runs on every pull request, `main` push and daily. + +## Scope +- `.claude-plugin/marketplace.json`, `.agents/plugins/marketplace.json` +- `crates/agentplugins-check/src/{main,remote,evals}.rs`, `.github/workflows/remote-plugins.yml` +- `plugins/workspace-hygiene/` (removed), routing skill, wave skill, README, AGENTS.md, website diff --git a/.github/workflows/remote-plugins.yml b/.github/workflows/remote-plugins.yml new file mode 100644 index 0000000..1c30200 --- /dev/null +++ b/.github/workflows/remote-plugins.yml @@ -0,0 +1,24 @@ +name: Remote plugins + +on: + push: + branches: [main] + pull_request: + schedule: + - cron: '17 5 * * *' + workflow_dispatch: + +permissions: + contents: read + +jobs: + pins: + name: Remote plugin pins + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2 + - name: Verify every remote plugin pin against its repository + run: cargo run --quiet --locked --bin agentplugins-check -- remote diff --git a/AGENTS.md b/AGENTS.md index 5b026b3..0b5ed88 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,7 +9,13 @@ ## Invariants -- Marketplace identity is `beyond10x` in every marketplace format. +- Marketplace identity is `b10x` in every marketplace format. +- A product that ships its own plugin keeps it in its own repository at the binary's version. The + Claude Code marketplace lists it as a `git-subdir` entry pinned by release tag and full commit + (`crates/agentplugins-check/src/remote.rs` `REMOTE`), never as a copy. `agentplugins-check remote` + (network) refuses a pin that is not the tag's commit, whose manifests declare another version, or + that is not the newest release; the product's release procedure opens the bot pull request that + moves the pin. - Keep exactly the focused plugin boundaries described in `README.md`. The `beyond10x` front door may route to specialists and teach portable plugin authoring, but it must not absorb their workflows or become a mixed catch-all. diff --git a/CHANGELOG.md b/CHANGELOG.md index 66e4fe6..a666522 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## [0.11.0] — 2026-09-24 + +- **Breaking:** the marketplace identity is `b10x` in both formats. Installs name plugins as + `@b10x`. A registration made from an earlier release is named `beyond10x`: remove its + plugins and run `/plugin marketplace remove beyond10x` (Claude Code) or + `codex plugin marketplace remove beyond10x` (Codex), then register this release. +- **Breaking:** `workspace-hygiene` is retired. Worktree ships its own plugin, `worktree`, from the + `beyond10x/worktree` repository at the version of the `worktree` binary, and the skill + `workspace-hygiene:worktree` becomes `worktree:worktree`. The copy here released on its own + cadence and had drifted: `workspace-hygiene` 0.10.0 lacked the patch-equivalent recovery-proof + guidance Worktree 0.5.0 generates. +- The Claude Code marketplace lists `worktree` as a `git-subdir` entry pinned to Worktree `0.6.0` + and its full commit, carrying no copy. Codex reads `worktree@worktree` from the worktree + repository's own marketplace. +- `agentplugins-check` checks the entry's shape offline. The new `agentplugins-check remote` + refuses a commit that is not the tag's, manifests at that commit that declare another version, + and a tag that is not the newest Worktree release; `.github/workflows/remote-plugins.yml` runs it + on every pull request, `main` push and daily. `workspace-hygiene` joins the retired names. +- The routing skill, the wave skill, README, install guide and website point at `worktree`; the + eval corpus names 4 of 7 skills. Eval checker tests that used `workspace-hygiene` as a fixture + use `connectors`. + ## [0.10.0] — 2026-09-23 - **Breaking:** `ess-specify` is retired from this marketplace. ESS now ships its own plugin, `ess`, diff --git a/Cargo.lock b/Cargo.lock index 8510018..080a999 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "agentplugins-check" -version = "0.10.0" +version = "0.11.0" dependencies = [ "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index df7f44f..4bcbfda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["crates/agentplugins-check"] [workspace.package] -version = "0.10.0" +version = "0.11.0" edition = "2021" rust-version = "1.85" license = "Apache-2.0" diff --git a/README.md b/README.md index 91914af..82cc6b4 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,24 @@ # Beyond10x Agent Plugins -Curated marketplace identity: `beyond10x`. +Curated marketplace identity: `b10x`. -The repository deliberately contains five focused plugins: +The repository deliberately contains four focused plugins: - `beyond10x`: marketplace navigation, public resource discovery, and portable plugin creation. - `aep-plan`: governed planning, decomposition, plan review, and reverse engineering. - `aep-drive`: wave coordination, story scoping, implementation, and adversarial review. -- `workspace-hygiene`: safe creation, leases, publication checks, and cleanup for Git worktrees. - `connectors`: provider setup, connection diagnostics, and governed CLI operation invocation. +The Claude Code marketplace also lists plugins that ship from their product's own repository at +the binary's version. It pins each one by release tag and full commit; it carries no copy: + +- `worktree`: safe creation, leases, publication checks, and cleanup for Git worktrees, from + [`beyond10x/worktree`](https://github.com/beyond10x/worktree) `plugins/worktree/`. + +`agentplugins-check remote` refuses a pin whose commit is not its tag, whose manifests at that +commit declare another version, or whose tag is not the product's newest release. CI runs it on +every pull request, every `main` push and daily. + Spec-driven work — writing, retrofitting, validating and conformance-testing an ESS specification — is served by the ESS repository itself: its `ess` plugin ships from [`beyond10x/ess`](https://github.com/beyond10x/ess) at the same version as the `ess` binary, and @@ -21,7 +30,7 @@ Codex and Claude Code. It does not copy or replace the specialists' instructions ## Install -The `connectors` plugin is included in release `0.10.0` for both hosts. +The `connectors` plugin is included in release `0.11.0` for both hosts. See the [Connectors installation guide](website/docs/plugins/connectors.md) for both hosts. Install the standalone `connectors` CLI first. @@ -38,17 +47,18 @@ Metaharness↔AEP pair instead of assuming it matches the `0.55.0` on your `PATH Paste this pinned block into a Claude Code session: ```text -/plugin marketplace add https://github.com/beyond10x/agentplugins.git#0.10.0 -/plugin install aep-plan@beyond10x -/plugin install aep-drive@beyond10x +/plugin marketplace add https://github.com/beyond10x/agentplugins.git#0.11.0 +/plugin install aep-plan@b10x +/plugin install aep-drive@b10x /reload-plugins ``` -Add `/plugin install beyond10x@beyond10x` for the front door and -`/plugin install workspace-hygiene@beyond10x` for managed worktrees, or -`/plugin install connectors@beyond10x` for integrations. Codex offers the same plugins -from the same repository, following `.agents/plugins/marketplace.json`; its exact non-interactive -CLI bootstrap and upgrade commands are in [`website/docs/install.md`](website/docs/install.md). +Add `/plugin install beyond10x@b10x` for the front door and +`/plugin install worktree@b10x` for managed worktrees, or +`/plugin install connectors@b10x` for integrations. Codex offers the four plugins this repository +carries, following `.agents/plugins/marketplace.json`; it reads `worktree` from the worktree +repository's own marketplace. Its exact non-interactive CLI bootstrap and upgrade commands are in +[`website/docs/install.md`](website/docs/install.md). Codex marketplace metadata lives at `.agents/plugins/marketplace.json`; Claude plugin marketplace metadata lives at `.claude-plugin/marketplace.json`. Each plugin owns its own manifest and only the @@ -65,7 +75,7 @@ the private organization tooling outside this tree. ## Evals Eight cases under [`evals/`](evals/) — one `eval-case/1` each, judged by a `trace-spec/1` document, -run by the `aep` CLI — name 7 of this repository's 10 agents and 4 of its 8 skills in their +run by the `aep` CLI — name 7 of this repository's 10 agents and 4 of its 7 skills in their `subject:` fields. Those `subject:` fields are the source of truth for eval coverage: every coverage number here and in [`evals/README.md`](evals/README.md) is counted from `evals/*/case.yaml`, never from a prose table. Covered: the agents `aep-drive:adversary`, `aep-drive:story-scoper`, @@ -73,8 +83,8 @@ coverage number here and in [`evals/README.md`](evals/README.md) is counted from `aep-plan:plan-critic-parallel-safety` and `aep-plan:plan-critic-scope`, and the skills `aep-drive:drive`, `aep-drive:wave`, `aep-plan:planning` and `connectors:connectors`. Not covered: the agents `aep-drive:implementor`, `aep-plan:plan-reviewer` and -`aep-plan:reverse-engineer`, and the skills `aep-plan:story-migration`, `beyond10x:beyond10x`, -`beyond10x:plugin-creator` and `workspace-hygiene:worktree`. A change that breaks a covered charter +`aep-plan:reverse-engineer`, and the skills `aep-plan:story-migration`, `beyond10x:beyond10x` and +`beyond10x:plugin-creator`. A change that breaks a covered charter turns a row red instead of being noticed by a reader; a change to an uncovered one does not. Free, offline, and part of `task check`: diff --git a/b10x.docs.yaml b/b10x.docs.yaml index b4d8696..5343233 100644 --- a/b10x.docs.yaml +++ b/b10x.docs.yaml @@ -84,4 +84,4 @@ surfaces: order: 30 sidebar: autogenerated root: website - summary: Navigate and create portable plugins, or install focused AEP planning, AEP delivery, and ESS specification guidance from the curated beyond10x marketplace. + summary: Navigate and create portable plugins, or install focused AEP planning, AEP delivery, and ESS specification guidance from the curated b10x marketplace. diff --git a/crates/agentplugins-check/src/evals.rs b/crates/agentplugins-check/src/evals.rs index 2315fde..392ad86 100644 --- a/crates/agentplugins-check/src/evals.rs +++ b/crates/agentplugins-check/src/evals.rs @@ -940,7 +940,7 @@ fn skill_directory(root: &Path, plugin: &str, name: &str, case: &str) -> Result< /// /// Handled before the marketplace check's own argument match and never inside it, so that adding /// this surface moved three lines of `main` and touched no existing arm. The `Ok` arm there prints -/// *marketplace beyond10x* and would be a false sentence under either verb below. +/// *marketplace b10x* and would be a false sentence under either verb below. pub(crate) fn cli(root: &Path, arguments: &[String]) -> Option { let verdict = match arguments .iter() @@ -1066,10 +1066,10 @@ mod tests { // manifest still pins the pre-0.6.2 spellings, because it is the record of a run that // happened under them — so that replay takes the branch the third test covers, and this one // is about the rule rather than about today's corpus. - let case = case_about(&["aep-plan", "aep-drive", "workspace-hygiene"]); + let case = case_about(&["aep-plan", "aep-drive", "connectors"]); let pins = vec![ "beyond10x/agentplugins@aep-drive@0.6.1".to_owned(), - "beyond10x/agentplugins@workspace-hygiene@0.6.1".to_owned(), + "beyond10x/agentplugins@connectors@0.6.1".to_owned(), ]; assert_eq!( treatment_args(&case, pins), @@ -1079,7 +1079,7 @@ mod tests { "--plugin", "beyond10x/agentplugins@aep-drive@0.6.1", "--plugin", - "beyond10x/agentplugins@workspace-hygiene@0.6.1", + "beyond10x/agentplugins@connectors@0.6.1", ] ); } @@ -1095,7 +1095,7 @@ mod tests { fn an_ambiguous_remainder_sends_the_pins_rather_than_failing_the_gate() { // `--plugin-dir` reaches only the spawn a replay never performs. Refusing here would stop // a replay that would have succeeded, over an argument `aep` discards. - let two_left = case_about(&["aep-plan", "aep-drive", "workspace-hygiene", "extra"]); + let two_left = case_about(&["aep-plan", "aep-drive", "connectors", "extra"]); let pins = vec!["beyond10x/agentplugins@aep-drive@0.6.1".to_owned()]; let args = treatment_args(&two_left, pins.clone()); assert!(!args.iter().any(|a| a == "--plugin-dir"), "{args:?}"); @@ -1287,9 +1287,9 @@ mod tests { #[test] fn a_skill_is_resolved_by_the_name_its_document_declares() { let root = root(); - resolve_skill(&root, "workspace-hygiene:worktree", "t") - .expect("the worktree skill declares `name: worktree` under `skills/worktree/`"); - let error = resolve_skill(&root, "workspace-hygiene:schema-validation", "t") + resolve_skill(&root, "connectors:connectors", "t") + .expect("the connectors skill declares `name: connectors` under `skills/connectors/`"); + let error = resolve_skill(&root, "connectors:schema-validation", "t") .expect_err("a name no SKILL.md declares is not what a harness lists"); assert!(error.contains("declares"), "{error}"); } diff --git a/crates/agentplugins-check/src/main.rs b/crates/agentplugins-check/src/main.rs index f937b2f..aa774a4 100644 --- a/crates/agentplugins-check/src/main.rs +++ b/crates/agentplugins-check/src/main.rs @@ -5,6 +5,10 @@ use std::process::{Command, ExitCode}; mod evals; mod readiness; +mod remote; + +/// The marketplace identity in every marketplace format. +const MARKETPLACE: &str = "b10x"; const PLUGINS: &[(&str, &[&str])] = &[ ( @@ -41,7 +45,6 @@ const PLUGINS: &[(&str, &[&str])] = &[ "agents/adversary.md", ], ), - ("workspace-hygiene", &["skills/worktree/SKILL.md"]), ("connectors", &["skills/connectors/SKILL.md"]), ]; @@ -51,25 +54,37 @@ fn json(path: &Path) -> Result { serde_json::from_str(&text).map_err(|error| format!("parsing {}: {error}", path.display())) } -fn marketplace(root: &Path, relative: &str) -> Result<(), String> { +/// `remote` is whether this marketplace format also lists [`remote::REMOTE`] after the plugins it +/// carries; only the Claude Code format can point into another repository. +fn marketplace(root: &Path, relative: &str, remote: bool) -> Result<(), String> { let document = json(&root.join(relative))?; - if document.get("name").and_then(serde_json::Value::as_str) != Some("beyond10x") { + if document.get("name").and_then(serde_json::Value::as_str) != Some(MARKETPLACE) { return Err(format!( - "{relative} does not declare marketplace `beyond10x`" + "{relative} does not declare marketplace `{MARKETPLACE}`" )); } let entries = document .get("plugins") .and_then(serde_json::Value::as_array) .ok_or_else(|| format!("{relative} has no plugins array"))?; - if entries.len() != PLUGINS.len() { + let expected = PLUGINS + .iter() + .map(|(name, _)| *name) + .chain( + remote::REMOTE + .iter() + .filter(|_| remote) + .map(|remote| remote.name), + ) + .collect::>(); + if entries.len() != expected.len() { return Err(format!( - "{relative} contains {} plugins; expected {} focused plugins", + "{relative} contains {} plugins; expected {}", entries.len(), - PLUGINS.len() + expected.len() )); } - for (index, (plugin, _)) in PLUGINS.iter().enumerate() { + for (index, plugin) in expected.iter().enumerate() { let actual = entries[index] .get("name") .and_then(serde_json::Value::as_str); @@ -235,6 +250,12 @@ const RETIRED: &[Retired] = &[ new: "ess@ess (beyond10x/ess marketplace)", wire_next: &[], }, + // Worktree ships its own plugin from its repository; this marketplace pins it by tag. + Retired { + old: "workspace-hygiene", + new: "worktree@b10x", + wire_next: &[], + }, ]; /// Directories never walked looking for a retired name, wherever they sit. @@ -698,8 +719,9 @@ fn flat_spellings(root: &Path) -> Result<(), String> { } fn check(root: &Path) -> Result<(), String> { - marketplace(root, ".agents/plugins/marketplace.json")?; - marketplace(root, ".claude-plugin/marketplace.json")?; + marketplace(root, ".agents/plugins/marketplace.json", false)?; + marketplace(root, ".claude-plugin/marketplace.json", true)?; + remote::shape(root)?; for (name, required) in PLUGINS { plugin(root, name, required)?; } @@ -748,11 +770,12 @@ fn main() -> ExitCode { } let result = match arguments.as_slice() { [] => check(&root), + [remote] if remote == "remote" => check(&root).and_then(|()| remote::verify(&root)), [release, verify, version] if release == "release" && verify == "verify" => { check(&root).and_then(|()| verify_release(&root, version)) } _ => Err( - "usage: agentplugins-check [release verify | evals | evals scope ...]" + "usage: agentplugins-check [remote | release verify | evals | evals scope ...]" .to_owned(), ), }; @@ -760,8 +783,9 @@ fn main() -> ExitCode { match result { Ok(()) => { println!( - "valid: marketplace beyond10x, {} focused plugin(s)", - PLUGINS.len() + "valid: marketplace {MARKETPLACE}, {} focused plugin(s), {} remote plugin(s)", + PLUGINS.len(), + remote::REMOTE.len() ); ExitCode::SUCCESS } diff --git a/crates/agentplugins-check/src/remote.rs b/crates/agentplugins-check/src/remote.rs new file mode 100644 index 0000000..4d5331b --- /dev/null +++ b/crates/agentplugins-check/src/remote.rs @@ -0,0 +1,333 @@ +//! Plugins this marketplace lists but does not carry. +//! +//! A product that ships its own plugin keeps the plugin beside the binary it describes, at the +//! binary's version, so the two cannot drift. This marketplace only points at it: a `git-subdir` +//! entry naming the product repository, the plugin directory, a release tag and that tag's full +//! commit. Pointing at a tag is what lets the catalog go stale instead, so the two halves below +//! check it from both sides: +//! +//! - [`shape`] runs in the offline gate and refuses an entry that is not a pinned `git-subdir` at +//! the declared repository and path. +//! - [`verify`] runs with network access (`agentplugins-check remote`, on every pull request, `main` +//! push and a daily schedule) and refuses a `sha` that is not the tag's commit, a manifest at that +//! commit whose version is not the tag, and a tag that is not the repository's newest release. + +use std::path::Path; +use std::process::Command; + +/// One plugin that lives in its product's own repository. +pub struct Remote { + /// Plugin and manifest name. + pub name: &'static str, + /// The only repository the entry may point at. + pub url: &'static str, + /// The plugin directory inside that repository. + pub path: &'static str, +} + +/// Every plugin this marketplace lists from another repository, in marketplace order after the +/// plugins it carries. +pub const REMOTE: &[Remote] = &[Remote { + name: "worktree", + url: "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/beyond10x/worktree.git", + path: "plugins/worktree", +}]; + +/// The Claude Code marketplace file; Codex reads no remote entries. +const CLAUDE_MARKETPLACE: &str = ".claude-plugin/marketplace.json"; + +/// A pinned entry as the marketplace declares it. +pub struct Pin { + /// Which remote plugin. + pub remote: &'static Remote, + /// Release tag. + pub tag: String, + /// The tag's full commit. + pub sha: String, +} + +fn bare_version(tag: &str) -> Option<(u64, u64, u64)> { + let mut parts = tag.split('.'); + let version = ( + parts.next()?.parse().ok()?, + parts.next()?.parse().ok()?, + parts.next()?.parse().ok()?, + ); + parts.next().is_none().then_some(version) +} + +fn full_sha(sha: &str) -> bool { + sha.len() == 40 + && sha + .bytes() + .all(|byte| byte.is_ascii_hexdigit() && !byte.is_ascii_uppercase()) +} + +/// Read and check every remote entry's shape, without the network. +pub fn shape(root: &Path) -> Result, String> { + let document = super::json(&root.join(CLAUDE_MARKETPLACE))?; + let entries = document + .get("plugins") + .and_then(serde_json::Value::as_array) + .ok_or_else(|| format!("{CLAUDE_MARKETPLACE} has no plugins array"))?; + let mut pins = Vec::new(); + for remote in REMOTE { + let entry = entries + .iter() + .find(|entry| { + entry.get("name").and_then(serde_json::Value::as_str) == Some(remote.name) + }) + .ok_or_else(|| format!("{CLAUDE_MARKETPLACE} does not list `{}`", remote.name))?; + let source = entry + .get("source") + .ok_or_else(|| format!("`{}` has no source", remote.name))?; + let field = |key: &str| source.get(key).and_then(serde_json::Value::as_str); + if field("source") != Some("git-subdir") { + return Err(format!("`{}` source is not `git-subdir`", remote.name)); + } + if field("url") != Some(remote.url) || field("path") != Some(remote.path) { + return Err(format!( + "`{}` must point at {} path {}", + remote.name, remote.url, remote.path + )); + } + let tag = field("ref").unwrap_or_default(); + if bare_version(tag).is_none() { + return Err(format!( + "`{}` ref `{tag}` is not a bare release tag", + remote.name + )); + } + let sha = field("sha").unwrap_or_default(); + if !full_sha(sha) { + return Err(format!( + "`{}` sha `{sha}` is not a full commit", + remote.name + )); + } + if entry.get("version").is_some() { + return Err(format!( + "`{}` declares a version; the manifest at the pinned commit owns it", + remote.name + )); + } + pins.push(Pin { + remote, + tag: tag.to_owned(), + sha: sha.to_owned(), + }); + } + Ok(pins) +} + +fn git(arguments: &[&str], directory: Option<&Path>) -> Result { + let mut command = Command::new("git"); + command.args(arguments); + if let Some(directory) = directory { + command.current_dir(directory); + } + let output = command + .output() + .map_err(|error| format!("running git {}: {error}", arguments.join(" ")))?; + if !output.status.success() { + return Err(format!( + "git {} failed: {}", + arguments.join(" "), + String::from_utf8_lossy(&output.stderr).trim() + )); + } + String::from_utf8(output.stdout).map_err(|error| format!("git output: {error}")) +} + +/// The commit each release tag of `url` points at, peeled through annotated tags. +fn tags(url: &str) -> Result, String> { + let listing = git(&["ls-remote", "--tags", url], None)?; + let mut direct = std::collections::BTreeMap::new(); + let mut peeled = std::collections::BTreeMap::new(); + for line in listing.lines() { + let Some((sha, reference)) = line.split_once('\t') else { + continue; + }; + let Some(name) = reference.strip_prefix("refs/tags/") else { + continue; + }; + match name.strip_suffix("^{}") { + Some(name) => peeled.insert(name.to_owned(), sha.to_owned()), + None => direct.insert(name.to_owned(), sha.to_owned()), + }; + } + Ok(direct + .into_iter() + .filter(|(name, _)| bare_version(name).is_some()) + .map(|(name, sha)| { + let commit = peeled.remove(&name).unwrap_or(sha); + (name, commit) + }) + .collect()) +} + +/// Check every pin against its repository. Needs the network and `git`. +pub fn verify(root: &Path) -> Result<(), String> { + for pin in shape(root)? { + let name = pin.remote.name; + let releases = tags(pin.remote.url)?; + let commit = releases + .iter() + .find(|(tag, _)| *tag == pin.tag) + .map(|(_, commit)| commit) + .ok_or_else(|| format!("`{name}`: {} has no tag `{}`", pin.remote.url, pin.tag))?; + if *commit != pin.sha { + return Err(format!( + "`{name}`: sha {} is not tag `{}` ({commit})", + pin.sha, pin.tag + )); + } + let newest = releases + .iter() + .filter_map(|(tag, _)| bare_version(tag).map(|version| (version, tag))) + .max() + .map(|(_, tag)| tag.clone()) + .unwrap_or_default(); + if newest != pin.tag { + return Err(format!( + "`{name}` pins `{}`; {} has released `{newest}`", + pin.tag, pin.remote.url + )); + } + + let scratch = std::env::temp_dir().join(format!( + "agentplugins-check-{name}-{}-{}", + std::process::id(), + &pin.sha[..12] + )); + let _ = std::fs::remove_dir_all(&scratch); + std::fs::create_dir_all(&scratch) + .map_err(|error| format!("creating {}: {error}", scratch.display()))?; + let result = (|| { + git(&["init", "--quiet", "--bare"], Some(&scratch))?; + git( + &["fetch", "--quiet", "--depth", "1", pin.remote.url, &pin.sha], + Some(&scratch), + )?; + for manifest in [".claude-plugin/plugin.json", ".codex-plugin/plugin.json"] { + let text = git( + &[ + "show", + &format!("{}:{}/{manifest}", pin.sha, pin.remote.path), + ], + Some(&scratch), + )?; + let document: serde_json::Value = serde_json::from_str(&text) + .map_err(|error| format!("`{name}` {manifest}: {error}"))?; + if document.get("name").and_then(serde_json::Value::as_str) != Some(name) { + return Err(format!("`{name}` {manifest} carries another plugin name")); + } + let version = document.get("version").and_then(serde_json::Value::as_str); + if version != Some(pin.tag.as_str()) { + return Err(format!( + "`{name}` {manifest} at {} declares version {version:?}, not `{}`", + pin.sha, pin.tag + )); + } + } + Ok(()) + })(); + let _ = std::fs::remove_dir_all(&scratch); + result?; + println!( + "remote `{name}`: {} at {} is the newest release", + pin.tag, pin.sha + ); + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn release_tags_are_bare_semver() { + assert_eq!(bare_version("0.6.0"), Some((0, 6, 0))); + assert_eq!(bare_version("v0.6.0"), None); + assert_eq!(bare_version("0.6"), None); + assert_eq!(bare_version("0.6.0.1"), None); + } + + #[test] + fn a_sha_is_forty_lowercase_hex() { + assert!(full_sha(&"a".repeat(40))); + assert!(!full_sha(&"A".repeat(40))); + assert!(!full_sha(&"a".repeat(39))); + } + + fn marketplace_with(source: &serde_json::Value) -> tempdir::Scratch { + let scratch = tempdir::Scratch::new(); + let path = scratch.0.join(".claude-plugin"); + std::fs::create_dir_all(&path).unwrap(); + let document = serde_json::json!({ + "name": "b10x", + "plugins": [{"name": "worktree", "source": source}], + }); + std::fs::write(path.join("marketplace.json"), document.to_string()).unwrap(); + scratch + } + + mod tempdir { + pub struct Scratch(pub std::path::PathBuf); + impl Scratch { + pub fn new() -> Self { + use std::sync::atomic::{AtomicUsize, Ordering}; + static NEXT: AtomicUsize = AtomicUsize::new(0); + let path = std::env::temp_dir().join(format!( + "agentplugins-check-remote-test-{}-{}", + std::process::id(), + NEXT.fetch_add(1, Ordering::SeqCst) + )); + std::fs::create_dir_all(&path).unwrap(); + Self(path) + } + } + impl Drop for Scratch { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.0); + } + } + } + + fn pinned() -> serde_json::Value { + serde_json::json!({ + "source": "git-subdir", + "url": "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/beyond10x/worktree.git", + "path": "plugins/worktree", + "ref": "0.6.0", + "sha": "a".repeat(40), + }) + } + + #[test] + fn a_pinned_git_subdir_entry_passes() { + let scratch = marketplace_with(&pinned()); + let pins = shape(&scratch.0).expect("pinned entry"); + assert_eq!(pins[0].tag, "0.6.0"); + } + + #[test] + fn an_unpinned_or_redirected_entry_fails() { + for (key, value) in [ + ("sha", serde_json::json!("abc")), + ("ref", serde_json::json!("main")), + ( + "url", + serde_json::json!("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/someone/worktree.git"), + ), + ("path", serde_json::json!("plugins/other")), + ("source", serde_json::json!("github")), + ] { + let mut source = pinned(); + source[key] = value; + let scratch = marketplace_with(&source); + assert!(shape(&scratch.0).is_err(), "{key} change must be refused"); + } + } +} diff --git a/evals/README.md b/evals/README.md index ff89578..65f60fb 100644 --- a/evals/README.md +++ b/evals/README.md @@ -17,7 +17,7 @@ A case is four things and no others: Every cell in the middle column is that case's `subject:` in full, read from its `case.yaml`, and those fields — not this table and not any prose elsewhere — are the source of truth for what the corpus covers: counted from them the eight cases name **7 of this repository's 10 agents** and -**4 of its 8 skills**. +**4 of its 7 skills**. | Case | `subject:` agents and skills | The claim it holds the subject to | |---|---|---| @@ -31,8 +31,8 @@ corpus covers: counted from them the eight cases name **7 of this repository's 1 | `connectors-readiness` | `connectors:connectors` | diagnosis uses the CLI; help is allowed and Connector mutations are rejected | No case names the agents `aep-drive:implementor`, `aep-plan:plan-reviewer` or -`aep-plan:reverse-engineer`, nor the skills `aep-plan:story-migration`, `beyond10x:beyond10x`, -`beyond10x:plugin-creator` or `workspace-hygiene:worktree`; those seven are +`aep-plan:reverse-engineer`, nor the skills `aep-plan:story-migration`, `beyond10x:beyond10x` or +`beyond10x:plugin-creator`; those six are the remaining scope of `story:plugin-eval-cases` in `.engineering/planning`, and a change to one of them turns no row red. diff --git a/plugins/aep-drive/.claude-plugin/plugin.json b/plugins/aep-drive/.claude-plugin/plugin.json index a0d5187..c76b0db 100644 --- a/plugins/aep-drive/.claude-plugin/plugin.json +++ b/plugins/aep-drive/.claude-plugin/plugin.json @@ -2,7 +2,7 @@ "name": "aep-drive", "displayName": "AEP Drive", "description": "Coordinate AEP development waves, story scoping, implementation, and adversarial review.", - "version": "0.10.0", + "version": "0.11.0", "author": { "name": "Beyond10x" }, "license": "Apache-2.0", "repository": "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/beyond10x/agentplugins", diff --git a/plugins/aep-drive/.codex-plugin/plugin.json b/plugins/aep-drive/.codex-plugin/plugin.json index ab18da7..1ddd58e 100644 --- a/plugins/aep-drive/.codex-plugin/plugin.json +++ b/plugins/aep-drive/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "aep-drive", - "version": "0.10.0", + "version": "0.11.0", "description": "Coordinate AEP development waves with scoped implementors and adversarial review.", "author": { "name": "Beyond10x" diff --git a/plugins/aep-drive/skills/wave/SKILL.md b/plugins/aep-drive/skills/wave/SKILL.md index e8f24f2..6667c66 100644 --- a/plugins/aep-drive/skills/wave/SKILL.md +++ b/plugins/aep-drive/skills/wave/SKILL.md @@ -3,7 +3,7 @@ name: wave description: Run a wave — pick the next set of stories that can be implemented at once, propose it for approval, then dispatch one implementor per story into its own worktree, send each result to the adversary, and merge what goes green into one integration branch. Use when the operator asks to pick the next wave, to start a wave, to implement several stories in parallel, or to fan out work across sub-agents. Proposes first and stops; it never starts a wave nobody approved. --- -**Skill version 0.10.0** — the version in `.claude-plugin/plugin.json`; the stage-1 proposal quotes it. +**Skill version 0.11.0** — the version in `.claude-plugin/plugin.json`; the stage-1 proposal quotes it. # Running a wave @@ -378,7 +378,7 @@ It costs seconds. One integration branch for the wave; one branch and one worktree per unit, each forked from the integration branch. -Invoke the `workspace-hygiene:worktree` skill and create every checkout with `worktree create`, +Invoke the `worktree:worktree` skill and create every checkout with `worktree create`, including the coordinator's integration checkout. Record each managed id, owning session, story/task id and published branch alongside the paths below. Acquire a coordinator lease before using a tree and renew it while agents or checks run. Each implementor and adversary maintains diff --git a/plugins/aep-plan/.claude-plugin/plugin.json b/plugins/aep-plan/.claude-plugin/plugin.json index 38cb672..0b20fef 100644 --- a/plugins/aep-plan/.claude-plugin/plugin.json +++ b/plugins/aep-plan/.claude-plugin/plugin.json @@ -2,7 +2,7 @@ "name": "aep-plan", "displayName": "AEP Plan", "description": "Govern AEP planning artifacts, decomposition, review, and reverse engineering.", - "version": "0.10.0", + "version": "0.11.0", "author": { "name": "Beyond10x" }, "license": "Apache-2.0", "repository": "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/beyond10x/agentplugins", diff --git a/plugins/aep-plan/.codex-plugin/plugin.json b/plugins/aep-plan/.codex-plugin/plugin.json index d148a4f..a78898c 100644 --- a/plugins/aep-plan/.codex-plugin/plugin.json +++ b/plugins/aep-plan/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "aep-plan", - "version": "0.10.0", + "version": "0.11.0", "description": "Govern AEP planning artifacts and review plans without bypassing their lifecycle.", "author": { "name": "Beyond10x" diff --git a/plugins/aep-plan/skills/planning/SKILL.md b/plugins/aep-plan/skills/planning/SKILL.md index 9557e4e..a75fc60 100644 --- a/plugins/aep-plan/skills/planning/SKILL.md +++ b/plugins/aep-plan/skills/planning/SKILL.md @@ -3,7 +3,7 @@ name: planning description: Plan engineering work in a governed markdown artifact store — create, relate, move and validate epics, stories, tasks and initiatives through the `aep` CLI. Use when the user mentions planning, a backlog, an epic, a story, a task, decomposing or breaking down work, an artifact's status ("move this to active", "what is still in draft?", "why can't this be implemented?"), or when the project contains a `.engineering/planning/` directory. Use it at adoption too — the user asks to adopt AEP, to migrate from or replace the track plugin, to start a first backlog, or works in a repository with no `.engineering/` directory at all — because § 5 says how a first store is populated and it is worth nothing after one has been hand-written. Also use before editing any file under `.engineering/planning/`. --- -**Skill version 0.10.0** — the version in `.claude-plugin/plugin.json`. +**Skill version 0.11.0** — the version in `.claude-plugin/plugin.json`. # Planning in a governed artifact store diff --git a/plugins/aep-plan/skills/story-migration/SKILL.md b/plugins/aep-plan/skills/story-migration/SKILL.md index 96a9d1e..fb88f3a 100644 --- a/plugins/aep-plan/skills/story-migration/SKILL.md +++ b/plugins/aep-plan/skills/story-migration/SKILL.md @@ -3,7 +3,7 @@ name: story-migration description: Migrate a repository's legacy work tracking — story trees, TODO.md, plan and issue documents — into the governed AEP planning store, without deleting or rewriting the sources. Use when the user asks to migrate, import, port or convert an existing backlog into AEP, when a repository is adopting AEP and already has work written down somewhere, or when a store has been adopted beside a legacy backlog nobody retired. Read it before creating the first artifact in a repository that already tracks work in markdown. --- -**Skill version 0.10.0** — the version in `.claude-plugin/plugin.json`. +**Skill version 0.11.0** — the version in `.claude-plugin/plugin.json`. # Migrating legacy tracking into the store diff --git a/plugins/beyond10x/.claude-plugin/plugin.json b/plugins/beyond10x/.claude-plugin/plugin.json index d595fea..b345f1f 100644 --- a/plugins/beyond10x/.claude-plugin/plugin.json +++ b/plugins/beyond10x/.claude-plugin/plugin.json @@ -2,7 +2,7 @@ "name": "beyond10x", "displayName": "Beyond10x", "description": "Route work to focused Beyond10x plugins and create portable plugins for Codex and Claude Code.", - "version": "0.10.0", + "version": "0.11.0", "author": { "name": "Beyond10x" }, "license": "Apache-2.0", "repository": "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/beyond10x/agentplugins", diff --git a/plugins/beyond10x/.codex-plugin/plugin.json b/plugins/beyond10x/.codex-plugin/plugin.json index e46a3ec..48f73ac 100644 --- a/plugins/beyond10x/.codex-plugin/plugin.json +++ b/plugins/beyond10x/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "beyond10x", - "version": "0.10.0", + "version": "0.11.0", "description": "Route work to focused Beyond10x plugins and create portable plugins for Codex and Claude Code.", "author": { "name": "Beyond10x" diff --git a/plugins/beyond10x/skills/beyond10x/SKILL.md b/plugins/beyond10x/skills/beyond10x/SKILL.md index e302671..834e391 100644 --- a/plugins/beyond10x/skills/beyond10x/SKILL.md +++ b/plugins/beyond10x/skills/beyond10x/SKILL.md @@ -27,7 +27,7 @@ Route the request; do not reproduce a specialist plugin's full workflow. | Plan or decompose work, review a plan, or reverse-engineer a backlog | `aep-plan` | | Scope and deliver accepted development work through a reviewed wave | `aep-drive` | | Specify, retrofit or conformance-test an ESS model | the `ess` plugin from the `beyond10x/ess` marketplace (`ess skill` prints the same skills) | -| Create, inspect, finish, or safely clean Git worktrees | `workspace-hygiene` | +| Create, inspect, finish, or safely clean Git worktrees | `worktree` (from the `b10x` marketplace, released with the `worktree` binary) | | Set up providers, inspect Connector readiness, or invoke configured integrations through the CLI | `connectors` | ## Preserve boundaries diff --git a/plugins/beyond10x/skills/beyond10x/references/resources.md b/plugins/beyond10x/skills/beyond10x/references/resources.md index 5cbe10b..34e028d 100644 --- a/plugins/beyond10x/skills/beyond10x/references/resources.md +++ b/plugins/beyond10x/skills/beyond10x/references/resources.md @@ -11,7 +11,7 @@ Use the narrowest link that answers the request. | [AEP Plan plugin](https://beyond10x.github.io/agentplugins/docs/plugins/aep-plan) | Governed planning skill and specialist planning agents | | [AEP Drive plugin](https://beyond10x.github.io/agentplugins/docs/plugins/aep-drive) | Development-wave roles and coordination | | [ESS agent plugin](https://github.com/beyond10x/ess#point-your-agent-here) | ESS specification, retrofit, validation, projection and conformance guidance, released with the `ess` binary | -| [Workspace Hygiene plugin](https://beyond10x.github.io/agentplugins/docs/plugins/workspace-hygiene) | Managed Git worktree lifecycle and cleanup guidance | +| [Worktree plugin](https://beyond10x.github.io/agentplugins/docs/plugins/worktree) | Managed Git worktree lifecycle and cleanup guidance, released with the `worktree` binary | | [AEP](https://beyond10x.github.io/aep/) | Protocol concepts, commands, and adopter documentation | | [AEP Service](https://beyond10x.github.io/aep-service/) | Hosted AEP service boundary and operations | | [ESS](https://beyond10x.github.io/ess/) | Executable System Specification model, CLI, and adapters | diff --git a/plugins/connectors/.claude-plugin/plugin.json b/plugins/connectors/.claude-plugin/plugin.json index 9b3ec32..8ee2aa0 100644 --- a/plugins/connectors/.claude-plugin/plugin.json +++ b/plugins/connectors/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "connectors", - "version": "0.10.0", + "version": "0.11.0", "description": "Set up, inspect, and invoke governed integrations through the connectors CLI.", "author": { "name": "Beyond10x" }, "license": "Apache-2.0", diff --git a/plugins/connectors/.codex-plugin/plugin.json b/plugins/connectors/.codex-plugin/plugin.json index 53d7289..38750fc 100644 --- a/plugins/connectors/.codex-plugin/plugin.json +++ b/plugins/connectors/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "connectors", - "version": "0.10.0", + "version": "0.11.0", "description": "Set up, inspect, and invoke governed integrations through the connectors CLI.", "author": { "name": "Beyond10x" }, "license": "Apache-2.0", diff --git a/plugins/workspace-hygiene/.claude-plugin/plugin.json b/plugins/workspace-hygiene/.claude-plugin/plugin.json deleted file mode 100644 index 9494d87..0000000 --- a/plugins/workspace-hygiene/.claude-plugin/plugin.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "workspace-hygiene", - "displayName": "Workspace Hygiene", - "description": "Use the public worktree toolchain for safe, recoverable agent checkout lifecycle.", - "version": "0.10.0", - "author": { "name": "Beyond10x" }, - "license": "Apache-2.0", - "repository": "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/beyond10x/agentplugins", - "keywords": ["beyond10x", "git", "worktree", "agents", "workspace-hygiene"] -} diff --git a/plugins/workspace-hygiene/.codex-plugin/plugin.json b/plugins/workspace-hygiene/.codex-plugin/plugin.json deleted file mode 100644 index b975a2c..0000000 --- a/plugins/workspace-hygiene/.codex-plugin/plugin.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "workspace-hygiene", - "version": "0.10.0", - "description": "Use the public worktree toolchain for safe, recoverable agent checkout lifecycle.", - "author": { - "name": "Beyond10x" - }, - "skills": "./skills/", - "interface": { - "displayName": "Workspace Hygiene", - "shortDescription": "Keep agent worktrees isolated and recoverable.", - "longDescription": "Create, lease, finish, audit, and safely clean Git worktrees through the versioned public worktree CLI instead of ad hoc host conventions.", - "developerName": "Beyond10x", - "category": "Productivity", - "capabilities": [], - "defaultPrompt": "Use the worktree skill to prepare an isolated checkout for this task and preserve safe cleanup evidence." - } -} diff --git a/plugins/workspace-hygiene/skills/worktree/SKILL.md b/plugins/workspace-hygiene/skills/worktree/SKILL.md deleted file mode 100644 index 296e119..0000000 --- a/plugins/workspace-hygiene/skills/worktree/SKILL.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -name: worktree -description: Safely create, inspect, finish, reconcile, recover, and garbage-collect managed Git worktrees. Use whenever an agent needs an isolated checkout for repository changes, must hand off a worktree, or needs to audit, recover, or clean linked worktrees. ---- - -# Worktree - - - -Use the `worktree` CLI as the sole owner of linked-worktree lifecycle. It keeps trees outside primary checkout collections and refuses cleanup without current recovery proof. - -## Start repository work - -1. Invoke `$worktree`, then from a primary checkout run `worktree create --purpose `. Add `--repo `, `--base `, or `--id ` when needed. -2. Treat the printed path as the task checkout and do all changes there. -3. If already inside a managed tree, reuse it; do not nest another worktree. -4. For automation, add `--json` and consume the versioned output. - -## Maintain the lease - -Acquire a lease before changing the tree: run `worktree hook session-start --path --session `. Use a stable id unique to this session. If the host does not demonstrably run lifecycle hooks, run these commands yourself; loading this skill does not install hooks. - -Run `worktree hook heartbeat --path --session ` periodically during long work, before the configured lease expiry, including while builds or external checks are running. Check each result. A live lease blocks cleanup; a missing or expired lease does not prove that another session has stopped. - -Release only your own lease with `worktree hook session-end --path --session ` when leaving or immediately before finish. Never clear another session's lease to make cleanup pass. - -## Bound disposable storage - -Before a large build, inspect free space and `worktree inspect --repo --id `. Keep compiler caches and dependencies separate from source and retained evidence. Prefer a repository-supported cache location and bounded build settings; do not force a shared target directory across incompatible build configurations. - -After verification, preserve the small logs, reports, or deliverables needed for review in their intended durable location. Remove only exact build or dependency directories known to be reproducible, owned by this task, and unused by any running process. Ignored files can contain valuable work: never blanket-delete them or use `git clean -fdx`. A worktree saves duplicate Git history; its build output still consumes disk and is not automatically reclaimed. - -## Finish and clean up - -1. Commit and publish every wanted change. A local-only commit is deliberately not cleanup-safe. -2. Preserve required evidence and remove this task's disposable output as described above. Release your own lease, then run `worktree finish `. It refuses dirty, locked, unmanaged, live, or mid-operation Git worktrees. -3. Run `worktree gc --repo --dry-run --id ` and inspect every result. Without exact ids, `--repo` selects the activated workspace profile, not just the repository: the assessment covers records under that profile's `workspace_root`, including other repositories. -4. Run `worktree gc --repo --apply --id ` with repeated `--id` values only for the exact results intended for removal. The command refreshes remote advertisements, fetches required objects, and revalidates immediately before non-forced removal. Check the result before reporting storage reclaimed. -5. End with either verified cleanup or an explicit handoff: tree id and path, published branch/commit, related work-item references, retained evidence, remaining blockers, next owner and next action. Never leave a tree silently active or label work complete merely from its age or Git state. - -## Audit and recovery - -- Run `worktree inspect --repo ` for actual Git state, separate ignored-file counts, storage, leases, and retention blockers. It defaults to that repository; add `--workspace` to expand to its profile and repeat `--id` to narrow the selection. Sizes are bounded observations, not promised reclaimable bytes. Add `--refresh` for fresh remote recovery evidence (which may fetch objects). Inspection never changes lifecycle or infers owner abandonment or story completion; review GC separately before removal. -- Run `worktree status` for durable lifecycle state. It accepts no filter and reports every record in every profile, so read `repository_root` on each one before acting. -- Run `worktree repo list --repo ` to distinguish managed, unmanaged, primary, and linked checkouts. -- Run `worktree reconcile --repo --dry-run` to assess interrupted provisioning, adopted legacy paths, finished external trees, and missing records. -- Apply reconciliation only to ids copied from that immediately preceding dry-run with `worktree reconcile --repo --apply --id ` and repeated `--id` arguments when needed. -- If that dry-run explicitly proposes `retire-external`, confirm that destructive action separately by adding `--allow-external-retirement`; never add it for an unrelated migration or missing-record repair. -- A finished external legacy tree may supersede a stale migration intent only when the dry-run itself proposes `retire-external`; never reinterpret or bypass a cross-device or ambiguous-relocation refusal. -- If removal is interrupted while the path still exists, rerun GC dry-run and exact-id apply. If the path is already absent, use reconciliation dry-run and exact-id apply; its durable removal intent can safely finish the recorded transition. -- A missing Active record without matching durable removal intent must remain refused. Preserve and investigate its registry evidence; never manually tombstone it, delete related state, or fabricate recovery proof. -- Run `worktree doctor --check` for prerequisites and configuration. -- Only after a human explicitly decides an existing linked tree should become manager-owned, run `worktree repo adopt --repo --path --id --purpose `. Then review `reconcile --dry-run` and use exact-id apply only if migration is intended. - -Never run `git worktree remove --force`, recursively delete a linked tree, place managed trees below the primary workspace, or clean up a tree merely because it looks old. diff --git a/plugins/workspace-hygiene/skills/worktree/agents/openai.yaml b/plugins/workspace-hygiene/skills/worktree/agents/openai.yaml deleted file mode 100644 index f29d05f..0000000 --- a/plugins/workspace-hygiene/skills/worktree/agents/openai.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# Generated by `worktree skill`; edit the generator, not this file. -interface: - display_name: "Worktree" - short_description: "Safely manage isolated Git worktree lifecycles" - default_prompt: "Use $worktree and its CLI to create or maintain an isolated checkout, preserve recovery evidence, reconcile lifecycle state, and clean it up safely." diff --git a/website/docs/choose-a-plugin.md b/website/docs/choose-a-plugin.md index 21cd167..01262cb 100644 --- a/website/docs/choose-a-plugin.md +++ b/website/docs/choose-a-plugin.md @@ -35,7 +35,7 @@ them. ## Managing repository workspaces -Use **Workspace Hygiene** before an agent changes a repository or when linked worktrees need an +Use **Worktree** before an agent changes a repository or when linked worktrees need an inventory or cleanup sweep. Its skill is generated by the public `worktree` CLI, so the documented commands and the executable safety policy stay aligned. The plugin does not delete unmanaged trees or replace the standalone toolchain. diff --git a/website/docs/install.md b/website/docs/install.md index ef5dc98..52ba2c8 100644 --- a/website/docs/install.md +++ b/website/docs/install.md @@ -3,11 +3,13 @@ sidebar_position: 3 title: Install --- -# Install from the `beyond10x` marketplace +# Install from the `b10x` marketplace The marketplace source is the GitHub repository `beyond10x/agentplugins` and the marketplace -identity is `beyond10x`. The installable names are `beyond10x`, `aep-plan`, `aep-drive`, -`workspace-hygiene`, and `connectors`. The [Connectors guide](plugins/connectors.md) covers its +identity is `b10x`. The installable names are `beyond10x`, `aep-plan`, `aep-drive`, `connectors` +and, in Claude Code, `worktree`. `worktree` ships from the +[worktree repository](https://github.com/beyond10x/worktree) at the version of the `worktree` +binary; this marketplace pins it by release tag and commit. The [Connectors guide](plugins/connectors.md) covers its separate CLI prerequisite. The ESS plugin is not in this marketplace. It ships from the @@ -90,33 +92,34 @@ The wave skill, the planning skill and every other plugin need no Metaharness. Copy the whole block into a Claude Code session: ```text -/plugin marketplace add https://github.com/beyond10x/agentplugins.git#0.10.0 -/plugin install aep-plan@beyond10x -/plugin install aep-drive@beyond10x +/plugin marketplace add https://github.com/beyond10x/agentplugins.git#0.11.0 +/plugin install aep-plan@b10x +/plugin install aep-drive@b10x /reload-plugins ``` -The first line registers the repository at the immutable `0.10.0` release; each install names its -plugin in the `@beyond10x` form. `/reload-plugins` activates them immediately. Add -`/plugin install beyond10x@beyond10x` for the front door and -`/plugin install workspace-hygiene@beyond10x` for managed worktrees, or -`/plugin install connectors@beyond10x` for integrations. Claude Code reads +The first line registers the repository at the immutable `0.11.0` release; each install names its +plugin in the `@b10x` form. `/reload-plugins` activates them immediately. Add +`/plugin install beyond10x@b10x` for the front door and +`/plugin install worktree@b10x` for managed worktrees, or +`/plugin install connectors@b10x` for integrations. Claude Code reads `.claude-plugin/marketplace.json` and the selected plugin's `.claude-plugin/plugin.json`. See [Claude Code's plugin documentation](https://code.claude.com/docs/en/discover-plugins) for the host commands and supported marketplace sources. ## Codex -Codex offers the same plugins from the same repository under the same `beyond10x` identity. -For a fresh installation, run this release-pinned block: +Codex offers the four plugins this repository carries under the same `b10x` identity. It reads +`worktree` from the worktree repository instead: +`codex plugin marketplace add https://github.com/beyond10x/worktree.git --ref `, then +`codex plugin add worktree@worktree`. For a fresh installation, run this release-pinned block: ```bash -codex plugin marketplace add https://github.com/beyond10x/agentplugins.git --ref 0.10.0 -codex plugin add beyond10x@beyond10x -codex plugin add aep-plan@beyond10x -codex plugin add aep-drive@beyond10x -codex plugin add workspace-hygiene@beyond10x -codex plugin add connectors@beyond10x +codex plugin marketplace add https://github.com/beyond10x/agentplugins.git --ref 0.11.0 +codex plugin add beyond10x@b10x +codex plugin add aep-plan@b10x +codex plugin add aep-drive@b10x +codex plugin add connectors@b10x ``` An immutable marketplace pin does not advance when `codex plugin marketplace upgrade` runs. To @@ -124,12 +127,11 @@ replace an older pin, remove the installed plugins and marketplace registration, block above: ```bash -codex plugin remove beyond10x@beyond10x -codex plugin remove aep-plan@beyond10x -codex plugin remove aep-drive@beyond10x -codex plugin remove workspace-hygiene@beyond10x -codex plugin remove connectors@beyond10x -codex plugin marketplace remove beyond10x +codex plugin remove beyond10x@b10x +codex plugin remove aep-plan@b10x +codex plugin remove aep-drive@b10x +codex plugin remove connectors@b10x +codex plugin marketplace remove b10x ``` The commands leave every focused plugin installed and enabled. Start a new Codex thread afterwards; @@ -142,7 +144,7 @@ The `aep` binary requirement above applies unchanged. ## Pinning -The blocks above are already pinned to the bare `0.10.0` release tag. Upgrade by changing that tag +The blocks above are already pinned to the bare `0.11.0` release tag. Upgrade by changing that tag deliberately, re-registering the marketplace source, and running `/reload-plugins`. The release gate validates both marketplace formats, every declared instruction file, the public documentation, and the version recorded by each plugin manifest. diff --git a/website/docs/intro.md b/website/docs/intro.md index 8279016..1a7d91a 100644 --- a/website/docs/intro.md +++ b/website/docs/intro.md @@ -2,12 +2,12 @@ sidebar_position: 1 slug: / title: Agent Plugins -description: The curated beyond10x marketplace for focused engineering-agent guidance. +description: The curated b10x marketplace for focused engineering-agent guidance. --- # Focused guidance, explicit scope -The `beyond10x` marketplace publishes a front door and four specialist plugins. Install the front +The `b10x` marketplace publishes a front door and four specialist plugins. Install the front door when you want routing, ecosystem resources, or portable plugin creation. Install a specialist directly when the work is already clear. @@ -16,7 +16,7 @@ directly when the work is already clear. | [`beyond10x`](./plugins/beyond10x.md) | Marketplace navigation and plugin authoring | router, public resource map, portable plugin creator | | [`aep-plan`](./plugins/aep-plan.md) | Governed plans and artifact stores | planning skill, decomposer, plan reviewer, reverse engineer | | [`aep-drive`](./plugins/aep-drive.md) | Governed development delivery | wave skill, story scoper, implementor, adversary | -| [`workspace-hygiene`](./plugins/workspace-hygiene.md) | Git workspaces | managed worktrees, leases, recovery proof, and safe cleanup | +| [`worktree`](./plugins/worktree.md) | Git workspaces | managed worktrees, leases, recovery proof, and safe cleanup | Executable System Specifications have their own plugin, `ess`, served by the [ESS repository](https://github.com/beyond10x/ess#point-your-agent-here) at the version of the diff --git a/website/docs/plugins/beyond10x.md b/website/docs/plugins/beyond10x.md index 16482a0..2391cba 100644 --- a/website/docs/plugins/beyond10x.md +++ b/website/docs/plugins/beyond10x.md @@ -10,7 +10,7 @@ capabilities portable across Codex and Claude Code. It provides: -- a `beyond10x` routing skill for selecting `aep-plan`, `aep-drive`, `workspace-hygiene`, +- a `beyond10x` routing skill for selecting `aep-plan`, `aep-drive`, `worktree`, `connectors`, or the ESS repository's own `ess` plugin; - direct links to public product guides, command references, plugin references, and source; - a `plugin-creator` skill for creating or porting dual-harness plugins. @@ -38,6 +38,6 @@ the governed workflow: - [`aep-plan`](./aep-plan.md) for plans and artifact stores; - [`aep-drive`](./aep-drive.md) for accepted development work; - the [ESS repository's `ess` plugin](https://github.com/beyond10x/ess#point-your-agent-here) for ESS specification, retrofit, validation and conformance; -- [`workspace-hygiene`](./workspace-hygiene.md) for managed Git worktrees and safe cleanup. +- [`worktree`](./worktree.md) for managed Git worktrees and safe cleanup. For the broader organization map, start at [Beyond10x getting started](https://beyond10x.github.io/getting-started/). diff --git a/website/docs/plugins/connectors.md b/website/docs/plugins/connectors.md index ed8849e..e137f2e 100644 --- a/website/docs/plugins/connectors.md +++ b/website/docs/plugins/connectors.md @@ -29,16 +29,16 @@ rate-limit responses. ## Install in either host -Release `0.10.0` includes this plugin. For a fresh marketplace registration, use the release pin: +Release `0.11.0` includes this plugin. For a fresh marketplace registration, use the release pin: ```bash -claude plugin marketplace add https://github.com/beyond10x/agentplugins.git#0.10.0 -claude plugin install connectors@beyond10x +claude plugin marketplace add https://github.com/beyond10x/agentplugins.git#0.11.0 +claude plugin install connectors@b10x ``` ```bash -codex plugin marketplace add https://github.com/beyond10x/agentplugins.git --ref 0.10.0 -codex plugin add connectors@beyond10x +codex plugin marketplace add https://github.com/beyond10x/agentplugins.git --ref 0.11.0 +codex plugin add connectors@b10x ``` An existing `beyond10x` registration pinned to `0.7.0` must be repointed before it can offer this diff --git a/website/docs/plugins/workspace-hygiene.md b/website/docs/plugins/workspace-hygiene.md deleted file mode 100644 index bdb90ac..0000000 --- a/website/docs/plugins/workspace-hygiene.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -sidebar_position: 5 -title: Workspace Hygiene ---- - -# `workspace-hygiene` - -Use this plugin whenever an agent needs an isolated Git checkout, hands work to another session, -or audits old linked worktrees. It contributes the `worktree` skill generated by the public -[`beyond10x/worktree`](https://github.com/beyond10x/worktree) CLI. - -The executable remains a separately installed Rust tool: - -```bash -cargo install --git https://github.com/beyond10x/worktree --tag 0.4.0 b10x-worktree-cli -worktree activate --profile --workspace -worktree doctor --check -``` - -The skill teaches agents to create trees outside the primary repository collection, maintain live -session leases, and publish wanted commits before finishing. Cleanup is review-bound: inspect -`worktree gc --repo --dry-run`, then pass only ids from that review to -`worktree gc --repo --apply --id `. Dirty, locked, live, local-only, -offline, unmanaged, and out-of-policy trees are retained. - -Worktree 0.4.0 adds `worktree inspect --repo ` for actual Git state, storage, -ignored files, leases and retention blockers. It defaults to one repository; use `--workspace` -to inspect the wider profile. Add `--refresh` for current remote recovery evidence. Inspection -does not infer story completion or authorize removal. - -When the host does not run hooks, the agent explicitly acquires and renews its lease, then -releases its own lease before finishing. After verification, it preserves useful evidence and -removes only its own reproducible build output. Each session ends with verified cleanup or an -explicit handoff that names the retained tree, published commit, blockers and next owner. - -Use `worktree reconcile --repo --dry-run` for interrupted provisioning, adopted legacy -paths, finished external trees, and already-missing records. Apply only exact reviewed ids. An -interrupted removal keeps durable recovery proof, while a missing Active record without matching -intent remains refused. External retirement additionally requires the explicit -`--allow-external-retirement` acknowledgement. - -For a finished external legacy tree stranded by stale pre-0.3 relocation intent, act only when the -reconciliation dry-run itself proposes `retire-external`. Worktree requires the exact source and -HEAD to agree and the intended destination to be absent; a cross-device or ambiguous-relocation -refusal is not permission to reinterpret or clear the state by hand. - -The plugin contains no cleanup script and no independent policy copy. Update the source CLI and run -`worktree skill --out plugins/workspace-hygiene/skills/worktree` to refresh the shared Codex and -Claude-compatible guidance. diff --git a/website/docs/plugins/worktree.md b/website/docs/plugins/worktree.md new file mode 100644 index 0000000..748b93a --- /dev/null +++ b/website/docs/plugins/worktree.md @@ -0,0 +1,51 @@ +--- +sidebar_position: 5 +title: Worktree +--- + +# `worktree` + +Use this plugin whenever an agent needs an isolated Git checkout, hands work to another session, +or audits old linked worktrees. It contributes the `worktree` skill generated by the public +[`beyond10x/worktree`](https://github.com/beyond10x/worktree) CLI. + +The plugin ships from the worktree repository, `plugins/worktree/`, at the same version as the +`worktree` binary. This marketplace carries no copy: its Claude Code entry pins the worktree +repository by release tag and full commit, and `agentplugins-check remote` refuses a pin that is +not the newest release or whose manifests declare another version. + +```text +/plugin install worktree@b10x +``` + +Codex reads the worktree repository's own marketplace: +`codex plugin marketplace add https://github.com/beyond10x/worktree.git --ref `, then +`codex plugin add worktree@worktree`. + +The executable remains a separately installed Rust tool. Install the release the plugin names: + +```bash +cargo install --git https://github.com/beyond10x/worktree --tag b10x-worktree-cli +worktree activate --profile --workspace +worktree doctor --check +``` + +The skill teaches agents to create trees outside the primary repository collection, maintain live +session leases, and publish wanted commits before finishing. Cleanup is review-bound: inspect +`worktree gc --repo --dry-run`, then pass only ids from that review to +`worktree gc --repo --apply --id `. Dirty, locked, live, local-only, +offline, unmanaged, and out-of-policy trees are retained. Work merged as rebased or cherry-picked +copies is recoverable when an advertised ref carries every unique commit's exact patch. + +`worktree inspect --repo ` reports actual Git state, storage, ignored files, leases and +retention blockers. It defaults to one repository; use `--workspace` to inspect the wider profile. +Add `--refresh` for current remote recovery evidence. Inspection does not infer story completion +or authorize removal. + +Use `worktree reconcile --repo --dry-run` for interrupted provisioning, adopted legacy +paths, finished external trees, and already-missing records. Apply only exact reviewed ids. +External retirement additionally requires the explicit `--allow-external-retirement` +acknowledgement. + +The plugin contains no cleanup script and no independent policy copy. The worktree repository's +own gate verifies the plugin's skill against the binary on every change. diff --git a/website/sidebars.ts b/website/sidebars.ts index 6941806..83d644e 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -9,7 +9,7 @@ const sidebars: SidebarsConfig = { { type: 'category', label: 'Plugin reference', - items: ['plugins/beyond10x', 'plugins/aep-plan', 'plugins/aep-drive', 'plugins/workspace-hygiene', 'plugins/connectors'], + items: ['plugins/beyond10x', 'plugins/aep-plan', 'plugins/aep-drive', 'plugins/worktree', 'plugins/connectors'], }, 'trust-and-scope', ], diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index 78fd6ac..367ce30 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -8,7 +8,7 @@ const plugins = [ ['Beyond10x', 'Route work, find public resources, and create portable plugins.', '/docs/plugins/beyond10x'], ['AEP Plan', 'Plan, decompose, review, and reverse-engineer governed work.', '/docs/plugins/aep-plan'], ['AEP Drive', 'Scope stories and coordinate implementation waves with adversarial review.', '/docs/plugins/aep-drive'], - ['Workspace Hygiene', 'Manage isolated Git worktrees with explicit recovery proof.', '/docs/plugins/workspace-hygiene'], + ['Worktree', 'Manage isolated Git worktrees with explicit recovery proof.', '/docs/plugins/worktree'], ]; export default function Home(): ReactNode { @@ -16,7 +16,7 @@ export default function Home(): ReactNode {
-

Curated marketplace · beyond10x

+

Curated marketplace · b10x

Give each agent only the engineering guidance it needs.

A lightweight front door routes work to four focused specialists and helps create diff --git a/website/static/img/social-card.svg b/website/static/img/social-card.svg index c47e7ee..e9875fb 100644 --- a/website/static/img/social-card.svg +++ b/website/static/img/social-card.svg @@ -5,5 +5,5 @@ BEYOND10X Agent Plugins Focused guidance for governed engineering agents. - aep-plan · aep-drive · workspace-hygiene + aep-plan · aep-drive · worktree