fix(handoff): quote heredoc to prevent git output execution
Git status output contains ## which was being interpreted as bash. Split render() into quoted heredocs + echo statements.
This commit is contained in:
parent
9efc9aaa9f
commit
f2d7fd7451
|
|
@ -277,7 +277,7 @@
|
|||
{"id":"skills-sx8u","title":"Build 'spec new' command","description":"CLI command to create new spec from template.\n\n## Usage\n```bash\nspec new \"feature name\"\nspec new \"feature name\" --template=minimal\n```\n\n## Behavior\n- Generate unique ID\n- Create file in .specs/active/\n- Pre-fill template sections\n- Open in editor (optional)\n\n## Implementation\n- Shell script or small tool\n- Template interpolation\n- ID generation (timestamp? random?)","status":"closed","priority":2,"issue_type":"task","owner":"dan@delpad","created_at":"2026-01-18T08:13:57.937067038-08:00","created_by":"dan","updated_at":"2026-01-18T08:25:53.383301191-08:00","closed_at":"2026-01-18T08:25:53.383301191-08:00","close_reason":"Simplified: structure in bead issues, not separate files","dependencies":[{"issue_id":"skills-sx8u","depends_on_id":"skills-oh8m","type":"blocks","created_at":"2026-01-18T08:14:32.51120206-08:00","created_by":"dan"},{"issue_id":"skills-sx8u","depends_on_id":"skills-ya44","type":"blocks","created_at":"2026-01-18T08:14:44.593664507-08:00","created_by":"dan"},{"issue_id":"skills-sx8u","depends_on_id":"skills-rqi3","type":"blocks","created_at":"2026-01-18T08:14:44.688938513-08:00","created_by":"dan"}]}
|
||||
{"id":"skills-t9ub","title":"Clean up dead code and unused imports","description":"Quick cleanup pass:\n\n- skills-5ax: Remove unused strformat, strutils imports in db.nim\n- skills-kvdl: Remove unused globalChannel in heartbeat.nim\n- skills-ib9u: Remove unused times import in heartbeat.nim\n- skills-fdu: Verify BusJsonlPath, BlobsDir, WorkersDir usage, delete if unused\n- skills-ghlb: Remove unused 'by' parameter from approve()\n\nParent: skills-g2wa","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-10T20:18:50.017642793-08:00","created_by":"dan","updated_at":"2026-01-10T20:41:09.681717088-08:00","closed_at":"2026-01-10T20:41:09.681717088-08:00","close_reason":"Dead code cleanup complete"}
|
||||
{"id":"skills-tdfm","title":"Add error handling to writeContext for file write failures","description":"[ERROR] MED context.nim:11 - writeFile can fail (permissions, disk full) with no handling. Wrap in try/except with context: 'Failed to write context to {path}: {error}'","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-10T20:10:03.523837508-08:00","created_by":"dan","updated_at":"2026-01-10T20:37:04.75187149-08:00","closed_at":"2026-01-10T20:37:04.75187149-08:00","close_reason":"Implemented consistent error handling strategy"}
|
||||
{"id":"skills-telx","title":"Add handoff skill (portable)","description":"Create a portable handoff skill that generates structured Markdown summaries for session transitions. Include SKILL.md, README.md, and scripts/handoff.sh with git context (status, branch, commits, diff stat).","status":"open","priority":2,"issue_type":"task","owner":"dan@delpad","created_at":"2026-01-20T22:26:09.526265946-08:00","created_by":"dan","updated_at":"2026-01-20T22:26:09.526265946-08:00"}
|
||||
{"id":"skills-telx","title":"Add handoff skill (portable)","description":"Create a portable handoff skill that generates structured Markdown summaries for session transitions. Include SKILL.md, README.md, and scripts/handoff.sh with git context (status, branch, commits, diff stat).","status":"closed","priority":2,"issue_type":"task","owner":"dan@delpad","created_at":"2026-01-20T22:26:09.526265946-08:00","created_by":"dan","updated_at":"2026-01-23T10:17:21.131207714-08:00","closed_at":"2026-01-23T10:17:21.131207714-08:00","close_reason":"Skill complete: SKILL.md, README.md, handoff.sh script. Fixed heredoc quoting bug."}
|
||||
{"id":"skills-thk","title":"Design: Hybrid hook + gate architecture","description":"Design enforcement that uses hooks where available, orchestrator gates elsewhere.\n\n## Hook-Capable Agents (Claude, Gemini)\n- Stop hook checks beads for review status\n- Mechanical enforcement - agent can't bypass\n\n## Non-Hook Agents (OpenCode, Codex) \n- Orchestrator pattern enforces gate\n- Orchestrator checks beads before declaring done\n- Worker can't bypass because doesn't control session\n\n## Shared Components\n- beads: persistent state (issues, review status)\n- jwz: transient state (session messages, async handoffs)\n- review-gate CLI: checks state, returns exit code\n\n## Deliverable\nArchitecture doc showing:\n1. Hook configuration for Claude/Gemini\n2. Orchestrator flow for OpenCode/Codex\n3. State schema in beads\n4. review-gate CLI design","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-09T19:01:24.270855877-08:00","created_by":"dan","updated_at":"2026-01-09T19:33:36.705975116-08:00","closed_at":"2026-01-09T19:33:36.705975116-08:00","close_reason":"Consolidated into skills-8sj"}
|
||||
{"id":"skills-tta","title":"Design: Circuit breaker patterns","description":"Design circuit breakers to prevent agent infinite loops.\n\n## Patterns to Implement\n\n### Semantic Drift Detection\n- Embed last N agent thoughts\n- If \u003e95% similar, inject \"try different approach\"\n- Use cheap embedding model\n\n### Three-Strike Tool Rule \n- Track tool call signatures (tool + args + error)\n- 3 identical failures → force strategy shift\n- Implement in PostToolUse hook\n\n### Budget-Based Interrupts\n- Allocate token budget per sub-task\n- Pause if \u003e50% budget used with \u003c30% progress\n- Request plan refinement\n\n### Time-Based Breaker\n- Timeout per task type\n- Escalate to review if exceeded\n\n## Implementation Options\n- Hook-based (Claude/Gemini)\n- Wrapper-based (all agents)\n- Orchestrator-enforced (all agents)\n\n## Deliverable\n- Circuit breaker design doc\n- Prototype implementation for one pattern","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-09T19:01:44.536499408-08:00","created_by":"dan","updated_at":"2026-01-09T19:59:37.700476328-08:00","closed_at":"2026-01-09T19:59:37.700476328-08:00","close_reason":"Covered in architecture design doc (docs/design/cross-agent-enforcement-architecture.md)"}
|
||||
{"id":"skills-ty7","title":"Define trace levels (audit vs debug)","description":"Two trace levels to manage noise vs utility:\n\n1. Audit trace (minimal, safe, always on):\n - skill id/ref, start/end\n - high-level checkpoints\n - artifact hashes/paths\n - exit status\n\n2. Debug trace (opt-in, verbose):\n - tool calls with args\n - stdout/stderr snippets\n - expanded inputs\n - timing details\n\nConsider OpenTelemetry span model as reference.\nGPT proposed this; Gemini focused on rotation/caps instead.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-23T19:49:48.514684945-05:00","updated_at":"2025-12-29T13:55:35.838961236-05:00","closed_at":"2025-12-29T13:55:35.838961236-05:00","close_reason":"Parked with ADR-001: skills-molecules integration deferred. Current simpler approach (skills as standalone) works well. Revisit when complex orchestration needed."}
|
||||
|
|
|
|||
23
skills/handoff/README.md
Normal file
23
skills/handoff/README.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# handoff
|
||||
|
||||
Generate a structured handoff summary for a new session or another agent.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
./scripts/handoff.sh --goal "Short goal description"
|
||||
./scripts/handoff.sh --goal "Short goal description" --output /tmp/handoff.md
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
The script prints a Markdown summary including:
|
||||
- Goal and next steps placeholders
|
||||
- Repo location and branch
|
||||
- Git status + diff summary
|
||||
- Recent commits
|
||||
|
||||
## Requirements
|
||||
|
||||
- `git` installed
|
||||
- Bash 4+
|
||||
45
skills/handoff/SKILL.md
Normal file
45
skills/handoff/SKILL.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
name: handoff
|
||||
description: Create a structured handoff summary for continuing work in a new session. Use when you need to pause and resume later or transfer context to another agent.
|
||||
---
|
||||
|
||||
# Handoff
|
||||
|
||||
Create a portable handoff summary that captures current state, context, and next steps for another agent or future session.
|
||||
|
||||
## When to Use
|
||||
|
||||
- "Create a handoff"
|
||||
- "Summarize this for another agent"
|
||||
- "I need to pause and resume later"
|
||||
- "Write a context handoff"
|
||||
|
||||
## Process
|
||||
|
||||
1. Run the helper script to generate a structured summary.
|
||||
2. Add or edit the **Goal**, **Open Questions**, and **Next Steps** sections.
|
||||
3. Paste the output into the new session or share with another agent.
|
||||
|
||||
## Helper Scripts
|
||||
|
||||
### handoff.sh
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
./scripts/handoff.sh --goal "Short goal description" --output /tmp/handoff.md
|
||||
```
|
||||
|
||||
**Examples**:
|
||||
```bash
|
||||
./scripts/handoff.sh --goal "Implement worker RPC launcher"
|
||||
./scripts/handoff.sh --goal "Audit web skills" --output /tmp/handoff.md
|
||||
```
|
||||
|
||||
**Notes**:
|
||||
- If `--output` is omitted, the handoff is printed to stdout.
|
||||
- Requires a git repository for full context. If not in a git repo, only basic info is included.
|
||||
|
||||
## Requirements
|
||||
|
||||
- `git` in PATH
|
||||
- Bash 4+ shell
|
||||
137
skills/handoff/scripts/handoff.sh
Executable file
137
skills/handoff/scripts/handoff.sh
Executable file
|
|
@ -0,0 +1,137 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: handoff.sh --goal "short goal" [--output /path/to/handoff.md]
|
||||
|
||||
Options:
|
||||
-g, --goal Short goal description (required)
|
||||
-o, --output Write output to file (optional; defaults to stdout)
|
||||
-h, --help Show this help
|
||||
USAGE
|
||||
}
|
||||
|
||||
GOAL=""
|
||||
OUTPUT=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-g|--goal)
|
||||
if [[ $# -lt 2 || "$2" == -* ]]; then
|
||||
echo "Error: --goal requires a value" >&2
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
GOAL="$2"
|
||||
shift 2
|
||||
;;
|
||||
-o|--output)
|
||||
if [[ $# -lt 2 || "$2" == -* ]]; then
|
||||
echo "Error: --output requires a path" >&2
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
OUTPUT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Error: unknown argument '$1'" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$GOAL" ]]; then
|
||||
echo "Error: --goal is required" >&2
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v git >/dev/null; then
|
||||
echo "Error: git is required" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
repo_root=""
|
||||
branch=""
|
||||
status=""
|
||||
diff_stat=""
|
||||
recent_commits=""
|
||||
|
||||
if git rev-parse --show-toplevel >/dev/null 2>&1; then
|
||||
repo_root=$(git rev-parse --show-toplevel)
|
||||
branch=$(git branch --show-current || true)
|
||||
status=$(git status --short --branch)
|
||||
diff_stat=$(git diff --stat)
|
||||
recent_commits=$(git log --oneline -5)
|
||||
fi
|
||||
|
||||
timestamp=$(date -Iseconds)
|
||||
|
||||
render() {
|
||||
cat <<'HEADER'
|
||||
# Handoff Summary
|
||||
|
||||
HEADER
|
||||
echo "**Goal:** $GOAL"
|
||||
echo ""
|
||||
echo "**Timestamp:** $timestamp"
|
||||
cat <<'MIDDLE'
|
||||
|
||||
## Current State
|
||||
|
||||
- [ ] Summary of what is already done
|
||||
- [ ] Notable decisions made
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [ ] Step 1
|
||||
- [ ] Step 2
|
||||
|
||||
## Open Questions
|
||||
|
||||
- [ ] Question 1
|
||||
|
||||
## Repository Context
|
||||
|
||||
MIDDLE
|
||||
echo "**Repo Root:** ${repo_root:-"(not in git repo)"}"
|
||||
echo "**Branch:** ${branch:-"(unknown)"}"
|
||||
cat <<'GITHEADER'
|
||||
|
||||
### Git Status
|
||||
|
||||
```
|
||||
GITHEADER
|
||||
echo "${status:-"(no git status available)"}"
|
||||
cat <<'DIFFHEADER'
|
||||
```
|
||||
|
||||
### Diff Summary
|
||||
|
||||
```
|
||||
DIFFHEADER
|
||||
echo "${diff_stat:-"(no changes)"}"
|
||||
cat <<'COMMITSHEADER'
|
||||
```
|
||||
|
||||
### Recent Commits
|
||||
|
||||
```
|
||||
COMMITSHEADER
|
||||
echo "${recent_commits:-"(no commits found)"}"
|
||||
echo '```'
|
||||
}
|
||||
|
||||
if [[ -n "$OUTPUT" ]]; then
|
||||
render > "$OUTPUT"
|
||||
echo "Wrote handoff to $OUTPUT"
|
||||
else
|
||||
render
|
||||
fi
|
||||
Loading…
Reference in a new issue