@nimbase/cli 0.1.0 → 0.2.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 (38) hide show
  1. package/dist/chunk-2BYB6W4B.js +44 -0
  2. package/dist/chunk-2BYB6W4B.js.map +1 -0
  3. package/dist/chunk-6MCLE65K.js +46 -0
  4. package/dist/chunk-6MCLE65K.js.map +1 -0
  5. package/dist/chunk-IJCEQQWX.js +150 -0
  6. package/dist/chunk-IJCEQQWX.js.map +1 -0
  7. package/dist/chunk-KKZVWJDK.js +528 -0
  8. package/dist/chunk-KKZVWJDK.js.map +1 -0
  9. package/dist/commands/auth/login.js +8 -32
  10. package/dist/commands/auth/login.js.map +1 -1
  11. package/dist/commands/auth/logout.js +14 -15
  12. package/dist/commands/auth/logout.js.map +1 -1
  13. package/dist/commands/auth/signup.js +18 -0
  14. package/dist/commands/auth/signup.js.map +1 -0
  15. package/dist/commands/auth/status.js +1 -1
  16. package/dist/commands/connector/connect.js +93 -0
  17. package/dist/commands/connector/connect.js.map +1 -0
  18. package/dist/commands/connector/list.js +42 -0
  19. package/dist/commands/connector/list.js.map +1 -0
  20. package/dist/commands/connector/revoke.js +50 -0
  21. package/dist/commands/connector/revoke.js.map +1 -0
  22. package/dist/commands/connector/status.js +46 -0
  23. package/dist/commands/connector/status.js.map +1 -0
  24. package/dist/commands/connector/sync.js +57 -0
  25. package/dist/commands/connector/sync.js.map +1 -0
  26. package/dist/commands/workspace/create.js +2 -4
  27. package/dist/commands/workspace/create.js.map +1 -1
  28. package/dist/commands/workspace/current.js +2 -4
  29. package/dist/commands/workspace/current.js.map +1 -1
  30. package/dist/commands/workspace/list.js +2 -4
  31. package/dist/commands/workspace/list.js.map +1 -1
  32. package/dist/commands/workspace/select.js +2 -4
  33. package/dist/commands/workspace/select.js.map +1 -1
  34. package/package.json +13 -3
  35. package/dist/chunk-YQIGSGD4.js +0 -293
  36. package/dist/chunk-YQIGSGD4.js.map +0 -1
  37. package/dist/chunk-Z6XCOT3K.js +0 -35
  38. package/dist/chunk-Z6XCOT3K.js.map +0 -1
@@ -0,0 +1,528 @@
1
+ // src/credentials.ts
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ import { z as z2 } from "zod/v4";
5
+
6
+ // src/env.ts
7
+ import { createEnv } from "@t3-oss/env-core";
8
+ import { z } from "zod/v4";
9
+ var DEFAULT_API_URL = "https://api.nimbase.ai";
10
+ var DEFAULT_APP_URL = "https://app.nimbase.ai";
11
+ if (process.env.NIMBASE_API_URL && !process.env.NIMBASE_CLI_API_URL) {
12
+ console.warn(
13
+ `Warning: the CLI ignores NIMBASE_API_URL. Set NIMBASE_CLI_API_URL to choose an API origin; using ${DEFAULT_API_URL}.`
14
+ );
15
+ }
16
+ var env = createEnv({
17
+ server: {
18
+ HOME: z.string().optional(),
19
+ NIMBASE_CLI_API_URL: z.url().default(DEFAULT_API_URL),
20
+ NIMBASE_CLI_APP_URL: z.url().default(DEFAULT_APP_URL),
21
+ XDG_CONFIG_HOME: z.string().optional()
22
+ },
23
+ runtimeEnv: process.env,
24
+ emptyStringAsUndefined: true,
25
+ onValidationError: (issues) => {
26
+ for (const issue of issues) {
27
+ const variable = issue.path?.join(".") ?? "environment variable";
28
+ console.error(`Error: ${variable} is invalid: ${issue.message}.`);
29
+ }
30
+ console.error(
31
+ `Set NIMBASE_CLI_API_URL to an API origin such as http://localhost:3001 and NIMBASE_CLI_APP_URL to a web origin such as http://localhost:3000, or unset them to use the production defaults.`
32
+ );
33
+ process.exit(2);
34
+ }
35
+ });
36
+
37
+ // src/private-json-file.ts
38
+ import { randomUUID } from "crypto";
39
+ import {
40
+ chmod,
41
+ mkdir,
42
+ readFile,
43
+ rename,
44
+ rm,
45
+ writeFile
46
+ } from "fs/promises";
47
+ import { dirname } from "path";
48
+ async function readValidatedJsonFile(path, schema, description) {
49
+ let contents;
50
+ try {
51
+ contents = await readFile(path, "utf8");
52
+ } catch (error) {
53
+ if (isMissingFile(error)) return null;
54
+ throw new Error(`Could not read ${description} at ${path}`, {
55
+ cause: error
56
+ });
57
+ }
58
+ try {
59
+ return schema.parse(JSON.parse(contents));
60
+ } catch {
61
+ await removePrivateFile(path);
62
+ return null;
63
+ }
64
+ }
65
+ async function writePrivateJsonFile(path, value) {
66
+ const directory = dirname(path);
67
+ const temporaryPath = `${path}.${randomUUID()}.tmp`;
68
+ await mkdir(directory, { recursive: true, mode: 448 });
69
+ await chmod(directory, 448);
70
+ try {
71
+ await writeFile(temporaryPath, `${JSON.stringify(value)}
72
+ `, {
73
+ flag: "wx",
74
+ mode: 384
75
+ });
76
+ await chmod(temporaryPath, 384);
77
+ await rename(temporaryPath, path);
78
+ } catch (error) {
79
+ await rm(temporaryPath, { force: true }).catch(() => void 0);
80
+ throw error;
81
+ }
82
+ }
83
+ async function removePrivateFile(path) {
84
+ await rm(path, { force: true });
85
+ }
86
+ function isMissingFile(error) {
87
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
88
+ }
89
+
90
+ // src/credentials.ts
91
+ var credentialsSchema = z2.object({
92
+ origin: z2.url(),
93
+ token: z2.string().min(1)
94
+ });
95
+ function apiOrigin(apiUrl) {
96
+ return new URL(apiUrl).origin;
97
+ }
98
+ function credentialsPath(environment = env) {
99
+ const configRoot = environment.XDG_CONFIG_HOME ?? join(environment.HOME ?? homedir(), ".config");
100
+ return join(configRoot, "nimbase", "credentials.json");
101
+ }
102
+ async function readSession(path = credentialsPath()) {
103
+ return readValidatedJsonFile(path, credentialsSchema, "CLI credentials");
104
+ }
105
+ async function writeSession(apiUrl, token, path = credentialsPath()) {
106
+ await writePrivateJsonFile(
107
+ path,
108
+ credentialsSchema.parse({ origin: apiOrigin(apiUrl), token })
109
+ );
110
+ }
111
+ async function clearSession(path = credentialsPath()) {
112
+ await removePrivateFile(path);
113
+ }
114
+
115
+ // src/preferences.ts
116
+ import { dirname as dirname2, join as join2 } from "path";
117
+ import { z as z3 } from "zod/v4";
118
+ var preferencesSchema = z3.object({ workspaceId: z3.uuid().optional() });
119
+ function preferencesPath() {
120
+ return join2(dirname2(credentialsPath()), "preferences.json");
121
+ }
122
+ async function readWorkspaceId(path = preferencesPath()) {
123
+ const value = await readValidatedJsonFile(
124
+ path,
125
+ preferencesSchema,
126
+ "CLI preferences"
127
+ );
128
+ return value?.workspaceId ?? null;
129
+ }
130
+ async function writeWorkspaceId(workspaceId, path = preferencesPath()) {
131
+ await writePrivateJsonFile(path, preferencesSchema.parse({ workspaceId }));
132
+ }
133
+ async function clearWorkspaceId(path = preferencesPath()) {
134
+ await removePrivateFile(path);
135
+ }
136
+
137
+ // src/base-command.ts
138
+ import { Command } from "@oclif/core";
139
+
140
+ // ../../packages/sdk/src/contracts.ts
141
+ import { z as z4 } from "zod/v4";
142
+
143
+ // ../../packages/knowledge/src/model.ts
144
+ var toKnowledgeItemId = (value) => value;
145
+
146
+ // ../../packages/sources/src/connector.ts
147
+ var toConnectorConnectionId = (value) => value;
148
+
149
+ // ../../packages/sources/src/model.ts
150
+ var toSourceId = (value) => value;
151
+
152
+ // ../../packages/tenancy/src/index.ts
153
+ var toWorkspaceId = (value) => value;
154
+
155
+ // ../../packages/sdk/src/contracts.ts
156
+ var userSchema = z4.object({
157
+ id: z4.string(),
158
+ name: z4.string(),
159
+ email: z4.string()
160
+ });
161
+ var sessionSchema = z4.object({ user: userSchema });
162
+ var workspaceSchema = z4.object({
163
+ id: z4.uuid(),
164
+ name: z4.string(),
165
+ slug: z4.string()
166
+ }).transform((workspace) => ({
167
+ ...workspace,
168
+ id: toWorkspaceId(workspace.id)
169
+ }));
170
+ var workspaceListSchema = z4.object({
171
+ workspaces: z4.array(workspaceSchema)
172
+ });
173
+ var workspaceCreatedSchema = z4.object({ workspace: workspaceSchema });
174
+ var connectorProviderSchema = z4.object({
175
+ provider: z4.string().min(1),
176
+ displayName: z4.string().min(1)
177
+ });
178
+ var connectorConnectionSchema = z4.object({
179
+ id: z4.uuid(),
180
+ workspaceId: z4.uuid(),
181
+ provider: z4.string().min(1),
182
+ displayName: z4.string().min(1),
183
+ externalAccountId: z4.string().min(1),
184
+ status: z4.enum(["active", "paused", "revoked"]),
185
+ lastSyncStartedAt: z4.iso.datetime().nullable(),
186
+ lastSyncCompletedAt: z4.iso.datetime().nullable(),
187
+ createdAt: z4.iso.datetime(),
188
+ updatedAt: z4.iso.datetime()
189
+ }).transform((connection) => ({
190
+ ...connection,
191
+ id: toConnectorConnectionId(connection.id),
192
+ workspaceId: toWorkspaceId(connection.workspaceId),
193
+ lastSyncStartedAt: connection.lastSyncStartedAt ? new Date(connection.lastSyncStartedAt) : null,
194
+ lastSyncCompletedAt: connection.lastSyncCompletedAt ? new Date(connection.lastSyncCompletedAt) : null,
195
+ createdAt: new Date(connection.createdAt),
196
+ updatedAt: new Date(connection.updatedAt)
197
+ }));
198
+ var connectorOverviewSchema = z4.object({
199
+ providers: z4.array(connectorProviderSchema),
200
+ connections: z4.array(connectorConnectionSchema)
201
+ });
202
+ var connectorAuthorizationSchema = z4.object({ url: z4.url() });
203
+ var connectorSyncSchema = z4.object({
204
+ jobId: z4.uuid(),
205
+ connectionId: z4.uuid(),
206
+ trigger: z4.enum(["connect", "manual", "scheduled", "continuation"]),
207
+ createdAt: z4.iso.datetime()
208
+ }).transform((sync) => ({
209
+ ...sync,
210
+ connectionId: toConnectorConnectionId(sync.connectionId),
211
+ createdAt: new Date(sync.createdAt)
212
+ }));
213
+ var connectorSyncResponseSchema = z4.object({
214
+ sync: connectorSyncSchema
215
+ });
216
+ var connectorSyncStatusSchema = z4.object({
217
+ jobId: z4.uuid(),
218
+ activeJobId: z4.uuid(),
219
+ connectionId: z4.uuid(),
220
+ trigger: z4.enum(["connect", "manual", "scheduled", "continuation"]),
221
+ status: z4.enum(["queued", "running", "succeeded", "failed", "cancelled"]),
222
+ attemptCount: z4.number().int().nonnegative(),
223
+ maxAttempts: z4.number().int().positive(),
224
+ createdAt: z4.iso.datetime(),
225
+ startedAt: z4.iso.datetime().nullable(),
226
+ availableAt: z4.iso.datetime().optional(),
227
+ finishedAt: z4.iso.datetime().optional(),
228
+ failureCode: z4.string().optional(),
229
+ lastFailureCode: z4.string().optional()
230
+ }).transform((status) => ({
231
+ ...status,
232
+ connectionId: toConnectorConnectionId(status.connectionId),
233
+ createdAt: new Date(status.createdAt),
234
+ startedAt: status.startedAt ? new Date(status.startedAt) : null,
235
+ ...status.availableAt ? { availableAt: new Date(status.availableAt) } : {},
236
+ ...status.finishedAt ? { finishedAt: new Date(status.finishedAt) } : {}
237
+ }));
238
+ var connectorRevokedSchema = z4.object({
239
+ revoked: z4.literal(true),
240
+ providerRevoked: z4.boolean()
241
+ });
242
+ var retrievalResponseSchema = z4.object({
243
+ kind: z4.literal("success"),
244
+ evidence: z4.array(
245
+ z4.object({
246
+ excerpt: z4.string(),
247
+ provenance: z4.object({
248
+ workspaceId: z4.uuid(),
249
+ knowledgeItemId: z4.uuid(),
250
+ sourceId: z4.uuid(),
251
+ sourceExternalId: z4.string(),
252
+ sourceRevisionKey: z4.string(),
253
+ observedAt: z4.iso.datetime()
254
+ }).transform((provenance) => ({
255
+ ...provenance,
256
+ workspaceId: toWorkspaceId(provenance.workspaceId),
257
+ knowledgeItemId: toKnowledgeItemId(provenance.knowledgeItemId),
258
+ sourceId: toSourceId(provenance.sourceId),
259
+ observedAt: new Date(provenance.observedAt)
260
+ }))
261
+ })
262
+ ),
263
+ retrievedAt: z4.iso.datetime().transform((value) => new Date(value))
264
+ });
265
+
266
+ // ../../packages/sdk/src/client.ts
267
+ var ApiError = class extends Error {
268
+ constructor(message, status) {
269
+ super(message);
270
+ this.status = status;
271
+ this.name = "ApiError";
272
+ }
273
+ status;
274
+ };
275
+ var NimbaseApi = class {
276
+ constructor(baseUrl, request = fetch, createRequestId = () => crypto.randomUUID()) {
277
+ this.baseUrl = baseUrl;
278
+ this.request = request;
279
+ this.createRequestId = createRequestId;
280
+ this.origin = new URL(baseUrl).origin;
281
+ }
282
+ baseUrl;
283
+ request;
284
+ createRequestId;
285
+ origin;
286
+ async signIn(email, password) {
287
+ const response = await this.request(this.url("/api/auth/sign-in/email"), {
288
+ method: "POST",
289
+ headers: {
290
+ "Content-Type": "application/json",
291
+ Origin: this.origin
292
+ },
293
+ body: JSON.stringify({ email, password })
294
+ });
295
+ if (!response.ok) throw await apiError(response, "Sign-in failed.");
296
+ const token = response.headers.get("set-auth-token");
297
+ if (!token) {
298
+ throw new Error("The server did not issue a CLI session token.");
299
+ }
300
+ return token;
301
+ }
302
+ async exchangeOneTimeToken(oneTimeToken) {
303
+ const response = await this.request(
304
+ this.url("/api/auth/cli-session/exchange"),
305
+ {
306
+ method: "POST",
307
+ headers: { "Content-Type": "application/json" },
308
+ body: JSON.stringify({ token: oneTimeToken })
309
+ }
310
+ );
311
+ if (!response.ok) {
312
+ throw await apiError(response, "Browser authentication failed.");
313
+ }
314
+ const body = await response.json().catch(() => null);
315
+ if (!isTokenResponse(body)) {
316
+ throw new Error("The server did not issue a CLI session token.");
317
+ }
318
+ return body.token;
319
+ }
320
+ async getUser(token) {
321
+ const response = await this.request(this.url("/api/auth/get-session"), {
322
+ headers: authorization(token)
323
+ });
324
+ if (!response.ok) throw await apiError(response, "Session expired.");
325
+ const session = sessionSchema.safeParse(await response.json());
326
+ if (!session.success) throw new ApiError("Session expired.", 401);
327
+ return session.data.user;
328
+ }
329
+ async signOut(token) {
330
+ const response = await this.request(this.url("/api/auth/sign-out"), {
331
+ method: "POST",
332
+ headers: {
333
+ ...authorization(token),
334
+ "Content-Type": "application/json",
335
+ Origin: this.origin
336
+ },
337
+ body: "{}"
338
+ });
339
+ if (!response.ok) throw await apiError(response, "Sign-out failed.");
340
+ }
341
+ async listWorkspaces(token) {
342
+ const response = await this.request(this.url("/api/workspaces"), {
343
+ headers: authorization(token)
344
+ });
345
+ if (!response.ok) {
346
+ throw await apiError(response, "Could not load workspaces.");
347
+ }
348
+ return workspaceListSchema.parse(await response.json()).workspaces;
349
+ }
350
+ async createWorkspace(token, name) {
351
+ const response = await this.request(this.url("/api/workspaces"), {
352
+ method: "POST",
353
+ headers: {
354
+ ...authorization(token),
355
+ "Content-Type": "application/json"
356
+ },
357
+ body: JSON.stringify({ requestId: this.createRequestId(), name })
358
+ });
359
+ if (!response.ok) {
360
+ throw await apiError(response, "Could not create the workspace.");
361
+ }
362
+ return workspaceCreatedSchema.parse(await response.json()).workspace;
363
+ }
364
+ async listConnectors(token, workspaceId) {
365
+ const response = await this.request(
366
+ this.url(`/api/workspaces/${encodeURIComponent(workspaceId)}/connectors`),
367
+ { headers: authorization(token) }
368
+ );
369
+ if (!response.ok) {
370
+ throw await apiError(response, "Could not load connectors.");
371
+ }
372
+ return connectorOverviewSchema.parse(await response.json());
373
+ }
374
+ async beginConnectorAuthorization(token, workspaceId, provider) {
375
+ const response = await this.request(
376
+ this.url(
377
+ `/api/workspaces/${encodeURIComponent(workspaceId)}/connectors/${encodeURIComponent(provider)}/authorizations`
378
+ ),
379
+ { method: "POST", headers: authorization(token) }
380
+ );
381
+ if (!response.ok) {
382
+ throw await apiError(
383
+ response,
384
+ `Could not start ${provider} authorization.`
385
+ );
386
+ }
387
+ return connectorAuthorizationSchema.parse(await response.json()).url;
388
+ }
389
+ async requestConnectorSync(token, workspaceId, connectionId) {
390
+ const response = await this.request(
391
+ this.url(
392
+ `/api/workspaces/${encodeURIComponent(workspaceId)}/connectors/${encodeURIComponent(connectionId)}/syncs`
393
+ ),
394
+ {
395
+ method: "POST",
396
+ headers: {
397
+ ...authorization(token),
398
+ "Content-Type": "application/json"
399
+ },
400
+ body: JSON.stringify({ requestId: this.createRequestId() })
401
+ }
402
+ );
403
+ if (!response.ok) {
404
+ throw await apiError(response, "Could not schedule connector sync.");
405
+ }
406
+ return connectorSyncResponseSchema.parse(await response.json()).sync;
407
+ }
408
+ async getConnectorSync(token, workspaceId, jobId) {
409
+ const response = await this.request(
410
+ this.url(
411
+ `/api/workspaces/${encodeURIComponent(workspaceId)}/connectors/syncs/${encodeURIComponent(jobId)}`
412
+ ),
413
+ { headers: authorization(token) }
414
+ );
415
+ if (!response.ok) {
416
+ throw await apiError(response, "Could not load connector sync.");
417
+ }
418
+ return connectorSyncStatusSchema.parse(await response.json());
419
+ }
420
+ async revokeConnector(token, workspaceId, connectionId) {
421
+ const response = await this.request(
422
+ this.url(
423
+ `/api/workspaces/${encodeURIComponent(workspaceId)}/connectors/${encodeURIComponent(connectionId)}/revoke`
424
+ ),
425
+ { method: "POST", headers: authorization(token) }
426
+ );
427
+ if (!response.ok) {
428
+ throw await apiError(response, "Could not revoke connector.");
429
+ }
430
+ const result = connectorRevokedSchema.parse(await response.json());
431
+ return { providerRevoked: result.providerRevoked };
432
+ }
433
+ async retrieve(token, workspaceId, query, limit = 10) {
434
+ const response = await this.request(
435
+ this.url(`/api/workspaces/${encodeURIComponent(workspaceId)}/retrieval`),
436
+ {
437
+ method: "POST",
438
+ headers: {
439
+ ...authorization(token),
440
+ "Content-Type": "application/json",
441
+ Origin: this.origin
442
+ },
443
+ body: JSON.stringify({ query, limit })
444
+ }
445
+ );
446
+ if (!response.ok) {
447
+ throw await apiError(response, "Could not retrieve workspace memory.");
448
+ }
449
+ return retrievalResponseSchema.parse(await response.json());
450
+ }
451
+ url(path) {
452
+ return new URL(path, this.baseUrl);
453
+ }
454
+ };
455
+ function isTokenResponse(value) {
456
+ return typeof value === "object" && value !== null && "token" in value && typeof value.token === "string" && value.token.length > 0;
457
+ }
458
+ function authorization(token) {
459
+ return { Authorization: `Bearer ${token}` };
460
+ }
461
+ async function apiError(response, fallback) {
462
+ const value = await response.json().catch(() => null);
463
+ if (typeof value === "object" && value !== null && "message" in value && typeof value.message === "string") {
464
+ return new ApiError(value.message, response.status);
465
+ }
466
+ return new ApiError(fallback, response.status);
467
+ }
468
+
469
+ // src/error-message.ts
470
+ function describeError(error, apiUrl) {
471
+ if (error instanceof ApiError) return error.message;
472
+ if (isNetworkError(error)) {
473
+ return `Could not reach Nimbase at ${apiUrl}. Check your connection, or set NIMBASE_CLI_API_URL to a different API origin.`;
474
+ }
475
+ return error instanceof Error ? error.message : "Something went wrong.";
476
+ }
477
+ function isNetworkError(error) {
478
+ return error instanceof TypeError && error.message.includes("fetch failed");
479
+ }
480
+
481
+ // src/base-command.ts
482
+ var NimbaseCommand = class extends Command {
483
+ apiUrl = env.NIMBASE_CLI_API_URL;
484
+ api = new NimbaseApi(this.apiUrl);
485
+ get origin() {
486
+ return apiOrigin(this.apiUrl);
487
+ }
488
+ async requireToken() {
489
+ const session = await readSession();
490
+ if (!session)
491
+ this.error("You are not signed in. Run `nimbase auth login`.");
492
+ if (session.origin !== this.origin) {
493
+ this.error(
494
+ `You are signed in to ${session.origin}, not ${this.origin}. Run \`nimbase auth login\` to sign in to ${this.origin}.`
495
+ );
496
+ }
497
+ return session.token;
498
+ }
499
+ async requireWorkspaceId() {
500
+ const workspaceId = await readWorkspaceId();
501
+ if (!workspaceId) {
502
+ this.error(
503
+ "No workspace selected. Run `nimbase workspace select <workspace>`."
504
+ );
505
+ }
506
+ return workspaceId;
507
+ }
508
+ async handleError(error) {
509
+ if (error instanceof ApiError && error.status === 401) {
510
+ await clearSession();
511
+ this.error("Your session has expired. Run `nimbase auth login` again.");
512
+ }
513
+ this.error(describeError(error, this.apiUrl));
514
+ }
515
+ };
516
+
517
+ export {
518
+ env,
519
+ readSession,
520
+ writeSession,
521
+ clearSession,
522
+ describeError,
523
+ readWorkspaceId,
524
+ writeWorkspaceId,
525
+ clearWorkspaceId,
526
+ NimbaseCommand
527
+ };
528
+ //# sourceMappingURL=chunk-KKZVWJDK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/credentials.ts","../src/env.ts","../src/private-json-file.ts","../src/preferences.ts","../src/base-command.ts","../../../packages/sdk/src/contracts.ts","../../../packages/knowledge/src/model.ts","../../../packages/sources/src/connector.ts","../../../packages/sources/src/model.ts","../../../packages/tenancy/src/index.ts","../../../packages/sdk/src/client.ts","../src/error-message.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { z } from \"zod/v4\";\n\nimport { env } from \"./env.js\";\nimport {\n readValidatedJsonFile,\n removePrivateFile,\n writePrivateJsonFile,\n} from \"./private-json-file.js\";\n\n/**\n * A session is bound to the API origin that issued it. Without the binding, a\n * token minted by one origin would be sent to whichever origin the current\n * environment points at.\n */\nconst credentialsSchema = z.object({\n origin: z.url(),\n token: z.string().min(1),\n});\n\nexport type Session = z.infer<typeof credentialsSchema>;\n\ninterface ConfigEnvironment {\n HOME?: string;\n XDG_CONFIG_HOME?: string;\n}\n\nexport function apiOrigin(apiUrl: string): string {\n return new URL(apiUrl).origin;\n}\n\nexport function credentialsPath(environment: ConfigEnvironment = env) {\n const configRoot =\n environment.XDG_CONFIG_HOME ??\n join(environment.HOME ?? homedir(), \".config\");\n return join(configRoot, \"nimbase\", \"credentials.json\");\n}\n\nexport async function readSession(\n path = credentialsPath(),\n): Promise<Session | null> {\n return readValidatedJsonFile(path, credentialsSchema, \"CLI credentials\");\n}\n\nexport async function writeSession(\n apiUrl: string,\n token: string,\n path = credentialsPath(),\n): Promise<void> {\n await writePrivateJsonFile(\n path,\n credentialsSchema.parse({ origin: apiOrigin(apiUrl), token }),\n );\n}\n\nexport async function clearSession(path = credentialsPath()): Promise<void> {\n await removePrivateFile(path);\n}\n","import { createEnv } from \"@t3-oss/env-core\";\nimport { z } from \"zod/v4\";\n\nconst DEFAULT_API_URL = \"https://api.nimbase.ai\";\nconst DEFAULT_APP_URL = \"https://app.nimbase.ai\";\n\n/**\n * The API server uses `NIMBASE_API_URL` for its own public origin, so the CLI\n * deliberately does not read that name: a shell carrying the server\n * environment must not silently retarget the CLI.\n */\nif (process.env.NIMBASE_API_URL && !process.env.NIMBASE_CLI_API_URL) {\n console.warn(\n `Warning: the CLI ignores NIMBASE_API_URL. Set NIMBASE_CLI_API_URL to choose an API origin; using ${DEFAULT_API_URL}.`,\n );\n}\n\nexport const env = createEnv({\n server: {\n HOME: z.string().optional(),\n NIMBASE_CLI_API_URL: z.url().default(DEFAULT_API_URL),\n NIMBASE_CLI_APP_URL: z.url().default(DEFAULT_APP_URL),\n XDG_CONFIG_HOME: z.string().optional(),\n },\n runtimeEnv: process.env,\n emptyStringAsUndefined: true,\n onValidationError: (issues) => {\n for (const issue of issues) {\n const variable = issue.path?.join(\".\") ?? \"environment variable\";\n console.error(`Error: ${variable} is invalid: ${issue.message}.`);\n }\n console.error(\n `Set NIMBASE_CLI_API_URL to an API origin such as http://localhost:3001 and NIMBASE_CLI_APP_URL to a web origin such as http://localhost:3000, or unset them to use the production defaults.`,\n );\n process.exit(2);\n },\n});\n","import { randomUUID } from \"node:crypto\";\nimport {\n chmod,\n mkdir,\n readFile,\n rename,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { ZodType } from \"zod/v4\";\n\nexport async function readValidatedJsonFile<T>(\n path: string,\n schema: ZodType<T>,\n description: string,\n): Promise<T | null> {\n let contents: string;\n try {\n contents = await readFile(path, \"utf8\");\n } catch (error) {\n if (isMissingFile(error)) return null;\n throw new Error(`Could not read ${description} at ${path}`, {\n cause: error,\n });\n }\n\n try {\n return schema.parse(JSON.parse(contents));\n } catch {\n await removePrivateFile(path);\n return null;\n }\n}\n\nexport async function writePrivateJsonFile(\n path: string,\n value: unknown,\n): Promise<void> {\n const directory = dirname(path);\n const temporaryPath = `${path}.${randomUUID()}.tmp`;\n await mkdir(directory, { recursive: true, mode: 0o700 });\n await chmod(directory, 0o700);\n try {\n await writeFile(temporaryPath, `${JSON.stringify(value)}\\n`, {\n flag: \"wx\",\n mode: 0o600,\n });\n await chmod(temporaryPath, 0o600);\n await rename(temporaryPath, path);\n } catch (error) {\n await rm(temporaryPath, { force: true }).catch(() => undefined);\n throw error;\n }\n}\n\nexport async function removePrivateFile(path: string): Promise<void> {\n await rm(path, { force: true });\n}\n\nfunction isMissingFile(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n );\n}\n","import { dirname, join } from \"node:path\";\nimport { z } from \"zod/v4\";\n\nimport { credentialsPath } from \"./credentials.js\";\nimport {\n readValidatedJsonFile,\n removePrivateFile,\n writePrivateJsonFile,\n} from \"./private-json-file.js\";\n\nconst preferencesSchema = z.object({ workspaceId: z.uuid().optional() });\n\nfunction preferencesPath(): string {\n return join(dirname(credentialsPath()), \"preferences.json\");\n}\n\nexport async function readWorkspaceId(\n path = preferencesPath(),\n): Promise<string | null> {\n const value = await readValidatedJsonFile(\n path,\n preferencesSchema,\n \"CLI preferences\",\n );\n return value?.workspaceId ?? null;\n}\n\nexport async function writeWorkspaceId(\n workspaceId: string,\n path = preferencesPath(),\n): Promise<void> {\n await writePrivateJsonFile(path, preferencesSchema.parse({ workspaceId }));\n}\n\nexport async function clearWorkspaceId(\n path = preferencesPath(),\n): Promise<void> {\n await removePrivateFile(path);\n}\n","import { Command } from \"@oclif/core\";\n\nimport { ApiError, NimbaseApi } from \"@nimbase/sdk\";\n\nimport { apiOrigin, clearSession, readSession } from \"./credentials.js\";\nimport { env } from \"./env.js\";\nimport { describeError } from \"./error-message.js\";\nimport { readWorkspaceId } from \"./preferences.js\";\n\nexport abstract class NimbaseCommand extends Command {\n protected readonly apiUrl = env.NIMBASE_CLI_API_URL;\n protected readonly api = new NimbaseApi(this.apiUrl);\n\n protected get origin(): string {\n return apiOrigin(this.apiUrl);\n }\n\n protected async requireToken(): Promise<string> {\n const session = await readSession();\n if (!session)\n this.error(\"You are not signed in. Run `nimbase auth login`.\");\n if (session.origin !== this.origin) {\n this.error(\n `You are signed in to ${session.origin}, not ${this.origin}. Run \\`nimbase auth login\\` to sign in to ${this.origin}.`,\n );\n }\n return session.token;\n }\n\n protected async requireWorkspaceId(): Promise<string> {\n const workspaceId = await readWorkspaceId();\n if (!workspaceId) {\n this.error(\n \"No workspace selected. Run `nimbase workspace select <workspace>`.\",\n );\n }\n return workspaceId;\n }\n\n protected async handleError(error: unknown): Promise<never> {\n if (error instanceof ApiError && error.status === 401) {\n await clearSession();\n this.error(\"Your session has expired. Run `nimbase auth login` again.\");\n }\n this.error(describeError(error, this.apiUrl));\n }\n}\n","import { z } from \"zod/v4\";\n\nimport { toKnowledgeItemId } from \"@nimbase/knowledge\";\nimport { toConnectorConnectionId, toSourceId } from \"@nimbase/sources\";\nimport { toWorkspaceId } from \"@nimbase/tenancy\";\n\nexport const userSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n});\n\nexport const sessionSchema = z.object({ user: userSchema });\n\nexport const workspaceSchema = z\n .object({\n id: z.uuid(),\n name: z.string(),\n slug: z.string(),\n })\n .transform((workspace) => ({\n ...workspace,\n id: toWorkspaceId(workspace.id),\n }));\n\nexport const workspaceListSchema = z.object({\n workspaces: z.array(workspaceSchema),\n});\n\nexport const workspaceCreatedSchema = z.object({ workspace: workspaceSchema });\n\nexport const connectorProviderSchema = z.object({\n provider: z.string().min(1),\n displayName: z.string().min(1),\n});\n\nexport const connectorConnectionSchema = z\n .object({\n id: z.uuid(),\n workspaceId: z.uuid(),\n provider: z.string().min(1),\n displayName: z.string().min(1),\n externalAccountId: z.string().min(1),\n status: z.enum([\"active\", \"paused\", \"revoked\"]),\n lastSyncStartedAt: z.iso.datetime().nullable(),\n lastSyncCompletedAt: z.iso.datetime().nullable(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n })\n .transform((connection) => ({\n ...connection,\n id: toConnectorConnectionId(connection.id),\n workspaceId: toWorkspaceId(connection.workspaceId),\n lastSyncStartedAt: connection.lastSyncStartedAt\n ? new Date(connection.lastSyncStartedAt)\n : null,\n lastSyncCompletedAt: connection.lastSyncCompletedAt\n ? new Date(connection.lastSyncCompletedAt)\n : null,\n createdAt: new Date(connection.createdAt),\n updatedAt: new Date(connection.updatedAt),\n }));\n\nexport const connectorOverviewSchema = z.object({\n providers: z.array(connectorProviderSchema),\n connections: z.array(connectorConnectionSchema),\n});\n\nexport const connectorAuthorizationSchema = z.object({ url: z.url() });\n\nexport const connectorSyncSchema = z\n .object({\n jobId: z.uuid(),\n connectionId: z.uuid(),\n trigger: z.enum([\"connect\", \"manual\", \"scheduled\", \"continuation\"]),\n createdAt: z.iso.datetime(),\n })\n .transform((sync) => ({\n ...sync,\n connectionId: toConnectorConnectionId(sync.connectionId),\n createdAt: new Date(sync.createdAt),\n }));\n\nexport const connectorSyncResponseSchema = z.object({\n sync: connectorSyncSchema,\n});\n\nexport const connectorSyncStatusSchema = z\n .object({\n jobId: z.uuid(),\n activeJobId: z.uuid(),\n connectionId: z.uuid(),\n trigger: z.enum([\"connect\", \"manual\", \"scheduled\", \"continuation\"]),\n status: z.enum([\"queued\", \"running\", \"succeeded\", \"failed\", \"cancelled\"]),\n attemptCount: z.number().int().nonnegative(),\n maxAttempts: z.number().int().positive(),\n createdAt: z.iso.datetime(),\n startedAt: z.iso.datetime().nullable(),\n availableAt: z.iso.datetime().optional(),\n finishedAt: z.iso.datetime().optional(),\n failureCode: z.string().optional(),\n lastFailureCode: z.string().optional(),\n })\n .transform((status) => ({\n ...status,\n connectionId: toConnectorConnectionId(status.connectionId),\n createdAt: new Date(status.createdAt),\n startedAt: status.startedAt ? new Date(status.startedAt) : null,\n ...(status.availableAt\n ? { availableAt: new Date(status.availableAt) }\n : {}),\n ...(status.finishedAt ? { finishedAt: new Date(status.finishedAt) } : {}),\n }));\n\nexport const connectorRevokedSchema = z.object({\n revoked: z.literal(true),\n providerRevoked: z.boolean(),\n});\n\nexport const retrievalResponseSchema = z.object({\n kind: z.literal(\"success\"),\n evidence: z.array(\n z.object({\n excerpt: z.string(),\n provenance: z\n .object({\n workspaceId: z.uuid(),\n knowledgeItemId: z.uuid(),\n sourceId: z.uuid(),\n sourceExternalId: z.string(),\n sourceRevisionKey: z.string(),\n observedAt: z.iso.datetime(),\n })\n .transform((provenance) => ({\n ...provenance,\n workspaceId: toWorkspaceId(provenance.workspaceId),\n knowledgeItemId: toKnowledgeItemId(provenance.knowledgeItemId),\n sourceId: toSourceId(provenance.sourceId),\n observedAt: new Date(provenance.observedAt),\n })),\n }),\n ),\n retrievedAt: z.iso.datetime().transform((value) => new Date(value)),\n});\n\nexport type User = z.infer<typeof userSchema>;\nexport type Workspace = z.infer<typeof workspaceSchema>;\nexport type RetrievalResult = z.infer<typeof retrievalResponseSchema>;\nexport type ConnectorProvider = z.infer<typeof connectorProviderSchema>;\nexport type ConnectorConnection = z.infer<typeof connectorConnectionSchema>;\nexport type ConnectorOverview = z.infer<typeof connectorOverviewSchema>;\nexport type ConnectorSync = z.infer<typeof connectorSyncSchema>;\nexport type ConnectorSyncStatus = z.infer<typeof connectorSyncStatusSchema>;\n","import type { SourceId } from \"@nimbase/sources\";\nimport type { WorkspaceId } from \"@nimbase/tenancy\";\n\ndeclare const knowledgeItemIdBrand: unique symbol;\n\nexport type KnowledgeItemId = string & {\n readonly [knowledgeItemIdBrand]: \"KnowledgeItemId\";\n};\n\nexport const toKnowledgeItemId = (value: string) => value as KnowledgeItemId;\n\nexport type JsonValue =\n | boolean\n | number\n | string\n | null\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n\nexport type KnowledgeMetadata = Readonly<Record<string, JsonValue>>;\n\nexport interface KnowledgeContent {\n mediaType: string;\n text: string;\n}\n\nexport interface KnowledgeProvenance {\n sourceId: SourceId;\n externalId: string;\n revisionKey: string;\n observedAt: Date;\n}\n\nexport interface KnowledgeItem {\n id: KnowledgeItemId;\n workspaceId: WorkspaceId;\n type: string;\n content: KnowledgeContent;\n provenance: KnowledgeProvenance;\n metadata: KnowledgeMetadata;\n createdAt: Date;\n updatedAt: Date;\n}\n","import type { ActorId } from \"@nimbase/access\";\nimport type { WorkspaceId } from \"@nimbase/tenancy\";\n\ndeclare const connectorConnectionIdBrand: unique symbol;\n\nexport type ConnectorConnectionId = string & {\n readonly [connectorConnectionIdBrand]: \"ConnectorConnectionId\";\n};\n\nexport const toConnectorConnectionId = (value: string) =>\n value as ConnectorConnectionId;\n\n/**\n * One authorized link between a workspace and a provider account. Credentials\n * are referenced, never embedded; provider-specific state lives in adapters.\n */\nexport interface ConnectorConnection {\n id: ConnectorConnectionId;\n workspaceId: WorkspaceId;\n /** The human whose authority created the connection and owns its syncs. */\n ownerActorId: ActorId;\n provider: string;\n externalAccountId: string;\n displayName: string;\n secretReference: string;\n status: \"active\" | \"paused\" | \"revoked\";\n lastSyncStartedAt: Date | null;\n lastSyncCompletedAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface ConnectorCheckpoint {\n connectionId: ConnectorConnectionId;\n workspaceId: WorkspaceId;\n stream: string;\n cursor: string;\n updatedAt: Date;\n}\n","import type { ActorId } from \"@nimbase/access\";\nimport type { WorkspaceId } from \"@nimbase/tenancy\";\n\nimport type { ConnectorConnectionId } from \"./connector\";\n\ndeclare const sourceIdBrand: unique symbol;\n\nexport type SourceId = string & {\n readonly [sourceIdBrand]: \"SourceId\";\n};\n\nexport const toSourceId = (value: string) => value as SourceId;\n\nexport interface Source {\n id: SourceId;\n workspaceId: WorkspaceId;\n connectionId?: ConnectorConnectionId;\n createdByActorId: ActorId;\n provider: string;\n externalId: string;\n name: string;\n createdAt: Date;\n updatedAt: Date;\n}\n","declare const workspaceIdBrand: unique symbol;\n\nexport type WorkspaceId = string & {\n readonly [workspaceIdBrand]: \"WorkspaceId\";\n};\n\nexport const toWorkspaceId = (value: string) => value as WorkspaceId;\n\nexport interface Workspace {\n id: WorkspaceId;\n slug: string;\n name: string;\n}\n","import type {\n ConnectorOverview,\n ConnectorSync,\n ConnectorSyncStatus,\n RetrievalResult,\n User,\n Workspace,\n} from \"./contracts\";\nimport {\n connectorAuthorizationSchema,\n connectorOverviewSchema,\n connectorRevokedSchema,\n connectorSyncResponseSchema,\n connectorSyncStatusSchema,\n retrievalResponseSchema,\n sessionSchema,\n workspaceCreatedSchema,\n workspaceListSchema,\n} from \"./contracts\";\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\nexport class NimbaseApi {\n private readonly origin: string;\n\n constructor(\n private readonly baseUrl: string,\n private readonly request: typeof fetch = fetch,\n private readonly createRequestId: () => string = () => crypto.randomUUID(),\n ) {\n this.origin = new URL(baseUrl).origin;\n }\n\n async signIn(email: string, password: string): Promise<string> {\n const response = await this.request(this.url(\"/api/auth/sign-in/email\"), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Origin: this.origin,\n },\n body: JSON.stringify({ email, password }),\n });\n if (!response.ok) throw await apiError(response, \"Sign-in failed.\");\n\n const token = response.headers.get(\"set-auth-token\");\n if (!token) {\n throw new Error(\"The server did not issue a CLI session token.\");\n }\n return token;\n }\n\n async exchangeOneTimeToken(oneTimeToken: string): Promise<string> {\n const response = await this.request(\n this.url(\"/api/auth/cli-session/exchange\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ token: oneTimeToken }),\n },\n );\n if (!response.ok) {\n throw await apiError(response, \"Browser authentication failed.\");\n }\n\n const body: unknown = await response.json().catch(() => null);\n if (!isTokenResponse(body)) {\n throw new Error(\"The server did not issue a CLI session token.\");\n }\n return body.token;\n }\n\n async getUser(token: string): Promise<User> {\n const response = await this.request(this.url(\"/api/auth/get-session\"), {\n headers: authorization(token),\n });\n if (!response.ok) throw await apiError(response, \"Session expired.\");\n const session = sessionSchema.safeParse(await response.json());\n if (!session.success) throw new ApiError(\"Session expired.\", 401);\n return session.data.user;\n }\n\n async signOut(token: string): Promise<void> {\n const response = await this.request(this.url(\"/api/auth/sign-out\"), {\n method: \"POST\",\n headers: {\n ...authorization(token),\n \"Content-Type\": \"application/json\",\n Origin: this.origin,\n },\n body: \"{}\",\n });\n if (!response.ok) throw await apiError(response, \"Sign-out failed.\");\n }\n\n async listWorkspaces(token: string): Promise<Workspace[]> {\n const response = await this.request(this.url(\"/api/workspaces\"), {\n headers: authorization(token),\n });\n if (!response.ok) {\n throw await apiError(response, \"Could not load workspaces.\");\n }\n return workspaceListSchema.parse(await response.json()).workspaces;\n }\n\n async createWorkspace(token: string, name: string): Promise<Workspace> {\n const response = await this.request(this.url(\"/api/workspaces\"), {\n method: \"POST\",\n headers: {\n ...authorization(token),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ requestId: this.createRequestId(), name }),\n });\n if (!response.ok) {\n throw await apiError(response, \"Could not create the workspace.\");\n }\n return workspaceCreatedSchema.parse(await response.json()).workspace;\n }\n\n async listConnectors(\n token: string,\n workspaceId: string,\n ): Promise<ConnectorOverview> {\n const response = await this.request(\n this.url(`/api/workspaces/${encodeURIComponent(workspaceId)}/connectors`),\n { headers: authorization(token) },\n );\n if (!response.ok) {\n throw await apiError(response, \"Could not load connectors.\");\n }\n return connectorOverviewSchema.parse(await response.json());\n }\n\n async beginConnectorAuthorization(\n token: string,\n workspaceId: string,\n provider: string,\n ): Promise<string> {\n const response = await this.request(\n this.url(\n `/api/workspaces/${encodeURIComponent(workspaceId)}/connectors/${encodeURIComponent(provider)}/authorizations`,\n ),\n { method: \"POST\", headers: authorization(token) },\n );\n if (!response.ok) {\n throw await apiError(\n response,\n `Could not start ${provider} authorization.`,\n );\n }\n return connectorAuthorizationSchema.parse(await response.json()).url;\n }\n\n async requestConnectorSync(\n token: string,\n workspaceId: string,\n connectionId: string,\n ): Promise<ConnectorSync> {\n const response = await this.request(\n this.url(\n `/api/workspaces/${encodeURIComponent(workspaceId)}/connectors/${encodeURIComponent(connectionId)}/syncs`,\n ),\n {\n method: \"POST\",\n headers: {\n ...authorization(token),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ requestId: this.createRequestId() }),\n },\n );\n if (!response.ok) {\n throw await apiError(response, \"Could not schedule connector sync.\");\n }\n return connectorSyncResponseSchema.parse(await response.json()).sync;\n }\n\n async getConnectorSync(\n token: string,\n workspaceId: string,\n jobId: string,\n ): Promise<ConnectorSyncStatus> {\n const response = await this.request(\n this.url(\n `/api/workspaces/${encodeURIComponent(workspaceId)}/connectors/syncs/${encodeURIComponent(jobId)}`,\n ),\n { headers: authorization(token) },\n );\n if (!response.ok) {\n throw await apiError(response, \"Could not load connector sync.\");\n }\n return connectorSyncStatusSchema.parse(await response.json());\n }\n\n async revokeConnector(\n token: string,\n workspaceId: string,\n connectionId: string,\n ): Promise<{ readonly providerRevoked: boolean }> {\n const response = await this.request(\n this.url(\n `/api/workspaces/${encodeURIComponent(workspaceId)}/connectors/${encodeURIComponent(connectionId)}/revoke`,\n ),\n { method: \"POST\", headers: authorization(token) },\n );\n if (!response.ok) {\n throw await apiError(response, \"Could not revoke connector.\");\n }\n const result = connectorRevokedSchema.parse(await response.json());\n return { providerRevoked: result.providerRevoked };\n }\n\n async retrieve(\n token: string,\n workspaceId: string,\n query: string,\n limit = 10,\n ): Promise<RetrievalResult> {\n const response = await this.request(\n this.url(`/api/workspaces/${encodeURIComponent(workspaceId)}/retrieval`),\n {\n method: \"POST\",\n headers: {\n ...authorization(token),\n \"Content-Type\": \"application/json\",\n Origin: this.origin,\n },\n body: JSON.stringify({ query, limit }),\n },\n );\n if (!response.ok) {\n throw await apiError(response, \"Could not retrieve workspace memory.\");\n }\n return retrievalResponseSchema.parse(await response.json());\n }\n\n private url(path: string): URL {\n return new URL(path, this.baseUrl);\n }\n}\n\nfunction isTokenResponse(value: unknown): value is { token: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"token\" in value &&\n typeof value.token === \"string\" &&\n value.token.length > 0\n );\n}\n\nfunction authorization(token: string): Record<string, string> {\n return { Authorization: `Bearer ${token}` };\n}\n\nasync function apiError(\n response: Response,\n fallback: string,\n): Promise<ApiError> {\n const value: unknown = await response.json().catch(() => null);\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"message\" in value &&\n typeof value.message === \"string\"\n ) {\n return new ApiError(value.message, response.status);\n }\n return new ApiError(fallback, response.status);\n}\n","import { ApiError } from \"@nimbase/sdk\";\n\n/**\n * Turns a thrown value into one sentence a signed-in user can act on.\n * Network failures reach us as a `TypeError` from `fetch`, whose message\n * (\"fetch failed\") says nothing about which origin was unreachable.\n */\nexport function describeError(error: unknown, apiUrl: string): string {\n if (error instanceof ApiError) return error.message;\n if (isNetworkError(error)) {\n return `Could not reach Nimbase at ${apiUrl}. Check your connection, or set NIMBASE_CLI_API_URL to a different API origin.`;\n }\n return error instanceof Error ? error.message : \"Something went wrong.\";\n}\n\nfunction isNetworkError(error: unknown): boolean {\n return error instanceof TypeError && error.message.includes(\"fetch failed\");\n}\n"],"mappings":"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","names":["z","z","dirname","join","z","z","join","dirname","z","z"]}
@@ -1,39 +1,15 @@
1
1
  import {
2
- NimbaseCommand,
3
- writeToken
4
- } from "../../chunk-YQIGSGD4.js";
2
+ BrowserAuthCommand
3
+ } from "../../chunk-2BYB6W4B.js";
4
+ import "../../chunk-IJCEQQWX.js";
5
+ import "../../chunk-KKZVWJDK.js";
5
6
 
6
7
  // src/commands/auth/login.ts
7
- import { password as passwordPrompt } from "@inquirer/prompts";
8
- import { Flags } from "@oclif/core";
9
- var Login = class _Login extends NimbaseCommand {
10
- static description = "Sign in to Nimbase";
11
- static examples = [
12
- "<%= config.bin %> <%= command.id %> --email you@example.com"
13
- ];
14
- static flags = {
15
- email: Flags.string({
16
- char: "e",
17
- description: "account email",
18
- required: true
19
- }),
20
- password: Flags.string({
21
- description: "account password (prefer the prompt)"
22
- })
23
- };
8
+ var Login = class _Login extends BrowserAuthCommand {
9
+ static description = "Sign in to the CLI through the Nimbase web app";
24
10
  async run() {
25
- const { flags } = await this.parse(_Login);
26
- const password = flags.password ?? await passwordPrompt({ message: "Password", mask: "*" });
27
- let token = null;
28
- try {
29
- token = await this.api.signIn(flags.email.trim(), password);
30
- const user = await this.api.getUser(token);
31
- await writeToken(token);
32
- this.log(`Signed in as ${user.email}.`);
33
- } catch (error) {
34
- if (token) await this.api.signOut(token).catch(() => void 0);
35
- await this.handleError(error);
36
- }
11
+ await this.parse(_Login);
12
+ await this.authenticateInBrowser("login");
37
13
  }
38
14
  };
39
15
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/auth/login.ts"],"sourcesContent":["import { password as passwordPrompt } from \"@inquirer/prompts\";\nimport { Flags } from \"@oclif/core\";\n\nimport { NimbaseCommand } from \"../../base-command.js\";\nimport { writeToken } from \"../../credentials.js\";\n\nexport default class Login extends NimbaseCommand {\n static description = \"Sign in to Nimbase\";\n static examples = [\n \"<%= config.bin %> <%= command.id %> --email you@example.com\",\n ];\n static flags = {\n email: Flags.string({\n char: \"e\",\n description: \"account email\",\n required: true,\n }),\n password: Flags.string({\n description: \"account password (prefer the prompt)\",\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Login);\n const password =\n flags.password ??\n (await passwordPrompt({ message: \"Password\", mask: \"*\" }));\n let token: string | null = null;\n try {\n token = await this.api.signIn(flags.email.trim(), password);\n const user = await this.api.getUser(token);\n await writeToken(token);\n this.log(`Signed in as ${user.email}.`);\n } catch (error) {\n if (token) await this.api.signOut(token).catch(() => undefined);\n await this.handleError(error);\n }\n }\n}\n"],"mappings":";;;;;;AAAA,SAAS,YAAY,sBAAsB;AAC3C,SAAS,aAAa;AAKtB,IAAqB,QAArB,MAAqB,eAAc,eAAe;AAAA,EAChD,OAAO,cAAc;AAAA,EACrB,OAAO,WAAW;AAAA,IAChB;AAAA,EACF;AAAA,EACA,OAAO,QAAQ;AAAA,IACb,OAAO,MAAM,OAAO;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ,CAAC;AAAA,IACD,UAAU,MAAM,OAAO;AAAA,MACrB,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,MAAK;AACxC,UAAM,WACJ,MAAM,YACL,MAAM,eAAe,EAAE,SAAS,YAAY,MAAM,IAAI,CAAC;AAC1D,QAAI,QAAuB;AAC3B,QAAI;AACF,cAAQ,MAAM,KAAK,IAAI,OAAO,MAAM,MAAM,KAAK,GAAG,QAAQ;AAC1D,YAAM,OAAO,MAAM,KAAK,IAAI,QAAQ,KAAK;AACzC,YAAM,WAAW,KAAK;AACtB,WAAK,IAAI,gBAAgB,KAAK,KAAK,GAAG;AAAA,IACxC,SAAS,OAAO;AACd,UAAI,MAAO,OAAM,KAAK,IAAI,QAAQ,KAAK,EAAE,MAAM,MAAM,MAAS;AAC9D,YAAM,KAAK,YAAY,KAAK;AAAA,IAC9B;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/commands/auth/login.ts"],"sourcesContent":["import { BrowserAuthCommand } from \"../../browser-auth-command.js\";\n\nexport default class Login extends BrowserAuthCommand {\n static description = \"Sign in to the CLI through the Nimbase web app\";\n\n async run(): Promise<void> {\n await this.parse(Login);\n await this.authenticateInBrowser(\"login\");\n }\n}\n"],"mappings":";;;;;;;AAEA,IAAqB,QAArB,MAAqB,eAAc,mBAAmB;AAAA,EACpD,OAAO,cAAc;AAAA,EAErB,MAAM,MAAqB;AACzB,UAAM,KAAK,MAAM,MAAK;AACtB,UAAM,KAAK,sBAAsB,OAAO;AAAA,EAC1C;AACF;","names":[]}