diff --git a/.claude/commands/add_platform.md b/.claude/commands/add_platform.md
deleted file mode 100644
index e23ea1f2..00000000
--- a/.claude/commands/add_platform.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-description: Add a new AI platform to DeepWork with adapter, templates, and tests
----
-
-# add_platform
-
-You are executing the **add_platform** job. Add a new AI platform to DeepWork with adapter, templates, and tests
-
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
-
-
-## Available Steps
-
-This job has 4 step(s):
-
-### research
-**Research Platform Documentation**: Capture CLI configuration and hooks system documentation for the new platform
-- Command: `uw.add_platform.research`
-### add_capabilities
-**Add Hook Capabilities**: Update job schema and adapters with any new hook events the platform supports
-- Command: `uw.add_platform.add_capabilities`
-- Requires: research
-### implement
-**Implement Platform Support**: Add platform adapter, templates, tests with 100% coverage, and README documentation
-- Command: `uw.add_platform.implement`
-- Requires: research, add_capabilities
-### verify
-**Verify Installation**: Set up platform directories and verify deepwork install works correctly
-- Command: `uw.add_platform.verify`
-- Requires: implement
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and run through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/add_platform`
-
-2. **Identify the starting step** based on intent:
- - research: Capture CLI configuration and hooks system documentation for the new platform
- - add_capabilities: Update job schema and adapters with any new hook events the platform supports
- - implement: Add platform adapter, templates, tests with 100% coverage, and README documentation
- - verify: Set up platform directories and verify deepwork install works correctly
-
-3. **Run the workflow** starting from the identified step:
- - Invoke the starting step using the Skill tool
- - When that step completes, **automatically continue** to the next step in the workflow
- - Continue until the workflow is complete or the user intervenes
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Use AskUserQuestion to let them choose
-
-**Critical**:
-- You MUST invoke each step using the Skill tool. Do not copy/paste step instructions.
-- After each step completes, check if there's a next step and invoke it automatically.
-- The workflow continues until all dependent steps are complete.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
\ No newline at end of file
diff --git a/.claude/commands/deepwork_jobs.md b/.claude/commands/deepwork_jobs.md
deleted file mode 100644
index 2d9b911c..00000000
--- a/.claude/commands/deepwork_jobs.md
+++ /dev/null
@@ -1,63 +0,0 @@
----
-description: DeepWork job management commands
----
-
-# deepwork_jobs
-
-You are executing the **deepwork_jobs** job. DeepWork job management commands
-
-Core commands for managing DeepWork jobs. These commands help you define new multi-step
-workflows and learn from running them.
-
-The `define` command guides you through an interactive process to create a new job by
-asking structured questions about your workflow, understanding each step's inputs and outputs,
-and generating all necessary files.
-
-The `learn` command reflects on conversations where DeepWork jobs were run, identifies
-confusion or inefficiencies, and improves job instructions. It also captures bespoke
-learnings specific to the current run into AGENTS.md files in the working folder.
-
-
-## Available Steps
-
-This job has 3 step(s):
-
-### define
-**Define Job Specification**: Create the job.yml specification file by understanding workflow requirements
-- Command: `uw.deepwork_jobs.define`
-### implement
-**Implement Job Steps**: Generate instruction files for each step based on the job.yml specification
-- Command: `uw.deepwork_jobs.implement`
-- Requires: define
-### learn
-**Learn from Job Execution**: Reflect on conversation to improve job instructions and capture learnings
-- Command: `deepwork_jobs.learn`
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and run through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/deepwork_jobs`
-
-2. **Identify the starting step** based on intent:
- - define: Create the job.yml specification file by understanding workflow requirements
- - implement: Generate instruction files for each step based on the job.yml specification
- - learn: Reflect on conversation to improve job instructions and capture learnings
-
-3. **Run the workflow** starting from the identified step:
- - Invoke the starting step using the Skill tool
- - When that step completes, **automatically continue** to the next step in the workflow
- - Continue until the workflow is complete or the user intervenes
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Use AskUserQuestion to let them choose
-
-**Critical**:
-- You MUST invoke each step using the Skill tool. Do not copy/paste step instructions.
-- After each step completes, check if there's a next step and invoke it automatically.
-- The workflow continues until all dependent steps are complete.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
\ No newline at end of file
diff --git a/.claude/commands/deepwork_rules.md b/.claude/commands/deepwork_rules.md
deleted file mode 100644
index 7535c6e7..00000000
--- a/.claude/commands/deepwork_rules.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-description: Rules enforcement for AI agent sessions
----
-
-# deepwork_rules
-
-You are executing the **deepwork_rules** job. Rules enforcement for AI agent sessions
-
-Manages rules that automatically trigger when certain files change during an AI agent session.
-Rules help ensure that code changes follow team guidelines, documentation is updated,
-and architectural decisions are respected.
-
-Rules are stored as individual markdown files with YAML frontmatter in the `.deepwork/rules/`
-directory. Each rule file specifies:
-- Detection mode: trigger/safety, set (bidirectional), or pair (directional)
-- Patterns: Glob patterns for matching files, with optional variable capture
-- Instructions: Markdown content describing what the agent should do
-
-Example use cases:
-- Update installation docs when configuration files change
-- Require security review when authentication code is modified
-- Ensure API documentation stays in sync with API code
-- Enforce source/test file pairing
-
-
-## Available Steps
-
-This job has 1 step(s):
-
-### define
-**Define Rule**: Create a new rule file in .deepwork/rules/
-- Command: `uw.deepwork_rules.define`
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and run through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/deepwork_rules`
-
-2. **Identify the starting step** based on intent:
- - define: Create a new rule file in .deepwork/rules/
-
-3. **Run the workflow** starting from the identified step:
- - Invoke the starting step using the Skill tool
- - When that step completes, **automatically continue** to the next step in the workflow
- - Continue until the workflow is complete or the user intervenes
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Use AskUserQuestion to let them choose
-
-**Critical**:
-- You MUST invoke each step using the Skill tool. Do not copy/paste step instructions.
-- After each step completes, check if there's a next step and invoke it automatically.
-- The workflow continues until all dependent steps are complete.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_rules/job.yml`
\ No newline at end of file
diff --git a/.claude/commands/update.md b/.claude/commands/update.md
deleted file mode 100644
index 3c7b2705..00000000
--- a/.claude/commands/update.md
+++ /dev/null
@@ -1,57 +0,0 @@
----
-description: Update standard jobs in src/ and sync to installed locations
----
-
-# update
-
-You are executing the **update** job. Update standard jobs in src/ and sync to installed locations
-
-A workflow for maintaining standard jobs bundled with DeepWork. Standard jobs
-(like `deepwork_jobs` and `deepwork_rules`) are source-controlled in
-`src/deepwork/standard_jobs/` and must be edited there—never in `.deepwork/jobs/`
-or `.claude/commands/` directly.
-
-This job guides you through:
-1. Identifying which standard job(s) to update from conversation context
-2. Making changes in the correct source location (`src/deepwork/standard_jobs/[job_name]/`)
-3. Running `deepwork install` to propagate changes to `.deepwork/` and command directories
-4. Verifying the sync completed successfully
-
-Use this job whenever you need to modify job.yml files, step instructions, or hooks
-for any standard job in the DeepWork repository.
-
-
-## Available Steps
-
-This job has 1 step(s):
-
-### job
-**Update Standard Job**: Edit standard job source files and sync to installed locations
-- Command: `uw.update.job`
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and run through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/update`
-
-2. **Identify the starting step** based on intent:
- - job: Edit standard job source files and sync to installed locations
-
-3. **Run the workflow** starting from the identified step:
- - Invoke the starting step using the Skill tool
- - When that step completes, **automatically continue** to the next step in the workflow
- - Continue until the workflow is complete or the user intervenes
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Use AskUserQuestion to let them choose
-
-**Critical**:
-- You MUST invoke each step using the Skill tool. Do not copy/paste step instructions.
-- After each step completes, check if there's a next step and invoke it automatically.
-- The workflow continues until all dependent steps are complete.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/update/job.yml`
\ No newline at end of file
diff --git a/.claude/settings.json b/.claude/settings.json
index d2fd4875..fc367260 100644
--- a/.claude/settings.json
+++ b/.claude/settings.json
@@ -1,6 +1,11 @@
{
"permissions": {
"allow": [
+ "WebFetch(domain:code.claude.com)",
+ "WebFetch(domain:www.anthropic.com)",
+ "WebFetch(domain:anthropic.com)",
+ "WebFetch(domain:platform.claude.com)",
+ "WebFetch(domain:docs.anthropic.com)",
"Bash(ls:*)",
"Bash(grep:*)",
"Bash(find:*)",
diff --git a/.claude/commands/uw.add_platform.add_capabilities.md b/.claude/skills/add_platform.add_capabilities/SKILL.md
similarity index 74%
rename from .claude/commands/uw.add_platform.add_capabilities.md
rename to .claude/skills/add_platform.add_capabilities/SKILL.md
index f63224d7..be4e4fd4 100644
--- a/.claude/commands/uw.add_platform.add_capabilities.md
+++ b/.claude/skills/add_platform.add_capabilities/SKILL.md
@@ -1,5 +1,7 @@
---
-description: Update job schema and adapters with any new hook events the platform supports
+name: add_platform.add_capabilities
+description: "Update job schema and adapters with any new hook events the platform supports"
+user-invocable: false
hooks:
Stop:
- hooks:
@@ -20,39 +22,19 @@ hooks:
# add_platform.add_capabilities
-**Step 2 of 4** in the **add_platform** workflow
+**Step 2/4** in **add_platform** workflow
-**Summary**: Add a new AI platform to DeepWork with adapter, templates, and tests
+> Add a new AI platform to DeepWork with adapter, templates, and tests
-## Job Overview
+## Prerequisites (Verify First)
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
-
-
-## Prerequisites
-
-This step requires completion of the following step(s):
+Before proceeding, confirm these steps are complete:
- `/add_platform.research`
-Please ensure these steps have been completed before proceeding.
-
## Instructions
+**Goal**: Update job schema and adapters with any new hook events the platform supports
+
# Add Hook Capabilities
## Objective
@@ -190,75 +172,57 @@ For reference, here are common hook patterns across platforms:
When you find a new hook type, consider whether it maps to an existing pattern or is genuinely new functionality.
-## Inputs
-
-
-### Required Files
+### Job Context
-This step requires the following files from previous steps:
-- `hooks_system.md` (from step `research`)
-
-Make sure to read and use these files as context for this step.
-
-## Work Branch Management
-
-All work for this job should be done on a dedicated work branch:
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/add_platform-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
-## Output Requirements
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
-Create the following output(s):
-- `job_schema.py`- `adapters.py`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
-## Quality Validation Loop
+## Required Inputs
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
+**Files from Previous Steps** - Read these first:
+- `hooks_system.md` (from `research`)
+## Work Branch
-### Completion Promise
+Use branch format: `deepwork/add_platform-[instance]-YYYYMMDD`
-To signal that all quality criteria have been met, include this tag in your final response:
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)`
-```
-✓ Quality Criteria Met
-```
+## Outputs
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
+**Required outputs**:
+- `job_schema.py`- `adapters.py`
+## Quality Validation
-## Completion
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
-After completing this step:
-1. **Verify outputs**: Confirm all required files have been created
-2. **Inform the user**:
- - Step 2 of 4 is complete
- - Outputs created: job_schema.py, adapters.py
- - Ready to proceed to next step: `/add_platform.implement`
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
-## Next Step
+## On Completion
-To continue the workflow, run:
-```
-/add_platform.implement
-```
+1. Verify outputs are created
+2. Inform user: "Step 2/4 complete, outputs: job_schema.py, adapters.py"
+3. **Continue workflow**: Use Skill tool to invoke `/add_platform.implement`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-- Step instructions: `.deepwork/jobs/add_platform/steps/add_capabilities.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/add_platform/job.yml`, `.deepwork/jobs/add_platform/steps/add_capabilities.md`
\ No newline at end of file
diff --git a/.claude/commands/uw.add_platform.implement.md b/.claude/skills/add_platform.implement/SKILL.md
similarity index 76%
rename from .claude/commands/uw.add_platform.implement.md
rename to .claude/skills/add_platform.implement/SKILL.md
index 3e1e99c8..6f320d28 100644
--- a/.claude/commands/uw.add_platform.implement.md
+++ b/.claude/skills/add_platform.implement/SKILL.md
@@ -1,5 +1,7 @@
---
-description: Add platform adapter, templates, tests with 100% coverage, and README documentation
+name: add_platform.implement
+description: "Add platform adapter, templates, tests with 100% coverage, and README documentation"
+user-invocable: false
hooks:
Stop:
- hooks:
@@ -24,40 +26,20 @@ hooks:
# add_platform.implement
-**Step 3 of 4** in the **add_platform** workflow
+**Step 3/4** in **add_platform** workflow
-**Summary**: Add a new AI platform to DeepWork with adapter, templates, and tests
+> Add a new AI platform to DeepWork with adapter, templates, and tests
-## Job Overview
+## Prerequisites (Verify First)
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
-
-
-## Prerequisites
-
-This step requires completion of the following step(s):
+Before proceeding, confirm these steps are complete:
- `/add_platform.research`
- `/add_platform.add_capabilities`
-Please ensure these steps have been completed before proceeding.
-
## Instructions
+**Goal**: Add platform adapter, templates, tests with 100% coverage, and README documentation
+
# Implement Platform Support
## Objective
@@ -286,80 +268,60 @@ The templates use Jinja2 and should produce files that match exactly what the pl
- Template syntax errors often show up at runtime - test early
-## Inputs
-
-
-### Required Files
-
-This step requires the following files from previous steps:
-- `job_schema.py` (from step `add_capabilities`)
-- `adapters.py` (from step `add_capabilities`)
-- `cli_configuration.md` (from step `research`)
-
-Make sure to read and use these files as context for this step.
+### Job Context
-## Work Branch Management
-
-All work for this job should be done on a dedicated work branch:
-
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/add_platform-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
-## Output Requirements
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
-Create the following output(s):
-- `templates/` (directory)- `tests/` (directory)- `README.md`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
-## Quality Validation Loop
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
+## Required Inputs
-**Validation Script**: `.deepwork/jobs/add_platform/hooks/run_tests.sh`
+**Files from Previous Steps** - Read these first:
+- `job_schema.py` (from `add_capabilities`)
+- `adapters.py` (from `add_capabilities`)
+- `cli_configuration.md` (from `research`)
-The validation script will be executed automatically when you attempt to complete this step.
+## Work Branch
-### Completion Promise
+Use branch format: `deepwork/add_platform-[instance]-YYYYMMDD`
-To signal that all quality criteria have been met, include this tag in your final response:
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)`
-```
-✓ Quality Criteria Met
-```
+## Outputs
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
+**Required outputs**:
+- `templates/` (directory)- `tests/` (directory)- `README.md`
+## Quality Validation
-## Completion
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
-After completing this step:
-1. **Verify outputs**: Confirm all required files have been created
+**Validation script**: `.deepwork/jobs/add_platform/hooks/run_tests.sh` (runs automatically)
-2. **Inform the user**:
- - Step 3 of 4 is complete
- - Outputs created: templates/, tests/, README.md
- - Ready to proceed to next step: `/add_platform.verify`
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
-## Next Step
+## On Completion
-To continue the workflow, run:
-```
-/add_platform.verify
-```
+1. Verify outputs are created
+2. Inform user: "Step 3/4 complete, outputs: templates/, tests/, README.md"
+3. **Continue workflow**: Use Skill tool to invoke `/add_platform.verify`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-- Step instructions: `.deepwork/jobs/add_platform/steps/implement.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/add_platform/job.yml`, `.deepwork/jobs/add_platform/steps/implement.md`
\ No newline at end of file
diff --git a/.claude/commands/uw.add_platform.research.md b/.claude/skills/add_platform.research/SKILL.md
similarity index 77%
rename from .claude/commands/uw.add_platform.research.md
rename to .claude/skills/add_platform.research/SKILL.md
index d8bf5be4..288223d9 100644
--- a/.claude/commands/uw.add_platform.research.md
+++ b/.claude/skills/add_platform.research/SKILL.md
@@ -1,5 +1,7 @@
---
-description: Capture CLI configuration and hooks system documentation for the new platform
+name: add_platform.research
+description: "Capture CLI configuration and hooks system documentation for the new platform"
+user-invocable: false
hooks:
Stop:
- hooks:
@@ -21,33 +23,15 @@ hooks:
# add_platform.research
-**Step 1 of 4** in the **add_platform** workflow
-
-**Summary**: Add a new AI platform to DeepWork with adapter, templates, and tests
-
-## Job Overview
-
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
+**Step 1/4** in **add_platform** workflow
+> Add a new AI platform to DeepWork with adapter, templates, and tests
## Instructions
+**Goal**: Capture CLI configuration and hooks system documentation for the new platform
+
# Research Platform Documentation
## Objective
@@ -238,73 +222,57 @@ Take time to be thorough - incomplete documentation will slow down subsequent st
- Include code examples from the official docs where available
-## Inputs
-
-### User Parameters
-
-Please gather the following information from the user:
-- **platform_name**: Clear identifier of the platform (e.g., 'cursor', 'windsurf-editor', 'github-copilot-chat')
-
-
-## Work Branch Management
+### Job Context
-All work for this job should be done on a dedicated work branch:
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/add_platform-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
-## Output Requirements
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
-Create the following output(s):
-- `cli_configuration.md`- `hooks_system.md`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
-## Quality Validation Loop
+## Required Inputs
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
+**User Parameters** - Gather from user before starting:
+- **platform_name**: Clear identifier of the platform (e.g., 'cursor', 'windsurf-editor', 'github-copilot-chat')
+## Work Branch
-### Completion Promise
+Use branch format: `deepwork/add_platform-[instance]-YYYYMMDD`
-To signal that all quality criteria have been met, include this tag in your final response:
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)`
-```
-✓ Quality Criteria Met
-```
+## Outputs
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
+**Required outputs**:
+- `cli_configuration.md`- `hooks_system.md`
+## Quality Validation
-## Completion
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
-After completing this step:
-1. **Verify outputs**: Confirm all required files have been created
-2. **Inform the user**:
- - Step 1 of 4 is complete
- - Outputs created: cli_configuration.md, hooks_system.md
- - Ready to proceed to next step: `/add_platform.add_capabilities`
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
-## Next Step
+## On Completion
-To continue the workflow, run:
-```
-/add_platform.add_capabilities
-```
+1. Verify outputs are created
+2. Inform user: "Step 1/4 complete, outputs: cli_configuration.md, hooks_system.md"
+3. **Continue workflow**: Use Skill tool to invoke `/add_platform.add_capabilities`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-- Step instructions: `.deepwork/jobs/add_platform/steps/research.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/add_platform/job.yml`, `.deepwork/jobs/add_platform/steps/research.md`
\ No newline at end of file
diff --git a/.claude/commands/uw.add_platform.verify.md b/.claude/skills/add_platform.verify/SKILL.md
similarity index 69%
rename from .claude/commands/uw.add_platform.verify.md
rename to .claude/skills/add_platform.verify/SKILL.md
index d7c3a61e..70ca3ffc 100644
--- a/.claude/commands/uw.add_platform.verify.md
+++ b/.claude/skills/add_platform.verify/SKILL.md
@@ -1,5 +1,7 @@
---
-description: Set up platform directories and verify deepwork install works correctly
+name: add_platform.verify
+description: "Set up platform directories and verify deepwork install works correctly"
+user-invocable: false
hooks:
Stop:
- hooks:
@@ -19,39 +21,19 @@ hooks:
# add_platform.verify
-**Step 4 of 4** in the **add_platform** workflow
+**Step 4/4** in **add_platform** workflow
-**Summary**: Add a new AI platform to DeepWork with adapter, templates, and tests
+> Add a new AI platform to DeepWork with adapter, templates, and tests
-## Job Overview
+## Prerequisites (Verify First)
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
-
-
-## Prerequisites
-
-This step requires completion of the following step(s):
+Before proceeding, confirm these steps are complete:
- `/add_platform.implement`
-Please ensure these steps have been completed before proceeding.
-
## Instructions
+**Goal**: Set up platform directories and verify deepwork install works correctly
+
# Verify Installation
## Objective
@@ -165,72 +147,57 @@ Take time to verify each aspect - finding issues now is much better than having
- **Permission issues**: Directory creation might fail in some cases
-## Inputs
+### Job Context
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-### Required Files
-
-This step requires the following files from previous steps:
-- `templates/` (from step `implement`)
-
-Make sure to read and use these files as context for this step.
-
-## Work Branch Management
-
-All work for this job should be done on a dedicated work branch:
-
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/add_platform-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
-## Output Requirements
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
-No specific files are output by this command.
-## Quality Validation Loop
+## Required Inputs
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
+**Files from Previous Steps** - Read these first:
+- `templates/` (from `implement`)
+## Work Branch
-### Completion Promise
+Use branch format: `deepwork/add_platform-[instance]-YYYYMMDD`
-To signal that all quality criteria have been met, include this tag in your final response:
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)`
-```
-✓ Quality Criteria Met
-```
+## Outputs
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
+No specific file outputs required.
-## Completion
+## Quality Validation
-After completing this step:
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
-1. **Verify outputs**: Confirm all required files have been created
-2. **Inform the user**:
- - Step 4 of 4 is complete
- - This is the final step - the job is complete!
-## Workflow Complete
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
-This is the final step in the add_platform workflow. All outputs should now be complete and ready for review.
+## On Completion
-Consider:
-- Reviewing all work products
-- Creating a pull request to merge the work branch
-- Documenting any insights or learnings
+1. Verify outputs are created
+2. Inform user: "Step 4/4 complete"
+3. **Workflow complete**: All steps finished. Consider creating a PR to merge the work branch.
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-- Step instructions: `.deepwork/jobs/add_platform/steps/verify.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/add_platform/job.yml`, `.deepwork/jobs/add_platform/steps/verify.md`
\ No newline at end of file
diff --git a/.claude/skills/add_platform/SKILL.md b/.claude/skills/add_platform/SKILL.md
new file mode 100644
index 00000000..c9c5cfa9
--- /dev/null
+++ b/.claude/skills/add_platform/SKILL.md
@@ -0,0 +1,69 @@
+---
+name: add_platform
+description: "Add a new AI platform to DeepWork with adapter, templates, and tests"
+---
+
+# add_platform
+
+**Multi-step workflow**: Add a new AI platform to DeepWork with adapter, templates, and tests
+
+> **CRITICAL**: Always invoke steps using the Skill tool. Never copy/paste step instructions directly.
+
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
+
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
+
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
+
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
+
+
+## Available Steps
+
+1. **research** - Capture CLI configuration and hooks system documentation for the new platform
+2. **add_capabilities** - Update job schema and adapters with any new hook events the platform supports (requires: research)
+3. **implement** - Add platform adapter, templates, tests with 100% coverage, and README documentation (requires: research, add_capabilities)
+4. **verify** - Set up platform directories and verify deepwork install works correctly (requires: implement)
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/add_platform` to determine user intent:
+- "research" or related terms → start at `add_platform.research`
+- "add_capabilities" or related terms → start at `add_platform.add_capabilities`
+- "implement" or related terms → start at `add_platform.implement`
+- "verify" or related terms → start at `add_platform.verify`
+
+### Step 2: Invoke Starting Step
+
+Use the Skill tool to invoke the identified starting step:
+```
+Skill tool: add_platform.research
+```
+
+### Step 3: Continue Workflow Automatically
+
+After each step completes:
+1. Check if there's a next step in the sequence
+2. Invoke the next step using the Skill tool
+3. Repeat until workflow is complete or user intervenes
+
+### Handling Ambiguous Intent
+
+If user intent is unclear, use AskUserQuestion to clarify:
+- Present available steps as numbered options
+- Let user select the starting point
+
+## Context Files
+
+- Job definition: `.deepwork/jobs/add_platform/job.yml`
\ No newline at end of file
diff --git a/.claude/skills/commit.commit_and_push/SKILL.md b/.claude/skills/commit.commit_and_push/SKILL.md
new file mode 100644
index 00000000..61e17763
--- /dev/null
+++ b/.claude/skills/commit.commit_and_push/SKILL.md
@@ -0,0 +1,159 @@
+---
+name: commit.commit_and_push
+description: "Review changed files, commit, and push to remote"
+user-invocable: false
+hooks:
+ Stop:
+ - hooks:
+ - type: prompt
+ prompt: |
+ Verify the commit is ready:
+ 1. Changed files list was reviewed with user
+ 2. User confirmed the files match expectations
+ 3. Commit was created with appropriate message
+ 4. Changes were pushed to remote
+ If ALL criteria are met, include `✓ Quality Criteria Met`.
+
+---
+
+# commit.commit_and_push
+
+**Step 3/3** in **commit** workflow
+
+> Run tests, lint, and commit code changes
+
+## Prerequisites (Verify First)
+
+Before proceeding, confirm these steps are complete:
+- `/commit.lint`
+
+## Instructions
+
+**Goal**: Review changed files, commit, and push to remote
+
+# Commit and Push
+
+## Objective
+
+Review the changed files with the user, create a commit with an appropriate message, and push to the remote repository.
+
+## Task
+
+Present the list of changed files for user review, ensure they match expectations, then commit and push the changes.
+
+### Process
+
+1. **Get the list of changed files**
+ ```bash
+ git status
+ ```
+ Also run `git diff --stat` to see a summary of changes.
+
+2. **Present changes to the user for review**
+
+ Use the AskUserQuestion tool to ask structured questions about the changes:
+
+ Show the user:
+ - List of modified files
+ - List of new files
+ - List of deleted files
+ - Summary of changes (lines added/removed)
+
+ Ask them to confirm:
+ - "Do these changed files match your expectations?"
+ - Provide options: "Yes, proceed with commit" / "No, let me review first" / "No, some files shouldn't be included"
+
+3. **Handle user response**
+
+ - If user confirms, proceed to commit
+ - If user wants to review first, wait for them to come back
+ - If user says some files shouldn't be included, ask which files to exclude and use `git restore` or `git checkout` to unstage them
+
+4. **Stage all appropriate changes**
+ ```bash
+ git add -A
+ ```
+ Or stage specific files if user excluded some.
+
+5. **View recent commit messages for style reference**
+ ```bash
+ git log --oneline -10
+ ```
+
+6. **Create the commit**
+
+ Generate an appropriate commit message based on:
+ - The changes made
+ - The style of recent commits
+ - Conventional commit format if the project uses it
+
+ ```bash
+ git commit -m "commit message here"
+ ```
+
+7. **Push to remote**
+ ```bash
+ git push
+ ```
+ If the branch has no upstream, use:
+ ```bash
+ git push -u origin HEAD
+ ```
+
+## Quality Criteria
+
+- Changed files list was presented to user
+- User explicitly confirmed the files match expectations
+- Commit message follows project conventions
+- Commit was created successfully
+- Changes were pushed to remote
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This is the final step of the commit workflow. It ensures the user has reviewed and approved the changes before they are committed and pushed. This prevents accidental commits of unintended files or changes.
+
+
+### Job Context
+
+A workflow for preparing and committing code changes with quality checks.
+
+This job runs tests until they pass, formats and lints code with ruff,
+then reviews changed files before committing and pushing. The lint step
+uses a sub-agent to reduce context usage.
+
+Steps:
+1. test - Pull latest code and run tests until they pass
+2. lint - Format and lint code with ruff (runs in sub-agent)
+3. commit_and_push - Review changes and commit/push
+
+
+
+## Work Branch
+
+Use branch format: `deepwork/commit-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/commit-[instance]-$(date +%Y%m%d)`
+
+## Outputs
+
+No specific file outputs required.
+
+## Quality Validation
+
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
+
+
+
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
+
+## On Completion
+
+1. Verify outputs are created
+2. Inform user: "Step 3/3 complete"
+3. **Workflow complete**: All steps finished. Consider creating a PR to merge the work branch.
+
+---
+
+**Reference files**: `.deepwork/jobs/commit/job.yml`, `.deepwork/jobs/commit/steps/commit_and_push.md`
\ No newline at end of file
diff --git a/.claude/skills/commit.lint/SKILL.md b/.claude/skills/commit.lint/SKILL.md
new file mode 100644
index 00000000..c77290f7
--- /dev/null
+++ b/.claude/skills/commit.lint/SKILL.md
@@ -0,0 +1,149 @@
+---
+name: commit.lint
+description: "Format and lint code with ruff using a sub-agent"
+user-invocable: false
+hooks:
+ Stop:
+ - hooks:
+ - type: prompt
+ prompt: |
+ Verify the linting is complete:
+ 1. ruff format was run successfully
+ 2. ruff check was run successfully (with --fix)
+ 3. No remaining lint errors
+ If ALL criteria are met, include `✓ Quality Criteria Met`.
+
+---
+
+# commit.lint
+
+**Step 2/3** in **commit** workflow
+
+> Run tests, lint, and commit code changes
+
+## Prerequisites (Verify First)
+
+Before proceeding, confirm these steps are complete:
+- `/commit.test`
+
+## Instructions
+
+**Goal**: Format and lint code with ruff using a sub-agent
+
+# Lint Code
+
+## Objective
+
+Format and lint the codebase using ruff to ensure code quality and consistency.
+
+## Task
+
+Run ruff format and ruff check to format and lint the code. This step should be executed using a sub-agent to conserve context in the main conversation.
+
+### Process
+
+**IMPORTANT**: Use the Task tool to spawn a sub-agent for this work. This saves context in the main conversation. Use the `haiku` model for speed.
+
+1. **Spawn a sub-agent to run linting**
+
+ Use the Task tool with these parameters:
+ - `subagent_type`: "Bash"
+ - `model`: "haiku"
+ - `prompt`: See below
+
+ The sub-agent should:
+
+ a. **Run ruff format**
+ ```bash
+ ruff format .
+ ```
+ This formats the code according to ruff's style rules.
+
+ b. **Run ruff check with auto-fix**
+ ```bash
+ ruff check --fix .
+ ```
+ This checks for lint errors and automatically fixes what it can.
+
+ c. **Run ruff check again to verify**
+ ```bash
+ ruff check .
+ ```
+ Capture the final output to verify no remaining issues.
+
+2. **Review sub-agent results**
+ - Check that both format and check completed successfully
+ - Note any remaining lint issues that couldn't be auto-fixed
+
+3. **Handle remaining issues**
+ - If there are lint errors that couldn't be auto-fixed, fix them manually
+ - Re-run ruff check to verify
+
+## Example Sub-Agent Prompt
+
+```
+Run ruff to format and lint the codebase:
+
+1. Run: ruff format .
+2. Run: ruff check --fix .
+3. Run: ruff check . (to verify no remaining issues)
+
+Report the results of each command.
+```
+
+## Quality Criteria
+
+- ruff format was run successfully
+- ruff check was run with --fix flag
+- No remaining lint errors (or all are documented and intentional)
+- Sub-agent was used to conserve context
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This step ensures code quality and consistency before committing. It runs after tests pass and before the commit step. Using a sub-agent keeps the main conversation context clean for the commit review.
+
+
+### Job Context
+
+A workflow for preparing and committing code changes with quality checks.
+
+This job runs tests until they pass, formats and lints code with ruff,
+then reviews changed files before committing and pushing. The lint step
+uses a sub-agent to reduce context usage.
+
+Steps:
+1. test - Pull latest code and run tests until they pass
+2. lint - Format and lint code with ruff (runs in sub-agent)
+3. commit_and_push - Review changes and commit/push
+
+
+
+## Work Branch
+
+Use branch format: `deepwork/commit-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/commit-[instance]-$(date +%Y%m%d)`
+
+## Outputs
+
+No specific file outputs required.
+
+## Quality Validation
+
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
+
+
+
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
+
+## On Completion
+
+1. Verify outputs are created
+2. Inform user: "Step 2/3 complete"
+3. **Continue workflow**: Use Skill tool to invoke `/commit.commit_and_push`
+
+---
+
+**Reference files**: `.deepwork/jobs/commit/job.yml`, `.deepwork/jobs/commit/steps/lint.md`
\ No newline at end of file
diff --git a/.claude/skills/commit.test/SKILL.md b/.claude/skills/commit.test/SKILL.md
new file mode 100644
index 00000000..373efe35
--- /dev/null
+++ b/.claude/skills/commit.test/SKILL.md
@@ -0,0 +1,132 @@
+---
+name: commit.test
+description: "Pull latest code and run the test suite until all tests pass"
+user-invocable: false
+hooks:
+ Stop:
+ - hooks:
+ - type: prompt
+ prompt: |
+ Verify the tests are passing:
+ 1. Latest code was pulled from the branch
+ 2. All tests completed successfully
+ 3. No test failures or errors remain
+ 4. Test output shows passing status
+ If ALL criteria are met, include `✓ Quality Criteria Met`.
+
+---
+
+# commit.test
+
+**Step 1/3** in **commit** workflow
+
+> Run tests, lint, and commit code changes
+
+
+## Instructions
+
+**Goal**: Pull latest code and run the test suite until all tests pass
+
+# Run Tests
+
+## Objective
+
+Run the project's test suite and fix any failing tests until all tests pass.
+
+## Task
+
+Execute the test suite for the project and iteratively fix any failures until all tests pass.
+
+### Process
+
+1. **Pull latest code from the branch**
+ - Run `git pull` to fetch and merge any changes from the remote
+ - If there are merge conflicts, resolve them before proceeding
+ - This ensures you're testing against the latest code
+
+2. **Detect or use the test command**
+ - If a test command was provided, use that
+ - Otherwise, auto-detect the project type and determine the appropriate test command:
+ - Python: `pytest`, `python -m pytest`, `uv run pytest`
+ - Node.js: `npm test`, `yarn test`, `bun test`
+ - Go: `go test ./...`
+ - Rust: `cargo test`
+ - Check `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod` for hints
+
+3. **Run the tests**
+ - Execute the test command
+ - Capture the output
+
+4. **Analyze failures**
+ - If tests pass, proceed to output
+ - If tests fail, analyze the failure messages
+ - Identify the root cause of each failure
+
+5. **Fix failing tests**
+ - Make the necessary code changes to fix failures
+ - This may involve fixing bugs in implementation code or updating tests
+ - Re-run tests after each fix
+
+6. **Iterate until passing**
+ - Continue the fix/test cycle until all tests pass
+
+## Quality Criteria
+
+- Latest code was pulled from the branch
+- Test command was correctly identified or used from input
+- All tests are now passing
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This is the first step of the commit workflow. Tests must pass before proceeding to lint and commit. This ensures code quality and prevents broken code from being committed.
+
+
+### Job Context
+
+A workflow for preparing and committing code changes with quality checks.
+
+This job runs tests until they pass, formats and lints code with ruff,
+then reviews changed files before committing and pushing. The lint step
+uses a sub-agent to reduce context usage.
+
+Steps:
+1. test - Pull latest code and run tests until they pass
+2. lint - Format and lint code with ruff (runs in sub-agent)
+3. commit_and_push - Review changes and commit/push
+
+
+## Required Inputs
+
+**User Parameters** - Gather from user before starting:
+- **test_command**: Test command to run (optional - will auto-detect if not provided)
+
+
+## Work Branch
+
+Use branch format: `deepwork/commit-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/commit-[instance]-$(date +%Y%m%d)`
+
+## Outputs
+
+No specific file outputs required.
+
+## Quality Validation
+
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
+
+
+
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
+
+## On Completion
+
+1. Verify outputs are created
+2. Inform user: "Step 1/3 complete"
+3. **Continue workflow**: Use Skill tool to invoke `/commit.lint`
+
+---
+
+**Reference files**: `.deepwork/jobs/commit/job.yml`, `.deepwork/jobs/commit/steps/test.md`
\ No newline at end of file
diff --git a/.claude/skills/commit/SKILL.md b/.claude/skills/commit/SKILL.md
new file mode 100644
index 00000000..247ca8ef
--- /dev/null
+++ b/.claude/skills/commit/SKILL.md
@@ -0,0 +1,61 @@
+---
+name: commit
+description: "Run tests, lint, and commit code changes"
+---
+
+# commit
+
+**Multi-step workflow**: Run tests, lint, and commit code changes
+
+> **CRITICAL**: Always invoke steps using the Skill tool. Never copy/paste step instructions directly.
+
+A workflow for preparing and committing code changes with quality checks.
+
+This job runs tests until they pass, formats and lints code with ruff,
+then reviews changed files before committing and pushing. The lint step
+uses a sub-agent to reduce context usage.
+
+Steps:
+1. test - Pull latest code and run tests until they pass
+2. lint - Format and lint code with ruff (runs in sub-agent)
+3. commit_and_push - Review changes and commit/push
+
+
+## Available Steps
+
+1. **test** - Pull latest code and run the test suite until all tests pass
+2. **lint** - Format and lint code with ruff using a sub-agent (requires: test)
+3. **commit_and_push** - Review changed files, commit, and push to remote (requires: lint)
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/commit` to determine user intent:
+- "test" or related terms → start at `commit.test`
+- "lint" or related terms → start at `commit.lint`
+- "commit_and_push" or related terms → start at `commit.commit_and_push`
+
+### Step 2: Invoke Starting Step
+
+Use the Skill tool to invoke the identified starting step:
+```
+Skill tool: commit.test
+```
+
+### Step 3: Continue Workflow Automatically
+
+After each step completes:
+1. Check if there's a next step in the sequence
+2. Invoke the next step using the Skill tool
+3. Repeat until workflow is complete or user intervenes
+
+### Handling Ambiguous Intent
+
+If user intent is unclear, use AskUserQuestion to clarify:
+- Present available steps as numbered options
+- Let user select the starting point
+
+## Context Files
+
+- Job definition: `.deepwork/jobs/commit/job.yml`
\ No newline at end of file
diff --git a/.claude/commands/uw.deepwork_jobs.define.md b/.claude/skills/deepwork_jobs.define/SKILL.md
similarity index 88%
rename from .claude/commands/uw.deepwork_jobs.define.md
rename to .claude/skills/deepwork_jobs.define/SKILL.md
index 6902fe1b..d76043d0 100644
--- a/.claude/commands/uw.deepwork_jobs.define.md
+++ b/.claude/skills/deepwork_jobs.define/SKILL.md
@@ -1,5 +1,7 @@
---
-description: Create the job.yml specification file by understanding workflow requirements
+name: deepwork_jobs.define
+description: "Create the job.yml specification file by understanding workflow requirements"
+user-invocable: false
hooks:
Stop:
- hooks:
@@ -32,27 +34,15 @@ hooks:
# deepwork_jobs.define
-**Step 1 of 3** in the **deepwork_jobs** workflow
-
-**Summary**: DeepWork job management commands
-
-## Job Overview
-
-Core commands for managing DeepWork jobs. These commands help you define new multi-step
-workflows and learn from running them.
-
-The `define` command guides you through an interactive process to create a new job by
-asking structured questions about your workflow, understanding each step's inputs and outputs,
-and generating all necessary files.
-
-The `learn` command reflects on conversations where DeepWork jobs were run, identifies
-confusion or inefficiencies, and improves job instructions. It also captures bespoke
-learnings specific to the current run into AGENTS.md files in the working folder.
+**Step 1/3** in **deepwork_jobs** workflow
+> DeepWork job management commands
## Instructions
+**Goal**: Create the job.yml specification file by understanding workflow requirements
+
# Define Job Specification
## Objective
@@ -386,42 +376,42 @@ After creating the file:
- Ready for implementation step
-## Inputs
+### Job Context
-### User Parameters
+Core commands for managing DeepWork jobs. These commands help you define new multi-step
+workflows and learn from running them.
-Please gather the following information from the user:
-- **job_purpose**: What complex task or workflow are you trying to accomplish?
+The `define` command guides you through an interactive process to create a new job by
+asking structured questions about your workflow, understanding each step's inputs and outputs,
+and generating all necessary files.
+The `learn` command reflects on conversations where DeepWork jobs were run, identifies
+confusion or inefficiencies, and improves job instructions. It also captures bespoke
+learnings specific to the current run into AGENTS.md files in the working folder.
-## Work Branch Management
-All work for this job should be done on a dedicated work branch:
+## Required Inputs
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/deepwork_jobs-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+**User Parameters** - Gather from user before starting:
+- **job_purpose**: What complex task or workflow are you trying to accomplish?
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-## Output Requirements
+## Work Branch
-Create the following output(s):
-- `job.yml`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+Use branch format: `deepwork/deepwork_jobs-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)`
-## Quality Validation Loop
+## Outputs
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
+**Required outputs**:
+- `job.yml`
+## Quality Validation
-### Quality Criteria
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
+**Criteria (all must be satisfied)**:
1. **User Understanding**: Did the agent fully understand the user's workflow by asking structured questions?
2. **Structured Questions Used**: Did the agent ask structured questions (using the AskUserQuestion tool) to gather user input?
3. **Clear Inputs/Outputs**: Does every step have clearly defined inputs and outputs?
@@ -432,37 +422,14 @@ This step uses an iterative quality validation loop. After completing your work,
8. **File Created**: Has the job.yml file been created in `.deepwork/jobs/[job_name]/job.yml`?
-### Completion Promise
-
-To signal that all quality criteria have been met, include this tag in your final response:
-
-```
-✓ Quality Criteria Met
-```
-
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
-
-## Completion
-
-After completing this step:
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
-1. **Verify outputs**: Confirm all required files have been created
+## On Completion
-2. **Inform the user**:
- - Step 1 of 3 is complete
- - Outputs created: job.yml
- - Ready to proceed to next step: `/deepwork_jobs.implement`
-
-## Next Step
-
-To continue the workflow, run:
-```
-/deepwork_jobs.implement
-```
+1. Verify outputs are created
+2. Inform user: "Step 1/3 complete, outputs: job.yml"
+3. **Continue workflow**: Use Skill tool to invoke `/deepwork_jobs.implement`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
-- Step instructions: `.deepwork/jobs/deepwork_jobs/steps/define.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/deepwork_jobs/job.yml`, `.deepwork/jobs/deepwork_jobs/steps/define.md`
\ No newline at end of file
diff --git a/.claude/commands/uw.deepwork_jobs.implement.md b/.claude/skills/deepwork_jobs.implement/SKILL.md
similarity index 82%
rename from .claude/commands/uw.deepwork_jobs.implement.md
rename to .claude/skills/deepwork_jobs.implement/SKILL.md
index 2ad241f7..ce48081f 100644
--- a/.claude/commands/uw.deepwork_jobs.implement.md
+++ b/.claude/skills/deepwork_jobs.implement/SKILL.md
@@ -1,5 +1,7 @@
---
-description: Generate instruction files for each step based on the job.yml specification
+name: deepwork_jobs.implement
+description: "Generate instruction files for each step based on the job.yml specification"
+user-invocable: false
hooks:
Stop:
- hooks:
@@ -33,33 +35,19 @@ hooks:
# deepwork_jobs.implement
-**Step 2 of 3** in the **deepwork_jobs** workflow
+**Step 2/3** in **deepwork_jobs** workflow
-**Summary**: DeepWork job management commands
+> DeepWork job management commands
-## Job Overview
+## Prerequisites (Verify First)
-Core commands for managing DeepWork jobs. These commands help you define new multi-step
-workflows and learn from running them.
-
-The `define` command guides you through an interactive process to create a new job by
-asking structured questions about your workflow, understanding each step's inputs and outputs,
-and generating all necessary files.
-
-The `learn` command reflects on conversations where DeepWork jobs were run, identifies
-confusion or inefficiencies, and improves job instructions. It also captures bespoke
-learnings specific to the current run into AGENTS.md files in the working folder.
-
-
-## Prerequisites
-
-This step requires completion of the following step(s):
+Before proceeding, confirm these steps are complete:
- `/deepwork_jobs.define`
-Please ensure these steps have been completed before proceeding.
-
## Instructions
+**Goal**: Generate instruction files for each step based on the job.yml specification
+
# Implement Job Steps
## Objective
@@ -175,9 +163,9 @@ See `.deepwork/jobs/deepwork_jobs/steps/supplemental_file_references.md` for det
Verify that `job.yml` is in the correct location at `.deepwork/jobs/[job_name]/job.yml`. The define step should have created it there. If for some reason it's not there, you may need to create or move it.
-### Step 5: Sync Commands
+### Step 5: Sync Skills
-Run `deepwork sync` to generate the slash-commands for this job:
+Run `deepwork sync` to generate the skills for this job:
```bash
deepwork sync
@@ -185,12 +173,12 @@ deepwork sync
This will:
- Parse the job definition
-- Generate slash-commands for each step
-- Make the commands available in `.claude/commands/` (or appropriate platform directory)
+- Generate skills for each step
+- Make the skills available in `.claude/skills/` (or appropriate platform directory)
### Step 6: Relay Reload Instructions
-After running `deepwork sync`, look at the "To use the new commands" section in the output. **Relay these exact reload instructions to the user** so they know how to pick up the new commands. Don't just reference the sync output - tell them directly what they need to do (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code, or "Run '/memory refresh'" for Gemini CLI).
+After running `deepwork sync`, look at the "To use the new skills" section in the output. **Relay these exact reload instructions to the user** so they know how to pick up the new skills. Don't just reference the sync output - tell them directly what they need to do (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code, or "Run '/memory refresh'" for Gemini CLI).
### Step 7: Consider Rules for the New Job
@@ -282,7 +270,7 @@ Before marking this step complete, ensure:
- [ ] All step instruction files created
- [ ] Each instruction file is complete and actionable
- [ ] `deepwork sync` executed successfully
-- [ ] Commands generated in platform directory
+- [ ] Skills generated in platform directory
- [ ] User informed to follow reload instructions from `deepwork sync`
- [ ] Considered whether rules would benefit this job (Step 7)
- [ ] If rules suggested, offered to run `/deepwork_rules.define`
@@ -296,48 +284,46 @@ Before marking this step complete, ensure:
- Quality criteria defined for each step
- Steps with user inputs explicitly use "ask structured questions" phrasing
- Sync completed successfully
-- Commands available for use
+- Skills available for use
- Thoughtfully considered relevant rules for the job domain
-## Inputs
+### Job Context
+Core commands for managing DeepWork jobs. These commands help you define new multi-step
+workflows and learn from running them.
-### Required Files
+The `define` command guides you through an interactive process to create a new job by
+asking structured questions about your workflow, understanding each step's inputs and outputs,
+and generating all necessary files.
-This step requires the following files from previous steps:
-- `job.yml` (from step `define`)
+The `learn` command reflects on conversations where DeepWork jobs were run, identifies
+confusion or inefficiencies, and improves job instructions. It also captures bespoke
+learnings specific to the current run into AGENTS.md files in the working folder.
-Make sure to read and use these files as context for this step.
-## Work Branch Management
+## Required Inputs
-All work for this job should be done on a dedicated work branch:
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/deepwork_jobs-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+**Files from Previous Steps** - Read these first:
+- `job.yml` (from `define`)
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+## Work Branch
-## Output Requirements
+Use branch format: `deepwork/deepwork_jobs-[instance]-YYYYMMDD`
-Create the following output(s):
-- `steps/` (directory)
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)`
-## Quality Validation Loop
+## Outputs
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
+**Required outputs**:
+- `steps/` (directory)
+## Quality Validation
-### Quality Criteria
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
+**Criteria (all must be satisfied)**:
1. **Directory Structure**: Is `.deepwork/jobs/[job_name]/` created correctly?
2. **Complete Instructions**: Are ALL step instruction files complete (not stubs or placeholders)?
3. **Specific & Actionable**: Are instructions tailored to each step's purpose, not generic?
@@ -349,37 +335,14 @@ This step uses an iterative quality validation loop. After completing your work,
9. **Rules Considered**: Has the agent thought about whether rules would benefit this job? If relevant rules were identified, did they explain them and offer to run `/deepwork_rules.define`? Not every job needs rules - only suggest when genuinely helpful.
-### Completion Promise
-
-To signal that all quality criteria have been met, include this tag in your final response:
-
-```
-✓ Quality Criteria Met
-```
-
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
-
-## Completion
-
-After completing this step:
-
-1. **Verify outputs**: Confirm all required files have been created
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
-2. **Inform the user**:
- - Step 2 of 3 is complete
- - Outputs created: steps/
- - Ready to proceed to next step: `/deepwork_jobs.learn`
+## On Completion
-## Next Step
-
-To continue the workflow, run:
-```
-/deepwork_jobs.learn
-```
+1. Verify outputs are created
+2. Inform user: "Step 2/3 complete, outputs: steps/"
+3. **Continue workflow**: Use Skill tool to invoke `/deepwork_jobs.learn`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
-- Step instructions: `.deepwork/jobs/deepwork_jobs/steps/implement.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/deepwork_jobs/job.yml`, `.deepwork/jobs/deepwork_jobs/steps/implement.md`
\ No newline at end of file
diff --git a/.claude/commands/deepwork_jobs.learn.md b/.claude/skills/deepwork_jobs.learn/SKILL.md
similarity index 83%
rename from .claude/commands/deepwork_jobs.learn.md
rename to .claude/skills/deepwork_jobs.learn/SKILL.md
index d8910651..491d6b72 100644
--- a/.claude/commands/deepwork_jobs.learn.md
+++ b/.claude/skills/deepwork_jobs.learn/SKILL.md
@@ -1,5 +1,6 @@
---
-description: Reflect on conversation to improve job instructions and capture learnings
+name: deepwork_jobs.learn
+description: "Reflect on conversation to improve job instructions and capture learnings"
hooks:
Stop:
- hooks:
@@ -34,27 +35,15 @@ hooks:
# deepwork_jobs.learn
-**Standalone command** in the **deepwork_jobs** job - can be run anytime
-
-**Summary**: DeepWork job management commands
-
-## Job Overview
-
-Core commands for managing DeepWork jobs. These commands help you define new multi-step
-workflows and learn from running them.
-
-The `define` command guides you through an interactive process to create a new job by
-asking structured questions about your workflow, understanding each step's inputs and outputs,
-and generating all necessary files.
-
-The `learn` command reflects on conversations where DeepWork jobs were run, identifies
-confusion or inefficiencies, and improves job instructions. It also captures bespoke
-learnings specific to the current run into AGENTS.md files in the working folder.
+**Standalone skill** - can be run anytime
+> DeepWork job management commands
## Instructions
+**Goal**: Reflect on conversation to improve job instructions and capture learnings
+
# Learn from Job Execution
## Objective
@@ -228,7 +217,7 @@ If instruction files were modified:
deepwork sync
```
-2. **If commands were regenerated**, look at the "To use the new commands" section in the `deepwork sync` output and **relay these exact reload instructions to the user** (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code)
+2. **If skills were regenerated**, look at the "To use the new skills" section in the `deepwork sync` output and **relay these exact reload instructions to the user** (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code)
## File Reference Patterns
@@ -318,7 +307,7 @@ I found the following job executions:
**Summary**
-Updated job instructions and created AGENTS.md with bespoke learnings. To get the updated commands, type 'exit' then run 'claude --resume'.
+Updated job instructions and created AGENTS.md with bespoke learnings. To get the updated skills, type 'exit' then run 'claude --resume'.
```
## Handling Edge Cases
@@ -345,42 +334,42 @@ Updated job instructions and created AGENTS.md with bespoke learnings. To get th
- Reference config files instead of including values
-## Inputs
+### Job Context
-### User Parameters
+Core commands for managing DeepWork jobs. These commands help you define new multi-step
+workflows and learn from running them.
-Please gather the following information from the user:
-- **job_name**: Name of the job that was run (optional - will auto-detect from conversation)
+The `define` command guides you through an interactive process to create a new job by
+asking structured questions about your workflow, understanding each step's inputs and outputs,
+and generating all necessary files.
+The `learn` command reflects on conversations where DeepWork jobs were run, identifies
+confusion or inefficiencies, and improves job instructions. It also captures bespoke
+learnings specific to the current run into AGENTS.md files in the working folder.
-## Work Branch Management
-All work for this job should be done on a dedicated work branch:
+## Required Inputs
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/deepwork_jobs-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+**User Parameters** - Gather from user before starting:
+- **job_name**: Name of the job that was run (optional - will auto-detect from conversation)
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-## Output Requirements
+## Work Branch
-Create the following output(s):
-- `AGENTS.md`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+Use branch format: `deepwork/deepwork_jobs-[instance]-YYYYMMDD`
-## Quality Validation Loop
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)`
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
+## Outputs
-### Quality Criteria
+**Required outputs**:
+- `AGENTS.md`
+## Quality Validation
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
+
+**Criteria (all must be satisfied)**:
1. **Conversation Analyzed**: Did the agent review the conversation for DeepWork job executions?
2. **Confusion Identified**: Did the agent identify points of confusion, errors, or inefficiencies?
3. **Instructions Improved**: Were job instructions updated to address identified issues?
@@ -393,39 +382,15 @@ This step uses an iterative quality validation loop. After completing your work,
10. **Sync Complete**: Has `deepwork sync` been run if instructions were modified?
-### Completion Promise
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
-To signal that all quality criteria have been met, include this tag in your final response:
+## On Completion
-```
-✓ Quality Criteria Met
-```
-
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
-
-## Completion
-
-After completing this step:
-
-1. **Verify outputs**: Confirm all required files have been created
+1. Verify outputs are created
+2. Inform user: "learn complete, outputs: AGENTS.md"
-2. **Inform the user**:
- - The learn command is complete
- - Outputs created: AGENTS.md
- - This command can be run again anytime to make further changes
-
-## Command Complete
-
-This is a standalone command that can be run anytime. The outputs are ready for use.
-
-Consider:
-- Reviewing the outputs
-- Running `deepwork sync` if job definitions were changed
-- Re-running this command later if further changes are needed
+This standalone skill can be re-run anytime.
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
-- Step instructions: `.deepwork/jobs/deepwork_jobs/steps/learn.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/deepwork_jobs/job.yml`, `.deepwork/jobs/deepwork_jobs/steps/learn.md`
\ No newline at end of file
diff --git a/.claude/skills/deepwork_jobs/SKILL.md b/.claude/skills/deepwork_jobs/SKILL.md
new file mode 100644
index 00000000..aaca12b3
--- /dev/null
+++ b/.claude/skills/deepwork_jobs/SKILL.md
@@ -0,0 +1,61 @@
+---
+name: deepwork_jobs
+description: "DeepWork job management commands"
+---
+
+# deepwork_jobs
+
+**Multi-step workflow**: DeepWork job management commands
+
+> **CRITICAL**: Always invoke steps using the Skill tool. Never copy/paste step instructions directly.
+
+Core commands for managing DeepWork jobs. These commands help you define new multi-step
+workflows and learn from running them.
+
+The `define` command guides you through an interactive process to create a new job by
+asking structured questions about your workflow, understanding each step's inputs and outputs,
+and generating all necessary files.
+
+The `learn` command reflects on conversations where DeepWork jobs were run, identifies
+confusion or inefficiencies, and improves job instructions. It also captures bespoke
+learnings specific to the current run into AGENTS.md files in the working folder.
+
+
+## Available Steps
+
+1. **define** - Create the job.yml specification file by understanding workflow requirements
+2. **implement** - Generate instruction files for each step based on the job.yml specification (requires: define)
+3. **learn** - Reflect on conversation to improve job instructions and capture learnings
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/deepwork_jobs` to determine user intent:
+- "define" or related terms → start at `deepwork_jobs.define`
+- "implement" or related terms → start at `deepwork_jobs.implement`
+- "learn" or related terms → start at `deepwork_jobs.learn`
+
+### Step 2: Invoke Starting Step
+
+Use the Skill tool to invoke the identified starting step:
+```
+Skill tool: deepwork_jobs.define
+```
+
+### Step 3: Continue Workflow Automatically
+
+After each step completes:
+1. Check if there's a next step in the sequence
+2. Invoke the next step using the Skill tool
+3. Repeat until workflow is complete or user intervenes
+
+### Handling Ambiguous Intent
+
+If user intent is unclear, use AskUserQuestion to clarify:
+- Present available steps as numbered options
+- Let user select the starting point
+
+## Context Files
+
+- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
\ No newline at end of file
diff --git a/.claude/commands/uw.deepwork_rules.define.md b/.claude/skills/deepwork_rules.define/SKILL.md
similarity index 85%
rename from .claude/commands/uw.deepwork_rules.define.md
rename to .claude/skills/deepwork_rules.define/SKILL.md
index 148247f2..3788c946 100644
--- a/.claude/commands/uw.deepwork_rules.define.md
+++ b/.claude/skills/deepwork_rules.define/SKILL.md
@@ -1,35 +1,20 @@
---
-description: Create a new rule file in .deepwork/rules/
+name: deepwork_rules.define
+description: "Create a new rule file in .deepwork/rules/"
+user-invocable: false
---
# deepwork_rules.define
-**Standalone command** in the **deepwork_rules** job - can be run anytime
-
-**Summary**: Rules enforcement for AI agent sessions
-
-## Job Overview
-
-Manages rules that automatically trigger when certain files change during an AI agent session.
-Rules help ensure that code changes follow team guidelines, documentation is updated,
-and architectural decisions are respected.
-
-Rules are stored as individual markdown files with YAML frontmatter in the `.deepwork/rules/`
-directory. Each rule file specifies:
-- Detection mode: trigger/safety, set (bidirectional), or pair (directional)
-- Patterns: Glob patterns for matching files, with optional variable capture
-- Instructions: Markdown content describing what the agent should do
-
-Example use cases:
-- Update installation docs when configuration files change
-- Require security review when authentication code is modified
-- Ensure API documentation stays in sync with API code
-- Enforce source/test file pairing
+**Standalone skill** - can be run anytime
+> Rules enforcement for AI agent sessions
## Instructions
+**Goal**: Create a new rule file in .deepwork/rules/
+
# Define Rule
## Objective
@@ -281,59 +266,49 @@ Rules are evaluated automatically when the agent finishes a task. The system:
You can mark a rule as addressed by including `Rule Name` in your response (replace Rule Name with the actual rule name from the `name` field). This tells the system you've already handled that rule's requirements.
-## Inputs
-
-### User Parameters
-
-Please gather the following information from the user:
-- **rule_purpose**: What guideline or constraint should this rule enforce?
+### Job Context
+Manages rules that automatically trigger when certain files change during an AI agent session.
+Rules help ensure that code changes follow team guidelines, documentation is updated,
+and architectural decisions are respected.
-## Work Branch Management
+Rules are stored as individual markdown files with YAML frontmatter in the `.deepwork/rules/`
+directory. Each rule file specifies:
+- Detection mode: trigger/safety, set (bidirectional), or pair (directional)
+- Patterns: Glob patterns for matching files, with optional variable capture
+- Instructions: Markdown content describing what the agent should do
-All work for this job should be done on a dedicated work branch:
+Example use cases:
+- Update installation docs when configuration files change
+- Require security review when authentication code is modified
+- Ensure API documentation stays in sync with API code
+- Enforce source/test file pairing
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/deepwork_rules-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/deepwork_rules-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+## Required Inputs
-## Output Requirements
+**User Parameters** - Gather from user before starting:
+- **rule_purpose**: What guideline or constraint should this rule enforce?
-Create the following output(s):
-- `.deepwork/rules/{rule-name}.md`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
-## Completion
+## Work Branch
-After completing this step:
+Use branch format: `deepwork/deepwork_rules-[instance]-YYYYMMDD`
-1. **Verify outputs**: Confirm all required files have been created
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/deepwork_rules-[instance]-$(date +%Y%m%d)`
-2. **Inform the user**:
- - The define command is complete
- - Outputs created: .deepwork/rules/{rule-name}.md
- - This command can be run again anytime to make further changes
+## Outputs
-## Command Complete
+**Required outputs**:
+- `.deepwork/rules/{rule-name}.md`
+## On Completion
-This is a standalone command that can be run anytime. The outputs are ready for use.
+1. Verify outputs are created
+2. Inform user: "define complete, outputs: .deepwork/rules/{rule-name}.md"
-Consider:
-- Reviewing the outputs
-- Running `deepwork sync` if job definitions were changed
-- Re-running this command later if further changes are needed
+This standalone skill can be re-run anytime.
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_rules/job.yml`
-- Step instructions: `.deepwork/jobs/deepwork_rules/steps/define.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/deepwork_rules/job.yml`, `.deepwork/jobs/deepwork_rules/steps/define.md`
\ No newline at end of file
diff --git a/.claude/skills/deepwork_rules/SKILL.md b/.claude/skills/deepwork_rules/SKILL.md
new file mode 100644
index 00000000..d391af84
--- /dev/null
+++ b/.claude/skills/deepwork_rules/SKILL.md
@@ -0,0 +1,62 @@
+---
+name: deepwork_rules
+description: "Rules enforcement for AI agent sessions"
+---
+
+# deepwork_rules
+
+**Multi-step workflow**: Rules enforcement for AI agent sessions
+
+> **CRITICAL**: Always invoke steps using the Skill tool. Never copy/paste step instructions directly.
+
+Manages rules that automatically trigger when certain files change during an AI agent session.
+Rules help ensure that code changes follow team guidelines, documentation is updated,
+and architectural decisions are respected.
+
+Rules are stored as individual markdown files with YAML frontmatter in the `.deepwork/rules/`
+directory. Each rule file specifies:
+- Detection mode: trigger/safety, set (bidirectional), or pair (directional)
+- Patterns: Glob patterns for matching files, with optional variable capture
+- Instructions: Markdown content describing what the agent should do
+
+Example use cases:
+- Update installation docs when configuration files change
+- Require security review when authentication code is modified
+- Ensure API documentation stays in sync with API code
+- Enforce source/test file pairing
+
+
+## Available Steps
+
+1. **define** - Create a new rule file in .deepwork/rules/
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/deepwork_rules` to determine user intent:
+- "define" or related terms → start at `deepwork_rules.define`
+
+### Step 2: Invoke Starting Step
+
+Use the Skill tool to invoke the identified starting step:
+```
+Skill tool: deepwork_rules.define
+```
+
+### Step 3: Continue Workflow Automatically
+
+After each step completes:
+1. Check if there's a next step in the sequence
+2. Invoke the next step using the Skill tool
+3. Repeat until workflow is complete or user intervenes
+
+### Handling Ambiguous Intent
+
+If user intent is unclear, use AskUserQuestion to clarify:
+- Present available steps as numbered options
+- Let user select the starting point
+
+## Context Files
+
+- Job definition: `.deepwork/jobs/deepwork_rules/job.yml`
\ No newline at end of file
diff --git a/.claude/commands/uw.update.job.md b/.claude/skills/update.job/SKILL.md
similarity index 62%
rename from .claude/commands/uw.update.job.md
rename to .claude/skills/update.job/SKILL.md
index 6a30da15..331d0874 100644
--- a/.claude/commands/uw.update.job.md
+++ b/.claude/skills/update.job/SKILL.md
@@ -1,5 +1,7 @@
---
-description: Edit standard job source files and sync to installed locations
+name: update.job
+description: "Edit standard job source files and sync to installed locations"
+user-invocable: false
hooks:
Stop:
- hooks:
@@ -16,30 +18,15 @@ hooks:
# update.job
-**Standalone command** in the **update** job - can be run anytime
-
-**Summary**: Update standard jobs in src/ and sync to installed locations
-
-## Job Overview
-
-A workflow for maintaining standard jobs bundled with DeepWork. Standard jobs
-(like `deepwork_jobs` and `deepwork_rules`) are source-controlled in
-`src/deepwork/standard_jobs/` and must be edited there—never in `.deepwork/jobs/`
-or `.claude/commands/` directly.
-
-This job guides you through:
-1. Identifying which standard job(s) to update from conversation context
-2. Making changes in the correct source location (`src/deepwork/standard_jobs/[job_name]/`)
-3. Running `deepwork install` to propagate changes to `.deepwork/` and command directories
-4. Verifying the sync completed successfully
-
-Use this job whenever you need to modify job.yml files, step instructions, or hooks
-for any standard job in the DeepWork repository.
+**Standalone skill** - can be run anytime
+> Update standard jobs in src/ and sync to installed locations
## Instructions
+**Goal**: Edit standard job source files and sync to installed locations
+
# Update Standard Job
## Objective
@@ -115,70 +102,55 @@ ls -la .claude/commands/[job_name].*.md
- When all criteria are met, include `✓ Quality Criteria Met`
-## Inputs
+### Job Context
-### User Parameters
-
-Please gather the following information from the user:
-- **job_context**: Determine from conversation context which standard job(s) to update and what changes are needed
-
-
-## Work Branch Management
-
-All work for this job should be done on a dedicated work branch:
+A workflow for maintaining standard jobs bundled with DeepWork. Standard jobs
+(like `deepwork_jobs` and `deepwork_rules`) are source-controlled in
+`src/deepwork/standard_jobs/` and must be edited there—never in `.deepwork/jobs/`
+or `.claude/commands/` directly.
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/update-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+This job guides you through:
+1. Identifying which standard job(s) to update from conversation context
+2. Making changes in the correct source location (`src/deepwork/standard_jobs/[job_name]/`)
+3. Running `deepwork install` to propagate changes to `.deepwork/` and command directories
+4. Verifying the sync completed successfully
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/update-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+Use this job whenever you need to modify job.yml files, step instructions, or hooks
+for any standard job in the DeepWork repository.
-## Output Requirements
-No specific files are output by this command.
+## Required Inputs
-## Quality Validation Loop
+**User Parameters** - Gather from user before starting:
+- **job_context**: Determine from conversation context which standard job(s) to update and what changes are needed
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
+## Work Branch
+Use branch format: `deepwork/update-[instance]-YYYYMMDD`
-### Completion Promise
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/update-[instance]-$(date +%Y%m%d)`
-To signal that all quality criteria have been met, include this tag in your final response:
+## Outputs
-```
-✓ Quality Criteria Met
-```
+No specific file outputs required.
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
+## Quality Validation
-## Completion
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
-After completing this step:
-1. **Verify outputs**: Confirm all required files have been created
-2. **Inform the user**:
- - The job command is complete
- - This command can be run again anytime to make further changes
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
-## Command Complete
+## On Completion
-This is a standalone command that can be run anytime. The outputs are ready for use.
+1. Verify outputs are created
+2. Inform user: "job complete"
-Consider:
-- Reviewing the outputs
-- Running `deepwork sync` if job definitions were changed
-- Re-running this command later if further changes are needed
+This standalone skill can be re-run anytime.
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/update/job.yml`
-- Step instructions: `.deepwork/jobs/update/steps/job.md`
\ No newline at end of file
+**Reference files**: `.deepwork/jobs/update/job.yml`, `.deepwork/jobs/update/steps/job.md`
\ No newline at end of file
diff --git a/.claude/skills/update/SKILL.md b/.claude/skills/update/SKILL.md
new file mode 100644
index 00000000..b0cf11f9
--- /dev/null
+++ b/.claude/skills/update/SKILL.md
@@ -0,0 +1,60 @@
+---
+name: update
+description: "Update standard jobs in src/ and sync to installed locations"
+---
+
+# update
+
+**Multi-step workflow**: Update standard jobs in src/ and sync to installed locations
+
+> **CRITICAL**: Always invoke steps using the Skill tool. Never copy/paste step instructions directly.
+
+A workflow for maintaining standard jobs bundled with DeepWork. Standard jobs
+(like `deepwork_jobs` and `deepwork_rules`) are source-controlled in
+`src/deepwork/standard_jobs/` and must be edited there—never in `.deepwork/jobs/`
+or `.claude/commands/` directly.
+
+This job guides you through:
+1. Identifying which standard job(s) to update from conversation context
+2. Making changes in the correct source location (`src/deepwork/standard_jobs/[job_name]/`)
+3. Running `deepwork install` to propagate changes to `.deepwork/` and command directories
+4. Verifying the sync completed successfully
+
+Use this job whenever you need to modify job.yml files, step instructions, or hooks
+for any standard job in the DeepWork repository.
+
+
+## Available Steps
+
+1. **job** - Edit standard job source files and sync to installed locations
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/update` to determine user intent:
+- "job" or related terms → start at `update.job`
+
+### Step 2: Invoke Starting Step
+
+Use the Skill tool to invoke the identified starting step:
+```
+Skill tool: update.job
+```
+
+### Step 3: Continue Workflow Automatically
+
+After each step completes:
+1. Check if there's a next step in the sequence
+2. Invoke the next step using the Skill tool
+3. Repeat until workflow is complete or user intervenes
+
+### Handling Ambiguous Intent
+
+If user intent is unclear, use AskUserQuestion to clarify:
+- Present available steps as numbered options
+- Let user select the starting point
+
+## Context Files
+
+- Job definition: `.deepwork/jobs/update/job.yml`
\ No newline at end of file
diff --git a/.deepwork/jobs/commit/job.yml b/.deepwork/jobs/commit/job.yml
new file mode 100644
index 00000000..e33923bf
--- /dev/null
+++ b/.deepwork/jobs/commit/job.yml
@@ -0,0 +1,73 @@
+name: commit
+version: "1.0.0"
+summary: "Run tests, lint, and commit code changes"
+description: |
+ A workflow for preparing and committing code changes with quality checks.
+
+ This job runs tests until they pass, formats and lints code with ruff,
+ then reviews changed files before committing and pushing. The lint step
+ uses a sub-agent to reduce context usage.
+
+ Steps:
+ 1. test - Pull latest code and run tests until they pass
+ 2. lint - Format and lint code with ruff (runs in sub-agent)
+ 3. commit_and_push - Review changes and commit/push
+
+changelog:
+ - version: "1.0.0"
+ changes: "Initial job creation"
+
+steps:
+ - id: test
+ name: "Run Tests"
+ description: "Pull latest code and run the test suite until all tests pass"
+ instructions_file: steps/test.md
+ inputs:
+ - name: test_command
+ description: "Test command to run (optional - will auto-detect if not provided)"
+ outputs: []
+ dependencies: []
+ hooks:
+ after_agent:
+ - prompt: |
+ Verify the tests are passing:
+ 1. Latest code was pulled from the branch
+ 2. All tests completed successfully
+ 3. No test failures or errors remain
+ 4. Test output shows passing status
+ If ALL criteria are met, include `✓ Quality Criteria Met`.
+
+ - id: lint
+ name: "Lint Code"
+ description: "Format and lint code with ruff using a sub-agent"
+ instructions_file: steps/lint.md
+ inputs: []
+ outputs: []
+ dependencies:
+ - test
+ hooks:
+ after_agent:
+ - prompt: |
+ Verify the linting is complete:
+ 1. ruff format was run successfully
+ 2. ruff check was run successfully (with --fix)
+ 3. No remaining lint errors
+ If ALL criteria are met, include `✓ Quality Criteria Met`.
+
+ - id: commit_and_push
+ name: "Commit and Push"
+ description: "Review changed files, commit, and push to remote"
+ instructions_file: steps/commit_and_push.md
+ inputs: []
+ outputs: []
+ dependencies:
+ - lint
+ hooks:
+ after_agent:
+ - prompt: |
+ Verify the commit is ready:
+ 1. Changed files list was reviewed with user
+ 2. User confirmed the files match expectations
+ 3. Commit was created with appropriate message
+ 4. Changes were pushed to remote
+ If ALL criteria are met, include `✓ Quality Criteria Met`.
diff --git a/.deepwork/jobs/commit/steps/commit_and_push.md b/.deepwork/jobs/commit/steps/commit_and_push.md
new file mode 100644
index 00000000..d82d60f4
--- /dev/null
+++ b/.deepwork/jobs/commit/steps/commit_and_push.md
@@ -0,0 +1,81 @@
+# Commit and Push
+
+## Objective
+
+Review the changed files with the user, create a commit with an appropriate message, and push to the remote repository.
+
+## Task
+
+Present the list of changed files for user review, ensure they match expectations, then commit and push the changes.
+
+### Process
+
+1. **Get the list of changed files**
+ ```bash
+ git status
+ ```
+ Also run `git diff --stat` to see a summary of changes.
+
+2. **Present changes to the user for review**
+
+ Use the AskUserQuestion tool to ask structured questions about the changes:
+
+ Show the user:
+ - List of modified files
+ - List of new files
+ - List of deleted files
+ - Summary of changes (lines added/removed)
+
+ Ask them to confirm:
+ - "Do these changed files match your expectations?"
+ - Provide options: "Yes, proceed with commit" / "No, let me review first" / "No, some files shouldn't be included"
+
+3. **Handle user response**
+
+ - If user confirms, proceed to commit
+ - If user wants to review first, wait for them to come back
+ - If user says some files shouldn't be included, ask which files to exclude and use `git restore` or `git checkout` to unstage them
+
+4. **Stage all appropriate changes**
+ ```bash
+ git add -A
+ ```
+ Or stage specific files if user excluded some.
+
+5. **View recent commit messages for style reference**
+ ```bash
+ git log --oneline -10
+ ```
+
+6. **Create the commit**
+
+ Generate an appropriate commit message based on:
+ - The changes made
+ - The style of recent commits
+ - Conventional commit format if the project uses it
+
+ ```bash
+ git commit -m "commit message here"
+ ```
+
+7. **Push to remote**
+ ```bash
+ git push
+ ```
+ If the branch has no upstream, use:
+ ```bash
+ git push -u origin HEAD
+ ```
+
+## Quality Criteria
+
+- Changed files list was presented to user
+- User explicitly confirmed the files match expectations
+- Commit message follows project conventions
+- Commit was created successfully
+- Changes were pushed to remote
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This is the final step of the commit workflow. It ensures the user has reviewed and approved the changes before they are committed and pushed. This prevents accidental commits of unintended files or changes.
diff --git a/.deepwork/jobs/commit/steps/lint.md b/.deepwork/jobs/commit/steps/lint.md
new file mode 100644
index 00000000..a94e8c21
--- /dev/null
+++ b/.deepwork/jobs/commit/steps/lint.md
@@ -0,0 +1,72 @@
+# Lint Code
+
+## Objective
+
+Format and lint the codebase using ruff to ensure code quality and consistency.
+
+## Task
+
+Run ruff format and ruff check to format and lint the code. This step should be executed using a sub-agent to conserve context in the main conversation.
+
+### Process
+
+**IMPORTANT**: Use the Task tool to spawn a sub-agent for this work. This saves context in the main conversation. Use the `haiku` model for speed.
+
+1. **Spawn a sub-agent to run linting**
+
+ Use the Task tool with these parameters:
+ - `subagent_type`: "Bash"
+ - `model`: "haiku"
+ - `prompt`: See below
+
+ The sub-agent should:
+
+ a. **Run ruff format**
+ ```bash
+ ruff format .
+ ```
+ This formats the code according to ruff's style rules.
+
+ b. **Run ruff check with auto-fix**
+ ```bash
+ ruff check --fix .
+ ```
+ This checks for lint errors and automatically fixes what it can.
+
+ c. **Run ruff check again to verify**
+ ```bash
+ ruff check .
+ ```
+ Capture the final output to verify no remaining issues.
+
+2. **Review sub-agent results**
+ - Check that both format and check completed successfully
+ - Note any remaining lint issues that couldn't be auto-fixed
+
+3. **Handle remaining issues**
+ - If there are lint errors that couldn't be auto-fixed, fix them manually
+ - Re-run ruff check to verify
+
+## Example Sub-Agent Prompt
+
+```
+Run ruff to format and lint the codebase:
+
+1. Run: ruff format .
+2. Run: ruff check --fix .
+3. Run: ruff check . (to verify no remaining issues)
+
+Report the results of each command.
+```
+
+## Quality Criteria
+
+- ruff format was run successfully
+- ruff check was run with --fix flag
+- No remaining lint errors (or all are documented and intentional)
+- Sub-agent was used to conserve context
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This step ensures code quality and consistency before committing. It runs after tests pass and before the commit step. Using a sub-agent keeps the main conversation context clean for the commit review.
diff --git a/.deepwork/jobs/commit/steps/test.md b/.deepwork/jobs/commit/steps/test.md
new file mode 100644
index 00000000..bfe7a327
--- /dev/null
+++ b/.deepwork/jobs/commit/steps/test.md
@@ -0,0 +1,53 @@
+# Run Tests
+
+## Objective
+
+Run the project's test suite and fix any failing tests until all tests pass.
+
+## Task
+
+Execute the test suite for the project and iteratively fix any failures until all tests pass.
+
+### Process
+
+1. **Pull latest code from the branch**
+ - Run `git pull` to fetch and merge any changes from the remote
+ - If there are merge conflicts, resolve them before proceeding
+ - This ensures you're testing against the latest code
+
+2. **Detect or use the test command**
+ - If a test command was provided, use that
+ - Otherwise, auto-detect the project type and determine the appropriate test command:
+ - Python: `pytest`, `python -m pytest`, `uv run pytest`
+ - Node.js: `npm test`, `yarn test`, `bun test`
+ - Go: `go test ./...`
+ - Rust: `cargo test`
+ - Check `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod` for hints
+
+3. **Run the tests**
+ - Execute the test command
+ - Capture the output
+
+4. **Analyze failures**
+ - If tests pass, proceed to output
+ - If tests fail, analyze the failure messages
+ - Identify the root cause of each failure
+
+5. **Fix failing tests**
+ - Make the necessary code changes to fix failures
+ - This may involve fixing bugs in implementation code or updating tests
+ - Re-run tests after each fix
+
+6. **Iterate until passing**
+ - Continue the fix/test cycle until all tests pass
+
+## Quality Criteria
+
+- Latest code was pulled from the branch
+- Test command was correctly identified or used from input
+- All tests are now passing
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This is the first step of the commit workflow. Tests must pass before proceeding to lint and commit. This ensures code quality and prevents broken code from being committed.
diff --git a/.deepwork/jobs/deepwork_jobs/steps/implement.md b/.deepwork/jobs/deepwork_jobs/steps/implement.md
index 7771eaee..34caed9f 100644
--- a/.deepwork/jobs/deepwork_jobs/steps/implement.md
+++ b/.deepwork/jobs/deepwork_jobs/steps/implement.md
@@ -113,9 +113,9 @@ See `.deepwork/jobs/deepwork_jobs/steps/supplemental_file_references.md` for det
Verify that `job.yml` is in the correct location at `.deepwork/jobs/[job_name]/job.yml`. The define step should have created it there. If for some reason it's not there, you may need to create or move it.
-### Step 5: Sync Commands
+### Step 5: Sync Skills
-Run `deepwork sync` to generate the slash-commands for this job:
+Run `deepwork sync` to generate the skills for this job:
```bash
deepwork sync
@@ -123,12 +123,12 @@ deepwork sync
This will:
- Parse the job definition
-- Generate slash-commands for each step
-- Make the commands available in `.claude/commands/` (or appropriate platform directory)
+- Generate skills for each step
+- Make the skills available in `.claude/skills/` (or appropriate platform directory)
### Step 6: Relay Reload Instructions
-After running `deepwork sync`, look at the "To use the new commands" section in the output. **Relay these exact reload instructions to the user** so they know how to pick up the new commands. Don't just reference the sync output - tell them directly what they need to do (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code, or "Run '/memory refresh'" for Gemini CLI).
+After running `deepwork sync`, look at the "To use the new skills" section in the output. **Relay these exact reload instructions to the user** so they know how to pick up the new skills. Don't just reference the sync output - tell them directly what they need to do (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code, or "Run '/memory refresh'" for Gemini CLI).
### Step 7: Consider Rules for the New Job
@@ -220,7 +220,7 @@ Before marking this step complete, ensure:
- [ ] All step instruction files created
- [ ] Each instruction file is complete and actionable
- [ ] `deepwork sync` executed successfully
-- [ ] Commands generated in platform directory
+- [ ] Skills generated in platform directory
- [ ] User informed to follow reload instructions from `deepwork sync`
- [ ] Considered whether rules would benefit this job (Step 7)
- [ ] If rules suggested, offered to run `/deepwork_rules.define`
@@ -234,5 +234,5 @@ Before marking this step complete, ensure:
- Quality criteria defined for each step
- Steps with user inputs explicitly use "ask structured questions" phrasing
- Sync completed successfully
-- Commands available for use
+- Skills available for use
- Thoughtfully considered relevant rules for the job domain
diff --git a/.deepwork/jobs/deepwork_jobs/steps/learn.md b/.deepwork/jobs/deepwork_jobs/steps/learn.md
index 36bfd8c7..f89a8873 100644
--- a/.deepwork/jobs/deepwork_jobs/steps/learn.md
+++ b/.deepwork/jobs/deepwork_jobs/steps/learn.md
@@ -171,7 +171,7 @@ If instruction files were modified:
deepwork sync
```
-2. **If commands were regenerated**, look at the "To use the new commands" section in the `deepwork sync` output and **relay these exact reload instructions to the user** (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code)
+2. **If skills were regenerated**, look at the "To use the new skills" section in the `deepwork sync` output and **relay these exact reload instructions to the user** (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code)
## File Reference Patterns
@@ -261,7 +261,7 @@ I found the following job executions:
**Summary**
-Updated job instructions and created AGENTS.md with bespoke learnings. To get the updated commands, type 'exit' then run 'claude --resume'.
+Updated job instructions and created AGENTS.md with bespoke learnings. To get the updated skills, type 'exit' then run 'claude --resume'.
```
## Handling Edge Cases
diff --git a/.deepwork/jobs/deepwork_rules/rules/skill-md-validation.md b/.deepwork/jobs/deepwork_rules/rules/skill-md-validation.md
new file mode 100644
index 00000000..6f7cb3d2
--- /dev/null
+++ b/.deepwork/jobs/deepwork_rules/rules/skill-md-validation.md
@@ -0,0 +1,45 @@
+---
+name: SKILL.md Validation
+trigger: "**/SKILL.md"
+---
+A SKILL.md file has been created or modified. Please validate that it follows the required format:
+
+## Required Structure
+
+The file MUST have valid YAML frontmatter at the start, enclosed between `---` markers:
+
+```markdown
+---
+name: my-skill-name
+description: A description of what this skill does
+---
+
+# Rest of the skill documentation...
+```
+
+## Validation Checklist
+
+1. **YAML Frontmatter**: Verify the file starts with `---` followed by valid YAML and ends with `---`
+
+2. **`name` field** (required):
+ - Must be present in the frontmatter
+ - Must contain only lowercase letters, numbers, and hyphens (`a-z`, `0-9`, `-`)
+ - Must be 64 characters or fewer
+ - Example valid names: `my-skill`, `code-review-2`, `lint`
+ - Example invalid names: `My Skill` (uppercase/spaces), `skill_name` (underscores), `SKILL` (uppercase)
+
+3. **`description` field** (required):
+ - Must be present in the frontmatter
+ - Must be 1024 characters or fewer
+ - Should clearly describe what the skill does
+
+## What to Check
+
+For the modified file: {trigger_files}
+
+1. Parse the YAML frontmatter and verify it is valid YAML
+2. Check that `name` exists and matches the pattern `^[a-z0-9-]+$` with max length 64
+3. Check that `description` exists and is at most 1024 characters
+4. Report any validation errors to the user
+
+If the file does not pass validation, help the user fix the issues.
diff --git a/.deepwork/rules/skill-template-best-practices.md b/.deepwork/rules/skill-template-best-practices.md
new file mode 100644
index 00000000..ff33ecfd
--- /dev/null
+++ b/.deepwork/rules/skill-template-best-practices.md
@@ -0,0 +1,46 @@
+---
+name: Skill Template Best Practices
+trigger: src/deepwork/templates/**/skill-job*.jinja
+compare_to: prompt
+---
+Skill template files are being modified. Ensure the generated skills follow these best practices:
+
+## Description Guidelines
+
+The description appears in skill search results and helps users find the right skill. Keep it search-friendly and scannable.
+
+1. **Be specific** - Name exact capabilities/actions the skill performs
+2. **Keep concise** - One sentence, max ~100 chars; describes WHAT it does, not HOW
+3. **Avoid vagueness** - "Extract text from PDFs, fill forms" is good; "Helps with documents" is bad
+4. **Avoid meta-language** - Don't include "Trigger:", "Keywords:", or similar prefixes. Let the description itself be searchable.
+
+## Instruction Writing
+
+1. **Keep focused** - Core instructions should be under 500 lines; use supporting files for details
+2. **Use progressive disclosure** - Essential info in main content, detailed reference in linked files
+3. **Be explicit** - Provide clear, step-by-step guidance rather than relying on inference
+4. **Structure clearly** - Use headers, numbered lists for sequential steps, bullets for options
+
+## Prompt Structure
+
+1. **Specificity first** - Detailed directions upfront prevent course corrections later
+2. **Plan before action** - Ask agent to analyze/plan before implementing
+3. **Reference concrete files** - Use specific paths, not general descriptions
+4. **Include context** - Mention edge cases, preferred patterns, and expected outcomes
+
+## Quality Criteria
+
+1. **Make measurable** - Criteria should be verifiable, not subjective
+2. **Focus on outcomes** - What the output should achieve, not process steps
+3. **Keep actionable** - Agent should be able to self-evaluate against criteria
+
+## Platform Considerations
+
+- **Claude**: Supports hooks for automated validation; use Skill tool for step invocation
+- **Gemini**: No hook support; instructions must guide manual verification
+
+## Reference Documentation
+
+When unsure about best practices, consult:
+- https://code.claude.com/docs/en/skills - Official skills documentation
+- https://www.anthropic.com/engineering/claude-code-best-practices - Prompting best practices
diff --git a/.gemini/commands/add_platform/index.toml b/.gemini/commands/add_platform/index.toml
deleted file mode 100644
index b46ed1fc..00000000
--- a/.gemini/commands/add_platform/index.toml
+++ /dev/null
@@ -1,84 +0,0 @@
-# add_platform
-#
-# Add a new AI platform to DeepWork with adapter, templates, and tests
-#
-# Generated by DeepWork - do not edit manually
-
-description = "Add a new AI platform to DeepWork with adapter, templates, and tests"
-
-prompt = """
-# add_platform
-
-You are executing the **add_platform** job. Add a new AI platform to DeepWork with adapter, templates, and tests
-
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
-
-
-## Available Steps
-
-This job has 4 step(s):
-
-### research
-**Research Platform Documentation**: Capture CLI configuration and hooks system documentation for the new platform
-- Command: `/add_platform:uw.research`
-### add_capabilities
-**Add Hook Capabilities**: Update job schema and adapters with any new hook events the platform supports
-- Command: `/add_platform:uw.add_capabilities`
-- Requires: research
-### implement
-**Implement Platform Support**: Add platform adapter, templates, tests with 100% coverage, and README documentation
-- Command: `/add_platform:uw.implement`
-- Requires: research, add_capabilities
-### verify
-**Verify Installation**: Set up platform directories and verify deepwork install works correctly
-- Command: `/add_platform:uw.verify`
-- Requires: implement
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and guide the user through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/add_platform`
-
-2. **Identify the starting step** based on intent:
- - research: Capture CLI configuration and hooks system documentation for the new platform
- - add_capabilities: Update job schema and adapters with any new hook events the platform supports
- - implement: Add platform adapter, templates, tests with 100% coverage, and README documentation
- - verify: Set up platform directories and verify deepwork install works correctly
-
-3. **Guide the user through the workflow**:
- - Tell the user to run the starting step command
- - After each step completes, guide them to the next step in the workflow
- - Continue until the workflow is complete
-
- Step commands:
- - research: `/add_platform:uw.research`
- - add_capabilities: `/add_platform:uw.add_capabilities`
- - implement: `/add_platform:uw.implement`
- - verify: `/add_platform:uw.verify`
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Let them choose
-
-**Note**: Gemini CLI requires manual command invocation. After each step completes, remind the user to run the next step command.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-"""
\ No newline at end of file
diff --git a/.gemini/commands/deepwork_jobs/index.toml b/.gemini/commands/deepwork_jobs/index.toml
deleted file mode 100644
index 7ab8bcf4..00000000
--- a/.gemini/commands/deepwork_jobs/index.toml
+++ /dev/null
@@ -1,71 +0,0 @@
-# deepwork_jobs
-#
-# DeepWork job management commands
-#
-# Generated by DeepWork - do not edit manually
-
-description = "DeepWork job management commands"
-
-prompt = """
-# deepwork_jobs
-
-You are executing the **deepwork_jobs** job. DeepWork job management commands
-
-Core commands for managing DeepWork jobs. These commands help you define new multi-step
-workflows and learn from running them.
-
-The `define` command guides you through an interactive process to create a new job by
-asking structured questions about your workflow, understanding each step's inputs and outputs,
-and generating all necessary files.
-
-The `learn` command reflects on conversations where DeepWork jobs were run, identifies
-confusion or inefficiencies, and improves job instructions. It also captures bespoke
-learnings specific to the current run into AGENTS.md files in the working folder.
-
-
-## Available Steps
-
-This job has 3 step(s):
-
-### define
-**Define Job Specification**: Create the job.yml specification file by understanding workflow requirements
-- Command: `/deepwork_jobs:uw.define`
-### implement
-**Implement Job Steps**: Generate instruction files for each step based on the job.yml specification
-- Command: `/deepwork_jobs:uw.implement`
-- Requires: define
-### learn
-**Learn from Job Execution**: Reflect on conversation to improve job instructions and capture learnings
-- Command: `/deepwork_jobs:learn`
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and guide the user through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/deepwork_jobs`
-
-2. **Identify the starting step** based on intent:
- - define: Create the job.yml specification file by understanding workflow requirements
- - implement: Generate instruction files for each step based on the job.yml specification
- - learn: Reflect on conversation to improve job instructions and capture learnings
-
-3. **Guide the user through the workflow**:
- - Tell the user to run the starting step command
- - After each step completes, guide them to the next step in the workflow
- - Continue until the workflow is complete
-
- Step commands:
- - define: `/deepwork_jobs:uw.define`
- - implement: `/deepwork_jobs:uw.implement`
- - learn: `/deepwork_jobs:learn`
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Let them choose
-
-**Note**: Gemini CLI requires manual command invocation. After each step completes, remind the user to run the next step command.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
-"""
\ No newline at end of file
diff --git a/.gemini/commands/update/index.toml b/.gemini/commands/update/index.toml
deleted file mode 100644
index f564b188..00000000
--- a/.gemini/commands/update/index.toml
+++ /dev/null
@@ -1,63 +0,0 @@
-# update
-#
-# Update standard jobs in src/ and sync to installed locations
-#
-# Generated by DeepWork - do not edit manually
-
-description = "Update standard jobs in src/ and sync to installed locations"
-
-prompt = """
-# update
-
-You are executing the **update** job. Update standard jobs in src/ and sync to installed locations
-
-A workflow for maintaining standard jobs bundled with DeepWork. Standard jobs
-(like `deepwork_jobs` and `deepwork_rules`) are source-controlled in
-`src/deepwork/standard_jobs/` and must be edited there—never in `.deepwork/jobs/`
-or `.claude/commands/` directly.
-
-This job guides you through:
-1. Identifying which standard job(s) to update from conversation context
-2. Making changes in the correct source location (`src/deepwork/standard_jobs/[job_name]/`)
-3. Running `deepwork install` to propagate changes to `.deepwork/` and command directories
-4. Verifying the sync completed successfully
-
-Use this job whenever you need to modify job.yml files, step instructions, or hooks
-for any standard job in the DeepWork repository.
-
-
-## Available Steps
-
-This job has 1 step(s):
-
-### job
-**Update Standard Job**: Edit standard job source files and sync to installed locations
-- Command: `/update:uw.job`
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and guide the user through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/update`
-
-2. **Identify the starting step** based on intent:
- - job: Edit standard job source files and sync to installed locations
-
-3. **Guide the user through the workflow**:
- - Tell the user to run the starting step command
- - After each step completes, guide them to the next step in the workflow
- - Continue until the workflow is complete
-
- Step commands:
- - job: `/update:uw.job`
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Let them choose
-
-**Note**: Gemini CLI requires manual command invocation. After each step completes, remind the user to run the next step command.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/update/job.yml`
-"""
\ No newline at end of file
diff --git a/.gemini/commands/add_platform/uw.add_capabilities.toml b/.gemini/skills/add_platform/add_capabilities.toml
similarity index 79%
rename from .gemini/commands/add_platform/uw.add_capabilities.toml
rename to .gemini/skills/add_platform/add_capabilities.toml
index da2fec82..24f65e42 100644
--- a/.gemini/commands/add_platform/uw.add_capabilities.toml
+++ b/.gemini/skills/add_platform/add_capabilities.toml
@@ -9,39 +9,19 @@ description = "Update job schema and adapters with any new hook events the platf
prompt = """
# add_platform:add_capabilities
-**Step 2 of 4** in the **add_platform** workflow
+**Step 2/4** in **add_platform** workflow
-**Summary**: Add a new AI platform to DeepWork with adapter, templates, and tests
+> Add a new AI platform to DeepWork with adapter, templates, and tests
-## Job Overview
+## Prerequisites (Verify First)
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
-
-
-## Prerequisites
-
-This step requires completion of the following step(s):
+Before proceeding, confirm these steps are complete:
- `/add_platform:research`
-Please ensure these steps have been completed before proceeding.
-
## Instructions
+**Goal**: Update job schema and adapters with any new hook events the platform supports
+
# Add Hook Capabilities
## Objective
@@ -179,62 +159,50 @@ For reference, here are common hook patterns across platforms:
When you find a new hook type, consider whether it maps to an existing pattern or is genuinely new functionality.
-## Inputs
-
-
-### Required Files
+### Job Context
-This step requires the following files from previous steps:
-- `hooks_system.md` (from step `research`)
-
-Make sure to read and use these files as context for this step.
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-## Work Branch Management
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
-All work for this job should be done on a dedicated work branch:
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/add_platform-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-## Output Requirements
+## Required Inputs
-Create the following output(s):
-- `job_schema.py`
-- `adapters.py`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+**Files from Previous Steps** - Read these first:
+- `hooks_system.md` (from `research`)
-## Completion
+## Work Branch
-After completing this step:
+Use branch format: `deepwork/add_platform-[instance]-YYYYMMDD`
-1. **Verify outputs**: Confirm all required files have been created
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)`
-2. **Inform the user**:
- - Step 2 of 4 is complete
- - Outputs created: job_schema.py, adapters.py
- - Ready to proceed to next step: `/add_platform:implement`
+## Outputs
-## Next Step
+**Required outputs**:
+- `job_schema.py`- `adapters.py`
+## On Completion
-To continue the workflow, run:
-```
-/add_platform:implement
-```
+1. Verify outputs are created
+2. Inform user: "Step 2/4 complete, outputs: job_schema.py, adapters.py"
+3. **Tell user next command**: `/add_platform:implement`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-- Step instructions: `.deepwork/jobs/add_platform/steps/add_capabilities.md`
+**Reference files**: `.deepwork/jobs/add_platform/job.yml`, `.deepwork/jobs/add_platform/steps/add_capabilities.md`
"""
\ No newline at end of file
diff --git a/.gemini/commands/add_platform/uw.implement.toml b/.gemini/skills/add_platform/implement.toml
similarity index 81%
rename from .gemini/commands/add_platform/uw.implement.toml
rename to .gemini/skills/add_platform/implement.toml
index 4c348a38..d3c86e28 100644
--- a/.gemini/commands/add_platform/uw.implement.toml
+++ b/.gemini/skills/add_platform/implement.toml
@@ -9,40 +9,20 @@ description = "Add platform adapter, templates, tests with 100% coverage, and RE
prompt = """
# add_platform:implement
-**Step 3 of 4** in the **add_platform** workflow
+**Step 3/4** in **add_platform** workflow
-**Summary**: Add a new AI platform to DeepWork with adapter, templates, and tests
+> Add a new AI platform to DeepWork with adapter, templates, and tests
-## Job Overview
+## Prerequisites (Verify First)
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
-
-
-## Prerequisites
-
-This step requires completion of the following step(s):
+Before proceeding, confirm these steps are complete:
- `/add_platform:research`
- `/add_platform:add_capabilities`
-Please ensure these steps have been completed before proceeding.
-
## Instructions
+**Goal**: Add platform adapter, templates, tests with 100% coverage, and README documentation
+
# Implement Platform Support
## Objective
@@ -271,65 +251,52 @@ The templates use Jinja2 and should produce files that match exactly what the pl
- Template syntax errors often show up at runtime - test early
-## Inputs
+### Job Context
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-### Required Files
-
-This step requires the following files from previous steps:
-- `job_schema.py` (from step `add_capabilities`)
-- `adapters.py` (from step `add_capabilities`)
-- `cli_configuration.md` (from step `research`)
-
-Make sure to read and use these files as context for this step.
-
-## Work Branch Management
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
-All work for this job should be done on a dedicated work branch:
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/add_platform-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-## Output Requirements
+## Required Inputs
-Create the following output(s):
-- `templates/` (directory)
-- `tests/` (directory)
-- `README.md`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+**Files from Previous Steps** - Read these first:
+- `job_schema.py` (from `add_capabilities`)
+- `adapters.py` (from `add_capabilities`)
+- `cli_configuration.md` (from `research`)
-## Completion
+## Work Branch
-After completing this step:
+Use branch format: `deepwork/add_platform-[instance]-YYYYMMDD`
-1. **Verify outputs**: Confirm all required files have been created
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)`
-2. **Inform the user**:
- - Step 3 of 4 is complete
- - Outputs created: templates/, tests/, README.md
- - Ready to proceed to next step: `/add_platform:verify`
+## Outputs
-## Next Step
+**Required outputs**:
+- `templates/` (directory)- `tests/` (directory)- `README.md`
+## On Completion
-To continue the workflow, run:
-```
-/add_platform:verify
-```
+1. Verify outputs are created
+2. Inform user: "Step 3/4 complete, outputs: templates/, tests/, README.md"
+3. **Tell user next command**: `/add_platform:verify`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-- Step instructions: `.deepwork/jobs/add_platform/steps/implement.md`
+**Reference files**: `.deepwork/jobs/add_platform/job.yml`, `.deepwork/jobs/add_platform/steps/implement.md`
"""
\ No newline at end of file
diff --git a/.gemini/skills/add_platform/index.toml b/.gemini/skills/add_platform/index.toml
new file mode 100644
index 00000000..ff3c4ce3
--- /dev/null
+++ b/.gemini/skills/add_platform/index.toml
@@ -0,0 +1,75 @@
+# add_platform
+#
+# Add a new AI platform to DeepWork with adapter, templates, and tests
+#
+# Generated by DeepWork - do not edit manually
+
+description = "Add a new AI platform to DeepWork with adapter, templates, and tests"
+
+prompt = """
+# add_platform
+
+**Multi-step workflow**: Add a new AI platform to DeepWork with adapter, templates, and tests
+
+> **NOTE**: Gemini CLI requires manual command invocation. After each step, tell the user which command to run next.
+
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
+
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
+
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
+
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
+
+
+## Available Steps
+
+1. **research** - Capture CLI configuration and hooks system documentation for the new platform
+ Command: `/add_platform:research`
+2. **add_capabilities** - Update job schema and adapters with any new hook events the platform supports (requires: research)
+ Command: `/add_platform:add_capabilities`
+3. **implement** - Add platform adapter, templates, tests with 100% coverage, and README documentation (requires: research, add_capabilities)
+ Command: `/add_platform:implement`
+4. **verify** - Set up platform directories and verify deepwork install works correctly (requires: implement)
+ Command: `/add_platform:verify`
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/add_platform` to determine user intent:
+- "research" or related terms → start at `/add_platform:research`
+- "add_capabilities" or related terms → start at `/add_platform:add_capabilities`
+- "implement" or related terms → start at `/add_platform:implement`
+- "verify" or related terms → start at `/add_platform:verify`
+
+### Step 2: Direct User to Starting Step
+
+Tell the user which command to run:
+```
+/add_platform:research
+```
+
+### Step 3: Guide Through Workflow
+
+After each step completes, tell the user the next command to run until workflow is complete.
+
+### Handling Ambiguous Intent
+
+If user intent is unclear:
+- Present available steps as numbered options
+- Ask user to select the starting point
+
+## Reference
+
+- Job definition: `.deepwork/jobs/add_platform/job.yml`
+"""
\ No newline at end of file
diff --git a/.gemini/commands/add_platform/uw.research.toml b/.gemini/skills/add_platform/research.toml
similarity index 82%
rename from .gemini/commands/add_platform/uw.research.toml
rename to .gemini/skills/add_platform/research.toml
index 48f4afd1..9097c01f 100644
--- a/.gemini/commands/add_platform/uw.research.toml
+++ b/.gemini/skills/add_platform/research.toml
@@ -9,33 +9,15 @@ description = "Capture CLI configuration and hooks system documentation for the
prompt = """
# add_platform:research
-**Step 1 of 4** in the **add_platform** workflow
-
-**Summary**: Add a new AI platform to DeepWork with adapter, templates, and tests
-
-## Job Overview
-
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
+**Step 1/4** in **add_platform** workflow
+> Add a new AI platform to DeepWork with adapter, templates, and tests
## Instructions
+**Goal**: Capture CLI configuration and hooks system documentation for the new platform
+
# Research Platform Documentation
## Objective
@@ -226,60 +208,50 @@ Take time to be thorough - incomplete documentation will slow down subsequent st
- Include code examples from the official docs where available
-## Inputs
-
-### User Parameters
-
-Please gather the following information from the user:
-- **platform_name**: Clear identifier of the platform (e.g., 'cursor', 'windsurf-editor', 'github-copilot-chat')
+### Job Context
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-## Work Branch Management
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
-All work for this job should be done on a dedicated work branch:
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/add_platform-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-## Output Requirements
+## Required Inputs
-Create the following output(s):
-- `cli_configuration.md`
-- `hooks_system.md`
+**User Parameters** - Gather from user before starting:
+- **platform_name**: Clear identifier of the platform (e.g., 'cursor', 'windsurf-editor', 'github-copilot-chat')
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
-## Completion
+## Work Branch
-After completing this step:
+Use branch format: `deepwork/add_platform-[instance]-YYYYMMDD`
-1. **Verify outputs**: Confirm all required files have been created
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)`
-2. **Inform the user**:
- - Step 1 of 4 is complete
- - Outputs created: cli_configuration.md, hooks_system.md
- - Ready to proceed to next step: `/add_platform:add_capabilities`
+## Outputs
-## Next Step
+**Required outputs**:
+- `cli_configuration.md`- `hooks_system.md`
+## On Completion
-To continue the workflow, run:
-```
-/add_platform:add_capabilities
-```
+1. Verify outputs are created
+2. Inform user: "Step 1/4 complete, outputs: cli_configuration.md, hooks_system.md"
+3. **Tell user next command**: `/add_platform:add_capabilities`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-- Step instructions: `.deepwork/jobs/add_platform/steps/research.md`
+**Reference files**: `.deepwork/jobs/add_platform/job.yml`, `.deepwork/jobs/add_platform/steps/research.md`
"""
\ No newline at end of file
diff --git a/.gemini/commands/add_platform/uw.verify.toml b/.gemini/skills/add_platform/verify.toml
similarity index 74%
rename from .gemini/commands/add_platform/uw.verify.toml
rename to .gemini/skills/add_platform/verify.toml
index acfd9671..4f046377 100644
--- a/.gemini/commands/add_platform/uw.verify.toml
+++ b/.gemini/skills/add_platform/verify.toml
@@ -9,39 +9,19 @@ description = "Set up platform directories and verify deepwork install works cor
prompt = """
# add_platform:verify
-**Step 4 of 4** in the **add_platform** workflow
+**Step 4/4** in **add_platform** workflow
-**Summary**: Add a new AI platform to DeepWork with adapter, templates, and tests
+> Add a new AI platform to DeepWork with adapter, templates, and tests
-## Job Overview
+## Prerequisites (Verify First)
-A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-
-This job guides you through four phases:
-1. **Research**: Capture the platform's CLI configuration and hooks system documentation
-2. **Add Capabilities**: Update the job schema and adapters with any new hook events
-3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
-4. **Verify**: Ensure installation works correctly and produces expected files
-
-The workflow ensures consistency across all supported platforms and maintains
-comprehensive test coverage for new functionality.
-
-**Important Notes**:
-- Only hooks available on slash command definitions should be captured
-- Each existing adapter must be updated when new hooks are added (typically with null values)
-- Tests must achieve 100% coverage for any new functionality
-- Installation verification confirms the platform integrates correctly with existing jobs
-
-
-## Prerequisites
-
-This step requires completion of the following step(s):
+Before proceeding, confirm these steps are complete:
- `/add_platform:implement`
-Please ensure these steps have been completed before proceeding.
-
## Instructions
+**Goal**: Set up platform directories and verify deepwork install works correctly
+
# Verify Installation
## Objective
@@ -155,57 +135,50 @@ Take time to verify each aspect - finding issues now is much better than having
- **Permission issues**: Directory creation might fail in some cases
-## Inputs
-
-
-### Required Files
+### Job Context
-This step requires the following files from previous steps:
-- `templates/` (from step `implement`)
+A workflow for adding support for a new AI platform (like Cursor, Windsurf, etc.) to DeepWork.
-Make sure to read and use these files as context for this step.
+This job guides you through four phases:
+1. **Research**: Capture the platform's CLI configuration and hooks system documentation
+2. **Add Capabilities**: Update the job schema and adapters with any new hook events
+3. **Implement**: Create the platform adapter, templates, tests (100% coverage), and README updates
+4. **Verify**: Ensure installation works correctly and produces expected files
-## Work Branch Management
+The workflow ensures consistency across all supported platforms and maintains
+comprehensive test coverage for new functionality.
-All work for this job should be done on a dedicated work branch:
+**Important Notes**:
+- Only hooks available on slash command definitions should be captured
+- Each existing adapter must be updated when new hooks are added (typically with null values)
+- Tests must achieve 100% coverage for any new functionality
+- Installation verification confirms the platform integrates correctly with existing jobs
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/add_platform-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+## Required Inputs
-## Output Requirements
-No specific files are output by this command.
+**Files from Previous Steps** - Read these first:
+- `templates/` (from `implement`)
-## Completion
+## Work Branch
-After completing this step:
+Use branch format: `deepwork/add_platform-[instance]-YYYYMMDD`
-1. **Verify outputs**: Confirm all required files have been created
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/add_platform-[instance]-$(date +%Y%m%d)`
-2. **Inform the user**:
- - Step 4 of 4 is complete
- - This is the final step - the job is complete!
+## Outputs
-## Workflow Complete
+No specific file outputs required.
-This is the final step in the add_platform workflow. All outputs should now be complete and ready for review.
+## On Completion
-Consider:
-- Reviewing all work products
-- Creating a pull request to merge the work branch
-- Documenting any insights or learnings
+1. Verify outputs are created
+2. Inform user: "Step 4/4 complete"
+3. **Workflow complete**: All steps finished. Consider creating a PR to merge the work branch.
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/add_platform/job.yml`
-- Step instructions: `.deepwork/jobs/add_platform/steps/verify.md`
+**Reference files**: `.deepwork/jobs/add_platform/job.yml`, `.deepwork/jobs/add_platform/steps/verify.md`
"""
\ No newline at end of file
diff --git a/.gemini/skills/commit/commit_and_push.toml b/.gemini/skills/commit/commit_and_push.toml
new file mode 100644
index 00000000..5b69a2af
--- /dev/null
+++ b/.gemini/skills/commit/commit_and_push.toml
@@ -0,0 +1,143 @@
+# commit:commit_and_push
+#
+# Review changed files, commit, and push to remote
+#
+# Generated by DeepWork - do not edit manually
+
+description = "Review changed files, commit, and push to remote"
+
+prompt = """
+# commit:commit_and_push
+
+**Step 3/3** in **commit** workflow
+
+> Run tests, lint, and commit code changes
+
+## Prerequisites (Verify First)
+
+Before proceeding, confirm these steps are complete:
+- `/commit:lint`
+
+## Instructions
+
+**Goal**: Review changed files, commit, and push to remote
+
+# Commit and Push
+
+## Objective
+
+Review the changed files with the user, create a commit with an appropriate message, and push to the remote repository.
+
+## Task
+
+Present the list of changed files for user review, ensure they match expectations, then commit and push the changes.
+
+### Process
+
+1. **Get the list of changed files**
+ ```bash
+ git status
+ ```
+ Also run `git diff --stat` to see a summary of changes.
+
+2. **Present changes to the user for review**
+
+ Use the AskUserQuestion tool to ask structured questions about the changes:
+
+ Show the user:
+ - List of modified files
+ - List of new files
+ - List of deleted files
+ - Summary of changes (lines added/removed)
+
+ Ask them to confirm:
+ - "Do these changed files match your expectations?"
+ - Provide options: "Yes, proceed with commit" / "No, let me review first" / "No, some files shouldn't be included"
+
+3. **Handle user response**
+
+ - If user confirms, proceed to commit
+ - If user wants to review first, wait for them to come back
+ - If user says some files shouldn't be included, ask which files to exclude and use `git restore` or `git checkout` to unstage them
+
+4. **Stage all appropriate changes**
+ ```bash
+ git add -A
+ ```
+ Or stage specific files if user excluded some.
+
+5. **View recent commit messages for style reference**
+ ```bash
+ git log --oneline -10
+ ```
+
+6. **Create the commit**
+
+ Generate an appropriate commit message based on:
+ - The changes made
+ - The style of recent commits
+ - Conventional commit format if the project uses it
+
+ ```bash
+ git commit -m "commit message here"
+ ```
+
+7. **Push to remote**
+ ```bash
+ git push
+ ```
+ If the branch has no upstream, use:
+ ```bash
+ git push -u origin HEAD
+ ```
+
+## Quality Criteria
+
+- Changed files list was presented to user
+- User explicitly confirmed the files match expectations
+- Commit message follows project conventions
+- Commit was created successfully
+- Changes were pushed to remote
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This is the final step of the commit workflow. It ensures the user has reviewed and approved the changes before they are committed and pushed. This prevents accidental commits of unintended files or changes.
+
+
+### Job Context
+
+A workflow for preparing and committing code changes with quality checks.
+
+This job runs tests until they pass, formats and lints code with ruff,
+then reviews changed files before committing and pushing. The lint step
+uses a sub-agent to reduce context usage.
+
+Steps:
+1. test - Pull latest code and run tests until they pass
+2. lint - Format and lint code with ruff (runs in sub-agent)
+3. commit_and_push - Review changes and commit/push
+
+
+
+## Work Branch
+
+Use branch format: `deepwork/commit-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/commit-[instance]-$(date +%Y%m%d)`
+
+## Outputs
+
+No specific file outputs required.
+
+## On Completion
+
+1. Verify outputs are created
+2. Inform user: "Step 3/3 complete"
+3. **Workflow complete**: All steps finished. Consider creating a PR to merge the work branch.
+
+---
+
+**Reference files**: `.deepwork/jobs/commit/job.yml`, `.deepwork/jobs/commit/steps/commit_and_push.md`
+"""
\ No newline at end of file
diff --git a/.gemini/skills/commit/index.toml b/.gemini/skills/commit/index.toml
new file mode 100644
index 00000000..e4794158
--- /dev/null
+++ b/.gemini/skills/commit/index.toml
@@ -0,0 +1,66 @@
+# commit
+#
+# Run tests, lint, and commit code changes
+#
+# Generated by DeepWork - do not edit manually
+
+description = "Run tests, lint, and commit code changes"
+
+prompt = """
+# commit
+
+**Multi-step workflow**: Run tests, lint, and commit code changes
+
+> **NOTE**: Gemini CLI requires manual command invocation. After each step, tell the user which command to run next.
+
+A workflow for preparing and committing code changes with quality checks.
+
+This job runs tests until they pass, formats and lints code with ruff,
+then reviews changed files before committing and pushing. The lint step
+uses a sub-agent to reduce context usage.
+
+Steps:
+1. test - Pull latest code and run tests until they pass
+2. lint - Format and lint code with ruff (runs in sub-agent)
+3. commit_and_push - Review changes and commit/push
+
+
+## Available Steps
+
+1. **test** - Pull latest code and run the test suite until all tests pass
+ Command: `/commit:test`
+2. **lint** - Format and lint code with ruff using a sub-agent (requires: test)
+ Command: `/commit:lint`
+3. **commit_and_push** - Review changed files, commit, and push to remote (requires: lint)
+ Command: `/commit:commit_and_push`
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/commit` to determine user intent:
+- "test" or related terms → start at `/commit:test`
+- "lint" or related terms → start at `/commit:lint`
+- "commit_and_push" or related terms → start at `/commit:commit_and_push`
+
+### Step 2: Direct User to Starting Step
+
+Tell the user which command to run:
+```
+/commit:test
+```
+
+### Step 3: Guide Through Workflow
+
+After each step completes, tell the user the next command to run until workflow is complete.
+
+### Handling Ambiguous Intent
+
+If user intent is unclear:
+- Present available steps as numbered options
+- Ask user to select the starting point
+
+## Reference
+
+- Job definition: `.deepwork/jobs/commit/job.yml`
+"""
\ No newline at end of file
diff --git a/.gemini/skills/commit/lint.toml b/.gemini/skills/commit/lint.toml
new file mode 100644
index 00000000..29c16cf5
--- /dev/null
+++ b/.gemini/skills/commit/lint.toml
@@ -0,0 +1,134 @@
+# commit:lint
+#
+# Format and lint code with ruff using a sub-agent
+#
+# Generated by DeepWork - do not edit manually
+
+description = "Format and lint code with ruff using a sub-agent"
+
+prompt = """
+# commit:lint
+
+**Step 2/3** in **commit** workflow
+
+> Run tests, lint, and commit code changes
+
+## Prerequisites (Verify First)
+
+Before proceeding, confirm these steps are complete:
+- `/commit:test`
+
+## Instructions
+
+**Goal**: Format and lint code with ruff using a sub-agent
+
+# Lint Code
+
+## Objective
+
+Format and lint the codebase using ruff to ensure code quality and consistency.
+
+## Task
+
+Run ruff format and ruff check to format and lint the code. This step should be executed using a sub-agent to conserve context in the main conversation.
+
+### Process
+
+**IMPORTANT**: Use the Task tool to spawn a sub-agent for this work. This saves context in the main conversation. Use the `haiku` model for speed.
+
+1. **Spawn a sub-agent to run linting**
+
+ Use the Task tool with these parameters:
+ - `subagent_type`: "Bash"
+ - `model`: "haiku"
+ - `prompt`: See below
+
+ The sub-agent should:
+
+ a. **Run ruff format**
+ ```bash
+ ruff format .
+ ```
+ This formats the code according to ruff's style rules.
+
+ b. **Run ruff check with auto-fix**
+ ```bash
+ ruff check --fix .
+ ```
+ This checks for lint errors and automatically fixes what it can.
+
+ c. **Run ruff check again to verify**
+ ```bash
+ ruff check .
+ ```
+ Capture the final output to verify no remaining issues.
+
+2. **Review sub-agent results**
+ - Check that both format and check completed successfully
+ - Note any remaining lint issues that couldn't be auto-fixed
+
+3. **Handle remaining issues**
+ - If there are lint errors that couldn't be auto-fixed, fix them manually
+ - Re-run ruff check to verify
+
+## Example Sub-Agent Prompt
+
+```
+Run ruff to format and lint the codebase:
+
+1. Run: ruff format .
+2. Run: ruff check --fix .
+3. Run: ruff check . (to verify no remaining issues)
+
+Report the results of each command.
+```
+
+## Quality Criteria
+
+- ruff format was run successfully
+- ruff check was run with --fix flag
+- No remaining lint errors (or all are documented and intentional)
+- Sub-agent was used to conserve context
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This step ensures code quality and consistency before committing. It runs after tests pass and before the commit step. Using a sub-agent keeps the main conversation context clean for the commit review.
+
+
+### Job Context
+
+A workflow for preparing and committing code changes with quality checks.
+
+This job runs tests until they pass, formats and lints code with ruff,
+then reviews changed files before committing and pushing. The lint step
+uses a sub-agent to reduce context usage.
+
+Steps:
+1. test - Pull latest code and run tests until they pass
+2. lint - Format and lint code with ruff (runs in sub-agent)
+3. commit_and_push - Review changes and commit/push
+
+
+
+## Work Branch
+
+Use branch format: `deepwork/commit-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/commit-[instance]-$(date +%Y%m%d)`
+
+## Outputs
+
+No specific file outputs required.
+
+## On Completion
+
+1. Verify outputs are created
+2. Inform user: "Step 2/3 complete"
+3. **Tell user next command**: `/commit:commit_and_push`
+
+---
+
+**Reference files**: `.deepwork/jobs/commit/job.yml`, `.deepwork/jobs/commit/steps/lint.md`
+"""
\ No newline at end of file
diff --git a/.gemini/skills/commit/test.toml b/.gemini/skills/commit/test.toml
new file mode 100644
index 00000000..03cafacc
--- /dev/null
+++ b/.gemini/skills/commit/test.toml
@@ -0,0 +1,116 @@
+# commit:test
+#
+# Pull latest code and run the test suite until all tests pass
+#
+# Generated by DeepWork - do not edit manually
+
+description = "Pull latest code and run the test suite until all tests pass"
+
+prompt = """
+# commit:test
+
+**Step 1/3** in **commit** workflow
+
+> Run tests, lint, and commit code changes
+
+
+## Instructions
+
+**Goal**: Pull latest code and run the test suite until all tests pass
+
+# Run Tests
+
+## Objective
+
+Run the project's test suite and fix any failing tests until all tests pass.
+
+## Task
+
+Execute the test suite for the project and iteratively fix any failures until all tests pass.
+
+### Process
+
+1. **Pull latest code from the branch**
+ - Run `git pull` to fetch and merge any changes from the remote
+ - If there are merge conflicts, resolve them before proceeding
+ - This ensures you're testing against the latest code
+
+2. **Detect or use the test command**
+ - If a test command was provided, use that
+ - Otherwise, auto-detect the project type and determine the appropriate test command:
+ - Python: `pytest`, `python -m pytest`, `uv run pytest`
+ - Node.js: `npm test`, `yarn test`, `bun test`
+ - Go: `go test ./...`
+ - Rust: `cargo test`
+ - Check `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod` for hints
+
+3. **Run the tests**
+ - Execute the test command
+ - Capture the output
+
+4. **Analyze failures**
+ - If tests pass, proceed to output
+ - If tests fail, analyze the failure messages
+ - Identify the root cause of each failure
+
+5. **Fix failing tests**
+ - Make the necessary code changes to fix failures
+ - This may involve fixing bugs in implementation code or updating tests
+ - Re-run tests after each fix
+
+6. **Iterate until passing**
+ - Continue the fix/test cycle until all tests pass
+
+## Quality Criteria
+
+- Latest code was pulled from the branch
+- Test command was correctly identified or used from input
+- All tests are now passing
+- When all criteria are met, include `✓ Quality Criteria Met` in your response
+
+## Context
+
+This is the first step of the commit workflow. Tests must pass before proceeding to lint and commit. This ensures code quality and prevents broken code from being committed.
+
+
+### Job Context
+
+A workflow for preparing and committing code changes with quality checks.
+
+This job runs tests until they pass, formats and lints code with ruff,
+then reviews changed files before committing and pushing. The lint step
+uses a sub-agent to reduce context usage.
+
+Steps:
+1. test - Pull latest code and run tests until they pass
+2. lint - Format and lint code with ruff (runs in sub-agent)
+3. commit_and_push - Review changes and commit/push
+
+
+## Required Inputs
+
+**User Parameters** - Gather from user before starting:
+- **test_command**: Test command to run (optional - will auto-detect if not provided)
+
+
+## Work Branch
+
+Use branch format: `deepwork/commit-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/commit-[instance]-$(date +%Y%m%d)`
+
+## Outputs
+
+No specific file outputs required.
+
+## On Completion
+
+1. Verify outputs are created
+2. Inform user: "Step 1/3 complete"
+3. **Tell user next command**: `/commit:lint`
+
+---
+
+**Reference files**: `.deepwork/jobs/commit/job.yml`, `.deepwork/jobs/commit/steps/test.md`
+"""
\ No newline at end of file
diff --git a/.gemini/commands/deepwork_jobs/uw.define.toml b/.gemini/skills/deepwork_jobs/define.toml
similarity index 90%
rename from .gemini/commands/deepwork_jobs/uw.define.toml
rename to .gemini/skills/deepwork_jobs/define.toml
index 13784b61..fc07ef69 100644
--- a/.gemini/commands/deepwork_jobs/uw.define.toml
+++ b/.gemini/skills/deepwork_jobs/define.toml
@@ -9,27 +9,15 @@ description = "Create the job.yml specification file by understanding workflow r
prompt = """
# deepwork_jobs:define
-**Step 1 of 3** in the **deepwork_jobs** workflow
-
-**Summary**: DeepWork job management commands
-
-## Job Overview
-
-Core commands for managing DeepWork jobs. These commands help you define new multi-step
-workflows and learn from running them.
-
-The `define` command guides you through an interactive process to create a new job by
-asking structured questions about your workflow, understanding each step's inputs and outputs,
-and generating all necessary files.
-
-The `learn` command reflects on conversations where DeepWork jobs were run, identifies
-confusion or inefficiencies, and improves job instructions. It also captures bespoke
-learnings specific to the current run into AGENTS.md files in the working folder.
+**Step 1/3** in **deepwork_jobs** workflow
+> DeepWork job management commands
## Instructions
+**Goal**: Create the job.yml specification file by understanding workflow requirements
+
# Define Job Specification
## Objective
@@ -363,43 +351,42 @@ After creating the file:
- Ready for implementation step
-## Inputs
+### Job Context
-### User Parameters
+Core commands for managing DeepWork jobs. These commands help you define new multi-step
+workflows and learn from running them.
-Please gather the following information from the user:
-- **job_purpose**: What complex task or workflow are you trying to accomplish?
+The `define` command guides you through an interactive process to create a new job by
+asking structured questions about your workflow, understanding each step's inputs and outputs,
+and generating all necessary files.
+The `learn` command reflects on conversations where DeepWork jobs were run, identifies
+confusion or inefficiencies, and improves job instructions. It also captures bespoke
+learnings specific to the current run into AGENTS.md files in the working folder.
-## Work Branch Management
-All work for this job should be done on a dedicated work branch:
+## Required Inputs
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/deepwork_jobs-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+**User Parameters** - Gather from user before starting:
+- **job_purpose**: What complex task or workflow are you trying to accomplish?
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-## Output Requirements
+## Work Branch
-Create the following output(s):
-- `job.yml`
+Use branch format: `deepwork/deepwork_jobs-[instance]-YYYYMMDD`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)`
-## Quality Validation
+## Outputs
-This step has quality criteria that should be verified before completion.
+**Required outputs**:
+- `job.yml`
+## Quality Validation (Manual)
-### Quality Criteria
+**NOTE**: Gemini CLI does not support automated validation. Manually verify criteria before completing.
+**Criteria (all must be satisfied)**:
1. **User Understanding**: Did the agent fully understand the user's workflow by asking structured questions?
2. **Structured Questions Used**: Did the agent ask structured questions (using the AskUserQuestion tool) to gather user input?
3. **Clear Inputs/Outputs**: Does every step have clearly defined inputs and outputs?
@@ -408,31 +395,13 @@ This step has quality criteria that should be verified before completion.
6. **Rich Description**: Does the description provide enough context for future refinement?
7. **Valid Schema**: Does the job.yml follow the required schema (name, version, summary, steps)?
8. **File Created**: Has the job.yml file been created in `.deepwork/jobs/[job_name]/job.yml`?
+## On Completion
-**Note**: Gemini CLI does not support automated validation hooks. Please manually verify the criteria above before proceeding.
-
-## Completion
-
-After completing this step:
-
-1. **Verify outputs**: Confirm all required files have been created
-
-2. **Inform the user**:
- - Step 1 of 3 is complete
- - Outputs created: job.yml
- - Ready to proceed to next step: `/deepwork_jobs:implement`
-
-## Next Step
-
-To continue the workflow, run:
-```
-/deepwork_jobs:implement
-```
+1. Verify outputs are created
+2. Inform user: "Step 1/3 complete, outputs: job.yml"
+3. **Tell user next command**: `/deepwork_jobs:implement`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
-- Step instructions: `.deepwork/jobs/deepwork_jobs/steps/define.md`
+**Reference files**: `.deepwork/jobs/deepwork_jobs/job.yml`, `.deepwork/jobs/deepwork_jobs/steps/define.md`
"""
\ No newline at end of file
diff --git a/.gemini/commands/deepwork_jobs/uw.implement.toml b/.gemini/skills/deepwork_jobs/implement.toml
similarity index 82%
rename from .gemini/commands/deepwork_jobs/uw.implement.toml
rename to .gemini/skills/deepwork_jobs/implement.toml
index 4170a65f..83047a35 100644
--- a/.gemini/commands/deepwork_jobs/uw.implement.toml
+++ b/.gemini/skills/deepwork_jobs/implement.toml
@@ -9,33 +9,19 @@ description = "Generate instruction files for each step based on the job.yml spe
prompt = """
# deepwork_jobs:implement
-**Step 2 of 3** in the **deepwork_jobs** workflow
+**Step 2/3** in **deepwork_jobs** workflow
-**Summary**: DeepWork job management commands
+> DeepWork job management commands
-## Job Overview
+## Prerequisites (Verify First)
-Core commands for managing DeepWork jobs. These commands help you define new multi-step
-workflows and learn from running them.
-
-The `define` command guides you through an interactive process to create a new job by
-asking structured questions about your workflow, understanding each step's inputs and outputs,
-and generating all necessary files.
-
-The `learn` command reflects on conversations where DeepWork jobs were run, identifies
-confusion or inefficiencies, and improves job instructions. It also captures bespoke
-learnings specific to the current run into AGENTS.md files in the working folder.
-
-
-## Prerequisites
-
-This step requires completion of the following step(s):
+Before proceeding, confirm these steps are complete:
- `/deepwork_jobs:define`
-Please ensure these steps have been completed before proceeding.
-
## Instructions
+**Goal**: Generate instruction files for each step based on the job.yml specification
+
# Implement Job Steps
## Objective
@@ -151,9 +137,9 @@ See `.deepwork/jobs/deepwork_jobs/steps/supplemental_file_references.md` for det
Verify that `job.yml` is in the correct location at `.deepwork/jobs/[job_name]/job.yml`. The define step should have created it there. If for some reason it's not there, you may need to create or move it.
-### Step 5: Sync Commands
+### Step 5: Sync Skills
-Run `deepwork sync` to generate the slash-commands for this job:
+Run `deepwork sync` to generate the skills for this job:
```bash
deepwork sync
@@ -161,12 +147,12 @@ deepwork sync
This will:
- Parse the job definition
-- Generate slash-commands for each step
-- Make the commands available in `.claude/commands/` (or appropriate platform directory)
+- Generate skills for each step
+- Make the skills available in `.claude/skills/` (or appropriate platform directory)
### Step 6: Relay Reload Instructions
-After running `deepwork sync`, look at the "To use the new commands" section in the output. **Relay these exact reload instructions to the user** so they know how to pick up the new commands. Don't just reference the sync output - tell them directly what they need to do (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code, or "Run '/memory refresh'" for Gemini CLI).
+After running `deepwork sync`, look at the "To use the new skills" section in the output. **Relay these exact reload instructions to the user** so they know how to pick up the new skills. Don't just reference the sync output - tell them directly what they need to do (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code, or "Run '/memory refresh'" for Gemini CLI).
### Step 7: Consider Rules for the New Job
@@ -258,7 +244,7 @@ Before marking this step complete, ensure:
- [ ] All step instruction files created
- [ ] Each instruction file is complete and actionable
- [ ] `deepwork sync` executed successfully
-- [ ] Commands generated in platform directory
+- [ ] Skills generated in platform directory
- [ ] User informed to follow reload instructions from `deepwork sync`
- [ ] Considered whether rules would benefit this job (Step 7)
- [ ] If rules suggested, offered to run `/deepwork_rules.define`
@@ -272,49 +258,46 @@ Before marking this step complete, ensure:
- Quality criteria defined for each step
- Steps with user inputs explicitly use "ask structured questions" phrasing
- Sync completed successfully
-- Commands available for use
+- Skills available for use
- Thoughtfully considered relevant rules for the job domain
-## Inputs
-
+### Job Context
-### Required Files
+Core commands for managing DeepWork jobs. These commands help you define new multi-step
+workflows and learn from running them.
-This step requires the following files from previous steps:
-- `job.yml` (from step `define`)
+The `define` command guides you through an interactive process to create a new job by
+asking structured questions about your workflow, understanding each step's inputs and outputs,
+and generating all necessary files.
-Make sure to read and use these files as context for this step.
+The `learn` command reflects on conversations where DeepWork jobs were run, identifies
+confusion or inefficiencies, and improves job instructions. It also captures bespoke
+learnings specific to the current run into AGENTS.md files in the working folder.
-## Work Branch Management
-All work for this job should be done on a dedicated work branch:
+## Required Inputs
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/deepwork_jobs-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+**Files from Previous Steps** - Read these first:
+- `job.yml` (from `define`)
-## Output Requirements
+## Work Branch
-Create the following output(s):
-- `steps/` (directory)
+Use branch format: `deepwork/deepwork_jobs-[instance]-YYYYMMDD`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)`
-## Quality Validation
+## Outputs
-This step has quality criteria that should be verified before completion.
+**Required outputs**:
+- `steps/` (directory)
+## Quality Validation (Manual)
-### Quality Criteria
+**NOTE**: Gemini CLI does not support automated validation. Manually verify criteria before completing.
+**Criteria (all must be satisfied)**:
1. **Directory Structure**: Is `.deepwork/jobs/[job_name]/` created correctly?
2. **Complete Instructions**: Are ALL step instruction files complete (not stubs or placeholders)?
3. **Specific & Actionable**: Are instructions tailored to each step's purpose, not generic?
@@ -324,31 +307,13 @@ This step has quality criteria that should be verified before completion.
7. **Sync Complete**: Has `deepwork sync` been run successfully?
8. **Commands Available**: Are the slash-commands generated in `.claude/commands/`?
9. **Rules Considered**: Has the agent thought about whether rules would benefit this job? If relevant rules were identified, did they explain them and offer to run `/deepwork_rules.define`? Not every job needs rules - only suggest when genuinely helpful.
+## On Completion
-**Note**: Gemini CLI does not support automated validation hooks. Please manually verify the criteria above before proceeding.
-
-## Completion
-
-After completing this step:
-
-1. **Verify outputs**: Confirm all required files have been created
-
-2. **Inform the user**:
- - Step 2 of 3 is complete
- - Outputs created: steps/
- - Ready to proceed to next step: `/deepwork_jobs:learn`
-
-## Next Step
-
-To continue the workflow, run:
-```
-/deepwork_jobs:learn
-```
+1. Verify outputs are created
+2. Inform user: "Step 2/3 complete, outputs: steps/"
+3. **Tell user next command**: `/deepwork_jobs:learn`
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
-- Step instructions: `.deepwork/jobs/deepwork_jobs/steps/implement.md`
+**Reference files**: `.deepwork/jobs/deepwork_jobs/job.yml`, `.deepwork/jobs/deepwork_jobs/steps/implement.md`
"""
\ No newline at end of file
diff --git a/.gemini/skills/deepwork_jobs/index.toml b/.gemini/skills/deepwork_jobs/index.toml
new file mode 100644
index 00000000..d00ca4cb
--- /dev/null
+++ b/.gemini/skills/deepwork_jobs/index.toml
@@ -0,0 +1,66 @@
+# deepwork_jobs
+#
+# DeepWork job management commands
+#
+# Generated by DeepWork - do not edit manually
+
+description = "DeepWork job management commands"
+
+prompt = """
+# deepwork_jobs
+
+**Multi-step workflow**: DeepWork job management commands
+
+> **NOTE**: Gemini CLI requires manual command invocation. After each step, tell the user which command to run next.
+
+Core commands for managing DeepWork jobs. These commands help you define new multi-step
+workflows and learn from running them.
+
+The `define` command guides you through an interactive process to create a new job by
+asking structured questions about your workflow, understanding each step's inputs and outputs,
+and generating all necessary files.
+
+The `learn` command reflects on conversations where DeepWork jobs were run, identifies
+confusion or inefficiencies, and improves job instructions. It also captures bespoke
+learnings specific to the current run into AGENTS.md files in the working folder.
+
+
+## Available Steps
+
+1. **define** - Create the job.yml specification file by understanding workflow requirements
+ Command: `/deepwork_jobs:define`
+2. **implement** - Generate instruction files for each step based on the job.yml specification (requires: define)
+ Command: `/deepwork_jobs:implement`
+3. **learn** - Reflect on conversation to improve job instructions and capture learnings
+ Command: `/deepwork_jobs:learn`
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/deepwork_jobs` to determine user intent:
+- "define" or related terms → start at `/deepwork_jobs:define`
+- "implement" or related terms → start at `/deepwork_jobs:implement`
+- "learn" or related terms → start at `/deepwork_jobs:learn`
+
+### Step 2: Direct User to Starting Step
+
+Tell the user which command to run:
+```
+/deepwork_jobs:define
+```
+
+### Step 3: Guide Through Workflow
+
+After each step completes, tell the user the next command to run until workflow is complete.
+
+### Handling Ambiguous Intent
+
+If user intent is unclear:
+- Present available steps as numbered options
+- Ask user to select the starting point
+
+## Reference
+
+- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
+"""
\ No newline at end of file
diff --git a/.gemini/commands/deepwork_jobs/learn.toml b/.gemini/skills/deepwork_jobs/learn.toml
similarity index 84%
rename from .gemini/commands/deepwork_jobs/learn.toml
rename to .gemini/skills/deepwork_jobs/learn.toml
index 3cd2aaad..bb4ddb82 100644
--- a/.gemini/commands/deepwork_jobs/learn.toml
+++ b/.gemini/skills/deepwork_jobs/learn.toml
@@ -9,27 +9,15 @@ description = "Reflect on conversation to improve job instructions and capture l
prompt = """
# deepwork_jobs:learn
-**Standalone command** in the **deepwork_jobs** job - can be run anytime
-
-**Summary**: DeepWork job management commands
-
-## Job Overview
-
-Core commands for managing DeepWork jobs. These commands help you define new multi-step
-workflows and learn from running them.
-
-The `define` command guides you through an interactive process to create a new job by
-asking structured questions about your workflow, understanding each step's inputs and outputs,
-and generating all necessary files.
-
-The `learn` command reflects on conversations where DeepWork jobs were run, identifies
-confusion or inefficiencies, and improves job instructions. It also captures bespoke
-learnings specific to the current run into AGENTS.md files in the working folder.
+**Standalone command** - can be run anytime
+> DeepWork job management commands
## Instructions
+**Goal**: Reflect on conversation to improve job instructions and capture learnings
+
# Learn from Job Execution
## Objective
@@ -203,7 +191,7 @@ If instruction files were modified:
deepwork sync
```
-2. **If commands were regenerated**, look at the "To use the new commands" section in the `deepwork sync` output and **relay these exact reload instructions to the user** (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code)
+2. **If skills were regenerated**, look at the "To use the new skills" section in the `deepwork sync` output and **relay these exact reload instructions to the user** (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code)
## File Reference Patterns
@@ -293,7 +281,7 @@ I found the following job executions:
**Summary**
-Updated job instructions and created AGENTS.md with bespoke learnings. To get the updated commands, type 'exit' then run 'claude --resume'.
+Updated job instructions and created AGENTS.md with bespoke learnings. To get the updated skills, type 'exit' then run 'claude --resume'.
```
## Handling Edge Cases
@@ -320,43 +308,42 @@ Updated job instructions and created AGENTS.md with bespoke learnings. To get th
- Reference config files instead of including values
-## Inputs
+### Job Context
-### User Parameters
+Core commands for managing DeepWork jobs. These commands help you define new multi-step
+workflows and learn from running them.
-Please gather the following information from the user:
-- **job_name**: Name of the job that was run (optional - will auto-detect from conversation)
+The `define` command guides you through an interactive process to create a new job by
+asking structured questions about your workflow, understanding each step's inputs and outputs,
+and generating all necessary files.
+The `learn` command reflects on conversations where DeepWork jobs were run, identifies
+confusion or inefficiencies, and improves job instructions. It also captures bespoke
+learnings specific to the current run into AGENTS.md files in the working folder.
-## Work Branch Management
-All work for this job should be done on a dedicated work branch:
+## Required Inputs
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/deepwork_jobs-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+**User Parameters** - Gather from user before starting:
+- **job_name**: Name of the job that was run (optional - will auto-detect from conversation)
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-## Output Requirements
+## Work Branch
-Create the following output(s):
-- `AGENTS.md`
+Use branch format: `deepwork/deepwork_jobs-[instance]-YYYYMMDD`
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/deepwork_jobs-[instance]-$(date +%Y%m%d)`
-## Quality Validation
+## Outputs
-This step has quality criteria that should be verified before completion.
+**Required outputs**:
+- `AGENTS.md`
+## Quality Validation (Manual)
-### Quality Criteria
+**NOTE**: Gemini CLI does not support automated validation. Manually verify criteria before completing.
+**Criteria (all must be satisfied)**:
1. **Conversation Analyzed**: Did the agent review the conversation for DeepWork job executions?
2. **Confusion Identified**: Did the agent identify points of confusion, errors, or inefficiencies?
3. **Instructions Improved**: Were job instructions updated to address identified issues?
@@ -367,33 +354,14 @@ This step has quality criteria that should be verified before completion.
8. **Working Folder Correct**: Is AGENTS.md in the correct working folder for the job?
9. **Generalizable Separated**: Are generalizable improvements in instructions, not AGENTS.md?
10. **Sync Complete**: Has `deepwork sync` been run if instructions were modified?
+## On Completion
-**Note**: Gemini CLI does not support automated validation hooks. Please manually verify the criteria above before proceeding.
-
-## Completion
-
-After completing this step:
-
-1. **Verify outputs**: Confirm all required files have been created
+1. Verify outputs are created
+2. Inform user: "learn complete, outputs: AGENTS.md"
-2. **Inform the user**:
- - The learn command is complete
- - Outputs created: AGENTS.md
- - This command can be run again anytime to make further changes
-
-## Command Complete
-
-This is a standalone command that can be run anytime. The outputs are ready for use.
-
-Consider:
-- Reviewing the outputs
-- Running `deepwork sync` if job definitions were changed
-- Re-running this command later if further changes are needed
+This standalone command can be re-run anytime.
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_jobs/job.yml`
-- Step instructions: `.deepwork/jobs/deepwork_jobs/steps/learn.md`
+**Reference files**: `.deepwork/jobs/deepwork_jobs/job.yml`, `.deepwork/jobs/deepwork_jobs/steps/learn.md`
"""
\ No newline at end of file
diff --git a/.gemini/commands/deepwork_rules/uw.define.toml b/.gemini/skills/deepwork_rules/define.toml
similarity index 85%
rename from .gemini/commands/deepwork_rules/uw.define.toml
rename to .gemini/skills/deepwork_rules/define.toml
index 28d6d5b4..b0d3f959 100644
--- a/.gemini/commands/deepwork_rules/uw.define.toml
+++ b/.gemini/skills/deepwork_rules/define.toml
@@ -9,32 +9,15 @@ description = "Create a new rule file in .deepwork/rules/"
prompt = """
# deepwork_rules:define
-**Standalone command** in the **deepwork_rules** job - can be run anytime
-
-**Summary**: Rules enforcement for AI agent sessions
-
-## Job Overview
-
-Manages rules that automatically trigger when certain files change during an AI agent session.
-Rules help ensure that code changes follow team guidelines, documentation is updated,
-and architectural decisions are respected.
-
-Rules are stored as individual markdown files with YAML frontmatter in the `.deepwork/rules/`
-directory. Each rule file specifies:
-- Detection mode: trigger/safety, set (bidirectional), or pair (directional)
-- Patterns: Glob patterns for matching files, with optional variable capture
-- Instructions: Markdown content describing what the agent should do
-
-Example use cases:
-- Update installation docs when configuration files change
-- Require security review when authentication code is modified
-- Ensure API documentation stays in sync with API code
-- Enforce source/test file pairing
+**Standalone command** - can be run anytime
+> Rules enforcement for AI agent sessions
## Instructions
+**Goal**: Create a new rule file in .deepwork/rules/
+
# Define Rule
## Objective
@@ -286,61 +269,50 @@ Rules are evaluated automatically when the agent finishes a task. The system:
You can mark a rule as addressed by including `Rule Name` in your response (replace Rule Name with the actual rule name from the `name` field). This tells the system you've already handled that rule's requirements.
-## Inputs
-
-### User Parameters
+### Job Context
-Please gather the following information from the user:
-- **rule_purpose**: What guideline or constraint should this rule enforce?
-
-
-## Work Branch Management
+Manages rules that automatically trigger when certain files change during an AI agent session.
+Rules help ensure that code changes follow team guidelines, documentation is updated,
+and architectural decisions are respected.
-All work for this job should be done on a dedicated work branch:
+Rules are stored as individual markdown files with YAML frontmatter in the `.deepwork/rules/`
+directory. Each rule file specifies:
+- Detection mode: trigger/safety, set (bidirectional), or pair (directional)
+- Patterns: Glob patterns for matching files, with optional variable capture
+- Instructions: Markdown content describing what the agent should do
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/deepwork_rules-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+Example use cases:
+- Update installation docs when configuration files change
+- Require security review when authentication code is modified
+- Ensure API documentation stays in sync with API code
+- Enforce source/test file pairing
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/deepwork_rules-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-## Output Requirements
+## Required Inputs
-Create the following output(s):
-- `.deepwork/rules/{rule-name}.md`
+**User Parameters** - Gather from user before starting:
+- **rule_purpose**: What guideline or constraint should this rule enforce?
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
-## Completion
+## Work Branch
-After completing this step:
+Use branch format: `deepwork/deepwork_rules-[instance]-YYYYMMDD`
-1. **Verify outputs**: Confirm all required files have been created
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/deepwork_rules-[instance]-$(date +%Y%m%d)`
-2. **Inform the user**:
- - The define command is complete
- - Outputs created: .deepwork/rules/{rule-name}.md
- - This command can be run again anytime to make further changes
+## Outputs
-## Command Complete
+**Required outputs**:
+- `.deepwork/rules/{rule-name}.md`
+## On Completion
-This is a standalone command that can be run anytime. The outputs are ready for use.
+1. Verify outputs are created
+2. Inform user: "define complete, outputs: .deepwork/rules/{rule-name}.md"
-Consider:
-- Reviewing the outputs
-- Running `deepwork sync` if job definitions were changed
-- Re-running this command later if further changes are needed
+This standalone command can be re-run anytime.
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/deepwork_rules/job.yml`
-- Step instructions: `.deepwork/jobs/deepwork_rules/steps/define.md`
+**Reference files**: `.deepwork/jobs/deepwork_rules/job.yml`, `.deepwork/jobs/deepwork_rules/steps/define.md`
"""
\ No newline at end of file
diff --git a/.gemini/commands/deepwork_rules/index.toml b/.gemini/skills/deepwork_rules/index.toml
similarity index 50%
rename from .gemini/commands/deepwork_rules/index.toml
rename to .gemini/skills/deepwork_rules/index.toml
index b3c6a0f1..41d4cd9f 100644
--- a/.gemini/commands/deepwork_rules/index.toml
+++ b/.gemini/skills/deepwork_rules/index.toml
@@ -9,7 +9,9 @@ description = "Rules enforcement for AI agent sessions"
prompt = """
# deepwork_rules
-You are executing the **deepwork_rules** job. Rules enforcement for AI agent sessions
+**Multi-step workflow**: Rules enforcement for AI agent sessions
+
+> **NOTE**: Gemini CLI requires manual command invocation. After each step, tell the user which command to run next.
Manages rules that automatically trigger when certain files change during an AI agent session.
Rules help ensure that code changes follow team guidelines, documentation is updated,
@@ -30,36 +32,34 @@ Example use cases:
## Available Steps
-This job has 1 step(s):
+1. **define** - Create a new rule file in .deepwork/rules/
+ Command: `/deepwork_rules:define`
-### define
-**Define Rule**: Create a new rule file in .deepwork/rules/
-- Command: `/deepwork_rules:uw.define`
+## Execution Instructions
-## Instructions
+### Step 1: Analyze Intent
-This is a **multi-step workflow**. Determine the starting point and guide the user through the steps in sequence.
+Parse any text following `/deepwork_rules` to determine user intent:
+- "define" or related terms → start at `/deepwork_rules:define`
-1. **Analyze user intent** from the text that follows `/deepwork_rules`
+### Step 2: Direct User to Starting Step
-2. **Identify the starting step** based on intent:
- - define: Create a new rule file in .deepwork/rules/
+Tell the user which command to run:
+```
+/deepwork_rules:define
+```
-3. **Guide the user through the workflow**:
- - Tell the user to run the starting step command
- - After each step completes, guide them to the next step in the workflow
- - Continue until the workflow is complete
+### Step 3: Guide Through Workflow
- Step commands:
- - define: `/deepwork_rules:uw.define`
+After each step completes, tell the user the next command to run until workflow is complete.
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Let them choose
+### Handling Ambiguous Intent
-**Note**: Gemini CLI requires manual command invocation. After each step completes, remind the user to run the next step command.
+If user intent is unclear:
+- Present available steps as numbered options
+- Ask user to select the starting point
-## Context Files
+## Reference
- Job definition: `.deepwork/jobs/deepwork_rules/job.yml`
"""
\ No newline at end of file
diff --git a/.gemini/skills/update/index.toml b/.gemini/skills/update/index.toml
new file mode 100644
index 00000000..2e2bcc0e
--- /dev/null
+++ b/.gemini/skills/update/index.toml
@@ -0,0 +1,63 @@
+# update
+#
+# Update standard jobs in src/ and sync to installed locations
+#
+# Generated by DeepWork - do not edit manually
+
+description = "Update standard jobs in src/ and sync to installed locations"
+
+prompt = """
+# update
+
+**Multi-step workflow**: Update standard jobs in src/ and sync to installed locations
+
+> **NOTE**: Gemini CLI requires manual command invocation. After each step, tell the user which command to run next.
+
+A workflow for maintaining standard jobs bundled with DeepWork. Standard jobs
+(like `deepwork_jobs` and `deepwork_rules`) are source-controlled in
+`src/deepwork/standard_jobs/` and must be edited there—never in `.deepwork/jobs/`
+or `.claude/commands/` directly.
+
+This job guides you through:
+1. Identifying which standard job(s) to update from conversation context
+2. Making changes in the correct source location (`src/deepwork/standard_jobs/[job_name]/`)
+3. Running `deepwork install` to propagate changes to `.deepwork/` and command directories
+4. Verifying the sync completed successfully
+
+Use this job whenever you need to modify job.yml files, step instructions, or hooks
+for any standard job in the DeepWork repository.
+
+
+## Available Steps
+
+1. **job** - Edit standard job source files and sync to installed locations
+ Command: `/update:job`
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/update` to determine user intent:
+- "job" or related terms → start at `/update:job`
+
+### Step 2: Direct User to Starting Step
+
+Tell the user which command to run:
+```
+/update:job
+```
+
+### Step 3: Guide Through Workflow
+
+After each step completes, tell the user the next command to run until workflow is complete.
+
+### Handling Ambiguous Intent
+
+If user intent is unclear:
+- Present available steps as numbered options
+- Ask user to select the starting point
+
+## Reference
+
+- Job definition: `.deepwork/jobs/update/job.yml`
+"""
\ No newline at end of file
diff --git a/.gemini/commands/update/uw.job.toml b/.gemini/skills/update/job.toml
similarity index 69%
rename from .gemini/commands/update/uw.job.toml
rename to .gemini/skills/update/job.toml
index c38490e5..0abaf780 100644
--- a/.gemini/commands/update/uw.job.toml
+++ b/.gemini/skills/update/job.toml
@@ -9,30 +9,15 @@ description = "Edit standard job source files and sync to installed locations"
prompt = """
# update:job
-**Standalone command** in the **update** job - can be run anytime
-
-**Summary**: Update standard jobs in src/ and sync to installed locations
-
-## Job Overview
-
-A workflow for maintaining standard jobs bundled with DeepWork. Standard jobs
-(like `deepwork_jobs` and `deepwork_rules`) are source-controlled in
-`src/deepwork/standard_jobs/` and must be edited there—never in `.deepwork/jobs/`
-or `.claude/commands/` directly.
-
-This job guides you through:
-1. Identifying which standard job(s) to update from conversation context
-2. Making changes in the correct source location (`src/deepwork/standard_jobs/[job_name]/`)
-3. Running `deepwork install` to propagate changes to `.deepwork/` and command directories
-4. Verifying the sync completed successfully
-
-Use this job whenever you need to modify job.yml files, step instructions, or hooks
-for any standard job in the DeepWork repository.
+**Standalone command** - can be run anytime
+> Update standard jobs in src/ and sync to installed locations
## Instructions
+**Goal**: Edit standard job source files and sync to installed locations
+
# Update Standard Job
## Objective
@@ -108,55 +93,48 @@ ls -la .claude/commands/[job_name].*.md
- When all criteria are met, include `✓ Quality Criteria Met`
-## Inputs
-
-### User Parameters
+### Job Context
-Please gather the following information from the user:
-- **job_context**: Determine from conversation context which standard job(s) to update and what changes are needed
+A workflow for maintaining standard jobs bundled with DeepWork. Standard jobs
+(like `deepwork_jobs` and `deepwork_rules`) are source-controlled in
+`src/deepwork/standard_jobs/` and must be edited there—never in `.deepwork/jobs/`
+or `.claude/commands/` directly.
+This job guides you through:
+1. Identifying which standard job(s) to update from conversation context
+2. Making changes in the correct source location (`src/deepwork/standard_jobs/[job_name]/`)
+3. Running `deepwork install` to propagate changes to `.deepwork/` and command directories
+4. Verifying the sync completed successfully
-## Work Branch Management
+Use this job whenever you need to modify job.yml files, step instructions, or hooks
+for any standard job in the DeepWork repository.
-All work for this job should be done on a dedicated work branch:
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/update-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
+## Required Inputs
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/update-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
+**User Parameters** - Gather from user before starting:
+- **job_context**: Determine from conversation context which standard job(s) to update and what changes are needed
-## Output Requirements
-No specific files are output by this command.
+## Work Branch
-## Completion
+Use branch format: `deepwork/update-[instance]-YYYYMMDD`
-After completing this step:
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/update-[instance]-$(date +%Y%m%d)`
-1. **Verify outputs**: Confirm all required files have been created
+## Outputs
-2. **Inform the user**:
- - The job command is complete
- - This command can be run again anytime to make further changes
+No specific file outputs required.
-## Command Complete
+## On Completion
-This is a standalone command that can be run anytime. The outputs are ready for use.
+1. Verify outputs are created
+2. Inform user: "job complete"
-Consider:
-- Reviewing the outputs
-- Running `deepwork sync` if job definitions were changed
-- Re-running this command later if further changes are needed
+This standalone command can be re-run anytime.
---
-## Context Files
-
-- Job definition: `.deepwork/jobs/update/job.yml`
-- Step instructions: `.deepwork/jobs/update/steps/job.md`
+**Reference files**: `.deepwork/jobs/update/job.yml`, `.deepwork/jobs/update/steps/job.md`
"""
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 26a9a3ba..62c20eef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,27 @@ All notable changes to DeepWork will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.5.0] - 2026-01-18
+
+- **BREAKING**: Refactored "commands" terminology to "skills" throughout the codebase
+ - Directory structure changed from `.claude/commands/` to `.claude/skills/`
+ - Directory structure changed from `.gemini/commands/` to `.gemini/skills/`
+ - Class renamed: `CommandGenerator` → `SkillGenerator`
+ - Enum renamed: `CommandLifecycleHook` → `SkillLifecycleHook`
+ - Class attributes renamed: `commands_dir` → `skills_dir`, `command_template` → `skill_template`
+ - Methods renamed: `get_commands_dir()` → `get_skills_dir()`, `generate_all_commands()` → `generate_all_skills()`, etc.
+ - Template files renamed: `command-job-step.md.jinja` → `skill-job-step.md.jinja`, etc.
+- **BREAKING**: Removed `uw.` prefix convention for hidden steps
+ - Step skills now use clean filenames (e.g., `job_name.step_id.md` instead of `uw.job_name.step_id.md`)
+ - Hidden steps use `user-invocable: false` in YAML frontmatter instead
+ - The `exposed` field in job.yml now controls the `user-invocable` frontmatter setting
+- CLI output messages updated to use "skills" terminology
+
+### Migration Guide
+- Run `deepwork install --platform claude` to regenerate skills in the new location
+- Remove old `.claude/commands/` and `.gemini/commands/` directories manually
+- Update any custom code that imports `CommandGenerator` or `CommandLifecycleHook`
+
## [0.4.1] - 2026-01-18
### Fixed
@@ -13,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Now each failed rule shows: `To skip, include Rule Name in your response`
- This allows agents to understand how to proceed when a command rule fails
+
## [0.4.0] - 2026-01-16
### Added
diff --git a/README.md b/README.md
index c4c0176f..0d6c7bfd 100644
--- a/README.md
+++ b/README.md
@@ -168,7 +168,7 @@ DeepWork follows a **Git-native, installation-only** design:
- **No runtime daemon**: DeepWork is purely a CLI tool
- **Git-based workflow**: All work happens on dedicated branches
-- **Skills as interface**: AI agents interact via generated markdown skill files
+- **Skills as interface**: AI agents interact via generated skill files
- **Platform-agnostic**: Works with any AI coding assistant that supports skills
### Directory Structure
@@ -185,12 +185,12 @@ your-project/
│ └── job_name/
│ ├── job.yml # Job metadata
│ └── steps/ # Step instructions
-├── .claude/ # Claude Code commands (auto-generated)
-│ └── commands/
+├── .claude/ # Claude Code skills (auto-generated)
+│ └── skills/
│ ├── deepwork_jobs.define.md
│ └── job_name.step_name.md
-└── .gemini/ # Gemini CLI commands (auto-generated)
- └── commands/
+└── .gemini/ # Gemini CLI skills (auto-generated)
+ └── skills/
└── job_name/
└── step_name.toml
```
diff --git a/claude.md b/claude.md
index 9141a2b9..d5a8d9fd 100644
--- a/claude.md
+++ b/claude.md
@@ -97,9 +97,9 @@ cd my-project/
deepwork install --claude
```
-This installs core commands into `.claude/commands/`:
+This installs core skills into `.claude/skills/`:
- `deepwork_jobs.define` - Interactive job definition wizard
-- `deepwork_jobs.implement` - Generates step files and syncs commands
+- `deepwork_jobs.implement` - Generates step files and syncs skills
- `deepwork_jobs.refine` - Refine existing job definitions
### 2. Job Definition
@@ -118,7 +118,7 @@ This creates the `job.yml` file. Then run:
/deepwork_jobs.implement
```
-This generates step instruction files and syncs commands to `.claude/commands/`.
+This generates step instruction files and syncs skills to `.claude/skills/`.
Job definitions are stored in `.deepwork/jobs/[job-name]/` and tracked in Git.
@@ -146,7 +146,7 @@ Each step:
my-project/
├── .git/
├── .claude/ # Claude Code directory
-│ └── commands/ # Command files
+│ └── skills/ # Skill files
│ ├── deepwork_jobs.define.md
│ ├── deepwork_jobs.implement.md
│ ├── deepwork_jobs.refine.md
@@ -188,11 +188,11 @@ my-project/
1. **Source of truth**: `src/deepwork/standard_jobs/[job_name]/` - The canonical source files
2. **Installed copy**: `.deepwork/jobs/[job_name]/` - Installed by `deepwork install`
-3. **Generated commands**: `.claude/commands/[job_name].[step].md` - Generated from installed jobs
+3. **Generated skills**: `.claude/skills/[job_name].[step].md` - Generated from installed jobs
### Editing Workflow for Standard Jobs
-**NEVER edit files in `.deepwork/jobs/` or `.claude/commands/` for standard jobs directly!**
+**NEVER edit files in `.deepwork/jobs/` or `.claude/skills/` for standard jobs directly!**
Instead, follow this workflow:
@@ -201,7 +201,7 @@ Instead, follow this workflow:
- `steps/*.md` - Step instruction files
- `hooks/*` - Any hook scripts
-2. **Run `deepwork install --platform claude`** to sync changes to `.deepwork/jobs/` and `.claude/commands/`
+2. **Run `deepwork install --platform claude`** to sync changes to `.deepwork/jobs/` and `.claude/skills/`
3. **Verify** the changes propagated correctly to all locations
diff --git a/doc/architecture.md b/doc/architecture.md
index a79377fd..c569abd5 100644
--- a/doc/architecture.md
+++ b/doc/architecture.md
@@ -57,9 +57,9 @@ deepwork/ # DeepWork tool repository
│ │ ├── claude_hook.sh # Shell wrapper for Claude Code
│ │ ├── gemini_hook.sh # Shell wrapper for Gemini CLI
│ │ └── rules_check.py # Cross-platform rule evaluation hook
-│ ├── templates/ # Command templates for each platform
+│ ├── templates/ # Skill templates for each platform
│ │ ├── claude/
-│ │ │ └── command-job-step.md.jinja
+│ │ │ └── skill-job-step.md.jinja
│ │ ├── gemini/
│ │ └── copilot/
│ ├── standard_jobs/ # Built-in job definitions
@@ -136,8 +136,8 @@ def install(platform: str):
write_yaml(".deepwork/config.yml", config)
- # Run sync to generate commands
- sync_commands()
+ # Run sync to generate skills
+ sync_skills()
print(f"✓ DeepWork installed for {platform}")
print(f" Run /deepwork_jobs.define to create your first job")
@@ -149,7 +149,7 @@ Defines the modular adapter architecture for AI platforms. Each adapter encapsul
**Adapter Architecture**:
```python
-class CommandLifecycleHook(str, Enum):
+class SkillLifecycleHook(str, Enum):
"""Generic lifecycle hook events supported by DeepWork."""
AFTER_AGENT = "after_agent" # After agent finishes (quality validation)
BEFORE_TOOL = "before_tool" # Before tool execution
@@ -165,15 +165,15 @@ class AgentAdapter(ABC):
name: ClassVar[str] # "claude"
display_name: ClassVar[str] # "Claude Code"
config_dir: ClassVar[str] # ".claude"
- commands_dir: ClassVar[str] = "commands"
+ skills_dir: ClassVar[str] = "skills"
# Mapping from generic hook names to platform-specific names
- hook_name_mapping: ClassVar[dict[CommandLifecycleHook, str]] = {}
+ hook_name_mapping: ClassVar[dict[SkillLifecycleHook, str]] = {}
def detect(self, project_root: Path) -> bool:
"""Check if this platform is available in the project."""
- def get_platform_hook_name(self, hook: CommandLifecycleHook) -> str | None:
+ def get_platform_hook_name(self, hook: SkillLifecycleHook) -> str | None:
"""Get platform-specific event name for a generic hook."""
@abstractmethod
@@ -187,9 +187,9 @@ class ClaudeAdapter(AgentAdapter):
# Claude Code uses PascalCase event names
hook_name_mapping = {
- CommandLifecycleHook.AFTER_AGENT: "Stop",
- CommandLifecycleHook.BEFORE_TOOL: "PreToolUse",
- CommandLifecycleHook.BEFORE_PROMPT: "UserPromptSubmit",
+ SkillLifecycleHook.AFTER_AGENT: "Stop",
+ SkillLifecycleHook.BEFORE_TOOL: "PreToolUse",
+ SkillLifecycleHook.BEFORE_PROMPT: "UserPromptSubmit",
}
```
@@ -217,24 +217,24 @@ class PlatformDetector:
]
```
-### 4. Command Generator (`generator.py`)
+### 4. Skill Generator (`generator.py`)
-Generates AI-platform-specific command files from job definitions.
+Generates AI-platform-specific skill files from job definitions.
-This component is called by the `sync` command to regenerate all commands:
+This component is called by the `sync` command to regenerate all skills:
1. Reads the job definition from `.deepwork/jobs/[job-name]/job.yml`
2. Loads platform-specific templates
-3. Generates command files for each step in the job
-4. Writes commands to the AI platform's commands directory
+3. Generates skill files for each step in the job
+4. Writes skills to the AI platform's skills directory
**Example Generation Flow**:
```python
-class CommandGenerator:
- def generate_all_commands(self, job: JobDefinition,
+class SkillGenerator:
+ def generate_all_skills(self, job: JobDefinition,
platform: PlatformConfig,
output_dir: Path) -> list[Path]:
- """Generate command files for all steps in a job."""
- command_paths = []
+ """Generate skill files for all steps in a job."""
+ skill_paths = []
for step_index, step in enumerate(job.steps):
# Load step instructions
@@ -252,18 +252,19 @@ class CommandGenerator:
"file_inputs": [inp for inp in step.inputs if inp.is_file_input()],
"outputs": step.outputs,
"dependencies": step.dependencies,
+ "exposed": step.exposed,
}
# Render template
- template = env.get_template("command-job-step.md.jinja")
+ template = env.get_template("skill-job-step.md.jinja")
rendered = template.render(**context)
- # Write to platform's commands directory
- command_path = output_dir / platform.config_dir / platform.commands_dir / f"{job.name}.{step.id}.md"
- write_file(command_path, rendered)
- command_paths.append(command_path)
+ # Write to platform's skills directory
+ skill_path = output_dir / platform.config_dir / platform.skills_dir / f"{job.name}.{step.id}.md"
+ write_file(skill_path, rendered)
+ skill_paths.append(skill_path)
- return command_paths
+ return skill_paths
```
---
@@ -279,8 +280,8 @@ my-project/ # User's project (target)
├── .git/
├── .claude/ # Claude Code directory
│ ├── settings.json # Includes installed hooks
-│ └── commands/ # Command files
-│ ├── deepwork_jobs.define.md # Core DeepWork commands
+│ └── skills/ # Skill files
+│ ├── deepwork_jobs.define.md # Core DeepWork skills
│ ├── deepwork_jobs.implement.md
│ ├── deepwork_jobs.refine.md
│ ├── deepwork_rules.define.md # Rule management
@@ -531,7 +532,7 @@ Create `competitors.md` with this structure:
When the job is defined and `sync` is run, DeepWork generates command files. Example for Claude Code:
-`.deepwork/jobs/competitive_research` a step called `identify_competitors` will generate a command file at `.claude/commands/competitive_research.identify_competitors.md`:
+`.deepwork/jobs/competitive_research` a step called `identify_competitors` will generate a skill file at `.claude/skills/competitive_research.identify_competitors.md`:
# Part 3: Runtime Execution Model
@@ -561,14 +562,14 @@ This section describes how AI agents (like Claude Code) actually execute jobs us
[Interactive dialog to define all the steps]
Claude: ✓ Job 'competitive_research' created with 5 steps
- Run /deepwork_jobs.implement to generate command files
- Then run 'deepwork sync' to install commands
+ Run /deepwork_jobs.implement to generate skill files
+ Then run 'deepwork sync' to install skills
User: /deepwork_jobs.implement
Claude: [Generates step instruction files]
[Runs deepwork sync]
- ✓ Commands installed to .claude/commands/
+ ✓ Skills installed to .claude/skills/
Run /competitive_research.identify_competitors to start
```
@@ -614,22 +615,22 @@ This section describes how AI agents (like Claude Code) actually execute jobs us
PR created: https://github.com/user/project/pull/123
```
-## How Claude Code Executes Commands
+## How Claude Code Executes Skills
When user types `/competitive_research.identify_competitors`:
-1. **Command Discovery**:
- - Claude Code scans `.claude/commands/` directory
+1. **Skill Discovery**:
+ - Claude Code scans `.claude/skills/` directory
- Finds `competitive_research.identify_competitors.md`
- - Loads the command definition
+ - Loads the skill definition
2. **Context Loading**:
- - Command file contains embedded instructions
+ - Skill file contains embedded instructions
- References to job definition and step files
- Claude reads these files to understand the full context
3. **Execution**:
- - Claude follows the instructions in the command
+ - Claude follows the instructions in the skill
- Uses its tools (Read, Write, WebSearch, WebFetch, etc.)
- Creates outputs in the specified format
@@ -641,7 +642,7 @@ When user types `/competitive_research.identify_competitors`:
5. **No DeepWork Runtime**:
- DeepWork CLI is NOT running during execution
- Everything happens through Claude Code's native execution
- - Commands are just markdown instruction files that Claude interprets
+ - Skills are just markdown instruction files that Claude interprets
## Context Passing Between Steps
@@ -669,9 +670,9 @@ Each command instructs Claude to:
- Write specific output files for this step
- All on the same work branch
-### 2. Command Instructions
+### 2. Skill Instructions
-Each command file explicitly states its dependencies:
+Each skill file explicitly states its dependencies:
```markdown
### Prerequisites
@@ -721,9 +722,9 @@ Where `instance-identifier` can be:
**Date format**: `YYYY-MM-DD`
-### Command Behavior
+### Skill Behavior
-Commands should:
+Skills should:
1. Check if we're already on a branch for this job
2. If not, ask user for instance name or auto-generate from timestamp
3. Create branch: `git checkout -b deepwork/[job_name]-[instance]-[date]`
@@ -785,9 +786,9 @@ When a user runs `/deepwork_jobs.define` in Claude Code:
- Interactive question flow
- Job.yml creation logic
-**Command File Structure**:
+**Skill File Structure**:
-The actual command file `.claude/commands/deepwork_jobs.define.md` contains:
+The actual skill file `.claude/skills/deepwork_jobs.define.md` contains:
```markdown
---
@@ -810,7 +811,7 @@ When creating job.yml, use this structure:
### The `/deepwork_jobs.implement` Command
-Generates step instruction files from job.yml and syncs commands:
+Generates step instruction files from job.yml and syncs skills:
```
User: /deepwork_jobs.implement
@@ -824,9 +825,9 @@ Claude: Reading job definition from .deepwork/jobs/competitive_research/job.yml.
✓ Created steps/positioning.md
Running deepwork sync...
- ✓ Generated 5 command files in .claude/commands/
+ ✓ Generated 5 skill files in .claude/skills/
- New commands available:
+ New skills available:
- /competitive_research.identify_competitors
- /competitive_research.primary_research
- /competitive_research.secondary_research
diff --git a/pyproject.toml b/pyproject.toml
index 5aefbca2..a76599d4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "deepwork"
-version = "0.4.1"
+version = "0.5.0"
description = "Framework for enabling AI agents to perform complex, multi-step work tasks"
readme = "README.md"
requires-python = ">=3.11"
diff --git a/src/deepwork/cli/install.py b/src/deepwork/cli/install.py
index 1eaca748..d6909e96 100644
--- a/src/deepwork/cli/install.py
+++ b/src/deepwork/cli/install.py
@@ -354,17 +354,17 @@ def _install_deepwork(platform_name: str | None, project_path: Path) -> None:
save_yaml(config_file, config_data)
console.print(f" [green]✓[/green] Updated {config_file.relative_to(project_path)}")
- # Step 5: Run sync to generate commands
+ # Step 5: Run sync to generate skills
console.print()
- console.print("[yellow]→[/yellow] Running sync to generate commands...")
+ console.print("[yellow]→[/yellow] Running sync to generate skills...")
console.print()
- from deepwork.cli.sync import sync_commands
+ from deepwork.cli.sync import sync_skills
try:
- sync_commands(project_path)
+ sync_skills(project_path)
except Exception as e:
- raise InstallError(f"Failed to sync commands: {e}") from e
+ raise InstallError(f"Failed to sync skills: {e}") from e
# Success message
console.print()
diff --git a/src/deepwork/cli/sync.py b/src/deepwork/cli/sync.py
index b533eb58..072b600a 100644
--- a/src/deepwork/cli/sync.py
+++ b/src/deepwork/cli/sync.py
@@ -7,7 +7,7 @@
from rich.table import Table
from deepwork.core.adapters import AgentAdapter
-from deepwork.core.generator import CommandGenerator
+from deepwork.core.generator import SkillGenerator
from deepwork.core.hooks_syncer import collect_job_hooks, sync_hooks_to_platform
from deepwork.core.parser import parse_job_definition
from deepwork.utils.fs import ensure_dir
@@ -31,13 +31,13 @@ class SyncError(Exception):
)
def sync(path: Path) -> None:
"""
- Sync DeepWork commands to all configured platforms.
+ Sync DeepWork skills to all configured platforms.
- Regenerates all slash-commands for job steps and core commands based on
+ Regenerates all skills for job steps and core skills based on
the current job definitions in .deepwork/jobs/.
"""
try:
- sync_commands(path)
+ sync_skills(path)
except SyncError as e:
console.print(f"[red]Error:[/red] {e}")
raise click.Abort() from e
@@ -46,9 +46,9 @@ def sync(path: Path) -> None:
raise
-def sync_commands(project_path: Path) -> None:
+def sync_skills(project_path: Path) -> None:
"""
- Sync commands to all configured platforms.
+ Sync skills to all configured platforms.
Args:
project_path: Path to project directory
@@ -78,7 +78,7 @@ def sync_commands(project_path: Path) -> None:
"Run 'deepwork install --platform ' to add a platform."
)
- console.print("[bold cyan]Syncing DeepWork Commands[/bold cyan]\n")
+ console.print("[bold cyan]Syncing DeepWork Skills[/bold cyan]\n")
# Discover jobs
jobs_dir = deepwork_dir / "jobs"
@@ -115,8 +115,8 @@ def sync_commands(project_path: Path) -> None:
console.print(f"[yellow]→[/yellow] Found {len(job_hooks_list)} job(s) with hooks")
# Sync each platform
- generator = CommandGenerator()
- stats = {"platforms": 0, "commands": 0, "hooks": 0}
+ generator = SkillGenerator()
+ stats = {"platforms": 0, "skills": 0, "hooks": 0}
synced_adapters: list[AgentAdapter] = []
for platform_name in platforms:
@@ -130,19 +130,19 @@ def sync_commands(project_path: Path) -> None:
console.print(f"\n[yellow]→[/yellow] Syncing to {adapter.display_name}...")
platform_dir = project_path / adapter.config_dir
- commands_dir = platform_dir / adapter.commands_dir
+ skills_dir = platform_dir / adapter.skills_dir
- # Create commands directory
- ensure_dir(commands_dir)
+ # Create skills directory
+ ensure_dir(skills_dir)
- # Generate commands for all jobs
+ # Generate skills for all jobs
if jobs:
- console.print(" [dim]•[/dim] Generating commands...")
+ console.print(" [dim]•[/dim] Generating skills...")
for job in jobs:
try:
- job_paths = generator.generate_all_commands(job, adapter, platform_dir)
- stats["commands"] += len(job_paths)
- console.print(f" [green]✓[/green] {job.name} ({len(job_paths)} commands)")
+ job_paths = generator.generate_all_skills(job, adapter, platform_dir)
+ stats["skills"] += len(job_paths)
+ console.print(f" [green]✓[/green] {job.name} ({len(job_paths)} skills)")
except Exception as e:
console.print(f" [red]✗[/red] Failed for {job.name}: {e}")
@@ -170,7 +170,7 @@ def sync_commands(project_path: Path) -> None:
table.add_column("Count", style="green")
table.add_row("Platforms synced", str(stats["platforms"]))
- table.add_row("Total commands", str(stats["commands"]))
+ table.add_row("Total skills", str(stats["skills"]))
if stats["hooks"] > 0:
table.add_row("Hooks synced", str(stats["hooks"]))
@@ -178,8 +178,8 @@ def sync_commands(project_path: Path) -> None:
console.print()
# Show reload instructions for each synced platform
- if synced_adapters and stats["commands"] > 0:
- console.print("[bold]To use the new commands:[/bold]")
+ if synced_adapters and stats["skills"] > 0:
+ console.print("[bold]To use the new skills:[/bold]")
for adapter in synced_adapters:
console.print(f" [cyan]{adapter.display_name}:[/cyan] {adapter.reload_instructions}")
console.print()
diff --git a/src/deepwork/core/adapters.py b/src/deepwork/core/adapters.py
index 0aa6c27a..9c52bde0 100644
--- a/src/deepwork/core/adapters.py
+++ b/src/deepwork/core/adapters.py
@@ -15,10 +15,10 @@ class AdapterError(Exception):
pass
-class CommandLifecycleHook(str, Enum):
- """Generic command lifecycle hook events supported by DeepWork.
+class SkillLifecycleHook(str, Enum):
+ """Generic skill lifecycle hook events supported by DeepWork.
- These represent hook points in the AI agent's command execution lifecycle.
+ These represent hook points in the AI agent's skill execution lifecycle.
Each adapter maps these generic names to platform-specific event names.
The enum values are the generic names used in job.yml files.
"""
@@ -36,8 +36,8 @@ class CommandLifecycleHook(str, Enum):
BEFORE_PROMPT = "before_prompt"
-# List of all supported command lifecycle hooks
-COMMAND_LIFECYCLE_HOOKS_SUPPORTED: list[CommandLifecycleHook] = list(CommandLifecycleHook)
+# List of all supported skill lifecycle hooks
+SKILL_LIFECYCLE_HOOKS_SUPPORTED: list[SkillLifecycleHook] = list(SkillLifecycleHook)
class AgentAdapter(ABC):
@@ -54,19 +54,17 @@ class AgentAdapter(ABC):
name: ClassVar[str]
display_name: ClassVar[str]
config_dir: ClassVar[str]
- commands_dir: ClassVar[str] = "commands"
- command_template: ClassVar[str] = "command-job-step.md.jinja"
- meta_command_template: ClassVar[str] = "command-job-meta.md.jinja"
+ skills_dir: ClassVar[str] = "skills"
+ skill_template: ClassVar[str] = "skill-job-step.md.jinja"
+ meta_skill_template: ClassVar[str] = "skill-job-meta.md.jinja"
- # Instructions for reloading commands after sync (shown to users)
+ # Instructions for reloading skills after sync (shown to users)
# Subclasses should override with platform-specific instructions.
- reload_instructions: ClassVar[str] = (
- "Restart your AI assistant session to use the new commands."
- )
+ reload_instructions: ClassVar[str] = "Restart your AI assistant session to use the new skills."
- # Mapping from generic CommandLifecycleHook to platform-specific event names.
+ # Mapping from generic SkillLifecycleHook to platform-specific event names.
# Subclasses should override this to provide platform-specific mappings.
- hook_name_mapping: ClassVar[dict[CommandLifecycleHook, str]] = {}
+ hook_name_mapping: ClassVar[dict[SkillLifecycleHook, str]] = {}
def __init__(self, project_root: Path | str | None = None):
"""
@@ -136,15 +134,15 @@ def get_template_dir(self, templates_root: Path) -> Path:
"""
return templates_root / self.name
- def get_commands_dir(self, project_root: Path | None = None) -> Path:
+ def get_skills_dir(self, project_root: Path | None = None) -> Path:
"""
- Get the commands directory path.
+ Get the skills directory path.
Args:
project_root: Project root (uses instance's project_root if not provided)
Returns:
- Path to commands directory
+ Path to skills directory
Raises:
AdapterError: If no project root specified
@@ -152,40 +150,39 @@ def get_commands_dir(self, project_root: Path | None = None) -> Path:
root = project_root or self.project_root
if not root:
raise AdapterError("No project root specified")
- return root / self.config_dir / self.commands_dir
+ return root / self.config_dir / self.skills_dir
- def get_meta_command_filename(self, job_name: str) -> str:
+ def get_meta_skill_filename(self, job_name: str) -> str:
"""
- Get the filename for a job's meta-command.
+ Get the filename for a job's meta-skill.
- The meta-command is the primary user interface for a job.
+ The meta-skill is the primary user interface for a job.
Can be overridden for different file formats.
Args:
job_name: Name of the job
Returns:
- Meta-command filename (e.g., "job_name.md")
+ Meta-skill filename (e.g., "job_name/SKILL.md" for Claude)
"""
- return f"{job_name}.md"
+ return f"{job_name}/SKILL.md"
- def get_step_command_filename(self, job_name: str, step_id: str, exposed: bool = False) -> str:
+ def get_step_skill_filename(self, job_name: str, step_id: str, exposed: bool = False) -> str:
"""
- Get the filename for a step command.
+ Get the filename for a step skill.
- Step commands are hidden by default (uw. prefix) unless exposed=True.
- Can be overridden for different file formats (e.g., TOML for Gemini).
+ All step skills use the same filename format. The exposed parameter
+ is used for template context (user-invocable frontmatter setting).
Args:
job_name: Name of the job
step_id: ID of the step
- exposed: If True, command is visible (no uw. prefix). Default: False.
+ exposed: If True, skill is user-invocable (for template context). Default: False.
Returns:
- Command filename (e.g., "uw.job_name.step_id.md" or "job_name.step_id.md" if exposed)
+ Skill filename (e.g., "job_name.step_id/SKILL.md" for Claude)
"""
- prefix = "" if exposed else "uw."
- return f"{prefix}{job_name}.{step_id}.md"
+ return f"{job_name}.{step_id}/SKILL.md"
def detect(self, project_root: Path | None = None) -> bool:
"""
@@ -203,24 +200,24 @@ def detect(self, project_root: Path | None = None) -> bool:
config_path = root / self.config_dir
return config_path.exists() and config_path.is_dir()
- def get_platform_hook_name(self, hook: CommandLifecycleHook) -> str | None:
+ def get_platform_hook_name(self, hook: SkillLifecycleHook) -> str | None:
"""
Get the platform-specific event name for a generic hook.
Args:
- hook: Generic CommandLifecycleHook
+ hook: Generic SkillLifecycleHook
Returns:
Platform-specific event name, or None if not supported
"""
return self.hook_name_mapping.get(hook)
- def supports_hook(self, hook: CommandLifecycleHook) -> bool:
+ def supports_hook(self, hook: SkillLifecycleHook) -> bool:
"""
Check if this adapter supports a specific hook.
Args:
- hook: Generic CommandLifecycleHook
+ hook: Generic SkillLifecycleHook
Returns:
True if the hook is supported
@@ -260,15 +257,15 @@ def _hook_already_present(hooks: list[dict[str, Any]], script_path: str) -> bool
# =============================================================================
#
# Each adapter must define hook_name_mapping to indicate which hooks it supports.
-# Use an empty dict {} for platforms that don't support command-level hooks.
+# Use an empty dict {} for platforms that don't support skill-level hooks.
#
# Hook support reviewed:
# - Claude Code: Full support (Stop, PreToolUse, UserPromptSubmit) - reviewed 2026-01-16
-# All three command lifecycle hooks are supported in markdown frontmatter.
+# All three skill lifecycle hooks are supported in markdown frontmatter.
# See: doc/platforms/claude/hooks_system.md
-# - Gemini CLI: No command-level hooks (reviewed 2026-01-12)
-# Gemini's hooks are global/project-level in settings.json, not per-command.
-# TOML command files only support 'prompt' and 'description' fields.
+# - Gemini CLI: No skill-level hooks (reviewed 2026-01-12)
+# Gemini's hooks are global/project-level in settings.json, not per-skill.
+# TOML skill files only support 'prompt' and 'description' fields.
# See: doc/platforms/gemini/hooks_system.md
# =============================================================================
@@ -287,10 +284,10 @@ class ClaudeAdapter(AgentAdapter):
)
# Claude Code uses PascalCase event names
- hook_name_mapping: ClassVar[dict[CommandLifecycleHook, str]] = {
- CommandLifecycleHook.AFTER_AGENT: "Stop",
- CommandLifecycleHook.BEFORE_TOOL: "PreToolUse",
- CommandLifecycleHook.BEFORE_PROMPT: "UserPromptSubmit",
+ hook_name_mapping: ClassVar[dict[SkillLifecycleHook, str]] = {
+ SkillLifecycleHook.AFTER_AGENT: "Stop",
+ SkillLifecycleHook.BEFORE_TOOL: "PreToolUse",
+ SkillLifecycleHook.BEFORE_PROMPT: "UserPromptSubmit",
}
def sync_hooks(self, project_path: Path, hooks: dict[str, list[dict[str, Any]]]) -> int:
@@ -351,11 +348,11 @@ def sync_hooks(self, project_path: Path, hooks: dict[str, list[dict[str, Any]]])
class GeminiAdapter(AgentAdapter):
"""Adapter for Gemini CLI.
- Gemini CLI uses TOML format for custom commands stored in .gemini/commands/.
- Commands use colon (:) for namespacing instead of dot (.).
+ Gemini CLI uses TOML format for custom skills stored in .gemini/skills/.
+ Skills use colon (:) for namespacing instead of dot (.).
- Note: Gemini CLI does NOT support command-level hooks. Hooks are configured
- globally in settings.json, not per-command. Therefore, hook_name_mapping
+ Note: Gemini CLI does NOT support skill-level hooks. Hooks are configured
+ globally in settings.json, not per-skill. Therefore, hook_name_mapping
is empty and sync_hooks returns 0.
See: doc/platforms/gemini/hooks_system.md
@@ -364,21 +361,21 @@ class GeminiAdapter(AgentAdapter):
name = "gemini"
display_name = "Gemini CLI"
config_dir = ".gemini"
- command_template = "command-job-step.toml.jinja"
- meta_command_template = "command-job-meta.toml.jinja"
+ skill_template = "skill-job-step.toml.jinja"
+ meta_skill_template = "skill-job-meta.toml.jinja"
# Gemini CLI can reload with /memory refresh
reload_instructions: ClassVar[str] = (
- "Run '/memory refresh' to reload commands, or restart your Gemini CLI session."
+ "Run '/memory refresh' to reload skills, or restart your Gemini CLI session."
)
- # Gemini CLI does NOT support command-level hooks
- # Hooks are global/project-level in settings.json, not per-command
- hook_name_mapping: ClassVar[dict[CommandLifecycleHook, str]] = {}
+ # Gemini CLI does NOT support skill-level hooks
+ # Hooks are global/project-level in settings.json, not per-skill
+ hook_name_mapping: ClassVar[dict[SkillLifecycleHook, str]] = {}
- def get_meta_command_filename(self, job_name: str) -> str:
+ def get_meta_skill_filename(self, job_name: str) -> str:
"""
- Get the filename for a Gemini job's meta-command.
+ Get the filename for a Gemini job's meta-skill.
Gemini uses TOML files and colon namespacing via subdirectories.
For job "my_job", creates: my_job/index.toml
@@ -387,34 +384,34 @@ def get_meta_command_filename(self, job_name: str) -> str:
job_name: Name of the job
Returns:
- Meta-command filename path (e.g., "my_job/index.toml")
+ Meta-skill filename path (e.g., "my_job/index.toml")
"""
return f"{job_name}/index.toml"
- def get_step_command_filename(self, job_name: str, step_id: str, exposed: bool = False) -> str:
+ def get_step_skill_filename(self, job_name: str, step_id: str, exposed: bool = False) -> str:
"""
- Get the filename for a Gemini step command.
+ Get the filename for a Gemini step skill.
Gemini uses TOML files and colon namespacing via subdirectories.
- Step commands are hidden by default (uw. prefix) unless exposed=True.
- For job "my_job" and step "step_one", creates: my_job/uw.step_one.toml
+ All step skills use the same filename format. The exposed parameter
+ is used for template context (user-invocable setting).
+ For job "my_job" and step "step_one", creates: my_job/step_one.toml
Args:
job_name: Name of the job
step_id: ID of the step
- exposed: If True, command is visible (no uw. prefix). Default: False.
+ exposed: If True, skill is user-invocable (for template context). Default: False.
Returns:
- Command filename path (e.g., "my_job/uw.step_one.toml" or "my_job/step_one.toml" if exposed)
+ Skill filename path (e.g., "my_job/step_one.toml")
"""
- prefix = "" if exposed else "uw."
- return f"{job_name}/{prefix}{step_id}.toml"
+ return f"{job_name}/{step_id}.toml"
def sync_hooks(self, project_path: Path, hooks: dict[str, list[dict[str, Any]]]) -> int:
"""
Sync hooks to Gemini CLI settings.
- Gemini CLI does not support command-level hooks. All hooks are
+ Gemini CLI does not support skill-level hooks. All hooks are
configured globally in settings.json. This method is a no-op
that always returns 0.
@@ -423,8 +420,8 @@ def sync_hooks(self, project_path: Path, hooks: dict[str, list[dict[str, Any]]])
hooks: Dict mapping lifecycle events to hook configurations (ignored)
Returns:
- 0 (Gemini does not support command-level hooks)
+ 0 (Gemini does not support skill-level hooks)
"""
- # Gemini CLI does not support command-level hooks
- # Hooks are configured globally in settings.json, not per-command
+ # Gemini CLI does not support skill-level hooks
+ # Hooks are configured globally in settings.json, not per-skill
return 0
diff --git a/src/deepwork/core/generator.py b/src/deepwork/core/generator.py
index 8531f76c..227a2b4d 100644
--- a/src/deepwork/core/generator.py
+++ b/src/deepwork/core/generator.py
@@ -1,24 +1,24 @@
-"""Slash-command file generator using Jinja2 templates."""
+"""Skill file generator using Jinja2 templates."""
from pathlib import Path
from typing import Any
from jinja2 import Environment, FileSystemLoader, TemplateNotFound
-from deepwork.core.adapters import AgentAdapter, CommandLifecycleHook
+from deepwork.core.adapters import AgentAdapter, SkillLifecycleHook
from deepwork.core.parser import JobDefinition, Step
from deepwork.schemas.job_schema import LIFECYCLE_HOOK_EVENTS
from deepwork.utils.fs import safe_read, safe_write
class GeneratorError(Exception):
- """Exception raised for command generation errors."""
+ """Exception raised for skill generation errors."""
pass
-class CommandGenerator:
- """Generates slash-command files from job definitions."""
+class SkillGenerator:
+ """Generates skill files from job definitions."""
def __init__(self, templates_dir: Path | str | None = None):
"""
@@ -163,7 +163,7 @@ def _build_step_context(
for event in LIFECYCLE_HOOK_EVENTS:
if event in step.hooks:
# Get platform-specific event name from adapter
- hook_enum = CommandLifecycleHook(event)
+ hook_enum = SkillLifecycleHook(event)
platform_event_name = adapter.get_platform_hook_name(hook_enum)
if platform_event_name:
hook_contexts = [
@@ -175,7 +175,7 @@ def _build_step_context(
# Backward compatibility: stop_hooks is after_agent hooks
stop_hooks = hooks.get(
- adapter.get_platform_hook_name(CommandLifecycleHook.AFTER_AGENT) or "Stop", []
+ adapter.get_platform_hook_name(SkillLifecycleHook.AFTER_AGENT) or "Stop", []
)
return {
@@ -202,11 +202,11 @@ def _build_step_context(
"quality_criteria": step.quality_criteria, # Declarative criteria with framing
}
- def _build_meta_command_context(
+ def _build_meta_skill_context(
self, job: JobDefinition, adapter: AgentAdapter
) -> dict[str, Any]:
"""
- Build template context for a job's meta-command.
+ Build template context for a job's meta-skill.
Args:
job: Job definition
@@ -215,27 +215,28 @@ def _build_meta_command_context(
Returns:
Template context dictionary
"""
- # Build step info for the meta-command
+ # Build step info for the meta-skill
steps_info = []
for step in job.steps:
- command_filename = adapter.get_step_command_filename(job.name, step.id, step.exposed)
- # Extract just the command name (without path and extension)
- # For Claude: uw.job_name.step_id.md -> uw.job_name.step_id
- # For Gemini: job_name/uw.step_id.toml -> job_name:uw.step_id
+ skill_filename = adapter.get_step_skill_filename(job.name, step.id, step.exposed)
+ # Extract just the skill name (without path and extension)
+ # For Claude: job_name.step_id/SKILL.md -> job_name.step_id
+ # For Gemini: job_name/step_id.toml -> job_name:step_id
if adapter.name == "gemini":
- # Gemini uses colon for namespacing: job_name:step_id or job_name:uw.step_id
- parts = command_filename.replace(".toml", "").split("/")
- command_name = ":".join(parts)
+ # Gemini uses colon for namespacing: job_name:step_id
+ parts = skill_filename.replace(".toml", "").split("/")
+ skill_name = ":".join(parts)
else:
- # Claude uses dot for namespacing: uw.job_name.step_id
- command_name = command_filename.replace(".md", "")
+ # Claude uses directory/SKILL.md format, extract directory name
+ # job_name.step_id/SKILL.md -> job_name.step_id
+ skill_name = skill_filename.replace("/SKILL.md", "")
steps_info.append(
{
"id": step.id,
"name": step.name,
"description": step.description,
- "command_name": command_name,
+ "command_name": skill_name,
"dependencies": step.dependencies,
"exposed": step.exposed,
}
@@ -250,65 +251,65 @@ def _build_meta_command_context(
"steps": steps_info,
}
- def generate_meta_command(
+ def generate_meta_skill(
self,
job: JobDefinition,
adapter: AgentAdapter,
output_dir: Path | str,
) -> Path:
"""
- Generate the meta-command file for a job.
+ Generate the meta-skill file for a job.
- The meta-command is the primary user interface for a job, routing
+ The meta-skill is the primary user interface for a job, routing
user intent to the appropriate step.
Args:
job: Job definition
adapter: Agent adapter for the target platform
- output_dir: Directory to write command file to
+ output_dir: Directory to write skill file to
Returns:
- Path to generated meta-command file
+ Path to generated meta-skill file
Raises:
GeneratorError: If generation fails
"""
output_dir = Path(output_dir)
- # Create commands subdirectory if needed
- commands_dir = output_dir / adapter.commands_dir
- commands_dir.mkdir(parents=True, exist_ok=True)
+ # Create skills subdirectory if needed
+ skills_dir = output_dir / adapter.skills_dir
+ skills_dir.mkdir(parents=True, exist_ok=True)
# Build context
- context = self._build_meta_command_context(job, adapter)
+ context = self._build_meta_skill_context(job, adapter)
# Load and render template
env = self._get_jinja_env(adapter)
try:
- template = env.get_template(adapter.meta_command_template)
+ template = env.get_template(adapter.meta_skill_template)
except TemplateNotFound as e:
- raise GeneratorError(f"Meta-command template not found: {e}") from e
+ raise GeneratorError(f"Meta-skill template not found: {e}") from e
try:
rendered = template.render(**context)
except Exception as e:
- raise GeneratorError(f"Meta-command template rendering failed: {e}") from e
+ raise GeneratorError(f"Meta-skill template rendering failed: {e}") from e
- # Write meta-command file
- command_filename = adapter.get_meta_command_filename(job.name)
- command_path = commands_dir / command_filename
+ # Write meta-skill file
+ skill_filename = adapter.get_meta_skill_filename(job.name)
+ skill_path = skills_dir / skill_filename
# Ensure parent directories exist (for Gemini's job_name/index.toml structure)
- command_path.parent.mkdir(parents=True, exist_ok=True)
+ skill_path.parent.mkdir(parents=True, exist_ok=True)
try:
- safe_write(command_path, rendered)
+ safe_write(skill_path, rendered)
except Exception as e:
- raise GeneratorError(f"Failed to write meta-command file: {e}") from e
+ raise GeneratorError(f"Failed to write meta-skill file: {e}") from e
- return command_path
+ return skill_path
- def generate_step_command(
+ def generate_step_skill(
self,
job: JobDefinition,
step: Step,
@@ -316,25 +317,25 @@ def generate_step_command(
output_dir: Path | str,
) -> Path:
"""
- Generate slash-command file for a single step.
+ Generate skill file for a single step.
Args:
job: Job definition
- step: Step to generate command for
+ step: Step to generate skill for
adapter: Agent adapter for the target platform
- output_dir: Directory to write command file to
+ output_dir: Directory to write skill file to
Returns:
- Path to generated command file
+ Path to generated skill file
Raises:
GeneratorError: If generation fails
"""
output_dir = Path(output_dir)
- # Create commands subdirectory if needed
- commands_dir = output_dir / adapter.commands_dir
- commands_dir.mkdir(parents=True, exist_ok=True)
+ # Create skills subdirectory if needed
+ skills_dir = output_dir / adapter.skills_dir
+ skills_dir.mkdir(parents=True, exist_ok=True)
# Find step index
try:
@@ -342,13 +343,14 @@ def generate_step_command(
except StopIteration as e:
raise GeneratorError(f"Step '{step.id}' not found in job '{job.name}'") from e
- # Build context
+ # Build context (include exposed for template user-invocable setting)
context = self._build_step_context(job, step, step_index, adapter)
+ context["exposed"] = step.exposed
# Load and render template
env = self._get_jinja_env(adapter)
try:
- template = env.get_template(adapter.command_template)
+ template = env.get_template(adapter.skill_template)
except TemplateNotFound as e:
raise GeneratorError(f"Template not found: {e}") from e
@@ -357,49 +359,49 @@ def generate_step_command(
except Exception as e:
raise GeneratorError(f"Template rendering failed: {e}") from e
- # Write command file (hidden by default unless step.exposed is True)
- command_filename = adapter.get_step_command_filename(job.name, step.id, step.exposed)
- command_path = commands_dir / command_filename
+ # Write skill file
+ skill_filename = adapter.get_step_skill_filename(job.name, step.id, step.exposed)
+ skill_path = skills_dir / skill_filename
# Ensure parent directories exist (for Gemini's job_name/step_id.toml structure)
- command_path.parent.mkdir(parents=True, exist_ok=True)
+ skill_path.parent.mkdir(parents=True, exist_ok=True)
try:
- safe_write(command_path, rendered)
+ safe_write(skill_path, rendered)
except Exception as e:
- raise GeneratorError(f"Failed to write command file: {e}") from e
+ raise GeneratorError(f"Failed to write skill file: {e}") from e
- return command_path
+ return skill_path
- def generate_all_commands(
+ def generate_all_skills(
self,
job: JobDefinition,
adapter: AgentAdapter,
output_dir: Path | str,
) -> list[Path]:
"""
- Generate all command files for a job: meta-command and step commands.
+ Generate all skill files for a job: meta-skill and step skills.
Args:
job: Job definition
adapter: Agent adapter for the target platform
- output_dir: Directory to write command files to
+ output_dir: Directory to write skill files to
Returns:
- List of paths to generated command files (meta-command first, then steps)
+ List of paths to generated skill files (meta-skill first, then steps)
Raises:
GeneratorError: If generation fails
"""
- command_paths = []
+ skill_paths = []
- # Generate meta-command first (job-level entry point)
- meta_command_path = self.generate_meta_command(job, adapter, output_dir)
- command_paths.append(meta_command_path)
+ # Generate meta-skill first (job-level entry point)
+ meta_skill_path = self.generate_meta_skill(job, adapter, output_dir)
+ skill_paths.append(meta_skill_path)
- # Generate step commands (hidden by default unless step.exposed is True)
+ # Generate step skills
for step in job.steps:
- command_path = self.generate_step_command(job, step, adapter, output_dir)
- command_paths.append(command_path)
+ skill_path = self.generate_step_skill(job, step, adapter, output_dir)
+ skill_paths.append(skill_path)
- return command_paths
+ return skill_paths
diff --git a/src/deepwork/core/parser.py b/src/deepwork/core/parser.py
index 3585d02e..61abceb8 100644
--- a/src/deepwork/core/parser.py
+++ b/src/deepwork/core/parser.py
@@ -108,7 +108,7 @@ class Step:
# Event names: after_agent, before_tool, before_prompt
hooks: dict[str, list[HookAction]] = field(default_factory=dict)
- # If true, step command is visible (no uw. prefix). Default: false (hidden).
+ # If true, skill is user-invocable in menus. Default: false (hidden from menus).
exposed: bool = False
# Declarative quality criteria rendered with standard evaluation framing
diff --git a/src/deepwork/schemas/job_schema.py b/src/deepwork/schemas/job_schema.py
index 29c4df1f..a3ef7260 100644
--- a/src/deepwork/schemas/job_schema.py
+++ b/src/deepwork/schemas/job_schema.py
@@ -3,7 +3,7 @@
from typing import Any
# Supported lifecycle hook events (generic names, mapped to platform-specific by adapters)
-# These values must match CommandLifecycleHook enum in adapters.py
+# These values must match SkillLifecycleHook enum in adapters.py
LIFECYCLE_HOOK_EVENTS = ["after_agent", "before_tool", "before_prompt"]
# Schema definition for a single hook action (prompt, prompt_file, or script)
@@ -205,7 +205,7 @@
},
"exposed": {
"type": "boolean",
- "description": "If true, step command is visible (no uw. prefix). Default: false (hidden).",
+ "description": "If true, skill is user-invocable in menus. Default: false (hidden from menus).",
"default": False,
},
"quality_criteria": {
diff --git a/src/deepwork/standard_jobs/deepwork_jobs/steps/implement.md b/src/deepwork/standard_jobs/deepwork_jobs/steps/implement.md
index 7771eaee..34caed9f 100644
--- a/src/deepwork/standard_jobs/deepwork_jobs/steps/implement.md
+++ b/src/deepwork/standard_jobs/deepwork_jobs/steps/implement.md
@@ -113,9 +113,9 @@ See `.deepwork/jobs/deepwork_jobs/steps/supplemental_file_references.md` for det
Verify that `job.yml` is in the correct location at `.deepwork/jobs/[job_name]/job.yml`. The define step should have created it there. If for some reason it's not there, you may need to create or move it.
-### Step 5: Sync Commands
+### Step 5: Sync Skills
-Run `deepwork sync` to generate the slash-commands for this job:
+Run `deepwork sync` to generate the skills for this job:
```bash
deepwork sync
@@ -123,12 +123,12 @@ deepwork sync
This will:
- Parse the job definition
-- Generate slash-commands for each step
-- Make the commands available in `.claude/commands/` (or appropriate platform directory)
+- Generate skills for each step
+- Make the skills available in `.claude/skills/` (or appropriate platform directory)
### Step 6: Relay Reload Instructions
-After running `deepwork sync`, look at the "To use the new commands" section in the output. **Relay these exact reload instructions to the user** so they know how to pick up the new commands. Don't just reference the sync output - tell them directly what they need to do (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code, or "Run '/memory refresh'" for Gemini CLI).
+After running `deepwork sync`, look at the "To use the new skills" section in the output. **Relay these exact reload instructions to the user** so they know how to pick up the new skills. Don't just reference the sync output - tell them directly what they need to do (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code, or "Run '/memory refresh'" for Gemini CLI).
### Step 7: Consider Rules for the New Job
@@ -220,7 +220,7 @@ Before marking this step complete, ensure:
- [ ] All step instruction files created
- [ ] Each instruction file is complete and actionable
- [ ] `deepwork sync` executed successfully
-- [ ] Commands generated in platform directory
+- [ ] Skills generated in platform directory
- [ ] User informed to follow reload instructions from `deepwork sync`
- [ ] Considered whether rules would benefit this job (Step 7)
- [ ] If rules suggested, offered to run `/deepwork_rules.define`
@@ -234,5 +234,5 @@ Before marking this step complete, ensure:
- Quality criteria defined for each step
- Steps with user inputs explicitly use "ask structured questions" phrasing
- Sync completed successfully
-- Commands available for use
+- Skills available for use
- Thoughtfully considered relevant rules for the job domain
diff --git a/src/deepwork/standard_jobs/deepwork_jobs/steps/learn.md b/src/deepwork/standard_jobs/deepwork_jobs/steps/learn.md
index 36bfd8c7..f89a8873 100644
--- a/src/deepwork/standard_jobs/deepwork_jobs/steps/learn.md
+++ b/src/deepwork/standard_jobs/deepwork_jobs/steps/learn.md
@@ -171,7 +171,7 @@ If instruction files were modified:
deepwork sync
```
-2. **If commands were regenerated**, look at the "To use the new commands" section in the `deepwork sync` output and **relay these exact reload instructions to the user** (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code)
+2. **If skills were regenerated**, look at the "To use the new skills" section in the `deepwork sync` output and **relay these exact reload instructions to the user** (e.g., "Type 'exit' then run 'claude --resume'" for Claude Code)
## File Reference Patterns
@@ -261,7 +261,7 @@ I found the following job executions:
**Summary**
-Updated job instructions and created AGENTS.md with bespoke learnings. To get the updated commands, type 'exit' then run 'claude --resume'.
+Updated job instructions and created AGENTS.md with bespoke learnings. To get the updated skills, type 'exit' then run 'claude --resume'.
```
## Handling Edge Cases
diff --git a/src/deepwork/standard_jobs/deepwork_rules/rules/skill-md-validation.md b/src/deepwork/standard_jobs/deepwork_rules/rules/skill-md-validation.md
new file mode 100644
index 00000000..6f7cb3d2
--- /dev/null
+++ b/src/deepwork/standard_jobs/deepwork_rules/rules/skill-md-validation.md
@@ -0,0 +1,45 @@
+---
+name: SKILL.md Validation
+trigger: "**/SKILL.md"
+---
+A SKILL.md file has been created or modified. Please validate that it follows the required format:
+
+## Required Structure
+
+The file MUST have valid YAML frontmatter at the start, enclosed between `---` markers:
+
+```markdown
+---
+name: my-skill-name
+description: A description of what this skill does
+---
+
+# Rest of the skill documentation...
+```
+
+## Validation Checklist
+
+1. **YAML Frontmatter**: Verify the file starts with `---` followed by valid YAML and ends with `---`
+
+2. **`name` field** (required):
+ - Must be present in the frontmatter
+ - Must contain only lowercase letters, numbers, and hyphens (`a-z`, `0-9`, `-`)
+ - Must be 64 characters or fewer
+ - Example valid names: `my-skill`, `code-review-2`, `lint`
+ - Example invalid names: `My Skill` (uppercase/spaces), `skill_name` (underscores), `SKILL` (uppercase)
+
+3. **`description` field** (required):
+ - Must be present in the frontmatter
+ - Must be 1024 characters or fewer
+ - Should clearly describe what the skill does
+
+## What to Check
+
+For the modified file: {trigger_files}
+
+1. Parse the YAML frontmatter and verify it is valid YAML
+2. Check that `name` exists and matches the pattern `^[a-z0-9-]+$` with max length 64
+3. Check that `description` exists and is at most 1024 characters
+4. Report any validation errors to the user
+
+If the file does not pass validation, help the user fix the issues.
diff --git a/src/deepwork/templates/claude/command-job-meta.md.jinja b/src/deepwork/templates/claude/command-job-meta.md.jinja
deleted file mode 100644
index 66de2041..00000000
--- a/src/deepwork/templates/claude/command-job-meta.md.jinja
+++ /dev/null
@@ -1,53 +0,0 @@
----
-description: {{ job_summary }}
----
-
-# {{ job_name }}
-
-You are executing the **{{ job_name }}** job. {{ job_summary }}
-
-{% if job_description %}
-{{ job_description }}
-{% endif %}
-
-## Available Steps
-
-This job has {{ total_steps }} step(s):
-
-{% for step in steps %}
-### {{ step.id }}
-**{{ step.name }}**: {{ step.description }}
-- Command: `{{ step.command_name }}`
-{% if step.dependencies %}
-- Requires: {{ step.dependencies | join(', ') }}
-{% endif %}
-{% endfor %}
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and run through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/{{ job_name }}`
-
-2. **Identify the starting step** based on intent:
-{% for step in steps %}
- - {{ step.id }}: {{ step.description }}
-{% endfor %}
-
-3. **Run the workflow** starting from the identified step:
- - Invoke the starting step using the Skill tool
- - When that step completes, **automatically continue** to the next step in the workflow
- - Continue until the workflow is complete or the user intervenes
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Use AskUserQuestion to let them choose
-
-**Critical**:
-- You MUST invoke each step using the Skill tool. Do not copy/paste step instructions.
-- After each step completes, check if there's a next step and invoke it automatically.
-- The workflow continues until all dependent steps are complete.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/{{ job_name }}/job.yml`
diff --git a/src/deepwork/templates/claude/command-job-step.md.jinja b/src/deepwork/templates/claude/command-job-step.md.jinja
deleted file mode 100644
index 5793dc3f..00000000
--- a/src/deepwork/templates/claude/command-job-step.md.jinja
+++ /dev/null
@@ -1,221 +0,0 @@
----
-description: {{ step_description }}
-{% if quality_criteria or hooks %}
-hooks:
-{% if quality_criteria %}
- Stop:
- - hooks:
- - type: prompt
- prompt: |
- You must evaluate whether Claude has met all the below quality criteria for the request.
-
- ## Quality Criteria
-
-{% for criterion in quality_criteria %}
- {{ loop.index }}. {{ criterion }}
-{% endfor %}
-
- ## Instructions
-
- Review the conversation and determine if ALL quality criteria above have been satisfied.
- Look for evidence that each criterion has been addressed.
-
- If the agent has included `✓ Quality Criteria Met` in their response AND
- all criteria appear to be met, respond with: {"ok": true}
-
- If criteria are NOT met OR the promise tag is missing, respond with:
- {"ok": false, "reason": "**AGENT: TAKE ACTION** - [which criteria failed and why]"}
-{% endif %}
-{% for event_name, event_hooks in hooks.items() %}
-{% if not (event_name == "Stop" and quality_criteria) %}
- {{ event_name }}:
- - hooks:
-{% for hook in event_hooks %}
-{% if hook.type == "script" %}
- - type: command
- command: ".deepwork/jobs/{{ job_name }}/{{ hook.path }}"
-{% else %}
- - type: prompt
- prompt: |
- {{ hook.content | indent(12) }}
-{% endif %}
-{% endfor %}
-{% endif %}
-{% endfor %}
-{% endif %}
----
-
-# {{ job_name }}.{{ step_id }}
-
-{% if is_standalone %}
-**Standalone command** in the **{{ job_name }}** job - can be run anytime
-{% else %}
-**Step {{ step_number }} of {{ total_steps }}** in the **{{ job_name }}** workflow
-{% endif %}
-
-**Summary**: {{ job_summary }}
-
-{% if job_description %}
-## Job Overview
-
-{{ job_description }}
-{% endif %}
-
-{% if dependencies %}
-## Prerequisites
-
-This step requires completion of the following step(s):
-{% for dep in dependencies %}
-- `/{{ job_name }}.{{ dep }}`
-{% endfor %}
-
-Please ensure these steps have been completed before proceeding.
-{% endif %}
-
-## Instructions
-
-{{ instructions_content }}
-
-{% if user_inputs or file_inputs %}
-## Inputs
-
-{% if user_inputs %}
-### User Parameters
-
-Please gather the following information from the user:
-{% for input in user_inputs %}
-- **{{ input.name }}**: {{ input.description }}
-{% endfor %}
-{% endif %}
-
-{% if file_inputs %}
-### Required Files
-
-This step requires the following files from previous steps:
-{% for input in file_inputs %}
-- `{{ input.file }}` (from step `{{ input.from_step }}`)
-{% endfor %}
-
-Make sure to read and use these files as context for this step.
-{% endif %}
-{% endif %}
-
-## Work Branch Management
-
-All work for this job should be done on a dedicated work branch:
-
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/{{ job_name }}-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
-
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/{{ job_name }}-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-
-## Output Requirements
-
-{% if outputs %}
-Create the following output(s):
-{% for output in outputs %}
-- `{{ output }}`{% if output.endswith('/') %} (directory){% endif %}
-{% endfor %}
-
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
-{% else %}
-No specific files are output by this command.
-{% endif %}
-
-{% if quality_criteria or stop_hooks %}
-## Quality Validation Loop
-
-This step uses an iterative quality validation loop. After completing your work, stop hook(s) will evaluate whether the outputs meet quality criteria. If criteria are not met, you will be prompted to continue refining.
-
-{% if quality_criteria %}
-### Quality Criteria
-
-{% for criterion in quality_criteria %}
-{{ loop.index }}. {{ criterion }}
-{% endfor %}
-{% endif %}
-
-{% for hook in stop_hooks %}
-{% if hook.type == "script" %}
-**Validation Script**: `.deepwork/jobs/{{ job_name }}/{{ hook.path }}`
-
-The validation script will be executed automatically when you attempt to complete this step.
-{% endif %}
-{% endfor %}
-
-### Completion Promise
-
-To signal that all quality criteria have been met, include this tag in your final response:
-
-```
-✓ Quality Criteria Met
-```
-
-**Important**: Only include this promise tag when you have verified that ALL quality criteria above are satisfied. The validation loop will continue until this promise is detected.
-
-{% endif %}
-## Completion
-
-After completing this step:
-
-1. **Verify outputs**: Confirm all required files have been created
-
-2. **Inform the user**:
-{% if is_standalone %}
- - The {{ step_id }} command is complete
-{% if outputs %}
- - Outputs created: {{ outputs | join(', ') }}
-{% endif %}
- - This command can be run again anytime to make further changes
-{% else %}
- - Step {{ step_number }} of {{ total_steps }} is complete
-{% if outputs %}
- - Outputs created: {{ outputs | join(', ') }}
-{% endif %}
- {% if next_step %}
- - Ready to proceed to next step: `/{{ job_name }}.{{ next_step }}`
- {% else %}
- - This is the final step - the job is complete!
- {% endif %}
-{% endif %}
-
-{% if is_standalone %}
-## Command Complete
-
-This is a standalone command that can be run anytime. The outputs are ready for use.
-
-Consider:
-- Reviewing the outputs
-- Running `deepwork sync` if job definitions were changed
-- Re-running this command later if further changes are needed
-{% elif next_step %}
-## Next Step
-
-To continue the workflow, run:
-```
-/{{ job_name }}.{{ next_step }}
-```
-{% else %}
-## Workflow Complete
-
-This is the final step in the {{ job_name }} workflow. All outputs should now be complete and ready for review.
-
-Consider:
-- Reviewing all work products
-- Creating a pull request to merge the work branch
-- Documenting any insights or learnings
-{% endif %}
-
----
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/{{ job_name }}/job.yml`
-- Step instructions: `.deepwork/jobs/{{ job_name }}/{{ instructions_file }}`
diff --git a/src/deepwork/templates/claude/skill-job-meta.md.jinja b/src/deepwork/templates/claude/skill-job-meta.md.jinja
new file mode 100644
index 00000000..54de8fad
--- /dev/null
+++ b/src/deepwork/templates/claude/skill-job-meta.md.jinja
@@ -0,0 +1,70 @@
+{#
+Template: skill-job-meta.md.jinja
+Purpose: Generates the job overview skill file for Claude Code
+
+Template Variables:
+ - job_name: string - Job identifier (e.g., "competitive_research")
+ - job_summary: string - Short one-line summary of the job
+ - job_description: string|null - Full description (optional)
+ - total_steps: int - Number of steps in the job
+ - steps: list - Array of step objects:
+ - id: string - Step identifier
+ - name: string - Human-readable step name
+ - description: string - What the step does
+ - command_name: string - Slash command (e.g., "job_name.step_id")
+ - dependencies: list[string]|null - Required prior steps
+#}
+---
+name: {{ job_name }}
+description: "{{ job_summary }}"
+---
+
+# {{ job_name }}
+
+**Multi-step workflow**: {{ job_summary }}
+
+> **CRITICAL**: Always invoke steps using the Skill tool. Never copy/paste step instructions directly.
+
+{% if job_description %}
+{{ job_description }}
+{% endif %}
+
+## Available Steps
+
+{% for step in steps %}
+{{ loop.index }}. **{{ step.id }}** - {{ step.description }}{% if step.dependencies %} (requires: {{ step.dependencies | join(', ') }}){% endif %}
+
+{% endfor %}
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/{{ job_name }}` to determine user intent:
+{% for step in steps %}
+- "{{ step.id }}" or related terms → start at `{{ step.command_name }}`
+{% endfor %}
+
+### Step 2: Invoke Starting Step
+
+Use the Skill tool to invoke the identified starting step:
+```
+Skill tool: {{ steps[0].command_name }}
+```
+
+### Step 3: Continue Workflow Automatically
+
+After each step completes:
+1. Check if there's a next step in the sequence
+2. Invoke the next step using the Skill tool
+3. Repeat until workflow is complete or user intervenes
+
+### Handling Ambiguous Intent
+
+If user intent is unclear, use AskUserQuestion to clarify:
+- Present available steps as numbered options
+- Let user select the starting point
+
+## Context Files
+
+- Job definition: `.deepwork/jobs/{{ job_name }}/job.yml`
diff --git a/src/deepwork/templates/claude/skill-job-step.md.jinja b/src/deepwork/templates/claude/skill-job-step.md.jinja
new file mode 100644
index 00000000..ed534958
--- /dev/null
+++ b/src/deepwork/templates/claude/skill-job-step.md.jinja
@@ -0,0 +1,198 @@
+{#
+Template: skill-job-step.md.jinja
+Purpose: Generates individual step skill files for Claude Code
+
+Template Variables:
+ Job Context:
+ - job_name: string - Job identifier
+ - job_summary: string - Short job summary
+ - job_description: string|null - Full job description
+
+ Step Metadata:
+ - step_id: string - Step identifier
+ - step_description: string - What this step does
+ - step_number: int - Position in workflow (1-indexed)
+ - total_steps: int - Total steps in job
+ - is_standalone: bool - True if step can run independently
+ - exposed: bool - True if user can invoke directly (default: true)
+ - dependencies: list[string]|null - Required prior step IDs
+ - next_step: string|null - Next step ID in workflow
+ - instructions_file: string - Path to step instructions file
+
+ Step Content:
+ - instructions_content: string - Full instructions markdown
+ - user_inputs: list|null - User parameters to gather:
+ - name: string - Parameter name
+ - description: string - What to ask for
+ - file_inputs: list|null - Files from previous steps:
+ - file: string - File path
+ - from_step: string - Source step ID
+ - outputs: list[string]|null - Output file paths
+
+ Quality & Hooks:
+ - quality_criteria: list[string]|null - Criteria for completion
+ - stop_hooks: list|null - Stop hook configurations:
+ - type: "script"|"prompt"
+ - path: string (for script)
+ - content: string (for prompt)
+ - hooks: dict|null - All hooks by event name (Stop, PreToolUse, etc.)
+#}
+---
+name: {{ job_name }}.{{ step_id }}
+description: "{{ step_description }}"
+{% if not exposed %}
+user-invocable: false
+{% endif %}
+{% if quality_criteria or hooks %}
+hooks:
+{% if quality_criteria %}
+ Stop:
+ - hooks:
+ - type: prompt
+ prompt: |
+ You must evaluate whether Claude has met all the below quality criteria for the request.
+
+ ## Quality Criteria
+
+{% for criterion in quality_criteria %}
+ {{ loop.index }}. {{ criterion }}
+{% endfor %}
+
+ ## Instructions
+
+ Review the conversation and determine if ALL quality criteria above have been satisfied.
+ Look for evidence that each criterion has been addressed.
+
+ If the agent has included `✓ Quality Criteria Met` in their response AND
+ all criteria appear to be met, respond with: {"ok": true}
+
+ If criteria are NOT met OR the promise tag is missing, respond with:
+ {"ok": false, "reason": "**AGENT: TAKE ACTION** - [which criteria failed and why]"}
+{% endif %}
+{% for event_name, event_hooks in hooks.items() %}
+{% if not (event_name == "Stop" and quality_criteria) %}
+ {{ event_name }}:
+ - hooks:
+{% for hook in event_hooks %}
+{% if hook.type == "script" %}
+ - type: command
+ command: ".deepwork/jobs/{{ job_name }}/{{ hook.path }}"
+{% else %}
+ - type: prompt
+ prompt: |
+ {{ hook.content | indent(12) }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+---
+
+# {{ job_name }}.{{ step_id }}
+
+{% if is_standalone %}
+**Standalone skill** - can be run anytime
+{% else %}
+**Step {{ step_number }}/{{ total_steps }}** in **{{ job_name }}** workflow
+{% endif %}
+
+> {{ job_summary }}
+
+{% if dependencies %}
+## Prerequisites (Verify First)
+
+Before proceeding, confirm these steps are complete:
+{% for dep in dependencies %}
+- `/{{ job_name }}.{{ dep }}`
+{% endfor %}
+{% endif %}
+
+## Instructions
+
+**Goal**: {{ step_description }}
+
+{{ instructions_content }}
+
+{% if job_description %}
+### Job Context
+
+{{ job_description }}
+{% endif %}
+
+{% if user_inputs or file_inputs %}
+## Required Inputs
+
+{% if user_inputs %}
+**User Parameters** - Gather from user before starting:
+{% for input in user_inputs %}
+- **{{ input.name }}**: {{ input.description }}
+{% endfor %}
+{% endif %}
+
+{% if file_inputs %}
+**Files from Previous Steps** - Read these first:
+{% for input in file_inputs %}
+- `{{ input.file }}` (from `{{ input.from_step }}`)
+{% endfor %}
+{% endif %}
+{% endif %}
+
+## Work Branch
+
+Use branch format: `deepwork/{{ job_name }}-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/{{ job_name }}-[instance]-$(date +%Y%m%d)`
+
+## Outputs
+
+{% if outputs %}
+**Required outputs**:
+{% for output in outputs %}
+- `{{ output }}`{% if output.endswith('/') %} (directory){% endif %}
+{% endfor %}
+{% else %}
+No specific file outputs required.
+{% endif %}
+
+{% if quality_criteria or stop_hooks %}
+## Quality Validation
+
+Stop hooks will automatically validate your work. The loop continues until all criteria pass.
+
+{% if quality_criteria %}
+**Criteria (all must be satisfied)**:
+{% for criterion in quality_criteria %}
+{{ loop.index }}. {{ criterion }}
+{% endfor %}
+{% endif %}
+
+{% for hook in stop_hooks %}
+{% if hook.type == "script" %}
+**Validation script**: `.deepwork/jobs/{{ job_name }}/{{ hook.path }}` (runs automatically)
+{% endif %}
+{% endfor %}
+
+**To complete**: Include `✓ Quality Criteria Met` in your final response only after verifying ALL criteria are satisfied.
+
+{% endif %}
+## On Completion
+
+{% if is_standalone %}
+1. Verify outputs are created
+2. Inform user: "{{ step_id }} complete{% if outputs %}, outputs: {{ outputs | join(', ') }}{% endif %}"
+
+This standalone skill can be re-run anytime.
+{% else %}
+1. Verify outputs are created
+2. Inform user: "Step {{ step_number }}/{{ total_steps }} complete{% if outputs %}, outputs: {{ outputs | join(', ') }}{% endif %}"
+{% if next_step %}
+3. **Continue workflow**: Use Skill tool to invoke `/{{ job_name }}.{{ next_step }}`
+{% else %}
+3. **Workflow complete**: All steps finished. Consider creating a PR to merge the work branch.
+{% endif %}
+{% endif %}
+
+---
+
+**Reference files**: `.deepwork/jobs/{{ job_name }}/job.yml`, `.deepwork/jobs/{{ job_name }}/{{ instructions_file }}`
diff --git a/src/deepwork/templates/gemini/command-job-meta.toml.jinja b/src/deepwork/templates/gemini/command-job-meta.toml.jinja
deleted file mode 100644
index d0ffefa1..00000000
--- a/src/deepwork/templates/gemini/command-job-meta.toml.jinja
+++ /dev/null
@@ -1,61 +0,0 @@
-# {{ job_name }}
-#
-# {{ job_summary }}
-#
-# Generated by DeepWork - do not edit manually
-
-description = "{{ job_summary | replace('"', '\\"') }}"
-
-prompt = """
-# {{ job_name }}
-
-You are executing the **{{ job_name }}** job. {{ job_summary }}
-
-{% if job_description %}
-{{ job_description }}
-{% endif %}
-
-## Available Steps
-
-This job has {{ total_steps }} step(s):
-
-{% for step in steps %}
-### {{ step.id }}
-**{{ step.name }}**: {{ step.description }}
-- Command: `/{{ step.command_name }}`
-{% if step.dependencies %}
-- Requires: {{ step.dependencies | join(', ') }}
-{% endif %}
-{% endfor %}
-
-## Instructions
-
-This is a **multi-step workflow**. Determine the starting point and guide the user through the steps in sequence.
-
-1. **Analyze user intent** from the text that follows `/{{ job_name }}`
-
-2. **Identify the starting step** based on intent:
-{% for step in steps %}
- - {{ step.id }}: {{ step.description }}
-{% endfor %}
-
-3. **Guide the user through the workflow**:
- - Tell the user to run the starting step command
- - After each step completes, guide them to the next step in the workflow
- - Continue until the workflow is complete
-
- Step commands:
-{% for step in steps %}
- - {{ step.id }}: `/{{ step.command_name }}`
-{% endfor %}
-
-4. **If intent is ambiguous**, ask the user which step to start from:
- - Present the available steps as numbered options
- - Let them choose
-
-**Note**: Gemini CLI requires manual command invocation. After each step completes, remind the user to run the next step command.
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/{{ job_name }}/job.yml`
-"""
diff --git a/src/deepwork/templates/gemini/command-job-step.toml.jinja b/src/deepwork/templates/gemini/command-job-step.toml.jinja
deleted file mode 100644
index 47081b8f..00000000
--- a/src/deepwork/templates/gemini/command-job-step.toml.jinja
+++ /dev/null
@@ -1,169 +0,0 @@
-# {{ job_name }}:{{ step_id }}
-#
-# {{ step_description }}
-#
-# Generated by DeepWork - do not edit manually
-
-description = "{{ step_description | replace('"', '\\"') }}"
-
-prompt = """
-# {{ job_name }}:{{ step_id }}
-
-{% if is_standalone %}
-**Standalone command** in the **{{ job_name }}** job - can be run anytime
-{% else %}
-**Step {{ step_number }} of {{ total_steps }}** in the **{{ job_name }}** workflow
-{% endif %}
-
-**Summary**: {{ job_summary }}
-
-{% if job_description %}
-## Job Overview
-
-{{ job_description }}
-{% endif %}
-
-{% if dependencies %}
-## Prerequisites
-
-This step requires completion of the following step(s):
-{% for dep in dependencies %}
-- `/{{ job_name }}:{{ dep }}`
-{% endfor %}
-
-Please ensure these steps have been completed before proceeding.
-{% endif %}
-
-## Instructions
-
-{{ instructions_content }}
-
-{% if user_inputs or file_inputs %}
-## Inputs
-
-{% if user_inputs %}
-### User Parameters
-
-Please gather the following information from the user:
-{% for input in user_inputs %}
-- **{{ input.name }}**: {{ input.description }}
-{% endfor %}
-{% endif %}
-
-{% if file_inputs %}
-### Required Files
-
-This step requires the following files from previous steps:
-{% for input in file_inputs %}
-- `{{ input.file }}` (from step `{{ input.from_step }}`)
-{% endfor %}
-
-Make sure to read and use these files as context for this step.
-{% endif %}
-{% endif %}
-
-## Work Branch Management
-
-All work for this job should be done on a dedicated work branch:
-
-1. **Check current branch**:
- - If already on a work branch for this job (format: `deepwork/{{ job_name }}-[instance]-[date]`), continue using it
- - If on main/master, create a new work branch
-
-2. **Create work branch** (if needed):
- ```bash
- git checkout -b deepwork/{{ job_name }}-[instance]-$(date +%Y%m%d)
- ```
- Replace `[instance]` with a descriptive identifier (e.g., `acme`, `q1-launch`, etc.)
-
-## Output Requirements
-
-{% if outputs %}
-Create the following output(s):
-{% for output in outputs %}
-- `{{ output }}`{% if output.endswith('/') %} (directory){% endif %}
-
-{% endfor %}
-
-Ensure all outputs are:
-- Well-formatted and complete
-- Ready for review or use by subsequent steps
-{% else %}
-No specific files are output by this command.
-{% endif %}
-
-{% if quality_criteria or stop_hooks %}
-## Quality Validation
-
-This step has quality criteria that should be verified before completion.
-
-{% if quality_criteria %}
-### Quality Criteria
-
-{% for criterion in quality_criteria %}
-{{ loop.index }}. {{ criterion }}
-{% endfor %}
-{% endif %}
-
-**Note**: Gemini CLI does not support automated validation hooks. Please manually verify the criteria above before proceeding.
-
-{% endif %}
-## Completion
-
-After completing this step:
-
-1. **Verify outputs**: Confirm all required files have been created
-
-2. **Inform the user**:
-{% if is_standalone %}
- - The {{ step_id }} command is complete
-{% if outputs %}
- - Outputs created: {{ outputs | join(', ') }}
-{% endif %}
- - This command can be run again anytime to make further changes
-{% else %}
- - Step {{ step_number }} of {{ total_steps }} is complete
-{% if outputs %}
- - Outputs created: {{ outputs | join(', ') }}
-{% endif %}
- {% if next_step %}
- - Ready to proceed to next step: `/{{ job_name }}:{{ next_step }}`
- {% else %}
- - This is the final step - the job is complete!
- {% endif %}
-{% endif %}
-
-{% if is_standalone %}
-## Command Complete
-
-This is a standalone command that can be run anytime. The outputs are ready for use.
-
-Consider:
-- Reviewing the outputs
-- Running `deepwork sync` if job definitions were changed
-- Re-running this command later if further changes are needed
-{% elif next_step %}
-## Next Step
-
-To continue the workflow, run:
-```
-/{{ job_name }}:{{ next_step }}
-```
-{% else %}
-## Workflow Complete
-
-This is the final step in the {{ job_name }} workflow. All outputs should now be complete and ready for review.
-
-Consider:
-- Reviewing all work products
-- Creating a pull request to merge the work branch
-- Documenting any insights or learnings
-{% endif %}
-
----
-
-## Context Files
-
-- Job definition: `.deepwork/jobs/{{ job_name }}/job.yml`
-- Step instructions: `.deepwork/jobs/{{ job_name }}/{{ instructions_file }}`
-"""
diff --git a/src/deepwork/templates/gemini/skill-job-meta.toml.jinja b/src/deepwork/templates/gemini/skill-job-meta.toml.jinja
new file mode 100644
index 00000000..158790d7
--- /dev/null
+++ b/src/deepwork/templates/gemini/skill-job-meta.toml.jinja
@@ -0,0 +1,76 @@
+{#
+Template: skill-job-meta.toml.jinja
+Purpose: Generates the job overview skill file for Gemini CLI
+
+Template Variables:
+ - job_name: string - Job identifier (e.g., "competitive_research")
+ - job_summary: string - Short one-line summary of the job
+ - job_description: string|null - Full description (optional)
+ - total_steps: int - Number of steps in the job
+ - steps: list - Array of step objects:
+ - id: string - Step identifier
+ - name: string - Human-readable step name
+ - description: string - What the step does
+ - command_name: string - Slash command (e.g., "job_name:step_id")
+ - dependencies: list[string]|null - Required prior steps
+
+Note: Gemini uses TOML format with description + prompt fields.
+ Commands use colon separator (/job_name:step_id) not period.
+#}
+# {{ job_name }}
+#
+# {{ job_summary }}
+#
+# Generated by DeepWork - do not edit manually
+
+description = "{{ job_summary | replace('"', '\\"') }}"
+
+prompt = """
+# {{ job_name }}
+
+**Multi-step workflow**: {{ job_summary }}
+
+> **NOTE**: Gemini CLI requires manual command invocation. After each step, tell the user which command to run next.
+
+{% if job_description %}
+{{ job_description }}
+{% endif %}
+
+## Available Steps
+
+{% for step in steps %}
+{{ loop.index }}. **{{ step.id }}** - {{ step.description }}{% if step.dependencies %} (requires: {{ step.dependencies | join(', ') }}){% endif %}
+
+ Command: `/{{ step.command_name }}`
+{% endfor %}
+
+## Execution Instructions
+
+### Step 1: Analyze Intent
+
+Parse any text following `/{{ job_name }}` to determine user intent:
+{% for step in steps %}
+- "{{ step.id }}" or related terms → start at `/{{ step.command_name }}`
+{% endfor %}
+
+### Step 2: Direct User to Starting Step
+
+Tell the user which command to run:
+```
+/{{ steps[0].command_name }}
+```
+
+### Step 3: Guide Through Workflow
+
+After each step completes, tell the user the next command to run until workflow is complete.
+
+### Handling Ambiguous Intent
+
+If user intent is unclear:
+- Present available steps as numbered options
+- Ask user to select the starting point
+
+## Reference
+
+- Job definition: `.deepwork/jobs/{{ job_name }}/job.yml`
+"""
diff --git a/src/deepwork/templates/gemini/skill-job-step.toml.jinja b/src/deepwork/templates/gemini/skill-job-step.toml.jinja
new file mode 100644
index 00000000..150c78a9
--- /dev/null
+++ b/src/deepwork/templates/gemini/skill-job-step.toml.jinja
@@ -0,0 +1,147 @@
+{#
+Template: skill-job-step.toml.jinja
+Purpose: Generates individual step skill files for Gemini CLI
+
+Template Variables:
+ Job Context:
+ - job_name: string - Job identifier
+ - job_summary: string - Short job summary
+ - job_description: string|null - Full job description
+
+ Step Metadata:
+ - step_id: string - Step identifier
+ - step_description: string - What this step does
+ - step_number: int - Position in workflow (1-indexed)
+ - total_steps: int - Total steps in job
+ - is_standalone: bool - True if step can run independently
+ - dependencies: list[string]|null - Required prior step IDs
+ - next_step: string|null - Next step ID in workflow
+ - instructions_file: string - Path to step instructions file
+
+ Step Content:
+ - instructions_content: string - Full instructions markdown
+ - user_inputs: list|null - User parameters to gather:
+ - name: string - Parameter name
+ - description: string - What to ask for
+ - file_inputs: list|null - Files from previous steps:
+ - file: string - File path
+ - from_step: string - Source step ID
+ - outputs: list[string]|null - Output file paths
+
+ Quality:
+ - quality_criteria: list[string]|null - Criteria for completion
+ - stop_hooks: list|null - Stop hook configurations (note: Gemini
+ does not support automated hooks, so these are for manual verification)
+
+Note: Gemini uses TOML format with description + prompt fields.
+ Commands use colon separator (/job_name:step_id) not period.
+#}
+# {{ job_name }}:{{ step_id }}
+#
+# {{ step_description }}
+#
+# Generated by DeepWork - do not edit manually
+
+description = "{{ step_description | replace('"', '\\"') }}"
+
+prompt = """
+# {{ job_name }}:{{ step_id }}
+
+{% if is_standalone %}
+**Standalone command** - can be run anytime
+{% else %}
+**Step {{ step_number }}/{{ total_steps }}** in **{{ job_name }}** workflow
+{% endif %}
+
+> {{ job_summary }}
+
+{% if dependencies %}
+## Prerequisites (Verify First)
+
+Before proceeding, confirm these steps are complete:
+{% for dep in dependencies %}
+- `/{{ job_name }}:{{ dep }}`
+{% endfor %}
+{% endif %}
+
+## Instructions
+
+**Goal**: {{ step_description }}
+
+{{ instructions_content }}
+
+{% if job_description %}
+### Job Context
+
+{{ job_description }}
+{% endif %}
+
+{% if user_inputs or file_inputs %}
+## Required Inputs
+
+{% if user_inputs %}
+**User Parameters** - Gather from user before starting:
+{% for input in user_inputs %}
+- **{{ input.name }}**: {{ input.description }}
+{% endfor %}
+{% endif %}
+
+{% if file_inputs %}
+**Files from Previous Steps** - Read these first:
+{% for input in file_inputs %}
+- `{{ input.file }}` (from `{{ input.from_step }}`)
+{% endfor %}
+{% endif %}
+{% endif %}
+
+## Work Branch
+
+Use branch format: `deepwork/{{ job_name }}-[instance]-YYYYMMDD`
+
+- If on a matching work branch: continue using it
+- If on main/master: create new branch with `git checkout -b deepwork/{{ job_name }}-[instance]-$(date +%Y%m%d)`
+
+## Outputs
+
+{% if outputs %}
+**Required outputs**:
+{% for output in outputs %}
+- `{{ output }}`{% if output.endswith('/') %} (directory){% endif %}
+{% endfor %}
+{% else %}
+No specific file outputs required.
+{% endif %}
+
+{% if quality_criteria or stop_hooks %}
+## Quality Validation (Manual)
+
+**NOTE**: Gemini CLI does not support automated validation. Manually verify criteria before completing.
+
+{% if quality_criteria %}
+**Criteria (all must be satisfied)**:
+{% for criterion in quality_criteria %}
+{{ loop.index }}. {{ criterion }}
+{% endfor %}
+{% endif %}
+{% endif %}
+## On Completion
+
+{% if is_standalone %}
+1. Verify outputs are created
+2. Inform user: "{{ step_id }} complete{% if outputs %}, outputs: {{ outputs | join(', ') }}{% endif %}"
+
+This standalone command can be re-run anytime.
+{% else %}
+1. Verify outputs are created
+2. Inform user: "Step {{ step_number }}/{{ total_steps }} complete{% if outputs %}, outputs: {{ outputs | join(', ') }}{% endif %}"
+{% if next_step %}
+3. **Tell user next command**: `/{{ job_name }}:{{ next_step }}`
+{% else %}
+3. **Workflow complete**: All steps finished. Consider creating a PR to merge the work branch.
+{% endif %}
+{% endif %}
+
+---
+
+**Reference files**: `.deepwork/jobs/{{ job_name }}/job.yml`, `.deepwork/jobs/{{ job_name }}/{{ instructions_file }}`
+"""
diff --git a/tests/e2e/test_claude_code_integration.py b/tests/e2e/test_claude_code_integration.py
index 5becbbec..bba2e8ce 100644
--- a/tests/e2e/test_claude_code_integration.py
+++ b/tests/e2e/test_claude_code_integration.py
@@ -18,7 +18,7 @@
import pytest
from deepwork.core.adapters import ClaudeAdapter
-from deepwork.core.generator import CommandGenerator
+from deepwork.core.generator import SkillGenerator
from deepwork.core.parser import parse_job_definition
# Test input for deterministic validation
@@ -84,86 +84,86 @@ def test_generate_fruits_commands_in_temp_project(self) -> None:
capture_output=True,
)
- # Parse job and generate commands
+ # Parse job and generate skills
job = parse_job_definition(deepwork_dir / "fruits")
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = project_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = project_dir / ".claude"
+ skills_dir.mkdir()
- command_paths = generator.generate_all_commands(job, adapter, commands_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, skills_dir)
- # Validate commands were generated (meta + steps)
- assert len(command_paths) == 3 # 1 meta + 2 steps
+ # Validate skills were generated (meta + steps)
+ assert len(skill_paths) == 3 # 1 meta + 2 steps
- meta_cmd = commands_dir / "commands" / "fruits.md"
- identify_cmd = commands_dir / "commands" / "uw.fruits.identify.md"
- classify_cmd = commands_dir / "commands" / "uw.fruits.classify.md"
+ meta_skill = skills_dir / "skills" / "fruits" / "SKILL.md"
+ identify_skill = skills_dir / "skills" / "fruits.identify" / "SKILL.md"
+ classify_skill = skills_dir / "skills" / "fruits.classify" / "SKILL.md"
- assert meta_cmd.exists()
- assert identify_cmd.exists()
- assert classify_cmd.exists()
+ assert meta_skill.exists()
+ assert identify_skill.exists()
+ assert classify_skill.exists()
- # Validate command content
- identify_content = identify_cmd.read_text()
+ # Validate skill content
+ identify_content = identify_skill.read_text()
assert "# fruits.identify" in identify_content
assert "raw_items" in identify_content
assert "identified_fruits.md" in identify_content
- classify_content = classify_cmd.read_text()
+ classify_content = classify_skill.read_text()
assert "# fruits.classify" in classify_content
assert "identified_fruits.md" in classify_content
assert "classified_fruits.md" in classify_content
- def test_command_structure_matches_claude_code_expectations(self) -> None:
- """Test that generated commands have the structure Claude Code expects."""
+ def test_skill_structure_matches_claude_code_expectations(self) -> None:
+ """Test that generated skills have the structure Claude Code expects."""
fixtures_dir = Path(__file__).parent.parent / "fixtures" / "jobs" / "fruits"
job = parse_job_definition(fixtures_dir)
with tempfile.TemporaryDirectory() as tmpdir:
- commands_dir = Path(tmpdir) / ".claude"
- commands_dir.mkdir()
+ skills_dir = Path(tmpdir) / ".claude"
+ skills_dir.mkdir()
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- generator.generate_all_commands(job, adapter, commands_dir)
+ generator.generate_all_skills(job, adapter, skills_dir)
- # Step commands now have uw. prefix
- identify_cmd = commands_dir / "commands" / "uw.fruits.identify.md"
- content = identify_cmd.read_text()
+ # Step skills use directory/SKILL.md format
+ identify_skill = skills_dir / "skills" / "fruits.identify" / "SKILL.md"
+ content = identify_skill.read_text()
# Claude Code expects specific sections
- assert "# fruits.identify" in content # Command name header
+ assert "# fruits.identify" in content # Skill name header
assert "## Instructions" in content # Instructions section
- assert "## Inputs" in content # Inputs section
- assert "## Output" in content # Output section
+ assert "## Required Inputs" in content # Inputs section
+ assert "## Outputs" in content # Outputs section
# Check for user input prompt
assert "raw_items" in content
- def test_dependency_chain_in_commands(self) -> None:
- """Test that dependency chain is correctly represented in commands."""
+ def test_dependency_chain_in_skills(self) -> None:
+ """Test that dependency chain is correctly represented in skills."""
fixtures_dir = Path(__file__).parent.parent / "fixtures" / "jobs" / "fruits"
job = parse_job_definition(fixtures_dir)
with tempfile.TemporaryDirectory() as tmpdir:
- commands_dir = Path(tmpdir) / ".claude"
- commands_dir.mkdir()
+ skills_dir = Path(tmpdir) / ".claude"
+ skills_dir.mkdir()
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- generator.generate_all_commands(job, adapter, commands_dir)
+ generator.generate_all_skills(job, adapter, skills_dir)
- # Step commands now have uw. prefix
+ # Step skills use directory/SKILL.md format
# First step should have no prerequisites
- identify_cmd = commands_dir / "commands" / "uw.fruits.identify.md"
- identify_content = identify_cmd.read_text()
+ identify_skill = skills_dir / "skills" / "fruits.identify" / "SKILL.md"
+ identify_content = identify_skill.read_text()
assert "## Prerequisites" not in identify_content
# Second step should reference first step
- classify_cmd = commands_dir / "commands" / "uw.fruits.classify.md"
- classify_content = classify_cmd.read_text()
+ classify_skill = skills_dir / "skills" / "fruits.classify" / "SKILL.md"
+ classify_content = classify_skill.read_text()
assert "## Prerequisites" in classify_content
assert "identify" in classify_content.lower()
@@ -217,14 +217,14 @@ def project_with_commands(self) -> Path:
capture_output=True,
)
- # Generate commands
+ # Generate skills
job = parse_job_definition(deepwork_dir / "fruits")
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = project_dir / ".claude"
- commands_dir.mkdir()
- generator.generate_all_commands(job, adapter, commands_dir)
+ skills_dir = project_dir / ".claude"
+ skills_dir.mkdir()
+ generator.generate_all_skills(job, adapter, skills_dir)
yield project_dir
diff --git a/tests/integration/test_fruits_workflow.py b/tests/integration/test_fruits_workflow.py
index ee80380b..88efa1a9 100644
--- a/tests/integration/test_fruits_workflow.py
+++ b/tests/integration/test_fruits_workflow.py
@@ -7,7 +7,7 @@
from pathlib import Path
from deepwork.core.adapters import ClaudeAdapter
-from deepwork.core.generator import CommandGenerator
+from deepwork.core.generator import SkillGenerator
from deepwork.core.parser import parse_job_definition
@@ -68,50 +68,50 @@ def test_fruits_classify_step_structure(self, fixtures_dir: Path) -> None:
# Depends on identify step
assert classify_step.dependencies == ["identify"]
- def test_fruits_command_generation(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test that fruits job generates valid Claude commands."""
+ def test_fruits_skill_generation(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test that fruits job generates valid Claude skills."""
job_dir = fixtures_dir / "jobs" / "fruits"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = temp_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = temp_dir / ".claude"
+ skills_dir.mkdir()
- command_paths = generator.generate_all_commands(job, adapter, commands_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, skills_dir)
- # Now includes meta-command + step commands
- assert len(command_paths) == 3 # 1 meta + 2 steps
+ # Now includes meta-skill + step skills
+ assert len(skill_paths) == 3 # 1 meta + 2 steps
- # Verify command files exist
- meta_cmd = commands_dir / "commands" / "fruits.md"
- identify_cmd = commands_dir / "commands" / "uw.fruits.identify.md"
- classify_cmd = commands_dir / "commands" / "uw.fruits.classify.md"
- assert meta_cmd.exists()
- assert identify_cmd.exists()
- assert classify_cmd.exists()
+ # Verify skill directories with SKILL.md files exist
+ meta_skill = skills_dir / "skills" / "fruits" / "SKILL.md"
+ identify_skill = skills_dir / "skills" / "fruits.identify" / "SKILL.md"
+ classify_skill = skills_dir / "skills" / "fruits.classify" / "SKILL.md"
+ assert meta_skill.exists()
+ assert identify_skill.exists()
+ assert classify_skill.exists()
- def test_fruits_identify_command_content(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test the identify command has correct content."""
+ def test_fruits_identify_skill_content(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test the identify skill has correct content."""
job_dir = fixtures_dir / "jobs" / "fruits"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = temp_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = temp_dir / ".claude"
+ skills_dir.mkdir()
- generator.generate_all_commands(job, adapter, commands_dir)
+ generator.generate_all_skills(job, adapter, skills_dir)
- # Step commands now have uw. prefix
- identify_cmd = commands_dir / "commands" / "uw.fruits.identify.md"
- content = identify_cmd.read_text()
+ # Step skills use directory/SKILL.md format
+ identify_skill = skills_dir / "skills" / "fruits.identify" / "SKILL.md"
+ content = identify_skill.read_text()
# Check header
assert "# fruits.identify" in content
# Check step info
- assert "Step 1 of 2" in content
+ assert "Step 1/2" in content
# Check user input is mentioned
assert "raw_items" in content
@@ -122,37 +122,37 @@ def test_fruits_identify_command_content(self, fixtures_dir: Path, temp_dir: Pat
# Check next step is suggested
assert "/fruits.classify" in content
- def test_fruits_classify_command_content(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test the classify command has correct content."""
+ def test_fruits_classify_skill_content(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test the classify skill has correct content."""
job_dir = fixtures_dir / "jobs" / "fruits"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = temp_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = temp_dir / ".claude"
+ skills_dir.mkdir()
- generator.generate_all_commands(job, adapter, commands_dir)
+ generator.generate_all_skills(job, adapter, skills_dir)
- # Step commands now have uw. prefix
- classify_cmd = commands_dir / "commands" / "uw.fruits.classify.md"
- content = classify_cmd.read_text()
+ # Step skills use directory/SKILL.md format
+ classify_skill = skills_dir / "skills" / "fruits.classify" / "SKILL.md"
+ content = classify_skill.read_text()
# Check header
assert "# fruits.classify" in content
# Check step info
- assert "Step 2 of 2" in content
+ assert "Step 2/2" in content
# Check file input is mentioned
assert "identified_fruits.md" in content
- assert "from step `identify`" in content
+ assert "from `identify`" in content
# Check output is mentioned
assert "classified_fruits.md" in content
# Check workflow complete (last step)
- assert "Workflow Complete" in content
+ assert "Workflow complete" in content
def test_fruits_dependency_validation(self, fixtures_dir: Path) -> None:
"""Test that dependency validation passes for fruits job."""
diff --git a/tests/integration/test_full_workflow.py b/tests/integration/test_full_workflow.py
index 7d05634b..bc7f83bf 100644
--- a/tests/integration/test_full_workflow.py
+++ b/tests/integration/test_full_workflow.py
@@ -3,7 +3,7 @@
from pathlib import Path
from deepwork.core.adapters import ClaudeAdapter
-from deepwork.core.generator import CommandGenerator
+from deepwork.core.generator import SkillGenerator
from deepwork.core.parser import parse_job_definition
@@ -11,7 +11,7 @@ class TestJobWorkflow:
"""Integration tests for complete job workflow."""
def test_parse_and_generate_workflow(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test complete workflow: parse job → generate commands."""
+ """Test complete workflow: parse job → generate skills."""
# Step 1: Parse job definition
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
@@ -19,33 +19,33 @@ def test_parse_and_generate_workflow(self, fixtures_dir: Path, temp_dir: Path) -
assert job.name == "competitive_research"
assert len(job.steps) == 4
- # Step 2: Generate commands
- generator = CommandGenerator()
+ # Step 2: Generate skills
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = temp_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = temp_dir / ".claude"
+ skills_dir.mkdir()
- command_paths = generator.generate_all_commands(job, adapter, commands_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, skills_dir)
- # Now includes meta-command + step commands
- assert len(command_paths) == 5 # 1 meta + 4 steps
+ # Now includes meta-skill + step skills
+ assert len(skill_paths) == 5 # 1 meta + 4 steps
- # First command is the meta-command
- assert command_paths[0].exists()
- meta_content = command_paths[0].read_text()
+ # First skill is the meta-skill
+ assert skill_paths[0].exists()
+ meta_content = skill_paths[0].read_text()
assert f"# {job.name}" in meta_content
assert "Available Steps" in meta_content
- # Verify all step command files exist and have correct content
- for i, command_path in enumerate(command_paths[1:]): # Skip meta-command
- assert command_path.exists()
- content = command_path.read_text()
+ # Verify all step skill files exist and have correct content
+ for i, skill_path in enumerate(skill_paths[1:]): # Skip meta-skill
+ assert skill_path.exists()
+ content = skill_path.read_text()
- # Check command name format (header)
+ # Check skill name format (header)
assert f"# {job.name}.{job.steps[i].id}" in content
# Check step numbers
- assert f"Step {i + 1} of 4" in content
+ assert f"Step {i + 1}/4" in content
def test_simple_job_workflow(self, fixtures_dir: Path, temp_dir: Path) -> None:
"""Test workflow with simple single-step job."""
@@ -56,98 +56,98 @@ def test_simple_job_workflow(self, fixtures_dir: Path, temp_dir: Path) -> None:
assert len(job.steps) == 1
# Generate
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = temp_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = temp_dir / ".claude"
+ skills_dir.mkdir()
- command_paths = generator.generate_all_commands(job, adapter, commands_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, skills_dir)
- # Now includes meta-command + step commands
- assert len(command_paths) == 2 # 1 meta + 1 step
+ # Now includes meta-skill + step skills
+ assert len(skill_paths) == 2 # 1 meta + 1 step
- # Verify step command content (skip meta-command at index 0)
- content = command_paths[1].read_text()
+ # Verify step skill content (skip meta-skill at index 0)
+ content = skill_paths[1].read_text()
assert "# simple_job.single_step" in content
# Single step with no dependencies is treated as standalone
- assert "Standalone command" in content
+ assert "Standalone skill" in content
assert "input_param" in content
- assert "Command Complete" in content # Standalone completion message
+ assert "standalone skill can be re-run" in content # Standalone completion message
- def test_command_generation_with_dependencies(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test that generated commands properly handle dependencies."""
+ def test_skill_generation_with_dependencies(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test that generated skills properly handle dependencies."""
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = temp_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = temp_dir / ".claude"
+ skills_dir.mkdir()
- command_paths = generator.generate_all_commands(job, adapter, commands_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, skills_dir)
- # command_paths[0] is meta-command, steps start at index 1
+ # skill_paths[0] is meta-skill, steps start at index 1
# Check first step (no prerequisites)
- step1_content = command_paths[1].read_text()
+ step1_content = skill_paths[1].read_text()
assert "## Prerequisites" not in step1_content
assert "/competitive_research.primary_research" in step1_content # Next step
# Check second step (has prerequisites and next step)
- step2_content = command_paths[2].read_text()
+ step2_content = skill_paths[2].read_text()
assert "## Prerequisites" in step2_content
assert "/competitive_research.identify_competitors" in step2_content
assert "/competitive_research.secondary_research" in step2_content # Next step
# Check last step (has prerequisites, no next step)
- step4_content = command_paths[4].read_text()
+ step4_content = skill_paths[4].read_text()
assert "## Prerequisites" in step4_content
- assert "## Workflow Complete" in step4_content
+ assert "**Workflow complete**" in step4_content
assert "## Next Step" not in step4_content
- def test_command_generation_with_file_inputs(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test that generated commands properly handle file inputs."""
+ def test_skill_generation_with_file_inputs(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test that generated skills properly handle file inputs."""
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = temp_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = temp_dir / ".claude"
+ skills_dir.mkdir()
- command_paths = generator.generate_all_commands(job, adapter, commands_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, skills_dir)
- # command_paths[0] is meta-command, steps start at index 1
+ # skill_paths[0] is meta-skill, steps start at index 1
# Check step with file input
- step2_content = command_paths[2].read_text() # primary_research (index 2)
- assert "## Inputs" in step2_content
- assert "### Required Files" in step2_content
+ step2_content = skill_paths[2].read_text() # primary_research (index 2)
+ assert "## Required Inputs" in step2_content
+ assert "**Files from Previous Steps**" in step2_content
assert "competitors.md" in step2_content
- assert "from step `identify_competitors`" in step2_content
+ assert "from `identify_competitors`" in step2_content
# Check step with multiple file inputs
- step4_content = command_paths[4].read_text() # comparative_report (index 4)
+ step4_content = skill_paths[4].read_text() # comparative_report (index 4)
assert "primary_research.md" in step4_content
assert "secondary_research.md" in step4_content
- def test_command_generation_with_user_inputs(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test that generated commands properly handle user parameter inputs."""
+ def test_skill_generation_with_user_inputs(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test that generated skills properly handle user parameter inputs."""
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- commands_dir = temp_dir / ".claude"
- commands_dir.mkdir()
+ skills_dir = temp_dir / ".claude"
+ skills_dir.mkdir()
- command_paths = generator.generate_all_commands(job, adapter, commands_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, skills_dir)
- # command_paths[0] is meta-command, steps start at index 1
+ # skill_paths[0] is meta-skill, steps start at index 1
# Check step with user inputs
- step1_content = command_paths[1].read_text() # identify_competitors (index 1)
- assert "## Inputs" in step1_content
- assert "### User Parameters" in step1_content
+ step1_content = skill_paths[1].read_text() # identify_competitors (index 1)
+ assert "## Required Inputs" in step1_content
+ assert "**User Parameters**" in step1_content
assert "market_segment" in step1_content
assert "product_category" in step1_content
diff --git a/tests/integration/test_install_flow.py b/tests/integration/test_install_flow.py
index 66bcdc20..9e62a685 100644
--- a/tests/integration/test_install_flow.py
+++ b/tests/integration/test_install_flow.py
@@ -39,24 +39,24 @@ def test_install_with_claude(self, mock_claude_project: Path) -> None:
assert config is not None
assert "claude" in config["platforms"]
- # Verify core commands were created
- claude_dir = mock_claude_project / ".claude" / "commands"
- # Meta-command
- assert (claude_dir / "deepwork_jobs.md").exists()
- # Hidden step command (uw. prefix)
- assert (claude_dir / "uw.deepwork_jobs.define.md").exists()
- # Exposed step command (no uw. prefix - learn has exposed: true)
- assert (claude_dir / "deepwork_jobs.learn.md").exists()
-
- # Verify meta-command content
- meta_command = (claude_dir / "deepwork_jobs.md").read_text()
- assert "# deepwork_jobs" in meta_command
- assert "Available Steps" in meta_command
-
- # Verify hidden step command content
- define_command = (claude_dir / "uw.deepwork_jobs.define.md").read_text()
- assert "# deepwork_jobs.define" in define_command
- assert "Define Job Specification" in define_command
+ # Verify core skills were created (directory/SKILL.md format)
+ claude_dir = mock_claude_project / ".claude" / "skills"
+ # Meta-skill
+ assert (claude_dir / "deepwork_jobs" / "SKILL.md").exists()
+ # Step skill (no prefix, but has user-invocable: false in frontmatter)
+ assert (claude_dir / "deepwork_jobs.define" / "SKILL.md").exists()
+ # Exposed step skill (user-invocable - learn has exposed: true)
+ assert (claude_dir / "deepwork_jobs.learn" / "SKILL.md").exists()
+
+ # Verify meta-skill content
+ meta_skill = (claude_dir / "deepwork_jobs" / "SKILL.md").read_text()
+ assert "# deepwork_jobs" in meta_skill
+ assert "Available Steps" in meta_skill
+
+ # Verify step skill content
+ define_skill = (claude_dir / "deepwork_jobs.define" / "SKILL.md").read_text()
+ assert "# deepwork_jobs.define" in define_skill
+ assert "Define Job Specification" in define_skill
def test_install_with_auto_detect(self, mock_claude_project: Path) -> None:
"""Test installing with auto-detection."""
@@ -113,17 +113,17 @@ def test_install_with_multiple_platforms_auto_detect(
assert "claude" in config["platforms"]
assert "gemini" in config["platforms"]
- # Verify commands were created for both platforms
- claude_dir = mock_multi_platform_project / ".claude" / "commands"
- # Meta-command and hidden step commands
- assert (claude_dir / "deepwork_jobs.md").exists()
- assert (claude_dir / "uw.deepwork_jobs.define.md").exists()
+ # Verify skills were created for both platforms
+ claude_dir = mock_multi_platform_project / ".claude" / "skills"
+ # Meta-skill and step skills (directory/SKILL.md format)
+ assert (claude_dir / "deepwork_jobs" / "SKILL.md").exists()
+ assert (claude_dir / "deepwork_jobs.define" / "SKILL.md").exists()
# Gemini uses job_name/step_id.toml structure
- gemini_dir = mock_multi_platform_project / ".gemini" / "commands"
- # Meta-command (index.toml) and hidden step commands
+ gemini_dir = mock_multi_platform_project / ".gemini" / "skills"
+ # Meta-skill (index.toml) and step skills
assert (gemini_dir / "deepwork_jobs" / "index.toml").exists()
- assert (gemini_dir / "deepwork_jobs" / "uw.define.toml").exists()
+ assert (gemini_dir / "deepwork_jobs" / "define.toml").exists()
def test_install_with_specified_platform_when_missing(self, mock_git_repo: Path) -> None:
"""Test that install fails when specified platform is not present."""
@@ -161,11 +161,11 @@ def test_install_is_idempotent(self, mock_claude_project: Path) -> None:
deepwork_dir = mock_claude_project / ".deepwork"
assert (deepwork_dir / "config.yml").exists()
- claude_dir = mock_claude_project / ".claude" / "commands"
- # Meta-command and step commands
- assert (claude_dir / "deepwork_jobs.md").exists()
- assert (claude_dir / "uw.deepwork_jobs.define.md").exists()
- assert (claude_dir / "deepwork_jobs.learn.md").exists()
+ claude_dir = mock_claude_project / ".claude" / "skills"
+ # Meta-skill and step skills (directory/SKILL.md format)
+ assert (claude_dir / "deepwork_jobs" / "SKILL.md").exists()
+ assert (claude_dir / "deepwork_jobs.define" / "SKILL.md").exists()
+ assert (claude_dir / "deepwork_jobs.learn" / "SKILL.md").exists()
def test_install_creates_rules_directory(self, mock_claude_project: Path) -> None:
"""Test that install creates the v2 rules directory with example templates."""
diff --git a/tests/unit/test_adapters.py b/tests/unit/test_adapters.py
index d052f001..4f2f3e17 100644
--- a/tests/unit/test_adapters.py
+++ b/tests/unit/test_adapters.py
@@ -9,8 +9,8 @@
AdapterError,
AgentAdapter,
ClaudeAdapter,
- CommandLifecycleHook,
GeminiAdapter,
+ SkillLifecycleHook,
)
@@ -53,7 +53,7 @@ def test_class_attributes(self) -> None:
assert ClaudeAdapter.name == "claude"
assert ClaudeAdapter.display_name == "Claude Code"
assert ClaudeAdapter.config_dir == ".claude"
- assert ClaudeAdapter.commands_dir == "commands"
+ assert ClaudeAdapter.skills_dir == "skills"
def test_init_with_project_root(self, temp_dir: Path) -> None:
"""Test initialization with project root."""
@@ -96,52 +96,52 @@ def test_get_template_dir(self, temp_dir: Path) -> None:
assert result == templates_root / "claude"
- def test_get_commands_dir(self, temp_dir: Path) -> None:
- """Test get_commands_dir."""
+ def test_get_skills_dir(self, temp_dir: Path) -> None:
+ """Test get_skills_dir."""
adapter = ClaudeAdapter(temp_dir)
- result = adapter.get_commands_dir()
+ result = adapter.get_skills_dir()
- assert result == temp_dir / ".claude" / "commands"
+ assert result == temp_dir / ".claude" / "skills"
- def test_get_commands_dir_with_explicit_root(self, temp_dir: Path) -> None:
- """Test get_commands_dir with explicit project root."""
+ def test_get_skills_dir_with_explicit_root(self, temp_dir: Path) -> None:
+ """Test get_skills_dir with explicit project root."""
adapter = ClaudeAdapter()
- result = adapter.get_commands_dir(temp_dir)
+ result = adapter.get_skills_dir(temp_dir)
- assert result == temp_dir / ".claude" / "commands"
+ assert result == temp_dir / ".claude" / "skills"
- def test_get_commands_dir_raises_without_root(self) -> None:
- """Test get_commands_dir raises when no project root specified."""
+ def test_get_skills_dir_raises_without_root(self) -> None:
+ """Test get_skills_dir raises when no project root specified."""
adapter = ClaudeAdapter()
with pytest.raises(AdapterError, match="No project root specified"):
- adapter.get_commands_dir()
+ adapter.get_skills_dir()
- def test_get_meta_command_filename(self) -> None:
- """Test get_meta_command_filename."""
+ def test_get_meta_skill_filename(self) -> None:
+ """Test get_meta_skill_filename returns directory/SKILL.md format."""
adapter = ClaudeAdapter()
- result = adapter.get_meta_command_filename("my_job")
+ result = adapter.get_meta_skill_filename("my_job")
- assert result == "my_job.md"
+ assert result == "my_job/SKILL.md"
- def test_get_step_command_filename_hidden_by_default(self) -> None:
- """Test get_step_command_filename returns hidden filename by default."""
+ def test_get_step_skill_filename_returns_directory_format(self) -> None:
+ """Test get_step_skill_filename returns directory/SKILL.md format."""
adapter = ClaudeAdapter()
- result = adapter.get_step_command_filename("my_job", "step_one")
+ result = adapter.get_step_skill_filename("my_job", "step_one")
- assert result == "uw.my_job.step_one.md"
+ assert result == "my_job.step_one/SKILL.md"
- def test_get_step_command_filename_exposed(self) -> None:
- """Test get_step_command_filename returns visible filename when exposed."""
+ def test_get_step_skill_filename_exposed(self) -> None:
+ """Test get_step_skill_filename with exposed=True (same format)."""
adapter = ClaudeAdapter()
- result = adapter.get_step_command_filename("my_job", "step_one", exposed=True)
+ result = adapter.get_step_skill_filename("my_job", "step_one", exposed=True)
- assert result == "my_job.step_one.md"
+ assert result == "my_job.step_one/SKILL.md"
def test_sync_hooks_creates_settings_file(self, temp_dir: Path) -> None:
"""Test sync_hooks creates settings.json when it doesn't exist."""
@@ -195,8 +195,8 @@ def test_class_attributes(self) -> None:
assert GeminiAdapter.name == "gemini"
assert GeminiAdapter.display_name == "Gemini CLI"
assert GeminiAdapter.config_dir == ".gemini"
- assert GeminiAdapter.commands_dir == "commands"
- assert GeminiAdapter.command_template == "command-job-step.toml.jinja"
+ assert GeminiAdapter.skills_dir == "skills"
+ assert GeminiAdapter.skill_template == "skill-job-step.toml.jinja"
def test_init_with_project_root(self, temp_dir: Path) -> None:
"""Test initialization with project root."""
@@ -239,81 +239,81 @@ def test_get_template_dir(self, temp_dir: Path) -> None:
assert result == templates_root / "gemini"
- def test_get_commands_dir(self, temp_dir: Path) -> None:
- """Test get_commands_dir."""
+ def test_get_skills_dir(self, temp_dir: Path) -> None:
+ """Test get_skills_dir."""
adapter = GeminiAdapter(temp_dir)
- result = adapter.get_commands_dir()
+ result = adapter.get_skills_dir()
- assert result == temp_dir / ".gemini" / "commands"
+ assert result == temp_dir / ".gemini" / "skills"
- def test_get_commands_dir_with_explicit_root(self, temp_dir: Path) -> None:
- """Test get_commands_dir with explicit project root."""
+ def test_get_skills_dir_with_explicit_root(self, temp_dir: Path) -> None:
+ """Test get_skills_dir with explicit project root."""
adapter = GeminiAdapter()
- result = adapter.get_commands_dir(temp_dir)
+ result = adapter.get_skills_dir(temp_dir)
- assert result == temp_dir / ".gemini" / "commands"
+ assert result == temp_dir / ".gemini" / "skills"
- def test_get_commands_dir_raises_without_root(self) -> None:
- """Test get_commands_dir raises when no project root specified."""
+ def test_get_skills_dir_raises_without_root(self) -> None:
+ """Test get_skills_dir raises when no project root specified."""
adapter = GeminiAdapter()
with pytest.raises(AdapterError, match="No project root specified"):
- adapter.get_commands_dir()
+ adapter.get_skills_dir()
- def test_get_meta_command_filename(self) -> None:
- """Test get_meta_command_filename returns index.toml in subdirectory."""
+ def test_get_meta_skill_filename(self) -> None:
+ """Test get_meta_skill_filename returns index.toml in subdirectory."""
adapter = GeminiAdapter()
- result = adapter.get_meta_command_filename("my_job")
+ result = adapter.get_meta_skill_filename("my_job")
- # Gemini uses subdirectories with index.toml for meta-commands
+ # Gemini uses subdirectories with index.toml for meta-skills
assert result == "my_job/index.toml"
- def test_get_step_command_filename_hidden_by_default(self) -> None:
- """Test get_step_command_filename returns hidden TOML with subdirectory."""
+ def test_get_step_skill_filename_returns_clean_name(self) -> None:
+ """Test get_step_skill_filename returns clean TOML with subdirectory."""
adapter = GeminiAdapter()
- result = adapter.get_step_command_filename("my_job", "step_one")
+ result = adapter.get_step_skill_filename("my_job", "step_one")
# Gemini uses subdirectories for namespacing (colon becomes path)
- # Hidden steps have uw. prefix
- assert result == "my_job/uw.step_one.toml"
+ # No prefix on skill filenames
+ assert result == "my_job/step_one.toml"
- def test_get_step_command_filename_exposed(self) -> None:
- """Test get_step_command_filename returns visible TOML when exposed."""
+ def test_get_step_skill_filename_exposed(self) -> None:
+ """Test get_step_skill_filename with exposed=True (same result, no prefix)."""
adapter = GeminiAdapter()
- result = adapter.get_step_command_filename("my_job", "step_one", exposed=True)
+ result = adapter.get_step_skill_filename("my_job", "step_one", exposed=True)
- # Exposed steps have no uw. prefix
+ # Same filename whether exposed or not
assert result == "my_job/step_one.toml"
- def test_get_step_command_filename_with_underscores(self) -> None:
- """Test get_step_command_filename with underscores in names."""
+ def test_get_step_skill_filename_with_underscores(self) -> None:
+ """Test get_step_skill_filename with underscores in names."""
adapter = GeminiAdapter()
- result = adapter.get_step_command_filename("competitive_research", "identify_competitors")
+ result = adapter.get_step_skill_filename("competitive_research", "identify_competitors")
- assert result == "competitive_research/uw.identify_competitors.toml"
+ assert result == "competitive_research/identify_competitors.toml"
def test_hook_name_mapping_is_empty(self) -> None:
- """Test that Gemini has no command-level hooks."""
+ """Test that Gemini has no skill-level hooks."""
assert GeminiAdapter.hook_name_mapping == {}
def test_supports_hook_returns_false_for_all_hooks(self) -> None:
- """Test that Gemini doesn't support any command-level hooks."""
+ """Test that Gemini doesn't support any skill-level hooks."""
adapter = GeminiAdapter()
- for hook in CommandLifecycleHook:
+ for hook in SkillLifecycleHook:
assert adapter.supports_hook(hook) is False
def test_get_platform_hook_name_returns_none(self) -> None:
"""Test that get_platform_hook_name returns None for all hooks."""
adapter = GeminiAdapter()
- for hook in CommandLifecycleHook:
+ for hook in SkillLifecycleHook:
assert adapter.get_platform_hook_name(hook) is None
def test_sync_hooks_returns_zero(self, temp_dir: Path) -> None:
diff --git a/tests/unit/test_generator.py b/tests/unit/test_generator.py
index 839cd6fd..34827201 100644
--- a/tests/unit/test_generator.py
+++ b/tests/unit/test_generator.py
@@ -1,20 +1,20 @@
-"""Tests for command generator."""
+"""Tests for skill generator."""
from pathlib import Path
import pytest
from deepwork.core.adapters import ClaudeAdapter
-from deepwork.core.generator import CommandGenerator, GeneratorError
+from deepwork.core.generator import GeneratorError, SkillGenerator
from deepwork.core.parser import parse_job_definition
-class TestCommandGenerator:
- """Tests for CommandGenerator class."""
+class TestSkillGenerator:
+ """Tests for SkillGenerator class."""
def test_init_default_templates_dir(self) -> None:
"""Test initialization with default templates directory."""
- generator = CommandGenerator()
+ generator = SkillGenerator()
assert generator.templates_dir.exists()
assert (generator.templates_dir / "claude").exists()
@@ -24,7 +24,7 @@ def test_init_custom_templates_dir(self, temp_dir: Path) -> None:
templates_dir = temp_dir / "templates"
templates_dir.mkdir()
- generator = CommandGenerator(templates_dir)
+ generator = SkillGenerator(templates_dir)
assert generator.templates_dir == templates_dir
@@ -33,44 +33,45 @@ def test_init_raises_for_missing_templates_dir(self, temp_dir: Path) -> None:
nonexistent = temp_dir / "nonexistent"
with pytest.raises(GeneratorError, match="Templates directory not found"):
- CommandGenerator(nonexistent)
+ SkillGenerator(nonexistent)
- def test_generate_step_command_simple_job(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test generating command for simple job step (hidden by default)."""
+ def test_generate_step_skill_simple_job(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test generating skill for simple job step."""
job_dir = fixtures_dir / "jobs" / "simple_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- command_path = generator.generate_step_command(job, job.steps[0], adapter, temp_dir)
+ skill_path = generator.generate_step_skill(job, job.steps[0], adapter, temp_dir)
- assert command_path.exists()
- # Step commands are hidden by default (uw. prefix)
- assert command_path.name == "uw.simple_job.single_step.md"
+ assert skill_path.exists()
+ # Step skills use directory/SKILL.md format
+ assert skill_path.name == "SKILL.md"
+ assert skill_path.parent.name == "simple_job.single_step"
- content = command_path.read_text()
+ content = skill_path.read_text()
assert "# simple_job.single_step" in content
# Single step with no dependencies is treated as standalone
- assert "Standalone command" in content
+ assert "Standalone skill" in content
assert "input_param" in content
assert "output.md" in content
- def test_generate_step_command_complex_job_first_step(
+ def test_generate_step_skill_complex_job_first_step(
self, fixtures_dir: Path, temp_dir: Path
) -> None:
- """Test generating command for first step of complex job."""
+ """Test generating skill for first step of complex job."""
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- command_path = generator.generate_step_command(job, job.steps[0], adapter, temp_dir)
+ skill_path = generator.generate_step_skill(job, job.steps[0], adapter, temp_dir)
- content = command_path.read_text()
+ content = skill_path.read_text()
assert "# competitive_research.identify_competitors" in content
- assert "Step 1 of 4" in content
+ assert "Step 1/4" in content
assert "market_segment" in content
assert "product_category" in content
# First step has no prerequisites
@@ -78,64 +79,64 @@ def test_generate_step_command_complex_job_first_step(
# Has next step
assert "/competitive_research.primary_research" in content
- def test_generate_step_command_complex_job_middle_step(
+ def test_generate_step_skill_complex_job_middle_step(
self, fixtures_dir: Path, temp_dir: Path
) -> None:
- """Test generating command for middle step with dependencies."""
+ """Test generating skill for middle step with dependencies."""
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
# Generate primary_research (step 2)
- command_path = generator.generate_step_command(job, job.steps[1], adapter, temp_dir)
+ skill_path = generator.generate_step_skill(job, job.steps[1], adapter, temp_dir)
- content = command_path.read_text()
+ content = skill_path.read_text()
assert "# competitive_research.primary_research" in content
- assert "Step 2 of 4" in content
+ assert "Step 2/4" in content
# Has prerequisites
assert "## Prerequisites" in content
assert "/competitive_research.identify_competitors" in content
# Has file input
assert "competitors.md" in content
- assert "from step `identify_competitors`" in content
+ assert "from `identify_competitors`" in content
# Has next step
assert "/competitive_research.secondary_research" in content
- def test_generate_step_command_complex_job_final_step(
+ def test_generate_step_skill_complex_job_final_step(
self, fixtures_dir: Path, temp_dir: Path
) -> None:
- """Test generating command for final step."""
+ """Test generating skill for final step."""
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
# Generate comparative_report (step 4)
- command_path = generator.generate_step_command(job, job.steps[3], adapter, temp_dir)
+ skill_path = generator.generate_step_skill(job, job.steps[3], adapter, temp_dir)
- content = command_path.read_text()
+ content = skill_path.read_text()
assert "# competitive_research.comparative_report" in content
- assert "Step 4 of 4" in content
+ assert "Step 4/4" in content
# Has prerequisites
assert "## Prerequisites" in content
# Has multiple file inputs
assert "primary_research.md" in content
assert "secondary_research.md" in content
# Final step - no next step
- assert "## Workflow Complete" in content
+ assert "**Workflow complete**" in content
assert "## Next Step" not in content
- def test_generate_step_command_raises_for_missing_step(
+ def test_generate_step_skill_raises_for_missing_step(
self, fixtures_dir: Path, temp_dir: Path
) -> None:
- """Test that generating command for non-existent step raises error."""
+ """Test that generating skill for non-existent step raises error."""
job_dir = fixtures_dir / "jobs" / "simple_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
# Create a fake step not in the job
@@ -150,9 +151,9 @@ def test_generate_step_command_raises_for_missing_step(
)
with pytest.raises(GeneratorError, match="Step 'fake' not found"):
- generator.generate_step_command(job, fake_step, adapter, temp_dir)
+ generator.generate_step_skill(job, fake_step, adapter, temp_dir)
- def test_generate_step_command_raises_for_missing_instructions(
+ def test_generate_step_skill_raises_for_missing_instructions(
self, fixtures_dir: Path, temp_dir: Path
) -> None:
"""Test that missing instructions file raises error."""
@@ -167,97 +168,102 @@ def test_generate_step_command_raises_for_missing_instructions(
# Delete the instructions file
instructions_file.unlink()
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
with pytest.raises(GeneratorError, match="instructions file not found"):
- generator.generate_step_command(job, job.steps[0], adapter, temp_dir)
+ generator.generate_step_skill(job, job.steps[0], adapter, temp_dir)
finally:
# Restore the file
instructions_file.write_text(original_content)
- def test_generate_all_commands(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test generating commands for all steps in a job (meta + hidden steps)."""
+ def test_generate_all_skills(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test generating skills for all steps in a job (meta + step skills)."""
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- command_paths = generator.generate_all_commands(job, adapter, temp_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, temp_dir)
- # Now includes meta-command plus step commands
- assert len(command_paths) == 5 # 1 meta + 4 steps
- assert all(p.exists() for p in command_paths)
+ # Now includes meta-skill plus step skills
+ assert len(skill_paths) == 5 # 1 meta + 4 steps
+ assert all(p.exists() for p in skill_paths)
- # Check filenames - meta-command first, then hidden step commands
- expected_names = [
- "competitive_research.md", # Meta-command
- "uw.competitive_research.identify_competitors.md", # Hidden steps
- "uw.competitive_research.primary_research.md",
- "uw.competitive_research.secondary_research.md",
- "uw.competitive_research.comparative_report.md",
+ # Check directory names - meta-skill first, then step skills
+ # All files are named SKILL.md inside skill directories
+ expected_dirs = [
+ "competitive_research", # Meta-skill
+ "competitive_research.identify_competitors", # Step skills
+ "competitive_research.primary_research",
+ "competitive_research.secondary_research",
+ "competitive_research.comparative_report",
]
- actual_names = [p.name for p in command_paths]
- assert actual_names == expected_names
+ actual_dirs = [p.parent.name for p in skill_paths]
+ assert actual_dirs == expected_dirs
+ assert all(p.name == "SKILL.md" for p in skill_paths)
- def test_generate_meta_command(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test generating meta-command for a job."""
+ def test_generate_meta_skill(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test generating meta-skill for a job."""
job_dir = fixtures_dir / "jobs" / "complex_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- meta_command_path = generator.generate_meta_command(job, adapter, temp_dir)
+ meta_skill_path = generator.generate_meta_skill(job, adapter, temp_dir)
- assert meta_command_path.exists()
- assert meta_command_path.name == "competitive_research.md"
+ assert meta_skill_path.exists()
+ assert meta_skill_path.name == "SKILL.md"
+ assert meta_skill_path.parent.name == "competitive_research"
- content = meta_command_path.read_text()
- # Check meta-command content
+ content = meta_skill_path.read_text()
+ # Check meta-skill content
assert "# competitive_research" in content
assert "Available Steps" in content
assert "identify_competitors" in content
assert "primary_research" in content
assert "Skill tool" in content
- def test_generate_step_command_exposed_step(self, fixtures_dir: Path, temp_dir: Path) -> None:
- """Test generating command for exposed step (no uw. prefix)."""
+ def test_generate_step_skill_exposed_step(self, fixtures_dir: Path, temp_dir: Path) -> None:
+ """Test generating skill for exposed step."""
job_dir = fixtures_dir / "jobs" / "exposed_step_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
# Generate the exposed step (index 1)
- command_path = generator.generate_step_command(job, job.steps[1], adapter, temp_dir)
+ skill_path = generator.generate_step_skill(job, job.steps[1], adapter, temp_dir)
- assert command_path.exists()
- # Exposed step should NOT have uw. prefix
- assert command_path.name == "exposed_job.exposed_step.md"
+ assert skill_path.exists()
+ # Uses directory/SKILL.md format whether exposed or not
+ assert skill_path.name == "SKILL.md"
+ assert skill_path.parent.name == "exposed_job.exposed_step"
- def test_generate_all_commands_with_exposed_steps(
+ def test_generate_all_skills_with_exposed_steps(
self, fixtures_dir: Path, temp_dir: Path
) -> None:
- """Test generating all commands with mix of hidden and exposed steps."""
+ """Test generating all skills with mix of hidden and exposed steps."""
job_dir = fixtures_dir / "jobs" / "exposed_step_job"
job = parse_job_definition(job_dir)
- generator = CommandGenerator()
+ generator = SkillGenerator()
adapter = ClaudeAdapter()
- command_paths = generator.generate_all_commands(job, adapter, temp_dir)
+ skill_paths = generator.generate_all_skills(job, adapter, temp_dir)
- # Meta-command + 2 steps (1 hidden, 1 exposed)
- assert len(command_paths) == 3
- assert all(p.exists() for p in command_paths)
+ # Meta-skill + 2 steps
+ assert len(skill_paths) == 3
+ assert all(p.exists() for p in skill_paths)
- # Check filenames - hidden step has uw. prefix, exposed doesn't
- expected_names = [
- "exposed_job.md", # Meta-command
- "uw.exposed_job.hidden_step.md", # Hidden step
- "exposed_job.exposed_step.md", # Exposed step (no uw. prefix)
+ # Check directory names - all use directory/SKILL.md format
+ expected_dirs = [
+ "exposed_job", # Meta-skill
+ "exposed_job.hidden_step", # Step skill
+ "exposed_job.exposed_step", # Step skill
]
- actual_names = [p.name for p in command_paths]
- assert actual_names == expected_names
+ actual_dirs = [p.parent.name for p in skill_paths]
+ assert actual_dirs == expected_dirs
+ assert all(p.name == "SKILL.md" for p in skill_paths)
diff --git a/tests/unit/test_stop_hooks.py b/tests/unit/test_stop_hooks.py
index 0e30117e..7406600a 100644
--- a/tests/unit/test_stop_hooks.py
+++ b/tests/unit/test_stop_hooks.py
@@ -5,7 +5,7 @@
import pytest
from deepwork.core.adapters import ClaudeAdapter
-from deepwork.core.generator import CommandGenerator, GeneratorError
+from deepwork.core.generator import GeneratorError, SkillGenerator
from deepwork.core.parser import HookAction, JobDefinition, Step, StopHook
from deepwork.schemas.job_schema import JOB_SCHEMA
from deepwork.utils.validation import ValidationError, validate_against_schema
@@ -360,7 +360,7 @@ class TestGeneratorStopHooks:
"""Tests for generator stop hooks context building."""
@pytest.fixture
- def generator(self, tmp_path: Path) -> CommandGenerator:
+ def generator(self, tmp_path: Path) -> SkillGenerator:
"""Create generator with temp templates."""
templates_dir = tmp_path / "templates"
claude_dir = templates_dir / "claude"
@@ -387,8 +387,8 @@ def generator(self, tmp_path: Path) -> CommandGenerator:
# {{ job_name }}.{{ step_id }}
{{ instructions_content }}
"""
- (claude_dir / "command-job-step.md.jinja").write_text(template_content)
- return CommandGenerator(templates_dir)
+ (claude_dir / "skill-job-step.md.jinja").write_text(template_content)
+ return SkillGenerator(templates_dir)
@pytest.fixture
def job_with_hooks(self, tmp_path: Path) -> JobDefinition:
@@ -481,7 +481,7 @@ def job_with_prompt_file_hook(self, tmp_path: Path) -> JobDefinition:
)
def test_build_context_with_prompt_hook(
- self, generator: CommandGenerator, job_with_hooks: JobDefinition
+ self, generator: SkillGenerator, job_with_hooks: JobDefinition
) -> None:
"""Test context building includes prompt stop hook."""
adapter = ClaudeAdapter()
@@ -492,7 +492,7 @@ def test_build_context_with_prompt_hook(
assert context["stop_hooks"][0]["content"] == "Verify quality criteria"
def test_build_context_with_script_hook(
- self, generator: CommandGenerator, job_with_script_hook: JobDefinition
+ self, generator: SkillGenerator, job_with_script_hook: JobDefinition
) -> None:
"""Test context building includes script stop hook."""
adapter = ClaudeAdapter()
@@ -505,7 +505,7 @@ def test_build_context_with_script_hook(
assert context["stop_hooks"][0]["path"] == "hooks/validate.sh"
def test_build_context_with_prompt_file_hook(
- self, generator: CommandGenerator, job_with_prompt_file_hook: JobDefinition
+ self, generator: SkillGenerator, job_with_prompt_file_hook: JobDefinition
) -> None:
"""Test context building reads prompt file content."""
adapter = ClaudeAdapter()
@@ -518,7 +518,7 @@ def test_build_context_with_prompt_file_hook(
assert context["stop_hooks"][0]["content"] == "Check all quality criteria"
def test_build_context_with_missing_prompt_file(
- self, generator: CommandGenerator, tmp_path: Path
+ self, generator: SkillGenerator, tmp_path: Path
) -> None:
"""Test error when prompt file is missing."""
job_dir = tmp_path / "test_job"
@@ -551,7 +551,7 @@ def test_build_context_with_missing_prompt_file(
with pytest.raises(GeneratorError, match="prompt file not found"):
generator._build_step_context(job, job.steps[0], 0, adapter)
- def test_build_context_no_hooks(self, generator: CommandGenerator, tmp_path: Path) -> None:
+ def test_build_context_no_hooks(self, generator: SkillGenerator, tmp_path: Path) -> None:
"""Test context with no stop hooks."""
job_dir = tmp_path / "test_job"
job_dir.mkdir()
@@ -580,9 +580,7 @@ def test_build_context_no_hooks(self, generator: CommandGenerator, tmp_path: Pat
context = generator._build_step_context(job, job.steps[0], 0, adapter)
assert context["stop_hooks"] == []
- def test_build_context_multiple_hooks(
- self, generator: CommandGenerator, tmp_path: Path
- ) -> None:
+ def test_build_context_multiple_hooks(self, generator: SkillGenerator, tmp_path: Path) -> None:
"""Test context with multiple stop hooks."""
job_dir = tmp_path / "test_job"
job_dir.mkdir()
diff --git a/uv.lock b/uv.lock
index cd4110a3..564a99f6 100644
--- a/uv.lock
+++ b/uv.lock
@@ -126,7 +126,7 @@ toml = [
[[package]]
name = "deepwork"
-version = "0.4.0"
+version = "0.5.0"
source = { editable = "." }
dependencies = [
{ name = "click" },