init-session.sh 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #!/usr/bin/env bash
  2. # Initialize planning files for a new session.
  3. #
  4. # Usage:
  5. # ./init-session.sh # legacy: root-level task_plan.md, findings.md, progress.md
  6. # ./init-session.sh [--template TYPE] # legacy with template choice
  7. # ./init-session.sh "Backend Refactor" # slug mode: .planning/<date>-backend-refactor/
  8. # ./init-session.sh --plan-dir # slug mode with auto-generated untitled-<short> name
  9. # ./init-session.sh --plan-dir "Quick Spike" # slug mode, explicit slug
  10. #
  11. # Legacy mode (zero positional args, no --plan-dir) preserves v1.x behavior so
  12. # upgrades stay non-breaking. Slug mode addresses parallel multi-task isolation
  13. # (issue #148) by writing each plan under .planning/<date>-<slug>/ and pinning
  14. # .planning/.active_plan so resolve-plan-dir.sh can find it.
  15. set -e
  16. TEMPLATE="default"
  17. PROJECT_NAME=""
  18. USE_PLAN_DIR=0
  19. while [[ $# -gt 0 ]]; do
  20. case "$1" in
  21. --template|-t)
  22. TEMPLATE="$2"
  23. shift 2
  24. ;;
  25. --plan-dir)
  26. USE_PLAN_DIR=1
  27. shift
  28. ;;
  29. *)
  30. if [ -z "$PROJECT_NAME" ]; then
  31. PROJECT_NAME="$1"
  32. else
  33. PROJECT_NAME="$PROJECT_NAME $1"
  34. fi
  35. shift
  36. ;;
  37. esac
  38. done
  39. DATE=$(date +%Y-%m-%d)
  40. SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
  41. SKILL_ROOT="$(dirname "$SCRIPT_DIR")"
  42. TEMPLATE_DIR="$SKILL_ROOT/templates"
  43. if [ "$TEMPLATE" != "default" ] && [ "$TEMPLATE" != "analytics" ]; then
  44. echo "Unknown template: $TEMPLATE (available: default, analytics). Using default."
  45. TEMPLATE="default"
  46. fi
  47. # Slug mode triggers when a project name was given OR --plan-dir was passed.
  48. SLUG_MODE=0
  49. if [ -n "$PROJECT_NAME" ] || [ "$USE_PLAN_DIR" -eq 1 ]; then
  50. SLUG_MODE=1
  51. fi
  52. slugify() {
  53. # Lowercase, non-alphanumerics → '-', collapse repeats, trim leading/trailing '-'
  54. printf '%s' "$1" \
  55. | tr '[:upper:]' '[:lower:]' \
  56. | sed -e 's/[^a-z0-9]/-/g' -e 's/-\{2,\}/-/g' -e 's/^-//' -e 's/-$//' \
  57. | cut -c1-40
  58. }
  59. short_uuid() {
  60. # Probe each candidate: command -v alone is not enough on Windows because
  61. # App Execution Aliases report presence but exit non-zero when run.
  62. _py="${PYTHON_BIN:-}"
  63. if [ -z "$_py" ]; then
  64. for _c in python3 python py; do
  65. if command -v "$_c" >/dev/null 2>&1 && "$_c" -c "import uuid" >/dev/null 2>&1; then
  66. _py="$_c"
  67. break
  68. fi
  69. done
  70. fi
  71. if [ -n "$_py" ]; then
  72. "$_py" -c "import uuid; print(uuid.uuid4().hex[:8])"
  73. return
  74. fi
  75. if command -v uuidgen >/dev/null 2>&1; then
  76. uuidgen | tr '[:upper:]' '[:lower:]' | tr -d '-' | cut -c1-8
  77. return
  78. fi
  79. # Last-ditch: seconds timestamp as 8 hex chars
  80. printf '%08x' "$(date +%s)" | cut -c1-8
  81. }
  82. write_default_task_plan() {
  83. cat > "$1" << 'EOF'
  84. # Task Plan: [Brief Description]
  85. ## Goal
  86. [One sentence describing the end state]
  87. ## Current Phase
  88. Phase 1
  89. ## Phases
  90. ### Phase 1: Requirements & Discovery
  91. - [ ] Understand user intent
  92. - [ ] Identify constraints
  93. - [ ] Document in findings.md
  94. - **Status:** in_progress
  95. ### Phase 2: Planning & Structure
  96. - [ ] Define approach
  97. - [ ] Create project structure
  98. - **Status:** pending
  99. ### Phase 3: Implementation
  100. - [ ] Execute the plan
  101. - [ ] Write to files before executing
  102. - **Status:** pending
  103. ### Phase 4: Testing & Verification
  104. - [ ] Verify requirements met
  105. - [ ] Document test results
  106. - **Status:** pending
  107. ### Phase 5: Delivery
  108. - [ ] Review outputs
  109. - [ ] Deliver to user
  110. - **Status:** pending
  111. ## Decisions Made
  112. | Decision | Rationale |
  113. |----------|-----------|
  114. ## Errors Encountered
  115. | Error | Resolution |
  116. |-------|------------|
  117. EOF
  118. }
  119. write_default_findings() {
  120. cat > "$1" << 'EOF'
  121. # Findings & Decisions
  122. ## Requirements
  123. -
  124. ## Research Findings
  125. -
  126. ## Technical Decisions
  127. | Decision | Rationale |
  128. |----------|-----------|
  129. ## Issues Encountered
  130. | Issue | Resolution |
  131. |-------|------------|
  132. ## Resources
  133. -
  134. EOF
  135. }
  136. write_default_progress() {
  137. local date_value="$1"
  138. local target="$2"
  139. cat > "$target" << EOF
  140. # Progress Log
  141. ## Session: $date_value
  142. ### Current Status
  143. - **Phase:** 1 - Requirements & Discovery
  144. - **Started:** $date_value
  145. ### Actions Taken
  146. -
  147. ### Test Results
  148. | Test | Expected | Actual | Status |
  149. |------|----------|--------|--------|
  150. ### Errors
  151. | Error | Resolution |
  152. |-------|------------|
  153. EOF
  154. }
  155. write_analytics_progress() {
  156. local date_value="$1"
  157. local target="$2"
  158. cat > "$target" << EOF
  159. # Progress Log
  160. ## Session: $date_value
  161. ### Current Status
  162. - **Phase:** 1 - Data Discovery
  163. - **Started:** $date_value
  164. ### Actions Taken
  165. -
  166. ### Query Log
  167. | Query | Result Summary | Interpretation |
  168. |-------|---------------|----------------|
  169. ### Errors
  170. | Error | Resolution |
  171. |-------|------------|
  172. EOF
  173. }
  174. create_files_in() {
  175. local target_dir="$1"
  176. local plan_path="$target_dir/task_plan.md"
  177. local findings_path="$target_dir/findings.md"
  178. local progress_path="$target_dir/progress.md"
  179. if [ ! -f "$plan_path" ]; then
  180. if [ "$TEMPLATE" = "analytics" ] && [ -f "$TEMPLATE_DIR/analytics_task_plan.md" ]; then
  181. cp "$TEMPLATE_DIR/analytics_task_plan.md" "$plan_path"
  182. else
  183. write_default_task_plan "$plan_path"
  184. fi
  185. echo "Created $plan_path"
  186. else
  187. echo "$plan_path already exists, skipping"
  188. fi
  189. if [ ! -f "$findings_path" ]; then
  190. if [ "$TEMPLATE" = "analytics" ] && [ -f "$TEMPLATE_DIR/analytics_findings.md" ]; then
  191. cp "$TEMPLATE_DIR/analytics_findings.md" "$findings_path"
  192. else
  193. write_default_findings "$findings_path"
  194. fi
  195. echo "Created $findings_path"
  196. else
  197. echo "$findings_path already exists, skipping"
  198. fi
  199. if [ ! -f "$progress_path" ]; then
  200. if [ "$TEMPLATE" = "analytics" ]; then
  201. write_analytics_progress "$DATE" "$progress_path"
  202. else
  203. write_default_progress "$DATE" "$progress_path"
  204. fi
  205. echo "Created $progress_path"
  206. else
  207. echo "$progress_path already exists, skipping"
  208. fi
  209. }
  210. if [ "$SLUG_MODE" -eq 1 ]; then
  211. SLUG="$(slugify "$PROJECT_NAME")"
  212. if [ -z "$SLUG" ]; then
  213. SLUG="untitled-$(short_uuid)"
  214. fi
  215. BASE_ID="${DATE}-${SLUG}"
  216. PLAN_ID="$BASE_ID"
  217. PLAN_ROOT="${PWD}/.planning"
  218. counter=2
  219. while [ -d "${PLAN_ROOT}/${PLAN_ID}" ]; do
  220. PLAN_ID="${BASE_ID}-${counter}"
  221. counter=$((counter + 1))
  222. done
  223. PLAN_DIR="${PLAN_ROOT}/${PLAN_ID}"
  224. mkdir -p "$PLAN_DIR"
  225. echo "Initializing planning files for: ${PROJECT_NAME:-untitled} (template: $TEMPLATE)"
  226. echo "PLAN_ID=$PLAN_ID"
  227. create_files_in "$PLAN_DIR"
  228. printf "%s\n" "$PLAN_ID" > "${PLAN_ROOT}/.active_plan"
  229. echo ""
  230. echo "Active plan recorded: ${PLAN_ROOT}/.active_plan"
  231. echo "Pin this terminal to the plan for parallel sessions:"
  232. echo " export PLAN_ID=$PLAN_ID"
  233. else
  234. PROJECT_NAME="${PROJECT_NAME:-project}"
  235. echo "Initializing planning files for: $PROJECT_NAME (template: $TEMPLATE)"
  236. create_files_in "$(pwd)"
  237. echo ""
  238. echo "Planning files initialized!"
  239. echo "Files: task_plan.md, findings.md, progress.md"
  240. fi