@hyperstar/mcp 0.1.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/README.md +186 -0
- package/dist/auth/cli-auth-client.d.ts +48 -0
- package/dist/auth/cli-auth-client.js +214 -0
- package/dist/auth/cli-auth-client.js.map +1 -0
- package/dist/auth/cli-auth-state.d.ts +26 -0
- package/dist/auth/cli-auth-state.js +176 -0
- package/dist/auth/cli-auth-state.js.map +1 -0
- package/dist/auth/local-callback.d.ts +18 -0
- package/dist/auth/local-callback.js +90 -0
- package/dist/auth/local-callback.js.map +1 -0
- package/dist/auth/pkce.d.ts +8 -0
- package/dist/auth/pkce.js +14 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/cli.d.ts +18 -0
- package/dist/cli.js +326 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.js +101 -0
- package/dist/config.js.map +1 -0
- package/dist/http.d.ts +24 -0
- package/dist/http.js +131 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas.d.ts +61 -0
- package/dist/schemas.js +57 -0
- package/dist/schemas.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +12 -0
- package/dist/server.js.map +1 -0
- package/dist/tool-inputs.d.ts +254 -0
- package/dist/tool-inputs.js +239 -0
- package/dist/tool-inputs.js.map +1 -0
- package/dist/tool-result.d.ts +4 -0
- package/dist/tool-result.js +23 -0
- package/dist/tool-result.js.map +1 -0
- package/dist/tools.d.ts +8 -0
- package/dist/tools.js +259 -0
- package/dist/tools.js.map +1 -0
- package/dist/workspaces.d.ts +11 -0
- package/dist/workspaces.js +77 -0
- package/dist/workspaces.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type LocalCallbackResult = {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly state: string;
|
|
4
|
+
} | {
|
|
5
|
+
readonly error: string;
|
|
6
|
+
readonly state?: string;
|
|
7
|
+
};
|
|
8
|
+
export type LocalCallbackServer = {
|
|
9
|
+
readonly callbackUrl: string;
|
|
10
|
+
readonly result: Promise<LocalCallbackResult>;
|
|
11
|
+
readonly close: () => Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
export type LocalCallbackOptions = {
|
|
14
|
+
readonly expectedState: string;
|
|
15
|
+
readonly timeoutMs?: number;
|
|
16
|
+
};
|
|
17
|
+
/** Start a one-shot OAuth callback server bound to 127.0.0.1. */
|
|
18
|
+
export declare function startLocalCallbackServer(options: LocalCallbackOptions): Promise<LocalCallbackServer>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
/** Start a one-shot OAuth callback server bound to 127.0.0.1. */
|
|
3
|
+
export async function startLocalCallbackServer(options) {
|
|
4
|
+
let settle;
|
|
5
|
+
const result = new Promise((resolve) => {
|
|
6
|
+
settle = resolve;
|
|
7
|
+
});
|
|
8
|
+
const timeoutMs = options.timeoutMs ?? 120_000;
|
|
9
|
+
let settled = false;
|
|
10
|
+
const server = createServer((request, response) => {
|
|
11
|
+
const requestUrl = new URL(request.url ?? "/", "http://127.0.0.1");
|
|
12
|
+
if (requestUrl.pathname !== "/callback") {
|
|
13
|
+
response.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
14
|
+
response.end("Not found");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const state = requestUrl.searchParams.get("state") ?? undefined;
|
|
18
|
+
const code = requestUrl.searchParams.get("code") ?? undefined;
|
|
19
|
+
const error = requestUrl.searchParams.get("error") ?? undefined;
|
|
20
|
+
if (state !== options.expectedState) {
|
|
21
|
+
response.writeHead(400, { "content-type": "text/plain; charset=utf-8" });
|
|
22
|
+
response.end("Invalid state");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (error !== undefined && error.length > 0) {
|
|
26
|
+
response.writeHead(400, { "content-type": "text/plain; charset=utf-8" });
|
|
27
|
+
response.end("Authorization failed");
|
|
28
|
+
finish({ error, state });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (code === undefined || code.length === 0) {
|
|
32
|
+
response.writeHead(400, { "content-type": "text/plain; charset=utf-8" });
|
|
33
|
+
response.end("Missing code");
|
|
34
|
+
finish({ error: "missing_code", state });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
response.writeHead(200, { "content-type": "text/plain; charset=utf-8" });
|
|
38
|
+
response.end("Hyperstar login complete. You can close this window.");
|
|
39
|
+
finish({ code, state });
|
|
40
|
+
});
|
|
41
|
+
const close = async () => closeServer(server);
|
|
42
|
+
const timeout = setTimeout(() => {
|
|
43
|
+
finish({ error: "timeout" });
|
|
44
|
+
}, timeoutMs);
|
|
45
|
+
timeout.unref();
|
|
46
|
+
/** Resolve once and close the one-shot callback server. */
|
|
47
|
+
function finish(callbackResult) {
|
|
48
|
+
if (settled) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
settled = true;
|
|
52
|
+
clearTimeout(timeout);
|
|
53
|
+
settle(callbackResult);
|
|
54
|
+
void close();
|
|
55
|
+
}
|
|
56
|
+
await new Promise((resolve, reject) => {
|
|
57
|
+
server.once("error", reject);
|
|
58
|
+
server.listen(0, "127.0.0.1", () => {
|
|
59
|
+
server.off("error", reject);
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
const address = server.address();
|
|
64
|
+
if (address === null || typeof address === "string") {
|
|
65
|
+
await close();
|
|
66
|
+
throw new Error("Failed to bind local callback server");
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
callbackUrl: `http://127.0.0.1:${address.port}/callback`,
|
|
70
|
+
result,
|
|
71
|
+
close,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** Close a Node HTTP server if it is still listening. */
|
|
75
|
+
async function closeServer(server) {
|
|
76
|
+
if (!server.listening) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
await new Promise((resolve, reject) => {
|
|
80
|
+
server.close((error) => {
|
|
81
|
+
if (error === undefined) {
|
|
82
|
+
resolve();
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
reject(error);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=local-callback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-callback.js","sourceRoot":"","sources":["../../src/auth/local-callback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type PkcePair = {
|
|
2
|
+
readonly verifier: string;
|
|
3
|
+
readonly challenge: string;
|
|
4
|
+
};
|
|
5
|
+
/** Create a URL-safe PKCE verifier and its S256 challenge. */
|
|
6
|
+
export declare function createPkcePair(): PkcePair;
|
|
7
|
+
/** Create a URL-safe OAuth state value. */
|
|
8
|
+
export declare function createState(): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
/** Create a URL-safe PKCE verifier and its S256 challenge. */
|
|
3
|
+
export function createPkcePair() {
|
|
4
|
+
const verifier = randomBytes(64).toString("base64url");
|
|
5
|
+
const challenge = createHash("sha256")
|
|
6
|
+
.update(verifier, "ascii")
|
|
7
|
+
.digest("base64url");
|
|
8
|
+
return { verifier, challenge };
|
|
9
|
+
}
|
|
10
|
+
/** Create a URL-safe OAuth state value. */
|
|
11
|
+
export function createState() {
|
|
12
|
+
return randomBytes(32).toString("base64url");
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=pkce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAOtD,8DAA8D;AAC9D,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC;SACnC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC;SACzB,MAAM,CAAC,WAAW,CAAC,CAAC;IACvB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type Fetcher } from "./auth/cli-auth-client.js";
|
|
3
|
+
import { type CliAuthStateStore } from "./auth/cli-auth-state.js";
|
|
4
|
+
import { type LocalCallbackOptions, type LocalCallbackServer } from "./auth/local-callback.js";
|
|
5
|
+
export type CliDependencies = {
|
|
6
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
7
|
+
readonly fetcher?: Fetcher | undefined;
|
|
8
|
+
readonly openBrowser?: (url: URL) => Promise<void>;
|
|
9
|
+
readonly startCallback?: (options: LocalCallbackOptions) => Promise<LocalCallbackServer>;
|
|
10
|
+
readonly stateStore?: CliAuthStateStore;
|
|
11
|
+
readonly stdout?: (line: string) => void;
|
|
12
|
+
readonly stderr?: (line: string) => void;
|
|
13
|
+
readonly now?: (() => Date) | undefined;
|
|
14
|
+
};
|
|
15
|
+
/** Return whether a module URL is the process entrypoint, following npm bin symlinks. */
|
|
16
|
+
export declare function isDirectCliInvocation(moduleUrl: string, argvPath: string | undefined, resolveRealpath?: (path: string) => string): boolean;
|
|
17
|
+
/** Run the Hyperstar CLI with injectable process boundaries for tests. */
|
|
18
|
+
export declare function runCli(argv?: readonly string[], dependencies?: CliDependencies): Promise<number>;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { realpathSync } from "node:fs";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { createCliAuthClient, createStoredCliAccessTokenProvider, tokenPairToAuthState, } from "./auth/cli-auth-client.js";
|
|
7
|
+
import { createFileCliAuthStateStore, } from "./auth/cli-auth-state.js";
|
|
8
|
+
import { startLocalCallbackServer, } from "./auth/local-callback.js";
|
|
9
|
+
import { createPkcePair, createState } from "./auth/pkce.js";
|
|
10
|
+
import { DEFAULT_API_BASE_URL, DEFAULT_APP_BASE_URL, createCliWorkspaceSelection, normalizeBaseUrl, } from "./config.js";
|
|
11
|
+
import { createHyperstarClient } from "./http.js";
|
|
12
|
+
const CLI_USAGE = [
|
|
13
|
+
"Usage: hyperstar <command> [options]",
|
|
14
|
+
"",
|
|
15
|
+
"Commands:",
|
|
16
|
+
" login Open browser login and save local CLI auth",
|
|
17
|
+
" logout Revoke and clear local CLI auth",
|
|
18
|
+
" whoami [--json] Print the authenticated principal",
|
|
19
|
+
" workspaces list [--json] List accessible workspaces",
|
|
20
|
+
" workspaces use <workspace_id> Select a workspace for Product API calls",
|
|
21
|
+
"",
|
|
22
|
+
"Options:",
|
|
23
|
+
" --json Print supported command output as JSON",
|
|
24
|
+
" --help Show this help",
|
|
25
|
+
].join("\n");
|
|
26
|
+
/** Return whether a module URL is the process entrypoint, following npm bin symlinks. */
|
|
27
|
+
export function isDirectCliInvocation(moduleUrl, argvPath, resolveRealpath = realpathSync) {
|
|
28
|
+
if (argvPath === undefined) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return (resolveRealpath(fileURLToPath(moduleUrl)) === resolveRealpath(argvPath));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Run the Hyperstar CLI with injectable process boundaries for tests. */
|
|
39
|
+
export async function runCli(argv = process.argv.slice(2), dependencies = {}) {
|
|
40
|
+
const stdout = dependencies.stdout ?? ((line) => process.stdout.write(`${line}\n`));
|
|
41
|
+
const stderr = dependencies.stderr ?? ((line) => process.stderr.write(`${line}\n`));
|
|
42
|
+
try {
|
|
43
|
+
const command = parseCommand(argv);
|
|
44
|
+
if (command.help) {
|
|
45
|
+
stdout(CLI_USAGE);
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
const env = dependencies.env ?? process.env;
|
|
49
|
+
const store = dependencies.stateStore ?? createFileCliAuthStateStore({ env });
|
|
50
|
+
const fetcher = dependencies.fetcher;
|
|
51
|
+
if (command.positionals[0] === "login") {
|
|
52
|
+
await login({ env, store, fetcher, stdout, dependencies });
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
if (command.positionals[0] === "logout") {
|
|
56
|
+
await logout({ store, fetcher, stdout });
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
if (command.positionals[0] === "whoami") {
|
|
60
|
+
await whoami({
|
|
61
|
+
store,
|
|
62
|
+
fetcher,
|
|
63
|
+
stdout,
|
|
64
|
+
json: command.json,
|
|
65
|
+
now: dependencies.now,
|
|
66
|
+
});
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
if (command.positionals[0] === "workspaces" &&
|
|
70
|
+
command.positionals[1] === "list") {
|
|
71
|
+
await listWorkspaces({
|
|
72
|
+
store,
|
|
73
|
+
fetcher,
|
|
74
|
+
stdout,
|
|
75
|
+
json: command.json,
|
|
76
|
+
now: dependencies.now,
|
|
77
|
+
});
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
if (command.positionals[0] === "workspaces" &&
|
|
81
|
+
command.positionals[1] === "use") {
|
|
82
|
+
await useWorkspace({
|
|
83
|
+
store,
|
|
84
|
+
fetcher,
|
|
85
|
+
stdout,
|
|
86
|
+
workspaceId: command.positionals[2],
|
|
87
|
+
now: dependencies.now,
|
|
88
|
+
});
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
stderr(CLI_USAGE);
|
|
92
|
+
return 2;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
stderr(error instanceof Error ? error.message : String(error));
|
|
96
|
+
return 1;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** Parse CLI arguments using Node's standard parser. */
|
|
100
|
+
function parseCommand(argv) {
|
|
101
|
+
const parsed = parseArgs({
|
|
102
|
+
args: [...argv],
|
|
103
|
+
allowPositionals: true,
|
|
104
|
+
options: {
|
|
105
|
+
json: { type: "boolean", default: false },
|
|
106
|
+
help: { type: "boolean", default: false },
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
positionals: parsed.positionals,
|
|
111
|
+
json: parsed.values.json ?? false,
|
|
112
|
+
help: parsed.values.help ?? false,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** Complete browser-based local login and persist token state. */
|
|
116
|
+
async function login(options) {
|
|
117
|
+
const apiBaseUrl = resolveEnvBaseUrl(options.env.HYPERSTAR_API_BASE_URL, DEFAULT_API_BASE_URL, "HYPERSTAR_API_BASE_URL");
|
|
118
|
+
const appBaseUrl = resolveLoginAppBaseUrl(options.env, apiBaseUrl);
|
|
119
|
+
const pkce = createPkcePair();
|
|
120
|
+
const state = createState();
|
|
121
|
+
const startCallback = options.dependencies.startCallback ?? startLocalCallbackServer;
|
|
122
|
+
const callback = await startCallback({ expectedState: state });
|
|
123
|
+
try {
|
|
124
|
+
const client = createCliAuthClient({
|
|
125
|
+
apiBaseUrl,
|
|
126
|
+
appBaseUrl,
|
|
127
|
+
fetcher: options.fetcher,
|
|
128
|
+
});
|
|
129
|
+
const authorizeUrl = client.buildAuthorizeUrl(callback.callbackUrl, pkce, state);
|
|
130
|
+
options.stdout(`Open this URL to authorize Hyperstar CLI: ${authorizeUrl.toString()}`);
|
|
131
|
+
try {
|
|
132
|
+
await (options.dependencies.openBrowser ?? openBrowser)(authorizeUrl);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
void error;
|
|
136
|
+
options.stdout("Could not open your browser automatically. Copy the URL above into your browser.");
|
|
137
|
+
}
|
|
138
|
+
const callbackResult = await callback.result;
|
|
139
|
+
if ("error" in callbackResult) {
|
|
140
|
+
throw new Error(`Hyperstar login failed: ${callbackResult.error}`);
|
|
141
|
+
}
|
|
142
|
+
const tokenPair = await client.exchangeCode(callbackResult.code, pkce.verifier, callback.callbackUrl);
|
|
143
|
+
await options.store.withExclusiveLock(async () => {
|
|
144
|
+
await options.store.write(tokenPairToAuthState(tokenPair, {
|
|
145
|
+
apiBaseUrl,
|
|
146
|
+
appBaseUrl,
|
|
147
|
+
previousState: await options.store.read(),
|
|
148
|
+
}));
|
|
149
|
+
});
|
|
150
|
+
options.stdout("Logged in to Hyperstar.");
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
await callback.close();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Log out remotely when possible and remove local auth state. */
|
|
157
|
+
async function logout(options) {
|
|
158
|
+
await options.store.withExclusiveLock(async () => {
|
|
159
|
+
const state = await options.store.read();
|
|
160
|
+
if (state !== null) {
|
|
161
|
+
const client = createCliAuthClient({
|
|
162
|
+
apiBaseUrl: state.apiBaseUrl,
|
|
163
|
+
appBaseUrl: state.appBaseUrl,
|
|
164
|
+
fetcher: options.fetcher,
|
|
165
|
+
});
|
|
166
|
+
try {
|
|
167
|
+
await client.logout(state.refreshToken);
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
await options.store.clear();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
await options.store.clear();
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
options.stdout("Logged out of Hyperstar.");
|
|
178
|
+
}
|
|
179
|
+
/** Print the authenticated principal from the Product API. */
|
|
180
|
+
async function whoami(options) {
|
|
181
|
+
const client = await createCliProductClient(options);
|
|
182
|
+
const payload = await client.get("/v1/whoami");
|
|
183
|
+
printPayload(payload, options.json, options.stdout);
|
|
184
|
+
}
|
|
185
|
+
/** List workspaces available to the logged-in CLI user. */
|
|
186
|
+
async function listWorkspaces(options) {
|
|
187
|
+
const { authClient, accessToken } = await createWorkspaceClient(options);
|
|
188
|
+
const payload = await authClient.listWorkspaces(accessToken);
|
|
189
|
+
if (options.json) {
|
|
190
|
+
options.stdout(JSON.stringify(payload, null, 2));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
for (const workspace of payload.workspaces) {
|
|
194
|
+
options.stdout(`${workspace.organization_id}${workspace.name === undefined ? "" : `\t${workspace.name}`}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** Persist the selected workspace after verifying it is accessible. */
|
|
198
|
+
async function useWorkspace(options) {
|
|
199
|
+
if (options.workspaceId === undefined || options.workspaceId.length === 0) {
|
|
200
|
+
throw new Error("Workspace id is required");
|
|
201
|
+
}
|
|
202
|
+
const { authClient, accessToken } = await createWorkspaceClient(options);
|
|
203
|
+
const payload = await authClient.listWorkspaces(accessToken);
|
|
204
|
+
if (!payload.workspaces.some((workspace) => workspace.organization_id === options.workspaceId)) {
|
|
205
|
+
throw new Error(`Workspace ${options.workspaceId} is not available`);
|
|
206
|
+
}
|
|
207
|
+
await createCliWorkspaceSelection(options.store).setSelectedOrganizationId(options.workspaceId);
|
|
208
|
+
options.stdout(`Selected workspace ${options.workspaceId}.`);
|
|
209
|
+
}
|
|
210
|
+
/** Build an HTTP client authenticated from persisted CLI state. */
|
|
211
|
+
async function createCliProductClient(options) {
|
|
212
|
+
const state = await requireAuthState(options.store);
|
|
213
|
+
const authClient = createCliAuthClient({
|
|
214
|
+
apiBaseUrl: state.apiBaseUrl,
|
|
215
|
+
appBaseUrl: state.appBaseUrl,
|
|
216
|
+
fetcher: options.fetcher,
|
|
217
|
+
});
|
|
218
|
+
const accessTokenProvider = createStoredCliAccessTokenProvider({
|
|
219
|
+
store: options.store,
|
|
220
|
+
client: authClient,
|
|
221
|
+
now: options.now,
|
|
222
|
+
});
|
|
223
|
+
return createHyperstarClient({
|
|
224
|
+
config: {
|
|
225
|
+
authMode: "cli",
|
|
226
|
+
apiBaseUrl: state.apiBaseUrl,
|
|
227
|
+
appBaseUrl: state.appBaseUrl,
|
|
228
|
+
accessTokenProvider,
|
|
229
|
+
workspaceSelection: createCliWorkspaceSelection(options.store),
|
|
230
|
+
},
|
|
231
|
+
fetcher: options.fetcher,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/** Build workspace-listing dependencies from persisted CLI state. */
|
|
235
|
+
async function createWorkspaceClient(options) {
|
|
236
|
+
const state = await requireAuthState(options.store);
|
|
237
|
+
const authClient = createCliAuthClient({
|
|
238
|
+
apiBaseUrl: state.apiBaseUrl,
|
|
239
|
+
appBaseUrl: state.appBaseUrl,
|
|
240
|
+
fetcher: options.fetcher,
|
|
241
|
+
});
|
|
242
|
+
const provider = createStoredCliAccessTokenProvider({
|
|
243
|
+
store: options.store,
|
|
244
|
+
client: authClient,
|
|
245
|
+
now: options.now,
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
state,
|
|
249
|
+
authClient,
|
|
250
|
+
accessToken: await provider.getAccessToken(),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/** Require local CLI auth state or explain how to create it. */
|
|
254
|
+
async function requireAuthState(store) {
|
|
255
|
+
const state = await store.read();
|
|
256
|
+
if (state === null) {
|
|
257
|
+
throw new Error("Run `hyperstar login` or set HYPERSTAR_API_KEY");
|
|
258
|
+
}
|
|
259
|
+
return state;
|
|
260
|
+
}
|
|
261
|
+
/** Print structured payloads as JSON or a compact human string. */
|
|
262
|
+
function printPayload(payload, json, stdout) {
|
|
263
|
+
if (json || typeof payload !== "object" || payload === null) {
|
|
264
|
+
stdout(JSON.stringify(payload, null, 2));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
stdout(JSON.stringify(payload));
|
|
268
|
+
}
|
|
269
|
+
/** Resolve and normalize an optional base URL env value. */
|
|
270
|
+
function resolveEnvBaseUrl(rawValue, fallback, envName) {
|
|
271
|
+
const value = rawValue?.trim();
|
|
272
|
+
return normalizeBaseUrl(value === undefined || value.length === 0 ? fallback : value, envName);
|
|
273
|
+
}
|
|
274
|
+
/** Resolve the browser app URL used by login so auth and token exchange match. */
|
|
275
|
+
function resolveLoginAppBaseUrl(env, apiBaseUrl) {
|
|
276
|
+
if (env.HYPERSTAR_APP_BASE_URL !== undefined) {
|
|
277
|
+
return resolveEnvBaseUrl(env.HYPERSTAR_APP_BASE_URL, DEFAULT_APP_BASE_URL, "HYPERSTAR_APP_BASE_URL");
|
|
278
|
+
}
|
|
279
|
+
return appBaseUrlForApiBaseUrl(apiBaseUrl);
|
|
280
|
+
}
|
|
281
|
+
/** Map known deployed Product API origins to their matching frontend origins. */
|
|
282
|
+
function appBaseUrlForApiBaseUrl(apiBaseUrl) {
|
|
283
|
+
const origin = new URL(apiBaseUrl).origin;
|
|
284
|
+
if (origin === "https://autopilot.dev.hyper-star.org") {
|
|
285
|
+
return "https://app.dev.hyper-star.org";
|
|
286
|
+
}
|
|
287
|
+
if (origin === "https://autopilot.hyper-star.org") {
|
|
288
|
+
return DEFAULT_APP_BASE_URL;
|
|
289
|
+
}
|
|
290
|
+
if (origin === DEFAULT_API_BASE_URL) {
|
|
291
|
+
return DEFAULT_APP_BASE_URL;
|
|
292
|
+
}
|
|
293
|
+
throw new Error("Set HYPERSTAR_APP_BASE_URL when HYPERSTAR_API_BASE_URL does not use a known Hyperstar API origin");
|
|
294
|
+
}
|
|
295
|
+
/** Open the system browser for the authorization request. */
|
|
296
|
+
async function openBrowser(url) {
|
|
297
|
+
const command = process.platform === "darwin"
|
|
298
|
+
? "open"
|
|
299
|
+
: process.platform === "win32"
|
|
300
|
+
? "cmd"
|
|
301
|
+
: "xdg-open";
|
|
302
|
+
const args = process.platform === "win32"
|
|
303
|
+
? ["/c", "start", "", url.toString()]
|
|
304
|
+
: [url.toString()];
|
|
305
|
+
await new Promise((resolve) => {
|
|
306
|
+
try {
|
|
307
|
+
const child = spawn(command, args, {
|
|
308
|
+
detached: true,
|
|
309
|
+
stdio: "ignore",
|
|
310
|
+
});
|
|
311
|
+
child.once("error", () => resolve());
|
|
312
|
+
child.once("spawn", () => resolve());
|
|
313
|
+
child.unref();
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
void error;
|
|
317
|
+
resolve();
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
if (isDirectCliInvocation(import.meta.url, process.argv[1])) {
|
|
322
|
+
void runCli().then((exitCode) => {
|
|
323
|
+
process.exitCode = exitCode;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type CliAccessTokenProvider, type Fetcher } from "./auth/cli-auth-client.js";
|
|
2
|
+
import { type CliAuthStateStore } from "./auth/cli-auth-state.js";
|
|
3
|
+
export type ServiceAccountConfig = {
|
|
4
|
+
readonly authMode: "service_account";
|
|
5
|
+
readonly apiBaseUrl: string;
|
|
6
|
+
readonly apiKey: string;
|
|
7
|
+
};
|
|
8
|
+
export type CliConfig = {
|
|
9
|
+
readonly authMode: "cli";
|
|
10
|
+
readonly apiBaseUrl: string;
|
|
11
|
+
readonly appBaseUrl: string;
|
|
12
|
+
readonly accessTokenProvider: CliAccessTokenProvider;
|
|
13
|
+
readonly workspaceSelection: CliWorkspaceSelection;
|
|
14
|
+
};
|
|
15
|
+
export type HyperstarMcpConfig = ServiceAccountConfig | CliConfig;
|
|
16
|
+
export type Env = Readonly<Record<string, string | undefined>>;
|
|
17
|
+
export type CliWorkspaceSelection = {
|
|
18
|
+
readonly getSelectedOrganizationId: () => Promise<string | undefined>;
|
|
19
|
+
readonly setSelectedOrganizationId: (organizationId: string) => Promise<void>;
|
|
20
|
+
};
|
|
21
|
+
export declare const DEFAULT_API_BASE_URL = "https://autopilot.hyper-star.org";
|
|
22
|
+
export declare const DEFAULT_APP_BASE_URL = "https://app.hyper-star.org";
|
|
23
|
+
export type LoadConfigOptions = {
|
|
24
|
+
readonly env?: Env;
|
|
25
|
+
readonly fetcher?: Fetcher | undefined;
|
|
26
|
+
readonly now?: (() => Date) | undefined;
|
|
27
|
+
};
|
|
28
|
+
/** Load MCP configuration from env or persisted CLI auth state. */
|
|
29
|
+
export declare function loadConfig(options?: Env | LoadConfigOptions): HyperstarMcpConfig;
|
|
30
|
+
/** Create the local CLI workspace-selection port backed by auth state. */
|
|
31
|
+
export declare function createCliWorkspaceSelection(store: CliAuthStateStore): CliWorkspaceSelection;
|
|
32
|
+
/** Redact an API key or bearer token for error messages. */
|
|
33
|
+
export declare function redactSecret(value: string): string;
|
|
34
|
+
/** Normalize an env-provided base URL. */
|
|
35
|
+
export declare function normalizeBaseUrl(rawBaseUrl: string, envName: string): string;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { createCliAuthClient, createStoredCliAccessTokenProvider, } from "./auth/cli-auth-client.js";
|
|
2
|
+
import { createFileCliAuthStateStore, } from "./auth/cli-auth-state.js";
|
|
3
|
+
export const DEFAULT_API_BASE_URL = "https://autopilot.hyper-star.org";
|
|
4
|
+
export const DEFAULT_APP_BASE_URL = "https://app.hyper-star.org";
|
|
5
|
+
/** Load MCP configuration from env or persisted CLI auth state. */
|
|
6
|
+
export function loadConfig(options = process.env) {
|
|
7
|
+
const loadOptions = isLoadConfigOptions(options) ? options : { env: options };
|
|
8
|
+
const env = loadOptions.env ?? process.env;
|
|
9
|
+
const fetcher = loadOptions.fetcher;
|
|
10
|
+
const now = loadOptions.now;
|
|
11
|
+
const apiKey = env.HYPERSTAR_API_KEY?.trim();
|
|
12
|
+
const rawBaseUrl = env.HYPERSTAR_API_BASE_URL?.trim() ?? DEFAULT_API_BASE_URL;
|
|
13
|
+
const apiBaseUrl = normalizeBaseUrl(rawBaseUrl.length === 0 ? DEFAULT_API_BASE_URL : rawBaseUrl, "HYPERSTAR_API_BASE_URL");
|
|
14
|
+
if (apiKey !== undefined && apiKey.length > 0) {
|
|
15
|
+
if (!isValidApiKeyHeaderValue(apiKey)) {
|
|
16
|
+
throw new Error("HYPERSTAR_API_KEY contains unsupported characters");
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
authMode: "service_account",
|
|
20
|
+
apiBaseUrl,
|
|
21
|
+
apiKey,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const store = createFileCliAuthStateStore({ env });
|
|
25
|
+
const state = store.readSync();
|
|
26
|
+
if (state === null) {
|
|
27
|
+
throw new Error("Run `hyperstar login` or set HYPERSTAR_API_KEY");
|
|
28
|
+
}
|
|
29
|
+
const cliApiBaseUrl = normalizeBaseUrl(env.HYPERSTAR_API_BASE_URL?.trim() ?? state.apiBaseUrl, "HYPERSTAR_API_BASE_URL");
|
|
30
|
+
const cliAppBaseUrl = normalizeBaseUrl(env.HYPERSTAR_APP_BASE_URL?.trim() ?? state.appBaseUrl, "HYPERSTAR_APP_BASE_URL");
|
|
31
|
+
const client = createCliAuthClient({
|
|
32
|
+
apiBaseUrl: cliApiBaseUrl,
|
|
33
|
+
appBaseUrl: cliAppBaseUrl,
|
|
34
|
+
fetcher,
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
authMode: "cli",
|
|
38
|
+
apiBaseUrl: cliApiBaseUrl,
|
|
39
|
+
appBaseUrl: cliAppBaseUrl,
|
|
40
|
+
accessTokenProvider: createStoredCliAccessTokenProvider({
|
|
41
|
+
store,
|
|
42
|
+
client,
|
|
43
|
+
now,
|
|
44
|
+
}),
|
|
45
|
+
workspaceSelection: createCliWorkspaceSelection(store),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Create the local CLI workspace-selection port backed by auth state. */
|
|
49
|
+
export function createCliWorkspaceSelection(store) {
|
|
50
|
+
return {
|
|
51
|
+
getSelectedOrganizationId: async () => (await store.read())?.selectedOrganizationId,
|
|
52
|
+
setSelectedOrganizationId: async (organizationId) => {
|
|
53
|
+
await store.withExclusiveLock(async () => {
|
|
54
|
+
const state = await store.read();
|
|
55
|
+
if (state === null) {
|
|
56
|
+
throw new Error("Run `hyperstar login` or set HYPERSTAR_API_KEY");
|
|
57
|
+
}
|
|
58
|
+
await store.write({
|
|
59
|
+
...state,
|
|
60
|
+
selectedOrganizationId: organizationId,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/** Return true when loadConfig received its structured options object. */
|
|
67
|
+
function isLoadConfigOptions(options) {
|
|
68
|
+
return "env" in options || "fetcher" in options || "now" in options;
|
|
69
|
+
}
|
|
70
|
+
/** Redact an API key or bearer token for error messages. */
|
|
71
|
+
export function redactSecret(value) {
|
|
72
|
+
const separatorIndex = value.indexOf(".");
|
|
73
|
+
if (separatorIndex <= 0) {
|
|
74
|
+
return "[redacted]";
|
|
75
|
+
}
|
|
76
|
+
return `${value.slice(0, separatorIndex)}.[redacted]`;
|
|
77
|
+
}
|
|
78
|
+
/** Return true when the key can be safely used as one HTTP header value. */
|
|
79
|
+
function isValidApiKeyHeaderValue(value) {
|
|
80
|
+
return /^[\x21-\x7e]+$/.test(value);
|
|
81
|
+
}
|
|
82
|
+
/** Normalize an env-provided base URL. */
|
|
83
|
+
export function normalizeBaseUrl(rawBaseUrl, envName) {
|
|
84
|
+
let parsed;
|
|
85
|
+
try {
|
|
86
|
+
parsed = new URL(rawBaseUrl);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
throw new Error(`${envName} must be a valid URL`);
|
|
90
|
+
}
|
|
91
|
+
if (parsed.username.length > 0 || parsed.password.length > 0) {
|
|
92
|
+
throw new Error(`${envName} must not include credentials`);
|
|
93
|
+
}
|
|
94
|
+
const isHttps = parsed.protocol === "https:";
|
|
95
|
+
const isLocalhostHttp = parsed.protocol === "http:" && parsed.hostname === "localhost";
|
|
96
|
+
if (!isHttps && !isLocalhostHttp) {
|
|
97
|
+
throw new Error(`${envName} must use HTTPS, except localhost development URLs`);
|
|
98
|
+
}
|
|
99
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|