Skip to content

feat(opencode): integrate OpenCode v1.2.0 SQLite database for session inspection#969

Open
rblalock wants to merge 5 commits intomainfrom
coder-sql-opencode
Open

feat(opencode): integrate OpenCode v1.2.0 SQLite database for session inspection#969
rblalock wants to merge 5 commits intomainfrom
coder-sql-opencode

Conversation

@rblalock
Copy link
Member

@rblalock rblalock commented Feb 14, 2026

Summary

  • Adds OpenCodeDBReader module (packages/opencode/src/sqlite/) to read OpenCode's local SQLite database directly, enabling fast session inspection without API calls
  • Adds CLI dashboard command (agentuity ai opencode dashboard) with tree rendering, JSON output, and watch mode
  • Enhances BackgroundManager, Cadence hooks, and plugin tools with SQLite-first inspection that gracefully falls back to API for pre-v1.2.0 users

What Changed

New: packages/opencode/src/sqlite/

  • types.ts — TypeScript types matching OpenCode's 8-table SQLite schema
  • queries.ts — Raw SQL queries with json_valid() guards for safe JSON extraction
  • reader.tsOpenCodeDBReader class using bun:sqlite with WAL mode support, readonly access, and availability checks
  • index.ts — Barrel exports

New: packages/cli/src/cmd/ai/opencode/dashboard.ts

  • 607-line CLI dashboard command for inspecting OpenCode sessions
  • Tree rendering for parent/child session hierarchies
  • JSON output mode (--json) for programmatic consumption
  • Watch mode (--watch) for live monitoring
  • Graceful "DB not found" with helpful messaging

Enhanced: packages/opencode/src/background/manager.ts

  • SQLite-first task inspection: reads session status directly from DB
  • Falls back to API calls when DB unavailable
  • Child session discovery via parent_id for task recovery

Enhanced: packages/opencode/src/plugin/plugin.ts

  • Initializes OpenCodeDBReader on plugin startup
  • New tools: agentuity_background_inspect and agentuity_session_dashboard
  • Exposes DB reader via shell.env for other agents
  • Clean shutdown of DB reader

Enhanced: packages/opencode/src/plugin/hooks/cadence.ts

  • SQLite dashboard injection at Cadence iteration boundaries
  • Shows session tree, cost summaries, and child session status

Tests

  • 107 tests, 327 assertions — all passing
  • Uses in-memory SQLite with shared cache for fast, isolated testing
  • Covers: reader lifecycle, session queries, message/part parsing, cost aggregation, child sessions, edge cases

Backward Compatibility

Fully backward compatible. Every code path that uses the SQLite DB:

  • Checks dbReader?.isAvailable() before use
  • Returns safe defaults (null, empty arrays, zero values)
  • Falls back to API calls when DB unavailable

Users on OpenCode < v1.2.0 get a fully functional plugin — just without SQLite-powered features.

Testing

bun run test          # 107/107 pass
bun run typecheck     # clean
bun run lint          # clean  
bun run build         # clean

Summary by CodeRabbit

  • New Features

    • Added CLI commands to show session dashboards and inspect individual sessions.
    • New session-dashboard tool to view a parent session’s dashboard from a local OpenCode DB.
  • Improvements

    • Richer inspection data: message counts, active tools, todos, cost and child-session summaries.
    • Background processes can surface DB-backed session data and watch until tasks complete.
  • Tests

    • Added comprehensive SQLite-backed reader tests.
  • Chores

    • Ignore SQLite in-memory test artifacts in .gitignore.

… inspection

Add OpenCodeDBReader to read OpenCode's local SQLite database, enabling
direct session inspection, background task monitoring, and CLI dashboard
without API calls.

New modules:
- packages/opencode/src/sqlite/ — OpenCodeDBReader with typed queries
  for sessions, messages, parts, todos, and child sessions
- packages/cli/src/cmd/ai/opencode/dashboard.ts — CLI dashboard command
  with tree rendering, JSON output, and watch mode (607 lines)
- packages/opencode/test/sqlite.test.ts — 107 tests, 327 assertions

Enhanced features:
- BackgroundManager: SQLite-first task inspection with API fallback
- Cadence hooks: SQLite dashboard injection at iteration boundaries
- Plugin: agentuity_background_inspect and agentuity_session_dashboard tools
- Monitor agent: DB reader exposure for background task monitoring

Gracefully degrades when SQLite DB is unavailable (pre-v1.2.0 users).
@coderabbitai
Copy link

coderabbitai bot commented Feb 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an OpenCode SQLite reader, types, and queries; integrates the reader into plugin, background manager, cadence hooks, and tools; adds CLI inspect and dashboard subcommands; updates monitor/lead guidance; extends inspection types; adds tests and a .gitignore rule for in-memory SQLite artifacts.

Changes

Cohort / File(s) Summary
SQLite core
packages/opencode/src/sqlite/types.ts, packages/opencode/src/sqlite/queries.ts, packages/opencode/src/sqlite/reader.ts, packages/opencode/src/sqlite/index.ts
New SQLite type definitions and exports, a frozen QUERIES object, and an exported OpenCodeDBReader class implementing connection/statement caching, schema validation, session/tree/message/tool/todo/cost queries, dashboard aggregation, and public read APIs. Review API surface, error handling, PRAGMA/connection handling, and cycle detection.
CLI: dashboard, inspect & DB helpers
packages/cli/src/cmd/ai/opencode/dashboard.ts, packages/cli/src/cmd/ai/opencode/inspect.ts, packages/cli/src/cmd/ai/opencode/db.ts, packages/cli/src/cmd/ai/opencode/index.ts
Adds ai opencode dashboard (text/JSON, watch mode) and ai opencode inspect subcommands, plus DB path helpers and REQUIRED_TABLES. Check JSON vs human output, watch/keyboard loop cleanup, DB path resolution, memory-mode handling, schema validation, and CLI exports.
Plugin integration & tools
packages/opencode/src/plugin/plugin.ts
Resolves DB path, constructs OpenCodeDBReader, threads it into BackgroundManager, cadence hooks, and tool creation; exposes agentuity_session_dashboard tool; sets OPENCODE_DB_PATH at startup and closes DB on shutdown. Review lifecycle, shutdown/close handling, and tool surface changes.
Background manager & inspection types
packages/opencode/src/background/manager.ts, packages/opencode/src/background/types.ts
BackgroundManager now accepts optional dbReader?: OpenCodeDBReader and uses DB-backed flows for inspection/recovery/results when available; TaskInspection gained optional fields (messageCount, activeTools, todos, costSummary, childSessionCount). Verify fallback behavior when DB absent and status mapping.
Cadence hooks
packages/opencode/src/plugin/hooks/cadence.ts
createCadenceHooks signature extended with dbReader?: OpenCodeDBReader; on compacting it can append a SQLite dashboard summary (recursive rendering helpers). Validate hook signature propagation and safe injection of generated content.
Agents / prompts
packages/opencode/src/agents/monitor.ts, packages/opencode/src/agents/lead.ts
Monitor system prompt augmented with Enhanced Inspection guidance and references to new inspection/dashboard tools; Lead guidance adds a session-dashboard narrative for Lead-of-Leads orchestration. Review prompt/content changes and any referenced tool names.
Queries & reader tests
packages/opencode/test/sqlite.test.ts, packages/opencode/src/sqlite/queries.ts
Adds comprehensive tests for OpenCodeDBReader (in-memory DB seeding, corrupted JSON handling, cost/dashboard checks) and introduces query constants used by the reader. Ensure test determinism and query correctness.
CLI/Repo hygiene
.gitignore
Adds ignore rule and comment for SQLite in-memory test artifacts: **/file:opencode-* (with comment about bun:sqlite shared cache URIs). Ensure the pattern matches intended temporary files and doesn't over-ignore.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

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


No actionable comments were generated in the recent review. 🎉

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 76e4235 and 24f0bc7.

📒 Files selected for processing (6)
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/plugin/plugin.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/opencode/src/sqlite/reader.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/opencode/src/sqlite/queries.ts
  • packages/opencode/src/agents/monitor.ts
🧰 Additional context used
📓 Path-based instructions (7)
packages/cli/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

Use Bun.file(f).exists() instead of existsSync(f) for file existence checks

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/inspect.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with tabs (width 3), single quotes, and semicolons for code formatting

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with ESNext target and bundler moduleResolution

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use StructuredError from @agentuity/core for error handling

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
packages/cli/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use commander.js framework for CLI implementation in the cli package

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/inspect.ts
packages/opencode/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Use Zod for schema validation

Files:

  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
packages/opencode/src/plugin/**/*.ts

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Plugin target is OpenCode CLI

Files:

  • packages/opencode/src/plugin/plugin.ts
🧠 Learnings (1)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.

Applied to files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
🧬 Code graph analysis (2)
packages/cli/src/cmd/ai/opencode/dashboard.ts (1)
packages/cli/src/cmd/ai/opencode/db.ts (4)
  • isMemoryPath (6-8)
  • REQUIRED_TABLES (4-4)
  • resolveOpenCodeDBPath (31-46)
  • getDefaultDBCandidates (10-29)
packages/cli/src/cmd/ai/opencode/inspect.ts (2)
packages/cli/src/cmd/ai/opencode/db.ts (4)
  • getDefaultDBCandidates (10-29)
  • isMemoryPath (6-8)
  • REQUIRED_TABLES (4-4)
  • parseDisplayTitle (53-66)
packages/cli/src/tui.ts (1)
  • table (2136-2224)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Cloud Deployment Tests
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Build
🔇 Additional comments (3)
packages/cli/src/cmd/ai/opencode/dashboard.ts (1)

689-722: runOnce now propagates failure correctly.
Good improvement: the handler returns { success: ok } and JSON/non-JSON paths return boolean status.

packages/cli/src/cmd/ai/opencode/inspect.ts (1)

233-266: Active vs. recent tool queries look correct.
Including pending alongside running for active tools and excluding both from recent history matches the intended status semantics.

packages/opencode/src/plugin/plugin.ts (1)

48-51: No changes needed. The code is correct as written. StructuredError returns a class constructor directly when no generic type is specified. The trailing () is only required when using generic types (e.g., <{ reason: string }>()), not when omitting them. This matches the established pattern in the same file: MemoryShareAuthError, MemoryShareCLIError, and MemoryShareError all use trailing () because they include generic types, while OpenCodeDashboardUnavailableError correctly omits it. The instantiation on line 805 (new OpenCodeDashboardUnavailableError()) works as intended.

Likely an incorrect or invalid review comment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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

@github-actions
Copy link

github-actions bot commented Feb 14, 2026

📦 Canary Packages Published

version: 1.0.12-24f0bc7

Packages
Package Version URL
@agentuity/react 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-react-1.0.12-24f0bc7.tgz
@agentuity/opencode 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-opencode-1.0.12-24f0bc7.tgz
@agentuity/server 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-server-1.0.12-24f0bc7.tgz
@agentuity/core 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-core-1.0.12-24f0bc7.tgz
@agentuity/postgres 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-postgres-1.0.12-24f0bc7.tgz
@agentuity/workbench 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-workbench-1.0.12-24f0bc7.tgz
@agentuity/frontend 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-frontend-1.0.12-24f0bc7.tgz
@agentuity/claude-code 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-claude-code-1.0.12-24f0bc7.tgz
@agentuity/drizzle 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-drizzle-1.0.12-24f0bc7.tgz
@agentuity/runtime 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-runtime-1.0.12-24f0bc7.tgz
@agentuity/schema 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-schema-1.0.12-24f0bc7.tgz
@agentuity/evals 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-evals-1.0.12-24f0bc7.tgz
@agentuity/cli 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-cli-1.0.12-24f0bc7.tgz
@agentuity/auth 1.0.12-24f0bc7 https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-auth-1.0.12-24f0bc7.tgz
Install

Add to your package.json:

{
  "dependencies": {
    "@agentuity/react": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-react-1.0.12-24f0bc7.tgz",
    "@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-opencode-1.0.12-24f0bc7.tgz",
    "@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-server-1.0.12-24f0bc7.tgz",
    "@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-core-1.0.12-24f0bc7.tgz",
    "@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-postgres-1.0.12-24f0bc7.tgz",
    "@agentuity/workbench": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-workbench-1.0.12-24f0bc7.tgz",
    "@agentuity/frontend": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-frontend-1.0.12-24f0bc7.tgz",
    "@agentuity/claude-code": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-claude-code-1.0.12-24f0bc7.tgz",
    "@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-drizzle-1.0.12-24f0bc7.tgz",
    "@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-runtime-1.0.12-24f0bc7.tgz",
    "@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-schema-1.0.12-24f0bc7.tgz",
    "@agentuity/evals": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-evals-1.0.12-24f0bc7.tgz",
    "@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-cli-1.0.12-24f0bc7.tgz",
    "@agentuity/auth": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-auth-1.0.12-24f0bc7.tgz"
  }
}

Or install directly:

bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-react-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-opencode-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-server-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-core-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-postgres-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-workbench-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-frontend-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-claude-code-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-drizzle-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-runtime-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-schema-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-evals-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-cli-1.0.12-24f0bc7.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.12-24f0bc7/agentuity-auth-1.0.12-24f0bc7.tgz

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/cli/src/cmd/ai/opencode/dashboard.ts`:
- Around line 564-596: The runOnce function currently swallows errors and
returns early without signaling failure to the caller; update runOnce (the async
function that calls loadDashboardData and uses
jsonMode/outputJSON/renderDashboard) to return a boolean or throw on error
(e.g., return false when result.error or !result.data, and true on success),
then change the non-watch path that does "await runOnce(); return { success:
true }" to inspect the runOnce result (or catch the thrown error) and return {
success: false } when runOnce failed (or rethrow) so the handler accurately
reflects success/failure.
🧹 Nitpick comments (7)
packages/cli/src/cmd/ai/opencode/dashboard.ts (1)

245-267: Consider handling database open errors more gracefully.

If new Database(dbPath, ...) throws for reasons other than missing file (e.g., file locked, corrupt header), the generic catch block on line 385 returns a vague "query_failed" error. The DB constructor can throw before any query runs.

💡 Optional: Distinguish DB open failures from query failures
 	try {
-		db = new Database(dbPath, isMemory ? undefined : { readonly: true });
+		try {
+			db = new Database(dbPath, isMemory ? undefined : { readonly: true });
+		} catch (openError) {
+			return {
+				error: 'open_failed',
+				message: openError instanceof Error ? openError.message : 'Failed to open database.',
+			};
+		}
packages/opencode/src/agents/monitor.ts (1)

70-70: Minor documentation inconsistency with tool usage.

Line 70 states "❌ Use tools other than agentuity_background_output" but the Enhanced Inspection section (lines 16-23) instructs using agentuity_background_inspect. The exclude list correctly allows both tools; the prose could be updated to match.

📝 Suggested documentation fix
-- ❌ Use tools other than agentuity_background_output
+- ❌ Use tools other than agentuity_background_output and agentuity_background_inspect

Also applies to: 116-116

packages/opencode/test/sqlite.test.ts (1)

282-286: Consider cleaning up the reader in the unavailability test.

The reader created at line 283 is never closed. While it doesn't open a connection (since open() returns false), adding a reader.close() call maintains consistency with other tests.

💡 Optional: Add cleanup for consistency
 	it('reports unavailable when DB path is missing', () => {
 		const reader = new OpenCodeDBReader({ dbPath: '/tmp/opencode/missing.db' });
 		expect(reader.isAvailable()).toBe(false);
 		expect(reader.open()).toBe(false);
+		reader.close();
 	});
packages/opencode/src/background/manager.ts (1)

748-758: Message iteration order may not return the latest assistant response.

The getMessages query returns messages sorted by time_created DESC (newest first), but the code iterates forward through the array looking for the first assistant message. This should return the latest assistant message correctly.

However, the logic differs from the API fallback (lines 766-770) which explicitly iterates backwards (for (let i = entries.length - 1; i >= 0; i -= 1)). For consistency and clarity, consider adding a comment noting that DB messages are already in descending order, or explicitly reversing the iteration to match the API fallback pattern.

packages/opencode/src/plugin/hooks/cadence.ts (1)

465-487: Consider formatting cost values for readability.

The totalCost value is displayed as a raw number. For consistency with appendDashboardNode (line 500) which also shows raw cost values, consider formatting these as currency (e.g., $0.0012) or adding a unit suffix for clarity in the compaction context.

packages/opencode/src/plugin/plugin.ts (2)

1034-1066: Consider extracting shared DB path resolution logic.

This function is nearly identical to resolveDBPath in packages/opencode/src/sqlite/reader.ts (lines 103-133). The only difference is that this one checks OPENCODE_DB_PATH env var while the reader version checks config?.dbPath.

Consider exporting a unified resolver from the sqlite module to avoid duplication and ensure consistent path resolution across the codebase.

♻️ Suggested approach

Export resolveDBPath from packages/opencode/src/sqlite/reader.ts (or a shared utility) with an optional env var parameter:

// In packages/opencode/src/sqlite/reader.ts or a new utils.ts
export function resolveDBPath(config?: { dbPath?: string; checkEnv?: boolean }): string | null {
  if (config?.checkEnv) {
    const envPath = process.env.OPENCODE_DB_PATH;
    if (envPath) {
      if (isMemoryPath(envPath)) return envPath;
      if (existsSync(envPath)) return envPath;
    }
  }
  
  if (config?.dbPath) {
    return config.dbPath;
  }
  // ... rest of platform-specific resolution
}

Then in plugin.ts:

import { resolveDBPath } from '../sqlite';
const resolvedDbPath = resolveDBPath({ checkEnv: true });

1068-1070: Duplicate helper function.

This is identical to isMemoryPath in packages/opencode/src/sqlite/reader.ts. Consider exporting from the sqlite module.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a9472d7 and 2ddb1e2.

📒 Files selected for processing (13)
  • .gitignore
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/background/manager.ts
  • packages/opencode/src/background/types.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
  • packages/opencode/src/sqlite/index.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/sqlite/types.ts
  • packages/opencode/test/sqlite.test.ts
🧰 Additional context used
📓 Path-based instructions (13)
packages/opencode/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Use Zod for schema validation

Files:

  • packages/opencode/src/sqlite/index.ts
  • packages/opencode/src/background/types.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/opencode/test/sqlite.test.ts
  • packages/opencode/src/background/manager.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/sqlite/types.ts
  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with tabs (width 3), single quotes, and semicolons for code formatting

Files:

  • packages/opencode/src/sqlite/index.ts
  • packages/opencode/src/background/types.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/test/sqlite.test.ts
  • packages/opencode/src/background/manager.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/sqlite/types.ts
  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with ESNext target and bundler moduleResolution

Files:

  • packages/opencode/src/sqlite/index.ts
  • packages/opencode/src/background/types.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/test/sqlite.test.ts
  • packages/opencode/src/background/manager.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/sqlite/types.ts
  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
**/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use named exports from package index.ts files

Files:

  • packages/opencode/src/sqlite/index.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use StructuredError from @agentuity/core for error handling

Files:

  • packages/opencode/src/sqlite/index.ts
  • packages/opencode/src/background/types.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/test/sqlite.test.ts
  • packages/opencode/src/background/manager.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/sqlite/types.ts
  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
packages/opencode/src/background/**/*.ts

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Background tasks run in separate processes/sessions

Files:

  • packages/opencode/src/background/types.ts
  • packages/opencode/src/background/manager.ts
packages/cli/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

Use Bun.file(f).exists() instead of existsSync(f) for file existence checks

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
packages/cli/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use commander.js framework for CLI implementation in the cli package

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
packages/opencode/test/**/*.ts

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

When running tests, prefer using a subagent (Task tool) to avoid context bloat from test output

Files:

  • packages/opencode/test/sqlite.test.ts
**/test/**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.{test,spec}.{ts,tsx,js,jsx}: Place tests in test/ folder, never in src/ or __tests__/ directories
Import test dependencies from ../src/ in test files
Use @agentuity/test-utils for mocks in tests

Files:

  • packages/opencode/test/sqlite.test.ts
packages/cli/src/cmd/**/index.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

packages/cli/src/cmd/**/index.ts: Each command must be structured as a directory in src/cmd/ with an index.ts file as the entry point
Always define interfaces or Zod schemas for command options; never use any type for type safety
Use tui.* helpers (header, info, success, warning, error, table, progress) for formatted TUI output instead of raw console methods
Use ctx.logger for logging instead of console methods; use logger.fatal() for fatal errors which logs and exits with code 1
Always check isJSONMode() before outputting data and provide machine-readable output when in JSON mode
Use requireAuth(ctx) for commands that require authentication or optionalAuth(ctx) for commands that support optional authentication

Files:

  • packages/cli/src/cmd/ai/opencode/index.ts
packages/opencode/src/plugin/**/*.ts

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Plugin target is OpenCode CLI

Files:

  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
packages/opencode/src/agents/*.ts

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Agent system prompts are embedded in agent definition files

Files:

  • packages/opencode/src/agents/monitor.ts
🧠 Learnings (1)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.

Applied to files:

  • packages/opencode/src/sqlite/index.ts
  • packages/opencode/src/background/types.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/test/sqlite.test.ts
  • packages/opencode/src/background/manager.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/sqlite/types.ts
  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/reader.ts
  • packages/opencode/src/plugin/plugin.ts
🧬 Code graph analysis (6)
packages/opencode/test/sqlite.test.ts (1)
packages/opencode/src/sqlite/reader.ts (1)
  • OpenCodeDBReader (262-658)
packages/opencode/src/background/manager.ts (3)
packages/opencode/src/sqlite/reader.ts (1)
  • OpenCodeDBReader (262-658)
packages/opencode/src/background/types.ts (2)
  • BackgroundTask (12-30)
  • BackgroundTaskStatus (2-2)
packages/opencode/src/sqlite/types.ts (1)
  • DBTextPart (71-77)
packages/cli/src/cmd/ai/opencode/index.ts (1)
packages/cli/src/cmd/ai/opencode/dashboard.ts (1)
  • dashboardSubcommand (516-604)
packages/opencode/src/plugin/hooks/cadence.ts (2)
packages/opencode/src/sqlite/reader.ts (1)
  • OpenCodeDBReader (262-658)
packages/opencode/src/sqlite/types.ts (1)
  • SessionTreeNode (109-116)
packages/opencode/src/sqlite/reader.ts (3)
packages/opencode/src/sqlite/index.ts (13)
  • OpenCodeDBConfig (10-10)
  • SessionSummary (13-13)
  • DBSession (5-5)
  • DBMessage (3-3)
  • MessageTokens (9-9)
  • DBToolCall (8-8)
  • DBTextPart (6-6)
  • DBTodo (7-7)
  • TodoSummary (15-15)
  • SessionTreeNode (14-14)
  • OpenCodeDBReader (1-1)
  • SessionCostSummary (11-11)
  • SessionStatus (12-12)
packages/opencode/src/sqlite/types.ts (12)
  • OpenCodeDBConfig (118-121)
  • SessionSummary (1-6)
  • DBSession (19-33)
  • DBMessage (35-46)
  • MessageTokens (8-17)
  • DBToolCall (58-69)
  • DBTextPart (71-77)
  • DBTodo (79-85)
  • TodoSummary (103-107)
  • SessionTreeNode (109-116)
  • SessionCostSummary (87-96)
  • SessionStatus (98-101)
packages/opencode/src/sqlite/queries.ts (1)
  • QUERIES (1-46)
packages/opencode/src/plugin/plugin.ts (2)
packages/opencode/src/sqlite/reader.ts (1)
  • OpenCodeDBReader (262-658)
packages/opencode/src/sqlite/types.ts (1)
  • SessionTreeNode (109-116)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Template Integration Tests
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Pack & Upload
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Cloud Deployment Tests
  • GitHub Check: Build
🔇 Additional comments (50)
.gitignore (1)

70-71: LGTM — ignore rule matches the new SQLite test artifacts.
The added pattern is clear and scoped to the expected bun:sqlite shared-cache filenames.

packages/opencode/src/sqlite/queries.ts (1)

1-46: LGTM!

The SQL queries are well-structured with appropriate safeguards:

  • json_valid() guards prevent errors from malformed JSON data
  • COALESCE handles null values correctly for aggregations
  • Parameterized queries (?) prevent SQL injection
  • Recursive CTE for descendant sessions handles hierarchical data properly
packages/opencode/src/background/types.ts (1)

69-78: LGTM!

The new optional fields extend TaskInspection with richer DB-backed metadata while maintaining backward compatibility. The types align well with the SQLite reader's output.

packages/cli/src/cmd/ai/opencode/dashboard.ts (3)

10-15: LGTM - Zod schema for CLI options.

Proper use of Zod for schema validation as per coding guidelines. The .describe() calls provide useful CLI help text.


120-135: LGTM - Proper use of Bun.file().exists() for file existence checks.

Correctly uses Bun.file(path).exists() instead of existsSync() as per coding guidelines for the CLI package.


418-494: LGTM - Rendering functions use tui.* helpers correctly.

Good use of tui.output, tui.table, tui.bold, tui.muted, tui.info, and tui.newline for formatted TUI output as per coding guidelines.

packages/cli/src/cmd/ai/opencode/index.ts (1)

5-5: LGTM!

Clean integration of the dashboard subcommand following the established pattern. The example entry correctly documents the new command.

Also applies to: 25-30

packages/opencode/src/sqlite/types.ts (1)

1-121: LGTM!

Comprehensive and well-typed interfaces for the SQLite data layer. Good use of:

  • Optional fields for nullable DB columns
  • Literal union types for constrained values (SessionStatus.status)
  • Recursive types for tree structures (SessionTreeNode)
  • Separation between DB row types and computed summaries
packages/opencode/src/sqlite/index.ts (1)

1-16: LGTM!

Clean barrel exports following the coding guideline for named exports from index.ts files. Good use of export type for type-only exports.

packages/opencode/src/agents/monitor.ts (1)

14-24: LGTM - Enhanced inspection guidance.

Clear documentation of the new agentuity_background_inspect capabilities for deeper task insight.

packages/opencode/test/sqlite.test.ts (3)

1-10: LGTM - Test setup and lifecycle management.

Good test structure with:

  • Proper imports from ../src/ as per guidelines
  • In-memory SQLite with shared cache for test isolation
  • Clean beforeEach/afterEach lifecycle management

Also applies to: 261-280


312-317: Good edge case coverage for corrupted JSON.

Testing graceful handling of malformed JSON data by verifying the reader returns a sensible default (role: 'unknown') rather than throwing.


357-368: Good negative test for schema validation.

Verifies that OpenCodeDBReader.open() returns false when required tables are missing, ensuring the reader won't operate on an incompatible database.

packages/opencode/src/background/manager.ts (6)

4-4: LGTM!

Import correctly brings in required types from the sqlite module.


50-51: LGTM!

Constructor correctly accepts optional dbReader parameter and stores it. The parameter is positioned last to maintain backward compatibility with existing call sites.

Also applies to: 58-72


129-185: LGTM!

The DB-backed inspection path is well-implemented:

  • Properly checks dbReader?.isAvailable() before use
  • Fetches comprehensive session data (messages, text parts, tools, todos, cost, child sessions)
  • Falls back to API when DB unavailable
  • Message sorting by timeCreated ensures chronological order

300-353: LGTM!

The DB-backed task recovery path correctly:

  • Uses AGENTUITY_OPENCODE_SESSION env var for parent session discovery
  • Parses JSON metadata from session titles to reconstruct tasks
  • Maps DB status to task status via mapDbStatusToTaskStatus
  • Returns early to avoid redundant API calls when DB recovery succeeds

779-794: LGTM!

Status mapping logic is correct and handles all DB session states appropriately:

  • idle/archivedcompleted (session finished)
  • active/compactingrunning (session still working)
  • errorerror
  • Default → pending (safe fallback)

882-903: LGTM!

Helper functions are well-implemented:

  • groupTextPartsByMessage properly groups and sorts text parts by timeCreated
  • buildTextParts and joinTextParts handle empty/undefined inputs gracefully
  • All functions are pure and correctly typed
packages/opencode/src/plugin/hooks/cadence.ts (5)

4-4: LGTM!

Import correctly brings in required types from the sqlite module.


70-75: LGTM!

Function signature correctly updated to accept optional dbReader parameter while maintaining backward compatibility.


368-372: LGTM!

Dashboard summary injection is clean and follows the existing pattern of appending to output.context. Proper null check ensures nothing is pushed when DB is unavailable or no child sessions exist.


489-512: LGTM!

Dashboard node rendering is well-structured:

  • Correctly fetches session status for each node
  • Formats todo and cost summaries appropriately
  • Recursive tree traversal with proper indentation
  • Informative output format showing all relevant session details

514-526: LGTM!

Label formatting correctly handles JSON-encoded task metadata in session titles with appropriate fallbacks.

packages/opencode/src/plugin/plugin.ts (9)

4-6: LGTM!

Imports correctly bring in Node.js filesystem/OS utilities and SQLite types needed for DB path resolution and reader integration.

Also applies to: 20-21


87-88: LGTM!

DB reader initialization with optional config is correct. The reader handles unavailable DB gracefully via isAvailable() checks.


106-127: LGTM!

BackgroundManager correctly receives dbReader as the 4th parameter, maintaining backward compatibility with the callback object in the 3rd position.


207-209: LGTM!

Setting OPENCODE_DB_PATH in shell.env allows downstream CLI commands and tools to access the same database path.


628-631: LGTM!

Function signature correctly updated to accept optional dbReader parameter.


744-764: LGTM!

Enhanced inspection output correctly detects DB-derived fields and returns richer data when available, falling back to basic message extraction otherwise.


792-814: LGTM!

The agentuity_session_dashboard tool is well-implemented:

  • Proper availability check with clear error message
  • Returns structured dashboard data with session tree hierarchy
  • Useful for Lead-of-Leads monitoring as described

996-1032: LGTM!

Dashboard tree builder correctly transforms SessionTreeNode[] into a structured format with session details, status, and summaries. Recursive processing of children maintains hierarchy.


1072-1077: LGTM!

Shutdown handler correctly updated to close the DB reader during plugin shutdown. The try-catch pattern with logging is consistent with other cleanup operations.

Also applies to: 1120-1128

packages/opencode/src/sqlite/reader.ts (17)

1-19: LGTM!

Imports are appropriate for the functionality. Type imports from ./types provide strong typing for the data models.


21-85: LGTM!

Row types correctly model the SQLite table schemas with snake_case column names. The ToolState and PartData types appropriately handle both camelCase and snake_case field variants for JSON parsing flexibility.


90-97: LGTM!

safeParseJSON correctly handles null/undefined inputs and catches parse errors, returning null as a safe fallback.


103-133: LGTM!

Platform-specific DB path resolution is comprehensive, covering macOS (Library/Application Support), Windows (APPDATA/LOCALAPPDATA), and Linux (.local/share) locations.


155-171: LGTM!

mapSession correctly transforms snake_case DB columns to camelCase TypeScript properties with proper null/undefined handling.


173-189: LGTM!

mapMessage safely parses JSON data with defensive type checks for each field. Returns sensible defaults for missing data.


191-212: LGTM!

mapToolCall correctly handles both callID and callId variants and both timeStarted/time_started conventions, accommodating potential inconsistencies in the data.


262-274: LGTM!

Class initialization is clean with sensible defaults. Schema validation enabled by default is a good safety measure.


276-289: LGTM!

isAvailable() correctly handles three cases:

  1. Already open and available → return true
  2. Memory path → always available
  3. File path → check existence

291-338: LGTM!

open() implementation is well-designed:

  • Memory DBs open in readwrite mode for pragma support
  • File DBs open readonly for safety
  • WAL mode and busy_timeout configured appropriately
  • Schema validation prevents use with incompatible databases
  • Proper cleanup on failure

340-347: LGTM!

close() properly cleans up all resources: closes the database handle, resets state flags, and clears the statement cache.


349-407: LGTM!

Session and message query methods follow a consistent, defensive pattern:

  • Check ensureOpen() before operations
  • Use prepared statements via getStatement()
  • Wrap in try-catch with logging
  • Return safe defaults on failure

435-476: LGTM!

Tool and text part query methods correctly use isNotNull filter to remove null values from mapped results, handling rows that don't match expected types.


499-549: LGTM!

getSessionCost() returns a complete SessionCostSummary with all fields, using zero defaults both for unavailable DB and query failures. Consistent error handling.


551-578: LGTM!

getSessionStatus() correctly derives status from session state:

  • Archived → archived
  • Compacting → compacting
  • Latest message has error → error
  • Active tools present → active
  • Otherwise → idle

The lastActivity calculation using Math.max of session and message timestamps is correct.


598-607: LGTM!

Statement caching implementation is correct and improves performance by reusing prepared statements.


628-657: LGTM!

buildSessionTree() correctly handles:

  • Cycle detection via visited set with warning
  • Graceful handling of missing sessions via createEmptySession
  • Recursive child processing
  • Aggregation of message count, tool count, todos, and cost

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

…watch mode UX

CLI Dashboard:
- Add --limit, --since, --status, --search, --all filtering flags
- Default to 10 most recent sessions (--all for everything)
- Add fuzzy search by title (case-insensitive LIKE)
- Add relative timestamps (5m ago, 2h ago) and Last Active column
- Fix runOnce error handling to return success/failure
- Watch mode: q to quit, r to refresh, keyboard shortcuts footer

Tool Response (agentuity_session_dashboard):
- Parse JSON title blobs into displayTitle field
- Return activeTools array with tool names (not just count)
- Add currentActivity snippet per session
- Add ISO timestamps alongside epoch millis
- Add aggregate health summary (active/idle/error counts)
- Make todoSummary always present (zeros when empty)

Agent Prompts:
- Add agentuity_session_dashboard references to Lead, Monitor,
  and Cadence prompts for Lead-of-Leads monitoring
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In `@packages/cli/src/cmd/ai/opencode/dashboard.ts`:
- Around line 351-362: The SQL that populates activeToolRows currently filters
only for status = 'running', causing sessions with 'pending' tool calls to be
treated as idle; update the db.query in the activeToolRows block (the query used
to build activeTools / activeToolRows) to include pending statuses (e.g., change
the WHERE clause json_extract(p.data, '$.state.status') = 'running' to either IN
('running','pending') or an equivalent OR condition) so that both running and
pending tool-invocation/tool rows are considered active.
- Around line 158-170: Replace the generic Error throws in parseDuration with
StructuredError from `@agentuity/core`: import StructuredError and throw new
StructuredError instances when the regex fails or the unit is unknown
(references: function parseDuration, DURATION_UNITS). Ensure each
StructuredError includes a clear message, an error code/tag (e.g.,
"INVALID_DURATION" or "UNKNOWN_DURATION_UNIT") and metadata identifying the
problematic value (e.g., { input: duration, unit }). Do not change the function
signature; only swap the throw sites to StructuredError and include the extra
structured fields so callers can surface consistent tags.

In `@packages/opencode/src/agents/monitor.ts`:
- Around line 14-26: The guidance text conflicts with the tool restrictions:
either permit agentuity_session_dashboard or remove its mention and update the
"Do NOT Do" constraints to match available tools. Fix by editing the Monitor
prompt text where agentuity_background_inspect and agentuity_session_dashboard
are referenced (also the repeated block later) so it only suggests tools
actually allowed (agentuity_background_output and agentuity_background_inspect),
or alternatively add agentuity_session_dashboard to the allowed tool list and
remove it from the forbid list; ensure the “Do NOT Do” section explicitly
matches the final allowed tools to avoid conflicting instructions.

In `@packages/opencode/src/plugin/plugin.ts`:
- Around line 792-805: The sessionDashboard tool currently returns a plain
string error when the SQLite DB is not available; create a new StructuredError
class OpenCodeDashboardUnavailableError (modeled after MemoryShareError and
other errors in this file) and import/use StructuredError from `@agentuity/core`,
then change the error return in the sessionDashboard.execute path to return the
new error's _tag (e.g., { success: false, error:
OpenCodeDashboardUnavailableError._tag }) so the client receives a
StructuredError identifier consistent with project conventions.

In `@packages/opencode/src/sqlite/reader.ts`:
- Around line 191-205: The mapToolCall function currently only treats
payload.type === 'tool' as valid and returns null for 'tool-invocation', causing
those parts to be dropped; update mapToolCall to accept both 'tool' and
'tool-invocation' (check payload.type === 'tool' || payload.type ===
'tool-invocation') and preserve existing parsing logic (callId, tool, state).
Also update any SQL WHERE clauses or query helpers that filter parts by type
(the queries that currently restrict to "tool") to include "tool-invocation" so
stored tool calls are not excluded from active tools and history counts.
- Around line 90-97: The current safeParseJSON function uses raw JSON.parse and
unchecked assertions; define Zod schemas for the DB payload shapes used in
mapMessage, mapToolCall, and mapTextPart (e.g., schemas for MessageTokens,
PartData, ToolCallPayload), then replace usages of safeParseJSON and direct `as
T` casts with schema.safeParse calls; refactor safeParseJSON into a generic
helper that accepts a Zod schema (or remove it) so callers call
schema.safeParse(parsed) and handle failures (return null or throw) instead of
trusting unchecked casts in mapMessage, mapToolCall, and mapTextPart.
🧹 Nitpick comments (1)
packages/opencode/src/plugin/plugin.ts (1)

1061-1084: Avoid duplicate active-tool queries per node.
buildDashboardTree calls getSessionStatus (which queries active tools) and then immediately calls getActiveToolCalls again for the same session. Consider reusing the fetched list or adding a helper that accepts active tools to cut DB reads, especially for large trees.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2ddb1e2 and b6afec9.

📒 Files selected for processing (7)
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/src/agents/lead.ts
  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/opencode/src/sqlite/reader.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/opencode/src/agents/lead.ts
🧰 Additional context used
📓 Path-based instructions (8)
packages/opencode/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Use Zod for schema validation

Files:

  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
  • packages/opencode/src/sqlite/reader.ts
packages/opencode/src/agents/*.ts

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Agent system prompts are embedded in agent definition files

Files:

  • packages/opencode/src/agents/monitor.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with tabs (width 3), single quotes, and semicolons for code formatting

Files:

  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
  • packages/opencode/src/sqlite/reader.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with ESNext target and bundler moduleResolution

Files:

  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
  • packages/opencode/src/sqlite/reader.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use StructuredError from @agentuity/core for error handling

Files:

  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
  • packages/opencode/src/sqlite/reader.ts
packages/cli/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

Use Bun.file(f).exists() instead of existsSync(f) for file existence checks

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
packages/cli/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use commander.js framework for CLI implementation in the cli package

Files:

  • packages/cli/src/cmd/ai/opencode/dashboard.ts
packages/opencode/src/plugin/**/*.ts

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

Plugin target is OpenCode CLI

Files:

  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
🧠 Learnings (1)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.

Applied to files:

  • packages/opencode/src/agents/monitor.ts
  • packages/opencode/src/sqlite/queries.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/opencode/src/plugin/hooks/cadence.ts
  • packages/opencode/src/plugin/plugin.ts
  • packages/opencode/src/sqlite/reader.ts
🧬 Code graph analysis (2)
packages/cli/src/cmd/ai/opencode/dashboard.ts (2)
packages/opencode/src/sqlite/reader.ts (1)
  • buildSessionTree (647-676)
packages/cli/src/tui.ts (1)
  • table (2136-2224)
packages/opencode/src/sqlite/reader.ts (3)
packages/opencode/src/sqlite/index.ts (13)
  • OpenCodeDBConfig (10-10)
  • SessionSummary (13-13)
  • DBSession (5-5)
  • DBMessage (3-3)
  • MessageTokens (9-9)
  • DBToolCall (8-8)
  • DBTextPart (6-6)
  • DBTodo (7-7)
  • TodoSummary (15-15)
  • SessionTreeNode (14-14)
  • OpenCodeDBReader (1-1)
  • SessionCostSummary (11-11)
  • SessionStatus (12-12)
packages/opencode/src/sqlite/types.ts (12)
  • OpenCodeDBConfig (118-121)
  • SessionSummary (1-6)
  • DBSession (19-33)
  • DBMessage (35-46)
  • MessageTokens (8-17)
  • DBToolCall (58-69)
  • DBTextPart (71-77)
  • DBTodo (79-85)
  • TodoSummary (103-107)
  • SessionTreeNode (109-116)
  • SessionCostSummary (87-96)
  • SessionStatus (98-101)
packages/opencode/src/sqlite/queries.ts (1)
  • QUERIES (1-50)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: Template Integration Tests
  • GitHub Check: Cloud Deployment Tests
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Build
🔇 Additional comments (2)
packages/opencode/src/sqlite/queries.ts (1)

1-49: LGTM — query catalog is clear and consistent.

packages/opencode/src/plugin/hooks/cadence.ts (1)

466-488: Nice addition of the SQLite dashboard summary hook.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Dashboard fixes:
- Fix --status filter to recursively prune non-matching children
  while preserving tree context for matching descendants
- Show only pending todos by default, add --all-todos flag
- Rename to 'Coder Dashboard' (remove emoji)
- Extract shared DB utilities to db.ts

New inspect subcommand:
- agentuity ai opencode inspect --session <id>
- Returns full session detail: messages, tools, todos, cost, children
- Includes displayTitle (parsed JSON titles) and ISO timestamps
- Human-readable and JSON output modes
- inspect: session ID is now a positional arg (inspect ses_xxx)
  instead of a flag (inspect --session ses_xxx)
- parseDisplayTitle: check description, title, and name fields
  from JSON title blobs (was only checking title)
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/cli/src/cmd/ai/opencode/inspect.ts`:
- Around line 236-269: Active tool detection currently only treats status
'running' as active so 'pending' invocations appear in recentToolRows; update
the SQL for activeToolRows to treat both 'running' and 'pending' as active
(change the WHERE clause checking json_extract(p.data, '$.state.status') =
'running' to check IN ('running','pending')), and update the recentToolRows
query to exclude pending (change the condition json_extract(p.data,
'$.state.status') != 'running' to something like json_extract(p.data,
'$.state.status') NOT IN ('running','pending')) so pending calls are counted as
active and omitted from recentToolRows; modify the queries where variables
activeToolRows and recentToolRows are built (they use sessionId and return
ToolRow[]).
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6afec9 and 114ef98.

📒 Files selected for processing (4)
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/db.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
  • packages/cli/src/cmd/ai/opencode/inspect.ts
🧰 Additional context used
📓 Path-based instructions (7)
packages/cli/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

Use Bun.file(f).exists() instead of existsSync(f) for file existence checks

Files:

  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/db.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with tabs (width 3), single quotes, and semicolons for code formatting

Files:

  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/db.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with ESNext target and bundler moduleResolution

Files:

  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/db.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use StructuredError from @agentuity/core for error handling

Files:

  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/db.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
packages/cli/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use commander.js framework for CLI implementation in the cli package

Files:

  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/db.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
packages/cli/src/cmd/**/index.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

packages/cli/src/cmd/**/index.ts: Each command must be structured as a directory in src/cmd/ with an index.ts file as the entry point
Always define interfaces or Zod schemas for command options; never use any type for type safety
Use tui.* helpers (header, info, success, warning, error, table, progress) for formatted TUI output instead of raw console methods
Use ctx.logger for logging instead of console methods; use logger.fatal() for fatal errors which logs and exits with code 1
Always check isJSONMode() before outputting data and provide machine-readable output when in JSON mode
Use requireAuth(ctx) for commands that require authentication or optionalAuth(ctx) for commands that support optional authentication

Files:

  • packages/cli/src/cmd/ai/opencode/index.ts
**/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use named exports from package index.ts files

Files:

  • packages/cli/src/cmd/ai/opencode/index.ts
🧠 Learnings (1)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.

Applied to files:

  • packages/cli/src/cmd/ai/opencode/inspect.ts
  • packages/cli/src/cmd/ai/opencode/dashboard.ts
  • packages/cli/src/cmd/ai/opencode/db.ts
  • packages/cli/src/cmd/ai/opencode/index.ts
🧬 Code graph analysis (3)
packages/cli/src/cmd/ai/opencode/inspect.ts (2)
packages/cli/src/cmd/ai/opencode/db.ts (4)
  • getDefaultDBCandidates (10-29)
  • isMemoryPath (6-8)
  • REQUIRED_TABLES (4-4)
  • parseDisplayTitle (53-64)
packages/cli/src/tui.ts (1)
  • table (2136-2224)
packages/cli/src/cmd/ai/opencode/dashboard.ts (1)
packages/cli/src/cmd/ai/opencode/db.ts (4)
  • isMemoryPath (6-8)
  • REQUIRED_TABLES (4-4)
  • resolveOpenCodeDBPath (31-46)
  • getDefaultDBCandidates (10-29)
packages/cli/src/cmd/ai/opencode/index.ts (2)
packages/cli/src/cmd/ai/opencode/dashboard.ts (1)
  • dashboardSubcommand (604-770)
packages/cli/src/cmd/ai/opencode/inspect.ts (1)
  • inspectSubcommand (112-517)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Build
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: Cloud Deployment Tests
🔇 Additional comments (5)
packages/cli/src/cmd/ai/opencode/db.ts (1)

1-64: Clean DB path utilities.

Nice encapsulation of DB path resolution and display-title parsing with safe fallbacks.

packages/cli/src/cmd/ai/opencode/inspect.ts (2)

71-110: Helper time/status formatting looks solid.

The ISO/relative time helpers and status computation are clear and consistent.


112-516: Command flow and output modes look good.

Schema validation, JSON/human-readable output, and DB lifecycle handling are all well-structured.

packages/cli/src/cmd/ai/opencode/index.ts (1)

5-41: Command registration updates look good.

The new dashboard and inspect subcommands are properly surfaced with examples.

packages/cli/src/cmd/ai/opencode/dashboard.ts (1)

689-722: Success/failure propagation in runOnce looks good.

Returning a boolean and wiring it into the handler makes the CLI exit status accurate.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

…turedError, monitor tools

- Dashboard + inspect: include 'pending' tools as active (was only 'running')
- Inspect: exclude pending tools from recentTools (NOT IN instead of !=)
- Reader + queries: handle both 'tool' and 'tool-invocation' part types
- Monitor: allow agentuity_session_dashboard (removed from exclude list)
- Plugin: use StructuredError for dashboard unavailable error
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