Repository navigation
Conversation
- main/Cargo.toml 删除 6 个已无引用的 optional 领域依赖: db、ssh、sftp_view、known_hosts_view、port_forwarding、port_forwarding_view (builtin-duckdb 改由 db_view 转发) - 修 shell-only 构建下的 Redis 资源池 helper cfg、外观页误加的 cfg - 新增 script/check-product-deps.sh(本地依赖树守卫) - 新增两个 manifest 契约测试:独立产品只开自己领域 feature、 database/shell feature 互不包含对方领域依赖 - 文档补 §27(main 已无领域 use、cfg 161→57、验证与剩余项)
- main 默认 feature 追加 database/shell 后,同步 script/test-release-packaging.mjs 断言 - update/install.rs 已下沉到 crates/app_kit,修正契约脚本读取路径
- crates/core/key_storage.rs 的 keyring_services 只在 test/macOS/Windows 下引用钥匙串服务名常量,补上同样的 cfg,修 Linux 构建的 E0425 - app_kit 单实例 Windows 模块在迁移后丢了可见性:forward_attempt / create_pipe_instance / serve_forever 改 pub(super),补 ForwardAttempt import
Linux CI 用 -D warnings,keyring_services/keyring_service_for 在非 test/macOS/Windows 平台被 cfg 掉后 KeyringServices 的 installed/development 两个字段变成 never read,补 allow(dead_code)。
remote_desktop_window/mstsc_credentials_windows.rs 用 windows crate 的 Win32_Security_Credentials,迁移时漏了 Cargo 依赖,Windows CI 报 cannot find module or crate `windows`。按 main 原配置补到 shell_domain 的 windows target 依赖。
RDP probe 用 --locked 构建,lock 未记录 shell_domain → windows 0.62 这条边 会导致 cannot update the lock file because --locked was passed。
report_single_instance_failure 收 &str,app_kit 的 user_message() 返回 String,Windows CI 报 E0308 expected &str, found String。
把人工 cargo tree | grep 的验收固化成集成测试:navop-shell 的依赖树不能 出现 db_view/redis_view/mongodb_view,navop-data 不能出现 terminal_view/sftp_view/remote_desktop_view/known_hosts_view/ port_forwarding_view。feature 写漏时编译不会报错,只有依赖树能拦住。
refactor(product-split): 三产品共用全量主页 + 领域 feature 拆分与 UI 下沉
- 删除 ProductKind/ProductProfile/run()/run_product():身份与领域装配只存在于 apps/* 的 Product 实现,main 只保留 run_with(product, version)。 - 删除 main/src/main.rs:main 包只提供 navop_app 库,入口统一到 apps/*。 - main 的 shell feature 移除 shell_domain 依赖(main 不再构造 ShellDomain); data_domain 暂留,公共 MCP 的 Redis/Mongo 工具集实现还在 data_domain::mcp。 - 同步更新 domain feature 契约测试与文档 §26。
- data_domain 新增 builtin-mongodb feature,DataDomain::init 在 mongodb_view::init 之后按同一 cfg 安装原生驱动工厂。 - main 删除 init_native_data_driver_factories 及其调用,改用弱依赖 data_domain?/builtin-mongodb 转发 feature,保持「领域初始化 → 公共 MCP」 的既有顺序。 - 契约测试改为断言 domains < public_mcp,工厂实现由 data_domain 单测覆盖。
SCAN 的返回值原先按 `(u64, Vec<String>)` 解析,redis-rs 会对每个 bulk string 做严格 UTF-8 校验;只要库里存在一个 JDK 原生序列化对象之类的二进制键,整批 回复就变成 `Cannot convert from UTF-8`,列表加载直接报错(issue #485)。 改为在 redis-runtime 引入二进制安全的键编解码: - 新增 `key_codec`:`encode` 把服务端键字节转成可显示、可还原的字符串 (可打印 UTF-8 键原样,其余为 `U+0001` 前缀 + 逐字节 `\xNN` 转义); `decode` 在真正下发命令前还原原始字节,普通键恒等借用、零分配。 - SCAN / KEYS 回复改按 `Vec<Vec<u8>>` 解析,逐键 `encode` 后进入树与列表。 - 所有下发键的命令(TYPE/TTL/GET/SET/DEL/EXPIRE/PERSIST/RENAME/HSCAN/SSCAN/ LRANGE/ZRANGE/XRANGE 等)在 trait 边界 `decode`,因此列表显示形态可以原样 回传到读取、改 TTL、重命名、删除等入口。 - `key_value_view` 等 UI 侧无需改动,`KeyInfo.name` 保持显示形态与树一致。 测试:新增 key_codec 单元测试,以及 SCAN 回复解析回归测试与二进制键 「扫描 → 读取 → 删除」端到端测试(本机 127.0.0.1:6379 上实测通过)。
根因:单格选区只带一列,`TableMetadata::select_columns` 只保留「落在选区里的主键」, `primary_key_indices` 因此变成空,`copy_sql_format::format_update` / `format_delete` 立即返回空字符串;而 `copy_with_format` 仍把空串写入剪贴板并提示「已复制到剪贴板」, 用户看到的现象就是「复制为 → UPDATE 复制不出来」。 修法:UPDATE/DELETE 复制前用新增的 `TableMetadata::indices_with_primary_keys` 把缺失的 主键列追加进复制上下文(SET 仍只用选区列,只有 WHERE 使用主键);表本身没有主键,或 生成结果为空(主键值为空 / 选区只有主键列)时改为明确 warning,不再写空剪贴板并谎报成功。 其他复制格式(TSV/CSV/JSON/Markdown/INSERT/IN)行为不变。 新增 `TableData.copy_sql_requires_primary_key`、`TableData.copy_sql_unavailable` 三语文案, 以及 `sql_mutations_include_primary_keys_missing_from_the_selection` 回归测试。
冲突解决:main/src/home/home_tabs.rs 保留三产品拆分布局,快捷键复制改走 TabContainer::duplicate_active_tab(等价 #483:与标签菜单共用复制路径,终端保留当前工作目录, 并对任何可复制标签生效),复制出的终端标签在 main/src/home_tab/lifecycle.rs 补回 OpenSftp / SaveAsConnection 订阅;随之删除不再被使用的 ShellExtras::duplicate_terminal_tab 契约。 origin/main 上的 #482 / #483 / #484 其余改动(标签收缩、Esc 只在编辑器上下文生效、 terminal 测试隔离)均无冲突合入。 顺带修 main/src/home/home_tabs.rs 里 notify_unsupported 的属性与文档注释空行(clippy 告警)。
服务端把测试版清单单独落在 updates/beta/latest.json,稳定清单 updates/latest.json 完全不动,老客户端行为不变: - release.yml 从 tag 形态推导通道,beta 发布给 GitHub Release 加 --prerelease,并把 channel 显式派发给 upload-r2.yml; - upload-r2.yml 新增 channel 输入(留空按 tag 推导 + 白名单校验), 清单按通道落位;prune 额外保留 beta 清单指向的安装包,避免 404; - script/beta-release.sh 一条命令完成 beta 版本号 + changelog + commit + tag + push,--dry-run 可预演; - script/test-release-packaging.mjs 补 beta 清单与 prune 场景断言。 客户端新增「更新通道」设置(稳定版/测试版,默认跟随构建版本): - AppSettings.update_channel,预发布构建默认 Beta; - feed 由通道派生,stable 永远只接受正式版本号,beta 才接受预发布; - beta 通道不回落 GitHub Releases(该端点语义排除 prerelease), beta 清单 404 视为「还没有 beta 版本」而非检查失败; - 「跳过此版本」按通道分别记录(beta:/stable: 前缀),互不影响; - 关于页更新分组加通道下拉(切 Beta 先确认)、预发布构建版本号加 Beta 标签,切回稳定通道时给出说明条;更新弹窗标题与徽标区分测试版。 文档:docs/design/beta-channel.md 记录分层、推导规则与客户端消费方式; .github/RELEASE.md 补 beta 发版流程。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
内容
dev 领先 main 124 个提交:三产品彻底拆分落地(#489 及其后续收尾)+ 8 项修复(含 #485)。逐项如下。
1. 三产品彻底拆分:navop / navop-shell / navop-data
契约层与启动
dc3c7e98d feat(domain_api):新增三产品共用领域契约层(Product/Domain/Hook/DomainRegistry、TabOpener打开模式、d572a14ed端口转发运行时改为可选供 Data 实现)。e4181254e+6ef0f60a6+4a9c41b57:HomePage 实现TabHost/HomeContext,main 实现Product并经app_kit::bootstrap初始化(领域 init 支持错误传播),run_with(product, version)统一入口;main抽出navop_app库,全量产品移到apps/navop。ca747569b+09d8bd1c2:app_kit/core按产品身份配置 keychain 与数据目录(便携/开发/缓存),修ssh_form移动后的源码断言路径。main 收敛为纯应用外壳(39 个
refactor(product-split))DomainRegistry与ShellExtras/FileOpenHandler/ActiveResourceProvider契约驱动,main/src已无use 领域crate。a21ea7cbf/128741fb1:main 引入database/shell领域 feature 并下沉视觉与驱动资产,独立产品default-features = false只开自己的领域。b0dc6b379+85d9b02ca:裁剪 main 的领域依赖,加独立产品依赖树隔离契约测试(database/shell不许互相夹带对方依赖)。579da7841:托盘图标按产品加角标、退出提示带产品名。两个独立产品
fa0a70f9d+05195c80a+731d97209:新增apps/navop-shell、apps/navop-data可执行包,分别装配 Shell 主页与 Database/Redis/MongoDB 主页;7f4c661ce补齐新建连接、基础设置与 Shell 连接类型覆盖。领域实现下沉
shell_domain:SSH 终端、SFTP 双栏、RDP/VNC、端口转发、本地终端、KnownHosts、会话日志、远程桌面窗口全部经领域注册表打开;4bc1361c8从terminal_view抽出独立的ssh_form(SSH 表单与主机密钥 UI)。data_domain:Database/Redis/MongoDB 单连接与工作区打开路径、Redis 工作区标签与连接排序、6b1efc09d驱动检查与安装提示、e147f19b1Mongo 原生驱动工厂。d3930398cruntime_core(跨域共用)、7a29ea95aruntime_database、e7d3d48f6runtime_redis/runtime_sftp;e12c7945b/312aa8e8b/62d38c9ce把数据库与远程桌面能力改为可选特性,切断terminal_view到db的编译链。Public MCP 三产品化
0a5b4e472三产品 Public MCP 宿主 + 独立发现身份;0c958ddcf独立产品注册 connection 管理工具集;0c56a0b98工具集开关接入设置并加逐项 UI;cbb72d954Mongo/Redis live provider 下沉并复用通用审批 UI;2260fcc53数据领域工具集改由领域契约提供(main 不再依赖data_domain/mongodb_view);66bab9beb独立产品按领域包写入默认工具集。打包与 CI
5974b0d3amacOS 应用包按产品生成独立身份;04fdc8c95Linux 包资源与独立打包脚本;ed7614d22Windows 安装器身份参数化;355be3cf7增加 Shell/Data 的 macOS 与 Linux 构建矩阵;7e371c60apackaging 支持按平台筛选与分支构建;8480e16b7校验 navop 产品包与主包版本一致。2.
e982a939e fix(redis):键名含非法 UTF-8 时列表加载、读取与删除不再失败(#485)根因:SCAN/KEYS 回复用
Vec<String>解析,redis-rs 对 bulk string 做严格 UTF-8 校验;遇到 JDK 原生序列化等二进制键直接报Command error: ... Cannot convert from UTF-8 - TypeError,整页列表加载失败(#485 日志的key scan failed)。修法:新增
crates/redis-runtime/src/key_codec.rs做二进制安全 key 编解码——合法 UTF-8 且不以U+0001开头的键原样透传(decode零拷贝Cow::Borrowed),其余编码成U+0001+ 每字节\xNN的可读转义形态。SCAN/KEYS 回复改按Vec<Vec<u8>>解析后逐键 encode;所有真正下发命令的入口(TYPE/TTL/STRLEN 族/GET/GETRANGE/SSCAN/HSCAN/LRANGE/ZRANGE/XRANGE/EXPIRE/PERSIST/RENAME/HSET/HDEL/LPUSH/RPUSH/LSET/SADD/SREM/ZADD/ZREM/DEL 等)在命令边界 decode 回真实字节,普通文本键恒等、零行为变化;KeyInfo.name保持与树显示一致。验证:
cargo test -p redis-runtime32 passed(新增 codec 单元测试 + SCAN 回复二进制键保持转义并反解 + 本机真实 Redis 端到端:写二进制键 → SCAN 列出 → 点开读到值 → DEL 成功 → 再扫不到);cargo test -p redis_view --lib80 passed;cargo clippy -p redis-runtime -p redis_view -- -D warnings在这两个 crate 零告警(其余 error 均为仓库既有基线,未触碰)。3. 其余 7 项修复
205d97f55 fix(app_kit):独立产品启动时初始化应用路径(否则便携/开发目录解析为空)。0209bdb91 fix(domain_api):惰性打开已存在的连接标签,避免重复建连。f7faecea2 fix(domain_api):HomeContext::notify暴露Window/App,独立产品才能推送通知。6bcc309b2+af3d3dc51:无系统凭据库的平台上不再读KeyringServices字段,并补 Shell 领域的 Windows 凭据管理器依赖。ce374ccc6+83adeb140:Windows 单实例失败提示改用&str入参,并同步源码契约断言。cbfcf7f61 fix(product-split):修领域 feature 组合下 Linux/Windows 的 CI 编译失败。9a3215839目标包默认 feature 与 update 模块路径对齐;85d9b02ca独立产品依赖树隔离契约。e98d18122 fix(db_view):复制为 UPDATE / DELETE 时选区不含主键不再输出空字符串。4. 与 main 的同步(
b3ef361a3、806c30780)main 上由贡献者直接合入的 #482 / #483 / #484 已并入 dev:
f0773f1df标签栏空间不足时非活动标签可收缩(crates/core/src/tab_container.rs,无冲突)。a5b135a90快捷键复制改为走标签菜单的复制路径。三产品拆分里HomePage::duplicate_active_tab原来调ShellExtras::duplicate_terminal_tab(会新建连接、丢当前工作目录),现改为直接调用TabContainer::duplicate_active_tab,由标签内容自己克隆;复制出的终端标签在main/src/home_tab/lifecycle.rs订阅TabContainerEvent::TabDuplicated后补回 OpenSftp / SaveAsConnection 响应。因此不再需要ShellExtras::duplicate_terminal_tab这一契约,已删除(含domain_api默认实现与 shell 领域实现)。ae4824cedEsc 只在编辑器上下文生效(markdown-editor / notes / 快速打开弹窗测试,无冲突)。159149d07terminal 集成测试各自隔离临时目录(无冲突)。main/src/home/home_tabs.rs中notify_unsupported属性与文档注释之间的空行(clippy 告警)。说明
docs(design)是docs/design/下的实施进度记录(三产品依赖图、MCP 隔离、打包矩阵、启动冒烟等),无代码变更。public_mcp_runtime仍留在main/src/public_mcp_runtime按 feature 装配工具集;main 里仍有少量#[cfg(feature)]领域分支(Mongo 驱动工厂、扩展连接终端启动、远程桌面协议映射等);CI 依赖树 guard job 仍以契约测试 +script/check-product-deps.sh等价替代。.github/RELEASE.md走同一个 dev → main release PR(版本号与 CHANGELOG 一起改)。验证
cargo test -p main --lib592 passed、cargo test -p terminal -p markdown-editor -p notes -p shell_domain -p domain_api -p one-core --lib全绿(557 / 87 / 963 / 42 / 530 / 11)、cargo check -p navop-shell -p navop-data --all-targets通过、clippy 在改动文件零告警。cargo build -p navop -p navop-shell -p navop-data通过、cargo test -p main --lib591 passed、领域包 141/18/42/11 passed、两个独立产品临时 HOME 启动 RUNNING_OK、cargo tree校验独立产品不含对方领域依赖。