Skip to content

refactor(frontend): decompose sessions.js tool rendering into dispatc…#62

Merged
wpak-ai merged 5 commits into
masterfrom
refactor/sessions-tool-dispatch-registry
Jun 3, 2026
Merged

refactor(frontend): decompose sessions.js tool rendering into dispatc…#62
wpak-ai merged 5 commits into
masterfrom
refactor/sessions-tool-dispatch-registry

Conversation

@clean6378-max-it
Copy link
Copy Markdown
Collaborator

@clean6378-max-it clean6378-max-it commented Jun 2, 2026

closes #59

Summary

Decompose sessions.js tool rendering into static/js/render/ dispatch registry, mirroring backend utils/tool_dispatch.py.

  • Add TOOL_USE_RENDERERS and TOOL_RESULT_RENDERERS in static/js/render/registry.js
  • Extract one module per tool use type (render/tool_use/) and per result_type (render/tool_result/), with fallbacks for unknown tools
  • Slim sessions.js to workspace/session orchestration and message bubbles; tool cards delegate to the registry
  • Add Vitest tests in static/js/render/registry.test.js (registry keys, HTML escaping, getToolSummary, fallbacks)
  • Document frontend registry pattern in docs/architecture.md

Closes Chen W1 sprint item #1 (8 pt).

Motivation

static/js/sessions.js had long if/else chains for renderToolUse and renderToolResult. Every new tool type required editing that file. The backend already uses a dispatch table in utils/tool_dispatch.py; this PR brings the same pattern to the frontend with direct key lookup plus fallback renderers.

Test plan

  • npm test — includes new registry.test.js (25 tests total)
  • pytest -q — 324 passed
  • Manual: open a session with Bash, Read, Task, and TodoWrite tool use/results — UI unchanged vs pre-refactor
  • Manual: python app.py --host 127.0.0.1 --port 5000 smoke on a real session

Acceptance criteria

  • Dispatch registry: map of tool types → render functions (use + result)
  • Each tool type renderer in its own module/function
  • sessions.js no longer contains multi-page tool if/else chains
  • New tool types addable by registering one function in registry.js
  • All existing rendering behavior preserved (manual smoke pending)
  • Vitest tests covering registry + ≥2 renderers
  • npm test and pytest -q green locally

Out of scope

  • Backend tool_dispatch.py changes
  • Windows CI matrix (Wednesday #2)
  • Removing export_count (Thursday #4)

Files changed

Area Path
Registry static/js/render/registry.js
Tool use static/js/render/tool_use/*.js
Tool result static/js/render/tool_result/*.js
Orchestration static/js/sessions.js
Tests static/js/render/registry.test.js
Docs docs/architecture.md

Summary by CodeRabbit

  • New Features

    • Centralized renderer registry and new renderers for many tool uses/results (bash, file read/write/edit, glob, grep, web fetch/search, task, todo, user input, plan) with richer summaries and optional detailed bodies.
  • Refactor

    • Client-side rendering consolidated to use shared registry and helpers.
  • Bug Fixes

    • Improved HTML-escaping, truncation, and safer fallback handling.
  • Tests

    • Added tests covering registry dispatch, escaping, summaries, and fallback behavior.
  • Documentation

    • Architecture docs updated to describe the registry and test setup.

…h registry

Extract tool use and tool result rendering from sessions.js into
static/js/render/ with TOOL_USE_RENDERERS and TOOL_RESULT_RENDERERS,
one module per tool type, mirroring utils/tool_dispatch.py. sessions.js
retains workspace and message orchestration only.
Add Vitest coverage for registry wiring, HTML escaping, and getToolSummary.
Document the frontend registry in docs/architecture.md. No intended
visual or behavior change for existing sessions.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 248556f9-7209-43ce-80bf-2186304cc038

📥 Commits

Reviewing files that changed from the base of the PR and between 2c1bedd and 6a01ac5.

📒 Files selected for processing (6)
  • static/js/render/constants.js
  • static/js/render/registry.js
  • static/js/render/registry.test.js
  • static/js/render/tool_result/fallback.js
  • static/js/render/tool_result/utils.js
  • static/js/render/tool_use/fallback.js
✅ Files skipped from review due to trivial changes (1)
  • static/js/render/constants.js
🚧 Files skipped from review as they are similar to previous changes (5)
  • static/js/render/tool_result/fallback.js
  • static/js/render/tool_result/utils.js
  • static/js/render/registry.js
  • static/js/render/tool_use/fallback.js
  • static/js/render/registry.test.js

📝 Walkthrough

Walkthrough

Refactors frontend tool rendering into a centralized registry (static/js/render/registry.js), adds per-tool use/result renderer modules, updates sessions.js to call the registry, and adds Vitest coverage plus docs noting the registry and its test.

Changes

Tool Rendering Registry Decomposition

Layer / File(s) Summary
Registry dispatch foundation and wiring
static/js/render/registry.js
Central registry maps tool names to TOOL_USE_RENDERERS and result types to TOOL_RESULT_RENDERERS. Exports renderToolUse and renderToolResult which dispatch to registered renderers or fallbacks, and re-exports getToolSummary and toolResultHasBody.
Registry wiring and escape testing
static/js/render/registry.test.js
Vitest suite validates core tool-use and tool-result registrations, HTML-escaping in renderers (Bash/read/stdout), summary formatting, and fallback/dispatch behavior including todo count and unknown types.
Tool-use helpers and summary
static/js/render/tool_use/common.js, static/js/render/tool_use/summary.js
wrapToolUse(summary, body) builds tool-call HTML; getToolSummary(name, inp) produces plain one-line summaries per tool type.
Individual tool-use renderers
static/js/render/tool_use/{bash,read,write,edit,glob,grep,task,todo_write,ask_user_question,web_fetch,web_search,fallback}.js
Per-tool renderers build escaped/truncated HTML bodies and return wrapped results; WebFetch/WebSearch preserve legacy fallback JSON behavior via wrappers.
Tool-result helpers
static/js/render/tool_result/common.js, static/js/render/tool_result/utils.js
finishToolResult(summary, body) wraps results in <details> or a simple <div>; toolResultHasBody(parsed) detects when result types include body content.
Individual tool-result renderers
static/js/render/tool_result/{bash,file_read,file_edit,file_write,glob,grep,web_search,web_fetch,task,todo_write,user_input,plan,fallback}.js
Per-result renderers format summaries and optional bodies (bash: status + truncated stdout/stderr; file ops: paths/line counts; task: status/duration/tokens/retrieval/description; todo_write/user_input: escaped lists; fallback: summary-only).
Sessions.js integration
static/js/sessions.js
Now imports renderToolUse, renderToolResult, and toolResultHasBody from render/registry.js, removing prior in-file rendering logic.
Architecture documentation
docs/architecture.md
Adds render/registry.js to the frontend module list and documents the registry role and test wiring.
sequenceDiagram
  participant Sessions as static/js/sessions.js
  participant Registry as static/js/render/registry.js
  participant ToolUse as static/js/render/tool_use/*
  participant ToolResult as static/js/render/tool_result/*

  Sessions->>Registry: renderToolUse(tool)
  Registry->>ToolUse: dispatch to registered renderer or fallback
  Sessions->>Registry: renderToolResult(parsed)
  Registry->>ToolResult: dispatch to registered renderer or fallback
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

"🐇
I nibbled up the monolith, now sprigs divide,
Each tool has its burrow, tidy side by side.
Registry hums softly, dispatch neat and clear,
Rendered bits stay safe — no mess, no fear.
Hop on, test the patch — the garden's in good cheer!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor(frontend): decompose sessions.js tool rendering into dispatc…' is directly related to the main change—extracting tool rendering logic from sessions.js into a dispatch registry pattern under static/js/render/.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #59: implements TOOL_USE_RENDERERS and TOOL_RESULT_RENDERERS registries, extracts per-tool renderers into separate modules, significantly reduces sessions.js, adds Vitest tests validating registry wiring and HTML escaping, preserves all tool rendering behavior with proper security (esc() usage), and documents the pattern in docs/architecture.md.
Out of Scope Changes check ✅ Passed All changes are directly scoped to decomposing the sessions.js tool rendering monolith: registry modules, per-tool renderers, constants, test suite, architecture documentation, and sessions.js refactoring—no out-of-scope modifications detected.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/sessions-tool-dispatch-registry

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

@clean6378-max-it clean6378-max-it self-assigned this Jun 2, 2026
Copy link
Copy Markdown

@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: 7

🤖 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 `@static/js/render/registry.js`:
- Around line 30-40: TOOL_USE_RENDERERS currently omits the known web tool names
so WebSearch and WebFetch calls fall back to the generic renderer; update the
registry constant TOOL_USE_RENDERERS to include entries for WebSearch and
WebFetch mapping to the proper renderers (renderWebSearchUse and
renderWebFetchUse) and ensure those renderer functions are imported or
implemented in this module (or referenced correctly if they live elsewhere) so
web tool uses are rendered with the intended UI rather than the fallback.

In `@static/js/render/registry.test.js`:
- Around line 82-90: The test currently uses the real tool name "WebFetch" which
hides missing-registry bugs; update the test that calls renderToolUse(...) to
use a clearly fictitious tool name (e.g., "UnknownToolXYZ") so the JSON fallback
path is exercised, and add or update tests that explicitly register/cover the
real web tools (the registry/registration helper used by your codebase) so that
real web tools are asserted separately; locate references to renderToolUse and
the test block "renderToolUse fallback" and modify the tool name and add a
sibling test that calls the actual registry registration function for web tools
to ensure they are covered.

In `@static/js/render/tool_result/bash.js`:
- Around line 5-7: The status string can end up as "exit undefined" when
parsed.exit_code is missing; update the logic around exitCode/status/summary to
provide a fallback (e.g., use a safeExit variable like typeof parsed.exit_code
=== 'number' ? parsed.exit_code : 'unknown' or 'N/A') and use that safeExit in
the final branch that builds status and summary so the summary never contains
"undefined".

In `@static/js/render/tool_result/utils.js`:
- Around line 1-7: toolResultHasBody currently skips several result types that
render only a summary; update the function (toolResultHasBody) to treat
'file_write', 'grep', 'plan', 'web_fetch', and 'web_search' as having a body
when their renderers will show a summary by checking parsed.summary (or
parsed.summary_html) or parsed.title — e.g., add explicit conditions for those
result_type values that return true when parsed.summary || parsed.summary_html
|| parsed.title is truthy so renderUser() will emit the standalone tool-result
bubble for summary-only results.

In `@static/js/render/tool_use/edit.js`:
- Around line 9-10: The current checks drop sections when old_string or
new_string are empty strings; change the truthiness guards to explicit
undefined/null checks so empty strings still render: replace the conditions
around inp.old_string and inp.new_string with checks like "if (inp.old_string
!== undefined && inp.old_string !== null)" (and same for inp.new_string) so the
Edit tool will render empty Old/New sections rather than omitting them; keep the
existing esc(truncate(...)) rendering logic and styling unchanged.

In `@static/js/render/tool_use/summary.js`:
- Around line 4-11: The Bash, WebFetch, and WebSearch branches return raw
user-controlled strings (inp.command, inp.url, inp.query) which must be
HTML-escaped; update the summary generation so these branches call the existing
esc() helper (and still apply truncate() where used) instead of returning raw
values—i.e., for the Bash branch use esc(inp.command || '') wrapped/applied with
truncate as needed, and for WebFetch/WebSearch call esc(inp.url || '') and
esc(inp.query || '') (respectively) when building their returned strings so all
user text flows through esc().

In `@static/js/render/tool_use/write.js`:
- Around line 8-9: The content section is omitted when inp.content is an empty
string because the code uses a truthiness check; change the condition to detect
the presence of the content property instead (e.g., check "'content' in inp" or
"inp.content !== undefined") so that an explicit empty-string write still
renders the Content section; update the block that builds the body (referencing
variables body, inp.content, esc, and truncate) to use that presence check and
keep the existing esc/truncate rendering logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3ff48947-b9d5-413a-9a4b-98e8da1c6f5d

📥 Commits

Reviewing files that changed from the base of the PR and between 4b2a4c6 and 512e71c.

📒 Files selected for processing (31)
  • docs/architecture.md
  • static/js/render/registry.js
  • static/js/render/registry.test.js
  • static/js/render/tool_result/bash.js
  • static/js/render/tool_result/common.js
  • static/js/render/tool_result/fallback.js
  • static/js/render/tool_result/file_edit.js
  • static/js/render/tool_result/file_read.js
  • static/js/render/tool_result/file_write.js
  • static/js/render/tool_result/glob.js
  • static/js/render/tool_result/grep.js
  • static/js/render/tool_result/plan.js
  • static/js/render/tool_result/task.js
  • static/js/render/tool_result/todo_write.js
  • static/js/render/tool_result/user_input.js
  • static/js/render/tool_result/utils.js
  • static/js/render/tool_result/web_fetch.js
  • static/js/render/tool_result/web_search.js
  • static/js/render/tool_use/ask_user_question.js
  • static/js/render/tool_use/bash.js
  • static/js/render/tool_use/common.js
  • static/js/render/tool_use/edit.js
  • static/js/render/tool_use/fallback.js
  • static/js/render/tool_use/glob.js
  • static/js/render/tool_use/grep.js
  • static/js/render/tool_use/read.js
  • static/js/render/tool_use/summary.js
  • static/js/render/tool_use/task.js
  • static/js/render/tool_use/todo_write.js
  • static/js/render/tool_use/write.js
  • static/js/sessions.js

Comment thread static/js/render/registry.js
Comment thread static/js/render/registry.test.js
Comment thread static/js/render/tool_result/bash.js
Comment thread static/js/render/tool_result/utils.js
Comment thread static/js/render/tool_use/edit.js
Comment thread static/js/render/tool_use/summary.js
Comment thread static/js/render/tool_use/write.js
…h registry

Extract tool use and tool result rendering from sessions.js into
static/js/render/ with TOOL_USE_RENDERERS and TOOL_RESULT_RENDERERS,
one module per tool type, mirroring utils/tool_dispatch.py. Register
WebFetch and WebSearch explicitly (JSON body via fallback helper).
Fix bash result summary when exit_code is missing (use "unknown" not
"exit undefined"). Tighten Vitest: fictitious tool for fallback path,
separate WebFetch/WebSearch registry tests.
Add Vitest coverage for registry wiring, HTML escaping, and getToolSummary.
Document the frontend registry in docs/architecture.md. No intended
visual or behavior change for existing sessions.
@clean6378-max-it
Copy link
Copy Markdown
Collaborator Author

Please review this PR fully again
@CodeRabbit

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

@clean6378-max-it Sure! I'll perform a full review of PR #62 right away.

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@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: 2

🧹 Nitpick comments (1)
static/js/render/registry.test.js (1)

99-107: 💤 Low value

Assertions don't actually distinguish the WebFetch renderer from the JSON fallback.

The test name promises "not unknown-tool path", but tool-call/example.com/<pre><code> would also appear in the generic JSON fallback. The real guarantee comes from the registration check at Lines 28-32. Consider asserting something renderer-specific (or it's fine to rely on the registration test and rename this case).

🤖 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 `@static/js/render/registry.test.js` around lines 99 - 107, The test "renders
WebFetch via registry (JSON body, not unknown-tool path)" doesn't prove the
WebFetch renderer was used because the assertions (tool-call, example.com,
<pre><code>) also match the JSON fallback; update the test to either assert a
WebFetch-specific output (e.g. a unique CSS class/HTML fragment produced by the
WebFetch renderer) by calling renderToolUse({name: 'WebFetch', ...}) and
checking for that marker, or rename the test to indicate it only verifies
rendering output generically and rely on the existing registration test that
confirms the renderer is registered.
🤖 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 `@static/js/render/registry.js`:
- Around line 61-70: The registry lookups in renderToolUse and renderToolResult
rely on direct property access (TOOL_USE_RENDERERS[name] ?? fallback) which can
hit prototype properties like "__proto__" or "constructor"; change both
dispatches to use an own-property check (e.g.,
Object.prototype.hasOwnProperty.call(TOOL_USE_RENDERERS, name) ?
TOOL_USE_RENDERERS[name] : renderToolUseFallback and similarly for
TOOL_RESULT_RENDERERS with parsed.result_type/rt) so that only own keys are used
and the fallback is reliably chosen when no renderer is defined.

In `@static/js/render/tool_result/todo_write.js`:
- Around line 5-13: The summary count can mismatch because count is set from
parsed.todo_count independently of parsed.todos; change the summary computation
to derive count from the same source you iterate (e.g., set count = typeof
parsed.todo_count === 'number' ? parsed.todo_count : (parsed.todos ?
parsed.todos.length : 0)) and then build summary = `Todos updated (${count}
items)` so that count, parsed.todo_count and parsed.todos stay consistent with
the rendered body; update the code surrounding count, summary and the for-loop
that iterates parsed.todos accordingly.

---

Nitpick comments:
In `@static/js/render/registry.test.js`:
- Around line 99-107: The test "renders WebFetch via registry (JSON body, not
unknown-tool path)" doesn't prove the WebFetch renderer was used because the
assertions (tool-call, example.com, <pre><code>) also match the JSON fallback;
update the test to either assert a WebFetch-specific output (e.g. a unique CSS
class/HTML fragment produced by the WebFetch renderer) by calling
renderToolUse({name: 'WebFetch', ...}) and checking for that marker, or rename
the test to indicate it only verifies rendering output generically and rely on
the existing registration test that confirms the renderer is registered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2a608499-9abb-4bd1-960a-ccdd21707366

📥 Commits

Reviewing files that changed from the base of the PR and between 4b2a4c6 and 4d1edfd.

📒 Files selected for processing (33)
  • docs/architecture.md
  • static/js/render/registry.js
  • static/js/render/registry.test.js
  • static/js/render/tool_result/bash.js
  • static/js/render/tool_result/common.js
  • static/js/render/tool_result/fallback.js
  • static/js/render/tool_result/file_edit.js
  • static/js/render/tool_result/file_read.js
  • static/js/render/tool_result/file_write.js
  • static/js/render/tool_result/glob.js
  • static/js/render/tool_result/grep.js
  • static/js/render/tool_result/plan.js
  • static/js/render/tool_result/task.js
  • static/js/render/tool_result/todo_write.js
  • static/js/render/tool_result/user_input.js
  • static/js/render/tool_result/utils.js
  • static/js/render/tool_result/web_fetch.js
  • static/js/render/tool_result/web_search.js
  • static/js/render/tool_use/ask_user_question.js
  • static/js/render/tool_use/bash.js
  • static/js/render/tool_use/common.js
  • static/js/render/tool_use/edit.js
  • static/js/render/tool_use/fallback.js
  • static/js/render/tool_use/glob.js
  • static/js/render/tool_use/grep.js
  • static/js/render/tool_use/read.js
  • static/js/render/tool_use/summary.js
  • static/js/render/tool_use/task.js
  • static/js/render/tool_use/todo_write.js
  • static/js/render/tool_use/web_fetch.js
  • static/js/render/tool_use/web_search.js
  • static/js/render/tool_use/write.js
  • static/js/sessions.js

Comment thread static/js/render/registry.js Outdated
Comment thread static/js/render/tool_result/todo_write.js Outdated
…h registry

Extract tool use and tool result rendering into static/js/render/ with
TOOL_USE_RENDERERS and TOOL_RESULT_RENDERERS (one module per type),
mirroring utils/tool_dispatch.py. sessions.js keeps workspace orchestration.
Harden registry dispatch with hasOwnProperty lookups; register WebFetch and
WebSearch explicitly (JSON body via fallback helper). Fix bash result summary
when exit_code is missing; align todo_write summary count with parsed.todos.
Add Vitest for registry wiring, escaping, fallback vs registered tools, and
todo_write count consistency. Document render/registry.js in architecture.md.
@timon0305
Copy link
Copy Markdown
Collaborator

The string 'unknown' is used as both "the value when tool.name is empty" and (implicitly, via the hasOwnProperty miss) the fallback-routing key. Three places agree on this convention. If anyone ever adds TOOL_USE_RENDERERS.unknown = …, behavior silently changes. Either add a short comment naming it a sentinel, or use a Symbol-based sentinel that can't collide with a real tool name. Minor — current code works.

Comment thread static/js/render/registry.js
Comment thread static/js/render/registry.test.js
…Body

Introduce UNKNOWN_DISPATCH_KEY sentinel with documented non-registration
rule. Guard renderToolUse/renderToolResult against null input; guard
toolResultHasBody similarly. Add Vitest coverage for sentinel, null args,
and toolResultHasBody contract used by sessions.js.
@clean6378-max-it
Copy link
Copy Markdown
Collaborator Author

@CodeRabbit, do you think my last commit addressed 3 comments of @timon0305 ?

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# List all PR review comments by timon0305
gh pr view 62 --repo cppalliance/claude-code-chat-browser --json reviews,comments 2>/dev/null | jq '.reviews[] | select(.author.login == "timon0305")' 2>/dev/null || true

echo "--- PR review comments ---"
gh api repos/cppalliance/claude-code-chat-browser/pulls/62/comments 2>/dev/null | jq '.[] | select(.user.login == "timon0305") | {id: .id, body: .body, path: .path, line: .line}' 2>/dev/null || true

echo "--- PR issue comments ---"
gh api repos/cppalliance/claude-code-chat-browser/issues/62/comments 2>/dev/null | jq '.[] | select(.user.login == "timon0305") | {id: .id, body: .body}' 2>/dev/null || true

Length of output: 2391


🏁 Script executed:

#!/bin/bash
# Read the new constants.js sentinel file
cat static/js/render/constants.js

echo "--- registry.js ---"
cat static/js/render/registry.js

echo "--- fallback.js (tool_use) ---"
cat static/js/render/tool_use/fallback.js

echo "--- fallback.js (tool_result) ---"
cat static/js/render/tool_result/fallback.js

Length of output: 4780



@clean6378-max-it — Yes, your last commit addressed all three of timon0305's comments. Here's a breakdown:

# timon0305's concern What the commit did Verdict
1 'unknown' string used as both a missing-name sentinel and a fallback-routing key — silent breakage if TOOL_USE_RENDERERS.unknown is ever registered Introduced UNKNOWN_DISPATCH_KEY = 'unknown' in static/js/render/constants.js with an explicit JSDoc: "do not add UNKNOWN_DISPATCH_KEY to TOOL*RENDERERS"; tests additionally assert the sentinel is not an own property of either registry ✅ Addressed (took the "named constant + comment" path timon0305 explicitly listed as sufficient)
2 renderToolUse/renderToolResult dereference their argument immediately — a null/undefined input would throw a TypeError into the session rendering loop Added if (!tool) return '' and if (!parsed) return '' guards at the top of both dispatch functions ✅ Addressed
3 toolResultHasBody was the only exported helper with no test coverage Added Vitest cases for bash, user_input, todo_write, and task confirming when a body is expected vs. not ✅ Addressed

The only design choice worth noting: the sentinel remains a string constant rather than a Symbol. timon0305 offered both as valid options, and the named constant with the explicit "do not register" rule is a clean, doc-friendly solution — especially since Symbols can't be serialised as JSON keys, which would complicate any future debugging.

(´• ω •`) 🐇

@clean6378-max-it clean6378-max-it requested a review from wpak-ai June 2, 2026 22:52
@wpak-ai wpak-ai merged commit 965618b into master Jun 3, 2026
6 checks passed
@wpak-ai wpak-ai deleted the refactor/sessions-tool-dispatch-registry branch June 3, 2026 00:11
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.

claude-code-chat-browser: Decompose sessions.js tool rendering into dispatch registry

3 participants