Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughThe change adds Claude Code sub-agent discovery and nested rendering, expands Antigravity deletion cleanup, filters internal Codex guardian threads, and adds packaged UI smoke testing to the publish workflow. ChangesClaude Code session hierarchy
Antigravity conversation cleanup
Codex guardian thread filtering
Packaged UI smoke verification
Sequence Diagram(s)sequenceDiagram
participant ClaudeCodeDb
participant TranscriptFiles
participant SessionTable
ClaudeCodeDb->>TranscriptFiles: discover parent and sub-agent transcripts
TranscriptFiles->>ClaudeCodeDb: return transcript metadata
ClaudeCodeDb->>SessionTable: provide sessions with parentSessionId
SessionTable->>SessionTable: build and render the nested session tree
sequenceDiagram
participant PackageSmoke
participant Bunx
participant SpirachaUI
PackageSmoke->>PackageSmoke: create package and select port
PackageSmoke->>Bunx: launch packaged CLI
Bunx->>SpirachaUI: serve packaged UI
PackageSmoke->>SpirachaUI: poll and validate HTML
PackageSmoke->>Bunx: stop process and clean files
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@apps/ui/src/components/claude-code-sessions-table.tsx`:
- Around line 34-40: Update SessionTitleCell so nested sessions use depth-based
left padding rather than the fixed pl-3 class. Preserve the existing border
styling for subagents, and ensure each increase in depth produces an additional
indentation level while top-level sessions remain unpadded.
In `@src/lib/antigravity-db.ts`:
- Around line 1219-1224: Replace the fixed Bun.sleep(10) retry boundary in the
deletion flow surrounding removeConversationFromSummaryIndex and
removeAntigravityConversationPaths with coordination with the active SQLite
connection owner. If coordination cannot guarantee quiescence, verify all
conversation artifacts are absent after cleanup and report incomplete deletion
rather than returning success; add coverage that recreates the database after
the second cleanup pass.
In `@src/package-smoke.ts`:
- Around line 92-102: Update the probe request around fetch in the package smoke
flow to pass an abort signal using the remaining startup deadline, calculated as
AbortSignal.timeout(Math.max(1, deadline - Date.now())). Ensure the signal is
cleared after each request attempt completes, including failures, while
preserving the existing response handling and retry behavior.
- Around line 145-162: Update the catch path around the process probe so proc is
terminated with SIGTERM before awaiting stdoutPromise and stderrPromise. Then
collect and include the pipe output as currently done, while preserving the
existing finally cleanup and error-message composition.
🪄 Autofix
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: ASSERTIVE
Plan: Pro Plus
Run ID: 4098fd68-51cd-4aee-880e-d88f4ac9f12f
📒 Files selected for processing (17)
apps/ui/src/components/claude-code-sessions-table.tsxapps/ui/src/components/source-tables.vitest.tsxapps/ui/src/lib/claude-code-server.vitest.tsapps/ui/src/lib/claude-code-transcript-events.vitest.tsapps/ui/src/routes/claude-code-sessions.$sessionId.tsxpackage.jsonsrc/lib/antigravity-db.test.tssrc/lib/antigravity-db.tssrc/lib/claude-code-db.test.tssrc/lib/claude-code-db.tssrc/lib/claude-code-exporter-types.tssrc/lib/claude-code-transcript.test.tssrc/lib/codex-browser-db.test.tssrc/lib/codex-browser-db.tssrc/package-manifest.test.tssrc/package-smoke.test.tssrc/package-smoke.ts
| const SessionTitleCell = ({ depth, session }: { depth: number; session: ClaudeCodeSessionTreeNode }) => { | ||
| const isSubagent = depth > 0; | ||
|
|
||
| return ( | ||
| <div | ||
| className={cn('min-w-0', isSubagent ? 'border-[var(--border)] border-l-2 pl-3' : '')} | ||
| data-row-depth={depth} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Indent each nested level.
At Line 39, every subagent uses the same pl-3 padding. A grandchild session renders at the same horizontal position as a direct child. Calculate the padding from depth.
Proposed fix
<div
- className={cn('min-w-0', isSubagent ? 'border-[var(--border)] border-l-2 pl-3' : '')}
+ className={cn('min-w-0', isSubagent ? 'border-[var(--border)] border-l-2' : '')}
data-row-depth={depth}
+ style={isSubagent ? { paddingInlineStart: `${depth * 0.75}rem` } : undefined}
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const SessionTitleCell = ({ depth, session }: { depth: number; session: ClaudeCodeSessionTreeNode }) => { | |
| const isSubagent = depth > 0; | |
| return ( | |
| <div | |
| className={cn('min-w-0', isSubagent ? 'border-[var(--border)] border-l-2 pl-3' : '')} | |
| data-row-depth={depth} | |
| const SessionTitleCell = ({ depth, session }: { depth: number; session: ClaudeCodeSessionTreeNode }) => { | |
| const isSubagent = depth > 0; | |
| return ( | |
| <div | |
| className={cn('min-w-0', isSubagent ? 'border-[var(--border)] border-l-2' : '')} | |
| data-row-depth={depth} | |
| style={isSubagent ? { paddingInlineStart: `${depth * 0.75}rem` } : undefined} | |
| > |
🤖 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 `@apps/ui/src/components/claude-code-sessions-table.tsx` around lines 34 - 40,
Update SessionTitleCell so nested sessions use depth-based left padding rather
than the fixed pl-3 class. Preserve the existing border styling for subagents,
and ensure each increase in depth produces an additional indentation level while
top-level sessions remain unpadded.
| if (deletedSummary || deletedPaths.length > 0) { | ||
| await Bun.sleep(10); | ||
| for (const root of roots) { | ||
| await removeConversationFromSummaryIndex(getAntigravitySummaryIndexPath(root), conversationId); | ||
| await removeAntigravityConversationPaths(root, conversationId); | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Do not use a fixed delay as the deletion boundary.
Line 1220 waits 10 ms and then runs one final cleanup pass. A live writer can recreate the database or a SQLite sidecar after that pass. The function then reports deletion while the conversation artifact remains on disk.
Coordinate deletion with the process that owns active SQLite connections. If coordination is not possible, detect and report incomplete cleanup instead of treating a timed second pass as complete. Add a test that recreates the database after the second pass.
🤖 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/lib/antigravity-db.ts` around lines 1219 - 1224, Replace the fixed
Bun.sleep(10) retry boundary in the deletion flow surrounding
removeConversationFromSummaryIndex and removeAntigravityConversationPaths with
coordination with the active SQLite connection owner. If coordination cannot
guarantee quiescence, verify all conversation artifacts are absent after cleanup
and report incomplete deletion rather than returning success; add coverage that
recreates the database after the second cleanup pass.
| const response = await fetch(url); | ||
| if (response.ok) { | ||
| return response; | ||
| } | ||
|
|
||
| lastError = `HTTP ${response.status}`; | ||
| } catch (error) { | ||
| lastError = error instanceof Error ? error.message : String(error); | ||
| } | ||
|
|
||
| await Bun.sleep(250); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
jq -r '.engines.bun' package.json
nl -ba src/package-smoke.ts | sed -n '86,106p'
curl -fsSL https://bun.sh/docs/api/fetch |
rg -io '.{0,80}(abort|signal|timeout).{0,80}' |
head -n 20 || trueRepository: ragaeeb/spiracha
Length of output: 203
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Bun engine: '
jq -r '.engines.bun' package.json
printf '\nwaitForServer probe loop:\n'
awk 'NR>=86 && NR<=115' src/package-smoke.ts
printf '\nSearch waitForServer definitions/usages:\n'
grep -Rn "waitForServer\|deadline\|fetch\\(" src/package-smoke.ts || trueRepository: ragaeeb/spiracha
Length of output: 1363
🌐 Web query:
Bun fetch abort signal timeout API documentation
💡 Result:
In Bun, you can handle timeouts for fetch requests using the standard AbortSignal.timeout API or, in more recent versions, a direct timeout option [1][2]. Standard AbortSignal.timeout To set a timeout for a fetch request, pass an AbortSignal created with AbortSignal.timeout(milliseconds) to the signal property in the fetch options [1][3]: const response = await fetch("https://example.com", { signal: AbortSignal.timeout(1000), // Aborts after 1000ms }); Direct timeout option Recent updates to Bun have added a shorthand numeric timeout option to the fetch API for increased convenience [2]: const response = await fetch("https://example.com", { timeout: 1000, // Aborts after 1000ms }); Key Considerations - AbortSignal support: Bun continues to support the standard Web API AbortSignal for canceling requests [2]. If the timeout elapses, the fetch promise will reject with an error (typically a TimeoutError or AbortError) [4]. - Troubleshooting: If you find that AbortSignal.timeout is not behaving as expected in specific networking scenarios (such as when a host drops packets), ensure you are on the latest version of Bun, as ongoing fixes have been implemented to improve signal propagation and socket cancellation [4].
Citations:
- 1: https://bun.com/docs/runtime/networking/fetch
- 2: Add
timeout: numberoption to fetch oven-sh/bun#19767 - 3: https://github.com/oven-sh/bun/blob/6618e7f7/docs/runtime/networking/fetch.mdx
- 4:
AbortSignal.timeoutdoes nothing infetchwhen the host drops all packets oven-sh/bun#18536
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'STARTUP_TIMEOUT_MS values/usages:\n'
grep -Rn "STARTUP_TIMEOUT_MS\|waitForServer" src/package-smoke.ts || true
printf '\nProbe loop with STARTUP_TIMEOUT_MS nearby:\n'
awk 'NR>=1 && NR<=170' src/package-smoke.ts
printf '\nCheck BOM/nonstandard line encoding in src/package-smoke.ts:\n'
file src/package-smoke.ts
od -An -tx1 -v src/package-smoke.ts | head -n 3Repository: ragaeeb/spiracha
Length of output: 6288
🌐 Web query:
Bun fetch supports timeout option AbortSignal.timeout documentation
💡 Result:
Yes, Bun supports using AbortSignal.timeout with the fetch API [1][2]. This is the standard Web API approach for implementing request timeouts [3][4]. To use it, you pass an AbortSignal returned by AbortSignal.timeout(milliseconds) to the signal option in your fetch request [1][5]: const response = await fetch("http://example.com", { signal: AbortSignal.timeout(1000), // Aborts the request after 1000ms }); When the timeout is reached, the fetch promise will reject with a TimeoutError DOMException [3][4]. Additionally, Bun has introduced a first-class numeric timeout option for the fetch API, which allows you to specify a timeout directly in the options object [6][7]. According to recent developments, Bun's fetch now supports the following options for more granular control: - timeout: A numeric value (in milliseconds) for the whole-request wall-clock deadline [7]. - connectTimeout: A numeric value for the DNS, TCP, and TLS handshake phases [7]. - socketTimeout: A numeric value for inactivity in either direction [7]. These extensions provide more specific control than the standard Fetch API, though AbortSignal.timeout remains the standard, cross-platform method for implementing timeouts in fetch requests [1][3].
Citations:
- 1: https://bun.com/docs/runtime/networking/fetch
- 2: https://bun.sh/docs/runtime/networking/fetch
- 3: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static
- 4: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
- 5: https://bun.com/reference/globals/AbortSignal/timeout
- 6: Add
timeout: numberoption to fetch oven-sh/bun#19767 - 7: fetch: add connectTimeout, socketTimeout, and a whole-request timeout oven-sh/bun#33338
Bound each probe request by the remaining startup deadline.
Line 92 calls await fetch(url) without an abort signal. An indefinite fetch can run past STARTUP_TIMEOUT_MS and block the outer timeout. Pass AbortSignal.timeout(Math.max(1, deadline - Date.now())) in fetch options, and clear it after the attempt completes.
🤖 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/package-smoke.ts` around lines 92 - 102, Update the probe request around
fetch in the package smoke flow to pass an abort signal using the remaining
startup deadline, calculated as AbortSignal.timeout(Math.max(1, deadline -
Date.now())). Ensure the signal is cleared after each request attempt completes,
including failures, while preserving the existing response handling and retry
behavior.
| } catch (error) { | ||
| const [stdoutText, stderrText] = await Promise.all([stdoutPromise, stderrPromise]); | ||
| throw new Error( | ||
| [ | ||
| error instanceof Error ? error.message : String(error), | ||
| stdoutText.trim() ? `stdout:\n${stdoutText}` : '', | ||
| stderrText.trim() ? `stderr:\n${stderrText}` : '', | ||
| ] | ||
| .filter(Boolean) | ||
| .join('\n\n'), | ||
| ); | ||
| } finally { | ||
| proc.kill('SIGTERM'); | ||
| await Promise.all([ | ||
| proc.exited.catch(() => undefined), | ||
| stdoutPromise.catch(() => ''), | ||
| stderrPromise.catch(() => ''), | ||
| ]); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
nl -ba src/package-smoke.ts | sed -n '121,163p'
rg -n -C 3 'stdoutPromise|stderrPromise|proc\.kill|Promise\.all' src/package-smoke.tsRepository: ragaeeb/spiracha
Length of output: 194
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read relevant lines without nl.
awk '{printf "%6d\t%s\n", NR, $0}' src/package-smoke.ts | sed -n '121,163p'
# Locate the relevant symbols with context.
grep -n -C 3 'stdoutPromise\|stderrPromise\|proc\.kill\|Promise\.all' src/package-smoke.ts || trueRepository: ragaeeb/spiracha
Length of output: 3658
🌐 Web query:
Bun process spawn stdout pipe close after process exits Response readable stream
💡 Result:
In Bun, when you spawn a process using Bun.spawn with stdout set to "pipe" (the default), the stdout property is a ReadableStream that automatically closes once the spawned process finishes and all pending output has been read [1][2][3]. Key details regarding this behavior include: 1. Automatic Stream Closure: The ReadableStream represents the pipe connected to the child process's standard output [2][3]. When the process exits, Bun ensures the stream is closed after the remaining data is drained [4][5]. 2. Timing of Exit vs. Stream Completion: The closure of the pipe (and the ending of the stream) may occur slightly before or after the process exit callback (onExit) or the resolution of the exited promise, depending on system timing [2][6]. You should not rely on a specific ordering between the stream ending and the process exit event [2]. 3. Draining: If the process exits before you have finished reading all the stdout data, the pipe remains active until the data is fully consumed [4]. Internally, Bun maintains the stream until the data is drained, at which point the resources are cleaned up [4][5]. 4. Lazy Loading: If you use the lazy: true option, reading does not begin until you access the stdout property [2][7]. Even in this case, the stream will behave normally and close upon process termination and consumption of output. If you encounter issues where the stream appears not to close, ensure you are fully consuming the stream (e.g., using await proc.stdout.text or by piping it to another destination) [2][8]. Internal memory management improvements in Bun have addressed issues related to stream finalization to ensure resources are properly released after the process exits [9].
Citations:
- 1: https://bun.com/reference/bun/Subprocess
- 2: https://bun.sh/reference/bun/spawn
- 3: https://bun.sh/docs/runtime/child-process
- 4: https://github.com/oven-sh/bun/blob/6618e7f7/src/runtime/api/bun/subprocess.rs
- 5: https://github.com/oven-sh/bun/blob/7e57e529/src/bun.js/api/bun/subprocess.zig
- 6: https://bun.com/reference/bun/spawn
- 7: https://bun.com/reference/bun/Spawn/SpawnOptions
- 8: https://bun.com/docs/guides/process/spawn-stdout
- 9: fix(spawn): memory leak in
"pipe"d stdout/stderr oven-sh/bun#18316
🌐 Web query:
site:docs.bun.sh subprocess kill SIGTERM stdout pipe close immediately
💡 Result:
Bun’s docs indicate:
stdoutis aReadableStreamwhen configured as"pipe"(the default for stdout). (bun.com)proc.kill("SIGTERM")sends SIGTERM, but does not guarantee immediate process termination; the child may handle or ignore it. (bun.com)- Use
await proc.exitedto wait until the process actually exits. (bun.com)
const proc = Bun.spawn(cmd, { stdout: "pipe" });
proc.kill("SIGTERM");
await proc.exited;
const output = await proc.stdout.text();If you need immediate termination, use SIGKILL:
proc.kill("SIGKILL");
await proc.exited;If stdout remains open after the parent exits, a descendant process likely inherited the pipe; terminate the process group/tree, not only the direct child.
Citations:
- 1: https://bun.com/docs/runtime/child-process
- 2: https://bun.com/docs/runtime/child-process
- 3: https://bun.com/docs/runtime/child-process
🌐 Web query:
Bun subprocess kill stdout pipe closes before exited promise
💡 Result:
In Bun, the subprocess.exited promise resolves when the child process has exited [1][2]. The behavior regarding stdout pipes closing before this promise resolves is a known aspect of how Bun manages subprocess I/O [3][4]. If you are encountering issues where you lose access to stdout data, it is important to note: 1. Pipe Behavior: The stdout property is a ReadableStream [1][5]. When a process exits or is killed, the pipe is closed by the runtime to clean up resources [4]. If you have not fully consumed the stream by the time the process exits, you may lose the remaining buffered data [3]. 2. Consumption Strategy: To ensure you receive all output, you must continue reading from the stdout stream until it is exhausted (i.e., done is true in your reader loop), rather than relying solely on await subprocess.exited to signal that all data has been received [3]. 3. Known Issues and Fixes: Earlier versions of Bun had issues where killing a subprocess while reading its stdout could cause the Bun process to hang or improperly close the stream [3]. These issues have been addressed in subsequent releases [6][3]. Ensure you are using the latest version of Bun to take advantage of these stability improvements. 4. Correct Implementation: Always drain your stdout or stderr streams to completion [3]. A robust pattern involves initiating the reading process (e.g., via a for await loop or a getReader() loop) and concurrently or sequentially waiting for the exited promise [3]. If you find that data is consistently truncated or the stream closes prematurely despite full consumption, verify that your child process is properly flushing its own stdout buffer before exiting [3]. For complex shell-based subprocesses, be aware that some abstractions (like Bun Shell) may have specific limitations regarding streaming output during execution compared to Bun.spawn [7].
Citations:
- 1: https://bun.sh/docs/runtime/child-process
- 2: https://bun.com/docs/runtime/child-process
- 3: Killing a subprocess while
.read()ing a buffered stdout causes bun to remain open. oven-sh/bun#1498 - 4: https://github.com/oven-sh/bun/blob/6618e7f7/src/runtime/api/bun/subprocess.rs
- 5: https://github.com/oven-sh/bun/blob/6618e7f7/docs/runtime/child-process.mdx
- 6: Bun exits before
await subprocess.exitedresolves oven-sh/bun#3137 - 7: Reading stdout and stderr while a process created with Bun Shell is running oven-sh/bun#14693
Terminate the child before reading pipe output.
Lines 145-146 wait for stdoutPromise and stderrPromise while proc is still running. A failed probe can leave the child running and its pipes open, so the catch path waits before finally sends SIGTERM and the publish step can hit the CI job timeout.
Proposed fix
} catch (error) {
+ proc.kill('SIGTERM');
const [stdoutText, stderrText] = await Promise.all([stdoutPromise, stderrPromise]);
throw new Error(📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } catch (error) { | |
| const [stdoutText, stderrText] = await Promise.all([stdoutPromise, stderrPromise]); | |
| throw new Error( | |
| [ | |
| error instanceof Error ? error.message : String(error), | |
| stdoutText.trim() ? `stdout:\n${stdoutText}` : '', | |
| stderrText.trim() ? `stderr:\n${stderrText}` : '', | |
| ] | |
| .filter(Boolean) | |
| .join('\n\n'), | |
| ); | |
| } finally { | |
| proc.kill('SIGTERM'); | |
| await Promise.all([ | |
| proc.exited.catch(() => undefined), | |
| stdoutPromise.catch(() => ''), | |
| stderrPromise.catch(() => ''), | |
| ]); | |
| } catch (error) { | |
| proc.kill('SIGTERM'); | |
| const [stdoutText, stderrText] = await Promise.all([stdoutPromise, stderrPromise]); | |
| throw new Error( | |
| [ | |
| error instanceof Error ? error.message : String(error), | |
| stdoutText.trim() ? `stdout:\n${stdoutText}` : '', | |
| stderrText.trim() ? `stderr:\n${stderrText}` : '', | |
| ] | |
| .filter(Boolean) | |
| .join('\n\n'), | |
| ); | |
| } finally { | |
| proc.kill('SIGTERM'); | |
| await Promise.all([ | |
| proc.exited.catch(() => undefined), | |
| stdoutPromise.catch(() => ''), | |
| stderrPromise.catch(() => ''), | |
| ]); |
🤖 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/package-smoke.ts` around lines 145 - 162, Update the catch path around
the process probe so proc is terminated with SIGTERM before awaiting
stdoutPromise and stderrPromise. Then collect and include the pipe output as
currently done, while preserving the existing finally cleanup and error-message
composition.
Summary by CodeRabbit
GPT 5.6 Luna
Read
AGENTS.md. I couldn’t reproduce the current clean install failure; the packed artifact starts successfully. The missing protection was that no test exercised the published tarball throughbunx.Implemented:
prepublishOnlyenforcement in package.json.The gate packs the package, installs it in a clean temp consumer, runs exact
bunx, and verifies SSR HTML—catching missing Vite runtime chunks before publication.Verified:
prepublishOnlypassedGPT 5.6 Luna
Implemented TDD-style.
subagents/*.jsonlfiles and reads their.meta.jsonmetadata.Implement fingerprint #100 and #101.Claude Opus 5; parent sessions remainClaude Fable 5.Key files: claude-code-db.ts, Claude sessions table, regression tests.
The repeated parent prompt/title is expected: these are separate parent sessions launched from the same coordinator prompt; child metadata provides the distinct sub-agent titles.
Release protection also remains in place:
prepublishOnlynow runs the packedbunxsmoke test via package.json. The exact Vite error was not reproducible in a clean local tarball, so publishing now fails if the real packaged consumer path breaks.Verification: root
555 pass, UI313 pass, typecheck, lint, build, package smoke, and coverage all pass. The live table showed the expected nesting before the referenced Claude JSONL records disappeared externally; isolated fixtures verify the behavior without restoring or modifying those records.GPT 5.6 Sol
Fixed and verified.
Root causes:
annotations/<conversation-id>.pbtxtsidecar was never deleted, allowing summary metadata to linger.Changes:
The requested conversation was deleted. After refresh:
null.A byte-identical backup remains recoverable at .spiracha-backups.
Validation passed: lint, typecheck, build, 557 root tests, 313 UI tests, coverage gates, and
git diff --check. Existing unrelated Codex changes were preserved.GPT 5.6 Sol
Fixed the Antigravity route regression.
A deleted conversation’s 4 KB SQLite file was recreated without the required
stepstable. Discovery now ignores only this incomplete schema state while still surfacing malformed/corrupt databases.Verified the real
/antigravityroute loads without the error. Lint, typecheck, build, 559 root tests, 313 UI tests, coverage, and diff checks pass.Antigravity has separately recreated the previously deleted summary index entry; this fix preserves legitimate summary-only conversations rather than globally hiding them.
GPT 5.6 Sol
Fixed the Kiro cold-navigation experience.
The underlying Kiro filesystem scan measured only 8–9 ms, so no potentially stale caching was added.
Verification passed:
The pre-existing Antigravity changes remain untouched.
GPT 5.6 Sol
MiniMax is now optimized consistently with Kiro:
The underlying MiniMax scan measured 64–71 ms, so no stale caching was needed.
Verification passed: 559 tests, lint, typecheck, build, and diff checks.
GPT 5.6 Sol
Claude Code and MiniMax now share the same cold-load optimization:
Verification passed: 559 tests, lint, typecheck, production build, and diff checks. One unrelated file-watcher test timed out on the first run, then passed focused and in the complete rerun.
GPT 5.6 Sol
Implemented and verified.
composerHeaderstable.Live verification found one root orchestrator plus eleven nested subagents. The supplied request ID and message excerpts match. Cursor records that particular reused subagent as Grok 4.5, High reasoning—not Medium/Low—so Spiracha displays High faithfully.
Key changes: cursor-db.ts, cursor-threads-table.tsx, grok.index.tsx.
Validation passed:
bun testbun run lintbun run typecheckbun run buildgit diff --checkGPT 5.6 Sol
Fixed the multi-tab loading regression and added Cursor optimizations.
Live verification:
Verification passed:
git diff --checkKey changes: app-shell.tsx, codex-queries.ts, cursor.index.tsx, and Cursor regression test.
GPT 5.6 Luna
Fixed and consolidated.
The
apps/uisplit was legacy from the removed CLI. It created a second dependency/configuration root, which allowed stale TanStack/React packages to cause thehydrateStartcrash. The UI now lives undersrc/ui, using the root manifest, Vite config, TypeScript config, andnode_modules;apps/uiis gone.Also fixed:
bunx spirachanow launches from the package root./and/antigravitybrowser loads without errors.Verification:
fghtests: 42 passedfghonly importsspiracha/clientthrough its localfile:../spirachadependency; it does not start the UI or load Vite/TanStack browser code, so it was not causing the hydration failure. Its existing dirty files were left untouched. Refresh the older open Spiracha tabs once so they discard their stale Vite module graph.GPT 5.3 Codex Spark
Implemented and validated the requested fixes.
What changed
apps/ui/src/components/claude-code-sessions-table.tsx:20-42
SessionTitleCellnow uses depth-based indentation (paddingLeft:${depth * 0.75}rem``) for subagent rows instead of fixedpl-3.border-[var(--border)] border-l-2).src/lib/antigravity-db.ts:1200-1329
Bun.sleep(10)retry boundary with SQLite-owner coordination usingbun:sqlite(BEGIN IMMEDIATE/COMMITprobe) plus bounded lock polling.deletedConversationIds: []) when cleanup cannot be proven quiescent or artifacts still reappear.src/package-smoke.ts:92-102, 145-167
waitForServernow uses a per-attempt remaining-deadline abort signal (AbortSignal.timeout(Math.max(1, deadline - Date.now()))) and ensures cleanup (clearTimeout,abort) in afinallyblock.SIGTERMbefore awaitingstdoutPromise/stderrPromise; response/error handling and final cleanup were preserved.Test coverage updates
src/lib/antigravity-db.test.ts:1110-1160
apps/ui/src/components/source-tables.vitest.tsx:276-310
depth=2) and assert per-depth indentation (0.75rem,1.5rem), then adjusted query to avoid duplicate-title collision.Validation run
rtk bun test src/lib/antigravity-db.test.ts src/package-smoke.test.ts27 pass, 0 failrtk bunx vitest run apps/ui/src/components/source-tables.vitest.tsx --config apps/ui/vitest.config.ts1 file / 7 testsNo additional requested findings remain open; the earlier prior expectations that assumed successful deletion when recreating DB artifacts were replaced rather than fixed, per your requested semantics.
GPT 5.3 Codex Spark
Root cause identified: CI failed because the UI suite now imports
src/lib/antigravity-db.tsin Vitest, and that file had a top-levelbun:sqliteimport, which Vite cannot bundle for the UI test environment.Fix applied:
import { Database } from 'bun:sqlite'.bun:sqliteviaFunction-based dynamic import insidetryAcquireAntigravityConversationDbOwner.bun:sqliteis unavailable, ownership checks fallback safely without importing the module at startup.Validation now passing locally:
rtk bun run test:uirtk bun test src/ui-suite.test.tsrtk bun test src/lib/antigravity-db.test.ts src/package-smoke.test.tsrtk bunx vitest run apps/ui/src/components/source-tables.vitest.tsx --config apps/ui/vitest.config.ts