Skip to content

feat(app): Share-dialog hub CTA + local-only link confirm (0290) - #449

Closed
crs48 wants to merge 1 commit into
mainfrom
claude/0290-share-dialog-hub-cta-local-only
Closed

feat(app): Share-dialog hub CTA + local-only link confirm (0290)#449
crs48 wants to merge 1 commit into
mainfrom
claude/0290-share-dialog-hub-cta-local-only

Conversation

@crs48

@crs48 crs48 commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Implements the two remaining UI items from docs/explorations/0290_[_]_SHARE_LINK_GENERATION_FAILURE_MODES.md (bugs #2 and #3, both Option A). Follows up on #448.

No-hub dead-end → "Connect a hub…" CTA

  • ShareDialog (!ready) now explains why sharing needs a hub and offers a Connect a hub… button that closes the dialog and opens the status bar's connection panel (new openSyncStatusPanel() event in SyncStatus.tsx; the mobile sheet listens too).
  • The connection panel gains an inline hub-URL connect form (shown while disconnected), persisting via the same hub-url.ts helpers as Settings → Network and reloading to apply — so the CTA genuinely lands you connected, per the exploration's validation criterion.
  • Bug fix uncovered en route: the floating-islands shell (0286) clips the status bar island with overflow-hidden, which swallowed the sync-status popover entirely (it opened invisibly). The popover is now portaled into .wb-root (fixed-position above the chip; portal stays inside the shell root so .dark .wb-root tokens keep working) and uses bg-island-pop — the previous bg-surface resolved to transparent (same dead token 0287 fixed for modals).

Private-hub links → "Local only" + confirm

  • Fresh and listed link URLs get an amber Local only chip when isPrivateHubHost(hubHttpUrl).
  • Copy and QR arm on first click ("Copy anyway" / "QR anyway", 4s window) before acting. Generation stays enabled — LAN/in-person QR handoff is legitimate.

Verification

  • apps/web typecheck clean; new ShareDialog.test.tsx (CTA event + arming + public-hub no-confirm) plus FormShareBar/share-links/sync-format suites: 41 tests green (re-run after rebasing onto post-Enforce demo-hub storage guardrails (0291) + workspace share links (0290) #448 main).
  • Driven live against a real local hub (ws://localhost:4444): CTA → panel → connect → reload → chip "Hub: connected · healthy" → New link mints http://localhost:4444/s/… with Local-only chip; Copy/QR require the confirm click; QR renders after confirming.
  • Checked off the two implementation-checklist items in the 0290 doc (the doc also picked up repo-prettier reformatting from the pre-commit hook).

🤖 Generated with Claude Code

With no hub connected the Share dialog dead-ended at explanatory text; it
now explains why sharing needs a hub and offers a "Connect a hub…" button
that opens the status bar's connection panel. That panel gains an inline
hub-URL connect form (persisted like Settings → Network, reload applies),
and is portaled out of the status-bar island — the floating-islands shell's
overflow-hidden was clipping the popover into invisibility.

Links minted on a private/LAN hub are labelled "Local only", and Copy/QR
arm on first click ("Copy anyway" / "QR anyway") so a link that only works
on the local network isn't handed out as if it were public. Generation
stays enabled — LAN/QR handoff is legitimate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
@github-actions

Copy link
Copy Markdown
Contributor

🖼️ UI changes in this PR

No visual differences detected in the changed UI.

CI run

github-actions Bot added a commit that referenced this pull request Jul 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Preview: https://xnet.fyi/pr/449/app/

@crs48

crs48 commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

Closing in favour of #658, which rebuilds both of these items against today's surfaces.

This diff could not be rebased: its main target, apps/web/src/workbench/SyncStatus.tsx, was deleted from main by the 0406 unification (#653) — the component now lives in packages/workbench/src/SyncStatus.tsx, and ShareDialog.tsx gained 99 lines since this branch's merge-base (03782e355, 20 days old).

That turned out to be good news for the feature: building it in packages/workbench lands the hub CTA on desktop and web at once, which this web-only patch could not.

Both 0290 items (the !ready "Connect a hub…" CTA, and the local-only copy confirm) are implemented and verified against a real hub in #658; 0290 is now [-] at 11/20. Full triage: docs/explorations/0410_[_]_OPEN_PR_TRIAGE_AND_THE_STRANDED_BRANCH_PROBLEM.md.

@crs48 crs48 closed this Jul 30, 2026
crs48 added a commit that referenced this pull request Jul 30, 2026
…(0410) (#658)

Implements exploration
`0410_[_]_OPEN_PR_TRIAGE_AND_THE_STRANDED_BRANCH_PROBLEM.md`, written in
the previous turn.

## What this closes out

Eight PRs were open, the oldest from March. Checking each one's **actual
diff against `main`** (rather than its description) found that four
described work already in `main`, re-derived and landed weeks later by
another route.

| PR | Age | Action taken |
| --- | --- | --- |
| #400 | 24d | **Closed** — fix landed on main in a better form; branch
predates 0391 and would have deleted `NodeLineRunner` |
| #9 | 145d | **Closed** — draft;
`apps/electron/src/renderer/workspace/` no longer exists |
| #595 | 11d | **Closed** — byte-identical to main (`fbc2965a2`) |
| #463 | 20d | **Closed** — main has a longer, `[x]` version of 0298 |
| #13 | 141d | **Closed** — both fixes on main verbatim |
| #505 | 17d | **Merged** — exploration 0318 + scale bench |
| #389 | 25d | **Merged** — exploration 0270 |
| #449 | 20d | **Rebuilt here** — see below |

`#400` was the load-bearing one: `git diff origin/main pr400 --
packages/devkit/src/command-runner.ts` showed ~150 lines of *deletion*
covering the whole 0391 streaming agent seam. Only its `CONFLICTING`
state had prevented that.

`#505`'s `build-and-smoke-test` went green on a rebase, confirming it
was branch staleness rather than the diff.

## The #449 rebuild (0290 bugs #2 and #3)

The original patched `apps/web/src/workbench/SyncStatus.tsx`, which 0406
deleted; the component now lives in `packages/workbench`, so the rebuild
lands on **desktop and web at once**.

- `WorkbenchHost` gains a `hub` capability (`configuredUrl` / `connect`)
so the shell can offer a way out of the disconnected state without
importing either app's `hub-url` module. `connect` returns a reason
string on rejection — never a silent no-op.
- `SyncStatus` exports `openSyncStatusPanel()`; the desktop popover and
mobile sheet both listen. The panel shows an inline hub-URL form while
there is no hub.
- `ShareDialog`'s `!ready` branch explains why a hub is needed and
offers **Connect a hub…**; private-hub links now confirm before copying.
- Adds `normalizeHubUrl` to the electron renderer's `hub-url` mirror (+4
unit tests), so a malformed URL is rejected loudly rather than
persisted.

Verified by driving the real app against a local hub — the CTA closes
the dialog and opens the panel; an invalid URL shows an error and
persists nothing; `https://hub.xnet.fyi/` normalises to
`wss://hub.xnet.fyi`; a `localhost` link's first Copy click asks "Copy
local-only link?" and writes nothing, the second copies. No console
errors. 0290 is now `[-]` at 11/20.

## Stopping the recurrence

Time-to-merge for the last 20 merged PRs was **0 hours median, 1 hour
max** — there is no review queue, so a PR that outlives its session is
abandoned, not pending.

- `.github/workflows/stale.yml` — warns at 14d, closes at 21d,
`keep-open` exempts. Named consumer (the maintainer, weekly) and a
decidable pass condition, per AGENTS.md.
- Fixed the `/explore` next-number command, which read only the working
tree and so handed out numbers already claimed on branches. Seven
explorations were found stranded that way.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

1 participant