From 7798f2625931df43d50b4e810be4d6c02003798c Mon Sep 17 00:00:00 2001 From: Abishek Yadav Date: Tue, 14 Apr 2026 10:18:59 -0500 Subject: [PATCH 1/3] docs: parallel agents, Git extension, extensions.yml; v1.3.0 - README: disable git before_specify via extensions.yml, base-ref HEAD, after_specify ordering, preset note, 1.0.0 opt-in - Command doc: prerequisites, --base-ref, branch creation rules - ADMIN_REPLY_SPEC_KIT_PR.md: maintainer PR comment template - Bump version and catalog entry for v1.3.0 tag Made-with: Cursor --- ADMIN_REPLY_SPEC_KIT_PR.md | 17 ++++++++++++++++ CHANGELOG.md | 9 +++++++++ PUBLISH.md | 2 +- README.md | 30 ++++++++++++++++++++++++++-- catalog-entry.json | 6 +++--- commands/speckit.worktrees.create.md | 7 +++++-- extension.yml | 2 +- 7 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 ADMIN_REPLY_SPEC_KIT_PR.md diff --git a/ADMIN_REPLY_SPEC_KIT_PR.md b/ADMIN_REPLY_SPEC_KIT_PR.md new file mode 100644 index 0000000..466ec45 --- /dev/null +++ b/ADMIN_REPLY_SPEC_KIT_PR.md @@ -0,0 +1,17 @@ +# Comment to post on the github/spec-kit PR (e.g. hook overrides / modifies_hooks) + +Use or shorten as needed. + +--- + +Thanks for the feedback — I agree with the boundary and I’m **closing / withdrawing this PR** in favor of the approach you described. + +**Cross-extension configuration:** I won’t ship logic where one extension rewrites another’s hooks or config on install (including `modifies_hooks` targeting the Git extension). That coupling is brittle when the Git extension evolves and it conflicts with **Git becoming opt-in at 1.0.0**. + +**Parallel worktrees:** The real issue is that `before_specify → speckit.git.feature` runs `git checkout` / `git checkout -b` on the **shared** primary checkout, which disrupts parallel agents. Worktree-based flows should rely on **`git worktree add -b`** (branch created in the new worktree, primary `HEAD` unchanged) and on **explicit** project config: users who need a stable primary branch can set `enabled: false` on that hook in **`.specify/extensions.yml`**. + +**Presets:** Opinionated “worktree-first” command text and ordering should live in a **preset** that overrides only the commands that need to differ — so teams stay in control. + +**Spec-kit follow-up:** No core changes are required from this PR. I submitted a small **documentation** update: `extensions/git/README.md` — new subsection *Parallel worktrees (shared primary clone)* — pointing maintainers and users at `extensions.yml` and presets. I can open that as a **separate tiny doc PR** against `main` if you prefer it decoupled from this closed PR. + +--- diff --git a/CHANGELOG.md b/CHANGELOG.md index 9946548..baab8e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.3.0 (2026-04-14) + +### Added +- README section **Parallel agents and the Git extension**: manual `.specify/extensions.yml` change to disable Git’s `before_specify` hook when you need a stable primary checkout; branch base `--base-ref HEAD`; honest note on `after_specify` ordering vs running specify from the worktree root +- Command doc prerequisites: Git extension vs `git` CLI, and corrected branch-creation rule (worktree can create the branch with `git worktree add -b`) + +### Changed +- Documentation-only release aligned with Spec Kit maintainer guidance: no cross-extension hook mutation on install; optional future **preset** for worktree-first command overrides called out in README + ## 1.2.1 (2026-04-14) ### Removed diff --git a/PUBLISH.md b/PUBLISH.md index 49d8c8b..1a79c24 100644 --- a/PUBLISH.md +++ b/PUBLISH.md @@ -27,5 +27,5 @@ Reference issues: #61, #1476 ## 3. Install in any repo ```bash -specify extension add --from https://github.com/dango85/spec-kit-worktree-parallel/archive/refs/tags/v1.0.0.zip +specify extension add --from https://github.com/dango85/spec-kit-worktree-parallel/archive/refs/tags/v1.3.0.zip ``` diff --git a/README.md b/README.md index 0ee6f63..47332b1 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,14 @@ The community [spec-kit-worktree](https://github.com/Quratulain-bilal/spec-kit-w 1. **Default-on** — worktrees are created automatically after `/speckit.specify`. Opt *out* with `--in-place`, rather than opting in. 2. **Nested layout by default** — worktrees live at `.worktrees//` inside the repo (gitignored, self-contained). Sibling-dir layout (`../--`) is available as an option for IDE-per-feature workflows. -3. **Deterministic bash script** — a real script (`create-worktree.sh`) with `--json` output, `--dry-run`, and `SPECIFY_WORKTREE_PATH` override, suitable for CI and scripted workflows. +3. **Deterministic bash script** — a real script (`create-worktree.sh`) with `--json` output, `--dry-run`, `--base-ref`, and `SPECIFY_WORKTREE_PATH` override, suitable for CI and scripted workflows. + +This extension **does not** change another extension’s configuration on install (for example it does not disable the Git extension’s hooks). You opt into hook changes explicitly in `.specify/extensions.yml` when you need them (see below). ## Installation ```bash -specify extension add --from https://github.com/dango85/spec-kit-worktree-parallel/archive/refs/tags/v1.0.0.zip +specify extension add --from https://github.com/dango85/spec-kit-worktree-parallel/archive/refs/tags/v1.3.0.zip ``` ## Layout modes @@ -48,6 +50,30 @@ parent/ Open each directory in its own IDE window. Switch with `layout: "sibling"` in `worktree-config.yml`. +## Parallel agents and the Git extension + +**Git extension vs `git` on your PATH:** This extension requires the **`git` CLI** only. It does not require the Spec Kit **Git extension** (`speckit.git.*`). That distinction matters because the Git extension registers **`before_specify → speckit.git.feature`**, which runs `git checkout` / `git checkout -b` on **whatever directory the agent is using as the repo root**. On a **shared** primary clone, that moves `HEAD` for everyone and fights parallel worktrees. + +**What this extension does instead:** `create-worktree.sh` uses **`git worktree add`** (and **`git worktree add -b`** for a new branch). That creates the feature branch **inside the new worktree** and leaves the primary checkout’s `HEAD` alone. + +**If the Git extension is installed and you want a stable primary checkout:** edit **`.specify/extensions.yml`** and set **`enabled: false`** on the `before_specify` entry whose **`extension`** is **`git`** and **`command`** is **`speckit.git.feature`**. Your file may include extra keys (`optional`, `prompt`, …); only `enabled` needs to change. + +```yaml +hooks: + before_specify: + - extension: git + command: speckit.git.feature + enabled: false + optional: false + # …other keys from your install stay as-is… +``` + +After disabling that hook, **feature branch naming** is no longer applied by `speckit.git.feature` before specify. Use **`create-new-feature.sh --dry-run --json`** from the Git extension if you still want the same numbering **without** a checkout, or agree on branch names in the specify step. **Branch from current `HEAD`** when creating a worktree: pass **`--base-ref HEAD`** to `create-worktree.sh` (default base is `main` / `origin/main` when present). + +**`after_specify` ordering:** This extension’s hook runs **after** `/speckit.specify`. Spec files are written to the **current** working tree first, then the worktree is created. For **full** isolation, run specify **from the worktree root** (worktree-first workflow). A Spec Kit **preset** that overrides only the commands you need is the maintainers’ recommended way to encode that workflow explicitly; this repo does not ship that preset yet. + +**Spec Kit 1.0.0:** The Git extension is expected to become **opt-in**. Do not assume `before_specify` / `speckit.git.feature` is always present; keep the worktree flow valid with Git extension off. + ## Configuration Create `.specify/extensions/worktrees/worktree-config.yml` to override defaults: diff --git a/catalog-entry.json b/catalog-entry.json index c823d9b..2f7b0e7 100644 --- a/catalog-entry.json +++ b/catalog-entry.json @@ -4,8 +4,8 @@ "id": "worktrees", "description": "Default-on worktree isolation for parallel agents — sibling or nested layout", "author": "dango85", - "version": "1.0.0", - "download_url": "https://github.com/dango85/spec-kit-worktree-parallel/archive/refs/tags/v1.0.0.zip", + "version": "1.3.0", + "download_url": "https://github.com/dango85/spec-kit-worktree-parallel/archive/refs/tags/v1.3.0.zip", "repository": "https://github.com/dango85/spec-kit-worktree-parallel", "homepage": "https://github.com/dango85/spec-kit-worktree-parallel", "documentation": "https://github.com/dango85/spec-kit-worktree-parallel/blob/main/README.md", @@ -29,6 +29,6 @@ "downloads": 0, "stars": 0, "created_at": "2026-04-13T00:00:00Z", - "updated_at": "2026-04-13T00:00:00Z" + "updated_at": "2026-04-14T00:00:00Z" } } diff --git a/commands/speckit.worktrees.create.md b/commands/speckit.worktrees.create.md index b331c3e..32021d1 100644 --- a/commands/speckit.worktrees.create.md +++ b/commands/speckit.worktrees.create.md @@ -22,6 +22,8 @@ You **MUST** consider the user input before proceeding (if not empty). The user 1. Verify the project is a git repository (`git rev-parse --show-toplevel`) 2. Verify `git worktree` is available (`git worktree list` succeeds) +**Git extension (optional):** The Spec Kit Git extension’s `before_specify → speckit.git.feature` checks out the feature branch on the **current** tree. For parallel agents on one primary clone, maintainers recommend disabling that hook in `.specify/extensions.yml` and relying on `git worktree add -b` (this script) so the primary `HEAD` stays put. See the extension README *Parallel agents and the Git extension*. + ## Configuration Read configuration from `.specify/extensions/worktrees/worktree-config.yml` if it exists. Defaults apply when the file is absent. @@ -50,6 +52,7 @@ Environment variable `SPECIFY_WORKTREE_PATH` overrides the computed path entirel bash "$(dirname "$0")/../scripts/bash/create-worktree.sh" \ --json \ [--layout sibling|nested] \ + [--base-ref HEAD|main|origin/main|…] \ [--path ] \ [--in-place] \ [--dry-run] \ @@ -67,7 +70,7 @@ Environment variable `SPECIFY_WORKTREE_PATH` overrides the computed path entirel - Run `git worktree add -b ` (new branch) or `git worktree add ` (existing branch) - For nested layout, ensure `.worktrees/` is in `.gitignore` -3. **Verify spec artifacts**: Check that `specs//` exists in the new worktree. List which artifacts are present (spec.md, plan.md, tasks.md). +3. **Verify spec artifacts**: Prefer `specs//` **in the worktree** when using a worktree-first workflow. If `/speckit.specify` ran on the primary checkout first (`after_specify` hook order), artifacts may still be under the primary tree — report where they actually are. 4. **Report**: Output a summary: @@ -93,4 +96,4 @@ Environment variable `SPECIFY_WORKTREE_PATH` overrides the computed path entirel - **One worktree per branch** — refuse to create a duplicate; report the existing path instead - **Never modify the primary checkout** — worktree operations happen in the new directory only - **Always update .gitignore for nested layout** — add the `dotworktrees_dir` value if not present -- **Validate branch exists** — for existing branches; for new branches the `after_specify` hook should have already created the branch via the git extension +- **New vs existing branch** — if the branch does not exist locally, `git worktree add -b` creates it from the configured base ref; if it already exists, the worktree attaches to it. Do not assume the Git extension ran `speckit.git.feature` first (it may be disabled for parallel worktrees) diff --git a/extension.yml b/extension.yml index ec6752f..f25f1ff 100644 --- a/extension.yml +++ b/extension.yml @@ -3,7 +3,7 @@ schema_version: "1.0" extension: id: worktrees name: "Worktrees" - version: "1.2.1" + version: "1.3.0" description: "Default-on worktree isolation for parallel agents — sibling or nested layout" author: "dango85" repository: "https://github.com/dango85/spec-kit-worktree-parallel" From 891f4d6cbdfd9fd63c5bc82a6c77ae57695dbec0 Mon Sep 17 00:00:00 2001 From: Abishek Yadav Date: Tue, 14 Apr 2026 10:26:36 -0500 Subject: [PATCH 2/3] docs: admin reply points to extension README only (no spec-kit doc PR) Made-with: Cursor --- ADMIN_REPLY_SPEC_KIT_PR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ADMIN_REPLY_SPEC_KIT_PR.md b/ADMIN_REPLY_SPEC_KIT_PR.md index 466ec45..5e9c6f0 100644 --- a/ADMIN_REPLY_SPEC_KIT_PR.md +++ b/ADMIN_REPLY_SPEC_KIT_PR.md @@ -12,6 +12,6 @@ Thanks for the feedback — I agree with the boundary and I’m **closing / with **Presets:** Opinionated “worktree-first” command text and ordering should live in a **preset** that overrides only the commands that need to differ — so teams stay in control. -**Spec-kit follow-up:** No core changes are required from this PR. I submitted a small **documentation** update: `extensions/git/README.md` — new subsection *Parallel worktrees (shared primary clone)* — pointing maintainers and users at `extensions.yml` and presets. I can open that as a **separate tiny doc PR** against `main` if you prefer it decoupled from this closed PR. +**Spec-kit follow-up:** No spec-kit changes are required from this PR. The operational guidance (*parallel agents*, `.specify/extensions.yml`, presets) lives in the **Worktrees extension** repository README so it ships with the extension. --- From 00b64acac1d4f67a9bb8be603ee366ad7bdd2bf6 Mon Sep 17 00:00:00 2001 From: Abishek Yadav Date: Tue, 14 Apr 2026 10:28:46 -0500 Subject: [PATCH 3/3] chore: CONTRIBUTING, PR template, publish flow via PR to main Made-with: Cursor --- .github/pull_request_template.md | 9 +++++++++ CONTRIBUTING.md | 32 ++++++++++++++++++++++++++++++++ PUBLISH.md | 18 ++++++++++++++---- README.md | 2 ++ 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 .github/pull_request_template.md create mode 100644 CONTRIBUTING.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..cc6b7ed --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,9 @@ +## Summary + + + +## Checklist + +- [ ] Targets **`main`** via a **feature branch** (not direct commits to `main`) +- [ ] `CHANGELOG.md` updated if this is user-visible (version bump when releasing) +- [ ] CI passes (Actions) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..aa8dc7f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,32 @@ +# Contributing + +This is a public repository. Changes should follow the usual **GitHub flow**: work on a **branch**, open a **pull request** into `main`, and merge only after review — **not** by committing directly to `main`. + +## For contributors + +1. **Fork** the repository (or use a branch if you have write access). +2. Create a **feature branch** from up-to-date `main`: + + ```bash + git fetch origin + git checkout -b your-branch-name origin/main + ``` + +3. Make commits with clear messages. +4. **Push** your branch and open a **pull request** targeting `main`. +5. Wait for CI (GitHub Actions) to pass and for maintainer review. + +## For maintainers + +- Merge contributions via **Pull request** → **Merge** (squash or merge commit, per repo preference). +- **Do not** push commits directly to `main` for routine changes; use a short-lived branch and PR so history and review stay consistent with contributor expectations. +- In repository **Settings → Rules → Rulesets** (or **Branch protection rules**), protect `main`: require a pull request before merging, and require status checks where appropriate. + +## Releases + +After a change to versioned files (`extension.yml`, `CHANGELOG.md`, `catalog-entry.json`) is **merged** to `main`: + +1. Tag a semantic version (e.g. `v1.3.0`) on the merge commit. +2. Push the tag so `download_url` and install snippets that point at `/archive/refs/tags/v…` stay valid. + +See [PUBLISH.md](PUBLISH.md) for catalog and distribution notes. diff --git a/PUBLISH.md b/PUBLISH.md index 1a79c24..f898f96 100644 --- a/PUBLISH.md +++ b/PUBLISH.md @@ -1,13 +1,23 @@ # Publishing steps -## 1. Push to GitHub +## 1. Land changes on `main` via pull request + +Do **not** push routine commits directly to `main`. See [CONTRIBUTING.md](CONTRIBUTING.md). ```bash cd /Users/abiyadav/SourceCode/spec-kit-worktree-parallel +git fetch origin && git checkout -b your-branch origin/main +# … commit … +git push -u origin your-branch +gh pr create --base main --head your-branch +# After review, merge the PR on GitHub +``` + +Initial repo setup (one-time): + +```bash gh repo create dango85/spec-kit-worktree-parallel --public --source . --push -# or manually: -git remote add origin https://github.com/dango85/spec-kit-worktree-parallel.git -git push -u origin main --tags +# or: git remote add origin https://github.com/dango85/spec-kit-worktree-parallel.git ``` ## 2. Submit catalog PR to github/spec-kit diff --git a/README.md b/README.md index 47332b1..528ebb2 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ [![Tests](https://github.com/dango85/spec-kit-worktree-parallel/actions/workflows/test.yml/badge.svg)](https://github.com/dango85/spec-kit-worktree-parallel/actions/workflows/test.yml) +**Contributing:** use a **branch + pull request** into `main` — see [CONTRIBUTING.md](CONTRIBUTING.md). + A [Spec Kit](https://github.com/github/spec-kit) extension for **default-on** git worktree isolation — work on multiple features (or run parallel agents) without checkout switching. ## Why another worktree extension?