Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Structured planning workflow that uses files to track tasks, decisions, and project progress.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/init-session.sh
1#!/usr/bin/env bash2# Initialize planning files for a new session.3#4# Usage:5# ./init-session.sh # legacy: root-level task_plan.md, findings.md, progress.md6# ./init-session.sh [--template TYPE] # legacy with template choice7# ./init-session.sh "Backend Refactor" # slug mode: .planning/<date>-backend-refactor/8# ./init-session.sh --plan-dir # slug mode with auto-generated untitled-<short> name9# ./init-session.sh --plan-dir "Quick Spike" # slug mode, explicit slug10# ./init-session.sh --autonomous "Long Run" # v3 autonomous mode (opt-in): .mode + nonce + auto-attest11# ./init-session.sh --gated "Gated Run" # v3 gated mode (opt-in, implies autonomous): adds Stop-gate marker12# ./init-session.sh --autonomous # v3 flags also work in legacy root mode (dotfiles at root)13#14# Legacy mode (zero positional args, no --plan-dir) preserves v1.x behavior so15# upgrades stay non-breaking. Slug mode addresses parallel multi-task isolation16# (issue #148) by writing each plan under .planning/<date>-<slug>/ and pinning17# .planning/.active_plan so resolve-plan-dir.sh can find it.18#19# v3 modes (opt-in): --autonomous / --gated write a .mode marker next to the20# plan, reset the .stop_blocks gate counter, clear any stale gate ledger, write21# a fresh nonce for delimiter framing, and auto-attest the plan. With NO v3 flag22# and no .mode file, behavior is byte-equivalent to v2.43.0 (no .mode, no nonce,23# no attestation change).2425set -e2627TEMPLATE="default"28PROJECT_NAME=""29USE_PLAN_DIR=030MODE=""3132while [ $# -gt 0 ]; do33case "$1" in34--template|-t)35TEMPLATE="$2"36shift 237;;38--plan-dir)39USE_PLAN_DIR=140shift41;;42--autonomous)43# autonomous wins only if --gated hasn't already been set (gated44# implies autonomous and is the stronger marker).45if [ "$MODE" != "gated" ]; then46MODE="autonomous"47fi48shift49;;50--gated)51MODE="gated"52shift53;;54*)55if [ -z "$PROJECT_NAME" ]; then56PROJECT_NAME="$1"57else58PROJECT_NAME="$PROJECT_NAME $1"59fi60shift61;;62esac63done6465DATE=$(date +%Y-%m-%d)6667SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"68SKILL_ROOT="$(dirname "$SCRIPT_DIR")"69TEMPLATE_DIR="$SKILL_ROOT/templates"7071if [ "$TEMPLATE" != "default" ] && [ "$TEMPLATE" != "analytics" ]; then72echo "Unknown template: $TEMPLATE (available: default, analytics). Using default."73TEMPLATE="default"74fi7576# Slug mode triggers when a project name was given OR --plan-dir was passed.77SLUG_MODE=078if [ -n "$PROJECT_NAME" ] || [ "$USE_PLAN_DIR" -eq 1 ]; then79SLUG_MODE=180fi8182slugify() {83# Lowercase, non-alphanumerics → '-', collapse repeats, trim leading/trailing '-'84printf '%s' "$1" \85| tr '[:upper:]' '[:lower:]' \86| sed -e 's/[^a-z0-9]/-/g' -e 's/-\{2,\}/-/g' -e 's/^-//' -e 's/-$//' \87| cut -c1-4088}8990short_uuid() {91# Probe each candidate: command -v alone is not enough on Windows because92# App Execution Aliases report presence but exit non-zero when run.93_py="${PYTHON_BIN:-}"94if [ -z "$_py" ]; then95for _c in python3 python py; do96if command -v "$_c" >/dev/null 2>&1 && "$_c" -c "import uuid" >/dev/null 2>&1; then97_py="$_c"98break99fi100done101fi102if [ -n "$_py" ]; then103"$_py" -c "import uuid; print(uuid.uuid4().hex[:8])"104return105fi106if command -v uuidgen >/dev/null 2>&1; then107uuidgen | tr '[:upper:]' '[:lower:]' | tr -d '-' | cut -c1-8108return109fi110# Last-ditch: seconds timestamp as 8 hex chars111printf '%08x' "$(date +%s)" | cut -c1-8112}113114gen_nonce() {115# 16 hex chars for the plan-data delimiter framing (security strand rec 8).116# short_uuid() yields 8 hex chars; concatenate two draws and clip to 16 so117# the result stays exactly 16 even if a fallback path over-produces.118_n1="$(short_uuid)"119_n2="$(short_uuid)"120# short_uuid's third-level fallback is printf '%08x' "$(date +%s)" with121# 1-second resolution: two draws in the same second return the SAME 8 hex,122# collapsing the nonce to the epoch value doubled (32 bits, not 64). When123# the halves match, mix the PID into the second half so the nonce keeps 64124# bits of unpredictability on the no-uuid fallback path (Alpine/minimal).125if [ "$_n1" = "$_n2" ]; then126printf '%08x%08x' "$(date +%s)" "$$" | tr -d '\n' | cut -c1-16127else128printf '%s%s' "$_n1" "$_n2" | tr -d '\n' | cut -c1-16129fi130}131132# Apply v3 opt-in mode side effects to a plan directory.133# $1 = plan dir (absolute or relative); dotfiles live directly inside it.134# $2 = plan file path (task_plan.md) used for auto-attestation resolution.135# No-op when MODE is empty (legacy path stays byte-equivalent to v2.43.0).136apply_v3_mode() {137_mode_dir="$1"138_mode_plan="$2"139[ -z "$MODE" ] && return 0140141# (a) reset the gate block counter and drop any stale gate ledger so a prior142# run's high block count cannot let the next run stop instantly.143printf '0\n' > "${_mode_dir}/.stop_blocks"144rm -f "${_mode_dir}/.gate_last_ledger" 2>/dev/null || true145146# (b) write a fresh 16-hex nonce for delimiter framing.147gen_nonce > "${_mode_dir}/.nonce"148149# write the mode marker. gated implies autonomous, so it carries both tokens.150if [ "$MODE" = "gated" ]; then151printf 'autonomous gate\n' > "${_mode_dir}/.mode"152else153printf 'autonomous\n' > "${_mode_dir}/.mode"154fi155156# (c) auto-attest the plan (attestation default-on in v3 modes, security157# strand rec 1). attest-plan.sh resolves the same way init-session just158# pinned things: in slug mode PLAN_ID points at this plan dir; in legacy159# mode it is empty and the script falls back to ./task_plan.md at root.160# Run from the project root (CWD here) so both resolutions land.161_attest="${SCRIPT_DIR}/attest-plan.sh"162if [ -f "${_attest}" ] && [ -f "${_mode_plan}" ]; then163PLAN_ID="${PLAN_ID:-}" sh "${_attest}" >/dev/null 2>&1 || true164fi165}166167write_default_task_plan() {168cat > "$1" << 'EOF'169# Task Plan: [Brief Description]170171## Goal172[One sentence describing the end state]173174## Current Phase175Phase 1176177## Phases178179### Phase 1: Requirements & Discovery180- [ ] Understand user intent181- [ ] Identify constraints182- [ ] Document in findings.md183- **Status:** in_progress184185### Phase 2: Planning & Structure186- [ ] Define approach187- [ ] Create project structure188- **Status:** pending189190### Phase 3: Implementation191- [ ] Execute the plan192- [ ] Write to files before executing193- **Status:** pending194195### Phase 4: Testing & Verification196- [ ] Verify requirements met197- [ ] Document test results198- **Status:** pending199200### Phase 5: Delivery201- [ ] Review outputs202- [ ] Deliver to user203- **Status:** pending204205## Decisions Made206| Decision | Rationale |207|----------|-----------|208209## Errors Encountered210| Error | Resolution |211|-------|------------|212EOF213}214215write_default_findings() {216cat > "$1" << 'EOF'217# Findings & Decisions218219## Requirements220-221222## Research Findings223-224225## Technical Decisions226| Decision | Rationale |227|----------|-----------|228229## Issues Encountered230| Issue | Resolution |231|-------|------------|232233## Resources234-235EOF236}237238write_default_progress() {239local date_value="$1"240local target="$2"241cat > "$target" << EOF242# Progress Log243244## Session: $date_value245246### Current Status247- **Phase:** 1 - Requirements & Discovery248- **Started:** $date_value249250### Actions Taken251-252253### Test Results254| Test | Expected | Actual | Status |255|------|----------|--------|--------|256257### Errors258| Error | Resolution |259|-------|------------|260EOF261}262263write_analytics_progress() {264local date_value="$1"265local target="$2"266cat > "$target" << EOF267# Progress Log268269## Session: $date_value270271### Current Status272- **Phase:** 1 - Data Discovery273- **Started:** $date_value274275### Actions Taken276-277278### Query Log279| Query | Result Summary | Interpretation |280|-------|---------------|----------------|281282### Errors283| Error | Resolution |284|-------|------------|285EOF286}287288create_files_in() {289local target_dir="$1"290local plan_path="$target_dir/task_plan.md"291local findings_path="$target_dir/findings.md"292local progress_path="$target_dir/progress.md"293294if [ ! -f "$plan_path" ]; then295if [ "$TEMPLATE" = "analytics" ] && [ -f "$TEMPLATE_DIR/analytics_task_plan.md" ]; then296cp "$TEMPLATE_DIR/analytics_task_plan.md" "$plan_path"297else298write_default_task_plan "$plan_path"299fi300echo "Created $plan_path"301else302echo "$plan_path already exists, skipping"303fi304305if [ ! -f "$findings_path" ]; then306if [ "$TEMPLATE" = "analytics" ] && [ -f "$TEMPLATE_DIR/analytics_findings.md" ]; then307cp "$TEMPLATE_DIR/analytics_findings.md" "$findings_path"308else309write_default_findings "$findings_path"310fi311echo "Created $findings_path"312else313echo "$findings_path already exists, skipping"314fi315316if [ ! -f "$progress_path" ]; then317if [ "$TEMPLATE" = "analytics" ]; then318write_analytics_progress "$DATE" "$progress_path"319else320write_default_progress "$DATE" "$progress_path"321fi322echo "Created $progress_path"323else324echo "$progress_path already exists, skipping"325fi326}327328if [ "$SLUG_MODE" -eq 1 ]; then329SLUG="$(slugify "$PROJECT_NAME")"330if [ -z "$SLUG" ]; then331SLUG="untitled-$(short_uuid)"332fi333BASE_ID="${DATE}-${SLUG}"334PLAN_ID="$BASE_ID"335PLAN_ROOT="${PWD}/.planning"336counter=2337while [ -d "${PLAN_ROOT}/${PLAN_ID}" ]; do338PLAN_ID="${BASE_ID}-${counter}"339counter=$((counter + 1))340done341PLAN_DIR="${PLAN_ROOT}/${PLAN_ID}"342mkdir -p "$PLAN_DIR"343344echo "Initializing planning files for: ${PROJECT_NAME:-untitled} (template: $TEMPLATE)"345echo "PLAN_ID=$PLAN_ID"346create_files_in "$PLAN_DIR"347printf "%s\n" "$PLAN_ID" > "${PLAN_ROOT}/.active_plan"348apply_v3_mode "$PLAN_DIR" "${PLAN_DIR}/task_plan.md"349echo ""350echo "Active plan recorded: ${PLAN_ROOT}/.active_plan"351echo "Pin this terminal to the plan for parallel sessions:"352echo " export PLAN_ID=$PLAN_ID"353if [ -n "$MODE" ]; then354echo "Mode: $(cat "${PLAN_DIR}/.mode") (attested, gate counter reset)"355fi356else357PROJECT_NAME="${PROJECT_NAME:-project}"358echo "Initializing planning files for: $PROJECT_NAME (template: $TEMPLATE)"359create_files_in "$(pwd)"360apply_v3_mode "$(pwd)" "$(pwd)/task_plan.md"361echo ""362echo "Planning files initialized!"363echo "Files: task_plan.md, findings.md, progress.md"364if [ -n "$MODE" ]; then365echo "Mode: $(cat "$(pwd)/.mode") (attested, gate counter reset)"366fi367fi368