Skip to content

[ef-9] perf/fix: simplify codebase, fix bugs, optimize hot paths#8

Merged
NiveditJain merged 1 commit into
mainfrom
ef-9
Apr 6, 2026
Merged

[ef-9] perf/fix: simplify codebase, fix bugs, optimize hot paths#8
NiveditJain merged 1 commit into
mainfrom
ef-9

Conversation

@NiveditJain

@NiveditJain NiveditJain commented Apr 6, 2026

Copy link
Copy Markdown
Member

Summary

  • 2 bug fixes: inverted error handling in resolveSubagentPath (non-ENOENT errors silently continued); negative durationMs from clock skew in log enrichment
  • 5 performance fixes: regex literals hoisted to module-level constants (compiled once, not per-call); git rev-parse cached per-cwd in blockWorkOnMain (avoids repeated 3s synchronous block); policy registry lookup now uses a lazy index cache; Promise.all in project/session listing replaced with bounded batchAll(16) to prevent fd exhaustion; removed TTL refresh on cache hits in runtimeCache (was defeating the revalidateSeconds contract)
  • 4 deduplication: extracted shared formatRelativeTime to lib/format-duration.ts; removed duplicate implementations in hooks-client.tsx and session-hooks-panel.tsx; replaced local CopyButton reimplementation with the shared component

Test plan

  • bun run build — passes, no TypeScript errors
  • bun run test:run — 709/709 tests pass
  • Manual: launch dashboard, browse sessions, verify log viewer and copy buttons work
  • Manual: trigger blockWorkOnMain twice on the same repo — second call should be instant (no execSync)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Performance

    • Optimized internal caching and batch processing for improved responsiveness
    • Consolidated time formatting utilities for consistent display across the application
    • Enhanced policy evaluation with faster lookup caching
  • Bug Fixes

    • Fixed potential negative duration values in activity logging
    • Improved error handling for file path resolution

Bug fixes:
- lib/resolve-subagent-path: fix inverted error handling (ENOENT should
  continue, not non-ENOENT); non-ENOENT errors now break the search
- lib/log-entries: clamp durationMs to 0 to prevent negative durations
  from clock skew producing outputs like "-0.3s"

Performance:
- src/hooks/builtin-policies: hoist all static regex literals to
  module-level constants so they are compiled once, not per-call
- src/hooks/builtin-policies: cache git branch per cwd in
  blockWorkOnMain to avoid repeated synchronous execSync (up to 3s
  block per call)
- src/hooks/policy-registry: add lazy index cache to getPoliciesForEvent
  so filter+sort runs once per (eventType, toolName) pair instead of
  on every tool event
- lib/projects: replace unbounded Promise.all with batchAll(concurrency=16)
  in getProjectFolders and getSessionFiles to avoid fd exhaustion
- lib/runtime-cache: remove TTL refresh on cache hits (was causing hot
  keys to live in cache indefinitely, defeating the revalidateSeconds
  contract); eviction is now insertion-order (FIFO)

Simplification:
- lib/format-duration: extract shared formatRelativeTime utility
- app/policies/hooks-client: remove duplicate formatRelativeTime,
  import from lib/format-duration
- app/components/session-hooks-panel: remove duplicate formatRelativeTime
  and local CopyButton reimplementation; use shared components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 6, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Free

Run ID: 5d1de781-cb65-4e1b-9c44-29bfc86c4131

📥 Commits

Reviewing files that changed from the base of the PR and between 2b78c30 and 7034706.

📒 Files selected for processing (11)
  • __tests__/hooks/builtin-policies.test.ts
  • __tests__/lib/runtime-cache.test.ts
  • app/components/session-hooks-panel.tsx
  • app/policies/hooks-client.tsx
  • lib/format-duration.ts
  • lib/log-entries.ts
  • lib/projects.ts
  • lib/resolve-subagent-path.ts
  • lib/runtime-cache.ts
  • src/hooks/builtin-policies.ts
  • src/hooks/policy-registry.ts
💤 Files with no reviewable changes (1)
  • lib/runtime-cache.ts

📝 Walkthrough

Walkthrough

The PR consolidates duplicate formatting utilities into shared modules, optimizes caching strategies across runtime and policy registries, hoists compiled regular expressions to module-level constants, introduces git branch caching, refactors async promise handling with concurrency limits, adjusts error handling logic, and updates tests to reflect new cache behaviors.

Changes

Cohort / File(s) Summary
Formatting Consolidation
lib/format-duration.ts, app/components/session-hooks-panel.tsx, app/policies/hooks-client.tsx
Extracted formatRelativeTime into shared utility; removed duplicate implementations and associated UI components (CopyButton), consolidating relative-time formatting across the codebase.
Runtime Cache & Policy Indexing
lib/runtime-cache.ts, src/hooks/policy-registry.ts
Removed LRU-on-hit refresh behavior from runtime cache; added global index caching to policy registry to memoize filtered and sorted policy results by event type and tool name.
Performance Optimizations
src/hooks/builtin-policies.ts
Hoisted module-level regex pattern constants for security checks (JWT, API keys, secrets, SQL, shell commands, git operations); introduced git branch caching per cwd with exported clearGitBranchCache() function for test isolation.
Test Updates
__tests__/hooks/builtin-policies.test.ts, __tests__/lib/runtime-cache.test.ts
Added explicit cache invalidation calls in test afterEach hooks; adjusted LRU expectations to insertion-order eviction instead of recency-based reordering.
Error Handling & Async Management
lib/resolve-subagent-path.ts, lib/projects.ts, lib/log-entries.ts
Changed error continuation logic to break on non-ENOENT errors; refactored unbounded Promise.all to batchAll with concurrency limit of 16; clamped tool-use result duration to non-negative values.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Policy Event Handler
    participant Registry as getPoliciesForEvent()
    participant Cache as Index Cache
    participant Store as Policy Registry Store

    Caller->>Registry: getPoliciesForEvent(eventType, toolName)
    Registry->>Cache: Check cache key (eventType, toolName)
    
    alt Cache Hit
        Cache-->>Registry: Return cached policies array
        Registry-->>Caller: Return policies
    else Cache Miss
        Registry->>Store: Query policies from registry
        Store-->>Registry: Return unfiltered policies
        Registry->>Registry: Filter by event type & tool name
        Registry->>Registry: Sort by priority
        Registry->>Cache: Store result in cache
        Cache-->>Registry: Cache updated
        Registry-->>Caller: Return policies
    end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

A rabbit hops through caches deep,
With regex stored and branches to keep.
No more duplication, formatters now shared,
Concurrency bounded, performance prepared.
Hopping faster with each optimization! 🐰✨


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands and usage tips.

@NiveditJain NiveditJain merged commit 94bb6b7 into main Apr 6, 2026
8 checks passed
@NiveditJain NiveditJain deleted the ef-9 branch April 6, 2026 19:51
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.

1 participant