prjct-cli 0.45.0 → 0.45.4

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 (207) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/bin/prjct.ts +117 -10
  3. package/core/__tests__/agentic/memory-system.test.ts +39 -26
  4. package/core/__tests__/agentic/plan-mode.test.ts +64 -46
  5. package/core/__tests__/agentic/prompt-builder.test.ts +14 -14
  6. package/core/__tests__/services/project-index.test.ts +353 -0
  7. package/core/__tests__/types/fs.test.ts +3 -3
  8. package/core/__tests__/utils/date-helper.test.ts +10 -10
  9. package/core/__tests__/utils/output.test.ts +9 -6
  10. package/core/__tests__/utils/project-commands.test.ts +5 -6
  11. package/core/agentic/agent-router.ts +9 -10
  12. package/core/agentic/chain-of-thought.ts +16 -4
  13. package/core/agentic/command-executor.ts +66 -40
  14. package/core/agentic/context-builder.ts +8 -5
  15. package/core/agentic/ground-truth.ts +15 -9
  16. package/core/agentic/index.ts +145 -152
  17. package/core/agentic/loop-detector.ts +40 -11
  18. package/core/agentic/memory-system.ts +98 -35
  19. package/core/agentic/orchestrator-executor.ts +135 -71
  20. package/core/agentic/plan-mode.ts +46 -16
  21. package/core/agentic/prompt-builder.ts +108 -42
  22. package/core/agentic/services.ts +10 -9
  23. package/core/agentic/skill-loader.ts +9 -15
  24. package/core/agentic/smart-context.ts +129 -79
  25. package/core/agentic/template-executor.ts +13 -12
  26. package/core/agentic/template-loader.ts +7 -4
  27. package/core/agentic/tool-registry.ts +16 -13
  28. package/core/agents/index.ts +1 -1
  29. package/core/agents/performance.ts +10 -27
  30. package/core/ai-tools/formatters.ts +8 -6
  31. package/core/ai-tools/generator.ts +4 -4
  32. package/core/ai-tools/index.ts +1 -1
  33. package/core/ai-tools/registry.ts +21 -11
  34. package/core/bus/bus.ts +23 -16
  35. package/core/bus/index.ts +2 -2
  36. package/core/cli/linear.ts +3 -5
  37. package/core/cli/start.ts +28 -25
  38. package/core/commands/analysis.ts +58 -39
  39. package/core/commands/analytics.ts +52 -44
  40. package/core/commands/base.ts +15 -13
  41. package/core/commands/cleanup.ts +6 -13
  42. package/core/commands/command-data.ts +28 -4
  43. package/core/commands/commands.ts +57 -24
  44. package/core/commands/context.ts +4 -4
  45. package/core/commands/design.ts +3 -10
  46. package/core/commands/index.ts +5 -8
  47. package/core/commands/maintenance.ts +7 -4
  48. package/core/commands/planning.ts +179 -56
  49. package/core/commands/register.ts +13 -9
  50. package/core/commands/registry.ts +15 -14
  51. package/core/commands/setup.ts +26 -14
  52. package/core/commands/shipping.ts +11 -16
  53. package/core/commands/snapshots.ts +16 -32
  54. package/core/commands/uninstall.ts +541 -0
  55. package/core/commands/workflow.ts +24 -28
  56. package/core/constants/index.ts +10 -22
  57. package/core/context/generator.ts +82 -33
  58. package/core/context-tools/files-tool.ts +18 -19
  59. package/core/context-tools/imports-tool.ts +13 -33
  60. package/core/context-tools/index.ts +29 -54
  61. package/core/context-tools/recent-tool.ts +16 -22
  62. package/core/context-tools/signatures-tool.ts +17 -26
  63. package/core/context-tools/summary-tool.ts +20 -22
  64. package/core/context-tools/token-counter.ts +25 -20
  65. package/core/context-tools/types.ts +5 -5
  66. package/core/domain/agent-generator.ts +7 -5
  67. package/core/domain/agent-loader.ts +2 -2
  68. package/core/domain/analyzer.ts +19 -16
  69. package/core/domain/architecture-generator.ts +6 -3
  70. package/core/domain/context-estimator.ts +3 -4
  71. package/core/domain/snapshot-manager.ts +25 -22
  72. package/core/domain/task-stack.ts +24 -14
  73. package/core/errors.ts +1 -1
  74. package/core/events/events.ts +2 -4
  75. package/core/events/index.ts +1 -2
  76. package/core/index.ts +28 -16
  77. package/core/infrastructure/agent-detector.ts +3 -3
  78. package/core/infrastructure/ai-provider.ts +23 -20
  79. package/core/infrastructure/author-detector.ts +16 -10
  80. package/core/infrastructure/capability-installer.ts +2 -2
  81. package/core/infrastructure/claude-agent.ts +6 -6
  82. package/core/infrastructure/command-installer.ts +22 -17
  83. package/core/infrastructure/config-manager.ts +18 -14
  84. package/core/infrastructure/editors-config.ts +8 -4
  85. package/core/infrastructure/path-manager.ts +8 -6
  86. package/core/infrastructure/permission-manager.ts +20 -17
  87. package/core/infrastructure/setup.ts +42 -38
  88. package/core/infrastructure/update-checker.ts +5 -5
  89. package/core/integrations/issue-tracker/enricher.ts +8 -19
  90. package/core/integrations/issue-tracker/index.ts +2 -2
  91. package/core/integrations/issue-tracker/manager.ts +15 -15
  92. package/core/integrations/issue-tracker/types.ts +5 -22
  93. package/core/integrations/jira/client.ts +67 -59
  94. package/core/integrations/jira/index.ts +11 -14
  95. package/core/integrations/jira/mcp-adapter.ts +5 -10
  96. package/core/integrations/jira/service.ts +10 -10
  97. package/core/integrations/linear/client.ts +27 -18
  98. package/core/integrations/linear/index.ts +9 -12
  99. package/core/integrations/linear/service.ts +11 -11
  100. package/core/integrations/linear/sync.ts +8 -8
  101. package/core/outcomes/analyzer.ts +5 -18
  102. package/core/outcomes/index.ts +2 -2
  103. package/core/outcomes/recorder.ts +3 -3
  104. package/core/plugin/builtin/webhook.ts +19 -15
  105. package/core/plugin/hooks.ts +29 -21
  106. package/core/plugin/index.ts +7 -7
  107. package/core/plugin/loader.ts +19 -19
  108. package/core/plugin/registry.ts +12 -23
  109. package/core/schemas/agents.ts +1 -1
  110. package/core/schemas/analysis.ts +1 -1
  111. package/core/schemas/enriched-task.ts +62 -49
  112. package/core/schemas/ideas.ts +13 -13
  113. package/core/schemas/index.ts +17 -27
  114. package/core/schemas/issues.ts +40 -25
  115. package/core/schemas/metrics.ts +25 -25
  116. package/core/schemas/outcomes.ts +70 -62
  117. package/core/schemas/permissions.ts +15 -12
  118. package/core/schemas/prd.ts +27 -14
  119. package/core/schemas/project.ts +3 -3
  120. package/core/schemas/roadmap.ts +47 -34
  121. package/core/schemas/schemas.ts +3 -4
  122. package/core/schemas/shipped.ts +3 -3
  123. package/core/schemas/state.ts +43 -29
  124. package/core/server/index.ts +5 -6
  125. package/core/server/routes-extended.ts +68 -72
  126. package/core/server/routes.ts +3 -3
  127. package/core/server/server.ts +31 -26
  128. package/core/services/agent-generator.ts +237 -0
  129. package/core/services/agent-service.ts +2 -2
  130. package/core/services/breakdown-service.ts +2 -4
  131. package/core/services/context-generator.ts +299 -0
  132. package/core/services/context-selector.ts +420 -0
  133. package/core/services/doctor-service.ts +426 -0
  134. package/core/services/file-categorizer.ts +448 -0
  135. package/core/services/file-scorer.ts +270 -0
  136. package/core/services/git-analyzer.ts +267 -0
  137. package/core/services/index.ts +27 -10
  138. package/core/services/memory-service.ts +3 -4
  139. package/core/services/project-index.ts +911 -0
  140. package/core/services/project-service.ts +4 -4
  141. package/core/services/skill-installer.ts +14 -17
  142. package/core/services/skill-lock.ts +3 -3
  143. package/core/services/skill-service.ts +12 -6
  144. package/core/services/stack-detector.ts +245 -0
  145. package/core/services/sync-service.ts +87 -345
  146. package/core/services/watch-service.ts +294 -0
  147. package/core/session/compaction.ts +23 -31
  148. package/core/session/index.ts +11 -5
  149. package/core/session/log-migration.ts +3 -3
  150. package/core/session/metrics.ts +19 -14
  151. package/core/session/session-log-manager.ts +12 -17
  152. package/core/session/task-session-manager.ts +25 -25
  153. package/core/session/utils.ts +1 -1
  154. package/core/storage/ideas-storage.ts +41 -57
  155. package/core/storage/index-storage.ts +514 -0
  156. package/core/storage/index.ts +41 -17
  157. package/core/storage/metrics-storage.ts +39 -34
  158. package/core/storage/queue-storage.ts +35 -45
  159. package/core/storage/shipped-storage.ts +17 -20
  160. package/core/storage/state-storage.ts +50 -30
  161. package/core/storage/storage-manager.ts +6 -6
  162. package/core/storage/storage.ts +18 -15
  163. package/core/sync/auth-config.ts +3 -3
  164. package/core/sync/index.ts +13 -19
  165. package/core/sync/oauth-handler.ts +3 -3
  166. package/core/sync/sync-client.ts +4 -9
  167. package/core/sync/sync-manager.ts +12 -14
  168. package/core/types/commands.ts +42 -7
  169. package/core/types/index.ts +284 -305
  170. package/core/types/integrations.ts +3 -3
  171. package/core/types/storage.ts +14 -14
  172. package/core/types/utils.ts +3 -3
  173. package/core/utils/agent-stream.ts +3 -1
  174. package/core/utils/animations.ts +14 -11
  175. package/core/utils/branding.ts +7 -7
  176. package/core/utils/cache.ts +1 -3
  177. package/core/utils/collection-filters.ts +3 -15
  178. package/core/utils/date-helper.ts +2 -7
  179. package/core/utils/file-helper.ts +13 -8
  180. package/core/utils/jsonl-helper.ts +13 -10
  181. package/core/utils/keychain.ts +4 -8
  182. package/core/utils/logger.ts +1 -1
  183. package/core/utils/next-steps.ts +3 -3
  184. package/core/utils/output.ts +58 -11
  185. package/core/utils/project-commands.ts +6 -6
  186. package/core/utils/project-credentials.ts +5 -12
  187. package/core/utils/runtime.ts +2 -2
  188. package/core/utils/session-helper.ts +3 -4
  189. package/core/utils/version.ts +3 -3
  190. package/core/wizard/index.ts +13 -0
  191. package/core/wizard/onboarding.ts +633 -0
  192. package/core/workflow/state-machine.ts +7 -7
  193. package/dist/bin/prjct.mjs +18755 -15574
  194. package/dist/core/infrastructure/command-installer.js +86 -79
  195. package/dist/core/infrastructure/editors-config.js +6 -6
  196. package/dist/core/infrastructure/setup.js +246 -225
  197. package/dist/core/utils/version.js +9 -9
  198. package/package.json +11 -12
  199. package/scripts/build.js +3 -3
  200. package/scripts/postinstall.js +2 -2
  201. package/templates/mcp-config.json +6 -1
  202. package/templates/permissions/permissive.jsonc +1 -1
  203. package/templates/permissions/strict.jsonc +5 -9
  204. package/templates/global/docs/agents.md +0 -88
  205. package/templates/global/docs/architecture.md +0 -103
  206. package/templates/global/docs/commands.md +0 -96
  207. package/templates/global/docs/validation.md +0 -95
@@ -60,7 +60,7 @@ __export(ai_provider_exports, {
60
60
  });
61
61
  function whichCommand(command) {
62
62
  try {
63
- const result = (0, import_child_process.execSync)(`which ${command}`, { stdio: "pipe", encoding: "utf-8" });
63
+ const result = (0, import_node_child_process.execSync)(`which ${command}`, { stdio: "pipe", encoding: "utf-8" });
64
64
  return result.trim();
65
65
  } catch {
66
66
  return null;
@@ -68,7 +68,7 @@ function whichCommand(command) {
68
68
  }
69
69
  function getCliVersion(command) {
70
70
  try {
71
- const result = (0, import_child_process.execSync)(`${command} --version`, { stdio: "pipe", encoding: "utf-8" });
71
+ const result = (0, import_node_child_process.execSync)(`${command} --version`, { stdio: "pipe", encoding: "utf-8" });
72
72
  const match = result.match(/\d+\.\d+\.\d+/);
73
73
  return match ? match[0] : result.trim();
74
74
  } catch {
@@ -115,7 +115,7 @@ function hasProviderConfig(provider) {
115
115
  if (!config.configDir) {
116
116
  return false;
117
117
  }
118
- return import_fs2.default.existsSync(config.configDir);
118
+ return import_node_fs2.default.existsSync(config.configDir);
119
119
  }
120
120
  function getProviderBranding(provider) {
121
121
  const commitFooter = `Generated with [p/](https://www.prjct.app/)`;
@@ -132,11 +132,11 @@ function getProviderBranding(provider) {
132
132
  };
133
133
  }
134
134
  function detectCursorProject(projectRoot) {
135
- const cursorDir = import_path2.default.join(projectRoot, ".cursor");
136
- const rulesDir = import_path2.default.join(cursorDir, "rules");
137
- const routerPath = import_path2.default.join(rulesDir, "prjct.mdc");
138
- const detected = import_fs2.default.existsSync(cursorDir);
139
- const routerInstalled = import_fs2.default.existsSync(routerPath);
135
+ const cursorDir = import_node_path2.default.join(projectRoot, ".cursor");
136
+ const rulesDir = import_node_path2.default.join(cursorDir, "rules");
137
+ const routerPath = import_node_path2.default.join(rulesDir, "prjct.mdc");
138
+ const detected = import_node_fs2.default.existsSync(cursorDir);
139
+ const routerInstalled = import_node_fs2.default.existsSync(routerPath);
140
140
  return {
141
141
  detected,
142
142
  routerInstalled,
@@ -148,11 +148,11 @@ function needsCursorRouterRegeneration(projectRoot) {
148
148
  return detection.detected && !detection.routerInstalled;
149
149
  }
150
150
  function detectWindsurfProject(projectRoot) {
151
- const windsurfDir = import_path2.default.join(projectRoot, ".windsurf");
152
- const rulesDir = import_path2.default.join(windsurfDir, "rules");
153
- const routerPath = import_path2.default.join(rulesDir, "prjct.md");
154
- const detected = import_fs2.default.existsSync(windsurfDir);
155
- const routerInstalled = import_fs2.default.existsSync(routerPath);
151
+ const windsurfDir = import_node_path2.default.join(projectRoot, ".windsurf");
152
+ const rulesDir = import_node_path2.default.join(windsurfDir, "rules");
153
+ const routerPath = import_node_path2.default.join(rulesDir, "prjct.md");
154
+ const detected = import_node_fs2.default.existsSync(windsurfDir);
155
+ const routerInstalled = import_node_fs2.default.existsSync(routerPath);
156
156
  return {
157
157
  detected,
158
158
  routerInstalled,
@@ -168,9 +168,9 @@ function detectAntigravity() {
168
168
  if (!configPath) {
169
169
  return { installed: false, skillInstalled: false };
170
170
  }
171
- const installed = import_fs2.default.existsSync(configPath);
172
- const skillPath = import_path2.default.join(configPath, "skills", "prjct", "SKILL.md");
173
- const skillInstalled = import_fs2.default.existsSync(skillPath);
171
+ const installed = import_node_fs2.default.existsSync(configPath);
172
+ const skillPath = import_node_path2.default.join(configPath, "skills", "prjct", "SKILL.md");
173
+ const skillInstalled = import_node_fs2.default.existsSync(skillPath);
174
174
  return {
175
175
  installed,
176
176
  skillInstalled,
@@ -182,14 +182,14 @@ function getGlobalContextPath(provider) {
182
182
  if (!config.configDir) {
183
183
  return null;
184
184
  }
185
- return import_path2.default.join(config.configDir, config.contextFile);
185
+ return import_node_path2.default.join(config.configDir, config.contextFile);
186
186
  }
187
187
  function getGlobalSettingsPath(provider) {
188
188
  const config = Providers[provider];
189
189
  if (!config.configDir || !config.settingsFile) {
190
190
  return null;
191
191
  }
192
- return import_path2.default.join(config.configDir, config.settingsFile);
192
+ return import_node_path2.default.join(config.configDir, config.settingsFile);
193
193
  }
194
194
  function getSkillsPath(provider) {
195
195
  return Providers[provider].skillsDir;
@@ -199,7 +199,7 @@ function getCommandsDir(provider) {
199
199
  }
200
200
  function getProjectCommandsPath(provider, projectRoot) {
201
201
  const config = Providers[provider];
202
- return import_path2.default.join(projectRoot, config.commandsDir);
202
+ return import_node_path2.default.join(projectRoot, config.commandsDir);
203
203
  }
204
204
  function selectProvider() {
205
205
  const detection = detectAllProviders();
@@ -233,21 +233,21 @@ function selectProvider() {
233
233
  detection
234
234
  };
235
235
  }
236
- var import_child_process, import_fs2, import_path2, import_os, ClaudeProvider, GeminiProvider, AntigravityProvider, CursorProvider, WindsurfProvider, Providers, ai_provider_default;
236
+ var import_node_child_process, import_node_fs2, import_node_os, import_node_path2, ClaudeProvider, GeminiProvider, AntigravityProvider, CursorProvider, WindsurfProvider, Providers, ai_provider_default;
237
237
  var init_ai_provider = __esm({
238
238
  "core/infrastructure/ai-provider.ts"() {
239
239
  "use strict";
240
- import_child_process = require("child_process");
241
- import_fs2 = __toESM(require("fs"));
242
- import_path2 = __toESM(require("path"));
243
- import_os = __toESM(require("os"));
240
+ import_node_child_process = require("node:child_process");
241
+ import_node_fs2 = __toESM(require("node:fs"));
242
+ import_node_os = __toESM(require("node:os"));
243
+ import_node_path2 = __toESM(require("node:path"));
244
244
  ClaudeProvider = {
245
245
  name: "claude",
246
246
  displayName: "Claude Code",
247
247
  cliCommand: "claude",
248
- configDir: import_path2.default.join(import_os.default.homedir(), ".claude"),
248
+ configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".claude"),
249
249
  contextFile: "CLAUDE.md",
250
- skillsDir: import_path2.default.join(import_os.default.homedir(), ".claude", "skills"),
250
+ skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".claude", "skills"),
251
251
  commandsDir: ".claude/commands",
252
252
  commandFormat: "md",
253
253
  settingsFile: "settings.json",
@@ -260,9 +260,9 @@ var init_ai_provider = __esm({
260
260
  name: "gemini",
261
261
  displayName: "Gemini CLI",
262
262
  cliCommand: "gemini",
263
- configDir: import_path2.default.join(import_os.default.homedir(), ".gemini"),
263
+ configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini"),
264
264
  contextFile: "GEMINI.md",
265
- skillsDir: import_path2.default.join(import_os.default.homedir(), ".gemini", "skills"),
265
+ skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "skills"),
266
266
  commandsDir: ".gemini/commands",
267
267
  commandFormat: "toml",
268
268
  settingsFile: "settings.json",
@@ -276,9 +276,9 @@ var init_ai_provider = __esm({
276
276
  displayName: "Google Antigravity",
277
277
  cliCommand: null,
278
278
  // Not a CLI command, but a platform/app
279
- configDir: import_path2.default.join(import_os.default.homedir(), ".gemini", "antigravity"),
279
+ configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "antigravity"),
280
280
  contextFile: "ANTIGRAVITY.md",
281
- skillsDir: import_path2.default.join(import_os.default.homedir(), ".gemini", "antigravity", "global_skills"),
281
+ skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "antigravity", "global_skills"),
282
282
  commandsDir: ".agent/skills",
283
283
  // Antigravity uses .agent/skills in projects
284
284
  commandFormat: "md",
@@ -404,19 +404,20 @@ __export(setup_exports, {
404
404
  run: () => run
405
405
  });
406
406
  module.exports = __toCommonJS(setup_exports);
407
- var import_child_process2 = require("child_process");
408
- var import_fs4 = __toESM(require("fs"));
409
- var import_path5 = __toESM(require("path"));
410
- var import_os4 = __toESM(require("os"));
407
+ var import_node_child_process2 = require("node:child_process");
408
+ var import_node_fs3 = __toESM(require("node:fs"));
409
+ var import_node_os4 = __toESM(require("node:os"));
410
+ var import_node_path5 = __toESM(require("node:path"));
411
411
 
412
- // core/infrastructure/command-installer.ts
413
- var import_promises = __toESM(require("fs/promises"));
414
- var import_path3 = __toESM(require("path"));
415
- var import_os2 = __toESM(require("os"));
412
+ // core/types/fs.ts
413
+ function isNotFoundError(error) {
414
+ return error?.code === "ENOENT";
415
+ }
416
+ __name(isNotFoundError, "isNotFoundError");
416
417
 
417
418
  // core/utils/version.ts
418
- var import_fs = __toESM(require("fs"));
419
- var import_path = __toESM(require("path"));
419
+ var import_node_fs = __toESM(require("node:fs"));
420
+ var import_node_path = __toESM(require("node:path"));
420
421
  var cachedVersion = null;
421
422
  var cachedPackageJson = null;
422
423
  var cachedPackageRoot = null;
@@ -426,10 +427,10 @@ function getPackageRoot() {
426
427
  }
427
428
  let currentDir = __dirname;
428
429
  for (let i = 0; i < 5; i++) {
429
- const packageJsonPath = import_path.default.join(currentDir, "package.json");
430
- if (import_fs.default.existsSync(packageJsonPath)) {
430
+ const packageJsonPath = import_node_path.default.join(currentDir, "package.json");
431
+ if (import_node_fs.default.existsSync(packageJsonPath)) {
431
432
  try {
432
- const pkg = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
433
+ const pkg = JSON.parse(import_node_fs.default.readFileSync(packageJsonPath, "utf-8"));
433
434
  if (pkg.name === "prjct-cli") {
434
435
  cachedPackageRoot = currentDir;
435
436
  return currentDir;
@@ -437,9 +438,9 @@ function getPackageRoot() {
437
438
  } catch (_error) {
438
439
  }
439
440
  }
440
- currentDir = import_path.default.dirname(currentDir);
441
+ currentDir = import_node_path.default.dirname(currentDir);
441
442
  }
442
- cachedPackageRoot = import_path.default.join(__dirname, "..", "..", "..");
443
+ cachedPackageRoot = import_node_path.default.join(__dirname, "..", "..", "..");
443
444
  return cachedPackageRoot;
444
445
  }
445
446
  __name(getPackageRoot, "getPackageRoot");
@@ -448,8 +449,8 @@ function getVersion() {
448
449
  return cachedVersion;
449
450
  }
450
451
  try {
451
- const packageJsonPath = import_path.default.join(getPackageRoot(), "package.json");
452
- const packageJson = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
452
+ const packageJsonPath = import_node_path.default.join(getPackageRoot(), "package.json");
453
+ const packageJson = JSON.parse(import_node_fs.default.readFileSync(packageJsonPath, "utf-8"));
453
454
  cachedVersion = packageJson.version;
454
455
  cachedPackageJson = packageJson;
455
456
  return cachedVersion;
@@ -462,23 +463,23 @@ __name(getVersion, "getVersion");
462
463
  var VERSION = getVersion();
463
464
  var PACKAGE_ROOT = getPackageRoot();
464
465
 
465
- // core/types/fs.ts
466
- function isNotFoundError(error) {
467
- return error?.code === "ENOENT";
468
- }
469
- __name(isNotFoundError, "isNotFoundError");
466
+ // core/infrastructure/setup.ts
467
+ init_ai_provider();
470
468
 
471
469
  // core/infrastructure/command-installer.ts
470
+ var import_promises = __toESM(require("node:fs/promises"));
471
+ var import_node_os2 = __toESM(require("node:os"));
472
+ var import_node_path3 = __toESM(require("node:path"));
472
473
  async function installDocs() {
473
474
  try {
474
- const docsDir = import_path3.default.join(import_os2.default.homedir(), ".prjct-cli", "docs");
475
- const templateDocsDir = import_path3.default.join(getPackageRoot(), "templates/global/docs");
475
+ const docsDir = import_node_path3.default.join(import_node_os2.default.homedir(), ".prjct-cli", "docs");
476
+ const templateDocsDir = import_node_path3.default.join(getPackageRoot(), "templates/global/docs");
476
477
  await import_promises.default.mkdir(docsDir, { recursive: true });
477
478
  const docFiles = await import_promises.default.readdir(templateDocsDir);
478
479
  for (const file of docFiles) {
479
480
  if (file.endsWith(".md")) {
480
- const srcPath = import_path3.default.join(templateDocsDir, file);
481
- const destPath = import_path3.default.join(docsDir, file);
481
+ const srcPath = import_node_path3.default.join(templateDocsDir, file);
482
+ const destPath = import_node_path3.default.join(docsDir, file);
482
483
  const content = await import_promises.default.readFile(srcPath, "utf-8");
483
484
  await import_promises.default.writeFile(destPath, content, "utf-8");
484
485
  }
@@ -503,13 +504,18 @@ async function installGlobalConfig() {
503
504
  }
504
505
  try {
505
506
  await import_promises.default.mkdir(activeProvider.configDir, { recursive: true });
506
- const globalConfigPath = import_path3.default.join(activeProvider.configDir, activeProvider.contextFile);
507
- const templatePath = import_path3.default.join(getPackageRoot(), "templates", "global", activeProvider.contextFile);
507
+ const globalConfigPath = import_node_path3.default.join(activeProvider.configDir, activeProvider.contextFile);
508
+ const templatePath = import_node_path3.default.join(
509
+ getPackageRoot(),
510
+ "templates",
511
+ "global",
512
+ activeProvider.contextFile
513
+ );
508
514
  let templateContent = "";
509
515
  try {
510
516
  templateContent = await import_promises.default.readFile(templatePath, "utf-8");
511
- } catch (error) {
512
- const fallbackTemplatePath = import_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
517
+ } catch (_error) {
518
+ const fallbackTemplatePath = import_node_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
513
519
  templateContent = await import_promises.default.readFile(fallbackTemplatePath, "utf-8");
514
520
  if (providerName === "gemini") {
515
521
  templateContent = templateContent.replace(/Claude/g, "Gemini");
@@ -539,7 +545,9 @@ async function installGlobalConfig() {
539
545
  const endMarker = "<!-- prjct:end - DO NOT REMOVE THIS MARKER -->";
540
546
  const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
541
547
  if (!hasMarkers) {
542
- const updatedContent = existingContent + "\n\n" + templateContent;
548
+ const updatedContent = `${existingContent}
549
+
550
+ ${templateContent}`;
543
551
  await import_promises.default.writeFile(globalConfigPath, updatedContent, "utf-8");
544
552
  return {
545
553
  success: true,
@@ -582,16 +590,16 @@ var CommandInstaller = class {
582
590
  claudeConfigPath;
583
591
  templatesDir;
584
592
  constructor() {
585
- this.homeDir = import_os2.default.homedir();
593
+ this.homeDir = import_node_os2.default.homedir();
586
594
  const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
587
595
  const activeProvider = aiProvider.getActiveProvider();
588
596
  if (activeProvider.name === "gemini") {
589
- this.claudeCommandsPath = import_path3.default.join(activeProvider.configDir, "commands");
597
+ this.claudeCommandsPath = import_node_path3.default.join(activeProvider.configDir, "commands");
590
598
  } else {
591
- this.claudeCommandsPath = import_path3.default.join(activeProvider.configDir, "commands", "p");
599
+ this.claudeCommandsPath = import_node_path3.default.join(activeProvider.configDir, "commands", "p");
592
600
  }
593
601
  this.claudeConfigPath = activeProvider.configDir;
594
- this.templatesDir = import_path3.default.join(getPackageRoot(), "templates", "commands");
602
+ this.templatesDir = import_node_path3.default.join(getPackageRoot(), "templates", "commands");
595
603
  }
596
604
  /**
597
605
  * Detect if active provider is installed
@@ -620,7 +628,7 @@ var CommandInstaller = class {
620
628
  try {
621
629
  const files = await import_promises.default.readdir(this.templatesDir);
622
630
  return files.filter((f) => f.endsWith(".md"));
623
- } catch (error) {
631
+ } catch (_error) {
624
632
  return [
625
633
  "init.md",
626
634
  "now.md",
@@ -665,8 +673,8 @@ var CommandInstaller = class {
665
673
  const errors = [];
666
674
  for (const file of commandFiles) {
667
675
  try {
668
- const sourcePath = import_path3.default.join(this.templatesDir, file);
669
- const destPath = import_path3.default.join(this.claudeCommandsPath, file);
676
+ const sourcePath = import_node_path3.default.join(this.templatesDir, file);
677
+ const destPath = import_node_path3.default.join(this.claudeCommandsPath, file);
670
678
  const content = await import_promises.default.readFile(sourcePath, "utf-8");
671
679
  await import_promises.default.writeFile(destPath, content, "utf-8");
672
680
  installed.push(file.replace(".md", ""));
@@ -697,7 +705,7 @@ var CommandInstaller = class {
697
705
  const errors = [];
698
706
  for (const file of commandFiles) {
699
707
  try {
700
- const filePath = import_path3.default.join(this.claudeCommandsPath, file);
708
+ const filePath = import_node_path3.default.join(this.claudeCommandsPath, file);
701
709
  await import_promises.default.unlink(filePath);
702
710
  uninstalled.push(file.replace(".md", ""));
703
711
  } catch (error) {
@@ -708,7 +716,7 @@ var CommandInstaller = class {
708
716
  }
709
717
  try {
710
718
  await import_promises.default.rmdir(this.claudeCommandsPath);
711
- } catch (error) {
719
+ } catch (_error) {
712
720
  }
713
721
  return {
714
722
  success: true,
@@ -782,7 +790,7 @@ var CommandInstaller = class {
782
790
  */
783
791
  async verifyTemplate(commandName) {
784
792
  try {
785
- const templatePath = import_path3.default.join(this.templatesDir, `${commandName}.md`);
793
+ const templatePath = import_node_path3.default.join(this.templatesDir, `${commandName}.md`);
786
794
  await import_promises.default.access(templatePath);
787
795
  return true;
788
796
  } catch (error) {
@@ -801,9 +809,9 @@ var CommandInstaller = class {
801
809
  const activeProvider = aiProvider.getActiveProvider();
802
810
  const routerFile = activeProvider.name === "gemini" ? "p.toml" : "p.md";
803
811
  try {
804
- const routerSource = import_path3.default.join(this.templatesDir, routerFile);
805
- const routerDest = import_path3.default.join(activeProvider.configDir, "commands", routerFile);
806
- await import_promises.default.mkdir(import_path3.default.dirname(routerDest), { recursive: true });
812
+ const routerSource = import_node_path3.default.join(this.templatesDir, routerFile);
813
+ const routerDest = import_node_path3.default.join(activeProvider.configDir, "commands", routerFile);
814
+ await import_promises.default.mkdir(import_node_path3.default.dirname(routerDest), { recursive: true });
807
815
  const content = await import_promises.default.readFile(routerSource, "utf-8");
808
816
  await import_promises.default.writeFile(routerDest, content, "utf-8");
809
817
  return true;
@@ -852,8 +860,8 @@ var CommandInstaller = class {
852
860
  };
853
861
  for (const file of templateFiles) {
854
862
  try {
855
- const sourcePath = import_path3.default.join(this.templatesDir, file);
856
- const destPath = import_path3.default.join(this.claudeCommandsPath, file);
863
+ const sourcePath = import_node_path3.default.join(this.templatesDir, file);
864
+ const destPath = import_node_path3.default.join(this.claudeCommandsPath, file);
857
865
  const exists = installedFiles.includes(file);
858
866
  const content = await import_promises.default.readFile(sourcePath, "utf-8");
859
867
  await import_promises.default.writeFile(destPath, content, "utf-8");
@@ -894,9 +902,9 @@ var commandInstaller = new CommandInstaller();
894
902
  var command_installer_default = commandInstaller;
895
903
 
896
904
  // core/infrastructure/editors-config.ts
897
- var import_promises2 = __toESM(require("fs/promises"));
898
- var import_path4 = __toESM(require("path"));
899
- var import_os3 = __toESM(require("os"));
905
+ var import_promises2 = __toESM(require("node:fs/promises"));
906
+ var import_node_os3 = __toESM(require("node:os"));
907
+ var import_node_path4 = __toESM(require("node:path"));
900
908
  var EditorsConfig = class {
901
909
  static {
902
910
  __name(this, "EditorsConfig");
@@ -905,9 +913,9 @@ var EditorsConfig = class {
905
913
  configDir;
906
914
  configFile;
907
915
  constructor() {
908
- this.homeDir = import_os3.default.homedir();
909
- this.configDir = import_path4.default.join(this.homeDir, ".prjct-cli", "config");
910
- this.configFile = import_path4.default.join(this.configDir, "installed-editors.json");
916
+ this.homeDir = import_node_os3.default.homedir();
917
+ this.configDir = import_node_path4.default.join(this.homeDir, ".prjct-cli", "config");
918
+ this.configFile = import_node_path4.default.join(this.configDir, "installed-editors.json");
911
919
  }
912
920
  /**
913
921
  * Ensure config directory exists
@@ -1027,7 +1035,6 @@ var editorsConfig = new EditorsConfig();
1027
1035
  var editors_config_default = editorsConfig;
1028
1036
 
1029
1037
  // core/infrastructure/setup.ts
1030
- init_ai_provider();
1031
1038
  var GREEN = "\x1B[32m";
1032
1039
  var YELLOW = "\x1B[33m";
1033
1040
  var DIM = "\x1B[2m";
@@ -1037,13 +1044,15 @@ async function installAICLI(provider) {
1037
1044
  try {
1038
1045
  console.log(`${YELLOW}\u{1F4E6} ${provider.displayName} not found. Installing...${NC}`);
1039
1046
  console.log("");
1040
- (0, import_child_process2.execSync)(`npm install -g ${packageName}`, { stdio: "inherit" });
1047
+ (0, import_node_child_process2.execSync)(`npm install -g ${packageName}`, { stdio: "inherit" });
1041
1048
  console.log("");
1042
1049
  console.log(`${GREEN}\u2713${NC} ${provider.displayName} installed successfully`);
1043
1050
  console.log("");
1044
1051
  return true;
1045
1052
  } catch (error) {
1046
- console.log(`${YELLOW}\u26A0\uFE0F Failed to install ${provider.displayName}: ${error.message}${NC}`);
1053
+ console.log(
1054
+ `${YELLOW}\u26A0\uFE0F Failed to install ${provider.displayName}: ${error.message}${NC}`
1055
+ );
1047
1056
  console.log(`${DIM}Please install manually: npm install -g ${packageName}${NC}`);
1048
1057
  console.log("");
1049
1058
  return false;
@@ -1053,7 +1062,7 @@ __name(installAICLI, "installAICLI");
1053
1062
  async function run() {
1054
1063
  const detection = detectAllProviders();
1055
1064
  const selection = selectProvider();
1056
- const primaryProvider = Providers[selection.provider];
1065
+ const _primaryProvider = Providers[selection.provider];
1057
1066
  const results = {
1058
1067
  provider: selection.provider,
1059
1068
  providers: [],
@@ -1137,12 +1146,12 @@ __name(run, "run");
1137
1146
  var setup_default = { run };
1138
1147
  async function installGeminiRouter() {
1139
1148
  try {
1140
- const geminiCommandsDir = import_path5.default.join(import_os4.default.homedir(), ".gemini", "commands");
1141
- const routerSource = import_path5.default.join(getPackageRoot(), "templates", "commands", "p.toml");
1142
- const routerDest = import_path5.default.join(geminiCommandsDir, "p.toml");
1143
- import_fs4.default.mkdirSync(geminiCommandsDir, { recursive: true });
1144
- if (import_fs4.default.existsSync(routerSource)) {
1145
- import_fs4.default.copyFileSync(routerSource, routerDest);
1149
+ const geminiCommandsDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".gemini", "commands");
1150
+ const routerSource = import_node_path5.default.join(getPackageRoot(), "templates", "commands", "p.toml");
1151
+ const routerDest = import_node_path5.default.join(geminiCommandsDir, "p.toml");
1152
+ import_node_fs3.default.mkdirSync(geminiCommandsDir, { recursive: true });
1153
+ if (import_node_fs3.default.existsSync(routerSource)) {
1154
+ import_node_fs3.default.copyFileSync(routerSource, routerDest);
1146
1155
  return true;
1147
1156
  }
1148
1157
  return false;
@@ -1154,15 +1163,15 @@ async function installGeminiRouter() {
1154
1163
  __name(installGeminiRouter, "installGeminiRouter");
1155
1164
  async function installGeminiGlobalConfig() {
1156
1165
  try {
1157
- const geminiDir = import_path5.default.join(import_os4.default.homedir(), ".gemini");
1158
- const globalConfigPath = import_path5.default.join(geminiDir, "GEMINI.md");
1159
- const templatePath = import_path5.default.join(getPackageRoot(), "templates", "global", "GEMINI.md");
1160
- import_fs4.default.mkdirSync(geminiDir, { recursive: true });
1161
- const templateContent = import_fs4.default.readFileSync(templatePath, "utf-8");
1166
+ const geminiDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".gemini");
1167
+ const globalConfigPath = import_node_path5.default.join(geminiDir, "GEMINI.md");
1168
+ const templatePath = import_node_path5.default.join(getPackageRoot(), "templates", "global", "GEMINI.md");
1169
+ import_node_fs3.default.mkdirSync(geminiDir, { recursive: true });
1170
+ const templateContent = import_node_fs3.default.readFileSync(templatePath, "utf-8");
1162
1171
  let existingContent = "";
1163
1172
  let fileExists = false;
1164
1173
  try {
1165
- existingContent = import_fs4.default.readFileSync(globalConfigPath, "utf-8");
1174
+ existingContent = import_node_fs3.default.readFileSync(globalConfigPath, "utf-8");
1166
1175
  fileExists = true;
1167
1176
  } catch (error) {
1168
1177
  if (isNotFoundError(error)) {
@@ -1172,15 +1181,17 @@ async function installGeminiGlobalConfig() {
1172
1181
  }
1173
1182
  }
1174
1183
  if (!fileExists) {
1175
- import_fs4.default.writeFileSync(globalConfigPath, templateContent, "utf-8");
1184
+ import_node_fs3.default.writeFileSync(globalConfigPath, templateContent, "utf-8");
1176
1185
  return { success: true, action: "created" };
1177
1186
  }
1178
1187
  const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
1179
1188
  const endMarker = "<!-- prjct:end - DO NOT REMOVE THIS MARKER -->";
1180
1189
  const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
1181
1190
  if (!hasMarkers) {
1182
- const updatedContent2 = existingContent + "\n\n" + templateContent;
1183
- import_fs4.default.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
1191
+ const updatedContent2 = `${existingContent}
1192
+
1193
+ ${templateContent}`;
1194
+ import_node_fs3.default.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
1184
1195
  return { success: true, action: "appended" };
1185
1196
  }
1186
1197
  const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
@@ -1192,7 +1203,7 @@ async function installGeminiGlobalConfig() {
1192
1203
  templateContent.indexOf(endMarker) + endMarker.length
1193
1204
  );
1194
1205
  const updatedContent = beforeMarker + prjctSection + afterMarker;
1195
- import_fs4.default.writeFileSync(globalConfigPath, updatedContent, "utf-8");
1206
+ import_node_fs3.default.writeFileSync(globalConfigPath, updatedContent, "utf-8");
1196
1207
  return { success: true, action: "updated" };
1197
1208
  } catch (error) {
1198
1209
  console.error(`Gemini config warning: ${error.message}`);
@@ -1202,18 +1213,18 @@ async function installGeminiGlobalConfig() {
1202
1213
  __name(installGeminiGlobalConfig, "installGeminiGlobalConfig");
1203
1214
  async function installAntigravitySkill() {
1204
1215
  try {
1205
- const antigravitySkillsDir = import_path5.default.join(import_os4.default.homedir(), ".gemini", "antigravity", "skills");
1206
- const prjctSkillDir = import_path5.default.join(antigravitySkillsDir, "prjct");
1207
- const skillMdPath = import_path5.default.join(prjctSkillDir, "SKILL.md");
1208
- const templatePath = import_path5.default.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
1209
- import_fs4.default.mkdirSync(prjctSkillDir, { recursive: true });
1210
- const fileExists = import_fs4.default.existsSync(skillMdPath);
1211
- if (!import_fs4.default.existsSync(templatePath)) {
1216
+ const antigravitySkillsDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".gemini", "antigravity", "skills");
1217
+ const prjctSkillDir = import_node_path5.default.join(antigravitySkillsDir, "prjct");
1218
+ const skillMdPath = import_node_path5.default.join(prjctSkillDir, "SKILL.md");
1219
+ const templatePath = import_node_path5.default.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
1220
+ import_node_fs3.default.mkdirSync(prjctSkillDir, { recursive: true });
1221
+ const fileExists = import_node_fs3.default.existsSync(skillMdPath);
1222
+ if (!import_node_fs3.default.existsSync(templatePath)) {
1212
1223
  console.error("Antigravity SKILL.md template not found");
1213
1224
  return { success: false, action: null };
1214
1225
  }
1215
- const templateContent = import_fs4.default.readFileSync(templatePath, "utf-8");
1216
- import_fs4.default.writeFileSync(skillMdPath, templateContent, "utf-8");
1226
+ const templateContent = import_node_fs3.default.readFileSync(templatePath, "utf-8");
1227
+ import_node_fs3.default.writeFileSync(skillMdPath, templateContent, "utf-8");
1217
1228
  return { success: true, action: fileExists ? "updated" : "created" };
1218
1229
  } catch (error) {
1219
1230
  console.error(`Antigravity skill warning: ${error.message}`);
@@ -1234,24 +1245,24 @@ async function installCursorProject(projectRoot) {
1234
1245
  gitignoreUpdated: false
1235
1246
  };
1236
1247
  try {
1237
- const cursorDir = import_path5.default.join(projectRoot, ".cursor");
1238
- const rulesDir = import_path5.default.join(cursorDir, "rules");
1239
- const commandsDir = import_path5.default.join(cursorDir, "commands");
1240
- const routerMdcDest = import_path5.default.join(rulesDir, "prjct.mdc");
1241
- const routerMdcSource = import_path5.default.join(getPackageRoot(), "templates", "cursor", "router.mdc");
1242
- const cursorCommandsSource = import_path5.default.join(getPackageRoot(), "templates", "cursor", "commands");
1243
- import_fs4.default.mkdirSync(rulesDir, { recursive: true });
1244
- import_fs4.default.mkdirSync(commandsDir, { recursive: true });
1245
- if (import_fs4.default.existsSync(routerMdcSource)) {
1246
- import_fs4.default.copyFileSync(routerMdcSource, routerMdcDest);
1248
+ const cursorDir = import_node_path5.default.join(projectRoot, ".cursor");
1249
+ const rulesDir = import_node_path5.default.join(cursorDir, "rules");
1250
+ const commandsDir = import_node_path5.default.join(cursorDir, "commands");
1251
+ const routerMdcDest = import_node_path5.default.join(rulesDir, "prjct.mdc");
1252
+ const routerMdcSource = import_node_path5.default.join(getPackageRoot(), "templates", "cursor", "router.mdc");
1253
+ const cursorCommandsSource = import_node_path5.default.join(getPackageRoot(), "templates", "cursor", "commands");
1254
+ import_node_fs3.default.mkdirSync(rulesDir, { recursive: true });
1255
+ import_node_fs3.default.mkdirSync(commandsDir, { recursive: true });
1256
+ if (import_node_fs3.default.existsSync(routerMdcSource)) {
1257
+ import_node_fs3.default.copyFileSync(routerMdcSource, routerMdcDest);
1247
1258
  result.rulesCreated = true;
1248
1259
  }
1249
- if (import_fs4.default.existsSync(cursorCommandsSource)) {
1250
- const commandFiles = import_fs4.default.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
1260
+ if (import_node_fs3.default.existsSync(cursorCommandsSource)) {
1261
+ const commandFiles = import_node_fs3.default.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
1251
1262
  for (const file of commandFiles) {
1252
- const src = import_path5.default.join(cursorCommandsSource, file);
1253
- const dest = import_path5.default.join(commandsDir, file);
1254
- import_fs4.default.copyFileSync(src, dest);
1263
+ const src = import_node_path5.default.join(cursorCommandsSource, file);
1264
+ const dest = import_node_path5.default.join(commandsDir, file);
1265
+ import_node_fs3.default.copyFileSync(src, dest);
1255
1266
  }
1256
1267
  result.commandsCreated = commandFiles.length > 0;
1257
1268
  }
@@ -1266,7 +1277,7 @@ async function installCursorProject(projectRoot) {
1266
1277
  __name(installCursorProject, "installCursorProject");
1267
1278
  async function addCursorToGitignore(projectRoot) {
1268
1279
  try {
1269
- const gitignorePath = import_path5.default.join(projectRoot, ".gitignore");
1280
+ const gitignorePath = import_node_path5.default.join(projectRoot, ".gitignore");
1270
1281
  const entriesToAdd = [
1271
1282
  "# prjct Cursor routers (regenerated per-developer)",
1272
1283
  ".cursor/rules/prjct.mdc",
@@ -1281,7 +1292,7 @@ async function addCursorToGitignore(projectRoot) {
1281
1292
  let content = "";
1282
1293
  let fileExists = false;
1283
1294
  try {
1284
- content = import_fs4.default.readFileSync(gitignorePath, "utf-8");
1295
+ content = import_node_fs3.default.readFileSync(gitignorePath, "utf-8");
1285
1296
  fileExists = true;
1286
1297
  } catch (error) {
1287
1298
  if (!isNotFoundError(error)) {
@@ -1291,8 +1302,12 @@ async function addCursorToGitignore(projectRoot) {
1291
1302
  if (content.includes(".cursor/rules/prjct.mdc")) {
1292
1303
  return false;
1293
1304
  }
1294
- const newContent = fileExists ? content.trimEnd() + "\n\n" + entriesToAdd.join("\n") + "\n" : entriesToAdd.join("\n") + "\n";
1295
- import_fs4.default.writeFileSync(gitignorePath, newContent, "utf-8");
1305
+ const newContent = fileExists ? `${content.trimEnd()}
1306
+
1307
+ ${entriesToAdd.join("\n")}
1308
+ ` : `${entriesToAdd.join("\n")}
1309
+ `;
1310
+ import_node_fs3.default.writeFileSync(gitignorePath, newContent, "utf-8");
1296
1311
  return true;
1297
1312
  } catch (error) {
1298
1313
  console.error(`Gitignore update warning: ${error.message}`);
@@ -1301,13 +1316,13 @@ async function addCursorToGitignore(projectRoot) {
1301
1316
  }
1302
1317
  __name(addCursorToGitignore, "addCursorToGitignore");
1303
1318
  function hasCursorProject(projectRoot) {
1304
- return import_fs4.default.existsSync(import_path5.default.join(projectRoot, ".cursor"));
1319
+ return import_node_fs3.default.existsSync(import_node_path5.default.join(projectRoot, ".cursor"));
1305
1320
  }
1306
1321
  __name(hasCursorProject, "hasCursorProject");
1307
1322
  function needsCursorRegeneration(projectRoot) {
1308
- const cursorDir = import_path5.default.join(projectRoot, ".cursor");
1309
- const routerPath = import_path5.default.join(cursorDir, "rules", "prjct.mdc");
1310
- return import_fs4.default.existsSync(cursorDir) && !import_fs4.default.existsSync(routerPath);
1323
+ const cursorDir = import_node_path5.default.join(projectRoot, ".cursor");
1324
+ const routerPath = import_node_path5.default.join(cursorDir, "rules", "prjct.mdc");
1325
+ return import_node_fs3.default.existsSync(cursorDir) && !import_node_fs3.default.existsSync(routerPath);
1311
1326
  }
1312
1327
  __name(needsCursorRegeneration, "needsCursorRegeneration");
1313
1328
  async function installWindsurfProject(projectRoot) {
@@ -1318,24 +1333,29 @@ async function installWindsurfProject(projectRoot) {
1318
1333
  gitignoreUpdated: false
1319
1334
  };
1320
1335
  try {
1321
- const windsurfDir = import_path5.default.join(projectRoot, ".windsurf");
1322
- const rulesDir = import_path5.default.join(windsurfDir, "rules");
1323
- const workflowsDir = import_path5.default.join(windsurfDir, "workflows");
1324
- const routerDest = import_path5.default.join(rulesDir, "prjct.md");
1325
- const routerSource = import_path5.default.join(getPackageRoot(), "templates", "windsurf", "router.md");
1326
- const windsurfWorkflowsSource = import_path5.default.join(getPackageRoot(), "templates", "windsurf", "workflows");
1327
- import_fs4.default.mkdirSync(rulesDir, { recursive: true });
1328
- import_fs4.default.mkdirSync(workflowsDir, { recursive: true });
1329
- if (import_fs4.default.existsSync(routerSource)) {
1330
- import_fs4.default.copyFileSync(routerSource, routerDest);
1336
+ const windsurfDir = import_node_path5.default.join(projectRoot, ".windsurf");
1337
+ const rulesDir = import_node_path5.default.join(windsurfDir, "rules");
1338
+ const workflowsDir = import_node_path5.default.join(windsurfDir, "workflows");
1339
+ const routerDest = import_node_path5.default.join(rulesDir, "prjct.md");
1340
+ const routerSource = import_node_path5.default.join(getPackageRoot(), "templates", "windsurf", "router.md");
1341
+ const windsurfWorkflowsSource = import_node_path5.default.join(
1342
+ getPackageRoot(),
1343
+ "templates",
1344
+ "windsurf",
1345
+ "workflows"
1346
+ );
1347
+ import_node_fs3.default.mkdirSync(rulesDir, { recursive: true });
1348
+ import_node_fs3.default.mkdirSync(workflowsDir, { recursive: true });
1349
+ if (import_node_fs3.default.existsSync(routerSource)) {
1350
+ import_node_fs3.default.copyFileSync(routerSource, routerDest);
1331
1351
  result.rulesCreated = true;
1332
1352
  }
1333
- if (import_fs4.default.existsSync(windsurfWorkflowsSource)) {
1334
- const workflowFiles = import_fs4.default.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
1353
+ if (import_node_fs3.default.existsSync(windsurfWorkflowsSource)) {
1354
+ const workflowFiles = import_node_fs3.default.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
1335
1355
  for (const file of workflowFiles) {
1336
- const src = import_path5.default.join(windsurfWorkflowsSource, file);
1337
- const dest = import_path5.default.join(workflowsDir, file);
1338
- import_fs4.default.copyFileSync(src, dest);
1356
+ const src = import_node_path5.default.join(windsurfWorkflowsSource, file);
1357
+ const dest = import_node_path5.default.join(workflowsDir, file);
1358
+ import_node_fs3.default.copyFileSync(src, dest);
1339
1359
  }
1340
1360
  result.workflowsCreated = workflowFiles.length > 0;
1341
1361
  }
@@ -1350,7 +1370,7 @@ async function installWindsurfProject(projectRoot) {
1350
1370
  __name(installWindsurfProject, "installWindsurfProject");
1351
1371
  async function addWindsurfToGitignore(projectRoot) {
1352
1372
  try {
1353
- const gitignorePath = import_path5.default.join(projectRoot, ".gitignore");
1373
+ const gitignorePath = import_node_path5.default.join(projectRoot, ".gitignore");
1354
1374
  const entriesToAdd = [
1355
1375
  "# prjct Windsurf routers (regenerated per-developer)",
1356
1376
  ".windsurf/rules/prjct.md",
@@ -1365,7 +1385,7 @@ async function addWindsurfToGitignore(projectRoot) {
1365
1385
  let content = "";
1366
1386
  let fileExists = false;
1367
1387
  try {
1368
- content = import_fs4.default.readFileSync(gitignorePath, "utf-8");
1388
+ content = import_node_fs3.default.readFileSync(gitignorePath, "utf-8");
1369
1389
  fileExists = true;
1370
1390
  } catch (error) {
1371
1391
  if (!isNotFoundError(error)) {
@@ -1375,8 +1395,12 @@ async function addWindsurfToGitignore(projectRoot) {
1375
1395
  if (content.includes(".windsurf/rules/prjct.md")) {
1376
1396
  return false;
1377
1397
  }
1378
- const newContent = fileExists ? content.trimEnd() + "\n\n" + entriesToAdd.join("\n") + "\n" : entriesToAdd.join("\n") + "\n";
1379
- import_fs4.default.writeFileSync(gitignorePath, newContent, "utf-8");
1398
+ const newContent = fileExists ? `${content.trimEnd()}
1399
+
1400
+ ${entriesToAdd.join("\n")}
1401
+ ` : `${entriesToAdd.join("\n")}
1402
+ `;
1403
+ import_node_fs3.default.writeFileSync(gitignorePath, newContent, "utf-8");
1380
1404
  return true;
1381
1405
  } catch (error) {
1382
1406
  console.error(`Gitignore update warning: ${error.message}`);
@@ -1385,34 +1409,34 @@ async function addWindsurfToGitignore(projectRoot) {
1385
1409
  }
1386
1410
  __name(addWindsurfToGitignore, "addWindsurfToGitignore");
1387
1411
  function hasWindsurfProject(projectRoot) {
1388
- return import_fs4.default.existsSync(import_path5.default.join(projectRoot, ".windsurf"));
1412
+ return import_node_fs3.default.existsSync(import_node_path5.default.join(projectRoot, ".windsurf"));
1389
1413
  }
1390
1414
  __name(hasWindsurfProject, "hasWindsurfProject");
1391
1415
  function needsWindsurfRegeneration(projectRoot) {
1392
- const windsurfDir = import_path5.default.join(projectRoot, ".windsurf");
1393
- const routerPath = import_path5.default.join(windsurfDir, "rules", "prjct.md");
1394
- return import_fs4.default.existsSync(windsurfDir) && !import_fs4.default.existsSync(routerPath);
1416
+ const windsurfDir = import_node_path5.default.join(projectRoot, ".windsurf");
1417
+ const routerPath = import_node_path5.default.join(windsurfDir, "rules", "prjct.md");
1418
+ return import_node_fs3.default.existsSync(windsurfDir) && !import_node_fs3.default.existsSync(routerPath);
1395
1419
  }
1396
1420
  __name(needsWindsurfRegeneration, "needsWindsurfRegeneration");
1397
1421
  async function migrateProjectsCliVersion() {
1398
1422
  try {
1399
- const projectsDir = import_path5.default.join(import_os4.default.homedir(), ".prjct-cli", "projects");
1400
- if (!import_fs4.default.existsSync(projectsDir)) {
1423
+ const projectsDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".prjct-cli", "projects");
1424
+ if (!import_node_fs3.default.existsSync(projectsDir)) {
1401
1425
  return;
1402
1426
  }
1403
- const projectDirs = import_fs4.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
1427
+ const projectDirs = import_node_fs3.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
1404
1428
  let migrated = 0;
1405
1429
  for (const projectId of projectDirs) {
1406
- const projectJsonPath = import_path5.default.join(projectsDir, projectId, "project.json");
1407
- if (!import_fs4.default.existsSync(projectJsonPath)) {
1430
+ const projectJsonPath = import_node_path5.default.join(projectsDir, projectId, "project.json");
1431
+ if (!import_node_fs3.default.existsSync(projectJsonPath)) {
1408
1432
  continue;
1409
1433
  }
1410
1434
  try {
1411
- const content = import_fs4.default.readFileSync(projectJsonPath, "utf8");
1435
+ const content = import_node_fs3.default.readFileSync(projectJsonPath, "utf8");
1412
1436
  const project = JSON.parse(content);
1413
1437
  if (project.cliVersion !== VERSION) {
1414
1438
  project.cliVersion = VERSION;
1415
- import_fs4.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
1439
+ import_node_fs3.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
1416
1440
  migrated++;
1417
1441
  }
1418
1442
  } catch (error) {
@@ -1433,9 +1457,9 @@ async function migrateProjectsCliVersion() {
1433
1457
  __name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
1434
1458
  function ensureStatusLineSettings(settingsPath, statusLinePath) {
1435
1459
  let settings = {};
1436
- if (import_fs4.default.existsSync(settingsPath)) {
1460
+ if (import_node_fs3.default.existsSync(settingsPath)) {
1437
1461
  try {
1438
- settings = JSON.parse(import_fs4.default.readFileSync(settingsPath, "utf8"));
1462
+ settings = JSON.parse(import_node_fs3.default.readFileSync(settingsPath, "utf8"));
1439
1463
  } catch (error) {
1440
1464
  if (!(error instanceof SyntaxError)) {
1441
1465
  throw error;
@@ -1443,43 +1467,43 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
1443
1467
  }
1444
1468
  }
1445
1469
  settings.statusLine = { type: "command", command: statusLinePath };
1446
- import_fs4.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
1470
+ import_node_fs3.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
1447
1471
  }
1448
1472
  __name(ensureStatusLineSettings, "ensureStatusLineSettings");
1449
1473
  async function installStatusLine() {
1450
1474
  try {
1451
- const claudeDir = import_path5.default.join(import_os4.default.homedir(), ".claude");
1452
- const settingsPath = import_path5.default.join(claudeDir, "settings.json");
1453
- const claudeStatusLinePath = import_path5.default.join(claudeDir, "prjct-statusline.sh");
1454
- const prjctStatusLineDir = import_path5.default.join(import_os4.default.homedir(), ".prjct-cli", "statusline");
1455
- const prjctStatusLinePath = import_path5.default.join(prjctStatusLineDir, "statusline.sh");
1456
- const prjctThemesDir = import_path5.default.join(prjctStatusLineDir, "themes");
1457
- const prjctLibDir = import_path5.default.join(prjctStatusLineDir, "lib");
1458
- const prjctComponentsDir = import_path5.default.join(prjctStatusLineDir, "components");
1459
- const prjctConfigPath = import_path5.default.join(prjctStatusLineDir, "config.json");
1460
- const assetsDir = import_path5.default.join(getPackageRoot(), "assets", "statusline");
1461
- const sourceScript = import_path5.default.join(assetsDir, "statusline.sh");
1462
- const sourceThemeDir = import_path5.default.join(assetsDir, "themes");
1463
- const sourceLibDir = import_path5.default.join(assetsDir, "lib");
1464
- const sourceComponentsDir = import_path5.default.join(assetsDir, "components");
1465
- const sourceConfigPath = import_path5.default.join(assetsDir, "default-config.json");
1466
- if (!import_fs4.default.existsSync(claudeDir)) {
1467
- import_fs4.default.mkdirSync(claudeDir, { recursive: true });
1475
+ const claudeDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".claude");
1476
+ const settingsPath = import_node_path5.default.join(claudeDir, "settings.json");
1477
+ const claudeStatusLinePath = import_node_path5.default.join(claudeDir, "prjct-statusline.sh");
1478
+ const prjctStatusLineDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".prjct-cli", "statusline");
1479
+ const prjctStatusLinePath = import_node_path5.default.join(prjctStatusLineDir, "statusline.sh");
1480
+ const prjctThemesDir = import_node_path5.default.join(prjctStatusLineDir, "themes");
1481
+ const prjctLibDir = import_node_path5.default.join(prjctStatusLineDir, "lib");
1482
+ const prjctComponentsDir = import_node_path5.default.join(prjctStatusLineDir, "components");
1483
+ const prjctConfigPath = import_node_path5.default.join(prjctStatusLineDir, "config.json");
1484
+ const assetsDir = import_node_path5.default.join(getPackageRoot(), "assets", "statusline");
1485
+ const sourceScript = import_node_path5.default.join(assetsDir, "statusline.sh");
1486
+ const sourceThemeDir = import_node_path5.default.join(assetsDir, "themes");
1487
+ const sourceLibDir = import_node_path5.default.join(assetsDir, "lib");
1488
+ const sourceComponentsDir = import_node_path5.default.join(assetsDir, "components");
1489
+ const sourceConfigPath = import_node_path5.default.join(assetsDir, "default-config.json");
1490
+ if (!import_node_fs3.default.existsSync(claudeDir)) {
1491
+ import_node_fs3.default.mkdirSync(claudeDir, { recursive: true });
1468
1492
  }
1469
- if (!import_fs4.default.existsSync(prjctStatusLineDir)) {
1470
- import_fs4.default.mkdirSync(prjctStatusLineDir, { recursive: true });
1493
+ if (!import_node_fs3.default.existsSync(prjctStatusLineDir)) {
1494
+ import_node_fs3.default.mkdirSync(prjctStatusLineDir, { recursive: true });
1471
1495
  }
1472
- if (!import_fs4.default.existsSync(prjctThemesDir)) {
1473
- import_fs4.default.mkdirSync(prjctThemesDir, { recursive: true });
1496
+ if (!import_node_fs3.default.existsSync(prjctThemesDir)) {
1497
+ import_node_fs3.default.mkdirSync(prjctThemesDir, { recursive: true });
1474
1498
  }
1475
- if (!import_fs4.default.existsSync(prjctLibDir)) {
1476
- import_fs4.default.mkdirSync(prjctLibDir, { recursive: true });
1499
+ if (!import_node_fs3.default.existsSync(prjctLibDir)) {
1500
+ import_node_fs3.default.mkdirSync(prjctLibDir, { recursive: true });
1477
1501
  }
1478
- if (!import_fs4.default.existsSync(prjctComponentsDir)) {
1479
- import_fs4.default.mkdirSync(prjctComponentsDir, { recursive: true });
1502
+ if (!import_node_fs3.default.existsSync(prjctComponentsDir)) {
1503
+ import_node_fs3.default.mkdirSync(prjctComponentsDir, { recursive: true });
1480
1504
  }
1481
- if (import_fs4.default.existsSync(prjctStatusLinePath)) {
1482
- const existingContent = import_fs4.default.readFileSync(prjctStatusLinePath, "utf8");
1505
+ if (import_node_fs3.default.existsSync(prjctStatusLinePath)) {
1506
+ const existingContent = import_node_fs3.default.readFileSync(prjctStatusLinePath, "utf8");
1483
1507
  if (existingContent.includes("CLI_VERSION=")) {
1484
1508
  const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
1485
1509
  if (versionMatch && versionMatch[1] !== VERSION) {
@@ -1487,7 +1511,7 @@ async function installStatusLine() {
1487
1511
  /CLI_VERSION="[^"]*"/,
1488
1512
  `CLI_VERSION="${VERSION}"`
1489
1513
  );
1490
- import_fs4.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
1514
+ import_node_fs3.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
1491
1515
  }
1492
1516
  installStatusLineModules(sourceLibDir, prjctLibDir);
1493
1517
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
@@ -1496,25 +1520,22 @@ async function installStatusLine() {
1496
1520
  return;
1497
1521
  }
1498
1522
  }
1499
- if (import_fs4.default.existsSync(sourceScript)) {
1500
- let scriptContent = import_fs4.default.readFileSync(sourceScript, "utf8");
1501
- scriptContent = scriptContent.replace(
1502
- /CLI_VERSION="[^"]*"/,
1503
- `CLI_VERSION="${VERSION}"`
1504
- );
1505
- import_fs4.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
1523
+ if (import_node_fs3.default.existsSync(sourceScript)) {
1524
+ let scriptContent = import_node_fs3.default.readFileSync(sourceScript, "utf8");
1525
+ scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
1526
+ import_node_fs3.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
1506
1527
  installStatusLineModules(sourceLibDir, prjctLibDir);
1507
1528
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
1508
- if (import_fs4.default.existsSync(sourceThemeDir)) {
1509
- const themes = import_fs4.default.readdirSync(sourceThemeDir);
1529
+ if (import_node_fs3.default.existsSync(sourceThemeDir)) {
1530
+ const themes = import_node_fs3.default.readdirSync(sourceThemeDir);
1510
1531
  for (const theme of themes) {
1511
- const src = import_path5.default.join(sourceThemeDir, theme);
1512
- const dest = import_path5.default.join(prjctThemesDir, theme);
1513
- import_fs4.default.copyFileSync(src, dest);
1532
+ const src = import_node_path5.default.join(sourceThemeDir, theme);
1533
+ const dest = import_node_path5.default.join(prjctThemesDir, theme);
1534
+ import_node_fs3.default.copyFileSync(src, dest);
1514
1535
  }
1515
1536
  }
1516
- if (!import_fs4.default.existsSync(prjctConfigPath) && import_fs4.default.existsSync(sourceConfigPath)) {
1517
- import_fs4.default.copyFileSync(sourceConfigPath, prjctConfigPath);
1537
+ if (!import_node_fs3.default.existsSync(prjctConfigPath) && import_node_fs3.default.existsSync(sourceConfigPath)) {
1538
+ import_node_fs3.default.copyFileSync(sourceConfigPath, prjctConfigPath);
1518
1539
  }
1519
1540
  } else {
1520
1541
  const scriptContent = `#!/bin/bash
@@ -1549,7 +1570,7 @@ if [ -f "$CONFIG" ]; then
1549
1570
  fi
1550
1571
  echo "prjct"
1551
1572
  `;
1552
- import_fs4.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
1573
+ import_node_fs3.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
1553
1574
  }
1554
1575
  ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
1555
1576
  ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
@@ -1561,38 +1582,38 @@ echo "prjct"
1561
1582
  }
1562
1583
  __name(installStatusLine, "installStatusLine");
1563
1584
  function installStatusLineModules(sourceDir, destDir) {
1564
- if (!import_fs4.default.existsSync(sourceDir)) {
1585
+ if (!import_node_fs3.default.existsSync(sourceDir)) {
1565
1586
  return;
1566
1587
  }
1567
- const files = import_fs4.default.readdirSync(sourceDir);
1588
+ const files = import_node_fs3.default.readdirSync(sourceDir);
1568
1589
  for (const file of files) {
1569
1590
  if (file.endsWith(".sh")) {
1570
- const src = import_path5.default.join(sourceDir, file);
1571
- const dest = import_path5.default.join(destDir, file);
1572
- import_fs4.default.copyFileSync(src, dest);
1573
- import_fs4.default.chmodSync(dest, 493);
1591
+ const src = import_node_path5.default.join(sourceDir, file);
1592
+ const dest = import_node_path5.default.join(destDir, file);
1593
+ import_node_fs3.default.copyFileSync(src, dest);
1594
+ import_node_fs3.default.chmodSync(dest, 493);
1574
1595
  }
1575
1596
  }
1576
1597
  }
1577
1598
  __name(installStatusLineModules, "installStatusLineModules");
1578
1599
  function ensureStatusLineSymlink(linkPath, targetPath) {
1579
1600
  try {
1580
- if (import_fs4.default.existsSync(linkPath)) {
1581
- const stats = import_fs4.default.lstatSync(linkPath);
1601
+ if (import_node_fs3.default.existsSync(linkPath)) {
1602
+ const stats = import_node_fs3.default.lstatSync(linkPath);
1582
1603
  if (stats.isSymbolicLink()) {
1583
- const existingTarget = import_fs4.default.readlinkSync(linkPath);
1604
+ const existingTarget = import_node_fs3.default.readlinkSync(linkPath);
1584
1605
  if (existingTarget === targetPath) {
1585
1606
  return;
1586
1607
  }
1587
1608
  }
1588
- import_fs4.default.unlinkSync(linkPath);
1609
+ import_node_fs3.default.unlinkSync(linkPath);
1589
1610
  }
1590
- import_fs4.default.symlinkSync(targetPath, linkPath);
1591
- } catch (error) {
1611
+ import_node_fs3.default.symlinkSync(targetPath, linkPath);
1612
+ } catch (_error) {
1592
1613
  try {
1593
- if (import_fs4.default.existsSync(targetPath)) {
1594
- import_fs4.default.copyFileSync(targetPath, linkPath);
1595
- import_fs4.default.chmodSync(linkPath, 493);
1614
+ if (import_node_fs3.default.existsSync(targetPath)) {
1615
+ import_node_fs3.default.copyFileSync(targetPath, linkPath);
1616
+ import_node_fs3.default.chmodSync(linkPath, 493);
1596
1617
  }
1597
1618
  } catch (copyError) {
1598
1619
  if (!isNotFoundError(copyError)) {