prjct-cli 0.29.4 → 0.29.6
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/core/infrastructure/command-installer.ts +5 -3
- package/core/infrastructure/setup.ts +2 -2
- package/core/utils/version.ts +39 -2
- package/dist/bin/prjct.mjs +33 -7
- package/dist/core/infrastructure/command-installer.js +69 -19
- package/dist/core/infrastructure/setup.js +14 -13
- package/dist/core/utils/version.js +33 -2
- package/package.json +1 -1
- package/scripts/postinstall.js +13 -8
- package/templates/commands/p.md +19 -6
- package/templates/commands/update.md +39 -0
|
@@ -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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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')
|
package/core/utils/version.ts
CHANGED
|
@@ -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(
|
|
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
|
}
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
12537
|
+
version: "0.29.5",
|
|
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
|
|
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 =
|
|
46
|
-
const templateDocsDir =
|
|
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 =
|
|
52
|
-
const destPath =
|
|
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 =
|
|
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 =
|
|
76
|
-
const templatePath =
|
|
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 =
|
|
143
|
-
this.claudeConfigPath =
|
|
144
|
-
this.templatesDir =
|
|
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 =
|
|
208
|
-
const destPath =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
336
|
-
const routerDest =
|
|
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 =
|
|
379
|
-
const destPath =
|
|
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");
|
|
@@ -44,10 +44,11 @@ var import_os3 = __toESM(require("os"));
|
|
|
44
44
|
var import_promises = __toESM(require("fs/promises"));
|
|
45
45
|
var import_path = __toESM(require("path"));
|
|
46
46
|
var import_os = __toESM(require("os"));
|
|
47
|
+
var import_version = require("../utils/version");
|
|
47
48
|
async function installDocs() {
|
|
48
49
|
try {
|
|
49
50
|
const docsDir = import_path.default.join(import_os.default.homedir(), ".prjct-cli", "docs");
|
|
50
|
-
const templateDocsDir = import_path.default.join(
|
|
51
|
+
const templateDocsDir = import_path.default.join((0, import_version.getPackageRoot)(), "templates/global/docs");
|
|
51
52
|
await import_promises.default.mkdir(docsDir, { recursive: true });
|
|
52
53
|
const docFiles = await import_promises.default.readdir(templateDocsDir);
|
|
53
54
|
for (const file of docFiles) {
|
|
@@ -77,7 +78,7 @@ async function installGlobalConfig(claudeConfigPath, detectClaude) {
|
|
|
77
78
|
const claudeDir = import_path.default.join(import_os.default.homedir(), ".claude");
|
|
78
79
|
await import_promises.default.mkdir(claudeDir, { recursive: true });
|
|
79
80
|
const globalConfigPath = import_path.default.join(claudeDir, "CLAUDE.md");
|
|
80
|
-
const templatePath = import_path.default.join(
|
|
81
|
+
const templatePath = import_path.default.join((0, import_version.getPackageRoot)(), "templates/global/CLAUDE.md");
|
|
81
82
|
const templateContent = await import_promises.default.readFile(templatePath, "utf-8");
|
|
82
83
|
let existingContent = "";
|
|
83
84
|
let fileExists = false;
|
|
@@ -145,7 +146,7 @@ var CommandInstaller = class {
|
|
|
145
146
|
this.homeDir = import_os.default.homedir();
|
|
146
147
|
this.claudeCommandsPath = import_path.default.join(this.homeDir, ".claude", "commands", "p");
|
|
147
148
|
this.claudeConfigPath = import_path.default.join(this.homeDir, ".claude");
|
|
148
|
-
this.templatesDir = import_path.default.join(
|
|
149
|
+
this.templatesDir = import_path.default.join((0, import_version.getPackageRoot)(), "templates", "commands");
|
|
149
150
|
}
|
|
150
151
|
/**
|
|
151
152
|
* Detect if Claude is installed
|
|
@@ -544,7 +545,7 @@ var editorsConfig = new EditorsConfig();
|
|
|
544
545
|
var editors_config_default = editorsConfig;
|
|
545
546
|
|
|
546
547
|
// core/infrastructure/setup.ts
|
|
547
|
-
var
|
|
548
|
+
var import_version2 = require("../utils/version");
|
|
548
549
|
var GREEN = "\x1B[32m";
|
|
549
550
|
var YELLOW = "\x1B[33m";
|
|
550
551
|
var DIM = "\x1B[2m";
|
|
@@ -605,7 +606,7 @@ async function run() {
|
|
|
605
606
|
await command_installer_default.installDocs();
|
|
606
607
|
await installStatusLine();
|
|
607
608
|
}
|
|
608
|
-
await editors_config_default.saveConfig(
|
|
609
|
+
await editors_config_default.saveConfig(import_version2.VERSION, command_installer_default.getInstallPath());
|
|
609
610
|
await migrateProjectsCliVersion();
|
|
610
611
|
showResults(results);
|
|
611
612
|
return results;
|
|
@@ -628,8 +629,8 @@ async function migrateProjectsCliVersion() {
|
|
|
628
629
|
try {
|
|
629
630
|
const content = import_fs.default.readFileSync(projectJsonPath, "utf8");
|
|
630
631
|
const project = JSON.parse(content);
|
|
631
|
-
if (project.cliVersion !==
|
|
632
|
-
project.cliVersion =
|
|
632
|
+
if (project.cliVersion !== import_version2.VERSION) {
|
|
633
|
+
project.cliVersion = import_version2.VERSION;
|
|
633
634
|
import_fs.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
634
635
|
migrated++;
|
|
635
636
|
}
|
|
@@ -637,7 +638,7 @@ async function migrateProjectsCliVersion() {
|
|
|
637
638
|
}
|
|
638
639
|
}
|
|
639
640
|
if (migrated > 0) {
|
|
640
|
-
console.log(` ${GREEN}\u2713${NC} Updated ${migrated} project(s) to v${
|
|
641
|
+
console.log(` ${GREEN}\u2713${NC} Updated ${migrated} project(s) to v${import_version2.VERSION}`);
|
|
641
642
|
}
|
|
642
643
|
} catch {
|
|
643
644
|
}
|
|
@@ -666,7 +667,7 @@ async function installStatusLine() {
|
|
|
666
667
|
const prjctLibDir = import_path3.default.join(prjctStatusLineDir, "lib");
|
|
667
668
|
const prjctComponentsDir = import_path3.default.join(prjctStatusLineDir, "components");
|
|
668
669
|
const prjctConfigPath = import_path3.default.join(prjctStatusLineDir, "config.json");
|
|
669
|
-
const assetsDir = import_path3.default.join(
|
|
670
|
+
const assetsDir = import_path3.default.join((0, import_version2.getPackageRoot)(), "assets", "statusline");
|
|
670
671
|
const sourceScript = import_path3.default.join(assetsDir, "statusline.sh");
|
|
671
672
|
const sourceThemeDir = import_path3.default.join(assetsDir, "themes");
|
|
672
673
|
const sourceLibDir = import_path3.default.join(assetsDir, "lib");
|
|
@@ -691,10 +692,10 @@ async function installStatusLine() {
|
|
|
691
692
|
const existingContent = import_fs.default.readFileSync(prjctStatusLinePath, "utf8");
|
|
692
693
|
if (existingContent.includes("CLI_VERSION=")) {
|
|
693
694
|
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
694
|
-
if (versionMatch && versionMatch[1] !==
|
|
695
|
+
if (versionMatch && versionMatch[1] !== import_version2.VERSION) {
|
|
695
696
|
const updatedContent = existingContent.replace(
|
|
696
697
|
/CLI_VERSION="[^"]*"/,
|
|
697
|
-
`CLI_VERSION="${
|
|
698
|
+
`CLI_VERSION="${import_version2.VERSION}"`
|
|
698
699
|
);
|
|
699
700
|
import_fs.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
700
701
|
}
|
|
@@ -709,7 +710,7 @@ async function installStatusLine() {
|
|
|
709
710
|
let scriptContent = import_fs.default.readFileSync(sourceScript, "utf8");
|
|
710
711
|
scriptContent = scriptContent.replace(
|
|
711
712
|
/CLI_VERSION="[^"]*"/,
|
|
712
|
-
`CLI_VERSION="${
|
|
713
|
+
`CLI_VERSION="${import_version2.VERSION}"`
|
|
713
714
|
);
|
|
714
715
|
import_fs.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
715
716
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
@@ -728,7 +729,7 @@ async function installStatusLine() {
|
|
|
728
729
|
} else {
|
|
729
730
|
const scriptContent = `#!/bin/bash
|
|
730
731
|
# prjct Status Line for Claude Code
|
|
731
|
-
CLI_VERSION="${
|
|
732
|
+
CLI_VERSION="${import_version2.VERSION}"
|
|
732
733
|
input=$(cat)
|
|
733
734
|
CWD=$(echo "$input" | jq -r '.workspace.current_dir // "~"' 2>/dev/null)
|
|
734
735
|
CONFIG="$CWD/.prjct/prjct.config.json"
|
|
@@ -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(
|
|
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
package/scripts/postinstall.js
CHANGED
|
@@ -154,10 +154,9 @@ function updateStatusLineVersion() {
|
|
|
154
154
|
* Main
|
|
155
155
|
*/
|
|
156
156
|
async function main() {
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
157
|
+
// ALWAYS run setup - don't try to detect global vs local
|
|
158
|
+
// Worst case: setup runs unnecessarily on local dev installs (harmless)
|
|
159
|
+
// Best case: setup actually works for all users
|
|
161
160
|
|
|
162
161
|
console.log('')
|
|
163
162
|
console.log(' prjct-cli postinstall')
|
|
@@ -169,17 +168,23 @@ async function main() {
|
|
|
169
168
|
}
|
|
170
169
|
|
|
171
170
|
// Run full setup
|
|
171
|
+
let success = false
|
|
172
172
|
if (hasBun()) {
|
|
173
|
-
await runSetupBun()
|
|
173
|
+
success = await runSetupBun()
|
|
174
174
|
} else {
|
|
175
|
-
await runSetupCompiled()
|
|
175
|
+
success = await runSetupCompiled()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (!success) {
|
|
179
|
+
console.log(' ⚠ Setup incomplete. Run: npx prjct-cli setup')
|
|
176
180
|
}
|
|
177
181
|
|
|
178
182
|
console.log('')
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
main().catch((error) => {
|
|
182
|
-
//
|
|
183
|
-
console.
|
|
186
|
+
// Log error but don't fail npm install
|
|
187
|
+
console.error(' postinstall error:', error.message)
|
|
188
|
+
console.log(' Run manually: npx prjct-cli setup')
|
|
184
189
|
process.exit(0)
|
|
185
190
|
})
|
package/templates/commands/p.md
CHANGED
|
@@ -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
|
|
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.
|
|
16
|
-
|
|
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
|
-
-
|
|
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
|
|
45
|
+
NOW find npm root and read the command template.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
allowed-tools: [Bash, Read, Write]
|
|
3
|
+
description: 'Update prjct-cli installation - sync commands, statusline, config'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# p. update - Update prjct-cli Installation
|
|
7
|
+
|
|
8
|
+
Run this after `npm update -g prjct-cli` to sync all components.
|
|
9
|
+
|
|
10
|
+
## What It Does
|
|
11
|
+
|
|
12
|
+
1. Syncs commands to `~/.claude/commands/p/`
|
|
13
|
+
2. Updates statusline in `~/.prjct-cli/statusline/`
|
|
14
|
+
3. Updates global CLAUDE.md config
|
|
15
|
+
4. Updates project versions
|
|
16
|
+
|
|
17
|
+
## Execute
|
|
18
|
+
|
|
19
|
+
Run the setup script directly:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
node "$(npm root -g)/prjct-cli/dist/core/infrastructure/setup.js"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If that fails, try with bun:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun "$(npm root -g)/prjct-cli/core/infrastructure/setup.ts"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Output
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
✓ prjct-cli updated to v{version}
|
|
35
|
+
|
|
36
|
+
Commands: {n} synced
|
|
37
|
+
Statusline: updated
|
|
38
|
+
Config: updated
|
|
39
|
+
```
|