prjct-cli 0.23.0 → 0.25.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 +46 -0
- package/CLAUDE.md +14 -7
- package/core/commands/command-data.ts +21 -8
- package/core/commands/setup.ts +52 -17
- package/core/infrastructure/setup.ts +101 -0
- package/core/schemas/project.ts +1 -0
- package/package.json +1 -1
- package/templates/commands/feature.md +28 -677
- package/templates/commands/now.md +32 -195
- package/templates/commands/sync.md +41 -3
- package/templates/commands/task.md +686 -0
- package/templates/global/CLAUDE.md +10 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.25.0] - 2025-12-30
|
|
4
|
+
|
|
5
|
+
### Maintenance Release
|
|
6
|
+
|
|
7
|
+
Version bump for release preparation.
|
|
8
|
+
|
|
9
|
+
## [0.24.0] - 2025-12-28
|
|
10
|
+
|
|
11
|
+
### Breaking Change: Unified Task Command
|
|
12
|
+
|
|
13
|
+
Consolidated `/p:now`, `/p:feature`, and `/p:work` into a single `/p:task` command with agentic classification.
|
|
14
|
+
|
|
15
|
+
**New Command: `/p:task`**
|
|
16
|
+
- Unified entry point for all work
|
|
17
|
+
- Agentic type classification (not keyword-based)
|
|
18
|
+
- 7-phase development workflow for all task types
|
|
19
|
+
- Git branch management with type-based prefixes
|
|
20
|
+
|
|
21
|
+
**Agentic Classification:**
|
|
22
|
+
The agent analyzes task descriptions holistically to determine type:
|
|
23
|
+
- `feature` - Adds new functionality
|
|
24
|
+
- `bug` - Something broken or incorrect
|
|
25
|
+
- `improvement` - Enhances existing functionality
|
|
26
|
+
- `refactor` - Reorganizes without behavior change
|
|
27
|
+
- `chore` - Maintenance, deps, docs
|
|
28
|
+
|
|
29
|
+
**Migration:**
|
|
30
|
+
```
|
|
31
|
+
/p:now "fix login bug" → /p:task "fix login bug"
|
|
32
|
+
/p:feature "add dark mode" → /p:task "add dark mode"
|
|
33
|
+
/p:work "update docs" → /p:task "update docs"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Deprecated Commands:**
|
|
37
|
+
- `/p:now` - Redirects to `/p:task`
|
|
38
|
+
- `/p:feature` - Redirects to `/p:task`
|
|
39
|
+
- `/p:work` - Redirects to `/p:task`
|
|
40
|
+
|
|
41
|
+
**Files Changed:**
|
|
42
|
+
- `templates/commands/task.md` - New unified template
|
|
43
|
+
- `templates/commands/now.md` - Deprecated, redirects
|
|
44
|
+
- `templates/commands/feature.md` - Deprecated, redirects
|
|
45
|
+
- `core/commands/command-data.ts` - Registry updates
|
|
46
|
+
- `templates/global/CLAUDE.md` - Updated workflow docs
|
|
47
|
+
- `CLAUDE.md` - Updated project docs
|
|
48
|
+
|
|
3
49
|
## [0.23.0] - 2025-12-28
|
|
4
50
|
|
|
5
51
|
### Feature: Branch + PR Workflow
|
package/CLAUDE.md
CHANGED
|
@@ -86,19 +86,18 @@ User Action → Storage (JSON) → Context (MD) → Sync Events
|
|
|
86
86
|
## Core Workflow
|
|
87
87
|
|
|
88
88
|
```
|
|
89
|
-
/p:sync → /p:
|
|
89
|
+
/p:sync → /p:task "description" → [work] → /p:done → /p:ship
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
## Commands
|
|
93
93
|
|
|
94
|
-
### Core Commands
|
|
94
|
+
### Core Commands
|
|
95
95
|
| Command | Purpose |
|
|
96
96
|
|---------|---------|
|
|
97
97
|
| `/p:init` | Initialize project with deep analysis |
|
|
98
98
|
| `/p:idea` | Transform ideas into architectures |
|
|
99
|
-
| `/p:
|
|
99
|
+
| `/p:task` | Start task with agentic classification + 7-phase workflow |
|
|
100
100
|
| `/p:spec` | Create detailed specifications |
|
|
101
|
-
| `/p:now [task]` | Start/show current task |
|
|
102
101
|
| `/p:pause` | Pause active task |
|
|
103
102
|
| `/p:resume` | Resume paused task |
|
|
104
103
|
| `/p:next` | Show priority queue |
|
|
@@ -109,6 +108,13 @@ User Action → Storage (JSON) → Context (MD) → Sync Events
|
|
|
109
108
|
| `/p:sync` | Analyze repo, generate agents |
|
|
110
109
|
| `/p:suggest` | Context-aware recommendations |
|
|
111
110
|
|
|
111
|
+
### Deprecated Commands
|
|
112
|
+
| Command | Migration |
|
|
113
|
+
|---------|-----------|
|
|
114
|
+
| `/p:now` | Use `/p:task` instead |
|
|
115
|
+
| `/p:feature` | Use `/p:task` instead |
|
|
116
|
+
| `/p:work` | Use `/p:task` instead |
|
|
117
|
+
|
|
112
118
|
### Optional Commands
|
|
113
119
|
| Command | Purpose |
|
|
114
120
|
|---------|---------|
|
|
@@ -123,9 +129,10 @@ User Action → Storage (JSON) → Context (MD) → Sync Events
|
|
|
123
129
|
|
|
124
130
|
Messages starting with `p.` trigger commands:
|
|
125
131
|
```
|
|
126
|
-
p.
|
|
127
|
-
p.
|
|
128
|
-
p.
|
|
132
|
+
p. task add auth → /p:task "add auth"
|
|
133
|
+
p. task fix login → /p:task "fix login"
|
|
134
|
+
p. done → /p:done
|
|
135
|
+
p. ship login → /p:ship "login"
|
|
129
136
|
```
|
|
130
137
|
|
|
131
138
|
## Template-Driven Execution
|
|
@@ -51,16 +51,27 @@ export const COMMANDS: CommandMeta[] = [
|
|
|
51
51
|
requiresProject: true,
|
|
52
52
|
features: ['Simple ideas -> Quick capture', 'Complex ideas -> Full architecture'],
|
|
53
53
|
},
|
|
54
|
+
{
|
|
55
|
+
name: 'task',
|
|
56
|
+
group: 'core',
|
|
57
|
+
description: 'Start task with agentic classification and 7-phase workflow',
|
|
58
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
59
|
+
params: '<description>',
|
|
60
|
+
implemented: true,
|
|
61
|
+
hasTemplate: true,
|
|
62
|
+
requiresProject: true,
|
|
63
|
+
features: ['Agentic type classification', '7-phase workflow', 'Git branch management', 'Task breakdown'],
|
|
64
|
+
},
|
|
54
65
|
{
|
|
55
66
|
name: 'feature',
|
|
56
67
|
group: 'core',
|
|
57
|
-
description: '
|
|
58
|
-
usage: { claude: '/p:
|
|
68
|
+
description: 'DEPRECATED - Use /p:task instead',
|
|
69
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
59
70
|
params: '<description>',
|
|
60
71
|
implemented: true,
|
|
61
72
|
hasTemplate: true,
|
|
62
73
|
requiresProject: true,
|
|
63
|
-
|
|
74
|
+
deprecated: true,
|
|
64
75
|
},
|
|
65
76
|
{
|
|
66
77
|
name: 'spec',
|
|
@@ -75,22 +86,24 @@ export const COMMANDS: CommandMeta[] = [
|
|
|
75
86
|
{
|
|
76
87
|
name: 'now',
|
|
77
88
|
group: 'core',
|
|
78
|
-
description: '
|
|
79
|
-
usage: { claude: '/p:
|
|
80
|
-
params: '[task]
|
|
89
|
+
description: 'DEPRECATED - Use /p:task instead',
|
|
90
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
91
|
+
params: '[task]',
|
|
81
92
|
implemented: true,
|
|
82
93
|
hasTemplate: true,
|
|
83
94
|
requiresProject: true,
|
|
95
|
+
deprecated: true,
|
|
84
96
|
},
|
|
85
97
|
{
|
|
86
98
|
name: 'work',
|
|
87
99
|
group: 'core',
|
|
88
|
-
description: '
|
|
89
|
-
usage: { claude: '/p:
|
|
100
|
+
description: 'DEPRECATED - Use /p:task instead',
|
|
101
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
90
102
|
params: '[task]',
|
|
91
103
|
implemented: true,
|
|
92
104
|
hasTemplate: true,
|
|
93
105
|
requiresProject: true,
|
|
106
|
+
deprecated: true,
|
|
94
107
|
},
|
|
95
108
|
{
|
|
96
109
|
name: 'pause',
|
package/core/commands/setup.ts
CHANGED
|
@@ -130,28 +130,63 @@ export class SetupCommands extends PrjctCommandsBase {
|
|
|
130
130
|
const settingsPath = path.join(claudeDir, 'settings.json')
|
|
131
131
|
const statusLinePath = path.join(claudeDir, 'prjct-statusline.sh')
|
|
132
132
|
|
|
133
|
+
// Version is embedded at install time
|
|
133
134
|
const scriptContent = `#!/bin/bash
|
|
134
135
|
# prjct Status Line for Claude Code
|
|
135
|
-
# Shows
|
|
136
|
+
# Shows version update notifications and current task
|
|
137
|
+
|
|
138
|
+
# Current CLI version (embedded at install time)
|
|
139
|
+
CLI_VERSION="${VERSION}"
|
|
136
140
|
|
|
137
141
|
# Read JSON context from stdin (provided by Claude Code)
|
|
138
142
|
read -r json
|
|
139
143
|
|
|
140
|
-
#
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
#
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
#
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if [ -
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
144
|
+
# Extract cwd from JSON
|
|
145
|
+
CWD=$(echo "$json" | grep -o '"cwd"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"cwd"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
146
|
+
|
|
147
|
+
# Check if this is a prjct project
|
|
148
|
+
CONFIG="$CWD/.prjct/prjct.config.json"
|
|
149
|
+
if [[ -f "$CONFIG" ]]; then
|
|
150
|
+
# Extract projectId
|
|
151
|
+
PROJECT_ID=$(grep -o '"projectId"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG" | sed 's/.*"projectId"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
152
|
+
|
|
153
|
+
if [[ -n "$PROJECT_ID" ]]; then
|
|
154
|
+
PROJECT_JSON="$HOME/.prjct-cli/projects/$PROJECT_ID/project.json"
|
|
155
|
+
|
|
156
|
+
# Check version mismatch
|
|
157
|
+
if [[ -f "$PROJECT_JSON" ]]; then
|
|
158
|
+
PROJECT_VERSION=$(grep -o '"cliVersion"[[:space:]]*:[[:space:]]*"[^"]*"' "$PROJECT_JSON" | sed 's/.*"cliVersion"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
159
|
+
|
|
160
|
+
# If no cliVersion or different version, show update notice
|
|
161
|
+
if [[ -z "$PROJECT_VERSION" ]] || [[ "$PROJECT_VERSION" != "$CLI_VERSION" ]]; then
|
|
162
|
+
echo "⚠️ prjct v$CLI_VERSION available! Run /p:sync"
|
|
163
|
+
exit 0
|
|
164
|
+
fi
|
|
165
|
+
else
|
|
166
|
+
# No project.json means project needs sync
|
|
167
|
+
echo "⚠️ prjct v$CLI_VERSION available! Run /p:sync"
|
|
168
|
+
exit 0
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
# Show current task if exists
|
|
172
|
+
STATE="$HOME/.prjct-cli/projects/$PROJECT_ID/storage/state.json"
|
|
173
|
+
if [[ -f "$STATE" ]]; then
|
|
174
|
+
TASK=$(grep -o '"description"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"description"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
175
|
+
STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"status"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
176
|
+
|
|
177
|
+
if [[ -n "$TASK" ]] && [[ "$STATUS" == "active" ]]; then
|
|
178
|
+
# Truncate task to 40 chars
|
|
179
|
+
TASK_SHORT="\${TASK:0:40}"
|
|
180
|
+
[[ \${#TASK} -gt 40 ]] && TASK_SHORT="$TASK_SHORT..."
|
|
181
|
+
echo "🎯 $TASK_SHORT"
|
|
182
|
+
exit 0
|
|
183
|
+
fi
|
|
184
|
+
fi
|
|
185
|
+
fi
|
|
154
186
|
fi
|
|
187
|
+
|
|
188
|
+
# Default: show prjct branding
|
|
189
|
+
echo "⚡ prjct"
|
|
155
190
|
`
|
|
156
191
|
fs.writeFileSync(statusLinePath, scriptContent, { mode: 0o755 })
|
|
157
192
|
|
|
@@ -204,8 +239,8 @@ fi
|
|
|
204
239
|
console.log(` ${chalk.bold('1.')} Initialize your project:`)
|
|
205
240
|
console.log(` ${chalk.green('cd your-project && prjct init')}`)
|
|
206
241
|
console.log('')
|
|
207
|
-
console.log(` ${chalk.bold('2.')}
|
|
208
|
-
console.log(` ${chalk.green('prjct
|
|
242
|
+
console.log(` ${chalk.bold('2.')} Start your first task:`)
|
|
243
|
+
console.log(` ${chalk.green('prjct task "build auth"')}`)
|
|
209
244
|
console.log('')
|
|
210
245
|
console.log(` ${chalk.bold('3.')} Ship & celebrate:`)
|
|
211
246
|
console.log(` ${chalk.green('prjct ship "user login"')}`)
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { execSync } from 'child_process'
|
|
16
|
+
import fs from 'fs'
|
|
17
|
+
import path from 'path'
|
|
18
|
+
import os from 'os'
|
|
16
19
|
import installer from './command-installer'
|
|
17
20
|
import editorsConfig from './editors-config'
|
|
18
21
|
import { VERSION } from '../utils/version'
|
|
@@ -106,6 +109,9 @@ export async function run(): Promise<SetupResults> {
|
|
|
106
109
|
|
|
107
110
|
// Step 4b: Install documentation files
|
|
108
111
|
await installer.installDocs()
|
|
112
|
+
|
|
113
|
+
// Step 4c: Install status line with version check
|
|
114
|
+
await installStatusLine()
|
|
109
115
|
}
|
|
110
116
|
|
|
111
117
|
// Step 5: Save version in editors-config
|
|
@@ -120,6 +126,101 @@ export async function run(): Promise<SetupResults> {
|
|
|
120
126
|
// Default export for CommonJS require
|
|
121
127
|
export default { run }
|
|
122
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Install status line script with version check
|
|
131
|
+
*/
|
|
132
|
+
async function installStatusLine(): Promise<void> {
|
|
133
|
+
try {
|
|
134
|
+
const claudeDir = path.join(os.homedir(), '.claude')
|
|
135
|
+
const settingsPath = path.join(claudeDir, 'settings.json')
|
|
136
|
+
const statusLinePath = path.join(claudeDir, 'prjct-statusline.sh')
|
|
137
|
+
|
|
138
|
+
// Ensure .claude directory exists
|
|
139
|
+
if (!fs.existsSync(claudeDir)) {
|
|
140
|
+
fs.mkdirSync(claudeDir, { recursive: true })
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Version is embedded at install time
|
|
144
|
+
const scriptContent = `#!/bin/bash
|
|
145
|
+
# prjct Status Line for Claude Code
|
|
146
|
+
# Shows version update notifications and current task
|
|
147
|
+
|
|
148
|
+
# Current CLI version (embedded at install time)
|
|
149
|
+
CLI_VERSION="${VERSION}"
|
|
150
|
+
|
|
151
|
+
# Read JSON context from stdin (provided by Claude Code)
|
|
152
|
+
read -r json
|
|
153
|
+
|
|
154
|
+
# Extract cwd from JSON
|
|
155
|
+
CWD=$(echo "$json" | grep -o '"cwd"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"cwd"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
156
|
+
|
|
157
|
+
# Check if this is a prjct project
|
|
158
|
+
CONFIG="$CWD/.prjct/prjct.config.json"
|
|
159
|
+
if [[ -f "$CONFIG" ]]; then
|
|
160
|
+
# Extract projectId
|
|
161
|
+
PROJECT_ID=$(grep -o '"projectId"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG" | sed 's/.*"projectId"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
162
|
+
|
|
163
|
+
if [[ -n "$PROJECT_ID" ]]; then
|
|
164
|
+
PROJECT_JSON="$HOME/.prjct-cli/projects/$PROJECT_ID/project.json"
|
|
165
|
+
|
|
166
|
+
# Check version mismatch
|
|
167
|
+
if [[ -f "$PROJECT_JSON" ]]; then
|
|
168
|
+
PROJECT_VERSION=$(grep -o '"cliVersion"[[:space:]]*:[[:space:]]*"[^"]*"' "$PROJECT_JSON" | sed 's/.*"cliVersion"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
169
|
+
|
|
170
|
+
# If no cliVersion or different version, show update notice
|
|
171
|
+
if [[ -z "$PROJECT_VERSION" ]] || [[ "$PROJECT_VERSION" != "$CLI_VERSION" ]]; then
|
|
172
|
+
echo "⚠️ prjct v$CLI_VERSION available! Run /p:sync"
|
|
173
|
+
exit 0
|
|
174
|
+
fi
|
|
175
|
+
else
|
|
176
|
+
# No project.json means project needs sync
|
|
177
|
+
echo "⚠️ prjct v$CLI_VERSION available! Run /p:sync"
|
|
178
|
+
exit 0
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
# Show current task if exists
|
|
182
|
+
STATE="$HOME/.prjct-cli/projects/$PROJECT_ID/storage/state.json"
|
|
183
|
+
if [[ -f "$STATE" ]]; then
|
|
184
|
+
TASK=$(grep -o '"description"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"description"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
185
|
+
STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"status"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
186
|
+
|
|
187
|
+
if [[ -n "$TASK" ]] && [[ "$STATUS" == "active" ]]; then
|
|
188
|
+
# Truncate task to 40 chars
|
|
189
|
+
TASK_SHORT="\${TASK:0:40}"
|
|
190
|
+
[[ \${#TASK} -gt 40 ]] && TASK_SHORT="$TASK_SHORT..."
|
|
191
|
+
echo "🎯 $TASK_SHORT"
|
|
192
|
+
exit 0
|
|
193
|
+
fi
|
|
194
|
+
fi
|
|
195
|
+
fi
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
# Default: show prjct branding
|
|
199
|
+
echo "⚡ prjct"
|
|
200
|
+
`
|
|
201
|
+
fs.writeFileSync(statusLinePath, scriptContent, { mode: 0o755 })
|
|
202
|
+
|
|
203
|
+
// Update settings.json to use this status line
|
|
204
|
+
let settings: Record<string, unknown> = {}
|
|
205
|
+
if (fs.existsSync(settingsPath)) {
|
|
206
|
+
try {
|
|
207
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'))
|
|
208
|
+
} catch {
|
|
209
|
+
// Invalid JSON, start fresh
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
settings.statusLine = {
|
|
214
|
+
type: 'command',
|
|
215
|
+
command: statusLinePath
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2))
|
|
219
|
+
} catch {
|
|
220
|
+
// Silently fail - status line is optional
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
123
224
|
/**
|
|
124
225
|
* Show setup results
|
|
125
226
|
*/
|
package/core/schemas/project.ts
CHANGED
|
@@ -19,6 +19,7 @@ export const ProjectItemSchema = z.object({
|
|
|
19
19
|
repoPath: z.string(),
|
|
20
20
|
description: z.string().optional(),
|
|
21
21
|
version: z.string().optional(),
|
|
22
|
+
cliVersion: z.string().optional(), // prjct-cli version used to sync
|
|
22
23
|
techStack: z.array(z.string()),
|
|
23
24
|
fileCount: z.number(),
|
|
24
25
|
commitCount: z.number(),
|