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
7 changes: 4 additions & 3 deletions .claude/rules/tauri-backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ paths:
| `main.rs` | 二进制入口,仅调用 `code_manager_lib::run()` |
| `utils.rs` | 公共锁、JSON 读写、原子文件写入、应用数据目录解析 |
| `config.rs` | 配置 / Provider 合并落盘、`resolve_profile_settings()`、模型测试、`config-registry.json` |
| `deep_link.rs` | 深度链接:`code-manager://profiles/import` 解析、内嵌 payload / 远端 HTTPS 拉取(SSRF 防护)、pending 队列与导入链接生成 |
| `deep_link.rs` | 深度链接:`code-manager://profiles/import` 解析、内嵌 payload / 远端 HTTPS 拉取(SSRF 防护)、pending 队列(peek/ack,切页不丢)与导入链接生成 |
| `memory.rs` | 用户级 `CLAUDE.md` 与 `rules/*.md` 的托管、导入、启停 |
| `skills.rs` | Skills 启停、`~/.codex/skills/<id>` 软链同步、`SKILL.md` 读写、文件树扫描 |
| `history.rs` | `~/.claude/history.jsonl` 读取、会话详情解析、轮询变更 |
Expand Down Expand Up @@ -84,8 +84,9 @@ const workspace = await ipc.getConfigWorkspace();
## 后端边界

- 后端继续负责配置合并、路径校验、目录遍历安全、真实落盘和日志脱敏。
- 路径相关 command 必须防止符号链接、绝对路径和 `..` 路径逃逸。
- `claude_directory` 和 `project` 的文件树/预览 command 只能暴露受控目录内部内容,不能让前端绕过后端路径边界。
- 路径相关 command 必须防止绝对路径和 `..` 路径逃逸。
- **只读跟随软链(ADR 0002)**:`claude_directory` 与项目级 `.claude` 的**扫描 / 预览**允许跟随符号链接,目标可在受控 root 外;相对路径仍禁止 `..` / 绝对段。用户级与项目级(含项目 `.claude` 根目录本身是软链)共用该只读契约。
- **写操作与外部编辑器仍拒绝软链路径**:新建 / 重命名 / 删除,以及 `open_claude_file_in_editor` / `open_project_claude_file_in_editor`,路径一旦经过软链组件必须拒绝;项目侧创建设置文件时若 `.claude` 根是软链也拒绝。
- 日志脱敏字段清单与日志格式规范见 `.claude/rules/projects-tray-diagnostics.md` 的「日志与诊断」一节,不要在两处维护副本。

## 用量 runtime 与 SQLite
Expand Down
68 changes: 66 additions & 2 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@ Code Manager 的领域术语表(glossary),只记录本项目语境下需要统

## Language

### 配置系统(Config System)

**配置(Profile)**:
一份完整的 Claude Code 设置单元,引用一个 [Provider](#provider供应商) 并在其 `env` 之上叠加自身 `settings`(认证密钥、permissions/hooks、行为等)。可被[应用](#应用apply)写入 `~/.claude/settings.json`。已移除旧的继承链,配置之间不再互相继承。
_Avoid_: Profile(裸用英文)、预设/preset(已移除的旧继承模型残留,仅存于 `presetId` 兼容别名)、方案

**Provider(供应商)**:
只承载供应商客观信息的单元:连接地址 `env.ANTHROPIC_BASE_URL`、模型映射与元数据(`models`/`docUrl`)。**全部内置只读、不支持自定义、无继承**,且**不含认证密钥、不含 permissions/hooks**——那些都属于[配置](#配置profile)。
_Avoid_: 预设/preset、渠道、服务商、模型源

**应用(Apply)**:
把[配置](#配置profile)解析为最终设置、原子写入 `~/.claude/settings.json`,并在注册表记录[绑定](#绑定binding)的动作。仅预览合并结果、不落盘的是另一回事。
_Avoid_: 激活、保存、部署、切换(切换只是在 UI 选中另一份配置,不等于应用)

**绑定(Binding)**:
注册表中记录「当前哪份[配置](#配置profile)挂在 `~/.claude/settings.json` 上」的持久关联(`bindings.user_profile_id`)。被绑定配置被修改时会重新[应用](#应用apply)。
_Avoid_: 应用状态、关联、挂载

**托管(Managed)**:
`~/.claude/settings.json` 的内容由某份[配置](#配置profile)所管理的状态。反之,未被任何配置管理的现存 `settings.json` 是**未托管设置(Unmanaged User Settings)**,可被原地接管(import)为一份新配置,而不立即重写文件。
_Avoid_: 管理、纳管、接入

**设置漂移(Settings Mismatch)**:
已[绑定](#绑定binding)配置的预期内容与磁盘上真实 `~/.claude/settings.json` 不一致的状态(`activeUserSettingsMismatch`)。经 diff 展示后,可选择接管实际内容或重新[应用](#应用apply)。
_Avoid_: 冲突、不同步、脏配置

### 防止休眠(Sleep Prevention)

**防止休眠(Sleep Prevention)**:
Expand Down Expand Up @@ -57,7 +83,7 @@ _Avoid_: 源码、纯文本白名单(判定是「非已知二进制」,不是穷
_Avoid_: 万能链接(Universal Link / App Link,指 https 关联应用)、自定义协议(泛称实现手段时)

**配置导入链接(Profile Import Link)**:
一种[深度链接](#深度链接deep-link),动作为将外部 Claude settings 导入为**新配置(Profile)**。打开后须经预览确认才入库,且**不自动应用/绑定**到 `~/.claude/settings.json`。
一种[深度链接](#深度链接deep-link),动作为将外部 Claude settings 导入为一份新[配置](#配置profile)。打开后须经预览确认才入库,且**不自动应用/绑定**到 `~/.claude/settings.json`。
_Avoid_: 一键应用链接、配置同步链接、远程配置下发

**内嵌载荷导入(Embedded Payload Import)**:
Expand All @@ -68,7 +94,21 @@ _Avoid_: 附件导入、剪贴板导入(那是别的入口)
[配置导入链接](#配置导入链接profile-import-link)的一种来源:query `url` 指向一份 HTTPS 上的 settings JSON,由应用拉取后再走同一套预览导入。
_Avoid_: 在线配置中心、配置订阅、远程同步

### Token 用量(Token Usage)
### 历史、统计与用量(History, Stats & Usage)

三者数据源不同,互不混用。

**项目(Project)**:
Claude Code 的会话工作目录视图,数据源是 `~/.claude/history.jsonl`。
_Avoid_: 工作区、仓库、会话(会话是项目内的单次对话)

**统计(Stats)**:
基于 `~/.claude.json` 的账户级统计视图。
_Avoid_: 用量(数据源不同,见下)、报表

**用量(Usage)**:
扫描 `~/.claude/projects/**/*.jsonl` 得到的 Token 消耗与费用视图;[缓存命中率](#缓存命中率cache-hit-rate)等指标都归此。
_Avoid_: 统计(数据源不同,见上)、账单

**缓存命中率(Cache Hit Rate)**:
在筛选范围内,缓存读取占全部输入侧 Token 的比例。口径固定为 `cacheRead / (input + cacheCreate + cacheRead)`;输出 Token 不计入分母。无输入时记为 0%。
Expand All @@ -81,3 +121,27 @@ _Avoid_: 平均命中率、模型命中率均值
**模型缓存命中率(Model Cache Hit Rate)**:
单个模型在同一筛选与时间桶内、仅用该模型 token 算出的[缓存命中率](#缓存命中率cache-hit-rate)。与[总体缓存命中率](#总体缓存命中率overall-cache-hit-rate)并列展示,便于对比模型缓存表现。
_Avoid_: 模型缓存率(省略「命中」)、用总体分母去除模型分子

### 记忆(Memory)

**记忆(Memory)**:
Code Manager 管理的 Claude Code 用户级指令文件,即 `~/.claude/CLAUDE.md` 与 `~/.claude/rules/*.md`。**不含** Claude Code 的 auto memory——那是独立机制,当前不扫描、不导入、不写入。
_Avoid_: 指令、提示词、Claude Code auto memory(独立机制,不归本页管)

**claude 记忆(Claude Memory)**:
`claude` 类型的[记忆](#记忆memory),同一时间只能启用一个,启用即写入 `~/.claude/CLAUDE.md`。
_Avoid_: 主记忆、全局记忆

**rule 记忆(Rule Memory)**:
`rule` 类型的[记忆](#记忆memory),可同时启用多个,分别写入 `~/.claude/rules/<rulePath>`,携带结构化 `pathPatterns` 决定按路径触发。
_Avoid_: 规则文件(泛指)、path rule

### Skills

**Skill**:
一个带 `SKILL.md` 的目录单元。启用时位于 `~/.claude/skills/<id>/`,禁用时移到应用数据目录的 `skills-disabled/<id>/`;id 只含小写字母、数字与连字符。
_Avoid_: 技能(项目 UI 与代码统一用 Skill)、插件、能力

**软链接 Skill(Symlinked Skill)**:
本体为目录级符号链接的 [Skill](#skill)。只读查看其目标目录的 `SKILL.md`,不递归读取支持文件,不可经应用编辑。与[软链条目](#软链条目symlink-entry)同源但专指 Skill。
_Avoid_: 外部 Skill、引用 Skill
13 changes: 7 additions & 6 deletions docs/adr/0002-directory-overview-readonly-follow-symlinks.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
## Decision

1. **扫描收录软链**:目录软链可展开并递归列子项;文件软链可点开预览。顶栏统计为「含 N 个软链接」,不再「跳过」。
2. **预览只读跟随,允许出界**:相对路径仍禁止 `..` / 绝对段;解析时允许跟随符号链接,目标可在 root 外。写操作(新建 / 重命名 / 删除)在路径上一旦经过软链则全部拒绝。
3. **损坏与环**:悬空软链仍显示并标损坏;以 canonicalize 真实路径去重,再次遇到标循环且不递归。
4. **二进制预览**:按已知二进制扩展名(及 `.DS_Store` 等特殊名)黑名单判定;其余一律按 UTF-8 / lossy 文本预览,不再因内容含 `NUL` 清空。
5. **范围**:用户级 `~/.claude` 总览与项目级 `.claude` 浏览共用同一契约。
2. **预览只读跟随,允许出界**:相对路径仍禁止 `..` / 绝对段;解析时允许跟随符号链接,目标可在 root 外。
3. **写边界(含外部编辑器)**:新建 / 重命名 / 删除,以及 **用默认编辑器打开**(可写回磁盘),在路径上一旦经过软链则全部拒绝。用户级 `open_claude_file_in_editor` 与项目级 `open_project_claude_file_in_editor` 同一语义。
4. **损坏与环**:悬空软链仍显示并标损坏;以 canonicalize 真实路径去重,再次遇到标循环且不递归。
5. **二进制预览**:按已知二进制扩展名(及 `.DS_Store` 等特殊名)黑名单判定;其余一律按 UTF-8 / lossy 文本预览,不再因内容含 `NUL` 清空。
6. **范围**:用户级 `~/.claude` 总览与项目级 `.claude` 浏览共用同一契约。

## Consequences

- 读预览的可达面扩大到软链指向的任意本地目标;风险靠「只读 + 大小截断 + 写拒绝」收敛。
- 读预览的可达面扩大到软链指向的任意本地目标;风险靠「只读 + 大小截断 + 写/编辑器打开拒绝」收敛。
- UI 必须标明软链与目标路径,避免用户把出界内容误认为 root 内真文件。
- 删除 / 修复悬空软链需在终端或源目录完成,总览不提供写入口
- 删除 / 修复悬空软链、或编辑软链目标内容,需在终端或源目录完成;总览预览可读,但不提供经软链的写入口(含外部编辑器)
2 changes: 1 addition & 1 deletion docs/adr/0003-deeplink-profile-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- `payload` 与 `url` 都缺或都有 → 拒绝。可选 query `name` / `description` 仅预填导入对话框,不参与签名或信任。
3. **载荷契约对齐文件导入**:内容是**裸 Claude settings JSON**(不是带 `providerId` 的私有 envelope)。校验与入库语义对齐现有 `preview_profile_import` / `import_profile_from_file`:预览确认后**新建配置**,`providerId` 为空,**不自动应用/绑定**。
4. **密钥策略**:不强制剥离密钥。预览若检测到认证密钥,必须**风险横幅 + 勾选确认**后才能导入。导出侧新增「复制 Deep Link」,默认**不含密钥**;用户显式包含密钥时,复制前使用**同一档确认**。
5. **生命周期与 UI**:单实例;冷启动与热启动都处理链接;多条链接**排队**(取消或失败后自动处理下一条,取消不清空整队)。成功解析后聚焦 **main** 窗口、切到配置页、打开与文件导入同一套预览 UI。三端(macOS / Windows / Linux)均注册 scheme。
5. **生命周期与 UI**:单实例;冷启动与热启动都处理链接;多条链接**排队**(取消或失败后自动处理下一条,取消不清空整队)。队列权威源在后端 pending:前端 `peek` 队头做预览,用户确认导入 / 取消 / 解析失败后 `ack` 移除;切页不 ack、不丢链。成功解析后聚焦 **main** 窗口、切到配置页、打开与文件导入同一套预览 UI。三端(macOS / Windows / Linux)均注册 scheme。
6. **首期明确不做**:自动 apply、应用代托管 JSON、主机白名单、payload 压缩、分享 envelope、多实例、仅热启动处理。

## Consequences
Expand Down
24 changes: 24 additions & 0 deletions docs/user-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@ After you click Test Model, a request is sent based on the current edits. The re

Model testing requires a valid `ANTHROPIC_AUTH_TOKEN` and an accessible model API.

### Deep Link Import

You can send a Claude settings document into Code Manager via a system URL for preview-and-import. The scheme/path is `code-manager://profiles/import`.

- **Two mutually exclusive sources**: embedded `payload=` (base64url-encoded bare settings JSON, about 16KB decoded), or remote `url=` (HTTPS only; the app fetches then imports, with SSRF protections and size/redirect limits).
- **Optional query params**: `name` and `description` only prefill the import dialog.
- **Does not auto-enable**: after a successful resolve, the app switches to the Configurations page and opens the same preview dialog as file import. Confirming **creates a new configuration** with an empty `providerId` and **does not** automatically write or bind `~/.claude/settings.json`.
- **Secrets**: if the payload contains authentication-like fields, you must acknowledge the risk before import. “Copy Deep Link” from an existing profile excludes secrets by default; including secrets requires the same acknowledgement.
- **Queue**: multiple links are queued. Closing the preview or finishing an import continues with the next item. Leaving the Configurations page and returning restores unconfirmed links (the authoritative queue lives in the app backend).

The scheme is registered for packaged installs on macOS / Windows / Linux; Linux/Windows may need extra registration in some development setups.

## Providers

Providers are all built-in and read-only. They carry only objective provider information (the connection endpoint `ANTHROPIC_BASE_URL`, the model mapping, and optional additional environment variables) and contain no authentication keys. They currently cover Anthropic, DeepSeek, Zhipu GLM Coding Plan, Kimi Code Plan, MiniMax Token Plan, Xiaomi MiMo Token Plan, OpenRouter, Volcengine Ark Coding Plan, Alibaba Cloud Bailian Coding Plan, Wanjie Ark, and Ollama.
Expand Down Expand Up @@ -300,6 +312,18 @@ The Settings entry is in the lower-left corner. Settings are grouped into Interf

> The entire Device Integration group is shown only on macOS; other platforms do not provide the LED or the global session focus shortcut.

### Prevent Sleep (macOS only)

When Claude Code sessions need to run for a long time, you can stop the Mac from entering idle sleep.

- **Mode (one of three)**:
- **Off**: do not interfere with system sleep.
- **While active**: stay awake while there is a running Claude Code session; idle sleep is allowed again when all sessions end.
- **Always**: stay awake unconditionally (still subject to the display option below).
- **Keep display awake**: orthogonal to the mode. By default only **system idle sleep** is blocked and the display may still dim per system policy; enabling this keeps the display on as well.
- **Live status**: when the mode is not Off, Settings shows a status dot such as “Keeping awake” or “Idle, may sleep”; the tray menu can also switch modes.
- **Limits**: macOS only; hardware policies such as closing the lid may still sleep the machine; quitting the app releases the power assertion.

### System Notifications and Pricing

- System notifications: used when a Claude session enters the pending state, and in scenarios such as when clicking a session to jump but terminal location fails. When enabled, system notification permission is requested first; if permission is denied, the setting stays off.
Expand Down
24 changes: 24 additions & 0 deletions docs/user-manual.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@ Skills 对应 `~/.claude/skills/<id>/SKILL.md`。启用的 Skill 保存在 `~/.c

模型测试需要有效的 `ANTHROPIC_AUTH_TOKEN` 和可访问的模型 API。

### 深度链接导入

可用系统 URL 把一份 Claude settings 送进 Code Manager 做预览导入,scheme为 `code-manager://profiles/import`。

- **两种来源(互斥)**:内嵌 `payload=`(base64url 编码的裸 settings JSON,解码后约 16KB 上限),或远端 `url=`(仅 HTTPS,应用拉取后导入;有 SSRF 防护与体积/跳转限制)。
- **可选参数**:`name`、`description` 仅用于预填导入对话框。
- **不自动启用**:解析成功后会切到配置页并打开与文件导入相同的预览对话框;确认后**新建配置**,`providerId` 为空,且**不会**自动写入或绑定 `~/.claude/settings.json`。
- **密钥**:若载荷含认证类字段,须勾选风险确认后才能导入。从已有配置「复制 Deep Link」时默认不含密钥;显式包含密钥时同样需勾选确认。
- **多条排队**:连续打开多条链接会排队处理;关闭预览或导入成功后继续下一条。离开配置页再回来,未确认的链接仍会恢复(权威队列在应用后端)。

macOS / Windows / Linux 在安装包场景下均可注册 scheme;开发态下 Linux/Windows 可能需额外注册。

## 供应商 Provider

供应商均为内置且只读,只承载供应商客观信息(连接地址 `ANTHROPIC_BASE_URL`、模型映射与可选附加环境变量),不含认证密钥。当前覆盖 Anthropic、DeepSeek、智谱 GLM Coding Plan、Kimi Code Plan、MiniMax Token Plan、小米 MiMo Token Plan、OpenRouter、火山方舟 Coding Plan、阿里云百炼 Coding Plan、万界方舟和 Ollama。
Expand Down Expand Up @@ -300,6 +312,18 @@ Code Manager 常驻系统托盘(菜单栏),菜单分两部分:

> 设备联动整组仅在 macOS 显示;其它平台不提供 LED 与全局会话聚焦快捷键。

### 防止休眠(仅 macOS)

在 Claude Code 会话需要长时间运行时,可阻止电脑因空闲进入休眠。

- **模式(三选一)**:
- **关闭**:不干预系统休眠。
- **仅活动时**:有运行中的 Claude Code 会话时保持唤醒;会话全部结束后可正常休眠。
- **始终**:无条件保持唤醒(仍受「屏幕常亮」开关约束)。
- **同时保持屏幕常亮**:与模式正交。默认只阻止**系统空闲休眠**,屏幕仍可按系统策略熄灭;开启后连显示器一起保持点亮。
- **实时状态**:模式非关闭时,设置区会显示「正在保持唤醒」或「空闲,可休眠」等状态点;托盘菜单也可切换模式。
- **边界**:仅 macOS 生效;合盖等硬件策略可能仍导致睡眠;退出应用会释放电源断言。

### 系统通知与计价

- 系统通知:用于 Claude 会话进入待处理状态,以及点击会话跳转但终端定位失败等场景。开启时会先请求系统通知权限;权限被拒绝时设置保持关闭。
Expand Down
Loading