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
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Get recent changes from _recent.md
|
|
8
|
+
*/
|
|
9
|
+
function getRecentChanges(proagentsDir) {
|
|
10
|
+
const recentPath = join(proagentsDir, 'changelog', '_recent.md');
|
|
11
|
+
if (existsSync(recentPath)) {
|
|
12
|
+
return readFileSync(recentPath, 'utf-8');
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Add entry to _recent.md
|
|
19
|
+
*/
|
|
20
|
+
function addToRecent(proagentsDir, entry) {
|
|
21
|
+
const changelogDir = join(proagentsDir, 'changelog');
|
|
22
|
+
const recentPath = join(changelogDir, '_recent.md');
|
|
23
|
+
|
|
24
|
+
// Ensure directory exists
|
|
25
|
+
if (!existsSync(changelogDir)) {
|
|
26
|
+
mkdirSync(changelogDir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
30
|
+
const formattedEntry = `- [${timestamp}] ${entry}\n`;
|
|
31
|
+
|
|
32
|
+
if (existsSync(recentPath)) {
|
|
33
|
+
const existing = readFileSync(recentPath, 'utf-8');
|
|
34
|
+
const lines = existing.split('\n').filter(l => l.trim());
|
|
35
|
+
|
|
36
|
+
// Keep only last 50 entries
|
|
37
|
+
const updatedLines = [formattedEntry.trim(), ...lines].slice(0, 50);
|
|
38
|
+
writeFileSync(recentPath, updatedLines.join('\n') + '\n');
|
|
39
|
+
} else {
|
|
40
|
+
writeFileSync(recentPath, `# Recent Changes\n\n${formattedEntry}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { success: true, timestamp };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Generate changelog from git commits
|
|
48
|
+
*/
|
|
49
|
+
function generateFromGit(options = {}) {
|
|
50
|
+
const { since, until, limit = 50 } = options;
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
let command = 'git log';
|
|
54
|
+
|
|
55
|
+
if (since) {
|
|
56
|
+
command += ` ${since}..${until || 'HEAD'}`;
|
|
57
|
+
} else {
|
|
58
|
+
command += ` -${limit}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
command += ' --pretty=format:"- %s (%h, %an, %ad)" --date=short';
|
|
62
|
+
|
|
63
|
+
const output = execSync(command, { encoding: 'utf-8' });
|
|
64
|
+
return output.trim();
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Export changelog to CHANGELOG.md
|
|
72
|
+
*/
|
|
73
|
+
function exportChangelog(targetDir, proagentsDir, options = {}) {
|
|
74
|
+
const changelogPath = join(targetDir, 'CHANGELOG.md');
|
|
75
|
+
|
|
76
|
+
let content = `# Changelog
|
|
77
|
+
|
|
78
|
+
All notable changes to this project will be documented in this file.
|
|
79
|
+
|
|
80
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
81
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
82
|
+
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
// Get recent changes
|
|
86
|
+
const recent = getRecentChanges(proagentsDir);
|
|
87
|
+
if (recent) {
|
|
88
|
+
content += `## [Unreleased]\n\n`;
|
|
89
|
+
// Parse recent changes
|
|
90
|
+
const lines = recent.split('\n').filter(l => l.startsWith('- ['));
|
|
91
|
+
if (lines.length > 0) {
|
|
92
|
+
content += lines.join('\n') + '\n\n';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Add git history if requested
|
|
97
|
+
if (options.includeGit) {
|
|
98
|
+
const gitLog = generateFromGit({ limit: 100 });
|
|
99
|
+
if (gitLog) {
|
|
100
|
+
content += `## Git History\n\n${gitLog}\n`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
writeFileSync(changelogPath, content);
|
|
105
|
+
return changelogPath;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* View changelog for a specific feature
|
|
110
|
+
*/
|
|
111
|
+
function viewFeatureChangelog(proagentsDir, featureName) {
|
|
112
|
+
const featurePath = join(proagentsDir, 'changelog', 'features', `${featureName}.md`);
|
|
113
|
+
if (existsSync(featurePath)) {
|
|
114
|
+
return readFileSync(featurePath, 'utf-8');
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* View changelog for a specific module
|
|
121
|
+
*/
|
|
122
|
+
function viewModuleChangelog(proagentsDir, moduleName) {
|
|
123
|
+
const modulePath = join(proagentsDir, 'changelog', 'modules', `${moduleName}.md`);
|
|
124
|
+
if (existsSync(modulePath)) {
|
|
125
|
+
return readFileSync(modulePath, 'utf-8');
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* List available changelogs
|
|
132
|
+
*/
|
|
133
|
+
function listChangelogs(proagentsDir) {
|
|
134
|
+
const result = { features: [], modules: [], years: [] };
|
|
135
|
+
|
|
136
|
+
const changelogDir = join(proagentsDir, 'changelog');
|
|
137
|
+
if (!existsSync(changelogDir)) return result;
|
|
138
|
+
|
|
139
|
+
// Features
|
|
140
|
+
const featuresDir = join(changelogDir, 'features');
|
|
141
|
+
if (existsSync(featuresDir)) {
|
|
142
|
+
try {
|
|
143
|
+
result.features = readdirSync(featuresDir)
|
|
144
|
+
.filter(f => f.endsWith('.md'))
|
|
145
|
+
.map(f => f.replace('.md', ''));
|
|
146
|
+
} catch {
|
|
147
|
+
// Directory not readable
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Modules
|
|
152
|
+
const modulesDir = join(changelogDir, 'modules');
|
|
153
|
+
if (existsSync(modulesDir)) {
|
|
154
|
+
try {
|
|
155
|
+
result.modules = readdirSync(modulesDir)
|
|
156
|
+
.filter(f => f.endsWith('.md'))
|
|
157
|
+
.map(f => f.replace('.md', ''));
|
|
158
|
+
} catch {
|
|
159
|
+
// Directory not readable
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Year folders
|
|
164
|
+
try {
|
|
165
|
+
const entries = readdirSync(changelogDir, { withFileTypes: true });
|
|
166
|
+
result.years = entries
|
|
167
|
+
.filter(e => e.isDirectory() && /^20[2-9][0-9]$/.test(e.name))
|
|
168
|
+
.map(e => e.name);
|
|
169
|
+
} catch {
|
|
170
|
+
// Directory not readable
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Changelog command - manage project changelogs
|
|
178
|
+
*/
|
|
179
|
+
export async function changelogCommand(action, value, options = {}) {
|
|
180
|
+
const targetDir = process.cwd();
|
|
181
|
+
const proagentsDir = join(targetDir, '.proagents');
|
|
182
|
+
|
|
183
|
+
// Ensure proagents exists for some commands
|
|
184
|
+
if (!existsSync(proagentsDir) && action !== 'export') {
|
|
185
|
+
console.log(chalk.yellow('\nProAgents is not installed in this project.'));
|
|
186
|
+
console.log(chalk.gray('Run `npx proagents init` to initialize.\n'));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Handle different actions
|
|
191
|
+
switch (action) {
|
|
192
|
+
case 'add': {
|
|
193
|
+
if (!value) {
|
|
194
|
+
console.log(chalk.red('\nError: Please provide a changelog entry.'));
|
|
195
|
+
console.log(chalk.gray('Usage: proagents changelog add "Fixed login bug"\n'));
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const result = addToRecent(proagentsDir, value);
|
|
200
|
+
|
|
201
|
+
if (options.json) {
|
|
202
|
+
console.log(JSON.stringify(result, null, 2));
|
|
203
|
+
} else {
|
|
204
|
+
console.log(chalk.green(`\n✓ Added to changelog: ${value}`));
|
|
205
|
+
console.log(chalk.gray(` Timestamp: ${result.timestamp}\n`));
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
case 'view':
|
|
211
|
+
case 'show':
|
|
212
|
+
default: {
|
|
213
|
+
console.log(chalk.bold('\nRecent Changes'));
|
|
214
|
+
console.log(chalk.gray('==============\n'));
|
|
215
|
+
|
|
216
|
+
const recent = getRecentChanges(proagentsDir);
|
|
217
|
+
if (recent) {
|
|
218
|
+
// Show last N entries
|
|
219
|
+
const limit = options.limit || 10;
|
|
220
|
+
const lines = recent.split('\n').filter(l => l.startsWith('- ['));
|
|
221
|
+
const display = lines.slice(0, limit);
|
|
222
|
+
|
|
223
|
+
if (display.length > 0) {
|
|
224
|
+
for (const line of display) {
|
|
225
|
+
// Color-code by type
|
|
226
|
+
if (line.toLowerCase().includes('fix')) {
|
|
227
|
+
console.log(chalk.blue(line));
|
|
228
|
+
} else if (line.toLowerCase().includes('feat') || line.toLowerCase().includes('add')) {
|
|
229
|
+
console.log(chalk.green(line));
|
|
230
|
+
} else if (line.toLowerCase().includes('break')) {
|
|
231
|
+
console.log(chalk.red(line));
|
|
232
|
+
} else {
|
|
233
|
+
console.log(line);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (lines.length > limit) {
|
|
237
|
+
console.log(chalk.gray(`\n... and ${lines.length - limit} more entries`));
|
|
238
|
+
}
|
|
239
|
+
} else {
|
|
240
|
+
console.log(chalk.gray('No recent changes recorded.'));
|
|
241
|
+
}
|
|
242
|
+
} else {
|
|
243
|
+
console.log(chalk.gray('No changelog found.'));
|
|
244
|
+
}
|
|
245
|
+
console.log('');
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
case 'list': {
|
|
250
|
+
console.log(chalk.bold('\nAvailable Changelogs'));
|
|
251
|
+
console.log(chalk.gray('====================\n'));
|
|
252
|
+
|
|
253
|
+
const changelogs = listChangelogs(proagentsDir);
|
|
254
|
+
|
|
255
|
+
if (options.json) {
|
|
256
|
+
console.log(JSON.stringify(changelogs, null, 2));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (changelogs.features.length > 0) {
|
|
261
|
+
console.log(chalk.cyan('Features:'));
|
|
262
|
+
for (const f of changelogs.features) {
|
|
263
|
+
console.log(` • ${f}`);
|
|
264
|
+
}
|
|
265
|
+
console.log('');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (changelogs.modules.length > 0) {
|
|
269
|
+
console.log(chalk.cyan('Modules:'));
|
|
270
|
+
for (const m of changelogs.modules) {
|
|
271
|
+
console.log(` • ${m}`);
|
|
272
|
+
}
|
|
273
|
+
console.log('');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (changelogs.years.length > 0) {
|
|
277
|
+
console.log(chalk.cyan('Years:'));
|
|
278
|
+
for (const y of changelogs.years) {
|
|
279
|
+
console.log(` • ${y}`);
|
|
280
|
+
}
|
|
281
|
+
console.log('');
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (changelogs.features.length === 0 && changelogs.modules.length === 0 && changelogs.years.length === 0) {
|
|
285
|
+
console.log(chalk.gray('No changelogs found.\n'));
|
|
286
|
+
}
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
case 'feature': {
|
|
291
|
+
if (!value) {
|
|
292
|
+
console.log(chalk.red('\nError: Please provide a feature name.'));
|
|
293
|
+
console.log(chalk.gray('Usage: proagents changelog feature <name>\n'));
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const featureLog = viewFeatureChangelog(proagentsDir, value);
|
|
298
|
+
if (featureLog) {
|
|
299
|
+
console.log(chalk.bold(`\nFeature Changelog: ${value}`));
|
|
300
|
+
console.log(chalk.gray('─'.repeat(40)));
|
|
301
|
+
console.log(featureLog);
|
|
302
|
+
} else {
|
|
303
|
+
console.log(chalk.yellow(`\nNo changelog found for feature: ${value}\n`));
|
|
304
|
+
}
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
case 'module': {
|
|
309
|
+
if (!value) {
|
|
310
|
+
console.log(chalk.red('\nError: Please provide a module name.'));
|
|
311
|
+
console.log(chalk.gray('Usage: proagents changelog module <name>\n'));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const moduleLog = viewModuleChangelog(proagentsDir, value);
|
|
316
|
+
if (moduleLog) {
|
|
317
|
+
console.log(chalk.bold(`\nModule Changelog: ${value}`));
|
|
318
|
+
console.log(chalk.gray('─'.repeat(40)));
|
|
319
|
+
console.log(moduleLog);
|
|
320
|
+
} else {
|
|
321
|
+
console.log(chalk.yellow(`\nNo changelog found for module: ${value}\n`));
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
case 'export': {
|
|
327
|
+
console.log(chalk.bold('\nExporting Changelog'));
|
|
328
|
+
console.log(chalk.gray('===================\n'));
|
|
329
|
+
|
|
330
|
+
const outputPath = exportChangelog(targetDir, proagentsDir, {
|
|
331
|
+
includeGit: options.git
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
if (options.json) {
|
|
335
|
+
console.log(JSON.stringify({ success: true, path: outputPath }, null, 2));
|
|
336
|
+
} else {
|
|
337
|
+
console.log(chalk.green(`✓ Exported to: ${outputPath}\n`));
|
|
338
|
+
}
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
case 'git': {
|
|
343
|
+
console.log(chalk.bold('\nGit Commit History'));
|
|
344
|
+
console.log(chalk.gray('==================\n'));
|
|
345
|
+
|
|
346
|
+
const gitLog = generateFromGit({
|
|
347
|
+
since: options.since,
|
|
348
|
+
until: options.until,
|
|
349
|
+
limit: options.limit || 20
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
if (gitLog) {
|
|
353
|
+
console.log(gitLog);
|
|
354
|
+
} else {
|
|
355
|
+
console.log(chalk.yellow('Could not retrieve git history.'));
|
|
356
|
+
}
|
|
357
|
+
console.log('');
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Changelog list subcommand
|
|
365
|
+
*/
|
|
366
|
+
export async function changelogListCommand(options = {}) {
|
|
367
|
+
return changelogCommand('list', null, options);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Changelog add subcommand
|
|
372
|
+
*/
|
|
373
|
+
export async function changelogAddCommand(entry, options = {}) {
|
|
374
|
+
return changelogCommand('add', entry, options);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Changelog export subcommand
|
|
379
|
+
*/
|
|
380
|
+
export async function changelogExportCommand(options = {}) {
|
|
381
|
+
return changelogCommand('export', null, options);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Changelog view subcommand (default)
|
|
386
|
+
*/
|
|
387
|
+
export async function changelogViewCommand(options = {}) {
|
|
388
|
+
return changelogCommand('view', null, options);
|
|
389
|
+
}
|