prjct-cli 1.5.1 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,10 +16,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
16
16
  if (typeof require !== "undefined") return require.apply(this, arguments);
17
17
  throw Error('Dynamic require of "' + x + '" is not supported');
18
18
  });
19
- var __glob = (map) => (path62) => {
20
- var fn = map[path62];
19
+ var __glob = (map) => (path64) => {
20
+ var fn = map[path64];
21
21
  if (fn) return fn();
22
- throw new Error("Module not found in bundle: " + path62);
22
+ throw new Error("Module not found in bundle: " + path64);
23
23
  };
24
24
  var __esm = (fn, res) => function __init() {
25
25
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -2390,7 +2390,7 @@ var init_output = __esm({
2390
2390
  }, "truncate");
2391
2391
  __name(limitLines, "limitLines");
2392
2392
  __name(formatForHuman, "formatForHuman");
2393
- clear = /* @__PURE__ */ __name(() => process.stdout.write(`\r${" ".repeat(80)}\r`), "clear");
2393
+ clear = /* @__PURE__ */ __name(() => process.stdout.isTTY ? process.stdout.write(`\r${" ".repeat(80)}\r`) : true, "clear");
2394
2394
  out = {
2395
2395
  // Branding: Show header at start
2396
2396
  start() {
@@ -2403,9 +2403,15 @@ var init_output = __esm({
2403
2403
  return this;
2404
2404
  },
2405
2405
  // Branded spinner: prjct message...
2406
+ // In non-TTY (CI, Claude Code), prints a static line instead of animating
2406
2407
  spin(msg) {
2407
2408
  if (quietMode) return this;
2408
2409
  this.stop();
2410
+ if (!process.stdout.isTTY) {
2411
+ process.stdout.write(`${branding_default.cli.spin(0, truncate(msg, 45))}
2412
+ `);
2413
+ return this;
2414
+ }
2409
2415
  interval = setInterval(() => {
2410
2416
  process.stdout.write(`\r${branding_default.cli.spin(frame++, truncate(msg, 45))}`);
2411
2417
  }, SPEED);
@@ -2549,6 +2555,11 @@ ${chalk2.bold(title)}`);
2549
2555
  if (quietMode) return this;
2550
2556
  this.stop();
2551
2557
  const counter = chalk2.dim(`[${current}/${total}]`);
2558
+ if (!process.stdout.isTTY) {
2559
+ process.stdout.write(`${branding_default.cli.spin(0, `${counter} ${truncate(msg, 35)}`)}
2560
+ `);
2561
+ return this;
2562
+ }
2552
2563
  interval = setInterval(() => {
2553
2564
  process.stdout.write(`\r${branding_default.cli.spin(frame++, `${counter} ${truncate(msg, 35)}`)}`);
2554
2565
  }, SPEED);
@@ -2563,6 +2574,11 @@ ${chalk2.bold(title)}`);
2563
2574
  const empty = 10 - filled;
2564
2575
  const bar = chalk2.cyan("\u2588".repeat(filled)) + chalk2.dim("\u2591".repeat(empty));
2565
2576
  const text = msg ? ` ${truncate(msg, 25)}` : "";
2577
+ if (!process.stdout.isTTY) {
2578
+ process.stdout.write(`${branding_default.cli.spin(0, `[${bar}] ${percent}%${text}`)}
2579
+ `);
2580
+ return this;
2581
+ }
2566
2582
  interval = setInterval(() => {
2567
2583
  process.stdout.write(`\r${branding_default.cli.spin(frame++, `[${bar}] ${percent}%${text}`)}`);
2568
2584
  }, SPEED);
@@ -4259,8 +4275,8 @@ function tryResolve(basePath, projectPath) {
4259
4275
  for (const ext of extensions) {
4260
4276
  const fullPath = basePath + ext;
4261
4277
  try {
4262
- const fs49 = __require("node:fs");
4263
- if (fs49.existsSync(fullPath) && fs49.statSync(fullPath).isFile()) {
4278
+ const fs51 = __require("node:fs");
4279
+ if (fs51.existsSync(fullPath) && fs51.statSync(fullPath).isFile()) {
4264
4280
  return path13.relative(projectPath, fullPath);
4265
4281
  }
4266
4282
  } catch {
@@ -4753,6 +4769,8 @@ var init_token_counter = __esm({
4753
4769
  // $1/$5 per M
4754
4770
  "claude-opus-4": { input: 0.015, output: 0.075 },
4755
4771
  // $15/$75 per M (legacy)
4772
+ "claude-opus-4-6": { input: 0.015, output: 0.075 },
4773
+ // $15/$75 per M
4756
4774
  // OpenAI
4757
4775
  "gpt-4o": { input: 25e-4, output: 0.01 },
4758
4776
  // $2.50/$10 per M
@@ -4771,6 +4789,7 @@ var init_token_counter = __esm({
4771
4789
  BREAKDOWN_MODELS = [
4772
4790
  "claude-sonnet-4.5",
4773
4791
  "claude-opus-4.5",
4792
+ "claude-opus-4-6",
4774
4793
  "gpt-4o",
4775
4794
  "gemini-1.5-pro"
4776
4795
  ];
@@ -5443,11 +5462,11 @@ async function runSignaturesTool(args2, projectPath) {
5443
5462
  }
5444
5463
  };
5445
5464
  }
5446
- const fs49 = await import("node:fs/promises");
5447
- const path62 = await import("node:path");
5448
- const fullPath = path62.isAbsolute(filePath) ? filePath : path62.join(projectPath, filePath);
5465
+ const fs51 = await import("node:fs/promises");
5466
+ const path64 = await import("node:path");
5467
+ const fullPath = path64.isAbsolute(filePath) ? filePath : path64.join(projectPath, filePath);
5449
5468
  try {
5450
- const stat = await fs49.stat(fullPath);
5469
+ const stat = await fs51.stat(fullPath);
5451
5470
  if (stat.isDirectory()) {
5452
5471
  const results = await extractDirectorySignatures(filePath, projectPath, {
5453
5472
  recursive: args2.includes("--recursive") || args2.includes("-r")
@@ -5514,11 +5533,11 @@ async function runSummaryTool(args2, projectPath) {
5514
5533
  }
5515
5534
  };
5516
5535
  }
5517
- const fs49 = await import("node:fs/promises");
5518
- const path62 = await import("node:path");
5519
- const fullPath = path62.isAbsolute(targetPath) ? targetPath : path62.join(projectPath, targetPath);
5536
+ const fs51 = await import("node:fs/promises");
5537
+ const path64 = await import("node:path");
5538
+ const fullPath = path64.isAbsolute(targetPath) ? targetPath : path64.join(projectPath, targetPath);
5520
5539
  try {
5521
- const stat = await fs49.stat(fullPath);
5540
+ const stat = await fs51.stat(fullPath);
5522
5541
  if (stat.isDirectory()) {
5523
5542
  const results = await summarizeDirectory(targetPath, projectPath, {
5524
5543
  recursive: args2.includes("--recursive") || args2.includes("-r")
@@ -12246,18 +12265,24 @@ var init_template_loader = __esm({
12246
12265
  });
12247
12266
 
12248
12267
  // core/agentic/orchestrator-executor.ts
12268
+ import { exec as execCallback5 } from "node:child_process";
12249
12269
  import fs26 from "node:fs/promises";
12250
12270
  import os8 from "node:os";
12251
12271
  import path25 from "node:path";
12252
- var DOMAIN_KEYWORDS2, DOMAIN_DEPENDENCY_ORDER, OrchestratorExecutor, orchestratorExecutor, orchestrator_executor_default;
12272
+ import { promisify as promisify7 } from "node:util";
12273
+ var execAsync3, DOMAIN_KEYWORDS2, DOMAIN_DEPENDENCY_ORDER, OrchestratorExecutor, orchestratorExecutor, orchestrator_executor_default;
12253
12274
  var init_orchestrator_executor = __esm({
12254
12275
  "core/agentic/orchestrator-executor.ts"() {
12255
12276
  "use strict";
12277
+ init_files_tool();
12278
+ init_recent_tool();
12279
+ init_signatures_tool();
12256
12280
  init_config_manager();
12257
12281
  init_path_manager();
12258
12282
  init_storage2();
12259
12283
  init_fs();
12260
12284
  init_template_loader();
12285
+ execAsync3 = promisify7(execCallback5);
12261
12286
  DOMAIN_KEYWORDS2 = {
12262
12287
  database: [
12263
12288
  "database",
@@ -12408,6 +12433,7 @@ var init_orchestrator_executor = __esm({
12408
12433
  const { domains, primary } = await this.detectDomains(taskDescription, projectId, repoAnalysis);
12409
12434
  const agents = await this.loadAgents(domains, projectId);
12410
12435
  const skills = await this.loadSkills(agents);
12436
+ const realContext = await this.gatherRealContext(taskDescription, projectPath);
12411
12437
  const requiresFragmentation = this.shouldFragment(domains, taskDescription);
12412
12438
  let subtasks = null;
12413
12439
  if (requiresFragmentation && command === "task") {
@@ -12424,9 +12450,87 @@ var init_orchestrator_executor = __esm({
12424
12450
  id: projectId,
12425
12451
  ecosystem: repoAnalysis?.ecosystem || "unknown",
12426
12452
  conventions: repoAnalysis?.conventions || []
12427
- }
12453
+ },
12454
+ realContext
12428
12455
  };
12429
12456
  }
12457
+ /**
12458
+ * Gather real codebase context proactively.
12459
+ *
12460
+ * Calls existing context tools (files-tool, recent-tool, signatures-tool)
12461
+ * to build a briefing so the agent doesn't need to explore first.
12462
+ */
12463
+ async gatherRealContext(taskDescription, projectPath) {
12464
+ try {
12465
+ const [gitResult, filesResult, recentResult] = await Promise.all([
12466
+ this.getGitState(projectPath),
12467
+ findRelevantFiles(taskDescription, projectPath, { maxFiles: 10, minScore: 0.15 }),
12468
+ getRecentFiles(projectPath, { commits: 10, maxFiles: 10 })
12469
+ ]);
12470
+ const topFiles = filesResult.files.slice(0, 3);
12471
+ const signatureResults = await Promise.all(
12472
+ topFiles.map(async (f) => {
12473
+ try {
12474
+ const result = await extractSignatures(f.path, projectPath);
12475
+ if (result.signatures.length === 0) return null;
12476
+ const sigContent = result.signatures.map((s) => `${s.exported ? "export " : ""}${s.type} ${s.name}: ${s.signature}`).join("\n");
12477
+ return { path: f.path, content: sigContent };
12478
+ } catch {
12479
+ return null;
12480
+ }
12481
+ })
12482
+ );
12483
+ return {
12484
+ gitBranch: gitResult.branch,
12485
+ gitStatus: gitResult.status,
12486
+ relevantFiles: filesResult.files.map((f) => ({
12487
+ path: f.path,
12488
+ score: Math.round(f.score * 100),
12489
+ reason: f.reasons.join(", ")
12490
+ })),
12491
+ recentFiles: recentResult.hotFiles.slice(0, 5).map((f) => ({
12492
+ path: f.path,
12493
+ lastChanged: f.lastChanged,
12494
+ changes: f.changes
12495
+ })),
12496
+ signatures: signatureResults.filter(
12497
+ (s) => s !== null
12498
+ )
12499
+ };
12500
+ } catch {
12501
+ return void 0;
12502
+ }
12503
+ }
12504
+ /**
12505
+ * Get current git state (branch + short status)
12506
+ */
12507
+ async getGitState(projectPath) {
12508
+ try {
12509
+ const [branchResult, statusResult] = await Promise.all([
12510
+ execAsync3("git branch --show-current", { cwd: projectPath }),
12511
+ execAsync3("git status --porcelain", { cwd: projectPath })
12512
+ ]);
12513
+ const branch = branchResult.stdout.trim() || "main";
12514
+ const lines = statusResult.stdout.trim().split("\n").filter(Boolean);
12515
+ let modified = 0;
12516
+ let untracked = 0;
12517
+ let staged = 0;
12518
+ for (const line of lines) {
12519
+ const code = line.substring(0, 2);
12520
+ if (code.startsWith("??")) untracked++;
12521
+ else if (code[0] !== " " && code[0] !== "?") staged++;
12522
+ else modified++;
12523
+ }
12524
+ const parts = [];
12525
+ if (staged > 0) parts.push(`${staged} staged`);
12526
+ if (modified > 0) parts.push(`${modified} modified`);
12527
+ if (untracked > 0) parts.push(`${untracked} untracked`);
12528
+ const status = parts.length > 0 ? parts.join(", ") : "clean";
12529
+ return { branch, status };
12530
+ } catch {
12531
+ return { branch: "unknown", status: "git unavailable" };
12532
+ }
12533
+ }
12430
12534
  /**
12431
12535
  * Load repo-analysis.json for project context
12432
12536
  */
@@ -12527,7 +12631,9 @@ var init_orchestrator_executor = __esm({
12527
12631
  domain,
12528
12632
  content: body,
12529
12633
  skills: frontmatter.skills || [],
12530
- filePath
12634
+ filePath,
12635
+ effort: frontmatter.effort,
12636
+ model: frontmatter.model
12531
12637
  };
12532
12638
  } catch {
12533
12639
  }
@@ -12560,13 +12666,15 @@ var init_orchestrator_executor = __esm({
12560
12666
  */
12561
12667
  async loadSkills(agents) {
12562
12668
  const skillsDir = path25.join(os8.homedir(), ".claude", "skills");
12563
- const uniqueSkillNames = /* @__PURE__ */ new Set();
12669
+ const skillToAgents = /* @__PURE__ */ new Map();
12564
12670
  for (const agent of agents) {
12565
12671
  for (const skillName of agent.skills) {
12566
- uniqueSkillNames.add(skillName);
12672
+ const existing = skillToAgents.get(skillName) || [];
12673
+ existing.push(agent.name);
12674
+ skillToAgents.set(skillName, existing);
12567
12675
  }
12568
12676
  }
12569
- const skillPromises = Array.from(uniqueSkillNames).map(
12677
+ const skillPromises = Array.from(skillToAgents.keys()).map(
12570
12678
  async (skillName) => {
12571
12679
  const flatPath = path25.join(skillsDir, `${skillName}.md`);
12572
12680
  const subdirPath = path25.join(skillsDir, skillName, "SKILL.md");
@@ -12578,6 +12686,10 @@ var init_orchestrator_executor = __esm({
12578
12686
  const content = await fs26.readFile(flatPath, "utf-8");
12579
12687
  return { name: skillName, content, filePath: flatPath };
12580
12688
  } catch {
12689
+ const agentNames = skillToAgents.get(skillName) || [];
12690
+ console.warn(
12691
+ `\u26A0 Skill "${skillName}" not installed (needed by: ${agentNames.join(", ")}). Run \`prjct sync\` to auto-install.`
12692
+ );
12581
12693
  return null;
12582
12694
  }
12583
12695
  }
@@ -13898,6 +14010,10 @@ Apply specialized expertise. Read agent file for details if needed.
13898
14010
  parts.push("### LOADED AGENTS (Project-Specific Specialists)\n\n");
13899
14011
  for (const agent2 of orchestratorContext.agents) {
13900
14012
  parts.push(`#### Agent: ${agent2.name} (${agent2.domain})
14013
+ `);
14014
+ if (agent2.effort) parts.push(`Effort: ${agent2.effort}
14015
+ `);
14016
+ if (agent2.model) parts.push(`Model: ${agent2.model}
13901
14017
  `);
13902
14018
  if (agent2.skills.length > 0) {
13903
14019
  parts.push(`Skills: ${agent2.skills.join(", ")}
@@ -13917,12 +14033,47 @@ ${truncatedContent}
13917
14033
  for (const skill of orchestratorContext.skills) {
13918
14034
  parts.push(`#### Skill: ${skill.name}
13919
14035
  `);
13920
- const truncatedContent = skill.content.length > 1e3 ? `${skill.content.substring(0, 1e3)}
14036
+ const truncatedContent = skill.content.length > 2e3 ? `${skill.content.substring(0, 2e3)}
13921
14037
  ... (truncated)` : skill.content;
13922
14038
  parts.push(`\`\`\`markdown
13923
14039
  ${truncatedContent}
13924
14040
  \`\`\`
13925
14041
 
14042
+ `);
14043
+ }
14044
+ }
14045
+ if (orchestratorContext.realContext) {
14046
+ const rc = orchestratorContext.realContext;
14047
+ parts.push("### CODEBASE CONTEXT (Real \u2014 gathered proactively)\n\n");
14048
+ parts.push(`**Git State**: Branch \`${rc.gitBranch}\` | ${rc.gitStatus}
14049
+
14050
+ `);
14051
+ if (rc.relevantFiles.length > 0) {
14052
+ parts.push("**Relevant Files** (scored by task relevance):\n");
14053
+ parts.push("| Score | File | Why |\n");
14054
+ parts.push("|-------|------|-----|\n");
14055
+ for (const f of rc.relevantFiles.slice(0, 8)) {
14056
+ parts.push(`| ${f.score} | ${f.path} | ${f.reason} |
14057
+ `);
14058
+ }
14059
+ parts.push("\n");
14060
+ }
14061
+ if (rc.signatures.length > 0) {
14062
+ parts.push("**Code Signatures** (top files):\n");
14063
+ for (const sig of rc.signatures) {
14064
+ parts.push(`\`\`\`typescript
14065
+ // ${sig.path}
14066
+ ${sig.content}
14067
+ \`\`\`
14068
+ `);
14069
+ }
14070
+ parts.push("\n");
14071
+ }
14072
+ if (rc.recentFiles.length > 0) {
14073
+ parts.push("**Recently Changed**: ");
14074
+ const recentSummary = rc.recentFiles.slice(0, 5).map((f) => `${f.path} (${f.lastChanged})`).join(", ");
14075
+ parts.push(`${recentSummary}
14076
+
13926
14077
  `);
13927
14078
  }
13928
14079
  }
@@ -14401,12 +14552,12 @@ When fragmenting tasks:
14401
14552
  // core/agentic/tool-registry.ts
14402
14553
  import { exec as exec7 } from "node:child_process";
14403
14554
  import fs29 from "node:fs/promises";
14404
- import { promisify as promisify7 } from "node:util";
14405
- var execAsync3, toolRegistry, tool_registry_default;
14555
+ import { promisify as promisify8 } from "node:util";
14556
+ var execAsync4, toolRegistry, tool_registry_default;
14406
14557
  var init_tool_registry = __esm({
14407
14558
  "core/agentic/tool-registry.ts"() {
14408
14559
  "use strict";
14409
- execAsync3 = promisify7(exec7);
14560
+ execAsync4 = promisify8(exec7);
14410
14561
  toolRegistry = {
14411
14562
  tools: /* @__PURE__ */ new Map(),
14412
14563
  /**
@@ -14461,7 +14612,7 @@ var init_tool_registry = __esm({
14461
14612
  "Bash",
14462
14613
  async (command) => {
14463
14614
  try {
14464
- const { stdout, stderr } = await execAsync3(command);
14615
+ const { stdout, stderr } = await execAsync4(command);
14465
14616
  return { stdout, stderr };
14466
14617
  } catch (error) {
14467
14618
  const err = error;
@@ -15567,11 +15718,12 @@ var init_breakdown_service = __esm({
15567
15718
  });
15568
15719
 
15569
15720
  // core/services/context-selector.ts
15570
- var DOMAIN_KEYWORDS3, ContextSelector, contextSelector;
15721
+ var DEFAULT_TOKEN_BUDGET, DOMAIN_KEYWORDS3, ContextSelector, contextSelector;
15571
15722
  var init_context_selector = __esm({
15572
15723
  "core/services/context-selector.ts"() {
15573
15724
  "use strict";
15574
15725
  init_index_storage();
15726
+ DEFAULT_TOKEN_BUDGET = 8e4;
15575
15727
  DOMAIN_KEYWORDS3 = {
15576
15728
  payments: [
15577
15729
  "payment",
@@ -15694,7 +15846,7 @@ var init_context_selector = __esm({
15694
15846
  const maxFiles = options.maxFiles || 50;
15695
15847
  const minScore = options.minScore || 30;
15696
15848
  const includeGeneral = options.includeGeneral !== false;
15697
- const tokenBudget = options.tokenBudget || 5e4;
15849
+ const tokenBudget = options.tokenBudget || DEFAULT_TOKEN_BUDGET;
15698
15850
  const [index, domainsData, categoriesCache] = await Promise.all([
15699
15851
  indexStorage.readIndex(projectId),
15700
15852
  indexStorage.readDomains(projectId),
@@ -15820,7 +15972,7 @@ var init_context_selector = __esm({
15820
15972
  fallbackSelection(files, options) {
15821
15973
  const maxFiles = options.maxFiles || 50;
15822
15974
  const minScore = options.minScore || 30;
15823
- const tokenBudget = options.tokenBudget || 5e4;
15975
+ const tokenBudget = options.tokenBudget || DEFAULT_TOKEN_BUDGET;
15824
15976
  const filteredFiles = files.filter((f) => f.score >= minScore).sort((a, b) => b.score - a.score);
15825
15977
  let estimatedTokens = 0;
15826
15978
  const selectedFiles = [];
@@ -16597,14 +16749,14 @@ ${hints}`
16597
16749
 
16598
16750
  // core/services/git-analyzer.ts
16599
16751
  import { exec as exec8 } from "node:child_process";
16600
- import { promisify as promisify8 } from "node:util";
16601
- var execAsync4;
16752
+ import { promisify as promisify9 } from "node:util";
16753
+ var execAsync5;
16602
16754
  var init_git_analyzer = __esm({
16603
16755
  "core/services/git-analyzer.ts"() {
16604
16756
  "use strict";
16605
16757
  init_constants();
16606
16758
  init_dependency_validator();
16607
- execAsync4 = promisify8(exec8);
16759
+ execAsync5 = promisify9(exec8);
16608
16760
  }
16609
16761
  });
16610
16762
 
@@ -17280,15 +17432,15 @@ ${agent.description}`;
17280
17432
 
17281
17433
  // core/services/project-index.ts
17282
17434
  import { exec as exec9 } from "node:child_process";
17283
- import { promisify as promisify9 } from "node:util";
17284
- var execAsync5;
17435
+ import { promisify as promisify10 } from "node:util";
17436
+ var execAsync6;
17285
17437
  var init_project_index = __esm({
17286
17438
  "core/services/project-index.ts"() {
17287
17439
  "use strict";
17288
17440
  init_index_storage();
17289
17441
  init_date_helper();
17290
17442
  init_file_scorer();
17291
- execAsync5 = promisify9(exec9);
17443
+ execAsync6 = promisify10(exec9);
17292
17444
  }
17293
17445
  });
17294
17446
 
@@ -17761,16 +17913,16 @@ var init_onboarding = __esm({
17761
17913
  * Detect project type from file system
17762
17914
  */
17763
17915
  async detectProjectType() {
17764
- const fs49 = await import("node:fs/promises");
17765
- const path62 = await import("node:path");
17916
+ const fs51 = await import("node:fs/promises");
17917
+ const path64 = await import("node:path");
17766
17918
  try {
17767
- const files = await fs49.readdir(this.projectPath);
17919
+ const files = await fs51.readdir(this.projectPath);
17768
17920
  if (files.includes("turbo.json") || files.includes("lerna.json") || files.includes("nx.json")) {
17769
17921
  return "monorepo";
17770
17922
  }
17771
17923
  if (files.includes("package.json")) {
17772
- const pkgPath = path62.join(this.projectPath, "package.json");
17773
- const pkgContent = await fs49.readFile(pkgPath, "utf-8");
17924
+ const pkgPath = path64.join(this.projectPath, "package.json");
17925
+ const pkgContent = await fs51.readFile(pkgPath, "utf-8");
17774
17926
  const pkg = JSON.parse(pkgContent);
17775
17927
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
17776
17928
  if (pkg.bin) return "cli-tool";
@@ -17806,32 +17958,32 @@ var init_onboarding = __esm({
17806
17958
  * Detect installed AI agents from config files
17807
17959
  */
17808
17960
  async detectInstalledAgents() {
17809
- const fs49 = await import("node:fs/promises");
17810
- const path62 = await import("node:path");
17811
- const os17 = await import("node:os");
17961
+ const fs51 = await import("node:fs/promises");
17962
+ const path64 = await import("node:path");
17963
+ const os20 = await import("node:os");
17812
17964
  const agents = [];
17813
17965
  try {
17814
- await fs49.access(path62.join(os17.homedir(), ".claude"));
17966
+ await fs51.access(path64.join(os20.homedir(), ".claude"));
17815
17967
  agents.push("claude");
17816
17968
  } catch {
17817
17969
  }
17818
17970
  try {
17819
- await fs49.access(path62.join(this.projectPath, ".cursorrules"));
17971
+ await fs51.access(path64.join(this.projectPath, ".cursorrules"));
17820
17972
  agents.push("cursor");
17821
17973
  } catch {
17822
17974
  }
17823
17975
  try {
17824
- await fs49.access(path62.join(this.projectPath, ".windsurfrules"));
17976
+ await fs51.access(path64.join(this.projectPath, ".windsurfrules"));
17825
17977
  agents.push("windsurf");
17826
17978
  } catch {
17827
17979
  }
17828
17980
  try {
17829
- await fs49.access(path62.join(this.projectPath, ".github", "copilot-instructions.md"));
17981
+ await fs51.access(path64.join(this.projectPath, ".github", "copilot-instructions.md"));
17830
17982
  agents.push("copilot");
17831
17983
  } catch {
17832
17984
  }
17833
17985
  try {
17834
- await fs49.access(path62.join(os17.homedir(), ".gemini"));
17986
+ await fs51.access(path64.join(os20.homedir(), ".gemini"));
17835
17987
  agents.push("gemini");
17836
17988
  } catch {
17837
17989
  }
@@ -17841,17 +17993,17 @@ var init_onboarding = __esm({
17841
17993
  * Detect tech stack from project files
17842
17994
  */
17843
17995
  async detectStack() {
17844
- const fs49 = await import("node:fs/promises");
17845
- const path62 = await import("node:path");
17996
+ const fs51 = await import("node:fs/promises");
17997
+ const path64 = await import("node:path");
17846
17998
  const stack = {
17847
17999
  language: "Unknown",
17848
18000
  technologies: []
17849
18001
  };
17850
18002
  try {
17851
- const files = await fs49.readdir(this.projectPath);
18003
+ const files = await fs51.readdir(this.projectPath);
17852
18004
  if (files.includes("package.json")) {
17853
- const pkgPath = path62.join(this.projectPath, "package.json");
17854
- const pkgContent = await fs49.readFile(pkgPath, "utf-8");
18005
+ const pkgPath = path64.join(this.projectPath, "package.json");
18006
+ const pkgContent = await fs51.readFile(pkgPath, "utf-8");
17855
18007
  const pkg = JSON.parse(pkgContent);
17856
18008
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
17857
18009
  stack.language = deps.typescript ? "TypeScript" : "JavaScript";
@@ -17960,7 +18112,7 @@ var init_wizard = __esm({
17960
18112
  import { exec as exec10 } from "node:child_process";
17961
18113
  import fs34 from "node:fs/promises";
17962
18114
  import path36 from "node:path";
17963
- import { promisify as promisify10 } from "node:util";
18115
+ import { promisify as promisify11 } from "node:util";
17964
18116
  async function generateContext(projectId, repoPath) {
17965
18117
  const _globalPath = path_manager_default.getGlobalProjectPath(projectId);
17966
18118
  const contextPath = path_manager_default.getContextPath(projectId);
@@ -18018,17 +18170,17 @@ async function getGitData(repoPath) {
18018
18170
  recentCommits: []
18019
18171
  };
18020
18172
  try {
18021
- const { stdout: branch } = await execAsync6("git branch --show-current", { cwd: repoPath });
18173
+ const { stdout: branch } = await execAsync7("git branch --show-current", { cwd: repoPath });
18022
18174
  data.branch = branch.trim() || "main";
18023
- const { stdout: commits } = await execAsync6("git rev-list --count HEAD", { cwd: repoPath });
18175
+ const { stdout: commits } = await execAsync7("git rev-list --count HEAD", { cwd: repoPath });
18024
18176
  data.commits = parseInt(commits.trim(), 10) || 0;
18025
- const { stdout: contributors } = await execAsync6("git shortlog -sn --all | wc -l", {
18177
+ const { stdout: contributors } = await execAsync7("git shortlog -sn --all | wc -l", {
18026
18178
  cwd: repoPath
18027
18179
  });
18028
18180
  data.contributors = parseInt(contributors.trim(), 10) || 0;
18029
- const { stdout: status } = await execAsync6("git status --porcelain", { cwd: repoPath });
18181
+ const { stdout: status } = await execAsync7("git status --porcelain", { cwd: repoPath });
18030
18182
  data.hasChanges = status.trim().length > 0;
18031
- const { stdout: log } = await execAsync6(
18183
+ const { stdout: log } = await execAsync7(
18032
18184
  'git log --oneline -10 --pretty=format:"%h|%s|%ad" --date=short',
18033
18185
  { cwd: repoPath }
18034
18186
  );
@@ -18177,13 +18329,13 @@ async function generateSummaryMd(contextPath, project, gitData, pkgData) {
18177
18329
  `;
18178
18330
  await fs34.writeFile(path36.join(contextPath, "summary.md"), content, "utf-8");
18179
18331
  }
18180
- var execAsync6;
18332
+ var execAsync7;
18181
18333
  var init_generator = __esm({
18182
18334
  "core/context/generator.ts"() {
18183
18335
  "use strict";
18184
18336
  init_path_manager();
18185
18337
  init_storage2();
18186
- execAsync6 = promisify10(exec10);
18338
+ execAsync7 = promisify11(exec10);
18187
18339
  __name(generateContext, "generateContext");
18188
18340
  __name(getGitData, "getGitData");
18189
18341
  __name(getPackageData, "getPackageData");
@@ -18195,16 +18347,16 @@ var init_generator = __esm({
18195
18347
  });
18196
18348
 
18197
18349
  // core/domain/analyzer.ts
18198
- import { exec as execCallback5 } from "node:child_process";
18350
+ import { exec as execCallback6 } from "node:child_process";
18199
18351
  import fs35 from "node:fs/promises";
18200
18352
  import path37 from "node:path";
18201
- import { promisify as promisify11 } from "node:util";
18353
+ import { promisify as promisify12 } from "node:util";
18202
18354
  var exec11, CodebaseAnalyzer, analyzer, analyzer_default2;
18203
18355
  var init_analyzer2 = __esm({
18204
18356
  "core/domain/analyzer.ts"() {
18205
18357
  "use strict";
18206
18358
  init_fs();
18207
- exec11 = promisify11(execCallback5);
18359
+ exec11 = promisify12(execCallback6);
18208
18360
  CodebaseAnalyzer = class {
18209
18361
  static {
18210
18362
  __name(this, "CodebaseAnalyzer");
@@ -19132,6 +19284,11 @@ ${formatFullDiff(diff)}`);
19132
19284
  const skillWord = result.skills.length === 1 ? "skill" : "skills";
19133
19285
  generatedItems.push(`${result.skills.length} ${skillWord}`);
19134
19286
  }
19287
+ const installed = result.skillsInstalled?.filter((s) => s.status === "installed") || [];
19288
+ if (installed.length > 0) {
19289
+ const word = installed.length === 1 ? "skill" : "skills";
19290
+ generatedItems.push(`${installed.length} ${word} auto-installed`);
19291
+ }
19135
19292
  output_default.section("Generated");
19136
19293
  output_default.list(generatedItems, { bullet: "\u2713" });
19137
19294
  console.log("");
@@ -19969,8 +20126,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
19969
20126
  const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
19970
20127
  const specsPath2 = path39.join(globalPath2, "planning", "specs");
19971
20128
  try {
19972
- const fs49 = await import("node:fs/promises");
19973
- const files = await fs49.readdir(specsPath2);
20129
+ const fs51 = await import("node:fs/promises");
20130
+ const files = await fs51.readdir(specsPath2);
19974
20131
  const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
19975
20132
  if (specs.length === 0) {
19976
20133
  output_default.warn("no specs yet");
@@ -20186,14 +20343,14 @@ var init_project_service = __esm({
20186
20343
  import { exec as exec12 } from "node:child_process";
20187
20344
  import fs37 from "node:fs/promises";
20188
20345
  import path40 from "node:path";
20189
- import { promisify as promisify12 } from "node:util";
20190
- var execAsync7, DEFAULT_CONFIG, StalenessChecker, createStalenessChecker;
20346
+ import { promisify as promisify13 } from "node:util";
20347
+ var execAsync8, DEFAULT_CONFIG, StalenessChecker, createStalenessChecker;
20191
20348
  var init_staleness_checker = __esm({
20192
20349
  "core/services/staleness-checker.ts"() {
20193
20350
  "use strict";
20194
20351
  init_path_manager();
20195
20352
  init_session_tracker();
20196
- execAsync7 = promisify12(exec12);
20353
+ execAsync8 = promisify13(exec12);
20197
20354
  DEFAULT_CONFIG = {
20198
20355
  commitThreshold: 10,
20199
20356
  dayThreshold: 3,
@@ -20246,7 +20403,7 @@ var init_staleness_checker = __esm({
20246
20403
  status.lastSyncCommit = projectJson.lastSyncCommit || null;
20247
20404
  const lastSync = projectJson.lastSync;
20248
20405
  try {
20249
- const { stdout } = await execAsync7("git rev-parse --short HEAD", {
20406
+ const { stdout } = await execAsync8("git rev-parse --short HEAD", {
20250
20407
  cwd: this.projectPath
20251
20408
  });
20252
20409
  status.currentCommit = stdout.trim();
@@ -20264,7 +20421,7 @@ var init_staleness_checker = __esm({
20264
20421
  return status;
20265
20422
  }
20266
20423
  try {
20267
- const { stdout } = await execAsync7(`git rev-list --count ${status.lastSyncCommit}..HEAD`, {
20424
+ const { stdout } = await execAsync8(`git rev-list --count ${status.lastSyncCommit}..HEAD`, {
20268
20425
  cwd: this.projectPath
20269
20426
  });
20270
20427
  status.commitsSinceSync = parseInt(stdout.trim(), 10) || 0;
@@ -20281,7 +20438,7 @@ var init_staleness_checker = __esm({
20281
20438
  );
20282
20439
  }
20283
20440
  try {
20284
- const { stdout } = await execAsync7(`git diff --name-only ${status.lastSyncCommit}..HEAD`, {
20441
+ const { stdout } = await execAsync8(`git diff --name-only ${status.lastSyncCommit}..HEAD`, {
20285
20442
  cwd: this.projectPath
20286
20443
  });
20287
20444
  status.changedFiles = stdout.trim().split("\n").filter(Boolean);
@@ -20700,13 +20857,13 @@ var init_formatters = __esm({
20700
20857
  import { exec as exec13 } from "node:child_process";
20701
20858
  import os11 from "node:os";
20702
20859
  import path41 from "node:path";
20703
- import { promisify as promisify13 } from "node:util";
20860
+ import { promisify as promisify14 } from "node:util";
20704
20861
  function getAIToolConfig(id) {
20705
20862
  return AI_TOOLS[id] || null;
20706
20863
  }
20707
20864
  async function commandExists(cmd) {
20708
20865
  try {
20709
- await execAsync8(`which ${cmd}`);
20866
+ await execAsync9(`which ${cmd}`);
20710
20867
  return true;
20711
20868
  } catch {
20712
20869
  return false;
@@ -20741,19 +20898,19 @@ async function resolveToolIds(mode, repoPath = process.cwd()) {
20741
20898
  }
20742
20899
  return mode.filter((id) => AI_TOOLS[id]);
20743
20900
  }
20744
- var execAsync8, AI_TOOLS, DEFAULT_AI_TOOLS, SUPPORTED_AI_TOOLS;
20901
+ var execAsync9, AI_TOOLS, DEFAULT_AI_TOOLS, SUPPORTED_AI_TOOLS;
20745
20902
  var init_registry = __esm({
20746
20903
  "core/ai-tools/registry.ts"() {
20747
20904
  "use strict";
20748
20905
  init_fs_helpers();
20749
- execAsync8 = promisify13(exec13);
20906
+ execAsync9 = promisify14(exec13);
20750
20907
  AI_TOOLS = {
20751
20908
  claude: {
20752
20909
  id: "claude",
20753
20910
  name: "Claude Code",
20754
20911
  outputFile: "CLAUDE.md",
20755
20912
  outputPath: "global",
20756
- maxTokens: 3e3,
20913
+ maxTokens: 6e3,
20757
20914
  format: "detailed",
20758
20915
  description: "Anthropic Claude Code CLI"
20759
20916
  },
@@ -20895,6 +21052,45 @@ var init_ai_tools = __esm({
20895
21052
  }
20896
21053
  });
20897
21054
 
21055
+ // core/utils/logger.ts
21056
+ function getLogLevel() {
21057
+ const debugEnv = process.env.PRJCT_DEBUG || process.env.DEBUG || "";
21058
+ if (!debugEnv) return { level: -1, name: "disabled" };
21059
+ if (TRUTHY_VALUES.has(debugEnv) || debugEnv.includes("prjct")) {
21060
+ return { level: LEVELS.debug, name: "debug" };
21061
+ }
21062
+ const levelValue = LEVELS[debugEnv] ?? -1;
21063
+ const levelName = levelValue >= 0 ? debugEnv : "disabled";
21064
+ return { level: levelValue, name: levelName };
21065
+ }
21066
+ function createLogMethod(levelThreshold, prefix, method) {
21067
+ return currentLevel >= levelThreshold ? (...args2) => console[method](prefix, ...args2) : noop;
21068
+ }
21069
+ var LEVELS, TRUTHY_VALUES, currentLevel, currentLevelName, noop, logger2, logger_default;
21070
+ var init_logger = __esm({
21071
+ "core/utils/logger.ts"() {
21072
+ "use strict";
21073
+ LEVELS = { error: 0, warn: 1, info: 2, debug: 3 };
21074
+ TRUTHY_VALUES = /* @__PURE__ */ new Set(["1", "true", "*"]);
21075
+ __name(getLogLevel, "getLogLevel");
21076
+ ({ level: currentLevel, name: currentLevelName } = getLogLevel());
21077
+ noop = /* @__PURE__ */ __name(() => {
21078
+ }, "noop");
21079
+ __name(createLogMethod, "createLogMethod");
21080
+ logger2 = {
21081
+ error: createLogMethod(LEVELS.error, "[prjct:error]", "error"),
21082
+ warn: createLogMethod(LEVELS.warn, "[prjct:warn]", "warn"),
21083
+ info: createLogMethod(LEVELS.info, "[prjct:info]", "log"),
21084
+ debug: createLogMethod(LEVELS.debug, "[prjct:debug]", "log"),
21085
+ // Check if logging is enabled (useful for expensive log prep)
21086
+ isEnabled: /* @__PURE__ */ __name(() => currentLevel >= 0, "isEnabled"),
21087
+ // Get current level name (pre-computed, no runtime lookup)
21088
+ level: /* @__PURE__ */ __name(() => currentLevelName, "level")
21089
+ };
21090
+ logger_default = logger2;
21091
+ }
21092
+ });
21093
+
20898
21094
  // core/services/context-generator.ts
20899
21095
  import fs39 from "node:fs/promises";
20900
21096
  import path43 from "node:path";
@@ -21343,9 +21539,364 @@ var init_local_state_generator = __esm({
21343
21539
  }
21344
21540
  });
21345
21541
 
21346
- // core/services/stack-detector.ts
21542
+ // core/services/skill-lock.ts
21347
21543
  import fs41 from "node:fs/promises";
21544
+ import os12 from "node:os";
21348
21545
  import path45 from "node:path";
21546
+ function getLockFilePath() {
21547
+ return path45.join(os12.homedir(), ".prjct-cli", "skills", LOCK_FILE_NAME);
21548
+ }
21549
+ function createEmptyLockFile() {
21550
+ return {
21551
+ version: 1,
21552
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
21553
+ skills: {}
21554
+ };
21555
+ }
21556
+ async function read() {
21557
+ try {
21558
+ const content = await fs41.readFile(getLockFilePath(), "utf-8");
21559
+ return JSON.parse(content);
21560
+ } catch {
21561
+ return createEmptyLockFile();
21562
+ }
21563
+ }
21564
+ async function write(lockFile) {
21565
+ const lockPath = getLockFilePath();
21566
+ await fs41.mkdir(path45.dirname(lockPath), { recursive: true });
21567
+ lockFile.generatedAt = (/* @__PURE__ */ new Date()).toISOString();
21568
+ await fs41.writeFile(lockPath, JSON.stringify(lockFile, null, 2), "utf-8");
21569
+ }
21570
+ async function addEntry(entry) {
21571
+ const lockFile = await read();
21572
+ lockFile.skills[entry.name] = entry;
21573
+ await write(lockFile);
21574
+ }
21575
+ async function removeEntry(name) {
21576
+ const lockFile = await read();
21577
+ if (!(name in lockFile.skills)) return false;
21578
+ delete lockFile.skills[name];
21579
+ await write(lockFile);
21580
+ return true;
21581
+ }
21582
+ async function getEntry(name) {
21583
+ const lockFile = await read();
21584
+ return lockFile.skills[name] || null;
21585
+ }
21586
+ async function getAll() {
21587
+ const lockFile = await read();
21588
+ return lockFile.skills;
21589
+ }
21590
+ function getPath() {
21591
+ return getLockFilePath();
21592
+ }
21593
+ var LOCK_FILE_NAME, skillLock;
21594
+ var init_skill_lock = __esm({
21595
+ "core/services/skill-lock.ts"() {
21596
+ "use strict";
21597
+ LOCK_FILE_NAME = ".skill-lock.json";
21598
+ __name(getLockFilePath, "getLockFilePath");
21599
+ __name(createEmptyLockFile, "createEmptyLockFile");
21600
+ __name(read, "read");
21601
+ __name(write, "write");
21602
+ __name(addEntry, "addEntry");
21603
+ __name(removeEntry, "removeEntry");
21604
+ __name(getEntry, "getEntry");
21605
+ __name(getAll, "getAll");
21606
+ __name(getPath, "getPath");
21607
+ skillLock = {
21608
+ read,
21609
+ write,
21610
+ addEntry,
21611
+ removeEntry,
21612
+ getEntry,
21613
+ getAll,
21614
+ getPath
21615
+ };
21616
+ }
21617
+ });
21618
+
21619
+ // core/services/skill-installer.ts
21620
+ import { exec as execCallback7 } from "node:child_process";
21621
+ import fs42 from "node:fs/promises";
21622
+ import os13 from "node:os";
21623
+ import path46 from "node:path";
21624
+ import { promisify as promisify15 } from "node:util";
21625
+ import { glob } from "glob";
21626
+ function parseSource(source) {
21627
+ if (source.startsWith("./") || source.startsWith("/") || source.startsWith("~")) {
21628
+ const resolvedPath = source.startsWith("~") ? path46.join(os13.homedir(), source.slice(1)) : path46.resolve(source);
21629
+ return {
21630
+ type: "local",
21631
+ localPath: resolvedPath,
21632
+ url: resolvedPath
21633
+ };
21634
+ }
21635
+ const atIndex = source.indexOf("@");
21636
+ if (atIndex > 0) {
21637
+ const repoPath = source.slice(0, atIndex);
21638
+ const skillName = source.slice(atIndex + 1);
21639
+ const [owner, repo] = repoPath.split("/");
21640
+ if (owner && repo) {
21641
+ return {
21642
+ type: "github",
21643
+ owner,
21644
+ repo,
21645
+ skillName,
21646
+ url: `https://github.com/${owner}/${repo}`
21647
+ };
21648
+ }
21649
+ }
21650
+ const parts = source.split("/");
21651
+ if (parts.length === 2 && parts[0] && parts[1]) {
21652
+ return {
21653
+ type: "github",
21654
+ owner: parts[0],
21655
+ repo: parts[1],
21656
+ url: `https://github.com/${parts[0]}/${parts[1]}`
21657
+ };
21658
+ }
21659
+ throw new Error(
21660
+ `Invalid source format: "${source}". Expected "owner/repo", "owner/repo@skill-name", or "./local-path"`
21661
+ );
21662
+ }
21663
+ async function discoverSkills(dir) {
21664
+ const skills = [];
21665
+ try {
21666
+ const rootSkill = path46.join(dir, "SKILL.md");
21667
+ await fs42.access(rootSkill);
21668
+ const dirName = path46.basename(dir);
21669
+ skills.push({ name: dirName, filePath: rootSkill });
21670
+ } catch {
21671
+ }
21672
+ const subdirSkills = await glob("*/SKILL.md", { cwd: dir, absolute: true });
21673
+ for (const filePath of subdirSkills) {
21674
+ const name = path46.basename(path46.dirname(filePath));
21675
+ if (!skills.some((s) => s.name === name)) {
21676
+ skills.push({ name, filePath });
21677
+ }
21678
+ }
21679
+ const nestedSkills = await glob("skills/*/SKILL.md", { cwd: dir, absolute: true });
21680
+ for (const filePath of nestedSkills) {
21681
+ const name = path46.basename(path46.dirname(filePath));
21682
+ if (!skills.some((s) => s.name === name)) {
21683
+ skills.push({ name, filePath });
21684
+ }
21685
+ }
21686
+ return skills;
21687
+ }
21688
+ function injectSourceMetadata(content, source, sha) {
21689
+ const now = (/* @__PURE__ */ new Date()).toISOString();
21690
+ const prjctBlock = [
21691
+ `_prjct:`,
21692
+ ` sourceUrl: ${source.url}`,
21693
+ ` sourceType: ${source.type}`,
21694
+ ` installedAt: ${now}`
21695
+ ];
21696
+ if (sha) {
21697
+ prjctBlock.push(` sha: ${sha}`);
21698
+ }
21699
+ const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---/;
21700
+ const match = content.match(frontmatterRegex);
21701
+ if (match) {
21702
+ let frontmatter = match[1];
21703
+ frontmatter = frontmatter.replace(/\n?_prjct:[\s\S]*?(?=\n[a-zA-Z]|\n---|\s*$)/g, "");
21704
+ const updatedFrontmatter = `${frontmatter.trimEnd()}
21705
+ ${prjctBlock.join("\n")}`;
21706
+ return content.replace(frontmatterRegex, `---
21707
+ ${updatedFrontmatter}
21708
+ ---`);
21709
+ }
21710
+ return `---
21711
+ ${prjctBlock.join("\n")}
21712
+ ---
21713
+
21714
+ ${content}`;
21715
+ }
21716
+ function getInstallDir() {
21717
+ return path46.join(os13.homedir(), ".claude", "skills");
21718
+ }
21719
+ async function installSkillFile(sourcePath, name, source, sha) {
21720
+ const installDir = getInstallDir();
21721
+ const targetDir = path46.join(installDir, name);
21722
+ const targetPath = path46.join(targetDir, "SKILL.md");
21723
+ const content = await fs42.readFile(sourcePath, "utf-8");
21724
+ const enrichedContent = injectSourceMetadata(content, source, sha);
21725
+ await fs42.mkdir(targetDir, { recursive: true });
21726
+ await fs42.writeFile(targetPath, enrichedContent, "utf-8");
21727
+ return {
21728
+ name,
21729
+ filePath: targetPath,
21730
+ source,
21731
+ sha
21732
+ };
21733
+ }
21734
+ async function installFromGitHub(source) {
21735
+ const result = { installed: [], skipped: [], errors: [] };
21736
+ if (!dependencyValidator.isAvailable("git")) {
21737
+ const gitStatus = dependencyValidator.checkTool("git");
21738
+ result.errors.push(
21739
+ `Cannot install from GitHub: git is not available. ${gitStatus.error?.hint || "Install git and try again."}`
21740
+ );
21741
+ return result;
21742
+ }
21743
+ const tmpDir = path46.join(os13.tmpdir(), `prjct-skill-${Date.now()}`);
21744
+ try {
21745
+ const cloneUrl = `https://github.com/${source.owner}/${source.repo}.git`;
21746
+ await exec14(`git clone --depth 1 ${cloneUrl} ${tmpDir}`, { timeout: getTimeout("GIT_CLONE") });
21747
+ let sha;
21748
+ try {
21749
+ const { stdout } = await exec14("git rev-parse HEAD", {
21750
+ cwd: tmpDir,
21751
+ timeout: getTimeout("TOOL_CHECK")
21752
+ });
21753
+ sha = stdout.trim();
21754
+ } catch {
21755
+ }
21756
+ const discoveredSkills = await discoverSkills(tmpDir);
21757
+ if (discoveredSkills.length === 0) {
21758
+ result.errors.push(`No SKILL.md files found in ${source.owner}/${source.repo}`);
21759
+ return result;
21760
+ }
21761
+ const skillsToInstall = source.skillName ? discoveredSkills.filter((s) => s.name === source.skillName) : discoveredSkills;
21762
+ if (source.skillName && skillsToInstall.length === 0) {
21763
+ result.errors.push(`Skill "${source.skillName}" not found in ${source.owner}/${source.repo}`);
21764
+ return result;
21765
+ }
21766
+ for (const skill of skillsToInstall) {
21767
+ try {
21768
+ const installed = await installSkillFile(skill.filePath, skill.name, source, sha);
21769
+ const lockEntry = {
21770
+ name: skill.name,
21771
+ source: {
21772
+ type: "github",
21773
+ url: `${source.owner}/${source.repo}`,
21774
+ sha
21775
+ },
21776
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
21777
+ filePath: installed.filePath
21778
+ };
21779
+ await skillLock.addEntry(lockEntry);
21780
+ result.installed.push(installed);
21781
+ } catch (error) {
21782
+ result.errors.push(`Failed to install ${skill.name}: ${error.message}`);
21783
+ }
21784
+ }
21785
+ } finally {
21786
+ try {
21787
+ await fs42.rm(tmpDir, { recursive: true, force: true });
21788
+ } catch {
21789
+ }
21790
+ }
21791
+ return result;
21792
+ }
21793
+ async function installFromLocal(source) {
21794
+ const result = { installed: [], skipped: [], errors: [] };
21795
+ const localPath = source.localPath;
21796
+ try {
21797
+ await fs42.access(localPath);
21798
+ } catch {
21799
+ result.errors.push(`Local path not found: ${localPath}`);
21800
+ return result;
21801
+ }
21802
+ const stat = await fs42.stat(localPath);
21803
+ if (stat.isFile()) {
21804
+ const name = path46.basename(path46.dirname(localPath));
21805
+ try {
21806
+ const installed = await installSkillFile(localPath, name, source);
21807
+ const lockEntry = {
21808
+ name,
21809
+ source: { type: "local", url: localPath },
21810
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
21811
+ filePath: installed.filePath
21812
+ };
21813
+ await skillLock.addEntry(lockEntry);
21814
+ result.installed.push(installed);
21815
+ } catch (error) {
21816
+ result.errors.push(`Failed to install from ${localPath}: ${error.message}`);
21817
+ }
21818
+ } else {
21819
+ const discoveredSkills = await discoverSkills(localPath);
21820
+ if (discoveredSkills.length === 0) {
21821
+ result.errors.push(`No SKILL.md files found in ${localPath}`);
21822
+ return result;
21823
+ }
21824
+ for (const skill of discoveredSkills) {
21825
+ try {
21826
+ const installed = await installSkillFile(skill.filePath, skill.name, source);
21827
+ const lockEntry = {
21828
+ name: skill.name,
21829
+ source: { type: "local", url: localPath },
21830
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
21831
+ filePath: installed.filePath
21832
+ };
21833
+ await skillLock.addEntry(lockEntry);
21834
+ result.installed.push(installed);
21835
+ } catch (error) {
21836
+ result.errors.push(`Failed to install ${skill.name}: ${error.message}`);
21837
+ }
21838
+ }
21839
+ }
21840
+ return result;
21841
+ }
21842
+ async function remove(name) {
21843
+ const installDir = getInstallDir();
21844
+ const subdirPath = path46.join(installDir, name);
21845
+ try {
21846
+ await fs42.rm(subdirPath, { recursive: true, force: true });
21847
+ } catch {
21848
+ }
21849
+ const flatPath = path46.join(installDir, `${name}.md`);
21850
+ try {
21851
+ await fs42.rm(flatPath, { force: true });
21852
+ } catch {
21853
+ }
21854
+ return skillLock.removeEntry(name);
21855
+ }
21856
+ async function install(sourceStr) {
21857
+ const source = parseSource(sourceStr);
21858
+ switch (source.type) {
21859
+ case "github":
21860
+ return installFromGitHub(source);
21861
+ case "local":
21862
+ return installFromLocal(source);
21863
+ default:
21864
+ return {
21865
+ installed: [],
21866
+ skipped: [],
21867
+ errors: [`Unsupported source type: ${source.type}`]
21868
+ };
21869
+ }
21870
+ }
21871
+ var exec14, skillInstaller;
21872
+ var init_skill_installer = __esm({
21873
+ "core/services/skill-installer.ts"() {
21874
+ "use strict";
21875
+ init_constants();
21876
+ init_dependency_validator();
21877
+ init_skill_lock();
21878
+ exec14 = promisify15(execCallback7);
21879
+ __name(parseSource, "parseSource");
21880
+ __name(discoverSkills, "discoverSkills");
21881
+ __name(injectSourceMetadata, "injectSourceMetadata");
21882
+ __name(getInstallDir, "getInstallDir");
21883
+ __name(installSkillFile, "installSkillFile");
21884
+ __name(installFromGitHub, "installFromGitHub");
21885
+ __name(installFromLocal, "installFromLocal");
21886
+ __name(remove, "remove");
21887
+ __name(install, "install");
21888
+ skillInstaller = {
21889
+ install,
21890
+ remove,
21891
+ parseSource,
21892
+ getInstallDir
21893
+ };
21894
+ }
21895
+ });
21896
+
21897
+ // core/services/stack-detector.ts
21898
+ import fs43 from "node:fs/promises";
21899
+ import path47 from "node:path";
21349
21900
  var StackDetector;
21350
21901
  var init_stack_detector = __esm({
21351
21902
  "core/services/stack-detector.ts"() {
@@ -21504,8 +22055,8 @@ var init_stack_detector = __esm({
21504
22055
  */
21505
22056
  async readPackageJson() {
21506
22057
  try {
21507
- const pkgPath = path45.join(this.projectPath, "package.json");
21508
- const content = await fs41.readFile(pkgPath, "utf-8");
22058
+ const pkgPath = path47.join(this.projectPath, "package.json");
22059
+ const content = await fs43.readFile(pkgPath, "utf-8");
21509
22060
  return JSON.parse(content);
21510
22061
  } catch {
21511
22062
  return null;
@@ -21516,7 +22067,7 @@ var init_stack_detector = __esm({
21516
22067
  */
21517
22068
  async fileExists(filename) {
21518
22069
  try {
21519
- await fs41.access(path45.join(this.projectPath, filename));
22070
+ await fs43.access(path47.join(this.projectPath, filename));
21520
22071
  return true;
21521
22072
  } catch {
21522
22073
  return false;
@@ -21527,16 +22078,16 @@ var init_stack_detector = __esm({
21527
22078
  });
21528
22079
 
21529
22080
  // core/services/sync-verifier.ts
21530
- import { exec as exec14 } from "node:child_process";
21531
- import fs42 from "node:fs/promises";
21532
- import path46 from "node:path";
21533
- import { promisify as promisify14 } from "node:util";
21534
- var execAsync9, BUILTIN_CHECKS, SyncVerifier, syncVerifier;
22081
+ import { exec as exec15 } from "node:child_process";
22082
+ import fs44 from "node:fs/promises";
22083
+ import path48 from "node:path";
22084
+ import { promisify as promisify16 } from "node:util";
22085
+ var execAsync10, BUILTIN_CHECKS, SyncVerifier, syncVerifier;
21535
22086
  var init_sync_verifier = __esm({
21536
22087
  "core/services/sync-verifier.ts"() {
21537
22088
  "use strict";
21538
22089
  init_fs();
21539
- execAsync9 = promisify14(exec14);
22090
+ execAsync10 = promisify16(exec15);
21540
22091
  BUILTIN_CHECKS = {
21541
22092
  /**
21542
22093
  * Verify all expected context files exist after sync
@@ -21546,9 +22097,9 @@ var init_sync_verifier = __esm({
21546
22097
  const expected = ["context/CLAUDE.md"];
21547
22098
  const missing = [];
21548
22099
  for (const file of expected) {
21549
- const filePath = path46.join(globalPath, file);
22100
+ const filePath = path48.join(globalPath, file);
21550
22101
  try {
21551
- await fs42.access(filePath);
22102
+ await fs44.access(filePath);
21552
22103
  } catch {
21553
22104
  missing.push(file);
21554
22105
  }
@@ -21569,9 +22120,9 @@ var init_sync_verifier = __esm({
21569
22120
  const jsonFiles = ["storage/state.json"];
21570
22121
  const invalid = [];
21571
22122
  for (const file of jsonFiles) {
21572
- const filePath = path46.join(globalPath, file);
22123
+ const filePath = path48.join(globalPath, file);
21573
22124
  try {
21574
- const content = await fs42.readFile(filePath, "utf-8");
22125
+ const content = await fs44.readFile(filePath, "utf-8");
21575
22126
  JSON.parse(content);
21576
22127
  } catch (error) {
21577
22128
  if (!isNotFoundError(error)) {
@@ -21592,7 +22143,7 @@ var init_sync_verifier = __esm({
21592
22143
  */
21593
22144
  async noSensitiveData(globalPath) {
21594
22145
  const start = Date.now();
21595
- const contextDir = path46.join(globalPath, "context");
22146
+ const contextDir = path48.join(globalPath, "context");
21596
22147
  const patterns = [
21597
22148
  /(?:api[_-]?key|apikey)\s*[:=]\s*['"][^'"]{10,}/i,
21598
22149
  /(?:password|passwd|pwd)\s*[:=]\s*['"][^'"]{4,}/i,
@@ -21600,10 +22151,10 @@ var init_sync_verifier = __esm({
21600
22151
  ];
21601
22152
  const violations = [];
21602
22153
  try {
21603
- const files = await fs42.readdir(contextDir);
22154
+ const files = await fs44.readdir(contextDir);
21604
22155
  for (const file of files) {
21605
22156
  if (!file.endsWith(".md")) continue;
21606
- const content = await fs42.readFile(path46.join(contextDir, file), "utf-8");
22157
+ const content = await fs44.readFile(path48.join(contextDir, file), "utf-8");
21607
22158
  for (const pattern of patterns) {
21608
22159
  if (pattern.test(content)) {
21609
22160
  violations.push(`${file}: potential sensitive data detected`);
@@ -21697,7 +22248,7 @@ var init_sync_verifier = __esm({
21697
22248
  };
21698
22249
  }
21699
22250
  try {
21700
- const { stdout, stderr } = await execAsync9(command, {
22251
+ const { stdout, stderr } = await execAsync10(command, {
21701
22252
  cwd: projectPath,
21702
22253
  timeout: 3e4
21703
22254
  });
@@ -21723,26 +22274,30 @@ var init_sync_verifier = __esm({
21723
22274
  });
21724
22275
 
21725
22276
  // core/services/sync-service.ts
21726
- import { exec as exec15 } from "node:child_process";
21727
- import fs43 from "node:fs/promises";
21728
- import path47 from "node:path";
21729
- import { promisify as promisify15 } from "node:util";
21730
- var execAsync10, SyncService, syncService;
22277
+ import { exec as exec16 } from "node:child_process";
22278
+ import fs45 from "node:fs/promises";
22279
+ import os14 from "node:os";
22280
+ import path49 from "node:path";
22281
+ import { promisify as promisify17 } from "node:util";
22282
+ var execAsync11, SyncService, syncService;
21731
22283
  var init_sync_service = __esm({
21732
22284
  "core/services/sync-service.ts"() {
21733
22285
  "use strict";
21734
22286
  init_ai_tools();
22287
+ init_errors();
21735
22288
  init_command_installer();
21736
22289
  init_config_manager();
21737
22290
  init_path_manager();
21738
22291
  init_metrics_storage();
21739
22292
  init_citations();
21740
22293
  init_date_helper();
22294
+ init_logger();
21741
22295
  init_context_generator();
21742
22296
  init_local_state_generator();
22297
+ init_skill_installer();
21743
22298
  init_stack_detector();
21744
22299
  init_sync_verifier();
21745
- execAsync10 = promisify15(exec15);
22300
+ execAsync11 = promisify17(exec16);
21746
22301
  SyncService = class {
21747
22302
  static {
21748
22303
  __name(this, "SyncService");
@@ -21787,6 +22342,7 @@ var init_sync_service = __esm({
21787
22342
  stack: this.emptyStack(),
21788
22343
  agents: [],
21789
22344
  skills: [],
22345
+ skillsInstalled: [],
21790
22346
  contextFiles: [],
21791
22347
  aiTools: [],
21792
22348
  error: "No prjct project. Run p. init first."
@@ -21804,6 +22360,7 @@ var init_sync_service = __esm({
21804
22360
  await ensureDirsPromise;
21805
22361
  const agents = await this.generateAgents(stack, stats);
21806
22362
  const skills = this.configureSkills(agents);
22363
+ const skillsInstalled = await this.autoInstallSkills(agents);
21807
22364
  const sources = this.buildSources(stats, commands);
21808
22365
  const contextFiles = await this.generateContextFiles(git, stats, commands, agents, sources);
21809
22366
  const projectContext = {
@@ -21861,6 +22418,7 @@ var init_sync_service = __esm({
21861
22418
  stack,
21862
22419
  agents,
21863
22420
  skills,
22421
+ skillsInstalled,
21864
22422
  contextFiles,
21865
22423
  aiTools: aiToolResults.map((r) => ({
21866
22424
  toolId: r.toolId,
@@ -21881,6 +22439,7 @@ var init_sync_service = __esm({
21881
22439
  stack: this.emptyStack(),
21882
22440
  agents: [],
21883
22441
  skills: [],
22442
+ skillsInstalled: [],
21884
22443
  contextFiles: [],
21885
22444
  aiTools: [],
21886
22445
  error: error.message
@@ -21893,7 +22452,7 @@ var init_sync_service = __esm({
21893
22452
  async ensureDirectories() {
21894
22453
  const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
21895
22454
  await Promise.all(
21896
- dirs.map((dir) => fs43.mkdir(path47.join(this.globalPath, dir), { recursive: true }))
22455
+ dirs.map((dir) => fs45.mkdir(path49.join(this.globalPath, dir), { recursive: true }))
21897
22456
  );
21898
22457
  }
21899
22458
  // ==========================================================================
@@ -21912,19 +22471,19 @@ var init_sync_service = __esm({
21912
22471
  weeklyCommits: 0
21913
22472
  };
21914
22473
  try {
21915
- const { stdout: branch } = await execAsync10("git branch --show-current", {
22474
+ const { stdout: branch } = await execAsync11("git branch --show-current", {
21916
22475
  cwd: this.projectPath
21917
22476
  });
21918
22477
  data.branch = branch.trim() || "main";
21919
- const { stdout: commits } = await execAsync10("git rev-list --count HEAD", {
22478
+ const { stdout: commits } = await execAsync11("git rev-list --count HEAD", {
21920
22479
  cwd: this.projectPath
21921
22480
  });
21922
22481
  data.commits = parseInt(commits.trim(), 10) || 0;
21923
- const { stdout: contributors } = await execAsync10("git shortlog -sn --all | wc -l", {
22482
+ const { stdout: contributors } = await execAsync11("git shortlog -sn --all | wc -l", {
21924
22483
  cwd: this.projectPath
21925
22484
  });
21926
22485
  data.contributors = parseInt(contributors.trim(), 10) || 0;
21927
- const { stdout: status } = await execAsync10("git status --porcelain", {
22486
+ const { stdout: status } = await execAsync11("git status --porcelain", {
21928
22487
  cwd: this.projectPath
21929
22488
  });
21930
22489
  const lines = status.trim().split("\n").filter(Boolean);
@@ -21940,7 +22499,7 @@ var init_sync_service = __esm({
21940
22499
  data.untrackedFiles.push(file);
21941
22500
  }
21942
22501
  }
21943
- const { stdout: log } = await execAsync10(
22502
+ const { stdout: log } = await execAsync11(
21944
22503
  'git log --oneline -20 --pretty=format:"%h|%s|%ad" --date=short',
21945
22504
  { cwd: this.projectPath }
21946
22505
  );
@@ -21948,7 +22507,7 @@ var init_sync_service = __esm({
21948
22507
  const [hash, message, date] = line.split("|");
21949
22508
  return { hash, message, date };
21950
22509
  });
21951
- const { stdout: weekly } = await execAsync10('git log --oneline --since="1 week ago" | wc -l', {
22510
+ const { stdout: weekly } = await execAsync11('git log --oneline --since="1 week ago" | wc -l', {
21952
22511
  cwd: this.projectPath
21953
22512
  });
21954
22513
  data.weeklyCommits = parseInt(weekly.trim(), 10) || 0;
@@ -21963,14 +22522,14 @@ var init_sync_service = __esm({
21963
22522
  const stats = {
21964
22523
  fileCount: 0,
21965
22524
  version: "0.0.0",
21966
- name: path47.basename(this.projectPath),
22525
+ name: path49.basename(this.projectPath),
21967
22526
  ecosystem: "unknown",
21968
22527
  projectType: "simple",
21969
22528
  languages: [],
21970
22529
  frameworks: []
21971
22530
  };
21972
22531
  try {
21973
- const { stdout } = await execAsync10(
22532
+ const { stdout } = await execAsync11(
21974
22533
  'find . -type f \\( -name "*.js" -o -name "*.ts" -o -name "*.tsx" -o -name "*.py" -o -name "*.go" -o -name "*.rs" \\) -not -path "./node_modules/*" -not -path "./.git/*" | wc -l',
21975
22534
  { cwd: this.projectPath }
21976
22535
  );
@@ -21979,8 +22538,8 @@ var init_sync_service = __esm({
21979
22538
  stats.fileCount = 0;
21980
22539
  }
21981
22540
  try {
21982
- const pkgPath = path47.join(this.projectPath, "package.json");
21983
- const pkg = JSON.parse(await fs43.readFile(pkgPath, "utf-8"));
22541
+ const pkgPath = path49.join(this.projectPath, "package.json");
22542
+ const pkg = JSON.parse(await fs45.readFile(pkgPath, "utf-8"));
21984
22543
  stats.version = pkg.version || "0.0.0";
21985
22544
  stats.name = pkg.name || stats.name;
21986
22545
  stats.ecosystem = "JavaScript";
@@ -22124,12 +22683,12 @@ var init_sync_service = __esm({
22124
22683
  // ==========================================================================
22125
22684
  async generateAgents(stack, stats) {
22126
22685
  const agents = [];
22127
- const agentsPath = path47.join(this.globalPath, "agents");
22686
+ const agentsPath = path49.join(this.globalPath, "agents");
22128
22687
  try {
22129
- const files = await fs43.readdir(agentsPath);
22688
+ const files = await fs45.readdir(agentsPath);
22130
22689
  for (const file of files) {
22131
22690
  if (file.endsWith(".md")) {
22132
- await fs43.unlink(path47.join(agentsPath, file));
22691
+ await fs45.unlink(path49.join(agentsPath, file));
22133
22692
  }
22134
22693
  }
22135
22694
  } catch {
@@ -22169,7 +22728,7 @@ var init_sync_service = __esm({
22169
22728
  async generateWorkflowAgent(name, agentsPath) {
22170
22729
  let content = "";
22171
22730
  try {
22172
- const templatePath = path47.join(
22731
+ const templatePath = path49.join(
22173
22732
  __dirname,
22174
22733
  "..",
22175
22734
  "..",
@@ -22178,16 +22737,16 @@ var init_sync_service = __esm({
22178
22737
  "workflow",
22179
22738
  `${name}.md`
22180
22739
  );
22181
- content = await fs43.readFile(templatePath, "utf-8");
22740
+ content = await fs45.readFile(templatePath, "utf-8");
22182
22741
  } catch {
22183
22742
  content = this.generateMinimalWorkflowAgent(name);
22184
22743
  }
22185
- await fs43.writeFile(path47.join(agentsPath, `${name}.md`), content, "utf-8");
22744
+ await fs45.writeFile(path49.join(agentsPath, `${name}.md`), content, "utf-8");
22186
22745
  }
22187
22746
  async generateDomainAgent(name, agentsPath, stats, stack) {
22188
22747
  let content = "";
22189
22748
  try {
22190
- const templatePath = path47.join(
22749
+ const templatePath = path49.join(
22191
22750
  __dirname,
22192
22751
  "..",
22193
22752
  "..",
@@ -22196,14 +22755,14 @@ var init_sync_service = __esm({
22196
22755
  "domain",
22197
22756
  `${name}.md`
22198
22757
  );
22199
- content = await fs43.readFile(templatePath, "utf-8");
22758
+ content = await fs45.readFile(templatePath, "utf-8");
22200
22759
  content = content.replace("{projectName}", stats.name);
22201
22760
  content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
22202
22761
  content = content.replace("{ecosystem}", stats.ecosystem);
22203
22762
  } catch {
22204
22763
  content = this.generateMinimalDomainAgent(name, stats, stack);
22205
22764
  }
22206
- await fs43.writeFile(path47.join(agentsPath, `${name}.md`), content, "utf-8");
22765
+ await fs45.writeFile(path49.join(agentsPath, `${name}.md`), content, "utf-8");
22207
22766
  }
22208
22767
  generateMinimalWorkflowAgent(name) {
22209
22768
  const descriptions = {
@@ -22271,8 +22830,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
22271
22830
  })),
22272
22831
  agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
22273
22832
  };
22274
- fs43.writeFile(
22275
- path47.join(this.globalPath, "config", "skills.json"),
22833
+ fs45.writeFile(
22834
+ path49.join(this.globalPath, "config", "skills.json"),
22276
22835
  JSON.stringify(skillsConfig, null, 2),
22277
22836
  "utf-8"
22278
22837
  ).catch(() => {
@@ -22280,6 +22839,85 @@ You are the ${name} expert for this project. Apply best practices for the detect
22280
22839
  return skills;
22281
22840
  }
22282
22841
  // ==========================================================================
22842
+ // SKILL AUTO-INSTALLATION
22843
+ // ==========================================================================
22844
+ /**
22845
+ * Auto-install skills from skill-mappings.json for generated agents.
22846
+ * Reads the mapping, checks which packages are needed, and installs missing ones.
22847
+ */
22848
+ async autoInstallSkills(agents) {
22849
+ const results = [];
22850
+ try {
22851
+ const mappingsPath = path49.join(
22852
+ __dirname,
22853
+ "..",
22854
+ "..",
22855
+ "templates",
22856
+ "config",
22857
+ "skill-mappings.json"
22858
+ );
22859
+ const mappingsContent = await fs45.readFile(mappingsPath, "utf-8");
22860
+ const mappings = JSON.parse(mappingsContent);
22861
+ const agentToSkillMap = mappings.agentToSkillMap || {};
22862
+ const packagesToInstall = [];
22863
+ for (const agent of agents) {
22864
+ const mapping = agentToSkillMap[agent.name];
22865
+ if (mapping?.packages) {
22866
+ for (const pkg of mapping.packages) {
22867
+ packagesToInstall.push({ pkg, agent: agent.name });
22868
+ }
22869
+ }
22870
+ }
22871
+ if (packagesToInstall.length === 0) return results;
22872
+ const skillsDir = path49.join(os14.homedir(), ".claude", "skills");
22873
+ for (const { pkg, agent } of packagesToInstall) {
22874
+ const skillName = pkg.split("/").pop() || pkg;
22875
+ const subdirPath = path49.join(skillsDir, skillName, "SKILL.md");
22876
+ const flatPath = path49.join(skillsDir, `${skillName}.md`);
22877
+ let alreadyInstalled = false;
22878
+ try {
22879
+ await fs45.access(subdirPath);
22880
+ alreadyInstalled = true;
22881
+ } catch {
22882
+ try {
22883
+ await fs45.access(flatPath);
22884
+ alreadyInstalled = true;
22885
+ } catch {
22886
+ }
22887
+ }
22888
+ if (alreadyInstalled) {
22889
+ results.push({ name: skillName, agent, status: "skipped" });
22890
+ continue;
22891
+ }
22892
+ try {
22893
+ const parts = pkg.split("/");
22894
+ let installSource;
22895
+ if (parts.length === 3) {
22896
+ installSource = `${parts[0]}/${parts[1]}@${parts[2]}`;
22897
+ } else {
22898
+ installSource = pkg;
22899
+ }
22900
+ const installResult = await skillInstaller.install(installSource);
22901
+ if (installResult.installed.length > 0) {
22902
+ results.push({ name: skillName, agent, status: "installed" });
22903
+ logger_default.info(`Installed skill: ${skillName} for agent: ${agent}`);
22904
+ } else if (installResult.errors.length > 0) {
22905
+ results.push({ name: skillName, agent, status: "error" });
22906
+ logger_default.debug(`Failed to install skill ${skillName}`, { errors: installResult.errors });
22907
+ } else {
22908
+ results.push({ name: skillName, agent, status: "skipped" });
22909
+ }
22910
+ } catch (error) {
22911
+ results.push({ name: skillName, agent, status: "error" });
22912
+ logger_default.debug(`Skill install error for ${skillName}`, { error: getErrorMessage(error) });
22913
+ }
22914
+ }
22915
+ } catch (error) {
22916
+ logger_default.debug("Skill auto-installation failed (non-critical)", { error: getErrorMessage(error) });
22917
+ }
22918
+ return results;
22919
+ }
22920
+ // ==========================================================================
22283
22921
  // CONTEXT FILE GENERATION
22284
22922
  // ==========================================================================
22285
22923
  async generateContextFiles(git, stats, commands, agents, sources) {
@@ -22300,10 +22938,10 @@ You are the ${name} expert for this project. Apply best practices for the detect
22300
22938
  // PROJECT.JSON UPDATE
22301
22939
  // ==========================================================================
22302
22940
  async updateProjectJson(git, stats) {
22303
- const projectJsonPath = path47.join(this.globalPath, "project.json");
22941
+ const projectJsonPath = path49.join(this.globalPath, "project.json");
22304
22942
  let existing = {};
22305
22943
  try {
22306
- existing = JSON.parse(await fs43.readFile(projectJsonPath, "utf-8"));
22944
+ existing = JSON.parse(await fs45.readFile(projectJsonPath, "utf-8"));
22307
22945
  } catch {
22308
22946
  }
22309
22947
  const updated = {
@@ -22325,16 +22963,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
22325
22963
  lastSyncCommit: git.recentCommits[0]?.hash || null,
22326
22964
  lastSyncBranch: git.branch
22327
22965
  };
22328
- await fs43.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
22966
+ await fs45.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
22329
22967
  }
22330
22968
  // ==========================================================================
22331
22969
  // STATE.JSON UPDATE
22332
22970
  // ==========================================================================
22333
22971
  async updateStateJson(stats, stack) {
22334
- const statePath = path47.join(this.globalPath, "storage", "state.json");
22972
+ const statePath = path49.join(this.globalPath, "storage", "state.json");
22335
22973
  let state = {};
22336
22974
  try {
22337
- state = JSON.parse(await fs43.readFile(statePath, "utf-8"));
22975
+ state = JSON.parse(await fs45.readFile(statePath, "utf-8"));
22338
22976
  } catch {
22339
22977
  }
22340
22978
  state.projectId = this.projectId;
@@ -22361,7 +22999,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
22361
22999
  lastAction: "Synced project",
22362
23000
  nextAction: 'Run `p. task "description"` to start working'
22363
23001
  };
22364
- await fs43.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
23002
+ await fs45.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
22365
23003
  try {
22366
23004
  await localStateGenerator.generate(
22367
23005
  this.projectPath,
@@ -22374,7 +23012,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
22374
23012
  // MEMORY LOGGING
22375
23013
  // ==========================================================================
22376
23014
  async logToMemory(git, stats) {
22377
- const memoryPath = path47.join(this.globalPath, "memory", "events.jsonl");
23015
+ const memoryPath = path49.join(this.globalPath, "memory", "events.jsonl");
22378
23016
  const event = {
22379
23017
  ts: date_helper_default.getTimestamp(),
22380
23018
  action: "sync",
@@ -22383,7 +23021,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
22383
23021
  fileCount: stats.fileCount,
22384
23022
  commitCount: git.commits
22385
23023
  };
22386
- await fs43.appendFile(memoryPath, `${JSON.stringify(event)}
23024
+ await fs45.appendFile(memoryPath, `${JSON.stringify(event)}
22387
23025
  `, "utf-8");
22388
23026
  }
22389
23027
  // ==========================================================================
@@ -22403,16 +23041,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
22403
23041
  let filteredChars = 0;
22404
23042
  for (const file of contextFiles) {
22405
23043
  try {
22406
- const filePath = path47.join(this.globalPath, file);
22407
- const content = await fs43.readFile(filePath, "utf-8");
23044
+ const filePath = path49.join(this.globalPath, file);
23045
+ const content = await fs45.readFile(filePath, "utf-8");
22408
23046
  filteredChars += content.length;
22409
23047
  } catch {
22410
23048
  }
22411
23049
  }
22412
23050
  for (const agent of agents) {
22413
23051
  try {
22414
- const agentPath = path47.join(this.globalPath, "agents", `${agent.name}.md`);
22415
- const content = await fs43.readFile(agentPath, "utf-8");
23052
+ const agentPath = path49.join(this.globalPath, "agents", `${agent.name}.md`);
23053
+ const content = await fs45.readFile(agentPath, "utf-8");
22416
23054
  filteredChars += content.length;
22417
23055
  } catch {
22418
23056
  }
@@ -22444,7 +23082,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
22444
23082
  // ==========================================================================
22445
23083
  async fileExists(filename) {
22446
23084
  try {
22447
- await fs43.access(path47.join(this.projectPath, filename));
23085
+ await fs45.access(path49.join(this.projectPath, filename));
22448
23086
  return true;
22449
23087
  } catch {
22450
23088
  return false;
@@ -22452,8 +23090,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
22452
23090
  }
22453
23091
  async getCliVersion() {
22454
23092
  try {
22455
- const pkgPath = path47.join(__dirname, "..", "..", "package.json");
22456
- const pkg = JSON.parse(await fs43.readFile(pkgPath, "utf-8"));
23093
+ const pkgPath = path49.join(__dirname, "..", "..", "package.json");
23094
+ const pkg = JSON.parse(await fs45.readFile(pkgPath, "utf-8"));
22457
23095
  return pkg.version || "0.0.0";
22458
23096
  } catch {
22459
23097
  return "0.0.0";
@@ -22613,22 +23251,22 @@ __export(uninstall_exports, {
22613
23251
  uninstall: () => uninstall
22614
23252
  });
22615
23253
  import { execSync as execSync3 } from "node:child_process";
22616
- import fs44 from "node:fs/promises";
22617
- import os12 from "node:os";
22618
- import path48 from "node:path";
23254
+ import fs46 from "node:fs/promises";
23255
+ import os15 from "node:os";
23256
+ import path50 from "node:path";
22619
23257
  import readline2 from "node:readline";
22620
23258
  import chalk12 from "chalk";
22621
23259
  async function getDirectorySize(dirPath) {
22622
23260
  let totalSize = 0;
22623
23261
  try {
22624
- const entries = await fs44.readdir(dirPath, { withFileTypes: true });
23262
+ const entries = await fs46.readdir(dirPath, { withFileTypes: true });
22625
23263
  for (const entry of entries) {
22626
- const entryPath = path48.join(dirPath, entry.name);
23264
+ const entryPath = path50.join(dirPath, entry.name);
22627
23265
  if (entry.isDirectory()) {
22628
23266
  totalSize += await getDirectorySize(entryPath);
22629
23267
  } else {
22630
23268
  try {
22631
- const stats = await fs44.stat(entryPath);
23269
+ const stats = await fs46.stat(entryPath);
22632
23270
  totalSize += stats.size;
22633
23271
  } catch {
22634
23272
  }
@@ -22647,7 +23285,7 @@ function formatSize(bytes) {
22647
23285
  }
22648
23286
  async function countDirectoryItems(dirPath) {
22649
23287
  try {
22650
- const entries = await fs44.readdir(dirPath, { withFileTypes: true });
23288
+ const entries = await fs46.readdir(dirPath, { withFileTypes: true });
22651
23289
  return entries.filter((e) => e.isDirectory()).length;
22652
23290
  } catch {
22653
23291
  return 0;
@@ -22680,7 +23318,7 @@ async function gatherUninstallItems() {
22680
23318
  const providerPaths = getProviderPaths();
22681
23319
  const prjctCliPath = path_manager_default.getGlobalBasePath();
22682
23320
  const prjctCliExists = await fileExists(prjctCliPath);
22683
- const projectCount = prjctCliExists ? await countDirectoryItems(path48.join(prjctCliPath, "projects")) : 0;
23321
+ const projectCount = prjctCliExists ? await countDirectoryItems(path50.join(prjctCliPath, "projects")) : 0;
22684
23322
  const prjctCliSize = prjctCliExists ? await getDirectorySize(prjctCliPath) : 0;
22685
23323
  items.push({
22686
23324
  path: prjctCliPath,
@@ -22690,12 +23328,12 @@ async function gatherUninstallItems() {
22690
23328
  count: projectCount,
22691
23329
  exists: prjctCliExists
22692
23330
  });
22693
- const claudeMdPath = path48.join(providerPaths.claude.config, "CLAUDE.md");
23331
+ const claudeMdPath = path50.join(providerPaths.claude.config, "CLAUDE.md");
22694
23332
  const claudeMdExists = await fileExists(claudeMdPath);
22695
23333
  let hasPrjctSection = false;
22696
23334
  if (claudeMdExists) {
22697
23335
  try {
22698
- const content = await fs44.readFile(claudeMdPath, "utf-8");
23336
+ const content = await fs46.readFile(claudeMdPath, "utf-8");
22699
23337
  hasPrjctSection = content.includes(PRJCT_START_MARKER) && content.includes(PRJCT_END_MARKER);
22700
23338
  } catch {
22701
23339
  }
@@ -22724,7 +23362,7 @@ async function gatherUninstallItems() {
22724
23362
  description: "Claude router",
22725
23363
  exists: claudeRouterExists
22726
23364
  });
22727
- const statusLinePath = path48.join(providerPaths.claude.config, "prjct-statusline.sh");
23365
+ const statusLinePath = path50.join(providerPaths.claude.config, "prjct-statusline.sh");
22728
23366
  const statusLineExists = await fileExists(statusLinePath);
22729
23367
  items.push({
22730
23368
  path: statusLinePath,
@@ -22740,12 +23378,12 @@ async function gatherUninstallItems() {
22740
23378
  description: "Gemini router",
22741
23379
  exists: geminiRouterExists
22742
23380
  });
22743
- const geminiMdPath = path48.join(providerPaths.gemini.config, "GEMINI.md");
23381
+ const geminiMdPath = path50.join(providerPaths.gemini.config, "GEMINI.md");
22744
23382
  const geminiMdExists = await fileExists(geminiMdPath);
22745
23383
  let hasGeminiPrjctSection = false;
22746
23384
  if (geminiMdExists) {
22747
23385
  try {
22748
- const content = await fs44.readFile(geminiMdPath, "utf-8");
23386
+ const content = await fs46.readFile(geminiMdPath, "utf-8");
22749
23387
  hasGeminiPrjctSection = content.includes(PRJCT_START_MARKER) && content.includes(PRJCT_END_MARKER);
22750
23388
  } catch {
22751
23389
  }
@@ -22762,7 +23400,7 @@ async function gatherUninstallItems() {
22762
23400
  }
22763
23401
  async function removePrjctSection(filePath) {
22764
23402
  try {
22765
- const content = await fs44.readFile(filePath, "utf-8");
23403
+ const content = await fs46.readFile(filePath, "utf-8");
22766
23404
  if (!content.includes(PRJCT_START_MARKER) || !content.includes(PRJCT_END_MARKER)) {
22767
23405
  return false;
22768
23406
  }
@@ -22771,9 +23409,9 @@ async function removePrjctSection(filePath) {
22771
23409
  let newContent = content.substring(0, startIndex) + content.substring(endIndex);
22772
23410
  newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
22773
23411
  if (!newContent || newContent.trim().length === 0) {
22774
- await fs44.unlink(filePath);
23412
+ await fs46.unlink(filePath);
22775
23413
  } else {
22776
- await fs44.writeFile(filePath, `${newContent}
23414
+ await fs46.writeFile(filePath, `${newContent}
22777
23415
  `, "utf-8");
22778
23416
  }
22779
23417
  return true;
@@ -22782,14 +23420,14 @@ async function removePrjctSection(filePath) {
22782
23420
  }
22783
23421
  }
22784
23422
  async function createBackup() {
22785
- const homeDir = os12.homedir();
23423
+ const homeDir = os15.homedir();
22786
23424
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
22787
- const backupDir = path48.join(homeDir, `.prjct-backup-${timestamp}`);
23425
+ const backupDir = path50.join(homeDir, `.prjct-backup-${timestamp}`);
22788
23426
  try {
22789
- await fs44.mkdir(backupDir, { recursive: true });
23427
+ await fs46.mkdir(backupDir, { recursive: true });
22790
23428
  const prjctCliPath = path_manager_default.getGlobalBasePath();
22791
23429
  if (await fileExists(prjctCliPath)) {
22792
- await copyDirectory(prjctCliPath, path48.join(backupDir, ".prjct-cli"));
23430
+ await copyDirectory(prjctCliPath, path50.join(backupDir, ".prjct-cli"));
22793
23431
  }
22794
23432
  return backupDir;
22795
23433
  } catch {
@@ -22797,15 +23435,15 @@ async function createBackup() {
22797
23435
  }
22798
23436
  }
22799
23437
  async function copyDirectory(src, dest) {
22800
- await fs44.mkdir(dest, { recursive: true });
22801
- const entries = await fs44.readdir(src, { withFileTypes: true });
23438
+ await fs46.mkdir(dest, { recursive: true });
23439
+ const entries = await fs46.readdir(src, { withFileTypes: true });
22802
23440
  for (const entry of entries) {
22803
- const srcPath = path48.join(src, entry.name);
22804
- const destPath = path48.join(dest, entry.name);
23441
+ const srcPath = path50.join(src, entry.name);
23442
+ const destPath = path50.join(dest, entry.name);
22805
23443
  if (entry.isDirectory()) {
22806
23444
  await copyDirectory(srcPath, destPath);
22807
23445
  } else {
22808
- await fs44.copyFile(srcPath, destPath);
23446
+ await fs46.copyFile(srcPath, destPath);
22809
23447
  }
22810
23448
  }
22811
23449
  }
@@ -22821,10 +23459,10 @@ async function performUninstall(items, installation, options) {
22821
23459
  deleted.push(item.path);
22822
23460
  }
22823
23461
  } else if (item.type === "directory") {
22824
- await fs44.rm(item.path, { recursive: true, force: true });
23462
+ await fs46.rm(item.path, { recursive: true, force: true });
22825
23463
  deleted.push(item.path);
22826
23464
  } else if (item.type === "file") {
22827
- await fs44.unlink(item.path);
23465
+ await fs46.unlink(item.path);
22828
23466
  deleted.push(item.path);
22829
23467
  }
22830
23468
  } catch (error) {
@@ -23000,7 +23638,7 @@ __export(watch_service_exports, {
23000
23638
  WatchService: () => WatchService,
23001
23639
  watchService: () => watchService
23002
23640
  });
23003
- import path49 from "node:path";
23641
+ import path51 from "node:path";
23004
23642
  import chalk13 from "chalk";
23005
23643
  import chokidar from "chokidar";
23006
23644
  var TRIGGER_PATTERNS, IGNORE_PATTERNS2, WatchService, watchService;
@@ -23205,7 +23843,7 @@ ${chalk13.dim(`[${timestamp}]`)} ${chalk13.cyan("\u27F3")} ${filesSummary} chang
23205
23843
  printStartup() {
23206
23844
  console.log("");
23207
23845
  console.log(chalk13.cyan("\u{1F441}\uFE0F Watching for changes..."));
23208
- console.log(chalk13.dim(` Project: ${path49.basename(this.projectPath)}`));
23846
+ console.log(chalk13.dim(` Project: ${path51.basename(this.projectPath)}`));
23209
23847
  console.log(chalk13.dim(` Debounce: ${this.options.debounceMs}ms`));
23210
23848
  console.log(chalk13.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
23211
23849
  console.log("");
@@ -23883,9 +24521,9 @@ __export(setup_exports, {
23883
24521
  run: () => run
23884
24522
  });
23885
24523
  import { execSync as execSync4 } from "node:child_process";
23886
- import fs45 from "node:fs/promises";
23887
- import os13 from "node:os";
23888
- import path50 from "node:path";
24524
+ import fs47 from "node:fs/promises";
24525
+ import os16 from "node:os";
24526
+ import path52 from "node:path";
23889
24527
  import chalk15 from "chalk";
23890
24528
  async function installAICLI(provider) {
23891
24529
  const packageName = provider.name === "claude" ? "@anthropic-ai/claude-code" : "@google/gemini-cli";
@@ -24024,12 +24662,12 @@ async function run() {
24024
24662
  }
24025
24663
  async function installGeminiRouter() {
24026
24664
  try {
24027
- const geminiCommandsDir = path50.join(os13.homedir(), ".gemini", "commands");
24028
- const routerSource = path50.join(getPackageRoot(), "templates", "commands", "p.toml");
24029
- const routerDest = path50.join(geminiCommandsDir, "p.toml");
24030
- await fs45.mkdir(geminiCommandsDir, { recursive: true });
24665
+ const geminiCommandsDir = path52.join(os16.homedir(), ".gemini", "commands");
24666
+ const routerSource = path52.join(getPackageRoot(), "templates", "commands", "p.toml");
24667
+ const routerDest = path52.join(geminiCommandsDir, "p.toml");
24668
+ await fs47.mkdir(geminiCommandsDir, { recursive: true });
24031
24669
  if (await fileExists(routerSource)) {
24032
- await fs45.copyFile(routerSource, routerDest);
24670
+ await fs47.copyFile(routerSource, routerDest);
24033
24671
  return true;
24034
24672
  }
24035
24673
  return false;
@@ -24040,15 +24678,15 @@ async function installGeminiRouter() {
24040
24678
  }
24041
24679
  async function installGeminiGlobalConfig() {
24042
24680
  try {
24043
- const geminiDir = path50.join(os13.homedir(), ".gemini");
24044
- const globalConfigPath = path50.join(geminiDir, "GEMINI.md");
24045
- const templatePath = path50.join(getPackageRoot(), "templates", "global", "GEMINI.md");
24046
- await fs45.mkdir(geminiDir, { recursive: true });
24047
- const templateContent = await fs45.readFile(templatePath, "utf-8");
24681
+ const geminiDir = path52.join(os16.homedir(), ".gemini");
24682
+ const globalConfigPath = path52.join(geminiDir, "GEMINI.md");
24683
+ const templatePath = path52.join(getPackageRoot(), "templates", "global", "GEMINI.md");
24684
+ await fs47.mkdir(geminiDir, { recursive: true });
24685
+ const templateContent = await fs47.readFile(templatePath, "utf-8");
24048
24686
  let existingContent = "";
24049
24687
  let configExists = false;
24050
24688
  try {
24051
- existingContent = await fs45.readFile(globalConfigPath, "utf-8");
24689
+ existingContent = await fs47.readFile(globalConfigPath, "utf-8");
24052
24690
  configExists = true;
24053
24691
  } catch (error) {
24054
24692
  if (isNotFoundError(error)) {
@@ -24058,7 +24696,7 @@ async function installGeminiGlobalConfig() {
24058
24696
  }
24059
24697
  }
24060
24698
  if (!configExists) {
24061
- await fs45.writeFile(globalConfigPath, templateContent, "utf-8");
24699
+ await fs47.writeFile(globalConfigPath, templateContent, "utf-8");
24062
24700
  return { success: true, action: "created" };
24063
24701
  }
24064
24702
  const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
@@ -24068,7 +24706,7 @@ async function installGeminiGlobalConfig() {
24068
24706
  const updatedContent2 = `${existingContent}
24069
24707
 
24070
24708
  ${templateContent}`;
24071
- await fs45.writeFile(globalConfigPath, updatedContent2, "utf-8");
24709
+ await fs47.writeFile(globalConfigPath, updatedContent2, "utf-8");
24072
24710
  return { success: true, action: "appended" };
24073
24711
  }
24074
24712
  const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
@@ -24080,7 +24718,7 @@ ${templateContent}`;
24080
24718
  templateContent.indexOf(endMarker) + endMarker.length
24081
24719
  );
24082
24720
  const updatedContent = beforeMarker + prjctSection + afterMarker;
24083
- await fs45.writeFile(globalConfigPath, updatedContent, "utf-8");
24721
+ await fs47.writeFile(globalConfigPath, updatedContent, "utf-8");
24084
24722
  return { success: true, action: "updated" };
24085
24723
  } catch (error) {
24086
24724
  console.error(`Gemini config warning: ${error.message}`);
@@ -24089,18 +24727,18 @@ ${templateContent}`;
24089
24727
  }
24090
24728
  async function installAntigravitySkill() {
24091
24729
  try {
24092
- const antigravitySkillsDir = path50.join(os13.homedir(), ".gemini", "antigravity", "skills");
24093
- const prjctSkillDir = path50.join(antigravitySkillsDir, "prjct");
24094
- const skillMdPath = path50.join(prjctSkillDir, "SKILL.md");
24095
- const templatePath = path50.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
24096
- await fs45.mkdir(prjctSkillDir, { recursive: true });
24730
+ const antigravitySkillsDir = path52.join(os16.homedir(), ".gemini", "antigravity", "skills");
24731
+ const prjctSkillDir = path52.join(antigravitySkillsDir, "prjct");
24732
+ const skillMdPath = path52.join(prjctSkillDir, "SKILL.md");
24733
+ const templatePath = path52.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
24734
+ await fs47.mkdir(prjctSkillDir, { recursive: true });
24097
24735
  const skillExists = await fileExists(skillMdPath);
24098
24736
  if (!await fileExists(templatePath)) {
24099
24737
  console.error("Antigravity SKILL.md template not found");
24100
24738
  return { success: false, action: null };
24101
24739
  }
24102
- const templateContent = await fs45.readFile(templatePath, "utf-8");
24103
- await fs45.writeFile(skillMdPath, templateContent, "utf-8");
24740
+ const templateContent = await fs47.readFile(templatePath, "utf-8");
24741
+ await fs47.writeFile(skillMdPath, templateContent, "utf-8");
24104
24742
  return { success: true, action: skillExists ? "updated" : "created" };
24105
24743
  } catch (error) {
24106
24744
  console.error(`Antigravity skill warning: ${error.message}`);
@@ -24119,24 +24757,24 @@ async function installCursorProject(projectRoot) {
24119
24757
  gitignoreUpdated: false
24120
24758
  };
24121
24759
  try {
24122
- const cursorDir = path50.join(projectRoot, ".cursor");
24123
- const rulesDir = path50.join(cursorDir, "rules");
24124
- const commandsDir = path50.join(cursorDir, "commands");
24125
- const routerMdcDest = path50.join(rulesDir, "prjct.mdc");
24126
- const routerMdcSource = path50.join(getPackageRoot(), "templates", "cursor", "router.mdc");
24127
- const cursorCommandsSource = path50.join(getPackageRoot(), "templates", "cursor", "commands");
24128
- await fs45.mkdir(rulesDir, { recursive: true });
24129
- await fs45.mkdir(commandsDir, { recursive: true });
24760
+ const cursorDir = path52.join(projectRoot, ".cursor");
24761
+ const rulesDir = path52.join(cursorDir, "rules");
24762
+ const commandsDir = path52.join(cursorDir, "commands");
24763
+ const routerMdcDest = path52.join(rulesDir, "prjct.mdc");
24764
+ const routerMdcSource = path52.join(getPackageRoot(), "templates", "cursor", "router.mdc");
24765
+ const cursorCommandsSource = path52.join(getPackageRoot(), "templates", "cursor", "commands");
24766
+ await fs47.mkdir(rulesDir, { recursive: true });
24767
+ await fs47.mkdir(commandsDir, { recursive: true });
24130
24768
  if (await fileExists(routerMdcSource)) {
24131
- await fs45.copyFile(routerMdcSource, routerMdcDest);
24769
+ await fs47.copyFile(routerMdcSource, routerMdcDest);
24132
24770
  result.rulesCreated = true;
24133
24771
  }
24134
24772
  if (await fileExists(cursorCommandsSource)) {
24135
- const commandFiles = (await fs45.readdir(cursorCommandsSource)).filter((f) => f.endsWith(".md"));
24773
+ const commandFiles = (await fs47.readdir(cursorCommandsSource)).filter((f) => f.endsWith(".md"));
24136
24774
  for (const file of commandFiles) {
24137
- const src = path50.join(cursorCommandsSource, file);
24138
- const dest = path50.join(commandsDir, file);
24139
- await fs45.copyFile(src, dest);
24775
+ const src = path52.join(cursorCommandsSource, file);
24776
+ const dest = path52.join(commandsDir, file);
24777
+ await fs47.copyFile(src, dest);
24140
24778
  }
24141
24779
  result.commandsCreated = commandFiles.length > 0;
24142
24780
  }
@@ -24150,7 +24788,7 @@ async function installCursorProject(projectRoot) {
24150
24788
  }
24151
24789
  async function addCursorToGitignore(projectRoot) {
24152
24790
  try {
24153
- const gitignorePath = path50.join(projectRoot, ".gitignore");
24791
+ const gitignorePath = path52.join(projectRoot, ".gitignore");
24154
24792
  const entriesToAdd = [
24155
24793
  "# prjct Cursor routers (regenerated per-developer)",
24156
24794
  ".cursor/rules/prjct.mdc",
@@ -24165,7 +24803,7 @@ async function addCursorToGitignore(projectRoot) {
24165
24803
  let content = "";
24166
24804
  let configExists = false;
24167
24805
  try {
24168
- content = await fs45.readFile(gitignorePath, "utf-8");
24806
+ content = await fs47.readFile(gitignorePath, "utf-8");
24169
24807
  configExists = true;
24170
24808
  } catch (error) {
24171
24809
  if (!isNotFoundError(error)) {
@@ -24180,7 +24818,7 @@ async function addCursorToGitignore(projectRoot) {
24180
24818
  ${entriesToAdd.join("\n")}
24181
24819
  ` : `${entriesToAdd.join("\n")}
24182
24820
  `;
24183
- await fs45.writeFile(gitignorePath, newContent, "utf-8");
24821
+ await fs47.writeFile(gitignorePath, newContent, "utf-8");
24184
24822
  return true;
24185
24823
  } catch (error) {
24186
24824
  console.error(`Gitignore update warning: ${error.message}`);
@@ -24188,11 +24826,11 @@ ${entriesToAdd.join("\n")}
24188
24826
  }
24189
24827
  }
24190
24828
  async function hasCursorProject(projectRoot) {
24191
- return await fileExists(path50.join(projectRoot, ".cursor"));
24829
+ return await fileExists(path52.join(projectRoot, ".cursor"));
24192
24830
  }
24193
24831
  async function needsCursorRegeneration(projectRoot) {
24194
- const cursorDir = path50.join(projectRoot, ".cursor");
24195
- const routerPath = path50.join(cursorDir, "rules", "prjct.mdc");
24832
+ const cursorDir = path52.join(projectRoot, ".cursor");
24833
+ const routerPath = path52.join(cursorDir, "rules", "prjct.mdc");
24196
24834
  return await fileExists(cursorDir) && !await fileExists(routerPath);
24197
24835
  }
24198
24836
  async function installWindsurfProject(projectRoot) {
@@ -24203,31 +24841,31 @@ async function installWindsurfProject(projectRoot) {
24203
24841
  gitignoreUpdated: false
24204
24842
  };
24205
24843
  try {
24206
- const windsurfDir = path50.join(projectRoot, ".windsurf");
24207
- const rulesDir = path50.join(windsurfDir, "rules");
24208
- const workflowsDir = path50.join(windsurfDir, "workflows");
24209
- const routerDest = path50.join(rulesDir, "prjct.md");
24210
- const routerSource = path50.join(getPackageRoot(), "templates", "windsurf", "router.md");
24211
- const windsurfWorkflowsSource = path50.join(
24844
+ const windsurfDir = path52.join(projectRoot, ".windsurf");
24845
+ const rulesDir = path52.join(windsurfDir, "rules");
24846
+ const workflowsDir = path52.join(windsurfDir, "workflows");
24847
+ const routerDest = path52.join(rulesDir, "prjct.md");
24848
+ const routerSource = path52.join(getPackageRoot(), "templates", "windsurf", "router.md");
24849
+ const windsurfWorkflowsSource = path52.join(
24212
24850
  getPackageRoot(),
24213
24851
  "templates",
24214
24852
  "windsurf",
24215
24853
  "workflows"
24216
24854
  );
24217
- await fs45.mkdir(rulesDir, { recursive: true });
24218
- await fs45.mkdir(workflowsDir, { recursive: true });
24855
+ await fs47.mkdir(rulesDir, { recursive: true });
24856
+ await fs47.mkdir(workflowsDir, { recursive: true });
24219
24857
  if (await fileExists(routerSource)) {
24220
- await fs45.copyFile(routerSource, routerDest);
24858
+ await fs47.copyFile(routerSource, routerDest);
24221
24859
  result.rulesCreated = true;
24222
24860
  }
24223
24861
  if (await fileExists(windsurfWorkflowsSource)) {
24224
- const workflowFiles = (await fs45.readdir(windsurfWorkflowsSource)).filter(
24862
+ const workflowFiles = (await fs47.readdir(windsurfWorkflowsSource)).filter(
24225
24863
  (f) => f.endsWith(".md")
24226
24864
  );
24227
24865
  for (const file of workflowFiles) {
24228
- const src = path50.join(windsurfWorkflowsSource, file);
24229
- const dest = path50.join(workflowsDir, file);
24230
- await fs45.copyFile(src, dest);
24866
+ const src = path52.join(windsurfWorkflowsSource, file);
24867
+ const dest = path52.join(workflowsDir, file);
24868
+ await fs47.copyFile(src, dest);
24231
24869
  }
24232
24870
  result.workflowsCreated = workflowFiles.length > 0;
24233
24871
  }
@@ -24241,7 +24879,7 @@ async function installWindsurfProject(projectRoot) {
24241
24879
  }
24242
24880
  async function addWindsurfToGitignore(projectRoot) {
24243
24881
  try {
24244
- const gitignorePath = path50.join(projectRoot, ".gitignore");
24882
+ const gitignorePath = path52.join(projectRoot, ".gitignore");
24245
24883
  const entriesToAdd = [
24246
24884
  "# prjct Windsurf routers (regenerated per-developer)",
24247
24885
  ".windsurf/rules/prjct.md",
@@ -24256,7 +24894,7 @@ async function addWindsurfToGitignore(projectRoot) {
24256
24894
  let content = "";
24257
24895
  let configExists = false;
24258
24896
  try {
24259
- content = await fs45.readFile(gitignorePath, "utf-8");
24897
+ content = await fs47.readFile(gitignorePath, "utf-8");
24260
24898
  configExists = true;
24261
24899
  } catch (error) {
24262
24900
  if (!isNotFoundError(error)) {
@@ -24271,7 +24909,7 @@ async function addWindsurfToGitignore(projectRoot) {
24271
24909
  ${entriesToAdd.join("\n")}
24272
24910
  ` : `${entriesToAdd.join("\n")}
24273
24911
  `;
24274
- await fs45.writeFile(gitignorePath, newContent, "utf-8");
24912
+ await fs47.writeFile(gitignorePath, newContent, "utf-8");
24275
24913
  return true;
24276
24914
  } catch (error) {
24277
24915
  console.error(`Gitignore update warning: ${error.message}`);
@@ -24279,32 +24917,32 @@ ${entriesToAdd.join("\n")}
24279
24917
  }
24280
24918
  }
24281
24919
  async function hasWindsurfProject(projectRoot) {
24282
- return await fileExists(path50.join(projectRoot, ".windsurf"));
24920
+ return await fileExists(path52.join(projectRoot, ".windsurf"));
24283
24921
  }
24284
24922
  async function needsWindsurfRegeneration(projectRoot) {
24285
- const windsurfDir = path50.join(projectRoot, ".windsurf");
24286
- const routerPath = path50.join(windsurfDir, "rules", "prjct.md");
24923
+ const windsurfDir = path52.join(projectRoot, ".windsurf");
24924
+ const routerPath = path52.join(windsurfDir, "rules", "prjct.md");
24287
24925
  return await fileExists(windsurfDir) && !await fileExists(routerPath);
24288
24926
  }
24289
24927
  async function migrateProjectsCliVersion() {
24290
24928
  try {
24291
- const projectsDir = path50.join(os13.homedir(), ".prjct-cli", "projects");
24929
+ const projectsDir = path52.join(os16.homedir(), ".prjct-cli", "projects");
24292
24930
  if (!await fileExists(projectsDir)) {
24293
24931
  return;
24294
24932
  }
24295
- const projectDirs = (await fs45.readdir(projectsDir, { withFileTypes: true })).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
24933
+ const projectDirs = (await fs47.readdir(projectsDir, { withFileTypes: true })).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
24296
24934
  let migrated = 0;
24297
24935
  for (const projectId of projectDirs) {
24298
- const projectJsonPath = path50.join(projectsDir, projectId, "project.json");
24936
+ const projectJsonPath = path52.join(projectsDir, projectId, "project.json");
24299
24937
  if (!await fileExists(projectJsonPath)) {
24300
24938
  continue;
24301
24939
  }
24302
24940
  try {
24303
- const content = await fs45.readFile(projectJsonPath, "utf8");
24941
+ const content = await fs47.readFile(projectJsonPath, "utf8");
24304
24942
  const project = JSON.parse(content);
24305
24943
  if (project.cliVersion !== VERSION) {
24306
24944
  project.cliVersion = VERSION;
24307
- await fs45.writeFile(projectJsonPath, JSON.stringify(project, null, 2));
24945
+ await fs47.writeFile(projectJsonPath, JSON.stringify(project, null, 2));
24308
24946
  migrated++;
24309
24947
  }
24310
24948
  } catch (error) {
@@ -24326,7 +24964,7 @@ async function ensureStatusLineSettings(settingsPath, statusLinePath) {
24326
24964
  let settings = {};
24327
24965
  if (await fileExists(settingsPath)) {
24328
24966
  try {
24329
- settings = JSON.parse(await fs45.readFile(settingsPath, "utf8"));
24967
+ settings = JSON.parse(await fs47.readFile(settingsPath, "utf8"));
24330
24968
  } catch (error) {
24331
24969
  if (!(error instanceof SyntaxError)) {
24332
24970
  throw error;
@@ -24334,42 +24972,42 @@ async function ensureStatusLineSettings(settingsPath, statusLinePath) {
24334
24972
  }
24335
24973
  }
24336
24974
  settings.statusLine = { type: "command", command: statusLinePath };
24337
- await fs45.writeFile(settingsPath, JSON.stringify(settings, null, 2));
24975
+ await fs47.writeFile(settingsPath, JSON.stringify(settings, null, 2));
24338
24976
  }
24339
24977
  async function installStatusLine() {
24340
24978
  try {
24341
- const claudeDir = path50.join(os13.homedir(), ".claude");
24342
- const settingsPath = path50.join(claudeDir, "settings.json");
24343
- const claudeStatusLinePath = path50.join(claudeDir, "prjct-statusline.sh");
24344
- const prjctStatusLineDir = path50.join(os13.homedir(), ".prjct-cli", "statusline");
24345
- const prjctStatusLinePath = path50.join(prjctStatusLineDir, "statusline.sh");
24346
- const prjctThemesDir = path50.join(prjctStatusLineDir, "themes");
24347
- const prjctLibDir = path50.join(prjctStatusLineDir, "lib");
24348
- const prjctComponentsDir = path50.join(prjctStatusLineDir, "components");
24349
- const prjctConfigPath = path50.join(prjctStatusLineDir, "config.json");
24350
- const assetsDir = path50.join(getPackageRoot(), "assets", "statusline");
24351
- const sourceScript = path50.join(assetsDir, "statusline.sh");
24352
- const sourceThemeDir = path50.join(assetsDir, "themes");
24353
- const sourceLibDir = path50.join(assetsDir, "lib");
24354
- const sourceComponentsDir = path50.join(assetsDir, "components");
24355
- const sourceConfigPath = path50.join(assetsDir, "default-config.json");
24979
+ const claudeDir = path52.join(os16.homedir(), ".claude");
24980
+ const settingsPath = path52.join(claudeDir, "settings.json");
24981
+ const claudeStatusLinePath = path52.join(claudeDir, "prjct-statusline.sh");
24982
+ const prjctStatusLineDir = path52.join(os16.homedir(), ".prjct-cli", "statusline");
24983
+ const prjctStatusLinePath = path52.join(prjctStatusLineDir, "statusline.sh");
24984
+ const prjctThemesDir = path52.join(prjctStatusLineDir, "themes");
24985
+ const prjctLibDir = path52.join(prjctStatusLineDir, "lib");
24986
+ const prjctComponentsDir = path52.join(prjctStatusLineDir, "components");
24987
+ const prjctConfigPath = path52.join(prjctStatusLineDir, "config.json");
24988
+ const assetsDir = path52.join(getPackageRoot(), "assets", "statusline");
24989
+ const sourceScript = path52.join(assetsDir, "statusline.sh");
24990
+ const sourceThemeDir = path52.join(assetsDir, "themes");
24991
+ const sourceLibDir = path52.join(assetsDir, "lib");
24992
+ const sourceComponentsDir = path52.join(assetsDir, "components");
24993
+ const sourceConfigPath = path52.join(assetsDir, "default-config.json");
24356
24994
  if (!await fileExists(claudeDir)) {
24357
- await fs45.mkdir(claudeDir, { recursive: true });
24995
+ await fs47.mkdir(claudeDir, { recursive: true });
24358
24996
  }
24359
24997
  if (!await fileExists(prjctStatusLineDir)) {
24360
- await fs45.mkdir(prjctStatusLineDir, { recursive: true });
24998
+ await fs47.mkdir(prjctStatusLineDir, { recursive: true });
24361
24999
  }
24362
25000
  if (!await fileExists(prjctThemesDir)) {
24363
- await fs45.mkdir(prjctThemesDir, { recursive: true });
25001
+ await fs47.mkdir(prjctThemesDir, { recursive: true });
24364
25002
  }
24365
25003
  if (!await fileExists(prjctLibDir)) {
24366
- await fs45.mkdir(prjctLibDir, { recursive: true });
25004
+ await fs47.mkdir(prjctLibDir, { recursive: true });
24367
25005
  }
24368
25006
  if (!await fileExists(prjctComponentsDir)) {
24369
- await fs45.mkdir(prjctComponentsDir, { recursive: true });
25007
+ await fs47.mkdir(prjctComponentsDir, { recursive: true });
24370
25008
  }
24371
25009
  if (await fileExists(prjctStatusLinePath)) {
24372
- const existingContent = await fs45.readFile(prjctStatusLinePath, "utf8");
25010
+ const existingContent = await fs47.readFile(prjctStatusLinePath, "utf8");
24373
25011
  if (existingContent.includes("CLI_VERSION=")) {
24374
25012
  const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
24375
25013
  if (versionMatch && versionMatch[1] !== VERSION) {
@@ -24377,7 +25015,7 @@ async function installStatusLine() {
24377
25015
  /CLI_VERSION="[^"]*"/,
24378
25016
  `CLI_VERSION="${VERSION}"`
24379
25017
  );
24380
- await fs45.writeFile(prjctStatusLinePath, updatedContent, { mode: 493 });
25018
+ await fs47.writeFile(prjctStatusLinePath, updatedContent, { mode: 493 });
24381
25019
  }
24382
25020
  await installStatusLineModules(sourceLibDir, prjctLibDir);
24383
25021
  await installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
@@ -24387,21 +25025,21 @@ async function installStatusLine() {
24387
25025
  }
24388
25026
  }
24389
25027
  if (await fileExists(sourceScript)) {
24390
- let scriptContent = await fs45.readFile(sourceScript, "utf8");
25028
+ let scriptContent = await fs47.readFile(sourceScript, "utf8");
24391
25029
  scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
24392
- await fs45.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
25030
+ await fs47.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
24393
25031
  await installStatusLineModules(sourceLibDir, prjctLibDir);
24394
25032
  await installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
24395
25033
  if (await fileExists(sourceThemeDir)) {
24396
- const themes = await fs45.readdir(sourceThemeDir);
25034
+ const themes = await fs47.readdir(sourceThemeDir);
24397
25035
  for (const theme of themes) {
24398
- const src = path50.join(sourceThemeDir, theme);
24399
- const dest = path50.join(prjctThemesDir, theme);
24400
- await fs45.copyFile(src, dest);
25036
+ const src = path52.join(sourceThemeDir, theme);
25037
+ const dest = path52.join(prjctThemesDir, theme);
25038
+ await fs47.copyFile(src, dest);
24401
25039
  }
24402
25040
  }
24403
25041
  if (!await fileExists(prjctConfigPath) && await fileExists(sourceConfigPath)) {
24404
- await fs45.copyFile(sourceConfigPath, prjctConfigPath);
25042
+ await fs47.copyFile(sourceConfigPath, prjctConfigPath);
24405
25043
  }
24406
25044
  } else {
24407
25045
  const scriptContent = `#!/bin/bash
@@ -24436,7 +25074,7 @@ if [ -f "$CONFIG" ]; then
24436
25074
  fi
24437
25075
  echo "prjct"
24438
25076
  `;
24439
- await fs45.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
25077
+ await fs47.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
24440
25078
  }
24441
25079
  await ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
24442
25080
  await ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
@@ -24448,10 +25086,10 @@ echo "prjct"
24448
25086
  }
24449
25087
  async function installContext7MCP() {
24450
25088
  try {
24451
- const claudeDir = path50.join(os13.homedir(), ".claude");
24452
- const mcpConfigPath = path50.join(claudeDir, "mcp.json");
25089
+ const claudeDir = path52.join(os16.homedir(), ".claude");
25090
+ const mcpConfigPath = path52.join(claudeDir, "mcp.json");
24453
25091
  if (!await fileExists(claudeDir)) {
24454
- await fs45.mkdir(claudeDir, { recursive: true });
25092
+ await fs47.mkdir(claudeDir, { recursive: true });
24455
25093
  }
24456
25094
  const context7Config = {
24457
25095
  mcpServers: {
@@ -24462,16 +25100,16 @@ async function installContext7MCP() {
24462
25100
  }
24463
25101
  };
24464
25102
  if (await fileExists(mcpConfigPath)) {
24465
- const existingContent = await fs45.readFile(mcpConfigPath, "utf-8");
25103
+ const existingContent = await fs47.readFile(mcpConfigPath, "utf-8");
24466
25104
  const existingConfig = JSON.parse(existingContent);
24467
25105
  if (existingConfig.mcpServers?.context7) {
24468
25106
  return;
24469
25107
  }
24470
25108
  existingConfig.mcpServers = existingConfig.mcpServers || {};
24471
25109
  existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
24472
- await fs45.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
25110
+ await fs47.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
24473
25111
  } else {
24474
- await fs45.writeFile(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
25112
+ await fs47.writeFile(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
24475
25113
  }
24476
25114
  } catch (error) {
24477
25115
  console.error(`Context7 MCP setup warning: ${error.message}`);
@@ -24481,34 +25119,34 @@ async function installStatusLineModules(sourceDir, destDir) {
24481
25119
  if (!await fileExists(sourceDir)) {
24482
25120
  return;
24483
25121
  }
24484
- const files = await fs45.readdir(sourceDir);
25122
+ const files = await fs47.readdir(sourceDir);
24485
25123
  for (const file of files) {
24486
25124
  if (file.endsWith(".sh")) {
24487
- const src = path50.join(sourceDir, file);
24488
- const dest = path50.join(destDir, file);
24489
- await fs45.copyFile(src, dest);
24490
- await fs45.chmod(dest, 493);
25125
+ const src = path52.join(sourceDir, file);
25126
+ const dest = path52.join(destDir, file);
25127
+ await fs47.copyFile(src, dest);
25128
+ await fs47.chmod(dest, 493);
24491
25129
  }
24492
25130
  }
24493
25131
  }
24494
25132
  async function ensureStatusLineSymlink(linkPath, targetPath) {
24495
25133
  try {
24496
25134
  if (await fileExists(linkPath)) {
24497
- const stats = await fs45.lstat(linkPath);
25135
+ const stats = await fs47.lstat(linkPath);
24498
25136
  if (stats.isSymbolicLink()) {
24499
- const existingTarget = await fs45.readlink(linkPath);
25137
+ const existingTarget = await fs47.readlink(linkPath);
24500
25138
  if (existingTarget === targetPath) {
24501
25139
  return;
24502
25140
  }
24503
25141
  }
24504
- await fs45.unlink(linkPath);
25142
+ await fs47.unlink(linkPath);
24505
25143
  }
24506
- await fs45.symlink(targetPath, linkPath);
25144
+ await fs47.symlink(targetPath, linkPath);
24507
25145
  } catch (_error) {
24508
25146
  try {
24509
25147
  if (await fileExists(targetPath)) {
24510
- await fs45.copyFile(targetPath, linkPath);
24511
- await fs45.chmod(linkPath, 493);
25148
+ await fs47.copyFile(targetPath, linkPath);
25149
+ await fs47.chmod(linkPath, 493);
24512
25150
  }
24513
25151
  } catch (copyError) {
24514
25152
  if (!isNotFoundError(copyError)) {
@@ -24922,7 +25560,7 @@ var init_registry2 = __esm({
24922
25560
  });
24923
25561
 
24924
25562
  // core/commands/analytics.ts
24925
- import path51 from "node:path";
25563
+ import path53 from "node:path";
24926
25564
  var AnalyticsCommands;
24927
25565
  var init_analytics = __esm({
24928
25566
  "core/commands/analytics.ts"() {
@@ -24948,7 +25586,7 @@ var init_analytics = __esm({
24948
25586
  output_default.failWithHint("NO_PROJECT_ID");
24949
25587
  return { success: false, error: "No project ID found" };
24950
25588
  }
24951
- const projectName = path51.basename(projectPath);
25589
+ const projectName = path53.basename(projectPath);
24952
25590
  const currentTask = await stateStorage.getCurrentTask(projectId);
24953
25591
  const queueTasks = await queueStorage.getActiveTasks(projectId);
24954
25592
  const shipped = await shippedStorage.getRecent(projectId, 5);
@@ -25200,8 +25838,8 @@ ${"\u2550".repeat(50)}
25200
25838
  });
25201
25839
 
25202
25840
  // core/commands/context.ts
25203
- import fs46 from "node:fs/promises";
25204
- import path52 from "node:path";
25841
+ import fs48 from "node:fs/promises";
25842
+ import path54 from "node:path";
25205
25843
  var ContextCommands, contextCommands;
25206
25844
  var init_context = __esm({
25207
25845
  "core/commands/context.ts"() {
@@ -25327,8 +25965,8 @@ var init_context = __esm({
25327
25965
  */
25328
25966
  async loadRepoAnalysis(globalPath) {
25329
25967
  try {
25330
- const analysisPath = path52.join(globalPath, "analysis", "repo-analysis.json");
25331
- const content = await fs46.readFile(analysisPath, "utf-8");
25968
+ const analysisPath = path54.join(globalPath, "analysis", "repo-analysis.json");
25969
+ const content = await fs48.readFile(analysisPath, "utf-8");
25332
25970
  const data = JSON.parse(content);
25333
25971
  return {
25334
25972
  ecosystem: data.ecosystem || "unknown",
@@ -25347,7 +25985,7 @@ var init_context = __esm({
25347
25985
  });
25348
25986
 
25349
25987
  // core/commands/cleanup.ts
25350
- import path53 from "node:path";
25988
+ import path55 from "node:path";
25351
25989
  async function cleanupMemory(projectPath) {
25352
25990
  const projectId = await config_manager_default.getProjectId(projectPath);
25353
25991
  const results = { rotated: [], totalSize: 0, freedSpace: 0 };
@@ -25363,7 +26001,7 @@ async function cleanupMemory(projectPath) {
25363
26001
  results.totalSize += sizeMB;
25364
26002
  const rotated = await jsonl_helper_default.rotateJsonLinesIfNeeded(filePath, 10);
25365
26003
  if (rotated) {
25366
- results.rotated.push(path53.basename(filePath));
26004
+ results.rotated.push(path55.basename(filePath));
25367
26005
  results.freedSpace += sizeMB;
25368
26006
  }
25369
26007
  }
@@ -25470,7 +26108,7 @@ var init_cleanup = __esm({
25470
26108
  });
25471
26109
 
25472
26110
  // core/commands/design.ts
25473
- import path54 from "node:path";
26111
+ import path56 from "node:path";
25474
26112
  async function design(target = null, options = {}, projectPath = process.cwd()) {
25475
26113
  try {
25476
26114
  const designType = options.type || "architecture";
@@ -25482,7 +26120,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
25482
26120
  const designTarget = target || "system";
25483
26121
  output_default.spin(`designing ${designType}...`);
25484
26122
  const projectId = await config_manager_default.getProjectId(projectPath);
25485
- const designsPath = path54.join(
26123
+ const designsPath = path56.join(
25486
26124
  path_manager_default.getGlobalProjectPath(projectId),
25487
26125
  "planning",
25488
26126
  "designs"
@@ -25522,7 +26160,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
25522
26160
  break;
25523
26161
  }
25524
26162
  const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
25525
- const designFilePath = path54.join(designsPath, designFileName);
26163
+ const designFilePath = path56.join(designsPath, designFileName);
25526
26164
  await file_helper_exports.writeFile(designFilePath, designContent);
25527
26165
  await memoryService.log(projectPath, "design_created", {
25528
26166
  type: designType,
@@ -25546,7 +26184,7 @@ var init_design = __esm({
25546
26184
  });
25547
26185
 
25548
26186
  // core/commands/snapshots.ts
25549
- import path55 from "node:path";
26187
+ import path57 from "node:path";
25550
26188
  async function recover(projectPath = process.cwd()) {
25551
26189
  try {
25552
26190
  const projectId = await config_manager_default.getProjectId(projectPath);
@@ -25598,7 +26236,7 @@ async function undo(projectPath = process.cwd()) {
25598
26236
  output_default.failWithHint("NO_PROJECT_ID");
25599
26237
  return { success: false, error: "No project ID found" };
25600
26238
  }
25601
- const snapshotsPath = path55.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
26239
+ const snapshotsPath = path57.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
25602
26240
  await file_helper_exports.ensureDir(snapshotsPath);
25603
26241
  const { execSync: execSync5 } = await import("node:child_process");
25604
26242
  try {
@@ -25616,7 +26254,7 @@ async function undo(projectPath = process.cwd()) {
25616
26254
  cwd: projectPath,
25617
26255
  encoding: "utf-8"
25618
26256
  });
25619
- const snapshotFile = path55.join(snapshotsPath, "history.json");
26257
+ const snapshotFile = path57.join(snapshotsPath, "history.json");
25620
26258
  let history2 = { snapshots: [], current: -1 };
25621
26259
  try {
25622
26260
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -25656,8 +26294,8 @@ async function redo(projectPath = process.cwd()) {
25656
26294
  output_default.failWithHint("NO_PROJECT_ID");
25657
26295
  return { success: false, error: "No project ID found" };
25658
26296
  }
25659
- const snapshotsPath = path55.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
25660
- const snapshotFile = path55.join(snapshotsPath, "history.json");
26297
+ const snapshotsPath = path57.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
26298
+ const snapshotFile = path57.join(snapshotsPath, "history.json");
25661
26299
  let history2;
25662
26300
  try {
25663
26301
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -25716,8 +26354,8 @@ async function history(projectPath = process.cwd()) {
25716
26354
  output_default.failWithHint("NO_PROJECT_ID");
25717
26355
  return { success: false, error: "No project ID found" };
25718
26356
  }
25719
- const snapshotsPath = path55.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
25720
- const snapshotFile = path55.join(snapshotsPath, "history.json");
26357
+ const snapshotsPath = path57.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
26358
+ const snapshotFile = path57.join(snapshotsPath, "history.json");
25721
26359
  let snapshotHistory;
25722
26360
  try {
25723
26361
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -25824,8 +26462,8 @@ var init_maintenance = __esm({
25824
26462
  });
25825
26463
 
25826
26464
  // core/commands/setup.ts
25827
- import fs47 from "node:fs/promises";
25828
- import path56 from "node:path";
26465
+ import fs49 from "node:fs/promises";
26466
+ import path58 from "node:path";
25829
26467
  import chalk16 from "chalk";
25830
26468
  var SetupCommands;
25831
26469
  var init_setup2 = __esm({
@@ -25953,7 +26591,7 @@ Please install it first:
25953
26591
  try {
25954
26592
  const claudeDir = path_manager_default.getClaudeDir();
25955
26593
  const settingsPath = path_manager_default.getClaudeSettingsPath();
25956
- const statusLinePath = path56.join(claudeDir, "prjct-statusline.sh");
26594
+ const statusLinePath = path58.join(claudeDir, "prjct-statusline.sh");
25957
26595
  const scriptContent = `#!/bin/bash
25958
26596
  # prjct Status Line for Claude Code
25959
26597
  # Shows version update notifications and current task
@@ -26011,11 +26649,11 @@ fi
26011
26649
  # Default: show prjct branding
26012
26650
  echo "\u26A1 prjct"
26013
26651
  `;
26014
- await fs47.writeFile(statusLinePath, scriptContent, { mode: 493 });
26652
+ await fs49.writeFile(statusLinePath, scriptContent, { mode: 493 });
26015
26653
  let settings = {};
26016
26654
  if (await fileExists(settingsPath)) {
26017
26655
  try {
26018
- settings = JSON.parse(await fs47.readFile(settingsPath, "utf8"));
26656
+ settings = JSON.parse(await fs49.readFile(settingsPath, "utf8"));
26019
26657
  } catch (_error) {
26020
26658
  }
26021
26659
  }
@@ -26023,7 +26661,7 @@ echo "\u26A1 prjct"
26023
26661
  type: "command",
26024
26662
  command: statusLinePath
26025
26663
  };
26026
- await fs47.writeFile(settingsPath, JSON.stringify(settings, null, 2));
26664
+ await fs49.writeFile(settingsPath, JSON.stringify(settings, null, 2));
26027
26665
  return { success: true };
26028
26666
  } catch (error) {
26029
26667
  return { success: false, error: error.message };
@@ -26079,18 +26717,18 @@ echo "\u26A1 prjct"
26079
26717
  });
26080
26718
 
26081
26719
  // core/utils/project-commands.ts
26082
- import path57 from "node:path";
26720
+ import path59 from "node:path";
26083
26721
  async function detectPackageManager(projectPath, pkg) {
26084
26722
  const declared = pkg?.packageManager?.trim().toLowerCase();
26085
26723
  if (declared?.startsWith("pnpm@")) return "pnpm";
26086
26724
  if (declared?.startsWith("yarn@")) return "yarn";
26087
26725
  if (declared?.startsWith("bun@")) return "bun";
26088
26726
  if (declared?.startsWith("npm@")) return "npm";
26089
- if (await fileExists2(path57.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
26090
- if (await fileExists2(path57.join(projectPath, "yarn.lock"))) return "yarn";
26091
- if (await fileExists2(path57.join(projectPath, "bun.lockb"))) return "bun";
26092
- if (await fileExists2(path57.join(projectPath, "bun.lock"))) return "bun";
26093
- if (await fileExists2(path57.join(projectPath, "package-lock.json"))) return "npm";
26727
+ if (await fileExists2(path59.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
26728
+ if (await fileExists2(path59.join(projectPath, "yarn.lock"))) return "yarn";
26729
+ if (await fileExists2(path59.join(projectPath, "bun.lockb"))) return "bun";
26730
+ if (await fileExists2(path59.join(projectPath, "bun.lock"))) return "bun";
26731
+ if (await fileExists2(path59.join(projectPath, "package-lock.json"))) return "npm";
26094
26732
  return "npm";
26095
26733
  }
26096
26734
  function pmRun(pm, scriptName) {
@@ -26106,7 +26744,7 @@ function pmTest(pm) {
26106
26744
  return "npm test";
26107
26745
  }
26108
26746
  async function detectProjectCommands(projectPath) {
26109
- const pkgPath = path57.join(projectPath, "package.json");
26747
+ const pkgPath = path59.join(projectPath, "package.json");
26110
26748
  const pkg = await readJson(pkgPath, null);
26111
26749
  if (pkg) {
26112
26750
  const pm = await detectPackageManager(projectPath, pkg);
@@ -26123,27 +26761,27 @@ async function detectProjectCommands(projectPath) {
26123
26761
  }
26124
26762
  return result;
26125
26763
  }
26126
- if (await fileExists2(path57.join(projectPath, "pytest.ini"))) {
26764
+ if (await fileExists2(path59.join(projectPath, "pytest.ini"))) {
26127
26765
  return { stack: "python", test: { tool: "pytest", command: "pytest" } };
26128
26766
  }
26129
- const pyproject = await readFile(path57.join(projectPath, "pyproject.toml"), "");
26767
+ const pyproject = await readFile(path59.join(projectPath, "pyproject.toml"), "");
26130
26768
  if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
26131
26769
  return { stack: "python", test: { tool: "pytest", command: "pytest" } };
26132
26770
  }
26133
- if (await fileExists2(path57.join(projectPath, "Cargo.toml"))) {
26771
+ if (await fileExists2(path59.join(projectPath, "Cargo.toml"))) {
26134
26772
  return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
26135
26773
  }
26136
- if (await fileExists2(path57.join(projectPath, "go.mod"))) {
26774
+ if (await fileExists2(path59.join(projectPath, "go.mod"))) {
26137
26775
  return { stack: "go", test: { tool: "go", command: "go test ./..." } };
26138
26776
  }
26139
26777
  const files = await listFiles(projectPath);
26140
26778
  if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
26141
26779
  return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
26142
26780
  }
26143
- if (await fileExists2(path57.join(projectPath, "pom.xml"))) {
26781
+ if (await fileExists2(path59.join(projectPath, "pom.xml"))) {
26144
26782
  return { stack: "java", test: { tool: "maven", command: "mvn test" } };
26145
26783
  }
26146
- if (await fileExists2(path57.join(projectPath, "gradlew")) && (await fileExists2(path57.join(projectPath, "build.gradle")) || await fileExists2(path57.join(projectPath, "build.gradle.kts")))) {
26784
+ if (await fileExists2(path59.join(projectPath, "gradlew")) && (await fileExists2(path59.join(projectPath, "build.gradle")) || await fileExists2(path59.join(projectPath, "build.gradle.kts")))) {
26147
26785
  return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
26148
26786
  }
26149
26787
  return { stack: "unknown" };
@@ -26160,8 +26798,8 @@ var init_project_commands = __esm({
26160
26798
  });
26161
26799
 
26162
26800
  // core/workflow/workflow-preferences.ts
26163
- import { exec as exec16 } from "node:child_process";
26164
- import { promisify as promisify16 } from "node:util";
26801
+ import { exec as exec17 } from "node:child_process";
26802
+ import { promisify as promisify18 } from "node:util";
26165
26803
  import chalk17 from "chalk";
26166
26804
  function prefKey(hook, command) {
26167
26805
  return `workflow:${hook}_${command}`;
@@ -26233,7 +26871,7 @@ async function runWorkflowHooks(projectId, phase, command, options = {}) {
26233
26871
  ${chalk17.dim(`Running ${phase}-${command}: ${action}`)}`);
26234
26872
  try {
26235
26873
  const startTime = Date.now();
26236
- await execAsync11(action, {
26874
+ await execAsync12(action, {
26237
26875
  timeout: 6e4,
26238
26876
  cwd: options.projectPath || process.cwd(),
26239
26877
  env: { ...process.env }
@@ -26297,12 +26935,12 @@ Set one: "p. workflow antes de ship corre los tests"`;
26297
26935
  lines.push(chalk17.dim('Remove: "p. workflow quita el hook de ship"'));
26298
26936
  return lines.join("\n");
26299
26937
  }
26300
- var execAsync11, sessionPreferences, oncePreferences;
26938
+ var execAsync12, sessionPreferences, oncePreferences;
26301
26939
  var init_workflow_preferences = __esm({
26302
26940
  "core/workflow/workflow-preferences.ts"() {
26303
26941
  "use strict";
26304
26942
  init_memory_system();
26305
- execAsync11 = promisify16(exec16);
26943
+ execAsync12 = promisify18(exec17);
26306
26944
  sessionPreferences = /* @__PURE__ */ new Map();
26307
26945
  oncePreferences = /* @__PURE__ */ new Map();
26308
26946
  __name(prefKey, "prefKey");
@@ -26316,7 +26954,7 @@ var init_workflow_preferences = __esm({
26316
26954
  });
26317
26955
 
26318
26956
  // core/commands/shipping.ts
26319
- import path58 from "node:path";
26957
+ import path60 from "node:path";
26320
26958
  var ShippingCommands;
26321
26959
  var init_shipping = __esm({
26322
26960
  "core/commands/shipping.ts"() {
@@ -26462,7 +27100,7 @@ ${result.stderr}`.trim();
26462
27100
  */
26463
27101
  async _bumpVersion(projectPath) {
26464
27102
  try {
26465
- const pkgPath = path58.join(projectPath, "package.json");
27103
+ const pkgPath = path60.join(projectPath, "package.json");
26466
27104
  const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
26467
27105
  const oldVersion = pkg?.version || "0.0.0";
26468
27106
  const [major, minor, patch] = oldVersion.split(".").map(Number);
@@ -26484,7 +27122,7 @@ ${result.stderr}`.trim();
26484
27122
  */
26485
27123
  async _updateChangelog(feature, version, projectPath) {
26486
27124
  try {
26487
- const changelogPath = path58.join(projectPath, "CHANGELOG.md");
27125
+ const changelogPath = path60.join(projectPath, "CHANGELOG.md");
26488
27126
  const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
26489
27127
  const entry = `## [${version}] - ${date_helper_default.formatDate(/* @__PURE__ */ new Date())}
26490
27128
 
@@ -26583,14 +27221,14 @@ var init_cache2 = __esm({
26583
27221
  });
26584
27222
 
26585
27223
  // core/utils/keychain.ts
26586
- import { exec as exec17 } from "node:child_process";
26587
- import { promisify as promisify17 } from "node:util";
27224
+ import { exec as exec18 } from "node:child_process";
27225
+ import { promisify as promisify19 } from "node:util";
26588
27226
  async function getCredential(key) {
26589
27227
  if (process.platform !== "darwin") {
26590
27228
  return getEnvFallback(key);
26591
27229
  }
26592
27230
  try {
26593
- const { stdout } = await execAsync12(
27231
+ const { stdout } = await execAsync13(
26594
27232
  `security find-generic-password -s "${SERVICE_NAME}" -a "${key}" -w 2>/dev/null`
26595
27233
  );
26596
27234
  return stdout.trim() || null;
@@ -26606,11 +27244,11 @@ function getEnvFallback(key) {
26606
27244
  const envVar = envMap[key];
26607
27245
  return process.env[envVar] || null;
26608
27246
  }
26609
- var execAsync12, SERVICE_NAME;
27247
+ var execAsync13, SERVICE_NAME;
26610
27248
  var init_keychain = __esm({
26611
27249
  "core/utils/keychain.ts"() {
26612
27250
  "use strict";
26613
- execAsync12 = promisify17(exec17);
27251
+ execAsync13 = promisify19(exec18);
26614
27252
  SERVICE_NAME = "prjct-cli";
26615
27253
  __name(getCredential, "getCredential");
26616
27254
  __name(getEnvFallback, "getEnvFallback");
@@ -27376,11 +28014,11 @@ var init_linear = __esm({
27376
28014
  });
27377
28015
 
27378
28016
  // core/utils/project-credentials.ts
27379
- import fs48 from "node:fs/promises";
27380
- import os14 from "node:os";
27381
- import path59 from "node:path";
28017
+ import fs50 from "node:fs/promises";
28018
+ import os17 from "node:os";
28019
+ import path61 from "node:path";
27382
28020
  function getCredentialsPath(projectId) {
27383
- return path59.join(os14.homedir(), ".prjct-cli", "projects", projectId, "config", "credentials.json");
28021
+ return path61.join(os17.homedir(), ".prjct-cli", "projects", projectId, "config", "credentials.json");
27384
28022
  }
27385
28023
  async function getProjectCredentials(projectId) {
27386
28024
  const credPath = getCredentialsPath(projectId);
@@ -27388,7 +28026,7 @@ async function getProjectCredentials(projectId) {
27388
28026
  return {};
27389
28027
  }
27390
28028
  try {
27391
- return JSON.parse(await fs48.readFile(credPath, "utf-8"));
28029
+ return JSON.parse(await fs50.readFile(credPath, "utf-8"));
27392
28030
  } catch (error) {
27393
28031
  console.error("[project-credentials] Failed to read credentials:", error.message);
27394
28032
  return {};
@@ -27966,7 +28604,7 @@ var require_package = __commonJS({
27966
28604
  "package.json"(exports, module) {
27967
28605
  module.exports = {
27968
28606
  name: "prjct-cli",
27969
- version: "1.5.1",
28607
+ version: "1.6.1",
27970
28608
  description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
27971
28609
  main: "core/index.ts",
27972
28610
  bin: {
@@ -28073,8 +28711,8 @@ var require_package = __commonJS({
28073
28711
 
28074
28712
  // core/index.ts
28075
28713
  var core_exports = {};
28076
- import os15 from "node:os";
28077
- import path60 from "node:path";
28714
+ import os18 from "node:os";
28715
+ import path62 from "node:path";
28078
28716
  import chalk18 from "chalk";
28079
28717
  async function main() {
28080
28718
  const [commandName, ...rawArgs] = process.argv.slice(2);
@@ -28271,13 +28909,13 @@ function parseCommandArgs(_cmd, rawArgs) {
28271
28909
  }
28272
28910
  async function displayVersion(version) {
28273
28911
  const detection = await detectAllProviders();
28274
- const claudeCommandPath = path60.join(os15.homedir(), ".claude", "commands", "p.md");
28275
- const geminiCommandPath = path60.join(os15.homedir(), ".gemini", "commands", "p.toml");
28912
+ const claudeCommandPath = path62.join(os18.homedir(), ".claude", "commands", "p.md");
28913
+ const geminiCommandPath = path62.join(os18.homedir(), ".gemini", "commands", "p.toml");
28276
28914
  const [claudeConfigured, geminiConfigured, cursorConfigured, cursorExists] = await Promise.all([
28277
28915
  fileExists(claudeCommandPath),
28278
28916
  fileExists(geminiCommandPath),
28279
- fileExists(path60.join(process.cwd(), ".cursor", "commands", "sync.md")),
28280
- fileExists(path60.join(process.cwd(), ".cursor"))
28917
+ fileExists(path62.join(process.cwd(), ".cursor", "commands", "sync.md")),
28918
+ fileExists(path62.join(process.cwd(), ".cursor"))
28281
28919
  ]);
28282
28920
  const antigravityDetection = await detectAntigravity();
28283
28921
  console.log(`
@@ -28413,8 +29051,8 @@ var init_core = __esm({
28413
29051
  init_ai_provider();
28414
29052
  init_config_manager();
28415
29053
  init_editors_config();
28416
- import os16 from "node:os";
28417
- import path61 from "node:path";
29054
+ import os19 from "node:os";
29055
+ import path63 from "node:path";
28418
29056
  import chalk19 from "chalk";
28419
29057
 
28420
29058
  // core/server/server.ts
@@ -29155,16 +29793,16 @@ __name(startServer, "startServer");
29155
29793
  init_fs_helpers();
29156
29794
  init_version();
29157
29795
  async function checkRoutersInstalled() {
29158
- const home = os16.homedir();
29796
+ const home = os19.homedir();
29159
29797
  const detection = await detectAllProviders();
29160
29798
  if (detection.claude.installed) {
29161
- const claudeRouter = path61.join(home, ".claude", "commands", "p.md");
29799
+ const claudeRouter = path63.join(home, ".claude", "commands", "p.md");
29162
29800
  if (!await fileExists(claudeRouter)) {
29163
29801
  return false;
29164
29802
  }
29165
29803
  }
29166
29804
  if (detection.gemini.installed) {
29167
- const geminiRouter = path61.join(home, ".gemini", "commands", "p.toml");
29805
+ const geminiRouter = path63.join(home, ".gemini", "commands", "p.toml");
29168
29806
  if (!await fileExists(geminiRouter)) {
29169
29807
  return false;
29170
29808
  }
@@ -29292,7 +29930,7 @@ if (args[0] === "start" || args[0] === "setup") {
29292
29930
  console.error('No prjct project found. Run "prjct init" first.');
29293
29931
  process.exitCode = 1;
29294
29932
  } else {
29295
- const linearCliPath = path61.join(__dirname, "..", "core", "cli", "linear.ts");
29933
+ const linearCliPath = path63.join(__dirname, "..", "core", "cli", "linear.ts");
29296
29934
  const linearArgs = ["--project", projectId, ...args.slice(1)];
29297
29935
  const child = spawn("bun", [linearCliPath, ...linearArgs], {
29298
29936
  stdio: "inherit",
@@ -29309,7 +29947,7 @@ if (args[0] === "start" || args[0] === "setup") {
29309
29947
  process.exitCode = 0;
29310
29948
  } else if (args[0] === "version" || args[0] === "-v" || args[0] === "--version") {
29311
29949
  const detection = await detectAllProviders();
29312
- const home = os16.homedir();
29950
+ const home = os19.homedir();
29313
29951
  const cwd = process.cwd();
29314
29952
  const [
29315
29953
  claudeConfigured,
@@ -29319,12 +29957,12 @@ if (args[0] === "start" || args[0] === "setup") {
29319
29957
  windsurfDetected,
29320
29958
  windsurfConfigured
29321
29959
  ] = await Promise.all([
29322
- fileExists(path61.join(home, ".claude", "commands", "p.md")),
29323
- fileExists(path61.join(home, ".gemini", "commands", "p.toml")),
29324
- fileExists(path61.join(cwd, ".cursor")),
29325
- fileExists(path61.join(cwd, ".cursor", "rules", "prjct.mdc")),
29326
- fileExists(path61.join(cwd, ".windsurf")),
29327
- fileExists(path61.join(cwd, ".windsurf", "rules", "prjct.md"))
29960
+ fileExists(path63.join(home, ".claude", "commands", "p.md")),
29961
+ fileExists(path63.join(home, ".gemini", "commands", "p.toml")),
29962
+ fileExists(path63.join(cwd, ".cursor")),
29963
+ fileExists(path63.join(cwd, ".cursor", "rules", "prjct.mdc")),
29964
+ fileExists(path63.join(cwd, ".windsurf")),
29965
+ fileExists(path63.join(cwd, ".windsurf", "rules", "prjct.md"))
29328
29966
  ]);
29329
29967
  console.log(`
29330
29968
  ${chalk19.cyan("p/")} prjct v${VERSION}
@@ -29363,7 +30001,7 @@ ${chalk19.dim("Run 'prjct init' to configure (Cursor/Windsurf IDE)")}
29363
30001
  ${chalk19.cyan("https://prjct.app")}
29364
30002
  `);
29365
30003
  } else {
29366
- const configPath = path61.join(os16.homedir(), ".prjct-cli", "config", "installed-editors.json");
30004
+ const configPath = path63.join(os19.homedir(), ".prjct-cli", "config", "installed-editors.json");
29367
30005
  const routersInstalled = await checkRoutersInstalled();
29368
30006
  if (!await fileExists(configPath) || !routersInstalled) {
29369
30007
  console.log(`