@gravirei/reis 2.6.0 → 2.6.1

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 CHANGED
@@ -1,5 +1,37 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.6.1] - 2026-01-26
4
+
5
+ ### 🐛 Bug Fixes
6
+
7
+ #### Fixed `reis update` Command
8
+ - **Fixed crash** when a new version was available (missing `showWarning` function)
9
+ - Command now works correctly for all scenarios
10
+
11
+ ### ✨ UI Improvements
12
+
13
+ #### Redesigned `reis update` Command
14
+ - Added welcome banner (consistent with `reis help`)
15
+ - Shows current version first, then checks for updates
16
+ - Beautiful bordered info boxes for status display
17
+ - **User confirmation prompt** before downloading updates
18
+ - Clear success/error messages with helpful instructions
19
+ - Non-interactive mode fallback with manual instructions
20
+
21
+ #### Redesigned `reis whats-new` Command
22
+ - Added welcome banner (consistent with `reis help`)
23
+ - **Now parses actual `CHANGELOG.md`** instead of hardcoded content
24
+ - Shows up to 3 major sections with smart truncation
25
+ - Displays bullet points, headers, and code examples nicely
26
+ - Fallback message if version not found in changelog
27
+ - Links to full changelog and documentation
28
+
29
+ ### 🔧 Internal Changes
30
+
31
+ - Added `showWarning` function to `lib/utils/command-helpers.js`
32
+
33
+ ---
34
+
3
35
  ## [2.6.0] - 2026-01-26
4
36
 
5
37
  ### 🎯 Major Features
@@ -1,5 +1,6 @@
1
- const { showInfo, showSuccess, showError, showWarning, getVersion } = require('../utils/command-helpers.js');
1
+ const chalk = require('chalk');
2
2
  const { execSync } = require('child_process');
3
+ const { getVersion } = require('../utils/command-helpers.js');
3
4
 
4
5
  /**
5
6
  * Update command - check for and install REIS updates
@@ -8,68 +9,130 @@ const { execSync } = require('child_process');
8
9
  module.exports = async function(args) {
9
10
  const currentVersion = getVersion();
10
11
  const packageName = '@gravirei/reis';
12
+ const w = chalk.bold.white;
13
+ const g = chalk.green;
14
+ const y = chalk.yellow;
15
+ const r = chalk.red;
16
+ const c = chalk.cyan;
17
+
18
+ // ASCII Art Banner
19
+ console.log(w(`
20
+ ██████╗ ███████╗██╗███████╗
21
+ ██╔══██╗██╔════╝██║██╔════╝
22
+ ██████╔╝█████╗ ██║███████╗
23
+ ██╔══██╗██╔══╝ ██║╚════██║
24
+ ██║ ██║███████╗██║███████║
25
+ ╚═╝ ╚═╝╚══════╝╚═╝╚══════╝
26
+ `));
11
27
 
28
+ console.log(w(' REIS - Roadmap Execution & Implementation System'));
29
+ console.log(w(' Specially designed for Atlassian Rovo Dev'));
12
30
  console.log('');
13
- showInfo('🔍 Checking for REIS updates...');
31
+ console.log(w('● Update Manager'));
32
+ console.log(w(' ───────────────'));
14
33
  console.log('');
15
- showInfo(` Current version: v${currentVersion}`);
16
-
34
+ console.log(w(` Current Version: v${currentVersion}`));
35
+ console.log('');
36
+ console.log(c(' 🔍 Checking for updates...'));
37
+ console.log('');
38
+
17
39
  try {
18
40
  // Check latest version from npm
19
41
  const latestVersion = execSync(`npm view ${packageName} version 2>/dev/null`, {
20
42
  encoding: 'utf-8'
21
43
  }).trim();
22
-
23
- showInfo(` Latest version: v${latestVersion}`);
24
- console.log('');
25
-
44
+
26
45
  if (currentVersion === latestVersion) {
27
- showSuccess('✅ You are already on the latest version!');
46
+ // Already up to date
47
+ console.log(w(' ┌──────────────────────────────────────────────────────┐'));
48
+ console.log(w(' │ ') + g('✅ You\'re up to date!') + w(' │'));
49
+ console.log(w(' │ │'));
50
+ console.log(w(' │ Installed: ') + g(`v${currentVersion}`) + w(' (latest)' + ' '.repeat(Math.max(0, 22 - currentVersion.length))) + w('│'));
51
+ console.log(w(' └──────────────────────────────────────────────────────┘'));
28
52
  console.log('');
29
53
  return 0;
30
54
  }
31
-
55
+
32
56
  // New version available
33
- showWarning(`📦 New version available: v${currentVersion} → v${latestVersion}`);
57
+ console.log(w(` Latest Version: v${latestVersion}`));
34
58
  console.log('');
35
- showInfo(' Updating REIS...');
59
+ console.log(w(' ┌──────────────────────────────────────────────────────┐'));
60
+ console.log(w(' │ ') + y('📦 New version available!') + w(' │'));
61
+ console.log(w(' │ │'));
62
+ const versionLine = `v${currentVersion} → v${latestVersion}`;
63
+ const padding = Math.max(0, 38 - versionLine.length);
64
+ console.log(w(' │ ') + c(versionLine) + w(' '.repeat(padding) + '│'));
65
+ console.log(w(' └──────────────────────────────────────────────────────┘'));
36
66
  console.log('');
37
-
67
+
68
+ // Ask user for confirmation
69
+ const inquirer = require('inquirer');
38
70
  try {
39
- // Try global update
40
- execSync(`npm install -g ${packageName}@latest`, {
41
- stdio: 'inherit',
42
- encoding: 'utf-8'
43
- });
44
-
45
- console.log('');
46
- showSuccess(`✅ Successfully updated to v${latestVersion}!`);
47
- console.log('');
48
- showInfo(' Run "reis whats-new" to see what\'s changed.');
71
+ const { confirmUpdate } = await inquirer.prompt([
72
+ {
73
+ type: 'confirm',
74
+ name: 'confirmUpdate',
75
+ message: 'Do you want to update REIS now?',
76
+ default: true
77
+ }
78
+ ]);
79
+
49
80
  console.log('');
50
-
51
- } catch (installError) {
52
- // If global install fails, suggest manual update
81
+
82
+ if (!confirmUpdate) {
83
+ console.log(c(' ℹ Update skipped. Run "reis update" anytime to update.'));
84
+ console.log('');
85
+ return 0;
86
+ }
87
+
88
+ // User confirmed, proceed with update
89
+ console.log(c(` ⏳ Downloading and installing v${latestVersion}...`));
53
90
  console.log('');
54
- showError('❌ Automatic update failed (may need sudo/admin privileges)');
91
+
92
+ try {
93
+ // Try global update
94
+ execSync(`npm install -g ${packageName}@latest`, {
95
+ stdio: 'inherit',
96
+ encoding: 'utf-8'
97
+ });
98
+
99
+ console.log('');
100
+ console.log(g(` ✓ Successfully updated to v${latestVersion}!`));
101
+ console.log('');
102
+ console.log(c(' Run "reis whats-new" to see what\'s changed.'));
103
+ console.log('');
104
+ return 0;
105
+
106
+ } catch (installError) {
107
+ // If global install fails, suggest manual update
108
+ console.log('');
109
+ console.log(r(' ❌ Update failed (may need elevated privileges)'));
110
+ console.log('');
111
+ console.log(w(' Try manually:'));
112
+ console.log(c(` $ sudo npm install -g ${packageName}@latest`));
113
+ console.log('');
114
+ return 1;
115
+ }
116
+
117
+ } catch (promptError) {
118
+ // Non-interactive mode - show manual instructions
119
+ console.log(y(' Non-interactive mode detected.'));
55
120
  console.log('');
56
- showInfo(' Try manually:');
57
- showInfo(` $ sudo npm install -g ${packageName}@latest`);
58
- showInfo(' or');
59
- showInfo(` $ npm install -g ${packageName}@latest --force`);
121
+ console.log(w(' To update manually, run:'));
122
+ console.log(c(` $ npm install -g ${packageName}@latest`));
60
123
  console.log('');
61
- return 1;
124
+ return 0;
62
125
  }
63
-
126
+
64
127
  } catch (error) {
65
- showError('❌ Failed to check for updates');
66
- showInfo(' Check your internet connection and try again.');
128
+ // Network error or npm not available
129
+ console.log(r(' Could not check for updates'));
67
130
  console.log('');
68
- showInfo(' Manual update:');
69
- showInfo(` $ npm install -g ${packageName}@latest`);
131
+ console.log(w(' Please check your internet connection and try again.'));
132
+ console.log('');
133
+ console.log(w(' Manual update:'));
134
+ console.log(c(` $ npm install -g ${packageName}@latest`));
70
135
  console.log('');
71
136
  return 1;
72
137
  }
73
-
74
- return 0;
75
138
  };
@@ -1,4 +1,116 @@
1
- const { showInfo, getVersion } = require('../utils/command-helpers.js');
1
+ const chalk = require('chalk');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const { getVersion } = require('../utils/command-helpers.js');
5
+
6
+ /**
7
+ * Parse CHANGELOG.md and extract changes for a specific version
8
+ * @param {string} version - Version to find (e.g., "2.6.0")
9
+ * @returns {object} - { found: boolean, title: string, sections: [{header, items}] }
10
+ */
11
+ function parseChangelog(version) {
12
+ const changelogPaths = [
13
+ path.join(__dirname, '../../CHANGELOG.md'),
14
+ path.join(process.cwd(), 'CHANGELOG.md')
15
+ ];
16
+
17
+ let changelogContent = null;
18
+ for (const p of changelogPaths) {
19
+ if (fs.existsSync(p)) {
20
+ changelogContent = fs.readFileSync(p, 'utf-8');
21
+ break;
22
+ }
23
+ }
24
+
25
+ if (!changelogContent) {
26
+ return { found: false, title: '', sections: [] };
27
+ }
28
+
29
+ // Find the section for this version
30
+ const versionRegex = new RegExp(`^## \\[${version.replace(/\./g, '\\.')}\\].*$`, 'm');
31
+ const match = changelogContent.match(versionRegex);
32
+
33
+ if (!match) {
34
+ return { found: false, title: '', sections: [] };
35
+ }
36
+
37
+ const startIndex = match.index;
38
+ const title = match[0];
39
+
40
+ // Find the next version section (or end of file)
41
+ const nextVersionRegex = /^## \[/m;
42
+ const afterStart = changelogContent.substring(startIndex + title.length);
43
+ const nextMatch = afterStart.match(nextVersionRegex);
44
+
45
+ const endIndex = nextMatch
46
+ ? startIndex + title.length + nextMatch.index
47
+ : changelogContent.length;
48
+
49
+ const versionContent = changelogContent.substring(startIndex + title.length, endIndex).trim();
50
+
51
+ // Parse sections (### headers)
52
+ const sections = [];
53
+ const sectionRegex = /^### (.+)$/gm;
54
+ let lastIndex = 0;
55
+ let currentSection = null;
56
+ let sectionMatch;
57
+
58
+ while ((sectionMatch = sectionRegex.exec(versionContent)) !== null) {
59
+ if (currentSection) {
60
+ currentSection.content = versionContent.substring(lastIndex, sectionMatch.index).trim();
61
+ sections.push(currentSection);
62
+ }
63
+ currentSection = { header: sectionMatch[1], content: '' };
64
+ lastIndex = sectionMatch.index + sectionMatch[0].length;
65
+ }
66
+
67
+ if (currentSection) {
68
+ currentSection.content = versionContent.substring(lastIndex).trim();
69
+ sections.push(currentSection);
70
+ }
71
+
72
+ // If no ### sections, treat entire content as one section
73
+ if (sections.length === 0 && versionContent) {
74
+ sections.push({ header: 'Changes', content: versionContent });
75
+ }
76
+
77
+ return { found: true, title, sections };
78
+ }
79
+
80
+ /**
81
+ * Format and display a section's content
82
+ * @param {string} content - Section content
83
+ * @param {function} w - White chalk function
84
+ * @param {function} c - Cyan chalk function
85
+ */
86
+ function displaySectionContent(content, w, c) {
87
+ const lines = content.split('\n');
88
+
89
+ for (const line of lines) {
90
+ // Skip code blocks for cleaner display
91
+ if (line.startsWith('```')) continue;
92
+
93
+ // Handle bullet points
94
+ if (line.startsWith('- ') || line.startsWith('* ')) {
95
+ console.log(c(' •') + w(' ' + line.substring(2)));
96
+ }
97
+ // Handle sub-headers (####)
98
+ else if (line.startsWith('#### ')) {
99
+ console.log('');
100
+ console.log(w(' ' + line.substring(5)));
101
+ }
102
+ // Handle code in backticks (command examples)
103
+ else if (line.includes('`') && !line.startsWith('```')) {
104
+ // Display inline code lines
105
+ const formatted = line.replace(/`([^`]+)`/g, chalk.cyan('$1'));
106
+ console.log(w(' ' + formatted));
107
+ }
108
+ // Skip empty lines at start, show others
109
+ else if (line.trim()) {
110
+ console.log(w(' ' + line));
111
+ }
112
+ }
113
+ }
2
114
 
3
115
  /**
4
116
  * Whats-new command - show recent changes and features
@@ -6,14 +118,78 @@ const { showInfo, getVersion } = require('../utils/command-helpers.js');
6
118
  */
7
119
  module.exports = function(args) {
8
120
  const version = getVersion();
121
+ const w = chalk.bold.white;
122
+ const g = chalk.green;
123
+ const c = chalk.cyan;
124
+ const y = chalk.yellow;
125
+
126
+ // ASCII Art Banner
127
+ console.log(w(`
128
+ ██████╗ ███████╗██╗███████╗
129
+ ██╔══██╗██╔════╝██║██╔════╝
130
+ ██████╔╝█████╗ ██║███████╗
131
+ ██╔══██╗██╔══╝ ██║╚════██║
132
+ ██║ ██║███████╗██║███████║
133
+ ╚═╝ ╚═╝╚══════╝╚═╝╚══════╝
134
+ `));
9
135
 
10
- showInfo(`REIS v${version} - What's New`);
11
- showInfo('');
12
- showInfo('• Initial release');
13
- showInfo(' 29 commands for systematic development');
14
- showInfo(' Parallel subagent execution (up to 4 simultaneous)');
15
- showInfo('• Fresh context per task (200k tokens)');
16
- showInfo('• Transformed from GSD for Rovo Dev');
17
- showInfo('');
18
- showInfo('Full documentation: ~/.rovodev/reis/README.md');
136
+ console.log(w(' REIS - Roadmap Execution & Implementation System'));
137
+ console.log(w(' Specially designed for Atlassian Rovo Dev'));
138
+ console.log('');
139
+ console.log(w('● What\'s New in v' + version));
140
+ console.log(w(' ' + '─'.repeat(18 + version.length)));
141
+ console.log('');
142
+
143
+ // Parse changelog for current version
144
+ const changelog = parseChangelog(version);
145
+
146
+ if (!changelog.found) {
147
+ // Fallback if version not found in changelog
148
+ console.log(y(' No changelog entry found for v' + version));
149
+ console.log('');
150
+ console.log(w(' This may be a development version or the changelog'));
151
+ console.log(w(' hasn\'t been updated yet.'));
152
+ console.log('');
153
+ console.log(w(' For full documentation:'));
154
+ console.log(c(' ~/.rovodev/reis/README.md'));
155
+ console.log('');
156
+ return;
157
+ }
158
+
159
+ // Display sections (limit to first 3 major sections for readability)
160
+ const maxSections = 3;
161
+ const displaySections = changelog.sections.slice(0, maxSections);
162
+
163
+ for (const section of displaySections) {
164
+ console.log(g(' ' + section.header));
165
+ console.log('');
166
+
167
+ // Limit content display for very long sections
168
+ const contentLines = section.content.split('\n');
169
+ const maxLines = 20;
170
+ const truncatedContent = contentLines.slice(0, maxLines).join('\n');
171
+
172
+ displaySectionContent(truncatedContent, w, c);
173
+
174
+ if (contentLines.length > maxLines) {
175
+ console.log('');
176
+ console.log(y(' ... and more'));
177
+ }
178
+ console.log('');
179
+ }
180
+
181
+ if (changelog.sections.length > maxSections) {
182
+ console.log(y(` + ${changelog.sections.length - maxSections} more sections`));
183
+ console.log('');
184
+ }
185
+
186
+ // Footer
187
+ console.log(w(' ───────────────────────────────────────────────────────'));
188
+ console.log('');
189
+ console.log(w(' Full changelog:'));
190
+ console.log(c(' ~/.rovodev/reis/CHANGELOG.md'));
191
+ console.log('');
192
+ console.log(w(' Documentation:'));
193
+ console.log(c(' ~/.rovodev/reis/README.md'));
194
+ console.log('');
19
195
  };
@@ -36,6 +36,14 @@ function showInfo(message) {
36
36
  console.log(chalk.cyan(message));
37
37
  }
38
38
 
39
+ /**
40
+ * Display a warning message
41
+ * @param {string} message - The warning message
42
+ */
43
+ function showWarning(message) {
44
+ console.log(chalk.yellow(`⚠ ${message}`));
45
+ }
46
+
39
47
  /**
40
48
  * Get the package version
41
49
  * @returns {string} - The version string
@@ -77,6 +85,7 @@ module.exports = {
77
85
  showError,
78
86
  showSuccess,
79
87
  showInfo,
88
+ showWarning,
80
89
  getVersion,
81
90
  checkPlanningDir,
82
91
  validatePhaseNumber
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravirei/reis",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Roadmap Execution & Implementation System v2.0 - Wave-based execution with checkpoints, metrics, and visualization for Atlassian Rovo Dev",
5
5
  "main": "lib/index.js",
6
6
  "bin": {