prjct-cli 0.49.0 → 0.51.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.
@@ -2065,6 +2065,7 @@ var init_error_messages = __esm({
2065
2065
  var output_exports = {};
2066
2066
  __export(output_exports, {
2067
2067
  ERRORS: () => ERRORS,
2068
+ ICONS: () => ICONS,
2068
2069
  createError: () => createError,
2069
2070
  default: () => output_default,
2070
2071
  getError: () => getError,
@@ -2078,7 +2079,7 @@ function setQuietMode(enabled) {
2078
2079
  function isQuietMode() {
2079
2080
  return quietMode;
2080
2081
  }
2081
- var _FRAMES, SPEED, interval, frame, quietMode, truncate, clear, out, output_default;
2082
+ var _FRAMES, SPEED, ICONS, interval, frame, quietMode, truncate, clear, out, output_default;
2082
2083
  var init_output = __esm({
2083
2084
  "core/utils/output.ts"() {
2084
2085
  "use strict";
@@ -2087,6 +2088,18 @@ var init_output = __esm({
2087
2088
  init_error_messages();
2088
2089
  _FRAMES = branding_default.spinner.frames;
2089
2090
  SPEED = branding_default.spinner.speed;
2091
+ ICONS = {
2092
+ success: chalk2.green("\u2713"),
2093
+ fail: chalk2.red("\u2717"),
2094
+ warn: chalk2.yellow("\u26A0"),
2095
+ info: chalk2.blue("\u2139"),
2096
+ debug: chalk2.dim("\u{1F527}"),
2097
+ bullet: chalk2.dim("\u2022"),
2098
+ arrow: chalk2.dim("\u2192"),
2099
+ check: chalk2.green("\u2713"),
2100
+ cross: chalk2.red("\u2717"),
2101
+ spinner: chalk2.cyan("\u25D0")
2102
+ };
2090
2103
  interval = null;
2091
2104
  frame = 0;
2092
2105
  quietMode = false;
@@ -2127,14 +2140,14 @@ var init_output = __esm({
2127
2140
  suffix = chalk2.dim(` [${parts.join(" | ")}]`);
2128
2141
  }
2129
2142
  }
2130
- console.log(`${chalk2.green("\u2713")} ${truncate(msg, 50)}${suffix}`);
2143
+ console.log(`${ICONS.success} ${truncate(msg, 50)}${suffix}`);
2131
2144
  }
2132
2145
  return this;
2133
2146
  },
2134
2147
  // Errors go to stderr even in quiet mode
2135
2148
  fail(msg) {
2136
2149
  this.stop();
2137
- console.error(`${chalk2.red("\u2717")} ${truncate(msg, 65)}`);
2150
+ console.error(`${ICONS.fail} ${truncate(msg, 65)}`);
2138
2151
  return this;
2139
2152
  },
2140
2153
  // Rich error with context and recovery hint
@@ -2142,7 +2155,7 @@ var init_output = __esm({
2142
2155
  this.stop();
2143
2156
  const err = typeof error === "string" ? getError(error) : error;
2144
2157
  console.error();
2145
- console.error(`${chalk2.red("\u2717")} ${err.message}`);
2158
+ console.error(`${ICONS.fail} ${err.message}`);
2146
2159
  if (err.file) {
2147
2160
  console.error(chalk2.dim(` File: ${err.file}`));
2148
2161
  }
@@ -2157,7 +2170,77 @@ var init_output = __esm({
2157
2170
  },
2158
2171
  warn(msg) {
2159
2172
  this.stop();
2160
- if (!quietMode) console.log(`${chalk2.yellow("\u26A0")} ${truncate(msg, 65)}`);
2173
+ if (!quietMode) console.log(`${ICONS.warn} ${truncate(msg, 65)}`);
2174
+ return this;
2175
+ },
2176
+ // Informational message
2177
+ info(msg) {
2178
+ this.stop();
2179
+ if (!quietMode) console.log(`${ICONS.info} ${msg}`);
2180
+ return this;
2181
+ },
2182
+ // Debug message (only if DEBUG=1 or DEBUG=true)
2183
+ debug(msg) {
2184
+ this.stop();
2185
+ const debugEnabled = process.env.DEBUG === "1" || process.env.DEBUG === "true";
2186
+ if (!quietMode && debugEnabled) {
2187
+ console.log(`${ICONS.debug} ${chalk2.dim(msg)}`);
2188
+ }
2189
+ return this;
2190
+ },
2191
+ // Alias for done - explicit success indicator
2192
+ success(msg, metrics) {
2193
+ return this.done(msg, metrics);
2194
+ },
2195
+ // Bulleted list
2196
+ list(items, options = {}) {
2197
+ this.stop();
2198
+ if (quietMode) return this;
2199
+ const bullet = options.bullet || ICONS.bullet;
2200
+ const indent = " ".repeat(options.indent || 0);
2201
+ for (const item of items) {
2202
+ console.log(`${indent}${bullet} ${item}`);
2203
+ }
2204
+ return this;
2205
+ },
2206
+ // Simple table output
2207
+ table(rows, options = {}) {
2208
+ this.stop();
2209
+ if (quietMode || rows.length === 0) return this;
2210
+ const keys = Object.keys(rows[0]);
2211
+ const colWidths = {};
2212
+ for (const key of keys) {
2213
+ colWidths[key] = key.length;
2214
+ for (const row of rows) {
2215
+ const val = String(row[key] ?? "");
2216
+ if (val.length > colWidths[key]) colWidths[key] = val.length;
2217
+ }
2218
+ }
2219
+ if (options.header !== false) {
2220
+ const headerLine = keys.map((k) => k.padEnd(colWidths[k])).join(" ");
2221
+ console.log(chalk2.dim(headerLine));
2222
+ console.log(chalk2.dim("\u2500".repeat(headerLine.length)));
2223
+ }
2224
+ for (const row of rows) {
2225
+ const line = keys.map((k) => String(row[k] ?? "").padEnd(colWidths[k])).join(" ");
2226
+ console.log(line);
2227
+ }
2228
+ return this;
2229
+ },
2230
+ // Boxed content
2231
+ box(title, content) {
2232
+ this.stop();
2233
+ if (quietMode) return this;
2234
+ const lines = content.split("\n");
2235
+ const maxLen = Math.max(title.length, ...lines.map((l) => l.length));
2236
+ const border = "\u2500".repeat(maxLen + 2);
2237
+ console.log(chalk2.dim(`\u250C${border}\u2510`));
2238
+ console.log(chalk2.dim("\u2502") + ` ${chalk2.bold(title.padEnd(maxLen))} ` + chalk2.dim("\u2502"));
2239
+ console.log(chalk2.dim(`\u251C${border}\u2524`));
2240
+ for (const line of lines) {
2241
+ console.log(chalk2.dim("\u2502") + ` ${line.padEnd(maxLen)} ` + chalk2.dim("\u2502"));
2242
+ }
2243
+ console.log(chalk2.dim(`\u2514${border}\u2518`));
2161
2244
  return this;
2162
2245
  },
2163
2246
  stop() {
@@ -3684,8 +3767,8 @@ function tryResolve(basePath, projectPath) {
3684
3767
  for (const ext of extensions) {
3685
3768
  const fullPath = basePath + ext;
3686
3769
  try {
3687
- const fs46 = __require("node:fs");
3688
- if (fs46.existsSync(fullPath) && fs46.statSync(fullPath).isFile()) {
3770
+ const fs47 = __require("node:fs");
3771
+ if (fs47.existsSync(fullPath) && fs47.statSync(fullPath).isFile()) {
3689
3772
  return path12.relative(projectPath, fullPath);
3690
3773
  }
3691
3774
  } catch {
@@ -4868,11 +4951,11 @@ async function runSignaturesTool(args2, projectPath) {
4868
4951
  }
4869
4952
  };
4870
4953
  }
4871
- const fs46 = await import("node:fs/promises");
4954
+ const fs47 = await import("node:fs/promises");
4872
4955
  const path56 = await import("node:path");
4873
4956
  const fullPath = path56.isAbsolute(filePath) ? filePath : path56.join(projectPath, filePath);
4874
4957
  try {
4875
- const stat = await fs46.stat(fullPath);
4958
+ const stat = await fs47.stat(fullPath);
4876
4959
  if (stat.isDirectory()) {
4877
4960
  const results = await extractDirectorySignatures(filePath, projectPath, {
4878
4961
  recursive: args2.includes("--recursive") || args2.includes("-r")
@@ -4939,11 +5022,11 @@ async function runSummaryTool(args2, projectPath) {
4939
5022
  }
4940
5023
  };
4941
5024
  }
4942
- const fs46 = await import("node:fs/promises");
5025
+ const fs47 = await import("node:fs/promises");
4943
5026
  const path56 = await import("node:path");
4944
5027
  const fullPath = path56.isAbsolute(targetPath) ? targetPath : path56.join(projectPath, targetPath);
4945
5028
  try {
4946
- const stat = await fs46.stat(fullPath);
5029
+ const stat = await fs47.stat(fullPath);
4947
5030
  if (stat.isDirectory()) {
4948
5031
  const results = await summarizeDirectory(targetPath, projectPath, {
4949
5032
  recursive: args2.includes("--recursive") || args2.includes("-r")
@@ -11365,7 +11448,7 @@ var init_constants = __esm({
11365
11448
 
11366
11449
  // core/agentic/plan-mode.ts
11367
11450
  function generateApprovalPrompt(commandName, context2) {
11368
- const prompts2 = {
11451
+ const prompts3 = {
11369
11452
  ship: {
11370
11453
  title: "Ship Confirmation",
11371
11454
  message: "Ready to commit and push changes?",
@@ -11403,7 +11486,7 @@ function generateApprovalPrompt(commandName, context2) {
11403
11486
  ]
11404
11487
  }
11405
11488
  };
11406
- return prompts2[commandName] || {
11489
+ return prompts3[commandName] || {
11407
11490
  title: "Confirmation Required",
11408
11491
  message: `Execute ${commandName}?`,
11409
11492
  options: [
@@ -15458,16 +15541,16 @@ var init_onboarding = __esm({
15458
15541
  * Detect project type from file system
15459
15542
  */
15460
15543
  async detectProjectType() {
15461
- const fs46 = await import("node:fs/promises");
15544
+ const fs47 = await import("node:fs/promises");
15462
15545
  const path56 = await import("node:path");
15463
15546
  try {
15464
- const files = await fs46.readdir(this.projectPath);
15547
+ const files = await fs47.readdir(this.projectPath);
15465
15548
  if (files.includes("turbo.json") || files.includes("lerna.json") || files.includes("nx.json")) {
15466
15549
  return "monorepo";
15467
15550
  }
15468
15551
  if (files.includes("package.json")) {
15469
15552
  const pkgPath = path56.join(this.projectPath, "package.json");
15470
- const pkgContent = await fs46.readFile(pkgPath, "utf-8");
15553
+ const pkgContent = await fs47.readFile(pkgPath, "utf-8");
15471
15554
  const pkg = JSON.parse(pkgContent);
15472
15555
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
15473
15556
  if (pkg.bin) return "cli-tool";
@@ -15503,32 +15586,32 @@ var init_onboarding = __esm({
15503
15586
  * Detect installed AI agents from config files
15504
15587
  */
15505
15588
  async detectInstalledAgents() {
15506
- const fs46 = await import("node:fs/promises");
15589
+ const fs47 = await import("node:fs/promises");
15507
15590
  const path56 = await import("node:path");
15508
15591
  const os17 = await import("node:os");
15509
15592
  const agents = [];
15510
15593
  try {
15511
- await fs46.access(path56.join(os17.homedir(), ".claude"));
15594
+ await fs47.access(path56.join(os17.homedir(), ".claude"));
15512
15595
  agents.push("claude");
15513
15596
  } catch {
15514
15597
  }
15515
15598
  try {
15516
- await fs46.access(path56.join(this.projectPath, ".cursorrules"));
15599
+ await fs47.access(path56.join(this.projectPath, ".cursorrules"));
15517
15600
  agents.push("cursor");
15518
15601
  } catch {
15519
15602
  }
15520
15603
  try {
15521
- await fs46.access(path56.join(this.projectPath, ".windsurfrules"));
15604
+ await fs47.access(path56.join(this.projectPath, ".windsurfrules"));
15522
15605
  agents.push("windsurf");
15523
15606
  } catch {
15524
15607
  }
15525
15608
  try {
15526
- await fs46.access(path56.join(this.projectPath, ".github", "copilot-instructions.md"));
15609
+ await fs47.access(path56.join(this.projectPath, ".github", "copilot-instructions.md"));
15527
15610
  agents.push("copilot");
15528
15611
  } catch {
15529
15612
  }
15530
15613
  try {
15531
- await fs46.access(path56.join(os17.homedir(), ".gemini"));
15614
+ await fs47.access(path56.join(os17.homedir(), ".gemini"));
15532
15615
  agents.push("gemini");
15533
15616
  } catch {
15534
15617
  }
@@ -15538,17 +15621,17 @@ var init_onboarding = __esm({
15538
15621
  * Detect tech stack from project files
15539
15622
  */
15540
15623
  async detectStack() {
15541
- const fs46 = await import("node:fs/promises");
15624
+ const fs47 = await import("node:fs/promises");
15542
15625
  const path56 = await import("node:path");
15543
15626
  const stack = {
15544
15627
  language: "Unknown",
15545
15628
  technologies: []
15546
15629
  };
15547
15630
  try {
15548
- const files = await fs46.readdir(this.projectPath);
15631
+ const files = await fs47.readdir(this.projectPath);
15549
15632
  if (files.includes("package.json")) {
15550
15633
  const pkgPath = path56.join(this.projectPath, "package.json");
15551
- const pkgContent = await fs46.readFile(pkgPath, "utf-8");
15634
+ const pkgContent = await fs47.readFile(pkgPath, "utf-8");
15552
15635
  const pkg = JSON.parse(pkgContent);
15553
15636
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
15554
15637
  stack.language = deps.typescript ? "TypeScript" : "JavaScript";
@@ -16213,12 +16296,229 @@ var init_analyzer2 = __esm({
16213
16296
  }
16214
16297
  });
16215
16298
 
16299
+ // core/services/diff-generator.ts
16300
+ import chalk8 from "chalk";
16301
+ function estimateTokens(content) {
16302
+ return Math.ceil(content.length / CHARS_PER_TOKEN2);
16303
+ }
16304
+ function parseMarkdownSections(content) {
16305
+ const lines = content.split("\n");
16306
+ const sections = [];
16307
+ let currentSection = null;
16308
+ for (let i = 0; i < lines.length; i++) {
16309
+ const line = lines[i];
16310
+ const headerMatch = line.match(/^(#{1,3})\s+(.+)$/);
16311
+ if (headerMatch) {
16312
+ if (currentSection) {
16313
+ currentSection.endLine = i - 1;
16314
+ sections.push(currentSection);
16315
+ }
16316
+ currentSection = {
16317
+ name: headerMatch[2].trim(),
16318
+ content: line,
16319
+ startLine: i,
16320
+ endLine: i
16321
+ };
16322
+ } else if (currentSection) {
16323
+ currentSection.content += `
16324
+ ${line}`;
16325
+ }
16326
+ }
16327
+ if (currentSection) {
16328
+ currentSection.endLine = lines.length - 1;
16329
+ sections.push(currentSection);
16330
+ }
16331
+ return sections;
16332
+ }
16333
+ function isPreservedSection(content) {
16334
+ return content.includes("<!-- prjct:preserve");
16335
+ }
16336
+ function generateSyncDiff(oldContent, newContent) {
16337
+ const oldSections = parseMarkdownSections(oldContent);
16338
+ const newSections = parseMarkdownSections(newContent);
16339
+ const diff = {
16340
+ hasChanges: false,
16341
+ added: [],
16342
+ modified: [],
16343
+ removed: [],
16344
+ preserved: [],
16345
+ tokensBefore: estimateTokens(oldContent),
16346
+ tokensAfter: estimateTokens(newContent),
16347
+ tokenDelta: 0
16348
+ };
16349
+ diff.tokenDelta = diff.tokensAfter - diff.tokensBefore;
16350
+ const oldMap = new Map(oldSections.map((s) => [s.name.toLowerCase(), s]));
16351
+ const newMap = new Map(newSections.map((s) => [s.name.toLowerCase(), s]));
16352
+ for (const section of oldSections) {
16353
+ if (isPreservedSection(section.content)) {
16354
+ diff.preserved.push({
16355
+ name: section.name,
16356
+ lineCount: section.content.split("\n").length
16357
+ });
16358
+ }
16359
+ }
16360
+ for (const newSection of newSections) {
16361
+ const key = newSection.name.toLowerCase();
16362
+ const oldSection = oldMap.get(key);
16363
+ if (!oldSection) {
16364
+ diff.added.push({
16365
+ name: newSection.name,
16366
+ type: "added",
16367
+ after: newSection.content,
16368
+ lineCount: newSection.content.split("\n").length
16369
+ });
16370
+ diff.hasChanges = true;
16371
+ } else if (oldSection.content.trim() !== newSection.content.trim()) {
16372
+ if (!isPreservedSection(oldSection.content)) {
16373
+ diff.modified.push({
16374
+ name: newSection.name,
16375
+ type: "modified",
16376
+ before: oldSection.content,
16377
+ after: newSection.content,
16378
+ lineCount: newSection.content.split("\n").length
16379
+ });
16380
+ diff.hasChanges = true;
16381
+ }
16382
+ }
16383
+ }
16384
+ for (const oldSection of oldSections) {
16385
+ const key = oldSection.name.toLowerCase();
16386
+ if (!newMap.has(key) && !isPreservedSection(oldSection.content)) {
16387
+ diff.removed.push({
16388
+ name: oldSection.name,
16389
+ type: "removed",
16390
+ before: oldSection.content,
16391
+ lineCount: oldSection.content.split("\n").length
16392
+ });
16393
+ diff.hasChanges = true;
16394
+ }
16395
+ }
16396
+ return diff;
16397
+ }
16398
+ function formatDiffPreview(diff, options = {}) {
16399
+ const { colorize = true } = options;
16400
+ const lines = [];
16401
+ const green = colorize ? chalk8.green : (s) => s;
16402
+ const red = colorize ? chalk8.red : (s) => s;
16403
+ const yellow = colorize ? chalk8.yellow : (s) => s;
16404
+ const dim = colorize ? chalk8.dim : (s) => s;
16405
+ const bold = colorize ? chalk8.bold : (s) => s;
16406
+ if (!diff.hasChanges) {
16407
+ lines.push(dim("No changes detected (context is up to date)"));
16408
+ return lines.join("\n");
16409
+ }
16410
+ lines.push("");
16411
+ lines.push(bold("\u{1F4CB} Changes to context files:"));
16412
+ lines.push("");
16413
+ if (diff.added.length > 0) {
16414
+ for (const section of diff.added) {
16415
+ lines.push(green(`+ \u2502 + ${section.name} (new)`));
16416
+ }
16417
+ }
16418
+ if (diff.modified.length > 0) {
16419
+ for (const section of diff.modified) {
16420
+ lines.push(yellow(`~ \u2502 ${section.name} (modified)`));
16421
+ }
16422
+ }
16423
+ if (diff.removed.length > 0) {
16424
+ for (const section of diff.removed) {
16425
+ lines.push(red(`- \u2502 - ${section.name} (removed)`));
16426
+ }
16427
+ }
16428
+ if (diff.preserved.length > 0) {
16429
+ lines.push("");
16430
+ lines.push(dim(" ## Your Customizations"));
16431
+ for (const section of diff.preserved) {
16432
+ lines.push(dim(` \u2502 \u2713 ${section.name} (${section.lineCount} lines preserved)`));
16433
+ }
16434
+ }
16435
+ lines.push("");
16436
+ lines.push(dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
16437
+ const summaryParts = [];
16438
+ if (diff.added.length > 0) summaryParts.push(green(`+${diff.added.length} added`));
16439
+ if (diff.modified.length > 0) summaryParts.push(yellow(`~${diff.modified.length} modified`));
16440
+ if (diff.removed.length > 0) summaryParts.push(red(`-${diff.removed.length} removed`));
16441
+ lines.push(`Summary: ${summaryParts.join(", ") || "no changes"}`);
16442
+ const tokenSign = diff.tokenDelta >= 0 ? "+" : "";
16443
+ const tokenColor = diff.tokenDelta >= 0 ? green : red;
16444
+ lines.push(
16445
+ `Tokens: ${diff.tokensBefore.toLocaleString()} \u2192 ${diff.tokensAfter.toLocaleString()} (${tokenColor(tokenSign + diff.tokenDelta.toLocaleString())})`
16446
+ );
16447
+ lines.push("");
16448
+ return lines.join("\n");
16449
+ }
16450
+ function formatFullDiff(diff, options = {}) {
16451
+ const { colorize = true } = options;
16452
+ const lines = [];
16453
+ const green = colorize ? chalk8.green : (s) => s;
16454
+ const red = colorize ? chalk8.red : (s) => s;
16455
+ const cyan = colorize ? chalk8.cyan : (s) => s;
16456
+ const dim = colorize ? chalk8.dim : (s) => s;
16457
+ for (const section of diff.added) {
16458
+ lines.push(cyan(`@@ +${section.name} @@`));
16459
+ if (section.after) {
16460
+ for (const line of section.after.split("\n")) {
16461
+ lines.push(green(`+ ${line}`));
16462
+ }
16463
+ }
16464
+ lines.push("");
16465
+ }
16466
+ for (const section of diff.modified) {
16467
+ lines.push(cyan(`@@ ${section.name} @@`));
16468
+ if (section.before) {
16469
+ for (const line of section.before.split("\n").slice(0, 5)) {
16470
+ lines.push(red(`- ${line}`));
16471
+ }
16472
+ if (section.before.split("\n").length > 5) {
16473
+ lines.push(dim(` ... ${section.before.split("\n").length - 5} more lines`));
16474
+ }
16475
+ }
16476
+ if (section.after) {
16477
+ for (const line of section.after.split("\n").slice(0, 5)) {
16478
+ lines.push(green(`+ ${line}`));
16479
+ }
16480
+ if (section.after.split("\n").length > 5) {
16481
+ lines.push(dim(` ... ${section.after.split("\n").length - 5} more lines`));
16482
+ }
16483
+ }
16484
+ lines.push("");
16485
+ }
16486
+ for (const section of diff.removed) {
16487
+ lines.push(cyan(`@@ -${section.name} @@`));
16488
+ if (section.before) {
16489
+ for (const line of section.before.split("\n").slice(0, 5)) {
16490
+ lines.push(red(`- ${line}`));
16491
+ }
16492
+ if (section.before.split("\n").length > 5) {
16493
+ lines.push(dim(` ... ${section.before.split("\n").length - 5} more lines`));
16494
+ }
16495
+ }
16496
+ lines.push("");
16497
+ }
16498
+ return lines.join("\n");
16499
+ }
16500
+ var CHARS_PER_TOKEN2;
16501
+ var init_diff_generator = __esm({
16502
+ "core/services/diff-generator.ts"() {
16503
+ "use strict";
16504
+ CHARS_PER_TOKEN2 = 4;
16505
+ __name(estimateTokens, "estimateTokens");
16506
+ __name(parseMarkdownSections, "parseMarkdownSections");
16507
+ __name(isPreservedSection, "isPreservedSection");
16508
+ __name(generateSyncDiff, "generateSyncDiff");
16509
+ __name(formatDiffPreview, "formatDiffPreview");
16510
+ __name(formatFullDiff, "formatFullDiff");
16511
+ }
16512
+ });
16513
+
16216
16514
  // core/commands/analysis.ts
16217
16515
  var analysis_exports = {};
16218
16516
  __export(analysis_exports, {
16219
16517
  AnalysisCommands: () => AnalysisCommands
16220
16518
  });
16519
+ import fs34 from "node:fs/promises";
16221
16520
  import path35 from "node:path";
16521
+ import prompts2 from "prompts";
16222
16522
  var AnalysisCommands;
16223
16523
  var init_analysis2 = __esm({
16224
16524
  "core/commands/analysis.ts"() {
@@ -16228,8 +16528,10 @@ var init_analysis2 = __esm({
16228
16528
  init_command_installer();
16229
16529
  init_metrics();
16230
16530
  init_services();
16531
+ init_diff_generator();
16231
16532
  init_metrics_storage();
16232
16533
  init_next_steps();
16534
+ init_output();
16233
16535
  init_base();
16234
16536
  AnalysisCommands = class extends PrjctCommandsBase {
16235
16537
  static {
@@ -16373,7 +16675,7 @@ var init_analysis2 = __esm({
16373
16675
  return lines.join("\n");
16374
16676
  }
16375
16677
  /**
16376
- * /p:sync - Comprehensive project sync
16678
+ * /p:sync - Comprehensive project sync with diff preview
16377
16679
  *
16378
16680
  * Uses syncService to do ALL operations in one TypeScript execution:
16379
16681
  * - Git analysis
@@ -16383,99 +16685,181 @@ var init_analysis2 = __esm({
16383
16685
  * - Skill configuration
16384
16686
  * - State updates
16385
16687
  *
16688
+ * Options:
16689
+ * - --preview: Show what would change without applying
16690
+ * - --yes: Skip confirmation prompt
16691
+ *
16386
16692
  * This eliminates the need for Claude to make 50+ individual tool calls.
16693
+ *
16694
+ * @see PRJ-125
16387
16695
  */
16388
16696
  async sync(projectPath = process.cwd(), options = {}) {
16389
16697
  try {
16390
16698
  const initResult = await this.ensureProjectInit(projectPath);
16391
16699
  if (!initResult.success) return initResult;
16700
+ const projectId = await config_manager_default.getProjectId(projectPath);
16701
+ if (!projectId) {
16702
+ output_default.failWithHint("NO_PROJECT_ID");
16703
+ return { success: false, error: "No project ID found" };
16704
+ }
16705
+ const globalPath = path_manager_default.getGlobalProjectPath(projectId);
16392
16706
  const startTime = Date.now();
16393
- console.log("\u{1F504} Syncing project...\n");
16707
+ const claudeMdPath = path35.join(globalPath, "context", "CLAUDE.md");
16708
+ let existingContent = null;
16709
+ try {
16710
+ existingContent = await fs34.readFile(claudeMdPath, "utf-8");
16711
+ } catch {
16712
+ }
16713
+ if (existingContent && !options.yes) {
16714
+ output_default.spin("Analyzing changes...");
16715
+ const result2 = await syncService.sync(projectPath, { aiTools: options.aiTools });
16716
+ if (!result2.success) {
16717
+ output_default.fail(result2.error || "Sync failed");
16718
+ return { success: false, error: result2.error };
16719
+ }
16720
+ let newContent;
16721
+ try {
16722
+ newContent = await fs34.readFile(claudeMdPath, "utf-8");
16723
+ } catch {
16724
+ newContent = "";
16725
+ }
16726
+ const diff = generateSyncDiff(existingContent, newContent);
16727
+ output_default.stop();
16728
+ if (!diff.hasChanges) {
16729
+ output_default.done("No changes detected (context is up to date)");
16730
+ return { success: true, message: "No changes" };
16731
+ }
16732
+ console.log(formatDiffPreview(diff));
16733
+ if (options.preview) {
16734
+ return {
16735
+ success: true,
16736
+ isPreview: true,
16737
+ diff,
16738
+ message: "Preview complete (no changes applied)"
16739
+ };
16740
+ }
16741
+ const response = await prompts2({
16742
+ type: "select",
16743
+ name: "action",
16744
+ message: "Apply these changes?",
16745
+ choices: [
16746
+ { title: "Yes, apply changes", value: "apply" },
16747
+ { title: "No, cancel", value: "cancel" },
16748
+ { title: "Show full diff", value: "diff" }
16749
+ ]
16750
+ });
16751
+ if (response.action === "cancel" || !response.action) {
16752
+ output_default.warn("Sync cancelled");
16753
+ return { success: false, message: "Cancelled by user" };
16754
+ }
16755
+ if (response.action === "diff") {
16756
+ console.log(`
16757
+ ${formatFullDiff(diff)}`);
16758
+ const confirm = await prompts2({
16759
+ type: "confirm",
16760
+ name: "apply",
16761
+ message: "Apply these changes?",
16762
+ initial: true
16763
+ });
16764
+ if (!confirm.apply) {
16765
+ output_default.warn("Sync cancelled");
16766
+ return { success: false, message: "Cancelled by user" };
16767
+ }
16768
+ }
16769
+ output_default.done("Changes applied");
16770
+ return this.showSyncResult(result2, startTime);
16771
+ }
16772
+ output_default.spin("Syncing project...");
16394
16773
  const result = await syncService.sync(projectPath, { aiTools: options.aiTools });
16395
16774
  if (!result.success) {
16396
- console.error("\u274C Sync failed:", result.error);
16775
+ output_default.fail(result.error || "Sync failed");
16397
16776
  return { success: false, error: result.error };
16398
16777
  }
16399
- const globalConfigResult = await command_installer_default.installGlobalConfig();
16400
- if (globalConfigResult.success) {
16401
- console.log(`\u{1F4DD} Updated ${path_manager_default.getDisplayPath(globalConfigResult.path)}`);
16402
- }
16403
- console.log(`\u{1F504} Project synced to prjct v${result.cliVersion}
16778
+ output_default.stop();
16779
+ return this.showSyncResult(result, startTime);
16780
+ } catch (error) {
16781
+ output_default.fail(error.message);
16782
+ return { success: false, error: error.message };
16783
+ }
16784
+ }
16785
+ /**
16786
+ * Display sync results (extracted to avoid duplication)
16787
+ */
16788
+ async showSyncResult(result, startTime) {
16789
+ const globalConfigResult = await command_installer_default.installGlobalConfig();
16790
+ if (globalConfigResult.success) {
16791
+ console.log(`\u{1F4DD} Updated ${path_manager_default.getDisplayPath(globalConfigResult.path)}`);
16792
+ }
16793
+ console.log(`\u{1F504} Project synced to prjct v${result.cliVersion}
16404
16794
  `);
16405
- console.log("\u{1F4CA} Project Stats");
16406
- console.log(`\u251C\u2500\u2500 Files: ~${result.stats.fileCount}`);
16407
- console.log(`\u251C\u2500\u2500 Commits: ${result.git.commits}`);
16408
- console.log(`\u251C\u2500\u2500 Version: ${result.stats.version}`);
16409
- console.log(`\u2514\u2500\u2500 Stack: ${result.stats.ecosystem}
16795
+ console.log("\u{1F4CA} Project Stats");
16796
+ console.log(`\u251C\u2500\u2500 Files: ~${result.stats.fileCount}`);
16797
+ console.log(`\u251C\u2500\u2500 Commits: ${result.git.commits}`);
16798
+ console.log(`\u251C\u2500\u2500 Version: ${result.stats.version}`);
16799
+ console.log(`\u2514\u2500\u2500 Stack: ${result.stats.ecosystem}
16410
16800
  `);
16411
- console.log("\u{1F33F} Git Status");
16412
- console.log(`\u251C\u2500\u2500 Branch: ${result.git.branch}`);
16413
- console.log(`\u251C\u2500\u2500 Uncommitted: ${result.git.hasChanges ? "Yes" : "Clean"}`);
16414
- console.log(`\u2514\u2500\u2500 Recent: ${result.git.weeklyCommits} commits this week
16801
+ console.log("\u{1F33F} Git Status");
16802
+ console.log(`\u251C\u2500\u2500 Branch: ${result.git.branch}`);
16803
+ console.log(`\u251C\u2500\u2500 Uncommitted: ${result.git.hasChanges ? "Yes" : "Clean"}`);
16804
+ console.log(`\u2514\u2500\u2500 Recent: ${result.git.weeklyCommits} commits this week
16415
16805
  `);
16416
- console.log("\u{1F4C1} Context Updated");
16417
- for (const file of result.contextFiles) {
16418
- console.log(`\u251C\u2500\u2500 ${file}`);
16806
+ console.log("\u{1F4C1} Context Updated");
16807
+ for (const file of result.contextFiles) {
16808
+ console.log(`\u251C\u2500\u2500 ${file}`);
16809
+ }
16810
+ console.log("");
16811
+ if (result.aiTools && result.aiTools.length > 0) {
16812
+ const successTools = result.aiTools.filter((t) => t.success);
16813
+ console.log(`\u{1F916} AI Tools Context (${successTools.length})`);
16814
+ for (const tool of result.aiTools) {
16815
+ const status = tool.success ? "\u2713" : "\u2717";
16816
+ console.log(`\u251C\u2500\u2500 ${status} ${tool.outputFile} (${tool.toolId})`);
16419
16817
  }
16420
16818
  console.log("");
16421
- if (result.aiTools && result.aiTools.length > 0) {
16422
- const successTools = result.aiTools.filter((t) => t.success);
16423
- console.log(`\u{1F916} AI Tools Context (${successTools.length})`);
16424
- for (const tool of result.aiTools) {
16425
- const status = tool.success ? "\u2713" : "\u2717";
16426
- console.log(`\u251C\u2500\u2500 ${status} ${tool.outputFile} (${tool.toolId})`);
16427
- }
16428
- console.log("");
16429
- }
16430
- const workflowAgents = result.agents.filter((a) => a.type === "workflow").map((a) => a.name);
16431
- const domainAgents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
16432
- console.log(`\u{1F916} Agents Regenerated (${result.agents.length})`);
16433
- console.log(`\u251C\u2500\u2500 Workflow: ${workflowAgents.join(", ")}`);
16434
- console.log(`\u2514\u2500\u2500 Domain: ${domainAgents.join(", ") || "none"}
16819
+ }
16820
+ const workflowAgents = result.agents.filter((a) => a.type === "workflow").map((a) => a.name);
16821
+ const domainAgents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
16822
+ console.log(`\u{1F916} Agents Regenerated (${result.agents.length})`);
16823
+ console.log(`\u251C\u2500\u2500 Workflow: ${workflowAgents.join(", ")}`);
16824
+ console.log(`\u2514\u2500\u2500 Domain: ${domainAgents.join(", ") || "none"}
16435
16825
  `);
16436
- if (result.skills.length > 0) {
16437
- console.log("\u{1F4E6} Skills Configured");
16438
- for (const skill of result.skills) {
16439
- console.log(`\u251C\u2500\u2500 ${skill.agent}.md \u2192 ${skill.skill}`);
16440
- }
16441
- console.log("");
16826
+ if (result.skills.length > 0) {
16827
+ console.log("\u{1F4E6} Skills Configured");
16828
+ for (const skill of result.skills) {
16829
+ console.log(`\u251C\u2500\u2500 ${skill.agent}.md \u2192 ${skill.skill}`);
16442
16830
  }
16443
- if (result.git.hasChanges) {
16444
- console.log("\u26A0\uFE0F You have uncommitted changes\n");
16445
- } else {
16446
- console.log("\u2728 Repository is clean!\n");
16447
- }
16448
- showNextSteps("sync");
16449
- const elapsed = Date.now() - startTime;
16450
- const contextFilesCount = result.contextFiles.length + (result.aiTools?.filter((t) => t.success).length || 0);
16451
- const agentCount = result.agents.length;
16452
- console.log("\u2500".repeat(45));
16453
- console.log(`\u{1F4CA} Sync Summary`);
16454
- console.log(
16455
- ` Stack: ${result.stats.ecosystem} (${result.stats.frameworks.join(", ") || "no frameworks"})`
16456
- );
16457
- console.log(
16458
- ` Files: ${result.stats.fileCount} analyzed \u2192 ${contextFilesCount} context files`
16459
- );
16460
- console.log(
16461
- ` Agents: ${agentCount} (${result.agents.filter((a) => a.type === "domain").length} domain)`
16462
- );
16463
- console.log(` Time: ${(elapsed / 1e3).toFixed(1)}s`);
16464
16831
  console.log("");
16465
- return {
16466
- success: true,
16467
- data: result,
16468
- metrics: {
16469
- elapsed,
16470
- contextFilesCount,
16471
- agentCount,
16472
- fileCount: result.stats.fileCount
16473
- }
16474
- };
16475
- } catch (error) {
16476
- console.error("\u274C Error:", error.message);
16477
- return { success: false, error: error.message };
16478
16832
  }
16833
+ if (result.git.hasChanges) {
16834
+ console.log("\u26A0\uFE0F You have uncommitted changes\n");
16835
+ } else {
16836
+ console.log("\u2728 Repository is clean!\n");
16837
+ }
16838
+ showNextSteps("sync");
16839
+ const elapsed = Date.now() - startTime;
16840
+ const contextFilesCount = result.contextFiles.length + (result.aiTools?.filter((t) => t.success).length || 0);
16841
+ const agentCount = result.agents.length;
16842
+ console.log("\u2500".repeat(45));
16843
+ console.log("\u{1F4CA} Sync Summary");
16844
+ console.log(
16845
+ ` Stack: ${result.stats.ecosystem} (${result.stats.frameworks.join(", ") || "no frameworks"})`
16846
+ );
16847
+ console.log(` Files: ${result.stats.fileCount} analyzed \u2192 ${contextFilesCount} context files`);
16848
+ console.log(
16849
+ ` Agents: ${agentCount} (${result.agents.filter((a) => a.type === "domain").length} domain)`
16850
+ );
16851
+ console.log(` Time: ${(elapsed / 1e3).toFixed(1)}s`);
16852
+ console.log("");
16853
+ return {
16854
+ success: true,
16855
+ data: result,
16856
+ metrics: {
16857
+ elapsed,
16858
+ contextFilesCount,
16859
+ agentCount,
16860
+ fileCount: result.stats.fileCount
16861
+ }
16862
+ };
16479
16863
  }
16480
16864
  /**
16481
16865
  * /p:stats - Value dashboard showing accumulated savings and impact
@@ -16514,10 +16898,10 @@ var init_analysis2 = __esm({
16514
16898
  const globalPath = path_manager_default.getGlobalProjectPath(projectId);
16515
16899
  let projectName = "Unknown";
16516
16900
  try {
16517
- const fs46 = __require("node:fs/promises");
16901
+ const fs47 = __require("node:fs/promises");
16518
16902
  const path56 = __require("node:path");
16519
16903
  const projectJson = JSON.parse(
16520
- await fs46.readFile(path56.join(globalPath, "project.json"), "utf-8")
16904
+ await fs47.readFile(path56.join(globalPath, "project.json"), "utf-8")
16521
16905
  );
16522
16906
  projectName = projectJson.name || "Unknown";
16523
16907
  } catch {
@@ -17124,8 +17508,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
17124
17508
  const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
17125
17509
  const specsPath2 = path36.join(globalPath2, "planning", "specs");
17126
17510
  try {
17127
- const fs46 = await import("node:fs/promises");
17128
- const files = await fs46.readdir(specsPath2);
17511
+ const fs47 = await import("node:fs/promises");
17512
+ const files = await fs47.readdir(specsPath2);
17129
17513
  const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
17130
17514
  if (specs.length === 0) {
17131
17515
  output_default.warn("no specs yet");
@@ -17556,7 +17940,7 @@ var init_formatters = __esm({
17556
17940
 
17557
17941
  // core/ai-tools/registry.ts
17558
17942
  import { execSync as execSync4 } from "node:child_process";
17559
- import fs34 from "node:fs";
17943
+ import fs35 from "node:fs";
17560
17944
  import os11 from "node:os";
17561
17945
  import path37 from "node:path";
17562
17946
  function getAIToolConfig(id) {
@@ -17575,16 +17959,16 @@ function detectInstalledTools(repoPath = process.cwd()) {
17575
17959
  if (commandExists("claude")) {
17576
17960
  detected.push("claude");
17577
17961
  }
17578
- if (commandExists("cursor") || fs34.existsSync(path37.join(repoPath, ".cursor"))) {
17962
+ if (commandExists("cursor") || fs35.existsSync(path37.join(repoPath, ".cursor"))) {
17579
17963
  detected.push("cursor");
17580
17964
  }
17581
- if (fs34.existsSync(path37.join(repoPath, ".github"))) {
17965
+ if (fs35.existsSync(path37.join(repoPath, ".github"))) {
17582
17966
  detected.push("copilot");
17583
17967
  }
17584
- if (commandExists("windsurf") || fs34.existsSync(path37.join(repoPath, ".windsurf"))) {
17968
+ if (commandExists("windsurf") || fs35.existsSync(path37.join(repoPath, ".windsurf"))) {
17585
17969
  detected.push("windsurf");
17586
17970
  }
17587
- if (fs34.existsSync(path37.join(repoPath, ".continue")) || fs34.existsSync(path37.join(os11.homedir(), ".continue"))) {
17971
+ if (fs35.existsSync(path37.join(repoPath, ".continue")) || fs35.existsSync(path37.join(os11.homedir(), ".continue"))) {
17588
17972
  detected.push("continue");
17589
17973
  }
17590
17974
  return detected;
@@ -17660,7 +18044,7 @@ var init_registry = __esm({
17660
18044
  });
17661
18045
 
17662
18046
  // core/ai-tools/generator.ts
17663
- import fs35 from "node:fs/promises";
18047
+ import fs36 from "node:fs/promises";
17664
18048
  import path38 from "node:path";
17665
18049
  async function generateAIToolContexts(context2, globalPath, repoPath, toolIds = DEFAULT_AI_TOOLS) {
17666
18050
  const results = [];
@@ -17700,9 +18084,9 @@ async function generateForTool(context2, config, globalPath, repoPath) {
17700
18084
  } else {
17701
18085
  outputPath = path38.join(globalPath, "context", config.outputFile);
17702
18086
  }
17703
- await fs35.mkdir(path38.dirname(outputPath), { recursive: true });
18087
+ await fs36.mkdir(path38.dirname(outputPath), { recursive: true });
17704
18088
  try {
17705
- const existingContent = await fs35.readFile(outputPath, "utf-8");
18089
+ const existingContent = await fs36.readFile(outputPath, "utf-8");
17706
18090
  const validation = validatePreserveBlocks(existingContent);
17707
18091
  if (!validation.valid) {
17708
18092
  console.warn(`\u26A0\uFE0F ${config.outputFile} has invalid preserve blocks:`);
@@ -17713,7 +18097,7 @@ async function generateForTool(context2, config, globalPath, repoPath) {
17713
18097
  content = mergePreservedSections(content, existingContent);
17714
18098
  } catch {
17715
18099
  }
17716
- await fs35.writeFile(outputPath, content, "utf-8");
18100
+ await fs36.writeFile(outputPath, content, "utf-8");
17717
18101
  return {
17718
18102
  toolId: config.id,
17719
18103
  outputFile: config.outputFile,
@@ -17752,7 +18136,7 @@ var init_ai_tools = __esm({
17752
18136
  });
17753
18137
 
17754
18138
  // core/services/context-generator.ts
17755
- import fs36 from "node:fs/promises";
18139
+ import fs37 from "node:fs/promises";
17756
18140
  import path39 from "node:path";
17757
18141
  var ContextFileGenerator;
17758
18142
  var init_context_generator = __esm({
@@ -17775,7 +18159,7 @@ var init_context_generator = __esm({
17775
18159
  async writeWithPreservation(filePath, content) {
17776
18160
  let finalContent = content;
17777
18161
  try {
17778
- const existingContent = await fs36.readFile(filePath, "utf-8");
18162
+ const existingContent = await fs37.readFile(filePath, "utf-8");
17779
18163
  const validation = validatePreserveBlocks(existingContent);
17780
18164
  if (!validation.valid) {
17781
18165
  const filename = path39.basename(filePath);
@@ -17787,7 +18171,7 @@ var init_context_generator = __esm({
17787
18171
  finalContent = mergePreservedSections(content, existingContent);
17788
18172
  } catch {
17789
18173
  }
17790
- await fs36.writeFile(filePath, finalContent, "utf-8");
18174
+ await fs37.writeFile(filePath, finalContent, "utf-8");
17791
18175
  }
17792
18176
  /**
17793
18177
  * Generate all context files in parallel
@@ -17897,7 +18281,7 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
17897
18281
  let currentTask = null;
17898
18282
  try {
17899
18283
  const statePath = path39.join(this.config.globalPath, "storage", "state.json");
17900
- const state = JSON.parse(await fs36.readFile(statePath, "utf-8"));
18284
+ const state = JSON.parse(await fs37.readFile(statePath, "utf-8"));
17901
18285
  currentTask = state.currentTask;
17902
18286
  } catch {
17903
18287
  }
@@ -17922,7 +18306,7 @@ Use \`p. task "description"\` to start working.
17922
18306
  let queue = { tasks: [] };
17923
18307
  try {
17924
18308
  const queuePath = path39.join(this.config.globalPath, "storage", "queue.json");
17925
- queue = JSON.parse(await fs36.readFile(queuePath, "utf-8"));
18309
+ queue = JSON.parse(await fs37.readFile(queuePath, "utf-8"));
17926
18310
  } catch {
17927
18311
  }
17928
18312
  const content = `# NEXT
@@ -17938,7 +18322,7 @@ ${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}
17938
18322
  let ideas = { ideas: [] };
17939
18323
  try {
17940
18324
  const ideasPath = path39.join(this.config.globalPath, "storage", "ideas.json");
17941
- ideas = JSON.parse(await fs36.readFile(ideasPath, "utf-8"));
18325
+ ideas = JSON.parse(await fs37.readFile(ideasPath, "utf-8"));
17942
18326
  } catch {
17943
18327
  }
17944
18328
  const content = `# IDEAS
@@ -17956,7 +18340,7 @@ ${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [
17956
18340
  };
17957
18341
  try {
17958
18342
  const shippedPath = path39.join(this.config.globalPath, "storage", "shipped.json");
17959
- shipped = JSON.parse(await fs36.readFile(shippedPath, "utf-8"));
18343
+ shipped = JSON.parse(await fs37.readFile(shippedPath, "utf-8"));
17960
18344
  } catch {
17961
18345
  }
17962
18346
  const content = `# SHIPPED \u{1F680}
@@ -17972,7 +18356,7 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
17972
18356
  });
17973
18357
 
17974
18358
  // core/services/stack-detector.ts
17975
- import fs37 from "node:fs/promises";
18359
+ import fs38 from "node:fs/promises";
17976
18360
  import path40 from "node:path";
17977
18361
  var StackDetector;
17978
18362
  var init_stack_detector = __esm({
@@ -18133,7 +18517,7 @@ var init_stack_detector = __esm({
18133
18517
  async readPackageJson() {
18134
18518
  try {
18135
18519
  const pkgPath = path40.join(this.projectPath, "package.json");
18136
- const content = await fs37.readFile(pkgPath, "utf-8");
18520
+ const content = await fs38.readFile(pkgPath, "utf-8");
18137
18521
  return JSON.parse(content);
18138
18522
  } catch {
18139
18523
  return null;
@@ -18144,7 +18528,7 @@ var init_stack_detector = __esm({
18144
18528
  */
18145
18529
  async fileExists(filename) {
18146
18530
  try {
18147
- await fs37.access(path40.join(this.projectPath, filename));
18531
+ await fs38.access(path40.join(this.projectPath, filename));
18148
18532
  return true;
18149
18533
  } catch {
18150
18534
  return false;
@@ -18156,7 +18540,7 @@ var init_stack_detector = __esm({
18156
18540
 
18157
18541
  // core/services/sync-service.ts
18158
18542
  import { exec as exec10 } from "node:child_process";
18159
- import fs38 from "node:fs/promises";
18543
+ import fs39 from "node:fs/promises";
18160
18544
  import path41 from "node:path";
18161
18545
  import { promisify as promisify10 } from "node:util";
18162
18546
  var execAsync5, SyncService, syncService;
@@ -18303,7 +18687,7 @@ var init_sync_service = __esm({
18303
18687
  async ensureDirectories() {
18304
18688
  const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
18305
18689
  await Promise.all(
18306
- dirs.map((dir) => fs38.mkdir(path41.join(this.globalPath, dir), { recursive: true }))
18690
+ dirs.map((dir) => fs39.mkdir(path41.join(this.globalPath, dir), { recursive: true }))
18307
18691
  );
18308
18692
  }
18309
18693
  // ==========================================================================
@@ -18390,7 +18774,7 @@ var init_sync_service = __esm({
18390
18774
  }
18391
18775
  try {
18392
18776
  const pkgPath = path41.join(this.projectPath, "package.json");
18393
- const pkg = JSON.parse(await fs38.readFile(pkgPath, "utf-8"));
18777
+ const pkg = JSON.parse(await fs39.readFile(pkgPath, "utf-8"));
18394
18778
  stats.version = pkg.version || "0.0.0";
18395
18779
  stats.name = pkg.name || stats.name;
18396
18780
  stats.ecosystem = "JavaScript";
@@ -18500,10 +18884,10 @@ var init_sync_service = __esm({
18500
18884
  const agents = [];
18501
18885
  const agentsPath = path41.join(this.globalPath, "agents");
18502
18886
  try {
18503
- const files = await fs38.readdir(agentsPath);
18887
+ const files = await fs39.readdir(agentsPath);
18504
18888
  for (const file of files) {
18505
18889
  if (file.endsWith(".md")) {
18506
- await fs38.unlink(path41.join(agentsPath, file));
18890
+ await fs39.unlink(path41.join(agentsPath, file));
18507
18891
  }
18508
18892
  }
18509
18893
  } catch {
@@ -18552,11 +18936,11 @@ var init_sync_service = __esm({
18552
18936
  "workflow",
18553
18937
  `${name}.md`
18554
18938
  );
18555
- content = await fs38.readFile(templatePath, "utf-8");
18939
+ content = await fs39.readFile(templatePath, "utf-8");
18556
18940
  } catch {
18557
18941
  content = this.generateMinimalWorkflowAgent(name);
18558
18942
  }
18559
- await fs38.writeFile(path41.join(agentsPath, `${name}.md`), content, "utf-8");
18943
+ await fs39.writeFile(path41.join(agentsPath, `${name}.md`), content, "utf-8");
18560
18944
  }
18561
18945
  async generateDomainAgent(name, agentsPath, stats, stack) {
18562
18946
  let content = "";
@@ -18570,14 +18954,14 @@ var init_sync_service = __esm({
18570
18954
  "domain",
18571
18955
  `${name}.md`
18572
18956
  );
18573
- content = await fs38.readFile(templatePath, "utf-8");
18957
+ content = await fs39.readFile(templatePath, "utf-8");
18574
18958
  content = content.replace("{projectName}", stats.name);
18575
18959
  content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
18576
18960
  content = content.replace("{ecosystem}", stats.ecosystem);
18577
18961
  } catch {
18578
18962
  content = this.generateMinimalDomainAgent(name, stats, stack);
18579
18963
  }
18580
- await fs38.writeFile(path41.join(agentsPath, `${name}.md`), content, "utf-8");
18964
+ await fs39.writeFile(path41.join(agentsPath, `${name}.md`), content, "utf-8");
18581
18965
  }
18582
18966
  generateMinimalWorkflowAgent(name) {
18583
18967
  const descriptions = {
@@ -18645,7 +19029,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
18645
19029
  })),
18646
19030
  agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
18647
19031
  };
18648
- fs38.writeFile(
19032
+ fs39.writeFile(
18649
19033
  path41.join(this.globalPath, "config", "skills.json"),
18650
19034
  JSON.stringify(skillsConfig, null, 2),
18651
19035
  "utf-8"
@@ -18671,7 +19055,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
18671
19055
  const projectJsonPath = path41.join(this.globalPath, "project.json");
18672
19056
  let existing = {};
18673
19057
  try {
18674
- existing = JSON.parse(await fs38.readFile(projectJsonPath, "utf-8"));
19058
+ existing = JSON.parse(await fs39.readFile(projectJsonPath, "utf-8"));
18675
19059
  } catch {
18676
19060
  }
18677
19061
  const updated = {
@@ -18690,7 +19074,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
18690
19074
  createdAt: existing.createdAt || date_helper_default.getTimestamp(),
18691
19075
  lastSync: date_helper_default.getTimestamp()
18692
19076
  };
18693
- await fs38.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
19077
+ await fs39.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
18694
19078
  }
18695
19079
  // ==========================================================================
18696
19080
  // STATE.JSON UPDATE
@@ -18699,7 +19083,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
18699
19083
  const statePath = path41.join(this.globalPath, "storage", "state.json");
18700
19084
  let state = {};
18701
19085
  try {
18702
- state = JSON.parse(await fs38.readFile(statePath, "utf-8"));
19086
+ state = JSON.parse(await fs39.readFile(statePath, "utf-8"));
18703
19087
  } catch {
18704
19088
  }
18705
19089
  state.projectId = this.projectId;
@@ -18726,7 +19110,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
18726
19110
  lastAction: "Synced project",
18727
19111
  nextAction: 'Run `p. task "description"` to start working'
18728
19112
  };
18729
- await fs38.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
19113
+ await fs39.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
18730
19114
  }
18731
19115
  // ==========================================================================
18732
19116
  // MEMORY LOGGING
@@ -18741,7 +19125,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
18741
19125
  fileCount: stats.fileCount,
18742
19126
  commitCount: git.commits
18743
19127
  };
18744
- await fs38.appendFile(memoryPath, `${JSON.stringify(event)}
19128
+ await fs39.appendFile(memoryPath, `${JSON.stringify(event)}
18745
19129
  `, "utf-8");
18746
19130
  }
18747
19131
  // ==========================================================================
@@ -18757,12 +19141,12 @@ You are the ${name} expert for this project. Apply best practices for the detect
18757
19141
  * Token estimation: ~4 chars per token (industry standard)
18758
19142
  */
18759
19143
  async recordSyncMetrics(stats, contextFiles, agents, duration) {
18760
- const CHARS_PER_TOKEN2 = 4;
19144
+ const CHARS_PER_TOKEN3 = 4;
18761
19145
  let filteredChars = 0;
18762
19146
  for (const file of contextFiles) {
18763
19147
  try {
18764
19148
  const filePath = path41.join(this.globalPath, file);
18765
- const content = await fs38.readFile(filePath, "utf-8");
19149
+ const content = await fs39.readFile(filePath, "utf-8");
18766
19150
  filteredChars += content.length;
18767
19151
  } catch {
18768
19152
  }
@@ -18770,12 +19154,12 @@ You are the ${name} expert for this project. Apply best practices for the detect
18770
19154
  for (const agent of agents) {
18771
19155
  try {
18772
19156
  const agentPath = path41.join(this.globalPath, "agents", `${agent.name}.md`);
18773
- const content = await fs38.readFile(agentPath, "utf-8");
19157
+ const content = await fs39.readFile(agentPath, "utf-8");
18774
19158
  filteredChars += content.length;
18775
19159
  } catch {
18776
19160
  }
18777
19161
  }
18778
- const filteredSize = Math.floor(filteredChars / CHARS_PER_TOKEN2);
19162
+ const filteredSize = Math.floor(filteredChars / CHARS_PER_TOKEN3);
18779
19163
  const avgTokensPerFile = 500;
18780
19164
  const originalSize = stats.fileCount * avgTokensPerFile;
18781
19165
  const compressionRate = originalSize > 0 ? Math.max(0, (originalSize - filteredSize) / originalSize) : 0;
@@ -18802,7 +19186,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
18802
19186
  // ==========================================================================
18803
19187
  async fileExists(filename) {
18804
19188
  try {
18805
- await fs38.access(path41.join(this.projectPath, filename));
19189
+ await fs39.access(path41.join(this.projectPath, filename));
18806
19190
  return true;
18807
19191
  } catch {
18808
19192
  return false;
@@ -18811,7 +19195,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
18811
19195
  async getCliVersion() {
18812
19196
  try {
18813
19197
  const pkgPath = path41.join(__dirname, "..", "..", "package.json");
18814
- const pkg = JSON.parse(await fs38.readFile(pkgPath, "utf-8"));
19198
+ const pkg = JSON.parse(await fs39.readFile(pkgPath, "utf-8"));
18815
19199
  return pkg.version || "0.0.0";
18816
19200
  } catch {
18817
19201
  return "0.0.0";
@@ -18970,22 +19354,22 @@ __export(uninstall_exports, {
18970
19354
  });
18971
19355
  import { execSync as execSync5 } from "node:child_process";
18972
19356
  import fsSync2 from "node:fs";
18973
- import fs39 from "node:fs/promises";
19357
+ import fs40 from "node:fs/promises";
18974
19358
  import os12 from "node:os";
18975
19359
  import path42 from "node:path";
18976
19360
  import readline2 from "node:readline";
18977
- import chalk8 from "chalk";
19361
+ import chalk9 from "chalk";
18978
19362
  async function getDirectorySize(dirPath) {
18979
19363
  let totalSize = 0;
18980
19364
  try {
18981
- const entries = await fs39.readdir(dirPath, { withFileTypes: true });
19365
+ const entries = await fs40.readdir(dirPath, { withFileTypes: true });
18982
19366
  for (const entry of entries) {
18983
19367
  const entryPath = path42.join(dirPath, entry.name);
18984
19368
  if (entry.isDirectory()) {
18985
19369
  totalSize += await getDirectorySize(entryPath);
18986
19370
  } else {
18987
19371
  try {
18988
- const stats = await fs39.stat(entryPath);
19372
+ const stats = await fs40.stat(entryPath);
18989
19373
  totalSize += stats.size;
18990
19374
  } catch {
18991
19375
  }
@@ -19004,7 +19388,7 @@ function formatSize(bytes) {
19004
19388
  }
19005
19389
  async function countDirectoryItems(dirPath) {
19006
19390
  try {
19007
- const entries = await fs39.readdir(dirPath, { withFileTypes: true });
19391
+ const entries = await fs40.readdir(dirPath, { withFileTypes: true });
19008
19392
  return entries.filter((e) => e.isDirectory()).length;
19009
19393
  } catch {
19010
19394
  return 0;
@@ -19119,7 +19503,7 @@ async function gatherUninstallItems() {
19119
19503
  }
19120
19504
  async function removePrjctSection(filePath) {
19121
19505
  try {
19122
- const content = await fs39.readFile(filePath, "utf-8");
19506
+ const content = await fs40.readFile(filePath, "utf-8");
19123
19507
  if (!content.includes(PRJCT_START_MARKER) || !content.includes(PRJCT_END_MARKER)) {
19124
19508
  return false;
19125
19509
  }
@@ -19128,9 +19512,9 @@ async function removePrjctSection(filePath) {
19128
19512
  let newContent = content.substring(0, startIndex) + content.substring(endIndex);
19129
19513
  newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
19130
19514
  if (!newContent || newContent.trim().length === 0) {
19131
- await fs39.unlink(filePath);
19515
+ await fs40.unlink(filePath);
19132
19516
  } else {
19133
- await fs39.writeFile(filePath, `${newContent}
19517
+ await fs40.writeFile(filePath, `${newContent}
19134
19518
  `, "utf-8");
19135
19519
  }
19136
19520
  return true;
@@ -19143,7 +19527,7 @@ async function createBackup() {
19143
19527
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
19144
19528
  const backupDir = path42.join(homeDir, `.prjct-backup-${timestamp}`);
19145
19529
  try {
19146
- await fs39.mkdir(backupDir, { recursive: true });
19530
+ await fs40.mkdir(backupDir, { recursive: true });
19147
19531
  const prjctCliPath = path_manager_default.getGlobalBasePath();
19148
19532
  if (fsSync2.existsSync(prjctCliPath)) {
19149
19533
  await copyDirectory(prjctCliPath, path42.join(backupDir, ".prjct-cli"));
@@ -19154,15 +19538,15 @@ async function createBackup() {
19154
19538
  }
19155
19539
  }
19156
19540
  async function copyDirectory(src, dest) {
19157
- await fs39.mkdir(dest, { recursive: true });
19158
- const entries = await fs39.readdir(src, { withFileTypes: true });
19541
+ await fs40.mkdir(dest, { recursive: true });
19542
+ const entries = await fs40.readdir(src, { withFileTypes: true });
19159
19543
  for (const entry of entries) {
19160
19544
  const srcPath = path42.join(src, entry.name);
19161
19545
  const destPath = path42.join(dest, entry.name);
19162
19546
  if (entry.isDirectory()) {
19163
19547
  await copyDirectory(srcPath, destPath);
19164
19548
  } else {
19165
- await fs39.copyFile(srcPath, destPath);
19549
+ await fs40.copyFile(srcPath, destPath);
19166
19550
  }
19167
19551
  }
19168
19552
  }
@@ -19178,10 +19562,10 @@ async function performUninstall(items, installation, options) {
19178
19562
  deleted.push(item.path);
19179
19563
  }
19180
19564
  } else if (item.type === "directory") {
19181
- await fs39.rm(item.path, { recursive: true, force: true });
19565
+ await fs40.rm(item.path, { recursive: true, force: true });
19182
19566
  deleted.push(item.path);
19183
19567
  } else if (item.type === "file") {
19184
- await fs39.unlink(item.path);
19568
+ await fs40.unlink(item.path);
19185
19569
  deleted.push(item.path);
19186
19570
  }
19187
19571
  } catch (error) {
@@ -19229,7 +19613,7 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
19229
19613
  const installation = detectInstallation();
19230
19614
  const existingItems = items.filter((i) => i.exists);
19231
19615
  if (existingItems.length === 0 && !installation.homebrew && !installation.npm) {
19232
- console.log(chalk8.yellow("\nNo prjct installation found."));
19616
+ console.log(chalk9.yellow("\nNo prjct installation found."));
19233
19617
  return {
19234
19618
  success: true,
19235
19619
  message: "Nothing to uninstall"
@@ -19237,36 +19621,36 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
19237
19621
  }
19238
19622
  const totalSize = existingItems.reduce((sum, item) => sum + (item.size || 0), 0);
19239
19623
  console.log("");
19240
- console.log(chalk8.red.bold(" WARNING: This action is DANGEROUS and IRREVERSIBLE"));
19624
+ console.log(chalk9.red.bold(" WARNING: This action is DANGEROUS and IRREVERSIBLE"));
19241
19625
  console.log("");
19242
- console.log(chalk8.white("The following will be permanently deleted:"));
19626
+ console.log(chalk9.white("The following will be permanently deleted:"));
19243
19627
  console.log("");
19244
19628
  for (const item of existingItems) {
19245
19629
  const displayPath = path_manager_default.getDisplayPath(item.path);
19246
19630
  let info = "";
19247
19631
  if (item.type === "section") {
19248
- info = chalk8.dim("(section only)");
19632
+ info = chalk9.dim("(section only)");
19249
19633
  } else if (item.size) {
19250
- info = chalk8.dim(`(${formatSize(item.size)})`);
19634
+ info = chalk9.dim(`(${formatSize(item.size)})`);
19251
19635
  }
19252
- console.log(` ${chalk8.cyan(displayPath.padEnd(35))} ${info}`);
19253
- console.log(` ${chalk8.dim(item.description)}`);
19636
+ console.log(` ${chalk9.cyan(displayPath.padEnd(35))} ${info}`);
19637
+ console.log(` ${chalk9.dim(item.description)}`);
19254
19638
  console.log("");
19255
19639
  }
19256
19640
  if (installation.homebrew) {
19257
- console.log(` ${chalk8.cyan("Homebrew".padEnd(35))} ${chalk8.dim("prjct-cli formula")}`);
19641
+ console.log(` ${chalk9.cyan("Homebrew".padEnd(35))} ${chalk9.dim("prjct-cli formula")}`);
19258
19642
  console.log("");
19259
19643
  }
19260
19644
  if (installation.npm) {
19261
- console.log(` ${chalk8.cyan("npm global".padEnd(35))} ${chalk8.dim("prjct-cli package")}`);
19645
+ console.log(` ${chalk9.cyan("npm global".padEnd(35))} ${chalk9.dim("prjct-cli package")}`);
19262
19646
  console.log("");
19263
19647
  }
19264
19648
  if (totalSize > 0) {
19265
- console.log(chalk8.dim(` Total size: ${formatSize(totalSize)}`));
19649
+ console.log(chalk9.dim(` Total size: ${formatSize(totalSize)}`));
19266
19650
  console.log("");
19267
19651
  }
19268
19652
  if (options.dryRun) {
19269
- console.log(chalk8.yellow("Dry run - no changes made"));
19653
+ console.log(chalk9.yellow("Dry run - no changes made"));
19270
19654
  return {
19271
19655
  success: true,
19272
19656
  message: "Dry run complete",
@@ -19274,20 +19658,20 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
19274
19658
  };
19275
19659
  }
19276
19660
  if (options.backup) {
19277
- console.log(chalk8.blue("Creating backup..."));
19661
+ console.log(chalk9.blue("Creating backup..."));
19278
19662
  const backupPath = await createBackup();
19279
19663
  if (backupPath) {
19280
- console.log(chalk8.green(`Backup created: ${path_manager_default.getDisplayPath(backupPath)}`));
19664
+ console.log(chalk9.green(`Backup created: ${path_manager_default.getDisplayPath(backupPath)}`));
19281
19665
  console.log("");
19282
19666
  } else {
19283
- console.log(chalk8.yellow("Failed to create backup, continuing..."));
19667
+ console.log(chalk9.yellow("Failed to create backup, continuing..."));
19284
19668
  }
19285
19669
  }
19286
19670
  if (!options.force) {
19287
- console.log(chalk8.yellow('Type "uninstall" to confirm:'));
19671
+ console.log(chalk9.yellow('Type "uninstall" to confirm:'));
19288
19672
  const confirmed = await promptConfirmation("> ");
19289
19673
  if (!confirmed) {
19290
- console.log(chalk8.yellow("\nUninstall cancelled."));
19674
+ console.log(chalk9.yellow("\nUninstall cancelled."));
19291
19675
  return {
19292
19676
  success: false,
19293
19677
  message: "Uninstall cancelled by user"
@@ -19295,22 +19679,22 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
19295
19679
  }
19296
19680
  }
19297
19681
  console.log("");
19298
- console.log(chalk8.blue("Removing prjct..."));
19682
+ console.log(chalk9.blue("Removing prjct..."));
19299
19683
  const { deleted, errors } = await performUninstall(items, installation, options);
19300
19684
  console.log("");
19301
19685
  if (deleted.length > 0) {
19302
- console.log(chalk8.green(`Removed ${deleted.length} items`));
19686
+ console.log(chalk9.green(`Removed ${deleted.length} items`));
19303
19687
  }
19304
19688
  if (errors.length > 0) {
19305
- console.log(chalk8.yellow(`
19689
+ console.log(chalk9.yellow(`
19306
19690
  ${errors.length} errors:`));
19307
19691
  for (const error of errors) {
19308
- console.log(chalk8.red(` - ${error}`));
19692
+ console.log(chalk9.red(` - ${error}`));
19309
19693
  }
19310
19694
  }
19311
19695
  console.log("");
19312
- console.log(chalk8.green("prjct has been uninstalled."));
19313
- console.log(chalk8.dim("Thanks for using prjct! We hope to see you again."));
19696
+ console.log(chalk9.green("prjct has been uninstalled."));
19697
+ console.log(chalk9.dim("Thanks for using prjct! We hope to see you again."));
19314
19698
  console.log("");
19315
19699
  return {
19316
19700
  success: errors.length === 0,
@@ -19357,7 +19741,7 @@ __export(watch_service_exports, {
19357
19741
  watchService: () => watchService
19358
19742
  });
19359
19743
  import path43 from "node:path";
19360
- import chalk9 from "chalk";
19744
+ import chalk10 from "chalk";
19361
19745
  import chokidar from "chokidar";
19362
19746
  var TRIGGER_PATTERNS, IGNORE_PATTERNS2, WatchService, watchService;
19363
19747
  var init_watch_service = __esm({
@@ -19467,7 +19851,7 @@ var init_watch_service = __esm({
19467
19851
  async stop() {
19468
19852
  if (!this.options.quiet) {
19469
19853
  console.log("");
19470
- console.log(chalk9.dim(`
19854
+ console.log(chalk10.dim(`
19471
19855
  \u{1F44B} Stopped watching (${this.syncCount} syncs performed)`));
19472
19856
  }
19473
19857
  if (this.debounceTimer) {
@@ -19488,7 +19872,7 @@ var init_watch_service = __esm({
19488
19872
  this.pendingChanges.add(filePath);
19489
19873
  if (this.options.verbose && !this.options.quiet) {
19490
19874
  const eventIcon = event === "add" ? "\u2795" : event === "unlink" ? "\u2796" : "\u{1F4DD}";
19491
- console.log(chalk9.dim(` ${eventIcon} ${filePath}`));
19875
+ console.log(chalk10.dim(` ${eventIcon} ${filePath}`));
19492
19876
  }
19493
19877
  this.scheduleSyncIfNeeded();
19494
19878
  }
@@ -19505,7 +19889,7 @@ var init_watch_service = __esm({
19505
19889
  if (timeSinceLastSync < this.options.minIntervalMs && this.lastSyncTime > 0) {
19506
19890
  const waitTime = this.options.minIntervalMs - timeSinceLastSync;
19507
19891
  if (this.options.verbose && !this.options.quiet) {
19508
- console.log(chalk9.dim(` \u23F3 Rate limited, waiting ${Math.round(waitTime / 1e3)}s...`));
19892
+ console.log(chalk10.dim(` \u23F3 Rate limited, waiting ${Math.round(waitTime / 1e3)}s...`));
19509
19893
  }
19510
19894
  this.debounceTimer = setTimeout(() => this.performSync(), waitTime);
19511
19895
  return;
@@ -19525,7 +19909,7 @@ var init_watch_service = __esm({
19525
19909
  const filesSummary = changedFiles.length === 1 ? changedFiles[0] : `${changedFiles.length} files`;
19526
19910
  console.log(
19527
19911
  `
19528
- ${chalk9.dim(`[${timestamp}]`)} ${chalk9.cyan("\u27F3")} ${filesSummary} changed \u2192 syncing...`
19912
+ ${chalk10.dim(`[${timestamp}]`)} ${chalk10.cyan("\u27F3")} ${filesSummary} changed \u2192 syncing...`
19529
19913
  );
19530
19914
  }
19531
19915
  try {
@@ -19536,16 +19920,16 @@ ${chalk9.dim(`[${timestamp}]`)} ${chalk9.cyan("\u27F3")} ${filesSummary} changed
19536
19920
  if (!this.options.quiet) {
19537
19921
  const agents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
19538
19922
  const agentStr = agents.length > 0 ? ` [${agents.join(", ")}]` : "";
19539
- console.log(`${chalk9.dim(`[${timestamp}]`)} ${chalk9.green("\u2713")} Synced${agentStr}`);
19923
+ console.log(`${chalk10.dim(`[${timestamp}]`)} ${chalk10.green("\u2713")} Synced${agentStr}`);
19540
19924
  }
19541
19925
  } else {
19542
19926
  console.error(
19543
- `${chalk9.dim(`[${timestamp}]`)} ${chalk9.red("\u2717")} Sync failed: ${result.error}`
19927
+ `${chalk10.dim(`[${timestamp}]`)} ${chalk10.red("\u2717")} Sync failed: ${result.error}`
19544
19928
  );
19545
19929
  }
19546
19930
  } catch (error) {
19547
19931
  console.error(
19548
- `${chalk9.dim(`[${timestamp}]`)} ${chalk9.red("\u2717")} Error: ${error.message}`
19932
+ `${chalk10.dim(`[${timestamp}]`)} ${chalk10.red("\u2717")} Error: ${error.message}`
19549
19933
  );
19550
19934
  }
19551
19935
  }
@@ -19553,19 +19937,19 @@ ${chalk9.dim(`[${timestamp}]`)} ${chalk9.cyan("\u27F3")} ${filesSummary} changed
19553
19937
  * Handle watcher errors
19554
19938
  */
19555
19939
  handleError(error) {
19556
- console.error(chalk9.red(`Watch error: ${error.message}`));
19940
+ console.error(chalk10.red(`Watch error: ${error.message}`));
19557
19941
  }
19558
19942
  /**
19559
19943
  * Print startup message
19560
19944
  */
19561
19945
  printStartup() {
19562
19946
  console.log("");
19563
- console.log(chalk9.cyan("\u{1F441}\uFE0F Watching for changes..."));
19564
- console.log(chalk9.dim(` Project: ${path43.basename(this.projectPath)}`));
19565
- console.log(chalk9.dim(` Debounce: ${this.options.debounceMs}ms`));
19566
- console.log(chalk9.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
19947
+ console.log(chalk10.cyan("\u{1F441}\uFE0F Watching for changes..."));
19948
+ console.log(chalk10.dim(` Project: ${path43.basename(this.projectPath)}`));
19949
+ console.log(chalk10.dim(` Debounce: ${this.options.debounceMs}ms`));
19950
+ console.log(chalk10.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
19567
19951
  console.log("");
19568
- console.log(chalk9.dim(" Press Ctrl+C to stop"));
19952
+ console.log(chalk10.dim(" Press Ctrl+C to stop"));
19569
19953
  console.log("");
19570
19954
  }
19571
19955
  };
@@ -20213,7 +20597,7 @@ __export(setup_exports, {
20213
20597
  run: () => run
20214
20598
  });
20215
20599
  import { execSync as execSync6 } from "node:child_process";
20216
- import fs40 from "node:fs";
20600
+ import fs41 from "node:fs";
20217
20601
  import os13 from "node:os";
20218
20602
  import path44 from "node:path";
20219
20603
  async function installAICLI(provider) {
@@ -20323,9 +20707,9 @@ async function installGeminiRouter() {
20323
20707
  const geminiCommandsDir = path44.join(os13.homedir(), ".gemini", "commands");
20324
20708
  const routerSource = path44.join(getPackageRoot(), "templates", "commands", "p.toml");
20325
20709
  const routerDest = path44.join(geminiCommandsDir, "p.toml");
20326
- fs40.mkdirSync(geminiCommandsDir, { recursive: true });
20327
- if (fs40.existsSync(routerSource)) {
20328
- fs40.copyFileSync(routerSource, routerDest);
20710
+ fs41.mkdirSync(geminiCommandsDir, { recursive: true });
20711
+ if (fs41.existsSync(routerSource)) {
20712
+ fs41.copyFileSync(routerSource, routerDest);
20329
20713
  return true;
20330
20714
  }
20331
20715
  return false;
@@ -20339,12 +20723,12 @@ async function installGeminiGlobalConfig() {
20339
20723
  const geminiDir = path44.join(os13.homedir(), ".gemini");
20340
20724
  const globalConfigPath = path44.join(geminiDir, "GEMINI.md");
20341
20725
  const templatePath = path44.join(getPackageRoot(), "templates", "global", "GEMINI.md");
20342
- fs40.mkdirSync(geminiDir, { recursive: true });
20343
- const templateContent = fs40.readFileSync(templatePath, "utf-8");
20726
+ fs41.mkdirSync(geminiDir, { recursive: true });
20727
+ const templateContent = fs41.readFileSync(templatePath, "utf-8");
20344
20728
  let existingContent = "";
20345
20729
  let fileExists2 = false;
20346
20730
  try {
20347
- existingContent = fs40.readFileSync(globalConfigPath, "utf-8");
20731
+ existingContent = fs41.readFileSync(globalConfigPath, "utf-8");
20348
20732
  fileExists2 = true;
20349
20733
  } catch (error) {
20350
20734
  if (isNotFoundError(error)) {
@@ -20354,7 +20738,7 @@ async function installGeminiGlobalConfig() {
20354
20738
  }
20355
20739
  }
20356
20740
  if (!fileExists2) {
20357
- fs40.writeFileSync(globalConfigPath, templateContent, "utf-8");
20741
+ fs41.writeFileSync(globalConfigPath, templateContent, "utf-8");
20358
20742
  return { success: true, action: "created" };
20359
20743
  }
20360
20744
  const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
@@ -20364,7 +20748,7 @@ async function installGeminiGlobalConfig() {
20364
20748
  const updatedContent2 = `${existingContent}
20365
20749
 
20366
20750
  ${templateContent}`;
20367
- fs40.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
20751
+ fs41.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
20368
20752
  return { success: true, action: "appended" };
20369
20753
  }
20370
20754
  const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
@@ -20376,7 +20760,7 @@ ${templateContent}`;
20376
20760
  templateContent.indexOf(endMarker) + endMarker.length
20377
20761
  );
20378
20762
  const updatedContent = beforeMarker + prjctSection + afterMarker;
20379
- fs40.writeFileSync(globalConfigPath, updatedContent, "utf-8");
20763
+ fs41.writeFileSync(globalConfigPath, updatedContent, "utf-8");
20380
20764
  return { success: true, action: "updated" };
20381
20765
  } catch (error) {
20382
20766
  console.error(`Gemini config warning: ${error.message}`);
@@ -20389,14 +20773,14 @@ async function installAntigravitySkill() {
20389
20773
  const prjctSkillDir = path44.join(antigravitySkillsDir, "prjct");
20390
20774
  const skillMdPath = path44.join(prjctSkillDir, "SKILL.md");
20391
20775
  const templatePath = path44.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
20392
- fs40.mkdirSync(prjctSkillDir, { recursive: true });
20393
- const fileExists2 = fs40.existsSync(skillMdPath);
20394
- if (!fs40.existsSync(templatePath)) {
20776
+ fs41.mkdirSync(prjctSkillDir, { recursive: true });
20777
+ const fileExists2 = fs41.existsSync(skillMdPath);
20778
+ if (!fs41.existsSync(templatePath)) {
20395
20779
  console.error("Antigravity SKILL.md template not found");
20396
20780
  return { success: false, action: null };
20397
20781
  }
20398
- const templateContent = fs40.readFileSync(templatePath, "utf-8");
20399
- fs40.writeFileSync(skillMdPath, templateContent, "utf-8");
20782
+ const templateContent = fs41.readFileSync(templatePath, "utf-8");
20783
+ fs41.writeFileSync(skillMdPath, templateContent, "utf-8");
20400
20784
  return { success: true, action: fileExists2 ? "updated" : "created" };
20401
20785
  } catch (error) {
20402
20786
  console.error(`Antigravity skill warning: ${error.message}`);
@@ -20421,18 +20805,18 @@ async function installCursorProject(projectRoot) {
20421
20805
  const routerMdcDest = path44.join(rulesDir, "prjct.mdc");
20422
20806
  const routerMdcSource = path44.join(getPackageRoot(), "templates", "cursor", "router.mdc");
20423
20807
  const cursorCommandsSource = path44.join(getPackageRoot(), "templates", "cursor", "commands");
20424
- fs40.mkdirSync(rulesDir, { recursive: true });
20425
- fs40.mkdirSync(commandsDir, { recursive: true });
20426
- if (fs40.existsSync(routerMdcSource)) {
20427
- fs40.copyFileSync(routerMdcSource, routerMdcDest);
20808
+ fs41.mkdirSync(rulesDir, { recursive: true });
20809
+ fs41.mkdirSync(commandsDir, { recursive: true });
20810
+ if (fs41.existsSync(routerMdcSource)) {
20811
+ fs41.copyFileSync(routerMdcSource, routerMdcDest);
20428
20812
  result.rulesCreated = true;
20429
20813
  }
20430
- if (fs40.existsSync(cursorCommandsSource)) {
20431
- const commandFiles = fs40.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
20814
+ if (fs41.existsSync(cursorCommandsSource)) {
20815
+ const commandFiles = fs41.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
20432
20816
  for (const file of commandFiles) {
20433
20817
  const src = path44.join(cursorCommandsSource, file);
20434
20818
  const dest = path44.join(commandsDir, file);
20435
- fs40.copyFileSync(src, dest);
20819
+ fs41.copyFileSync(src, dest);
20436
20820
  }
20437
20821
  result.commandsCreated = commandFiles.length > 0;
20438
20822
  }
@@ -20461,7 +20845,7 @@ async function addCursorToGitignore(projectRoot) {
20461
20845
  let content = "";
20462
20846
  let fileExists2 = false;
20463
20847
  try {
20464
- content = fs40.readFileSync(gitignorePath, "utf-8");
20848
+ content = fs41.readFileSync(gitignorePath, "utf-8");
20465
20849
  fileExists2 = true;
20466
20850
  } catch (error) {
20467
20851
  if (!isNotFoundError(error)) {
@@ -20476,7 +20860,7 @@ async function addCursorToGitignore(projectRoot) {
20476
20860
  ${entriesToAdd.join("\n")}
20477
20861
  ` : `${entriesToAdd.join("\n")}
20478
20862
  `;
20479
- fs40.writeFileSync(gitignorePath, newContent, "utf-8");
20863
+ fs41.writeFileSync(gitignorePath, newContent, "utf-8");
20480
20864
  return true;
20481
20865
  } catch (error) {
20482
20866
  console.error(`Gitignore update warning: ${error.message}`);
@@ -20484,12 +20868,12 @@ ${entriesToAdd.join("\n")}
20484
20868
  }
20485
20869
  }
20486
20870
  function hasCursorProject(projectRoot) {
20487
- return fs40.existsSync(path44.join(projectRoot, ".cursor"));
20871
+ return fs41.existsSync(path44.join(projectRoot, ".cursor"));
20488
20872
  }
20489
20873
  function needsCursorRegeneration(projectRoot) {
20490
20874
  const cursorDir = path44.join(projectRoot, ".cursor");
20491
20875
  const routerPath = path44.join(cursorDir, "rules", "prjct.mdc");
20492
- return fs40.existsSync(cursorDir) && !fs40.existsSync(routerPath);
20876
+ return fs41.existsSync(cursorDir) && !fs41.existsSync(routerPath);
20493
20877
  }
20494
20878
  async function installWindsurfProject(projectRoot) {
20495
20879
  const result = {
@@ -20510,18 +20894,18 @@ async function installWindsurfProject(projectRoot) {
20510
20894
  "windsurf",
20511
20895
  "workflows"
20512
20896
  );
20513
- fs40.mkdirSync(rulesDir, { recursive: true });
20514
- fs40.mkdirSync(workflowsDir, { recursive: true });
20515
- if (fs40.existsSync(routerSource)) {
20516
- fs40.copyFileSync(routerSource, routerDest);
20897
+ fs41.mkdirSync(rulesDir, { recursive: true });
20898
+ fs41.mkdirSync(workflowsDir, { recursive: true });
20899
+ if (fs41.existsSync(routerSource)) {
20900
+ fs41.copyFileSync(routerSource, routerDest);
20517
20901
  result.rulesCreated = true;
20518
20902
  }
20519
- if (fs40.existsSync(windsurfWorkflowsSource)) {
20520
- const workflowFiles = fs40.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
20903
+ if (fs41.existsSync(windsurfWorkflowsSource)) {
20904
+ const workflowFiles = fs41.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
20521
20905
  for (const file of workflowFiles) {
20522
20906
  const src = path44.join(windsurfWorkflowsSource, file);
20523
20907
  const dest = path44.join(workflowsDir, file);
20524
- fs40.copyFileSync(src, dest);
20908
+ fs41.copyFileSync(src, dest);
20525
20909
  }
20526
20910
  result.workflowsCreated = workflowFiles.length > 0;
20527
20911
  }
@@ -20550,7 +20934,7 @@ async function addWindsurfToGitignore(projectRoot) {
20550
20934
  let content = "";
20551
20935
  let fileExists2 = false;
20552
20936
  try {
20553
- content = fs40.readFileSync(gitignorePath, "utf-8");
20937
+ content = fs41.readFileSync(gitignorePath, "utf-8");
20554
20938
  fileExists2 = true;
20555
20939
  } catch (error) {
20556
20940
  if (!isNotFoundError(error)) {
@@ -20565,7 +20949,7 @@ async function addWindsurfToGitignore(projectRoot) {
20565
20949
  ${entriesToAdd.join("\n")}
20566
20950
  ` : `${entriesToAdd.join("\n")}
20567
20951
  `;
20568
- fs40.writeFileSync(gitignorePath, newContent, "utf-8");
20952
+ fs41.writeFileSync(gitignorePath, newContent, "utf-8");
20569
20953
  return true;
20570
20954
  } catch (error) {
20571
20955
  console.error(`Gitignore update warning: ${error.message}`);
@@ -20573,32 +20957,32 @@ ${entriesToAdd.join("\n")}
20573
20957
  }
20574
20958
  }
20575
20959
  function hasWindsurfProject(projectRoot) {
20576
- return fs40.existsSync(path44.join(projectRoot, ".windsurf"));
20960
+ return fs41.existsSync(path44.join(projectRoot, ".windsurf"));
20577
20961
  }
20578
20962
  function needsWindsurfRegeneration(projectRoot) {
20579
20963
  const windsurfDir = path44.join(projectRoot, ".windsurf");
20580
20964
  const routerPath = path44.join(windsurfDir, "rules", "prjct.md");
20581
- return fs40.existsSync(windsurfDir) && !fs40.existsSync(routerPath);
20965
+ return fs41.existsSync(windsurfDir) && !fs41.existsSync(routerPath);
20582
20966
  }
20583
20967
  async function migrateProjectsCliVersion() {
20584
20968
  try {
20585
20969
  const projectsDir = path44.join(os13.homedir(), ".prjct-cli", "projects");
20586
- if (!fs40.existsSync(projectsDir)) {
20970
+ if (!fs41.existsSync(projectsDir)) {
20587
20971
  return;
20588
20972
  }
20589
- const projectDirs = fs40.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
20973
+ const projectDirs = fs41.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
20590
20974
  let migrated = 0;
20591
20975
  for (const projectId of projectDirs) {
20592
20976
  const projectJsonPath = path44.join(projectsDir, projectId, "project.json");
20593
- if (!fs40.existsSync(projectJsonPath)) {
20977
+ if (!fs41.existsSync(projectJsonPath)) {
20594
20978
  continue;
20595
20979
  }
20596
20980
  try {
20597
- const content = fs40.readFileSync(projectJsonPath, "utf8");
20981
+ const content = fs41.readFileSync(projectJsonPath, "utf8");
20598
20982
  const project = JSON.parse(content);
20599
20983
  if (project.cliVersion !== VERSION) {
20600
20984
  project.cliVersion = VERSION;
20601
- fs40.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
20985
+ fs41.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
20602
20986
  migrated++;
20603
20987
  }
20604
20988
  } catch (error) {
@@ -20618,9 +21002,9 @@ async function migrateProjectsCliVersion() {
20618
21002
  }
20619
21003
  function ensureStatusLineSettings(settingsPath, statusLinePath) {
20620
21004
  let settings = {};
20621
- if (fs40.existsSync(settingsPath)) {
21005
+ if (fs41.existsSync(settingsPath)) {
20622
21006
  try {
20623
- settings = JSON.parse(fs40.readFileSync(settingsPath, "utf8"));
21007
+ settings = JSON.parse(fs41.readFileSync(settingsPath, "utf8"));
20624
21008
  } catch (error) {
20625
21009
  if (!(error instanceof SyntaxError)) {
20626
21010
  throw error;
@@ -20628,7 +21012,7 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
20628
21012
  }
20629
21013
  }
20630
21014
  settings.statusLine = { type: "command", command: statusLinePath };
20631
- fs40.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
21015
+ fs41.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
20632
21016
  }
20633
21017
  async function installStatusLine() {
20634
21018
  try {
@@ -20647,23 +21031,23 @@ async function installStatusLine() {
20647
21031
  const sourceLibDir = path44.join(assetsDir, "lib");
20648
21032
  const sourceComponentsDir = path44.join(assetsDir, "components");
20649
21033
  const sourceConfigPath = path44.join(assetsDir, "default-config.json");
20650
- if (!fs40.existsSync(claudeDir)) {
20651
- fs40.mkdirSync(claudeDir, { recursive: true });
21034
+ if (!fs41.existsSync(claudeDir)) {
21035
+ fs41.mkdirSync(claudeDir, { recursive: true });
20652
21036
  }
20653
- if (!fs40.existsSync(prjctStatusLineDir)) {
20654
- fs40.mkdirSync(prjctStatusLineDir, { recursive: true });
21037
+ if (!fs41.existsSync(prjctStatusLineDir)) {
21038
+ fs41.mkdirSync(prjctStatusLineDir, { recursive: true });
20655
21039
  }
20656
- if (!fs40.existsSync(prjctThemesDir)) {
20657
- fs40.mkdirSync(prjctThemesDir, { recursive: true });
21040
+ if (!fs41.existsSync(prjctThemesDir)) {
21041
+ fs41.mkdirSync(prjctThemesDir, { recursive: true });
20658
21042
  }
20659
- if (!fs40.existsSync(prjctLibDir)) {
20660
- fs40.mkdirSync(prjctLibDir, { recursive: true });
21043
+ if (!fs41.existsSync(prjctLibDir)) {
21044
+ fs41.mkdirSync(prjctLibDir, { recursive: true });
20661
21045
  }
20662
- if (!fs40.existsSync(prjctComponentsDir)) {
20663
- fs40.mkdirSync(prjctComponentsDir, { recursive: true });
21046
+ if (!fs41.existsSync(prjctComponentsDir)) {
21047
+ fs41.mkdirSync(prjctComponentsDir, { recursive: true });
20664
21048
  }
20665
- if (fs40.existsSync(prjctStatusLinePath)) {
20666
- const existingContent = fs40.readFileSync(prjctStatusLinePath, "utf8");
21049
+ if (fs41.existsSync(prjctStatusLinePath)) {
21050
+ const existingContent = fs41.readFileSync(prjctStatusLinePath, "utf8");
20667
21051
  if (existingContent.includes("CLI_VERSION=")) {
20668
21052
  const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
20669
21053
  if (versionMatch && versionMatch[1] !== VERSION) {
@@ -20671,7 +21055,7 @@ async function installStatusLine() {
20671
21055
  /CLI_VERSION="[^"]*"/,
20672
21056
  `CLI_VERSION="${VERSION}"`
20673
21057
  );
20674
- fs40.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
21058
+ fs41.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
20675
21059
  }
20676
21060
  installStatusLineModules(sourceLibDir, prjctLibDir);
20677
21061
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
@@ -20680,22 +21064,22 @@ async function installStatusLine() {
20680
21064
  return;
20681
21065
  }
20682
21066
  }
20683
- if (fs40.existsSync(sourceScript)) {
20684
- let scriptContent = fs40.readFileSync(sourceScript, "utf8");
21067
+ if (fs41.existsSync(sourceScript)) {
21068
+ let scriptContent = fs41.readFileSync(sourceScript, "utf8");
20685
21069
  scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
20686
- fs40.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
21070
+ fs41.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
20687
21071
  installStatusLineModules(sourceLibDir, prjctLibDir);
20688
21072
  installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
20689
- if (fs40.existsSync(sourceThemeDir)) {
20690
- const themes = fs40.readdirSync(sourceThemeDir);
21073
+ if (fs41.existsSync(sourceThemeDir)) {
21074
+ const themes = fs41.readdirSync(sourceThemeDir);
20691
21075
  for (const theme of themes) {
20692
21076
  const src = path44.join(sourceThemeDir, theme);
20693
21077
  const dest = path44.join(prjctThemesDir, theme);
20694
- fs40.copyFileSync(src, dest);
21078
+ fs41.copyFileSync(src, dest);
20695
21079
  }
20696
21080
  }
20697
- if (!fs40.existsSync(prjctConfigPath) && fs40.existsSync(sourceConfigPath)) {
20698
- fs40.copyFileSync(sourceConfigPath, prjctConfigPath);
21081
+ if (!fs41.existsSync(prjctConfigPath) && fs41.existsSync(sourceConfigPath)) {
21082
+ fs41.copyFileSync(sourceConfigPath, prjctConfigPath);
20699
21083
  }
20700
21084
  } else {
20701
21085
  const scriptContent = `#!/bin/bash
@@ -20730,7 +21114,7 @@ if [ -f "$CONFIG" ]; then
20730
21114
  fi
20731
21115
  echo "prjct"
20732
21116
  `;
20733
- fs40.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
21117
+ fs41.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
20734
21118
  }
20735
21119
  ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
20736
21120
  ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
@@ -20741,37 +21125,37 @@ echo "prjct"
20741
21125
  }
20742
21126
  }
20743
21127
  function installStatusLineModules(sourceDir, destDir) {
20744
- if (!fs40.existsSync(sourceDir)) {
21128
+ if (!fs41.existsSync(sourceDir)) {
20745
21129
  return;
20746
21130
  }
20747
- const files = fs40.readdirSync(sourceDir);
21131
+ const files = fs41.readdirSync(sourceDir);
20748
21132
  for (const file of files) {
20749
21133
  if (file.endsWith(".sh")) {
20750
21134
  const src = path44.join(sourceDir, file);
20751
21135
  const dest = path44.join(destDir, file);
20752
- fs40.copyFileSync(src, dest);
20753
- fs40.chmodSync(dest, 493);
21136
+ fs41.copyFileSync(src, dest);
21137
+ fs41.chmodSync(dest, 493);
20754
21138
  }
20755
21139
  }
20756
21140
  }
20757
21141
  function ensureStatusLineSymlink(linkPath, targetPath) {
20758
21142
  try {
20759
- if (fs40.existsSync(linkPath)) {
20760
- const stats = fs40.lstatSync(linkPath);
21143
+ if (fs41.existsSync(linkPath)) {
21144
+ const stats = fs41.lstatSync(linkPath);
20761
21145
  if (stats.isSymbolicLink()) {
20762
- const existingTarget = fs40.readlinkSync(linkPath);
21146
+ const existingTarget = fs41.readlinkSync(linkPath);
20763
21147
  if (existingTarget === targetPath) {
20764
21148
  return;
20765
21149
  }
20766
21150
  }
20767
- fs40.unlinkSync(linkPath);
21151
+ fs41.unlinkSync(linkPath);
20768
21152
  }
20769
- fs40.symlinkSync(targetPath, linkPath);
21153
+ fs41.symlinkSync(targetPath, linkPath);
20770
21154
  } catch (_error) {
20771
21155
  try {
20772
- if (fs40.existsSync(targetPath)) {
20773
- fs40.copyFileSync(targetPath, linkPath);
20774
- fs40.chmodSync(linkPath, 493);
21156
+ if (fs41.existsSync(targetPath)) {
21157
+ fs41.copyFileSync(targetPath, linkPath);
21158
+ fs41.chmodSync(linkPath, 493);
20775
21159
  }
20776
21160
  } catch (copyError) {
20777
21161
  if (!isNotFoundError(copyError)) {
@@ -21455,7 +21839,7 @@ ${"\u2550".repeat(50)}
21455
21839
  });
21456
21840
 
21457
21841
  // core/commands/context.ts
21458
- import fs41 from "node:fs/promises";
21842
+ import fs42 from "node:fs/promises";
21459
21843
  import path46 from "node:path";
21460
21844
  var ContextCommands, contextCommands;
21461
21845
  var init_context = __esm({
@@ -21583,7 +21967,7 @@ var init_context = __esm({
21583
21967
  async loadRepoAnalysis(globalPath) {
21584
21968
  try {
21585
21969
  const analysisPath = path46.join(globalPath, "analysis", "repo-analysis.json");
21586
- const content = await fs41.readFile(analysisPath, "utf-8");
21970
+ const content = await fs42.readFile(analysisPath, "utf-8");
21587
21971
  const data = JSON.parse(content);
21588
21972
  return {
21589
21973
  ecosystem: data.ecosystem || "unknown",
@@ -22079,9 +22463,9 @@ var init_maintenance = __esm({
22079
22463
  });
22080
22464
 
22081
22465
  // core/commands/setup.ts
22082
- import fs42 from "node:fs";
22466
+ import fs43 from "node:fs";
22083
22467
  import path50 from "node:path";
22084
- import chalk10 from "chalk";
22468
+ import chalk11 from "chalk";
22085
22469
  var SetupCommands;
22086
22470
  var init_setup2 = __esm({
22087
22471
  "core/commands/setup.ts"() {
@@ -22265,11 +22649,11 @@ fi
22265
22649
  # Default: show prjct branding
22266
22650
  echo "\u26A1 prjct"
22267
22651
  `;
22268
- fs42.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
22652
+ fs43.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
22269
22653
  let settings = {};
22270
- if (fs42.existsSync(settingsPath)) {
22654
+ if (fs43.existsSync(settingsPath)) {
22271
22655
  try {
22272
- settings = JSON.parse(fs42.readFileSync(settingsPath, "utf8"));
22656
+ settings = JSON.parse(fs43.readFileSync(settingsPath, "utf8"));
22273
22657
  } catch (_error) {
22274
22658
  }
22275
22659
  }
@@ -22277,7 +22661,7 @@ echo "\u26A1 prjct"
22277
22661
  type: "command",
22278
22662
  command: statusLinePath
22279
22663
  };
22280
- fs42.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
22664
+ fs43.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
22281
22665
  return { success: true };
22282
22666
  } catch (error) {
22283
22667
  return { success: false, error: error.message };
@@ -22287,45 +22671,45 @@ echo "\u26A1 prjct"
22287
22671
  * Show beautiful ASCII art with quick start
22288
22672
  */
22289
22673
  showAsciiArt() {
22290
- console.log(chalk10.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
22674
+ console.log(chalk11.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
22291
22675
  console.log("");
22292
- console.log(chalk10.bold.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"));
22293
- console.log(chalk10.bold.cyan(" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D"));
22294
- console.log(chalk10.bold.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"));
22295
- console.log(chalk10.bold.cyan(" \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"));
22296
- console.log(chalk10.bold.cyan(" \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551"));
22297
- console.log(chalk10.bold.cyan(" \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D"));
22676
+ console.log(chalk11.bold.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"));
22677
+ console.log(chalk11.bold.cyan(" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D"));
22678
+ console.log(chalk11.bold.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"));
22679
+ console.log(chalk11.bold.cyan(" \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"));
22680
+ console.log(chalk11.bold.cyan(" \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551"));
22681
+ console.log(chalk11.bold.cyan(" \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D"));
22298
22682
  console.log("");
22299
22683
  console.log(
22300
- ` ${chalk10.bold.cyan("prjct")}${chalk10.magenta("/")}${chalk10.green("cli")} ${chalk10.dim.white(`v${VERSION} installed`)}`
22684
+ ` ${chalk11.bold.cyan("prjct")}${chalk11.magenta("/")}${chalk11.green("cli")} ${chalk11.dim.white(`v${VERSION} installed`)}`
22301
22685
  );
22302
22686
  console.log("");
22303
- console.log(` ${chalk10.yellow("\u26A1")} Ship faster with zero friction`);
22304
- console.log(` ${chalk10.green("\u{1F4DD}")} From idea to technical tasks in minutes`);
22305
- console.log(` ${chalk10.cyan("\u{1F916}")} Perfect context for AI agents`);
22687
+ console.log(` ${chalk11.yellow("\u26A1")} Ship faster with zero friction`);
22688
+ console.log(` ${chalk11.green("\u{1F4DD}")} From idea to technical tasks in minutes`);
22689
+ console.log(` ${chalk11.cyan("\u{1F916}")} Perfect context for AI agents`);
22306
22690
  console.log("");
22307
- console.log(chalk10.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
22691
+ console.log(chalk11.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
22308
22692
  console.log("");
22309
- console.log(chalk10.bold.cyan("\u{1F680} Quick Start"));
22310
- console.log(chalk10.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
22693
+ console.log(chalk11.bold.cyan("\u{1F680} Quick Start"));
22694
+ console.log(chalk11.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
22311
22695
  console.log("");
22312
- console.log(` ${chalk10.bold("1.")} Initialize your project:`);
22313
- console.log(` ${chalk10.green("cd your-project && prjct init")}`);
22696
+ console.log(` ${chalk11.bold("1.")} Initialize your project:`);
22697
+ console.log(` ${chalk11.green("cd your-project && prjct init")}`);
22314
22698
  console.log("");
22315
- console.log(` ${chalk10.bold("2.")} Start your first task:`);
22316
- console.log(` ${chalk10.green('prjct task "build auth"')}`);
22699
+ console.log(` ${chalk11.bold("2.")} Start your first task:`);
22700
+ console.log(` ${chalk11.green('prjct task "build auth"')}`);
22317
22701
  console.log("");
22318
- console.log(` ${chalk10.bold("3.")} Ship & celebrate:`);
22319
- console.log(` ${chalk10.green('prjct ship "user login"')}`);
22702
+ console.log(` ${chalk11.bold("3.")} Ship & celebrate:`);
22703
+ console.log(` ${chalk11.green('prjct ship "user login"')}`);
22320
22704
  console.log("");
22321
- console.log(chalk10.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
22705
+ console.log(chalk11.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
22322
22706
  console.log("");
22323
- console.log(` ${chalk10.dim("Documentation:")} ${chalk10.cyan("https://prjct.app")}`);
22707
+ console.log(` ${chalk11.dim("Documentation:")} ${chalk11.cyan("https://prjct.app")}`);
22324
22708
  console.log(
22325
- ` ${chalk10.dim("Report issues:")} ${chalk10.cyan("https://github.com/jlopezlira/prjct-cli/issues")}`
22709
+ ` ${chalk11.dim("Report issues:")} ${chalk11.cyan("https://github.com/jlopezlira/prjct-cli/issues")}`
22326
22710
  );
22327
22711
  console.log("");
22328
- console.log(chalk10.bold.magenta("Happy shipping! \u{1F680}"));
22712
+ console.log(chalk11.bold.magenta("Happy shipping! \u{1F680}"));
22329
22713
  console.log("");
22330
22714
  }
22331
22715
  };
@@ -23635,7 +24019,7 @@ var init_linear = __esm({
23635
24019
  });
23636
24020
 
23637
24021
  // core/utils/project-credentials.ts
23638
- import fs43 from "node:fs";
24022
+ import fs44 from "node:fs";
23639
24023
  import os14 from "node:os";
23640
24024
  import path53 from "node:path";
23641
24025
  function getCredentialsPath(projectId) {
@@ -23643,11 +24027,11 @@ function getCredentialsPath(projectId) {
23643
24027
  }
23644
24028
  async function getProjectCredentials(projectId) {
23645
24029
  const credPath = getCredentialsPath(projectId);
23646
- if (!fs43.existsSync(credPath)) {
24030
+ if (!fs44.existsSync(credPath)) {
23647
24031
  return {};
23648
24032
  }
23649
24033
  try {
23650
- return JSON.parse(fs43.readFileSync(credPath, "utf-8"));
24034
+ return JSON.parse(fs44.readFileSync(credPath, "utf-8"));
23651
24035
  } catch (error) {
23652
24036
  console.error("[project-credentials] Failed to read credentials:", error.message);
23653
24037
  return {};
@@ -24220,7 +24604,7 @@ var require_package = __commonJS({
24220
24604
  "package.json"(exports, module) {
24221
24605
  module.exports = {
24222
24606
  name: "prjct-cli",
24223
- version: "0.49.0",
24607
+ version: "0.51.0",
24224
24608
  description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
24225
24609
  main: "core/index.ts",
24226
24610
  bin: {
@@ -24325,7 +24709,7 @@ var require_package = __commonJS({
24325
24709
 
24326
24710
  // core/index.ts
24327
24711
  var core_exports = {};
24328
- import fs44 from "node:fs";
24712
+ import fs45 from "node:fs";
24329
24713
  import os15 from "node:os";
24330
24714
  import path54 from "node:path";
24331
24715
  async function main() {
@@ -24454,10 +24838,10 @@ function displayVersion(version) {
24454
24838
  const detection = detectAllProviders();
24455
24839
  const claudeCommandPath = path54.join(os15.homedir(), ".claude", "commands", "p.md");
24456
24840
  const geminiCommandPath = path54.join(os15.homedir(), ".gemini", "commands", "p.toml");
24457
- const claudeConfigured = fs44.existsSync(claudeCommandPath);
24458
- const geminiConfigured = fs44.existsSync(geminiCommandPath);
24459
- const cursorConfigured = fs44.existsSync(path54.join(process.cwd(), ".cursor", "commands", "sync.md"));
24460
- const cursorExists = fs44.existsSync(path54.join(process.cwd(), ".cursor"));
24841
+ const claudeConfigured = fs45.existsSync(claudeCommandPath);
24842
+ const geminiConfigured = fs45.existsSync(geminiCommandPath);
24843
+ const cursorConfigured = fs45.existsSync(path54.join(process.cwd(), ".cursor", "commands", "sync.md"));
24844
+ const cursorExists = fs45.existsSync(path54.join(process.cwd(), ".cursor"));
24461
24845
  console.log(`
24462
24846
  ${CYAN3}p/${RESET5} prjct v${version}
24463
24847
  ${DIM6}Context layer for AI coding agents${RESET5}
@@ -24590,7 +24974,7 @@ var init_core = __esm({
24590
24974
  init_ai_provider();
24591
24975
  init_config_manager();
24592
24976
  init_editors_config();
24593
- import fs45 from "node:fs";
24977
+ import fs46 from "node:fs";
24594
24978
  import os16 from "node:os";
24595
24979
  import path55 from "node:path";
24596
24980
 
@@ -25335,13 +25719,13 @@ function checkRoutersInstalled() {
25335
25719
  const detection = detectAllProviders();
25336
25720
  if (detection.claude.installed) {
25337
25721
  const claudeRouter = path55.join(home, ".claude", "commands", "p.md");
25338
- if (!fs45.existsSync(claudeRouter)) {
25722
+ if (!fs46.existsSync(claudeRouter)) {
25339
25723
  return false;
25340
25724
  }
25341
25725
  }
25342
25726
  if (detection.gemini.installed) {
25343
25727
  const geminiRouter = path55.join(home, ".gemini", "commands", "p.toml");
25344
- if (!fs45.existsSync(geminiRouter)) {
25728
+ if (!fs46.existsSync(geminiRouter)) {
25345
25729
  return false;
25346
25730
  }
25347
25731
  }
@@ -25461,12 +25845,12 @@ if (args[0] === "start" || args[0] === "setup") {
25461
25845
  const detection = detectAllProviders();
25462
25846
  const home = os16.homedir();
25463
25847
  const cwd = process.cwd();
25464
- const claudeConfigured = fs45.existsSync(path55.join(home, ".claude", "commands", "p.md"));
25465
- const geminiConfigured = fs45.existsSync(path55.join(home, ".gemini", "commands", "p.toml"));
25466
- const cursorDetected = fs45.existsSync(path55.join(cwd, ".cursor"));
25467
- const cursorConfigured = fs45.existsSync(path55.join(cwd, ".cursor", "rules", "prjct.mdc"));
25468
- const windsurfDetected = fs45.existsSync(path55.join(cwd, ".windsurf"));
25469
- const windsurfConfigured = fs45.existsSync(path55.join(cwd, ".windsurf", "rules", "prjct.md"));
25848
+ const claudeConfigured = fs46.existsSync(path55.join(home, ".claude", "commands", "p.md"));
25849
+ const geminiConfigured = fs46.existsSync(path55.join(home, ".gemini", "commands", "p.toml"));
25850
+ const cursorDetected = fs46.existsSync(path55.join(cwd, ".cursor"));
25851
+ const cursorConfigured = fs46.existsSync(path55.join(cwd, ".cursor", "rules", "prjct.mdc"));
25852
+ const windsurfDetected = fs46.existsSync(path55.join(cwd, ".windsurf"));
25853
+ const windsurfConfigured = fs46.existsSync(path55.join(cwd, ".windsurf", "rules", "prjct.md"));
25470
25854
  const GREEN7 = "\x1B[32m";
25471
25855
  console.log(`
25472
25856
  ${CYAN4}p/${RESET6} prjct v${VERSION}
@@ -25507,7 +25891,7 @@ ${CYAN4}https://prjct.app${RESET6}
25507
25891
  } else {
25508
25892
  const configPath = path55.join(os16.homedir(), ".prjct-cli", "config", "installed-editors.json");
25509
25893
  const routersInstalled = checkRoutersInstalled();
25510
- if (!fs45.existsSync(configPath) || !routersInstalled) {
25894
+ if (!fs46.existsSync(configPath) || !routersInstalled) {
25511
25895
  console.log(`
25512
25896
  ${CYAN4}${BOLD4} Welcome to prjct!${RESET6}
25513
25897