Skip to content

feat: project-scoped bus + immediate auto-ingest + app.log warnings #151 #152 #153#155

Merged
four-bytes-robby merged 2 commits into
mainfrom
feat/152-project-scoped-bus-startup
Jun 15, 2026
Merged

feat: project-scoped bus + immediate auto-ingest + app.log warnings #151 #152 #153#155
four-bytes-robby merged 2 commits into
mainfrom
feat/152-project-scoped-bus-startup

Conversation

@four-bytes-robby

@four-bytes-robby four-bytes-robby commented Jun 15, 2026

Copy link
Copy Markdown
Member

Closes #151, closes #152, closes #153

Changes

Depends on

  • @four-bytes/opencode-plugin-lib v0.7.1 (local path — forProject + onWarn)

Summary by cubic

Switch brain status updates to project-scoped bus channels, start auto-ingest immediately at plugin init, and inline project ID hashing so server and TUI share the same channel. Adds app.log warnings for bus issues and fixes the startup “ready” race. (#151, #152, #153, #155)

Written for commit 049e925. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Chores
    • Version bumped to 1.7.10
  • Refactor
    • Auto-ingest now starts immediately at plugin initialization (once per plugin lifetime) instead of waiting for session creation.
    • Ingest timeout is computed dynamically from a preliminary file-count scan, with clearer progress/timeout/failure handling.
    • Real-time status and TUI updates are now project-scoped (based on the configured directory), rather than session-scoped.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

Recent review info
Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3412fb5e-254b-4da8-8545-cce06fc01b38

Commits

Reviewing files that changed from the base of the PR and between d83d13b and 049e925.

Files selected for processing (3)
  • package.json
  • src/status.ts
  • src/tui.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • src/status.ts

Walkthrough

Walkthrough

Auto-ingest is moved from the session.created event handler to immediate plugin initialization, with a dynamic timeout computed from a preliminary file-count scan and explicit outcome handling via status updates and toasts. Status bus publishing in status.ts is switched from session-scoped to project-scoped targeting using deriveProjectId, and the TUI subscription is updated to match. The package version is bumped to 1.7.10.

Changes

Auto-ingest timing fix and project-scoped status bus

Layer / File(s) Summary
Project-scoped bus targeting
src/status.ts, src/tui.tsx
Both status.ts and tui.tsx add deriveProjectId helpers to compute stable FNV-1a hash identifiers from directory paths. status.ts stores the directory in _directory during initStatus, then rewrites write() to publish via bus.forService("brain").forProject(projectId); publishing is skipped when no projectId can be derived and sessionId is removed from the payload. tui.tsx updates useServiceBus subscription to derive projectId from api.state.path.directory instead of using props.sessionId.
Immediate auto-ingest with dynamic timeout and outcome handling
src/four-opencode-brain.ts
Replaces deferred auto-ingest with a runAutoIngest closure launched at plugin init, guarded by _autoIngestDone. Scans file count to compute a dynamic ingest timeout, runs ingestPath under withTimeout, and calls updateStatus/toast for success, zero-files, timeout, and error outcomes. Conditions updateStatus("ready") at init on _autoIngestDone being false so auto-ingest transitions to ready itself. Reduces session.created handler to setSessionId only.
Package version bump
package.json
Version incremented from 1.7.7 to 1.7.10.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #151 (fix: regression — auto-ingest + status not firing on startup): This PR directly implements the fix described — auto-ingest is moved back to immediate fire-and-forget at plugin init and session.created is reduced to session ID capture only.
  • #152 ([FIX] Project-scoped bus for startup/ingest status): This PR implements the exact changes described: status.ts publishes to brain/{projectId}/status via forProject(deriveProjectId(directory)), and updateStatus("ready") is conditioned on auto-ingest not running.

Possibly related PRs

  • four-bytes/four-opencode-brain#148: The PR being reviewed directly reverts the auto-ingest deferral and session-scoped status publishing introduced in that PR, replacing them with immediate init-time ingest and project-scoped bus targeting.
  • four-bytes/four-opencode-brain#150: Both PRs modify src/four-opencode-brain.ts around the updateStatus("ready") call at plugin startup and its relationship to auto-ingest state.
  • four-bytes/four-opencode-brain#145: Both PRs refactor the bus publish targeting in src/status.ts to use scoped bus API methods, with this PR switching to forProject and the earlier PR introducing the scoped API usage pattern.
Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the three main changes: project-scoped bus, immediate auto-ingest, and app.log warnings routing.
Description check ✅ Passed The PR description comprehensively covers all changes, related issues, dependencies, and includes detailed explanation of fixes with proper issue references.
Linked Issues check ✅ Passed Code changes fully address all three linked issues: auto-ingest runs immediately at init (#151), status uses project-scoped bus (#152), and BusClient warnings route to app.log (#153).
Out of Scope Changes check ✅ Passed All changes are directly related to the three linked issues; version bump and modifications to status routing, auto-ingest timing, and logging are all within scope.

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

Finishing Touches
Generate docstrings
  • Create stacked PR
  • Commit on current branch
Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/152-project-scoped-bus-startup
Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/152-project-scoped-bus-startup

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


// Trigger auto-ingest immediately (fire-and-forget, not deferred to session.created).
// updateStatus("ready") is NOT called here — auto-ingest transitions to ready/success/error on its own.
if (autoIngest && !shouldSkip && !_autoIngestDone) {

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/status.ts (1)

139-155: ⚠️ Potential issue | 🔴 Critical

Update TUI subscription to match project-scoped publishing.

The publisher at line 149 sends status events to bus.forService("brain").forProject(projectId), but the TUI in src/tui.tsx line 65 remains subscribed to a session-scoped channel:

useServiceBus("brain", () => props.sessionId, "status", (payload) => {
  handleStatus(payload as BrainStatusEvent);
});

The TUI must switch from props.sessionId to forProject(projectId) to receive the published events. Update the subscription to:

useServiceBus("brain", () => deriveProjectId(props.directory), "status", (payload) => {
  handleStatus(payload as BrainStatusEvent);
});

Also correct the comment at line 140 to reflect the actual subscription method.

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/status.ts` around lines 139 - 155, The TUI subscription in src/tui.tsx at
the useServiceBus call is subscribed to a session-scoped channel using
props.sessionId, but the publisher in src/status.ts sends status events to a
project-scoped channel using forProject(projectId). Update the useServiceBus
subscription in src/tui.tsx to use deriveProjectId(props.directory) instead of
props.sessionId as the scope identifier so the TUI receives the project-scoped
status events being published. After making this change, verify that the comment
at line 140 in src/status.ts accurately reflects the updated subscription
behavior.
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.

Inline comments:
In `@src/status.ts`:
- Line 7: The import statement in the status.ts file is trying to import
deriveProjectId from the opencode-plugin-lib library, but this export does not
exist in the currently installed version 0.6.1. Update the dependency version
for `@four-bytes/opencode-plugin-lib` in package.json to ^0.7.1, which is the
required version that exports deriveProjectId and supports the forProject()
method referenced in the PR objectives.

---

Outside diff comments:
In `@src/status.ts`:
- Around line 139-155: The TUI subscription in src/tui.tsx at the useServiceBus
call is subscribed to a session-scoped channel using props.sessionId, but the
publisher in src/status.ts sends status events to a project-scoped channel using
forProject(projectId). Update the useServiceBus subscription in src/tui.tsx to
use deriveProjectId(props.directory) instead of props.sessionId as the scope
identifier so the TUI receives the project-scoped status events being published.
After making this change, verify that the comment at line 140 in src/status.ts
accurately reflects the updated subscription behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

Review info
Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ff8e443c-651a-4366-ad9e-3f527cb33d7b

Commits

Reviewing files that changed from the base of the PR and between a676f50 and d83d13b.

Files selected for processing (3)
  • package.json
  • src/four-opencode-brain.ts
  • src/status.ts

Comment thread src/status.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 3 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/four-opencode-brain.ts">

<violation number="1" location="src/four-opencode-brain.ts:174">
P2: Auto-ingest top-level rejection path only logs and does not update status, so startup can be stuck in busy state. Handle the catch by publishing an error status.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment on lines +174 to +176
runAutoIngest().catch((err) => {
log("error", "auto-ingest", `Auto-ingest failed: ${String(err)}`);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Auto-ingest top-level rejection path only logs and does not update status, so startup can be stuck in busy state. Handle the catch by publishing an error status.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/four-opencode-brain.ts, line 174:

<comment>Auto-ingest top-level rejection path only logs and does not update status, so startup can be stuck in busy state. Handle the catch by publishing an error status.</comment>

<file context>
@@ -91,102 +91,91 @@ const _serverPlugin = async (input: PluginInput) => {
+  // updateStatus("ready") is NOT called here — auto-ingest transitions to ready/success/error on its own.
+  if (autoIngest && !shouldSkip && !_autoIngestDone) {
+    _autoIngestDone = true;
+    runAutoIngest().catch((err) => {
+      log("error", "auto-ingest", `Auto-ingest failed: ${String(err)}`);
+    });
</file context>
Suggested change
runAutoIngest().catch((err) => {
log("error", "auto-ingest", `Auto-ingest failed: ${String(err)}`);
});
runAutoIngest().catch((err) => {
const errMsg = `Auto-ingest failed: ${String(err)}`;
log("error", "auto-ingest", errMsg);
updateStatus("error", { text: errMsg, toast: errMsg });
});

@four-bytes-robby four-bytes-robby merged commit 17fb261 into main Jun 15, 2026
6 checks passed
@four-bytes-robby four-bytes-robby deleted the feat/152-project-scoped-bus-startup branch June 15, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant