prjct-cli 0.10.9 → 0.10.10
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 +35 -0
- package/CLAUDE.md +121 -996
- package/core/agentic/prompt-builder.js +57 -56
- package/package.json +1 -1
- package/templates/analysis/patterns.md +27 -173
- package/templates/commands/done.md +129 -15
- package/templates/commands/feature.md +262 -21
- package/templates/commands/ship.md +244 -23
- package/templates/commands/sync.md +235 -44
|
@@ -24,41 +24,18 @@ class PromptBuilder {
|
|
|
24
24
|
// Store context for use in helper methods
|
|
25
25
|
this._currentContext = context
|
|
26
26
|
|
|
27
|
-
// Agent assignment (
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (agent.domain) {
|
|
40
|
-
parts.push(`Domain: ${agent.domain}\n`)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Include skills if available
|
|
44
|
-
if (agent.skills && agent.skills.length > 0) {
|
|
45
|
-
parts.push(`Skills: ${agent.skills.join(', ')}\n`)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
parts.push(`\n## AGENT INSTRUCTIONS\n`)
|
|
49
|
-
|
|
50
|
-
// CRITICAL: Include full agent content
|
|
51
|
-
// This is the specialized knowledge for this project
|
|
52
|
-
if (agent.content) {
|
|
53
|
-
parts.push(agent.content)
|
|
54
|
-
parts.push(`\n`)
|
|
55
|
-
} else if (agent.name) {
|
|
56
|
-
// Fallback if content not loaded
|
|
57
|
-
parts.push(`You are the ${agent.name} agent for this project.\n`)
|
|
58
|
-
parts.push(`Apply your specialized expertise to complete the task.\n\n`)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
parts.push(`CONTEXT: ${context.filteredSize || 'all'} files (${context.reduction || 0}% reduced)\n\n`)
|
|
27
|
+
// Agent assignment (CONDITIONAL - only for code-modifying commands)
|
|
28
|
+
// Commands like done, ship, recap, next don't need specialized agents
|
|
29
|
+
const commandName = template.frontmatter?.name?.replace('p:', '') || ''
|
|
30
|
+
const agentCommands = ['now', 'build', 'feature', 'design', 'fix', 'bug', 'test', 'work', 'cleanup', 'spec']
|
|
31
|
+
const needsAgent = agentCommands.includes(commandName)
|
|
32
|
+
|
|
33
|
+
if (agent && needsAgent) {
|
|
34
|
+
// COMPRESSED: Only essential agent info (500 bytes vs 3-5KB)
|
|
35
|
+
parts.push(`# AGENT: ${agent.name}\n`)
|
|
36
|
+
if (agent.role) parts.push(`Role: ${agent.role}\n`)
|
|
37
|
+
if (agent.skills?.length) parts.push(`Skills: ${agent.skills.join(', ')}\n`)
|
|
38
|
+
parts.push(`\nApply specialized expertise. Read agent file for details if needed.\n\n`)
|
|
62
39
|
}
|
|
63
40
|
|
|
64
41
|
// Core instruction (concise)
|
|
@@ -93,38 +70,30 @@ class PromptBuilder {
|
|
|
93
70
|
parts.push('\n')
|
|
94
71
|
}
|
|
95
72
|
|
|
96
|
-
//
|
|
97
|
-
if (context.files
|
|
98
|
-
|
|
99
|
-
parts.push(
|
|
100
|
-
parts.push('
|
|
101
|
-
parts.push('\nTop relevant files:\n')
|
|
102
|
-
const topFiles = context.files.slice(0, 20).map(f => `- ${f}`).join('\n')
|
|
103
|
-
parts.push(topFiles)
|
|
104
|
-
if (context.files.length > 20) {
|
|
105
|
-
parts.push(`\n... and ${context.files.length - 20} more files. Use Read tool to access them.\n`)
|
|
106
|
-
}
|
|
107
|
-
parts.push('\n')
|
|
73
|
+
// COMPRESSED: File list (5 files vs 20, saves ~400 bytes)
|
|
74
|
+
if (context.files?.length > 0) {
|
|
75
|
+
const top5 = context.files.slice(0, 5).join(', ')
|
|
76
|
+
parts.push(`\n## FILES: ${context.files.length} available. Top: ${top5}\n`)
|
|
77
|
+
parts.push('Read BEFORE modifying. Use Glob/Grep to find more.\n\n')
|
|
108
78
|
} else if (context.projectPath) {
|
|
109
|
-
parts.push(
|
|
110
|
-
parts.push(`Project path: ${context.projectPath}\n`)
|
|
111
|
-
parts.push('**USE Read TOOL TO LOAD FILES YOU NEED TO UNDERSTAND OR MODIFY.**\n')
|
|
112
|
-
parts.push('**NEVER MODIFY CODE WITHOUT READING IT FIRST.**\n\n')
|
|
79
|
+
parts.push(`\n## PROJECT: ${context.projectPath}\nRead files before modifying.\n\n`)
|
|
113
80
|
}
|
|
114
81
|
|
|
115
82
|
// OPTIMIZED: Only include patterns for code-modifying commands
|
|
116
83
|
// Commands like done, ship, recap, next don't need full patterns
|
|
117
84
|
const codeCommands = ['now', 'build', 'feature', 'design', 'cleanup', 'fix', 'bug', 'test', 'init', 'spec', 'work']
|
|
118
|
-
const commandName = template.frontmatter?.name?.replace('p:', '') || ''
|
|
119
85
|
const needsPatterns = codeCommands.includes(commandName)
|
|
120
86
|
|
|
121
87
|
// Include code patterns analysis for code-modifying commands
|
|
88
|
+
// COMPRESSED: Extract only conventions and anti-patterns (800 bytes max vs 6KB)
|
|
122
89
|
const codePatternsContent = state?.codePatterns || ''
|
|
123
90
|
if (needsPatterns && codePatternsContent && codePatternsContent.trim()) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
91
|
+
const patternSummary = this.extractPatternSummary(codePatternsContent)
|
|
92
|
+
if (patternSummary) {
|
|
93
|
+
parts.push('\n## CODE PATTERNS\n')
|
|
94
|
+
parts.push(patternSummary)
|
|
95
|
+
parts.push('\nFull patterns: Read analysis/patterns.md\n')
|
|
96
|
+
}
|
|
128
97
|
}
|
|
129
98
|
|
|
130
99
|
const analysisContent = state?.analysis || ''
|
|
@@ -243,6 +212,38 @@ class PromptBuilder {
|
|
|
243
212
|
return parts.join('')
|
|
244
213
|
}
|
|
245
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Extract pattern summary from full patterns content
|
|
217
|
+
* OPTIMIZED: Returns only conventions + high-priority anti-patterns (800 bytes max)
|
|
218
|
+
*/
|
|
219
|
+
extractPatternSummary(content) {
|
|
220
|
+
if (!content) return null
|
|
221
|
+
|
|
222
|
+
const parts = []
|
|
223
|
+
|
|
224
|
+
// Extract conventions section
|
|
225
|
+
const conventionsMatch = content.match(/## Conventions[\s\S]*?(?=##|$)/i)
|
|
226
|
+
if (conventionsMatch) {
|
|
227
|
+
// Compress to key lines only
|
|
228
|
+
const conventions = conventionsMatch[0]
|
|
229
|
+
.split('\n')
|
|
230
|
+
.filter(line => line.includes(':') || line.startsWith('-'))
|
|
231
|
+
.slice(0, 6)
|
|
232
|
+
.join('\n')
|
|
233
|
+
if (conventions) parts.push(conventions)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Extract high priority anti-patterns only
|
|
237
|
+
const antiPatternsMatch = content.match(/### High Priority[\s\S]*?(?=###|##|$)/i)
|
|
238
|
+
if (antiPatternsMatch) {
|
|
239
|
+
const antiPatterns = antiPatternsMatch[0].substring(0, 300)
|
|
240
|
+
parts.push('\nAvoid:\n' + antiPatterns)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const result = parts.join('\n').substring(0, 800)
|
|
244
|
+
return result || null
|
|
245
|
+
}
|
|
246
|
+
|
|
246
247
|
/**
|
|
247
248
|
* Build critical rules - compressed anti-hallucination
|
|
248
249
|
* OPTIMIZED: From 66 lines to 12 lines (~82% reduction)
|
package/package.json
CHANGED
|
@@ -1,142 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
allowed-tools: [Read, Glob, Grep]
|
|
3
|
-
description: 'Analyze code patterns
|
|
3
|
+
description: 'Analyze code patterns and conventions'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Code Pattern Analysis
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Detection Steps
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
1. **Structure** (5-10 files): File org, exports, modules
|
|
11
|
+
2. **Patterns**: SOLID, DRY, factory/singleton/observer
|
|
12
|
+
3. **Conventions**: Naming, style, error handling, async
|
|
13
|
+
4. **Anti-patterns**: God class, spaghetti, copy-paste, magic numbers
|
|
14
|
+
5. **Performance**: Memoization, N+1 queries, leaks
|
|
11
15
|
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
### File Organization
|
|
15
|
-
- Read 5-10 representative source files
|
|
16
|
-
- Identify: single vs multiple exports per file
|
|
17
|
-
- Check: file size patterns (small focused files vs large files)
|
|
18
|
-
- Note: directory organization (by feature, by layer, by type)
|
|
19
|
-
|
|
20
|
-
### Module Patterns
|
|
21
|
-
- ES Modules vs CommonJS
|
|
22
|
-
- Default exports vs named exports
|
|
23
|
-
- Barrel files (index.js re-exports)
|
|
24
|
-
- Circular dependency patterns
|
|
25
|
-
|
|
26
|
-
## Step 2: Detect Design Patterns
|
|
27
|
-
|
|
28
|
-
### SOLID Principles
|
|
29
|
-
Analyze for evidence of:
|
|
30
|
-
|
|
31
|
-
| Principle | Look For | Example |
|
|
32
|
-
|-----------|----------|---------|
|
|
33
|
-
| **S**ingle Responsibility | Small, focused files/functions | `validateUser()` not `validateAndSaveUser()` |
|
|
34
|
-
| **O**pen/Closed | Extension points, plugins | Base classes, strategy pattern |
|
|
35
|
-
| **L**iskov Substitution | Interface consistency | Subclasses behave like parents |
|
|
36
|
-
| **I**nterface Segregation | Small, specific interfaces | Multiple small interfaces vs one large |
|
|
37
|
-
| **D**ependency Inversion | Dependency injection | Constructor injection, factories |
|
|
38
|
-
|
|
39
|
-
### DRY (Don't Repeat Yourself)
|
|
40
|
-
- Check for utility/helper directories
|
|
41
|
-
- Look for shared constants
|
|
42
|
-
- Identify reusable components/functions
|
|
43
|
-
- Note any obvious duplication
|
|
44
|
-
|
|
45
|
-
### Other Patterns
|
|
46
|
-
- Factory pattern (createX functions)
|
|
47
|
-
- Singleton pattern (shared instances)
|
|
48
|
-
- Observer pattern (event emitters)
|
|
49
|
-
- Repository pattern (data access layer)
|
|
50
|
-
- Strategy pattern (interchangeable algorithms)
|
|
51
|
-
|
|
52
|
-
## Step 3: Identify Conventions
|
|
53
|
-
|
|
54
|
-
### Naming Conventions
|
|
55
|
-
```
|
|
56
|
-
Analyze actual code for:
|
|
57
|
-
- Functions: camelCase, snake_case, PascalCase?
|
|
58
|
-
- Classes: PascalCase?
|
|
59
|
-
- Constants: UPPER_SNAKE_CASE?
|
|
60
|
-
- Files: kebab-case, camelCase, PascalCase?
|
|
61
|
-
- Private members: _prefix, #private?
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Code Style
|
|
65
|
-
- Semicolons: yes/no
|
|
66
|
-
- Quotes: single/double
|
|
67
|
-
- Indentation: tabs/spaces (2/4)
|
|
68
|
-
- Trailing commas: yes/no
|
|
69
|
-
- Max line length observed
|
|
70
|
-
|
|
71
|
-
### Error Handling
|
|
72
|
-
- Try-catch patterns
|
|
73
|
-
- Custom error classes
|
|
74
|
-
- Error propagation (throw vs return)
|
|
75
|
-
- Logging patterns
|
|
76
|
-
|
|
77
|
-
### Async Patterns
|
|
78
|
-
- async/await vs Promises vs callbacks
|
|
79
|
-
- Error handling in async code
|
|
80
|
-
- Parallel execution patterns
|
|
81
|
-
|
|
82
|
-
## Step 4: Detect Anti-Patterns
|
|
83
|
-
|
|
84
|
-
### Code Smells (Flag These)
|
|
85
|
-
|
|
86
|
-
| Anti-Pattern | Detection | Severity |
|
|
87
|
-
|--------------|-----------|----------|
|
|
88
|
-
| **God Class/File** | File > 300 lines, too many responsibilities | HIGH |
|
|
89
|
-
| **Spaghetti Code** | Deep nesting > 4 levels, unclear flow | HIGH |
|
|
90
|
-
| **Copy-Paste Code** | Duplicate blocks across files | MEDIUM |
|
|
91
|
-
| **Magic Numbers** | Hardcoded values without constants | MEDIUM |
|
|
92
|
-
| **Long Functions** | Function > 50 lines | MEDIUM |
|
|
93
|
-
| **Too Many Parameters** | Function with > 4 params | LOW |
|
|
94
|
-
| **Dead Code** | Commented out code, unused exports | LOW |
|
|
95
|
-
| **Mixed Concerns** | I/O mixed with business logic | MEDIUM |
|
|
96
|
-
| **Callback Hell** | Nested callbacks > 3 levels | HIGH |
|
|
97
|
-
| **Mutable Global State** | Global variables modified everywhere | HIGH |
|
|
98
|
-
|
|
99
|
-
### Architecture Smells
|
|
100
|
-
|
|
101
|
-
| Anti-Pattern | Detection | Recommendation |
|
|
102
|
-
|--------------|-----------|----------------|
|
|
103
|
-
| **Circular Dependencies** | A imports B, B imports A | Extract shared module |
|
|
104
|
-
| **Feature Envy** | Function uses other module's data excessively | Move function to that module |
|
|
105
|
-
| **Inappropriate Intimacy** | Classes know too much about each other | Use interfaces/abstractions |
|
|
106
|
-
| **Lazy Class** | Class does almost nothing | Merge with related class |
|
|
107
|
-
| **Speculative Generality** | Unused abstractions "for future" | Remove until needed |
|
|
108
|
-
|
|
109
|
-
## Step 5: Performance Patterns
|
|
110
|
-
|
|
111
|
-
### Good Patterns to Note
|
|
112
|
-
- Memoization usage
|
|
113
|
-
- Lazy loading
|
|
114
|
-
- Caching strategies
|
|
115
|
-
- Batch operations
|
|
116
|
-
- Connection pooling
|
|
117
|
-
|
|
118
|
-
### Performance Anti-Patterns
|
|
119
|
-
- N+1 queries
|
|
120
|
-
- Synchronous I/O in loops
|
|
121
|
-
- Memory leaks (unclosed resources)
|
|
122
|
-
- Unbounded data structures
|
|
123
|
-
|
|
124
|
-
## Output Format
|
|
125
|
-
|
|
126
|
-
Generate `analysis/patterns.md` with:
|
|
16
|
+
## Output: analysis/patterns.md
|
|
127
17
|
|
|
128
18
|
```markdown
|
|
129
|
-
# Code Patterns - {Project
|
|
19
|
+
# Code Patterns - {Project}
|
|
130
20
|
|
|
131
|
-
>
|
|
132
|
-
> Last analyzed: {timestamp}
|
|
21
|
+
> Generated: {GetTimestamp()}
|
|
133
22
|
|
|
134
|
-
##
|
|
23
|
+
## Patterns Detected
|
|
24
|
+
- **{Pattern}**: {Where} - {Example}
|
|
135
25
|
|
|
136
|
-
|
|
137
|
-
- **{Pattern}**: {Where used} - {Example}
|
|
138
|
-
|
|
139
|
-
### SOLID Compliance
|
|
26
|
+
## SOLID Compliance
|
|
140
27
|
| Principle | Status | Evidence |
|
|
141
28
|
|-----------|--------|----------|
|
|
142
29
|
| Single Responsibility | ✅/⚠️/❌ | {evidence} |
|
|
@@ -146,61 +33,28 @@ Generate `analysis/patterns.md` with:
|
|
|
146
33
|
| Dependency Inversion | ✅/⚠️/❌ | {evidence} |
|
|
147
34
|
|
|
148
35
|
## Conventions (MUST FOLLOW)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
-
|
|
152
|
-
- Classes: {convention}
|
|
153
|
-
- Files: {convention}
|
|
154
|
-
- Constants: {convention}
|
|
155
|
-
|
|
156
|
-
### Style
|
|
157
|
-
- Semicolons: {yes/no}
|
|
36
|
+
- Functions: {camelCase/snake_case}
|
|
37
|
+
- Classes: {PascalCase}
|
|
38
|
+
- Files: {kebab-case/camelCase}
|
|
158
39
|
- Quotes: {single/double}
|
|
159
|
-
- Async: {async-await/promises
|
|
160
|
-
|
|
161
|
-
### Structure
|
|
162
|
-
- Exports: {single/multiple per file}
|
|
163
|
-
- Max file size: {observed max}
|
|
164
|
-
- Directory organization: {pattern}
|
|
40
|
+
- Async: {async-await/promises}
|
|
165
41
|
|
|
166
|
-
## Anti-Patterns
|
|
42
|
+
## Anti-Patterns ⚠️
|
|
167
43
|
|
|
168
44
|
### High Priority
|
|
169
|
-
1. **{
|
|
170
|
-
- Problem: {description}
|
|
171
|
-
- Fix: {recommendation}
|
|
45
|
+
1. **{Issue}**: {file:line} - Fix: {action}
|
|
172
46
|
|
|
173
47
|
### Medium Priority
|
|
174
|
-
1. **{
|
|
175
|
-
- Problem: {description}
|
|
176
|
-
- Fix: {recommendation}
|
|
48
|
+
1. **{Issue}**: {file:line} - Fix: {action}
|
|
177
49
|
|
|
178
50
|
## Recommendations
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
1. {Action with specific file/location}
|
|
182
|
-
|
|
183
|
-
### Best Practices for New Code
|
|
184
|
-
1. {Practice based on detected patterns}
|
|
185
|
-
2. {Practice based on conventions}
|
|
186
|
-
3. {Practice to avoid anti-patterns}
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
**IMPORTANT**: All new code MUST follow these patterns and conventions.
|
|
51
|
+
1. {Immediate action}
|
|
52
|
+
2. {Best practice}
|
|
191
53
|
```
|
|
192
54
|
|
|
193
|
-
##
|
|
194
|
-
|
|
195
|
-
When generating new code, Claude MUST:
|
|
196
|
-
|
|
197
|
-
1. **Check patterns.md FIRST** before writing any code
|
|
198
|
-
2. **Match naming conventions** exactly as detected
|
|
199
|
-
3. **Follow file structure** patterns (size, organization)
|
|
200
|
-
4. **Apply detected design patterns** where appropriate
|
|
201
|
-
5. **NEVER introduce anti-patterns** listed in the analysis
|
|
202
|
-
6. **Warn if asked to violate** established patterns
|
|
203
|
-
|
|
204
|
-
---
|
|
55
|
+
## Rules
|
|
205
56
|
|
|
206
|
-
|
|
57
|
+
1. Check patterns.md FIRST before writing code
|
|
58
|
+
2. Match conventions exactly
|
|
59
|
+
3. NEVER introduce anti-patterns
|
|
60
|
+
4. Warn if asked to violate patterns
|
|
@@ -1,23 +1,137 @@
|
|
|
1
1
|
---
|
|
2
2
|
allowed-tools: [Read, Write]
|
|
3
|
-
description: 'Complete task'
|
|
4
|
-
|
|
3
|
+
description: 'Complete current task'
|
|
4
|
+
timestamp-rule: 'GetTimestamp() for all timestamps'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# /p:done
|
|
7
|
+
# /p:done - Complete Current Task
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
## Context Variables
|
|
10
|
+
- `{projectId}`: From `.prjct/prjct.config.json`
|
|
11
|
+
- `{globalPath}`: `~/.prjct-cli/projects/{projectId}`
|
|
12
|
+
- `{nowPath}`: `{globalPath}/core/now.md`
|
|
13
|
+
- `{memoryPath}`: `{globalPath}/memory/context.jsonl`
|
|
14
|
+
- `{metricsPath}`: `{globalPath}/progress/metrics.md`
|
|
14
15
|
|
|
15
|
-
##
|
|
16
|
-
Requires: `core/now.md` has content
|
|
16
|
+
## Step 1: Read Config
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
2. Clear now.md → Update metrics → Log
|
|
18
|
+
READ: `.prjct/prjct.config.json`
|
|
19
|
+
EXTRACT: `projectId`
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
IF file not found:
|
|
22
|
+
OUTPUT: "No prjct project. Run /p:init first."
|
|
23
|
+
STOP
|
|
24
|
+
|
|
25
|
+
## Step 2: Validate Active Task
|
|
26
|
+
|
|
27
|
+
READ: `{nowPath}`
|
|
28
|
+
|
|
29
|
+
IF empty OR contains "No current task":
|
|
30
|
+
OUTPUT: "⚠️ No active task to complete. Use /p:now to start one."
|
|
31
|
+
STOP
|
|
32
|
+
|
|
33
|
+
## Step 3: Extract Task Data
|
|
34
|
+
|
|
35
|
+
From NOW file content, extract:
|
|
36
|
+
|
|
37
|
+
1. **Task name**: Text between `**` markers
|
|
38
|
+
- Pattern: `**(.+?)**`
|
|
39
|
+
- Example: `**implement auth**` → "implement auth"
|
|
40
|
+
|
|
41
|
+
2. **Start time**: Text after "Started:"
|
|
42
|
+
- Pattern: `Started: (.+)`
|
|
43
|
+
- Example: `Started: 11/28/2025, 2:30:00 PM`
|
|
44
|
+
|
|
45
|
+
3. **Calculate duration**:
|
|
46
|
+
- Current: GetTimestamp()
|
|
47
|
+
- Duration: current - started
|
|
48
|
+
- Format: "Xh Ym" (e.g., "2h 15m")
|
|
49
|
+
- If < 1 hour: "Xm"
|
|
50
|
+
- If < 1 minute: "< 1m"
|
|
51
|
+
|
|
52
|
+
## Step 4: Clear Task File
|
|
53
|
+
|
|
54
|
+
WRITE: `{nowPath}`
|
|
55
|
+
|
|
56
|
+
Content (exact):
|
|
57
|
+
```markdown
|
|
58
|
+
# NOW
|
|
59
|
+
|
|
60
|
+
No current task. Use `/p:now` to set focus.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Step 5: Log to Memory
|
|
64
|
+
|
|
65
|
+
APPEND to: `{memoryPath}`
|
|
66
|
+
|
|
67
|
+
Single line (JSONL format):
|
|
68
|
+
```json
|
|
69
|
+
{"timestamp":"{GetTimestamp()}","action":"task_completed","task":"{task}","duration":"{duration}"}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Step 6: Update Metrics (Optional)
|
|
73
|
+
|
|
74
|
+
IF `{metricsPath}` exists:
|
|
75
|
+
READ current content
|
|
76
|
+
APPEND new entry with task and duration
|
|
77
|
+
|
|
78
|
+
## Output
|
|
79
|
+
|
|
80
|
+
SUCCESS:
|
|
81
|
+
```
|
|
82
|
+
✅ {task} ({duration})
|
|
83
|
+
|
|
84
|
+
Next:
|
|
85
|
+
• /p:now - Start next task
|
|
86
|
+
• /p:ship - Ship completed work
|
|
87
|
+
• /p:next - See priority queue
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Error Handling
|
|
91
|
+
|
|
92
|
+
| Error | Response |
|
|
93
|
+
|-------|----------|
|
|
94
|
+
| Config not found | "No prjct project. Run /p:init first." |
|
|
95
|
+
| Now.md empty | "⚠️ No active task. Use /p:now to start." |
|
|
96
|
+
| Parse fails | Use task = "task", duration = "unknown", continue |
|
|
97
|
+
| Write fails | Log warning, continue (non-critical) |
|
|
98
|
+
|
|
99
|
+
## Examples
|
|
100
|
+
|
|
101
|
+
### Example 1: Success
|
|
102
|
+
**now.md content:**
|
|
103
|
+
```
|
|
104
|
+
# NOW
|
|
105
|
+
|
|
106
|
+
**implement authentication**
|
|
107
|
+
|
|
108
|
+
Started: 11/28/2025, 12:15:00 PM
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Current time:** 11/28/2025, 2:30:00 PM
|
|
112
|
+
**Duration:** 2h 15m
|
|
113
|
+
**Output:** `✅ implement authentication (2h 15m)`
|
|
114
|
+
|
|
115
|
+
### Example 2: No Task
|
|
116
|
+
**now.md content:**
|
|
117
|
+
```
|
|
118
|
+
# NOW
|
|
119
|
+
|
|
120
|
+
No current task.
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Output:** `⚠️ No active task to complete. Use /p:now to start one.`
|
|
124
|
+
|
|
125
|
+
### Example 3: Quick Task
|
|
126
|
+
**now.md content:**
|
|
127
|
+
```
|
|
128
|
+
# NOW
|
|
129
|
+
|
|
130
|
+
**fix typo in readme**
|
|
131
|
+
|
|
132
|
+
Started: 11/28/2025, 2:25:00 PM
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Current time:** 11/28/2025, 2:30:00 PM
|
|
136
|
+
**Duration:** 5m
|
|
137
|
+
**Output:** `✅ fix typo in readme (5m)`
|