diff --git a/plugins-claude/session/.claude-plugin/plugin.json b/plugins-claude/session/.claude-plugin/plugin.json index e84953a..5f05c66 100644 --- a/plugins-claude/session/.claude-plugin/plugin.json +++ b/plugins-claude/session/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session", - "version": "4.3.0", + "version": "4.3.2", "description": "Work session management — issue-driven and freeform doors sharing an explore-then-plan spine, with multi-agent orchestration and a review-gated PR finalizer", "author": { "name": "Logan Gagne" diff --git a/plugins-claude/session/README.md b/plugins-claude/session/README.md index beb1146..df90e88 100644 --- a/plugins-claude/session/README.md +++ b/plugins-claude/session/README.md @@ -59,8 +59,8 @@ same either way. Both take in-flight work through commit → push → PR → CI → merge → return-to-default. Pick based on what you need: -- **`/session:session-end`** — adds a pre-PR code-review gate and `Resolves #N` - issue linking. Worktree-aware (tears down the worktree after merge). +- **`/session:session-end`** — adds a pre-PR code-review gate and `Closes #N` / + `Fixes #N` issue linking. Worktree-aware (tears down the worktree after merge). - **`/git-tools:ship`** — the quick canonical lifecycle, no review gate. Also worktree-aware: after merge it returns to the main worktree, removes the merged worktree, prunes, and deletes the branch. diff --git a/plugins-claude/session/skills/session-end/SKILL.md b/plugins-claude/session/skills/session-end/SKILL.md index 4e85fe1..1ff1614 100644 --- a/plugins-claude/session/skills/session-end/SKILL.md +++ b/plugins-claude/session/skills/session-end/SKILL.md @@ -9,7 +9,7 @@ Finalize the work: review, clean up commits, push, open a PR, watch CI, and return to the default branch. This is the **review-gated, worktree-aware** finalizer. It owns a -pre-PR code review gate, `Resolves #N` issue linking, and worktree +pre-PR code review gate, `Closes #N` / `Fixes #N` issue linking, and worktree teardown after merge. For a quick lifecycle with none of that — just stage → commit → push → PR → watch → merge → return — use `/git-tools:ship` instead. (`session-end` does not delegate to @@ -85,8 +85,11 @@ fails from inside a worktree.) flow; user will re-invoke when ready - **Open PR anyway** — skip fixes and proceed -5. Determine the linked issue number from the branch - name (`type/NNN-*`). Build the PR body: +5. Determine whether the work is linked to an issue. Reuse the issue number from + prior session context, an explicit `#N` in the user request, or existing + commit/PR text when available. **Do not** parse it from the branch name — issue + branches use `-`. If no confident issue number is available, leave + the PR unlinked. Build the PR body: ```markdown ## Summary @@ -102,8 +105,8 @@ fails from inside a worktree.) ``` - If a linked issue exists, append `Resolves #N` - to the summary. + If a linked issue exists, append `Fixes #N` for bug/fix work or `Closes #N` + otherwise to the PR body. 6. Create the PR: diff --git a/plugins-copilot/session/.claude-plugin/plugin.json b/plugins-copilot/session/.claude-plugin/plugin.json index e84953a..5f05c66 100644 --- a/plugins-copilot/session/.claude-plugin/plugin.json +++ b/plugins-copilot/session/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session", - "version": "4.3.0", + "version": "4.3.2", "description": "Work session management — issue-driven and freeform doors sharing an explore-then-plan spine, with multi-agent orchestration and a review-gated PR finalizer", "author": { "name": "Logan Gagne" diff --git a/plugins-copilot/session/README.md b/plugins-copilot/session/README.md deleted file mode 120000 index 5534af8..0000000 --- a/plugins-copilot/session/README.md +++ /dev/null @@ -1 +0,0 @@ -../../plugins-claude/session/README.md \ No newline at end of file diff --git a/plugins-copilot/session/README.md b/plugins-copilot/session/README.md new file mode 100644 index 0000000..e8cc598 --- /dev/null +++ b/plugins-copilot/session/README.md @@ -0,0 +1,100 @@ +# Session + +Work session management: two lightweight doors into a shared explore → plan spine, +a heavyweight multi-agent orchestrator, and a review-gated PR finalizer. + +## Installation + +```bash +copilot plugin install St0nefish/agent-toolkit/session +``` + +## How It Works + +Every entry point follows the same **begin-work spine** — *isolate (worktree) → +offer orchestration → explore (parallel research agents) → plan (plan mode) → +hand-off* — and they differ only in **how the work is chosen**: + +- **`/session:start`** — the *input-driven* door. You describe what to do; it + grounds in the current branch state, creates or reuses a branch, and runs the spine. + If your description references an issue (`#42`), it links it. +- **`/session:issue`** — the *discovery* door. It ranks the open issues, asks + you to pick from the top 3, then runs the same spine. + +For non-trivial work, both doors offer to escalate to +**`/session:orchestrate`** — the multi-agent playbook (spec → plan → refine → +divide → execute → review) with model tiering and an automated review pass. The +lightweight spine is the single-session counterpart to this heavyweight flow. + +The shared spine lives in the Claude-side `reference/spine.md`; `start` and +`issue` read and execute that same flow so there is one source of truth. + +When an issue is linked, the branch name uses the issue's type and a slug +(`type-slug`, e.g. `bug-fix-login-crash`). The issue is auto-closed via `Closes #N` +in the PR when it merges — the linkage lives there, not in the branch name. + +### Working Without Issues + +`/session:start` accepts freeform descriptions and creates `wip-` +branches — no issue tracker required. The `/session:end` PR workflow works the +same either way. + +## Commands + +| Command | Description | +|---------|-------------| +| `/session:start` | Start from your description — ground, branch, explore, plan | +| `/session:issue` | Rank open issues, pick one, then explore and plan | +| `/session:orchestrate` | Multi-agent feature workflow: spec → plan → refine → divide → execute → review | +| `/session:end` | Review changes, open a PR, watch CI, wait for merge, return to default (worktree-aware) | + +## Skills (Model-Triggered) + +| Skill | Triggers on | +|-------|-------------| +| `summarize` | "what was I working on?", "session status", "catch me up", or returning to active work | + +## Finalizing: `session-end` vs `git-tools:ship` + +Both take in-flight work through commit → push → PR → CI → merge → return-to-default. +Pick based on what you need: + +- **`/session:end`** — adds a pre-PR code-review gate and `Closes #N` / + `Fixes #N` issue linking. Worktree-aware (tears down the worktree after merge). +- **`/git-tools:ship`** — the quick canonical lifecycle, no review gate. Also + worktree-aware: after merge it returns to the main worktree, removes the merged + worktree, prunes, and deletes the branch. + +## Typical Workflow + +```text +/session:start "add CSV export" # or /session:issue to pick one + → isolates in a worktree, explores, enters plan mode + ... implement ... +/session:end # review, PR, watch CI, merge, tear down worktree +``` + +## Branch Type Detection + +When starting from an issue, the branch type is inferred from issue labels: + +| Labels | Branch prefix | +|--------|--------------| +| `bug`, `fix` | `bug-` | +| `enhancement`, `feature`, `improvement` | `enhancement-` | +| `docs`, `chore`, `refactor`, `maintenance` | `chore-` | +| (none of the above) | `feature-` | + +## Dependencies + +| Tool | Required | Purpose | +|------|----------|---------| +| `git` | Yes | All branch, commit, and diff operations | +| `gh` | Yes* | GitHub API — issues, PRs, CI | +| `tea` | Yes* | Gitea API — issues, PRs, CI | +| `jq` | Yes | JSON processing in git-cli | + +*Either `gh` or `tea` is required depending on your git remote host. + +The `git-cli` wrapper is bundled as a vendored script in `scripts/` — you don't need +to install it separately, but you do need the underlying CLI tools. diff --git a/plugins-copilot/session/commands/session-end.md b/plugins-copilot/session/commands/end.md similarity index 92% rename from plugins-copilot/session/commands/session-end.md rename to plugins-copilot/session/commands/end.md index fa3bd76..d7c3356 100644 --- a/plugins-copilot/session/commands/session-end.md +++ b/plugins-copilot/session/commands/end.md @@ -53,7 +53,11 @@ watch CI, and return to the default branch. - **I'll fix the issues first** — pause the `end` flow; user will re-invoke when ready - **Open PR anyway** — skip fixes and proceed -5. Determine the linked issue number from the branch name (`type/NNN-*`). Build the PR body: +5. Determine whether the work is linked to an issue. Reuse the issue number from prior + session context, an explicit `#N` in the user request, or existing commit/PR text + when available. Do **not** parse it from the branch name — issue branches use + `-`. If no confident issue number is available, leave the PR unlinked. + Build the PR body: ```markdown ## Summary @@ -69,7 +73,8 @@ watch CI, and return to the default branch. ``` - If a linked issue exists, append `Resolves #N` to the summary. + If a linked issue exists, append `Fixes #N` for bug/fix work or `Closes #N` + otherwise to the PR body. 6. Create the PR: - on GitHub repos, prefer `gh pr create` with the title, base branch, head branch, and PR body from step 5 diff --git a/plugins-copilot/session/commands/issue.md b/plugins-copilot/session/commands/issue.md new file mode 100644 index 0000000..73be043 --- /dev/null +++ b/plugins-copilot/session/commands/issue.md @@ -0,0 +1,16 @@ +--- +description: "Browse open issues, pick one, and start work on it" +allowed-tools: Bash, AskUserQuestion +--- + +Take the discovery path: rank the open issues, pick one, then explore the code and +propose a concrete plan before implementing. + +This command invokes the sibling `session-issue` skill. The flow: + +1. **Fetch and rank issues** with native host tooling (`gh` on GitHub, host-native equivalent elsewhere). +2. **Let the user choose** from the top-ranked issues via AskUserQuestion. +3. **Fetch the selected issue** and keep its body + labels as context. +4. **Choose the branch type** from labels and isolate the work on a branch or worktree. +5. **Offer orchestration** for non-trivial issues via `/session:orchestrate`. +6. **Explore, then plan** — inspect the codebase and present a concrete implementation plan. diff --git a/plugins-copilot/session/commands/session-orchestrate.md b/plugins-copilot/session/commands/orchestrate.md similarity index 92% rename from plugins-copilot/session/commands/session-orchestrate.md rename to plugins-copilot/session/commands/orchestrate.md index 85614ff..357943b 100644 --- a/plugins-copilot/session/commands/session-orchestrate.md +++ b/plugins-copilot/session/commands/orchestrate.md @@ -3,7 +3,7 @@ description: "Multi-phase, multi-agent feature workflow: spec → plan → refin allowed-tools: Bash, Read, AskUserQuestion --- -Run a complex feature through a structured multi-agent workflow with explicit model tiering, user gates, and an automated review pass. Use this when work is non-trivial — multiple files, design ambiguity, cross-cutting concerns, or correctness-critical paths. For small fixes, prefer `/session:session-start` directly. +Run a complex feature through a structured multi-agent workflow with explicit model tiering, user gates, and an automated review pass. Use this when work is non-trivial — multiple files, design ambiguity, cross-cutting concerns, or correctness-critical paths. For small fixes, prefer `/session:start` directly. The workflow has seven phases. Two have hard user gates (Refine and Execute). The Review phase auto-loops on blockers up to a cap. @@ -13,8 +13,8 @@ The workflow has seven phases. Two have hard user gates (Refine and Execute). Th ### Inputs -- `$ARGUMENTS` — optional initial description. If empty and no context inherited from `/session:session-start`, ask the user to describe the feature before starting Phase 1. -- Inherited context — if invoked after `/session:session-start`'s escalation, the branch is already created and the issue/description is known. Do not re-ask for a description. +- `$ARGUMENTS` — optional initial description. If empty and no context inherited from `/session:start`, ask the user to describe the feature before starting Phase 1. +- Inherited context — if invoked after `/session:start`'s escalation, the branch is already created and the issue/description is known. Do not re-ask for a description. ### Phase 0 — Detect existing context @@ -34,7 +34,7 @@ Before starting Phase 1, check whether prior phases of this workflow have alread Orchestrate runs are heavy and long-lived — **isolate them in a git worktree by default** (assumes the `git-worktree` Copilot extension is available) so the main checkout stays clean. -- **Already isolated** — if the session is already in a worktree, or a feature branch is already checked out (inherited from `/session:session-start`, or the current branch is not the default), proceed in the current checkout. Do **not** create another worktree. +- **Already isolated** — if the session is already in a worktree, or a feature branch is already checked out (inherited from `/session:start`, or the current branch is not the default), proceed in the current checkout. Do **not** create another worktree. - **Fresh run on the default branch** — create the work's branch as a worktree by default. Derive a branch name (`-` from the issue — no number, that lives in the PR's `Closes #N` — or `wip-` from the description) and create it with `sf_git_worktree_create` (equivalent direct flow: `git worktree add .github/worktrees/ -b `). Then run **all** subsequent phases from inside the worktree by prefixing commands with `cd .github/worktrees/ && …`. A fresh worktree is a clean checkout — reinstall or symlink heavy gitignored deps if the work needs them. Offer a one-key opt-out (work in place) via `AskUserQuestion`, but default to the worktree. Then proceed to Phase 1. @@ -165,10 +165,10 @@ Goal: summarize and route to the appropriate finalization flow. - Test coverage added (if any) - Caveats — deferred concerns from Phase 6 and any known risks or follow-ups -2. **Then stop and wait for the user's free-text response.** Do NOT use `AskUserQuestion` and do NOT auto-commit, push, or open a PR. Let the user decide what's next — they may run `/git-tools:ship` (commit, push, PR, watch CI), `/session:session-end` (review-then-PR flow), ask for adjustments, or finalize manually. Just present the summary and wait in the normal chat input. +2. **Then stop and wait for the user's free-text response.** Do NOT use `AskUserQuestion` and do NOT auto-commit, push, or open a PR. Let the user decide what's next — they may run `/git-tools:ship` (commit, push, PR, watch CI), `/session:end` (review-then-PR flow), ask for adjustments, or finalize manually. Just present the summary and wait in the normal chat input. ### Notes -- **Always think about whether the workflow is the right tool.** If the user invoked this for a small, well-scoped change, gently suggest `/session:session-start` instead before kicking off Phase 1. +- **Always think about whether the workflow is the right tool.** If the user invoked this for a small, well-scoped change, gently suggest `/session:start` instead before kicking off Phase 1. - **Do not skip the user gates.** Phases 3 and 5 must use `AskUserQuestion`. - **For full Claude-tier orchestration** (parallel sub-agents, Haiku/Sonnet/Opus model tiering, dedicated review-pass agents), use the Claude version of this plugin. diff --git a/plugins-copilot/session/commands/session-start.md b/plugins-copilot/session/commands/start.md similarity index 96% rename from plugins-copilot/session/commands/session-start.md rename to plugins-copilot/session/commands/start.md index f1bae3f..377fab2 100644 --- a/plugins-copilot/session/commands/session-start.md +++ b/plugins-copilot/session/commands/start.md @@ -6,7 +6,7 @@ allowed-tools: Bash, AskUserQuestion Start work from whatever you describe. This is the **input-driven** door: you say what to do, it grounds in the current repo state, creates or reuses a branch, explores the code, and proposes a plan before implementing. To browse and pick from -open issues instead, use `/session:session-issue`. +open issues instead, use `/session:issue`. > Drive this to a plan. Do NOT end on "suggested first steps" — explore the code and > propose a concrete plan for approval before implementing. @@ -46,7 +46,7 @@ open issues instead, use `/session:session-issue`. acceptance criteria), or keywords like `refactor`, `redesign`, `migration`, `architecture`, `system`. For simple or moderate work, say nothing about orchestrate and continue. Only when genuinely complex, offer - `/session:session-orchestrate` (multi-agent dispatch, model tiering, automated + `/session:orchestrate` (multi-agent dispatch, model tiering, automated review) once. If the user escalates, hand off and stop. 6. **Explore, then plan.** Investigate the relevant code — read the files, trace the diff --git a/plugins-copilot/session/commands/session-issue.md b/plugins-copilot/session/skills/session-issue/SKILL.md similarity index 95% rename from plugins-copilot/session/commands/session-issue.md rename to plugins-copilot/session/skills/session-issue/SKILL.md index d312cd6..a5f7d38 100644 --- a/plugins-copilot/session/commands/session-issue.md +++ b/plugins-copilot/session/skills/session-issue/SKILL.md @@ -1,11 +1,13 @@ --- +disable-model-invocation: true +name: session-issue description: "Browse open issues, pick one, and start work on it" allowed-tools: Bash, AskUserQuestion --- The **discovery** door: rank the open issues, pick one, then explore the code and propose a plan. To start from your own description instead, use -`/session:session-start`. +`/session:start`. > Drive this to a plan. Do NOT end on "suggested first steps" — explore the code and > propose a concrete plan for approval before implementing. @@ -25,7 +27,7 @@ propose a plan. To start from your own description instead, use - Older issues rank higher than newer (age as proxy for neglect) **Select** based on the total number of open issues: - - **0** — tell the user there are none and suggest `/session:session-start`. Stop. + - **0** — tell the user there are none and suggest `/session:start`. Stop. - **1** — state the single `#N — Title` plus a one-line summary, then ask the user to confirm before starting (they may want to defer it or do it from a specific machine). Only proceed once they confirm. @@ -60,7 +62,7 @@ propose a plan. To start from your own description instead, use acceptance criteria/checkboxes), or keywords like `refactor`, `redesign`, `migration`, `architecture`, `system`. For simple or moderate issues, say nothing about orchestrate and continue. Only when genuinely complex, offer - `/session:session-orchestrate` once. If the user escalates, hand off and stop. + `/session:orchestrate` once. If the user escalates, hand off and stop. 7. **Explore, then plan.** Investigate the relevant code — read the files, trace the call/data flow, find existing tests and conventions. Then present a concrete plan diff --git a/tests/git-worktree/test-docs.sh b/tests/git-worktree/test-docs.sh index 5ba067a..0b2f709 100755 --- a/tests/git-worktree/test-docs.sh +++ b/tests/git-worktree/test-docs.sh @@ -7,10 +7,10 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" README_CONTENT=$(cat "$REPO_ROOT/README.md") CLAUDE_CONTENT=$(cat "$REPO_ROOT/CLAUDE.md") -SESSION_START=$(cat "$REPO_ROOT/plugins-copilot/session/commands/session-start.md") -SESSION_ISSUE=$(cat "$REPO_ROOT/plugins-copilot/session/commands/session-issue.md") -SESSION_ORCH=$(cat "$REPO_ROOT/plugins-copilot/session/commands/session-orchestrate.md") -SESSION_END=$(cat "$REPO_ROOT/plugins-copilot/session/commands/session-end.md") +SESSION_START=$(cat "$REPO_ROOT/plugins-copilot/session/commands/start.md") +SESSION_ISSUE=$(cat "$REPO_ROOT/plugins-copilot/session/skills/session-issue/SKILL.md") +SESSION_ORCH=$(cat "$REPO_ROOT/plugins-copilot/session/commands/orchestrate.md") +SESSION_END=$(cat "$REPO_ROOT/plugins-copilot/session/commands/end.md") AUTO_SESSION=$(cat "$REPO_ROOT/plugins-claude/auto-session-title/README.md") MARKETPLACE=$(cat "$REPO_ROOT/.github/plugin/marketplace.json")