prjct-cli 0.44.1 → 0.45.3
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 +114 -0
- package/bin/prjct.ts +131 -10
- package/core/__tests__/agentic/memory-system.test.ts +39 -26
- package/core/__tests__/agentic/plan-mode.test.ts +64 -46
- package/core/__tests__/agentic/prompt-builder.test.ts +14 -14
- package/core/__tests__/services/project-index.test.ts +353 -0
- package/core/__tests__/types/fs.test.ts +3 -3
- package/core/__tests__/utils/date-helper.test.ts +10 -10
- package/core/__tests__/utils/output.test.ts +9 -6
- package/core/__tests__/utils/project-commands.test.ts +5 -6
- package/core/agentic/agent-router.ts +9 -10
- package/core/agentic/chain-of-thought.ts +16 -4
- package/core/agentic/command-executor.ts +66 -40
- package/core/agentic/context-builder.ts +8 -5
- package/core/agentic/ground-truth.ts +15 -9
- package/core/agentic/index.ts +145 -152
- package/core/agentic/loop-detector.ts +40 -11
- package/core/agentic/memory-system.ts +98 -35
- package/core/agentic/orchestrator-executor.ts +135 -71
- package/core/agentic/plan-mode.ts +46 -16
- package/core/agentic/prompt-builder.ts +108 -42
- package/core/agentic/services.ts +10 -9
- package/core/agentic/skill-loader.ts +9 -15
- package/core/agentic/smart-context.ts +129 -79
- package/core/agentic/template-executor.ts +13 -12
- package/core/agentic/template-loader.ts +7 -4
- package/core/agentic/tool-registry.ts +16 -13
- package/core/agents/index.ts +1 -1
- package/core/agents/performance.ts +10 -27
- package/core/ai-tools/formatters.ts +8 -6
- package/core/ai-tools/generator.ts +4 -4
- package/core/ai-tools/index.ts +1 -1
- package/core/ai-tools/registry.ts +21 -11
- package/core/bus/bus.ts +23 -16
- package/core/bus/index.ts +2 -2
- package/core/cli/linear.ts +3 -5
- package/core/cli/start.ts +28 -25
- package/core/commands/analysis.ts +287 -29
- package/core/commands/analytics.ts +52 -44
- package/core/commands/base.ts +15 -13
- package/core/commands/cleanup.ts +6 -13
- package/core/commands/command-data.ts +49 -8
- package/core/commands/commands.ts +60 -23
- package/core/commands/context.ts +4 -4
- package/core/commands/design.ts +3 -10
- package/core/commands/index.ts +5 -8
- package/core/commands/maintenance.ts +7 -4
- package/core/commands/planning.ts +179 -56
- package/core/commands/register.ts +14 -9
- package/core/commands/registry.ts +15 -14
- package/core/commands/setup.ts +26 -14
- package/core/commands/shipping.ts +11 -16
- package/core/commands/snapshots.ts +16 -32
- package/core/commands/uninstall.ts +541 -0
- package/core/commands/workflow.ts +24 -28
- package/core/constants/index.ts +10 -22
- package/core/context/generator.ts +82 -33
- package/core/context-tools/files-tool.ts +583 -0
- package/core/context-tools/imports-tool.ts +403 -0
- package/core/context-tools/index.ts +433 -0
- package/core/context-tools/recent-tool.ts +307 -0
- package/core/context-tools/signatures-tool.ts +501 -0
- package/core/context-tools/summary-tool.ts +307 -0
- package/core/context-tools/token-counter.ts +284 -0
- package/core/context-tools/types.ts +253 -0
- package/core/domain/agent-generator.ts +7 -5
- package/core/domain/agent-loader.ts +2 -2
- package/core/domain/analyzer.ts +19 -16
- package/core/domain/architecture-generator.ts +6 -3
- package/core/domain/context-estimator.ts +3 -4
- package/core/domain/snapshot-manager.ts +25 -22
- package/core/domain/task-stack.ts +24 -14
- package/core/errors.ts +1 -1
- package/core/events/events.ts +2 -4
- package/core/events/index.ts +1 -2
- package/core/index.ts +28 -12
- package/core/infrastructure/agent-detector.ts +3 -3
- package/core/infrastructure/ai-provider.ts +23 -20
- package/core/infrastructure/author-detector.ts +16 -10
- package/core/infrastructure/capability-installer.ts +2 -2
- package/core/infrastructure/claude-agent.ts +6 -6
- package/core/infrastructure/command-installer.ts +22 -17
- package/core/infrastructure/config-manager.ts +18 -14
- package/core/infrastructure/editors-config.ts +8 -4
- package/core/infrastructure/path-manager.ts +8 -6
- package/core/infrastructure/permission-manager.ts +20 -17
- package/core/infrastructure/setup.ts +42 -38
- package/core/infrastructure/update-checker.ts +5 -5
- package/core/integrations/issue-tracker/enricher.ts +8 -19
- package/core/integrations/issue-tracker/index.ts +2 -2
- package/core/integrations/issue-tracker/manager.ts +15 -15
- package/core/integrations/issue-tracker/types.ts +5 -22
- package/core/integrations/jira/client.ts +67 -59
- package/core/integrations/jira/index.ts +11 -14
- package/core/integrations/jira/mcp-adapter.ts +5 -10
- package/core/integrations/jira/service.ts +10 -10
- package/core/integrations/linear/client.ts +27 -18
- package/core/integrations/linear/index.ts +9 -12
- package/core/integrations/linear/service.ts +11 -11
- package/core/integrations/linear/sync.ts +8 -8
- package/core/outcomes/analyzer.ts +5 -18
- package/core/outcomes/index.ts +2 -2
- package/core/outcomes/recorder.ts +3 -3
- package/core/plugin/builtin/webhook.ts +19 -15
- package/core/plugin/hooks.ts +29 -21
- package/core/plugin/index.ts +7 -7
- package/core/plugin/loader.ts +19 -19
- package/core/plugin/registry.ts +12 -23
- package/core/schemas/agents.ts +1 -1
- package/core/schemas/analysis.ts +1 -1
- package/core/schemas/enriched-task.ts +62 -49
- package/core/schemas/ideas.ts +13 -13
- package/core/schemas/index.ts +17 -27
- package/core/schemas/issues.ts +40 -25
- package/core/schemas/metrics.ts +143 -0
- package/core/schemas/outcomes.ts +70 -62
- package/core/schemas/permissions.ts +15 -12
- package/core/schemas/prd.ts +27 -14
- package/core/schemas/project.ts +3 -3
- package/core/schemas/roadmap.ts +47 -34
- package/core/schemas/schemas.ts +3 -4
- package/core/schemas/shipped.ts +3 -3
- package/core/schemas/state.ts +43 -29
- package/core/server/index.ts +5 -6
- package/core/server/routes-extended.ts +68 -72
- package/core/server/routes.ts +3 -3
- package/core/server/server.ts +31 -26
- package/core/services/agent-generator.ts +237 -0
- package/core/services/agent-service.ts +2 -2
- package/core/services/breakdown-service.ts +2 -4
- package/core/services/context-generator.ts +299 -0
- package/core/services/context-selector.ts +420 -0
- package/core/services/doctor-service.ts +426 -0
- package/core/services/file-categorizer.ts +448 -0
- package/core/services/file-scorer.ts +270 -0
- package/core/services/git-analyzer.ts +267 -0
- package/core/services/index.ts +27 -10
- package/core/services/memory-service.ts +3 -4
- package/core/services/project-index.ts +911 -0
- package/core/services/project-service.ts +4 -4
- package/core/services/skill-installer.ts +14 -17
- package/core/services/skill-lock.ts +3 -3
- package/core/services/skill-service.ts +12 -6
- package/core/services/stack-detector.ts +245 -0
- package/core/services/sync-service.ts +170 -329
- package/core/services/watch-service.ts +294 -0
- package/core/session/compaction.ts +23 -31
- package/core/session/index.ts +11 -5
- package/core/session/log-migration.ts +3 -3
- package/core/session/metrics.ts +19 -14
- package/core/session/session-log-manager.ts +12 -17
- package/core/session/task-session-manager.ts +25 -25
- package/core/session/utils.ts +1 -1
- package/core/storage/ideas-storage.ts +41 -57
- package/core/storage/index-storage.ts +514 -0
- package/core/storage/index.ts +41 -13
- package/core/storage/metrics-storage.ts +320 -0
- package/core/storage/queue-storage.ts +35 -45
- package/core/storage/shipped-storage.ts +17 -20
- package/core/storage/state-storage.ts +50 -30
- package/core/storage/storage-manager.ts +6 -6
- package/core/storage/storage.ts +18 -15
- package/core/sync/auth-config.ts +3 -3
- package/core/sync/index.ts +13 -19
- package/core/sync/oauth-handler.ts +3 -3
- package/core/sync/sync-client.ts +4 -9
- package/core/sync/sync-manager.ts +12 -14
- package/core/types/commands.ts +42 -7
- package/core/types/index.ts +284 -302
- package/core/types/integrations.ts +3 -3
- package/core/types/storage.ts +49 -0
- package/core/types/utils.ts +3 -3
- package/core/utils/agent-stream.ts +3 -1
- package/core/utils/animations.ts +14 -11
- package/core/utils/branding.ts +7 -7
- package/core/utils/cache.ts +1 -3
- package/core/utils/collection-filters.ts +3 -15
- package/core/utils/date-helper.ts +2 -7
- package/core/utils/file-helper.ts +13 -8
- package/core/utils/jsonl-helper.ts +13 -10
- package/core/utils/keychain.ts +4 -8
- package/core/utils/logger.ts +1 -1
- package/core/utils/next-steps.ts +3 -3
- package/core/utils/output.ts +58 -11
- package/core/utils/project-commands.ts +6 -6
- package/core/utils/project-credentials.ts +5 -12
- package/core/utils/runtime.ts +2 -2
- package/core/utils/session-helper.ts +3 -4
- package/core/utils/version.ts +3 -3
- package/core/wizard/index.ts +13 -0
- package/core/wizard/onboarding.ts +633 -0
- package/core/workflow/state-machine.ts +7 -7
- package/dist/bin/prjct.mjs +18907 -13189
- package/dist/core/infrastructure/command-installer.js +96 -111
- package/dist/core/infrastructure/editors-config.js +6 -6
- package/dist/core/infrastructure/setup.js +256 -257
- package/dist/core/utils/version.js +9 -9
- package/package.json +11 -12
- package/scripts/build.js +3 -3
- package/scripts/postinstall.js +2 -2
- package/templates/mcp-config.json +6 -1
- package/templates/permissions/permissive.jsonc +1 -1
- package/templates/permissions/strict.jsonc +5 -9
- package/templates/global/docs/agents.md +0 -88
- package/templates/global/docs/architecture.md +0 -103
- package/templates/global/docs/commands.md +0 -96
- package/templates/global/docs/validation.md +0 -95
|
@@ -60,7 +60,7 @@ __export(ai_provider_exports, {
|
|
|
60
60
|
});
|
|
61
61
|
function whichCommand(command) {
|
|
62
62
|
try {
|
|
63
|
-
const result = (0,
|
|
63
|
+
const result = (0, import_node_child_process.execSync)(`which ${command}`, { stdio: "pipe", encoding: "utf-8" });
|
|
64
64
|
return result.trim();
|
|
65
65
|
} catch {
|
|
66
66
|
return null;
|
|
@@ -68,7 +68,7 @@ function whichCommand(command) {
|
|
|
68
68
|
}
|
|
69
69
|
function getCliVersion(command) {
|
|
70
70
|
try {
|
|
71
|
-
const result = (0,
|
|
71
|
+
const result = (0, import_node_child_process.execSync)(`${command} --version`, { stdio: "pipe", encoding: "utf-8" });
|
|
72
72
|
const match = result.match(/\d+\.\d+\.\d+/);
|
|
73
73
|
return match ? match[0] : result.trim();
|
|
74
74
|
} catch {
|
|
@@ -115,50 +115,28 @@ function hasProviderConfig(provider) {
|
|
|
115
115
|
if (!config.configDir) {
|
|
116
116
|
return false;
|
|
117
117
|
}
|
|
118
|
-
return
|
|
118
|
+
return import_node_fs2.default.existsSync(config.configDir);
|
|
119
119
|
}
|
|
120
120
|
function getProviderBranding(provider) {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
if (provider === "cursor") {
|
|
130
|
-
return {
|
|
131
|
-
commitFooter: `\u{1F916} Generated with [p/](https://www.prjct.app/)
|
|
132
|
-
Built with [Cursor](${config.websiteUrl})`,
|
|
133
|
-
signature: "\u26A1 prjct + Cursor"
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
if (provider === "antigravity") {
|
|
137
|
-
return {
|
|
138
|
-
commitFooter: `\u{1F916} Generated with [p/](https://www.prjct.app/)
|
|
139
|
-
Powered by [Antigravity](${config.websiteUrl})`,
|
|
140
|
-
signature: "\u26A1 prjct + Antigravity"
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
if (provider === "windsurf") {
|
|
144
|
-
return {
|
|
145
|
-
commitFooter: `\u{1F916} Generated with [p/](https://www.prjct.app/)
|
|
146
|
-
Built with [Windsurf](${config.websiteUrl})`,
|
|
147
|
-
signature: "\u26A1 prjct + Windsurf"
|
|
148
|
-
};
|
|
149
|
-
}
|
|
121
|
+
const commitFooter = `Generated with [p/](https://www.prjct.app/)`;
|
|
122
|
+
const signatures = {
|
|
123
|
+
claude: "\u26A1 prjct + Claude",
|
|
124
|
+
gemini: "\u26A1 prjct + Gemini",
|
|
125
|
+
cursor: "\u26A1 prjct + Cursor",
|
|
126
|
+
antigravity: "\u26A1 prjct + Antigravity",
|
|
127
|
+
windsurf: "\u26A1 prjct + Windsurf"
|
|
128
|
+
};
|
|
150
129
|
return {
|
|
151
|
-
commitFooter
|
|
152
|
-
|
|
153
|
-
signature: "\u26A1 prjct + Claude"
|
|
130
|
+
commitFooter,
|
|
131
|
+
signature: signatures[provider] || "\u26A1 prjct"
|
|
154
132
|
};
|
|
155
133
|
}
|
|
156
134
|
function detectCursorProject(projectRoot) {
|
|
157
|
-
const cursorDir =
|
|
158
|
-
const rulesDir =
|
|
159
|
-
const routerPath =
|
|
160
|
-
const detected =
|
|
161
|
-
const routerInstalled =
|
|
135
|
+
const cursorDir = import_node_path2.default.join(projectRoot, ".cursor");
|
|
136
|
+
const rulesDir = import_node_path2.default.join(cursorDir, "rules");
|
|
137
|
+
const routerPath = import_node_path2.default.join(rulesDir, "prjct.mdc");
|
|
138
|
+
const detected = import_node_fs2.default.existsSync(cursorDir);
|
|
139
|
+
const routerInstalled = import_node_fs2.default.existsSync(routerPath);
|
|
162
140
|
return {
|
|
163
141
|
detected,
|
|
164
142
|
routerInstalled,
|
|
@@ -170,11 +148,11 @@ function needsCursorRouterRegeneration(projectRoot) {
|
|
|
170
148
|
return detection.detected && !detection.routerInstalled;
|
|
171
149
|
}
|
|
172
150
|
function detectWindsurfProject(projectRoot) {
|
|
173
|
-
const windsurfDir =
|
|
174
|
-
const rulesDir =
|
|
175
|
-
const routerPath =
|
|
176
|
-
const detected =
|
|
177
|
-
const routerInstalled =
|
|
151
|
+
const windsurfDir = import_node_path2.default.join(projectRoot, ".windsurf");
|
|
152
|
+
const rulesDir = import_node_path2.default.join(windsurfDir, "rules");
|
|
153
|
+
const routerPath = import_node_path2.default.join(rulesDir, "prjct.md");
|
|
154
|
+
const detected = import_node_fs2.default.existsSync(windsurfDir);
|
|
155
|
+
const routerInstalled = import_node_fs2.default.existsSync(routerPath);
|
|
178
156
|
return {
|
|
179
157
|
detected,
|
|
180
158
|
routerInstalled,
|
|
@@ -190,9 +168,9 @@ function detectAntigravity() {
|
|
|
190
168
|
if (!configPath) {
|
|
191
169
|
return { installed: false, skillInstalled: false };
|
|
192
170
|
}
|
|
193
|
-
const installed =
|
|
194
|
-
const skillPath =
|
|
195
|
-
const skillInstalled =
|
|
171
|
+
const installed = import_node_fs2.default.existsSync(configPath);
|
|
172
|
+
const skillPath = import_node_path2.default.join(configPath, "skills", "prjct", "SKILL.md");
|
|
173
|
+
const skillInstalled = import_node_fs2.default.existsSync(skillPath);
|
|
196
174
|
return {
|
|
197
175
|
installed,
|
|
198
176
|
skillInstalled,
|
|
@@ -204,14 +182,14 @@ function getGlobalContextPath(provider) {
|
|
|
204
182
|
if (!config.configDir) {
|
|
205
183
|
return null;
|
|
206
184
|
}
|
|
207
|
-
return
|
|
185
|
+
return import_node_path2.default.join(config.configDir, config.contextFile);
|
|
208
186
|
}
|
|
209
187
|
function getGlobalSettingsPath(provider) {
|
|
210
188
|
const config = Providers[provider];
|
|
211
189
|
if (!config.configDir || !config.settingsFile) {
|
|
212
190
|
return null;
|
|
213
191
|
}
|
|
214
|
-
return
|
|
192
|
+
return import_node_path2.default.join(config.configDir, config.settingsFile);
|
|
215
193
|
}
|
|
216
194
|
function getSkillsPath(provider) {
|
|
217
195
|
return Providers[provider].skillsDir;
|
|
@@ -221,7 +199,7 @@ function getCommandsDir(provider) {
|
|
|
221
199
|
}
|
|
222
200
|
function getProjectCommandsPath(provider, projectRoot) {
|
|
223
201
|
const config = Providers[provider];
|
|
224
|
-
return
|
|
202
|
+
return import_node_path2.default.join(projectRoot, config.commandsDir);
|
|
225
203
|
}
|
|
226
204
|
function selectProvider() {
|
|
227
205
|
const detection = detectAllProviders();
|
|
@@ -255,21 +233,21 @@ function selectProvider() {
|
|
|
255
233
|
detection
|
|
256
234
|
};
|
|
257
235
|
}
|
|
258
|
-
var
|
|
236
|
+
var import_node_child_process, import_node_fs2, import_node_os, import_node_path2, ClaudeProvider, GeminiProvider, AntigravityProvider, CursorProvider, WindsurfProvider, Providers, ai_provider_default;
|
|
259
237
|
var init_ai_provider = __esm({
|
|
260
238
|
"core/infrastructure/ai-provider.ts"() {
|
|
261
239
|
"use strict";
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
240
|
+
import_node_child_process = require("node:child_process");
|
|
241
|
+
import_node_fs2 = __toESM(require("node:fs"));
|
|
242
|
+
import_node_os = __toESM(require("node:os"));
|
|
243
|
+
import_node_path2 = __toESM(require("node:path"));
|
|
266
244
|
ClaudeProvider = {
|
|
267
245
|
name: "claude",
|
|
268
246
|
displayName: "Claude Code",
|
|
269
247
|
cliCommand: "claude",
|
|
270
|
-
configDir:
|
|
248
|
+
configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".claude"),
|
|
271
249
|
contextFile: "CLAUDE.md",
|
|
272
|
-
skillsDir:
|
|
250
|
+
skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".claude", "skills"),
|
|
273
251
|
commandsDir: ".claude/commands",
|
|
274
252
|
commandFormat: "md",
|
|
275
253
|
settingsFile: "settings.json",
|
|
@@ -282,9 +260,9 @@ var init_ai_provider = __esm({
|
|
|
282
260
|
name: "gemini",
|
|
283
261
|
displayName: "Gemini CLI",
|
|
284
262
|
cliCommand: "gemini",
|
|
285
|
-
configDir:
|
|
263
|
+
configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini"),
|
|
286
264
|
contextFile: "GEMINI.md",
|
|
287
|
-
skillsDir:
|
|
265
|
+
skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "skills"),
|
|
288
266
|
commandsDir: ".gemini/commands",
|
|
289
267
|
commandFormat: "toml",
|
|
290
268
|
settingsFile: "settings.json",
|
|
@@ -298,9 +276,9 @@ var init_ai_provider = __esm({
|
|
|
298
276
|
displayName: "Google Antigravity",
|
|
299
277
|
cliCommand: null,
|
|
300
278
|
// Not a CLI command, but a platform/app
|
|
301
|
-
configDir:
|
|
279
|
+
configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "antigravity"),
|
|
302
280
|
contextFile: "ANTIGRAVITY.md",
|
|
303
|
-
skillsDir:
|
|
281
|
+
skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "antigravity", "global_skills"),
|
|
304
282
|
commandsDir: ".agent/skills",
|
|
305
283
|
// Antigravity uses .agent/skills in projects
|
|
306
284
|
commandFormat: "md",
|
|
@@ -426,19 +404,20 @@ __export(setup_exports, {
|
|
|
426
404
|
run: () => run
|
|
427
405
|
});
|
|
428
406
|
module.exports = __toCommonJS(setup_exports);
|
|
429
|
-
var
|
|
430
|
-
var
|
|
431
|
-
var
|
|
432
|
-
var
|
|
407
|
+
var import_node_child_process2 = require("node:child_process");
|
|
408
|
+
var import_node_fs3 = __toESM(require("node:fs"));
|
|
409
|
+
var import_node_os4 = __toESM(require("node:os"));
|
|
410
|
+
var import_node_path5 = __toESM(require("node:path"));
|
|
433
411
|
|
|
434
|
-
// core/
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
412
|
+
// core/types/fs.ts
|
|
413
|
+
function isNotFoundError(error) {
|
|
414
|
+
return error?.code === "ENOENT";
|
|
415
|
+
}
|
|
416
|
+
__name(isNotFoundError, "isNotFoundError");
|
|
438
417
|
|
|
439
418
|
// core/utils/version.ts
|
|
440
|
-
var
|
|
441
|
-
var
|
|
419
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
420
|
+
var import_node_path = __toESM(require("node:path"));
|
|
442
421
|
var cachedVersion = null;
|
|
443
422
|
var cachedPackageJson = null;
|
|
444
423
|
var cachedPackageRoot = null;
|
|
@@ -448,10 +427,10 @@ function getPackageRoot() {
|
|
|
448
427
|
}
|
|
449
428
|
let currentDir = __dirname;
|
|
450
429
|
for (let i = 0; i < 5; i++) {
|
|
451
|
-
const packageJsonPath =
|
|
452
|
-
if (
|
|
430
|
+
const packageJsonPath = import_node_path.default.join(currentDir, "package.json");
|
|
431
|
+
if (import_node_fs.default.existsSync(packageJsonPath)) {
|
|
453
432
|
try {
|
|
454
|
-
const pkg = JSON.parse(
|
|
433
|
+
const pkg = JSON.parse(import_node_fs.default.readFileSync(packageJsonPath, "utf-8"));
|
|
455
434
|
if (pkg.name === "prjct-cli") {
|
|
456
435
|
cachedPackageRoot = currentDir;
|
|
457
436
|
return currentDir;
|
|
@@ -459,9 +438,9 @@ function getPackageRoot() {
|
|
|
459
438
|
} catch (_error) {
|
|
460
439
|
}
|
|
461
440
|
}
|
|
462
|
-
currentDir =
|
|
441
|
+
currentDir = import_node_path.default.dirname(currentDir);
|
|
463
442
|
}
|
|
464
|
-
cachedPackageRoot =
|
|
443
|
+
cachedPackageRoot = import_node_path.default.join(__dirname, "..", "..", "..");
|
|
465
444
|
return cachedPackageRoot;
|
|
466
445
|
}
|
|
467
446
|
__name(getPackageRoot, "getPackageRoot");
|
|
@@ -470,8 +449,8 @@ function getVersion() {
|
|
|
470
449
|
return cachedVersion;
|
|
471
450
|
}
|
|
472
451
|
try {
|
|
473
|
-
const packageJsonPath =
|
|
474
|
-
const packageJson = JSON.parse(
|
|
452
|
+
const packageJsonPath = import_node_path.default.join(getPackageRoot(), "package.json");
|
|
453
|
+
const packageJson = JSON.parse(import_node_fs.default.readFileSync(packageJsonPath, "utf-8"));
|
|
475
454
|
cachedVersion = packageJson.version;
|
|
476
455
|
cachedPackageJson = packageJson;
|
|
477
456
|
return cachedVersion;
|
|
@@ -484,23 +463,23 @@ __name(getVersion, "getVersion");
|
|
|
484
463
|
var VERSION = getVersion();
|
|
485
464
|
var PACKAGE_ROOT = getPackageRoot();
|
|
486
465
|
|
|
487
|
-
// core/
|
|
488
|
-
|
|
489
|
-
return error?.code === "ENOENT";
|
|
490
|
-
}
|
|
491
|
-
__name(isNotFoundError, "isNotFoundError");
|
|
466
|
+
// core/infrastructure/setup.ts
|
|
467
|
+
init_ai_provider();
|
|
492
468
|
|
|
493
469
|
// core/infrastructure/command-installer.ts
|
|
470
|
+
var import_promises = __toESM(require("node:fs/promises"));
|
|
471
|
+
var import_node_os2 = __toESM(require("node:os"));
|
|
472
|
+
var import_node_path3 = __toESM(require("node:path"));
|
|
494
473
|
async function installDocs() {
|
|
495
474
|
try {
|
|
496
|
-
const docsDir =
|
|
497
|
-
const templateDocsDir =
|
|
475
|
+
const docsDir = import_node_path3.default.join(import_node_os2.default.homedir(), ".prjct-cli", "docs");
|
|
476
|
+
const templateDocsDir = import_node_path3.default.join(getPackageRoot(), "templates/global/docs");
|
|
498
477
|
await import_promises.default.mkdir(docsDir, { recursive: true });
|
|
499
478
|
const docFiles = await import_promises.default.readdir(templateDocsDir);
|
|
500
479
|
for (const file of docFiles) {
|
|
501
480
|
if (file.endsWith(".md")) {
|
|
502
|
-
const srcPath =
|
|
503
|
-
const destPath =
|
|
481
|
+
const srcPath = import_node_path3.default.join(templateDocsDir, file);
|
|
482
|
+
const destPath = import_node_path3.default.join(docsDir, file);
|
|
504
483
|
const content = await import_promises.default.readFile(srcPath, "utf-8");
|
|
505
484
|
await import_promises.default.writeFile(destPath, content, "utf-8");
|
|
506
485
|
}
|
|
@@ -525,13 +504,18 @@ async function installGlobalConfig() {
|
|
|
525
504
|
}
|
|
526
505
|
try {
|
|
527
506
|
await import_promises.default.mkdir(activeProvider.configDir, { recursive: true });
|
|
528
|
-
const globalConfigPath =
|
|
529
|
-
const templatePath =
|
|
507
|
+
const globalConfigPath = import_node_path3.default.join(activeProvider.configDir, activeProvider.contextFile);
|
|
508
|
+
const templatePath = import_node_path3.default.join(
|
|
509
|
+
getPackageRoot(),
|
|
510
|
+
"templates",
|
|
511
|
+
"global",
|
|
512
|
+
activeProvider.contextFile
|
|
513
|
+
);
|
|
530
514
|
let templateContent = "";
|
|
531
515
|
try {
|
|
532
516
|
templateContent = await import_promises.default.readFile(templatePath, "utf-8");
|
|
533
|
-
} catch (
|
|
534
|
-
const fallbackTemplatePath =
|
|
517
|
+
} catch (_error) {
|
|
518
|
+
const fallbackTemplatePath = import_node_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
535
519
|
templateContent = await import_promises.default.readFile(fallbackTemplatePath, "utf-8");
|
|
536
520
|
if (providerName === "gemini") {
|
|
537
521
|
templateContent = templateContent.replace(/Claude/g, "Gemini");
|
|
@@ -561,7 +545,9 @@ async function installGlobalConfig() {
|
|
|
561
545
|
const endMarker = "<!-- prjct:end - DO NOT REMOVE THIS MARKER -->";
|
|
562
546
|
const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
|
|
563
547
|
if (!hasMarkers) {
|
|
564
|
-
const updatedContent = existingContent
|
|
548
|
+
const updatedContent = `${existingContent}
|
|
549
|
+
|
|
550
|
+
${templateContent}`;
|
|
565
551
|
await import_promises.default.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
566
552
|
return {
|
|
567
553
|
success: true,
|
|
@@ -604,16 +590,16 @@ var CommandInstaller = class {
|
|
|
604
590
|
claudeConfigPath;
|
|
605
591
|
templatesDir;
|
|
606
592
|
constructor() {
|
|
607
|
-
this.homeDir =
|
|
593
|
+
this.homeDir = import_node_os2.default.homedir();
|
|
608
594
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
609
595
|
const activeProvider = aiProvider.getActiveProvider();
|
|
610
596
|
if (activeProvider.name === "gemini") {
|
|
611
|
-
this.claudeCommandsPath =
|
|
597
|
+
this.claudeCommandsPath = import_node_path3.default.join(activeProvider.configDir, "commands");
|
|
612
598
|
} else {
|
|
613
|
-
this.claudeCommandsPath =
|
|
599
|
+
this.claudeCommandsPath = import_node_path3.default.join(activeProvider.configDir, "commands", "p");
|
|
614
600
|
}
|
|
615
601
|
this.claudeConfigPath = activeProvider.configDir;
|
|
616
|
-
this.templatesDir =
|
|
602
|
+
this.templatesDir = import_node_path3.default.join(getPackageRoot(), "templates", "commands");
|
|
617
603
|
}
|
|
618
604
|
/**
|
|
619
605
|
* Detect if active provider is installed
|
|
@@ -642,7 +628,7 @@ var CommandInstaller = class {
|
|
|
642
628
|
try {
|
|
643
629
|
const files = await import_promises.default.readdir(this.templatesDir);
|
|
644
630
|
return files.filter((f) => f.endsWith(".md"));
|
|
645
|
-
} catch (
|
|
631
|
+
} catch (_error) {
|
|
646
632
|
return [
|
|
647
633
|
"init.md",
|
|
648
634
|
"now.md",
|
|
@@ -687,8 +673,8 @@ var CommandInstaller = class {
|
|
|
687
673
|
const errors = [];
|
|
688
674
|
for (const file of commandFiles) {
|
|
689
675
|
try {
|
|
690
|
-
const sourcePath =
|
|
691
|
-
const destPath =
|
|
676
|
+
const sourcePath = import_node_path3.default.join(this.templatesDir, file);
|
|
677
|
+
const destPath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
692
678
|
const content = await import_promises.default.readFile(sourcePath, "utf-8");
|
|
693
679
|
await import_promises.default.writeFile(destPath, content, "utf-8");
|
|
694
680
|
installed.push(file.replace(".md", ""));
|
|
@@ -719,7 +705,7 @@ var CommandInstaller = class {
|
|
|
719
705
|
const errors = [];
|
|
720
706
|
for (const file of commandFiles) {
|
|
721
707
|
try {
|
|
722
|
-
const filePath =
|
|
708
|
+
const filePath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
723
709
|
await import_promises.default.unlink(filePath);
|
|
724
710
|
uninstalled.push(file.replace(".md", ""));
|
|
725
711
|
} catch (error) {
|
|
@@ -730,7 +716,7 @@ var CommandInstaller = class {
|
|
|
730
716
|
}
|
|
731
717
|
try {
|
|
732
718
|
await import_promises.default.rmdir(this.claudeCommandsPath);
|
|
733
|
-
} catch (
|
|
719
|
+
} catch (_error) {
|
|
734
720
|
}
|
|
735
721
|
return {
|
|
736
722
|
success: true,
|
|
@@ -804,7 +790,7 @@ var CommandInstaller = class {
|
|
|
804
790
|
*/
|
|
805
791
|
async verifyTemplate(commandName) {
|
|
806
792
|
try {
|
|
807
|
-
const templatePath =
|
|
793
|
+
const templatePath = import_node_path3.default.join(this.templatesDir, `${commandName}.md`);
|
|
808
794
|
await import_promises.default.access(templatePath);
|
|
809
795
|
return true;
|
|
810
796
|
} catch (error) {
|
|
@@ -823,9 +809,9 @@ var CommandInstaller = class {
|
|
|
823
809
|
const activeProvider = aiProvider.getActiveProvider();
|
|
824
810
|
const routerFile = activeProvider.name === "gemini" ? "p.toml" : "p.md";
|
|
825
811
|
try {
|
|
826
|
-
const routerSource =
|
|
827
|
-
const routerDest =
|
|
828
|
-
await import_promises.default.mkdir(
|
|
812
|
+
const routerSource = import_node_path3.default.join(this.templatesDir, routerFile);
|
|
813
|
+
const routerDest = import_node_path3.default.join(activeProvider.configDir, "commands", routerFile);
|
|
814
|
+
await import_promises.default.mkdir(import_node_path3.default.dirname(routerDest), { recursive: true });
|
|
829
815
|
const content = await import_promises.default.readFile(routerSource, "utf-8");
|
|
830
816
|
await import_promises.default.writeFile(routerDest, content, "utf-8");
|
|
831
817
|
return true;
|
|
@@ -874,8 +860,8 @@ var CommandInstaller = class {
|
|
|
874
860
|
};
|
|
875
861
|
for (const file of templateFiles) {
|
|
876
862
|
try {
|
|
877
|
-
const sourcePath =
|
|
878
|
-
const destPath =
|
|
863
|
+
const sourcePath = import_node_path3.default.join(this.templatesDir, file);
|
|
864
|
+
const destPath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
879
865
|
const exists = installedFiles.includes(file);
|
|
880
866
|
const content = await import_promises.default.readFile(sourcePath, "utf-8");
|
|
881
867
|
await import_promises.default.writeFile(destPath, content, "utf-8");
|
|
@@ -916,9 +902,9 @@ var commandInstaller = new CommandInstaller();
|
|
|
916
902
|
var command_installer_default = commandInstaller;
|
|
917
903
|
|
|
918
904
|
// core/infrastructure/editors-config.ts
|
|
919
|
-
var import_promises2 = __toESM(require("fs/promises"));
|
|
920
|
-
var
|
|
921
|
-
var
|
|
905
|
+
var import_promises2 = __toESM(require("node:fs/promises"));
|
|
906
|
+
var import_node_os3 = __toESM(require("node:os"));
|
|
907
|
+
var import_node_path4 = __toESM(require("node:path"));
|
|
922
908
|
var EditorsConfig = class {
|
|
923
909
|
static {
|
|
924
910
|
__name(this, "EditorsConfig");
|
|
@@ -927,9 +913,9 @@ var EditorsConfig = class {
|
|
|
927
913
|
configDir;
|
|
928
914
|
configFile;
|
|
929
915
|
constructor() {
|
|
930
|
-
this.homeDir =
|
|
931
|
-
this.configDir =
|
|
932
|
-
this.configFile =
|
|
916
|
+
this.homeDir = import_node_os3.default.homedir();
|
|
917
|
+
this.configDir = import_node_path4.default.join(this.homeDir, ".prjct-cli", "config");
|
|
918
|
+
this.configFile = import_node_path4.default.join(this.configDir, "installed-editors.json");
|
|
933
919
|
}
|
|
934
920
|
/**
|
|
935
921
|
* Ensure config directory exists
|
|
@@ -1049,7 +1035,6 @@ var editorsConfig = new EditorsConfig();
|
|
|
1049
1035
|
var editors_config_default = editorsConfig;
|
|
1050
1036
|
|
|
1051
1037
|
// core/infrastructure/setup.ts
|
|
1052
|
-
init_ai_provider();
|
|
1053
1038
|
var GREEN = "\x1B[32m";
|
|
1054
1039
|
var YELLOW = "\x1B[33m";
|
|
1055
1040
|
var DIM = "\x1B[2m";
|
|
@@ -1059,13 +1044,15 @@ async function installAICLI(provider) {
|
|
|
1059
1044
|
try {
|
|
1060
1045
|
console.log(`${YELLOW}\u{1F4E6} ${provider.displayName} not found. Installing...${NC}`);
|
|
1061
1046
|
console.log("");
|
|
1062
|
-
(0,
|
|
1047
|
+
(0, import_node_child_process2.execSync)(`npm install -g ${packageName}`, { stdio: "inherit" });
|
|
1063
1048
|
console.log("");
|
|
1064
1049
|
console.log(`${GREEN}\u2713${NC} ${provider.displayName} installed successfully`);
|
|
1065
1050
|
console.log("");
|
|
1066
1051
|
return true;
|
|
1067
1052
|
} catch (error) {
|
|
1068
|
-
console.log(
|
|
1053
|
+
console.log(
|
|
1054
|
+
`${YELLOW}\u26A0\uFE0F Failed to install ${provider.displayName}: ${error.message}${NC}`
|
|
1055
|
+
);
|
|
1069
1056
|
console.log(`${DIM}Please install manually: npm install -g ${packageName}${NC}`);
|
|
1070
1057
|
console.log("");
|
|
1071
1058
|
return false;
|
|
@@ -1075,7 +1062,7 @@ __name(installAICLI, "installAICLI");
|
|
|
1075
1062
|
async function run() {
|
|
1076
1063
|
const detection = detectAllProviders();
|
|
1077
1064
|
const selection = selectProvider();
|
|
1078
|
-
const
|
|
1065
|
+
const _primaryProvider = Providers[selection.provider];
|
|
1079
1066
|
const results = {
|
|
1080
1067
|
provider: selection.provider,
|
|
1081
1068
|
providers: [],
|
|
@@ -1159,12 +1146,12 @@ __name(run, "run");
|
|
|
1159
1146
|
var setup_default = { run };
|
|
1160
1147
|
async function installGeminiRouter() {
|
|
1161
1148
|
try {
|
|
1162
|
-
const geminiCommandsDir =
|
|
1163
|
-
const routerSource =
|
|
1164
|
-
const routerDest =
|
|
1165
|
-
|
|
1166
|
-
if (
|
|
1167
|
-
|
|
1149
|
+
const geminiCommandsDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".gemini", "commands");
|
|
1150
|
+
const routerSource = import_node_path5.default.join(getPackageRoot(), "templates", "commands", "p.toml");
|
|
1151
|
+
const routerDest = import_node_path5.default.join(geminiCommandsDir, "p.toml");
|
|
1152
|
+
import_node_fs3.default.mkdirSync(geminiCommandsDir, { recursive: true });
|
|
1153
|
+
if (import_node_fs3.default.existsSync(routerSource)) {
|
|
1154
|
+
import_node_fs3.default.copyFileSync(routerSource, routerDest);
|
|
1168
1155
|
return true;
|
|
1169
1156
|
}
|
|
1170
1157
|
return false;
|
|
@@ -1176,15 +1163,15 @@ async function installGeminiRouter() {
|
|
|
1176
1163
|
__name(installGeminiRouter, "installGeminiRouter");
|
|
1177
1164
|
async function installGeminiGlobalConfig() {
|
|
1178
1165
|
try {
|
|
1179
|
-
const geminiDir =
|
|
1180
|
-
const globalConfigPath =
|
|
1181
|
-
const templatePath =
|
|
1182
|
-
|
|
1183
|
-
const templateContent =
|
|
1166
|
+
const geminiDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".gemini");
|
|
1167
|
+
const globalConfigPath = import_node_path5.default.join(geminiDir, "GEMINI.md");
|
|
1168
|
+
const templatePath = import_node_path5.default.join(getPackageRoot(), "templates", "global", "GEMINI.md");
|
|
1169
|
+
import_node_fs3.default.mkdirSync(geminiDir, { recursive: true });
|
|
1170
|
+
const templateContent = import_node_fs3.default.readFileSync(templatePath, "utf-8");
|
|
1184
1171
|
let existingContent = "";
|
|
1185
1172
|
let fileExists = false;
|
|
1186
1173
|
try {
|
|
1187
|
-
existingContent =
|
|
1174
|
+
existingContent = import_node_fs3.default.readFileSync(globalConfigPath, "utf-8");
|
|
1188
1175
|
fileExists = true;
|
|
1189
1176
|
} catch (error) {
|
|
1190
1177
|
if (isNotFoundError(error)) {
|
|
@@ -1194,15 +1181,17 @@ async function installGeminiGlobalConfig() {
|
|
|
1194
1181
|
}
|
|
1195
1182
|
}
|
|
1196
1183
|
if (!fileExists) {
|
|
1197
|
-
|
|
1184
|
+
import_node_fs3.default.writeFileSync(globalConfigPath, templateContent, "utf-8");
|
|
1198
1185
|
return { success: true, action: "created" };
|
|
1199
1186
|
}
|
|
1200
1187
|
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
1201
1188
|
const endMarker = "<!-- prjct:end - DO NOT REMOVE THIS MARKER -->";
|
|
1202
1189
|
const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
|
|
1203
1190
|
if (!hasMarkers) {
|
|
1204
|
-
const updatedContent2 = existingContent
|
|
1205
|
-
|
|
1191
|
+
const updatedContent2 = `${existingContent}
|
|
1192
|
+
|
|
1193
|
+
${templateContent}`;
|
|
1194
|
+
import_node_fs3.default.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
|
|
1206
1195
|
return { success: true, action: "appended" };
|
|
1207
1196
|
}
|
|
1208
1197
|
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
|
|
@@ -1214,7 +1203,7 @@ async function installGeminiGlobalConfig() {
|
|
|
1214
1203
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
1215
1204
|
);
|
|
1216
1205
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
1217
|
-
|
|
1206
|
+
import_node_fs3.default.writeFileSync(globalConfigPath, updatedContent, "utf-8");
|
|
1218
1207
|
return { success: true, action: "updated" };
|
|
1219
1208
|
} catch (error) {
|
|
1220
1209
|
console.error(`Gemini config warning: ${error.message}`);
|
|
@@ -1224,18 +1213,18 @@ async function installGeminiGlobalConfig() {
|
|
|
1224
1213
|
__name(installGeminiGlobalConfig, "installGeminiGlobalConfig");
|
|
1225
1214
|
async function installAntigravitySkill() {
|
|
1226
1215
|
try {
|
|
1227
|
-
const antigravitySkillsDir =
|
|
1228
|
-
const prjctSkillDir =
|
|
1229
|
-
const skillMdPath =
|
|
1230
|
-
const templatePath =
|
|
1231
|
-
|
|
1232
|
-
const fileExists =
|
|
1233
|
-
if (!
|
|
1216
|
+
const antigravitySkillsDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".gemini", "antigravity", "skills");
|
|
1217
|
+
const prjctSkillDir = import_node_path5.default.join(antigravitySkillsDir, "prjct");
|
|
1218
|
+
const skillMdPath = import_node_path5.default.join(prjctSkillDir, "SKILL.md");
|
|
1219
|
+
const templatePath = import_node_path5.default.join(getPackageRoot(), "templates", "antigravity", "SKILL.md");
|
|
1220
|
+
import_node_fs3.default.mkdirSync(prjctSkillDir, { recursive: true });
|
|
1221
|
+
const fileExists = import_node_fs3.default.existsSync(skillMdPath);
|
|
1222
|
+
if (!import_node_fs3.default.existsSync(templatePath)) {
|
|
1234
1223
|
console.error("Antigravity SKILL.md template not found");
|
|
1235
1224
|
return { success: false, action: null };
|
|
1236
1225
|
}
|
|
1237
|
-
const templateContent =
|
|
1238
|
-
|
|
1226
|
+
const templateContent = import_node_fs3.default.readFileSync(templatePath, "utf-8");
|
|
1227
|
+
import_node_fs3.default.writeFileSync(skillMdPath, templateContent, "utf-8");
|
|
1239
1228
|
return { success: true, action: fileExists ? "updated" : "created" };
|
|
1240
1229
|
} catch (error) {
|
|
1241
1230
|
console.error(`Antigravity skill warning: ${error.message}`);
|
|
@@ -1256,24 +1245,24 @@ async function installCursorProject(projectRoot) {
|
|
|
1256
1245
|
gitignoreUpdated: false
|
|
1257
1246
|
};
|
|
1258
1247
|
try {
|
|
1259
|
-
const cursorDir =
|
|
1260
|
-
const rulesDir =
|
|
1261
|
-
const commandsDir =
|
|
1262
|
-
const routerMdcDest =
|
|
1263
|
-
const routerMdcSource =
|
|
1264
|
-
const cursorCommandsSource =
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1248
|
+
const cursorDir = import_node_path5.default.join(projectRoot, ".cursor");
|
|
1249
|
+
const rulesDir = import_node_path5.default.join(cursorDir, "rules");
|
|
1250
|
+
const commandsDir = import_node_path5.default.join(cursorDir, "commands");
|
|
1251
|
+
const routerMdcDest = import_node_path5.default.join(rulesDir, "prjct.mdc");
|
|
1252
|
+
const routerMdcSource = import_node_path5.default.join(getPackageRoot(), "templates", "cursor", "router.mdc");
|
|
1253
|
+
const cursorCommandsSource = import_node_path5.default.join(getPackageRoot(), "templates", "cursor", "commands");
|
|
1254
|
+
import_node_fs3.default.mkdirSync(rulesDir, { recursive: true });
|
|
1255
|
+
import_node_fs3.default.mkdirSync(commandsDir, { recursive: true });
|
|
1256
|
+
if (import_node_fs3.default.existsSync(routerMdcSource)) {
|
|
1257
|
+
import_node_fs3.default.copyFileSync(routerMdcSource, routerMdcDest);
|
|
1269
1258
|
result.rulesCreated = true;
|
|
1270
1259
|
}
|
|
1271
|
-
if (
|
|
1272
|
-
const commandFiles =
|
|
1260
|
+
if (import_node_fs3.default.existsSync(cursorCommandsSource)) {
|
|
1261
|
+
const commandFiles = import_node_fs3.default.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
|
|
1273
1262
|
for (const file of commandFiles) {
|
|
1274
|
-
const src =
|
|
1275
|
-
const dest =
|
|
1276
|
-
|
|
1263
|
+
const src = import_node_path5.default.join(cursorCommandsSource, file);
|
|
1264
|
+
const dest = import_node_path5.default.join(commandsDir, file);
|
|
1265
|
+
import_node_fs3.default.copyFileSync(src, dest);
|
|
1277
1266
|
}
|
|
1278
1267
|
result.commandsCreated = commandFiles.length > 0;
|
|
1279
1268
|
}
|
|
@@ -1288,7 +1277,7 @@ async function installCursorProject(projectRoot) {
|
|
|
1288
1277
|
__name(installCursorProject, "installCursorProject");
|
|
1289
1278
|
async function addCursorToGitignore(projectRoot) {
|
|
1290
1279
|
try {
|
|
1291
|
-
const gitignorePath =
|
|
1280
|
+
const gitignorePath = import_node_path5.default.join(projectRoot, ".gitignore");
|
|
1292
1281
|
const entriesToAdd = [
|
|
1293
1282
|
"# prjct Cursor routers (regenerated per-developer)",
|
|
1294
1283
|
".cursor/rules/prjct.mdc",
|
|
@@ -1303,7 +1292,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
1303
1292
|
let content = "";
|
|
1304
1293
|
let fileExists = false;
|
|
1305
1294
|
try {
|
|
1306
|
-
content =
|
|
1295
|
+
content = import_node_fs3.default.readFileSync(gitignorePath, "utf-8");
|
|
1307
1296
|
fileExists = true;
|
|
1308
1297
|
} catch (error) {
|
|
1309
1298
|
if (!isNotFoundError(error)) {
|
|
@@ -1313,8 +1302,12 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
1313
1302
|
if (content.includes(".cursor/rules/prjct.mdc")) {
|
|
1314
1303
|
return false;
|
|
1315
1304
|
}
|
|
1316
|
-
const newContent = fileExists ? content.trimEnd()
|
|
1317
|
-
|
|
1305
|
+
const newContent = fileExists ? `${content.trimEnd()}
|
|
1306
|
+
|
|
1307
|
+
${entriesToAdd.join("\n")}
|
|
1308
|
+
` : `${entriesToAdd.join("\n")}
|
|
1309
|
+
`;
|
|
1310
|
+
import_node_fs3.default.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
1318
1311
|
return true;
|
|
1319
1312
|
} catch (error) {
|
|
1320
1313
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -1323,13 +1316,13 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
1323
1316
|
}
|
|
1324
1317
|
__name(addCursorToGitignore, "addCursorToGitignore");
|
|
1325
1318
|
function hasCursorProject(projectRoot) {
|
|
1326
|
-
return
|
|
1319
|
+
return import_node_fs3.default.existsSync(import_node_path5.default.join(projectRoot, ".cursor"));
|
|
1327
1320
|
}
|
|
1328
1321
|
__name(hasCursorProject, "hasCursorProject");
|
|
1329
1322
|
function needsCursorRegeneration(projectRoot) {
|
|
1330
|
-
const cursorDir =
|
|
1331
|
-
const routerPath =
|
|
1332
|
-
return
|
|
1323
|
+
const cursorDir = import_node_path5.default.join(projectRoot, ".cursor");
|
|
1324
|
+
const routerPath = import_node_path5.default.join(cursorDir, "rules", "prjct.mdc");
|
|
1325
|
+
return import_node_fs3.default.existsSync(cursorDir) && !import_node_fs3.default.existsSync(routerPath);
|
|
1333
1326
|
}
|
|
1334
1327
|
__name(needsCursorRegeneration, "needsCursorRegeneration");
|
|
1335
1328
|
async function installWindsurfProject(projectRoot) {
|
|
@@ -1340,24 +1333,29 @@ async function installWindsurfProject(projectRoot) {
|
|
|
1340
1333
|
gitignoreUpdated: false
|
|
1341
1334
|
};
|
|
1342
1335
|
try {
|
|
1343
|
-
const windsurfDir =
|
|
1344
|
-
const rulesDir =
|
|
1345
|
-
const workflowsDir =
|
|
1346
|
-
const routerDest =
|
|
1347
|
-
const routerSource =
|
|
1348
|
-
const windsurfWorkflowsSource =
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1336
|
+
const windsurfDir = import_node_path5.default.join(projectRoot, ".windsurf");
|
|
1337
|
+
const rulesDir = import_node_path5.default.join(windsurfDir, "rules");
|
|
1338
|
+
const workflowsDir = import_node_path5.default.join(windsurfDir, "workflows");
|
|
1339
|
+
const routerDest = import_node_path5.default.join(rulesDir, "prjct.md");
|
|
1340
|
+
const routerSource = import_node_path5.default.join(getPackageRoot(), "templates", "windsurf", "router.md");
|
|
1341
|
+
const windsurfWorkflowsSource = import_node_path5.default.join(
|
|
1342
|
+
getPackageRoot(),
|
|
1343
|
+
"templates",
|
|
1344
|
+
"windsurf",
|
|
1345
|
+
"workflows"
|
|
1346
|
+
);
|
|
1347
|
+
import_node_fs3.default.mkdirSync(rulesDir, { recursive: true });
|
|
1348
|
+
import_node_fs3.default.mkdirSync(workflowsDir, { recursive: true });
|
|
1349
|
+
if (import_node_fs3.default.existsSync(routerSource)) {
|
|
1350
|
+
import_node_fs3.default.copyFileSync(routerSource, routerDest);
|
|
1353
1351
|
result.rulesCreated = true;
|
|
1354
1352
|
}
|
|
1355
|
-
if (
|
|
1356
|
-
const workflowFiles =
|
|
1353
|
+
if (import_node_fs3.default.existsSync(windsurfWorkflowsSource)) {
|
|
1354
|
+
const workflowFiles = import_node_fs3.default.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
|
|
1357
1355
|
for (const file of workflowFiles) {
|
|
1358
|
-
const src =
|
|
1359
|
-
const dest =
|
|
1360
|
-
|
|
1356
|
+
const src = import_node_path5.default.join(windsurfWorkflowsSource, file);
|
|
1357
|
+
const dest = import_node_path5.default.join(workflowsDir, file);
|
|
1358
|
+
import_node_fs3.default.copyFileSync(src, dest);
|
|
1361
1359
|
}
|
|
1362
1360
|
result.workflowsCreated = workflowFiles.length > 0;
|
|
1363
1361
|
}
|
|
@@ -1372,7 +1370,7 @@ async function installWindsurfProject(projectRoot) {
|
|
|
1372
1370
|
__name(installWindsurfProject, "installWindsurfProject");
|
|
1373
1371
|
async function addWindsurfToGitignore(projectRoot) {
|
|
1374
1372
|
try {
|
|
1375
|
-
const gitignorePath =
|
|
1373
|
+
const gitignorePath = import_node_path5.default.join(projectRoot, ".gitignore");
|
|
1376
1374
|
const entriesToAdd = [
|
|
1377
1375
|
"# prjct Windsurf routers (regenerated per-developer)",
|
|
1378
1376
|
".windsurf/rules/prjct.md",
|
|
@@ -1387,7 +1385,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
1387
1385
|
let content = "";
|
|
1388
1386
|
let fileExists = false;
|
|
1389
1387
|
try {
|
|
1390
|
-
content =
|
|
1388
|
+
content = import_node_fs3.default.readFileSync(gitignorePath, "utf-8");
|
|
1391
1389
|
fileExists = true;
|
|
1392
1390
|
} catch (error) {
|
|
1393
1391
|
if (!isNotFoundError(error)) {
|
|
@@ -1397,8 +1395,12 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
1397
1395
|
if (content.includes(".windsurf/rules/prjct.md")) {
|
|
1398
1396
|
return false;
|
|
1399
1397
|
}
|
|
1400
|
-
const newContent = fileExists ? content.trimEnd()
|
|
1401
|
-
|
|
1398
|
+
const newContent = fileExists ? `${content.trimEnd()}
|
|
1399
|
+
|
|
1400
|
+
${entriesToAdd.join("\n")}
|
|
1401
|
+
` : `${entriesToAdd.join("\n")}
|
|
1402
|
+
`;
|
|
1403
|
+
import_node_fs3.default.writeFileSync(gitignorePath, newContent, "utf-8");
|
|
1402
1404
|
return true;
|
|
1403
1405
|
} catch (error) {
|
|
1404
1406
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -1407,34 +1409,34 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
1407
1409
|
}
|
|
1408
1410
|
__name(addWindsurfToGitignore, "addWindsurfToGitignore");
|
|
1409
1411
|
function hasWindsurfProject(projectRoot) {
|
|
1410
|
-
return
|
|
1412
|
+
return import_node_fs3.default.existsSync(import_node_path5.default.join(projectRoot, ".windsurf"));
|
|
1411
1413
|
}
|
|
1412
1414
|
__name(hasWindsurfProject, "hasWindsurfProject");
|
|
1413
1415
|
function needsWindsurfRegeneration(projectRoot) {
|
|
1414
|
-
const windsurfDir =
|
|
1415
|
-
const routerPath =
|
|
1416
|
-
return
|
|
1416
|
+
const windsurfDir = import_node_path5.default.join(projectRoot, ".windsurf");
|
|
1417
|
+
const routerPath = import_node_path5.default.join(windsurfDir, "rules", "prjct.md");
|
|
1418
|
+
return import_node_fs3.default.existsSync(windsurfDir) && !import_node_fs3.default.existsSync(routerPath);
|
|
1417
1419
|
}
|
|
1418
1420
|
__name(needsWindsurfRegeneration, "needsWindsurfRegeneration");
|
|
1419
1421
|
async function migrateProjectsCliVersion() {
|
|
1420
1422
|
try {
|
|
1421
|
-
const projectsDir =
|
|
1422
|
-
if (!
|
|
1423
|
+
const projectsDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".prjct-cli", "projects");
|
|
1424
|
+
if (!import_node_fs3.default.existsSync(projectsDir)) {
|
|
1423
1425
|
return;
|
|
1424
1426
|
}
|
|
1425
|
-
const projectDirs =
|
|
1427
|
+
const projectDirs = import_node_fs3.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1426
1428
|
let migrated = 0;
|
|
1427
1429
|
for (const projectId of projectDirs) {
|
|
1428
|
-
const projectJsonPath =
|
|
1429
|
-
if (!
|
|
1430
|
+
const projectJsonPath = import_node_path5.default.join(projectsDir, projectId, "project.json");
|
|
1431
|
+
if (!import_node_fs3.default.existsSync(projectJsonPath)) {
|
|
1430
1432
|
continue;
|
|
1431
1433
|
}
|
|
1432
1434
|
try {
|
|
1433
|
-
const content =
|
|
1435
|
+
const content = import_node_fs3.default.readFileSync(projectJsonPath, "utf8");
|
|
1434
1436
|
const project = JSON.parse(content);
|
|
1435
1437
|
if (project.cliVersion !== VERSION) {
|
|
1436
1438
|
project.cliVersion = VERSION;
|
|
1437
|
-
|
|
1439
|
+
import_node_fs3.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
1438
1440
|
migrated++;
|
|
1439
1441
|
}
|
|
1440
1442
|
} catch (error) {
|
|
@@ -1455,9 +1457,9 @@ async function migrateProjectsCliVersion() {
|
|
|
1455
1457
|
__name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
|
|
1456
1458
|
function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
1457
1459
|
let settings = {};
|
|
1458
|
-
if (
|
|
1460
|
+
if (import_node_fs3.default.existsSync(settingsPath)) {
|
|
1459
1461
|
try {
|
|
1460
|
-
settings = JSON.parse(
|
|
1462
|
+
settings = JSON.parse(import_node_fs3.default.readFileSync(settingsPath, "utf8"));
|
|
1461
1463
|
} catch (error) {
|
|
1462
1464
|
if (!(error instanceof SyntaxError)) {
|
|
1463
1465
|
throw error;
|
|
@@ -1465,43 +1467,43 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
|
1465
1467
|
}
|
|
1466
1468
|
}
|
|
1467
1469
|
settings.statusLine = { type: "command", command: statusLinePath };
|
|
1468
|
-
|
|
1470
|
+
import_node_fs3.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
1469
1471
|
}
|
|
1470
1472
|
__name(ensureStatusLineSettings, "ensureStatusLineSettings");
|
|
1471
1473
|
async function installStatusLine() {
|
|
1472
1474
|
try {
|
|
1473
|
-
const claudeDir =
|
|
1474
|
-
const settingsPath =
|
|
1475
|
-
const claudeStatusLinePath =
|
|
1476
|
-
const prjctStatusLineDir =
|
|
1477
|
-
const prjctStatusLinePath =
|
|
1478
|
-
const prjctThemesDir =
|
|
1479
|
-
const prjctLibDir =
|
|
1480
|
-
const prjctComponentsDir =
|
|
1481
|
-
const prjctConfigPath =
|
|
1482
|
-
const assetsDir =
|
|
1483
|
-
const sourceScript =
|
|
1484
|
-
const sourceThemeDir =
|
|
1485
|
-
const sourceLibDir =
|
|
1486
|
-
const sourceComponentsDir =
|
|
1487
|
-
const sourceConfigPath =
|
|
1488
|
-
if (!
|
|
1489
|
-
|
|
1475
|
+
const claudeDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".claude");
|
|
1476
|
+
const settingsPath = import_node_path5.default.join(claudeDir, "settings.json");
|
|
1477
|
+
const claudeStatusLinePath = import_node_path5.default.join(claudeDir, "prjct-statusline.sh");
|
|
1478
|
+
const prjctStatusLineDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".prjct-cli", "statusline");
|
|
1479
|
+
const prjctStatusLinePath = import_node_path5.default.join(prjctStatusLineDir, "statusline.sh");
|
|
1480
|
+
const prjctThemesDir = import_node_path5.default.join(prjctStatusLineDir, "themes");
|
|
1481
|
+
const prjctLibDir = import_node_path5.default.join(prjctStatusLineDir, "lib");
|
|
1482
|
+
const prjctComponentsDir = import_node_path5.default.join(prjctStatusLineDir, "components");
|
|
1483
|
+
const prjctConfigPath = import_node_path5.default.join(prjctStatusLineDir, "config.json");
|
|
1484
|
+
const assetsDir = import_node_path5.default.join(getPackageRoot(), "assets", "statusline");
|
|
1485
|
+
const sourceScript = import_node_path5.default.join(assetsDir, "statusline.sh");
|
|
1486
|
+
const sourceThemeDir = import_node_path5.default.join(assetsDir, "themes");
|
|
1487
|
+
const sourceLibDir = import_node_path5.default.join(assetsDir, "lib");
|
|
1488
|
+
const sourceComponentsDir = import_node_path5.default.join(assetsDir, "components");
|
|
1489
|
+
const sourceConfigPath = import_node_path5.default.join(assetsDir, "default-config.json");
|
|
1490
|
+
if (!import_node_fs3.default.existsSync(claudeDir)) {
|
|
1491
|
+
import_node_fs3.default.mkdirSync(claudeDir, { recursive: true });
|
|
1490
1492
|
}
|
|
1491
|
-
if (!
|
|
1492
|
-
|
|
1493
|
+
if (!import_node_fs3.default.existsSync(prjctStatusLineDir)) {
|
|
1494
|
+
import_node_fs3.default.mkdirSync(prjctStatusLineDir, { recursive: true });
|
|
1493
1495
|
}
|
|
1494
|
-
if (!
|
|
1495
|
-
|
|
1496
|
+
if (!import_node_fs3.default.existsSync(prjctThemesDir)) {
|
|
1497
|
+
import_node_fs3.default.mkdirSync(prjctThemesDir, { recursive: true });
|
|
1496
1498
|
}
|
|
1497
|
-
if (!
|
|
1498
|
-
|
|
1499
|
+
if (!import_node_fs3.default.existsSync(prjctLibDir)) {
|
|
1500
|
+
import_node_fs3.default.mkdirSync(prjctLibDir, { recursive: true });
|
|
1499
1501
|
}
|
|
1500
|
-
if (!
|
|
1501
|
-
|
|
1502
|
+
if (!import_node_fs3.default.existsSync(prjctComponentsDir)) {
|
|
1503
|
+
import_node_fs3.default.mkdirSync(prjctComponentsDir, { recursive: true });
|
|
1502
1504
|
}
|
|
1503
|
-
if (
|
|
1504
|
-
const existingContent =
|
|
1505
|
+
if (import_node_fs3.default.existsSync(prjctStatusLinePath)) {
|
|
1506
|
+
const existingContent = import_node_fs3.default.readFileSync(prjctStatusLinePath, "utf8");
|
|
1505
1507
|
if (existingContent.includes("CLI_VERSION=")) {
|
|
1506
1508
|
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
1507
1509
|
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
@@ -1509,7 +1511,7 @@ async function installStatusLine() {
|
|
|
1509
1511
|
/CLI_VERSION="[^"]*"/,
|
|
1510
1512
|
`CLI_VERSION="${VERSION}"`
|
|
1511
1513
|
);
|
|
1512
|
-
|
|
1514
|
+
import_node_fs3.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
1513
1515
|
}
|
|
1514
1516
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1515
1517
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
@@ -1518,25 +1520,22 @@ async function installStatusLine() {
|
|
|
1518
1520
|
return;
|
|
1519
1521
|
}
|
|
1520
1522
|
}
|
|
1521
|
-
if (
|
|
1522
|
-
let scriptContent =
|
|
1523
|
-
scriptContent = scriptContent.replace(
|
|
1524
|
-
|
|
1525
|
-
`CLI_VERSION="${VERSION}"`
|
|
1526
|
-
);
|
|
1527
|
-
import_fs4.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
1523
|
+
if (import_node_fs3.default.existsSync(sourceScript)) {
|
|
1524
|
+
let scriptContent = import_node_fs3.default.readFileSync(sourceScript, "utf8");
|
|
1525
|
+
scriptContent = scriptContent.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`);
|
|
1526
|
+
import_node_fs3.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
1528
1527
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1529
1528
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
1530
|
-
if (
|
|
1531
|
-
const themes =
|
|
1529
|
+
if (import_node_fs3.default.existsSync(sourceThemeDir)) {
|
|
1530
|
+
const themes = import_node_fs3.default.readdirSync(sourceThemeDir);
|
|
1532
1531
|
for (const theme of themes) {
|
|
1533
|
-
const src =
|
|
1534
|
-
const dest =
|
|
1535
|
-
|
|
1532
|
+
const src = import_node_path5.default.join(sourceThemeDir, theme);
|
|
1533
|
+
const dest = import_node_path5.default.join(prjctThemesDir, theme);
|
|
1534
|
+
import_node_fs3.default.copyFileSync(src, dest);
|
|
1536
1535
|
}
|
|
1537
1536
|
}
|
|
1538
|
-
if (!
|
|
1539
|
-
|
|
1537
|
+
if (!import_node_fs3.default.existsSync(prjctConfigPath) && import_node_fs3.default.existsSync(sourceConfigPath)) {
|
|
1538
|
+
import_node_fs3.default.copyFileSync(sourceConfigPath, prjctConfigPath);
|
|
1540
1539
|
}
|
|
1541
1540
|
} else {
|
|
1542
1541
|
const scriptContent = `#!/bin/bash
|
|
@@ -1571,7 +1570,7 @@ if [ -f "$CONFIG" ]; then
|
|
|
1571
1570
|
fi
|
|
1572
1571
|
echo "prjct"
|
|
1573
1572
|
`;
|
|
1574
|
-
|
|
1573
|
+
import_node_fs3.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
1575
1574
|
}
|
|
1576
1575
|
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
1577
1576
|
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
@@ -1583,38 +1582,38 @@ echo "prjct"
|
|
|
1583
1582
|
}
|
|
1584
1583
|
__name(installStatusLine, "installStatusLine");
|
|
1585
1584
|
function installStatusLineModules(sourceDir, destDir) {
|
|
1586
|
-
if (!
|
|
1585
|
+
if (!import_node_fs3.default.existsSync(sourceDir)) {
|
|
1587
1586
|
return;
|
|
1588
1587
|
}
|
|
1589
|
-
const files =
|
|
1588
|
+
const files = import_node_fs3.default.readdirSync(sourceDir);
|
|
1590
1589
|
for (const file of files) {
|
|
1591
1590
|
if (file.endsWith(".sh")) {
|
|
1592
|
-
const src =
|
|
1593
|
-
const dest =
|
|
1594
|
-
|
|
1595
|
-
|
|
1591
|
+
const src = import_node_path5.default.join(sourceDir, file);
|
|
1592
|
+
const dest = import_node_path5.default.join(destDir, file);
|
|
1593
|
+
import_node_fs3.default.copyFileSync(src, dest);
|
|
1594
|
+
import_node_fs3.default.chmodSync(dest, 493);
|
|
1596
1595
|
}
|
|
1597
1596
|
}
|
|
1598
1597
|
}
|
|
1599
1598
|
__name(installStatusLineModules, "installStatusLineModules");
|
|
1600
1599
|
function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
1601
1600
|
try {
|
|
1602
|
-
if (
|
|
1603
|
-
const stats =
|
|
1601
|
+
if (import_node_fs3.default.existsSync(linkPath)) {
|
|
1602
|
+
const stats = import_node_fs3.default.lstatSync(linkPath);
|
|
1604
1603
|
if (stats.isSymbolicLink()) {
|
|
1605
|
-
const existingTarget =
|
|
1604
|
+
const existingTarget = import_node_fs3.default.readlinkSync(linkPath);
|
|
1606
1605
|
if (existingTarget === targetPath) {
|
|
1607
1606
|
return;
|
|
1608
1607
|
}
|
|
1609
1608
|
}
|
|
1610
|
-
|
|
1609
|
+
import_node_fs3.default.unlinkSync(linkPath);
|
|
1611
1610
|
}
|
|
1612
|
-
|
|
1613
|
-
} catch (
|
|
1611
|
+
import_node_fs3.default.symlinkSync(targetPath, linkPath);
|
|
1612
|
+
} catch (_error) {
|
|
1614
1613
|
try {
|
|
1615
|
-
if (
|
|
1616
|
-
|
|
1617
|
-
|
|
1614
|
+
if (import_node_fs3.default.existsSync(targetPath)) {
|
|
1615
|
+
import_node_fs3.default.copyFileSync(targetPath, linkPath);
|
|
1616
|
+
import_node_fs3.default.chmodSync(linkPath, 493);
|
|
1618
1617
|
}
|
|
1619
1618
|
} catch (copyError) {
|
|
1620
1619
|
if (!isNotFoundError(copyError)) {
|