diff --git a/README.md b/README.md
index 3e2ce9c..2091e77 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,32 @@
-# AskKey
+
+
+
+
+# Ask Key
+
+
[](https://github.com/sudoHG/AskKey/actions/workflows/ci.yml) [](https://github.com/sudoHG/AskKey/releases/latest) [](https://github.com/sudoHG/AskKey/releases) [](#install) [](https://github.com/sudoHG/AskKey/stargazers) [](LICENSE) [](https://hits.sh/github.com/sudoHG/AskKey/)
-A macOS menu bar app that keeps your credentials encrypted on your Mac and lets AI agents use them only after you approve.
+**The Mac key manager for AI.** Your keys stay encrypted on your Mac, and AI agents use them only through Ask Key:
+
+- **Find keys:** agents look up what they need in Ask Key's catalog, so you stop pointing the way.
+- **Your rules:** everyday keys pass, sensitive ones wait for your approval, and some stay hidden.
+- **Locked down:** a key goes only to the program that needs it; the agent never sees the value.
-[Website](https://askkey.sudohg.com/) · English | [Simplified Chinese](README.zh-CN.md)
+**[Download for Mac](https://github.com/sudoHG/AskKey/releases/latest/download/AskKey.dmg)** (free, notarized, Apple silicon, macOS 14 or later) · [Website](https://askkey.sudohg.com/)
-> **[Download the latest release](https://github.com/sudoHG/AskKey/releases/latest/download/AskKey.dmg)** (notarized DMG, macOS 14+). AskKey has no backup or recovery yet, so keep the originals of your credentials somewhere else.
+> Ask Key has no backup or recovery yet, so keep the originals of your credentials somewhere else.
-
+
## Why it exists
Coding agents need real secrets to deploy code, call APIs or log in to servers. The usual shortcuts are pasting a key into a chat, writing it into a prompt or leaving it in a `.env` file. Each of those hands plaintext to every tool, transcript and log that can read it, and you rarely see which agent used what.
-AskKey takes the secret out of that path. The agent never holds the stored value. It asks, you decide, and the value goes only to the program that needs it.
+Ask Key takes the secret out of that path. The agent never holds the stored value. It asks, you decide, and the value goes only to the program that needs it.
## Install
@@ -43,7 +53,7 @@ The welcome page walks you through the same steps.
## How it works
-AskKey stores text credentials (API keys, tokens, passwords) and files (SSH keys, `.p8`, PEM, service-account JSON). One credential can have several parts, each mapped to an environment variable name. You add credentials by hand or import a `.env` file in the app.
+Ask Key stores text credentials (API keys, tokens, passwords) and files (SSH keys, `.p8`, PEM, service-account JSON). One credential can have several parts, each mapped to an environment variable name. You add credentials by hand or import a `.env` file in the app.
```mermaid
flowchart LR
@@ -78,15 +88,15 @@ Each credential has one permission:
When you approve a read, you choose **Once** or a **Timed allowance**: a number of minutes during which that credential can be read without asking again, until it ends or you revoke it. Pending requests expire after five minutes.
-Agent writes (create, modify, delete) always need approval for that single operation. The approval is tied to the exact content you were shown and cannot be reused for another change. Permanent deletion stays in the app.
+Agents can also write: create, modify or delete a credential, set its usage instructions and group, or move credentials and create, rename or delete groups in one batch. Every write needs your approval for that operation (a batch is approved once), the approval is tied to the exact content you were shown, and it cannot be reused for another change. Permanent deletion stays in the app.
## Supported clients
-
+
Claude Code, Codex, Cursor and Grok CLI. Open the app's **Agent access** page, check a client, then confirm. For each client, setup:
-- adds AskKey as an MCP server in the user-level configuration, keeping a private backup and your other settings;
+- adds Ask Key as an MCP server in the user-level configuration, keeping a private backup and your other settings;
- installs a discovery hook that reminds the agent to look up the catalog before common direct SSH commands;
- verifies the configuration, the bundled helper and the Broker before it reports the client as connected.
@@ -94,7 +104,7 @@ Setup runs only when you ask for it, and writing a client's configuration needs
### Other MCP clients
-Any client that supports standard MCP stdio servers can connect to AskKey by defining a server with:
+Any client that supports standard MCP stdio servers can connect to Ask Key by defining a server with:
- `command`: `/Applications/Ask Key.app/Contents/Helpers/askkey`
- `args`: `["mcp"]`
@@ -105,11 +115,11 @@ Manual setup does not include automatic discovery reminders before SSH commands
The full policy, including how to report a vulnerability privately, is in [SECURITY.md](SECURITY.md). In short:
-- Credentials are encrypted locally. Responses from AskKey's management, MCP and helper interfaces do not contain stored plaintext.
+- Credentials are encrypted locally. Responses from Ask Key's management, MCP and helper interfaces do not contain stored plaintext.
- Revealing or copying a stored value in the app requires fresh system authentication.
- Revoking, expiring or pausing stops deliveries that have not started and cleans up temporary files.
-What AskKey does not guarantee:
+What Ask Key does not guarantee:
- An approved target can print, copy or forward what it receives.
- Caller names and purposes are declared by the agent. They help you read a request; they are not verified identity.
@@ -122,9 +132,9 @@ Quit Ask Key, download and verify the new DMG as described in [Install](#install
## Uninstall
-Quit Ask Key and delete `/Applications/Ask Key.app`. For each connected client, remove only the AskKey entries and owned files listed in [What setup writes](docs/client-integrations.md#what-setup-writes), including MCP configuration, discovery Hooks and AskKey-specific Hook trust settings (for example, for Claude Code, run `claude mcp remove askkey --scope user` and remove AskKey handlers from `~/.claude/settings.json`). Preserve unrelated client settings and Hooks. There is no in-app way to disconnect a client.
+Quit Ask Key and delete `/Applications/Ask Key.app`. For each connected client, remove only the Ask Key entries and owned files listed in [What setup writes](docs/client-integrations.md#what-setup-writes), including MCP configuration, discovery Hooks and Ask Key-specific Hook trust settings (for example, for Claude Code, run `claude mcp remove askkey --scope user` and remove Ask Key handlers from `~/.claude/settings.json`). Preserve unrelated client settings and Hooks. There is no in-app way to disconnect a client.
-You can optionally erase the local credential library as well. **This permanently destroys all stored credentials and cannot be undone; AskKey has no backup or recovery.** To do so, delete `~/Library/Application Support/AskKey` and use Keychain Access to delete the keychain item with service `com.sudohg.askkey.vault`.
+You can optionally erase the local credential library as well. **This permanently destroys all stored credentials and cannot be undone; Ask Key has no backup or recovery.** To do so, delete `~/Library/Application Support/AskKey` and use Keychain Access to delete the keychain item with service `com.sudohg.askkey.vault`.
## Build from source
@@ -136,7 +146,7 @@ swift test
make run
```
-`make run` builds a Debug app and starts it with separate development data, key material and socket, so it never touches an installed copy of AskKey. Use synthetic credentials when trying it out. See [CONTRIBUTING.md](CONTRIBUTING.md) for the full requirements, UI test flow and pull request checks.
+`make run` builds a Debug app and starts it with separate development data, key material and socket, so it never touches an installed copy of Ask Key. Use synthetic credentials when trying it out. See [CONTRIBUTING.md](CONTRIBUTING.md) for the full requirements, UI test flow and pull request checks.
## Documentation
@@ -144,4 +154,4 @@ The [documentation index](docs/README.md) lists every guide and architecture dec
## License and credits
-MIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE). AskKey started as a fork of [Lokalite](https://github.com/RubenGlez/lokalite) by Ruben González Alonso; the product and most of the code have since been rewritten. The Chinese product name is 请旨.
+MIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE). Ask Key started as a fork of [Lokalite](https://github.com/RubenGlez/lokalite) by Ruben González Alonso; the product and most of the code have since been rewritten. The Chinese product name is 请旨.
diff --git a/README.zh-CN.md b/README.zh-CN.md
index db444aa..1530e99 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,22 +1,32 @@
-# AskKey(请旨)
+
+
+
+
+# 请旨 Ask Key
+
+
[](https://github.com/sudoHG/AskKey/actions/workflows/ci.yml) [](https://github.com/sudoHG/AskKey/releases/latest) [](https://github.com/sudoHG/AskKey/releases) [](#安装) [](https://github.com/sudoHG/AskKey/stargazers) [](LICENSE) [](https://hits.sh/github.com/sudoHG/AskKey/)
-一个 macOS 菜单栏应用:凭证加密保存在你的 Mac 上,AI Agent 必须经过你的批准才能使用。
+**给 AI 用的 Mac 密钥管家。** 密钥加密存在你的 Mac 上,AI 只能通过请旨来用:
+
+- **密钥在哪:** AI 自己就找得到,不用再频繁给它指路。
+- **权限你定:** 普通密钥直接放行,敏感密钥由你审批,不想让 AI 碰的可以隐藏。
+- **安全加固:** 密钥只会交给目标程序,AI 看不到明文。
-[官网](https://askkey.sudohg.com/zh/) · [English](README.md) | 简体中文
+**[下载 macOS 版](https://github.com/sudoHG/AskKey/releases/latest/download/AskKey.dmg)**(免费、经过 Apple 公证,需 Apple 芯片及 macOS 14 或更高版本)· [官网](https://askkey.sudohg.com/zh/) · [English](README.md)
-> **[下载最新版本](https://github.com/sudoHG/AskKey/releases/latest/download/AskKey.dmg)**(经过 Apple 公证的 DMG,需要 macOS 14 或更高版本)。请旨目前没有备份和恢复功能,请自行另存一份凭证原件。
+> 请旨目前没有备份和恢复功能,请自行另存一份凭证原件。
-
+
## 为什么需要它
编码 Agent 要部署代码、调用 API、登录服务器,就得用到真实的密钥。常见做法是把 key 贴进对话、写进提示词,或者留在 `.env` 文件里。这等于把明文交给每一个能读到它的工具、聊天记录和日志,而你往往不知道哪个 Agent 用了什么。
-AskKey 把密钥从这条路径里拿出来:Agent 手里没有保存的凭证值,它只能提出请求,由你决定,值只交给真正需要它的那个程序。
+请旨把密钥从这条路径里拿出来:Agent 手里没有保存的凭证值,它只能提出请求,由你决定,值只交给真正需要它的那个程序。
## 安装
@@ -43,7 +53,7 @@ AskKey 把密钥从这条路径里拿出来:Agent 手里没有保存的凭证
## 工作方式
-AskKey 可以保存文本凭证(API key、token、密码)和文件(SSH 私钥、`.p8`、PEM、服务账号 JSON)。一份凭证可以包含多项内容,每一项映射到一个环境变量名。你可以在应用里手动添加,也可以导入 `.env` 文件。
+请旨可以保存文本凭证(API key、token、密码)和文件(SSH 私钥、`.p8`、PEM、服务账号 JSON)。一份凭证可以包含多项内容,每一项映射到一个环境变量名。你可以在应用里手动添加,也可以导入 `.env` 文件。
```mermaid
flowchart LR
@@ -78,15 +88,15 @@ helper 位于应用包内的 `Contents/Helpers/askkey`。目标进程只会拿
批准读取时,你可以选择“仅本次”或“限时允许”:在设定的分钟数内,这份凭证可以不再询问直接读取,到期或被你撤销后失效。待处理的请求 5 分钟后过期。
-Agent 的写操作(新建、修改、删除)永远要对每一次操作单独批准。批准绑定的是你看到的那份具体内容,不能挪用到另一次修改上。永久删除只能在应用里进行。
+Agent 也能写入:新建、修改或删除凭证,设置使用说明和分组,或者一次性批量移动凭证、新建、重命名和删除分组。每次写入都要你对这一次操作批准(批量操作批准一次即可)。批准绑定的是你看到的那份具体内容,不能挪用到另一次修改上。永久删除只能在应用里进行。
## 支持的客户端
-
+
Claude Code、Codex、Cursor 和 Grok CLI。在应用的 **Agent 接入**页面里先检查某个客户端,再确认连接。对每个客户端,接入会:
-- 在用户级配置里把 AskKey 添加为 MCP server,同时保留私有备份,不动你的其他设置;
+- 在用户级配置里把请旨添加为 MCP server,同时保留私有备份,不动你的其他设置;
- 安装一个发现 hook,在 Agent 直接执行常见 SSH 命令之前,提醒它先查询凭证目录;
- 验证配置、内置 helper 和 Broker 都正常之后,才显示“已验证连接”。
@@ -94,7 +104,7 @@ Claude Code、Codex、Cursor 和 Grok CLI。在应用的 **Agent 接入**页面
### 其他 MCP 客户端
-任何支持标准 MCP stdio 协议的客户端都可以手动接入 AskKey,配置如下服务器定义:
+任何支持标准 MCP stdio 协议的客户端都可以手动接入请旨,配置如下服务器定义:
- `command`: `/Applications/Ask Key.app/Contents/Helpers/askkey`
- `args`: `["mcp"]`
@@ -105,11 +115,11 @@ Claude Code、Codex、Cursor 和 Grok CLI。在应用的 **Agent 接入**页面
完整政策(包括如何私下报告漏洞)见 [SECURITY.md](SECURITY.md)。简要来说:
-- 凭证在本机加密保存。AskKey 的管理、MCP 和 helper 响应都不会返回已保存的明文。
+- 凭证在本机加密保存。请旨的管理、MCP 和 helper 响应都不会返回已保存的明文。
- 在应用里查看或复制凭证值,需要重新做系统验证。
- 撤销、到期或暂停会阻止尚未开始的交付,并清理临时文件。
-AskKey 不保证的事:
+请旨不保证的事:
- 获准的目标程序可以把收到的内容打印、复制或转发出去。
- 调用方名称和用途由 Agent 自行声明,只是帮你看懂请求,不是经过验证的身份。
@@ -122,7 +132,7 @@ AskKey 不保证的事:
## 卸载
-退出请旨并删除 `/Applications/Ask Key.app`。对每个已连接的客户端,只移除 [What setup writes](docs/client-integrations.md#what-setup-writes) 中列出的 AskKey 配置项和专属文件,包括 MCP 配置、凭证查询 Hook 和 AskKey 专属的 Hook 信任设置(例如对于 Claude Code,运行 `claude mcp remove askkey --scope user` 并移除 `~/.claude/settings.json` 中的 AskKey 处理器)。保留其他客户端设置和 Hook。应用内没有断开客户端连接的功能。
+退出请旨并删除 `/Applications/Ask Key.app`。对每个已连接的客户端,只移除 [What setup writes](docs/client-integrations.md#what-setup-writes) 中列出的请旨配置项和专属文件,包括 MCP 配置、凭证查询 Hook 和请旨专属的 Hook 信任设置(例如对于 Claude Code,运行 `claude mcp remove askkey --scope user` 并移除 `~/.claude/settings.json` 中的请旨处理器)。保留其他客户端设置和 Hook。应用内没有断开客户端连接的功能。
你也可以选择一并删除本机凭证库。**这会永久销毁所有已保存的凭证,无法撤销;请旨目前没有备份和恢复功能。** 如需删除,请移除 `~/Library/Application Support/AskKey` 目录,并在“钥匙串访问”中删除服务名为 `com.sudohg.askkey.vault` 的钥匙串项目。
@@ -136,7 +146,7 @@ swift test
make run
```
-`make run` 会构建 Debug 版应用,并使用独立的开发数据、密钥材料和 socket 启动,不会碰已安装的 AskKey。试用时请使用合成凭证。完整要求、UI 测试流程和 PR 检查见 [CONTRIBUTING.md](CONTRIBUTING.md)。
+`make run` 会构建 Debug 版应用,并使用独立的开发数据、密钥材料和 socket 启动,不会碰已安装的请旨。试用时请使用合成凭证。完整要求、UI 测试流程和 PR 检查见 [CONTRIBUTING.md](CONTRIBUTING.md)。
## 文档
@@ -144,4 +154,4 @@ make run
## 许可证与致谢
-MIT 许可,见 [LICENSE](LICENSE) 和 [NOTICE](NOTICE)。AskKey 最初是 [Lokalite](https://github.com/RubenGlez/lokalite)(作者 Ruben González Alonso)的 fork,之后产品形态和大部分代码已经重写。
+MIT 许可,见 [LICENSE](LICENSE) 和 [NOTICE](NOTICE)。请旨最初是 [Lokalite](https://github.com/RubenGlez/lokalite)(作者 Ruben González Alonso)的 fork,之后产品形态和大部分代码已经重写。
diff --git a/Tests/AskKeyE2ETests/ScreenshotE2ETests.swift b/Tests/AskKeyE2ETests/ScreenshotE2ETests.swift
index ec269bf..5de57c9 100644
--- a/Tests/AskKeyE2ETests/ScreenshotE2ETests.swift
+++ b/Tests/AskKeyE2ETests/ScreenshotE2ETests.swift
@@ -47,6 +47,32 @@ final class ScreenshotE2ETests: E2EBaseCase {
capture("11-locked")
}
+ /// The two README pictures again in Simplified Chinese, for README.zh-CN.md.
+ func testReadmeScreensInChinese() throws {
+ app.launchEnvironment["ASKKEY_E2E_SCENARIO"] = "approval-screenshots"
+ app.launchEnvironment["ASKKEY_E2E_LANGUAGE"] = "zh-Hans"
+ app.launch()
+ _ = try waitForEvidence("approval-pending.json")
+ XCTAssertTrue(app.buttons["approval-details"].waitForExistence(timeout: 8))
+ XCTAssertTrue(app.buttons["approval-allow-once"].waitForExistence(timeout: 8))
+ capture("18-zh-approval-default", approval: true)
+ click("approval-deny")
+ _ = try waitForEvidence("approval-result.json")
+ app.terminate()
+
+ // The approval run left a saved credential, so the welcome page is past
+ // its first step; set it aside and open Agent access.
+ app.launchEnvironment["ASKKEY_E2E_SCENARIO"] = "screenshots-welcome"
+ app.launch()
+ moveManagementAboveDock()
+ XCTAssertTrue(app.buttons["welcome-later"].waitForExistence(timeout: 8))
+ click("welcome-later")
+ if app.buttons["unlock-management"].waitForExistence(timeout: 3) { click("unlock-management") }
+ click("sidebar-agent")
+ XCTAssertTrue(app.buttons["onboarding-review-codex"].waitForExistence(timeout: 8))
+ capture("19-zh-agent-access")
+ }
+
func testPendingRequestsAndAccessRecords() throws {
app.launchEnvironment["ASKKEY_E2E_SCENARIO"] = "approval-deny"
app.launchEnvironment["ASKKEY_E2E_LANGUAGE"] = "en"
diff --git a/assets/readme/agent-access-zh.png b/assets/readme/agent-access-zh.png
new file mode 100644
index 0000000..76c5df3
Binary files /dev/null and b/assets/readme/agent-access-zh.png differ
diff --git a/assets/readme/approval-prompt-zh.png b/assets/readme/approval-prompt-zh.png
new file mode 100644
index 0000000..54f5ad9
Binary files /dev/null and b/assets/readme/approval-prompt-zh.png differ
diff --git a/assets/readme/website-en.jpg b/assets/readme/website-en.jpg
new file mode 100644
index 0000000..d7bb20a
Binary files /dev/null and b/assets/readme/website-en.jpg differ
diff --git a/assets/readme/website-zh.jpg b/assets/readme/website-zh.jpg
new file mode 100644
index 0000000..f0a6220
Binary files /dev/null and b/assets/readme/website-zh.jpg differ
diff --git a/docs/testing.md b/docs/testing.md
index f6a7492..e83a162 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -89,9 +89,16 @@ The optional `ScreenshotE2ETests` suite runs separately in CI and does not chang
12-approval-default.png
13-approval-details.png
14-approval-cancelled-authentication.png
+15-approval-credential-metadata.png
+16-approval-organization.png
+17-approval-organization-existing-targets.png
+18-zh-approval-default.png
+19-zh-agent-access.png
```
-An optional capture failure is diagnostic: inspect the screenshot step, its log and xcresult, and the exported subset. A green required-flow job alone does not prove screenshot completeness; #146 acceptance also requires all 14 PNGs in the artifact. Delete downloaded evidence after review.
+`18` and `19` are the approval prompt and the Agent access page in Simplified Chinese, used in `README.zh-CN.md`.
+
+An optional capture failure is diagnostic: inspect the screenshot step, its log and xcresult, and the exported subset. A green required-flow job alone does not prove screenshot completeness; #146 acceptance also requires every PNG listed above in the artifact. Delete downloaded evidence after review.
Desktop tests exercise shared App/Broker/helper behavior, but system authentication and external client boundaries use isolated fixtures. Passing them does not validate real Touch ID, production keychain access, a real client task, signing/notarization, or a release. Per [ADR 0006](adr/0006-release-process.md), `Local` and `Release` builds run [release-gate.py](../scripts/release-gate.py): the checkout must be clean, `HEAD` must be reachable from `origin/main` after fetching, and the latest push-to-main `CI` run for that exact commit and both required jobs (`build-and-test`, `basic-ui-flows`) must succeed. Jobs are checked for the run's latest attempt. `Release` also requires the tag `v` to point at `HEAD`; signing identities, notarization, and explicit maintainer publication approval remain required by the release process.
diff --git a/scripts/e2e-report.py b/scripts/e2e-report.py
index 3c3d0b6..80da08e 100644
--- a/scripts/e2e-report.py
+++ b/scripts/e2e-report.py
@@ -17,6 +17,7 @@
"15-approval-credential-metadata",
"16-approval-organization",
"17-approval-organization-existing-targets",
+ "18-zh-approval-default", "19-zh-agent-access",
]