sdd-workspace 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #!/usr/bin/env bash
  2. # Resolve and ensure the working-tree directory SDD uses for one plan's
  3. # short-lived artifacts: task briefs, implementer reports, review packages,
  4. # and the progress ledger. Print the plan directory's absolute path.
  5. #
  6. # One directory per plan (.superpowers/sdd/<plan-basename>/) so a follow-up
  7. # plan in the same working tree can never read or overwrite another plan's
  8. # artifacts. A stale ledger misread as current progress makes controllers
  9. # skip whole task sequences — plan-scoping removes that failure structurally.
  10. #
  11. # The workspace lives in the working tree (not under .git/) because Claude Code
  12. # treats .git/ as a protected path and denies agent writes there — which blocks
  13. # an implementer subagent from writing its report file. A self-ignoring
  14. # .gitignore at .superpowers/sdd/ keeps every plan's workspace out of
  15. # `git status` and out of accidental commits without modifying any tracked file.
  16. #
  17. # Single source of truth for the workspace location, so task-brief and
  18. # review-package cannot drift to different directories.
  19. #
  20. # Usage: sdd-workspace PLAN_FILE
  21. set -euo pipefail
  22. if [ $# -ne 1 ]; then
  23. echo "usage: sdd-workspace PLAN_FILE" >&2
  24. exit 2
  25. fi
  26. plan=$1
  27. [ -f "$plan" ] || { echo "no such plan file: $plan" >&2; exit 2; }
  28. slug=$(basename "$plan" .md)
  29. [ -n "$slug" ] && [ "$slug" != "." ] && [ "$slug" != ".." ] \
  30. || { echo "cannot derive a workspace name from: $plan" >&2; exit 2; }
  31. root=$(git rev-parse --show-toplevel)
  32. base="$root/.superpowers/sdd"
  33. dir="$base/$slug"
  34. mkdir -p "$dir"
  35. printf '*\n' > "$base/.gitignore"
  36. cd "$dir" && pwd