Cut group sessions, camera, and the browser panel #9

Closed
opened 2026-07-29 17:32:06 +00:00 by aiko · 6 comments
Owner

What to build

Remove the three surfaces the redesign drops, before anything is built on top of them.

Group / multi-user sessions. Half-finished upstream (invite-dialog.tsx and use-invite-dialog.ts are empty files) and the receiver metaphor is single-listener by design. Remove GroupContext, the group drawer, the entry point, and the group.* i18n keys. Keep the name/avatar fields on AI messages — they identify the character, not a group member.

Camera. Removed entirely, context and all.

Browser panel. Removed entirely.

Screen capture stays in the tree, unwired — it is reworked into a grant in #21, not deleted here. (An earlier edit of this issue said to delete it, on the basis that #21 was permanently cut. #21 is reopened: Hermes does support image input, just not on the /v1/runs endpoint the bridge uses.)

Design reference: docs/design/denpa-receiver/README.md (card ids 1a, 4a… index into Denpa Receiver.dc.html, openable in a browser).

Acceptance criteria

  • No GroupContext, group drawer, or group entry point remains; group.* i18n keys gone
  • name/avatar on AI messages still work
  • Camera context and UI gone
  • Browser panel gone
  • npm run typecheck, npm run lint and the test suite pass
  • App still builds and connects

Blocked by

None - can start immediately

## What to build Remove the three surfaces the redesign drops, before anything is built on top of them. **Group / multi-user sessions.** Half-finished upstream (`invite-dialog.tsx` and `use-invite-dialog.ts` are empty files) and the receiver metaphor is single-listener by design. Remove `GroupContext`, the group drawer, the entry point, and the `group.*` i18n keys. **Keep the `name`/`avatar` fields on AI messages** — they identify the character, not a group member. **Camera.** Removed entirely, context and all. **Browser panel.** Removed entirely. Screen capture **stays in the tree**, unwired — it is reworked into a grant in #21, not deleted here. (An earlier edit of this issue said to delete it, on the basis that #21 was permanently cut. #21 is reopened: Hermes does support image input, just not on the `/v1/runs` endpoint the bridge uses.) Design reference: `docs/design/denpa-receiver/README.md` (card ids `1a`, `4a`… index into `Denpa Receiver.dc.html`, openable in a browser). ## Acceptance criteria - [ ] No `GroupContext`, group drawer, or group entry point remains; `group.*` i18n keys gone - [ ] `name`/`avatar` on AI messages still work - [ ] Camera context and UI gone - [ ] Browser panel gone - [ ] `npm run typecheck`, `npm run lint` and the test suite pass - [ ] App still builds and connects ## Blocked by None - can start immediately
Author
Owner

Screen-capture scope changed under this issue

This issue says "Screen capture stays in the tree for now — it is reworked into a grant in a later slice, not deleted here." That later slice was #21 (画面共有), which has since been cut: HermesAgent.chat() builds its prompt from input_data.texts only and never reads input_data.images, so a captured frame has nowhere to go and nothing can request one.

#21's closing note says the removal "makes that removal total rather than partial" — i.e. it expects this issue to take the screen-capture code with the camera and browser panel, not preserve it for a rework that is no longer coming.

Worth confirming which you want before this is picked up, because the two issues currently point in opposite directions:

  • Delete it too — matches #21's expectation, leaves no dead capture path in the tree.
  • Keep it parked — matches this issue as written, and costs nothing but unused code if image support later lands (#21 reopens "if the Hermes agent path grows image support").

Either is defensible; the drift is that both are currently written down.

## Screen-capture scope changed under this issue This issue says *"Screen capture stays in the tree for now — it is reworked into a grant in a later slice, not deleted here."* That later slice was #21 (画面共有), which has since been **cut**: `HermesAgent.chat()` builds its prompt from `input_data.texts` only and never reads `input_data.images`, so a captured frame has nowhere to go and nothing can request one. #21's closing note says the removal *"makes that removal total rather than partial"* — i.e. it expects this issue to take the screen-capture code with the camera and browser panel, not preserve it for a rework that is no longer coming. Worth confirming which you want before this is picked up, because the two issues currently point in opposite directions: - **Delete it too** — matches #21's expectation, leaves no dead capture path in the tree. - **Keep it parked** — matches this issue as written, and costs nothing but unused code if image support later lands (#21 reopens *"if the Hermes agent path grows image support"*). Either is defensible; the drift is that both are currently written down.
Author
Owner

Reverting the screen-capture instruction — keep it parked

My earlier comment and body edit said to delete the screen-capture path along with the camera and browser panel, following #21's "total rather than partial" note. #21 is reopened, so that no longer holds: the blocker was misidentified as "Hermes has no image support" when Hermes does have it, on /v1/chat/completions rather than the /v1/runs endpoint the bridge uses (api_server.py:471-547 vs :6084+).

Back to this issue as originally written: camera and browser panel are removed entirely; screen capture stays in the tree, unwired, for the grant rework in #21.

Apologies for the churn — the direction changed twice in one session. This is the settled version, and it matches what the issue said before I touched it.

## Reverting the screen-capture instruction — keep it parked My earlier comment and body edit said to delete the screen-capture path along with the camera and browser panel, following #21's *"total rather than partial"* note. **#21 is reopened**, so that no longer holds: the blocker was misidentified as "Hermes has no image support" when Hermes does have it, on `/v1/chat/completions` rather than the `/v1/runs` endpoint the bridge uses (`api_server.py:471-547` vs `:6084+`). Back to this issue as originally written: **camera and browser panel are removed entirely; screen capture stays in the tree**, unwired, for the grant rework in #21. Apologies for the churn — the direction changed twice in one session. This is the settled version, and it matches what the issue said before I touched it.
Author
Owner

Screen capture: keep it, and now for a positive reason

Small correction to the reference in this issue. It says screen capture stays in the tree for the grant rework in #21 - #21 is now closed and refiled as #31, which is unblocked: under ADR-0001 a captured frame is a MessageType.PHOTO MessageEvent that Hermes routes through its own vision pipeline.

So the capture path is not parked speculatively any more; it is about to be used. Camera and browser panel still go, entirely.

## Screen capture: keep it, and now for a positive reason Small correction to the reference in this issue. It says screen capture stays in the tree for the grant rework in #21 - #21 is now closed and refiled as **#31**, which is *unblocked*: under ADR-0001 a captured frame is a `MessageType.PHOTO` MessageEvent that Hermes routes through its own vision pipeline. So the capture path is not parked speculatively any more; it is about to be used. Camera and browser panel still go, entirely.
Author
Owner

Landed on issue/denpa-9-cut-group-camera-browser

Deletion only, 187 insertions / 1195 deletions across 26 files. npm test is 207 passed in 23 files (main was 200 in 22). npm run typecheck still reports exactly 585 errors, the same number as main, and none of them are in a file this branch touched.

Files deleted outright

context/group-context.tsx, context/camera-context.tsx, context/browser-context.tsx, components/sidebar/group-drawer.tsx, components/sidebar/invite-dialog.tsx (was empty), components/sidebar/camera-panel.tsx, components/sidebar/browser-panel.tsx, hooks/sidebar/use-group-drawer.tsx, hooks/sidebar/use-invite-dialog.ts (was empty), hooks/sidebar/use-camera-panel.ts.

Consumers followed

  • App.tsxGroupProvider, CameraProvider and BrowserProvider unmounted; nothing is left wrapping an empty subtree. ScreenCaptureProvider is now the outermost provider.
  • websocket-handler.tsxgroup-update and group-operation-result cases gone, the browser_view branch inside tool_call_status gone, setSelfUid call gone, dep array trimmed.
  • websocket-service.tsxmembers, is_owner, client_uid and the whole browser_view shape dropped from MessageEvent.
  • background.tsx / bgurl-context.tsx / use-general-settings.ts / general.tsx — the camera-background path, including the 設定 toggle, is gone; the background image select is now unconditional.
  • use-media-capture.tsx — keeps the screen path, loses the camera one. ImageData.source is now 'screen' only.
  • bottom-tab.tsx — 画面 is the only remaining tab.
  • sidebar.tsx — the FiUsers group entry point is gone.
  • Dead style blocks removed with their components: sidebarStyles.cameraPanel, sidebarStyles.browserPanel, sidebarStyles.groupDrawer, canvasStyles.background.video.
  • CLAUDE.md no longer lists GroupContext as a core context provider or group sessions as a feature.

i18n

group.* gone from both en and zh, plus sidebar.camera, sidebar.browser, sidebar.browserSession, sidebar.noBrowserSession, footer.cameraControl, footer.cameraStopping, settings.general.useCameraBackground, error.cameraApiNotSupported, error.noCameraFound, error.failedStartCamera, error.failedStartBackgroundCamera, error.enterValidUuid. A repo-wide grep for every one of those keys and symbols returns nothing outside the guard test.

Tests

Added, none fixed, none deleted. No test on main covered group, camera or the browser panel, so there was nothing to fix or remove — the 200 that were green before are the same 200, untouched.

New: src/renderer/src/cut-surfaces.test.ts, 7 cases in the source-scanning style chrome-is-mounted.test.ts already uses. It walks the renderer tree and fails if any of the three creeps back — a re-added provider, hook or panel; a re-added group-update / add-client-to-group / browser_view on the wire; a re-added i18n key. Watched it fail 4/7 before the deletion and pass 7/7 after. The three that passed from the start are the survivor assertions, which is the point: screen capture still in the tree (screen-capture-context, screen-panel, use-capture-screen, and useMediaCapture still reaching for the screen stream), 画面 still the tab, and name/avatar still flowing from MessageEvent through appendAIMessage to the log rail.

Followed the third comment here, not the first: screen capture is kept, for #31.

Assumed / left out

Two entries in the ledger. Short version: client_uid was dropped from the wire because GroupContext.setSelfUid was its only consumer; and sidebar.tsx, bottom-tab.tsx, screen-panel.tsx, background.tsx and footer.tsx are all unreferenced from App.tsx since the receiver chrome landed, but I left the files in place and only cleaned the group/camera/browser references inside them — deleting the whole upstream layout is the chrome owner's call, not this issue's.

Not verified: I cannot run the app or look at rendered output, so "app still builds and connects" rests on the typecheck delta and the suite, not on a launch.

## Landed on `issue/denpa-9-cut-group-camera-browser` Deletion only, 187 insertions / 1195 deletions across 26 files. `npm test` is **207 passed in 23 files** (main was 200 in 22). `npm run typecheck` still reports exactly **585** errors, the same number as `main`, and none of them are in a file this branch touched. ### Files deleted outright `context/group-context.tsx`, `context/camera-context.tsx`, `context/browser-context.tsx`, `components/sidebar/group-drawer.tsx`, `components/sidebar/invite-dialog.tsx` (was empty), `components/sidebar/camera-panel.tsx`, `components/sidebar/browser-panel.tsx`, `hooks/sidebar/use-group-drawer.tsx`, `hooks/sidebar/use-invite-dialog.ts` (was empty), `hooks/sidebar/use-camera-panel.ts`. ### Consumers followed - `App.tsx` — `GroupProvider`, `CameraProvider` and `BrowserProvider` unmounted; nothing is left wrapping an empty subtree. `ScreenCaptureProvider` is now the outermost provider. - `websocket-handler.tsx` — `group-update` and `group-operation-result` cases gone, the `browser_view` branch inside `tool_call_status` gone, `setSelfUid` call gone, dep array trimmed. - `websocket-service.tsx` — `members`, `is_owner`, `client_uid` and the whole `browser_view` shape dropped from `MessageEvent`. - `background.tsx` / `bgurl-context.tsx` / `use-general-settings.ts` / `general.tsx` — the camera-background path, including the 設定 toggle, is gone; the background image select is now unconditional. - `use-media-capture.tsx` — keeps the screen path, loses the camera one. `ImageData.source` is now `'screen'` only. - `bottom-tab.tsx` — 画面 is the only remaining tab. - `sidebar.tsx` — the `FiUsers` group entry point is gone. - Dead style blocks removed with their components: `sidebarStyles.cameraPanel`, `sidebarStyles.browserPanel`, `sidebarStyles.groupDrawer`, `canvasStyles.background.video`. - `CLAUDE.md` no longer lists `GroupContext` as a core context provider or group sessions as a feature. ### i18n `group.*` gone from both `en` and `zh`, plus `sidebar.camera`, `sidebar.browser`, `sidebar.browserSession`, `sidebar.noBrowserSession`, `footer.cameraControl`, `footer.cameraStopping`, `settings.general.useCameraBackground`, `error.cameraApiNotSupported`, `error.noCameraFound`, `error.failedStartCamera`, `error.failedStartBackgroundCamera`, `error.enterValidUuid`. A repo-wide grep for every one of those keys and symbols returns nothing outside the guard test. ### Tests **Added, none fixed, none deleted.** No test on `main` covered group, camera or the browser panel, so there was nothing to fix or remove — the 200 that were green before are the same 200, untouched. New: `src/renderer/src/cut-surfaces.test.ts`, 7 cases in the source-scanning style `chrome-is-mounted.test.ts` already uses. It walks the renderer tree and fails if any of the three creeps back — a re-added provider, hook or panel; a re-added `group-update` / `add-client-to-group` / `browser_view` on the wire; a re-added i18n key. Watched it fail 4/7 before the deletion and pass 7/7 after. The three that passed from the start are the survivor assertions, which is the point: screen capture still in the tree (`screen-capture-context`, `screen-panel`, `use-capture-screen`, and `useMediaCapture` still reaching for the screen stream), 画面 still the tab, and `name`/`avatar` still flowing from `MessageEvent` through `appendAIMessage` to the log rail. Followed the third comment here, not the first: screen capture is kept, for #31. ### Assumed / left out Two entries in the ledger. Short version: `client_uid` was dropped from the wire because `GroupContext.setSelfUid` was its only consumer; and `sidebar.tsx`, `bottom-tab.tsx`, `screen-panel.tsx`, `background.tsx` and `footer.tsx` are all unreferenced from `App.tsx` since the receiver chrome landed, but I left the files in place and only cleaned the group/camera/browser references inside them — deleting the whole upstream layout is the chrome owner's call, not this issue's. Not verified: I cannot run the app or look at rendered output, so "app still builds and connects" rests on the typecheck delta and the suite, not on a launch.
Author
Owner

Branch: issue/denpa-9-cut-group-camera-browser (pushed, not merged, no PR).

What changed

Deleted outright: context/group-context.tsx, context/camera-context.tsx, context/browser-context.tsx, components/sidebar/group-drawer.tsx, components/sidebar/camera-panel.tsx, components/sidebar/browser-panel.tsx, hooks/sidebar/use-group-drawer.tsx, hooks/sidebar/use-camera-panel.ts, plus two already-empty files (components/sidebar/invite-dialog.tsx, hooks/sidebar/use-invite-dialog.ts).

Edited to remove references: App.tsx (unmounted GroupProvider / CameraProvider / BrowserProvider), services/websocket-handler.tsx (dropped group-update, group-operation-result, the browser_view branch, setSelfUid), services/websocket-service.tsx (dropped members, is_owner, client_uid, browser_view from MessageEvent), components/canvas/background.tsx (camera-background branch), components/canvas/canvas-styles.tsx (dead background.video), context/bgurl-context.tsx (useCameraBackground), hooks/sidebar/setting/use-general-settings.ts (handleCameraToggle and the camera setting), components/sidebar/setting/general.tsx (camera switch gone, background fields now unconditional), hooks/utils/use-media-capture.tsx (camera path removed, screen path kept), components/sidebar/bottom-tab.tsx (screen is the only tab), components/sidebar/sidebar.tsx (group entry point), components/sidebar/sidebar-styles.tsx (cameraPanel, browserPanel, groupDrawer blocks), both locales/{en,zh}/translation.json, and CLAUDE.md (it claimed GroupContext and group sessions as core, which the issue flagged).

Also cut during review follow-up, in hooks/utils/use-audio-task.ts: the audio-play-start sendMessage block and the dead speaker_uid field, plus forwarded from MessageEvent and forwarded: message.forwarded || false in the handler. That message existed only so the server could echo a speaking turn to other group members. Verified against the go-between rather than assumed: src/open_llm_vtuber/websocket_handler.py:303-308 has no handler for it and only whitelists frontend-playback-complete from the unknown-type warning, and prepare_audio_payload (utils/stream_audio.py:31,63,83) defaults forwarded: bool = False with no caller passing True, so the client's if (!forwarded) guard was always true — one unhandled message and one server warning per utterance.

Tests

One new file, src/renderer/src/cut-surfaces.test.ts — a guard test, not behaviour coverage. It asserts by repo-wide grep that the removed symbols, the removed wire message types (group-update, group-operation-result, browser_view, audio-play-start, speaker_uid, forwarded) and the removed i18n keys do not reappear anywhere outside the test itself, and that the deleted files stay deleted. It also pins name/avatar on AI messages as present, since those sat next to the group fields and should not have gone with them. The wire assertions were confirmed red before the deletions: that block reported the 5 expected hits (use-audio-task.ts x3, websocket-handler.tsx, websocket-service.tsx), then green after.

 Test Files  23 passed (23)
      Tests  207 passed (207)
   Duration  6.09s

Main's baseline was 200 in 22 files. No test was deleted and none needed fixing — nothing in the existing suite touched the removed surfaces.

Typecheck: npm run typecheck reports exactly 585 errors, the documented main count. The only error in a file this branch touched is hooks/utils/use-audio-task.ts(18,6) TS6196 (Live2DModel declared but never used), verified byte-identical on the stashed pre-change tree. npm run lint was not run — pre-existing breakage per the brief, out of scope.

Deliberately left out

Screen capture in full: screen-capture-context.tsx, screen-panel.tsx, use-capture-screen.ts, and the screen branch of use-media-capture.tsx. The third and latest comment on this issue (07/30 00:04) settles that it stays, for #31 under ADR-0001 as a MessageType.PHOTO MessageEvent. The first two comments say otherwise; I followed the latest.

Also left standing: sidebar.tsx, bottom-tab.tsx, screen-panel.tsx, background.tsx and footer.tsx are all unreferenced from App.tsx since the receiver chrome landed. Deleting the whole upstream layout is the chrome owner's call, so I only cleaned the group/camera/browser references inside them. The 585 typecheck errors were not touched.

Not verified

I could not launch the app, so "still builds and connects" is unobserved — no tauri dev, no dev:web, no rendered output, no websocket against a live go-between. The evidence is indirect: the typecheck count is identical to main's with nothing new in any touched file, so no removal left a dangling import or broken type, and a repo-wide grep for every removed symbol, message type and i18n key comes back empty outside the guard test. What that cannot catch is a runtime-only regression — a Chakra Tabs.Root with a single child behaving differently now, or a translation lookup built from a runtime-assembled key rather than a literal. I also cannot see the rendered 設定 panel, so I cannot confirm the background-image select and custom-URL field look right now that the !useCameraBackground wrapper around them is gone.

Assumptions

  • client_uid on the wire existed only to feed GroupContext's selfUid, so it went out with members and is_owner. If the go-between wants to hand a client its own connection id for some non-group reason, the field has to come back.
  • error.enterValidUuid was only ever the group-invite validation message, so it went with the group keys.
  • Removing the camera-background toggle means the background-image select and custom-URL field are now always shown rather than conditionally; the toggle was the only reason for the condition.
  • Deleting the now-dead style blocks (sidebarStyles.cameraPanel / browserPanel / groupDrawer, canvasStyles.background.video) counts as part of the deletion, not unrelated cleanup — each existed solely for a deleted component.
  • Correcting CLAUDE.md's claim that GroupContext is a core context provider is in scope, since the issue named that listing.

All of the above are in .denpa-work/QUESTIONS.md.

Review findings

Two findings, both addressed, none skipped. The major one was the surviving audio-play-start emitter described above — a half-removed subsystem with a live emitter, correctly caught. The minor one was sidebar.live, orphaned in both locales once camera-panel.tsx's LiveIndicator went (screen-panel's indicator uses sidebar.screen); removed from both bundles and added to the guard test.

One out-of-band incident worth flagging because it is not visible in the diff: git worktree remove --force on the stale #9 worktree followed its node_modules junction and emptied denpa-client/node_modules, which is the shared target for the sibling worktrees too. Restored with npm ci in the main checkout (547 packages) and the suite is green on the restored tree, but if another agent hit a missing-module failure in that window, that is why. Noted in the ledger so the next teardown removes the junction first.

Branch: `issue/denpa-9-cut-group-camera-browser` (pushed, not merged, no PR). ## What changed Deleted outright: `context/group-context.tsx`, `context/camera-context.tsx`, `context/browser-context.tsx`, `components/sidebar/group-drawer.tsx`, `components/sidebar/camera-panel.tsx`, `components/sidebar/browser-panel.tsx`, `hooks/sidebar/use-group-drawer.tsx`, `hooks/sidebar/use-camera-panel.ts`, plus two already-empty files (`components/sidebar/invite-dialog.tsx`, `hooks/sidebar/use-invite-dialog.ts`). Edited to remove references: `App.tsx` (unmounted GroupProvider / CameraProvider / BrowserProvider), `services/websocket-handler.tsx` (dropped `group-update`, `group-operation-result`, the `browser_view` branch, `setSelfUid`), `services/websocket-service.tsx` (dropped `members`, `is_owner`, `client_uid`, `browser_view` from `MessageEvent`), `components/canvas/background.tsx` (camera-background branch), `components/canvas/canvas-styles.tsx` (dead `background.video`), `context/bgurl-context.tsx` (`useCameraBackground`), `hooks/sidebar/setting/use-general-settings.ts` (`handleCameraToggle` and the camera setting), `components/sidebar/setting/general.tsx` (camera switch gone, background fields now unconditional), `hooks/utils/use-media-capture.tsx` (camera path removed, screen path kept), `components/sidebar/bottom-tab.tsx` (screen is the only tab), `components/sidebar/sidebar.tsx` (group entry point), `components/sidebar/sidebar-styles.tsx` (`cameraPanel`, `browserPanel`, `groupDrawer` blocks), both `locales/{en,zh}/translation.json`, and `CLAUDE.md` (it claimed GroupContext and group sessions as core, which the issue flagged). Also cut during review follow-up, in `hooks/utils/use-audio-task.ts`: the `audio-play-start` `sendMessage` block and the dead `speaker_uid` field, plus `forwarded` from `MessageEvent` and `forwarded: message.forwarded || false` in the handler. That message existed only so the server could echo a speaking turn to other group members. Verified against the go-between rather than assumed: `src/open_llm_vtuber/websocket_handler.py:303-308` has no handler for it and only whitelists `frontend-playback-complete` from the unknown-type warning, and `prepare_audio_payload` (`utils/stream_audio.py:31,63,83`) defaults `forwarded: bool = False` with no caller passing `True`, so the client's `if (!forwarded)` guard was always true — one unhandled message and one server warning per utterance. ## Tests One new file, `src/renderer/src/cut-surfaces.test.ts` — a guard test, not behaviour coverage. It asserts by repo-wide grep that the removed symbols, the removed wire message types (`group-update`, `group-operation-result`, `browser_view`, `audio-play-start`, `speaker_uid`, `forwarded`) and the removed i18n keys do not reappear anywhere outside the test itself, and that the deleted files stay deleted. It also pins `name`/`avatar` on AI messages as *present*, since those sat next to the group fields and should not have gone with them. The wire assertions were confirmed red before the deletions: that block reported the 5 expected hits (`use-audio-task.ts` x3, `websocket-handler.tsx`, `websocket-service.tsx`), then green after. ``` Test Files 23 passed (23) Tests 207 passed (207) Duration 6.09s ``` Main's baseline was 200 in 22 files. No test was deleted and none needed fixing — nothing in the existing suite touched the removed surfaces. Typecheck: `npm run typecheck` reports exactly 585 errors, the documented `main` count. The only error in a file this branch touched is `hooks/utils/use-audio-task.ts(18,6)` TS6196 (`Live2DModel` declared but never used), verified byte-identical on the stashed pre-change tree. `npm run lint` was not run — pre-existing breakage per the brief, out of scope. ## Deliberately left out Screen capture in full: `screen-capture-context.tsx`, `screen-panel.tsx`, `use-capture-screen.ts`, and the screen branch of `use-media-capture.tsx`. The third and latest comment on this issue (07/30 00:04) settles that it stays, for #31 under ADR-0001 as a `MessageType.PHOTO` `MessageEvent`. The first two comments say otherwise; I followed the latest. Also left standing: `sidebar.tsx`, `bottom-tab.tsx`, `screen-panel.tsx`, `background.tsx` and `footer.tsx` are all unreferenced from `App.tsx` since the receiver chrome landed. Deleting the whole upstream layout is the chrome owner's call, so I only cleaned the group/camera/browser references *inside* them. The 585 typecheck errors were not touched. ## Not verified I could not launch the app, so "still builds and connects" is unobserved — no `tauri dev`, no `dev:web`, no rendered output, no websocket against a live go-between. The evidence is indirect: the typecheck count is identical to main's with nothing new in any touched file, so no removal left a dangling import or broken type, and a repo-wide grep for every removed symbol, message type and i18n key comes back empty outside the guard test. What that cannot catch is a runtime-only regression — a Chakra `Tabs.Root` with a single child behaving differently now, or a translation lookup built from a runtime-assembled key rather than a literal. I also cannot see the rendered 設定 panel, so I cannot confirm the background-image select and custom-URL field look right now that the `!useCameraBackground` wrapper around them is gone. ## Assumptions - `client_uid` on the wire existed only to feed GroupContext's `selfUid`, so it went out with `members` and `is_owner`. If the go-between wants to hand a client its own connection id for some non-group reason, the field has to come back. - `error.enterValidUuid` was only ever the group-invite validation message, so it went with the group keys. - Removing the camera-background toggle means the background-image select and custom-URL field are now always shown rather than conditionally; the toggle was the only reason for the condition. - Deleting the now-dead style blocks (`sidebarStyles.cameraPanel` / `browserPanel` / `groupDrawer`, `canvasStyles.background.video`) counts as part of the deletion, not unrelated cleanup — each existed solely for a deleted component. - Correcting `CLAUDE.md`'s claim that GroupContext is a core context provider is in scope, since the issue named that listing. All of the above are in `.denpa-work/QUESTIONS.md`. ## Review findings Two findings, both addressed, none skipped. The major one was the surviving `audio-play-start` emitter described above — a half-removed subsystem with a live emitter, correctly caught. The minor one was `sidebar.live`, orphaned in both locales once `camera-panel.tsx`'s `LiveIndicator` went (screen-panel's indicator uses `sidebar.screen`); removed from both bundles and added to the guard test. One out-of-band incident worth flagging because it is not visible in the diff: `git worktree remove --force` on the stale #9 worktree followed its `node_modules` junction and emptied `denpa-client/node_modules`, which is the shared target for the sibling worktrees too. Restored with `npm ci` in the main checkout (547 packages) and the suite is green on the restored tree, but if another agent hit a missing-module failure in that window, that is why. Noted in the ledger so the next teardown removes the junction first.
Author
Owner

Shipped. Merged to main at 19bf953 (phase B3 — remaining ungated).

Closed as part of reconciling the board with main: the autonomous run's policy was not to auto-close, so shipped work stayed open and the tracker read as though nothing had landed. That policy is now reversed — issues close when they land.

Shipped. Merged to `main` at [`19bf953`](https://git.aiko.works/aiko/denpa/commit/19bf953) (phase B3 — remaining ungated). Closed as part of reconciling the board with `main`: the autonomous run's policy was not to auto-close, so shipped work stayed open and the tracker read as though nothing had landed. That policy is now reversed — issues close when they land.
aiko closed this issue 2026-07-30 13:32:54 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiko/denpa#9
No description provided.