planning-with-files 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +131 -0
  2. package/SKILL.md +262 -0
  3. package/examples.md +202 -0
  4. package/extensions/planning-with-files/README.md +35 -0
  5. package/extensions/planning-with-files/__tests__/attestation.test.ts +79 -0
  6. package/extensions/planning-with-files/__tests__/plan-anchor.test.ts +228 -0
  7. package/extensions/planning-with-files/__tests__/runtime.test.ts +688 -0
  8. package/extensions/planning-with-files/attestation.ts +55 -0
  9. package/extensions/planning-with-files/constants.ts +31 -0
  10. package/extensions/planning-with-files/index.ts +6 -0
  11. package/extensions/planning-with-files/package.json +17 -0
  12. package/extensions/planning-with-files/plan.ts +263 -0
  13. package/extensions/planning-with-files/runtime.ts +788 -0
  14. package/package.json +46 -0
  15. package/reference.md +218 -0
  16. package/scripts/attest-plan.ps1 +137 -0
  17. package/scripts/attest-plan.sh +206 -0
  18. package/scripts/check-complete.ps1 +253 -0
  19. package/scripts/check-complete.sh +253 -0
  20. package/scripts/init-session.ps1 +230 -0
  21. package/scripts/init-session.sh +370 -0
  22. package/scripts/plan-doctor.sh +148 -0
  23. package/scripts/resolve-plan-dir.ps1 +106 -0
  24. package/scripts/resolve-plan-dir.sh +263 -0
  25. package/scripts/session-catchup.py +876 -0
  26. package/scripts/set-active-plan.ps1 +51 -0
  27. package/scripts/set-active-plan.sh +50 -0
  28. package/templates/analytics_findings.md +85 -0
  29. package/templates/analytics_task_plan.md +106 -0
  30. package/templates/findings.md +95 -0
  31. package/templates/progress.md +114 -0
  32. package/templates/task_plan.md +140 -0
@@ -0,0 +1,230 @@
1
+ # Initialize planning files for a new session
2
+ # Usage: .\init-session.ps1 [-Template TYPE] [project-name]
3
+ # .\init-session.ps1 -Autonomous # v3 autonomous mode (opt-in)
4
+ # .\init-session.ps1 -Gated # v3 gated mode (opt-in, implies autonomous)
5
+ # Templates: default, analytics
6
+ #
7
+ # v3 modes (opt-in): -Autonomous / -Gated write a .mode marker next to the plan,
8
+ # reset the .stop_blocks gate counter, clear any stale gate ledger, write a fresh
9
+ # 16-hex nonce for delimiter framing, and auto-attest the plan. With NO v3 switch
10
+ # and no .mode file, behavior is byte-equivalent to v2.43.0.
11
+
12
+ param(
13
+ [string]$ProjectName = "project",
14
+ [string]$Template = "default",
15
+ [switch]$Autonomous,
16
+ [switch]$Gated
17
+ )
18
+
19
+ $DATE = Get-Date -Format "yyyy-MM-dd"
20
+
21
+ # Resolve v3 opt-in mode. -Gated implies autonomous and is the stronger marker.
22
+ $Mode = ""
23
+ if ($Gated) {
24
+ $Mode = "gated"
25
+ } elseif ($Autonomous) {
26
+ $Mode = "autonomous"
27
+ }
28
+
29
+ # Resolve template directory (skill root is one level up from scripts/)
30
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
31
+ $SkillRoot = Split-Path -Parent $ScriptDir
32
+ $TemplateDir = Join-Path $SkillRoot "templates"
33
+
34
+ function Get-Nonce {
35
+ # 16 hex chars for the plan-data delimiter framing (security strand rec 8).
36
+ $bytes = New-Object 'System.Byte[]' 8
37
+ [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
38
+ ($bytes | ForEach-Object { $_.ToString("x2") }) -join ""
39
+ }
40
+
41
+ Write-Host "Initializing planning files for: $ProjectName (template: $Template)"
42
+
43
+ # Validate template
44
+ if ($Template -ne "default" -and $Template -ne "analytics") {
45
+ Write-Host "Unknown template: $Template (available: default, analytics). Using default."
46
+ $Template = "default"
47
+ }
48
+
49
+ # Create task_plan.md if it doesn't exist
50
+ if (-not (Test-Path "task_plan.md")) {
51
+ $AnalyticsPlan = Join-Path $TemplateDir "analytics_task_plan.md"
52
+ if ($Template -eq "analytics" -and (Test-Path $AnalyticsPlan)) {
53
+ Copy-Item $AnalyticsPlan "task_plan.md"
54
+ } else {
55
+ @"
56
+ # Task Plan: [Brief Description]
57
+
58
+ ## Goal
59
+ [One sentence describing the end state]
60
+
61
+ ## Next Step
62
+ [The single next action. Update whenever phase status changes.]
63
+
64
+ ## Current Phase
65
+ Phase 1
66
+
67
+ ## Phases
68
+
69
+ ### Phase 1: Requirements & Discovery
70
+ - [ ] Understand user intent
71
+ - [ ] Identify constraints
72
+ - [ ] Document in findings.md
73
+ - **Status:** in_progress
74
+
75
+ ### Phase 2: Planning & Structure
76
+ - [ ] Define approach
77
+ - [ ] Create project structure
78
+ - **Status:** pending
79
+
80
+ ### Phase 3: Implementation
81
+ - [ ] Execute the plan
82
+ - [ ] Write to files before executing
83
+ - **Status:** pending
84
+
85
+ ### Phase 4: Testing & Verification
86
+ - [ ] Verify requirements met
87
+ - [ ] Document test results
88
+ - **Status:** pending
89
+
90
+ ### Phase 5: Delivery
91
+ - [ ] Review outputs
92
+ - [ ] Deliver to user
93
+ - **Status:** pending
94
+
95
+ ## Decisions Made
96
+ | Decision | Rationale |
97
+ |----------|-----------|
98
+
99
+ ## Errors Encountered
100
+ | Error | Resolution |
101
+ |-------|------------|
102
+ "@ | Out-File -FilePath "task_plan.md" -Encoding UTF8
103
+ }
104
+ Write-Host "Created task_plan.md"
105
+ } else {
106
+ Write-Host "task_plan.md already exists, skipping"
107
+ }
108
+
109
+ # Create findings.md if it doesn't exist
110
+ if (-not (Test-Path "findings.md")) {
111
+ $AnalyticsFindings = Join-Path $TemplateDir "analytics_findings.md"
112
+ if ($Template -eq "analytics" -and (Test-Path $AnalyticsFindings)) {
113
+ Copy-Item $AnalyticsFindings "findings.md"
114
+ } else {
115
+ @"
116
+ # Findings & Decisions
117
+
118
+ ## Requirements
119
+ -
120
+
121
+ ## Research Findings
122
+ -
123
+
124
+ ## Technical Decisions
125
+ | Decision | Rationale |
126
+ |----------|-----------|
127
+
128
+ ## Issues Encountered
129
+ | Issue | Resolution |
130
+ |-------|------------|
131
+
132
+ ## Resources
133
+ -
134
+ "@ | Out-File -FilePath "findings.md" -Encoding UTF8
135
+ }
136
+ Write-Host "Created findings.md"
137
+ } else {
138
+ Write-Host "findings.md already exists, skipping"
139
+ }
140
+
141
+ # Create progress.md if it doesn't exist
142
+ if (-not (Test-Path "progress.md")) {
143
+ if ($Template -eq "analytics") {
144
+ @"
145
+ # Progress Log
146
+
147
+ ## Session: $DATE
148
+
149
+ ### Current Status
150
+ - **Phase:** 1 - Data Discovery
151
+ - **Started:** $DATE
152
+
153
+ ### Actions Taken
154
+ -
155
+
156
+ ### Query Log
157
+ | Query | Result Summary | Interpretation |
158
+ |-------|---------------|----------------|
159
+
160
+ ### Errors
161
+ | Error | Resolution |
162
+ |-------|------------|
163
+ "@ | Out-File -FilePath "progress.md" -Encoding UTF8
164
+ } else {
165
+ @"
166
+ # Progress Log
167
+
168
+ ## Session: $DATE
169
+
170
+ ### Current Status
171
+ - **Phase:** 1 - Requirements & Discovery
172
+ - **Started:** $DATE
173
+
174
+ ### Actions Taken
175
+ -
176
+
177
+ ### Test Results
178
+ | Test | Expected | Actual | Status |
179
+ |------|----------|--------|--------|
180
+
181
+ ### Errors
182
+ | Error | Resolution |
183
+ |-------|------------|
184
+ "@ | Out-File -FilePath "progress.md" -Encoding UTF8
185
+ }
186
+ Write-Host "Created progress.md"
187
+ } else {
188
+ Write-Host "progress.md already exists, skipping"
189
+ }
190
+
191
+ Write-Host ""
192
+ Write-Host "Planning files initialized!"
193
+ Write-Host "Files: task_plan.md, findings.md, progress.md"
194
+
195
+ # v3 opt-in mode side effects. No-op when -Autonomous/-Gated were not passed, so
196
+ # the default path stays byte-equivalent to v2.43.0. PS1 init writes in CWD, so
197
+ # dotfiles live in CWD and attest-plan.ps1 falls back to the legacy
198
+ # .plan-attestation at the project root.
199
+ if ($Mode -ne "") {
200
+ $PlanDirPwf = (Get-Location).Path
201
+
202
+ # (a) reset gate block counter, drop stale gate ledger.
203
+ Set-Content -LiteralPath (Join-Path $PlanDirPwf ".stop_blocks") -Value "0" -Encoding ascii
204
+ $StaleLedger = Join-Path $PlanDirPwf ".gate_last_ledger"
205
+ if (Test-Path -LiteralPath $StaleLedger) { Remove-Item -LiteralPath $StaleLedger -Force }
206
+
207
+ # (b) fresh 16-hex nonce for delimiter framing.
208
+ Set-Content -LiteralPath (Join-Path $PlanDirPwf ".nonce") -Value (Get-Nonce) -NoNewline -Encoding ascii
209
+
210
+ # mode marker. gated implies autonomous, so it carries both tokens.
211
+ if ($Mode -eq "gated") {
212
+ $MarkerText = "autonomous gate"
213
+ } else {
214
+ $MarkerText = "autonomous"
215
+ }
216
+ Set-Content -LiteralPath (Join-Path $PlanDirPwf ".mode") -Value $MarkerText -Encoding ascii
217
+
218
+ # (c) auto-attest (attestation default-on in v3 modes, security strand rec 1).
219
+ $AttestPs1 = Join-Path $ScriptDir "attest-plan.ps1"
220
+ $PlanFilePwf = Join-Path $PlanDirPwf "task_plan.md"
221
+ if ((Test-Path -LiteralPath $AttestPs1) -and (Test-Path -LiteralPath $PlanFilePwf)) {
222
+ try {
223
+ & $AttestPs1 *> $null
224
+ } catch {
225
+ # attestation failure must not abort init; the mode marker still stands.
226
+ }
227
+ }
228
+
229
+ Write-Host "Mode: $MarkerText (attested, gate counter reset)"
230
+ }
@@ -0,0 +1,370 @@
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
+ # ./init-session.sh --autonomous "Long Run" # v3 autonomous mode (opt-in): .mode + nonce + auto-attest
11
+ # ./init-session.sh --gated "Gated Run" # v3 gated mode (opt-in, implies autonomous): adds Stop-gate marker
12
+ # ./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 so
15
+ # upgrades stay non-breaking. Slug mode addresses parallel multi-task isolation
16
+ # (issue #148) by writing each plan under .planning/<date>-<slug>/ and pinning
17
+ # .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 the
20
+ # plan, reset the .stop_blocks gate counter, clear any stale gate ledger, write
21
+ # a fresh nonce for delimiter framing, and auto-attest the plan. With NO v3 flag
22
+ # and no .mode file, behavior is byte-equivalent to v2.43.0 (no .mode, no nonce,
23
+ # no attestation change).
24
+
25
+ set -e
26
+
27
+ TEMPLATE="default"
28
+ PROJECT_NAME=""
29
+ USE_PLAN_DIR=0
30
+ MODE=""
31
+
32
+ while [ $# -gt 0 ]; do
33
+ case "$1" in
34
+ --template|-t)
35
+ TEMPLATE="$2"
36
+ shift 2
37
+ ;;
38
+ --plan-dir)
39
+ USE_PLAN_DIR=1
40
+ shift
41
+ ;;
42
+ --autonomous)
43
+ # autonomous wins only if --gated hasn't already been set (gated
44
+ # implies autonomous and is the stronger marker).
45
+ if [ "$MODE" != "gated" ]; then
46
+ MODE="autonomous"
47
+ fi
48
+ shift
49
+ ;;
50
+ --gated)
51
+ MODE="gated"
52
+ shift
53
+ ;;
54
+ *)
55
+ if [ -z "$PROJECT_NAME" ]; then
56
+ PROJECT_NAME="$1"
57
+ else
58
+ PROJECT_NAME="$PROJECT_NAME $1"
59
+ fi
60
+ shift
61
+ ;;
62
+ esac
63
+ done
64
+
65
+ DATE=$(date +%Y-%m-%d)
66
+
67
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
68
+ SKILL_ROOT="$(dirname "$SCRIPT_DIR")"
69
+ TEMPLATE_DIR="$SKILL_ROOT/templates"
70
+
71
+ if [ "$TEMPLATE" != "default" ] && [ "$TEMPLATE" != "analytics" ]; then
72
+ echo "Unknown template: $TEMPLATE (available: default, analytics). Using default."
73
+ TEMPLATE="default"
74
+ fi
75
+
76
+ # Slug mode triggers when a project name was given OR --plan-dir was passed.
77
+ SLUG_MODE=0
78
+ if [ -n "$PROJECT_NAME" ] || [ "$USE_PLAN_DIR" -eq 1 ]; then
79
+ SLUG_MODE=1
80
+ fi
81
+
82
+ slugify() {
83
+ # Lowercase, non-alphanumerics → '-', collapse repeats, trim leading/trailing '-'
84
+ printf '%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-40
88
+ }
89
+
90
+ short_uuid() {
91
+ # Probe each candidate: command -v alone is not enough on Windows because
92
+ # App Execution Aliases report presence but exit non-zero when run.
93
+ _py="${PYTHON_BIN:-}"
94
+ if [ -z "$_py" ]; then
95
+ for _c in python3 python py; do
96
+ if command -v "$_c" >/dev/null 2>&1 && "$_c" -c "import uuid" >/dev/null 2>&1; then
97
+ _py="$_c"
98
+ break
99
+ fi
100
+ done
101
+ fi
102
+ if [ -n "$_py" ]; then
103
+ "$_py" -c "import uuid; print(uuid.uuid4().hex[:8])"
104
+ return
105
+ fi
106
+ if command -v uuidgen >/dev/null 2>&1; then
107
+ uuidgen | tr '[:upper:]' '[:lower:]' | tr -d '-' | cut -c1-8
108
+ return
109
+ fi
110
+ # Last-ditch: seconds timestamp as 8 hex chars
111
+ printf '%08x' "$(date +%s)" | cut -c1-8
112
+ }
113
+
114
+ gen_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 so
117
+ # 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)" with
121
+ # 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). When
123
+ # the halves match, mix the PID into the second half so the nonce keeps 64
124
+ # bits of unpredictability on the no-uuid fallback path (Alpine/minimal).
125
+ if [ "$_n1" = "$_n2" ]; then
126
+ printf '%08x%08x' "$(date +%s)" "$$" | tr -d '\n' | cut -c1-16
127
+ else
128
+ printf '%s%s' "$_n1" "$_n2" | tr -d '\n' | cut -c1-16
129
+ fi
130
+ }
131
+
132
+ # 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).
136
+ apply_v3_mode() {
137
+ _mode_dir="$1"
138
+ _mode_plan="$2"
139
+ [ -z "$MODE" ] && return 0
140
+
141
+ # (a) reset the gate block counter and drop any stale gate ledger so a prior
142
+ # run's high block count cannot let the next run stop instantly.
143
+ printf '0\n' > "${_mode_dir}/.stop_blocks"
144
+ rm -f "${_mode_dir}/.gate_last_ledger" 2>/dev/null || true
145
+
146
+ # (b) write a fresh 16-hex nonce for delimiter framing.
147
+ gen_nonce > "${_mode_dir}/.nonce"
148
+
149
+ # write the mode marker. gated implies autonomous, so it carries both tokens.
150
+ if [ "$MODE" = "gated" ]; then
151
+ printf 'autonomous gate\n' > "${_mode_dir}/.mode"
152
+ else
153
+ printf 'autonomous\n' > "${_mode_dir}/.mode"
154
+ fi
155
+
156
+ # (c) auto-attest the plan (attestation default-on in v3 modes, security
157
+ # strand rec 1). attest-plan.sh resolves the same way init-session just
158
+ # pinned things: in slug mode PLAN_ID points at this plan dir; in legacy
159
+ # 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"
162
+ if [ -f "${_attest}" ] && [ -f "${_mode_plan}" ]; then
163
+ PLAN_ID="${PLAN_ID:-}" sh "${_attest}" >/dev/null 2>&1 || true
164
+ fi
165
+ }
166
+
167
+ write_default_task_plan() {
168
+ cat > "$1" << 'EOF'
169
+ # Task Plan: [Brief Description]
170
+
171
+ ## Goal
172
+ [One sentence describing the end state]
173
+
174
+ ## Next Step
175
+ [The single next action. Update whenever phase status changes.]
176
+
177
+ ## Current Phase
178
+ Phase 1
179
+
180
+ ## Phases
181
+
182
+ ### Phase 1: Requirements & Discovery
183
+ - [ ] Understand user intent
184
+ - [ ] Identify constraints
185
+ - [ ] Document in findings.md
186
+ - **Status:** in_progress
187
+
188
+ ### Phase 2: Planning & Structure
189
+ - [ ] Define approach
190
+ - [ ] Create project structure
191
+ - **Status:** pending
192
+
193
+ ### Phase 3: Implementation
194
+ - [ ] Execute the plan
195
+ - [ ] Write to files before executing
196
+ - **Status:** pending
197
+
198
+ ### Phase 4: Testing & Verification
199
+ - [ ] Verify requirements met
200
+ - [ ] Document test results
201
+ - **Status:** pending
202
+
203
+ ### Phase 5: Delivery
204
+ - [ ] Review outputs
205
+ - [ ] Deliver to user
206
+ - **Status:** pending
207
+
208
+ ## Decisions Made
209
+ | Decision | Rationale |
210
+ |----------|-----------|
211
+
212
+ ## Errors Encountered
213
+ | Error | Resolution |
214
+ |-------|------------|
215
+ EOF
216
+ }
217
+
218
+ write_default_findings() {
219
+ cat > "$1" << 'EOF'
220
+ # Findings & Decisions
221
+
222
+ ## Requirements
223
+ -
224
+
225
+ ## Research Findings
226
+ -
227
+
228
+ ## Technical Decisions
229
+ | Decision | Rationale |
230
+ |----------|-----------|
231
+
232
+ ## Issues Encountered
233
+ | Issue | Resolution |
234
+ |-------|------------|
235
+
236
+ ## Resources
237
+ -
238
+ EOF
239
+ }
240
+
241
+ write_default_progress() {
242
+ local date_value="$1"
243
+ local target="$2"
244
+ cat > "$target" << EOF
245
+ # Progress Log
246
+
247
+ ## Session: $date_value
248
+
249
+ ### Current Status
250
+ - **Phase:** 1 - Requirements & Discovery
251
+ - **Started:** $date_value
252
+
253
+ ### Actions Taken
254
+ -
255
+
256
+ ### Test Results
257
+ | Test | Expected | Actual | Status |
258
+ |------|----------|--------|--------|
259
+
260
+ ### Errors
261
+ | Error | Resolution |
262
+ |-------|------------|
263
+ EOF
264
+ }
265
+
266
+ write_analytics_progress() {
267
+ local date_value="$1"
268
+ local target="$2"
269
+ cat > "$target" << EOF
270
+ # Progress Log
271
+
272
+ ## Session: $date_value
273
+
274
+ ### Current Status
275
+ - **Phase:** 1 - Data Discovery
276
+ - **Started:** $date_value
277
+
278
+ ### Actions Taken
279
+ -
280
+
281
+ ### Query Log
282
+ | Query | Result Summary | Interpretation |
283
+ |-------|---------------|----------------|
284
+
285
+ ### Errors
286
+ | Error | Resolution |
287
+ |-------|------------|
288
+ EOF
289
+ }
290
+
291
+ create_files_in() {
292
+ local target_dir="$1"
293
+ local plan_path="$target_dir/task_plan.md"
294
+ local findings_path="$target_dir/findings.md"
295
+ local progress_path="$target_dir/progress.md"
296
+
297
+ if [ ! -f "$plan_path" ]; then
298
+ if [ "$TEMPLATE" = "analytics" ] && [ -f "$TEMPLATE_DIR/analytics_task_plan.md" ]; then
299
+ cp "$TEMPLATE_DIR/analytics_task_plan.md" "$plan_path"
300
+ else
301
+ write_default_task_plan "$plan_path"
302
+ fi
303
+ echo "Created $plan_path"
304
+ else
305
+ echo "$plan_path already exists, skipping"
306
+ fi
307
+
308
+ if [ ! -f "$findings_path" ]; then
309
+ if [ "$TEMPLATE" = "analytics" ] && [ -f "$TEMPLATE_DIR/analytics_findings.md" ]; then
310
+ cp "$TEMPLATE_DIR/analytics_findings.md" "$findings_path"
311
+ else
312
+ write_default_findings "$findings_path"
313
+ fi
314
+ echo "Created $findings_path"
315
+ else
316
+ echo "$findings_path already exists, skipping"
317
+ fi
318
+
319
+ if [ ! -f "$progress_path" ]; then
320
+ if [ "$TEMPLATE" = "analytics" ]; then
321
+ write_analytics_progress "$DATE" "$progress_path"
322
+ else
323
+ write_default_progress "$DATE" "$progress_path"
324
+ fi
325
+ echo "Created $progress_path"
326
+ else
327
+ echo "$progress_path already exists, skipping"
328
+ fi
329
+ }
330
+
331
+ if [ "$SLUG_MODE" -eq 1 ]; then
332
+ SLUG="$(slugify "$PROJECT_NAME")"
333
+ if [ -z "$SLUG" ]; then
334
+ SLUG="untitled-$(short_uuid)"
335
+ fi
336
+ BASE_ID="${DATE}-${SLUG}"
337
+ PLAN_ID="$BASE_ID"
338
+ PLAN_ROOT="${PWD}/.planning"
339
+ counter=2
340
+ while [ -d "${PLAN_ROOT}/${PLAN_ID}" ]; do
341
+ PLAN_ID="${BASE_ID}-${counter}"
342
+ counter=$((counter + 1))
343
+ done
344
+ PLAN_DIR="${PLAN_ROOT}/${PLAN_ID}"
345
+ mkdir -p "$PLAN_DIR"
346
+
347
+ echo "Initializing planning files for: ${PROJECT_NAME:-untitled} (template: $TEMPLATE)"
348
+ echo "PLAN_ID=$PLAN_ID"
349
+ create_files_in "$PLAN_DIR"
350
+ printf "%s\n" "$PLAN_ID" > "${PLAN_ROOT}/.active_plan"
351
+ apply_v3_mode "$PLAN_DIR" "${PLAN_DIR}/task_plan.md"
352
+ echo ""
353
+ echo "Active plan recorded: ${PLAN_ROOT}/.active_plan"
354
+ echo "Pin this terminal to the plan for parallel sessions:"
355
+ echo " export PLAN_ID=$PLAN_ID"
356
+ if [ -n "$MODE" ]; then
357
+ echo "Mode: $(cat "${PLAN_DIR}/.mode") (attested, gate counter reset)"
358
+ fi
359
+ else
360
+ PROJECT_NAME="${PROJECT_NAME:-project}"
361
+ echo "Initializing planning files for: $PROJECT_NAME (template: $TEMPLATE)"
362
+ create_files_in "$(pwd)"
363
+ apply_v3_mode "$(pwd)" "$(pwd)/task_plan.md"
364
+ echo ""
365
+ echo "Planning files initialized!"
366
+ echo "Files: task_plan.md, findings.md, progress.md"
367
+ if [ -n "$MODE" ]; then
368
+ echo "Mode: $(cat "$(pwd)/.mode") (attested, gate counter reset)"
369
+ fi
370
+ fi