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.
- package/assets/statusline/statusline.sh +2 -33
- 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 +150 -101
- package/dist/core/utils/version.js +33 -2
- package/package.json +1 -1
- package/templates/commands/p.md +19 -6
- package/templates/commands/update.md +63 -0
|
@@ -48,39 +48,8 @@ load_config
|
|
|
48
48
|
load_theme
|
|
49
49
|
parse_stdin "$INPUT"
|
|
50
50
|
|
|
51
|
-
#
|
|
52
|
-
#
|
|
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(
|
|
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.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
|
|
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");
|
|
@@ -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
|
|
40
|
-
var
|
|
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
|
|
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 =
|
|
50
|
-
const templateDocsDir =
|
|
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 =
|
|
56
|
-
const destPath =
|
|
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 =
|
|
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 =
|
|
80
|
-
const templatePath =
|
|
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 =
|
|
147
|
-
this.claudeConfigPath =
|
|
148
|
-
this.templatesDir =
|
|
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 =
|
|
212
|
-
const destPath =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
340
|
-
const routerDest =
|
|
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 =
|
|
383
|
-
const destPath =
|
|
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
|
|
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 =
|
|
437
|
-
this.configFile =
|
|
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(
|
|
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 =
|
|
618
|
-
if (!
|
|
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 =
|
|
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 =
|
|
625
|
-
if (!
|
|
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 =
|
|
678
|
+
const content = import_fs2.default.readFileSync(projectJsonPath, "utf8");
|
|
630
679
|
const project = JSON.parse(content);
|
|
631
|
-
if (project.cliVersion !==
|
|
632
|
-
project.cliVersion =
|
|
633
|
-
|
|
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${
|
|
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 (
|
|
697
|
+
if (import_fs2.default.existsSync(settingsPath)) {
|
|
649
698
|
try {
|
|
650
|
-
settings = JSON.parse(
|
|
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
|
-
|
|
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 =
|
|
661
|
-
const settingsPath =
|
|
662
|
-
const claudeStatusLinePath =
|
|
663
|
-
const prjctStatusLineDir =
|
|
664
|
-
const prjctStatusLinePath =
|
|
665
|
-
const prjctThemesDir =
|
|
666
|
-
const prjctLibDir =
|
|
667
|
-
const prjctComponentsDir =
|
|
668
|
-
const prjctConfigPath =
|
|
669
|
-
const assetsDir =
|
|
670
|
-
const sourceScript =
|
|
671
|
-
const sourceThemeDir =
|
|
672
|
-
const sourceLibDir =
|
|
673
|
-
const sourceComponentsDir =
|
|
674
|
-
const sourceConfigPath =
|
|
675
|
-
if (!
|
|
676
|
-
|
|
677
|
-
}
|
|
678
|
-
if (!
|
|
679
|
-
|
|
680
|
-
}
|
|
681
|
-
if (!
|
|
682
|
-
|
|
683
|
-
}
|
|
684
|
-
if (!
|
|
685
|
-
|
|
686
|
-
}
|
|
687
|
-
if (!
|
|
688
|
-
|
|
689
|
-
}
|
|
690
|
-
if (
|
|
691
|
-
const existingContent =
|
|
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] !==
|
|
743
|
+
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
695
744
|
const updatedContent = existingContent.replace(
|
|
696
745
|
/CLI_VERSION="[^"]*"/,
|
|
697
|
-
`CLI_VERSION="${
|
|
746
|
+
`CLI_VERSION="${VERSION}"`
|
|
698
747
|
);
|
|
699
|
-
|
|
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 (
|
|
709
|
-
let scriptContent =
|
|
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="${
|
|
761
|
+
`CLI_VERSION="${VERSION}"`
|
|
713
762
|
);
|
|
714
|
-
|
|
763
|
+
import_fs2.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
715
764
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
716
765
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
717
|
-
if (
|
|
718
|
-
const themes =
|
|
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 =
|
|
721
|
-
const dest =
|
|
722
|
-
|
|
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 (!
|
|
726
|
-
|
|
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="${
|
|
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
|
-
|
|
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 (!
|
|
819
|
+
if (!import_fs2.default.existsSync(sourceDir)) {
|
|
771
820
|
return;
|
|
772
821
|
}
|
|
773
|
-
const files =
|
|
822
|
+
const files = import_fs2.default.readdirSync(sourceDir);
|
|
774
823
|
for (const file of files) {
|
|
775
824
|
if (file.endsWith(".sh")) {
|
|
776
|
-
const src =
|
|
777
|
-
const dest =
|
|
778
|
-
|
|
779
|
-
|
|
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 (
|
|
787
|
-
const stats =
|
|
835
|
+
if (import_fs2.default.existsSync(linkPath)) {
|
|
836
|
+
const stats = import_fs2.default.lstatSync(linkPath);
|
|
788
837
|
if (stats.isSymbolicLink()) {
|
|
789
|
-
const existingTarget =
|
|
838
|
+
const existingTarget = import_fs2.default.readlinkSync(linkPath);
|
|
790
839
|
if (existingTarget === targetPath) {
|
|
791
840
|
return;
|
|
792
841
|
}
|
|
793
842
|
}
|
|
794
|
-
|
|
843
|
+
import_fs2.default.unlinkSync(linkPath);
|
|
795
844
|
}
|
|
796
|
-
|
|
845
|
+
import_fs2.default.symlinkSync(targetPath, linkPath);
|
|
797
846
|
} catch {
|
|
798
847
|
try {
|
|
799
|
-
if (
|
|
800
|
-
|
|
801
|
-
|
|
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(
|
|
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/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,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.
|