prjct-cli 0.37.0 → 0.39.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 (33) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/README.md +84 -37
  3. package/bin/prjct.ts +11 -1
  4. package/core/index.ts +53 -26
  5. package/core/infrastructure/ai-provider.ts +157 -1
  6. package/core/infrastructure/setup.ts +225 -7
  7. package/core/types/provider.ts +18 -1
  8. package/dist/bin/prjct.mjs +3607 -1050
  9. package/dist/core/infrastructure/command-installer.js +458 -47
  10. package/dist/core/infrastructure/setup.js +728 -211
  11. package/package.json +1 -1
  12. package/templates/antigravity/SKILL.md +39 -0
  13. package/templates/cursor/commands/bug.md +8 -0
  14. package/templates/cursor/commands/done.md +4 -0
  15. package/templates/cursor/commands/pause.md +6 -0
  16. package/templates/cursor/commands/resume.md +4 -0
  17. package/templates/cursor/commands/ship.md +8 -0
  18. package/templates/cursor/commands/sync.md +4 -0
  19. package/templates/cursor/commands/task.md +8 -0
  20. package/templates/cursor/router.mdc +6 -6
  21. package/templates/global/ANTIGRAVITY.md +256 -0
  22. package/templates/global/CLAUDE.md +30 -0
  23. package/templates/global/CURSOR.mdc +60 -25
  24. package/templates/global/GEMINI.md +30 -0
  25. package/templates/global/WINDSURF.md +268 -0
  26. package/templates/windsurf/router.md +28 -0
  27. package/templates/windsurf/workflows/bug.md +8 -0
  28. package/templates/windsurf/workflows/done.md +4 -0
  29. package/templates/windsurf/workflows/pause.md +4 -0
  30. package/templates/windsurf/workflows/resume.md +4 -0
  31. package/templates/windsurf/workflows/ship.md +8 -0
  32. package/templates/windsurf/workflows/sync.md +4 -0
  33. package/templates/windsurf/workflows/task.md +8 -0
@@ -6,6 +6,9 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
8
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
9
12
  var __export = (target, all) => {
10
13
  for (var name in all)
11
14
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -28,22 +31,410 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
31
  ));
29
32
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
33
 
34
+ // core/infrastructure/ai-provider.ts
35
+ var ai_provider_exports = {};
36
+ __export(ai_provider_exports, {
37
+ AntigravityProvider: () => AntigravityProvider,
38
+ ClaudeProvider: () => ClaudeProvider,
39
+ CursorProvider: () => CursorProvider,
40
+ GeminiProvider: () => GeminiProvider,
41
+ Providers: () => Providers,
42
+ WindsurfProvider: () => WindsurfProvider,
43
+ default: () => ai_provider_default,
44
+ detectAllProviders: () => detectAllProviders,
45
+ detectAntigravity: () => detectAntigravity,
46
+ detectCursorProject: () => detectCursorProject,
47
+ detectProvider: () => detectProvider,
48
+ detectWindsurfProject: () => detectWindsurfProject,
49
+ getActiveProvider: () => getActiveProvider,
50
+ getCommandsDir: () => getCommandsDir,
51
+ getGlobalContextPath: () => getGlobalContextPath,
52
+ getGlobalSettingsPath: () => getGlobalSettingsPath,
53
+ getProjectCommandsPath: () => getProjectCommandsPath,
54
+ getProviderBranding: () => getProviderBranding,
55
+ getSkillsPath: () => getSkillsPath,
56
+ hasProviderConfig: () => hasProviderConfig,
57
+ needsCursorRouterRegeneration: () => needsCursorRouterRegeneration,
58
+ needsWindsurfRouterRegeneration: () => needsWindsurfRouterRegeneration,
59
+ selectProvider: () => selectProvider
60
+ });
61
+ function whichCommand(command) {
62
+ try {
63
+ const result = (0, import_child_process.execSync)(`which ${command}`, { stdio: "pipe", encoding: "utf-8" });
64
+ return result.trim();
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+ function getCliVersion(command) {
70
+ try {
71
+ const result = (0, import_child_process.execSync)(`${command} --version`, { stdio: "pipe", encoding: "utf-8" });
72
+ const match = result.match(/\d+\.\d+\.\d+/);
73
+ return match ? match[0] : result.trim();
74
+ } catch {
75
+ return null;
76
+ }
77
+ }
78
+ function detectProvider(provider) {
79
+ const config = Providers[provider];
80
+ if (!config.cliCommand) {
81
+ return { installed: false };
82
+ }
83
+ const cliPath = whichCommand(config.cliCommand);
84
+ if (!cliPath) {
85
+ return { installed: false };
86
+ }
87
+ const version = getCliVersion(config.cliCommand);
88
+ return {
89
+ installed: true,
90
+ version: version || void 0,
91
+ path: cliPath
92
+ };
93
+ }
94
+ function detectAllProviders() {
95
+ return {
96
+ claude: detectProvider("claude"),
97
+ gemini: detectProvider("gemini")
98
+ };
99
+ }
100
+ function getActiveProvider(projectProvider) {
101
+ if (projectProvider && Providers[projectProvider]) {
102
+ return Providers[projectProvider];
103
+ }
104
+ const detection = detectAllProviders();
105
+ if (detection.claude.installed && !detection.gemini.installed) {
106
+ return ClaudeProvider;
107
+ }
108
+ if (detection.gemini.installed && !detection.claude.installed) {
109
+ return GeminiProvider;
110
+ }
111
+ return ClaudeProvider;
112
+ }
113
+ function hasProviderConfig(provider) {
114
+ const config = Providers[provider];
115
+ if (!config.configDir) {
116
+ return false;
117
+ }
118
+ return import_fs2.default.existsSync(config.configDir);
119
+ }
120
+ function getProviderBranding(provider) {
121
+ const config = Providers[provider];
122
+ if (provider === "gemini") {
123
+ return {
124
+ commitFooter: `\u{1F916} Generated with [p/](https://www.prjct.app/)
125
+ Designed for [Gemini](${config.websiteUrl})`,
126
+ signature: "\u26A1 prjct + Gemini"
127
+ };
128
+ }
129
+ if (provider === "cursor") {
130
+ return {
131
+ commitFooter: `\u{1F916} Generated with [p/](https://www.prjct.app/)
132
+ Built with [Cursor](${config.websiteUrl})`,
133
+ signature: "\u26A1 prjct + Cursor"
134
+ };
135
+ }
136
+ if (provider === "antigravity") {
137
+ return {
138
+ commitFooter: `\u{1F916} Generated with [p/](https://www.prjct.app/)
139
+ Powered by [Antigravity](${config.websiteUrl})`,
140
+ signature: "\u26A1 prjct + Antigravity"
141
+ };
142
+ }
143
+ if (provider === "windsurf") {
144
+ return {
145
+ commitFooter: `\u{1F916} Generated with [p/](https://www.prjct.app/)
146
+ Built with [Windsurf](${config.websiteUrl})`,
147
+ signature: "\u26A1 prjct + Windsurf"
148
+ };
149
+ }
150
+ return {
151
+ commitFooter: `\u{1F916} Generated with [p/](https://www.prjct.app/)
152
+ Designed for [Claude](${config.websiteUrl})`,
153
+ signature: "\u26A1 prjct + Claude"
154
+ };
155
+ }
156
+ function detectCursorProject(projectRoot) {
157
+ const cursorDir = import_path2.default.join(projectRoot, ".cursor");
158
+ const rulesDir = import_path2.default.join(cursorDir, "rules");
159
+ const routerPath = import_path2.default.join(rulesDir, "prjct.mdc");
160
+ const detected = import_fs2.default.existsSync(cursorDir);
161
+ const routerInstalled = import_fs2.default.existsSync(routerPath);
162
+ return {
163
+ detected,
164
+ routerInstalled,
165
+ projectRoot: detected ? projectRoot : void 0
166
+ };
167
+ }
168
+ function needsCursorRouterRegeneration(projectRoot) {
169
+ const detection = detectCursorProject(projectRoot);
170
+ return detection.detected && !detection.routerInstalled;
171
+ }
172
+ function detectWindsurfProject(projectRoot) {
173
+ const windsurfDir = import_path2.default.join(projectRoot, ".windsurf");
174
+ const rulesDir = import_path2.default.join(windsurfDir, "rules");
175
+ const routerPath = import_path2.default.join(rulesDir, "prjct.md");
176
+ const detected = import_fs2.default.existsSync(windsurfDir);
177
+ const routerInstalled = import_fs2.default.existsSync(routerPath);
178
+ return {
179
+ detected,
180
+ routerInstalled,
181
+ projectRoot: detected ? projectRoot : void 0
182
+ };
183
+ }
184
+ function needsWindsurfRouterRegeneration(projectRoot) {
185
+ const detection = detectWindsurfProject(projectRoot);
186
+ return detection.detected && !detection.routerInstalled;
187
+ }
188
+ function detectAntigravity() {
189
+ const configPath = AntigravityProvider.configDir;
190
+ if (!configPath) {
191
+ return { installed: false, skillInstalled: false };
192
+ }
193
+ const installed = import_fs2.default.existsSync(configPath);
194
+ const skillPath = import_path2.default.join(configPath, "skills", "prjct", "SKILL.md");
195
+ const skillInstalled = import_fs2.default.existsSync(skillPath);
196
+ return {
197
+ installed,
198
+ skillInstalled,
199
+ configPath: installed ? configPath : void 0
200
+ };
201
+ }
202
+ function getGlobalContextPath(provider) {
203
+ const config = Providers[provider];
204
+ if (!config.configDir) {
205
+ return null;
206
+ }
207
+ return import_path2.default.join(config.configDir, config.contextFile);
208
+ }
209
+ function getGlobalSettingsPath(provider) {
210
+ const config = Providers[provider];
211
+ if (!config.configDir || !config.settingsFile) {
212
+ return null;
213
+ }
214
+ return import_path2.default.join(config.configDir, config.settingsFile);
215
+ }
216
+ function getSkillsPath(provider) {
217
+ return Providers[provider].skillsDir;
218
+ }
219
+ function getCommandsDir(provider) {
220
+ return Providers[provider].commandsDir;
221
+ }
222
+ function getProjectCommandsPath(provider, projectRoot) {
223
+ const config = Providers[provider];
224
+ return import_path2.default.join(projectRoot, config.commandsDir);
225
+ }
226
+ function selectProvider() {
227
+ const detection = detectAllProviders();
228
+ const claudeInstalled = detection.claude.installed;
229
+ const geminiInstalled = detection.gemini.installed;
230
+ if (!claudeInstalled && !geminiInstalled) {
231
+ return {
232
+ provider: "claude",
233
+ userSelected: false,
234
+ detection
235
+ };
236
+ }
237
+ if (claudeInstalled && !geminiInstalled) {
238
+ return {
239
+ provider: "claude",
240
+ userSelected: false,
241
+ detection
242
+ };
243
+ }
244
+ if (geminiInstalled && !claudeInstalled) {
245
+ return {
246
+ provider: "gemini",
247
+ userSelected: false,
248
+ detection
249
+ };
250
+ }
251
+ return {
252
+ provider: "claude",
253
+ userSelected: true,
254
+ // Indicates user should be prompted
255
+ detection
256
+ };
257
+ }
258
+ var import_child_process, import_fs2, import_path2, import_os, ClaudeProvider, GeminiProvider, AntigravityProvider, CursorProvider, WindsurfProvider, Providers, ai_provider_default;
259
+ var init_ai_provider = __esm({
260
+ "core/infrastructure/ai-provider.ts"() {
261
+ "use strict";
262
+ import_child_process = require("child_process");
263
+ import_fs2 = __toESM(require("fs"));
264
+ import_path2 = __toESM(require("path"));
265
+ import_os = __toESM(require("os"));
266
+ ClaudeProvider = {
267
+ name: "claude",
268
+ displayName: "Claude Code",
269
+ cliCommand: "claude",
270
+ configDir: import_path2.default.join(import_os.default.homedir(), ".claude"),
271
+ contextFile: "CLAUDE.md",
272
+ skillsDir: import_path2.default.join(import_os.default.homedir(), ".claude", "skills"),
273
+ commandsDir: ".claude/commands",
274
+ commandFormat: "md",
275
+ settingsFile: "settings.json",
276
+ projectSettingsFile: "settings.local.json",
277
+ ignoreFile: ".claudeignore",
278
+ websiteUrl: "https://www.anthropic.com/claude",
279
+ docsUrl: "https://docs.anthropic.com/claude-code"
280
+ };
281
+ GeminiProvider = {
282
+ name: "gemini",
283
+ displayName: "Gemini CLI",
284
+ cliCommand: "gemini",
285
+ configDir: import_path2.default.join(import_os.default.homedir(), ".gemini"),
286
+ contextFile: "GEMINI.md",
287
+ skillsDir: import_path2.default.join(import_os.default.homedir(), ".gemini", "skills"),
288
+ commandsDir: ".gemini/commands",
289
+ commandFormat: "toml",
290
+ settingsFile: "settings.json",
291
+ projectSettingsFile: "settings.json",
292
+ ignoreFile: ".geminiignore",
293
+ websiteUrl: "https://geminicli.com",
294
+ docsUrl: "https://geminicli.com/docs"
295
+ };
296
+ AntigravityProvider = {
297
+ name: "antigravity",
298
+ displayName: "Google Antigravity",
299
+ cliCommand: null,
300
+ // Not a CLI command, but a platform/app
301
+ configDir: import_path2.default.join(import_os.default.homedir(), ".gemini", "antigravity"),
302
+ contextFile: "ANTIGRAVITY.md",
303
+ skillsDir: import_path2.default.join(import_os.default.homedir(), ".gemini", "antigravity", "global_skills"),
304
+ commandsDir: ".agent/skills",
305
+ // Antigravity uses .agent/skills in projects
306
+ commandFormat: "md",
307
+ // Uses SKILL.md
308
+ settingsFile: "mcp_config.json",
309
+ // Uses MCP config
310
+ projectSettingsFile: null,
311
+ ignoreFile: ".agentignore",
312
+ // Assumed
313
+ websiteUrl: "https://gemini.google.com/app/antigravity",
314
+ docsUrl: "https://gemini.google.com/app/antigravity"
315
+ };
316
+ CursorProvider = {
317
+ name: "cursor",
318
+ displayName: "Cursor IDE",
319
+ cliCommand: null,
320
+ // Not a CLI - GUI app
321
+ configDir: null,
322
+ // No global config directory
323
+ contextFile: "prjct.mdc",
324
+ // Uses .mdc format with frontmatter
325
+ skillsDir: null,
326
+ // No skills directory
327
+ commandsDir: ".cursor/commands",
328
+ rulesDir: ".cursor/rules",
329
+ // Cursor-specific: rules directory
330
+ commandFormat: "md",
331
+ settingsFile: null,
332
+ projectSettingsFile: null,
333
+ ignoreFile: ".cursorignore",
334
+ isProjectLevel: true,
335
+ // Config is project-level only
336
+ websiteUrl: "https://cursor.com",
337
+ docsUrl: "https://cursor.com/docs"
338
+ };
339
+ WindsurfProvider = {
340
+ name: "windsurf",
341
+ displayName: "Windsurf IDE",
342
+ cliCommand: null,
343
+ // Not a CLI - GUI app
344
+ configDir: null,
345
+ // No global config directory
346
+ contextFile: "prjct.md",
347
+ // Uses .md format (not .mdc)
348
+ skillsDir: null,
349
+ // No skills directory
350
+ commandsDir: ".windsurf/workflows",
351
+ // Windsurf uses "workflows" not "commands"
352
+ rulesDir: ".windsurf/rules",
353
+ commandFormat: "md",
354
+ settingsFile: null,
355
+ projectSettingsFile: null,
356
+ ignoreFile: ".windsurfignore",
357
+ isProjectLevel: true,
358
+ // Config is project-level only
359
+ websiteUrl: "https://windsurf.com",
360
+ docsUrl: "https://docs.windsurf.com"
361
+ };
362
+ Providers = {
363
+ claude: ClaudeProvider,
364
+ gemini: GeminiProvider,
365
+ cursor: CursorProvider,
366
+ antigravity: AntigravityProvider,
367
+ windsurf: WindsurfProvider
368
+ };
369
+ __name(whichCommand, "whichCommand");
370
+ __name(getCliVersion, "getCliVersion");
371
+ __name(detectProvider, "detectProvider");
372
+ __name(detectAllProviders, "detectAllProviders");
373
+ __name(getActiveProvider, "getActiveProvider");
374
+ __name(hasProviderConfig, "hasProviderConfig");
375
+ __name(getProviderBranding, "getProviderBranding");
376
+ __name(detectCursorProject, "detectCursorProject");
377
+ __name(needsCursorRouterRegeneration, "needsCursorRouterRegeneration");
378
+ __name(detectWindsurfProject, "detectWindsurfProject");
379
+ __name(needsWindsurfRouterRegeneration, "needsWindsurfRouterRegeneration");
380
+ __name(detectAntigravity, "detectAntigravity");
381
+ __name(getGlobalContextPath, "getGlobalContextPath");
382
+ __name(getGlobalSettingsPath, "getGlobalSettingsPath");
383
+ __name(getSkillsPath, "getSkillsPath");
384
+ __name(getCommandsDir, "getCommandsDir");
385
+ __name(getProjectCommandsPath, "getProjectCommandsPath");
386
+ __name(selectProvider, "selectProvider");
387
+ ai_provider_default = {
388
+ Providers,
389
+ ClaudeProvider,
390
+ GeminiProvider,
391
+ CursorProvider,
392
+ AntigravityProvider,
393
+ WindsurfProvider,
394
+ detectProvider,
395
+ detectAllProviders,
396
+ detectAntigravity,
397
+ getActiveProvider,
398
+ hasProviderConfig,
399
+ getProviderBranding,
400
+ getGlobalContextPath,
401
+ getGlobalSettingsPath,
402
+ getSkillsPath,
403
+ getCommandsDir,
404
+ getProjectCommandsPath,
405
+ selectProvider,
406
+ detectCursorProject,
407
+ needsCursorRouterRegeneration,
408
+ detectWindsurfProject,
409
+ needsWindsurfRouterRegeneration
410
+ };
411
+ }
412
+ });
413
+
31
414
  // core/infrastructure/setup.ts
32
415
  var setup_exports = {};
33
416
  __export(setup_exports, {
34
417
  default: () => setup_default,
418
+ hasCursorProject: () => hasCursorProject,
419
+ hasWindsurfProject: () => hasWindsurfProject,
420
+ installAntigravitySkill: () => installAntigravitySkill,
421
+ installCursorProject: () => installCursorProject,
422
+ installWindsurfProject: () => installWindsurfProject,
423
+ needsAntigravityInstallation: () => needsAntigravityInstallation,
424
+ needsCursorRegeneration: () => needsCursorRegeneration,
425
+ needsWindsurfRegeneration: () => needsWindsurfRegeneration,
35
426
  run: () => run
36
427
  });
37
428
  module.exports = __toCommonJS(setup_exports);
38
429
  var import_child_process2 = require("child_process");
39
- var import_fs3 = __toESM(require("fs"));
430
+ var import_fs4 = __toESM(require("fs"));
40
431
  var import_path5 = __toESM(require("path"));
41
432
  var import_os4 = __toESM(require("os"));
42
433
 
43
434
  // core/infrastructure/command-installer.ts
44
435
  var import_promises = __toESM(require("fs/promises"));
45
- var import_path2 = __toESM(require("path"));
46
- var import_os = __toESM(require("os"));
436
+ var import_path3 = __toESM(require("path"));
437
+ var import_os2 = __toESM(require("os"));
47
438
 
48
439
  // core/utils/version.ts
49
440
  var import_fs = __toESM(require("fs"));
@@ -102,14 +493,14 @@ __name(isNotFoundError, "isNotFoundError");
102
493
  // core/infrastructure/command-installer.ts
103
494
  async function installDocs() {
104
495
  try {
105
- const docsDir = import_path2.default.join(import_os.default.homedir(), ".prjct-cli", "docs");
106
- const templateDocsDir = import_path2.default.join(getPackageRoot(), "templates/global/docs");
496
+ const docsDir = import_path3.default.join(import_os2.default.homedir(), ".prjct-cli", "docs");
497
+ const templateDocsDir = import_path3.default.join(getPackageRoot(), "templates/global/docs");
107
498
  await import_promises.default.mkdir(docsDir, { recursive: true });
108
499
  const docFiles = await import_promises.default.readdir(templateDocsDir);
109
500
  for (const file of docFiles) {
110
501
  if (file.endsWith(".md")) {
111
- const srcPath = import_path2.default.join(templateDocsDir, file);
112
- const destPath = import_path2.default.join(docsDir, file);
502
+ const srcPath = import_path3.default.join(templateDocsDir, file);
503
+ const destPath = import_path3.default.join(docsDir, file);
113
504
  const content = await import_promises.default.readFile(srcPath, "utf-8");
114
505
  await import_promises.default.writeFile(destPath, content, "utf-8");
115
506
  }
@@ -120,21 +511,32 @@ async function installDocs() {
120
511
  }
121
512
  }
122
513
  __name(installDocs, "installDocs");
123
- async function installGlobalConfig(claudeConfigPath, detectClaude) {
124
- const claudeDetected = await detectClaude();
125
- if (!claudeDetected) {
514
+ async function installGlobalConfig() {
515
+ const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
516
+ const activeProvider = aiProvider.getActiveProvider();
517
+ const providerName = activeProvider.name;
518
+ const detection = aiProvider.detectProvider(providerName);
519
+ if (!detection.installed && !activeProvider.configDir) {
126
520
  return {
127
521
  success: false,
128
- error: "Claude not detected",
522
+ error: `${activeProvider.displayName} not detected`,
129
523
  action: "skipped"
130
524
  };
131
525
  }
132
526
  try {
133
- const claudeDir = import_path2.default.join(import_os.default.homedir(), ".claude");
134
- await import_promises.default.mkdir(claudeDir, { recursive: true });
135
- const globalConfigPath = import_path2.default.join(claudeDir, "CLAUDE.md");
136
- const templatePath = import_path2.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
137
- const templateContent = await import_promises.default.readFile(templatePath, "utf-8");
527
+ await import_promises.default.mkdir(activeProvider.configDir, { recursive: true });
528
+ const globalConfigPath = import_path3.default.join(activeProvider.configDir, activeProvider.contextFile);
529
+ const templatePath = import_path3.default.join(getPackageRoot(), "templates", "global", activeProvider.contextFile);
530
+ let templateContent = "";
531
+ try {
532
+ templateContent = await import_promises.default.readFile(templatePath, "utf-8");
533
+ } catch (error) {
534
+ const fallbackTemplatePath = import_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
535
+ templateContent = await import_promises.default.readFile(fallbackTemplatePath, "utf-8");
536
+ if (providerName === "gemini") {
537
+ templateContent = templateContent.replace(/Claude/g, "Gemini");
538
+ }
539
+ }
138
540
  let existingContent = "";
139
541
  let fileExists = false;
140
542
  try {
@@ -202,15 +604,21 @@ var CommandInstaller = class {
202
604
  claudeConfigPath;
203
605
  templatesDir;
204
606
  constructor() {
205
- this.homeDir = import_os.default.homedir();
206
- this.claudeCommandsPath = import_path2.default.join(this.homeDir, ".claude", "commands", "p");
207
- this.claudeConfigPath = import_path2.default.join(this.homeDir, ".claude");
208
- this.templatesDir = import_path2.default.join(getPackageRoot(), "templates", "commands");
607
+ this.homeDir = import_os2.default.homedir();
608
+ const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
609
+ const activeProvider = aiProvider.getActiveProvider();
610
+ if (activeProvider.name === "gemini") {
611
+ this.claudeCommandsPath = import_path3.default.join(activeProvider.configDir, "commands");
612
+ } else {
613
+ this.claudeCommandsPath = import_path3.default.join(activeProvider.configDir, "commands", "p");
614
+ }
615
+ this.claudeConfigPath = activeProvider.configDir;
616
+ this.templatesDir = import_path3.default.join(getPackageRoot(), "templates", "commands");
209
617
  }
210
618
  /**
211
- * Detect if Claude is installed
619
+ * Detect if active provider is installed
212
620
  */
213
- async detectClaude() {
621
+ async detectActiveProvider() {
214
622
  try {
215
623
  await import_promises.default.access(this.claudeConfigPath);
216
624
  return true;
@@ -221,6 +629,12 @@ var CommandInstaller = class {
221
629
  throw error;
222
630
  }
223
631
  }
632
+ /**
633
+ * Detect if Claude is installed (legacy support)
634
+ */
635
+ async detectClaude() {
636
+ return this.detectActiveProvider();
637
+ }
224
638
  /**
225
639
  * Get list of command files to install
226
640
  */
@@ -253,14 +667,16 @@ var CommandInstaller = class {
253
667
  }
254
668
  }
255
669
  /**
256
- * Install commands to Claude
670
+ * Install commands to active AI agent
257
671
  */
258
672
  async installCommands() {
259
- const claudeDetected = await this.detectClaude();
260
- if (!claudeDetected) {
673
+ const providerDetected = await this.detectActiveProvider();
674
+ const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
675
+ const activeProvider = aiProvider.getActiveProvider();
676
+ if (!providerDetected) {
261
677
  return {
262
678
  success: false,
263
- error: "Claude not detected. Please install Claude Code or Claude Desktop first."
679
+ error: `${activeProvider.displayName} not detected. Please install it first.`
264
680
  };
265
681
  }
266
682
  try {
@@ -271,8 +687,8 @@ var CommandInstaller = class {
271
687
  const errors = [];
272
688
  for (const file of commandFiles) {
273
689
  try {
274
- const sourcePath = import_path2.default.join(this.templatesDir, file);
275
- const destPath = import_path2.default.join(this.claudeCommandsPath, file);
690
+ const sourcePath = import_path3.default.join(this.templatesDir, file);
691
+ const destPath = import_path3.default.join(this.claudeCommandsPath, file);
276
692
  const content = await import_promises.default.readFile(sourcePath, "utf-8");
277
693
  await import_promises.default.writeFile(destPath, content, "utf-8");
278
694
  installed.push(file.replace(".md", ""));
@@ -303,7 +719,7 @@ var CommandInstaller = class {
303
719
  const errors = [];
304
720
  for (const file of commandFiles) {
305
721
  try {
306
- const filePath = import_path2.default.join(this.claudeCommandsPath, file);
722
+ const filePath = import_path3.default.join(this.claudeCommandsPath, file);
307
723
  await import_promises.default.unlink(filePath);
308
724
  uninstalled.push(file.replace(".md", ""));
309
725
  } catch (error) {
@@ -388,7 +804,7 @@ var CommandInstaller = class {
388
804
  */
389
805
  async verifyTemplate(commandName) {
390
806
  try {
391
- const templatePath = import_path2.default.join(this.templatesDir, `${commandName}.md`);
807
+ const templatePath = import_path3.default.join(this.templatesDir, `${commandName}.md`);
392
808
  await import_promises.default.access(templatePath);
393
809
  return true;
394
810
  } catch (error) {
@@ -399,14 +815,17 @@ var CommandInstaller = class {
399
815
  }
400
816
  }
401
817
  /**
402
- * Install the p.md router to ~/.claude/commands/
818
+ * Install the router (p.md for Claude, p.toml for Gemini) to commands directory
403
819
  * This enables the "p. task" natural language trigger
404
- * Claude Code bug #2422 prevents subdirectory slash command discovery
405
820
  */
406
821
  async installRouter() {
822
+ const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
823
+ const activeProvider = aiProvider.getActiveProvider();
824
+ const routerFile = activeProvider.name === "gemini" ? "p.toml" : "p.md";
407
825
  try {
408
- const routerSource = import_path2.default.join(this.templatesDir, "p.md");
409
- const routerDest = import_path2.default.join(this.homeDir, ".claude", "commands", "p.md");
826
+ const routerSource = import_path3.default.join(this.templatesDir, routerFile);
827
+ const routerDest = import_path3.default.join(activeProvider.configDir, "commands", routerFile);
828
+ await import_promises.default.mkdir(import_path3.default.dirname(routerDest), { recursive: true });
410
829
  const content = await import_promises.default.readFile(routerSource, "utf-8");
411
830
  await import_promises.default.writeFile(routerDest, content, "utf-8");
412
831
  return true;
@@ -421,11 +840,11 @@ var CommandInstaller = class {
421
840
  * Sync commands - intelligent update that detects and removes orphans
422
841
  */
423
842
  async syncCommands() {
424
- const claudeDetected = await this.detectClaude();
425
- if (!claudeDetected) {
843
+ const providerDetected = await this.detectActiveProvider();
844
+ if (!providerDetected) {
426
845
  return {
427
846
  success: false,
428
- error: "Claude not detected",
847
+ error: "AI agent not detected",
429
848
  added: 0,
430
849
  updated: 0,
431
850
  removed: 0
@@ -455,8 +874,8 @@ var CommandInstaller = class {
455
874
  };
456
875
  for (const file of templateFiles) {
457
876
  try {
458
- const sourcePath = import_path2.default.join(this.templatesDir, file);
459
- const destPath = import_path2.default.join(this.claudeCommandsPath, file);
877
+ const sourcePath = import_path3.default.join(this.templatesDir, file);
878
+ const destPath = import_path3.default.join(this.claudeCommandsPath, file);
460
879
  const exists = installedFiles.includes(file);
461
880
  const content = await import_promises.default.readFile(sourcePath, "utf-8");
462
881
  await import_promises.default.writeFile(destPath, content, "utf-8");
@@ -481,10 +900,10 @@ var CommandInstaller = class {
481
900
  }
482
901
  }
483
902
  /**
484
- * Install or update global CLAUDE.md configuration
903
+ * Install or update global AI agent configuration (CLAUDE.md / GEMINI.md)
485
904
  */
486
905
  async installGlobalConfig() {
487
- return installGlobalConfig(this.claudeConfigPath, () => this.detectClaude());
906
+ return installGlobalConfig();
488
907
  }
489
908
  /**
490
909
  * Install documentation files to ~/.prjct-cli/docs/
@@ -498,8 +917,8 @@ var command_installer_default = commandInstaller;
498
917
 
499
918
  // core/infrastructure/editors-config.ts
500
919
  var import_promises2 = __toESM(require("fs/promises"));
501
- var import_path3 = __toESM(require("path"));
502
- var import_os2 = __toESM(require("os"));
920
+ var import_path4 = __toESM(require("path"));
921
+ var import_os3 = __toESM(require("os"));
503
922
  var EditorsConfig = class {
504
923
  static {
505
924
  __name(this, "EditorsConfig");
@@ -508,9 +927,9 @@ var EditorsConfig = class {
508
927
  configDir;
509
928
  configFile;
510
929
  constructor() {
511
- this.homeDir = import_os2.default.homedir();
512
- this.configDir = import_path3.default.join(this.homeDir, ".prjct-cli", "config");
513
- this.configFile = import_path3.default.join(this.configDir, "installed-editors.json");
930
+ this.homeDir = import_os3.default.homedir();
931
+ this.configDir = import_path4.default.join(this.homeDir, ".prjct-cli", "config");
932
+ this.configFile = import_path4.default.join(this.configDir, "installed-editors.json");
514
933
  }
515
934
  /**
516
935
  * Ensure config directory exists
@@ -629,119 +1048,8 @@ var EditorsConfig = class {
629
1048
  var editorsConfig = new EditorsConfig();
630
1049
  var editors_config_default = editorsConfig;
631
1050
 
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
-
744
1051
  // core/infrastructure/setup.ts
1052
+ init_ai_provider();
745
1053
  var GREEN = "\x1B[32m";
746
1054
  var YELLOW = "\x1B[33m";
747
1055
  var DIM = "\x1B[2m";
@@ -776,8 +1084,8 @@ async function run() {
776
1084
  commandsUpdated: 0,
777
1085
  configAction: null
778
1086
  };
779
- const providerNames = ["claude", "gemini"];
780
- for (const providerName of providerNames) {
1087
+ const cliProviderNames = ["claude", "gemini"];
1088
+ for (const providerName of cliProviderNames) {
781
1089
  const providerConfig = Providers[providerName];
782
1090
  const providerDetection = detection[providerName];
783
1091
  const providerResult = {
@@ -833,6 +1141,13 @@ async function run() {
833
1141
  }
834
1142
  results.providers.push(providerResult);
835
1143
  }
1144
+ const antigravityDetection = detectAntigravity();
1145
+ if (antigravityDetection.installed) {
1146
+ const antigravityResult = await installAntigravitySkill();
1147
+ if (antigravityResult.success) {
1148
+ console.log(` ${GREEN}\u2713${NC} Antigravity skill installed`);
1149
+ }
1150
+ }
836
1151
  await editors_config_default.saveConfig(VERSION, command_installer_default.getInstallPath(), selection.provider);
837
1152
  await migrateProjectsCliVersion();
838
1153
  for (const providerResult of results.providers) {
@@ -847,9 +1162,9 @@ async function installGeminiRouter() {
847
1162
  const geminiCommandsDir = import_path5.default.join(import_os4.default.homedir(), ".gemini", "commands");
848
1163
  const routerSource = import_path5.default.join(getPackageRoot(), "templates", "commands", "p.toml");
849
1164
  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);
1165
+ import_fs4.default.mkdirSync(geminiCommandsDir, { recursive: true });
1166
+ if (import_fs4.default.existsSync(routerSource)) {
1167
+ import_fs4.default.copyFileSync(routerSource, routerDest);
853
1168
  return true;
854
1169
  }
855
1170
  return false;
@@ -864,12 +1179,12 @@ async function installGeminiGlobalConfig() {
864
1179
  const geminiDir = import_path5.default.join(import_os4.default.homedir(), ".gemini");
865
1180
  const globalConfigPath = import_path5.default.join(geminiDir, "GEMINI.md");
866
1181
  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");
1182
+ import_fs4.default.mkdirSync(geminiDir, { recursive: true });
1183
+ const templateContent = import_fs4.default.readFileSync(templatePath, "utf-8");
869
1184
  let existingContent = "";
870
1185
  let fileExists = false;
871
1186
  try {
872
- existingContent = import_fs3.default.readFileSync(globalConfigPath, "utf-8");
1187
+ existingContent = import_fs4.default.readFileSync(globalConfigPath, "utf-8");
873
1188
  fileExists = true;
874
1189
  } catch (error) {
875
1190
  if (isNotFoundError(error)) {
@@ -879,7 +1194,7 @@ async function installGeminiGlobalConfig() {
879
1194
  }
880
1195
  }
881
1196
  if (!fileExists) {
882
- import_fs3.default.writeFileSync(globalConfigPath, templateContent, "utf-8");
1197
+ import_fs4.default.writeFileSync(globalConfigPath, templateContent, "utf-8");
883
1198
  return { success: true, action: "created" };
884
1199
  }
885
1200
  const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
@@ -887,7 +1202,7 @@ async function installGeminiGlobalConfig() {
887
1202
  const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
888
1203
  if (!hasMarkers) {
889
1204
  const updatedContent2 = existingContent + "\n\n" + templateContent;
890
- import_fs3.default.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
1205
+ import_fs4.default.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
891
1206
  return { success: true, action: "appended" };
892
1207
  }
893
1208
  const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
@@ -899,7 +1214,7 @@ async function installGeminiGlobalConfig() {
899
1214
  templateContent.indexOf(endMarker) + endMarker.length
900
1215
  );
901
1216
  const updatedContent = beforeMarker + prjctSection + afterMarker;
902
- import_fs3.default.writeFileSync(globalConfigPath, updatedContent, "utf-8");
1217
+ import_fs4.default.writeFileSync(globalConfigPath, updatedContent, "utf-8");
903
1218
  return { success: true, action: "updated" };
904
1219
  } catch (error) {
905
1220
  console.error(`Gemini config warning: ${error.message}`);
@@ -907,25 +1222,219 @@ async function installGeminiGlobalConfig() {
907
1222
  }
908
1223
  }
909
1224
  __name(installGeminiGlobalConfig, "installGeminiGlobalConfig");
1225
+ async function installAntigravitySkill() {
1226
+ try {
1227
+ const antigravitySkillsDir = import_path5.default.join(import_os4.default.homedir(), ".gemini", "antigravity", "skills");
1228
+ const prjctSkillDir = import_path5.default.join(antigravitySkillsDir, "prjct");
1229
+ const skillMdPath = import_path5.default.join(prjctSkillDir, "SKILL.md");
1230
+ const templatePath = import_path5.default.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
1231
+ import_fs4.default.mkdirSync(prjctSkillDir, { recursive: true });
1232
+ const fileExists = import_fs4.default.existsSync(skillMdPath);
1233
+ if (!import_fs4.default.existsSync(templatePath)) {
1234
+ console.error("Antigravity SKILL.md template not found");
1235
+ return { success: false, action: null };
1236
+ }
1237
+ const templateContent = import_fs4.default.readFileSync(templatePath, "utf-8");
1238
+ import_fs4.default.writeFileSync(skillMdPath, templateContent, "utf-8");
1239
+ return { success: true, action: fileExists ? "updated" : "created" };
1240
+ } catch (error) {
1241
+ console.error(`Antigravity skill warning: ${error.message}`);
1242
+ return { success: false, action: null };
1243
+ }
1244
+ }
1245
+ __name(installAntigravitySkill, "installAntigravitySkill");
1246
+ function needsAntigravityInstallation() {
1247
+ const detection = detectAntigravity();
1248
+ return detection.installed && !detection.skillInstalled;
1249
+ }
1250
+ __name(needsAntigravityInstallation, "needsAntigravityInstallation");
1251
+ async function installCursorProject(projectRoot) {
1252
+ const result = {
1253
+ success: false,
1254
+ rulesCreated: false,
1255
+ commandsCreated: false,
1256
+ gitignoreUpdated: false
1257
+ };
1258
+ try {
1259
+ const cursorDir = import_path5.default.join(projectRoot, ".cursor");
1260
+ const rulesDir = import_path5.default.join(cursorDir, "rules");
1261
+ const commandsDir = import_path5.default.join(cursorDir, "commands");
1262
+ const routerMdcDest = import_path5.default.join(rulesDir, "prjct.mdc");
1263
+ const routerMdcSource = import_path5.default.join(getPackageRoot(), "templates", "cursor", "router.mdc");
1264
+ const cursorCommandsSource = import_path5.default.join(getPackageRoot(), "templates", "cursor", "commands");
1265
+ import_fs4.default.mkdirSync(rulesDir, { recursive: true });
1266
+ import_fs4.default.mkdirSync(commandsDir, { recursive: true });
1267
+ if (import_fs4.default.existsSync(routerMdcSource)) {
1268
+ import_fs4.default.copyFileSync(routerMdcSource, routerMdcDest);
1269
+ result.rulesCreated = true;
1270
+ }
1271
+ if (import_fs4.default.existsSync(cursorCommandsSource)) {
1272
+ const commandFiles = import_fs4.default.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
1273
+ for (const file of commandFiles) {
1274
+ const src = import_path5.default.join(cursorCommandsSource, file);
1275
+ const dest = import_path5.default.join(commandsDir, file);
1276
+ import_fs4.default.copyFileSync(src, dest);
1277
+ }
1278
+ result.commandsCreated = commandFiles.length > 0;
1279
+ }
1280
+ result.gitignoreUpdated = await addCursorToGitignore(projectRoot);
1281
+ result.success = result.rulesCreated || result.commandsCreated;
1282
+ return result;
1283
+ } catch (error) {
1284
+ console.error(`Cursor installation warning: ${error.message}`);
1285
+ return result;
1286
+ }
1287
+ }
1288
+ __name(installCursorProject, "installCursorProject");
1289
+ async function addCursorToGitignore(projectRoot) {
1290
+ try {
1291
+ const gitignorePath = import_path5.default.join(projectRoot, ".gitignore");
1292
+ const entriesToAdd = [
1293
+ "# prjct Cursor routers (regenerated per-developer)",
1294
+ ".cursor/rules/prjct.mdc",
1295
+ ".cursor/commands/sync.md",
1296
+ ".cursor/commands/task.md",
1297
+ ".cursor/commands/done.md",
1298
+ ".cursor/commands/ship.md",
1299
+ ".cursor/commands/bug.md",
1300
+ ".cursor/commands/pause.md",
1301
+ ".cursor/commands/resume.md"
1302
+ ];
1303
+ let content = "";
1304
+ let fileExists = false;
1305
+ try {
1306
+ content = import_fs4.default.readFileSync(gitignorePath, "utf-8");
1307
+ fileExists = true;
1308
+ } catch (error) {
1309
+ if (!isNotFoundError(error)) {
1310
+ throw error;
1311
+ }
1312
+ }
1313
+ if (content.includes(".cursor/rules/prjct.mdc")) {
1314
+ return false;
1315
+ }
1316
+ const newContent = fileExists ? content.trimEnd() + "\n\n" + entriesToAdd.join("\n") + "\n" : entriesToAdd.join("\n") + "\n";
1317
+ import_fs4.default.writeFileSync(gitignorePath, newContent, "utf-8");
1318
+ return true;
1319
+ } catch (error) {
1320
+ console.error(`Gitignore update warning: ${error.message}`);
1321
+ return false;
1322
+ }
1323
+ }
1324
+ __name(addCursorToGitignore, "addCursorToGitignore");
1325
+ function hasCursorProject(projectRoot) {
1326
+ return import_fs4.default.existsSync(import_path5.default.join(projectRoot, ".cursor"));
1327
+ }
1328
+ __name(hasCursorProject, "hasCursorProject");
1329
+ function needsCursorRegeneration(projectRoot) {
1330
+ const cursorDir = import_path5.default.join(projectRoot, ".cursor");
1331
+ const routerPath = import_path5.default.join(cursorDir, "rules", "prjct.mdc");
1332
+ return import_fs4.default.existsSync(cursorDir) && !import_fs4.default.existsSync(routerPath);
1333
+ }
1334
+ __name(needsCursorRegeneration, "needsCursorRegeneration");
1335
+ async function installWindsurfProject(projectRoot) {
1336
+ const result = {
1337
+ success: false,
1338
+ rulesCreated: false,
1339
+ workflowsCreated: false,
1340
+ gitignoreUpdated: false
1341
+ };
1342
+ try {
1343
+ const windsurfDir = import_path5.default.join(projectRoot, ".windsurf");
1344
+ const rulesDir = import_path5.default.join(windsurfDir, "rules");
1345
+ const workflowsDir = import_path5.default.join(windsurfDir, "workflows");
1346
+ const routerDest = import_path5.default.join(rulesDir, "prjct.md");
1347
+ const routerSource = import_path5.default.join(getPackageRoot(), "templates", "windsurf", "router.md");
1348
+ const windsurfWorkflowsSource = import_path5.default.join(getPackageRoot(), "templates", "windsurf", "workflows");
1349
+ import_fs4.default.mkdirSync(rulesDir, { recursive: true });
1350
+ import_fs4.default.mkdirSync(workflowsDir, { recursive: true });
1351
+ if (import_fs4.default.existsSync(routerSource)) {
1352
+ import_fs4.default.copyFileSync(routerSource, routerDest);
1353
+ result.rulesCreated = true;
1354
+ }
1355
+ if (import_fs4.default.existsSync(windsurfWorkflowsSource)) {
1356
+ const workflowFiles = import_fs4.default.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
1357
+ for (const file of workflowFiles) {
1358
+ const src = import_path5.default.join(windsurfWorkflowsSource, file);
1359
+ const dest = import_path5.default.join(workflowsDir, file);
1360
+ import_fs4.default.copyFileSync(src, dest);
1361
+ }
1362
+ result.workflowsCreated = workflowFiles.length > 0;
1363
+ }
1364
+ result.gitignoreUpdated = await addWindsurfToGitignore(projectRoot);
1365
+ result.success = result.rulesCreated || result.workflowsCreated;
1366
+ return result;
1367
+ } catch (error) {
1368
+ console.error(`Windsurf installation warning: ${error.message}`);
1369
+ return result;
1370
+ }
1371
+ }
1372
+ __name(installWindsurfProject, "installWindsurfProject");
1373
+ async function addWindsurfToGitignore(projectRoot) {
1374
+ try {
1375
+ const gitignorePath = import_path5.default.join(projectRoot, ".gitignore");
1376
+ const entriesToAdd = [
1377
+ "# prjct Windsurf routers (regenerated per-developer)",
1378
+ ".windsurf/rules/prjct.md",
1379
+ ".windsurf/workflows/sync.md",
1380
+ ".windsurf/workflows/task.md",
1381
+ ".windsurf/workflows/done.md",
1382
+ ".windsurf/workflows/ship.md",
1383
+ ".windsurf/workflows/bug.md",
1384
+ ".windsurf/workflows/pause.md",
1385
+ ".windsurf/workflows/resume.md"
1386
+ ];
1387
+ let content = "";
1388
+ let fileExists = false;
1389
+ try {
1390
+ content = import_fs4.default.readFileSync(gitignorePath, "utf-8");
1391
+ fileExists = true;
1392
+ } catch (error) {
1393
+ if (!isNotFoundError(error)) {
1394
+ throw error;
1395
+ }
1396
+ }
1397
+ if (content.includes(".windsurf/rules/prjct.md")) {
1398
+ return false;
1399
+ }
1400
+ const newContent = fileExists ? content.trimEnd() + "\n\n" + entriesToAdd.join("\n") + "\n" : entriesToAdd.join("\n") + "\n";
1401
+ import_fs4.default.writeFileSync(gitignorePath, newContent, "utf-8");
1402
+ return true;
1403
+ } catch (error) {
1404
+ console.error(`Gitignore update warning: ${error.message}`);
1405
+ return false;
1406
+ }
1407
+ }
1408
+ __name(addWindsurfToGitignore, "addWindsurfToGitignore");
1409
+ function hasWindsurfProject(projectRoot) {
1410
+ return import_fs4.default.existsSync(import_path5.default.join(projectRoot, ".windsurf"));
1411
+ }
1412
+ __name(hasWindsurfProject, "hasWindsurfProject");
1413
+ function needsWindsurfRegeneration(projectRoot) {
1414
+ const windsurfDir = import_path5.default.join(projectRoot, ".windsurf");
1415
+ const routerPath = import_path5.default.join(windsurfDir, "rules", "prjct.md");
1416
+ return import_fs4.default.existsSync(windsurfDir) && !import_fs4.default.existsSync(routerPath);
1417
+ }
1418
+ __name(needsWindsurfRegeneration, "needsWindsurfRegeneration");
910
1419
  async function migrateProjectsCliVersion() {
911
1420
  try {
912
1421
  const projectsDir = import_path5.default.join(import_os4.default.homedir(), ".prjct-cli", "projects");
913
- if (!import_fs3.default.existsSync(projectsDir)) {
1422
+ if (!import_fs4.default.existsSync(projectsDir)) {
914
1423
  return;
915
1424
  }
916
- const projectDirs = import_fs3.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
1425
+ const projectDirs = import_fs4.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
917
1426
  let migrated = 0;
918
1427
  for (const projectId of projectDirs) {
919
1428
  const projectJsonPath = import_path5.default.join(projectsDir, projectId, "project.json");
920
- if (!import_fs3.default.existsSync(projectJsonPath)) {
1429
+ if (!import_fs4.default.existsSync(projectJsonPath)) {
921
1430
  continue;
922
1431
  }
923
1432
  try {
924
- const content = import_fs3.default.readFileSync(projectJsonPath, "utf8");
1433
+ const content = import_fs4.default.readFileSync(projectJsonPath, "utf8");
925
1434
  const project = JSON.parse(content);
926
1435
  if (project.cliVersion !== VERSION) {
927
1436
  project.cliVersion = VERSION;
928
- import_fs3.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
1437
+ import_fs4.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
929
1438
  migrated++;
930
1439
  }
931
1440
  } catch (error) {
@@ -946,9 +1455,9 @@ async function migrateProjectsCliVersion() {
946
1455
  __name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
947
1456
  function ensureStatusLineSettings(settingsPath, statusLinePath) {
948
1457
  let settings = {};
949
- if (import_fs3.default.existsSync(settingsPath)) {
1458
+ if (import_fs4.default.existsSync(settingsPath)) {
950
1459
  try {
951
- settings = JSON.parse(import_fs3.default.readFileSync(settingsPath, "utf8"));
1460
+ settings = JSON.parse(import_fs4.default.readFileSync(settingsPath, "utf8"));
952
1461
  } catch (error) {
953
1462
  if (!(error instanceof SyntaxError)) {
954
1463
  throw error;
@@ -956,7 +1465,7 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
956
1465
  }
957
1466
  }
958
1467
  settings.statusLine = { type: "command", command: statusLinePath };
959
- import_fs3.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
1468
+ import_fs4.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
960
1469
  }
961
1470
  __name(ensureStatusLineSettings, "ensureStatusLineSettings");
962
1471
  async function installStatusLine() {
@@ -976,23 +1485,23 @@ async function installStatusLine() {
976
1485
  const sourceLibDir = import_path5.default.join(assetsDir, "lib");
977
1486
  const sourceComponentsDir = import_path5.default.join(assetsDir, "components");
978
1487
  const sourceConfigPath = import_path5.default.join(assetsDir, "default-config.json");
979
- if (!import_fs3.default.existsSync(claudeDir)) {
980
- import_fs3.default.mkdirSync(claudeDir, { recursive: true });
1488
+ if (!import_fs4.default.existsSync(claudeDir)) {
1489
+ import_fs4.default.mkdirSync(claudeDir, { recursive: true });
981
1490
  }
982
- if (!import_fs3.default.existsSync(prjctStatusLineDir)) {
983
- import_fs3.default.mkdirSync(prjctStatusLineDir, { recursive: true });
1491
+ if (!import_fs4.default.existsSync(prjctStatusLineDir)) {
1492
+ import_fs4.default.mkdirSync(prjctStatusLineDir, { recursive: true });
984
1493
  }
985
- if (!import_fs3.default.existsSync(prjctThemesDir)) {
986
- import_fs3.default.mkdirSync(prjctThemesDir, { recursive: true });
1494
+ if (!import_fs4.default.existsSync(prjctThemesDir)) {
1495
+ import_fs4.default.mkdirSync(prjctThemesDir, { recursive: true });
987
1496
  }
988
- if (!import_fs3.default.existsSync(prjctLibDir)) {
989
- import_fs3.default.mkdirSync(prjctLibDir, { recursive: true });
1497
+ if (!import_fs4.default.existsSync(prjctLibDir)) {
1498
+ import_fs4.default.mkdirSync(prjctLibDir, { recursive: true });
990
1499
  }
991
- if (!import_fs3.default.existsSync(prjctComponentsDir)) {
992
- import_fs3.default.mkdirSync(prjctComponentsDir, { recursive: true });
1500
+ if (!import_fs4.default.existsSync(prjctComponentsDir)) {
1501
+ import_fs4.default.mkdirSync(prjctComponentsDir, { recursive: true });
993
1502
  }
994
- if (import_fs3.default.existsSync(prjctStatusLinePath)) {
995
- const existingContent = import_fs3.default.readFileSync(prjctStatusLinePath, "utf8");
1503
+ if (import_fs4.default.existsSync(prjctStatusLinePath)) {
1504
+ const existingContent = import_fs4.default.readFileSync(prjctStatusLinePath, "utf8");
996
1505
  if (existingContent.includes("CLI_VERSION=")) {
997
1506
  const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
998
1507
  if (versionMatch && versionMatch[1] !== VERSION) {
@@ -1000,7 +1509,7 @@ async function installStatusLine() {
1000
1509
  /CLI_VERSION="[^"]*"/,
1001
1510
  `CLI_VERSION="${VERSION}"`
1002
1511
  );
1003
- import_fs3.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
1512
+ import_fs4.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
1004
1513
  }
1005
1514
  installStatusLineModules(sourceLibDir, prjctLibDir);
1006
1515
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
@@ -1009,25 +1518,25 @@ async function installStatusLine() {
1009
1518
  return;
1010
1519
  }
1011
1520
  }
1012
- if (import_fs3.default.existsSync(sourceScript)) {
1013
- let scriptContent = import_fs3.default.readFileSync(sourceScript, "utf8");
1521
+ if (import_fs4.default.existsSync(sourceScript)) {
1522
+ let scriptContent = import_fs4.default.readFileSync(sourceScript, "utf8");
1014
1523
  scriptContent = scriptContent.replace(
1015
1524
  /CLI_VERSION="[^"]*"/,
1016
1525
  `CLI_VERSION="${VERSION}"`
1017
1526
  );
1018
- import_fs3.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
1527
+ import_fs4.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
1019
1528
  installStatusLineModules(sourceLibDir, prjctLibDir);
1020
1529
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
1021
- if (import_fs3.default.existsSync(sourceThemeDir)) {
1022
- const themes = import_fs3.default.readdirSync(sourceThemeDir);
1530
+ if (import_fs4.default.existsSync(sourceThemeDir)) {
1531
+ const themes = import_fs4.default.readdirSync(sourceThemeDir);
1023
1532
  for (const theme of themes) {
1024
1533
  const src = import_path5.default.join(sourceThemeDir, theme);
1025
1534
  const dest = import_path5.default.join(prjctThemesDir, theme);
1026
- import_fs3.default.copyFileSync(src, dest);
1535
+ import_fs4.default.copyFileSync(src, dest);
1027
1536
  }
1028
1537
  }
1029
- if (!import_fs3.default.existsSync(prjctConfigPath) && import_fs3.default.existsSync(sourceConfigPath)) {
1030
- import_fs3.default.copyFileSync(sourceConfigPath, prjctConfigPath);
1538
+ if (!import_fs4.default.existsSync(prjctConfigPath) && import_fs4.default.existsSync(sourceConfigPath)) {
1539
+ import_fs4.default.copyFileSync(sourceConfigPath, prjctConfigPath);
1031
1540
  }
1032
1541
  } else {
1033
1542
  const scriptContent = `#!/bin/bash
@@ -1062,7 +1571,7 @@ if [ -f "$CONFIG" ]; then
1062
1571
  fi
1063
1572
  echo "prjct"
1064
1573
  `;
1065
- import_fs3.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
1574
+ import_fs4.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
1066
1575
  }
1067
1576
  ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
1068
1577
  ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
@@ -1074,38 +1583,38 @@ echo "prjct"
1074
1583
  }
1075
1584
  __name(installStatusLine, "installStatusLine");
1076
1585
  function installStatusLineModules(sourceDir, destDir) {
1077
- if (!import_fs3.default.existsSync(sourceDir)) {
1586
+ if (!import_fs4.default.existsSync(sourceDir)) {
1078
1587
  return;
1079
1588
  }
1080
- const files = import_fs3.default.readdirSync(sourceDir);
1589
+ const files = import_fs4.default.readdirSync(sourceDir);
1081
1590
  for (const file of files) {
1082
1591
  if (file.endsWith(".sh")) {
1083
1592
  const src = import_path5.default.join(sourceDir, file);
1084
1593
  const dest = import_path5.default.join(destDir, file);
1085
- import_fs3.default.copyFileSync(src, dest);
1086
- import_fs3.default.chmodSync(dest, 493);
1594
+ import_fs4.default.copyFileSync(src, dest);
1595
+ import_fs4.default.chmodSync(dest, 493);
1087
1596
  }
1088
1597
  }
1089
1598
  }
1090
1599
  __name(installStatusLineModules, "installStatusLineModules");
1091
1600
  function ensureStatusLineSymlink(linkPath, targetPath) {
1092
1601
  try {
1093
- if (import_fs3.default.existsSync(linkPath)) {
1094
- const stats = import_fs3.default.lstatSync(linkPath);
1602
+ if (import_fs4.default.existsSync(linkPath)) {
1603
+ const stats = import_fs4.default.lstatSync(linkPath);
1095
1604
  if (stats.isSymbolicLink()) {
1096
- const existingTarget = import_fs3.default.readlinkSync(linkPath);
1605
+ const existingTarget = import_fs4.default.readlinkSync(linkPath);
1097
1606
  if (existingTarget === targetPath) {
1098
1607
  return;
1099
1608
  }
1100
1609
  }
1101
- import_fs3.default.unlinkSync(linkPath);
1610
+ import_fs4.default.unlinkSync(linkPath);
1102
1611
  }
1103
- import_fs3.default.symlinkSync(targetPath, linkPath);
1612
+ import_fs4.default.symlinkSync(targetPath, linkPath);
1104
1613
  } catch (error) {
1105
1614
  try {
1106
- if (import_fs3.default.existsSync(targetPath)) {
1107
- import_fs3.default.copyFileSync(targetPath, linkPath);
1108
- import_fs3.default.chmodSync(linkPath, 493);
1615
+ if (import_fs4.default.existsSync(targetPath)) {
1616
+ import_fs4.default.copyFileSync(targetPath, linkPath);
1617
+ import_fs4.default.chmodSync(linkPath, 493);
1109
1618
  }
1110
1619
  } catch (copyError) {
1111
1620
  if (!isNotFoundError(copyError)) {
@@ -1150,5 +1659,13 @@ if (isDirectRun) {
1150
1659
  }
1151
1660
  // Annotate the CommonJS export names for ESM import in node:
1152
1661
  0 && (module.exports = {
1662
+ hasCursorProject,
1663
+ hasWindsurfProject,
1664
+ installAntigravitySkill,
1665
+ installCursorProject,
1666
+ installWindsurfProject,
1667
+ needsAntigravityInstallation,
1668
+ needsCursorRegeneration,
1669
+ needsWindsurfRegeneration,
1153
1670
  run
1154
1671
  });