prjct-cli 0.50.0 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/core/commands/analysis.ts +199 -83
- package/core/services/diff-generator.ts +356 -0
- package/core/services/sync-service.ts +6 -0
- package/dist/bin/prjct.mjs +619 -318
- package/package.json +1 -1
package/dist/bin/prjct.mjs
CHANGED
|
@@ -3767,8 +3767,8 @@ function tryResolve(basePath, projectPath) {
|
|
|
3767
3767
|
for (const ext of extensions) {
|
|
3768
3768
|
const fullPath = basePath + ext;
|
|
3769
3769
|
try {
|
|
3770
|
-
const
|
|
3771
|
-
if (
|
|
3770
|
+
const fs47 = __require("node:fs");
|
|
3771
|
+
if (fs47.existsSync(fullPath) && fs47.statSync(fullPath).isFile()) {
|
|
3772
3772
|
return path12.relative(projectPath, fullPath);
|
|
3773
3773
|
}
|
|
3774
3774
|
} catch {
|
|
@@ -4951,11 +4951,11 @@ async function runSignaturesTool(args2, projectPath) {
|
|
|
4951
4951
|
}
|
|
4952
4952
|
};
|
|
4953
4953
|
}
|
|
4954
|
-
const
|
|
4954
|
+
const fs47 = await import("node:fs/promises");
|
|
4955
4955
|
const path56 = await import("node:path");
|
|
4956
4956
|
const fullPath = path56.isAbsolute(filePath) ? filePath : path56.join(projectPath, filePath);
|
|
4957
4957
|
try {
|
|
4958
|
-
const stat = await
|
|
4958
|
+
const stat = await fs47.stat(fullPath);
|
|
4959
4959
|
if (stat.isDirectory()) {
|
|
4960
4960
|
const results = await extractDirectorySignatures(filePath, projectPath, {
|
|
4961
4961
|
recursive: args2.includes("--recursive") || args2.includes("-r")
|
|
@@ -5022,11 +5022,11 @@ async function runSummaryTool(args2, projectPath) {
|
|
|
5022
5022
|
}
|
|
5023
5023
|
};
|
|
5024
5024
|
}
|
|
5025
|
-
const
|
|
5025
|
+
const fs47 = await import("node:fs/promises");
|
|
5026
5026
|
const path56 = await import("node:path");
|
|
5027
5027
|
const fullPath = path56.isAbsolute(targetPath) ? targetPath : path56.join(projectPath, targetPath);
|
|
5028
5028
|
try {
|
|
5029
|
-
const stat = await
|
|
5029
|
+
const stat = await fs47.stat(fullPath);
|
|
5030
5030
|
if (stat.isDirectory()) {
|
|
5031
5031
|
const results = await summarizeDirectory(targetPath, projectPath, {
|
|
5032
5032
|
recursive: args2.includes("--recursive") || args2.includes("-r")
|
|
@@ -11448,7 +11448,7 @@ var init_constants = __esm({
|
|
|
11448
11448
|
|
|
11449
11449
|
// core/agentic/plan-mode.ts
|
|
11450
11450
|
function generateApprovalPrompt(commandName, context2) {
|
|
11451
|
-
const
|
|
11451
|
+
const prompts3 = {
|
|
11452
11452
|
ship: {
|
|
11453
11453
|
title: "Ship Confirmation",
|
|
11454
11454
|
message: "Ready to commit and push changes?",
|
|
@@ -11486,7 +11486,7 @@ function generateApprovalPrompt(commandName, context2) {
|
|
|
11486
11486
|
]
|
|
11487
11487
|
}
|
|
11488
11488
|
};
|
|
11489
|
-
return
|
|
11489
|
+
return prompts3[commandName] || {
|
|
11490
11490
|
title: "Confirmation Required",
|
|
11491
11491
|
message: `Execute ${commandName}?`,
|
|
11492
11492
|
options: [
|
|
@@ -15541,16 +15541,16 @@ var init_onboarding = __esm({
|
|
|
15541
15541
|
* Detect project type from file system
|
|
15542
15542
|
*/
|
|
15543
15543
|
async detectProjectType() {
|
|
15544
|
-
const
|
|
15544
|
+
const fs47 = await import("node:fs/promises");
|
|
15545
15545
|
const path56 = await import("node:path");
|
|
15546
15546
|
try {
|
|
15547
|
-
const files = await
|
|
15547
|
+
const files = await fs47.readdir(this.projectPath);
|
|
15548
15548
|
if (files.includes("turbo.json") || files.includes("lerna.json") || files.includes("nx.json")) {
|
|
15549
15549
|
return "monorepo";
|
|
15550
15550
|
}
|
|
15551
15551
|
if (files.includes("package.json")) {
|
|
15552
15552
|
const pkgPath = path56.join(this.projectPath, "package.json");
|
|
15553
|
-
const pkgContent = await
|
|
15553
|
+
const pkgContent = await fs47.readFile(pkgPath, "utf-8");
|
|
15554
15554
|
const pkg = JSON.parse(pkgContent);
|
|
15555
15555
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
15556
15556
|
if (pkg.bin) return "cli-tool";
|
|
@@ -15586,32 +15586,32 @@ var init_onboarding = __esm({
|
|
|
15586
15586
|
* Detect installed AI agents from config files
|
|
15587
15587
|
*/
|
|
15588
15588
|
async detectInstalledAgents() {
|
|
15589
|
-
const
|
|
15589
|
+
const fs47 = await import("node:fs/promises");
|
|
15590
15590
|
const path56 = await import("node:path");
|
|
15591
15591
|
const os17 = await import("node:os");
|
|
15592
15592
|
const agents = [];
|
|
15593
15593
|
try {
|
|
15594
|
-
await
|
|
15594
|
+
await fs47.access(path56.join(os17.homedir(), ".claude"));
|
|
15595
15595
|
agents.push("claude");
|
|
15596
15596
|
} catch {
|
|
15597
15597
|
}
|
|
15598
15598
|
try {
|
|
15599
|
-
await
|
|
15599
|
+
await fs47.access(path56.join(this.projectPath, ".cursorrules"));
|
|
15600
15600
|
agents.push("cursor");
|
|
15601
15601
|
} catch {
|
|
15602
15602
|
}
|
|
15603
15603
|
try {
|
|
15604
|
-
await
|
|
15604
|
+
await fs47.access(path56.join(this.projectPath, ".windsurfrules"));
|
|
15605
15605
|
agents.push("windsurf");
|
|
15606
15606
|
} catch {
|
|
15607
15607
|
}
|
|
15608
15608
|
try {
|
|
15609
|
-
await
|
|
15609
|
+
await fs47.access(path56.join(this.projectPath, ".github", "copilot-instructions.md"));
|
|
15610
15610
|
agents.push("copilot");
|
|
15611
15611
|
} catch {
|
|
15612
15612
|
}
|
|
15613
15613
|
try {
|
|
15614
|
-
await
|
|
15614
|
+
await fs47.access(path56.join(os17.homedir(), ".gemini"));
|
|
15615
15615
|
agents.push("gemini");
|
|
15616
15616
|
} catch {
|
|
15617
15617
|
}
|
|
@@ -15621,17 +15621,17 @@ var init_onboarding = __esm({
|
|
|
15621
15621
|
* Detect tech stack from project files
|
|
15622
15622
|
*/
|
|
15623
15623
|
async detectStack() {
|
|
15624
|
-
const
|
|
15624
|
+
const fs47 = await import("node:fs/promises");
|
|
15625
15625
|
const path56 = await import("node:path");
|
|
15626
15626
|
const stack = {
|
|
15627
15627
|
language: "Unknown",
|
|
15628
15628
|
technologies: []
|
|
15629
15629
|
};
|
|
15630
15630
|
try {
|
|
15631
|
-
const files = await
|
|
15631
|
+
const files = await fs47.readdir(this.projectPath);
|
|
15632
15632
|
if (files.includes("package.json")) {
|
|
15633
15633
|
const pkgPath = path56.join(this.projectPath, "package.json");
|
|
15634
|
-
const pkgContent = await
|
|
15634
|
+
const pkgContent = await fs47.readFile(pkgPath, "utf-8");
|
|
15635
15635
|
const pkg = JSON.parse(pkgContent);
|
|
15636
15636
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
15637
15637
|
stack.language = deps.typescript ? "TypeScript" : "JavaScript";
|
|
@@ -16296,12 +16296,229 @@ var init_analyzer2 = __esm({
|
|
|
16296
16296
|
}
|
|
16297
16297
|
});
|
|
16298
16298
|
|
|
16299
|
+
// core/services/diff-generator.ts
|
|
16300
|
+
import chalk8 from "chalk";
|
|
16301
|
+
function estimateTokens(content) {
|
|
16302
|
+
return Math.ceil(content.length / CHARS_PER_TOKEN2);
|
|
16303
|
+
}
|
|
16304
|
+
function parseMarkdownSections(content) {
|
|
16305
|
+
const lines = content.split("\n");
|
|
16306
|
+
const sections = [];
|
|
16307
|
+
let currentSection = null;
|
|
16308
|
+
for (let i = 0; i < lines.length; i++) {
|
|
16309
|
+
const line = lines[i];
|
|
16310
|
+
const headerMatch = line.match(/^(#{1,3})\s+(.+)$/);
|
|
16311
|
+
if (headerMatch) {
|
|
16312
|
+
if (currentSection) {
|
|
16313
|
+
currentSection.endLine = i - 1;
|
|
16314
|
+
sections.push(currentSection);
|
|
16315
|
+
}
|
|
16316
|
+
currentSection = {
|
|
16317
|
+
name: headerMatch[2].trim(),
|
|
16318
|
+
content: line,
|
|
16319
|
+
startLine: i,
|
|
16320
|
+
endLine: i
|
|
16321
|
+
};
|
|
16322
|
+
} else if (currentSection) {
|
|
16323
|
+
currentSection.content += `
|
|
16324
|
+
${line}`;
|
|
16325
|
+
}
|
|
16326
|
+
}
|
|
16327
|
+
if (currentSection) {
|
|
16328
|
+
currentSection.endLine = lines.length - 1;
|
|
16329
|
+
sections.push(currentSection);
|
|
16330
|
+
}
|
|
16331
|
+
return sections;
|
|
16332
|
+
}
|
|
16333
|
+
function isPreservedSection(content) {
|
|
16334
|
+
return content.includes("<!-- prjct:preserve");
|
|
16335
|
+
}
|
|
16336
|
+
function generateSyncDiff(oldContent, newContent) {
|
|
16337
|
+
const oldSections = parseMarkdownSections(oldContent);
|
|
16338
|
+
const newSections = parseMarkdownSections(newContent);
|
|
16339
|
+
const diff = {
|
|
16340
|
+
hasChanges: false,
|
|
16341
|
+
added: [],
|
|
16342
|
+
modified: [],
|
|
16343
|
+
removed: [],
|
|
16344
|
+
preserved: [],
|
|
16345
|
+
tokensBefore: estimateTokens(oldContent),
|
|
16346
|
+
tokensAfter: estimateTokens(newContent),
|
|
16347
|
+
tokenDelta: 0
|
|
16348
|
+
};
|
|
16349
|
+
diff.tokenDelta = diff.tokensAfter - diff.tokensBefore;
|
|
16350
|
+
const oldMap = new Map(oldSections.map((s) => [s.name.toLowerCase(), s]));
|
|
16351
|
+
const newMap = new Map(newSections.map((s) => [s.name.toLowerCase(), s]));
|
|
16352
|
+
for (const section of oldSections) {
|
|
16353
|
+
if (isPreservedSection(section.content)) {
|
|
16354
|
+
diff.preserved.push({
|
|
16355
|
+
name: section.name,
|
|
16356
|
+
lineCount: section.content.split("\n").length
|
|
16357
|
+
});
|
|
16358
|
+
}
|
|
16359
|
+
}
|
|
16360
|
+
for (const newSection of newSections) {
|
|
16361
|
+
const key = newSection.name.toLowerCase();
|
|
16362
|
+
const oldSection = oldMap.get(key);
|
|
16363
|
+
if (!oldSection) {
|
|
16364
|
+
diff.added.push({
|
|
16365
|
+
name: newSection.name,
|
|
16366
|
+
type: "added",
|
|
16367
|
+
after: newSection.content,
|
|
16368
|
+
lineCount: newSection.content.split("\n").length
|
|
16369
|
+
});
|
|
16370
|
+
diff.hasChanges = true;
|
|
16371
|
+
} else if (oldSection.content.trim() !== newSection.content.trim()) {
|
|
16372
|
+
if (!isPreservedSection(oldSection.content)) {
|
|
16373
|
+
diff.modified.push({
|
|
16374
|
+
name: newSection.name,
|
|
16375
|
+
type: "modified",
|
|
16376
|
+
before: oldSection.content,
|
|
16377
|
+
after: newSection.content,
|
|
16378
|
+
lineCount: newSection.content.split("\n").length
|
|
16379
|
+
});
|
|
16380
|
+
diff.hasChanges = true;
|
|
16381
|
+
}
|
|
16382
|
+
}
|
|
16383
|
+
}
|
|
16384
|
+
for (const oldSection of oldSections) {
|
|
16385
|
+
const key = oldSection.name.toLowerCase();
|
|
16386
|
+
if (!newMap.has(key) && !isPreservedSection(oldSection.content)) {
|
|
16387
|
+
diff.removed.push({
|
|
16388
|
+
name: oldSection.name,
|
|
16389
|
+
type: "removed",
|
|
16390
|
+
before: oldSection.content,
|
|
16391
|
+
lineCount: oldSection.content.split("\n").length
|
|
16392
|
+
});
|
|
16393
|
+
diff.hasChanges = true;
|
|
16394
|
+
}
|
|
16395
|
+
}
|
|
16396
|
+
return diff;
|
|
16397
|
+
}
|
|
16398
|
+
function formatDiffPreview(diff, options = {}) {
|
|
16399
|
+
const { colorize = true } = options;
|
|
16400
|
+
const lines = [];
|
|
16401
|
+
const green = colorize ? chalk8.green : (s) => s;
|
|
16402
|
+
const red = colorize ? chalk8.red : (s) => s;
|
|
16403
|
+
const yellow = colorize ? chalk8.yellow : (s) => s;
|
|
16404
|
+
const dim = colorize ? chalk8.dim : (s) => s;
|
|
16405
|
+
const bold = colorize ? chalk8.bold : (s) => s;
|
|
16406
|
+
if (!diff.hasChanges) {
|
|
16407
|
+
lines.push(dim("No changes detected (context is up to date)"));
|
|
16408
|
+
return lines.join("\n");
|
|
16409
|
+
}
|
|
16410
|
+
lines.push("");
|
|
16411
|
+
lines.push(bold("\u{1F4CB} Changes to context files:"));
|
|
16412
|
+
lines.push("");
|
|
16413
|
+
if (diff.added.length > 0) {
|
|
16414
|
+
for (const section of diff.added) {
|
|
16415
|
+
lines.push(green(`+ \u2502 + ${section.name} (new)`));
|
|
16416
|
+
}
|
|
16417
|
+
}
|
|
16418
|
+
if (diff.modified.length > 0) {
|
|
16419
|
+
for (const section of diff.modified) {
|
|
16420
|
+
lines.push(yellow(`~ \u2502 ${section.name} (modified)`));
|
|
16421
|
+
}
|
|
16422
|
+
}
|
|
16423
|
+
if (diff.removed.length > 0) {
|
|
16424
|
+
for (const section of diff.removed) {
|
|
16425
|
+
lines.push(red(`- \u2502 - ${section.name} (removed)`));
|
|
16426
|
+
}
|
|
16427
|
+
}
|
|
16428
|
+
if (diff.preserved.length > 0) {
|
|
16429
|
+
lines.push("");
|
|
16430
|
+
lines.push(dim(" ## Your Customizations"));
|
|
16431
|
+
for (const section of diff.preserved) {
|
|
16432
|
+
lines.push(dim(` \u2502 \u2713 ${section.name} (${section.lineCount} lines preserved)`));
|
|
16433
|
+
}
|
|
16434
|
+
}
|
|
16435
|
+
lines.push("");
|
|
16436
|
+
lines.push(dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
16437
|
+
const summaryParts = [];
|
|
16438
|
+
if (diff.added.length > 0) summaryParts.push(green(`+${diff.added.length} added`));
|
|
16439
|
+
if (diff.modified.length > 0) summaryParts.push(yellow(`~${diff.modified.length} modified`));
|
|
16440
|
+
if (diff.removed.length > 0) summaryParts.push(red(`-${diff.removed.length} removed`));
|
|
16441
|
+
lines.push(`Summary: ${summaryParts.join(", ") || "no changes"}`);
|
|
16442
|
+
const tokenSign = diff.tokenDelta >= 0 ? "+" : "";
|
|
16443
|
+
const tokenColor = diff.tokenDelta >= 0 ? green : red;
|
|
16444
|
+
lines.push(
|
|
16445
|
+
`Tokens: ${diff.tokensBefore.toLocaleString()} \u2192 ${diff.tokensAfter.toLocaleString()} (${tokenColor(tokenSign + diff.tokenDelta.toLocaleString())})`
|
|
16446
|
+
);
|
|
16447
|
+
lines.push("");
|
|
16448
|
+
return lines.join("\n");
|
|
16449
|
+
}
|
|
16450
|
+
function formatFullDiff(diff, options = {}) {
|
|
16451
|
+
const { colorize = true } = options;
|
|
16452
|
+
const lines = [];
|
|
16453
|
+
const green = colorize ? chalk8.green : (s) => s;
|
|
16454
|
+
const red = colorize ? chalk8.red : (s) => s;
|
|
16455
|
+
const cyan = colorize ? chalk8.cyan : (s) => s;
|
|
16456
|
+
const dim = colorize ? chalk8.dim : (s) => s;
|
|
16457
|
+
for (const section of diff.added) {
|
|
16458
|
+
lines.push(cyan(`@@ +${section.name} @@`));
|
|
16459
|
+
if (section.after) {
|
|
16460
|
+
for (const line of section.after.split("\n")) {
|
|
16461
|
+
lines.push(green(`+ ${line}`));
|
|
16462
|
+
}
|
|
16463
|
+
}
|
|
16464
|
+
lines.push("");
|
|
16465
|
+
}
|
|
16466
|
+
for (const section of diff.modified) {
|
|
16467
|
+
lines.push(cyan(`@@ ${section.name} @@`));
|
|
16468
|
+
if (section.before) {
|
|
16469
|
+
for (const line of section.before.split("\n").slice(0, 5)) {
|
|
16470
|
+
lines.push(red(`- ${line}`));
|
|
16471
|
+
}
|
|
16472
|
+
if (section.before.split("\n").length > 5) {
|
|
16473
|
+
lines.push(dim(` ... ${section.before.split("\n").length - 5} more lines`));
|
|
16474
|
+
}
|
|
16475
|
+
}
|
|
16476
|
+
if (section.after) {
|
|
16477
|
+
for (const line of section.after.split("\n").slice(0, 5)) {
|
|
16478
|
+
lines.push(green(`+ ${line}`));
|
|
16479
|
+
}
|
|
16480
|
+
if (section.after.split("\n").length > 5) {
|
|
16481
|
+
lines.push(dim(` ... ${section.after.split("\n").length - 5} more lines`));
|
|
16482
|
+
}
|
|
16483
|
+
}
|
|
16484
|
+
lines.push("");
|
|
16485
|
+
}
|
|
16486
|
+
for (const section of diff.removed) {
|
|
16487
|
+
lines.push(cyan(`@@ -${section.name} @@`));
|
|
16488
|
+
if (section.before) {
|
|
16489
|
+
for (const line of section.before.split("\n").slice(0, 5)) {
|
|
16490
|
+
lines.push(red(`- ${line}`));
|
|
16491
|
+
}
|
|
16492
|
+
if (section.before.split("\n").length > 5) {
|
|
16493
|
+
lines.push(dim(` ... ${section.before.split("\n").length - 5} more lines`));
|
|
16494
|
+
}
|
|
16495
|
+
}
|
|
16496
|
+
lines.push("");
|
|
16497
|
+
}
|
|
16498
|
+
return lines.join("\n");
|
|
16499
|
+
}
|
|
16500
|
+
var CHARS_PER_TOKEN2;
|
|
16501
|
+
var init_diff_generator = __esm({
|
|
16502
|
+
"core/services/diff-generator.ts"() {
|
|
16503
|
+
"use strict";
|
|
16504
|
+
CHARS_PER_TOKEN2 = 4;
|
|
16505
|
+
__name(estimateTokens, "estimateTokens");
|
|
16506
|
+
__name(parseMarkdownSections, "parseMarkdownSections");
|
|
16507
|
+
__name(isPreservedSection, "isPreservedSection");
|
|
16508
|
+
__name(generateSyncDiff, "generateSyncDiff");
|
|
16509
|
+
__name(formatDiffPreview, "formatDiffPreview");
|
|
16510
|
+
__name(formatFullDiff, "formatFullDiff");
|
|
16511
|
+
}
|
|
16512
|
+
});
|
|
16513
|
+
|
|
16299
16514
|
// core/commands/analysis.ts
|
|
16300
16515
|
var analysis_exports = {};
|
|
16301
16516
|
__export(analysis_exports, {
|
|
16302
16517
|
AnalysisCommands: () => AnalysisCommands
|
|
16303
16518
|
});
|
|
16519
|
+
import fs34 from "node:fs/promises";
|
|
16304
16520
|
import path35 from "node:path";
|
|
16521
|
+
import prompts2 from "prompts";
|
|
16305
16522
|
var AnalysisCommands;
|
|
16306
16523
|
var init_analysis2 = __esm({
|
|
16307
16524
|
"core/commands/analysis.ts"() {
|
|
@@ -16311,8 +16528,10 @@ var init_analysis2 = __esm({
|
|
|
16311
16528
|
init_command_installer();
|
|
16312
16529
|
init_metrics();
|
|
16313
16530
|
init_services();
|
|
16531
|
+
init_diff_generator();
|
|
16314
16532
|
init_metrics_storage();
|
|
16315
16533
|
init_next_steps();
|
|
16534
|
+
init_output();
|
|
16316
16535
|
init_base();
|
|
16317
16536
|
AnalysisCommands = class extends PrjctCommandsBase {
|
|
16318
16537
|
static {
|
|
@@ -16456,7 +16675,7 @@ var init_analysis2 = __esm({
|
|
|
16456
16675
|
return lines.join("\n");
|
|
16457
16676
|
}
|
|
16458
16677
|
/**
|
|
16459
|
-
* /p:sync - Comprehensive project sync
|
|
16678
|
+
* /p:sync - Comprehensive project sync with diff preview
|
|
16460
16679
|
*
|
|
16461
16680
|
* Uses syncService to do ALL operations in one TypeScript execution:
|
|
16462
16681
|
* - Git analysis
|
|
@@ -16466,99 +16685,181 @@ var init_analysis2 = __esm({
|
|
|
16466
16685
|
* - Skill configuration
|
|
16467
16686
|
* - State updates
|
|
16468
16687
|
*
|
|
16688
|
+
* Options:
|
|
16689
|
+
* - --preview: Show what would change without applying
|
|
16690
|
+
* - --yes: Skip confirmation prompt
|
|
16691
|
+
*
|
|
16469
16692
|
* This eliminates the need for Claude to make 50+ individual tool calls.
|
|
16693
|
+
*
|
|
16694
|
+
* @see PRJ-125
|
|
16470
16695
|
*/
|
|
16471
16696
|
async sync(projectPath = process.cwd(), options = {}) {
|
|
16472
16697
|
try {
|
|
16473
16698
|
const initResult = await this.ensureProjectInit(projectPath);
|
|
16474
16699
|
if (!initResult.success) return initResult;
|
|
16700
|
+
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16701
|
+
if (!projectId) {
|
|
16702
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16703
|
+
return { success: false, error: "No project ID found" };
|
|
16704
|
+
}
|
|
16705
|
+
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
16475
16706
|
const startTime = Date.now();
|
|
16476
|
-
|
|
16707
|
+
const claudeMdPath = path35.join(globalPath, "context", "CLAUDE.md");
|
|
16708
|
+
let existingContent = null;
|
|
16709
|
+
try {
|
|
16710
|
+
existingContent = await fs34.readFile(claudeMdPath, "utf-8");
|
|
16711
|
+
} catch {
|
|
16712
|
+
}
|
|
16713
|
+
if (existingContent && !options.yes) {
|
|
16714
|
+
output_default.spin("Analyzing changes...");
|
|
16715
|
+
const result2 = await syncService.sync(projectPath, { aiTools: options.aiTools });
|
|
16716
|
+
if (!result2.success) {
|
|
16717
|
+
output_default.fail(result2.error || "Sync failed");
|
|
16718
|
+
return { success: false, error: result2.error };
|
|
16719
|
+
}
|
|
16720
|
+
let newContent;
|
|
16721
|
+
try {
|
|
16722
|
+
newContent = await fs34.readFile(claudeMdPath, "utf-8");
|
|
16723
|
+
} catch {
|
|
16724
|
+
newContent = "";
|
|
16725
|
+
}
|
|
16726
|
+
const diff = generateSyncDiff(existingContent, newContent);
|
|
16727
|
+
output_default.stop();
|
|
16728
|
+
if (!diff.hasChanges) {
|
|
16729
|
+
output_default.done("No changes detected (context is up to date)");
|
|
16730
|
+
return { success: true, message: "No changes" };
|
|
16731
|
+
}
|
|
16732
|
+
console.log(formatDiffPreview(diff));
|
|
16733
|
+
if (options.preview) {
|
|
16734
|
+
return {
|
|
16735
|
+
success: true,
|
|
16736
|
+
isPreview: true,
|
|
16737
|
+
diff,
|
|
16738
|
+
message: "Preview complete (no changes applied)"
|
|
16739
|
+
};
|
|
16740
|
+
}
|
|
16741
|
+
const response = await prompts2({
|
|
16742
|
+
type: "select",
|
|
16743
|
+
name: "action",
|
|
16744
|
+
message: "Apply these changes?",
|
|
16745
|
+
choices: [
|
|
16746
|
+
{ title: "Yes, apply changes", value: "apply" },
|
|
16747
|
+
{ title: "No, cancel", value: "cancel" },
|
|
16748
|
+
{ title: "Show full diff", value: "diff" }
|
|
16749
|
+
]
|
|
16750
|
+
});
|
|
16751
|
+
if (response.action === "cancel" || !response.action) {
|
|
16752
|
+
output_default.warn("Sync cancelled");
|
|
16753
|
+
return { success: false, message: "Cancelled by user" };
|
|
16754
|
+
}
|
|
16755
|
+
if (response.action === "diff") {
|
|
16756
|
+
console.log(`
|
|
16757
|
+
${formatFullDiff(diff)}`);
|
|
16758
|
+
const confirm = await prompts2({
|
|
16759
|
+
type: "confirm",
|
|
16760
|
+
name: "apply",
|
|
16761
|
+
message: "Apply these changes?",
|
|
16762
|
+
initial: true
|
|
16763
|
+
});
|
|
16764
|
+
if (!confirm.apply) {
|
|
16765
|
+
output_default.warn("Sync cancelled");
|
|
16766
|
+
return { success: false, message: "Cancelled by user" };
|
|
16767
|
+
}
|
|
16768
|
+
}
|
|
16769
|
+
output_default.done("Changes applied");
|
|
16770
|
+
return this.showSyncResult(result2, startTime);
|
|
16771
|
+
}
|
|
16772
|
+
output_default.spin("Syncing project...");
|
|
16477
16773
|
const result = await syncService.sync(projectPath, { aiTools: options.aiTools });
|
|
16478
16774
|
if (!result.success) {
|
|
16479
|
-
|
|
16775
|
+
output_default.fail(result.error || "Sync failed");
|
|
16480
16776
|
return { success: false, error: result.error };
|
|
16481
16777
|
}
|
|
16482
|
-
|
|
16483
|
-
|
|
16484
|
-
|
|
16485
|
-
|
|
16486
|
-
|
|
16778
|
+
output_default.stop();
|
|
16779
|
+
return this.showSyncResult(result, startTime);
|
|
16780
|
+
} catch (error) {
|
|
16781
|
+
output_default.fail(error.message);
|
|
16782
|
+
return { success: false, error: error.message };
|
|
16783
|
+
}
|
|
16784
|
+
}
|
|
16785
|
+
/**
|
|
16786
|
+
* Display sync results (extracted to avoid duplication)
|
|
16787
|
+
*/
|
|
16788
|
+
async showSyncResult(result, startTime) {
|
|
16789
|
+
const globalConfigResult = await command_installer_default.installGlobalConfig();
|
|
16790
|
+
if (globalConfigResult.success) {
|
|
16791
|
+
console.log(`\u{1F4DD} Updated ${path_manager_default.getDisplayPath(globalConfigResult.path)}`);
|
|
16792
|
+
}
|
|
16793
|
+
console.log(`\u{1F504} Project synced to prjct v${result.cliVersion}
|
|
16487
16794
|
`);
|
|
16488
|
-
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
|
|
16492
|
-
|
|
16795
|
+
console.log("\u{1F4CA} Project Stats");
|
|
16796
|
+
console.log(`\u251C\u2500\u2500 Files: ~${result.stats.fileCount}`);
|
|
16797
|
+
console.log(`\u251C\u2500\u2500 Commits: ${result.git.commits}`);
|
|
16798
|
+
console.log(`\u251C\u2500\u2500 Version: ${result.stats.version}`);
|
|
16799
|
+
console.log(`\u2514\u2500\u2500 Stack: ${result.stats.ecosystem}
|
|
16493
16800
|
`);
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16801
|
+
console.log("\u{1F33F} Git Status");
|
|
16802
|
+
console.log(`\u251C\u2500\u2500 Branch: ${result.git.branch}`);
|
|
16803
|
+
console.log(`\u251C\u2500\u2500 Uncommitted: ${result.git.hasChanges ? "Yes" : "Clean"}`);
|
|
16804
|
+
console.log(`\u2514\u2500\u2500 Recent: ${result.git.weeklyCommits} commits this week
|
|
16498
16805
|
`);
|
|
16499
|
-
|
|
16500
|
-
|
|
16501
|
-
|
|
16806
|
+
console.log("\u{1F4C1} Context Updated");
|
|
16807
|
+
for (const file of result.contextFiles) {
|
|
16808
|
+
console.log(`\u251C\u2500\u2500 ${file}`);
|
|
16809
|
+
}
|
|
16810
|
+
console.log("");
|
|
16811
|
+
if (result.aiTools && result.aiTools.length > 0) {
|
|
16812
|
+
const successTools = result.aiTools.filter((t) => t.success);
|
|
16813
|
+
console.log(`\u{1F916} AI Tools Context (${successTools.length})`);
|
|
16814
|
+
for (const tool of result.aiTools) {
|
|
16815
|
+
const status = tool.success ? "\u2713" : "\u2717";
|
|
16816
|
+
console.log(`\u251C\u2500\u2500 ${status} ${tool.outputFile} (${tool.toolId})`);
|
|
16502
16817
|
}
|
|
16503
16818
|
console.log("");
|
|
16504
|
-
|
|
16505
|
-
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
}
|
|
16511
|
-
console.log("");
|
|
16512
|
-
}
|
|
16513
|
-
const workflowAgents = result.agents.filter((a) => a.type === "workflow").map((a) => a.name);
|
|
16514
|
-
const domainAgents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
|
|
16515
|
-
console.log(`\u{1F916} Agents Regenerated (${result.agents.length})`);
|
|
16516
|
-
console.log(`\u251C\u2500\u2500 Workflow: ${workflowAgents.join(", ")}`);
|
|
16517
|
-
console.log(`\u2514\u2500\u2500 Domain: ${domainAgents.join(", ") || "none"}
|
|
16819
|
+
}
|
|
16820
|
+
const workflowAgents = result.agents.filter((a) => a.type === "workflow").map((a) => a.name);
|
|
16821
|
+
const domainAgents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
|
|
16822
|
+
console.log(`\u{1F916} Agents Regenerated (${result.agents.length})`);
|
|
16823
|
+
console.log(`\u251C\u2500\u2500 Workflow: ${workflowAgents.join(", ")}`);
|
|
16824
|
+
console.log(`\u2514\u2500\u2500 Domain: ${domainAgents.join(", ") || "none"}
|
|
16518
16825
|
`);
|
|
16519
|
-
|
|
16520
|
-
|
|
16521
|
-
|
|
16522
|
-
|
|
16523
|
-
}
|
|
16524
|
-
console.log("");
|
|
16826
|
+
if (result.skills.length > 0) {
|
|
16827
|
+
console.log("\u{1F4E6} Skills Configured");
|
|
16828
|
+
for (const skill of result.skills) {
|
|
16829
|
+
console.log(`\u251C\u2500\u2500 ${skill.agent}.md \u2192 ${skill.skill}`);
|
|
16525
16830
|
}
|
|
16526
|
-
if (result.git.hasChanges) {
|
|
16527
|
-
console.log("\u26A0\uFE0F You have uncommitted changes\n");
|
|
16528
|
-
} else {
|
|
16529
|
-
console.log("\u2728 Repository is clean!\n");
|
|
16530
|
-
}
|
|
16531
|
-
showNextSteps("sync");
|
|
16532
|
-
const elapsed = Date.now() - startTime;
|
|
16533
|
-
const contextFilesCount = result.contextFiles.length + (result.aiTools?.filter((t) => t.success).length || 0);
|
|
16534
|
-
const agentCount = result.agents.length;
|
|
16535
|
-
console.log("\u2500".repeat(45));
|
|
16536
|
-
console.log(`\u{1F4CA} Sync Summary`);
|
|
16537
|
-
console.log(
|
|
16538
|
-
` Stack: ${result.stats.ecosystem} (${result.stats.frameworks.join(", ") || "no frameworks"})`
|
|
16539
|
-
);
|
|
16540
|
-
console.log(
|
|
16541
|
-
` Files: ${result.stats.fileCount} analyzed \u2192 ${contextFilesCount} context files`
|
|
16542
|
-
);
|
|
16543
|
-
console.log(
|
|
16544
|
-
` Agents: ${agentCount} (${result.agents.filter((a) => a.type === "domain").length} domain)`
|
|
16545
|
-
);
|
|
16546
|
-
console.log(` Time: ${(elapsed / 1e3).toFixed(1)}s`);
|
|
16547
16831
|
console.log("");
|
|
16548
|
-
return {
|
|
16549
|
-
success: true,
|
|
16550
|
-
data: result,
|
|
16551
|
-
metrics: {
|
|
16552
|
-
elapsed,
|
|
16553
|
-
contextFilesCount,
|
|
16554
|
-
agentCount,
|
|
16555
|
-
fileCount: result.stats.fileCount
|
|
16556
|
-
}
|
|
16557
|
-
};
|
|
16558
|
-
} catch (error) {
|
|
16559
|
-
console.error("\u274C Error:", error.message);
|
|
16560
|
-
return { success: false, error: error.message };
|
|
16561
16832
|
}
|
|
16833
|
+
if (result.git.hasChanges) {
|
|
16834
|
+
console.log("\u26A0\uFE0F You have uncommitted changes\n");
|
|
16835
|
+
} else {
|
|
16836
|
+
console.log("\u2728 Repository is clean!\n");
|
|
16837
|
+
}
|
|
16838
|
+
showNextSteps("sync");
|
|
16839
|
+
const elapsed = Date.now() - startTime;
|
|
16840
|
+
const contextFilesCount = result.contextFiles.length + (result.aiTools?.filter((t) => t.success).length || 0);
|
|
16841
|
+
const agentCount = result.agents.length;
|
|
16842
|
+
console.log("\u2500".repeat(45));
|
|
16843
|
+
console.log("\u{1F4CA} Sync Summary");
|
|
16844
|
+
console.log(
|
|
16845
|
+
` Stack: ${result.stats.ecosystem} (${result.stats.frameworks.join(", ") || "no frameworks"})`
|
|
16846
|
+
);
|
|
16847
|
+
console.log(` Files: ${result.stats.fileCount} analyzed \u2192 ${contextFilesCount} context files`);
|
|
16848
|
+
console.log(
|
|
16849
|
+
` Agents: ${agentCount} (${result.agents.filter((a) => a.type === "domain").length} domain)`
|
|
16850
|
+
);
|
|
16851
|
+
console.log(` Time: ${(elapsed / 1e3).toFixed(1)}s`);
|
|
16852
|
+
console.log("");
|
|
16853
|
+
return {
|
|
16854
|
+
success: true,
|
|
16855
|
+
data: result,
|
|
16856
|
+
metrics: {
|
|
16857
|
+
elapsed,
|
|
16858
|
+
contextFilesCount,
|
|
16859
|
+
agentCount,
|
|
16860
|
+
fileCount: result.stats.fileCount
|
|
16861
|
+
}
|
|
16862
|
+
};
|
|
16562
16863
|
}
|
|
16563
16864
|
/**
|
|
16564
16865
|
* /p:stats - Value dashboard showing accumulated savings and impact
|
|
@@ -16597,10 +16898,10 @@ var init_analysis2 = __esm({
|
|
|
16597
16898
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
16598
16899
|
let projectName = "Unknown";
|
|
16599
16900
|
try {
|
|
16600
|
-
const
|
|
16901
|
+
const fs47 = __require("node:fs/promises");
|
|
16601
16902
|
const path56 = __require("node:path");
|
|
16602
16903
|
const projectJson = JSON.parse(
|
|
16603
|
-
await
|
|
16904
|
+
await fs47.readFile(path56.join(globalPath, "project.json"), "utf-8")
|
|
16604
16905
|
);
|
|
16605
16906
|
projectName = projectJson.name || "Unknown";
|
|
16606
16907
|
} catch {
|
|
@@ -17207,8 +17508,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
17207
17508
|
const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
|
|
17208
17509
|
const specsPath2 = path36.join(globalPath2, "planning", "specs");
|
|
17209
17510
|
try {
|
|
17210
|
-
const
|
|
17211
|
-
const files = await
|
|
17511
|
+
const fs47 = await import("node:fs/promises");
|
|
17512
|
+
const files = await fs47.readdir(specsPath2);
|
|
17212
17513
|
const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
|
|
17213
17514
|
if (specs.length === 0) {
|
|
17214
17515
|
output_default.warn("no specs yet");
|
|
@@ -17639,7 +17940,7 @@ var init_formatters = __esm({
|
|
|
17639
17940
|
|
|
17640
17941
|
// core/ai-tools/registry.ts
|
|
17641
17942
|
import { execSync as execSync4 } from "node:child_process";
|
|
17642
|
-
import
|
|
17943
|
+
import fs35 from "node:fs";
|
|
17643
17944
|
import os11 from "node:os";
|
|
17644
17945
|
import path37 from "node:path";
|
|
17645
17946
|
function getAIToolConfig(id) {
|
|
@@ -17658,16 +17959,16 @@ function detectInstalledTools(repoPath = process.cwd()) {
|
|
|
17658
17959
|
if (commandExists("claude")) {
|
|
17659
17960
|
detected.push("claude");
|
|
17660
17961
|
}
|
|
17661
|
-
if (commandExists("cursor") ||
|
|
17962
|
+
if (commandExists("cursor") || fs35.existsSync(path37.join(repoPath, ".cursor"))) {
|
|
17662
17963
|
detected.push("cursor");
|
|
17663
17964
|
}
|
|
17664
|
-
if (
|
|
17965
|
+
if (fs35.existsSync(path37.join(repoPath, ".github"))) {
|
|
17665
17966
|
detected.push("copilot");
|
|
17666
17967
|
}
|
|
17667
|
-
if (commandExists("windsurf") ||
|
|
17968
|
+
if (commandExists("windsurf") || fs35.existsSync(path37.join(repoPath, ".windsurf"))) {
|
|
17668
17969
|
detected.push("windsurf");
|
|
17669
17970
|
}
|
|
17670
|
-
if (
|
|
17971
|
+
if (fs35.existsSync(path37.join(repoPath, ".continue")) || fs35.existsSync(path37.join(os11.homedir(), ".continue"))) {
|
|
17671
17972
|
detected.push("continue");
|
|
17672
17973
|
}
|
|
17673
17974
|
return detected;
|
|
@@ -17743,7 +18044,7 @@ var init_registry = __esm({
|
|
|
17743
18044
|
});
|
|
17744
18045
|
|
|
17745
18046
|
// core/ai-tools/generator.ts
|
|
17746
|
-
import
|
|
18047
|
+
import fs36 from "node:fs/promises";
|
|
17747
18048
|
import path38 from "node:path";
|
|
17748
18049
|
async function generateAIToolContexts(context2, globalPath, repoPath, toolIds = DEFAULT_AI_TOOLS) {
|
|
17749
18050
|
const results = [];
|
|
@@ -17783,9 +18084,9 @@ async function generateForTool(context2, config, globalPath, repoPath) {
|
|
|
17783
18084
|
} else {
|
|
17784
18085
|
outputPath = path38.join(globalPath, "context", config.outputFile);
|
|
17785
18086
|
}
|
|
17786
|
-
await
|
|
18087
|
+
await fs36.mkdir(path38.dirname(outputPath), { recursive: true });
|
|
17787
18088
|
try {
|
|
17788
|
-
const existingContent = await
|
|
18089
|
+
const existingContent = await fs36.readFile(outputPath, "utf-8");
|
|
17789
18090
|
const validation = validatePreserveBlocks(existingContent);
|
|
17790
18091
|
if (!validation.valid) {
|
|
17791
18092
|
console.warn(`\u26A0\uFE0F ${config.outputFile} has invalid preserve blocks:`);
|
|
@@ -17796,7 +18097,7 @@ async function generateForTool(context2, config, globalPath, repoPath) {
|
|
|
17796
18097
|
content = mergePreservedSections(content, existingContent);
|
|
17797
18098
|
} catch {
|
|
17798
18099
|
}
|
|
17799
|
-
await
|
|
18100
|
+
await fs36.writeFile(outputPath, content, "utf-8");
|
|
17800
18101
|
return {
|
|
17801
18102
|
toolId: config.id,
|
|
17802
18103
|
outputFile: config.outputFile,
|
|
@@ -17835,7 +18136,7 @@ var init_ai_tools = __esm({
|
|
|
17835
18136
|
});
|
|
17836
18137
|
|
|
17837
18138
|
// core/services/context-generator.ts
|
|
17838
|
-
import
|
|
18139
|
+
import fs37 from "node:fs/promises";
|
|
17839
18140
|
import path39 from "node:path";
|
|
17840
18141
|
var ContextFileGenerator;
|
|
17841
18142
|
var init_context_generator = __esm({
|
|
@@ -17858,7 +18159,7 @@ var init_context_generator = __esm({
|
|
|
17858
18159
|
async writeWithPreservation(filePath, content) {
|
|
17859
18160
|
let finalContent = content;
|
|
17860
18161
|
try {
|
|
17861
|
-
const existingContent = await
|
|
18162
|
+
const existingContent = await fs37.readFile(filePath, "utf-8");
|
|
17862
18163
|
const validation = validatePreserveBlocks(existingContent);
|
|
17863
18164
|
if (!validation.valid) {
|
|
17864
18165
|
const filename = path39.basename(filePath);
|
|
@@ -17870,7 +18171,7 @@ var init_context_generator = __esm({
|
|
|
17870
18171
|
finalContent = mergePreservedSections(content, existingContent);
|
|
17871
18172
|
} catch {
|
|
17872
18173
|
}
|
|
17873
|
-
await
|
|
18174
|
+
await fs37.writeFile(filePath, finalContent, "utf-8");
|
|
17874
18175
|
}
|
|
17875
18176
|
/**
|
|
17876
18177
|
* Generate all context files in parallel
|
|
@@ -17980,7 +18281,7 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
|
|
|
17980
18281
|
let currentTask = null;
|
|
17981
18282
|
try {
|
|
17982
18283
|
const statePath = path39.join(this.config.globalPath, "storage", "state.json");
|
|
17983
|
-
const state = JSON.parse(await
|
|
18284
|
+
const state = JSON.parse(await fs37.readFile(statePath, "utf-8"));
|
|
17984
18285
|
currentTask = state.currentTask;
|
|
17985
18286
|
} catch {
|
|
17986
18287
|
}
|
|
@@ -18005,7 +18306,7 @@ Use \`p. task "description"\` to start working.
|
|
|
18005
18306
|
let queue = { tasks: [] };
|
|
18006
18307
|
try {
|
|
18007
18308
|
const queuePath = path39.join(this.config.globalPath, "storage", "queue.json");
|
|
18008
|
-
queue = JSON.parse(await
|
|
18309
|
+
queue = JSON.parse(await fs37.readFile(queuePath, "utf-8"));
|
|
18009
18310
|
} catch {
|
|
18010
18311
|
}
|
|
18011
18312
|
const content = `# NEXT
|
|
@@ -18021,7 +18322,7 @@ ${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}
|
|
|
18021
18322
|
let ideas = { ideas: [] };
|
|
18022
18323
|
try {
|
|
18023
18324
|
const ideasPath = path39.join(this.config.globalPath, "storage", "ideas.json");
|
|
18024
|
-
ideas = JSON.parse(await
|
|
18325
|
+
ideas = JSON.parse(await fs37.readFile(ideasPath, "utf-8"));
|
|
18025
18326
|
} catch {
|
|
18026
18327
|
}
|
|
18027
18328
|
const content = `# IDEAS
|
|
@@ -18039,7 +18340,7 @@ ${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [
|
|
|
18039
18340
|
};
|
|
18040
18341
|
try {
|
|
18041
18342
|
const shippedPath = path39.join(this.config.globalPath, "storage", "shipped.json");
|
|
18042
|
-
shipped = JSON.parse(await
|
|
18343
|
+
shipped = JSON.parse(await fs37.readFile(shippedPath, "utf-8"));
|
|
18043
18344
|
} catch {
|
|
18044
18345
|
}
|
|
18045
18346
|
const content = `# SHIPPED \u{1F680}
|
|
@@ -18055,7 +18356,7 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
|
|
|
18055
18356
|
});
|
|
18056
18357
|
|
|
18057
18358
|
// core/services/stack-detector.ts
|
|
18058
|
-
import
|
|
18359
|
+
import fs38 from "node:fs/promises";
|
|
18059
18360
|
import path40 from "node:path";
|
|
18060
18361
|
var StackDetector;
|
|
18061
18362
|
var init_stack_detector = __esm({
|
|
@@ -18216,7 +18517,7 @@ var init_stack_detector = __esm({
|
|
|
18216
18517
|
async readPackageJson() {
|
|
18217
18518
|
try {
|
|
18218
18519
|
const pkgPath = path40.join(this.projectPath, "package.json");
|
|
18219
|
-
const content = await
|
|
18520
|
+
const content = await fs38.readFile(pkgPath, "utf-8");
|
|
18220
18521
|
return JSON.parse(content);
|
|
18221
18522
|
} catch {
|
|
18222
18523
|
return null;
|
|
@@ -18227,7 +18528,7 @@ var init_stack_detector = __esm({
|
|
|
18227
18528
|
*/
|
|
18228
18529
|
async fileExists(filename) {
|
|
18229
18530
|
try {
|
|
18230
|
-
await
|
|
18531
|
+
await fs38.access(path40.join(this.projectPath, filename));
|
|
18231
18532
|
return true;
|
|
18232
18533
|
} catch {
|
|
18233
18534
|
return false;
|
|
@@ -18239,7 +18540,7 @@ var init_stack_detector = __esm({
|
|
|
18239
18540
|
|
|
18240
18541
|
// core/services/sync-service.ts
|
|
18241
18542
|
import { exec as exec10 } from "node:child_process";
|
|
18242
|
-
import
|
|
18543
|
+
import fs39 from "node:fs/promises";
|
|
18243
18544
|
import path41 from "node:path";
|
|
18244
18545
|
import { promisify as promisify10 } from "node:util";
|
|
18245
18546
|
var execAsync5, SyncService, syncService;
|
|
@@ -18386,7 +18687,7 @@ var init_sync_service = __esm({
|
|
|
18386
18687
|
async ensureDirectories() {
|
|
18387
18688
|
const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
|
|
18388
18689
|
await Promise.all(
|
|
18389
|
-
dirs.map((dir) =>
|
|
18690
|
+
dirs.map((dir) => fs39.mkdir(path41.join(this.globalPath, dir), { recursive: true }))
|
|
18390
18691
|
);
|
|
18391
18692
|
}
|
|
18392
18693
|
// ==========================================================================
|
|
@@ -18473,7 +18774,7 @@ var init_sync_service = __esm({
|
|
|
18473
18774
|
}
|
|
18474
18775
|
try {
|
|
18475
18776
|
const pkgPath = path41.join(this.projectPath, "package.json");
|
|
18476
|
-
const pkg = JSON.parse(await
|
|
18777
|
+
const pkg = JSON.parse(await fs39.readFile(pkgPath, "utf-8"));
|
|
18477
18778
|
stats.version = pkg.version || "0.0.0";
|
|
18478
18779
|
stats.name = pkg.name || stats.name;
|
|
18479
18780
|
stats.ecosystem = "JavaScript";
|
|
@@ -18583,10 +18884,10 @@ var init_sync_service = __esm({
|
|
|
18583
18884
|
const agents = [];
|
|
18584
18885
|
const agentsPath = path41.join(this.globalPath, "agents");
|
|
18585
18886
|
try {
|
|
18586
|
-
const files = await
|
|
18887
|
+
const files = await fs39.readdir(agentsPath);
|
|
18587
18888
|
for (const file of files) {
|
|
18588
18889
|
if (file.endsWith(".md")) {
|
|
18589
|
-
await
|
|
18890
|
+
await fs39.unlink(path41.join(agentsPath, file));
|
|
18590
18891
|
}
|
|
18591
18892
|
}
|
|
18592
18893
|
} catch {
|
|
@@ -18635,11 +18936,11 @@ var init_sync_service = __esm({
|
|
|
18635
18936
|
"workflow",
|
|
18636
18937
|
`${name}.md`
|
|
18637
18938
|
);
|
|
18638
|
-
content = await
|
|
18939
|
+
content = await fs39.readFile(templatePath, "utf-8");
|
|
18639
18940
|
} catch {
|
|
18640
18941
|
content = this.generateMinimalWorkflowAgent(name);
|
|
18641
18942
|
}
|
|
18642
|
-
await
|
|
18943
|
+
await fs39.writeFile(path41.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
18643
18944
|
}
|
|
18644
18945
|
async generateDomainAgent(name, agentsPath, stats, stack) {
|
|
18645
18946
|
let content = "";
|
|
@@ -18653,14 +18954,14 @@ var init_sync_service = __esm({
|
|
|
18653
18954
|
"domain",
|
|
18654
18955
|
`${name}.md`
|
|
18655
18956
|
);
|
|
18656
|
-
content = await
|
|
18957
|
+
content = await fs39.readFile(templatePath, "utf-8");
|
|
18657
18958
|
content = content.replace("{projectName}", stats.name);
|
|
18658
18959
|
content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
|
|
18659
18960
|
content = content.replace("{ecosystem}", stats.ecosystem);
|
|
18660
18961
|
} catch {
|
|
18661
18962
|
content = this.generateMinimalDomainAgent(name, stats, stack);
|
|
18662
18963
|
}
|
|
18663
|
-
await
|
|
18964
|
+
await fs39.writeFile(path41.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
18664
18965
|
}
|
|
18665
18966
|
generateMinimalWorkflowAgent(name) {
|
|
18666
18967
|
const descriptions = {
|
|
@@ -18728,7 +19029,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18728
19029
|
})),
|
|
18729
19030
|
agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
|
|
18730
19031
|
};
|
|
18731
|
-
|
|
19032
|
+
fs39.writeFile(
|
|
18732
19033
|
path41.join(this.globalPath, "config", "skills.json"),
|
|
18733
19034
|
JSON.stringify(skillsConfig, null, 2),
|
|
18734
19035
|
"utf-8"
|
|
@@ -18754,7 +19055,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18754
19055
|
const projectJsonPath = path41.join(this.globalPath, "project.json");
|
|
18755
19056
|
let existing = {};
|
|
18756
19057
|
try {
|
|
18757
|
-
existing = JSON.parse(await
|
|
19058
|
+
existing = JSON.parse(await fs39.readFile(projectJsonPath, "utf-8"));
|
|
18758
19059
|
} catch {
|
|
18759
19060
|
}
|
|
18760
19061
|
const updated = {
|
|
@@ -18773,7 +19074,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18773
19074
|
createdAt: existing.createdAt || date_helper_default.getTimestamp(),
|
|
18774
19075
|
lastSync: date_helper_default.getTimestamp()
|
|
18775
19076
|
};
|
|
18776
|
-
await
|
|
19077
|
+
await fs39.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
|
|
18777
19078
|
}
|
|
18778
19079
|
// ==========================================================================
|
|
18779
19080
|
// STATE.JSON UPDATE
|
|
@@ -18782,7 +19083,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18782
19083
|
const statePath = path41.join(this.globalPath, "storage", "state.json");
|
|
18783
19084
|
let state = {};
|
|
18784
19085
|
try {
|
|
18785
|
-
state = JSON.parse(await
|
|
19086
|
+
state = JSON.parse(await fs39.readFile(statePath, "utf-8"));
|
|
18786
19087
|
} catch {
|
|
18787
19088
|
}
|
|
18788
19089
|
state.projectId = this.projectId;
|
|
@@ -18809,7 +19110,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18809
19110
|
lastAction: "Synced project",
|
|
18810
19111
|
nextAction: 'Run `p. task "description"` to start working'
|
|
18811
19112
|
};
|
|
18812
|
-
await
|
|
19113
|
+
await fs39.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
|
|
18813
19114
|
}
|
|
18814
19115
|
// ==========================================================================
|
|
18815
19116
|
// MEMORY LOGGING
|
|
@@ -18824,7 +19125,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18824
19125
|
fileCount: stats.fileCount,
|
|
18825
19126
|
commitCount: git.commits
|
|
18826
19127
|
};
|
|
18827
|
-
await
|
|
19128
|
+
await fs39.appendFile(memoryPath, `${JSON.stringify(event)}
|
|
18828
19129
|
`, "utf-8");
|
|
18829
19130
|
}
|
|
18830
19131
|
// ==========================================================================
|
|
@@ -18840,12 +19141,12 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18840
19141
|
* Token estimation: ~4 chars per token (industry standard)
|
|
18841
19142
|
*/
|
|
18842
19143
|
async recordSyncMetrics(stats, contextFiles, agents, duration) {
|
|
18843
|
-
const
|
|
19144
|
+
const CHARS_PER_TOKEN3 = 4;
|
|
18844
19145
|
let filteredChars = 0;
|
|
18845
19146
|
for (const file of contextFiles) {
|
|
18846
19147
|
try {
|
|
18847
19148
|
const filePath = path41.join(this.globalPath, file);
|
|
18848
|
-
const content = await
|
|
19149
|
+
const content = await fs39.readFile(filePath, "utf-8");
|
|
18849
19150
|
filteredChars += content.length;
|
|
18850
19151
|
} catch {
|
|
18851
19152
|
}
|
|
@@ -18853,12 +19154,12 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18853
19154
|
for (const agent of agents) {
|
|
18854
19155
|
try {
|
|
18855
19156
|
const agentPath = path41.join(this.globalPath, "agents", `${agent.name}.md`);
|
|
18856
|
-
const content = await
|
|
19157
|
+
const content = await fs39.readFile(agentPath, "utf-8");
|
|
18857
19158
|
filteredChars += content.length;
|
|
18858
19159
|
} catch {
|
|
18859
19160
|
}
|
|
18860
19161
|
}
|
|
18861
|
-
const filteredSize = Math.floor(filteredChars /
|
|
19162
|
+
const filteredSize = Math.floor(filteredChars / CHARS_PER_TOKEN3);
|
|
18862
19163
|
const avgTokensPerFile = 500;
|
|
18863
19164
|
const originalSize = stats.fileCount * avgTokensPerFile;
|
|
18864
19165
|
const compressionRate = originalSize > 0 ? Math.max(0, (originalSize - filteredSize) / originalSize) : 0;
|
|
@@ -18885,7 +19186,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18885
19186
|
// ==========================================================================
|
|
18886
19187
|
async fileExists(filename) {
|
|
18887
19188
|
try {
|
|
18888
|
-
await
|
|
19189
|
+
await fs39.access(path41.join(this.projectPath, filename));
|
|
18889
19190
|
return true;
|
|
18890
19191
|
} catch {
|
|
18891
19192
|
return false;
|
|
@@ -18894,7 +19195,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18894
19195
|
async getCliVersion() {
|
|
18895
19196
|
try {
|
|
18896
19197
|
const pkgPath = path41.join(__dirname, "..", "..", "package.json");
|
|
18897
|
-
const pkg = JSON.parse(await
|
|
19198
|
+
const pkg = JSON.parse(await fs39.readFile(pkgPath, "utf-8"));
|
|
18898
19199
|
return pkg.version || "0.0.0";
|
|
18899
19200
|
} catch {
|
|
18900
19201
|
return "0.0.0";
|
|
@@ -19053,22 +19354,22 @@ __export(uninstall_exports, {
|
|
|
19053
19354
|
});
|
|
19054
19355
|
import { execSync as execSync5 } from "node:child_process";
|
|
19055
19356
|
import fsSync2 from "node:fs";
|
|
19056
|
-
import
|
|
19357
|
+
import fs40 from "node:fs/promises";
|
|
19057
19358
|
import os12 from "node:os";
|
|
19058
19359
|
import path42 from "node:path";
|
|
19059
19360
|
import readline2 from "node:readline";
|
|
19060
|
-
import
|
|
19361
|
+
import chalk9 from "chalk";
|
|
19061
19362
|
async function getDirectorySize(dirPath) {
|
|
19062
19363
|
let totalSize = 0;
|
|
19063
19364
|
try {
|
|
19064
|
-
const entries = await
|
|
19365
|
+
const entries = await fs40.readdir(dirPath, { withFileTypes: true });
|
|
19065
19366
|
for (const entry of entries) {
|
|
19066
19367
|
const entryPath = path42.join(dirPath, entry.name);
|
|
19067
19368
|
if (entry.isDirectory()) {
|
|
19068
19369
|
totalSize += await getDirectorySize(entryPath);
|
|
19069
19370
|
} else {
|
|
19070
19371
|
try {
|
|
19071
|
-
const stats = await
|
|
19372
|
+
const stats = await fs40.stat(entryPath);
|
|
19072
19373
|
totalSize += stats.size;
|
|
19073
19374
|
} catch {
|
|
19074
19375
|
}
|
|
@@ -19087,7 +19388,7 @@ function formatSize(bytes) {
|
|
|
19087
19388
|
}
|
|
19088
19389
|
async function countDirectoryItems(dirPath) {
|
|
19089
19390
|
try {
|
|
19090
|
-
const entries = await
|
|
19391
|
+
const entries = await fs40.readdir(dirPath, { withFileTypes: true });
|
|
19091
19392
|
return entries.filter((e) => e.isDirectory()).length;
|
|
19092
19393
|
} catch {
|
|
19093
19394
|
return 0;
|
|
@@ -19202,7 +19503,7 @@ async function gatherUninstallItems() {
|
|
|
19202
19503
|
}
|
|
19203
19504
|
async function removePrjctSection(filePath) {
|
|
19204
19505
|
try {
|
|
19205
|
-
const content = await
|
|
19506
|
+
const content = await fs40.readFile(filePath, "utf-8");
|
|
19206
19507
|
if (!content.includes(PRJCT_START_MARKER) || !content.includes(PRJCT_END_MARKER)) {
|
|
19207
19508
|
return false;
|
|
19208
19509
|
}
|
|
@@ -19211,9 +19512,9 @@ async function removePrjctSection(filePath) {
|
|
|
19211
19512
|
let newContent = content.substring(0, startIndex) + content.substring(endIndex);
|
|
19212
19513
|
newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
|
|
19213
19514
|
if (!newContent || newContent.trim().length === 0) {
|
|
19214
|
-
await
|
|
19515
|
+
await fs40.unlink(filePath);
|
|
19215
19516
|
} else {
|
|
19216
|
-
await
|
|
19517
|
+
await fs40.writeFile(filePath, `${newContent}
|
|
19217
19518
|
`, "utf-8");
|
|
19218
19519
|
}
|
|
19219
19520
|
return true;
|
|
@@ -19226,7 +19527,7 @@ async function createBackup() {
|
|
|
19226
19527
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
19227
19528
|
const backupDir = path42.join(homeDir, `.prjct-backup-${timestamp}`);
|
|
19228
19529
|
try {
|
|
19229
|
-
await
|
|
19530
|
+
await fs40.mkdir(backupDir, { recursive: true });
|
|
19230
19531
|
const prjctCliPath = path_manager_default.getGlobalBasePath();
|
|
19231
19532
|
if (fsSync2.existsSync(prjctCliPath)) {
|
|
19232
19533
|
await copyDirectory(prjctCliPath, path42.join(backupDir, ".prjct-cli"));
|
|
@@ -19237,15 +19538,15 @@ async function createBackup() {
|
|
|
19237
19538
|
}
|
|
19238
19539
|
}
|
|
19239
19540
|
async function copyDirectory(src, dest) {
|
|
19240
|
-
await
|
|
19241
|
-
const entries = await
|
|
19541
|
+
await fs40.mkdir(dest, { recursive: true });
|
|
19542
|
+
const entries = await fs40.readdir(src, { withFileTypes: true });
|
|
19242
19543
|
for (const entry of entries) {
|
|
19243
19544
|
const srcPath = path42.join(src, entry.name);
|
|
19244
19545
|
const destPath = path42.join(dest, entry.name);
|
|
19245
19546
|
if (entry.isDirectory()) {
|
|
19246
19547
|
await copyDirectory(srcPath, destPath);
|
|
19247
19548
|
} else {
|
|
19248
|
-
await
|
|
19549
|
+
await fs40.copyFile(srcPath, destPath);
|
|
19249
19550
|
}
|
|
19250
19551
|
}
|
|
19251
19552
|
}
|
|
@@ -19261,10 +19562,10 @@ async function performUninstall(items, installation, options) {
|
|
|
19261
19562
|
deleted.push(item.path);
|
|
19262
19563
|
}
|
|
19263
19564
|
} else if (item.type === "directory") {
|
|
19264
|
-
await
|
|
19565
|
+
await fs40.rm(item.path, { recursive: true, force: true });
|
|
19265
19566
|
deleted.push(item.path);
|
|
19266
19567
|
} else if (item.type === "file") {
|
|
19267
|
-
await
|
|
19568
|
+
await fs40.unlink(item.path);
|
|
19268
19569
|
deleted.push(item.path);
|
|
19269
19570
|
}
|
|
19270
19571
|
} catch (error) {
|
|
@@ -19312,7 +19613,7 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
|
|
|
19312
19613
|
const installation = detectInstallation();
|
|
19313
19614
|
const existingItems = items.filter((i) => i.exists);
|
|
19314
19615
|
if (existingItems.length === 0 && !installation.homebrew && !installation.npm) {
|
|
19315
|
-
console.log(
|
|
19616
|
+
console.log(chalk9.yellow("\nNo prjct installation found."));
|
|
19316
19617
|
return {
|
|
19317
19618
|
success: true,
|
|
19318
19619
|
message: "Nothing to uninstall"
|
|
@@ -19320,36 +19621,36 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
|
|
|
19320
19621
|
}
|
|
19321
19622
|
const totalSize = existingItems.reduce((sum, item) => sum + (item.size || 0), 0);
|
|
19322
19623
|
console.log("");
|
|
19323
|
-
console.log(
|
|
19624
|
+
console.log(chalk9.red.bold(" WARNING: This action is DANGEROUS and IRREVERSIBLE"));
|
|
19324
19625
|
console.log("");
|
|
19325
|
-
console.log(
|
|
19626
|
+
console.log(chalk9.white("The following will be permanently deleted:"));
|
|
19326
19627
|
console.log("");
|
|
19327
19628
|
for (const item of existingItems) {
|
|
19328
19629
|
const displayPath = path_manager_default.getDisplayPath(item.path);
|
|
19329
19630
|
let info = "";
|
|
19330
19631
|
if (item.type === "section") {
|
|
19331
|
-
info =
|
|
19632
|
+
info = chalk9.dim("(section only)");
|
|
19332
19633
|
} else if (item.size) {
|
|
19333
|
-
info =
|
|
19634
|
+
info = chalk9.dim(`(${formatSize(item.size)})`);
|
|
19334
19635
|
}
|
|
19335
|
-
console.log(` ${
|
|
19336
|
-
console.log(` ${
|
|
19636
|
+
console.log(` ${chalk9.cyan(displayPath.padEnd(35))} ${info}`);
|
|
19637
|
+
console.log(` ${chalk9.dim(item.description)}`);
|
|
19337
19638
|
console.log("");
|
|
19338
19639
|
}
|
|
19339
19640
|
if (installation.homebrew) {
|
|
19340
|
-
console.log(` ${
|
|
19641
|
+
console.log(` ${chalk9.cyan("Homebrew".padEnd(35))} ${chalk9.dim("prjct-cli formula")}`);
|
|
19341
19642
|
console.log("");
|
|
19342
19643
|
}
|
|
19343
19644
|
if (installation.npm) {
|
|
19344
|
-
console.log(` ${
|
|
19645
|
+
console.log(` ${chalk9.cyan("npm global".padEnd(35))} ${chalk9.dim("prjct-cli package")}`);
|
|
19345
19646
|
console.log("");
|
|
19346
19647
|
}
|
|
19347
19648
|
if (totalSize > 0) {
|
|
19348
|
-
console.log(
|
|
19649
|
+
console.log(chalk9.dim(` Total size: ${formatSize(totalSize)}`));
|
|
19349
19650
|
console.log("");
|
|
19350
19651
|
}
|
|
19351
19652
|
if (options.dryRun) {
|
|
19352
|
-
console.log(
|
|
19653
|
+
console.log(chalk9.yellow("Dry run - no changes made"));
|
|
19353
19654
|
return {
|
|
19354
19655
|
success: true,
|
|
19355
19656
|
message: "Dry run complete",
|
|
@@ -19357,20 +19658,20 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
|
|
|
19357
19658
|
};
|
|
19358
19659
|
}
|
|
19359
19660
|
if (options.backup) {
|
|
19360
|
-
console.log(
|
|
19661
|
+
console.log(chalk9.blue("Creating backup..."));
|
|
19361
19662
|
const backupPath = await createBackup();
|
|
19362
19663
|
if (backupPath) {
|
|
19363
|
-
console.log(
|
|
19664
|
+
console.log(chalk9.green(`Backup created: ${path_manager_default.getDisplayPath(backupPath)}`));
|
|
19364
19665
|
console.log("");
|
|
19365
19666
|
} else {
|
|
19366
|
-
console.log(
|
|
19667
|
+
console.log(chalk9.yellow("Failed to create backup, continuing..."));
|
|
19367
19668
|
}
|
|
19368
19669
|
}
|
|
19369
19670
|
if (!options.force) {
|
|
19370
|
-
console.log(
|
|
19671
|
+
console.log(chalk9.yellow('Type "uninstall" to confirm:'));
|
|
19371
19672
|
const confirmed = await promptConfirmation("> ");
|
|
19372
19673
|
if (!confirmed) {
|
|
19373
|
-
console.log(
|
|
19674
|
+
console.log(chalk9.yellow("\nUninstall cancelled."));
|
|
19374
19675
|
return {
|
|
19375
19676
|
success: false,
|
|
19376
19677
|
message: "Uninstall cancelled by user"
|
|
@@ -19378,22 +19679,22 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
|
|
|
19378
19679
|
}
|
|
19379
19680
|
}
|
|
19380
19681
|
console.log("");
|
|
19381
|
-
console.log(
|
|
19682
|
+
console.log(chalk9.blue("Removing prjct..."));
|
|
19382
19683
|
const { deleted, errors } = await performUninstall(items, installation, options);
|
|
19383
19684
|
console.log("");
|
|
19384
19685
|
if (deleted.length > 0) {
|
|
19385
|
-
console.log(
|
|
19686
|
+
console.log(chalk9.green(`Removed ${deleted.length} items`));
|
|
19386
19687
|
}
|
|
19387
19688
|
if (errors.length > 0) {
|
|
19388
|
-
console.log(
|
|
19689
|
+
console.log(chalk9.yellow(`
|
|
19389
19690
|
${errors.length} errors:`));
|
|
19390
19691
|
for (const error of errors) {
|
|
19391
|
-
console.log(
|
|
19692
|
+
console.log(chalk9.red(` - ${error}`));
|
|
19392
19693
|
}
|
|
19393
19694
|
}
|
|
19394
19695
|
console.log("");
|
|
19395
|
-
console.log(
|
|
19396
|
-
console.log(
|
|
19696
|
+
console.log(chalk9.green("prjct has been uninstalled."));
|
|
19697
|
+
console.log(chalk9.dim("Thanks for using prjct! We hope to see you again."));
|
|
19397
19698
|
console.log("");
|
|
19398
19699
|
return {
|
|
19399
19700
|
success: errors.length === 0,
|
|
@@ -19440,7 +19741,7 @@ __export(watch_service_exports, {
|
|
|
19440
19741
|
watchService: () => watchService
|
|
19441
19742
|
});
|
|
19442
19743
|
import path43 from "node:path";
|
|
19443
|
-
import
|
|
19744
|
+
import chalk10 from "chalk";
|
|
19444
19745
|
import chokidar from "chokidar";
|
|
19445
19746
|
var TRIGGER_PATTERNS, IGNORE_PATTERNS2, WatchService, watchService;
|
|
19446
19747
|
var init_watch_service = __esm({
|
|
@@ -19550,7 +19851,7 @@ var init_watch_service = __esm({
|
|
|
19550
19851
|
async stop() {
|
|
19551
19852
|
if (!this.options.quiet) {
|
|
19552
19853
|
console.log("");
|
|
19553
|
-
console.log(
|
|
19854
|
+
console.log(chalk10.dim(`
|
|
19554
19855
|
\u{1F44B} Stopped watching (${this.syncCount} syncs performed)`));
|
|
19555
19856
|
}
|
|
19556
19857
|
if (this.debounceTimer) {
|
|
@@ -19571,7 +19872,7 @@ var init_watch_service = __esm({
|
|
|
19571
19872
|
this.pendingChanges.add(filePath);
|
|
19572
19873
|
if (this.options.verbose && !this.options.quiet) {
|
|
19573
19874
|
const eventIcon = event === "add" ? "\u2795" : event === "unlink" ? "\u2796" : "\u{1F4DD}";
|
|
19574
|
-
console.log(
|
|
19875
|
+
console.log(chalk10.dim(` ${eventIcon} ${filePath}`));
|
|
19575
19876
|
}
|
|
19576
19877
|
this.scheduleSyncIfNeeded();
|
|
19577
19878
|
}
|
|
@@ -19588,7 +19889,7 @@ var init_watch_service = __esm({
|
|
|
19588
19889
|
if (timeSinceLastSync < this.options.minIntervalMs && this.lastSyncTime > 0) {
|
|
19589
19890
|
const waitTime = this.options.minIntervalMs - timeSinceLastSync;
|
|
19590
19891
|
if (this.options.verbose && !this.options.quiet) {
|
|
19591
|
-
console.log(
|
|
19892
|
+
console.log(chalk10.dim(` \u23F3 Rate limited, waiting ${Math.round(waitTime / 1e3)}s...`));
|
|
19592
19893
|
}
|
|
19593
19894
|
this.debounceTimer = setTimeout(() => this.performSync(), waitTime);
|
|
19594
19895
|
return;
|
|
@@ -19608,7 +19909,7 @@ var init_watch_service = __esm({
|
|
|
19608
19909
|
const filesSummary = changedFiles.length === 1 ? changedFiles[0] : `${changedFiles.length} files`;
|
|
19609
19910
|
console.log(
|
|
19610
19911
|
`
|
|
19611
|
-
${
|
|
19912
|
+
${chalk10.dim(`[${timestamp}]`)} ${chalk10.cyan("\u27F3")} ${filesSummary} changed \u2192 syncing...`
|
|
19612
19913
|
);
|
|
19613
19914
|
}
|
|
19614
19915
|
try {
|
|
@@ -19619,16 +19920,16 @@ ${chalk9.dim(`[${timestamp}]`)} ${chalk9.cyan("\u27F3")} ${filesSummary} changed
|
|
|
19619
19920
|
if (!this.options.quiet) {
|
|
19620
19921
|
const agents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
|
|
19621
19922
|
const agentStr = agents.length > 0 ? ` [${agents.join(", ")}]` : "";
|
|
19622
|
-
console.log(`${
|
|
19923
|
+
console.log(`${chalk10.dim(`[${timestamp}]`)} ${chalk10.green("\u2713")} Synced${agentStr}`);
|
|
19623
19924
|
}
|
|
19624
19925
|
} else {
|
|
19625
19926
|
console.error(
|
|
19626
|
-
`${
|
|
19927
|
+
`${chalk10.dim(`[${timestamp}]`)} ${chalk10.red("\u2717")} Sync failed: ${result.error}`
|
|
19627
19928
|
);
|
|
19628
19929
|
}
|
|
19629
19930
|
} catch (error) {
|
|
19630
19931
|
console.error(
|
|
19631
|
-
`${
|
|
19932
|
+
`${chalk10.dim(`[${timestamp}]`)} ${chalk10.red("\u2717")} Error: ${error.message}`
|
|
19632
19933
|
);
|
|
19633
19934
|
}
|
|
19634
19935
|
}
|
|
@@ -19636,19 +19937,19 @@ ${chalk9.dim(`[${timestamp}]`)} ${chalk9.cyan("\u27F3")} ${filesSummary} changed
|
|
|
19636
19937
|
* Handle watcher errors
|
|
19637
19938
|
*/
|
|
19638
19939
|
handleError(error) {
|
|
19639
|
-
console.error(
|
|
19940
|
+
console.error(chalk10.red(`Watch error: ${error.message}`));
|
|
19640
19941
|
}
|
|
19641
19942
|
/**
|
|
19642
19943
|
* Print startup message
|
|
19643
19944
|
*/
|
|
19644
19945
|
printStartup() {
|
|
19645
19946
|
console.log("");
|
|
19646
|
-
console.log(
|
|
19647
|
-
console.log(
|
|
19648
|
-
console.log(
|
|
19649
|
-
console.log(
|
|
19947
|
+
console.log(chalk10.cyan("\u{1F441}\uFE0F Watching for changes..."));
|
|
19948
|
+
console.log(chalk10.dim(` Project: ${path43.basename(this.projectPath)}`));
|
|
19949
|
+
console.log(chalk10.dim(` Debounce: ${this.options.debounceMs}ms`));
|
|
19950
|
+
console.log(chalk10.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
|
|
19650
19951
|
console.log("");
|
|
19651
|
-
console.log(
|
|
19952
|
+
console.log(chalk10.dim(" Press Ctrl+C to stop"));
|
|
19652
19953
|
console.log("");
|
|
19653
19954
|
}
|
|
19654
19955
|
};
|
|
@@ -20296,7 +20597,7 @@ __export(setup_exports, {
|
|
|
20296
20597
|
run: () => run
|
|
20297
20598
|
});
|
|
20298
20599
|
import { execSync as execSync6 } from "node:child_process";
|
|
20299
|
-
import
|
|
20600
|
+
import fs41 from "node:fs";
|
|
20300
20601
|
import os13 from "node:os";
|
|
20301
20602
|
import path44 from "node:path";
|
|
20302
20603
|
async function installAICLI(provider) {
|
|
@@ -20406,9 +20707,9 @@ async function installGeminiRouter() {
|
|
|
20406
20707
|
const geminiCommandsDir = path44.join(os13.homedir(), ".gemini", "commands");
|
|
20407
20708
|
const routerSource = path44.join(getPackageRoot(), "templates", "commands", "p.toml");
|
|
20408
20709
|
const routerDest = path44.join(geminiCommandsDir, "p.toml");
|
|
20409
|
-
|
|
20410
|
-
if (
|
|
20411
|
-
|
|
20710
|
+
fs41.mkdirSync(geminiCommandsDir, { recursive: true });
|
|
20711
|
+
if (fs41.existsSync(routerSource)) {
|
|
20712
|
+
fs41.copyFileSync(routerSource, routerDest);
|
|
20412
20713
|
return true;
|
|
20413
20714
|
}
|
|
20414
20715
|
return false;
|
|
@@ -20422,12 +20723,12 @@ async function installGeminiGlobalConfig() {
|
|
|
20422
20723
|
const geminiDir = path44.join(os13.homedir(), ".gemini");
|
|
20423
20724
|
const globalConfigPath = path44.join(geminiDir, "GEMINI.md");
|
|
20424
20725
|
const templatePath = path44.join(getPackageRoot(), "templates", "global", "GEMINI.md");
|
|
20425
|
-
|
|
20426
|
-
const templateContent =
|
|
20726
|
+
fs41.mkdirSync(geminiDir, { recursive: true });
|
|
20727
|
+
const templateContent = fs41.readFileSync(templatePath, "utf-8");
|
|
20427
20728
|
let existingContent = "";
|
|
20428
20729
|
let fileExists2 = false;
|
|
20429
20730
|
try {
|
|
20430
|
-
existingContent =
|
|
20731
|
+
existingContent = fs41.readFileSync(globalConfigPath, "utf-8");
|
|
20431
20732
|
fileExists2 = true;
|
|
20432
20733
|
} catch (error) {
|
|
20433
20734
|
if (isNotFoundError(error)) {
|
|
@@ -20437,7 +20738,7 @@ async function installGeminiGlobalConfig() {
|
|
|
20437
20738
|
}
|
|
20438
20739
|
}
|
|
20439
20740
|
if (!fileExists2) {
|
|
20440
|
-
|
|
20741
|
+
fs41.writeFileSync(globalConfigPath, templateContent, "utf-8");
|
|
20441
20742
|
return { success: true, action: "created" };
|
|
20442
20743
|
}
|
|
20443
20744
|
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
@@ -20447,7 +20748,7 @@ async function installGeminiGlobalConfig() {
|
|
|
20447
20748
|
const updatedContent2 = `${existingContent}
|
|
20448
20749
|
|
|
20449
20750
|
${templateContent}`;
|
|
20450
|
-
|
|
20751
|
+
fs41.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
|
|
20451
20752
|
return { success: true, action: "appended" };
|
|
20452
20753
|
}
|
|
20453
20754
|
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
|
|
@@ -20459,7 +20760,7 @@ ${templateContent}`;
|
|
|
20459
20760
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
20460
20761
|
);
|
|
20461
20762
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
20462
|
-
|
|
20763
|
+
fs41.writeFileSync(globalConfigPath, updatedContent, "utf-8");
|
|
20463
20764
|
return { success: true, action: "updated" };
|
|
20464
20765
|
} catch (error) {
|
|
20465
20766
|
console.error(`Gemini config warning: ${error.message}`);
|
|
@@ -20472,14 +20773,14 @@ async function installAntigravitySkill() {
|
|
|
20472
20773
|
const prjctSkillDir = path44.join(antigravitySkillsDir, "prjct");
|
|
20473
20774
|
const skillMdPath = path44.join(prjctSkillDir, "SKILL.md");
|
|
20474
20775
|
const templatePath = path44.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
|
|
20475
|
-
|
|
20476
|
-
const fileExists2 =
|
|
20477
|
-
if (!
|
|
20776
|
+
fs41.mkdirSync(prjctSkillDir, { recursive: true });
|
|
20777
|
+
const fileExists2 = fs41.existsSync(skillMdPath);
|
|
20778
|
+
if (!fs41.existsSync(templatePath)) {
|
|
20478
20779
|
console.error("Antigravity SKILL.md template not found");
|
|
20479
20780
|
return { success: false, action: null };
|
|
20480
20781
|
}
|
|
20481
|
-
const templateContent =
|
|
20482
|
-
|
|
20782
|
+
const templateContent = fs41.readFileSync(templatePath, "utf-8");
|
|
20783
|
+
fs41.writeFileSync(skillMdPath, templateContent, "utf-8");
|
|
20483
20784
|
return { success: true, action: fileExists2 ? "updated" : "created" };
|
|
20484
20785
|
} catch (error) {
|
|
20485
20786
|
console.error(`Antigravity skill warning: ${error.message}`);
|
|
@@ -20504,18 +20805,18 @@ async function installCursorProject(projectRoot) {
|
|
|
20504
20805
|
const routerMdcDest = path44.join(rulesDir, "prjct.mdc");
|
|
20505
20806
|
const routerMdcSource = path44.join(getPackageRoot(), "templates", "cursor", "router.mdc");
|
|
20506
20807
|
const cursorCommandsSource = path44.join(getPackageRoot(), "templates", "cursor", "commands");
|
|
20507
|
-
|
|
20508
|
-
|
|
20509
|
-
if (
|
|
20510
|
-
|
|
20808
|
+
fs41.mkdirSync(rulesDir, { recursive: true });
|
|
20809
|
+
fs41.mkdirSync(commandsDir, { recursive: true });
|
|
20810
|
+
if (fs41.existsSync(routerMdcSource)) {
|
|
20811
|
+
fs41.copyFileSync(routerMdcSource, routerMdcDest);
|
|
20511
20812
|
result.rulesCreated = true;
|
|
20512
20813
|
}
|
|
20513
|
-
if (
|
|
20514
|
-
const commandFiles =
|
|
20814
|
+
if (fs41.existsSync(cursorCommandsSource)) {
|
|
20815
|
+
const commandFiles = fs41.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
|
|
20515
20816
|
for (const file of commandFiles) {
|
|
20516
20817
|
const src = path44.join(cursorCommandsSource, file);
|
|
20517
20818
|
const dest = path44.join(commandsDir, file);
|
|
20518
|
-
|
|
20819
|
+
fs41.copyFileSync(src, dest);
|
|
20519
20820
|
}
|
|
20520
20821
|
result.commandsCreated = commandFiles.length > 0;
|
|
20521
20822
|
}
|
|
@@ -20544,7 +20845,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
20544
20845
|
let content = "";
|
|
20545
20846
|
let fileExists2 = false;
|
|
20546
20847
|
try {
|
|
20547
|
-
content =
|
|
20848
|
+
content = fs41.readFileSync(gitignorePath, "utf-8");
|
|
20548
20849
|
fileExists2 = true;
|
|
20549
20850
|
} catch (error) {
|
|
20550
20851
|
if (!isNotFoundError(error)) {
|
|
@@ -20559,7 +20860,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
20559
20860
|
${entriesToAdd.join("\n")}
|
|
20560
20861
|
` : `${entriesToAdd.join("\n")}
|
|
20561
20862
|
`;
|
|
20562
|
-
|
|
20863
|
+
fs41.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
20563
20864
|
return true;
|
|
20564
20865
|
} catch (error) {
|
|
20565
20866
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -20567,12 +20868,12 @@ ${entriesToAdd.join("\n")}
|
|
|
20567
20868
|
}
|
|
20568
20869
|
}
|
|
20569
20870
|
function hasCursorProject(projectRoot) {
|
|
20570
|
-
return
|
|
20871
|
+
return fs41.existsSync(path44.join(projectRoot, ".cursor"));
|
|
20571
20872
|
}
|
|
20572
20873
|
function needsCursorRegeneration(projectRoot) {
|
|
20573
20874
|
const cursorDir = path44.join(projectRoot, ".cursor");
|
|
20574
20875
|
const routerPath = path44.join(cursorDir, "rules", "prjct.mdc");
|
|
20575
|
-
return
|
|
20876
|
+
return fs41.existsSync(cursorDir) && !fs41.existsSync(routerPath);
|
|
20576
20877
|
}
|
|
20577
20878
|
async function installWindsurfProject(projectRoot) {
|
|
20578
20879
|
const result = {
|
|
@@ -20593,18 +20894,18 @@ async function installWindsurfProject(projectRoot) {
|
|
|
20593
20894
|
"windsurf",
|
|
20594
20895
|
"workflows"
|
|
20595
20896
|
);
|
|
20596
|
-
|
|
20597
|
-
|
|
20598
|
-
if (
|
|
20599
|
-
|
|
20897
|
+
fs41.mkdirSync(rulesDir, { recursive: true });
|
|
20898
|
+
fs41.mkdirSync(workflowsDir, { recursive: true });
|
|
20899
|
+
if (fs41.existsSync(routerSource)) {
|
|
20900
|
+
fs41.copyFileSync(routerSource, routerDest);
|
|
20600
20901
|
result.rulesCreated = true;
|
|
20601
20902
|
}
|
|
20602
|
-
if (
|
|
20603
|
-
const workflowFiles =
|
|
20903
|
+
if (fs41.existsSync(windsurfWorkflowsSource)) {
|
|
20904
|
+
const workflowFiles = fs41.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
|
|
20604
20905
|
for (const file of workflowFiles) {
|
|
20605
20906
|
const src = path44.join(windsurfWorkflowsSource, file);
|
|
20606
20907
|
const dest = path44.join(workflowsDir, file);
|
|
20607
|
-
|
|
20908
|
+
fs41.copyFileSync(src, dest);
|
|
20608
20909
|
}
|
|
20609
20910
|
result.workflowsCreated = workflowFiles.length > 0;
|
|
20610
20911
|
}
|
|
@@ -20633,7 +20934,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
20633
20934
|
let content = "";
|
|
20634
20935
|
let fileExists2 = false;
|
|
20635
20936
|
try {
|
|
20636
|
-
content =
|
|
20937
|
+
content = fs41.readFileSync(gitignorePath, "utf-8");
|
|
20637
20938
|
fileExists2 = true;
|
|
20638
20939
|
} catch (error) {
|
|
20639
20940
|
if (!isNotFoundError(error)) {
|
|
@@ -20648,7 +20949,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
20648
20949
|
${entriesToAdd.join("\n")}
|
|
20649
20950
|
` : `${entriesToAdd.join("\n")}
|
|
20650
20951
|
`;
|
|
20651
|
-
|
|
20952
|
+
fs41.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
20652
20953
|
return true;
|
|
20653
20954
|
} catch (error) {
|
|
20654
20955
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -20656,32 +20957,32 @@ ${entriesToAdd.join("\n")}
|
|
|
20656
20957
|
}
|
|
20657
20958
|
}
|
|
20658
20959
|
function hasWindsurfProject(projectRoot) {
|
|
20659
|
-
return
|
|
20960
|
+
return fs41.existsSync(path44.join(projectRoot, ".windsurf"));
|
|
20660
20961
|
}
|
|
20661
20962
|
function needsWindsurfRegeneration(projectRoot) {
|
|
20662
20963
|
const windsurfDir = path44.join(projectRoot, ".windsurf");
|
|
20663
20964
|
const routerPath = path44.join(windsurfDir, "rules", "prjct.md");
|
|
20664
|
-
return
|
|
20965
|
+
return fs41.existsSync(windsurfDir) && !fs41.existsSync(routerPath);
|
|
20665
20966
|
}
|
|
20666
20967
|
async function migrateProjectsCliVersion() {
|
|
20667
20968
|
try {
|
|
20668
20969
|
const projectsDir = path44.join(os13.homedir(), ".prjct-cli", "projects");
|
|
20669
|
-
if (!
|
|
20970
|
+
if (!fs41.existsSync(projectsDir)) {
|
|
20670
20971
|
return;
|
|
20671
20972
|
}
|
|
20672
|
-
const projectDirs =
|
|
20973
|
+
const projectDirs = fs41.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
20673
20974
|
let migrated = 0;
|
|
20674
20975
|
for (const projectId of projectDirs) {
|
|
20675
20976
|
const projectJsonPath = path44.join(projectsDir, projectId, "project.json");
|
|
20676
|
-
if (!
|
|
20977
|
+
if (!fs41.existsSync(projectJsonPath)) {
|
|
20677
20978
|
continue;
|
|
20678
20979
|
}
|
|
20679
20980
|
try {
|
|
20680
|
-
const content =
|
|
20981
|
+
const content = fs41.readFileSync(projectJsonPath, "utf8");
|
|
20681
20982
|
const project = JSON.parse(content);
|
|
20682
20983
|
if (project.cliVersion !== VERSION) {
|
|
20683
20984
|
project.cliVersion = VERSION;
|
|
20684
|
-
|
|
20985
|
+
fs41.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
20685
20986
|
migrated++;
|
|
20686
20987
|
}
|
|
20687
20988
|
} catch (error) {
|
|
@@ -20701,9 +21002,9 @@ async function migrateProjectsCliVersion() {
|
|
|
20701
21002
|
}
|
|
20702
21003
|
function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
20703
21004
|
let settings = {};
|
|
20704
|
-
if (
|
|
21005
|
+
if (fs41.existsSync(settingsPath)) {
|
|
20705
21006
|
try {
|
|
20706
|
-
settings = JSON.parse(
|
|
21007
|
+
settings = JSON.parse(fs41.readFileSync(settingsPath, "utf8"));
|
|
20707
21008
|
} catch (error) {
|
|
20708
21009
|
if (!(error instanceof SyntaxError)) {
|
|
20709
21010
|
throw error;
|
|
@@ -20711,7 +21012,7 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
|
20711
21012
|
}
|
|
20712
21013
|
}
|
|
20713
21014
|
settings.statusLine = { type: "command", command: statusLinePath };
|
|
20714
|
-
|
|
21015
|
+
fs41.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
20715
21016
|
}
|
|
20716
21017
|
async function installStatusLine() {
|
|
20717
21018
|
try {
|
|
@@ -20730,23 +21031,23 @@ async function installStatusLine() {
|
|
|
20730
21031
|
const sourceLibDir = path44.join(assetsDir, "lib");
|
|
20731
21032
|
const sourceComponentsDir = path44.join(assetsDir, "components");
|
|
20732
21033
|
const sourceConfigPath = path44.join(assetsDir, "default-config.json");
|
|
20733
|
-
if (!
|
|
20734
|
-
|
|
21034
|
+
if (!fs41.existsSync(claudeDir)) {
|
|
21035
|
+
fs41.mkdirSync(claudeDir, { recursive: true });
|
|
20735
21036
|
}
|
|
20736
|
-
if (!
|
|
20737
|
-
|
|
21037
|
+
if (!fs41.existsSync(prjctStatusLineDir)) {
|
|
21038
|
+
fs41.mkdirSync(prjctStatusLineDir, { recursive: true });
|
|
20738
21039
|
}
|
|
20739
|
-
if (!
|
|
20740
|
-
|
|
21040
|
+
if (!fs41.existsSync(prjctThemesDir)) {
|
|
21041
|
+
fs41.mkdirSync(prjctThemesDir, { recursive: true });
|
|
20741
21042
|
}
|
|
20742
|
-
if (!
|
|
20743
|
-
|
|
21043
|
+
if (!fs41.existsSync(prjctLibDir)) {
|
|
21044
|
+
fs41.mkdirSync(prjctLibDir, { recursive: true });
|
|
20744
21045
|
}
|
|
20745
|
-
if (!
|
|
20746
|
-
|
|
21046
|
+
if (!fs41.existsSync(prjctComponentsDir)) {
|
|
21047
|
+
fs41.mkdirSync(prjctComponentsDir, { recursive: true });
|
|
20747
21048
|
}
|
|
20748
|
-
if (
|
|
20749
|
-
const existingContent =
|
|
21049
|
+
if (fs41.existsSync(prjctStatusLinePath)) {
|
|
21050
|
+
const existingContent = fs41.readFileSync(prjctStatusLinePath, "utf8");
|
|
20750
21051
|
if (existingContent.includes("CLI_VERSION=")) {
|
|
20751
21052
|
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
20752
21053
|
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
@@ -20754,7 +21055,7 @@ async function installStatusLine() {
|
|
|
20754
21055
|
/CLI_VERSION="[^"]*"/,
|
|
20755
21056
|
`CLI_VERSION="${VERSION}"`
|
|
20756
21057
|
);
|
|
20757
|
-
|
|
21058
|
+
fs41.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
20758
21059
|
}
|
|
20759
21060
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
20760
21061
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
@@ -20763,22 +21064,22 @@ async function installStatusLine() {
|
|
|
20763
21064
|
return;
|
|
20764
21065
|
}
|
|
20765
21066
|
}
|
|
20766
|
-
if (
|
|
20767
|
-
let scriptContent =
|
|
21067
|
+
if (fs41.existsSync(sourceScript)) {
|
|
21068
|
+
let scriptContent = fs41.readFileSync(sourceScript, "utf8");
|
|
20768
21069
|
scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
|
|
20769
|
-
|
|
21070
|
+
fs41.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
20770
21071
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
20771
21072
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
20772
|
-
if (
|
|
20773
|
-
const themes =
|
|
21073
|
+
if (fs41.existsSync(sourceThemeDir)) {
|
|
21074
|
+
const themes = fs41.readdirSync(sourceThemeDir);
|
|
20774
21075
|
for (const theme of themes) {
|
|
20775
21076
|
const src = path44.join(sourceThemeDir, theme);
|
|
20776
21077
|
const dest = path44.join(prjctThemesDir, theme);
|
|
20777
|
-
|
|
21078
|
+
fs41.copyFileSync(src, dest);
|
|
20778
21079
|
}
|
|
20779
21080
|
}
|
|
20780
|
-
if (!
|
|
20781
|
-
|
|
21081
|
+
if (!fs41.existsSync(prjctConfigPath) && fs41.existsSync(sourceConfigPath)) {
|
|
21082
|
+
fs41.copyFileSync(sourceConfigPath, prjctConfigPath);
|
|
20782
21083
|
}
|
|
20783
21084
|
} else {
|
|
20784
21085
|
const scriptContent = `#!/bin/bash
|
|
@@ -20813,7 +21114,7 @@ if [ -f "$CONFIG" ]; then
|
|
|
20813
21114
|
fi
|
|
20814
21115
|
echo "prjct"
|
|
20815
21116
|
`;
|
|
20816
|
-
|
|
21117
|
+
fs41.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
20817
21118
|
}
|
|
20818
21119
|
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
20819
21120
|
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
@@ -20824,37 +21125,37 @@ echo "prjct"
|
|
|
20824
21125
|
}
|
|
20825
21126
|
}
|
|
20826
21127
|
function installStatusLineModules(sourceDir, destDir) {
|
|
20827
|
-
if (!
|
|
21128
|
+
if (!fs41.existsSync(sourceDir)) {
|
|
20828
21129
|
return;
|
|
20829
21130
|
}
|
|
20830
|
-
const files =
|
|
21131
|
+
const files = fs41.readdirSync(sourceDir);
|
|
20831
21132
|
for (const file of files) {
|
|
20832
21133
|
if (file.endsWith(".sh")) {
|
|
20833
21134
|
const src = path44.join(sourceDir, file);
|
|
20834
21135
|
const dest = path44.join(destDir, file);
|
|
20835
|
-
|
|
20836
|
-
|
|
21136
|
+
fs41.copyFileSync(src, dest);
|
|
21137
|
+
fs41.chmodSync(dest, 493);
|
|
20837
21138
|
}
|
|
20838
21139
|
}
|
|
20839
21140
|
}
|
|
20840
21141
|
function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
20841
21142
|
try {
|
|
20842
|
-
if (
|
|
20843
|
-
const stats =
|
|
21143
|
+
if (fs41.existsSync(linkPath)) {
|
|
21144
|
+
const stats = fs41.lstatSync(linkPath);
|
|
20844
21145
|
if (stats.isSymbolicLink()) {
|
|
20845
|
-
const existingTarget =
|
|
21146
|
+
const existingTarget = fs41.readlinkSync(linkPath);
|
|
20846
21147
|
if (existingTarget === targetPath) {
|
|
20847
21148
|
return;
|
|
20848
21149
|
}
|
|
20849
21150
|
}
|
|
20850
|
-
|
|
21151
|
+
fs41.unlinkSync(linkPath);
|
|
20851
21152
|
}
|
|
20852
|
-
|
|
21153
|
+
fs41.symlinkSync(targetPath, linkPath);
|
|
20853
21154
|
} catch (_error) {
|
|
20854
21155
|
try {
|
|
20855
|
-
if (
|
|
20856
|
-
|
|
20857
|
-
|
|
21156
|
+
if (fs41.existsSync(targetPath)) {
|
|
21157
|
+
fs41.copyFileSync(targetPath, linkPath);
|
|
21158
|
+
fs41.chmodSync(linkPath, 493);
|
|
20858
21159
|
}
|
|
20859
21160
|
} catch (copyError) {
|
|
20860
21161
|
if (!isNotFoundError(copyError)) {
|
|
@@ -21538,7 +21839,7 @@ ${"\u2550".repeat(50)}
|
|
|
21538
21839
|
});
|
|
21539
21840
|
|
|
21540
21841
|
// core/commands/context.ts
|
|
21541
|
-
import
|
|
21842
|
+
import fs42 from "node:fs/promises";
|
|
21542
21843
|
import path46 from "node:path";
|
|
21543
21844
|
var ContextCommands, contextCommands;
|
|
21544
21845
|
var init_context = __esm({
|
|
@@ -21666,7 +21967,7 @@ var init_context = __esm({
|
|
|
21666
21967
|
async loadRepoAnalysis(globalPath) {
|
|
21667
21968
|
try {
|
|
21668
21969
|
const analysisPath = path46.join(globalPath, "analysis", "repo-analysis.json");
|
|
21669
|
-
const content = await
|
|
21970
|
+
const content = await fs42.readFile(analysisPath, "utf-8");
|
|
21670
21971
|
const data = JSON.parse(content);
|
|
21671
21972
|
return {
|
|
21672
21973
|
ecosystem: data.ecosystem || "unknown",
|
|
@@ -22162,9 +22463,9 @@ var init_maintenance = __esm({
|
|
|
22162
22463
|
});
|
|
22163
22464
|
|
|
22164
22465
|
// core/commands/setup.ts
|
|
22165
|
-
import
|
|
22466
|
+
import fs43 from "node:fs";
|
|
22166
22467
|
import path50 from "node:path";
|
|
22167
|
-
import
|
|
22468
|
+
import chalk11 from "chalk";
|
|
22168
22469
|
var SetupCommands;
|
|
22169
22470
|
var init_setup2 = __esm({
|
|
22170
22471
|
"core/commands/setup.ts"() {
|
|
@@ -22348,11 +22649,11 @@ fi
|
|
|
22348
22649
|
# Default: show prjct branding
|
|
22349
22650
|
echo "\u26A1 prjct"
|
|
22350
22651
|
`;
|
|
22351
|
-
|
|
22652
|
+
fs43.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
22352
22653
|
let settings = {};
|
|
22353
|
-
if (
|
|
22654
|
+
if (fs43.existsSync(settingsPath)) {
|
|
22354
22655
|
try {
|
|
22355
|
-
settings = JSON.parse(
|
|
22656
|
+
settings = JSON.parse(fs43.readFileSync(settingsPath, "utf8"));
|
|
22356
22657
|
} catch (_error) {
|
|
22357
22658
|
}
|
|
22358
22659
|
}
|
|
@@ -22360,7 +22661,7 @@ echo "\u26A1 prjct"
|
|
|
22360
22661
|
type: "command",
|
|
22361
22662
|
command: statusLinePath
|
|
22362
22663
|
};
|
|
22363
|
-
|
|
22664
|
+
fs43.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
22364
22665
|
return { success: true };
|
|
22365
22666
|
} catch (error) {
|
|
22366
22667
|
return { success: false, error: error.message };
|
|
@@ -22370,45 +22671,45 @@ echo "\u26A1 prjct"
|
|
|
22370
22671
|
* Show beautiful ASCII art with quick start
|
|
22371
22672
|
*/
|
|
22372
22673
|
showAsciiArt() {
|
|
22373
|
-
console.log(
|
|
22674
|
+
console.log(chalk11.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
22374
22675
|
console.log("");
|
|
22375
|
-
console.log(
|
|
22376
|
-
console.log(
|
|
22377
|
-
console.log(
|
|
22378
|
-
console.log(
|
|
22379
|
-
console.log(
|
|
22380
|
-
console.log(
|
|
22676
|
+
console.log(chalk11.bold.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"));
|
|
22677
|
+
console.log(chalk11.bold.cyan(" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D"));
|
|
22678
|
+
console.log(chalk11.bold.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"));
|
|
22679
|
+
console.log(chalk11.bold.cyan(" \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"));
|
|
22680
|
+
console.log(chalk11.bold.cyan(" \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551"));
|
|
22681
|
+
console.log(chalk11.bold.cyan(" \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D"));
|
|
22381
22682
|
console.log("");
|
|
22382
22683
|
console.log(
|
|
22383
|
-
` ${
|
|
22684
|
+
` ${chalk11.bold.cyan("prjct")}${chalk11.magenta("/")}${chalk11.green("cli")} ${chalk11.dim.white(`v${VERSION} installed`)}`
|
|
22384
22685
|
);
|
|
22385
22686
|
console.log("");
|
|
22386
|
-
console.log(` ${
|
|
22387
|
-
console.log(` ${
|
|
22388
|
-
console.log(` ${
|
|
22687
|
+
console.log(` ${chalk11.yellow("\u26A1")} Ship faster with zero friction`);
|
|
22688
|
+
console.log(` ${chalk11.green("\u{1F4DD}")} From idea to technical tasks in minutes`);
|
|
22689
|
+
console.log(` ${chalk11.cyan("\u{1F916}")} Perfect context for AI agents`);
|
|
22389
22690
|
console.log("");
|
|
22390
|
-
console.log(
|
|
22691
|
+
console.log(chalk11.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
22391
22692
|
console.log("");
|
|
22392
|
-
console.log(
|
|
22393
|
-
console.log(
|
|
22693
|
+
console.log(chalk11.bold.cyan("\u{1F680} Quick Start"));
|
|
22694
|
+
console.log(chalk11.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
22394
22695
|
console.log("");
|
|
22395
|
-
console.log(` ${
|
|
22396
|
-
console.log(` ${
|
|
22696
|
+
console.log(` ${chalk11.bold("1.")} Initialize your project:`);
|
|
22697
|
+
console.log(` ${chalk11.green("cd your-project && prjct init")}`);
|
|
22397
22698
|
console.log("");
|
|
22398
|
-
console.log(` ${
|
|
22399
|
-
console.log(` ${
|
|
22699
|
+
console.log(` ${chalk11.bold("2.")} Start your first task:`);
|
|
22700
|
+
console.log(` ${chalk11.green('prjct task "build auth"')}`);
|
|
22400
22701
|
console.log("");
|
|
22401
|
-
console.log(` ${
|
|
22402
|
-
console.log(` ${
|
|
22702
|
+
console.log(` ${chalk11.bold("3.")} Ship & celebrate:`);
|
|
22703
|
+
console.log(` ${chalk11.green('prjct ship "user login"')}`);
|
|
22403
22704
|
console.log("");
|
|
22404
|
-
console.log(
|
|
22705
|
+
console.log(chalk11.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
22405
22706
|
console.log("");
|
|
22406
|
-
console.log(` ${
|
|
22707
|
+
console.log(` ${chalk11.dim("Documentation:")} ${chalk11.cyan("https://prjct.app")}`);
|
|
22407
22708
|
console.log(
|
|
22408
|
-
` ${
|
|
22709
|
+
` ${chalk11.dim("Report issues:")} ${chalk11.cyan("https://github.com/jlopezlira/prjct-cli/issues")}`
|
|
22409
22710
|
);
|
|
22410
22711
|
console.log("");
|
|
22411
|
-
console.log(
|
|
22712
|
+
console.log(chalk11.bold.magenta("Happy shipping! \u{1F680}"));
|
|
22412
22713
|
console.log("");
|
|
22413
22714
|
}
|
|
22414
22715
|
};
|
|
@@ -23718,7 +24019,7 @@ var init_linear = __esm({
|
|
|
23718
24019
|
});
|
|
23719
24020
|
|
|
23720
24021
|
// core/utils/project-credentials.ts
|
|
23721
|
-
import
|
|
24022
|
+
import fs44 from "node:fs";
|
|
23722
24023
|
import os14 from "node:os";
|
|
23723
24024
|
import path53 from "node:path";
|
|
23724
24025
|
function getCredentialsPath(projectId) {
|
|
@@ -23726,11 +24027,11 @@ function getCredentialsPath(projectId) {
|
|
|
23726
24027
|
}
|
|
23727
24028
|
async function getProjectCredentials(projectId) {
|
|
23728
24029
|
const credPath = getCredentialsPath(projectId);
|
|
23729
|
-
if (!
|
|
24030
|
+
if (!fs44.existsSync(credPath)) {
|
|
23730
24031
|
return {};
|
|
23731
24032
|
}
|
|
23732
24033
|
try {
|
|
23733
|
-
return JSON.parse(
|
|
24034
|
+
return JSON.parse(fs44.readFileSync(credPath, "utf-8"));
|
|
23734
24035
|
} catch (error) {
|
|
23735
24036
|
console.error("[project-credentials] Failed to read credentials:", error.message);
|
|
23736
24037
|
return {};
|
|
@@ -24303,7 +24604,7 @@ var require_package = __commonJS({
|
|
|
24303
24604
|
"package.json"(exports, module) {
|
|
24304
24605
|
module.exports = {
|
|
24305
24606
|
name: "prjct-cli",
|
|
24306
|
-
version: "0.
|
|
24607
|
+
version: "0.51.0",
|
|
24307
24608
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
24308
24609
|
main: "core/index.ts",
|
|
24309
24610
|
bin: {
|
|
@@ -24408,7 +24709,7 @@ var require_package = __commonJS({
|
|
|
24408
24709
|
|
|
24409
24710
|
// core/index.ts
|
|
24410
24711
|
var core_exports = {};
|
|
24411
|
-
import
|
|
24712
|
+
import fs45 from "node:fs";
|
|
24412
24713
|
import os15 from "node:os";
|
|
24413
24714
|
import path54 from "node:path";
|
|
24414
24715
|
async function main() {
|
|
@@ -24537,10 +24838,10 @@ function displayVersion(version) {
|
|
|
24537
24838
|
const detection = detectAllProviders();
|
|
24538
24839
|
const claudeCommandPath = path54.join(os15.homedir(), ".claude", "commands", "p.md");
|
|
24539
24840
|
const geminiCommandPath = path54.join(os15.homedir(), ".gemini", "commands", "p.toml");
|
|
24540
|
-
const claudeConfigured =
|
|
24541
|
-
const geminiConfigured =
|
|
24542
|
-
const cursorConfigured =
|
|
24543
|
-
const cursorExists =
|
|
24841
|
+
const claudeConfigured = fs45.existsSync(claudeCommandPath);
|
|
24842
|
+
const geminiConfigured = fs45.existsSync(geminiCommandPath);
|
|
24843
|
+
const cursorConfigured = fs45.existsSync(path54.join(process.cwd(), ".cursor", "commands", "sync.md"));
|
|
24844
|
+
const cursorExists = fs45.existsSync(path54.join(process.cwd(), ".cursor"));
|
|
24544
24845
|
console.log(`
|
|
24545
24846
|
${CYAN3}p/${RESET5} prjct v${version}
|
|
24546
24847
|
${DIM6}Context layer for AI coding agents${RESET5}
|
|
@@ -24673,7 +24974,7 @@ var init_core = __esm({
|
|
|
24673
24974
|
init_ai_provider();
|
|
24674
24975
|
init_config_manager();
|
|
24675
24976
|
init_editors_config();
|
|
24676
|
-
import
|
|
24977
|
+
import fs46 from "node:fs";
|
|
24677
24978
|
import os16 from "node:os";
|
|
24678
24979
|
import path55 from "node:path";
|
|
24679
24980
|
|
|
@@ -25418,13 +25719,13 @@ function checkRoutersInstalled() {
|
|
|
25418
25719
|
const detection = detectAllProviders();
|
|
25419
25720
|
if (detection.claude.installed) {
|
|
25420
25721
|
const claudeRouter = path55.join(home, ".claude", "commands", "p.md");
|
|
25421
|
-
if (!
|
|
25722
|
+
if (!fs46.existsSync(claudeRouter)) {
|
|
25422
25723
|
return false;
|
|
25423
25724
|
}
|
|
25424
25725
|
}
|
|
25425
25726
|
if (detection.gemini.installed) {
|
|
25426
25727
|
const geminiRouter = path55.join(home, ".gemini", "commands", "p.toml");
|
|
25427
|
-
if (!
|
|
25728
|
+
if (!fs46.existsSync(geminiRouter)) {
|
|
25428
25729
|
return false;
|
|
25429
25730
|
}
|
|
25430
25731
|
}
|
|
@@ -25544,12 +25845,12 @@ if (args[0] === "start" || args[0] === "setup") {
|
|
|
25544
25845
|
const detection = detectAllProviders();
|
|
25545
25846
|
const home = os16.homedir();
|
|
25546
25847
|
const cwd = process.cwd();
|
|
25547
|
-
const claudeConfigured =
|
|
25548
|
-
const geminiConfigured =
|
|
25549
|
-
const cursorDetected =
|
|
25550
|
-
const cursorConfigured =
|
|
25551
|
-
const windsurfDetected =
|
|
25552
|
-
const windsurfConfigured =
|
|
25848
|
+
const claudeConfigured = fs46.existsSync(path55.join(home, ".claude", "commands", "p.md"));
|
|
25849
|
+
const geminiConfigured = fs46.existsSync(path55.join(home, ".gemini", "commands", "p.toml"));
|
|
25850
|
+
const cursorDetected = fs46.existsSync(path55.join(cwd, ".cursor"));
|
|
25851
|
+
const cursorConfigured = fs46.existsSync(path55.join(cwd, ".cursor", "rules", "prjct.mdc"));
|
|
25852
|
+
const windsurfDetected = fs46.existsSync(path55.join(cwd, ".windsurf"));
|
|
25853
|
+
const windsurfConfigured = fs46.existsSync(path55.join(cwd, ".windsurf", "rules", "prjct.md"));
|
|
25553
25854
|
const GREEN7 = "\x1B[32m";
|
|
25554
25855
|
console.log(`
|
|
25555
25856
|
${CYAN4}p/${RESET6} prjct v${VERSION}
|
|
@@ -25590,7 +25891,7 @@ ${CYAN4}https://prjct.app${RESET6}
|
|
|
25590
25891
|
} else {
|
|
25591
25892
|
const configPath = path55.join(os16.homedir(), ".prjct-cli", "config", "installed-editors.json");
|
|
25592
25893
|
const routersInstalled = checkRoutersInstalled();
|
|
25593
|
-
if (!
|
|
25894
|
+
if (!fs46.existsSync(configPath) || !routersInstalled) {
|
|
25594
25895
|
console.log(`
|
|
25595
25896
|
${CYAN4}${BOLD4} Welcome to prjct!${RESET6}
|
|
25596
25897
|
|