diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index dc6c1db..79d7465 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -18,7 +18,7 @@ "name": "work-system", "source": "./plugins/work-system", "description": "Generic task and worktree workflow system for Claude Code. Manage tasks as markdown files, work in isolated git worktrees, and track progress through the full lifecycle.", - "version": "1.2.4" + "version": "1.2.5" }, { "name": "pr-flow", diff --git a/plugins/work-system/.claude-plugin/plugin.json b/plugins/work-system/.claude-plugin/plugin.json index 9e27f79..2a5cbee 100644 --- a/plugins/work-system/.claude-plugin/plugin.json +++ b/plugins/work-system/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "work-system", "description": "Generic task and worktree workflow system for Claude Code. Manage tasks as markdown files, work in isolated git worktrees, and track progress through the full lifecycle: create, start, continue, check, close.", - "version": "1.2.4", + "version": "1.2.5", "author": { "name": "gering" }, diff --git a/plugins/work-system/README.md b/plugins/work-system/README.md index a95e810..f620b50 100644 --- a/plugins/work-system/README.md +++ b/plugins/work-system/README.md @@ -39,7 +39,7 @@ Generic task and worktree workflow system for Claude Code. Manage tasks as markd ### Tasks -Each task is a markdown file in your project's `tasks/` directory: +Each task is a markdown file in your project's `tasks/` directory. This is a centralized backlog on the main worktree — `/define` always writes there, even when invoked from inside a linked worktree, so tasks stay visible to `/kickoff` and `/list` and survive `/close`: ```markdown # Add Dark Mode Support diff --git a/plugins/work-system/scripts/main-repo-path.sh b/plugins/work-system/scripts/main-repo-path.sh new file mode 100755 index 0000000..bbdad23 --- /dev/null +++ b/plugins/work-system/scripts/main-repo-path.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# main-repo-path.sh — resolve the main worktree for work-system skills. +# +# The shared task backlog (tasks/) lives in the main worktree. A skill invoked +# from a linked worktree must target the main worktree's tasks/, so it needs +# the main path and a way to tell the two invocations apart. +# +# Subcommands: +# path Print the absolute path of the main worktree (the first +# `git worktree list` entry). Robust against paths containing +# spaces — strips the porcelain "worktree " prefix without +# field-splitting. +# linked Print "linked" if the current directory is inside a linked +# worktree, "main" if it is the main worktree. Compares git's own +# dir bookkeeping (--git-common-dir vs --git-dir), so it is immune +# to symlinked paths rather than string-comparing two path forms. +# +# Exits non-zero if not run inside a git repository. +set -eu + +case "${1:-path}" in + path) + # Porcelain output starts each block with "worktree "; the first + # block is the main worktree. Take the first line, drop the prefix. + list="$(git worktree list --porcelain)" + first="${list%%$'\n'*}" + printf '%s\n' "${first#worktree }" + ;; + linked) + common="$(cd "$(git rev-parse --git-common-dir)" && pwd)" + gitdir="$(cd "$(git rev-parse --git-dir)" && pwd)" + if [ "$common" = "$gitdir" ]; then + echo "main" + else + echo "linked" + fi + ;; + *) + echo "usage: ${0##*/} [path|linked]" >&2 + exit 2 + ;; +esac diff --git a/plugins/work-system/skills/define/SKILL.md b/plugins/work-system/skills/define/SKILL.md index 72f388d..cd72181 100644 --- a/plugins/work-system/skills/define/SKILL.md +++ b/plugins/work-system/skills/define/SKILL.md @@ -11,13 +11,23 @@ user_invocable: true > Create a new task file from current context and conversation +## Where the task file lands + +Task files are a **centralized backlog** on the main worktree, visible to `/kickoff` and `/list`. When `/define` runs from inside a linked worktree, the file must still land in the **main repo's** `tasks/` — otherwise it's isolated on the task branch and lost when `/close` removes the worktree. + +Resolve the main repo path once (step 1) and use it for every path below. Never persist a `cd` — Bash CWD leaks across tool calls; use the absolute `` path instead. + ## Arguments - `$ARGUMENTS` - Optional: brief description of the task ## Instructions -1. **Gather task information**: +1. **Resolve the main repo path** (shared helper — handles paths with spaces and symlinks): + - Run: `bash "${CLAUDE_PLUGIN_ROOT}/scripts/main-repo-path.sh" path` → `` (the main worktree, where the shared `tasks/` backlog lives). + - Run: `bash "${CLAUDE_PLUGIN_ROOT}/scripts/main-repo-path.sh" linked` → `main` or `linked`. `linked` = invoked from a worktree (the task file still goes to `/tasks/`); `main` = behavior unchanged. + +2. **Gather task information**: If `$ARGUMENTS` provided, use as starting point for the task description. @@ -26,19 +36,19 @@ user_invocable: true - "Are there specific files or areas of code involved?" - "What are the acceptance criteria?" -2. **Generate task name**: +3. **Generate task name**: - Create a kebab-case name from the description - Examples: - "Fix the calendar date bug" → `fix-calendar-date-bug` - "Add dark mode support" → `add-dark-mode-support` - Show proposed name and ask for confirmation -3. **Check for duplicates**: - - Run: `ls tasks/ 2>/dev/null | grep -i ""` +4. **Check for duplicates**: + - Run: `ls "/tasks/" 2>/dev/null | grep -i ""` - If `gh` is available: `gh pr list --state open --search "" --limit 3` - If similar tasks exist, show them and ask if user wants to continue -4. **Create task file**: +5. **Create task file**: Template: ```markdown @@ -63,27 +73,28 @@ user_invocable: true ``` -5. **Include conversation context**: +6. **Include conversation context**: - If there was relevant discussion, summarize it in the Notes section - If specific code or files were mentioned, add them to Relevant Files - If errors or bugs were discussed, include error messages -6. **Write the file**: - - Path: `tasks/.md` +7. **Write the file**: + - Path: `/tasks/.md` (absolute — never `cd` into the main repo to write it) - Show the content to user for review - Ask: "Create this task file?" -7. **Confirm creation**: +8. **Confirm creation**: ``` - ✅ Task created: tasks/.md + ✅ Task created: /tasks/.md Next steps: • Start immediately: /kickoff • View all tasks: /list • Check status later: /status ``` + - When step 1 reported `linked`, add: "Written to the main repo backlog, not this worktree." -8. **Optional — Start immediately**: +9. **Optional — Start immediately**: - Ask: "Would you like to start working on this task now?" - If yes, proceed with `/kickoff` workflow