prjct-cli 0.10.13 → 0.11.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 (44) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/CLAUDE.md +47 -2
  3. package/bin/dev.js +217 -0
  4. package/bin/prjct +10 -0
  5. package/bin/serve.js +78 -0
  6. package/core/agentic/command-executor.js +38 -112
  7. package/core/agentic/prompt-builder.js +72 -0
  8. package/core/bus/index.js +322 -0
  9. package/core/command-registry.js +65 -0
  10. package/core/domain/snapshot-manager.js +375 -0
  11. package/core/plugin/hooks.js +313 -0
  12. package/core/plugin/index.js +52 -0
  13. package/core/plugin/loader.js +331 -0
  14. package/core/plugin/registry.js +325 -0
  15. package/core/plugins/webhook.js +143 -0
  16. package/core/session/index.js +449 -0
  17. package/core/session/metrics.js +293 -0
  18. package/package.json +18 -4
  19. package/templates/agentic/agent-routing.md +42 -9
  20. package/templates/agentic/checklist-routing.md +98 -0
  21. package/templates/checklists/accessibility.md +33 -0
  22. package/templates/checklists/architecture.md +28 -0
  23. package/templates/checklists/code-quality.md +28 -0
  24. package/templates/checklists/data.md +33 -0
  25. package/templates/checklists/documentation.md +33 -0
  26. package/templates/checklists/infrastructure.md +33 -0
  27. package/templates/checklists/performance.md +33 -0
  28. package/templates/checklists/security.md +33 -0
  29. package/templates/checklists/testing.md +33 -0
  30. package/templates/checklists/ux-ui.md +37 -0
  31. package/templates/commands/bug.md +27 -1
  32. package/templates/commands/done.md +176 -54
  33. package/templates/commands/feature.md +38 -1
  34. package/templates/commands/history.md +176 -0
  35. package/templates/commands/init.md +28 -1
  36. package/templates/commands/now.md +191 -9
  37. package/templates/commands/pause.md +176 -12
  38. package/templates/commands/redo.md +142 -0
  39. package/templates/commands/resume.md +166 -62
  40. package/templates/commands/serve.md +121 -0
  41. package/templates/commands/ship.md +45 -1
  42. package/templates/commands/sync.md +34 -1
  43. package/templates/commands/task.md +27 -1
  44. package/templates/commands/undo.md +152 -0
@@ -0,0 +1,176 @@
1
+ ---
2
+ allowed-tools: [Read, Bash]
3
+ description: 'View snapshot history for undo/redo'
4
+ timestamp-rule: 'None required - read-only command'
5
+ ---
6
+
7
+ # /p:history - View Snapshot History
8
+
9
+ ## Overview
10
+ Displays the history of snapshots for the current project. Shows what can be undone/redone.
11
+
12
+ ## Context Variables
13
+ - `{projectId}`: From `.prjct/prjct.config.json`
14
+ - `{globalPath}`: `~/.prjct-cli/projects/{projectId}`
15
+ - `{snapshotDir}`: `{globalPath}/snapshots`
16
+ - `{limit}`: Number of snapshots to show (default: 10)
17
+
18
+ ## Step 1: Read Config
19
+
20
+ READ: `.prjct/prjct.config.json`
21
+ EXTRACT: `projectId`
22
+
23
+ IF file not found:
24
+ OUTPUT: "No prjct project. Run /p:init first."
25
+ STOP
26
+
27
+ ## Step 2: Check Snapshots Exist
28
+
29
+ BASH: `ls ~/.prjct-cli/projects/{projectId}/snapshots/.git 2>/dev/null || echo "NO_SNAPSHOTS"`
30
+
31
+ IF output contains "NO_SNAPSHOTS":
32
+ OUTPUT: "⚠️ No snapshots yet. Create one with /p:ship."
33
+ STOP
34
+
35
+ ## Step 3: Get Snapshot History
36
+
37
+ BASH: `cd {snapshotDir} && git log --pretty=format:'%h|%s|%ar|%ai' -n {limit}`
38
+
39
+ CAPTURE output and parse each line:
40
+ - `{shortHash}`: Before first `|`
41
+ - `{message}`: Between first and second `|`
42
+ - `{relativeTime}`: Between second and third `|`
43
+ - `{absoluteTime}`: After third `|`
44
+
45
+ ## Step 4: Get Current Position
46
+
47
+ BASH: `cd {snapshotDir} && git rev-parse --short HEAD`
48
+ CAPTURE as {currentHash}
49
+
50
+ ## Step 5: Check Redo Stack
51
+
52
+ READ: `{snapshotDir}/redo-stack.json`
53
+
54
+ IF file exists AND not empty AND not "[]":
55
+ PARSE as JSON array
56
+ COUNT items as {redoCount}
57
+ ELSE:
58
+ {redoCount} = 0
59
+
60
+ ## Step 6: Format Output
61
+
62
+ Build table with columns:
63
+ - `#`: Index (1, 2, 3...)
64
+ - `Hash`: Short hash
65
+ - `Description`: Commit message (first line)
66
+ - `When`: Relative time
67
+ - `Status`: "← current" for current, empty for others
68
+
69
+ ### Table Format
70
+
71
+ ```
72
+ # Snapshot History
73
+
74
+ | # | Hash | Description | When |
75
+ |---|---------|------------------------------|------------|
76
+ | 1 | abc1234 | Ship authentication [← NOW] | 2 hours ago|
77
+ | 2 | def5678 | Add login form | 5 hours ago|
78
+ | 3 | ghi9012 | Initial setup | 1 day ago |
79
+ ```
80
+
81
+ ## Output
82
+
83
+ SUCCESS:
84
+ ```
85
+ 📜 Snapshot History
86
+
87
+ | # | Hash | Description | When |
88
+ |---|---------|------------------------------|-------------|
89
+ {formattedTable}
90
+
91
+ Current: {currentHash}
92
+ Redo available: {redoCount} snapshot(s)
93
+
94
+ Commands:
95
+ • /p:undo - Revert to previous snapshot
96
+ • /p:redo - Redo if available ({redoCount})
97
+ • /p:ship - Create new snapshot
98
+ ```
99
+
100
+ ## Empty State
101
+
102
+ IF no snapshots:
103
+ ```
104
+ 📜 Snapshot History
105
+
106
+ No snapshots yet.
107
+
108
+ Create your first snapshot:
109
+ • /p:ship <feature> - Ship a feature and create snapshot
110
+ ```
111
+
112
+ ## Examples
113
+
114
+ ### Example 1: Multiple Snapshots
115
+ ```
116
+ 📜 Snapshot History
117
+
118
+ | # | Hash | Description | When |
119
+ |---|---------|------------------------------|-------------|
120
+ | 1 | a1b2c3d | Ship user authentication | 2 hours ago |
121
+ | 2 | e4f5g6h | Add login form | 5 hours ago |
122
+ | 3 | i7j8k9l | Setup database models | 1 day ago |
123
+ | 4 | m0n1o2p | Initial project setup | 2 days ago |
124
+
125
+ Current: a1b2c3d
126
+ Redo available: 0 snapshot(s)
127
+
128
+ Commands:
129
+ • /p:undo - Revert to previous snapshot
130
+ • /p:redo - Redo if available (0)
131
+ • /p:ship - Create new snapshot
132
+ ```
133
+
134
+ ### Example 2: After Undo
135
+ ```
136
+ 📜 Snapshot History
137
+
138
+ | # | Hash | Description | When |
139
+ |---|---------|------------------------------|-------------|
140
+ | 1 | e4f5g6h | Add login form [← NOW] | 5 hours ago |
141
+ | 2 | i7j8k9l | Setup database models | 1 day ago |
142
+ | 3 | m0n1o2p | Initial project setup | 2 days ago |
143
+
144
+ Current: e4f5g6h
145
+ Redo available: 1 snapshot(s)
146
+
147
+ Commands:
148
+ • /p:undo - Revert to previous snapshot
149
+ • /p:redo - Redo if available (1)
150
+ • /p:ship - Create new snapshot
151
+ ```
152
+
153
+ ### Example 3: No Snapshots
154
+ ```
155
+ 📜 Snapshot History
156
+
157
+ No snapshots yet.
158
+
159
+ Create your first snapshot:
160
+ • /p:ship <feature> - Ship a feature and create snapshot
161
+ ```
162
+
163
+ ## Error Handling
164
+
165
+ | Error | Response | Action |
166
+ |-------|----------|--------|
167
+ | No project | "No prjct project" | STOP |
168
+ | No snapshots | Show empty state | STOP |
169
+ | Git error | Show error message | STOP |
170
+
171
+ ## Notes
172
+
173
+ - History is read-only, doesn't modify anything
174
+ - Shows relative times for quick scanning
175
+ - Indicates current position in history
176
+ - Shows redo availability count
@@ -1,10 +1,16 @@
1
1
  ---
2
2
  allowed-tools: [Read, Write, Bash]
3
3
  description: 'Initialize prjct'
4
+ timestamp-rule: 'GetTimestamp() for all timestamps'
4
5
  ---
5
6
 
6
7
  # /p:init
7
8
 
9
+ ## Context Variables
10
+ - `{projectId}`: Generated unique ID (12 chars hex)
11
+ - `{globalPath}`: `~/.prjct-cli/projects/{projectId}`
12
+ - `{cwd}`: Current working directory (repository path)
13
+
8
14
  ## Flow
9
15
 
10
16
  **Existing**: ID → dirs → config → analyze → agents
@@ -16,6 +22,28 @@ description: 'Initialize prjct'
16
22
  ## Config
17
23
  `.prjct/prjct.config.json`: version, projectId, dataPath, author
18
24
 
25
+ ## Step: Create project.json (REQUIRED)
26
+
27
+ This file is the source of truth for the web dashboard. It maps projectId → repoPath.
28
+
29
+ ### Determine Project Name
30
+ - Try package.json → `name` field
31
+ - Try Cargo.toml → `[package] name`
32
+ - Try pyproject.toml → `[project] name`
33
+ - Fallback to directory name (last segment of current path)
34
+
35
+ WRITE: `{globalPath}/project.json`
36
+
37
+ ```json
38
+ {
39
+ "projectId": "{projectId}",
40
+ "repoPath": "{cwd}",
41
+ "name": "{projectName}",
42
+ "createdAt": "{GetTimestamp()}",
43
+ "lastSync": "{GetTimestamp()}"
44
+ }
45
+ ```
46
+
19
47
  ## Response
20
48
  `✅ Init | {stack} | {N} agents | Next: /p:feature or /p:help`
21
49
 
@@ -31,4 +59,3 @@ description: 'Initialize prjct'
31
59
  💬 REMEMBER: Talk naturally! "Start with auth" / "Show roadmap" / "Add another feature"
32
60
 
33
61
  Ready to start building? 🚀
34
- ```
@@ -1,14 +1,196 @@
1
1
  ---
2
- allowed-tools: [Read, Write, GetTimestamp]
3
- description: 'Current task'
4
- timestamp-rule: 'GetTimestamp() for timestamps'
2
+ allowed-tools: [Read, Write, Bash]
3
+ description: 'Set or show current task with session tracking'
4
+ timestamp-rule: 'GetTimestamp() for ALL timestamps'
5
5
  ---
6
6
 
7
- # /p:now
7
+ # /p:now - Current Task with Session Tracking
8
8
 
9
- ## Flow
10
- **Show**: Read `core/now.md`
11
- **Set**: Write now.md + {GetTimestamp()} → Log
9
+ ## Context Variables
10
+ - `{projectId}`: From `.prjct/prjct.config.json`
11
+ - `{globalPath}`: `~/.prjct-cli/projects/{projectId}`
12
+ - `{nowPath}`: `{globalPath}/core/now.md`
13
+ - `{sessionPath}`: `{globalPath}/sessions/current.json`
14
+ - `{memoryPath}`: `{globalPath}/memory/context.jsonl`
15
+ - `{task}`: User-provided task (optional)
12
16
 
13
- ## Response
14
- `🎯 {task} | Started: {time} | Done: /p:done`
17
+ ## Step 1: Read Config
18
+
19
+ READ: `.prjct/prjct.config.json`
20
+ EXTRACT: `projectId`
21
+
22
+ IF file not found:
23
+ OUTPUT: "No prjct project. Run /p:init first."
24
+ STOP
25
+
26
+ ## Step 2: Check Current State
27
+
28
+ ### Check for active session
29
+ READ: `{sessionPath}`
30
+
31
+ IF file exists:
32
+ PARSE as JSON
33
+ EXTRACT: {currentTask}, {status}, {startedAt}, {duration}
34
+
35
+ ### Check now.md
36
+ READ: `{nowPath}`
37
+
38
+ ## Step 3: Handle Cases
39
+
40
+ ### Case A: No task provided - Show current
41
+ IF {task} is empty OR not provided:
42
+ IF {currentTask} exists AND {status} == "active":
43
+ CALCULATE: {elapsed} = time since {startedAt}
44
+ OUTPUT:
45
+ ```
46
+ 🎯 {currentTask}
47
+
48
+ Session: {sessionId}
49
+ Started: {startedAt} ({elapsed} ago)
50
+ Status: active
51
+
52
+ /p:done to complete | /p:pause to pause
53
+ ```
54
+ STOP
55
+ ELSE IF {currentTask} exists AND {status} == "paused":
56
+ OUTPUT:
57
+ ```
58
+ ⏸️ Paused: {currentTask}
59
+
60
+ Duration so far: {duration}
61
+
62
+ /p:resume to continue | /p:done to complete
63
+ ```
64
+ STOP
65
+ ELSE:
66
+ OUTPUT: "No current task. Use /p:now <task> to start one."
67
+ STOP
68
+
69
+ ### Case B: Task provided - Create/Update session
70
+ IF {task} is provided:
71
+
72
+ ## Check for existing active session
73
+ IF {status} == "active" AND {currentTask} != {task}:
74
+ OUTPUT:
75
+ ```
76
+ ⚠️ Already working on: {currentTask}
77
+
78
+ Options:
79
+ • /p:done - Complete current task first
80
+ • /p:pause - Pause and switch
81
+ • /p:now (same task) - Continue current
82
+ ```
83
+ STOP
84
+
85
+ ## If same task, just continue
86
+ IF {currentTask} == {task}:
87
+ OUTPUT: "🎯 Continuing: {task}"
88
+ STOP
89
+
90
+ ## Create new session
91
+ GENERATE: {sessionId} = "sess_" + 8 random alphanumeric chars
92
+ SET: {startedAt} = GetTimestamp()
93
+
94
+ ### Create session JSON
95
+ WRITE: `{sessionPath}`
96
+ Content:
97
+ ```json
98
+ {
99
+ "id": "{sessionId}",
100
+ "projectId": "{projectId}",
101
+ "task": "{task}",
102
+ "status": "active",
103
+ "startedAt": "{startedAt}",
104
+ "pausedAt": null,
105
+ "completedAt": null,
106
+ "duration": 0,
107
+ "metrics": {
108
+ "filesChanged": 0,
109
+ "linesAdded": 0,
110
+ "linesRemoved": 0,
111
+ "commits": 0,
112
+ "snapshots": []
113
+ },
114
+ "timeline": [
115
+ {"type": "start", "at": "{startedAt}"}
116
+ ]
117
+ }
118
+ ```
119
+
120
+ ### Update now.md (legacy support)
121
+ WRITE: `{nowPath}`
122
+ Content:
123
+ ```markdown
124
+ # NOW
125
+
126
+ **{task}**
127
+
128
+ Started: {startedAt}
129
+ Session: {sessionId}
130
+ ```
131
+
132
+ ### Log to memory
133
+ APPEND to: `{memoryPath}`
134
+ Single line (JSONL):
135
+ ```json
136
+ {"timestamp":"{startedAt}","action":"session_started","sessionId":"{sessionId}","task":"{task}"}
137
+ ```
138
+
139
+ ## Output
140
+
141
+ SUCCESS (new task):
142
+ ```
143
+ 🎯 {task}
144
+
145
+ Session: {sessionId}
146
+ Started: now
147
+
148
+ /p:done when finished | /p:pause to take a break
149
+ ```
150
+
151
+ ## Error Handling
152
+
153
+ | Error | Response | Action |
154
+ |-------|----------|--------|
155
+ | No project | "No prjct project" | STOP |
156
+ | Active session exists | Show options | STOP |
157
+ | Write fails | "Failed to create session" | STOP |
158
+
159
+ ## Examples
160
+
161
+ ### Example 1: Show Current Task
162
+ ```
163
+ User: /p:now
164
+ Output:
165
+ 🎯 Implement user authentication
166
+
167
+ Session: sess_abc12345
168
+ Started: 2 hours ago
169
+ Status: active
170
+
171
+ /p:done to complete | /p:pause to pause
172
+ ```
173
+
174
+ ### Example 2: Start New Task
175
+ ```
176
+ User: /p:now "Add login form"
177
+ Output:
178
+ 🎯 Add login form
179
+
180
+ Session: sess_xyz98765
181
+ Started: now
182
+
183
+ /p:done when finished | /p:pause to take a break
184
+ ```
185
+
186
+ ### Example 3: Task Conflict
187
+ ```
188
+ User: /p:now "Something else"
189
+ Output:
190
+ ⚠️ Already working on: Add login form
191
+
192
+ Options:
193
+ • /p:done - Complete current task first
194
+ • /p:pause - Pause and switch
195
+ • /p:now (same task) - Continue current
196
+ ```
@@ -1,18 +1,182 @@
1
1
  ---
2
- allowed-tools: [Read, Write, GetTimestamp]
3
- description: 'Pause task'
4
- timestamp-rule: 'GetTimestamp() for paused'
2
+ allowed-tools: [Read, Write, Bash]
3
+ description: 'Pause current session'
4
+ timestamp-rule: 'GetTimestamp() for all timestamps'
5
5
  ---
6
6
 
7
- # /p:pause
7
+ # /p:pause - Pause Current Session
8
8
 
9
- ## Check
10
- Requires active in `core/stack.jsonl`
9
+ ## Context Variables
10
+ - `{projectId}`: From `.prjct/prjct.config.json`
11
+ - `{globalPath}`: `~/.prjct-cli/projects/{projectId}`
12
+ - `{sessionPath}`: `{globalPath}/sessions/current.json`
13
+ - `{nowPath}`: `{globalPath}/core/now.md`
14
+ - `{memoryPath}`: `{globalPath}/memory/context.jsonl`
11
15
 
12
- ## Flow
13
- 1. Find active → Set status='paused', paused={GetTimestamp()}
14
- 2. Update stack.jsonl + now.md
15
- 3. Log: `{"ts":"{GetTimestamp()}","type":"task_pause","task":"{t}"}`
16
+ ## Step 1: Read Config
16
17
 
17
- ## Response
18
- `⏸️ {task} | Active: {duration} | Resume: /p:resume`
18
+ READ: `.prjct/prjct.config.json`
19
+ EXTRACT: `projectId`
20
+
21
+ IF file not found:
22
+ OUTPUT: "No prjct project. Run /p:init first."
23
+ STOP
24
+
25
+ ## Step 2: Check Session State
26
+
27
+ READ: `{sessionPath}`
28
+
29
+ IF file not found OR empty:
30
+ OUTPUT: "⚠️ No active session to pause. Use /p:now to start one."
31
+ STOP
32
+
33
+ PARSE as JSON → {session}
34
+
35
+ IF {session.status} == "paused":
36
+ CALCULATE: {elapsed} = time since {session.pausedAt}
37
+ OUTPUT:
38
+ ```
39
+ ⏸️ Already paused: {session.task}
40
+
41
+ Paused: {elapsed} ago
42
+ Duration so far: {session.duration}
43
+
44
+ /p:resume to continue | /p:done to complete
45
+ ```
46
+ STOP
47
+
48
+ IF {session.status} != "active":
49
+ OUTPUT: "⚠️ No active session to pause."
50
+ STOP
51
+
52
+ ## Step 3: Calculate Duration So Far
53
+
54
+ SET: {now} = GetTimestamp()
55
+
56
+ For each event in {session.timeline}:
57
+ Track start/resume/pause times
58
+ Calculate total active time up to now
59
+
60
+ SET: {duration} = total active seconds
61
+ SET: {durationFormatted} = format as "Xh Ym" or "Xm"
62
+
63
+ ## Step 4: Update Session
64
+
65
+ UPDATE {session}:
66
+ ```json
67
+ {
68
+ "id": "{session.id}",
69
+ "projectId": "{session.projectId}",
70
+ "task": "{session.task}",
71
+ "status": "paused",
72
+ "startedAt": "{session.startedAt}",
73
+ "pausedAt": "{now}",
74
+ "completedAt": null,
75
+ "duration": {duration},
76
+ "metrics": {session.metrics},
77
+ "timeline": [
78
+ ...{session.timeline},
79
+ {"type": "pause", "at": "{now}"}
80
+ ]
81
+ }
82
+ ```
83
+
84
+ WRITE: `{sessionPath}`
85
+ Content: Updated session JSON
86
+
87
+ ## Step 5: Update Legacy now.md
88
+
89
+ WRITE: `{nowPath}`
90
+ Content:
91
+ ```markdown
92
+ # NOW
93
+
94
+ ⏸️ **{session.task}** (paused)
95
+
96
+ Started: {session.startedAt}
97
+ Paused: {now}
98
+ Duration: {durationFormatted}
99
+ Session: {session.id}
100
+ ```
101
+
102
+ ## Step 6: Log to Memory
103
+
104
+ APPEND to: `{memoryPath}`
105
+
106
+ Single line (JSONL):
107
+ ```json
108
+ {"timestamp":"{now}","action":"session_paused","sessionId":"{session.id}","task":"{session.task}","duration":{duration}}
109
+ ```
110
+
111
+ ## Output
112
+
113
+ SUCCESS:
114
+ ```
115
+ ⏸️ Paused: {session.task}
116
+
117
+ Session: {session.id}
118
+ Active time: {durationFormatted}
119
+
120
+ Next:
121
+ • /p:resume - Continue this task
122
+ • /p:now <task> - Start different task
123
+ • /p:done - Complete without resuming
124
+ ```
125
+
126
+ ## Error Handling
127
+
128
+ | Error | Response | Action |
129
+ |-------|----------|--------|
130
+ | No project | "No prjct project" | STOP |
131
+ | No session | "No active session" | STOP |
132
+ | Already paused | Show paused state | STOP |
133
+ | Write fails | Log warning | CONTINUE |
134
+
135
+ ## Examples
136
+
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
+ }
149
+ ```
150
+
151
+ **Current time:** 12:30 PM
152
+ **Duration:** 2h 30m
153
+
154
+ **Output:**
155
+ ```
156
+ ⏸️ Paused: implement auth
157
+
158
+ Session: sess_abc12345
159
+ Active time: 2h 30m
160
+
161
+ Next:
162
+ • /p:resume - Continue this task
163
+ • /p:now <task> - Start different task
164
+ • /p:done - Complete without resuming
165
+ ```
166
+
167
+ ### Example 2: Already Paused
168
+ **Output:**
169
+ ```
170
+ ⏸️ Already paused: implement auth
171
+
172
+ Paused: 15m ago
173
+ Duration so far: 2h 30m
174
+
175
+ /p:resume to continue | /p:done to complete
176
+ ```
177
+
178
+ ### Example 3: No Active Session
179
+ **Output:**
180
+ ```
181
+ ⚠️ No active session to pause. Use /p:now to start one.
182
+ ```