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.
- package/README.md +131 -0
- package/SKILL.md +262 -0
- package/examples.md +202 -0
- package/extensions/planning-with-files/README.md +35 -0
- package/extensions/planning-with-files/__tests__/attestation.test.ts +79 -0
- package/extensions/planning-with-files/__tests__/plan-anchor.test.ts +228 -0
- package/extensions/planning-with-files/__tests__/runtime.test.ts +688 -0
- package/extensions/planning-with-files/attestation.ts +55 -0
- package/extensions/planning-with-files/constants.ts +31 -0
- package/extensions/planning-with-files/index.ts +6 -0
- package/extensions/planning-with-files/package.json +17 -0
- package/extensions/planning-with-files/plan.ts +263 -0
- package/extensions/planning-with-files/runtime.ts +788 -0
- package/package.json +46 -0
- package/reference.md +218 -0
- package/scripts/attest-plan.ps1 +137 -0
- package/scripts/attest-plan.sh +206 -0
- package/scripts/check-complete.ps1 +253 -0
- package/scripts/check-complete.sh +253 -0
- package/scripts/init-session.ps1 +230 -0
- package/scripts/init-session.sh +370 -0
- package/scripts/plan-doctor.sh +148 -0
- package/scripts/resolve-plan-dir.ps1 +106 -0
- package/scripts/resolve-plan-dir.sh +263 -0
- package/scripts/session-catchup.py +876 -0
- package/scripts/set-active-plan.ps1 +51 -0
- package/scripts/set-active-plan.sh +50 -0
- package/templates/analytics_findings.md +85 -0
- package/templates/analytics_task_plan.md +106 -0
- package/templates/findings.md +95 -0
- package/templates/progress.md +114 -0
- 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
|