prjct-cli 0.8.6 → 0.8.8
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 +76 -0
- package/CLAUDE.md +34 -0
- package/core/agentic/context-builder.js +4 -3
- package/core/agentic/tool-registry.js +35 -0
- package/core/commands.js +84 -0
- package/core/infrastructure/legacy-installer-detector.js +546 -0
- package/core/infrastructure/session-manager.js +14 -2
- package/core/infrastructure/setup.js +29 -11
- package/core/utils/jsonl-helper.js +137 -0
- package/package.json +1 -1
- package/scripts/install.sh +45 -8
- package/scripts/postinstall.js +5 -5
- package/templates/agents/AGENTS.md +3 -3
- package/templates/commands/ask.md +25 -338
- package/templates/commands/build.md +7 -4
- package/templates/commands/feature.md +19 -160
- package/templates/commands/help.md +41 -299
- package/templates/commands/idea.md +7 -4
- package/templates/commands/init.md +15 -112
- package/templates/commands/migrate-all.md +25 -84
- package/templates/commands/now.md +4 -3
- package/templates/commands/ship.md +20 -86
- package/templates/commands/suggest.md +36 -495
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,82 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.8.8] - 2025-10-06
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **System timestamp tools** - LLM now gets real date/time from system instead of guessing
|
|
15
|
+
- ✅ `GetTimestamp()` tool - Returns ISO timestamp from system clock
|
|
16
|
+
- ✅ `GetDate()` tool - Returns YYYY-MM-DD from system clock
|
|
17
|
+
- ✅ `GetDateTime()` tool - Returns full date/time object with components
|
|
18
|
+
- 🐛 **Bug fixed**: Tasks no longer show January 1st dates when it's October
|
|
19
|
+
- 📊 Impact: Session files now use correct dates, analytics work properly
|
|
20
|
+
|
|
21
|
+
- **Template optimization** - Phase 1 complete: Top 7 critical templates optimized
|
|
22
|
+
- ✅ Reduced from 2006 → 605 lines (69.8% reduction, saved 1401 lines)
|
|
23
|
+
- ✅ All templates now in English only (removed Spanish examples)
|
|
24
|
+
- ✅ Preserved 100% of business logic and decision-making patterns
|
|
25
|
+
- ✅ Removed verbose examples, success criteria, redundant explanations
|
|
26
|
+
- 📊 Impact: Faster LLM processing, lower token usage, clearer instructions
|
|
27
|
+
|
|
28
|
+
- **Legacy installation cleanup** - Automatic detection and removal of curl-based installations
|
|
29
|
+
- ✅ Detects legacy `~/.prjct-cli/` from curl install.sh (pre-v0.8.2)
|
|
30
|
+
- ✅ Migrates project data to npm global location automatically
|
|
31
|
+
- ✅ Removes legacy installation files (bin/, core/, templates/, etc.)
|
|
32
|
+
- ✅ Preserves user data (projects/ directory migrated safely)
|
|
33
|
+
- ✅ Cleans up shell PATH entries (bash/zsh/PowerShell)
|
|
34
|
+
- ✅ Removes legacy symlinks on Unix systems
|
|
35
|
+
- 🎯 **Impact**: Users on old curl installations automatically migrate to npm
|
|
36
|
+
- 🔧 **Windows compatible**: Handles PowerShell profiles, skips Unix-only operations
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **Critical timestamp rule in CLAUDE.md** - Added prominent warning about LLM timestamp limitations
|
|
41
|
+
- LLM knowledge cutoff is January 2025, cannot generate accurate timestamps
|
|
42
|
+
- All templates now include `timestamp-rule` in frontmatter
|
|
43
|
+
- Templates updated: feature.md, ship.md, now.md, build.md, idea.md
|
|
44
|
+
- Hardcoded example dates replaced with GetTimestamp()/GetDate() tool calls
|
|
45
|
+
|
|
46
|
+
- **Templates optimized** (Phase 1 - Top 7)
|
|
47
|
+
- suggest.md: 555 → 96 lines (82.7% reduction)
|
|
48
|
+
- ask.md: 386 → 73 lines (81.1% reduction)
|
|
49
|
+
- help.md: 348 → 90 lines (74.1% reduction)
|
|
50
|
+
- feature.md: 239 → 93 lines (61.1% reduction)
|
|
51
|
+
- init.md: 210 → 113 lines (46.2% reduction)
|
|
52
|
+
- ship.md: 148 → 79 lines (46.6% reduction)
|
|
53
|
+
- migrate-all.md: 120 → 61 lines (49.2% reduction)
|
|
54
|
+
|
|
55
|
+
- **context-builder.js** - Enhanced timestamp documentation
|
|
56
|
+
- Clarified that timestamps come from system clock, not LLM
|
|
57
|
+
- Added inline comments explaining ISO format and YYYY-MM-DD format
|
|
58
|
+
|
|
59
|
+
- **install.sh deprecation** - Enhanced messaging with legacy detection
|
|
60
|
+
- Now detects if user has legacy curl installation
|
|
61
|
+
- Shows version and location of legacy install
|
|
62
|
+
- Provides clear migration instructions
|
|
63
|
+
- Explains automatic cleanup process
|
|
64
|
+
|
|
65
|
+
- **All Spanish removed from codebase** - 100% English documentation
|
|
66
|
+
- Updated all JSDoc comments to English
|
|
67
|
+
- Removed Spanish examples from templates
|
|
68
|
+
- Fixed: setup.js, postinstall.js, AGENTS.md
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
|
|
72
|
+
- **Session date accuracy** - All session files now use correct system date
|
|
73
|
+
- Previously: LLM generated timestamps (often January 1st)
|
|
74
|
+
- Now: System clock provides accurate timestamps via GetTimestamp() tool
|
|
75
|
+
- Duration calculations now accurate
|
|
76
|
+
- Progress tracking and analytics now reliable
|
|
77
|
+
|
|
78
|
+
- **Windows compatibility** - Full cross-platform support
|
|
79
|
+
- Legacy installer detector works on Windows
|
|
80
|
+
- Platform detection via `process.platform === 'win32'`
|
|
81
|
+
- PowerShell profile cleanup (instead of bash/zsh)
|
|
82
|
+
- Skips symlink cleanup on Windows (Unix-only feature)
|
|
83
|
+
- Cross-platform path handling with `os.homedir()` and `path.join()`
|
|
84
|
+
- Command installer already works on Windows (no changes needed)
|
|
85
|
+
|
|
10
86
|
## [0.8.6] - 2025-10-05
|
|
11
87
|
|
|
12
88
|
### Fixed
|
package/CLAUDE.md
CHANGED
|
@@ -6,6 +6,40 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
6
6
|
|
|
7
7
|
**prjct-cli** is a developer momentum tool for solo builders, indie hackers, and small teams (2-5 people). Just ship. No BS. Track progress through slash commands without meetings, ceremonies, or traditional PM overhead.
|
|
8
8
|
|
|
9
|
+
## ⚠️ CRITICAL: Timestamp Management
|
|
10
|
+
|
|
11
|
+
**LLM DOES NOT KNOW CURRENT DATE/TIME** - Your knowledge cutoff is January 2025, and you cannot generate accurate timestamps.
|
|
12
|
+
|
|
13
|
+
### Timestamp Tools (MUST USE)
|
|
14
|
+
|
|
15
|
+
**ALWAYS use these tools for ALL timestamps and dates:**
|
|
16
|
+
|
|
17
|
+
- `GetTimestamp()` → Returns current system time in ISO format (e.g., "2025-10-07T14:30:00.000Z")
|
|
18
|
+
- `GetDate()` → Returns current date in YYYY-MM-DD format (e.g., "2025-10-07")
|
|
19
|
+
- `GetDateTime()` → Returns object with timestamp, date, year, month, day
|
|
20
|
+
|
|
21
|
+
### Rules
|
|
22
|
+
|
|
23
|
+
1. **NEVER generate timestamps manually** - All dates like "2025-10-04" or "2025-01-01" are WRONG
|
|
24
|
+
2. **ALWAYS call GetTimestamp()** when writing to session files (*.jsonl)
|
|
25
|
+
3. **ALWAYS call GetDate()** when adding entries to index files (shipped.md, roadmap.md, ideas.md)
|
|
26
|
+
4. **Templates have `timestamp-rule`** in frontmatter - READ AND FOLLOW IT
|
|
27
|
+
5. **Session files are organized by date** - Use system date to determine correct file path
|
|
28
|
+
|
|
29
|
+
### Example (CORRECT)
|
|
30
|
+
|
|
31
|
+
```jsonl
|
|
32
|
+
{"ts":"{GetTimestamp()}","type":"feature_add","name":"auth","tasks":5}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Example (WRONG - DO NOT DO THIS)
|
|
36
|
+
|
|
37
|
+
```jsonl
|
|
38
|
+
{"ts":"2025-10-04T14:30:00Z","type":"feature_add","name":"auth","tasks":5}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Why this matters**: Without system timestamps, all session data shows January 1st dates, making analytics and progress tracking completely broken.
|
|
42
|
+
|
|
9
43
|
## 🚀 Real-World Workflow (Simplified)
|
|
10
44
|
|
|
11
45
|
prjct follows your **actual** development workflow with 5 essential commands:
|
|
@@ -41,9 +41,10 @@ class ContextBuilder {
|
|
|
41
41
|
// Command parameters
|
|
42
42
|
params: commandParams,
|
|
43
43
|
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
// System timestamps (ALWAYS use these, NEVER generate timestamps)
|
|
45
|
+
// LLM does not know current date/time - these are from system clock
|
|
46
|
+
timestamp: new Date().toISOString(), // ISO format: "2025-10-07T14:30:00.000Z"
|
|
47
|
+
date: new Date().toISOString().split('T')[0], // YYYY-MM-DD: "2025-10-07"
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -9,6 +9,7 @@ const path = require('path')
|
|
|
9
9
|
const { promisify } = require('util')
|
|
10
10
|
const { exec: execCallback } = require('child_process')
|
|
11
11
|
const exec = promisify(execCallback)
|
|
12
|
+
const dateHelper = require('../utils/date-helper')
|
|
12
13
|
|
|
13
14
|
class ToolRegistry {
|
|
14
15
|
constructor() {
|
|
@@ -17,6 +18,9 @@ class ToolRegistry {
|
|
|
17
18
|
Write: this.write.bind(this),
|
|
18
19
|
Bash: this.bash.bind(this),
|
|
19
20
|
Exec: this.bash.bind(this), // Alias
|
|
21
|
+
GetTimestamp: this.getTimestamp.bind(this),
|
|
22
|
+
GetDate: this.getDate.bind(this),
|
|
23
|
+
GetDateTime: this.getDateTime.bind(this),
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
|
|
@@ -112,6 +116,37 @@ class ToolRegistry {
|
|
|
112
116
|
return []
|
|
113
117
|
}
|
|
114
118
|
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get current system timestamp (ISO format)
|
|
122
|
+
* LLM MUST use this instead of generating timestamps
|
|
123
|
+
* @returns {Promise<string>} ISO timestamp (e.g., "2025-10-07T14:30:00.000Z")
|
|
124
|
+
*/
|
|
125
|
+
async getTimestamp() {
|
|
126
|
+
return dateHelper.getTimestamp()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get current system date (YYYY-MM-DD)
|
|
131
|
+
* LLM MUST use this instead of generating dates
|
|
132
|
+
* @returns {Promise<string>} Date string (e.g., "2025-10-07")
|
|
133
|
+
*/
|
|
134
|
+
async getDate() {
|
|
135
|
+
return dateHelper.getTodayKey()
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get current system date/time components
|
|
140
|
+
* @returns {Promise<Object>} Date components {timestamp, date, year, month, day}
|
|
141
|
+
*/
|
|
142
|
+
async getDateTime() {
|
|
143
|
+
const now = new Date()
|
|
144
|
+
return {
|
|
145
|
+
timestamp: dateHelper.getTimestamp(),
|
|
146
|
+
date: dateHelper.getTodayKey(),
|
|
147
|
+
...dateHelper.getYearMonthDay(now),
|
|
148
|
+
}
|
|
149
|
+
}
|
|
115
150
|
}
|
|
116
151
|
|
|
117
152
|
module.exports = new ToolRegistry()
|
package/core/commands.js
CHANGED
|
@@ -1126,6 +1126,81 @@ class PrjctCommands {
|
|
|
1126
1126
|
* /p:design - Design system architecture, APIs, and components
|
|
1127
1127
|
* AGENTIC EXECUTION
|
|
1128
1128
|
*/
|
|
1129
|
+
/**
|
|
1130
|
+
* Memory cleanup helper
|
|
1131
|
+
* Rotates large JSONL files, archives old sessions, reports disk usage
|
|
1132
|
+
* @private
|
|
1133
|
+
*/
|
|
1134
|
+
async _cleanupMemory(projectPath) {
|
|
1135
|
+
const projectId = await configManager.getProjectId(projectPath)
|
|
1136
|
+
const globalPath = pathManager.getGlobalProjectPath(projectId)
|
|
1137
|
+
|
|
1138
|
+
console.log('📊 Analyzing disk usage...\n')
|
|
1139
|
+
|
|
1140
|
+
const results = {
|
|
1141
|
+
rotated: [],
|
|
1142
|
+
archived: [],
|
|
1143
|
+
totalSize: 0,
|
|
1144
|
+
freedSpace: 0,
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
// 1. Check and rotate large JSONL files
|
|
1148
|
+
const jsonlFiles = [
|
|
1149
|
+
pathManager.getFilePath(projectId, 'memory', 'context.jsonl'),
|
|
1150
|
+
pathManager.getFilePath(projectId, 'progress', 'shipped.md'),
|
|
1151
|
+
pathManager.getFilePath(projectId, 'planning', 'ideas.md'),
|
|
1152
|
+
]
|
|
1153
|
+
|
|
1154
|
+
for (const filePath of jsonlFiles) {
|
|
1155
|
+
try {
|
|
1156
|
+
const sizeMB = await jsonlHelper.getFileSizeMB(filePath)
|
|
1157
|
+
if (sizeMB > 0) {
|
|
1158
|
+
results.totalSize += sizeMB
|
|
1159
|
+
|
|
1160
|
+
const rotated = await jsonlHelper.rotateJsonLinesIfNeeded(filePath, 10)
|
|
1161
|
+
if (rotated) {
|
|
1162
|
+
results.rotated.push(path.basename(filePath))
|
|
1163
|
+
results.freedSpace += sizeMB
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
} catch (error) {
|
|
1167
|
+
// File doesn't exist, skip
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
// 2. Report disk usage
|
|
1172
|
+
console.log('💾 Disk Usage Report:\n')
|
|
1173
|
+
console.log(` Total size: ${results.totalSize.toFixed(2)}MB`)
|
|
1174
|
+
console.log(` Rotated files: ${results.rotated.length}`)
|
|
1175
|
+
|
|
1176
|
+
if (results.rotated.length > 0) {
|
|
1177
|
+
console.log(` Freed space: ${results.freedSpace.toFixed(2)}MB\n`)
|
|
1178
|
+
results.rotated.forEach((file) => console.log(` ✓ ${file}`))
|
|
1179
|
+
} else {
|
|
1180
|
+
console.log(' ✓ No rotation needed - all files under 10MB\n')
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
// 3. Suggestions
|
|
1184
|
+
console.log('\n💡 Recommendations:\n')
|
|
1185
|
+
console.log(' 1. Claude Code: Compact conversation regularly')
|
|
1186
|
+
console.log(' 2. Exclude from Spotlight: System Settings → Privacy')
|
|
1187
|
+
console.log(' 3. Clear npm cache: npm cache clean --force\n')
|
|
1188
|
+
|
|
1189
|
+
return { success: true, results }
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
/**
|
|
1193
|
+
* Internal cleanup helper for memory during normal cleanup
|
|
1194
|
+
* @private
|
|
1195
|
+
*/
|
|
1196
|
+
async _cleanupMemoryInternal(projectPath) {
|
|
1197
|
+
const projectId = await configManager.getProjectId(projectPath)
|
|
1198
|
+
|
|
1199
|
+
// Silently rotate large files
|
|
1200
|
+
const memoryPath = pathManager.getFilePath(projectId, 'memory', 'context.jsonl')
|
|
1201
|
+
await jsonlHelper.rotateJsonLinesIfNeeded(memoryPath, 10)
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1129
1204
|
async design(target = null, options = {}, projectPath = process.cwd()) {
|
|
1130
1205
|
try {
|
|
1131
1206
|
const initResult = await this.ensureProjectInit(projectPath)
|
|
@@ -1575,6 +1650,13 @@ Process flow for ${target}.
|
|
|
1575
1650
|
const initResult = await this.ensureProjectInit(projectPath)
|
|
1576
1651
|
if (!initResult.success) return initResult
|
|
1577
1652
|
|
|
1653
|
+
const isMemoryMode = _options.memory === true || _options.type === 'memory'
|
|
1654
|
+
|
|
1655
|
+
if (isMemoryMode) {
|
|
1656
|
+
console.log('🧹 Memory cleanup...\n')
|
|
1657
|
+
return await this._cleanupMemory(projectPath)
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1578
1660
|
console.log('🧹 Cleaning up project...\n')
|
|
1579
1661
|
|
|
1580
1662
|
const context = await contextBuilder.build(projectPath)
|
|
@@ -1649,6 +1731,8 @@ Process flow for ${target}.
|
|
|
1649
1731
|
console.log('✅ Cleanup complete!\n')
|
|
1650
1732
|
cleaned.forEach((item) => console.log(` • ${item}`))
|
|
1651
1733
|
|
|
1734
|
+
await this._cleanupMemoryInternal(projectPath)
|
|
1735
|
+
|
|
1652
1736
|
await this.logToMemory(projectPath, 'cleanup_performed', {
|
|
1653
1737
|
items: cleaned.length,
|
|
1654
1738
|
timestamp: dateHelper.getTimestamp(),
|