Skip to content

refactor: split the oversized client modules along their seams - #425

Merged
Grivn merged 8 commits into
mainfrom
claude/client-module-splits
Oct 17, 2026
Merged

Grivn merged 8 commits into
mainfrom
claude/client-module-splits

Conversation

@Grivn

@Grivn Grivn commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

摘要 / Summary

把三个过大的客户端模块按已有的接缝拆开,只搬移代码:记忆空间的 pages.tsx(1,774 行)变成按名称再导出的入口加 8 个模块;Git 同步区块(823 行)移出 GitHub 登录、仓库选择与高级设置;记忆系统工作台(953 行)移出状态页与 Source 管理页,并把工作区的状态、目录与导航状态放进三个 hook。用户看到的内容与行为不变,公开导出不变。

Three oversized client modules split along their seams by moving code verbatim: Memory Spaces' pages.tsx (1,774 lines) becomes a barrel of named re-exports over eight modules; the Git sync section (823) gives the GitHub sign-in, the repository picker and the advanced settings their own files; the Memory System workbench (953) moves the Status and Source management pages out and its workspace's status, catalog and navigation state into three hooks. Nothing users see or do changes, and the public exports are the same.

关联 Issue 或背景 / Related Issue or Context

Item M6 of the technical-debt review after v0.5.31 (#413).

涉及区域 / Affected Areas

  • Host 激活、Headless 或 bundle / Host activation, Headless, or bundle
  • 运行时记忆 / Runtime Memory
  • 项目档案 / Project Documents
  • 记忆空间或 Provider / Memory Spaces or Providers
  • 子 Agent 或 Agent 工作流 / Subagent or Agent workflow
  • Web UI 或对话交互 / Web UI or conversation interaction
  • 设置、存储或安全 / Settings, storage, or security
  • CLI、RPC、命令或工具 / CLI, RPC, commands, or tools
  • 安装、更新或发布 / Installation, update, or release
  • 测试、构建或文档 / Tests, build, or documentation
  • 其他(请说明)/ Other (explain below)

PR 类型 / PR Type

  • 面向用户的功能或行为变更 / User-facing feature or behavior change
  • Bug 修复 / Bug fix
  • 增强或优化 / Enhancement or optimization
  • 兼容性适配 / Compatibility change
  • 维护或重构 / Maintenance or refactor
  • 测试或构建 / Tests or build

变更内容 / Changes

  • Memory Spaces src/client/pages.tsx (1,774 -> 8 lines): named re-exports over widgets.tsx, memory-graph.tsx, overview-page.tsx, explore-page.tsx, entities-page.tsx, persistence-strategy-dialog.tsx, remember-page.tsx, list-page.tsx; the barrel lists pages first so modules load in the same order.
  • src/client/MnemonSyncSection.tsx (823 -> 412): MnemonSyncGitHubConnect.tsx, MnemonSyncRepositoryPicker.tsx, MnemonSyncAdvancedSettings.tsx, sync-feedback.tsx and sync-repository-editor.ts (the props the editor and the sign-in share).
  • src/client/MnemonWorkbench.tsx (953 -> 449): StatusPage.tsx, SourceManagementPage.tsx, is-record.ts, and the hooks use-workspace-status.ts, use-source-catalog.ts, use-workspace-navigation.ts, each called where its state stood so hooks and effects run in the same order.
  • Code moved verbatim with a line-range script (only export keywords added); tests/client-modal-css.spec.ts now reads every client source instead of a hand-kept list. Record docs/pr-assets/client-module-splits with its harness. Changeset: dsh-mnemon and dsh-mnemon-source-memory-spaces patch.

最新代码确认 / Latest Codebase Confirmation

  • 我已基于最新 main 分支开发,或在提交前已 rebase 或合并最新 main。 / I developed from the latest main, or rebased or merged the latest main before submitting.

同步命令 / Sync command:

git fetch origin main
git merge origin/main

Branched from main at 03dd40a4 (#423), the latest main.

AI 编码披露 / AI Coding Disclosure

  • 完全 AI 编码:全部编程改动由 AI 产出,并由贡献者接受和审查。 / Fully AI-coded: AI produced all programming changes, which the contributor accepted and reviewed.
  • 部分 AI 辅助:AI 帮助编写或修改了部分内容。 / Partially AI-assisted: AI helped write or modify part of the change.
  • 未使用 AI 编码辅助。 / No AI coding assistance was used.

使用的 AI 模型 / AI model used: Claude Opus 5.5 (claude-opus-5-5)

使用的编码 Agent 工具 / Coding Agent tool used: Claude Code

仓库规范检查 / Repository Rules

  • 未修改 DSH 官方源码,未让 tsconfig 指向 DSH 源码 checkout,仅使用正式的 @deepseek-ai/* NPM 契约。 / I did not modify DSH source or point tsconfig at a DSH source checkout, and used only published @deepseek-ai/* NPM contracts.
  • Client 与 Host 边界仍以浏览器安全的 src/host/protocol.ts 为准,没有在两侧重复定义 wire DTO。 / The Client and Host boundary still uses browser-safe src/host/protocol.ts as the source for wire DTOs.
  • 持久化格式、RPC 权限、路径或凭据处理的变更包含兼容或拒绝路径、安全分析和相应测试。 / Changes to persistence formats, RPC authority, paths, or credentials include compatibility or rejection paths, security analysis, and tests.
  • 没有提交 token、密钥、私有记忆、未脱敏日志或生成的 lib/ 文件。 / I did not commit tokens, credentials, private memory, unredacted logs, or generated lib/ files.
  • 用户可见文案和长期文档已同步维护中文与英文版本,命令、配置键和路径保持一致。 / User-facing copy and long-lived documentation are synchronized in Chinese and English, with matching commands, configuration keys, and paths.
  • 会改变发布制品或其元数据的 PR 已添加 changeset;仅测试、CI 或站点文档变更可不添加。 / A PR that changes a published artifact or its metadata includes a changeset; test-only, CI-only, and site-documentation-only changes may omit one.
  • 新增和修改的代码、注释、文档、提交信息不含 emoji。 / New and modified code, comments, documentation, and commits contain no emoji.

兼容性与数据安全 / Compatibility and Data Safety

  • No markup, class name, copy key, RPC call, browser storage key or effect order changes. Built bundles: the Starter's lib/client.js differs only by MnemonWorkspace becoming the new function plus three hooks (every old statement still present); Memory Spaces' lib/client.js has the same 167 top-level statements, and both keep their load-time statements in the same order and identical CSS. Every other built file, including lib/index.js and the Starter's declarations, is byte-identical.
  • Public surface: the 772 names public entries expose are identical; Memory Spaces' ./client resolves to the same 23 names with identical types. Memory Spaces ships 8 more declaration files for its new internal modules, reachable only by a deep path outside its exports map. No peer floor moves.

本地验证 / Local Validation

执行的命令 / Commands run:

pnpm install --frozen-lockfile && pnpm run build && pnpm --workspace-concurrency=4 -r build && pnpm run build
pnpm run verify
MNEMON_CLI_PATH=/nonexistent/mnemon MNEMON_PLUGIN_VERIFY_CONCURRENCY=1 pnpm run verify:plugins
DSH_HOST_ROOT=<DSH 0.2.0-rc.2> pnpm run test:installed-dsh
pnpm exec vitest run tests/client-*

结果摘要 / Result summary:

  • verify passed (root tests 2,098 passed, 7 skipped in 149 files, the same as main; Memory Spaces 291 passed, 2 skipped; deterministic build; Headless; package); verify:plugins passed; installed DSH 0.2.0-rc.2: 2,095 passed, 10 skipped; tests/client-*: 396 passed in 32 files; release:intent covers both packages.
  • An independent review rebuilt main and the branch from scratch and confirmed the moves are verbatim (line multisets and in-order blocks; every identifier binds the same way, checked with the TypeScript checker), rendered the workbench on main and on the branch through ten steps with recording fakes (identical RPCs, subscriptions, anchor reads, scroll resets and byte-identical DOM snapshots; both layout and all 12 passive effects in order), and confirmed load order, CSS and the public surface. It found nothing must- or should-fix; its two nits (a type-only import cycle between the sync section and the sign-in, and a hand-kept file list in the dialog footer test) are fixed in 9482d145 with the bundle byte-identical.

用户可见变更证据 / Local Feature Evidence

证据 / Evidence: N/A, nothing users see changes; the record has the equivalence harness and the bundle comparison.

🤖 Generated with Claude Code

Grivn and others added 8 commits October 17, 2026 22:42
pages.tsx held the six pages, the Overview graph and the widgets they share
in 1,774 lines. Each page now has its own module (overview-page,
explore-page, entities-page, persistence-strategy-dialog, remember-page,
list-page), the Overview graph and its layout are in memory-graph.tsx, and
the widgets more than one page uses are in widgets.tsx. The code moved
verbatim; the declarations a sibling module now imports gained `export`.

pages.tsx stays the module src/client.ts exports, re-exporting the same
names. The built lib/client.js holds the same statements and runs the same
load-time effects in the same order; only its module regions changed. The
dialog-footer check reads the modules the code moved to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… out

MnemonSyncSection.tsx (823 lines) also held the GitHub sign-in, the
repository picker and the advanced settings. Each now has its own module:
MnemonSyncGitHubConnect.tsx, MnemonSyncRepositoryPicker.tsx and
MnemonSyncAdvancedSettings.tsx, and the feedback line two of them share is
in sync-feedback.tsx. The code moved verbatim; the sync section keeps its
connect, sync and repository rows and the editor's address form, and still
exports MnemonSyncSection alone. The built lib/client.js holds the same
statements in the same load order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the workbench

MnemonWorkbench.tsx (953 lines) also held the Status page with its Provider
health and storage sections, and the descriptor-driven Source management
page. They now live in StatusPage.tsx and SourceManagementPage.tsx next to
it, moved verbatim. The two types the workbench shares with the Status page
(LayerState, ComponentCard) and the storage scope label its header also
shows are exported from StatusPage.tsx, and the JSON object check both the
workbench and the management page use joined isRecord in is-record.ts.

MnemonWorkbench.tsx keeps its exports. The built lib/client.js holds the
same statements in the same load order, and the dialog-footer check reads
the two new modules too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… state into hooks

MnemonWorkspace kept about 15 pieces of state and 10 effects in one body.
Three hooks now hold them, each in its own module next to the workbench:
useWorkspaceStatus (the status and its two-step read), useSourceCatalog
(the running Source instances, a management client for each, and the pages
and management tabs they give) and useWorkspaceNavigation (the open page,
the tabs, anchors, and a page following its layer). Their code moved
verbatim; the page id helpers moved with the navigation.

React runs a component's effects in the order its hooks are called, layout
effects before passive ones, so the hooks are called where the code they
hold stood: the catalog read, the component-name read, the page and anchor
effects and then the status read still go out in that order, and the two
layout effects keep theirs. The status read's effect stays in the workbench
after the navigation hook for that reason. The built lib/client.js differs
only in MnemonWorkspace and the three hook functions it calls, whose
statements are the old ones; the record compares both builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The record lists what moved where with line counts before and after, why
the workspace hooks keep every effect in its order, and the comparisons
that show it: the code lines of each split as multisets, the built client
bundles with their module boundaries normalized, the workspace function
against the hooks it became, the bundles' export names and every public
entry's names, all the same as main. The scripts it ran are in its
harness folder. The changeset marks dsh-mnemon and Memory Spaces patch
releases with nothing changed for users.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r own

The review found the sync section exporting RepositoryEditorProps only so
the GitHub sign-in could import it back, a type-only cycle. The props now
live in sync-repository-editor.ts, which both import, so the section again
exports MnemonSyncSection alone; the built bundle is byte-identical. The
dialog footer test now reads every client source of the Starter and the
shipped Sources instead of a hand-kept list, so a dialog in a new module
is checked too; it finds the same twelve footers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… source list

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…splits

# Conflicts:
#	docs/pr-assets/README.md
@Grivn
Grivn merged commit 7a7e1ae into main Oct 17, 2026
6 checks passed
@Grivn
Grivn deleted the claude/client-module-splits branch October 17, 2026 18:11
LoveDoLove pushed a commit to LoveDoLove-Forked-Projects/dsh-mnemon that referenced this pull request Oct 18, 2026
…ync checks

The record lists what moved where, where the settings form and the Host
still differ and why each keeps its rule, what stays as it is (the 28
endpoints only other callers use among them), the bundle and package
comparison with main 7a7e1ae, and a harness that runs both sides' sync
checks over 4,650 inputs with the same output on main's modules and this
branch's. Its results are those of the merge with main 7a7e1ae (omdsh-dev#424,
omdsh-dev#425).

The changeset covers dsh-mnemon and the two Sources whose contracts gain an
export, MEMORY_PLACEMENT_CAPABILITIES and RUNTIME_MEMORY_LIMIT_MAX_BYTES.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant