prjct-cli 0.12.2 → 0.13.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/CHANGELOG.md +43 -0
- package/CLAUDE.md +18 -6
- package/core/data/index.ts +19 -5
- package/core/data/md-base-manager.ts +203 -0
- package/core/data/md-queue-manager.ts +179 -0
- package/core/data/md-state-manager.ts +133 -0
- package/core/serializers/index.ts +20 -0
- package/core/serializers/queue-serializer.ts +210 -0
- package/core/serializers/state-serializer.ts +136 -0
- package/core/utils/file-helper.ts +12 -0
- package/package.json +1 -1
- package/packages/web/app/api/projects/[id]/stats/route.ts +6 -29
- package/packages/web/app/page.tsx +1 -6
- package/packages/web/app/project/[id]/page.tsx +34 -1
- package/packages/web/app/project/[id]/stats/page.tsx +11 -5
- package/packages/web/app/settings/page.tsx +2 -221
- package/packages/web/components/BlockersCard/BlockersCard.tsx +67 -0
- package/packages/web/components/BlockersCard/BlockersCard.types.ts +11 -0
- package/packages/web/components/BlockersCard/index.ts +2 -0
- package/packages/web/components/CommandButton/CommandButton.tsx +10 -3
- package/packages/web/lib/projects.ts +28 -27
- package/packages/web/lib/services/projects.server.ts +25 -21
- package/packages/web/lib/services/stats.server.ts +355 -57
- package/packages/web/package.json +0 -2
- package/templates/commands/decision.md +226 -0
- package/templates/commands/done.md +100 -68
- package/templates/commands/feature.md +102 -103
- package/templates/commands/idea.md +41 -38
- package/templates/commands/now.md +94 -33
- package/templates/commands/pause.md +90 -30
- package/templates/commands/ship.md +179 -74
- package/templates/commands/sync.md +324 -200
- package/packages/web/app/api/migrate/route.ts +0 -46
- package/packages/web/app/api/settings/route.ts +0 -97
- package/packages/web/app/api/v2/projects/[id]/unified/route.ts +0 -57
- package/packages/web/components/MigrationGate/MigrationGate.tsx +0 -304
- package/packages/web/components/MigrationGate/index.ts +0 -1
- package/packages/web/lib/json-loader.ts +0 -630
- package/packages/web/lib/services/migration.server.ts +0 -580
|
@@ -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: '
|
|
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:
|
|
10
|
+
## Architecture: MD-First
|
|
11
11
|
|
|
12
|
-
**Source of Truth**: `
|
|
13
|
-
|
|
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
|
-
- `{
|
|
19
|
-
- `{
|
|
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
|
-
|
|
79
|
-
|
|
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
|
|
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
|
-
|
|
102
|
-
REPLACE: `"version": "{currentVersion}"` with `"version": "{newVersion}"`
|
|
103
|
-
WRITE: `package.json`
|
|
150
|
+
WRITE the updated file.
|
|
104
151
|
|
|
105
|
-
|
|
152
|
+
**This step MUST complete. If it fails, STOP and report error.**
|
|
106
153
|
|
|
107
|
-
|
|
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
|
-
|
|
185
|
+
|
|
186
|
+
#### Changes
|
|
187
|
+
{commitList}
|
|
188
|
+
|
|
189
|
+
#### Quality
|
|
116
190
|
- Lint: {lintStatus}
|
|
117
191
|
- Tests: {testStatus}
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
118
195
|
```
|
|
119
196
|
|
|
120
|
-
|
|
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 (
|
|
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
|
-
```
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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 (
|
|
283
|
+
## Step 9: Update Roadmap Status (MD)
|
|
204
284
|
|
|
205
285
|
READ: `{roadmapPath}`
|
|
206
286
|
|
|
207
287
|
### Find matching feature and update status
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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:
|
|
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
|
|
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
|
|
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:
|
|
431
|
+
### Example 3: Known Issues
|
|
330
432
|
```
|
|
331
|
-
🚀 Shipped:
|
|
433
|
+
🚀 Shipped: performance updates
|
|
332
434
|
|
|
333
435
|
Version: 1.2.0 → 1.2.1
|
|
334
|
-
|
|
335
|
-
|
|
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
|
```
|