221 lines
5.8 KiB
Markdown
221 lines
5.8 KiB
Markdown
|
|
<gsd-version v="1.12.4" />
|
||
|
|
|
||
|
|
<gsd-arguments>
|
||
|
|
<settings><keep-extra-args /></settings>
|
||
|
|
</gsd-arguments>
|
||
|
|
|
||
|
|
<gsd-execute>
|
||
|
|
<shell command="pi-gsd-tools">
|
||
|
|
<args>
|
||
|
|
<arg string="state" />
|
||
|
|
<arg string="json" />
|
||
|
|
<arg string="--raw" />
|
||
|
|
</args>
|
||
|
|
<outs>
|
||
|
|
<out type="string" name="state" />
|
||
|
|
</outs>
|
||
|
|
</shell>
|
||
|
|
<shell command="pi-gsd-tools">
|
||
|
|
<args>
|
||
|
|
<arg string="current-timestamp" />
|
||
|
|
<arg string="--raw" />
|
||
|
|
</args>
|
||
|
|
<outs>
|
||
|
|
<out type="string" name="timestamp" />
|
||
|
|
</outs>
|
||
|
|
</shell>
|
||
|
|
<!-- CLEAR _auto_chain_active - chain ends here -->
|
||
|
|
<shell command="pi-gsd-tools">
|
||
|
|
<args>
|
||
|
|
<arg string="config-set" />
|
||
|
|
<arg string="workflow._auto_chain_active" />
|
||
|
|
<arg string="false" />
|
||
|
|
</args>
|
||
|
|
<outs><suppress-errors /></outs>
|
||
|
|
</shell>
|
||
|
|
</gsd-execute>
|
||
|
|
|
||
|
|
## Context (pre-injected)
|
||
|
|
|
||
|
|
**State:**
|
||
|
|
<gsd-paste name="state" />
|
||
|
|
|
||
|
|
**Timestamp:** <gsd-paste name="timestamp" />
|
||
|
|
|
||
|
|
<purpose>
|
||
|
|
Create structured `.planning/HANDOFF.json` and `.continue-here.md` handoff files to preserve complete work state across sessions. The JSON provides machine-readable state for `/gsd-resume-work`; the markdown provides human-readable context.
|
||
|
|
</purpose>
|
||
|
|
|
||
|
|
<required_reading>
|
||
|
|
Read all files referenced by the invoking prompt's execution_context before starting.
|
||
|
|
</required_reading>
|
||
|
|
|
||
|
|
<process>
|
||
|
|
|
||
|
|
<step name="detect">
|
||
|
|
Find current phase directory from most recently modified files:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Find most recent phase directory with work
|
||
|
|
(ls -lt .planning/phases/*/PLAN.md 2>/dev/null || true) | head -1 | grep -oP 'phases/\K[^/]+' || true
|
||
|
|
```
|
||
|
|
|
||
|
|
If no active phase detected, ask user which phase they're pausing work on.
|
||
|
|
</step>
|
||
|
|
|
||
|
|
<step name="gather">
|
||
|
|
**Collect complete state for handoff:**
|
||
|
|
|
||
|
|
1. **Current position**: Which phase, which plan, which task
|
||
|
|
2. **Work completed**: What got done this session
|
||
|
|
3. **Work remaining**: What's left in current plan/phase
|
||
|
|
4. **Decisions made**: Key decisions and rationale
|
||
|
|
5. **Blockers/issues**: Anything stuck
|
||
|
|
6. **Human actions pending**: Things that need manual intervention (MCP setup, API keys, approvals, manual testing)
|
||
|
|
7. **Background processes**: Any running servers/watchers that were part of the workflow
|
||
|
|
8. **Files modified**: What's changed but not committed
|
||
|
|
|
||
|
|
Ask user for clarifications if needed via conversational questions.
|
||
|
|
|
||
|
|
**Also inspect SUMMARY.md files for false completions:**
|
||
|
|
```bash
|
||
|
|
# Check for placeholder content in existing summaries
|
||
|
|
grep -l "To be filled\|placeholder\|TBD" .planning/phases/*/*.md 2>/dev/null || true
|
||
|
|
```
|
||
|
|
Report any summaries with placeholder content as incomplete items.
|
||
|
|
</step>
|
||
|
|
|
||
|
|
<step name="write_structured">
|
||
|
|
**Write structured handoff to `.planning/HANDOFF.json`:**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
timestamp=$(pi-gsd-tools current-timestamp full --raw)
|
||
|
|
```
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"version": "1.0",
|
||
|
|
"timestamp": "{timestamp}",
|
||
|
|
"phase": "{phase_number}",
|
||
|
|
"phase_name": "{phase_name}",
|
||
|
|
"phase_dir": "{phase_dir}",
|
||
|
|
"plan": {current_plan_number},
|
||
|
|
"task": {current_task_number},
|
||
|
|
"total_tasks": {total_task_count},
|
||
|
|
"status": "paused",
|
||
|
|
"completed_tasks": [
|
||
|
|
{"id": 1, "name": "{task_name}", "status": "done", "commit": "{short_hash}"},
|
||
|
|
{"id": 2, "name": "{task_name}", "status": "done", "commit": "{short_hash}"},
|
||
|
|
{"id": 3, "name": "{task_name}", "status": "in_progress", "progress": "{what_done}"}
|
||
|
|
],
|
||
|
|
"remaining_tasks": [
|
||
|
|
{"id": 4, "name": "{task_name}", "status": "not_started"},
|
||
|
|
{"id": 5, "name": "{task_name}", "status": "not_started"}
|
||
|
|
],
|
||
|
|
"blockers": [
|
||
|
|
{"description": "{blocker}", "type": "technical|human_action|external", "workaround": "{if any}"}
|
||
|
|
],
|
||
|
|
"human_actions_pending": [
|
||
|
|
{"action": "{what needs to be done}", "context": "{why}", "blocking": true}
|
||
|
|
],
|
||
|
|
"decisions": [
|
||
|
|
{"decision": "{what}", "rationale": "{why}", "phase": "{phase_number}"}
|
||
|
|
],
|
||
|
|
"uncommitted_files": [],
|
||
|
|
"next_action": "{specific first action when resuming}",
|
||
|
|
"context_notes": "{mental state, approach, what you were thinking}"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
</step>
|
||
|
|
|
||
|
|
<step name="write">
|
||
|
|
**Write handoff to `.planning/phases/XX-name/.continue-here.md`:**
|
||
|
|
|
||
|
|
```markdown
|
||
|
|
---
|
||
|
|
phase: XX-name
|
||
|
|
task: 3
|
||
|
|
total_tasks: 7
|
||
|
|
status: in_progress
|
||
|
|
last_updated: [timestamp from current-timestamp]
|
||
|
|
---
|
||
|
|
|
||
|
|
<current_state>
|
||
|
|
[Where exactly are we? Immediate context]
|
||
|
|
</current_state>
|
||
|
|
|
||
|
|
<completed_work>
|
||
|
|
|
||
|
|
- Task 1: [name] - Done
|
||
|
|
- Task 2: [name] - Done
|
||
|
|
- Task 3: [name] - In progress, [what's done]
|
||
|
|
</completed_work>
|
||
|
|
|
||
|
|
<remaining_work>
|
||
|
|
|
||
|
|
- Task 3: [what's left]
|
||
|
|
- Task 4: Not started
|
||
|
|
- Task 5: Not started
|
||
|
|
</remaining_work>
|
||
|
|
|
||
|
|
<decisions_made>
|
||
|
|
|
||
|
|
- Decided to use [X] because [reason]
|
||
|
|
- Chose [approach] over [alternative] because [reason]
|
||
|
|
</decisions_made>
|
||
|
|
|
||
|
|
<blockers>
|
||
|
|
- [Blocker 1]: [status/workaround]
|
||
|
|
</blockers>
|
||
|
|
|
||
|
|
<context>
|
||
|
|
[Mental state, what were you thinking, the plan]
|
||
|
|
</context>
|
||
|
|
|
||
|
|
<next_action>
|
||
|
|
Start with: [specific first action when resuming]
|
||
|
|
</next_action>
|
||
|
|
```
|
||
|
|
|
||
|
|
Be specific enough for a fresh the agent to understand immediately.
|
||
|
|
|
||
|
|
Use `current-timestamp` for last_updated field. You can use init todos (which provides timestamps) or call directly:
|
||
|
|
```bash
|
||
|
|
timestamp=$(pi-gsd-tools current-timestamp full --raw)
|
||
|
|
```
|
||
|
|
</step>
|
||
|
|
|
||
|
|
<step name="commit">
|
||
|
|
```bash
|
||
|
|
pi-gsd-tools commit "wip: [phase-name] paused at task [X]/[Y]" --files .planning/phases/*/.continue-here.md .planning/HANDOFF.json
|
||
|
|
```
|
||
|
|
</step>
|
||
|
|
|
||
|
|
<step name="confirm">
|
||
|
|
```
|
||
|
|
✓ Handoff created:
|
||
|
|
- .planning/HANDOFF.json (structured, machine-readable)
|
||
|
|
- .planning/phases/[XX-name]/.continue-here.md (human-readable)
|
||
|
|
|
||
|
|
Current state:
|
||
|
|
|
||
|
|
- Phase: [XX-name]
|
||
|
|
- Task: [X] of [Y]
|
||
|
|
- Status: [in_progress/blocked]
|
||
|
|
- Blockers: [count] ({human_actions_pending count} need human action)
|
||
|
|
- Committed as WIP
|
||
|
|
|
||
|
|
To resume: /gsd-resume-work
|
||
|
|
|
||
|
|
```
|
||
|
|
</step>
|
||
|
|
|
||
|
|
</process>
|
||
|
|
|
||
|
|
<success_criteria>
|
||
|
|
- [ ] .continue-here.md created in correct phase directory
|
||
|
|
- [ ] All sections filled with specific content
|
||
|
|
- [ ] Committed as WIP
|
||
|
|
- [ ] User knows location and how to resume
|
||
|
|
</success_criteria>
|