epismo 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 ADDED
@@ -0,0 +1,115 @@
1
+ # Epismo CLI
2
+
3
+ Command-line interface for [Epismo](https://epismo.ai).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g epismo
9
+ ```
10
+
11
+ Or run without installing:
12
+
13
+ ```bash
14
+ npx epismo <command>
15
+ ```
16
+
17
+ ## Authentication
18
+
19
+ ### Default login (OTP)
20
+
21
+ ```bash
22
+ epismo login
23
+ ```
24
+
25
+ Prompts for email and OTP code by default.
26
+
27
+ You can also provide the values inline:
28
+
29
+ ```bash
30
+ epismo login --email you@example.com --pin 123456
31
+ ```
32
+
33
+ ### Browser login
34
+
35
+ ```bash
36
+ epismo login --browser
37
+ ```
38
+
39
+ Opens a browser and signs you in via OAuth.
40
+
41
+ ### Logout
42
+
43
+ Clears local credentials.
44
+
45
+ ```bash
46
+ epismo logout
47
+ ```
48
+
49
+ ## Commands
50
+
51
+ ### `epismo whoami`
52
+
53
+ Show the currently authenticated user and accessible workspaces.
54
+
55
+ ```bash
56
+ epismo whoami
57
+ ```
58
+
59
+ ### `epismo workspace`
60
+
61
+ ```bash
62
+ epismo workspace list # list accessible workspaces
63
+ epismo workspace current # show saved default workspace
64
+ epismo workspace use <workspace-id> # set default workspace
65
+ epismo workspace clear # clear default workspace
66
+ ```
67
+
68
+ ### `epismo track`
69
+
70
+ Manage tasks, notes, and goals.
71
+
72
+ ```bash
73
+ epismo track upsert --type task --title "Fix bug" --content "Details..."
74
+ epismo track upsert --input @task.json
75
+ epismo track get --type task --id <id>
76
+ epismo track search --type task --query "bug" --filter '{"status":["todo"]}'
77
+ epismo track search --type task --query "bug" --view summary
78
+ epismo track delete --type task --id <id>
79
+ ```
80
+
81
+ ### `epismo asset`
82
+
83
+ ```bash
84
+ epismo asset upsert --type workflow --title "My workflow" --input @workflow.json
85
+ epismo asset get --type workflow --id <id>
86
+ epismo asset search --type workflow --query "onboarding" --filter '{"visibility":["public"]}'
87
+ epismo asset search --type workflow --query "onboarding" --view summary
88
+ epismo asset like --type workflow --id <id> --liked true
89
+ epismo asset import --project-id <project-id> --asset-ids <id1>,<id2>
90
+ epismo asset delete --type workflow --id <id>
91
+ ```
92
+
93
+ ### `epismo credit`
94
+
95
+ ```bash
96
+ epismo credit balance
97
+ epismo credit balance --workspace-id <workspace-id>
98
+ ```
99
+
100
+ ## Workspace Selection
101
+
102
+ - `epismo workspace use <workspace-id>` saves the default workspace.
103
+ - `--workspace-id <id>` overrides the saved default for a single command.
104
+ - If neither is set, the CLI operates in personal context.
105
+
106
+ ## Input Conventions
107
+
108
+ - `--input <json>` accepts an inline JSON object.
109
+ - `--input @path/to/file.json` loads a JSON object from a file.
110
+ - `--input -` reads a JSON object from stdin.
111
+ - Explicit flags override fields loaded from `--input`.
112
+
113
+ ## Output
114
+
115
+ All commands output JSON by default. Pass `--json` to force JSON output when a human-readable summary is also available.
package/dist/api.js ADDED
@@ -0,0 +1,37 @@
1
+ export async function requestJson(apiUrl, pathname, options = {}) {
2
+ const headers = {};
3
+ if (options.body !== undefined) {
4
+ headers["content-type"] = "application/json";
5
+ }
6
+ if (options.authToken) {
7
+ headers.authorization = `Bearer ${options.authToken}`;
8
+ }
9
+ const response = await fetch(`${apiUrl}${pathname}`, {
10
+ method: options.method ?? "GET",
11
+ headers,
12
+ body: options.body !== undefined ? JSON.stringify(options.body) : undefined
13
+ });
14
+ const text = await response.text();
15
+ let parsed = {};
16
+ if (text) {
17
+ try {
18
+ parsed = JSON.parse(text);
19
+ }
20
+ catch {
21
+ parsed = { error: text };
22
+ }
23
+ }
24
+ if (!response.ok) {
25
+ const payload = parsed && typeof parsed === "object" && !Array.isArray(parsed)
26
+ ? parsed
27
+ : {};
28
+ const message = typeof payload.error === "string"
29
+ ? payload.error
30
+ : typeof payload.error_description === "string"
31
+ ? payload.error_description
32
+ : `HTTP ${response.status}`;
33
+ throw new Error(message);
34
+ }
35
+ return parsed;
36
+ }
37
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,MAAc,EACd,QAAgB,EAChB,UAA8B,EAAE;IAEhC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,OAAO,CAAC,aAAa,GAAG,UAAU,OAAO,CAAC,SAAS,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,GAAG,QAAQ,EAAE,EAAE;QACpD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;QAC/B,OAAO;QACP,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC3E,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,MAAM,GAAY,EAAE,CAAC;IACzB,IAAI,IAAI,EAAE,CAAC;QACV,IAAI,CAAC;YACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAC1B,CAAC;IACF,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,OAAO,GACZ,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAC7D,CAAC,CAAE,MAAkC;YACrC,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,OAAO,GACZ,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YAChC,CAAC,CAAC,OAAO,CAAC,KAAK;YACf,CAAC,CAAC,OAAO,OAAO,CAAC,iBAAiB,KAAK,QAAQ;gBAC9C,CAAC,CAAC,OAAO,CAAC,iBAAiB;gBAC3B,CAAC,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,MAAmB,CAAC;AAC5B,CAAC"}
package/dist/assets.js ADDED
@@ -0,0 +1,85 @@
1
+ import { requestJson } from "./api.js";
2
+ import { resolveApiUrl } from "./config.js";
3
+ function withWorkspaceQuery(pathname, workspaceId) {
4
+ if (!workspaceId?.trim()) {
5
+ return pathname;
6
+ }
7
+ const params = new URLSearchParams({ workspaceId: workspaceId.trim() });
8
+ return `${pathname}?${params.toString()}`;
9
+ }
10
+ function readRequiredId(input) {
11
+ if (!input || typeof input !== "object") {
12
+ throw new Error("id is required.");
13
+ }
14
+ const id = input.id;
15
+ if (typeof id !== "string" || !id.trim()) {
16
+ throw new Error("id is required.");
17
+ }
18
+ return id.trim();
19
+ }
20
+ function readRequiredType(input) {
21
+ if (!input || typeof input !== "object") {
22
+ throw new Error("type is required.");
23
+ }
24
+ const type = input.type;
25
+ if (typeof type !== "string" || !type.trim()) {
26
+ throw new Error("type is required.");
27
+ }
28
+ return type.trim();
29
+ }
30
+ export async function upsertAsset(context, input) {
31
+ return requestJson(resolveApiUrl(), "/v1/assets", {
32
+ method: "PUT",
33
+ authToken: context.auth.accessToken,
34
+ body: {
35
+ ...(input && typeof input === "object" ? input : {}),
36
+ ...(context.workspaceId ? { workspaceId: context.workspaceId } : {})
37
+ }
38
+ });
39
+ }
40
+ export async function getAsset(context, input) {
41
+ const type = readRequiredType(input);
42
+ const id = readRequiredId(input);
43
+ return requestJson(resolveApiUrl(), withWorkspaceQuery(`/v1/assets/${encodeURIComponent(type)}/${encodeURIComponent(id)}`, context.workspaceId), {
44
+ authToken: context.auth.accessToken
45
+ });
46
+ }
47
+ export async function searchAssets(context, input) {
48
+ return requestJson(resolveApiUrl(), withWorkspaceQuery("/v1/assets/search", context.workspaceId), {
49
+ method: "POST",
50
+ authToken: context.auth.accessToken,
51
+ body: {
52
+ ...(input && typeof input === "object" ? input : {}),
53
+ ...(context.workspaceId ? { workspaceId: context.workspaceId } : {})
54
+ }
55
+ });
56
+ }
57
+ export async function likeAsset(context, input) {
58
+ return requestJson(resolveApiUrl(), withWorkspaceQuery("/v1/assets/like", context.workspaceId), {
59
+ method: "POST",
60
+ authToken: context.auth.accessToken,
61
+ body: {
62
+ ...(input && typeof input === "object" ? input : {}),
63
+ ...(context.workspaceId ? { workspaceId: context.workspaceId } : {})
64
+ }
65
+ });
66
+ }
67
+ export async function importAssets(context, input) {
68
+ return requestJson(resolveApiUrl(), withWorkspaceQuery("/v1/assets/import", context.workspaceId), {
69
+ method: "POST",
70
+ authToken: context.auth.accessToken,
71
+ body: {
72
+ ...(input && typeof input === "object" ? input : {}),
73
+ ...(context.workspaceId ? { workspaceId: context.workspaceId } : {})
74
+ }
75
+ });
76
+ }
77
+ export async function deleteAsset(context, input) {
78
+ const type = readRequiredType(input);
79
+ const id = readRequiredId(input);
80
+ return requestJson(resolveApiUrl(), withWorkspaceQuery(`/v1/assets/${encodeURIComponent(type)}/${encodeURIComponent(id)}`, context.workspaceId), {
81
+ method: "DELETE",
82
+ authToken: context.auth.accessToken
83
+ });
84
+ }
85
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"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"}
package/dist/auth.js ADDED
@@ -0,0 +1,330 @@
1
+ import { createServer } from "node:http";
2
+ import { randomBytes, createHash } from "node:crypto";
3
+ import { spawn } from "node:child_process";
4
+ import { createInterface } from "node:readline/promises";
5
+ import { stdin as input, stdout as output } from "node:process";
6
+ import { clearCredentials, readCliConfig, readCredentials, resolveApiUrl, resolveWebUrl, writeCliConfig, writeCredentials } from "./config.js";
7
+ import { requestJson } from "./api.js";
8
+ const CLI_CLIENT_ID = "epismo-cli";
9
+ const TOKEN_REFRESH_THRESHOLD_MS = 5 * 60 * 1000;
10
+ async function prompt(question) {
11
+ const readline = createInterface({ input, output });
12
+ try {
13
+ return (await readline.question(question)).trim();
14
+ }
15
+ finally {
16
+ readline.close();
17
+ }
18
+ }
19
+ function generatePkce() {
20
+ const verifier = randomBytes(32).toString("base64url");
21
+ const challenge = createHash("sha256").update(verifier).digest("base64url");
22
+ return { verifier, challenge };
23
+ }
24
+ function openBrowser(url) {
25
+ const platform = process.platform;
26
+ if (platform === "darwin") {
27
+ spawn("open", [url], { detached: true, stdio: "ignore" }).unref();
28
+ }
29
+ else if (platform === "win32") {
30
+ spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore" }).unref();
31
+ }
32
+ else {
33
+ spawn("xdg-open", [url], { detached: true, stdio: "ignore" }).unref();
34
+ }
35
+ }
36
+ function getRandomPort() {
37
+ return 49152 + Math.floor(Math.random() * 16383);
38
+ }
39
+ async function waitForOAuthCallback(port) {
40
+ return new Promise((resolve, reject) => {
41
+ const timeoutId = setTimeout(() => {
42
+ server.close();
43
+ reject(new Error("Authorization timed out after 5 minutes."));
44
+ }, 5 * 60 * 1000);
45
+ const server = createServer((req, res) => {
46
+ const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
47
+ if (url.pathname !== "/callback") {
48
+ res.writeHead(404);
49
+ res.end();
50
+ return;
51
+ }
52
+ const code = url.searchParams.get("code");
53
+ const error = url.searchParams.get("error");
54
+ const workspaceId = url.searchParams.get("workspace_id") ?? undefined;
55
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
56
+ res.end("<html><body><p>Authorization complete. You may close this tab.</p></body></html>");
57
+ clearTimeout(timeoutId);
58
+ server.close();
59
+ if (error) {
60
+ reject(new Error(`Authorization denied: ${error}`));
61
+ }
62
+ else if (code) {
63
+ resolve({ code, workspaceId });
64
+ }
65
+ else {
66
+ reject(new Error("No authorization code received."));
67
+ }
68
+ });
69
+ server.on("error", (err) => {
70
+ clearTimeout(timeoutId);
71
+ reject(err);
72
+ });
73
+ server.listen(port, "127.0.0.1");
74
+ });
75
+ }
76
+ async function postOAuthToken(apiUrl, body) {
77
+ return requestJson(apiUrl, "/oauth/token", {
78
+ method: "POST",
79
+ body
80
+ });
81
+ }
82
+ async function fetchUserInfo(apiUrl, accessToken) {
83
+ return requestJson(apiUrl, "/oauth/userinfo", {
84
+ authToken: accessToken
85
+ });
86
+ }
87
+ async function fetchWorkspaces(apiUrl, accessToken) {
88
+ const response = await requestJson(apiUrl, "/v1/workspaces", {
89
+ authToken: accessToken
90
+ });
91
+ return response.workspaces;
92
+ }
93
+ async function loginWithBrowser(apiUrl, webUrl) {
94
+ const { verifier, challenge } = generatePkce();
95
+ const port = getRandomPort();
96
+ const redirectUri = `http://127.0.0.1:${port}/callback`;
97
+ const authorizeUrl = new URL(`${webUrl}/oauth/authorize`);
98
+ authorizeUrl.searchParams.set("response_type", "code");
99
+ authorizeUrl.searchParams.set("client_id", CLI_CLIENT_ID);
100
+ authorizeUrl.searchParams.set("redirect_uri", redirectUri);
101
+ authorizeUrl.searchParams.set("scope", "read write offline_access");
102
+ authorizeUrl.searchParams.set("code_challenge", challenge);
103
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
104
+ process.stderr.write("Opening browser for authorization...\n");
105
+ process.stderr.write(`If the browser does not open, visit:\n ${authorizeUrl.toString()}\n`);
106
+ openBrowser(authorizeUrl.toString());
107
+ const { code, workspaceId } = await waitForOAuthCallback(port);
108
+ const tokenResponse = await postOAuthToken(apiUrl, {
109
+ grant_type: "authorization_code",
110
+ code,
111
+ client_id: CLI_CLIENT_ID,
112
+ redirect_uri: redirectUri,
113
+ code_verifier: verifier
114
+ });
115
+ const userInfo = await fetchUserInfo(apiUrl, tokenResponse.access_token);
116
+ const expiresAt = new Date(Date.now() + tokenResponse.expires_in * 1000).toISOString();
117
+ return {
118
+ accessToken: tokenResponse.access_token,
119
+ refreshToken: tokenResponse.refresh_token,
120
+ expiresAt,
121
+ clientId: CLI_CLIENT_ID,
122
+ userId: userInfo.sub,
123
+ selectedWorkspaceId: workspaceId?.trim() ? workspaceId.trim() : undefined
124
+ };
125
+ }
126
+ async function loginWithOtp(apiUrl, options) {
127
+ const email = options.email?.trim() || (await prompt("Email: "));
128
+ if (!email) {
129
+ throw new Error("Email is required.");
130
+ }
131
+ const otpId = options.otpId?.trim() ||
132
+ (await requestJson(apiUrl, "/v1/otp-tokens", {
133
+ method: "POST",
134
+ body: { email }
135
+ })).otpId;
136
+ if (!otpId) {
137
+ throw new Error("Failed to obtain OTP ID.");
138
+ }
139
+ const pin = options.pin?.trim() || (await prompt("OTP code: "));
140
+ if (!pin) {
141
+ throw new Error("OTP code is required.");
142
+ }
143
+ const tokenResponse = await postOAuthToken(apiUrl, {
144
+ grant_type: "otp",
145
+ otp_id: otpId,
146
+ pin,
147
+ client_id: CLI_CLIENT_ID
148
+ });
149
+ const userInfo = await fetchUserInfo(apiUrl, tokenResponse.access_token);
150
+ const expiresAt = new Date(Date.now() + tokenResponse.expires_in * 1000).toISOString();
151
+ return {
152
+ accessToken: tokenResponse.access_token,
153
+ refreshToken: tokenResponse.refresh_token,
154
+ expiresAt,
155
+ clientId: CLI_CLIENT_ID,
156
+ userId: userInfo.sub,
157
+ lastLoginEmail: email
158
+ };
159
+ }
160
+ export async function login(options) {
161
+ const apiUrl = resolveApiUrl();
162
+ const webUrl = resolveWebUrl();
163
+ const config = await readCliConfig();
164
+ let credentials;
165
+ let lastLoginEmail;
166
+ let selectedWorkspaceId;
167
+ if (options.browser) {
168
+ const result = await loginWithBrowser(apiUrl, webUrl);
169
+ ({ selectedWorkspaceId, ...credentials } = result);
170
+ }
171
+ else {
172
+ const result = await loginWithOtp(apiUrl, options);
173
+ ({ lastLoginEmail, ...credentials } = result);
174
+ }
175
+ await writeCredentials(credentials);
176
+ await writeCliConfig({
177
+ ...config,
178
+ lastLoginEmail: lastLoginEmail ?? config.lastLoginEmail,
179
+ ...(options.browser !== true || selectedWorkspaceId === undefined
180
+ ? {}
181
+ : { defaultWorkspaceId: selectedWorkspaceId })
182
+ });
183
+ return {
184
+ userId: credentials.userId,
185
+ expiresAt: credentials.expiresAt,
186
+ lastLoginEmail: lastLoginEmail ?? config.lastLoginEmail
187
+ };
188
+ }
189
+ export async function logout() {
190
+ const credentials = await readCredentials();
191
+ const hadCredentials = Boolean(credentials?.accessToken);
192
+ if (credentials?.refreshToken) {
193
+ try {
194
+ await requestJson(resolveApiUrl(), "/oauth/revoke", {
195
+ method: "POST",
196
+ body: { token: credentials.refreshToken, client_id: credentials.clientId }
197
+ });
198
+ }
199
+ catch {
200
+ // Clear local state even when server-side revocation fails.
201
+ }
202
+ }
203
+ await clearCredentials();
204
+ return { cleared: true, hadCredentials };
205
+ }
206
+ async function refreshAccessToken(credentials, apiUrl) {
207
+ const tokenResponse = await postOAuthToken(apiUrl, {
208
+ grant_type: "refresh_token",
209
+ refresh_token: credentials.refreshToken,
210
+ client_id: credentials.clientId
211
+ });
212
+ const expiresAt = new Date(Date.now() + tokenResponse.expires_in * 1000).toISOString();
213
+ const updated = {
214
+ ...credentials,
215
+ accessToken: tokenResponse.access_token,
216
+ refreshToken: tokenResponse.refresh_token,
217
+ expiresAt
218
+ };
219
+ await writeCredentials(updated);
220
+ return updated;
221
+ }
222
+ export async function resolveAuthentication() {
223
+ if (process.env.EPISMO_TOKEN?.trim()) {
224
+ throw new Error("EPISMO_TOKEN is not supported by this CLI yet. Run `epismo login` first.");
225
+ }
226
+ const credentials = await readCredentials();
227
+ if (!credentials?.accessToken || !credentials.userId) {
228
+ throw new Error("Not authenticated. Run `epismo login` first.");
229
+ }
230
+ const apiUrl = resolveApiUrl();
231
+ const expiresAt = new Date(credentials.expiresAt).getTime();
232
+ if (expiresAt - Date.now() < TOKEN_REFRESH_THRESHOLD_MS) {
233
+ if (!credentials.refreshToken) {
234
+ throw new Error("Token expired and no refresh token available. Run `epismo login` again.");
235
+ }
236
+ try {
237
+ const refreshed = await refreshAccessToken(credentials, apiUrl);
238
+ return {
239
+ mode: "oauth",
240
+ userId: refreshed.userId,
241
+ accessToken: refreshed.accessToken,
242
+ expiresAt: refreshed.expiresAt
243
+ };
244
+ }
245
+ catch {
246
+ throw new Error("Token refresh failed. Run `epismo login` again.");
247
+ }
248
+ }
249
+ return {
250
+ mode: "oauth",
251
+ userId: credentials.userId,
252
+ accessToken: credentials.accessToken,
253
+ expiresAt: credentials.expiresAt
254
+ };
255
+ }
256
+ export async function whoami(options) {
257
+ const config = await readCliConfig();
258
+ const defaultWorkspaceId = config.defaultWorkspaceId?.trim() ?? "";
259
+ const requestedWorkspaceId = options.workspaceId?.trim() ?? "";
260
+ const auth = await resolveAuthentication();
261
+ const apiUrl = resolveApiUrl();
262
+ const [user, workspaces] = await Promise.all([
263
+ fetchUserInfo(apiUrl, auth.accessToken),
264
+ fetchWorkspaces(apiUrl, auth.accessToken)
265
+ ]);
266
+ return {
267
+ auth: {
268
+ mode: auth.mode,
269
+ userId: auth.userId,
270
+ expiresAt: auth.expiresAt
271
+ },
272
+ user: {
273
+ id: user.sub,
274
+ email: user.email,
275
+ username: user.preferred_username
276
+ },
277
+ defaultWorkspaceId,
278
+ effectiveWorkspaceId: requestedWorkspaceId || defaultWorkspaceId,
279
+ workspaces
280
+ };
281
+ }
282
+ export async function listAvailableWorkspaces() {
283
+ const config = await readCliConfig();
284
+ const auth = await resolveAuthentication();
285
+ const workspaces = await fetchWorkspaces(resolveApiUrl(), auth.accessToken);
286
+ const defaultWorkspaceId = config.defaultWorkspaceId?.trim() ?? "";
287
+ return {
288
+ defaultWorkspaceId,
289
+ workspaces: workspaces.map((workspace) => ({
290
+ ...workspace,
291
+ isDefault: workspace.id === defaultWorkspaceId
292
+ }))
293
+ };
294
+ }
295
+ export async function getCurrentWorkspace() {
296
+ const listed = await listAvailableWorkspaces();
297
+ return {
298
+ defaultWorkspaceId: listed.defaultWorkspaceId,
299
+ currentWorkspace: listed.workspaces.find((workspace) => workspace.isDefault)
300
+ };
301
+ }
302
+ export async function useWorkspace(options) {
303
+ const requestedWorkspaceId = options.workspaceId.trim();
304
+ if (!requestedWorkspaceId) {
305
+ throw new Error("workspaceId is required.");
306
+ }
307
+ const config = await readCliConfig();
308
+ const listed = await listAvailableWorkspaces();
309
+ const matched = listed.workspaces.find((workspace) => workspace.id === requestedWorkspaceId);
310
+ if (!matched) {
311
+ throw new Error(`Workspace not found or not accessible: ${requestedWorkspaceId}`);
312
+ }
313
+ await writeCliConfig({
314
+ ...config,
315
+ defaultWorkspaceId: matched.id
316
+ });
317
+ return {
318
+ defaultWorkspaceId: matched.id,
319
+ workspace: matched
320
+ };
321
+ }
322
+ export async function clearWorkspace() {
323
+ const config = await readCliConfig();
324
+ await writeCliConfig({
325
+ ...config,
326
+ defaultWorkspaceId: undefined
327
+ });
328
+ return { cleared: true };
329
+ }
330
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/bin.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { register } from "tsx/esm/api";
3
+ register();
4
+ await import("./index.js");
5
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,QAAQ,EAAE,CAAC;AACX,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC"}