@indigoai-us/hq-cli 5.3.1 → 5.5.0
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/bin/hq-auth-refresh.d.ts +13 -0
- package/dist/bin/hq-auth-refresh.d.ts.map +1 -0
- package/dist/bin/hq-auth-refresh.js +27 -0
- package/dist/bin/hq-auth-refresh.js.map +1 -0
- package/dist/commands/auth.d.ts +17 -13
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +83 -238
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/cloud.d.ts +3 -12
- package/dist/commands/cloud.d.ts.map +1 -1
- package/dist/commands/cloud.js +55 -212
- package/dist/commands/cloud.js.map +1 -1
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +25 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +6 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +21 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/pkg-install.d.ts +17 -0
- package/dist/commands/pkg-install.d.ts.map +1 -0
- package/dist/commands/pkg-install.js +144 -0
- package/dist/commands/pkg-install.js.map +1 -0
- package/dist/commands/pkg-list.d.ts +8 -0
- package/dist/commands/pkg-list.d.ts.map +1 -0
- package/dist/commands/pkg-list.js +70 -0
- package/dist/commands/pkg-list.js.map +1 -0
- package/dist/commands/pkg-remove.d.ts +10 -0
- package/dist/commands/pkg-remove.d.ts.map +1 -0
- package/dist/commands/pkg-remove.js +53 -0
- package/dist/commands/pkg-remove.js.map +1 -0
- package/dist/commands/pkg-update.d.ts +9 -0
- package/dist/commands/pkg-update.d.ts.map +1 -0
- package/dist/commands/pkg-update.js +124 -0
- package/dist/commands/pkg-update.js.map +1 -0
- package/dist/commands/team-sync.d.ts +14 -0
- package/dist/commands/team-sync.d.ts.map +1 -0
- package/dist/commands/team-sync.js +422 -0
- package/dist/commands/team-sync.js.map +1 -0
- package/dist/commands/whoami.d.ts +6 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +29 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +33 -13
- package/dist/index.js.map +1 -1
- package/dist/strategies/merge.js +2 -2
- package/dist/strategies/merge.js.map +1 -1
- package/dist/utils/auth.d.ts +27 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +155 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/cognito-session.d.ts +35 -0
- package/dist/utils/cognito-session.d.ts.map +1 -0
- package/dist/utils/cognito-session.js +72 -0
- package/dist/utils/cognito-session.js.map +1 -0
- package/dist/utils/git.js +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/hq-root.d.ts +10 -0
- package/dist/utils/hq-root.d.ts.map +1 -0
- package/dist/utils/hq-root.js +22 -0
- package/dist/utils/hq-root.js.map +1 -0
- package/dist/utils/integrity.d.ts +14 -0
- package/dist/utils/integrity.d.ts.map +1 -0
- package/dist/utils/integrity.js +40 -0
- package/dist/utils/integrity.js.map +1 -0
- package/dist/utils/manifest.d.ts.map +1 -1
- package/dist/utils/manifest.js +2 -5
- package/dist/utils/manifest.js.map +1 -1
- package/dist/utils/registry-client.d.ts +65 -0
- package/dist/utils/registry-client.d.ts.map +1 -0
- package/dist/utils/registry-client.js +102 -0
- package/dist/utils/registry-client.js.map +1 -0
- package/dist/utils/registry.d.ts +33 -0
- package/dist/utils/registry.d.ts.map +1 -0
- package/dist/utils/registry.js +58 -0
- package/dist/utils/registry.js.map +1 -0
- package/dist/utils/token-store.d.ts +28 -0
- package/dist/utils/token-store.d.ts.map +1 -0
- package/dist/utils/token-store.js +68 -0
- package/dist/utils/token-store.js.map +1 -0
- package/package.json +35 -45
- package/src/bin/hq-auth-refresh.ts +32 -0
- package/src/commands/add.ts +74 -0
- package/src/commands/auth.ts +153 -0
- package/src/commands/cloud.ts +125 -0
- package/src/commands/list.ts +66 -0
- package/src/commands/login.ts +29 -0
- package/src/commands/logout.ts +25 -0
- package/src/commands/pkg-install.ts +181 -0
- package/src/commands/pkg-list.ts +98 -0
- package/src/commands/pkg-remove.ts +71 -0
- package/src/commands/pkg-update.ts +189 -0
- package/src/commands/sync.ts +149 -0
- package/src/commands/team-sync.ts +629 -0
- package/src/commands/update.ts +71 -0
- package/src/commands/whoami.ts +38 -0
- package/src/index.ts +72 -0
- package/src/schemas/hq-package.schema.json +137 -0
- package/src/strategies/link.ts +62 -0
- package/src/strategies/merge.ts +142 -0
- package/src/types.ts +47 -0
- package/src/utils/auth.ts +193 -0
- package/src/utils/cognito-session.ts +94 -0
- package/src/utils/git.ts +74 -0
- package/src/utils/hq-root.ts +27 -0
- package/src/utils/integrity.ts +54 -0
- package/src/utils/manifest.ts +109 -0
- package/src/utils/registry-client.ts +204 -0
- package/src/utils/registry.ts +89 -0
- package/src/utils/token-store.ts +83 -0
- package/tsconfig.json +8 -0
- package/dist/commands/cloud-setup.d.ts +0 -19
- package/dist/commands/cloud-setup.d.ts.map +0 -1
- package/dist/commands/cloud-setup.js +0 -206
- package/dist/commands/cloud-setup.js.map +0 -1
- package/dist/commands/initial-upload.d.ts +0 -67
- package/dist/commands/initial-upload.d.ts.map +0 -1
- package/dist/commands/initial-upload.js +0 -205
- package/dist/commands/initial-upload.js.map +0 -1
- package/dist/sync-worker.d.ts +0 -11
- package/dist/sync-worker.d.ts.map +0 -1
- package/dist/sync-worker.js +0 -77
- package/dist/sync-worker.js.map +0 -1
- package/dist/utils/api-client.d.ts +0 -26
- package/dist/utils/api-client.d.ts.map +0 -1
- package/dist/utils/api-client.js +0 -87
- package/dist/utils/api-client.js.map +0 -1
- package/dist/utils/credentials.d.ts +0 -44
- package/dist/utils/credentials.d.ts.map +0 -1
- package/dist/utils/credentials.js +0 -101
- package/dist/utils/credentials.js.map +0 -1
- package/dist/utils/sync.d.ts +0 -125
- package/dist/utils/sync.d.ts.map +0 -1
- package/dist/utils/sync.js +0 -291
- package/dist/utils/sync.js.map +0 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Standalone `hq-auth-refresh` entry point.
|
|
4
|
+
*
|
|
5
|
+
* Exists so the deploy skill (.claude/skills/deploy/SKILL.md step 4) can
|
|
6
|
+
* shell out to a plain binary instead of a subcommand. Equivalent to
|
|
7
|
+
* `hq auth refresh`.
|
|
8
|
+
*
|
|
9
|
+
* Exit 0 on refresh, exit 1 if no cached session or refresh failed.
|
|
10
|
+
* Writes the refreshed tokens to ~/.hq/cognito-tokens.json.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=hq-auth-refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hq-auth-refresh.d.ts","sourceRoot":"","sources":["../../src/bin/hq-auth-refresh.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Standalone `hq-auth-refresh` entry point.
|
|
4
|
+
*
|
|
5
|
+
* Exists so the deploy skill (.claude/skills/deploy/SKILL.md step 4) can
|
|
6
|
+
* shell out to a plain binary instead of a subcommand. Equivalent to
|
|
7
|
+
* `hq auth refresh`.
|
|
8
|
+
*
|
|
9
|
+
* Exit 0 on refresh, exit 1 if no cached session or refresh failed.
|
|
10
|
+
* Writes the refreshed tokens to ~/.hq/cognito-tokens.json.
|
|
11
|
+
*/
|
|
12
|
+
import { refreshCachedSession } from "../utils/cognito-session.js";
|
|
13
|
+
async function main() {
|
|
14
|
+
const result = await refreshCachedSession();
|
|
15
|
+
if (result.refreshed) {
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
if (result.reason) {
|
|
19
|
+
process.stderr.write(`hq-auth-refresh: ${result.reason}\n`);
|
|
20
|
+
}
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
main().catch((err) => {
|
|
24
|
+
process.stderr.write(`hq-auth-refresh: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=hq-auth-refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hq-auth-refresh.js","sourceRoot":"","sources":["../../src/bin/hq-auth-refresh.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,MAAM,oBAAoB,EAAE,CAAC;IAC5C,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oBAAoB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CACzE,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/commands/auth.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hq auth
|
|
2
|
+
* `hq auth` — Cognito identity management for HQ.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* hq auth login — open the Cognito Hosted UI in the browser and cache tokens
|
|
6
|
+
* hq auth logout — clear the cached HQ session
|
|
7
|
+
* hq auth refresh — refresh the cached Cognito session (non-interactive)
|
|
8
|
+
* hq auth status — show whether a valid session is cached + expiry
|
|
9
|
+
*
|
|
10
|
+
* Sign-up is owned by the onboarding web app at
|
|
11
|
+
* https://onboarding.indigo-hq.com. `hq auth login` signs an existing account
|
|
12
|
+
* into this machine by writing ~/.hq/cognito-tokens.json; once cached, the
|
|
13
|
+
* session is kept fresh by `hq auth refresh` / `hq-auth-refresh` and consumed
|
|
14
|
+
* by the deploy + sync skills.
|
|
15
|
+
*
|
|
16
|
+
* Note: the top-level `hq login` command authenticates against the HQ package
|
|
17
|
+
* registry (Clerk), not Cognito — that is a different auth stack.
|
|
15
18
|
*/
|
|
16
|
-
|
|
19
|
+
import { Command } from "commander";
|
|
20
|
+
export declare function registerAuthCommands(program: Command): void;
|
|
17
21
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+F3D"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,268 +1,113 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hq auth
|
|
2
|
+
* `hq auth` — Cognito identity management for HQ.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* hq auth login — open the Cognito Hosted UI in the browser and cache tokens
|
|
6
|
+
* hq auth logout — clear the cached HQ session
|
|
7
|
+
* hq auth refresh — refresh the cached Cognito session (non-interactive)
|
|
8
|
+
* hq auth status — show whether a valid session is cached + expiry
|
|
9
|
+
*
|
|
10
|
+
* Sign-up is owned by the onboarding web app at
|
|
11
|
+
* https://onboarding.indigo-hq.com. `hq auth login` signs an existing account
|
|
12
|
+
* into this machine by writing ~/.hq/cognito-tokens.json; once cached, the
|
|
13
|
+
* session is kept fresh by `hq auth refresh` / `hq-auth-refresh` and consumed
|
|
14
|
+
* by the deploy + sync skills.
|
|
15
|
+
*
|
|
16
|
+
* Note: the top-level `hq login` command authenticates against the HQ package
|
|
17
|
+
* registry (Clerk), not Cognito — that is a different auth stack.
|
|
11
18
|
*/
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import { readCredentials, writeCredentials, clearCredentials, isExpired, } from '../utils/credentials.js';
|
|
16
|
-
import { getApiUrl, apiRequest } from '../utils/api-client.js';
|
|
17
|
-
/** Port range for the localhost callback server */
|
|
18
|
-
const MIN_PORT = 19750;
|
|
19
|
-
const MAX_PORT = 19850;
|
|
20
|
-
/** Timeout for waiting for the browser callback (ms) */
|
|
21
|
-
const LOGIN_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
19
|
+
import chalk from "chalk";
|
|
20
|
+
import { browserLogin, clearCachedTokens, loadCachedTokens, isExpiring, CognitoAuthError, } from "@indigoai-us/hq-cloud";
|
|
21
|
+
import { DEFAULT_COGNITO, refreshCachedSession, } from "../utils/cognito-session.js";
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* Decode the (unverified) ID token payload for display purposes only.
|
|
24
|
+
* The token was just returned by Cognito's token endpoint, so its contents
|
|
25
|
+
* are trusted enough to print — we never use these claims for authorization.
|
|
25
26
|
*/
|
|
26
|
-
|
|
27
|
-
const { exec } = await import('child_process');
|
|
28
|
-
const { promisify } = await import('util');
|
|
29
|
-
const execAsync = promisify(exec);
|
|
30
|
-
const platform = process.platform;
|
|
31
|
-
let command;
|
|
32
|
-
if (platform === 'darwin') {
|
|
33
|
-
command = `open "${url}"`;
|
|
34
|
-
}
|
|
35
|
-
else if (platform === 'win32') {
|
|
36
|
-
command = `start "" "${url}"`;
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
// Linux — try xdg-open, then sensible-browser
|
|
40
|
-
command = `xdg-open "${url}" 2>/dev/null || sensible-browser "${url}" 2>/dev/null || echo "OPEN_FAILED"`;
|
|
41
|
-
}
|
|
27
|
+
function peekIdToken(idToken) {
|
|
42
28
|
try {
|
|
43
|
-
|
|
29
|
+
const payload = idToken.split(".")[1];
|
|
30
|
+
if (!payload)
|
|
31
|
+
return {};
|
|
32
|
+
const pad = payload.length % 4 === 0 ? "" : "=".repeat(4 - (payload.length % 4));
|
|
33
|
+
const normalized = payload.replace(/-/g, "+").replace(/_/g, "/") + pad;
|
|
34
|
+
const decoded = JSON.parse(Buffer.from(normalized, "base64").toString("utf-8"));
|
|
35
|
+
return { email: decoded.email, sub: decoded.sub };
|
|
44
36
|
}
|
|
45
37
|
catch {
|
|
46
|
-
|
|
38
|
+
return {};
|
|
47
39
|
}
|
|
48
40
|
}
|
|
49
|
-
|
|
50
|
-
* Find an available port in the callback port range.
|
|
51
|
-
*/
|
|
52
|
-
function findAvailablePort() {
|
|
53
|
-
return new Promise((resolve, reject) => {
|
|
54
|
-
const port = MIN_PORT + Math.floor(Math.random() * (MAX_PORT - MIN_PORT));
|
|
55
|
-
const server = http.createServer();
|
|
56
|
-
server.listen(port, '127.0.0.1', () => {
|
|
57
|
-
server.close(() => resolve(port));
|
|
58
|
-
});
|
|
59
|
-
server.on('error', () => {
|
|
60
|
-
// Try another port
|
|
61
|
-
const fallback = MIN_PORT + Math.floor(Math.random() * (MAX_PORT - MIN_PORT));
|
|
62
|
-
const server2 = http.createServer();
|
|
63
|
-
server2.listen(fallback, '127.0.0.1', () => {
|
|
64
|
-
server2.close(() => resolve(fallback));
|
|
65
|
-
});
|
|
66
|
-
server2.on('error', () => {
|
|
67
|
-
reject(new Error('Could not find an available port for auth callback'));
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* HTML page shown to the user after successful login.
|
|
74
|
-
*/
|
|
75
|
-
function successHtml() {
|
|
76
|
-
return `<!DOCTYPE html>
|
|
77
|
-
<html>
|
|
78
|
-
<head><title>HQ CLI — Logged In</title></head>
|
|
79
|
-
<body style="font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; background: #f8f9fa;">
|
|
80
|
-
<div style="text-align: center; max-width: 400px;">
|
|
81
|
-
<h1 style="color: #16a34a;">Logged In</h1>
|
|
82
|
-
<p style="color: #4b5563;">You have been authenticated. You can close this tab and return to the terminal.</p>
|
|
83
|
-
</div>
|
|
84
|
-
</body>
|
|
85
|
-
</html>`;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* HTML page shown on error.
|
|
89
|
-
*/
|
|
90
|
-
function errorHtml(message) {
|
|
91
|
-
return `<!DOCTYPE html>
|
|
92
|
-
<html>
|
|
93
|
-
<head><title>HQ CLI — Auth Error</title></head>
|
|
94
|
-
<body style="font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; background: #f8f9fa;">
|
|
95
|
-
<div style="text-align: center; max-width: 400px;">
|
|
96
|
-
<h1 style="color: #dc2626;">Authentication Error</h1>
|
|
97
|
-
<p style="color: #4b5563;">${message}</p>
|
|
98
|
-
<p style="color: #6b7280;">Please return to the terminal and try again.</p>
|
|
99
|
-
</div>
|
|
100
|
-
</body>
|
|
101
|
-
</html>`;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Start a temporary localhost server and wait for the auth callback.
|
|
105
|
-
* Returns the received token and user info.
|
|
106
|
-
*/
|
|
107
|
-
function waitForCallback(port) {
|
|
108
|
-
return new Promise((resolve, reject) => {
|
|
109
|
-
const server = http.createServer((req, res) => {
|
|
110
|
-
const url = new URL(req.url ?? '/', `http://127.0.0.1:${port}`);
|
|
111
|
-
if (url.pathname === '/callback') {
|
|
112
|
-
const token = url.searchParams.get('token');
|
|
113
|
-
const userId = url.searchParams.get('user_id');
|
|
114
|
-
const email = url.searchParams.get('email') ?? undefined;
|
|
115
|
-
const expiresAt = url.searchParams.get('expires_at') ?? undefined;
|
|
116
|
-
const error = url.searchParams.get('error');
|
|
117
|
-
if (error) {
|
|
118
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
119
|
-
res.end(errorHtml(error));
|
|
120
|
-
server.close();
|
|
121
|
-
reject(new Error(error));
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
if (!token || !userId) {
|
|
125
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
126
|
-
res.end(errorHtml('Missing token or user ID in callback'));
|
|
127
|
-
server.close();
|
|
128
|
-
reject(new Error('Invalid callback: missing token or user_id'));
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
132
|
-
res.end(successHtml());
|
|
133
|
-
// Close the server after sending the response
|
|
134
|
-
server.close();
|
|
135
|
-
resolve({ token, userId, email, expiresAt });
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
139
|
-
res.end('Not Found');
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
server.listen(port, '127.0.0.1', () => {
|
|
143
|
-
// Server is ready
|
|
144
|
-
});
|
|
145
|
-
// Timeout
|
|
146
|
-
const timeout = setTimeout(() => {
|
|
147
|
-
server.close();
|
|
148
|
-
reject(new Error('Login timed out. Please try again.'));
|
|
149
|
-
}, LOGIN_TIMEOUT_MS);
|
|
150
|
-
server.on('close', () => {
|
|
151
|
-
clearTimeout(timeout);
|
|
152
|
-
});
|
|
153
|
-
server.on('error', (err) => {
|
|
154
|
-
clearTimeout(timeout);
|
|
155
|
-
reject(err);
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Register the "hq auth" command group with login, logout, and status subcommands.
|
|
161
|
-
*/
|
|
162
|
-
export function registerAuthCommand(program) {
|
|
41
|
+
export function registerAuthCommands(program) {
|
|
163
42
|
const authCmd = program
|
|
164
|
-
.command(
|
|
165
|
-
.description(
|
|
166
|
-
// --- hq auth login ---
|
|
43
|
+
.command("auth")
|
|
44
|
+
.description("Manage the local HQ Cognito session");
|
|
167
45
|
authCmd
|
|
168
|
-
.command(
|
|
169
|
-
.description(
|
|
46
|
+
.command("login")
|
|
47
|
+
.description("Sign in to HQ — opens the Cognito Hosted UI and caches tokens locally")
|
|
170
48
|
.action(async () => {
|
|
49
|
+
const existing = loadCachedTokens();
|
|
50
|
+
if (existing && !isExpiring(existing, 120)) {
|
|
51
|
+
const who = peekIdToken(existing.idToken).email ?? "cached session";
|
|
52
|
+
console.log(chalk.green(`Already signed in (${who}). Run \`hq auth logout\` to switch accounts.`));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
171
55
|
try {
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
console.log(chalk.yellow(`Already logged in as ${label}.`));
|
|
177
|
-
console.log('Run "hq auth logout" first to switch accounts.');
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
// Generate a device code for the login session
|
|
181
|
-
const deviceCode = crypto.randomBytes(16).toString('hex');
|
|
182
|
-
// Find an available port for the callback
|
|
183
|
-
const port = await findAvailablePort();
|
|
184
|
-
const callbackUrl = `http://127.0.0.1:${port}/callback`;
|
|
185
|
-
// Build the login URL — go directly to the web app's CLI callback page
|
|
186
|
-
const webAppUrl = 'https://app.hq.getindigo.ai';
|
|
187
|
-
const loginUrl = `${webAppUrl}/cli-callback?device_code=${deviceCode}&callback_url=${encodeURIComponent(callbackUrl)}`;
|
|
188
|
-
console.log(chalk.blue('Opening browser for authentication...'));
|
|
189
|
-
console.log();
|
|
190
|
-
console.log(`If the browser does not open, visit this URL:`);
|
|
191
|
-
console.log(chalk.underline(loginUrl));
|
|
192
|
-
console.log();
|
|
193
|
-
console.log(chalk.dim('Waiting for authentication (timeout: 5 minutes)...'));
|
|
194
|
-
// Open browser
|
|
195
|
-
await openBrowser(loginUrl);
|
|
196
|
-
// Wait for callback
|
|
197
|
-
const result = await waitForCallback(port);
|
|
198
|
-
// Store credentials
|
|
199
|
-
writeCredentials({
|
|
200
|
-
token: result.token,
|
|
201
|
-
userId: result.userId,
|
|
202
|
-
email: result.email,
|
|
203
|
-
storedAt: new Date().toISOString(),
|
|
204
|
-
expiresAt: result.expiresAt,
|
|
205
|
-
});
|
|
206
|
-
const label = result.email ?? result.userId;
|
|
207
|
-
console.log();
|
|
208
|
-
console.log(chalk.green(`Logged in as ${label}`));
|
|
209
|
-
console.log(chalk.dim(`Credentials saved.`));
|
|
56
|
+
const tokens = await browserLogin(DEFAULT_COGNITO);
|
|
57
|
+
const who = peekIdToken(tokens.idToken).email ?? "HQ";
|
|
58
|
+
console.log(chalk.green(`Signed in as ${who}`));
|
|
59
|
+
console.log(chalk.dim(` Token cached at ~/.hq/cognito-tokens.json (expires ${tokens.expiresAt})`));
|
|
210
60
|
}
|
|
211
|
-
catch (
|
|
212
|
-
|
|
61
|
+
catch (err) {
|
|
62
|
+
const msg = err instanceof CognitoAuthError
|
|
63
|
+
? err.message
|
|
64
|
+
: err instanceof Error
|
|
65
|
+
? err.message
|
|
66
|
+
: String(err);
|
|
67
|
+
console.error(chalk.red(`Login failed: ${msg}`));
|
|
68
|
+
console.error(chalk.dim(" If you do not have an account, sign up at https://onboarding.indigo-hq.com"));
|
|
213
69
|
process.exit(1);
|
|
214
70
|
}
|
|
215
71
|
});
|
|
216
|
-
// --- hq auth logout ---
|
|
217
72
|
authCmd
|
|
218
|
-
.command(
|
|
219
|
-
.description(
|
|
73
|
+
.command("logout")
|
|
74
|
+
.description("Clear the cached HQ Cognito session")
|
|
220
75
|
.action(() => {
|
|
221
|
-
const
|
|
222
|
-
if (
|
|
223
|
-
console.log(chalk.
|
|
224
|
-
|
|
225
|
-
else {
|
|
226
|
-
console.log(chalk.yellow('Not logged in.'));
|
|
76
|
+
const existing = loadCachedTokens();
|
|
77
|
+
if (!existing) {
|
|
78
|
+
console.log(chalk.yellow("No cached HQ session"));
|
|
79
|
+
return;
|
|
227
80
|
}
|
|
81
|
+
clearCachedTokens();
|
|
82
|
+
console.log(chalk.green("Signed out — removed ~/.hq/cognito-tokens.json"));
|
|
228
83
|
});
|
|
229
|
-
// --- hq auth status ---
|
|
230
84
|
authCmd
|
|
231
|
-
.command(
|
|
232
|
-
.description(
|
|
85
|
+
.command("refresh")
|
|
86
|
+
.description("Refresh the cached Cognito session using the stored refresh token")
|
|
233
87
|
.action(async () => {
|
|
234
|
-
const
|
|
235
|
-
if (
|
|
236
|
-
console.log(chalk.
|
|
237
|
-
console.log('Run "hq auth login" to authenticate.');
|
|
88
|
+
const result = await refreshCachedSession();
|
|
89
|
+
if (result.refreshed) {
|
|
90
|
+
console.log(chalk.green("HQ session refreshed"));
|
|
238
91
|
return;
|
|
239
92
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
console.log(` API URL: ${getApiUrl()}`);
|
|
253
|
-
// Optionally verify with the API
|
|
254
|
-
try {
|
|
255
|
-
const resp = await apiRequest('GET', '/api/auth/me');
|
|
256
|
-
if (resp.ok && resp.data) {
|
|
257
|
-
console.log(chalk.dim(` Verified: API confirms session is valid`));
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
console.log(chalk.yellow(` Warning: API returned ${resp.status} — token may be invalid`));
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
catch {
|
|
264
|
-
console.log(chalk.dim(` Note: Could not reach API to verify token`));
|
|
93
|
+
console.error(chalk.yellow(`No refresh: ${result.reason ?? "unknown"}`));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
});
|
|
96
|
+
authCmd
|
|
97
|
+
.command("status")
|
|
98
|
+
.description("Show whether a valid HQ session is cached")
|
|
99
|
+
.action(() => {
|
|
100
|
+
const cached = loadCachedTokens();
|
|
101
|
+
if (!cached) {
|
|
102
|
+
console.log(chalk.yellow("No cached HQ session — run `hq auth login`"));
|
|
103
|
+
process.exit(1);
|
|
265
104
|
}
|
|
105
|
+
const who = peekIdToken(cached.idToken).email;
|
|
106
|
+
const expiring = isExpiring(cached);
|
|
107
|
+
const label = who ? `${who} — ` : "";
|
|
108
|
+
console.log(expiring
|
|
109
|
+
? chalk.yellow(`${label}HQ session cached but expiring (expiresAt=${cached.expiresAt})`)
|
|
110
|
+
: chalk.green(`${label}HQ session valid (expiresAt=${cached.expiresAt})`));
|
|
266
111
|
});
|
|
267
112
|
}
|
|
268
113
|
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/cloud.d.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hq sync commands — cloud sync management
|
|
3
|
-
*
|
|
4
|
-
* All sync operations go through the hq-cloud API (authenticated with Clerk
|
|
5
|
-
* tokens from US-002). No AWS credentials or direct S3 access needed.
|
|
6
|
-
*
|
|
7
|
-
* Commands:
|
|
8
|
-
* hq sync push — Upload changed local files to cloud
|
|
9
|
-
* hq sync pull — Download changed cloud files to local
|
|
10
|
-
* hq sync start — Begin background auto-sync watcher
|
|
11
|
-
* hq sync stop — Halt the background watcher
|
|
12
|
-
* hq sync status — Show sync state, last sync time, file counts
|
|
2
|
+
* hq sync commands — cloud sync management
|
|
3
|
+
* Bridges hq-cli to @indigoai-us/hq-cloud
|
|
13
4
|
*/
|
|
14
|
-
import { Command } from
|
|
5
|
+
import { Command } from "commander";
|
|
15
6
|
export declare function registerCloudCommands(program: Command): void;
|
|
16
7
|
//# sourceMappingURL=cloud.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/commands/cloud.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/commands/cloud.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoH5D"}
|