prjct-cli 0.60.1 → 0.61.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 +71 -0
- package/core/agentic/orchestrator-executor.ts +31 -33
- package/core/domain/agent-loader.ts +8 -8
- package/core/services/local-state-generator.ts +158 -0
- package/core/services/sync-service.ts +11 -0
- package/core/storage/state-storage.ts +3 -0
- package/dist/bin/prjct.mjs +453 -331
- 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) => (path59) => {
|
|
20
|
+
var fn = map[path59];
|
|
21
21
|
if (fn) return fn();
|
|
22
|
-
throw new Error("Module not found in bundle: " +
|
|
22
|
+
throw new Error("Module not found in bundle: " + path59);
|
|
23
23
|
};
|
|
24
24
|
var __esm = (fn, res) => function __init() {
|
|
25
25
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -4019,8 +4019,8 @@ function tryResolve(basePath, projectPath) {
|
|
|
4019
4019
|
for (const ext of extensions) {
|
|
4020
4020
|
const fullPath = basePath + ext;
|
|
4021
4021
|
try {
|
|
4022
|
-
const
|
|
4023
|
-
if (
|
|
4022
|
+
const fs50 = __require("node:fs");
|
|
4023
|
+
if (fs50.existsSync(fullPath) && fs50.statSync(fullPath).isFile()) {
|
|
4024
4024
|
return path12.relative(projectPath, fullPath);
|
|
4025
4025
|
}
|
|
4026
4026
|
} catch {
|
|
@@ -5203,11 +5203,11 @@ async function runSignaturesTool(args2, projectPath) {
|
|
|
5203
5203
|
}
|
|
5204
5204
|
};
|
|
5205
5205
|
}
|
|
5206
|
-
const
|
|
5207
|
-
const
|
|
5208
|
-
const fullPath =
|
|
5206
|
+
const fs50 = await import("node:fs/promises");
|
|
5207
|
+
const path59 = await import("node:path");
|
|
5208
|
+
const fullPath = path59.isAbsolute(filePath) ? filePath : path59.join(projectPath, filePath);
|
|
5209
5209
|
try {
|
|
5210
|
-
const stat = await
|
|
5210
|
+
const stat = await fs50.stat(fullPath);
|
|
5211
5211
|
if (stat.isDirectory()) {
|
|
5212
5212
|
const results = await extractDirectorySignatures(filePath, projectPath, {
|
|
5213
5213
|
recursive: args2.includes("--recursive") || args2.includes("-r")
|
|
@@ -5274,11 +5274,11 @@ async function runSummaryTool(args2, projectPath) {
|
|
|
5274
5274
|
}
|
|
5275
5275
|
};
|
|
5276
5276
|
}
|
|
5277
|
-
const
|
|
5278
|
-
const
|
|
5279
|
-
const fullPath =
|
|
5277
|
+
const fs50 = await import("node:fs/promises");
|
|
5278
|
+
const path59 = await import("node:path");
|
|
5279
|
+
const fullPath = path59.isAbsolute(targetPath) ? targetPath : path59.join(projectPath, targetPath);
|
|
5280
5280
|
try {
|
|
5281
|
-
const stat = await
|
|
5281
|
+
const stat = await fs50.stat(fullPath);
|
|
5282
5282
|
if (stat.isDirectory()) {
|
|
5283
5283
|
const results = await summarizeDirectory(targetPath, projectPath, {
|
|
5284
5284
|
recursive: args2.includes("--recursive") || args2.includes("-r")
|
|
@@ -11788,31 +11788,33 @@ var init_orchestrator_executor = __esm({
|
|
|
11788
11788
|
*
|
|
11789
11789
|
* Reads agent markdown files from {globalPath}/agents/
|
|
11790
11790
|
* and extracts their content and skills from frontmatter.
|
|
11791
|
+
*
|
|
11792
|
+
* Uses parallel file reads for performance (PRJ-110).
|
|
11791
11793
|
*/
|
|
11792
11794
|
async loadAgents(domains, projectId) {
|
|
11793
11795
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
11794
11796
|
const agentsDir = path23.join(globalPath, "agents");
|
|
11795
|
-
const
|
|
11796
|
-
for (const domain of domains) {
|
|
11797
|
+
const agentPromises = domains.map(async (domain) => {
|
|
11797
11798
|
const possibleNames = [`${domain}.md`, `${domain}-agent.md`, `prjct-${domain}.md`];
|
|
11798
11799
|
for (const fileName of possibleNames) {
|
|
11799
11800
|
const filePath = path23.join(agentsDir, fileName);
|
|
11800
11801
|
try {
|
|
11801
11802
|
const content = await fs24.readFile(filePath, "utf-8");
|
|
11802
11803
|
const { frontmatter, body } = this.parseAgentFile(content);
|
|
11803
|
-
|
|
11804
|
+
return {
|
|
11804
11805
|
name: fileName.replace(".md", ""),
|
|
11805
11806
|
domain,
|
|
11806
11807
|
content: body,
|
|
11807
11808
|
skills: frontmatter.skills || [],
|
|
11808
11809
|
filePath
|
|
11809
|
-
}
|
|
11810
|
-
break;
|
|
11810
|
+
};
|
|
11811
11811
|
} catch {
|
|
11812
11812
|
}
|
|
11813
11813
|
}
|
|
11814
|
-
|
|
11815
|
-
|
|
11814
|
+
return null;
|
|
11815
|
+
});
|
|
11816
|
+
const results = await Promise.all(agentPromises);
|
|
11817
|
+
return results.filter((agent) => agent !== null);
|
|
11816
11818
|
}
|
|
11817
11819
|
/**
|
|
11818
11820
|
* Parse agent markdown file to extract frontmatter and body
|
|
@@ -11832,40 +11834,36 @@ var init_orchestrator_executor = __esm({
|
|
|
11832
11834
|
* Load skills from agent frontmatter
|
|
11833
11835
|
*
|
|
11834
11836
|
* Skills are stored in ~/.claude/skills/{name}.md
|
|
11837
|
+
*
|
|
11838
|
+
* Uses parallel file reads for performance (PRJ-110).
|
|
11835
11839
|
*/
|
|
11836
11840
|
async loadSkills(agents) {
|
|
11837
11841
|
const skillsDir = path23.join(os8.homedir(), ".claude", "skills");
|
|
11838
|
-
const
|
|
11839
|
-
const loadedSkillNames = /* @__PURE__ */ new Set();
|
|
11842
|
+
const uniqueSkillNames = /* @__PURE__ */ new Set();
|
|
11840
11843
|
for (const agent of agents) {
|
|
11841
11844
|
for (const skillName of agent.skills) {
|
|
11842
|
-
|
|
11845
|
+
uniqueSkillNames.add(skillName);
|
|
11846
|
+
}
|
|
11847
|
+
}
|
|
11848
|
+
const skillPromises = Array.from(uniqueSkillNames).map(
|
|
11849
|
+
async (skillName) => {
|
|
11843
11850
|
const flatPath = path23.join(skillsDir, `${skillName}.md`);
|
|
11844
11851
|
const subdirPath = path23.join(skillsDir, skillName, "SKILL.md");
|
|
11845
|
-
let content = null;
|
|
11846
|
-
let resolvedPath = flatPath;
|
|
11847
11852
|
try {
|
|
11848
|
-
content = await fs24.readFile(subdirPath, "utf-8");
|
|
11849
|
-
|
|
11853
|
+
const content = await fs24.readFile(subdirPath, "utf-8");
|
|
11854
|
+
return { name: skillName, content, filePath: subdirPath };
|
|
11850
11855
|
} catch {
|
|
11851
11856
|
try {
|
|
11852
|
-
content = await fs24.readFile(flatPath, "utf-8");
|
|
11853
|
-
|
|
11857
|
+
const content = await fs24.readFile(flatPath, "utf-8");
|
|
11858
|
+
return { name: skillName, content, filePath: flatPath };
|
|
11854
11859
|
} catch {
|
|
11855
|
-
|
|
11860
|
+
return null;
|
|
11856
11861
|
}
|
|
11857
11862
|
}
|
|
11858
|
-
if (content) {
|
|
11859
|
-
skills.push({
|
|
11860
|
-
name: skillName,
|
|
11861
|
-
content,
|
|
11862
|
-
filePath: resolvedPath
|
|
11863
|
-
});
|
|
11864
|
-
loadedSkillNames.add(skillName);
|
|
11865
|
-
}
|
|
11866
11863
|
}
|
|
11867
|
-
|
|
11868
|
-
|
|
11864
|
+
);
|
|
11865
|
+
const results = await Promise.all(skillPromises);
|
|
11866
|
+
return results.filter((skill) => skill !== null);
|
|
11869
11867
|
}
|
|
11870
11868
|
/**
|
|
11871
11869
|
* Determine if task should be fragmented into subtasks
|
|
@@ -16760,16 +16758,16 @@ var init_onboarding = __esm({
|
|
|
16760
16758
|
* Detect project type from file system
|
|
16761
16759
|
*/
|
|
16762
16760
|
async detectProjectType() {
|
|
16763
|
-
const
|
|
16764
|
-
const
|
|
16761
|
+
const fs50 = await import("node:fs/promises");
|
|
16762
|
+
const path59 = await import("node:path");
|
|
16765
16763
|
try {
|
|
16766
|
-
const files = await
|
|
16764
|
+
const files = await fs50.readdir(this.projectPath);
|
|
16767
16765
|
if (files.includes("turbo.json") || files.includes("lerna.json") || files.includes("nx.json")) {
|
|
16768
16766
|
return "monorepo";
|
|
16769
16767
|
}
|
|
16770
16768
|
if (files.includes("package.json")) {
|
|
16771
|
-
const pkgPath =
|
|
16772
|
-
const pkgContent = await
|
|
16769
|
+
const pkgPath = path59.join(this.projectPath, "package.json");
|
|
16770
|
+
const pkgContent = await fs50.readFile(pkgPath, "utf-8");
|
|
16773
16771
|
const pkg = JSON.parse(pkgContent);
|
|
16774
16772
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
16775
16773
|
if (pkg.bin) return "cli-tool";
|
|
@@ -16805,32 +16803,32 @@ var init_onboarding = __esm({
|
|
|
16805
16803
|
* Detect installed AI agents from config files
|
|
16806
16804
|
*/
|
|
16807
16805
|
async detectInstalledAgents() {
|
|
16808
|
-
const
|
|
16809
|
-
const
|
|
16806
|
+
const fs50 = await import("node:fs/promises");
|
|
16807
|
+
const path59 = await import("node:path");
|
|
16810
16808
|
const os17 = await import("node:os");
|
|
16811
16809
|
const agents = [];
|
|
16812
16810
|
try {
|
|
16813
|
-
await
|
|
16811
|
+
await fs50.access(path59.join(os17.homedir(), ".claude"));
|
|
16814
16812
|
agents.push("claude");
|
|
16815
16813
|
} catch {
|
|
16816
16814
|
}
|
|
16817
16815
|
try {
|
|
16818
|
-
await
|
|
16816
|
+
await fs50.access(path59.join(this.projectPath, ".cursorrules"));
|
|
16819
16817
|
agents.push("cursor");
|
|
16820
16818
|
} catch {
|
|
16821
16819
|
}
|
|
16822
16820
|
try {
|
|
16823
|
-
await
|
|
16821
|
+
await fs50.access(path59.join(this.projectPath, ".windsurfrules"));
|
|
16824
16822
|
agents.push("windsurf");
|
|
16825
16823
|
} catch {
|
|
16826
16824
|
}
|
|
16827
16825
|
try {
|
|
16828
|
-
await
|
|
16826
|
+
await fs50.access(path59.join(this.projectPath, ".github", "copilot-instructions.md"));
|
|
16829
16827
|
agents.push("copilot");
|
|
16830
16828
|
} catch {
|
|
16831
16829
|
}
|
|
16832
16830
|
try {
|
|
16833
|
-
await
|
|
16831
|
+
await fs50.access(path59.join(os17.homedir(), ".gemini"));
|
|
16834
16832
|
agents.push("gemini");
|
|
16835
16833
|
} catch {
|
|
16836
16834
|
}
|
|
@@ -16840,17 +16838,17 @@ var init_onboarding = __esm({
|
|
|
16840
16838
|
* Detect tech stack from project files
|
|
16841
16839
|
*/
|
|
16842
16840
|
async detectStack() {
|
|
16843
|
-
const
|
|
16844
|
-
const
|
|
16841
|
+
const fs50 = await import("node:fs/promises");
|
|
16842
|
+
const path59 = await import("node:path");
|
|
16845
16843
|
const stack = {
|
|
16846
16844
|
language: "Unknown",
|
|
16847
16845
|
technologies: []
|
|
16848
16846
|
};
|
|
16849
16847
|
try {
|
|
16850
|
-
const files = await
|
|
16848
|
+
const files = await fs50.readdir(this.projectPath);
|
|
16851
16849
|
if (files.includes("package.json")) {
|
|
16852
|
-
const pkgPath =
|
|
16853
|
-
const pkgContent = await
|
|
16850
|
+
const pkgPath = path59.join(this.projectPath, "package.json");
|
|
16851
|
+
const pkgContent = await fs50.readFile(pkgPath, "utf-8");
|
|
16854
16852
|
const pkg = JSON.parse(pkgContent);
|
|
16855
16853
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
16856
16854
|
stack.language = deps.typescript ? "TypeScript" : "JavaScript";
|
|
@@ -18946,8 +18944,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
18946
18944
|
const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
|
|
18947
18945
|
const specsPath2 = path37.join(globalPath2, "planning", "specs");
|
|
18948
18946
|
try {
|
|
18949
|
-
const
|
|
18950
|
-
const files = await
|
|
18947
|
+
const fs50 = await import("node:fs/promises");
|
|
18948
|
+
const files = await fs50.readdir(specsPath2);
|
|
18951
18949
|
const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
|
|
18952
18950
|
if (specs.length === 0) {
|
|
18953
18951
|
output_default.warn("no specs yet");
|
|
@@ -20090,9 +20088,125 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
|
|
|
20090
20088
|
}
|
|
20091
20089
|
});
|
|
20092
20090
|
|
|
20093
|
-
// core/services/
|
|
20091
|
+
// core/services/local-state-generator.ts
|
|
20094
20092
|
import fs40 from "node:fs/promises";
|
|
20095
20093
|
import path42 from "node:path";
|
|
20094
|
+
var LOCAL_STATE_FILENAME, LocalStateGenerator, localStateGenerator;
|
|
20095
|
+
var init_local_state_generator = __esm({
|
|
20096
|
+
"core/services/local-state-generator.ts"() {
|
|
20097
|
+
"use strict";
|
|
20098
|
+
init_fs();
|
|
20099
|
+
LOCAL_STATE_FILENAME = ".prjct-state.md";
|
|
20100
|
+
LocalStateGenerator = class {
|
|
20101
|
+
static {
|
|
20102
|
+
__name(this, "LocalStateGenerator");
|
|
20103
|
+
}
|
|
20104
|
+
/**
|
|
20105
|
+
* Generate .prjct-state.md in the project root
|
|
20106
|
+
*/
|
|
20107
|
+
async generate(projectPath, state) {
|
|
20108
|
+
const filePath = path42.join(projectPath, LOCAL_STATE_FILENAME);
|
|
20109
|
+
const content = this.toMarkdown(state);
|
|
20110
|
+
await fs40.writeFile(filePath, content, "utf-8");
|
|
20111
|
+
}
|
|
20112
|
+
/**
|
|
20113
|
+
* Remove local state file
|
|
20114
|
+
*/
|
|
20115
|
+
async remove(projectPath) {
|
|
20116
|
+
const filePath = path42.join(projectPath, LOCAL_STATE_FILENAME);
|
|
20117
|
+
try {
|
|
20118
|
+
await fs40.unlink(filePath);
|
|
20119
|
+
} catch (error) {
|
|
20120
|
+
if (!isNotFoundError(error)) throw error;
|
|
20121
|
+
}
|
|
20122
|
+
}
|
|
20123
|
+
/**
|
|
20124
|
+
* Check if local state file exists
|
|
20125
|
+
*/
|
|
20126
|
+
async exists(projectPath) {
|
|
20127
|
+
const filePath = path42.join(projectPath, LOCAL_STATE_FILENAME);
|
|
20128
|
+
try {
|
|
20129
|
+
await fs40.access(filePath);
|
|
20130
|
+
return true;
|
|
20131
|
+
} catch {
|
|
20132
|
+
return false;
|
|
20133
|
+
}
|
|
20134
|
+
}
|
|
20135
|
+
/**
|
|
20136
|
+
* Convert state to markdown format
|
|
20137
|
+
* Note: Uses runtime types since state.json has fields not in strict Zod schema
|
|
20138
|
+
*/
|
|
20139
|
+
toMarkdown(state) {
|
|
20140
|
+
const lines = [
|
|
20141
|
+
"<!-- Auto-generated by prjct - DO NOT EDIT -->",
|
|
20142
|
+
"<!-- This file provides local state persistence for AI tools -->",
|
|
20143
|
+
"",
|
|
20144
|
+
"# prjct State",
|
|
20145
|
+
""
|
|
20146
|
+
];
|
|
20147
|
+
if (state.currentTask) {
|
|
20148
|
+
const task = state.currentTask;
|
|
20149
|
+
lines.push("## Current Task");
|
|
20150
|
+
lines.push("");
|
|
20151
|
+
lines.push(`**${task.description}**`);
|
|
20152
|
+
lines.push("");
|
|
20153
|
+
lines.push(`- Started: ${task.startedAt}`);
|
|
20154
|
+
if (task.linearId) {
|
|
20155
|
+
lines.push(`- Linear: ${task.linearId}`);
|
|
20156
|
+
}
|
|
20157
|
+
if (task.branch) {
|
|
20158
|
+
lines.push(`- Branch: ${task.branch}`);
|
|
20159
|
+
}
|
|
20160
|
+
lines.push(`- Status: ${task.status || "active"}`);
|
|
20161
|
+
lines.push("");
|
|
20162
|
+
if (task.subtasks && task.subtasks.length > 0) {
|
|
20163
|
+
lines.push("### Subtasks");
|
|
20164
|
+
lines.push("");
|
|
20165
|
+
task.subtasks.forEach((subtask, index) => {
|
|
20166
|
+
const statusIcon = subtask.status === "completed" ? "\u2705" : subtask.status === "in_progress" ? "\u25B6\uFE0F" : "\u23F3";
|
|
20167
|
+
const isActive = index === task.currentSubtaskIndex ? " \u2190 **Active**" : "";
|
|
20168
|
+
lines.push(`${index + 1}. ${statusIcon} ${subtask.description}${isActive}`);
|
|
20169
|
+
});
|
|
20170
|
+
lines.push("");
|
|
20171
|
+
const completed = task.subtasks.filter((s) => s.status === "completed").length;
|
|
20172
|
+
const total = task.subtasks.length;
|
|
20173
|
+
const percentage = Math.round(completed / total * 100);
|
|
20174
|
+
lines.push(`**Progress**: ${completed}/${total} (${percentage}%)`);
|
|
20175
|
+
lines.push("");
|
|
20176
|
+
}
|
|
20177
|
+
} else {
|
|
20178
|
+
lines.push("*No active task*");
|
|
20179
|
+
lines.push("");
|
|
20180
|
+
lines.push('Start a task with `p. task "description"`');
|
|
20181
|
+
lines.push("");
|
|
20182
|
+
}
|
|
20183
|
+
if (state.previousTask) {
|
|
20184
|
+
const prevTask = state.previousTask;
|
|
20185
|
+
lines.push("---");
|
|
20186
|
+
lines.push("");
|
|
20187
|
+
lines.push("## Previous Task");
|
|
20188
|
+
lines.push("");
|
|
20189
|
+
lines.push(`**${prevTask.description}**`);
|
|
20190
|
+
lines.push("");
|
|
20191
|
+
lines.push(`- Status: ${prevTask.status}`);
|
|
20192
|
+
if (prevTask.prUrl) {
|
|
20193
|
+
lines.push(`- PR: ${prevTask.prUrl}`);
|
|
20194
|
+
}
|
|
20195
|
+
lines.push("");
|
|
20196
|
+
}
|
|
20197
|
+
lines.push("---");
|
|
20198
|
+
lines.push(`*Last updated: ${state.lastUpdated || (/* @__PURE__ */ new Date()).toISOString()}*`);
|
|
20199
|
+
lines.push("");
|
|
20200
|
+
return lines.join("\n");
|
|
20201
|
+
}
|
|
20202
|
+
};
|
|
20203
|
+
localStateGenerator = new LocalStateGenerator();
|
|
20204
|
+
}
|
|
20205
|
+
});
|
|
20206
|
+
|
|
20207
|
+
// core/services/stack-detector.ts
|
|
20208
|
+
import fs41 from "node:fs/promises";
|
|
20209
|
+
import path43 from "node:path";
|
|
20096
20210
|
var StackDetector;
|
|
20097
20211
|
var init_stack_detector = __esm({
|
|
20098
20212
|
"core/services/stack-detector.ts"() {
|
|
@@ -20251,8 +20365,8 @@ var init_stack_detector = __esm({
|
|
|
20251
20365
|
*/
|
|
20252
20366
|
async readPackageJson() {
|
|
20253
20367
|
try {
|
|
20254
|
-
const pkgPath =
|
|
20255
|
-
const content = await
|
|
20368
|
+
const pkgPath = path43.join(this.projectPath, "package.json");
|
|
20369
|
+
const content = await fs41.readFile(pkgPath, "utf-8");
|
|
20256
20370
|
return JSON.parse(content);
|
|
20257
20371
|
} catch {
|
|
20258
20372
|
return null;
|
|
@@ -20263,7 +20377,7 @@ var init_stack_detector = __esm({
|
|
|
20263
20377
|
*/
|
|
20264
20378
|
async fileExists(filename) {
|
|
20265
20379
|
try {
|
|
20266
|
-
await
|
|
20380
|
+
await fs41.access(path43.join(this.projectPath, filename));
|
|
20267
20381
|
return true;
|
|
20268
20382
|
} catch {
|
|
20269
20383
|
return false;
|
|
@@ -20275,8 +20389,8 @@ var init_stack_detector = __esm({
|
|
|
20275
20389
|
|
|
20276
20390
|
// core/services/sync-service.ts
|
|
20277
20391
|
import { exec as exec11 } from "node:child_process";
|
|
20278
|
-
import
|
|
20279
|
-
import
|
|
20392
|
+
import fs42 from "node:fs/promises";
|
|
20393
|
+
import path44 from "node:path";
|
|
20280
20394
|
import { promisify as promisify11 } from "node:util";
|
|
20281
20395
|
var execAsync6, SyncService, syncService;
|
|
20282
20396
|
var init_sync_service = __esm({
|
|
@@ -20289,6 +20403,7 @@ var init_sync_service = __esm({
|
|
|
20289
20403
|
init_metrics_storage();
|
|
20290
20404
|
init_date_helper();
|
|
20291
20405
|
init_context_generator();
|
|
20406
|
+
init_local_state_generator();
|
|
20292
20407
|
init_stack_detector();
|
|
20293
20408
|
execAsync6 = promisify11(exec11);
|
|
20294
20409
|
SyncService = class {
|
|
@@ -20425,7 +20540,7 @@ var init_sync_service = __esm({
|
|
|
20425
20540
|
async ensureDirectories() {
|
|
20426
20541
|
const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
|
|
20427
20542
|
await Promise.all(
|
|
20428
|
-
dirs.map((dir) =>
|
|
20543
|
+
dirs.map((dir) => fs42.mkdir(path44.join(this.globalPath, dir), { recursive: true }))
|
|
20429
20544
|
);
|
|
20430
20545
|
}
|
|
20431
20546
|
// ==========================================================================
|
|
@@ -20495,7 +20610,7 @@ var init_sync_service = __esm({
|
|
|
20495
20610
|
const stats = {
|
|
20496
20611
|
fileCount: 0,
|
|
20497
20612
|
version: "0.0.0",
|
|
20498
|
-
name:
|
|
20613
|
+
name: path44.basename(this.projectPath),
|
|
20499
20614
|
ecosystem: "unknown",
|
|
20500
20615
|
projectType: "simple",
|
|
20501
20616
|
languages: [],
|
|
@@ -20511,8 +20626,8 @@ var init_sync_service = __esm({
|
|
|
20511
20626
|
stats.fileCount = 0;
|
|
20512
20627
|
}
|
|
20513
20628
|
try {
|
|
20514
|
-
const pkgPath =
|
|
20515
|
-
const pkg = JSON.parse(await
|
|
20629
|
+
const pkgPath = path44.join(this.projectPath, "package.json");
|
|
20630
|
+
const pkg = JSON.parse(await fs42.readFile(pkgPath, "utf-8"));
|
|
20516
20631
|
stats.version = pkg.version || "0.0.0";
|
|
20517
20632
|
stats.name = pkg.name || stats.name;
|
|
20518
20633
|
stats.ecosystem = "JavaScript";
|
|
@@ -20620,12 +20735,12 @@ var init_sync_service = __esm({
|
|
|
20620
20735
|
// ==========================================================================
|
|
20621
20736
|
async generateAgents(stack, stats) {
|
|
20622
20737
|
const agents = [];
|
|
20623
|
-
const agentsPath =
|
|
20738
|
+
const agentsPath = path44.join(this.globalPath, "agents");
|
|
20624
20739
|
try {
|
|
20625
|
-
const files = await
|
|
20740
|
+
const files = await fs42.readdir(agentsPath);
|
|
20626
20741
|
for (const file of files) {
|
|
20627
20742
|
if (file.endsWith(".md")) {
|
|
20628
|
-
await
|
|
20743
|
+
await fs42.unlink(path44.join(agentsPath, file));
|
|
20629
20744
|
}
|
|
20630
20745
|
}
|
|
20631
20746
|
} catch {
|
|
@@ -20665,7 +20780,7 @@ var init_sync_service = __esm({
|
|
|
20665
20780
|
async generateWorkflowAgent(name, agentsPath) {
|
|
20666
20781
|
let content = "";
|
|
20667
20782
|
try {
|
|
20668
|
-
const templatePath =
|
|
20783
|
+
const templatePath = path44.join(
|
|
20669
20784
|
__dirname,
|
|
20670
20785
|
"..",
|
|
20671
20786
|
"..",
|
|
@@ -20674,16 +20789,16 @@ var init_sync_service = __esm({
|
|
|
20674
20789
|
"workflow",
|
|
20675
20790
|
`${name}.md`
|
|
20676
20791
|
);
|
|
20677
|
-
content = await
|
|
20792
|
+
content = await fs42.readFile(templatePath, "utf-8");
|
|
20678
20793
|
} catch {
|
|
20679
20794
|
content = this.generateMinimalWorkflowAgent(name);
|
|
20680
20795
|
}
|
|
20681
|
-
await
|
|
20796
|
+
await fs42.writeFile(path44.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
20682
20797
|
}
|
|
20683
20798
|
async generateDomainAgent(name, agentsPath, stats, stack) {
|
|
20684
20799
|
let content = "";
|
|
20685
20800
|
try {
|
|
20686
|
-
const templatePath =
|
|
20801
|
+
const templatePath = path44.join(
|
|
20687
20802
|
__dirname,
|
|
20688
20803
|
"..",
|
|
20689
20804
|
"..",
|
|
@@ -20692,14 +20807,14 @@ var init_sync_service = __esm({
|
|
|
20692
20807
|
"domain",
|
|
20693
20808
|
`${name}.md`
|
|
20694
20809
|
);
|
|
20695
|
-
content = await
|
|
20810
|
+
content = await fs42.readFile(templatePath, "utf-8");
|
|
20696
20811
|
content = content.replace("{projectName}", stats.name);
|
|
20697
20812
|
content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
|
|
20698
20813
|
content = content.replace("{ecosystem}", stats.ecosystem);
|
|
20699
20814
|
} catch {
|
|
20700
20815
|
content = this.generateMinimalDomainAgent(name, stats, stack);
|
|
20701
20816
|
}
|
|
20702
|
-
await
|
|
20817
|
+
await fs42.writeFile(path44.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
20703
20818
|
}
|
|
20704
20819
|
generateMinimalWorkflowAgent(name) {
|
|
20705
20820
|
const descriptions = {
|
|
@@ -20767,8 +20882,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
20767
20882
|
})),
|
|
20768
20883
|
agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
|
|
20769
20884
|
};
|
|
20770
|
-
|
|
20771
|
-
|
|
20885
|
+
fs42.writeFile(
|
|
20886
|
+
path44.join(this.globalPath, "config", "skills.json"),
|
|
20772
20887
|
JSON.stringify(skillsConfig, null, 2),
|
|
20773
20888
|
"utf-8"
|
|
20774
20889
|
).catch(() => {
|
|
@@ -20790,10 +20905,10 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
20790
20905
|
// PROJECT.JSON UPDATE
|
|
20791
20906
|
// ==========================================================================
|
|
20792
20907
|
async updateProjectJson(git, stats) {
|
|
20793
|
-
const projectJsonPath =
|
|
20908
|
+
const projectJsonPath = path44.join(this.globalPath, "project.json");
|
|
20794
20909
|
let existing = {};
|
|
20795
20910
|
try {
|
|
20796
|
-
existing = JSON.parse(await
|
|
20911
|
+
existing = JSON.parse(await fs42.readFile(projectJsonPath, "utf-8"));
|
|
20797
20912
|
} catch {
|
|
20798
20913
|
}
|
|
20799
20914
|
const updated = {
|
|
@@ -20815,16 +20930,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
20815
20930
|
lastSyncCommit: git.recentCommits[0]?.hash || null,
|
|
20816
20931
|
lastSyncBranch: git.branch
|
|
20817
20932
|
};
|
|
20818
|
-
await
|
|
20933
|
+
await fs42.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
|
|
20819
20934
|
}
|
|
20820
20935
|
// ==========================================================================
|
|
20821
20936
|
// STATE.JSON UPDATE
|
|
20822
20937
|
// ==========================================================================
|
|
20823
20938
|
async updateStateJson(stats, stack) {
|
|
20824
|
-
const statePath =
|
|
20939
|
+
const statePath = path44.join(this.globalPath, "storage", "state.json");
|
|
20825
20940
|
let state = {};
|
|
20826
20941
|
try {
|
|
20827
|
-
state = JSON.parse(await
|
|
20942
|
+
state = JSON.parse(await fs42.readFile(statePath, "utf-8"));
|
|
20828
20943
|
} catch {
|
|
20829
20944
|
}
|
|
20830
20945
|
state.projectId = this.projectId;
|
|
@@ -20851,13 +20966,20 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
20851
20966
|
lastAction: "Synced project",
|
|
20852
20967
|
nextAction: 'Run `p. task "description"` to start working'
|
|
20853
20968
|
};
|
|
20854
|
-
await
|
|
20969
|
+
await fs42.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
|
|
20970
|
+
try {
|
|
20971
|
+
await localStateGenerator.generate(
|
|
20972
|
+
this.projectPath,
|
|
20973
|
+
state
|
|
20974
|
+
);
|
|
20975
|
+
} catch {
|
|
20976
|
+
}
|
|
20855
20977
|
}
|
|
20856
20978
|
// ==========================================================================
|
|
20857
20979
|
// MEMORY LOGGING
|
|
20858
20980
|
// ==========================================================================
|
|
20859
20981
|
async logToMemory(git, stats) {
|
|
20860
|
-
const memoryPath =
|
|
20982
|
+
const memoryPath = path44.join(this.globalPath, "memory", "events.jsonl");
|
|
20861
20983
|
const event = {
|
|
20862
20984
|
ts: date_helper_default.getTimestamp(),
|
|
20863
20985
|
action: "sync",
|
|
@@ -20866,7 +20988,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
20866
20988
|
fileCount: stats.fileCount,
|
|
20867
20989
|
commitCount: git.commits
|
|
20868
20990
|
};
|
|
20869
|
-
await
|
|
20991
|
+
await fs42.appendFile(memoryPath, `${JSON.stringify(event)}
|
|
20870
20992
|
`, "utf-8");
|
|
20871
20993
|
}
|
|
20872
20994
|
// ==========================================================================
|
|
@@ -20886,16 +21008,16 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
20886
21008
|
let filteredChars = 0;
|
|
20887
21009
|
for (const file of contextFiles) {
|
|
20888
21010
|
try {
|
|
20889
|
-
const filePath =
|
|
20890
|
-
const content = await
|
|
21011
|
+
const filePath = path44.join(this.globalPath, file);
|
|
21012
|
+
const content = await fs42.readFile(filePath, "utf-8");
|
|
20891
21013
|
filteredChars += content.length;
|
|
20892
21014
|
} catch {
|
|
20893
21015
|
}
|
|
20894
21016
|
}
|
|
20895
21017
|
for (const agent of agents) {
|
|
20896
21018
|
try {
|
|
20897
|
-
const agentPath =
|
|
20898
|
-
const content = await
|
|
21019
|
+
const agentPath = path44.join(this.globalPath, "agents", `${agent.name}.md`);
|
|
21020
|
+
const content = await fs42.readFile(agentPath, "utf-8");
|
|
20899
21021
|
filteredChars += content.length;
|
|
20900
21022
|
} catch {
|
|
20901
21023
|
}
|
|
@@ -20927,7 +21049,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
20927
21049
|
// ==========================================================================
|
|
20928
21050
|
async fileExists(filename) {
|
|
20929
21051
|
try {
|
|
20930
|
-
await
|
|
21052
|
+
await fs42.access(path44.join(this.projectPath, filename));
|
|
20931
21053
|
return true;
|
|
20932
21054
|
} catch {
|
|
20933
21055
|
return false;
|
|
@@ -20935,8 +21057,8 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
20935
21057
|
}
|
|
20936
21058
|
async getCliVersion() {
|
|
20937
21059
|
try {
|
|
20938
|
-
const pkgPath =
|
|
20939
|
-
const pkg = JSON.parse(await
|
|
21060
|
+
const pkgPath = path44.join(__dirname, "..", "..", "package.json");
|
|
21061
|
+
const pkg = JSON.parse(await fs42.readFile(pkgPath, "utf-8"));
|
|
20940
21062
|
return pkg.version || "0.0.0";
|
|
20941
21063
|
} catch {
|
|
20942
21064
|
return "0.0.0";
|
|
@@ -21097,22 +21219,22 @@ __export(uninstall_exports, {
|
|
|
21097
21219
|
});
|
|
21098
21220
|
import { execSync as execSync5 } from "node:child_process";
|
|
21099
21221
|
import fsSync2 from "node:fs";
|
|
21100
|
-
import
|
|
21222
|
+
import fs43 from "node:fs/promises";
|
|
21101
21223
|
import os12 from "node:os";
|
|
21102
|
-
import
|
|
21224
|
+
import path45 from "node:path";
|
|
21103
21225
|
import readline2 from "node:readline";
|
|
21104
21226
|
import chalk9 from "chalk";
|
|
21105
21227
|
async function getDirectorySize(dirPath) {
|
|
21106
21228
|
let totalSize = 0;
|
|
21107
21229
|
try {
|
|
21108
|
-
const entries = await
|
|
21230
|
+
const entries = await fs43.readdir(dirPath, { withFileTypes: true });
|
|
21109
21231
|
for (const entry of entries) {
|
|
21110
|
-
const entryPath =
|
|
21232
|
+
const entryPath = path45.join(dirPath, entry.name);
|
|
21111
21233
|
if (entry.isDirectory()) {
|
|
21112
21234
|
totalSize += await getDirectorySize(entryPath);
|
|
21113
21235
|
} else {
|
|
21114
21236
|
try {
|
|
21115
|
-
const stats = await
|
|
21237
|
+
const stats = await fs43.stat(entryPath);
|
|
21116
21238
|
totalSize += stats.size;
|
|
21117
21239
|
} catch {
|
|
21118
21240
|
}
|
|
@@ -21131,7 +21253,7 @@ function formatSize(bytes) {
|
|
|
21131
21253
|
}
|
|
21132
21254
|
async function countDirectoryItems(dirPath) {
|
|
21133
21255
|
try {
|
|
21134
|
-
const entries = await
|
|
21256
|
+
const entries = await fs43.readdir(dirPath, { withFileTypes: true });
|
|
21135
21257
|
return entries.filter((e) => e.isDirectory()).length;
|
|
21136
21258
|
} catch {
|
|
21137
21259
|
return 0;
|
|
@@ -21164,7 +21286,7 @@ async function gatherUninstallItems() {
|
|
|
21164
21286
|
const providerPaths = getProviderPaths();
|
|
21165
21287
|
const prjctCliPath = path_manager_default.getGlobalBasePath();
|
|
21166
21288
|
const prjctCliExists = fsSync2.existsSync(prjctCliPath);
|
|
21167
|
-
const projectCount = prjctCliExists ? await countDirectoryItems(
|
|
21289
|
+
const projectCount = prjctCliExists ? await countDirectoryItems(path45.join(prjctCliPath, "projects")) : 0;
|
|
21168
21290
|
const prjctCliSize = prjctCliExists ? await getDirectorySize(prjctCliPath) : 0;
|
|
21169
21291
|
items.push({
|
|
21170
21292
|
path: prjctCliPath,
|
|
@@ -21174,7 +21296,7 @@ async function gatherUninstallItems() {
|
|
|
21174
21296
|
count: projectCount,
|
|
21175
21297
|
exists: prjctCliExists
|
|
21176
21298
|
});
|
|
21177
|
-
const claudeMdPath =
|
|
21299
|
+
const claudeMdPath = path45.join(providerPaths.claude.config, "CLAUDE.md");
|
|
21178
21300
|
const claudeMdExists = fsSync2.existsSync(claudeMdPath);
|
|
21179
21301
|
let hasPrjctSection = false;
|
|
21180
21302
|
if (claudeMdExists) {
|
|
@@ -21208,7 +21330,7 @@ async function gatherUninstallItems() {
|
|
|
21208
21330
|
description: "Claude router",
|
|
21209
21331
|
exists: claudeRouterExists
|
|
21210
21332
|
});
|
|
21211
|
-
const statusLinePath =
|
|
21333
|
+
const statusLinePath = path45.join(providerPaths.claude.config, "prjct-statusline.sh");
|
|
21212
21334
|
const statusLineExists = fsSync2.existsSync(statusLinePath);
|
|
21213
21335
|
items.push({
|
|
21214
21336
|
path: statusLinePath,
|
|
@@ -21224,7 +21346,7 @@ async function gatherUninstallItems() {
|
|
|
21224
21346
|
description: "Gemini router",
|
|
21225
21347
|
exists: geminiRouterExists
|
|
21226
21348
|
});
|
|
21227
|
-
const geminiMdPath =
|
|
21349
|
+
const geminiMdPath = path45.join(providerPaths.gemini.config, "GEMINI.md");
|
|
21228
21350
|
const geminiMdExists = fsSync2.existsSync(geminiMdPath);
|
|
21229
21351
|
let hasGeminiPrjctSection = false;
|
|
21230
21352
|
if (geminiMdExists) {
|
|
@@ -21246,7 +21368,7 @@ async function gatherUninstallItems() {
|
|
|
21246
21368
|
}
|
|
21247
21369
|
async function removePrjctSection(filePath) {
|
|
21248
21370
|
try {
|
|
21249
|
-
const content = await
|
|
21371
|
+
const content = await fs43.readFile(filePath, "utf-8");
|
|
21250
21372
|
if (!content.includes(PRJCT_START_MARKER) || !content.includes(PRJCT_END_MARKER)) {
|
|
21251
21373
|
return false;
|
|
21252
21374
|
}
|
|
@@ -21255,9 +21377,9 @@ async function removePrjctSection(filePath) {
|
|
|
21255
21377
|
let newContent = content.substring(0, startIndex) + content.substring(endIndex);
|
|
21256
21378
|
newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
|
|
21257
21379
|
if (!newContent || newContent.trim().length === 0) {
|
|
21258
|
-
await
|
|
21380
|
+
await fs43.unlink(filePath);
|
|
21259
21381
|
} else {
|
|
21260
|
-
await
|
|
21382
|
+
await fs43.writeFile(filePath, `${newContent}
|
|
21261
21383
|
`, "utf-8");
|
|
21262
21384
|
}
|
|
21263
21385
|
return true;
|
|
@@ -21268,12 +21390,12 @@ async function removePrjctSection(filePath) {
|
|
|
21268
21390
|
async function createBackup() {
|
|
21269
21391
|
const homeDir = os12.homedir();
|
|
21270
21392
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").substring(0, 19);
|
|
21271
|
-
const backupDir =
|
|
21393
|
+
const backupDir = path45.join(homeDir, `.prjct-backup-${timestamp}`);
|
|
21272
21394
|
try {
|
|
21273
|
-
await
|
|
21395
|
+
await fs43.mkdir(backupDir, { recursive: true });
|
|
21274
21396
|
const prjctCliPath = path_manager_default.getGlobalBasePath();
|
|
21275
21397
|
if (fsSync2.existsSync(prjctCliPath)) {
|
|
21276
|
-
await copyDirectory(prjctCliPath,
|
|
21398
|
+
await copyDirectory(prjctCliPath, path45.join(backupDir, ".prjct-cli"));
|
|
21277
21399
|
}
|
|
21278
21400
|
return backupDir;
|
|
21279
21401
|
} catch {
|
|
@@ -21281,15 +21403,15 @@ async function createBackup() {
|
|
|
21281
21403
|
}
|
|
21282
21404
|
}
|
|
21283
21405
|
async function copyDirectory(src, dest) {
|
|
21284
|
-
await
|
|
21285
|
-
const entries = await
|
|
21406
|
+
await fs43.mkdir(dest, { recursive: true });
|
|
21407
|
+
const entries = await fs43.readdir(src, { withFileTypes: true });
|
|
21286
21408
|
for (const entry of entries) {
|
|
21287
|
-
const srcPath =
|
|
21288
|
-
const destPath =
|
|
21409
|
+
const srcPath = path45.join(src, entry.name);
|
|
21410
|
+
const destPath = path45.join(dest, entry.name);
|
|
21289
21411
|
if (entry.isDirectory()) {
|
|
21290
21412
|
await copyDirectory(srcPath, destPath);
|
|
21291
21413
|
} else {
|
|
21292
|
-
await
|
|
21414
|
+
await fs43.copyFile(srcPath, destPath);
|
|
21293
21415
|
}
|
|
21294
21416
|
}
|
|
21295
21417
|
}
|
|
@@ -21305,10 +21427,10 @@ async function performUninstall(items, installation, options) {
|
|
|
21305
21427
|
deleted.push(item.path);
|
|
21306
21428
|
}
|
|
21307
21429
|
} else if (item.type === "directory") {
|
|
21308
|
-
await
|
|
21430
|
+
await fs43.rm(item.path, { recursive: true, force: true });
|
|
21309
21431
|
deleted.push(item.path);
|
|
21310
21432
|
} else if (item.type === "file") {
|
|
21311
|
-
await
|
|
21433
|
+
await fs43.unlink(item.path);
|
|
21312
21434
|
deleted.push(item.path);
|
|
21313
21435
|
}
|
|
21314
21436
|
} catch (error) {
|
|
@@ -21483,7 +21605,7 @@ __export(watch_service_exports, {
|
|
|
21483
21605
|
WatchService: () => WatchService,
|
|
21484
21606
|
watchService: () => watchService
|
|
21485
21607
|
});
|
|
21486
|
-
import
|
|
21608
|
+
import path46 from "node:path";
|
|
21487
21609
|
import chalk10 from "chalk";
|
|
21488
21610
|
import chokidar from "chokidar";
|
|
21489
21611
|
var TRIGGER_PATTERNS, IGNORE_PATTERNS2, WatchService, watchService;
|
|
@@ -21688,7 +21810,7 @@ ${chalk10.dim(`[${timestamp}]`)} ${chalk10.cyan("\u27F3")} ${filesSummary} chang
|
|
|
21688
21810
|
printStartup() {
|
|
21689
21811
|
console.log("");
|
|
21690
21812
|
console.log(chalk10.cyan("\u{1F441}\uFE0F Watching for changes..."));
|
|
21691
|
-
console.log(chalk10.dim(` Project: ${
|
|
21813
|
+
console.log(chalk10.dim(` Project: ${path46.basename(this.projectPath)}`));
|
|
21692
21814
|
console.log(chalk10.dim(` Debounce: ${this.options.debounceMs}ms`));
|
|
21693
21815
|
console.log(chalk10.dim(` Min interval: ${this.options.minIntervalMs / 1e3}s`));
|
|
21694
21816
|
console.log("");
|
|
@@ -22361,9 +22483,9 @@ __export(setup_exports, {
|
|
|
22361
22483
|
run: () => run
|
|
22362
22484
|
});
|
|
22363
22485
|
import { execSync as execSync6 } from "node:child_process";
|
|
22364
|
-
import
|
|
22486
|
+
import fs44 from "node:fs";
|
|
22365
22487
|
import os13 from "node:os";
|
|
22366
|
-
import
|
|
22488
|
+
import path47 from "node:path";
|
|
22367
22489
|
async function installAICLI(provider) {
|
|
22368
22490
|
const packageName = provider.name === "claude" ? "@anthropic-ai/claude-code" : "@google/gemini-cli";
|
|
22369
22491
|
try {
|
|
@@ -22469,12 +22591,12 @@ async function run() {
|
|
|
22469
22591
|
}
|
|
22470
22592
|
async function installGeminiRouter() {
|
|
22471
22593
|
try {
|
|
22472
|
-
const geminiCommandsDir =
|
|
22473
|
-
const routerSource =
|
|
22474
|
-
const routerDest =
|
|
22475
|
-
|
|
22476
|
-
if (
|
|
22477
|
-
|
|
22594
|
+
const geminiCommandsDir = path47.join(os13.homedir(), ".gemini", "commands");
|
|
22595
|
+
const routerSource = path47.join(getPackageRoot(), "templates", "commands", "p.toml");
|
|
22596
|
+
const routerDest = path47.join(geminiCommandsDir, "p.toml");
|
|
22597
|
+
fs44.mkdirSync(geminiCommandsDir, { recursive: true });
|
|
22598
|
+
if (fs44.existsSync(routerSource)) {
|
|
22599
|
+
fs44.copyFileSync(routerSource, routerDest);
|
|
22478
22600
|
return true;
|
|
22479
22601
|
}
|
|
22480
22602
|
return false;
|
|
@@ -22485,15 +22607,15 @@ async function installGeminiRouter() {
|
|
|
22485
22607
|
}
|
|
22486
22608
|
async function installGeminiGlobalConfig() {
|
|
22487
22609
|
try {
|
|
22488
|
-
const geminiDir =
|
|
22489
|
-
const globalConfigPath =
|
|
22490
|
-
const templatePath =
|
|
22491
|
-
|
|
22492
|
-
const templateContent =
|
|
22610
|
+
const geminiDir = path47.join(os13.homedir(), ".gemini");
|
|
22611
|
+
const globalConfigPath = path47.join(geminiDir, "GEMINI.md");
|
|
22612
|
+
const templatePath = path47.join(getPackageRoot(), "templates", "global", "GEMINI.md");
|
|
22613
|
+
fs44.mkdirSync(geminiDir, { recursive: true });
|
|
22614
|
+
const templateContent = fs44.readFileSync(templatePath, "utf-8");
|
|
22493
22615
|
let existingContent = "";
|
|
22494
22616
|
let fileExists2 = false;
|
|
22495
22617
|
try {
|
|
22496
|
-
existingContent =
|
|
22618
|
+
existingContent = fs44.readFileSync(globalConfigPath, "utf-8");
|
|
22497
22619
|
fileExists2 = true;
|
|
22498
22620
|
} catch (error) {
|
|
22499
22621
|
if (isNotFoundError(error)) {
|
|
@@ -22503,7 +22625,7 @@ async function installGeminiGlobalConfig() {
|
|
|
22503
22625
|
}
|
|
22504
22626
|
}
|
|
22505
22627
|
if (!fileExists2) {
|
|
22506
|
-
|
|
22628
|
+
fs44.writeFileSync(globalConfigPath, templateContent, "utf-8");
|
|
22507
22629
|
return { success: true, action: "created" };
|
|
22508
22630
|
}
|
|
22509
22631
|
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
@@ -22513,7 +22635,7 @@ async function installGeminiGlobalConfig() {
|
|
|
22513
22635
|
const updatedContent2 = `${existingContent}
|
|
22514
22636
|
|
|
22515
22637
|
${templateContent}`;
|
|
22516
|
-
|
|
22638
|
+
fs44.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
|
|
22517
22639
|
return { success: true, action: "appended" };
|
|
22518
22640
|
}
|
|
22519
22641
|
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
|
|
@@ -22525,7 +22647,7 @@ ${templateContent}`;
|
|
|
22525
22647
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
22526
22648
|
);
|
|
22527
22649
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
22528
|
-
|
|
22650
|
+
fs44.writeFileSync(globalConfigPath, updatedContent, "utf-8");
|
|
22529
22651
|
return { success: true, action: "updated" };
|
|
22530
22652
|
} catch (error) {
|
|
22531
22653
|
console.error(`Gemini config warning: ${error.message}`);
|
|
@@ -22534,18 +22656,18 @@ ${templateContent}`;
|
|
|
22534
22656
|
}
|
|
22535
22657
|
async function installAntigravitySkill() {
|
|
22536
22658
|
try {
|
|
22537
|
-
const antigravitySkillsDir =
|
|
22538
|
-
const prjctSkillDir =
|
|
22539
|
-
const skillMdPath =
|
|
22540
|
-
const templatePath =
|
|
22541
|
-
|
|
22542
|
-
const fileExists2 =
|
|
22543
|
-
if (!
|
|
22659
|
+
const antigravitySkillsDir = path47.join(os13.homedir(), ".gemini", "antigravity", "skills");
|
|
22660
|
+
const prjctSkillDir = path47.join(antigravitySkillsDir, "prjct");
|
|
22661
|
+
const skillMdPath = path47.join(prjctSkillDir, "SKILL.md");
|
|
22662
|
+
const templatePath = path47.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
|
|
22663
|
+
fs44.mkdirSync(prjctSkillDir, { recursive: true });
|
|
22664
|
+
const fileExists2 = fs44.existsSync(skillMdPath);
|
|
22665
|
+
if (!fs44.existsSync(templatePath)) {
|
|
22544
22666
|
console.error("Antigravity SKILL.md template not found");
|
|
22545
22667
|
return { success: false, action: null };
|
|
22546
22668
|
}
|
|
22547
|
-
const templateContent =
|
|
22548
|
-
|
|
22669
|
+
const templateContent = fs44.readFileSync(templatePath, "utf-8");
|
|
22670
|
+
fs44.writeFileSync(skillMdPath, templateContent, "utf-8");
|
|
22549
22671
|
return { success: true, action: fileExists2 ? "updated" : "created" };
|
|
22550
22672
|
} catch (error) {
|
|
22551
22673
|
console.error(`Antigravity skill warning: ${error.message}`);
|
|
@@ -22564,24 +22686,24 @@ async function installCursorProject(projectRoot) {
|
|
|
22564
22686
|
gitignoreUpdated: false
|
|
22565
22687
|
};
|
|
22566
22688
|
try {
|
|
22567
|
-
const cursorDir =
|
|
22568
|
-
const rulesDir =
|
|
22569
|
-
const commandsDir =
|
|
22570
|
-
const routerMdcDest =
|
|
22571
|
-
const routerMdcSource =
|
|
22572
|
-
const cursorCommandsSource =
|
|
22573
|
-
|
|
22574
|
-
|
|
22575
|
-
if (
|
|
22576
|
-
|
|
22689
|
+
const cursorDir = path47.join(projectRoot, ".cursor");
|
|
22690
|
+
const rulesDir = path47.join(cursorDir, "rules");
|
|
22691
|
+
const commandsDir = path47.join(cursorDir, "commands");
|
|
22692
|
+
const routerMdcDest = path47.join(rulesDir, "prjct.mdc");
|
|
22693
|
+
const routerMdcSource = path47.join(getPackageRoot(), "templates", "cursor", "router.mdc");
|
|
22694
|
+
const cursorCommandsSource = path47.join(getPackageRoot(), "templates", "cursor", "commands");
|
|
22695
|
+
fs44.mkdirSync(rulesDir, { recursive: true });
|
|
22696
|
+
fs44.mkdirSync(commandsDir, { recursive: true });
|
|
22697
|
+
if (fs44.existsSync(routerMdcSource)) {
|
|
22698
|
+
fs44.copyFileSync(routerMdcSource, routerMdcDest);
|
|
22577
22699
|
result.rulesCreated = true;
|
|
22578
22700
|
}
|
|
22579
|
-
if (
|
|
22580
|
-
const commandFiles =
|
|
22701
|
+
if (fs44.existsSync(cursorCommandsSource)) {
|
|
22702
|
+
const commandFiles = fs44.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
|
|
22581
22703
|
for (const file of commandFiles) {
|
|
22582
|
-
const src =
|
|
22583
|
-
const dest =
|
|
22584
|
-
|
|
22704
|
+
const src = path47.join(cursorCommandsSource, file);
|
|
22705
|
+
const dest = path47.join(commandsDir, file);
|
|
22706
|
+
fs44.copyFileSync(src, dest);
|
|
22585
22707
|
}
|
|
22586
22708
|
result.commandsCreated = commandFiles.length > 0;
|
|
22587
22709
|
}
|
|
@@ -22595,7 +22717,7 @@ async function installCursorProject(projectRoot) {
|
|
|
22595
22717
|
}
|
|
22596
22718
|
async function addCursorToGitignore(projectRoot) {
|
|
22597
22719
|
try {
|
|
22598
|
-
const gitignorePath =
|
|
22720
|
+
const gitignorePath = path47.join(projectRoot, ".gitignore");
|
|
22599
22721
|
const entriesToAdd = [
|
|
22600
22722
|
"# prjct Cursor routers (regenerated per-developer)",
|
|
22601
22723
|
".cursor/rules/prjct.mdc",
|
|
@@ -22610,7 +22732,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
22610
22732
|
let content = "";
|
|
22611
22733
|
let fileExists2 = false;
|
|
22612
22734
|
try {
|
|
22613
|
-
content =
|
|
22735
|
+
content = fs44.readFileSync(gitignorePath, "utf-8");
|
|
22614
22736
|
fileExists2 = true;
|
|
22615
22737
|
} catch (error) {
|
|
22616
22738
|
if (!isNotFoundError(error)) {
|
|
@@ -22625,7 +22747,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
22625
22747
|
${entriesToAdd.join("\n")}
|
|
22626
22748
|
` : `${entriesToAdd.join("\n")}
|
|
22627
22749
|
`;
|
|
22628
|
-
|
|
22750
|
+
fs44.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
22629
22751
|
return true;
|
|
22630
22752
|
} catch (error) {
|
|
22631
22753
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -22633,12 +22755,12 @@ ${entriesToAdd.join("\n")}
|
|
|
22633
22755
|
}
|
|
22634
22756
|
}
|
|
22635
22757
|
function hasCursorProject(projectRoot) {
|
|
22636
|
-
return
|
|
22758
|
+
return fs44.existsSync(path47.join(projectRoot, ".cursor"));
|
|
22637
22759
|
}
|
|
22638
22760
|
function needsCursorRegeneration(projectRoot) {
|
|
22639
|
-
const cursorDir =
|
|
22640
|
-
const routerPath =
|
|
22641
|
-
return
|
|
22761
|
+
const cursorDir = path47.join(projectRoot, ".cursor");
|
|
22762
|
+
const routerPath = path47.join(cursorDir, "rules", "prjct.mdc");
|
|
22763
|
+
return fs44.existsSync(cursorDir) && !fs44.existsSync(routerPath);
|
|
22642
22764
|
}
|
|
22643
22765
|
async function installWindsurfProject(projectRoot) {
|
|
22644
22766
|
const result = {
|
|
@@ -22648,29 +22770,29 @@ async function installWindsurfProject(projectRoot) {
|
|
|
22648
22770
|
gitignoreUpdated: false
|
|
22649
22771
|
};
|
|
22650
22772
|
try {
|
|
22651
|
-
const windsurfDir =
|
|
22652
|
-
const rulesDir =
|
|
22653
|
-
const workflowsDir =
|
|
22654
|
-
const routerDest =
|
|
22655
|
-
const routerSource =
|
|
22656
|
-
const windsurfWorkflowsSource =
|
|
22773
|
+
const windsurfDir = path47.join(projectRoot, ".windsurf");
|
|
22774
|
+
const rulesDir = path47.join(windsurfDir, "rules");
|
|
22775
|
+
const workflowsDir = path47.join(windsurfDir, "workflows");
|
|
22776
|
+
const routerDest = path47.join(rulesDir, "prjct.md");
|
|
22777
|
+
const routerSource = path47.join(getPackageRoot(), "templates", "windsurf", "router.md");
|
|
22778
|
+
const windsurfWorkflowsSource = path47.join(
|
|
22657
22779
|
getPackageRoot(),
|
|
22658
22780
|
"templates",
|
|
22659
22781
|
"windsurf",
|
|
22660
22782
|
"workflows"
|
|
22661
22783
|
);
|
|
22662
|
-
|
|
22663
|
-
|
|
22664
|
-
if (
|
|
22665
|
-
|
|
22784
|
+
fs44.mkdirSync(rulesDir, { recursive: true });
|
|
22785
|
+
fs44.mkdirSync(workflowsDir, { recursive: true });
|
|
22786
|
+
if (fs44.existsSync(routerSource)) {
|
|
22787
|
+
fs44.copyFileSync(routerSource, routerDest);
|
|
22666
22788
|
result.rulesCreated = true;
|
|
22667
22789
|
}
|
|
22668
|
-
if (
|
|
22669
|
-
const workflowFiles =
|
|
22790
|
+
if (fs44.existsSync(windsurfWorkflowsSource)) {
|
|
22791
|
+
const workflowFiles = fs44.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
|
|
22670
22792
|
for (const file of workflowFiles) {
|
|
22671
|
-
const src =
|
|
22672
|
-
const dest =
|
|
22673
|
-
|
|
22793
|
+
const src = path47.join(windsurfWorkflowsSource, file);
|
|
22794
|
+
const dest = path47.join(workflowsDir, file);
|
|
22795
|
+
fs44.copyFileSync(src, dest);
|
|
22674
22796
|
}
|
|
22675
22797
|
result.workflowsCreated = workflowFiles.length > 0;
|
|
22676
22798
|
}
|
|
@@ -22684,7 +22806,7 @@ async function installWindsurfProject(projectRoot) {
|
|
|
22684
22806
|
}
|
|
22685
22807
|
async function addWindsurfToGitignore(projectRoot) {
|
|
22686
22808
|
try {
|
|
22687
|
-
const gitignorePath =
|
|
22809
|
+
const gitignorePath = path47.join(projectRoot, ".gitignore");
|
|
22688
22810
|
const entriesToAdd = [
|
|
22689
22811
|
"# prjct Windsurf routers (regenerated per-developer)",
|
|
22690
22812
|
".windsurf/rules/prjct.md",
|
|
@@ -22699,7 +22821,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
22699
22821
|
let content = "";
|
|
22700
22822
|
let fileExists2 = false;
|
|
22701
22823
|
try {
|
|
22702
|
-
content =
|
|
22824
|
+
content = fs44.readFileSync(gitignorePath, "utf-8");
|
|
22703
22825
|
fileExists2 = true;
|
|
22704
22826
|
} catch (error) {
|
|
22705
22827
|
if (!isNotFoundError(error)) {
|
|
@@ -22714,7 +22836,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
22714
22836
|
${entriesToAdd.join("\n")}
|
|
22715
22837
|
` : `${entriesToAdd.join("\n")}
|
|
22716
22838
|
`;
|
|
22717
|
-
|
|
22839
|
+
fs44.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
22718
22840
|
return true;
|
|
22719
22841
|
} catch (error) {
|
|
22720
22842
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -22722,32 +22844,32 @@ ${entriesToAdd.join("\n")}
|
|
|
22722
22844
|
}
|
|
22723
22845
|
}
|
|
22724
22846
|
function hasWindsurfProject(projectRoot) {
|
|
22725
|
-
return
|
|
22847
|
+
return fs44.existsSync(path47.join(projectRoot, ".windsurf"));
|
|
22726
22848
|
}
|
|
22727
22849
|
function needsWindsurfRegeneration(projectRoot) {
|
|
22728
|
-
const windsurfDir =
|
|
22729
|
-
const routerPath =
|
|
22730
|
-
return
|
|
22850
|
+
const windsurfDir = path47.join(projectRoot, ".windsurf");
|
|
22851
|
+
const routerPath = path47.join(windsurfDir, "rules", "prjct.md");
|
|
22852
|
+
return fs44.existsSync(windsurfDir) && !fs44.existsSync(routerPath);
|
|
22731
22853
|
}
|
|
22732
22854
|
async function migrateProjectsCliVersion() {
|
|
22733
22855
|
try {
|
|
22734
|
-
const projectsDir =
|
|
22735
|
-
if (!
|
|
22856
|
+
const projectsDir = path47.join(os13.homedir(), ".prjct-cli", "projects");
|
|
22857
|
+
if (!fs44.existsSync(projectsDir)) {
|
|
22736
22858
|
return;
|
|
22737
22859
|
}
|
|
22738
|
-
const projectDirs =
|
|
22860
|
+
const projectDirs = fs44.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
22739
22861
|
let migrated = 0;
|
|
22740
22862
|
for (const projectId of projectDirs) {
|
|
22741
|
-
const projectJsonPath =
|
|
22742
|
-
if (!
|
|
22863
|
+
const projectJsonPath = path47.join(projectsDir, projectId, "project.json");
|
|
22864
|
+
if (!fs44.existsSync(projectJsonPath)) {
|
|
22743
22865
|
continue;
|
|
22744
22866
|
}
|
|
22745
22867
|
try {
|
|
22746
|
-
const content =
|
|
22868
|
+
const content = fs44.readFileSync(projectJsonPath, "utf8");
|
|
22747
22869
|
const project = JSON.parse(content);
|
|
22748
22870
|
if (project.cliVersion !== VERSION) {
|
|
22749
22871
|
project.cliVersion = VERSION;
|
|
22750
|
-
|
|
22872
|
+
fs44.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
22751
22873
|
migrated++;
|
|
22752
22874
|
}
|
|
22753
22875
|
} catch (error) {
|
|
@@ -22767,9 +22889,9 @@ async function migrateProjectsCliVersion() {
|
|
|
22767
22889
|
}
|
|
22768
22890
|
function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
22769
22891
|
let settings = {};
|
|
22770
|
-
if (
|
|
22892
|
+
if (fs44.existsSync(settingsPath)) {
|
|
22771
22893
|
try {
|
|
22772
|
-
settings = JSON.parse(
|
|
22894
|
+
settings = JSON.parse(fs44.readFileSync(settingsPath, "utf8"));
|
|
22773
22895
|
} catch (error) {
|
|
22774
22896
|
if (!(error instanceof SyntaxError)) {
|
|
22775
22897
|
throw error;
|
|
@@ -22777,42 +22899,42 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
|
22777
22899
|
}
|
|
22778
22900
|
}
|
|
22779
22901
|
settings.statusLine = { type: "command", command: statusLinePath };
|
|
22780
|
-
|
|
22902
|
+
fs44.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
22781
22903
|
}
|
|
22782
22904
|
async function installStatusLine() {
|
|
22783
22905
|
try {
|
|
22784
|
-
const claudeDir =
|
|
22785
|
-
const settingsPath =
|
|
22786
|
-
const claudeStatusLinePath =
|
|
22787
|
-
const prjctStatusLineDir =
|
|
22788
|
-
const prjctStatusLinePath =
|
|
22789
|
-
const prjctThemesDir =
|
|
22790
|
-
const prjctLibDir =
|
|
22791
|
-
const prjctComponentsDir =
|
|
22792
|
-
const prjctConfigPath =
|
|
22793
|
-
const assetsDir =
|
|
22794
|
-
const sourceScript =
|
|
22795
|
-
const sourceThemeDir =
|
|
22796
|
-
const sourceLibDir =
|
|
22797
|
-
const sourceComponentsDir =
|
|
22798
|
-
const sourceConfigPath =
|
|
22799
|
-
if (!
|
|
22800
|
-
|
|
22906
|
+
const claudeDir = path47.join(os13.homedir(), ".claude");
|
|
22907
|
+
const settingsPath = path47.join(claudeDir, "settings.json");
|
|
22908
|
+
const claudeStatusLinePath = path47.join(claudeDir, "prjct-statusline.sh");
|
|
22909
|
+
const prjctStatusLineDir = path47.join(os13.homedir(), ".prjct-cli", "statusline");
|
|
22910
|
+
const prjctStatusLinePath = path47.join(prjctStatusLineDir, "statusline.sh");
|
|
22911
|
+
const prjctThemesDir = path47.join(prjctStatusLineDir, "themes");
|
|
22912
|
+
const prjctLibDir = path47.join(prjctStatusLineDir, "lib");
|
|
22913
|
+
const prjctComponentsDir = path47.join(prjctStatusLineDir, "components");
|
|
22914
|
+
const prjctConfigPath = path47.join(prjctStatusLineDir, "config.json");
|
|
22915
|
+
const assetsDir = path47.join(getPackageRoot(), "assets", "statusline");
|
|
22916
|
+
const sourceScript = path47.join(assetsDir, "statusline.sh");
|
|
22917
|
+
const sourceThemeDir = path47.join(assetsDir, "themes");
|
|
22918
|
+
const sourceLibDir = path47.join(assetsDir, "lib");
|
|
22919
|
+
const sourceComponentsDir = path47.join(assetsDir, "components");
|
|
22920
|
+
const sourceConfigPath = path47.join(assetsDir, "default-config.json");
|
|
22921
|
+
if (!fs44.existsSync(claudeDir)) {
|
|
22922
|
+
fs44.mkdirSync(claudeDir, { recursive: true });
|
|
22801
22923
|
}
|
|
22802
|
-
if (!
|
|
22803
|
-
|
|
22924
|
+
if (!fs44.existsSync(prjctStatusLineDir)) {
|
|
22925
|
+
fs44.mkdirSync(prjctStatusLineDir, { recursive: true });
|
|
22804
22926
|
}
|
|
22805
|
-
if (!
|
|
22806
|
-
|
|
22927
|
+
if (!fs44.existsSync(prjctThemesDir)) {
|
|
22928
|
+
fs44.mkdirSync(prjctThemesDir, { recursive: true });
|
|
22807
22929
|
}
|
|
22808
|
-
if (!
|
|
22809
|
-
|
|
22930
|
+
if (!fs44.existsSync(prjctLibDir)) {
|
|
22931
|
+
fs44.mkdirSync(prjctLibDir, { recursive: true });
|
|
22810
22932
|
}
|
|
22811
|
-
if (!
|
|
22812
|
-
|
|
22933
|
+
if (!fs44.existsSync(prjctComponentsDir)) {
|
|
22934
|
+
fs44.mkdirSync(prjctComponentsDir, { recursive: true });
|
|
22813
22935
|
}
|
|
22814
|
-
if (
|
|
22815
|
-
const existingContent =
|
|
22936
|
+
if (fs44.existsSync(prjctStatusLinePath)) {
|
|
22937
|
+
const existingContent = fs44.readFileSync(prjctStatusLinePath, "utf8");
|
|
22816
22938
|
if (existingContent.includes("CLI_VERSION=")) {
|
|
22817
22939
|
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
22818
22940
|
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
@@ -22820,7 +22942,7 @@ async function installStatusLine() {
|
|
|
22820
22942
|
/CLI_VERSION="[^"]*"/,
|
|
22821
22943
|
`CLI_VERSION="${VERSION}"`
|
|
22822
22944
|
);
|
|
22823
|
-
|
|
22945
|
+
fs44.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
22824
22946
|
}
|
|
22825
22947
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
22826
22948
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
@@ -22829,22 +22951,22 @@ async function installStatusLine() {
|
|
|
22829
22951
|
return;
|
|
22830
22952
|
}
|
|
22831
22953
|
}
|
|
22832
|
-
if (
|
|
22833
|
-
let scriptContent =
|
|
22954
|
+
if (fs44.existsSync(sourceScript)) {
|
|
22955
|
+
let scriptContent = fs44.readFileSync(sourceScript, "utf8");
|
|
22834
22956
|
scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
|
|
22835
|
-
|
|
22957
|
+
fs44.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
22836
22958
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
22837
22959
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
22838
|
-
if (
|
|
22839
|
-
const themes =
|
|
22960
|
+
if (fs44.existsSync(sourceThemeDir)) {
|
|
22961
|
+
const themes = fs44.readdirSync(sourceThemeDir);
|
|
22840
22962
|
for (const theme of themes) {
|
|
22841
|
-
const src =
|
|
22842
|
-
const dest =
|
|
22843
|
-
|
|
22963
|
+
const src = path47.join(sourceThemeDir, theme);
|
|
22964
|
+
const dest = path47.join(prjctThemesDir, theme);
|
|
22965
|
+
fs44.copyFileSync(src, dest);
|
|
22844
22966
|
}
|
|
22845
22967
|
}
|
|
22846
|
-
if (!
|
|
22847
|
-
|
|
22968
|
+
if (!fs44.existsSync(prjctConfigPath) && fs44.existsSync(sourceConfigPath)) {
|
|
22969
|
+
fs44.copyFileSync(sourceConfigPath, prjctConfigPath);
|
|
22848
22970
|
}
|
|
22849
22971
|
} else {
|
|
22850
22972
|
const scriptContent = `#!/bin/bash
|
|
@@ -22879,7 +23001,7 @@ if [ -f "$CONFIG" ]; then
|
|
|
22879
23001
|
fi
|
|
22880
23002
|
echo "prjct"
|
|
22881
23003
|
`;
|
|
22882
|
-
|
|
23004
|
+
fs44.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
22883
23005
|
}
|
|
22884
23006
|
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
22885
23007
|
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
@@ -22891,10 +23013,10 @@ echo "prjct"
|
|
|
22891
23013
|
}
|
|
22892
23014
|
async function installContext7MCP() {
|
|
22893
23015
|
try {
|
|
22894
|
-
const claudeDir =
|
|
22895
|
-
const mcpConfigPath =
|
|
22896
|
-
if (!
|
|
22897
|
-
|
|
23016
|
+
const claudeDir = path47.join(os13.homedir(), ".claude");
|
|
23017
|
+
const mcpConfigPath = path47.join(claudeDir, "mcp.json");
|
|
23018
|
+
if (!fs44.existsSync(claudeDir)) {
|
|
23019
|
+
fs44.mkdirSync(claudeDir, { recursive: true });
|
|
22898
23020
|
}
|
|
22899
23021
|
const context7Config = {
|
|
22900
23022
|
mcpServers: {
|
|
@@ -22904,54 +23026,54 @@ async function installContext7MCP() {
|
|
|
22904
23026
|
}
|
|
22905
23027
|
}
|
|
22906
23028
|
};
|
|
22907
|
-
if (
|
|
22908
|
-
const existingContent =
|
|
23029
|
+
if (fs44.existsSync(mcpConfigPath)) {
|
|
23030
|
+
const existingContent = fs44.readFileSync(mcpConfigPath, "utf-8");
|
|
22909
23031
|
const existingConfig = JSON.parse(existingContent);
|
|
22910
23032
|
if (existingConfig.mcpServers?.context7) {
|
|
22911
23033
|
return;
|
|
22912
23034
|
}
|
|
22913
23035
|
existingConfig.mcpServers = existingConfig.mcpServers || {};
|
|
22914
23036
|
existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
|
|
22915
|
-
|
|
23037
|
+
fs44.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
|
|
22916
23038
|
} else {
|
|
22917
|
-
|
|
23039
|
+
fs44.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
|
|
22918
23040
|
}
|
|
22919
23041
|
} catch (error) {
|
|
22920
23042
|
console.error(`Context7 MCP setup warning: ${error.message}`);
|
|
22921
23043
|
}
|
|
22922
23044
|
}
|
|
22923
23045
|
function installStatusLineModules(sourceDir, destDir) {
|
|
22924
|
-
if (!
|
|
23046
|
+
if (!fs44.existsSync(sourceDir)) {
|
|
22925
23047
|
return;
|
|
22926
23048
|
}
|
|
22927
|
-
const files =
|
|
23049
|
+
const files = fs44.readdirSync(sourceDir);
|
|
22928
23050
|
for (const file of files) {
|
|
22929
23051
|
if (file.endsWith(".sh")) {
|
|
22930
|
-
const src =
|
|
22931
|
-
const dest =
|
|
22932
|
-
|
|
22933
|
-
|
|
23052
|
+
const src = path47.join(sourceDir, file);
|
|
23053
|
+
const dest = path47.join(destDir, file);
|
|
23054
|
+
fs44.copyFileSync(src, dest);
|
|
23055
|
+
fs44.chmodSync(dest, 493);
|
|
22934
23056
|
}
|
|
22935
23057
|
}
|
|
22936
23058
|
}
|
|
22937
23059
|
function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
22938
23060
|
try {
|
|
22939
|
-
if (
|
|
22940
|
-
const stats =
|
|
23061
|
+
if (fs44.existsSync(linkPath)) {
|
|
23062
|
+
const stats = fs44.lstatSync(linkPath);
|
|
22941
23063
|
if (stats.isSymbolicLink()) {
|
|
22942
|
-
const existingTarget =
|
|
23064
|
+
const existingTarget = fs44.readlinkSync(linkPath);
|
|
22943
23065
|
if (existingTarget === targetPath) {
|
|
22944
23066
|
return;
|
|
22945
23067
|
}
|
|
22946
23068
|
}
|
|
22947
|
-
|
|
23069
|
+
fs44.unlinkSync(linkPath);
|
|
22948
23070
|
}
|
|
22949
|
-
|
|
23071
|
+
fs44.symlinkSync(targetPath, linkPath);
|
|
22950
23072
|
} catch (_error) {
|
|
22951
23073
|
try {
|
|
22952
|
-
if (
|
|
22953
|
-
|
|
22954
|
-
|
|
23074
|
+
if (fs44.existsSync(targetPath)) {
|
|
23075
|
+
fs44.copyFileSync(targetPath, linkPath);
|
|
23076
|
+
fs44.chmodSync(linkPath, 493);
|
|
22955
23077
|
}
|
|
22956
23078
|
} catch (copyError) {
|
|
22957
23079
|
if (!isNotFoundError(copyError)) {
|
|
@@ -23366,7 +23488,7 @@ var init_registry2 = __esm({
|
|
|
23366
23488
|
});
|
|
23367
23489
|
|
|
23368
23490
|
// core/commands/analytics.ts
|
|
23369
|
-
import
|
|
23491
|
+
import path48 from "node:path";
|
|
23370
23492
|
var AnalyticsCommands;
|
|
23371
23493
|
var init_analytics = __esm({
|
|
23372
23494
|
"core/commands/analytics.ts"() {
|
|
@@ -23392,7 +23514,7 @@ var init_analytics = __esm({
|
|
|
23392
23514
|
output_default.failWithHint("NO_PROJECT_ID");
|
|
23393
23515
|
return { success: false, error: "No project ID found" };
|
|
23394
23516
|
}
|
|
23395
|
-
const projectName =
|
|
23517
|
+
const projectName = path48.basename(projectPath);
|
|
23396
23518
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
23397
23519
|
const queueTasks = await queueStorage.getActiveTasks(projectId);
|
|
23398
23520
|
const shipped = await shippedStorage.getRecent(projectId, 5);
|
|
@@ -23644,8 +23766,8 @@ ${"\u2550".repeat(50)}
|
|
|
23644
23766
|
});
|
|
23645
23767
|
|
|
23646
23768
|
// core/commands/context.ts
|
|
23647
|
-
import
|
|
23648
|
-
import
|
|
23769
|
+
import fs45 from "node:fs/promises";
|
|
23770
|
+
import path49 from "node:path";
|
|
23649
23771
|
var ContextCommands, contextCommands;
|
|
23650
23772
|
var init_context = __esm({
|
|
23651
23773
|
"core/commands/context.ts"() {
|
|
@@ -23771,8 +23893,8 @@ var init_context = __esm({
|
|
|
23771
23893
|
*/
|
|
23772
23894
|
async loadRepoAnalysis(globalPath) {
|
|
23773
23895
|
try {
|
|
23774
|
-
const analysisPath =
|
|
23775
|
-
const content = await
|
|
23896
|
+
const analysisPath = path49.join(globalPath, "analysis", "repo-analysis.json");
|
|
23897
|
+
const content = await fs45.readFile(analysisPath, "utf-8");
|
|
23776
23898
|
const data = JSON.parse(content);
|
|
23777
23899
|
return {
|
|
23778
23900
|
ecosystem: data.ecosystem || "unknown",
|
|
@@ -23791,7 +23913,7 @@ var init_context = __esm({
|
|
|
23791
23913
|
});
|
|
23792
23914
|
|
|
23793
23915
|
// core/commands/cleanup.ts
|
|
23794
|
-
import
|
|
23916
|
+
import path50 from "node:path";
|
|
23795
23917
|
async function cleanupMemory(projectPath) {
|
|
23796
23918
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23797
23919
|
const results = { rotated: [], totalSize: 0, freedSpace: 0 };
|
|
@@ -23807,7 +23929,7 @@ async function cleanupMemory(projectPath) {
|
|
|
23807
23929
|
results.totalSize += sizeMB;
|
|
23808
23930
|
const rotated = await jsonl_helper_default.rotateJsonLinesIfNeeded(filePath, 10);
|
|
23809
23931
|
if (rotated) {
|
|
23810
|
-
results.rotated.push(
|
|
23932
|
+
results.rotated.push(path50.basename(filePath));
|
|
23811
23933
|
results.freedSpace += sizeMB;
|
|
23812
23934
|
}
|
|
23813
23935
|
}
|
|
@@ -23914,7 +24036,7 @@ var init_cleanup = __esm({
|
|
|
23914
24036
|
});
|
|
23915
24037
|
|
|
23916
24038
|
// core/commands/design.ts
|
|
23917
|
-
import
|
|
24039
|
+
import path51 from "node:path";
|
|
23918
24040
|
async function design(target = null, options = {}, projectPath = process.cwd()) {
|
|
23919
24041
|
try {
|
|
23920
24042
|
const designType = options.type || "architecture";
|
|
@@ -23926,7 +24048,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
23926
24048
|
const designTarget = target || "system";
|
|
23927
24049
|
output_default.spin(`designing ${designType}...`);
|
|
23928
24050
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23929
|
-
const designsPath =
|
|
24051
|
+
const designsPath = path51.join(
|
|
23930
24052
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
23931
24053
|
"planning",
|
|
23932
24054
|
"designs"
|
|
@@ -23966,7 +24088,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
23966
24088
|
break;
|
|
23967
24089
|
}
|
|
23968
24090
|
const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
|
|
23969
|
-
const designFilePath =
|
|
24091
|
+
const designFilePath = path51.join(designsPath, designFileName);
|
|
23970
24092
|
await file_helper_exports.writeFile(designFilePath, designContent);
|
|
23971
24093
|
await memoryService.log(projectPath, "design_created", {
|
|
23972
24094
|
type: designType,
|
|
@@ -23990,7 +24112,7 @@ var init_design = __esm({
|
|
|
23990
24112
|
});
|
|
23991
24113
|
|
|
23992
24114
|
// core/commands/snapshots.ts
|
|
23993
|
-
import
|
|
24115
|
+
import path52 from "node:path";
|
|
23994
24116
|
async function recover(projectPath = process.cwd()) {
|
|
23995
24117
|
try {
|
|
23996
24118
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
@@ -24042,7 +24164,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
24042
24164
|
output_default.failWithHint("NO_PROJECT_ID");
|
|
24043
24165
|
return { success: false, error: "No project ID found" };
|
|
24044
24166
|
}
|
|
24045
|
-
const snapshotsPath =
|
|
24167
|
+
const snapshotsPath = path52.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
24046
24168
|
await file_helper_exports.ensureDir(snapshotsPath);
|
|
24047
24169
|
const { execSync: execSync7 } = await import("node:child_process");
|
|
24048
24170
|
try {
|
|
@@ -24060,7 +24182,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
24060
24182
|
cwd: projectPath,
|
|
24061
24183
|
encoding: "utf-8"
|
|
24062
24184
|
});
|
|
24063
|
-
const snapshotFile =
|
|
24185
|
+
const snapshotFile = path52.join(snapshotsPath, "history.json");
|
|
24064
24186
|
let history2 = { snapshots: [], current: -1 };
|
|
24065
24187
|
try {
|
|
24066
24188
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -24100,8 +24222,8 @@ async function redo(projectPath = process.cwd()) {
|
|
|
24100
24222
|
output_default.failWithHint("NO_PROJECT_ID");
|
|
24101
24223
|
return { success: false, error: "No project ID found" };
|
|
24102
24224
|
}
|
|
24103
|
-
const snapshotsPath =
|
|
24104
|
-
const snapshotFile =
|
|
24225
|
+
const snapshotsPath = path52.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
24226
|
+
const snapshotFile = path52.join(snapshotsPath, "history.json");
|
|
24105
24227
|
let history2;
|
|
24106
24228
|
try {
|
|
24107
24229
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -24160,8 +24282,8 @@ async function history(projectPath = process.cwd()) {
|
|
|
24160
24282
|
output_default.failWithHint("NO_PROJECT_ID");
|
|
24161
24283
|
return { success: false, error: "No project ID found" };
|
|
24162
24284
|
}
|
|
24163
|
-
const snapshotsPath =
|
|
24164
|
-
const snapshotFile =
|
|
24285
|
+
const snapshotsPath = path52.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
24286
|
+
const snapshotFile = path52.join(snapshotsPath, "history.json");
|
|
24165
24287
|
let snapshotHistory;
|
|
24166
24288
|
try {
|
|
24167
24289
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -24268,8 +24390,8 @@ var init_maintenance = __esm({
|
|
|
24268
24390
|
});
|
|
24269
24391
|
|
|
24270
24392
|
// core/commands/setup.ts
|
|
24271
|
-
import
|
|
24272
|
-
import
|
|
24393
|
+
import fs46 from "node:fs";
|
|
24394
|
+
import path53 from "node:path";
|
|
24273
24395
|
import chalk11 from "chalk";
|
|
24274
24396
|
var SetupCommands;
|
|
24275
24397
|
var init_setup2 = __esm({
|
|
@@ -24396,7 +24518,7 @@ Please install it first:
|
|
|
24396
24518
|
try {
|
|
24397
24519
|
const claudeDir = path_manager_default.getClaudeDir();
|
|
24398
24520
|
const settingsPath = path_manager_default.getClaudeSettingsPath();
|
|
24399
|
-
const statusLinePath =
|
|
24521
|
+
const statusLinePath = path53.join(claudeDir, "prjct-statusline.sh");
|
|
24400
24522
|
const scriptContent = `#!/bin/bash
|
|
24401
24523
|
# prjct Status Line for Claude Code
|
|
24402
24524
|
# Shows version update notifications and current task
|
|
@@ -24454,11 +24576,11 @@ fi
|
|
|
24454
24576
|
# Default: show prjct branding
|
|
24455
24577
|
echo "\u26A1 prjct"
|
|
24456
24578
|
`;
|
|
24457
|
-
|
|
24579
|
+
fs46.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
24458
24580
|
let settings = {};
|
|
24459
|
-
if (
|
|
24581
|
+
if (fs46.existsSync(settingsPath)) {
|
|
24460
24582
|
try {
|
|
24461
|
-
settings = JSON.parse(
|
|
24583
|
+
settings = JSON.parse(fs46.readFileSync(settingsPath, "utf8"));
|
|
24462
24584
|
} catch (_error) {
|
|
24463
24585
|
}
|
|
24464
24586
|
}
|
|
@@ -24466,7 +24588,7 @@ echo "\u26A1 prjct"
|
|
|
24466
24588
|
type: "command",
|
|
24467
24589
|
command: statusLinePath
|
|
24468
24590
|
};
|
|
24469
|
-
|
|
24591
|
+
fs46.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
24470
24592
|
return { success: true };
|
|
24471
24593
|
} catch (error) {
|
|
24472
24594
|
return { success: false, error: error.message };
|
|
@@ -24522,18 +24644,18 @@ echo "\u26A1 prjct"
|
|
|
24522
24644
|
});
|
|
24523
24645
|
|
|
24524
24646
|
// core/utils/project-commands.ts
|
|
24525
|
-
import
|
|
24647
|
+
import path54 from "node:path";
|
|
24526
24648
|
async function detectPackageManager(projectPath, pkg) {
|
|
24527
24649
|
const declared = pkg?.packageManager?.trim().toLowerCase();
|
|
24528
24650
|
if (declared?.startsWith("pnpm@")) return "pnpm";
|
|
24529
24651
|
if (declared?.startsWith("yarn@")) return "yarn";
|
|
24530
24652
|
if (declared?.startsWith("bun@")) return "bun";
|
|
24531
24653
|
if (declared?.startsWith("npm@")) return "npm";
|
|
24532
|
-
if (await fileExists(
|
|
24533
|
-
if (await fileExists(
|
|
24534
|
-
if (await fileExists(
|
|
24535
|
-
if (await fileExists(
|
|
24536
|
-
if (await fileExists(
|
|
24654
|
+
if (await fileExists(path54.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
|
|
24655
|
+
if (await fileExists(path54.join(projectPath, "yarn.lock"))) return "yarn";
|
|
24656
|
+
if (await fileExists(path54.join(projectPath, "bun.lockb"))) return "bun";
|
|
24657
|
+
if (await fileExists(path54.join(projectPath, "bun.lock"))) return "bun";
|
|
24658
|
+
if (await fileExists(path54.join(projectPath, "package-lock.json"))) return "npm";
|
|
24537
24659
|
return "npm";
|
|
24538
24660
|
}
|
|
24539
24661
|
function pmRun(pm, scriptName) {
|
|
@@ -24549,7 +24671,7 @@ function pmTest(pm) {
|
|
|
24549
24671
|
return "npm test";
|
|
24550
24672
|
}
|
|
24551
24673
|
async function detectProjectCommands(projectPath) {
|
|
24552
|
-
const pkgPath =
|
|
24674
|
+
const pkgPath = path54.join(projectPath, "package.json");
|
|
24553
24675
|
const pkg = await readJson(pkgPath, null);
|
|
24554
24676
|
if (pkg) {
|
|
24555
24677
|
const pm = await detectPackageManager(projectPath, pkg);
|
|
@@ -24566,27 +24688,27 @@ async function detectProjectCommands(projectPath) {
|
|
|
24566
24688
|
}
|
|
24567
24689
|
return result;
|
|
24568
24690
|
}
|
|
24569
|
-
if (await fileExists(
|
|
24691
|
+
if (await fileExists(path54.join(projectPath, "pytest.ini"))) {
|
|
24570
24692
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
24571
24693
|
}
|
|
24572
|
-
const pyproject = await readFile(
|
|
24694
|
+
const pyproject = await readFile(path54.join(projectPath, "pyproject.toml"), "");
|
|
24573
24695
|
if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
|
|
24574
24696
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
24575
24697
|
}
|
|
24576
|
-
if (await fileExists(
|
|
24698
|
+
if (await fileExists(path54.join(projectPath, "Cargo.toml"))) {
|
|
24577
24699
|
return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
|
|
24578
24700
|
}
|
|
24579
|
-
if (await fileExists(
|
|
24701
|
+
if (await fileExists(path54.join(projectPath, "go.mod"))) {
|
|
24580
24702
|
return { stack: "go", test: { tool: "go", command: "go test ./..." } };
|
|
24581
24703
|
}
|
|
24582
24704
|
const files = await listFiles(projectPath);
|
|
24583
24705
|
if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
|
|
24584
24706
|
return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
|
|
24585
24707
|
}
|
|
24586
|
-
if (await fileExists(
|
|
24708
|
+
if (await fileExists(path54.join(projectPath, "pom.xml"))) {
|
|
24587
24709
|
return { stack: "java", test: { tool: "maven", command: "mvn test" } };
|
|
24588
24710
|
}
|
|
24589
|
-
if (await fileExists(
|
|
24711
|
+
if (await fileExists(path54.join(projectPath, "gradlew")) && (await fileExists(path54.join(projectPath, "build.gradle")) || await fileExists(path54.join(projectPath, "build.gradle.kts")))) {
|
|
24590
24712
|
return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
|
|
24591
24713
|
}
|
|
24592
24714
|
return { stack: "unknown" };
|
|
@@ -24763,7 +24885,7 @@ var init_workflow_preferences = __esm({
|
|
|
24763
24885
|
});
|
|
24764
24886
|
|
|
24765
24887
|
// core/commands/shipping.ts
|
|
24766
|
-
import
|
|
24888
|
+
import path55 from "node:path";
|
|
24767
24889
|
var ShippingCommands;
|
|
24768
24890
|
var init_shipping = __esm({
|
|
24769
24891
|
"core/commands/shipping.ts"() {
|
|
@@ -24909,7 +25031,7 @@ ${result.stderr}`.trim();
|
|
|
24909
25031
|
*/
|
|
24910
25032
|
async _bumpVersion(projectPath) {
|
|
24911
25033
|
try {
|
|
24912
|
-
const pkgPath =
|
|
25034
|
+
const pkgPath = path55.join(projectPath, "package.json");
|
|
24913
25035
|
const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
|
|
24914
25036
|
const oldVersion = pkg?.version || "0.0.0";
|
|
24915
25037
|
const [major, minor, patch] = oldVersion.split(".").map(Number);
|
|
@@ -24931,7 +25053,7 @@ ${result.stderr}`.trim();
|
|
|
24931
25053
|
*/
|
|
24932
25054
|
async _updateChangelog(feature, version, projectPath) {
|
|
24933
25055
|
try {
|
|
24934
|
-
const changelogPath =
|
|
25056
|
+
const changelogPath = path55.join(projectPath, "CHANGELOG.md");
|
|
24935
25057
|
const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
|
|
24936
25058
|
const entry = `## [${version}] - ${date_helper_default.formatDate(/* @__PURE__ */ new Date())}
|
|
24937
25059
|
|
|
@@ -25823,19 +25945,19 @@ var init_linear = __esm({
|
|
|
25823
25945
|
});
|
|
25824
25946
|
|
|
25825
25947
|
// core/utils/project-credentials.ts
|
|
25826
|
-
import
|
|
25948
|
+
import fs47 from "node:fs";
|
|
25827
25949
|
import os14 from "node:os";
|
|
25828
|
-
import
|
|
25950
|
+
import path56 from "node:path";
|
|
25829
25951
|
function getCredentialsPath(projectId) {
|
|
25830
|
-
return
|
|
25952
|
+
return path56.join(os14.homedir(), ".prjct-cli", "projects", projectId, "config", "credentials.json");
|
|
25831
25953
|
}
|
|
25832
25954
|
async function getProjectCredentials(projectId) {
|
|
25833
25955
|
const credPath = getCredentialsPath(projectId);
|
|
25834
|
-
if (!
|
|
25956
|
+
if (!fs47.existsSync(credPath)) {
|
|
25835
25957
|
return {};
|
|
25836
25958
|
}
|
|
25837
25959
|
try {
|
|
25838
|
-
return JSON.parse(
|
|
25960
|
+
return JSON.parse(fs47.readFileSync(credPath, "utf-8"));
|
|
25839
25961
|
} catch (error) {
|
|
25840
25962
|
console.error("[project-credentials] Failed to read credentials:", error.message);
|
|
25841
25963
|
return {};
|
|
@@ -26412,7 +26534,7 @@ var require_package = __commonJS({
|
|
|
26412
26534
|
"package.json"(exports, module) {
|
|
26413
26535
|
module.exports = {
|
|
26414
26536
|
name: "prjct-cli",
|
|
26415
|
-
version: "0.
|
|
26537
|
+
version: "0.61.0",
|
|
26416
26538
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
26417
26539
|
main: "core/index.ts",
|
|
26418
26540
|
bin: {
|
|
@@ -26519,9 +26641,9 @@ var require_package = __commonJS({
|
|
|
26519
26641
|
|
|
26520
26642
|
// core/index.ts
|
|
26521
26643
|
var core_exports = {};
|
|
26522
|
-
import
|
|
26644
|
+
import fs48 from "node:fs";
|
|
26523
26645
|
import os15 from "node:os";
|
|
26524
|
-
import
|
|
26646
|
+
import path57 from "node:path";
|
|
26525
26647
|
async function main() {
|
|
26526
26648
|
const [commandName, ...rawArgs] = process.argv.slice(2);
|
|
26527
26649
|
if (["-v", "--version", "version"].includes(commandName)) {
|
|
@@ -26653,12 +26775,12 @@ function parseCommandArgs(_cmd, rawArgs) {
|
|
|
26653
26775
|
}
|
|
26654
26776
|
function displayVersion(version) {
|
|
26655
26777
|
const detection = detectAllProviders();
|
|
26656
|
-
const claudeCommandPath =
|
|
26657
|
-
const geminiCommandPath =
|
|
26658
|
-
const claudeConfigured =
|
|
26659
|
-
const geminiConfigured =
|
|
26660
|
-
const cursorConfigured =
|
|
26661
|
-
const cursorExists =
|
|
26778
|
+
const claudeCommandPath = path57.join(os15.homedir(), ".claude", "commands", "p.md");
|
|
26779
|
+
const geminiCommandPath = path57.join(os15.homedir(), ".gemini", "commands", "p.toml");
|
|
26780
|
+
const claudeConfigured = fs48.existsSync(claudeCommandPath);
|
|
26781
|
+
const geminiConfigured = fs48.existsSync(geminiCommandPath);
|
|
26782
|
+
const cursorConfigured = fs48.existsSync(path57.join(process.cwd(), ".cursor", "commands", "sync.md"));
|
|
26783
|
+
const cursorExists = fs48.existsSync(path57.join(process.cwd(), ".cursor"));
|
|
26662
26784
|
console.log(`
|
|
26663
26785
|
${CYAN3}p/${RESET5} prjct v${version}
|
|
26664
26786
|
${DIM6}Context layer for AI coding agents${RESET5}
|
|
@@ -26791,9 +26913,9 @@ var init_core = __esm({
|
|
|
26791
26913
|
init_ai_provider();
|
|
26792
26914
|
init_config_manager();
|
|
26793
26915
|
init_editors_config();
|
|
26794
|
-
import
|
|
26916
|
+
import fs49 from "node:fs";
|
|
26795
26917
|
import os16 from "node:os";
|
|
26796
|
-
import
|
|
26918
|
+
import path58 from "node:path";
|
|
26797
26919
|
|
|
26798
26920
|
// core/server/server.ts
|
|
26799
26921
|
import { Hono as Hono3 } from "hono";
|
|
@@ -27535,14 +27657,14 @@ function checkRoutersInstalled() {
|
|
|
27535
27657
|
const home = os16.homedir();
|
|
27536
27658
|
const detection = detectAllProviders();
|
|
27537
27659
|
if (detection.claude.installed) {
|
|
27538
|
-
const claudeRouter =
|
|
27539
|
-
if (!
|
|
27660
|
+
const claudeRouter = path58.join(home, ".claude", "commands", "p.md");
|
|
27661
|
+
if (!fs49.existsSync(claudeRouter)) {
|
|
27540
27662
|
return false;
|
|
27541
27663
|
}
|
|
27542
27664
|
}
|
|
27543
27665
|
if (detection.gemini.installed) {
|
|
27544
|
-
const geminiRouter =
|
|
27545
|
-
if (!
|
|
27666
|
+
const geminiRouter = path58.join(home, ".gemini", "commands", "p.toml");
|
|
27667
|
+
if (!fs49.existsSync(geminiRouter)) {
|
|
27546
27668
|
return false;
|
|
27547
27669
|
}
|
|
27548
27670
|
}
|
|
@@ -27643,7 +27765,7 @@ if (args[0] === "start" || args[0] === "setup") {
|
|
|
27643
27765
|
console.error('No prjct project found. Run "prjct init" first.');
|
|
27644
27766
|
process.exitCode = 1;
|
|
27645
27767
|
} else {
|
|
27646
|
-
const linearCliPath =
|
|
27768
|
+
const linearCliPath = path58.join(__dirname, "..", "core", "cli", "linear.ts");
|
|
27647
27769
|
const linearArgs = ["--project", projectId, ...args.slice(1)];
|
|
27648
27770
|
const child = spawn("bun", [linearCliPath, ...linearArgs], {
|
|
27649
27771
|
stdio: "inherit",
|
|
@@ -27662,12 +27784,12 @@ if (args[0] === "start" || args[0] === "setup") {
|
|
|
27662
27784
|
const detection = detectAllProviders();
|
|
27663
27785
|
const home = os16.homedir();
|
|
27664
27786
|
const cwd = process.cwd();
|
|
27665
|
-
const claudeConfigured =
|
|
27666
|
-
const geminiConfigured =
|
|
27667
|
-
const cursorDetected =
|
|
27668
|
-
const cursorConfigured =
|
|
27669
|
-
const windsurfDetected =
|
|
27670
|
-
const windsurfConfigured =
|
|
27787
|
+
const claudeConfigured = fs49.existsSync(path58.join(home, ".claude", "commands", "p.md"));
|
|
27788
|
+
const geminiConfigured = fs49.existsSync(path58.join(home, ".gemini", "commands", "p.toml"));
|
|
27789
|
+
const cursorDetected = fs49.existsSync(path58.join(cwd, ".cursor"));
|
|
27790
|
+
const cursorConfigured = fs49.existsSync(path58.join(cwd, ".cursor", "rules", "prjct.mdc"));
|
|
27791
|
+
const windsurfDetected = fs49.existsSync(path58.join(cwd, ".windsurf"));
|
|
27792
|
+
const windsurfConfigured = fs49.existsSync(path58.join(cwd, ".windsurf", "rules", "prjct.md"));
|
|
27671
27793
|
const GREEN7 = "\x1B[32m";
|
|
27672
27794
|
console.log(`
|
|
27673
27795
|
${CYAN4}p/${RESET6} prjct v${VERSION}
|
|
@@ -27706,9 +27828,9 @@ ${DIM7}Run 'prjct init' to configure (Cursor/Windsurf IDE)${RESET6}
|
|
|
27706
27828
|
${CYAN4}https://prjct.app${RESET6}
|
|
27707
27829
|
`);
|
|
27708
27830
|
} else {
|
|
27709
|
-
const configPath =
|
|
27831
|
+
const configPath = path58.join(os16.homedir(), ".prjct-cli", "config", "installed-editors.json");
|
|
27710
27832
|
const routersInstalled = checkRoutersInstalled();
|
|
27711
|
-
if (!
|
|
27833
|
+
if (!fs49.existsSync(configPath) || !routersInstalled) {
|
|
27712
27834
|
console.log(`
|
|
27713
27835
|
${CYAN4}${BOLD4} Welcome to prjct!${RESET6}
|
|
27714
27836
|
|