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.
Files changed (43) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +64 -618
  3. package/bin/prjct.ts +128 -17
  4. package/core/agentic/template-executor.ts +14 -4
  5. package/core/cli/start.ts +397 -0
  6. package/core/commands/analysis.ts +6 -3
  7. package/core/commands/setup.ts +27 -17
  8. package/core/index.ts +101 -35
  9. package/core/infrastructure/ai-provider.ts +414 -0
  10. package/core/infrastructure/command-installer.ts +119 -42
  11. package/core/infrastructure/editors-config.ts +20 -6
  12. package/core/infrastructure/path-manager.ts +18 -9
  13. package/core/infrastructure/setup.ts +356 -62
  14. package/core/services/skill-service.ts +52 -16
  15. package/core/types/index.ts +12 -0
  16. package/core/types/provider.ts +134 -0
  17. package/core/utils/branding.ts +20 -3
  18. package/dist/bin/prjct.mjs +1482 -2763
  19. package/dist/core/infrastructure/command-installer.js +33 -2
  20. package/dist/core/infrastructure/editors-config.js +13 -3
  21. package/dist/core/infrastructure/setup.js +293 -73
  22. package/package.json +9 -9
  23. package/scripts/postinstall.js +17 -119
  24. package/templates/_bases/tracker-base.md +7 -5
  25. package/templates/agents/AGENTS.md +9 -1
  26. package/templates/commands/github.md +7 -5
  27. package/templates/commands/init.md +16 -0
  28. package/templates/commands/jira.md +8 -6
  29. package/templates/commands/linear.md +8 -6
  30. package/templates/commands/monday.md +8 -6
  31. package/templates/commands/p.md +1 -1
  32. package/templates/commands/p.toml +37 -0
  33. package/templates/commands/sync.md +11 -1
  34. package/templates/cursor/p.md +29 -0
  35. package/templates/cursor/router.mdc +28 -0
  36. package/templates/global/CLAUDE.md +33 -1
  37. package/templates/global/CURSOR.mdc +233 -0
  38. package/templates/global/GEMINI.md +265 -0
  39. package/templates/global/STORAGE-SPEC.md +256 -0
  40. package/templates/global/docs/agents.md +88 -0
  41. package/templates/global/docs/architecture.md +103 -0
  42. package/templates/global/docs/commands.md +96 -0
  43. 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, claudePath) {
80
+ async saveConfig(version, installPath, provider = "claude") {
81
81
  try {
82
82
  await this.ensureConfigDir();
83
83
  const config = {
84
84
  version,
85
- editor: "claude",
85
+ editor: provider,
86
+ // deprecated, kept for backward compatibility
87
+ provider,
86
88
  lastInstall: (/* @__PURE__ */ new Date()).toISOString(),
87
- path: claudePath
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 import_child_process = require("child_process");
38
+ var import_child_process2 = require("child_process");
39
39
  var import_fs3 = __toESM(require("fs"));
40
- var import_path4 = __toESM(require("path"));
41
- var import_os3 = __toESM(require("os"));
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, claudePath) {
543
+ async saveConfig(version, installPath, provider = "claude") {
544
544
  try {
545
545
  await this.ensureConfigDir();
546
546
  const config = {
547
547
  version,
548
- editor: "claude",
548
+ editor: provider,
549
+ // deprecated, kept for backward compatibility
550
+ provider,
549
551
  lastInstall: (/* @__PURE__ */ new Date()).toISOString(),
550
- path: claudePath
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 hasClaudeCodeCLI() {
628
- try {
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} Claude Code not found. Installing...${NC}`);
752
+ console.log(`${YELLOW}\u{1F4E6} ${provider.displayName} not found. Installing...${NC}`);
639
753
  console.log("");
640
- (0, import_child_process.execSync)("npm install -g @anthropic-ai/claude-code", { stdio: "inherit" });
754
+ (0, import_child_process2.execSync)(`npm install -g ${packageName}`, { stdio: "inherit" });
641
755
  console.log("");
642
- console.log(`${GREEN}\u2713${NC} Claude Code installed successfully`);
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 Claude Code: ${error.message}${NC}`);
647
- console.log(`${DIM}Please install manually: npm install -g @anthropic-ai/claude-code${NC}`);
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(installClaudeCode, "installClaudeCode");
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
- claudeInstalled: false,
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 hasClaude = await hasClaudeCodeCLI();
661
- if (!hasClaude) {
662
- const installed = await installClaudeCode();
663
- if (installed) {
664
- results.claudeInstalled = true;
665
- } else {
666
- throw new Error("Claude Code installation failed");
667
- }
668
- }
669
- const claudeDetected = await command_installer_default.detectClaude();
670
- if (claudeDetected) {
671
- const syncResult = await command_installer_default.syncCommands();
672
- if (syncResult.success) {
673
- results.commandsAdded = syncResult.added;
674
- results.commandsUpdated = syncResult.updated;
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
- const configResult = await command_installer_default.installGlobalConfig();
677
- if (configResult.success) {
678
- results.configAction = configResult.action;
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
- await command_installer_default.installDocs();
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
- showResults(results);
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 = import_path4.default.join(import_os3.default.homedir(), ".prjct-cli", "projects");
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 = import_path4.default.join(projectsDir, projectId, "project.json");
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 = import_path4.default.join(import_os3.default.homedir(), ".claude");
745
- const settingsPath = import_path4.default.join(claudeDir, "settings.json");
746
- const claudeStatusLinePath = import_path4.default.join(claudeDir, "prjct-statusline.sh");
747
- const prjctStatusLineDir = import_path4.default.join(import_os3.default.homedir(), ".prjct-cli", "statusline");
748
- const prjctStatusLinePath = import_path4.default.join(prjctStatusLineDir, "statusline.sh");
749
- const prjctThemesDir = import_path4.default.join(prjctStatusLineDir, "themes");
750
- const prjctLibDir = import_path4.default.join(prjctStatusLineDir, "lib");
751
- const prjctComponentsDir = import_path4.default.join(prjctStatusLineDir, "components");
752
- const prjctConfigPath = import_path4.default.join(prjctStatusLineDir, "config.json");
753
- const assetsDir = import_path4.default.join(getPackageRoot(), "assets", "statusline");
754
- const sourceScript = import_path4.default.join(assetsDir, "statusline.sh");
755
- const sourceThemeDir = import_path4.default.join(assetsDir, "themes");
756
- const sourceLibDir = import_path4.default.join(assetsDir, "lib");
757
- const sourceComponentsDir = import_path4.default.join(assetsDir, "components");
758
- const sourceConfigPath = import_path4.default.join(assetsDir, "default-config.json");
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 = import_path4.default.join(sourceThemeDir, theme);
805
- const dest = import_path4.default.join(prjctThemesDir, theme);
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 = import_path4.default.join(sourceDir, file);
864
- const dest = import_path4.default.join(destDir, file);
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.claudeInstalled) {
901
- console.log(` ${GREEN}\u2713${NC} Claude Code CLI installed`);
1120
+ if (results.cliInstalled) {
1121
+ console.log(` ${GREEN}\u2713${NC} ${provider.displayName} CLI installed`);
902
1122
  } else {
903
- console.log(` ${GREEN}\u2713${NC} Claude Code CLI found`);
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.35.4",
4
- "description": "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
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
- "claude-desktop",
38
- "developer-momentum",
39
- "indie-hacker",
40
- "ship-fast",
37
+ "gemini-cli",
38
+ "ai-agents",
39
+ "context-layer",
40
+ "developer-tools",
41
41
  "ai-assistant",
42
42
  "productivity",
43
- "developer-tools",
44
- "no-bs",
45
- "focus"
43
+ "mcp",
44
+ "llm",
45
+ "coding-agents"
46
46
  ],
47
47
  "author": "prjct.app",
48
48
  "license": "MIT",