Skip to content

feat: add Zencoder CLI agent support#144

Merged
wesm merged 7 commits intowesm:mainfrom
asotov-zen:extract-zencoder-integration-int-43b4
Mar 15, 2026
Merged

feat: add Zencoder CLI agent support#144
wesm merged 7 commits intowesm:mainfrom
asotov-zen:extract-zencoder-integration-int-43b4

Conversation

@asotov-zen
Copy link
Copy Markdown
Contributor

@asotov-zen asotov-zen commented Mar 11, 2026

Summary

Add Zencoder as the 9th supported coding agent. Zencoder CLI stores sessions as JSONL files in ~/.zencoder/sessions/ — this PR adds a parser, sync integration, and frontend rendering for those sessions.

Key capabilities:

  • Session parsing — handles Zencoder's JSONL format including system/user/assistant/tool/finish messages, tool call extraction, and continuation session detection
  • Subagent session linking — tool calls that spawn subagent sessions are linked to their child sessions via <session-id> XML tags in tool results, with inline preview and navigation
  • Skill block rendering[Skill: name]...[/Skill] blocks render as collapsible sections with teal accent, showing an 80-char preview when collapsed

Configurable via ZENCODER_DIR env var (defaults to ~/.zencoder/sessions).

Changes

Backend

  • internal/parser/zencoder.go — JSONL parser for Zencoder sessions
  • internal/parser/types.goAgentZencoder constant and registry entry
  • internal/parser/taxonomy.go — tool name mappings for Zencoder
  • internal/sync/engine.go — discovery, processing, and LinkSubagentSessions call
  • internal/db/sessions.goLinkSubagentSessions() for parent-child linking
  • Minor broadening in claude.go, content.go for subagent substring matching

Frontend

  • SkillBlock.svelte — collapsible skill block component
  • agents.ts — Zencoder agent entry (red accent)
  • content-parser.ts — skill segment type and extraction
  • SubagentInline.svelte — session metadata and "Open session" link
  • sessions.svelte.tsnavigateToSession() method

Test plan

  • 19 parser test functions covering: basic parsing, tool calls, reasoning blocks, tool results, user input filtering, continuation sessions, project extraction, empty sessions, discovery
  • go test ./internal/parser/... ./internal/sync/... ./internal/db/...
  • go vet clean
  • Manual: Zencoder sessions appear with correct agent color, subagent inline expansion works, skill blocks render and collapse

@asotov-zen asotov-zen changed the title feat: add Zencoder CLI agent support with subagent sessions and skill blocks feat: add Zencoder CLI agent support Mar 11, 2026
@wesm
Copy link
Copy Markdown
Owner

wesm commented Mar 11, 2026

You can just keep updating the same PR, you don't need to keep closing and opening PRs. Let me know when you think this is ready for review, and I will take it over

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 11, 2026

roborev: Combined Review (a6b7582)

Verdict: The PR successfully introduces
Zencoder session parsing, skills rendering, and subagent linking, but requires fixes for tool result population, message counting, and single-session sync regressions.

Medium

  • [internal/parser/zencoder.go](/home/roborev/.roborev/clones/wesm/agents
    view/internal/parser/zencoder.go), lines 207-210

    Zencoder tool results never populate ParsedToolResult.ContentRaw; only ContentLength is set. Downstream pairing relies on ContentRaw to fill toolCall.result_content in the
    DB and UI (pairToolResults decodes tr.ContentRaw), so Zencoder tool outputs will not show up in expanded tool blocks. Suggested fix: store block.Get("content").Raw in ParsedToolResult.ContentRaw, and add a sync/integration test that asserts tool_ calls.result_content is populated for a Zencoder session.

  • internal/sync/engine.go, lines 1663-1666
    and 1732-1735; internal/parser/zencoder.go, lines 88-92, 121-1
    27, 155-160, 468-471

    The parser distinguishes Zencoder system messages with IsSystem, and computes UserMessageCount excluding them, but the sync layer immediately recomputes counts from persisted db.Message rows using only
    Role == "user". Because Zencoder system/finish messages are stored as user-role rows, they will inflate user_message_count and any filters/analytics based on it. Suggested fix: preserve system-ness through the sync/DB path or compute post-filter user counts from parsed messages
    with IsSystem awareness. A sync-layer test for Zencoder should cover this.

  • internal/sync/engine.go, lines 1092
    -1097 and 1939-1943

    LinkSubagentSessions() now runs once at the end of bulk sync, but SyncSingleSession() no longer invokes it. That means explicit single-session re-syncs can leave Zencoder subagent children un
    linked until the next full sync, which is a regression from the earlier per-batch behavior. Suggested fix: call LinkSubagentSessions() after writeSessionFull() in the single-session path, or factor the linking step into a shared post-write hook. A targeted SyncSingleSession test should
    cover parent/child linking.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@asotov-zen
Copy link
Copy Markdown
Contributor Author

Hey @wesm
Sorry for openning and closing PRs. I just wanted to prepare clear one, which encapsulates only changes related to zencoder cli integration.

I am going to polish review feedback in this one and then we can proceed with merging.

Then I'll send my other proposed features as a separate PRs for clarity.

Thank you!

@wesm
Copy link
Copy Markdown
Owner

wesm commented Mar 11, 2026

No problem, in the future you can just force push the PR and update the PR description. I have a strict squash merge policy so I don't care about the intermediate state of any PR

asotov-zen added a commit to asotov-zen/agentsview that referenced this pull request Mar 11, 2026
Rewrote PR wesm#144 description to be concise and focused on the three
key features: session parsing, subagent linking, and skill blocks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 11, 2026

roborev: Combined Review (e8881ae)

Summary Verdict: The PR successfully implements Zencoder session support, but requires a logic fix to prevent indexing empty system-only sessions.

Medium

  • internal/parser/zencoder.go:408: The parser imports system-only Zencoder files as real sessions.
    handleSystemMessage() persists the environment banner as a message, and the empty-session guard only checks m.Content != "", meaning a brand-new chat with only the header and initial system block is kept despite the function comment stating otherwise. This creates blank/low-signal sessions in the database and sidebar.

    • Suggested fix: Require at least one non-system user/assistant message before returning a session, and add a regression test for header + system with no real conversation.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 12, 2026

roborev: Combined Review (8511d9d)

Summary: The PR successfully adds Zencoder support and session metadata features end-to-end, but introduces a frontend build break, a CORS exfiltration vulnerability, and several medium-severity regressions that must be addressed.

High

  • Frontend Build Break (Duplicate Imports & Branches)

    frontend/src/lib/components/content/MessageContent.svelte:11
    SkillBlock is imported twice under the same identifier, and the template rendering chain contains a duplicate segment.type === "skill" branch. This causes a compile-time error in the Svelte/TS module and breaks the build. Remove the duplicate import and keep a single skill-rendering branch.

  • CORS Ex
    filtration Risk on Raw Session Download

    internal/server/export.go:44, internal/server/server.go:144

    The new GET /api/v1/sessions/{id}/raw endpoint exposes the original session file over a simple GET. Because
    API responses use Access-Control-Allow-Origin: *, this significantly increases browser-based exfiltration risk, allowing any malicious webpage a user visits to read localhost session data. Restrict CORS to trusted origins, suppress it for this endpoint, and enforce proper auth/origin checks.

Medium

  • Command Injection
    Risk via resumeCommand

    [frontend/src/lib/components/layout/SessionBreadcrumb.svelte:255](/home/roborev/.roborev/clones/wesm/agentsview/frontend/src/lib/components/layout/SessionBreadcrumb.svelte
    #L255)
    The resumeCommand is built by directly interpolating session.cwd and rawId into a shell command (cd ${cwd} && claude --resume ${rawId}). A crafted cwd path containing shell metacharacters could lead to unintended command execution
    if copied and pasted by the user. Shell-escape the values with a POSIX helper or present them separately.

  • Subagent Linking Regression for Claude
    [internal/parser/claude.go:521](/home/roborev/.roborev/clones/wesm
    /agentsview/internal/parser/claude.go#L521)
    The updated annotateSubagentSessions() condition only matches calls where the category is "Task" or the name contains "subagent". Existing Claude Agent tool calls will no longer link to child sessions, reg
    ressing inline subagent navigation. Preserve the old tc.ToolName == "Agent" case or normalize "Agent" to "Task".

  • Analytics Metrics Skewed by System Messages
    [internal/db/analytics.go:475](/home/roborev/.robore
    v/clones/wesm/agentsview/internal/db/analytics.go#L475), [internal/db/analytics.go:1222](/home/roborev/.roborev/clones/wesm/agentsview/internal/db/analytics.go
    #L1222), internal/db/analytics.go:1512, internal/server/export.go:5
    39

    Synthetic/system-injected user rows are now persisted with is_system=true but still use role='user' . Downstream consumers (analytics, queries, exports) only key off role='user', causing metrics to skew and hidden system prompts to appear in exported HTML. Filter is_system rows out of analytics/export by default or make the downstream paths system-aware.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 12, 2026

roborev: Combined Review (849fc06)

Summary Verdict: The PR successfully adds Zencoder session support and raw downloads, but requires fixes for a frontend build break, a remote authentication failure, and timestamp sorting inconsistencies.

High

  • Raw Download Build
    Break & Authentication Failure
    • Locations: client.ts and [AppHeader.svelte](/home/robore
      v/.roborev/clones/wesm/agentsview/frontend/src/lib/components/layout/AppHeader.svelte#L44)
    • Issue: getRawUrl() interpolates BASE, which is no longer defined (replaced by getBase()), causing
      a frontend build break. Additionally, using window.open opens a bare URL without authentication headers, which will fail with a 401 Unauthorized in authenticated remote mode and may cause unexpected window behavior in the Tauri wrapper.
    • Suggested Fix: Replace getRawUrl() with a download Raw() helper (similar to downloadExport()) that uses getBase() and fetch with getAuthHeaders() to download the file as a blob and trigger the download via a temporary object URL.

Medium

  • Session Timestamp Inconsistencies
    • Locations:
      zencoder.go and [zencoder.go](/home/roborev/.roborev/clones/wesm/agentsview/
      internal/parser/zencoder.go#L495)
    • Issue: The parser reads per-message createdAt but does not update the session-level b.startedAt / b.endedAt. Files with missing or stale header times will sort and display incorrectly despite
      having accurate per-message timestamps.
    • Suggested Fix: Update session bounds on every non-zero message timestamp and add regression coverage for missing-header and stale-header cases.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 12, 2026

roborev: Combined Review (5308e04)

Summary Verdict: The changes successfully implement
Zencoder session support, but introduce a medium-severity issue where hidden system messages remain searchable without updating the UI state.

Medium

  • Hidden system messages appear in search results
    [MessageList.svelte](/home/roborev/.roborev/clones/wesm/agentsview/
    frontend/src/lib/components/content/MessageList.svelte) / CommandPalette.svelte / [search.go](/
    home/roborev/.roborev/clones/wesm/agentsview/internal/db/search.go)
    System messages are now stored instead of being dropped, and the default UI now hides them. Search was not updated accordingly, so FTS can return hits from hidden system content,
    and selecting one only scrolls to its ordinal; it does not enable showSystem. The result is a search hit that navigates to an invisible message. Suggested fix: exclude is_system=1 rows from search results, or return is_system in SearchResult and auto-enable ui .showSystem before scrolling. Add a regression test for searching text that exists only in a system message.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@asotov-zen asotov-zen force-pushed the extract-zencoder-integration-int-43b4 branch from 5308e04 to 44bce80 Compare March 12, 2026 14:53
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 12, 2026

roborev: Combined Review (44bce80)

Summary: Adds end-to-end support for the Zencoder CLI agent, including parsing, sync, and frontend integration, but requires
a fix for session-level timestamp initialization.

Medium

  • zencoder.go#L58, zencoder.go#L7
    0

    Per-message createdAt is now parsed, but the builder never folds those timestamps into startedAt / endedAt. If
    a Zencoder header is missing createdAt or updatedAt, the session-level timestamps still stay zero, so the sidebar/header can still show blank or sort incorrectly even though every message now has a timestamp.
    Suggested fix: Whenever ts is non-zero in processMessage,
    initialize startedAt if empty and advance endedAt to the latest seen value. Add a parser test for “header missing timestamps, messages have them”.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 12, 2026

roborev: Combined Review (a46cee4)

Verdict: The changes successfully add end-to-end support for Zencoder sessions, but introduce medium-severity regressions in Claude subagent linking and inconsistent user-message counting.

Medium

  • Claude Agent subagent calls no longer linked: The old annotateSubagentSessions logic explicitly handled both Task and Agent, but the new condition only annotates calls whose category is Task or whose raw name contains "subagent" in internal/parser/claude.go. This diff does not add an Agent -> Task taxonomy mapping in internal/parser/taxonomy.go, meaning existing Claude Agent tool calls can silently lose SubagentSessionID, breaking subagent navigation for already-supported Claude sessions.
    • Suggested fix: Keep the explicit tc.ToolName == "Agent" check or normalize Agent to Task, and add a regression test covering a Claude Agent tool call.
  • Inconsistent user-message counting for Zencoder: Zencoder system/injected messages are now stored as role = user plus a transient IsSystem flag in internal/parser/zencoder.go and internal/sync/engine.go. While postFilter Counts() was updated, DB-level consumers still count raw role='user' (e.g., prune filtering in internal/db/sessions.go and autonomy analytics in internal/db/analytics.go). This causes Zencoder sessions with instruction/reminder/finish messages to have inconsistent "user message
    " semantics across features.
    • Suggested fix: Persist is_system in the DB schema or avoid storing injected/system entries as role='user', then update the affected queries and add corresponding tests.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 12, 2026

roborev: Combined Review (665bf28)

Summary Verdict: The PR successfully integrates Zencoder session ingestion and frontend rendering, but introduces two medium-
severity logic issues around source file resolution and subagent classification.

Medium

  • internal/parser/zencoder.go:465-471 and internal/parser/zencoder.go:562-574
    ParseZencoderSession() uses the JSONL header id as the persisted session ID, but FindZencoderSourceFile() assumes the source filename is <rawID>.jsonl. Those two assumptions conflict as soon as the header ID and filename differ, and the parser tests already model that case. The result is that FindSource File(), session watching, and SyncSingleSession() can fail for valid Zencoder sessions.
    Suggested fix: Resolve the source file by scanning JSONL headers (or by trusting stored file_path when available) instead of reconstructing the filename from the session ID. Add an integration test around
    engine.FindSourceFile() / SyncSingleSession() for a Zencoder file whose header ID differs from its filename.

  • internal/parser/zencoder.go:473-485 and internal/db/sessions.go:559-579
    Zencoder sessions are initially classified from header parentId/creationReason, and LinkSubagentSessions() only rewrites rows whose parent_session_id is empty. If a spawned subagent session also carries a header parent, it will stay classified as continuation instead of
    subagent, which breaks child grouping and keeps it in analytics/search paths that intentionally exclude subagents.
    Suggested fix: When a tool_calls.subagent_session_id backlink exists, prefer relationship_type='subagent' even if parent_session_id is already populated, or at minimum update rows whose current relationship type is not subagent. Add a test covering a child session with both header ancestry and a subagent backlink.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 12, 2026

roborev: Combined Review (6c43420)

Verdict: Adds support for Zencoder CLI agent sessions, but
introduces a medium-severity bug with duplicate rendering of tagged reminder blocks.

Medium

  • Duplicate Zencoder reminder blocks: Tagged Zencoder reminder blocks will be shown twice in the UI: once as tool output and again as a separate system message. In internal/parser/zencoder.go:
    222
    the parser stores the full tool-result payload in ContentRaw, then in internal/parser/zencoder.go
    :242
    it also extracts tagged text blocks into systemParts. Later internal/parser/content.go:119
    decodes every text field back into tool_calls.result_content, so the reminder text appears in both places.
    *
    Suggested fix: Sanitize the Zencoder tool-result content before storing ContentRaw/ContentLength so tagged system blocks are excluded from paired tool output, and add an end-to-end test that asserts result_content contains only the actual tool output.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 13, 2026

roborev: Combined Review (3bf5994)

Summary: Integrates Zencoder CLI agent support end-to-end, including session parsing, sub
agent linking, and skill-block rendering, with one medium-severity issue identified in task formatting.

Medium

  1. internal/parser/content.go

The new Zencoder subagent tool path reuses formatTask(input), but formatTask only reads Claude-style fields like description and subagent_type. The Zencoder tests in this diff show inputs shaped like {"prompt":"...","agent":"..."}. That means rendered tool
text will collapse to [Task: ()] for Zencoder subagent calls, which degrades the main session view and any task-preview UI built from that content. Suggested fix: make formatTask fall back to prompt and agent when the Claude fields are empty, and add a parser
/content test for Zencoder subagent formatting.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 13, 2026

roborev: Combined Review (283afd5)

This PR adds support for the Zencoder CLI agent, parsing its sessions, subagent tool calls, and skill blocks, but introduces a few medium-severity issues
related to content parsing and session ID validation.

Medium

Unvalidated Zencoder session IDs are reused as URL path segments
Files: internal/parser/zencoder.go:58, internal/parser/zencoder.go:216, frontend/src/lib/ components/content/SubagentInline.svelte:26, frontend/src/lib/components/content/SubagentInline.svelte:41
The new parser accepts raw session IDs from Zencoder content in two places: the JSONL header (id) and `...</session-id

extracted from tool-result text. The new subagent UI then passes those IDs directly intogetSession()/getMessages()and session navigation without validation or URL encoding. Because the frontend API layer builds paths by string interpolation, a value like../config/githubresolves to/api/v1/config
/githubrather than staying under/api/v1/sessions/{id}. That lets malicious session content steer authenticated same-origin requests to unintended endpoints when a user expands or opens a subagent session. *Suggested remediation:* Validate Zencoder session IDs before storing/using them (strict allowlist such as UUID or [A-Za-z0-9_-]+, otherwise ignore/fallback), and URL-encode every sessionId when constructing client URLs (encodeURIComponent(sessionId)). Server-side rejection of invalid {id}` path values would provide defense in depth.

Task formatter misses Zencoder-
specific fields

File: internal/parser/content.go
The new Zencoder subagent tool names are routed through formatTask(...), but formatTask still only reads Claude-style fields (description, subagent_type). Zencoder examples in this diff use prompt and agent, so these blocks will render as effectively empty task labels like [Task: ()]. That is a user-facing regression in the new subagent flow and it is not covered by tests.
Suggested fix: Make formatTask fall back to prompt/agent when
description/subagent_type are absent, and add a parser/unit test that asserts the rendered task text for Zencoder inputs.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@wesm
Copy link
Copy Markdown
Owner

wesm commented Mar 14, 2026

I'll take a pass on this and work on getting it merged

asotov-zen and others added 2 commits March 14, 2026 13:20
… blocks

- Add Zencoder session parser with subagent linking and skill block extraction
- Move LinkSubagentSessions to run once per sync
- Extract per-message timestamps in Zencoder parser
- Persist is_system flag and filter system messages from search/analytics
- Resolve source file from stored path and fix subagent linking
- Strip tagged blocks from tool-result ContentRaw to prevent double rendering
…ll blocks

- Include is_system column in CopyOrphanedDataFrom message copy,
  probing the old DB schema so older sources still fall back safely.
  Without this, archived Zencoder system messages would lose their
  is_system flag and leak into search/analytics after a full resync.

- Make SkillBlock rendering respect the parent role visibility toggle
  (showText) in MessageContent.svelte, and update hasVisibleSegments
  to check role visibility for skill segments instead of returning
  true unconditionally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wesm wesm force-pushed the extract-zencoder-integration-int-43b4 branch from 283afd5 to 6b47d8e Compare March 14, 2026 22:36
…lity

- TestCopyOrphanedDataFrom_IsSystem: verifies is_system=1 survives
  orphan migration from a modern source DB.
- TestCopyOrphanedDataFrom_LegacyNoIsSystem: verifies copy succeeds
  from a legacy messages table without the is_system column, defaulting
  to false.
- hasVisibleSegments skill tests: verifies skill segments are hidden
  when the parent role filter (user/assistant) is off, and visible
  when it is on.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 14, 2026

roborev: Combined Review (6b47d8e)

Verdict: The PR
successfully implements Zencoder agent support, but introduces medium-severity bugs in subagent rendering and session navigation state management that need to be addressed.

Medium

  • Broken task labels/metadata for Zencoder subagent calls

    • Files: internal/parser/content.go,
      frontend/src/lib/components/content/ToolBlock.svelte
    • Details: Zencoder subagent calls will render with broken task labels/metadata. In internal/parser/content.go, the new subagent fallback sends these tools through formatTask(), but
      formatTask() only reads description and subagent_type. The Zencoder examples use prompt and agent, so the synthesized text becomes effectively empty ([Task: ()]). The frontend relies on the same assumption in ToolBlock.svelte, where taskMeta only looks at
      description/subagent_type. As a result, the main new subagent feature shows a useless collapsed header and loses the agent/type metadata.
    • Suggested Fix: Teach both the formatter and taskMeta to read Zencoder’s prompt/agent shape, and add a
      test that asserts the rendered label for a Zencoder subagent call.
  • Async selection race and duplicate appending in navigateToSession()

    • Files: frontend/src/lib/stores/sessions.svelte.ts, frontend/src/lib/components/content/Sub agentInline.svelte
    • Details: navigateToSession() has an async selection race and can append duplicates. In sessions.svelte.ts, activeSessionId is only set after awaiting api.getSession(). If a user clicks two “Open session” links quickly from Sub agentInline.svelte, the slower earlier request can overwrite the later selection. Because the existence check also happens before the await, concurrent calls can append the same session twice.
    • Suggested Fix: Set activeSessionId immediately, then guard late responses with a request token or a second dedupe check before appending.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

wesm and others added 2 commits March 14, 2026 17:55
Covers the case where the parent role filter is enabled but the tool
filter is disabled — skill blocks should still be visible since they
follow the role filter, not the tool filter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…der task fields

- Re-run LinkSubagentSessions after CopyOrphanedDataFrom in the resync
  path so copied orphaned subagent sessions are properly relinked via
  their tool_calls.subagent_session_id references.

- Fix SubagentInline "Open session" to use pendingNavTarget + router
  navigation (matching PinnedPage pattern) so it works from non-session
  pages like Pinned or Trash.

- Extend formatTask to fall back to Zencoder's prompt/agent fields when
  Claude-style description/subagent_type are absent, preventing empty
  [Task:  ()] labels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 14, 2026

roborev: Combined Review (4258910)

Summary: The backend and parser changes for Zencoder support are solid, but there
is a routing bug in the new frontend subagent navigation flow.

Medium

  • SubagentInline.svelte and [App.svelte](/tmp
    /agentsview-4258910/frontend/src/App.svelte#L166)
    : openAsSession() only sets pendingNavTarget and calls router.navigate("sessions"). From the normal session view, that is usually the same hash, so no
    hashchange fires, sessions.initFromParams() never consumes pendingNavTarget, and the new "Open session" link is a no-op. The helper that would actually load/select a child session, [sessions.svelte.ts](/tmp/agentsview-425891
    0/frontend/src/lib/stores/sessions.svelte.ts#L325)
    , is added but never used.
    • Suggested fix: Call await sessions.navigateToSession(sessionId) directly, and only route-change when router.route !== "sessions".

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 15, 2026

roborev: Combined Review (8a993ec)

Verdict: Clean - No issues found.

All successful reviews indicate the code is clean. (Note: The Codex default and security reviews failed to execute).


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

…une count

- Fix SubagentInline openAsSession to call navigateToSession directly
  when already on the sessions route, falling back to pendingNavTarget
  + router.navigate for cross-page navigation. The previous approach
  was a no-op on the sessions page since router.navigate returns false
  for the same hash.

- Exclude is_system=1 messages from FindPruneCandidates MaxMessages
  count so Zencoder system/skill messages don't inflate the user
  message count and cause sessions to be incorrectly filtered.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wesm wesm force-pushed the extract-zencoder-integration-int-43b4 branch from 8a993ec to 30b9079 Compare March 15, 2026 01:00
@wesm
Copy link
Copy Markdown
Owner

wesm commented Mar 15, 2026

Fixed codex in the CI poller so the full review should run now

Verify FindPruneCandidates MaxMessages ignores role='user' messages
with is_system=1, so Zencoder system/skill messages don't inflate
the user message count.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented Mar 15, 2026

roborev: Combined Review (75e0dd8)

Summary Verdict: The changes successfully implement Zencoder session support and subagent navigation, but there is one medium-severity issue regarding missing parent session
data during navigation.

Medium

  • sessions.svelte.ts: navigateToSession() only fetches the target session, not its parent
    chain. In the same reviewed tree, findRoot() in sessions.svelte.ts explicitly stops grouping when a parent is missing, and
    isSubagentAncestry() in MessageContent.svelte also depends on loaded ancestors. That means opening a filtered-out continuation child of a subagent
    can still render as a disconnected root and lose ancestry-based labeling/grouping. Suggested fix: when navigating to a missing session, recursively fetch parent_session_id ancestors before inserting/selecting, or add an API that returns the ancestry chain.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@wesm
Copy link
Copy Markdown
Owner

wesm commented Mar 15, 2026

This is good. Merging

@wesm wesm merged commit 9cd98c5 into wesm:main Mar 15, 2026
9 checks passed
@xechehot
Copy link
Copy Markdown

Thanks, Wes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants