prjct-cli 0.35.4 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +84 -0
- package/README.md +64 -618
- package/bin/prjct.ts +128 -17
- package/core/agentic/template-executor.ts +14 -4
- package/core/cli/start.ts +397 -0
- package/core/commands/analysis.ts +6 -3
- package/core/commands/setup.ts +27 -17
- package/core/index.ts +101 -35
- package/core/infrastructure/ai-provider.ts +414 -0
- package/core/infrastructure/command-installer.ts +119 -42
- package/core/infrastructure/editors-config.ts +20 -6
- package/core/infrastructure/path-manager.ts +18 -9
- package/core/infrastructure/setup.ts +356 -62
- package/core/services/skill-service.ts +52 -16
- package/core/types/index.ts +12 -0
- package/core/types/provider.ts +134 -0
- package/core/utils/branding.ts +20 -3
- package/dist/bin/prjct.mjs +1482 -2763
- package/dist/core/infrastructure/command-installer.js +33 -2
- package/dist/core/infrastructure/editors-config.js +13 -3
- package/dist/core/infrastructure/setup.js +293 -73
- package/package.json +9 -9
- package/scripts/postinstall.js +17 -119
- package/templates/_bases/tracker-base.md +7 -5
- package/templates/agents/AGENTS.md +9 -1
- package/templates/commands/github.md +7 -5
- package/templates/commands/init.md +16 -0
- package/templates/commands/jira.md +8 -6
- package/templates/commands/linear.md +8 -6
- package/templates/commands/monday.md +8 -6
- package/templates/commands/p.md +1 -1
- package/templates/commands/p.toml +37 -0
- package/templates/commands/sync.md +11 -1
- package/templates/cursor/p.md +29 -0
- package/templates/cursor/router.mdc +28 -0
- package/templates/global/CLAUDE.md +33 -1
- package/templates/global/CURSOR.mdc +233 -0
- package/templates/global/GEMINI.md +265 -0
- package/templates/global/STORAGE-SPEC.md +256 -0
- package/templates/global/docs/agents.md +88 -0
- package/templates/global/docs/architecture.md +103 -0
- package/templates/global/docs/commands.md +96 -0
- package/templates/global/docs/validation.md +95 -0
|
@@ -33,8 +33,10 @@ var command_installer_exports = {};
|
|
|
33
33
|
__export(command_installer_exports, {
|
|
34
34
|
CommandInstaller: () => CommandInstaller,
|
|
35
35
|
default: () => command_installer_default,
|
|
36
|
+
getProviderPaths: () => getProviderPaths,
|
|
36
37
|
installDocs: () => installDocs,
|
|
37
|
-
installGlobalConfig: () => installGlobalConfig
|
|
38
|
+
installGlobalConfig: () => installGlobalConfig,
|
|
39
|
+
isRouterInstalled: () => isRouterInstalled
|
|
38
40
|
});
|
|
39
41
|
module.exports = __toCommonJS(command_installer_exports);
|
|
40
42
|
var import_promises = __toESM(require("fs/promises"));
|
|
@@ -489,11 +491,40 @@ var CommandInstaller = class {
|
|
|
489
491
|
return installDocs();
|
|
490
492
|
}
|
|
491
493
|
};
|
|
494
|
+
function getProviderPaths() {
|
|
495
|
+
const homeDir = import_os.default.homedir();
|
|
496
|
+
return {
|
|
497
|
+
claude: {
|
|
498
|
+
commands: import_path2.default.join(homeDir, ".claude", "commands", "p"),
|
|
499
|
+
config: import_path2.default.join(homeDir, ".claude"),
|
|
500
|
+
router: import_path2.default.join(homeDir, ".claude", "commands", "p.md")
|
|
501
|
+
},
|
|
502
|
+
gemini: {
|
|
503
|
+
commands: import_path2.default.join(homeDir, ".gemini", "commands"),
|
|
504
|
+
config: import_path2.default.join(homeDir, ".gemini"),
|
|
505
|
+
router: import_path2.default.join(homeDir, ".gemini", "commands", "p.toml")
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
__name(getProviderPaths, "getProviderPaths");
|
|
510
|
+
async function isRouterInstalled(provider) {
|
|
511
|
+
const paths = getProviderPaths();
|
|
512
|
+
const routerPath = paths[provider].router;
|
|
513
|
+
try {
|
|
514
|
+
await import_promises.default.access(routerPath);
|
|
515
|
+
return true;
|
|
516
|
+
} catch {
|
|
517
|
+
return false;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
__name(isRouterInstalled, "isRouterInstalled");
|
|
492
521
|
var commandInstaller = new CommandInstaller();
|
|
493
522
|
var command_installer_default = commandInstaller;
|
|
494
523
|
// Annotate the CommonJS export names for ESM import in node:
|
|
495
524
|
0 && (module.exports = {
|
|
496
525
|
CommandInstaller,
|
|
526
|
+
getProviderPaths,
|
|
497
527
|
installDocs,
|
|
498
|
-
installGlobalConfig
|
|
528
|
+
installGlobalConfig,
|
|
529
|
+
isRouterInstalled
|
|
499
530
|
});
|
|
@@ -77,14 +77,16 @@ var EditorsConfig = class {
|
|
|
77
77
|
/**
|
|
78
78
|
* Save installation configuration
|
|
79
79
|
*/
|
|
80
|
-
async saveConfig(version,
|
|
80
|
+
async saveConfig(version, installPath, provider = "claude") {
|
|
81
81
|
try {
|
|
82
82
|
await this.ensureConfigDir();
|
|
83
83
|
const config = {
|
|
84
84
|
version,
|
|
85
|
-
editor:
|
|
85
|
+
editor: provider,
|
|
86
|
+
// deprecated, kept for backward compatibility
|
|
87
|
+
provider,
|
|
86
88
|
lastInstall: (/* @__PURE__ */ new Date()).toISOString(),
|
|
87
|
-
path:
|
|
89
|
+
path: installPath
|
|
88
90
|
};
|
|
89
91
|
await import_promises.default.writeFile(this.configFile, JSON.stringify(config, null, 2), "utf-8");
|
|
90
92
|
return true;
|
|
@@ -93,6 +95,14 @@ var EditorsConfig = class {
|
|
|
93
95
|
return false;
|
|
94
96
|
}
|
|
95
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Get the configured provider
|
|
100
|
+
*/
|
|
101
|
+
async getProvider() {
|
|
102
|
+
const config = await this.loadConfig();
|
|
103
|
+
if (!config) return null;
|
|
104
|
+
return config.provider || config.editor || "claude";
|
|
105
|
+
}
|
|
96
106
|
/**
|
|
97
107
|
* Get last installed version
|
|
98
108
|
*/
|
|
@@ -35,10 +35,10 @@ __export(setup_exports, {
|
|
|
35
35
|
run: () => run
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(setup_exports);
|
|
38
|
-
var
|
|
38
|
+
var import_child_process2 = require("child_process");
|
|
39
39
|
var import_fs3 = __toESM(require("fs"));
|
|
40
|
-
var
|
|
41
|
-
var
|
|
40
|
+
var import_path5 = __toESM(require("path"));
|
|
41
|
+
var import_os4 = __toESM(require("os"));
|
|
42
42
|
|
|
43
43
|
// core/infrastructure/command-installer.ts
|
|
44
44
|
var import_promises = __toESM(require("fs/promises"));
|
|
@@ -540,14 +540,16 @@ var EditorsConfig = class {
|
|
|
540
540
|
/**
|
|
541
541
|
* Save installation configuration
|
|
542
542
|
*/
|
|
543
|
-
async saveConfig(version,
|
|
543
|
+
async saveConfig(version, installPath, provider = "claude") {
|
|
544
544
|
try {
|
|
545
545
|
await this.ensureConfigDir();
|
|
546
546
|
const config = {
|
|
547
547
|
version,
|
|
548
|
-
editor:
|
|
548
|
+
editor: provider,
|
|
549
|
+
// deprecated, kept for backward compatibility
|
|
550
|
+
provider,
|
|
549
551
|
lastInstall: (/* @__PURE__ */ new Date()).toISOString(),
|
|
550
|
-
path:
|
|
552
|
+
path: installPath
|
|
551
553
|
};
|
|
552
554
|
await import_promises2.default.writeFile(this.configFile, JSON.stringify(config, null, 2), "utf-8");
|
|
553
555
|
return true;
|
|
@@ -556,6 +558,14 @@ var EditorsConfig = class {
|
|
|
556
558
|
return false;
|
|
557
559
|
}
|
|
558
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* Get the configured provider
|
|
563
|
+
*/
|
|
564
|
+
async getProvider() {
|
|
565
|
+
const config = await this.loadConfig();
|
|
566
|
+
if (!config) return null;
|
|
567
|
+
return config.provider || config.editor || "claude";
|
|
568
|
+
}
|
|
559
569
|
/**
|
|
560
570
|
* Get last installed version
|
|
561
571
|
*/
|
|
@@ -619,84 +629,294 @@ var EditorsConfig = class {
|
|
|
619
629
|
var editorsConfig = new EditorsConfig();
|
|
620
630
|
var editors_config_default = editorsConfig;
|
|
621
631
|
|
|
632
|
+
// core/infrastructure/ai-provider.ts
|
|
633
|
+
var import_child_process = require("child_process");
|
|
634
|
+
var import_path4 = __toESM(require("path"));
|
|
635
|
+
var import_os3 = __toESM(require("os"));
|
|
636
|
+
var ClaudeProvider = {
|
|
637
|
+
name: "claude",
|
|
638
|
+
displayName: "Claude Code",
|
|
639
|
+
cliCommand: "claude",
|
|
640
|
+
configDir: import_path4.default.join(import_os3.default.homedir(), ".claude"),
|
|
641
|
+
contextFile: "CLAUDE.md",
|
|
642
|
+
skillsDir: import_path4.default.join(import_os3.default.homedir(), ".claude", "skills"),
|
|
643
|
+
commandsDir: ".claude/commands",
|
|
644
|
+
commandFormat: "md",
|
|
645
|
+
settingsFile: "settings.json",
|
|
646
|
+
projectSettingsFile: "settings.local.json",
|
|
647
|
+
ignoreFile: ".claudeignore",
|
|
648
|
+
websiteUrl: "https://www.anthropic.com/claude",
|
|
649
|
+
docsUrl: "https://docs.anthropic.com/claude-code"
|
|
650
|
+
};
|
|
651
|
+
var GeminiProvider = {
|
|
652
|
+
name: "gemini",
|
|
653
|
+
displayName: "Gemini CLI",
|
|
654
|
+
cliCommand: "gemini",
|
|
655
|
+
configDir: import_path4.default.join(import_os3.default.homedir(), ".gemini"),
|
|
656
|
+
contextFile: "GEMINI.md",
|
|
657
|
+
skillsDir: import_path4.default.join(import_os3.default.homedir(), ".gemini", "skills"),
|
|
658
|
+
commandsDir: ".gemini/commands",
|
|
659
|
+
commandFormat: "toml",
|
|
660
|
+
settingsFile: "settings.json",
|
|
661
|
+
projectSettingsFile: "settings.json",
|
|
662
|
+
ignoreFile: ".geminiignore",
|
|
663
|
+
websiteUrl: "https://geminicli.com",
|
|
664
|
+
docsUrl: "https://geminicli.com/docs"
|
|
665
|
+
};
|
|
666
|
+
var Providers = {
|
|
667
|
+
claude: ClaudeProvider,
|
|
668
|
+
gemini: GeminiProvider
|
|
669
|
+
};
|
|
670
|
+
function whichCommand(command) {
|
|
671
|
+
try {
|
|
672
|
+
const result = (0, import_child_process.execSync)(`which ${command}`, { stdio: "pipe", encoding: "utf-8" });
|
|
673
|
+
return result.trim();
|
|
674
|
+
} catch {
|
|
675
|
+
return null;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
__name(whichCommand, "whichCommand");
|
|
679
|
+
function getCliVersion(command) {
|
|
680
|
+
try {
|
|
681
|
+
const result = (0, import_child_process.execSync)(`${command} --version`, { stdio: "pipe", encoding: "utf-8" });
|
|
682
|
+
const match = result.match(/\d+\.\d+\.\d+/);
|
|
683
|
+
return match ? match[0] : result.trim();
|
|
684
|
+
} catch {
|
|
685
|
+
return null;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
__name(getCliVersion, "getCliVersion");
|
|
689
|
+
function detectProvider(provider) {
|
|
690
|
+
const config = Providers[provider];
|
|
691
|
+
const cliPath = whichCommand(config.cliCommand);
|
|
692
|
+
if (!cliPath) {
|
|
693
|
+
return { installed: false };
|
|
694
|
+
}
|
|
695
|
+
const version = getCliVersion(config.cliCommand);
|
|
696
|
+
return {
|
|
697
|
+
installed: true,
|
|
698
|
+
version: version || void 0,
|
|
699
|
+
path: cliPath
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
__name(detectProvider, "detectProvider");
|
|
703
|
+
function detectAllProviders() {
|
|
704
|
+
return {
|
|
705
|
+
claude: detectProvider("claude"),
|
|
706
|
+
gemini: detectProvider("gemini")
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
__name(detectAllProviders, "detectAllProviders");
|
|
710
|
+
function selectProvider() {
|
|
711
|
+
const detection = detectAllProviders();
|
|
712
|
+
const claudeInstalled = detection.claude.installed;
|
|
713
|
+
const geminiInstalled = detection.gemini.installed;
|
|
714
|
+
if (!claudeInstalled && !geminiInstalled) {
|
|
715
|
+
return {
|
|
716
|
+
provider: "claude",
|
|
717
|
+
userSelected: false,
|
|
718
|
+
detection
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
if (claudeInstalled && !geminiInstalled) {
|
|
722
|
+
return {
|
|
723
|
+
provider: "claude",
|
|
724
|
+
userSelected: false,
|
|
725
|
+
detection
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
if (geminiInstalled && !claudeInstalled) {
|
|
729
|
+
return {
|
|
730
|
+
provider: "gemini",
|
|
731
|
+
userSelected: false,
|
|
732
|
+
detection
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
return {
|
|
736
|
+
provider: "claude",
|
|
737
|
+
userSelected: true,
|
|
738
|
+
// Indicates user should be prompted
|
|
739
|
+
detection
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
__name(selectProvider, "selectProvider");
|
|
743
|
+
|
|
622
744
|
// core/infrastructure/setup.ts
|
|
623
745
|
var GREEN = "\x1B[32m";
|
|
624
746
|
var YELLOW = "\x1B[33m";
|
|
625
747
|
var DIM = "\x1B[2m";
|
|
626
748
|
var NC = "\x1B[0m";
|
|
627
|
-
async function
|
|
628
|
-
|
|
629
|
-
(0, import_child_process.execSync)("which claude", { stdio: "ignore" });
|
|
630
|
-
return true;
|
|
631
|
-
} catch (_error) {
|
|
632
|
-
return false;
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
__name(hasClaudeCodeCLI, "hasClaudeCodeCLI");
|
|
636
|
-
async function installClaudeCode() {
|
|
749
|
+
async function installAICLI(provider) {
|
|
750
|
+
const packageName = provider.name === "claude" ? "@anthropic-ai/claude-code" : "@google/gemini-cli";
|
|
637
751
|
try {
|
|
638
|
-
console.log(`${YELLOW}\u{1F4E6}
|
|
752
|
+
console.log(`${YELLOW}\u{1F4E6} ${provider.displayName} not found. Installing...${NC}`);
|
|
639
753
|
console.log("");
|
|
640
|
-
(0,
|
|
754
|
+
(0, import_child_process2.execSync)(`npm install -g ${packageName}`, { stdio: "inherit" });
|
|
641
755
|
console.log("");
|
|
642
|
-
console.log(`${GREEN}\u2713${NC}
|
|
756
|
+
console.log(`${GREEN}\u2713${NC} ${provider.displayName} installed successfully`);
|
|
643
757
|
console.log("");
|
|
644
758
|
return true;
|
|
645
759
|
} catch (error) {
|
|
646
|
-
console.log(`${YELLOW}\u26A0\uFE0F Failed to install
|
|
647
|
-
console.log(`${DIM}Please install manually: npm install -g
|
|
760
|
+
console.log(`${YELLOW}\u26A0\uFE0F Failed to install ${provider.displayName}: ${error.message}${NC}`);
|
|
761
|
+
console.log(`${DIM}Please install manually: npm install -g ${packageName}${NC}`);
|
|
648
762
|
console.log("");
|
|
649
763
|
return false;
|
|
650
764
|
}
|
|
651
765
|
}
|
|
652
|
-
__name(
|
|
766
|
+
__name(installAICLI, "installAICLI");
|
|
653
767
|
async function run() {
|
|
768
|
+
const detection = detectAllProviders();
|
|
769
|
+
const selection = selectProvider();
|
|
770
|
+
const primaryProvider = Providers[selection.provider];
|
|
654
771
|
const results = {
|
|
655
|
-
|
|
772
|
+
provider: selection.provider,
|
|
773
|
+
providers: [],
|
|
774
|
+
cliInstalled: false,
|
|
656
775
|
commandsAdded: 0,
|
|
657
776
|
commandsUpdated: 0,
|
|
658
777
|
configAction: null
|
|
659
778
|
};
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
const
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
779
|
+
const providerNames = ["claude", "gemini"];
|
|
780
|
+
for (const providerName of providerNames) {
|
|
781
|
+
const providerConfig = Providers[providerName];
|
|
782
|
+
const providerDetection = detection[providerName];
|
|
783
|
+
const providerResult = {
|
|
784
|
+
provider: providerName,
|
|
785
|
+
cliInstalled: false,
|
|
786
|
+
commandsAdded: 0,
|
|
787
|
+
commandsUpdated: 0,
|
|
788
|
+
configAction: null
|
|
789
|
+
};
|
|
790
|
+
if (!providerDetection.installed) {
|
|
791
|
+
if (providerName === selection.provider) {
|
|
792
|
+
const installed = await installAICLI(providerConfig);
|
|
793
|
+
if (installed) {
|
|
794
|
+
providerResult.cliInstalled = true;
|
|
795
|
+
results.cliInstalled = true;
|
|
796
|
+
} else {
|
|
797
|
+
throw new Error(`${providerConfig.displayName} installation failed`);
|
|
798
|
+
}
|
|
799
|
+
} else {
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
675
802
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
803
|
+
if (providerName === "claude") {
|
|
804
|
+
const claudeDetected = await command_installer_default.detectClaude();
|
|
805
|
+
if (claudeDetected) {
|
|
806
|
+
const syncResult = await command_installer_default.syncCommands();
|
|
807
|
+
if (syncResult.success) {
|
|
808
|
+
providerResult.commandsAdded = syncResult.added;
|
|
809
|
+
providerResult.commandsUpdated = syncResult.updated;
|
|
810
|
+
results.commandsAdded += syncResult.added;
|
|
811
|
+
results.commandsUpdated += syncResult.updated;
|
|
812
|
+
}
|
|
813
|
+
const configResult = await command_installer_default.installGlobalConfig();
|
|
814
|
+
if (configResult.success) {
|
|
815
|
+
providerResult.configAction = configResult.action;
|
|
816
|
+
if (!results.configAction) {
|
|
817
|
+
results.configAction = configResult.action;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
await command_installer_default.installDocs();
|
|
821
|
+
await installStatusLine();
|
|
822
|
+
}
|
|
823
|
+
} else if (providerName === "gemini") {
|
|
824
|
+
const geminiInstalled = await installGeminiRouter();
|
|
825
|
+
if (geminiInstalled) {
|
|
826
|
+
providerResult.commandsAdded = 1;
|
|
827
|
+
results.commandsAdded += 1;
|
|
828
|
+
}
|
|
829
|
+
const geminiConfigResult = await installGeminiGlobalConfig();
|
|
830
|
+
if (geminiConfigResult.success) {
|
|
831
|
+
providerResult.configAction = geminiConfigResult.action;
|
|
832
|
+
}
|
|
679
833
|
}
|
|
680
|
-
|
|
681
|
-
await installStatusLine();
|
|
834
|
+
results.providers.push(providerResult);
|
|
682
835
|
}
|
|
683
|
-
await editors_config_default.saveConfig(VERSION, command_installer_default.getInstallPath());
|
|
836
|
+
await editors_config_default.saveConfig(VERSION, command_installer_default.getInstallPath(), selection.provider);
|
|
684
837
|
await migrateProjectsCliVersion();
|
|
685
|
-
|
|
838
|
+
for (const providerResult of results.providers) {
|
|
839
|
+
showResults(providerResult, Providers[providerResult.provider]);
|
|
840
|
+
}
|
|
686
841
|
return results;
|
|
687
842
|
}
|
|
688
843
|
__name(run, "run");
|
|
689
844
|
var setup_default = { run };
|
|
845
|
+
async function installGeminiRouter() {
|
|
846
|
+
try {
|
|
847
|
+
const geminiCommandsDir = import_path5.default.join(import_os4.default.homedir(), ".gemini", "commands");
|
|
848
|
+
const routerSource = import_path5.default.join(getPackageRoot(), "templates", "commands", "p.toml");
|
|
849
|
+
const routerDest = import_path5.default.join(geminiCommandsDir, "p.toml");
|
|
850
|
+
import_fs3.default.mkdirSync(geminiCommandsDir, { recursive: true });
|
|
851
|
+
if (import_fs3.default.existsSync(routerSource)) {
|
|
852
|
+
import_fs3.default.copyFileSync(routerSource, routerDest);
|
|
853
|
+
return true;
|
|
854
|
+
}
|
|
855
|
+
return false;
|
|
856
|
+
} catch (error) {
|
|
857
|
+
console.error(`Gemini router warning: ${error.message}`);
|
|
858
|
+
return false;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
__name(installGeminiRouter, "installGeminiRouter");
|
|
862
|
+
async function installGeminiGlobalConfig() {
|
|
863
|
+
try {
|
|
864
|
+
const geminiDir = import_path5.default.join(import_os4.default.homedir(), ".gemini");
|
|
865
|
+
const globalConfigPath = import_path5.default.join(geminiDir, "GEMINI.md");
|
|
866
|
+
const templatePath = import_path5.default.join(getPackageRoot(), "templates", "global", "GEMINI.md");
|
|
867
|
+
import_fs3.default.mkdirSync(geminiDir, { recursive: true });
|
|
868
|
+
const templateContent = import_fs3.default.readFileSync(templatePath, "utf-8");
|
|
869
|
+
let existingContent = "";
|
|
870
|
+
let fileExists = false;
|
|
871
|
+
try {
|
|
872
|
+
existingContent = import_fs3.default.readFileSync(globalConfigPath, "utf-8");
|
|
873
|
+
fileExists = true;
|
|
874
|
+
} catch (error) {
|
|
875
|
+
if (isNotFoundError(error)) {
|
|
876
|
+
fileExists = false;
|
|
877
|
+
} else {
|
|
878
|
+
throw error;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
if (!fileExists) {
|
|
882
|
+
import_fs3.default.writeFileSync(globalConfigPath, templateContent, "utf-8");
|
|
883
|
+
return { success: true, action: "created" };
|
|
884
|
+
}
|
|
885
|
+
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
886
|
+
const endMarker = "<!-- prjct:end - DO NOT REMOVE THIS MARKER -->";
|
|
887
|
+
const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
|
|
888
|
+
if (!hasMarkers) {
|
|
889
|
+
const updatedContent2 = existingContent + "\n\n" + templateContent;
|
|
890
|
+
import_fs3.default.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
|
|
891
|
+
return { success: true, action: "appended" };
|
|
892
|
+
}
|
|
893
|
+
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
|
|
894
|
+
const afterMarker = existingContent.substring(
|
|
895
|
+
existingContent.indexOf(endMarker) + endMarker.length
|
|
896
|
+
);
|
|
897
|
+
const prjctSection = templateContent.substring(
|
|
898
|
+
templateContent.indexOf(startMarker),
|
|
899
|
+
templateContent.indexOf(endMarker) + endMarker.length
|
|
900
|
+
);
|
|
901
|
+
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
902
|
+
import_fs3.default.writeFileSync(globalConfigPath, updatedContent, "utf-8");
|
|
903
|
+
return { success: true, action: "updated" };
|
|
904
|
+
} catch (error) {
|
|
905
|
+
console.error(`Gemini config warning: ${error.message}`);
|
|
906
|
+
return { success: false, action: null };
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
__name(installGeminiGlobalConfig, "installGeminiGlobalConfig");
|
|
690
910
|
async function migrateProjectsCliVersion() {
|
|
691
911
|
try {
|
|
692
|
-
const projectsDir =
|
|
912
|
+
const projectsDir = import_path5.default.join(import_os4.default.homedir(), ".prjct-cli", "projects");
|
|
693
913
|
if (!import_fs3.default.existsSync(projectsDir)) {
|
|
694
914
|
return;
|
|
695
915
|
}
|
|
696
916
|
const projectDirs = import_fs3.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
697
917
|
let migrated = 0;
|
|
698
918
|
for (const projectId of projectDirs) {
|
|
699
|
-
const projectJsonPath =
|
|
919
|
+
const projectJsonPath = import_path5.default.join(projectsDir, projectId, "project.json");
|
|
700
920
|
if (!import_fs3.default.existsSync(projectJsonPath)) {
|
|
701
921
|
continue;
|
|
702
922
|
}
|
|
@@ -741,21 +961,21 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
|
741
961
|
__name(ensureStatusLineSettings, "ensureStatusLineSettings");
|
|
742
962
|
async function installStatusLine() {
|
|
743
963
|
try {
|
|
744
|
-
const claudeDir =
|
|
745
|
-
const settingsPath =
|
|
746
|
-
const claudeStatusLinePath =
|
|
747
|
-
const prjctStatusLineDir =
|
|
748
|
-
const prjctStatusLinePath =
|
|
749
|
-
const prjctThemesDir =
|
|
750
|
-
const prjctLibDir =
|
|
751
|
-
const prjctComponentsDir =
|
|
752
|
-
const prjctConfigPath =
|
|
753
|
-
const assetsDir =
|
|
754
|
-
const sourceScript =
|
|
755
|
-
const sourceThemeDir =
|
|
756
|
-
const sourceLibDir =
|
|
757
|
-
const sourceComponentsDir =
|
|
758
|
-
const sourceConfigPath =
|
|
964
|
+
const claudeDir = import_path5.default.join(import_os4.default.homedir(), ".claude");
|
|
965
|
+
const settingsPath = import_path5.default.join(claudeDir, "settings.json");
|
|
966
|
+
const claudeStatusLinePath = import_path5.default.join(claudeDir, "prjct-statusline.sh");
|
|
967
|
+
const prjctStatusLineDir = import_path5.default.join(import_os4.default.homedir(), ".prjct-cli", "statusline");
|
|
968
|
+
const prjctStatusLinePath = import_path5.default.join(prjctStatusLineDir, "statusline.sh");
|
|
969
|
+
const prjctThemesDir = import_path5.default.join(prjctStatusLineDir, "themes");
|
|
970
|
+
const prjctLibDir = import_path5.default.join(prjctStatusLineDir, "lib");
|
|
971
|
+
const prjctComponentsDir = import_path5.default.join(prjctStatusLineDir, "components");
|
|
972
|
+
const prjctConfigPath = import_path5.default.join(prjctStatusLineDir, "config.json");
|
|
973
|
+
const assetsDir = import_path5.default.join(getPackageRoot(), "assets", "statusline");
|
|
974
|
+
const sourceScript = import_path5.default.join(assetsDir, "statusline.sh");
|
|
975
|
+
const sourceThemeDir = import_path5.default.join(assetsDir, "themes");
|
|
976
|
+
const sourceLibDir = import_path5.default.join(assetsDir, "lib");
|
|
977
|
+
const sourceComponentsDir = import_path5.default.join(assetsDir, "components");
|
|
978
|
+
const sourceConfigPath = import_path5.default.join(assetsDir, "default-config.json");
|
|
759
979
|
if (!import_fs3.default.existsSync(claudeDir)) {
|
|
760
980
|
import_fs3.default.mkdirSync(claudeDir, { recursive: true });
|
|
761
981
|
}
|
|
@@ -801,8 +1021,8 @@ async function installStatusLine() {
|
|
|
801
1021
|
if (import_fs3.default.existsSync(sourceThemeDir)) {
|
|
802
1022
|
const themes = import_fs3.default.readdirSync(sourceThemeDir);
|
|
803
1023
|
for (const theme of themes) {
|
|
804
|
-
const src =
|
|
805
|
-
const dest =
|
|
1024
|
+
const src = import_path5.default.join(sourceThemeDir, theme);
|
|
1025
|
+
const dest = import_path5.default.join(prjctThemesDir, theme);
|
|
806
1026
|
import_fs3.default.copyFileSync(src, dest);
|
|
807
1027
|
}
|
|
808
1028
|
}
|
|
@@ -860,8 +1080,8 @@ function installStatusLineModules(sourceDir, destDir) {
|
|
|
860
1080
|
const files = import_fs3.default.readdirSync(sourceDir);
|
|
861
1081
|
for (const file of files) {
|
|
862
1082
|
if (file.endsWith(".sh")) {
|
|
863
|
-
const src =
|
|
864
|
-
const dest =
|
|
1083
|
+
const src = import_path5.default.join(sourceDir, file);
|
|
1084
|
+
const dest = import_path5.default.join(destDir, file);
|
|
865
1085
|
import_fs3.default.copyFileSync(src, dest);
|
|
866
1086
|
import_fs3.default.chmodSync(dest, 493);
|
|
867
1087
|
}
|
|
@@ -895,12 +1115,12 @@ function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
|
895
1115
|
}
|
|
896
1116
|
}
|
|
897
1117
|
__name(ensureStatusLineSymlink, "ensureStatusLineSymlink");
|
|
898
|
-
function showResults(results) {
|
|
1118
|
+
function showResults(results, provider) {
|
|
899
1119
|
console.log("");
|
|
900
|
-
if (results.
|
|
901
|
-
console.log(` ${GREEN}\u2713${NC}
|
|
1120
|
+
if (results.cliInstalled) {
|
|
1121
|
+
console.log(` ${GREEN}\u2713${NC} ${provider.displayName} CLI installed`);
|
|
902
1122
|
} else {
|
|
903
|
-
console.log(` ${GREEN}\u2713${NC}
|
|
1123
|
+
console.log(` ${GREEN}\u2713${NC} ${provider.displayName} CLI found`);
|
|
904
1124
|
}
|
|
905
1125
|
const totalCommands = results.commandsAdded + results.commandsUpdated;
|
|
906
1126
|
if (totalCommands > 0) {
|
|
@@ -912,11 +1132,11 @@ function showResults(results) {
|
|
|
912
1132
|
console.log(` ${GREEN}\u2713${NC} Commands up to date`);
|
|
913
1133
|
}
|
|
914
1134
|
if (results.configAction === "created") {
|
|
915
|
-
console.log(` ${GREEN}\u2713${NC} Global config created`);
|
|
1135
|
+
console.log(` ${GREEN}\u2713${NC} Global config created (${provider.contextFile})`);
|
|
916
1136
|
} else if (results.configAction === "updated") {
|
|
917
|
-
console.log(` ${GREEN}\u2713${NC} Global config updated`);
|
|
1137
|
+
console.log(` ${GREEN}\u2713${NC} Global config updated (${provider.contextFile})`);
|
|
918
1138
|
} else if (results.configAction === "appended") {
|
|
919
|
-
console.log(` ${GREEN}\u2713${NC} Global config merged`);
|
|
1139
|
+
console.log(` ${GREEN}\u2713${NC} Global config merged (${provider.contextFile})`);
|
|
920
1140
|
}
|
|
921
1141
|
console.log("");
|
|
922
1142
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prjct-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.37.0",
|
|
4
|
+
"description": "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
5
5
|
"main": "core/index.ts",
|
|
6
6
|
"bin": {
|
|
7
7
|
"prjct": "bin/prjct"
|
|
@@ -34,15 +34,15 @@
|
|
|
34
34
|
},
|
|
35
35
|
"keywords": [
|
|
36
36
|
"claude-code",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
37
|
+
"gemini-cli",
|
|
38
|
+
"ai-agents",
|
|
39
|
+
"context-layer",
|
|
40
|
+
"developer-tools",
|
|
41
41
|
"ai-assistant",
|
|
42
42
|
"productivity",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
43
|
+
"mcp",
|
|
44
|
+
"llm",
|
|
45
|
+
"coding-agents"
|
|
46
46
|
],
|
|
47
47
|
"author": "prjct.app",
|
|
48
48
|
"license": "MIT",
|