proagents 1.6.12 → 1.6.13
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/.proagents/.cursorrules +16 -2
- package/.proagents/.windsurfrules +16 -2
- package/.proagents/AI_INSTRUCTIONS.md +1219 -53
- package/.proagents/ANTIGRAVITY.md +16 -2
- package/.proagents/BOLT.md +16 -2
- package/.proagents/CHATGPT.md +16 -2
- package/.proagents/CLAUDE.md +16 -2
- package/.proagents/GEMINI.md +16 -2
- package/.proagents/GROQ.md +16 -2
- package/.proagents/KIRO.md +16 -2
- package/.proagents/LOVABLE.md +16 -2
- package/.proagents/PROAGENTS.md +52 -26
- package/.proagents/REPLIT.md +16 -2
- package/.proagents/docs/command-details.md +985 -82
- package/.proagents/worklog/_context.md +31 -1
- package/.proagents/worklog/ai-stats.json +19 -0
- package/README.md +85 -1
- package/bin/proagents.js +132 -1
- package/lib/commands/changelog.js +389 -0
- package/lib/commands/completion.js +413 -0
- package/lib/commands/config.js +248 -0
- package/lib/commands/doctor.js +222 -25
- package/lib/commands/help.js +22 -2
- package/lib/commands/init.js +2 -1
- package/lib/commands/open.js +188 -0
- package/lib/commands/release.js +1007 -0
- package/lib/commands/restore.js +150 -0
- package/lib/commands/stats.js +320 -0
- package/lib/commands/uninstall.js +98 -4
- package/lib/commands/upgrade.js +102 -10
- package/lib/commands/version.js +140 -0
- package/package.json +1 -1
package/lib/commands/doctor.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
3
4
|
import chalk from 'chalk';
|
|
4
5
|
import yaml from 'js-yaml';
|
|
5
6
|
|
|
@@ -98,7 +99,9 @@ function checkPlatformSync(targetDir) {
|
|
|
98
99
|
const content = readFileSync(configPath, 'utf-8');
|
|
99
100
|
const config = yaml.load(content);
|
|
100
101
|
configPlatforms = config?.platforms || config?.ai_platforms || [];
|
|
101
|
-
} catch {
|
|
102
|
+
} catch {
|
|
103
|
+
// Config file unreadable - will be caught by other checks
|
|
104
|
+
}
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
// Check each platform file
|
|
@@ -134,7 +137,7 @@ function checkPlatformSync(targetDir) {
|
|
|
134
137
|
* Check for lock file
|
|
135
138
|
*/
|
|
136
139
|
function checkLockFile(targetDir) {
|
|
137
|
-
const lockPath = join(targetDir, 'proagents', '.lock');
|
|
140
|
+
const lockPath = join(targetDir, '.proagents', '.lock');
|
|
138
141
|
const checks = [];
|
|
139
142
|
|
|
140
143
|
if (existsSync(lockPath)) {
|
|
@@ -163,18 +166,187 @@ function checkLockFile(targetDir) {
|
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
/**
|
|
166
|
-
*
|
|
169
|
+
* Extended checks for --full mode
|
|
167
170
|
*/
|
|
168
|
-
|
|
171
|
+
function checkExtended(targetDir) {
|
|
169
172
|
const checks = [];
|
|
170
173
|
|
|
174
|
+
// Check changelog size
|
|
175
|
+
const recentPath = join(targetDir, '.proagents', 'changelog', '_recent.md');
|
|
176
|
+
if (existsSync(recentPath)) {
|
|
177
|
+
try {
|
|
178
|
+
const content = readFileSync(recentPath, 'utf-8');
|
|
179
|
+
const entries = (content.match(/^### /gm) || []).length;
|
|
180
|
+
if (entries > 50) {
|
|
181
|
+
checks.push({ name: 'Changelog size', status: 'warning', message: `${entries} entries (consider archiving)` });
|
|
182
|
+
} else {
|
|
183
|
+
checks.push({ name: 'Changelog size', status: 'ok', message: `${entries} entries` });
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
checks.push({ name: 'Changelog size', status: 'skip', message: 'Could not read' });
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
checks.push({ name: 'Changelog', status: 'info', message: 'No recent changelog' });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Check activity log freshness
|
|
193
|
+
const activityPath = join(targetDir, '.proagents', 'activity.log');
|
|
194
|
+
if (existsSync(activityPath)) {
|
|
195
|
+
try {
|
|
196
|
+
const content = readFileSync(activityPath, 'utf-8');
|
|
197
|
+
const lines = content.trim().split('\n').filter(l => l && !l.startsWith('#') && !l.includes('Activity Log'));
|
|
198
|
+
if (lines.length > 0) {
|
|
199
|
+
const lastLine = lines[lines.length - 1];
|
|
200
|
+
const dateMatch = lastLine.match(/^\[?(\d{4}-\d{2}-\d{2})/);
|
|
201
|
+
if (dateMatch) {
|
|
202
|
+
const lastDate = new Date(dateMatch[1]);
|
|
203
|
+
const daysAgo = Math.floor((Date.now() - lastDate.getTime()) / (1000 * 60 * 60 * 24));
|
|
204
|
+
if (daysAgo > 7) {
|
|
205
|
+
checks.push({ name: 'Activity log', status: 'warning', message: `Last entry ${daysAgo} days ago` });
|
|
206
|
+
} else if (daysAgo > 0) {
|
|
207
|
+
checks.push({ name: 'Activity log', status: 'ok', message: `Last entry ${daysAgo} day(s) ago` });
|
|
208
|
+
} else {
|
|
209
|
+
checks.push({ name: 'Activity log', status: 'ok', message: 'Activity today' });
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
checks.push({ name: 'Activity log', status: 'ok', message: `${lines.length} entries` });
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
checks.push({ name: 'Activity log', status: 'info', message: 'No entries yet' });
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
218
|
+
checks.push({ name: 'Activity log', status: 'skip', message: 'Could not read' });
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
checks.push({ name: 'Activity log', status: 'info', message: 'No activity log' });
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Check for stale feature branches
|
|
171
225
|
try {
|
|
172
|
-
|
|
226
|
+
const branches = execSync('git branch --list "feature/*" 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
227
|
+
if (branches) {
|
|
228
|
+
const branchCount = branches.split('\n').filter(b => b.trim()).length;
|
|
229
|
+
if (branchCount > 5) {
|
|
230
|
+
checks.push({ name: 'Feature branches', status: 'warning', message: `${branchCount} branches (consider cleanup)` });
|
|
231
|
+
} else if (branchCount > 0) {
|
|
232
|
+
checks.push({ name: 'Feature branches', status: 'ok', message: `${branchCount} active` });
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
checks.push({ name: 'Feature branches', status: 'ok', message: 'None' });
|
|
236
|
+
}
|
|
237
|
+
} catch {
|
|
238
|
+
checks.push({ name: 'Feature branches', status: 'skip', message: 'Not a git repo or no feature branches' });
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Check active features
|
|
242
|
+
const featuresPath = join(targetDir, '.proagents', 'active-features', '_index.json');
|
|
243
|
+
if (existsSync(featuresPath)) {
|
|
244
|
+
try {
|
|
245
|
+
const content = readFileSync(featuresPath, 'utf-8');
|
|
246
|
+
const index = JSON.parse(content);
|
|
247
|
+
const activeCount = index.active_features?.length || 0;
|
|
248
|
+
const completedCount = index.completed_features?.length || 0;
|
|
249
|
+
|
|
250
|
+
if (activeCount > 0) {
|
|
251
|
+
checks.push({ name: 'Active features', status: 'ok', message: `${activeCount} active, ${completedCount} completed` });
|
|
252
|
+
} else {
|
|
253
|
+
checks.push({ name: 'Active features', status: 'info', message: `None active, ${completedCount} completed` });
|
|
254
|
+
}
|
|
255
|
+
} catch {
|
|
256
|
+
checks.push({ name: 'Active features', status: 'skip', message: 'Could not read index' });
|
|
257
|
+
}
|
|
258
|
+
} else {
|
|
259
|
+
checks.push({ name: 'Active features', status: 'info', message: 'No features tracked' });
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Check worklog context
|
|
263
|
+
const contextPath = join(targetDir, '.proagents', 'worklog', '_context.md');
|
|
264
|
+
if (existsSync(contextPath)) {
|
|
265
|
+
checks.push({ name: 'Worklog context', status: 'ok', message: 'Present' });
|
|
266
|
+
} else {
|
|
267
|
+
checks.push({ name: 'Worklog context', status: 'warning', message: 'Missing (cross-AI sync may be affected)' });
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Check for required folders
|
|
271
|
+
const requiredFolders = [
|
|
272
|
+
{ path: '.proagents/prompts', name: 'Prompts folder' },
|
|
273
|
+
{ path: '.proagents/templates', name: 'Templates folder' },
|
|
274
|
+
{ path: '.proagents/changelog', name: 'Changelog folder' },
|
|
275
|
+
{ path: '.proagents/worklog', name: 'Worklog folder' }
|
|
276
|
+
];
|
|
277
|
+
|
|
278
|
+
for (const folder of requiredFolders) {
|
|
279
|
+
if (existsSync(join(targetDir, folder.path))) {
|
|
280
|
+
checks.push({ name: folder.name, status: 'ok', message: 'Present' });
|
|
281
|
+
} else {
|
|
282
|
+
checks.push({ name: folder.name, status: 'warning', message: 'Missing' });
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return checks;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Compare semantic versions
|
|
291
|
+
* Returns: -1 if v1 < v2, 0 if equal, 1 if v1 > v2
|
|
292
|
+
*/
|
|
293
|
+
function compareVersions(v1, v2) {
|
|
294
|
+
const parts1 = v1.split('.').map(Number);
|
|
295
|
+
const parts2 = v2.split('.').map(Number);
|
|
296
|
+
|
|
297
|
+
for (let i = 0; i < 3; i++) {
|
|
298
|
+
const p1 = parts1[i] || 0;
|
|
299
|
+
const p2 = parts2[i] || 0;
|
|
300
|
+
if (p1 < p2) return -1;
|
|
301
|
+
if (p1 > p2) return 1;
|
|
302
|
+
}
|
|
303
|
+
return 0;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Check version (CLI, project, and npm)
|
|
308
|
+
*/
|
|
309
|
+
async function checkVersion(targetDir) {
|
|
310
|
+
const checks = [];
|
|
311
|
+
const recommendations = [];
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
// Get CLI version from package.json
|
|
173
315
|
const packagePath = new URL('../../package.json', import.meta.url);
|
|
174
316
|
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
checks.push({ name: '
|
|
317
|
+
const cliVersion = packageJson.version;
|
|
318
|
+
|
|
319
|
+
checks.push({ name: 'CLI version', status: 'info', message: `v${cliVersion}` });
|
|
320
|
+
|
|
321
|
+
// Get project version from .proagents/.version
|
|
322
|
+
const projectVersionPath = join(targetDir, '.proagents', '.version');
|
|
323
|
+
let projectVersion = null;
|
|
324
|
+
|
|
325
|
+
if (existsSync(projectVersionPath)) {
|
|
326
|
+
try {
|
|
327
|
+
projectVersion = readFileSync(projectVersionPath, 'utf-8').trim();
|
|
328
|
+
|
|
329
|
+
if (projectVersion === cliVersion) {
|
|
330
|
+
checks.push({ name: 'Project version', status: 'ok', message: `v${projectVersion} (synced with CLI)` });
|
|
331
|
+
} else if (compareVersions(projectVersion, cliVersion) < 0) {
|
|
332
|
+
checks.push({ name: 'Project version', status: 'warning', message: `v${projectVersion} (outdated)` });
|
|
333
|
+
recommendations.push({
|
|
334
|
+
issue: 'Project framework is outdated',
|
|
335
|
+
action: 'Run `npx proagents init` to update framework files'
|
|
336
|
+
});
|
|
337
|
+
} else {
|
|
338
|
+
checks.push({ name: 'Project version', status: 'info', message: `v${projectVersion}` });
|
|
339
|
+
}
|
|
340
|
+
} catch {
|
|
341
|
+
checks.push({ name: 'Project version', status: 'warning', message: 'Could not read version file' });
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
checks.push({ name: 'Project version', status: 'warning', message: 'No version marker (older installation)' });
|
|
345
|
+
recommendations.push({
|
|
346
|
+
issue: 'No version tracking',
|
|
347
|
+
action: 'Run `npx proagents init` to update and add version tracking'
|
|
348
|
+
});
|
|
349
|
+
}
|
|
178
350
|
|
|
179
351
|
// Try to fetch latest version from npm (with timeout)
|
|
180
352
|
try {
|
|
@@ -190,20 +362,24 @@ async function checkVersion() {
|
|
|
190
362
|
const data = await response.json();
|
|
191
363
|
const latestVersion = data.version;
|
|
192
364
|
|
|
193
|
-
if (
|
|
194
|
-
checks.push({ name: '
|
|
365
|
+
if (compareVersions(cliVersion, latestVersion) >= 0) {
|
|
366
|
+
checks.push({ name: 'npm registry', status: 'ok', message: `v${latestVersion} (up to date)` });
|
|
195
367
|
} else {
|
|
196
|
-
checks.push({ name: '
|
|
368
|
+
checks.push({ name: 'npm registry', status: 'warning', message: `v${latestVersion} available` });
|
|
369
|
+
recommendations.push({
|
|
370
|
+
issue: 'CLI update available',
|
|
371
|
+
action: 'Run `npm update -g proagents` to update CLI'
|
|
372
|
+
});
|
|
197
373
|
}
|
|
198
374
|
}
|
|
199
375
|
} catch {
|
|
200
|
-
checks.push({ name: '
|
|
376
|
+
checks.push({ name: 'npm registry', status: 'skip', message: 'Could not check (offline?)' });
|
|
201
377
|
}
|
|
202
|
-
} catch {
|
|
203
|
-
checks.push({ name: 'Version', status: 'error', message:
|
|
378
|
+
} catch (error) {
|
|
379
|
+
checks.push({ name: 'Version', status: 'error', message: `Could not read version: ${error.message}` });
|
|
204
380
|
}
|
|
205
381
|
|
|
206
|
-
return checks;
|
|
382
|
+
return { checks, recommendations };
|
|
207
383
|
}
|
|
208
384
|
|
|
209
385
|
/**
|
|
@@ -248,16 +424,14 @@ function printChecks(title, checks) {
|
|
|
248
424
|
/**
|
|
249
425
|
* Doctor command - check health of ProAgents installation
|
|
250
426
|
*/
|
|
251
|
-
export async function doctorCommand() {
|
|
427
|
+
export async function doctorCommand(options = {}) {
|
|
252
428
|
const targetDir = process.cwd();
|
|
429
|
+
const isFullMode = options.full || false;
|
|
253
430
|
|
|
254
|
-
console.log(chalk.bold('\nProAgents Doctor'));
|
|
255
|
-
console.log(chalk.gray('
|
|
431
|
+
console.log(chalk.bold('\nProAgents Doctor' + (isFullMode ? ' (Full)' : '')));
|
|
432
|
+
console.log(chalk.gray('═'.repeat(40)));
|
|
256
433
|
console.log(chalk.gray(`Checking: ${targetDir}\n`));
|
|
257
434
|
|
|
258
|
-
let hasErrors = false;
|
|
259
|
-
let hasWarnings = false;
|
|
260
|
-
|
|
261
435
|
// Run all checks
|
|
262
436
|
const installChecks = checkInstallation(targetDir);
|
|
263
437
|
printChecks('Installation', installChecks);
|
|
@@ -271,14 +445,32 @@ export async function doctorCommand() {
|
|
|
271
445
|
const lockChecks = checkLockFile(targetDir);
|
|
272
446
|
printChecks('Lock Status', lockChecks);
|
|
273
447
|
|
|
274
|
-
const
|
|
275
|
-
printChecks('Version',
|
|
448
|
+
const versionResult = await checkVersion(targetDir);
|
|
449
|
+
printChecks('Version', versionResult.checks);
|
|
450
|
+
|
|
451
|
+
// Extended checks for --full mode
|
|
452
|
+
let extendedChecks = [];
|
|
453
|
+
if (isFullMode) {
|
|
454
|
+
extendedChecks = checkExtended(targetDir);
|
|
455
|
+
printChecks('Extended Health Checks', extendedChecks);
|
|
456
|
+
}
|
|
276
457
|
|
|
277
458
|
// Count issues
|
|
278
|
-
const allChecks = [...installChecks, ...configChecks, ...platformChecks, ...lockChecks, ...
|
|
459
|
+
const allChecks = [...installChecks, ...configChecks, ...platformChecks, ...lockChecks, ...versionResult.checks, ...extendedChecks];
|
|
279
460
|
const errors = allChecks.filter(c => c.status === 'error').length;
|
|
280
461
|
const warnings = allChecks.filter(c => c.status === 'warning').length;
|
|
281
462
|
|
|
463
|
+
// Recommendations section (if any)
|
|
464
|
+
if (versionResult.recommendations && versionResult.recommendations.length > 0) {
|
|
465
|
+
console.log(chalk.bold('\nRecommendations'));
|
|
466
|
+
console.log(chalk.gray('─'.repeat(40)));
|
|
467
|
+
|
|
468
|
+
for (const rec of versionResult.recommendations) {
|
|
469
|
+
console.log(chalk.yellow(` ⚡ ${rec.issue}`));
|
|
470
|
+
console.log(chalk.cyan(` → ${rec.action}`));
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
282
474
|
// Summary
|
|
283
475
|
console.log(chalk.bold('\nSummary'));
|
|
284
476
|
console.log(chalk.gray('─'.repeat(40)));
|
|
@@ -298,8 +490,13 @@ export async function doctorCommand() {
|
|
|
298
490
|
console.log(chalk.gray('Run `npx proagents init` to fix installation issues.'));
|
|
299
491
|
}
|
|
300
492
|
if (platformChecks.some(c => c.status === 'warning')) {
|
|
301
|
-
console.log(chalk.gray('Run `
|
|
493
|
+
console.log(chalk.gray('Run `npx proagents ai add` to fix platform sync issues.'));
|
|
302
494
|
}
|
|
303
495
|
console.log('');
|
|
304
496
|
}
|
|
497
|
+
|
|
498
|
+
// Hint for full mode
|
|
499
|
+
if (!isFullMode) {
|
|
500
|
+
console.log(chalk.gray('Run `proagents doctor --full` for extended health checks.\n'));
|
|
501
|
+
}
|
|
305
502
|
}
|
package/lib/commands/help.js
CHANGED
|
@@ -53,10 +53,30 @@ export async function helpCommand() {
|
|
|
53
53
|
console.log(chalk.bold.white('Status & Info'));
|
|
54
54
|
console.log(chalk.gray('─'.repeat(40)));
|
|
55
55
|
console.log(chalk.cyan('proagents status') + ' Show ProAgents status');
|
|
56
|
+
console.log(chalk.cyan('proagents version') + ' Show detailed version info');
|
|
57
|
+
console.log(chalk.cyan('proagents doctor') + ' Health check installation');
|
|
56
58
|
console.log(chalk.cyan('proagents docs') + ' Open documentation');
|
|
57
59
|
console.log(chalk.cyan('proagents commands') + ' Show this help');
|
|
58
|
-
console.log(
|
|
59
|
-
|
|
60
|
+
console.log('');
|
|
61
|
+
|
|
62
|
+
// Release & Maintenance
|
|
63
|
+
console.log(chalk.bold.white('Release & Maintenance'));
|
|
64
|
+
console.log(chalk.gray('─'.repeat(40)));
|
|
65
|
+
console.log(chalk.cyan('proagents release') + ' Interactive release notes');
|
|
66
|
+
console.log(chalk.gray(' Types: -t detailed | short | client | developer | hotfix | prerelease'));
|
|
67
|
+
console.log(chalk.gray(' Filters:'));
|
|
68
|
+
console.log(chalk.cyan(' --include fixes') + ' Only include bug fixes');
|
|
69
|
+
console.log(chalk.cyan(' --include features') + ' Only include features');
|
|
70
|
+
console.log(chalk.cyan(' --exclude docs,deps') + ' Exclude docs and deps');
|
|
71
|
+
console.log(chalk.cyan(' --module auth') + ' Filter by module name');
|
|
72
|
+
console.log(chalk.cyan(' --path src/lib') + ' Filter by file path');
|
|
73
|
+
console.log(chalk.gray(' Options:'));
|
|
74
|
+
console.log(chalk.cyan(' --append') + ' Append to existing notes');
|
|
75
|
+
console.log(chalk.cyan(' --bump') + ' Suggest version bump');
|
|
76
|
+
console.log(chalk.cyan(' --prerelease beta') + ' Mark as beta/rc/alpha');
|
|
77
|
+
console.log(chalk.cyan(' --since v1.0.0') + ' From specific tag');
|
|
78
|
+
console.log(chalk.cyan('proagents upgrade') + ' Upgrade .proagents folder');
|
|
79
|
+
console.log(chalk.cyan('proagents uninstall') + ' Remove ProAgents from project');
|
|
60
80
|
console.log('');
|
|
61
81
|
|
|
62
82
|
// Commands for AI Assistants
|
package/lib/commands/init.js
CHANGED
|
@@ -14,6 +14,8 @@ const PRESERVE_PATHS = [
|
|
|
14
14
|
'active-features', // User's work in progress
|
|
15
15
|
'.learning', // Learned patterns
|
|
16
16
|
'cache', // Cached analysis
|
|
17
|
+
'changelog', // Change history (user data)
|
|
18
|
+
'worklog', // Work context (user data)
|
|
17
19
|
];
|
|
18
20
|
|
|
19
21
|
// Config file is handled specially - merged not preserved
|
|
@@ -41,7 +43,6 @@ const FRAMEWORK_FOLDERS = [
|
|
|
41
43
|
'api-versioning',
|
|
42
44
|
'approval-workflows',
|
|
43
45
|
'automation',
|
|
44
|
-
'changelog',
|
|
45
46
|
'cicd',
|
|
46
47
|
'collaboration',
|
|
47
48
|
'compliance',
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
|
|
6
|
+
// File shortcuts mapping
|
|
7
|
+
const FILE_SHORTCUTS = {
|
|
8
|
+
// Main config
|
|
9
|
+
'config': 'proagents.config.yaml',
|
|
10
|
+
'cfg': 'proagents.config.yaml',
|
|
11
|
+
|
|
12
|
+
// Changelog files
|
|
13
|
+
'changelog': '.proagents/changelog/_recent.md',
|
|
14
|
+
'changes': '.proagents/changelog/_recent.md',
|
|
15
|
+
'recent': '.proagents/changelog/_recent.md',
|
|
16
|
+
|
|
17
|
+
// Activity and logs
|
|
18
|
+
'activity': '.proagents/activity.log',
|
|
19
|
+
'log': '.proagents/activity.log',
|
|
20
|
+
'logs': '.proagents/activity.log',
|
|
21
|
+
|
|
22
|
+
// Context and worklog
|
|
23
|
+
'context': '.proagents/worklog/_context.md',
|
|
24
|
+
'ctx': '.proagents/worklog/_context.md',
|
|
25
|
+
'worklog': '.proagents/worklog/',
|
|
26
|
+
|
|
27
|
+
// AI instructions
|
|
28
|
+
'instructions': '.proagents/AI_INSTRUCTIONS.md',
|
|
29
|
+
'ai': '.proagents/AI_INSTRUCTIONS.md',
|
|
30
|
+
|
|
31
|
+
// Learning and feedback
|
|
32
|
+
'feedback': '.proagents/feedback.md',
|
|
33
|
+
'errors': '.proagents/errors.md',
|
|
34
|
+
'decisions': '.proagents/decisions.md',
|
|
35
|
+
|
|
36
|
+
// Watchlist
|
|
37
|
+
'watchlist': '.proagents/watchlist.yaml',
|
|
38
|
+
'watch': '.proagents/watchlist.yaml',
|
|
39
|
+
|
|
40
|
+
// Handoff
|
|
41
|
+
'handoff': '.proagents/handoff.md',
|
|
42
|
+
|
|
43
|
+
// Features
|
|
44
|
+
'features': '.proagents/active-features/',
|
|
45
|
+
|
|
46
|
+
// Standards and rules
|
|
47
|
+
'standards': '.proagents/config/standards/',
|
|
48
|
+
'rules': '.proagents/config/rules/',
|
|
49
|
+
'integrations': '.proagents/config/integrations/',
|
|
50
|
+
|
|
51
|
+
// Quick reference
|
|
52
|
+
'commands': '.proagents/PROAGENTS.md',
|
|
53
|
+
'help': '.proagents/PROAGENTS.md',
|
|
54
|
+
'workflow': '.proagents/WORKFLOW.md',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get the editor command based on environment
|
|
59
|
+
*/
|
|
60
|
+
function getEditorCommand() {
|
|
61
|
+
// Check for common environment variables
|
|
62
|
+
const editor = process.env.EDITOR || process.env.VISUAL;
|
|
63
|
+
if (editor) return editor;
|
|
64
|
+
|
|
65
|
+
// Platform-specific defaults
|
|
66
|
+
const platform = process.platform;
|
|
67
|
+
if (platform === 'darwin') {
|
|
68
|
+
// macOS - try code, then open
|
|
69
|
+
try {
|
|
70
|
+
execSync('which code', { stdio: 'ignore' });
|
|
71
|
+
return 'code';
|
|
72
|
+
} catch {
|
|
73
|
+
return 'open';
|
|
74
|
+
}
|
|
75
|
+
} else if (platform === 'win32') {
|
|
76
|
+
return 'notepad';
|
|
77
|
+
} else {
|
|
78
|
+
// Linux - try code, vim, nano
|
|
79
|
+
try {
|
|
80
|
+
execSync('which code', { stdio: 'ignore' });
|
|
81
|
+
return 'code';
|
|
82
|
+
} catch {
|
|
83
|
+
try {
|
|
84
|
+
execSync('which vim', { stdio: 'ignore' });
|
|
85
|
+
return 'vim';
|
|
86
|
+
} catch {
|
|
87
|
+
return 'nano';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Open a file or directory in the default editor
|
|
95
|
+
*/
|
|
96
|
+
function openInEditor(path) {
|
|
97
|
+
const editor = getEditorCommand();
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
if (editor === 'open') {
|
|
101
|
+
// macOS open command
|
|
102
|
+
execSync(`open "${path}"`, { stdio: 'inherit' });
|
|
103
|
+
} else if (editor === 'code') {
|
|
104
|
+
// VS Code
|
|
105
|
+
execSync(`code "${path}"`, { stdio: 'inherit' });
|
|
106
|
+
} else {
|
|
107
|
+
// Other editors
|
|
108
|
+
execSync(`${editor} "${path}"`, { stdio: 'inherit' });
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Command: proagents open <shortcut|path>
|
|
118
|
+
* Open ProAgents files quickly
|
|
119
|
+
*/
|
|
120
|
+
export function openCommand(target, options = {}) {
|
|
121
|
+
const targetDir = process.cwd();
|
|
122
|
+
|
|
123
|
+
// If no target, show available shortcuts
|
|
124
|
+
if (!target) {
|
|
125
|
+
console.log(chalk.bold('\nProAgents Open - Quick File Access'));
|
|
126
|
+
console.log(chalk.gray('══════════════════════════════════════════════════════════\n'));
|
|
127
|
+
|
|
128
|
+
console.log(chalk.cyan('Usage:'));
|
|
129
|
+
console.log(chalk.white(' proagents open <shortcut>'));
|
|
130
|
+
console.log(chalk.white(' proagents open <file-path>\n'));
|
|
131
|
+
|
|
132
|
+
console.log(chalk.cyan('Shortcuts:'));
|
|
133
|
+
console.log(chalk.gray('─────────────────────────────────────────────────'));
|
|
134
|
+
|
|
135
|
+
const categories = {
|
|
136
|
+
'Configuration': ['config', 'watchlist', 'standards', 'rules'],
|
|
137
|
+
'Changelog & Logs': ['changelog', 'activity', 'context'],
|
|
138
|
+
'AI & Workflow': ['instructions', 'commands', 'workflow'],
|
|
139
|
+
'Learning': ['feedback', 'errors', 'decisions'],
|
|
140
|
+
'Collaboration': ['handoff', 'features', 'worklog'],
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
for (const [category, shortcuts] of Object.entries(categories)) {
|
|
144
|
+
console.log(chalk.yellow(`\n ${category}:`));
|
|
145
|
+
for (const shortcut of shortcuts) {
|
|
146
|
+
const path = FILE_SHORTCUTS[shortcut];
|
|
147
|
+
if (path) {
|
|
148
|
+
const exists = existsSync(join(targetDir, path));
|
|
149
|
+
const status = exists ? chalk.green('✓') : chalk.gray('○');
|
|
150
|
+
console.log(` ${status} ${chalk.white(shortcut.padEnd(15))} → ${chalk.gray(path)}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
console.log(chalk.gray('\n─────────────────────────────────────────────────'));
|
|
156
|
+
console.log(chalk.gray('Legend: ') + chalk.green('✓ exists ') + chalk.gray('○ not created yet\n'));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Check if target is a shortcut
|
|
161
|
+
let filePath = FILE_SHORTCUTS[target.toLowerCase()];
|
|
162
|
+
|
|
163
|
+
if (filePath) {
|
|
164
|
+
filePath = join(targetDir, filePath);
|
|
165
|
+
} else {
|
|
166
|
+
// Treat as direct path
|
|
167
|
+
filePath = target.startsWith('/') ? target : join(targetDir, target);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Check if file/directory exists
|
|
171
|
+
if (!existsSync(filePath)) {
|
|
172
|
+
console.log(chalk.red(`\nFile not found: ${filePath}`));
|
|
173
|
+
console.log(chalk.gray('Run "proagents open" to see available shortcuts.\n'));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Open the file
|
|
178
|
+
console.log(chalk.cyan(`\nOpening: ${filePath}`));
|
|
179
|
+
|
|
180
|
+
const success = openInEditor(filePath);
|
|
181
|
+
|
|
182
|
+
if (success) {
|
|
183
|
+
console.log(chalk.green('✓ Opened in editor\n'));
|
|
184
|
+
} else {
|
|
185
|
+
console.log(chalk.yellow(`\nCould not open automatically.`));
|
|
186
|
+
console.log(chalk.gray(`Path: ${filePath}\n`));
|
|
187
|
+
}
|
|
188
|
+
}
|