Skip to content

feat: add wow features foundation + single-click packaging#8

Merged
Manish0Jha merged 36 commits intomainfrom
feat/wow-features-foundation
Apr 8, 2026
Merged

feat: add wow features foundation + single-click packaging#8
Manish0Jha merged 36 commits intomainfrom
feat/wow-features-foundation

Conversation

@Manish0Jha
Copy link
Copy Markdown
Contributor

Summary

  • Wow Features Foundation: Deja Vu alerts, Decision Replay, Session Storytelling, Blast Radius prediction, Developer Growth Tracker — full stack (Core models, Storage, Agents, API endpoints, CLI commands, Dashboard pages)
  • Single-Click Packaging: Electron tray app for daemon lifecycle management, package manager distribution (winget, Homebrew, APT), CI/CD pipeline for building and publishing packages

Key Changes

Wow Features (20 commits)

  • Core models: DejaVuAlert, DecisionChain, BlastRadius, GrowthModels, SessionSummary
  • Storage: SqliteAlertStore, SqliteDeadEndStore, SqliteSessionStore, SqliteGrowthStore, BlastRadiusCalculator, DecisionChainBuilder
  • Agents: DejaVuAgent, DecisionChainAgent, StorytellerAgent, GrowthAgent
  • API: Alert, BlastRadius, Replay, Growth, Session endpoints
  • CLI: alerts, blast, replay, growth, story commands
  • Dashboard: Alerts, BlastRadius, Replay, Growth, Sessions pages

Packaging (14 commits)

  • Electron tray app (packages/tray/) with health monitor, daemon manager, bootstrap orchestrator
  • CLI/tray coordination via tray.lock + stopped sentinel
  • electron-builder config for NSIS (Windows), DMG (macOS), .deb (Linux)
  • Package manager manifests: Homebrew formula, winget manifest, APT debian files
  • CI/CD workflow (package.yml) for Electron build + package manager publishing
  • Design spec and implementation plan in docs/superpowers/

Test plan

  • 135 .NET tests pass (xUnit) — agents, storage, capture, core, integration
  • 21 Electron tests pass (Jest) — health monitor, daemon manager, bootstrap
  • .NET build succeeds (dotnet build DevBrain.slnx)
  • TypeScript build succeeds (cd packages/tray && npm run build)
  • Manual: verify Electron tray app launches on Windows
  • Manual: verify electron-builder --dir produces unpacked app
  • CI: verify package.yml workflow triggers correctly on tag push

🤖 Generated with Claude Code

Manish0Jha and others added 30 commits April 7, 2026 05:31
- Add Cronos package for cron expression parsing
- Add enums: MatchStrategy, DecisionStepType, MilestoneType
- Add models: DejaVuAlert, SessionSummary, DecisionChain, BlastRadius, GrowthModels
- Add interfaces: IDeadEndStore, IAlertSink
- Extend AgentContext with IDeadEndStore
- Extend IGraphStore with multi-edge-type GetNeighbors overload
- Extend IObservationStore with GetSessionObservations
- Extend AgentOutputType with 5 new members
- Add centralized Prompts.cs with all LLM prompt templates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tables: deja_vu_alerts, session_summaries, developer_metrics,
milestones, growth_reports with appropriate indexes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…multi-edge GetNeighbors

- SqliteDeadEndStore with CRUD, FindByFiles, FindSimilar
- GetSessionObservations on SqliteObservationStore
- Multi-edge-type GetNeighbors overload on SqliteGraphStore
- 7 new tests, all passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace stub IsCronDue with Cronos-based cron expression parsing
- Persist DeadEndDetected outputs via IDeadEndStore in AgentScheduler
- Migrate BriefingAgent and CompressionAgent to use Prompts.cs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Wire IDeadEndStore and DecisionChainAgent in Program.cs
- Implement DecisionChainAgent with LLM-powered causal edge classification
- Update LinkerAgentTests for new AgentContext shape
- Add DecisionChainAgent tests with mock LLM service
- All 32 tests passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical fixes:
- Replace string.Format with Prompts.Fill() using named placeholders
  to prevent FormatException on content with braces
- Replace fragile JSON round-trip with concrete DeadEndOutputData DTO
  in AgentScheduler dead-end persistence
- Add SQL LIKE pre-filter in FindByFiles to avoid full-table scan

High priority fixes:
- Add IGraphStore.GetNodeBySourceId for O(1) indexed lookups,
  replacing O(N) GetNodesByType scans in DecisionChainAgent
- Move IDeadEndStore to end of AgentContext parameter list to
  preserve backward compatibility for positional constructors
- Re-throw OperationCanceledException in DecisionChainAgent to
  support clean shutdown

Medium fixes:
- Extract project from observations in dead-end persistence
  (was hardcoded "unknown")
- Extract shared NullVectorStore/NullLlmService/NullDeadEndStore
  into TestHelpers.cs to eliminate duplication
- Lower FindSimilar keyword minimum length from 4 to 3 chars

All 55 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- IAlertStore with Add, GetActive, GetAll, Dismiss, Exists
- SqliteAlertStore persists to deja_vu_alerts table
- Dedup via Exists(threadId, deadEndId) ignoring dismissed
- 5 tests covering CRUD, dismiss, and dedup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Triggers on FileChange and Error events
- Groups observations by thread, matches against dead-end store
- Confidence threshold 0.5 (file overlap ratio)
- Deduplicates via IAlertStore.Exists
- Optional IAlertSink for SSE broadcast
- 4 tests covering match, threshold, dedup, and threadId guard

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- AlertChannel implements IAlertSink via bounded Channel<T>
- REST endpoints: GET /alerts, GET /alerts/all, POST /alerts/{id}/dismiss
- SSE endpoint: GET /alerts/stream for real-time push
- Wire IAlertStore, AlertChannel, DejaVuAgent in Program.cs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DejaVuAlert type and API methods in client.ts
- Alerts page with dismiss buttons and show-dismissed toggle
- AlertBanner component polls every 10s, shows at top of all pages
- Route and nav link for /alerts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical:
- Guard against division-by-zero when deadEnd.FilesInvolved is empty

High:
- AlertChannel uses DropOldest to prevent blocking agents
- Document single-consumer SSE limitation

Medium:
- Dismiss endpoint returns 404 on nonexistent alert IDs
- IAlertStore.Dismiss returns bool for row-found check
- CLI URL-encodes alert ID with Uri.EscapeDataString
- StreamWriter in SSE uses await using for proper disposal
- Limit cap (max 1000) on /alerts/all endpoint

Low:
- Remove unused includeStatus parameter from CLI PrintAlerts
- Add IAlertSink integration test (CapturingAlertSink)
- Add test for empty FilesInvolved guard

All 66 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…torytellerAgent

- ISessionStore with Add, GetBySessionId, GetAll, GetLatest
- SqliteSessionStore persists to session_summaries table
- StorytellerAgent: phase detection, turning points, LLM synthesis
- Phase classification: Exploration, Implementation, Debugging, Refactoring
- 4 store tests + 5 agent tests (including phase/turning point unit tests)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SessionEndpoints: GET /sessions, GET /sessions/{id}, GET/POST /sessions/{id}/story
- StoryCommand CLI: devbrain story [--session id]
- Sessions dashboard page with phase bar, expandable narrative, copy-as-markdown
- Wire ISessionStore, StorytellerAgent in Program.cs
- API client types + methods for SessionSummary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical:
- Remove dead durationSeconds fallback in CLI, display TimeSpan directly
- Replace fragile RawContent slicing with safe Truncate() helper

High:
- POST /sessions/{id}/story now honest about being validation-only (v1)
- Add ISessionStore.GetByDateRange for Growth Tracker needs
- Rename route params from {id} to {sessionId} for clarity

Medium:
- DetectPhases handles sessions shorter than 10 min / same timestamp
- "Error resolved" label changed to "Error at X, no recurrence after"
  with guard requiring subsequent non-error activity
- Fix case sensitivity inconsistency in sessionFiles Distinct()
- Add INSERT OR IGNORE for TOCTOU safety on session_summaries
- Wrap dashboard phase labels in same conditional as phase bar

Low:
- CLI differentiates 404 vs other HTTP errors
- Add 4 new tests: single window, same timestamp, empty observations,
  LLM failure path

All 79 tests passing, dashboard builds clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DecisionChainBuilder: traverses causal graph edges to build
  chronological decision chains for files and decision nodes
- ReplayEndpoints: GET /replay/file/{path}, GET /replay/decision/{nodeId}
- ReplayCommand CLI: devbrain replay <path> [--decision <id>]
- Dashboard Replay page with vertical timeline visualization,
  color-coded step types, file tags, and narrative summary
- 5 new tests for DecisionChainBuilder (chain building, dead ends,
  empty file, causal traversal, nonexistent node)
- Wire DecisionChainBuilder in Program.cs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical:
- BuildForDecision rejects non-Decision/Bug root nodes (returns null)
- Extract TraverseCausalGraph() method for Blast Radius reuse
- CausalEdgeTypes now IReadOnlyList<string> (immutable)
- BuildSteps type filter prevents non-decision nodes from leaking
- Batch observation lookups via obsMap (eliminates N+1 queries)

High:
- Remove unpopulated AlternativesRejected from DecisionStep model
- RootNodeId now deterministic (chronologically earliest step)

Medium:
- CLI path argument is now optional when using --decision
- Dashboard error handling improved (structured check vs string match)
- 3 new tests: non-Decision root rejection, deterministic root,
  hops limit verification

All 87 tests passing, dashboard builds clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- BlastRadiusCalculator: reuses TraverseCausalGraph from DecisionChainBuilder,
  collects downstream files, computes risk scores per spec formula
- Risk = (1/chainLength) * deadEndMultiplier * recencyDecay
- BlastRadiusEndpoints: GET /blast-radius/{path}?hops=N (max 5)
- BlastCommand CLI: devbrain blast <path> with color-coded risk output
- Dashboard BlastRadius page with risk bars, dead-end warnings, file cards
- 8 new tests: affected files, source exclusion, dead ends, unknown file,
  causal chain traversal, risk score unit tests (3)
- InternalsVisibleTo for Storage.Tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
High:
- Clamp risk score to [0, 1] with Math.Min(1.0, raw)
- Replace EstimateChainLength with real depth tracking via
  TraverseCausalGraphWithDepth (BFS with per-node depth)
- deadEndsInChain now per-node (Bug type = 1, else 0)
  instead of global count inflating all scores equally

Medium:
- Remove dead sourceFileNorm variable

Low:
- Clamp hops parameter: Math.Clamp(hops ?? 3, 1, 5)
- Rename DecisionChain field to LinkedDecisionId (was always 1 element)
- Add --hops option to CLI BlastCommand
- Fix test name typo: Folls -> Follows
- 2 new tests: score clamped to 1.0, closer files get higher risk

All 97 tests passing, dashboard builds clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- IGrowthStore with metrics, milestones, reports CRUD + Clear
- SqliteGrowthStore persists to developer_metrics, milestones, growth_reports
- GrowthAgent (weekly cron): computes 8 metric dimensions
  (debugging_speed, dead_end_rate, exploration_breadth, decision_velocity,
  retry_rate, tool_repertoire, problem_complexity, code_quality)
- Milestone detection: first-project, 20%+ improvement, composite
  complexity-up-quality-holding insight
- LLM narrative via Prompts.GrowthNarrative (PreferLocal)
- GrowthEndpoints: GET /growth, /growth/history, /growth/milestones
- GrowthCommand CLI: devbrain growth, growth milestones, growth reset
- Growth dashboard page with narrative card, metrics grid, milestone timeline
- 5 store tests + 7 agent tests (metrics computation, milestone detection)
- Wire IGrowthStore, GrowthAgent in Program.cs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical:
- Fix MapReport to hydrate Metrics and Milestones from stored IDs
  (was returning empty collections, making dashboard non-functional)
- Fix ComputeDebuggingSpeed to measure first-error-to-resolution
  instead of error span (lastError - firstError)
- Rework complexity normalization: 1.0 + raw with better weights
  so scores actually vary across thread sizes (was clamping all to 1.0)

High:
- Detect milestones BEFORE persisting metrics to avoid consuming
  history slots with current week's data
- Add Before filter to weekly observation query
- Reduce historical project query from 5000 to 500

Medium:
- Add DELETE /growth endpoint for reset functionality
- Fix CLI reset command to use API instead of dead-end message

Low:
- Add streak milestone detection for zero dead-end weeks
- 5 new tests: error-to-resolution, zero errors, complexity variation,
  report round-trip with hydrated metrics, multi-session retry rate
- Fix existing debugging speed test for new correct behavior

All 114 tests passing, dashboard builds clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers cross-platform package manager distribution (winget, brew, apt),
Electron tray app for daemon lifecycle, Ollama auto-bootstrap, and CI/CD
pipeline for building and publishing packages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 tasks covering Electron tray app (health, daemon, bootstrap),
CLI/tray coordination, electron-builder config, package manager
manifests (Homebrew, winget, APT), and CI/CD pipeline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Manish0Jha and others added 5 commits April 7, 2026 20:23
…ntinel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…shing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Write stopped sentinel in daemon.stop() before killing process
- Add immediate health check on monitor start
- Fix tag detection logic in CI workflow
- Remove nonexistent DevBrain.app from Homebrew formula
- Remove unused electron-log dependency

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 8, 2026 03:35
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces the “Wow Features” foundation (alerts, decision replay, blast radius, session storytelling, growth tracking) across core models, storage, agents, API, CLI, and dashboard, and adds a single-click packaging flow via an Electron tray app and package-manager publishing.

Changes:

  • Add new Core models + Storage stores/calculators for alerts, sessions, growth, decision chains, and blast radius.
  • Add new Agents + API endpoints + CLI commands + Dashboard pages to surface these features end-to-end.
  • Add Electron tray app + packaging manifests + CI workflow to build and publish installable artifacts.

Reviewed changes

Copilot reviewed 107 out of 109 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
tests/DevBrain.Storage.Tests/SqliteSessionStoreTests.cs Tests for session story storage
tests/DevBrain.Storage.Tests/SqliteGrowthStoreTests.cs Tests for growth store CRUD/hydration
tests/DevBrain.Storage.Tests/SqliteGraphStoreMultiEdgeTests.cs Tests multi-edge-type neighbor traversal
tests/DevBrain.Storage.Tests/SqliteDeadEndStoreTests.cs Tests dead-end storage querying/matching
tests/DevBrain.Storage.Tests/SqliteAlertStoreTests.cs Tests alert store add/dismiss/dedup
tests/DevBrain.Storage.Tests/DecisionChainBuilderTests.cs Tests decision chain building logic
tests/DevBrain.Storage.Tests/BlastRadiusCalculatorTests.cs Tests blast radius + risk scoring
tests/DevBrain.Agents.Tests/TestHelpers.cs Shared null test doubles for agents
tests/DevBrain.Agents.Tests/StorytellerAgentTests.cs Tests session storytelling agent
tests/DevBrain.Agents.Tests/LinkerAgentTests.cs Update context wiring for new deps
tests/DevBrain.Agents.Tests/GrowthAgentTests.cs Tests growth agent metrics/milestones
tests/DevBrain.Agents.Tests/DejaVuAgentTests.cs Tests alert firing + dedup behavior
tests/DevBrain.Agents.Tests/DecisionChainAgentTests.cs Tests decision-linking agent
src/DevBrain.Storage/SqliteSessionStore.cs Session summaries persistence + queries
src/DevBrain.Storage/SqliteObservationStore.cs Add session observation retrieval
src/DevBrain.Storage/SqliteGrowthStore.cs Growth metrics/milestones/report storage
src/DevBrain.Storage/SqliteGraphStore.cs Add node lookup + multi-edge neighbor query
src/DevBrain.Storage/SqliteDeadEndStore.cs Dead-end store implementation
src/DevBrain.Storage/SqliteAlertStore.cs Alert store implementation
src/DevBrain.Storage/Schema/SchemaManager.cs New tables/indexes for wow features
src/DevBrain.Storage/DevBrain.Storage.csproj InternalsVisibleTo for tests
src/DevBrain.Storage/DecisionChainBuilder.cs Shared causal traversal + chain building
src/DevBrain.Storage/BlastRadiusCalculator.cs Blast radius computation + risk scoring
src/DevBrain.Core/Prompts.cs Centralized prompt templates + filler
src/DevBrain.Core/Models/SessionSummary.cs Session story model
src/DevBrain.Core/Models/GrowthModels.cs Growth tracker models
src/DevBrain.Core/Models/DejaVuAlert.cs Alert model
src/DevBrain.Core/Models/DecisionChain.cs Decision chain model
src/DevBrain.Core/Models/BlastRadius.cs Blast radius model
src/DevBrain.Core/Models/AgentOutput.cs New agent output types + payload
src/DevBrain.Core/Interfaces/ISessionStore.cs Session store contract
src/DevBrain.Core/Interfaces/IObservationStore.cs Add session-observations API
src/DevBrain.Core/Interfaces/IIntelligenceAgent.cs Add DeadEnds to AgentContext
src/DevBrain.Core/Interfaces/IGrowthStore.cs Growth store contract
src/DevBrain.Core/Interfaces/IGraphStore.cs Graph store additions/overloads
src/DevBrain.Core/Interfaces/IDeadEndStore.cs Dead-end store contract
src/DevBrain.Core/Interfaces/IAlertStore.cs Alert store contract
src/DevBrain.Core/Interfaces/IAlertSink.cs Alert sink contract
src/DevBrain.Core/Enums/MilestoneType.cs Growth milestone types
src/DevBrain.Core/Enums/MatchStrategy.cs Alert matching strategies
src/DevBrain.Core/Enums/DecisionStepType.cs Decision chain step types
src/DevBrain.Cli/Program.cs Register new CLI commands
src/DevBrain.Cli/Commands/StoryCommand.cs CLI for session stories
src/DevBrain.Cli/Commands/StopCommand.cs Tray coordination via sentinel
src/DevBrain.Cli/Commands/StartCommand.cs Avoid conflicting with tray manager
src/DevBrain.Cli/Commands/ReplayCommand.cs CLI for decision replay
src/DevBrain.Cli/Commands/GrowthCommand.cs CLI for growth reporting/reset
src/DevBrain.Cli/Commands/BlastCommand.cs CLI for blast radius analysis
src/DevBrain.Cli/Commands/AlertsCommand.cs CLI for alert listing/dismiss
src/DevBrain.Api/Services/AlertChannel.cs SSE channel for alert streaming
src/DevBrain.Api/Program.cs Wire stores/agents/endpoints
src/DevBrain.Api/Endpoints/SessionEndpoints.cs Sessions/story endpoints
src/DevBrain.Api/Endpoints/ReplayEndpoints.cs Replay endpoints for file/decision
src/DevBrain.Api/Endpoints/GrowthEndpoints.cs Growth endpoints
src/DevBrain.Api/Endpoints/BlastRadiusEndpoints.cs Blast radius endpoint
src/DevBrain.Api/Endpoints/AlertEndpoints.cs Alerts endpoints + SSE stream
src/DevBrain.Agents/StorytellerAgent.cs Generate session narratives
src/DevBrain.Agents/DevBrain.Agents.csproj Add Cronos + test visibility
src/DevBrain.Agents/DejaVuAgent.cs Fire alerts from dead-end matches
src/DevBrain.Agents/DecisionChainAgent.cs Link decisions + resolve dead ends
src/DevBrain.Agents/DeadEndAgent.cs Typed payload for persisted outputs
src/DevBrain.Agents/CompressionAgent.cs Use centralized prompt templates
src/DevBrain.Agents/BriefingAgent.cs Use centralized prompt templates
src/DevBrain.Agents/AgentScheduler.cs Cron scheduling + dead-end persistence
packages/winget/DevBrain.DevBrain.yaml winget manifest for installer
packages/tray/tsconfig.json Tray TS compiler config
packages/tray/src/paths.ts Tray filesystem/binary path helpers
packages/tray/src/notifications.ts Tray notifications wrapper
packages/tray/src/main.ts Electron tray UX + lifecycle
packages/tray/src/health.ts Daemon health polling
packages/tray/src/daemon.ts Daemon start/stop/restart + crash loop
packages/tray/src/bootstrap.ts First-run bootstrap (config + Ollama)
packages/tray/package.json Tray scripts/deps
packages/tray/jest.config.js Tray Jest config
packages/tray/electron-builder.yml Electron packaging config
packages/tray/build/linux-after-remove.sh Linux uninstall hooks
packages/tray/build/linux-after-install.sh Linux install hooks
packages/tray/build/installer.nsh Windows NSIS customization
packages/tray/assets/icon.png Tray icon asset
packages/tray/assets/icon.ico Windows icon asset
packages/tray/assets/icon.icns macOS icon asset
packages/tray/assets/icon-yellow.png Tray “starting” icon
packages/tray/assets/icon-red.png Tray “unhealthy” icon
packages/tray/tests/health.test.ts Health monitor tests
packages/tray/tests/daemon.test.ts Daemon manager tests
packages/tray/tests/bootstrap.test.ts Bootstrap tests
packages/homebrew/devbrain.rb Homebrew formula for CLI binaries
packages/apt/debian/rules Debian packaging rules
packages/apt/debian/prerm Debian pre-remove script
packages/apt/debian/postinst Debian post-install script
packages/apt/debian/devbrain.desktop Autostart desktop entry
packages/apt/debian/control Debian package metadata
package.json Workspace root for tray/dashboard
dashboard/src/pages/Sessions.tsx Sessions UI
dashboard/src/pages/Replay.tsx Replay UI
dashboard/src/pages/Growth.tsx Growth UI
dashboard/src/pages/BlastRadius.tsx Blast radius UI
dashboard/src/pages/Alerts.tsx Alerts UI
dashboard/src/components/Navigation.tsx Add nav links
dashboard/src/components/AlertBanner.tsx Alert polling banner
dashboard/src/App.tsx Route new pages + banner
dashboard/src/api/client.ts Client types + endpoints
CLAUDE.md Updated build/workflow guidance
.gitignore Ignore tray build/artifacts
.github/workflows/package.yml Packaging CI workflow

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +201 to +205
FROM neighbors n
JOIN graph_edges e ON (e.source_id = n.node_id OR e.target_id = n.node_id)
{inClause}
WHERE n.depth < @hops
AND instr(n.path, CASE WHEN e.source_id = n.node_id THEN e.target_id ELSE e.source_id END) = 0
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The recursive CTE cycle check uses instr(n.path, <nextId>) = 0 while path is a comma-separated string of node IDs. This can produce false positives when one ID is a substring of another (e.g., ...,'1','11',...), incorrectly blocking traversal and returning incomplete neighbor sets. Consider storing the path with leading/trailing delimiters (e.g., ',' || id || ',') and checking instr(path, ',' || nextId || ',') = 0 (or use a dedicated visited table in the CTE).

Copilot uses AI. Check for mistakes.
Comment on lines +122 to +126
CREATE TABLE IF NOT EXISTS deja_vu_alerts (
id TEXT PRIMARY KEY,
thread_id TEXT NOT NULL,
matched_dead_end_id TEXT NOT NULL,
confidence REAL NOT NULL,
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deja_vu_alerts has no uniqueness constraint for (thread_id, matched_dead_end_id). Since deduplication currently relies on a separate Exists() check, concurrent agent runs can still insert duplicate active alerts. Consider enforcing this at the DB level via a UNIQUE index (ideally a partial unique index like UNIQUE(thread_id, matched_dead_end_id) WHERE dismissed = 0) and handling constraint violations gracefully in the store.

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +28
cmd.CommandText = """
INSERT OR IGNORE INTO session_summaries (id, session_id, narrative, outcome,
duration_seconds, observation_count, files_touched, dead_ends_hit,
phases, created_at)
VALUES (@id, @sessionId, @narrative, @outcome,
@durationSeconds, @observationCount, @filesTouched, @deadEndsHit,
@phases, @createdAt)
""";
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add() uses INSERT OR IGNORE but always returns the passed-in summary without indicating whether the insert actually happened. With the session_id UNIQUE constraint, callers can believe a story was persisted when it was silently ignored. Consider using an UPSERT (ON CONFLICT(session_id) DO UPDATE), or check the affected row count and either return the existing row / throw to make the behavior explicit.

Copilot uses AI. Check for mistakes.
Comment on lines +148 to +167
var metrics = new List<DeveloperMetric>();
foreach (var id in shell.MetricIds)
{
using var cmd = _connection.CreateCommand();
cmd.CommandText = "SELECT * FROM developer_metrics WHERE id = @id";
cmd.Parameters.AddWithValue("@id", id);
using var reader = await cmd.ExecuteReaderAsync();
if (await reader.ReadAsync())
metrics.Add(MapMetric(reader));
}

var milestones = new List<GrowthMilestone>();
foreach (var id in shell.MilestoneIds)
{
using var cmd = _connection.CreateCommand();
cmd.CommandText = "SELECT * FROM milestones WHERE id = @id";
cmd.Parameters.AddWithValue("@id", id);
using var reader = await cmd.ExecuteReaderAsync();
if (await reader.ReadAsync())
milestones.Add(MapMilestone(reader));
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HydrateReport() performs one SQL query per metric ID and milestone ID, which can become an N+1 pattern as reports grow (and it runs again in GetReports). Consider fetching all metrics/milestones in a single query each using WHERE id IN (...) (with generated parameters) and then re-ordering them to match the stored ID lists.

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +86
this.process.on("exit", (code) => {
if (fs.existsSync(stoppedSentinelPath())) {
return;
}

if (code !== 0 && code !== null) {
this.recordCrash();
this.onCrashCallback?.();

if (this.shouldRestart()) {
this.start();
} else {
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exit handler triggers an async restart via this.start() without awaiting/handling the returned promise. If start() fails (e.g., missing binary, filesystem issues), this can become an unhandled rejection and the manager may repeatedly try to restart without surfacing the error. Consider making the handler async and awaiting (or at least .catch(...)ing) the restart attempt.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1 @@
placeholder
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is committed as plain text (placeholder) but is referenced as the application icon by electron-builder. electron-builder/platform installers expect a valid PNG/ICO/ICNS binary; this will break packaging. Replace this placeholder with an actual icon asset (and ensure the platform-specific formats are valid).

Suggested change
placeholder
[REPLACE THIS FILE'S CONTENTS WITH A VALID PNG BINARY IMAGE, NOT TEXT. For example, overwrite `packages/tray/assets/icon.png` with the real application icon exported as PNG.]

Copilot uses AI. Check for mistakes.
@@ -0,0 +1 @@
placeholder
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is committed as plain text (placeholder) but is configured as the Windows icon (win.icon / nsis.installerIcon) in electron-builder. Windows packaging expects a valid .ico binary; this will fail during build or produce a broken installer icon. Replace with a real ICO asset.

Suggested change
placeholder
[binary ICO asset data replacing the entire file]

Copilot uses AI. Check for mistakes.
@@ -0,0 +1 @@
placeholder
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is committed as plain text (placeholder) but is configured as the macOS app icon (mac.icon) in electron-builder. macOS packaging expects a valid .icns binary; replace this placeholder with a real icon file to avoid build failures / missing icons.

Suggested change
placeholder
<replace this placeholder file with the actual binary contents of a valid macOS .icns icon file>

Copilot uses AI. Check for mistakes.
@@ -0,0 +1 @@
placeholder
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tray uses this asset for the unhealthy (red) status icon, but it is committed as plain text (placeholder) rather than a valid PNG. Replace with a real PNG to avoid runtime failures when nativeImage.createFromPath loads the icon.

Suggested change
placeholder
<replace this file's contents with a valid PNG binary for the red status icon; the current text placeholder must not remain>

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +83
this.process.on("exit", (code) => {
if (fs.existsSync(stoppedSentinelPath())) {
return;
}

if (code !== 0 && code !== null) {
this.recordCrash();
this.onCrashCallback?.();

Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exit handler only treats non-zero numeric exit codes as crashes (code !== 0 && code !== null). If the daemon terminates via signal (where code is null and a signal is provided), it will be treated as a non-crash and won’t restart, potentially leaving the tray thinking the daemon is down with no recovery. Consider handling the signal argument (and/or treating code === null as a crash unless the stopped sentinel is present).

Copilot uses AI. Check for mistakes.
Critical:
- Ollama install: prefer winget/brew over raw downloads, add Authenticode
  signature verification on Windows, remove curl|sh on macOS (require brew)
- GPG key: use temp file with restricted permissions instead of echo

High:
- PID reuse: verify process name before killing (tasklist/ps check)
- Daemon stderr: redirect to log file for debugging startup failures
- electron-builder: set explicit output directory, fix CI artifact paths
- StopCommand: verify process name matches devbrain-daemon before kill

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Manish0Jha Manish0Jha merged commit adcfacc into main Apr 8, 2026
4 of 6 checks passed
@Manish0Jha Manish0Jha deleted the feat/wow-features-foundation branch April 8, 2026 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants