@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.
Files changed (44) hide show
  1. package/README.md +186 -0
  2. package/dist/auth/cli-auth-client.d.ts +48 -0
  3. package/dist/auth/cli-auth-client.js +214 -0
  4. package/dist/auth/cli-auth-client.js.map +1 -0
  5. package/dist/auth/cli-auth-state.d.ts +26 -0
  6. package/dist/auth/cli-auth-state.js +176 -0
  7. package/dist/auth/cli-auth-state.js.map +1 -0
  8. package/dist/auth/local-callback.d.ts +18 -0
  9. package/dist/auth/local-callback.js +90 -0
  10. package/dist/auth/local-callback.js.map +1 -0
  11. package/dist/auth/pkce.d.ts +8 -0
  12. package/dist/auth/pkce.js +14 -0
  13. package/dist/auth/pkce.js.map +1 -0
  14. package/dist/cli.d.ts +18 -0
  15. package/dist/cli.js +326 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/config.d.ts +35 -0
  18. package/dist/config.js +101 -0
  19. package/dist/config.js.map +1 -0
  20. package/dist/http.d.ts +24 -0
  21. package/dist/http.js +131 -0
  22. package/dist/http.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +16 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/schemas.d.ts +61 -0
  27. package/dist/schemas.js +57 -0
  28. package/dist/schemas.js.map +1 -0
  29. package/dist/server.d.ts +4 -0
  30. package/dist/server.js +12 -0
  31. package/dist/server.js.map +1 -0
  32. package/dist/tool-inputs.d.ts +254 -0
  33. package/dist/tool-inputs.js +239 -0
  34. package/dist/tool-inputs.js.map +1 -0
  35. package/dist/tool-result.d.ts +4 -0
  36. package/dist/tool-result.js +23 -0
  37. package/dist/tool-result.js.map +1 -0
  38. package/dist/tools.d.ts +8 -0
  39. package/dist/tools.js +259 -0
  40. package/dist/tools.js.map +1 -0
  41. package/dist/workspaces.d.ts +11 -0
  42. package/dist/workspaces.js +77 -0
  43. package/dist/workspaces.js.map +1 -0
  44. package/package.json +41 -0
package/README.md ADDED
@@ -0,0 +1,186 @@
1
+ # @hyperstar/mcp
2
+
3
+ `@hyperstar/mcp` is the local stdio MCP server for Hyperstar headless
4
+ workflows. It exposes scoped creator search, campaign roster, bulk email, and
5
+ inbox tools for MCP clients using either a service-account key or local browser
6
+ CLI login.
7
+
8
+ ## Install
9
+
10
+ After `@hyperstar/mcp` is published to npm:
11
+
12
+ ```sh
13
+ npx -y --package @hyperstar/mcp hyperstar-mcp
14
+ ```
15
+
16
+ The package exposes two binaries:
17
+
18
+ - `hyperstar-mcp`: the stdio MCP server.
19
+ - `hyperstar`: the local login and workspace helper CLI.
20
+
21
+ Because the package exposes multiple binaries, use the explicit
22
+ `--package @hyperstar/mcp hyperstar-mcp` form instead of bare
23
+ `npx -y @hyperstar/mcp` in MCP client configs.
24
+
25
+ For a one-off browser login without a global install:
26
+
27
+ ```sh
28
+ npx -y --package @hyperstar/mcp hyperstar login
29
+ npx -y --package @hyperstar/mcp hyperstar workspaces list --json
30
+ npx -y --package @hyperstar/mcp hyperstar workspaces use org_123
31
+ ```
32
+
33
+ Before the first npm publish, dev e2e should use a local pack:
34
+
35
+ ```sh
36
+ cd projects/hyperstar-mcp
37
+ npm pack --dry-run
38
+ npm pack
39
+ npx -y --package ./hyperstar-mcp-0.1.0.tgz hyperstar-mcp
40
+ npx -y --package ./hyperstar-mcp-0.1.0.tgz hyperstar login
41
+ npx -y --package ./hyperstar-mcp-0.1.0.tgz hyperstar workspaces list --json
42
+ npx -y --package ./hyperstar-mcp-0.1.0.tgz hyperstar workspaces use org_123
43
+ ```
44
+
45
+ The first public scoped publish must use public access. This package sets
46
+ `publishConfig.access=public`, so `npm publish` is sufficient once npm
47
+ credentials are configured.
48
+
49
+ ## MCP client config
50
+
51
+ Service-account auth is the simplest non-interactive setup. Configure the MCP
52
+ server with a Hyperstar Product API base URL and service-account API key:
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "hyperstar": {
58
+ "command": "npx",
59
+ "args": ["-y", "--package", "@hyperstar/mcp", "hyperstar-mcp"],
60
+ "env": {
61
+ "HYPERSTAR_API_BASE_URL": "https://api.hyperstar.example",
62
+ "HYPERSTAR_API_KEY": "hstar_test_public-prefix.secret"
63
+ }
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ Create API keys in the dashboard from Team -> API keys. Use the headless
70
+ workflow preset. Enable inbox write only for agents that are allowed to send
71
+ inbox replies.
72
+
73
+ When `HYPERSTAR_API_KEY` is omitted, the server falls back to the local browser
74
+ login state created by the `hyperstar` CLI:
75
+
76
+ ```json
77
+ {
78
+ "mcpServers": {
79
+ "hyperstar": {
80
+ "command": "npx",
81
+ "args": ["-y", "--package", "@hyperstar/mcp", "hyperstar-mcp"],
82
+ "env": {
83
+ "HYPERSTAR_API_BASE_URL": "https://autopilot.dev.hyper-star.org",
84
+ "HYPERSTAR_APP_BASE_URL": "https://app.dev.hyper-star.org"
85
+ }
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ Local browser login stores tokens under the OS config directory and the selected
92
+ workspace in the same auth state file. Run `hyperstar login`, then either select
93
+ a workspace with `hyperstar workspaces use <organization_id>` or use the MCP
94
+ `list_workspaces` and `select_workspace` tools. Service-account mode is already
95
+ workspace-scoped, so `get_hyperstar_workflow_guide` omits `select_workspace`
96
+ when `HYPERSTAR_API_KEY` is used. For non-production login, set matching
97
+ `HYPERSTAR_API_BASE_URL` and `HYPERSTAR_APP_BASE_URL`; the CLI maps the standard
98
+ dev API origin to the dev app automatically, while custom API origins must
99
+ provide an explicit app base URL. `HYPERSTAR_API_KEY` takes precedence over local
100
+ CLI auth when both are present.
101
+
102
+ ## Tools
103
+
104
+ - `hyperstar_whoami`
105
+ - `list_workspaces`
106
+ - `select_workspace`
107
+ - `get_hyperstar_workflow_guide`
108
+ - `search_creators`
109
+ - `get_search_results`
110
+ - `save_search_results_to_campaign`
111
+ - `list_campaign_creators`
112
+ - `check_bulk_email_readiness`
113
+ - `start_bulk_email`
114
+ - `get_bulk_email_job`
115
+ - `list_inbox_threads`
116
+ - `get_inbox_aggregates`
117
+ - `update_inbox_thread_state`
118
+ - `send_inbox_reply`
119
+
120
+ ## Development
121
+
122
+ ```sh
123
+ npm install
124
+ npm test
125
+ npm run build
126
+ ```
127
+
128
+ ## Examples
129
+
130
+ Search creators:
131
+
132
+ ```json
133
+ {
134
+ "tool": "search_creators",
135
+ "arguments": {
136
+ "kind": "semantic",
137
+ "platform": "tiktok",
138
+ "region": "US",
139
+ "query": "ceramic mug reviewers",
140
+ "limit": 25
141
+ }
142
+ }
143
+ ```
144
+
145
+ Save search results to a campaign roster:
146
+
147
+ ```json
148
+ {
149
+ "tool": "save_search_results_to_campaign",
150
+ "arguments": {
151
+ "campaign_id": 123,
152
+ "search_id": "550e8400-e29b-41d4-a716-446655440000",
153
+ "limit": 100
154
+ }
155
+ }
156
+ ```
157
+
158
+ Start a bulk email job. This performs a real send:
159
+
160
+ ```json
161
+ {
162
+ "tool": "start_bulk_email",
163
+ "arguments": {
164
+ "campaign_id": 123,
165
+ "subject": "Partnership idea",
166
+ "body_text": "Hi, we would like to introduce our new campaign.",
167
+ "campaign_creator_ids": [7, 8],
168
+ "idempotency_key": "campaign-123-intro-2026-07-09"
169
+ }
170
+ }
171
+ ```
172
+
173
+ Reply to an inbox thread. This performs a real send:
174
+
175
+ ```json
176
+ {
177
+ "tool": "send_inbox_reply",
178
+ "arguments": {
179
+ "platform": "tiktok",
180
+ "thread_id": 456,
181
+ "subject": "Re: Partnership idea",
182
+ "body_text": "Thanks for the reply. Here are the next details.",
183
+ "idempotency_key": "thread-456-reply-2026-07-09"
184
+ }
185
+ }
186
+ ```
@@ -0,0 +1,48 @@
1
+ import type { CliAuthState, CliAuthStateStore } from "./cli-auth-state.js";
2
+ import type { PkcePair } from "./pkce.js";
3
+ export declare const CLI_CLIENT_ID = "hyperstar-local-agent";
4
+ export type Fetcher = (input: URL, init: RequestInit) => Promise<Response>;
5
+ export type CliTokenPair = {
6
+ readonly accessToken: string;
7
+ readonly refreshToken: string;
8
+ readonly accessTokenExpiresAt: string;
9
+ };
10
+ export type Workspace = {
11
+ readonly organization_id: string;
12
+ readonly name?: string;
13
+ };
14
+ export type WorkspaceList = {
15
+ readonly workspaces: readonly Workspace[];
16
+ };
17
+ export type CliAuthClient = {
18
+ readonly buildAuthorizeUrl: (callbackUrl: string, pkce: PkcePair, state: string) => URL;
19
+ readonly exchangeCode: (code: string, verifier: string, redirectUri: string) => Promise<CliTokenPair>;
20
+ readonly refresh: (refreshToken: string) => Promise<CliTokenPair>;
21
+ readonly logout: (refreshToken: string) => Promise<void>;
22
+ readonly listWorkspaces: (accessToken: string) => Promise<WorkspaceList>;
23
+ };
24
+ export type CliAccessTokenProvider = {
25
+ readonly getAccessToken: () => Promise<string>;
26
+ readonly refreshAccessToken?: () => Promise<string>;
27
+ };
28
+ export type CliAuthClientOptions = {
29
+ readonly apiBaseUrl: string;
30
+ readonly appBaseUrl: string;
31
+ readonly fetcher?: Fetcher | undefined;
32
+ readonly now?: (() => Date) | undefined;
33
+ };
34
+ /** Create a client for the backend CLI auth routes. */
35
+ export declare function createCliAuthClient(options: CliAuthClientOptions): CliAuthClient;
36
+ export type StoredCliAccessTokenProviderOptions = {
37
+ readonly store: CliAuthStateStore;
38
+ readonly client: CliAuthClient;
39
+ readonly now?: (() => Date) | undefined;
40
+ };
41
+ /** Create an access-token provider that refreshes expired persisted CLI tokens. */
42
+ export declare function createStoredCliAccessTokenProvider(options: StoredCliAccessTokenProviderOptions): CliAccessTokenProvider;
43
+ /** Convert a token pair into persisted CLI auth state. */
44
+ export declare function tokenPairToAuthState(tokenPair: CliTokenPair, options: {
45
+ readonly apiBaseUrl: string;
46
+ readonly appBaseUrl: string;
47
+ readonly previousState?: CliAuthState | null;
48
+ }): CliAuthState;
@@ -0,0 +1,214 @@
1
+ export const CLI_CLIENT_ID = "hyperstar-local-agent";
2
+ /** Create a client for the backend CLI auth routes. */
3
+ export function createCliAuthClient(options) {
4
+ const fetcher = options.fetcher ?? fetch;
5
+ const now = options.now ?? (() => new Date());
6
+ return {
7
+ buildAuthorizeUrl: (callbackUrl, pkce, state) => buildAuthorizeUrl(options.appBaseUrl, callbackUrl, pkce, state),
8
+ exchangeCode: async (code, verifier, redirectUri) => requestToken(fetcher, options.apiBaseUrl, now, {
9
+ code,
10
+ code_verifier: verifier,
11
+ client_id: CLI_CLIENT_ID,
12
+ redirect_uri: redirectUri,
13
+ }),
14
+ refresh: async (refreshToken) => requestRefresh(fetcher, options.apiBaseUrl, now, {
15
+ refresh_token: refreshToken,
16
+ }),
17
+ logout: async (refreshToken) => {
18
+ const response = await fetcher(buildApiUrl(options.apiBaseUrl, "/api/v1/cli-auth/logout"), {
19
+ method: "POST",
20
+ headers: {
21
+ accept: "application/json",
22
+ "content-type": "application/json",
23
+ },
24
+ body: JSON.stringify({ refresh_token: refreshToken }),
25
+ });
26
+ if (!response.ok) {
27
+ throw new Error(`Hyperstar logout failed with status ${response.status}`);
28
+ }
29
+ },
30
+ listWorkspaces: async (accessToken) => {
31
+ const response = await fetcher(buildApiUrl(options.apiBaseUrl, "/v1/workspaces"), {
32
+ method: "GET",
33
+ headers: {
34
+ accept: "application/json",
35
+ Authorization: `Bearer ${accessToken}`,
36
+ },
37
+ });
38
+ const payload = await readJson(response);
39
+ if (!response.ok) {
40
+ throw new Error(`Hyperstar workspace request failed with status ${response.status}`);
41
+ }
42
+ return parseWorkspaceList(payload);
43
+ },
44
+ };
45
+ }
46
+ /** Create an access-token provider that refreshes expired persisted CLI tokens. */
47
+ export function createStoredCliAccessTokenProvider(options) {
48
+ let pendingRefresh = null;
49
+ const runExclusiveRefresh = (force) => {
50
+ if (pendingRefresh !== null) {
51
+ return pendingRefresh;
52
+ }
53
+ pendingRefresh = readOrRefreshAccessToken(options, force).finally(() => {
54
+ pendingRefresh = null;
55
+ });
56
+ return pendingRefresh;
57
+ };
58
+ return {
59
+ getAccessToken: async () => runExclusiveRefresh(false),
60
+ refreshAccessToken: async () => runExclusiveRefresh(true),
61
+ };
62
+ }
63
+ /** Read a valid access token or refresh persisted CLI auth state. */
64
+ async function readOrRefreshAccessToken(options, forceRefresh) {
65
+ return options.store.withExclusiveLock(() => readOrRefreshAccessTokenLocked(options, forceRefresh));
66
+ }
67
+ /** Read or refresh persisted CLI auth state while holding the store lock. */
68
+ async function readOrRefreshAccessTokenLocked(options, forceRefresh) {
69
+ const now = options.now ?? (() => new Date());
70
+ const state = await options.store.read();
71
+ if (state === null) {
72
+ throw new Error("Run `hyperstar login` or set HYPERSTAR_API_KEY");
73
+ }
74
+ if (!forceRefresh && !isNearExpiry(state.accessTokenExpiresAt, now())) {
75
+ return state.accessToken;
76
+ }
77
+ return refreshAndStore(options, state);
78
+ }
79
+ /** Build the browser authorization URL for local CLI login. */
80
+ function buildAuthorizeUrl(appBaseUrl, callbackUrl, pkce, state) {
81
+ const url = new URL("/cli/authorize", `${appBaseUrl}/`);
82
+ url.searchParams.set("client_id", CLI_CLIENT_ID);
83
+ url.searchParams.set("redirect_uri", callbackUrl);
84
+ url.searchParams.set("code_challenge", pkce.challenge);
85
+ url.searchParams.set("code_challenge_method", "S256");
86
+ url.searchParams.set("state", state);
87
+ return url;
88
+ }
89
+ /** Exchange an authorization or refresh grant for CLI tokens. */
90
+ async function requestToken(fetcher, apiBaseUrl, now, body) {
91
+ const response = await fetcher(buildApiUrl(apiBaseUrl, "/api/v1/cli-auth/token"), {
92
+ method: "POST",
93
+ headers: {
94
+ accept: "application/json",
95
+ "content-type": "application/json",
96
+ },
97
+ body: JSON.stringify(body),
98
+ });
99
+ const payload = await readJson(response);
100
+ if (!response.ok) {
101
+ throw new Error(`Hyperstar token request failed with status ${response.status}`);
102
+ }
103
+ return parseTokenPair(payload, now);
104
+ }
105
+ /** Rotate a refresh token using the backend refresh route. */
106
+ async function requestRefresh(fetcher, apiBaseUrl, now, body) {
107
+ const response = await fetcher(buildApiUrl(apiBaseUrl, "/api/v1/cli-auth/refresh"), {
108
+ method: "POST",
109
+ headers: {
110
+ accept: "application/json",
111
+ "content-type": "application/json",
112
+ },
113
+ body: JSON.stringify(body),
114
+ });
115
+ const payload = await readJson(response);
116
+ if (!response.ok) {
117
+ throw new Error(`Hyperstar refresh request failed with status ${response.status}`);
118
+ }
119
+ return parseTokenPair(payload, now);
120
+ }
121
+ /** Build a root-relative API URL. */
122
+ function buildApiUrl(apiBaseUrl, path) {
123
+ return new URL(path, `${apiBaseUrl}/`);
124
+ }
125
+ /** Parse response JSON, preserving empty bodies as null. */
126
+ async function readJson(response) {
127
+ const text = await response.text();
128
+ if (text.trim().length === 0) {
129
+ return null;
130
+ }
131
+ return JSON.parse(text);
132
+ }
133
+ /** Parse backend token payloads into local camelCase state. */
134
+ function parseTokenPair(payload, now) {
135
+ if (typeof payload === "object" &&
136
+ payload !== null &&
137
+ "access_token" in payload &&
138
+ "refresh_token" in payload &&
139
+ "expires_in" in payload &&
140
+ typeof payload.access_token === "string" &&
141
+ typeof payload.refresh_token === "string" &&
142
+ typeof payload.expires_in === "number" &&
143
+ Number.isFinite(payload.expires_in) &&
144
+ payload.expires_in > 0) {
145
+ return {
146
+ accessToken: payload.access_token,
147
+ refreshToken: payload.refresh_token,
148
+ accessTokenExpiresAt: new Date(now().getTime() + payload.expires_in * 1_000).toISOString(),
149
+ };
150
+ }
151
+ throw new Error("Hyperstar token response was invalid");
152
+ }
153
+ /** Refresh an expired access token and persist the rotated token pair. */
154
+ async function refreshAndStore(options, state) {
155
+ const tokenPair = await options.client.refresh(state.refreshToken);
156
+ await options.store.write({
157
+ ...state,
158
+ accessToken: tokenPair.accessToken,
159
+ refreshToken: tokenPair.refreshToken,
160
+ accessTokenExpiresAt: tokenPair.accessTokenExpiresAt,
161
+ });
162
+ return tokenPair.accessToken;
163
+ }
164
+ /** Parse backend workspace list payloads. */
165
+ function parseWorkspaceList(payload) {
166
+ if (typeof payload === "object" &&
167
+ payload !== null &&
168
+ "workspaces" in payload &&
169
+ Array.isArray(payload.workspaces)) {
170
+ return {
171
+ workspaces: payload.workspaces.map(parseWorkspace),
172
+ };
173
+ }
174
+ throw new Error("Hyperstar workspace response was invalid");
175
+ }
176
+ /** Parse one workspace record from the backend. */
177
+ function parseWorkspace(payload) {
178
+ if (typeof payload === "object" &&
179
+ payload !== null &&
180
+ "organization_id" in payload &&
181
+ typeof payload.organization_id === "string") {
182
+ return {
183
+ organization_id: payload.organization_id,
184
+ ...("name" in payload && typeof payload.name === "string"
185
+ ? { name: payload.name }
186
+ : {}),
187
+ };
188
+ }
189
+ throw new Error("Hyperstar workspace response was invalid");
190
+ }
191
+ /** Return true when a token expires within the refresh window. */
192
+ function isNearExpiry(expiresAt, now) {
193
+ const expiresAtMs = Date.parse(expiresAt);
194
+ if (Number.isNaN(expiresAtMs)) {
195
+ return true;
196
+ }
197
+ return expiresAtMs - now.getTime() <= 60_000;
198
+ }
199
+ /** Convert a token pair into persisted CLI auth state. */
200
+ export function tokenPairToAuthState(tokenPair, options) {
201
+ return {
202
+ apiBaseUrl: options.apiBaseUrl,
203
+ appBaseUrl: options.appBaseUrl,
204
+ refreshToken: tokenPair.refreshToken,
205
+ accessToken: tokenPair.accessToken,
206
+ accessTokenExpiresAt: tokenPair.accessTokenExpiresAt,
207
+ ...(options.previousState?.selectedOrganizationId === undefined
208
+ ? {}
209
+ : {
210
+ selectedOrganizationId: options.previousState.selectedOrganizationId,
211
+ }),
212
+ };
213
+ }
214
+ //# sourceMappingURL=cli-auth-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-auth-client.js","sourceRoot":"","sources":["../../src/auth/cli-auth-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export type CliAuthState = {
2
+ readonly apiBaseUrl: string;
3
+ readonly appBaseUrl: string;
4
+ readonly refreshToken: string;
5
+ readonly accessToken: string;
6
+ readonly accessTokenExpiresAt: string;
7
+ readonly selectedOrganizationId?: string;
8
+ };
9
+ export type AuthStatePathOptions = {
10
+ readonly env?: Readonly<Record<string, string | undefined>>;
11
+ readonly platform?: NodeJS.Platform;
12
+ readonly homedir?: () => string;
13
+ };
14
+ export type CliAuthStateStore = {
15
+ readonly pathOptions: AuthStatePathOptions;
16
+ readonly path: string;
17
+ readonly read: () => Promise<CliAuthState | null>;
18
+ readonly readSync: () => CliAuthState | null;
19
+ readonly write: (state: CliAuthState) => Promise<void>;
20
+ readonly clear: () => Promise<void>;
21
+ readonly withExclusiveLock: <T>(action: () => Promise<T>) => Promise<T>;
22
+ };
23
+ /** Resolve the local CLI auth state path for the current OS conventions. */
24
+ export declare function resolveAuthStatePath(options?: AuthStatePathOptions): string;
25
+ /** Create a file-backed CLI auth state store. */
26
+ export declare function createFileCliAuthStateStore(options?: AuthStatePathOptions): CliAuthStateStore;
@@ -0,0 +1,176 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { chmod, mkdir, readFile, rename, rm, stat, writeFile, } from "node:fs/promises";
3
+ import { homedir as defaultHomedir } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ import { setTimeout as sleep } from "node:timers/promises";
6
+ const STALE_LOCK_MS = 60_000;
7
+ const LOCK_HEARTBEAT_MS = 5_000;
8
+ /** Resolve the local CLI auth state path for the current OS conventions. */
9
+ export function resolveAuthStatePath(options = {}) {
10
+ const env = options.env ?? process.env;
11
+ const platform = options.platform ?? process.platform;
12
+ const homedir = options.homedir ?? defaultHomedir;
13
+ if (platform === "win32") {
14
+ return join(env.APPDATA ?? join(homedir(), "AppData", "Roaming"), "Hyperstar", "auth.json");
15
+ }
16
+ return join(env.XDG_CONFIG_HOME ?? join(homedir(), ".config"), "hyperstar", "auth.json");
17
+ }
18
+ /** Create a file-backed CLI auth state store. */
19
+ export function createFileCliAuthStateStore(options = {}) {
20
+ const path = resolveAuthStatePath(options);
21
+ return {
22
+ pathOptions: options,
23
+ path,
24
+ read: async () => readAuthState(path),
25
+ readSync: () => readAuthStateSync(path),
26
+ write: async (state) => writeAuthState(path, state),
27
+ clear: async () => {
28
+ await rm(path, { force: true });
29
+ },
30
+ withExclusiveLock: async (action) => withAuthStateLock(path, action),
31
+ };
32
+ }
33
+ /** Read auth state JSON from disk. */
34
+ async function readAuthState(path) {
35
+ try {
36
+ return parseAuthState(await readFile(path, "utf8"));
37
+ }
38
+ catch (error) {
39
+ if (isNotFoundError(error)) {
40
+ return null;
41
+ }
42
+ throw error;
43
+ }
44
+ }
45
+ /** Read auth state JSON synchronously for process startup configuration. */
46
+ function readAuthStateSync(path) {
47
+ if (!existsSync(path)) {
48
+ return null;
49
+ }
50
+ return parseAuthState(readFileSync(path, "utf8"));
51
+ }
52
+ /** Write auth state JSON with restrictive permissions where the OS supports it. */
53
+ async function writeAuthState(path, state) {
54
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
55
+ const tempPath = `${path}.${process.pid}.${Date.now()}.tmp`;
56
+ await writeFile(tempPath, `${JSON.stringify(state, null, 2)}\n`, {
57
+ encoding: "utf8",
58
+ mode: 0o600,
59
+ });
60
+ if (process.platform !== "win32") {
61
+ await chmod(tempPath, 0o600);
62
+ }
63
+ await rename(tempPath, path);
64
+ }
65
+ /** Parse and minimally validate persisted auth state. */
66
+ function parseAuthState(raw) {
67
+ const value = JSON.parse(raw);
68
+ if (typeof value.apiBaseUrl !== "string" ||
69
+ typeof value.appBaseUrl !== "string" ||
70
+ typeof value.refreshToken !== "string" ||
71
+ typeof value.accessToken !== "string" ||
72
+ typeof value.accessTokenExpiresAt !== "string") {
73
+ throw new Error("Hyperstar auth state is invalid; run `hyperstar login` again");
74
+ }
75
+ return {
76
+ apiBaseUrl: value.apiBaseUrl,
77
+ appBaseUrl: value.appBaseUrl,
78
+ refreshToken: value.refreshToken,
79
+ accessToken: value.accessToken,
80
+ accessTokenExpiresAt: value.accessTokenExpiresAt,
81
+ ...(typeof value.selectedOrganizationId === "string"
82
+ ? { selectedOrganizationId: value.selectedOrganizationId }
83
+ : {}),
84
+ };
85
+ }
86
+ /** Return true when a filesystem error is an ENOENT. */
87
+ function isNotFoundError(error) {
88
+ return (typeof error === "object" &&
89
+ error !== null &&
90
+ "code" in error &&
91
+ error.code === "ENOENT");
92
+ }
93
+ /** Run an auth-state operation under a filesystem lock shared by CLI processes. */
94
+ async function withAuthStateLock(path, action) {
95
+ const release = await acquireAuthStateLock(`${path}.lock`);
96
+ try {
97
+ return await action();
98
+ }
99
+ finally {
100
+ await release();
101
+ }
102
+ }
103
+ /** Acquire a directory lock using atomic mkdir. */
104
+ async function acquireAuthStateLock(lockPath) {
105
+ const startedAt = Date.now();
106
+ await mkdir(dirname(lockPath), { recursive: true, mode: 0o700 });
107
+ while (true) {
108
+ try {
109
+ await mkdir(lockPath, { mode: 0o700 });
110
+ return await holdAuthStateLock(lockPath);
111
+ }
112
+ catch (error) {
113
+ if (!isAlreadyExistsError(error) || Date.now() - startedAt > 10_000) {
114
+ throw new Error("Timed out waiting for Hyperstar auth state lock");
115
+ }
116
+ await removeStaleAuthStateLock(lockPath);
117
+ await sleep(25);
118
+ }
119
+ }
120
+ }
121
+ /** Write owner metadata and keep the lock heartbeat fresh until release. */
122
+ async function holdAuthStateLock(lockPath) {
123
+ await writeLockHeartbeat(lockPath);
124
+ const heartbeat = setInterval(() => {
125
+ void writeLockHeartbeat(lockPath).catch(() => undefined);
126
+ }, LOCK_HEARTBEAT_MS);
127
+ return async () => {
128
+ clearInterval(heartbeat);
129
+ await rm(lockPath, { force: true, recursive: true });
130
+ };
131
+ }
132
+ /** Refresh the lock heartbeat file used to distinguish live and stale locks. */
133
+ async function writeLockHeartbeat(lockPath) {
134
+ await writeFile(join(lockPath, "owner.json"), `${JSON.stringify({ pid: process.pid, updated_at: new Date().toISOString() })}\n`, {
135
+ encoding: "utf8",
136
+ mode: 0o600,
137
+ });
138
+ }
139
+ /** Remove lock directories old enough to have been left by a killed process. */
140
+ async function removeStaleAuthStateLock(lockPath) {
141
+ try {
142
+ const heartbeatStat = await stat(join(lockPath, "owner.json"));
143
+ if (Date.now() - heartbeatStat.mtimeMs >= STALE_LOCK_MS) {
144
+ await rm(lockPath, { force: true, recursive: true });
145
+ }
146
+ }
147
+ catch (error) {
148
+ if (isNotFoundError(error)) {
149
+ await removeLockDirectoryIfStale(lockPath);
150
+ return;
151
+ }
152
+ throw error;
153
+ }
154
+ }
155
+ /** Remove a lock directory only when it still exists and is stale. */
156
+ async function removeLockDirectoryIfStale(lockPath) {
157
+ try {
158
+ const lockStat = await stat(lockPath);
159
+ if (Date.now() - lockStat.mtimeMs >= STALE_LOCK_MS) {
160
+ await rm(lockPath, { force: true, recursive: true });
161
+ }
162
+ }
163
+ catch (error) {
164
+ if (!isNotFoundError(error)) {
165
+ throw error;
166
+ }
167
+ }
168
+ }
169
+ /** Return true when a filesystem error means the lock already exists. */
170
+ function isAlreadyExistsError(error) {
171
+ return (typeof error === "object" &&
172
+ error !== null &&
173
+ "code" in error &&
174
+ error.code === "EEXIST");
175
+ }
176
+ //# sourceMappingURL=cli-auth-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-auth-state.js","sourceRoot":"","sources":["../../src/auth/cli-auth-state.ts"],"names":[],"mappings":"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"}