Repository navigation
feat(app): offer Get your team started and deploy the team's services from the app - #553
Merged
Merged
Conversation
…tarted Ace Helper ships prebuilt directory and channel bundles and deploys them with the owner's wrangler login, naming them after the tailnet, then joins the directory. The Set up step shows progress instead of a command to copy. Fly.io still runs the checkout script. Why: apps/host/src/team.ts | Ace Helper runs wrangler as plain Bun via BUN_BE_BUN, and deploys the bundles apps/desktop/scripts/helper.ts writes to Resources/services; both layouts must stay in step.
#561) * feat(app): invite teammates with one link that fills in Join your team The Invite screen and Settings → Team → Invite… copy an ace://join link carrying the directory URL and team secret. Pasting it into either join form fills both fields, and the desktop app registers its channel's scheme so opening the link brings up Join your team, filled in, for the person to check and join. Why: apps/desktop/electrobun.config.ts | each build channel registers its own scheme (ace, ace-canary, ace-dev) so a dev or Canary build never answers stable's invite links; apps/app/src/invite.ts reads all of them. Why: apps/app/src/invite.ts#function parse | an invite link only fills the join form; joining must stay an explicit Check and join, since a link can name any directory. * lane: confirm notes for invite link * lane: sync invite-link memory * feat(app): send invites as an https link to the join page Chat apps linkify https, not ace://. The link opens ace.githubnext.com/join, which offers the download and hands off to ace://join. Pasting either form still fills Join your team. Why: apps/app/src/invite.ts#function link | the invite must stay in the URL fragment so the secret never reaches the site's server * lane: confirm invite parse note * lane: sync invite-link memory * feat(app): ask a teammate's host to join the team over the tailnet (#563) * feat(app): ask a teammate's host to join the team over the tailnet A host that isn't in a team finds peers whose hello names a team directory and offers "<person> on <machine> is in a team. Ask to join". The peer's owner approves or denies in their app; on approval the directory URL and secret travel over the tailnet and the asking host joins as with directory-set. Asks end on deny, disconnect, a repeat ask, or after five minutes. Why: apps/host/src/protocol.ts#type Hello | hello answers any tailnet peer, so team carries only the directory's host, never the secret Why: apps/host/src/gateway.ts#function asksChanged | only the local app can answer an ask (team-answer is a keychain op), so asks reach local sockets only * lane: confirm notes for ask to join * lane: sync ask-to-join memory
# Conflicts: # .lane/memory/apps/host/src/gateway.ts/01M5D4BXMERGZ1EZ3EYAFM3YC4-worker-requests-worker-never.md # apps/app/src/directory-settings.tsx
This was referenced Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First run now opens a team setup dialog, built from the reviewed design in #549. It opens once, when there are no projects yet, and Settings → Team → Set up your team opens it again.
bun services/deploy.ts cloudflarefrom feat: deploy the team's services to Cloudflare or Fly.io with one command #552.tail1234.ts.netgetsace-directory-tail1234.How it works: the desktop build prebuilds both services with
wrangler deploy --dry-run --outdirintoResources/services/<service>/(with awrangler.jsonset tono_bundle). The directory is 12 KB and the channel service is 5 MB. A newteam-deployhost op runswrangler@4.140.0through Ace Helper's own Bun (BUN_BE_BUN=1), so it needs no Node. It streams progress withwaitingframes, the same waycompute-startdoes, and only the owner's local app can call it, like the other keychain ops. A source run deploys fromservices/instead.Tested in the dev build (
bun desktop dev): clicked through to Deploy with hosted channels off. The deploy signed in, deployedace-directory-tail49836a, and joined in about 15 seconds. Settings then showed the directory, with the secret saved in Keychain. The Worker refused unauthenticated requests (401). Afterwards I deleted the Worker and left the directory.Earlier, tested headlessly against a fresh host profile, in light and dark:
smoke3, deleted afterwards) joined through the dialog and reached the invite screen.Depends on #552 for the Fly.io script and tailnet naming. Part of #549, #550.
Built in Ace
No. Claude Code in a terminal wrote this, drove a headless browser for the checks, and clicked through the dev build with Desktop Tools, because the session started outside Ace. It wasn't blocked by a missing Ace capability, so no issue was filed.
Also includes #561 (invite link) and #563 (ask to join over the tailnet), squash-merged into this branch.