deepwork 0.5.1__py3-none-any.whl → 0.7.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deepwork/__init__.py +1 -1
- deepwork/cli/hook.py +3 -4
- deepwork/cli/install.py +70 -117
- deepwork/cli/main.py +2 -2
- deepwork/cli/serve.py +133 -0
- deepwork/cli/sync.py +93 -58
- deepwork/core/adapters.py +91 -102
- deepwork/core/generator.py +19 -386
- deepwork/core/hooks_syncer.py +1 -1
- deepwork/core/parser.py +270 -1
- deepwork/hooks/README.md +0 -44
- deepwork/hooks/__init__.py +3 -6
- deepwork/hooks/check_version.sh +54 -21
- deepwork/mcp/__init__.py +23 -0
- deepwork/mcp/quality_gate.py +347 -0
- deepwork/mcp/schemas.py +263 -0
- deepwork/mcp/server.py +253 -0
- deepwork/mcp/state.py +422 -0
- deepwork/mcp/tools.py +394 -0
- deepwork/schemas/job.schema.json +347 -0
- deepwork/schemas/job_schema.py +27 -239
- deepwork/standard_jobs/deepwork_jobs/doc_specs/job_spec.md +9 -15
- deepwork/standard_jobs/deepwork_jobs/job.yml +146 -46
- deepwork/standard_jobs/deepwork_jobs/steps/define.md +100 -33
- deepwork/standard_jobs/deepwork_jobs/steps/errata.md +154 -0
- deepwork/standard_jobs/deepwork_jobs/steps/fix_jobs.md +207 -0
- deepwork/standard_jobs/deepwork_jobs/steps/fix_settings.md +177 -0
- deepwork/standard_jobs/deepwork_jobs/steps/implement.md +22 -138
- deepwork/standard_jobs/deepwork_jobs/steps/iterate.md +221 -0
- deepwork/standard_jobs/deepwork_jobs/steps/learn.md +2 -26
- deepwork/standard_jobs/deepwork_jobs/steps/test.md +154 -0
- deepwork/standard_jobs/deepwork_jobs/templates/job.yml.template +2 -0
- deepwork/templates/claude/settings.json +16 -0
- deepwork/templates/claude/skill-deepwork.md.jinja +37 -0
- deepwork/templates/gemini/skill-deepwork.md.jinja +37 -0
- deepwork-0.7.0a1.dist-info/METADATA +317 -0
- deepwork-0.7.0a1.dist-info/RECORD +64 -0
- deepwork/cli/rules.py +0 -32
- deepwork/core/command_executor.py +0 -190
- deepwork/core/pattern_matcher.py +0 -271
- deepwork/core/rules_parser.py +0 -559
- deepwork/core/rules_queue.py +0 -321
- deepwork/hooks/rules_check.py +0 -759
- deepwork/schemas/rules_schema.py +0 -135
- deepwork/standard_jobs/deepwork_jobs/steps/review_job_spec.md +0 -208
- deepwork/standard_jobs/deepwork_jobs/templates/doc_spec.md.example +0 -86
- deepwork/standard_jobs/deepwork_rules/hooks/capture_prompt_work_tree.sh +0 -38
- deepwork/standard_jobs/deepwork_rules/hooks/global_hooks.yml +0 -8
- deepwork/standard_jobs/deepwork_rules/hooks/user_prompt_submit.sh +0 -16
- deepwork/standard_jobs/deepwork_rules/job.yml +0 -49
- deepwork/standard_jobs/deepwork_rules/rules/.gitkeep +0 -13
- deepwork/standard_jobs/deepwork_rules/rules/api-documentation-sync.md.example +0 -10
- deepwork/standard_jobs/deepwork_rules/rules/readme-documentation.md.example +0 -10
- deepwork/standard_jobs/deepwork_rules/rules/security-review.md.example +0 -11
- deepwork/standard_jobs/deepwork_rules/rules/skill-md-validation.md +0 -46
- deepwork/standard_jobs/deepwork_rules/rules/source-test-pairing.md.example +0 -13
- deepwork/standard_jobs/deepwork_rules/steps/define.md +0 -249
- deepwork/templates/claude/skill-job-meta.md.jinja +0 -77
- deepwork/templates/claude/skill-job-step.md.jinja +0 -235
- deepwork/templates/gemini/skill-job-meta.toml.jinja +0 -76
- deepwork/templates/gemini/skill-job-step.toml.jinja +0 -162
- deepwork-0.5.1.dist-info/METADATA +0 -381
- deepwork-0.5.1.dist-info/RECORD +0 -72
- {deepwork-0.5.1.dist-info → deepwork-0.7.0a1.dist-info}/WHEEL +0 -0
- {deepwork-0.5.1.dist-info → deepwork-0.7.0a1.dist-info}/entry_points.txt +0 -0
- {deepwork-0.5.1.dist-info → deepwork-0.7.0a1.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
# Define Rule
|
|
2
|
-
|
|
3
|
-
## Objective
|
|
4
|
-
|
|
5
|
-
Create a new rule file in the `.deepwork/rules/` directory to enforce team guidelines, documentation requirements, or other constraints when specific files change.
|
|
6
|
-
|
|
7
|
-
## Task
|
|
8
|
-
|
|
9
|
-
Guide the user through defining a new rule by asking structured questions. **Do not create the rule without first understanding what they want to enforce.**
|
|
10
|
-
|
|
11
|
-
**Important**: Use the AskUserQuestion tool to ask structured questions when gathering information from the user. This provides a better user experience with clear options and guided choices.
|
|
12
|
-
|
|
13
|
-
### Step 1: Understand the Rule Purpose
|
|
14
|
-
|
|
15
|
-
Start by asking structured questions to understand what the user wants to enforce:
|
|
16
|
-
|
|
17
|
-
1. **What guideline or constraint should this rule enforce?**
|
|
18
|
-
- What situation triggers the need for action?
|
|
19
|
-
- What files or directories, when changed, should trigger this rule?
|
|
20
|
-
- Examples: "When config files change", "When API code changes", "When database schema changes"
|
|
21
|
-
|
|
22
|
-
2. **What action should be taken?**
|
|
23
|
-
- What should the agent do when the rule triggers?
|
|
24
|
-
- Update documentation? Perform a security review? Update tests?
|
|
25
|
-
- Is there a specific file or process that needs attention?
|
|
26
|
-
|
|
27
|
-
3. **Are there any "safety" conditions?**
|
|
28
|
-
- Are there files that, if also changed, mean the rule doesn't need to fire?
|
|
29
|
-
- For example: If config changes AND install_guide.md changes, assume docs are already updated
|
|
30
|
-
- This prevents redundant prompts when the user has already done the right thing
|
|
31
|
-
|
|
32
|
-
### Step 2: Choose the Detection Mode
|
|
33
|
-
|
|
34
|
-
Help the user select the appropriate detection mode:
|
|
35
|
-
|
|
36
|
-
**Trigger/Safety Mode** (most common):
|
|
37
|
-
- Fires when trigger patterns match AND no safety patterns match
|
|
38
|
-
- Use for: "When X changes, check Y" rules
|
|
39
|
-
- Example: When config changes, verify install docs
|
|
40
|
-
|
|
41
|
-
**Set Mode** (bidirectional correspondence):
|
|
42
|
-
- Fires when files that should change together don't all change
|
|
43
|
-
- Use for: Source/test pairing, model/migration sync
|
|
44
|
-
- Example: `src/foo.py` and `tests/foo_test.py` should change together
|
|
45
|
-
|
|
46
|
-
**Pair Mode** (directional correspondence):
|
|
47
|
-
- Fires when a trigger file changes but expected files don't
|
|
48
|
-
- Changes to expected files alone do NOT trigger
|
|
49
|
-
- Use for: API code requires documentation updates (but docs can update independently)
|
|
50
|
-
|
|
51
|
-
### Step 3: Define the Patterns
|
|
52
|
-
|
|
53
|
-
Help the user define glob patterns for files.
|
|
54
|
-
|
|
55
|
-
**Common patterns:**
|
|
56
|
-
- `src/**/*.py` - All Python files in src directory (recursive)
|
|
57
|
-
- `app/config/**/*` - All files in app/config directory
|
|
58
|
-
- `*.md` - All markdown files in root
|
|
59
|
-
- `src/api/**/*` - All files in the API directory
|
|
60
|
-
- `migrations/**/*.sql` - All SQL migrations
|
|
61
|
-
|
|
62
|
-
**Variable patterns (for set/pair modes):**
|
|
63
|
-
- `src/{path}.py` - Captures path variable (e.g., `foo/bar` from `src/foo/bar.py`)
|
|
64
|
-
- `tests/{path}_test.py` - Uses same path variable in corresponding file
|
|
65
|
-
- `{name}` matches single segment, `{path}` matches multiple segments
|
|
66
|
-
|
|
67
|
-
**Pattern syntax:**
|
|
68
|
-
- `*` - Matches any characters within a single path segment
|
|
69
|
-
- `**` - Matches any characters across multiple path segments (recursive)
|
|
70
|
-
- `?` - Matches a single character
|
|
71
|
-
|
|
72
|
-
### Step 4: Choose the Comparison Mode (Optional)
|
|
73
|
-
|
|
74
|
-
The `compare_to` field controls what baseline is used when detecting "changed files":
|
|
75
|
-
|
|
76
|
-
**Options:**
|
|
77
|
-
- `base` (default) - Compares to the base of the current branch (merge-base with main/master). Best for feature branches.
|
|
78
|
-
- `default_tip` - Compares to the current tip of the default branch. Useful for seeing difference from production.
|
|
79
|
-
- `prompt` - Compares to the state at the start of each prompt. For rules about very recent changes.
|
|
80
|
-
|
|
81
|
-
Most rules should use the default (`base`) and don't need to specify `compare_to`.
|
|
82
|
-
|
|
83
|
-
### Step 5: Write the Instructions
|
|
84
|
-
|
|
85
|
-
Create clear, actionable instructions for what the agent should do when the rule fires.
|
|
86
|
-
|
|
87
|
-
**Good instructions include:**
|
|
88
|
-
- What to check or review
|
|
89
|
-
- What files might need updating
|
|
90
|
-
- Specific actions to take
|
|
91
|
-
- Quality criteria for completion
|
|
92
|
-
|
|
93
|
-
**Template variables available in instructions:**
|
|
94
|
-
- `{trigger_files}` - Files that triggered the rule
|
|
95
|
-
- `{expected_files}` - Expected corresponding files (for set/pair modes)
|
|
96
|
-
|
|
97
|
-
### Step 6: Create the Rule File
|
|
98
|
-
|
|
99
|
-
Create a new file in `.deepwork/rules/` with a kebab-case filename:
|
|
100
|
-
|
|
101
|
-
**File Location**: `.deepwork/rules/{rule-name}.md`
|
|
102
|
-
|
|
103
|
-
**Format for Trigger/Safety Mode:**
|
|
104
|
-
```markdown
|
|
105
|
-
---
|
|
106
|
-
name: Friendly Name for the Rule
|
|
107
|
-
trigger: "glob/pattern/**/*" # or array: ["pattern1", "pattern2"]
|
|
108
|
-
safety: "optional/pattern" # optional, or array
|
|
109
|
-
compare_to: base # optional: "base" (default), "default_tip", or "prompt"
|
|
110
|
-
---
|
|
111
|
-
Instructions for the agent when this rule fires.
|
|
112
|
-
|
|
113
|
-
Multi-line markdown content is supported.
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Format for Set Mode (bidirectional):**
|
|
117
|
-
```markdown
|
|
118
|
-
---
|
|
119
|
-
name: Source/Test Pairing
|
|
120
|
-
set:
|
|
121
|
-
- src/{path}.py
|
|
122
|
-
- tests/{path}_test.py
|
|
123
|
-
---
|
|
124
|
-
Source and test files should change together.
|
|
125
|
-
|
|
126
|
-
Modified: {trigger_files}
|
|
127
|
-
Expected: {expected_files}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Format for Pair Mode (directional):**
|
|
131
|
-
```markdown
|
|
132
|
-
---
|
|
133
|
-
name: API Documentation
|
|
134
|
-
pair:
|
|
135
|
-
trigger: api/{path}.py
|
|
136
|
-
expects: docs/api/{path}.md
|
|
137
|
-
---
|
|
138
|
-
API code requires documentation updates.
|
|
139
|
-
|
|
140
|
-
Changed API: {trigger_files}
|
|
141
|
-
Update docs: {expected_files}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Step 7: Verify the Rule
|
|
145
|
-
|
|
146
|
-
After creating the rule:
|
|
147
|
-
|
|
148
|
-
1. **Check the YAML frontmatter** - Ensure valid YAML formatting
|
|
149
|
-
2. **Test trigger patterns** - Verify patterns match intended files
|
|
150
|
-
3. **Review instructions** - Ensure they're clear and actionable
|
|
151
|
-
4. **Check for conflicts** - Ensure the rule doesn't conflict with existing ones
|
|
152
|
-
|
|
153
|
-
## Example Rules
|
|
154
|
-
|
|
155
|
-
### Update Documentation on Config Changes
|
|
156
|
-
`.deepwork/rules/config-docs.md`:
|
|
157
|
-
```markdown
|
|
158
|
-
---
|
|
159
|
-
name: Update Install Guide on Config Changes
|
|
160
|
-
trigger: app/config/**/*
|
|
161
|
-
safety: docs/install_guide.md
|
|
162
|
-
---
|
|
163
|
-
Configuration files have been modified. Please review docs/install_guide.md
|
|
164
|
-
and update it if any installation instructions need to change based on the
|
|
165
|
-
new configuration.
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Security Review for Auth Code
|
|
169
|
-
`.deepwork/rules/security-review.md`:
|
|
170
|
-
```markdown
|
|
171
|
-
---
|
|
172
|
-
name: Security Review for Authentication Changes
|
|
173
|
-
trigger:
|
|
174
|
-
- src/auth/**/*
|
|
175
|
-
- src/security/**/*
|
|
176
|
-
safety:
|
|
177
|
-
- SECURITY.md
|
|
178
|
-
- docs/security_audit.md
|
|
179
|
-
---
|
|
180
|
-
Authentication or security code has been changed. Please:
|
|
181
|
-
|
|
182
|
-
1. Review for hardcoded credentials or secrets
|
|
183
|
-
2. Check input validation on user inputs
|
|
184
|
-
3. Verify access control logic is correct
|
|
185
|
-
4. Update security documentation if needed
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Source/Test Pairing
|
|
189
|
-
`.deepwork/rules/source-test-pairing.md`:
|
|
190
|
-
```markdown
|
|
191
|
-
---
|
|
192
|
-
name: Source/Test Pairing
|
|
193
|
-
set:
|
|
194
|
-
- src/{path}.py
|
|
195
|
-
- tests/{path}_test.py
|
|
196
|
-
---
|
|
197
|
-
Source and test files should change together.
|
|
198
|
-
|
|
199
|
-
When modifying source code, ensure corresponding tests are updated.
|
|
200
|
-
When adding tests, ensure they test actual source code.
|
|
201
|
-
|
|
202
|
-
Modified: {trigger_files}
|
|
203
|
-
Expected: {expected_files}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### API Documentation Sync
|
|
207
|
-
`.deepwork/rules/api-docs.md`:
|
|
208
|
-
```markdown
|
|
209
|
-
---
|
|
210
|
-
name: API Documentation Update
|
|
211
|
-
pair:
|
|
212
|
-
trigger: src/api/{path}.py
|
|
213
|
-
expects: docs/api/{path}.md
|
|
214
|
-
---
|
|
215
|
-
API code has changed. Please verify that API documentation in docs/api/
|
|
216
|
-
is up to date with the code changes. Pay special attention to:
|
|
217
|
-
|
|
218
|
-
- New or changed endpoints
|
|
219
|
-
- Modified request/response schemas
|
|
220
|
-
- Updated authentication requirements
|
|
221
|
-
|
|
222
|
-
Changed API: {trigger_files}
|
|
223
|
-
Update: {expected_files}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
## Output Format
|
|
227
|
-
|
|
228
|
-
### .deepwork/rules/{rule-name}.md
|
|
229
|
-
Create a new file with the rule definition using YAML frontmatter and markdown body.
|
|
230
|
-
|
|
231
|
-
## Quality Criteria
|
|
232
|
-
|
|
233
|
-
- Asked structured questions to understand user requirements
|
|
234
|
-
- Rule name is clear and descriptive (used in promise tags)
|
|
235
|
-
- Correct detection mode selected for the use case
|
|
236
|
-
- Patterns accurately match the intended files
|
|
237
|
-
- Safety patterns prevent unnecessary triggering (if applicable)
|
|
238
|
-
- Instructions are actionable and specific
|
|
239
|
-
- YAML frontmatter is valid
|
|
240
|
-
|
|
241
|
-
## Context
|
|
242
|
-
|
|
243
|
-
Rules are evaluated automatically when the agent finishes a task. The system:
|
|
244
|
-
1. Determines which files have changed based on each rule's `compare_to` setting
|
|
245
|
-
2. Evaluates rules based on their detection mode (trigger/safety, set, or pair)
|
|
246
|
-
3. Skips rules where the correspondence is satisfied (for set/pair) or safety matched
|
|
247
|
-
4. Prompts you with instructions for any triggered rules
|
|
248
|
-
|
|
249
|
-
You can mark a rule as addressed by including `<promise>Rule Name</promise>` 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.
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
{#
|
|
2
|
-
Template: skill-job-meta.md.jinja
|
|
3
|
-
Purpose: Generates the job overview skill file for Claude Code
|
|
4
|
-
|
|
5
|
-
Template Variables:
|
|
6
|
-
- job_name: string - Job identifier (e.g., "competitive_research")
|
|
7
|
-
- job_summary: string - Short one-line summary of the job
|
|
8
|
-
- job_description: string|null - Full description (optional)
|
|
9
|
-
- total_steps: int - Number of steps in the job
|
|
10
|
-
- steps: list - Array of step objects:
|
|
11
|
-
- id: string - Step identifier
|
|
12
|
-
- name: string - Human-readable step name
|
|
13
|
-
- description: string - What the step does
|
|
14
|
-
- command_name: string - Slash command (e.g., "job_name.step_id")
|
|
15
|
-
- dependencies: list[string]|null - Required prior steps
|
|
16
|
-
#}
|
|
17
|
-
---
|
|
18
|
-
name: {{ job_name }}
|
|
19
|
-
description: "{{ job_summary }}"
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
# {{ job_name }}
|
|
23
|
-
|
|
24
|
-
**Multi-step workflow**: {{ job_summary }}
|
|
25
|
-
|
|
26
|
-
> **CRITICAL**: Always invoke steps using the Skill tool. Never copy/paste step instructions directly.
|
|
27
|
-
|
|
28
|
-
{% if job_description %}
|
|
29
|
-
{{ job_description }}
|
|
30
|
-
{% endif %}
|
|
31
|
-
|
|
32
|
-
## Available Steps
|
|
33
|
-
|
|
34
|
-
{% for step in steps %}
|
|
35
|
-
{{ loop.index }}. **{{ step.id }}** - {{ step.description }}{% if step.dependencies %} (requires: {{ step.dependencies | join(', ') }}){% endif %}
|
|
36
|
-
|
|
37
|
-
{% endfor %}
|
|
38
|
-
|
|
39
|
-
## Execution Instructions
|
|
40
|
-
|
|
41
|
-
### Step 1: Analyze Intent
|
|
42
|
-
|
|
43
|
-
Parse any text following `/{{ job_name }}` to determine user intent:
|
|
44
|
-
{% for step in steps %}
|
|
45
|
-
- "{{ step.id }}" or related terms → start at `{{ step.command_name }}`
|
|
46
|
-
{% endfor %}
|
|
47
|
-
|
|
48
|
-
### Step 2: Invoke Starting Step
|
|
49
|
-
|
|
50
|
-
Use the Skill tool to invoke the identified starting step:
|
|
51
|
-
```
|
|
52
|
-
Skill tool: {{ steps[0].command_name }}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Step 3: Continue Workflow Automatically
|
|
56
|
-
|
|
57
|
-
After each step completes:
|
|
58
|
-
1. Check if there's a next step in the sequence
|
|
59
|
-
2. Invoke the next step using the Skill tool
|
|
60
|
-
3. Repeat until workflow is complete or user intervenes
|
|
61
|
-
|
|
62
|
-
### Handling Ambiguous Intent
|
|
63
|
-
|
|
64
|
-
If user intent is unclear, use AskUserQuestion to clarify:
|
|
65
|
-
- Present available steps as numbered options
|
|
66
|
-
- Let user select the starting point
|
|
67
|
-
|
|
68
|
-
## Guardrails
|
|
69
|
-
|
|
70
|
-
- Do NOT copy/paste step instructions directly; always use the Skill tool to invoke steps
|
|
71
|
-
- Do NOT skip steps in the workflow unless the user explicitly requests it
|
|
72
|
-
- Do NOT proceed to the next step if the current step's outputs are incomplete
|
|
73
|
-
- Do NOT make assumptions about user intent; ask for clarification when ambiguous
|
|
74
|
-
|
|
75
|
-
## Context Files
|
|
76
|
-
|
|
77
|
-
- Job definition: `.deepwork/jobs/{{ job_name }}/job.yml`
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
{#
|
|
2
|
-
Template: skill-job-step.md.jinja
|
|
3
|
-
Purpose: Generates individual step skill files for Claude Code
|
|
4
|
-
|
|
5
|
-
Template Variables:
|
|
6
|
-
Job Context:
|
|
7
|
-
- job_name: string - Job identifier
|
|
8
|
-
- job_summary: string - Short job summary
|
|
9
|
-
- job_description: string|null - Full job description
|
|
10
|
-
|
|
11
|
-
Step Metadata:
|
|
12
|
-
- step_id: string - Step identifier
|
|
13
|
-
- step_description: string - What this step does
|
|
14
|
-
- step_number: int - Position in workflow (1-indexed)
|
|
15
|
-
- total_steps: int - Total steps in job
|
|
16
|
-
- is_standalone: bool - True if step can run independently
|
|
17
|
-
- exposed: bool - True if user can invoke directly (default: true)
|
|
18
|
-
- dependencies: list[string]|null - Required prior step IDs
|
|
19
|
-
- next_step: string|null - Next step ID in workflow
|
|
20
|
-
- instructions_file: string - Path to step instructions file
|
|
21
|
-
|
|
22
|
-
Step Content:
|
|
23
|
-
- instructions_content: string - Full instructions markdown
|
|
24
|
-
- user_inputs: list|null - User parameters to gather:
|
|
25
|
-
- name: string - Parameter name
|
|
26
|
-
- description: string - What to ask for
|
|
27
|
-
- file_inputs: list|null - Files from previous steps:
|
|
28
|
-
- file: string - File path
|
|
29
|
-
- from_step: string - Source step ID
|
|
30
|
-
- outputs: list[string]|null - Output file paths
|
|
31
|
-
|
|
32
|
-
Quality & Hooks:
|
|
33
|
-
- quality_criteria: list[string]|null - Criteria for completion
|
|
34
|
-
- stop_hooks: list|null - Stop hook configurations:
|
|
35
|
-
- type: "script"|"prompt"
|
|
36
|
-
- path: string (for script)
|
|
37
|
-
- content: string (for prompt)
|
|
38
|
-
- hooks: dict|null - All hooks by event name (Stop, PreToolUse, etc.)
|
|
39
|
-
#}
|
|
40
|
-
---
|
|
41
|
-
name: {{ job_name }}.{{ step_id }}
|
|
42
|
-
description: "{{ step_description }}"
|
|
43
|
-
{%- if not exposed %}
|
|
44
|
-
user-invocable: false
|
|
45
|
-
{%- endif %}{#- if not exposed #}
|
|
46
|
-
{#-
|
|
47
|
-
NOTE: Prompt-based stop hooks do not currently work in Claude Code.
|
|
48
|
-
See: https://github.com/anthropics/claude-code/issues/20221
|
|
49
|
-
Only command/script hooks are generated here. Prompt hooks are filtered out.
|
|
50
|
-
Quality validation is handled via sub-agent review in the instructions section.
|
|
51
|
-
#}
|
|
52
|
-
{%- if hooks -%}
|
|
53
|
-
{%- set has_command_hooks = namespace(value=false) -%}
|
|
54
|
-
{%- for event_name, event_hooks in hooks.items() -%}
|
|
55
|
-
{%- for hook in event_hooks -%}
|
|
56
|
-
{%- if hook.type == "script" -%}
|
|
57
|
-
{%- set has_command_hooks.value = true -%}
|
|
58
|
-
{%- endif -%}{#- if hook.type == "script" #}
|
|
59
|
-
{%- endfor -%}{#- for hook in event_hooks #}
|
|
60
|
-
{%- endfor -%}{#- for event_name, event_hooks in hooks.items() #}
|
|
61
|
-
{%- if has_command_hooks.value %}
|
|
62
|
-
hooks:
|
|
63
|
-
{%- for event_name, event_hooks in hooks.items() %}
|
|
64
|
-
{%- set script_hooks = event_hooks | selectattr("type", "equalto", "script") | list %}
|
|
65
|
-
{%- if script_hooks -%}
|
|
66
|
-
{#- For Stop events, generate both Stop and SubagentStop blocks #}
|
|
67
|
-
{%- if event_name == "Stop" %}
|
|
68
|
-
{%- for stop_event in ["Stop", "SubagentStop"] %}
|
|
69
|
-
{{ stop_event }}:
|
|
70
|
-
- hooks:
|
|
71
|
-
{%- for hook in script_hooks %}
|
|
72
|
-
- type: command
|
|
73
|
-
command: ".deepwork/jobs/{{ job_name }}/{{ hook.path }}"
|
|
74
|
-
{%- endfor %}{#- for hook in script_hooks #}
|
|
75
|
-
{%- endfor %}{#- for stop_event in ["Stop", "SubagentStop"] #}
|
|
76
|
-
{%- elif event_name != "SubagentStop" or "Stop" not in hooks %}
|
|
77
|
-
{{ event_name }}:
|
|
78
|
-
- hooks:
|
|
79
|
-
{%- for hook in script_hooks %}
|
|
80
|
-
- type: command
|
|
81
|
-
command: ".deepwork/jobs/{{ job_name }}/{{ hook.path }}"
|
|
82
|
-
{%- endfor %}{#- for hook in script_hooks #}
|
|
83
|
-
{%- endif %}{#- if event_name == "Stop" #}
|
|
84
|
-
{%- endif %}{#- if script_hooks #}
|
|
85
|
-
{%- endfor %}{#- for event_name, event_hooks in hooks.items() #}
|
|
86
|
-
{%- endif %}{#- if has_command_hooks.value #}
|
|
87
|
-
{%- endif %}{#- if hooks #}
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
# {{ job_name }}.{{ step_id }}
|
|
91
|
-
|
|
92
|
-
{% if is_standalone %}
|
|
93
|
-
**Standalone skill** - can be run anytime
|
|
94
|
-
{% else %}
|
|
95
|
-
**Step {{ step_number }}/{{ total_steps }}** in **{{ job_name }}** workflow
|
|
96
|
-
{% endif %}{#- if is_standalone #}
|
|
97
|
-
|
|
98
|
-
> {{ job_summary }}
|
|
99
|
-
|
|
100
|
-
{% if dependencies %}
|
|
101
|
-
## Prerequisites (Verify First)
|
|
102
|
-
|
|
103
|
-
Before proceeding, confirm these steps are complete:
|
|
104
|
-
{% for dep in dependencies %}
|
|
105
|
-
- `/{{ job_name }}.{{ dep }}`
|
|
106
|
-
{% endfor %}{#- for dep in dependencies #}
|
|
107
|
-
{% endif %}{#- if dependencies #}
|
|
108
|
-
|
|
109
|
-
## Instructions
|
|
110
|
-
|
|
111
|
-
**Goal**: {{ step_description }}
|
|
112
|
-
|
|
113
|
-
{{ instructions_content }}
|
|
114
|
-
|
|
115
|
-
{% if job_description %}
|
|
116
|
-
### Job Context
|
|
117
|
-
|
|
118
|
-
{{ job_description }}
|
|
119
|
-
{% endif %}{#- if job_description #}
|
|
120
|
-
|
|
121
|
-
{% if user_inputs or file_inputs %}
|
|
122
|
-
## Required Inputs
|
|
123
|
-
|
|
124
|
-
{% if user_inputs %}
|
|
125
|
-
**User Parameters** - Gather from user before starting:
|
|
126
|
-
{% for input in user_inputs %}
|
|
127
|
-
- **{{ input.name }}**: {{ input.description }}
|
|
128
|
-
{% endfor %}{#- for input in user_inputs #}
|
|
129
|
-
{% endif %}{#- if user_inputs #}
|
|
130
|
-
|
|
131
|
-
{% if file_inputs %}
|
|
132
|
-
**Files from Previous Steps** - Read these first:
|
|
133
|
-
{% for input in file_inputs %}
|
|
134
|
-
- `{{ input.file }}` (from `{{ input.from_step }}`)
|
|
135
|
-
{% endfor %}{#- for input in file_inputs #}
|
|
136
|
-
{% endif %}{#- if file_inputs #}
|
|
137
|
-
{% endif %}{#- if user_inputs or file_inputs #}
|
|
138
|
-
|
|
139
|
-
## Work Branch
|
|
140
|
-
|
|
141
|
-
Use branch format: `deepwork/{{ job_name }}-[instance]-YYYYMMDD`
|
|
142
|
-
|
|
143
|
-
- If on a matching work branch: continue using it
|
|
144
|
-
- If on main/master: create new branch with `git checkout -b deepwork/{{ job_name }}-[instance]-$(date +%Y%m%d)`
|
|
145
|
-
|
|
146
|
-
## Outputs
|
|
147
|
-
|
|
148
|
-
{% if outputs %}
|
|
149
|
-
**Required outputs**:
|
|
150
|
-
{% for output in outputs %}
|
|
151
|
-
- `{{ output.file }}`{% if output.file.endswith('/') %} (directory){% endif %}
|
|
152
|
-
|
|
153
|
-
{% if output.has_doc_spec and output.doc_spec %}
|
|
154
|
-
**Doc Spec**: {{ output.doc_spec.name }}
|
|
155
|
-
> {{ output.doc_spec.description }}
|
|
156
|
-
**Definition**: `{{ output.doc_spec.path }}`
|
|
157
|
-
{% if output.doc_spec.target_audience %}
|
|
158
|
-
**Target Audience**: {{ output.doc_spec.target_audience }}
|
|
159
|
-
{% endif %}{#- if output.doc_spec.target_audience #}
|
|
160
|
-
{% if output.doc_spec.quality_criteria %}
|
|
161
|
-
**Quality Criteria**:
|
|
162
|
-
{% for criterion in output.doc_spec.quality_criteria %}
|
|
163
|
-
{{ loop.index }}. **{{ criterion.name }}**: {{ criterion.description }}
|
|
164
|
-
{% endfor %}{#- for criterion in output.doc_spec.quality_criteria #}
|
|
165
|
-
{% endif %}{#- if output.doc_spec.quality_criteria #}
|
|
166
|
-
{% if output.doc_spec.example_document %}
|
|
167
|
-
|
|
168
|
-
<details>
|
|
169
|
-
<summary>Example Document Structure</summary>
|
|
170
|
-
|
|
171
|
-
```markdown
|
|
172
|
-
{{ output.doc_spec.example_document | indent(2) }}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
</details>
|
|
176
|
-
{% endif %}{#- if output.doc_spec.example_document #}
|
|
177
|
-
{% endif %}{#- if output.has_doc_spec and output.doc_spec #}
|
|
178
|
-
{% endfor %}{#- for output in outputs #}
|
|
179
|
-
{% else %}
|
|
180
|
-
No specific file outputs required.
|
|
181
|
-
{% endif %}{#- if outputs #}
|
|
182
|
-
|
|
183
|
-
## Guardrails
|
|
184
|
-
|
|
185
|
-
- Do NOT skip prerequisite verification if this step has dependencies
|
|
186
|
-
- Do NOT produce partial outputs; complete all required outputs before finishing
|
|
187
|
-
- Do NOT proceed without required inputs; ask the user if any are missing
|
|
188
|
-
- Do NOT modify files outside the scope of this step's defined outputs
|
|
189
|
-
|
|
190
|
-
{% if quality_criteria %}
|
|
191
|
-
## Quality Validation
|
|
192
|
-
|
|
193
|
-
**Before completing this step, you MUST have your work reviewed against the quality criteria below.**
|
|
194
|
-
|
|
195
|
-
Use a sub-agent (Haiku model) to review your work against these criteria:
|
|
196
|
-
|
|
197
|
-
**Criteria (all must be satisfied)**:
|
|
198
|
-
{% for criterion in quality_criteria -%}
|
|
199
|
-
{{ loop.index }}. {{ criterion }}
|
|
200
|
-
{% endfor %}{#- for criterion in quality_criteria #}
|
|
201
|
-
**Review Process**:
|
|
202
|
-
1. Once you believe your work is complete, spawn a sub-agent using Haiku to review your work against the quality criteria above
|
|
203
|
-
2. The sub-agent should examine your outputs and verify each criterion is met
|
|
204
|
-
3. If the sub-agent identifies valid issues, fix them
|
|
205
|
-
4. Have the sub-agent review again until all valid feedback has been addressed
|
|
206
|
-
5. Only mark the step complete when the sub-agent confirms all criteria are satisfied
|
|
207
|
-
|
|
208
|
-
{% endif %}{#- if quality_criteria #}
|
|
209
|
-
{% if stop_hooks -%}
|
|
210
|
-
{% for hook in stop_hooks -%}
|
|
211
|
-
{% if hook.type == "script" -%}
|
|
212
|
-
**Validation script**: `.deepwork/jobs/{{ job_name }}/{{ hook.path }}` (runs automatically)
|
|
213
|
-
{% endif -%}{#- if hook.type == "script" #}
|
|
214
|
-
{% endfor %}{#- for hook in stop_hooks #}
|
|
215
|
-
{% endif %}{#- if stop_hooks #}
|
|
216
|
-
## On Completion
|
|
217
|
-
|
|
218
|
-
{% if is_standalone %}
|
|
219
|
-
1. Verify outputs are created
|
|
220
|
-
2. Inform user: "{{ step_id }} complete{% if outputs %}, outputs: {{ outputs | map(attribute='file') | join(', ') }}{% endif %}"
|
|
221
|
-
|
|
222
|
-
This standalone skill can be re-run anytime.
|
|
223
|
-
{% else %}
|
|
224
|
-
1. Verify outputs are created
|
|
225
|
-
2. Inform user: "Step {{ step_number }}/{{ total_steps }} complete{% if outputs %}, outputs: {{ outputs | map(attribute='file') | join(', ') }}{% endif %}"
|
|
226
|
-
{% if next_step %}
|
|
227
|
-
3. **Continue workflow**: Use Skill tool to invoke `/{{ job_name }}.{{ next_step }}`
|
|
228
|
-
{% else %}
|
|
229
|
-
3. **Workflow complete**: All steps finished. Consider creating a PR to merge the work branch.
|
|
230
|
-
{% endif %}{#- if next_step #}
|
|
231
|
-
{% endif %}{#- if is_standalone #}
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
**Reference files**: `.deepwork/jobs/{{ job_name }}/job.yml`, `.deepwork/jobs/{{ job_name }}/{{ instructions_file }}`
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
{#
|
|
2
|
-
Template: skill-job-meta.toml.jinja
|
|
3
|
-
Purpose: Generates the job overview skill file for Gemini CLI
|
|
4
|
-
|
|
5
|
-
Template Variables:
|
|
6
|
-
- job_name: string - Job identifier (e.g., "competitive_research")
|
|
7
|
-
- job_summary: string - Short one-line summary of the job
|
|
8
|
-
- job_description: string|null - Full description (optional)
|
|
9
|
-
- total_steps: int - Number of steps in the job
|
|
10
|
-
- steps: list - Array of step objects:
|
|
11
|
-
- id: string - Step identifier
|
|
12
|
-
- name: string - Human-readable step name
|
|
13
|
-
- description: string - What the step does
|
|
14
|
-
- command_name: string - Slash command (e.g., "job_name:step_id")
|
|
15
|
-
- dependencies: list[string]|null - Required prior steps
|
|
16
|
-
|
|
17
|
-
Note: Gemini uses TOML format with description + prompt fields.
|
|
18
|
-
Commands use colon separator (/job_name:step_id) not period.
|
|
19
|
-
#}
|
|
20
|
-
# {{ job_name }}
|
|
21
|
-
#
|
|
22
|
-
# {{ job_summary }}
|
|
23
|
-
#
|
|
24
|
-
# Generated by DeepWork - do not edit manually
|
|
25
|
-
|
|
26
|
-
description = "{{ job_summary | replace('"', '\\"') }}"
|
|
27
|
-
|
|
28
|
-
prompt = """
|
|
29
|
-
# {{ job_name }}
|
|
30
|
-
|
|
31
|
-
**Multi-step workflow**: {{ job_summary }}
|
|
32
|
-
|
|
33
|
-
> **NOTE**: Gemini CLI requires manual command invocation. After each step, tell the user which command to run next.
|
|
34
|
-
|
|
35
|
-
{% if job_description %}
|
|
36
|
-
{{ job_description }}
|
|
37
|
-
{% endif %}
|
|
38
|
-
|
|
39
|
-
## Available Steps
|
|
40
|
-
|
|
41
|
-
{% for step in steps %}
|
|
42
|
-
{{ loop.index }}. **{{ step.id }}** - {{ step.description }}{% if step.dependencies %} (requires: {{ step.dependencies | join(', ') }}){% endif %}
|
|
43
|
-
|
|
44
|
-
Command: `/{{ step.command_name }}`
|
|
45
|
-
{% endfor %}
|
|
46
|
-
|
|
47
|
-
## Execution Instructions
|
|
48
|
-
|
|
49
|
-
### Step 1: Analyze Intent
|
|
50
|
-
|
|
51
|
-
Parse any text following `/{{ job_name }}` to determine user intent:
|
|
52
|
-
{% for step in steps %}
|
|
53
|
-
- "{{ step.id }}" or related terms → start at `/{{ step.command_name }}`
|
|
54
|
-
{% endfor %}
|
|
55
|
-
|
|
56
|
-
### Step 2: Direct User to Starting Step
|
|
57
|
-
|
|
58
|
-
Tell the user which command to run:
|
|
59
|
-
```
|
|
60
|
-
/{{ steps[0].command_name }}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Step 3: Guide Through Workflow
|
|
64
|
-
|
|
65
|
-
After each step completes, tell the user the next command to run until workflow is complete.
|
|
66
|
-
|
|
67
|
-
### Handling Ambiguous Intent
|
|
68
|
-
|
|
69
|
-
If user intent is unclear:
|
|
70
|
-
- Present available steps as numbered options
|
|
71
|
-
- Ask user to select the starting point
|
|
72
|
-
|
|
73
|
-
## Reference
|
|
74
|
-
|
|
75
|
-
- Job definition: `.deepwork/jobs/{{ job_name }}/job.yml`
|
|
76
|
-
"""
|