Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Agent 对话默认关闭,打开某个项目的 Agent 面板时才启动本机

## 决策

- **侧栏入口图标**:Agent 使用 Lithe 原创的“对话气泡 + 星光”线性 SVG,由工作台 renderer 显式绑定,避免落入通用模块图标而让用户误认成插件管理。图标作为固定源资源随应用打包,复用现有模板着色与选中态;不下载、不生成运行时文件,不影响安装包的只读边界。面板内 Codex/Claude 标志仍表示具体供应商。
- **安装包图标解析**:Agent 品牌图标从应用的 `Contents/Resources/Lithe_Lithe.bundle` 只读加载;资源包或图标缺失时使用默认标志。不要在已安装的 `.app` 中直接调用 SwiftPM(Swift 包管理器)生成的 `Bundle.module`:它只查应用旁的资源包和编译目录,找不到会直接终止进程,开发机器残留的构建资源还会掩盖问题。开发和测试入口保留 SwiftPM 回退;安装版不使用编译目录,也不通过启动时复制资源来修补发行包,避免改变代码签名和 Sparkle 增量更新基线。
- **共享实现**:`rust/lithe-agent-host` 使用官方 `agent-client-protocol` SDK。一个 `AgentHandle` 对应一个项目的 Agent 进程和 ACP 连接,负责初始化、网关登录、会话新建/列出/加载、消息、权限、取消和进程树清理。Mac 通过 Rust Core C ABI(`lithe_agent_open_json`、`lithe_agent_send_json`、`lithe_agent_close`)调用;Windows 以后直接依赖同一个 crate。命令和事件的 JSON 形状由 `shared/fixtures/agent/acp-events-v1.json` 固定。
- **按需启动,跟着项目走**:`LitheAgentConversationModule` 是内置可选模块,默认禁用。每个项目有自己的模块运行时,所以会话天然属于项目。切换标签或窗口不会结束任何会话,后台项目的这一轮会继续跑完;只有关闭项目、关闭功能或退出应用时才停止 Agent。后台项目的会话在等待权限时,项目标签上会显示提醒点。
- **API Key 模式显式登录**:初始化时声明 `auth._meta.gateway = true`,然后只用 `gateway` 方式登录,把服务商地址和 `Authorization: Bearer <key>` 放进 `authenticate` 请求,经 stdio 传给 Agent。Key 不进命令行参数、环境变量或文件,Lithe 也不设置 `APP_SERVER_LOGS`。Agent 不提供 `gateway` 登录时直接报错,不会退而使用它的账号登录。Codex 使用 Responses,Claude 使用 Anthropic Messages;二者均不静默回退到账户订阅。
Expand Down Expand Up @@ -114,6 +116,7 @@ npm 的进度选项只面向终端,HTTP 日志通常在请求完成后才输

## 验证

- `./.agents/skills/write-stable-tests/scripts/test-stability-macos.sh -- --filter AgentBrandIconResourceTests`:临时安装包布局覆盖 Codex/Claude 图标加载、资源包和图标缺失时安全回退、缓存隔离,比较读取前后的文件清单与内容,确认不改写发行资源。
- 订阅新增测试覆盖旧配置兼容、显式登录、已有账号、认证通知顺序、登录取消和超时、账号变更、额度真实窗口/缺失值/多 bucket、仅查询不发送 prompt,以及临时失败保留旧值。Linux 已运行 Agent Host 的逐测试计时套件;macOS Swift 编译、真实账号登录及深浅主题/窄宽布局仍须在目标环境验证,不将代码存在等同于运行验证。
- 真实账号验收:先用 API Key 对话,空闲切换 Codex 订阅,确认请求使用本机账号;未登录时确认打开面板不会启动浏览器,点击登录与取消正确;上下文右侧额度每分钟更新,断网后灰显,换账号后旧值清除,关闭项目不残留探测进程。Claude 不出现订阅入口。Windows 已有共享协议和 host,但订阅选择和额度 UI 待接入。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## 先说结论

快捷键只有一个集中目录,菜单、搜索、设置和实际分发都从这个目录生成。持久化使用稳定的命令 ID,显示文字或分组变化不能随意改变 ID;普通输入按键也不能被误识别成全局命令。
快捷键只有一个集中命令目录,菜单、搜索、设置和实际分发都从这个目录生成。用户可以在 macOS、IntelliJ IDEA Classic 和 Eclipse 三套预设间切换;每套预设的自定义修改分别保存。持久化使用稳定的命令 ID,显示文字或分组变化不能随意改变 ID;普通输入按键也不能被误识别成全局命令。

## 问题

Expand All @@ -27,7 +27,8 @@ ID、本地化标题、分组和默认绑定;菜单、Search Everywhere、设
`⌘`、`⌥` 等字符串只在渲染时生成。普通字符必须带有
Command、Control 或 Option 之一,功能键、方向键等特殊按键可以单独使用。

`AppSettings` 在版本化的 `keyboardShortcutOverrides` 载荷中保存用户覆盖:
`AppSettings` 保存当前预设和按预设分开的版本化用户覆盖。旧版单套
`keyboardShortcutOverrides` 载荷只在首次迁移时归入 macOS 预设:

- 没有命令条目时使用目录默认值;
- 非空列表替换该命令的全部绑定;
Expand All @@ -36,15 +37,29 @@ Command、Control 或 Option 之一,功能键、方向键等特殊按键可以
- 未知命令、非法绑定和重复绑定被忽略;
- 整个载荷无法解码时回退到全部默认值。

预设只映射 Lithe 已有且与 IntelliJ Community 源码能对应的操作,真正没有
对应上游动作的 Lithe 命令才沿用 Lithe 默认绑定。Eclipse 预设先解析
`$default`、`Mac OS X 10.5+`、`Eclipse (Mac OS X)` 的继承顺序;子层
没有声明动作时继承父层,声明空动作时清除父层绑定。例如 Eclipse 的
`Find` 为空,不能回退成 Lithe 的 `⌘F`。切换预设时先切换预设身份,再发布该预设的覆盖值,
使设置页、菜单和原生监听器同时看到新绑定;录制中的操作在切换前取消。
IDEA 的 `Stop` 是按上下文停止运行或调试的单一动作;Lithe 目前仍有独立的
`stop-run` 和 `stop-debug`,因此 `Control-F2` 暂时只绑定 `stop-run`。
要同时覆盖调试场景,需要先提供能识别当前会话的统一 Stop 命令。
应用级恢复默认清除所有预设的用户覆盖并返回 macOS,Keymap 页的恢复默认
只清除当前预设的覆盖。官方映射依据是 IntelliJ Community 的
[`$default.xml`](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-resources/src/keymaps/%24default.xml)
和 [`Eclipse (Mac OS X).xml`](https://github.com/JetBrains/intellij-community/blob/master/plugins/keymaps/eclipse-keymap/resources/keymaps/Eclipse%20%28Mac%20OS%20X%29.xml);
Eclipse 文件继承的 macOS 映射见 [`Mac OS X 10.5+.xml`](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-resources/src/keymaps/Mac%20OS%20X%2010.5%2B.xml)。

`KeyboardShortcutFeatureModel` 负责合成有效值、录制状态、冲突检测、单项
恢复和全部恢复。相同绑定发生冲突时指出占用它的命令并拒绝保存,不自动
覆盖已有命令。`ShortcutSessionCoordinator` 将有效注册同步给 macOS
监听器;录制快捷键时暂停命令分发,非活动会话和已关闭会话不执行排队的
旧命令。

Search Everywhere 保留双击 Shift 和 `⇧⌘O` 两个默认入口。应用级
“恢复全部默认”会同时清除快捷键覆盖,Keymap 页面自己的“全部恢复默认”
只清除快捷键覆盖。该功能只属于 macOS,不把 Windows keymap 或新的跨平台
Search Everywhere 的 macOS 预设保留双击 Shift 和 `⇧⌘O` 两个默认入口。
该功能只属于 macOS,不把 Windows keymap 或新的跨平台
快捷键契约纳入本决策。

## 考虑过的备选方案
Expand All @@ -59,8 +74,9 @@ Search Everywhere 保留双击 Shift 和 `⇧⌘O` 两个默认入口。应用
明确报告冲突并拒绝保存。
- **立即设计 Windows 与 macOS 共用 keymap 契约**:两端事件模型和原生
编辑行为不同,当前收益不足以抵消跨平台兼容面,暂不扩展范围。
- **加入 IDEA keymap 导入、预设、导出或云同步**:这些能力会扩大稳定性
和数据兼容范围,当前需求不包含它们。
- **直接导入 IDEA 全量 keymap 文件**:Lithe 没有 IDEA 的全部命令和动作
语义,全量导入会产生无法执行的配置;只映射现有对应操作。自定义 keymap
文件导入、导出和云同步仍不在本次范围。

## 后果

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ jobs:
needs: changes
if: needs.changes.outputs.rust_core == 'true'
runs-on: macos-26
timeout-minutes: 20
timeout-minutes: 30

steps:
- name: Check out source
Expand Down
Loading
Loading