create-hq 10.1.0 → 10.7.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/admin-onboarding.d.ts +42 -0
- package/dist/admin-onboarding.d.ts.map +1 -0
- package/dist/admin-onboarding.js +460 -0
- package/dist/admin-onboarding.js.map +1 -0
- package/dist/art.d.ts +17 -0
- package/dist/art.d.ts.map +1 -0
- package/dist/art.js +171 -0
- package/dist/art.js.map +1 -0
- package/dist/auth.d.ts +60 -23
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +219 -116
- package/dist/auth.js.map +1 -1
- package/dist/cloud.d.ts +26 -0
- package/dist/cloud.d.ts.map +1 -0
- package/dist/cloud.js +126 -0
- package/dist/cloud.js.map +1 -0
- package/dist/company-template.d.ts +34 -0
- package/dist/company-template.d.ts.map +1 -0
- package/dist/company-template.js +142 -0
- package/dist/company-template.js.map +1 -0
- package/dist/deps.d.ts +2 -0
- package/dist/deps.d.ts.map +1 -1
- package/dist/deps.js +42 -30
- package/dist/deps.js.map +1 -1
- package/dist/fetch-template.d.ts +2 -2
- package/dist/fetch-template.d.ts.map +1 -1
- package/dist/fetch-template.js +54 -38
- package/dist/fetch-template.js.map +1 -1
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +28 -4
- package/dist/git.js.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/invite-command.d.ts +10 -0
- package/dist/invite-command.d.ts.map +1 -0
- package/dist/invite-command.js +110 -0
- package/dist/invite-command.js.map +1 -0
- package/dist/invite.d.ts +91 -0
- package/dist/invite.d.ts.map +1 -0
- package/dist/invite.js +230 -0
- package/dist/invite.js.map +1 -0
- package/dist/join-flow.d.ts +32 -0
- package/dist/join-flow.d.ts.map +1 -0
- package/dist/join-flow.js +194 -0
- package/dist/join-flow.js.map +1 -0
- package/dist/platform.d.ts +2 -2
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +14 -1
- package/dist/platform.js.map +1 -1
- package/dist/scaffold.d.ts +4 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +152 -41
- package/dist/scaffold.js.map +1 -1
- package/dist/team-setup.d.ts +58 -0
- package/dist/team-setup.d.ts.map +1 -0
- package/dist/team-setup.js +237 -0
- package/dist/team-setup.js.map +1 -0
- package/dist/teams-flow.d.ts +36 -0
- package/dist/teams-flow.d.ts.map +1 -0
- package/dist/teams-flow.js +134 -0
- package/dist/teams-flow.js.map +1 -0
- package/dist/tui.d.ts +8 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +86 -0
- package/dist/tui.js.map +1 -0
- package/dist/ui.d.ts +17 -0
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +45 -0
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
package/dist/auth.js
CHANGED
|
@@ -1,44 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* GitHub App device flow auth for create-hq.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Talks directly to github.com — no backend involved.
|
|
5
|
+
*
|
|
6
|
+
* Flow:
|
|
7
|
+
* 1. POST github.com/login/device/code with our App's client_id
|
|
8
|
+
* 2. Display user_code, open verification_uri in browser
|
|
9
|
+
* 3. Poll github.com/login/oauth/access_token at the GitHub-specified interval
|
|
10
|
+
* 4. On success: GET api.github.com/user → store { access_token, login, id, name, email }
|
|
11
|
+
*
|
|
12
|
+
* Token is stored at ~/.hq/credentials.json (mode 0600). Tokens are
|
|
13
|
+
* GitHub App user-to-server tokens (ghu_…), so they ignore OAuth scopes —
|
|
14
|
+
* permissions are configured on the App settings page.
|
|
7
15
|
*
|
|
8
16
|
* Token values are NEVER written to stdout or logs.
|
|
9
17
|
*/
|
|
10
|
-
import * as crypto from "crypto";
|
|
11
|
-
import * as http from "http";
|
|
12
18
|
import * as fs from "fs";
|
|
13
19
|
import * as path from "path";
|
|
14
20
|
import * as os from "os";
|
|
15
21
|
import { exec } from "child_process";
|
|
22
|
+
import chalk from "chalk";
|
|
23
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
24
|
+
/** hq-team-sync GitHub App client ID (public — safe to commit). */
|
|
25
|
+
export const HQ_GITHUB_APP_CLIENT_ID = "Iv23liSdkCBQYhrNcRmI";
|
|
26
|
+
export const HQ_GITHUB_APP_SLUG = "hq-team-sync";
|
|
27
|
+
const GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
|
|
28
|
+
const GITHUB_TOKEN_URL = "https://github.com/login/oauth/access_token";
|
|
29
|
+
const GITHUB_API_USER_URL = "https://api.github.com/user";
|
|
16
30
|
const HQ_DIR = path.join(os.homedir(), ".hq");
|
|
17
|
-
const
|
|
18
|
-
// ─── Token store
|
|
31
|
+
const CREDENTIALS_FILE = path.join(HQ_DIR, "credentials.json");
|
|
32
|
+
// ─── Token store ────────────────────────────────────────────────────────────
|
|
19
33
|
function ensureHqDir() {
|
|
20
34
|
if (!fs.existsSync(HQ_DIR)) {
|
|
21
35
|
fs.mkdirSync(HQ_DIR, { recursive: true, mode: 0o700 });
|
|
22
36
|
}
|
|
23
37
|
}
|
|
24
|
-
/** Save
|
|
25
|
-
export function
|
|
38
|
+
/** Save credentials to ~/.hq/credentials.json with 0600 perms. */
|
|
39
|
+
export function saveGitHubAuth(auth) {
|
|
26
40
|
ensureHqDir();
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
fs.writeFileSync(CREDENTIALS_FILE, JSON.stringify(auth, null, 2), {
|
|
42
|
+
mode: 0o600,
|
|
43
|
+
});
|
|
29
44
|
}
|
|
30
|
-
/** Load
|
|
31
|
-
export function
|
|
45
|
+
/** Load credentials, or null if missing/invalid. */
|
|
46
|
+
export function loadGitHubAuth() {
|
|
32
47
|
try {
|
|
33
|
-
if (!fs.existsSync(
|
|
48
|
+
if (!fs.existsSync(CREDENTIALS_FILE))
|
|
34
49
|
return null;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
typeof parsed.user_id !== "string" ||
|
|
40
|
-
typeof parsed.email !== "string" ||
|
|
41
|
-
typeof parsed.expires_at !== "string") {
|
|
50
|
+
const parsed = JSON.parse(fs.readFileSync(CREDENTIALS_FILE, "utf-8"));
|
|
51
|
+
if (typeof parsed.access_token !== "string" ||
|
|
52
|
+
typeof parsed.login !== "string" ||
|
|
53
|
+
typeof parsed.id !== "number") {
|
|
42
54
|
return null;
|
|
43
55
|
}
|
|
44
56
|
return parsed;
|
|
@@ -47,110 +59,201 @@ export function loadToken() {
|
|
|
47
59
|
return null;
|
|
48
60
|
}
|
|
49
61
|
}
|
|
50
|
-
/**
|
|
51
|
-
export function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
/** Remove stored credentials. */
|
|
63
|
+
export function clearGitHubAuth() {
|
|
64
|
+
try {
|
|
65
|
+
if (fs.existsSync(CREDENTIALS_FILE)) {
|
|
66
|
+
fs.unlinkSync(CREDENTIALS_FILE);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// ignore
|
|
71
|
+
}
|
|
59
72
|
}
|
|
60
|
-
|
|
61
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Quick liveness probe — does the stored token still work?
|
|
75
|
+
* Calls api.github.com/user with the token; returns true on 200.
|
|
76
|
+
*/
|
|
77
|
+
export async function isGitHubAuthValid(auth) {
|
|
78
|
+
try {
|
|
79
|
+
const res = await fetch(GITHUB_API_USER_URL, {
|
|
80
|
+
headers: {
|
|
81
|
+
Authorization: `token ${auth.access_token}`,
|
|
82
|
+
Accept: "application/vnd.github+json",
|
|
83
|
+
"User-Agent": "create-hq",
|
|
84
|
+
},
|
|
85
|
+
signal: AbortSignal.timeout(10_000),
|
|
86
|
+
});
|
|
87
|
+
return res.ok;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
62
92
|
}
|
|
63
|
-
|
|
64
|
-
|
|
93
|
+
// ─── Browser open (cross-platform) ──────────────────────────────────────────
|
|
94
|
+
/** Open a URL in the user's default browser. Best-effort, never throws. */
|
|
95
|
+
export function openBrowser(url) {
|
|
96
|
+
let command;
|
|
97
|
+
if (process.platform === "darwin") {
|
|
98
|
+
command = `open "${url}"`;
|
|
99
|
+
}
|
|
100
|
+
else if (process.platform === "win32") {
|
|
101
|
+
// Windows: `start` is a cmd.exe builtin. The empty quotes are the
|
|
102
|
+
// window title argument (start treats the first quoted arg as title).
|
|
103
|
+
command = `start "" "${url}"`;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
command = `xdg-open "${url}"`;
|
|
107
|
+
}
|
|
65
108
|
exec(command, (err) => {
|
|
66
109
|
if (err) {
|
|
67
|
-
console.error(`
|
|
110
|
+
console.error(chalk.dim(` (could not open browser automatically — visit ${url} manually)`));
|
|
68
111
|
}
|
|
69
112
|
});
|
|
70
113
|
}
|
|
71
|
-
// ───
|
|
114
|
+
// ─── Device flow ────────────────────────────────────────────────────────────
|
|
115
|
+
function sleep(ms) {
|
|
116
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
117
|
+
}
|
|
72
118
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
119
|
+
* Run the GitHub App device authorization flow.
|
|
120
|
+
*
|
|
121
|
+
* Throws on:
|
|
122
|
+
* - Network errors talking to github.com
|
|
123
|
+
* - User-denied authorization (access_denied)
|
|
124
|
+
* - Device code expiration
|
|
125
|
+
* - Failure to fetch the user profile
|
|
80
126
|
*/
|
|
81
|
-
export async function
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
127
|
+
export async function startGitHubDeviceFlow() {
|
|
128
|
+
// 1. Request a device code
|
|
129
|
+
const deviceRes = await fetch(GITHUB_DEVICE_CODE_URL, {
|
|
130
|
+
method: "POST",
|
|
131
|
+
headers: {
|
|
132
|
+
Accept: "application/json",
|
|
133
|
+
"Content-Type": "application/json",
|
|
134
|
+
"User-Agent": "create-hq",
|
|
135
|
+
},
|
|
136
|
+
body: JSON.stringify({
|
|
137
|
+
client_id: HQ_GITHUB_APP_CLIENT_ID,
|
|
138
|
+
}),
|
|
139
|
+
signal: AbortSignal.timeout(15_000),
|
|
140
|
+
});
|
|
141
|
+
if (!deviceRes.ok) {
|
|
142
|
+
const body = await deviceRes.text().catch(() => "");
|
|
143
|
+
throw new Error(`GitHub device code request failed (${deviceRes.status}): ${body}`);
|
|
144
|
+
}
|
|
145
|
+
const device = (await deviceRes.json());
|
|
146
|
+
// 2. Display the code and open the browser
|
|
147
|
+
console.log();
|
|
148
|
+
console.log(chalk.bold(" Sign in with GitHub"));
|
|
149
|
+
console.log();
|
|
150
|
+
console.log(` Open this URL in your browser:`);
|
|
151
|
+
console.log(` ${chalk.cyan(device.verification_uri)}`);
|
|
152
|
+
console.log();
|
|
153
|
+
console.log(` Enter this code: ${chalk.bold.white(device.user_code)}`);
|
|
154
|
+
console.log();
|
|
155
|
+
console.log(chalk.dim(" Waiting for authorization..."));
|
|
156
|
+
openBrowser(device.verification_uri);
|
|
157
|
+
// 3. Poll for token
|
|
158
|
+
let pollInterval = Math.max((device.interval ?? 5) * 1000, 5000);
|
|
159
|
+
const expiresAt = Date.now() + (device.expires_in ?? 900) * 1000;
|
|
160
|
+
while (Date.now() < expiresAt) {
|
|
161
|
+
await sleep(pollInterval);
|
|
162
|
+
let tokenRes;
|
|
163
|
+
try {
|
|
164
|
+
tokenRes = await fetch(GITHUB_TOKEN_URL, {
|
|
165
|
+
method: "POST",
|
|
166
|
+
headers: {
|
|
167
|
+
Accept: "application/json",
|
|
168
|
+
"Content-Type": "application/json",
|
|
169
|
+
"User-Agent": "create-hq",
|
|
170
|
+
},
|
|
171
|
+
body: JSON.stringify({
|
|
172
|
+
client_id: HQ_GITHUB_APP_CLIENT_ID,
|
|
173
|
+
device_code: device.device_code,
|
|
174
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
175
|
+
}),
|
|
176
|
+
signal: AbortSignal.timeout(15_000),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// Network blip — keep polling
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const data = (await tokenRes.json().catch(() => ({})));
|
|
184
|
+
if (data.error === "authorization_pending")
|
|
185
|
+
continue;
|
|
186
|
+
if (data.error === "slow_down") {
|
|
187
|
+
// Per spec: increase polling interval by at least 5 seconds
|
|
188
|
+
const bump = (data.interval ?? 5) * 1000;
|
|
189
|
+
pollInterval = Math.max(pollInterval + bump, pollInterval + 5000);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (data.error === "expired_token") {
|
|
193
|
+
throw new Error("GitHub device code expired — please run create-hq again");
|
|
194
|
+
}
|
|
195
|
+
if (data.error === "access_denied") {
|
|
196
|
+
throw new Error("Authorization was denied");
|
|
197
|
+
}
|
|
198
|
+
if (data.error) {
|
|
199
|
+
throw new Error(`GitHub auth error: ${data.error}${data.error_description ? ` — ${data.error_description}` : ""}`);
|
|
200
|
+
}
|
|
201
|
+
if (!data.access_token) {
|
|
202
|
+
throw new Error("GitHub returned no access_token");
|
|
203
|
+
}
|
|
204
|
+
// 4. Fetch the authenticated user profile
|
|
205
|
+
const userRes = await fetch(GITHUB_API_USER_URL, {
|
|
206
|
+
headers: {
|
|
207
|
+
Authorization: `token ${data.access_token}`,
|
|
208
|
+
Accept: "application/vnd.github+json",
|
|
209
|
+
"User-Agent": "create-hq",
|
|
210
|
+
},
|
|
211
|
+
signal: AbortSignal.timeout(15_000),
|
|
148
212
|
});
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
213
|
+
if (!userRes.ok) {
|
|
214
|
+
const body = await userRes.text().catch(() => "");
|
|
215
|
+
throw new Error(`Failed to fetch GitHub user (${userRes.status}): ${body}`);
|
|
216
|
+
}
|
|
217
|
+
const user = (await userRes.json());
|
|
218
|
+
const auth = {
|
|
219
|
+
access_token: data.access_token,
|
|
220
|
+
login: user.login,
|
|
221
|
+
id: user.id,
|
|
222
|
+
name: user.name,
|
|
223
|
+
email: user.email,
|
|
224
|
+
issued_at: new Date().toISOString(),
|
|
225
|
+
};
|
|
226
|
+
saveGitHubAuth(auth);
|
|
227
|
+
return auth;
|
|
228
|
+
}
|
|
229
|
+
throw new Error("GitHub device flow timed out — please try again");
|
|
230
|
+
}
|
|
231
|
+
// ─── GitHub API helpers used by downstream flows ────────────────────────────
|
|
232
|
+
/**
|
|
233
|
+
* Authenticated fetch against api.github.com. Throws on non-2xx with
|
|
234
|
+
* the response body included for diagnostics.
|
|
235
|
+
*/
|
|
236
|
+
export async function githubApi(pathname, auth, init = {}) {
|
|
237
|
+
const url = pathname.startsWith("https://")
|
|
238
|
+
? pathname
|
|
239
|
+
: `https://api.github.com${pathname.startsWith("/") ? "" : "/"}${pathname}`;
|
|
240
|
+
const res = await fetch(url, {
|
|
241
|
+
...init,
|
|
242
|
+
headers: {
|
|
243
|
+
Authorization: `token ${auth.access_token}`,
|
|
244
|
+
Accept: "application/vnd.github+json",
|
|
245
|
+
"User-Agent": "create-hq",
|
|
246
|
+
...(init.headers || {}),
|
|
247
|
+
},
|
|
248
|
+
signal: init.signal ?? AbortSignal.timeout(20_000),
|
|
154
249
|
});
|
|
250
|
+
if (!res.ok) {
|
|
251
|
+
const body = await res.text().catch(() => "");
|
|
252
|
+
throw new Error(`GitHub API ${res.status} ${pathname}: ${body}`);
|
|
253
|
+
}
|
|
254
|
+
// Some endpoints return 204
|
|
255
|
+
if (res.status === 204)
|
|
256
|
+
return undefined;
|
|
257
|
+
return (await res.json());
|
|
155
258
|
}
|
|
156
259
|
//# sourceMappingURL=auth.js.map
|
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/cloud.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result type for cloud state detection.
|
|
3
|
+
*/
|
|
4
|
+
export type CloudState = {
|
|
5
|
+
status: "has-files";
|
|
6
|
+
count: number;
|
|
7
|
+
} | {
|
|
8
|
+
status: "empty";
|
|
9
|
+
} | {
|
|
10
|
+
status: "error";
|
|
11
|
+
message: string;
|
|
12
|
+
} | {
|
|
13
|
+
status: "no-auth";
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Pure function that checks cloud state without side effects.
|
|
17
|
+
* Takes dependencies as parameters for testability.
|
|
18
|
+
*/
|
|
19
|
+
export declare function checkCloudState(deps: {
|
|
20
|
+
hasCredentials: () => boolean;
|
|
21
|
+
listRemoteFiles: () => Promise<{
|
|
22
|
+
key: string;
|
|
23
|
+
}[]>;
|
|
24
|
+
}): Promise<CloudState>;
|
|
25
|
+
export declare function checkAndSyncCloud(targetDir: string): Promise<void>;
|
|
26
|
+
//# sourceMappingURL=cloud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"AAYA;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1B;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,cAAc,EAAE,MAAM,OAAO,CAAC;IAC9B,eAAe,EAAE,MAAM,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;CACnD,GAAG,OAAO,CAAC,UAAU,CAAC,CAetB;AAED,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8FxE"}
|
package/dist/cloud.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { success, warn, step } from "./ui.js";
|
|
2
|
+
import { tuiPrompt, tuiConfirm } from "./tui.js";
|
|
3
|
+
// Lazy import hq-cloud — it may not be installed yet
|
|
4
|
+
async function loadHqCloud() {
|
|
5
|
+
try {
|
|
6
|
+
return await import("@indigoai/hq-cloud");
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Pure function that checks cloud state without side effects.
|
|
14
|
+
* Takes dependencies as parameters for testability.
|
|
15
|
+
*/
|
|
16
|
+
export async function checkCloudState(deps) {
|
|
17
|
+
if (!deps.hasCredentials()) {
|
|
18
|
+
return { status: "no-auth" };
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const files = await deps.listRemoteFiles();
|
|
22
|
+
if (files.length > 0) {
|
|
23
|
+
return { status: "has-files", count: files.length };
|
|
24
|
+
}
|
|
25
|
+
return { status: "empty" };
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
29
|
+
return { status: "error", message };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function checkAndSyncCloud(targetDir) {
|
|
33
|
+
console.log();
|
|
34
|
+
const setupSync = await tuiConfirm("Set up cloud sync? (enables mobile access via hq.indigoai.com)");
|
|
35
|
+
if (!setupSync)
|
|
36
|
+
return;
|
|
37
|
+
const hqCloud = await loadHqCloud();
|
|
38
|
+
if (!hqCloud) {
|
|
39
|
+
warn("@indigoai/hq-cloud not available — skipping cloud sync");
|
|
40
|
+
step("You can set up cloud sync later with: hq sync init");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Authenticate
|
|
44
|
+
step("Authenticating with HQ Cloud...");
|
|
45
|
+
let authenticated = false;
|
|
46
|
+
try {
|
|
47
|
+
if (hqCloud.hasCredentials()) {
|
|
48
|
+
authenticated = true;
|
|
49
|
+
step("Using existing credentials");
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
await hqCloud.authenticate();
|
|
53
|
+
authenticated = true;
|
|
54
|
+
success("Authenticated with HQ Cloud");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
59
|
+
warn(`Authentication failed: ${message}`);
|
|
60
|
+
const skip = await tuiConfirm("Skip cloud setup and continue?");
|
|
61
|
+
if (skip)
|
|
62
|
+
return;
|
|
63
|
+
// If they don't want to skip, try once more
|
|
64
|
+
try {
|
|
65
|
+
await hqCloud.authenticate();
|
|
66
|
+
authenticated = true;
|
|
67
|
+
success("Authenticated with HQ Cloud");
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
warn("Authentication failed again — skipping cloud setup");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (!authenticated)
|
|
75
|
+
return;
|
|
76
|
+
// Check for existing remote files
|
|
77
|
+
step("Checking for existing files in your cloud HQ...");
|
|
78
|
+
let remoteFiles;
|
|
79
|
+
try {
|
|
80
|
+
remoteFiles = await hqCloud.listRemoteFiles();
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
84
|
+
warn(`Could not check remote files: ${message}`);
|
|
85
|
+
const skip = await tuiConfirm("Skip cloud setup and continue?");
|
|
86
|
+
if (!skip) {
|
|
87
|
+
warn("Cloud setup skipped");
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (remoteFiles.length > 0) {
|
|
92
|
+
// Existing files found — offer to clone down
|
|
93
|
+
console.log();
|
|
94
|
+
const cloneDown = await tuiConfirm(`Found ${remoteFiles.length} files in your cloud HQ. Clone to this machine?`);
|
|
95
|
+
if (cloneDown) {
|
|
96
|
+
step("Cloning files from cloud...");
|
|
97
|
+
try {
|
|
98
|
+
const result = await hqCloud.pullAll(targetDir);
|
|
99
|
+
success(`Cloned ${result.filesDownloaded} files from cloud to local HQ`);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
103
|
+
warn(`Clone failed: ${message}`);
|
|
104
|
+
step("Your local template files are still intact");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// User declined clone — warn about overwrite
|
|
109
|
+
warn("Uploading will overwrite your existing cloud files");
|
|
110
|
+
const overwriteConfirm = await tuiPrompt("This will replace your cloud HQ. Type YES to confirm:");
|
|
111
|
+
if (overwriteConfirm === "YES") {
|
|
112
|
+
step("Cloud files will be replaced on next sync");
|
|
113
|
+
step("Run: hq sync push");
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
step("Cloud sync skipped — your cloud files are unchanged");
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// No remote files — proceed with standard flow
|
|
122
|
+
step("No existing cloud files found — starting fresh");
|
|
123
|
+
step("Run: hq sync push — to upload your HQ to the cloud");
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=cloud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud.js","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Company / team-repo template generator.
|
|
3
|
+
*
|
|
4
|
+
* When an admin creates a new team, we need to seed the new {org}/hq private
|
|
5
|
+
* repo with a baseline directory structure that mirrors what /newcompany
|
|
6
|
+
* produces. This module renders that structure into a target directory
|
|
7
|
+
* (which is then committed and pushed to the new GitHub repo).
|
|
8
|
+
*
|
|
9
|
+
* No filesystem dependencies on the core HQ template — these files are
|
|
10
|
+
* synthesized in code so the seed is version-locked with the create-hq
|
|
11
|
+
* release the user just installed.
|
|
12
|
+
*/
|
|
13
|
+
export interface TeamMetadata {
|
|
14
|
+
team_id: string;
|
|
15
|
+
team_name: string;
|
|
16
|
+
team_slug: string;
|
|
17
|
+
org_login: string;
|
|
18
|
+
org_id: number;
|
|
19
|
+
created_by: string;
|
|
20
|
+
created_at: string;
|
|
21
|
+
hq_version: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Render the company template into targetDir. Creates the directory if it
|
|
25
|
+
* does not exist. Will not overwrite existing files (idempotent on re-runs).
|
|
26
|
+
*/
|
|
27
|
+
export declare function writeCompanyTemplate(targetDir: string, meta: TeamMetadata): void;
|
|
28
|
+
/**
|
|
29
|
+
* Ensure all standard company subdirectories exist inside targetDir
|
|
30
|
+
* without overwriting any existing files. Used after cloning a team repo
|
|
31
|
+
* to fill in any directories the upstream repo doesn't have yet.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ensureCompanyStructure(targetDir: string): void;
|
|
34
|
+
//# sourceMappingURL=company-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"company-template.d.ts","sourceRoot":"","sources":["../src/company-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AA0ED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,GACjB,IAAI,CA6CN;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAO9D"}
|