prjct-cli 0.50.0 → 0.52.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 +39 -0
- package/core/agentic/memory-system.ts +96 -18
- 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/types/memory.ts +41 -2
- package/dist/bin/prjct.mjs +694 -333
- package/package.json +1 -1
package/dist/bin/prjct.mjs
CHANGED
|
@@ -3767,8 +3767,8 @@ function tryResolve(basePath, projectPath) {
|
|
|
3767
3767
|
for (const ext of extensions) {
|
|
3768
3768
|
const fullPath = basePath + ext;
|
|
3769
3769
|
try {
|
|
3770
|
-
const
|
|
3771
|
-
if (
|
|
3770
|
+
const fs47 = __require("node:fs");
|
|
3771
|
+
if (fs47.existsSync(fullPath) && fs47.statSync(fullPath).isFile()) {
|
|
3772
3772
|
return path12.relative(projectPath, fullPath);
|
|
3773
3773
|
}
|
|
3774
3774
|
} catch {
|
|
@@ -4951,11 +4951,11 @@ async function runSignaturesTool(args2, projectPath) {
|
|
|
4951
4951
|
}
|
|
4952
4952
|
};
|
|
4953
4953
|
}
|
|
4954
|
-
const
|
|
4954
|
+
const fs47 = await import("node:fs/promises");
|
|
4955
4955
|
const path56 = await import("node:path");
|
|
4956
4956
|
const fullPath = path56.isAbsolute(filePath) ? filePath : path56.join(projectPath, filePath);
|
|
4957
4957
|
try {
|
|
4958
|
-
const stat = await
|
|
4958
|
+
const stat = await fs47.stat(fullPath);
|
|
4959
4959
|
if (stat.isDirectory()) {
|
|
4960
4960
|
const results = await extractDirectorySignatures(filePath, projectPath, {
|
|
4961
4961
|
recursive: args2.includes("--recursive") || args2.includes("-r")
|
|
@@ -5022,11 +5022,11 @@ async function runSummaryTool(args2, projectPath) {
|
|
|
5022
5022
|
}
|
|
5023
5023
|
};
|
|
5024
5024
|
}
|
|
5025
|
-
const
|
|
5025
|
+
const fs47 = await import("node:fs/promises");
|
|
5026
5026
|
const path56 = await import("node:path");
|
|
5027
5027
|
const fullPath = path56.isAbsolute(targetPath) ? targetPath : path56.join(projectPath, targetPath);
|
|
5028
5028
|
try {
|
|
5029
|
-
const stat = await
|
|
5029
|
+
const stat = await fs47.stat(fullPath);
|
|
5030
5030
|
if (stat.isDirectory()) {
|
|
5031
5031
|
const results = await summarizeDirectory(targetPath, projectPath, {
|
|
5032
5032
|
recursive: args2.includes("--recursive") || args2.includes("-r")
|
|
@@ -8568,6 +8568,12 @@ var init_jsonl_helper = __esm({
|
|
|
8568
8568
|
});
|
|
8569
8569
|
|
|
8570
8570
|
// core/types/memory.ts
|
|
8571
|
+
function calculateConfidence(count, userConfirmed = false) {
|
|
8572
|
+
if (userConfirmed) return "high";
|
|
8573
|
+
if (count >= 6) return "high";
|
|
8574
|
+
if (count >= 3) return "medium";
|
|
8575
|
+
return "low";
|
|
8576
|
+
}
|
|
8571
8577
|
var MEMORY_TAGS;
|
|
8572
8578
|
var init_memory = __esm({
|
|
8573
8579
|
"core/types/memory.ts"() {
|
|
@@ -8591,6 +8597,7 @@ var init_memory = __esm({
|
|
|
8591
8597
|
CONFIRMATION_LEVEL: "confirmation_level",
|
|
8592
8598
|
AGENT_PREFERENCE: "agent_preference"
|
|
8593
8599
|
};
|
|
8600
|
+
__name(calculateConfidence, "calculateConfidence");
|
|
8594
8601
|
}
|
|
8595
8602
|
});
|
|
8596
8603
|
|
|
@@ -8782,7 +8789,7 @@ var init_memory_system = __esm({
|
|
|
8782
8789
|
async savePatterns(projectId) {
|
|
8783
8790
|
return this.save(projectId);
|
|
8784
8791
|
}
|
|
8785
|
-
async recordDecision(projectId, key, value, context2 = "") {
|
|
8792
|
+
async recordDecision(projectId, key, value, context2 = "", options = {}) {
|
|
8786
8793
|
const patterns = await this.load(projectId);
|
|
8787
8794
|
const now = getTimestamp();
|
|
8788
8795
|
if (!patterns.decisions[key]) {
|
|
@@ -8791,8 +8798,9 @@ var init_memory_system = __esm({
|
|
|
8791
8798
|
count: 1,
|
|
8792
8799
|
firstSeen: now,
|
|
8793
8800
|
lastSeen: now,
|
|
8794
|
-
confidence: "low",
|
|
8795
|
-
contexts: [context2].filter(Boolean)
|
|
8801
|
+
confidence: options.userConfirmed ? "high" : "low",
|
|
8802
|
+
contexts: [context2].filter(Boolean),
|
|
8803
|
+
userConfirmed: options.userConfirmed || false
|
|
8796
8804
|
};
|
|
8797
8805
|
} else {
|
|
8798
8806
|
const decision = patterns.decisions[key];
|
|
@@ -8802,20 +8810,30 @@ var init_memory_system = __esm({
|
|
|
8802
8810
|
if (context2 && !decision.contexts.includes(context2)) {
|
|
8803
8811
|
decision.contexts.push(context2);
|
|
8804
8812
|
}
|
|
8805
|
-
if (
|
|
8806
|
-
decision.
|
|
8807
|
-
} else if (decision.count >= 3) {
|
|
8808
|
-
decision.confidence = "medium";
|
|
8813
|
+
if (options.userConfirmed) {
|
|
8814
|
+
decision.userConfirmed = true;
|
|
8809
8815
|
}
|
|
8816
|
+
decision.confidence = calculateConfidence(decision.count, decision.userConfirmed);
|
|
8810
8817
|
} else {
|
|
8811
8818
|
decision.value = value;
|
|
8812
8819
|
decision.count = 1;
|
|
8813
8820
|
decision.lastSeen = now;
|
|
8814
|
-
decision.
|
|
8821
|
+
decision.userConfirmed = options.userConfirmed || false;
|
|
8822
|
+
decision.confidence = options.userConfirmed ? "high" : "low";
|
|
8815
8823
|
}
|
|
8816
8824
|
}
|
|
8817
8825
|
await this.save(projectId);
|
|
8818
8826
|
}
|
|
8827
|
+
async confirmDecision(projectId, key) {
|
|
8828
|
+
const patterns = await this.load(projectId);
|
|
8829
|
+
const decision = patterns.decisions[key];
|
|
8830
|
+
if (!decision) return false;
|
|
8831
|
+
decision.userConfirmed = true;
|
|
8832
|
+
decision.confidence = "high";
|
|
8833
|
+
decision.lastSeen = getTimestamp();
|
|
8834
|
+
await this.save(projectId);
|
|
8835
|
+
return true;
|
|
8836
|
+
}
|
|
8819
8837
|
async getDecision(projectId, key) {
|
|
8820
8838
|
const patterns = await this.load(projectId);
|
|
8821
8839
|
const decision = patterns.decisions[key];
|
|
@@ -8835,25 +8853,58 @@ var init_memory_system = __esm({
|
|
|
8835
8853
|
...pattern,
|
|
8836
8854
|
count: 1,
|
|
8837
8855
|
firstSeen: now,
|
|
8838
|
-
lastSeen: now
|
|
8856
|
+
lastSeen: now,
|
|
8857
|
+
confidence: "low",
|
|
8858
|
+
userConfirmed: false
|
|
8839
8859
|
};
|
|
8840
8860
|
} else {
|
|
8841
|
-
patterns.workflows[workflowName]
|
|
8842
|
-
|
|
8861
|
+
const workflow2 = patterns.workflows[workflowName];
|
|
8862
|
+
workflow2.count++;
|
|
8863
|
+
workflow2.lastSeen = now;
|
|
8864
|
+
workflow2.confidence = calculateConfidence(workflow2.count, workflow2.userConfirmed);
|
|
8843
8865
|
}
|
|
8844
8866
|
await this.save(projectId);
|
|
8845
8867
|
}
|
|
8868
|
+
async confirmWorkflow(projectId, workflowName) {
|
|
8869
|
+
const patterns = await this.load(projectId);
|
|
8870
|
+
const workflow2 = patterns.workflows[workflowName];
|
|
8871
|
+
if (!workflow2) return false;
|
|
8872
|
+
workflow2.userConfirmed = true;
|
|
8873
|
+
workflow2.confidence = "high";
|
|
8874
|
+
workflow2.lastSeen = getTimestamp();
|
|
8875
|
+
await this.save(projectId);
|
|
8876
|
+
return true;
|
|
8877
|
+
}
|
|
8846
8878
|
async getWorkflow(projectId, workflowName) {
|
|
8847
8879
|
const patterns = await this.load(projectId);
|
|
8848
8880
|
const workflow2 = patterns.workflows[workflowName];
|
|
8849
8881
|
if (!workflow2 || workflow2.count < 3) return null;
|
|
8850
8882
|
return workflow2;
|
|
8851
8883
|
}
|
|
8852
|
-
async setPreference(projectId, key, value) {
|
|
8884
|
+
async setPreference(projectId, key, value, options = {}) {
|
|
8853
8885
|
const patterns = await this.load(projectId);
|
|
8854
|
-
patterns.preferences[key]
|
|
8886
|
+
const existing = patterns.preferences[key];
|
|
8887
|
+
const observationCount = existing ? existing.observationCount + 1 : 1;
|
|
8888
|
+
const userConfirmed = options.userConfirmed || existing?.userConfirmed || false;
|
|
8889
|
+
patterns.preferences[key] = {
|
|
8890
|
+
value,
|
|
8891
|
+
updatedAt: getTimestamp(),
|
|
8892
|
+
confidence: calculateConfidence(observationCount, userConfirmed),
|
|
8893
|
+
observationCount,
|
|
8894
|
+
userConfirmed
|
|
8895
|
+
};
|
|
8855
8896
|
await this.save(projectId);
|
|
8856
8897
|
}
|
|
8898
|
+
async confirmPreference(projectId, key) {
|
|
8899
|
+
const patterns = await this.load(projectId);
|
|
8900
|
+
const pref = patterns.preferences[key];
|
|
8901
|
+
if (!pref) return false;
|
|
8902
|
+
pref.userConfirmed = true;
|
|
8903
|
+
pref.confidence = "high";
|
|
8904
|
+
pref.updatedAt = getTimestamp();
|
|
8905
|
+
await this.save(projectId);
|
|
8906
|
+
return true;
|
|
8907
|
+
}
|
|
8857
8908
|
async getPreference(projectId, key, defaultValue = null) {
|
|
8858
8909
|
const patterns = await this.load(projectId);
|
|
8859
8910
|
return patterns.preferences[key]?.value ?? defaultValue;
|
|
@@ -9169,12 +9220,21 @@ Context: ${context2}` : ""}`,
|
|
|
9169
9220
|
getWorkflow(projectId, workflowName) {
|
|
9170
9221
|
return this._patternStore.getWorkflow(projectId, workflowName);
|
|
9171
9222
|
}
|
|
9172
|
-
setPreference(projectId, key, value) {
|
|
9173
|
-
return this._patternStore.setPreference(projectId, key, value);
|
|
9223
|
+
setPreference(projectId, key, value, options) {
|
|
9224
|
+
return this._patternStore.setPreference(projectId, key, value, options);
|
|
9174
9225
|
}
|
|
9175
9226
|
getPreference(projectId, key, defaultValue) {
|
|
9176
9227
|
return this._patternStore.getPreference(projectId, key, defaultValue);
|
|
9177
9228
|
}
|
|
9229
|
+
confirmPreference(projectId, key) {
|
|
9230
|
+
return this._patternStore.confirmPreference(projectId, key);
|
|
9231
|
+
}
|
|
9232
|
+
confirmDecision(projectId, key) {
|
|
9233
|
+
return this._patternStore.confirmDecision(projectId, key);
|
|
9234
|
+
}
|
|
9235
|
+
confirmWorkflow(projectId, workflowName) {
|
|
9236
|
+
return this._patternStore.confirmWorkflow(projectId, workflowName);
|
|
9237
|
+
}
|
|
9178
9238
|
getPatternsSummary(projectId) {
|
|
9179
9239
|
return this._patternStore.getPatternsSummary(projectId);
|
|
9180
9240
|
}
|
|
@@ -11448,7 +11508,7 @@ var init_constants = __esm({
|
|
|
11448
11508
|
|
|
11449
11509
|
// core/agentic/plan-mode.ts
|
|
11450
11510
|
function generateApprovalPrompt(commandName, context2) {
|
|
11451
|
-
const
|
|
11511
|
+
const prompts3 = {
|
|
11452
11512
|
ship: {
|
|
11453
11513
|
title: "Ship Confirmation",
|
|
11454
11514
|
message: "Ready to commit and push changes?",
|
|
@@ -11486,7 +11546,7 @@ function generateApprovalPrompt(commandName, context2) {
|
|
|
11486
11546
|
]
|
|
11487
11547
|
}
|
|
11488
11548
|
};
|
|
11489
|
-
return
|
|
11549
|
+
return prompts3[commandName] || {
|
|
11490
11550
|
title: "Confirmation Required",
|
|
11491
11551
|
message: `Execute ${commandName}?`,
|
|
11492
11552
|
options: [
|
|
@@ -15541,16 +15601,16 @@ var init_onboarding = __esm({
|
|
|
15541
15601
|
* Detect project type from file system
|
|
15542
15602
|
*/
|
|
15543
15603
|
async detectProjectType() {
|
|
15544
|
-
const
|
|
15604
|
+
const fs47 = await import("node:fs/promises");
|
|
15545
15605
|
const path56 = await import("node:path");
|
|
15546
15606
|
try {
|
|
15547
|
-
const files = await
|
|
15607
|
+
const files = await fs47.readdir(this.projectPath);
|
|
15548
15608
|
if (files.includes("turbo.json") || files.includes("lerna.json") || files.includes("nx.json")) {
|
|
15549
15609
|
return "monorepo";
|
|
15550
15610
|
}
|
|
15551
15611
|
if (files.includes("package.json")) {
|
|
15552
15612
|
const pkgPath = path56.join(this.projectPath, "package.json");
|
|
15553
|
-
const pkgContent = await
|
|
15613
|
+
const pkgContent = await fs47.readFile(pkgPath, "utf-8");
|
|
15554
15614
|
const pkg = JSON.parse(pkgContent);
|
|
15555
15615
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
15556
15616
|
if (pkg.bin) return "cli-tool";
|
|
@@ -15586,32 +15646,32 @@ var init_onboarding = __esm({
|
|
|
15586
15646
|
* Detect installed AI agents from config files
|
|
15587
15647
|
*/
|
|
15588
15648
|
async detectInstalledAgents() {
|
|
15589
|
-
const
|
|
15649
|
+
const fs47 = await import("node:fs/promises");
|
|
15590
15650
|
const path56 = await import("node:path");
|
|
15591
15651
|
const os17 = await import("node:os");
|
|
15592
15652
|
const agents = [];
|
|
15593
15653
|
try {
|
|
15594
|
-
await
|
|
15654
|
+
await fs47.access(path56.join(os17.homedir(), ".claude"));
|
|
15595
15655
|
agents.push("claude");
|
|
15596
15656
|
} catch {
|
|
15597
15657
|
}
|
|
15598
15658
|
try {
|
|
15599
|
-
await
|
|
15659
|
+
await fs47.access(path56.join(this.projectPath, ".cursorrules"));
|
|
15600
15660
|
agents.push("cursor");
|
|
15601
15661
|
} catch {
|
|
15602
15662
|
}
|
|
15603
15663
|
try {
|
|
15604
|
-
await
|
|
15664
|
+
await fs47.access(path56.join(this.projectPath, ".windsurfrules"));
|
|
15605
15665
|
agents.push("windsurf");
|
|
15606
15666
|
} catch {
|
|
15607
15667
|
}
|
|
15608
15668
|
try {
|
|
15609
|
-
await
|
|
15669
|
+
await fs47.access(path56.join(this.projectPath, ".github", "copilot-instructions.md"));
|
|
15610
15670
|
agents.push("copilot");
|
|
15611
15671
|
} catch {
|
|
15612
15672
|
}
|
|
15613
15673
|
try {
|
|
15614
|
-
await
|
|
15674
|
+
await fs47.access(path56.join(os17.homedir(), ".gemini"));
|
|
15615
15675
|
agents.push("gemini");
|
|
15616
15676
|
} catch {
|
|
15617
15677
|
}
|
|
@@ -15621,17 +15681,17 @@ var init_onboarding = __esm({
|
|
|
15621
15681
|
* Detect tech stack from project files
|
|
15622
15682
|
*/
|
|
15623
15683
|
async detectStack() {
|
|
15624
|
-
const
|
|
15684
|
+
const fs47 = await import("node:fs/promises");
|
|
15625
15685
|
const path56 = await import("node:path");
|
|
15626
15686
|
const stack = {
|
|
15627
15687
|
language: "Unknown",
|
|
15628
15688
|
technologies: []
|
|
15629
15689
|
};
|
|
15630
15690
|
try {
|
|
15631
|
-
const files = await
|
|
15691
|
+
const files = await fs47.readdir(this.projectPath);
|
|
15632
15692
|
if (files.includes("package.json")) {
|
|
15633
15693
|
const pkgPath = path56.join(this.projectPath, "package.json");
|
|
15634
|
-
const pkgContent = await
|
|
15694
|
+
const pkgContent = await fs47.readFile(pkgPath, "utf-8");
|
|
15635
15695
|
const pkg = JSON.parse(pkgContent);
|
|
15636
15696
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
15637
15697
|
stack.language = deps.typescript ? "TypeScript" : "JavaScript";
|
|
@@ -16296,12 +16356,229 @@ var init_analyzer2 = __esm({
|
|
|
16296
16356
|
}
|
|
16297
16357
|
});
|
|
16298
16358
|
|
|
16359
|
+
// core/services/diff-generator.ts
|
|
16360
|
+
import chalk8 from "chalk";
|
|
16361
|
+
function estimateTokens(content) {
|
|
16362
|
+
return Math.ceil(content.length / CHARS_PER_TOKEN2);
|
|
16363
|
+
}
|
|
16364
|
+
function parseMarkdownSections(content) {
|
|
16365
|
+
const lines = content.split("\n");
|
|
16366
|
+
const sections = [];
|
|
16367
|
+
let currentSection = null;
|
|
16368
|
+
for (let i = 0; i < lines.length; i++) {
|
|
16369
|
+
const line = lines[i];
|
|
16370
|
+
const headerMatch = line.match(/^(#{1,3})\s+(.+)$/);
|
|
16371
|
+
if (headerMatch) {
|
|
16372
|
+
if (currentSection) {
|
|
16373
|
+
currentSection.endLine = i - 1;
|
|
16374
|
+
sections.push(currentSection);
|
|
16375
|
+
}
|
|
16376
|
+
currentSection = {
|
|
16377
|
+
name: headerMatch[2].trim(),
|
|
16378
|
+
content: line,
|
|
16379
|
+
startLine: i,
|
|
16380
|
+
endLine: i
|
|
16381
|
+
};
|
|
16382
|
+
} else if (currentSection) {
|
|
16383
|
+
currentSection.content += `
|
|
16384
|
+
${line}`;
|
|
16385
|
+
}
|
|
16386
|
+
}
|
|
16387
|
+
if (currentSection) {
|
|
16388
|
+
currentSection.endLine = lines.length - 1;
|
|
16389
|
+
sections.push(currentSection);
|
|
16390
|
+
}
|
|
16391
|
+
return sections;
|
|
16392
|
+
}
|
|
16393
|
+
function isPreservedSection(content) {
|
|
16394
|
+
return content.includes("<!-- prjct:preserve");
|
|
16395
|
+
}
|
|
16396
|
+
function generateSyncDiff(oldContent, newContent) {
|
|
16397
|
+
const oldSections = parseMarkdownSections(oldContent);
|
|
16398
|
+
const newSections = parseMarkdownSections(newContent);
|
|
16399
|
+
const diff = {
|
|
16400
|
+
hasChanges: false,
|
|
16401
|
+
added: [],
|
|
16402
|
+
modified: [],
|
|
16403
|
+
removed: [],
|
|
16404
|
+
preserved: [],
|
|
16405
|
+
tokensBefore: estimateTokens(oldContent),
|
|
16406
|
+
tokensAfter: estimateTokens(newContent),
|
|
16407
|
+
tokenDelta: 0
|
|
16408
|
+
};
|
|
16409
|
+
diff.tokenDelta = diff.tokensAfter - diff.tokensBefore;
|
|
16410
|
+
const oldMap = new Map(oldSections.map((s) => [s.name.toLowerCase(), s]));
|
|
16411
|
+
const newMap = new Map(newSections.map((s) => [s.name.toLowerCase(), s]));
|
|
16412
|
+
for (const section of oldSections) {
|
|
16413
|
+
if (isPreservedSection(section.content)) {
|
|
16414
|
+
diff.preserved.push({
|
|
16415
|
+
name: section.name,
|
|
16416
|
+
lineCount: section.content.split("\n").length
|
|
16417
|
+
});
|
|
16418
|
+
}
|
|
16419
|
+
}
|
|
16420
|
+
for (const newSection of newSections) {
|
|
16421
|
+
const key = newSection.name.toLowerCase();
|
|
16422
|
+
const oldSection = oldMap.get(key);
|
|
16423
|
+
if (!oldSection) {
|
|
16424
|
+
diff.added.push({
|
|
16425
|
+
name: newSection.name,
|
|
16426
|
+
type: "added",
|
|
16427
|
+
after: newSection.content,
|
|
16428
|
+
lineCount: newSection.content.split("\n").length
|
|
16429
|
+
});
|
|
16430
|
+
diff.hasChanges = true;
|
|
16431
|
+
} else if (oldSection.content.trim() !== newSection.content.trim()) {
|
|
16432
|
+
if (!isPreservedSection(oldSection.content)) {
|
|
16433
|
+
diff.modified.push({
|
|
16434
|
+
name: newSection.name,
|
|
16435
|
+
type: "modified",
|
|
16436
|
+
before: oldSection.content,
|
|
16437
|
+
after: newSection.content,
|
|
16438
|
+
lineCount: newSection.content.split("\n").length
|
|
16439
|
+
});
|
|
16440
|
+
diff.hasChanges = true;
|
|
16441
|
+
}
|
|
16442
|
+
}
|
|
16443
|
+
}
|
|
16444
|
+
for (const oldSection of oldSections) {
|
|
16445
|
+
const key = oldSection.name.toLowerCase();
|
|
16446
|
+
if (!newMap.has(key) && !isPreservedSection(oldSection.content)) {
|
|
16447
|
+
diff.removed.push({
|
|
16448
|
+
name: oldSection.name,
|
|
16449
|
+
type: "removed",
|
|
16450
|
+
before: oldSection.content,
|
|
16451
|
+
lineCount: oldSection.content.split("\n").length
|
|
16452
|
+
});
|
|
16453
|
+
diff.hasChanges = true;
|
|
16454
|
+
}
|
|
16455
|
+
}
|
|
16456
|
+
return diff;
|
|
16457
|
+
}
|
|
16458
|
+
function formatDiffPreview(diff, options = {}) {
|
|
16459
|
+
const { colorize = true } = options;
|
|
16460
|
+
const lines = [];
|
|
16461
|
+
const green = colorize ? chalk8.green : (s) => s;
|
|
16462
|
+
const red = colorize ? chalk8.red : (s) => s;
|
|
16463
|
+
const yellow = colorize ? chalk8.yellow : (s) => s;
|
|
16464
|
+
const dim = colorize ? chalk8.dim : (s) => s;
|
|
16465
|
+
const bold = colorize ? chalk8.bold : (s) => s;
|
|
16466
|
+
if (!diff.hasChanges) {
|
|
16467
|
+
lines.push(dim("No changes detected (context is up to date)"));
|
|
16468
|
+
return lines.join("\n");
|
|
16469
|
+
}
|
|
16470
|
+
lines.push("");
|
|
16471
|
+
lines.push(bold("\u{1F4CB} Changes to context files:"));
|
|
16472
|
+
lines.push("");
|
|
16473
|
+
if (diff.added.length > 0) {
|
|
16474
|
+
for (const section of diff.added) {
|
|
16475
|
+
lines.push(green(`+ \u2502 + ${section.name} (new)`));
|
|
16476
|
+
}
|
|
16477
|
+
}
|
|
16478
|
+
if (diff.modified.length > 0) {
|
|
16479
|
+
for (const section of diff.modified) {
|
|
16480
|
+
lines.push(yellow(`~ \u2502 ${section.name} (modified)`));
|
|
16481
|
+
}
|
|
16482
|
+
}
|
|
16483
|
+
if (diff.removed.length > 0) {
|
|
16484
|
+
for (const section of diff.removed) {
|
|
16485
|
+
lines.push(red(`- \u2502 - ${section.name} (removed)`));
|
|
16486
|
+
}
|
|
16487
|
+
}
|
|
16488
|
+
if (diff.preserved.length > 0) {
|
|
16489
|
+
lines.push("");
|
|
16490
|
+
lines.push(dim(" ## Your Customizations"));
|
|
16491
|
+
for (const section of diff.preserved) {
|
|
16492
|
+
lines.push(dim(` \u2502 \u2713 ${section.name} (${section.lineCount} lines preserved)`));
|
|
16493
|
+
}
|
|
16494
|
+
}
|
|
16495
|
+
lines.push("");
|
|
16496
|
+
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"));
|
|
16497
|
+
const summaryParts = [];
|
|
16498
|
+
if (diff.added.length > 0) summaryParts.push(green(`+${diff.added.length} added`));
|
|
16499
|
+
if (diff.modified.length > 0) summaryParts.push(yellow(`~${diff.modified.length} modified`));
|
|
16500
|
+
if (diff.removed.length > 0) summaryParts.push(red(`-${diff.removed.length} removed`));
|
|
16501
|
+
lines.push(`Summary: ${summaryParts.join(", ") || "no changes"}`);
|
|
16502
|
+
const tokenSign = diff.tokenDelta >= 0 ? "+" : "";
|
|
16503
|
+
const tokenColor = diff.tokenDelta >= 0 ? green : red;
|
|
16504
|
+
lines.push(
|
|
16505
|
+
`Tokens: ${diff.tokensBefore.toLocaleString()} \u2192 ${diff.tokensAfter.toLocaleString()} (${tokenColor(tokenSign + diff.tokenDelta.toLocaleString())})`
|
|
16506
|
+
);
|
|
16507
|
+
lines.push("");
|
|
16508
|
+
return lines.join("\n");
|
|
16509
|
+
}
|
|
16510
|
+
function formatFullDiff(diff, options = {}) {
|
|
16511
|
+
const { colorize = true } = options;
|
|
16512
|
+
const lines = [];
|
|
16513
|
+
const green = colorize ? chalk8.green : (s) => s;
|
|
16514
|
+
const red = colorize ? chalk8.red : (s) => s;
|
|
16515
|
+
const cyan = colorize ? chalk8.cyan : (s) => s;
|
|
16516
|
+
const dim = colorize ? chalk8.dim : (s) => s;
|
|
16517
|
+
for (const section of diff.added) {
|
|
16518
|
+
lines.push(cyan(`@@ +${section.name} @@`));
|
|
16519
|
+
if (section.after) {
|
|
16520
|
+
for (const line of section.after.split("\n")) {
|
|
16521
|
+
lines.push(green(`+ ${line}`));
|
|
16522
|
+
}
|
|
16523
|
+
}
|
|
16524
|
+
lines.push("");
|
|
16525
|
+
}
|
|
16526
|
+
for (const section of diff.modified) {
|
|
16527
|
+
lines.push(cyan(`@@ ${section.name} @@`));
|
|
16528
|
+
if (section.before) {
|
|
16529
|
+
for (const line of section.before.split("\n").slice(0, 5)) {
|
|
16530
|
+
lines.push(red(`- ${line}`));
|
|
16531
|
+
}
|
|
16532
|
+
if (section.before.split("\n").length > 5) {
|
|
16533
|
+
lines.push(dim(` ... ${section.before.split("\n").length - 5} more lines`));
|
|
16534
|
+
}
|
|
16535
|
+
}
|
|
16536
|
+
if (section.after) {
|
|
16537
|
+
for (const line of section.after.split("\n").slice(0, 5)) {
|
|
16538
|
+
lines.push(green(`+ ${line}`));
|
|
16539
|
+
}
|
|
16540
|
+
if (section.after.split("\n").length > 5) {
|
|
16541
|
+
lines.push(dim(` ... ${section.after.split("\n").length - 5} more lines`));
|
|
16542
|
+
}
|
|
16543
|
+
}
|
|
16544
|
+
lines.push("");
|
|
16545
|
+
}
|
|
16546
|
+
for (const section of diff.removed) {
|
|
16547
|
+
lines.push(cyan(`@@ -${section.name} @@`));
|
|
16548
|
+
if (section.before) {
|
|
16549
|
+
for (const line of section.before.split("\n").slice(0, 5)) {
|
|
16550
|
+
lines.push(red(`- ${line}`));
|
|
16551
|
+
}
|
|
16552
|
+
if (section.before.split("\n").length > 5) {
|
|
16553
|
+
lines.push(dim(` ... ${section.before.split("\n").length - 5} more lines`));
|
|
16554
|
+
}
|
|
16555
|
+
}
|
|
16556
|
+
lines.push("");
|
|
16557
|
+
}
|
|
16558
|
+
return lines.join("\n");
|
|
16559
|
+
}
|
|
16560
|
+
var CHARS_PER_TOKEN2;
|
|
16561
|
+
var init_diff_generator = __esm({
|
|
16562
|
+
"core/services/diff-generator.ts"() {
|
|
16563
|
+
"use strict";
|
|
16564
|
+
CHARS_PER_TOKEN2 = 4;
|
|
16565
|
+
__name(estimateTokens, "estimateTokens");
|
|
16566
|
+
__name(parseMarkdownSections, "parseMarkdownSections");
|
|
16567
|
+
__name(isPreservedSection, "isPreservedSection");
|
|
16568
|
+
__name(generateSyncDiff, "generateSyncDiff");
|
|
16569
|
+
__name(formatDiffPreview, "formatDiffPreview");
|
|
16570
|
+
__name(formatFullDiff, "formatFullDiff");
|
|
16571
|
+
}
|
|
16572
|
+
});
|
|
16573
|
+
|
|
16299
16574
|
// core/commands/analysis.ts
|
|
16300
16575
|
var analysis_exports = {};
|
|
16301
16576
|
__export(analysis_exports, {
|
|
16302
16577
|
AnalysisCommands: () => AnalysisCommands
|
|
16303
16578
|
});
|
|
16579
|
+
import fs34 from "node:fs/promises";
|
|
16304
16580
|
import path35 from "node:path";
|
|
16581
|
+
import prompts2 from "prompts";
|
|
16305
16582
|
var AnalysisCommands;
|
|
16306
16583
|
var init_analysis2 = __esm({
|
|
16307
16584
|
"core/commands/analysis.ts"() {
|
|
@@ -16311,8 +16588,10 @@ var init_analysis2 = __esm({
|
|
|
16311
16588
|
init_command_installer();
|
|
16312
16589
|
init_metrics();
|
|
16313
16590
|
init_services();
|
|
16591
|
+
init_diff_generator();
|
|
16314
16592
|
init_metrics_storage();
|
|
16315
16593
|
init_next_steps();
|
|
16594
|
+
init_output();
|
|
16316
16595
|
init_base();
|
|
16317
16596
|
AnalysisCommands = class extends PrjctCommandsBase {
|
|
16318
16597
|
static {
|
|
@@ -16456,7 +16735,7 @@ var init_analysis2 = __esm({
|
|
|
16456
16735
|
return lines.join("\n");
|
|
16457
16736
|
}
|
|
16458
16737
|
/**
|
|
16459
|
-
* /p:sync - Comprehensive project sync
|
|
16738
|
+
* /p:sync - Comprehensive project sync with diff preview
|
|
16460
16739
|
*
|
|
16461
16740
|
* Uses syncService to do ALL operations in one TypeScript execution:
|
|
16462
16741
|
* - Git analysis
|
|
@@ -16466,99 +16745,181 @@ var init_analysis2 = __esm({
|
|
|
16466
16745
|
* - Skill configuration
|
|
16467
16746
|
* - State updates
|
|
16468
16747
|
*
|
|
16748
|
+
* Options:
|
|
16749
|
+
* - --preview: Show what would change without applying
|
|
16750
|
+
* - --yes: Skip confirmation prompt
|
|
16751
|
+
*
|
|
16469
16752
|
* This eliminates the need for Claude to make 50+ individual tool calls.
|
|
16753
|
+
*
|
|
16754
|
+
* @see PRJ-125
|
|
16470
16755
|
*/
|
|
16471
16756
|
async sync(projectPath = process.cwd(), options = {}) {
|
|
16472
16757
|
try {
|
|
16473
16758
|
const initResult = await this.ensureProjectInit(projectPath);
|
|
16474
16759
|
if (!initResult.success) return initResult;
|
|
16760
|
+
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16761
|
+
if (!projectId) {
|
|
16762
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16763
|
+
return { success: false, error: "No project ID found" };
|
|
16764
|
+
}
|
|
16765
|
+
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
16475
16766
|
const startTime = Date.now();
|
|
16476
|
-
|
|
16767
|
+
const claudeMdPath = path35.join(globalPath, "context", "CLAUDE.md");
|
|
16768
|
+
let existingContent = null;
|
|
16769
|
+
try {
|
|
16770
|
+
existingContent = await fs34.readFile(claudeMdPath, "utf-8");
|
|
16771
|
+
} catch {
|
|
16772
|
+
}
|
|
16773
|
+
if (existingContent && !options.yes) {
|
|
16774
|
+
output_default.spin("Analyzing changes...");
|
|
16775
|
+
const result2 = await syncService.sync(projectPath, { aiTools: options.aiTools });
|
|
16776
|
+
if (!result2.success) {
|
|
16777
|
+
output_default.fail(result2.error || "Sync failed");
|
|
16778
|
+
return { success: false, error: result2.error };
|
|
16779
|
+
}
|
|
16780
|
+
let newContent;
|
|
16781
|
+
try {
|
|
16782
|
+
newContent = await fs34.readFile(claudeMdPath, "utf-8");
|
|
16783
|
+
} catch {
|
|
16784
|
+
newContent = "";
|
|
16785
|
+
}
|
|
16786
|
+
const diff = generateSyncDiff(existingContent, newContent);
|
|
16787
|
+
output_default.stop();
|
|
16788
|
+
if (!diff.hasChanges) {
|
|
16789
|
+
output_default.done("No changes detected (context is up to date)");
|
|
16790
|
+
return { success: true, message: "No changes" };
|
|
16791
|
+
}
|
|
16792
|
+
console.log(formatDiffPreview(diff));
|
|
16793
|
+
if (options.preview) {
|
|
16794
|
+
return {
|
|
16795
|
+
success: true,
|
|
16796
|
+
isPreview: true,
|
|
16797
|
+
diff,
|
|
16798
|
+
message: "Preview complete (no changes applied)"
|
|
16799
|
+
};
|
|
16800
|
+
}
|
|
16801
|
+
const response = await prompts2({
|
|
16802
|
+
type: "select",
|
|
16803
|
+
name: "action",
|
|
16804
|
+
message: "Apply these changes?",
|
|
16805
|
+
choices: [
|
|
16806
|
+
{ title: "Yes, apply changes", value: "apply" },
|
|
16807
|
+
{ title: "No, cancel", value: "cancel" },
|
|
16808
|
+
{ title: "Show full diff", value: "diff" }
|
|
16809
|
+
]
|
|
16810
|
+
});
|
|
16811
|
+
if (response.action === "cancel" || !response.action) {
|
|
16812
|
+
output_default.warn("Sync cancelled");
|
|
16813
|
+
return { success: false, message: "Cancelled by user" };
|
|
16814
|
+
}
|
|
16815
|
+
if (response.action === "diff") {
|
|
16816
|
+
console.log(`
|
|
16817
|
+
${formatFullDiff(diff)}`);
|
|
16818
|
+
const confirm = await prompts2({
|
|
16819
|
+
type: "confirm",
|
|
16820
|
+
name: "apply",
|
|
16821
|
+
message: "Apply these changes?",
|
|
16822
|
+
initial: true
|
|
16823
|
+
});
|
|
16824
|
+
if (!confirm.apply) {
|
|
16825
|
+
output_default.warn("Sync cancelled");
|
|
16826
|
+
return { success: false, message: "Cancelled by user" };
|
|
16827
|
+
}
|
|
16828
|
+
}
|
|
16829
|
+
output_default.done("Changes applied");
|
|
16830
|
+
return this.showSyncResult(result2, startTime);
|
|
16831
|
+
}
|
|
16832
|
+
output_default.spin("Syncing project...");
|
|
16477
16833
|
const result = await syncService.sync(projectPath, { aiTools: options.aiTools });
|
|
16478
16834
|
if (!result.success) {
|
|
16479
|
-
|
|
16835
|
+
output_default.fail(result.error || "Sync failed");
|
|
16480
16836
|
return { success: false, error: result.error };
|
|
16481
16837
|
}
|
|
16482
|
-
|
|
16483
|
-
|
|
16484
|
-
|
|
16485
|
-
|
|
16486
|
-
|
|
16838
|
+
output_default.stop();
|
|
16839
|
+
return this.showSyncResult(result, startTime);
|
|
16840
|
+
} catch (error) {
|
|
16841
|
+
output_default.fail(error.message);
|
|
16842
|
+
return { success: false, error: error.message };
|
|
16843
|
+
}
|
|
16844
|
+
}
|
|
16845
|
+
/**
|
|
16846
|
+
* Display sync results (extracted to avoid duplication)
|
|
16847
|
+
*/
|
|
16848
|
+
async showSyncResult(result, startTime) {
|
|
16849
|
+
const globalConfigResult = await command_installer_default.installGlobalConfig();
|
|
16850
|
+
if (globalConfigResult.success) {
|
|
16851
|
+
console.log(`\u{1F4DD} Updated ${path_manager_default.getDisplayPath(globalConfigResult.path)}`);
|
|
16852
|
+
}
|
|
16853
|
+
console.log(`\u{1F504} Project synced to prjct v${result.cliVersion}
|
|
16487
16854
|
`);
|
|
16488
|
-
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
|
|
16492
|
-
|
|
16855
|
+
console.log("\u{1F4CA} Project Stats");
|
|
16856
|
+
console.log(`\u251C\u2500\u2500 Files: ~${result.stats.fileCount}`);
|
|
16857
|
+
console.log(`\u251C\u2500\u2500 Commits: ${result.git.commits}`);
|
|
16858
|
+
console.log(`\u251C\u2500\u2500 Version: ${result.stats.version}`);
|
|
16859
|
+
console.log(`\u2514\u2500\u2500 Stack: ${result.stats.ecosystem}
|
|
16493
16860
|
`);
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16861
|
+
console.log("\u{1F33F} Git Status");
|
|
16862
|
+
console.log(`\u251C\u2500\u2500 Branch: ${result.git.branch}`);
|
|
16863
|
+
console.log(`\u251C\u2500\u2500 Uncommitted: ${result.git.hasChanges ? "Yes" : "Clean"}`);
|
|
16864
|
+
console.log(`\u2514\u2500\u2500 Recent: ${result.git.weeklyCommits} commits this week
|
|
16498
16865
|
`);
|
|
16499
|
-
|
|
16500
|
-
|
|
16501
|
-
|
|
16866
|
+
console.log("\u{1F4C1} Context Updated");
|
|
16867
|
+
for (const file of result.contextFiles) {
|
|
16868
|
+
console.log(`\u251C\u2500\u2500 ${file}`);
|
|
16869
|
+
}
|
|
16870
|
+
console.log("");
|
|
16871
|
+
if (result.aiTools && result.aiTools.length > 0) {
|
|
16872
|
+
const successTools = result.aiTools.filter((t) => t.success);
|
|
16873
|
+
console.log(`\u{1F916} AI Tools Context (${successTools.length})`);
|
|
16874
|
+
for (const tool of result.aiTools) {
|
|
16875
|
+
const status = tool.success ? "\u2713" : "\u2717";
|
|
16876
|
+
console.log(`\u251C\u2500\u2500 ${status} ${tool.outputFile} (${tool.toolId})`);
|
|
16502
16877
|
}
|
|
16503
16878
|
console.log("");
|
|
16504
|
-
|
|
16505
|
-
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
}
|
|
16511
|
-
console.log("");
|
|
16512
|
-
}
|
|
16513
|
-
const workflowAgents = result.agents.filter((a) => a.type === "workflow").map((a) => a.name);
|
|
16514
|
-
const domainAgents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
|
|
16515
|
-
console.log(`\u{1F916} Agents Regenerated (${result.agents.length})`);
|
|
16516
|
-
console.log(`\u251C\u2500\u2500 Workflow: ${workflowAgents.join(", ")}`);
|
|
16517
|
-
console.log(`\u2514\u2500\u2500 Domain: ${domainAgents.join(", ") || "none"}
|
|
16879
|
+
}
|
|
16880
|
+
const workflowAgents = result.agents.filter((a) => a.type === "workflow").map((a) => a.name);
|
|
16881
|
+
const domainAgents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
|
|
16882
|
+
console.log(`\u{1F916} Agents Regenerated (${result.agents.length})`);
|
|
16883
|
+
console.log(`\u251C\u2500\u2500 Workflow: ${workflowAgents.join(", ")}`);
|
|
16884
|
+
console.log(`\u2514\u2500\u2500 Domain: ${domainAgents.join(", ") || "none"}
|
|
16518
16885
|
`);
|
|
16519
|
-
|
|
16520
|
-
|
|
16521
|
-
|
|
16522
|
-
|
|
16523
|
-
}
|
|
16524
|
-
console.log("");
|
|
16886
|
+
if (result.skills.length > 0) {
|
|
16887
|
+
console.log("\u{1F4E6} Skills Configured");
|
|
16888
|
+
for (const skill of result.skills) {
|
|
16889
|
+
console.log(`\u251C\u2500\u2500 ${skill.agent}.md \u2192 ${skill.skill}`);
|
|
16525
16890
|
}
|
|
16526
|
-
if (result.git.hasChanges) {
|
|
16527
|
-
console.log("\u26A0\uFE0F You have uncommitted changes\n");
|
|
16528
|
-
} else {
|
|
16529
|
-
console.log("\u2728 Repository is clean!\n");
|
|
16530
|
-
}
|
|
16531
|
-
showNextSteps("sync");
|
|
16532
|
-
const elapsed = Date.now() - startTime;
|
|
16533
|
-
const contextFilesCount = result.contextFiles.length + (result.aiTools?.filter((t) => t.success).length || 0);
|
|
16534
|
-
const agentCount = result.agents.length;
|
|
16535
|
-
console.log("\u2500".repeat(45));
|
|
16536
|
-
console.log(`\u{1F4CA} Sync Summary`);
|
|
16537
|
-
console.log(
|
|
16538
|
-
` Stack: ${result.stats.ecosystem} (${result.stats.frameworks.join(", ") || "no frameworks"})`
|
|
16539
|
-
);
|
|
16540
|
-
console.log(
|
|
16541
|
-
` Files: ${result.stats.fileCount} analyzed \u2192 ${contextFilesCount} context files`
|
|
16542
|
-
);
|
|
16543
|
-
console.log(
|
|
16544
|
-
` Agents: ${agentCount} (${result.agents.filter((a) => a.type === "domain").length} domain)`
|
|
16545
|
-
);
|
|
16546
|
-
console.log(` Time: ${(elapsed / 1e3).toFixed(1)}s`);
|
|
16547
16891
|
console.log("");
|
|
16548
|
-
return {
|
|
16549
|
-
success: true,
|
|
16550
|
-
data: result,
|
|
16551
|
-
metrics: {
|
|
16552
|
-
elapsed,
|
|
16553
|
-
contextFilesCount,
|
|
16554
|
-
agentCount,
|
|
16555
|
-
fileCount: result.stats.fileCount
|
|
16556
|
-
}
|
|
16557
|
-
};
|
|
16558
|
-
} catch (error) {
|
|
16559
|
-
console.error("\u274C Error:", error.message);
|
|
16560
|
-
return { success: false, error: error.message };
|
|
16561
16892
|
}
|
|
16893
|
+
if (result.git.hasChanges) {
|
|
16894
|
+
console.log("\u26A0\uFE0F You have uncommitted changes\n");
|
|
16895
|
+
} else {
|
|
16896
|
+
console.log("\u2728 Repository is clean!\n");
|
|
16897
|
+
}
|
|
16898
|
+
showNextSteps("sync");
|
|
16899
|
+
const elapsed = Date.now() - startTime;
|
|
16900
|
+
const contextFilesCount = result.contextFiles.length + (result.aiTools?.filter((t) => t.success).length || 0);
|
|
16901
|
+
const agentCount = result.agents.length;
|
|
16902
|
+
console.log("\u2500".repeat(45));
|
|
16903
|
+
console.log("\u{1F4CA} Sync Summary");
|
|
16904
|
+
console.log(
|
|
16905
|
+
` Stack: ${result.stats.ecosystem} (${result.stats.frameworks.join(", ") || "no frameworks"})`
|
|
16906
|
+
);
|
|
16907
|
+
console.log(` Files: ${result.stats.fileCount} analyzed \u2192 ${contextFilesCount} context files`);
|
|
16908
|
+
console.log(
|
|
16909
|
+
` Agents: ${agentCount} (${result.agents.filter((a) => a.type === "domain").length} domain)`
|
|
16910
|
+
);
|
|
16911
|
+
console.log(` Time: ${(elapsed / 1e3).toFixed(1)}s`);
|
|
16912
|
+
console.log("");
|
|
16913
|
+
return {
|
|
16914
|
+
success: true,
|
|
16915
|
+
data: result,
|
|
16916
|
+
metrics: {
|
|
16917
|
+
elapsed,
|
|
16918
|
+
contextFilesCount,
|
|
16919
|
+
agentCount,
|
|
16920
|
+
fileCount: result.stats.fileCount
|
|
16921
|
+
}
|
|
16922
|
+
};
|
|
16562
16923
|
}
|
|
16563
16924
|
/**
|
|
16564
16925
|
* /p:stats - Value dashboard showing accumulated savings and impact
|
|
@@ -16597,10 +16958,10 @@ var init_analysis2 = __esm({
|
|
|
16597
16958
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
16598
16959
|
let projectName = "Unknown";
|
|
16599
16960
|
try {
|
|
16600
|
-
const
|
|
16961
|
+
const fs47 = __require("node:fs/promises");
|
|
16601
16962
|
const path56 = __require("node:path");
|
|
16602
16963
|
const projectJson = JSON.parse(
|
|
16603
|
-
await
|
|
16964
|
+
await fs47.readFile(path56.join(globalPath, "project.json"), "utf-8")
|
|
16604
16965
|
);
|
|
16605
16966
|
projectName = projectJson.name || "Unknown";
|
|
16606
16967
|
} catch {
|
|
@@ -17207,8 +17568,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
17207
17568
|
const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
|
|
17208
17569
|
const specsPath2 = path36.join(globalPath2, "planning", "specs");
|
|
17209
17570
|
try {
|
|
17210
|
-
const
|
|
17211
|
-
const files = await
|
|
17571
|
+
const fs47 = await import("node:fs/promises");
|
|
17572
|
+
const files = await fs47.readdir(specsPath2);
|
|
17212
17573
|
const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
|
|
17213
17574
|
if (specs.length === 0) {
|
|
17214
17575
|
output_default.warn("no specs yet");
|
|
@@ -17639,7 +18000,7 @@ var init_formatters = __esm({
|
|
|
17639
18000
|
|
|
17640
18001
|
// core/ai-tools/registry.ts
|
|
17641
18002
|
import { execSync as execSync4 } from "node:child_process";
|
|
17642
|
-
import
|
|
18003
|
+
import fs35 from "node:fs";
|
|
17643
18004
|
import os11 from "node:os";
|
|
17644
18005
|
import path37 from "node:path";
|
|
17645
18006
|
function getAIToolConfig(id) {
|
|
@@ -17658,16 +18019,16 @@ function detectInstalledTools(repoPath = process.cwd()) {
|
|
|
17658
18019
|
if (commandExists("claude")) {
|
|
17659
18020
|
detected.push("claude");
|
|
17660
18021
|
}
|
|
17661
|
-
if (commandExists("cursor") ||
|
|
18022
|
+
if (commandExists("cursor") || fs35.existsSync(path37.join(repoPath, ".cursor"))) {
|
|
17662
18023
|
detected.push("cursor");
|
|
17663
18024
|
}
|
|
17664
|
-
if (
|
|
18025
|
+
if (fs35.existsSync(path37.join(repoPath, ".github"))) {
|
|
17665
18026
|
detected.push("copilot");
|
|
17666
18027
|
}
|
|
17667
|
-
if (commandExists("windsurf") ||
|
|
18028
|
+
if (commandExists("windsurf") || fs35.existsSync(path37.join(repoPath, ".windsurf"))) {
|
|
17668
18029
|
detected.push("windsurf");
|
|
17669
18030
|
}
|
|
17670
|
-
if (
|
|
18031
|
+
if (fs35.existsSync(path37.join(repoPath, ".continue")) || fs35.existsSync(path37.join(os11.homedir(), ".continue"))) {
|
|
17671
18032
|
detected.push("continue");
|
|
17672
18033
|
}
|
|
17673
18034
|
return detected;
|
|
@@ -17743,7 +18104,7 @@ var init_registry = __esm({
|
|
|
17743
18104
|
});
|
|
17744
18105
|
|
|
17745
18106
|
// core/ai-tools/generator.ts
|
|
17746
|
-
import
|
|
18107
|
+
import fs36 from "node:fs/promises";
|
|
17747
18108
|
import path38 from "node:path";
|
|
17748
18109
|
async function generateAIToolContexts(context2, globalPath, repoPath, toolIds = DEFAULT_AI_TOOLS) {
|
|
17749
18110
|
const results = [];
|
|
@@ -17783,9 +18144,9 @@ async function generateForTool(context2, config, globalPath, repoPath) {
|
|
|
17783
18144
|
} else {
|
|
17784
18145
|
outputPath = path38.join(globalPath, "context", config.outputFile);
|
|
17785
18146
|
}
|
|
17786
|
-
await
|
|
18147
|
+
await fs36.mkdir(path38.dirname(outputPath), { recursive: true });
|
|
17787
18148
|
try {
|
|
17788
|
-
const existingContent = await
|
|
18149
|
+
const existingContent = await fs36.readFile(outputPath, "utf-8");
|
|
17789
18150
|
const validation = validatePreserveBlocks(existingContent);
|
|
17790
18151
|
if (!validation.valid) {
|
|
17791
18152
|
console.warn(`\u26A0\uFE0F ${config.outputFile} has invalid preserve blocks:`);
|
|
@@ -17796,7 +18157,7 @@ async function generateForTool(context2, config, globalPath, repoPath) {
|
|
|
17796
18157
|
content = mergePreservedSections(content, existingContent);
|
|
17797
18158
|
} catch {
|
|
17798
18159
|
}
|
|
17799
|
-
await
|
|
18160
|
+
await fs36.writeFile(outputPath, content, "utf-8");
|
|
17800
18161
|
return {
|
|
17801
18162
|
toolId: config.id,
|
|
17802
18163
|
outputFile: config.outputFile,
|
|
@@ -17835,7 +18196,7 @@ var init_ai_tools = __esm({
|
|
|
17835
18196
|
});
|
|
17836
18197
|
|
|
17837
18198
|
// core/services/context-generator.ts
|
|
17838
|
-
import
|
|
18199
|
+
import fs37 from "node:fs/promises";
|
|
17839
18200
|
import path39 from "node:path";
|
|
17840
18201
|
var ContextFileGenerator;
|
|
17841
18202
|
var init_context_generator = __esm({
|
|
@@ -17858,7 +18219,7 @@ var init_context_generator = __esm({
|
|
|
17858
18219
|
async writeWithPreservation(filePath, content) {
|
|
17859
18220
|
let finalContent = content;
|
|
17860
18221
|
try {
|
|
17861
|
-
const existingContent = await
|
|
18222
|
+
const existingContent = await fs37.readFile(filePath, "utf-8");
|
|
17862
18223
|
const validation = validatePreserveBlocks(existingContent);
|
|
17863
18224
|
if (!validation.valid) {
|
|
17864
18225
|
const filename = path39.basename(filePath);
|
|
@@ -17870,7 +18231,7 @@ var init_context_generator = __esm({
|
|
|
17870
18231
|
finalContent = mergePreservedSections(content, existingContent);
|
|
17871
18232
|
} catch {
|
|
17872
18233
|
}
|
|
17873
|
-
await
|
|
18234
|
+
await fs37.writeFile(filePath, finalContent, "utf-8");
|
|
17874
18235
|
}
|
|
17875
18236
|
/**
|
|
17876
18237
|
* Generate all context files in parallel
|
|
@@ -17980,7 +18341,7 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
|
|
|
17980
18341
|
let currentTask = null;
|
|
17981
18342
|
try {
|
|
17982
18343
|
const statePath = path39.join(this.config.globalPath, "storage", "state.json");
|
|
17983
|
-
const state = JSON.parse(await
|
|
18344
|
+
const state = JSON.parse(await fs37.readFile(statePath, "utf-8"));
|
|
17984
18345
|
currentTask = state.currentTask;
|
|
17985
18346
|
} catch {
|
|
17986
18347
|
}
|
|
@@ -18005,7 +18366,7 @@ Use \`p. task "description"\` to start working.
|
|
|
18005
18366
|
let queue = { tasks: [] };
|
|
18006
18367
|
try {
|
|
18007
18368
|
const queuePath = path39.join(this.config.globalPath, "storage", "queue.json");
|
|
18008
|
-
queue = JSON.parse(await
|
|
18369
|
+
queue = JSON.parse(await fs37.readFile(queuePath, "utf-8"));
|
|
18009
18370
|
} catch {
|
|
18010
18371
|
}
|
|
18011
18372
|
const content = `# NEXT
|
|
@@ -18021,7 +18382,7 @@ ${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}
|
|
|
18021
18382
|
let ideas = { ideas: [] };
|
|
18022
18383
|
try {
|
|
18023
18384
|
const ideasPath = path39.join(this.config.globalPath, "storage", "ideas.json");
|
|
18024
|
-
ideas = JSON.parse(await
|
|
18385
|
+
ideas = JSON.parse(await fs37.readFile(ideasPath, "utf-8"));
|
|
18025
18386
|
} catch {
|
|
18026
18387
|
}
|
|
18027
18388
|
const content = `# IDEAS
|
|
@@ -18039,7 +18400,7 @@ ${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [
|
|
|
18039
18400
|
};
|
|
18040
18401
|
try {
|
|
18041
18402
|
const shippedPath = path39.join(this.config.globalPath, "storage", "shipped.json");
|
|
18042
|
-
shipped = JSON.parse(await
|
|
18403
|
+
shipped = JSON.parse(await fs37.readFile(shippedPath, "utf-8"));
|
|
18043
18404
|
} catch {
|
|
18044
18405
|
}
|
|
18045
18406
|
const content = `# SHIPPED \u{1F680}
|
|
@@ -18055,7 +18416,7 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
|
|
|
18055
18416
|
});
|
|
18056
18417
|
|
|
18057
18418
|
// core/services/stack-detector.ts
|
|
18058
|
-
import
|
|
18419
|
+
import fs38 from "node:fs/promises";
|
|
18059
18420
|
import path40 from "node:path";
|
|
18060
18421
|
var StackDetector;
|
|
18061
18422
|
var init_stack_detector = __esm({
|
|
@@ -18216,7 +18577,7 @@ var init_stack_detector = __esm({
|
|
|
18216
18577
|
async readPackageJson() {
|
|
18217
18578
|
try {
|
|
18218
18579
|
const pkgPath = path40.join(this.projectPath, "package.json");
|
|
18219
|
-
const content = await
|
|
18580
|
+
const content = await fs38.readFile(pkgPath, "utf-8");
|
|
18220
18581
|
return JSON.parse(content);
|
|
18221
18582
|
} catch {
|
|
18222
18583
|
return null;
|
|
@@ -18227,7 +18588,7 @@ var init_stack_detector = __esm({
|
|
|
18227
18588
|
*/
|
|
18228
18589
|
async fileExists(filename) {
|
|
18229
18590
|
try {
|
|
18230
|
-
await
|
|
18591
|
+
await fs38.access(path40.join(this.projectPath, filename));
|
|
18231
18592
|
return true;
|
|
18232
18593
|
} catch {
|
|
18233
18594
|
return false;
|
|
@@ -18239,7 +18600,7 @@ var init_stack_detector = __esm({
|
|
|
18239
18600
|
|
|
18240
18601
|
// core/services/sync-service.ts
|
|
18241
18602
|
import { exec as exec10 } from "node:child_process";
|
|
18242
|
-
import
|
|
18603
|
+
import fs39 from "node:fs/promises";
|
|
18243
18604
|
import path41 from "node:path";
|
|
18244
18605
|
import { promisify as promisify10 } from "node:util";
|
|
18245
18606
|
var execAsync5, SyncService, syncService;
|
|
@@ -18386,7 +18747,7 @@ var init_sync_service = __esm({
|
|
|
18386
18747
|
async ensureDirectories() {
|
|
18387
18748
|
const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
|
|
18388
18749
|
await Promise.all(
|
|
18389
|
-
dirs.map((dir) =>
|
|
18750
|
+
dirs.map((dir) => fs39.mkdir(path41.join(this.globalPath, dir), { recursive: true }))
|
|
18390
18751
|
);
|
|
18391
18752
|
}
|
|
18392
18753
|
// ==========================================================================
|
|
@@ -18473,7 +18834,7 @@ var init_sync_service = __esm({
|
|
|
18473
18834
|
}
|
|
18474
18835
|
try {
|
|
18475
18836
|
const pkgPath = path41.join(this.projectPath, "package.json");
|
|
18476
|
-
const pkg = JSON.parse(await
|
|
18837
|
+
const pkg = JSON.parse(await fs39.readFile(pkgPath, "utf-8"));
|
|
18477
18838
|
stats.version = pkg.version || "0.0.0";
|
|
18478
18839
|
stats.name = pkg.name || stats.name;
|
|
18479
18840
|
stats.ecosystem = "JavaScript";
|
|
@@ -18583,10 +18944,10 @@ var init_sync_service = __esm({
|
|
|
18583
18944
|
const agents = [];
|
|
18584
18945
|
const agentsPath = path41.join(this.globalPath, "agents");
|
|
18585
18946
|
try {
|
|
18586
|
-
const files = await
|
|
18947
|
+
const files = await fs39.readdir(agentsPath);
|
|
18587
18948
|
for (const file of files) {
|
|
18588
18949
|
if (file.endsWith(".md")) {
|
|
18589
|
-
await
|
|
18950
|
+
await fs39.unlink(path41.join(agentsPath, file));
|
|
18590
18951
|
}
|
|
18591
18952
|
}
|
|
18592
18953
|
} catch {
|
|
@@ -18635,11 +18996,11 @@ var init_sync_service = __esm({
|
|
|
18635
18996
|
"workflow",
|
|
18636
18997
|
`${name}.md`
|
|
18637
18998
|
);
|
|
18638
|
-
content = await
|
|
18999
|
+
content = await fs39.readFile(templatePath, "utf-8");
|
|
18639
19000
|
} catch {
|
|
18640
19001
|
content = this.generateMinimalWorkflowAgent(name);
|
|
18641
19002
|
}
|
|
18642
|
-
await
|
|
19003
|
+
await fs39.writeFile(path41.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
18643
19004
|
}
|
|
18644
19005
|
async generateDomainAgent(name, agentsPath, stats, stack) {
|
|
18645
19006
|
let content = "";
|
|
@@ -18653,14 +19014,14 @@ var init_sync_service = __esm({
|
|
|
18653
19014
|
"domain",
|
|
18654
19015
|
`${name}.md`
|
|
18655
19016
|
);
|
|
18656
|
-
content = await
|
|
19017
|
+
content = await fs39.readFile(templatePath, "utf-8");
|
|
18657
19018
|
content = content.replace("{projectName}", stats.name);
|
|
18658
19019
|
content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
|
|
18659
19020
|
content = content.replace("{ecosystem}", stats.ecosystem);
|
|
18660
19021
|
} catch {
|
|
18661
19022
|
content = this.generateMinimalDomainAgent(name, stats, stack);
|
|
18662
19023
|
}
|
|
18663
|
-
await
|
|
19024
|
+
await fs39.writeFile(path41.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
18664
19025
|
}
|
|
18665
19026
|
generateMinimalWorkflowAgent(name) {
|
|
18666
19027
|
const descriptions = {
|
|
@@ -18728,7 +19089,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18728
19089
|
})),
|
|
18729
19090
|
agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
|
|
18730
19091
|
};
|
|
18731
|
-
|
|
19092
|
+
fs39.writeFile(
|
|
18732
19093
|
path41.join(this.globalPath, "config", "skills.json"),
|
|
18733
19094
|
JSON.stringify(skillsConfig, null, 2),
|
|
18734
19095
|
"utf-8"
|
|
@@ -18754,7 +19115,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18754
19115
|
const projectJsonPath = path41.join(this.globalPath, "project.json");
|
|
18755
19116
|
let existing = {};
|
|
18756
19117
|
try {
|
|
18757
|
-
existing = JSON.parse(await
|
|
19118
|
+
existing = JSON.parse(await fs39.readFile(projectJsonPath, "utf-8"));
|
|
18758
19119
|
} catch {
|
|
18759
19120
|
}
|
|
18760
19121
|
const updated = {
|
|
@@ -18773,7 +19134,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18773
19134
|
createdAt: existing.createdAt || date_helper_default.getTimestamp(),
|
|
18774
19135
|
lastSync: date_helper_default.getTimestamp()
|
|
18775
19136
|
};
|
|
18776
|
-
await
|
|
19137
|
+
await fs39.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
|
|
18777
19138
|
}
|
|
18778
19139
|
// ==========================================================================
|
|
18779
19140
|
// STATE.JSON UPDATE
|
|
@@ -18782,7 +19143,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18782
19143
|
const statePath = path41.join(this.globalPath, "storage", "state.json");
|
|
18783
19144
|
let state = {};
|
|
18784
19145
|
try {
|
|
18785
|
-
state = JSON.parse(await
|
|
19146
|
+
state = JSON.parse(await fs39.readFile(statePath, "utf-8"));
|
|
18786
19147
|
} catch {
|
|
18787
19148
|
}
|
|
18788
19149
|
state.projectId = this.projectId;
|
|
@@ -18809,7 +19170,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18809
19170
|
lastAction: "Synced project",
|
|
18810
19171
|
nextAction: 'Run `p. task "description"` to start working'
|
|
18811
19172
|
};
|
|
18812
|
-
await
|
|
19173
|
+
await fs39.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
|
|
18813
19174
|
}
|
|
18814
19175
|
// ==========================================================================
|
|
18815
19176
|
// MEMORY LOGGING
|
|
@@ -18824,7 +19185,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18824
19185
|
fileCount: stats.fileCount,
|
|
18825
19186
|
commitCount: git.commits
|
|
18826
19187
|
};
|
|
18827
|
-
await
|
|
19188
|
+
await fs39.appendFile(memoryPath, `${JSON.stringify(event)}
|
|
18828
19189
|
`, "utf-8");
|
|
18829
19190
|
}
|
|
18830
19191
|
// ==========================================================================
|
|
@@ -18840,12 +19201,12 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18840
19201
|
* Token estimation: ~4 chars per token (industry standard)
|
|
18841
19202
|
*/
|
|
18842
19203
|
async recordSyncMetrics(stats, contextFiles, agents, duration) {
|
|
18843
|
-
const
|
|
19204
|
+
const CHARS_PER_TOKEN3 = 4;
|
|
18844
19205
|
let filteredChars = 0;
|
|
18845
19206
|
for (const file of contextFiles) {
|
|
18846
19207
|
try {
|
|
18847
19208
|
const filePath = path41.join(this.globalPath, file);
|
|
18848
|
-
const content = await
|
|
19209
|
+
const content = await fs39.readFile(filePath, "utf-8");
|
|
18849
19210
|
filteredChars += content.length;
|
|
18850
19211
|
} catch {
|
|
18851
19212
|
}
|
|
@@ -18853,12 +19214,12 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18853
19214
|
for (const agent of agents) {
|
|
18854
19215
|
try {
|
|
18855
19216
|
const agentPath = path41.join(this.globalPath, "agents", `${agent.name}.md`);
|
|
18856
|
-
const content = await
|
|
19217
|
+
const content = await fs39.readFile(agentPath, "utf-8");
|
|
18857
19218
|
filteredChars += content.length;
|
|
18858
19219
|
} catch {
|
|
18859
19220
|
}
|
|
18860
19221
|
}
|
|
18861
|
-
const filteredSize = Math.floor(filteredChars /
|
|
19222
|
+
const filteredSize = Math.floor(filteredChars / CHARS_PER_TOKEN3);
|
|
18862
19223
|
const avgTokensPerFile = 500;
|
|
18863
19224
|
const originalSize = stats.fileCount * avgTokensPerFile;
|
|
18864
19225
|
const compressionRate = originalSize > 0 ? Math.max(0, (originalSize - filteredSize) / originalSize) : 0;
|
|
@@ -18885,7 +19246,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18885
19246
|
// ==========================================================================
|
|
18886
19247
|
async fileExists(filename) {
|
|
18887
19248
|
try {
|
|
18888
|
-
await
|
|
19249
|
+
await fs39.access(path41.join(this.projectPath, filename));
|
|
18889
19250
|
return true;
|
|
18890
19251
|
} catch {
|
|
18891
19252
|
return false;
|
|
@@ -18894,7 +19255,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
18894
19255
|
async getCliVersion() {
|
|
18895
19256
|
try {
|
|
18896
19257
|
const pkgPath = path41.join(__dirname, "..", "..", "package.json");
|
|
18897
|
-
const pkg = JSON.parse(await
|
|
19258
|
+
const pkg = JSON.parse(await fs39.readFile(pkgPath, "utf-8"));
|
|
18898
19259
|
return pkg.version || "0.0.0";
|
|
18899
19260
|
} catch {
|
|
18900
19261
|
return "0.0.0";
|
|
@@ -19053,22 +19414,22 @@ __export(uninstall_exports, {
|
|
|
19053
19414
|
});
|
|
19054
19415
|
import { execSync as execSync5 } from "node:child_process";
|
|
19055
19416
|
import fsSync2 from "node:fs";
|
|
19056
|
-
import
|
|
19417
|
+
import fs40 from "node:fs/promises";
|
|
19057
19418
|
import os12 from "node:os";
|
|
19058
19419
|
import path42 from "node:path";
|
|
19059
19420
|
import readline2 from "node:readline";
|
|
19060
|
-
import
|
|
19421
|
+
import chalk9 from "chalk";
|
|
19061
19422
|
async function getDirectorySize(dirPath) {
|
|
19062
19423
|
let totalSize = 0;
|
|
19063
19424
|
try {
|
|
19064
|
-
const entries = await
|
|
19425
|
+
const entries = await fs40.readdir(dirPath, { withFileTypes: true });
|
|
19065
19426
|
for (const entry of entries) {
|
|
19066
19427
|
const entryPath = path42.join(dirPath, entry.name);
|
|
19067
19428
|
if (entry.isDirectory()) {
|
|
19068
19429
|
totalSize += await getDirectorySize(entryPath);
|
|
19069
19430
|
} else {
|
|
19070
19431
|
try {
|
|
19071
|
-
const stats = await
|
|
19432
|
+
const stats = await fs40.stat(entryPath);
|
|
19072
19433
|
totalSize += stats.size;
|
|
19073
19434
|
} catch {
|
|
19074
19435
|
}
|
|
@@ -19087,7 +19448,7 @@ function formatSize(bytes) {
|
|
|
19087
19448
|
}
|
|
19088
19449
|
async function countDirectoryItems(dirPath) {
|
|
19089
19450
|
try {
|
|
19090
|
-
const entries = await
|
|
19451
|
+
const entries = await fs40.readdir(dirPath, { withFileTypes: true });
|
|
19091
19452
|
return entries.filter((e) => e.isDirectory()).length;
|
|
19092
19453
|
} catch {
|
|
19093
19454
|
return 0;
|
|
@@ -19202,7 +19563,7 @@ async function gatherUninstallItems() {
|
|
|
19202
19563
|
}
|
|
19203
19564
|
async function removePrjctSection(filePath) {
|
|
19204
19565
|
try {
|
|
19205
|
-
const content = await
|
|
19566
|
+
const content = await fs40.readFile(filePath, "utf-8");
|
|
19206
19567
|
if (!content.includes(PRJCT_START_MARKER) || !content.includes(PRJCT_END_MARKER)) {
|
|
19207
19568
|
return false;
|
|
19208
19569
|
}
|
|
@@ -19211,9 +19572,9 @@ async function removePrjctSection(filePath) {
|
|
|
19211
19572
|
let newContent = content.substring(0, startIndex) + content.substring(endIndex);
|
|
19212
19573
|
newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
|
|
19213
19574
|
if (!newContent || newContent.trim().length === 0) {
|
|
19214
|
-
await
|
|
19575
|
+
await fs40.unlink(filePath);
|
|
19215
19576
|
} else {
|
|
19216
|
-
await
|
|
19577
|
+
await fs40.writeFile(filePath, `${newContent}
|
|
19217
19578
|
`, "utf-8");
|
|
19218
19579
|
}
|
|
19219
19580
|
return true;
|
|
@@ -19226,7 +19587,7 @@ async function createBackup() {
|
|
|
19226
19587
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
19227
19588
|
const backupDir = path42.join(homeDir, `.prjct-backup-${timestamp}`);
|
|
19228
19589
|
try {
|
|
19229
|
-
await
|
|
19590
|
+
await fs40.mkdir(backupDir, { recursive: true });
|
|
19230
19591
|
const prjctCliPath = path_manager_default.getGlobalBasePath();
|
|
19231
19592
|
if (fsSync2.existsSync(prjctCliPath)) {
|
|
19232
19593
|
await copyDirectory(prjctCliPath, path42.join(backupDir, ".prjct-cli"));
|
|
@@ -19237,15 +19598,15 @@ async function createBackup() {
|
|
|
19237
19598
|
}
|
|
19238
19599
|
}
|
|
19239
19600
|
async function copyDirectory(src, dest) {
|
|
19240
|
-
await
|
|
19241
|
-
const entries = await
|
|
19601
|
+
await fs40.mkdir(dest, { recursive: true });
|
|
19602
|
+
const entries = await fs40.readdir(src, { withFileTypes: true });
|
|
19242
19603
|
for (const entry of entries) {
|
|
19243
19604
|
const srcPath = path42.join(src, entry.name);
|
|
19244
19605
|
const destPath = path42.join(dest, entry.name);
|
|
19245
19606
|
if (entry.isDirectory()) {
|
|
19246
19607
|
await copyDirectory(srcPath, destPath);
|
|
19247
19608
|
} else {
|
|
19248
|
-
await
|
|
19609
|
+
await fs40.copyFile(srcPath, destPath);
|
|
19249
19610
|
}
|
|
19250
19611
|
}
|
|
19251
19612
|
}
|
|
@@ -19261,10 +19622,10 @@ async function performUninstall(items, installation, options) {
|
|
|
19261
19622
|
deleted.push(item.path);
|
|
19262
19623
|
}
|
|
19263
19624
|
} else if (item.type === "directory") {
|
|
19264
|
-
await
|
|
19625
|
+
await fs40.rm(item.path, { recursive: true, force: true });
|
|
19265
19626
|
deleted.push(item.path);
|
|
19266
19627
|
} else if (item.type === "file") {
|
|
19267
|
-
await
|
|
19628
|
+
await fs40.unlink(item.path);
|
|
19268
19629
|
deleted.push(item.path);
|
|
19269
19630
|
}
|
|
19270
19631
|
} catch (error) {
|
|
@@ -19312,7 +19673,7 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
|
|
|
19312
19673
|
const installation = detectInstallation();
|
|
19313
19674
|
const existingItems = items.filter((i) => i.exists);
|
|
19314
19675
|
if (existingItems.length === 0 && !installation.homebrew && !installation.npm) {
|
|
19315
|
-
console.log(
|
|
19676
|
+
console.log(chalk9.yellow("\nNo prjct installation found."));
|
|
19316
19677
|
return {
|
|
19317
19678
|
success: true,
|
|
19318
19679
|
message: "Nothing to uninstall"
|
|
@@ -19320,36 +19681,36 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
|
|
|
19320
19681
|
}
|
|
19321
19682
|
const totalSize = existingItems.reduce((sum, item) => sum + (item.size || 0), 0);
|
|
19322
19683
|
console.log("");
|
|
19323
|
-
console.log(
|
|
19684
|
+
console.log(chalk9.red.bold(" WARNING: This action is DANGEROUS and IRREVERSIBLE"));
|
|
19324
19685
|
console.log("");
|
|
19325
|
-
console.log(
|
|
19686
|
+
console.log(chalk9.white("The following will be permanently deleted:"));
|
|
19326
19687
|
console.log("");
|
|
19327
19688
|
for (const item of existingItems) {
|
|
19328
19689
|
const displayPath = path_manager_default.getDisplayPath(item.path);
|
|
19329
19690
|
let info = "";
|
|
19330
19691
|
if (item.type === "section") {
|
|
19331
|
-
info =
|
|
19692
|
+
info = chalk9.dim("(section only)");
|
|
19332
19693
|
} else if (item.size) {
|
|
19333
|
-
info =
|
|
19694
|
+
info = chalk9.dim(`(${formatSize(item.size)})`);
|
|
19334
19695
|
}
|
|
19335
|
-
console.log(` ${
|
|
19336
|
-
console.log(` ${
|
|
19696
|
+
console.log(` ${chalk9.cyan(displayPath.padEnd(35))} ${info}`);
|
|
19697
|
+
console.log(` ${chalk9.dim(item.description)}`);
|
|
19337
19698
|
console.log("");
|
|
19338
19699
|
}
|
|
19339
19700
|
if (installation.homebrew) {
|
|
19340
|
-
console.log(` ${
|
|
19701
|
+
console.log(` ${chalk9.cyan("Homebrew".padEnd(35))} ${chalk9.dim("prjct-cli formula")}`);
|
|
19341
19702
|
console.log("");
|
|
19342
19703
|
}
|
|
19343
19704
|
if (installation.npm) {
|
|
19344
|
-
console.log(` ${
|
|
19705
|
+
console.log(` ${chalk9.cyan("npm global".padEnd(35))} ${chalk9.dim("prjct-cli package")}`);
|
|
19345
19706
|
console.log("");
|
|
19346
19707
|
}
|
|
19347
19708
|
if (totalSize > 0) {
|
|
19348
|
-
console.log(
|
|
19709
|
+
console.log(chalk9.dim(` Total size: ${formatSize(totalSize)}`));
|
|
19349
19710
|
console.log("");
|
|
19350
19711
|
}
|
|
19351
19712
|
if (options.dryRun) {
|
|
19352
|
-
console.log(
|
|
19713
|
+
console.log(chalk9.yellow("Dry run - no changes made"));
|
|
19353
19714
|
return {
|
|
19354
19715
|
success: true,
|
|
19355
19716
|
message: "Dry run complete",
|
|
@@ -19357,20 +19718,20 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
|
|
|
19357
19718
|
};
|
|
19358
19719
|
}
|
|
19359
19720
|
if (options.backup) {
|
|
19360
|
-
console.log(
|
|
19721
|
+
console.log(chalk9.blue("Creating backup..."));
|
|
19361
19722
|
const backupPath = await createBackup();
|
|
19362
19723
|
if (backupPath) {
|
|
19363
|
-
console.log(
|
|
19724
|
+
console.log(chalk9.green(`Backup created: ${path_manager_default.getDisplayPath(backupPath)}`));
|
|
19364
19725
|
console.log("");
|
|
19365
19726
|
} else {
|
|
19366
|
-
console.log(
|
|
19727
|
+
console.log(chalk9.yellow("Failed to create backup, continuing..."));
|
|
19367
19728
|
}
|
|
19368
19729
|
}
|
|
19369
19730
|
if (!options.force) {
|
|
19370
|
-
console.log(
|
|
19731
|
+
console.log(chalk9.yellow('Type "uninstall" to confirm:'));
|
|
19371
19732
|
const confirmed = await promptConfirmation("> ");
|
|
19372
19733
|
if (!confirmed) {
|
|
19373
|
-
console.log(
|
|
19734
|
+
console.log(chalk9.yellow("\nUninstall cancelled."));
|
|
19374
19735
|
return {
|
|
19375
19736
|
success: false,
|
|
19376
19737
|
message: "Uninstall cancelled by user"
|
|
@@ -19378,22 +19739,22 @@ async function uninstall(options = {}, _projectPath = process.cwd()) {
|
|
|
19378
19739
|
}
|
|
19379
19740
|
}
|
|
19380
19741
|
console.log("");
|
|
19381
|
-
console.log(
|
|
19742
|
+
console.log(chalk9.blue("Removing prjct..."));
|
|
19382
19743
|
const { deleted, errors } = await performUninstall(items, installation, options);
|
|
19383
19744
|
console.log("");
|
|
19384
19745
|
if (deleted.length > 0) {
|
|
19385
|
-
console.log(
|
|
19746
|
+
console.log(chalk9.green(`Removed ${deleted.length} items`));
|
|
19386
19747
|
}
|
|
19387
19748
|
if (errors.length > 0) {
|
|
19388
|
-
console.log(
|
|
19749
|
+
console.log(chalk9.yellow(`
|
|
19389
19750
|
${errors.length} errors:`));
|
|
19390
19751
|
for (const error of errors) {
|
|
19391
|
-
console.log(
|
|
19752
|
+
console.log(chalk9.red(` - ${error}`));
|
|
19392
19753
|
}
|
|
19393
19754
|
}
|
|
19394
19755
|
console.log("");
|
|
19395
|
-
console.log(
|
|
19396
|
-
console.log(
|
|
19756
|
+
console.log(chalk9.green("prjct has been uninstalled."));
|
|
19757
|
+
console.log(chalk9.dim("Thanks for using prjct! We hope to see you again."));
|
|
19397
19758
|
console.log("");
|
|
19398
19759
|
return {
|
|
19399
19760
|
success: errors.length === 0,
|
|
@@ -19440,7 +19801,7 @@ __export(watch_service_exports, {
|
|
|
19440
19801
|
watchService: () => watchService
|
|
19441
19802
|
});
|
|
19442
19803
|
import path43 from "node:path";
|
|
19443
|
-
import
|
|
19804
|
+
import chalk10 from "chalk";
|
|
19444
19805
|
import chokidar from "chokidar";
|
|
19445
19806
|
var TRIGGER_PATTERNS, IGNORE_PATTERNS2, WatchService, watchService;
|
|
19446
19807
|
var init_watch_service = __esm({
|
|
@@ -19550,7 +19911,7 @@ var init_watch_service = __esm({
|
|
|
19550
19911
|
async stop() {
|
|
19551
19912
|
if (!this.options.quiet) {
|
|
19552
19913
|
console.log("");
|
|
19553
|
-
console.log(
|
|
19914
|
+
console.log(chalk10.dim(`
|
|
19554
19915
|
\u{1F44B} Stopped watching (${this.syncCount} syncs performed)`));
|
|
19555
19916
|
}
|
|
19556
19917
|
if (this.debounceTimer) {
|
|
@@ -19571,7 +19932,7 @@ var init_watch_service = __esm({
|
|
|
19571
19932
|
this.pendingChanges.add(filePath);
|
|
19572
19933
|
if (this.options.verbose && !this.options.quiet) {
|
|
19573
19934
|
const eventIcon = event === "add" ? "\u2795" : event === "unlink" ? "\u2796" : "\u{1F4DD}";
|
|
19574
|
-
console.log(
|
|
19935
|
+
console.log(chalk10.dim(` ${eventIcon} ${filePath}`));
|
|
19575
19936
|
}
|
|
19576
19937
|
this.scheduleSyncIfNeeded();
|
|
19577
19938
|
}
|
|
@@ -19588,7 +19949,7 @@ var init_watch_service = __esm({
|
|
|
19588
19949
|
if (timeSinceLastSync < this.options.minIntervalMs && this.lastSyncTime > 0) {
|
|
19589
19950
|
const waitTime = this.options.minIntervalMs - timeSinceLastSync;
|
|
19590
19951
|
if (this.options.verbose && !this.options.quiet) {
|
|
19591
|
-
console.log(
|
|
19952
|
+
console.log(chalk10.dim(` \u23F3 Rate limited, waiting ${Math.round(waitTime / 1e3)}s...`));
|
|
19592
19953
|
}
|
|
19593
19954
|
this.debounceTimer = setTimeout(() => this.performSync(), waitTime);
|
|
19594
19955
|
return;
|
|
@@ -19608,7 +19969,7 @@ var init_watch_service = __esm({
|
|
|
19608
19969
|
const filesSummary = changedFiles.length === 1 ? changedFiles[0] : `${changedFiles.length} files`;
|
|
19609
19970
|
console.log(
|
|
19610
19971
|
`
|
|
19611
|
-
${
|
|
19972
|
+
${chalk10.dim(`[${timestamp}]`)} ${chalk10.cyan("\u27F3")} ${filesSummary} changed \u2192 syncing...`
|
|
19612
19973
|
);
|
|
19613
19974
|
}
|
|
19614
19975
|
try {
|
|
@@ -19619,16 +19980,16 @@ ${chalk9.dim(`[${timestamp}]`)} ${chalk9.cyan("\u27F3")} ${filesSummary} changed
|
|
|
19619
19980
|
if (!this.options.quiet) {
|
|
19620
19981
|
const agents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
|
|
19621
19982
|
const agentStr = agents.length > 0 ? ` [${agents.join(", ")}]` : "";
|
|
19622
|
-
console.log(`${
|
|
19983
|
+
console.log(`${chalk10.dim(`[${timestamp}]`)} ${chalk10.green("\u2713")} Synced${agentStr}`);
|
|
19623
19984
|
}
|
|
19624
19985
|
} else {
|
|
19625
19986
|
console.error(
|
|
19626
|
-
`${
|
|
19987
|
+
`${chalk10.dim(`[${timestamp}]`)} ${chalk10.red("\u2717")} Sync failed: ${result.error}`
|
|
19627
19988
|
);
|
|
19628
19989
|
}
|
|
19629
19990
|
} catch (error) {
|
|
19630
19991
|
console.error(
|
|
19631
|
-
`${
|
|
19992
|
+
`${chalk10.dim(`[${timestamp}]`)} ${chalk10.red("\u2717")} Error: ${error.message}`
|
|
19632
19993
|
);
|
|
19633
19994
|
}
|
|
19634
19995
|
}
|
|
@@ -19636,19 +19997,19 @@ ${chalk9.dim(`[${timestamp}]`)} ${chalk9.cyan("\u27F3")} ${filesSummary} changed
|
|
|
19636
19997
|
* Handle watcher errors
|
|
19637
19998
|
*/
|
|
19638
19999
|
handleError(error) {
|
|
19639
|
-
console.error(
|
|
20000
|
+
console.error(chalk10.red(`Watch error: ${error.message}`));
|
|
19640
20001
|
}
|
|
19641
20002
|
/**
|
|
19642
20003
|
* Print startup message
|
|
19643
20004
|
*/
|
|
19644
20005
|
printStartup() {
|
|
19645
20006
|
console.log("");
|
|
19646
|
-
console.log(
|
|
19647
|
-
console.log(
|
|
19648
|
-
console.log(
|
|
19649
|
-
console.log(
|
|
20007
|
+
console.log(chalk10.cyan("\u{1F441}\uFE0F Watching for changes..."));
|
|
20008
|
+
console.log(chalk10.dim(` Project: ${path43.basename(this.projectPath)}`));
|
|
20009
|
+
console.log(chalk10.dim(` Debounce: ${this.options.debounceMs}ms`));
|
|
20010
|
+
console.log(chalk10.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
|
|
19650
20011
|
console.log("");
|
|
19651
|
-
console.log(
|
|
20012
|
+
console.log(chalk10.dim(" Press Ctrl+C to stop"));
|
|
19652
20013
|
console.log("");
|
|
19653
20014
|
}
|
|
19654
20015
|
};
|
|
@@ -20296,7 +20657,7 @@ __export(setup_exports, {
|
|
|
20296
20657
|
run: () => run
|
|
20297
20658
|
});
|
|
20298
20659
|
import { execSync as execSync6 } from "node:child_process";
|
|
20299
|
-
import
|
|
20660
|
+
import fs41 from "node:fs";
|
|
20300
20661
|
import os13 from "node:os";
|
|
20301
20662
|
import path44 from "node:path";
|
|
20302
20663
|
async function installAICLI(provider) {
|
|
@@ -20406,9 +20767,9 @@ async function installGeminiRouter() {
|
|
|
20406
20767
|
const geminiCommandsDir = path44.join(os13.homedir(), ".gemini", "commands");
|
|
20407
20768
|
const routerSource = path44.join(getPackageRoot(), "templates", "commands", "p.toml");
|
|
20408
20769
|
const routerDest = path44.join(geminiCommandsDir, "p.toml");
|
|
20409
|
-
|
|
20410
|
-
if (
|
|
20411
|
-
|
|
20770
|
+
fs41.mkdirSync(geminiCommandsDir, { recursive: true });
|
|
20771
|
+
if (fs41.existsSync(routerSource)) {
|
|
20772
|
+
fs41.copyFileSync(routerSource, routerDest);
|
|
20412
20773
|
return true;
|
|
20413
20774
|
}
|
|
20414
20775
|
return false;
|
|
@@ -20422,12 +20783,12 @@ async function installGeminiGlobalConfig() {
|
|
|
20422
20783
|
const geminiDir = path44.join(os13.homedir(), ".gemini");
|
|
20423
20784
|
const globalConfigPath = path44.join(geminiDir, "GEMINI.md");
|
|
20424
20785
|
const templatePath = path44.join(getPackageRoot(), "templates", "global", "GEMINI.md");
|
|
20425
|
-
|
|
20426
|
-
const templateContent =
|
|
20786
|
+
fs41.mkdirSync(geminiDir, { recursive: true });
|
|
20787
|
+
const templateContent = fs41.readFileSync(templatePath, "utf-8");
|
|
20427
20788
|
let existingContent = "";
|
|
20428
20789
|
let fileExists2 = false;
|
|
20429
20790
|
try {
|
|
20430
|
-
existingContent =
|
|
20791
|
+
existingContent = fs41.readFileSync(globalConfigPath, "utf-8");
|
|
20431
20792
|
fileExists2 = true;
|
|
20432
20793
|
} catch (error) {
|
|
20433
20794
|
if (isNotFoundError(error)) {
|
|
@@ -20437,7 +20798,7 @@ async function installGeminiGlobalConfig() {
|
|
|
20437
20798
|
}
|
|
20438
20799
|
}
|
|
20439
20800
|
if (!fileExists2) {
|
|
20440
|
-
|
|
20801
|
+
fs41.writeFileSync(globalConfigPath, templateContent, "utf-8");
|
|
20441
20802
|
return { success: true, action: "created" };
|
|
20442
20803
|
}
|
|
20443
20804
|
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
@@ -20447,7 +20808,7 @@ async function installGeminiGlobalConfig() {
|
|
|
20447
20808
|
const updatedContent2 = `${existingContent}
|
|
20448
20809
|
|
|
20449
20810
|
${templateContent}`;
|
|
20450
|
-
|
|
20811
|
+
fs41.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
|
|
20451
20812
|
return { success: true, action: "appended" };
|
|
20452
20813
|
}
|
|
20453
20814
|
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
|
|
@@ -20459,7 +20820,7 @@ ${templateContent}`;
|
|
|
20459
20820
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
20460
20821
|
);
|
|
20461
20822
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
20462
|
-
|
|
20823
|
+
fs41.writeFileSync(globalConfigPath, updatedContent, "utf-8");
|
|
20463
20824
|
return { success: true, action: "updated" };
|
|
20464
20825
|
} catch (error) {
|
|
20465
20826
|
console.error(`Gemini config warning: ${error.message}`);
|
|
@@ -20472,14 +20833,14 @@ async function installAntigravitySkill() {
|
|
|
20472
20833
|
const prjctSkillDir = path44.join(antigravitySkillsDir, "prjct");
|
|
20473
20834
|
const skillMdPath = path44.join(prjctSkillDir, "SKILL.md");
|
|
20474
20835
|
const templatePath = path44.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
|
|
20475
|
-
|
|
20476
|
-
const fileExists2 =
|
|
20477
|
-
if (!
|
|
20836
|
+
fs41.mkdirSync(prjctSkillDir, { recursive: true });
|
|
20837
|
+
const fileExists2 = fs41.existsSync(skillMdPath);
|
|
20838
|
+
if (!fs41.existsSync(templatePath)) {
|
|
20478
20839
|
console.error("Antigravity SKILL.md template not found");
|
|
20479
20840
|
return { success: false, action: null };
|
|
20480
20841
|
}
|
|
20481
|
-
const templateContent =
|
|
20482
|
-
|
|
20842
|
+
const templateContent = fs41.readFileSync(templatePath, "utf-8");
|
|
20843
|
+
fs41.writeFileSync(skillMdPath, templateContent, "utf-8");
|
|
20483
20844
|
return { success: true, action: fileExists2 ? "updated" : "created" };
|
|
20484
20845
|
} catch (error) {
|
|
20485
20846
|
console.error(`Antigravity skill warning: ${error.message}`);
|
|
@@ -20504,18 +20865,18 @@ async function installCursorProject(projectRoot) {
|
|
|
20504
20865
|
const routerMdcDest = path44.join(rulesDir, "prjct.mdc");
|
|
20505
20866
|
const routerMdcSource = path44.join(getPackageRoot(), "templates", "cursor", "router.mdc");
|
|
20506
20867
|
const cursorCommandsSource = path44.join(getPackageRoot(), "templates", "cursor", "commands");
|
|
20507
|
-
|
|
20508
|
-
|
|
20509
|
-
if (
|
|
20510
|
-
|
|
20868
|
+
fs41.mkdirSync(rulesDir, { recursive: true });
|
|
20869
|
+
fs41.mkdirSync(commandsDir, { recursive: true });
|
|
20870
|
+
if (fs41.existsSync(routerMdcSource)) {
|
|
20871
|
+
fs41.copyFileSync(routerMdcSource, routerMdcDest);
|
|
20511
20872
|
result.rulesCreated = true;
|
|
20512
20873
|
}
|
|
20513
|
-
if (
|
|
20514
|
-
const commandFiles =
|
|
20874
|
+
if (fs41.existsSync(cursorCommandsSource)) {
|
|
20875
|
+
const commandFiles = fs41.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
|
|
20515
20876
|
for (const file of commandFiles) {
|
|
20516
20877
|
const src = path44.join(cursorCommandsSource, file);
|
|
20517
20878
|
const dest = path44.join(commandsDir, file);
|
|
20518
|
-
|
|
20879
|
+
fs41.copyFileSync(src, dest);
|
|
20519
20880
|
}
|
|
20520
20881
|
result.commandsCreated = commandFiles.length > 0;
|
|
20521
20882
|
}
|
|
@@ -20544,7 +20905,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
20544
20905
|
let content = "";
|
|
20545
20906
|
let fileExists2 = false;
|
|
20546
20907
|
try {
|
|
20547
|
-
content =
|
|
20908
|
+
content = fs41.readFileSync(gitignorePath, "utf-8");
|
|
20548
20909
|
fileExists2 = true;
|
|
20549
20910
|
} catch (error) {
|
|
20550
20911
|
if (!isNotFoundError(error)) {
|
|
@@ -20559,7 +20920,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
20559
20920
|
${entriesToAdd.join("\n")}
|
|
20560
20921
|
` : `${entriesToAdd.join("\n")}
|
|
20561
20922
|
`;
|
|
20562
|
-
|
|
20923
|
+
fs41.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
20563
20924
|
return true;
|
|
20564
20925
|
} catch (error) {
|
|
20565
20926
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -20567,12 +20928,12 @@ ${entriesToAdd.join("\n")}
|
|
|
20567
20928
|
}
|
|
20568
20929
|
}
|
|
20569
20930
|
function hasCursorProject(projectRoot) {
|
|
20570
|
-
return
|
|
20931
|
+
return fs41.existsSync(path44.join(projectRoot, ".cursor"));
|
|
20571
20932
|
}
|
|
20572
20933
|
function needsCursorRegeneration(projectRoot) {
|
|
20573
20934
|
const cursorDir = path44.join(projectRoot, ".cursor");
|
|
20574
20935
|
const routerPath = path44.join(cursorDir, "rules", "prjct.mdc");
|
|
20575
|
-
return
|
|
20936
|
+
return fs41.existsSync(cursorDir) && !fs41.existsSync(routerPath);
|
|
20576
20937
|
}
|
|
20577
20938
|
async function installWindsurfProject(projectRoot) {
|
|
20578
20939
|
const result = {
|
|
@@ -20593,18 +20954,18 @@ async function installWindsurfProject(projectRoot) {
|
|
|
20593
20954
|
"windsurf",
|
|
20594
20955
|
"workflows"
|
|
20595
20956
|
);
|
|
20596
|
-
|
|
20597
|
-
|
|
20598
|
-
if (
|
|
20599
|
-
|
|
20957
|
+
fs41.mkdirSync(rulesDir, { recursive: true });
|
|
20958
|
+
fs41.mkdirSync(workflowsDir, { recursive: true });
|
|
20959
|
+
if (fs41.existsSync(routerSource)) {
|
|
20960
|
+
fs41.copyFileSync(routerSource, routerDest);
|
|
20600
20961
|
result.rulesCreated = true;
|
|
20601
20962
|
}
|
|
20602
|
-
if (
|
|
20603
|
-
const workflowFiles =
|
|
20963
|
+
if (fs41.existsSync(windsurfWorkflowsSource)) {
|
|
20964
|
+
const workflowFiles = fs41.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
|
|
20604
20965
|
for (const file of workflowFiles) {
|
|
20605
20966
|
const src = path44.join(windsurfWorkflowsSource, file);
|
|
20606
20967
|
const dest = path44.join(workflowsDir, file);
|
|
20607
|
-
|
|
20968
|
+
fs41.copyFileSync(src, dest);
|
|
20608
20969
|
}
|
|
20609
20970
|
result.workflowsCreated = workflowFiles.length > 0;
|
|
20610
20971
|
}
|
|
@@ -20633,7 +20994,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
20633
20994
|
let content = "";
|
|
20634
20995
|
let fileExists2 = false;
|
|
20635
20996
|
try {
|
|
20636
|
-
content =
|
|
20997
|
+
content = fs41.readFileSync(gitignorePath, "utf-8");
|
|
20637
20998
|
fileExists2 = true;
|
|
20638
20999
|
} catch (error) {
|
|
20639
21000
|
if (!isNotFoundError(error)) {
|
|
@@ -20648,7 +21009,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
20648
21009
|
${entriesToAdd.join("\n")}
|
|
20649
21010
|
` : `${entriesToAdd.join("\n")}
|
|
20650
21011
|
`;
|
|
20651
|
-
|
|
21012
|
+
fs41.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
20652
21013
|
return true;
|
|
20653
21014
|
} catch (error) {
|
|
20654
21015
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -20656,32 +21017,32 @@ ${entriesToAdd.join("\n")}
|
|
|
20656
21017
|
}
|
|
20657
21018
|
}
|
|
20658
21019
|
function hasWindsurfProject(projectRoot) {
|
|
20659
|
-
return
|
|
21020
|
+
return fs41.existsSync(path44.join(projectRoot, ".windsurf"));
|
|
20660
21021
|
}
|
|
20661
21022
|
function needsWindsurfRegeneration(projectRoot) {
|
|
20662
21023
|
const windsurfDir = path44.join(projectRoot, ".windsurf");
|
|
20663
21024
|
const routerPath = path44.join(windsurfDir, "rules", "prjct.md");
|
|
20664
|
-
return
|
|
21025
|
+
return fs41.existsSync(windsurfDir) && !fs41.existsSync(routerPath);
|
|
20665
21026
|
}
|
|
20666
21027
|
async function migrateProjectsCliVersion() {
|
|
20667
21028
|
try {
|
|
20668
21029
|
const projectsDir = path44.join(os13.homedir(), ".prjct-cli", "projects");
|
|
20669
|
-
if (!
|
|
21030
|
+
if (!fs41.existsSync(projectsDir)) {
|
|
20670
21031
|
return;
|
|
20671
21032
|
}
|
|
20672
|
-
const projectDirs =
|
|
21033
|
+
const projectDirs = fs41.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
20673
21034
|
let migrated = 0;
|
|
20674
21035
|
for (const projectId of projectDirs) {
|
|
20675
21036
|
const projectJsonPath = path44.join(projectsDir, projectId, "project.json");
|
|
20676
|
-
if (!
|
|
21037
|
+
if (!fs41.existsSync(projectJsonPath)) {
|
|
20677
21038
|
continue;
|
|
20678
21039
|
}
|
|
20679
21040
|
try {
|
|
20680
|
-
const content =
|
|
21041
|
+
const content = fs41.readFileSync(projectJsonPath, "utf8");
|
|
20681
21042
|
const project = JSON.parse(content);
|
|
20682
21043
|
if (project.cliVersion !== VERSION) {
|
|
20683
21044
|
project.cliVersion = VERSION;
|
|
20684
|
-
|
|
21045
|
+
fs41.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
20685
21046
|
migrated++;
|
|
20686
21047
|
}
|
|
20687
21048
|
} catch (error) {
|
|
@@ -20701,9 +21062,9 @@ async function migrateProjectsCliVersion() {
|
|
|
20701
21062
|
}
|
|
20702
21063
|
function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
20703
21064
|
let settings = {};
|
|
20704
|
-
if (
|
|
21065
|
+
if (fs41.existsSync(settingsPath)) {
|
|
20705
21066
|
try {
|
|
20706
|
-
settings = JSON.parse(
|
|
21067
|
+
settings = JSON.parse(fs41.readFileSync(settingsPath, "utf8"));
|
|
20707
21068
|
} catch (error) {
|
|
20708
21069
|
if (!(error instanceof SyntaxError)) {
|
|
20709
21070
|
throw error;
|
|
@@ -20711,7 +21072,7 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
|
20711
21072
|
}
|
|
20712
21073
|
}
|
|
20713
21074
|
settings.statusLine = { type: "command", command: statusLinePath };
|
|
20714
|
-
|
|
21075
|
+
fs41.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
20715
21076
|
}
|
|
20716
21077
|
async function installStatusLine() {
|
|
20717
21078
|
try {
|
|
@@ -20730,23 +21091,23 @@ async function installStatusLine() {
|
|
|
20730
21091
|
const sourceLibDir = path44.join(assetsDir, "lib");
|
|
20731
21092
|
const sourceComponentsDir = path44.join(assetsDir, "components");
|
|
20732
21093
|
const sourceConfigPath = path44.join(assetsDir, "default-config.json");
|
|
20733
|
-
if (!
|
|
20734
|
-
|
|
21094
|
+
if (!fs41.existsSync(claudeDir)) {
|
|
21095
|
+
fs41.mkdirSync(claudeDir, { recursive: true });
|
|
20735
21096
|
}
|
|
20736
|
-
if (!
|
|
20737
|
-
|
|
21097
|
+
if (!fs41.existsSync(prjctStatusLineDir)) {
|
|
21098
|
+
fs41.mkdirSync(prjctStatusLineDir, { recursive: true });
|
|
20738
21099
|
}
|
|
20739
|
-
if (!
|
|
20740
|
-
|
|
21100
|
+
if (!fs41.existsSync(prjctThemesDir)) {
|
|
21101
|
+
fs41.mkdirSync(prjctThemesDir, { recursive: true });
|
|
20741
21102
|
}
|
|
20742
|
-
if (!
|
|
20743
|
-
|
|
21103
|
+
if (!fs41.existsSync(prjctLibDir)) {
|
|
21104
|
+
fs41.mkdirSync(prjctLibDir, { recursive: true });
|
|
20744
21105
|
}
|
|
20745
|
-
if (!
|
|
20746
|
-
|
|
21106
|
+
if (!fs41.existsSync(prjctComponentsDir)) {
|
|
21107
|
+
fs41.mkdirSync(prjctComponentsDir, { recursive: true });
|
|
20747
21108
|
}
|
|
20748
|
-
if (
|
|
20749
|
-
const existingContent =
|
|
21109
|
+
if (fs41.existsSync(prjctStatusLinePath)) {
|
|
21110
|
+
const existingContent = fs41.readFileSync(prjctStatusLinePath, "utf8");
|
|
20750
21111
|
if (existingContent.includes("CLI_VERSION=")) {
|
|
20751
21112
|
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
20752
21113
|
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
@@ -20754,7 +21115,7 @@ async function installStatusLine() {
|
|
|
20754
21115
|
/CLI_VERSION="[^"]*"/,
|
|
20755
21116
|
`CLI_VERSION="${VERSION}"`
|
|
20756
21117
|
);
|
|
20757
|
-
|
|
21118
|
+
fs41.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
20758
21119
|
}
|
|
20759
21120
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
20760
21121
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
@@ -20763,22 +21124,22 @@ async function installStatusLine() {
|
|
|
20763
21124
|
return;
|
|
20764
21125
|
}
|
|
20765
21126
|
}
|
|
20766
|
-
if (
|
|
20767
|
-
let scriptContent =
|
|
21127
|
+
if (fs41.existsSync(sourceScript)) {
|
|
21128
|
+
let scriptContent = fs41.readFileSync(sourceScript, "utf8");
|
|
20768
21129
|
scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
|
|
20769
|
-
|
|
21130
|
+
fs41.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
20770
21131
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
20771
21132
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
20772
|
-
if (
|
|
20773
|
-
const themes =
|
|
21133
|
+
if (fs41.existsSync(sourceThemeDir)) {
|
|
21134
|
+
const themes = fs41.readdirSync(sourceThemeDir);
|
|
20774
21135
|
for (const theme of themes) {
|
|
20775
21136
|
const src = path44.join(sourceThemeDir, theme);
|
|
20776
21137
|
const dest = path44.join(prjctThemesDir, theme);
|
|
20777
|
-
|
|
21138
|
+
fs41.copyFileSync(src, dest);
|
|
20778
21139
|
}
|
|
20779
21140
|
}
|
|
20780
|
-
if (!
|
|
20781
|
-
|
|
21141
|
+
if (!fs41.existsSync(prjctConfigPath) && fs41.existsSync(sourceConfigPath)) {
|
|
21142
|
+
fs41.copyFileSync(sourceConfigPath, prjctConfigPath);
|
|
20782
21143
|
}
|
|
20783
21144
|
} else {
|
|
20784
21145
|
const scriptContent = `#!/bin/bash
|
|
@@ -20813,7 +21174,7 @@ if [ -f "$CONFIG" ]; then
|
|
|
20813
21174
|
fi
|
|
20814
21175
|
echo "prjct"
|
|
20815
21176
|
`;
|
|
20816
|
-
|
|
21177
|
+
fs41.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
20817
21178
|
}
|
|
20818
21179
|
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
20819
21180
|
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
@@ -20824,37 +21185,37 @@ echo "prjct"
|
|
|
20824
21185
|
}
|
|
20825
21186
|
}
|
|
20826
21187
|
function installStatusLineModules(sourceDir, destDir) {
|
|
20827
|
-
if (!
|
|
21188
|
+
if (!fs41.existsSync(sourceDir)) {
|
|
20828
21189
|
return;
|
|
20829
21190
|
}
|
|
20830
|
-
const files =
|
|
21191
|
+
const files = fs41.readdirSync(sourceDir);
|
|
20831
21192
|
for (const file of files) {
|
|
20832
21193
|
if (file.endsWith(".sh")) {
|
|
20833
21194
|
const src = path44.join(sourceDir, file);
|
|
20834
21195
|
const dest = path44.join(destDir, file);
|
|
20835
|
-
|
|
20836
|
-
|
|
21196
|
+
fs41.copyFileSync(src, dest);
|
|
21197
|
+
fs41.chmodSync(dest, 493);
|
|
20837
21198
|
}
|
|
20838
21199
|
}
|
|
20839
21200
|
}
|
|
20840
21201
|
function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
20841
21202
|
try {
|
|
20842
|
-
if (
|
|
20843
|
-
const stats =
|
|
21203
|
+
if (fs41.existsSync(linkPath)) {
|
|
21204
|
+
const stats = fs41.lstatSync(linkPath);
|
|
20844
21205
|
if (stats.isSymbolicLink()) {
|
|
20845
|
-
const existingTarget =
|
|
21206
|
+
const existingTarget = fs41.readlinkSync(linkPath);
|
|
20846
21207
|
if (existingTarget === targetPath) {
|
|
20847
21208
|
return;
|
|
20848
21209
|
}
|
|
20849
21210
|
}
|
|
20850
|
-
|
|
21211
|
+
fs41.unlinkSync(linkPath);
|
|
20851
21212
|
}
|
|
20852
|
-
|
|
21213
|
+
fs41.symlinkSync(targetPath, linkPath);
|
|
20853
21214
|
} catch (_error) {
|
|
20854
21215
|
try {
|
|
20855
|
-
if (
|
|
20856
|
-
|
|
20857
|
-
|
|
21216
|
+
if (fs41.existsSync(targetPath)) {
|
|
21217
|
+
fs41.copyFileSync(targetPath, linkPath);
|
|
21218
|
+
fs41.chmodSync(linkPath, 493);
|
|
20858
21219
|
}
|
|
20859
21220
|
} catch (copyError) {
|
|
20860
21221
|
if (!isNotFoundError(copyError)) {
|
|
@@ -21538,7 +21899,7 @@ ${"\u2550".repeat(50)}
|
|
|
21538
21899
|
});
|
|
21539
21900
|
|
|
21540
21901
|
// core/commands/context.ts
|
|
21541
|
-
import
|
|
21902
|
+
import fs42 from "node:fs/promises";
|
|
21542
21903
|
import path46 from "node:path";
|
|
21543
21904
|
var ContextCommands, contextCommands;
|
|
21544
21905
|
var init_context = __esm({
|
|
@@ -21666,7 +22027,7 @@ var init_context = __esm({
|
|
|
21666
22027
|
async loadRepoAnalysis(globalPath) {
|
|
21667
22028
|
try {
|
|
21668
22029
|
const analysisPath = path46.join(globalPath, "analysis", "repo-analysis.json");
|
|
21669
|
-
const content = await
|
|
22030
|
+
const content = await fs42.readFile(analysisPath, "utf-8");
|
|
21670
22031
|
const data = JSON.parse(content);
|
|
21671
22032
|
return {
|
|
21672
22033
|
ecosystem: data.ecosystem || "unknown",
|
|
@@ -22162,9 +22523,9 @@ var init_maintenance = __esm({
|
|
|
22162
22523
|
});
|
|
22163
22524
|
|
|
22164
22525
|
// core/commands/setup.ts
|
|
22165
|
-
import
|
|
22526
|
+
import fs43 from "node:fs";
|
|
22166
22527
|
import path50 from "node:path";
|
|
22167
|
-
import
|
|
22528
|
+
import chalk11 from "chalk";
|
|
22168
22529
|
var SetupCommands;
|
|
22169
22530
|
var init_setup2 = __esm({
|
|
22170
22531
|
"core/commands/setup.ts"() {
|
|
@@ -22348,11 +22709,11 @@ fi
|
|
|
22348
22709
|
# Default: show prjct branding
|
|
22349
22710
|
echo "\u26A1 prjct"
|
|
22350
22711
|
`;
|
|
22351
|
-
|
|
22712
|
+
fs43.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
22352
22713
|
let settings = {};
|
|
22353
|
-
if (
|
|
22714
|
+
if (fs43.existsSync(settingsPath)) {
|
|
22354
22715
|
try {
|
|
22355
|
-
settings = JSON.parse(
|
|
22716
|
+
settings = JSON.parse(fs43.readFileSync(settingsPath, "utf8"));
|
|
22356
22717
|
} catch (_error) {
|
|
22357
22718
|
}
|
|
22358
22719
|
}
|
|
@@ -22360,7 +22721,7 @@ echo "\u26A1 prjct"
|
|
|
22360
22721
|
type: "command",
|
|
22361
22722
|
command: statusLinePath
|
|
22362
22723
|
};
|
|
22363
|
-
|
|
22724
|
+
fs43.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
22364
22725
|
return { success: true };
|
|
22365
22726
|
} catch (error) {
|
|
22366
22727
|
return { success: false, error: error.message };
|
|
@@ -22370,45 +22731,45 @@ echo "\u26A1 prjct"
|
|
|
22370
22731
|
* Show beautiful ASCII art with quick start
|
|
22371
22732
|
*/
|
|
22372
22733
|
showAsciiArt() {
|
|
22373
|
-
console.log(
|
|
22734
|
+
console.log(chalk11.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
22374
22735
|
console.log("");
|
|
22375
|
-
console.log(
|
|
22376
|
-
console.log(
|
|
22377
|
-
console.log(
|
|
22378
|
-
console.log(
|
|
22379
|
-
console.log(
|
|
22380
|
-
console.log(
|
|
22736
|
+
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"));
|
|
22737
|
+
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"));
|
|
22738
|
+
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"));
|
|
22739
|
+
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"));
|
|
22740
|
+
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"));
|
|
22741
|
+
console.log(chalk11.bold.cyan(" \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D"));
|
|
22381
22742
|
console.log("");
|
|
22382
22743
|
console.log(
|
|
22383
|
-
` ${
|
|
22744
|
+
` ${chalk11.bold.cyan("prjct")}${chalk11.magenta("/")}${chalk11.green("cli")} ${chalk11.dim.white(`v${VERSION} installed`)}`
|
|
22384
22745
|
);
|
|
22385
22746
|
console.log("");
|
|
22386
|
-
console.log(` ${
|
|
22387
|
-
console.log(` ${
|
|
22388
|
-
console.log(` ${
|
|
22747
|
+
console.log(` ${chalk11.yellow("\u26A1")} Ship faster with zero friction`);
|
|
22748
|
+
console.log(` ${chalk11.green("\u{1F4DD}")} From idea to technical tasks in minutes`);
|
|
22749
|
+
console.log(` ${chalk11.cyan("\u{1F916}")} Perfect context for AI agents`);
|
|
22389
22750
|
console.log("");
|
|
22390
|
-
console.log(
|
|
22751
|
+
console.log(chalk11.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
22391
22752
|
console.log("");
|
|
22392
|
-
console.log(
|
|
22393
|
-
console.log(
|
|
22753
|
+
console.log(chalk11.bold.cyan("\u{1F680} Quick Start"));
|
|
22754
|
+
console.log(chalk11.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
22394
22755
|
console.log("");
|
|
22395
|
-
console.log(` ${
|
|
22396
|
-
console.log(` ${
|
|
22756
|
+
console.log(` ${chalk11.bold("1.")} Initialize your project:`);
|
|
22757
|
+
console.log(` ${chalk11.green("cd your-project && prjct init")}`);
|
|
22397
22758
|
console.log("");
|
|
22398
|
-
console.log(` ${
|
|
22399
|
-
console.log(` ${
|
|
22759
|
+
console.log(` ${chalk11.bold("2.")} Start your first task:`);
|
|
22760
|
+
console.log(` ${chalk11.green('prjct task "build auth"')}`);
|
|
22400
22761
|
console.log("");
|
|
22401
|
-
console.log(` ${
|
|
22402
|
-
console.log(` ${
|
|
22762
|
+
console.log(` ${chalk11.bold("3.")} Ship & celebrate:`);
|
|
22763
|
+
console.log(` ${chalk11.green('prjct ship "user login"')}`);
|
|
22403
22764
|
console.log("");
|
|
22404
|
-
console.log(
|
|
22765
|
+
console.log(chalk11.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
22405
22766
|
console.log("");
|
|
22406
|
-
console.log(` ${
|
|
22767
|
+
console.log(` ${chalk11.dim("Documentation:")} ${chalk11.cyan("https://prjct.app")}`);
|
|
22407
22768
|
console.log(
|
|
22408
|
-
` ${
|
|
22769
|
+
` ${chalk11.dim("Report issues:")} ${chalk11.cyan("https://github.com/jlopezlira/prjct-cli/issues")}`
|
|
22409
22770
|
);
|
|
22410
22771
|
console.log("");
|
|
22411
|
-
console.log(
|
|
22772
|
+
console.log(chalk11.bold.magenta("Happy shipping! \u{1F680}"));
|
|
22412
22773
|
console.log("");
|
|
22413
22774
|
}
|
|
22414
22775
|
};
|
|
@@ -23718,7 +24079,7 @@ var init_linear = __esm({
|
|
|
23718
24079
|
});
|
|
23719
24080
|
|
|
23720
24081
|
// core/utils/project-credentials.ts
|
|
23721
|
-
import
|
|
24082
|
+
import fs44 from "node:fs";
|
|
23722
24083
|
import os14 from "node:os";
|
|
23723
24084
|
import path53 from "node:path";
|
|
23724
24085
|
function getCredentialsPath(projectId) {
|
|
@@ -23726,11 +24087,11 @@ function getCredentialsPath(projectId) {
|
|
|
23726
24087
|
}
|
|
23727
24088
|
async function getProjectCredentials(projectId) {
|
|
23728
24089
|
const credPath = getCredentialsPath(projectId);
|
|
23729
|
-
if (!
|
|
24090
|
+
if (!fs44.existsSync(credPath)) {
|
|
23730
24091
|
return {};
|
|
23731
24092
|
}
|
|
23732
24093
|
try {
|
|
23733
|
-
return JSON.parse(
|
|
24094
|
+
return JSON.parse(fs44.readFileSync(credPath, "utf-8"));
|
|
23734
24095
|
} catch (error) {
|
|
23735
24096
|
console.error("[project-credentials] Failed to read credentials:", error.message);
|
|
23736
24097
|
return {};
|
|
@@ -24303,7 +24664,7 @@ var require_package = __commonJS({
|
|
|
24303
24664
|
"package.json"(exports, module) {
|
|
24304
24665
|
module.exports = {
|
|
24305
24666
|
name: "prjct-cli",
|
|
24306
|
-
version: "0.
|
|
24667
|
+
version: "0.52.0",
|
|
24307
24668
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
24308
24669
|
main: "core/index.ts",
|
|
24309
24670
|
bin: {
|
|
@@ -24408,7 +24769,7 @@ var require_package = __commonJS({
|
|
|
24408
24769
|
|
|
24409
24770
|
// core/index.ts
|
|
24410
24771
|
var core_exports = {};
|
|
24411
|
-
import
|
|
24772
|
+
import fs45 from "node:fs";
|
|
24412
24773
|
import os15 from "node:os";
|
|
24413
24774
|
import path54 from "node:path";
|
|
24414
24775
|
async function main() {
|
|
@@ -24537,10 +24898,10 @@ function displayVersion(version) {
|
|
|
24537
24898
|
const detection = detectAllProviders();
|
|
24538
24899
|
const claudeCommandPath = path54.join(os15.homedir(), ".claude", "commands", "p.md");
|
|
24539
24900
|
const geminiCommandPath = path54.join(os15.homedir(), ".gemini", "commands", "p.toml");
|
|
24540
|
-
const claudeConfigured =
|
|
24541
|
-
const geminiConfigured =
|
|
24542
|
-
const cursorConfigured =
|
|
24543
|
-
const cursorExists =
|
|
24901
|
+
const claudeConfigured = fs45.existsSync(claudeCommandPath);
|
|
24902
|
+
const geminiConfigured = fs45.existsSync(geminiCommandPath);
|
|
24903
|
+
const cursorConfigured = fs45.existsSync(path54.join(process.cwd(), ".cursor", "commands", "sync.md"));
|
|
24904
|
+
const cursorExists = fs45.existsSync(path54.join(process.cwd(), ".cursor"));
|
|
24544
24905
|
console.log(`
|
|
24545
24906
|
${CYAN3}p/${RESET5} prjct v${version}
|
|
24546
24907
|
${DIM6}Context layer for AI coding agents${RESET5}
|
|
@@ -24673,7 +25034,7 @@ var init_core = __esm({
|
|
|
24673
25034
|
init_ai_provider();
|
|
24674
25035
|
init_config_manager();
|
|
24675
25036
|
init_editors_config();
|
|
24676
|
-
import
|
|
25037
|
+
import fs46 from "node:fs";
|
|
24677
25038
|
import os16 from "node:os";
|
|
24678
25039
|
import path55 from "node:path";
|
|
24679
25040
|
|
|
@@ -25418,13 +25779,13 @@ function checkRoutersInstalled() {
|
|
|
25418
25779
|
const detection = detectAllProviders();
|
|
25419
25780
|
if (detection.claude.installed) {
|
|
25420
25781
|
const claudeRouter = path55.join(home, ".claude", "commands", "p.md");
|
|
25421
|
-
if (!
|
|
25782
|
+
if (!fs46.existsSync(claudeRouter)) {
|
|
25422
25783
|
return false;
|
|
25423
25784
|
}
|
|
25424
25785
|
}
|
|
25425
25786
|
if (detection.gemini.installed) {
|
|
25426
25787
|
const geminiRouter = path55.join(home, ".gemini", "commands", "p.toml");
|
|
25427
|
-
if (!
|
|
25788
|
+
if (!fs46.existsSync(geminiRouter)) {
|
|
25428
25789
|
return false;
|
|
25429
25790
|
}
|
|
25430
25791
|
}
|
|
@@ -25544,12 +25905,12 @@ if (args[0] === "start" || args[0] === "setup") {
|
|
|
25544
25905
|
const detection = detectAllProviders();
|
|
25545
25906
|
const home = os16.homedir();
|
|
25546
25907
|
const cwd = process.cwd();
|
|
25547
|
-
const claudeConfigured =
|
|
25548
|
-
const geminiConfigured =
|
|
25549
|
-
const cursorDetected =
|
|
25550
|
-
const cursorConfigured =
|
|
25551
|
-
const windsurfDetected =
|
|
25552
|
-
const windsurfConfigured =
|
|
25908
|
+
const claudeConfigured = fs46.existsSync(path55.join(home, ".claude", "commands", "p.md"));
|
|
25909
|
+
const geminiConfigured = fs46.existsSync(path55.join(home, ".gemini", "commands", "p.toml"));
|
|
25910
|
+
const cursorDetected = fs46.existsSync(path55.join(cwd, ".cursor"));
|
|
25911
|
+
const cursorConfigured = fs46.existsSync(path55.join(cwd, ".cursor", "rules", "prjct.mdc"));
|
|
25912
|
+
const windsurfDetected = fs46.existsSync(path55.join(cwd, ".windsurf"));
|
|
25913
|
+
const windsurfConfigured = fs46.existsSync(path55.join(cwd, ".windsurf", "rules", "prjct.md"));
|
|
25553
25914
|
const GREEN7 = "\x1B[32m";
|
|
25554
25915
|
console.log(`
|
|
25555
25916
|
${CYAN4}p/${RESET6} prjct v${VERSION}
|
|
@@ -25590,7 +25951,7 @@ ${CYAN4}https://prjct.app${RESET6}
|
|
|
25590
25951
|
} else {
|
|
25591
25952
|
const configPath = path55.join(os16.homedir(), ".prjct-cli", "config", "installed-editors.json");
|
|
25592
25953
|
const routersInstalled = checkRoutersInstalled();
|
|
25593
|
-
if (!
|
|
25954
|
+
if (!fs46.existsSync(configPath) || !routersInstalled) {
|
|
25594
25955
|
console.log(`
|
|
25595
25956
|
${CYAN4}${BOLD4} Welcome to prjct!${RESET6}
|
|
25596
25957
|
|