agentvibes 4.6.3 → 4.6.5

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/RELEASE_NOTES.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # AgentVibes Release Notes
2
2
 
3
+ ## šŸ”§ v4.6.5 — Patch Release
4
+
5
+ **Release Date:** April 2026
6
+
7
+ ### Improvements
8
+
9
+ - **TUI non-interactive hint** — Installer header now shows a two-tone hint on row 2: `Skip this TUI?` (white) + `npx agentvibes install --non-interactive` (yellow), with a sponsor link on the right. Useful for CI/CD pipelines and scripted installs.
10
+
11
+ - **`--non-interactive` routing fix** — `npx agentvibes install --non-interactive` (and `--yes`/`-y`) now correctly bypasses the TUI and routes directly to the CLI installer. Previously the TUI would still launch.
12
+
13
+ - **Sponsor link in TUI header** — Row 2 of the header now shows a `ā™” Sponsor this Developer github.com/sponsors/paulpreibisch` link on the right side, alongside the non-interactive hint on the left.
14
+
15
+ - **Consistent line endings via `.gitattributes`** — Added `.gitattributes` to enforce `LF` for shell scripts, JS, JSON, and markdown, and `CRLF` for PowerShell scripts. Prevents spurious `bin/` file modifications showing as dirty on Windows due to CRLF noise.
16
+
17
+ - **`bin/` execute bits restored** — Re-indexed `bin/agent-vibes`, `bin/agentvibes-voice-browser.js`, `bin/mcp-server.js`, and `bin/test-bmad-pr` to ensure consistent line endings; verified all four retain `chmod +x` (`100755` mode).
18
+
19
+ - **Standardized release process** — `/release` command now documents a privacy scan checkpoint: confirm no API keys, no personal info (email, phone, personal port numbers), before committing. CI must be green before releasing.
20
+
21
+ ### User Impact
22
+
23
+ - No functional changes — infrastructure and tooling improvements only
24
+
25
+ ---
26
+
27
+ ## šŸ› v4.6.4 — Patch Release
28
+
29
+ **Release Date:** April 2026
30
+
31
+ ### Bug Fixes
32
+
33
+ - **CI green on macOS** — `mktemp` with a file extension suffix (e.g. `tts-XXXXXX.wav`) works on Linux (GNU mktemp) but silently fails on macOS (BSD mktemp), which requires `XXXXXX` to be at the very end of the template. Fixed all 12 occurrences across `play-tts-piper.sh`, `play-tts-soprano.sh`, `play-tts-macos.sh`, and `audio-processor.sh` by creating the temp file without extension then renaming to add `.wav`/`.aiff`.
34
+
35
+ - **macOS path symlink in test 213** — macOS transparently resolves `/var/folders/...` to `/private/var/folders/...` via a symlink. The voice-manager replay test was comparing against the unresolved path and failing. Fixed by using `cd && pwd` to get the real path before asserting.
36
+
37
+ - **`bmad-party-speak.sh` execute permission** — The bash hook lost its `+x` bit, causing `party mode scripts ship with the package` CI test to fail. Restored `100755` mode via `git update-index`.
38
+
39
+ ### User Impact
40
+
41
+ - No user-facing changes — CI infrastructure fixes only
42
+
43
+ ---
44
+
3
45
  ## šŸ› v4.6.3 — Patch Release
4
46
 
5
47
  **Release Date:** April 2026
package/bin/agentvibes.js CHANGED
@@ -67,6 +67,11 @@ export function resolveStartTab(args, configService) {
67
67
  const cmd = args[0];
68
68
 
69
69
  if (cmd === 'install') {
70
+ // Non-interactive flags → delegate to CLI installer (src/installer.js), not TUI
71
+ const isNonInteractive = args.includes('--non-interactive') || args.includes('--yes') || args.includes('-y');
72
+ if (isNonInteractive) {
73
+ return { cliInstall: true, args: args.slice(1) };
74
+ }
70
75
  return { startTab: 'install' };
71
76
  }
72
77
 
@@ -139,6 +144,16 @@ if (_argv1 === _thisFile) {
139
144
  process.exit(1);
140
145
  }
141
146
 
147
+ if (result.cliInstall) {
148
+ // Route to CLI installer for non-interactive installs
149
+ const installerPath = path.resolve(__dirname, '..', 'src', 'installer.js');
150
+ execFileSync(process.execPath, [installerPath, 'install', ...result.args], {
151
+ stdio: 'inherit',
152
+ shell: false,
153
+ });
154
+ process.exit(0);
155
+ }
156
+
142
157
  launchConsole({ startTab: result.startTab }).catch(err => {
143
158
  process.stderr.write(`Failed to launch AgentVibes console: ${err.message}\n`);
144
159
  process.exit(1);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "agentvibes",
4
- "version": "4.6.3",
4
+ "version": "4.6.5",
5
5
  "description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code, Claude Desktop (via MCP), and Clawdbot with multi-provider support.",
6
6
  "homepage": "https://agentvibes.org",
7
7
  "keywords": [
@@ -151,7 +151,7 @@ export class AgentVibesConsole {
151
151
  top: 0,
152
152
  left: 0,
153
153
  width: '100%',
154
- height: 3,
154
+ height: 4,
155
155
  tags: false,
156
156
  wrap: false,
157
157
  scrollable: false,
@@ -192,6 +192,28 @@ export class AgentVibesConsole {
192
192
  style: { bg: COLORS.headerBg },
193
193
  });
194
194
 
195
+ // Row 2: non-interactive mode hint — direct screen child (like tab items) so tags render correctly
196
+ blessed.text({
197
+ parent: this.screen,
198
+ top: 2,
199
+ left: 2,
200
+ shrink: true,
201
+ tags: true,
202
+ content: `{white-fg}Skip this TUI?{/white-fg} {yellow-fg}npx agentvibes install --non-interactive{/yellow-fg}`,
203
+ style: { bg: COLORS.headerBg },
204
+ });
205
+
206
+ // Row 2 (right): sponsor message
207
+ blessed.text({
208
+ parent: this.screen,
209
+ top: 2,
210
+ right: 2,
211
+ shrink: true,
212
+ tags: true,
213
+ content: `{magenta-fg}\u2661{/magenta-fg} {white-fg}Sponsor this Developer{/white-fg} {magenta-fg}github.com/sponsors/paulpreibisch{/magenta-fg}`,
214
+ style: { bg: COLORS.headerBg },
215
+ });
216
+
195
217
  // Row 1 (right): Active settings summary [provider][voice][effects][music]
196
218
  this._headerStatusText = blessed.text({
197
219
  parent: this.headerBox,
@@ -281,17 +303,17 @@ export class AgentVibesConsole {
281
303
  // Background strip — screen child so blessed uses absolute coordinates directly.
282
304
  // Tab items are ALSO screen children (not children of tabBarBox) to avoid the
283
305
  // WSL/Windows Terminal parent-relative positioning bug that renders them 1 row
284
- // too high (at row 2 instead of row 3), producing a ghost duplicate tab bar.
306
+ // too high (at row 3 instead of row 4), producing a ghost duplicate tab bar.
285
307
  this.tabBarBox = blessed.box({
286
308
  parent: this.screen,
287
- top: 3,
309
+ top: 4,
288
310
  left: 0,
289
311
  width: '100%',
290
312
  height: 1,
291
313
  style: { bg: COLORS.tabBarBg },
292
314
  });
293
315
 
294
- // One box per tab — direct screen children at absolute top:3. No tag parsing, no wrapping.
316
+ // One box per tab — direct screen children at absolute top:4. No tag parsing, no wrapping.
295
317
  this._tabItems = {};
296
318
  this._tabItemXOffsets = {}; // track x positions for label refresh
297
319
  let xOffset = 1;
@@ -302,7 +324,7 @@ export class AgentVibesConsole {
302
324
  const text = ` [${shortcutKey}] ${label} `;
303
325
  const el = blessed.box({
304
326
  parent: this.screen,
305
- top: 3,
327
+ top: 4,
306
328
  left: xOffset,
307
329
  width: text.length,
308
330
  height: 1,
@@ -318,14 +340,14 @@ export class AgentVibesConsole {
318
340
  xOffset += text.length + 1; // 1-space gap between tabs
319
341
  }
320
342
 
321
- // Right-aligned Quit item — direct screen child at absolute top:3
343
+ // Right-aligned Quit item — direct screen child at absolute top:4
322
344
  const _quitText = ' [Q] Quit ';
323
345
  const _quitBase = _quitText;
324
346
  const _quitBlock = _quitText.slice(0, -1) + 'ā–ˆ';
325
347
  let _quitInterval = null;
326
348
  this._quitItem = blessed.box({
327
349
  parent: this.screen,
328
- top: 3,
350
+ top: 4,
329
351
  right: 1,
330
352
  width: _quitText.length,
331
353
  height: 1,
@@ -532,12 +554,12 @@ export class AgentVibesConsole {
532
554
  }
533
555
 
534
556
  // ---------------------------------------------------------------------------
535
- // Private: Content area (rows 4..N-1) — tab components mount here
557
+ // Private: Content area (rows 5..N-1) — tab components mount here
536
558
 
537
559
  _createContentArea() {
538
560
  // bottom: 2 reserves 2 rows at the bottom: context footer (story 6.3) + GitHub footer
539
561
  this.contentArea = blessed.box({
540
- top: 4,
562
+ top: 5,
541
563
  left: 0,
542
564
  width: '100%',
543
565
  bottom: 2,
@@ -747,18 +769,18 @@ export class AgentVibesConsole {
747
769
  this.screen.render = () => {};
748
770
 
749
771
  try {
750
- // Nuclear clear: wipe the content area (row 4+) to remove stale cell content
751
- // from the previous tab. Start at row 4 — header (0-2) and tab bar (3) are
772
+ // Nuclear clear: wipe the content area (row 5+) to remove stale cell content
773
+ // from the previous tab. Start at row 5 — header (0-3) and tab bar (4) are
752
774
  // static widgets that don't need clearing; wiping them causes the double
753
- // tab bar artifact (row 2 of header shows tab bar ghost from prior render).
775
+ // tab bar artifact (row 3 of header shows tab bar ghost from prior render).
754
776
  // blessed's render loop never resets the `lines` buffer before rendering
755
777
  // (see: blessed/lib/widgets/screen.js line 733, commented-out clear).
756
- this.screen.clearRegion(0, this.screen.cols, 4, this.screen.rows - 2);
778
+ this.screen.clearRegion(0, this.screen.cols, 5, this.screen.rows - 2);
757
779
 
758
780
  // Force-invalidate olines for the entire visible area (rows 0..rows-3).
759
- // Includes header rows 0-1 so the branded header is always redrawn on
781
+ // Includes header rows 0-3 so the branded header is always redrawn on
760
782
  // tab switches — prevents corruption from persisting across tabs.
761
- // Row 2 (header bottom), row 3 (tab bar) and content rows accumulate
783
+ // Row 3 (header bottom), row 4 (tab bar) and content rows accumulate
762
784
  // ghost rendering artifacts — draw() skips them when lines==olines even
763
785
  // though the terminal still shows stale chars from earlier renders.
764
786
  // Setting attr=-1 is impossible for any real cell, so draw() is forced
@@ -772,13 +794,13 @@ export class AgentVibesConsole {
772
794
  orow.dirty = true;
773
795
  }
774
796
 
775
- // Row 2 (header bottom) is never dirty after draw 1 — its content (headerBg+
797
+ // Row 3 (header bottom) is never dirty after draw 1 — its content (headerBg+
776
798
  // spaces) never changes so element.render() never marks it dirty. The olines
777
- // invalidation above sets olines[2][c][0]=-1, but draw() only compares cells
799
+ // invalidation above sets olines[3][c][0]=-1, but draw() only compares cells
778
800
  // when lines[r].dirty is true; a false dirty flag skips the entire row without
779
801
  // ever consulting olines. Force-mark it dirty so draw() emits the explicit
780
- // cup(3,1)+headerBg+spaces sequence and overwrites any ghost terminal content.
781
- if (this.screen.lines?.[2]) this.screen.lines[2].dirty = true;
802
+ // cup(4,1)+headerBg+spaces sequence and overwrites any ghost terminal content.
803
+ if (this.screen.lines?.[3]) this.screen.lines[3].dirty = true;
782
804
 
783
805
  // Update tab bar, footer, and header status inside suppression — no intermediate render.
784
806
  this._updateTabBar(tabId);
@@ -227,7 +227,7 @@ ${_tl('bmadDesc')}
227
227
 
228
228
  const box = blessed.box({
229
229
  parent: screen,
230
- top: 4,
230
+ top: 5,
231
231
  left: 0,
232
232
  width: '100%',
233
233
  bottom: 2,
@@ -160,7 +160,7 @@ export function createHelpTab(screen, services) {
160
160
 
161
161
  const box = blessed.box({
162
162
  parent: screen,
163
- top: 4,
163
+ top: 5,
164
164
  left: 0,
165
165
  width: '100%',
166
166
  bottom: 2,
@@ -166,7 +166,7 @@ export function createInstallTab(screen, services) {
166
166
 
167
167
  const box = blessed.box({
168
168
  parent: screen,
169
- top: 4,
169
+ top: 5,
170
170
  left: 0,
171
171
  width: '100%',
172
172
  bottom: 2,
@@ -284,7 +284,7 @@ export function createMusicTab(screen, services) {
284
284
 
285
285
  const box = blessed.box({
286
286
  parent: screen,
287
- top: 4,
287
+ top: 5,
288
288
  left: 0,
289
289
  width: '100%',
290
290
  bottom: 2,
@@ -132,7 +132,7 @@ export function createReadmeTab(screen, services) {
132
132
 
133
133
  const box = blessed.box({
134
134
  parent: screen,
135
- top: 4,
135
+ top: 5,
136
136
  left: 0,
137
137
  width: '100%',
138
138
  bottom: 2,
@@ -790,7 +790,7 @@ export function createReceiverTab(screen, services) {
790
790
 
791
791
  const box = blessed.box({
792
792
  parent: screen,
793
- top: 4,
793
+ top: 5,
794
794
  left: 0,
795
795
  width: '100%',
796
796
  bottom: 2,
@@ -751,7 +751,7 @@ export function createSettingsTab(screen, services) {
751
751
 
752
752
  const box = blessed.box({
753
753
  parent: screen,
754
- top: 4, // Below header (row 0-2) + tab bar (row 3)
754
+ top: 5, // Below header (rows 0-3) + tab bar (row 4)
755
755
  left: 0,
756
756
  width: '100%',
757
757
  bottom: 2, // Above context footer + GitHub footer
@@ -493,7 +493,7 @@ export function createVoicesTab(screen, services) {
493
493
 
494
494
  const box = blessed.box({
495
495
  parent: screen,
496
- top: 4,
496
+ top: 5,
497
497
  left: 0,
498
498
  width: '100%',
499
499
  bottom: 2,
package/src/installer.js CHANGED
@@ -2669,25 +2669,54 @@ function showWelcome() {
2669
2669
 
2670
2670
  /**
2671
2671
  * Display latest release information box
2672
- * Shown during install and update commands
2672
+ * Reads the first section from RELEASE_NOTES.md so it's always current.
2673
+ * Falls back to a minimal static string if the file is missing.
2673
2674
  */
2674
2675
  function getReleaseInfoBoxen() {
2675
- return chalk.cyan.bold('šŸ“¦ AgentVibes v4.0.0 - Interactive Console & Voice Explorer\n\n') +
2676
- chalk.green.bold('šŸŽ™ļø WHAT\'S NEW:\n\n') +
2677
- chalk.cyan('Major release with a full interactive TUI console, voice browser with 914+ voices,\n') +
2678
- chalk.cyan('and comprehensive platform support. Includes 58 security fixes, reliable TTS hooks,\n') +
2679
- chalk.cyan('and support for Windows, macOS, Android/Termux, and SSH-remote audio.\n\n') +
2680
- chalk.green.bold('✨ KEY HIGHLIGHTS:\n\n') +
2681
- chalk.gray(' šŸ–„ļø Interactive TUI Console - Settings, Voices, Music tabs with live preview\n') +
2682
- chalk.gray(' šŸŽ¤ Voice Browser - Browse and preview 914+ Piper TTS voices\n') +
2683
- chalk.gray(' šŸ”§ Reliable TTS Hooks - JSON context injection, auto git-init\n') +
2684
- chalk.gray(' šŸŒ Multi-Platform - Windows, macOS, Android/Termux, SSH-remote\n') +
2685
- chalk.gray(' šŸ” Security Hardened - 58 issues fixed, 180+ security tests\n\n') +
2686
- chalk.gray('šŸ“– Full Release Notes: RELEASE_NOTES.md\n') +
2687
- chalk.gray('🌐 Website: https://agentvibes.org\n') +
2688
- chalk.gray('šŸ“¦ Repository: https://github.com/paulpreibisch/AgentVibes\n\n') +
2689
- chalk.gray('Co-created by Paul Preibisch with Claude AI\n') +
2690
- chalk.gray('Copyright Ā© 2026 Paul Preibisch | Apache-2.0 License');
2676
+ try {
2677
+ const notesPath = path.join(__dirname, '..', 'RELEASE_NOTES.md');
2678
+ const raw = fsSync.readFileSync(notesPath, 'utf8');
2679
+ const lines = raw.split('\n');
2680
+
2681
+ // Find the first ## heading (latest release section)
2682
+ const startIdx = lines.findIndex(l => l.startsWith('## '));
2683
+ if (startIdx < 0) return '';
2684
+
2685
+ // Collect lines until the next ## heading (or end of file)
2686
+ const sectionLines = [];
2687
+ for (let i = startIdx; i < lines.length; i++) {
2688
+ if (i !== startIdx && lines[i].startsWith('## ')) break;
2689
+ sectionLines.push(lines[i]);
2690
+ }
2691
+
2692
+ // Strip markdown syntax from a line for plain display
2693
+ const stripMd = (s) => s
2694
+ .replace(/^#{1,6}\s*/, '') // ## headings
2695
+ .replace(/\*\*([^*]+)\*\*/g, '$1') // **bold**
2696
+ .replace(/`([^`]+)`/g, '$1') // `code`
2697
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1'); // [text](url)
2698
+
2699
+ // Render: heading in cyan, bullets as gray, skip blank/hr lines at end
2700
+ return sectionLines
2701
+ .map((line, i) => {
2702
+ if (i === 0) return chalk.cyan.bold(stripMd(line));
2703
+ if (line.startsWith('### ')) return chalk.green.bold(stripMd(line));
2704
+ if (line.startsWith('- ')) return chalk.gray(' ' + stripMd(line));
2705
+ if (line === '---') return '';
2706
+ return chalk.gray(stripMd(line));
2707
+ })
2708
+ .join('\n')
2709
+ .trimEnd() + '\n\n' +
2710
+ chalk.gray('šŸ“– Full Release Notes: RELEASE_NOTES.md\n') +
2711
+ chalk.gray('🌐 Website: https://agentvibes.org\n') +
2712
+ chalk.gray('šŸ“¦ Repository: https://github.com/paulpreibisch/AgentVibes\n\n') +
2713
+ chalk.gray('Co-created by Paul Preibisch with Claude AI\n') +
2714
+ chalk.gray('Copyright Ā© 2026 Paul Preibisch | Apache-2.0 License');
2715
+ } catch {
2716
+ return chalk.cyan.bold(`šŸ“¦ AgentVibes v${VERSION}\n`) +
2717
+ chalk.gray('šŸ“– Full Release Notes: RELEASE_NOTES.md\n') +
2718
+ chalk.gray('🌐 Website: https://agentvibes.org');
2719
+ }
2691
2720
  }
2692
2721
 
2693
2722
  /**
@@ -4126,6 +4155,12 @@ async function checkAndInstallPiperWindows(targetDir, options) {
4126
4155
  return;
4127
4156
  }
4128
4157
 
4158
+ // Also check PATH — piper may be installed outside the standard location
4159
+ if (isPiperInstalled()) {
4160
+ console.log(chalk.green('āœ“ Piper TTS is already available in PATH\n'));
4161
+ return;
4162
+ }
4163
+
4129
4164
  spinner.start('Downloading Piper TTS for Windows...');
4130
4165
  try {
4131
4166
  await fs.mkdir(piperDir, { recursive: true });
@@ -4237,7 +4272,7 @@ async function handleMcpConfiguration(targetDir, options) {
4237
4272
  chalk.white('to your ') + chalk.cyan('mcpServers') + chalk.white(' section:'),
4238
4273
  {
4239
4274
  padding: 1,
4240
- margin: 1,
4275
+ margin: { top: 1, bottom: 1, left: 0, right: 0 },
4241
4276
  borderStyle: 'round',
4242
4277
  borderColor: 'yellow',
4243
4278
  }
@@ -4260,7 +4295,7 @@ async function handleMcpConfiguration(targetDir, options) {
4260
4295
  chalk.cyan.bold('https://github.com/paulpreibisch/AgentVibes#mcp-server'),
4261
4296
  {
4262
4297
  padding: 1,
4263
- margin: 1,
4298
+ margin: { top: 1, bottom: 1, left: 0, right: 0 },
4264
4299
  borderStyle: 'round',
4265
4300
  borderColor: 'cyan',
4266
4301
  }
@@ -4280,7 +4315,7 @@ async function handleMcpConfiguration(targetDir, options) {
4280
4315
  chalk.white('No ') + chalk.cyan('.mcp.json') + chalk.white(' found in this project.'),
4281
4316
  {
4282
4317
  padding: 1,
4283
- margin: 1,
4318
+ margin: { top: 1, bottom: 1, left: 0, right: 0 },
4284
4319
  borderStyle: 'round',
4285
4320
  borderColor: 'cyan',
4286
4321
  }
@@ -4315,12 +4350,15 @@ async function handleMcpConfiguration(targetDir, options) {
4315
4350
  chalk.green('The MCP server is now installed and ready to use!'),
4316
4351
  {
4317
4352
  padding: 1,
4318
- margin: 1,
4353
+ margin: { top: 1, bottom: 1, left: 0, right: 0 },
4319
4354
  borderStyle: 'double',
4320
4355
  borderColor: 'green',
4321
4356
  }
4322
4357
  )
4323
4358
  );
4359
+
4360
+ // Show the installed JSON so users can see exactly what was written
4361
+ console.log(chalk.gray(JSON.stringify(mcpConfig, null, 2)) + '\n');
4324
4362
  } catch (error) {
4325
4363
  console.log(chalk.red(`\nāœ— Failed to create .mcp.json: ${error.message}`));
4326
4364
  console.log(chalk.gray(' You can create it manually with the config shown below.\n'));
@@ -4337,7 +4375,7 @@ async function handleMcpConfiguration(targetDir, options) {
4337
4375
  chalk.white('Create a ') + chalk.cyan('.mcp.json') + chalk.white(' file in your project with:'),
4338
4376
  {
4339
4377
  padding: 1,
4340
- margin: 1,
4378
+ margin: { top: 1, bottom: 1, left: 0, right: 0 },
4341
4379
  borderStyle: 'round',
4342
4380
  borderColor: 'cyan',
4343
4381
  }
@@ -4366,7 +4404,7 @@ async function handleMcpConfiguration(targetDir, options) {
4366
4404
  chalk.cyan.bold('https://github.com/paulpreibisch/AgentVibes#mcp-server'),
4367
4405
  {
4368
4406
  padding: 1,
4369
- margin: 1,
4407
+ margin: { top: 1, bottom: 1, left: 0, right: 0 },
4370
4408
  borderStyle: 'round',
4371
4409
  borderColor: 'cyan',
4372
4410
  }
@@ -5344,12 +5382,17 @@ Troubleshooting:
5344
5382
  await createDefaultBmadVoiceAssignmentsProactive(targetDir);
5345
5383
  await handleBmadIntegration(targetDir, { ...options, yes: true });
5346
5384
 
5347
- spinner.succeed(chalk.green('AgentVibes installed successfully!'));
5348
-
5349
5385
  if (options.nonInteractive || process.env.AGENT_VIBES_NON_INTERACTIVE === '1') {
5350
- console.log(`[AV] Installation complete`);
5351
5386
  console.log(`[AV] Provider: ${selectedProvider} | Location: ${targetDir}/.claude/ | Version: ${VERSION}`);
5352
- } else {
5387
+ }
5388
+
5389
+ console.log('');
5390
+ spinner.succeed(chalk.green('AgentVibes installed successfully!'));
5391
+ console.log('');
5392
+ console.log(chalk.magenta(' \u2661 Sponsor this Developer github.com/sponsors/paulpreibisch'));
5393
+ console.log('');
5394
+
5395
+ if (!(options.nonInteractive || process.env.AGENT_VIBES_NON_INTERACTIVE === '1')) {
5353
5396
  // Clean final summary
5354
5397
  console.log('');
5355
5398
  console.log(chalk.green.bold(' āœ… Installation Complete'));