Appearance
功能规格说明:桌面端深链唤起
创建日期:2026-10-12
本规格定义与兄弟产品 codewave sdd(web coding agent)的接力面:sdd 在 web 上生成 spec 文档并推入 git,然后给出一个
wave://链接,把用户接续到桌面端继续开发。链接只携带仓库地址、分支与提示词,不携带任何凭据:clone 与后续 git 操作一律使用本机已有的 Wave 登录态(SSO token),本机未登录时先引导登录;该凭据在 git 服务侧如何校验由 sdd 后端负责。相关规格:desktop-shell.md(SSO 登录、单实例、外链白名单)、desktop-sessions.md(工作目录与会话新建)、../enterprise/sso-auth.md(凭据存储与刷新)。
用户场景与测试
用户故事:从网页唤起桌面端并克隆仓库开始开发(优先级:P1)
作为 codewave sdd 的用户,我在 web 上让 agent 生成好 spec 并推入 git 之后,希望点一下页面上的链接就唤起 CodeWave IDE、选个目录,然后仓库被克隆好、自动开一个新对话并把链接里的提示词(例如「实现 spec」)发进去,以便不用手动 clone、不用手动建会话就能接着开发。
为什么是这个优先级:这是本能力的全部价值——唤起、clone、自动开对话并发送提示词,缺任何一环用户都要回到手工流程,sdd 到桌面端的接力就断了。
独立测试:构造一条带仓库地址、分支与提示词的 wave:// 链接,分别在「桌面端未运行」与「桌面端已运行」两种状态下点击,验证确认框弹出、选定目录后仓库被克隆到该目录下的同名子目录、新会话以该子目录为工作目录建立、首条消息为链接里的提示词;再验证取消、目标目录已存在、仓库地址缺失、链接超长四类拒绝路径不产生任何 clone 或会话。
验收场景:
- 假设桌面端未运行(Windows / Linux),当用户从网页点击
wave://链接,则应用冷启动、从命令行参数中识别出该链接,窗口就绪后弹出克隆确认框。 - 假设桌面端未运行(macOS),当用户点击链接,则链接在窗口就绪之前即被接收并暂存,待窗口就绪后再弹出确认框,不得丢失。
- 假设桌面端已运行,当用户点击链接,则不启动第二个实例,由已运行的实例接收该链接、把窗口带到前台并弹出确认框;macOS 由系统派发给运行中的实例,Windows / Linux 由二次启动转交,三端行为一致。
- 假设多条链接连续到达(含冷启动期间到达的),则按到达顺序逐条处理,不丢失、不互相覆盖。
- 假设确认框已弹出,则在用户确认之前即展示将要克隆的仓库地址、将使用的分支、以及将要发送给 agent 的提示词全文——用户在确认前能看到这一步将要发生什么。
- 假设用户选定目录并确认,则在该目录下创建以仓库名命名的子目录并把仓库克隆进去;用户选定的是「放在哪儿」,仓库名由仓库地址推导,链接不能指定绝对路径。
- 假设目标子目录已存在(无论是否为空),则不覆盖、不自动改名,提示用户另选目录。
- 假设 clone 成功,则自动新建一个以该子目录为工作目录的会话(不复用任何既有会话,也不复用唤起前正在显示的那个),并把链接里的提示词作为首条消息自动发出。
- 假设链接未携带提示词,则只新建会话、不自动发送任何消息。
- 假设 clone 失败(网络不可达、认证被拒、无权限、磁盘空间不足、本机未安装 git 等),则在应用内给出可读错误,不新建会话,且不残留半成品目录。
- 假设用户在确认框取消,则不 clone、不新建会话;若应用是因本次唤起才冷启动的,停留在正常启动后的初始状态。
- 假设链接缺少仓库地址、分支形态非法、或仓库地址不是受支持的形态(仅接受 http(s) 与 ssh 形态的仓库地址,不接受本地路径与
file://),则拒绝该链接并给出可读错误,不发起任何 clone。 - 假设链接整体长度超过安全上限,则拒绝并给出可读提示,不得进入 clone 流程后才在系统层静默失败。
- 假设同一条链接被重复触发(用户手滑双击、或同一任务重复点击),则不产生重复的 clone 或重复的会话。
用户故事:克隆出的仓库长期自动认证(优先级:P1)
作为刚被链接接过手的用户,我希望 agent 之后在这个仓库里 push / pull / fetch 时自动带上认证,不用我再配任何凭据。
为什么是这个优先级:sdd 的意图是让桌面端接手「实现 spec」并把改动推回 git;认证断在 push 上,等于整个接力只做了一半。
独立测试:完成一次由链接发起的 clone,检查新仓库的 git 配置里存在指向本机 Wave 取凭据的 credential helper 且不含凭据本身;在该仓库内触发一次 git 网络操作,验证认证自动完成且每次认证前重新取凭据;在本机无可用凭据时验证取凭据快速失败并给出可读原因、不挂起等待输入。
验收场景:
- 假设用户确认 clone,则 clone 即以本机已有的 Wave 登录态完成认证,用户不需要额外输入任何东西。
- 假设 clone 完成,则该仓库的 git 配置里写入 credential helper,其值为「向本机 Wave 取当前登录凭据」的命令;凭据本身不得写入仓库配置。
- 假设之后在该仓库内执行 git 网络操作,则每次认证前都重新取一次当前有效凭据——凭据轮换或刷新后自动跟上,不得依赖 clone 当时的那一份。
- 假设本机全局/系统层已存在其他 credential helper,则注入时先清空继承来的 helper,避免本机已有的凭据缓存把动态凭据钉死。
- 假设本机没有可用凭据,则取凭据的过程快速失败并给出可读原因,不得挂在等待输入上(agent 自动执行 git 时没有终端可以输入)。
- 假设任意时刻,则应用日志、错误提示与仓库配置中均不得出现凭据明文。
用户故事:认证只来自本机登录态(链接不携带凭据)(优先级:P1)
作为桌面端用户,我希望链接里不带任何凭据、认证只用我本机已有的 Wave 登录态,本机未登录时先明确告诉我需要登录;任何网页都能构造这样的链接,凭据绝不能被一条链接安装进我的机器。
为什么是这个优先级:凭据的来源决定了这条链路是「接续开发」还是「点一下陌生链接就换一个身份」——后者是不可接受的安全面。来源钉死为本机登录态后,未登录时的引导就成了这条链路上唯一还缺的一环,缺它则 clone 直接失败且用户不知道原因。
独立测试:在未登录状态下用链接唤起,验证 clone 确认框之前先出现登录引导、用户取消即结束、登录完成后继续走确认框;在已登录状态下用链接唤起,验证不再出现登录引导;用一条带凭据字段(如 token=)的链接唤起,验证该字段不被读取、本机登录态不被改写;用一个当前身份无权的仓库验证错误提示指明可能是身份问题。
验收场景:
- 假设本机已登录,当用户确认 clone,则 clone 与之后该仓库的 git 操作都使用本机登录态,链接内容不参与认证。
- 假设本机未登录,则在弹出 clone 确认框之前先提示需要登录(认证只可能来自本机登录态,没有第二条路径),用户取消则整个流程结束:不 clone、不新建会话。
- 假设本机未登录、用户在登录引导中完成登录,则登录成功后继续走 clone 确认流程。
- 假设链接中出现任何凭据字段(如
token=),则该字段一律不被读取,本机登录态不被改写。 - 假设 clone 因身份与仓库授权不符被拒,则错误提示说明「当前登录身份可能无权访问该仓库」,而不是只透出底层 git 报错。
边界情况
- 协议注册在三端落点不同:macOS 靠打包配置(
Info.plist的 URL scheme);Windows 的安装器不写注册表,必须由应用在运行时自行注册,因此首次运行前点链接不会唤起应用——这是安装后的正常时序,不是缺陷。卸载后注册表残留会导致「点链接仍弹确认框但打不开」,需在卸载路径上一并清理。 - 开发(未打包)模式下 macOS 注册不上:macOS 的协议注册必须有已打包的应用包,因此本条链路只能在打包产物上验收,dev 运行时不具备该能力。
- 浏览器侧必然有一次确认:首次点击会弹「是否打开 CodeWave IDE」,用户可勾选「始终允许」。浏览器不提供「唤起成功 / 失败」的回调,因此发起方(sdd)需要自备降级,本规格不承担(见非目标)。
- 链接长度的平台差异(必须由应用侧先拦):Windows 上超长链接是静默失败(浏览器确认框照弹、点确定后什么都不发生),因此上限校验必须在应用侧完成并给出可读拒绝,不能寄望于系统报错。中文提示词经 URL 编码后单字约占 9 个字符,上限判定要按编码后长度。macOS 未发现同类硬上限,但上限判定按最严的平台统一执行。
- 链接文本必须按 URL 规范编码:提示词为自由文本(可含中文、空格、
&、#等),编码与解码两侧都要正确处理;解析入口需容忍残缺的百分号转义而不抛异常中断整个唤起。 - 确认框是唯一的人类确认点:任意网页都能构造本链接,且 Windows 上任何应用都能注册同名 scheme(后注册者胜出)。因此确认框必须如实展示仓库地址、分支与提示词全文,不能让用户在不知情的情况下触发 clone;自动发送提示词不等于自动批准工具调用,仍按当前权限模式逐次确认。
- 目标目录与 clone 的失败面:目录不可写、磁盘空间不足、路径含符号链接、clone 中途网络中断等,一律按验收场景 10 处理(可读错误 + 清理半成品 + 不建会话)。
- 远端主机不在本条链路内:唤起与 clone 都只作用于本机,不因链接把会话切到 SSH 远端主机。
- 与被唤起前的界面状态无关:无论唤起时用户正在看哪个会话或是否停在欢迎态,clone 成功后一律新建会话,不覆盖、不复用既有会话(与 desktop-sessions.md「选定目录一律新建对话」一致)。
非目标(明确排除)
- 不定义发起方(sdd)侧的降级引导:浏览器拿不到唤起成败,「没反应?去下载桌面端」这类兜底由发起方自己实现。
- 不支持在 SSH 远端主机上 clone:本条链路的 clone 固定落在本机。
- 不定义除「clone 并开会话」以外的深链动作:打开指定会话、打开指定文件、打开工作目录等动作不在本规格内。
- 不改动权限模式:链接触发的会话沿用用户当前权限模式,不自动批准任何工具调用。
- 不提供防 scheme 劫持:Windows 上同名 scheme 可被其他应用抢注。主要缓解是链接里没有凭据可劫(凭据只来自本机登录态),劫持者最多拿到仓库地址、分支与提示词——这也是确认框必须如实展示这三项的原因;凭据本身在任何情况下都不写入仓库配置、日志或错误提示。