prjct-cli 1.2.2 → 1.3.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 +52 -0
- package/bin/prjct.ts +26 -0
- package/core/commands/analysis.ts +8 -2
- package/core/index.ts +26 -1
- package/core/services/session-tracker.ts +287 -0
- package/core/services/staleness-checker.ts +52 -0
- package/dist/bin/prjct.mjs +1135 -838
- package/package.json +1 -1
package/dist/bin/prjct.mjs
CHANGED
|
@@ -16,10 +16,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
16
16
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
17
17
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
18
18
|
});
|
|
19
|
-
var __glob = (map) => (
|
|
20
|
-
var fn = map[
|
|
19
|
+
var __glob = (map) => (path61) => {
|
|
20
|
+
var fn = map[path61];
|
|
21
21
|
if (fn) return fn();
|
|
22
|
-
throw new Error("Module not found in bundle: " +
|
|
22
|
+
throw new Error("Module not found in bundle: " + path61);
|
|
23
23
|
};
|
|
24
24
|
var __esm = (fn, res) => function __init() {
|
|
25
25
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -2541,15 +2541,219 @@ ${chalk2.bold(title)}`);
|
|
|
2541
2541
|
}
|
|
2542
2542
|
});
|
|
2543
2543
|
|
|
2544
|
+
// core/services/session-tracker.ts
|
|
2545
|
+
var session_tracker_exports = {};
|
|
2546
|
+
__export(session_tracker_exports, {
|
|
2547
|
+
default: () => session_tracker_default,
|
|
2548
|
+
sessionTracker: () => sessionTracker
|
|
2549
|
+
});
|
|
2550
|
+
import fs9 from "node:fs/promises";
|
|
2551
|
+
import path9 from "node:path";
|
|
2552
|
+
var SESSION_FILENAME, DEFAULT_IDLE_TIMEOUT_MS, MAX_COMMAND_HISTORY, MAX_FILE_HISTORY, SessionTracker, sessionTracker, session_tracker_default;
|
|
2553
|
+
var init_session_tracker = __esm({
|
|
2554
|
+
"core/services/session-tracker.ts"() {
|
|
2555
|
+
"use strict";
|
|
2556
|
+
init_path_manager();
|
|
2557
|
+
init_fs();
|
|
2558
|
+
init_date_helper();
|
|
2559
|
+
SESSION_FILENAME = "session.json";
|
|
2560
|
+
DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
2561
|
+
MAX_COMMAND_HISTORY = 50;
|
|
2562
|
+
MAX_FILE_HISTORY = 200;
|
|
2563
|
+
SessionTracker = class {
|
|
2564
|
+
static {
|
|
2565
|
+
__name(this, "SessionTracker");
|
|
2566
|
+
}
|
|
2567
|
+
getPath(projectId) {
|
|
2568
|
+
return path_manager_default.getStoragePath(projectId, SESSION_FILENAME);
|
|
2569
|
+
}
|
|
2570
|
+
/**
|
|
2571
|
+
* Read session file from disk
|
|
2572
|
+
*/
|
|
2573
|
+
async read(projectId) {
|
|
2574
|
+
const filePath = this.getPath(projectId);
|
|
2575
|
+
try {
|
|
2576
|
+
const content = await fs9.readFile(filePath, "utf-8");
|
|
2577
|
+
return JSON.parse(content);
|
|
2578
|
+
} catch (error) {
|
|
2579
|
+
if (isNotFoundError(error) || error instanceof SyntaxError) {
|
|
2580
|
+
return this.getDefault();
|
|
2581
|
+
}
|
|
2582
|
+
throw error;
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
/**
|
|
2586
|
+
* Write session file to disk
|
|
2587
|
+
*/
|
|
2588
|
+
async write(projectId, data) {
|
|
2589
|
+
const filePath = this.getPath(projectId);
|
|
2590
|
+
await fs9.mkdir(path9.dirname(filePath), { recursive: true });
|
|
2591
|
+
await fs9.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
2592
|
+
}
|
|
2593
|
+
getDefault() {
|
|
2594
|
+
return {
|
|
2595
|
+
current: null,
|
|
2596
|
+
config: {
|
|
2597
|
+
idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS
|
|
2598
|
+
}
|
|
2599
|
+
};
|
|
2600
|
+
}
|
|
2601
|
+
/**
|
|
2602
|
+
* Check if a session has expired based on idle timeout
|
|
2603
|
+
*/
|
|
2604
|
+
isExpired(session, timeoutMs) {
|
|
2605
|
+
const lastActivity = new Date(session.lastActivity).getTime();
|
|
2606
|
+
const now = Date.now();
|
|
2607
|
+
return now - lastActivity > timeoutMs;
|
|
2608
|
+
}
|
|
2609
|
+
/**
|
|
2610
|
+
* Touch session — create new or resume existing.
|
|
2611
|
+
* Called at the start of every CLI command.
|
|
2612
|
+
* Returns the active session.
|
|
2613
|
+
*/
|
|
2614
|
+
async touch(projectId) {
|
|
2615
|
+
const file = await this.read(projectId);
|
|
2616
|
+
const now = getTimestamp();
|
|
2617
|
+
if (file.current && !this.isExpired(file.current, file.config.idleTimeoutMs)) {
|
|
2618
|
+
file.current.lastActivity = now;
|
|
2619
|
+
await this.write(projectId, file);
|
|
2620
|
+
return file.current;
|
|
2621
|
+
}
|
|
2622
|
+
const session = {
|
|
2623
|
+
id: crypto.randomUUID(),
|
|
2624
|
+
projectId,
|
|
2625
|
+
status: "active",
|
|
2626
|
+
createdAt: now,
|
|
2627
|
+
lastActivity: now,
|
|
2628
|
+
commands: [],
|
|
2629
|
+
files: []
|
|
2630
|
+
};
|
|
2631
|
+
file.current = session;
|
|
2632
|
+
await this.write(projectId, file);
|
|
2633
|
+
return session;
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Record a command execution in the current session
|
|
2637
|
+
*/
|
|
2638
|
+
async trackCommand(projectId, command, durationMs) {
|
|
2639
|
+
const file = await this.read(projectId);
|
|
2640
|
+
if (!file.current) return;
|
|
2641
|
+
const now = getTimestamp();
|
|
2642
|
+
file.current.lastActivity = now;
|
|
2643
|
+
file.current.commands.push({
|
|
2644
|
+
command,
|
|
2645
|
+
timestamp: now,
|
|
2646
|
+
durationMs
|
|
2647
|
+
});
|
|
2648
|
+
if (file.current.commands.length > MAX_COMMAND_HISTORY) {
|
|
2649
|
+
file.current.commands = file.current.commands.slice(-MAX_COMMAND_HISTORY);
|
|
2650
|
+
}
|
|
2651
|
+
await this.write(projectId, file);
|
|
2652
|
+
}
|
|
2653
|
+
/**
|
|
2654
|
+
* Record a file access in the current session
|
|
2655
|
+
*/
|
|
2656
|
+
async trackFile(projectId, filePath, operation) {
|
|
2657
|
+
const file = await this.read(projectId);
|
|
2658
|
+
if (!file.current) return;
|
|
2659
|
+
const now = getTimestamp();
|
|
2660
|
+
file.current.lastActivity = now;
|
|
2661
|
+
file.current.files.push({
|
|
2662
|
+
path: filePath,
|
|
2663
|
+
operation,
|
|
2664
|
+
timestamp: now
|
|
2665
|
+
});
|
|
2666
|
+
if (file.current.files.length > MAX_FILE_HISTORY) {
|
|
2667
|
+
file.current.files = file.current.files.slice(-MAX_FILE_HISTORY);
|
|
2668
|
+
}
|
|
2669
|
+
await this.write(projectId, file);
|
|
2670
|
+
}
|
|
2671
|
+
/**
|
|
2672
|
+
* Get session info for display (used by `prjct status`)
|
|
2673
|
+
*/
|
|
2674
|
+
async getInfo(projectId) {
|
|
2675
|
+
const file = await this.read(projectId);
|
|
2676
|
+
if (!file.current || this.isExpired(file.current, file.config.idleTimeoutMs)) {
|
|
2677
|
+
return {
|
|
2678
|
+
active: false,
|
|
2679
|
+
id: null,
|
|
2680
|
+
duration: null,
|
|
2681
|
+
idleSince: null,
|
|
2682
|
+
idleMs: 0,
|
|
2683
|
+
expiresIn: null,
|
|
2684
|
+
commandCount: 0,
|
|
2685
|
+
commands: [],
|
|
2686
|
+
filesRead: 0,
|
|
2687
|
+
filesWritten: 0
|
|
2688
|
+
};
|
|
2689
|
+
}
|
|
2690
|
+
const session = file.current;
|
|
2691
|
+
const now = Date.now();
|
|
2692
|
+
const createdAt = new Date(session.createdAt).getTime();
|
|
2693
|
+
const lastActivity = new Date(session.lastActivity).getTime();
|
|
2694
|
+
const idleMs = now - lastActivity;
|
|
2695
|
+
const timeoutMs = file.config.idleTimeoutMs;
|
|
2696
|
+
const expiresInMs = Math.max(0, timeoutMs - idleMs);
|
|
2697
|
+
const uniqueCommands = session.commands.map((c) => c.command);
|
|
2698
|
+
const filesRead = new Set(
|
|
2699
|
+
session.files.filter((f) => f.operation === "read").map((f) => f.path)
|
|
2700
|
+
).size;
|
|
2701
|
+
const filesWritten = new Set(
|
|
2702
|
+
session.files.filter((f) => f.operation === "write").map((f) => f.path)
|
|
2703
|
+
).size;
|
|
2704
|
+
return {
|
|
2705
|
+
active: true,
|
|
2706
|
+
id: session.id,
|
|
2707
|
+
duration: formatDuration(now - createdAt),
|
|
2708
|
+
idleSince: session.lastActivity,
|
|
2709
|
+
idleMs,
|
|
2710
|
+
expiresIn: formatDuration(expiresInMs),
|
|
2711
|
+
commandCount: session.commands.length,
|
|
2712
|
+
commands: uniqueCommands,
|
|
2713
|
+
filesRead,
|
|
2714
|
+
filesWritten
|
|
2715
|
+
};
|
|
2716
|
+
}
|
|
2717
|
+
/**
|
|
2718
|
+
* Expire the current session (cleanup)
|
|
2719
|
+
*/
|
|
2720
|
+
async expire(projectId) {
|
|
2721
|
+
const file = await this.read(projectId);
|
|
2722
|
+
if (file.current) {
|
|
2723
|
+
file.current.status = "expired";
|
|
2724
|
+
file.current = null;
|
|
2725
|
+
await this.write(projectId, file);
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
/**
|
|
2729
|
+
* Check and expire stale session if needed.
|
|
2730
|
+
* Called on startup to clean up leftover sessions.
|
|
2731
|
+
* Returns true if a session was expired.
|
|
2732
|
+
*/
|
|
2733
|
+
async expireIfStale(projectId) {
|
|
2734
|
+
const file = await this.read(projectId);
|
|
2735
|
+
if (file.current && this.isExpired(file.current, file.config.idleTimeoutMs)) {
|
|
2736
|
+
file.current = null;
|
|
2737
|
+
await this.write(projectId, file);
|
|
2738
|
+
return true;
|
|
2739
|
+
}
|
|
2740
|
+
return false;
|
|
2741
|
+
}
|
|
2742
|
+
};
|
|
2743
|
+
sessionTracker = new SessionTracker();
|
|
2744
|
+
session_tracker_default = sessionTracker;
|
|
2745
|
+
}
|
|
2746
|
+
});
|
|
2747
|
+
|
|
2544
2748
|
// core/cli/start.ts
|
|
2545
2749
|
var start_exports = {};
|
|
2546
2750
|
__export(start_exports, {
|
|
2547
2751
|
default: () => start_default,
|
|
2548
2752
|
runStart: () => runStart
|
|
2549
2753
|
});
|
|
2550
|
-
import
|
|
2754
|
+
import fs10 from "node:fs";
|
|
2551
2755
|
import os4 from "node:os";
|
|
2552
|
-
import
|
|
2756
|
+
import path10 from "node:path";
|
|
2553
2757
|
import chalk3 from "chalk";
|
|
2554
2758
|
function showBanner() {
|
|
2555
2759
|
console.clear();
|
|
@@ -2652,15 +2856,15 @@ async function installRouter(provider) {
|
|
|
2652
2856
|
return false;
|
|
2653
2857
|
}
|
|
2654
2858
|
try {
|
|
2655
|
-
const commandsDir =
|
|
2656
|
-
|
|
2859
|
+
const commandsDir = path10.join(config.configDir, "commands");
|
|
2860
|
+
fs10.mkdirSync(commandsDir, { recursive: true });
|
|
2657
2861
|
const { getPackageRoot: getPackageRoot2 } = await Promise.resolve().then(() => (init_version(), version_exports));
|
|
2658
2862
|
const packageRoot = getPackageRoot2();
|
|
2659
2863
|
const routerFile = provider === "claude" ? "p.md" : "p.toml";
|
|
2660
|
-
const src =
|
|
2661
|
-
const dest =
|
|
2662
|
-
if (
|
|
2663
|
-
|
|
2864
|
+
const src = path10.join(packageRoot, "templates", "commands", routerFile);
|
|
2865
|
+
const dest = path10.join(commandsDir, routerFile);
|
|
2866
|
+
if (fs10.existsSync(src)) {
|
|
2867
|
+
fs10.copyFileSync(src, dest);
|
|
2664
2868
|
return true;
|
|
2665
2869
|
}
|
|
2666
2870
|
return false;
|
|
@@ -2677,16 +2881,16 @@ async function installGlobalConfig(provider) {
|
|
|
2677
2881
|
return false;
|
|
2678
2882
|
}
|
|
2679
2883
|
try {
|
|
2680
|
-
|
|
2884
|
+
fs10.mkdirSync(config.configDir, { recursive: true });
|
|
2681
2885
|
const { getPackageRoot: getPackageRoot2 } = await Promise.resolve().then(() => (init_version(), version_exports));
|
|
2682
2886
|
const packageRoot = getPackageRoot2();
|
|
2683
2887
|
const configFile = provider === "claude" ? "CLAUDE.md" : "GEMINI.md";
|
|
2684
|
-
const src =
|
|
2685
|
-
const dest =
|
|
2686
|
-
if (
|
|
2687
|
-
const content =
|
|
2688
|
-
if (
|
|
2689
|
-
const existing =
|
|
2888
|
+
const src = path10.join(packageRoot, "templates", "global", configFile);
|
|
2889
|
+
const dest = path10.join(config.configDir, configFile);
|
|
2890
|
+
if (fs10.existsSync(src)) {
|
|
2891
|
+
const content = fs10.readFileSync(src, "utf-8");
|
|
2892
|
+
if (fs10.existsSync(dest)) {
|
|
2893
|
+
const existing = fs10.readFileSync(dest, "utf-8");
|
|
2690
2894
|
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
2691
2895
|
const endMarker = "<!-- prjct:end - DO NOT REMOVE THIS MARKER -->";
|
|
2692
2896
|
if (existing.includes(startMarker) && existing.includes(endMarker)) {
|
|
@@ -2696,14 +2900,14 @@ async function installGlobalConfig(provider) {
|
|
|
2696
2900
|
content.indexOf(startMarker),
|
|
2697
2901
|
content.indexOf(endMarker) + endMarker.length
|
|
2698
2902
|
);
|
|
2699
|
-
|
|
2903
|
+
fs10.writeFileSync(dest, before + prjctSection + after);
|
|
2700
2904
|
} else {
|
|
2701
|
-
|
|
2905
|
+
fs10.writeFileSync(dest, `${existing}
|
|
2702
2906
|
|
|
2703
2907
|
${content}`);
|
|
2704
2908
|
}
|
|
2705
2909
|
} else {
|
|
2706
|
-
|
|
2910
|
+
fs10.writeFileSync(dest, content);
|
|
2707
2911
|
}
|
|
2708
2912
|
return true;
|
|
2709
2913
|
}
|
|
@@ -2716,9 +2920,9 @@ ${content}`);
|
|
|
2716
2920
|
}
|
|
2717
2921
|
}
|
|
2718
2922
|
async function saveSetupConfig(providers) {
|
|
2719
|
-
const configDir =
|
|
2720
|
-
|
|
2721
|
-
const configPath =
|
|
2923
|
+
const configDir = path10.join(os4.homedir(), ".prjct-cli", "config");
|
|
2924
|
+
fs10.mkdirSync(configDir, { recursive: true });
|
|
2925
|
+
const configPath = path10.join(configDir, "installed-editors.json");
|
|
2722
2926
|
const config = {
|
|
2723
2927
|
version: VERSION,
|
|
2724
2928
|
providers,
|
|
@@ -2726,9 +2930,9 @@ async function saveSetupConfig(providers) {
|
|
|
2726
2930
|
// deprecated, for backward compat
|
|
2727
2931
|
provider: providers[0],
|
|
2728
2932
|
lastInstall: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2729
|
-
path:
|
|
2933
|
+
path: path10.join(os4.homedir(), `.${providers[0]}`, "commands")
|
|
2730
2934
|
};
|
|
2731
|
-
|
|
2935
|
+
fs10.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
2732
2936
|
}
|
|
2733
2937
|
function showCompletion(providers) {
|
|
2734
2938
|
console.log(`
|
|
@@ -2756,9 +2960,9 @@ ${chalk3.green.bold(" \u2713 Setup complete!")}
|
|
|
2756
2960
|
}
|
|
2757
2961
|
async function runStart() {
|
|
2758
2962
|
showBanner();
|
|
2759
|
-
const configPath =
|
|
2760
|
-
if (
|
|
2761
|
-
const existing = JSON.parse(
|
|
2963
|
+
const configPath = path10.join(os4.homedir(), ".prjct-cli", "config", "installed-editors.json");
|
|
2964
|
+
if (fs10.existsSync(configPath)) {
|
|
2965
|
+
const existing = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
|
|
2762
2966
|
if (existing.version === VERSION) {
|
|
2763
2967
|
console.log(` ${chalk3.yellow("\u2139")} Already configured for v${VERSION}`);
|
|
2764
2968
|
console.log(` ${chalk3.dim("Run with --force to reconfigure")}
|
|
@@ -3111,8 +3315,8 @@ var init_cache = __esm({
|
|
|
3111
3315
|
});
|
|
3112
3316
|
|
|
3113
3317
|
// core/storage/storage-manager.ts
|
|
3114
|
-
import
|
|
3115
|
-
import
|
|
3318
|
+
import fs11 from "node:fs/promises";
|
|
3319
|
+
import path11 from "node:path";
|
|
3116
3320
|
var StorageManager;
|
|
3117
3321
|
var init_storage_manager = __esm({
|
|
3118
3322
|
"core/storage/storage-manager.ts"() {
|
|
@@ -3156,7 +3360,7 @@ var init_storage_manager = __esm({
|
|
|
3156
3360
|
}
|
|
3157
3361
|
const filePath = this.getStoragePath(projectId);
|
|
3158
3362
|
try {
|
|
3159
|
-
const content = await
|
|
3363
|
+
const content = await fs11.readFile(filePath, "utf-8");
|
|
3160
3364
|
const data = JSON.parse(content);
|
|
3161
3365
|
this.cache.set(projectId, data);
|
|
3162
3366
|
return data;
|
|
@@ -3173,13 +3377,13 @@ var init_storage_manager = __esm({
|
|
|
3173
3377
|
async write(projectId, data) {
|
|
3174
3378
|
const storagePath = this.getStoragePath(projectId);
|
|
3175
3379
|
const contextPath = this.getContextPath(projectId, this.getMdFilename());
|
|
3176
|
-
await
|
|
3177
|
-
await
|
|
3380
|
+
await fs11.mkdir(path11.dirname(storagePath), { recursive: true });
|
|
3381
|
+
await fs11.mkdir(path11.dirname(contextPath), { recursive: true });
|
|
3178
3382
|
const tempPath = `${storagePath}.${Date.now()}.tmp`;
|
|
3179
|
-
await
|
|
3180
|
-
await
|
|
3383
|
+
await fs11.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
3384
|
+
await fs11.rename(tempPath, storagePath);
|
|
3181
3385
|
const md2 = this.toMarkdown(data);
|
|
3182
|
-
await
|
|
3386
|
+
await fs11.writeFile(contextPath, md2, "utf-8");
|
|
3183
3387
|
this.cache.set(projectId, data);
|
|
3184
3388
|
}
|
|
3185
3389
|
/**
|
|
@@ -3227,7 +3431,7 @@ var init_storage_manager = __esm({
|
|
|
3227
3431
|
async exists(projectId) {
|
|
3228
3432
|
const filePath = this.getStoragePath(projectId);
|
|
3229
3433
|
try {
|
|
3230
|
-
await
|
|
3434
|
+
await fs11.access(filePath);
|
|
3231
3435
|
return true;
|
|
3232
3436
|
} catch (error) {
|
|
3233
3437
|
if (isNotFoundError(error)) {
|
|
@@ -3489,8 +3693,8 @@ var init_metrics_storage = __esm({
|
|
|
3489
3693
|
|
|
3490
3694
|
// core/context-tools/files-tool.ts
|
|
3491
3695
|
import { exec as execCallback2 } from "node:child_process";
|
|
3492
|
-
import
|
|
3493
|
-
import
|
|
3696
|
+
import fs12 from "node:fs/promises";
|
|
3697
|
+
import path12 from "node:path";
|
|
3494
3698
|
import { promisify as promisify2 } from "node:util";
|
|
3495
3699
|
async function findRelevantFiles(taskDescription, projectPath, options = {}) {
|
|
3496
3700
|
const startTime = Date.now();
|
|
@@ -3619,17 +3823,17 @@ async function getAllCodeFiles(projectPath) {
|
|
|
3619
3823
|
const files = [];
|
|
3620
3824
|
async function walk(dir, relativePath = "") {
|
|
3621
3825
|
try {
|
|
3622
|
-
const entries = await
|
|
3826
|
+
const entries = await fs12.readdir(dir, { withFileTypes: true });
|
|
3623
3827
|
for (const entry of entries) {
|
|
3624
|
-
const fullPath =
|
|
3625
|
-
const relPath =
|
|
3828
|
+
const fullPath = path12.join(dir, entry.name);
|
|
3829
|
+
const relPath = path12.join(relativePath, entry.name);
|
|
3626
3830
|
if (entry.isDirectory()) {
|
|
3627
3831
|
if (IGNORE_DIRS.has(entry.name) || entry.name.startsWith(".")) {
|
|
3628
3832
|
continue;
|
|
3629
3833
|
}
|
|
3630
3834
|
await walk(fullPath, relPath);
|
|
3631
3835
|
} else if (entry.isFile()) {
|
|
3632
|
-
const ext =
|
|
3836
|
+
const ext = path12.extname(entry.name).toLowerCase();
|
|
3633
3837
|
if (CODE_EXTENSIONS.has(ext)) {
|
|
3634
3838
|
files.push(relPath);
|
|
3635
3839
|
}
|
|
@@ -3726,7 +3930,7 @@ function scoreFile(filePath, keywords, gitRecency) {
|
|
|
3726
3930
|
recencyScore = Math.min(1, recencyScore + 0.2);
|
|
3727
3931
|
}
|
|
3728
3932
|
}
|
|
3729
|
-
const filename =
|
|
3933
|
+
const filename = path12.basename(filePath).toLowerCase();
|
|
3730
3934
|
if (filename.includes("index") || filename.includes("main") || filename.includes("app") || filename.includes("entry")) {
|
|
3731
3935
|
importScore = 0.5;
|
|
3732
3936
|
reasons.push("import:0");
|
|
@@ -3923,14 +4127,14 @@ var init_files_tool = __esm({
|
|
|
3923
4127
|
|
|
3924
4128
|
// core/context-tools/imports-tool.ts
|
|
3925
4129
|
import { exec as execCallback3 } from "node:child_process";
|
|
3926
|
-
import
|
|
3927
|
-
import
|
|
4130
|
+
import fs13 from "node:fs/promises";
|
|
4131
|
+
import path13 from "node:path";
|
|
3928
4132
|
import { promisify as promisify3 } from "node:util";
|
|
3929
4133
|
async function analyzeImports(filePath, projectPath = process.cwd(), options = {}) {
|
|
3930
|
-
const absolutePath =
|
|
4134
|
+
const absolutePath = path13.isAbsolute(filePath) ? filePath : path13.join(projectPath, filePath);
|
|
3931
4135
|
let content;
|
|
3932
4136
|
try {
|
|
3933
|
-
content = await
|
|
4137
|
+
content = await fs13.readFile(absolutePath, "utf-8");
|
|
3934
4138
|
} catch (error) {
|
|
3935
4139
|
if (isNotFoundError(error)) {
|
|
3936
4140
|
return {
|
|
@@ -3947,7 +4151,7 @@ async function analyzeImports(filePath, projectPath = process.cwd(), options = {
|
|
|
3947
4151
|
}
|
|
3948
4152
|
throw error;
|
|
3949
4153
|
}
|
|
3950
|
-
const ext =
|
|
4154
|
+
const ext = path13.extname(filePath).toLowerCase();
|
|
3951
4155
|
const language = EXT_TO_LANG[ext] || "unknown";
|
|
3952
4156
|
const patterns = IMPORT_PATTERNS[language] || [];
|
|
3953
4157
|
const imports = extractImports(content, patterns, absolutePath, projectPath);
|
|
@@ -4009,12 +4213,12 @@ function extractImports(content, patterns, absolutePath, projectPath) {
|
|
|
4009
4213
|
return imports;
|
|
4010
4214
|
}
|
|
4011
4215
|
function resolveImport(source, fromFile, projectPath) {
|
|
4012
|
-
const fileDir =
|
|
4216
|
+
const fileDir = path13.dirname(fromFile);
|
|
4013
4217
|
if (source.startsWith("@/")) {
|
|
4014
|
-
const aliasPath =
|
|
4218
|
+
const aliasPath = path13.join(projectPath, "src", source.slice(2));
|
|
4015
4219
|
return tryResolve(aliasPath, projectPath);
|
|
4016
4220
|
}
|
|
4017
|
-
const resolved =
|
|
4221
|
+
const resolved = path13.resolve(fileDir, source);
|
|
4018
4222
|
return tryResolve(resolved, projectPath);
|
|
4019
4223
|
}
|
|
4020
4224
|
function tryResolve(basePath, projectPath) {
|
|
@@ -4022,9 +4226,9 @@ function tryResolve(basePath, projectPath) {
|
|
|
4022
4226
|
for (const ext of extensions) {
|
|
4023
4227
|
const fullPath = basePath + ext;
|
|
4024
4228
|
try {
|
|
4025
|
-
const
|
|
4026
|
-
if (
|
|
4027
|
-
return
|
|
4229
|
+
const fs52 = __require("node:fs");
|
|
4230
|
+
if (fs52.existsSync(fullPath) && fs52.statSync(fullPath).isFile()) {
|
|
4231
|
+
return path13.relative(projectPath, fullPath);
|
|
4028
4232
|
}
|
|
4029
4233
|
} catch {
|
|
4030
4234
|
}
|
|
@@ -4033,8 +4237,8 @@ function tryResolve(basePath, projectPath) {
|
|
|
4033
4237
|
}
|
|
4034
4238
|
async function findImportedBy(filePath, projectPath) {
|
|
4035
4239
|
const importedBy = [];
|
|
4036
|
-
const baseName =
|
|
4037
|
-
const _dirName =
|
|
4240
|
+
const baseName = path13.basename(filePath, path13.extname(filePath));
|
|
4241
|
+
const _dirName = path13.dirname(filePath);
|
|
4038
4242
|
try {
|
|
4039
4243
|
const searchPatterns = [
|
|
4040
4244
|
`from ['"].*${baseName}['"]`,
|
|
@@ -4548,13 +4752,13 @@ var init_token_counter = __esm({
|
|
|
4548
4752
|
});
|
|
4549
4753
|
|
|
4550
4754
|
// core/context-tools/signatures-tool.ts
|
|
4551
|
-
import
|
|
4552
|
-
import
|
|
4755
|
+
import fs14 from "node:fs/promises";
|
|
4756
|
+
import path14 from "node:path";
|
|
4553
4757
|
async function extractSignatures(filePath, projectPath = process.cwd()) {
|
|
4554
|
-
const absolutePath =
|
|
4758
|
+
const absolutePath = path14.isAbsolute(filePath) ? filePath : path14.join(projectPath, filePath);
|
|
4555
4759
|
let content;
|
|
4556
4760
|
try {
|
|
4557
|
-
content = await
|
|
4761
|
+
content = await fs14.readFile(absolutePath, "utf-8");
|
|
4558
4762
|
} catch (error) {
|
|
4559
4763
|
if (isNotFoundError(error)) {
|
|
4560
4764
|
return {
|
|
@@ -4568,7 +4772,7 @@ async function extractSignatures(filePath, projectPath = process.cwd()) {
|
|
|
4568
4772
|
}
|
|
4569
4773
|
throw error;
|
|
4570
4774
|
}
|
|
4571
|
-
const ext =
|
|
4775
|
+
const ext = path14.extname(filePath).toLowerCase();
|
|
4572
4776
|
const language = EXTENSION_TO_LANGUAGE[ext] || "unknown";
|
|
4573
4777
|
const patterns = LANGUAGE_PATTERNS[language];
|
|
4574
4778
|
if (!patterns || patterns.length === 0) {
|
|
@@ -4595,13 +4799,13 @@ async function extractSignatures(filePath, projectPath = process.cwd()) {
|
|
|
4595
4799
|
};
|
|
4596
4800
|
}
|
|
4597
4801
|
async function extractDirectorySignatures(dirPath, projectPath = process.cwd(), options = {}) {
|
|
4598
|
-
const absolutePath =
|
|
4802
|
+
const absolutePath = path14.isAbsolute(dirPath) ? dirPath : path14.join(projectPath, dirPath);
|
|
4599
4803
|
const results = [];
|
|
4600
4804
|
async function processDir(dir) {
|
|
4601
|
-
const entries = await
|
|
4805
|
+
const entries = await fs14.readdir(dir, { withFileTypes: true });
|
|
4602
4806
|
for (const entry of entries) {
|
|
4603
|
-
const fullPath =
|
|
4604
|
-
const relativePath =
|
|
4807
|
+
const fullPath = path14.join(dir, entry.name);
|
|
4808
|
+
const relativePath = path14.relative(projectPath, fullPath);
|
|
4605
4809
|
if (entry.isDirectory()) {
|
|
4606
4810
|
if (entry.name === "node_modules" || entry.name === ".git" || entry.name.startsWith(".")) {
|
|
4607
4811
|
continue;
|
|
@@ -4610,7 +4814,7 @@ async function extractDirectorySignatures(dirPath, projectPath = process.cwd(),
|
|
|
4610
4814
|
await processDir(fullPath);
|
|
4611
4815
|
}
|
|
4612
4816
|
} else if (entry.isFile()) {
|
|
4613
|
-
const ext =
|
|
4817
|
+
const ext = path14.extname(entry.name).toLowerCase();
|
|
4614
4818
|
if (EXTENSION_TO_LANGUAGE[ext]) {
|
|
4615
4819
|
const result = await extractSignatures(relativePath, projectPath);
|
|
4616
4820
|
results.push(result);
|
|
@@ -4900,13 +5104,13 @@ var init_signatures_tool = __esm({
|
|
|
4900
5104
|
});
|
|
4901
5105
|
|
|
4902
5106
|
// core/context-tools/summary-tool.ts
|
|
4903
|
-
import
|
|
4904
|
-
import
|
|
5107
|
+
import fs15 from "node:fs/promises";
|
|
5108
|
+
import path15 from "node:path";
|
|
4905
5109
|
async function summarizeFile(filePath, projectPath = process.cwd()) {
|
|
4906
|
-
const absolutePath =
|
|
5110
|
+
const absolutePath = path15.isAbsolute(filePath) ? filePath : path15.join(projectPath, filePath);
|
|
4907
5111
|
let content;
|
|
4908
5112
|
try {
|
|
4909
|
-
content = await
|
|
5113
|
+
content = await fs15.readFile(absolutePath, "utf-8");
|
|
4910
5114
|
} catch (error) {
|
|
4911
5115
|
if (isNotFoundError(error)) {
|
|
4912
5116
|
return {
|
|
@@ -4919,7 +5123,7 @@ async function summarizeFile(filePath, projectPath = process.cwd()) {
|
|
|
4919
5123
|
}
|
|
4920
5124
|
throw error;
|
|
4921
5125
|
}
|
|
4922
|
-
const ext =
|
|
5126
|
+
const ext = path15.extname(filePath).toLowerCase();
|
|
4923
5127
|
const language = EXT_TO_LANG2[ext] || "unknown";
|
|
4924
5128
|
const signaturesResult = await extractSignatures(filePath, projectPath);
|
|
4925
5129
|
const importsResult = await analyzeImports(filePath, projectPath);
|
|
@@ -4941,13 +5145,13 @@ async function summarizeFile(filePath, projectPath = process.cwd()) {
|
|
|
4941
5145
|
};
|
|
4942
5146
|
}
|
|
4943
5147
|
async function summarizeDirectory(dirPath, projectPath = process.cwd(), options = {}) {
|
|
4944
|
-
const absolutePath =
|
|
5148
|
+
const absolutePath = path15.isAbsolute(dirPath) ? dirPath : path15.join(projectPath, dirPath);
|
|
4945
5149
|
const results = [];
|
|
4946
5150
|
async function processDir(dir) {
|
|
4947
|
-
const entries = await
|
|
5151
|
+
const entries = await fs15.readdir(dir, { withFileTypes: true });
|
|
4948
5152
|
for (const entry of entries) {
|
|
4949
|
-
const fullPath =
|
|
4950
|
-
const relativePath =
|
|
5153
|
+
const fullPath = path15.join(dir, entry.name);
|
|
5154
|
+
const relativePath = path15.relative(projectPath, fullPath);
|
|
4951
5155
|
if (entry.isDirectory()) {
|
|
4952
5156
|
if (entry.name === "node_modules" || entry.name === ".git" || entry.name.startsWith(".")) {
|
|
4953
5157
|
continue;
|
|
@@ -4956,7 +5160,7 @@ async function summarizeDirectory(dirPath, projectPath = process.cwd(), options
|
|
|
4956
5160
|
await processDir(fullPath);
|
|
4957
5161
|
}
|
|
4958
5162
|
} else if (entry.isFile()) {
|
|
4959
|
-
const ext =
|
|
5163
|
+
const ext = path15.extname(entry.name).toLowerCase();
|
|
4960
5164
|
if (EXT_TO_LANG2[ext]) {
|
|
4961
5165
|
const result = await summarizeFile(relativePath, projectPath);
|
|
4962
5166
|
results.push(result);
|
|
@@ -5006,7 +5210,7 @@ function extractFilePurpose(content, language) {
|
|
|
5006
5210
|
}
|
|
5007
5211
|
}
|
|
5008
5212
|
const fileName = content.split("\n")[0] || "";
|
|
5009
|
-
return `Module: ${
|
|
5213
|
+
return `Module: ${path15.basename(fileName, path15.extname(fileName))}`;
|
|
5010
5214
|
}
|
|
5011
5215
|
function extractDescriptionFromDocstring(docstring) {
|
|
5012
5216
|
return docstring.replace(/^\/\*\*\s*/, "").replace(/\*\/$/, "").replace(/^\/\/\/?\s*/, "").replace(/^#\s*/, "").replace(/^"""\s*/, "").replace(/"""\s*$/, "").trim().split("\n")[0].trim();
|
|
@@ -5206,11 +5410,11 @@ async function runSignaturesTool(args2, projectPath) {
|
|
|
5206
5410
|
}
|
|
5207
5411
|
};
|
|
5208
5412
|
}
|
|
5209
|
-
const
|
|
5210
|
-
const
|
|
5211
|
-
const fullPath =
|
|
5413
|
+
const fs52 = await import("node:fs/promises");
|
|
5414
|
+
const path61 = await import("node:path");
|
|
5415
|
+
const fullPath = path61.isAbsolute(filePath) ? filePath : path61.join(projectPath, filePath);
|
|
5212
5416
|
try {
|
|
5213
|
-
const stat = await
|
|
5417
|
+
const stat = await fs52.stat(fullPath);
|
|
5214
5418
|
if (stat.isDirectory()) {
|
|
5215
5419
|
const results = await extractDirectorySignatures(filePath, projectPath, {
|
|
5216
5420
|
recursive: args2.includes("--recursive") || args2.includes("-r")
|
|
@@ -5277,11 +5481,11 @@ async function runSummaryTool(args2, projectPath) {
|
|
|
5277
5481
|
}
|
|
5278
5482
|
};
|
|
5279
5483
|
}
|
|
5280
|
-
const
|
|
5281
|
-
const
|
|
5282
|
-
const fullPath =
|
|
5484
|
+
const fs52 = await import("node:fs/promises");
|
|
5485
|
+
const path61 = await import("node:path");
|
|
5486
|
+
const fullPath = path61.isAbsolute(targetPath) ? targetPath : path61.join(projectPath, targetPath);
|
|
5283
5487
|
try {
|
|
5284
|
-
const stat = await
|
|
5488
|
+
const stat = await fs52.stat(fullPath);
|
|
5285
5489
|
if (stat.isDirectory()) {
|
|
5286
5490
|
const results = await summarizeDirectory(targetPath, projectPath, {
|
|
5287
5491
|
recursive: args2.includes("--recursive") || args2.includes("-r")
|
|
@@ -5441,8 +5645,8 @@ __export(hooks_service_exports, {
|
|
|
5441
5645
|
default: () => hooks_service_default,
|
|
5442
5646
|
hooksService: () => hooksService
|
|
5443
5647
|
});
|
|
5444
|
-
import
|
|
5445
|
-
import
|
|
5648
|
+
import fs16 from "node:fs";
|
|
5649
|
+
import path16 from "node:path";
|
|
5446
5650
|
import chalk4 from "chalk";
|
|
5447
5651
|
function getPostCommitScript() {
|
|
5448
5652
|
return `#!/bin/sh
|
|
@@ -5505,13 +5709,13 @@ exit 0
|
|
|
5505
5709
|
}
|
|
5506
5710
|
function detectHookManagers(projectPath) {
|
|
5507
5711
|
const detected = [];
|
|
5508
|
-
if (
|
|
5712
|
+
if (fs16.existsSync(path16.join(projectPath, "lefthook.yml")) || fs16.existsSync(path16.join(projectPath, "lefthook.yaml"))) {
|
|
5509
5713
|
detected.push("lefthook");
|
|
5510
5714
|
}
|
|
5511
|
-
if (
|
|
5715
|
+
if (fs16.existsSync(path16.join(projectPath, ".husky")) || fs16.existsSync(path16.join(projectPath, ".husky", "_"))) {
|
|
5512
5716
|
detected.push("husky");
|
|
5513
5717
|
}
|
|
5514
|
-
if (
|
|
5718
|
+
if (fs16.existsSync(path16.join(projectPath, ".git"))) {
|
|
5515
5719
|
detected.push("direct");
|
|
5516
5720
|
}
|
|
5517
5721
|
return detected;
|
|
@@ -5522,9 +5726,9 @@ function selectStrategy(detected) {
|
|
|
5522
5726
|
return "direct";
|
|
5523
5727
|
}
|
|
5524
5728
|
function installLefthook(projectPath, hooks) {
|
|
5525
|
-
const configFile =
|
|
5526
|
-
const configPath =
|
|
5527
|
-
let content =
|
|
5729
|
+
const configFile = fs16.existsSync(path16.join(projectPath, "lefthook.yml")) ? "lefthook.yml" : "lefthook.yaml";
|
|
5730
|
+
const configPath = path16.join(projectPath, configFile);
|
|
5731
|
+
let content = fs16.readFileSync(configPath, "utf-8");
|
|
5528
5732
|
for (const hook of hooks) {
|
|
5529
5733
|
const sectionName = hook;
|
|
5530
5734
|
const commandName = `prjct-sync-${hook}`;
|
|
@@ -5553,87 +5757,87 @@ ${sectionName}:
|
|
|
5553
5757
|
${hookBlock}`;
|
|
5554
5758
|
}
|
|
5555
5759
|
}
|
|
5556
|
-
|
|
5760
|
+
fs16.writeFileSync(configPath, content, "utf-8");
|
|
5557
5761
|
return true;
|
|
5558
5762
|
}
|
|
5559
5763
|
function installHusky(projectPath, hooks) {
|
|
5560
|
-
const huskyDir =
|
|
5764
|
+
const huskyDir = path16.join(projectPath, ".husky");
|
|
5561
5765
|
for (const hook of hooks) {
|
|
5562
|
-
const hookPath =
|
|
5766
|
+
const hookPath = path16.join(huskyDir, hook);
|
|
5563
5767
|
const script = hook === "post-commit" ? getPostCommitScript() : getPostCheckoutScript();
|
|
5564
|
-
if (
|
|
5565
|
-
const existing =
|
|
5768
|
+
if (fs16.existsSync(hookPath)) {
|
|
5769
|
+
const existing = fs16.readFileSync(hookPath, "utf-8");
|
|
5566
5770
|
if (existing.includes("prjct sync")) {
|
|
5567
5771
|
continue;
|
|
5568
5772
|
}
|
|
5569
|
-
|
|
5773
|
+
fs16.appendFileSync(hookPath, "\n# prjct auto-sync\nprjct sync --quiet --yes &\n");
|
|
5570
5774
|
} else {
|
|
5571
|
-
|
|
5775
|
+
fs16.writeFileSync(hookPath, script, { mode: 493 });
|
|
5572
5776
|
}
|
|
5573
5777
|
}
|
|
5574
5778
|
return true;
|
|
5575
5779
|
}
|
|
5576
5780
|
function installDirect(projectPath, hooks) {
|
|
5577
|
-
const hooksDir =
|
|
5578
|
-
if (!
|
|
5579
|
-
|
|
5781
|
+
const hooksDir = path16.join(projectPath, ".git", "hooks");
|
|
5782
|
+
if (!fs16.existsSync(hooksDir)) {
|
|
5783
|
+
fs16.mkdirSync(hooksDir, { recursive: true });
|
|
5580
5784
|
}
|
|
5581
5785
|
for (const hook of hooks) {
|
|
5582
|
-
const hookPath =
|
|
5786
|
+
const hookPath = path16.join(hooksDir, hook);
|
|
5583
5787
|
const script = hook === "post-commit" ? getPostCommitScript() : getPostCheckoutScript();
|
|
5584
|
-
if (
|
|
5585
|
-
const existing =
|
|
5788
|
+
if (fs16.existsSync(hookPath)) {
|
|
5789
|
+
const existing = fs16.readFileSync(hookPath, "utf-8");
|
|
5586
5790
|
if (existing.includes("prjct sync")) {
|
|
5587
5791
|
continue;
|
|
5588
5792
|
}
|
|
5589
|
-
|
|
5793
|
+
fs16.appendFileSync(hookPath, `
|
|
5590
5794
|
# prjct auto-sync
|
|
5591
5795
|
${script.split("\n").slice(1).join("\n")}`);
|
|
5592
5796
|
} else {
|
|
5593
|
-
|
|
5797
|
+
fs16.writeFileSync(hookPath, script, { mode: 493 });
|
|
5594
5798
|
}
|
|
5595
5799
|
}
|
|
5596
5800
|
return true;
|
|
5597
5801
|
}
|
|
5598
5802
|
function uninstallLefthook(projectPath) {
|
|
5599
|
-
const configFile =
|
|
5600
|
-
const configPath =
|
|
5601
|
-
if (!
|
|
5602
|
-
let content =
|
|
5803
|
+
const configFile = fs16.existsSync(path16.join(projectPath, "lefthook.yml")) ? "lefthook.yml" : "lefthook.yaml";
|
|
5804
|
+
const configPath = path16.join(projectPath, configFile);
|
|
5805
|
+
if (!fs16.existsSync(configPath)) return false;
|
|
5806
|
+
let content = fs16.readFileSync(configPath, "utf-8");
|
|
5603
5807
|
content = content.replace(/\s*prjct-sync-[\w-]+:[\s\S]*?(?=\n\S|\n*$)/g, "");
|
|
5604
5808
|
content = content.replace(/^(post-commit|post-checkout):\s*commands:\s*$/gm, "");
|
|
5605
|
-
|
|
5809
|
+
fs16.writeFileSync(configPath, `${content.trimEnd()}
|
|
5606
5810
|
`, "utf-8");
|
|
5607
5811
|
return true;
|
|
5608
5812
|
}
|
|
5609
5813
|
function uninstallHusky(projectPath) {
|
|
5610
|
-
const huskyDir =
|
|
5814
|
+
const huskyDir = path16.join(projectPath, ".husky");
|
|
5611
5815
|
for (const hook of ["post-commit", "post-checkout"]) {
|
|
5612
|
-
const hookPath =
|
|
5613
|
-
if (!
|
|
5614
|
-
const content =
|
|
5816
|
+
const hookPath = path16.join(huskyDir, hook);
|
|
5817
|
+
if (!fs16.existsSync(hookPath)) continue;
|
|
5818
|
+
const content = fs16.readFileSync(hookPath, "utf-8");
|
|
5615
5819
|
if (!content.includes("prjct sync")) continue;
|
|
5616
5820
|
const cleaned = content.split("\n").filter((line) => !line.includes("prjct sync") && !line.includes("prjct auto-sync")).join("\n");
|
|
5617
5821
|
if (cleaned.trim() === "#!/bin/sh" || cleaned.trim() === "#!/usr/bin/env sh") {
|
|
5618
|
-
|
|
5822
|
+
fs16.unlinkSync(hookPath);
|
|
5619
5823
|
} else {
|
|
5620
|
-
|
|
5824
|
+
fs16.writeFileSync(hookPath, cleaned, { mode: 493 });
|
|
5621
5825
|
}
|
|
5622
5826
|
}
|
|
5623
5827
|
return true;
|
|
5624
5828
|
}
|
|
5625
5829
|
function uninstallDirect(projectPath) {
|
|
5626
|
-
const hooksDir =
|
|
5830
|
+
const hooksDir = path16.join(projectPath, ".git", "hooks");
|
|
5627
5831
|
for (const hook of ["post-commit", "post-checkout"]) {
|
|
5628
|
-
const hookPath =
|
|
5629
|
-
if (!
|
|
5630
|
-
const content =
|
|
5832
|
+
const hookPath = path16.join(hooksDir, hook);
|
|
5833
|
+
if (!fs16.existsSync(hookPath)) continue;
|
|
5834
|
+
const content = fs16.readFileSync(hookPath, "utf-8");
|
|
5631
5835
|
if (!content.includes("prjct sync")) continue;
|
|
5632
5836
|
if (content.includes("Installed by: prjct hooks install")) {
|
|
5633
|
-
|
|
5837
|
+
fs16.unlinkSync(hookPath);
|
|
5634
5838
|
} else {
|
|
5635
5839
|
const cleaned = content.split("\n").filter((line) => !line.includes("prjct sync") && !line.includes("prjct auto-sync")).join("\n");
|
|
5636
|
-
|
|
5840
|
+
fs16.writeFileSync(hookPath, cleaned, { mode: 493 });
|
|
5637
5841
|
}
|
|
5638
5842
|
}
|
|
5639
5843
|
return true;
|
|
@@ -5852,24 +6056,24 @@ var init_hooks_service = __esm({
|
|
|
5852
6056
|
// ==========================================================================
|
|
5853
6057
|
isHookInstalled(projectPath, hook, strategy) {
|
|
5854
6058
|
if (strategy === "lefthook") {
|
|
5855
|
-
const configFile =
|
|
5856
|
-
const configPath =
|
|
5857
|
-
if (!
|
|
5858
|
-
const content =
|
|
6059
|
+
const configFile = fs16.existsSync(path16.join(projectPath, "lefthook.yml")) ? "lefthook.yml" : "lefthook.yaml";
|
|
6060
|
+
const configPath = path16.join(projectPath, configFile);
|
|
6061
|
+
if (!fs16.existsSync(configPath)) return false;
|
|
6062
|
+
const content = fs16.readFileSync(configPath, "utf-8");
|
|
5859
6063
|
return content.includes(`prjct-sync-${hook}`);
|
|
5860
6064
|
}
|
|
5861
6065
|
if (strategy === "husky") {
|
|
5862
|
-
const hookPath2 =
|
|
5863
|
-
if (!
|
|
5864
|
-
return
|
|
6066
|
+
const hookPath2 = path16.join(projectPath, ".husky", hook);
|
|
6067
|
+
if (!fs16.existsSync(hookPath2)) return false;
|
|
6068
|
+
return fs16.readFileSync(hookPath2, "utf-8").includes("prjct sync");
|
|
5865
6069
|
}
|
|
5866
|
-
const hookPath =
|
|
5867
|
-
if (!
|
|
5868
|
-
return
|
|
6070
|
+
const hookPath = path16.join(projectPath, ".git", "hooks", hook);
|
|
6071
|
+
if (!fs16.existsSync(hookPath)) return false;
|
|
6072
|
+
return fs16.readFileSync(hookPath, "utf-8").includes("prjct sync");
|
|
5869
6073
|
}
|
|
5870
6074
|
getHookPath(projectPath, hook, strategy) {
|
|
5871
6075
|
if (strategy === "lefthook") {
|
|
5872
|
-
return
|
|
6076
|
+
return fs16.existsSync(path16.join(projectPath, "lefthook.yml")) ? "lefthook.yml" : "lefthook.yaml";
|
|
5873
6077
|
}
|
|
5874
6078
|
if (strategy === "husky") {
|
|
5875
6079
|
return `.husky/${hook}`;
|
|
@@ -5880,15 +6084,15 @@ var init_hooks_service = __esm({
|
|
|
5880
6084
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
5881
6085
|
if (!projectId) return null;
|
|
5882
6086
|
try {
|
|
5883
|
-
const projectJsonPath =
|
|
6087
|
+
const projectJsonPath = path16.join(
|
|
5884
6088
|
process.env.HOME || "",
|
|
5885
6089
|
".prjct-cli",
|
|
5886
6090
|
"projects",
|
|
5887
6091
|
projectId,
|
|
5888
6092
|
"project.json"
|
|
5889
6093
|
);
|
|
5890
|
-
if (!
|
|
5891
|
-
const project = JSON.parse(
|
|
6094
|
+
if (!fs16.existsSync(projectJsonPath)) return null;
|
|
6095
|
+
const project = JSON.parse(fs16.readFileSync(projectJsonPath, "utf-8"));
|
|
5892
6096
|
return project.hooks || null;
|
|
5893
6097
|
} catch {
|
|
5894
6098
|
return null;
|
|
@@ -5898,17 +6102,17 @@ var init_hooks_service = __esm({
|
|
|
5898
6102
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
5899
6103
|
if (!projectId) return;
|
|
5900
6104
|
try {
|
|
5901
|
-
const projectJsonPath =
|
|
6105
|
+
const projectJsonPath = path16.join(
|
|
5902
6106
|
process.env.HOME || "",
|
|
5903
6107
|
".prjct-cli",
|
|
5904
6108
|
"projects",
|
|
5905
6109
|
projectId,
|
|
5906
6110
|
"project.json"
|
|
5907
6111
|
);
|
|
5908
|
-
if (!
|
|
5909
|
-
const project = JSON.parse(
|
|
6112
|
+
if (!fs16.existsSync(projectJsonPath)) return;
|
|
6113
|
+
const project = JSON.parse(fs16.readFileSync(projectJsonPath, "utf-8"));
|
|
5910
6114
|
project.hooks = config;
|
|
5911
|
-
|
|
6115
|
+
fs16.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
5912
6116
|
} catch {
|
|
5913
6117
|
}
|
|
5914
6118
|
}
|
|
@@ -5925,8 +6129,8 @@ __export(doctor_service_exports, {
|
|
|
5925
6129
|
doctorService: () => doctorService
|
|
5926
6130
|
});
|
|
5927
6131
|
import { execSync as execSync2 } from "node:child_process";
|
|
5928
|
-
import
|
|
5929
|
-
import
|
|
6132
|
+
import fs17 from "node:fs/promises";
|
|
6133
|
+
import path17 from "node:path";
|
|
5930
6134
|
import chalk5 from "chalk";
|
|
5931
6135
|
var DoctorService, doctorService;
|
|
5932
6136
|
var init_doctor_service = __esm({
|
|
@@ -6039,9 +6243,9 @@ var init_doctor_service = __esm({
|
|
|
6039
6243
|
return checks;
|
|
6040
6244
|
}
|
|
6041
6245
|
async checkPrjctConfig() {
|
|
6042
|
-
const configPath =
|
|
6246
|
+
const configPath = path17.join(this.projectPath, ".prjct", "prjct.config.json");
|
|
6043
6247
|
try {
|
|
6044
|
-
await
|
|
6248
|
+
await fs17.access(configPath);
|
|
6045
6249
|
return {
|
|
6046
6250
|
name: "prjct config",
|
|
6047
6251
|
status: "ok",
|
|
@@ -6063,9 +6267,9 @@ var init_doctor_service = __esm({
|
|
|
6063
6267
|
message: "project not initialized"
|
|
6064
6268
|
};
|
|
6065
6269
|
}
|
|
6066
|
-
const claudePath =
|
|
6270
|
+
const claudePath = path17.join(this.globalPath, "context", "CLAUDE.md");
|
|
6067
6271
|
try {
|
|
6068
|
-
const stat = await
|
|
6272
|
+
const stat = await fs17.stat(claudePath);
|
|
6069
6273
|
const ageMs = Date.now() - stat.mtimeMs;
|
|
6070
6274
|
const ageHours = Math.floor(ageMs / (1e3 * 60 * 60));
|
|
6071
6275
|
const ageDays = Math.floor(ageHours / 24);
|
|
@@ -6137,9 +6341,9 @@ var init_doctor_service = __esm({
|
|
|
6137
6341
|
message: "project not initialized"
|
|
6138
6342
|
};
|
|
6139
6343
|
}
|
|
6140
|
-
const statePath =
|
|
6344
|
+
const statePath = path17.join(this.globalPath, "storage", "state.json");
|
|
6141
6345
|
try {
|
|
6142
|
-
const content = await
|
|
6346
|
+
const content = await fs17.readFile(statePath, "utf-8");
|
|
6143
6347
|
const state = JSON.parse(content);
|
|
6144
6348
|
if (state.currentTask) {
|
|
6145
6349
|
return {
|
|
@@ -6236,13 +6440,13 @@ var init_doctor_service = __esm({
|
|
|
6236
6440
|
});
|
|
6237
6441
|
|
|
6238
6442
|
// core/infrastructure/command-installer.ts
|
|
6239
|
-
import
|
|
6443
|
+
import fs18 from "node:fs/promises";
|
|
6240
6444
|
import os5 from "node:os";
|
|
6241
|
-
import
|
|
6445
|
+
import path18 from "node:path";
|
|
6242
6446
|
async function loadModuleConfig() {
|
|
6243
6447
|
try {
|
|
6244
|
-
const configPath =
|
|
6245
|
-
const content = await
|
|
6448
|
+
const configPath = path18.join(getPackageRoot(), "templates/global/modules/module-config.json");
|
|
6449
|
+
const content = await fs18.readFile(configPath, "utf-8");
|
|
6246
6450
|
return JSON.parse(content);
|
|
6247
6451
|
} catch {
|
|
6248
6452
|
return null;
|
|
@@ -6250,18 +6454,18 @@ async function loadModuleConfig() {
|
|
|
6250
6454
|
}
|
|
6251
6455
|
async function composeGlobalTemplate(profile) {
|
|
6252
6456
|
const config = await loadModuleConfig();
|
|
6253
|
-
const modulesDir =
|
|
6457
|
+
const modulesDir = path18.join(getPackageRoot(), "templates/global/modules");
|
|
6254
6458
|
if (!config) {
|
|
6255
|
-
const legacyPath =
|
|
6256
|
-
return
|
|
6459
|
+
const legacyPath = path18.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
6460
|
+
return fs18.readFile(legacyPath, "utf-8");
|
|
6257
6461
|
}
|
|
6258
6462
|
const profileName = profile || config.default;
|
|
6259
6463
|
const selectedProfile = config.profiles[profileName];
|
|
6260
6464
|
if (!selectedProfile) {
|
|
6261
6465
|
const defaultProfile = config.profiles[config.default];
|
|
6262
6466
|
if (!defaultProfile) {
|
|
6263
|
-
const legacyPath =
|
|
6264
|
-
return
|
|
6467
|
+
const legacyPath = path18.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
6468
|
+
return fs18.readFile(legacyPath, "utf-8");
|
|
6265
6469
|
}
|
|
6266
6470
|
}
|
|
6267
6471
|
const modules = (selectedProfile || config.profiles[config.default]).modules;
|
|
@@ -6269,8 +6473,8 @@ async function composeGlobalTemplate(profile) {
|
|
|
6269
6473
|
parts.push("<!-- prjct:start - DO NOT REMOVE THIS MARKER -->");
|
|
6270
6474
|
for (const moduleName of modules) {
|
|
6271
6475
|
try {
|
|
6272
|
-
const modulePath =
|
|
6273
|
-
const content = await
|
|
6476
|
+
const modulePath = path18.join(modulesDir, moduleName);
|
|
6477
|
+
const content = await fs18.readFile(modulePath, "utf-8");
|
|
6274
6478
|
parts.push("");
|
|
6275
6479
|
parts.push(content);
|
|
6276
6480
|
} catch {
|
|
@@ -6284,16 +6488,16 @@ async function composeGlobalTemplate(profile) {
|
|
|
6284
6488
|
}
|
|
6285
6489
|
async function installDocs() {
|
|
6286
6490
|
try {
|
|
6287
|
-
const docsDir =
|
|
6288
|
-
const templateDocsDir =
|
|
6289
|
-
await
|
|
6290
|
-
const docFiles = await
|
|
6491
|
+
const docsDir = path18.join(os5.homedir(), ".prjct-cli", "docs");
|
|
6492
|
+
const templateDocsDir = path18.join(getPackageRoot(), "templates/global/docs");
|
|
6493
|
+
await fs18.mkdir(docsDir, { recursive: true });
|
|
6494
|
+
const docFiles = await fs18.readdir(templateDocsDir);
|
|
6291
6495
|
for (const file of docFiles) {
|
|
6292
6496
|
if (file.endsWith(".md")) {
|
|
6293
|
-
const srcPath =
|
|
6294
|
-
const destPath =
|
|
6295
|
-
const content = await
|
|
6296
|
-
await
|
|
6497
|
+
const srcPath = path18.join(templateDocsDir, file);
|
|
6498
|
+
const destPath = path18.join(docsDir, file);
|
|
6499
|
+
const content = await fs18.readFile(srcPath, "utf-8");
|
|
6500
|
+
await fs18.writeFile(destPath, content, "utf-8");
|
|
6297
6501
|
}
|
|
6298
6502
|
}
|
|
6299
6503
|
return { success: true };
|
|
@@ -6314,9 +6518,9 @@ async function installGlobalConfig2() {
|
|
|
6314
6518
|
};
|
|
6315
6519
|
}
|
|
6316
6520
|
try {
|
|
6317
|
-
await
|
|
6318
|
-
const globalConfigPath =
|
|
6319
|
-
const templatePath =
|
|
6521
|
+
await fs18.mkdir(activeProvider.configDir, { recursive: true });
|
|
6522
|
+
const globalConfigPath = path18.join(activeProvider.configDir, activeProvider.contextFile);
|
|
6523
|
+
const templatePath = path18.join(
|
|
6320
6524
|
getPackageRoot(),
|
|
6321
6525
|
"templates",
|
|
6322
6526
|
"global",
|
|
@@ -6324,18 +6528,18 @@ async function installGlobalConfig2() {
|
|
|
6324
6528
|
);
|
|
6325
6529
|
let templateContent = "";
|
|
6326
6530
|
try {
|
|
6327
|
-
templateContent = await
|
|
6531
|
+
templateContent = await fs18.readFile(templatePath, "utf-8");
|
|
6328
6532
|
} catch (_error) {
|
|
6329
6533
|
if (providerName === "claude") {
|
|
6330
6534
|
try {
|
|
6331
6535
|
templateContent = await composeGlobalTemplate("standard");
|
|
6332
6536
|
} catch {
|
|
6333
|
-
const fallbackTemplatePath =
|
|
6334
|
-
templateContent = await
|
|
6537
|
+
const fallbackTemplatePath = path18.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
6538
|
+
templateContent = await fs18.readFile(fallbackTemplatePath, "utf-8");
|
|
6335
6539
|
}
|
|
6336
6540
|
} else {
|
|
6337
|
-
const fallbackTemplatePath =
|
|
6338
|
-
templateContent = await
|
|
6541
|
+
const fallbackTemplatePath = path18.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
6542
|
+
templateContent = await fs18.readFile(fallbackTemplatePath, "utf-8");
|
|
6339
6543
|
if (providerName === "gemini") {
|
|
6340
6544
|
templateContent = templateContent.replace(/Claude/g, "Gemini");
|
|
6341
6545
|
}
|
|
@@ -6344,7 +6548,7 @@ async function installGlobalConfig2() {
|
|
|
6344
6548
|
let existingContent = "";
|
|
6345
6549
|
let fileExists2 = false;
|
|
6346
6550
|
try {
|
|
6347
|
-
existingContent = await
|
|
6551
|
+
existingContent = await fs18.readFile(globalConfigPath, "utf-8");
|
|
6348
6552
|
fileExists2 = true;
|
|
6349
6553
|
} catch (error) {
|
|
6350
6554
|
if (isNotFoundError(error)) {
|
|
@@ -6354,7 +6558,7 @@ async function installGlobalConfig2() {
|
|
|
6354
6558
|
}
|
|
6355
6559
|
}
|
|
6356
6560
|
if (!fileExists2) {
|
|
6357
|
-
await
|
|
6561
|
+
await fs18.writeFile(globalConfigPath, templateContent, "utf-8");
|
|
6358
6562
|
return {
|
|
6359
6563
|
success: true,
|
|
6360
6564
|
action: "created",
|
|
@@ -6368,7 +6572,7 @@ async function installGlobalConfig2() {
|
|
|
6368
6572
|
const updatedContent = `${existingContent}
|
|
6369
6573
|
|
|
6370
6574
|
${templateContent}`;
|
|
6371
|
-
await
|
|
6575
|
+
await fs18.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
6372
6576
|
return {
|
|
6373
6577
|
success: true,
|
|
6374
6578
|
action: "appended",
|
|
@@ -6384,7 +6588,7 @@ ${templateContent}`;
|
|
|
6384
6588
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
6385
6589
|
);
|
|
6386
6590
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
6387
|
-
await
|
|
6591
|
+
await fs18.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
6388
6592
|
return {
|
|
6389
6593
|
success: true,
|
|
6390
6594
|
action: "updated",
|
|
@@ -6404,14 +6608,14 @@ function getProviderPaths() {
|
|
|
6404
6608
|
const homeDir = os5.homedir();
|
|
6405
6609
|
return {
|
|
6406
6610
|
claude: {
|
|
6407
|
-
commands:
|
|
6408
|
-
config:
|
|
6409
|
-
router:
|
|
6611
|
+
commands: path18.join(homeDir, ".claude", "commands", "p"),
|
|
6612
|
+
config: path18.join(homeDir, ".claude"),
|
|
6613
|
+
router: path18.join(homeDir, ".claude", "commands", "p.md")
|
|
6410
6614
|
},
|
|
6411
6615
|
gemini: {
|
|
6412
|
-
commands:
|
|
6413
|
-
config:
|
|
6414
|
-
router:
|
|
6616
|
+
commands: path18.join(homeDir, ".gemini", "commands"),
|
|
6617
|
+
config: path18.join(homeDir, ".gemini"),
|
|
6618
|
+
router: path18.join(homeDir, ".gemini", "commands", "p.toml")
|
|
6415
6619
|
}
|
|
6416
6620
|
};
|
|
6417
6621
|
}
|
|
@@ -6438,19 +6642,19 @@ var init_command_installer = __esm({
|
|
|
6438
6642
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
6439
6643
|
const activeProvider = aiProvider.getActiveProvider();
|
|
6440
6644
|
if (activeProvider.name === "gemini") {
|
|
6441
|
-
this.claudeCommandsPath =
|
|
6645
|
+
this.claudeCommandsPath = path18.join(activeProvider.configDir, "commands");
|
|
6442
6646
|
} else {
|
|
6443
|
-
this.claudeCommandsPath =
|
|
6647
|
+
this.claudeCommandsPath = path18.join(activeProvider.configDir, "commands", "p");
|
|
6444
6648
|
}
|
|
6445
6649
|
this.claudeConfigPath = activeProvider.configDir;
|
|
6446
|
-
this.templatesDir =
|
|
6650
|
+
this.templatesDir = path18.join(getPackageRoot(), "templates", "commands");
|
|
6447
6651
|
}
|
|
6448
6652
|
/**
|
|
6449
6653
|
* Detect if active provider is installed
|
|
6450
6654
|
*/
|
|
6451
6655
|
async detectActiveProvider() {
|
|
6452
6656
|
try {
|
|
6453
|
-
await
|
|
6657
|
+
await fs18.access(this.claudeConfigPath);
|
|
6454
6658
|
return true;
|
|
6455
6659
|
} catch (error) {
|
|
6456
6660
|
if (isNotFoundError(error)) {
|
|
@@ -6470,7 +6674,7 @@ var init_command_installer = __esm({
|
|
|
6470
6674
|
*/
|
|
6471
6675
|
async getCommandFiles() {
|
|
6472
6676
|
try {
|
|
6473
|
-
const files = await
|
|
6677
|
+
const files = await fs18.readdir(this.templatesDir);
|
|
6474
6678
|
return files.filter((f) => f.endsWith(".md"));
|
|
6475
6679
|
} catch (_error) {
|
|
6476
6680
|
return [
|
|
@@ -6511,16 +6715,16 @@ var init_command_installer = __esm({
|
|
|
6511
6715
|
}
|
|
6512
6716
|
try {
|
|
6513
6717
|
await this.installRouter();
|
|
6514
|
-
await
|
|
6718
|
+
await fs18.mkdir(this.claudeCommandsPath, { recursive: true });
|
|
6515
6719
|
const commandFiles = await this.getCommandFiles();
|
|
6516
6720
|
const installed = [];
|
|
6517
6721
|
const errors = [];
|
|
6518
6722
|
for (const file of commandFiles) {
|
|
6519
6723
|
try {
|
|
6520
|
-
const sourcePath =
|
|
6521
|
-
const destPath =
|
|
6522
|
-
const content = await
|
|
6523
|
-
await
|
|
6724
|
+
const sourcePath = path18.join(this.templatesDir, file);
|
|
6725
|
+
const destPath = path18.join(this.claudeCommandsPath, file);
|
|
6726
|
+
const content = await fs18.readFile(sourcePath, "utf-8");
|
|
6727
|
+
await fs18.writeFile(destPath, content, "utf-8");
|
|
6524
6728
|
installed.push(file.replace(".md", ""));
|
|
6525
6729
|
} catch (error) {
|
|
6526
6730
|
errors.push({ file, error: error.message });
|
|
@@ -6549,8 +6753,8 @@ var init_command_installer = __esm({
|
|
|
6549
6753
|
const errors = [];
|
|
6550
6754
|
for (const file of commandFiles) {
|
|
6551
6755
|
try {
|
|
6552
|
-
const filePath =
|
|
6553
|
-
await
|
|
6756
|
+
const filePath = path18.join(this.claudeCommandsPath, file);
|
|
6757
|
+
await fs18.unlink(filePath);
|
|
6554
6758
|
uninstalled.push(file.replace(".md", ""));
|
|
6555
6759
|
} catch (error) {
|
|
6556
6760
|
if (error.code !== "ENOENT") {
|
|
@@ -6559,7 +6763,7 @@ var init_command_installer = __esm({
|
|
|
6559
6763
|
}
|
|
6560
6764
|
}
|
|
6561
6765
|
try {
|
|
6562
|
-
await
|
|
6766
|
+
await fs18.rmdir(this.claudeCommandsPath);
|
|
6563
6767
|
} catch (_error) {
|
|
6564
6768
|
}
|
|
6565
6769
|
return {
|
|
@@ -6586,8 +6790,8 @@ var init_command_installer = __esm({
|
|
|
6586
6790
|
};
|
|
6587
6791
|
}
|
|
6588
6792
|
try {
|
|
6589
|
-
await
|
|
6590
|
-
const files = await
|
|
6793
|
+
await fs18.access(this.claudeCommandsPath);
|
|
6794
|
+
const files = await fs18.readdir(this.claudeCommandsPath);
|
|
6591
6795
|
const installedCommands = files.filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
6592
6796
|
return {
|
|
6593
6797
|
installed: installedCommands.length > 0,
|
|
@@ -6634,8 +6838,8 @@ var init_command_installer = __esm({
|
|
|
6634
6838
|
*/
|
|
6635
6839
|
async verifyTemplate(commandName) {
|
|
6636
6840
|
try {
|
|
6637
|
-
const templatePath =
|
|
6638
|
-
await
|
|
6841
|
+
const templatePath = path18.join(this.templatesDir, `${commandName}.md`);
|
|
6842
|
+
await fs18.access(templatePath);
|
|
6639
6843
|
return true;
|
|
6640
6844
|
} catch (error) {
|
|
6641
6845
|
if (isNotFoundError(error)) {
|
|
@@ -6653,11 +6857,11 @@ var init_command_installer = __esm({
|
|
|
6653
6857
|
const activeProvider = aiProvider.getActiveProvider();
|
|
6654
6858
|
const routerFile = activeProvider.name === "gemini" ? "p.toml" : "p.md";
|
|
6655
6859
|
try {
|
|
6656
|
-
const routerSource =
|
|
6657
|
-
const routerDest =
|
|
6658
|
-
await
|
|
6659
|
-
const content = await
|
|
6660
|
-
await
|
|
6860
|
+
const routerSource = path18.join(this.templatesDir, routerFile);
|
|
6861
|
+
const routerDest = path18.join(activeProvider.configDir, "commands", routerFile);
|
|
6862
|
+
await fs18.mkdir(path18.dirname(routerDest), { recursive: true });
|
|
6863
|
+
const content = await fs18.readFile(routerSource, "utf-8");
|
|
6864
|
+
await fs18.writeFile(routerDest, content, "utf-8");
|
|
6661
6865
|
return true;
|
|
6662
6866
|
} catch (error) {
|
|
6663
6867
|
if (isNotFoundError(error)) {
|
|
@@ -6673,14 +6877,14 @@ var init_command_installer = __esm({
|
|
|
6673
6877
|
async removeLegacyCommands() {
|
|
6674
6878
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
6675
6879
|
const activeProvider = aiProvider.getActiveProvider();
|
|
6676
|
-
const commandsRoot =
|
|
6880
|
+
const commandsRoot = path18.join(activeProvider.configDir, "commands");
|
|
6677
6881
|
let removed = 0;
|
|
6678
6882
|
try {
|
|
6679
|
-
const files = await
|
|
6883
|
+
const files = await fs18.readdir(commandsRoot);
|
|
6680
6884
|
const legacyFiles = files.filter((f) => f.startsWith("p.") && f.endsWith(".md"));
|
|
6681
6885
|
for (const file of legacyFiles) {
|
|
6682
6886
|
try {
|
|
6683
|
-
await
|
|
6887
|
+
await fs18.unlink(path18.join(commandsRoot, file));
|
|
6684
6888
|
removed++;
|
|
6685
6889
|
} catch {
|
|
6686
6890
|
}
|
|
@@ -6705,11 +6909,11 @@ var init_command_installer = __esm({
|
|
|
6705
6909
|
}
|
|
6706
6910
|
try {
|
|
6707
6911
|
await this.installRouter();
|
|
6708
|
-
await
|
|
6912
|
+
await fs18.mkdir(this.claudeCommandsPath, { recursive: true });
|
|
6709
6913
|
const templateFiles = await this.getCommandFiles();
|
|
6710
6914
|
let installedFiles = [];
|
|
6711
6915
|
try {
|
|
6712
|
-
installedFiles = await
|
|
6916
|
+
installedFiles = await fs18.readdir(this.claudeCommandsPath);
|
|
6713
6917
|
installedFiles = installedFiles.filter((f) => f.endsWith(".md"));
|
|
6714
6918
|
} catch (error) {
|
|
6715
6919
|
if (isNotFoundError(error)) {
|
|
@@ -6727,11 +6931,11 @@ var init_command_installer = __esm({
|
|
|
6727
6931
|
};
|
|
6728
6932
|
for (const file of templateFiles) {
|
|
6729
6933
|
try {
|
|
6730
|
-
const sourcePath =
|
|
6731
|
-
const destPath =
|
|
6934
|
+
const sourcePath = path18.join(this.templatesDir, file);
|
|
6935
|
+
const destPath = path18.join(this.claudeCommandsPath, file);
|
|
6732
6936
|
const exists = installedFiles.includes(file);
|
|
6733
|
-
const content = await
|
|
6734
|
-
await
|
|
6937
|
+
const content = await fs18.readFile(sourcePath, "utf-8");
|
|
6938
|
+
await fs18.writeFile(destPath, content, "utf-8");
|
|
6735
6939
|
if (!exists) {
|
|
6736
6940
|
results.added++;
|
|
6737
6941
|
} else {
|
|
@@ -7114,7 +7318,7 @@ var init_chain_of_thought = __esm({
|
|
|
7114
7318
|
});
|
|
7115
7319
|
|
|
7116
7320
|
// core/agentic/context-builder.ts
|
|
7117
|
-
import
|
|
7321
|
+
import fs19 from "node:fs/promises";
|
|
7118
7322
|
var ContextBuilder, contextBuilder, context_builder_default;
|
|
7119
7323
|
var init_context_builder = __esm({
|
|
7120
7324
|
"core/agentic/context-builder.ts"() {
|
|
@@ -7193,7 +7397,7 @@ var init_context_builder = __esm({
|
|
|
7193
7397
|
for (const [, filePath] of filteredEntries) {
|
|
7194
7398
|
if (this._cache.has(filePath)) {
|
|
7195
7399
|
try {
|
|
7196
|
-
const stat = await
|
|
7400
|
+
const stat = await fs19.stat(filePath);
|
|
7197
7401
|
const cachedMtime = this._mtimes.get(filePath);
|
|
7198
7402
|
if (!cachedMtime || stat.mtimeMs > cachedMtime) {
|
|
7199
7403
|
this._cache.delete(filePath);
|
|
@@ -7221,8 +7425,8 @@ var init_context_builder = __esm({
|
|
|
7221
7425
|
const readPromises = uncachedEntries.map(async ([key, filePath]) => {
|
|
7222
7426
|
try {
|
|
7223
7427
|
const [content, stat] = await Promise.all([
|
|
7224
|
-
|
|
7225
|
-
|
|
7428
|
+
fs19.readFile(filePath, "utf-8"),
|
|
7429
|
+
fs19.stat(filePath)
|
|
7226
7430
|
]);
|
|
7227
7431
|
return { key, filePath, content, mtime: stat.mtimeMs };
|
|
7228
7432
|
} catch (error) {
|
|
@@ -7296,7 +7500,7 @@ var init_context_builder = __esm({
|
|
|
7296
7500
|
if (uncachedPaths.length > 0) {
|
|
7297
7501
|
const readPromises = uncachedPaths.map(async (filePath) => {
|
|
7298
7502
|
try {
|
|
7299
|
-
const content = await
|
|
7503
|
+
const content = await fs19.readFile(filePath, "utf-8");
|
|
7300
7504
|
return { filePath, content };
|
|
7301
7505
|
} catch (error) {
|
|
7302
7506
|
if (isNotFoundError(error)) {
|
|
@@ -7330,7 +7534,7 @@ var init_context_builder = __esm({
|
|
|
7330
7534
|
*/
|
|
7331
7535
|
async fileExists(filePath) {
|
|
7332
7536
|
try {
|
|
7333
|
-
await
|
|
7537
|
+
await fs19.access(filePath);
|
|
7334
7538
|
return true;
|
|
7335
7539
|
} catch (error) {
|
|
7336
7540
|
if (isNotFoundError(error)) {
|
|
@@ -7357,9 +7561,9 @@ var init_context_builder = __esm({
|
|
|
7357
7561
|
|
|
7358
7562
|
// core/agentic/ground-truth.ts
|
|
7359
7563
|
import { exec as exec5 } from "node:child_process";
|
|
7360
|
-
import
|
|
7564
|
+
import fs20 from "node:fs/promises";
|
|
7361
7565
|
import os6 from "node:os";
|
|
7362
|
-
import
|
|
7566
|
+
import path19 from "node:path";
|
|
7363
7567
|
import { promisify as promisify5 } from "node:util";
|
|
7364
7568
|
function formatDuration2(ms) {
|
|
7365
7569
|
const hours = Math.floor(ms / (1e3 * 60 * 60));
|
|
@@ -7396,7 +7600,7 @@ async function verifyDone(context2) {
|
|
|
7396
7600
|
const actual = {};
|
|
7397
7601
|
const nowPath = context2.paths.now;
|
|
7398
7602
|
try {
|
|
7399
|
-
const nowContent = await
|
|
7603
|
+
const nowContent = await fs20.readFile(nowPath, "utf-8");
|
|
7400
7604
|
actual.nowExists = true;
|
|
7401
7605
|
actual.nowContent = nowContent.trim();
|
|
7402
7606
|
actual.nowLength = nowContent.length;
|
|
@@ -7424,7 +7628,7 @@ async function verifyDone(context2) {
|
|
|
7424
7628
|
}
|
|
7425
7629
|
const nextPath = context2.paths.next;
|
|
7426
7630
|
try {
|
|
7427
|
-
const nextContent = await
|
|
7631
|
+
const nextContent = await fs20.readFile(nextPath, "utf-8");
|
|
7428
7632
|
actual.nextExists = true;
|
|
7429
7633
|
const tasks = nextContent.match(/- \[ \]/g) || [];
|
|
7430
7634
|
actual.pendingTasks = tasks.length;
|
|
@@ -7438,7 +7642,7 @@ async function verifyDone(context2) {
|
|
|
7438
7642
|
}
|
|
7439
7643
|
const metricsPath = context2.paths.metrics;
|
|
7440
7644
|
try {
|
|
7441
|
-
await
|
|
7645
|
+
await fs20.access(path19.dirname(metricsPath), fs20.constants.W_OK);
|
|
7442
7646
|
actual.metricsWritable = true;
|
|
7443
7647
|
} catch (error) {
|
|
7444
7648
|
if (isNotFoundError(error)) {
|
|
@@ -7472,9 +7676,9 @@ async function verifyShip(context2) {
|
|
|
7472
7676
|
} catch (_error) {
|
|
7473
7677
|
actual.gitAvailable = false;
|
|
7474
7678
|
}
|
|
7475
|
-
const pkgPath =
|
|
7679
|
+
const pkgPath = path19.join(context2.projectPath, "package.json");
|
|
7476
7680
|
try {
|
|
7477
|
-
const pkgContent = await
|
|
7681
|
+
const pkgContent = await fs20.readFile(pkgPath, "utf-8");
|
|
7478
7682
|
const pkg = JSON.parse(pkgContent);
|
|
7479
7683
|
actual.currentVersion = pkg.version;
|
|
7480
7684
|
actual.hasPackageJson = true;
|
|
@@ -7490,7 +7694,7 @@ async function verifyShip(context2) {
|
|
|
7490
7694
|
}
|
|
7491
7695
|
const shippedPath = context2.paths.shipped;
|
|
7492
7696
|
try {
|
|
7493
|
-
const shippedContent = await
|
|
7697
|
+
const shippedContent = await fs20.readFile(shippedPath, "utf-8");
|
|
7494
7698
|
actual.shippedExists = true;
|
|
7495
7699
|
const featureName = context2.params.feature || context2.params.description;
|
|
7496
7700
|
if (featureName) {
|
|
@@ -7510,7 +7714,7 @@ async function verifyShip(context2) {
|
|
|
7510
7714
|
}
|
|
7511
7715
|
if (actual.hasPackageJson) {
|
|
7512
7716
|
try {
|
|
7513
|
-
const pkgContent = await
|
|
7717
|
+
const pkgContent = await fs20.readFile(pkgPath, "utf-8");
|
|
7514
7718
|
const pkg = JSON.parse(pkgContent);
|
|
7515
7719
|
actual.hasTestScript = !!pkg.scripts?.test;
|
|
7516
7720
|
} catch (error) {
|
|
@@ -7534,7 +7738,7 @@ async function verifyFeature(context2) {
|
|
|
7534
7738
|
const actual = {};
|
|
7535
7739
|
const nextPath = context2.paths.next;
|
|
7536
7740
|
try {
|
|
7537
|
-
const nextContent = await
|
|
7741
|
+
const nextContent = await fs20.readFile(nextPath, "utf-8");
|
|
7538
7742
|
actual.nextExists = true;
|
|
7539
7743
|
const tasks = nextContent.match(/- \[[ x]\]/g) || [];
|
|
7540
7744
|
actual.taskCount = tasks.length;
|
|
@@ -7553,7 +7757,7 @@ async function verifyFeature(context2) {
|
|
|
7553
7757
|
}
|
|
7554
7758
|
const roadmapPath = context2.paths.roadmap;
|
|
7555
7759
|
try {
|
|
7556
|
-
const roadmapContent = await
|
|
7760
|
+
const roadmapContent = await fs20.readFile(roadmapPath, "utf-8");
|
|
7557
7761
|
actual.roadmapExists = true;
|
|
7558
7762
|
const featureName = context2.params.description || context2.params.feature;
|
|
7559
7763
|
if (featureName) {
|
|
@@ -7572,7 +7776,7 @@ async function verifyFeature(context2) {
|
|
|
7572
7776
|
}
|
|
7573
7777
|
const nowPath = context2.paths.now;
|
|
7574
7778
|
try {
|
|
7575
|
-
const nowContent = await
|
|
7779
|
+
const nowContent = await fs20.readFile(nowPath, "utf-8");
|
|
7576
7780
|
actual.hasActiveTask = nowContent.trim().length > 0 && !nowContent.includes("No current task");
|
|
7577
7781
|
if (actual.hasActiveTask) {
|
|
7578
7782
|
recommendations.push("Consider completing current task first with /p:done");
|
|
@@ -7597,7 +7801,7 @@ async function verifyNow(context2) {
|
|
|
7597
7801
|
const actual = {};
|
|
7598
7802
|
const nowPath = context2.paths.now;
|
|
7599
7803
|
try {
|
|
7600
|
-
const nowContent = await
|
|
7804
|
+
const nowContent = await fs20.readFile(nowPath, "utf-8");
|
|
7601
7805
|
actual.nowExists = true;
|
|
7602
7806
|
actual.nowContent = nowContent.trim();
|
|
7603
7807
|
const hasRealTask = nowContent.trim().length > 0 && !nowContent.includes("No current task") && !nowContent.match(/^#\s*NOW\s*$/m);
|
|
@@ -7617,7 +7821,7 @@ async function verifyNow(context2) {
|
|
|
7617
7821
|
}
|
|
7618
7822
|
const nextPath = context2.paths.next;
|
|
7619
7823
|
try {
|
|
7620
|
-
const nextContent = await
|
|
7824
|
+
const nextContent = await fs20.readFile(nextPath, "utf-8");
|
|
7621
7825
|
const pendingTasks = (nextContent.match(/- \[ \]/g) || []).length;
|
|
7622
7826
|
actual.pendingTasks = pendingTasks;
|
|
7623
7827
|
if (!context2.params.task && pendingTasks > 0) {
|
|
@@ -7641,9 +7845,9 @@ async function verifyInit(context2) {
|
|
|
7641
7845
|
const warnings = [];
|
|
7642
7846
|
const recommendations = [];
|
|
7643
7847
|
const actual = {};
|
|
7644
|
-
const configPath =
|
|
7848
|
+
const configPath = path19.join(context2.projectPath, ".prjct/prjct.config.json");
|
|
7645
7849
|
try {
|
|
7646
|
-
const configContent = await
|
|
7850
|
+
const configContent = await fs20.readFile(configPath, "utf-8");
|
|
7647
7851
|
actual.alreadyInitialized = true;
|
|
7648
7852
|
actual.existingConfig = JSON.parse(configContent);
|
|
7649
7853
|
warnings.push("Project already initialized");
|
|
@@ -7658,14 +7862,14 @@ async function verifyInit(context2) {
|
|
|
7658
7862
|
throw error;
|
|
7659
7863
|
}
|
|
7660
7864
|
}
|
|
7661
|
-
const globalPath =
|
|
7865
|
+
const globalPath = path19.join(os6.homedir(), ".prjct-cli");
|
|
7662
7866
|
try {
|
|
7663
|
-
await
|
|
7867
|
+
await fs20.access(globalPath, fs20.constants.W_OK);
|
|
7664
7868
|
actual.globalPathWritable = true;
|
|
7665
7869
|
} catch (error) {
|
|
7666
7870
|
if (isNotFoundError(error)) {
|
|
7667
7871
|
try {
|
|
7668
|
-
await
|
|
7872
|
+
await fs20.mkdir(globalPath, { recursive: true });
|
|
7669
7873
|
actual.globalPathWritable = true;
|
|
7670
7874
|
actual.globalPathCreated = true;
|
|
7671
7875
|
} catch (_mkdirError) {
|
|
@@ -7690,9 +7894,9 @@ async function verifySync(context2) {
|
|
|
7690
7894
|
const warnings = [];
|
|
7691
7895
|
const recommendations = [];
|
|
7692
7896
|
const actual = {};
|
|
7693
|
-
const configPath =
|
|
7897
|
+
const configPath = path19.join(context2.projectPath, ".prjct/prjct.config.json");
|
|
7694
7898
|
try {
|
|
7695
|
-
const configContent = await
|
|
7899
|
+
const configContent = await fs20.readFile(configPath, "utf-8");
|
|
7696
7900
|
actual.hasConfig = true;
|
|
7697
7901
|
actual.config = JSON.parse(configContent);
|
|
7698
7902
|
} catch (error) {
|
|
@@ -7711,9 +7915,9 @@ async function verifySync(context2) {
|
|
|
7711
7915
|
}
|
|
7712
7916
|
}
|
|
7713
7917
|
const projectId = actual.config?.projectId;
|
|
7714
|
-
const globalProjectPath =
|
|
7918
|
+
const globalProjectPath = path19.join(os6.homedir(), ".prjct-cli/projects", projectId || "");
|
|
7715
7919
|
try {
|
|
7716
|
-
await
|
|
7920
|
+
await fs20.access(globalProjectPath);
|
|
7717
7921
|
actual.globalStorageExists = true;
|
|
7718
7922
|
} catch (error) {
|
|
7719
7923
|
if (isNotFoundError(error)) {
|
|
@@ -7739,7 +7943,7 @@ async function verifyAnalyze(context2) {
|
|
|
7739
7943
|
actual.detectedFiles = [];
|
|
7740
7944
|
for (const file of files) {
|
|
7741
7945
|
try {
|
|
7742
|
-
await
|
|
7946
|
+
await fs20.access(path19.join(context2.projectPath, file));
|
|
7743
7947
|
actual.detectedFiles.push(file);
|
|
7744
7948
|
} catch (error) {
|
|
7745
7949
|
if (!isNotFoundError(error)) {
|
|
@@ -7755,7 +7959,7 @@ async function verifyAnalyze(context2) {
|
|
|
7755
7959
|
actual.detectedSrcDirs = [];
|
|
7756
7960
|
for (const dir of srcDirs) {
|
|
7757
7961
|
try {
|
|
7758
|
-
const stat = await
|
|
7962
|
+
const stat = await fs20.stat(path19.join(context2.projectPath, dir));
|
|
7759
7963
|
if (stat.isDirectory()) {
|
|
7760
7964
|
;
|
|
7761
7965
|
actual.detectedSrcDirs.push(dir);
|
|
@@ -7780,9 +7984,9 @@ async function verifySpec(context2) {
|
|
|
7780
7984
|
const actual = {};
|
|
7781
7985
|
const specsPath = context2.paths.specs;
|
|
7782
7986
|
try {
|
|
7783
|
-
await
|
|
7987
|
+
await fs20.access(specsPath);
|
|
7784
7988
|
actual.specsExists = true;
|
|
7785
|
-
const files = await
|
|
7989
|
+
const files = await fs20.readdir(specsPath);
|
|
7786
7990
|
actual.existingSpecs = files.filter((f) => f.endsWith(".md"));
|
|
7787
7991
|
actual.specCount = actual.existingSpecs.length;
|
|
7788
7992
|
} catch (error) {
|
|
@@ -9183,8 +9387,8 @@ var init_schemas2 = __esm({
|
|
|
9183
9387
|
|
|
9184
9388
|
// core/utils/jsonl-helper.ts
|
|
9185
9389
|
import fsSync from "node:fs";
|
|
9186
|
-
import
|
|
9187
|
-
import
|
|
9390
|
+
import fs21 from "node:fs/promises";
|
|
9391
|
+
import path20 from "node:path";
|
|
9188
9392
|
import readline from "node:readline";
|
|
9189
9393
|
function parseJsonLines(content) {
|
|
9190
9394
|
const lines = content.split("\n").filter((line) => line.trim());
|
|
@@ -9203,7 +9407,7 @@ function stringifyJsonLines(objects) {
|
|
|
9203
9407
|
}
|
|
9204
9408
|
async function readJsonLines(filePath) {
|
|
9205
9409
|
try {
|
|
9206
|
-
const content = await
|
|
9410
|
+
const content = await fs21.readFile(filePath, "utf-8");
|
|
9207
9411
|
return parseJsonLines(content);
|
|
9208
9412
|
} catch (error) {
|
|
9209
9413
|
if (isNotFoundError(error)) {
|
|
@@ -9214,16 +9418,16 @@ async function readJsonLines(filePath) {
|
|
|
9214
9418
|
}
|
|
9215
9419
|
async function writeJsonLines(filePath, objects) {
|
|
9216
9420
|
const content = stringifyJsonLines(objects);
|
|
9217
|
-
await
|
|
9421
|
+
await fs21.writeFile(filePath, content, "utf-8");
|
|
9218
9422
|
}
|
|
9219
9423
|
async function appendJsonLine(filePath, object) {
|
|
9220
9424
|
const line = `${JSON.stringify(object)}
|
|
9221
9425
|
`;
|
|
9222
|
-
await
|
|
9426
|
+
await fs21.appendFile(filePath, line, "utf-8");
|
|
9223
9427
|
}
|
|
9224
9428
|
async function appendJsonLines(filePath, objects) {
|
|
9225
9429
|
const content = stringifyJsonLines(objects);
|
|
9226
|
-
await
|
|
9430
|
+
await fs21.appendFile(filePath, content, "utf-8");
|
|
9227
9431
|
}
|
|
9228
9432
|
async function filterJsonLines(filePath, predicate) {
|
|
9229
9433
|
const entries = await readJsonLines(filePath);
|
|
@@ -9231,7 +9435,7 @@ async function filterJsonLines(filePath, predicate) {
|
|
|
9231
9435
|
}
|
|
9232
9436
|
async function countJsonLines(filePath) {
|
|
9233
9437
|
try {
|
|
9234
|
-
const content = await
|
|
9438
|
+
const content = await fs21.readFile(filePath, "utf-8");
|
|
9235
9439
|
const lines = content.split("\n").filter((line) => line.trim());
|
|
9236
9440
|
return lines.length;
|
|
9237
9441
|
} catch (error) {
|
|
@@ -9290,7 +9494,7 @@ async function readJsonLinesStreaming(filePath, maxLines = 1e3) {
|
|
|
9290
9494
|
}
|
|
9291
9495
|
async function getFileSizeMB(filePath) {
|
|
9292
9496
|
try {
|
|
9293
|
-
const stats = await
|
|
9497
|
+
const stats = await fs21.stat(filePath);
|
|
9294
9498
|
return stats.size / (1024 * 1024);
|
|
9295
9499
|
} catch (error) {
|
|
9296
9500
|
if (isNotFoundError(error)) {
|
|
@@ -9305,13 +9509,13 @@ async function rotateJsonLinesIfNeeded(filePath, maxSizeMB = 10) {
|
|
|
9305
9509
|
return false;
|
|
9306
9510
|
}
|
|
9307
9511
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
9308
|
-
const dir =
|
|
9309
|
-
const ext =
|
|
9310
|
-
const base =
|
|
9311
|
-
const archivePath =
|
|
9312
|
-
await
|
|
9512
|
+
const dir = path20.dirname(filePath);
|
|
9513
|
+
const ext = path20.extname(filePath);
|
|
9514
|
+
const base = path20.basename(filePath, ext);
|
|
9515
|
+
const archivePath = path20.join(dir, `${base}-${timestamp}${ext}`);
|
|
9516
|
+
await fs21.rename(filePath, archivePath);
|
|
9313
9517
|
console.log(
|
|
9314
|
-
`\u{1F4E6} Rotated ${
|
|
9518
|
+
`\u{1F4E6} Rotated ${path20.basename(filePath)} (${sizeMB.toFixed(1)}MB) \u2192 ${path20.basename(archivePath)}`
|
|
9315
9519
|
);
|
|
9316
9520
|
return true;
|
|
9317
9521
|
}
|
|
@@ -9324,7 +9528,7 @@ async function checkFileSizeWarning(filePath, warnThresholdMB = 50) {
|
|
|
9324
9528
|
const isLarge = sizeMB > warnThresholdMB;
|
|
9325
9529
|
if (isLarge) {
|
|
9326
9530
|
console.warn(
|
|
9327
|
-
`\u26A0\uFE0F Large file detected: ${
|
|
9531
|
+
`\u26A0\uFE0F Large file detected: ${path20.basename(filePath)} (${sizeMB.toFixed(1)}MB). Reading may use significant memory.`
|
|
9328
9532
|
);
|
|
9329
9533
|
}
|
|
9330
9534
|
return { sizeMB, isLarge };
|
|
@@ -9408,8 +9612,8 @@ var init_memory = __esm({
|
|
|
9408
9612
|
});
|
|
9409
9613
|
|
|
9410
9614
|
// core/agentic/memory-system.ts
|
|
9411
|
-
import
|
|
9412
|
-
import
|
|
9615
|
+
import fs22 from "node:fs/promises";
|
|
9616
|
+
import path21 from "node:path";
|
|
9413
9617
|
var CachedStore, SessionStore, HistoryStore, PatternStore, SemanticMemories, MemorySystem, memorySystem, memory_system_default;
|
|
9414
9618
|
var init_memory_system = __esm({
|
|
9415
9619
|
"core/agentic/memory-system.ts"() {
|
|
@@ -9439,12 +9643,12 @@ var init_memory_system = __esm({
|
|
|
9439
9643
|
* Get full path for the store file
|
|
9440
9644
|
*/
|
|
9441
9645
|
getPath(projectId) {
|
|
9442
|
-
const basePath =
|
|
9646
|
+
const basePath = path21.join(path_manager_default.getGlobalProjectPath(projectId), "memory");
|
|
9443
9647
|
const subdir = this.getSubdirectory();
|
|
9444
9648
|
if (subdir) {
|
|
9445
|
-
return
|
|
9649
|
+
return path21.join(basePath, subdir, this.getFilename());
|
|
9446
9650
|
}
|
|
9447
|
-
return
|
|
9651
|
+
return path21.join(basePath, this.getFilename());
|
|
9448
9652
|
}
|
|
9449
9653
|
/**
|
|
9450
9654
|
* Load data from disk (with caching)
|
|
@@ -9456,7 +9660,7 @@ var init_memory_system = __esm({
|
|
|
9456
9660
|
}
|
|
9457
9661
|
const filePath = this.getPath(projectId);
|
|
9458
9662
|
try {
|
|
9459
|
-
const content = await
|
|
9663
|
+
const content = await fs22.readFile(filePath, "utf-8");
|
|
9460
9664
|
this._data = JSON.parse(content);
|
|
9461
9665
|
this.afterLoad(this._data);
|
|
9462
9666
|
} catch (error) {
|
|
@@ -9482,8 +9686,8 @@ var init_memory_system = __esm({
|
|
|
9482
9686
|
async save(projectId) {
|
|
9483
9687
|
if (!this._data) return;
|
|
9484
9688
|
const filePath = this.getPath(projectId);
|
|
9485
|
-
await
|
|
9486
|
-
await
|
|
9689
|
+
await fs22.mkdir(path21.dirname(filePath), { recursive: true });
|
|
9690
|
+
await fs22.writeFile(filePath, JSON.stringify(this._data, null, 2), "utf-8");
|
|
9487
9691
|
}
|
|
9488
9692
|
/**
|
|
9489
9693
|
* Get cached data without loading (may be null)
|
|
@@ -9549,7 +9753,7 @@ var init_memory_system = __esm({
|
|
|
9549
9753
|
const now = /* @__PURE__ */ new Date();
|
|
9550
9754
|
const yearMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
9551
9755
|
const day = getTodayKey();
|
|
9552
|
-
return
|
|
9756
|
+
return path21.join(
|
|
9553
9757
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
9554
9758
|
"memory",
|
|
9555
9759
|
"sessions",
|
|
@@ -9559,7 +9763,7 @@ var init_memory_system = __esm({
|
|
|
9559
9763
|
}
|
|
9560
9764
|
async appendHistory(projectId, entry) {
|
|
9561
9765
|
const sessionPath = this._getSessionPath(projectId);
|
|
9562
|
-
await ensureDir(
|
|
9766
|
+
await ensureDir(path21.dirname(sessionPath));
|
|
9563
9767
|
const logEntry = {
|
|
9564
9768
|
ts: getTimestamp(),
|
|
9565
9769
|
...entry,
|
|
@@ -10449,8 +10653,8 @@ var init_ideas_storage = __esm({
|
|
|
10449
10653
|
|
|
10450
10654
|
// core/storage/index-storage.ts
|
|
10451
10655
|
import crypto4 from "node:crypto";
|
|
10452
|
-
import
|
|
10453
|
-
import
|
|
10656
|
+
import fs23 from "node:fs/promises";
|
|
10657
|
+
import path22 from "node:path";
|
|
10454
10658
|
function getDefaultChecksums() {
|
|
10455
10659
|
return {
|
|
10456
10660
|
version: INDEX_VERSION,
|
|
@@ -10475,14 +10679,14 @@ var init_index_storage = __esm({
|
|
|
10475
10679
|
* Get the index directory path for a project
|
|
10476
10680
|
*/
|
|
10477
10681
|
getIndexPath(projectId) {
|
|
10478
|
-
return
|
|
10682
|
+
return path22.join(path_manager_default.getGlobalProjectPath(projectId), "index");
|
|
10479
10683
|
}
|
|
10480
10684
|
/**
|
|
10481
10685
|
* Ensure index directory exists
|
|
10482
10686
|
*/
|
|
10483
10687
|
async ensureIndexDir(projectId) {
|
|
10484
10688
|
const indexPath = this.getIndexPath(projectId);
|
|
10485
|
-
await
|
|
10689
|
+
await fs23.mkdir(indexPath, { recursive: true });
|
|
10486
10690
|
return indexPath;
|
|
10487
10691
|
}
|
|
10488
10692
|
// ==========================================================================
|
|
@@ -10492,9 +10696,9 @@ var init_index_storage = __esm({
|
|
|
10492
10696
|
* Read the project index
|
|
10493
10697
|
*/
|
|
10494
10698
|
async readIndex(projectId) {
|
|
10495
|
-
const filePath =
|
|
10699
|
+
const filePath = path22.join(this.getIndexPath(projectId), "project-index.json");
|
|
10496
10700
|
try {
|
|
10497
|
-
const content = await
|
|
10701
|
+
const content = await fs23.readFile(filePath, "utf-8");
|
|
10498
10702
|
const index = JSON.parse(content);
|
|
10499
10703
|
if (index.version !== INDEX_VERSION) {
|
|
10500
10704
|
return null;
|
|
@@ -10512,8 +10716,8 @@ var init_index_storage = __esm({
|
|
|
10512
10716
|
*/
|
|
10513
10717
|
async writeIndex(projectId, index) {
|
|
10514
10718
|
await this.ensureIndexDir(projectId);
|
|
10515
|
-
const filePath =
|
|
10516
|
-
await
|
|
10719
|
+
const filePath = path22.join(this.getIndexPath(projectId), "project-index.json");
|
|
10720
|
+
await fs23.writeFile(filePath, JSON.stringify(index, null, 2), "utf-8");
|
|
10517
10721
|
}
|
|
10518
10722
|
/**
|
|
10519
10723
|
* Check if index exists and is valid
|
|
@@ -10529,9 +10733,9 @@ var init_index_storage = __esm({
|
|
|
10529
10733
|
* Read file checksums
|
|
10530
10734
|
*/
|
|
10531
10735
|
async readChecksums(projectId) {
|
|
10532
|
-
const filePath =
|
|
10736
|
+
const filePath = path22.join(this.getIndexPath(projectId), "checksums.json");
|
|
10533
10737
|
try {
|
|
10534
|
-
const content = await
|
|
10738
|
+
const content = await fs23.readFile(filePath, "utf-8");
|
|
10535
10739
|
return JSON.parse(content);
|
|
10536
10740
|
} catch (error) {
|
|
10537
10741
|
if (isNotFoundError(error)) {
|
|
@@ -10545,15 +10749,15 @@ var init_index_storage = __esm({
|
|
|
10545
10749
|
*/
|
|
10546
10750
|
async writeChecksums(projectId, checksums) {
|
|
10547
10751
|
await this.ensureIndexDir(projectId);
|
|
10548
|
-
const filePath =
|
|
10549
|
-
await
|
|
10752
|
+
const filePath = path22.join(this.getIndexPath(projectId), "checksums.json");
|
|
10753
|
+
await fs23.writeFile(filePath, JSON.stringify(checksums, null, 2), "utf-8");
|
|
10550
10754
|
}
|
|
10551
10755
|
/**
|
|
10552
10756
|
* Calculate checksum for a file
|
|
10553
10757
|
*/
|
|
10554
10758
|
async calculateChecksum(filePath) {
|
|
10555
10759
|
try {
|
|
10556
|
-
const content = await
|
|
10760
|
+
const content = await fs23.readFile(filePath);
|
|
10557
10761
|
return crypto4.createHash("md5").update(content).digest("hex");
|
|
10558
10762
|
} catch {
|
|
10559
10763
|
return "";
|
|
@@ -10589,9 +10793,9 @@ var init_index_storage = __esm({
|
|
|
10589
10793
|
* Read file scores
|
|
10590
10794
|
*/
|
|
10591
10795
|
async readScores(projectId) {
|
|
10592
|
-
const filePath =
|
|
10796
|
+
const filePath = path22.join(this.getIndexPath(projectId), "file-scores.json");
|
|
10593
10797
|
try {
|
|
10594
|
-
const content = await
|
|
10798
|
+
const content = await fs23.readFile(filePath, "utf-8");
|
|
10595
10799
|
const data = JSON.parse(content);
|
|
10596
10800
|
return data.scores || [];
|
|
10597
10801
|
} catch (error) {
|
|
@@ -10606,13 +10810,13 @@ var init_index_storage = __esm({
|
|
|
10606
10810
|
*/
|
|
10607
10811
|
async writeScores(projectId, scores) {
|
|
10608
10812
|
await this.ensureIndexDir(projectId);
|
|
10609
|
-
const filePath =
|
|
10813
|
+
const filePath = path22.join(this.getIndexPath(projectId), "file-scores.json");
|
|
10610
10814
|
const data = {
|
|
10611
10815
|
version: INDEX_VERSION,
|
|
10612
10816
|
lastUpdated: getTimestamp(),
|
|
10613
10817
|
scores
|
|
10614
10818
|
};
|
|
10615
|
-
await
|
|
10819
|
+
await fs23.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
10616
10820
|
}
|
|
10617
10821
|
// ==========================================================================
|
|
10618
10822
|
// UTILITY METHODS
|
|
@@ -10623,8 +10827,8 @@ var init_index_storage = __esm({
|
|
|
10623
10827
|
async clearIndex(projectId) {
|
|
10624
10828
|
const indexPath = this.getIndexPath(projectId);
|
|
10625
10829
|
try {
|
|
10626
|
-
const files = await
|
|
10627
|
-
await Promise.all(files.map((file) =>
|
|
10830
|
+
const files = await fs23.readdir(indexPath);
|
|
10831
|
+
await Promise.all(files.map((file) => fs23.unlink(path22.join(indexPath, file))));
|
|
10628
10832
|
} catch (error) {
|
|
10629
10833
|
if (!isNotFoundError(error)) {
|
|
10630
10834
|
throw error;
|
|
@@ -10650,9 +10854,9 @@ var init_index_storage = __esm({
|
|
|
10650
10854
|
* Read discovered domains for a project
|
|
10651
10855
|
*/
|
|
10652
10856
|
async readDomains(projectId) {
|
|
10653
|
-
const filePath =
|
|
10857
|
+
const filePath = path22.join(this.getIndexPath(projectId), "domains.json");
|
|
10654
10858
|
try {
|
|
10655
|
-
const content = await
|
|
10859
|
+
const content = await fs23.readFile(filePath, "utf-8");
|
|
10656
10860
|
const domains = JSON.parse(content);
|
|
10657
10861
|
if (domains.version !== INDEX_VERSION) {
|
|
10658
10862
|
return null;
|
|
@@ -10670,8 +10874,8 @@ var init_index_storage = __esm({
|
|
|
10670
10874
|
*/
|
|
10671
10875
|
async writeDomains(projectId, domains) {
|
|
10672
10876
|
await this.ensureIndexDir(projectId);
|
|
10673
|
-
const filePath =
|
|
10674
|
-
await
|
|
10877
|
+
const filePath = path22.join(this.getIndexPath(projectId), "domains.json");
|
|
10878
|
+
await fs23.writeFile(filePath, JSON.stringify(domains, null, 2), "utf-8");
|
|
10675
10879
|
}
|
|
10676
10880
|
// ==========================================================================
|
|
10677
10881
|
// CATEGORIES CACHE
|
|
@@ -10680,9 +10884,9 @@ var init_index_storage = __esm({
|
|
|
10680
10884
|
* Read categories cache
|
|
10681
10885
|
*/
|
|
10682
10886
|
async readCategories(projectId) {
|
|
10683
|
-
const filePath =
|
|
10887
|
+
const filePath = path22.join(this.getIndexPath(projectId), "categories-cache.json");
|
|
10684
10888
|
try {
|
|
10685
|
-
const content = await
|
|
10889
|
+
const content = await fs23.readFile(filePath, "utf-8");
|
|
10686
10890
|
const cache2 = JSON.parse(content);
|
|
10687
10891
|
if (cache2.version !== INDEX_VERSION) {
|
|
10688
10892
|
return null;
|
|
@@ -10700,8 +10904,8 @@ var init_index_storage = __esm({
|
|
|
10700
10904
|
*/
|
|
10701
10905
|
async writeCategories(projectId, cache2) {
|
|
10702
10906
|
await this.ensureIndexDir(projectId);
|
|
10703
|
-
const filePath =
|
|
10704
|
-
await
|
|
10907
|
+
const filePath = path22.join(this.getIndexPath(projectId), "categories-cache.json");
|
|
10908
|
+
await fs23.writeFile(filePath, JSON.stringify(cache2, null, 2), "utf-8");
|
|
10705
10909
|
}
|
|
10706
10910
|
/**
|
|
10707
10911
|
* Get file categories for specific paths
|
|
@@ -11761,9 +11965,9 @@ var init_state_storage = __esm({
|
|
|
11761
11965
|
});
|
|
11762
11966
|
|
|
11763
11967
|
// core/storage/storage.ts
|
|
11764
|
-
import
|
|
11968
|
+
import fs24 from "node:fs/promises";
|
|
11765
11969
|
import os7 from "node:os";
|
|
11766
|
-
import
|
|
11970
|
+
import path23 from "node:path";
|
|
11767
11971
|
function getStorage(projectId) {
|
|
11768
11972
|
return new FileStorage(projectId);
|
|
11769
11973
|
}
|
|
@@ -11781,7 +11985,7 @@ var init_storage = __esm({
|
|
|
11781
11985
|
basePath;
|
|
11782
11986
|
constructor(projectId) {
|
|
11783
11987
|
this.projectId = projectId;
|
|
11784
|
-
this.basePath =
|
|
11988
|
+
this.basePath = path23.join(os7.homedir(), ".prjct-cli/projects", projectId, "data");
|
|
11785
11989
|
}
|
|
11786
11990
|
/**
|
|
11787
11991
|
* Convert path array to file path
|
|
@@ -11790,17 +11994,17 @@ var init_storage = __esm({
|
|
|
11790
11994
|
*/
|
|
11791
11995
|
pathToFile(pathArray) {
|
|
11792
11996
|
if (pathArray.length === 1) {
|
|
11793
|
-
return
|
|
11997
|
+
return path23.join(this.basePath, `${pathArray[0]}.json`);
|
|
11794
11998
|
}
|
|
11795
11999
|
const dir = `${pathArray[0]}s`;
|
|
11796
12000
|
const rest = pathArray.slice(1);
|
|
11797
12001
|
const filename = `${rest.join("/")}.json`;
|
|
11798
|
-
return
|
|
12002
|
+
return path23.join(this.basePath, dir, filename);
|
|
11799
12003
|
}
|
|
11800
12004
|
async write(pathArray, data) {
|
|
11801
12005
|
const filePath = this.pathToFile(pathArray);
|
|
11802
|
-
await
|
|
11803
|
-
await
|
|
12006
|
+
await fs24.mkdir(path23.dirname(filePath), { recursive: true });
|
|
12007
|
+
await fs24.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
11804
12008
|
eventBus.publish({
|
|
11805
12009
|
type: inferEventType(pathArray, "write"),
|
|
11806
12010
|
path: pathArray,
|
|
@@ -11815,7 +12019,7 @@ var init_storage = __esm({
|
|
|
11815
12019
|
async read(pathArray) {
|
|
11816
12020
|
const filePath = this.pathToFile(pathArray);
|
|
11817
12021
|
try {
|
|
11818
|
-
const content = await
|
|
12022
|
+
const content = await fs24.readFile(filePath, "utf-8");
|
|
11819
12023
|
return JSON.parse(content);
|
|
11820
12024
|
} catch (error) {
|
|
11821
12025
|
if (isNotFoundError(error) || error instanceof SyntaxError) {
|
|
@@ -11825,9 +12029,9 @@ var init_storage = __esm({
|
|
|
11825
12029
|
}
|
|
11826
12030
|
}
|
|
11827
12031
|
async list(prefix) {
|
|
11828
|
-
const dir =
|
|
12032
|
+
const dir = path23.join(this.basePath, `${prefix[0]}s`);
|
|
11829
12033
|
try {
|
|
11830
|
-
const files = await
|
|
12034
|
+
const files = await fs24.readdir(dir);
|
|
11831
12035
|
return files.filter((f) => f.endsWith(".json") && f !== "index.json").map((f) => [...prefix, f.replace(".json", "")]);
|
|
11832
12036
|
} catch (error) {
|
|
11833
12037
|
if (isNotFoundError(error)) {
|
|
@@ -11839,7 +12043,7 @@ var init_storage = __esm({
|
|
|
11839
12043
|
async delete(pathArray) {
|
|
11840
12044
|
const filePath = this.pathToFile(pathArray);
|
|
11841
12045
|
try {
|
|
11842
|
-
await
|
|
12046
|
+
await fs24.unlink(filePath);
|
|
11843
12047
|
eventBus.publish({
|
|
11844
12048
|
type: inferEventType(pathArray, "delete"),
|
|
11845
12049
|
path: pathArray,
|
|
@@ -11859,7 +12063,7 @@ var init_storage = __esm({
|
|
|
11859
12063
|
async exists(pathArray) {
|
|
11860
12064
|
const filePath = this.pathToFile(pathArray);
|
|
11861
12065
|
try {
|
|
11862
|
-
await
|
|
12066
|
+
await fs24.access(filePath);
|
|
11863
12067
|
return true;
|
|
11864
12068
|
} catch (error) {
|
|
11865
12069
|
if (isNotFoundError(error)) {
|
|
@@ -11872,10 +12076,10 @@ var init_storage = __esm({
|
|
|
11872
12076
|
* Update collection index
|
|
11873
12077
|
*/
|
|
11874
12078
|
async updateIndex(collection, id, action) {
|
|
11875
|
-
const indexPath =
|
|
12079
|
+
const indexPath = path23.join(this.basePath, `${collection}s`, "index.json");
|
|
11876
12080
|
let index = { ids: [], updatedAt: "" };
|
|
11877
12081
|
try {
|
|
11878
|
-
const content = await
|
|
12082
|
+
const content = await fs24.readFile(indexPath, "utf-8");
|
|
11879
12083
|
index = JSON.parse(content);
|
|
11880
12084
|
} catch (error) {
|
|
11881
12085
|
if (!isNotFoundError(error) && !(error instanceof SyntaxError)) {
|
|
@@ -11888,8 +12092,8 @@ var init_storage = __esm({
|
|
|
11888
12092
|
index.ids = index.ids.filter((i) => i !== id);
|
|
11889
12093
|
}
|
|
11890
12094
|
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11891
|
-
await
|
|
11892
|
-
await
|
|
12095
|
+
await fs24.mkdir(path23.dirname(indexPath), { recursive: true });
|
|
12096
|
+
await fs24.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
11893
12097
|
}
|
|
11894
12098
|
};
|
|
11895
12099
|
__name(getStorage, "getStorage");
|
|
@@ -11912,8 +12116,8 @@ var init_storage2 = __esm({
|
|
|
11912
12116
|
});
|
|
11913
12117
|
|
|
11914
12118
|
// core/agentic/template-loader.ts
|
|
11915
|
-
import
|
|
11916
|
-
import
|
|
12119
|
+
import fs25 from "node:fs/promises";
|
|
12120
|
+
import path24 from "node:path";
|
|
11917
12121
|
function updateLruOrder(key) {
|
|
11918
12122
|
const index = cacheOrder.indexOf(key);
|
|
11919
12123
|
if (index > -1) cacheOrder.splice(index, 1);
|
|
@@ -11951,9 +12155,9 @@ async function load(commandName) {
|
|
|
11951
12155
|
updateLruOrder(commandName);
|
|
11952
12156
|
return cache.get(commandName);
|
|
11953
12157
|
}
|
|
11954
|
-
const templatePath =
|
|
12158
|
+
const templatePath = path24.join(TEMPLATES_DIR, `${commandName}.md`);
|
|
11955
12159
|
try {
|
|
11956
|
-
const rawContent = await
|
|
12160
|
+
const rawContent = await fs25.readFile(templatePath, "utf-8");
|
|
11957
12161
|
const parsed = parseFrontmatter(rawContent);
|
|
11958
12162
|
evictLru();
|
|
11959
12163
|
cache.set(commandName, parsed);
|
|
@@ -11976,7 +12180,7 @@ var init_template_loader = __esm({
|
|
|
11976
12180
|
"core/agentic/template-loader.ts"() {
|
|
11977
12181
|
"use strict";
|
|
11978
12182
|
init_errors();
|
|
11979
|
-
TEMPLATES_DIR =
|
|
12183
|
+
TEMPLATES_DIR = path24.join(__dirname, "..", "..", "templates", "commands");
|
|
11980
12184
|
MAX_CACHE_SIZE = 50;
|
|
11981
12185
|
cache = /* @__PURE__ */ new Map();
|
|
11982
12186
|
cacheOrder = [];
|
|
@@ -11996,9 +12200,9 @@ var init_template_loader = __esm({
|
|
|
11996
12200
|
});
|
|
11997
12201
|
|
|
11998
12202
|
// core/agentic/orchestrator-executor.ts
|
|
11999
|
-
import
|
|
12203
|
+
import fs26 from "node:fs/promises";
|
|
12000
12204
|
import os8 from "node:os";
|
|
12001
|
-
import
|
|
12205
|
+
import path25 from "node:path";
|
|
12002
12206
|
var DOMAIN_KEYWORDS2, DOMAIN_DEPENDENCY_ORDER, OrchestratorExecutor, orchestratorExecutor, orchestrator_executor_default;
|
|
12003
12207
|
var init_orchestrator_executor = __esm({
|
|
12004
12208
|
"core/agentic/orchestrator-executor.ts"() {
|
|
@@ -12182,8 +12386,8 @@ var init_orchestrator_executor = __esm({
|
|
|
12182
12386
|
*/
|
|
12183
12387
|
async loadRepoAnalysis(globalPath) {
|
|
12184
12388
|
try {
|
|
12185
|
-
const analysisPath =
|
|
12186
|
-
const content = await
|
|
12389
|
+
const analysisPath = path25.join(globalPath, "analysis", "repo-analysis.json");
|
|
12390
|
+
const content = await fs26.readFile(analysisPath, "utf-8");
|
|
12187
12391
|
return JSON.parse(content);
|
|
12188
12392
|
} catch (error) {
|
|
12189
12393
|
if (isNotFoundError(error)) return null;
|
|
@@ -12247,8 +12451,8 @@ var init_orchestrator_executor = __esm({
|
|
|
12247
12451
|
*/
|
|
12248
12452
|
async getAvailableAgentNames(globalPath) {
|
|
12249
12453
|
try {
|
|
12250
|
-
const agentsDir =
|
|
12251
|
-
const files = await
|
|
12454
|
+
const agentsDir = path25.join(globalPath, "agents");
|
|
12455
|
+
const files = await fs26.readdir(agentsDir);
|
|
12252
12456
|
return files.filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
12253
12457
|
} catch {
|
|
12254
12458
|
return [];
|
|
@@ -12264,13 +12468,13 @@ var init_orchestrator_executor = __esm({
|
|
|
12264
12468
|
*/
|
|
12265
12469
|
async loadAgents(domains, projectId) {
|
|
12266
12470
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
12267
|
-
const agentsDir =
|
|
12471
|
+
const agentsDir = path25.join(globalPath, "agents");
|
|
12268
12472
|
const agentPromises = domains.map(async (domain) => {
|
|
12269
12473
|
const possibleNames = [`${domain}.md`, `${domain}-agent.md`, `prjct-${domain}.md`];
|
|
12270
12474
|
for (const fileName of possibleNames) {
|
|
12271
|
-
const filePath =
|
|
12475
|
+
const filePath = path25.join(agentsDir, fileName);
|
|
12272
12476
|
try {
|
|
12273
|
-
const content = await
|
|
12477
|
+
const content = await fs26.readFile(filePath, "utf-8");
|
|
12274
12478
|
const { frontmatter, body } = this.parseAgentFile(content);
|
|
12275
12479
|
return {
|
|
12276
12480
|
name: fileName.replace(".md", ""),
|
|
@@ -12309,7 +12513,7 @@ var init_orchestrator_executor = __esm({
|
|
|
12309
12513
|
* Uses parallel file reads for performance (PRJ-110).
|
|
12310
12514
|
*/
|
|
12311
12515
|
async loadSkills(agents) {
|
|
12312
|
-
const skillsDir =
|
|
12516
|
+
const skillsDir = path25.join(os8.homedir(), ".claude", "skills");
|
|
12313
12517
|
const uniqueSkillNames = /* @__PURE__ */ new Set();
|
|
12314
12518
|
for (const agent of agents) {
|
|
12315
12519
|
for (const skillName of agent.skills) {
|
|
@@ -12318,14 +12522,14 @@ var init_orchestrator_executor = __esm({
|
|
|
12318
12522
|
}
|
|
12319
12523
|
const skillPromises = Array.from(uniqueSkillNames).map(
|
|
12320
12524
|
async (skillName) => {
|
|
12321
|
-
const flatPath =
|
|
12322
|
-
const subdirPath =
|
|
12525
|
+
const flatPath = path25.join(skillsDir, `${skillName}.md`);
|
|
12526
|
+
const subdirPath = path25.join(skillsDir, skillName, "SKILL.md");
|
|
12323
12527
|
try {
|
|
12324
|
-
const content = await
|
|
12528
|
+
const content = await fs26.readFile(subdirPath, "utf-8");
|
|
12325
12529
|
return { name: skillName, content, filePath: subdirPath };
|
|
12326
12530
|
} catch {
|
|
12327
12531
|
try {
|
|
12328
|
-
const content = await
|
|
12532
|
+
const content = await fs26.readFile(flatPath, "utf-8");
|
|
12329
12533
|
return { name: skillName, content, filePath: flatPath };
|
|
12330
12534
|
} catch {
|
|
12331
12535
|
return null;
|
|
@@ -12932,7 +13136,7 @@ var init_types3 = __esm({
|
|
|
12932
13136
|
});
|
|
12933
13137
|
|
|
12934
13138
|
// core/outcomes/recorder.ts
|
|
12935
|
-
import
|
|
13139
|
+
import path26 from "node:path";
|
|
12936
13140
|
var OUTCOMES_DIR, OUTCOMES_FILE, OutcomeRecorder, outcomeRecorder, recorder_default;
|
|
12937
13141
|
var init_recorder = __esm({
|
|
12938
13142
|
"core/outcomes/recorder.ts"() {
|
|
@@ -12951,13 +13155,13 @@ var init_recorder = __esm({
|
|
|
12951
13155
|
*/
|
|
12952
13156
|
getOutcomesDir(projectId) {
|
|
12953
13157
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
12954
|
-
return
|
|
13158
|
+
return path26.join(globalPath, OUTCOMES_DIR);
|
|
12955
13159
|
}
|
|
12956
13160
|
/**
|
|
12957
13161
|
* Get outcomes file path for a project.
|
|
12958
13162
|
*/
|
|
12959
13163
|
getOutcomesPath(projectId) {
|
|
12960
|
-
return
|
|
13164
|
+
return path26.join(this.getOutcomesDir(projectId), OUTCOMES_FILE);
|
|
12961
13165
|
}
|
|
12962
13166
|
/**
|
|
12963
13167
|
* Record an outcome.
|
|
@@ -12968,7 +13172,7 @@ var init_recorder = __esm({
|
|
|
12968
13172
|
id: generateUUID()
|
|
12969
13173
|
};
|
|
12970
13174
|
const outcomesPath = this.getOutcomesPath(projectId);
|
|
12971
|
-
await ensureDir(
|
|
13175
|
+
await ensureDir(path26.dirname(outcomesPath));
|
|
12972
13176
|
await appendLine(outcomesPath, JSON.stringify(outcome));
|
|
12973
13177
|
return outcome;
|
|
12974
13178
|
}
|
|
@@ -13317,8 +13521,8 @@ var init_outcomes2 = __esm({
|
|
|
13317
13521
|
});
|
|
13318
13522
|
|
|
13319
13523
|
// core/agentic/prompt-builder.ts
|
|
13320
|
-
import
|
|
13321
|
-
import
|
|
13524
|
+
import fs27 from "node:fs";
|
|
13525
|
+
import path27 from "node:path";
|
|
13322
13526
|
var PromptBuilder, promptBuilder, prompt_builder_default;
|
|
13323
13527
|
var init_prompt_builder = __esm({
|
|
13324
13528
|
"core/agentic/prompt-builder.ts"() {
|
|
@@ -13354,8 +13558,8 @@ var init_prompt_builder = __esm({
|
|
|
13354
13558
|
return cached.content;
|
|
13355
13559
|
}
|
|
13356
13560
|
try {
|
|
13357
|
-
if (
|
|
13358
|
-
const content =
|
|
13561
|
+
if (fs27.existsSync(templatePath)) {
|
|
13562
|
+
const content = fs27.readFileSync(templatePath, "utf-8");
|
|
13359
13563
|
this._templateCache.set(templatePath, { content, loadedAt: now });
|
|
13360
13564
|
return content;
|
|
13361
13565
|
}
|
|
@@ -13394,7 +13598,7 @@ var init_prompt_builder = __esm({
|
|
|
13394
13598
|
* These modules extend the base global CLAUDE.md for complex operations
|
|
13395
13599
|
*/
|
|
13396
13600
|
loadModule(moduleName) {
|
|
13397
|
-
const modulePath =
|
|
13601
|
+
const modulePath = path27.join(getPackageRoot(), "templates/global/modules", moduleName);
|
|
13398
13602
|
return this.getTemplate(modulePath);
|
|
13399
13603
|
}
|
|
13400
13604
|
/**
|
|
@@ -13422,14 +13626,14 @@ var init_prompt_builder = __esm({
|
|
|
13422
13626
|
if (this._checklistsCache && now - this._checklistsCacheTime < this.TEMPLATE_CACHE_TTL_MS) {
|
|
13423
13627
|
return this._checklistsCache;
|
|
13424
13628
|
}
|
|
13425
|
-
const checklistsDir =
|
|
13629
|
+
const checklistsDir = path27.join(__dirname, "..", "..", "templates", "checklists");
|
|
13426
13630
|
const checklists = {};
|
|
13427
13631
|
try {
|
|
13428
|
-
if (
|
|
13429
|
-
const files =
|
|
13632
|
+
if (fs27.existsSync(checklistsDir)) {
|
|
13633
|
+
const files = fs27.readdirSync(checklistsDir).filter((f) => f.endsWith(".md"));
|
|
13430
13634
|
for (const file of files) {
|
|
13431
13635
|
const name = file.replace(".md", "");
|
|
13432
|
-
const templatePath =
|
|
13636
|
+
const templatePath = path27.join(checklistsDir, file);
|
|
13433
13637
|
const content = this.getTemplate(templatePath);
|
|
13434
13638
|
if (content) {
|
|
13435
13639
|
checklists[name] = content;
|
|
@@ -13548,7 +13752,7 @@ var init_prompt_builder = __esm({
|
|
|
13548
13752
|
if (this._checklistRoutingCache && now - this._checklistRoutingCacheTime < this.TEMPLATE_CACHE_TTL_MS) {
|
|
13549
13753
|
return this._checklistRoutingCache;
|
|
13550
13754
|
}
|
|
13551
|
-
const routingPath =
|
|
13755
|
+
const routingPath = path27.join(
|
|
13552
13756
|
__dirname,
|
|
13553
13757
|
"..",
|
|
13554
13758
|
"..",
|
|
@@ -13947,8 +14151,8 @@ Context: ${fileCount} files available. Read what you need.
|
|
|
13947
14151
|
});
|
|
13948
14152
|
|
|
13949
14153
|
// core/agentic/template-executor.ts
|
|
13950
|
-
import
|
|
13951
|
-
import
|
|
14154
|
+
import fs28 from "node:fs/promises";
|
|
14155
|
+
import path28 from "node:path";
|
|
13952
14156
|
var ORCHESTRATED_COMMANDS, SIMPLE_COMMANDS, TemplateExecutor, templateExecutor, template_executor_default;
|
|
13953
14157
|
var init_template_executor = __esm({
|
|
13954
14158
|
"core/agentic/template-executor.ts"() {
|
|
@@ -13966,7 +14170,7 @@ var init_template_executor = __esm({
|
|
|
13966
14170
|
* Get npm root for templates path
|
|
13967
14171
|
*/
|
|
13968
14172
|
async getNpmRoot() {
|
|
13969
|
-
const moduleDir =
|
|
14173
|
+
const moduleDir = path28.dirname(__require.resolve("prjct-cli/package.json"));
|
|
13970
14174
|
return moduleDir;
|
|
13971
14175
|
}
|
|
13972
14176
|
/**
|
|
@@ -13987,9 +14191,9 @@ var init_template_executor = __esm({
|
|
|
13987
14191
|
let templatesDir;
|
|
13988
14192
|
try {
|
|
13989
14193
|
const npmRoot = await this.getNpmRoot();
|
|
13990
|
-
templatesDir =
|
|
14194
|
+
templatesDir = path28.join(npmRoot, "templates");
|
|
13991
14195
|
} catch {
|
|
13992
|
-
templatesDir =
|
|
14196
|
+
templatesDir = path28.join(__dirname, "..", "..", "templates");
|
|
13993
14197
|
}
|
|
13994
14198
|
return {
|
|
13995
14199
|
projectPath,
|
|
@@ -14000,14 +14204,14 @@ var init_template_executor = __esm({
|
|
|
14000
14204
|
agentName: activeProvider.displayName,
|
|
14001
14205
|
agentSettingsPath: path_manager_default.getAgentSettingsPath(),
|
|
14002
14206
|
paths: {
|
|
14003
|
-
orchestrator:
|
|
14004
|
-
agentRouting:
|
|
14005
|
-
taskFragmentation:
|
|
14006
|
-
commandTemplate:
|
|
14007
|
-
repoAnalysis:
|
|
14008
|
-
agentsDir:
|
|
14207
|
+
orchestrator: path28.join(templatesDir, "agentic", "orchestrator.md"),
|
|
14208
|
+
agentRouting: path28.join(templatesDir, "agentic", "agent-routing.md"),
|
|
14209
|
+
taskFragmentation: path28.join(templatesDir, "agentic", "task-fragmentation.md"),
|
|
14210
|
+
commandTemplate: path28.join(templatesDir, "commands", `${command}.md`),
|
|
14211
|
+
repoAnalysis: path28.join(globalPath, "analysis", "repo-analysis.json"),
|
|
14212
|
+
agentsDir: path28.join(globalPath, "agents"),
|
|
14009
14213
|
skillsDir: activeProvider.skillsDir,
|
|
14010
|
-
stateJson:
|
|
14214
|
+
stateJson: path28.join(globalPath, "storage", "state.json")
|
|
14011
14215
|
}
|
|
14012
14216
|
};
|
|
14013
14217
|
}
|
|
@@ -14025,8 +14229,8 @@ var init_template_executor = __esm({
|
|
|
14025
14229
|
async hasAgents(projectPath) {
|
|
14026
14230
|
try {
|
|
14027
14231
|
const projectId = await this.getProjectId(projectPath);
|
|
14028
|
-
const agentsDir =
|
|
14029
|
-
const files = await
|
|
14232
|
+
const agentsDir = path28.join(path_manager_default.getGlobalProjectPath(projectId), "agents");
|
|
14233
|
+
const files = await fs28.readdir(agentsDir);
|
|
14030
14234
|
return files.some((f) => f.endsWith(".md"));
|
|
14031
14235
|
} catch (error) {
|
|
14032
14236
|
if (isNotFoundError(error)) return false;
|
|
@@ -14039,8 +14243,8 @@ var init_template_executor = __esm({
|
|
|
14039
14243
|
async getAvailableAgents(projectPath) {
|
|
14040
14244
|
try {
|
|
14041
14245
|
const projectId = await this.getProjectId(projectPath);
|
|
14042
|
-
const agentsDir =
|
|
14043
|
-
const files = await
|
|
14246
|
+
const agentsDir = path28.join(path_manager_default.getGlobalProjectPath(projectId), "agents");
|
|
14247
|
+
const files = await fs28.readdir(agentsDir);
|
|
14044
14248
|
return files.filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
14045
14249
|
} catch {
|
|
14046
14250
|
return [];
|
|
@@ -14149,7 +14353,7 @@ When fragmenting tasks:
|
|
|
14149
14353
|
|
|
14150
14354
|
// core/agentic/tool-registry.ts
|
|
14151
14355
|
import { exec as exec6 } from "node:child_process";
|
|
14152
|
-
import
|
|
14356
|
+
import fs29 from "node:fs/promises";
|
|
14153
14357
|
import { promisify as promisify6 } from "node:util";
|
|
14154
14358
|
var execAsync2, toolRegistry, tool_registry_default;
|
|
14155
14359
|
var init_tool_registry = __esm({
|
|
@@ -14193,14 +14397,14 @@ var init_tool_registry = __esm({
|
|
|
14193
14397
|
};
|
|
14194
14398
|
toolRegistry.register("Read", async (filePath) => {
|
|
14195
14399
|
try {
|
|
14196
|
-
return await
|
|
14400
|
+
return await fs29.readFile(filePath, "utf-8");
|
|
14197
14401
|
} catch (_error) {
|
|
14198
14402
|
return null;
|
|
14199
14403
|
}
|
|
14200
14404
|
});
|
|
14201
14405
|
toolRegistry.register("Write", async (filePath, content) => {
|
|
14202
14406
|
try {
|
|
14203
|
-
await
|
|
14407
|
+
await fs29.writeFile(filePath, content, "utf-8");
|
|
14204
14408
|
return true;
|
|
14205
14409
|
} catch (_error) {
|
|
14206
14410
|
return false;
|
|
@@ -14235,23 +14439,23 @@ var init_tool_registry = __esm({
|
|
|
14235
14439
|
});
|
|
14236
14440
|
|
|
14237
14441
|
// core/agentic/command-executor.ts
|
|
14238
|
-
import
|
|
14442
|
+
import fs30 from "node:fs";
|
|
14239
14443
|
import os9 from "node:os";
|
|
14240
|
-
import
|
|
14444
|
+
import path29 from "node:path";
|
|
14241
14445
|
function signalStart(commandName) {
|
|
14242
14446
|
try {
|
|
14243
|
-
const dir =
|
|
14244
|
-
if (!
|
|
14245
|
-
|
|
14447
|
+
const dir = path29.dirname(RUNNING_FILE);
|
|
14448
|
+
if (!fs30.existsSync(dir)) {
|
|
14449
|
+
fs30.mkdirSync(dir, { recursive: true });
|
|
14246
14450
|
}
|
|
14247
|
-
|
|
14451
|
+
fs30.writeFileSync(RUNNING_FILE, `/p:${commandName}`);
|
|
14248
14452
|
} catch (_error) {
|
|
14249
14453
|
}
|
|
14250
14454
|
}
|
|
14251
14455
|
function signalEnd() {
|
|
14252
14456
|
try {
|
|
14253
|
-
if (
|
|
14254
|
-
|
|
14457
|
+
if (fs30.existsSync(RUNNING_FILE)) {
|
|
14458
|
+
fs30.unlinkSync(RUNNING_FILE);
|
|
14255
14459
|
}
|
|
14256
14460
|
} catch (_error) {
|
|
14257
14461
|
}
|
|
@@ -14273,7 +14477,7 @@ var init_command_executor = __esm({
|
|
|
14273
14477
|
init_template_executor();
|
|
14274
14478
|
init_template_loader();
|
|
14275
14479
|
init_tool_registry();
|
|
14276
|
-
RUNNING_FILE =
|
|
14480
|
+
RUNNING_FILE = path29.join(os9.homedir(), ".prjct-cli", ".running");
|
|
14277
14481
|
__name(signalStart, "signalStart");
|
|
14278
14482
|
__name(signalEnd, "signalEnd");
|
|
14279
14483
|
CommandExecutor = class {
|
|
@@ -14582,10 +14786,10 @@ var init_command_executor = __esm({
|
|
|
14582
14786
|
});
|
|
14583
14787
|
|
|
14584
14788
|
// core/infrastructure/update-checker.ts
|
|
14585
|
-
import
|
|
14789
|
+
import fs31 from "node:fs";
|
|
14586
14790
|
import https from "node:https";
|
|
14587
14791
|
import os10 from "node:os";
|
|
14588
|
-
import
|
|
14792
|
+
import path30 from "node:path";
|
|
14589
14793
|
import chalk8 from "chalk";
|
|
14590
14794
|
var UpdateChecker, update_checker_default;
|
|
14591
14795
|
var init_update_checker = __esm({
|
|
@@ -14601,8 +14805,8 @@ var init_update_checker = __esm({
|
|
|
14601
14805
|
checkInterval;
|
|
14602
14806
|
constructor() {
|
|
14603
14807
|
this.packageName = "prjct-cli";
|
|
14604
|
-
this.cacheDir =
|
|
14605
|
-
this.cacheFile =
|
|
14808
|
+
this.cacheDir = path30.join(os10.homedir(), ".prjct-cli", "config");
|
|
14809
|
+
this.cacheFile = path30.join(this.cacheDir, "update-cache.json");
|
|
14606
14810
|
this.checkInterval = 24 * 60 * 60 * 1e3;
|
|
14607
14811
|
}
|
|
14608
14812
|
/**
|
|
@@ -14610,8 +14814,8 @@ var init_update_checker = __esm({
|
|
|
14610
14814
|
*/
|
|
14611
14815
|
getCurrentVersion() {
|
|
14612
14816
|
try {
|
|
14613
|
-
const packageJsonPath =
|
|
14614
|
-
const packageJson = JSON.parse(
|
|
14817
|
+
const packageJsonPath = path30.join(__dirname, "..", "..", "package.json");
|
|
14818
|
+
const packageJson = JSON.parse(fs31.readFileSync(packageJsonPath, "utf8"));
|
|
14615
14819
|
return packageJson.version;
|
|
14616
14820
|
} catch (error) {
|
|
14617
14821
|
console.error("Error reading package version:", error.message);
|
|
@@ -14680,8 +14884,8 @@ var init_update_checker = __esm({
|
|
|
14680
14884
|
*/
|
|
14681
14885
|
readCache() {
|
|
14682
14886
|
try {
|
|
14683
|
-
if (
|
|
14684
|
-
const cache2 = JSON.parse(
|
|
14887
|
+
if (fs31.existsSync(this.cacheFile)) {
|
|
14888
|
+
const cache2 = JSON.parse(fs31.readFileSync(this.cacheFile, "utf8"));
|
|
14685
14889
|
return cache2;
|
|
14686
14890
|
}
|
|
14687
14891
|
} catch (_error) {
|
|
@@ -14693,10 +14897,10 @@ var init_update_checker = __esm({
|
|
|
14693
14897
|
*/
|
|
14694
14898
|
writeCache(data) {
|
|
14695
14899
|
try {
|
|
14696
|
-
if (!
|
|
14697
|
-
|
|
14900
|
+
if (!fs31.existsSync(this.cacheDir)) {
|
|
14901
|
+
fs31.mkdirSync(this.cacheDir, { recursive: true });
|
|
14698
14902
|
}
|
|
14699
|
-
|
|
14903
|
+
fs31.writeFileSync(this.cacheFile, JSON.stringify(data, null, 2), "utf8");
|
|
14700
14904
|
} catch (_error) {
|
|
14701
14905
|
}
|
|
14702
14906
|
}
|
|
@@ -14854,8 +15058,8 @@ var init_agent_generator = __esm({
|
|
|
14854
15058
|
});
|
|
14855
15059
|
|
|
14856
15060
|
// core/agentic/agent-router.ts
|
|
14857
|
-
import
|
|
14858
|
-
import
|
|
15061
|
+
import fs32 from "node:fs/promises";
|
|
15062
|
+
import path31 from "node:path";
|
|
14859
15063
|
var AgentRouter, agent_router_default;
|
|
14860
15064
|
var init_agent_router = __esm({
|
|
14861
15065
|
"core/agentic/agent-router.ts"() {
|
|
@@ -14884,12 +15088,12 @@ var init_agent_router = __esm({
|
|
|
14884
15088
|
async loadAvailableAgents() {
|
|
14885
15089
|
if (!this.agentsPath) return [];
|
|
14886
15090
|
try {
|
|
14887
|
-
const files = await
|
|
15091
|
+
const files = await fs32.readdir(this.agentsPath);
|
|
14888
15092
|
const agents = [];
|
|
14889
15093
|
for (const file of files) {
|
|
14890
15094
|
if (file.endsWith(".md")) {
|
|
14891
15095
|
const name = file.replace(".md", "");
|
|
14892
|
-
const content = await
|
|
15096
|
+
const content = await fs32.readFile(path31.join(this.agentsPath, file), "utf-8");
|
|
14893
15097
|
agents.push({ name, content });
|
|
14894
15098
|
}
|
|
14895
15099
|
}
|
|
@@ -14914,8 +15118,8 @@ var init_agent_router = __esm({
|
|
|
14914
15118
|
async loadAgent(name) {
|
|
14915
15119
|
if (!this.agentsPath) return null;
|
|
14916
15120
|
try {
|
|
14917
|
-
const filePath =
|
|
14918
|
-
const content = await
|
|
15121
|
+
const filePath = path31.join(this.agentsPath, `${name}.md`);
|
|
15122
|
+
const content = await fs32.readFile(filePath, "utf-8");
|
|
14919
15123
|
return { name, content };
|
|
14920
15124
|
} catch (error) {
|
|
14921
15125
|
if (!isNotFoundError(error)) {
|
|
@@ -14943,7 +15147,7 @@ var init_agent_router = __esm({
|
|
|
14943
15147
|
*/
|
|
14944
15148
|
async logUsage(task, agent, _projectPath) {
|
|
14945
15149
|
try {
|
|
14946
|
-
const logPath =
|
|
15150
|
+
const logPath = path31.join(
|
|
14947
15151
|
process.env.HOME || "",
|
|
14948
15152
|
".prjct-cli",
|
|
14949
15153
|
"projects",
|
|
@@ -14957,7 +15161,7 @@ var init_agent_router = __esm({
|
|
|
14957
15161
|
projectId: this.projectId
|
|
14958
15162
|
})}
|
|
14959
15163
|
`;
|
|
14960
|
-
await
|
|
15164
|
+
await fs32.appendFile(logPath, entry);
|
|
14961
15165
|
} catch (error) {
|
|
14962
15166
|
if (!isNotFoundError(error)) {
|
|
14963
15167
|
console.error(`Agent usage log error: ${error.message}`);
|
|
@@ -14970,15 +15174,15 @@ var init_agent_router = __esm({
|
|
|
14970
15174
|
});
|
|
14971
15175
|
|
|
14972
15176
|
// core/infrastructure/agent-detector.ts
|
|
14973
|
-
import
|
|
14974
|
-
import
|
|
15177
|
+
import fs33 from "node:fs";
|
|
15178
|
+
import path32 from "node:path";
|
|
14975
15179
|
function isClaudeEnvironment() {
|
|
14976
15180
|
if (process.env.CLAUDE_AGENT || process.env.ANTHROPIC_CLAUDE) return true;
|
|
14977
15181
|
if (global.mcp || process.env.MCP_AVAILABLE) return true;
|
|
14978
15182
|
const projectRoot = process.cwd();
|
|
14979
|
-
if (
|
|
15183
|
+
if (fs33.existsSync(path32.join(projectRoot, "CLAUDE.md"))) return true;
|
|
14980
15184
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
14981
|
-
if (
|
|
15185
|
+
if (fs33.existsSync(path32.join(homeDir, ".claude"))) return true;
|
|
14982
15186
|
const cwd = process.cwd();
|
|
14983
15187
|
if (cwd.includes("/.claude/") || cwd.includes("/claude-workspace/")) return true;
|
|
14984
15188
|
return false;
|
|
@@ -15626,7 +15830,7 @@ var init_context_selector = __esm({
|
|
|
15626
15830
|
});
|
|
15627
15831
|
|
|
15628
15832
|
// core/services/file-categorizer.ts
|
|
15629
|
-
import
|
|
15833
|
+
import path33 from "node:path";
|
|
15630
15834
|
var HEURISTIC_PATTERNS, FileCategorizer, fileCategorizer;
|
|
15631
15835
|
var init_file_categorizer = __esm({
|
|
15632
15836
|
"core/services/file-categorizer.ts"() {
|
|
@@ -15722,8 +15926,8 @@ var init_file_categorizer = __esm({
|
|
|
15722
15926
|
if (!domainPatterns.has(domain)) {
|
|
15723
15927
|
domainPatterns.set(domain, /* @__PURE__ */ new Set());
|
|
15724
15928
|
}
|
|
15725
|
-
const dir =
|
|
15726
|
-
domainPatterns.get(domain).add(`**/${
|
|
15929
|
+
const dir = path33.dirname(file.path);
|
|
15930
|
+
domainPatterns.get(domain).add(`**/${path33.basename(dir)}/**`);
|
|
15727
15931
|
}
|
|
15728
15932
|
}
|
|
15729
15933
|
}
|
|
@@ -15908,7 +16112,7 @@ var init_file_categorizer = __esm({
|
|
|
15908
16112
|
});
|
|
15909
16113
|
|
|
15910
16114
|
// core/services/file-scorer.ts
|
|
15911
|
-
import
|
|
16115
|
+
import path34 from "node:path";
|
|
15912
16116
|
var RELEVANCE_THRESHOLD, CONFIG_PATTERNS, IMPORTANT_NAME_PATTERNS, FileScorer, fileScorer;
|
|
15913
16117
|
var init_file_scorer = __esm({
|
|
15914
16118
|
"core/services/file-scorer.ts"() {
|
|
@@ -16043,7 +16247,7 @@ var init_file_scorer = __esm({
|
|
|
16043
16247
|
* Config files are always important
|
|
16044
16248
|
*/
|
|
16045
16249
|
calculateConfigRelevance(stats) {
|
|
16046
|
-
const filename =
|
|
16250
|
+
const filename = path34.basename(stats.path);
|
|
16047
16251
|
for (const pattern of CONFIG_PATTERNS) {
|
|
16048
16252
|
if (pattern.test(filename) || pattern.test(stats.path)) {
|
|
16049
16253
|
return 20;
|
|
@@ -16056,13 +16260,13 @@ var init_file_scorer = __esm({
|
|
|
16056
16260
|
* Certain filenames indicate importance
|
|
16057
16261
|
*/
|
|
16058
16262
|
calculateNameRelevance(stats) {
|
|
16059
|
-
const filename =
|
|
16263
|
+
const filename = path34.basename(stats.path);
|
|
16060
16264
|
for (const pattern of IMPORTANT_NAME_PATTERNS) {
|
|
16061
16265
|
if (pattern.test(filename)) {
|
|
16062
16266
|
return 15;
|
|
16063
16267
|
}
|
|
16064
16268
|
}
|
|
16065
|
-
const dir =
|
|
16269
|
+
const dir = path34.dirname(stats.path);
|
|
16066
16270
|
if (dir.includes("/api/") || dir.includes("/routes/")) return 10;
|
|
16067
16271
|
if (dir.includes("/components/") && filename.startsWith("index")) return 10;
|
|
16068
16272
|
if (dir.includes("/pages/") || dir.includes("/app/")) return 8;
|
|
@@ -16463,8 +16667,8 @@ var init_memory_service = __esm({
|
|
|
16463
16667
|
});
|
|
16464
16668
|
|
|
16465
16669
|
// core/services/nested-context-resolver.ts
|
|
16466
|
-
import
|
|
16467
|
-
import
|
|
16670
|
+
import fs34 from "node:fs/promises";
|
|
16671
|
+
import path35 from "node:path";
|
|
16468
16672
|
var NestedContextResolver;
|
|
16469
16673
|
var init_nested_context_resolver = __esm({
|
|
16470
16674
|
"core/services/nested-context-resolver.ts"() {
|
|
@@ -16478,7 +16682,7 @@ var init_nested_context_resolver = __esm({
|
|
|
16478
16682
|
rootPath;
|
|
16479
16683
|
monoInfo = null;
|
|
16480
16684
|
constructor(rootPath) {
|
|
16481
|
-
this.rootPath =
|
|
16685
|
+
this.rootPath = path35.resolve(rootPath);
|
|
16482
16686
|
}
|
|
16483
16687
|
/**
|
|
16484
16688
|
* Initialize the resolver with monorepo detection
|
|
@@ -16491,14 +16695,14 @@ var init_nested_context_resolver = __esm({
|
|
|
16491
16695
|
*/
|
|
16492
16696
|
async discoverContextFiles() {
|
|
16493
16697
|
const contexts = [];
|
|
16494
|
-
const rootPrjctPath =
|
|
16698
|
+
const rootPrjctPath = path35.join(this.rootPath, "PRJCT.md");
|
|
16495
16699
|
if (await fileExists(rootPrjctPath)) {
|
|
16496
16700
|
const rootContext = await this.loadContext(rootPrjctPath, null);
|
|
16497
16701
|
contexts.push(rootContext);
|
|
16498
16702
|
}
|
|
16499
16703
|
if (this.monoInfo?.isMonorepo) {
|
|
16500
16704
|
for (const pkg of this.monoInfo.packages) {
|
|
16501
|
-
const pkgPrjctPath =
|
|
16705
|
+
const pkgPrjctPath = path35.join(pkg.path, "PRJCT.md");
|
|
16502
16706
|
if (await fileExists(pkgPrjctPath)) {
|
|
16503
16707
|
const parentContext = contexts.find((c) => c.depth === 0) || null;
|
|
16504
16708
|
const pkgContext = await this.loadContext(pkgPrjctPath, parentContext, pkg);
|
|
@@ -16517,9 +16721,9 @@ var init_nested_context_resolver = __esm({
|
|
|
16517
16721
|
* Load a single PRJCT.md file into a NestedContext
|
|
16518
16722
|
*/
|
|
16519
16723
|
async loadContext(filePath, parent, pkg = null) {
|
|
16520
|
-
const content = await
|
|
16521
|
-
const relativePath =
|
|
16522
|
-
const depth = relativePath.split(
|
|
16724
|
+
const content = await fs34.readFile(filePath, "utf-8");
|
|
16725
|
+
const relativePath = path35.relative(this.rootPath, filePath);
|
|
16726
|
+
const depth = relativePath.split(path35.sep).length - 1;
|
|
16523
16727
|
return {
|
|
16524
16728
|
path: filePath,
|
|
16525
16729
|
relativePath,
|
|
@@ -16573,14 +16777,14 @@ var init_nested_context_resolver = __esm({
|
|
|
16573
16777
|
const scan = /* @__PURE__ */ __name(async (currentDir, depth) => {
|
|
16574
16778
|
if (depth > 5) return;
|
|
16575
16779
|
try {
|
|
16576
|
-
const entries = await
|
|
16780
|
+
const entries = await fs34.readdir(currentDir, { withFileTypes: true });
|
|
16577
16781
|
for (const entry of entries) {
|
|
16578
16782
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "coverage") {
|
|
16579
16783
|
continue;
|
|
16580
16784
|
}
|
|
16581
16785
|
if (entry.isDirectory()) {
|
|
16582
|
-
const subDir =
|
|
16583
|
-
const prjctPath =
|
|
16786
|
+
const subDir = path35.join(currentDir, entry.name);
|
|
16787
|
+
const prjctPath = path35.join(subDir, "PRJCT.md");
|
|
16584
16788
|
if (await fileExists(prjctPath) && !existingPaths.has(prjctPath)) {
|
|
16585
16789
|
const parent = this.findParentContext(prjctPath, existing.concat(found));
|
|
16586
16790
|
const context2 = await this.loadContext(prjctPath, parent);
|
|
@@ -16603,10 +16807,10 @@ var init_nested_context_resolver = __esm({
|
|
|
16603
16807
|
* Find the parent context for a given path
|
|
16604
16808
|
*/
|
|
16605
16809
|
findParentContext(filePath, contexts) {
|
|
16606
|
-
const fileDir =
|
|
16810
|
+
const fileDir = path35.dirname(filePath);
|
|
16607
16811
|
const sorted = [...contexts].sort((a, b) => b.depth - a.depth);
|
|
16608
16812
|
for (const ctx of sorted) {
|
|
16609
|
-
const ctxDir =
|
|
16813
|
+
const ctxDir = path35.dirname(ctx.path);
|
|
16610
16814
|
if (fileDir.startsWith(ctxDir) && fileDir !== ctxDir) {
|
|
16611
16815
|
return ctx;
|
|
16612
16816
|
}
|
|
@@ -16619,10 +16823,10 @@ var init_nested_context_resolver = __esm({
|
|
|
16619
16823
|
*/
|
|
16620
16824
|
async resolveContextForPath(targetPath) {
|
|
16621
16825
|
const contexts = await this.discoverContextFiles();
|
|
16622
|
-
const targetDir =
|
|
16826
|
+
const targetDir = path35.resolve(targetPath);
|
|
16623
16827
|
let bestMatch = null;
|
|
16624
16828
|
for (const ctx of contexts) {
|
|
16625
|
-
const ctxDir =
|
|
16829
|
+
const ctxDir = path35.dirname(ctx.path);
|
|
16626
16830
|
if (targetDir.startsWith(ctxDir)) {
|
|
16627
16831
|
if (!bestMatch || ctx.depth > bestMatch.depth) {
|
|
16628
16832
|
bestMatch = ctx;
|
|
@@ -16714,14 +16918,14 @@ ${content}`);
|
|
|
16714
16918
|
*/
|
|
16715
16919
|
async discoverAgentFiles() {
|
|
16716
16920
|
const agentFiles = [];
|
|
16717
|
-
const rootAgentsPath =
|
|
16921
|
+
const rootAgentsPath = path35.join(this.rootPath, "AGENTS.md");
|
|
16718
16922
|
if (await fileExists(rootAgentsPath)) {
|
|
16719
16923
|
const rootAgents = await this.loadAgents(rootAgentsPath, null);
|
|
16720
16924
|
agentFiles.push(rootAgents);
|
|
16721
16925
|
}
|
|
16722
16926
|
if (this.monoInfo?.isMonorepo) {
|
|
16723
16927
|
for (const pkg of this.monoInfo.packages) {
|
|
16724
|
-
const pkgAgentsPath =
|
|
16928
|
+
const pkgAgentsPath = path35.join(pkg.path, "AGENTS.md");
|
|
16725
16929
|
if (await fileExists(pkgAgentsPath)) {
|
|
16726
16930
|
const parentAgents = agentFiles.find((a) => a.depth === 0) || null;
|
|
16727
16931
|
const pkgAgents = await this.loadAgents(pkgAgentsPath, parentAgents, pkg);
|
|
@@ -16740,9 +16944,9 @@ ${content}`);
|
|
|
16740
16944
|
* Load a single AGENTS.md file into a NestedAgents structure
|
|
16741
16945
|
*/
|
|
16742
16946
|
async loadAgents(filePath, parent, pkg = null) {
|
|
16743
|
-
const content = await
|
|
16744
|
-
const relativePath =
|
|
16745
|
-
const depth = relativePath.split(
|
|
16947
|
+
const content = await fs34.readFile(filePath, "utf-8");
|
|
16948
|
+
const relativePath = path35.relative(this.rootPath, filePath);
|
|
16949
|
+
const depth = relativePath.split(path35.sep).length - 1;
|
|
16746
16950
|
return {
|
|
16747
16951
|
path: filePath,
|
|
16748
16952
|
relativePath,
|
|
@@ -16875,14 +17079,14 @@ ${content}`);
|
|
|
16875
17079
|
const scan = /* @__PURE__ */ __name(async (currentDir, depth) => {
|
|
16876
17080
|
if (depth > 5) return;
|
|
16877
17081
|
try {
|
|
16878
|
-
const entries = await
|
|
17082
|
+
const entries = await fs34.readdir(currentDir, { withFileTypes: true });
|
|
16879
17083
|
for (const entry of entries) {
|
|
16880
17084
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "coverage") {
|
|
16881
17085
|
continue;
|
|
16882
17086
|
}
|
|
16883
17087
|
if (entry.isDirectory()) {
|
|
16884
|
-
const subDir =
|
|
16885
|
-
const agentsPath =
|
|
17088
|
+
const subDir = path35.join(currentDir, entry.name);
|
|
17089
|
+
const agentsPath = path35.join(subDir, "AGENTS.md");
|
|
16886
17090
|
if (await fileExists(agentsPath) && !existingPaths.has(agentsPath)) {
|
|
16887
17091
|
const parent = this.findParentAgents(agentsPath, existing.concat(found));
|
|
16888
17092
|
const agents = await this.loadAgents(agentsPath, parent);
|
|
@@ -16905,10 +17109,10 @@ ${content}`);
|
|
|
16905
17109
|
* Find the parent agents file for a given path
|
|
16906
17110
|
*/
|
|
16907
17111
|
findParentAgents(filePath, agentFiles) {
|
|
16908
|
-
const fileDir =
|
|
17112
|
+
const fileDir = path35.dirname(filePath);
|
|
16909
17113
|
const sorted = [...agentFiles].sort((a, b) => b.depth - a.depth);
|
|
16910
17114
|
for (const agents of sorted) {
|
|
16911
|
-
const agentsDir =
|
|
17115
|
+
const agentsDir = path35.dirname(agents.path);
|
|
16912
17116
|
if (fileDir.startsWith(agentsDir) && fileDir !== agentsDir) {
|
|
16913
17117
|
return agents;
|
|
16914
17118
|
}
|
|
@@ -16921,10 +17125,10 @@ ${content}`);
|
|
|
16921
17125
|
*/
|
|
16922
17126
|
async resolveAgentsForPath(targetPath) {
|
|
16923
17127
|
const agentFiles = await this.discoverAgentFiles();
|
|
16924
|
-
const targetDir =
|
|
17128
|
+
const targetDir = path35.resolve(targetPath);
|
|
16925
17129
|
let bestMatch = null;
|
|
16926
17130
|
for (const agents of agentFiles) {
|
|
16927
|
-
const agentsDir =
|
|
17131
|
+
const agentsDir = path35.dirname(agents.path);
|
|
16928
17132
|
if (targetDir.startsWith(agentsDir)) {
|
|
16929
17133
|
if (!bestMatch || agents.depth > bestMatch.depth) {
|
|
16930
17134
|
bestMatch = agents;
|
|
@@ -17508,16 +17712,16 @@ var init_onboarding = __esm({
|
|
|
17508
17712
|
* Detect project type from file system
|
|
17509
17713
|
*/
|
|
17510
17714
|
async detectProjectType() {
|
|
17511
|
-
const
|
|
17512
|
-
const
|
|
17715
|
+
const fs52 = await import("node:fs/promises");
|
|
17716
|
+
const path61 = await import("node:path");
|
|
17513
17717
|
try {
|
|
17514
|
-
const files = await
|
|
17718
|
+
const files = await fs52.readdir(this.projectPath);
|
|
17515
17719
|
if (files.includes("turbo.json") || files.includes("lerna.json") || files.includes("nx.json")) {
|
|
17516
17720
|
return "monorepo";
|
|
17517
17721
|
}
|
|
17518
17722
|
if (files.includes("package.json")) {
|
|
17519
|
-
const pkgPath =
|
|
17520
|
-
const pkgContent = await
|
|
17723
|
+
const pkgPath = path61.join(this.projectPath, "package.json");
|
|
17724
|
+
const pkgContent = await fs52.readFile(pkgPath, "utf-8");
|
|
17521
17725
|
const pkg = JSON.parse(pkgContent);
|
|
17522
17726
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
17523
17727
|
if (pkg.bin) return "cli-tool";
|
|
@@ -17553,32 +17757,32 @@ var init_onboarding = __esm({
|
|
|
17553
17757
|
* Detect installed AI agents from config files
|
|
17554
17758
|
*/
|
|
17555
17759
|
async detectInstalledAgents() {
|
|
17556
|
-
const
|
|
17557
|
-
const
|
|
17760
|
+
const fs52 = await import("node:fs/promises");
|
|
17761
|
+
const path61 = await import("node:path");
|
|
17558
17762
|
const os17 = await import("node:os");
|
|
17559
17763
|
const agents = [];
|
|
17560
17764
|
try {
|
|
17561
|
-
await
|
|
17765
|
+
await fs52.access(path61.join(os17.homedir(), ".claude"));
|
|
17562
17766
|
agents.push("claude");
|
|
17563
17767
|
} catch {
|
|
17564
17768
|
}
|
|
17565
17769
|
try {
|
|
17566
|
-
await
|
|
17770
|
+
await fs52.access(path61.join(this.projectPath, ".cursorrules"));
|
|
17567
17771
|
agents.push("cursor");
|
|
17568
17772
|
} catch {
|
|
17569
17773
|
}
|
|
17570
17774
|
try {
|
|
17571
|
-
await
|
|
17775
|
+
await fs52.access(path61.join(this.projectPath, ".windsurfrules"));
|
|
17572
17776
|
agents.push("windsurf");
|
|
17573
17777
|
} catch {
|
|
17574
17778
|
}
|
|
17575
17779
|
try {
|
|
17576
|
-
await
|
|
17780
|
+
await fs52.access(path61.join(this.projectPath, ".github", "copilot-instructions.md"));
|
|
17577
17781
|
agents.push("copilot");
|
|
17578
17782
|
} catch {
|
|
17579
17783
|
}
|
|
17580
17784
|
try {
|
|
17581
|
-
await
|
|
17785
|
+
await fs52.access(path61.join(os17.homedir(), ".gemini"));
|
|
17582
17786
|
agents.push("gemini");
|
|
17583
17787
|
} catch {
|
|
17584
17788
|
}
|
|
@@ -17588,17 +17792,17 @@ var init_onboarding = __esm({
|
|
|
17588
17792
|
* Detect tech stack from project files
|
|
17589
17793
|
*/
|
|
17590
17794
|
async detectStack() {
|
|
17591
|
-
const
|
|
17592
|
-
const
|
|
17795
|
+
const fs52 = await import("node:fs/promises");
|
|
17796
|
+
const path61 = await import("node:path");
|
|
17593
17797
|
const stack = {
|
|
17594
17798
|
language: "Unknown",
|
|
17595
17799
|
technologies: []
|
|
17596
17800
|
};
|
|
17597
17801
|
try {
|
|
17598
|
-
const files = await
|
|
17802
|
+
const files = await fs52.readdir(this.projectPath);
|
|
17599
17803
|
if (files.includes("package.json")) {
|
|
17600
|
-
const pkgPath =
|
|
17601
|
-
const pkgContent = await
|
|
17804
|
+
const pkgPath = path61.join(this.projectPath, "package.json");
|
|
17805
|
+
const pkgContent = await fs52.readFile(pkgPath, "utf-8");
|
|
17602
17806
|
const pkg = JSON.parse(pkgContent);
|
|
17603
17807
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
17604
17808
|
stack.language = deps.typescript ? "TypeScript" : "JavaScript";
|
|
@@ -17705,14 +17909,14 @@ var init_wizard = __esm({
|
|
|
17705
17909
|
|
|
17706
17910
|
// core/context/generator.ts
|
|
17707
17911
|
import { exec as exec9 } from "node:child_process";
|
|
17708
|
-
import
|
|
17709
|
-
import
|
|
17912
|
+
import fs35 from "node:fs/promises";
|
|
17913
|
+
import path36 from "node:path";
|
|
17710
17914
|
import { promisify as promisify9 } from "node:util";
|
|
17711
17915
|
async function generateContext(projectId, repoPath) {
|
|
17712
17916
|
const _globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
17713
17917
|
const contextPath = path_manager_default.getContextPath(projectId);
|
|
17714
17918
|
const storage = getStorage(projectId);
|
|
17715
|
-
await
|
|
17919
|
+
await fs35.mkdir(contextPath, { recursive: true });
|
|
17716
17920
|
const project = await storage.read(["project"]) || {};
|
|
17717
17921
|
const taskPaths = await storage.list(["task"]);
|
|
17718
17922
|
const featurePaths = await storage.list(["feature"]);
|
|
@@ -17794,8 +17998,8 @@ async function getPackageData(repoPath) {
|
|
|
17794
17998
|
scripts: {}
|
|
17795
17999
|
};
|
|
17796
18000
|
try {
|
|
17797
|
-
const pkgPath =
|
|
17798
|
-
const pkg = JSON.parse(await
|
|
18001
|
+
const pkgPath = path36.join(repoPath, "package.json");
|
|
18002
|
+
const pkg = JSON.parse(await fs35.readFile(pkgPath, "utf-8"));
|
|
17799
18003
|
data.dependencies = pkg.dependencies || {};
|
|
17800
18004
|
data.devDependencies = pkg.devDependencies || {};
|
|
17801
18005
|
data.scripts = pkg.scripts || {};
|
|
@@ -17804,7 +18008,7 @@ async function getPackageData(repoPath) {
|
|
|
17804
18008
|
return data;
|
|
17805
18009
|
}
|
|
17806
18010
|
async function generateClaudeMd(contextPath, projectId, project, tasks, features, ideas, agents, gitData, pkgData, repoPath) {
|
|
17807
|
-
const projectName = project.name ||
|
|
18011
|
+
const projectName = project.name || path36.basename(repoPath);
|
|
17808
18012
|
const currentTask = tasks.find((t) => t.status === "in_progress");
|
|
17809
18013
|
const pendingTasks = tasks.filter((t) => t.status === "pending");
|
|
17810
18014
|
const activeFeatures = features.filter((f) => f.status === "in_progress" || f.status === "active");
|
|
@@ -17879,7 +18083,7 @@ ${agents.length > 0 ? agents.map((a) => `- **${a.name}**: ${a.role || "Specialis
|
|
|
17879
18083
|
\u2514\u2500\u2500 pending.json
|
|
17880
18084
|
\`\`\`
|
|
17881
18085
|
`;
|
|
17882
|
-
await
|
|
18086
|
+
await fs35.writeFile(path36.join(contextPath, "CLAUDE.md"), content, "utf-8");
|
|
17883
18087
|
}
|
|
17884
18088
|
async function generateNowMd(contextPath, tasks) {
|
|
17885
18089
|
const currentTask = tasks.find((t) => t.status === "in_progress");
|
|
@@ -17894,7 +18098,7 @@ async function generateNowMd(contextPath, tasks) {
|
|
|
17894
18098
|
|
|
17895
18099
|
_No active task. Use /p:now to start._
|
|
17896
18100
|
`;
|
|
17897
|
-
await
|
|
18101
|
+
await fs35.writeFile(path36.join(contextPath, "now.md"), content, "utf-8");
|
|
17898
18102
|
}
|
|
17899
18103
|
async function generateQueueMd(contextPath, tasks) {
|
|
17900
18104
|
const pendingTasks = tasks.filter((t) => t.status === "pending");
|
|
@@ -17902,7 +18106,7 @@ async function generateQueueMd(contextPath, tasks) {
|
|
|
17902
18106
|
|
|
17903
18107
|
${pendingTasks.length > 0 ? pendingTasks.map((t, i) => `${i + 1}. ${t.description}${t.priority ? ` [${t.priority}]` : ""}`).join("\n") : "_Empty queue. Use /p:next to add tasks._"}
|
|
17904
18108
|
`;
|
|
17905
|
-
await
|
|
18109
|
+
await fs35.writeFile(path36.join(contextPath, "queue.md"), content, "utf-8");
|
|
17906
18110
|
}
|
|
17907
18111
|
async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
17908
18112
|
const content = `# PROJECT SUMMARY
|
|
@@ -17922,7 +18126,7 @@ async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
|
17922
18126
|
- Production: ${Object.keys(pkgData.dependencies).length}
|
|
17923
18127
|
- Dev: ${Object.keys(pkgData.devDependencies).length}
|
|
17924
18128
|
`;
|
|
17925
|
-
await
|
|
18129
|
+
await fs35.writeFile(path36.join(contextPath, "summary.md"), content, "utf-8");
|
|
17926
18130
|
}
|
|
17927
18131
|
var execAsync5;
|
|
17928
18132
|
var init_generator = __esm({
|
|
@@ -17943,8 +18147,8 @@ var init_generator = __esm({
|
|
|
17943
18147
|
|
|
17944
18148
|
// core/domain/analyzer.ts
|
|
17945
18149
|
import { exec as execCallback5 } from "node:child_process";
|
|
17946
|
-
import
|
|
17947
|
-
import
|
|
18150
|
+
import fs36 from "node:fs/promises";
|
|
18151
|
+
import path37 from "node:path";
|
|
17948
18152
|
import { promisify as promisify10 } from "node:util";
|
|
17949
18153
|
var exec10, CodebaseAnalyzer, analyzer, analyzer_default2;
|
|
17950
18154
|
var init_analyzer2 = __esm({
|
|
@@ -17968,8 +18172,8 @@ var init_analyzer2 = __esm({
|
|
|
17968
18172
|
*/
|
|
17969
18173
|
async readPackageJson() {
|
|
17970
18174
|
try {
|
|
17971
|
-
const packagePath =
|
|
17972
|
-
const content = await
|
|
18175
|
+
const packagePath = path37.join(this.projectPath, "package.json");
|
|
18176
|
+
const content = await fs36.readFile(packagePath, "utf-8");
|
|
17973
18177
|
return JSON.parse(content);
|
|
17974
18178
|
} catch (error) {
|
|
17975
18179
|
if (isNotFoundError(error) || error instanceof SyntaxError) {
|
|
@@ -17983,8 +18187,8 @@ var init_analyzer2 = __esm({
|
|
|
17983
18187
|
*/
|
|
17984
18188
|
async readCargoToml() {
|
|
17985
18189
|
try {
|
|
17986
|
-
const cargoPath =
|
|
17987
|
-
return await
|
|
18190
|
+
const cargoPath = path37.join(this.projectPath, "Cargo.toml");
|
|
18191
|
+
return await fs36.readFile(cargoPath, "utf-8");
|
|
17988
18192
|
} catch (error) {
|
|
17989
18193
|
if (isNotFoundError(error)) {
|
|
17990
18194
|
return null;
|
|
@@ -17997,8 +18201,8 @@ var init_analyzer2 = __esm({
|
|
|
17997
18201
|
*/
|
|
17998
18202
|
async readRequirements() {
|
|
17999
18203
|
try {
|
|
18000
|
-
const reqPath =
|
|
18001
|
-
return await
|
|
18204
|
+
const reqPath = path37.join(this.projectPath, "requirements.txt");
|
|
18205
|
+
return await fs36.readFile(reqPath, "utf-8");
|
|
18002
18206
|
} catch (error) {
|
|
18003
18207
|
if (isNotFoundError(error)) {
|
|
18004
18208
|
return null;
|
|
@@ -18011,8 +18215,8 @@ var init_analyzer2 = __esm({
|
|
|
18011
18215
|
*/
|
|
18012
18216
|
async readGoMod() {
|
|
18013
18217
|
try {
|
|
18014
|
-
const goModPath =
|
|
18015
|
-
return await
|
|
18218
|
+
const goModPath = path37.join(this.projectPath, "go.mod");
|
|
18219
|
+
return await fs36.readFile(goModPath, "utf-8");
|
|
18016
18220
|
} catch (error) {
|
|
18017
18221
|
if (isNotFoundError(error)) {
|
|
18018
18222
|
return null;
|
|
@@ -18025,8 +18229,8 @@ var init_analyzer2 = __esm({
|
|
|
18025
18229
|
*/
|
|
18026
18230
|
async readGemfile() {
|
|
18027
18231
|
try {
|
|
18028
|
-
const gemfilePath =
|
|
18029
|
-
return await
|
|
18232
|
+
const gemfilePath = path37.join(this.projectPath, "Gemfile");
|
|
18233
|
+
return await fs36.readFile(gemfilePath, "utf-8");
|
|
18030
18234
|
} catch (error) {
|
|
18031
18235
|
if (isNotFoundError(error)) {
|
|
18032
18236
|
return null;
|
|
@@ -18039,8 +18243,8 @@ var init_analyzer2 = __esm({
|
|
|
18039
18243
|
*/
|
|
18040
18244
|
async readMixExs() {
|
|
18041
18245
|
try {
|
|
18042
|
-
const mixPath =
|
|
18043
|
-
return await
|
|
18246
|
+
const mixPath = path37.join(this.projectPath, "mix.exs");
|
|
18247
|
+
return await fs36.readFile(mixPath, "utf-8");
|
|
18044
18248
|
} catch (error) {
|
|
18045
18249
|
if (isNotFoundError(error)) {
|
|
18046
18250
|
return null;
|
|
@@ -18053,8 +18257,8 @@ var init_analyzer2 = __esm({
|
|
|
18053
18257
|
*/
|
|
18054
18258
|
async readPomXml() {
|
|
18055
18259
|
try {
|
|
18056
|
-
const pomPath =
|
|
18057
|
-
return await
|
|
18260
|
+
const pomPath = path37.join(this.projectPath, "pom.xml");
|
|
18261
|
+
return await fs36.readFile(pomPath, "utf-8");
|
|
18058
18262
|
} catch (error) {
|
|
18059
18263
|
if (isNotFoundError(error)) {
|
|
18060
18264
|
return null;
|
|
@@ -18067,8 +18271,8 @@ var init_analyzer2 = __esm({
|
|
|
18067
18271
|
*/
|
|
18068
18272
|
async readComposerJson() {
|
|
18069
18273
|
try {
|
|
18070
|
-
const composerPath =
|
|
18071
|
-
const content = await
|
|
18274
|
+
const composerPath = path37.join(this.projectPath, "composer.json");
|
|
18275
|
+
const content = await fs36.readFile(composerPath, "utf-8");
|
|
18072
18276
|
return JSON.parse(content);
|
|
18073
18277
|
} catch (error) {
|
|
18074
18278
|
if (isNotFoundError(error) || error instanceof SyntaxError) {
|
|
@@ -18082,8 +18286,8 @@ var init_analyzer2 = __esm({
|
|
|
18082
18286
|
*/
|
|
18083
18287
|
async readPyprojectToml() {
|
|
18084
18288
|
try {
|
|
18085
|
-
const pyprojectPath =
|
|
18086
|
-
return await
|
|
18289
|
+
const pyprojectPath = path37.join(this.projectPath, "pyproject.toml");
|
|
18290
|
+
return await fs36.readFile(pyprojectPath, "utf-8");
|
|
18087
18291
|
} catch (error) {
|
|
18088
18292
|
if (isNotFoundError(error)) {
|
|
18089
18293
|
return null;
|
|
@@ -18119,7 +18323,7 @@ var init_analyzer2 = __esm({
|
|
|
18119
18323
|
*/
|
|
18120
18324
|
async listConfigFiles() {
|
|
18121
18325
|
try {
|
|
18122
|
-
const entries = await
|
|
18326
|
+
const entries = await fs36.readdir(this.projectPath);
|
|
18123
18327
|
const configPatterns = [
|
|
18124
18328
|
/^package\.json$/,
|
|
18125
18329
|
/^Cargo\.toml$/,
|
|
@@ -18149,7 +18353,7 @@ var init_analyzer2 = __esm({
|
|
|
18149
18353
|
*/
|
|
18150
18354
|
async listDirectories() {
|
|
18151
18355
|
try {
|
|
18152
|
-
const entries = await
|
|
18356
|
+
const entries = await fs36.readdir(this.projectPath, { withFileTypes: true });
|
|
18153
18357
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => !name.startsWith(".") && name !== "node_modules");
|
|
18154
18358
|
} catch (error) {
|
|
18155
18359
|
if (isNotFoundError(error)) {
|
|
@@ -18220,7 +18424,7 @@ var init_analyzer2 = __esm({
|
|
|
18220
18424
|
*/
|
|
18221
18425
|
async fileExists(filename) {
|
|
18222
18426
|
try {
|
|
18223
|
-
await
|
|
18427
|
+
await fs36.access(path37.join(this.projectPath, filename));
|
|
18224
18428
|
return true;
|
|
18225
18429
|
} catch (error) {
|
|
18226
18430
|
if (isNotFoundError(error)) {
|
|
@@ -18234,8 +18438,8 @@ var init_analyzer2 = __esm({
|
|
|
18234
18438
|
*/
|
|
18235
18439
|
async readFile(relativePath) {
|
|
18236
18440
|
try {
|
|
18237
|
-
const fullPath =
|
|
18238
|
-
return await
|
|
18441
|
+
const fullPath = path37.join(this.projectPath, relativePath);
|
|
18442
|
+
return await fs36.readFile(fullPath, "utf-8");
|
|
18239
18443
|
} catch (error) {
|
|
18240
18444
|
if (isNotFoundError(error)) {
|
|
18241
18445
|
return null;
|
|
@@ -18483,8 +18687,8 @@ var analysis_exports = {};
|
|
|
18483
18687
|
__export(analysis_exports, {
|
|
18484
18688
|
AnalysisCommands: () => AnalysisCommands
|
|
18485
18689
|
});
|
|
18486
|
-
import
|
|
18487
|
-
import
|
|
18690
|
+
import fs37 from "node:fs/promises";
|
|
18691
|
+
import path38 from "node:path";
|
|
18488
18692
|
import prompts2 from "prompts";
|
|
18489
18693
|
var AnalysisCommands;
|
|
18490
18694
|
var init_analysis2 = __esm({
|
|
@@ -18571,7 +18775,7 @@ var init_analysis2 = __esm({
|
|
|
18571
18775
|
lines.push("# Repository Analysis\n");
|
|
18572
18776
|
lines.push(`Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
18573
18777
|
`);
|
|
18574
|
-
const projectName =
|
|
18778
|
+
const projectName = path38.basename(projectPath);
|
|
18575
18779
|
lines.push(`## Project: ${projectName}
|
|
18576
18780
|
`);
|
|
18577
18781
|
lines.push("## Stack Detected\n");
|
|
@@ -18711,10 +18915,10 @@ var init_analysis2 = __esm({
|
|
|
18711
18915
|
}
|
|
18712
18916
|
return { success: result2.success };
|
|
18713
18917
|
}
|
|
18714
|
-
const claudeMdPath =
|
|
18918
|
+
const claudeMdPath = path38.join(globalPath, "context", "CLAUDE.md");
|
|
18715
18919
|
let existingContent = null;
|
|
18716
18920
|
try {
|
|
18717
|
-
existingContent = await
|
|
18921
|
+
existingContent = await fs37.readFile(claudeMdPath, "utf-8");
|
|
18718
18922
|
} catch {
|
|
18719
18923
|
}
|
|
18720
18924
|
const isNonInteractive = !process.stdin.isTTY || options.json;
|
|
@@ -18733,7 +18937,7 @@ var init_analysis2 = __esm({
|
|
|
18733
18937
|
}
|
|
18734
18938
|
let newContent;
|
|
18735
18939
|
try {
|
|
18736
|
-
newContent = await
|
|
18940
|
+
newContent = await fs37.readFile(claudeMdPath, "utf-8");
|
|
18737
18941
|
} catch {
|
|
18738
18942
|
newContent = "";
|
|
18739
18943
|
}
|
|
@@ -18944,7 +19148,7 @@ ${formatFullDiff(diff)}`);
|
|
|
18944
19148
|
let projectName = "Unknown";
|
|
18945
19149
|
try {
|
|
18946
19150
|
const projectJson = JSON.parse(
|
|
18947
|
-
await
|
|
19151
|
+
await fs37.readFile(path38.join(globalPath, "project.json"), "utf-8")
|
|
18948
19152
|
);
|
|
18949
19153
|
projectName = projectJson.name || "Unknown";
|
|
18950
19154
|
} catch {
|
|
@@ -19063,19 +19267,23 @@ ${formatFullDiff(diff)}`);
|
|
|
19063
19267
|
}
|
|
19064
19268
|
const checker = createStalenessChecker(projectPath);
|
|
19065
19269
|
const status = await checker.check(projectId);
|
|
19270
|
+
const sessionInfo = await checker.getSessionInfo(projectId);
|
|
19066
19271
|
if (options.json) {
|
|
19067
19272
|
console.log(
|
|
19068
19273
|
JSON.stringify({
|
|
19069
19274
|
success: true,
|
|
19070
|
-
...status
|
|
19275
|
+
...status,
|
|
19276
|
+
session: sessionInfo
|
|
19071
19277
|
})
|
|
19072
19278
|
);
|
|
19073
|
-
return { success: true, data: status };
|
|
19279
|
+
return { success: true, data: { ...status, session: sessionInfo } };
|
|
19074
19280
|
}
|
|
19075
19281
|
console.log("");
|
|
19076
19282
|
console.log(checker.formatStatus(status));
|
|
19077
19283
|
console.log("");
|
|
19078
|
-
|
|
19284
|
+
console.log(checker.formatSessionInfo(sessionInfo));
|
|
19285
|
+
console.log("");
|
|
19286
|
+
return { success: true, data: { ...status, session: sessionInfo } };
|
|
19079
19287
|
} catch (error) {
|
|
19080
19288
|
const errMsg = error.message;
|
|
19081
19289
|
if (options.json) {
|
|
@@ -19241,7 +19449,7 @@ var planning_exports = {};
|
|
|
19241
19449
|
__export(planning_exports, {
|
|
19242
19450
|
PlanningCommands: () => PlanningCommands
|
|
19243
19451
|
});
|
|
19244
|
-
import
|
|
19452
|
+
import path39 from "node:path";
|
|
19245
19453
|
async function getAnalysisCommands() {
|
|
19246
19454
|
if (!_analysisCommands) {
|
|
19247
19455
|
const { AnalysisCommands: AnalysisCommands2 } = await Promise.resolve().then(() => (init_analysis2(), analysis_exports));
|
|
@@ -19348,7 +19556,7 @@ var init_planning = __esm({
|
|
|
19348
19556
|
);
|
|
19349
19557
|
}
|
|
19350
19558
|
for (const [filePath, content] of Object.entries(baseFiles)) {
|
|
19351
|
-
await tool_registry_default.get("Write")(
|
|
19559
|
+
await tool_registry_default.get("Write")(path39.join(globalPath, filePath), content);
|
|
19352
19560
|
}
|
|
19353
19561
|
const isEmpty = await this._detectEmptyDirectory(projectPath);
|
|
19354
19562
|
const hasCode = await this._detectExistingCode(projectPath);
|
|
@@ -19375,7 +19583,7 @@ var init_planning = __esm({
|
|
|
19375
19583
|
return { success: true, mode: "blank_no_idea", projectId, wizard: wizardResult };
|
|
19376
19584
|
}
|
|
19377
19585
|
output_default.spin("architect mode...");
|
|
19378
|
-
const sessionPath =
|
|
19586
|
+
const sessionPath = path39.join(globalPath, "planning", "architect-session.md");
|
|
19379
19587
|
const sessionContent = `# Architect Session
|
|
19380
19588
|
|
|
19381
19589
|
## Idea
|
|
@@ -19561,7 +19769,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
19561
19769
|
if (!initResult.success) return initResult;
|
|
19562
19770
|
console.log("\u{1F3D7}\uFE0F Architect Mode - Code Generation\n");
|
|
19563
19771
|
const globalPath = await this.getGlobalProjectPath(projectPath);
|
|
19564
|
-
const planPath =
|
|
19772
|
+
const planPath = path39.join(globalPath, "planning", "architect-session.md");
|
|
19565
19773
|
let planContent;
|
|
19566
19774
|
try {
|
|
19567
19775
|
planContent = await file_helper_exports.readFile(planPath);
|
|
@@ -19636,7 +19844,7 @@ ${"=".repeat(60)}`);
|
|
|
19636
19844
|
if (isComplex) {
|
|
19637
19845
|
output_default.spin("analyzing idea...");
|
|
19638
19846
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
19639
|
-
const sessionPath =
|
|
19847
|
+
const sessionPath = path39.join(globalPath, "planning", "architect-session.md");
|
|
19640
19848
|
const sessionContent = `# Architect Session
|
|
19641
19849
|
|
|
19642
19850
|
## Idea
|
|
@@ -19692,10 +19900,10 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
19692
19900
|
if (!featureName) {
|
|
19693
19901
|
output_default.spin("loading specs...");
|
|
19694
19902
|
const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
|
|
19695
|
-
const specsPath2 =
|
|
19903
|
+
const specsPath2 = path39.join(globalPath2, "planning", "specs");
|
|
19696
19904
|
try {
|
|
19697
|
-
const
|
|
19698
|
-
const files = await
|
|
19905
|
+
const fs52 = await import("node:fs/promises");
|
|
19906
|
+
const files = await fs52.readdir(specsPath2);
|
|
19699
19907
|
const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
|
|
19700
19908
|
if (specs.length === 0) {
|
|
19701
19909
|
output_default.warn("no specs yet");
|
|
@@ -19718,10 +19926,10 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
19718
19926
|
}
|
|
19719
19927
|
output_default.spin("creating spec...");
|
|
19720
19928
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
19721
|
-
const specsPath =
|
|
19929
|
+
const specsPath = path39.join(globalPath, "planning", "specs");
|
|
19722
19930
|
await file_helper_exports.ensureDir(specsPath);
|
|
19723
19931
|
const slug = featureName.toLowerCase().replace(/\s+/g, "-");
|
|
19724
|
-
const specFile =
|
|
19932
|
+
const specFile = path39.join(specsPath, `${slug}.md`);
|
|
19725
19933
|
const specContent = `# Specification: ${featureName}
|
|
19726
19934
|
|
|
19727
19935
|
## Overview
|
|
@@ -19909,14 +20117,15 @@ var init_project_service = __esm({
|
|
|
19909
20117
|
|
|
19910
20118
|
// core/services/staleness-checker.ts
|
|
19911
20119
|
import { exec as exec11 } from "node:child_process";
|
|
19912
|
-
import
|
|
19913
|
-
import
|
|
20120
|
+
import fs38 from "node:fs/promises";
|
|
20121
|
+
import path40 from "node:path";
|
|
19914
20122
|
import { promisify as promisify11 } from "node:util";
|
|
19915
20123
|
var execAsync6, DEFAULT_CONFIG, StalenessChecker, createStalenessChecker;
|
|
19916
20124
|
var init_staleness_checker = __esm({
|
|
19917
20125
|
"core/services/staleness-checker.ts"() {
|
|
19918
20126
|
"use strict";
|
|
19919
20127
|
init_path_manager();
|
|
20128
|
+
init_session_tracker();
|
|
19920
20129
|
execAsync6 = promisify11(exec11);
|
|
19921
20130
|
DEFAULT_CONFIG = {
|
|
19922
20131
|
commitThreshold: 10,
|
|
@@ -19958,10 +20167,10 @@ var init_staleness_checker = __esm({
|
|
|
19958
20167
|
significantChanges: []
|
|
19959
20168
|
};
|
|
19960
20169
|
try {
|
|
19961
|
-
const projectJsonPath =
|
|
20170
|
+
const projectJsonPath = path40.join(path_manager_default.getGlobalProjectPath(projectId), "project.json");
|
|
19962
20171
|
let projectJson = {};
|
|
19963
20172
|
try {
|
|
19964
|
-
projectJson = JSON.parse(await
|
|
20173
|
+
projectJson = JSON.parse(await fs38.readFile(projectJsonPath, "utf-8"));
|
|
19965
20174
|
} catch {
|
|
19966
20175
|
status.isStale = true;
|
|
19967
20176
|
status.reason = "No sync history found. Run `prjct sync` to initialize.";
|
|
@@ -20090,6 +20299,49 @@ var init_staleness_checker = __esm({
|
|
|
20090
20299
|
}
|
|
20091
20300
|
return lines.join("\n");
|
|
20092
20301
|
}
|
|
20302
|
+
/**
|
|
20303
|
+
* Get session info for the project
|
|
20304
|
+
*/
|
|
20305
|
+
async getSessionInfo(projectId) {
|
|
20306
|
+
return sessionTracker.getInfo(projectId);
|
|
20307
|
+
}
|
|
20308
|
+
/**
|
|
20309
|
+
* Format session info for display
|
|
20310
|
+
*/
|
|
20311
|
+
formatSessionInfo(info) {
|
|
20312
|
+
const lines = [];
|
|
20313
|
+
if (!info.active) {
|
|
20314
|
+
lines.push("Session: \u25CB No active session");
|
|
20315
|
+
return lines.join("\n");
|
|
20316
|
+
}
|
|
20317
|
+
lines.push(`Session: \u25B6 Active (${info.duration})`);
|
|
20318
|
+
const details = [];
|
|
20319
|
+
if (info.commandCount > 0) {
|
|
20320
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20321
|
+
const unique = [];
|
|
20322
|
+
for (const cmd of info.commands) {
|
|
20323
|
+
if (!seen.has(cmd)) {
|
|
20324
|
+
seen.add(cmd);
|
|
20325
|
+
unique.push(cmd);
|
|
20326
|
+
}
|
|
20327
|
+
}
|
|
20328
|
+
details.push(`Commands: ${unique.join(" \u2192 ")} (${info.commandCount} total)`);
|
|
20329
|
+
}
|
|
20330
|
+
if (info.filesRead > 0 || info.filesWritten > 0) {
|
|
20331
|
+
details.push(`Files: ${info.filesRead} read, ${info.filesWritten} written`);
|
|
20332
|
+
}
|
|
20333
|
+
details.push(`Idle: ${info.expiresIn} until timeout`);
|
|
20334
|
+
if (details.length > 0) {
|
|
20335
|
+
const maxLen = Math.max(...details.map((l) => l.length));
|
|
20336
|
+
const border = "\u2500".repeat(maxLen + 2);
|
|
20337
|
+
lines.push(`\u250C${border}\u2510`);
|
|
20338
|
+
for (const detail of details) {
|
|
20339
|
+
lines.push(`\u2502 ${detail.padEnd(maxLen)} \u2502`);
|
|
20340
|
+
}
|
|
20341
|
+
lines.push(`\u2514${border}\u2518`);
|
|
20342
|
+
}
|
|
20343
|
+
return lines.join("\n");
|
|
20344
|
+
}
|
|
20093
20345
|
/**
|
|
20094
20346
|
* Get a short warning message if stale (for other commands)
|
|
20095
20347
|
*/
|
|
@@ -20338,9 +20590,9 @@ var init_formatters = __esm({
|
|
|
20338
20590
|
|
|
20339
20591
|
// core/ai-tools/registry.ts
|
|
20340
20592
|
import { execSync as execSync4 } from "node:child_process";
|
|
20341
|
-
import
|
|
20593
|
+
import fs39 from "node:fs";
|
|
20342
20594
|
import os11 from "node:os";
|
|
20343
|
-
import
|
|
20595
|
+
import path41 from "node:path";
|
|
20344
20596
|
function getAIToolConfig(id) {
|
|
20345
20597
|
return AI_TOOLS[id] || null;
|
|
20346
20598
|
}
|
|
@@ -20357,16 +20609,16 @@ function detectInstalledTools(repoPath = process.cwd()) {
|
|
|
20357
20609
|
if (commandExists("claude")) {
|
|
20358
20610
|
detected.push("claude");
|
|
20359
20611
|
}
|
|
20360
|
-
if (commandExists("cursor") ||
|
|
20612
|
+
if (commandExists("cursor") || fs39.existsSync(path41.join(repoPath, ".cursor"))) {
|
|
20361
20613
|
detected.push("cursor");
|
|
20362
20614
|
}
|
|
20363
|
-
if (
|
|
20615
|
+
if (fs39.existsSync(path41.join(repoPath, ".github"))) {
|
|
20364
20616
|
detected.push("copilot");
|
|
20365
20617
|
}
|
|
20366
|
-
if (commandExists("windsurf") ||
|
|
20618
|
+
if (commandExists("windsurf") || fs39.existsSync(path41.join(repoPath, ".windsurf"))) {
|
|
20367
20619
|
detected.push("windsurf");
|
|
20368
20620
|
}
|
|
20369
|
-
if (
|
|
20621
|
+
if (fs39.existsSync(path41.join(repoPath, ".continue")) || fs39.existsSync(path41.join(os11.homedir(), ".continue"))) {
|
|
20370
20622
|
detected.push("continue");
|
|
20371
20623
|
}
|
|
20372
20624
|
return detected;
|
|
@@ -20442,8 +20694,8 @@ var init_registry = __esm({
|
|
|
20442
20694
|
});
|
|
20443
20695
|
|
|
20444
20696
|
// core/ai-tools/generator.ts
|
|
20445
|
-
import
|
|
20446
|
-
import
|
|
20697
|
+
import fs40 from "node:fs/promises";
|
|
20698
|
+
import path42 from "node:path";
|
|
20447
20699
|
async function generateAIToolContexts(context2, globalPath, repoPath, toolIds = DEFAULT_AI_TOOLS) {
|
|
20448
20700
|
const results = [];
|
|
20449
20701
|
for (const toolId of toolIds) {
|
|
@@ -20478,13 +20730,13 @@ async function generateForTool(context2, config, globalPath, repoPath) {
|
|
|
20478
20730
|
let content = formatter(context2, config);
|
|
20479
20731
|
let outputPath;
|
|
20480
20732
|
if (config.outputPath === "repo") {
|
|
20481
|
-
outputPath =
|
|
20733
|
+
outputPath = path42.join(repoPath, config.outputFile);
|
|
20482
20734
|
} else {
|
|
20483
|
-
outputPath =
|
|
20735
|
+
outputPath = path42.join(globalPath, "context", config.outputFile);
|
|
20484
20736
|
}
|
|
20485
|
-
await
|
|
20737
|
+
await fs40.mkdir(path42.dirname(outputPath), { recursive: true });
|
|
20486
20738
|
try {
|
|
20487
|
-
const existingContent = await
|
|
20739
|
+
const existingContent = await fs40.readFile(outputPath, "utf-8");
|
|
20488
20740
|
const validation = validatePreserveBlocks(existingContent);
|
|
20489
20741
|
if (!validation.valid) {
|
|
20490
20742
|
console.warn(`\u26A0\uFE0F ${config.outputFile} has invalid preserve blocks:`);
|
|
@@ -20495,7 +20747,7 @@ async function generateForTool(context2, config, globalPath, repoPath) {
|
|
|
20495
20747
|
content = mergePreservedSections(content, existingContent);
|
|
20496
20748
|
} catch {
|
|
20497
20749
|
}
|
|
20498
|
-
await
|
|
20750
|
+
await fs40.writeFile(outputPath, content, "utf-8");
|
|
20499
20751
|
return {
|
|
20500
20752
|
toolId: config.id,
|
|
20501
20753
|
outputFile: config.outputFile,
|
|
@@ -20534,8 +20786,8 @@ var init_ai_tools = __esm({
|
|
|
20534
20786
|
});
|
|
20535
20787
|
|
|
20536
20788
|
// core/services/context-generator.ts
|
|
20537
|
-
import
|
|
20538
|
-
import
|
|
20789
|
+
import fs41 from "node:fs/promises";
|
|
20790
|
+
import path43 from "node:path";
|
|
20539
20791
|
var ContextFileGenerator;
|
|
20540
20792
|
var init_context_generator = __esm({
|
|
20541
20793
|
"core/services/context-generator.ts"() {
|
|
@@ -20559,10 +20811,10 @@ var init_context_generator = __esm({
|
|
|
20559
20811
|
async writeWithPreservation(filePath, content) {
|
|
20560
20812
|
let finalContent = content;
|
|
20561
20813
|
try {
|
|
20562
|
-
const existingContent = await
|
|
20814
|
+
const existingContent = await fs41.readFile(filePath, "utf-8");
|
|
20563
20815
|
const validation = validatePreserveBlocks(existingContent);
|
|
20564
20816
|
if (!validation.valid) {
|
|
20565
|
-
const filename =
|
|
20817
|
+
const filename = path43.basename(filePath);
|
|
20566
20818
|
console.warn(`\u26A0\uFE0F ${filename} has invalid preserve blocks:`);
|
|
20567
20819
|
for (const error of validation.errors) {
|
|
20568
20820
|
console.warn(` ${error}`);
|
|
@@ -20571,13 +20823,13 @@ var init_context_generator = __esm({
|
|
|
20571
20823
|
finalContent = mergePreservedSections(content, existingContent);
|
|
20572
20824
|
} catch {
|
|
20573
20825
|
}
|
|
20574
|
-
await
|
|
20826
|
+
await fs41.writeFile(filePath, finalContent, "utf-8");
|
|
20575
20827
|
}
|
|
20576
20828
|
/**
|
|
20577
20829
|
* Generate all context files in parallel
|
|
20578
20830
|
*/
|
|
20579
20831
|
async generate(git, stats, commands, agents) {
|
|
20580
|
-
const contextPath =
|
|
20832
|
+
const contextPath = path43.join(this.config.globalPath, "context");
|
|
20581
20833
|
await Promise.all([
|
|
20582
20834
|
this.generateClaudeMd(contextPath, git, stats, commands, agents),
|
|
20583
20835
|
this.generateNowMd(contextPath),
|
|
@@ -20671,7 +20923,7 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
|
|
|
20671
20923
|
**Workflow**: ${workflowAgents.join(", ")}
|
|
20672
20924
|
**Domain**: ${domainAgents.join(", ") || "none"}
|
|
20673
20925
|
`;
|
|
20674
|
-
const claudePath =
|
|
20926
|
+
const claudePath = path43.join(contextPath, "CLAUDE.md");
|
|
20675
20927
|
await this.writeWithPreservation(claudePath, content);
|
|
20676
20928
|
}
|
|
20677
20929
|
/**
|
|
@@ -20680,8 +20932,8 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
|
|
|
20680
20932
|
async generateNowMd(contextPath) {
|
|
20681
20933
|
let currentTask = null;
|
|
20682
20934
|
try {
|
|
20683
|
-
const statePath =
|
|
20684
|
-
const state = JSON.parse(await
|
|
20935
|
+
const statePath = path43.join(this.config.globalPath, "storage", "state.json");
|
|
20936
|
+
const state = JSON.parse(await fs41.readFile(statePath, "utf-8"));
|
|
20685
20937
|
currentTask = state.currentTask;
|
|
20686
20938
|
} catch {
|
|
20687
20939
|
}
|
|
@@ -20697,7 +20949,7 @@ _No active task_
|
|
|
20697
20949
|
|
|
20698
20950
|
Use \`p. task "description"\` to start working.
|
|
20699
20951
|
`;
|
|
20700
|
-
await this.writeWithPreservation(
|
|
20952
|
+
await this.writeWithPreservation(path43.join(contextPath, "now.md"), content);
|
|
20701
20953
|
}
|
|
20702
20954
|
/**
|
|
20703
20955
|
* Generate next.md - task queue
|
|
@@ -20705,15 +20957,15 @@ Use \`p. task "description"\` to start working.
|
|
|
20705
20957
|
async generateNextMd(contextPath) {
|
|
20706
20958
|
let queue = { tasks: [] };
|
|
20707
20959
|
try {
|
|
20708
|
-
const queuePath =
|
|
20709
|
-
queue = JSON.parse(await
|
|
20960
|
+
const queuePath = path43.join(this.config.globalPath, "storage", "queue.json");
|
|
20961
|
+
queue = JSON.parse(await fs41.readFile(queuePath, "utf-8"));
|
|
20710
20962
|
} catch {
|
|
20711
20963
|
}
|
|
20712
20964
|
const content = `# NEXT
|
|
20713
20965
|
|
|
20714
20966
|
${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}${t.priority ? ` [${t.priority}]` : ""}`).join("\n") : "_Empty queue_"}
|
|
20715
20967
|
`;
|
|
20716
|
-
await this.writeWithPreservation(
|
|
20968
|
+
await this.writeWithPreservation(path43.join(contextPath, "next.md"), content);
|
|
20717
20969
|
}
|
|
20718
20970
|
/**
|
|
20719
20971
|
* Generate ideas.md - captured ideas
|
|
@@ -20721,15 +20973,15 @@ ${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}
|
|
|
20721
20973
|
async generateIdeasMd(contextPath) {
|
|
20722
20974
|
let ideas = { ideas: [] };
|
|
20723
20975
|
try {
|
|
20724
|
-
const ideasPath =
|
|
20725
|
-
ideas = JSON.parse(await
|
|
20976
|
+
const ideasPath = path43.join(this.config.globalPath, "storage", "ideas.json");
|
|
20977
|
+
ideas = JSON.parse(await fs41.readFile(ideasPath, "utf-8"));
|
|
20726
20978
|
} catch {
|
|
20727
20979
|
}
|
|
20728
20980
|
const content = `# IDEAS
|
|
20729
20981
|
|
|
20730
20982
|
${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [${i.priority}]` : ""}`).join("\n") : "_No ideas captured yet_"}
|
|
20731
20983
|
`;
|
|
20732
|
-
await this.writeWithPreservation(
|
|
20984
|
+
await this.writeWithPreservation(path43.join(contextPath, "ideas.md"), content);
|
|
20733
20985
|
}
|
|
20734
20986
|
/**
|
|
20735
20987
|
* Generate shipped.md - completed features
|
|
@@ -20739,8 +20991,8 @@ ${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [
|
|
|
20739
20991
|
shipped: []
|
|
20740
20992
|
};
|
|
20741
20993
|
try {
|
|
20742
|
-
const shippedPath =
|
|
20743
|
-
shipped = JSON.parse(await
|
|
20994
|
+
const shippedPath = path43.join(this.config.globalPath, "storage", "shipped.json");
|
|
20995
|
+
shipped = JSON.parse(await fs41.readFile(shippedPath, "utf-8"));
|
|
20744
20996
|
} catch {
|
|
20745
20997
|
}
|
|
20746
20998
|
const content = `# SHIPPED \u{1F680}
|
|
@@ -20749,7 +21001,7 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
|
|
|
20749
21001
|
|
|
20750
21002
|
**Total shipped:** ${shipped.shipped.length}
|
|
20751
21003
|
`;
|
|
20752
|
-
await this.writeWithPreservation(
|
|
21004
|
+
await this.writeWithPreservation(path43.join(contextPath, "shipped.md"), content);
|
|
20753
21005
|
}
|
|
20754
21006
|
// ==========================================================================
|
|
20755
21007
|
// MONOREPO SUPPORT
|
|
@@ -20778,9 +21030,9 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
|
|
|
20778
21030
|
commands,
|
|
20779
21031
|
agents
|
|
20780
21032
|
);
|
|
20781
|
-
const claudePath =
|
|
21033
|
+
const claudePath = path43.join(pkg.path, "CLAUDE.md");
|
|
20782
21034
|
await this.writeWithPreservation(claudePath, content);
|
|
20783
|
-
generatedFiles.push(
|
|
21035
|
+
generatedFiles.push(path43.relative(this.config.projectPath, claudePath));
|
|
20784
21036
|
}
|
|
20785
21037
|
return generatedFiles;
|
|
20786
21038
|
}
|
|
@@ -20793,8 +21045,8 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
|
|
|
20793
21045
|
let pkgVersion = stats.version;
|
|
20794
21046
|
let pkgName = pkg.name;
|
|
20795
21047
|
try {
|
|
20796
|
-
const pkgJsonPath =
|
|
20797
|
-
const pkgJson = JSON.parse(await
|
|
21048
|
+
const pkgJsonPath = path43.join(pkg.path, "package.json");
|
|
21049
|
+
const pkgJson = JSON.parse(await fs41.readFile(pkgJsonPath, "utf-8"));
|
|
20798
21050
|
pkgVersion = pkgJson.version || stats.version;
|
|
20799
21051
|
pkgName = pkgJson.name || pkg.name;
|
|
20800
21052
|
} catch {
|
|
@@ -20859,8 +21111,8 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
|
|
|
20859
21111
|
});
|
|
20860
21112
|
|
|
20861
21113
|
// core/services/local-state-generator.ts
|
|
20862
|
-
import
|
|
20863
|
-
import
|
|
21114
|
+
import fs42 from "node:fs/promises";
|
|
21115
|
+
import path44 from "node:path";
|
|
20864
21116
|
var LOCAL_STATE_FILENAME, LocalStateGenerator, localStateGenerator;
|
|
20865
21117
|
var init_local_state_generator = __esm({
|
|
20866
21118
|
"core/services/local-state-generator.ts"() {
|
|
@@ -20875,17 +21127,17 @@ var init_local_state_generator = __esm({
|
|
|
20875
21127
|
* Generate .prjct-state.md in the project root
|
|
20876
21128
|
*/
|
|
20877
21129
|
async generate(projectPath, state) {
|
|
20878
|
-
const filePath =
|
|
21130
|
+
const filePath = path44.join(projectPath, LOCAL_STATE_FILENAME);
|
|
20879
21131
|
const content = this.toMarkdown(state);
|
|
20880
|
-
await
|
|
21132
|
+
await fs42.writeFile(filePath, content, "utf-8");
|
|
20881
21133
|
}
|
|
20882
21134
|
/**
|
|
20883
21135
|
* Remove local state file
|
|
20884
21136
|
*/
|
|
20885
21137
|
async remove(projectPath) {
|
|
20886
|
-
const filePath =
|
|
21138
|
+
const filePath = path44.join(projectPath, LOCAL_STATE_FILENAME);
|
|
20887
21139
|
try {
|
|
20888
|
-
await
|
|
21140
|
+
await fs42.unlink(filePath);
|
|
20889
21141
|
} catch (error) {
|
|
20890
21142
|
if (!isNotFoundError(error)) throw error;
|
|
20891
21143
|
}
|
|
@@ -20894,9 +21146,9 @@ var init_local_state_generator = __esm({
|
|
|
20894
21146
|
* Check if local state file exists
|
|
20895
21147
|
*/
|
|
20896
21148
|
async exists(projectPath) {
|
|
20897
|
-
const filePath =
|
|
21149
|
+
const filePath = path44.join(projectPath, LOCAL_STATE_FILENAME);
|
|
20898
21150
|
try {
|
|
20899
|
-
await
|
|
21151
|
+
await fs42.access(filePath);
|
|
20900
21152
|
return true;
|
|
20901
21153
|
} catch {
|
|
20902
21154
|
return false;
|
|
@@ -20975,8 +21227,8 @@ var init_local_state_generator = __esm({
|
|
|
20975
21227
|
});
|
|
20976
21228
|
|
|
20977
21229
|
// core/services/stack-detector.ts
|
|
20978
|
-
import
|
|
20979
|
-
import
|
|
21230
|
+
import fs43 from "node:fs/promises";
|
|
21231
|
+
import path45 from "node:path";
|
|
20980
21232
|
var StackDetector;
|
|
20981
21233
|
var init_stack_detector = __esm({
|
|
20982
21234
|
"core/services/stack-detector.ts"() {
|
|
@@ -21135,8 +21387,8 @@ var init_stack_detector = __esm({
|
|
|
21135
21387
|
*/
|
|
21136
21388
|
async readPackageJson() {
|
|
21137
21389
|
try {
|
|
21138
|
-
const pkgPath =
|
|
21139
|
-
const content = await
|
|
21390
|
+
const pkgPath = path45.join(this.projectPath, "package.json");
|
|
21391
|
+
const content = await fs43.readFile(pkgPath, "utf-8");
|
|
21140
21392
|
return JSON.parse(content);
|
|
21141
21393
|
} catch {
|
|
21142
21394
|
return null;
|
|
@@ -21147,7 +21399,7 @@ var init_stack_detector = __esm({
|
|
|
21147
21399
|
*/
|
|
21148
21400
|
async fileExists(filename) {
|
|
21149
21401
|
try {
|
|
21150
|
-
await
|
|
21402
|
+
await fs43.access(path45.join(this.projectPath, filename));
|
|
21151
21403
|
return true;
|
|
21152
21404
|
} catch {
|
|
21153
21405
|
return false;
|
|
@@ -21159,8 +21411,8 @@ var init_stack_detector = __esm({
|
|
|
21159
21411
|
|
|
21160
21412
|
// core/services/sync-service.ts
|
|
21161
21413
|
import { exec as exec12 } from "node:child_process";
|
|
21162
|
-
import
|
|
21163
|
-
import
|
|
21414
|
+
import fs44 from "node:fs/promises";
|
|
21415
|
+
import path46 from "node:path";
|
|
21164
21416
|
import { promisify as promisify12 } from "node:util";
|
|
21165
21417
|
var execAsync7, SyncService, syncService;
|
|
21166
21418
|
var init_sync_service = __esm({
|
|
@@ -21313,7 +21565,7 @@ var init_sync_service = __esm({
|
|
|
21313
21565
|
async ensureDirectories() {
|
|
21314
21566
|
const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
|
|
21315
21567
|
await Promise.all(
|
|
21316
|
-
dirs.map((dir) =>
|
|
21568
|
+
dirs.map((dir) => fs44.mkdir(path46.join(this.globalPath, dir), { recursive: true }))
|
|
21317
21569
|
);
|
|
21318
21570
|
}
|
|
21319
21571
|
// ==========================================================================
|
|
@@ -21383,7 +21635,7 @@ var init_sync_service = __esm({
|
|
|
21383
21635
|
const stats = {
|
|
21384
21636
|
fileCount: 0,
|
|
21385
21637
|
version: "0.0.0",
|
|
21386
|
-
name:
|
|
21638
|
+
name: path46.basename(this.projectPath),
|
|
21387
21639
|
ecosystem: "unknown",
|
|
21388
21640
|
projectType: "simple",
|
|
21389
21641
|
languages: [],
|
|
@@ -21399,8 +21651,8 @@ var init_sync_service = __esm({
|
|
|
21399
21651
|
stats.fileCount = 0;
|
|
21400
21652
|
}
|
|
21401
21653
|
try {
|
|
21402
|
-
const pkgPath =
|
|
21403
|
-
const pkg = JSON.parse(await
|
|
21654
|
+
const pkgPath = path46.join(this.projectPath, "package.json");
|
|
21655
|
+
const pkg = JSON.parse(await fs44.readFile(pkgPath, "utf-8"));
|
|
21404
21656
|
stats.version = pkg.version || "0.0.0";
|
|
21405
21657
|
stats.name = pkg.name || stats.name;
|
|
21406
21658
|
stats.ecosystem = "JavaScript";
|
|
@@ -21508,12 +21760,12 @@ var init_sync_service = __esm({
|
|
|
21508
21760
|
// ==========================================================================
|
|
21509
21761
|
async generateAgents(stack, stats) {
|
|
21510
21762
|
const agents = [];
|
|
21511
|
-
const agentsPath =
|
|
21763
|
+
const agentsPath = path46.join(this.globalPath, "agents");
|
|
21512
21764
|
try {
|
|
21513
|
-
const files = await
|
|
21765
|
+
const files = await fs44.readdir(agentsPath);
|
|
21514
21766
|
for (const file of files) {
|
|
21515
21767
|
if (file.endsWith(".md")) {
|
|
21516
|
-
await
|
|
21768
|
+
await fs44.unlink(path46.join(agentsPath, file));
|
|
21517
21769
|
}
|
|
21518
21770
|
}
|
|
21519
21771
|
} catch {
|
|
@@ -21553,7 +21805,7 @@ var init_sync_service = __esm({
|
|
|
21553
21805
|
async generateWorkflowAgent(name, agentsPath) {
|
|
21554
21806
|
let content = "";
|
|
21555
21807
|
try {
|
|
21556
|
-
const templatePath =
|
|
21808
|
+
const templatePath = path46.join(
|
|
21557
21809
|
__dirname,
|
|
21558
21810
|
"..",
|
|
21559
21811
|
"..",
|
|
@@ -21562,16 +21814,16 @@ var init_sync_service = __esm({
|
|
|
21562
21814
|
"workflow",
|
|
21563
21815
|
`${name}.md`
|
|
21564
21816
|
);
|
|
21565
|
-
content = await
|
|
21817
|
+
content = await fs44.readFile(templatePath, "utf-8");
|
|
21566
21818
|
} catch {
|
|
21567
21819
|
content = this.generateMinimalWorkflowAgent(name);
|
|
21568
21820
|
}
|
|
21569
|
-
await
|
|
21821
|
+
await fs44.writeFile(path46.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
21570
21822
|
}
|
|
21571
21823
|
async generateDomainAgent(name, agentsPath, stats, stack) {
|
|
21572
21824
|
let content = "";
|
|
21573
21825
|
try {
|
|
21574
|
-
const templatePath =
|
|
21826
|
+
const templatePath = path46.join(
|
|
21575
21827
|
__dirname,
|
|
21576
21828
|
"..",
|
|
21577
21829
|
"..",
|
|
@@ -21580,14 +21832,14 @@ var init_sync_service = __esm({
|
|
|
21580
21832
|
"domain",
|
|
21581
21833
|
`${name}.md`
|
|
21582
21834
|
);
|
|
21583
|
-
content = await
|
|
21835
|
+
content = await fs44.readFile(templatePath, "utf-8");
|
|
21584
21836
|
content = content.replace("{projectName}", stats.name);
|
|
21585
21837
|
content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
|
|
21586
21838
|
content = content.replace("{ecosystem}", stats.ecosystem);
|
|
21587
21839
|
} catch {
|
|
21588
21840
|
content = this.generateMinimalDomainAgent(name, stats, stack);
|
|
21589
21841
|
}
|
|
21590
|
-
await
|
|
21842
|
+
await fs44.writeFile(path46.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
21591
21843
|
}
|
|
21592
21844
|
generateMinimalWorkflowAgent(name) {
|
|
21593
21845
|
const descriptions = {
|
|
@@ -21655,8 +21907,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21655
21907
|
})),
|
|
21656
21908
|
agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
|
|
21657
21909
|
};
|
|
21658
|
-
|
|
21659
|
-
|
|
21910
|
+
fs44.writeFile(
|
|
21911
|
+
path46.join(this.globalPath, "config", "skills.json"),
|
|
21660
21912
|
JSON.stringify(skillsConfig, null, 2),
|
|
21661
21913
|
"utf-8"
|
|
21662
21914
|
).catch(() => {
|
|
@@ -21678,10 +21930,10 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21678
21930
|
// PROJECT.JSON UPDATE
|
|
21679
21931
|
// ==========================================================================
|
|
21680
21932
|
async updateProjectJson(git, stats) {
|
|
21681
|
-
const projectJsonPath =
|
|
21933
|
+
const projectJsonPath = path46.join(this.globalPath, "project.json");
|
|
21682
21934
|
let existing = {};
|
|
21683
21935
|
try {
|
|
21684
|
-
existing = JSON.parse(await
|
|
21936
|
+
existing = JSON.parse(await fs44.readFile(projectJsonPath, "utf-8"));
|
|
21685
21937
|
} catch {
|
|
21686
21938
|
}
|
|
21687
21939
|
const updated = {
|
|
@@ -21703,16 +21955,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21703
21955
|
lastSyncCommit: git.recentCommits[0]?.hash || null,
|
|
21704
21956
|
lastSyncBranch: git.branch
|
|
21705
21957
|
};
|
|
21706
|
-
await
|
|
21958
|
+
await fs44.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
|
|
21707
21959
|
}
|
|
21708
21960
|
// ==========================================================================
|
|
21709
21961
|
// STATE.JSON UPDATE
|
|
21710
21962
|
// ==========================================================================
|
|
21711
21963
|
async updateStateJson(stats, stack) {
|
|
21712
|
-
const statePath =
|
|
21964
|
+
const statePath = path46.join(this.globalPath, "storage", "state.json");
|
|
21713
21965
|
let state = {};
|
|
21714
21966
|
try {
|
|
21715
|
-
state = JSON.parse(await
|
|
21967
|
+
state = JSON.parse(await fs44.readFile(statePath, "utf-8"));
|
|
21716
21968
|
} catch {
|
|
21717
21969
|
}
|
|
21718
21970
|
state.projectId = this.projectId;
|
|
@@ -21739,7 +21991,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21739
21991
|
lastAction: "Synced project",
|
|
21740
21992
|
nextAction: 'Run `p. task "description"` to start working'
|
|
21741
21993
|
};
|
|
21742
|
-
await
|
|
21994
|
+
await fs44.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
|
|
21743
21995
|
try {
|
|
21744
21996
|
await localStateGenerator.generate(
|
|
21745
21997
|
this.projectPath,
|
|
@@ -21752,7 +22004,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21752
22004
|
// MEMORY LOGGING
|
|
21753
22005
|
// ==========================================================================
|
|
21754
22006
|
async logToMemory(git, stats) {
|
|
21755
|
-
const memoryPath =
|
|
22007
|
+
const memoryPath = path46.join(this.globalPath, "memory", "events.jsonl");
|
|
21756
22008
|
const event = {
|
|
21757
22009
|
ts: date_helper_default.getTimestamp(),
|
|
21758
22010
|
action: "sync",
|
|
@@ -21761,7 +22013,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21761
22013
|
fileCount: stats.fileCount,
|
|
21762
22014
|
commitCount: git.commits
|
|
21763
22015
|
};
|
|
21764
|
-
await
|
|
22016
|
+
await fs44.appendFile(memoryPath, `${JSON.stringify(event)}
|
|
21765
22017
|
`, "utf-8");
|
|
21766
22018
|
}
|
|
21767
22019
|
// ==========================================================================
|
|
@@ -21781,16 +22033,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21781
22033
|
let filteredChars = 0;
|
|
21782
22034
|
for (const file of contextFiles) {
|
|
21783
22035
|
try {
|
|
21784
|
-
const filePath =
|
|
21785
|
-
const content = await
|
|
22036
|
+
const filePath = path46.join(this.globalPath, file);
|
|
22037
|
+
const content = await fs44.readFile(filePath, "utf-8");
|
|
21786
22038
|
filteredChars += content.length;
|
|
21787
22039
|
} catch {
|
|
21788
22040
|
}
|
|
21789
22041
|
}
|
|
21790
22042
|
for (const agent of agents) {
|
|
21791
22043
|
try {
|
|
21792
|
-
const agentPath =
|
|
21793
|
-
const content = await
|
|
22044
|
+
const agentPath = path46.join(this.globalPath, "agents", `${agent.name}.md`);
|
|
22045
|
+
const content = await fs44.readFile(agentPath, "utf-8");
|
|
21794
22046
|
filteredChars += content.length;
|
|
21795
22047
|
} catch {
|
|
21796
22048
|
}
|
|
@@ -21822,7 +22074,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21822
22074
|
// ==========================================================================
|
|
21823
22075
|
async fileExists(filename) {
|
|
21824
22076
|
try {
|
|
21825
|
-
await
|
|
22077
|
+
await fs44.access(path46.join(this.projectPath, filename));
|
|
21826
22078
|
return true;
|
|
21827
22079
|
} catch {
|
|
21828
22080
|
return false;
|
|
@@ -21830,8 +22082,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
21830
22082
|
}
|
|
21831
22083
|
async getCliVersion() {
|
|
21832
22084
|
try {
|
|
21833
|
-
const pkgPath =
|
|
21834
|
-
const pkg = JSON.parse(await
|
|
22085
|
+
const pkgPath = path46.join(__dirname, "..", "..", "package.json");
|
|
22086
|
+
const pkg = JSON.parse(await fs44.readFile(pkgPath, "utf-8"));
|
|
21835
22087
|
return pkg.version || "0.0.0";
|
|
21836
22088
|
} catch {
|
|
21837
22089
|
return "0.0.0";
|
|
@@ -21992,22 +22244,22 @@ __export(uninstall_exports, {
|
|
|
21992
22244
|
});
|
|
21993
22245
|
import { execSync as execSync5 } from "node:child_process";
|
|
21994
22246
|
import fsSync2 from "node:fs";
|
|
21995
|
-
import
|
|
22247
|
+
import fs45 from "node:fs/promises";
|
|
21996
22248
|
import os12 from "node:os";
|
|
21997
|
-
import
|
|
22249
|
+
import path47 from "node:path";
|
|
21998
22250
|
import readline2 from "node:readline";
|
|
21999
22251
|
import chalk12 from "chalk";
|
|
22000
22252
|
async function getDirectorySize(dirPath) {
|
|
22001
22253
|
let totalSize = 0;
|
|
22002
22254
|
try {
|
|
22003
|
-
const entries = await
|
|
22255
|
+
const entries = await fs45.readdir(dirPath, { withFileTypes: true });
|
|
22004
22256
|
for (const entry of entries) {
|
|
22005
|
-
const entryPath =
|
|
22257
|
+
const entryPath = path47.join(dirPath, entry.name);
|
|
22006
22258
|
if (entry.isDirectory()) {
|
|
22007
22259
|
totalSize += await getDirectorySize(entryPath);
|
|
22008
22260
|
} else {
|
|
22009
22261
|
try {
|
|
22010
|
-
const stats = await
|
|
22262
|
+
const stats = await fs45.stat(entryPath);
|
|
22011
22263
|
totalSize += stats.size;
|
|
22012
22264
|
} catch {
|
|
22013
22265
|
}
|
|
@@ -22026,7 +22278,7 @@ function formatSize(bytes) {
|
|
|
22026
22278
|
}
|
|
22027
22279
|
async function countDirectoryItems(dirPath) {
|
|
22028
22280
|
try {
|
|
22029
|
-
const entries = await
|
|
22281
|
+
const entries = await fs45.readdir(dirPath, { withFileTypes: true });
|
|
22030
22282
|
return entries.filter((e) => e.isDirectory()).length;
|
|
22031
22283
|
} catch {
|
|
22032
22284
|
return 0;
|
|
@@ -22059,7 +22311,7 @@ async function gatherUninstallItems() {
|
|
|
22059
22311
|
const providerPaths = getProviderPaths();
|
|
22060
22312
|
const prjctCliPath = path_manager_default.getGlobalBasePath();
|
|
22061
22313
|
const prjctCliExists = fsSync2.existsSync(prjctCliPath);
|
|
22062
|
-
const projectCount = prjctCliExists ? await countDirectoryItems(
|
|
22314
|
+
const projectCount = prjctCliExists ? await countDirectoryItems(path47.join(prjctCliPath, "projects")) : 0;
|
|
22063
22315
|
const prjctCliSize = prjctCliExists ? await getDirectorySize(prjctCliPath) : 0;
|
|
22064
22316
|
items.push({
|
|
22065
22317
|
path: prjctCliPath,
|
|
@@ -22069,7 +22321,7 @@ async function gatherUninstallItems() {
|
|
|
22069
22321
|
count: projectCount,
|
|
22070
22322
|
exists: prjctCliExists
|
|
22071
22323
|
});
|
|
22072
|
-
const claudeMdPath =
|
|
22324
|
+
const claudeMdPath = path47.join(providerPaths.claude.config, "CLAUDE.md");
|
|
22073
22325
|
const claudeMdExists = fsSync2.existsSync(claudeMdPath);
|
|
22074
22326
|
let hasPrjctSection = false;
|
|
22075
22327
|
if (claudeMdExists) {
|
|
@@ -22103,7 +22355,7 @@ async function gatherUninstallItems() {
|
|
|
22103
22355
|
description: "Claude router",
|
|
22104
22356
|
exists: claudeRouterExists
|
|
22105
22357
|
});
|
|
22106
|
-
const statusLinePath =
|
|
22358
|
+
const statusLinePath = path47.join(providerPaths.claude.config, "prjct-statusline.sh");
|
|
22107
22359
|
const statusLineExists = fsSync2.existsSync(statusLinePath);
|
|
22108
22360
|
items.push({
|
|
22109
22361
|
path: statusLinePath,
|
|
@@ -22119,7 +22371,7 @@ async function gatherUninstallItems() {
|
|
|
22119
22371
|
description: "Gemini router",
|
|
22120
22372
|
exists: geminiRouterExists
|
|
22121
22373
|
});
|
|
22122
|
-
const geminiMdPath =
|
|
22374
|
+
const geminiMdPath = path47.join(providerPaths.gemini.config, "GEMINI.md");
|
|
22123
22375
|
const geminiMdExists = fsSync2.existsSync(geminiMdPath);
|
|
22124
22376
|
let hasGeminiPrjctSection = false;
|
|
22125
22377
|
if (geminiMdExists) {
|
|
@@ -22141,7 +22393,7 @@ async function gatherUninstallItems() {
|
|
|
22141
22393
|
}
|
|
22142
22394
|
async function removePrjctSection(filePath) {
|
|
22143
22395
|
try {
|
|
22144
|
-
const content = await
|
|
22396
|
+
const content = await fs45.readFile(filePath, "utf-8");
|
|
22145
22397
|
if (!content.includes(PRJCT_START_MARKER) || !content.includes(PRJCT_END_MARKER)) {
|
|
22146
22398
|
return false;
|
|
22147
22399
|
}
|
|
@@ -22150,9 +22402,9 @@ async function removePrjctSection(filePath) {
|
|
|
22150
22402
|
let newContent = content.substring(0, startIndex) + content.substring(endIndex);
|
|
22151
22403
|
newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
|
|
22152
22404
|
if (!newContent || newContent.trim().length === 0) {
|
|
22153
|
-
await
|
|
22405
|
+
await fs45.unlink(filePath);
|
|
22154
22406
|
} else {
|
|
22155
|
-
await
|
|
22407
|
+
await fs45.writeFile(filePath, `${newContent}
|
|
22156
22408
|
`, "utf-8");
|
|
22157
22409
|
}
|
|
22158
22410
|
return true;
|
|
@@ -22163,12 +22415,12 @@ async function removePrjctSection(filePath) {
|
|
|
22163
22415
|
async function createBackup() {
|
|
22164
22416
|
const homeDir = os12.homedir();
|
|
22165
22417
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
22166
|
-
const backupDir =
|
|
22418
|
+
const backupDir = path47.join(homeDir, `.prjct-backup-${timestamp}`);
|
|
22167
22419
|
try {
|
|
22168
|
-
await
|
|
22420
|
+
await fs45.mkdir(backupDir, { recursive: true });
|
|
22169
22421
|
const prjctCliPath = path_manager_default.getGlobalBasePath();
|
|
22170
22422
|
if (fsSync2.existsSync(prjctCliPath)) {
|
|
22171
|
-
await copyDirectory(prjctCliPath,
|
|
22423
|
+
await copyDirectory(prjctCliPath, path47.join(backupDir, ".prjct-cli"));
|
|
22172
22424
|
}
|
|
22173
22425
|
return backupDir;
|
|
22174
22426
|
} catch {
|
|
@@ -22176,15 +22428,15 @@ async function createBackup() {
|
|
|
22176
22428
|
}
|
|
22177
22429
|
}
|
|
22178
22430
|
async function copyDirectory(src, dest) {
|
|
22179
|
-
await
|
|
22180
|
-
const entries = await
|
|
22431
|
+
await fs45.mkdir(dest, { recursive: true });
|
|
22432
|
+
const entries = await fs45.readdir(src, { withFileTypes: true });
|
|
22181
22433
|
for (const entry of entries) {
|
|
22182
|
-
const srcPath =
|
|
22183
|
-
const destPath =
|
|
22434
|
+
const srcPath = path47.join(src, entry.name);
|
|
22435
|
+
const destPath = path47.join(dest, entry.name);
|
|
22184
22436
|
if (entry.isDirectory()) {
|
|
22185
22437
|
await copyDirectory(srcPath, destPath);
|
|
22186
22438
|
} else {
|
|
22187
|
-
await
|
|
22439
|
+
await fs45.copyFile(srcPath, destPath);
|
|
22188
22440
|
}
|
|
22189
22441
|
}
|
|
22190
22442
|
}
|
|
@@ -22200,10 +22452,10 @@ async function performUninstall(items, installation, options) {
|
|
|
22200
22452
|
deleted.push(item.path);
|
|
22201
22453
|
}
|
|
22202
22454
|
} else if (item.type === "directory") {
|
|
22203
|
-
await
|
|
22455
|
+
await fs45.rm(item.path, { recursive: true, force: true });
|
|
22204
22456
|
deleted.push(item.path);
|
|
22205
22457
|
} else if (item.type === "file") {
|
|
22206
|
-
await
|
|
22458
|
+
await fs45.unlink(item.path);
|
|
22207
22459
|
deleted.push(item.path);
|
|
22208
22460
|
}
|
|
22209
22461
|
} catch (error) {
|
|
@@ -22378,7 +22630,7 @@ __export(watch_service_exports, {
|
|
|
22378
22630
|
WatchService: () => WatchService,
|
|
22379
22631
|
watchService: () => watchService
|
|
22380
22632
|
});
|
|
22381
|
-
import
|
|
22633
|
+
import path48 from "node:path";
|
|
22382
22634
|
import chalk13 from "chalk";
|
|
22383
22635
|
import chokidar from "chokidar";
|
|
22384
22636
|
var TRIGGER_PATTERNS, IGNORE_PATTERNS2, WatchService, watchService;
|
|
@@ -22583,7 +22835,7 @@ ${chalk13.dim(`[${timestamp}]`)} ${chalk13.cyan("\u27F3")} ${filesSummary} chang
|
|
|
22583
22835
|
printStartup() {
|
|
22584
22836
|
console.log("");
|
|
22585
22837
|
console.log(chalk13.cyan("\u{1F441}\uFE0F Watching for changes..."));
|
|
22586
|
-
console.log(chalk13.dim(` Project: ${
|
|
22838
|
+
console.log(chalk13.dim(` Project: ${path48.basename(this.projectPath)}`));
|
|
22587
22839
|
console.log(chalk13.dim(` Debounce: ${this.options.debounceMs}ms`));
|
|
22588
22840
|
console.log(chalk13.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
|
|
22589
22841
|
console.log("");
|
|
@@ -23261,9 +23513,9 @@ __export(setup_exports, {
|
|
|
23261
23513
|
run: () => run
|
|
23262
23514
|
});
|
|
23263
23515
|
import { execSync as execSync6 } from "node:child_process";
|
|
23264
|
-
import
|
|
23516
|
+
import fs46 from "node:fs";
|
|
23265
23517
|
import os13 from "node:os";
|
|
23266
|
-
import
|
|
23518
|
+
import path49 from "node:path";
|
|
23267
23519
|
import chalk15 from "chalk";
|
|
23268
23520
|
async function installAICLI(provider) {
|
|
23269
23521
|
const packageName = provider.name === "claude" ? "@anthropic-ai/claude-code" : "@google/gemini-cli";
|
|
@@ -23402,12 +23654,12 @@ async function run() {
|
|
|
23402
23654
|
}
|
|
23403
23655
|
async function installGeminiRouter() {
|
|
23404
23656
|
try {
|
|
23405
|
-
const geminiCommandsDir =
|
|
23406
|
-
const routerSource =
|
|
23407
|
-
const routerDest =
|
|
23408
|
-
|
|
23409
|
-
if (
|
|
23410
|
-
|
|
23657
|
+
const geminiCommandsDir = path49.join(os13.homedir(), ".gemini", "commands");
|
|
23658
|
+
const routerSource = path49.join(getPackageRoot(), "templates", "commands", "p.toml");
|
|
23659
|
+
const routerDest = path49.join(geminiCommandsDir, "p.toml");
|
|
23660
|
+
fs46.mkdirSync(geminiCommandsDir, { recursive: true });
|
|
23661
|
+
if (fs46.existsSync(routerSource)) {
|
|
23662
|
+
fs46.copyFileSync(routerSource, routerDest);
|
|
23411
23663
|
return true;
|
|
23412
23664
|
}
|
|
23413
23665
|
return false;
|
|
@@ -23418,15 +23670,15 @@ async function installGeminiRouter() {
|
|
|
23418
23670
|
}
|
|
23419
23671
|
async function installGeminiGlobalConfig() {
|
|
23420
23672
|
try {
|
|
23421
|
-
const geminiDir =
|
|
23422
|
-
const globalConfigPath =
|
|
23423
|
-
const templatePath =
|
|
23424
|
-
|
|
23425
|
-
const templateContent =
|
|
23673
|
+
const geminiDir = path49.join(os13.homedir(), ".gemini");
|
|
23674
|
+
const globalConfigPath = path49.join(geminiDir, "GEMINI.md");
|
|
23675
|
+
const templatePath = path49.join(getPackageRoot(), "templates", "global", "GEMINI.md");
|
|
23676
|
+
fs46.mkdirSync(geminiDir, { recursive: true });
|
|
23677
|
+
const templateContent = fs46.readFileSync(templatePath, "utf-8");
|
|
23426
23678
|
let existingContent = "";
|
|
23427
23679
|
let fileExists2 = false;
|
|
23428
23680
|
try {
|
|
23429
|
-
existingContent =
|
|
23681
|
+
existingContent = fs46.readFileSync(globalConfigPath, "utf-8");
|
|
23430
23682
|
fileExists2 = true;
|
|
23431
23683
|
} catch (error) {
|
|
23432
23684
|
if (isNotFoundError(error)) {
|
|
@@ -23436,7 +23688,7 @@ async function installGeminiGlobalConfig() {
|
|
|
23436
23688
|
}
|
|
23437
23689
|
}
|
|
23438
23690
|
if (!fileExists2) {
|
|
23439
|
-
|
|
23691
|
+
fs46.writeFileSync(globalConfigPath, templateContent, "utf-8");
|
|
23440
23692
|
return { success: true, action: "created" };
|
|
23441
23693
|
}
|
|
23442
23694
|
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
@@ -23446,7 +23698,7 @@ async function installGeminiGlobalConfig() {
|
|
|
23446
23698
|
const updatedContent2 = `${existingContent}
|
|
23447
23699
|
|
|
23448
23700
|
${templateContent}`;
|
|
23449
|
-
|
|
23701
|
+
fs46.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
|
|
23450
23702
|
return { success: true, action: "appended" };
|
|
23451
23703
|
}
|
|
23452
23704
|
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
|
|
@@ -23458,7 +23710,7 @@ ${templateContent}`;
|
|
|
23458
23710
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
23459
23711
|
);
|
|
23460
23712
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
23461
|
-
|
|
23713
|
+
fs46.writeFileSync(globalConfigPath, updatedContent, "utf-8");
|
|
23462
23714
|
return { success: true, action: "updated" };
|
|
23463
23715
|
} catch (error) {
|
|
23464
23716
|
console.error(`Gemini config warning: ${error.message}`);
|
|
@@ -23467,18 +23719,18 @@ ${templateContent}`;
|
|
|
23467
23719
|
}
|
|
23468
23720
|
async function installAntigravitySkill() {
|
|
23469
23721
|
try {
|
|
23470
|
-
const antigravitySkillsDir =
|
|
23471
|
-
const prjctSkillDir =
|
|
23472
|
-
const skillMdPath =
|
|
23473
|
-
const templatePath =
|
|
23474
|
-
|
|
23475
|
-
const fileExists2 =
|
|
23476
|
-
if (!
|
|
23722
|
+
const antigravitySkillsDir = path49.join(os13.homedir(), ".gemini", "antigravity", "skills");
|
|
23723
|
+
const prjctSkillDir = path49.join(antigravitySkillsDir, "prjct");
|
|
23724
|
+
const skillMdPath = path49.join(prjctSkillDir, "SKILL.md");
|
|
23725
|
+
const templatePath = path49.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
|
|
23726
|
+
fs46.mkdirSync(prjctSkillDir, { recursive: true });
|
|
23727
|
+
const fileExists2 = fs46.existsSync(skillMdPath);
|
|
23728
|
+
if (!fs46.existsSync(templatePath)) {
|
|
23477
23729
|
console.error("Antigravity SKILL.md template not found");
|
|
23478
23730
|
return { success: false, action: null };
|
|
23479
23731
|
}
|
|
23480
|
-
const templateContent =
|
|
23481
|
-
|
|
23732
|
+
const templateContent = fs46.readFileSync(templatePath, "utf-8");
|
|
23733
|
+
fs46.writeFileSync(skillMdPath, templateContent, "utf-8");
|
|
23482
23734
|
return { success: true, action: fileExists2 ? "updated" : "created" };
|
|
23483
23735
|
} catch (error) {
|
|
23484
23736
|
console.error(`Antigravity skill warning: ${error.message}`);
|
|
@@ -23497,24 +23749,24 @@ async function installCursorProject(projectRoot) {
|
|
|
23497
23749
|
gitignoreUpdated: false
|
|
23498
23750
|
};
|
|
23499
23751
|
try {
|
|
23500
|
-
const cursorDir =
|
|
23501
|
-
const rulesDir =
|
|
23502
|
-
const commandsDir =
|
|
23503
|
-
const routerMdcDest =
|
|
23504
|
-
const routerMdcSource =
|
|
23505
|
-
const cursorCommandsSource =
|
|
23506
|
-
|
|
23507
|
-
|
|
23508
|
-
if (
|
|
23509
|
-
|
|
23752
|
+
const cursorDir = path49.join(projectRoot, ".cursor");
|
|
23753
|
+
const rulesDir = path49.join(cursorDir, "rules");
|
|
23754
|
+
const commandsDir = path49.join(cursorDir, "commands");
|
|
23755
|
+
const routerMdcDest = path49.join(rulesDir, "prjct.mdc");
|
|
23756
|
+
const routerMdcSource = path49.join(getPackageRoot(), "templates", "cursor", "router.mdc");
|
|
23757
|
+
const cursorCommandsSource = path49.join(getPackageRoot(), "templates", "cursor", "commands");
|
|
23758
|
+
fs46.mkdirSync(rulesDir, { recursive: true });
|
|
23759
|
+
fs46.mkdirSync(commandsDir, { recursive: true });
|
|
23760
|
+
if (fs46.existsSync(routerMdcSource)) {
|
|
23761
|
+
fs46.copyFileSync(routerMdcSource, routerMdcDest);
|
|
23510
23762
|
result.rulesCreated = true;
|
|
23511
23763
|
}
|
|
23512
|
-
if (
|
|
23513
|
-
const commandFiles =
|
|
23764
|
+
if (fs46.existsSync(cursorCommandsSource)) {
|
|
23765
|
+
const commandFiles = fs46.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
|
|
23514
23766
|
for (const file of commandFiles) {
|
|
23515
|
-
const src =
|
|
23516
|
-
const dest =
|
|
23517
|
-
|
|
23767
|
+
const src = path49.join(cursorCommandsSource, file);
|
|
23768
|
+
const dest = path49.join(commandsDir, file);
|
|
23769
|
+
fs46.copyFileSync(src, dest);
|
|
23518
23770
|
}
|
|
23519
23771
|
result.commandsCreated = commandFiles.length > 0;
|
|
23520
23772
|
}
|
|
@@ -23528,7 +23780,7 @@ async function installCursorProject(projectRoot) {
|
|
|
23528
23780
|
}
|
|
23529
23781
|
async function addCursorToGitignore(projectRoot) {
|
|
23530
23782
|
try {
|
|
23531
|
-
const gitignorePath =
|
|
23783
|
+
const gitignorePath = path49.join(projectRoot, ".gitignore");
|
|
23532
23784
|
const entriesToAdd = [
|
|
23533
23785
|
"# prjct Cursor routers (regenerated per-developer)",
|
|
23534
23786
|
".cursor/rules/prjct.mdc",
|
|
@@ -23543,7 +23795,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
23543
23795
|
let content = "";
|
|
23544
23796
|
let fileExists2 = false;
|
|
23545
23797
|
try {
|
|
23546
|
-
content =
|
|
23798
|
+
content = fs46.readFileSync(gitignorePath, "utf-8");
|
|
23547
23799
|
fileExists2 = true;
|
|
23548
23800
|
} catch (error) {
|
|
23549
23801
|
if (!isNotFoundError(error)) {
|
|
@@ -23558,7 +23810,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
23558
23810
|
${entriesToAdd.join("\n")}
|
|
23559
23811
|
` : `${entriesToAdd.join("\n")}
|
|
23560
23812
|
`;
|
|
23561
|
-
|
|
23813
|
+
fs46.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
23562
23814
|
return true;
|
|
23563
23815
|
} catch (error) {
|
|
23564
23816
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -23566,12 +23818,12 @@ ${entriesToAdd.join("\n")}
|
|
|
23566
23818
|
}
|
|
23567
23819
|
}
|
|
23568
23820
|
function hasCursorProject(projectRoot) {
|
|
23569
|
-
return
|
|
23821
|
+
return fs46.existsSync(path49.join(projectRoot, ".cursor"));
|
|
23570
23822
|
}
|
|
23571
23823
|
function needsCursorRegeneration(projectRoot) {
|
|
23572
|
-
const cursorDir =
|
|
23573
|
-
const routerPath =
|
|
23574
|
-
return
|
|
23824
|
+
const cursorDir = path49.join(projectRoot, ".cursor");
|
|
23825
|
+
const routerPath = path49.join(cursorDir, "rules", "prjct.mdc");
|
|
23826
|
+
return fs46.existsSync(cursorDir) && !fs46.existsSync(routerPath);
|
|
23575
23827
|
}
|
|
23576
23828
|
async function installWindsurfProject(projectRoot) {
|
|
23577
23829
|
const result = {
|
|
@@ -23581,29 +23833,29 @@ async function installWindsurfProject(projectRoot) {
|
|
|
23581
23833
|
gitignoreUpdated: false
|
|
23582
23834
|
};
|
|
23583
23835
|
try {
|
|
23584
|
-
const windsurfDir =
|
|
23585
|
-
const rulesDir =
|
|
23586
|
-
const workflowsDir =
|
|
23587
|
-
const routerDest =
|
|
23588
|
-
const routerSource =
|
|
23589
|
-
const windsurfWorkflowsSource =
|
|
23836
|
+
const windsurfDir = path49.join(projectRoot, ".windsurf");
|
|
23837
|
+
const rulesDir = path49.join(windsurfDir, "rules");
|
|
23838
|
+
const workflowsDir = path49.join(windsurfDir, "workflows");
|
|
23839
|
+
const routerDest = path49.join(rulesDir, "prjct.md");
|
|
23840
|
+
const routerSource = path49.join(getPackageRoot(), "templates", "windsurf", "router.md");
|
|
23841
|
+
const windsurfWorkflowsSource = path49.join(
|
|
23590
23842
|
getPackageRoot(),
|
|
23591
23843
|
"templates",
|
|
23592
23844
|
"windsurf",
|
|
23593
23845
|
"workflows"
|
|
23594
23846
|
);
|
|
23595
|
-
|
|
23596
|
-
|
|
23597
|
-
if (
|
|
23598
|
-
|
|
23847
|
+
fs46.mkdirSync(rulesDir, { recursive: true });
|
|
23848
|
+
fs46.mkdirSync(workflowsDir, { recursive: true });
|
|
23849
|
+
if (fs46.existsSync(routerSource)) {
|
|
23850
|
+
fs46.copyFileSync(routerSource, routerDest);
|
|
23599
23851
|
result.rulesCreated = true;
|
|
23600
23852
|
}
|
|
23601
|
-
if (
|
|
23602
|
-
const workflowFiles =
|
|
23853
|
+
if (fs46.existsSync(windsurfWorkflowsSource)) {
|
|
23854
|
+
const workflowFiles = fs46.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
|
|
23603
23855
|
for (const file of workflowFiles) {
|
|
23604
|
-
const src =
|
|
23605
|
-
const dest =
|
|
23606
|
-
|
|
23856
|
+
const src = path49.join(windsurfWorkflowsSource, file);
|
|
23857
|
+
const dest = path49.join(workflowsDir, file);
|
|
23858
|
+
fs46.copyFileSync(src, dest);
|
|
23607
23859
|
}
|
|
23608
23860
|
result.workflowsCreated = workflowFiles.length > 0;
|
|
23609
23861
|
}
|
|
@@ -23617,7 +23869,7 @@ async function installWindsurfProject(projectRoot) {
|
|
|
23617
23869
|
}
|
|
23618
23870
|
async function addWindsurfToGitignore(projectRoot) {
|
|
23619
23871
|
try {
|
|
23620
|
-
const gitignorePath =
|
|
23872
|
+
const gitignorePath = path49.join(projectRoot, ".gitignore");
|
|
23621
23873
|
const entriesToAdd = [
|
|
23622
23874
|
"# prjct Windsurf routers (regenerated per-developer)",
|
|
23623
23875
|
".windsurf/rules/prjct.md",
|
|
@@ -23632,7 +23884,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
23632
23884
|
let content = "";
|
|
23633
23885
|
let fileExists2 = false;
|
|
23634
23886
|
try {
|
|
23635
|
-
content =
|
|
23887
|
+
content = fs46.readFileSync(gitignorePath, "utf-8");
|
|
23636
23888
|
fileExists2 = true;
|
|
23637
23889
|
} catch (error) {
|
|
23638
23890
|
if (!isNotFoundError(error)) {
|
|
@@ -23647,7 +23899,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
23647
23899
|
${entriesToAdd.join("\n")}
|
|
23648
23900
|
` : `${entriesToAdd.join("\n")}
|
|
23649
23901
|
`;
|
|
23650
|
-
|
|
23902
|
+
fs46.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
23651
23903
|
return true;
|
|
23652
23904
|
} catch (error) {
|
|
23653
23905
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -23655,32 +23907,32 @@ ${entriesToAdd.join("\n")}
|
|
|
23655
23907
|
}
|
|
23656
23908
|
}
|
|
23657
23909
|
function hasWindsurfProject(projectRoot) {
|
|
23658
|
-
return
|
|
23910
|
+
return fs46.existsSync(path49.join(projectRoot, ".windsurf"));
|
|
23659
23911
|
}
|
|
23660
23912
|
function needsWindsurfRegeneration(projectRoot) {
|
|
23661
|
-
const windsurfDir =
|
|
23662
|
-
const routerPath =
|
|
23663
|
-
return
|
|
23913
|
+
const windsurfDir = path49.join(projectRoot, ".windsurf");
|
|
23914
|
+
const routerPath = path49.join(windsurfDir, "rules", "prjct.md");
|
|
23915
|
+
return fs46.existsSync(windsurfDir) && !fs46.existsSync(routerPath);
|
|
23664
23916
|
}
|
|
23665
23917
|
async function migrateProjectsCliVersion() {
|
|
23666
23918
|
try {
|
|
23667
|
-
const projectsDir =
|
|
23668
|
-
if (!
|
|
23919
|
+
const projectsDir = path49.join(os13.homedir(), ".prjct-cli", "projects");
|
|
23920
|
+
if (!fs46.existsSync(projectsDir)) {
|
|
23669
23921
|
return;
|
|
23670
23922
|
}
|
|
23671
|
-
const projectDirs =
|
|
23923
|
+
const projectDirs = fs46.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
23672
23924
|
let migrated = 0;
|
|
23673
23925
|
for (const projectId of projectDirs) {
|
|
23674
|
-
const projectJsonPath =
|
|
23675
|
-
if (!
|
|
23926
|
+
const projectJsonPath = path49.join(projectsDir, projectId, "project.json");
|
|
23927
|
+
if (!fs46.existsSync(projectJsonPath)) {
|
|
23676
23928
|
continue;
|
|
23677
23929
|
}
|
|
23678
23930
|
try {
|
|
23679
|
-
const content =
|
|
23931
|
+
const content = fs46.readFileSync(projectJsonPath, "utf8");
|
|
23680
23932
|
const project = JSON.parse(content);
|
|
23681
23933
|
if (project.cliVersion !== VERSION) {
|
|
23682
23934
|
project.cliVersion = VERSION;
|
|
23683
|
-
|
|
23935
|
+
fs46.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
23684
23936
|
migrated++;
|
|
23685
23937
|
}
|
|
23686
23938
|
} catch (error) {
|
|
@@ -23700,9 +23952,9 @@ async function migrateProjectsCliVersion() {
|
|
|
23700
23952
|
}
|
|
23701
23953
|
function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
23702
23954
|
let settings = {};
|
|
23703
|
-
if (
|
|
23955
|
+
if (fs46.existsSync(settingsPath)) {
|
|
23704
23956
|
try {
|
|
23705
|
-
settings = JSON.parse(
|
|
23957
|
+
settings = JSON.parse(fs46.readFileSync(settingsPath, "utf8"));
|
|
23706
23958
|
} catch (error) {
|
|
23707
23959
|
if (!(error instanceof SyntaxError)) {
|
|
23708
23960
|
throw error;
|
|
@@ -23710,42 +23962,42 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
|
23710
23962
|
}
|
|
23711
23963
|
}
|
|
23712
23964
|
settings.statusLine = { type: "command", command: statusLinePath };
|
|
23713
|
-
|
|
23965
|
+
fs46.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
23714
23966
|
}
|
|
23715
23967
|
async function installStatusLine() {
|
|
23716
23968
|
try {
|
|
23717
|
-
const claudeDir =
|
|
23718
|
-
const settingsPath =
|
|
23719
|
-
const claudeStatusLinePath =
|
|
23720
|
-
const prjctStatusLineDir =
|
|
23721
|
-
const prjctStatusLinePath =
|
|
23722
|
-
const prjctThemesDir =
|
|
23723
|
-
const prjctLibDir =
|
|
23724
|
-
const prjctComponentsDir =
|
|
23725
|
-
const prjctConfigPath =
|
|
23726
|
-
const assetsDir =
|
|
23727
|
-
const sourceScript =
|
|
23728
|
-
const sourceThemeDir =
|
|
23729
|
-
const sourceLibDir =
|
|
23730
|
-
const sourceComponentsDir =
|
|
23731
|
-
const sourceConfigPath =
|
|
23732
|
-
if (!
|
|
23733
|
-
|
|
23734
|
-
}
|
|
23735
|
-
if (!
|
|
23736
|
-
|
|
23737
|
-
}
|
|
23738
|
-
if (!
|
|
23739
|
-
|
|
23740
|
-
}
|
|
23741
|
-
if (!
|
|
23742
|
-
|
|
23743
|
-
}
|
|
23744
|
-
if (!
|
|
23745
|
-
|
|
23746
|
-
}
|
|
23747
|
-
if (
|
|
23748
|
-
const existingContent =
|
|
23969
|
+
const claudeDir = path49.join(os13.homedir(), ".claude");
|
|
23970
|
+
const settingsPath = path49.join(claudeDir, "settings.json");
|
|
23971
|
+
const claudeStatusLinePath = path49.join(claudeDir, "prjct-statusline.sh");
|
|
23972
|
+
const prjctStatusLineDir = path49.join(os13.homedir(), ".prjct-cli", "statusline");
|
|
23973
|
+
const prjctStatusLinePath = path49.join(prjctStatusLineDir, "statusline.sh");
|
|
23974
|
+
const prjctThemesDir = path49.join(prjctStatusLineDir, "themes");
|
|
23975
|
+
const prjctLibDir = path49.join(prjctStatusLineDir, "lib");
|
|
23976
|
+
const prjctComponentsDir = path49.join(prjctStatusLineDir, "components");
|
|
23977
|
+
const prjctConfigPath = path49.join(prjctStatusLineDir, "config.json");
|
|
23978
|
+
const assetsDir = path49.join(getPackageRoot(), "assets", "statusline");
|
|
23979
|
+
const sourceScript = path49.join(assetsDir, "statusline.sh");
|
|
23980
|
+
const sourceThemeDir = path49.join(assetsDir, "themes");
|
|
23981
|
+
const sourceLibDir = path49.join(assetsDir, "lib");
|
|
23982
|
+
const sourceComponentsDir = path49.join(assetsDir, "components");
|
|
23983
|
+
const sourceConfigPath = path49.join(assetsDir, "default-config.json");
|
|
23984
|
+
if (!fs46.existsSync(claudeDir)) {
|
|
23985
|
+
fs46.mkdirSync(claudeDir, { recursive: true });
|
|
23986
|
+
}
|
|
23987
|
+
if (!fs46.existsSync(prjctStatusLineDir)) {
|
|
23988
|
+
fs46.mkdirSync(prjctStatusLineDir, { recursive: true });
|
|
23989
|
+
}
|
|
23990
|
+
if (!fs46.existsSync(prjctThemesDir)) {
|
|
23991
|
+
fs46.mkdirSync(prjctThemesDir, { recursive: true });
|
|
23992
|
+
}
|
|
23993
|
+
if (!fs46.existsSync(prjctLibDir)) {
|
|
23994
|
+
fs46.mkdirSync(prjctLibDir, { recursive: true });
|
|
23995
|
+
}
|
|
23996
|
+
if (!fs46.existsSync(prjctComponentsDir)) {
|
|
23997
|
+
fs46.mkdirSync(prjctComponentsDir, { recursive: true });
|
|
23998
|
+
}
|
|
23999
|
+
if (fs46.existsSync(prjctStatusLinePath)) {
|
|
24000
|
+
const existingContent = fs46.readFileSync(prjctStatusLinePath, "utf8");
|
|
23749
24001
|
if (existingContent.includes("CLI_VERSION=")) {
|
|
23750
24002
|
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
23751
24003
|
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
@@ -23753,7 +24005,7 @@ async function installStatusLine() {
|
|
|
23753
24005
|
/CLI_VERSION="[^"]*"/,
|
|
23754
24006
|
`CLI_VERSION="${VERSION}"`
|
|
23755
24007
|
);
|
|
23756
|
-
|
|
24008
|
+
fs46.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
23757
24009
|
}
|
|
23758
24010
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
23759
24011
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
@@ -23762,22 +24014,22 @@ async function installStatusLine() {
|
|
|
23762
24014
|
return;
|
|
23763
24015
|
}
|
|
23764
24016
|
}
|
|
23765
|
-
if (
|
|
23766
|
-
let scriptContent =
|
|
24017
|
+
if (fs46.existsSync(sourceScript)) {
|
|
24018
|
+
let scriptContent = fs46.readFileSync(sourceScript, "utf8");
|
|
23767
24019
|
scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
|
|
23768
|
-
|
|
24020
|
+
fs46.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
23769
24021
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
23770
24022
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
23771
|
-
if (
|
|
23772
|
-
const themes =
|
|
24023
|
+
if (fs46.existsSync(sourceThemeDir)) {
|
|
24024
|
+
const themes = fs46.readdirSync(sourceThemeDir);
|
|
23773
24025
|
for (const theme of themes) {
|
|
23774
|
-
const src =
|
|
23775
|
-
const dest =
|
|
23776
|
-
|
|
24026
|
+
const src = path49.join(sourceThemeDir, theme);
|
|
24027
|
+
const dest = path49.join(prjctThemesDir, theme);
|
|
24028
|
+
fs46.copyFileSync(src, dest);
|
|
23777
24029
|
}
|
|
23778
24030
|
}
|
|
23779
|
-
if (!
|
|
23780
|
-
|
|
24031
|
+
if (!fs46.existsSync(prjctConfigPath) && fs46.existsSync(sourceConfigPath)) {
|
|
24032
|
+
fs46.copyFileSync(sourceConfigPath, prjctConfigPath);
|
|
23781
24033
|
}
|
|
23782
24034
|
} else {
|
|
23783
24035
|
const scriptContent = `#!/bin/bash
|
|
@@ -23812,7 +24064,7 @@ if [ -f "$CONFIG" ]; then
|
|
|
23812
24064
|
fi
|
|
23813
24065
|
echo "prjct"
|
|
23814
24066
|
`;
|
|
23815
|
-
|
|
24067
|
+
fs46.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
23816
24068
|
}
|
|
23817
24069
|
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
23818
24070
|
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
@@ -23824,10 +24076,10 @@ echo "prjct"
|
|
|
23824
24076
|
}
|
|
23825
24077
|
async function installContext7MCP() {
|
|
23826
24078
|
try {
|
|
23827
|
-
const claudeDir =
|
|
23828
|
-
const mcpConfigPath =
|
|
23829
|
-
if (!
|
|
23830
|
-
|
|
24079
|
+
const claudeDir = path49.join(os13.homedir(), ".claude");
|
|
24080
|
+
const mcpConfigPath = path49.join(claudeDir, "mcp.json");
|
|
24081
|
+
if (!fs46.existsSync(claudeDir)) {
|
|
24082
|
+
fs46.mkdirSync(claudeDir, { recursive: true });
|
|
23831
24083
|
}
|
|
23832
24084
|
const context7Config = {
|
|
23833
24085
|
mcpServers: {
|
|
@@ -23837,54 +24089,54 @@ async function installContext7MCP() {
|
|
|
23837
24089
|
}
|
|
23838
24090
|
}
|
|
23839
24091
|
};
|
|
23840
|
-
if (
|
|
23841
|
-
const existingContent =
|
|
24092
|
+
if (fs46.existsSync(mcpConfigPath)) {
|
|
24093
|
+
const existingContent = fs46.readFileSync(mcpConfigPath, "utf-8");
|
|
23842
24094
|
const existingConfig = JSON.parse(existingContent);
|
|
23843
24095
|
if (existingConfig.mcpServers?.context7) {
|
|
23844
24096
|
return;
|
|
23845
24097
|
}
|
|
23846
24098
|
existingConfig.mcpServers = existingConfig.mcpServers || {};
|
|
23847
24099
|
existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
|
|
23848
|
-
|
|
24100
|
+
fs46.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
|
|
23849
24101
|
} else {
|
|
23850
|
-
|
|
24102
|
+
fs46.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
|
|
23851
24103
|
}
|
|
23852
24104
|
} catch (error) {
|
|
23853
24105
|
console.error(`Context7 MCP setup warning: ${error.message}`);
|
|
23854
24106
|
}
|
|
23855
24107
|
}
|
|
23856
24108
|
function installStatusLineModules(sourceDir, destDir) {
|
|
23857
|
-
if (!
|
|
24109
|
+
if (!fs46.existsSync(sourceDir)) {
|
|
23858
24110
|
return;
|
|
23859
24111
|
}
|
|
23860
|
-
const files =
|
|
24112
|
+
const files = fs46.readdirSync(sourceDir);
|
|
23861
24113
|
for (const file of files) {
|
|
23862
24114
|
if (file.endsWith(".sh")) {
|
|
23863
|
-
const src =
|
|
23864
|
-
const dest =
|
|
23865
|
-
|
|
23866
|
-
|
|
24115
|
+
const src = path49.join(sourceDir, file);
|
|
24116
|
+
const dest = path49.join(destDir, file);
|
|
24117
|
+
fs46.copyFileSync(src, dest);
|
|
24118
|
+
fs46.chmodSync(dest, 493);
|
|
23867
24119
|
}
|
|
23868
24120
|
}
|
|
23869
24121
|
}
|
|
23870
24122
|
function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
23871
24123
|
try {
|
|
23872
|
-
if (
|
|
23873
|
-
const stats =
|
|
24124
|
+
if (fs46.existsSync(linkPath)) {
|
|
24125
|
+
const stats = fs46.lstatSync(linkPath);
|
|
23874
24126
|
if (stats.isSymbolicLink()) {
|
|
23875
|
-
const existingTarget =
|
|
24127
|
+
const existingTarget = fs46.readlinkSync(linkPath);
|
|
23876
24128
|
if (existingTarget === targetPath) {
|
|
23877
24129
|
return;
|
|
23878
24130
|
}
|
|
23879
24131
|
}
|
|
23880
|
-
|
|
24132
|
+
fs46.unlinkSync(linkPath);
|
|
23881
24133
|
}
|
|
23882
|
-
|
|
24134
|
+
fs46.symlinkSync(targetPath, linkPath);
|
|
23883
24135
|
} catch (_error) {
|
|
23884
24136
|
try {
|
|
23885
|
-
if (
|
|
23886
|
-
|
|
23887
|
-
|
|
24137
|
+
if (fs46.existsSync(targetPath)) {
|
|
24138
|
+
fs46.copyFileSync(targetPath, linkPath);
|
|
24139
|
+
fs46.chmodSync(linkPath, 493);
|
|
23888
24140
|
}
|
|
23889
24141
|
} catch (copyError) {
|
|
23890
24142
|
if (!isNotFoundError(copyError)) {
|
|
@@ -24297,7 +24549,7 @@ var init_registry2 = __esm({
|
|
|
24297
24549
|
});
|
|
24298
24550
|
|
|
24299
24551
|
// core/commands/analytics.ts
|
|
24300
|
-
import
|
|
24552
|
+
import path50 from "node:path";
|
|
24301
24553
|
var AnalyticsCommands;
|
|
24302
24554
|
var init_analytics = __esm({
|
|
24303
24555
|
"core/commands/analytics.ts"() {
|
|
@@ -24323,7 +24575,7 @@ var init_analytics = __esm({
|
|
|
24323
24575
|
output_default.failWithHint("NO_PROJECT_ID");
|
|
24324
24576
|
return { success: false, error: "No project ID found" };
|
|
24325
24577
|
}
|
|
24326
|
-
const projectName =
|
|
24578
|
+
const projectName = path50.basename(projectPath);
|
|
24327
24579
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
24328
24580
|
const queueTasks = await queueStorage.getActiveTasks(projectId);
|
|
24329
24581
|
const shipped = await shippedStorage.getRecent(projectId, 5);
|
|
@@ -24575,8 +24827,8 @@ ${"\u2550".repeat(50)}
|
|
|
24575
24827
|
});
|
|
24576
24828
|
|
|
24577
24829
|
// core/commands/context.ts
|
|
24578
|
-
import
|
|
24579
|
-
import
|
|
24830
|
+
import fs47 from "node:fs/promises";
|
|
24831
|
+
import path51 from "node:path";
|
|
24580
24832
|
var ContextCommands, contextCommands;
|
|
24581
24833
|
var init_context = __esm({
|
|
24582
24834
|
"core/commands/context.ts"() {
|
|
@@ -24702,8 +24954,8 @@ var init_context = __esm({
|
|
|
24702
24954
|
*/
|
|
24703
24955
|
async loadRepoAnalysis(globalPath) {
|
|
24704
24956
|
try {
|
|
24705
|
-
const analysisPath =
|
|
24706
|
-
const content = await
|
|
24957
|
+
const analysisPath = path51.join(globalPath, "analysis", "repo-analysis.json");
|
|
24958
|
+
const content = await fs47.readFile(analysisPath, "utf-8");
|
|
24707
24959
|
const data = JSON.parse(content);
|
|
24708
24960
|
return {
|
|
24709
24961
|
ecosystem: data.ecosystem || "unknown",
|
|
@@ -24722,7 +24974,7 @@ var init_context = __esm({
|
|
|
24722
24974
|
});
|
|
24723
24975
|
|
|
24724
24976
|
// core/commands/cleanup.ts
|
|
24725
|
-
import
|
|
24977
|
+
import path52 from "node:path";
|
|
24726
24978
|
async function cleanupMemory(projectPath) {
|
|
24727
24979
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
24728
24980
|
const results = { rotated: [], totalSize: 0, freedSpace: 0 };
|
|
@@ -24738,7 +24990,7 @@ async function cleanupMemory(projectPath) {
|
|
|
24738
24990
|
results.totalSize += sizeMB;
|
|
24739
24991
|
const rotated = await jsonl_helper_default.rotateJsonLinesIfNeeded(filePath, 10);
|
|
24740
24992
|
if (rotated) {
|
|
24741
|
-
results.rotated.push(
|
|
24993
|
+
results.rotated.push(path52.basename(filePath));
|
|
24742
24994
|
results.freedSpace += sizeMB;
|
|
24743
24995
|
}
|
|
24744
24996
|
}
|
|
@@ -24845,7 +25097,7 @@ var init_cleanup = __esm({
|
|
|
24845
25097
|
});
|
|
24846
25098
|
|
|
24847
25099
|
// core/commands/design.ts
|
|
24848
|
-
import
|
|
25100
|
+
import path53 from "node:path";
|
|
24849
25101
|
async function design(target = null, options = {}, projectPath = process.cwd()) {
|
|
24850
25102
|
try {
|
|
24851
25103
|
const designType = options.type || "architecture";
|
|
@@ -24857,7 +25109,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
24857
25109
|
const designTarget = target || "system";
|
|
24858
25110
|
output_default.spin(`designing ${designType}...`);
|
|
24859
25111
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
24860
|
-
const designsPath =
|
|
25112
|
+
const designsPath = path53.join(
|
|
24861
25113
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
24862
25114
|
"planning",
|
|
24863
25115
|
"designs"
|
|
@@ -24897,7 +25149,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
24897
25149
|
break;
|
|
24898
25150
|
}
|
|
24899
25151
|
const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
|
|
24900
|
-
const designFilePath =
|
|
25152
|
+
const designFilePath = path53.join(designsPath, designFileName);
|
|
24901
25153
|
await file_helper_exports.writeFile(designFilePath, designContent);
|
|
24902
25154
|
await memoryService.log(projectPath, "design_created", {
|
|
24903
25155
|
type: designType,
|
|
@@ -24921,7 +25173,7 @@ var init_design = __esm({
|
|
|
24921
25173
|
});
|
|
24922
25174
|
|
|
24923
25175
|
// core/commands/snapshots.ts
|
|
24924
|
-
import
|
|
25176
|
+
import path54 from "node:path";
|
|
24925
25177
|
async function recover(projectPath = process.cwd()) {
|
|
24926
25178
|
try {
|
|
24927
25179
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
@@ -24973,7 +25225,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
24973
25225
|
output_default.failWithHint("NO_PROJECT_ID");
|
|
24974
25226
|
return { success: false, error: "No project ID found" };
|
|
24975
25227
|
}
|
|
24976
|
-
const snapshotsPath =
|
|
25228
|
+
const snapshotsPath = path54.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
24977
25229
|
await file_helper_exports.ensureDir(snapshotsPath);
|
|
24978
25230
|
const { execSync: execSync7 } = await import("node:child_process");
|
|
24979
25231
|
try {
|
|
@@ -24991,7 +25243,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
24991
25243
|
cwd: projectPath,
|
|
24992
25244
|
encoding: "utf-8"
|
|
24993
25245
|
});
|
|
24994
|
-
const snapshotFile =
|
|
25246
|
+
const snapshotFile = path54.join(snapshotsPath, "history.json");
|
|
24995
25247
|
let history2 = { snapshots: [], current: -1 };
|
|
24996
25248
|
try {
|
|
24997
25249
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -25031,8 +25283,8 @@ async function redo(projectPath = process.cwd()) {
|
|
|
25031
25283
|
output_default.failWithHint("NO_PROJECT_ID");
|
|
25032
25284
|
return { success: false, error: "No project ID found" };
|
|
25033
25285
|
}
|
|
25034
|
-
const snapshotsPath =
|
|
25035
|
-
const snapshotFile =
|
|
25286
|
+
const snapshotsPath = path54.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
25287
|
+
const snapshotFile = path54.join(snapshotsPath, "history.json");
|
|
25036
25288
|
let history2;
|
|
25037
25289
|
try {
|
|
25038
25290
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -25091,8 +25343,8 @@ async function history(projectPath = process.cwd()) {
|
|
|
25091
25343
|
output_default.failWithHint("NO_PROJECT_ID");
|
|
25092
25344
|
return { success: false, error: "No project ID found" };
|
|
25093
25345
|
}
|
|
25094
|
-
const snapshotsPath =
|
|
25095
|
-
const snapshotFile =
|
|
25346
|
+
const snapshotsPath = path54.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
25347
|
+
const snapshotFile = path54.join(snapshotsPath, "history.json");
|
|
25096
25348
|
let snapshotHistory;
|
|
25097
25349
|
try {
|
|
25098
25350
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -25199,8 +25451,8 @@ var init_maintenance = __esm({
|
|
|
25199
25451
|
});
|
|
25200
25452
|
|
|
25201
25453
|
// core/commands/setup.ts
|
|
25202
|
-
import
|
|
25203
|
-
import
|
|
25454
|
+
import fs48 from "node:fs";
|
|
25455
|
+
import path55 from "node:path";
|
|
25204
25456
|
import chalk16 from "chalk";
|
|
25205
25457
|
var SetupCommands;
|
|
25206
25458
|
var init_setup2 = __esm({
|
|
@@ -25327,7 +25579,7 @@ Please install it first:
|
|
|
25327
25579
|
try {
|
|
25328
25580
|
const claudeDir = path_manager_default.getClaudeDir();
|
|
25329
25581
|
const settingsPath = path_manager_default.getClaudeSettingsPath();
|
|
25330
|
-
const statusLinePath =
|
|
25582
|
+
const statusLinePath = path55.join(claudeDir, "prjct-statusline.sh");
|
|
25331
25583
|
const scriptContent = `#!/bin/bash
|
|
25332
25584
|
# prjct Status Line for Claude Code
|
|
25333
25585
|
# Shows version update notifications and current task
|
|
@@ -25385,11 +25637,11 @@ fi
|
|
|
25385
25637
|
# Default: show prjct branding
|
|
25386
25638
|
echo "\u26A1 prjct"
|
|
25387
25639
|
`;
|
|
25388
|
-
|
|
25640
|
+
fs48.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
25389
25641
|
let settings = {};
|
|
25390
|
-
if (
|
|
25642
|
+
if (fs48.existsSync(settingsPath)) {
|
|
25391
25643
|
try {
|
|
25392
|
-
settings = JSON.parse(
|
|
25644
|
+
settings = JSON.parse(fs48.readFileSync(settingsPath, "utf8"));
|
|
25393
25645
|
} catch (_error) {
|
|
25394
25646
|
}
|
|
25395
25647
|
}
|
|
@@ -25397,7 +25649,7 @@ echo "\u26A1 prjct"
|
|
|
25397
25649
|
type: "command",
|
|
25398
25650
|
command: statusLinePath
|
|
25399
25651
|
};
|
|
25400
|
-
|
|
25652
|
+
fs48.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
25401
25653
|
return { success: true };
|
|
25402
25654
|
} catch (error) {
|
|
25403
25655
|
return { success: false, error: error.message };
|
|
@@ -25453,18 +25705,18 @@ echo "\u26A1 prjct"
|
|
|
25453
25705
|
});
|
|
25454
25706
|
|
|
25455
25707
|
// core/utils/project-commands.ts
|
|
25456
|
-
import
|
|
25708
|
+
import path56 from "node:path";
|
|
25457
25709
|
async function detectPackageManager(projectPath, pkg) {
|
|
25458
25710
|
const declared = pkg?.packageManager?.trim().toLowerCase();
|
|
25459
25711
|
if (declared?.startsWith("pnpm@")) return "pnpm";
|
|
25460
25712
|
if (declared?.startsWith("yarn@")) return "yarn";
|
|
25461
25713
|
if (declared?.startsWith("bun@")) return "bun";
|
|
25462
25714
|
if (declared?.startsWith("npm@")) return "npm";
|
|
25463
|
-
if (await fileExists(
|
|
25464
|
-
if (await fileExists(
|
|
25465
|
-
if (await fileExists(
|
|
25466
|
-
if (await fileExists(
|
|
25467
|
-
if (await fileExists(
|
|
25715
|
+
if (await fileExists(path56.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
|
|
25716
|
+
if (await fileExists(path56.join(projectPath, "yarn.lock"))) return "yarn";
|
|
25717
|
+
if (await fileExists(path56.join(projectPath, "bun.lockb"))) return "bun";
|
|
25718
|
+
if (await fileExists(path56.join(projectPath, "bun.lock"))) return "bun";
|
|
25719
|
+
if (await fileExists(path56.join(projectPath, "package-lock.json"))) return "npm";
|
|
25468
25720
|
return "npm";
|
|
25469
25721
|
}
|
|
25470
25722
|
function pmRun(pm, scriptName) {
|
|
@@ -25480,7 +25732,7 @@ function pmTest(pm) {
|
|
|
25480
25732
|
return "npm test";
|
|
25481
25733
|
}
|
|
25482
25734
|
async function detectProjectCommands(projectPath) {
|
|
25483
|
-
const pkgPath =
|
|
25735
|
+
const pkgPath = path56.join(projectPath, "package.json");
|
|
25484
25736
|
const pkg = await readJson(pkgPath, null);
|
|
25485
25737
|
if (pkg) {
|
|
25486
25738
|
const pm = await detectPackageManager(projectPath, pkg);
|
|
@@ -25497,27 +25749,27 @@ async function detectProjectCommands(projectPath) {
|
|
|
25497
25749
|
}
|
|
25498
25750
|
return result;
|
|
25499
25751
|
}
|
|
25500
|
-
if (await fileExists(
|
|
25752
|
+
if (await fileExists(path56.join(projectPath, "pytest.ini"))) {
|
|
25501
25753
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
25502
25754
|
}
|
|
25503
|
-
const pyproject = await readFile(
|
|
25755
|
+
const pyproject = await readFile(path56.join(projectPath, "pyproject.toml"), "");
|
|
25504
25756
|
if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
|
|
25505
25757
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
25506
25758
|
}
|
|
25507
|
-
if (await fileExists(
|
|
25759
|
+
if (await fileExists(path56.join(projectPath, "Cargo.toml"))) {
|
|
25508
25760
|
return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
|
|
25509
25761
|
}
|
|
25510
|
-
if (await fileExists(
|
|
25762
|
+
if (await fileExists(path56.join(projectPath, "go.mod"))) {
|
|
25511
25763
|
return { stack: "go", test: { tool: "go", command: "go test ./..." } };
|
|
25512
25764
|
}
|
|
25513
25765
|
const files = await listFiles(projectPath);
|
|
25514
25766
|
if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
|
|
25515
25767
|
return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
|
|
25516
25768
|
}
|
|
25517
|
-
if (await fileExists(
|
|
25769
|
+
if (await fileExists(path56.join(projectPath, "pom.xml"))) {
|
|
25518
25770
|
return { stack: "java", test: { tool: "maven", command: "mvn test" } };
|
|
25519
25771
|
}
|
|
25520
|
-
if (await fileExists(
|
|
25772
|
+
if (await fileExists(path56.join(projectPath, "gradlew")) && (await fileExists(path56.join(projectPath, "build.gradle")) || await fileExists(path56.join(projectPath, "build.gradle.kts")))) {
|
|
25521
25773
|
return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
|
|
25522
25774
|
}
|
|
25523
25775
|
return { stack: "unknown" };
|
|
@@ -25690,7 +25942,7 @@ var init_workflow_preferences = __esm({
|
|
|
25690
25942
|
});
|
|
25691
25943
|
|
|
25692
25944
|
// core/commands/shipping.ts
|
|
25693
|
-
import
|
|
25945
|
+
import path57 from "node:path";
|
|
25694
25946
|
var ShippingCommands;
|
|
25695
25947
|
var init_shipping = __esm({
|
|
25696
25948
|
"core/commands/shipping.ts"() {
|
|
@@ -25836,7 +26088,7 @@ ${result.stderr}`.trim();
|
|
|
25836
26088
|
*/
|
|
25837
26089
|
async _bumpVersion(projectPath) {
|
|
25838
26090
|
try {
|
|
25839
|
-
const pkgPath =
|
|
26091
|
+
const pkgPath = path57.join(projectPath, "package.json");
|
|
25840
26092
|
const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
|
|
25841
26093
|
const oldVersion = pkg?.version || "0.0.0";
|
|
25842
26094
|
const [major, minor, patch] = oldVersion.split(".").map(Number);
|
|
@@ -25858,7 +26110,7 @@ ${result.stderr}`.trim();
|
|
|
25858
26110
|
*/
|
|
25859
26111
|
async _updateChangelog(feature, version, projectPath) {
|
|
25860
26112
|
try {
|
|
25861
|
-
const changelogPath =
|
|
26113
|
+
const changelogPath = path57.join(projectPath, "CHANGELOG.md");
|
|
25862
26114
|
const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
|
|
25863
26115
|
const entry = `## [${version}] - ${date_helper_default.formatDate(/* @__PURE__ */ new Date())}
|
|
25864
26116
|
|
|
@@ -26750,19 +27002,19 @@ var init_linear = __esm({
|
|
|
26750
27002
|
});
|
|
26751
27003
|
|
|
26752
27004
|
// core/utils/project-credentials.ts
|
|
26753
|
-
import
|
|
27005
|
+
import fs49 from "node:fs";
|
|
26754
27006
|
import os14 from "node:os";
|
|
26755
|
-
import
|
|
27007
|
+
import path58 from "node:path";
|
|
26756
27008
|
function getCredentialsPath(projectId) {
|
|
26757
|
-
return
|
|
27009
|
+
return path58.join(os14.homedir(), ".prjct-cli", "projects", projectId, "config", "credentials.json");
|
|
26758
27010
|
}
|
|
26759
27011
|
async function getProjectCredentials(projectId) {
|
|
26760
27012
|
const credPath = getCredentialsPath(projectId);
|
|
26761
|
-
if (!
|
|
27013
|
+
if (!fs49.existsSync(credPath)) {
|
|
26762
27014
|
return {};
|
|
26763
27015
|
}
|
|
26764
27016
|
try {
|
|
26765
|
-
return JSON.parse(
|
|
27017
|
+
return JSON.parse(fs49.readFileSync(credPath, "utf-8"));
|
|
26766
27018
|
} catch (error) {
|
|
26767
27019
|
console.error("[project-credentials] Failed to read credentials:", error.message);
|
|
26768
27020
|
return {};
|
|
@@ -27339,7 +27591,7 @@ var require_package = __commonJS({
|
|
|
27339
27591
|
"package.json"(exports, module) {
|
|
27340
27592
|
module.exports = {
|
|
27341
27593
|
name: "prjct-cli",
|
|
27342
|
-
version: "1.
|
|
27594
|
+
version: "1.3.0",
|
|
27343
27595
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
27344
27596
|
main: "core/index.ts",
|
|
27345
27597
|
bin: {
|
|
@@ -27446,9 +27698,9 @@ var require_package = __commonJS({
|
|
|
27446
27698
|
|
|
27447
27699
|
// core/index.ts
|
|
27448
27700
|
var core_exports = {};
|
|
27449
|
-
import
|
|
27701
|
+
import fs50 from "node:fs";
|
|
27450
27702
|
import os15 from "node:os";
|
|
27451
|
-
import
|
|
27703
|
+
import path59 from "node:path";
|
|
27452
27704
|
import chalk18 from "chalk";
|
|
27453
27705
|
async function main() {
|
|
27454
27706
|
const [commandName, ...rawArgs] = process.argv.slice(2);
|
|
@@ -27488,6 +27740,16 @@ Use 'prjct --help' to see available commands.`);
|
|
|
27488
27740
|
process.exit(1);
|
|
27489
27741
|
}
|
|
27490
27742
|
const { parsedArgs, options } = parseCommandArgs(cmd, rawArgs);
|
|
27743
|
+
let projectId = null;
|
|
27744
|
+
const commandStartTime = Date.now();
|
|
27745
|
+
try {
|
|
27746
|
+
projectId = await config_manager_default.getProjectId(process.cwd());
|
|
27747
|
+
if (projectId) {
|
|
27748
|
+
await sessionTracker.expireIfStale(projectId);
|
|
27749
|
+
await sessionTracker.touch(projectId);
|
|
27750
|
+
}
|
|
27751
|
+
} catch {
|
|
27752
|
+
}
|
|
27491
27753
|
const commands = new PrjctCommands();
|
|
27492
27754
|
let result;
|
|
27493
27755
|
if (commandName === "design") {
|
|
@@ -27547,6 +27809,13 @@ Use 'prjct --help' to see available commands.`);
|
|
|
27547
27809
|
throw new Error(`Command '${commandName}' has no handler`);
|
|
27548
27810
|
}
|
|
27549
27811
|
}
|
|
27812
|
+
if (projectId) {
|
|
27813
|
+
const durationMs = Date.now() - commandStartTime;
|
|
27814
|
+
try {
|
|
27815
|
+
await sessionTracker.trackCommand(projectId, commandName, durationMs);
|
|
27816
|
+
} catch {
|
|
27817
|
+
}
|
|
27818
|
+
}
|
|
27550
27819
|
if (result?.message) {
|
|
27551
27820
|
console.log(result.message);
|
|
27552
27821
|
}
|
|
@@ -27581,12 +27850,12 @@ function parseCommandArgs(_cmd, rawArgs) {
|
|
|
27581
27850
|
}
|
|
27582
27851
|
function displayVersion(version) {
|
|
27583
27852
|
const detection = detectAllProviders();
|
|
27584
|
-
const claudeCommandPath =
|
|
27585
|
-
const geminiCommandPath =
|
|
27586
|
-
const claudeConfigured =
|
|
27587
|
-
const geminiConfigured =
|
|
27588
|
-
const cursorConfigured =
|
|
27589
|
-
const cursorExists =
|
|
27853
|
+
const claudeCommandPath = path59.join(os15.homedir(), ".claude", "commands", "p.md");
|
|
27854
|
+
const geminiCommandPath = path59.join(os15.homedir(), ".gemini", "commands", "p.toml");
|
|
27855
|
+
const claudeConfigured = fs50.existsSync(claudeCommandPath);
|
|
27856
|
+
const geminiConfigured = fs50.existsSync(geminiCommandPath);
|
|
27857
|
+
const cursorConfigured = fs50.existsSync(path59.join(process.cwd(), ".cursor", "commands", "sync.md"));
|
|
27858
|
+
const cursorExists = fs50.existsSync(path59.join(process.cwd(), ".cursor"));
|
|
27590
27859
|
console.log(`
|
|
27591
27860
|
${chalk18.cyan("p/")} prjct v${version}
|
|
27592
27861
|
${chalk18.dim("Context layer for AI coding agents")}
|
|
@@ -27695,6 +27964,8 @@ var init_core = __esm({
|
|
|
27695
27964
|
init_registry2();
|
|
27696
27965
|
init_register();
|
|
27697
27966
|
init_ai_provider();
|
|
27967
|
+
init_config_manager();
|
|
27968
|
+
init_session_tracker();
|
|
27698
27969
|
init_output();
|
|
27699
27970
|
__name(main, "main");
|
|
27700
27971
|
__name(parseCommandArgs, "parseCommandArgs");
|
|
@@ -27714,9 +27985,9 @@ var init_core = __esm({
|
|
|
27714
27985
|
init_ai_provider();
|
|
27715
27986
|
init_config_manager();
|
|
27716
27987
|
init_editors_config();
|
|
27717
|
-
import
|
|
27988
|
+
import fs51 from "node:fs";
|
|
27718
27989
|
import os16 from "node:os";
|
|
27719
|
-
import
|
|
27990
|
+
import path60 from "node:path";
|
|
27720
27991
|
import chalk19 from "chalk";
|
|
27721
27992
|
|
|
27722
27993
|
// core/server/server.ts
|
|
@@ -28459,14 +28730,14 @@ function checkRoutersInstalled() {
|
|
|
28459
28730
|
const home = os16.homedir();
|
|
28460
28731
|
const detection = detectAllProviders();
|
|
28461
28732
|
if (detection.claude.installed) {
|
|
28462
|
-
const claudeRouter =
|
|
28463
|
-
if (!
|
|
28733
|
+
const claudeRouter = path60.join(home, ".claude", "commands", "p.md");
|
|
28734
|
+
if (!fs51.existsSync(claudeRouter)) {
|
|
28464
28735
|
return false;
|
|
28465
28736
|
}
|
|
28466
28737
|
}
|
|
28467
28738
|
if (detection.gemini.installed) {
|
|
28468
|
-
const geminiRouter =
|
|
28469
|
-
if (!
|
|
28739
|
+
const geminiRouter = path60.join(home, ".gemini", "commands", "p.toml");
|
|
28740
|
+
if (!fs51.existsSync(geminiRouter)) {
|
|
28470
28741
|
return false;
|
|
28471
28742
|
}
|
|
28472
28743
|
}
|
|
@@ -28484,6 +28755,26 @@ if (isQuietMode2) {
|
|
|
28484
28755
|
const { setQuietMode: setQuietMode2 } = await Promise.resolve().then(() => (init_output(), output_exports));
|
|
28485
28756
|
setQuietMode2(true);
|
|
28486
28757
|
}
|
|
28758
|
+
async function trackSession(command) {
|
|
28759
|
+
const start = Date.now();
|
|
28760
|
+
try {
|
|
28761
|
+
const projectId = await config_manager_default.getProjectId(process.cwd());
|
|
28762
|
+
if (projectId) {
|
|
28763
|
+
const { sessionTracker: sessionTracker2 } = await Promise.resolve().then(() => (init_session_tracker(), session_tracker_exports));
|
|
28764
|
+
await sessionTracker2.expireIfStale(projectId);
|
|
28765
|
+
await sessionTracker2.touch(projectId);
|
|
28766
|
+
return () => {
|
|
28767
|
+
const durationMs = Date.now() - start;
|
|
28768
|
+
sessionTracker2.trackCommand(projectId, command, durationMs).catch(() => {
|
|
28769
|
+
});
|
|
28770
|
+
};
|
|
28771
|
+
}
|
|
28772
|
+
} catch {
|
|
28773
|
+
}
|
|
28774
|
+
return () => {
|
|
28775
|
+
};
|
|
28776
|
+
}
|
|
28777
|
+
__name(trackSession, "trackSession");
|
|
28487
28778
|
if (args[0] === "start" || args[0] === "setup") {
|
|
28488
28779
|
const { runStart: runStart2 } = await Promise.resolve().then(() => (init_start(), start_exports));
|
|
28489
28780
|
await runStart2();
|
|
@@ -28513,20 +28804,26 @@ if (args[0] === "start" || args[0] === "setup") {
|
|
|
28513
28804
|
console.error('No prjct project found. Run "prjct init" first.');
|
|
28514
28805
|
process.exitCode = 1;
|
|
28515
28806
|
} else {
|
|
28807
|
+
const done = await trackSession("context");
|
|
28516
28808
|
const { runContextTool: runContextTool2 } = await Promise.resolve().then(() => (init_context_tools(), context_tools_exports));
|
|
28517
28809
|
const result = await runContextTool2(args.slice(1), projectId, projectPath);
|
|
28518
28810
|
console.log(JSON.stringify(result, null, 2));
|
|
28519
28811
|
process.exitCode = result.tool === "error" ? 1 : 0;
|
|
28812
|
+
done();
|
|
28520
28813
|
}
|
|
28521
28814
|
} else if (args[0] === "hooks") {
|
|
28815
|
+
const done = await trackSession("hooks");
|
|
28522
28816
|
const { hooksService: hooksService2 } = await Promise.resolve().then(() => (init_hooks_service(), hooks_service_exports));
|
|
28523
28817
|
const subcommand = args[1] || "status";
|
|
28524
28818
|
const exitCode = await hooksService2.run(process.cwd(), subcommand);
|
|
28525
28819
|
process.exitCode = exitCode;
|
|
28820
|
+
done();
|
|
28526
28821
|
} else if (args[0] === "doctor") {
|
|
28822
|
+
const done = await trackSession("doctor");
|
|
28527
28823
|
const { doctorService: doctorService2 } = await Promise.resolve().then(() => (init_doctor_service(), doctor_service_exports));
|
|
28528
28824
|
const exitCode = await doctorService2.run(process.cwd());
|
|
28529
28825
|
process.exitCode = exitCode;
|
|
28826
|
+
done();
|
|
28530
28827
|
} else if (args[0] === "uninstall") {
|
|
28531
28828
|
const { uninstall: uninstall2 } = await Promise.resolve().then(() => (init_uninstall(), uninstall_exports));
|
|
28532
28829
|
const force = args.includes("--force") || args.includes("-f");
|
|
@@ -28567,7 +28864,7 @@ if (args[0] === "start" || args[0] === "setup") {
|
|
|
28567
28864
|
console.error('No prjct project found. Run "prjct init" first.');
|
|
28568
28865
|
process.exitCode = 1;
|
|
28569
28866
|
} else {
|
|
28570
|
-
const linearCliPath =
|
|
28867
|
+
const linearCliPath = path60.join(__dirname, "..", "core", "cli", "linear.ts");
|
|
28571
28868
|
const linearArgs = ["--project", projectId, ...args.slice(1)];
|
|
28572
28869
|
const child = spawn("bun", [linearCliPath, ...linearArgs], {
|
|
28573
28870
|
stdio: "inherit",
|
|
@@ -28586,12 +28883,12 @@ if (args[0] === "start" || args[0] === "setup") {
|
|
|
28586
28883
|
const detection = detectAllProviders();
|
|
28587
28884
|
const home = os16.homedir();
|
|
28588
28885
|
const cwd = process.cwd();
|
|
28589
|
-
const claudeConfigured =
|
|
28590
|
-
const geminiConfigured =
|
|
28591
|
-
const cursorDetected =
|
|
28592
|
-
const cursorConfigured =
|
|
28593
|
-
const windsurfDetected =
|
|
28594
|
-
const windsurfConfigured =
|
|
28886
|
+
const claudeConfigured = fs51.existsSync(path60.join(home, ".claude", "commands", "p.md"));
|
|
28887
|
+
const geminiConfigured = fs51.existsSync(path60.join(home, ".gemini", "commands", "p.toml"));
|
|
28888
|
+
const cursorDetected = fs51.existsSync(path60.join(cwd, ".cursor"));
|
|
28889
|
+
const cursorConfigured = fs51.existsSync(path60.join(cwd, ".cursor", "rules", "prjct.mdc"));
|
|
28890
|
+
const windsurfDetected = fs51.existsSync(path60.join(cwd, ".windsurf"));
|
|
28891
|
+
const windsurfConfigured = fs51.existsSync(path60.join(cwd, ".windsurf", "rules", "prjct.md"));
|
|
28595
28892
|
console.log(`
|
|
28596
28893
|
${chalk19.cyan("p/")} prjct v${VERSION}
|
|
28597
28894
|
${chalk19.dim("Context layer for AI coding agents")}
|
|
@@ -28629,9 +28926,9 @@ ${chalk19.dim("Run 'prjct init' to configure (Cursor/Windsurf IDE)")}
|
|
|
28629
28926
|
${chalk19.cyan("https://prjct.app")}
|
|
28630
28927
|
`);
|
|
28631
28928
|
} else {
|
|
28632
|
-
const configPath =
|
|
28929
|
+
const configPath = path60.join(os16.homedir(), ".prjct-cli", "config", "installed-editors.json");
|
|
28633
28930
|
const routersInstalled = checkRoutersInstalled();
|
|
28634
|
-
if (!
|
|
28931
|
+
if (!fs51.existsSync(configPath) || !routersInstalled) {
|
|
28635
28932
|
console.log(`
|
|
28636
28933
|
${chalk19.cyan.bold(" Welcome to prjct!")}
|
|
28637
28934
|
|