Skip to content

fix: ClickUp task deep links, plus a rewriter-pack audit - #11

Merged
jnahian merged 2 commits into
mainfrom
claude/clickup-deeplink-chrome-l0nu90
Aug 3, 2026
Merged

jnahian merged 2 commits into
mainfrom
claude/clickup-deeplink-chrome-l0nu90

Conversation

@jnahian

@jnahian jnahian commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Fixes #10, then audits the rest of the rewriter pack for the same class of bug.

1. The reported bug: ClickUp task links

The clickup rewriter captured a single path segment after /t/, so a workspace-scoped task URL — the form the ClickUp web app puts in the address bar, and the one Copy link gives when Custom Task IDs are on — lost the task ID:

https://app.clickup.com/t/9018159683/DEV-1234  →  clickup://t/9018159683

That's the workspace ID, so ClickUp opened on whatever screen it was last showing. Short shared links (/t/86cxk2m1q) were unaffected, which is why it looked intermittent. Now matches the whole task path and hands it to the app verbatim, the way clickup-doc already does.

2. The audit

The interesting part of that bug isn't the regex — it's that the rewrite succeeded. A rewriter that returns a valid-looking URL bypasses the "a link is never lost" guarantee: RoutingEngine sees a successful rewrite, Dispatcher finds an app for the scheme, and the link opens somewhere wrong. A rewriter that returns nil degrades to the browser and the user just sees a browser. So the pack was checked for that specific failure first.

Silently wrong target

Rewriter Input Was Now
apple-music music.apple.com/us/album/blue/1440835967?i=1440836193 music://…/1440835967 — the album, track 1 keeps ?i=, opens the song
github-desktop github.com/settings/profile, /orgs/x, /features/x, /sponsors/x, /topics/x, /users/x asked GitHub Desktop to open a repo that doesn't exist no rewrite → browser
linear linear.app/pricing, /docs/…, /blog/… opened the Linear app on a marketing page no rewrite → browser
clickup /t/<workspace>/<task> wrong task fixed (above)

github-desktop matched any two-segment path as owner/repo. The reserved-segment list is anchored with a trailing / so an owner may still start with a reserved word — newrelic/newrelic-ruby-agent still works (there's a test).

linear matched all of linear.app, which is also Linear's marketing, docs and blog. It's now an allowlist of workspace routes (issue, team, project, view, document, initiative, inbox, my-issues, settings, roadmap, cycle, label, search, triage, active, backlog). An allowlist rather than a blocklist because the marketing routes grow and the app routes don't — and an unknown route degrading to the browser is the safe direction.

Missed matches

Safe (the link opened in a browser), but the app was never offered:

  • teams — only knew teams.microsoft.com, not the newer teams.cloud.microsoft or teams.live.com.
  • telegram — no pattern for a link to a single post (t.me/durov/123); it opened the channel at the bottom. Reuses the shared template: post= is dropped by cleanEmptyParams when the matching pattern has no second capture, the same trick zoom uses for pwd.
  • todoist — required the app. subdomain on task URLs.
  • discord — didn't know the legacy discordapp.com.
  • clickup-doc — kept a trailing slash in the deep link.

Left alone deliberately

  • notion matches all of notion.so. Notion's marketing lives on notion.com now, so the over-match is theoretical.
  • vscode turns github.dev/o/r into vscode://o/r, which doesn't look like a valid VS Code URI (those are vscode://<extension-id>/…). It's flagged experimental in its own name and I can't check the real behavior without a Mac, so I didn't guess at a replacement. Worth a look.
  • ClickUp list/board/space views (app.clickup.com/9018159683/v/li/…) still have no rewriter. That's a new rewriter rather than a fix — the follow-up noted in ClickUp deep link opens the wrong screen for task URLs copied from Chrome (/t/<workspaceId>/<taskId>) #10.

Changes

  • Sources/JunctionCore/Resources/rewriters.json — 9 rewriters touched, patterns and two templates.
  • Tests/JunctionCoreTests/TransformTests.swift — 8 new/extended tests covering each fix and the non-matches that must stay non-matches.
  • CHANGELOG.mdFixed: entries under ## Unreleased, one per user-visible change.

No docs change: the deep-link app list on the website is generated from rewriters.json at build time, and no rule field, CLI flag, or Settings screen moved.

Verification

  • 61 URL cases run against the compiled patterns — every fix above plus regression guards on the rewriters I didn't touch (zoom, spotify, slack, slack-channel, figma, notion, whatsapp, asana, app-store). All pass.
  • cd web && npm test && npm run build — pass.
  • CI's rewriters.json schema/regex validator, run locally — pass, 19 rewriters.
  • swift test not run — no Swift toolchain in this Linux container. CI runs it on macOS and Linux. The changes are data-only and the new tests exercise the bundled pack, but they are unexecuted here.
  • Nothing was verified against the actual desktop apps. The URL shapes come from each service's documented/observed link formats; a Mac spot-check of the Apple Music song link and a Linear issue link would be worth doing before release.

The `clickup` rewriter captured a single path segment after `/t/`, so a
workspace-scoped task URL — `app.clickup.com/t/9018159683/DEV-1234`, the
form the web app puts in the address bar and the one "Copy link" gives
when Custom Task IDs are on — rewrote to `clickup://t/9018159683`. That
is the workspace ID, not the task, so ClickUp opened on whatever screen
it was last showing.

The rewrite succeeded, so the degrade-to-fallback path never engaged and
the link was silently sent to the wrong place. Match the whole task path
instead and hand it to the app verbatim, the way the `clickup-doc`
rewriter already does. Short links keep working; a bare `/t/` still fails
the rewrite and falls back to the browser.

Fixes #10

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SuMinAawh7kGt3npJe8v5
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
junction Ready Ready Preview Aug 3, 2026 12:26pm

@jnahian
jnahian marked this pull request as ready for review August 3, 2026 12:19
…ains

Audit of the whole rewriter pack, prompted by the ClickUp task bug. Two
classes of problem, one much worse than the other.

Silently wrong target — the rewrite succeeds, so the degrade-to-fallback
path never engages and the link lands somewhere wrong instead of in a
browser:

- apple-music dropped the query, but a song lives at its album's address
  with `?i=<trackID>`. Every song link opened the album at track 1.
- github-desktop treated any two-segment path as `owner/repo`, so
  /settings/*, /orgs/*, /features/*, /sponsors/*, /topics/* and /users/*
  asked GitHub Desktop to open a repository that doesn't exist. The
  reserved-segment list is anchored with a trailing slash so an owner may
  still start with one (newrelic/…).
- linear matched all of linear.app, which is also Linear's marketing,
  docs and blog. Restricted to workspace routes; anything else falls
  back to the browser.

Missed matches — safe, the link still opened in a browser, but the app
was never offered:

- teams only knew teams.microsoft.com, not the newer
  teams.cloud.microsoft or teams.live.com.
- telegram had no pattern for a link to a single post; it opened the
  channel at the bottom. Reuses the shared template — `post=` is dropped
  by cleanEmptyParams when the pattern has no second capture.
- todoist required the app. subdomain on task URLs.
- discord didn't know the legacy discordapp.com.
- clickup-doc kept a trailing slash in the deep link.

Left alone deliberately: notion (notion.so is all workspace content now)
and vscode, whose `vscode://<path>` output looks wrong but is flagged
experimental and can't be checked without a Mac.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SuMinAawh7kGt3npJe8v5
@jnahian jnahian changed the title fix: deep-link workspace-scoped ClickUp task URLs fix: ClickUp task deep links, plus a rewriter-pack audit Aug 3, 2026

@jnahian jnahian left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Approved

@jnahian
jnahian merged commit 374838b into main Aug 3, 2026
6 checks passed
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.

ClickUp deep link opens the wrong screen for task URLs copied from Chrome (/t/<workspaceId>/<taskId>)

2 participants