chore(dmworkbase): remove dead ThreadList component (#282)#478
Conversation
`packages/dmworkbase/src/Components/ThreadList/` is unreached at runtime: - 0 direct imports outside the component folder - not re-exported from `packages/dmworkbase/src/index.tsx` (so external packages cannot resolve `ThreadList` via `@octo/base`) - 0 references in `apps/web/src/**` or `apps/extension/src/**` - Storybook entry `ThreadList.stories.tsx` renders a placeholder, not the real component - name collisions in repo (`ThreadListStatus` type, `onThreadListError` callback, `isThreadListVisible` local var) are unrelated to the React component The real per-thread UI lives in `Components/ThreadPanel/index.tsx` (`renderListView` → `renderThreadItem`); deletion happens via a deeper menu (tracked separately in #280, opposite direction — over-permissive there). Removes ~508 lines (index.tsx, vm.ts, index.css, ThreadList.stories.tsx) with no behavior change. Fixes #282
OctoBoooot
left a comment
There was a problem hiding this comment.
Review: chore(dmworkbase): remove dead ThreadList component (#282) (#478)
Verdict: Approve
Clean dead-code deletion (−508, 4 files: the Components/ThreadList/ folder — component, vm, css, stories). The PR body's 5-layer reachability proof holds up under independent verification.
Independently verified the zero-importer claim (the load-bearing assertion for any "delete dead code" PR):
- No file outside
Components/ThreadList/imports the component or referencesComponents/ThreadList. - Not re-exported from
@octo/base(packages/dmworkbase/src/index.tsx— confirmed noThreadListexport). - The repo-wide
ThreadListgrep returns hits, but I checked each non-folder match and they're all the substring collisions the body correctly enumerated — none is a component import:channelDataSource.threadList(groupNo, ...)— datasource method, unrelatedbase.threadList.*— i18n keys for ThreadPanelThreadListStatus— type alias inService/Thread.ts("active"|"archived"|"all")isThreadListVisible— local boolean inPages/Chat/index.tsx(ThreadPanel toggle)onThreadListError/threadList:— callback + property indmworktodo/buildLinkableChannels.ts
- The real per-thread UI lives in
Components/ThreadPanel/(untouched), so deleting this folder doesn't remove any reachable feature. CI green.
The triage history is sound: #282 was filed as a delete-button permission bug, but the follow-up reachability check found the whole component unreached, so deleting it (Option A) is the correct resolution rather than fixing a render condition no user can hit.
Praise
- The 5-layer reachability table (direct import /
@octo/basere-export /apps/web/apps/extension/ Storybook) plus the explicit name-collision disambiguation (ThreadListStatus,onThreadListError,isThreadListVisibleall called out as unrelated) is exactly the evidence a dead-code deletion needs. It turned my verification from "hunt for any importer" into "confirm the enumerated collisions are real" — and every one checked out. This is how to make a deletion reviewable: prove the negative, and pre-empt the false-positive grep hits the reviewer will otherwise chase. - Distinguishing this (component fully unreached → delete) from #280 (the real ThreadPanel delete-gate, which is over-permissive — opposite direction) in the body keeps the two threads from being conflated. Precise scoping.
Out of scope (informational)
- Draft PR;
Fixes #282. Pure deletion with no co-located test removed beyond the stories stub — appropriate, since there's nothing left to test. CI typecheck/build is the right safety net here (a stale type reference would fail the build), and it's green.
Jerry-Xin
left a comment
There was a problem hiding this comment.
This PR is in scope for Mininglamp-OSS/octo-web and cleanly removes an unreachable dmworkbase component without leaving component imports, exports, or Storybook references behind.
🔴 Blocking: none.
💬 Non-blocking:
- 🔵 Suggestion: consider removing now-unused translation keys that were only consumed by the deleted component, such as
threadList.createdAt,threadList.createFirst,threadList.deleteConfirm,threadList.join, andthreadList.leaveinpackages/dmworkbase/src/i18n/locales/en-US.json:707andpackages/dmworkbase/src/i18n/locales/zh-CN.json:707. Keep the follow/unfollow keys, becauseThreadPanelstill uses them atpackages/dmworkbase/src/Components/ThreadPanel/index.tsx:1475andpackages/dmworkbase/src/Components/ThreadPanel/index.tsx:1750.
✅ Highlights:
- Verified no remaining
ThreadList,ThreadListVM,Components/ThreadList,Thread/ThreadList, or deleted CSS class references inpackagesorapps. - Confirmed
@octo/basedoes not export the deleted component. - The remaining
threadListAPI/type references are unrelated runtime data-source usage, not references to the deleted React component.
Verification caveat: I attempted pnpm --filter @octo/web build, but it could not run because node_modules is missing and vite is not installed in this checkout.
mochashanyao
left a comment
There was a problem hiding this comment.
[Octo-Q · automated review]
Verdict: Approve — no blocking findings; notes below (data-flow traced).
yujiawei
left a comment
There was a problem hiding this comment.
Code Review — PR #478 (octo-web)
Scope: delete-only dead-code removal of packages/dmworkbase/src/Components/ThreadList/ (4 files, 508 deletions, 0 additions). Reviewed against head 922e0f0a with merge-base 65eb9375.
1. Spec compliance
The diff does exactly what the PR describes and nothing more:
- No under-build: the triage decision (Option A) was to delete the unreachable folder; all four files (
index.tsx,vm.ts,index.css,ThreadList.stories.tsx) are removed. - No over-build: the PR touches only the
ThreadList/folder — no unrelated files, no new flags, no behavioral changes. - No deviation: pure deletion, matching the stated approach.
Spec: ✅
2. Code quality / safety
The only real risk in a delete-only PR is a surviving live reference. I independently re-verified the reachability claim rather than trusting the description, across three reference classes:
- Static imports — repo-wide search (excluding the deleted folder and
node_modules) for the component classThreadListandThreadListVM: 0 matches. Sibling components (ThreadCreate,ThreadPanel,ThreadIndicator) carry no import of it. - Dynamic / string refs — no
React.lazy, dynamicimport(),require(), route/registry maps, Storybook globs, jest/tsconfig/vite path entries referencing the component. A path-literal grep forComponents/ThreadListoutside the folder returns nothing. - Public API / barrel exports —
packages/dmworkbase/src/index.tsx(the@octo/basepublic surface) uses an explicit named-export list and never exportedThreadList; noexport *barrel transitively re-exports it. Downstream consumers of@octo/baseimport onlyThreadListStatus(an unrelated"active" | "archived" | "all"type alias), never the component.
The remaining ThreadList* hits in the tree are confirmed unrelated naming and not affected by this deletion:
ThreadListStatus— type alias inService/Thread.ts:41onThreadListError— callback option indmworktodo/utils/buildLinkableChannels.ts:42isThreadListVisible— local boolean inPages/Chat/index.tsx:1175(controls the ThreadPanel toggle)
The live per-thread UI continues to live in Components/ThreadPanel/, which is untouched. I also checked open sibling PRs; none re-introduces an import of the deleted component.
Coverage note / residual risk: all evidence is static analysis. The only theoretical gap is runtime reflection by the literal string "ThreadList" (e.g. a registry keyed by string) — no such pattern exists anywhere in the repo, so confidence is high. CI typecheck/build is the appropriate final gate and is expected to stay green.
Quality: Approved
3. Overall verdict
APPROVED — Spec ✅ and Quality Approved. Clean, well-evidenced dead-code removal with no live references in any reference class.
4. Suggestions (non-blocking)
- None required. Optionally, the
ThreadList.stories.tsxwas a placeholder stub kept only to satisfy a coverage check — its removal here is correct and removes a misleading "component exists" signal in Storybook.
根因 / 实现说明
packages/dmworkbase/src/Components/ThreadList/is dead code at runtime. Issue #282 was originally filed as a permission bug (over-restrictive delete-button render condition), but a follow-up 5-layer reachability check confirmed the component is unreached by any user path in the current build. This PR deletes the folder per the triage decision (Option A from the issue body).改动摘要
packages/dmworkbase/src/Components/ThreadList/:index.tsx(component)vm.ts(view model)index.cssThreadList.stories.tsx(Storybook placeholder, not the real component)Dead-code evidence (5 independent layers)
import ThreadListoutside the component folder@octo/basere-export (packages/dmworkbase/src/index.tsx)apps/web/src/**referencesapps/extension/src/**referencesName collisions verified unrelated to the React component:
ThreadListStatus— type alias"active" | "archived" | "all"inService/Thread.tsonThreadListError— callback option indmworktodo/utils/buildLinkableChannels.tsisThreadListVisible— local boolean inPages/Chat/index.tsx(controls ThreadPanel toggle)The real per-thread UI lives in
packages/dmworkbase/src/Components/ThreadPanel/index.tsx(renderListView→renderThreadItem); deletion happens via a deeper menu (tracked separately in #280, where the gate is over-permissive — opposite direction).测试
验证 (baseline diff)
pnpm build(chore tick budget 限制);由 CI 验证 typecheck + build.Fixes #282