Skip to content

fix(typecheck): restore proactive module import surface - #1495

Merged
kevincodex1 merged 3 commits into
Twigpine:mainfrom
chioarub:fix/typecheck-proactive-import-surface
Jun 4, 2026
Merged

kevincodex1 merged 3 commits into
Twigpine:mainfrom
chioarub:fix/typecheck-proactive-import-surface

Conversation

@chioarub

@chioarub chioarub commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Refs #1486.

Restores the proactive module import surface expected by feature-gated consumers and hardens the new state helper against stale pause state and subscriber failures.

What changed

  • Added src/proactive/index.ts with the proactive active/paused state helpers used by CLI, REPL, prompt, and tool code.
  • Exposed the subscription and context-blocking helpers that existing lazy imports already call.
  • Made activation clear stale context blocking so enabling proactive mode cannot remain silently paused.
  • Isolated proactive-change listener failures so one bad subscriber cannot abort later notifications or leak through state transitions.
  • Added focused unit tests for stale context-block activation and failing-listener notification behavior.

Why

Several consumers lazy-require ../proactive/index.js behind feature gates, but main no longer has that module. This leaves focused typecheck errors for the proactive import path and would also fail at runtime if the feature-gated path is enabled.

The review pass found two edge cases in the initial shim: context blocking could survive activation, and notification callbacks were allowed to throw through the state transition. Both are fixed in the state module rather than making callers defend against broken global state.

Validation

  • bun test src/proactive/index.test.ts - 2 pass, 0 fail
  • git diff --check - passed
  • bun run build - passed
  • bun run typecheck 2>&1 | tee /tmp/openclaude-typecheck-after-proactive-review.txt - still reports unrelated repository backlog errors, but targeted grep for proactive/index and src/proactive has no matches

Summary by CodeRabbit

  • New Features
    • Introduced proactive state management with activation, deactivation, pause/resume, and context-blocking behavior
    • Added a subscription API that notifies listeners on state changes and isolates listener errors so one failure doesn't block others
  • Tests
    • Added tests covering state transitions, context-blocking behavior, subscription cleanup, and listener error isolation

@chioarub

chioarub commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 3, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 3, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 627281a0-5789-4a23-b5e9-1dc00e890d4a

📥 Commits

Reviewing files that changed from the base of the PR and between f03c60e and d00be51.

📒 Files selected for processing (2)
  • src/proactive/index.test.ts
  • src/proactive/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/proactive/index.test.ts
  • src/proactive/index.ts

📝 Walkthrough

Walkthrough

New proactive state module: subscription-based listener notifications, state query helpers, and control functions (activate/deactivate/pause/resume/setContextBlocked). Listeners are invoked on each transition with isolated error handling; Bun tests validate context-block clearing and listener error isolation.

Changes

Proactive State Management

Layer / File(s) Summary
Listener infra, notifier, and queries
src/proactive/index.ts
Defines internal listener Set and notifier with per-listener try/catch + console.error; subscribeToProactiveChanges registers/unregisters listeners; isProactiveActive, isProactivePaused, getNextTickAt expose state (nextTickAt masked when paused/context-blocked).
State transitions (activate/pause/block)
src/proactive/index.ts
activateProactive/deactivateProactive reset flags and clear nextTickAt; pauseProactive/resumeProactive toggle pause (resume no-op if not active); setContextBlocked toggles blocking and clears nextTickAt when blocking. All transitions notify listeners.
Test suite
src/proactive/index.test.ts
Bun tests add/cleanup subscriptions; verify activateProactive() clears setContextBlocked(true), and that a throwing listener does not prevent other listeners from receiving notifications or leave proactive paused; also asserts console.error logs the listener error.

Sequence Diagrams

sequenceDiagram
  participant Caller
  participant Proactive Module
  participant Listeners
  Caller->>Proactive Module: subscribeToProactiveChanges(listener)
  Proactive Module->>Proactive Module: add listener to Set
  Proactive Module->>Caller: return unsubscribe function
  Caller->>Proactive Module: isProactiveActive()
  Proactive Module->>Caller: return boolean state
  Caller->>Proactive Module: getNextTickAt()
  Proactive Module->>Caller: return nextTickAt or null
  Caller->>Proactive Module: unsubscribe()
  Proactive Module->>Proactive Module: remove listener from Set
Loading
stateDiagram-v2
  [*] --> Inactive
  Inactive --> Active: activateProactive()
  Active --> Inactive: deactivateProactive()
  Active --> Paused: pauseProactive()
  Paused --> Active: resumeProactive()
  Active --> ContextBlocked: setContextBlocked(true)
  Paused --> ContextBlocked: setContextBlocked(true)
  ContextBlocked --> Active: setContextBlocked(false)
  
  note right of Active
    notifyListeners() called
    on every transition
  end note
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through flags and listener sets with care,
Subscribed and listened to state changes in the air,
A thrown error logged but did not stall the race,
Activate cleared the block and kept the pace,
Tiny paws tidy subscriptions with flair.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(typecheck): restore proactive module import surface' clearly summarizes the main change—restoring the missing proactive module import path to fix typecheck errors.
Description check ✅ Passed The PR description comprehensively covers all required template sections: Summary explains what changed and why, Impact addresses both user and developer concerns, Testing documents validation performed, and Notes clarifies the issue context and edge cases fixed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/proactive/index.ts (1)

10-18: 💤 Low value

Consider logging swallowed listener exceptions for observability.

Silent exception swallowing is correct for isolation, but completely silent failures can make debugging listener issues difficult. A console.error would preserve isolation while aiding diagnosis.

🔇 Proposed improvement for error visibility
 function notifyProactiveListeners(): void {
   for (const listener of [...listeners]) {
     try {
       listener()
-    } catch {
+    } catch (err) {
+      console.error('Proactive listener threw:', err)
       // Listener failures must not prevent state transitions or later listeners.
     }
   }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/proactive/index.ts` around lines 10 - 18, The notifyProactiveListeners
function currently swallows exceptions from each listener (variable listeners)
without any visibility; modify the catch block inside notifyProactiveListeners
to log the caught error (and optionally context such as which listener or its
index) using console.error so listener failures remain isolated but are
observable for debugging; ensure the log message is descriptive (e.g.,
"proactive listener error") and include the error object to preserve stack
traces.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/proactive/index.ts`:
- Around line 10-18: The notifyProactiveListeners function currently swallows
exceptions from each listener (variable listeners) without any visibility;
modify the catch block inside notifyProactiveListeners to log the caught error
(and optionally context such as which listener or its index) using console.error
so listener failures remain isolated but are observable for debugging; ensure
the log message is descriptive (e.g., "proactive listener error") and include
the error object to preserve stack traces.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a275501-d311-449d-95d5-397f4863e7ab

📥 Commits

Reviewing files that changed from the base of the PR and between cfcc5d0 and f03c60e.

📒 Files selected for processing (2)
  • src/proactive/index.test.ts
  • src/proactive/index.ts

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the contribution. I do not see any actionable issues from my review.

@kevincodex1

@kevincodex1 kevincodex1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks good!

@kevincodex1
kevincodex1 merged commit e357d59 into Twigpine:main Jun 4, 2026
3 checks passed
@chioarub
chioarub deleted the fix/typecheck-proactive-import-surface branch June 4, 2026 08:55
hotmanxp added a commit to hotmanxp/openclaude that referenced this pull request Jun 7, 2026
Upstream 47eea3f..e7abb81, applied 2 of 5 KEEP candidates in tier 1
(3 already applied under prior sync 4f6bccc but were missed by
subject-match dedup due to squash-merge subject loss):

  e357d59 fix(typecheck): restore proactive module import surface (Twigpine#1495)
  e7abb81 fix(typecheck): make session history cache variant-safe (Twigpine#1494)

Already-applied (byte-equal content + fork-specific @ts-nocheck):
  47eea3f fix(typecheck): type search UI state (Twigpine#1529)
  11e46af fix(typecheck): narrow hook event counts (Twigpine#1496)
  2c755d3 fix(typecheck): restore typed add-dir source (Twigpine#1504)

Notes:
- e357d59: 2 new files (src/proactive/{index.ts,index.test.ts});
  pulls cleanly, no provider leakage
- e7abb81: 1 new file (sessionHistorySerialization.ts) + 3 mods.
  sessionHistory.test.ts gets // @ts-nocheck (upstream tests use
  SDKUserMessage.message + new serialization import; local SDKUserMessage
  type doesn't include .message field, and sessionHistory.ts still uses
  inline impl). sessionHistory.ts gets the upstream rewrite (inline
  functions replaced with imports from sessionHistorySerialization.ts);
  @ts-nocheck preserved.
- conversationCache.ts: Message[] → CacheMessage[]; CacheMessage becomes
  Record<string, unknown> (was: alias of Message interface)

Verification:
  typecheck: 0 errors
  bun test src/assistant/sessionHistory.test.ts: 6 pass, 0 fail
  bun test src/proactive/index.test.ts: 2 pass, 0 fail
  build: Built v0.16.1 → dist/cli.mjs
  naming scan: no openclaude/gitlawb leakage
deagwon97 pushed a commit to deagwon97/openclaude that referenced this pull request Jun 11, 2026
* fix(typecheck): restore proactive module import surface

* test(proactive): harden state change notifications

* fix(proactive): log listener notification errors
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.

3 participants