Skip to content

fix(desktop): open external links in system browser#487

Open
gdemonc wants to merge 7 commits into1024XEngineer:mainfrom
gdemonc:feat/shell-ball-linkify-bubble-483
Open

fix(desktop): open external links in system browser#487
gdemonc wants to merge 7 commits into1024XEngineer:mainfrom
gdemonc:feat/shell-ball-linkify-bubble-483

Conversation

@gdemonc
Copy link
Copy Markdown
Collaborator

@gdemonc gdemonc commented May 8, 2026

solve #483

Summary

  • linkify shell-ball reply urls and route clicks through a desktop host bridge instead of the embedded WebView
  • add a new desktop_open_external_url Tauri command so http/https links open in the system default browser
  • reuse the same desktop external-url open flow for shell-ball, task delivery links, and note resource links

Verification

  • pnpm --dir apps/desktop typecheck
  • pnpm --dir apps/desktop lint
  • cargo check in apps/desktop/src-tauri

Notes

  • shell-ball link rendering keeps existing markdown-link support and adds bare-url linkification
  • pinned shell-ball bubbles now share the same markdown link rendering path
  • lint still reports the repository's pre-existing fast-refresh warnings

@gdemonc gdemonc requested review from Late-Smoke and liche719 and removed request for Late-Smoke May 8, 2026 17:43
Copy link
Copy Markdown
Contributor

@fennoai fennoai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found 4 noteworthy issues after the code-quality, performance, security, and documentation passes. Performance and docs did not add separate findings beyond the comments below.

Comment thread apps/desktop/src/features/dashboard/tasks/taskOutput.service.ts Outdated
Comment thread apps/desktop/src/features/dashboard/notes/notePage.service.ts Outdated
Comment thread apps/desktop/src-tauri/src/local_path.rs Outdated
Comment thread apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented May 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@gdemonc gdemonc linked an issue May 8, 2026 that may be closed by this pull request
@gdemonc
Copy link
Copy Markdown
Collaborator Author

gdemonc commented May 8, 2026

@xgopilot 解决了你提的问题

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 8, 2026

Review Result

No new findings.

I re-checked the four issues from the previous review against origin/main...HEAD:

  • apps/desktop/src/features/dashboard/tasks/taskOutput.service.ts now catches openDesktopExternalUrl() failures and falls back to copyable feedback.
  • apps/desktop/src/features/dashboard/notes/notePage.service.ts applies the same failure-to-feedback fallback for note resource links.
  • apps/desktop/src-tauri/src/local_path.rs now accepts uppercase HTTP/HTTPS schemes in the host-side validator.
  • apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx now preserves balanced trailing parentheses for bare-URL linkification, and the added contract test covers the Wikipedia-style case.

Verification

I could not run the requested checks in this runner because pnpm and cargo are not installed here.

View job run

@gdemonc gdemonc requested review from Late-Smoke and jinyu918 May 9, 2026 03:13
Late-Smoke
Late-Smoke previously approved these changes May 9, 2026
@liche719
Copy link
Copy Markdown
Collaborator

liche719 commented May 9, 2026

@xgopilot trimTrailingUrlPunctuation 这里漏掉了全角右括号 的处理。现在中文常见写法 (https://...) 会把结尾的 一起带进 href,最终生成坏链接。我本地按这个输入复现后,渲染结果里的 hrefhttps://github.com/1024XEngineer/CialloClaw)。建议把全角括号也纳入尾部裁剪 / 括号平衡逻辑,否则 shell-ball 的自动 linkify 在中文语境下会经常点不开。
这个问题需要解决吗

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 9, 2026

Review Result

  1. apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx:221 这里的问题需要解决。trimTrailingUrlPunctuation() 的尾部裁剪规则只覆盖了 ASCII ),没有覆盖全角右括号 ,而 matchAutoLink() 会把 (https://...) 这种中文常见写法整体抓进候选串。按当前实现,https://github.com/1024XEngineer/CialloClaw) 会原样进入 href,生成不可打开的坏链接。我在本地按这段函数逻辑复算,确实得到同样结果;现有测试也只覆盖了中文句号和 ASCII 括号平衡,没有覆盖全角括号场景。

结论:这是当前 PR 新增 bare-url linkify 路径里的真实回归,建议在合入前补上 的尾部裁剪 / 括号平衡处理,并增加一个 (https://...) 的 contract test,避免中文语境下继续出坏链接。

Scope

本次只做分析和 review,没有修改代码。

View job run

@gdemonc
Copy link
Copy Markdown
Collaborator Author

gdemonc commented May 10, 2026

@xgopilot 修复这个问题

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 10, 2026

Result

已修复 shell-ball 自动 linkify 对全角右括号 的处理遗漏。

Changes

  • apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx 中把全角右括号纳入尾部裁剪,并补上全角括号的平衡判断,避免中文常见写法 (https://...) 带进 href
  • apps/desktop/src/features/shell-ball/shellBall.contract.test.ts 中新增回归用例,覆盖 (https://github.com/1024XEngineer/CialloClaw) 这类输入,确保生成的链接不会包含尾部

Verification

当前 runner 缺少 pnpm,且 apps/desktop/node_modules 不存在,所以未能在这里执行 pnpm --dir apps/desktop typecheckpnpm --dir apps/desktop lint

Git

View job run

xgopilot and others added 2 commits May 10, 2026 04:58
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: gdemonc <146809967+gdemonc@users.noreply.github.com>
fix(desktop): trim full-width shell-ball links
@gdemonc
Copy link
Copy Markdown
Collaborator Author

gdemonc commented May 10, 2026

@xgopilot 为什么ci不通过了?

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 10, 2026

分析结果

我先对照了 PR 实际会跑的 workflow。pull_request 触发的是 .github/workflows/desktop-test.yml,它在这个 PR 上会跑 5 段:

  • pnpm --dir apps/desktop lint
  • pnpm --dir apps/desktop typecheck
  • pnpm --dir apps/desktop test:memory
  • pnpm build:service
  • pnpm --dir apps/desktop exec tauri build --debug

我本地复现到的结果是:

  • lint 通过,只有仓库里原有的 react-refresh/only-export-components warnings,没有新的 error。
  • typecheck 通过。
  • test:memory 通过。
  • node scripts/ci/build-service.mjs 通过。

所以这次 PR 的前端 TS/ESLint 和 Go sidecar 这几段,我这里没有复现出失败。按剩余项看,最可能挂的是最后的 Windows Tauri build,也就是你这次同时改到的 Rust/Tauri 宿主侧:

额外说明

我这里没法直接看 GitHub Actions 的失败日志,也没能在当前 runner 里把完整 Windows Rust/Tauri 构建复现出来,所以现在还不能断言是 Rust 编译错误、Tauri 打包错误,还是 Windows-only 行为问题。

另外我顺手跑了 pnpm --dir apps/desktop test:dashboard,它本地确实会失败,但那是 release.yml 里的检查,不是这个 PR 的 desktop-test.yml。而且失败点看起来是仓库里已有的 dashboard contract 断言,不是这次 external-link 改动直接打出来的 CI 主因。

结论

目前能确认的是:如果你看到的是这个 PR 的 GitHub 检查红了,优先去看 Build Windows Tauri app 那一步。 你把那一步的第一段报错贴出来,我可以继续直接定位到具体代码行。

Scope

本次只做分析,没有修改代码。

View job run

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 10, 2026

分析结果

我重新按这个 PR 实际触发的 workflow .github/workflows/desktop-test.yml 本地复现了一遍。这个 job 一共跑 5 段:

  • pnpm --dir apps/desktop lint
  • pnpm --dir apps/desktop typecheck
  • pnpm --dir apps/desktop test:memory
  • pnpm build:service
  • pnpm --dir apps/desktop exec tauri build --debug

我这里已经复现到的结果是:

  • lint 通过,只有仓库原有的 react-refresh/only-export-components warnings,没有新的 error。
  • typecheck 通过。
  • test:memory 通过。
  • build:service 通过。

所以这次 CI 红掉,基本可以先排除前四步,问题范围已经收敛到最后一段 Build Windows Tauri app。而这一段正好覆盖了你这次 PR 里新增的宿主侧改动:

  • apps/desktop/src-tauri/src/local_path.rs
  • apps/desktop/src-tauri/src/main.rs

为什么我现在还不能直接给出具体报错行

当前 runner 能把 Node/TS/Go 侧检查跑完,但没有现成的 Rust toolchain,也看不到 GitHub Actions 的实际失败日志,所以我没法在这里直接拿到 Windows 那一步的首条编译错误。

结论

如果你现在看到的是这个 PR 的检查失败,优先去看 GitHub Actions 里 Build Windows Tauri app 那一步的第一段报错。前四步我这里都没复现出失败。

把那一步最前面的错误栈贴出来,我可以继续直接定位到具体代码行。大概率会落在这次新增的 desktop_open_external_url 注册或 local_path.rs 里的平台分支实现上。

View job run

@gdemonc
Copy link
Copy Markdown
Collaborator Author

gdemonc commented May 10, 2026

@xgopilot /review

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 10, 2026

Review

  1. Medium: apps/desktop/src/features/dashboard/tasks/TaskDeliveryPage.tsx:439
    The payload card still renders the formal delivery URL as a raw <a href={formalDeliveryUrl} target="_blank">. Clicking that link will stay on the embedded WebView path instead of going through desktop_open_external_url, so this PR leaves one task-delivery link flow outside the new system-browser bridge.

  2. Medium: apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx:188
    matchLink() still uses \((https?:\/\/[^\s)]+)\), which rejects valid markdown links whose URL contains balanced ) characters. A case like [wiki](https://en.wikipedia.org/wiki/Function_(mathematics)) will not round-trip through the shared markdown renderer even though bare URLs now handle that shape. Since pinned and unpinned bubbles both use this parser, that is a user-visible regression for existing markdown links.

View job run

@gdemonc
Copy link
Copy Markdown
Collaborator Author

gdemonc commented May 10, 2026

@xgopilot 缺少右括号的问题不是解决了吗?

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 10, 2026

Answer

分两类看:

(https://...) 这种 bare URL + 全角右括号 的问题,已经修了。当前 trimTrailingUrlPunctuation() 已经补了全角 的裁剪和平衡处理,见 apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx:221,对应回归测试也已经加上,见 apps/desktop/src/features/shell-ball/shellBall.contract.test.ts:5112

但我上一条 review 说的不是这个。我说的是 markdown link 里的 ASCII 右括号 ),例如:

[wiki](https://en.wikipedia.org/wiki/Function_(mathematics))

这个在当前 PR head 里还没修。原因是 matchLink() 现在仍然是:

/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/

位置在 apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx:187。这个正则会把 href 截成:

https://en.wikipedia.org/wiki/Function_(mathematics

也就是最后那个 ASCII ) 还会丢掉,所以我那个 finding 仍然成立。现有新增测试 apps/desktop/src/features/shell-ball/shellBall.contract.test.ts:5085 只覆盖了 bare URL https://...Function_(mathematics),没有覆盖 markdown link [wiki](...) 这一种。

结论:

  • 全角 的 bare-url 问题:已经解决。
  • 我上条 review 提到的 markdown-link 缺少右括号问题:当前 head 还没有解决。

View job run

@gdemonc
Copy link
Copy Markdown
Collaborator Author

gdemonc commented May 10, 2026

@xgopilot 行,你解决一下

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 10, 2026

Result

已修掉上次 review 里剩下的两个问题。

  • apps/desktop/src/features/dashboard/tasks/TaskDeliveryPage.tsx 里的正式交付 URL 不再直接走嵌入式 WebView 的原生 <a> 打开,而是拦截点击后复用 performTaskOpenExecution()open_url 路径,统一走桌面宿主 desktop_open_external_url
  • apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx 的 markdown-link 解析不再用会截断 ) 的正则,而是显式扫描并保留 href 内部的平衡括号,所以 [wiki](https://en.wikipedia.org/wiki/Function_(mathematics)) 现在能正确保留结尾右括号。
  • 补了两边的 contract coverage:dashboard 侧验证正式交付页链接走共享打开流,shell-ball 侧新增 markdown-link 平衡括号回归用例。

Verification

已通过:

  • ./node_modules/.bin/tsc --noEmit -p tsconfig.json
  • ./node_modules/.bin/eslint . --ext .ts,.tsx(仅有仓库现存 react-refresh/only-export-components warnings,无新增 error)
  • 定向 contract tests
    • task workspace routes formal delivery through a dedicated page and keeps list refresh task-updated aware
    • task rpc service builds protocol-only experience instead of reusing mock task fixtures
    • shell-ball bare urls keep balanced parentheses inside the linked href
    • shell-ball markdown links keep balanced parentheses inside the linked href
    • shell-ball markdown links open through the desktop external-url bridge

未完成:

  • cargo check 无法在当前 runner 执行,这里没有可用的 Rust 默认 toolchain。
  • 两个完整 contract suites 在这个环境里本身就有无关失败,所以我只单独确认了和本次改动直接相关的用例。

Git

View job run

xgopilot and others added 2 commits May 10, 2026 07:51
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: gdemonc <146809967+gdemonc@users.noreply.github.com>
fix(desktop): route formal links through host bridge
@gdemonc
Copy link
Copy Markdown
Collaborator Author

gdemonc commented May 10, 2026

@xgopilot /review

@fennoai
Copy link
Copy Markdown
Contributor

fennoai Bot commented May 10, 2026

Review Result

No new findings.

I re-checked the two previously reported regressions against the current origin/main...HEAD diff:

  • apps/desktop/src/features/dashboard/tasks/TaskDeliveryPage.tsx:241 now routes the formal delivery URL through performTaskOpenExecution() instead of leaving it on the embedded WebView path.
  • apps/desktop/src/features/shell-ball/components/ShellBallMarkdown.tsx:187 now parses markdown-link hrefs with balanced ) characters, and apps/desktop/src/features/shell-ball/shellBall.contract.test.ts:5112 adds coverage for the Wikipedia-style case.

Verification

I could not run pnpm --dir apps/desktop test:shell-ball or pnpm --dir apps/desktop test:dashboard in this runner because pnpm is not installed.

View job run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

提案:悬浮球的返回气泡中的网站链接变成超链接

4 participants