Skip to content

Commit 8a2cdcd

Browse files
committed
feat: link CTA straight to the extension when no click proxy is set
The editor/extension CTA was gated on cta_base_url, so with no proxy (the default) PR comments showed only the warning banner — no link to open the architecture in the editor or install the extension. Now the links always render: through the proxy when cta_base_url is set, else straight to the editor deep link (vscode/cursor:extension/Codeboarding.codeboarding) and the Marketplace listing.
1 parent 5798c06 commit 8a2cdcd

4 files changed

Lines changed: 40 additions & 24 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ The command needs the `issue_comment` trigger and runs from your default branch
165165
| `parsing_model` | `google/gemini-3.1-flash-lite-preview` | Parsing model. OpenRouter default shown; other providers use their own engine default. |
166166
| `comment_header` | `Architecture review` | Heading for the PR comment. |
167167
| `trigger_command` | `/codeboarding` | Slash command for trusted on-demand runs. |
168-
| `cta_base_url` | empty | Optional click-proxy base URL for editor and extension links. |
168+
| `cta_base_url` | empty | Click-proxy base URL for the editor/extension links (tracks owner/repo/pr). Empty links straight to the editor deep link and Marketplace. |
169169

170170
## Outputs
171171

action.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ inputs:
5151
required: false
5252
default: '1'
5353
cta_base_url:
54-
description: 'Base URL of the click proxy (e.g. https://go.codeboarding.org). When set, the comment adds "open in VS Code/Cursor" / "get the extension" links with owner/repo/pr appended. Empty disables the CTA.'
54+
description: 'Base URL of the click proxy (e.g. https://go.codeboarding.org) for the "open in VS Code/Cursor" / "get the extension" links, so owner/repo/pr are tracked. Empty (default) links straight to the editor deep link and Marketplace instead.'
5555
required: false
5656
default: ''
5757
trigger_command:
@@ -573,8 +573,8 @@ runs:
573573
else echo "$N components changed"; fi
574574
}
575575
576-
# CTA footer (editor + extension links via the click proxy, warning banner
577-
# on real health findings). build_cta also emits the ⚠️ banner with no proxy.
576+
# CTA footer: editor + extension links (via the click proxy when CTA_BASE is
577+
# set, else straight to the editor deep link / Marketplace) plus the ⚠️ banner.
578578
cta() {
579579
python3 "$ACTION_PATH/scripts/build_cta.py" \
580580
--cta-base "$CTA_BASE" --owner "$OWNER" --repo "$REPO" --pr "$PR" \

scripts/build_cta.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
"""Build the call-to-action footer appended to the architecture-diff PR comment.
22
3-
The footer links into CodeBoarding's click proxy (so owner/repo/pr are tracked)
4-
and currently drives straight to the VS Code/Cursor **extension**: an "open this
3+
The footer drives straight to the VS Code/Cursor **extension**: an "open this
54
architecture in your editor" link (editor-specific) plus an "install the
6-
extension" link, and a warning banner when real health findings exist. A
5+
extension" link, and a warning banner when real health findings exist. When a
6+
click proxy (``cta_base``) is set the links route through it so owner/repo/pr are
7+
tracked; otherwise they point at the final destinations directly — the editor
8+
``<scheme>:extension/...`` deep link and the Marketplace listing. A
79
no-install hosted-webview ("explore in browser") tier is intentionally deferred
810
(see docs/COMMIT_STRATEGY.md) — the committed analysis already supports it later.
911
@@ -45,33 +47,42 @@ def detect_editors(repo_path: Path) -> list[str]:
4547

4648
_EDITOR_LABEL = {"vscode": "VS Code", "cursor": "Cursor"}
4749

50+
# No-proxy fallback targets: the final destinations the click proxy would route to.
51+
_EXTENSION_ID = "Codeboarding.codeboarding"
52+
_EDITOR_DEEPLINK = {e: f"{e}:extension/{_EXTENSION_ID}" for e in _EDITOR_LABEL}
53+
_MARKETPLACE_URL = f"https://marketplace.visualstudio.com/items?itemName={_EXTENSION_ID}"
54+
4855

4956
def build_cta(cta_base: str, owner: str, repo: str, pr: str, repo_path: Path, issues: int = 0) -> str:
50-
"""Return the markdown CTA footer (the warning banner shows even without a proxy URL).
57+
"""Return the markdown CTA footer: a health-warning banner plus editor/extension links.
5158
52-
The ⚠️ health banner is informational and needs no proxy, so it renders
53-
whenever ``issues > 0``; the editor/marketplace links require ``cta_base``.
54-
Returns '' only when there's nothing to show.
59+
With a ``cta_base`` proxy the links route through it (owner/repo/pr tracked);
60+
without one they point straight to the destinations the proxy would route to —
61+
the editor's ``<scheme>:extension/...`` deep link and the Marketplace listing.
62+
The ⚠️ banner shows whenever ``issues > 0``.
5563
"""
5664
parts: list[str] = []
5765
if issues > 0:
5866
noun = "issue" if issues == 1 else "issues"
5967
parts.append(f"⚠️ **{issues} architecture {noun} found** — open CodeBoarding to explore them.")
6068

69+
editors = detect_editors(repo_path)
6170
if cta_base:
6271
base = cta_base.rstrip("/")
6372

6473
def link(path: str, **extra: str) -> str:
6574
return f"{base}/{path}?" + urlencode({"owner": owner, "repo": repo, "pr": pr, **extra})
6675

67-
editor_links = " · ".join(
68-
f"[**Open in {_EDITOR_LABEL[e]} →**]({link('open-in-editor', editor=e)})" for e in detect_editors(repo_path)
69-
)
70-
parts.append(f"See this architecture in your editor: {editor_links}")
71-
parts.append(f"💡 New to CodeBoarding? [**Get the extension →**]({link('use-marketplace')})")
76+
editor_href = {e: link("open-in-editor", editor=e) for e in editors}
77+
extension_href = link("use-marketplace")
78+
else:
79+
editor_href = {e: _EDITOR_DEEPLINK[e] for e in editors}
80+
extension_href = _MARKETPLACE_URL
81+
82+
editor_links = " · ".join(f"[**Open in {_EDITOR_LABEL[e]} →**]({editor_href[e]})" for e in editors)
83+
parts.append(f"See this architecture in your editor: {editor_links}")
84+
parts.append(f"💡 New to CodeBoarding? [**Get the extension →**]({extension_href})")
7285

73-
if not parts:
74-
return ""
7586
lines = ["", "---"]
7687
for p in parts:
7788
lines += ["", p]

tests/test_build_cta.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,18 @@ def test_both_vscode_first(self):
3131

3232

3333
class TestBuildCta(unittest.TestCase):
34-
def test_empty_base_yields_no_footer(self):
35-
self.assertEqual(bc.build_cta("", "o", "r", "1", repo_with()), "")
36-
37-
def test_warning_shows_without_cta_base(self):
38-
out = bc.build_cta("", "o", "r", "1", repo_with(), issues=3)
34+
def test_no_proxy_falls_back_to_editor_deeplink_and_marketplace(self):
35+
out = bc.build_cta("", "o", "r", "1", repo_with(".cursor"), issues=3)
3936
self.assertIn("3 architecture issues found", out)
40-
self.assertNotIn("http", out) # no links without a proxy base
37+
self.assertIn("[**Open in Cursor →**](cursor:extension/Codeboarding.codeboarding)", out)
38+
self.assertIn("marketplace.visualstudio.com/items?itemName=Codeboarding.codeboarding", out)
39+
self.assertNotIn("open-in-editor", out) # no proxy routing
40+
self.assertNotIn("Open in VS Code", out) # cursor-only repo
41+
42+
def test_no_proxy_default_vscode_deeplink_no_banner_at_zero(self):
43+
out = bc.build_cta("", "o", "r", "1", repo_with()) # neither dir, no issues
44+
self.assertIn("[**Open in VS Code →**](vscode:extension/Codeboarding.codeboarding)", out)
45+
self.assertNotIn("architecture issue", out) # banner suppressed at 0 issues
4146

4247
def test_links_banner_and_cursor_only(self):
4348
out = bc.build_cta("https://x.dev/", "Org", "Repo", "9", repo_with(".cursor"), issues=2)

0 commit comments

Comments
 (0)