create-hq 10.8.0 → 10.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/__tests__/auth.test.d.ts +2 -0
  2. package/dist/__tests__/auth.test.d.ts.map +1 -0
  3. package/dist/__tests__/auth.test.js +201 -0
  4. package/dist/__tests__/auth.test.js.map +1 -0
  5. package/dist/admin-onboarding.d.ts +12 -10
  6. package/dist/admin-onboarding.d.ts.map +1 -1
  7. package/dist/admin-onboarding.js +107 -48
  8. package/dist/admin-onboarding.js.map +1 -1
  9. package/dist/auth.d.ts +74 -14
  10. package/dist/auth.d.ts.map +1 -1
  11. package/dist/auth.js +176 -103
  12. package/dist/auth.js.map +1 -1
  13. package/dist/fetch-template.d.ts +3 -3
  14. package/dist/fetch-template.d.ts.map +1 -1
  15. package/dist/fetch-template.js +93 -71
  16. package/dist/fetch-template.js.map +1 -1
  17. package/dist/git.d.ts +12 -1
  18. package/dist/git.d.ts.map +1 -1
  19. package/dist/git.js +40 -20
  20. package/dist/git.js.map +1 -1
  21. package/dist/index.js +0 -0
  22. package/dist/scaffold.d.ts.map +1 -1
  23. package/dist/scaffold.js +55 -18
  24. package/dist/scaffold.js.map +1 -1
  25. package/dist/team-setup.d.ts.map +1 -1
  26. package/dist/team-setup.js +3 -0
  27. package/dist/team-setup.js.map +1 -1
  28. package/dist/teams-flow.d.ts +7 -2
  29. package/dist/teams-flow.d.ts.map +1 -1
  30. package/dist/teams-flow.js +53 -14
  31. package/dist/teams-flow.js.map +1 -1
  32. package/dist/ui.d.ts +3 -0
  33. package/dist/ui.d.ts.map +1 -1
  34. package/dist/ui.js +79 -3
  35. package/dist/ui.js.map +1 -1
  36. package/package.json +1 -1
  37. package/dist/art.d.ts +0 -17
  38. package/dist/art.d.ts.map +0 -1
  39. package/dist/art.js +0 -171
  40. package/dist/art.js.map +0 -1
  41. package/dist/cloud.d.ts +0 -26
  42. package/dist/cloud.d.ts.map +0 -1
  43. package/dist/cloud.js +0 -126
  44. package/dist/cloud.js.map +0 -1
  45. package/dist/tui.d.ts +0 -8
  46. package/dist/tui.d.ts.map +0 -1
  47. package/dist/tui.js +0 -86
  48. package/dist/tui.js.map +0 -1
package/dist/auth.d.ts CHANGED
@@ -7,17 +7,21 @@
7
7
  * 1. POST github.com/login/device/code with our App's client_id
8
8
  * 2. Display user_code, open verification_uri in browser
9
9
  * 3. Poll github.com/login/oauth/access_token at the GitHub-specified interval
10
- * 4. On success: GET api.github.com/user → configure gh CLI with the token
10
+ * 4. On success: GET api.github.com/user → save token to ~/.hq/app-token.json
11
11
  *
12
- * After authentication, the token is handed to `gh auth login --with-token`
13
- * so that subsequent sessions can use `gh` for all GitHub operations.
14
- * No credentials are persisted to disk by create-hq itself.
12
+ * The HQ App token is stored in ~/.hq/app-token.json (mode 0600) and is
13
+ * completely independent of the user's `gh` CLI auth. This means:
14
+ * - Running `gh auth login` / `gh auth logout` does not affect HQ auth
15
+ * - HQ auth does not overwrite the user's existing `gh` token
16
+ * - The App token is only used for HQ-specific API calls (installations, etc.)
15
17
  *
16
18
  * Token values are NEVER written to stdout or logs.
17
19
  */
18
20
  /** hq-team-sync GitHub App client ID (public — safe to commit). */
19
21
  export declare const HQ_GITHUB_APP_CLIENT_ID = "Iv23liSdkCBQYhrNcRmI";
20
22
  export declare const HQ_GITHUB_APP_SLUG = "hq-team-sync";
23
+ /** Where the HQ App token is persisted. Exported for tests. */
24
+ export declare const HQ_APP_TOKEN_PATH: string;
21
25
  /** Authenticated GitHub user info. The access_token is held in-memory only. */
22
26
  export interface GitHubAuth {
23
27
  /** ghu_ user-to-server token from GitHub App device flow (in-memory only). */
@@ -39,22 +43,51 @@ export interface GitHubAuth {
39
43
  */
40
44
  export type AuthToken = GitHubAuth;
41
45
  /**
42
- * Save the GitHub auth to gh CLI. The token is handed to `gh auth login`
43
- * so it's stored in the OS keychain, not on disk as a plain file.
46
+ * Save the HQ App auth to ~/.hq/app-token.json.
47
+ *
48
+ * The file is written with mode 0600 (owner read+write only). The user's
49
+ * existing `gh` CLI auth is never touched.
50
+ *
51
+ * @param tokenPath — override for testing; defaults to HQ_APP_TOKEN_PATH
52
+ */
53
+ export declare function saveGitHubAuth(auth: GitHubAuth, tokenPath?: string): void;
54
+ /**
55
+ * Load HQ App auth from ~/.hq/app-token.json.
56
+ *
57
+ * Returns null if the file doesn't exist, is corrupted, or is missing
58
+ * required fields. Does NOT fall back to `gh` CLI — the HQ App token
59
+ * is separate from the user's personal GitHub auth.
60
+ *
61
+ * @param tokenPath — override for testing; defaults to HQ_APP_TOKEN_PATH
44
62
  */
45
- export declare function saveGitHubAuth(auth: GitHubAuth): void;
63
+ export declare function loadGitHubAuth(tokenPath?: string): GitHubAuth | null;
46
64
  /**
47
- * Load GitHub auth from `gh` CLI. Returns null if gh is not installed
48
- * or not authenticated. Fetches user profile from GitHub API via gh.
65
+ * Remove stored HQ App credentials.
66
+ *
67
+ * Deletes ~/.hq/app-token.json. Does NOT touch `gh` CLI auth.
68
+ *
69
+ * @param tokenPath — override for testing; defaults to HQ_APP_TOKEN_PATH
49
70
  */
50
- export declare function loadGitHubAuth(): GitHubAuth | null;
51
- /** Remove stored credentials by logging out of gh. */
52
- export declare function clearGitHubAuth(): void;
71
+ export declare function clearGitHubAuth(tokenPath?: string): void;
53
72
  /**
54
73
  * Quick liveness probe — does the stored token still work?
55
- * Uses `gh auth status` which validates the token against GitHub.
74
+ * Validates the token by hitting GET /user on api.github.com.
56
75
  */
57
76
  export declare function isGitHubAuthValid(auth: GitHubAuth): Promise<boolean>;
77
+ /** Result of the App scope probe. */
78
+ export type AppScopeResult = "yes" | "no" | "unknown";
79
+ /**
80
+ * Probe whether a token has GitHub App scopes by hitting /user/installations.
81
+ *
82
+ * Returns:
83
+ * - `"yes"` — 2xx, token has App scopes
84
+ * - `"no"` — 403, token is definitively the wrong type
85
+ * - `"unknown"` — transient failure (network error, 5xx, timeout)
86
+ *
87
+ * Callers should only delete cached tokens on `"no"`, not on `"unknown"`.
88
+ * This is a lightweight check — we request per_page=1 to minimise payload.
89
+ */
90
+ export declare function isAppScopedToken(auth: GitHubAuth): Promise<AppScopeResult>;
58
91
  /** Open a URL in the user's default browser. Best-effort, never throws. */
59
92
  export declare function openBrowser(url: string): void;
60
93
  /**
@@ -62,7 +95,9 @@ export declare function openBrowser(url: string): void;
62
95
  *
63
96
  * On success, the token is:
64
97
  * 1. Returned in-memory as part of GitHubAuth (for the current session)
65
- * 2. Configured in `gh` CLI for future sessions (via gh auth login --with-token)
98
+ * 2. Persisted to ~/.hq/app-token.json for future sessions
99
+ *
100
+ * The user's existing `gh` CLI auth is never modified.
66
101
  *
67
102
  * Throws on:
68
103
  * - Network errors talking to github.com
@@ -71,6 +106,31 @@ export declare function openBrowser(url: string): void;
71
106
  * - Failure to fetch the user profile
72
107
  */
73
108
  export declare function startGitHubDeviceFlow(): Promise<GitHubAuth>;
109
+ /**
110
+ * Try to get the user's `gh` CLI OAuth token.
111
+ *
112
+ * Returns the token string if `gh` is installed, the user is logged in, and
113
+ * `gh auth token` succeeds. Returns null otherwise — this is purely
114
+ * opportunistic and never throws.
115
+ *
116
+ * The gh CLI token typically has `read:org` scope, which lets us enumerate
117
+ * ALL the user's org memberships — not just orgs where our GitHub App is
118
+ * installed. This gives us a better org picker during admin onboarding.
119
+ */
120
+ export declare function getGhCliToken(): string | null;
121
+ /**
122
+ * Fetch orgs where the user is an admin, using a raw bearer token.
123
+ *
124
+ * Works with both gh CLI tokens (PAT/OAuth) and GitHub App user tokens.
125
+ * The difference: a gh CLI token with `read:org` scope sees ALL orgs,
126
+ * while an App token only sees orgs where the App is installed.
127
+ *
128
+ * Returns an empty array on any error (permissions, network, etc.).
129
+ */
130
+ export declare function fetchAdminOrgsWithToken(token: string): Promise<{
131
+ login: string;
132
+ id: number;
133
+ }[]>;
74
134
  /**
75
135
  * Authenticated fetch against api.github.com. Throws on non-2xx with
76
136
  * the response body included for diagnostics.
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAUH,mEAAmE;AACnE,eAAO,MAAM,uBAAuB,yBAAyB,CAAC;AAC9D,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AAUjD,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,gEAAgE;IAChE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,yDAAyD;IACzD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC;AA8EnC;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAErD;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,GAAG,IAAI,CA+BlD;AAED,sDAAsD;AACtD,wBAAgB,eAAe,IAAI,IAAI,CAUtC;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAoB1E;AAID,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAkB7C;AAQD;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,UAAU,CAAC,CA0HjE;AAID;;;GAGG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAwBZ"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAUH,mEAAmE;AACnE,eAAO,MAAM,uBAAuB,yBAAyB,CAAC;AAC9D,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AAQjD,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,QAAsC,CAAC;AAIrE,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,gEAAgE;IAChE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,yDAAyD;IACzD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC;AA4BnC;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,SAAoB,GAAG,IAAI,CASpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,SAAS,SAAoB,GAAG,UAAU,GAAG,IAAI,CAW/E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,SAAoB,GAAG,IAAI,CAQnE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAe1E;AAED,qCAAqC;AACrC,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAuBhF;AAID,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAkB7C;AAQD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,UAAU,CAAC,CA0HjE;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAc7C;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CA2B1C;AAID;;;GAGG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAuCZ"}
package/dist/auth.js CHANGED
@@ -7,14 +7,17 @@
7
7
  * 1. POST github.com/login/device/code with our App's client_id
8
8
  * 2. Display user_code, open verification_uri in browser
9
9
  * 3. Poll github.com/login/oauth/access_token at the GitHub-specified interval
10
- * 4. On success: GET api.github.com/user → configure gh CLI with the token
10
+ * 4. On success: GET api.github.com/user → save token to ~/.hq/app-token.json
11
11
  *
12
- * After authentication, the token is handed to `gh auth login --with-token`
13
- * so that subsequent sessions can use `gh` for all GitHub operations.
14
- * No credentials are persisted to disk by create-hq itself.
12
+ * The HQ App token is stored in ~/.hq/app-token.json (mode 0600) and is
13
+ * completely independent of the user's `gh` CLI auth. This means:
14
+ * - Running `gh auth login` / `gh auth logout` does not affect HQ auth
15
+ * - HQ auth does not overwrite the user's existing `gh` token
16
+ * - The App token is only used for HQ-specific API calls (installations, etc.)
15
17
  *
16
18
  * Token values are NEVER written to stdout or logs.
17
19
  */
20
+ import * as fs from "fs";
18
21
  import * as path from "path";
19
22
  import * as os from "os";
20
23
  import { exec, execSync } from "child_process";
@@ -27,128 +30,125 @@ const GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
27
30
  const GITHUB_TOKEN_URL = "https://github.com/login/oauth/access_token";
28
31
  const GITHUB_API_USER_URL = "https://api.github.com/user";
29
32
  const HQ_DIR = path.join(os.homedir(), ".hq");
30
- // ─── gh CLI helpers ────────────────────────────────────────────────────────
31
- /** Check if `gh` CLI is installed. */
32
- function isGhInstalled() {
33
- try {
34
- execSync("gh --version", { stdio: "ignore" });
35
- return true;
36
- }
37
- catch {
38
- return false;
33
+ /** Where the HQ App token is persisted. Exported for tests. */
34
+ export const HQ_APP_TOKEN_PATH = path.join(HQ_DIR, "app-token.json");
35
+ // ─── Token persistence (~/.hq/app-token.json) ────────────────────────────
36
+ /**
37
+ * Save the HQ App auth to ~/.hq/app-token.json.
38
+ *
39
+ * The file is written with mode 0600 (owner read+write only). The user's
40
+ * existing `gh` CLI auth is never touched.
41
+ *
42
+ * @param tokenPath — override for testing; defaults to HQ_APP_TOKEN_PATH
43
+ */
44
+ export function saveGitHubAuth(auth, tokenPath = HQ_APP_TOKEN_PATH) {
45
+ const dir = path.dirname(tokenPath);
46
+ if (!fs.existsSync(dir)) {
47
+ fs.mkdirSync(dir, { recursive: true });
39
48
  }
49
+ fs.writeFileSync(tokenPath, JSON.stringify(auth, null, 2), {
50
+ encoding: "utf-8",
51
+ mode: 0o600,
52
+ });
40
53
  }
41
- /** Check if `gh` is authenticated with any GitHub host. */
42
- function isGhAuthenticated() {
54
+ /**
55
+ * Load HQ App auth from ~/.hq/app-token.json.
56
+ *
57
+ * Returns null if the file doesn't exist, is corrupted, or is missing
58
+ * required fields. Does NOT fall back to `gh` CLI — the HQ App token
59
+ * is separate from the user's personal GitHub auth.
60
+ *
61
+ * @param tokenPath — override for testing; defaults to HQ_APP_TOKEN_PATH
62
+ */
63
+ export function loadGitHubAuth(tokenPath = HQ_APP_TOKEN_PATH) {
43
64
  try {
44
- execSync("gh auth status", { stdio: "ignore" });
45
- return true;
65
+ if (!fs.existsSync(tokenPath))
66
+ return null;
67
+ const raw = fs.readFileSync(tokenPath, "utf-8");
68
+ const data = JSON.parse(raw);
69
+ // Minimal validation — must have at least a token and login
70
+ if (!data.access_token || !data.login)
71
+ return null;
72
+ return data;
46
73
  }
47
74
  catch {
48
- return false;
75
+ return null;
49
76
  }
50
77
  }
51
78
  /**
52
- * Configure `gh` CLI with a token and set up git credential helper.
53
- * This makes the token available for all future `gh` and `git` operations.
79
+ * Remove stored HQ App credentials.
80
+ *
81
+ * Deletes ~/.hq/app-token.json. Does NOT touch `gh` CLI auth.
82
+ *
83
+ * @param tokenPath — override for testing; defaults to HQ_APP_TOKEN_PATH
54
84
  */
55
- function configureGhAuth(token) {
56
- if (!isGhInstalled()) {
57
- console.error(chalk.dim(" (gh CLI not found — install it from https://cli.github.com for team commands)"));
58
- return;
59
- }
85
+ export function clearGitHubAuth(tokenPath = HQ_APP_TOKEN_PATH) {
60
86
  try {
61
- // Pipe token to gh auth login (stdin, non-interactive)
62
- execSync("gh auth login --with-token", {
63
- input: token,
64
- stdio: ["pipe", "ignore", "ignore"],
65
- });
66
- // Configure git to use gh for HTTPS auth
67
- execSync("gh auth setup-git", { stdio: "ignore" });
87
+ if (fs.existsSync(tokenPath)) {
88
+ fs.unlinkSync(tokenPath);
89
+ }
68
90
  }
69
- catch (err) {
70
- console.error(chalk.dim(" (could not configure gh CLI you can run `gh auth login` manually)"));
91
+ catch {
92
+ // ignoremay already be gone
71
93
  }
72
94
  }
73
95
  /**
74
- * Save the GitHub auth to gh CLI. The token is handed to `gh auth login`
75
- * so it's stored in the OS keychain, not on disk as a plain file.
76
- */
77
- export function saveGitHubAuth(auth) {
78
- configureGhAuth(auth.access_token);
79
- }
80
- /**
81
- * Load GitHub auth from `gh` CLI. Returns null if gh is not installed
82
- * or not authenticated. Fetches user profile from GitHub API via gh.
96
+ * Quick liveness probe does the stored token still work?
97
+ * Validates the token by hitting GET /user on api.github.com.
83
98
  */
84
- export function loadGitHubAuth() {
85
- if (!isGhInstalled() || !isGhAuthenticated())
86
- return null;
99
+ export async function isGitHubAuthValid(auth) {
100
+ if (!auth.access_token)
101
+ return false;
87
102
  try {
88
- // Get the token from gh
89
- const token = execSync("gh auth token", {
90
- encoding: "utf-8",
91
- stdio: ["pipe", "pipe", "ignore"],
92
- }).trim();
93
- if (!token)
94
- return null;
95
- // Get user profile via gh api
96
- const userJson = execSync('gh api user --jq \'{"login":.login,"id":.id,"name":.name,"email":.email}\'', {
97
- encoding: "utf-8",
98
- stdio: ["pipe", "pipe", "ignore"],
99
- }).trim();
100
- const user = JSON.parse(userJson);
101
- return {
102
- access_token: token,
103
- login: user.login,
104
- id: user.id,
105
- name: user.name,
106
- email: user.email,
107
- issued_at: new Date().toISOString(),
108
- };
103
+ const res = await fetch(GITHUB_API_USER_URL, {
104
+ headers: {
105
+ Authorization: `token ${auth.access_token}`,
106
+ Accept: "application/vnd.github+json",
107
+ "User-Agent": "create-hq",
108
+ },
109
+ signal: AbortSignal.timeout(10_000),
110
+ });
111
+ return res.ok;
109
112
  }
110
113
  catch {
111
- return null;
114
+ return false;
112
115
  }
113
116
  }
114
- /** Remove stored credentials by logging out of gh. */
115
- export function clearGitHubAuth() {
116
- if (!isGhInstalled())
117
- return;
117
+ /**
118
+ * Probe whether a token has GitHub App scopes by hitting /user/installations.
119
+ *
120
+ * Returns:
121
+ * - `"yes"` — 2xx, token has App scopes
122
+ * - `"no"` — 403, token is definitively the wrong type
123
+ * - `"unknown"` — transient failure (network error, 5xx, timeout)
124
+ *
125
+ * Callers should only delete cached tokens on `"no"`, not on `"unknown"`.
126
+ * This is a lightweight check — we request per_page=1 to minimise payload.
127
+ */
128
+ export async function isAppScopedToken(auth) {
129
+ if (!auth.access_token)
130
+ return "no";
118
131
  try {
119
- execSync("gh auth logout --hostname github.com", {
120
- input: "Y\n",
121
- stdio: ["pipe", "ignore", "ignore"],
132
+ const res = await fetch("https://api.github.com/user/installations?per_page=1", {
133
+ headers: {
134
+ Authorization: `token ${auth.access_token}`,
135
+ Accept: "application/vnd.github+json",
136
+ "User-Agent": "create-hq",
137
+ },
138
+ signal: AbortSignal.timeout(10_000),
122
139
  });
140
+ if (res.ok)
141
+ return "yes";
142
+ // 401/403 = definitive "wrong token type"
143
+ if (res.status === 401 || res.status === 403)
144
+ return "no";
145
+ // Anything else (429, 5xx) = transient
146
+ return "unknown";
123
147
  }
124
148
  catch {
125
- // ignore may already be logged out
126
- }
127
- }
128
- /**
129
- * Quick liveness probe — does the stored token still work?
130
- * Uses `gh auth status` which validates the token against GitHub.
131
- */
132
- export async function isGitHubAuthValid(auth) {
133
- // If we have a token in memory, verify it directly
134
- if (auth.access_token) {
135
- try {
136
- const res = await fetch(GITHUB_API_USER_URL, {
137
- headers: {
138
- Authorization: `token ${auth.access_token}`,
139
- Accept: "application/vnd.github+json",
140
- "User-Agent": "create-hq",
141
- },
142
- signal: AbortSignal.timeout(10_000),
143
- });
144
- return res.ok;
145
- }
146
- catch {
147
- return false;
148
- }
149
+ // Network error, timeout, DNS failure = transient
150
+ return "unknown";
149
151
  }
150
- // Fall back to gh auth status
151
- return isGhAuthenticated();
152
152
  }
153
153
  // ─── Browser open (cross-platform) ──────────────────────────────────────────
154
154
  /** Open a URL in the user's default browser. Best-effort, never throws. */
@@ -180,7 +180,9 @@ function sleep(ms) {
180
180
  *
181
181
  * On success, the token is:
182
182
  * 1. Returned in-memory as part of GitHubAuth (for the current session)
183
- * 2. Configured in `gh` CLI for future sessions (via gh auth login --with-token)
183
+ * 2. Persisted to ~/.hq/app-token.json for future sessions
184
+ *
185
+ * The user's existing `gh` CLI auth is never modified.
184
186
  *
185
187
  * Throws on:
186
188
  * - Network errors talking to github.com
@@ -287,12 +289,74 @@ export async function startGitHubDeviceFlow() {
287
289
  email: user.email,
288
290
  issued_at: new Date().toISOString(),
289
291
  };
290
- // Configure gh CLI with the token for future sessions
292
+ // Persist for future sessions (does not touch gh CLI)
291
293
  saveGitHubAuth(auth);
292
294
  return auth;
293
295
  }
294
296
  throw new Error("GitHub device flow timed out — please try again");
295
297
  }
298
+ // ─── gh CLI token (opportunistic) ──────────────────────────────────────────
299
+ /**
300
+ * Try to get the user's `gh` CLI OAuth token.
301
+ *
302
+ * Returns the token string if `gh` is installed, the user is logged in, and
303
+ * `gh auth token` succeeds. Returns null otherwise — this is purely
304
+ * opportunistic and never throws.
305
+ *
306
+ * The gh CLI token typically has `read:org` scope, which lets us enumerate
307
+ * ALL the user's org memberships — not just orgs where our GitHub App is
308
+ * installed. This gives us a better org picker during admin onboarding.
309
+ */
310
+ export function getGhCliToken() {
311
+ try {
312
+ const token = execSync("gh auth token", {
313
+ stdio: ["pipe", "pipe", "pipe"],
314
+ timeout: 5_000,
315
+ })
316
+ .toString()
317
+ .trim();
318
+ // Sanity check — gh tokens start with gho_ or ghp_ (OAuth / PAT)
319
+ if (token && token.length > 10)
320
+ return token;
321
+ return null;
322
+ }
323
+ catch {
324
+ return null;
325
+ }
326
+ }
327
+ /**
328
+ * Fetch orgs where the user is an admin, using a raw bearer token.
329
+ *
330
+ * Works with both gh CLI tokens (PAT/OAuth) and GitHub App user tokens.
331
+ * The difference: a gh CLI token with `read:org` scope sees ALL orgs,
332
+ * while an App token only sees orgs where the App is installed.
333
+ *
334
+ * Returns an empty array on any error (permissions, network, etc.).
335
+ */
336
+ export async function fetchAdminOrgsWithToken(token) {
337
+ try {
338
+ const res = await fetch("https://api.github.com/user/memberships/orgs?state=active&per_page=100", {
339
+ headers: {
340
+ Authorization: `token ${token}`,
341
+ Accept: "application/vnd.github+json",
342
+ "User-Agent": "create-hq",
343
+ },
344
+ signal: AbortSignal.timeout(15_000),
345
+ });
346
+ if (!res.ok)
347
+ return [];
348
+ const memberships = (await res.json());
349
+ return memberships
350
+ .filter((m) => m.role === "admin")
351
+ .map((m) => ({
352
+ login: m.organization.login,
353
+ id: m.organization.id,
354
+ }));
355
+ }
356
+ catch {
357
+ return [];
358
+ }
359
+ }
296
360
  // ─── GitHub API helpers used by downstream flows ────────────────────────────
297
361
  /**
298
362
  * Authenticated fetch against api.github.com. Throws on non-2xx with
@@ -314,6 +378,15 @@ export async function githubApi(pathname, auth, init = {}) {
314
378
  });
315
379
  if (!res.ok) {
316
380
  const body = await res.text().catch(() => "");
381
+ // Friendly error when a non-App token hits the App-only installations endpoint.
382
+ if (res.status === 403 &&
383
+ pathname.startsWith("/user/installations") &&
384
+ body.includes("authorized to a GitHub App")) {
385
+ throw new Error("You're signed in with a regular GitHub token that can't list App installations.\n" +
386
+ " HQ Teams requires authentication through the HQ GitHub App.\n\n" +
387
+ " To fix this, re-run the installer — it will prompt you to authorize the HQ App:\n" +
388
+ " npx create-hq");
389
+ }
317
390
  throw new Error(`GitHub API ${res.status} ${pathname}: ${body}`);
318
391
  }
319
392
  // Some endpoints return 204
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -3,12 +3,12 @@
3
3
  *
4
4
  * Strategy:
5
5
  * 1. GitHub REST API → download tarball_url
6
- * 2. Fallback: `git clone --depth 1` (git is a hard dep, checked up front)
7
- * 3. If both fail: throw with manual instructions
6
+ * 2. Fallback: gh CLI (`gh api repos/indigoai-us/hq/tarball/{ref}`)
7
+ * 3. If both fail: throw with manual clone instructions
8
8
  *
9
9
  * Returns the version tag that was fetched.
10
10
  */
11
- export declare function fetchTemplate(targetDir: string, tag?: string): Promise<{
11
+ export declare function fetchTemplate(targetDir: string, tag?: string, onProgress?: (phase: string) => void): Promise<{
12
12
  version: string;
13
13
  }>;
14
14
  //# sourceMappingURL=fetch-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-template.d.ts","sourceRoot":"","sources":["../src/fetch-template.ts"],"names":[],"mappings":"AAqIA;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA6B9B"}
1
+ {"version":3,"file":"fetch-template.d.ts","sourceRoot":"","sources":["../src/fetch-template.ts"],"names":[],"mappings":"AAsJA;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,GAAG,CAAC,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GACnC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAyC9B"}