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 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
- // Timestamps
45
- timestamp: new Date().toISOString(),
46
- date: new Date().toLocaleString(),
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(),