prjct-cli 0.29.5 → 0.29.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.
@@ -48,39 +48,8 @@ load_config
48
48
  load_theme
49
49
  parse_stdin "$INPUT"
50
50
 
51
- # ============================================================================
52
- # Version Check - Show update notification if needed
53
- # ============================================================================
54
- check_version_upgrade() {
55
- local config_file="${CWD}/.prjct/prjct.config.json"
56
-
57
- [[ ! -f "$config_file" ]] && return 1
58
-
59
- local project_id=$(jq -r '.projectId // ""' "$config_file" 2>/dev/null)
60
- [[ -z "$project_id" ]] && return 1
61
-
62
- local project_json="${HOME}/.prjct-cli/projects/${project_id}/project.json"
63
- [[ ! -f "$project_json" ]] && {
64
- echo -e "${WARNING}prjct v${CLI_VERSION}${NC} ${MUTED}run p. sync${NC}"
65
- return 0
66
- }
67
-
68
- local project_version=$(jq -r '.cliVersion // ""' "$project_json" 2>/dev/null)
69
-
70
- if [[ -z "$project_version" ]] || [[ "$project_version" != "$CLI_VERSION" ]]; then
71
- echo -e "${WARNING}prjct v${CLI_VERSION}${NC} ${MUTED}run p. sync${NC}"
72
- return 0
73
- fi
74
-
75
- return 1
76
- }
77
-
78
- # Check for version upgrade first
79
- VERSION_MSG=$(check_version_upgrade)
80
- if [[ -n "$VERSION_MSG" ]]; then
81
- echo -e "$VERSION_MSG"
82
- exit 0
83
- fi
51
+ # Version check removed - was causing confusing duplicate statusline display
52
+ # Users will see update prompts when running p. commands
84
53
 
85
54
  # ============================================================================
86
55
  # Build Statusline
@@ -12,6 +12,7 @@
12
12
  import fs from 'fs/promises'
13
13
  import path from 'path'
14
14
  import os from 'os'
15
+ import { getPackageRoot } from '../utils/version'
15
16
  import type {
16
17
  InstallResult,
17
18
  UninstallResult,
@@ -30,7 +31,7 @@ import type {
30
31
  export async function installDocs(): Promise<{ success: boolean; error?: string }> {
31
32
  try {
32
33
  const docsDir = path.join(os.homedir(), '.prjct-cli', 'docs')
33
- const templateDocsDir = path.join(__dirname, '../../templates/global/docs')
34
+ const templateDocsDir = path.join(getPackageRoot(), 'templates/global/docs')
34
35
 
35
36
  // Ensure docs directory exists
36
37
  await fs.mkdir(docsDir, { recursive: true })
@@ -77,7 +78,7 @@ export async function installGlobalConfig(
77
78
  await fs.mkdir(claudeDir, { recursive: true })
78
79
 
79
80
  const globalConfigPath = path.join(claudeDir, 'CLAUDE.md')
80
- const templatePath = path.join(__dirname, '../../templates/global/CLAUDE.md')
81
+ const templatePath = path.join(getPackageRoot(), 'templates/global/CLAUDE.md')
81
82
 
82
83
  // Read template content
83
84
  const templateContent = await fs.readFile(templatePath, 'utf-8')
@@ -168,7 +169,8 @@ export class CommandInstaller {
168
169
  // We use the p.md router in commands/ root instead
169
170
  this.claudeCommandsPath = path.join(this.homeDir, '.claude', 'commands', 'p')
170
171
  this.claudeConfigPath = path.join(this.homeDir, '.claude')
171
- this.templatesDir = path.join(__dirname, '..', '..', 'templates', 'commands')
172
+ // Use getPackageRoot() to find templates - works from both source and compiled
173
+ this.templatesDir = path.join(getPackageRoot(), 'templates', 'commands')
172
174
  }
173
175
 
174
176
  /**
@@ -18,7 +18,7 @@ import path from 'path'
18
18
  import os from 'os'
19
19
  import installer from './command-installer'
20
20
  import editorsConfig from './editors-config'
21
- import { VERSION } from '../utils/version'
21
+ import { VERSION, getPackageRoot } from '../utils/version'
22
22
 
23
23
  // Colors
24
24
  const GREEN = '\x1b[32m'
@@ -215,7 +215,7 @@ async function installStatusLine(): Promise<void> {
215
215
  const prjctConfigPath = path.join(prjctStatusLineDir, 'config.json')
216
216
 
217
217
  // Source assets (from the package)
218
- const assetsDir = path.join(__dirname, '..', '..', 'assets', 'statusline')
218
+ const assetsDir = path.join(getPackageRoot(), 'assets', 'statusline')
219
219
  const sourceScript = path.join(assetsDir, 'statusline.sh')
220
220
  const sourceThemeDir = path.join(assetsDir, 'themes')
221
221
  const sourceLibDir = path.join(assetsDir, 'lib')
@@ -17,6 +17,40 @@ interface PackageJson {
17
17
 
18
18
  let cachedVersion: string | null = null
19
19
  let cachedPackageJson: PackageJson | null = null
20
+ let cachedPackageRoot: string | null = null
21
+
22
+ /**
23
+ * Find the package root by searching up from __dirname for package.json
24
+ * Works whether running from source (core/utils/) or compiled (dist/core/utils/)
25
+ */
26
+ export function getPackageRoot(): string {
27
+ if (cachedPackageRoot) {
28
+ return cachedPackageRoot
29
+ }
30
+
31
+ let currentDir = __dirname
32
+
33
+ // Search up to 5 levels up for package.json with name "prjct-cli"
34
+ for (let i = 0; i < 5; i++) {
35
+ const packageJsonPath = path.join(currentDir, 'package.json')
36
+ if (fs.existsSync(packageJsonPath)) {
37
+ try {
38
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
39
+ if (pkg.name === 'prjct-cli') {
40
+ cachedPackageRoot = currentDir
41
+ return currentDir
42
+ }
43
+ } catch {
44
+ // Continue searching
45
+ }
46
+ }
47
+ currentDir = path.dirname(currentDir)
48
+ }
49
+
50
+ // Fallback: assume 3 levels up from __dirname (works for dist/core/utils/)
51
+ cachedPackageRoot = path.join(__dirname, '..', '..', '..')
52
+ return cachedPackageRoot
53
+ }
20
54
 
21
55
  /**
22
56
  * Get the current application version from package.json
@@ -27,7 +61,7 @@ export function getVersion(): string {
27
61
  }
28
62
 
29
63
  try {
30
- const packageJsonPath = path.join(__dirname, '..', '..', 'package.json')
64
+ const packageJsonPath = path.join(getPackageRoot(), 'package.json')
31
65
  const packageJson: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
32
66
  cachedVersion = packageJson.version
33
67
  cachedPackageJson = packageJson
@@ -87,13 +121,16 @@ export function needsMigration(fromVersion: string, toVersion: string | null = n
87
121
  }
88
122
 
89
123
  export const VERSION = getVersion()
124
+ export const PACKAGE_ROOT = getPackageRoot()
90
125
 
91
126
  // Default export for CommonJS compatibility
92
127
  export default {
93
128
  getVersion,
129
+ getPackageRoot,
94
130
  getPackageInfo,
95
131
  compareVersions,
96
132
  isCompatible,
97
133
  needsMigration,
98
- VERSION
134
+ VERSION,
135
+ PACKAGE_ROOT
99
136
  }
@@ -45,12 +45,34 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
45
45
  // core/utils/version.ts
46
46
  import fs from "fs";
47
47
  import path from "path";
48
+ function getPackageRoot() {
49
+ if (cachedPackageRoot) {
50
+ return cachedPackageRoot;
51
+ }
52
+ let currentDir = __dirname;
53
+ for (let i = 0; i < 5; i++) {
54
+ const packageJsonPath = path.join(currentDir, "package.json");
55
+ if (fs.existsSync(packageJsonPath)) {
56
+ try {
57
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
58
+ if (pkg.name === "prjct-cli") {
59
+ cachedPackageRoot = currentDir;
60
+ return currentDir;
61
+ }
62
+ } catch {
63
+ }
64
+ }
65
+ currentDir = path.dirname(currentDir);
66
+ }
67
+ cachedPackageRoot = path.join(__dirname, "..", "..", "..");
68
+ return cachedPackageRoot;
69
+ }
48
70
  function getVersion() {
49
71
  if (cachedVersion) {
50
72
  return cachedVersion;
51
73
  }
52
74
  try {
53
- const packageJsonPath = path.join(__dirname, "..", "..", "package.json");
75
+ const packageJsonPath = path.join(getPackageRoot(), "package.json");
54
76
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
55
77
  cachedVersion = packageJson.version;
56
78
  cachedPackageJson = packageJson;
@@ -60,14 +82,17 @@ function getVersion() {
60
82
  return "0.0.0";
61
83
  }
62
84
  }
63
- var cachedVersion, cachedPackageJson, VERSION;
85
+ var cachedVersion, cachedPackageJson, cachedPackageRoot, VERSION, PACKAGE_ROOT;
64
86
  var init_version = __esm({
65
87
  "core/utils/version.ts"() {
66
88
  "use strict";
67
89
  cachedVersion = null;
68
90
  cachedPackageJson = null;
91
+ cachedPackageRoot = null;
92
+ __name(getPackageRoot, "getPackageRoot");
69
93
  __name(getVersion, "getVersion");
70
94
  VERSION = getVersion();
95
+ PACKAGE_ROOT = getPackageRoot();
71
96
  }
72
97
  });
73
98
 
@@ -1409,7 +1434,7 @@ import os4 from "os";
1409
1434
  async function installDocs() {
1410
1435
  try {
1411
1436
  const docsDir = path8.join(os4.homedir(), ".prjct-cli", "docs");
1412
- const templateDocsDir = path8.join(__dirname, "../../templates/global/docs");
1437
+ const templateDocsDir = path8.join(getPackageRoot(), "templates/global/docs");
1413
1438
  await fs8.mkdir(docsDir, { recursive: true });
1414
1439
  const docFiles = await fs8.readdir(templateDocsDir);
1415
1440
  for (const file of docFiles) {
@@ -1438,7 +1463,7 @@ async function installGlobalConfig(claudeConfigPath, detectClaude) {
1438
1463
  const claudeDir = path8.join(os4.homedir(), ".claude");
1439
1464
  await fs8.mkdir(claudeDir, { recursive: true });
1440
1465
  const globalConfigPath = path8.join(claudeDir, "CLAUDE.md");
1441
- const templatePath = path8.join(__dirname, "../../templates/global/CLAUDE.md");
1466
+ const templatePath = path8.join(getPackageRoot(), "templates/global/CLAUDE.md");
1442
1467
  const templateContent = await fs8.readFile(templatePath, "utf-8");
1443
1468
  let existingContent = "";
1444
1469
  let fileExists2 = false;
@@ -1497,6 +1522,7 @@ var CommandInstaller, commandInstaller, command_installer_default;
1497
1522
  var init_command_installer = __esm({
1498
1523
  "core/infrastructure/command-installer.ts"() {
1499
1524
  "use strict";
1525
+ init_version();
1500
1526
  __name(installDocs, "installDocs");
1501
1527
  __name(installGlobalConfig, "installGlobalConfig");
1502
1528
  CommandInstaller = class {
@@ -1511,7 +1537,7 @@ var init_command_installer = __esm({
1511
1537
  this.homeDir = os4.homedir();
1512
1538
  this.claudeCommandsPath = path8.join(this.homeDir, ".claude", "commands", "p");
1513
1539
  this.claudeConfigPath = path8.join(this.homeDir, ".claude");
1514
- this.templatesDir = path8.join(__dirname, "..", "..", "templates", "commands");
1540
+ this.templatesDir = path8.join(getPackageRoot(), "templates", "commands");
1515
1541
  }
1516
1542
  /**
1517
1543
  * Detect if Claude is installed
@@ -1909,7 +1935,7 @@ async function installStatusLine() {
1909
1935
  const prjctLibDir = path9.join(prjctStatusLineDir, "lib");
1910
1936
  const prjctComponentsDir = path9.join(prjctStatusLineDir, "components");
1911
1937
  const prjctConfigPath = path9.join(prjctStatusLineDir, "config.json");
1912
- const assetsDir = path9.join(__dirname, "..", "..", "assets", "statusline");
1938
+ const assetsDir = path9.join(getPackageRoot(), "assets", "statusline");
1913
1939
  const sourceScript = path9.join(assetsDir, "statusline.sh");
1914
1940
  const sourceThemeDir = path9.join(assetsDir, "themes");
1915
1941
  const sourceLibDir = path9.join(assetsDir, "lib");
@@ -12508,7 +12534,7 @@ var require_package = __commonJS({
12508
12534
  "package.json"(exports, module) {
12509
12535
  module.exports = {
12510
12536
  name: "prjct-cli",
12511
- version: "0.29.4",
12537
+ version: "0.29.7",
12512
12538
  description: "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
12513
12539
  main: "core/index.ts",
12514
12540
  bin: {
@@ -38,18 +38,68 @@ __export(command_installer_exports, {
38
38
  });
39
39
  module.exports = __toCommonJS(command_installer_exports);
40
40
  var import_promises = __toESM(require("fs/promises"));
41
- var import_path = __toESM(require("path"));
41
+ var import_path2 = __toESM(require("path"));
42
42
  var import_os = __toESM(require("os"));
43
+
44
+ // core/utils/version.ts
45
+ var import_fs = __toESM(require("fs"));
46
+ var import_path = __toESM(require("path"));
47
+ var cachedVersion = null;
48
+ var cachedPackageJson = null;
49
+ var cachedPackageRoot = null;
50
+ function getPackageRoot() {
51
+ if (cachedPackageRoot) {
52
+ return cachedPackageRoot;
53
+ }
54
+ let currentDir = __dirname;
55
+ for (let i = 0; i < 5; i++) {
56
+ const packageJsonPath = import_path.default.join(currentDir, "package.json");
57
+ if (import_fs.default.existsSync(packageJsonPath)) {
58
+ try {
59
+ const pkg = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
60
+ if (pkg.name === "prjct-cli") {
61
+ cachedPackageRoot = currentDir;
62
+ return currentDir;
63
+ }
64
+ } catch {
65
+ }
66
+ }
67
+ currentDir = import_path.default.dirname(currentDir);
68
+ }
69
+ cachedPackageRoot = import_path.default.join(__dirname, "..", "..", "..");
70
+ return cachedPackageRoot;
71
+ }
72
+ __name(getPackageRoot, "getPackageRoot");
73
+ function getVersion() {
74
+ if (cachedVersion) {
75
+ return cachedVersion;
76
+ }
77
+ try {
78
+ const packageJsonPath = import_path.default.join(getPackageRoot(), "package.json");
79
+ const packageJson = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
80
+ cachedVersion = packageJson.version;
81
+ cachedPackageJson = packageJson;
82
+ return cachedVersion;
83
+ } catch (error) {
84
+ console.error("Failed to read version from package.json:", error.message);
85
+ return "0.0.0";
86
+ }
87
+ }
88
+ __name(getVersion, "getVersion");
89
+ var VERSION = getVersion();
90
+ var PACKAGE_ROOT = getPackageRoot();
91
+
92
+ // core/infrastructure/command-installer.ts
43
93
  async function installDocs() {
44
94
  try {
45
- const docsDir = import_path.default.join(import_os.default.homedir(), ".prjct-cli", "docs");
46
- const templateDocsDir = import_path.default.join(__dirname, "../../templates/global/docs");
95
+ const docsDir = import_path2.default.join(import_os.default.homedir(), ".prjct-cli", "docs");
96
+ const templateDocsDir = import_path2.default.join(getPackageRoot(), "templates/global/docs");
47
97
  await import_promises.default.mkdir(docsDir, { recursive: true });
48
98
  const docFiles = await import_promises.default.readdir(templateDocsDir);
49
99
  for (const file of docFiles) {
50
100
  if (file.endsWith(".md")) {
51
- const srcPath = import_path.default.join(templateDocsDir, file);
52
- const destPath = import_path.default.join(docsDir, file);
101
+ const srcPath = import_path2.default.join(templateDocsDir, file);
102
+ const destPath = import_path2.default.join(docsDir, file);
53
103
  const content = await import_promises.default.readFile(srcPath, "utf-8");
54
104
  await import_promises.default.writeFile(destPath, content, "utf-8");
55
105
  }
@@ -70,10 +120,10 @@ async function installGlobalConfig(claudeConfigPath, detectClaude) {
70
120
  };
71
121
  }
72
122
  try {
73
- const claudeDir = import_path.default.join(import_os.default.homedir(), ".claude");
123
+ const claudeDir = import_path2.default.join(import_os.default.homedir(), ".claude");
74
124
  await import_promises.default.mkdir(claudeDir, { recursive: true });
75
- const globalConfigPath = import_path.default.join(claudeDir, "CLAUDE.md");
76
- const templatePath = import_path.default.join(__dirname, "../../templates/global/CLAUDE.md");
125
+ const globalConfigPath = import_path2.default.join(claudeDir, "CLAUDE.md");
126
+ const templatePath = import_path2.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
77
127
  const templateContent = await import_promises.default.readFile(templatePath, "utf-8");
78
128
  let existingContent = "";
79
129
  let fileExists = false;
@@ -139,9 +189,9 @@ var CommandInstaller = class {
139
189
  templatesDir;
140
190
  constructor() {
141
191
  this.homeDir = import_os.default.homedir();
142
- this.claudeCommandsPath = import_path.default.join(this.homeDir, ".claude", "commands", "p");
143
- this.claudeConfigPath = import_path.default.join(this.homeDir, ".claude");
144
- this.templatesDir = import_path.default.join(__dirname, "..", "..", "templates", "commands");
192
+ this.claudeCommandsPath = import_path2.default.join(this.homeDir, ".claude", "commands", "p");
193
+ this.claudeConfigPath = import_path2.default.join(this.homeDir, ".claude");
194
+ this.templatesDir = import_path2.default.join(getPackageRoot(), "templates", "commands");
145
195
  }
146
196
  /**
147
197
  * Detect if Claude is installed
@@ -204,8 +254,8 @@ var CommandInstaller = class {
204
254
  const errors = [];
205
255
  for (const file of commandFiles) {
206
256
  try {
207
- const sourcePath = import_path.default.join(this.templatesDir, file);
208
- const destPath = import_path.default.join(this.claudeCommandsPath, file);
257
+ const sourcePath = import_path2.default.join(this.templatesDir, file);
258
+ const destPath = import_path2.default.join(this.claudeCommandsPath, file);
209
259
  const content = await import_promises.default.readFile(sourcePath, "utf-8");
210
260
  await import_promises.default.writeFile(destPath, content, "utf-8");
211
261
  installed.push(file.replace(".md", ""));
@@ -236,7 +286,7 @@ var CommandInstaller = class {
236
286
  const errors = [];
237
287
  for (const file of commandFiles) {
238
288
  try {
239
- const filePath = import_path.default.join(this.claudeCommandsPath, file);
289
+ const filePath = import_path2.default.join(this.claudeCommandsPath, file);
240
290
  await import_promises.default.unlink(filePath);
241
291
  uninstalled.push(file.replace(".md", ""));
242
292
  } catch (error) {
@@ -318,7 +368,7 @@ var CommandInstaller = class {
318
368
  */
319
369
  async verifyTemplate(commandName) {
320
370
  try {
321
- const templatePath = import_path.default.join(this.templatesDir, `${commandName}.md`);
371
+ const templatePath = import_path2.default.join(this.templatesDir, `${commandName}.md`);
322
372
  await import_promises.default.access(templatePath);
323
373
  return true;
324
374
  } catch {
@@ -332,8 +382,8 @@ var CommandInstaller = class {
332
382
  */
333
383
  async installRouter() {
334
384
  try {
335
- const routerSource = import_path.default.join(this.templatesDir, "p.md");
336
- const routerDest = import_path.default.join(this.homeDir, ".claude", "commands", "p.md");
385
+ const routerSource = import_path2.default.join(this.templatesDir, "p.md");
386
+ const routerDest = import_path2.default.join(this.homeDir, ".claude", "commands", "p.md");
337
387
  const content = await import_promises.default.readFile(routerSource, "utf-8");
338
388
  await import_promises.default.writeFile(routerDest, content, "utf-8");
339
389
  return true;
@@ -375,8 +425,8 @@ var CommandInstaller = class {
375
425
  };
376
426
  for (const file of templateFiles) {
377
427
  try {
378
- const sourcePath = import_path.default.join(this.templatesDir, file);
379
- const destPath = import_path.default.join(this.claudeCommandsPath, file);
428
+ const sourcePath = import_path2.default.join(this.templatesDir, file);
429
+ const destPath = import_path2.default.join(this.claudeCommandsPath, file);
380
430
  const exists = installedFiles.includes(file);
381
431
  const content = await import_promises.default.readFile(sourcePath, "utf-8");
382
432
  await import_promises.default.writeFile(destPath, content, "utf-8");
@@ -36,24 +36,74 @@ __export(setup_exports, {
36
36
  });
37
37
  module.exports = __toCommonJS(setup_exports);
38
38
  var import_child_process = require("child_process");
39
- var import_fs = __toESM(require("fs"));
40
- var import_path3 = __toESM(require("path"));
39
+ var import_fs2 = __toESM(require("fs"));
40
+ var import_path4 = __toESM(require("path"));
41
41
  var import_os3 = __toESM(require("os"));
42
42
 
43
43
  // core/infrastructure/command-installer.ts
44
44
  var import_promises = __toESM(require("fs/promises"));
45
- var import_path = __toESM(require("path"));
45
+ var import_path2 = __toESM(require("path"));
46
46
  var import_os = __toESM(require("os"));
47
+
48
+ // core/utils/version.ts
49
+ var import_fs = __toESM(require("fs"));
50
+ var import_path = __toESM(require("path"));
51
+ var cachedVersion = null;
52
+ var cachedPackageJson = null;
53
+ var cachedPackageRoot = null;
54
+ function getPackageRoot() {
55
+ if (cachedPackageRoot) {
56
+ return cachedPackageRoot;
57
+ }
58
+ let currentDir = __dirname;
59
+ for (let i = 0; i < 5; i++) {
60
+ const packageJsonPath = import_path.default.join(currentDir, "package.json");
61
+ if (import_fs.default.existsSync(packageJsonPath)) {
62
+ try {
63
+ const pkg = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
64
+ if (pkg.name === "prjct-cli") {
65
+ cachedPackageRoot = currentDir;
66
+ return currentDir;
67
+ }
68
+ } catch {
69
+ }
70
+ }
71
+ currentDir = import_path.default.dirname(currentDir);
72
+ }
73
+ cachedPackageRoot = import_path.default.join(__dirname, "..", "..", "..");
74
+ return cachedPackageRoot;
75
+ }
76
+ __name(getPackageRoot, "getPackageRoot");
77
+ function getVersion() {
78
+ if (cachedVersion) {
79
+ return cachedVersion;
80
+ }
81
+ try {
82
+ const packageJsonPath = import_path.default.join(getPackageRoot(), "package.json");
83
+ const packageJson = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
84
+ cachedVersion = packageJson.version;
85
+ cachedPackageJson = packageJson;
86
+ return cachedVersion;
87
+ } catch (error) {
88
+ console.error("Failed to read version from package.json:", error.message);
89
+ return "0.0.0";
90
+ }
91
+ }
92
+ __name(getVersion, "getVersion");
93
+ var VERSION = getVersion();
94
+ var PACKAGE_ROOT = getPackageRoot();
95
+
96
+ // core/infrastructure/command-installer.ts
47
97
  async function installDocs() {
48
98
  try {
49
- const docsDir = import_path.default.join(import_os.default.homedir(), ".prjct-cli", "docs");
50
- const templateDocsDir = import_path.default.join(__dirname, "../../templates/global/docs");
99
+ const docsDir = import_path2.default.join(import_os.default.homedir(), ".prjct-cli", "docs");
100
+ const templateDocsDir = import_path2.default.join(getPackageRoot(), "templates/global/docs");
51
101
  await import_promises.default.mkdir(docsDir, { recursive: true });
52
102
  const docFiles = await import_promises.default.readdir(templateDocsDir);
53
103
  for (const file of docFiles) {
54
104
  if (file.endsWith(".md")) {
55
- const srcPath = import_path.default.join(templateDocsDir, file);
56
- const destPath = import_path.default.join(docsDir, file);
105
+ const srcPath = import_path2.default.join(templateDocsDir, file);
106
+ const destPath = import_path2.default.join(docsDir, file);
57
107
  const content = await import_promises.default.readFile(srcPath, "utf-8");
58
108
  await import_promises.default.writeFile(destPath, content, "utf-8");
59
109
  }
@@ -74,10 +124,10 @@ async function installGlobalConfig(claudeConfigPath, detectClaude) {
74
124
  };
75
125
  }
76
126
  try {
77
- const claudeDir = import_path.default.join(import_os.default.homedir(), ".claude");
127
+ const claudeDir = import_path2.default.join(import_os.default.homedir(), ".claude");
78
128
  await import_promises.default.mkdir(claudeDir, { recursive: true });
79
- const globalConfigPath = import_path.default.join(claudeDir, "CLAUDE.md");
80
- const templatePath = import_path.default.join(__dirname, "../../templates/global/CLAUDE.md");
129
+ const globalConfigPath = import_path2.default.join(claudeDir, "CLAUDE.md");
130
+ const templatePath = import_path2.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
81
131
  const templateContent = await import_promises.default.readFile(templatePath, "utf-8");
82
132
  let existingContent = "";
83
133
  let fileExists = false;
@@ -143,9 +193,9 @@ var CommandInstaller = class {
143
193
  templatesDir;
144
194
  constructor() {
145
195
  this.homeDir = import_os.default.homedir();
146
- this.claudeCommandsPath = import_path.default.join(this.homeDir, ".claude", "commands", "p");
147
- this.claudeConfigPath = import_path.default.join(this.homeDir, ".claude");
148
- this.templatesDir = import_path.default.join(__dirname, "..", "..", "templates", "commands");
196
+ this.claudeCommandsPath = import_path2.default.join(this.homeDir, ".claude", "commands", "p");
197
+ this.claudeConfigPath = import_path2.default.join(this.homeDir, ".claude");
198
+ this.templatesDir = import_path2.default.join(getPackageRoot(), "templates", "commands");
149
199
  }
150
200
  /**
151
201
  * Detect if Claude is installed
@@ -208,8 +258,8 @@ var CommandInstaller = class {
208
258
  const errors = [];
209
259
  for (const file of commandFiles) {
210
260
  try {
211
- const sourcePath = import_path.default.join(this.templatesDir, file);
212
- const destPath = import_path.default.join(this.claudeCommandsPath, file);
261
+ const sourcePath = import_path2.default.join(this.templatesDir, file);
262
+ const destPath = import_path2.default.join(this.claudeCommandsPath, file);
213
263
  const content = await import_promises.default.readFile(sourcePath, "utf-8");
214
264
  await import_promises.default.writeFile(destPath, content, "utf-8");
215
265
  installed.push(file.replace(".md", ""));
@@ -240,7 +290,7 @@ var CommandInstaller = class {
240
290
  const errors = [];
241
291
  for (const file of commandFiles) {
242
292
  try {
243
- const filePath = import_path.default.join(this.claudeCommandsPath, file);
293
+ const filePath = import_path2.default.join(this.claudeCommandsPath, file);
244
294
  await import_promises.default.unlink(filePath);
245
295
  uninstalled.push(file.replace(".md", ""));
246
296
  } catch (error) {
@@ -322,7 +372,7 @@ var CommandInstaller = class {
322
372
  */
323
373
  async verifyTemplate(commandName) {
324
374
  try {
325
- const templatePath = import_path.default.join(this.templatesDir, `${commandName}.md`);
375
+ const templatePath = import_path2.default.join(this.templatesDir, `${commandName}.md`);
326
376
  await import_promises.default.access(templatePath);
327
377
  return true;
328
378
  } catch {
@@ -336,8 +386,8 @@ var CommandInstaller = class {
336
386
  */
337
387
  async installRouter() {
338
388
  try {
339
- const routerSource = import_path.default.join(this.templatesDir, "p.md");
340
- const routerDest = import_path.default.join(this.homeDir, ".claude", "commands", "p.md");
389
+ const routerSource = import_path2.default.join(this.templatesDir, "p.md");
390
+ const routerDest = import_path2.default.join(this.homeDir, ".claude", "commands", "p.md");
341
391
  const content = await import_promises.default.readFile(routerSource, "utf-8");
342
392
  await import_promises.default.writeFile(routerDest, content, "utf-8");
343
393
  return true;
@@ -379,8 +429,8 @@ var CommandInstaller = class {
379
429
  };
380
430
  for (const file of templateFiles) {
381
431
  try {
382
- const sourcePath = import_path.default.join(this.templatesDir, file);
383
- const destPath = import_path.default.join(this.claudeCommandsPath, file);
432
+ const sourcePath = import_path2.default.join(this.templatesDir, file);
433
+ const destPath = import_path2.default.join(this.claudeCommandsPath, file);
384
434
  const exists = installedFiles.includes(file);
385
435
  const content = await import_promises.default.readFile(sourcePath, "utf-8");
386
436
  await import_promises.default.writeFile(destPath, content, "utf-8");
@@ -422,7 +472,7 @@ var command_installer_default = commandInstaller;
422
472
 
423
473
  // core/infrastructure/editors-config.ts
424
474
  var import_promises2 = __toESM(require("fs/promises"));
425
- var import_path2 = __toESM(require("path"));
475
+ var import_path3 = __toESM(require("path"));
426
476
  var import_os2 = __toESM(require("os"));
427
477
  var EditorsConfig = class {
428
478
  static {
@@ -433,8 +483,8 @@ var EditorsConfig = class {
433
483
  configFile;
434
484
  constructor() {
435
485
  this.homeDir = import_os2.default.homedir();
436
- this.configDir = import_path2.default.join(this.homeDir, ".prjct-cli", "config");
437
- this.configFile = import_path2.default.join(this.configDir, "installed-editors.json");
486
+ this.configDir = import_path3.default.join(this.homeDir, ".prjct-cli", "config");
487
+ this.configFile = import_path3.default.join(this.configDir, "installed-editors.json");
438
488
  }
439
489
  /**
440
490
  * Ensure config directory exists
@@ -544,7 +594,6 @@ var editorsConfig = new EditorsConfig();
544
594
  var editors_config_default = editorsConfig;
545
595
 
546
596
  // core/infrastructure/setup.ts
547
- var import_version = require("../utils/version");
548
597
  var GREEN = "\x1B[32m";
549
598
  var YELLOW = "\x1B[33m";
550
599
  var DIM = "\x1B[2m";
@@ -605,7 +654,7 @@ async function run() {
605
654
  await command_installer_default.installDocs();
606
655
  await installStatusLine();
607
656
  }
608
- await editors_config_default.saveConfig(import_version.VERSION, command_installer_default.getInstallPath());
657
+ await editors_config_default.saveConfig(VERSION, command_installer_default.getInstallPath());
609
658
  await migrateProjectsCliVersion();
610
659
  showResults(results);
611
660
  return results;
@@ -614,30 +663,30 @@ __name(run, "run");
614
663
  var setup_default = { run };
615
664
  async function migrateProjectsCliVersion() {
616
665
  try {
617
- const projectsDir = import_path3.default.join(import_os3.default.homedir(), ".prjct-cli", "projects");
618
- if (!import_fs.default.existsSync(projectsDir)) {
666
+ const projectsDir = import_path4.default.join(import_os3.default.homedir(), ".prjct-cli", "projects");
667
+ if (!import_fs2.default.existsSync(projectsDir)) {
619
668
  return;
620
669
  }
621
- const projectDirs = import_fs.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
670
+ const projectDirs = import_fs2.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
622
671
  let migrated = 0;
623
672
  for (const projectId of projectDirs) {
624
- const projectJsonPath = import_path3.default.join(projectsDir, projectId, "project.json");
625
- if (!import_fs.default.existsSync(projectJsonPath)) {
673
+ const projectJsonPath = import_path4.default.join(projectsDir, projectId, "project.json");
674
+ if (!import_fs2.default.existsSync(projectJsonPath)) {
626
675
  continue;
627
676
  }
628
677
  try {
629
- const content = import_fs.default.readFileSync(projectJsonPath, "utf8");
678
+ const content = import_fs2.default.readFileSync(projectJsonPath, "utf8");
630
679
  const project = JSON.parse(content);
631
- if (project.cliVersion !== import_version.VERSION) {
632
- project.cliVersion = import_version.VERSION;
633
- import_fs.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
680
+ if (project.cliVersion !== VERSION) {
681
+ project.cliVersion = VERSION;
682
+ import_fs2.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
634
683
  migrated++;
635
684
  }
636
685
  } catch {
637
686
  }
638
687
  }
639
688
  if (migrated > 0) {
640
- console.log(` ${GREEN}\u2713${NC} Updated ${migrated} project(s) to v${import_version.VERSION}`);
689
+ console.log(` ${GREEN}\u2713${NC} Updated ${migrated} project(s) to v${VERSION}`);
641
690
  }
642
691
  } catch {
643
692
  }
@@ -645,58 +694,58 @@ async function migrateProjectsCliVersion() {
645
694
  __name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
646
695
  function ensureStatusLineSettings(settingsPath, statusLinePath) {
647
696
  let settings = {};
648
- if (import_fs.default.existsSync(settingsPath)) {
697
+ if (import_fs2.default.existsSync(settingsPath)) {
649
698
  try {
650
- settings = JSON.parse(import_fs.default.readFileSync(settingsPath, "utf8"));
699
+ settings = JSON.parse(import_fs2.default.readFileSync(settingsPath, "utf8"));
651
700
  } catch {
652
701
  }
653
702
  }
654
703
  settings.statusLine = { type: "command", command: statusLinePath };
655
- import_fs.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
704
+ import_fs2.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
656
705
  }
657
706
  __name(ensureStatusLineSettings, "ensureStatusLineSettings");
658
707
  async function installStatusLine() {
659
708
  try {
660
- const claudeDir = import_path3.default.join(import_os3.default.homedir(), ".claude");
661
- const settingsPath = import_path3.default.join(claudeDir, "settings.json");
662
- const claudeStatusLinePath = import_path3.default.join(claudeDir, "prjct-statusline.sh");
663
- const prjctStatusLineDir = import_path3.default.join(import_os3.default.homedir(), ".prjct-cli", "statusline");
664
- const prjctStatusLinePath = import_path3.default.join(prjctStatusLineDir, "statusline.sh");
665
- const prjctThemesDir = import_path3.default.join(prjctStatusLineDir, "themes");
666
- const prjctLibDir = import_path3.default.join(prjctStatusLineDir, "lib");
667
- const prjctComponentsDir = import_path3.default.join(prjctStatusLineDir, "components");
668
- const prjctConfigPath = import_path3.default.join(prjctStatusLineDir, "config.json");
669
- const assetsDir = import_path3.default.join(__dirname, "..", "..", "assets", "statusline");
670
- const sourceScript = import_path3.default.join(assetsDir, "statusline.sh");
671
- const sourceThemeDir = import_path3.default.join(assetsDir, "themes");
672
- const sourceLibDir = import_path3.default.join(assetsDir, "lib");
673
- const sourceComponentsDir = import_path3.default.join(assetsDir, "components");
674
- const sourceConfigPath = import_path3.default.join(assetsDir, "default-config.json");
675
- if (!import_fs.default.existsSync(claudeDir)) {
676
- import_fs.default.mkdirSync(claudeDir, { recursive: true });
677
- }
678
- if (!import_fs.default.existsSync(prjctStatusLineDir)) {
679
- import_fs.default.mkdirSync(prjctStatusLineDir, { recursive: true });
680
- }
681
- if (!import_fs.default.existsSync(prjctThemesDir)) {
682
- import_fs.default.mkdirSync(prjctThemesDir, { recursive: true });
683
- }
684
- if (!import_fs.default.existsSync(prjctLibDir)) {
685
- import_fs.default.mkdirSync(prjctLibDir, { recursive: true });
686
- }
687
- if (!import_fs.default.existsSync(prjctComponentsDir)) {
688
- import_fs.default.mkdirSync(prjctComponentsDir, { recursive: true });
689
- }
690
- if (import_fs.default.existsSync(prjctStatusLinePath)) {
691
- const existingContent = import_fs.default.readFileSync(prjctStatusLinePath, "utf8");
709
+ const claudeDir = import_path4.default.join(import_os3.default.homedir(), ".claude");
710
+ const settingsPath = import_path4.default.join(claudeDir, "settings.json");
711
+ const claudeStatusLinePath = import_path4.default.join(claudeDir, "prjct-statusline.sh");
712
+ const prjctStatusLineDir = import_path4.default.join(import_os3.default.homedir(), ".prjct-cli", "statusline");
713
+ const prjctStatusLinePath = import_path4.default.join(prjctStatusLineDir, "statusline.sh");
714
+ const prjctThemesDir = import_path4.default.join(prjctStatusLineDir, "themes");
715
+ const prjctLibDir = import_path4.default.join(prjctStatusLineDir, "lib");
716
+ const prjctComponentsDir = import_path4.default.join(prjctStatusLineDir, "components");
717
+ const prjctConfigPath = import_path4.default.join(prjctStatusLineDir, "config.json");
718
+ const assetsDir = import_path4.default.join(getPackageRoot(), "assets", "statusline");
719
+ const sourceScript = import_path4.default.join(assetsDir, "statusline.sh");
720
+ const sourceThemeDir = import_path4.default.join(assetsDir, "themes");
721
+ const sourceLibDir = import_path4.default.join(assetsDir, "lib");
722
+ const sourceComponentsDir = import_path4.default.join(assetsDir, "components");
723
+ const sourceConfigPath = import_path4.default.join(assetsDir, "default-config.json");
724
+ if (!import_fs2.default.existsSync(claudeDir)) {
725
+ import_fs2.default.mkdirSync(claudeDir, { recursive: true });
726
+ }
727
+ if (!import_fs2.default.existsSync(prjctStatusLineDir)) {
728
+ import_fs2.default.mkdirSync(prjctStatusLineDir, { recursive: true });
729
+ }
730
+ if (!import_fs2.default.existsSync(prjctThemesDir)) {
731
+ import_fs2.default.mkdirSync(prjctThemesDir, { recursive: true });
732
+ }
733
+ if (!import_fs2.default.existsSync(prjctLibDir)) {
734
+ import_fs2.default.mkdirSync(prjctLibDir, { recursive: true });
735
+ }
736
+ if (!import_fs2.default.existsSync(prjctComponentsDir)) {
737
+ import_fs2.default.mkdirSync(prjctComponentsDir, { recursive: true });
738
+ }
739
+ if (import_fs2.default.existsSync(prjctStatusLinePath)) {
740
+ const existingContent = import_fs2.default.readFileSync(prjctStatusLinePath, "utf8");
692
741
  if (existingContent.includes("CLI_VERSION=")) {
693
742
  const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
694
- if (versionMatch && versionMatch[1] !== import_version.VERSION) {
743
+ if (versionMatch && versionMatch[1] !== VERSION) {
695
744
  const updatedContent = existingContent.replace(
696
745
  /CLI_VERSION="[^"]*"/,
697
- `CLI_VERSION="${import_version.VERSION}"`
746
+ `CLI_VERSION="${VERSION}"`
698
747
  );
699
- import_fs.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
748
+ import_fs2.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
700
749
  }
701
750
  installStatusLineModules(sourceLibDir, prjctLibDir);
702
751
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
@@ -705,30 +754,30 @@ async function installStatusLine() {
705
754
  return;
706
755
  }
707
756
  }
708
- if (import_fs.default.existsSync(sourceScript)) {
709
- let scriptContent = import_fs.default.readFileSync(sourceScript, "utf8");
757
+ if (import_fs2.default.existsSync(sourceScript)) {
758
+ let scriptContent = import_fs2.default.readFileSync(sourceScript, "utf8");
710
759
  scriptContent = scriptContent.replace(
711
760
  /CLI_VERSION="[^"]*"/,
712
- `CLI_VERSION="${import_version.VERSION}"`
761
+ `CLI_VERSION="${VERSION}"`
713
762
  );
714
- import_fs.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
763
+ import_fs2.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
715
764
  installStatusLineModules(sourceLibDir, prjctLibDir);
716
765
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
717
- if (import_fs.default.existsSync(sourceThemeDir)) {
718
- const themes = import_fs.default.readdirSync(sourceThemeDir);
766
+ if (import_fs2.default.existsSync(sourceThemeDir)) {
767
+ const themes = import_fs2.default.readdirSync(sourceThemeDir);
719
768
  for (const theme of themes) {
720
- const src = import_path3.default.join(sourceThemeDir, theme);
721
- const dest = import_path3.default.join(prjctThemesDir, theme);
722
- import_fs.default.copyFileSync(src, dest);
769
+ const src = import_path4.default.join(sourceThemeDir, theme);
770
+ const dest = import_path4.default.join(prjctThemesDir, theme);
771
+ import_fs2.default.copyFileSync(src, dest);
723
772
  }
724
773
  }
725
- if (!import_fs.default.existsSync(prjctConfigPath) && import_fs.default.existsSync(sourceConfigPath)) {
726
- import_fs.default.copyFileSync(sourceConfigPath, prjctConfigPath);
774
+ if (!import_fs2.default.existsSync(prjctConfigPath) && import_fs2.default.existsSync(sourceConfigPath)) {
775
+ import_fs2.default.copyFileSync(sourceConfigPath, prjctConfigPath);
727
776
  }
728
777
  } else {
729
778
  const scriptContent = `#!/bin/bash
730
779
  # prjct Status Line for Claude Code
731
- CLI_VERSION="${import_version.VERSION}"
780
+ CLI_VERSION="${VERSION}"
732
781
  input=$(cat)
733
782
  CWD=$(echo "$input" | jq -r '.workspace.current_dir // "~"' 2>/dev/null)
734
783
  CONFIG="$CWD/.prjct/prjct.config.json"
@@ -758,7 +807,7 @@ if [ -f "$CONFIG" ]; then
758
807
  fi
759
808
  echo "prjct"
760
809
  `;
761
- import_fs.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
810
+ import_fs2.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
762
811
  }
763
812
  ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
764
813
  ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
@@ -767,38 +816,38 @@ echo "prjct"
767
816
  }
768
817
  __name(installStatusLine, "installStatusLine");
769
818
  function installStatusLineModules(sourceDir, destDir) {
770
- if (!import_fs.default.existsSync(sourceDir)) {
819
+ if (!import_fs2.default.existsSync(sourceDir)) {
771
820
  return;
772
821
  }
773
- const files = import_fs.default.readdirSync(sourceDir);
822
+ const files = import_fs2.default.readdirSync(sourceDir);
774
823
  for (const file of files) {
775
824
  if (file.endsWith(".sh")) {
776
- const src = import_path3.default.join(sourceDir, file);
777
- const dest = import_path3.default.join(destDir, file);
778
- import_fs.default.copyFileSync(src, dest);
779
- import_fs.default.chmodSync(dest, 493);
825
+ const src = import_path4.default.join(sourceDir, file);
826
+ const dest = import_path4.default.join(destDir, file);
827
+ import_fs2.default.copyFileSync(src, dest);
828
+ import_fs2.default.chmodSync(dest, 493);
780
829
  }
781
830
  }
782
831
  }
783
832
  __name(installStatusLineModules, "installStatusLineModules");
784
833
  function ensureStatusLineSymlink(linkPath, targetPath) {
785
834
  try {
786
- if (import_fs.default.existsSync(linkPath)) {
787
- const stats = import_fs.default.lstatSync(linkPath);
835
+ if (import_fs2.default.existsSync(linkPath)) {
836
+ const stats = import_fs2.default.lstatSync(linkPath);
788
837
  if (stats.isSymbolicLink()) {
789
- const existingTarget = import_fs.default.readlinkSync(linkPath);
838
+ const existingTarget = import_fs2.default.readlinkSync(linkPath);
790
839
  if (existingTarget === targetPath) {
791
840
  return;
792
841
  }
793
842
  }
794
- import_fs.default.unlinkSync(linkPath);
843
+ import_fs2.default.unlinkSync(linkPath);
795
844
  }
796
- import_fs.default.symlinkSync(targetPath, linkPath);
845
+ import_fs2.default.symlinkSync(targetPath, linkPath);
797
846
  } catch {
798
847
  try {
799
- if (import_fs.default.existsSync(targetPath)) {
800
- import_fs.default.copyFileSync(targetPath, linkPath);
801
- import_fs.default.chmodSync(linkPath, 493);
848
+ if (import_fs2.default.existsSync(targetPath)) {
849
+ import_fs2.default.copyFileSync(targetPath, linkPath);
850
+ import_fs2.default.chmodSync(linkPath, 493);
802
851
  }
803
852
  } catch {
804
853
  }
@@ -31,10 +31,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // core/utils/version.ts
32
32
  var version_exports = {};
33
33
  __export(version_exports, {
34
+ PACKAGE_ROOT: () => PACKAGE_ROOT,
34
35
  VERSION: () => VERSION,
35
36
  compareVersions: () => compareVersions,
36
37
  default: () => version_default,
37
38
  getPackageInfo: () => getPackageInfo,
39
+ getPackageRoot: () => getPackageRoot,
38
40
  getVersion: () => getVersion,
39
41
  isCompatible: () => isCompatible,
40
42
  needsMigration: () => needsMigration
@@ -44,12 +46,36 @@ var import_fs = __toESM(require("fs"));
44
46
  var import_path = __toESM(require("path"));
45
47
  var cachedVersion = null;
46
48
  var cachedPackageJson = null;
49
+ var cachedPackageRoot = null;
50
+ function getPackageRoot() {
51
+ if (cachedPackageRoot) {
52
+ return cachedPackageRoot;
53
+ }
54
+ let currentDir = __dirname;
55
+ for (let i = 0; i < 5; i++) {
56
+ const packageJsonPath = import_path.default.join(currentDir, "package.json");
57
+ if (import_fs.default.existsSync(packageJsonPath)) {
58
+ try {
59
+ const pkg = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
60
+ if (pkg.name === "prjct-cli") {
61
+ cachedPackageRoot = currentDir;
62
+ return currentDir;
63
+ }
64
+ } catch {
65
+ }
66
+ }
67
+ currentDir = import_path.default.dirname(currentDir);
68
+ }
69
+ cachedPackageRoot = import_path.default.join(__dirname, "..", "..", "..");
70
+ return cachedPackageRoot;
71
+ }
72
+ __name(getPackageRoot, "getPackageRoot");
47
73
  function getVersion() {
48
74
  if (cachedVersion) {
49
75
  return cachedVersion;
50
76
  }
51
77
  try {
52
- const packageJsonPath = import_path.default.join(__dirname, "..", "..", "package.json");
78
+ const packageJsonPath = import_path.default.join(getPackageRoot(), "package.json");
53
79
  const packageJson = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
54
80
  cachedVersion = packageJson.version;
55
81
  cachedPackageJson = packageJson;
@@ -92,19 +118,24 @@ function needsMigration(fromVersion, toVersion = null) {
92
118
  }
93
119
  __name(needsMigration, "needsMigration");
94
120
  var VERSION = getVersion();
121
+ var PACKAGE_ROOT = getPackageRoot();
95
122
  var version_default = {
96
123
  getVersion,
124
+ getPackageRoot,
97
125
  getPackageInfo,
98
126
  compareVersions,
99
127
  isCompatible,
100
128
  needsMigration,
101
- VERSION
129
+ VERSION,
130
+ PACKAGE_ROOT
102
131
  };
103
132
  // Annotate the CommonJS export names for ESM import in node:
104
133
  0 && (module.exports = {
134
+ PACKAGE_ROOT,
105
135
  VERSION,
106
136
  compareVersions,
107
137
  getPackageInfo,
138
+ getPackageRoot,
108
139
  getVersion,
109
140
  isCompatible,
110
141
  needsMigration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "0.29.5",
3
+ "version": "0.29.8",
4
4
  "description": "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
5
5
  "main": "core/index.ts",
6
6
  "bin": {
@@ -5,28 +5,41 @@ allowed-tools: [Read, Write, Edit, Bash, Glob, Grep, Task, AskUserQuestion, Todo
5
5
 
6
6
  # prjct Command Router
7
7
 
8
- Route `p. <command>` to the appropriate prjct command.
8
+ Route `p. <command>` to the appropriate prjct template.
9
9
 
10
10
  ## Instructions
11
11
 
12
12
  **ARGUMENTS**: $ARGUMENTS
13
13
 
14
14
  1. Parse ARGUMENTS: first word = `command`, rest = `commandArgs`
15
- 2. Read the template file: `~/.claude/commands/p/{command}.md`
16
- 3. Execute that template with `commandArgs` as the task description
15
+ 2. Find npm global root by running:
16
+ ```bash
17
+ npm root -g
18
+ ```
19
+ This returns a path like `/opt/homebrew/lib/node_modules` or `/usr/local/lib/node_modules`
20
+ 3. Read template from the npm package location:
21
+ ```
22
+ {npmRoot}/prjct-cli/templates/commands/{command}.md
23
+ ```
24
+ 4. Execute that template with `commandArgs` as input
17
25
 
18
26
  ## Example
19
27
 
20
28
  If ARGUMENTS = "task fix the login bug":
21
29
  - command = "task"
22
30
  - commandArgs = "fix the login bug"
23
- - Read: `~/.claude/commands/p/task.md`
31
+ - Run: `npm root -g` → `/opt/homebrew/lib/node_modules`
32
+ - Read: `/opt/homebrew/lib/node_modules/prjct-cli/templates/commands/task.md`
24
33
  - Execute with: "fix the login bug"
25
34
 
35
+ ## Fallback
36
+
37
+ If npm root fails, read from local cache: `~/.claude/commands/p/{command}.md`
38
+
26
39
  ## Available Commands
27
40
 
28
- `task` `done` `ship` `sync` `init` `idea` `dash` `next` `pause` `resume` `bug` `linear` `feature` `prd` `plan` `review` `merge` `git` `test` `cleanup` `design` `analyze` `history` `enrich`
41
+ `task` `done` `ship` `sync` `init` `idea` `dash` `next` `pause` `resume` `bug` `linear` `feature` `prd` `plan` `review` `merge` `git` `test` `cleanup` `design` `analyze` `history` `enrich` `update`
29
42
 
30
43
  ## Action
31
44
 
32
- NOW read the command template and execute it.
45
+ NOW find npm root and read the command template.
@@ -0,0 +1,63 @@
1
+ ---
2
+ allowed-tools: [Bash, Read, Write, Glob]
3
+ description: 'Force update prjct-cli - sync all templates from npm package'
4
+ ---
5
+
6
+ # p. update - Force Update prjct-cli
7
+
8
+ Manually sync all templates from npm package to local installation.
9
+
10
+ ## Step 1: Find npm package location
11
+
12
+ ```bash
13
+ npm root -g
14
+ ```
15
+
16
+ Save this path as `NPM_ROOT`.
17
+
18
+ ## Step 2: Copy p.md router
19
+
20
+ Read: `{NPM_ROOT}/prjct-cli/templates/commands/p.md`
21
+ Write to: `~/.claude/commands/p.md`
22
+
23
+ ## Step 3: Copy ALL command templates
24
+
25
+ For each `.md` file in `{NPM_ROOT}/prjct-cli/templates/commands/`:
26
+ - Read the file
27
+ - Write to `~/.claude/commands/p/{filename}`
28
+
29
+ ## Step 4: Update CLAUDE.md
30
+
31
+ Read: `{NPM_ROOT}/prjct-cli/templates/global/CLAUDE.md`
32
+
33
+ Check if `~/.claude/CLAUDE.md` exists:
34
+ - If NOT exists: Write the template content directly
35
+ - If exists: Find markers `<!-- prjct:start -->` and `<!-- prjct:end -->`, replace content between them
36
+
37
+ ## Step 5: Copy statusline
38
+
39
+ Copy from `{NPM_ROOT}/prjct-cli/assets/statusline/` to `~/.prjct-cli/statusline/`:
40
+ - `statusline.sh`
41
+ - `lib/*.sh`
42
+ - `components/*.sh`
43
+ - `themes/*.json`
44
+
45
+ ## Step 6: Get version and confirm
46
+
47
+ ```bash
48
+ cat "$(npm root -g)/prjct-cli/package.json" | grep '"version"'
49
+ ```
50
+
51
+ ## Output
52
+
53
+ ```
54
+ ✅ prjct-cli updated
55
+
56
+ Commands: synced to ~/.claude/commands/p/
57
+ Config: ~/.claude/CLAUDE.md updated
58
+ Statusline: ~/.prjct-cli/statusline/ updated
59
+ ```
60
+
61
+ ## Action
62
+
63
+ NOW execute steps 1-6 in order. Use Bash to find npm root, then Read/Write to copy files.