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