prjct-cli 0.45.0 → 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 +75 -0
- package/bin/prjct.ts +117 -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 +58 -39
- 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 +28 -4
- package/core/commands/commands.ts +57 -24
- 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 +13 -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 +18 -19
- package/core/context-tools/imports-tool.ts +13 -33
- package/core/context-tools/index.ts +29 -54
- package/core/context-tools/recent-tool.ts +16 -22
- package/core/context-tools/signatures-tool.ts +17 -26
- package/core/context-tools/summary-tool.ts +20 -22
- package/core/context-tools/token-counter.ts +25 -20
- package/core/context-tools/types.ts +5 -5
- 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 -16
- 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 +25 -25
- 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 +87 -345
- 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 -17
- package/core/storage/metrics-storage.ts +39 -34
- 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 -305
- package/core/types/integrations.ts +3 -3
- package/core/types/storage.ts +14 -14
- 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 +18755 -15574
- package/dist/core/infrastructure/command-installer.js +86 -79
- package/dist/core/infrastructure/editors-config.js +6 -6
- package/dist/core/infrastructure/setup.js +246 -225
- 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,7 +115,7 @@ 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
121
|
const commitFooter = `Generated with [p/](https://www.prjct.app/)`;
|
|
@@ -132,11 +132,11 @@ function getProviderBranding(provider) {
|
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
function detectCursorProject(projectRoot) {
|
|
135
|
-
const cursorDir =
|
|
136
|
-
const rulesDir =
|
|
137
|
-
const routerPath =
|
|
138
|
-
const detected =
|
|
139
|
-
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);
|
|
140
140
|
return {
|
|
141
141
|
detected,
|
|
142
142
|
routerInstalled,
|
|
@@ -148,11 +148,11 @@ function needsCursorRouterRegeneration(projectRoot) {
|
|
|
148
148
|
return detection.detected && !detection.routerInstalled;
|
|
149
149
|
}
|
|
150
150
|
function detectWindsurfProject(projectRoot) {
|
|
151
|
-
const windsurfDir =
|
|
152
|
-
const rulesDir =
|
|
153
|
-
const routerPath =
|
|
154
|
-
const detected =
|
|
155
|
-
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);
|
|
156
156
|
return {
|
|
157
157
|
detected,
|
|
158
158
|
routerInstalled,
|
|
@@ -168,9 +168,9 @@ function detectAntigravity() {
|
|
|
168
168
|
if (!configPath) {
|
|
169
169
|
return { installed: false, skillInstalled: false };
|
|
170
170
|
}
|
|
171
|
-
const installed =
|
|
172
|
-
const skillPath =
|
|
173
|
-
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);
|
|
174
174
|
return {
|
|
175
175
|
installed,
|
|
176
176
|
skillInstalled,
|
|
@@ -182,14 +182,14 @@ function getGlobalContextPath(provider) {
|
|
|
182
182
|
if (!config.configDir) {
|
|
183
183
|
return null;
|
|
184
184
|
}
|
|
185
|
-
return
|
|
185
|
+
return import_node_path2.default.join(config.configDir, config.contextFile);
|
|
186
186
|
}
|
|
187
187
|
function getGlobalSettingsPath(provider) {
|
|
188
188
|
const config = Providers[provider];
|
|
189
189
|
if (!config.configDir || !config.settingsFile) {
|
|
190
190
|
return null;
|
|
191
191
|
}
|
|
192
|
-
return
|
|
192
|
+
return import_node_path2.default.join(config.configDir, config.settingsFile);
|
|
193
193
|
}
|
|
194
194
|
function getSkillsPath(provider) {
|
|
195
195
|
return Providers[provider].skillsDir;
|
|
@@ -199,7 +199,7 @@ function getCommandsDir(provider) {
|
|
|
199
199
|
}
|
|
200
200
|
function getProjectCommandsPath(provider, projectRoot) {
|
|
201
201
|
const config = Providers[provider];
|
|
202
|
-
return
|
|
202
|
+
return import_node_path2.default.join(projectRoot, config.commandsDir);
|
|
203
203
|
}
|
|
204
204
|
function selectProvider() {
|
|
205
205
|
const detection = detectAllProviders();
|
|
@@ -233,21 +233,21 @@ function selectProvider() {
|
|
|
233
233
|
detection
|
|
234
234
|
};
|
|
235
235
|
}
|
|
236
|
-
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;
|
|
237
237
|
var init_ai_provider = __esm({
|
|
238
238
|
"core/infrastructure/ai-provider.ts"() {
|
|
239
239
|
"use strict";
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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"));
|
|
244
244
|
ClaudeProvider = {
|
|
245
245
|
name: "claude",
|
|
246
246
|
displayName: "Claude Code",
|
|
247
247
|
cliCommand: "claude",
|
|
248
|
-
configDir:
|
|
248
|
+
configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".claude"),
|
|
249
249
|
contextFile: "CLAUDE.md",
|
|
250
|
-
skillsDir:
|
|
250
|
+
skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".claude", "skills"),
|
|
251
251
|
commandsDir: ".claude/commands",
|
|
252
252
|
commandFormat: "md",
|
|
253
253
|
settingsFile: "settings.json",
|
|
@@ -260,9 +260,9 @@ var init_ai_provider = __esm({
|
|
|
260
260
|
name: "gemini",
|
|
261
261
|
displayName: "Gemini CLI",
|
|
262
262
|
cliCommand: "gemini",
|
|
263
|
-
configDir:
|
|
263
|
+
configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini"),
|
|
264
264
|
contextFile: "GEMINI.md",
|
|
265
|
-
skillsDir:
|
|
265
|
+
skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "skills"),
|
|
266
266
|
commandsDir: ".gemini/commands",
|
|
267
267
|
commandFormat: "toml",
|
|
268
268
|
settingsFile: "settings.json",
|
|
@@ -276,9 +276,9 @@ var init_ai_provider = __esm({
|
|
|
276
276
|
displayName: "Google Antigravity",
|
|
277
277
|
cliCommand: null,
|
|
278
278
|
// Not a CLI command, but a platform/app
|
|
279
|
-
configDir:
|
|
279
|
+
configDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "antigravity"),
|
|
280
280
|
contextFile: "ANTIGRAVITY.md",
|
|
281
|
-
skillsDir:
|
|
281
|
+
skillsDir: import_node_path2.default.join(import_node_os.default.homedir(), ".gemini", "antigravity", "global_skills"),
|
|
282
282
|
commandsDir: ".agent/skills",
|
|
283
283
|
// Antigravity uses .agent/skills in projects
|
|
284
284
|
commandFormat: "md",
|
|
@@ -404,19 +404,20 @@ __export(setup_exports, {
|
|
|
404
404
|
run: () => run
|
|
405
405
|
});
|
|
406
406
|
module.exports = __toCommonJS(setup_exports);
|
|
407
|
-
var
|
|
408
|
-
var
|
|
409
|
-
var
|
|
410
|
-
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"));
|
|
411
411
|
|
|
412
|
-
// core/
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
412
|
+
// core/types/fs.ts
|
|
413
|
+
function isNotFoundError(error) {
|
|
414
|
+
return error?.code === "ENOENT";
|
|
415
|
+
}
|
|
416
|
+
__name(isNotFoundError, "isNotFoundError");
|
|
416
417
|
|
|
417
418
|
// core/utils/version.ts
|
|
418
|
-
var
|
|
419
|
-
var
|
|
419
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
420
|
+
var import_node_path = __toESM(require("node:path"));
|
|
420
421
|
var cachedVersion = null;
|
|
421
422
|
var cachedPackageJson = null;
|
|
422
423
|
var cachedPackageRoot = null;
|
|
@@ -426,10 +427,10 @@ function getPackageRoot() {
|
|
|
426
427
|
}
|
|
427
428
|
let currentDir = __dirname;
|
|
428
429
|
for (let i = 0; i < 5; i++) {
|
|
429
|
-
const packageJsonPath =
|
|
430
|
-
if (
|
|
430
|
+
const packageJsonPath = import_node_path.default.join(currentDir, "package.json");
|
|
431
|
+
if (import_node_fs.default.existsSync(packageJsonPath)) {
|
|
431
432
|
try {
|
|
432
|
-
const pkg = JSON.parse(
|
|
433
|
+
const pkg = JSON.parse(import_node_fs.default.readFileSync(packageJsonPath, "utf-8"));
|
|
433
434
|
if (pkg.name === "prjct-cli") {
|
|
434
435
|
cachedPackageRoot = currentDir;
|
|
435
436
|
return currentDir;
|
|
@@ -437,9 +438,9 @@ function getPackageRoot() {
|
|
|
437
438
|
} catch (_error) {
|
|
438
439
|
}
|
|
439
440
|
}
|
|
440
|
-
currentDir =
|
|
441
|
+
currentDir = import_node_path.default.dirname(currentDir);
|
|
441
442
|
}
|
|
442
|
-
cachedPackageRoot =
|
|
443
|
+
cachedPackageRoot = import_node_path.default.join(__dirname, "..", "..", "..");
|
|
443
444
|
return cachedPackageRoot;
|
|
444
445
|
}
|
|
445
446
|
__name(getPackageRoot, "getPackageRoot");
|
|
@@ -448,8 +449,8 @@ function getVersion() {
|
|
|
448
449
|
return cachedVersion;
|
|
449
450
|
}
|
|
450
451
|
try {
|
|
451
|
-
const packageJsonPath =
|
|
452
|
-
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"));
|
|
453
454
|
cachedVersion = packageJson.version;
|
|
454
455
|
cachedPackageJson = packageJson;
|
|
455
456
|
return cachedVersion;
|
|
@@ -462,23 +463,23 @@ __name(getVersion, "getVersion");
|
|
|
462
463
|
var VERSION = getVersion();
|
|
463
464
|
var PACKAGE_ROOT = getPackageRoot();
|
|
464
465
|
|
|
465
|
-
// core/
|
|
466
|
-
|
|
467
|
-
return error?.code === "ENOENT";
|
|
468
|
-
}
|
|
469
|
-
__name(isNotFoundError, "isNotFoundError");
|
|
466
|
+
// core/infrastructure/setup.ts
|
|
467
|
+
init_ai_provider();
|
|
470
468
|
|
|
471
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"));
|
|
472
473
|
async function installDocs() {
|
|
473
474
|
try {
|
|
474
|
-
const docsDir =
|
|
475
|
-
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");
|
|
476
477
|
await import_promises.default.mkdir(docsDir, { recursive: true });
|
|
477
478
|
const docFiles = await import_promises.default.readdir(templateDocsDir);
|
|
478
479
|
for (const file of docFiles) {
|
|
479
480
|
if (file.endsWith(".md")) {
|
|
480
|
-
const srcPath =
|
|
481
|
-
const destPath =
|
|
481
|
+
const srcPath = import_node_path3.default.join(templateDocsDir, file);
|
|
482
|
+
const destPath = import_node_path3.default.join(docsDir, file);
|
|
482
483
|
const content = await import_promises.default.readFile(srcPath, "utf-8");
|
|
483
484
|
await import_promises.default.writeFile(destPath, content, "utf-8");
|
|
484
485
|
}
|
|
@@ -503,13 +504,18 @@ async function installGlobalConfig() {
|
|
|
503
504
|
}
|
|
504
505
|
try {
|
|
505
506
|
await import_promises.default.mkdir(activeProvider.configDir, { recursive: true });
|
|
506
|
-
const globalConfigPath =
|
|
507
|
-
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
|
+
);
|
|
508
514
|
let templateContent = "";
|
|
509
515
|
try {
|
|
510
516
|
templateContent = await import_promises.default.readFile(templatePath, "utf-8");
|
|
511
|
-
} catch (
|
|
512
|
-
const fallbackTemplatePath =
|
|
517
|
+
} catch (_error) {
|
|
518
|
+
const fallbackTemplatePath = import_node_path3.default.join(getPackageRoot(), "templates/global/CLAUDE.md");
|
|
513
519
|
templateContent = await import_promises.default.readFile(fallbackTemplatePath, "utf-8");
|
|
514
520
|
if (providerName === "gemini") {
|
|
515
521
|
templateContent = templateContent.replace(/Claude/g, "Gemini");
|
|
@@ -539,7 +545,9 @@ async function installGlobalConfig() {
|
|
|
539
545
|
const endMarker = "<!-- prjct:end - DO NOT REMOVE THIS MARKER -->";
|
|
540
546
|
const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
|
|
541
547
|
if (!hasMarkers) {
|
|
542
|
-
const updatedContent = existingContent
|
|
548
|
+
const updatedContent = `${existingContent}
|
|
549
|
+
|
|
550
|
+
${templateContent}`;
|
|
543
551
|
await import_promises.default.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
544
552
|
return {
|
|
545
553
|
success: true,
|
|
@@ -582,16 +590,16 @@ var CommandInstaller = class {
|
|
|
582
590
|
claudeConfigPath;
|
|
583
591
|
templatesDir;
|
|
584
592
|
constructor() {
|
|
585
|
-
this.homeDir =
|
|
593
|
+
this.homeDir = import_node_os2.default.homedir();
|
|
586
594
|
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
587
595
|
const activeProvider = aiProvider.getActiveProvider();
|
|
588
596
|
if (activeProvider.name === "gemini") {
|
|
589
|
-
this.claudeCommandsPath =
|
|
597
|
+
this.claudeCommandsPath = import_node_path3.default.join(activeProvider.configDir, "commands");
|
|
590
598
|
} else {
|
|
591
|
-
this.claudeCommandsPath =
|
|
599
|
+
this.claudeCommandsPath = import_node_path3.default.join(activeProvider.configDir, "commands", "p");
|
|
592
600
|
}
|
|
593
601
|
this.claudeConfigPath = activeProvider.configDir;
|
|
594
|
-
this.templatesDir =
|
|
602
|
+
this.templatesDir = import_node_path3.default.join(getPackageRoot(), "templates", "commands");
|
|
595
603
|
}
|
|
596
604
|
/**
|
|
597
605
|
* Detect if active provider is installed
|
|
@@ -620,7 +628,7 @@ var CommandInstaller = class {
|
|
|
620
628
|
try {
|
|
621
629
|
const files = await import_promises.default.readdir(this.templatesDir);
|
|
622
630
|
return files.filter((f) => f.endsWith(".md"));
|
|
623
|
-
} catch (
|
|
631
|
+
} catch (_error) {
|
|
624
632
|
return [
|
|
625
633
|
"init.md",
|
|
626
634
|
"now.md",
|
|
@@ -665,8 +673,8 @@ var CommandInstaller = class {
|
|
|
665
673
|
const errors = [];
|
|
666
674
|
for (const file of commandFiles) {
|
|
667
675
|
try {
|
|
668
|
-
const sourcePath =
|
|
669
|
-
const destPath =
|
|
676
|
+
const sourcePath = import_node_path3.default.join(this.templatesDir, file);
|
|
677
|
+
const destPath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
670
678
|
const content = await import_promises.default.readFile(sourcePath, "utf-8");
|
|
671
679
|
await import_promises.default.writeFile(destPath, content, "utf-8");
|
|
672
680
|
installed.push(file.replace(".md", ""));
|
|
@@ -697,7 +705,7 @@ var CommandInstaller = class {
|
|
|
697
705
|
const errors = [];
|
|
698
706
|
for (const file of commandFiles) {
|
|
699
707
|
try {
|
|
700
|
-
const filePath =
|
|
708
|
+
const filePath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
701
709
|
await import_promises.default.unlink(filePath);
|
|
702
710
|
uninstalled.push(file.replace(".md", ""));
|
|
703
711
|
} catch (error) {
|
|
@@ -708,7 +716,7 @@ var CommandInstaller = class {
|
|
|
708
716
|
}
|
|
709
717
|
try {
|
|
710
718
|
await import_promises.default.rmdir(this.claudeCommandsPath);
|
|
711
|
-
} catch (
|
|
719
|
+
} catch (_error) {
|
|
712
720
|
}
|
|
713
721
|
return {
|
|
714
722
|
success: true,
|
|
@@ -782,7 +790,7 @@ var CommandInstaller = class {
|
|
|
782
790
|
*/
|
|
783
791
|
async verifyTemplate(commandName) {
|
|
784
792
|
try {
|
|
785
|
-
const templatePath =
|
|
793
|
+
const templatePath = import_node_path3.default.join(this.templatesDir, `${commandName}.md`);
|
|
786
794
|
await import_promises.default.access(templatePath);
|
|
787
795
|
return true;
|
|
788
796
|
} catch (error) {
|
|
@@ -801,9 +809,9 @@ var CommandInstaller = class {
|
|
|
801
809
|
const activeProvider = aiProvider.getActiveProvider();
|
|
802
810
|
const routerFile = activeProvider.name === "gemini" ? "p.toml" : "p.md";
|
|
803
811
|
try {
|
|
804
|
-
const routerSource =
|
|
805
|
-
const routerDest =
|
|
806
|
-
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 });
|
|
807
815
|
const content = await import_promises.default.readFile(routerSource, "utf-8");
|
|
808
816
|
await import_promises.default.writeFile(routerDest, content, "utf-8");
|
|
809
817
|
return true;
|
|
@@ -852,8 +860,8 @@ var CommandInstaller = class {
|
|
|
852
860
|
};
|
|
853
861
|
for (const file of templateFiles) {
|
|
854
862
|
try {
|
|
855
|
-
const sourcePath =
|
|
856
|
-
const destPath =
|
|
863
|
+
const sourcePath = import_node_path3.default.join(this.templatesDir, file);
|
|
864
|
+
const destPath = import_node_path3.default.join(this.claudeCommandsPath, file);
|
|
857
865
|
const exists = installedFiles.includes(file);
|
|
858
866
|
const content = await import_promises.default.readFile(sourcePath, "utf-8");
|
|
859
867
|
await import_promises.default.writeFile(destPath, content, "utf-8");
|
|
@@ -894,9 +902,9 @@ var commandInstaller = new CommandInstaller();
|
|
|
894
902
|
var command_installer_default = commandInstaller;
|
|
895
903
|
|
|
896
904
|
// core/infrastructure/editors-config.ts
|
|
897
|
-
var import_promises2 = __toESM(require("fs/promises"));
|
|
898
|
-
var
|
|
899
|
-
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"));
|
|
900
908
|
var EditorsConfig = class {
|
|
901
909
|
static {
|
|
902
910
|
__name(this, "EditorsConfig");
|
|
@@ -905,9 +913,9 @@ var EditorsConfig = class {
|
|
|
905
913
|
configDir;
|
|
906
914
|
configFile;
|
|
907
915
|
constructor() {
|
|
908
|
-
this.homeDir =
|
|
909
|
-
this.configDir =
|
|
910
|
-
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");
|
|
911
919
|
}
|
|
912
920
|
/**
|
|
913
921
|
* Ensure config directory exists
|
|
@@ -1027,7 +1035,6 @@ var editorsConfig = new EditorsConfig();
|
|
|
1027
1035
|
var editors_config_default = editorsConfig;
|
|
1028
1036
|
|
|
1029
1037
|
// core/infrastructure/setup.ts
|
|
1030
|
-
init_ai_provider();
|
|
1031
1038
|
var GREEN = "\x1B[32m";
|
|
1032
1039
|
var YELLOW = "\x1B[33m";
|
|
1033
1040
|
var DIM = "\x1B[2m";
|
|
@@ -1037,13 +1044,15 @@ async function installAICLI(provider) {
|
|
|
1037
1044
|
try {
|
|
1038
1045
|
console.log(`${YELLOW}\u{1F4E6} ${provider.displayName} not found. Installing...${NC}`);
|
|
1039
1046
|
console.log("");
|
|
1040
|
-
(0,
|
|
1047
|
+
(0, import_node_child_process2.execSync)(`npm install -g ${packageName}`, { stdio: "inherit" });
|
|
1041
1048
|
console.log("");
|
|
1042
1049
|
console.log(`${GREEN}\u2713${NC} ${provider.displayName} installed successfully`);
|
|
1043
1050
|
console.log("");
|
|
1044
1051
|
return true;
|
|
1045
1052
|
} catch (error) {
|
|
1046
|
-
console.log(
|
|
1053
|
+
console.log(
|
|
1054
|
+
`${YELLOW}\u26A0\uFE0F Failed to install ${provider.displayName}: ${error.message}${NC}`
|
|
1055
|
+
);
|
|
1047
1056
|
console.log(`${DIM}Please install manually: npm install -g ${packageName}${NC}`);
|
|
1048
1057
|
console.log("");
|
|
1049
1058
|
return false;
|
|
@@ -1053,7 +1062,7 @@ __name(installAICLI, "installAICLI");
|
|
|
1053
1062
|
async function run() {
|
|
1054
1063
|
const detection = detectAllProviders();
|
|
1055
1064
|
const selection = selectProvider();
|
|
1056
|
-
const
|
|
1065
|
+
const _primaryProvider = Providers[selection.provider];
|
|
1057
1066
|
const results = {
|
|
1058
1067
|
provider: selection.provider,
|
|
1059
1068
|
providers: [],
|
|
@@ -1137,12 +1146,12 @@ __name(run, "run");
|
|
|
1137
1146
|
var setup_default = { run };
|
|
1138
1147
|
async function installGeminiRouter() {
|
|
1139
1148
|
try {
|
|
1140
|
-
const geminiCommandsDir =
|
|
1141
|
-
const routerSource =
|
|
1142
|
-
const routerDest =
|
|
1143
|
-
|
|
1144
|
-
if (
|
|
1145
|
-
|
|
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);
|
|
1146
1155
|
return true;
|
|
1147
1156
|
}
|
|
1148
1157
|
return false;
|
|
@@ -1154,15 +1163,15 @@ async function installGeminiRouter() {
|
|
|
1154
1163
|
__name(installGeminiRouter, "installGeminiRouter");
|
|
1155
1164
|
async function installGeminiGlobalConfig() {
|
|
1156
1165
|
try {
|
|
1157
|
-
const geminiDir =
|
|
1158
|
-
const globalConfigPath =
|
|
1159
|
-
const templatePath =
|
|
1160
|
-
|
|
1161
|
-
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");
|
|
1162
1171
|
let existingContent = "";
|
|
1163
1172
|
let fileExists = false;
|
|
1164
1173
|
try {
|
|
1165
|
-
existingContent =
|
|
1174
|
+
existingContent = import_node_fs3.default.readFileSync(globalConfigPath, "utf-8");
|
|
1166
1175
|
fileExists = true;
|
|
1167
1176
|
} catch (error) {
|
|
1168
1177
|
if (isNotFoundError(error)) {
|
|
@@ -1172,15 +1181,17 @@ async function installGeminiGlobalConfig() {
|
|
|
1172
1181
|
}
|
|
1173
1182
|
}
|
|
1174
1183
|
if (!fileExists) {
|
|
1175
|
-
|
|
1184
|
+
import_node_fs3.default.writeFileSync(globalConfigPath, templateContent, "utf-8");
|
|
1176
1185
|
return { success: true, action: "created" };
|
|
1177
1186
|
}
|
|
1178
1187
|
const startMarker = "<!-- prjct:start - DO NOT REMOVE THIS MARKER -->";
|
|
1179
1188
|
const endMarker = "<!-- prjct:end - DO NOT REMOVE THIS MARKER -->";
|
|
1180
1189
|
const hasMarkers = existingContent.includes(startMarker) && existingContent.includes(endMarker);
|
|
1181
1190
|
if (!hasMarkers) {
|
|
1182
|
-
const updatedContent2 = existingContent
|
|
1183
|
-
|
|
1191
|
+
const updatedContent2 = `${existingContent}
|
|
1192
|
+
|
|
1193
|
+
${templateContent}`;
|
|
1194
|
+
import_node_fs3.default.writeFileSync(globalConfigPath, updatedContent2, "utf-8");
|
|
1184
1195
|
return { success: true, action: "appended" };
|
|
1185
1196
|
}
|
|
1186
1197
|
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker));
|
|
@@ -1192,7 +1203,7 @@ async function installGeminiGlobalConfig() {
|
|
|
1192
1203
|
templateContent.indexOf(endMarker) + endMarker.length
|
|
1193
1204
|
);
|
|
1194
1205
|
const updatedContent = beforeMarker + prjctSection + afterMarker;
|
|
1195
|
-
|
|
1206
|
+
import_node_fs3.default.writeFileSync(globalConfigPath, updatedContent, "utf-8");
|
|
1196
1207
|
return { success: true, action: "updated" };
|
|
1197
1208
|
} catch (error) {
|
|
1198
1209
|
console.error(`Gemini config warning: ${error.message}`);
|
|
@@ -1202,18 +1213,18 @@ async function installGeminiGlobalConfig() {
|
|
|
1202
1213
|
__name(installGeminiGlobalConfig, "installGeminiGlobalConfig");
|
|
1203
1214
|
async function installAntigravitySkill() {
|
|
1204
1215
|
try {
|
|
1205
|
-
const antigravitySkillsDir =
|
|
1206
|
-
const prjctSkillDir =
|
|
1207
|
-
const skillMdPath =
|
|
1208
|
-
const templatePath =
|
|
1209
|
-
|
|
1210
|
-
const fileExists =
|
|
1211
|
-
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)) {
|
|
1212
1223
|
console.error("Antigravity SKILL.md template not found");
|
|
1213
1224
|
return { success: false, action: null };
|
|
1214
1225
|
}
|
|
1215
|
-
const templateContent =
|
|
1216
|
-
|
|
1226
|
+
const templateContent = import_node_fs3.default.readFileSync(templatePath, "utf-8");
|
|
1227
|
+
import_node_fs3.default.writeFileSync(skillMdPath, templateContent, "utf-8");
|
|
1217
1228
|
return { success: true, action: fileExists ? "updated" : "created" };
|
|
1218
1229
|
} catch (error) {
|
|
1219
1230
|
console.error(`Antigravity skill warning: ${error.message}`);
|
|
@@ -1234,24 +1245,24 @@ async function installCursorProject(projectRoot) {
|
|
|
1234
1245
|
gitignoreUpdated: false
|
|
1235
1246
|
};
|
|
1236
1247
|
try {
|
|
1237
|
-
const cursorDir =
|
|
1238
|
-
const rulesDir =
|
|
1239
|
-
const commandsDir =
|
|
1240
|
-
const routerMdcDest =
|
|
1241
|
-
const routerMdcSource =
|
|
1242
|
-
const cursorCommandsSource =
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
if (
|
|
1246
|
-
|
|
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);
|
|
1247
1258
|
result.rulesCreated = true;
|
|
1248
1259
|
}
|
|
1249
|
-
if (
|
|
1250
|
-
const commandFiles =
|
|
1260
|
+
if (import_node_fs3.default.existsSync(cursorCommandsSource)) {
|
|
1261
|
+
const commandFiles = import_node_fs3.default.readdirSync(cursorCommandsSource).filter((f) => f.endsWith(".md"));
|
|
1251
1262
|
for (const file of commandFiles) {
|
|
1252
|
-
const src =
|
|
1253
|
-
const dest =
|
|
1254
|
-
|
|
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);
|
|
1255
1266
|
}
|
|
1256
1267
|
result.commandsCreated = commandFiles.length > 0;
|
|
1257
1268
|
}
|
|
@@ -1266,7 +1277,7 @@ async function installCursorProject(projectRoot) {
|
|
|
1266
1277
|
__name(installCursorProject, "installCursorProject");
|
|
1267
1278
|
async function addCursorToGitignore(projectRoot) {
|
|
1268
1279
|
try {
|
|
1269
|
-
const gitignorePath =
|
|
1280
|
+
const gitignorePath = import_node_path5.default.join(projectRoot, ".gitignore");
|
|
1270
1281
|
const entriesToAdd = [
|
|
1271
1282
|
"# prjct Cursor routers (regenerated per-developer)",
|
|
1272
1283
|
".cursor/rules/prjct.mdc",
|
|
@@ -1281,7 +1292,7 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
1281
1292
|
let content = "";
|
|
1282
1293
|
let fileExists = false;
|
|
1283
1294
|
try {
|
|
1284
|
-
content =
|
|
1295
|
+
content = import_node_fs3.default.readFileSync(gitignorePath, "utf-8");
|
|
1285
1296
|
fileExists = true;
|
|
1286
1297
|
} catch (error) {
|
|
1287
1298
|
if (!isNotFoundError(error)) {
|
|
@@ -1291,8 +1302,12 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
1291
1302
|
if (content.includes(".cursor/rules/prjct.mdc")) {
|
|
1292
1303
|
return false;
|
|
1293
1304
|
}
|
|
1294
|
-
const newContent = fileExists ? content.trimEnd()
|
|
1295
|
-
|
|
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");
|
|
1296
1311
|
return true;
|
|
1297
1312
|
} catch (error) {
|
|
1298
1313
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -1301,13 +1316,13 @@ async function addCursorToGitignore(projectRoot) {
|
|
|
1301
1316
|
}
|
|
1302
1317
|
__name(addCursorToGitignore, "addCursorToGitignore");
|
|
1303
1318
|
function hasCursorProject(projectRoot) {
|
|
1304
|
-
return
|
|
1319
|
+
return import_node_fs3.default.existsSync(import_node_path5.default.join(projectRoot, ".cursor"));
|
|
1305
1320
|
}
|
|
1306
1321
|
__name(hasCursorProject, "hasCursorProject");
|
|
1307
1322
|
function needsCursorRegeneration(projectRoot) {
|
|
1308
|
-
const cursorDir =
|
|
1309
|
-
const routerPath =
|
|
1310
|
-
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);
|
|
1311
1326
|
}
|
|
1312
1327
|
__name(needsCursorRegeneration, "needsCursorRegeneration");
|
|
1313
1328
|
async function installWindsurfProject(projectRoot) {
|
|
@@ -1318,24 +1333,29 @@ async function installWindsurfProject(projectRoot) {
|
|
|
1318
1333
|
gitignoreUpdated: false
|
|
1319
1334
|
};
|
|
1320
1335
|
try {
|
|
1321
|
-
const windsurfDir =
|
|
1322
|
-
const rulesDir =
|
|
1323
|
-
const workflowsDir =
|
|
1324
|
-
const routerDest =
|
|
1325
|
-
const routerSource =
|
|
1326
|
-
const windsurfWorkflowsSource =
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
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);
|
|
1331
1351
|
result.rulesCreated = true;
|
|
1332
1352
|
}
|
|
1333
|
-
if (
|
|
1334
|
-
const workflowFiles =
|
|
1353
|
+
if (import_node_fs3.default.existsSync(windsurfWorkflowsSource)) {
|
|
1354
|
+
const workflowFiles = import_node_fs3.default.readdirSync(windsurfWorkflowsSource).filter((f) => f.endsWith(".md"));
|
|
1335
1355
|
for (const file of workflowFiles) {
|
|
1336
|
-
const src =
|
|
1337
|
-
const dest =
|
|
1338
|
-
|
|
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);
|
|
1339
1359
|
}
|
|
1340
1360
|
result.workflowsCreated = workflowFiles.length > 0;
|
|
1341
1361
|
}
|
|
@@ -1350,7 +1370,7 @@ async function installWindsurfProject(projectRoot) {
|
|
|
1350
1370
|
__name(installWindsurfProject, "installWindsurfProject");
|
|
1351
1371
|
async function addWindsurfToGitignore(projectRoot) {
|
|
1352
1372
|
try {
|
|
1353
|
-
const gitignorePath =
|
|
1373
|
+
const gitignorePath = import_node_path5.default.join(projectRoot, ".gitignore");
|
|
1354
1374
|
const entriesToAdd = [
|
|
1355
1375
|
"# prjct Windsurf routers (regenerated per-developer)",
|
|
1356
1376
|
".windsurf/rules/prjct.md",
|
|
@@ -1365,7 +1385,7 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
1365
1385
|
let content = "";
|
|
1366
1386
|
let fileExists = false;
|
|
1367
1387
|
try {
|
|
1368
|
-
content =
|
|
1388
|
+
content = import_node_fs3.default.readFileSync(gitignorePath, "utf-8");
|
|
1369
1389
|
fileExists = true;
|
|
1370
1390
|
} catch (error) {
|
|
1371
1391
|
if (!isNotFoundError(error)) {
|
|
@@ -1375,8 +1395,12 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
1375
1395
|
if (content.includes(".windsurf/rules/prjct.md")) {
|
|
1376
1396
|
return false;
|
|
1377
1397
|
}
|
|
1378
|
-
const newContent = fileExists ? content.trimEnd()
|
|
1379
|
-
|
|
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");
|
|
1380
1404
|
return true;
|
|
1381
1405
|
} catch (error) {
|
|
1382
1406
|
console.error(`Gitignore update warning: ${error.message}`);
|
|
@@ -1385,34 +1409,34 @@ async function addWindsurfToGitignore(projectRoot) {
|
|
|
1385
1409
|
}
|
|
1386
1410
|
__name(addWindsurfToGitignore, "addWindsurfToGitignore");
|
|
1387
1411
|
function hasWindsurfProject(projectRoot) {
|
|
1388
|
-
return
|
|
1412
|
+
return import_node_fs3.default.existsSync(import_node_path5.default.join(projectRoot, ".windsurf"));
|
|
1389
1413
|
}
|
|
1390
1414
|
__name(hasWindsurfProject, "hasWindsurfProject");
|
|
1391
1415
|
function needsWindsurfRegeneration(projectRoot) {
|
|
1392
|
-
const windsurfDir =
|
|
1393
|
-
const routerPath =
|
|
1394
|
-
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);
|
|
1395
1419
|
}
|
|
1396
1420
|
__name(needsWindsurfRegeneration, "needsWindsurfRegeneration");
|
|
1397
1421
|
async function migrateProjectsCliVersion() {
|
|
1398
1422
|
try {
|
|
1399
|
-
const projectsDir =
|
|
1400
|
-
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)) {
|
|
1401
1425
|
return;
|
|
1402
1426
|
}
|
|
1403
|
-
const projectDirs =
|
|
1427
|
+
const projectDirs = import_node_fs3.default.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1404
1428
|
let migrated = 0;
|
|
1405
1429
|
for (const projectId of projectDirs) {
|
|
1406
|
-
const projectJsonPath =
|
|
1407
|
-
if (!
|
|
1430
|
+
const projectJsonPath = import_node_path5.default.join(projectsDir, projectId, "project.json");
|
|
1431
|
+
if (!import_node_fs3.default.existsSync(projectJsonPath)) {
|
|
1408
1432
|
continue;
|
|
1409
1433
|
}
|
|
1410
1434
|
try {
|
|
1411
|
-
const content =
|
|
1435
|
+
const content = import_node_fs3.default.readFileSync(projectJsonPath, "utf8");
|
|
1412
1436
|
const project = JSON.parse(content);
|
|
1413
1437
|
if (project.cliVersion !== VERSION) {
|
|
1414
1438
|
project.cliVersion = VERSION;
|
|
1415
|
-
|
|
1439
|
+
import_node_fs3.default.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
1416
1440
|
migrated++;
|
|
1417
1441
|
}
|
|
1418
1442
|
} catch (error) {
|
|
@@ -1433,9 +1457,9 @@ async function migrateProjectsCliVersion() {
|
|
|
1433
1457
|
__name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
|
|
1434
1458
|
function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
1435
1459
|
let settings = {};
|
|
1436
|
-
if (
|
|
1460
|
+
if (import_node_fs3.default.existsSync(settingsPath)) {
|
|
1437
1461
|
try {
|
|
1438
|
-
settings = JSON.parse(
|
|
1462
|
+
settings = JSON.parse(import_node_fs3.default.readFileSync(settingsPath, "utf8"));
|
|
1439
1463
|
} catch (error) {
|
|
1440
1464
|
if (!(error instanceof SyntaxError)) {
|
|
1441
1465
|
throw error;
|
|
@@ -1443,43 +1467,43 @@ function ensureStatusLineSettings(settingsPath, statusLinePath) {
|
|
|
1443
1467
|
}
|
|
1444
1468
|
}
|
|
1445
1469
|
settings.statusLine = { type: "command", command: statusLinePath };
|
|
1446
|
-
|
|
1470
|
+
import_node_fs3.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
1447
1471
|
}
|
|
1448
1472
|
__name(ensureStatusLineSettings, "ensureStatusLineSettings");
|
|
1449
1473
|
async function installStatusLine() {
|
|
1450
1474
|
try {
|
|
1451
|
-
const claudeDir =
|
|
1452
|
-
const settingsPath =
|
|
1453
|
-
const claudeStatusLinePath =
|
|
1454
|
-
const prjctStatusLineDir =
|
|
1455
|
-
const prjctStatusLinePath =
|
|
1456
|
-
const prjctThemesDir =
|
|
1457
|
-
const prjctLibDir =
|
|
1458
|
-
const prjctComponentsDir =
|
|
1459
|
-
const prjctConfigPath =
|
|
1460
|
-
const assetsDir =
|
|
1461
|
-
const sourceScript =
|
|
1462
|
-
const sourceThemeDir =
|
|
1463
|
-
const sourceLibDir =
|
|
1464
|
-
const sourceComponentsDir =
|
|
1465
|
-
const sourceConfigPath =
|
|
1466
|
-
if (!
|
|
1467
|
-
|
|
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 });
|
|
1468
1492
|
}
|
|
1469
|
-
if (!
|
|
1470
|
-
|
|
1493
|
+
if (!import_node_fs3.default.existsSync(prjctStatusLineDir)) {
|
|
1494
|
+
import_node_fs3.default.mkdirSync(prjctStatusLineDir, { recursive: true });
|
|
1471
1495
|
}
|
|
1472
|
-
if (!
|
|
1473
|
-
|
|
1496
|
+
if (!import_node_fs3.default.existsSync(prjctThemesDir)) {
|
|
1497
|
+
import_node_fs3.default.mkdirSync(prjctThemesDir, { recursive: true });
|
|
1474
1498
|
}
|
|
1475
|
-
if (!
|
|
1476
|
-
|
|
1499
|
+
if (!import_node_fs3.default.existsSync(prjctLibDir)) {
|
|
1500
|
+
import_node_fs3.default.mkdirSync(prjctLibDir, { recursive: true });
|
|
1477
1501
|
}
|
|
1478
|
-
if (!
|
|
1479
|
-
|
|
1502
|
+
if (!import_node_fs3.default.existsSync(prjctComponentsDir)) {
|
|
1503
|
+
import_node_fs3.default.mkdirSync(prjctComponentsDir, { recursive: true });
|
|
1480
1504
|
}
|
|
1481
|
-
if (
|
|
1482
|
-
const existingContent =
|
|
1505
|
+
if (import_node_fs3.default.existsSync(prjctStatusLinePath)) {
|
|
1506
|
+
const existingContent = import_node_fs3.default.readFileSync(prjctStatusLinePath, "utf8");
|
|
1483
1507
|
if (existingContent.includes("CLI_VERSION=")) {
|
|
1484
1508
|
const versionMatch = existingContent.match(/CLI_VERSION="([^"]*)"/);
|
|
1485
1509
|
if (versionMatch && versionMatch[1] !== VERSION) {
|
|
@@ -1487,7 +1511,7 @@ async function installStatusLine() {
|
|
|
1487
1511
|
/CLI_VERSION="[^"]*"/,
|
|
1488
1512
|
`CLI_VERSION="${VERSION}"`
|
|
1489
1513
|
);
|
|
1490
|
-
|
|
1514
|
+
import_node_fs3.default.writeFileSync(prjctStatusLinePath, updatedContent, { mode: 493 });
|
|
1491
1515
|
}
|
|
1492
1516
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1493
1517
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
@@ -1496,25 +1520,22 @@ async function installStatusLine() {
|
|
|
1496
1520
|
return;
|
|
1497
1521
|
}
|
|
1498
1522
|
}
|
|
1499
|
-
if (
|
|
1500
|
-
let scriptContent =
|
|
1501
|
-
scriptContent = scriptContent.replace(
|
|
1502
|
-
|
|
1503
|
-
`CLI_VERSION="${VERSION}"`
|
|
1504
|
-
);
|
|
1505
|
-
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 });
|
|
1506
1527
|
installStatusLineModules(sourceLibDir, prjctLibDir);
|
|
1507
1528
|
installStatusLineModules(sourceComponentsDir, prjctComponentsDir);
|
|
1508
|
-
if (
|
|
1509
|
-
const themes =
|
|
1529
|
+
if (import_node_fs3.default.existsSync(sourceThemeDir)) {
|
|
1530
|
+
const themes = import_node_fs3.default.readdirSync(sourceThemeDir);
|
|
1510
1531
|
for (const theme of themes) {
|
|
1511
|
-
const src =
|
|
1512
|
-
const dest =
|
|
1513
|
-
|
|
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);
|
|
1514
1535
|
}
|
|
1515
1536
|
}
|
|
1516
|
-
if (!
|
|
1517
|
-
|
|
1537
|
+
if (!import_node_fs3.default.existsSync(prjctConfigPath) && import_node_fs3.default.existsSync(sourceConfigPath)) {
|
|
1538
|
+
import_node_fs3.default.copyFileSync(sourceConfigPath, prjctConfigPath);
|
|
1518
1539
|
}
|
|
1519
1540
|
} else {
|
|
1520
1541
|
const scriptContent = `#!/bin/bash
|
|
@@ -1549,7 +1570,7 @@ if [ -f "$CONFIG" ]; then
|
|
|
1549
1570
|
fi
|
|
1550
1571
|
echo "prjct"
|
|
1551
1572
|
`;
|
|
1552
|
-
|
|
1573
|
+
import_node_fs3.default.writeFileSync(prjctStatusLinePath, scriptContent, { mode: 493 });
|
|
1553
1574
|
}
|
|
1554
1575
|
ensureStatusLineSymlink(claudeStatusLinePath, prjctStatusLinePath);
|
|
1555
1576
|
ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
@@ -1561,38 +1582,38 @@ echo "prjct"
|
|
|
1561
1582
|
}
|
|
1562
1583
|
__name(installStatusLine, "installStatusLine");
|
|
1563
1584
|
function installStatusLineModules(sourceDir, destDir) {
|
|
1564
|
-
if (!
|
|
1585
|
+
if (!import_node_fs3.default.existsSync(sourceDir)) {
|
|
1565
1586
|
return;
|
|
1566
1587
|
}
|
|
1567
|
-
const files =
|
|
1588
|
+
const files = import_node_fs3.default.readdirSync(sourceDir);
|
|
1568
1589
|
for (const file of files) {
|
|
1569
1590
|
if (file.endsWith(".sh")) {
|
|
1570
|
-
const src =
|
|
1571
|
-
const dest =
|
|
1572
|
-
|
|
1573
|
-
|
|
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);
|
|
1574
1595
|
}
|
|
1575
1596
|
}
|
|
1576
1597
|
}
|
|
1577
1598
|
__name(installStatusLineModules, "installStatusLineModules");
|
|
1578
1599
|
function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
1579
1600
|
try {
|
|
1580
|
-
if (
|
|
1581
|
-
const stats =
|
|
1601
|
+
if (import_node_fs3.default.existsSync(linkPath)) {
|
|
1602
|
+
const stats = import_node_fs3.default.lstatSync(linkPath);
|
|
1582
1603
|
if (stats.isSymbolicLink()) {
|
|
1583
|
-
const existingTarget =
|
|
1604
|
+
const existingTarget = import_node_fs3.default.readlinkSync(linkPath);
|
|
1584
1605
|
if (existingTarget === targetPath) {
|
|
1585
1606
|
return;
|
|
1586
1607
|
}
|
|
1587
1608
|
}
|
|
1588
|
-
|
|
1609
|
+
import_node_fs3.default.unlinkSync(linkPath);
|
|
1589
1610
|
}
|
|
1590
|
-
|
|
1591
|
-
} catch (
|
|
1611
|
+
import_node_fs3.default.symlinkSync(targetPath, linkPath);
|
|
1612
|
+
} catch (_error) {
|
|
1592
1613
|
try {
|
|
1593
|
-
if (
|
|
1594
|
-
|
|
1595
|
-
|
|
1614
|
+
if (import_node_fs3.default.existsSync(targetPath)) {
|
|
1615
|
+
import_node_fs3.default.copyFileSync(targetPath, linkPath);
|
|
1616
|
+
import_node_fs3.default.chmodSync(linkPath, 493);
|
|
1596
1617
|
}
|
|
1597
1618
|
} catch (copyError) {
|
|
1598
1619
|
if (!isNotFoundError(copyError)) {
|