ReviewOS

also looking at this

stacks/buddy

feat(events): one notification story — fire every declared event, trim setup to its real job

#1449
Merged glennmichael123 wants to merge refactor/setup-plugin-trim into main
14 files +308 -81
bin/cli.tsmodified+23-1
Changes to bin/cli.ts
@@ -18,6 +18,7 @@ import {
1818 parseDashboardActions,
1919 uncheckDashboardActions,
2020} from '../src/dashboard/dashboard-actions'
21import { emitEvent } from '../src/events'
2122import { manifestUpdates, parseManifest } from '../src/pr/pr-manifest'
2223import {
2324 analyzeProject,
@@ -404,7 +405,12 @@ cli
404405 }
405406 }
406407 else if (availablePlugins.length > 0 && options.nonInteractive) {
407 console.log(`\n🔌 Found ${availablePlugins.length} integration(s), skipping in non-interactive mode`)
408 // The docs promise setup-completion notifications; silently skipping
409 // them made that a lie in exactly the mode CI uses.
410 console.log(`\n🔌 Found ${availablePlugins.length} integration(s) — enabled for setup notifications`)
411 for (const plugin of availablePlugins) {
412 await pluginManager.loadPlugin(plugin)
413 }
408414 }
409415
410416 // Pre-flight checks
@@ -780,6 +786,7 @@ cli
780786 }
781787 catch (error) {
782788 logger.error('Scan failed:', error)
789 await emitEvent(config.notifications as Parameters<typeof emitEvent>[0], 'run.failed', { command: 'scan', error: error instanceof Error ? error.message : String(error) })
783790 process.exit(1)
784791 }
785792 })
@@ -840,6 +847,7 @@ cli
840847 }
841848 catch (error) {
842849 logger.error('Dashboard creation failed:', error)
850 await emitEvent(config.notifications as Parameters<typeof emitEvent>[0], 'run.failed', { command: 'dashboard', error: error instanceof Error ? error.message : String(error) })
843851 process.exit(1)
844852 }
845853 })
@@ -924,6 +932,7 @@ cli
924932 }
925933 catch (error) {
926934 logger.error('Update failed:', error)
935 await emitEvent(config.notifications as Parameters<typeof emitEvent>[0], 'run.failed', { command: 'update', error: error instanceof Error ? error.message : String(error) })
927936 process.exit(1)
928937 }
929938 })
@@ -1329,6 +1338,7 @@ cli
13291338 }
13301339 catch (error) {
13311340 logger.error('update-check failed:', error)
1341 await emitEvent(config.notifications as Parameters<typeof emitEvent>[0], 'run.failed', { command: 'update-check', error: error instanceof Error ? error.message : String(error) })
13321342 process.exit(1)
13331343 }
13341344 })
@@ -1400,6 +1410,7 @@ cli
14001410 }
14011411 catch (error) {
14021412 logger.error('fix-ci failed:', error)
1413 await emitEvent(config.notifications as Parameters<typeof emitEvent>[0], 'run.failed', { command: 'fix-ci', error: error instanceof Error ? error.message : String(error) })
14031414 process.exit(1)
14041415 }
14051416 })
@@ -1656,6 +1667,10 @@ cli
16561667 })
16571668
16581669 logger.success(`✅ ${status}`)
1670 await emitEvent(config.notifications as Parameters<typeof emitEvent>[0], 'review.completed', {
1671 number: Number.parseInt(prNumber, 10),
1672 findings: result?.findings.length ?? 0,
1673 })
16591674
16601675 // `--format` and `--fail-on` were accepted on this path and applied
16611676 // only on the local one, so a pull request review could not be
@@ -1759,6 +1774,7 @@ cli
17591774 }
17601775 catch (error) {
17611776 logger.error('Review failed:', error)
1777 await emitEvent(config.notifications as Parameters<typeof emitEvent>[0], 'run.failed', { command: 'review', error: error instanceof Error ? error.message : String(error) })
17621778 process.exit(1)
17631779 }
17641780 })
@@ -3164,6 +3180,12 @@ cli
31643180 logger.info(`${gateIcon(result)} ${result.name}: ${result.summary}`)
31653181
31663182 const blocking = summary.conclusion === 'failure'
3183 if (blocking) {
3184 await emitEvent(config.notifications as Parameters<typeof emitEvent>[0], 'gate.failed', {
3185 number,
3186 checks: results.filter(result => !result.passed).map(result => result.name),
3187 })
3188 }
31673189
31683190 if (options.dryRun || !supports(provider, 'checkRuns', 'createCheckRun')) {
31693191 logger.info(summary.summary)