Data-driven sprint retrospectives that live where the work happens. IntelliJ-native plugin + real-time web dashboard for agile engineering teams.
Hack Košice 2026 — JetBrains Plugin Track.
RetroScope turns the IDE into a continuous, ambient data collector for retro-relevant moments, and turns the retrospective itself into a live, code-linked session on a shared web dashboard. Flags attach to actual code elements (methods, classes, files) via PSI — not free-form text — and action items become first-class entities the system tracks across sprints.
Full design: CLAUDE.md.
Every agile team runs retrospectives. Almost every team runs them badly. Action items are vague, nobody remembers what hurt two weeks later, and there's no way to tell whether last sprint's decisions improved anything. Retro tools live in Miro, FigJam, or Jira — completely disconnected from the code the retro is supposed to be about.
RetroScope fills a genuine gap. YouTrack (JetBrains' own product) has sprint management but zero retrospective support. No plugin in the JetBrains Marketplace covers this. JetBrains' own engineering team blogs about running retros manually with sticky notes.
Flag in 2 seconds, never leave the editor. Alt+Enter on any line, pick a category, done. No switching to Miro, no opening a browser, no trying to remember what bothered you two weeks later. You flag it when it happens.
Your flags have code context. When you flag "this payment handler is a mess", the flag points at the actual method via PSI — not a vague sticky note. During the retro, everyone sees what you're talking about, not just that you're frustrated.
Previous retro commitments are in your tool window. You don't need to dig through Confluence to find what the team agreed to fix. Open the Retro panel in IntelliJ — action items from last sprint are right there while you code. Close them with a note when done.
Gutter icons and inlay hints show team pain. You're about to edit a method and see "3 teammates flagged friction here" as an inlay hint. That's not a code smell detector — it's human signal from your team.
Build fails? Commit something tricky? The plugin nudges: "Flag this moment?" One click. That frustration gets captured for the retro instead of forgotten by Friday.
You see what actually happened, not what people remember. Flags are captured throughout the sprint in real-time. By the time you open the retro board, the data is already there — no more "so... what went well?" silence.
Guided retro session, not a blank board. Two steps: evaluate the flag board (wins, friction, improvements, learnings — already populated), then manage action items. No more facilitating a Miro board with 40 empty sticky note zones.
Action items are trackable across sprints. You created "Improve code review turnaround" last retro. This sprint, the dashboard shows whether it was closed, who resolved it, and what note they left. You can finally answer: did our retros actually change anything?
Hotspot visibility without asking. The dashboard shows which files have the most friction flags. You don't need to ask "where are we struggling?" — the heatmap tells you. That's sprint planning intel for free.
Vocabulary your team actually uses. Some teams say "Blocker", others say "Frustrated", others want emoji. You pick the vocabulary; the system maps everything to four universal categories. The retro speaks your team's language.
No new tool to onboard. Devs flag from IntelliJ — they're already there. You facilitate from the web dashboard. Nobody installs a new app or learns a new workflow. Adoption is near-zero-friction because RetroScope meets each role where they already work.
- Developer flags friction on a method in IntelliJ (Alt+Enter, 2 seconds)
- Flag appears on the web dashboard instantly (WebSocket, ~100ms)
- Team opens the retro session — board shows all flags organized by category
- Action items created, linked to flags, with resolution tracking
- Next sprint — developer sees those commitments in their IDE tool window
- Dashboard shows "Action items from last retro" — close them as you go
One unbroken narrative: capture, discuss, commit, follow through.
hackkosice2026/
├── apps/
│ ├── plugin/ # JetBrains IntelliJ plugin (Kotlin + IntelliJ Platform SDK)
│ ├── web/ # Web dashboard (React 18 + Vite + TypeScript + Tailwind)
│ └── backend/ # API server (Node.js + Fastify + WebSocket + Drizzle ORM)
├── packages/
│ ├── protocol/ # Shared WS + REST Zod schemas — source of truth for contracts
│ └── types/ # Shared TypeScript types
├── infra/
│ ├── docker-compose.yml # Postgres 16 + Redis 7 for local dev
│ └── migrations/ # SQL migrations
├── package.json # pnpm workspaces root
├── pnpm-workspace.yaml
├── turbo.json # Turborepo pipeline
├── settings.gradle.kts # Gradle root (plugin only)
└── tsconfig.base.json # Shared TS compiler options
@retroscope/web@retroscope/backend@retroscope/protocol@retroscope/types
- Node.js 20+ and pnpm 9+ (
brew install pnpm/npm i -g pnpm) - JDK 17 (for the IntelliJ plugin)
- Docker (for Postgres + Redis via docker compose)
- Gradle CLI — only for first-time wrapper bootstrap. Any 8.x works.
- Google OAuth2 client credentials (client ID + secret). Two clients:
one "Web application" (for the SPA) and one "TVs and Limited Input devices"
(for the plugin's device flow). See
infra/README.md. - Anthropic API key (optional, for AI-generated retro agenda)
Open 4 terminals.
# From repo root
pnpm install
# Start Postgres + Redis
docker compose -f infra/docker-compose.yml up -d
# Wait ~5 seconds for Postgres to be healthy, then run migrations
pnpm --filter @retroscope/backend db:migrate# First time: copy env + fill in secrets
cp apps/backend/.env.example apps/backend/.env
# Edit apps/backend/.env and set:
# GOOGLE_OAUTH_CLIENT_ID=<from Google Cloud Console>
# GOOGLE_OAUTH_CLIENT_SECRET=<from Google Cloud Console>
# JWT_SECRET=<any 32+ random bytes>
# ANTHROPIC_API_KEY=<optional, for AI agenda>
pnpm --filter @retroscope/backend devThe backend listens on http://localhost:3001. Health probe:
curl http://localhost:3001/health → {"status":"ok"}.
# First time: copy env + fill in Google client ID (must match backend)
cp apps/web/.env.example apps/web/.env
# Edit apps/web/.env:
# VITE_GOOGLE_CLIENT_ID=<same as backend's GOOGLE_OAUTH_CLIENT_ID>
pnpm --filter @retroscope/web devThe web app opens at http://localhost:5173. Sign in with Google, land on the
dashboard.
cd apps/plugin
# ONE-TIME: generate the Gradle wrapper
gradle wrapper --gradle-version 8.10
# Launch a sandboxed IntelliJ IDEA Community with the plugin loaded
./gradlew runIdeInside the sandbox IDE:
- Open any project (or create one).
- Tools → Sign in to RetroScope… — browser opens, Google login.
- Copy the user code from the plugin dialog into the web page at
http://localhost:5173/device(already open). Approve. - Plugin dialog closes. The right-hand RetroScope tool window flips to "Signed in as …" and the status line says "Connected".
- Settings → Tools → RetroScope — set your Team ID (create a team from the web admin first if you don't have one).
- In the IDE, put the caret inside any function.
Alt+Enter→ Flag with RetroScope… → pick Friction.- Within ~200 ms, the flag shows up on the web dashboard.
- On the web dashboard, open Retrospective → create an action item linked to that flag.
- Back in the IDE, the tool window shows the action item count update.
Plugin features: see apps/plugin/README.md.
Web features: see apps/web/ (dashboard, admin, retro board).
Backend features: see apps/backend/README.md (if present) or CLAUDE.md §6.3.
| Command | Runs |
|---|---|
pnpm install |
Install workspace deps |
pnpm dev |
Backend + web in parallel (Turborepo) |
pnpm build |
Build everything (web + backend) |
pnpm typecheck |
TS typecheck across all workspaces |
pnpm --filter @retroscope/backend db:migrate |
Apply SQL migrations |
cd apps/plugin && ./gradlew runIde |
Sandbox IDE with plugin |
cd apps/plugin && ./gradlew buildPlugin |
Produces distributable .zip |
docker compose -f infra/docker-compose.yml down -v |
Nuke local DB & Redis |
Each app has its own .env.example:
apps/backend/.env— Postgres URL, Redis URL, JWT secret, Google OAuth creds, Anthropic keyapps/web/.env— Backend URL, Google client ID
pnpm devdoesn't start one of the apps — check the relevant.envfile exists and is filled in.- Google OAuth callback fails — verify the redirect URI matches
http://localhost:5173/auth/callbackin both the Google Console and the backend.env. - Plugin can't reach backend — IntelliJ sandbox uses a different user dir; confirm Backend URL in Settings → Tools → RetroScope.
- WebSocket keeps reconnecting — usually a bad JWT or stopped backend. Sign out + sign in again from the IDE.
- Docker Postgres not healthy —
docker compose logs postgres; confirm port 5432 isn't already in use.
All three surfaces implemented. Plugin has all 12 features (F1–F12). Web dashboard includes auth, landing, dashboard, retrospective board, admin (team / vocabulary / sprints), device approval, settings. Backend covers REST (auth, teams, sprints, flags, action items, vocabularies), WebSocket with Redis pub/sub, Google OAuth2 (PKCE + device flow), JWT sessions, Drizzle over Postgres, and an AI agenda stub ready for the Anthropic call.
Ready to iterate toward demo.
Hayat Tofik Erik Novysedlák Martin Novysedlák