feat(settings): add Cloudflare Tunnel pairing intent by Pierre-Mike · Pull Request #14040 · stablyai/orca · GitHub
Skip to content

feat(settings): add Cloudflare Tunnel pairing intent - #14040

Open
Pierre-Mike wants to merge 3 commits into
stablyai:mainfrom
Pierre-Mike:feat/cloudflare-tunnel-pairing-option
Open

Pierre-Mike wants to merge 3 commits into
stablyai:mainfrom
Pierre-Mike:feat/cloudflare-tunnel-pairing-option

Conversation

@Pierre-Mike

@Pierre-Mike Pierre-Mike commented Aug 12, 2026 •

Copy link
Copy Markdown

ELI5

Orca can already hand you a link that opens the whole app in a browser. Today that link only works if the browser can already reach your machine — same Wi-Fi, Tailscale, or an SSH tunnel you set up yourself. This adds a "Cloudflare Tunnel" choice that shows you the one command to run, takes the URL that command prints, and turns it into a link that works from anywhere.

What Changed

A fourth option in Settings → Remote Orca Servers → Share this host → "Where will this link be opened?":

  • Shows cloudflared tunnel --url http://127.0.0.1:<port> using the runtime's real bound port, with a copy button.
  • Accepts the https://….trycloudflare.com URL cloudflared prints, and normalizes it to wss:// before it reaches the main process.
  • Rejects loopback, tailnet, and LAN hostnames for this field, since a tunnel fronting those mints a link the outside world cannot open.
  • Warns when the hostname is a quick tunnel, because those change on every cloudflared restart and silently kill a previously generated link.
  • Withholds the command entirely (rather than printing a placeholder port) when the runtime port isn't known yet.

Supporting refactors, no behavior change: the intent radios moved to RuntimePairingIntentOptions.tsx and the access-grant list/revoke logic to a useRuntimeAccessGrants hook. RuntimePairingUrlGenerator.tsx was sitting at exactly the 400-line max-lines cap, so this keeps both files under it without adding a suppression.

Why

The existing Custom address field cannot serve this case, for two concrete reasons:

  1. parseServerShareAddress rejects http(s):// outright, so pasting what cloudflared actually prints fails validation.
  2. A scheme-less host takes the parseHostOverride path in resolveAdvertisedPairingEndpoint and inherits the bound local port — foo.trycloudflare.com would be advertised as ws://foo.trycloudflare.com:6768 against a tunnel edge that only answers on 443. That link fails silently, with no clue why.

So the fix is not "document the custom field." It needs a parser that always emits a full wss:// URL. That is what parseCloudflareTunnelAddress does.

This also makes the browser client genuinely usable remotely: the tunnel terminates TLS, so the page is served over https:// and the socket is wss://, which sidesteps the mixed-content rejection in isMixedContentWebSocket that blocks the plain-LAN http:// + ws:// combination.

Linked Issue

Fixes #14039

Also related to #12535, which asks for the same thing on the Orca Mobile pairing surface (Orca Relay / LAN). This PR covers the desktop Share this host surface only, so it does not close that one. Worth deciding whether the two should be tracked together.

Visual Proof

The whole flow

Recorded from the real app: pick the option, see the command with this runtime's actual bound port, get a loopback URL rejected, paste the URL cloudflared prints and watch it accepted with the quick-tunnel warning, then the same state in dark mode.

Cloudflare Tunnel flow

The recording deliberately stops before Generate Access Link — clicking it renders a real pairing token on screen, which does not belong in a public PR.

Before / after

Same viewport and pane in both, so they tab cleanly.

Before — three options:

Before

After — four options in a 2×2 grid:

After

Dark mode

Dark mode

One thing the screenshots caught that no static check would: at four columns the cards were too narrow for the settings pane and "Another device" wrapped mid-phrase into Another / device. Fixed by dropping to a 2×2 grid.

Media is hosted on the pr-media branch of the fork so it stays out of this PR's diff, per the template's "do not commit to files".

Testing

Verified by driving the real app through the repo's own e2e harness (tests/e2e/helpers/orca-app.ts, isolated userData, built --mode e2e), navigating to the pane and exercising every state. The capture spec was removed before commit per tests/e2e/AGENTS.md — the logic is pure and already covered by DOM-level unit tests, so a permanent e2e spec would pay an Electron launch for no added coverage.

Reviewer steps:

  1. Settings → Remote Orca Servers → Share this host.
  2. Pick Cloudflare Tunnel. Confirm the command shows your actual runtime port.
  3. Run that command; paste the printed https://… URL. Generate Access Link, open it in a browser.
  4. Try https://127.0.0.1:6768 in the field — it should be refused.
Check Result
pnpm lint pass
pnpm typecheck pass
pnpm test 50,652 pass; 3 pre-existing failures, see below
pnpm build (build:desktop) pass
Localization catalog / extraction / coverage pass, keys added to all 5 locales
max-lines ratchet, reliability gates pass

Pre-existing test failures, not from this PR: src/main/providers/local-pty-shell-ready.test.ts (typeset -U path scoping) and 2 in src/relay/agent-exec-handler.test.ts. I stashed the entire change and reproduced the identical 3 failures on clean HEAD — they're environmental on my machine (zsh config / process spawning).

Platforms: developed and verified on macOS. No platform-specific code paths — no keyboard shortcuts, no filesystem paths, and cloudflared tunnel --url http://127.0.0.1:<port> is byte-identical on macOS, Linux, and Windows. Not manually run on Linux or Windows.

  • I manually tested these changes locally
  • Automated tests added/updated, or explained why not below

Added: cloudflare-tunnel-address.test.ts (parser edge cases — loopback/tailnet/LAN rejection, trailing slash, scheme-less host, credential-bearing URLs), plus cases in RuntimePairingGeneratorForm.test.tsx (command rendering, withheld command, Generate gating) and RuntimePairingUrlGenerator.test.tsx (reach for the new intent, and that a pasted https:// URL reaches main as wss://).

AI Disclosure

Written with Claude Code using Claude Opus 5. Every check in the table above was run locally; the before/after screenshots come from driving the real Electron app, not from mockups.

Review

  • Security. The tunnel makes the runtime reachable from the internet while cloudflared runs; the UI says so and points at the revocable grant list below. Pairing payloads stay in the URL fragment, so the token never reaches Cloudflare's edge in a request line or Referer. The field refuses credential-bearing URLs (normalizePairingUrl rejects user/password) and wildcard hosts.
  • ⚠️ Reach — please review this specifically. The new intent uses reach: 'network', same as Custom, so generating a link still fires the one-way ensureNetworkExposure() widen from STA-2370. For a Cloudflare Tunnel that widen is arguably unnecessary, because cloudflared dials loopback. I deliberately did not narrow it: servesThisComputerOnly only skips the widen when the advertised host is loopback, and a tunnel's host is public, so honoring it would mean changing that invariant — with a real risk of minting links that have no listener behind them. That belongs in its own reviewed change, not as a rider on a UI addition. Flagging it as a deliberate call, not an oversight.
  • Cross-platform. No platform-conditional code. See Testing.
  • Remote SSH. The port and the pairing address both come from the same local rpcServer (isWebSocketReady / getRuntimePairingUrl), so they cannot disagree. Matches how the three existing intents already behave.
  • Mobile. Untouched. Mobile-scoped pairing offers still return webClientUrl: null, and WebConnect still rejects a mobile-scope offer for the full web app.
  • Backwards compatibility. No wire change. RuntimePairingIntent gains a renderer-local variant; the value sent to main is an ordinary advertised address string that resolveAdvertisedPairingEndpoint already accepted.
  • Performance. One extra isWebSocketReady() IPC on pane mount, guarded and best-effort. Parsing is synchronous string work on input.

Known overlap I chose not to refactor: webSocketEndpointPort in src/shared/network/pairing-url.ts duplicates getWebSocketPort in src/main/runtime/windows-mobile-firewall.ts. The latter is main-process and separately tested; deduping it would widen this diff. Happy to fold that in if you'd rather.

Not covered by tests: the live isWebSocketReady() → port plumbing (unit tests mock it). If that IPC changes shape, the panel silently falls back to the unavailable row instead of failing loudly. Can add a narrow e2e spec for just that if you want it.

Checklist

  • This PR is small and focused
  • I explained what changed and why (including ELI5)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

Author

  • X / Twitter: — (happy to add if you'd like the shout-out)

Adds a fourth option to "Where will this link be opened?" so a browser
outside the network can reach this Orca server through a Cloudflare
Tunnel. The panel shows the `cloudflared` command with the runtime's
real bound port, then accepts the https:// URL cloudflared prints.

The existing Custom address field could not serve this: it rejects
https:// outright, and a scheme-less host would inherit the bound local
port from resolveAdvertisedPairingEndpoint and advertise
ws://host:6768 against a tunnel edge that only answers on 443. The new
parser always normalizes to a full wss:// URL and rejects loopback,
tailnet, and LAN hosts, which would mint a link the outside world
cannot open.

Reach is unchanged (network), so the one-way STA-2370 widen still
applies. Narrowing it for tunnels touches that invariant and belongs in
its own change.

Extracted the intent radios and the access-grant hook to keep both
touched files under the max-lines cap without a suppression.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The pairing settings now include Cloudflare Tunnel as a runtime pairing intent. The form validates public tunnel URLs, generates loopback cloudflared commands, and supports command copying. The generator discovers the local WebSocket port, normalizes tunnel addresses, caches intent-specific addresses, and manages access grants through a new hook. Shared network utilities and tests cover address parsing, quick tunnels, command formatting, and endpoint ports. Localized strings were added for supported languages.

Merge Risk: 🟡 Moderate · up to 08158

The PR adds Cloudflare Tunnel pairing, but the current head contains malformed Spanish localization data that can prevent the catalog from loading and should be fixed before merge. A separate low-severity failure path can leave the runtime listener exposed on network interfaces after pairing setup fails, requiring explicit owner follow-up.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 12 files. (5 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: adding Cloudflare Tunnel pairing support in settings.
Description check ✅ Passed The description is detailed and mostly complete. It explains the change, motivation, linked issue, visual proof, testing, AI use, review considerations, scope, and checklist status.
Linked Issues check ✅ Passed The implementation satisfies issue [#14039]. It adds a dedicated Cloudflare Tunnel target, uses the runtime port, normalizes HTTPS tunnel URLs to wss://, rejects unsafe hosts, warns about quick tunnel…
Out of Scope Changes check ✅ Passed The changes remain within scope. The extracted intent component, access-grant hook, shared parsing utilities, localization, and tests directly support the Cloudflare Tunnel feature or maintain existin…
Full details: Linked Issues check

Explanation

The implementation satisfies issue [#14039]. It adds a dedicated Cloudflare Tunnel target, uses the runtime port, normalizes HTTPS tunnel URLs to wss://, rejects unsafe hosts, warns about quick tunnels, preserves access grants and pairing behavior, and keeps mobile scope unchanged.

Full details: Out of Scope Changes check

Explanation

The changes remain within scope. The extracted intent component, access-grant hook, shared parsing utilities, localization, and tests directly support the Cloudflare Tunnel feature or maintain existing behavior.

Full details: Docstring Coverage

Explanation

Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 12 files. (5 skipped: 5 unsupported.)

  • Fix all pre-merge checks with AI

Warning

Some tools did not complete. Review the errors below.

🔧 Biome (2.5.7)
src/renderer/src/i18n/locales/en.json

File contains syntax errors that prevent linting: Line 11495: expected , but instead found "GlobalWorktreeVisibilitySourcesSetting"; Line 17067: expected } but instead the file ends

src/renderer/src/i18n/locales/es.json

File contains syntax errors that prevent linting: Line 10291: expected , but instead found "GlobalWorktreeVisibilitySourcesSetting"; Line 14850: expected } but instead the file ends

src/renderer/src/i18n/locales/ja.json

File contains syntax errors that prevent linting: Line 10291: expected , but instead found "GlobalWorktreeVisibilitySourcesSetting"; Line 14850: expected } but instead the file ends

  • 2 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/renderer/src/components/settings/RuntimePairingUrlGenerator.test.tsx (1)

116-117: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reduce this comment to one line.

Keep the rationale, but state it in one concise sentence.

-  // Why: the pairing offer only skips grafting the bound local port onto the advertised host when the
-  // address carries a scheme, so an https:// paste has to reach main as wss:// or the link dials :6768.
+  // Preserve `wss://` so main does not append the local WebSocket port.

As per coding guidelines, comments must be concise, non-obvious, and brief—prefer one line.

Source: Coding guidelines

src/renderer/src/components/settings/RuntimePairingUrlGenerator.tsx (1)

143-145: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Keep explanatory comments brief.

These comments repeat nearby code behavior across multiple lines. Reduce each comment to one non-obvious sentence, or remove it.

As per coding guidelines: “Comments must be concise, non-obvious, and brief—prefer one line; do not explain obvious behavior or walk through code.”

Also applies to: 177-179

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bc17dd2f-ec48-4331-9ec5-d8b5d8ad7e26

📥 Commits

Reviewing files that changed from the base of the PR and between 09ec516 and d4e186c.

📒 Files selected for processing (16)
  • src/renderer/src/components/settings/CloudflareTunnelFields.tsx
  • src/renderer/src/components/settings/RuntimePairingGeneratorForm.test.tsx
  • src/renderer/src/components/settings/RuntimePairingGeneratorForm.tsx
  • src/renderer/src/components/settings/RuntimePairingIntentOptions.tsx
  • src/renderer/src/components/settings/RuntimePairingUrlGenerator.test.tsx
  • src/renderer/src/components/settings/RuntimePairingUrlGenerator.tsx
  • src/renderer/src/components/settings/runtime-pairing-link-state.ts
  • src/renderer/src/components/settings/useRuntimeAccessGrants.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/shared/network/cloudflare-tunnel-address.test.ts
  • src/shared/network/cloudflare-tunnel-address.ts
  • src/shared/network/pairing-url.ts

Comment thread src/renderer/src/components/settings/RuntimePairingUrlGenerator.tsx Outdated
Comment thread src/renderer/src/components/settings/useRuntimeAccessGrants.ts
Comment thread src/shared/network/cloudflare-tunnel-address.ts
Review follow-ups on stablyai#14040.

parseCloudflareTunnelAddress accepted any scheme normalizePairingUrl
accepted, and that maps http: to ws: rather than wss:. A pasted
http://host therefore passed validation and was advertised as
ws://host, carrying pairing and control traffic to a public
destination in cleartext while the UI copy promised wss://. Reject
anything that does not normalize to wss://.

useRuntimeAccessGrants: a reload in flight when a revoke landed kept
the live loadId, so its pre-revocation response wrote the revoked
grant back into the list. Invalidate the load and clear its loading
state before filtering.

Re-read the bound WebSocket port on intent change so selecting
Cloudflare Tunnel picks up a listener that bound, or rebound on a new
port, after the pane mounted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Pierre-Mike

Copy link
Copy Markdown
Author

Thanks — the security finding was a real bug. All three actionable items and both nitpicks are addressed in ad48e9d.

🟠 http:// downgrading to cleartext ws:// — fixed

Confirmed before fixing. I wrote a throwaway test asserting the vulnerable behaviour and it passed, which proved it:

parseCloudflareTunnelAddress('http://orca.example.com')
  → { ok: true, value: 'ws://orca.example.com' }

So a pasted http:// address was advertised as plain ws:// to a public host, while the field's own helper text promised wss://. Worse, it would not have tripped isMixedContentWebSocket either: createWebClientUrl maps ws: → http:, so the browser page would have been served over http:// too and the whole session would have run in cleartext without a single warning.

Fixed by requiring wss:// after normalization, with tests covering http://, ws://, and http://…trycloudflare.com.

🟡 Reload resurrecting a revoked grant — fixed

Also confirmed with a failing test first (useRuntimeAccessGrants.test.ts), which reproduced it exactly:

AssertionError: expected [ 'a', 'b' ] to deeply equal [ 'b' ]

Applied your fix — bump loadIdRef and clear isLoading before filtering. The setIsLoading(false) matters and I'd have missed it: invalidating the load means its own finally can no longer clear the flag, so the list would have been stuck spinning. Both the happy path and the race are now pinned by tests.

Worth noting this race pre-dates the PR — it existed in RuntimePairingUrlGenerator.tsx before I extracted the hook. Fixed here since the extraction makes it mine.

🟡 Stale / missing localWebSocketPort — fixed

The effect now re-reads on intent change, so selecting Cloudflare Tunnel picks up a listener that bound, or rebound on a different port, after the pane mounted.

🧹 Both comment nitpicks — fixed

Reduced to one line each, per AGENTS.md ("BE CONCISE. 1 LINE if possible").


One check I'm not acting on: Docstring Coverage (25% vs 80%)

Raising this to 80% would mean adding docstrings to functions whose behaviour is already evident from their names and signatures — which this repo's AGENTS.md explicitly forbids:

Concise/Brief Non-obvious comments ONLY. DO NOT: be verbose, explain the obvious, walk through the code ("WHY not HOW"). BE CONCISE. 1 LINE if possible.

That directly contradicts the threshold, and the same run's nitpicks asked me to shorten comments. I've followed the repo's rule. Happy to add docstrings if a maintainer says the threshold wins.

Verification

pnpm lint, pnpm typecheck, type-aware audit, and build:web all pass. 1080 tests pass across the settings and network suites, up 3 from the new coverage.

Two open questions for a maintainer, both unchanged and flagged in the description: the reach / ensureNetworkExposure widen, and whether to consolidate with #12535.

@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1b42698c-fc47-48a2-b210-aef55ba831aa

📥 Commits

Reviewing files that changed from the base of the PR and between df95f03 and 08158c2.

📒 Files selected for processing (17)
  • src/renderer/src/components/settings/CloudflareTunnelFields.tsx
  • src/renderer/src/components/settings/RuntimePairingGeneratorForm.test.tsx
  • src/renderer/src/components/settings/RuntimePairingGeneratorForm.tsx
  • src/renderer/src/components/settings/RuntimePairingIntentOptions.tsx
  • src/renderer/src/components/settings/RuntimePairingUrlGenerator.test.tsx
  • src/renderer/src/components/settings/RuntimePairingUrlGenerator.tsx
  • src/renderer/src/components/settings/runtime-pairing-link-state.ts
  • src/renderer/src/components/settings/useRuntimeAccessGrants.test.ts
  • src/renderer/src/components/settings/useRuntimeAccessGrants.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/shared/network/cloudflare-tunnel-address.test.ts
  • src/shared/network/cloudflare-tunnel-address.ts
  • src/shared/network/pairing-url.ts
🚧 Files skipped from review as they are similar to previous changes (16)
  • src/renderer/src/components/settings/useRuntimeAccessGrants.test.ts
  • src/shared/network/cloudflare-tunnel-address.ts
  • src/shared/network/pairing-url.ts
  • src/renderer/src/components/settings/RuntimePairingGeneratorForm.tsx
  • src/renderer/src/components/settings/useRuntimeAccessGrants.ts
  • src/renderer/src/components/settings/RuntimePairingUrlGenerator.tsx
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/components/settings/RuntimePairingIntentOptions.tsx
  • src/renderer/src/components/settings/CloudflareTunnelFields.tsx
  • src/renderer/src/components/settings/RuntimePairingUrlGenerator.test.tsx
  • src/renderer/src/components/settings/runtime-pairing-link-state.ts
  • src/renderer/src/components/settings/RuntimePairingGeneratorForm.test.tsx
  • src/renderer/src/i18n/locales/zh.json
  • src/shared/network/cloudflare-tunnel-address.test.ts
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment on lines +6990 to +6992
"cloudflareTunnel": "Cloudflare Tunnel",
"cloudflareTunnelHelp": "Reach this server from outside your network",
"copiedTunnelCommand": "Copied tunnel command."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep untranslated English keys out of es.json.

cloudflareTunnelHelp and copiedTunnelCommand are English values in the Spanish catalog. Remove these entries until Spanish translations exist, while keeping the source keys in en.json. The inline translate() fallback should provide English without storing copied placeholders in the non-English catalog.

Based on learnings, the current localization workflow keeps new English-source keys out of non-English catalogs until real translations exist.

Source: Learnings

Comment on lines +10280 to +10290
"CloudflareTunnelFields": {
"startTunnel": "Start the tunnel on this computer",
"startTunnelHelp": "Run this where Orca is running and leave it open. It prints a public URL.",
"commandLabel": "Tunnel command",
"addressLabel": "Tunnel URL",
"addressPlaceholder": "https://example.trycloudflare.com",
"addressHint": "Paste the URL cloudflared printed. Orca connects to it over wss://.",
"addressInvalid": "Enter the public https:// or wss:// URL that cloudflared printed.",
"quickTunnelWarning": "Quick tunnel URLs change every time cloudflared restarts. Generate a new link after each restart.",
"exposureNote": "The tunnel makes this Orca server reachable from the internet while it runs. Revoke the access grant below when you are done.",
"commandUnavailable": "The runtime port is not available yet. Reopen this pane once the Orca server is listening."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Close CloudflareTunnelFields before the next locale section.

CloudflareTunnelFields opens on Line 10280, but GlobalWorktreeVisibilitySourcesSetting starts on Line 10291 before the object closes. This makes es.json invalid JSON and prevents the Spanish catalog from loading.

Proposed fix
-          "commandUnavailable": "The runtime port is not available yet. Reopen this pane once the Orca server is listening."
+          "commandUnavailable": "The runtime port is not available yet. Reopen this pane once the Orca server is listening.",
+        },
         "GlobalWorktreeVisibilitySourcesSetting": {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change

This branch has not been deployed

No deployments
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.

[Feature]: Add Cloudflare Tunnel as a pairing target for the browser access link

4 participants