prjct-cli 1.0.0 → 1.1.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 +40 -0
- package/dist/bin/prjct.mjs +1 -1
- package/package.json +1 -1
- package/templates/commands/status.md +207 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.0] - 2026-02-05
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- visual workflow status command (PRJ-140) (#109)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [1.1.0] - 2026-02-05
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- **Workflow visualization (PRJ-140)**: New `p. status` command with visual workflow diagram
|
|
15
|
+
|
|
16
|
+
### Implementation Details
|
|
17
|
+
|
|
18
|
+
Added visual workflow status template showing:
|
|
19
|
+
- ASCII workflow diagram with current position indicator (sync → task → work → done → ship)
|
|
20
|
+
- Subtask tree visualization with status icons (✅/🔄/⬜)
|
|
21
|
+
- Progress bar for subtask completion
|
|
22
|
+
- Paused tasks, queue summary, and recent ships
|
|
23
|
+
- Context staleness indicator from `prjct status --json`
|
|
24
|
+
- Compact mode for single-line status output
|
|
25
|
+
|
|
26
|
+
### Learnings
|
|
27
|
+
|
|
28
|
+
- Template-first approach: Complex visualizations can be defined entirely in markdown templates without code changes
|
|
29
|
+
|
|
30
|
+
### Test Plan
|
|
31
|
+
|
|
32
|
+
#### For QA
|
|
33
|
+
1. Run `prjct sync` to install new status template
|
|
34
|
+
2. Run `p. status` - verify workflow diagram displays
|
|
35
|
+
3. Verify subtask tree shows correct status icons
|
|
36
|
+
4. Test `p. status compact` for single-line output
|
|
37
|
+
|
|
38
|
+
#### For Users
|
|
39
|
+
- New `p. status` command shows visual workflow overview
|
|
40
|
+
- No breaking changes
|
|
41
|
+
|
|
42
|
+
|
|
3
43
|
## [1.0.0] - 2026-02-05
|
|
4
44
|
|
|
5
45
|
### Features
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -26859,7 +26859,7 @@ var require_package = __commonJS({
|
|
|
26859
26859
|
"package.json"(exports, module) {
|
|
26860
26860
|
module.exports = {
|
|
26861
26861
|
name: "prjct-cli",
|
|
26862
|
-
version: "1.
|
|
26862
|
+
version: "1.1.0",
|
|
26863
26863
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
26864
26864
|
main: "core/index.ts",
|
|
26865
26865
|
bin: {
|
package/package.json
CHANGED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
allowed-tools: [Read, Bash]
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# p. status
|
|
6
|
+
|
|
7
|
+
Visual workflow status showing current position in the prjct lifecycle.
|
|
8
|
+
|
|
9
|
+
## Step 1: Resolve Project Paths
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Get projectId from local config
|
|
13
|
+
cat .prjct/prjct.config.json | grep -o '"projectId"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Set `globalPath = ~/.prjct-cli/projects/{projectId}`
|
|
17
|
+
|
|
18
|
+
## Step 2: Read State and Context
|
|
19
|
+
|
|
20
|
+
READ:
|
|
21
|
+
- `{globalPath}/storage/state.json` → current task, paused, previous
|
|
22
|
+
- `{globalPath}/storage/queue.json` → upcoming tasks
|
|
23
|
+
- `{globalPath}/storage/shipped.json` → recent ships
|
|
24
|
+
- `{globalPath}/project.json` → lastSync timestamp
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Get staleness info
|
|
28
|
+
prjct status --json 2>/dev/null || echo '{"isStale": false}'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Step 3: Determine Workflow Position
|
|
32
|
+
|
|
33
|
+
Based on state.json, determine current position:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
IF no currentTask AND no previousTask:
|
|
37
|
+
position = "ready" # Ready to start (after sync)
|
|
38
|
+
ELSE IF currentTask.status == "active":
|
|
39
|
+
position = "working" # In task
|
|
40
|
+
ELSE IF currentTask.status == "in_review":
|
|
41
|
+
position = "reviewing" # PR open, waiting for merge
|
|
42
|
+
ELSE IF currentTask.status == "shipped":
|
|
43
|
+
position = "shipped" # Ready for next task
|
|
44
|
+
ELSE:
|
|
45
|
+
position = "idle"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Step 4: Calculate Progress
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
IF currentTask.subtasks exists:
|
|
52
|
+
completed = count where status == "completed"
|
|
53
|
+
total = subtasks.length
|
|
54
|
+
percent = (completed / total) * 100
|
|
55
|
+
progressBar = generateBar(percent, 10) # 10 chars wide
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Progress bar generation:
|
|
59
|
+
```
|
|
60
|
+
filled = floor(percent / 10)
|
|
61
|
+
empty = 10 - filled
|
|
62
|
+
bar = "█" × filled + "░" × empty
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Step 5: Format Subtask Tree
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
FOR EACH subtask in currentTask.subtasks:
|
|
69
|
+
IF index == currentSubtaskIndex:
|
|
70
|
+
prefix = "🔄" # Current
|
|
71
|
+
ELSE IF subtask.status == "completed":
|
|
72
|
+
prefix = "✅" # Done
|
|
73
|
+
ELSE:
|
|
74
|
+
prefix = "⬜" # Pending
|
|
75
|
+
|
|
76
|
+
connector = (index == last) ? "└─" : "├─"
|
|
77
|
+
OUTPUT: " {connector} {prefix} {subtask.description}"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Output: Workflow Diagram
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
📊 WORKFLOW STATUS
|
|
86
|
+
|
|
87
|
+
┌─────────────────────────────────────────────────────────┐
|
|
88
|
+
│ │
|
|
89
|
+
│ sync ──▶ task ──▶ [work] ──▶ done ──▶ ship │
|
|
90
|
+
│ ○ ○ ● ○ ○ │
|
|
91
|
+
│ ▲ │
|
|
92
|
+
│ YOU ARE HERE │
|
|
93
|
+
│ │
|
|
94
|
+
└─────────────────────────────────────────────────────────┘
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Position indicators:
|
|
98
|
+
- `○` = not active
|
|
99
|
+
- `●` = current position
|
|
100
|
+
- Arrow indicates flow direction
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Output: Full Status
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
📊 WORKFLOW STATUS
|
|
108
|
+
|
|
109
|
+
┌─────────────────────────────────────────────────────────┐
|
|
110
|
+
│ sync ──▶ task ──▶ work ──▶ done ──▶ ship │
|
|
111
|
+
│ {s} {t} {w} {d} {h} │
|
|
112
|
+
└─────────────────────────────────────────────────────────┘
|
|
113
|
+
|
|
114
|
+
🎯 Current: {currentTask.parentDescription}
|
|
115
|
+
Branch: {currentTask.branch}
|
|
116
|
+
Type: {currentTask.type} | Started: {elapsed}
|
|
117
|
+
{IF linearId: "Linear: {linearId}"}
|
|
118
|
+
|
|
119
|
+
Progress: {progressBar} {completed}/{total} subtasks
|
|
120
|
+
{subtask tree}
|
|
121
|
+
|
|
122
|
+
⏸️ Paused: {pausedTasks[0].description or "none"}
|
|
123
|
+
|
|
124
|
+
📋 Queue: {queueCount} tasks
|
|
125
|
+
{IF queueCount > 0:}
|
|
126
|
+
• {queue[0].description}
|
|
127
|
+
• {queue[1].description}
|
|
128
|
+
{... up to 3}
|
|
129
|
+
|
|
130
|
+
🚀 Last ship: {previousTask.description} ({daysSince})
|
|
131
|
+
{IF previousTask.prUrl: "PR: {prUrl}"}
|
|
132
|
+
|
|
133
|
+
📡 Context: {staleness status}
|
|
134
|
+
Last sync: {timeSinceSync}
|
|
135
|
+
{IF isStale: "⚠️ Run `p. sync` to refresh"}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Output: Compact (`p. status compact`)
|
|
141
|
+
|
|
142
|
+
Single-line summary:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
{position_emoji} {currentTask.description} │ {progressBar} {completed}/{total} │ 📋 {queueCount} │ {staleness_emoji}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Position emojis:
|
|
149
|
+
- 🔄 = working
|
|
150
|
+
- 👀 = reviewing
|
|
151
|
+
- ✅ = shipped
|
|
152
|
+
- 💤 = idle
|
|
153
|
+
|
|
154
|
+
Staleness emojis:
|
|
155
|
+
- ✅ = fresh
|
|
156
|
+
- ⚠️ = stale
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Output: No Active Task
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
📊 WORKFLOW STATUS
|
|
164
|
+
|
|
165
|
+
┌─────────────────────────────────────────────────────────┐
|
|
166
|
+
│ sync ──▶ task ──▶ work ──▶ done ──▶ ship │
|
|
167
|
+
│ ● ○ ○ ○ ○ │
|
|
168
|
+
└─────────────────────────────────────────────────────────┘
|
|
169
|
+
|
|
170
|
+
💤 No active task
|
|
171
|
+
|
|
172
|
+
📋 Queue: {queueCount} tasks
|
|
173
|
+
{IF queueCount > 0:}
|
|
174
|
+
• {queue[0].description}
|
|
175
|
+
|
|
176
|
+
🚀 Last ship: {previousTask.description} ({daysSince})
|
|
177
|
+
|
|
178
|
+
Next: `p. task "description"` or `p. task PRJ-XXX`
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Elapsed Time Formatting
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
IF minutes < 60: "{minutes}m"
|
|
187
|
+
ELSE IF hours < 24: "{hours}h {minutes}m"
|
|
188
|
+
ELSE: "{days}d {hours}h"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Context Staleness
|
|
194
|
+
|
|
195
|
+
From `prjct status --json`:
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"isStale": true,
|
|
199
|
+
"commitsSinceSync": 15,
|
|
200
|
+
"daysSinceSync": 3,
|
|
201
|
+
"significantChanges": ["package.json", "tsconfig.json"]
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Display:
|
|
206
|
+
- Fresh (< 10 commits, < 3 days): `✅ Fresh (synced {time} ago)`
|
|
207
|
+
- Stale: `⚠️ Stale ({commits} commits, {days}d) - run p. sync`
|