Team Onboarding
Team onboarding is built into create-hq, providing two distinct journeys depending on whether you’re creating a team or joining one.
Access to HQ is demo-gated — both journeys below begin once access has been granted through the demo flow. See Requesting Access.
Admin Journey
When an admin runs create-hq and has no pending invites:
1. "Do you have an HQ account?" → Yes → Device flow auth2. Check for pending invites → None found3. "Create a new team?"4. List GitHub orgs (from user's GitHub account)5. Check if HQ Team Sync App is installed └── Not installed → Opens browser for App install6. Confirm team name7. POST /api/teams/create-from-org └── Creates team, default 'base' pack (paths: ['*']) └── Creator assigned as admin8. Scaffold companies/{team-slug}/ └── Full directory structure (no sparse checkout for admin) └── team.json with team_id, org_login, etc.9. Post-setup orientation (4-6 bullet points)Member Journey
When a member runs create-hq and has a pending invite:
1. "Do you have an HQ account?" → Yes → Device flow auth2. Check for pending invites → Found! "You've been invited to join Acme Corp by alice@acme.com"3. Accept invite → POST /api/teams/join4. Fetch entitlements for assigned packs5. Scaffold companies/{team-slug}/ └── Sparse checkout for entitled paths only └── (or full checkout if pack has paths: ['*'])6. Configure git credential helper for future pulls7. Continue with normal HQ scaffoldGitHub Org Discovery
The onboarding flow uses two API endpoints to understand the user’s GitHub context:
GET /api/github/orgs— Lists orgs the user belongs toGET /api/github/installations— Lists orgs where the HQ Team Sync App is installed
If an org has the user as a member but doesn’t have the App installed, the flow guides them through installing it.
Bug Fixes
This project also fixed two blocking auth bugs from the hq-github-auth project:
- Device poll parameter name — The API now accepts both
device_codeanddeviceCodeto handle different client conventions - Auth redirect —
GET /api/auth/github/authorizenow returns a proper 302 redirect instead of a JSON 200 response
Filesystem Setup
Admin
companies/{team-slug}/ knowledge/ settings/ data/ workers/ repos/ projects/ policies/ team.json # team_id, org_login, github_app_installation_id .claude/commands/ # Team-distributed commandsMember (Sparse Checkout)
Only paths matching the assigned entitlement packs are checked out. Git credential helper is configured for git pull during future /sync operations.