chore: cut 1.0.0 release with usage docs and MIT license
Bump APP_VERSION to 1.0.0 / BUILD_NUMBER to 1; refresh README to clarify project direction and add quarantine-removal guidance for the unsigned release artifact; add USAGE.md as the end-user walkthrough; add MIT LICENSE.
This commit is contained in:
1 parent
da14031c83
commit
c78bb44c23
4 files changed
+213
-59
No files matched your search
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 OpenLess contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -2,76 +2,86 @@
|
||||
|
||||
OpenLess 是一个原生 macOS 语音输入应用:把光标放在任意输入框,按下全局快捷键说话,OpenLess 会录音、转写、轻度整理,并把结果插入当前输入位置。插入失败时会自动复制到剪贴板,尽量保证“用户说过的话不丢”。
|
||||
|
||||
## 当前状态
|
||||
## 项目方向
|
||||
|
||||
- 原生 Swift / SwiftUI / AppKit,SwiftPM 项目。
|
||||
- 支持 macOS 15+;macOS 26+ 使用 Liquid Glass 效果,旧系统回退到系统 material。
|
||||
OpenLess 只做一件事:**把语音变成可用的书面文字,落到当前光标位置。**
|
||||
|
||||
- 不做问答、不做任务执行、不做项目分析。
|
||||
- 不做对话上下文累积,每次输入都是独立的整理请求。
|
||||
- 输入语音 → 转写 → 整理 → 插入当前输入框。失败时复制到剪贴板。
|
||||
- 围绕这条主路径完善体验:模式选择、词典、历史、菜单栏、首页报告。
|
||||
|
||||
## 当前状态(v1.0)
|
||||
|
||||
- 原生 Swift / SwiftUI / AppKit,SwiftPM 项目;macOS 15+。
|
||||
- macOS 26+ 使用 Liquid Glass 效果,旧系统回退到系统 material。
|
||||
- 默认是切换式录音:按一次开始,再按一次结束;录音中按 `Esc` 取消。
|
||||
- 支持火山引擎流式 ASR 和 Ark / DeepSeek 兼容 Chat Completions 润色。
|
||||
- 支持 4 种输出模式:原文、轻度润色、清晰结构、正式表达。
|
||||
- 支持 Dock 主窗口、菜单栏控制、底部微型状态胶囊、首页报告、历史记录、词典、设置和剪贴板兜底。
|
||||
- 接入火山引擎流式 ASR 和 Ark / DeepSeek 兼容 Chat Completions 进行润色。
|
||||
- 4 种输出模式:原文、轻度润色、清晰结构、正式表达。
|
||||
- 主窗口按「首页 / 历史记录 / 词典 / 设置」组织;菜单栏常驻;底部有微型状态胶囊。
|
||||
- 词典支持作为 ASR 热词注入和润色阶段的语义判断。
|
||||
|
||||
## 运行方式
|
||||
## 下载与安装(普通用户)
|
||||
|
||||
到 [Releases](../../releases) 下载 `OpenLess-1.0.0.zip`,解压得到 `OpenLess.app`,拖到 `应用程序`。
|
||||
|
||||
**重要:** 1.0 是开发期 ad-hoc 签名构建(未做 Apple Developer ID 签名和 notarization)。直接打开会被 Gatekeeper 拦下提示“无法验证开发者”。需要在终端中移除隔离属性:
|
||||
|
||||
```bash
|
||||
./scripts/build-app.sh
|
||||
open build/OpenLess.app
|
||||
xattr -dr com.apple.quarantine /Applications/OpenLess.app
|
||||
```
|
||||
|
||||
开发期使用 ad-hoc 签名。每次重新构建后,脚本默认会重置辅助功能、麦克风、AppleEvents 和 ListenEvent 权限,确保 macOS 不继续引用旧二进制授权。
|
||||
之后就可以双击启动。首次启动需要在 `系统设置 → 隐私与安全`:
|
||||
|
||||
首次启动后:
|
||||
1. 授予 OpenLess 麦克风权限。
|
||||
2. 授予 OpenLess 辅助功能权限。
|
||||
3. **退出 OpenLess 并重新打开**(辅助功能授权对全局快捷键生效需要重启进程)。
|
||||
4. 从 Dock 打开 OpenLess 首页 → 「设置」 → 填入火山引擎 ASR 和 Ark 凭据。
|
||||
|
||||
1. 在系统设置中授予 OpenLess 辅助功能权限和麦克风权限。
|
||||
2. 退出 OpenLess。
|
||||
3. 重新打开 `build/OpenLess.app`。
|
||||
4. 从 Dock 打开 OpenLess 首页,在「设置」里填写火山引擎 ASR 和 Ark 凭据。
|
||||
完整的端用户使用步骤见 [USAGE.md](USAGE.md)。
|
||||
|
||||
实时日志:
|
||||
## 从源码构建(开发者)
|
||||
|
||||
```bash
|
||||
# 库 / 测试构建
|
||||
swift build
|
||||
swift test
|
||||
|
||||
# 完整 .app 构建(release,ad-hoc 签名,默认重置 TCC)
|
||||
./scripts/build-app.sh
|
||||
|
||||
# 保留已授予的 TCC 权限
|
||||
RESET_TCC=0 ./scripts/build-app.sh
|
||||
|
||||
# 启动
|
||||
open build/OpenLess.app
|
||||
|
||||
# 实时日志
|
||||
tail -f ~/Library/Logs/OpenLess/OpenLess.log
|
||||
```
|
||||
|
||||
启动参数(在 `AppDelegate.runLaunchActions` 处理):
|
||||
|
||||
```bash
|
||||
open build/OpenLess.app --args --open-settings
|
||||
open build/OpenLess.app --args --start-recording
|
||||
```
|
||||
|
||||
## 凭据
|
||||
|
||||
开发期凭据保存在本机:
|
||||
凭据保存在本机 Keychain(service = `com.openless.app`)。开发期同时维护一份明文 JSON 兜底,用于在 Keychain 不可用时回退:
|
||||
|
||||
```text
|
||||
~/.openless/credentials.json
|
||||
~/.openless/credentials.json # 0600,目录 0700
|
||||
```
|
||||
|
||||
文件权限会设置为 `0600`,目录权限为 `0700`。当前没有把 API Key 写入仓库、日志或公开配置。正式发布前建议切换到稳定开发者签名 + Keychain。
|
||||
仓库本身不包含任何 API Key、Token 或 Endpoint 之外的私有信息。
|
||||
|
||||
需要配置:
|
||||
需要配置的字段:
|
||||
|
||||
- 火山引擎 ASR:APP ID、Access Token、Resource ID。
|
||||
- Ark 润色:API Key、Model ID、Endpoint。
|
||||
|
||||
## 图标
|
||||
|
||||
图标源文件放在:
|
||||
|
||||
```text
|
||||
Resources/Brand/openless-app-icon-source.jpg
|
||||
```
|
||||
|
||||
生成脚本:
|
||||
|
||||
```bash
|
||||
swift scripts/generate-app-icon.swift
|
||||
```
|
||||
|
||||
脚本会输出:
|
||||
|
||||
```text
|
||||
Resources/AppIcon.png
|
||||
Resources/AppIcon.icns
|
||||
Resources/Brand/openless-standard-image.png
|
||||
```
|
||||
|
||||
`Resources/Brand/openless-standard-image.png` 是 1024×1024 的标准品牌图;`scripts/build-app.sh` 会自动生成图标并把 `AppIcon.icns` 写入 `.app` bundle。
|
||||
|
||||
## 提示词处理原则
|
||||
|
||||
OpenLess 的润色模型只做文本整理,不做问答、不做任务执行、不做项目分析。每次语音输入都会作为独立请求发送,提示词会明确告诉模型:
|
||||
@@ -102,22 +112,47 @@ OpenLess 的润色模型只做文本整理,不做问答、不做任务执行
|
||||
|
||||
主窗口按「首页 / 历史记录 / 词典 / 设置」组织;词典页点击“新建”会弹出独立编辑窗口,首页会展示口述时长、总字数、平均每分钟字数、估算节省时间和词典参与记录。
|
||||
|
||||
## 尚未完成的功能
|
||||
## 架构概览
|
||||
|
||||
- 按住说话模式:当前是切换式录音,尚未实现真正的 hold-to-talk。
|
||||
- 本地 ASR:当前主要接入火山引擎云端 ASR,本地模型路由还没有实现。
|
||||
- 常用片段 Snippets:需求中有规划,当前没有 UI 和触发逻辑。
|
||||
- 历史增强:当前能查看和清空历史,尚未支持复制按钮、搜索、重新润色、重新插入。
|
||||
- 粘贴上一条快捷键:需求中有规划,当前没有独立快捷键。
|
||||
- 多屏定位:胶囊目前优先显示在主屏底部,尚未按当前输入焦点所在屏幕定位。
|
||||
- 稳定签名与 Keychain:开发期使用 ad-hoc 签名和本机受保护文件,正式发布前需要开发者签名、notarization 和 Keychain 方案。
|
||||
- 自动更新和发布流水线:尚未接入 Sparkle、GitHub Release 自动打包或 notarization 流程。
|
||||
- 更完整测试环境:当前 `swift build` 可验证编译;本机 CommandLineTools 环境缺少 `XCTest`,需要完整 Xcode 环境后跑 `swift test`。
|
||||
SwiftPM 工作区,1 个可执行 + 8 个库。库与库之间无相互依赖,全部只依赖 `OpenLessCore`,由 `OpenLessApp` 统一在 `DictationCoordinator` 里编排。
|
||||
|
||||
## GitHub 发布前检查
|
||||
```
|
||||
OpenLessCore // Pure value types: DictationSession, PolishMode, HotkeyBinding,
|
||||
// AudioConsumer protocol, RawTranscript/FinalText, errors.
|
||||
OpenLessHotkey // CGEventTap-based modifier-key monitor. Requires Accessibility.
|
||||
OpenLessRecorder // AVAudioEngine → 16 kHz mono Int16 PCM, 推送到 AudioConsumer.
|
||||
OpenLessASR // 火山引擎 streaming ASR over WebSocket.
|
||||
OpenLessPolish // Ark / Doubao chat-completions 客户端 + 模式驱动 prompts。
|
||||
OpenLessInsertion // AX focused-element 优先;剪贴板 + Cmd+V 兜底;最后 copy-only。
|
||||
OpenLessPersistence // CredentialsVault (Keychain), HistoryStore, DictionaryStore,
|
||||
// UserPreferences。
|
||||
OpenLessUI // SwiftUI 胶囊视图 + 状态枚举(不接窗口)。
|
||||
OpenLessApp // AppDelegate, 菜单栏, 设置窗口, 胶囊窗口, DictationCoordinator。
|
||||
```
|
||||
|
||||
- 确认没有提交 `.build/`、`build/`、`.DS_Store`、本地凭据或临时截图。
|
||||
录音 → 转写 → 润色 → 插入的状态机由 `Sources/OpenLessApp/DictationCoordinator.swift` 单一拥有,详见 [CLAUDE.md](CLAUDE.md)。
|
||||
|
||||
## 1.0 之后的规划
|
||||
|
||||
下面这些功能在需求文档里有规划,但 1.0 没有发布:
|
||||
|
||||
- 按住说话模式(hold-to-talk):当前仅支持切换式。
|
||||
- 本地 ASR:当前仅接入火山引擎云端 ASR。
|
||||
- 常用片段 Snippets:尚无 UI 和触发逻辑。
|
||||
- 历史增强:复制按钮、搜索、重新润色、重新插入。
|
||||
- 粘贴上一条快捷键。
|
||||
- 多屏定位:胶囊按当前焦点所在屏幕显示。
|
||||
- Developer ID 签名 + Notarization + Sparkle 自动更新。
|
||||
|
||||
## 维护者:发布前检查
|
||||
|
||||
- 确认没有提交 `.build/`、`build/`、`.DS_Store`、`~/.openless/credentials.json` 或临时截图。
|
||||
- 保留 `Resources/Brand/openless-app-icon-source.jpg`、`Resources/AppIcon.png`、`Resources/AppIcon.icns`。
|
||||
- 运行 `./scripts/build-app.sh`,确认 `build/OpenLess.app` 可启动。
|
||||
- 在一台干净 macOS 机器上验证权限引导、快捷键、录音、ASR、润色、插入和剪贴板兜底。
|
||||
- 正式分发前完成 Developer ID 签名和 notarization。
|
||||
- 用 `ditto -c -k --keepParent build/OpenLess.app build/OpenLess-<version>.zip` 打包,确保 ad-hoc 签名和扩展属性保留。
|
||||
- 正式分发前请完成 Developer ID 签名和 notarization。
|
||||
|
||||
## 许可
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,98 @@
|
||||
# OpenLess 使用说明
|
||||
|
||||
面向普通用户。开发者和架构信息见 [README.md](README.md) 与 [CLAUDE.md](CLAUDE.md)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 下载与解除隔离
|
||||
|
||||
到 [Releases](../../releases) 下载最新的 `OpenLess-1.0.0.zip`,解压会得到 `OpenLess.app`。把它拖到 `应用程序`。
|
||||
|
||||
由于 1.0 是 ad-hoc 签名构建(没有付费 Apple Developer ID),macOS Gatekeeper 会拦下提示「无法验证开发者」。在终端中执行一次:
|
||||
|
||||
```bash
|
||||
xattr -dr com.apple.quarantine /Applications/OpenLess.app
|
||||
```
|
||||
|
||||
之后双击就能启动。
|
||||
|
||||
> 这一步只需要做一次。下次升级版本,覆盖 `OpenLess.app` 后再执行一次同样的命令即可。
|
||||
|
||||
## 2. 授权
|
||||
|
||||
OpenLess 需要两个系统权限:
|
||||
|
||||
| 权限 | 在哪里授权 | 用来做什么 |
|
||||
| --- | --- | --- |
|
||||
| 麦克风 | 系统设置 → 隐私与安全 → 麦克风 | 录音 |
|
||||
| 辅助功能 | 系统设置 → 隐私与安全 → 辅助功能 | 监听全局快捷键 + 把文本写入当前输入框 |
|
||||
|
||||
**授权辅助功能后必须退出 OpenLess 并重新打开。** macOS 不会把新授权同步给已经在跑的进程,全局快捷键监听需要进程重启才能生效。
|
||||
|
||||
## 3. 配置 ASR 和润色凭据
|
||||
|
||||
OpenLess 不内置任何云端 Key,需要你自己提供:
|
||||
|
||||
- **火山引擎流式 ASR**:APP ID、Access Token、Resource ID。在火山引擎控制台开通「语音技术 → 流式语音识别」后获取。
|
||||
- **Ark / DeepSeek 兼容 Chat Completions**:API Key、Model ID、Endpoint。Ark 默认 endpoint 是 `https://ark.cn-beijing.volces.com/api/v3/chat/completions`。
|
||||
|
||||
在 OpenLess 主窗口的「设置」标签页填入即可。凭据保存在系统 Keychain(service = `com.openless.app`),不会上传也不会写入仓库。
|
||||
|
||||
> 如果不填 Ark:OpenLess 会跳过润色,直接插入 ASR 原文。
|
||||
>
|
||||
> 如果不填火山:OpenLess 会跑一段 mock 流程,并把占位文本复制到剪贴板(不会插入到输入框)。
|
||||
|
||||
## 4. 日常使用
|
||||
|
||||
1. 把光标停在任意输入框(聊天框、邮件、代码编辑器、浏览器地址栏……)。
|
||||
2. 按一次右 `Option`(默认快捷键)开始录音。底部胶囊会变成红色音量条。
|
||||
3. 说话。
|
||||
4. 再按一次右 `Option` 结束录音。胶囊会进入「转写 → 润色」状态。
|
||||
5. 润色完的文字会自动插入到光标所在位置。如果当前应用拒绝写入,会复制到剪贴板,请手动 `Cmd+V`。
|
||||
6. 按 `Esc` 在录音过程中取消,原始音频不会发送到 ASR。
|
||||
|
||||
每一次会话都会保存到「历史记录」标签页,包含:录音时长、原始转写、润色后文本、采用的模式。
|
||||
|
||||
## 5. 输出模式
|
||||
|
||||
在主窗口顶部切换:
|
||||
|
||||
| 模式 | 适合场景 |
|
||||
| --- | --- |
|
||||
| 原文 | 不想做任何修改,直接拿 ASR 结果。 |
|
||||
| 轻度润色 | 去口癖、补标点。最常用。 |
|
||||
| 清晰结构 | 把连贯口语拆成短句、列表。适合需求/任务描述。 |
|
||||
| 正式表达 | 用更书面的语气重写。适合邮件、公告。 |
|
||||
|
||||
模式只影响润色 prompt,不会让模型「回答你说的话」。详见 README 的「提示词处理原则」。
|
||||
|
||||
## 6. 词典
|
||||
|
||||
「词典」标签页用来教模型识别你的专有名词、产品名、人名和新词。
|
||||
|
||||
- 每个词条只需要填正确写法、分类(可选)、备注(可选)。
|
||||
- 启用的词条会作为火山 ASR 的 `context.hotwords` 提交,识别阶段就尽量正确。
|
||||
- 同时会注入润色阶段,让模型根据上下文判断是否需要把同音词修正成你的词。例如词典里有 `Claude`,模型听到 `Cloud` 时会根据语境决定要不要改成 `Claude`。
|
||||
|
||||
## 7. 排查
|
||||
|
||||
- **按快捷键无反应**:辅助功能没授权,或授权后未重启 OpenLess。
|
||||
- **录音时胶囊一直是灰色**:麦克风没授权,或被其他应用独占。
|
||||
- **转写一直在转圈**:火山凭据填错,或网络无法访问火山服务。看日志确认。
|
||||
- **文字没插入但被复制了**:当前应用拒绝 AX 写入和 Cmd+V,按 `Cmd+V` 手动粘贴。
|
||||
- **看日志**:
|
||||
|
||||
```bash
|
||||
tail -f ~/Library/Logs/OpenLess/OpenLess.log
|
||||
```
|
||||
|
||||
## 8. 卸载
|
||||
|
||||
```bash
|
||||
rm -rf /Applications/OpenLess.app
|
||||
rm -rf ~/Library/Application\ Support/OpenLess
|
||||
rm -rf ~/Library/Logs/OpenLess
|
||||
rm -rf ~/.openless
|
||||
```
|
||||
|
||||
Keychain 里的凭据可以用「钥匙串访问.app」搜索 `com.openless.app` 删除。
|
||||
@@ -6,8 +6,8 @@ cd "$(dirname "$0")/.."
|
||||
|
||||
APP_NAME="OpenLess"
|
||||
BUNDLE_ID="com.openless.app"
|
||||
APP_VERSION="0.1.8"
|
||||
BUILD_NUMBER="9"
|
||||
APP_VERSION="1.0.0"
|
||||
BUILD_NUMBER="1"
|
||||
BUILD_DIR="build"
|
||||
APP_DIR="${BUILD_DIR}/${APP_NAME}.app"
|
||||
BIN_DIR="${APP_DIR}/Contents/MacOS"
|
||||
|
||||
Reference in new issue
Block a user