prjct-cli 0.12.2 → 0.13.1

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 (40) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/CLAUDE.md +18 -6
  3. package/core/data/index.ts +19 -5
  4. package/core/data/md-base-manager.ts +203 -0
  5. package/core/data/md-queue-manager.ts +179 -0
  6. package/core/data/md-state-manager.ts +133 -0
  7. package/core/serializers/index.ts +20 -0
  8. package/core/serializers/queue-serializer.ts +210 -0
  9. package/core/serializers/state-serializer.ts +136 -0
  10. package/core/utils/file-helper.ts +12 -0
  11. package/package.json +1 -1
  12. package/packages/web/app/api/projects/[id]/stats/route.ts +6 -29
  13. package/packages/web/app/page.tsx +1 -6
  14. package/packages/web/app/project/[id]/page.tsx +34 -1
  15. package/packages/web/app/project/[id]/stats/page.tsx +11 -5
  16. package/packages/web/app/settings/page.tsx +2 -221
  17. package/packages/web/components/BlockersCard/BlockersCard.tsx +67 -0
  18. package/packages/web/components/BlockersCard/BlockersCard.types.ts +11 -0
  19. package/packages/web/components/BlockersCard/index.ts +2 -0
  20. package/packages/web/components/CommandButton/CommandButton.tsx +10 -3
  21. package/packages/web/lib/projects.ts +28 -27
  22. package/packages/web/lib/services/projects.server.ts +25 -21
  23. package/packages/web/lib/services/stats.server.ts +355 -57
  24. package/packages/web/next-env.d.ts +1 -1
  25. package/packages/web/package.json +0 -4
  26. package/templates/commands/decision.md +226 -0
  27. package/templates/commands/done.md +100 -68
  28. package/templates/commands/feature.md +102 -103
  29. package/templates/commands/idea.md +41 -38
  30. package/templates/commands/now.md +94 -33
  31. package/templates/commands/pause.md +90 -30
  32. package/templates/commands/ship.md +179 -74
  33. package/templates/commands/sync.md +324 -200
  34. package/packages/web/app/api/migrate/route.ts +0 -46
  35. package/packages/web/app/api/settings/route.ts +0 -97
  36. package/packages/web/app/api/v2/projects/[id]/unified/route.ts +0 -57
  37. package/packages/web/components/MigrationGate/MigrationGate.tsx +0 -304
  38. package/packages/web/components/MigrationGate/index.ts +0 -1
  39. package/packages/web/lib/json-loader.ts +0 -630
  40. package/packages/web/lib/services/migration.server.ts +0 -580
@@ -1,17 +1,43 @@
1
1
  ---
2
2
  allowed-tools: [Read, Write, Bash]
3
- description: 'Pause current session'
3
+ description: 'Pause current session with reason'
4
4
  timestamp-rule: 'GetTimestamp() for all timestamps'
5
+ architecture: 'MD-first - MD files are source of truth'
5
6
  ---
6
7
 
7
8
  # /p:pause - Pause Current Session
8
9
 
10
+ ## Architecture: MD-First
11
+
12
+ **Source of Truth**: `core/now.md`, `sessions/current.json`
13
+
9
14
  ## Context Variables
10
15
  - `{projectId}`: From `.prjct/prjct.config.json`
11
16
  - `{globalPath}`: `~/.prjct-cli/projects/{projectId}`
12
17
  - `{sessionPath}`: `{globalPath}/sessions/current.json`
13
18
  - `{nowPath}`: `{globalPath}/core/now.md`
14
19
  - `{memoryPath}`: `{globalPath}/memory/context.jsonl`
20
+ - `{reason}`: User-provided reason (optional)
21
+
22
+ ## Pause Reasons
23
+
24
+ When pausing, capture WHY to enable blocker tracking:
25
+
26
+ | Reason | Meaning | Dashboard Impact |
27
+ |--------|---------|------------------|
28
+ | `blocked` | Waiting on external dependency | Shows in Blockers list |
29
+ | `switch` | Switching to higher priority task | Context switch metric |
30
+ | `break` | Taking a break | Normal pause |
31
+ | `research` | Need to investigate more | Research time tracked |
32
+
33
+ If no reason provided, ask:
34
+ ```
35
+ Why are you pausing?
36
+ 1. blocked - Waiting on something external
37
+ 2. switch - Starting a different task
38
+ 3. break - Taking a break
39
+ 4. research - Need to investigate
40
+ ```
15
41
 
16
42
  ## Step 1: Read Config
17
43
 
@@ -40,6 +66,7 @@ IF {session.status} == "paused":
40
66
 
41
67
  Paused: {elapsed} ago
42
68
  Duration so far: {session.duration}
69
+ Reason: {session.pauseReason}
43
70
 
44
71
  /p:resume to continue | /p:done to complete
45
72
  ```
@@ -49,7 +76,17 @@ IF {session.status} != "active":
49
76
  OUTPUT: "⚠️ No active session to pause."
50
77
  STOP
51
78
 
52
- ## Step 3: Calculate Duration So Far
79
+ ## Step 3: Get Pause Reason
80
+
81
+ IF {reason} not provided:
82
+ ASK user to select reason (blocked, switch, break, research)
83
+ OR auto-detect "break" as default
84
+
85
+ IF {reason} == "blocked":
86
+ ASK for blocker note: "What's blocking you?"
87
+ SET: {blockerNote} = user response
88
+
89
+ ## Step 4: Calculate Duration So Far
53
90
 
54
91
  SET: {now} = GetTimestamp()
55
92
 
@@ -60,7 +97,7 @@ For each event in {session.timeline}:
60
97
  SET: {duration} = total active seconds
61
98
  SET: {durationFormatted} = format as "Xh Ym" or "Xm"
62
99
 
63
- ## Step 4: Update Session
100
+ ## Step 5: Update Session
64
101
 
65
102
  UPDATE {session}:
66
103
  ```json
@@ -71,12 +108,14 @@ UPDATE {session}:
71
108
  "status": "paused",
72
109
  "startedAt": "{session.startedAt}",
73
110
  "pausedAt": "{now}",
111
+ "pauseReason": "{reason}",
112
+ "pauseNote": "{blockerNote}",
74
113
  "completedAt": null,
75
114
  "duration": {duration},
76
115
  "metrics": {session.metrics},
77
116
  "timeline": [
78
117
  ...{session.timeline},
79
- {"type": "pause", "at": "{now}"}
118
+ {"type": "pause", "at": "{now}", "reason": "{reason}", "note": "{blockerNote}"}
80
119
  ]
81
120
  }
82
121
  ```
@@ -84,7 +123,7 @@ UPDATE {session}:
84
123
  WRITE: `{sessionPath}`
85
124
  Content: Updated session JSON
86
125
 
87
- ## Step 5: Update Legacy now.md
126
+ ## Step 6: Update now.md (SOURCE OF TRUTH)
88
127
 
89
128
  WRITE: `{nowPath}`
90
129
  Content:
@@ -96,16 +135,18 @@ Content:
96
135
  Started: {session.startedAt}
97
136
  Paused: {now}
98
137
  Duration: {durationFormatted}
138
+ Reason: {reason}
99
139
  Session: {session.id}
140
+ {IF blockerNote: Note: {blockerNote}}
100
141
  ```
101
142
 
102
- ## Step 6: Log to Memory
143
+ ## Step 7: Log to Memory
103
144
 
104
145
  APPEND to: `{memoryPath}`
105
146
 
106
147
  Single line (JSONL):
107
148
  ```json
108
- {"timestamp":"{now}","action":"session_paused","sessionId":"{session.id}","task":"{session.task}","duration":{duration}}
149
+ {"timestamp":"{now}","action":"session_paused","sessionId":"{session.id}","task":"{session.task}","duration":{duration},"reason":"{reason}","note":"{blockerNote}"}
109
150
  ```
110
151
 
111
152
  ## Output
@@ -116,6 +157,8 @@ SUCCESS:
116
157
 
117
158
  Session: {session.id}
118
159
  Active time: {durationFormatted}
160
+ Reason: {reason}
161
+ {IF blockerNote: Note: {blockerNote}}
119
162
 
120
163
  Next:
121
164
  • /p:resume - Continue this task
@@ -134,22 +177,27 @@ Next:
134
177
 
135
178
  ## Examples
136
179
 
137
- ### Example 1: Pause Active Session
138
- **Session:**
139
- ```json
140
- {
141
- "id": "sess_abc12345",
142
- "task": "implement auth",
143
- "status": "active",
144
- "startedAt": "2025-12-07T10:00:00.000Z",
145
- "timeline": [
146
- {"type": "start", "at": "2025-12-07T10:00:00.000Z"}
147
- ]
148
- }
180
+ ### Example 1: Pause with Blocked Reason
181
+ **Input:** `/p:pause blocked`
182
+ **Prompt:** "What's blocking you?"
183
+ **User:** "Waiting for API credentials from vendor"
184
+
185
+ **Output:**
149
186
  ```
187
+ ⏸️ Paused: implement auth
150
188
 
151
- **Current time:** 12:30 PM
152
- **Duration:** 2h 30m
189
+ Session: sess_abc12345
190
+ Active time: 2h 30m
191
+ Reason: blocked
192
+ Note: Waiting for API credentials from vendor
193
+
194
+ Next:
195
+ • /p:resume - Continue this task
196
+ • /p:now <task> - Start different task
197
+ ```
198
+
199
+ ### Example 2: Quick Break
200
+ **Input:** `/p:pause break`
153
201
 
154
202
  **Output:**
155
203
  ```
@@ -157,26 +205,38 @@ Next:
157
205
 
158
206
  Session: sess_abc12345
159
207
  Active time: 2h 30m
208
+ Reason: break
160
209
 
161
210
  Next:
162
211
  • /p:resume - Continue this task
163
- • /p:now <task> - Start different task
164
- • /p:done - Complete without resuming
165
212
  ```
166
213
 
167
- ### Example 2: Already Paused
214
+ ### Example 3: Context Switch
215
+ **Input:** `/p:pause switch`
216
+
168
217
  **Output:**
169
218
  ```
170
- ⏸️ Already paused: implement auth
219
+ ⏸️ Paused: implement auth
171
220
 
172
- Paused: 15m ago
173
- Duration so far: 2h 30m
221
+ Session: sess_abc12345
222
+ Active time: 2h 30m
223
+ Reason: switch
174
224
 
175
- /p:resume to continue | /p:done to complete
225
+ Next:
226
+ • /p:now <task> - Start the urgent task
176
227
  ```
177
228
 
178
- ### Example 3: No Active Session
229
+ ### Example 4: No Reason (Interactive)
230
+ **Input:** `/p:pause`
231
+
179
232
  **Output:**
180
233
  ```
181
- ⚠️ No active session to pause. Use /p:now to start one.
234
+ Why are you pausing?
235
+
236
+ 1. blocked - Waiting on something external
237
+ 2. switch - Starting a different task
238
+ 3. break - Taking a break
239
+ 4. research - Need to investigate
240
+
241
+ Select [1-4]:
182
242
  ```
@@ -2,25 +2,46 @@
2
2
  allowed-tools: [Read, Write, Bash]
3
3
  description: 'Ship feature with automated workflow'
4
4
  timestamp-rule: 'GetTimestamp() and GetDate() for ALL timestamps'
5
- architecture: 'JSON-first - Write to data/*.json, views are generated'
5
+ architecture: 'MD-first - MD files are source of truth'
6
6
  ---
7
7
 
8
8
  # /p:ship - Ship Feature Workflow
9
9
 
10
- ## Architecture: JSON-First
10
+ ## Architecture: MD-First
11
11
 
12
- **Source of Truth**: `data/shipped.json`, `data/roadmap.json`
13
- **Generated Views**: `views/shipped.md`, `views/roadmap.md` (auto-generated)
12
+ **Source of Truth**: `progress/shipped.md`, `planning/roadmap.md`
13
+
14
+ MD files are the source of truth. Write directly to MD files.
14
15
 
15
16
  ## Context Variables
16
17
  - `{projectId}`: From `.prjct/prjct.config.json`
17
18
  - `{globalPath}`: `~/.prjct-cli/projects/{projectId}`
18
- - `{dataPath}`: `{globalPath}/data`
19
- - `{shippedPath}`: `{dataPath}/shipped.json`
20
- - `{roadmapPath}`: `{dataPath}/roadmap.json`
19
+ - `{shippedPath}`: `{globalPath}/progress/shipped.md`
20
+ - `{roadmapPath}`: `{globalPath}/planning/roadmap.md`
21
21
  - `{memoryPath}`: `{globalPath}/memory/context.jsonl`
22
22
  - `{snapshotDir}`: `{globalPath}/snapshots`
23
23
  - `{feature}`: User-provided feature name
24
+ - `{outcome}`: User-provided outcome status (optional)
25
+
26
+ ## Outcome Categories
27
+
28
+ Track what happened after shipping:
29
+
30
+ | Outcome | Meaning | Use When |
31
+ |---------|---------|----------|
32
+ | `validated` | Confirmed working in production | Feature verified by users/tests |
33
+ | `monitoring` | Deployed, needs observation | Just shipped, watching metrics |
34
+ | `known-issues` | Working with caveats | Minor issues known, acceptable |
35
+
36
+ If no outcome provided, default to `monitoring`.
37
+
38
+ Prompt (optional):
39
+ ```
40
+ Ship outcome? (default: monitoring)
41
+ 1. validated - Confirmed working
42
+ 2. monitoring - Watching metrics
43
+ 3. known-issues - Has minor issues
44
+ ```
24
45
 
25
46
  ## Step 1: Read Config
26
47
 
@@ -73,10 +94,32 @@ ELSE:
73
94
 
74
95
  **Note**: These are NON-BLOCKING. Continue even if they fail.
75
96
 
76
- ## Step 4: Version Bump
97
+ ## Step 4: Version Bump (MANDATORY)
77
98
 
78
- READ: `package.json`
79
- EXTRACT: current version as {currentVersion}
99
+ **CRITICAL**: Version bump is ALWAYS required. No exceptions.
100
+
101
+ ### Read Current Version (Language Agnostic)
102
+
103
+ Detect project type and read version from appropriate file:
104
+
105
+ | File | Language | Version Location |
106
+ |------|----------|------------------|
107
+ | `package.json` | Node.js | `"version": "X.Y.Z"` |
108
+ | `Cargo.toml` | Rust | `version = "X.Y.Z"` |
109
+ | `pyproject.toml` | Python | `version = "X.Y.Z"` |
110
+ | `go.mod` | Go | Use git tags |
111
+ | `VERSION` | Any | Plain text `X.Y.Z` |
112
+
113
+ BASH: Check which config exists:
114
+ ```bash
115
+ ls package.json Cargo.toml pyproject.toml VERSION 2>/dev/null | head -1
116
+ ```
117
+
118
+ READ appropriate file and EXTRACT: {currentVersion}
119
+
120
+ IF no version file found:
121
+ CREATE: `VERSION` file with content `0.0.0`
122
+ {currentVersion} = "0.0.0"
80
123
 
81
124
  ### Determine Bump Type
82
125
 
@@ -96,15 +139,42 @@ ELSE:
96
139
  {bumpType} = "patch"
97
140
  {newVersion} = increment Z in X.Y.Z
98
141
 
99
- ### Update package.json
142
+ ### Update Version File (MANDATORY)
143
+
144
+ Update the same file where version was read:
145
+ - `package.json`: Update `"version"` field
146
+ - `Cargo.toml`: Update `version` in `[package]`
147
+ - `pyproject.toml`: Update `version` in `[project]`
148
+ - `VERSION`: Replace entire content
100
149
 
101
- READ: `package.json`
102
- REPLACE: `"version": "{currentVersion}"` with `"version": "{newVersion}"`
103
- WRITE: `package.json`
150
+ WRITE the updated file.
104
151
 
105
- ## Step 5: Update CHANGELOG
152
+ **This step MUST complete. If it fails, STOP and report error.**
106
153
 
107
- READ: `CHANGELOG.md` (create if not exists)
154
+ ## Step 5: Update CHANGELOG (MANDATORY)
155
+
156
+ **CRITICAL**: CHANGELOG.md MUST be created/updated. No exceptions.
157
+
158
+ ### Check if CHANGELOG exists
159
+
160
+ BASH: `ls CHANGELOG.md 2>/dev/null || echo "NOT_FOUND"`
161
+
162
+ IF "NOT_FOUND":
163
+ CREATE new CHANGELOG.md with header:
164
+ ```markdown
165
+ # Changelog
166
+
167
+ All notable changes to this project will be documented in this file.
168
+
169
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
170
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
171
+
172
+ ```
173
+
174
+ ### Get Recent Commits for Changelog
175
+
176
+ BASH: `git log --oneline -20 --pretty=format:"- %s"`
177
+ CAPTURE as {commitList}
108
178
 
109
179
  ### Format New Entry
110
180
 
@@ -112,15 +182,26 @@ READ: `CHANGELOG.md` (create if not exists)
112
182
  ## [{newVersion}] - {GetDate()}
113
183
 
114
184
  ### {feature}
115
- - Shipped by prjct-cli
185
+
186
+ #### Changes
187
+ {commitList}
188
+
189
+ #### Quality
116
190
  - Lint: {lintStatus}
117
191
  - Tests: {testStatus}
192
+
193
+ ---
194
+
118
195
  ```
119
196
 
120
- INSERT at top of file (after # Changelog header)
197
+ ### Insert Entry
121
198
 
199
+ READ: `CHANGELOG.md`
200
+ INSERT new entry after "# Changelog" header (or after the preamble text)
122
201
  WRITE: `CHANGELOG.md`
123
202
 
203
+ **This step MUST complete. CHANGELOG.md MUST exist in repo after ship.**
204
+
124
205
  ## Step 6: Git Commit
125
206
 
126
207
  ### Stage Changes
@@ -128,11 +209,7 @@ BASH: `git add .`
128
209
 
129
210
  ### Create Commit
130
211
  BASH: `git commit -m "$(cat <<'EOF'
131
- feat: Ship {feature}
132
-
133
- - Version: {newVersion}
134
- - Lint: {lintStatus}
135
- - Tests: {testStatus}
212
+ feat: Ship {feature} v{newVersion}
136
213
 
137
214
  🤖 Generated with [p/](https://www.prjct.app/)
138
215
  Designed for [Claude](https://www.anthropic.com/claude)
@@ -152,7 +229,7 @@ IF contains "rejected" OR contains "failed":
152
229
  IF contains "no upstream":
153
230
  BASH: `git push -u origin HEAD`
154
231
 
155
- ## Step 8: Update Shipped (JSON)
232
+ ## Step 8: Update Shipped (MD)
156
233
 
157
234
  SET: {now} = GetTimestamp()
158
235
  GENERATE: {shipId} = "ship_" + 8 random alphanumeric chars
@@ -160,74 +237,71 @@ GENERATE: {shipId} = "ship_" + 8 random alphanumeric chars
160
237
  READ: `{shippedPath}` (or create default if not exists)
161
238
 
162
239
  Default structure:
163
- ```json
164
- {
165
- "items": [],
166
- "lastUpdated": ""
167
- }
240
+ ```markdown
241
+ # Shipped
242
+
243
+ ## Recent
244
+
245
+ _Nothing shipped yet_
246
+
247
+ ## Archive
248
+
249
+ _No archived ships_
168
250
  ```
169
251
 
170
252
  ### Get changes from git
171
253
  BASH: `git log --oneline -5`
172
254
  CAPTURE commit messages as {changes}
173
255
 
174
- ### Create shipped item
175
- ```json
176
- {
177
- "id": "{shipId}",
178
- "name": "{feature}",
179
- "version": "{newVersion}",
180
- "type": "feature",
181
- "changes": [{changes as array}],
182
- "metrics": {
183
- "lintStatus": "{lintStatus}",
184
- "testStatus": "{testStatus}"
185
- },
186
- "shippedAt": "{now}"
187
- }
188
- ```
256
+ ### Update shipped.md
189
257
 
190
- ### Update shipped.json
191
- ```json
192
- {
193
- "items": [
194
- {new shipped item},
195
- ...existing items
196
- ],
197
- "lastUpdated": "{now}"
198
- }
258
+ Parse existing content and add new ship under "## Recent" section:
259
+
260
+ ```markdown
261
+ # Shipped
262
+
263
+ ## Recent
264
+
265
+ ### {feature} (v{newVersion})
266
+ - **ID**: {shipId}
267
+ - **Shipped**: {now}
268
+ - **Outcome**: {outcome}
269
+ - **Lint**: {lintStatus}
270
+ - **Tests**: {testStatus}
271
+ - **Changes**:
272
+ {changes as bullet list}
273
+
274
+ {...existing recent ships}
275
+
276
+ ## Archive
277
+
278
+ {...existing archive}
199
279
  ```
200
280
 
201
281
  WRITE: `{shippedPath}`
202
282
 
203
- ## Step 9: Update Roadmap Status (JSON)
283
+ ## Step 9: Update Roadmap Status (MD)
204
284
 
205
285
  READ: `{roadmapPath}`
206
286
 
207
287
  ### Find matching feature and update status
208
- For feature matching {feature}:
209
- Set status = "shipped"
210
- Set shippedAt = "{now}"
211
- Set version = "{newVersion}"
288
+ Look for feature entry matching {feature}:
289
+ - Change status from `pending` or `active` to `shipped`
290
+ - Add `Shipped: {now}` line
291
+ - Add `Version: {newVersion}` line
212
292
 
213
293
  WRITE: `{roadmapPath}`
214
294
 
215
- ## Step 10: Generate Views
216
-
217
- BASH: `cd {projectRoot} && npx prjct-generate-views --project={projectId}`
218
-
219
- Note: This regenerates views/shipped.md, views/roadmap.md from JSON automatically.
220
-
221
- ## Step 11: Log to Memory
295
+ ## Step 10: Log to Memory
222
296
 
223
297
  APPEND to: `{memoryPath}`
224
298
 
225
299
  Single line (JSONL):
226
300
  ```json
227
- {"timestamp":"{now}","action":"feature_shipped","shipId":"{shipId}","feature":"{feature}","version":"{newVersion}"}
301
+ {"timestamp":"{now}","action":"feature_shipped","shipId":"{shipId}","feature":"{feature}","version":"{newVersion}","outcome":"{outcome}"}
228
302
  ```
229
303
 
230
- ## Step 12: Create Snapshot (Undo/Redo Support)
304
+ ## Step 11: Create Snapshot (Undo/Redo Support)
231
305
 
232
306
  This creates a snapshot for the undo/redo system.
233
307
 
@@ -269,6 +343,19 @@ Single line (JSONL):
269
343
  {"type":"snapshot","hash":"{snapshotHash}","message":"Ship: {feature}","version":"{newVersion}","timestamp":"{GetTimestamp()}"}
270
344
  ```
271
345
 
346
+ ## Step 12: Run Deep Sync
347
+
348
+ **CRITICAL**: After shipping, run a full sync to update ALL project data.
349
+
350
+ Execute `/p:sync` logic:
351
+ - Update `project.json` with new version, commit count
352
+ - Update `CLAUDE.md` Quick Reference table
353
+ - Sync `core/now.md` (clear completed task)
354
+ - Sync `core/next.md` (remove shipped items)
355
+ - Update all stats and metadata
356
+
357
+ This ensures the dashboard reflects the latest state after shipping.
358
+
272
359
  ## Output
273
360
 
274
361
  SUCCESS:
@@ -276,11 +363,17 @@ SUCCESS:
276
363
  🚀 Shipped: {feature}
277
364
 
278
365
  Version: {currentVersion} → {newVersion}
366
+ Outcome: {outcome}
279
367
  Lint: {lintStatus}
280
368
  Tests: {testStatus}
281
369
  Commit: {commitHash}
282
370
  Snapshot: {snapshotHash}
283
371
 
372
+ 🔄 Synced project data
373
+ ├── Files: {fileCount}
374
+ ├── Commits: {commitCount}
375
+ └── All MD files updated
376
+
284
377
  Next:
285
378
  • /p:undo - Revert this ship if needed
286
379
  • /p:feature - Plan next feature
@@ -296,15 +389,23 @@ Next:
296
389
  | Lint fails | Show warning | CONTINUE |
297
390
  | Tests fail | Show warning | CONTINUE |
298
391
  | Push fails | Show fix command | CONTINUE |
299
- | No package.json | Skip version bump | CONTINUE |
392
+ | No version file | CREATE `VERSION` file | CONTINUE |
393
+ | Version bump fails | "Failed to update version" | STOP |
394
+ | CHANGELOG fails | "Failed to update changelog" | STOP |
395
+
396
+ **MANDATORY outputs (never skip):**
397
+ - Version file updated (package.json, Cargo.toml, pyproject.toml, or VERSION)
398
+ - `CHANGELOG.md` with new entry
399
+ - Git commit with version in message
300
400
 
301
401
  ## Examples
302
402
 
303
- ### Example 1: Full Success
403
+ ### Example 1: Full Success (validated)
304
404
  ```
305
405
  🚀 Shipped: user authentication
306
406
 
307
407
  Version: 1.2.0 → 1.3.0
408
+ Outcome: validated
308
409
  Lint: passed
309
410
  Tests: passed
310
411
  Commit: abc1234
@@ -312,11 +413,12 @@ Commit: abc1234
312
413
  Next: /p:feature | /p:recap | compact
313
414
  ```
314
415
 
315
- ### Example 2: With Warnings
416
+ ### Example 2: With Warnings (monitoring)
316
417
  ```
317
418
  🚀 Shipped: bug fixes
318
419
 
319
420
  Version: 1.2.0 → 1.2.1
421
+ Outcome: monitoring
320
422
  Lint: warnings (non-blocking)
321
423
  Tests: skipped
322
424
  Commit: def5678
@@ -326,14 +428,17 @@ Commit: def5678
326
428
  Next: /p:feature | /p:recap | compact
327
429
  ```
328
430
 
329
- ### Example 3: No Tests/Lint
431
+ ### Example 3: Known Issues
330
432
  ```
331
- 🚀 Shipped: documentation update
433
+ 🚀 Shipped: performance updates
332
434
 
333
435
  Version: 1.2.0 → 1.2.1
334
- Lint: skipped (no script)
335
- Tests: skipped (no script)
436
+ Outcome: known-issues
437
+ Lint: passed
438
+ Tests: passed
336
439
  Commit: ghi9012
337
440
 
441
+ Note: Minor edge case in Safari, tracking issue #45
442
+
338
443
  Next: /p:feature | /p:recap | compact
339
444
  ```