prjct-cli 0.60.1 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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) => (path58) => {
20
- var fn = map[path58];
19
+ var __glob = (map) => (path59) => {
20
+ var fn = map[path59];
21
21
  if (fn) return fn();
22
- throw new Error("Module not found in bundle: " + path58);
22
+ throw new Error("Module not found in bundle: " + path59);
23
23
  };
24
24
  var __esm = (fn, res) => function __init() {
25
25
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -4019,8 +4019,8 @@ function tryResolve(basePath, projectPath) {
4019
4019
  for (const ext of extensions) {
4020
4020
  const fullPath = basePath + ext;
4021
4021
  try {
4022
- const fs49 = __require("node:fs");
4023
- if (fs49.existsSync(fullPath) && fs49.statSync(fullPath).isFile()) {
4022
+ const fs50 = __require("node:fs");
4023
+ if (fs50.existsSync(fullPath) && fs50.statSync(fullPath).isFile()) {
4024
4024
  return path12.relative(projectPath, fullPath);
4025
4025
  }
4026
4026
  } catch {
@@ -5203,11 +5203,11 @@ async function runSignaturesTool(args2, projectPath) {
5203
5203
  }
5204
5204
  };
5205
5205
  }
5206
- const fs49 = await import("node:fs/promises");
5207
- const path58 = await import("node:path");
5208
- const fullPath = path58.isAbsolute(filePath) ? filePath : path58.join(projectPath, filePath);
5206
+ const fs50 = await import("node:fs/promises");
5207
+ const path59 = await import("node:path");
5208
+ const fullPath = path59.isAbsolute(filePath) ? filePath : path59.join(projectPath, filePath);
5209
5209
  try {
5210
- const stat = await fs49.stat(fullPath);
5210
+ const stat = await fs50.stat(fullPath);
5211
5211
  if (stat.isDirectory()) {
5212
5212
  const results = await extractDirectorySignatures(filePath, projectPath, {
5213
5213
  recursive: args2.includes("--recursive") || args2.includes("-r")
@@ -5274,11 +5274,11 @@ async function runSummaryTool(args2, projectPath) {
5274
5274
  }
5275
5275
  };
5276
5276
  }
5277
- const fs49 = await import("node:fs/promises");
5278
- const path58 = await import("node:path");
5279
- const fullPath = path58.isAbsolute(targetPath) ? targetPath : path58.join(projectPath, targetPath);
5277
+ const fs50 = await import("node:fs/promises");
5278
+ const path59 = await import("node:path");
5279
+ const fullPath = path59.isAbsolute(targetPath) ? targetPath : path59.join(projectPath, targetPath);
5280
5280
  try {
5281
- const stat = await fs49.stat(fullPath);
5281
+ const stat = await fs50.stat(fullPath);
5282
5282
  if (stat.isDirectory()) {
5283
5283
  const results = await summarizeDirectory(targetPath, projectPath, {
5284
5284
  recursive: args2.includes("--recursive") || args2.includes("-r")
@@ -11788,31 +11788,33 @@ var init_orchestrator_executor = __esm({
11788
11788
  *
11789
11789
  * Reads agent markdown files from {globalPath}/agents/
11790
11790
  * and extracts their content and skills from frontmatter.
11791
+ *
11792
+ * Uses parallel file reads for performance (PRJ-110).
11791
11793
  */
11792
11794
  async loadAgents(domains, projectId) {
11793
11795
  const globalPath = path_manager_default.getGlobalProjectPath(projectId);
11794
11796
  const agentsDir = path23.join(globalPath, "agents");
11795
- const agents = [];
11796
- for (const domain of domains) {
11797
+ const agentPromises = domains.map(async (domain) => {
11797
11798
  const possibleNames = [`${domain}.md`, `${domain}-agent.md`, `prjct-${domain}.md`];
11798
11799
  for (const fileName of possibleNames) {
11799
11800
  const filePath = path23.join(agentsDir, fileName);
11800
11801
  try {
11801
11802
  const content = await fs24.readFile(filePath, "utf-8");
11802
11803
  const { frontmatter, body } = this.parseAgentFile(content);
11803
- agents.push({
11804
+ return {
11804
11805
  name: fileName.replace(".md", ""),
11805
11806
  domain,
11806
11807
  content: body,
11807
11808
  skills: frontmatter.skills || [],
11808
11809
  filePath
11809
- });
11810
- break;
11810
+ };
11811
11811
  } catch {
11812
11812
  }
11813
11813
  }
11814
- }
11815
- return agents;
11814
+ return null;
11815
+ });
11816
+ const results = await Promise.all(agentPromises);
11817
+ return results.filter((agent) => agent !== null);
11816
11818
  }
11817
11819
  /**
11818
11820
  * Parse agent markdown file to extract frontmatter and body
@@ -11832,40 +11834,36 @@ var init_orchestrator_executor = __esm({
11832
11834
  * Load skills from agent frontmatter
11833
11835
  *
11834
11836
  * Skills are stored in ~/.claude/skills/{name}.md
11837
+ *
11838
+ * Uses parallel file reads for performance (PRJ-110).
11835
11839
  */
11836
11840
  async loadSkills(agents) {
11837
11841
  const skillsDir = path23.join(os8.homedir(), ".claude", "skills");
11838
- const skills = [];
11839
- const loadedSkillNames = /* @__PURE__ */ new Set();
11842
+ const uniqueSkillNames = /* @__PURE__ */ new Set();
11840
11843
  for (const agent of agents) {
11841
11844
  for (const skillName of agent.skills) {
11842
- if (loadedSkillNames.has(skillName)) continue;
11845
+ uniqueSkillNames.add(skillName);
11846
+ }
11847
+ }
11848
+ const skillPromises = Array.from(uniqueSkillNames).map(
11849
+ async (skillName) => {
11843
11850
  const flatPath = path23.join(skillsDir, `${skillName}.md`);
11844
11851
  const subdirPath = path23.join(skillsDir, skillName, "SKILL.md");
11845
- let content = null;
11846
- let resolvedPath = flatPath;
11847
11852
  try {
11848
- content = await fs24.readFile(subdirPath, "utf-8");
11849
- resolvedPath = subdirPath;
11853
+ const content = await fs24.readFile(subdirPath, "utf-8");
11854
+ return { name: skillName, content, filePath: subdirPath };
11850
11855
  } catch {
11851
11856
  try {
11852
- content = await fs24.readFile(flatPath, "utf-8");
11853
- resolvedPath = flatPath;
11857
+ const content = await fs24.readFile(flatPath, "utf-8");
11858
+ return { name: skillName, content, filePath: flatPath };
11854
11859
  } catch {
11855
- console.warn(`Skill not found: ${skillName}`);
11860
+ return null;
11856
11861
  }
11857
11862
  }
11858
- if (content) {
11859
- skills.push({
11860
- name: skillName,
11861
- content,
11862
- filePath: resolvedPath
11863
- });
11864
- loadedSkillNames.add(skillName);
11865
- }
11866
11863
  }
11867
- }
11868
- return skills;
11864
+ );
11865
+ const results = await Promise.all(skillPromises);
11866
+ return results.filter((skill) => skill !== null);
11869
11867
  }
11870
11868
  /**
11871
11869
  * Determine if task should be fragmented into subtasks
@@ -16760,16 +16758,16 @@ var init_onboarding = __esm({
16760
16758
  * Detect project type from file system
16761
16759
  */
16762
16760
  async detectProjectType() {
16763
- const fs49 = await import("node:fs/promises");
16764
- const path58 = await import("node:path");
16761
+ const fs50 = await import("node:fs/promises");
16762
+ const path59 = await import("node:path");
16765
16763
  try {
16766
- const files = await fs49.readdir(this.projectPath);
16764
+ const files = await fs50.readdir(this.projectPath);
16767
16765
  if (files.includes("turbo.json") || files.includes("lerna.json") || files.includes("nx.json")) {
16768
16766
  return "monorepo";
16769
16767
  }
16770
16768
  if (files.includes("package.json")) {
16771
- const pkgPath = path58.join(this.projectPath, "package.json");
16772
- const pkgContent = await fs49.readFile(pkgPath, "utf-8");
16769
+ const pkgPath = path59.join(this.projectPath, "package.json");
16770
+ const pkgContent = await fs50.readFile(pkgPath, "utf-8");
16773
16771
  const pkg = JSON.parse(pkgContent);
16774
16772
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
16775
16773
  if (pkg.bin) return "cli-tool";
@@ -16805,32 +16803,32 @@ var init_onboarding = __esm({
16805
16803
  * Detect installed AI agents from config files
16806
16804
  */
16807
16805
  async detectInstalledAgents() {
16808
- const fs49 = await import("node:fs/promises");
16809
- const path58 = await import("node:path");
16806
+ const fs50 = await import("node:fs/promises");
16807
+ const path59 = await import("node:path");
16810
16808
  const os17 = await import("node:os");
16811
16809
  const agents = [];
16812
16810
  try {
16813
- await fs49.access(path58.join(os17.homedir(), ".claude"));
16811
+ await fs50.access(path59.join(os17.homedir(), ".claude"));
16814
16812
  agents.push("claude");
16815
16813
  } catch {
16816
16814
  }
16817
16815
  try {
16818
- await fs49.access(path58.join(this.projectPath, ".cursorrules"));
16816
+ await fs50.access(path59.join(this.projectPath, ".cursorrules"));
16819
16817
  agents.push("cursor");
16820
16818
  } catch {
16821
16819
  }
16822
16820
  try {
16823
- await fs49.access(path58.join(this.projectPath, ".windsurfrules"));
16821
+ await fs50.access(path59.join(this.projectPath, ".windsurfrules"));
16824
16822
  agents.push("windsurf");
16825
16823
  } catch {
16826
16824
  }
16827
16825
  try {
16828
- await fs49.access(path58.join(this.projectPath, ".github", "copilot-instructions.md"));
16826
+ await fs50.access(path59.join(this.projectPath, ".github", "copilot-instructions.md"));
16829
16827
  agents.push("copilot");
16830
16828
  } catch {
16831
16829
  }
16832
16830
  try {
16833
- await fs49.access(path58.join(os17.homedir(), ".gemini"));
16831
+ await fs50.access(path59.join(os17.homedir(), ".gemini"));
16834
16832
  agents.push("gemini");
16835
16833
  } catch {
16836
16834
  }
@@ -16840,17 +16838,17 @@ var init_onboarding = __esm({
16840
16838
  * Detect tech stack from project files
16841
16839
  */
16842
16840
  async detectStack() {
16843
- const fs49 = await import("node:fs/promises");
16844
- const path58 = await import("node:path");
16841
+ const fs50 = await import("node:fs/promises");
16842
+ const path59 = await import("node:path");
16845
16843
  const stack = {
16846
16844
  language: "Unknown",
16847
16845
  technologies: []
16848
16846
  };
16849
16847
  try {
16850
- const files = await fs49.readdir(this.projectPath);
16848
+ const files = await fs50.readdir(this.projectPath);
16851
16849
  if (files.includes("package.json")) {
16852
- const pkgPath = path58.join(this.projectPath, "package.json");
16853
- const pkgContent = await fs49.readFile(pkgPath, "utf-8");
16850
+ const pkgPath = path59.join(this.projectPath, "package.json");
16851
+ const pkgContent = await fs50.readFile(pkgPath, "utf-8");
16854
16852
  const pkg = JSON.parse(pkgContent);
16855
16853
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
16856
16854
  stack.language = deps.typescript ? "TypeScript" : "JavaScript";
@@ -18946,8 +18944,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
18946
18944
  const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
18947
18945
  const specsPath2 = path37.join(globalPath2, "planning", "specs");
18948
18946
  try {
18949
- const fs49 = await import("node:fs/promises");
18950
- const files = await fs49.readdir(specsPath2);
18947
+ const fs50 = await import("node:fs/promises");
18948
+ const files = await fs50.readdir(specsPath2);
18951
18949
  const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
18952
18950
  if (specs.length === 0) {
18953
18951
  output_default.warn("no specs yet");
@@ -20090,9 +20088,125 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
20090
20088
  }
20091
20089
  });
20092
20090
 
20093
- // core/services/stack-detector.ts
20091
+ // core/services/local-state-generator.ts
20094
20092
  import fs40 from "node:fs/promises";
20095
20093
  import path42 from "node:path";
20094
+ var LOCAL_STATE_FILENAME, LocalStateGenerator, localStateGenerator;
20095
+ var init_local_state_generator = __esm({
20096
+ "core/services/local-state-generator.ts"() {
20097
+ "use strict";
20098
+ init_fs();
20099
+ LOCAL_STATE_FILENAME = ".prjct-state.md";
20100
+ LocalStateGenerator = class {
20101
+ static {
20102
+ __name(this, "LocalStateGenerator");
20103
+ }
20104
+ /**
20105
+ * Generate .prjct-state.md in the project root
20106
+ */
20107
+ async generate(projectPath, state) {
20108
+ const filePath = path42.join(projectPath, LOCAL_STATE_FILENAME);
20109
+ const content = this.toMarkdown(state);
20110
+ await fs40.writeFile(filePath, content, "utf-8");
20111
+ }
20112
+ /**
20113
+ * Remove local state file
20114
+ */
20115
+ async remove(projectPath) {
20116
+ const filePath = path42.join(projectPath, LOCAL_STATE_FILENAME);
20117
+ try {
20118
+ await fs40.unlink(filePath);
20119
+ } catch (error) {
20120
+ if (!isNotFoundError(error)) throw error;
20121
+ }
20122
+ }
20123
+ /**
20124
+ * Check if local state file exists
20125
+ */
20126
+ async exists(projectPath) {
20127
+ const filePath = path42.join(projectPath, LOCAL_STATE_FILENAME);
20128
+ try {
20129
+ await fs40.access(filePath);
20130
+ return true;
20131
+ } catch {
20132
+ return false;
20133
+ }
20134
+ }
20135
+ /**
20136
+ * Convert state to markdown format
20137
+ * Note: Uses runtime types since state.json has fields not in strict Zod schema
20138
+ */
20139
+ toMarkdown(state) {
20140
+ const lines = [
20141
+ "<!-- Auto-generated by prjct - DO NOT EDIT -->",
20142
+ "<!-- This file provides local state persistence for AI tools -->",
20143
+ "",
20144
+ "# prjct State",
20145
+ ""
20146
+ ];
20147
+ if (state.currentTask) {
20148
+ const task = state.currentTask;
20149
+ lines.push("## Current Task");
20150
+ lines.push("");
20151
+ lines.push(`**${task.description}**`);
20152
+ lines.push("");
20153
+ lines.push(`- Started: ${task.startedAt}`);
20154
+ if (task.linearId) {
20155
+ lines.push(`- Linear: ${task.linearId}`);
20156
+ }
20157
+ if (task.branch) {
20158
+ lines.push(`- Branch: ${task.branch}`);
20159
+ }
20160
+ lines.push(`- Status: ${task.status || "active"}`);
20161
+ lines.push("");
20162
+ if (task.subtasks && task.subtasks.length > 0) {
20163
+ lines.push("### Subtasks");
20164
+ lines.push("");
20165
+ task.subtasks.forEach((subtask, index) => {
20166
+ const statusIcon = subtask.status === "completed" ? "\u2705" : subtask.status === "in_progress" ? "\u25B6\uFE0F" : "\u23F3";
20167
+ const isActive = index === task.currentSubtaskIndex ? " \u2190 **Active**" : "";
20168
+ lines.push(`${index + 1}. ${statusIcon} ${subtask.description}${isActive}`);
20169
+ });
20170
+ lines.push("");
20171
+ const completed = task.subtasks.filter((s) => s.status === "completed").length;
20172
+ const total = task.subtasks.length;
20173
+ const percentage = Math.round(completed / total * 100);
20174
+ lines.push(`**Progress**: ${completed}/${total} (${percentage}%)`);
20175
+ lines.push("");
20176
+ }
20177
+ } else {
20178
+ lines.push("*No active task*");
20179
+ lines.push("");
20180
+ lines.push('Start a task with `p. task "description"`');
20181
+ lines.push("");
20182
+ }
20183
+ if (state.previousTask) {
20184
+ const prevTask = state.previousTask;
20185
+ lines.push("---");
20186
+ lines.push("");
20187
+ lines.push("## Previous Task");
20188
+ lines.push("");
20189
+ lines.push(`**${prevTask.description}**`);
20190
+ lines.push("");
20191
+ lines.push(`- Status: ${prevTask.status}`);
20192
+ if (prevTask.prUrl) {
20193
+ lines.push(`- PR: ${prevTask.prUrl}`);
20194
+ }
20195
+ lines.push("");
20196
+ }
20197
+ lines.push("---");
20198
+ lines.push(`*Last updated: ${state.lastUpdated || (/* @__PURE__ */ new Date()).toISOString()}*`);
20199
+ lines.push("");
20200
+ return lines.join("\n");
20201
+ }
20202
+ };
20203
+ localStateGenerator = new LocalStateGenerator();
20204
+ }
20205
+ });
20206
+
20207
+ // core/services/stack-detector.ts
20208
+ import fs41 from "node:fs/promises";
20209
+ import path43 from "node:path";
20096
20210
  var StackDetector;
20097
20211
  var init_stack_detector = __esm({
20098
20212
  "core/services/stack-detector.ts"() {
@@ -20251,8 +20365,8 @@ var init_stack_detector = __esm({
20251
20365
  */
20252
20366
  async readPackageJson() {
20253
20367
  try {
20254
- const pkgPath = path42.join(this.projectPath, "package.json");
20255
- const content = await fs40.readFile(pkgPath, "utf-8");
20368
+ const pkgPath = path43.join(this.projectPath, "package.json");
20369
+ const content = await fs41.readFile(pkgPath, "utf-8");
20256
20370
  return JSON.parse(content);
20257
20371
  } catch {
20258
20372
  return null;
@@ -20263,7 +20377,7 @@ var init_stack_detector = __esm({
20263
20377
  */
20264
20378
  async fileExists(filename) {
20265
20379
  try {
20266
- await fs40.access(path42.join(this.projectPath, filename));
20380
+ await fs41.access(path43.join(this.projectPath, filename));
20267
20381
  return true;
20268
20382
  } catch {
20269
20383
  return false;
@@ -20275,8 +20389,8 @@ var init_stack_detector = __esm({
20275
20389
 
20276
20390
  // core/services/sync-service.ts
20277
20391
  import { exec as exec11 } from "node:child_process";
20278
- import fs41 from "node:fs/promises";
20279
- import path43 from "node:path";
20392
+ import fs42 from "node:fs/promises";
20393
+ import path44 from "node:path";
20280
20394
  import { promisify as promisify11 } from "node:util";
20281
20395
  var execAsync6, SyncService, syncService;
20282
20396
  var init_sync_service = __esm({
@@ -20289,6 +20403,7 @@ var init_sync_service = __esm({
20289
20403
  init_metrics_storage();
20290
20404
  init_date_helper();
20291
20405
  init_context_generator();
20406
+ init_local_state_generator();
20292
20407
  init_stack_detector();
20293
20408
  execAsync6 = promisify11(exec11);
20294
20409
  SyncService = class {
@@ -20425,7 +20540,7 @@ var init_sync_service = __esm({
20425
20540
  async ensureDirectories() {
20426
20541
  const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
20427
20542
  await Promise.all(
20428
- dirs.map((dir) => fs41.mkdir(path43.join(this.globalPath, dir), { recursive: true }))
20543
+ dirs.map((dir) => fs42.mkdir(path44.join(this.globalPath, dir), { recursive: true }))
20429
20544
  );
20430
20545
  }
20431
20546
  // ==========================================================================
@@ -20495,7 +20610,7 @@ var init_sync_service = __esm({
20495
20610
  const stats = {
20496
20611
  fileCount: 0,
20497
20612
  version: "0.0.0",
20498
- name: path43.basename(this.projectPath),
20613
+ name: path44.basename(this.projectPath),
20499
20614
  ecosystem: "unknown",
20500
20615
  projectType: "simple",
20501
20616
  languages: [],
@@ -20511,8 +20626,8 @@ var init_sync_service = __esm({
20511
20626
  stats.fileCount = 0;
20512
20627
  }
20513
20628
  try {
20514
- const pkgPath = path43.join(this.projectPath, "package.json");
20515
- const pkg = JSON.parse(await fs41.readFile(pkgPath, "utf-8"));
20629
+ const pkgPath = path44.join(this.projectPath, "package.json");
20630
+ const pkg = JSON.parse(await fs42.readFile(pkgPath, "utf-8"));
20516
20631
  stats.version = pkg.version || "0.0.0";
20517
20632
  stats.name = pkg.name || stats.name;
20518
20633
  stats.ecosystem = "JavaScript";
@@ -20620,12 +20735,12 @@ var init_sync_service = __esm({
20620
20735
  // ==========================================================================
20621
20736
  async generateAgents(stack, stats) {
20622
20737
  const agents = [];
20623
- const agentsPath = path43.join(this.globalPath, "agents");
20738
+ const agentsPath = path44.join(this.globalPath, "agents");
20624
20739
  try {
20625
- const files = await fs41.readdir(agentsPath);
20740
+ const files = await fs42.readdir(agentsPath);
20626
20741
  for (const file of files) {
20627
20742
  if (file.endsWith(".md")) {
20628
- await fs41.unlink(path43.join(agentsPath, file));
20743
+ await fs42.unlink(path44.join(agentsPath, file));
20629
20744
  }
20630
20745
  }
20631
20746
  } catch {
@@ -20665,7 +20780,7 @@ var init_sync_service = __esm({
20665
20780
  async generateWorkflowAgent(name, agentsPath) {
20666
20781
  let content = "";
20667
20782
  try {
20668
- const templatePath = path43.join(
20783
+ const templatePath = path44.join(
20669
20784
  __dirname,
20670
20785
  "..",
20671
20786
  "..",
@@ -20674,16 +20789,16 @@ var init_sync_service = __esm({
20674
20789
  "workflow",
20675
20790
  `${name}.md`
20676
20791
  );
20677
- content = await fs41.readFile(templatePath, "utf-8");
20792
+ content = await fs42.readFile(templatePath, "utf-8");
20678
20793
  } catch {
20679
20794
  content = this.generateMinimalWorkflowAgent(name);
20680
20795
  }
20681
- await fs41.writeFile(path43.join(agentsPath, `${name}.md`), content, "utf-8");
20796
+ await fs42.writeFile(path44.join(agentsPath, `${name}.md`), content, "utf-8");
20682
20797
  }
20683
20798
  async generateDomainAgent(name, agentsPath, stats, stack) {
20684
20799
  let content = "";
20685
20800
  try {
20686
- const templatePath = path43.join(
20801
+ const templatePath = path44.join(
20687
20802
  __dirname,
20688
20803
  "..",
20689
20804
  "..",
@@ -20692,14 +20807,14 @@ var init_sync_service = __esm({
20692
20807
  "domain",
20693
20808
  `${name}.md`
20694
20809
  );
20695
- content = await fs41.readFile(templatePath, "utf-8");
20810
+ content = await fs42.readFile(templatePath, "utf-8");
20696
20811
  content = content.replace("{projectName}", stats.name);
20697
20812
  content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
20698
20813
  content = content.replace("{ecosystem}", stats.ecosystem);
20699
20814
  } catch {
20700
20815
  content = this.generateMinimalDomainAgent(name, stats, stack);
20701
20816
  }
20702
- await fs41.writeFile(path43.join(agentsPath, `${name}.md`), content, "utf-8");
20817
+ await fs42.writeFile(path44.join(agentsPath, `${name}.md`), content, "utf-8");
20703
20818
  }
20704
20819
  generateMinimalWorkflowAgent(name) {
20705
20820
  const descriptions = {
@@ -20767,8 +20882,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
20767
20882
  })),
20768
20883
  agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
20769
20884
  };
20770
- fs41.writeFile(
20771
- path43.join(this.globalPath, "config", "skills.json"),
20885
+ fs42.writeFile(
20886
+ path44.join(this.globalPath, "config", "skills.json"),
20772
20887
  JSON.stringify(skillsConfig, null, 2),
20773
20888
  "utf-8"
20774
20889
  ).catch(() => {
@@ -20790,10 +20905,10 @@ You are the ${name} expert for this project. Apply best practices for the detect
20790
20905
  // PROJECT.JSON UPDATE
20791
20906
  // ==========================================================================
20792
20907
  async updateProjectJson(git, stats) {
20793
- const projectJsonPath = path43.join(this.globalPath, "project.json");
20908
+ const projectJsonPath = path44.join(this.globalPath, "project.json");
20794
20909
  let existing = {};
20795
20910
  try {
20796
- existing = JSON.parse(await fs41.readFile(projectJsonPath, "utf-8"));
20911
+ existing = JSON.parse(await fs42.readFile(projectJsonPath, "utf-8"));
20797
20912
  } catch {
20798
20913
  }
20799
20914
  const updated = {
@@ -20815,16 +20930,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
20815
20930
  lastSyncCommit: git.recentCommits[0]?.hash || null,
20816
20931
  lastSyncBranch: git.branch
20817
20932
  };
20818
- await fs41.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
20933
+ await fs42.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
20819
20934
  }
20820
20935
  // ==========================================================================
20821
20936
  // STATE.JSON UPDATE
20822
20937
  // ==========================================================================
20823
20938
  async updateStateJson(stats, stack) {
20824
- const statePath = path43.join(this.globalPath, "storage", "state.json");
20939
+ const statePath = path44.join(this.globalPath, "storage", "state.json");
20825
20940
  let state = {};
20826
20941
  try {
20827
- state = JSON.parse(await fs41.readFile(statePath, "utf-8"));
20942
+ state = JSON.parse(await fs42.readFile(statePath, "utf-8"));
20828
20943
  } catch {
20829
20944
  }
20830
20945
  state.projectId = this.projectId;
@@ -20851,13 +20966,20 @@ You are the ${name} expert for this project. Apply best practices for the detect
20851
20966
  lastAction: "Synced project",
20852
20967
  nextAction: 'Run `p. task "description"` to start working'
20853
20968
  };
20854
- await fs41.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
20969
+ await fs42.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
20970
+ try {
20971
+ await localStateGenerator.generate(
20972
+ this.projectPath,
20973
+ state
20974
+ );
20975
+ } catch {
20976
+ }
20855
20977
  }
20856
20978
  // ==========================================================================
20857
20979
  // MEMORY LOGGING
20858
20980
  // ==========================================================================
20859
20981
  async logToMemory(git, stats) {
20860
- const memoryPath = path43.join(this.globalPath, "memory", "events.jsonl");
20982
+ const memoryPath = path44.join(this.globalPath, "memory", "events.jsonl");
20861
20983
  const event = {
20862
20984
  ts: date_helper_default.getTimestamp(),
20863
20985
  action: "sync",
@@ -20866,7 +20988,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
20866
20988
  fileCount: stats.fileCount,
20867
20989
  commitCount: git.commits
20868
20990
  };
20869
- await fs41.appendFile(memoryPath, `${JSON.stringify(event)}
20991
+ await fs42.appendFile(memoryPath, `${JSON.stringify(event)}
20870
20992
  `, "utf-8");
20871
20993
  }
20872
20994
  // ==========================================================================
@@ -20886,16 +21008,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
20886
21008
  let filteredChars = 0;
20887
21009
  for (const file of contextFiles) {
20888
21010
  try {
20889
- const filePath = path43.join(this.globalPath, file);
20890
- const content = await fs41.readFile(filePath, "utf-8");
21011
+ const filePath = path44.join(this.globalPath, file);
21012
+ const content = await fs42.readFile(filePath, "utf-8");
20891
21013
  filteredChars += content.length;
20892
21014
  } catch {
20893
21015
  }
20894
21016
  }
20895
21017
  for (const agent of agents) {
20896
21018
  try {
20897
- const agentPath = path43.join(this.globalPath, "agents", `${agent.name}.md`);
20898
- const content = await fs41.readFile(agentPath, "utf-8");
21019
+ const agentPath = path44.join(this.globalPath, "agents", `${agent.name}.md`);
21020
+ const content = await fs42.readFile(agentPath, "utf-8");
20899
21021
  filteredChars += content.length;
20900
21022
  } catch {
20901
21023
  }
@@ -20927,7 +21049,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
20927
21049
  // ==========================================================================
20928
21050
  async fileExists(filename) {
20929
21051
  try {
20930
- await fs41.access(path43.join(this.projectPath, filename));
21052
+ await fs42.access(path44.join(this.projectPath, filename));
20931
21053
  return true;
20932
21054
  } catch {
20933
21055
  return false;
@@ -20935,8 +21057,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
20935
21057
  }
20936
21058
  async getCliVersion() {
20937
21059
  try {
20938
- const pkgPath = path43.join(__dirname, "..", "..", "package.json");
20939
- const pkg = JSON.parse(await fs41.readFile(pkgPath, "utf-8"));
21060
+ const pkgPath = path44.join(__dirname, "..", "..", "package.json");
21061
+ const pkg = JSON.parse(await fs42.readFile(pkgPath, "utf-8"));
20940
21062
  return pkg.version || "0.0.0";
20941
21063
  } catch {
20942
21064
  return "0.0.0";
@@ -21097,22 +21219,22 @@ __export(uninstall_exports, {
21097
21219
  });
21098
21220
  import { execSync as execSync5 } from "node:child_process";
21099
21221
  import fsSync2 from "node:fs";
21100
- import fs42 from "node:fs/promises";
21222
+ import fs43 from "node:fs/promises";
21101
21223
  import os12 from "node:os";
21102
- import path44 from "node:path";
21224
+ import path45 from "node:path";
21103
21225
  import readline2 from "node:readline";
21104
21226
  import chalk9 from "chalk";
21105
21227
  async function getDirectorySize(dirPath) {
21106
21228
  let totalSize = 0;
21107
21229
  try {
21108
- const entries = await fs42.readdir(dirPath, { withFileTypes: true });
21230
+ const entries = await fs43.readdir(dirPath, { withFileTypes: true });
21109
21231
  for (const entry of entries) {
21110
- const entryPath = path44.join(dirPath, entry.name);
21232
+ const entryPath = path45.join(dirPath, entry.name);
21111
21233
  if (entry.isDirectory()) {
21112
21234
  totalSize += await getDirectorySize(entryPath);
21113
21235
  } else {
21114
21236
  try {
21115
- const stats = await fs42.stat(entryPath);
21237
+ const stats = await fs43.stat(entryPath);
21116
21238
  totalSize += stats.size;
21117
21239
  } catch {
21118
21240
  }
@@ -21131,7 +21253,7 @@ function formatSize(bytes) {
21131
21253
  }
21132
21254
  async function countDirectoryItems(dirPath) {
21133
21255
  try {
21134
- const entries = await fs42.readdir(dirPath, { withFileTypes: true });
21256
+ const entries = await fs43.readdir(dirPath, { withFileTypes: true });
21135
21257
  return entries.filter((e) => e.isDirectory()).length;
21136
21258
  } catch {
21137
21259
  return 0;
@@ -21164,7 +21286,7 @@ async function gatherUninstallItems() {
21164
21286
  const providerPaths = getProviderPaths();
21165
21287
  const prjctCliPath = path_manager_default.getGlobalBasePath();
21166
21288
  const prjctCliExists = fsSync2.existsSync(prjctCliPath);
21167
- const projectCount = prjctCliExists ? await countDirectoryItems(path44.join(prjctCliPath, "projects")) : 0;
21289
+ const projectCount = prjctCliExists ? await countDirectoryItems(path45.join(prjctCliPath, "projects")) : 0;
21168
21290
  const prjctCliSize = prjctCliExists ? await getDirectorySize(prjctCliPath) : 0;
21169
21291
  items.push({
21170
21292
  path: prjctCliPath,
@@ -21174,7 +21296,7 @@ async function gatherUninstallItems() {
21174
21296
  count: projectCount,
21175
21297
  exists: prjctCliExists
21176
21298
  });
21177
- const claudeMdPath = path44.join(providerPaths.claude.config, "CLAUDE.md");
21299
+ const claudeMdPath = path45.join(providerPaths.claude.config, "CLAUDE.md");
21178
21300
  const claudeMdExists = fsSync2.existsSync(claudeMdPath);
21179
21301
  let hasPrjctSection = false;
21180
21302
  if (claudeMdExists) {
@@ -21208,7 +21330,7 @@ async function gatherUninstallItems() {
21208
21330
  description: "Claude router",
21209
21331
  exists: claudeRouterExists
21210
21332
  });
21211
- const statusLinePath = path44.join(providerPaths.claude.config, "prjct-statusline.sh");
21333
+ const statusLinePath = path45.join(providerPaths.claude.config, "prjct-statusline.sh");
21212
21334
  const statusLineExists = fsSync2.existsSync(statusLinePath);
21213
21335
  items.push({
21214
21336
  path: statusLinePath,
@@ -21224,7 +21346,7 @@ async function gatherUninstallItems() {
21224
21346
  description: "Gemini router",
21225
21347
  exists: geminiRouterExists
21226
21348
  });
21227
- const geminiMdPath = path44.join(providerPaths.gemini.config, "GEMINI.md");
21349
+ const geminiMdPath = path45.join(providerPaths.gemini.config, "GEMINI.md");
21228
21350
  const geminiMdExists = fsSync2.existsSync(geminiMdPath);
21229
21351
  let hasGeminiPrjctSection = false;
21230
21352
  if (geminiMdExists) {
@@ -21246,7 +21368,7 @@ async function gatherUninstallItems() {
21246
21368
  }
21247
21369
  async function removePrjctSection(filePath) {
21248
21370
  try {
21249
- const content = await fs42.readFile(filePath, "utf-8");
21371
+ const content = await fs43.readFile(filePath, "utf-8");
21250
21372
  if (!content.includes(PRJCT_START_MARKER) || !content.includes(PRJCT_END_MARKER)) {
21251
21373
  return false;
21252
21374
  }
@@ -21255,9 +21377,9 @@ async function removePrjctSection(filePath) {
21255
21377
  let newContent = content.substring(0, startIndex) + content.substring(endIndex);
21256
21378
  newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
21257
21379
  if (!newContent || newContent.trim().length === 0) {
21258
- await fs42.unlink(filePath);
21380
+ await fs43.unlink(filePath);
21259
21381
  } else {
21260
- await fs42.writeFile(filePath, `${newContent}
21382
+ await fs43.writeFile(filePath, `${newContent}
21261
21383
  `, "utf-8");
21262
21384
  }
21263
21385
  return true;
@@ -21268,12 +21390,12 @@ async function removePrjctSection(filePath) {
21268
21390
  async function createBackup() {
21269
21391
  const homeDir = os12.homedir();
21270
21392
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
21271
- const backupDir = path44.join(homeDir, `.prjct-backup-${timestamp}`);
21393
+ const backupDir = path45.join(homeDir, `.prjct-backup-${timestamp}`);
21272
21394
  try {
21273
- await fs42.mkdir(backupDir, { recursive: true });
21395
+ await fs43.mkdir(backupDir, { recursive: true });
21274
21396
  const prjctCliPath = path_manager_default.getGlobalBasePath();
21275
21397
  if (fsSync2.existsSync(prjctCliPath)) {
21276
- await copyDirectory(prjctCliPath, path44.join(backupDir, ".prjct-cli"));
21398
+ await copyDirectory(prjctCliPath, path45.join(backupDir, ".prjct-cli"));
21277
21399
  }
21278
21400
  return backupDir;
21279
21401
  } catch {
@@ -21281,15 +21403,15 @@ async function createBackup() {
21281
21403
  }
21282
21404
  }
21283
21405
  async function copyDirectory(src, dest) {
21284
- await fs42.mkdir(dest, { recursive: true });
21285
- const entries = await fs42.readdir(src, { withFileTypes: true });
21406
+ await fs43.mkdir(dest, { recursive: true });
21407
+ const entries = await fs43.readdir(src, { withFileTypes: true });
21286
21408
  for (const entry of entries) {
21287
- const srcPath = path44.join(src, entry.name);
21288
- const destPath = path44.join(dest, entry.name);
21409
+ const srcPath = path45.join(src, entry.name);
21410
+ const destPath = path45.join(dest, entry.name);
21289
21411
  if (entry.isDirectory()) {
21290
21412
  await copyDirectory(srcPath, destPath);
21291
21413
  } else {
21292
- await fs42.copyFile(srcPath, destPath);
21414
+ await fs43.copyFile(srcPath, destPath);
21293
21415
  }
21294
21416
  }
21295
21417
  }
@@ -21305,10 +21427,10 @@ async function performUninstall(items, installation, options) {
21305
21427
  deleted.push(item.path);
21306
21428
  }
21307
21429
  } else if (item.type === "directory") {
21308
- await fs42.rm(item.path, { recursive: true, force: true });
21430
+ await fs43.rm(item.path, { recursive: true, force: true });
21309
21431
  deleted.push(item.path);
21310
21432
  } else if (item.type === "file") {
21311
- await fs42.unlink(item.path);
21433
+ await fs43.unlink(item.path);
21312
21434
  deleted.push(item.path);
21313
21435
  }
21314
21436
  } catch (error) {
@@ -21483,7 +21605,7 @@ __export(watch_service_exports, {
21483
21605
  WatchService: () => WatchService,
21484
21606
  watchService: () => watchService
21485
21607
  });
21486
- import path45 from "node:path";
21608
+ import path46 from "node:path";
21487
21609
  import chalk10 from "chalk";
21488
21610
  import chokidar from "chokidar";
21489
21611
  var TRIGGER_PATTERNS, IGNORE_PATTERNS2, WatchService, watchService;
@@ -21688,7 +21810,7 @@ ${chalk10.dim(`[${timestamp}]`)} ${chalk10.cyan("\u27F3")} ${filesSummary} chang
21688
21810
  printStartup() {
21689
21811
  console.log("");
21690
21812
  console.log(chalk10.cyan("\u{1F441}\uFE0F Watching for changes..."));
21691
- console.log(chalk10.dim(` Project: ${path45.basename(this.projectPath)}`));
21813
+ console.log(chalk10.dim(` Project: ${path46.basename(this.projectPath)}`));
21692
21814
  console.log(chalk10.dim(` Debounce: ${this.options.debounceMs}ms`));
21693
21815
  console.log(chalk10.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
21694
21816
  console.log("");
@@ -22361,9 +22483,9 @@ __export(setup_exports, {
22361
22483
  run: () => run
22362
22484
  });
22363
22485
  import { execSync as execSync6 } from "node:child_process";
22364
- import fs43 from "node:fs";
22486
+ import fs44 from "node:fs";
22365
22487
  import os13 from "node:os";
22366
- import path46 from "node:path";
22488
+ import path47 from "node:path";
22367
22489
  async function installAICLI(provider) {
22368
22490
  const packageName = provider.name === "claude" ? "@anthropic-ai/claude-code" : "@google/gemini-cli";
22369
22491
  try {
@@ -22469,12 +22591,12 @@ async function run() {
22469
22591
  }
22470
22592
  async function installGeminiRouter() {
22471
22593
  try {
22472
- const geminiCommandsDir = path46.join(os13.homedir(), ".gemini", "commands");
22473
- const routerSource = path46.join(getPackageRoot(), "templates", "commands", "p.toml");
22474
- const routerDest = path46.join(geminiCommandsDir, "p.toml");
22475
- fs43.mkdirSync(geminiCommandsDir, { recursive: true });
22476
- if (fs43.existsSync(routerSource)) {
22477
- fs43.copyFileSync(routerSource, routerDest);
22594
+ const geminiCommandsDir = path47.join(os13.homedir(), ".gemini", "commands");
22595
+ const routerSource = path47.join(getPackageRoot(), "templates", "commands", "p.toml");
22596
+ const routerDest = path47.join(geminiCommandsDir, "p.toml");
22597
+ fs44.mkdirSync(geminiCommandsDir, { recursive: true });
22598
+ if (fs44.existsSync(routerSource)) {
22599
+ fs44.copyFileSync(routerSource, routerDest);
22478
22600
  return true;
22479
22601
  }
22480
22602
  return false;
@@ -22485,15 +22607,15 @@ async function installGeminiRouter() {
22485
22607
  }
22486
22608
  async function installGeminiGlobalConfig() {
22487
22609
  try {
22488
- const geminiDir = path46.join(os13.homedir(), ".gemini");
22489
- const globalConfigPath = path46.join(geminiDir, "GEMINI.md");
22490
- const templatePath = path46.join(getPackageRoot(), "templates", "global", "GEMINI.md");
22491
- fs43.mkdirSync(geminiDir, { recursive: true });
22492
- const templateContent = fs43.readFileSync(templatePath, "utf-8");
22610
+ const geminiDir = path47.join(os13.homedir(), ".gemini");
22611
+ const globalConfigPath = path47.join(geminiDir, "GEMINI.md");
22612
+ const templatePath = path47.join(getPackageRoot(), "templates", "global", "GEMINI.md");
22613
+ fs44.mkdirSync(geminiDir, { recursive: true });
22614
+ const templateContent = fs44.readFileSync(templatePath, "utf-8");
22493
22615
  let existingContent = "";
22494
22616
  let fileExists2 = false;
22495
22617
  try {
22496
- existingContent = fs43.readFileSync(globalConfigPath, "utf-8");
22618
+ existingContent = fs44.readFileSync(globalConfigPath, "utf-8");
22497
22619
  fileExists2 = true;
22498
22620
  } catch (error) {
22499
22621
  if (isNotFoundError(error)) {
@@ -22503,7 +22625,7 @@ async function installGeminiGlobalConfig() {
22503
22625
  }
22504
22626
  }
22505
22627
  if (!fileExists2) {
22506
- fs43.writeFileSync(globalConfigPath, templateContent, "utf-8");
22628
+ fs44.writeFileSync(globalConfigPath, templateContent, "utf-8");
22507
22629
  return { success: true, action: "created" };
22508
22630
  }
22509
22631
  const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
@@ -22513,7 +22635,7 @@ async function installGeminiGlobalConfig() {
22513
22635
  const updatedContent2 = `${existingContent}
22514
22636
 
22515
22637
  ${templateContent}`;
22516
- fs43.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
22638
+ fs44.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
22517
22639
  return { success: true, action: "appended" };
22518
22640
  }
22519
22641
  const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
@@ -22525,7 +22647,7 @@ ${templateContent}`;
22525
22647
  templateContent.indexOf(endMarker) + endMarker.length
22526
22648
  );
22527
22649
  const updatedContent = beforeMarker + prjctSection + afterMarker;
22528
- fs43.writeFileSync(globalConfigPath, updatedContent, "utf-8");
22650
+ fs44.writeFileSync(globalConfigPath, updatedContent, "utf-8");
22529
22651
  return { success: true, action: "updated" };
22530
22652
  } catch (error) {
22531
22653
  console.error(`Gemini config warning: ${error.message}`);
@@ -22534,18 +22656,18 @@ ${templateContent}`;
22534
22656
  }
22535
22657
  async function installAntigravitySkill() {
22536
22658
  try {
22537
- const antigravitySkillsDir = path46.join(os13.homedir(), ".gemini", "antigravity", "skills");
22538
- const prjctSkillDir = path46.join(antigravitySkillsDir, "prjct");
22539
- const skillMdPath = path46.join(prjctSkillDir, "SKILL.md");
22540
- const templatePath = path46.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
22541
- fs43.mkdirSync(prjctSkillDir, { recursive: true });
22542
- const fileExists2 = fs43.existsSync(skillMdPath);
22543
- if (!fs43.existsSync(templatePath)) {
22659
+ const antigravitySkillsDir = path47.join(os13.homedir(), ".gemini", "antigravity", "skills");
22660
+ const prjctSkillDir = path47.join(antigravitySkillsDir, "prjct");
22661
+ const skillMdPath = path47.join(prjctSkillDir, "SKILL.md");
22662
+ const templatePath = path47.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
22663
+ fs44.mkdirSync(prjctSkillDir, { recursive: true });
22664
+ const fileExists2 = fs44.existsSync(skillMdPath);
22665
+ if (!fs44.existsSync(templatePath)) {
22544
22666
  console.error("Antigravity SKILL.md template not found");
22545
22667
  return { success: false, action: null };
22546
22668
  }
22547
- const templateContent = fs43.readFileSync(templatePath, "utf-8");
22548
- fs43.writeFileSync(skillMdPath, templateContent, "utf-8");
22669
+ const templateContent = fs44.readFileSync(templatePath, "utf-8");
22670
+ fs44.writeFileSync(skillMdPath, templateContent, "utf-8");
22549
22671
  return { success: true, action: fileExists2 ? "updated" : "created" };
22550
22672
  } catch (error) {
22551
22673
  console.error(`Antigravity skill warning: ${error.message}`);
@@ -22564,24 +22686,24 @@ async function installCursorProject(projectRoot) {
22564
22686
  gitignoreUpdated: false
22565
22687
  };
22566
22688
  try {
22567
- const cursorDir = path46.join(projectRoot, ".cursor");
22568
- const rulesDir = path46.join(cursorDir, "rules");
22569
- const commandsDir = path46.join(cursorDir, "commands");
22570
- const routerMdcDest = path46.join(rulesDir, "prjct.mdc");
22571
- const routerMdcSource = path46.join(getPackageRoot(), "templates", "cursor", "router.mdc");
22572
- const cursorCommandsSource = path46.join(getPackageRoot(), "templates", "cursor", "commands");
22573
- fs43.mkdirSync(rulesDir, { recursive: true });
22574
- fs43.mkdirSync(commandsDir, { recursive: true });
22575
- if (fs43.existsSync(routerMdcSource)) {
22576
- fs43.copyFileSync(routerMdcSource, routerMdcDest);
22689
+ const cursorDir = path47.join(projectRoot, ".cursor");
22690
+ const rulesDir = path47.join(cursorDir, "rules");
22691
+ const commandsDir = path47.join(cursorDir, "commands");
22692
+ const routerMdcDest = path47.join(rulesDir, "prjct.mdc");
22693
+ const routerMdcSource = path47.join(getPackageRoot(), "templates", "cursor", "router.mdc");
22694
+ const cursorCommandsSource = path47.join(getPackageRoot(), "templates", "cursor", "commands");
22695
+ fs44.mkdirSync(rulesDir, { recursive: true });
22696
+ fs44.mkdirSync(commandsDir, { recursive: true });
22697
+ if (fs44.existsSync(routerMdcSource)) {
22698
+ fs44.copyFileSync(routerMdcSource, routerMdcDest);
22577
22699
  result.rulesCreated = true;
22578
22700
  }
22579
- if (fs43.existsSync(cursorCommandsSource)) {
22580
- const commandFiles = fs43.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
22701
+ if (fs44.existsSync(cursorCommandsSource)) {
22702
+ const commandFiles = fs44.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
22581
22703
  for (const file of commandFiles) {
22582
- const src = path46.join(cursorCommandsSource, file);
22583
- const dest = path46.join(commandsDir, file);
22584
- fs43.copyFileSync(src, dest);
22704
+ const src = path47.join(cursorCommandsSource, file);
22705
+ const dest = path47.join(commandsDir, file);
22706
+ fs44.copyFileSync(src, dest);
22585
22707
  }
22586
22708
  result.commandsCreated = commandFiles.length > 0;
22587
22709
  }
@@ -22595,7 +22717,7 @@ async function installCursorProject(projectRoot) {
22595
22717
  }
22596
22718
  async function addCursorToGitignore(projectRoot) {
22597
22719
  try {
22598
- const gitignorePath = path46.join(projectRoot, ".gitignore");
22720
+ const gitignorePath = path47.join(projectRoot, ".gitignore");
22599
22721
  const entriesToAdd = [
22600
22722
  "# prjct Cursor routers (regenerated per-developer)",
22601
22723
  ".cursor/rules/prjct.mdc",
@@ -22610,7 +22732,7 @@ async function addCursorToGitignore(projectRoot) {
22610
22732
  let content = "";
22611
22733
  let fileExists2 = false;
22612
22734
  try {
22613
- content = fs43.readFileSync(gitignorePath, "utf-8");
22735
+ content = fs44.readFileSync(gitignorePath, "utf-8");
22614
22736
  fileExists2 = true;
22615
22737
  } catch (error) {
22616
22738
  if (!isNotFoundError(error)) {
@@ -22625,7 +22747,7 @@ async function addCursorToGitignore(projectRoot) {
22625
22747
  ${entriesToAdd.join("\n")}
22626
22748
  ` : `${entriesToAdd.join("\n")}
22627
22749
  `;
22628
- fs43.writeFileSync(gitignorePath, newContent, "utf-8");
22750
+ fs44.writeFileSync(gitignorePath, newContent, "utf-8");
22629
22751
  return true;
22630
22752
  } catch (error) {
22631
22753
  console.error(`Gitignore update warning: ${error.message}`);
@@ -22633,12 +22755,12 @@ ${entriesToAdd.join("\n")}
22633
22755
  }
22634
22756
  }
22635
22757
  function hasCursorProject(projectRoot) {
22636
- return fs43.existsSync(path46.join(projectRoot, ".cursor"));
22758
+ return fs44.existsSync(path47.join(projectRoot, ".cursor"));
22637
22759
  }
22638
22760
  function needsCursorRegeneration(projectRoot) {
22639
- const cursorDir = path46.join(projectRoot, ".cursor");
22640
- const routerPath = path46.join(cursorDir, "rules", "prjct.mdc");
22641
- return fs43.existsSync(cursorDir) && !fs43.existsSync(routerPath);
22761
+ const cursorDir = path47.join(projectRoot, ".cursor");
22762
+ const routerPath = path47.join(cursorDir, "rules", "prjct.mdc");
22763
+ return fs44.existsSync(cursorDir) && !fs44.existsSync(routerPath);
22642
22764
  }
22643
22765
  async function installWindsurfProject(projectRoot) {
22644
22766
  const result = {
@@ -22648,29 +22770,29 @@ async function installWindsurfProject(projectRoot) {
22648
22770
  gitignoreUpdated: false
22649
22771
  };
22650
22772
  try {
22651
- const windsurfDir = path46.join(projectRoot, ".windsurf");
22652
- const rulesDir = path46.join(windsurfDir, "rules");
22653
- const workflowsDir = path46.join(windsurfDir, "workflows");
22654
- const routerDest = path46.join(rulesDir, "prjct.md");
22655
- const routerSource = path46.join(getPackageRoot(), "templates", "windsurf", "router.md");
22656
- const windsurfWorkflowsSource = path46.join(
22773
+ const windsurfDir = path47.join(projectRoot, ".windsurf");
22774
+ const rulesDir = path47.join(windsurfDir, "rules");
22775
+ const workflowsDir = path47.join(windsurfDir, "workflows");
22776
+ const routerDest = path47.join(rulesDir, "prjct.md");
22777
+ const routerSource = path47.join(getPackageRoot(), "templates", "windsurf", "router.md");
22778
+ const windsurfWorkflowsSource = path47.join(
22657
22779
  getPackageRoot(),
22658
22780
  "templates",
22659
22781
  "windsurf",
22660
22782
  "workflows"
22661
22783
  );
22662
- fs43.mkdirSync(rulesDir, { recursive: true });
22663
- fs43.mkdirSync(workflowsDir, { recursive: true });
22664
- if (fs43.existsSync(routerSource)) {
22665
- fs43.copyFileSync(routerSource, routerDest);
22784
+ fs44.mkdirSync(rulesDir, { recursive: true });
22785
+ fs44.mkdirSync(workflowsDir, { recursive: true });
22786
+ if (fs44.existsSync(routerSource)) {
22787
+ fs44.copyFileSync(routerSource, routerDest);
22666
22788
  result.rulesCreated = true;
22667
22789
  }
22668
- if (fs43.existsSync(windsurfWorkflowsSource)) {
22669
- const workflowFiles = fs43.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
22790
+ if (fs44.existsSync(windsurfWorkflowsSource)) {
22791
+ const workflowFiles = fs44.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
22670
22792
  for (const file of workflowFiles) {
22671
- const src = path46.join(windsurfWorkflowsSource, file);
22672
- const dest = path46.join(workflowsDir, file);
22673
- fs43.copyFileSync(src, dest);
22793
+ const src = path47.join(windsurfWorkflowsSource, file);
22794
+ const dest = path47.join(workflowsDir, file);
22795
+ fs44.copyFileSync(src, dest);
22674
22796
  }
22675
22797
  result.workflowsCreated = workflowFiles.length > 0;
22676
22798
  }
@@ -22684,7 +22806,7 @@ async function installWindsurfProject(projectRoot) {
22684
22806
  }
22685
22807
  async function addWindsurfToGitignore(projectRoot) {
22686
22808
  try {
22687
- const gitignorePath = path46.join(projectRoot, ".gitignore");
22809
+ const gitignorePath = path47.join(projectRoot, ".gitignore");
22688
22810
  const entriesToAdd = [
22689
22811
  "# prjct Windsurf routers (regenerated per-developer)",
22690
22812
  ".windsurf/rules/prjct.md",
@@ -22699,7 +22821,7 @@ async function addWindsurfToGitignore(projectRoot) {
22699
22821
  let content = "";
22700
22822
  let fileExists2 = false;
22701
22823
  try {
22702
- content = fs43.readFileSync(gitignorePath, "utf-8");
22824
+ content = fs44.readFileSync(gitignorePath, "utf-8");
22703
22825
  fileExists2 = true;
22704
22826
  } catch (error) {
22705
22827
  if (!isNotFoundError(error)) {
@@ -22714,7 +22836,7 @@ async function addWindsurfToGitignore(projectRoot) {
22714
22836
  ${entriesToAdd.join("\n")}
22715
22837
  ` : `${entriesToAdd.join("\n")}
22716
22838
  `;
22717
- fs43.writeFileSync(gitignorePath, newContent, "utf-8");
22839
+ fs44.writeFileSync(gitignorePath, newContent, "utf-8");
22718
22840
  return true;
22719
22841
  } catch (error) {
22720
22842
  console.error(`Gitignore update warning: ${error.message}`);
@@ -22722,32 +22844,32 @@ ${entriesToAdd.join("\n")}
22722
22844
  }
22723
22845
  }
22724
22846
  function hasWindsurfProject(projectRoot) {
22725
- return fs43.existsSync(path46.join(projectRoot, ".windsurf"));
22847
+ return fs44.existsSync(path47.join(projectRoot, ".windsurf"));
22726
22848
  }
22727
22849
  function needsWindsurfRegeneration(projectRoot) {
22728
- const windsurfDir = path46.join(projectRoot, ".windsurf");
22729
- const routerPath = path46.join(windsurfDir, "rules", "prjct.md");
22730
- return fs43.existsSync(windsurfDir) && !fs43.existsSync(routerPath);
22850
+ const windsurfDir = path47.join(projectRoot, ".windsurf");
22851
+ const routerPath = path47.join(windsurfDir, "rules", "prjct.md");
22852
+ return fs44.existsSync(windsurfDir) && !fs44.existsSync(routerPath);
22731
22853
  }
22732
22854
  async function migrateProjectsCliVersion() {
22733
22855
  try {
22734
- const projectsDir = path46.join(os13.homedir(), ".prjct-cli", "projects");
22735
- if (!fs43.existsSync(projectsDir)) {
22856
+ const projectsDir = path47.join(os13.homedir(), ".prjct-cli", "projects");
22857
+ if (!fs44.existsSync(projectsDir)) {
22736
22858
  return;
22737
22859
  }
22738
- const projectDirs = fs43.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
22860
+ const projectDirs = fs44.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
22739
22861
  let migrated = 0;
22740
22862
  for (const projectId of projectDirs) {
22741
- const projectJsonPath = path46.join(projectsDir, projectId, "project.json");
22742
- if (!fs43.existsSync(projectJsonPath)) {
22863
+ const projectJsonPath = path47.join(projectsDir, projectId, "project.json");
22864
+ if (!fs44.existsSync(projectJsonPath)) {
22743
22865
  continue;
22744
22866
  }
22745
22867
  try {
22746
- const content = fs43.readFileSync(projectJsonPath, "utf8");
22868
+ const content = fs44.readFileSync(projectJsonPath, "utf8");
22747
22869
  const project = JSON.parse(content);
22748
22870
  if (project.cliVersion !== VERSION) {
22749
22871
  project.cliVersion = VERSION;
22750
- fs43.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
22872
+ fs44.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
22751
22873
  migrated++;
22752
22874
  }
22753
22875
  } catch (error) {
@@ -22767,9 +22889,9 @@ async function migrateProjectsCliVersion() {
22767
22889
  }
22768
22890
  function ensureStatusLineSettings(settingsPath, statusLinePath) {
22769
22891
  let settings = {};
22770
- if (fs43.existsSync(settingsPath)) {
22892
+ if (fs44.existsSync(settingsPath)) {
22771
22893
  try {
22772
- settings = JSON.parse(fs43.readFileSync(settingsPath, "utf8"));
22894
+ settings = JSON.parse(fs44.readFileSync(settingsPath, "utf8"));
22773
22895
  } catch (error) {
22774
22896
  if (!(error instanceof SyntaxError)) {
22775
22897
  throw error;
@@ -22777,42 +22899,42 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
22777
22899
  }
22778
22900
  }
22779
22901
  settings.statusLine = { type: "command", command: statusLinePath };
22780
- fs43.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
22902
+ fs44.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
22781
22903
  }
22782
22904
  async function installStatusLine() {
22783
22905
  try {
22784
- const claudeDir = path46.join(os13.homedir(), ".claude");
22785
- const settingsPath = path46.join(claudeDir, "settings.json");
22786
- const claudeStatusLinePath = path46.join(claudeDir, "prjct-statusline.sh");
22787
- const prjctStatusLineDir = path46.join(os13.homedir(), ".prjct-cli", "statusline");
22788
- const prjctStatusLinePath = path46.join(prjctStatusLineDir, "statusline.sh");
22789
- const prjctThemesDir = path46.join(prjctStatusLineDir, "themes");
22790
- const prjctLibDir = path46.join(prjctStatusLineDir, "lib");
22791
- const prjctComponentsDir = path46.join(prjctStatusLineDir, "components");
22792
- const prjctConfigPath = path46.join(prjctStatusLineDir, "config.json");
22793
- const assetsDir = path46.join(getPackageRoot(), "assets", "statusline");
22794
- const sourceScript = path46.join(assetsDir, "statusline.sh");
22795
- const sourceThemeDir = path46.join(assetsDir, "themes");
22796
- const sourceLibDir = path46.join(assetsDir, "lib");
22797
- const sourceComponentsDir = path46.join(assetsDir, "components");
22798
- const sourceConfigPath = path46.join(assetsDir, "default-config.json");
22799
- if (!fs43.existsSync(claudeDir)) {
22800
- fs43.mkdirSync(claudeDir, { recursive: true });
22906
+ const claudeDir = path47.join(os13.homedir(), ".claude");
22907
+ const settingsPath = path47.join(claudeDir, "settings.json");
22908
+ const claudeStatusLinePath = path47.join(claudeDir, "prjct-statusline.sh");
22909
+ const prjctStatusLineDir = path47.join(os13.homedir(), ".prjct-cli", "statusline");
22910
+ const prjctStatusLinePath = path47.join(prjctStatusLineDir, "statusline.sh");
22911
+ const prjctThemesDir = path47.join(prjctStatusLineDir, "themes");
22912
+ const prjctLibDir = path47.join(prjctStatusLineDir, "lib");
22913
+ const prjctComponentsDir = path47.join(prjctStatusLineDir, "components");
22914
+ const prjctConfigPath = path47.join(prjctStatusLineDir, "config.json");
22915
+ const assetsDir = path47.join(getPackageRoot(), "assets", "statusline");
22916
+ const sourceScript = path47.join(assetsDir, "statusline.sh");
22917
+ const sourceThemeDir = path47.join(assetsDir, "themes");
22918
+ const sourceLibDir = path47.join(assetsDir, "lib");
22919
+ const sourceComponentsDir = path47.join(assetsDir, "components");
22920
+ const sourceConfigPath = path47.join(assetsDir, "default-config.json");
22921
+ if (!fs44.existsSync(claudeDir)) {
22922
+ fs44.mkdirSync(claudeDir, { recursive: true });
22801
22923
  }
22802
- if (!fs43.existsSync(prjctStatusLineDir)) {
22803
- fs43.mkdirSync(prjctStatusLineDir, { recursive: true });
22924
+ if (!fs44.existsSync(prjctStatusLineDir)) {
22925
+ fs44.mkdirSync(prjctStatusLineDir, { recursive: true });
22804
22926
  }
22805
- if (!fs43.existsSync(prjctThemesDir)) {
22806
- fs43.mkdirSync(prjctThemesDir, { recursive: true });
22927
+ if (!fs44.existsSync(prjctThemesDir)) {
22928
+ fs44.mkdirSync(prjctThemesDir, { recursive: true });
22807
22929
  }
22808
- if (!fs43.existsSync(prjctLibDir)) {
22809
- fs43.mkdirSync(prjctLibDir, { recursive: true });
22930
+ if (!fs44.existsSync(prjctLibDir)) {
22931
+ fs44.mkdirSync(prjctLibDir, { recursive: true });
22810
22932
  }
22811
- if (!fs43.existsSync(prjctComponentsDir)) {
22812
- fs43.mkdirSync(prjctComponentsDir, { recursive: true });
22933
+ if (!fs44.existsSync(prjctComponentsDir)) {
22934
+ fs44.mkdirSync(prjctComponentsDir, { recursive: true });
22813
22935
  }
22814
- if (fs43.existsSync(prjctStatusLinePath)) {
22815
- const existingContent = fs43.readFileSync(prjctStatusLinePath, "utf8");
22936
+ if (fs44.existsSync(prjctStatusLinePath)) {
22937
+ const existingContent = fs44.readFileSync(prjctStatusLinePath, "utf8");
22816
22938
  if (existingContent.includes("CLI_VERSION=")) {
22817
22939
  const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
22818
22940
  if (versionMatch && versionMatch[1] !== VERSION) {
@@ -22820,7 +22942,7 @@ async function installStatusLine() {
22820
22942
  /CLI_VERSION="[^"]*"/,
22821
22943
  `CLI_VERSION="${VERSION}"`
22822
22944
  );
22823
- fs43.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
22945
+ fs44.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
22824
22946
  }
22825
22947
  installStatusLineModules(sourceLibDir, prjctLibDir);
22826
22948
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
@@ -22829,22 +22951,22 @@ async function installStatusLine() {
22829
22951
  return;
22830
22952
  }
22831
22953
  }
22832
- if (fs43.existsSync(sourceScript)) {
22833
- let scriptContent = fs43.readFileSync(sourceScript, "utf8");
22954
+ if (fs44.existsSync(sourceScript)) {
22955
+ let scriptContent = fs44.readFileSync(sourceScript, "utf8");
22834
22956
  scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
22835
- fs43.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
22957
+ fs44.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
22836
22958
  installStatusLineModules(sourceLibDir, prjctLibDir);
22837
22959
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
22838
- if (fs43.existsSync(sourceThemeDir)) {
22839
- const themes = fs43.readdirSync(sourceThemeDir);
22960
+ if (fs44.existsSync(sourceThemeDir)) {
22961
+ const themes = fs44.readdirSync(sourceThemeDir);
22840
22962
  for (const theme of themes) {
22841
- const src = path46.join(sourceThemeDir, theme);
22842
- const dest = path46.join(prjctThemesDir, theme);
22843
- fs43.copyFileSync(src, dest);
22963
+ const src = path47.join(sourceThemeDir, theme);
22964
+ const dest = path47.join(prjctThemesDir, theme);
22965
+ fs44.copyFileSync(src, dest);
22844
22966
  }
22845
22967
  }
22846
- if (!fs43.existsSync(prjctConfigPath) && fs43.existsSync(sourceConfigPath)) {
22847
- fs43.copyFileSync(sourceConfigPath, prjctConfigPath);
22968
+ if (!fs44.existsSync(prjctConfigPath) && fs44.existsSync(sourceConfigPath)) {
22969
+ fs44.copyFileSync(sourceConfigPath, prjctConfigPath);
22848
22970
  }
22849
22971
  } else {
22850
22972
  const scriptContent = `#!/bin/bash
@@ -22879,7 +23001,7 @@ if [ -f "$CONFIG" ]; then
22879
23001
  fi
22880
23002
  echo "prjct"
22881
23003
  `;
22882
- fs43.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
23004
+ fs44.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
22883
23005
  }
22884
23006
  ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
22885
23007
  ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
@@ -22891,10 +23013,10 @@ echo "prjct"
22891
23013
  }
22892
23014
  async function installContext7MCP() {
22893
23015
  try {
22894
- const claudeDir = path46.join(os13.homedir(), ".claude");
22895
- const mcpConfigPath = path46.join(claudeDir, "mcp.json");
22896
- if (!fs43.existsSync(claudeDir)) {
22897
- fs43.mkdirSync(claudeDir, { recursive: true });
23016
+ const claudeDir = path47.join(os13.homedir(), ".claude");
23017
+ const mcpConfigPath = path47.join(claudeDir, "mcp.json");
23018
+ if (!fs44.existsSync(claudeDir)) {
23019
+ fs44.mkdirSync(claudeDir, { recursive: true });
22898
23020
  }
22899
23021
  const context7Config = {
22900
23022
  mcpServers: {
@@ -22904,54 +23026,54 @@ async function installContext7MCP() {
22904
23026
  }
22905
23027
  }
22906
23028
  };
22907
- if (fs43.existsSync(mcpConfigPath)) {
22908
- const existingContent = fs43.readFileSync(mcpConfigPath, "utf-8");
23029
+ if (fs44.existsSync(mcpConfigPath)) {
23030
+ const existingContent = fs44.readFileSync(mcpConfigPath, "utf-8");
22909
23031
  const existingConfig = JSON.parse(existingContent);
22910
23032
  if (existingConfig.mcpServers?.context7) {
22911
23033
  return;
22912
23034
  }
22913
23035
  existingConfig.mcpServers = existingConfig.mcpServers || {};
22914
23036
  existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
22915
- fs43.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
23037
+ fs44.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
22916
23038
  } else {
22917
- fs43.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
23039
+ fs44.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
22918
23040
  }
22919
23041
  } catch (error) {
22920
23042
  console.error(`Context7 MCP setup warning: ${error.message}`);
22921
23043
  }
22922
23044
  }
22923
23045
  function installStatusLineModules(sourceDir, destDir) {
22924
- if (!fs43.existsSync(sourceDir)) {
23046
+ if (!fs44.existsSync(sourceDir)) {
22925
23047
  return;
22926
23048
  }
22927
- const files = fs43.readdirSync(sourceDir);
23049
+ const files = fs44.readdirSync(sourceDir);
22928
23050
  for (const file of files) {
22929
23051
  if (file.endsWith(".sh")) {
22930
- const src = path46.join(sourceDir, file);
22931
- const dest = path46.join(destDir, file);
22932
- fs43.copyFileSync(src, dest);
22933
- fs43.chmodSync(dest, 493);
23052
+ const src = path47.join(sourceDir, file);
23053
+ const dest = path47.join(destDir, file);
23054
+ fs44.copyFileSync(src, dest);
23055
+ fs44.chmodSync(dest, 493);
22934
23056
  }
22935
23057
  }
22936
23058
  }
22937
23059
  function ensureStatusLineSymlink(linkPath, targetPath) {
22938
23060
  try {
22939
- if (fs43.existsSync(linkPath)) {
22940
- const stats = fs43.lstatSync(linkPath);
23061
+ if (fs44.existsSync(linkPath)) {
23062
+ const stats = fs44.lstatSync(linkPath);
22941
23063
  if (stats.isSymbolicLink()) {
22942
- const existingTarget = fs43.readlinkSync(linkPath);
23064
+ const existingTarget = fs44.readlinkSync(linkPath);
22943
23065
  if (existingTarget === targetPath) {
22944
23066
  return;
22945
23067
  }
22946
23068
  }
22947
- fs43.unlinkSync(linkPath);
23069
+ fs44.unlinkSync(linkPath);
22948
23070
  }
22949
- fs43.symlinkSync(targetPath, linkPath);
23071
+ fs44.symlinkSync(targetPath, linkPath);
22950
23072
  } catch (_error) {
22951
23073
  try {
22952
- if (fs43.existsSync(targetPath)) {
22953
- fs43.copyFileSync(targetPath, linkPath);
22954
- fs43.chmodSync(linkPath, 493);
23074
+ if (fs44.existsSync(targetPath)) {
23075
+ fs44.copyFileSync(targetPath, linkPath);
23076
+ fs44.chmodSync(linkPath, 493);
22955
23077
  }
22956
23078
  } catch (copyError) {
22957
23079
  if (!isNotFoundError(copyError)) {
@@ -23366,7 +23488,7 @@ var init_registry2 = __esm({
23366
23488
  });
23367
23489
 
23368
23490
  // core/commands/analytics.ts
23369
- import path47 from "node:path";
23491
+ import path48 from "node:path";
23370
23492
  var AnalyticsCommands;
23371
23493
  var init_analytics = __esm({
23372
23494
  "core/commands/analytics.ts"() {
@@ -23392,7 +23514,7 @@ var init_analytics = __esm({
23392
23514
  output_default.failWithHint("NO_PROJECT_ID");
23393
23515
  return { success: false, error: "No project ID found" };
23394
23516
  }
23395
- const projectName = path47.basename(projectPath);
23517
+ const projectName = path48.basename(projectPath);
23396
23518
  const currentTask = await stateStorage.getCurrentTask(projectId);
23397
23519
  const queueTasks = await queueStorage.getActiveTasks(projectId);
23398
23520
  const shipped = await shippedStorage.getRecent(projectId, 5);
@@ -23644,8 +23766,8 @@ ${"\u2550".repeat(50)}
23644
23766
  });
23645
23767
 
23646
23768
  // core/commands/context.ts
23647
- import fs44 from "node:fs/promises";
23648
- import path48 from "node:path";
23769
+ import fs45 from "node:fs/promises";
23770
+ import path49 from "node:path";
23649
23771
  var ContextCommands, contextCommands;
23650
23772
  var init_context = __esm({
23651
23773
  "core/commands/context.ts"() {
@@ -23771,8 +23893,8 @@ var init_context = __esm({
23771
23893
  */
23772
23894
  async loadRepoAnalysis(globalPath) {
23773
23895
  try {
23774
- const analysisPath = path48.join(globalPath, "analysis", "repo-analysis.json");
23775
- const content = await fs44.readFile(analysisPath, "utf-8");
23896
+ const analysisPath = path49.join(globalPath, "analysis", "repo-analysis.json");
23897
+ const content = await fs45.readFile(analysisPath, "utf-8");
23776
23898
  const data = JSON.parse(content);
23777
23899
  return {
23778
23900
  ecosystem: data.ecosystem || "unknown",
@@ -23791,7 +23913,7 @@ var init_context = __esm({
23791
23913
  });
23792
23914
 
23793
23915
  // core/commands/cleanup.ts
23794
- import path49 from "node:path";
23916
+ import path50 from "node:path";
23795
23917
  async function cleanupMemory(projectPath) {
23796
23918
  const projectId = await config_manager_default.getProjectId(projectPath);
23797
23919
  const results = { rotated: [], totalSize: 0, freedSpace: 0 };
@@ -23807,7 +23929,7 @@ async function cleanupMemory(projectPath) {
23807
23929
  results.totalSize += sizeMB;
23808
23930
  const rotated = await jsonl_helper_default.rotateJsonLinesIfNeeded(filePath, 10);
23809
23931
  if (rotated) {
23810
- results.rotated.push(path49.basename(filePath));
23932
+ results.rotated.push(path50.basename(filePath));
23811
23933
  results.freedSpace += sizeMB;
23812
23934
  }
23813
23935
  }
@@ -23914,7 +24036,7 @@ var init_cleanup = __esm({
23914
24036
  });
23915
24037
 
23916
24038
  // core/commands/design.ts
23917
- import path50 from "node:path";
24039
+ import path51 from "node:path";
23918
24040
  async function design(target = null, options = {}, projectPath = process.cwd()) {
23919
24041
  try {
23920
24042
  const designType = options.type || "architecture";
@@ -23926,7 +24048,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
23926
24048
  const designTarget = target || "system";
23927
24049
  output_default.spin(`designing ${designType}...`);
23928
24050
  const projectId = await config_manager_default.getProjectId(projectPath);
23929
- const designsPath = path50.join(
24051
+ const designsPath = path51.join(
23930
24052
  path_manager_default.getGlobalProjectPath(projectId),
23931
24053
  "planning",
23932
24054
  "designs"
@@ -23966,7 +24088,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
23966
24088
  break;
23967
24089
  }
23968
24090
  const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
23969
- const designFilePath = path50.join(designsPath, designFileName);
24091
+ const designFilePath = path51.join(designsPath, designFileName);
23970
24092
  await file_helper_exports.writeFile(designFilePath, designContent);
23971
24093
  await memoryService.log(projectPath, "design_created", {
23972
24094
  type: designType,
@@ -23990,7 +24112,7 @@ var init_design = __esm({
23990
24112
  });
23991
24113
 
23992
24114
  // core/commands/snapshots.ts
23993
- import path51 from "node:path";
24115
+ import path52 from "node:path";
23994
24116
  async function recover(projectPath = process.cwd()) {
23995
24117
  try {
23996
24118
  const projectId = await config_manager_default.getProjectId(projectPath);
@@ -24042,7 +24164,7 @@ async function undo(projectPath = process.cwd()) {
24042
24164
  output_default.failWithHint("NO_PROJECT_ID");
24043
24165
  return { success: false, error: "No project ID found" };
24044
24166
  }
24045
- const snapshotsPath = path51.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
24167
+ const snapshotsPath = path52.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
24046
24168
  await file_helper_exports.ensureDir(snapshotsPath);
24047
24169
  const { execSync: execSync7 } = await import("node:child_process");
24048
24170
  try {
@@ -24060,7 +24182,7 @@ async function undo(projectPath = process.cwd()) {
24060
24182
  cwd: projectPath,
24061
24183
  encoding: "utf-8"
24062
24184
  });
24063
- const snapshotFile = path51.join(snapshotsPath, "history.json");
24185
+ const snapshotFile = path52.join(snapshotsPath, "history.json");
24064
24186
  let history2 = { snapshots: [], current: -1 };
24065
24187
  try {
24066
24188
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -24100,8 +24222,8 @@ async function redo(projectPath = process.cwd()) {
24100
24222
  output_default.failWithHint("NO_PROJECT_ID");
24101
24223
  return { success: false, error: "No project ID found" };
24102
24224
  }
24103
- const snapshotsPath = path51.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
24104
- const snapshotFile = path51.join(snapshotsPath, "history.json");
24225
+ const snapshotsPath = path52.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
24226
+ const snapshotFile = path52.join(snapshotsPath, "history.json");
24105
24227
  let history2;
24106
24228
  try {
24107
24229
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -24160,8 +24282,8 @@ async function history(projectPath = process.cwd()) {
24160
24282
  output_default.failWithHint("NO_PROJECT_ID");
24161
24283
  return { success: false, error: "No project ID found" };
24162
24284
  }
24163
- const snapshotsPath = path51.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
24164
- const snapshotFile = path51.join(snapshotsPath, "history.json");
24285
+ const snapshotsPath = path52.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
24286
+ const snapshotFile = path52.join(snapshotsPath, "history.json");
24165
24287
  let snapshotHistory;
24166
24288
  try {
24167
24289
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -24268,8 +24390,8 @@ var init_maintenance = __esm({
24268
24390
  });
24269
24391
 
24270
24392
  // core/commands/setup.ts
24271
- import fs45 from "node:fs";
24272
- import path52 from "node:path";
24393
+ import fs46 from "node:fs";
24394
+ import path53 from "node:path";
24273
24395
  import chalk11 from "chalk";
24274
24396
  var SetupCommands;
24275
24397
  var init_setup2 = __esm({
@@ -24396,7 +24518,7 @@ Please install it first:
24396
24518
  try {
24397
24519
  const claudeDir = path_manager_default.getClaudeDir();
24398
24520
  const settingsPath = path_manager_default.getClaudeSettingsPath();
24399
- const statusLinePath = path52.join(claudeDir, "prjct-statusline.sh");
24521
+ const statusLinePath = path53.join(claudeDir, "prjct-statusline.sh");
24400
24522
  const scriptContent = `#!/bin/bash
24401
24523
  # prjct Status Line for Claude Code
24402
24524
  # Shows version update notifications and current task
@@ -24454,11 +24576,11 @@ fi
24454
24576
  # Default: show prjct branding
24455
24577
  echo "\u26A1 prjct"
24456
24578
  `;
24457
- fs45.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
24579
+ fs46.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
24458
24580
  let settings = {};
24459
- if (fs45.existsSync(settingsPath)) {
24581
+ if (fs46.existsSync(settingsPath)) {
24460
24582
  try {
24461
- settings = JSON.parse(fs45.readFileSync(settingsPath, "utf8"));
24583
+ settings = JSON.parse(fs46.readFileSync(settingsPath, "utf8"));
24462
24584
  } catch (_error) {
24463
24585
  }
24464
24586
  }
@@ -24466,7 +24588,7 @@ echo "\u26A1 prjct"
24466
24588
  type: "command",
24467
24589
  command: statusLinePath
24468
24590
  };
24469
- fs45.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
24591
+ fs46.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
24470
24592
  return { success: true };
24471
24593
  } catch (error) {
24472
24594
  return { success: false, error: error.message };
@@ -24522,18 +24644,18 @@ echo "\u26A1 prjct"
24522
24644
  });
24523
24645
 
24524
24646
  // core/utils/project-commands.ts
24525
- import path53 from "node:path";
24647
+ import path54 from "node:path";
24526
24648
  async function detectPackageManager(projectPath, pkg) {
24527
24649
  const declared = pkg?.packageManager?.trim().toLowerCase();
24528
24650
  if (declared?.startsWith("pnpm@")) return "pnpm";
24529
24651
  if (declared?.startsWith("yarn@")) return "yarn";
24530
24652
  if (declared?.startsWith("bun@")) return "bun";
24531
24653
  if (declared?.startsWith("npm@")) return "npm";
24532
- if (await fileExists(path53.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
24533
- if (await fileExists(path53.join(projectPath, "yarn.lock"))) return "yarn";
24534
- if (await fileExists(path53.join(projectPath, "bun.lockb"))) return "bun";
24535
- if (await fileExists(path53.join(projectPath, "bun.lock"))) return "bun";
24536
- if (await fileExists(path53.join(projectPath, "package-lock.json"))) return "npm";
24654
+ if (await fileExists(path54.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
24655
+ if (await fileExists(path54.join(projectPath, "yarn.lock"))) return "yarn";
24656
+ if (await fileExists(path54.join(projectPath, "bun.lockb"))) return "bun";
24657
+ if (await fileExists(path54.join(projectPath, "bun.lock"))) return "bun";
24658
+ if (await fileExists(path54.join(projectPath, "package-lock.json"))) return "npm";
24537
24659
  return "npm";
24538
24660
  }
24539
24661
  function pmRun(pm, scriptName) {
@@ -24549,7 +24671,7 @@ function pmTest(pm) {
24549
24671
  return "npm test";
24550
24672
  }
24551
24673
  async function detectProjectCommands(projectPath) {
24552
- const pkgPath = path53.join(projectPath, "package.json");
24674
+ const pkgPath = path54.join(projectPath, "package.json");
24553
24675
  const pkg = await readJson(pkgPath, null);
24554
24676
  if (pkg) {
24555
24677
  const pm = await detectPackageManager(projectPath, pkg);
@@ -24566,27 +24688,27 @@ async function detectProjectCommands(projectPath) {
24566
24688
  }
24567
24689
  return result;
24568
24690
  }
24569
- if (await fileExists(path53.join(projectPath, "pytest.ini"))) {
24691
+ if (await fileExists(path54.join(projectPath, "pytest.ini"))) {
24570
24692
  return { stack: "python", test: { tool: "pytest", command: "pytest" } };
24571
24693
  }
24572
- const pyproject = await readFile(path53.join(projectPath, "pyproject.toml"), "");
24694
+ const pyproject = await readFile(path54.join(projectPath, "pyproject.toml"), "");
24573
24695
  if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
24574
24696
  return { stack: "python", test: { tool: "pytest", command: "pytest" } };
24575
24697
  }
24576
- if (await fileExists(path53.join(projectPath, "Cargo.toml"))) {
24698
+ if (await fileExists(path54.join(projectPath, "Cargo.toml"))) {
24577
24699
  return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
24578
24700
  }
24579
- if (await fileExists(path53.join(projectPath, "go.mod"))) {
24701
+ if (await fileExists(path54.join(projectPath, "go.mod"))) {
24580
24702
  return { stack: "go", test: { tool: "go", command: "go test ./..." } };
24581
24703
  }
24582
24704
  const files = await listFiles(projectPath);
24583
24705
  if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
24584
24706
  return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
24585
24707
  }
24586
- if (await fileExists(path53.join(projectPath, "pom.xml"))) {
24708
+ if (await fileExists(path54.join(projectPath, "pom.xml"))) {
24587
24709
  return { stack: "java", test: { tool: "maven", command: "mvn test" } };
24588
24710
  }
24589
- if (await fileExists(path53.join(projectPath, "gradlew")) && (await fileExists(path53.join(projectPath, "build.gradle")) || await fileExists(path53.join(projectPath, "build.gradle.kts")))) {
24711
+ if (await fileExists(path54.join(projectPath, "gradlew")) && (await fileExists(path54.join(projectPath, "build.gradle")) || await fileExists(path54.join(projectPath, "build.gradle.kts")))) {
24590
24712
  return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
24591
24713
  }
24592
24714
  return { stack: "unknown" };
@@ -24763,7 +24885,7 @@ var init_workflow_preferences = __esm({
24763
24885
  });
24764
24886
 
24765
24887
  // core/commands/shipping.ts
24766
- import path54 from "node:path";
24888
+ import path55 from "node:path";
24767
24889
  var ShippingCommands;
24768
24890
  var init_shipping = __esm({
24769
24891
  "core/commands/shipping.ts"() {
@@ -24909,7 +25031,7 @@ ${result.stderr}`.trim();
24909
25031
  */
24910
25032
  async _bumpVersion(projectPath) {
24911
25033
  try {
24912
- const pkgPath = path54.join(projectPath, "package.json");
25034
+ const pkgPath = path55.join(projectPath, "package.json");
24913
25035
  const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
24914
25036
  const oldVersion = pkg?.version || "0.0.0";
24915
25037
  const [major, minor, patch] = oldVersion.split(".").map(Number);
@@ -24931,7 +25053,7 @@ ${result.stderr}`.trim();
24931
25053
  */
24932
25054
  async _updateChangelog(feature, version, projectPath) {
24933
25055
  try {
24934
- const changelogPath = path54.join(projectPath, "CHANGELOG.md");
25056
+ const changelogPath = path55.join(projectPath, "CHANGELOG.md");
24935
25057
  const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
24936
25058
  const entry = `## [${version}] - ${date_helper_default.formatDate(/* @__PURE__ */ new Date())}
24937
25059
 
@@ -25823,19 +25945,19 @@ var init_linear = __esm({
25823
25945
  });
25824
25946
 
25825
25947
  // core/utils/project-credentials.ts
25826
- import fs46 from "node:fs";
25948
+ import fs47 from "node:fs";
25827
25949
  import os14 from "node:os";
25828
- import path55 from "node:path";
25950
+ import path56 from "node:path";
25829
25951
  function getCredentialsPath(projectId) {
25830
- return path55.join(os14.homedir(), ".prjct-cli", "projects", projectId, "config", "credentials.json");
25952
+ return path56.join(os14.homedir(), ".prjct-cli", "projects", projectId, "config", "credentials.json");
25831
25953
  }
25832
25954
  async function getProjectCredentials(projectId) {
25833
25955
  const credPath = getCredentialsPath(projectId);
25834
- if (!fs46.existsSync(credPath)) {
25956
+ if (!fs47.existsSync(credPath)) {
25835
25957
  return {};
25836
25958
  }
25837
25959
  try {
25838
- return JSON.parse(fs46.readFileSync(credPath, "utf-8"));
25960
+ return JSON.parse(fs47.readFileSync(credPath, "utf-8"));
25839
25961
  } catch (error) {
25840
25962
  console.error("[project-credentials] Failed to read credentials:", error.message);
25841
25963
  return {};
@@ -26412,7 +26534,7 @@ var require_package = __commonJS({
26412
26534
  "package.json"(exports, module) {
26413
26535
  module.exports = {
26414
26536
  name: "prjct-cli",
26415
- version: "0.60.1",
26537
+ version: "0.61.0",
26416
26538
  description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
26417
26539
  main: "core/index.ts",
26418
26540
  bin: {
@@ -26519,9 +26641,9 @@ var require_package = __commonJS({
26519
26641
 
26520
26642
  // core/index.ts
26521
26643
  var core_exports = {};
26522
- import fs47 from "node:fs";
26644
+ import fs48 from "node:fs";
26523
26645
  import os15 from "node:os";
26524
- import path56 from "node:path";
26646
+ import path57 from "node:path";
26525
26647
  async function main() {
26526
26648
  const [commandName, ...rawArgs] = process.argv.slice(2);
26527
26649
  if (["-v", "--version", "version"].includes(commandName)) {
@@ -26653,12 +26775,12 @@ function parseCommandArgs(_cmd, rawArgs) {
26653
26775
  }
26654
26776
  function displayVersion(version) {
26655
26777
  const detection = detectAllProviders();
26656
- const claudeCommandPath = path56.join(os15.homedir(), ".claude", "commands", "p.md");
26657
- const geminiCommandPath = path56.join(os15.homedir(), ".gemini", "commands", "p.toml");
26658
- const claudeConfigured = fs47.existsSync(claudeCommandPath);
26659
- const geminiConfigured = fs47.existsSync(geminiCommandPath);
26660
- const cursorConfigured = fs47.existsSync(path56.join(process.cwd(), ".cursor", "commands", "sync.md"));
26661
- const cursorExists = fs47.existsSync(path56.join(process.cwd(), ".cursor"));
26778
+ const claudeCommandPath = path57.join(os15.homedir(), ".claude", "commands", "p.md");
26779
+ const geminiCommandPath = path57.join(os15.homedir(), ".gemini", "commands", "p.toml");
26780
+ const claudeConfigured = fs48.existsSync(claudeCommandPath);
26781
+ const geminiConfigured = fs48.existsSync(geminiCommandPath);
26782
+ const cursorConfigured = fs48.existsSync(path57.join(process.cwd(), ".cursor", "commands", "sync.md"));
26783
+ const cursorExists = fs48.existsSync(path57.join(process.cwd(), ".cursor"));
26662
26784
  console.log(`
26663
26785
  ${CYAN3}p/${RESET5} prjct v${version}
26664
26786
  ${DIM6}Context layer for AI coding agents${RESET5}
@@ -26791,9 +26913,9 @@ var init_core = __esm({
26791
26913
  init_ai_provider();
26792
26914
  init_config_manager();
26793
26915
  init_editors_config();
26794
- import fs48 from "node:fs";
26916
+ import fs49 from "node:fs";
26795
26917
  import os16 from "node:os";
26796
- import path57 from "node:path";
26918
+ import path58 from "node:path";
26797
26919
 
26798
26920
  // core/server/server.ts
26799
26921
  import { Hono as Hono3 } from "hono";
@@ -27535,14 +27657,14 @@ function checkRoutersInstalled() {
27535
27657
  const home = os16.homedir();
27536
27658
  const detection = detectAllProviders();
27537
27659
  if (detection.claude.installed) {
27538
- const claudeRouter = path57.join(home, ".claude", "commands", "p.md");
27539
- if (!fs48.existsSync(claudeRouter)) {
27660
+ const claudeRouter = path58.join(home, ".claude", "commands", "p.md");
27661
+ if (!fs49.existsSync(claudeRouter)) {
27540
27662
  return false;
27541
27663
  }
27542
27664
  }
27543
27665
  if (detection.gemini.installed) {
27544
- const geminiRouter = path57.join(home, ".gemini", "commands", "p.toml");
27545
- if (!fs48.existsSync(geminiRouter)) {
27666
+ const geminiRouter = path58.join(home, ".gemini", "commands", "p.toml");
27667
+ if (!fs49.existsSync(geminiRouter)) {
27546
27668
  return false;
27547
27669
  }
27548
27670
  }
@@ -27643,7 +27765,7 @@ if (args[0] === "start" || args[0] === "setup") {
27643
27765
  console.error('No prjct project found. Run "prjct init" first.');
27644
27766
  process.exitCode = 1;
27645
27767
  } else {
27646
- const linearCliPath = path57.join(__dirname, "..", "core", "cli", "linear.ts");
27768
+ const linearCliPath = path58.join(__dirname, "..", "core", "cli", "linear.ts");
27647
27769
  const linearArgs = ["--project", projectId, ...args.slice(1)];
27648
27770
  const child = spawn("bun", [linearCliPath, ...linearArgs], {
27649
27771
  stdio: "inherit",
@@ -27662,12 +27784,12 @@ if (args[0] === "start" || args[0] === "setup") {
27662
27784
  const detection = detectAllProviders();
27663
27785
  const home = os16.homedir();
27664
27786
  const cwd = process.cwd();
27665
- const claudeConfigured = fs48.existsSync(path57.join(home, ".claude", "commands", "p.md"));
27666
- const geminiConfigured = fs48.existsSync(path57.join(home, ".gemini", "commands", "p.toml"));
27667
- const cursorDetected = fs48.existsSync(path57.join(cwd, ".cursor"));
27668
- const cursorConfigured = fs48.existsSync(path57.join(cwd, ".cursor", "rules", "prjct.mdc"));
27669
- const windsurfDetected = fs48.existsSync(path57.join(cwd, ".windsurf"));
27670
- const windsurfConfigured = fs48.existsSync(path57.join(cwd, ".windsurf", "rules", "prjct.md"));
27787
+ const claudeConfigured = fs49.existsSync(path58.join(home, ".claude", "commands", "p.md"));
27788
+ const geminiConfigured = fs49.existsSync(path58.join(home, ".gemini", "commands", "p.toml"));
27789
+ const cursorDetected = fs49.existsSync(path58.join(cwd, ".cursor"));
27790
+ const cursorConfigured = fs49.existsSync(path58.join(cwd, ".cursor", "rules", "prjct.mdc"));
27791
+ const windsurfDetected = fs49.existsSync(path58.join(cwd, ".windsurf"));
27792
+ const windsurfConfigured = fs49.existsSync(path58.join(cwd, ".windsurf", "rules", "prjct.md"));
27671
27793
  const GREEN7 = "\x1B[32m";
27672
27794
  console.log(`
27673
27795
  ${CYAN4}p/${RESET6} prjct v${VERSION}
@@ -27706,9 +27828,9 @@ ${DIM7}Run 'prjct init' to configure (Cursor/Windsurf IDE)${RESET6}
27706
27828
  ${CYAN4}https://prjct.app${RESET6}
27707
27829
  `);
27708
27830
  } else {
27709
- const configPath = path57.join(os16.homedir(), ".prjct-cli", "config", "installed-editors.json");
27831
+ const configPath = path58.join(os16.homedir(), ".prjct-cli", "config", "installed-editors.json");
27710
27832
  const routersInstalled = checkRoutersInstalled();
27711
- if (!fs48.existsSync(configPath) || !routersInstalled) {
27833
+ if (!fs49.existsSync(configPath) || !routersInstalled) {
27712
27834
  console.log(`
27713
27835
  ${CYAN4}${BOLD4} Welcome to prjct!${RESET6}
27714
27836