prjct-cli 1.16.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,10 +16,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
16
16
  if (typeof require !== "undefined") return require.apply(this, arguments);
17
17
  throw Error('Dynamic require of "' + x + '" is not supported');
18
18
  });
19
- var __glob = (map) => (path70) => {
20
- var fn = map[path70];
19
+ var __glob = (map) => (path73) => {
20
+ var fn = map[path73];
21
21
  if (fn) return fn();
22
- throw new Error("Module not found in bundle: " + path70);
22
+ throw new Error("Module not found in bundle: " + path73);
23
23
  };
24
24
  var __esm = (fn, res) => function __init() {
25
25
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -4051,7 +4051,7 @@ var init_cache = __esm({
4051
4051
  import { Database } from "bun:sqlite";
4052
4052
  import fs15 from "node:fs";
4053
4053
  import path14 from "node:path";
4054
- var migrations, PrjctDatabase, prjctDb;
4054
+ var migrations, PrjctDatabase, prjctDb, database_default;
4055
4055
  var init_database = __esm({
4056
4056
  "core/storage/database.ts"() {
4057
4057
  "use strict";
@@ -4482,6 +4482,7 @@ var init_database = __esm({
4482
4482
  }
4483
4483
  };
4484
4484
  prjctDb = new PrjctDatabase();
4485
+ database_default = prjctDb;
4485
4486
  }
4486
4487
  });
4487
4488
 
@@ -6575,11 +6576,11 @@ async function runSignaturesTool(args2, projectPath) {
6575
6576
  }
6576
6577
  };
6577
6578
  }
6578
- const fs58 = await import("node:fs/promises");
6579
- const path70 = await import("node:path");
6580
- const fullPath = path70.isAbsolute(filePath) ? filePath : path70.join(projectPath, filePath);
6579
+ const fs61 = await import("node:fs/promises");
6580
+ const path73 = await import("node:path");
6581
+ const fullPath = path73.isAbsolute(filePath) ? filePath : path73.join(projectPath, filePath);
6581
6582
  try {
6582
- const stat = await fs58.stat(fullPath);
6583
+ const stat = await fs61.stat(fullPath);
6583
6584
  if (stat.isDirectory()) {
6584
6585
  const results = await extractDirectorySignatures(filePath, projectPath, {
6585
6586
  recursive: args2.includes("--recursive") || args2.includes("-r")
@@ -6646,11 +6647,11 @@ async function runSummaryTool(args2, projectPath) {
6646
6647
  }
6647
6648
  };
6648
6649
  }
6649
- const fs58 = await import("node:fs/promises");
6650
- const path70 = await import("node:path");
6651
- const fullPath = path70.isAbsolute(targetPath) ? targetPath : path70.join(projectPath, targetPath);
6650
+ const fs61 = await import("node:fs/promises");
6651
+ const path73 = await import("node:path");
6652
+ const fullPath = path73.isAbsolute(targetPath) ? targetPath : path73.join(projectPath, targetPath);
6652
6653
  try {
6653
- const stat = await fs58.stat(fullPath);
6654
+ const stat = await fs61.stat(fullPath);
6654
6655
  if (stat.isDirectory()) {
6655
6656
  const results = await summarizeDirectory(targetPath, projectPath, {
6656
6657
  recursive: args2.includes("--recursive") || args2.includes("-r")
@@ -21767,16 +21768,16 @@ var init_onboarding = __esm({
21767
21768
  * Detect project type from file system
21768
21769
  */
21769
21770
  async detectProjectType() {
21770
- const fs58 = await import("node:fs/promises");
21771
- const path70 = await import("node:path");
21771
+ const fs61 = await import("node:fs/promises");
21772
+ const path73 = await import("node:path");
21772
21773
  try {
21773
- const files = await fs58.readdir(this.projectPath);
21774
+ const files = await fs61.readdir(this.projectPath);
21774
21775
  if (files.includes("turbo.json") || files.includes("lerna.json") || files.includes("nx.json")) {
21775
21776
  return "monorepo";
21776
21777
  }
21777
21778
  if (files.includes("package.json")) {
21778
- const pkgPath = path70.join(this.projectPath, "package.json");
21779
- const pkgContent = await fs58.readFile(pkgPath, "utf-8");
21779
+ const pkgPath = path73.join(this.projectPath, "package.json");
21780
+ const pkgContent = await fs61.readFile(pkgPath, "utf-8");
21780
21781
  const pkg = JSON.parse(pkgContent);
21781
21782
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
21782
21783
  if (pkg.bin) return "cli-tool";
@@ -21812,32 +21813,32 @@ var init_onboarding = __esm({
21812
21813
  * Detect installed AI agents from config files
21813
21814
  */
21814
21815
  async detectInstalledAgents() {
21815
- const fs58 = await import("node:fs/promises");
21816
- const path70 = await import("node:path");
21816
+ const fs61 = await import("node:fs/promises");
21817
+ const path73 = await import("node:path");
21817
21818
  const os22 = await import("node:os");
21818
21819
  const agents = [];
21819
21820
  try {
21820
- await fs58.access(path70.join(os22.homedir(), ".claude"));
21821
+ await fs61.access(path73.join(os22.homedir(), ".claude"));
21821
21822
  agents.push("claude");
21822
21823
  } catch {
21823
21824
  }
21824
21825
  try {
21825
- await fs58.access(path70.join(this.projectPath, ".cursorrules"));
21826
+ await fs61.access(path73.join(this.projectPath, ".cursorrules"));
21826
21827
  agents.push("cursor");
21827
21828
  } catch {
21828
21829
  }
21829
21830
  try {
21830
- await fs58.access(path70.join(this.projectPath, ".windsurfrules"));
21831
+ await fs61.access(path73.join(this.projectPath, ".windsurfrules"));
21831
21832
  agents.push("windsurf");
21832
21833
  } catch {
21833
21834
  }
21834
21835
  try {
21835
- await fs58.access(path70.join(this.projectPath, ".github", "copilot-instructions.md"));
21836
+ await fs61.access(path73.join(this.projectPath, ".github", "copilot-instructions.md"));
21836
21837
  agents.push("copilot");
21837
21838
  } catch {
21838
21839
  }
21839
21840
  try {
21840
- await fs58.access(path70.join(os22.homedir(), ".gemini"));
21841
+ await fs61.access(path73.join(os22.homedir(), ".gemini"));
21841
21842
  agents.push("gemini");
21842
21843
  } catch {
21843
21844
  }
@@ -21847,17 +21848,17 @@ var init_onboarding = __esm({
21847
21848
  * Detect tech stack from project files
21848
21849
  */
21849
21850
  async detectStack() {
21850
- const fs58 = await import("node:fs/promises");
21851
- const path70 = await import("node:path");
21851
+ const fs61 = await import("node:fs/promises");
21852
+ const path73 = await import("node:path");
21852
21853
  const stack = {
21853
21854
  language: "Unknown",
21854
21855
  technologies: []
21855
21856
  };
21856
21857
  try {
21857
- const files = await fs58.readdir(this.projectPath);
21858
+ const files = await fs61.readdir(this.projectPath);
21858
21859
  if (files.includes("package.json")) {
21859
- const pkgPath = path70.join(this.projectPath, "package.json");
21860
- const pkgContent = await fs58.readFile(pkgPath, "utf-8");
21860
+ const pkgPath = path73.join(this.projectPath, "package.json");
21861
+ const pkgContent = await fs61.readFile(pkgPath, "utf-8");
21861
21862
  const pkg = JSON.parse(pkgContent);
21862
21863
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
21863
21864
  stack.language = deps.typescript ? "TypeScript" : "JavaScript";
@@ -22983,7 +22984,10 @@ var init_analysis2 = __esm({
22983
22984
  if (!isNonInteractive) {
22984
22985
  output_default.spin("Analyzing changes...");
22985
22986
  }
22986
- const result2 = await syncService.sync(projectPath, { aiTools: options.aiTools });
22987
+ const result2 = await syncService.sync(projectPath, {
22988
+ aiTools: options.aiTools,
22989
+ full: options.full
22990
+ });
22987
22991
  if (!result2.success) {
22988
22992
  if (isNonInteractive) {
22989
22993
  console.log(JSON.stringify({ success: false, error: result2.error || "Sync failed" }));
@@ -23097,7 +23101,10 @@ ${formatFullDiff(diff)}`);
23097
23101
  return this.showSyncResult(result2, startTime);
23098
23102
  }
23099
23103
  output_default.spin("Syncing project...");
23100
- const result = await syncService.sync(projectPath, { aiTools: options.aiTools });
23104
+ const result = await syncService.sync(projectPath, {
23105
+ aiTools: options.aiTools,
23106
+ full: options.full
23107
+ });
23101
23108
  if (!result.success) {
23102
23109
  output_default.fail(result.error || "Sync failed");
23103
23110
  return { success: false, error: result.error };
@@ -24082,8 +24089,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
24082
24089
  const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
24083
24090
  const specsPath2 = path45.join(globalPath2, "planning", "specs");
24084
24091
  try {
24085
- const fs58 = await import("node:fs/promises");
24086
- const files = await fs58.readdir(specsPath2);
24092
+ const fs61 = await import("node:fs/promises");
24093
+ const files = await fs61.readdir(specsPath2);
24087
24094
  const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
24088
24095
  if (specs.length === 0) {
24089
24096
  output_default.warn("no specs yet");
@@ -25010,9 +25017,765 @@ var init_ai_tools = __esm({
25010
25017
  }
25011
25018
  });
25012
25019
 
25013
- // core/services/context-generator.ts
25020
+ // core/domain/bm25.ts
25014
25021
  import fs46 from "node:fs/promises";
25015
25022
  import path49 from "node:path";
25023
+ function splitIdentifier(identifier) {
25024
+ return identifier.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/[-_./]/g, " ").toLowerCase().split(/\s+/).filter((w) => w.length > 1);
25025
+ }
25026
+ function tokenizeFile(content, filePath) {
25027
+ const tokens = [];
25028
+ const pathParts = filePath.replace(/\.[^.]+$/, "").split(/[/\\]/).filter(Boolean);
25029
+ for (const part of pathParts) {
25030
+ tokens.push(...splitIdentifier(part));
25031
+ }
25032
+ const exportPatterns = [
25033
+ /export\s+(?:async\s+)?function\s+(\w+)/g,
25034
+ /export\s+class\s+(\w+)/g,
25035
+ /export\s+interface\s+(\w+)/g,
25036
+ /export\s+type\s+(\w+)/g,
25037
+ /export\s+(?:const|let|var)\s+(\w+)/g,
25038
+ /export\s+default\s+(?:class|function)\s+(\w+)/g
25039
+ ];
25040
+ for (const pattern of exportPatterns) {
25041
+ let match;
25042
+ while ((match = pattern.exec(content)) !== null) {
25043
+ if (match[1]) {
25044
+ tokens.push(...splitIdentifier(match[1]));
25045
+ }
25046
+ }
25047
+ }
25048
+ const declPatterns = [
25049
+ /(?:async\s+)?function\s+(\w+)/g,
25050
+ /class\s+(\w+)/g,
25051
+ /interface\s+(\w+)/g,
25052
+ /type\s+(\w+)\s*=/g
25053
+ ];
25054
+ for (const pattern of declPatterns) {
25055
+ let match;
25056
+ while ((match = pattern.exec(content)) !== null) {
25057
+ if (match[1]) {
25058
+ tokens.push(...splitIdentifier(match[1]));
25059
+ }
25060
+ }
25061
+ }
25062
+ const importPattern = /(?:from|import)\s+['"]([^'"]+)['"]/g;
25063
+ let importMatch;
25064
+ while ((importMatch = importPattern.exec(content)) !== null) {
25065
+ const source = importMatch[1];
25066
+ if (source.startsWith(".") || source.startsWith("@/")) {
25067
+ tokens.push(...splitIdentifier(source));
25068
+ } else {
25069
+ const pkgName = source.startsWith("@") ? source.split("/").slice(0, 2).join("/") : source.split("/")[0];
25070
+ tokens.push(...splitIdentifier(pkgName));
25071
+ }
25072
+ }
25073
+ const singleLineComments = /\/\/\s*(.+)/g;
25074
+ let commentMatch;
25075
+ while ((commentMatch = singleLineComments.exec(content)) !== null) {
25076
+ const words = commentMatch[1].toLowerCase().split(/\s+/).filter((w) => w.length > 2);
25077
+ tokens.push(...words);
25078
+ }
25079
+ const multiLineComments = /\/\*\*?([\s\S]*?)\*\//g;
25080
+ let multiMatch;
25081
+ while ((multiMatch = multiLineComments.exec(content)) !== null) {
25082
+ const words = multiMatch[1].replace(/@\w+/g, "").replace(/\*/g, "").toLowerCase().split(/\s+/).filter((w) => w.length > 2 && /^[a-z]+$/.test(w));
25083
+ tokens.push(...words);
25084
+ }
25085
+ return tokens.filter((t) => t.length > 1 && !STOP_WORDS.has(t) && /^[a-z][a-z0-9]*$/.test(t));
25086
+ }
25087
+ async function listFiles2(dir, projectPath) {
25088
+ const files = [];
25089
+ const entries = await fs46.readdir(dir, { withFileTypes: true });
25090
+ for (const entry of entries) {
25091
+ if (SKIP_DIRS.has(entry.name)) continue;
25092
+ const fullPath = path49.join(dir, entry.name);
25093
+ if (entry.isDirectory()) {
25094
+ files.push(...await listFiles2(fullPath, projectPath));
25095
+ } else if (entry.isFile()) {
25096
+ const ext = path49.extname(entry.name).toLowerCase();
25097
+ if (INDEXABLE_EXTENSIONS.has(ext)) {
25098
+ files.push(path49.relative(projectPath, fullPath));
25099
+ }
25100
+ }
25101
+ }
25102
+ return files;
25103
+ }
25104
+ async function buildIndex(projectPath) {
25105
+ const files = await listFiles2(projectPath, projectPath);
25106
+ const documents = {};
25107
+ const invertedIndex = {};
25108
+ let totalLength = 0;
25109
+ const BATCH_SIZE = 50;
25110
+ for (let i = 0; i < files.length; i += BATCH_SIZE) {
25111
+ const batch = files.slice(i, i + BATCH_SIZE);
25112
+ const results = await Promise.all(
25113
+ batch.map(async (filePath) => {
25114
+ try {
25115
+ const content = await fs46.readFile(path49.join(projectPath, filePath), "utf-8");
25116
+ const tokens = tokenizeFile(content, filePath);
25117
+ return { filePath, tokens };
25118
+ } catch {
25119
+ return { filePath, tokens: [] };
25120
+ }
25121
+ })
25122
+ );
25123
+ for (const { filePath, tokens } of results) {
25124
+ if (tokens.length === 0) continue;
25125
+ documents[filePath] = { tokens, length: tokens.length };
25126
+ totalLength += tokens.length;
25127
+ const tfMap = /* @__PURE__ */ new Map();
25128
+ for (const token of tokens) {
25129
+ tfMap.set(token, (tfMap.get(token) || 0) + 1);
25130
+ }
25131
+ for (const [token, tf] of tfMap) {
25132
+ if (!invertedIndex[token]) {
25133
+ invertedIndex[token] = [];
25134
+ }
25135
+ invertedIndex[token].push({ path: filePath, tf });
25136
+ }
25137
+ }
25138
+ }
25139
+ const totalDocs = Object.keys(documents).length;
25140
+ return {
25141
+ documents,
25142
+ invertedIndex,
25143
+ avgDocLength: totalDocs > 0 ? totalLength / totalDocs : 0,
25144
+ totalDocs,
25145
+ builtAt: (/* @__PURE__ */ new Date()).toISOString()
25146
+ };
25147
+ }
25148
+ function saveIndex(projectId, index) {
25149
+ const storable = {
25150
+ invertedIndex: index.invertedIndex,
25151
+ avgDocLength: index.avgDocLength,
25152
+ totalDocs: index.totalDocs,
25153
+ builtAt: index.builtAt,
25154
+ // Store document lengths (needed for scoring) but not full token lists
25155
+ docLengths: Object.fromEntries(Object.entries(index.documents).map(([p, d]) => [p, d.length]))
25156
+ };
25157
+ database_default.setDoc(projectId, INDEX_KEY, storable);
25158
+ }
25159
+ async function indexProject(projectPath, projectId) {
25160
+ const index = await buildIndex(projectPath);
25161
+ saveIndex(projectId, index);
25162
+ return index;
25163
+ }
25164
+ var INDEXABLE_EXTENSIONS, STOP_WORDS, SKIP_DIRS, INDEX_KEY;
25165
+ var init_bm25 = __esm({
25166
+ "core/domain/bm25.ts"() {
25167
+ "use strict";
25168
+ init_database();
25169
+ INDEXABLE_EXTENSIONS = /* @__PURE__ */ new Set([
25170
+ ".ts",
25171
+ ".tsx",
25172
+ ".js",
25173
+ ".jsx",
25174
+ ".mjs",
25175
+ ".cjs",
25176
+ ".py",
25177
+ ".go",
25178
+ ".rs",
25179
+ ".java",
25180
+ ".cs",
25181
+ ".rb",
25182
+ ".php",
25183
+ ".vue",
25184
+ ".svelte"
25185
+ ]);
25186
+ STOP_WORDS = /* @__PURE__ */ new Set([
25187
+ "the",
25188
+ "a",
25189
+ "an",
25190
+ "is",
25191
+ "are",
25192
+ "was",
25193
+ "were",
25194
+ "be",
25195
+ "been",
25196
+ "being",
25197
+ "have",
25198
+ "has",
25199
+ "had",
25200
+ "do",
25201
+ "does",
25202
+ "did",
25203
+ "will",
25204
+ "would",
25205
+ "could",
25206
+ "should",
25207
+ "may",
25208
+ "might",
25209
+ "shall",
25210
+ "can",
25211
+ "of",
25212
+ "in",
25213
+ "to",
25214
+ "for",
25215
+ "with",
25216
+ "on",
25217
+ "at",
25218
+ "from",
25219
+ "by",
25220
+ "as",
25221
+ "or",
25222
+ "and",
25223
+ "but",
25224
+ "if",
25225
+ "not",
25226
+ "no",
25227
+ "so",
25228
+ "up",
25229
+ "out",
25230
+ "this",
25231
+ "that",
25232
+ "it",
25233
+ "its",
25234
+ "all",
25235
+ "any",
25236
+ // Code noise
25237
+ "import",
25238
+ "export",
25239
+ "default",
25240
+ "const",
25241
+ "let",
25242
+ "var",
25243
+ "function",
25244
+ "class",
25245
+ "interface",
25246
+ "type",
25247
+ "return",
25248
+ "new",
25249
+ "true",
25250
+ "false",
25251
+ "null",
25252
+ "undefined",
25253
+ "void",
25254
+ "async",
25255
+ "await",
25256
+ "static",
25257
+ "public",
25258
+ "private",
25259
+ "protected",
25260
+ "readonly",
25261
+ "string",
25262
+ "number",
25263
+ "boolean",
25264
+ "object",
25265
+ "array"
25266
+ ]);
25267
+ SKIP_DIRS = /* @__PURE__ */ new Set([
25268
+ "node_modules",
25269
+ ".git",
25270
+ "dist",
25271
+ "build",
25272
+ "out",
25273
+ ".next",
25274
+ "coverage",
25275
+ ".cache",
25276
+ ".turbo",
25277
+ ".vercel",
25278
+ "__pycache__",
25279
+ "vendor",
25280
+ "target"
25281
+ ]);
25282
+ __name(splitIdentifier, "splitIdentifier");
25283
+ __name(tokenizeFile, "tokenizeFile");
25284
+ __name(listFiles2, "listFiles");
25285
+ __name(buildIndex, "buildIndex");
25286
+ INDEX_KEY = "bm25-index";
25287
+ __name(saveIndex, "saveIndex");
25288
+ __name(indexProject, "indexProject");
25289
+ }
25290
+ });
25291
+
25292
+ // core/domain/import-graph.ts
25293
+ import fs47 from "node:fs/promises";
25294
+ import path50 from "node:path";
25295
+ function extractImportSources(content) {
25296
+ const sources = [];
25297
+ let match;
25298
+ const regex = new RegExp(IMPORT_REGEX.source, "g");
25299
+ while ((match = regex.exec(content)) !== null) {
25300
+ const source = match[1];
25301
+ if (source.startsWith(".") || source.startsWith("@/")) {
25302
+ sources.push(source);
25303
+ }
25304
+ }
25305
+ return sources;
25306
+ }
25307
+ async function resolveImport2(source, fromFile, projectPath) {
25308
+ let basePath;
25309
+ if (source.startsWith("@/")) {
25310
+ basePath = path50.join(projectPath, "src", source.slice(2));
25311
+ } else {
25312
+ const fromDir = path50.dirname(path50.join(projectPath, fromFile));
25313
+ basePath = path50.resolve(fromDir, source);
25314
+ }
25315
+ for (const ext of RESOLVE_EXTENSIONS) {
25316
+ const fullPath = basePath + ext;
25317
+ try {
25318
+ const stat = await fs47.stat(fullPath);
25319
+ if (stat.isFile()) {
25320
+ return path50.relative(projectPath, fullPath);
25321
+ }
25322
+ } catch {
25323
+ }
25324
+ }
25325
+ return null;
25326
+ }
25327
+ async function listFiles3(dir, projectPath) {
25328
+ const files = [];
25329
+ const entries = await fs47.readdir(dir, { withFileTypes: true });
25330
+ for (const entry of entries) {
25331
+ if (SKIP_DIRS2.has(entry.name)) continue;
25332
+ const fullPath = path50.join(dir, entry.name);
25333
+ if (entry.isDirectory()) {
25334
+ files.push(...await listFiles3(fullPath, projectPath));
25335
+ } else if (entry.isFile()) {
25336
+ const ext = path50.extname(entry.name).toLowerCase();
25337
+ if (INDEXABLE_EXTENSIONS2.has(ext)) {
25338
+ files.push(path50.relative(projectPath, fullPath));
25339
+ }
25340
+ }
25341
+ }
25342
+ return files;
25343
+ }
25344
+ async function buildGraph(projectPath) {
25345
+ const files = await listFiles3(projectPath, projectPath);
25346
+ const forward = {};
25347
+ const reverse = {};
25348
+ let edgeCount = 0;
25349
+ const BATCH_SIZE = 50;
25350
+ for (let i = 0; i < files.length; i += BATCH_SIZE) {
25351
+ const batch = files.slice(i, i + BATCH_SIZE);
25352
+ const results = await Promise.all(
25353
+ batch.map(async (filePath) => {
25354
+ try {
25355
+ const content = await fs47.readFile(path50.join(projectPath, filePath), "utf-8");
25356
+ const sources = extractImportSources(content);
25357
+ const resolved = [];
25358
+ for (const source of sources) {
25359
+ const target = await resolveImport2(source, filePath, projectPath);
25360
+ if (target && target !== filePath) {
25361
+ resolved.push(target);
25362
+ }
25363
+ }
25364
+ return { filePath, imports: resolved };
25365
+ } catch {
25366
+ return { filePath, imports: [] };
25367
+ }
25368
+ })
25369
+ );
25370
+ for (const { filePath, imports } of results) {
25371
+ if (imports.length === 0) continue;
25372
+ forward[filePath] = imports;
25373
+ edgeCount += imports.length;
25374
+ for (const target of imports) {
25375
+ if (!reverse[target]) reverse[target] = [];
25376
+ reverse[target].push(filePath);
25377
+ }
25378
+ }
25379
+ }
25380
+ return {
25381
+ forward,
25382
+ reverse,
25383
+ fileCount: files.length,
25384
+ edgeCount,
25385
+ builtAt: (/* @__PURE__ */ new Date()).toISOString()
25386
+ };
25387
+ }
25388
+ function saveGraph(projectId, graph) {
25389
+ database_default.setDoc(projectId, INDEX_KEY2, graph);
25390
+ }
25391
+ function loadGraph(projectId) {
25392
+ return database_default.getDoc(projectId, INDEX_KEY2);
25393
+ }
25394
+ async function indexImports(projectPath, projectId) {
25395
+ const graph = await buildGraph(projectPath);
25396
+ saveGraph(projectId, graph);
25397
+ return graph;
25398
+ }
25399
+ var INDEXABLE_EXTENSIONS2, SKIP_DIRS2, RESOLVE_EXTENSIONS, IMPORT_REGEX, INDEX_KEY2;
25400
+ var init_import_graph = __esm({
25401
+ "core/domain/import-graph.ts"() {
25402
+ "use strict";
25403
+ init_database();
25404
+ INDEXABLE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
25405
+ SKIP_DIRS2 = /* @__PURE__ */ new Set([
25406
+ "node_modules",
25407
+ ".git",
25408
+ "dist",
25409
+ "build",
25410
+ "out",
25411
+ ".next",
25412
+ "coverage",
25413
+ ".cache",
25414
+ ".turbo",
25415
+ ".vercel"
25416
+ ]);
25417
+ RESOLVE_EXTENSIONS = ["", ".ts", ".tsx", ".js", ".jsx", "/index.ts", "/index.js"];
25418
+ IMPORT_REGEX = /(?:import|from)\s+['"]([^'"]+)['"]/g;
25419
+ __name(extractImportSources, "extractImportSources");
25420
+ __name(resolveImport2, "resolveImport");
25421
+ __name(listFiles3, "listFiles");
25422
+ __name(buildGraph, "buildGraph");
25423
+ INDEX_KEY2 = "import-graph";
25424
+ __name(saveGraph, "saveGraph");
25425
+ __name(loadGraph, "loadGraph");
25426
+ __name(indexImports, "indexImports");
25427
+ }
25428
+ });
25429
+
25430
+ // core/domain/change-propagator.ts
25431
+ function propagateChanges(diff, projectId) {
25432
+ const directlyChanged = [...diff.added, ...diff.modified];
25433
+ const directSet = new Set(directlyChanged);
25434
+ const affected = /* @__PURE__ */ new Set();
25435
+ const graph = loadGraph(projectId);
25436
+ if (graph) {
25437
+ for (const changedFile of directlyChanged) {
25438
+ const importers = graph.reverse[changedFile];
25439
+ if (importers) {
25440
+ for (const importer of importers) {
25441
+ if (!directSet.has(importer)) {
25442
+ affected.add(importer);
25443
+ }
25444
+ }
25445
+ }
25446
+ }
25447
+ }
25448
+ const affectedByImports = Array.from(affected);
25449
+ const allAffected = [...directlyChanged, ...affectedByImports];
25450
+ return {
25451
+ directlyChanged,
25452
+ affectedByImports,
25453
+ deleted: diff.deleted,
25454
+ allAffected
25455
+ };
25456
+ }
25457
+ function affectedDomains(changedFiles) {
25458
+ const domains = /* @__PURE__ */ new Set();
25459
+ for (const file of changedFiles) {
25460
+ const lower = file.toLowerCase();
25461
+ if (lower.endsWith(".tsx") || lower.endsWith(".jsx") || lower.endsWith(".css") || lower.endsWith(".scss") || lower.endsWith(".vue") || lower.endsWith(".svelte") || lower.includes("/components/") || lower.includes("/pages/") || lower.includes("/app/")) {
25462
+ domains.add("frontend");
25463
+ domains.add("uxui");
25464
+ }
25465
+ if (lower.includes(".test.") || lower.includes(".spec.") || lower.includes("__tests__") || lower.includes("/test/")) {
25466
+ domains.add("testing");
25467
+ }
25468
+ if (lower.includes("dockerfile") || lower.includes("docker-compose") || lower.includes(".dockerignore") || lower.includes(".github/") || lower.includes("ci/") || lower.includes("cd/")) {
25469
+ domains.add("devops");
25470
+ }
25471
+ if (lower.endsWith(".sql") || lower.includes("prisma") || lower.includes("drizzle") || lower.includes("migration") || lower.includes("/db/")) {
25472
+ domains.add("database");
25473
+ }
25474
+ if ((lower.endsWith(".ts") || lower.endsWith(".js")) && !lower.includes(".test.") && !lower.includes(".spec.") && !lower.endsWith(".d.ts")) {
25475
+ domains.add("backend");
25476
+ }
25477
+ }
25478
+ return domains;
25479
+ }
25480
+ var init_change_propagator = __esm({
25481
+ "core/domain/change-propagator.ts"() {
25482
+ "use strict";
25483
+ init_import_graph();
25484
+ __name(propagateChanges, "propagateChanges");
25485
+ __name(affectedDomains, "affectedDomains");
25486
+ }
25487
+ });
25488
+
25489
+ // core/domain/file-hasher.ts
25490
+ import fs48 from "node:fs/promises";
25491
+ import path51 from "node:path";
25492
+ async function listProjectFiles(dir, projectPath) {
25493
+ const files = [];
25494
+ const entries = await fs48.readdir(dir, { withFileTypes: true }).catch(() => []);
25495
+ for (const entry of entries) {
25496
+ const name = String(entry.name);
25497
+ if (SKIP_DIRS3.has(name)) continue;
25498
+ if (name.startsWith(".") && name !== ".env.example") continue;
25499
+ const fullPath = path51.join(dir, name);
25500
+ if (entry.isDirectory()) {
25501
+ files.push(...await listProjectFiles(fullPath, projectPath));
25502
+ } else if (entry.isFile()) {
25503
+ const ext = path51.extname(name).toLowerCase();
25504
+ if (INDEXABLE_EXTENSIONS3.has(ext)) {
25505
+ files.push(path51.relative(projectPath, fullPath));
25506
+ }
25507
+ }
25508
+ }
25509
+ return files;
25510
+ }
25511
+ function hashContent(content) {
25512
+ if (typeof Bun !== "undefined" && Bun.hash) {
25513
+ return `xxh64:${Bun.hash(content).toString(36)}`;
25514
+ }
25515
+ let h = 2166136261;
25516
+ for (let i = 0; i < content.length; i++) {
25517
+ h ^= content.charCodeAt(i);
25518
+ h = Math.imul(h, 16777619);
25519
+ }
25520
+ return `fnv1a:${(h >>> 0).toString(36)}`;
25521
+ }
25522
+ async function computeHashes(projectPath) {
25523
+ const filePaths = await listProjectFiles(projectPath, projectPath);
25524
+ const hashes = /* @__PURE__ */ new Map();
25525
+ const BATCH_SIZE = 100;
25526
+ for (let i = 0; i < filePaths.length; i += BATCH_SIZE) {
25527
+ const batch = filePaths.slice(i, i + BATCH_SIZE);
25528
+ const results = await Promise.all(
25529
+ batch.map(async (filePath) => {
25530
+ try {
25531
+ const fullPath = path51.join(projectPath, filePath);
25532
+ const [content, stat] = await Promise.all([
25533
+ fs48.readFile(fullPath, "utf-8"),
25534
+ fs48.stat(fullPath)
25535
+ ]);
25536
+ return {
25537
+ path: filePath,
25538
+ hash: hashContent(content),
25539
+ size: stat.size,
25540
+ mtime: stat.mtime.toISOString()
25541
+ };
25542
+ } catch {
25543
+ return null;
25544
+ }
25545
+ })
25546
+ );
25547
+ for (const result of results) {
25548
+ if (result) {
25549
+ hashes.set(result.path, result);
25550
+ }
25551
+ }
25552
+ }
25553
+ return hashes;
25554
+ }
25555
+ function diffHashes(current, stored) {
25556
+ const added = [];
25557
+ const modified = [];
25558
+ const unchanged = [];
25559
+ for (const [filePath, currentHash] of current) {
25560
+ const storedHash = stored.get(filePath);
25561
+ if (!storedHash) {
25562
+ added.push(filePath);
25563
+ } else if (storedHash.hash !== currentHash.hash) {
25564
+ modified.push(filePath);
25565
+ } else {
25566
+ unchanged.push(filePath);
25567
+ }
25568
+ }
25569
+ const deleted = [];
25570
+ for (const filePath of stored.keys()) {
25571
+ if (!current.has(filePath)) {
25572
+ deleted.push(filePath);
25573
+ }
25574
+ }
25575
+ return { added, modified, deleted, unchanged };
25576
+ }
25577
+ function saveHashes(projectId, hashes) {
25578
+ const db = database_default.getDb(projectId);
25579
+ db.transaction(() => {
25580
+ db.prepare("DELETE FROM index_checksums").run();
25581
+ const insert = db.prepare(
25582
+ "INSERT INTO index_checksums (path, checksum, size, mtime) VALUES (?, ?, ?, ?)"
25583
+ );
25584
+ for (const [, hash] of hashes) {
25585
+ insert.run(hash.path, hash.hash, hash.size, hash.mtime);
25586
+ }
25587
+ })();
25588
+ database_default.setDoc(projectId, "file-hashes-meta", {
25589
+ fileCount: hashes.size,
25590
+ builtAt: (/* @__PURE__ */ new Date()).toISOString()
25591
+ });
25592
+ }
25593
+ function loadHashes(projectId) {
25594
+ const hashes = /* @__PURE__ */ new Map();
25595
+ try {
25596
+ const rows = database_default.query(
25597
+ projectId,
25598
+ "SELECT path, checksum, size, mtime FROM index_checksums"
25599
+ );
25600
+ for (const row of rows) {
25601
+ hashes.set(row.path, {
25602
+ path: row.path,
25603
+ hash: row.checksum,
25604
+ size: row.size || 0,
25605
+ mtime: row.mtime || ""
25606
+ });
25607
+ }
25608
+ } catch {
25609
+ }
25610
+ return hashes;
25611
+ }
25612
+ async function detectChanges(projectPath, projectId) {
25613
+ const [currentHashes, storedHashes] = await Promise.all([
25614
+ computeHashes(projectPath),
25615
+ Promise.resolve(loadHashes(projectId))
25616
+ ]);
25617
+ const diff = diffHashes(currentHashes, storedHashes);
25618
+ return { diff, currentHashes };
25619
+ }
25620
+ function hasHashRegistry(projectId) {
25621
+ return database_default.hasDoc(projectId, "file-hashes-meta");
25622
+ }
25623
+ var INDEXABLE_EXTENSIONS3, SKIP_DIRS3;
25624
+ var init_file_hasher = __esm({
25625
+ "core/domain/file-hasher.ts"() {
25626
+ "use strict";
25627
+ init_database();
25628
+ INDEXABLE_EXTENSIONS3 = /* @__PURE__ */ new Set([
25629
+ ".ts",
25630
+ ".tsx",
25631
+ ".js",
25632
+ ".jsx",
25633
+ ".mjs",
25634
+ ".cjs",
25635
+ ".json",
25636
+ ".md",
25637
+ ".css",
25638
+ ".scss",
25639
+ ".html",
25640
+ ".vue",
25641
+ ".svelte",
25642
+ ".py",
25643
+ ".go",
25644
+ ".rs",
25645
+ ".yaml",
25646
+ ".yml",
25647
+ ".toml"
25648
+ ]);
25649
+ SKIP_DIRS3 = /* @__PURE__ */ new Set([
25650
+ "node_modules",
25651
+ ".git",
25652
+ "dist",
25653
+ "build",
25654
+ "out",
25655
+ ".next",
25656
+ "coverage",
25657
+ ".cache",
25658
+ ".turbo",
25659
+ ".vercel",
25660
+ ".prjct"
25661
+ ]);
25662
+ __name(listProjectFiles, "listProjectFiles");
25663
+ __name(hashContent, "hashContent");
25664
+ __name(computeHashes, "computeHashes");
25665
+ __name(diffHashes, "diffHashes");
25666
+ __name(saveHashes, "saveHashes");
25667
+ __name(loadHashes, "loadHashes");
25668
+ __name(detectChanges, "detectChanges");
25669
+ __name(hasHashRegistry, "hasHashRegistry");
25670
+ }
25671
+ });
25672
+
25673
+ // core/domain/git-cochange.ts
25674
+ import { exec as execCallback7 } from "node:child_process";
25675
+ import { promisify as promisify15 } from "node:util";
25676
+ async function parseGitLog(projectPath, maxCommits = 100) {
25677
+ try {
25678
+ const { stdout } = await exec14(
25679
+ `git log --name-only --pretty=format:'---COMMIT---' -${maxCommits}`,
25680
+ { cwd: projectPath, maxBuffer: 10 * 1024 * 1024 }
25681
+ );
25682
+ const commits = [];
25683
+ let currentFiles = null;
25684
+ for (const line of stdout.split("\n")) {
25685
+ const trimmed = line.trim();
25686
+ if (trimmed === "---COMMIT---") {
25687
+ if (currentFiles && currentFiles.size > 0 && currentFiles.size <= MAX_FILES_PER_COMMIT) {
25688
+ commits.push(currentFiles);
25689
+ }
25690
+ currentFiles = /* @__PURE__ */ new Set();
25691
+ } else if (trimmed && currentFiles) {
25692
+ if (isSourceFile(trimmed)) {
25693
+ currentFiles.add(trimmed);
25694
+ }
25695
+ }
25696
+ }
25697
+ if (currentFiles && currentFiles.size > 0 && currentFiles.size <= MAX_FILES_PER_COMMIT) {
25698
+ commits.push(currentFiles);
25699
+ }
25700
+ return commits;
25701
+ } catch {
25702
+ return [];
25703
+ }
25704
+ }
25705
+ function isSourceFile(filePath) {
25706
+ const sourceExtensions = /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|cs|rb|php|vue|svelte)$/i;
25707
+ return sourceExtensions.test(filePath) && !filePath.includes("node_modules/");
25708
+ }
25709
+ async function buildMatrix(projectPath, maxCommits = 100) {
25710
+ const commitSets = await parseGitLog(projectPath, maxCommits);
25711
+ const fileCommitCount = /* @__PURE__ */ new Map();
25712
+ const pairCount = /* @__PURE__ */ new Map();
25713
+ for (const files of commitSets) {
25714
+ const fileArray = Array.from(files);
25715
+ for (const file of fileArray) {
25716
+ fileCommitCount.set(file, (fileCommitCount.get(file) || 0) + 1);
25717
+ }
25718
+ for (let i = 0; i < fileArray.length; i++) {
25719
+ for (let j = i + 1; j < fileArray.length; j++) {
25720
+ const key = pairKey(fileArray[i], fileArray[j]);
25721
+ pairCount.set(key, (pairCount.get(key) || 0) + 1);
25722
+ }
25723
+ }
25724
+ }
25725
+ const matrix = {};
25726
+ for (const [key, count] of pairCount) {
25727
+ const [fileA, fileB] = key.split("\0");
25728
+ const countA = fileCommitCount.get(fileA) || 0;
25729
+ const countB = fileCommitCount.get(fileB) || 0;
25730
+ if (countA < MIN_FILE_OCCURRENCES || countB < MIN_FILE_OCCURRENCES) continue;
25731
+ const unionCount = countA + countB - count;
25732
+ const similarity = unionCount > 0 ? count / unionCount : 0;
25733
+ if (similarity < MIN_SIMILARITY) continue;
25734
+ if (!matrix[fileA]) matrix[fileA] = {};
25735
+ if (!matrix[fileB]) matrix[fileB] = {};
25736
+ matrix[fileA][fileB] = similarity;
25737
+ matrix[fileB][fileA] = similarity;
25738
+ }
25739
+ return {
25740
+ matrix,
25741
+ commitsAnalyzed: commitSets.length,
25742
+ filesAnalyzed: fileCommitCount.size,
25743
+ builtAt: (/* @__PURE__ */ new Date()).toISOString()
25744
+ };
25745
+ }
25746
+ function pairKey(a, b) {
25747
+ return a < b ? `${a}\0${b}` : `${b}\0${a}`;
25748
+ }
25749
+ function saveMatrix(projectId, index) {
25750
+ database_default.setDoc(projectId, INDEX_KEY3, index);
25751
+ }
25752
+ async function indexCoChanges(projectPath, projectId, maxCommits = 100) {
25753
+ const index = await buildMatrix(projectPath, maxCommits);
25754
+ saveMatrix(projectId, index);
25755
+ return index;
25756
+ }
25757
+ var exec14, MIN_SIMILARITY, MIN_FILE_OCCURRENCES, MAX_FILES_PER_COMMIT, INDEX_KEY3;
25758
+ var init_git_cochange = __esm({
25759
+ "core/domain/git-cochange.ts"() {
25760
+ "use strict";
25761
+ init_database();
25762
+ exec14 = promisify15(execCallback7);
25763
+ MIN_SIMILARITY = 0.1;
25764
+ MIN_FILE_OCCURRENCES = 2;
25765
+ MAX_FILES_PER_COMMIT = 30;
25766
+ __name(parseGitLog, "parseGitLog");
25767
+ __name(isSourceFile, "isSourceFile");
25768
+ __name(buildMatrix, "buildMatrix");
25769
+ __name(pairKey, "pairKey");
25770
+ INDEX_KEY3 = "cochange-index";
25771
+ __name(saveMatrix, "saveMatrix");
25772
+ __name(indexCoChanges, "indexCoChanges");
25773
+ }
25774
+ });
25775
+
25776
+ // core/services/context-generator.ts
25777
+ import fs49 from "node:fs/promises";
25778
+ import path52 from "node:path";
25016
25779
  var ContextFileGenerator;
25017
25780
  var init_context_generator = __esm({
25018
25781
  "core/services/context-generator.ts"() {
@@ -25037,10 +25800,10 @@ var init_context_generator = __esm({
25037
25800
  async writeWithPreservation(filePath, content) {
25038
25801
  let finalContent = content;
25039
25802
  try {
25040
- const existingContent = await fs46.readFile(filePath, "utf-8");
25803
+ const existingContent = await fs49.readFile(filePath, "utf-8");
25041
25804
  const validation = validatePreserveBlocks(existingContent);
25042
25805
  if (!validation.valid) {
25043
- const filename = path49.basename(filePath);
25806
+ const filename = path52.basename(filePath);
25044
25807
  console.warn(`\u26A0\uFE0F ${filename} has invalid preserve blocks:`);
25045
25808
  for (const error of validation.errors) {
25046
25809
  console.warn(` ${error}`);
@@ -25049,13 +25812,13 @@ var init_context_generator = __esm({
25049
25812
  finalContent = mergePreservedSections(content, existingContent);
25050
25813
  } catch {
25051
25814
  }
25052
- await fs46.writeFile(filePath, finalContent, "utf-8");
25815
+ await fs49.writeFile(filePath, finalContent, "utf-8");
25053
25816
  }
25054
25817
  /**
25055
25818
  * Generate all context files in parallel
25056
25819
  */
25057
25820
  async generate(git, stats, commands, agents, sources) {
25058
- const contextPath = path49.join(this.config.globalPath, "context");
25821
+ const contextPath = path52.join(this.config.globalPath, "context");
25059
25822
  await Promise.all([
25060
25823
  this.generateClaudeMd(contextPath, git, stats, commands, agents, sources),
25061
25824
  this.generateNowMd(contextPath),
@@ -25155,7 +25918,7 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
25155
25918
  **Workflow**: ${workflowAgents.join(", ")}
25156
25919
  **Domain**: ${domainAgents.join(", ") || "none"}
25157
25920
  `;
25158
- const claudePath = path49.join(contextPath, "CLAUDE.md");
25921
+ const claudePath = path52.join(contextPath, "CLAUDE.md");
25159
25922
  await this.writeWithPreservation(claudePath, content);
25160
25923
  }
25161
25924
  /**
@@ -25164,8 +25927,8 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
25164
25927
  async generateNowMd(contextPath) {
25165
25928
  let currentTask = null;
25166
25929
  try {
25167
- const statePath = path49.join(this.config.globalPath, "storage", "state.json");
25168
- const state = JSON.parse(await fs46.readFile(statePath, "utf-8"));
25930
+ const statePath = path52.join(this.config.globalPath, "storage", "state.json");
25931
+ const state = JSON.parse(await fs49.readFile(statePath, "utf-8"));
25169
25932
  currentTask = state.currentTask;
25170
25933
  } catch {
25171
25934
  }
@@ -25181,7 +25944,7 @@ _No active task_
25181
25944
 
25182
25945
  Use \`p. task "description"\` to start working.
25183
25946
  `;
25184
- await this.writeWithPreservation(path49.join(contextPath, "now.md"), content);
25947
+ await this.writeWithPreservation(path52.join(contextPath, "now.md"), content);
25185
25948
  }
25186
25949
  /**
25187
25950
  * Generate next.md - task queue
@@ -25189,15 +25952,15 @@ Use \`p. task "description"\` to start working.
25189
25952
  async generateNextMd(contextPath) {
25190
25953
  let queue = { tasks: [] };
25191
25954
  try {
25192
- const queuePath = path49.join(this.config.globalPath, "storage", "queue.json");
25193
- queue = JSON.parse(await fs46.readFile(queuePath, "utf-8"));
25955
+ const queuePath = path52.join(this.config.globalPath, "storage", "queue.json");
25956
+ queue = JSON.parse(await fs49.readFile(queuePath, "utf-8"));
25194
25957
  } catch {
25195
25958
  }
25196
25959
  const content = `# NEXT
25197
25960
 
25198
25961
  ${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}${t.priority ? ` [${t.priority}]` : ""}`).join("\n") : "_Empty queue_"}
25199
25962
  `;
25200
- await this.writeWithPreservation(path49.join(contextPath, "next.md"), content);
25963
+ await this.writeWithPreservation(path52.join(contextPath, "next.md"), content);
25201
25964
  }
25202
25965
  /**
25203
25966
  * Generate ideas.md - captured ideas
@@ -25205,15 +25968,15 @@ ${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}
25205
25968
  async generateIdeasMd(contextPath) {
25206
25969
  let ideas = { ideas: [] };
25207
25970
  try {
25208
- const ideasPath = path49.join(this.config.globalPath, "storage", "ideas.json");
25209
- ideas = JSON.parse(await fs46.readFile(ideasPath, "utf-8"));
25971
+ const ideasPath = path52.join(this.config.globalPath, "storage", "ideas.json");
25972
+ ideas = JSON.parse(await fs49.readFile(ideasPath, "utf-8"));
25210
25973
  } catch {
25211
25974
  }
25212
25975
  const content = `# IDEAS
25213
25976
 
25214
25977
  ${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [${i.priority}]` : ""}`).join("\n") : "_No ideas captured yet_"}
25215
25978
  `;
25216
- await this.writeWithPreservation(path49.join(contextPath, "ideas.md"), content);
25979
+ await this.writeWithPreservation(path52.join(contextPath, "ideas.md"), content);
25217
25980
  }
25218
25981
  /**
25219
25982
  * Generate shipped.md - completed features
@@ -25223,8 +25986,8 @@ ${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [
25223
25986
  shipped: []
25224
25987
  };
25225
25988
  try {
25226
- const shippedPath = path49.join(this.config.globalPath, "storage", "shipped.json");
25227
- shipped = JSON.parse(await fs46.readFile(shippedPath, "utf-8"));
25989
+ const shippedPath = path52.join(this.config.globalPath, "storage", "shipped.json");
25990
+ shipped = JSON.parse(await fs49.readFile(shippedPath, "utf-8"));
25228
25991
  } catch {
25229
25992
  }
25230
25993
  const content = `# SHIPPED \u{1F680}
@@ -25233,7 +25996,7 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
25233
25996
 
25234
25997
  **Total shipped:** ${shipped.shipped.length}
25235
25998
  `;
25236
- await this.writeWithPreservation(path49.join(contextPath, "shipped.md"), content);
25999
+ await this.writeWithPreservation(path52.join(contextPath, "shipped.md"), content);
25237
26000
  }
25238
26001
  // ==========================================================================
25239
26002
  // MONOREPO SUPPORT
@@ -25262,9 +26025,9 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
25262
26025
  commands,
25263
26026
  agents
25264
26027
  );
25265
- const claudePath = path49.join(pkg.path, "CLAUDE.md");
26028
+ const claudePath = path52.join(pkg.path, "CLAUDE.md");
25266
26029
  await this.writeWithPreservation(claudePath, content);
25267
- generatedFiles.push(path49.relative(this.config.projectPath, claudePath));
26030
+ generatedFiles.push(path52.relative(this.config.projectPath, claudePath));
25268
26031
  }
25269
26032
  return generatedFiles;
25270
26033
  }
@@ -25277,8 +26040,8 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
25277
26040
  let pkgVersion = stats.version;
25278
26041
  let pkgName = pkg.name;
25279
26042
  try {
25280
- const pkgJsonPath = path49.join(pkg.path, "package.json");
25281
- const pkgJson = JSON.parse(await fs46.readFile(pkgJsonPath, "utf-8"));
26043
+ const pkgJsonPath = path52.join(pkg.path, "package.json");
26044
+ const pkgJson = JSON.parse(await fs49.readFile(pkgJsonPath, "utf-8"));
25282
26045
  pkgVersion = pkgJson.version || stats.version;
25283
26046
  pkgName = pkgJson.name || pkg.name;
25284
26047
  } catch {
@@ -25343,8 +26106,8 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
25343
26106
  });
25344
26107
 
25345
26108
  // core/services/local-state-generator.ts
25346
- import fs47 from "node:fs/promises";
25347
- import path50 from "node:path";
26109
+ import fs50 from "node:fs/promises";
26110
+ import path53 from "node:path";
25348
26111
  var LOCAL_STATE_FILENAME, LocalStateGenerator, localStateGenerator;
25349
26112
  var init_local_state_generator = __esm({
25350
26113
  "core/services/local-state-generator.ts"() {
@@ -25359,17 +26122,17 @@ var init_local_state_generator = __esm({
25359
26122
  * Generate .prjct-state.md in the project root
25360
26123
  */
25361
26124
  async generate(projectPath, state) {
25362
- const filePath = path50.join(projectPath, LOCAL_STATE_FILENAME);
26125
+ const filePath = path53.join(projectPath, LOCAL_STATE_FILENAME);
25363
26126
  const content = this.toMarkdown(state);
25364
- await fs47.writeFile(filePath, content, "utf-8");
26127
+ await fs50.writeFile(filePath, content, "utf-8");
25365
26128
  }
25366
26129
  /**
25367
26130
  * Remove local state file
25368
26131
  */
25369
26132
  async remove(projectPath) {
25370
- const filePath = path50.join(projectPath, LOCAL_STATE_FILENAME);
26133
+ const filePath = path53.join(projectPath, LOCAL_STATE_FILENAME);
25371
26134
  try {
25372
- await fs47.unlink(filePath);
26135
+ await fs50.unlink(filePath);
25373
26136
  } catch (error) {
25374
26137
  if (!isNotFoundError(error)) throw error;
25375
26138
  }
@@ -25378,9 +26141,9 @@ var init_local_state_generator = __esm({
25378
26141
  * Check if local state file exists
25379
26142
  */
25380
26143
  async exists(projectPath) {
25381
- const filePath = path50.join(projectPath, LOCAL_STATE_FILENAME);
26144
+ const filePath = path53.join(projectPath, LOCAL_STATE_FILENAME);
25382
26145
  try {
25383
- await fs47.access(filePath);
26146
+ await fs50.access(filePath);
25384
26147
  return true;
25385
26148
  } catch {
25386
26149
  return false;
@@ -25459,11 +26222,11 @@ var init_local_state_generator = __esm({
25459
26222
  });
25460
26223
 
25461
26224
  // core/services/skill-lock.ts
25462
- import fs48 from "node:fs/promises";
26225
+ import fs51 from "node:fs/promises";
25463
26226
  import os14 from "node:os";
25464
- import path51 from "node:path";
26227
+ import path54 from "node:path";
25465
26228
  function getLockFilePath() {
25466
- return path51.join(os14.homedir(), ".prjct-cli", "skills", LOCK_FILE_NAME);
26229
+ return path54.join(os14.homedir(), ".prjct-cli", "skills", LOCK_FILE_NAME);
25467
26230
  }
25468
26231
  function createEmptyLockFile() {
25469
26232
  return {
@@ -25474,7 +26237,7 @@ function createEmptyLockFile() {
25474
26237
  }
25475
26238
  async function read() {
25476
26239
  try {
25477
- const content = await fs48.readFile(getLockFilePath(), "utf-8");
26240
+ const content = await fs51.readFile(getLockFilePath(), "utf-8");
25478
26241
  return JSON.parse(content);
25479
26242
  } catch {
25480
26243
  return createEmptyLockFile();
@@ -25482,9 +26245,9 @@ async function read() {
25482
26245
  }
25483
26246
  async function write(lockFile) {
25484
26247
  const lockPath = getLockFilePath();
25485
- await fs48.mkdir(path51.dirname(lockPath), { recursive: true });
26248
+ await fs51.mkdir(path54.dirname(lockPath), { recursive: true });
25486
26249
  lockFile.generatedAt = (/* @__PURE__ */ new Date()).toISOString();
25487
- await fs48.writeFile(lockPath, JSON.stringify(lockFile, null, 2), "utf-8");
26250
+ await fs51.writeFile(lockPath, JSON.stringify(lockFile, null, 2), "utf-8");
25488
26251
  }
25489
26252
  async function addEntry(entry) {
25490
26253
  const lockFile = await read();
@@ -25536,15 +26299,15 @@ var init_skill_lock = __esm({
25536
26299
  });
25537
26300
 
25538
26301
  // core/services/skill-installer.ts
25539
- import { exec as execCallback7 } from "node:child_process";
25540
- import fs49 from "node:fs/promises";
26302
+ import { exec as execCallback8 } from "node:child_process";
26303
+ import fs52 from "node:fs/promises";
25541
26304
  import os15 from "node:os";
25542
- import path52 from "node:path";
25543
- import { promisify as promisify15 } from "node:util";
26305
+ import path55 from "node:path";
26306
+ import { promisify as promisify16 } from "node:util";
25544
26307
  import { glob } from "glob";
25545
26308
  function parseSource(source) {
25546
26309
  if (source.startsWith("./") || source.startsWith("/") || source.startsWith("~")) {
25547
- const resolvedPath = source.startsWith("~") ? path52.join(os15.homedir(), source.slice(1)) : path52.resolve(source);
26310
+ const resolvedPath = source.startsWith("~") ? path55.join(os15.homedir(), source.slice(1)) : path55.resolve(source);
25548
26311
  return {
25549
26312
  type: "local",
25550
26313
  localPath: resolvedPath,
@@ -25582,22 +26345,22 @@ function parseSource(source) {
25582
26345
  async function discoverSkills(dir) {
25583
26346
  const skills = [];
25584
26347
  try {
25585
- const rootSkill = path52.join(dir, "SKILL.md");
25586
- await fs49.access(rootSkill);
25587
- const dirName = path52.basename(dir);
26348
+ const rootSkill = path55.join(dir, "SKILL.md");
26349
+ await fs52.access(rootSkill);
26350
+ const dirName = path55.basename(dir);
25588
26351
  skills.push({ name: dirName, filePath: rootSkill });
25589
26352
  } catch {
25590
26353
  }
25591
26354
  const subdirSkills = await glob("*/SKILL.md", { cwd: dir, absolute: true });
25592
26355
  for (const filePath of subdirSkills) {
25593
- const name = path52.basename(path52.dirname(filePath));
26356
+ const name = path55.basename(path55.dirname(filePath));
25594
26357
  if (!skills.some((s) => s.name === name)) {
25595
26358
  skills.push({ name, filePath });
25596
26359
  }
25597
26360
  }
25598
26361
  const nestedSkills = await glob("skills/*/SKILL.md", { cwd: dir, absolute: true });
25599
26362
  for (const filePath of nestedSkills) {
25600
- const name = path52.basename(path52.dirname(filePath));
26363
+ const name = path55.basename(path55.dirname(filePath));
25601
26364
  if (!skills.some((s) => s.name === name)) {
25602
26365
  skills.push({ name, filePath });
25603
26366
  }
@@ -25633,16 +26396,16 @@ ${prjctBlock.join("\n")}
25633
26396
  ${content}`;
25634
26397
  }
25635
26398
  function getInstallDir() {
25636
- return path52.join(os15.homedir(), ".claude", "skills");
26399
+ return path55.join(os15.homedir(), ".claude", "skills");
25637
26400
  }
25638
26401
  async function installSkillFile(sourcePath, name, source, sha) {
25639
26402
  const installDir = getInstallDir();
25640
- const targetDir = path52.join(installDir, name);
25641
- const targetPath = path52.join(targetDir, "SKILL.md");
25642
- const content = await fs49.readFile(sourcePath, "utf-8");
26403
+ const targetDir = path55.join(installDir, name);
26404
+ const targetPath = path55.join(targetDir, "SKILL.md");
26405
+ const content = await fs52.readFile(sourcePath, "utf-8");
25643
26406
  const enrichedContent = injectSourceMetadata(content, source, sha);
25644
- await fs49.mkdir(targetDir, { recursive: true });
25645
- await fs49.writeFile(targetPath, enrichedContent, "utf-8");
26407
+ await fs52.mkdir(targetDir, { recursive: true });
26408
+ await fs52.writeFile(targetPath, enrichedContent, "utf-8");
25646
26409
  return {
25647
26410
  name,
25648
26411
  filePath: targetPath,
@@ -25659,13 +26422,13 @@ async function installFromGitHub(source) {
25659
26422
  );
25660
26423
  return result;
25661
26424
  }
25662
- const tmpDir = path52.join(os15.tmpdir(), `prjct-skill-${Date.now()}`);
26425
+ const tmpDir = path55.join(os15.tmpdir(), `prjct-skill-${Date.now()}`);
25663
26426
  try {
25664
26427
  const cloneUrl = `https://github.com/${source.owner}/${source.repo}.git`;
25665
- await exec14(`git clone --depth 1 ${cloneUrl} ${tmpDir}`, { timeout: getTimeout("GIT_CLONE") });
26428
+ await exec15(`git clone --depth 1 ${cloneUrl} ${tmpDir}`, { timeout: getTimeout("GIT_CLONE") });
25666
26429
  let sha;
25667
26430
  try {
25668
- const { stdout } = await exec14("git rev-parse HEAD", {
26431
+ const { stdout } = await exec15("git rev-parse HEAD", {
25669
26432
  cwd: tmpDir,
25670
26433
  timeout: getTimeout("TOOL_CHECK")
25671
26434
  });
@@ -25703,7 +26466,7 @@ async function installFromGitHub(source) {
25703
26466
  }
25704
26467
  } finally {
25705
26468
  try {
25706
- await fs49.rm(tmpDir, { recursive: true, force: true });
26469
+ await fs52.rm(tmpDir, { recursive: true, force: true });
25707
26470
  } catch {
25708
26471
  }
25709
26472
  }
@@ -25713,14 +26476,14 @@ async function installFromLocal(source) {
25713
26476
  const result = { installed: [], skipped: [], errors: [] };
25714
26477
  const localPath = source.localPath;
25715
26478
  try {
25716
- await fs49.access(localPath);
26479
+ await fs52.access(localPath);
25717
26480
  } catch {
25718
26481
  result.errors.push(`Local path not found: ${localPath}`);
25719
26482
  return result;
25720
26483
  }
25721
- const stat = await fs49.stat(localPath);
26484
+ const stat = await fs52.stat(localPath);
25722
26485
  if (stat.isFile()) {
25723
- const name = path52.basename(path52.dirname(localPath));
26486
+ const name = path55.basename(path55.dirname(localPath));
25724
26487
  try {
25725
26488
  const installed = await installSkillFile(localPath, name, source);
25726
26489
  const lockEntry = {
@@ -25760,14 +26523,14 @@ async function installFromLocal(source) {
25760
26523
  }
25761
26524
  async function remove(name) {
25762
26525
  const installDir = getInstallDir();
25763
- const subdirPath = path52.join(installDir, name);
26526
+ const subdirPath = path55.join(installDir, name);
25764
26527
  try {
25765
- await fs49.rm(subdirPath, { recursive: true, force: true });
26528
+ await fs52.rm(subdirPath, { recursive: true, force: true });
25766
26529
  } catch {
25767
26530
  }
25768
- const flatPath = path52.join(installDir, `${name}.md`);
26531
+ const flatPath = path55.join(installDir, `${name}.md`);
25769
26532
  try {
25770
- await fs49.rm(flatPath, { force: true });
26533
+ await fs52.rm(flatPath, { force: true });
25771
26534
  } catch {
25772
26535
  }
25773
26536
  return skillLock.removeEntry(name);
@@ -25787,7 +26550,7 @@ async function install(sourceStr) {
25787
26550
  };
25788
26551
  }
25789
26552
  }
25790
- var exec14, skillInstaller;
26553
+ var exec15, skillInstaller;
25791
26554
  var init_skill_installer = __esm({
25792
26555
  "core/services/skill-installer.ts"() {
25793
26556
  "use strict";
@@ -25795,7 +26558,7 @@ var init_skill_installer = __esm({
25795
26558
  init_fs();
25796
26559
  init_dependency_validator();
25797
26560
  init_skill_lock();
25798
- exec14 = promisify15(execCallback7);
26561
+ exec15 = promisify16(execCallback8);
25799
26562
  __name(parseSource, "parseSource");
25800
26563
  __name(discoverSkills, "discoverSkills");
25801
26564
  __name(injectSourceMetadata, "injectSourceMetadata");
@@ -25815,8 +26578,8 @@ var init_skill_installer = __esm({
25815
26578
  });
25816
26579
 
25817
26580
  // core/services/stack-detector.ts
25818
- import fs50 from "node:fs/promises";
25819
- import path53 from "node:path";
26581
+ import fs53 from "node:fs/promises";
26582
+ import path56 from "node:path";
25820
26583
  var StackDetector;
25821
26584
  var init_stack_detector = __esm({
25822
26585
  "core/services/stack-detector.ts"() {
@@ -25975,8 +26738,8 @@ var init_stack_detector = __esm({
25975
26738
  */
25976
26739
  async readPackageJson() {
25977
26740
  try {
25978
- const pkgPath = path53.join(this.projectPath, "package.json");
25979
- const content = await fs50.readFile(pkgPath, "utf-8");
26741
+ const pkgPath = path56.join(this.projectPath, "package.json");
26742
+ const content = await fs53.readFile(pkgPath, "utf-8");
25980
26743
  return JSON.parse(content);
25981
26744
  } catch {
25982
26745
  return null;
@@ -25987,7 +26750,7 @@ var init_stack_detector = __esm({
25987
26750
  */
25988
26751
  async fileExists(filename) {
25989
26752
  try {
25990
- await fs50.access(path53.join(this.projectPath, filename));
26753
+ await fs53.access(path56.join(this.projectPath, filename));
25991
26754
  return true;
25992
26755
  } catch {
25993
26756
  return false;
@@ -25998,16 +26761,16 @@ var init_stack_detector = __esm({
25998
26761
  });
25999
26762
 
26000
26763
  // core/services/sync-verifier.ts
26001
- import { exec as exec15 } from "node:child_process";
26002
- import fs51 from "node:fs/promises";
26003
- import path54 from "node:path";
26004
- import { promisify as promisify16 } from "node:util";
26764
+ import { exec as exec16 } from "node:child_process";
26765
+ import fs54 from "node:fs/promises";
26766
+ import path57 from "node:path";
26767
+ import { promisify as promisify17 } from "node:util";
26005
26768
  var execAsync10, BUILTIN_CHECKS, SyncVerifier, syncVerifier;
26006
26769
  var init_sync_verifier = __esm({
26007
26770
  "core/services/sync-verifier.ts"() {
26008
26771
  "use strict";
26009
26772
  init_fs();
26010
- execAsync10 = promisify16(exec15);
26773
+ execAsync10 = promisify17(exec16);
26011
26774
  BUILTIN_CHECKS = {
26012
26775
  /**
26013
26776
  * Verify all expected context files exist after sync
@@ -26017,9 +26780,9 @@ var init_sync_verifier = __esm({
26017
26780
  const expected = ["context/CLAUDE.md"];
26018
26781
  const missing = [];
26019
26782
  for (const file of expected) {
26020
- const filePath = path54.join(globalPath, file);
26783
+ const filePath = path57.join(globalPath, file);
26021
26784
  try {
26022
- await fs51.access(filePath);
26785
+ await fs54.access(filePath);
26023
26786
  } catch {
26024
26787
  missing.push(file);
26025
26788
  }
@@ -26040,9 +26803,9 @@ var init_sync_verifier = __esm({
26040
26803
  const jsonFiles = ["storage/state.json"];
26041
26804
  const invalid = [];
26042
26805
  for (const file of jsonFiles) {
26043
- const filePath = path54.join(globalPath, file);
26806
+ const filePath = path57.join(globalPath, file);
26044
26807
  try {
26045
- const content = await fs51.readFile(filePath, "utf-8");
26808
+ const content = await fs54.readFile(filePath, "utf-8");
26046
26809
  JSON.parse(content);
26047
26810
  } catch (error) {
26048
26811
  if (!isNotFoundError(error)) {
@@ -26063,7 +26826,7 @@ var init_sync_verifier = __esm({
26063
26826
  */
26064
26827
  async noSensitiveData(globalPath) {
26065
26828
  const start = Date.now();
26066
- const contextDir = path54.join(globalPath, "context");
26829
+ const contextDir = path57.join(globalPath, "context");
26067
26830
  const patterns = [
26068
26831
  /(?:api[_-]?key|apikey)\s*[:=]\s*['"][^'"]{10,}/i,
26069
26832
  /(?:password|passwd|pwd)\s*[:=]\s*['"][^'"]{4,}/i,
@@ -26071,10 +26834,10 @@ var init_sync_verifier = __esm({
26071
26834
  ];
26072
26835
  const violations = [];
26073
26836
  try {
26074
- const files = await fs51.readdir(contextDir);
26837
+ const files = await fs54.readdir(contextDir);
26075
26838
  for (const file of files) {
26076
26839
  if (!file.endsWith(".md")) continue;
26077
- const content = await fs51.readFile(path54.join(contextDir, file), "utf-8");
26840
+ const content = await fs54.readFile(path57.join(contextDir, file), "utf-8");
26078
26841
  for (const pattern of patterns) {
26079
26842
  if (pattern.test(content)) {
26080
26843
  violations.push(`${file}: potential sensitive data detected`);
@@ -26194,16 +26957,21 @@ var init_sync_verifier = __esm({
26194
26957
  });
26195
26958
 
26196
26959
  // core/services/sync-service.ts
26197
- import { exec as exec16 } from "node:child_process";
26198
- import fs52 from "node:fs/promises";
26960
+ import { exec as exec17 } from "node:child_process";
26961
+ import fs55 from "node:fs/promises";
26199
26962
  import os16 from "node:os";
26200
- import path55 from "node:path";
26201
- import { promisify as promisify17 } from "node:util";
26963
+ import path58 from "node:path";
26964
+ import { promisify as promisify18 } from "node:util";
26202
26965
  var execAsync11, SyncService, syncService;
26203
26966
  var init_sync_service = __esm({
26204
26967
  "core/services/sync-service.ts"() {
26205
26968
  "use strict";
26206
26969
  init_ai_tools();
26970
+ init_bm25();
26971
+ init_change_propagator();
26972
+ init_file_hasher();
26973
+ init_git_cochange();
26974
+ init_import_graph();
26207
26975
  init_errors();
26208
26976
  init_command_installer();
26209
26977
  init_config_manager();
@@ -26219,7 +26987,7 @@ var init_sync_service = __esm({
26219
26987
  init_skill_installer();
26220
26988
  init_stack_detector();
26221
26989
  init_sync_verifier();
26222
- execAsync11 = promisify17(exec16);
26990
+ execAsync11 = promisify18(exec17);
26223
26991
  SyncService = class {
26224
26992
  static {
26225
26993
  __name(this, "SyncService");
@@ -26281,9 +27049,80 @@ var init_sync_service = __esm({
26281
27049
  this.detectCommands(),
26282
27050
  this.detectStack()
26283
27051
  ]);
26284
- const agents = await this.generateAgents(stack, stats);
27052
+ const isFullSync = options.full === true;
27053
+ let incrementalInfo;
27054
+ let shouldRebuildIndexes = true;
27055
+ let shouldRegenerateAgents = true;
27056
+ let changedDomains = /* @__PURE__ */ new Set();
27057
+ if (!isFullSync && hasHashRegistry(this.projectId)) {
27058
+ try {
27059
+ const { diff, currentHashes } = await detectChanges(this.projectPath, this.projectId);
27060
+ const totalChanged = diff.added.length + diff.modified.length + diff.deleted.length;
27061
+ if (totalChanged === 0 && !options.changedFiles?.length) {
27062
+ shouldRebuildIndexes = false;
27063
+ shouldRegenerateAgents = false;
27064
+ incrementalInfo = {
27065
+ isIncremental: true,
27066
+ filesChanged: 0,
27067
+ filesUnchanged: diff.unchanged.length,
27068
+ indexesRebuilt: false,
27069
+ agentsRegenerated: false,
27070
+ affectedDomains: []
27071
+ };
27072
+ } else {
27073
+ const propagated = propagateChanges(diff, this.projectId);
27074
+ changedDomains = affectedDomains(propagated.allAffected);
27075
+ const sourceExtensions = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
27076
+ const hasSourceChanges = propagated.allAffected.some((f) => {
27077
+ const ext = f.substring(f.lastIndexOf("."));
27078
+ return sourceExtensions.has(ext);
27079
+ });
27080
+ shouldRebuildIndexes = hasSourceChanges;
27081
+ const configChanged = propagated.directlyChanged.some(
27082
+ (f) => f === "package.json" || f === "tsconfig.json" || f.includes("Dockerfile") || f.includes("docker-compose")
27083
+ );
27084
+ shouldRegenerateAgents = configChanged;
27085
+ incrementalInfo = {
27086
+ isIncremental: true,
27087
+ filesChanged: totalChanged,
27088
+ filesUnchanged: diff.unchanged.length,
27089
+ indexesRebuilt: shouldRebuildIndexes,
27090
+ agentsRegenerated: shouldRegenerateAgents,
27091
+ affectedDomains: Array.from(changedDomains)
27092
+ };
27093
+ }
27094
+ saveHashes(this.projectId, currentHashes);
27095
+ } catch (error) {
27096
+ logger_default.debug("Incremental detection failed, falling back to full sync", {
27097
+ error: getErrorMessage(error)
27098
+ });
27099
+ }
27100
+ } else {
27101
+ try {
27102
+ const { currentHashes } = await detectChanges(this.projectPath, this.projectId);
27103
+ saveHashes(this.projectId, currentHashes);
27104
+ } catch (error) {
27105
+ logger_default.debug("Hash computation failed (non-critical)", {
27106
+ error: getErrorMessage(error)
27107
+ });
27108
+ }
27109
+ }
27110
+ if (shouldRebuildIndexes) {
27111
+ try {
27112
+ await Promise.all([
27113
+ indexProject(this.projectPath, this.projectId),
27114
+ indexImports(this.projectPath, this.projectId),
27115
+ indexCoChanges(this.projectPath, this.projectId)
27116
+ ]);
27117
+ } catch (error) {
27118
+ logger_default.debug("File ranking index build failed (non-critical)", {
27119
+ error: getErrorMessage(error)
27120
+ });
27121
+ }
27122
+ }
27123
+ const agents = shouldRegenerateAgents ? await this.generateAgents(stack, stats) : await this.loadExistingAgents();
26285
27124
  const skills = this.configureSkills(agents);
26286
- const skillsInstalled = await this.autoInstallSkills(agents);
27125
+ const skillsInstalled = shouldRegenerateAgents ? await this.autoInstallSkills(agents) : [];
26287
27126
  const sources = this.buildSources(stats, commands);
26288
27127
  const contextFiles = await this.generateContextFiles(git, stats, commands, agents, sources);
26289
27128
  const projectContext = {
@@ -26351,7 +27190,8 @@ var init_sync_service = __esm({
26351
27190
  success: r.success
26352
27191
  })),
26353
27192
  syncMetrics,
26354
- verification
27193
+ verification,
27194
+ incremental: incrementalInfo
26355
27195
  };
26356
27196
  } catch (error) {
26357
27197
  return {
@@ -26377,7 +27217,7 @@ var init_sync_service = __esm({
26377
27217
  async ensureDirectories() {
26378
27218
  const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
26379
27219
  await Promise.all(
26380
- dirs.map((dir) => fs52.mkdir(path55.join(this.globalPath, dir), { recursive: true }))
27220
+ dirs.map((dir) => fs55.mkdir(path58.join(this.globalPath, dir), { recursive: true }))
26381
27221
  );
26382
27222
  }
26383
27223
  // ==========================================================================
@@ -26448,7 +27288,7 @@ var init_sync_service = __esm({
26448
27288
  const stats = {
26449
27289
  fileCount: 0,
26450
27290
  version: "0.0.0",
26451
- name: path55.basename(this.projectPath),
27291
+ name: path58.basename(this.projectPath),
26452
27292
  ecosystem: "unknown",
26453
27293
  projectType: "simple",
26454
27294
  languages: [],
@@ -26465,8 +27305,8 @@ var init_sync_service = __esm({
26465
27305
  stats.fileCount = 0;
26466
27306
  }
26467
27307
  try {
26468
- const pkgPath = path55.join(this.projectPath, "package.json");
26469
- const pkg = JSON.parse(await fs52.readFile(pkgPath, "utf-8"));
27308
+ const pkgPath = path58.join(this.projectPath, "package.json");
27309
+ const pkg = JSON.parse(await fs55.readFile(pkgPath, "utf-8"));
26470
27310
  stats.version = pkg.version || "0.0.0";
26471
27311
  stats.name = pkg.name || stats.name;
26472
27312
  stats.ecosystem = "JavaScript";
@@ -26611,12 +27451,12 @@ var init_sync_service = __esm({
26611
27451
  // ==========================================================================
26612
27452
  async generateAgents(stack, stats) {
26613
27453
  const agents = [];
26614
- const agentsPath = path55.join(this.globalPath, "agents");
27454
+ const agentsPath = path58.join(this.globalPath, "agents");
26615
27455
  try {
26616
- const files = await fs52.readdir(agentsPath);
27456
+ const files = await fs55.readdir(agentsPath);
26617
27457
  for (const file of files) {
26618
27458
  if (file.endsWith(".md")) {
26619
- await fs52.unlink(path55.join(agentsPath, file));
27459
+ await fs55.unlink(path58.join(agentsPath, file));
26620
27460
  }
26621
27461
  }
26622
27462
  } catch (error) {
@@ -26654,6 +27494,27 @@ var init_sync_service = __esm({
26654
27494
  }
26655
27495
  return agents;
26656
27496
  }
27497
+ /**
27498
+ * Load existing agent info from disk (for incremental sync when agents don't need regeneration).
27499
+ * Reads the agents directory and returns metadata without regenerating files.
27500
+ */
27501
+ async loadExistingAgents() {
27502
+ const agentsPath = path58.join(this.globalPath, "agents");
27503
+ const agents = [];
27504
+ try {
27505
+ const files = await fs55.readdir(agentsPath);
27506
+ const workflowNames = /* @__PURE__ */ new Set(["prjct-workflow", "prjct-planner", "prjct-shipper"]);
27507
+ for (const file of files) {
27508
+ if (!file.endsWith(".md")) continue;
27509
+ const name = file.replace(".md", "");
27510
+ const type = workflowNames.has(name) ? "workflow" : "domain";
27511
+ agents.push({ name, type });
27512
+ }
27513
+ } catch {
27514
+ return [];
27515
+ }
27516
+ return agents;
27517
+ }
26657
27518
  /**
26658
27519
  * Resolve {{> partial-name }} includes in template content.
26659
27520
  * Loads partials from templates/subagents/.
@@ -26665,7 +27526,7 @@ var init_sync_service = __esm({
26665
27526
  let resolved = content;
26666
27527
  for (const match of matches) {
26667
27528
  const partialName = match[1];
26668
- const partialPath = path55.join(
27529
+ const partialPath = path58.join(
26669
27530
  __dirname,
26670
27531
  "..",
26671
27532
  "..",
@@ -26674,7 +27535,7 @@ var init_sync_service = __esm({
26674
27535
  `${partialName}.md`
26675
27536
  );
26676
27537
  try {
26677
- const partialContent = await fs52.readFile(partialPath, "utf-8");
27538
+ const partialContent = await fs55.readFile(partialPath, "utf-8");
26678
27539
  resolved = resolved.replace(match[0], partialContent.trim());
26679
27540
  } catch {
26680
27541
  resolved = resolved.replace(match[0], `<!-- partial "${partialName}" not found -->`);
@@ -26685,7 +27546,7 @@ var init_sync_service = __esm({
26685
27546
  async generateWorkflowAgent(name, agentsPath) {
26686
27547
  let content = "";
26687
27548
  try {
26688
- const templatePath = path55.join(
27549
+ const templatePath = path58.join(
26689
27550
  __dirname,
26690
27551
  "..",
26691
27552
  "..",
@@ -26694,7 +27555,7 @@ var init_sync_service = __esm({
26694
27555
  "workflow",
26695
27556
  `${name}.md`
26696
27557
  );
26697
- content = await fs52.readFile(templatePath, "utf-8");
27558
+ content = await fs55.readFile(templatePath, "utf-8");
26698
27559
  content = await this.resolveTemplateIncludes(content);
26699
27560
  } catch (error) {
26700
27561
  logger_default.debug("Workflow agent template not found, generating minimal", {
@@ -26703,12 +27564,12 @@ var init_sync_service = __esm({
26703
27564
  });
26704
27565
  content = this.generateMinimalWorkflowAgent(name);
26705
27566
  }
26706
- await fs52.writeFile(path55.join(agentsPath, `${name}.md`), content, "utf-8");
27567
+ await fs55.writeFile(path58.join(agentsPath, `${name}.md`), content, "utf-8");
26707
27568
  }
26708
27569
  async generateDomainAgent(name, agentsPath, stats, stack) {
26709
27570
  let content = "";
26710
27571
  try {
26711
- const templatePath = path55.join(
27572
+ const templatePath = path58.join(
26712
27573
  __dirname,
26713
27574
  "..",
26714
27575
  "..",
@@ -26717,7 +27578,7 @@ var init_sync_service = __esm({
26717
27578
  "domain",
26718
27579
  `${name}.md`
26719
27580
  );
26720
- content = await fs52.readFile(templatePath, "utf-8");
27581
+ content = await fs55.readFile(templatePath, "utf-8");
26721
27582
  content = await this.resolveTemplateIncludes(content);
26722
27583
  content = content.replace("{projectName}", stats.name);
26723
27584
  content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
@@ -26729,7 +27590,7 @@ var init_sync_service = __esm({
26729
27590
  });
26730
27591
  content = this.generateMinimalDomainAgent(name, stats, stack);
26731
27592
  }
26732
- await fs52.writeFile(path55.join(agentsPath, `${name}.md`), content, "utf-8");
27593
+ await fs55.writeFile(path58.join(agentsPath, `${name}.md`), content, "utf-8");
26733
27594
  }
26734
27595
  generateMinimalWorkflowAgent(name) {
26735
27596
  const descriptions = {
@@ -26797,8 +27658,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
26797
27658
  })),
26798
27659
  agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
26799
27660
  };
26800
- fs52.writeFile(
26801
- path55.join(this.globalPath, "config", "skills.json"),
27661
+ fs55.writeFile(
27662
+ path58.join(this.globalPath, "config", "skills.json"),
26802
27663
  JSON.stringify(skillsConfig, null, 2),
26803
27664
  "utf-8"
26804
27665
  ).catch((error) => {
@@ -26816,7 +27677,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
26816
27677
  async autoInstallSkills(agents) {
26817
27678
  const results = [];
26818
27679
  try {
26819
- const mappingsPath = path55.join(
27680
+ const mappingsPath = path58.join(
26820
27681
  __dirname,
26821
27682
  "..",
26822
27683
  "..",
@@ -26824,7 +27685,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
26824
27685
  "config",
26825
27686
  "skill-mappings.json"
26826
27687
  );
26827
- const mappingsContent = await fs52.readFile(mappingsPath, "utf-8");
27688
+ const mappingsContent = await fs55.readFile(mappingsPath, "utf-8");
26828
27689
  const mappings = JSON.parse(mappingsContent);
26829
27690
  const agentToSkillMap = mappings.agentToSkillMap || {};
26830
27691
  const packagesToInstall = [];
@@ -26837,18 +27698,18 @@ You are the ${name} expert for this project. Apply best practices for the detect
26837
27698
  }
26838
27699
  }
26839
27700
  if (packagesToInstall.length === 0) return results;
26840
- const skillsDir = path55.join(os16.homedir(), ".claude", "skills");
27701
+ const skillsDir = path58.join(os16.homedir(), ".claude", "skills");
26841
27702
  for (const { pkg, agent } of packagesToInstall) {
26842
27703
  const skillName = pkg.split("/").pop() || pkg;
26843
- const subdirPath = path55.join(skillsDir, skillName, "SKILL.md");
26844
- const flatPath = path55.join(skillsDir, `${skillName}.md`);
27704
+ const subdirPath = path58.join(skillsDir, skillName, "SKILL.md");
27705
+ const flatPath = path58.join(skillsDir, `${skillName}.md`);
26845
27706
  let alreadyInstalled = false;
26846
27707
  try {
26847
- await fs52.access(subdirPath);
27708
+ await fs55.access(subdirPath);
26848
27709
  alreadyInstalled = true;
26849
27710
  } catch {
26850
27711
  try {
26851
- await fs52.access(flatPath);
27712
+ await fs55.access(flatPath);
26852
27713
  alreadyInstalled = true;
26853
27714
  } catch {
26854
27715
  }
@@ -26900,10 +27761,10 @@ You are the ${name} expert for this project. Apply best practices for the detect
26900
27761
  // PROJECT.JSON UPDATE
26901
27762
  // ==========================================================================
26902
27763
  async updateProjectJson(git, stats) {
26903
- const projectJsonPath = path55.join(this.globalPath, "project.json");
27764
+ const projectJsonPath = path58.join(this.globalPath, "project.json");
26904
27765
  let existing = {};
26905
27766
  try {
26906
- existing = JSON.parse(await fs52.readFile(projectJsonPath, "utf-8"));
27767
+ existing = JSON.parse(await fs55.readFile(projectJsonPath, "utf-8"));
26907
27768
  } catch (error) {
26908
27769
  logger_default.debug("No existing project.json", {
26909
27770
  path: projectJsonPath,
@@ -26929,16 +27790,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
26929
27790
  lastSyncCommit: git.recentCommits[0]?.hash || null,
26930
27791
  lastSyncBranch: git.branch
26931
27792
  };
26932
- await fs52.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
27793
+ await fs55.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
26933
27794
  }
26934
27795
  // ==========================================================================
26935
27796
  // STATE.JSON UPDATE
26936
27797
  // ==========================================================================
26937
27798
  async updateStateJson(stats, stack) {
26938
- const statePath = path55.join(this.globalPath, "storage", "state.json");
27799
+ const statePath = path58.join(this.globalPath, "storage", "state.json");
26939
27800
  let state = {};
26940
27801
  try {
26941
- state = JSON.parse(await fs52.readFile(statePath, "utf-8"));
27802
+ state = JSON.parse(await fs55.readFile(statePath, "utf-8"));
26942
27803
  } catch (error) {
26943
27804
  logger_default.debug("No existing state.json", { path: statePath, error: getErrorMessage(error) });
26944
27805
  }
@@ -26966,7 +27827,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
26966
27827
  lastAction: "Synced project",
26967
27828
  nextAction: 'Run `p. task "description"` to start working'
26968
27829
  };
26969
- await fs52.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
27830
+ await fs55.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
26970
27831
  try {
26971
27832
  await localStateGenerator.generate(
26972
27833
  this.projectPath,
@@ -26980,7 +27841,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
26980
27841
  // MEMORY LOGGING
26981
27842
  // ==========================================================================
26982
27843
  async logToMemory(git, stats) {
26983
- const memoryPath = path55.join(this.globalPath, "memory", "events.jsonl");
27844
+ const memoryPath = path58.join(this.globalPath, "memory", "events.jsonl");
26984
27845
  const event = {
26985
27846
  ts: getTimestamp(),
26986
27847
  action: "sync",
@@ -26989,7 +27850,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
26989
27850
  fileCount: stats.fileCount,
26990
27851
  commitCount: git.commits
26991
27852
  };
26992
- await fs52.appendFile(memoryPath, `${JSON.stringify(event)}
27853
+ await fs55.appendFile(memoryPath, `${JSON.stringify(event)}
26993
27854
  `, "utf-8");
26994
27855
  }
26995
27856
  // ==========================================================================
@@ -27009,8 +27870,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
27009
27870
  let filteredChars = 0;
27010
27871
  for (const file of contextFiles) {
27011
27872
  try {
27012
- const filePath = path55.join(this.globalPath, file);
27013
- const content = await fs52.readFile(filePath, "utf-8");
27873
+ const filePath = path58.join(this.globalPath, file);
27874
+ const content = await fs55.readFile(filePath, "utf-8");
27014
27875
  filteredChars += content.length;
27015
27876
  } catch (error) {
27016
27877
  logger_default.debug("Context file not found for metrics", { file, error: getErrorMessage(error) });
@@ -27018,8 +27879,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
27018
27879
  }
27019
27880
  for (const agent of agents) {
27020
27881
  try {
27021
- const agentPath = path55.join(this.globalPath, "agents", `${agent.name}.md`);
27022
- const content = await fs52.readFile(agentPath, "utf-8");
27882
+ const agentPath = path58.join(this.globalPath, "agents", `${agent.name}.md`);
27883
+ const content = await fs55.readFile(agentPath, "utf-8");
27023
27884
  filteredChars += content.length;
27024
27885
  } catch (error) {
27025
27886
  logger_default.debug("Agent file not found for metrics", {
@@ -27081,7 +27942,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
27081
27942
  // ==========================================================================
27082
27943
  async fileExists(filename) {
27083
27944
  try {
27084
- await fs52.access(path55.join(this.projectPath, filename));
27945
+ await fs55.access(path58.join(this.projectPath, filename));
27085
27946
  return true;
27086
27947
  } catch (error) {
27087
27948
  logger_default.debug("File not found", { filename, error: getErrorMessage(error) });
@@ -27090,8 +27951,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
27090
27951
  }
27091
27952
  async getCliVersion() {
27092
27953
  try {
27093
- const pkgPath = path55.join(__dirname, "..", "..", "package.json");
27094
- const pkg = JSON.parse(await fs52.readFile(pkgPath, "utf-8"));
27954
+ const pkgPath = path58.join(__dirname, "..", "..", "package.json");
27955
+ const pkg = JSON.parse(await fs55.readFile(pkgPath, "utf-8"));
27095
27956
  return pkg.version || "0.0.0";
27096
27957
  } catch (error) {
27097
27958
  logger_default.debug("Failed to read CLI version", { error: getErrorMessage(error) });
@@ -27252,22 +28113,22 @@ __export(uninstall_exports, {
27252
28113
  uninstall: () => uninstall
27253
28114
  });
27254
28115
  import { execSync as execSync3 } from "node:child_process";
27255
- import fs53 from "node:fs/promises";
28116
+ import fs56 from "node:fs/promises";
27256
28117
  import os17 from "node:os";
27257
- import path56 from "node:path";
28118
+ import path59 from "node:path";
27258
28119
  import readline2 from "node:readline";
27259
28120
  import chalk12 from "chalk";
27260
28121
  async function getDirectorySize(dirPath) {
27261
28122
  let totalSize = 0;
27262
28123
  try {
27263
- const entries = await fs53.readdir(dirPath, { withFileTypes: true });
28124
+ const entries = await fs56.readdir(dirPath, { withFileTypes: true });
27264
28125
  for (const entry of entries) {
27265
- const entryPath = path56.join(dirPath, entry.name);
28126
+ const entryPath = path59.join(dirPath, entry.name);
27266
28127
  if (entry.isDirectory()) {
27267
28128
  totalSize += await getDirectorySize(entryPath);
27268
28129
  } else {
27269
28130
  try {
27270
- const stats = await fs53.stat(entryPath);
28131
+ const stats = await fs56.stat(entryPath);
27271
28132
  totalSize += stats.size;
27272
28133
  } catch {
27273
28134
  }
@@ -27286,7 +28147,7 @@ function formatSize(bytes) {
27286
28147
  }
27287
28148
  async function countDirectoryItems(dirPath) {
27288
28149
  try {
27289
- const entries = await fs53.readdir(dirPath, { withFileTypes: true });
28150
+ const entries = await fs56.readdir(dirPath, { withFileTypes: true });
27290
28151
  return entries.filter((e) => e.isDirectory()).length;
27291
28152
  } catch {
27292
28153
  return 0;
@@ -27319,7 +28180,7 @@ async function gatherUninstallItems() {
27319
28180
  const providerPaths = getProviderPaths();
27320
28181
  const prjctCliPath = path_manager_default.getGlobalBasePath();
27321
28182
  const prjctCliExists = await fileExists(prjctCliPath);
27322
- const projectCount = prjctCliExists ? await countDirectoryItems(path56.join(prjctCliPath, "projects")) : 0;
28183
+ const projectCount = prjctCliExists ? await countDirectoryItems(path59.join(prjctCliPath, "projects")) : 0;
27323
28184
  const prjctCliSize = prjctCliExists ? await getDirectorySize(prjctCliPath) : 0;
27324
28185
  items.push({
27325
28186
  path: prjctCliPath,
@@ -27329,12 +28190,12 @@ async function gatherUninstallItems() {
27329
28190
  count: projectCount,
27330
28191
  exists: prjctCliExists
27331
28192
  });
27332
- const claudeMdPath = path56.join(providerPaths.claude.config, "CLAUDE.md");
28193
+ const claudeMdPath = path59.join(providerPaths.claude.config, "CLAUDE.md");
27333
28194
  const claudeMdExists = await fileExists(claudeMdPath);
27334
28195
  let hasPrjctSection = false;
27335
28196
  if (claudeMdExists) {
27336
28197
  try {
27337
- const content = await fs53.readFile(claudeMdPath, "utf-8");
28198
+ const content = await fs56.readFile(claudeMdPath, "utf-8");
27338
28199
  hasPrjctSection = content.includes(PRJCT_START_MARKER) && content.includes(PRJCT_END_MARKER);
27339
28200
  } catch {
27340
28201
  }
@@ -27363,7 +28224,7 @@ async function gatherUninstallItems() {
27363
28224
  description: "Claude router",
27364
28225
  exists: claudeRouterExists
27365
28226
  });
27366
- const statusLinePath = path56.join(providerPaths.claude.config, "prjct-statusline.sh");
28227
+ const statusLinePath = path59.join(providerPaths.claude.config, "prjct-statusline.sh");
27367
28228
  const statusLineExists = await fileExists(statusLinePath);
27368
28229
  items.push({
27369
28230
  path: statusLinePath,
@@ -27379,12 +28240,12 @@ async function gatherUninstallItems() {
27379
28240
  description: "Gemini router",
27380
28241
  exists: geminiRouterExists
27381
28242
  });
27382
- const geminiMdPath = path56.join(providerPaths.gemini.config, "GEMINI.md");
28243
+ const geminiMdPath = path59.join(providerPaths.gemini.config, "GEMINI.md");
27383
28244
  const geminiMdExists = await fileExists(geminiMdPath);
27384
28245
  let hasGeminiPrjctSection = false;
27385
28246
  if (geminiMdExists) {
27386
28247
  try {
27387
- const content = await fs53.readFile(geminiMdPath, "utf-8");
28248
+ const content = await fs56.readFile(geminiMdPath, "utf-8");
27388
28249
  hasGeminiPrjctSection = content.includes(PRJCT_START_MARKER) && content.includes(PRJCT_END_MARKER);
27389
28250
  } catch {
27390
28251
  }
@@ -27401,7 +28262,7 @@ async function gatherUninstallItems() {
27401
28262
  }
27402
28263
  async function removePrjctSection(filePath) {
27403
28264
  try {
27404
- const content = await fs53.readFile(filePath, "utf-8");
28265
+ const content = await fs56.readFile(filePath, "utf-8");
27405
28266
  if (!content.includes(PRJCT_START_MARKER) || !content.includes(PRJCT_END_MARKER)) {
27406
28267
  return false;
27407
28268
  }
@@ -27410,9 +28271,9 @@ async function removePrjctSection(filePath) {
27410
28271
  let newContent = content.substring(0, startIndex) + content.substring(endIndex);
27411
28272
  newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
27412
28273
  if (!newContent || newContent.trim().length === 0) {
27413
- await fs53.unlink(filePath);
28274
+ await fs56.unlink(filePath);
27414
28275
  } else {
27415
- await fs53.writeFile(filePath, `${newContent}
28276
+ await fs56.writeFile(filePath, `${newContent}
27416
28277
  `, "utf-8");
27417
28278
  }
27418
28279
  return true;
@@ -27423,12 +28284,12 @@ async function removePrjctSection(filePath) {
27423
28284
  async function createBackup3() {
27424
28285
  const homeDir = os17.homedir();
27425
28286
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
27426
- const backupDir = path56.join(homeDir, `.prjct-backup-${timestamp}`);
28287
+ const backupDir = path59.join(homeDir, `.prjct-backup-${timestamp}`);
27427
28288
  try {
27428
- await fs53.mkdir(backupDir, { recursive: true });
28289
+ await fs56.mkdir(backupDir, { recursive: true });
27429
28290
  const prjctCliPath = path_manager_default.getGlobalBasePath();
27430
28291
  if (await fileExists(prjctCliPath)) {
27431
- await copyDirectory(prjctCliPath, path56.join(backupDir, ".prjct-cli"));
28292
+ await copyDirectory(prjctCliPath, path59.join(backupDir, ".prjct-cli"));
27432
28293
  }
27433
28294
  return backupDir;
27434
28295
  } catch {
@@ -27436,15 +28297,15 @@ async function createBackup3() {
27436
28297
  }
27437
28298
  }
27438
28299
  async function copyDirectory(src, dest) {
27439
- await fs53.mkdir(dest, { recursive: true });
27440
- const entries = await fs53.readdir(src, { withFileTypes: true });
28300
+ await fs56.mkdir(dest, { recursive: true });
28301
+ const entries = await fs56.readdir(src, { withFileTypes: true });
27441
28302
  for (const entry of entries) {
27442
- const srcPath = path56.join(src, entry.name);
27443
- const destPath = path56.join(dest, entry.name);
28303
+ const srcPath = path59.join(src, entry.name);
28304
+ const destPath = path59.join(dest, entry.name);
27444
28305
  if (entry.isDirectory()) {
27445
28306
  await copyDirectory(srcPath, destPath);
27446
28307
  } else {
27447
- await fs53.copyFile(srcPath, destPath);
28308
+ await fs56.copyFile(srcPath, destPath);
27448
28309
  }
27449
28310
  }
27450
28311
  }
@@ -27460,10 +28321,10 @@ async function performUninstall(items, installation, options) {
27460
28321
  deleted.push(item.path);
27461
28322
  }
27462
28323
  } else if (item.type === "directory") {
27463
- await fs53.rm(item.path, { recursive: true, force: true });
28324
+ await fs56.rm(item.path, { recursive: true, force: true });
27464
28325
  deleted.push(item.path);
27465
28326
  } else if (item.type === "file") {
27466
- await fs53.unlink(item.path);
28327
+ await fs56.unlink(item.path);
27467
28328
  deleted.push(item.path);
27468
28329
  }
27469
28330
  } catch (error) {
@@ -27640,7 +28501,7 @@ __export(watch_service_exports, {
27640
28501
  WatchService: () => WatchService,
27641
28502
  watchService: () => watchService
27642
28503
  });
27643
- import path57 from "node:path";
28504
+ import path60 from "node:path";
27644
28505
  import chalk13 from "chalk";
27645
28506
  import chokidar from "chokidar";
27646
28507
  var TRIGGER_PATTERNS, IGNORE_PATTERNS2, WatchService, watchService;
@@ -27829,7 +28690,7 @@ ${chalk13.dim(`[${timestamp}]`)} ${chalk13.cyan("\u27F3")} ${filesSummary} chang
27829
28690
  );
27830
28691
  }
27831
28692
  try {
27832
- const result = await syncService.sync(this.projectPath);
28693
+ const result = await syncService.sync(this.projectPath, { changedFiles });
27833
28694
  this.lastSyncTime = Date.now();
27834
28695
  this.syncCount++;
27835
28696
  if (result.success) {
@@ -27861,7 +28722,7 @@ ${chalk13.dim(`[${timestamp}]`)} ${chalk13.cyan("\u27F3")} ${filesSummary} chang
27861
28722
  printStartup() {
27862
28723
  console.log("");
27863
28724
  console.log(chalk13.cyan("\u{1F441}\uFE0F Watching for changes..."));
27864
- console.log(chalk13.dim(` Project: ${path57.basename(this.projectPath)}`));
28725
+ console.log(chalk13.dim(` Project: ${path60.basename(this.projectPath)}`));
27865
28726
  console.log(chalk13.dim(` Debounce: ${this.options.debounceMs}ms`));
27866
28727
  console.log(chalk13.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
27867
28728
  console.log("");
@@ -28034,11 +28895,13 @@ var init_command_data = __esm({
28034
28895
  name: "sync",
28035
28896
  group: "core",
28036
28897
  description: "Sync project state and update workflow agents",
28037
- usage: { claude: "/p:sync", terminal: "prjct sync [--package=<name>]" },
28898
+ usage: { claude: "/p:sync", terminal: "prjct sync [--package=<name>] [--full]" },
28038
28899
  implemented: true,
28039
28900
  hasTemplate: true,
28040
28901
  requiresProject: true,
28041
28902
  features: [
28903
+ "Incremental sync: only re-analyzes changed files (default)",
28904
+ "Force full sync: --full bypasses incremental cache",
28042
28905
  "Monorepo support: --package=<name> for single package sync",
28043
28906
  "Nested PRJCT.md inheritance",
28044
28907
  "Per-package CLAUDE.md generation"
@@ -28592,9 +29455,9 @@ __export(setup_exports, {
28592
29455
  run: () => run
28593
29456
  });
28594
29457
  import { execSync as execSync4 } from "node:child_process";
28595
- import fs54 from "node:fs/promises";
29458
+ import fs57 from "node:fs/promises";
28596
29459
  import os18 from "node:os";
28597
- import path58 from "node:path";
29460
+ import path61 from "node:path";
28598
29461
  import chalk15 from "chalk";
28599
29462
  async function installAICLI(provider) {
28600
29463
  const packageName = provider.name === "claude" ? "@anthropic-ai/claude-code" : "@google/gemini-cli";
@@ -28733,12 +29596,12 @@ async function run() {
28733
29596
  }
28734
29597
  async function installGeminiRouter() {
28735
29598
  try {
28736
- const geminiCommandsDir = path58.join(os18.homedir(), ".gemini", "commands");
28737
- const routerSource = path58.join(PACKAGE_ROOT, "templates", "commands", "p.toml");
28738
- const routerDest = path58.join(geminiCommandsDir, "p.toml");
28739
- await fs54.mkdir(geminiCommandsDir, { recursive: true });
29599
+ const geminiCommandsDir = path61.join(os18.homedir(), ".gemini", "commands");
29600
+ const routerSource = path61.join(PACKAGE_ROOT, "templates", "commands", "p.toml");
29601
+ const routerDest = path61.join(geminiCommandsDir, "p.toml");
29602
+ await fs57.mkdir(geminiCommandsDir, { recursive: true });
28740
29603
  if (await fileExists(routerSource)) {
28741
- await fs54.copyFile(routerSource, routerDest);
29604
+ await fs57.copyFile(routerSource, routerDest);
28742
29605
  return true;
28743
29606
  }
28744
29607
  return false;
@@ -28749,15 +29612,15 @@ async function installGeminiRouter() {
28749
29612
  }
28750
29613
  async function installGeminiGlobalConfig() {
28751
29614
  try {
28752
- const geminiDir = path58.join(os18.homedir(), ".gemini");
28753
- const globalConfigPath = path58.join(geminiDir, "GEMINI.md");
28754
- const templatePath = path58.join(PACKAGE_ROOT, "templates", "global", "GEMINI.md");
28755
- await fs54.mkdir(geminiDir, { recursive: true });
28756
- const templateContent = await fs54.readFile(templatePath, "utf-8");
29615
+ const geminiDir = path61.join(os18.homedir(), ".gemini");
29616
+ const globalConfigPath = path61.join(geminiDir, "GEMINI.md");
29617
+ const templatePath = path61.join(PACKAGE_ROOT, "templates", "global", "GEMINI.md");
29618
+ await fs57.mkdir(geminiDir, { recursive: true });
29619
+ const templateContent = await fs57.readFile(templatePath, "utf-8");
28757
29620
  let existingContent = "";
28758
29621
  let configExists = false;
28759
29622
  try {
28760
- existingContent = await fs54.readFile(globalConfigPath, "utf-8");
29623
+ existingContent = await fs57.readFile(globalConfigPath, "utf-8");
28761
29624
  configExists = true;
28762
29625
  } catch (error) {
28763
29626
  if (isNotFoundError(error)) {
@@ -28767,7 +29630,7 @@ async function installGeminiGlobalConfig() {
28767
29630
  }
28768
29631
  }
28769
29632
  if (!configExists) {
28770
- await fs54.writeFile(globalConfigPath, templateContent, "utf-8");
29633
+ await fs57.writeFile(globalConfigPath, templateContent, "utf-8");
28771
29634
  return { success: true, action: "created" };
28772
29635
  }
28773
29636
  const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
@@ -28777,7 +29640,7 @@ async function installGeminiGlobalConfig() {
28777
29640
  const updatedContent2 = `${existingContent}
28778
29641
 
28779
29642
  ${templateContent}`;
28780
- await fs54.writeFile(globalConfigPath, updatedContent2, "utf-8");
29643
+ await fs57.writeFile(globalConfigPath, updatedContent2, "utf-8");
28781
29644
  return { success: true, action: "appended" };
28782
29645
  }
28783
29646
  const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
@@ -28789,7 +29652,7 @@ ${templateContent}`;
28789
29652
  templateContent.indexOf(endMarker) + endMarker.length
28790
29653
  );
28791
29654
  const updatedContent = beforeMarker + prjctSection + afterMarker;
28792
- await fs54.writeFile(globalConfigPath, updatedContent, "utf-8");
29655
+ await fs57.writeFile(globalConfigPath, updatedContent, "utf-8");
28793
29656
  return { success: true, action: "updated" };
28794
29657
  } catch (error) {
28795
29658
  logger_default.warn(`Gemini config warning: ${getErrorMessage2(error)}`);
@@ -28798,18 +29661,18 @@ ${templateContent}`;
28798
29661
  }
28799
29662
  async function installAntigravitySkill() {
28800
29663
  try {
28801
- const antigravitySkillsDir = path58.join(os18.homedir(), ".gemini", "antigravity", "skills");
28802
- const prjctSkillDir = path58.join(antigravitySkillsDir, "prjct");
28803
- const skillMdPath = path58.join(prjctSkillDir, "SKILL.md");
28804
- const templatePath = path58.join(PACKAGE_ROOT, "templates", "antigravity", "SKILL.md");
28805
- await fs54.mkdir(prjctSkillDir, { recursive: true });
29664
+ const antigravitySkillsDir = path61.join(os18.homedir(), ".gemini", "antigravity", "skills");
29665
+ const prjctSkillDir = path61.join(antigravitySkillsDir, "prjct");
29666
+ const skillMdPath = path61.join(prjctSkillDir, "SKILL.md");
29667
+ const templatePath = path61.join(PACKAGE_ROOT, "templates", "antigravity", "SKILL.md");
29668
+ await fs57.mkdir(prjctSkillDir, { recursive: true });
28806
29669
  const skillExists = await fileExists(skillMdPath);
28807
29670
  if (!await fileExists(templatePath)) {
28808
29671
  logger_default.warn("Antigravity SKILL.md template not found");
28809
29672
  return { success: false, action: null };
28810
29673
  }
28811
- const templateContent = await fs54.readFile(templatePath, "utf-8");
28812
- await fs54.writeFile(skillMdPath, templateContent, "utf-8");
29674
+ const templateContent = await fs57.readFile(templatePath, "utf-8");
29675
+ await fs57.writeFile(skillMdPath, templateContent, "utf-8");
28813
29676
  return { success: true, action: skillExists ? "updated" : "created" };
28814
29677
  } catch (error) {
28815
29678
  logger_default.warn(`Antigravity skill warning: ${getErrorMessage2(error)}`);
@@ -28828,24 +29691,24 @@ async function installCursorProject(projectRoot) {
28828
29691
  gitignoreUpdated: false
28829
29692
  };
28830
29693
  try {
28831
- const cursorDir = path58.join(projectRoot, ".cursor");
28832
- const rulesDir = path58.join(cursorDir, "rules");
28833
- const commandsDir = path58.join(cursorDir, "commands");
28834
- const routerMdcDest = path58.join(rulesDir, "prjct.mdc");
28835
- const routerMdcSource = path58.join(PACKAGE_ROOT, "templates", "cursor", "router.mdc");
28836
- const cursorCommandsSource = path58.join(PACKAGE_ROOT, "templates", "cursor", "commands");
28837
- await fs54.mkdir(rulesDir, { recursive: true });
28838
- await fs54.mkdir(commandsDir, { recursive: true });
29694
+ const cursorDir = path61.join(projectRoot, ".cursor");
29695
+ const rulesDir = path61.join(cursorDir, "rules");
29696
+ const commandsDir = path61.join(cursorDir, "commands");
29697
+ const routerMdcDest = path61.join(rulesDir, "prjct.mdc");
29698
+ const routerMdcSource = path61.join(PACKAGE_ROOT, "templates", "cursor", "router.mdc");
29699
+ const cursorCommandsSource = path61.join(PACKAGE_ROOT, "templates", "cursor", "commands");
29700
+ await fs57.mkdir(rulesDir, { recursive: true });
29701
+ await fs57.mkdir(commandsDir, { recursive: true });
28839
29702
  if (await fileExists(routerMdcSource)) {
28840
- await fs54.copyFile(routerMdcSource, routerMdcDest);
29703
+ await fs57.copyFile(routerMdcSource, routerMdcDest);
28841
29704
  result.rulesCreated = true;
28842
29705
  }
28843
29706
  if (await fileExists(cursorCommandsSource)) {
28844
- const commandFiles = (await fs54.readdir(cursorCommandsSource)).filter((f) => f.endsWith(".md"));
29707
+ const commandFiles = (await fs57.readdir(cursorCommandsSource)).filter((f) => f.endsWith(".md"));
28845
29708
  for (const file of commandFiles) {
28846
- const src = path58.join(cursorCommandsSource, file);
28847
- const dest = path58.join(commandsDir, file);
28848
- await fs54.copyFile(src, dest);
29709
+ const src = path61.join(cursorCommandsSource, file);
29710
+ const dest = path61.join(commandsDir, file);
29711
+ await fs57.copyFile(src, dest);
28849
29712
  }
28850
29713
  result.commandsCreated = commandFiles.length > 0;
28851
29714
  }
@@ -28859,7 +29722,7 @@ async function installCursorProject(projectRoot) {
28859
29722
  }
28860
29723
  async function addCursorToGitignore(projectRoot) {
28861
29724
  try {
28862
- const gitignorePath = path58.join(projectRoot, ".gitignore");
29725
+ const gitignorePath = path61.join(projectRoot, ".gitignore");
28863
29726
  const entriesToAdd = [
28864
29727
  "# prjct Cursor routers (regenerated per-developer)",
28865
29728
  ".cursor/rules/prjct.mdc",
@@ -28874,7 +29737,7 @@ async function addCursorToGitignore(projectRoot) {
28874
29737
  let content = "";
28875
29738
  let configExists = false;
28876
29739
  try {
28877
- content = await fs54.readFile(gitignorePath, "utf-8");
29740
+ content = await fs57.readFile(gitignorePath, "utf-8");
28878
29741
  configExists = true;
28879
29742
  } catch (error) {
28880
29743
  if (!isNotFoundError(error)) {
@@ -28889,7 +29752,7 @@ async function addCursorToGitignore(projectRoot) {
28889
29752
  ${entriesToAdd.join("\n")}
28890
29753
  ` : `${entriesToAdd.join("\n")}
28891
29754
  `;
28892
- await fs54.writeFile(gitignorePath, newContent, "utf-8");
29755
+ await fs57.writeFile(gitignorePath, newContent, "utf-8");
28893
29756
  return true;
28894
29757
  } catch (error) {
28895
29758
  logger_default.warn(`Gitignore update warning: ${getErrorMessage2(error)}`);
@@ -28897,11 +29760,11 @@ ${entriesToAdd.join("\n")}
28897
29760
  }
28898
29761
  }
28899
29762
  async function hasCursorProject(projectRoot) {
28900
- return await fileExists(path58.join(projectRoot, ".cursor"));
29763
+ return await fileExists(path61.join(projectRoot, ".cursor"));
28901
29764
  }
28902
29765
  async function needsCursorRegeneration(projectRoot) {
28903
- const cursorDir = path58.join(projectRoot, ".cursor");
28904
- const routerPath = path58.join(cursorDir, "rules", "prjct.mdc");
29766
+ const cursorDir = path61.join(projectRoot, ".cursor");
29767
+ const routerPath = path61.join(cursorDir, "rules", "prjct.mdc");
28905
29768
  return await fileExists(cursorDir) && !await fileExists(routerPath);
28906
29769
  }
28907
29770
  async function installWindsurfProject(projectRoot) {
@@ -28912,26 +29775,26 @@ async function installWindsurfProject(projectRoot) {
28912
29775
  gitignoreUpdated: false
28913
29776
  };
28914
29777
  try {
28915
- const windsurfDir = path58.join(projectRoot, ".windsurf");
28916
- const rulesDir = path58.join(windsurfDir, "rules");
28917
- const workflowsDir = path58.join(windsurfDir, "workflows");
28918
- const routerDest = path58.join(rulesDir, "prjct.md");
28919
- const routerSource = path58.join(PACKAGE_ROOT, "templates", "windsurf", "router.md");
28920
- const windsurfWorkflowsSource = path58.join(PACKAGE_ROOT, "templates", "windsurf", "workflows");
28921
- await fs54.mkdir(rulesDir, { recursive: true });
28922
- await fs54.mkdir(workflowsDir, { recursive: true });
29778
+ const windsurfDir = path61.join(projectRoot, ".windsurf");
29779
+ const rulesDir = path61.join(windsurfDir, "rules");
29780
+ const workflowsDir = path61.join(windsurfDir, "workflows");
29781
+ const routerDest = path61.join(rulesDir, "prjct.md");
29782
+ const routerSource = path61.join(PACKAGE_ROOT, "templates", "windsurf", "router.md");
29783
+ const windsurfWorkflowsSource = path61.join(PACKAGE_ROOT, "templates", "windsurf", "workflows");
29784
+ await fs57.mkdir(rulesDir, { recursive: true });
29785
+ await fs57.mkdir(workflowsDir, { recursive: true });
28923
29786
  if (await fileExists(routerSource)) {
28924
- await fs54.copyFile(routerSource, routerDest);
29787
+ await fs57.copyFile(routerSource, routerDest);
28925
29788
  result.rulesCreated = true;
28926
29789
  }
28927
29790
  if (await fileExists(windsurfWorkflowsSource)) {
28928
- const workflowFiles = (await fs54.readdir(windsurfWorkflowsSource)).filter(
29791
+ const workflowFiles = (await fs57.readdir(windsurfWorkflowsSource)).filter(
28929
29792
  (f) => f.endsWith(".md")
28930
29793
  );
28931
29794
  for (const file of workflowFiles) {
28932
- const src = path58.join(windsurfWorkflowsSource, file);
28933
- const dest = path58.join(workflowsDir, file);
28934
- await fs54.copyFile(src, dest);
29795
+ const src = path61.join(windsurfWorkflowsSource, file);
29796
+ const dest = path61.join(workflowsDir, file);
29797
+ await fs57.copyFile(src, dest);
28935
29798
  }
28936
29799
  result.workflowsCreated = workflowFiles.length > 0;
28937
29800
  }
@@ -28945,7 +29808,7 @@ async function installWindsurfProject(projectRoot) {
28945
29808
  }
28946
29809
  async function addWindsurfToGitignore(projectRoot) {
28947
29810
  try {
28948
- const gitignorePath = path58.join(projectRoot, ".gitignore");
29811
+ const gitignorePath = path61.join(projectRoot, ".gitignore");
28949
29812
  const entriesToAdd = [
28950
29813
  "# prjct Windsurf routers (regenerated per-developer)",
28951
29814
  ".windsurf/rules/prjct.md",
@@ -28960,7 +29823,7 @@ async function addWindsurfToGitignore(projectRoot) {
28960
29823
  let content = "";
28961
29824
  let configExists = false;
28962
29825
  try {
28963
- content = await fs54.readFile(gitignorePath, "utf-8");
29826
+ content = await fs57.readFile(gitignorePath, "utf-8");
28964
29827
  configExists = true;
28965
29828
  } catch (error) {
28966
29829
  if (!isNotFoundError(error)) {
@@ -28975,7 +29838,7 @@ async function addWindsurfToGitignore(projectRoot) {
28975
29838
  ${entriesToAdd.join("\n")}
28976
29839
  ` : `${entriesToAdd.join("\n")}
28977
29840
  `;
28978
- await fs54.writeFile(gitignorePath, newContent, "utf-8");
29841
+ await fs57.writeFile(gitignorePath, newContent, "utf-8");
28979
29842
  return true;
28980
29843
  } catch (error) {
28981
29844
  logger_default.warn(`Gitignore update warning: ${getErrorMessage2(error)}`);
@@ -28983,32 +29846,32 @@ ${entriesToAdd.join("\n")}
28983
29846
  }
28984
29847
  }
28985
29848
  async function hasWindsurfProject(projectRoot) {
28986
- return await fileExists(path58.join(projectRoot, ".windsurf"));
29849
+ return await fileExists(path61.join(projectRoot, ".windsurf"));
28987
29850
  }
28988
29851
  async function needsWindsurfRegeneration(projectRoot) {
28989
- const windsurfDir = path58.join(projectRoot, ".windsurf");
28990
- const routerPath = path58.join(windsurfDir, "rules", "prjct.md");
29852
+ const windsurfDir = path61.join(projectRoot, ".windsurf");
29853
+ const routerPath = path61.join(windsurfDir, "rules", "prjct.md");
28991
29854
  return await fileExists(windsurfDir) && !await fileExists(routerPath);
28992
29855
  }
28993
29856
  async function migrateProjectsCliVersion() {
28994
29857
  try {
28995
- const projectsDir = path58.join(os18.homedir(), ".prjct-cli", "projects");
29858
+ const projectsDir = path61.join(os18.homedir(), ".prjct-cli", "projects");
28996
29859
  if (!await fileExists(projectsDir)) {
28997
29860
  return;
28998
29861
  }
28999
- const projectDirs = (await fs54.readdir(projectsDir, { withFileTypes: true })).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
29862
+ const projectDirs = (await fs57.readdir(projectsDir, { withFileTypes: true })).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
29000
29863
  let migrated = 0;
29001
29864
  for (const projectId of projectDirs) {
29002
- const projectJsonPath = path58.join(projectsDir, projectId, "project.json");
29865
+ const projectJsonPath = path61.join(projectsDir, projectId, "project.json");
29003
29866
  if (!await fileExists(projectJsonPath)) {
29004
29867
  continue;
29005
29868
  }
29006
29869
  try {
29007
- const content = await fs54.readFile(projectJsonPath, "utf8");
29870
+ const content = await fs57.readFile(projectJsonPath, "utf8");
29008
29871
  const project = JSON.parse(content);
29009
29872
  if (project.cliVersion !== VERSION) {
29010
29873
  project.cliVersion = VERSION;
29011
- await fs54.writeFile(projectJsonPath, JSON.stringify(project, null, 2));
29874
+ await fs57.writeFile(projectJsonPath, JSON.stringify(project, null, 2));
29012
29875
  migrated++;
29013
29876
  }
29014
29877
  } catch (error) {
@@ -29030,7 +29893,7 @@ async function ensureStatusLineSettings(settingsPath, statusLinePath) {
29030
29893
  let settings = {};
29031
29894
  if (await fileExists(settingsPath)) {
29032
29895
  try {
29033
- settings = JSON.parse(await fs54.readFile(settingsPath, "utf8"));
29896
+ settings = JSON.parse(await fs57.readFile(settingsPath, "utf8"));
29034
29897
  } catch (error) {
29035
29898
  if (!(error instanceof SyntaxError)) {
29036
29899
  throw error;
@@ -29038,42 +29901,42 @@ async function ensureStatusLineSettings(settingsPath, statusLinePath) {
29038
29901
  }
29039
29902
  }
29040
29903
  settings.statusLine = { type: "command", command: statusLinePath };
29041
- await fs54.writeFile(settingsPath, JSON.stringify(settings, null, 2));
29904
+ await fs57.writeFile(settingsPath, JSON.stringify(settings, null, 2));
29042
29905
  }
29043
29906
  async function installStatusLine() {
29044
29907
  try {
29045
- const claudeDir = path58.join(os18.homedir(), ".claude");
29046
- const settingsPath = path58.join(claudeDir, "settings.json");
29047
- const claudeStatusLinePath = path58.join(claudeDir, "prjct-statusline.sh");
29048
- const prjctStatusLineDir = path58.join(os18.homedir(), ".prjct-cli", "statusline");
29049
- const prjctStatusLinePath = path58.join(prjctStatusLineDir, "statusline.sh");
29050
- const prjctThemesDir = path58.join(prjctStatusLineDir, "themes");
29051
- const prjctLibDir = path58.join(prjctStatusLineDir, "lib");
29052
- const prjctComponentsDir = path58.join(prjctStatusLineDir, "components");
29053
- const prjctConfigPath = path58.join(prjctStatusLineDir, "config.json");
29054
- const assetsDir = path58.join(PACKAGE_ROOT, "assets", "statusline");
29055
- const sourceScript = path58.join(assetsDir, "statusline.sh");
29056
- const sourceThemeDir = path58.join(assetsDir, "themes");
29057
- const sourceLibDir = path58.join(assetsDir, "lib");
29058
- const sourceComponentsDir = path58.join(assetsDir, "components");
29059
- const sourceConfigPath = path58.join(assetsDir, "default-config.json");
29908
+ const claudeDir = path61.join(os18.homedir(), ".claude");
29909
+ const settingsPath = path61.join(claudeDir, "settings.json");
29910
+ const claudeStatusLinePath = path61.join(claudeDir, "prjct-statusline.sh");
29911
+ const prjctStatusLineDir = path61.join(os18.homedir(), ".prjct-cli", "statusline");
29912
+ const prjctStatusLinePath = path61.join(prjctStatusLineDir, "statusline.sh");
29913
+ const prjctThemesDir = path61.join(prjctStatusLineDir, "themes");
29914
+ const prjctLibDir = path61.join(prjctStatusLineDir, "lib");
29915
+ const prjctComponentsDir = path61.join(prjctStatusLineDir, "components");
29916
+ const prjctConfigPath = path61.join(prjctStatusLineDir, "config.json");
29917
+ const assetsDir = path61.join(PACKAGE_ROOT, "assets", "statusline");
29918
+ const sourceScript = path61.join(assetsDir, "statusline.sh");
29919
+ const sourceThemeDir = path61.join(assetsDir, "themes");
29920
+ const sourceLibDir = path61.join(assetsDir, "lib");
29921
+ const sourceComponentsDir = path61.join(assetsDir, "components");
29922
+ const sourceConfigPath = path61.join(assetsDir, "default-config.json");
29060
29923
  if (!await fileExists(claudeDir)) {
29061
- await fs54.mkdir(claudeDir, { recursive: true });
29924
+ await fs57.mkdir(claudeDir, { recursive: true });
29062
29925
  }
29063
29926
  if (!await fileExists(prjctStatusLineDir)) {
29064
- await fs54.mkdir(prjctStatusLineDir, { recursive: true });
29927
+ await fs57.mkdir(prjctStatusLineDir, { recursive: true });
29065
29928
  }
29066
29929
  if (!await fileExists(prjctThemesDir)) {
29067
- await fs54.mkdir(prjctThemesDir, { recursive: true });
29930
+ await fs57.mkdir(prjctThemesDir, { recursive: true });
29068
29931
  }
29069
29932
  if (!await fileExists(prjctLibDir)) {
29070
- await fs54.mkdir(prjctLibDir, { recursive: true });
29933
+ await fs57.mkdir(prjctLibDir, { recursive: true });
29071
29934
  }
29072
29935
  if (!await fileExists(prjctComponentsDir)) {
29073
- await fs54.mkdir(prjctComponentsDir, { recursive: true });
29936
+ await fs57.mkdir(prjctComponentsDir, { recursive: true });
29074
29937
  }
29075
29938
  if (await fileExists(prjctStatusLinePath)) {
29076
- const existingContent = await fs54.readFile(prjctStatusLinePath, "utf8");
29939
+ const existingContent = await fs57.readFile(prjctStatusLinePath, "utf8");
29077
29940
  if (existingContent.includes("CLI_VERSION=")) {
29078
29941
  const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
29079
29942
  if (versionMatch && versionMatch[1] !== VERSION) {
@@ -29081,7 +29944,7 @@ async function installStatusLine() {
29081
29944
  /CLI_VERSION="[^"]*"/,
29082
29945
  `CLI_VERSION="${VERSION}"`
29083
29946
  );
29084
- await fs54.writeFile(prjctStatusLinePath, updatedContent, { mode: 493 });
29947
+ await fs57.writeFile(prjctStatusLinePath, updatedContent, { mode: 493 });
29085
29948
  }
29086
29949
  await installStatusLineModules(sourceLibDir, prjctLibDir);
29087
29950
  await installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
@@ -29091,21 +29954,21 @@ async function installStatusLine() {
29091
29954
  }
29092
29955
  }
29093
29956
  if (await fileExists(sourceScript)) {
29094
- let scriptContent = await fs54.readFile(sourceScript, "utf8");
29957
+ let scriptContent = await fs57.readFile(sourceScript, "utf8");
29095
29958
  scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
29096
- await fs54.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
29959
+ await fs57.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
29097
29960
  await installStatusLineModules(sourceLibDir, prjctLibDir);
29098
29961
  await installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
29099
29962
  if (await fileExists(sourceThemeDir)) {
29100
- const themes = await fs54.readdir(sourceThemeDir);
29963
+ const themes = await fs57.readdir(sourceThemeDir);
29101
29964
  for (const theme of themes) {
29102
- const src = path58.join(sourceThemeDir, theme);
29103
- const dest = path58.join(prjctThemesDir, theme);
29104
- await fs54.copyFile(src, dest);
29965
+ const src = path61.join(sourceThemeDir, theme);
29966
+ const dest = path61.join(prjctThemesDir, theme);
29967
+ await fs57.copyFile(src, dest);
29105
29968
  }
29106
29969
  }
29107
29970
  if (!await fileExists(prjctConfigPath) && await fileExists(sourceConfigPath)) {
29108
- await fs54.copyFile(sourceConfigPath, prjctConfigPath);
29971
+ await fs57.copyFile(sourceConfigPath, prjctConfigPath);
29109
29972
  }
29110
29973
  } else {
29111
29974
  const scriptContent = `#!/bin/bash
@@ -29140,7 +30003,7 @@ if [ -f "$CONFIG" ]; then
29140
30003
  fi
29141
30004
  echo "prjct"
29142
30005
  `;
29143
- await fs54.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
30006
+ await fs57.writeFile(prjctStatusLinePath, scriptContent, { mode: 493 });
29144
30007
  }
29145
30008
  await ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
29146
30009
  await ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
@@ -29152,10 +30015,10 @@ echo "prjct"
29152
30015
  }
29153
30016
  async function installContext7MCP() {
29154
30017
  try {
29155
- const claudeDir = path58.join(os18.homedir(), ".claude");
29156
- const mcpConfigPath = path58.join(claudeDir, "mcp.json");
30018
+ const claudeDir = path61.join(os18.homedir(), ".claude");
30019
+ const mcpConfigPath = path61.join(claudeDir, "mcp.json");
29157
30020
  if (!await fileExists(claudeDir)) {
29158
- await fs54.mkdir(claudeDir, { recursive: true });
30021
+ await fs57.mkdir(claudeDir, { recursive: true });
29159
30022
  }
29160
30023
  const context7Config = {
29161
30024
  mcpServers: {
@@ -29166,16 +30029,16 @@ async function installContext7MCP() {
29166
30029
  }
29167
30030
  };
29168
30031
  if (await fileExists(mcpConfigPath)) {
29169
- const existingContent = await fs54.readFile(mcpConfigPath, "utf-8");
30032
+ const existingContent = await fs57.readFile(mcpConfigPath, "utf-8");
29170
30033
  const existingConfig = JSON.parse(existingContent);
29171
30034
  if (existingConfig.mcpServers?.context7) {
29172
30035
  return;
29173
30036
  }
29174
30037
  existingConfig.mcpServers = existingConfig.mcpServers || {};
29175
30038
  existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
29176
- await fs54.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
30039
+ await fs57.writeFile(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
29177
30040
  } else {
29178
- await fs54.writeFile(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
30041
+ await fs57.writeFile(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
29179
30042
  }
29180
30043
  } catch (error) {
29181
30044
  logger_default.warn(`Context7 MCP setup warning: ${getErrorMessage2(error)}`);
@@ -29185,34 +30048,34 @@ async function installStatusLineModules(sourceDir, destDir) {
29185
30048
  if (!await fileExists(sourceDir)) {
29186
30049
  return;
29187
30050
  }
29188
- const files = await fs54.readdir(sourceDir);
30051
+ const files = await fs57.readdir(sourceDir);
29189
30052
  for (const file of files) {
29190
30053
  if (file.endsWith(".sh")) {
29191
- const src = path58.join(sourceDir, file);
29192
- const dest = path58.join(destDir, file);
29193
- await fs54.copyFile(src, dest);
29194
- await fs54.chmod(dest, 493);
30054
+ const src = path61.join(sourceDir, file);
30055
+ const dest = path61.join(destDir, file);
30056
+ await fs57.copyFile(src, dest);
30057
+ await fs57.chmod(dest, 493);
29195
30058
  }
29196
30059
  }
29197
30060
  }
29198
30061
  async function ensureStatusLineSymlink(linkPath, targetPath) {
29199
30062
  try {
29200
30063
  if (await fileExists(linkPath)) {
29201
- const stats = await fs54.lstat(linkPath);
30064
+ const stats = await fs57.lstat(linkPath);
29202
30065
  if (stats.isSymbolicLink()) {
29203
- const existingTarget = await fs54.readlink(linkPath);
30066
+ const existingTarget = await fs57.readlink(linkPath);
29204
30067
  if (existingTarget === targetPath) {
29205
30068
  return;
29206
30069
  }
29207
30070
  }
29208
- await fs54.unlink(linkPath);
30071
+ await fs57.unlink(linkPath);
29209
30072
  }
29210
- await fs54.symlink(targetPath, linkPath);
30073
+ await fs57.symlink(targetPath, linkPath);
29211
30074
  } catch (_error) {
29212
30075
  try {
29213
30076
  if (await fileExists(targetPath)) {
29214
- await fs54.copyFile(targetPath, linkPath);
29215
- await fs54.chmod(linkPath, 493);
30077
+ await fs57.copyFile(targetPath, linkPath);
30078
+ await fs57.chmod(linkPath, 493);
29216
30079
  }
29217
30080
  } catch (copyError) {
29218
30081
  if (!isNotFoundError(copyError)) {
@@ -29627,7 +30490,7 @@ var init_registry2 = __esm({
29627
30490
  });
29628
30491
 
29629
30492
  // core/commands/analytics.ts
29630
- import path59 from "node:path";
30493
+ import path62 from "node:path";
29631
30494
  var AnalyticsCommands;
29632
30495
  var init_analytics = __esm({
29633
30496
  "core/commands/analytics.ts"() {
@@ -29654,7 +30517,7 @@ var init_analytics = __esm({
29654
30517
  output_default.failWithHint("NO_PROJECT_ID");
29655
30518
  return { success: false, error: "No project ID found" };
29656
30519
  }
29657
- const projectName = path59.basename(projectPath);
30520
+ const projectName = path62.basename(projectPath);
29658
30521
  const currentTask = await stateStorage.getCurrentTask(projectId);
29659
30522
  const queueTasks = await queueStorage.getActiveTasks(projectId);
29660
30523
  const shipped = await shippedStorage.getRecent(projectId, 5);
@@ -29906,8 +30769,8 @@ ${"\u2550".repeat(50)}
29906
30769
  });
29907
30770
 
29908
30771
  // core/commands/context.ts
29909
- import fs55 from "node:fs/promises";
29910
- import path60 from "node:path";
30772
+ import fs58 from "node:fs/promises";
30773
+ import path63 from "node:path";
29911
30774
  var ContextCommands, contextCommands;
29912
30775
  var init_context = __esm({
29913
30776
  "core/commands/context.ts"() {
@@ -30033,8 +30896,8 @@ var init_context = __esm({
30033
30896
  */
30034
30897
  async loadRepoAnalysis(globalPath) {
30035
30898
  try {
30036
- const analysisPath = path60.join(globalPath, "analysis", "repo-analysis.json");
30037
- const content = await fs55.readFile(analysisPath, "utf-8");
30899
+ const analysisPath = path63.join(globalPath, "analysis", "repo-analysis.json");
30900
+ const content = await fs58.readFile(analysisPath, "utf-8");
30038
30901
  const data = JSON.parse(content);
30039
30902
  return {
30040
30903
  ecosystem: data.ecosystem || "unknown",
@@ -30053,7 +30916,7 @@ var init_context = __esm({
30053
30916
  });
30054
30917
 
30055
30918
  // core/commands/cleanup.ts
30056
- import path61 from "node:path";
30919
+ import path64 from "node:path";
30057
30920
  async function cleanupMemory(projectPath) {
30058
30921
  const projectId = await config_manager_default.getProjectId(projectPath);
30059
30922
  const results = { rotated: [], totalSize: 0, freedSpace: 0 };
@@ -30069,7 +30932,7 @@ async function cleanupMemory(projectPath) {
30069
30932
  results.totalSize += sizeMB;
30070
30933
  const rotated = await jsonl_helper_exports.rotateJsonLinesIfNeeded(filePath, 10);
30071
30934
  if (rotated) {
30072
- results.rotated.push(path61.basename(filePath));
30935
+ results.rotated.push(path64.basename(filePath));
30073
30936
  results.freedSpace += sizeMB;
30074
30937
  }
30075
30938
  }
@@ -30176,7 +31039,7 @@ var init_cleanup = __esm({
30176
31039
  });
30177
31040
 
30178
31041
  // core/commands/design.ts
30179
- import path62 from "node:path";
31042
+ import path65 from "node:path";
30180
31043
  async function design(target = null, options = {}, projectPath = process.cwd()) {
30181
31044
  try {
30182
31045
  const designType = options.type || "architecture";
@@ -30188,7 +31051,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
30188
31051
  const designTarget = target || "system";
30189
31052
  output_default.spin(`designing ${designType}...`);
30190
31053
  const projectId = await config_manager_default.getProjectId(projectPath);
30191
- const designsPath = path62.join(
31054
+ const designsPath = path65.join(
30192
31055
  path_manager_default.getGlobalProjectPath(projectId),
30193
31056
  "planning",
30194
31057
  "designs"
@@ -30228,7 +31091,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
30228
31091
  break;
30229
31092
  }
30230
31093
  const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
30231
- const designFilePath = path62.join(designsPath, designFileName);
31094
+ const designFilePath = path65.join(designsPath, designFileName);
30232
31095
  await file_helper_exports.writeFile(designFilePath, designContent);
30233
31096
  await memoryService.log(projectPath, "design_created", {
30234
31097
  type: designType,
@@ -30253,7 +31116,7 @@ var init_design = __esm({
30253
31116
  });
30254
31117
 
30255
31118
  // core/commands/snapshots.ts
30256
- import path63 from "node:path";
31119
+ import path66 from "node:path";
30257
31120
  async function recover(projectPath = process.cwd()) {
30258
31121
  try {
30259
31122
  const projectId = await config_manager_default.getProjectId(projectPath);
@@ -30305,7 +31168,7 @@ async function undo(projectPath = process.cwd()) {
30305
31168
  output_default.failWithHint("NO_PROJECT_ID");
30306
31169
  return { success: false, error: "No project ID found" };
30307
31170
  }
30308
- const snapshotsPath = path63.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
31171
+ const snapshotsPath = path66.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
30309
31172
  await file_helper_exports.ensureDir(snapshotsPath);
30310
31173
  const { execSync: execSync5 } = await import("node:child_process");
30311
31174
  try {
@@ -30323,7 +31186,7 @@ async function undo(projectPath = process.cwd()) {
30323
31186
  cwd: projectPath,
30324
31187
  encoding: "utf-8"
30325
31188
  });
30326
- const snapshotFile = path63.join(snapshotsPath, "history.json");
31189
+ const snapshotFile = path66.join(snapshotsPath, "history.json");
30327
31190
  let history2 = { snapshots: [], current: -1 };
30328
31191
  try {
30329
31192
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -30363,8 +31226,8 @@ async function redo(projectPath = process.cwd()) {
30363
31226
  output_default.failWithHint("NO_PROJECT_ID");
30364
31227
  return { success: false, error: "No project ID found" };
30365
31228
  }
30366
- const snapshotsPath = path63.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
30367
- const snapshotFile = path63.join(snapshotsPath, "history.json");
31229
+ const snapshotsPath = path66.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
31230
+ const snapshotFile = path66.join(snapshotsPath, "history.json");
30368
31231
  let history2;
30369
31232
  try {
30370
31233
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -30423,8 +31286,8 @@ async function history(projectPath = process.cwd()) {
30423
31286
  output_default.failWithHint("NO_PROJECT_ID");
30424
31287
  return { success: false, error: "No project ID found" };
30425
31288
  }
30426
- const snapshotsPath = path63.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
30427
- const snapshotFile = path63.join(snapshotsPath, "history.json");
31289
+ const snapshotsPath = path66.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
31290
+ const snapshotFile = path66.join(snapshotsPath, "history.json");
30428
31291
  let snapshotHistory;
30429
31292
  try {
30430
31293
  const content = await file_helper_exports.readFile(snapshotFile);
@@ -30627,8 +31490,8 @@ ${chalk16.cyan("Performance Report")} ${chalk16.dim(`(last ${days} days)`)}`);
30627
31490
  });
30628
31491
 
30629
31492
  // core/commands/setup.ts
30630
- import fs56 from "node:fs/promises";
30631
- import path64 from "node:path";
31493
+ import fs59 from "node:fs/promises";
31494
+ import path67 from "node:path";
30632
31495
  import chalk17 from "chalk";
30633
31496
  var SetupCommands;
30634
31497
  var init_setup2 = __esm({
@@ -30757,7 +31620,7 @@ Please install it first:
30757
31620
  try {
30758
31621
  const claudeDir = path_manager_default.getClaudeDir();
30759
31622
  const settingsPath = path_manager_default.getClaudeSettingsPath();
30760
- const statusLinePath = path64.join(claudeDir, "prjct-statusline.sh");
31623
+ const statusLinePath = path67.join(claudeDir, "prjct-statusline.sh");
30761
31624
  const scriptContent = `#!/bin/bash
30762
31625
  # prjct Status Line for Claude Code
30763
31626
  # Shows version update notifications and current task
@@ -30815,11 +31678,11 @@ fi
30815
31678
  # Default: show prjct branding
30816
31679
  echo "\u26A1 prjct"
30817
31680
  `;
30818
- await fs56.writeFile(statusLinePath, scriptContent, { mode: 493 });
31681
+ await fs59.writeFile(statusLinePath, scriptContent, { mode: 493 });
30819
31682
  let settings = {};
30820
31683
  if (await fileExists(settingsPath)) {
30821
31684
  try {
30822
- settings = JSON.parse(await fs56.readFile(settingsPath, "utf8"));
31685
+ settings = JSON.parse(await fs59.readFile(settingsPath, "utf8"));
30823
31686
  } catch (_error) {
30824
31687
  }
30825
31688
  }
@@ -30827,7 +31690,7 @@ echo "\u26A1 prjct"
30827
31690
  type: "command",
30828
31691
  command: statusLinePath
30829
31692
  };
30830
- await fs56.writeFile(settingsPath, JSON.stringify(settings, null, 2));
31693
+ await fs59.writeFile(settingsPath, JSON.stringify(settings, null, 2));
30831
31694
  return { success: true };
30832
31695
  } catch (error) {
30833
31696
  return { success: false, error: getErrorMessage2(error) };
@@ -30883,18 +31746,18 @@ echo "\u26A1 prjct"
30883
31746
  });
30884
31747
 
30885
31748
  // core/utils/project-commands.ts
30886
- import path65 from "node:path";
31749
+ import path68 from "node:path";
30887
31750
  async function detectPackageManager(projectPath, pkg) {
30888
31751
  const declared = pkg?.packageManager?.trim().toLowerCase();
30889
31752
  if (declared?.startsWith("pnpm@")) return "pnpm";
30890
31753
  if (declared?.startsWith("yarn@")) return "yarn";
30891
31754
  if (declared?.startsWith("bun@")) return "bun";
30892
31755
  if (declared?.startsWith("npm@")) return "npm";
30893
- if (await fileExists2(path65.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
30894
- if (await fileExists2(path65.join(projectPath, "yarn.lock"))) return "yarn";
30895
- if (await fileExists2(path65.join(projectPath, "bun.lockb"))) return "bun";
30896
- if (await fileExists2(path65.join(projectPath, "bun.lock"))) return "bun";
30897
- if (await fileExists2(path65.join(projectPath, "package-lock.json"))) return "npm";
31756
+ if (await fileExists2(path68.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
31757
+ if (await fileExists2(path68.join(projectPath, "yarn.lock"))) return "yarn";
31758
+ if (await fileExists2(path68.join(projectPath, "bun.lockb"))) return "bun";
31759
+ if (await fileExists2(path68.join(projectPath, "bun.lock"))) return "bun";
31760
+ if (await fileExists2(path68.join(projectPath, "package-lock.json"))) return "npm";
30898
31761
  return "npm";
30899
31762
  }
30900
31763
  function pmRun(pm, scriptName) {
@@ -30910,7 +31773,7 @@ function pmTest(pm) {
30910
31773
  return "npm test";
30911
31774
  }
30912
31775
  async function detectProjectCommands(projectPath) {
30913
- const pkgPath = path65.join(projectPath, "package.json");
31776
+ const pkgPath = path68.join(projectPath, "package.json");
30914
31777
  const pkg = await readJson(pkgPath, null);
30915
31778
  if (pkg) {
30916
31779
  const pm = await detectPackageManager(projectPath, pkg);
@@ -30927,27 +31790,27 @@ async function detectProjectCommands(projectPath) {
30927
31790
  }
30928
31791
  return result;
30929
31792
  }
30930
- if (await fileExists2(path65.join(projectPath, "pytest.ini"))) {
31793
+ if (await fileExists2(path68.join(projectPath, "pytest.ini"))) {
30931
31794
  return { stack: "python", test: { tool: "pytest", command: "pytest" } };
30932
31795
  }
30933
- const pyproject = await readFile(path65.join(projectPath, "pyproject.toml"), "");
31796
+ const pyproject = await readFile(path68.join(projectPath, "pyproject.toml"), "");
30934
31797
  if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
30935
31798
  return { stack: "python", test: { tool: "pytest", command: "pytest" } };
30936
31799
  }
30937
- if (await fileExists2(path65.join(projectPath, "Cargo.toml"))) {
31800
+ if (await fileExists2(path68.join(projectPath, "Cargo.toml"))) {
30938
31801
  return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
30939
31802
  }
30940
- if (await fileExists2(path65.join(projectPath, "go.mod"))) {
31803
+ if (await fileExists2(path68.join(projectPath, "go.mod"))) {
30941
31804
  return { stack: "go", test: { tool: "go", command: "go test ./..." } };
30942
31805
  }
30943
31806
  const files = await listFiles(projectPath);
30944
31807
  if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
30945
31808
  return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
30946
31809
  }
30947
- if (await fileExists2(path65.join(projectPath, "pom.xml"))) {
31810
+ if (await fileExists2(path68.join(projectPath, "pom.xml"))) {
30948
31811
  return { stack: "java", test: { tool: "maven", command: "mvn test" } };
30949
31812
  }
30950
- if (await fileExists2(path65.join(projectPath, "gradlew")) && (await fileExists2(path65.join(projectPath, "build.gradle")) || await fileExists2(path65.join(projectPath, "build.gradle.kts")))) {
31813
+ if (await fileExists2(path68.join(projectPath, "gradlew")) && (await fileExists2(path68.join(projectPath, "build.gradle")) || await fileExists2(path68.join(projectPath, "build.gradle.kts")))) {
30951
31814
  return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
30952
31815
  }
30953
31816
  return { stack: "unknown" };
@@ -30964,8 +31827,8 @@ var init_project_commands = __esm({
30964
31827
  });
30965
31828
 
30966
31829
  // core/workflow/workflow-preferences.ts
30967
- import { exec as exec17 } from "node:child_process";
30968
- import { promisify as promisify18 } from "node:util";
31830
+ import { exec as exec18 } from "node:child_process";
31831
+ import { promisify as promisify19 } from "node:util";
30969
31832
  import chalk18 from "chalk";
30970
31833
  function prefKey(hook, command) {
30971
31834
  return `workflow:${hook}_${command}`;
@@ -31108,7 +31971,7 @@ var init_workflow_preferences = __esm({
31108
31971
  init_memory_system();
31109
31972
  init_constants();
31110
31973
  init_fs();
31111
- execAsync12 = promisify18(exec17);
31974
+ execAsync12 = promisify19(exec18);
31112
31975
  sessionPreferences = /* @__PURE__ */ new Map();
31113
31976
  oncePreferences = /* @__PURE__ */ new Map();
31114
31977
  __name(prefKey, "prefKey");
@@ -31122,7 +31985,7 @@ var init_workflow_preferences = __esm({
31122
31985
  });
31123
31986
 
31124
31987
  // core/commands/shipping.ts
31125
- import path66 from "node:path";
31988
+ import path69 from "node:path";
31126
31989
  var ShippingCommands;
31127
31990
  var init_shipping = __esm({
31128
31991
  "core/commands/shipping.ts"() {
@@ -31268,7 +32131,7 @@ ${result.stderr}`.trim();
31268
32131
  */
31269
32132
  async _bumpVersion(projectPath) {
31270
32133
  try {
31271
- const pkgPath = path66.join(projectPath, "package.json");
32134
+ const pkgPath = path69.join(projectPath, "package.json");
31272
32135
  const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
31273
32136
  const oldVersion = pkg?.version || "0.0.0";
31274
32137
  const [major, minor, patch] = oldVersion.split(".").map(Number);
@@ -31290,7 +32153,7 @@ ${result.stderr}`.trim();
31290
32153
  */
31291
32154
  async _updateChangelog(feature, version, projectPath) {
31292
32155
  try {
31293
- const changelogPath = path66.join(projectPath, "CHANGELOG.md");
32156
+ const changelogPath = path69.join(projectPath, "CHANGELOG.md");
31294
32157
  const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
31295
32158
  const entry = `## [${version}] - ${date_helper_exports.formatDate(/* @__PURE__ */ new Date())}
31296
32159
 
@@ -31538,8 +32401,8 @@ var init_cache2 = __esm({
31538
32401
  });
31539
32402
 
31540
32403
  // core/utils/keychain.ts
31541
- import { exec as exec18 } from "node:child_process";
31542
- import { promisify as promisify19 } from "node:util";
32404
+ import { exec as exec19 } from "node:child_process";
32405
+ import { promisify as promisify20 } from "node:util";
31543
32406
  async function getCredential(key) {
31544
32407
  if (process.platform !== "darwin") {
31545
32408
  return getEnvFallback(key);
@@ -31566,7 +32429,7 @@ var init_keychain = __esm({
31566
32429
  "core/utils/keychain.ts"() {
31567
32430
  "use strict";
31568
32431
  init_fs();
31569
- execAsync13 = promisify19(exec18);
32432
+ execAsync13 = promisify20(exec19);
31570
32433
  SERVICE_NAME = "prjct-cli";
31571
32434
  __name(getCredential, "getCredential");
31572
32435
  __name(getEnvFallback, "getEnvFallback");
@@ -32334,11 +33197,11 @@ var init_linear = __esm({
32334
33197
  });
32335
33198
 
32336
33199
  // core/utils/project-credentials.ts
32337
- import fs57 from "node:fs/promises";
33200
+ import fs60 from "node:fs/promises";
32338
33201
  import os19 from "node:os";
32339
- import path67 from "node:path";
33202
+ import path70 from "node:path";
32340
33203
  function getCredentialsPath(projectId) {
32341
- return path67.join(os19.homedir(), ".prjct-cli", "projects", projectId, "config", "credentials.json");
33204
+ return path70.join(os19.homedir(), ".prjct-cli", "projects", projectId, "config", "credentials.json");
32342
33205
  }
32343
33206
  async function getProjectCredentials(projectId) {
32344
33207
  const credPath = getCredentialsPath(projectId);
@@ -32346,7 +33209,7 @@ async function getProjectCredentials(projectId) {
32346
33209
  return {};
32347
33210
  }
32348
33211
  try {
32349
- return JSON.parse(await fs57.readFile(credPath, "utf-8"));
33212
+ return JSON.parse(await fs60.readFile(credPath, "utf-8"));
32350
33213
  } catch (error) {
32351
33214
  console.error("[project-credentials] Failed to read credentials:", getErrorMessage2(error));
32352
33215
  return {};
@@ -33018,7 +33881,7 @@ var require_package = __commonJS({
33018
33881
  "package.json"(exports, module) {
33019
33882
  module.exports = {
33020
33883
  name: "prjct-cli",
33021
- version: "1.16.0",
33884
+ version: "1.18.0",
33022
33885
  description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
33023
33886
  main: "core/index.ts",
33024
33887
  bin: {
@@ -33125,7 +33988,7 @@ var require_package = __commonJS({
33125
33988
  // core/index.ts
33126
33989
  var core_exports = {};
33127
33990
  import os20 from "node:os";
33128
- import path68 from "node:path";
33991
+ import path71 from "node:path";
33129
33992
  import chalk20 from "chalk";
33130
33993
  async function main() {
33131
33994
  const [commandName, ...rawArgs] = process.argv.slice(2);
@@ -33230,7 +34093,8 @@ async function main() {
33230
34093
  preview: options.preview === true || options["dry-run"] === true,
33231
34094
  yes: options.yes === true,
33232
34095
  json: options.json === true,
33233
- package: options.package ? String(options.package) : void 0
34096
+ package: options.package ? String(options.package) : void 0,
34097
+ full: options.full === true
33234
34098
  }), "sync"),
33235
34099
  seal: /* @__PURE__ */ __name(() => commands.seal(process.cwd(), { json: options.json === true }), "seal"),
33236
34100
  verify: /* @__PURE__ */ __name(() => commands.verify(process.cwd(), { json: options.json === true }), "verify"),
@@ -33338,13 +34202,13 @@ function parseCommandArgs(_cmd, rawArgs) {
33338
34202
  }
33339
34203
  async function displayVersion(version) {
33340
34204
  const detection = await detectAllProviders();
33341
- const claudeCommandPath = path68.join(os20.homedir(), ".claude", "commands", "p.md");
33342
- const geminiCommandPath = path68.join(os20.homedir(), ".gemini", "commands", "p.toml");
34205
+ const claudeCommandPath = path71.join(os20.homedir(), ".claude", "commands", "p.md");
34206
+ const geminiCommandPath = path71.join(os20.homedir(), ".gemini", "commands", "p.toml");
33343
34207
  const [claudeConfigured, geminiConfigured, cursorConfigured, cursorExists] = await Promise.all([
33344
34208
  fileExists(claudeCommandPath),
33345
34209
  fileExists(geminiCommandPath),
33346
- fileExists(path68.join(process.cwd(), ".cursor", "commands", "sync.md")),
33347
- fileExists(path68.join(process.cwd(), ".cursor"))
34210
+ fileExists(path71.join(process.cwd(), ".cursor", "commands", "sync.md")),
34211
+ fileExists(path71.join(process.cwd(), ".cursor"))
33348
34212
  ]);
33349
34213
  const antigravityDetection = await detectAntigravity();
33350
34214
  console.log(`
@@ -33483,7 +34347,7 @@ init_ai_provider();
33483
34347
  init_config_manager();
33484
34348
  init_editors_config();
33485
34349
  import os21 from "node:os";
33486
- import path69 from "node:path";
34350
+ import path72 from "node:path";
33487
34351
  import chalk21 from "chalk";
33488
34352
 
33489
34353
  // core/server/server.ts
@@ -34304,13 +35168,13 @@ async function checkRoutersInstalled() {
34304
35168
  const home = os21.homedir();
34305
35169
  const detection = await detectAllProviders();
34306
35170
  if (detection.claude.installed) {
34307
- const claudeRouter = path69.join(home, ".claude", "commands", "p.md");
35171
+ const claudeRouter = path72.join(home, ".claude", "commands", "p.md");
34308
35172
  if (!await fileExists(claudeRouter)) {
34309
35173
  return false;
34310
35174
  }
34311
35175
  }
34312
35176
  if (detection.gemini.installed) {
34313
- const geminiRouter = path69.join(home, ".gemini", "commands", "p.toml");
35177
+ const geminiRouter = path72.join(home, ".gemini", "commands", "p.toml");
34314
35178
  if (!await fileExists(geminiRouter)) {
34315
35179
  return false;
34316
35180
  }
@@ -34451,7 +35315,7 @@ if (args[0] === "start" || args[0] === "setup") {
34451
35315
  console.error('No prjct project found. Run "prjct init" first.');
34452
35316
  process.exitCode = 1;
34453
35317
  } else {
34454
- const linearCliPath = path69.join(__dirname, "..", "core", "cli", "linear.ts");
35318
+ const linearCliPath = path72.join(__dirname, "..", "core", "cli", "linear.ts");
34455
35319
  const linearArgs = ["--project", projectId, ...args.slice(1)];
34456
35320
  const child = spawn("bun", [linearCliPath, ...linearArgs], {
34457
35321
  stdio: "inherit",
@@ -34478,12 +35342,12 @@ if (args[0] === "start" || args[0] === "setup") {
34478
35342
  windsurfDetected,
34479
35343
  windsurfConfigured
34480
35344
  ] = await Promise.all([
34481
- fileExists(path69.join(home, ".claude", "commands", "p.md")),
34482
- fileExists(path69.join(home, ".gemini", "commands", "p.toml")),
34483
- fileExists(path69.join(cwd, ".cursor")),
34484
- fileExists(path69.join(cwd, ".cursor", "rules", "prjct.mdc")),
34485
- fileExists(path69.join(cwd, ".windsurf")),
34486
- fileExists(path69.join(cwd, ".windsurf", "rules", "prjct.md"))
35345
+ fileExists(path72.join(home, ".claude", "commands", "p.md")),
35346
+ fileExists(path72.join(home, ".gemini", "commands", "p.toml")),
35347
+ fileExists(path72.join(cwd, ".cursor")),
35348
+ fileExists(path72.join(cwd, ".cursor", "rules", "prjct.mdc")),
35349
+ fileExists(path72.join(cwd, ".windsurf")),
35350
+ fileExists(path72.join(cwd, ".windsurf", "rules", "prjct.md"))
34487
35351
  ]);
34488
35352
  console.log(`
34489
35353
  ${chalk21.cyan("p/")} prjct v${VERSION}
@@ -34522,7 +35386,7 @@ ${chalk21.dim("Run 'prjct init' to configure (Cursor/Windsurf IDE)")}
34522
35386
  ${chalk21.cyan("https://prjct.app")}
34523
35387
  `);
34524
35388
  } else {
34525
- const configPath = path69.join(os21.homedir(), ".prjct-cli", "config", "installed-editors.json");
35389
+ const configPath = path72.join(os21.homedir(), ".prjct-cli", "config", "installed-editors.json");
34526
35390
  const routersInstalled = await checkRoutersInstalled();
34527
35391
  if (!await fileExists(configPath) || !routersInstalled) {
34528
35392
  console.log(`