From 301d09c5c02260167ee2a81e5d4e4669012e5061 Mon Sep 17 00:00:00 2001 From: "jack-nsheaps[bot]" <233066888+jack-nsheaps[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 11:31:07 -0400 Subject: [PATCH 01/13] =?UTF-8?q?docs(task-utils):=20initial=20spec=20?= =?UTF-8?q?=E2=80=94=20provider-based=20task=20sync=20architecture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/task-utils/docs/spec.md | 224 ++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 plugins/task-utils/docs/spec.md diff --git a/plugins/task-utils/docs/spec.md b/plugins/task-utils/docs/spec.md new file mode 100644 index 000000000..7b27a69fa --- /dev/null +++ b/plugins/task-utils/docs/spec.md @@ -0,0 +1,224 @@ +--- +name: task-utils +status: draft +description: Unified task management plugin consolidating todo-plus-plus, todo-sync, and task-parallelization into a single cohesive plugin with provider-based task sync. +--- + +# task-utils Plugin Spec + +## Problem Statement + +Task management is currently fragmented across three separate plugins: + +- **todo-plus-plus** (v0.1.5): lifecycle hooks (commit check, session restore, stop guard) +- **todo-sync** (v0.2.4): syncs TodoWrite output to GitHub issues and initializes `.gitignore` +- **task-parallelization** (v0.2.25): skill for running tasks in parallel + +These overlap in concern, share no config namespace, and require three separate install/update cycles. Agents must install all three to get complete task management behavior, and there is no single place to configure task-related settings. + +## Goals + +1. Single `task-utils` plugin replacing all three +2. Provider-based task sync — pluggable backends (filesystem, GitHub issues, extensible to others) +3. Complete task lifecycle management (session restore, commit guard, stop guard) +4. Parallelization skill migrated in +5. Clean migration path with no behavior regression + +## Non-Goals + +- Task storage backend (tasks remain in Claude Code's native task store) +- Multi-agent task coordination (out of scope for v1) +- Custom task types or fields beyond what TaskCreate/TaskUpdate support + +## Provider Architecture + +Task sync is handled by a configurable list of **providers**. Each provider implements a standard interface and is invoked on task lifecycle events. + +### Provider Interface + +```typescript +interface TaskProvider { + onTaskCreate(task: Task): Promise; + onTaskUpdate(task: Task): Promise; + onTaskComplete(task: Task): Promise; +} +``` + +### Built-in Providers + +#### `FilesystemProvider` + +Writes task state to `$CLAUDE_PROJECT_DIR/.claude/tasks/` as JSON files. + +- Source: migrated from todo-sync's filesystem output +- Purpose: provides local task persistence for environments where file access is available +- Status: **enabled by default in v1**, expected to be deprecated as agent environments become ephemeral (no persistent filesystem) +- Config key: `providers.filesystem` + +#### `GitHubIssuesProvider` + +Syncs task state to GitHub issues on the agent's configured repo. + +- Source: adapted from todo-sync (redesigned) +- **Sync behavior**: uses a haiku sub-agent to find existing issues matching the task (by title/ID) before creating new ones. Updates existing issues rather than creating duplicates. +- On `onTaskCreate`: search for existing issue → update if found, create if not +- On `onTaskUpdate`: update issue labels/status to match task state +- On `onTaskComplete`: close issue (or add "done" label, per config) +- Config key: `providers.githubIssues` + +### Design for Extensibility + +The provider list is open — future providers (e.g., Linear, Jira, Slack) can be added by implementing the `TaskProvider` interface and registering in config. No plugin changes required for new providers. + +### Provider Configuration + +```yaml +task-utils: + providers: + filesystem: + enabled: true # writes to $CLAUDE_PROJECT_DIR/.claude/tasks/ + githubIssues: + enabled: false # set true to enable GitHub issue sync + repo: "owner/repo" # required if enabled: true + labels: # optional labels to apply to created/updated issues + - "agent-task" + closeOnComplete: true # close issue when task completes +``` + +## Hooks (7 total) + +### 1. `TaskCompleted` — Commit Check + +**Source**: todo-plus-plus `TaskCompleted` hook +**Behavior**: Block task completion if uncommitted changes exist in the working directory. Forces agents to commit before marking a task done. +**Configurable**: `commitCheck.enabled` (default: `true`) +**Advisory**: No — blocks when enabled + +### 2. `SessionStart` — Task Awareness + Restore + +**Source**: todo-plus-plus `SessionStart` hook +**Behavior**: +- Injects task-awareness context into the session (reminder to use TaskCreate on every action request) +- Restores any `in_progress` tasks from the previous session, prompting the agent to resume or triage them + +**Advisory**: No — always runs + +### 3. `PreToolUse` (advisory) — No Active Task Warning + +**Source**: New (fills gap in todo-plus-plus) +**Behavior**: When a non-conversational tool is invoked and no task is `in_progress`, emit an advisory warning reminding the agent to create/activate a task. +**Advisory**: Yes — warns, does not block +**Configurable**: `activeTaskGuard.enabled` (default: `true`) + +### 4. `Stop` (advisory) — In-Progress Task Warning + +**Source**: todo-plus-plus `Stop` hook — **migrated from agent repo to plugin** +**Behavior**: When the session is about to end, warn if any tasks remain `in_progress`. Reminds the agent to complete or hand off work. +**Advisory**: Yes — warns, does not block +**Status**: Migrated in but **commented out initially** pending validation in plugin context +**Configurable**: `stopGuard.enabled` (default: `true`) + +### 5. `PostToolUse:TaskCreate` — Sync New Task to Providers + +**Source**: todo-sync (redesigned) +**Behavior**: After `TaskCreate` succeeds, invoke each enabled provider's `onTaskCreate`. The `GitHubIssuesProvider` uses a haiku sub-agent to find existing matching issues and update them, or create a new issue only if none exists. +**Configurable**: per-provider `enabled` flags +**Advisory**: No (when enabled) — failure emits warning but does not block + +### 6. `PostToolUse:TaskUpdate` — Sync Task Update to Providers + +**Source**: New +**Behavior**: After `TaskUpdate` changes task status, invoke each enabled provider's `onTaskUpdate`. GitHub issues receive label and status updates. +**Configurable**: per-provider `enabled` flags +**Advisory**: No (when enabled) — failure emits warning but does not block + +### 7. `PostToolUse:TodoWrite` — Sync Todo JSON *(deferred post-MVP)* + +**Source**: todo-sync +**Behavior**: After `TodoWrite`, sync the todo list to a GitHub issue or comment for visibility. +**Status**: **Deferred** — included in plugin structure but disabled by default. Will be enabled in v1.1 once TodoWrite→Task interop is better understood. + +## Skills + +### `task-parallelization` (migrated) + +Migrated verbatim from task-parallelization v0.2.25. No functional changes in v1. +Documents how to run multiple tasks in parallel using background agents. + +### `task-management` (new) + +New skill covering: +- When and how to use TaskCreate, TaskUpdate, TaskList, TaskGet +- Task naming conventions (include ID and ticket number) +- The full task lifecycle (created → in_progress → completed/cancelled) +- When to delegate tasks to sub-agents vs. execute directly + +## Configuration + +Full configuration reference via `plugins.settings.yaml` in the consuming agent's repo: + +```yaml +task-utils: + providers: + filesystem: + enabled: true # writes task state to $CLAUDE_PROJECT_DIR/.claude/tasks/ + githubIssues: + enabled: false # set true to enable GitHub issue sync + repo: "owner/repo" # required if enabled: true + labels: + - "agent-task" + closeOnComplete: true + commitCheck: + enabled: true # block TaskCompleted if uncommitted changes exist + stopGuard: + enabled: true # warn on Stop if in_progress tasks remain (commented out initially) + activeTaskGuard: + enabled: true # warn on tool use if no active task +``` + +## Migration Path + +For agents currently using the three separate plugins: + +1. Install `task-utils` (adds this plugin to `enabledPlugins`) +2. Remove `todo-plus-plus`, `todo-sync`, `task-parallelization` from `enabledPlugins` +3. Copy any custom config from old plugins into `task-utils` config block +4. Configure `providers.githubIssues.enabled` if you previously used todo-sync's GitHub sync (was previously always-on in todo-sync) + +No data migration required — task state lives in Claude Code's native store. + +**Note**: TodoWrite gitignore initialization (from todo-sync's `SessionStart`) is deferred post-MVP. If you relied on this, keep `todo-sync` installed until v1.1. + +## MVP Scope (v1) + +| Feature | Status | +|---|---| +| TaskCompleted commit check | In scope | +| SessionStart restore + awareness | In scope | +| PreToolUse active-task guard | In scope | +| Stop guard (migrated, commented out initially) | In scope | +| FilesystemProvider | In scope | +| GitHubIssuesProvider (find-or-create via haiku sub-agent) | In scope | +| task-parallelization skill (migrated) | In scope | +| task-management skill (new) | In scope | +| PostToolUse:TodoWrite sync | **Deferred** | +| TodoWrite gitignore init | **Deferred** | + +## Deferred Items (post-MVP) + +- **TodoWrite sync** (`PostToolUse:TodoWrite`): sync todo JSON state to GitHub. Needs clearer spec for what "syncing" means at the issue level. +- **GitIgnore init** (from todo-sync `SessionStart`): auto-add `.claude/todos/` to `.gitignore`. Low priority; agents can do this manually. +- **Task→PR linking**: automatically link tasks to open PRs when a TaskCreate happens on a feature branch. +- **FilesystemProvider deprecation**: once agent environments are consistently ephemeral, filesystem provider will be removed. For now it stays enabled by default. +- **Additional providers**: Linear, Jira, Slack, etc. — implementing the provider interface is sufficient to add new backends. + +## References + +- [#64](https://github.com/nsheaps/ai-mktpl/issues/64) — original todo-plus-plus issue +- [#65](https://github.com/nsheaps/ai-mktpl/issues/65) — todo-sync issue +- [#138](https://github.com/nsheaps/ai-mktpl/issues/138) — task-parallelization issue +- [#319](https://github.com/nsheaps/ai-mktpl/issues/319) — consolidation tracking +- [#320](https://github.com/nsheaps/ai-mktpl/issues/320) — GitHub sync design +- [#330](https://github.com/nsheaps/ai-mktpl/issues/330) — config namespace design +- [#370](https://github.com/nsheaps/ai-mktpl/issues/370) — migration path +- [Discord design thread](https://discord.com/channels/1490863845252665415/1497254984696205445) From 7814c1d49b1081ab9ba46d46f01beb684422a675 Mon Sep 17 00:00:00 2001 From: nsheaps <1282393+nsheaps@users.noreply.github.com> Date: Fri, 24 Apr 2026 15:32:16 +0000 Subject: [PATCH 02/13] chore: auto-bump plugin versions and update marketplace --- plugins/task-utils/docs/spec.md | 50 +++++++++++++++++---------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/plugins/task-utils/docs/spec.md b/plugins/task-utils/docs/spec.md index 7b27a69fa..02c24e700 100644 --- a/plugins/task-utils/docs/spec.md +++ b/plugins/task-utils/docs/spec.md @@ -76,13 +76,13 @@ The provider list is open — future providers (e.g., Linear, Jira, Slack) can b task-utils: providers: filesystem: - enabled: true # writes to $CLAUDE_PROJECT_DIR/.claude/tasks/ + enabled: true # writes to $CLAUDE_PROJECT_DIR/.claude/tasks/ githubIssues: - enabled: false # set true to enable GitHub issue sync - repo: "owner/repo" # required if enabled: true - labels: # optional labels to apply to created/updated issues + enabled: false # set true to enable GitHub issue sync + repo: "owner/repo" # required if enabled: true + labels: # optional labels to apply to created/updated issues - "agent-task" - closeOnComplete: true # close issue when task completes + closeOnComplete: true # close issue when task completes ``` ## Hooks (7 total) @@ -98,6 +98,7 @@ task-utils: **Source**: todo-plus-plus `SessionStart` hook **Behavior**: + - Injects task-awareness context into the session (reminder to use TaskCreate on every action request) - Restores any `in_progress` tasks from the previous session, prompting the agent to resume or triage them @@ -132,7 +133,7 @@ task-utils: **Configurable**: per-provider `enabled` flags **Advisory**: No (when enabled) — failure emits warning but does not block -### 7. `PostToolUse:TodoWrite` — Sync Todo JSON *(deferred post-MVP)* +### 7. `PostToolUse:TodoWrite` — Sync Todo JSON _(deferred post-MVP)_ **Source**: todo-sync **Behavior**: After `TodoWrite`, sync the todo list to a GitHub issue or comment for visibility. @@ -148,6 +149,7 @@ Documents how to run multiple tasks in parallel using background agents. ### `task-management` (new) New skill covering: + - When and how to use TaskCreate, TaskUpdate, TaskList, TaskGet - Task naming conventions (include ID and ticket number) - The full task lifecycle (created → in_progress → completed/cancelled) @@ -161,19 +163,19 @@ Full configuration reference via `plugins.settings.yaml` in the consuming agent' task-utils: providers: filesystem: - enabled: true # writes task state to $CLAUDE_PROJECT_DIR/.claude/tasks/ + enabled: true # writes task state to $CLAUDE_PROJECT_DIR/.claude/tasks/ githubIssues: - enabled: false # set true to enable GitHub issue sync - repo: "owner/repo" # required if enabled: true + enabled: false # set true to enable GitHub issue sync + repo: "owner/repo" # required if enabled: true labels: - "agent-task" closeOnComplete: true commitCheck: - enabled: true # block TaskCompleted if uncommitted changes exist + enabled: true # block TaskCompleted if uncommitted changes exist stopGuard: - enabled: true # warn on Stop if in_progress tasks remain (commented out initially) + enabled: true # warn on Stop if in_progress tasks remain (commented out initially) activeTaskGuard: - enabled: true # warn on tool use if no active task + enabled: true # warn on tool use if no active task ``` ## Migration Path @@ -191,18 +193,18 @@ No data migration required — task state lives in Claude Code's native store. ## MVP Scope (v1) -| Feature | Status | -|---|---| -| TaskCompleted commit check | In scope | -| SessionStart restore + awareness | In scope | -| PreToolUse active-task guard | In scope | -| Stop guard (migrated, commented out initially) | In scope | -| FilesystemProvider | In scope | -| GitHubIssuesProvider (find-or-create via haiku sub-agent) | In scope | -| task-parallelization skill (migrated) | In scope | -| task-management skill (new) | In scope | -| PostToolUse:TodoWrite sync | **Deferred** | -| TodoWrite gitignore init | **Deferred** | +| Feature | Status | +| --------------------------------------------------------- | ------------ | +| TaskCompleted commit check | In scope | +| SessionStart restore + awareness | In scope | +| PreToolUse active-task guard | In scope | +| Stop guard (migrated, commented out initially) | In scope | +| FilesystemProvider | In scope | +| GitHubIssuesProvider (find-or-create via haiku sub-agent) | In scope | +| task-parallelization skill (migrated) | In scope | +| task-management skill (new) | In scope | +| PostToolUse:TodoWrite sync | **Deferred** | +| TodoWrite gitignore init | **Deferred** | ## Deferred Items (post-MVP) From a70b4b1925cb95842577e3660f30a818876f6029 Mon Sep 17 00:00:00 2001 From: "jack-nsheaps[bot]" <233066888+jack-nsheaps[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 11:48:35 -0400 Subject: [PATCH 03/13] =?UTF-8?q?refactor(task-utils):=20delete=20todo-plu?= =?UTF-8?q?s-plus,=20todo-sync,=20task-parallelization=20=E2=80=94=20conso?= =?UTF-8?q?lidated=20into=20task-utils?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.claude-plugin/plugin.json | 20 -- plugins/task-parallelization/.release-it.js | 9 - plugins/task-parallelization/CHANGELOG.md | 77 ------- plugins/task-parallelization/README.md | 113 ---------- .../skills/task-parallelization/SKILL.md | 209 ------------------ .../todo-plus-plus/.claude-plugin/plugin.json | 10 - plugins/todo-plus-plus/.release-it.js | 9 - plugins/todo-plus-plus/README.md | 55 ----- plugins/todo-plus-plus/hooks/hooks.json | 29 --- plugins/todo-plus-plus/lib/log.sh | 1 - .../scripts/check-uncommitted.sh | 45 ---- .../skills/todo-plus-plus/SKILL.md | 59 ----- plugins/todo-sync/.claude-plugin/plugin.json | 10 - plugins/todo-sync/.release-it.js | 9 - plugins/todo-sync/README.md | 76 ------- plugins/todo-sync/hooks/hooks.json | 41 ---- plugins/todo-sync/lib/hook-output.sh | 1 - plugins/todo-sync/lib/log.sh | 1 - plugins/todo-sync/scripts/init-gitignore.sh | 37 ---- plugins/todo-sync/scripts/sync-todos.sh | 99 --------- plugins/todo-sync/skills/todo-sync/SKILL.md | 70 ------ 21 files changed, 980 deletions(-) delete mode 100644 plugins/task-parallelization/.claude-plugin/plugin.json delete mode 100644 plugins/task-parallelization/.release-it.js delete mode 100644 plugins/task-parallelization/CHANGELOG.md delete mode 100644 plugins/task-parallelization/README.md delete mode 100644 plugins/task-parallelization/skills/task-parallelization/SKILL.md delete mode 100644 plugins/todo-plus-plus/.claude-plugin/plugin.json delete mode 100644 plugins/todo-plus-plus/.release-it.js delete mode 100644 plugins/todo-plus-plus/README.md delete mode 100644 plugins/todo-plus-plus/hooks/hooks.json delete mode 120000 plugins/todo-plus-plus/lib/log.sh delete mode 100755 plugins/todo-plus-plus/scripts/check-uncommitted.sh delete mode 100644 plugins/todo-plus-plus/skills/todo-plus-plus/SKILL.md delete mode 100644 plugins/todo-sync/.claude-plugin/plugin.json delete mode 100644 plugins/todo-sync/.release-it.js delete mode 100644 plugins/todo-sync/README.md delete mode 100644 plugins/todo-sync/hooks/hooks.json delete mode 120000 plugins/todo-sync/lib/hook-output.sh delete mode 120000 plugins/todo-sync/lib/log.sh delete mode 100755 plugins/todo-sync/scripts/init-gitignore.sh delete mode 100755 plugins/todo-sync/scripts/sync-todos.sh delete mode 100644 plugins/todo-sync/skills/todo-sync/SKILL.md diff --git a/plugins/task-parallelization/.claude-plugin/plugin.json b/plugins/task-parallelization/.claude-plugin/plugin.json deleted file mode 100644 index 51dc0738d..000000000 --- a/plugins/task-parallelization/.claude-plugin/plugin.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "task-parallelization", - "version": "0.2.25", - "description": "Intelligent skill that helps Claude parallelize Task tool calls when working on repetitive or batch operations, optimizing throughput based on task complexity", - "author": { - "name": "Nathan Heaps", - "email": "nsheaps@gmail.com", - "url": "https://github.com/nsheaps" - }, - "homepage": "https://github.com/nsheaps/ai-mktpl/tree/main/plugins/task-parallelization", - "keywords": [ - "parallelization", - "task", - "agent", - "batch", - "performance", - "optimization", - "concurrent" - ] -} diff --git a/plugins/task-parallelization/.release-it.js b/plugins/task-parallelization/.release-it.js deleted file mode 100644 index 539d53629..000000000 --- a/plugins/task-parallelization/.release-it.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - extends: "../../.release-it.base.json", - plugins: { - "@release-it/bumper": { - in: ".claude-plugin/plugin.json", - out: ".claude-plugin/plugin.json", - }, - }, -}; diff --git a/plugins/task-parallelization/CHANGELOG.md b/plugins/task-parallelization/CHANGELOG.md deleted file mode 100644 index b3333c5bf..000000000 --- a/plugins/task-parallelization/CHANGELOG.md +++ /dev/null @@ -1,77 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. - -## 0.2.24 (2026-01-16) - -## 0.2.23 (2026-01-16) - -## 0.2.22 (2026-01-16) - -## 0.2.21 (2026-01-16) - -## 0.2.20 (2026-01-16) - -## 0.2.19 (2026-01-16) - -## 0.2.18 (2026-01-16) - -## 0.2.17 (2026-01-16) - -## 0.2.16 (2026-01-16) - -## 0.2.15 (2026-01-16) - -## 0.2.14 (2026-01-16) - -## 0.2.13 (2026-01-16) - -## 0.2.12 (2026-01-16) - -## 0.2.11 (2026-01-16) - -### Bug Fixes - -- improve version bump workflow and CI integration ([#73](https://github.com/nsheaps/.ai/issues/73)) ([d89cca3](https://github.com/nsheaps/.ai/commit/d89cca31f5691fbe1bf11dd5f21b8800ccae3c41)) - -## 0.2.10 (2026-01-16) - -## 0.2.9 (2026-01-16) - -## 0.2.8 (2026-01-16) - -## 0.2.7 (2026-01-16) - -## 0.2.6 (2026-01-16) - -## 0.2.5 (2026-01-16) - -## 0.2.4 (2026-01-16) - -## 0.2.3 (2026-01-16) - -## 0.2.2 (2026-01-16) - -### Bug Fixes - -- **self-terminate:** traverse process tree to find Claude ([9caa408](https://github.com/nsheaps/.ai/commit/9caa408369b3120868927b2d5f0cbdeca71aef5a)) - -## 0.2.1 (2026-01-16) - -### Features - -- add self-terminate plugin for graceful session exit ([9d120e8](https://github.com/nsheaps/.ai/commit/9d120e88d621263049463073af9750b99259a5c2)) - -## 0.0.8 (2026-01-16) - -## 0.0.7 (2026-01-16) - -## 0.0.6 (2026-01-16) - -## 0.0.5 (2026-01-16) - -## 0.0.4 (2026-01-16) - -## 0.0.3 (2026-01-16) - -## 0.0.2 (2026-01-16) diff --git a/plugins/task-parallelization/README.md b/plugins/task-parallelization/README.md deleted file mode 100644 index b9bb460ec..000000000 --- a/plugins/task-parallelization/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# Task Parallelization Plugin - -An intelligent skill that helps Claude Code parallelize Task tool calls when working on batch operations, repetitive changes, or research tasks. - -## Overview - -When you ask Claude to perform the same operation across many items (files, components, services), this skill automatically guides Claude to: - -1. **Identify parallelizable work** - Recognize when tasks can run concurrently -2. **Assess optimal parallelization** - Determine how many tasks to run in parallel based on complexity -3. **Execute efficiently** - Batch and run tasks for maximum throughput -4. **Handle failures gracefully** - Retry failed tasks and report results clearly - -## Features - -### Intelligent Parallelization Levels - -The skill defines 5 parallelization levels based on task characteristics: - -| Level | Concurrent Tasks | Use Case | -| -------------- | ---------------- | ---------------------------------------------- | -| **Maximum** | 8-10 | Read-only research, exploration, analysis | -| **High** | 5-7 | Simple templated changes, bulk updates | -| **Moderate** | 3-4 | Refactoring, migrations, context-aware changes | -| **Limited** | 2 | Complex logic, subtle dependencies | -| **Sequential** | 1 | Explicit dependencies, shared state | - -### Automatic Complexity Assessment - -The skill evaluates each batch operation for: - -- Task independence (can tasks run without affecting each other?) -- Resource requirements (CPU, memory, I/O intensity) -- Failure impact (what happens if one task fails?) -- Task complexity (simple pattern vs. complex reasoning) - -### Model Selection Guidance - -For cost-effective parallel execution: - -- **haiku**: Simple, repetitive tasks (renaming, imports, templated edits) -- **sonnet**: Moderate complexity (refactoring, documentation) -- **opus**: Complex reasoning (architecture, debugging) - -## Example Use Cases - -### High Parallelization Examples - -``` -"Research how 10 different libraries handle authentication" -"Add the same import to all 50 component files" -"Check which of these 20 APIs are still active" -``` - -### Moderate Parallelization Examples - -``` -"Refactor these 15 functions to use the new error handling pattern" -"Update all configuration files to the new schema" -"Add JSDoc comments to all exported functions" -``` - -### Sequential Examples - -``` -"Create the base class, then create all derived classes" -"Update the API schema, then update all callers" -``` - -## Installation - -See [Installation Guide](../../docs/installation.md) for all installation methods. - -### Quick Install - -```bash -# Via marketplace (recommended) -# Follow marketplace setup: ../../docs/manual-installation.md - -# Or via GitHub -claude plugins install github:nsheaps/ai-mktpl/plugins/task-parallelization - -# Or locally for testing -cc --plugin-dir /path/to/plugins/task-parallelization -``` - -## How It Works - -When you make a request that involves repetitive or batch operations, Claude will: - -1. **Recognize the pattern** - Identify that multiple similar tasks need to be performed -2. **Consult this skill** - Use the parallelization guidelines to plan execution -3. **Create task batches** - Group independent tasks based on the recommended parallelization level -4. **Execute in parallel** - Launch multiple Task agents concurrently -5. **Aggregate results** - Collect and summarize outcomes from all tasks - -## Best Practices - -### Do - -- Be specific about what needs to change across items -- Provide examples of the expected transformation -- Mention if there are any dependencies between items - -### Don't - -- Ask to parallelize tasks that modify the same file -- Expect shared context between parallel tasks -- Assume order of completion matches order of launch - -## License - -MIT License - See repository root for details. diff --git a/plugins/task-parallelization/skills/task-parallelization/SKILL.md b/plugins/task-parallelization/skills/task-parallelization/SKILL.md deleted file mode 100644 index 9d9d391d9..000000000 --- a/plugins/task-parallelization/skills/task-parallelization/SKILL.md +++ /dev/null @@ -1,209 +0,0 @@ ---- -name: task-parallelization -description: Automatically identify opportunities to parallelize Task tool calls when working on batch operations, repetitive changes, or research tasks. Use this skill when asked to make the same change across multiple files/items, perform bulk operations, or conduct research across multiple sources. ---- - -# Task Parallelization Skill - -This skill helps you identify when and how to parallelize Task tool calls for maximum efficiency when working on batch or repetitive operations. - -## When to Use Parallelization - -### High Parallelization Candidates (parallelize aggressively) - -- **Research tasks**: Searching documentation, exploring codebases, gathering information -- **Read-only operations**: Analyzing files, checking status, validating configurations -- **Independent file changes**: Same change across unrelated files (no dependencies) -- **Bulk lookups**: Fetching information from multiple sources -- **Code review**: Reviewing multiple files or PRs independently - -### Medium Parallelization Candidates (parallelize with caution) - -- **File modifications**: Editing multiple files with the same pattern -- **Test execution**: Running tests across different modules -- **Migrations**: Applying similar changes across related components -- **Refactoring**: Renaming or restructuring across the codebase - -### Low Parallelization Candidates (limit parallelization) - -- **Complex logic changes**: Changes requiring careful reasoning -- **Interdependent modifications**: Changes where one depends on another -- **Build/compilation tasks**: CPU-intensive operations -- **Database operations**: Operations that might conflict - -## Parallelization Levels - -### Level 1: Maximum Parallelization (8-10 concurrent tasks) - -**Use when:** - -- Tasks are purely read-only (research, exploration, analysis) -- Tasks are completely independent with no shared resources -- Tasks are simple and unlikely to fail -- Low CPU/memory requirements - -**Examples:** - -- "Research how 10 different libraries handle authentication" -- "Find all usages of a deprecated function across the codebase" -- "Check the status of 10 different services" - -### Level 2: High Parallelization (5-7 concurrent tasks) - -**Use when:** - -- Tasks involve simple, templated changes -- Tasks modify different files with no interdependencies -- Changes follow a clear, repeatable pattern -- Moderate complexity with low failure risk - -**Examples:** - -- "Add the same import statement to 20 files" -- "Update version numbers across all package.json files" -- "Add a standard header comment to all source files" - -### Level 3: Moderate Parallelization (3-4 concurrent tasks) - -**Use when:** - -- Tasks involve some complexity or judgment -- Tasks modify related files but without direct dependencies -- Changes require some context awareness -- Medium risk of conflicts or failures - -**Examples:** - -- "Refactor 10 similar functions to use a new API" -- "Update error handling patterns across modules" -- "Migrate configuration files to a new format" - -### Level 4: Limited Parallelization (2 concurrent tasks) - -**Use when:** - -- Tasks involve complex logic or decision-making -- Tasks might have subtle interdependencies -- Changes require careful reasoning -- Higher risk of conflicts or cascading failures - -**Examples:** - -- "Fix type errors in related components" -- "Update database schemas and their migrations" -- "Refactor tightly coupled modules" - -### Level 5: Sequential (1 task at a time) - -**Use when:** - -- Tasks have explicit dependencies (A must complete before B) -- Tasks modify shared state or resources -- Order of operations matters -- High complexity requiring full attention - -**Examples:** - -- "Build, then test, then deploy" -- "Create base class, then derived classes" -- "Update API, then update all callers" - -## Implementation Pattern - -When you identify a parallelizable request, structure your response like this: - -### Step 1: Identify the Work - -Break down the request into discrete, independent units of work. - -### Step 2: Assess Complexity - -Determine the appropriate parallelization level based on: - -- Task independence -- Resource requirements -- Failure impact -- Complexity of each task - -### Step 3: Batch and Execute - -Group tasks into batches based on the parallelization level and execute. - -### Example Implementation - -**User Request:** "Add JSDoc comments to all 12 exported functions in the utils/ directory" - -**Analysis:** - -- Task type: File modifications (templated changes) -- Independence: High (each function is independent) -- Complexity: Low-Medium (requires reading function, writing appropriate docs) -- Recommended level: Level 2-3 (4-6 concurrent tasks) - -**Execution Plan:** - -``` -Batch 1: Tasks 1-5 (parallel) -Batch 2: Tasks 6-10 (parallel) -Batch 3: Tasks 11-12 (parallel) -``` - -## Critical Rules - -### DO: - -1. **Always assess independence** before parallelizing -2. **Start conservatively** - you can increase parallelization if tasks succeed -3. **Use haiku model** for simple, repetitive tasks to save cost -4. **Group similar tasks** in the same batch for consistency -5. **Provide clear, detailed prompts** to each task (they don't share context) -6. **Include all necessary context** in each task prompt (file paths, patterns, examples) - -### DON'T: - -1. **Don't parallelize dependent tasks** - if B needs A's output, run sequentially -2. **Don't over-parallelize complex tasks** - quality suffers -3. **Don't parallelize tasks that modify shared state** (same file, same config) -4. **Don't assume tasks share context** - each Task agent is independent -5. **Don't forget to aggregate results** - summarize outcomes for the user - -## Task Prompt Template - -When launching parallel tasks, use this template: - -``` -You are performing task {N} of {TOTAL} in a parallel batch operation. - -## Task -{Specific task description} - -## Context -{Any necessary background information} - -## Files/Targets -{Specific file(s) or item(s) to work on} - -## Expected Output -{What the task should produce or change} - -## Constraints -- {Any limitations or rules} -- This is a standalone task - do not assume access to other parallel tasks' results -``` - -## Handling Failures - -When parallel tasks fail: - -1. **Identify failed tasks** from the results -2. **Analyze failure patterns** - are they related? -3. **Retry failed tasks** with potentially lower parallelization -4. **Report to user** which tasks succeeded and which need attention - -## Model Selection for Parallel Tasks - -- **haiku**: Simple, repetitive tasks (renaming, adding imports, simple edits) -- **sonnet**: Moderate complexity (refactoring, documentation, standard changes) -- **opus**: Complex reasoning (architecture decisions, complex debugging) - -Using haiku for simple parallel tasks can significantly reduce cost and latency while maintaining quality for straightforward operations. diff --git a/plugins/todo-plus-plus/.claude-plugin/plugin.json b/plugins/todo-plus-plus/.claude-plugin/plugin.json deleted file mode 100644 index 613f6ccc0..000000000 --- a/plugins/todo-plus-plus/.claude-plugin/plugin.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "todo-plus-plus", - "version": "0.1.5", - "description": "Enforces commit-on-complete for tasks and reminds about ephemeral session awareness", - "author": { - "name": "Nathan Heaps", - "email": "nsheaps@gmail.com" - }, - "keywords": ["tasks", "commit", "workflow", "ephemeral", "agent-teams"] -} diff --git a/plugins/todo-plus-plus/.release-it.js b/plugins/todo-plus-plus/.release-it.js deleted file mode 100644 index 539d53629..000000000 --- a/plugins/todo-plus-plus/.release-it.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - extends: "../../.release-it.base.json", - plugins: { - "@release-it/bumper": { - in: ".claude-plugin/plugin.json", - out: ".claude-plugin/plugin.json", - }, - }, -}; diff --git a/plugins/todo-plus-plus/README.md b/plugins/todo-plus-plus/README.md deleted file mode 100644 index 43ad57795..000000000 --- a/plugins/todo-plus-plus/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Todo++ Plugin - -Enforces commit-on-complete for tasks and provides ephemeral session awareness. - -## Features - -- **Commit-on-Complete**: Blocks task completion if there are uncommitted or unpushed changes -- **Ephemeral Session Awareness**: Reminds agents that Tasks are session-scoped, not persistent - -## Installation - -Add to your project or user settings.json enabledPlugins. - -## How It Works - -### TaskCompleted Hook - -When any task is marked complete (via TaskUpdate), the hook: - -1. Checks `git status` for uncommitted changes -2. Checks for unpushed commits -3. If either exists, blocks completion with a message telling Claude to commit and push first - -### SessionStart Hook - -On session start, injects a prompt reminding Claude that: - -- Tasks are for local session work only -- Always commit and push before completing tasks -- Use external systems for persistent project tracking - -## File Structure - -``` -todo-plus-plus/ -├── .claude-plugin/ -│ └── plugin.json -├── hooks/ -│ └── hooks.json # TaskCompleted + SessionStart hooks -├── scripts/ -│ └── check-uncommitted.sh # Git status checker -├── skills/ -│ └── todo-plus-plus/ -│ └── SKILL.md -└── README.md -``` - -## Related Plugins - -- **todo-sync** -- Syncs todos from ~/.claude/ to project .claude/ (complementary) -- **scm-utils** -- Git workflow utilities - -## License - -MIT diff --git a/plugins/todo-plus-plus/hooks/hooks.json b/plugins/todo-plus-plus/hooks/hooks.json deleted file mode 100644 index 448fdd33d..000000000 --- a/plugins/todo-plus-plus/hooks/hooks.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "description": "Commit enforcement on task completion and ephemeral session awareness on start", - "hooks": { - "TaskCompleted": [ - { - "matcher": "*", - "hooks": [ - { - "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/check-uncommitted.sh", - "timeout": 15 - } - ] - } - ], - "SessionStart": [ - { - "matcher": "*", - "hooks": [ - { - "type": "command", - "command": "echo '{\"systemMessage\": \"IMPORTANT SESSION CONTEXT: You may be running in an ephemeral session (a sub-agent, teammate, or temporary context). The Tasks system (TaskCreate, TaskUpdate, TaskList) is for tracking YOUR local work items within THIS session only. Do NOT use Tasks for persistent project tracking, feature backlogs, or cross-session work items. Those belong in external systems (GitHub Issues, Linear, etc.). Tasks are session-scoped and will not survive session end. Also: when you complete a task, ALWAYS commit and push your changes before marking it complete.\"}'", - "timeout": 5 - } - ] - } - ] - } -} diff --git a/plugins/todo-plus-plus/lib/log.sh b/plugins/todo-plus-plus/lib/log.sh deleted file mode 120000 index 3d035ca54..000000000 --- a/plugins/todo-plus-plus/lib/log.sh +++ /dev/null @@ -1 +0,0 @@ -../../../shared/lib/log.sh \ No newline at end of file diff --git a/plugins/todo-plus-plus/scripts/check-uncommitted.sh b/plugins/todo-plus-plus/scripts/check-uncommitted.sh deleted file mode 100755 index a905c25b9..000000000 --- a/plugins/todo-plus-plus/scripts/check-uncommitted.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash -# check-uncommitted.sh - Blocks task completion if there are uncommitted changes -# Triggered by TaskCompleted hook -# -# Exit code 2 = block completion and send stderr as feedback to Claude -# Exit code 0 = allow completion - -set -euo pipefail - -LOG_PREFIX="todo-plus-plus" -# shellcheck source=../lib/log.sh -source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/lib/log.sh" - -# Read hook input from stdin (consume it so the pipe doesn't break) -cat > /dev/null - -# Check if we're in a git repo -if ! git rev-parse --is-inside-work-tree &>/dev/null; then - # Not a git repo, allow completion - exit 0 -fi - -# Check for uncommitted changes (staged + unstaged + untracked) -status_output=$(git status --porcelain 2>/dev/null || true) - -if [ -n "$status_output" ]; then - # Count the changes - change_count=$(echo "$status_output" | wc -l | tr -d ' ') - - log_error "BLOCKED: You have $change_count uncommitted change(s). Commit and push your work before marking this task complete. Run 'git status' to see what needs to be committed." - exit 2 -fi - -# Check if local branch is ahead of remote -local_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "") -if [ -n "$local_branch" ] && [ "$local_branch" != "HEAD" ]; then - ahead_count=$(git rev-list --count "@{upstream}..HEAD" 2>/dev/null || echo "0") - if [ "$ahead_count" -gt 0 ]; then - log_error "BLOCKED: You have $ahead_count unpushed commit(s) on '$local_branch'. Push your changes before marking this task complete." - exit 2 - fi -fi - -# All clear -exit 0 diff --git a/plugins/todo-plus-plus/skills/todo-plus-plus/SKILL.md b/plugins/todo-plus-plus/skills/todo-plus-plus/SKILL.md deleted file mode 100644 index 106435aee..000000000 --- a/plugins/todo-plus-plus/skills/todo-plus-plus/SKILL.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -name: todo-plus-plus -description: Task workflow enforcement plugin. Use when asking about commit-on-complete behavior, task completion requirements, ephemeral session awareness, or why a task completion was blocked. ---- - -# Todo++ Plugin - -This plugin enforces two workflow rules for Claude Code sessions: - -## 1. Commit-on-Complete - -A **TaskCompleted** hook checks for uncommitted changes when any task is marked complete. If there are uncommitted or unpushed changes, the completion is **blocked** until you commit and push. - -### Why - -Agents frequently complete work but forget to commit. In ephemeral sessions (teammates, sub-agents), uncommitted work is **lost** when the session ends. This hook prevents that. - -### What Gets Checked - -1. **Uncommitted changes**: Any staged, unstaged, or untracked files (`git status --porcelain`) -2. **Unpushed commits**: Local commits that haven't been pushed to the remote - -### If Blocked - -When task completion is blocked: - -1. Run `git status` to see what needs attention -2. Stage and commit your changes -3. Push to remote -4. Then mark the task complete again - -### Exceptions - -- If not in a git repository, the check is skipped -- The hook only fires on TaskCompleted events (team task system) - -## 2. Ephemeral Session Awareness - -A **SessionStart** hook injects a reminder that: - -- Tasks (TaskCreate/TaskUpdate/TaskList) are for **local session work only** -- Tasks do NOT persist across sessions -- Persistent tracking belongs in external systems (GitHub Issues, Linear, etc.) -- Always commit and push before marking tasks complete - -### Why - -Agents sometimes use the Task system as if it were a persistent project tracker, creating tasks they expect to survive session boundaries. This wastes context and creates confusion when tasks disappear. - -## Configuration - -No configuration required. Install the plugin and it works automatically. - -## Disabling - -To temporarily disable commit enforcement, you can: - -1. Disable the plugin in settings.json -2. Or remove the plugin from enabledPlugins diff --git a/plugins/todo-sync/.claude-plugin/plugin.json b/plugins/todo-sync/.claude-plugin/plugin.json deleted file mode 100644 index 763531b05..000000000 --- a/plugins/todo-sync/.claude-plugin/plugin.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "todo-sync", - "version": "0.2.4", - "description": "Automatically syncs todos and plans from ~/.claude/ to the current project's .claude/ directory", - "author": { - "name": "Nathan Heaps", - "email": "nsheaps@gmail.com" - }, - "keywords": ["todos", "plans", "sync", "workflow", "productivity"] -} diff --git a/plugins/todo-sync/.release-it.js b/plugins/todo-sync/.release-it.js deleted file mode 100644 index 539d53629..000000000 --- a/plugins/todo-sync/.release-it.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - extends: "../../.release-it.base.json", - plugins: { - "@release-it/bumper": { - in: ".claude-plugin/plugin.json", - out: ".claude-plugin/plugin.json", - }, - }, -}; diff --git a/plugins/todo-sync/README.md b/plugins/todo-sync/README.md deleted file mode 100644 index 89da10735..000000000 --- a/plugins/todo-sync/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# Todo Sync Plugin - -Automatically syncs todos and plans from `~/.claude/` to your current project's `.claude/` directory. - -## Features - -- **Automatic sync**: Triggers after every `TodoWrite` call via PostToolUse hook -- **Smart merge**: Deduplicates todos by content when merging -- **Plans support**: Syncs plan files from global to project directory -- **Session-aware**: Only syncs the current session's todos - -## Installation - -Add to your project's `.claude/settings.json`: - -```json -{ - "plugins": ["/path/to/todo-sync"] -} -``` - -Or install from the marketplace (if published). - -## How It Works - -``` -TodoWrite called - ↓ -PostToolUse hook fires - ↓ -sync-todos.sh executes - ↓ -~/.claude/todos/{session}.json → .claude/todos/{session}.json -~/.claude/plans/*.md → .claude/plans/*.md -``` - -## File Structure - -``` -todo-sync/ -├── .claude-plugin/ -│ └── plugin.json # Plugin manifest -├── hooks/ -│ └── hooks.json # Hook configuration (SessionStart, UserPromptSubmit, PostToolUse) -├── scripts/ -│ ├── init-gitignore.sh # Ensures global gitignore patterns -│ └── sync-todos.sh # Sync logic -├── skills/ -│ └── todo-sync/ -│ └── SKILL.md # Usage documentation -└── README.md -``` - -## Configuration - -No configuration required. The plugin works automatically once installed. - -### Git Integration - -The plugin automatically ensures `~/.config/git/ignore` (the global gitignore) contains patterns for `.claude/todos/` and `.claude/plans/` directories. This ignores all synced files in any project by default. - -To track todos in version control for a specific project, add explicit `!.claude/todos/` pattern to that project's `.gitignore`. - -## Troubleshooting - -Run Claude Code in debug mode to see hook execution: - -```bash -claude --debug -``` - -Look for `PostToolUse` events on `TodoWrite` to verify the hook is firing. - -## License - -MIT diff --git a/plugins/todo-sync/hooks/hooks.json b/plugins/todo-sync/hooks/hooks.json deleted file mode 100644 index cf5d5c1c9..000000000 --- a/plugins/todo-sync/hooks/hooks.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "description": "Syncs todos and plans from ~/.claude/ to project .claude/ directory after TodoWrite", - "hooks": { - "SessionStart": [ - { - "matcher": "*", - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/scripts/init-gitignore.sh", - "timeout": 5 - } - ] - } - ], - "UserPromptSubmit": [ - { - "matcher": "*", - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/scripts/init-gitignore.sh", - "timeout": 5 - } - ] - } - ], - "PostToolUse": [ - { - "matcher": "TodoWrite", - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/scripts/sync-todos.sh", - "timeout": 10 - } - ] - } - ] - } -} diff --git a/plugins/todo-sync/lib/hook-output.sh b/plugins/todo-sync/lib/hook-output.sh deleted file mode 120000 index 4c67a420b..000000000 --- a/plugins/todo-sync/lib/hook-output.sh +++ /dev/null @@ -1 +0,0 @@ -../../../shared/lib/hook-output.sh \ No newline at end of file diff --git a/plugins/todo-sync/lib/log.sh b/plugins/todo-sync/lib/log.sh deleted file mode 120000 index 3d035ca54..000000000 --- a/plugins/todo-sync/lib/log.sh +++ /dev/null @@ -1 +0,0 @@ -../../../shared/lib/log.sh \ No newline at end of file diff --git a/plugins/todo-sync/scripts/init-gitignore.sh b/plugins/todo-sync/scripts/init-gitignore.sh deleted file mode 100755 index 6e0d9fbc4..000000000 --- a/plugins/todo-sync/scripts/init-gitignore.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash -# init-gitignore.sh - Ensures .claude/todos and .claude/plans are globally ignored -# Triggered by SessionStart and UserPromptSubmit hooks -# -# This approach adds patterns to ~/.config/git/ignore so that: -# 1. All projects automatically ignore these directories -# 2. No per-project .gitignore files needed -# 3. No commits required in each project - -set -euo pipefail - -# shellcheck source=../lib/hook-output.sh -source "${CLAUDE_PLUGIN_ROOT}/lib/hook-output.sh" - -# Global gitignore location -global_gitignore="$HOME/.config/git/ignore" - -# Patterns to ensure are present -patterns=( - "**/.claude/plans" - "**/.claude/todos" -) - -# Create directory if needed -mkdir -p "$(dirname "$global_gitignore")" - -# Create file if it doesn't exist -touch "$global_gitignore" - -# Add each pattern if not already present -for pattern in "${patterns[@]}"; do - if ! grep -qxF "$pattern" "$global_gitignore" 2>/dev/null; then - echo "$pattern" >> "$global_gitignore" - fi -done - -hook_msg "todo-sync: gitignore patterns configured" diff --git a/plugins/todo-sync/scripts/sync-todos.sh b/plugins/todo-sync/scripts/sync-todos.sh deleted file mode 100755 index c6dc9ffed..000000000 --- a/plugins/todo-sync/scripts/sync-todos.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env bash -# sync-todos.sh - Syncs todos and plans from ~/.claude/ to project .claude/ -# Triggered by PostToolUse hook on TodoWrite - -set -euo pipefail - -PLUGIN_NAME="todo-sync" -# shellcheck source=../lib/log.sh -source "${CLAUDE_PLUGIN_ROOT}/lib/log.sh" - -# Check for jq dependency -if ! command -v jq &>/dev/null; then - log_warn "jq not found, skipping sync" - exit 0 -fi - -# Read hook input from stdin -input=$(cat) - -# Extract session_id from hook input -session_id=$(echo "$input" | jq -r '.session_id // empty') - -if [ -z "$session_id" ]; then - log_warn "No session_id in hook input, skipping sync" - exit 0 -fi - -# Determine project directory -project_dir="${CLAUDE_PROJECT_DIR:-$(pwd)}" - -# Create target directories if they don't exist -mkdir -p "$project_dir/.claude/todos" -mkdir -p "$project_dir/.claude/plans" - -# ============================================================================ -# SYNC TODOS -# ============================================================================ - -# Find the todo file for current session in ~/.claude/todos/ -# Files are named: {session-id}-agent-{agent-id}.json or just {session-id}.json -global_todos_dir="$HOME/.claude/todos" - -if [ -d "$global_todos_dir" ]; then - # Find files matching this session_id (using while read to handle filenames with spaces) - find "$global_todos_dir" -name "${session_id}*.json" -type f 2>/dev/null | while IFS= read -r src_file; do - filename=$(basename "$src_file") - dest_file="$project_dir/.claude/todos/$filename" - - # Read source todos - src_content=$(cat "$src_file" 2>/dev/null || echo "[]") - - # Skip empty arrays - if [ "$src_content" = "[]" ]; then - continue - fi - - # Check if destination exists for merge - if [ -f "$dest_file" ]; then - dest_content=$(cat "$dest_file" 2>/dev/null || echo "[]") - - # Merge: combine arrays, remove duplicates by content field - merged=$(jq -s ' - .[0] + .[1] | - unique_by(.content // .) - ' <(echo "$dest_content") <(echo "$src_content")) - - echo "$merged" > "$dest_file" - else - # No destination file, just copy - cp "$src_file" "$dest_file" - fi - done -fi - -# ============================================================================ -# SYNC PLANS -# ============================================================================ - -global_plans_dir="$HOME/.claude/plans" - -if [ -d "$global_plans_dir" ]; then - # Sync all plan files (they're markdown, so we just copy newer versions) - for src_file in "$global_plans_dir"/*.md; do - [ -f "$src_file" ] || continue - - filename=$(basename "$src_file") - dest_file="$project_dir/.claude/plans/$filename" - - # Only copy if source is newer or destination doesn't exist - if [ ! -f "$dest_file" ] || [ "$src_file" -nt "$dest_file" ]; then - cp "$src_file" "$dest_file" - fi - done -fi - -# Output success message (shown in transcript) -log_info "Synced todos and plans to $project_dir/.claude/" - -exit 0 diff --git a/plugins/todo-sync/skills/todo-sync/SKILL.md b/plugins/todo-sync/skills/todo-sync/SKILL.md deleted file mode 100644 index 5e14bfaa9..000000000 --- a/plugins/todo-sync/skills/todo-sync/SKILL.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: Todo Sync -description: Automatically syncs todos and plans from ~/.claude/ to the current project. Use this skill when asking about todo sync behavior, troubleshooting sync issues, or understanding where todos are stored. ---- - -# Todo Sync Plugin - -This plugin automatically synchronizes your todos and plans from the global Claude directory (`~/.claude/`) to your current project's `.claude/` directory. - -## How It Works - -The plugin uses a **PostToolUse hook** that triggers after every `TodoWrite` tool call: - -1. When you create or update todos using TodoWrite, the hook fires -2. The sync script finds your session's todo file in `~/.claude/todos/` -3. It merges the todos into `.claude/todos/` in your project -4. It also syncs any plan files from `~/.claude/plans/` to `.claude/plans/` - -## File Locations - -### Source (Global) - -- **Todos**: `~/.claude/todos/{session-id}.json` -- **Plans**: `~/.claude/plans/{plan-name}.md` - -### Destination (Project) - -- **Todos**: `.claude/todos/{session-id}.json` -- **Plans**: `.claude/plans/{plan-name}.md` - -## Merge Behavior - -**Todos**: When both source and destination files exist, todos are merged by deduplicating on the `content` field. This prevents duplicate todo entries. - -**Plans**: Plans are copied if the source is newer than the destination or if the destination doesn't exist. - -## Troubleshooting - -### Todos not syncing - -1. Check if `~/.claude/todos/` contains files for your session -2. Verify the plugin is enabled: look for it in `/plugins` command output -3. Check hook execution with `claude --debug` - -### Permission errors - -The script creates directories automatically. If you see permission errors: - -1. Ensure you have write access to your project directory -2. Check that `.claude/` isn't gitignored with restrictive permissions - -### Empty todo files - -Files containing only `[]` (empty arrays) are skipped during sync to avoid cluttering the project. - -## Integration with Git - -The plugin automatically adds patterns to `~/.config/git/ignore` (the global gitignore) for `.claude/todos/` and `.claude/plans/` directories. This prevents synced files from being committed in any project by default. - -If you want to track todos in version control for a specific project, add explicit `!.claude/todos/` pattern to that project's `.gitignore`. - -## Manual Sync - -The sync happens automatically on TodoWrite. If you need to manually trigger it, simply update your todos: - -``` -TodoWrite: [your todos here] -``` - -The hook will fire and sync will occur. From 1ceb92f900fbff655084f9d907f3e7c730913c07 Mon Sep 17 00:00:00 2001 From: "jack-nsheaps[bot]" <233066888+jack-nsheaps[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 11:52:06 -0400 Subject: [PATCH 04/13] =?UTF-8?q?feat(task-utils):=20scaffold=20plugin=20?= =?UTF-8?q?=E2=80=94=20hooks,=20skills,=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/task-utils/.claude-plugin/plugin.json | 11 + plugins/task-utils/README.md | 84 +++++++ plugins/task-utils/hooks/hooks.json | 75 +++++++ .../hooks/scripts/active-task-guard.sh | 39 ++++ .../hooks/scripts/check-uncommitted.sh | 46 ++++ .../task-utils/hooks/scripts/session-start.sh | 17 ++ .../task-utils/hooks/scripts/stop-guard.sh | 19 ++ .../hooks/scripts/sync-task-create.sh | 36 +++ .../hooks/scripts/sync-task-update.sh | 36 +++ plugins/task-utils/lib/log.sh | 51 +++++ .../skills/task-management/SKILL.md | 154 +++++++++++++ .../skills/task-parallelization/SKILL.md | 209 ++++++++++++++++++ 12 files changed, 777 insertions(+) create mode 100644 plugins/task-utils/.claude-plugin/plugin.json create mode 100644 plugins/task-utils/README.md create mode 100644 plugins/task-utils/hooks/hooks.json create mode 100755 plugins/task-utils/hooks/scripts/active-task-guard.sh create mode 100755 plugins/task-utils/hooks/scripts/check-uncommitted.sh create mode 100755 plugins/task-utils/hooks/scripts/session-start.sh create mode 100755 plugins/task-utils/hooks/scripts/stop-guard.sh create mode 100755 plugins/task-utils/hooks/scripts/sync-task-create.sh create mode 100755 plugins/task-utils/hooks/scripts/sync-task-update.sh create mode 100755 plugins/task-utils/lib/log.sh create mode 100644 plugins/task-utils/skills/task-management/SKILL.md create mode 100644 plugins/task-utils/skills/task-parallelization/SKILL.md diff --git a/plugins/task-utils/.claude-plugin/plugin.json b/plugins/task-utils/.claude-plugin/plugin.json new file mode 100644 index 000000000..f5f88a64b --- /dev/null +++ b/plugins/task-utils/.claude-plugin/plugin.json @@ -0,0 +1,11 @@ +{ + "name": "task-utils", + "version": "1.0.0", + "description": "Unified task management plugin — commit-on-complete, session awareness, active-task guard, stop guard, and provider-based task sync. Consolidates todo-plus-plus, todo-sync, and task-parallelization.", + "author": { + "name": "Nathan Heaps", + "email": "nsheaps@gmail.com", + "url": "https://github.com/nsheaps" + }, + "keywords": ["tasks", "commit", "workflow", "ephemeral", "parallelization", "sync", "agent-teams", "productivity"] +} diff --git a/plugins/task-utils/README.md b/plugins/task-utils/README.md new file mode 100644 index 000000000..ac929127c --- /dev/null +++ b/plugins/task-utils/README.md @@ -0,0 +1,84 @@ +# task-utils + +Unified task management plugin for Claude Code agents. Consolidates `todo-plus-plus`, `todo-sync`, and `task-parallelization` into a single cohesive plugin. + +See the full spec at [`docs/spec.md`](docs/spec.md). + +## Features + +- **Commit-on-Complete** (`TaskCompleted` hook): Blocks task completion if there are uncommitted or unpushed changes +- **Session Awareness** (`SessionStart` hook): Reminds agents that Tasks are session-scoped and not persistent; to always commit before completing tasks +- **Active-Task Guard** (`PreToolUse` hook, advisory): Warns when a tool is used with no active task +- **Stop Guard** (`Stop` hook, advisory): Warns when a session ends with in-progress tasks +- **Provider-based Task Sync** (`PostToolUse:TaskCreate/TaskUpdate`): Syncs task state to configured backends (Filesystem, GitHub Issues) +- **Task Parallelization skill**: Migrated from `task-parallelization` — guidance on running parallel sub-agents +- **Task Management skill**: New skill covering the full task lifecycle, naming conventions, and delegation patterns + +## Installation + +Add `task-utils` to your `enabledPlugins` in `settings.json`. Remove `todo-plus-plus`, `todo-sync`, and `task-parallelization` if previously installed. + +## Configuration + +```yaml +# plugins.settings.yaml +task-utils: + providers: + filesystem: + enabled: true # writes task state to $CLAUDE_PROJECT_DIR/.claude/tasks/ + githubIssues: + enabled: false # set true to enable GitHub issue sync + repo: "owner/repo" # required if enabled: true + labels: + - "agent-task" + closeOnComplete: true + commitCheck: + enabled: true # block TaskCompleted if uncommitted changes exist + stopGuard: + enabled: true # warn on Stop if in_progress tasks remain + activeTaskGuard: + enabled: true # warn on tool use if no active task +``` + +## File Structure + +``` +task-utils/ +├── .claude-plugin/ +│ └── plugin.json +├── docs/ +│ └── spec.md # full specification +├── hooks/ +│ ├── hooks.json +│ └── scripts/ +│ ├── check-uncommitted.sh # TaskCompleted — commit guard +│ ├── session-start.sh # SessionStart — awareness + restore +│ ├── active-task-guard.sh # PreToolUse — active task advisory +│ ├── stop-guard.sh # Stop — in-progress task advisory +│ ├── sync-task-create.sh # PostToolUse:TaskCreate — provider sync +│ └── sync-task-update.sh # PostToolUse:TaskUpdate — provider sync +├── lib/ +│ └── log.sh # shared logging helpers +├── skills/ +│ ├── task-parallelization/ +│ │ └── SKILL.md # migrated from task-parallelization plugin +│ └── task-management/ +│ └── SKILL.md # new — task lifecycle and naming conventions +└── README.md +``` + +## Migration from Previous Plugins + +If you used `todo-plus-plus`, `todo-sync`, and/or `task-parallelization`: + +1. Install `task-utils` +2. Remove the old plugins from `enabledPlugins` +3. Configure `providers.githubIssues` if you used todo-sync's GitHub sync + +No data migration required — task state lives in Claude Code's native task store. + +**Note**: TodoWrite gitignore initialization (from todo-sync's `SessionStart`) is deferred to v1.1. If you relied on this, keep `todo-sync` installed until then. + +## License + +MIT diff --git a/plugins/task-utils/hooks/hooks.json b/plugins/task-utils/hooks/hooks.json new file mode 100644 index 000000000..8c1fb3e3b --- /dev/null +++ b/plugins/task-utils/hooks/hooks.json @@ -0,0 +1,75 @@ +{ + "description": "Task lifecycle hooks: commit check, session awareness + restore, active-task guard, stop guard, and provider sync", + "hooks": { + "TaskCompleted": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check-uncommitted.sh", + "timeout": 15 + } + ] + } + ], + "SessionStart": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start.sh", + "timeout": 10 + } + ] + } + ], + "PreToolUse": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/active-task-guard.sh", + "timeout": 5 + } + ] + } + ], + "Stop": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-guard.sh", + "timeout": 10 + } + ] + } + ], + "PostToolUse": [ + { + "matcher": "TaskCreate", + "hooks": [ + { + "type": "command", + "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/sync-task-create.sh", + "timeout": 30 + } + ] + }, + { + "matcher": "TaskUpdate", + "hooks": [ + { + "type": "command", + "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/sync-task-update.sh", + "timeout": 30 + } + ] + } + ] + } +} diff --git a/plugins/task-utils/hooks/scripts/active-task-guard.sh b/plugins/task-utils/hooks/scripts/active-task-guard.sh new file mode 100755 index 000000000..1323aa118 --- /dev/null +++ b/plugins/task-utils/hooks/scripts/active-task-guard.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# active-task-guard.sh — Advisory warning when a tool is used with no active task +# Triggered by PreToolUse hook (advisory only — does not block) +# +# This is a new hook with no predecessor in the consolidated plugins. +# Exit code 0 = allow (advisory warnings do not block) + +set -euo pipefail + +# Read hook input from stdin +input=$(cat) + +# Extract the tool name from the hook input +# Hook input format: {"tool_name": "...", "tool_input": {...}, ...} +tool_name="" +if command -v jq &>/dev/null; then + tool_name=$(echo "$input" | jq -r '.tool_name // empty' 2>/dev/null || echo "") +fi + +# Conversational tools that don't require an active task +EXEMPT_TOOLS=( + "TodoRead" + "TodoWrite" + "TaskList" + "TaskGet" +) + +# Check if the tool is exempt +for exempt in "${EXEMPT_TOOLS[@]}"; do + if [ "$tool_name" = "$exempt" ]; then + exit 0 + fi +done + +# Stub: active task detection would query TaskList here. +# For now this hook exits 0 (pass-through) — full implementation in v1.1 +# when TaskList output can be reliably parsed from within a hook. + +exit 0 diff --git a/plugins/task-utils/hooks/scripts/check-uncommitted.sh b/plugins/task-utils/hooks/scripts/check-uncommitted.sh new file mode 100755 index 000000000..fc8c7ee76 --- /dev/null +++ b/plugins/task-utils/hooks/scripts/check-uncommitted.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# check-uncommitted.sh — Blocks task completion if there are uncommitted changes +# Triggered by TaskCompleted hook +# +# Exit code 2 = block completion and send stderr as feedback to Claude +# Exit code 0 = allow completion +# +# Source: migrated from todo-plus-plus v0.1.5 + +set -euo pipefail + +LOG_PREFIX="task-utils" +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib/log.sh" + +# Read hook input from stdin (consume it so the pipe doesn't break) +cat > /dev/null + +# Check if we're in a git repo +if ! git rev-parse --is-inside-work-tree &>/dev/null; then + # Not a git repo, allow completion + exit 0 +fi + +# Check for uncommitted changes (staged + unstaged + untracked) +status_output=$(git status --porcelain 2>/dev/null || true) + +if [ -n "$status_output" ]; then + # Count the changes + change_count=$(echo "$status_output" | wc -l | tr -d ' ') + + log_error "BLOCKED: You have $change_count uncommitted change(s). Commit and push your work before marking this task complete. Run 'git status' to see what needs to be committed." + exit 2 +fi + +# Check if local branch is ahead of remote +local_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "") +if [ -n "$local_branch" ] && [ "$local_branch" != "HEAD" ]; then + ahead_count=$(git rev-list --count "@{upstream}..HEAD" 2>/dev/null || echo "0") + if [ "$ahead_count" -gt 0 ]; then + log_error "BLOCKED: You have $ahead_count unpushed commit(s) on '$local_branch'. Push your changes before marking this task complete." + exit 2 + fi +fi + +# All clear +exit 0 diff --git a/plugins/task-utils/hooks/scripts/session-start.sh b/plugins/task-utils/hooks/scripts/session-start.sh new file mode 100755 index 000000000..ac8398cdd --- /dev/null +++ b/plugins/task-utils/hooks/scripts/session-start.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# session-start.sh — Injects task-awareness context and restores in-progress tasks +# Triggered by SessionStart hook +# +# Source: migrated and extended from todo-plus-plus v0.1.5 SessionStart hook + +set -euo pipefail + +# Read hook input (consume stdin) +cat > /dev/null + +# Emit session context as a systemMessage via JSON output +cat <<'EOF' +{"systemMessage": "IMPORTANT SESSION CONTEXT: You may be running in an ephemeral session (a sub-agent, teammate, or temporary context). The Tasks system (TaskCreate, TaskUpdate, TaskList) is for tracking YOUR local work items within THIS session only. Do NOT use Tasks for persistent project tracking, feature backlogs, or cross-session work items. Those belong in external systems (GitHub Issues, Linear, etc.). Tasks are session-scoped and will not survive session end. Also: when you complete a task, ALWAYS commit and push your changes before marking it complete. Use TaskCreate on EVERY action request from the user — even simple, one-off tasks. Always keep your task list up to date."} +EOF + +exit 0 diff --git a/plugins/task-utils/hooks/scripts/stop-guard.sh b/plugins/task-utils/hooks/scripts/stop-guard.sh new file mode 100755 index 000000000..c21ea6492 --- /dev/null +++ b/plugins/task-utils/hooks/scripts/stop-guard.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# stop-guard.sh — Advisory warning when session ends with in-progress tasks +# Triggered by Stop hook (advisory only — does not block) +# +# Source: migrated from agent repo (was in .claude/rules as a hook, not a plugin hook). +# Commented out initially pending validation in plugin context — see spec. +# +# Exit code 0 = allow session to stop (advisory) + +set -euo pipefail + +# Read hook input (consume stdin) +cat > /dev/null + +# TODO: Implement in-progress task detection via TaskList. +# Full implementation deferred to v1.1 pending reliable TaskList access from hooks. +# The hook is registered in hooks.json and runs, but currently exits 0 (no-op). + +exit 0 diff --git a/plugins/task-utils/hooks/scripts/sync-task-create.sh b/plugins/task-utils/hooks/scripts/sync-task-create.sh new file mode 100755 index 000000000..9e2969b55 --- /dev/null +++ b/plugins/task-utils/hooks/scripts/sync-task-create.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# sync-task-create.sh — Syncs a newly created task to configured providers +# Triggered by PostToolUse:TaskCreate hook +# +# Source: new hook — replaces todo-sync's TodoWrite sync with provider-based architecture. +# Providers are configured in plugins.settings.yaml under task-utils.providers. + +set -euo pipefail + +LOG_PREFIX="task-utils" +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib/log.sh" + +# Read hook input from stdin +input=$(cat) + +# Extract task info (if jq is available) +if ! command -v jq &>/dev/null; then + log_warn "jq not found — skipping provider sync" + exit 0 +fi + +task_id=$(echo "$input" | jq -r '.tool_result.taskId // empty' 2>/dev/null || echo "") +task_title=$(echo "$input" | jq -r '.tool_result.subject // empty' 2>/dev/null || echo "") + +if [ -z "$task_id" ]; then + # No task ID in output — nothing to sync + exit 0 +fi + +# TODO: Read provider config from plugins.settings.yaml and invoke each enabled provider. +# FilesystemProvider and GitHubIssuesProvider will be implemented in the full v1 release. +# This stub exits 0 so the hook is registered and wired but does not fail. + +log_info "TaskCreate sync stub: task_id=$task_id title='$task_title' (providers not yet implemented)" + +exit 0 diff --git a/plugins/task-utils/hooks/scripts/sync-task-update.sh b/plugins/task-utils/hooks/scripts/sync-task-update.sh new file mode 100755 index 000000000..2088d65a9 --- /dev/null +++ b/plugins/task-utils/hooks/scripts/sync-task-update.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# sync-task-update.sh — Syncs task status changes to configured providers +# Triggered by PostToolUse:TaskUpdate hook +# +# Source: new hook — provider-based architecture (see spec.md). +# Providers are configured in plugins.settings.yaml under task-utils.providers. + +set -euo pipefail + +LOG_PREFIX="task-utils" +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib/log.sh" + +# Read hook input from stdin +input=$(cat) + +# Extract task info (if jq is available) +if ! command -v jq &>/dev/null; then + log_warn "jq not found — skipping provider sync" + exit 0 +fi + +task_id=$(echo "$input" | jq -r '.tool_input.id // empty' 2>/dev/null || echo "") +new_status=$(echo "$input" | jq -r '.tool_input.status // empty' 2>/dev/null || echo "") + +if [ -z "$task_id" ]; then + # No task ID in input — nothing to sync + exit 0 +fi + +# TODO: Read provider config from plugins.settings.yaml and invoke each enabled provider. +# FilesystemProvider and GitHubIssuesProvider will be implemented in the full v1 release. +# This stub exits 0 so the hook is registered and wired but does not fail. + +log_info "TaskUpdate sync stub: task_id=$task_id status='$new_status' (providers not yet implemented)" + +exit 0 diff --git a/plugins/task-utils/lib/log.sh b/plugins/task-utils/lib/log.sh new file mode 100755 index 000000000..6af67cc80 --- /dev/null +++ b/plugins/task-utils/lib/log.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# log.sh — Lightweight general-purpose logging for any bash script +# +# Provides consistent stderr logging with a configurable prefix. +# Works in any context: hooks, session-start scripts, utility scripts, etc. +# +# Usage: +# LOG_PREFIX="my-script" # Optional: defaults to PLUGIN_NAME or "script" +# source "/path/to/log.sh" +# +# log_info "Installing tool v1.2.3" # my-script: Installing tool v1.2.3 +# log_warn "Fallback to default" # my-script: [warn] Fallback to default +# log_error "File not found" # my-script: [error] File not found +# log_step "download" "Downloading..." # my-script: [download] Downloading... +# +# All output goes to stderr so it never interferes with stdout (hook responses, etc). + +# Guard against double-sourcing +if [ "${_LOG_SH_LOADED:-}" = "true" ]; then + return 0 2>/dev/null || true +fi +_LOG_SH_LOADED="true" + +# Resolve prefix: explicit LOG_PREFIX > PLUGIN_NAME > "script" +_LOG_PREFIX="${LOG_PREFIX:-${PLUGIN_NAME:-script}}" + +# --- Logging functions --- + +# Log an informational message to stderr. +# Args: $1=message +log_info() { + echo "${_LOG_PREFIX}: $1" >&2 +} + +# Log a warning message to stderr. +# Args: $1=message +log_warn() { + echo "${_LOG_PREFIX}: [warn] $1" >&2 +} + +# Log an error message to stderr. +# Args: $1=message +log_error() { + echo "${_LOG_PREFIX}: [error] $1" >&2 +} + +# Log a named step to stderr. +# Args: $1=step_id $2=message +log_step() { + echo "${_LOG_PREFIX}: [$1] $2" >&2 +} diff --git a/plugins/task-utils/skills/task-management/SKILL.md b/plugins/task-utils/skills/task-management/SKILL.md new file mode 100644 index 000000000..a7502c1de --- /dev/null +++ b/plugins/task-utils/skills/task-management/SKILL.md @@ -0,0 +1,154 @@ +--- +name: task-management +description: Task lifecycle management for Claude Code agents. Use this skill when working with TaskCreate, TaskUpdate, TaskList, TaskGet, or when asked about task naming conventions, the task lifecycle, or when to delegate tasks to sub-agents. +--- + +# Task Management Skill + +This skill covers the full task lifecycle for Claude Code agents: when to create tasks, how to name them, how to track their state, and when to delegate to sub-agents. + +## Core Rule: Always Use Tasks for Action Requests + +ALWAYS use TaskCreate to track your tasks on EVERY action request from the user. Even if it is a simple, one-off task. + +**Exception**: When the user asks a question, answer it first. Do NOT create tasks for questions — only create tasks after the user confirms they want action. + +## When and How to Use TaskCreate + +### Trigger: Any action request from the user + +``` +User: "Fix the bug in the login flow" +→ TaskCreate: { subject: "#23: Fix the bug in the login flow" } +``` + +### Do NOT create tasks for: + +- Questions ("What is X?", "Why does Y happen?") +- Conversational responses +- Clarifications + +## Task Naming Conventions + +Tasks MUST always include the task ID in the subject and activeForm. + +**GOOD:** +``` +#23: Fix the bug in the login flow +``` + +**BAD:** +``` +Fix the bug in the login flow +``` + +### Ticket/PR References + +- If a task directly relates to a ticket in an external tracking system, include the ticket number in the subject. +- If a task relates to a PR, include the PR number if the user is referencing change sets by PR number. + +**Examples:** +``` +#23: [GH-456] Fix the authentication bug +#24: [PR #789] Review and address feedback +``` + +## Task Lifecycle + +``` +created → in_progress → completed + → cancelled +``` + +1. **created**: Task is defined but work has not started +2. **in_progress**: Actively working on this task right now +3. **completed**: Work is done, changes are committed and pushed +4. **cancelled**: Task is no longer needed + +### Rules + +- Only ONE task should be `in_progress` at a time (unless delegated to parallel sub-agents) +- Use TaskUpdate to change status before and after each phase +- Always commit and push before marking a task `completed` +- Update Tasks BEFORE any tool use — never have stale Tasks + +## Keeping Tasks Up to Date + +Before using ANY tool (Read, Edit, Write, Bash, Grep, etc.), you MUST first check your Tasks: + +1. If Tasks don't reflect what you're about to do, update them first +2. Never have stale Tasks that don't match your current work +3. Mark the current task `in_progress` before starting work + +## Delegating Tasks to Sub-Agents + +When working on a task, prefer delegating to an appropriate sub-agent rather than executing directly in your own context. + +### Why Delegate + +- Better isolation of work +- Clearer permission boundaries +- More efficient context usage +- Agents can be resumed for related follow-up work + +### When to Delegate + +| Task Type | Delegate? | +|-----------|-----------| +| Codebase investigation / exploration | Yes — use Explore agent with haiku | +| Architectural decisions | Yes — use Plan agent | +| Implementation tasks (3+ files) | Yes — use general-purpose agent | +| Simple 1-file edits | No — execute directly | +| Quick lookups | No — execute directly | + +### Sub-Agent Prompt Pattern + +When delegating, always tell the sub-agent: + +1. What task it is working on (include task ID) +2. What to produce or change +3. Where to save any output +4. NOT to return large outputs inline — save to files and summarize + +``` +You are working on Task #23: Fix the authentication bug. + +Your job: [specific instructions] + +Output: Save findings to docs/research/auth-bug-investigation.md +Return: A summary of what you changed and any file paths created/modified. +Do NOT return the full file contents inline. +``` + +### Agent Resumption + +When continuing work on a related task, prefer resuming an existing agent by ID rather than starting fresh. This preserves context and reduces redundant exploration. + +## Task List Hygiene + +- Review TaskList at the start of each session +- Archive or cancel stale tasks that are no longer relevant +- Never let completed tasks sit as `in_progress` +- Use TaskGet to read full task details before resuming work + +## When Tasks Are Blocked + +If you cannot complete a task (blocked by dependency, missing info, external factor): + +1. Leave the task `in_progress` (it's still your responsibility) +2. Create a new task for the blocker: "#24: Unblock task #23 — [reason]" +3. Resolve the blocker first, then return to the original task + +## Task Completion Checklist + +Before marking a task `completed`: + +- [ ] The original user request is fully satisfied +- [ ] Changes have been tested and validated +- [ ] Code review feedback has been addressed +- [ ] All changes are committed and pushed to remote +- [ ] No known issues remain + +## Related Skills + +- `task-parallelization` — how to run multiple tasks concurrently for batch operations diff --git a/plugins/task-utils/skills/task-parallelization/SKILL.md b/plugins/task-utils/skills/task-parallelization/SKILL.md new file mode 100644 index 000000000..9d9d391d9 --- /dev/null +++ b/plugins/task-utils/skills/task-parallelization/SKILL.md @@ -0,0 +1,209 @@ +--- +name: task-parallelization +description: Automatically identify opportunities to parallelize Task tool calls when working on batch operations, repetitive changes, or research tasks. Use this skill when asked to make the same change across multiple files/items, perform bulk operations, or conduct research across multiple sources. +--- + +# Task Parallelization Skill + +This skill helps you identify when and how to parallelize Task tool calls for maximum efficiency when working on batch or repetitive operations. + +## When to Use Parallelization + +### High Parallelization Candidates (parallelize aggressively) + +- **Research tasks**: Searching documentation, exploring codebases, gathering information +- **Read-only operations**: Analyzing files, checking status, validating configurations +- **Independent file changes**: Same change across unrelated files (no dependencies) +- **Bulk lookups**: Fetching information from multiple sources +- **Code review**: Reviewing multiple files or PRs independently + +### Medium Parallelization Candidates (parallelize with caution) + +- **File modifications**: Editing multiple files with the same pattern +- **Test execution**: Running tests across different modules +- **Migrations**: Applying similar changes across related components +- **Refactoring**: Renaming or restructuring across the codebase + +### Low Parallelization Candidates (limit parallelization) + +- **Complex logic changes**: Changes requiring careful reasoning +- **Interdependent modifications**: Changes where one depends on another +- **Build/compilation tasks**: CPU-intensive operations +- **Database operations**: Operations that might conflict + +## Parallelization Levels + +### Level 1: Maximum Parallelization (8-10 concurrent tasks) + +**Use when:** + +- Tasks are purely read-only (research, exploration, analysis) +- Tasks are completely independent with no shared resources +- Tasks are simple and unlikely to fail +- Low CPU/memory requirements + +**Examples:** + +- "Research how 10 different libraries handle authentication" +- "Find all usages of a deprecated function across the codebase" +- "Check the status of 10 different services" + +### Level 2: High Parallelization (5-7 concurrent tasks) + +**Use when:** + +- Tasks involve simple, templated changes +- Tasks modify different files with no interdependencies +- Changes follow a clear, repeatable pattern +- Moderate complexity with low failure risk + +**Examples:** + +- "Add the same import statement to 20 files" +- "Update version numbers across all package.json files" +- "Add a standard header comment to all source files" + +### Level 3: Moderate Parallelization (3-4 concurrent tasks) + +**Use when:** + +- Tasks involve some complexity or judgment +- Tasks modify related files but without direct dependencies +- Changes require some context awareness +- Medium risk of conflicts or failures + +**Examples:** + +- "Refactor 10 similar functions to use a new API" +- "Update error handling patterns across modules" +- "Migrate configuration files to a new format" + +### Level 4: Limited Parallelization (2 concurrent tasks) + +**Use when:** + +- Tasks involve complex logic or decision-making +- Tasks might have subtle interdependencies +- Changes require careful reasoning +- Higher risk of conflicts or cascading failures + +**Examples:** + +- "Fix type errors in related components" +- "Update database schemas and their migrations" +- "Refactor tightly coupled modules" + +### Level 5: Sequential (1 task at a time) + +**Use when:** + +- Tasks have explicit dependencies (A must complete before B) +- Tasks modify shared state or resources +- Order of operations matters +- High complexity requiring full attention + +**Examples:** + +- "Build, then test, then deploy" +- "Create base class, then derived classes" +- "Update API, then update all callers" + +## Implementation Pattern + +When you identify a parallelizable request, structure your response like this: + +### Step 1: Identify the Work + +Break down the request into discrete, independent units of work. + +### Step 2: Assess Complexity + +Determine the appropriate parallelization level based on: + +- Task independence +- Resource requirements +- Failure impact +- Complexity of each task + +### Step 3: Batch and Execute + +Group tasks into batches based on the parallelization level and execute. + +### Example Implementation + +**User Request:** "Add JSDoc comments to all 12 exported functions in the utils/ directory" + +**Analysis:** + +- Task type: File modifications (templated changes) +- Independence: High (each function is independent) +- Complexity: Low-Medium (requires reading function, writing appropriate docs) +- Recommended level: Level 2-3 (4-6 concurrent tasks) + +**Execution Plan:** + +``` +Batch 1: Tasks 1-5 (parallel) +Batch 2: Tasks 6-10 (parallel) +Batch 3: Tasks 11-12 (parallel) +``` + +## Critical Rules + +### DO: + +1. **Always assess independence** before parallelizing +2. **Start conservatively** - you can increase parallelization if tasks succeed +3. **Use haiku model** for simple, repetitive tasks to save cost +4. **Group similar tasks** in the same batch for consistency +5. **Provide clear, detailed prompts** to each task (they don't share context) +6. **Include all necessary context** in each task prompt (file paths, patterns, examples) + +### DON'T: + +1. **Don't parallelize dependent tasks** - if B needs A's output, run sequentially +2. **Don't over-parallelize complex tasks** - quality suffers +3. **Don't parallelize tasks that modify shared state** (same file, same config) +4. **Don't assume tasks share context** - each Task agent is independent +5. **Don't forget to aggregate results** - summarize outcomes for the user + +## Task Prompt Template + +When launching parallel tasks, use this template: + +``` +You are performing task {N} of {TOTAL} in a parallel batch operation. + +## Task +{Specific task description} + +## Context +{Any necessary background information} + +## Files/Targets +{Specific file(s) or item(s) to work on} + +## Expected Output +{What the task should produce or change} + +## Constraints +- {Any limitations or rules} +- This is a standalone task - do not assume access to other parallel tasks' results +``` + +## Handling Failures + +When parallel tasks fail: + +1. **Identify failed tasks** from the results +2. **Analyze failure patterns** - are they related? +3. **Retry failed tasks** with potentially lower parallelization +4. **Report to user** which tasks succeeded and which need attention + +## Model Selection for Parallel Tasks + +- **haiku**: Simple, repetitive tasks (renaming, adding imports, simple edits) +- **sonnet**: Moderate complexity (refactoring, documentation, standard changes) +- **opus**: Complex reasoning (architecture decisions, complex debugging) + +Using haiku for simple parallel tasks can significantly reduce cost and latency while maintaining quality for straightforward operations. From e2dcca9f7f53d0936df035a75f46435652f0ab2f Mon Sep 17 00:00:00 2001 From: nsheaps <1282393+nsheaps@users.noreply.github.com> Date: Fri, 24 Apr 2026 15:54:05 +0000 Subject: [PATCH 05/13] chore: `mise run lint` --- plugins/task-utils/.claude-plugin/plugin.json | 11 ++++++++++- plugins/task-utils/README.md | 12 ++++++------ .../task-utils/skills/task-management/SKILL.md | 15 +++++++++------ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/plugins/task-utils/.claude-plugin/plugin.json b/plugins/task-utils/.claude-plugin/plugin.json index f5f88a64b..b2cc8a187 100644 --- a/plugins/task-utils/.claude-plugin/plugin.json +++ b/plugins/task-utils/.claude-plugin/plugin.json @@ -7,5 +7,14 @@ "email": "nsheaps@gmail.com", "url": "https://github.com/nsheaps" }, - "keywords": ["tasks", "commit", "workflow", "ephemeral", "parallelization", "sync", "agent-teams", "productivity"] + "keywords": [ + "tasks", + "commit", + "workflow", + "ephemeral", + "parallelization", + "sync", + "agent-teams", + "productivity" + ] } diff --git a/plugins/task-utils/README.md b/plugins/task-utils/README.md index ac929127c..d31e44dc5 100644 --- a/plugins/task-utils/README.md +++ b/plugins/task-utils/README.md @@ -25,19 +25,19 @@ Add `task-utils` to your `enabledPlugins` in `settings.json`. Remove `todo-plus- task-utils: providers: filesystem: - enabled: true # writes task state to $CLAUDE_PROJECT_DIR/.claude/tasks/ + enabled: true # writes task state to $CLAUDE_PROJECT_DIR/.claude/tasks/ githubIssues: - enabled: false # set true to enable GitHub issue sync - repo: "owner/repo" # required if enabled: true + enabled: false # set true to enable GitHub issue sync + repo: "owner/repo" # required if enabled: true labels: - "agent-task" closeOnComplete: true commitCheck: - enabled: true # block TaskCompleted if uncommitted changes exist + enabled: true # block TaskCompleted if uncommitted changes exist stopGuard: - enabled: true # warn on Stop if in_progress tasks remain + enabled: true # warn on Stop if in_progress tasks remain activeTaskGuard: - enabled: true # warn on tool use if no active task + enabled: true # warn on tool use if no active task ``` ## File Structure diff --git a/plugins/task-utils/skills/task-management/SKILL.md b/plugins/task-utils/skills/task-management/SKILL.md index a7502c1de..b5d8a019b 100644 --- a/plugins/task-utils/skills/task-management/SKILL.md +++ b/plugins/task-utils/skills/task-management/SKILL.md @@ -33,11 +33,13 @@ User: "Fix the bug in the login flow" Tasks MUST always include the task ID in the subject and activeForm. **GOOD:** + ``` #23: Fix the bug in the login flow ``` **BAD:** + ``` Fix the bug in the login flow ``` @@ -48,6 +50,7 @@ Fix the bug in the login flow - If a task relates to a PR, include the PR number if the user is referencing change sets by PR number. **Examples:** + ``` #23: [GH-456] Fix the authentication bug #24: [PR #789] Review and address feedback @@ -93,13 +96,13 @@ When working on a task, prefer delegating to an appropriate sub-agent rather tha ### When to Delegate -| Task Type | Delegate? | -|-----------|-----------| +| Task Type | Delegate? | +| ------------------------------------ | ---------------------------------- | | Codebase investigation / exploration | Yes — use Explore agent with haiku | -| Architectural decisions | Yes — use Plan agent | -| Implementation tasks (3+ files) | Yes — use general-purpose agent | -| Simple 1-file edits | No — execute directly | -| Quick lookups | No — execute directly | +| Architectural decisions | Yes — use Plan agent | +| Implementation tasks (3+ files) | Yes — use general-purpose agent | +| Simple 1-file edits | No — execute directly | +| Quick lookups | No — execute directly | ### Sub-Agent Prompt Pattern From e0ed50dd4e052588c79f778053aa64bca99a9f50 Mon Sep 17 00:00:00 2001 From: "automation-nsheaps[bot]" <251779498+automation-nsheaps[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 15:54:51 +0000 Subject: [PATCH 06/13] chore: auto-bump plugin versions and update marketplace --- .claude-plugin/marketplace.json | 45 ++++++++------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index d53695515..734e5ed38 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -755,23 +755,24 @@ ] }, { - "name": "task-parallelization", - "description": "Intelligent skill that helps Claude parallelize Task tool calls when working on repetitive or batch operations, optimizing throughput based on task complexity", - "version": "0.2.25", + "name": "task-utils", + "description": "Unified task management plugin — commit-on-complete, session awareness, active-task guard, stop guard, and provider-based task sync. Consolidates todo-plus-plus, todo-sync, and task-parallelization.", + "version": "1.0.0", "author": { "name": "Nathan Heaps" }, - "source": "./plugins/task-parallelization", + "source": "./plugins/task-utils", "category": "utility", "tags": ["utility", "skill"], "keywords": [ + "tasks", + "commit", + "workflow", + "ephemeral", "parallelization", - "task", - "agent", - "batch", - "performance", - "optimization", - "concurrent" + "sync", + "agent-teams", + "productivity" ] }, { @@ -798,30 +799,6 @@ "tags": ["utility", "command", "skill"], "keywords": ["tmux", "subagent", "parallel", "iterm", "terminal", "isolation", "delegation"] }, - { - "name": "todo-plus-plus", - "description": "Enforces commit-on-complete for tasks and reminds about ephemeral session awareness", - "version": "0.1.5", - "author": { - "name": "Nathan Heaps" - }, - "source": "./plugins/todo-plus-plus", - "category": "utility", - "tags": ["utility", "skill"], - "keywords": ["tasks", "commit", "workflow", "ephemeral", "agent-teams"] - }, - { - "name": "todo-sync", - "description": "Automatically syncs todos and plans from ~/.claude/ to the current project's .claude/ directory", - "version": "0.2.4", - "author": { - "name": "Nathan Heaps" - }, - "source": "./plugins/todo-sync", - "category": "utility", - "tags": ["utility", "skill"], - "keywords": ["todos", "plans", "sync", "workflow", "productivity"] - }, { "name": "web-auto-approve", "description": "Auto-approve Edit, Write, and Bash permission requests in Claude Code web sessions to suppress interactive permission prompts", From 74c6cb5a1126726f2e36678964941f8321f0b059 Mon Sep 17 00:00:00 2001 From: Nathan Heaps Date: Fri, 24 Apr 2026 16:43:08 -0400 Subject: [PATCH 07/13] =?UTF-8?q?fix(task-utils):=20address=20review=20fin?= =?UTF-8?q?dings=20=E2=80=94=20version,=20stubs,=20hooks,=20spec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/task-utils/.claude-plugin/plugin.json | 2 +- plugins/task-utils/README.md | 6 +-- plugins/task-utils/docs/spec.md | 4 +- plugins/task-utils/hooks/hooks.json | 13 +---- .../hooks/scripts/sync-task-create.sh | 2 + plugins/task-utils/lib/log.sh | 52 +------------------ 6 files changed, 10 insertions(+), 69 deletions(-) mode change 100755 => 120000 plugins/task-utils/lib/log.sh diff --git a/plugins/task-utils/.claude-plugin/plugin.json b/plugins/task-utils/.claude-plugin/plugin.json index b2cc8a187..9df2f4665 100644 --- a/plugins/task-utils/.claude-plugin/plugin.json +++ b/plugins/task-utils/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "task-utils", - "version": "1.0.0", + "version": "0.1.0", "description": "Unified task management plugin — commit-on-complete, session awareness, active-task guard, stop guard, and provider-based task sync. Consolidates todo-plus-plus, todo-sync, and task-parallelization.", "author": { "name": "Nathan Heaps", diff --git a/plugins/task-utils/README.md b/plugins/task-utils/README.md index d31e44dc5..358a9e19f 100644 --- a/plugins/task-utils/README.md +++ b/plugins/task-utils/README.md @@ -8,9 +8,9 @@ See the full spec at [`docs/spec.md`](docs/spec.md). - **Commit-on-Complete** (`TaskCompleted` hook): Blocks task completion if there are uncommitted or unpushed changes - **Session Awareness** (`SessionStart` hook): Reminds agents that Tasks are session-scoped and not persistent; to always commit before completing tasks -- **Active-Task Guard** (`PreToolUse` hook, advisory): Warns when a tool is used with no active task -- **Stop Guard** (`Stop` hook, advisory): Warns when a session ends with in-progress tasks -- **Provider-based Task Sync** (`PostToolUse:TaskCreate/TaskUpdate`): Syncs task state to configured backends (Filesystem, GitHub Issues) +- **Active-Task Guard** (`PreToolUse` hook, advisory): Warns when a tool is used with no active task (scaffold — no-op in this release) +- **Stop Guard** (`Stop` hook, advisory): Warns when a session ends with in-progress tasks (scaffold — no-op in this release) +- **Provider-based Task Sync** (`PostToolUse:TaskCreate/TaskUpdate`): Syncs task state to configured backends (Filesystem, GitHub Issues) (scaffold — no-op in this release) - **Task Parallelization skill**: Migrated from `task-parallelization` — guidance on running parallel sub-agents - **Task Management skill**: New skill covering the full task lifecycle, naming conventions, and delegation patterns diff --git a/plugins/task-utils/docs/spec.md b/plugins/task-utils/docs/spec.md index 02c24e700..ab4a5776e 100644 --- a/plugins/task-utils/docs/spec.md +++ b/plugins/task-utils/docs/spec.md @@ -22,7 +22,7 @@ These overlap in concern, share no config namespace, and require three separate 2. Provider-based task sync — pluggable backends (filesystem, GitHub issues, extensible to others) 3. Complete task lifecycle management (session restore, commit guard, stop guard) 4. Parallelization skill migrated in -5. Clean migration path with no behavior regression +5. Clean migration path with no behavior regression for todo-plus-plus / task-parallelization users ## Non-Goals @@ -116,7 +116,7 @@ task-utils: **Source**: todo-plus-plus `Stop` hook — **migrated from agent repo to plugin** **Behavior**: When the session is about to end, warn if any tasks remain `in_progress`. Reminds the agent to complete or hand off work. **Advisory**: Yes — warns, does not block -**Status**: Migrated in but **commented out initially** pending validation in plugin context +**Status**: Registered as a **no-op stub, full logic deferred to v1.1** **Configurable**: `stopGuard.enabled` (default: `true`) ### 5. `PostToolUse:TaskCreate` — Sync New Task to Providers diff --git a/plugins/task-utils/hooks/hooks.json b/plugins/task-utils/hooks/hooks.json index 8c1fb3e3b..efd78152e 100644 --- a/plugins/task-utils/hooks/hooks.json +++ b/plugins/task-utils/hooks/hooks.json @@ -25,18 +25,7 @@ ] } ], - "PreToolUse": [ - { - "matcher": "*", - "hooks": [ - { - "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/active-task-guard.sh", - "timeout": 5 - } - ] - } - ], + "PreToolUse": [], "Stop": [ { "matcher": "*", diff --git a/plugins/task-utils/hooks/scripts/sync-task-create.sh b/plugins/task-utils/hooks/scripts/sync-task-create.sh index 9e2969b55..4e339265e 100755 --- a/plugins/task-utils/hooks/scripts/sync-task-create.sh +++ b/plugins/task-utils/hooks/scripts/sync-task-create.sh @@ -19,6 +19,8 @@ if ! command -v jq &>/dev/null; then exit 0 fi +# NOTE: `.tool_result` may need to be `.tool_response` when providers are implemented — +# verify the actual hook payload schema at that time. task_id=$(echo "$input" | jq -r '.tool_result.taskId // empty' 2>/dev/null || echo "") task_title=$(echo "$input" | jq -r '.tool_result.subject // empty' 2>/dev/null || echo "") diff --git a/plugins/task-utils/lib/log.sh b/plugins/task-utils/lib/log.sh deleted file mode 100755 index 6af67cc80..000000000 --- a/plugins/task-utils/lib/log.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -# log.sh — Lightweight general-purpose logging for any bash script -# -# Provides consistent stderr logging with a configurable prefix. -# Works in any context: hooks, session-start scripts, utility scripts, etc. -# -# Usage: -# LOG_PREFIX="my-script" # Optional: defaults to PLUGIN_NAME or "script" -# source "/path/to/log.sh" -# -# log_info "Installing tool v1.2.3" # my-script: Installing tool v1.2.3 -# log_warn "Fallback to default" # my-script: [warn] Fallback to default -# log_error "File not found" # my-script: [error] File not found -# log_step "download" "Downloading..." # my-script: [download] Downloading... -# -# All output goes to stderr so it never interferes with stdout (hook responses, etc). - -# Guard against double-sourcing -if [ "${_LOG_SH_LOADED:-}" = "true" ]; then - return 0 2>/dev/null || true -fi -_LOG_SH_LOADED="true" - -# Resolve prefix: explicit LOG_PREFIX > PLUGIN_NAME > "script" -_LOG_PREFIX="${LOG_PREFIX:-${PLUGIN_NAME:-script}}" - -# --- Logging functions --- - -# Log an informational message to stderr. -# Args: $1=message -log_info() { - echo "${_LOG_PREFIX}: $1" >&2 -} - -# Log a warning message to stderr. -# Args: $1=message -log_warn() { - echo "${_LOG_PREFIX}: [warn] $1" >&2 -} - -# Log an error message to stderr. -# Args: $1=message -log_error() { - echo "${_LOG_PREFIX}: [error] $1" >&2 -} - -# Log a named step to stderr. -# Args: $1=step_id $2=message -log_step() { - echo "${_LOG_PREFIX}: [$1] $2" >&2 -} diff --git a/plugins/task-utils/lib/log.sh b/plugins/task-utils/lib/log.sh new file mode 120000 index 000000000..3d035ca54 --- /dev/null +++ b/plugins/task-utils/lib/log.sh @@ -0,0 +1 @@ +../../../shared/lib/log.sh \ No newline at end of file From 3c79b5147e6b30506b1e6087436e672edeb88e67 Mon Sep 17 00:00:00 2001 From: nsheaps <1282393+nsheaps@users.noreply.github.com> Date: Fri, 24 Apr 2026 20:44:09 +0000 Subject: [PATCH 08/13] chore: auto-bump plugin versions and update marketplace --- .claude-plugin/marketplace.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 734e5ed38..03179f081 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -757,7 +757,7 @@ { "name": "task-utils", "description": "Unified task management plugin — commit-on-complete, session awareness, active-task guard, stop guard, and provider-based task sync. Consolidates todo-plus-plus, todo-sync, and task-parallelization.", - "version": "1.0.0", + "version": "0.1.0", "author": { "name": "Nathan Heaps" }, From e0c12e64fac5c4f3226a385e6f05485c6486d20a Mon Sep 17 00:00:00 2001 From: Nathan Heaps Date: Fri, 24 Apr 2026 16:48:51 -0400 Subject: [PATCH 09/13] fix(task-utils): remove todo-sync from enabledPlugins after deletion --- .claude/settings.json | 1 - 1 file changed, 1 deletion(-) diff --git a/.claude/settings.json b/.claude/settings.json index e22892c2f..bc11697d9 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -130,7 +130,6 @@ "mise@ai-mktpl": true, "scm-utils@ai-mktpl": true, "sequential-thinking@ai-mktpl": false, - "todo-sync@ai-mktpl": false, "web-auto-approve@ai-mktpl": true }, "extraKnownMarketplaces": { From d9035fdb03a912aea7e84261dd5f807b3540ad3b Mon Sep 17 00:00:00 2001 From: Nathan Heaps Date: Sun, 26 Apr 2026 09:49:38 -0400 Subject: [PATCH 10/13] fix(task-utils): wire PreToolUse hook + add .release-it.js - Wire active-task-guard.sh into PreToolUse hook array in hooks.json - Add .release-it.js following existing plugin pattern (common-sense) - Update sync-task-create.sh comment to mark payload schema verification as a follow-up task instead of an inline NOTE --- plugins/task-utils/.release-it.js | 9 +++++++++ plugins/task-utils/hooks/hooks.json | 13 ++++++++++++- .../task-utils/hooks/scripts/sync-task-create.sh | 4 ++-- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 plugins/task-utils/.release-it.js diff --git a/plugins/task-utils/.release-it.js b/plugins/task-utils/.release-it.js new file mode 100644 index 000000000..539d53629 --- /dev/null +++ b/plugins/task-utils/.release-it.js @@ -0,0 +1,9 @@ +module.exports = { + extends: "../../.release-it.base.json", + plugins: { + "@release-it/bumper": { + in: ".claude-plugin/plugin.json", + out: ".claude-plugin/plugin.json", + }, + }, +}; diff --git a/plugins/task-utils/hooks/hooks.json b/plugins/task-utils/hooks/hooks.json index efd78152e..2621214ab 100644 --- a/plugins/task-utils/hooks/hooks.json +++ b/plugins/task-utils/hooks/hooks.json @@ -25,7 +25,18 @@ ] } ], - "PreToolUse": [], + "PreToolUse": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/active-task-guard.sh", + "timeout": 10 + } + ] + } + ], "Stop": [ { "matcher": "*", diff --git a/plugins/task-utils/hooks/scripts/sync-task-create.sh b/plugins/task-utils/hooks/scripts/sync-task-create.sh index 4e339265e..d17917016 100755 --- a/plugins/task-utils/hooks/scripts/sync-task-create.sh +++ b/plugins/task-utils/hooks/scripts/sync-task-create.sh @@ -19,8 +19,8 @@ if ! command -v jq &>/dev/null; then exit 0 fi -# NOTE: `.tool_result` may need to be `.tool_response` when providers are implemented — -# verify the actual hook payload schema at that time. +# TODO: verify `.tool_result` vs `.tool_response` in the actual hook payload schema +# when providers are implemented (follow-up task). task_id=$(echo "$input" | jq -r '.tool_result.taskId // empty' 2>/dev/null || echo "") task_title=$(echo "$input" | jq -r '.tool_result.subject // empty' 2>/dev/null || echo "") From 25866bd129985f858f35e87ab8552d967297a5a1 Mon Sep 17 00:00:00 2001 From: nsheaps <1282393+nsheaps@users.noreply.github.com> Date: Sun, 26 Apr 2026 13:50:46 +0000 Subject: [PATCH 11/13] chore: auto-bump plugin versions and update marketplace --- .claude-plugin/marketplace.json | 2 +- plugins/github-app/.claude-plugin/plugin.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 03179f081..588680411 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -375,7 +375,7 @@ { "name": "github-app", "description": "Automatic GitHub App token lifecycle for Claude Code sessions. Generates installation tokens on session start, monitors expiry via PreToolUse hook, and refreshes transparently before commands that need authentication.", - "version": "0.3.1", + "version": "0.3.2", "author": { "name": "Nathan Heaps" }, diff --git a/plugins/github-app/.claude-plugin/plugin.json b/plugins/github-app/.claude-plugin/plugin.json index 2e23c0e64..d247207e0 100644 --- a/plugins/github-app/.claude-plugin/plugin.json +++ b/plugins/github-app/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-app", - "version": "0.3.1", + "version": "0.3.2", "description": "Automatic GitHub App token lifecycle for Claude Code sessions. Generates installation tokens on session start, monitors expiry via PreToolUse hook, and refreshes transparently before commands that need authentication.", "author": { "name": "Nathan Heaps", From f3488563ceb0618adad975814c9e381b8832472e Mon Sep 17 00:00:00 2001 From: Nathan Heaps Date: Sun, 26 Apr 2026 10:17:35 -0400 Subject: [PATCH 12/13] =?UTF-8?q?fix(task-utils):=20address=20review=20rou?= =?UTF-8?q?nd=202=20=E2=80=94=20docs=20accuracy,=20hook=20scope,=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove self-contradicting migration note telling users to keep todo-sync installed (this PR deletes it) - Add "not yet implemented" callouts for config knobs in README and spec (no plugin_get_config calls exist in v0.1.0) - Mark 4 stub features as "Stub (no-op, v1.1)" in MVP scope table - Remove PreToolUse no-op from hooks.json (per-call overhead for zero benefit); mark deferred in spec - Fix session-start.sh comment claiming "restores in-progress tasks" when it only emits a static awareness message - Update spec frontmatter status from draft to in-progress --- plugins/task-utils/README.md | 8 ++-- plugins/task-utils/docs/spec.md | 37 ++++++++++--------- plugins/task-utils/hooks/hooks.json | 12 ------ .../task-utils/hooks/scripts/session-start.sh | 2 +- 4 files changed, 25 insertions(+), 34 deletions(-) diff --git a/plugins/task-utils/README.md b/plugins/task-utils/README.md index 358a9e19f..423bb5e06 100644 --- a/plugins/task-utils/README.md +++ b/plugins/task-utils/README.md @@ -20,8 +20,10 @@ Add `task-utils` to your `enabledPlugins` in `settings.json`. Remove `todo-plus- ## Configuration +> **Not yet implemented.** The configuration knobs below are planned for v1.1. In v0.1.0, all hooks use hardcoded defaults — `commitCheck` is always on, stub hooks always exit 0, and no provider sync runs. No `plugins.settings.yaml` is read. + ```yaml -# plugins.settings.yaml +# plugins.settings.yaml (planned — not read in v0.1.0) task-utils: providers: filesystem: @@ -52,7 +54,7 @@ task-utils/ │ ├── hooks.json │ └── scripts/ │ ├── check-uncommitted.sh # TaskCompleted — commit guard -│ ├── session-start.sh # SessionStart — awareness + restore +│ ├── session-start.sh # SessionStart — awareness message │ ├── active-task-guard.sh # PreToolUse — active task advisory │ ├── stop-guard.sh # Stop — in-progress task advisory │ ├── sync-task-create.sh # PostToolUse:TaskCreate — provider sync @@ -77,8 +79,6 @@ If you used `todo-plus-plus`, `todo-sync`, and/or `task-parallelization`: No data migration required — task state lives in Claude Code's native task store. -**Note**: TodoWrite gitignore initialization (from todo-sync's `SessionStart`) is deferred to v1.1. If you relied on this, keep `todo-sync` installed until then. - ## License MIT diff --git a/plugins/task-utils/docs/spec.md b/plugins/task-utils/docs/spec.md index ab4a5776e..34bb41759 100644 --- a/plugins/task-utils/docs/spec.md +++ b/plugins/task-utils/docs/spec.md @@ -1,6 +1,6 @@ --- name: task-utils -status: draft +status: in-progress description: Unified task management plugin consolidating todo-plus-plus, todo-sync, and task-parallelization into a single cohesive plugin with provider-based task sync. --- @@ -100,7 +100,7 @@ task-utils: **Behavior**: - Injects task-awareness context into the session (reminder to use TaskCreate on every action request) -- Restores any `in_progress` tasks from the previous session, prompting the agent to resume or triage them +- Task restore is **deferred to v1.1** — currently emits a static awareness message only **Advisory**: No — always runs @@ -109,7 +109,8 @@ task-utils: **Source**: New (fills gap in todo-plus-plus) **Behavior**: When a non-conversational tool is invoked and no task is `in_progress`, emit an advisory warning reminding the agent to create/activate a task. **Advisory**: Yes — warns, does not block -**Configurable**: `activeTaskGuard.enabled` (default: `true`) +**Configurable**: `activeTaskGuard.enabled` (default: `true`) +**Status**: **Deferred to v1.1** — script exists but is not wired in `hooks.json`. Running a no-op on every tool call adds per-call overhead for zero benefit; will be wired when guard logic is implemented. ### 4. `Stop` (advisory) — In-Progress Task Warning @@ -157,7 +158,9 @@ New skill covering: ## Configuration -Full configuration reference via `plugins.settings.yaml` in the consuming agent's repo: +> **Not yet implemented.** The configuration below is the planned interface for v1.1. In v0.1.0, no `plugin_get_config` calls exist and no `plugins.settings.yaml` is read — all hooks use hardcoded defaults. + +Full configuration reference via `plugins.settings.yaml` in the consuming agent's repo (planned): ```yaml task-utils: @@ -189,22 +192,22 @@ For agents currently using the three separate plugins: No data migration required — task state lives in Claude Code's native store. -**Note**: TodoWrite gitignore initialization (from todo-sync's `SessionStart`) is deferred post-MVP. If you relied on this, keep `todo-sync` installed until v1.1. +**Note**: TodoWrite gitignore initialization (from todo-sync's `SessionStart`) is deferred post-MVP. ## MVP Scope (v1) -| Feature | Status | -| --------------------------------------------------------- | ------------ | -| TaskCompleted commit check | In scope | -| SessionStart restore + awareness | In scope | -| PreToolUse active-task guard | In scope | -| Stop guard (migrated, commented out initially) | In scope | -| FilesystemProvider | In scope | -| GitHubIssuesProvider (find-or-create via haiku sub-agent) | In scope | -| task-parallelization skill (migrated) | In scope | -| task-management skill (new) | In scope | -| PostToolUse:TodoWrite sync | **Deferred** | -| TodoWrite gitignore init | **Deferred** | +| Feature | Status | +| --------------------------------------------------------- | -------------------------- | +| TaskCompleted commit check | **Implemented** | +| SessionStart awareness message | **Implemented** | +| PreToolUse active-task guard | **Stub** (no-op, v1.1) | +| Stop guard | **Stub** (no-op, v1.1) | +| FilesystemProvider | **Stub** (no-op, v1.1) | +| GitHubIssuesProvider (find-or-create via haiku sub-agent) | **Stub** (no-op, v1.1) | +| task-parallelization skill (migrated) | **Implemented** | +| task-management skill (new) | **Implemented** | +| PostToolUse:TodoWrite sync | **Deferred** | +| TodoWrite gitignore init | **Deferred** | ## Deferred Items (post-MVP) diff --git a/plugins/task-utils/hooks/hooks.json b/plugins/task-utils/hooks/hooks.json index 2621214ab..16fe3ac0b 100644 --- a/plugins/task-utils/hooks/hooks.json +++ b/plugins/task-utils/hooks/hooks.json @@ -25,18 +25,6 @@ ] } ], - "PreToolUse": [ - { - "matcher": "*", - "hooks": [ - { - "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/active-task-guard.sh", - "timeout": 10 - } - ] - } - ], "Stop": [ { "matcher": "*", diff --git a/plugins/task-utils/hooks/scripts/session-start.sh b/plugins/task-utils/hooks/scripts/session-start.sh index ac8398cdd..76b15696b 100755 --- a/plugins/task-utils/hooks/scripts/session-start.sh +++ b/plugins/task-utils/hooks/scripts/session-start.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# session-start.sh — Injects task-awareness context and restores in-progress tasks +# session-start.sh — Injects task-awareness context into the session # Triggered by SessionStart hook # # Source: migrated and extended from todo-plus-plus v0.1.5 SessionStart hook From 6a313712bd98faecd38e187ddd08e0dc9e9ae34f Mon Sep 17 00:00:00 2001 From: nsheaps <1282393+nsheaps@users.noreply.github.com> Date: Sun, 26 Apr 2026 14:18:23 +0000 Subject: [PATCH 13/13] chore: `mise run lint` --- .../renovate/skills/renovate-setup/SKILL.md | 16 +++++++++---- plugins/task-utils/docs/spec.md | 24 +++++++++---------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/plugins/renovate/skills/renovate-setup/SKILL.md b/plugins/renovate/skills/renovate-setup/SKILL.md index 6a5fb0730..0ddf8fee3 100644 --- a/plugins/renovate/skills/renovate-setup/SKILL.md +++ b/plugins/renovate/skills/renovate-setup/SKILL.md @@ -44,10 +44,10 @@ The correct file name changed from `default.json` to `default.json5`: ```json5 // renovate.json5 { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>nsheaps/renovate-config" // uses default.json5 automatically - ] + $schema: "https://docs.renovatebot.com/renovate-schema.json", + extends: [ + "github>nsheaps/renovate-config", // uses default.json5 automatically + ], } ``` @@ -59,33 +59,41 @@ settings, schedule, package rules, etc.). When a Renovate PR is stuck and not auto-merging: 1. **Repo setting enabled?** + ```bash gh api repos/nsheaps/ --jq '.allow_auto_merge' # should return: true ``` 2. **PR has auto-merge queued?** + ```bash gh pr view --repo nsheaps/ --json autoMergeRequest # autoMergeRequest should be non-null ``` + If null, enable it: + ```bash gh pr merge --repo nsheaps/ --auto --squash ``` 3. **Branch protection / rulesets blocking?** + ```bash gh api repos/nsheaps//rules/branches/main ``` + Common blockers: - `pull_request` rule requiring `required_approving_review_count: 1` → approve the PR - Required status checks that aren't running → check CI config 4. **Required status checks failing?** + ```bash gh pr view --repo nsheaps/ --json statusCheckRollup ``` + Empty `statusCheckRollup` + BLOCKED usually means a required check is configured but no CI run has happened (missing workflow trigger or CI never ran). diff --git a/plugins/task-utils/docs/spec.md b/plugins/task-utils/docs/spec.md index 34bb41759..064d40d66 100644 --- a/plugins/task-utils/docs/spec.md +++ b/plugins/task-utils/docs/spec.md @@ -196,18 +196,18 @@ No data migration required — task state lives in Claude Code's native store. ## MVP Scope (v1) -| Feature | Status | -| --------------------------------------------------------- | -------------------------- | -| TaskCompleted commit check | **Implemented** | -| SessionStart awareness message | **Implemented** | -| PreToolUse active-task guard | **Stub** (no-op, v1.1) | -| Stop guard | **Stub** (no-op, v1.1) | -| FilesystemProvider | **Stub** (no-op, v1.1) | -| GitHubIssuesProvider (find-or-create via haiku sub-agent) | **Stub** (no-op, v1.1) | -| task-parallelization skill (migrated) | **Implemented** | -| task-management skill (new) | **Implemented** | -| PostToolUse:TodoWrite sync | **Deferred** | -| TodoWrite gitignore init | **Deferred** | +| Feature | Status | +| --------------------------------------------------------- | ---------------------- | +| TaskCompleted commit check | **Implemented** | +| SessionStart awareness message | **Implemented** | +| PreToolUse active-task guard | **Stub** (no-op, v1.1) | +| Stop guard | **Stub** (no-op, v1.1) | +| FilesystemProvider | **Stub** (no-op, v1.1) | +| GitHubIssuesProvider (find-or-create via haiku sub-agent) | **Stub** (no-op, v1.1) | +| task-parallelization skill (migrated) | **Implemented** | +| task-management skill (new) | **Implemented** | +| PostToolUse:TodoWrite sync | **Deferred** | +| TodoWrite gitignore init | **Deferred** | ## Deferred Items (post-MVP)