6.4 KiB
2026-05-18 工作日志:bricks-mp / Sage 桌面客户端
背景
当天围绕 bricks-mp 仓库完成 Kotlin Multiplatform + Compose Desktop 运行时搭建,并针对 Sage / WebBricks 服务端 .ui、.dspy 加载链路进行了多轮调试。目标是让桌面端能够像浏览器端 bricks 一样加载 Sage 服务端 UI,并可打包为 macOS 应用。
仓库:git@git.opencomputing.cn:yumoqing/bricks-mp.git
主分支:main
时间线
上午:项目初始化与 Compose Desktop 打包链路
-
b9c5856初始化bricks-mp项目结构。- 建立
shared模块。 - 添加 Bricks 基础模型、解析器、渲染器、HTTP 客户端和 ActionDispatcher 雏形。
- 初步支持 Text、布局、输入等基础 widget。
- 建立
-
82c2b89增加 macOS Sage 桌面客户端能力。- 增加登录、UI 加载、Compose 渲染和 DMG 打包配置。
- 扩展
BricksRenderer,覆盖更多 bricks widget 到 Compose 的映射。 - 增加 Sage 客户端登录/session 相关逻辑。
-
bf7827a添加 Gradle Wrapper 8.5,确保构建工具版本固定。 -
45abb01为 desktop-only 构建暂时关闭 Android/iOS targets。- 当前环境没有 Android SDK / Xcode,直接启用多端 target 会导致构建失败。
-
03c8a8a修正 KMP JVM target 命名。- 从
jvm("desktop")改为jvm()。 - source set 从
desktopMain调整为jvmMain。
- 从
-
ceaadf3修正 DMG packageVersion。- Compose DMG 打包不接受
0.x.y,改为1.0.0。
- Compose DMG 打包不接受
-
7b88174调整工程结构。- 将
Main.kt移入shared/src/jvmMain。 - 移除容易出错的
desktopApp独立模块。 - 在 root build 配置中补足 repositories。
- 将
-
b80d607/605b520修复编译错误。- 处理
Modifier.weight()scope 问题。 - 修复
asStateFlow、cookie API、CoroutineScope import、JsonPrimitive 表单值、Material3 experimental API 等问题。
- 处理
上午:Sage 登录和 HTTP 表单链路调试
e4f35ec尝试使用 KtorFormDataContent处理表单 POST。b342ae8发现FormDataContent在 commonMain 不可用后,改为 URL-encoded string body。26ebfe1进一步调整 form encoding 和postForm参数。a0a4b56增加 User-Agent / Referer、先 GET index 获取 session cookie,并处理非 JSON 登录响应。9d3593f修正 Sage 登录端点。- 使用
/rbac/user/up_login.dspy。 - 登录字段使用
username和password/passwd链路排查后按 Sage 端实际接口调整。
- 使用
晚上:将 Sage 逻辑从库中剥离,补独立示例应用
-
4993e55重构产品边界。shared保持产品无关,只保留通用 bricks runtime、HTTP、ActionDispatcher。- 将 Sage 专有 bootstrap/login 逻辑从库包移出,放到应用示例层。
- 增加
WebBricksRequestContext,集中生成.ui/.dspy请求所需上下文参数:_webbricks_=1_width_height_is_mobile_lang
- 增加 README,说明产品专有客户端应放在应用工程中,不进入
com.bricks.mp通用库包。
-
d9b5455新增独立 Sage sample app。- 路径:
test/sageclient/ - 通过 Gradle composite build 引用根项目
:shared,不污染根settings.gradle.kts。 - 增加
build.sh,支持从任意目录运行,并优先使用 repo Gradle wrapper。 - 增加
test/sageclient/README.md。
- 路径:
-
1f577fd加强 JDK 检查。- Kotlin 2.1.0 不支持 Java 25/26 版本字符串。
build.sh要求 JDK 17 或 JDK 21;macOS 可自动选择/usr/libexec/java_home中的 21/17。
-
388272b修复 commonMain redirect 解析。- 避免使用 Ktor commonMain 中不可用/不稳定的
URLBuilder.encodedPath等 API。 - 改为平台无关字符串解析,适配绝对、根相对、相对 Location。
- 避免使用 Ktor commonMain 中不可用/不稳定的
-
87ebf5a支持 sageclient 启动 URL。- 支持命令行第一个参数直接传入
https://ai.atvoe.com/center.ui这类 URL。 - 对绝对 URL:提取 origin 作为
baseUrl,路径和 query 作为初始urlwidget加载目标。 - 文档中补充 Gradle run 和 macOS
.app启动方式。
- 支持命令行第一个参数直接传入
关键技术结论
-
bricks-mp的 shared library 必须保持产品无关。- Sage 登录、默认首页、业务 bootstrap 只能放在 sample/app 层。
- 通用库只提供 BricksHttp、renderer、parser、ActionDispatcher 等基础能力。
-
.ui/.dspy后端请求必须带 WebBricks 上下文参数。- 参数名必须是
_webbricks_,前后都有下划线。 _webbricks_=1表示前端 runtime 已存在,服务端应返回直接 UI/DSpy 结果,不应包 HTML bootstrap。- 同时需要
_width、_height、_is_mobile、_lang。
- 参数名必须是
-
Compose Desktop 运行时需要从窗口层同步真实 viewport。
- 使用 AWT window size 作为像素尺寸。
- density 转换的
WindowState.size只作为 fallback。
-
KMP commonMain 要避免 JVM-only API。
- 不能在 commonMain 依赖
java.net.URLEncoder、java.awt、javax.*。 - URL encode 使用 Ktor common 的
encodeURLParameter()。
- 不能在 commonMain 依赖
-
构建环境约束明确。
- JDK 17/21 可用。
- Java 25/26 会触发 Kotlin/Gradle 版本解析问题。
- 当前 Linux 执行环境未安装
java,无法在本机完整跑 Gradle build;已通过脚本语法和静态检查兜底。
验证记录
当天完成的验证包括:
- Git 提交链完整推送到
origin/main。 test/sageclient/build.sh增加 JDK 版本检查。- commonMain 中排查并移除不适合 commonMain 的 URLBuilder/encodedPath 依赖。
- sample app 使用 composite build,不纳入根项目默认构建。
- 文档覆盖:
- root README 中说明 WebBricks 参数和 HTTP error/redirect 处理。
test/sageclient/README.md中说明构建、运行、启动 URL 和可选系统属性。
后续 2026-05-19 追加修复
19 日零点后根据服务端日志继续修复启动 URL 请求链路:
39727f8 fix: preserve webbricks params for startup ui requests- 将
.ui/.dspy请求参数显式合成到最终 URL 后再调用 Ktor client。 - 避免启动 URL 链路中
_webbricks_未出现在真实请求 URL,导致 Sage 按普通页面返回 HTML/header/footer 模板。 - README 补充说明:startup URL 仍必须通过
BricksHttp请求并携带_webbricks_=1。
- 将
当前状态
- main 已推送到远端。
- 最新提交:
39727f8 fix: preserve webbricks params for startup ui requests。 - 2026-05-18 的开发记录已补写在本文件。