prjct-cli 1.5.0 → 1.5.1
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 +44 -1
- package/bin/prjct.ts +23 -14
- package/core/__tests__/agentic/command-executor.test.ts +19 -19
- package/core/__tests__/agentic/prompt-builder.test.ts +16 -16
- package/core/agentic/command-executor.ts +18 -17
- package/core/agentic/prompt-builder.ts +18 -17
- package/core/agentic/template-executor.ts +2 -2
- package/core/ai-tools/registry.ts +17 -14
- package/core/cli/start.ts +18 -17
- package/core/commands/analysis.ts +1 -1
- package/core/commands/setup.ts +8 -8
- package/core/commands/uninstall.ts +11 -11
- package/core/index.ts +12 -11
- package/core/infrastructure/agent-detector.ts +8 -8
- package/core/infrastructure/ai-provider.ts +49 -37
- package/core/infrastructure/command-installer.ts +18 -10
- package/core/infrastructure/path-manager.ts +4 -4
- package/core/infrastructure/setup.ts +124 -119
- package/core/infrastructure/update-checker.ts +14 -13
- package/core/integrations/linear/sync.ts +4 -4
- package/core/services/hooks-service.ts +78 -68
- package/core/services/sync-service.ts +3 -3
- package/core/utils/fs-helpers.ts +14 -0
- package/core/utils/project-credentials.ts +8 -7
- package/dist/bin/prjct.mjs +683 -625
- package/dist/core/infrastructure/command-installer.js +118 -87
- package/dist/core/infrastructure/setup.js +246 -210
- package/package.json +1 -1
|
@@ -31,6 +31,24 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
));
|
|
32
32
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
33
|
|
|
34
|
+
// core/utils/fs-helpers.ts
|
|
35
|
+
async function fileExists(filePath) {
|
|
36
|
+
try {
|
|
37
|
+
await import_promises.default.access(filePath);
|
|
38
|
+
return true;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
var import_promises;
|
|
44
|
+
var init_fs_helpers = __esm({
|
|
45
|
+
"core/utils/fs-helpers.ts"() {
|
|
46
|
+
"use strict";
|
|
47
|
+
import_promises = __toESM(require("node:fs/promises"));
|
|
48
|
+
__name(fileExists, "fileExists");
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
34
52
|
// core/infrastructure/ai-provider.ts
|
|
35
53
|
var ai_provider_exports = {};
|
|
36
54
|
__export(ai_provider_exports, {
|
|
@@ -58,50 +76,48 @@ __export(ai_provider_exports, {
|
|
|
58
76
|
needsWindsurfRouterRegeneration: () => needsWindsurfRouterRegeneration,
|
|
59
77
|
selectProvider: () => selectProvider
|
|
60
78
|
});
|
|
61
|
-
function whichCommand(command) {
|
|
79
|
+
async function whichCommand(command) {
|
|
62
80
|
try {
|
|
63
|
-
const
|
|
64
|
-
return
|
|
81
|
+
const { stdout } = await execAsync(`which ${command}`);
|
|
82
|
+
return stdout.trim();
|
|
65
83
|
} catch {
|
|
66
84
|
return null;
|
|
67
85
|
}
|
|
68
86
|
}
|
|
69
|
-
function getCliVersion(command) {
|
|
87
|
+
async function getCliVersion(command) {
|
|
70
88
|
try {
|
|
71
|
-
const
|
|
72
|
-
const match =
|
|
73
|
-
return match ? match[0] :
|
|
89
|
+
const { stdout } = await execAsync(`${command} --version`);
|
|
90
|
+
const match = stdout.match(/\d+\.\d+\.\d+/);
|
|
91
|
+
return match ? match[0] : stdout.trim();
|
|
74
92
|
} catch {
|
|
75
93
|
return null;
|
|
76
94
|
}
|
|
77
95
|
}
|
|
78
|
-
function detectProvider(provider) {
|
|
96
|
+
async function detectProvider(provider) {
|
|
79
97
|
const config = Providers[provider];
|
|
80
98
|
if (!config.cliCommand) {
|
|
81
99
|
return { installed: false };
|
|
82
100
|
}
|
|
83
|
-
const cliPath = whichCommand(config.cliCommand);
|
|
101
|
+
const cliPath = await whichCommand(config.cliCommand);
|
|
84
102
|
if (!cliPath) {
|
|
85
103
|
return { installed: false };
|
|
86
104
|
}
|
|
87
|
-
const version = getCliVersion(config.cliCommand);
|
|
105
|
+
const version = await getCliVersion(config.cliCommand);
|
|
88
106
|
return {
|
|
89
107
|
installed: true,
|
|
90
108
|
version: version || void 0,
|
|
91
109
|
path: cliPath
|
|
92
110
|
};
|
|
93
111
|
}
|
|
94
|
-
function detectAllProviders() {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
gemini: detectProvider("gemini")
|
|
98
|
-
};
|
|
112
|
+
async function detectAllProviders() {
|
|
113
|
+
const [claude, gemini] = await Promise.all([detectProvider("claude"), detectProvider("gemini")]);
|
|
114
|
+
return { claude, gemini };
|
|
99
115
|
}
|
|
100
|
-
function getActiveProvider(projectProvider) {
|
|
116
|
+
async function getActiveProvider(projectProvider) {
|
|
101
117
|
if (projectProvider && Providers[projectProvider]) {
|
|
102
118
|
return Providers[projectProvider];
|
|
103
119
|
}
|
|
104
|
-
const detection = detectAllProviders();
|
|
120
|
+
const detection = await detectAllProviders();
|
|
105
121
|
if (detection.claude.installed && !detection.gemini.installed) {
|
|
106
122
|
return ClaudeProvider;
|
|
107
123
|
}
|
|
@@ -110,12 +126,12 @@ function getActiveProvider(projectProvider) {
|
|
|
110
126
|
}
|
|
111
127
|
return ClaudeProvider;
|
|
112
128
|
}
|
|
113
|
-
function hasProviderConfig(provider) {
|
|
129
|
+
async function hasProviderConfig(provider) {
|
|
114
130
|
const config = Providers[provider];
|
|
115
131
|
if (!config.configDir) {
|
|
116
132
|
return false;
|
|
117
133
|
}
|
|
118
|
-
return
|
|
134
|
+
return fileExists(config.configDir);
|
|
119
135
|
}
|
|
120
136
|
function getProviderBranding(provider) {
|
|
121
137
|
const commitFooter = `Generated with [p/](https://www.prjct.app/)`;
|
|
@@ -131,46 +147,52 @@ function getProviderBranding(provider) {
|
|
|
131
147
|
signature: signatures[provider] || "\u26A1 prjct"
|
|
132
148
|
};
|
|
133
149
|
}
|
|
134
|
-
function detectCursorProject(projectRoot) {
|
|
150
|
+
async function detectCursorProject(projectRoot) {
|
|
135
151
|
const cursorDir = import_node_path2.default.join(projectRoot, ".cursor");
|
|
136
152
|
const rulesDir = import_node_path2.default.join(cursorDir, "rules");
|
|
137
153
|
const routerPath = import_node_path2.default.join(rulesDir, "prjct.mdc");
|
|
138
|
-
const detected =
|
|
139
|
-
|
|
154
|
+
const [detected, routerInstalled] = await Promise.all([
|
|
155
|
+
fileExists(cursorDir),
|
|
156
|
+
fileExists(routerPath)
|
|
157
|
+
]);
|
|
140
158
|
return {
|
|
141
159
|
detected,
|
|
142
160
|
routerInstalled,
|
|
143
161
|
projectRoot: detected ? projectRoot : void 0
|
|
144
162
|
};
|
|
145
163
|
}
|
|
146
|
-
function needsCursorRouterRegeneration(projectRoot) {
|
|
147
|
-
const detection = detectCursorProject(projectRoot);
|
|
164
|
+
async function needsCursorRouterRegeneration(projectRoot) {
|
|
165
|
+
const detection = await detectCursorProject(projectRoot);
|
|
148
166
|
return detection.detected && !detection.routerInstalled;
|
|
149
167
|
}
|
|
150
|
-
function detectWindsurfProject(projectRoot) {
|
|
168
|
+
async function detectWindsurfProject(projectRoot) {
|
|
151
169
|
const windsurfDir = import_node_path2.default.join(projectRoot, ".windsurf");
|
|
152
170
|
const rulesDir = import_node_path2.default.join(windsurfDir, "rules");
|
|
153
171
|
const routerPath = import_node_path2.default.join(rulesDir, "prjct.md");
|
|
154
|
-
const detected =
|
|
155
|
-
|
|
172
|
+
const [detected, routerInstalled] = await Promise.all([
|
|
173
|
+
fileExists(windsurfDir),
|
|
174
|
+
fileExists(routerPath)
|
|
175
|
+
]);
|
|
156
176
|
return {
|
|
157
177
|
detected,
|
|
158
178
|
routerInstalled,
|
|
159
179
|
projectRoot: detected ? projectRoot : void 0
|
|
160
180
|
};
|
|
161
181
|
}
|
|
162
|
-
function needsWindsurfRouterRegeneration(projectRoot) {
|
|
163
|
-
const detection = detectWindsurfProject(projectRoot);
|
|
182
|
+
async function needsWindsurfRouterRegeneration(projectRoot) {
|
|
183
|
+
const detection = await detectWindsurfProject(projectRoot);
|
|
164
184
|
return detection.detected && !detection.routerInstalled;
|
|
165
185
|
}
|
|
166
|
-
function detectAntigravity() {
|
|
186
|
+
async function detectAntigravity() {
|
|
167
187
|
const configPath = AntigravityProvider.configDir;
|
|
168
188
|
if (!configPath) {
|
|
169
189
|
return { installed: false, skillInstalled: false };
|
|
170
190
|
}
|
|
171
|
-
const installed = import_node_fs2.default.existsSync(configPath);
|
|
172
191
|
const skillPath = import_node_path2.default.join(configPath, "skills", "prjct", "SKILL.md");
|
|
173
|
-
const skillInstalled =
|
|
192
|
+
const [installed, skillInstalled] = await Promise.all([
|
|
193
|
+
fileExists(configPath),
|
|
194
|
+
fileExists(skillPath)
|
|
195
|
+
]);
|
|
174
196
|
return {
|
|
175
197
|
installed,
|
|
176
198
|
skillInstalled,
|
|
@@ -201,8 +223,8 @@ function getProjectCommandsPath(provider, projectRoot) {
|
|
|
201
223
|
const config = Providers[provider];
|
|
202
224
|
return import_node_path2.default.join(projectRoot, config.commandsDir);
|
|
203
225
|
}
|
|
204
|
-
function selectProvider() {
|
|
205
|
-
const detection = detectAllProviders();
|
|
226
|
+
async function selectProvider() {
|
|
227
|
+
const detection = await detectAllProviders();
|
|
206
228
|
const claudeInstalled = detection.claude.installed;
|
|
207
229
|
const geminiInstalled = detection.gemini.installed;
|
|
208
230
|
if (!claudeInstalled && !geminiInstalled) {
|
|
@@ -233,14 +255,16 @@ function selectProvider() {
|
|
|
233
255
|
detection
|
|
234
256
|
};
|
|
235
257
|
}
|
|
236
|
-
var import_node_child_process2,
|
|
258
|
+
var import_node_child_process2, import_node_os, import_node_path2, import_node_util, execAsync, ClaudeProvider, GeminiProvider, AntigravityProvider, CursorProvider, WindsurfProvider, Providers, ai_provider_default;
|
|
237
259
|
var init_ai_provider = __esm({
|
|
238
260
|
"core/infrastructure/ai-provider.ts"() {
|
|
239
261
|
"use strict";
|
|
240
262
|
import_node_child_process2 = require("node:child_process");
|
|
241
|
-
import_node_fs2 = __toESM(require("node:fs"));
|
|
242
263
|
import_node_os = __toESM(require("node:os"));
|
|
243
264
|
import_node_path2 = __toESM(require("node:path"));
|
|
265
|
+
import_node_util = require("node:util");
|
|
266
|
+
init_fs_helpers();
|
|
267
|
+
execAsync = (0, import_node_util.promisify)(import_node_child_process2.exec);
|
|
244
268
|
ClaudeProvider = {
|
|
245
269
|
name: "claude",
|
|
246
270
|
displayName: "Claude Code",
|
|
@@ -405,7 +429,7 @@ __export(setup_exports, {
|
|
|
405
429
|
});
|
|
406
430
|
module.exports = __toCommonJS(setup_exports);
|
|
407
431
|
var import_node_child_process3 = require("node:child_process");
|
|
408
|
-
var
|
|
432
|
+
var import_promises4 = __toESM(require("node:fs/promises"));
|
|
409
433
|
var import_node_os4 = __toESM(require("node:os"));
|
|
410
434
|
var import_node_path5 = __toESM(require("node:path"));
|
|
411
435
|
var import_chalk = __toESM(require("chalk"));
|
|
@@ -692,6 +716,9 @@ function isNotFoundError(error) {
|
|
|
692
716
|
}
|
|
693
717
|
__name(isNotFoundError, "isNotFoundError");
|
|
694
718
|
|
|
719
|
+
// core/infrastructure/setup.ts
|
|
720
|
+
init_fs_helpers();
|
|
721
|
+
|
|
695
722
|
// core/utils/version.ts
|
|
696
723
|
var import_node_fs = __toESM(require("node:fs"));
|
|
697
724
|
var import_node_path = __toESM(require("node:path"));
|
|
@@ -744,13 +771,13 @@ var PACKAGE_ROOT = getPackageRoot();
|
|
|
744
771
|
init_ai_provider();
|
|
745
772
|
|
|
746
773
|
// core/infrastructure/command-installer.ts
|
|
747
|
-
var
|
|
774
|
+
var import_promises2 = __toESM(require("node:fs/promises"));
|
|
748
775
|
var import_node_os2 = __toESM(require("node:os"));
|
|
749
776
|
var import_node_path3 = __toESM(require("node:path"));
|
|
750
777
|
async function loadModuleConfig() {
|
|
751
778
|
try {
|
|
752
779
|
const configPath = import_node_path3.default.join(getPackageRoot(), "templates/global/modules/module-config.json");
|
|
753
|
-
const content = await
|
|
780
|
+
const content = await import_promises2.default.readFile(configPath, "utf-8");
|
|
754
781
|
return JSON.parse(content);
|
|
755
782
|
} catch {
|
|
756
783
|
return null;
|
|
@@ -762,7 +789,7 @@ async function composeGlobalTemplate(profile) {
|
|
|
762
789
|
const modulesDir = import_node_path3.default.join(getPackageRoot(), "templates/global/modules");
|
|
763
790
|
if (!config) {
|
|
764
791
|
const legacyPath = import_node_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
765
|
-
return
|
|
792
|
+
return import_promises2.default.readFile(legacyPath, "utf-8");
|
|
766
793
|
}
|
|
767
794
|
const profileName = profile || config.default;
|
|
768
795
|
const selectedProfile = config.profiles[profileName];
|
|
@@ -770,7 +797,7 @@ async function composeGlobalTemplate(profile) {
|
|
|
770
797
|
const defaultProfile = config.profiles[config.default];
|
|
771
798
|
if (!defaultProfile) {
|
|
772
799
|
const legacyPath = import_node_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
773
|
-
return
|
|
800
|
+
return import_promises2.default.readFile(legacyPath, "utf-8");
|
|
774
801
|
}
|
|
775
802
|
}
|
|
776
803
|
const modules = (selectedProfile || config.profiles[config.default]).modules;
|
|
@@ -779,7 +806,7 @@ async function composeGlobalTemplate(profile) {
|
|
|
779
806
|
for (const moduleName of modules) {
|
|
780
807
|
try {
|
|
781
808
|
const modulePath = import_node_path3.default.join(modulesDir, moduleName);
|
|
782
|
-
const content = await
|
|
809
|
+
const content = await import_promises2.default.readFile(modulePath, "utf-8");
|
|
783
810
|
parts.push("");
|
|
784
811
|
parts.push(content);
|
|
785
812
|
} catch {
|
|
@@ -796,14 +823,14 @@ async function installDocs() {
|
|
|
796
823
|
try {
|
|
797
824
|
const docsDir = import_node_path3.default.join(import_node_os2.default.homedir(), ".prjct-cli", "docs");
|
|
798
825
|
const templateDocsDir = import_node_path3.default.join(getPackageRoot(), "templates/global/docs");
|
|
799
|
-
await
|
|
800
|
-
const docFiles = await
|
|
826
|
+
await import_promises2.default.mkdir(docsDir, { recursive: true });
|
|
827
|
+
const docFiles = await import_promises2.default.readdir(templateDocsDir);
|
|
801
828
|
for (const file of docFiles) {
|
|
802
829
|
if (file.endsWith(".md")) {
|
|
803
830
|
const srcPath = import_node_path3.default.join(templateDocsDir, file);
|
|
804
831
|
const destPath = import_node_path3.default.join(docsDir, file);
|
|
805
|
-
const content = await
|
|
806
|
-
await
|
|
832
|
+
const content = await import_promises2.default.readFile(srcPath, "utf-8");
|
|
833
|
+
await import_promises2.default.writeFile(destPath, content, "utf-8");
|
|
807
834
|
}
|
|
808
835
|
}
|
|
809
836
|
return { success: true };
|
|
@@ -814,9 +841,9 @@ async function installDocs() {
|
|
|
814
841
|
__name(installDocs, "installDocs");
|
|
815
842
|
async function installGlobalConfig() {
|
|
816
843
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
817
|
-
const activeProvider = aiProvider.getActiveProvider();
|
|
844
|
+
const activeProvider = await aiProvider.getActiveProvider();
|
|
818
845
|
const providerName = activeProvider.name;
|
|
819
|
-
const detection = aiProvider.detectProvider(providerName);
|
|
846
|
+
const detection = await aiProvider.detectProvider(providerName);
|
|
820
847
|
if (!detection.installed && !activeProvider.configDir) {
|
|
821
848
|
return {
|
|
822
849
|
success: false,
|
|
@@ -825,7 +852,7 @@ async function installGlobalConfig() {
|
|
|
825
852
|
};
|
|
826
853
|
}
|
|
827
854
|
try {
|
|
828
|
-
await
|
|
855
|
+
await import_promises2.default.mkdir(activeProvider.configDir, { recursive: true });
|
|
829
856
|
const globalConfigPath = import_node_path3.default.join(activeProvider.configDir, activeProvider.contextFile);
|
|
830
857
|
const templatePath = import_node_path3.default.join(
|
|
831
858
|
getPackageRoot(),
|
|
@@ -835,37 +862,37 @@ async function installGlobalConfig() {
|
|
|
835
862
|
);
|
|
836
863
|
let templateContent = "";
|
|
837
864
|
try {
|
|
838
|
-
templateContent = await
|
|
865
|
+
templateContent = await import_promises2.default.readFile(templatePath, "utf-8");
|
|
839
866
|
} catch (_error) {
|
|
840
867
|
if (providerName === "claude") {
|
|
841
868
|
try {
|
|
842
869
|
templateContent = await composeGlobalTemplate("standard");
|
|
843
870
|
} catch {
|
|
844
871
|
const fallbackTemplatePath = import_node_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
845
|
-
templateContent = await
|
|
872
|
+
templateContent = await import_promises2.default.readFile(fallbackTemplatePath, "utf-8");
|
|
846
873
|
}
|
|
847
874
|
} else {
|
|
848
875
|
const fallbackTemplatePath = import_node_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
849
|
-
templateContent = await
|
|
876
|
+
templateContent = await import_promises2.default.readFile(fallbackTemplatePath, "utf-8");
|
|
850
877
|
if (providerName === "gemini") {
|
|
851
878
|
templateContent = templateContent.replace(/Claude/g, "Gemini");
|
|
852
879
|
}
|
|
853
880
|
}
|
|
854
881
|
}
|
|
855
882
|
let existingContent = "";
|
|
856
|
-
let
|
|
883
|
+
let fileExists2 = false;
|
|
857
884
|
try {
|
|
858
|
-
existingContent = await
|
|
859
|
-
|
|
885
|
+
existingContent = await import_promises2.default.readFile(globalConfigPath, "utf-8");
|
|
886
|
+
fileExists2 = true;
|
|
860
887
|
} catch (error) {
|
|
861
888
|
if (isNotFoundError(error)) {
|
|
862
|
-
|
|
889
|
+
fileExists2 = false;
|
|
863
890
|
} else {
|
|
864
891
|
throw error;
|
|
865
892
|
}
|
|
866
893
|
}
|
|
867
|
-
if (!
|
|
868
|
-
await
|
|
894
|
+
if (!fileExists2) {
|
|
895
|
+
await import_promises2.default.writeFile(globalConfigPath, templateContent, "utf-8");
|
|
869
896
|
return {
|
|
870
897
|
success: true,
|
|
871
898
|
action: "created",
|
|
@@ -879,7 +906,7 @@ async function installGlobalConfig() {
|
|
|
879
906
|
const updatedContent = `${existingContent}
|
|
880
907
|
|
|
881
908
|
${templateContent}`;
|
|
882
|
-
await
|
|
909
|
+
await import_promises2.default.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
883
910
|
return {
|
|
884
911
|
success: true,
|
|
885
912
|
action: "appended",
|
|
@@ -895,7 +922,7 @@ ${templateContent}`;
|
|
|
895
922
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
896
923
|
);
|
|
897
924
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
898
|
-
await
|
|
925
|
+
await import_promises2.default.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
899
926
|
return {
|
|
900
927
|
success: true,
|
|
901
928
|
action: "updated",
|
|
@@ -917,27 +944,33 @@ var CommandInstaller = class {
|
|
|
917
944
|
__name(this, "CommandInstaller");
|
|
918
945
|
}
|
|
919
946
|
homeDir;
|
|
920
|
-
claudeCommandsPath;
|
|
921
|
-
claudeConfigPath;
|
|
947
|
+
claudeCommandsPath = "";
|
|
948
|
+
claudeConfigPath = "";
|
|
922
949
|
templatesDir;
|
|
950
|
+
_initialized = false;
|
|
923
951
|
constructor() {
|
|
924
952
|
this.homeDir = import_node_os2.default.homedir();
|
|
953
|
+
this.templatesDir = import_node_path3.default.join(getPackageRoot(), "templates", "commands");
|
|
954
|
+
}
|
|
955
|
+
async ensureInit() {
|
|
956
|
+
if (this._initialized) return;
|
|
925
957
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
926
|
-
const activeProvider = aiProvider.getActiveProvider();
|
|
958
|
+
const activeProvider = await aiProvider.getActiveProvider();
|
|
927
959
|
if (activeProvider.name === "gemini") {
|
|
928
960
|
this.claudeCommandsPath = import_node_path3.default.join(activeProvider.configDir, "commands");
|
|
929
961
|
} else {
|
|
930
962
|
this.claudeCommandsPath = import_node_path3.default.join(activeProvider.configDir, "commands", "p");
|
|
931
963
|
}
|
|
932
964
|
this.claudeConfigPath = activeProvider.configDir;
|
|
933
|
-
this.
|
|
965
|
+
this._initialized = true;
|
|
934
966
|
}
|
|
935
967
|
/**
|
|
936
968
|
* Detect if active provider is installed
|
|
937
969
|
*/
|
|
938
970
|
async detectActiveProvider() {
|
|
971
|
+
await this.ensureInit();
|
|
939
972
|
try {
|
|
940
|
-
await
|
|
973
|
+
await import_promises2.default.access(this.claudeConfigPath);
|
|
941
974
|
return true;
|
|
942
975
|
} catch (error) {
|
|
943
976
|
if (isNotFoundError(error)) {
|
|
@@ -957,7 +990,7 @@ var CommandInstaller = class {
|
|
|
957
990
|
*/
|
|
958
991
|
async getCommandFiles() {
|
|
959
992
|
try {
|
|
960
|
-
const files = await
|
|
993
|
+
const files = await import_promises2.default.readdir(this.templatesDir);
|
|
961
994
|
return files.filter((f) => f.endsWith(".md"));
|
|
962
995
|
} catch (_error) {
|
|
963
996
|
return [
|
|
@@ -989,7 +1022,7 @@ var CommandInstaller = class {
|
|
|
989
1022
|
async installCommands() {
|
|
990
1023
|
const providerDetected = await this.detectActiveProvider();
|
|
991
1024
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
992
|
-
const activeProvider = aiProvider.getActiveProvider();
|
|
1025
|
+
const activeProvider = await aiProvider.getActiveProvider();
|
|
993
1026
|
if (!providerDetected) {
|
|
994
1027
|
return {
|
|
995
1028
|
success: false,
|
|
@@ -998,7 +1031,7 @@ var CommandInstaller = class {
|
|
|
998
1031
|
}
|
|
999
1032
|
try {
|
|
1000
1033
|
await this.installRouter();
|
|
1001
|
-
await
|
|
1034
|
+
await import_promises2.default.mkdir(this.claudeCommandsPath, { recursive: true });
|
|
1002
1035
|
const commandFiles = await this.getCommandFiles();
|
|
1003
1036
|
const installed = [];
|
|
1004
1037
|
const errors = [];
|
|
@@ -1006,8 +1039,8 @@ var CommandInstaller = class {
|
|
|
1006
1039
|
try {
|
|
1007
1040
|
const sourcePath = import_node_path3.default.join(this.templatesDir, file);
|
|
1008
1041
|
const destPath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
1009
|
-
const content = await
|
|
1010
|
-
await
|
|
1042
|
+
const content = await import_promises2.default.readFile(sourcePath, "utf-8");
|
|
1043
|
+
await import_promises2.default.writeFile(destPath, content, "utf-8");
|
|
1011
1044
|
installed.push(file.replace(".md", ""));
|
|
1012
1045
|
} catch (error) {
|
|
1013
1046
|
errors.push({ file, error: error.message });
|
|
@@ -1037,7 +1070,7 @@ var CommandInstaller = class {
|
|
|
1037
1070
|
for (const file of commandFiles) {
|
|
1038
1071
|
try {
|
|
1039
1072
|
const filePath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
1040
|
-
await
|
|
1073
|
+
await import_promises2.default.unlink(filePath);
|
|
1041
1074
|
uninstalled.push(file.replace(".md", ""));
|
|
1042
1075
|
} catch (error) {
|
|
1043
1076
|
if (error.code !== "ENOENT") {
|
|
@@ -1046,7 +1079,7 @@ var CommandInstaller = class {
|
|
|
1046
1079
|
}
|
|
1047
1080
|
}
|
|
1048
1081
|
try {
|
|
1049
|
-
await
|
|
1082
|
+
await import_promises2.default.rmdir(this.claudeCommandsPath);
|
|
1050
1083
|
} catch (_error) {
|
|
1051
1084
|
}
|
|
1052
1085
|
return {
|
|
@@ -1073,8 +1106,8 @@ var CommandInstaller = class {
|
|
|
1073
1106
|
};
|
|
1074
1107
|
}
|
|
1075
1108
|
try {
|
|
1076
|
-
await
|
|
1077
|
-
const files = await
|
|
1109
|
+
await import_promises2.default.access(this.claudeCommandsPath);
|
|
1110
|
+
const files = await import_promises2.default.readdir(this.claudeCommandsPath);
|
|
1078
1111
|
const installedCommands = files.filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
1079
1112
|
return {
|
|
1080
1113
|
installed: installedCommands.length > 0,
|
|
@@ -1113,7 +1146,8 @@ var CommandInstaller = class {
|
|
|
1113
1146
|
/**
|
|
1114
1147
|
* Get installation path for Claude commands
|
|
1115
1148
|
*/
|
|
1116
|
-
getInstallPath() {
|
|
1149
|
+
async getInstallPath() {
|
|
1150
|
+
await this.ensureInit();
|
|
1117
1151
|
return this.claudeCommandsPath;
|
|
1118
1152
|
}
|
|
1119
1153
|
/**
|
|
@@ -1122,7 +1156,7 @@ var CommandInstaller = class {
|
|
|
1122
1156
|
async verifyTemplate(commandName) {
|
|
1123
1157
|
try {
|
|
1124
1158
|
const templatePath = import_node_path3.default.join(this.templatesDir, `${commandName}.md`);
|
|
1125
|
-
await
|
|
1159
|
+
await import_promises2.default.access(templatePath);
|
|
1126
1160
|
return true;
|
|
1127
1161
|
} catch (error) {
|
|
1128
1162
|
if (isNotFoundError(error)) {
|
|
@@ -1137,14 +1171,14 @@ var CommandInstaller = class {
|
|
|
1137
1171
|
*/
|
|
1138
1172
|
async installRouter() {
|
|
1139
1173
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
1140
|
-
const activeProvider = aiProvider.getActiveProvider();
|
|
1174
|
+
const activeProvider = await aiProvider.getActiveProvider();
|
|
1141
1175
|
const routerFile = activeProvider.name === "gemini" ? "p.toml" : "p.md";
|
|
1142
1176
|
try {
|
|
1143
1177
|
const routerSource = import_node_path3.default.join(this.templatesDir, routerFile);
|
|
1144
1178
|
const routerDest = import_node_path3.default.join(activeProvider.configDir, "commands", routerFile);
|
|
1145
|
-
await
|
|
1146
|
-
const content = await
|
|
1147
|
-
await
|
|
1179
|
+
await import_promises2.default.mkdir(import_node_path3.default.dirname(routerDest), { recursive: true });
|
|
1180
|
+
const content = await import_promises2.default.readFile(routerSource, "utf-8");
|
|
1181
|
+
await import_promises2.default.writeFile(routerDest, content, "utf-8");
|
|
1148
1182
|
return true;
|
|
1149
1183
|
} catch (error) {
|
|
1150
1184
|
if (isNotFoundError(error)) {
|
|
@@ -1159,15 +1193,15 @@ var CommandInstaller = class {
|
|
|
1159
1193
|
*/
|
|
1160
1194
|
async removeLegacyCommands() {
|
|
1161
1195
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
1162
|
-
const activeProvider = aiProvider.getActiveProvider();
|
|
1196
|
+
const activeProvider = await aiProvider.getActiveProvider();
|
|
1163
1197
|
const commandsRoot = import_node_path3.default.join(activeProvider.configDir, "commands");
|
|
1164
1198
|
let removed = 0;
|
|
1165
1199
|
try {
|
|
1166
|
-
const files = await
|
|
1200
|
+
const files = await import_promises2.default.readdir(commandsRoot);
|
|
1167
1201
|
const legacyFiles = files.filter((f) => f.startsWith("p.") && f.endsWith(".md"));
|
|
1168
1202
|
for (const file of legacyFiles) {
|
|
1169
1203
|
try {
|
|
1170
|
-
await
|
|
1204
|
+
await import_promises2.default.unlink(import_node_path3.default.join(commandsRoot, file));
|
|
1171
1205
|
removed++;
|
|
1172
1206
|
} catch {
|
|
1173
1207
|
}
|
|
@@ -1192,11 +1226,11 @@ var CommandInstaller = class {
|
|
|
1192
1226
|
}
|
|
1193
1227
|
try {
|
|
1194
1228
|
await this.installRouter();
|
|
1195
|
-
await
|
|
1229
|
+
await import_promises2.default.mkdir(this.claudeCommandsPath, { recursive: true });
|
|
1196
1230
|
const templateFiles = await this.getCommandFiles();
|
|
1197
1231
|
let installedFiles = [];
|
|
1198
1232
|
try {
|
|
1199
|
-
installedFiles = await
|
|
1233
|
+
installedFiles = await import_promises2.default.readdir(this.claudeCommandsPath);
|
|
1200
1234
|
installedFiles = installedFiles.filter((f) => f.endsWith(".md"));
|
|
1201
1235
|
} catch (error) {
|
|
1202
1236
|
if (isNotFoundError(error)) {
|
|
@@ -1217,8 +1251,8 @@ var CommandInstaller = class {
|
|
|
1217
1251
|
const sourcePath = import_node_path3.default.join(this.templatesDir, file);
|
|
1218
1252
|
const destPath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
1219
1253
|
const exists = installedFiles.includes(file);
|
|
1220
|
-
const content = await
|
|
1221
|
-
await
|
|
1254
|
+
const content = await import_promises2.default.readFile(sourcePath, "utf-8");
|
|
1255
|
+
await import_promises2.default.writeFile(destPath, content, "utf-8");
|
|
1222
1256
|
if (!exists) {
|
|
1223
1257
|
results.added++;
|
|
1224
1258
|
} else {
|
|
@@ -1257,7 +1291,7 @@ var commandInstaller = new CommandInstaller();
|
|
|
1257
1291
|
var command_installer_default = commandInstaller;
|
|
1258
1292
|
|
|
1259
1293
|
// core/infrastructure/editors-config.ts
|
|
1260
|
-
var
|
|
1294
|
+
var import_promises3 = __toESM(require("node:fs/promises"));
|
|
1261
1295
|
var import_node_os3 = __toESM(require("node:os"));
|
|
1262
1296
|
var import_node_path4 = __toESM(require("node:path"));
|
|
1263
1297
|
var EditorsConfig = class {
|
|
@@ -1277,7 +1311,7 @@ var EditorsConfig = class {
|
|
|
1277
1311
|
*/
|
|
1278
1312
|
async ensureConfigDir() {
|
|
1279
1313
|
try {
|
|
1280
|
-
await
|
|
1314
|
+
await import_promises3.default.mkdir(this.configDir, { recursive: true });
|
|
1281
1315
|
} catch (error) {
|
|
1282
1316
|
console.error("[editors-config] Error creating config directory:", error.message);
|
|
1283
1317
|
}
|
|
@@ -1287,7 +1321,7 @@ var EditorsConfig = class {
|
|
|
1287
1321
|
*/
|
|
1288
1322
|
async loadConfig() {
|
|
1289
1323
|
try {
|
|
1290
|
-
const content = await
|
|
1324
|
+
const content = await import_promises3.default.readFile(this.configFile, "utf-8");
|
|
1291
1325
|
return JSON.parse(content);
|
|
1292
1326
|
} catch (error) {
|
|
1293
1327
|
if (error.code === "ENOENT") {
|
|
@@ -1311,7 +1345,7 @@ var EditorsConfig = class {
|
|
|
1311
1345
|
lastInstall: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1312
1346
|
path: installPath
|
|
1313
1347
|
};
|
|
1314
|
-
await
|
|
1348
|
+
await import_promises3.default.writeFile(this.configFile, JSON.stringify(config, null, 2), "utf-8");
|
|
1315
1349
|
return true;
|
|
1316
1350
|
} catch (error) {
|
|
1317
1351
|
console.error("[editors-config] Error saving config:", error.message);
|
|
@@ -1351,7 +1385,7 @@ var EditorsConfig = class {
|
|
|
1351
1385
|
}
|
|
1352
1386
|
config.version = version;
|
|
1353
1387
|
config.lastInstall = (/* @__PURE__ */ new Date()).toISOString();
|
|
1354
|
-
await
|
|
1388
|
+
await import_promises3.default.writeFile(this.configFile, JSON.stringify(config, null, 2), "utf-8");
|
|
1355
1389
|
return true;
|
|
1356
1390
|
} catch (error) {
|
|
1357
1391
|
console.error("[editors-config] Error updating version:", error.message);
|
|
@@ -1363,7 +1397,7 @@ var EditorsConfig = class {
|
|
|
1363
1397
|
*/
|
|
1364
1398
|
async configExists() {
|
|
1365
1399
|
try {
|
|
1366
|
-
await
|
|
1400
|
+
await import_promises3.default.access(this.configFile);
|
|
1367
1401
|
return true;
|
|
1368
1402
|
} catch (_error) {
|
|
1369
1403
|
return false;
|
|
@@ -1377,7 +1411,7 @@ var EditorsConfig = class {
|
|
|
1377
1411
|
try {
|
|
1378
1412
|
const exists = await this.configExists();
|
|
1379
1413
|
if (exists) {
|
|
1380
|
-
await
|
|
1414
|
+
await import_promises3.default.unlink(this.configFile);
|
|
1381
1415
|
}
|
|
1382
1416
|
return true;
|
|
1383
1417
|
} catch (error) {
|
|
@@ -1443,8 +1477,8 @@ async function installAICLI(provider) {
|
|
|
1443
1477
|
}
|
|
1444
1478
|
__name(installAICLI, "installAICLI");
|
|
1445
1479
|
async function run() {
|
|
1446
|
-
const detection = detectAllProviders();
|
|
1447
|
-
const selection = selectProvider();
|
|
1480
|
+
const detection = await detectAllProviders();
|
|
1481
|
+
const selection = await selectProvider();
|
|
1448
1482
|
const _primaryProvider = Providers[selection.provider];
|
|
1449
1483
|
const results = {
|
|
1450
1484
|
provider: selection.provider,
|
|
@@ -1512,14 +1546,14 @@ async function run() {
|
|
|
1512
1546
|
}
|
|
1513
1547
|
results.providers.push(providerResult);
|
|
1514
1548
|
}
|
|
1515
|
-
const antigravityDetection = detectAntigravity();
|
|
1549
|
+
const antigravityDetection = await detectAntigravity();
|
|
1516
1550
|
if (antigravityDetection.installed) {
|
|
1517
1551
|
const antigravityResult = await installAntigravitySkill();
|
|
1518
1552
|
if (antigravityResult.success) {
|
|
1519
1553
|
console.log(` ${import_chalk.default.green("\u2713")} Antigravity skill installed`);
|
|
1520
1554
|
}
|
|
1521
1555
|
}
|
|
1522
|
-
await editors_config_default.saveConfig(VERSION, command_installer_default.getInstallPath(), selection.provider);
|
|
1556
|
+
await editors_config_default.saveConfig(VERSION, await command_installer_default.getInstallPath(), selection.provider);
|
|
1523
1557
|
await migrateProjectsCliVersion();
|
|
1524
1558
|
for (const providerResult of results.providers) {
|
|
1525
1559
|
showResults(providerResult, Providers[providerResult.provider]);
|
|
@@ -1533,9 +1567,9 @@ async function installGeminiRouter() {
|
|
|
1533
1567
|
const geminiCommandsDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".gemini", "commands");
|
|
1534
1568
|
const routerSource = import_node_path5.default.join(getPackageRoot(), "templates", "commands", "p.toml");
|
|
1535
1569
|
const routerDest = import_node_path5.default.join(geminiCommandsDir, "p.toml");
|
|
1536
|
-
|
|
1537
|
-
if (
|
|
1538
|
-
|
|
1570
|
+
await import_promises4.default.mkdir(geminiCommandsDir, { recursive: true });
|
|
1571
|
+
if (await fileExists(routerSource)) {
|
|
1572
|
+
await import_promises4.default.copyFile(routerSource, routerDest);
|
|
1539
1573
|
return true;
|
|
1540
1574
|
}
|
|
1541
1575
|
return false;
|
|
@@ -1550,22 +1584,22 @@ async function installGeminiGlobalConfig() {
|
|
|
1550
1584
|
const geminiDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".gemini");
|
|
1551
1585
|
const globalConfigPath = import_node_path5.default.join(geminiDir, "GEMINI.md");
|
|
1552
1586
|
const templatePath = import_node_path5.default.join(getPackageRoot(), "templates", "global", "GEMINI.md");
|
|
1553
|
-
|
|
1554
|
-
const templateContent =
|
|
1587
|
+
await import_promises4.default.mkdir(geminiDir, { recursive: true });
|
|
1588
|
+
const templateContent = await import_promises4.default.readFile(templatePath, "utf-8");
|
|
1555
1589
|
let existingContent = "";
|
|
1556
|
-
let
|
|
1590
|
+
let configExists = false;
|
|
1557
1591
|
try {
|
|
1558
|
-
existingContent =
|
|
1559
|
-
|
|
1592
|
+
existingContent = await import_promises4.default.readFile(globalConfigPath, "utf-8");
|
|
1593
|
+
configExists = true;
|
|
1560
1594
|
} catch (error) {
|
|
1561
1595
|
if (isNotFoundError(error)) {
|
|
1562
|
-
|
|
1596
|
+
configExists = false;
|
|
1563
1597
|
} else {
|
|
1564
1598
|
throw error;
|
|
1565
1599
|
}
|
|
1566
1600
|
}
|
|
1567
|
-
if (!
|
|
1568
|
-
|
|
1601
|
+
if (!configExists) {
|
|
1602
|
+
await import_promises4.default.writeFile(globalConfigPath, templateContent, "utf-8");
|
|
1569
1603
|
return { success: true, action: "created" };
|
|
1570
1604
|
}
|
|
1571
1605
|
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
@@ -1575,7 +1609,7 @@ async function installGeminiGlobalConfig() {
|
|
|
1575
1609
|
const updatedContent2 = `${existingContent}
|
|
1576
1610
|
|
|
1577
1611
|
${templateContent}`;
|
|
1578
|
-
|
|
1612
|
+
await import_promises4.default.writeFile(globalConfigPath, updatedContent2, "utf-8");
|
|
1579
1613
|
return { success: true, action: "appended" };
|
|
1580
1614
|
}
|
|
1581
1615
|
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
|
|
@@ -1587,7 +1621,7 @@ ${templateContent}`;
|
|
|
1587
1621
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
1588
1622
|
);
|
|
1589
1623
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
1590
|
-
|
|
1624
|
+
await import_promises4.default.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
1591
1625
|
return { success: true, action: "updated" };
|
|
1592
1626
|
} catch (error) {
|
|
1593
1627
|
console.error(`Gemini config warning: ${error.message}`);
|
|
@@ -1601,23 +1635,23 @@ async function installAntigravitySkill() {
|
|
|
1601
1635
|
const prjctSkillDir = import_node_path5.default.join(antigravitySkillsDir, "prjct");
|
|
1602
1636
|
const skillMdPath = import_node_path5.default.join(prjctSkillDir, "SKILL.md");
|
|
1603
1637
|
const templatePath = import_node_path5.default.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
|
|
1604
|
-
|
|
1605
|
-
const
|
|
1606
|
-
if (!
|
|
1638
|
+
await import_promises4.default.mkdir(prjctSkillDir, { recursive: true });
|
|
1639
|
+
const skillExists = await fileExists(skillMdPath);
|
|
1640
|
+
if (!await fileExists(templatePath)) {
|
|
1607
1641
|
console.error("Antigravity SKILL.md template not found");
|
|
1608
1642
|
return { success: false, action: null };
|
|
1609
1643
|
}
|
|
1610
|
-
const templateContent =
|
|
1611
|
-
|
|
1612
|
-
return { success: true, action:
|
|
1644
|
+
const templateContent = await import_promises4.default.readFile(templatePath, "utf-8");
|
|
1645
|
+
await import_promises4.default.writeFile(skillMdPath, templateContent, "utf-8");
|
|
1646
|
+
return { success: true, action: skillExists ? "updated" : "created" };
|
|
1613
1647
|
} catch (error) {
|
|
1614
1648
|
console.error(`Antigravity skill warning: ${error.message}`);
|
|
1615
1649
|
return { success: false, action: null };
|
|
1616
1650
|
}
|
|
1617
1651
|
}
|
|
1618
1652
|
__name(installAntigravitySkill, "installAntigravitySkill");
|
|
1619
|
-
function needsAntigravityInstallation() {
|
|
1620
|
-
const detection = detectAntigravity();
|
|
1653
|
+
async function needsAntigravityInstallation() {
|
|
1654
|
+
const detection = await detectAntigravity();
|
|
1621
1655
|
return detection.installed && !detection.skillInstalled;
|
|
1622
1656
|
}
|
|
1623
1657
|
__name(needsAntigravityInstallation, "needsAntigravityInstallation");
|
|
@@ -1635,18 +1669,18 @@ async function installCursorProject(projectRoot) {
|
|
|
1635
1669
|
const routerMdcDest = import_node_path5.default.join(rulesDir, "prjct.mdc");
|
|
1636
1670
|
const routerMdcSource = import_node_path5.default.join(getPackageRoot(), "templates", "cursor", "router.mdc");
|
|
1637
1671
|
const cursorCommandsSource = import_node_path5.default.join(getPackageRoot(), "templates", "cursor", "commands");
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
if (
|
|
1641
|
-
|
|
1672
|
+
await import_promises4.default.mkdir(rulesDir, { recursive: true });
|
|
1673
|
+
await import_promises4.default.mkdir(commandsDir, { recursive: true });
|
|
1674
|
+
if (await fileExists(routerMdcSource)) {
|
|
1675
|
+
await import_promises4.default.copyFile(routerMdcSource, routerMdcDest);
|
|
1642
1676
|
result.rulesCreated = true;
|
|
1643
1677
|
}
|
|
1644
|
-
if (
|
|
1645
|
-
const commandFiles =
|
|
1678
|
+
if (await fileExists(cursorCommandsSource)) {
|
|
1679
|
+
const commandFiles = (await import_promises4.default.readdir(cursorCommandsSource)).filter((f) => f.endsWith(".md"));
|
|
1646
1680
|
for (const file of commandFiles) {
|
|
1647
1681
|
const src = import_node_path5.default.join(cursorCommandsSource, file);
|
|
1648
1682
|
const dest = import_node_path5.default.join(commandsDir, file);
|
|
1649
|
-
|
|
1683
|
+
await import_promises4.default.copyFile(src, dest);
|
|
1650
1684
|
}
|
|
1651
1685
|
result.commandsCreated = commandFiles.length > 0;
|
|
1652
1686
|
}
|
|
@@ -1674,10 +1708,10 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
1674
1708
|
".cursor/commands/resume.md"
|
|
1675
1709
|
];
|
|
1676
1710
|
let content = "";
|
|
1677
|
-
let
|
|
1711
|
+
let configExists = false;
|
|
1678
1712
|
try {
|
|
1679
|
-
content =
|
|
1680
|
-
|
|
1713
|
+
content = await import_promises4.default.readFile(gitignorePath, "utf-8");
|
|
1714
|
+
configExists = true;
|
|
1681
1715
|
} catch (error) {
|
|
1682
1716
|
if (!isNotFoundError(error)) {
|
|
1683
1717
|
throw error;
|
|
@@ -1686,12 +1720,12 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
1686
1720
|
if (content.includes(".cursor/rules/prjct.mdc")) {
|
|
1687
1721
|
return false;
|
|
1688
1722
|
}
|
|
1689
|
-
const newContent =
|
|
1723
|
+
const newContent = configExists ? `${content.trimEnd()}
|
|
1690
1724
|
|
|
1691
1725
|
${entriesToAdd.join("\n")}
|
|
1692
1726
|
` : `${entriesToAdd.join("\n")}
|
|
1693
1727
|
`;
|
|
1694
|
-
|
|
1728
|
+
await import_promises4.default.writeFile(gitignorePath, newContent, "utf-8");
|
|
1695
1729
|
return true;
|
|
1696
1730
|
} catch (error) {
|
|
1697
1731
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -1699,14 +1733,14 @@ ${entriesToAdd.join("\n")}
|
|
|
1699
1733
|
}
|
|
1700
1734
|
}
|
|
1701
1735
|
__name(addCursorToGitignore, "addCursorToGitignore");
|
|
1702
|
-
function hasCursorProject(projectRoot) {
|
|
1703
|
-
return
|
|
1736
|
+
async function hasCursorProject(projectRoot) {
|
|
1737
|
+
return await fileExists(import_node_path5.default.join(projectRoot, ".cursor"));
|
|
1704
1738
|
}
|
|
1705
1739
|
__name(hasCursorProject, "hasCursorProject");
|
|
1706
|
-
function needsCursorRegeneration(projectRoot) {
|
|
1740
|
+
async function needsCursorRegeneration(projectRoot) {
|
|
1707
1741
|
const cursorDir = import_node_path5.default.join(projectRoot, ".cursor");
|
|
1708
1742
|
const routerPath = import_node_path5.default.join(cursorDir, "rules", "prjct.mdc");
|
|
1709
|
-
return
|
|
1743
|
+
return await fileExists(cursorDir) && !await fileExists(routerPath);
|
|
1710
1744
|
}
|
|
1711
1745
|
__name(needsCursorRegeneration, "needsCursorRegeneration");
|
|
1712
1746
|
async function installWindsurfProject(projectRoot) {
|
|
@@ -1728,18 +1762,20 @@ async function installWindsurfProject(projectRoot) {
|
|
|
1728
1762
|
"windsurf",
|
|
1729
1763
|
"workflows"
|
|
1730
1764
|
);
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
if (
|
|
1734
|
-
|
|
1765
|
+
await import_promises4.default.mkdir(rulesDir, { recursive: true });
|
|
1766
|
+
await import_promises4.default.mkdir(workflowsDir, { recursive: true });
|
|
1767
|
+
if (await fileExists(routerSource)) {
|
|
1768
|
+
await import_promises4.default.copyFile(routerSource, routerDest);
|
|
1735
1769
|
result.rulesCreated = true;
|
|
1736
1770
|
}
|
|
1737
|
-
if (
|
|
1738
|
-
const workflowFiles =
|
|
1771
|
+
if (await fileExists(windsurfWorkflowsSource)) {
|
|
1772
|
+
const workflowFiles = (await import_promises4.default.readdir(windsurfWorkflowsSource)).filter(
|
|
1773
|
+
(f) => f.endsWith(".md")
|
|
1774
|
+
);
|
|
1739
1775
|
for (const file of workflowFiles) {
|
|
1740
1776
|
const src = import_node_path5.default.join(windsurfWorkflowsSource, file);
|
|
1741
1777
|
const dest = import_node_path5.default.join(workflowsDir, file);
|
|
1742
|
-
|
|
1778
|
+
await import_promises4.default.copyFile(src, dest);
|
|
1743
1779
|
}
|
|
1744
1780
|
result.workflowsCreated = workflowFiles.length > 0;
|
|
1745
1781
|
}
|
|
@@ -1767,10 +1803,10 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
1767
1803
|
".windsurf/workflows/resume.md"
|
|
1768
1804
|
];
|
|
1769
1805
|
let content = "";
|
|
1770
|
-
let
|
|
1806
|
+
let configExists = false;
|
|
1771
1807
|
try {
|
|
1772
|
-
content =
|
|
1773
|
-
|
|
1808
|
+
content = await import_promises4.default.readFile(gitignorePath, "utf-8");
|
|
1809
|
+
configExists = true;
|
|
1774
1810
|
} catch (error) {
|
|
1775
1811
|
if (!isNotFoundError(error)) {
|
|
1776
1812
|
throw error;
|
|
@@ -1779,12 +1815,12 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
1779
1815
|
if (content.includes(".windsurf/rules/prjct.md")) {
|
|
1780
1816
|
return false;
|
|
1781
1817
|
}
|
|
1782
|
-
const newContent =
|
|
1818
|
+
const newContent = configExists ? `${content.trimEnd()}
|
|
1783
1819
|
|
|
1784
1820
|
${entriesToAdd.join("\n")}
|
|
1785
1821
|
` : `${entriesToAdd.join("\n")}
|
|
1786
1822
|
`;
|
|
1787
|
-
|
|
1823
|
+
await import_promises4.default.writeFile(gitignorePath, newContent, "utf-8");
|
|
1788
1824
|
return true;
|
|
1789
1825
|
} catch (error) {
|
|
1790
1826
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -1792,35 +1828,35 @@ ${entriesToAdd.join("\n")}
|
|
|
1792
1828
|
}
|
|
1793
1829
|
}
|
|
1794
1830
|
__name(addWindsurfToGitignore, "addWindsurfToGitignore");
|
|
1795
|
-
function hasWindsurfProject(projectRoot) {
|
|
1796
|
-
return
|
|
1831
|
+
async function hasWindsurfProject(projectRoot) {
|
|
1832
|
+
return await fileExists(import_node_path5.default.join(projectRoot, ".windsurf"));
|
|
1797
1833
|
}
|
|
1798
1834
|
__name(hasWindsurfProject, "hasWindsurfProject");
|
|
1799
|
-
function needsWindsurfRegeneration(projectRoot) {
|
|
1835
|
+
async function needsWindsurfRegeneration(projectRoot) {
|
|
1800
1836
|
const windsurfDir = import_node_path5.default.join(projectRoot, ".windsurf");
|
|
1801
1837
|
const routerPath = import_node_path5.default.join(windsurfDir, "rules", "prjct.md");
|
|
1802
|
-
return
|
|
1838
|
+
return await fileExists(windsurfDir) && !await fileExists(routerPath);
|
|
1803
1839
|
}
|
|
1804
1840
|
__name(needsWindsurfRegeneration, "needsWindsurfRegeneration");
|
|
1805
1841
|
async function migrateProjectsCliVersion() {
|
|
1806
1842
|
try {
|
|
1807
1843
|
const projectsDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".prjct-cli", "projects");
|
|
1808
|
-
if (!
|
|
1844
|
+
if (!await fileExists(projectsDir)) {
|
|
1809
1845
|
return;
|
|
1810
1846
|
}
|
|
1811
|
-
const projectDirs =
|
|
1847
|
+
const projectDirs = (await import_promises4.default.readdir(projectsDir, { withFileTypes: true })).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1812
1848
|
let migrated = 0;
|
|
1813
1849
|
for (const projectId of projectDirs) {
|
|
1814
1850
|
const projectJsonPath = import_node_path5.default.join(projectsDir, projectId, "project.json");
|
|
1815
|
-
if (!
|
|
1851
|
+
if (!await fileExists(projectJsonPath)) {
|
|
1816
1852
|
continue;
|
|
1817
1853
|
}
|
|
1818
1854
|
try {
|
|
1819
|
-
const content =
|
|
1855
|
+
const content = await import_promises4.default.readFile(projectJsonPath, "utf8");
|
|
1820
1856
|
const project = JSON.parse(content);
|
|
1821
1857
|
if (project.cliVersion !== VERSION) {
|
|
1822
1858
|
project.cliVersion = VERSION;
|
|
1823
|
-
|
|
1859
|
+
await import_promises4.default.writeFile(projectJsonPath, JSON.stringify(project, null, 2));
|
|
1824
1860
|
migrated++;
|
|
1825
1861
|
}
|
|
1826
1862
|
} catch (error) {
|
|
@@ -1839,11 +1875,11 @@ async function migrateProjectsCliVersion() {
|
|
|
1839
1875
|
}
|
|
1840
1876
|
}
|
|
1841
1877
|
__name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
|
|
1842
|
-
function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
1878
|
+
async function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
1843
1879
|
let settings = {};
|
|
1844
|
-
if (
|
|
1880
|
+
if (await fileExists(settingsPath)) {
|
|
1845
1881
|
try {
|
|
1846
|
-
settings = JSON.parse(
|
|
1882
|
+
settings = JSON.parse(await import_promises4.default.readFile(settingsPath, "utf8"));
|
|
1847
1883
|
} catch (error) {
|
|
1848
1884
|
if (!(error instanceof SyntaxError)) {
|
|
1849
1885
|
throw error;
|
|
@@ -1851,7 +1887,7 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
|
1851
1887
|
}
|
|
1852
1888
|
}
|
|
1853
1889
|
settings.statusLine = { type: "command", command: statusLinePath };
|
|
1854
|
-
|
|
1890
|
+
await import_promises4.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
1855
1891
|
}
|
|
1856
1892
|
__name(ensureStatusLineSettings, "ensureStatusLineSettings");
|
|
1857
1893
|
async function installStatusLine() {
|
|
@@ -1871,23 +1907,23 @@ async function installStatusLine() {
|
|
|
1871
1907
|
const sourceLibDir = import_node_path5.default.join(assetsDir, "lib");
|
|
1872
1908
|
const sourceComponentsDir = import_node_path5.default.join(assetsDir, "components");
|
|
1873
1909
|
const sourceConfigPath = import_node_path5.default.join(assetsDir, "default-config.json");
|
|
1874
|
-
if (!
|
|
1875
|
-
|
|
1910
|
+
if (!await fileExists(claudeDir)) {
|
|
1911
|
+
await import_promises4.default.mkdir(claudeDir, { recursive: true });
|
|
1876
1912
|
}
|
|
1877
|
-
if (!
|
|
1878
|
-
|
|
1913
|
+
if (!await fileExists(prjctStatusLineDir)) {
|
|
1914
|
+
await import_promises4.default.mkdir(prjctStatusLineDir, { recursive: true });
|
|
1879
1915
|
}
|
|
1880
|
-
if (!
|
|
1881
|
-
|
|
1916
|
+
if (!await fileExists(prjctThemesDir)) {
|
|
1917
|
+
await import_promises4.default.mkdir(prjctThemesDir, { recursive: true });
|
|
1882
1918
|
}
|
|
1883
|
-
if (!
|
|
1884
|
-
|
|
1919
|
+
if (!await fileExists(prjctLibDir)) {
|
|
1920
|
+
await import_promises4.default.mkdir(prjctLibDir, { recursive: true });
|
|
1885
1921
|
}
|
|
1886
|
-
if (!
|
|
1887
|
-
|
|
1922
|
+
if (!await fileExists(prjctComponentsDir)) {
|
|
1923
|
+
await import_promises4.default.mkdir(prjctComponentsDir, { recursive: true });
|
|
1888
1924
|
}
|
|
1889
|
-
if (
|
|
1890
|
-
const existingContent =
|
|
1925
|
+
if (await fileExists(prjctStatusLinePath)) {
|
|
1926
|
+
const existingContent = await import_promises4.default.readFile(prjctStatusLinePath, "utf8");
|
|
1891
1927
|
if (existingContent.includes("CLI_VERSION=")) {
|
|
1892
1928
|
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
1893
1929
|
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
@@ -1895,31 +1931,31 @@ async function installStatusLine() {
|
|
|
1895
1931
|
/CLI_VERSION="[^"]*"/,
|
|
1896
1932
|
`CLI_VERSION="${VERSION}"`
|
|
1897
1933
|
);
|
|
1898
|
-
|
|
1934
|
+
await import_promises4.default.writeFile(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
1899
1935
|
}
|
|
1900
|
-
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1901
|
-
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
1902
|
-
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
1903
|
-
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
1936
|
+
await installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1937
|
+
await installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
1938
|
+
await ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
1939
|
+
await ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
1904
1940
|
return;
|
|
1905
1941
|
}
|
|
1906
1942
|
}
|
|
1907
|
-
if (
|
|
1908
|
-
let scriptContent =
|
|
1943
|
+
if (await fileExists(sourceScript)) {
|
|
1944
|
+
let scriptContent = await import_promises4.default.readFile(sourceScript, "utf8");
|
|
1909
1945
|
scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
|
|
1910
|
-
|
|
1911
|
-
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1912
|
-
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
1913
|
-
if (
|
|
1914
|
-
const themes =
|
|
1946
|
+
await import_promises4.default.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
1947
|
+
await installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1948
|
+
await installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
1949
|
+
if (await fileExists(sourceThemeDir)) {
|
|
1950
|
+
const themes = await import_promises4.default.readdir(sourceThemeDir);
|
|
1915
1951
|
for (const theme of themes) {
|
|
1916
1952
|
const src = import_node_path5.default.join(sourceThemeDir, theme);
|
|
1917
1953
|
const dest = import_node_path5.default.join(prjctThemesDir, theme);
|
|
1918
|
-
|
|
1954
|
+
await import_promises4.default.copyFile(src, dest);
|
|
1919
1955
|
}
|
|
1920
1956
|
}
|
|
1921
|
-
if (!
|
|
1922
|
-
|
|
1957
|
+
if (!await fileExists(prjctConfigPath) && await fileExists(sourceConfigPath)) {
|
|
1958
|
+
await import_promises4.default.copyFile(sourceConfigPath, prjctConfigPath);
|
|
1923
1959
|
}
|
|
1924
1960
|
} else {
|
|
1925
1961
|
const scriptContent = `#!/bin/bash
|
|
@@ -1954,10 +1990,10 @@ if [ -f "$CONFIG" ]; then
|
|
|
1954
1990
|
fi
|
|
1955
1991
|
echo "prjct"
|
|
1956
1992
|
`;
|
|
1957
|
-
|
|
1993
|
+
await import_promises4.default.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
1958
1994
|
}
|
|
1959
|
-
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
1960
|
-
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
1995
|
+
await ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
1996
|
+
await ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
1961
1997
|
} catch (error) {
|
|
1962
1998
|
if (!isNotFoundError(error)) {
|
|
1963
1999
|
console.error(`Status line warning: ${error.message}`);
|
|
@@ -1969,8 +2005,8 @@ async function installContext7MCP() {
|
|
|
1969
2005
|
try {
|
|
1970
2006
|
const claudeDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".claude");
|
|
1971
2007
|
const mcpConfigPath = import_node_path5.default.join(claudeDir, "mcp.json");
|
|
1972
|
-
if (!
|
|
1973
|
-
|
|
2008
|
+
if (!await fileExists(claudeDir)) {
|
|
2009
|
+
await import_promises4.default.mkdir(claudeDir, { recursive: true });
|
|
1974
2010
|
}
|
|
1975
2011
|
const context7Config = {
|
|
1976
2012
|
mcpServers: {
|
|
@@ -1980,56 +2016,56 @@ async function installContext7MCP() {
|
|
|
1980
2016
|
}
|
|
1981
2017
|
}
|
|
1982
2018
|
};
|
|
1983
|
-
if (
|
|
1984
|
-
const existingContent =
|
|
2019
|
+
if (await fileExists(mcpConfigPath)) {
|
|
2020
|
+
const existingContent = await import_promises4.default.readFile(mcpConfigPath, "utf-8");
|
|
1985
2021
|
const existingConfig = JSON.parse(existingContent);
|
|
1986
2022
|
if (existingConfig.mcpServers?.context7) {
|
|
1987
2023
|
return;
|
|
1988
2024
|
}
|
|
1989
2025
|
existingConfig.mcpServers = existingConfig.mcpServers || {};
|
|
1990
2026
|
existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
|
|
1991
|
-
|
|
2027
|
+
await import_promises4.default.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
|
|
1992
2028
|
} else {
|
|
1993
|
-
|
|
2029
|
+
await import_promises4.default.writeFile(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
|
|
1994
2030
|
}
|
|
1995
2031
|
} catch (error) {
|
|
1996
2032
|
console.error(`Context7 MCP setup warning: ${error.message}`);
|
|
1997
2033
|
}
|
|
1998
2034
|
}
|
|
1999
2035
|
__name(installContext7MCP, "installContext7MCP");
|
|
2000
|
-
function installStatusLineModules(sourceDir, destDir) {
|
|
2001
|
-
if (!
|
|
2036
|
+
async function installStatusLineModules(sourceDir, destDir) {
|
|
2037
|
+
if (!await fileExists(sourceDir)) {
|
|
2002
2038
|
return;
|
|
2003
2039
|
}
|
|
2004
|
-
const files =
|
|
2040
|
+
const files = await import_promises4.default.readdir(sourceDir);
|
|
2005
2041
|
for (const file of files) {
|
|
2006
2042
|
if (file.endsWith(".sh")) {
|
|
2007
2043
|
const src = import_node_path5.default.join(sourceDir, file);
|
|
2008
2044
|
const dest = import_node_path5.default.join(destDir, file);
|
|
2009
|
-
|
|
2010
|
-
|
|
2045
|
+
await import_promises4.default.copyFile(src, dest);
|
|
2046
|
+
await import_promises4.default.chmod(dest, 493);
|
|
2011
2047
|
}
|
|
2012
2048
|
}
|
|
2013
2049
|
}
|
|
2014
2050
|
__name(installStatusLineModules, "installStatusLineModules");
|
|
2015
|
-
function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
2051
|
+
async function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
2016
2052
|
try {
|
|
2017
|
-
if (
|
|
2018
|
-
const stats =
|
|
2053
|
+
if (await fileExists(linkPath)) {
|
|
2054
|
+
const stats = await import_promises4.default.lstat(linkPath);
|
|
2019
2055
|
if (stats.isSymbolicLink()) {
|
|
2020
|
-
const existingTarget =
|
|
2056
|
+
const existingTarget = await import_promises4.default.readlink(linkPath);
|
|
2021
2057
|
if (existingTarget === targetPath) {
|
|
2022
2058
|
return;
|
|
2023
2059
|
}
|
|
2024
2060
|
}
|
|
2025
|
-
|
|
2061
|
+
await import_promises4.default.unlink(linkPath);
|
|
2026
2062
|
}
|
|
2027
|
-
|
|
2063
|
+
await import_promises4.default.symlink(targetPath, linkPath);
|
|
2028
2064
|
} catch (_error) {
|
|
2029
2065
|
try {
|
|
2030
|
-
if (
|
|
2031
|
-
|
|
2032
|
-
|
|
2066
|
+
if (await fileExists(targetPath)) {
|
|
2067
|
+
await import_promises4.default.copyFile(targetPath, linkPath);
|
|
2068
|
+
await import_promises4.default.chmod(linkPath, 493);
|
|
2033
2069
|
}
|
|
2034
2070
|
} catch (copyError) {
|
|
2035
2071
|
if (!isNotFoundError(copyError)) {
|