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.
- package/dist/__tests__/auth.test.d.ts +2 -0
- package/dist/__tests__/auth.test.d.ts.map +1 -0
- package/dist/__tests__/auth.test.js +201 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/admin-onboarding.d.ts +12 -10
- package/dist/admin-onboarding.d.ts.map +1 -1
- package/dist/admin-onboarding.js +107 -48
- package/dist/admin-onboarding.js.map +1 -1
- package/dist/auth.d.ts +74 -14
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +176 -103
- package/dist/auth.js.map +1 -1
- package/dist/fetch-template.d.ts +3 -3
- package/dist/fetch-template.d.ts.map +1 -1
- package/dist/fetch-template.js +93 -71
- package/dist/fetch-template.js.map +1 -1
- package/dist/git.d.ts +12 -1
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +40 -20
- package/dist/git.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +55 -18
- package/dist/scaffold.js.map +1 -1
- package/dist/team-setup.d.ts.map +1 -1
- package/dist/team-setup.js +3 -0
- package/dist/team-setup.js.map +1 -1
- package/dist/teams-flow.d.ts +7 -2
- package/dist/teams-flow.d.ts.map +1 -1
- package/dist/teams-flow.js +53 -14
- package/dist/teams-flow.js.map +1 -1
- package/dist/ui.d.ts +3 -0
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +79 -3
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/dist/art.d.ts +0 -17
- package/dist/art.d.ts.map +0 -1
- package/dist/art.js +0 -171
- package/dist/art.js.map +0 -1
- package/dist/cloud.d.ts +0 -26
- package/dist/cloud.d.ts.map +0 -1
- package/dist/cloud.js +0 -126
- package/dist/cloud.js.map +0 -1
- package/dist/tui.d.ts +0 -8
- package/dist/tui.d.ts.map +0 -1
- package/dist/tui.js +0 -86
- 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 →
|
|
10
|
+
* 4. On success: GET api.github.com/user → save token to ~/.hq/app-token.json
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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
|
|
43
|
-
*
|
|
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
|
|
63
|
+
export declare function loadGitHubAuth(tokenPath?: string): GitHubAuth | null;
|
|
46
64
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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.
|
|
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.
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA
|
|
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 →
|
|
10
|
+
* 4. On success: GET api.github.com/user → save token to ~/.hq/app-token.json
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
/**
|
|
42
|
-
|
|
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
|
-
|
|
45
|
-
|
|
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
|
|
75
|
+
return null;
|
|
49
76
|
}
|
|
50
77
|
}
|
|
51
78
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
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
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
|
70
|
-
|
|
91
|
+
catch {
|
|
92
|
+
// ignore — may already be gone
|
|
71
93
|
}
|
|
72
94
|
}
|
|
73
95
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
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
|
|
85
|
-
if (!
|
|
86
|
-
return
|
|
99
|
+
export async function isGitHubAuthValid(auth) {
|
|
100
|
+
if (!auth.access_token)
|
|
101
|
+
return false;
|
|
87
102
|
try {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
|
114
|
+
return false;
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
|
-
/**
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
//
|
|
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.
|
|
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
|
-
//
|
|
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":"AAAA
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/fetch-template.d.ts
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Strategy:
|
|
5
5
|
* 1. GitHub REST API → download tarball_url
|
|
6
|
-
* 2. Fallback:
|
|
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":"
|
|
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"}
|