prjct-cli 1.6.11 → 1.6.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.6.12] - 2026-02-07
4
+
5
+ ### Bug Fixes
6
+
7
+ - replace sync I/O in imports-tool hot path (PRJ-290) (#137)
8
+
9
+
10
+ ## [1.6.14] - 2026-02-07
11
+
12
+ ### Bug Fixes
13
+ - **Replace sync I/O in imports-tool hot path (PRJ-290)**: Converted `tryResolve`/`resolveImport`/`extractImports` from sync `require('node:fs')` with `existsSync`+`statSync` to async `fs.stat()` from `node:fs/promises`. Also replaced repeated `getPackageRoot()` calls with the pre-resolved `PACKAGE_ROOT` constant in prompt-builder, command-installer, and setup modules.
14
+
15
+ ### Implementation Details
16
+ The `imports-tool.ts` file had an inline `require('node:fs')` call inside `tryResolve()` that used `existsSync` and `statSync` in a loop — a true hot path during import analysis. Converted the entire chain (`tryResolve` → `resolveImport` → `extractImports`) to async, using the already-imported `fs` from `node:fs/promises`. `version.ts` was kept sync intentionally: esbuild CJS output (used for postinstall) doesn't support top-level await, and its I/O runs once at cold start with results cached.
17
+
18
+ ### Learnings
19
+ - esbuild CJS format does not support top-level `await` — async module exports require ESM format
20
+ - `version.ts` cold-start I/O is negligible (runs once, cached) vs `imports-tool.ts` which resolves extensions in a loop per import
21
+ - Using pre-resolved `PACKAGE_ROOT` constant avoids repeated sync function calls across modules
22
+
23
+ ### Test Plan
24
+
25
+ #### For QA
26
+ 1. Run `prjct context imports <file>` — verify import resolution works correctly (resolves `.ts`, `.tsx`, `.js` extensions and `/index.ts` barrel imports)
27
+ 2. Run `prjct sync` — verify command-installer and setup find templates via `PACKAGE_ROOT`
28
+ 3. Run `bun run build` — verify all 5 build targets compile without errors
29
+ 4. Verify no `fs.*Sync()` calls remain in `imports-tool.ts`
30
+
31
+ #### For Users
32
+ **What changed:** Import analysis is now fully async, eliminating sync file system calls in the hot path.
33
+ **How to use:** No changes needed — `prjct context imports` works the same way.
34
+ **Breaking changes:** None.
35
+
3
36
  ## [1.6.11] - 2026-02-07
4
37
 
5
38
  ### Performance
6
39
 
7
40
  - cache provider detection to eliminate redundant shell spawns (PRJ-289) (#136)
8
41
 
9
-
10
42
  ## [1.6.13] - 2026-02-07
11
43
 
12
44
  ### Improvements
@@ -27,7 +27,7 @@ import type {
27
27
  } from '../types'
28
28
  import { getErrorMessage, isNotFoundError } from '../types/fs'
29
29
  import { fileExists } from '../utils/fs-helpers'
30
- import { getPackageRoot } from '../utils/version'
30
+ import { PACKAGE_ROOT } from '../utils/version'
31
31
 
32
32
  // Re-export types for convenience
33
33
  export type {
@@ -132,7 +132,7 @@ class PromptBuilder {
132
132
  * These modules extend the base global CLAUDE.md for complex operations
133
133
  */
134
134
  async loadModule(moduleName: string): Promise<string | null> {
135
- const modulePath = path.join(getPackageRoot(), 'templates/global/modules', moduleName)
135
+ const modulePath = path.join(PACKAGE_ROOT, 'templates/global/modules', moduleName)
136
136
  return this.getTemplate(modulePath)
137
137
  }
138
138
 
@@ -178,7 +178,7 @@ export async function analyzeImports(
178
178
  const patterns = IMPORT_PATTERNS[language] || []
179
179
 
180
180
  // Extract imports
181
- const imports = extractImports(content, patterns, absolutePath, projectPath)
181
+ const imports = await extractImports(content, patterns, absolutePath, projectPath)
182
182
 
183
183
  // Get reverse imports if requested
184
184
  let importedBy: ImportedBy[] = []
@@ -217,12 +217,12 @@ export async function analyzeImports(
217
217
  /**
218
218
  * Extract imports from file content
219
219
  */
220
- function extractImports(
220
+ async function extractImports(
221
221
  content: string,
222
222
  patterns: ImportPattern[],
223
223
  absolutePath: string,
224
224
  projectPath: string
225
- ): ImportRelation[] {
225
+ ): Promise<ImportRelation[]> {
226
226
  const imports: ImportRelation[] = []
227
227
  const seen = new Set<string>()
228
228
 
@@ -254,7 +254,7 @@ function extractImports(
254
254
  // Resolve internal imports
255
255
  let resolved: string | null = null
256
256
  if (!isExternal) {
257
- resolved = resolveImport(source, absolutePath, projectPath)
257
+ resolved = await resolveImport(source, absolutePath, projectPath)
258
258
  }
259
259
 
260
260
  imports.push({
@@ -274,7 +274,11 @@ function extractImports(
274
274
  /**
275
275
  * Resolve a relative import to an absolute path
276
276
  */
277
- function resolveImport(source: string, fromFile: string, projectPath: string): string | null {
277
+ async function resolveImport(
278
+ source: string,
279
+ fromFile: string,
280
+ projectPath: string
281
+ ): Promise<string | null> {
278
282
  const fileDir = path.dirname(fromFile)
279
283
 
280
284
  // Handle path alias like @/
@@ -291,15 +295,14 @@ function resolveImport(source: string, fromFile: string, projectPath: string): s
291
295
  /**
292
296
  * Try to resolve a path, adding extensions if needed
293
297
  */
294
- function tryResolve(basePath: string, projectPath: string): string | null {
298
+ async function tryResolve(basePath: string, projectPath: string): Promise<string | null> {
295
299
  const extensions = ['', '.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.js']
296
300
 
297
301
  for (const ext of extensions) {
298
302
  const fullPath = basePath + ext
299
303
  try {
300
- // Check synchronously (we're in a hot path)
301
- const fs = require('node:fs')
302
- if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
304
+ const stat = await fs.stat(fullPath)
305
+ if (stat.isFile()) {
303
306
  return path.relative(projectPath, fullPath)
304
307
  }
305
308
  } catch {}
@@ -23,7 +23,7 @@ import type {
23
23
  UninstallResult,
24
24
  } from '../types'
25
25
  import { getErrorMessage, isNotFoundError } from '../types/fs'
26
- import { getPackageRoot } from '../utils/version'
26
+ import { PACKAGE_ROOT } from '../utils/version'
27
27
 
28
28
  // =============================================================================
29
29
  // Module Types
@@ -51,7 +51,7 @@ interface ModuleConfig {
51
51
  */
52
52
  async function loadModuleConfig(): Promise<ModuleConfig | null> {
53
53
  try {
54
- const configPath = path.join(getPackageRoot(), 'templates/global/modules/module-config.json')
54
+ const configPath = path.join(PACKAGE_ROOT, 'templates/global/modules/module-config.json')
55
55
  const content = await fs.readFile(configPath, 'utf-8')
56
56
  return JSON.parse(content) as ModuleConfig
57
57
  } catch {
@@ -66,11 +66,11 @@ async function loadModuleConfig(): Promise<ModuleConfig | null> {
66
66
  */
67
67
  export async function composeGlobalTemplate(profile?: string): Promise<string> {
68
68
  const config = await loadModuleConfig()
69
- const modulesDir = path.join(getPackageRoot(), 'templates/global/modules')
69
+ const modulesDir = path.join(PACKAGE_ROOT, 'templates/global/modules')
70
70
 
71
71
  // Fallback to legacy template if config not found
72
72
  if (!config) {
73
- const legacyPath = path.join(getPackageRoot(), 'templates/global/CLAUDE.md')
73
+ const legacyPath = path.join(PACKAGE_ROOT, 'templates/global/CLAUDE.md')
74
74
  return fs.readFile(legacyPath, 'utf-8')
75
75
  }
76
76
 
@@ -81,7 +81,7 @@ export async function composeGlobalTemplate(profile?: string): Promise<string> {
81
81
  // Fallback to default profile
82
82
  const defaultProfile = config.profiles[config.default]
83
83
  if (!defaultProfile) {
84
- const legacyPath = path.join(getPackageRoot(), 'templates/global/CLAUDE.md')
84
+ const legacyPath = path.join(PACKAGE_ROOT, 'templates/global/CLAUDE.md')
85
85
  return fs.readFile(legacyPath, 'utf-8')
86
86
  }
87
87
  }
@@ -130,7 +130,7 @@ export async function getProfileForCommand(command: string): Promise<string> {
130
130
  export async function installDocs(): Promise<{ success: boolean; error?: string }> {
131
131
  try {
132
132
  const docsDir = path.join(os.homedir(), '.prjct-cli', 'docs')
133
- const templateDocsDir = path.join(getPackageRoot(), 'templates/global/docs')
133
+ const templateDocsDir = path.join(PACKAGE_ROOT, 'templates/global/docs')
134
134
 
135
135
  // Ensure docs directory exists
136
136
  await fs.mkdir(docsDir, { recursive: true })
@@ -177,12 +177,7 @@ export async function installGlobalConfig(): Promise<GlobalConfigResult> {
177
177
  await fs.mkdir(activeProvider.configDir, { recursive: true })
178
178
 
179
179
  const globalConfigPath = path.join(activeProvider.configDir, activeProvider.contextFile)
180
- const templatePath = path.join(
181
- getPackageRoot(),
182
- 'templates',
183
- 'global',
184
- activeProvider.contextFile
185
- )
180
+ const templatePath = path.join(PACKAGE_ROOT, 'templates', 'global', activeProvider.contextFile)
186
181
 
187
182
  // Read template content - use modular composition (PRJ-94)
188
183
  let templateContent = ''
@@ -196,12 +191,12 @@ export async function installGlobalConfig(): Promise<GlobalConfigResult> {
196
191
  templateContent = await composeGlobalTemplate('standard')
197
192
  } catch {
198
193
  // Final fallback to legacy template
199
- const fallbackTemplatePath = path.join(getPackageRoot(), 'templates/global/CLAUDE.md')
194
+ const fallbackTemplatePath = path.join(PACKAGE_ROOT, 'templates/global/CLAUDE.md')
200
195
  templateContent = await fs.readFile(fallbackTemplatePath, 'utf-8')
201
196
  }
202
197
  } else {
203
198
  // Fallback for other providers
204
- const fallbackTemplatePath = path.join(getPackageRoot(), 'templates/global/CLAUDE.md')
199
+ const fallbackTemplatePath = path.join(PACKAGE_ROOT, 'templates/global/CLAUDE.md')
205
200
  templateContent = await fs.readFile(fallbackTemplatePath, 'utf-8')
206
201
  // If it is Gemini, we should rename Claude to Gemini in the fallback content
207
202
  if (providerName === 'gemini') {
@@ -296,7 +291,7 @@ export class CommandInstaller {
296
291
 
297
292
  constructor() {
298
293
  this.homeDir = os.homedir()
299
- this.templatesDir = path.join(getPackageRoot(), 'templates', 'commands')
294
+ this.templatesDir = path.join(PACKAGE_ROOT, 'templates', 'commands')
300
295
  }
301
296
 
302
297
  private async ensureInit(): Promise<void> {
@@ -28,7 +28,7 @@ import { getErrorMessage, isNotFoundError } from '../types/fs'
28
28
  import type { AIProviderConfig, AIProviderName } from '../types/provider'
29
29
  import { fileExists } from '../utils/fs-helpers'
30
30
  import log from '../utils/logger'
31
- import { getPackageRoot, VERSION } from '../utils/version'
31
+ import { PACKAGE_ROOT, VERSION } from '../utils/version'
32
32
  import {
33
33
  detectAllProviders,
34
34
  detectAntigravity,
@@ -255,7 +255,7 @@ export async function run(): Promise<SetupResults> {
255
255
  async function installGeminiRouter(): Promise<boolean> {
256
256
  try {
257
257
  const geminiCommandsDir = path.join(os.homedir(), '.gemini', 'commands')
258
- const routerSource = path.join(getPackageRoot(), 'templates', 'commands', 'p.toml')
258
+ const routerSource = path.join(PACKAGE_ROOT, 'templates', 'commands', 'p.toml')
259
259
  const routerDest = path.join(geminiCommandsDir, 'p.toml')
260
260
 
261
261
  // Ensure commands directory exists
@@ -280,7 +280,7 @@ async function installGeminiGlobalConfig(): Promise<{ success: boolean; action:
280
280
  try {
281
281
  const geminiDir = path.join(os.homedir(), '.gemini')
282
282
  const globalConfigPath = path.join(geminiDir, 'GEMINI.md')
283
- const templatePath = path.join(getPackageRoot(), 'templates', 'global', 'GEMINI.md')
283
+ const templatePath = path.join(PACKAGE_ROOT, 'templates', 'global', 'GEMINI.md')
284
284
 
285
285
  // Ensure ~/.gemini directory exists
286
286
  await fs.mkdir(geminiDir, { recursive: true })
@@ -361,7 +361,7 @@ export async function installAntigravitySkill(): Promise<{
361
361
  const antigravitySkillsDir = path.join(os.homedir(), '.gemini', 'antigravity', 'skills')
362
362
  const prjctSkillDir = path.join(antigravitySkillsDir, 'prjct')
363
363
  const skillMdPath = path.join(prjctSkillDir, 'SKILL.md')
364
- const templatePath = path.join(getPackageRoot(), 'templates', 'antigravity', 'SKILL.md')
364
+ const templatePath = path.join(PACKAGE_ROOT, 'templates', 'antigravity', 'SKILL.md')
365
365
 
366
366
  // Ensure skills directory exists
367
367
  await fs.mkdir(prjctSkillDir, { recursive: true })
@@ -431,8 +431,8 @@ export async function installCursorProject(projectRoot: string): Promise<{
431
431
 
432
432
  const routerMdcDest = path.join(rulesDir, 'prjct.mdc')
433
433
 
434
- const routerMdcSource = path.join(getPackageRoot(), 'templates', 'cursor', 'router.mdc')
435
- const cursorCommandsSource = path.join(getPackageRoot(), 'templates', 'cursor', 'commands')
434
+ const routerMdcSource = path.join(PACKAGE_ROOT, 'templates', 'cursor', 'router.mdc')
435
+ const cursorCommandsSource = path.join(PACKAGE_ROOT, 'templates', 'cursor', 'commands')
436
436
 
437
437
  // Ensure directories exist
438
438
  await fs.mkdir(rulesDir, { recursive: true })
@@ -574,13 +574,8 @@ export async function installWindsurfProject(projectRoot: string): Promise<{
574
574
 
575
575
  const routerDest = path.join(rulesDir, 'prjct.md')
576
576
 
577
- const routerSource = path.join(getPackageRoot(), 'templates', 'windsurf', 'router.md')
578
- const windsurfWorkflowsSource = path.join(
579
- getPackageRoot(),
580
- 'templates',
581
- 'windsurf',
582
- 'workflows'
583
- )
577
+ const routerSource = path.join(PACKAGE_ROOT, 'templates', 'windsurf', 'router.md')
578
+ const windsurfWorkflowsSource = path.join(PACKAGE_ROOT, 'templates', 'windsurf', 'workflows')
584
579
 
585
580
  // Ensure directories exist
586
581
  await fs.mkdir(rulesDir, { recursive: true })
@@ -785,7 +780,7 @@ async function installStatusLine(): Promise<void> {
785
780
  const prjctConfigPath = path.join(prjctStatusLineDir, 'config.json')
786
781
 
787
782
  // Source assets (from the package)
788
- const assetsDir = path.join(getPackageRoot(), 'assets', 'statusline')
783
+ const assetsDir = path.join(PACKAGE_ROOT, 'assets', 'statusline')
789
784
  const sourceScript = path.join(assetsDir, 'statusline.sh')
790
785
  const sourceThemeDir = path.join(assetsDir, 'themes')
791
786
  const sourceLibDir = path.join(assetsDir, 'lib')
@@ -7,6 +7,9 @@ import { getErrorMessage } from '../types/fs'
7
7
  *
8
8
  * Reads version from package.json dynamically to ensure consistency
9
9
  * across the entire application.
10
+ *
11
+ * Uses sync I/O intentionally: runs once at cold start, results cached.
12
+ * CJS build (postinstall) requires sync module-level exports.
10
13
  */
11
14
 
12
15
  interface PackageJson {
@@ -4309,7 +4309,7 @@ async function analyzeImports(filePath, projectPath = process.cwd(), options = {
4309
4309
  const ext = path14.extname(filePath).toLowerCase();
4310
4310
  const language = EXT_TO_LANG[ext] || "unknown";
4311
4311
  const patterns = IMPORT_PATTERNS[language] || [];
4312
- const imports = extractImports(content, patterns, absolutePath, projectPath);
4312
+ const imports = await extractImports(content, patterns, absolutePath, projectPath);
4313
4313
  let importedBy = [];
4314
4314
  if (options.reverse) {
4315
4315
  importedBy = await findImportedBy(filePath, projectPath);
@@ -4333,7 +4333,7 @@ async function analyzeImports(filePath, projectPath = process.cwd(), options = {
4333
4333
  }
4334
4334
  };
4335
4335
  }
4336
- function extractImports(content, patterns, absolutePath, projectPath) {
4336
+ async function extractImports(content, patterns, absolutePath, projectPath) {
4337
4337
  const imports = [];
4338
4338
  const seen = /* @__PURE__ */ new Set();
4339
4339
  for (const patternDef of patterns) {
@@ -4353,7 +4353,7 @@ function extractImports(content, patterns, absolutePath, projectPath) {
4353
4353
  const isExternal = !source.startsWith(".") && !source.startsWith("/") && !source.startsWith("@/");
4354
4354
  let resolved = null;
4355
4355
  if (!isExternal) {
4356
- resolved = resolveImport(source, absolutePath, projectPath);
4356
+ resolved = await resolveImport(source, absolutePath, projectPath);
4357
4357
  }
4358
4358
  imports.push({
4359
4359
  source,
@@ -4367,7 +4367,7 @@ function extractImports(content, patterns, absolutePath, projectPath) {
4367
4367
  }
4368
4368
  return imports;
4369
4369
  }
4370
- function resolveImport(source, fromFile, projectPath) {
4370
+ async function resolveImport(source, fromFile, projectPath) {
4371
4371
  const fileDir = path14.dirname(fromFile);
4372
4372
  if (source.startsWith("@/")) {
4373
4373
  const aliasPath = path14.join(projectPath, "src", source.slice(2));
@@ -4376,13 +4376,13 @@ function resolveImport(source, fromFile, projectPath) {
4376
4376
  const resolved = path14.resolve(fileDir, source);
4377
4377
  return tryResolve(resolved, projectPath);
4378
4378
  }
4379
- function tryResolve(basePath, projectPath) {
4379
+ async function tryResolve(basePath, projectPath) {
4380
4380
  const extensions = ["", ".ts", ".tsx", ".js", ".jsx", "/index.ts", "/index.js"];
4381
4381
  for (const ext of extensions) {
4382
4382
  const fullPath = basePath + ext;
4383
4383
  try {
4384
- const fs52 = __require("node:fs");
4385
- if (fs52.existsSync(fullPath) && fs52.statSync(fullPath).isFile()) {
4384
+ const stat = await fs14.stat(fullPath);
4385
+ if (stat.isFile()) {
4386
4386
  return path14.relative(projectPath, fullPath);
4387
4387
  }
4388
4388
  } catch {
@@ -6609,7 +6609,7 @@ import os6 from "node:os";
6609
6609
  import path19 from "node:path";
6610
6610
  async function loadModuleConfig() {
6611
6611
  try {
6612
- const configPath = path19.join(getPackageRoot(), "templates/global/modules/module-config.json");
6612
+ const configPath = path19.join(PACKAGE_ROOT, "templates/global/modules/module-config.json");
6613
6613
  const content = await fs19.readFile(configPath, "utf-8");
6614
6614
  return JSON.parse(content);
6615
6615
  } catch {
@@ -6618,9 +6618,9 @@ async function loadModuleConfig() {
6618
6618
  }
6619
6619
  async function composeGlobalTemplate(profile) {
6620
6620
  const config = await loadModuleConfig();
6621
- const modulesDir = path19.join(getPackageRoot(), "templates/global/modules");
6621
+ const modulesDir = path19.join(PACKAGE_ROOT, "templates/global/modules");
6622
6622
  if (!config) {
6623
- const legacyPath = path19.join(getPackageRoot(), "templates/global/CLAUDE.md");
6623
+ const legacyPath = path19.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
6624
6624
  return fs19.readFile(legacyPath, "utf-8");
6625
6625
  }
6626
6626
  const profileName = profile || config.default;
@@ -6628,7 +6628,7 @@ async function composeGlobalTemplate(profile) {
6628
6628
  if (!selectedProfile) {
6629
6629
  const defaultProfile = config.profiles[config.default];
6630
6630
  if (!defaultProfile) {
6631
- const legacyPath = path19.join(getPackageRoot(), "templates/global/CLAUDE.md");
6631
+ const legacyPath = path19.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
6632
6632
  return fs19.readFile(legacyPath, "utf-8");
6633
6633
  }
6634
6634
  }
@@ -6653,7 +6653,7 @@ async function composeGlobalTemplate(profile) {
6653
6653
  async function installDocs() {
6654
6654
  try {
6655
6655
  const docsDir = path19.join(os6.homedir(), ".prjct-cli", "docs");
6656
- const templateDocsDir = path19.join(getPackageRoot(), "templates/global/docs");
6656
+ const templateDocsDir = path19.join(PACKAGE_ROOT, "templates/global/docs");
6657
6657
  await fs19.mkdir(docsDir, { recursive: true });
6658
6658
  const docFiles = await fs19.readdir(templateDocsDir);
6659
6659
  for (const file of docFiles) {
@@ -6684,12 +6684,7 @@ async function installGlobalConfig2() {
6684
6684
  try {
6685
6685
  await fs19.mkdir(activeProvider.configDir, { recursive: true });
6686
6686
  const globalConfigPath = path19.join(activeProvider.configDir, activeProvider.contextFile);
6687
- const templatePath = path19.join(
6688
- getPackageRoot(),
6689
- "templates",
6690
- "global",
6691
- activeProvider.contextFile
6692
- );
6687
+ const templatePath = path19.join(PACKAGE_ROOT, "templates", "global", activeProvider.contextFile);
6693
6688
  let templateContent = "";
6694
6689
  try {
6695
6690
  templateContent = await fs19.readFile(templatePath, "utf-8");
@@ -6698,11 +6693,11 @@ async function installGlobalConfig2() {
6698
6693
  try {
6699
6694
  templateContent = await composeGlobalTemplate("standard");
6700
6695
  } catch {
6701
- const fallbackTemplatePath = path19.join(getPackageRoot(), "templates/global/CLAUDE.md");
6696
+ const fallbackTemplatePath = path19.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
6702
6697
  templateContent = await fs19.readFile(fallbackTemplatePath, "utf-8");
6703
6698
  }
6704
6699
  } else {
6705
- const fallbackTemplatePath = path19.join(getPackageRoot(), "templates/global/CLAUDE.md");
6700
+ const fallbackTemplatePath = path19.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
6706
6701
  templateContent = await fs19.readFile(fallbackTemplatePath, "utf-8");
6707
6702
  if (providerName === "gemini") {
6708
6703
  templateContent = templateContent.replace(/Claude/g, "Gemini");
@@ -6804,7 +6799,7 @@ var init_command_installer = __esm({
6804
6799
  _initialized = false;
6805
6800
  constructor() {
6806
6801
  this.homeDir = os6.homedir();
6807
- this.templatesDir = path19.join(getPackageRoot(), "templates", "commands");
6802
+ this.templatesDir = path19.join(PACKAGE_ROOT, "templates", "commands");
6808
6803
  }
6809
6804
  async ensureInit() {
6810
6805
  if (this._initialized) return;
@@ -13851,7 +13846,7 @@ var init_prompt_builder = __esm({
13851
13846
  * These modules extend the base global CLAUDE.md for complex operations
13852
13847
  */
13853
13848
  async loadModule(moduleName) {
13854
- const modulePath = path28.join(getPackageRoot(), "templates/global/modules", moduleName);
13849
+ const modulePath = path28.join(PACKAGE_ROOT, "templates/global/modules", moduleName);
13855
13850
  return this.getTemplate(modulePath);
13856
13851
  }
13857
13852
  /**
@@ -24764,7 +24759,7 @@ async function run() {
24764
24759
  async function installGeminiRouter() {
24765
24760
  try {
24766
24761
  const geminiCommandsDir = path53.join(os17.homedir(), ".gemini", "commands");
24767
- const routerSource = path53.join(getPackageRoot(), "templates", "commands", "p.toml");
24762
+ const routerSource = path53.join(PACKAGE_ROOT, "templates", "commands", "p.toml");
24768
24763
  const routerDest = path53.join(geminiCommandsDir, "p.toml");
24769
24764
  await fs48.mkdir(geminiCommandsDir, { recursive: true });
24770
24765
  if (await fileExists(routerSource)) {
@@ -24781,7 +24776,7 @@ async function installGeminiGlobalConfig() {
24781
24776
  try {
24782
24777
  const geminiDir = path53.join(os17.homedir(), ".gemini");
24783
24778
  const globalConfigPath = path53.join(geminiDir, "GEMINI.md");
24784
- const templatePath = path53.join(getPackageRoot(), "templates", "global", "GEMINI.md");
24779
+ const templatePath = path53.join(PACKAGE_ROOT, "templates", "global", "GEMINI.md");
24785
24780
  await fs48.mkdir(geminiDir, { recursive: true });
24786
24781
  const templateContent = await fs48.readFile(templatePath, "utf-8");
24787
24782
  let existingContent = "";
@@ -24831,7 +24826,7 @@ async function installAntigravitySkill() {
24831
24826
  const antigravitySkillsDir = path53.join(os17.homedir(), ".gemini", "antigravity", "skills");
24832
24827
  const prjctSkillDir = path53.join(antigravitySkillsDir, "prjct");
24833
24828
  const skillMdPath = path53.join(prjctSkillDir, "SKILL.md");
24834
- const templatePath = path53.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
24829
+ const templatePath = path53.join(PACKAGE_ROOT, "templates", "antigravity", "SKILL.md");
24835
24830
  await fs48.mkdir(prjctSkillDir, { recursive: true });
24836
24831
  const skillExists = await fileExists(skillMdPath);
24837
24832
  if (!await fileExists(templatePath)) {
@@ -24862,8 +24857,8 @@ async function installCursorProject(projectRoot) {
24862
24857
  const rulesDir = path53.join(cursorDir, "rules");
24863
24858
  const commandsDir = path53.join(cursorDir, "commands");
24864
24859
  const routerMdcDest = path53.join(rulesDir, "prjct.mdc");
24865
- const routerMdcSource = path53.join(getPackageRoot(), "templates", "cursor", "router.mdc");
24866
- const cursorCommandsSource = path53.join(getPackageRoot(), "templates", "cursor", "commands");
24860
+ const routerMdcSource = path53.join(PACKAGE_ROOT, "templates", "cursor", "router.mdc");
24861
+ const cursorCommandsSource = path53.join(PACKAGE_ROOT, "templates", "cursor", "commands");
24867
24862
  await fs48.mkdir(rulesDir, { recursive: true });
24868
24863
  await fs48.mkdir(commandsDir, { recursive: true });
24869
24864
  if (await fileExists(routerMdcSource)) {
@@ -24946,13 +24941,8 @@ async function installWindsurfProject(projectRoot) {
24946
24941
  const rulesDir = path53.join(windsurfDir, "rules");
24947
24942
  const workflowsDir = path53.join(windsurfDir, "workflows");
24948
24943
  const routerDest = path53.join(rulesDir, "prjct.md");
24949
- const routerSource = path53.join(getPackageRoot(), "templates", "windsurf", "router.md");
24950
- const windsurfWorkflowsSource = path53.join(
24951
- getPackageRoot(),
24952
- "templates",
24953
- "windsurf",
24954
- "workflows"
24955
- );
24944
+ const routerSource = path53.join(PACKAGE_ROOT, "templates", "windsurf", "router.md");
24945
+ const windsurfWorkflowsSource = path53.join(PACKAGE_ROOT, "templates", "windsurf", "workflows");
24956
24946
  await fs48.mkdir(rulesDir, { recursive: true });
24957
24947
  await fs48.mkdir(workflowsDir, { recursive: true });
24958
24948
  if (await fileExists(routerSource)) {
@@ -25086,7 +25076,7 @@ async function installStatusLine() {
25086
25076
  const prjctLibDir = path53.join(prjctStatusLineDir, "lib");
25087
25077
  const prjctComponentsDir = path53.join(prjctStatusLineDir, "components");
25088
25078
  const prjctConfigPath = path53.join(prjctStatusLineDir, "config.json");
25089
- const assetsDir = path53.join(getPackageRoot(), "assets", "statusline");
25079
+ const assetsDir = path53.join(PACKAGE_ROOT, "assets", "statusline");
25090
25080
  const sourceScript = path53.join(assetsDir, "statusline.sh");
25091
25081
  const sourceThemeDir = path53.join(assetsDir, "themes");
25092
25082
  const sourceLibDir = path53.join(assetsDir, "lib");
@@ -28716,7 +28706,7 @@ var require_package = __commonJS({
28716
28706
  "package.json"(exports, module) {
28717
28707
  module.exports = {
28718
28708
  name: "prjct-cli",
28719
- version: "1.6.11",
28709
+ version: "1.6.12",
28720
28710
  description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
28721
28711
  main: "core/index.ts",
28722
28712
  bin: {
@@ -517,7 +517,7 @@ var PACKAGE_ROOT = getPackageRoot();
517
517
  // core/infrastructure/command-installer.ts
518
518
  async function loadModuleConfig() {
519
519
  try {
520
- const configPath = import_node_path4.default.join(getPackageRoot(), "templates/global/modules/module-config.json");
520
+ const configPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/modules/module-config.json");
521
521
  const content = await import_promises3.default.readFile(configPath, "utf-8");
522
522
  return JSON.parse(content);
523
523
  } catch {
@@ -527,9 +527,9 @@ async function loadModuleConfig() {
527
527
  __name(loadModuleConfig, "loadModuleConfig");
528
528
  async function composeGlobalTemplate(profile) {
529
529
  const config = await loadModuleConfig();
530
- const modulesDir = import_node_path4.default.join(getPackageRoot(), "templates/global/modules");
530
+ const modulesDir = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/modules");
531
531
  if (!config) {
532
- const legacyPath = import_node_path4.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
532
+ const legacyPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
533
533
  return import_promises3.default.readFile(legacyPath, "utf-8");
534
534
  }
535
535
  const profileName = profile || config.default;
@@ -537,7 +537,7 @@ async function composeGlobalTemplate(profile) {
537
537
  if (!selectedProfile) {
538
538
  const defaultProfile = config.profiles[config.default];
539
539
  if (!defaultProfile) {
540
- const legacyPath = import_node_path4.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
540
+ const legacyPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
541
541
  return import_promises3.default.readFile(legacyPath, "utf-8");
542
542
  }
543
543
  }
@@ -569,7 +569,7 @@ __name(getProfileForCommand, "getProfileForCommand");
569
569
  async function installDocs() {
570
570
  try {
571
571
  const docsDir = import_node_path4.default.join(import_node_os3.default.homedir(), ".prjct-cli", "docs");
572
- const templateDocsDir = import_node_path4.default.join(getPackageRoot(), "templates/global/docs");
572
+ const templateDocsDir = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/docs");
573
573
  await import_promises3.default.mkdir(docsDir, { recursive: true });
574
574
  const docFiles = await import_promises3.default.readdir(templateDocsDir);
575
575
  for (const file of docFiles) {
@@ -601,12 +601,7 @@ async function installGlobalConfig() {
601
601
  try {
602
602
  await import_promises3.default.mkdir(activeProvider.configDir, { recursive: true });
603
603
  const globalConfigPath = import_node_path4.default.join(activeProvider.configDir, activeProvider.contextFile);
604
- const templatePath = import_node_path4.default.join(
605
- getPackageRoot(),
606
- "templates",
607
- "global",
608
- activeProvider.contextFile
609
- );
604
+ const templatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates", "global", activeProvider.contextFile);
610
605
  let templateContent = "";
611
606
  try {
612
607
  templateContent = await import_promises3.default.readFile(templatePath, "utf-8");
@@ -615,11 +610,11 @@ async function installGlobalConfig() {
615
610
  try {
616
611
  templateContent = await composeGlobalTemplate("standard");
617
612
  } catch {
618
- const fallbackTemplatePath = import_node_path4.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
613
+ const fallbackTemplatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
619
614
  templateContent = await import_promises3.default.readFile(fallbackTemplatePath, "utf-8");
620
615
  }
621
616
  } else {
622
- const fallbackTemplatePath = import_node_path4.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
617
+ const fallbackTemplatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
623
618
  templateContent = await import_promises3.default.readFile(fallbackTemplatePath, "utf-8");
624
619
  if (providerName === "gemini") {
625
620
  templateContent = templateContent.replace(/Claude/g, "Gemini");
@@ -697,7 +692,7 @@ var CommandInstaller = class {
697
692
  _initialized = false;
698
693
  constructor() {
699
694
  this.homeDir = import_node_os3.default.homedir();
700
- this.templatesDir = import_node_path4.default.join(getPackageRoot(), "templates", "commands");
695
+ this.templatesDir = import_node_path4.default.join(PACKAGE_ROOT, "templates", "commands");
701
696
  }
702
697
  async ensureInit() {
703
698
  if (this._initialized) return;
@@ -838,7 +838,7 @@ var import_node_os3 = __toESM(require("node:os"));
838
838
  var import_node_path4 = __toESM(require("node:path"));
839
839
  async function loadModuleConfig() {
840
840
  try {
841
- const configPath = import_node_path4.default.join(getPackageRoot(), "templates/global/modules/module-config.json");
841
+ const configPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/modules/module-config.json");
842
842
  const content = await import_promises3.default.readFile(configPath, "utf-8");
843
843
  return JSON.parse(content);
844
844
  } catch {
@@ -848,9 +848,9 @@ async function loadModuleConfig() {
848
848
  __name(loadModuleConfig, "loadModuleConfig");
849
849
  async function composeGlobalTemplate(profile) {
850
850
  const config = await loadModuleConfig();
851
- const modulesDir = import_node_path4.default.join(getPackageRoot(), "templates/global/modules");
851
+ const modulesDir = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/modules");
852
852
  if (!config) {
853
- const legacyPath = import_node_path4.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
853
+ const legacyPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
854
854
  return import_promises3.default.readFile(legacyPath, "utf-8");
855
855
  }
856
856
  const profileName = profile || config.default;
@@ -858,7 +858,7 @@ async function composeGlobalTemplate(profile) {
858
858
  if (!selectedProfile) {
859
859
  const defaultProfile = config.profiles[config.default];
860
860
  if (!defaultProfile) {
861
- const legacyPath = import_node_path4.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
861
+ const legacyPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
862
862
  return import_promises3.default.readFile(legacyPath, "utf-8");
863
863
  }
864
864
  }
@@ -884,7 +884,7 @@ __name(composeGlobalTemplate, "composeGlobalTemplate");
884
884
  async function installDocs() {
885
885
  try {
886
886
  const docsDir = import_node_path4.default.join(import_node_os3.default.homedir(), ".prjct-cli", "docs");
887
- const templateDocsDir = import_node_path4.default.join(getPackageRoot(), "templates/global/docs");
887
+ const templateDocsDir = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/docs");
888
888
  await import_promises3.default.mkdir(docsDir, { recursive: true });
889
889
  const docFiles = await import_promises3.default.readdir(templateDocsDir);
890
890
  for (const file of docFiles) {
@@ -916,12 +916,7 @@ async function installGlobalConfig() {
916
916
  try {
917
917
  await import_promises3.default.mkdir(activeProvider.configDir, { recursive: true });
918
918
  const globalConfigPath = import_node_path4.default.join(activeProvider.configDir, activeProvider.contextFile);
919
- const templatePath = import_node_path4.default.join(
920
- getPackageRoot(),
921
- "templates",
922
- "global",
923
- activeProvider.contextFile
924
- );
919
+ const templatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates", "global", activeProvider.contextFile);
925
920
  let templateContent = "";
926
921
  try {
927
922
  templateContent = await import_promises3.default.readFile(templatePath, "utf-8");
@@ -930,11 +925,11 @@ async function installGlobalConfig() {
930
925
  try {
931
926
  templateContent = await composeGlobalTemplate("standard");
932
927
  } catch {
933
- const fallbackTemplatePath = import_node_path4.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
928
+ const fallbackTemplatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
934
929
  templateContent = await import_promises3.default.readFile(fallbackTemplatePath, "utf-8");
935
930
  }
936
931
  } else {
937
- const fallbackTemplatePath = import_node_path4.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
932
+ const fallbackTemplatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
938
933
  templateContent = await import_promises3.default.readFile(fallbackTemplatePath, "utf-8");
939
934
  if (providerName === "gemini") {
940
935
  templateContent = templateContent.replace(/Claude/g, "Gemini");
@@ -1012,7 +1007,7 @@ var CommandInstaller = class {
1012
1007
  _initialized = false;
1013
1008
  constructor() {
1014
1009
  this.homeDir = import_node_os3.default.homedir();
1015
- this.templatesDir = import_node_path4.default.join(getPackageRoot(), "templates", "commands");
1010
+ this.templatesDir = import_node_path4.default.join(PACKAGE_ROOT, "templates", "commands");
1016
1011
  }
1017
1012
  async ensureInit() {
1018
1013
  if (this._initialized) return;
@@ -1626,7 +1621,7 @@ __name(run, "run");
1626
1621
  async function installGeminiRouter() {
1627
1622
  try {
1628
1623
  const geminiCommandsDir = import_node_path6.default.join(import_node_os5.default.homedir(), ".gemini", "commands");
1629
- const routerSource = import_node_path6.default.join(getPackageRoot(), "templates", "commands", "p.toml");
1624
+ const routerSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "commands", "p.toml");
1630
1625
  const routerDest = import_node_path6.default.join(geminiCommandsDir, "p.toml");
1631
1626
  await import_promises5.default.mkdir(geminiCommandsDir, { recursive: true });
1632
1627
  if (await fileExists(routerSource)) {
@@ -1644,7 +1639,7 @@ async function installGeminiGlobalConfig() {
1644
1639
  try {
1645
1640
  const geminiDir = import_node_path6.default.join(import_node_os5.default.homedir(), ".gemini");
1646
1641
  const globalConfigPath = import_node_path6.default.join(geminiDir, "GEMINI.md");
1647
- const templatePath = import_node_path6.default.join(getPackageRoot(), "templates", "global", "GEMINI.md");
1642
+ const templatePath = import_node_path6.default.join(PACKAGE_ROOT, "templates", "global", "GEMINI.md");
1648
1643
  await import_promises5.default.mkdir(geminiDir, { recursive: true });
1649
1644
  const templateContent = await import_promises5.default.readFile(templatePath, "utf-8");
1650
1645
  let existingContent = "";
@@ -1695,7 +1690,7 @@ async function installAntigravitySkill() {
1695
1690
  const antigravitySkillsDir = import_node_path6.default.join(import_node_os5.default.homedir(), ".gemini", "antigravity", "skills");
1696
1691
  const prjctSkillDir = import_node_path6.default.join(antigravitySkillsDir, "prjct");
1697
1692
  const skillMdPath = import_node_path6.default.join(prjctSkillDir, "SKILL.md");
1698
- const templatePath = import_node_path6.default.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
1693
+ const templatePath = import_node_path6.default.join(PACKAGE_ROOT, "templates", "antigravity", "SKILL.md");
1699
1694
  await import_promises5.default.mkdir(prjctSkillDir, { recursive: true });
1700
1695
  const skillExists = await fileExists(skillMdPath);
1701
1696
  if (!await fileExists(templatePath)) {
@@ -1728,8 +1723,8 @@ async function installCursorProject(projectRoot) {
1728
1723
  const rulesDir = import_node_path6.default.join(cursorDir, "rules");
1729
1724
  const commandsDir = import_node_path6.default.join(cursorDir, "commands");
1730
1725
  const routerMdcDest = import_node_path6.default.join(rulesDir, "prjct.mdc");
1731
- const routerMdcSource = import_node_path6.default.join(getPackageRoot(), "templates", "cursor", "router.mdc");
1732
- const cursorCommandsSource = import_node_path6.default.join(getPackageRoot(), "templates", "cursor", "commands");
1726
+ const routerMdcSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "cursor", "router.mdc");
1727
+ const cursorCommandsSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "cursor", "commands");
1733
1728
  await import_promises5.default.mkdir(rulesDir, { recursive: true });
1734
1729
  await import_promises5.default.mkdir(commandsDir, { recursive: true });
1735
1730
  if (await fileExists(routerMdcSource)) {
@@ -1816,13 +1811,8 @@ async function installWindsurfProject(projectRoot) {
1816
1811
  const rulesDir = import_node_path6.default.join(windsurfDir, "rules");
1817
1812
  const workflowsDir = import_node_path6.default.join(windsurfDir, "workflows");
1818
1813
  const routerDest = import_node_path6.default.join(rulesDir, "prjct.md");
1819
- const routerSource = import_node_path6.default.join(getPackageRoot(), "templates", "windsurf", "router.md");
1820
- const windsurfWorkflowsSource = import_node_path6.default.join(
1821
- getPackageRoot(),
1822
- "templates",
1823
- "windsurf",
1824
- "workflows"
1825
- );
1814
+ const routerSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "windsurf", "router.md");
1815
+ const windsurfWorkflowsSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "windsurf", "workflows");
1826
1816
  await import_promises5.default.mkdir(rulesDir, { recursive: true });
1827
1817
  await import_promises5.default.mkdir(workflowsDir, { recursive: true });
1828
1818
  if (await fileExists(routerSource)) {
@@ -1962,7 +1952,7 @@ async function installStatusLine() {
1962
1952
  const prjctLibDir = import_node_path6.default.join(prjctStatusLineDir, "lib");
1963
1953
  const prjctComponentsDir = import_node_path6.default.join(prjctStatusLineDir, "components");
1964
1954
  const prjctConfigPath = import_node_path6.default.join(prjctStatusLineDir, "config.json");
1965
- const assetsDir = import_node_path6.default.join(getPackageRoot(), "assets", "statusline");
1955
+ const assetsDir = import_node_path6.default.join(PACKAGE_ROOT, "assets", "statusline");
1966
1956
  const sourceScript = import_node_path6.default.join(assetsDir, "statusline.sh");
1967
1957
  const sourceThemeDir = import_node_path6.default.join(assetsDir, "themes");
1968
1958
  const sourceLibDir = import_node_path6.default.join(assetsDir, "lib");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "1.6.11",
3
+ "version": "1.6.12",
4
4
  "description": "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
5
5
  "main": "core/index.ts",
6
6
  "bin": {