prjct-cli 2.59.0 → 2.61.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 CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.61.0] - 2026-06-23
6
+
7
+ ### Added
8
+ - Improve prjct-cli maintainability performance and UX
9
+
10
+ ## [2.60.0] - 2026-06-22
11
+
12
+ ### Added
13
+ - update tolerates legacy project dbs
14
+
5
15
  ## [2.59.0] - 2026-06-22
6
16
 
7
17
  ### Fixed
package/bin/prjct.cjs CHANGED
@@ -16,7 +16,11 @@ const path = require('node:path')
16
16
  const SCRIPT_PATH = fs.realpathSync(__filename)
17
17
  const SCRIPT_DIR = path.dirname(SCRIPT_PATH)
18
18
  const ROOT_DIR = path.resolve(SCRIPT_DIR, '..')
19
- const HOME = os.homedir()
19
+ const HOME = process.env.HOME || process.env.USERPROFILE || os.homedir()
20
+ const CLI_HOME = process.env.PRJCT_CLI_HOME
21
+ ? path.resolve(process.env.PRJCT_CLI_HOME)
22
+ : path.join(HOME, '.prjct-cli')
23
+ const SETUP_STAMP_PATH = path.join(CLI_HOME, 'state', 'setup-version.json')
20
24
 
21
25
  function pathEntries() {
22
26
  return (process.env.PATH || '').split(path.delimiter).filter(Boolean)
@@ -114,12 +118,76 @@ function copyDirContents(srcDir, destDir) {
114
118
  }
115
119
  }
116
120
 
121
+ function packageVersion() {
122
+ try {
123
+ return JSON.parse(fs.readFileSync(path.join(ROOT_DIR, 'package.json'), 'utf-8')).version || ''
124
+ } catch {
125
+ return ''
126
+ }
127
+ }
128
+
129
+ function fileMissingWhenSourceExists(src, dest) {
130
+ try {
131
+ return fs.existsSync(src) && !fs.existsSync(dest)
132
+ } catch {
133
+ return false
134
+ }
135
+ }
136
+
137
+ function readSetupStamp() {
138
+ try {
139
+ return JSON.parse(fs.readFileSync(SETUP_STAMP_PATH, 'utf-8'))
140
+ } catch {
141
+ return null
142
+ }
143
+ }
144
+
145
+ function writeSetupStamp(version) {
146
+ try {
147
+ fs.mkdirSync(path.dirname(SETUP_STAMP_PATH), { recursive: true })
148
+ fs.writeFileSync(
149
+ SETUP_STAMP_PATH,
150
+ `${JSON.stringify({ version, completedAt: new Date().toISOString() }, null, 2)}\n`,
151
+ 'utf-8'
152
+ )
153
+ } catch {
154
+ /* best effort */
155
+ }
156
+ }
157
+
158
+ function shouldRunSetup(version) {
159
+ const stamp = readSetupStamp()
160
+ if (!stamp || stamp.version !== version) return true
161
+
162
+ if (fs.existsSync(path.join(HOME, '.claude', 'commands', 'p.md'))) return true
163
+ if (fs.existsSync(path.join(HOME, '.gemini', 'commands', 'p.toml'))) return true
164
+
165
+ const statuslineSrc = path.join(ROOT_DIR, 'assets', 'statusline', 'statusline.sh')
166
+ const statuslineDest = path.join(CLI_HOME, 'statusline', 'statusline.sh')
167
+ if (fileMissingWhenSourceExists(statuslineSrc, statuslineDest)) return true
168
+
169
+ const claudeSkillSrc = path.join(ROOT_DIR, 'templates', 'skills', 'prjct', 'SKILL.md')
170
+ const claudeSkillDest = path.join(HOME, '.claude', 'skills', 'prjct', 'SKILL.md')
171
+ if (fileMissingWhenSourceExists(claudeSkillSrc, claudeSkillDest)) return true
172
+
173
+ const codexSkillSrc = path.join(ROOT_DIR, 'templates', 'codex', 'SKILL.md')
174
+ const codexSkillDest = path.join(HOME, '.codex', 'skills', 'prjct', 'SKILL.md')
175
+ if (
176
+ fs.existsSync(path.join(HOME, '.codex')) &&
177
+ fileMissingWhenSourceExists(codexSkillSrc, codexSkillDest)
178
+ ) {
179
+ return true
180
+ }
181
+
182
+ return false
183
+ }
184
+
117
185
  function ensureSetup() {
118
186
  removeIfExists(path.join(HOME, '.claude', 'commands', 'p.md'))
119
187
  removeIfExists(path.join(HOME, '.gemini', 'commands', 'p.toml'))
120
188
 
121
189
  const statuslineSrc = path.join(ROOT_DIR, 'assets', 'statusline', 'statusline.sh')
122
- const statuslineDir = path.join(HOME, '.prjct-cli', 'statusline')
190
+ const statuslineDir = path.join(CLI_HOME, 'statusline')
123
191
  const statuslineDest = path.join(statuslineDir, 'statusline.sh')
124
192
  const claudeStatusline = path.join(HOME, '.claude', 'prjct-statusline.sh')
125
193
 
@@ -241,7 +309,22 @@ function main() {
241
309
  const args = process.argv.slice(2)
242
310
  if (args[0] === 'mcp-server') runMcpServer(args)
243
311
 
244
- ensureSetup()
312
+ const setupSkipCommands = new Set([
313
+ '-v',
314
+ '--version',
315
+ 'version',
316
+ '-h',
317
+ '--help',
318
+ 'help',
319
+ 'hook',
320
+ '__internal-auto-update',
321
+ '__post-upgrade',
322
+ ])
323
+ const version = packageVersion()
324
+ if (!setupSkipCommands.has(args[0]) && shouldRunSetup(version)) {
325
+ ensureSetup()
326
+ writeSetupStamp(version)
327
+ }
245
328
 
246
329
  if (runWithBun(args)) return
247
330
  runWithNode(args)