Refactor worker sessions to use HTTP server architecture#78
Conversation
| const clientCache = new Map<string, WorkerClient>(); | ||
|
|
||
| async function getClient(containerName: string): Promise<WorkerClient> { | ||
| let client = clientCache.get(containerName); | ||
| if (!client) { | ||
| client = await createWorkerClient(containerName); | ||
| clientCache.set(containerName, client); | ||
| } | ||
| return client; | ||
| } |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
|
|
||
| private async startWorkerServer(containerName: string): Promise<void> { | ||
| const WORKER_PORT = 7392; | ||
| const ip = await docker.getContainerIp(containerName); | ||
| if (!ip) { | ||
| console.warn( | ||
| `[sync] Could not get container IP for ${containerName}, skipping worker server` |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
Replace subprocess CLI calls with an HTTP server for session discovery: - Add `perry worker serve` command that starts HTTP server on port 7392 - Create SessionIndex class for caching sessions with file watchers - Worker server auto-starts when workspace initializes - Agent uses worker client to query sessions via container networking - Unified code path for host and container session discovery This improves performance by caching session data and watching for changes instead of re-parsing files on every request. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
616fb5e to
af2696a
Compare
| await Promise.all([this.discoverClaudeSessions(), this.discoverOpencodeSessions()]); | ||
|
|
||
| this.initialized = true; | ||
| } | ||
|
|
||
| async refresh(): Promise<void> { | ||
| await Promise.all([this.discoverClaudeSessions(), this.discoverOpencodeSessions()]); |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
af2696a to
6e0dd14
Compare
- Handle Claude session format where message.content is a string - Add messageCount to OpenCode session discovery - Add integration tests for session titles and message counts - Update test helper to support running as specific user Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
| const textContent = entry.message?.content?.find((c) => c.type === 'text'); | ||
| if (textContent?.text) { |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
The Claude session format can have message.content as either a string or an array of content blocks. Updated both the type definition and the conversion function to handle both cases properly. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
| if (entry.type === 'assistant') { | ||
| const content = entry.message?.content; | ||
| if (!Array.isArray(content)) return null; |
There was a problem hiding this comment.
Bug: The convertClaudeEntry function incorrectly drops assistant messages when their content is a string, as it only handles array-based content. This is a regression from the previous parser.
Severity: CRITICAL
🔍 Detailed Analysis
The convertClaudeEntry function, when processing assistant messages, checks if the content is an array and returns null if it is not. However, the type definition for message.content allows it to be a string, and the previous parser implementation handled this case. This regression causes any assistant message with string-based content to be silently dropped from the session history. This results in incomplete message histories being displayed to users, as the messageCount will be out of sync with the messages returned by getMessages().
💡 Suggested Fix
Update the convertClaudeEntry function to handle string content for assistant messages, not just array content. Add a check for typeof content === 'string' and process it accordingly, similar to how user messages are handled. This will prevent assistant messages from being dropped and align the function with its type definitions.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/worker/session-index.ts#L328-L330
Potential issue: The `convertClaudeEntry` function, when processing assistant messages,
checks if the `content` is an array and returns `null` if it is not. However, the type
definition for `message.content` allows it to be a string, and the previous parser
implementation handled this case. This regression causes any assistant message with
string-based content to be silently dropped from the session history. This results in
incomplete message histories being displayed to users, as the `messageCount` will be out
of sync with the messages returned by `getMessages()`.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 8434832
Summary
perry worker servecommand that starts HTTP server on port 7392Architecture
This change improves performance by:
The worker server is synced to containers (not baked into images) and started on workspace initialization.
Test plan
bun run validatepasses🤖 Generated with Claude Code