rekor-cli 0.1.19 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -43,7 +43,9 @@ function saveConfig(config) {
43
43
  // src/token-store.ts
44
44
  import * as fs from "fs";
45
45
  var KEYRING_SERVICE = "rekor";
46
- var KEYRING_ACCOUNT = "rec_token";
46
+ var KEY_REC = "rec_token";
47
+ var KEY_OAUTH_ACCESS = "oauth_access_token";
48
+ var KEY_OAUTH_REFRESH = "oauth_refresh_token";
47
49
  var keyringCache;
48
50
  async function getKeyring() {
49
51
  if (keyringCache !== void 0) return keyringCache;
@@ -74,17 +76,17 @@ async function getKeyring() {
74
76
  }
75
77
  return keyringCache;
76
78
  }
77
- function manualCleanupCommand() {
79
+ function manualCleanupCommand(account) {
78
80
  if (process.platform === "darwin") {
79
- return `security delete-generic-password -s ${KEYRING_SERVICE} -a ${KEYRING_ACCOUNT}`;
81
+ return `security delete-generic-password -s ${KEYRING_SERVICE} -a ${account}`;
80
82
  }
81
83
  if (process.platform === "win32") {
82
- return `cmdkey /delete:${KEYRING_SERVICE}/${KEYRING_ACCOUNT}`;
84
+ return `cmdkey /delete:${KEYRING_SERVICE}/${account}`;
83
85
  }
84
86
  if (process.platform === "linux") {
85
- return `secret-tool clear service ${KEYRING_SERVICE} account ${KEYRING_ACCOUNT}`;
87
+ return `secret-tool clear service ${KEYRING_SERVICE} account ${account}`;
86
88
  }
87
- return `(remove the entry with service="${KEYRING_SERVICE}" account="${KEYRING_ACCOUNT}" from your OS credential store)`;
89
+ return `(remove service="${KEYRING_SERVICE}" account="${account}" from your OS credential store)`;
88
90
  }
89
91
  function readConfigFile() {
90
92
  if (!fs.existsSync(CONFIG_FILE)) return null;
@@ -100,125 +102,314 @@ function writeConfigFile(data) {
100
102
  }
101
103
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), { mode: 384 });
102
104
  }
103
- function stripTokenFromFile() {
105
+ var StaleKeyringSlotError = class extends Error {
106
+ constructor(account) {
107
+ super(
108
+ `Stale credential remains in OS keychain slot "${account}" after delete. Clean it up manually and retry:
109
+ ${manualCleanupCommand(account)}`
110
+ );
111
+ this.account = account;
112
+ this.name = "StaleKeyringSlotError";
113
+ }
114
+ };
115
+ async function clearSlot(keyring, account) {
116
+ await keyring.deletePassword(KEYRING_SERVICE, account);
117
+ try {
118
+ return await keyring.getPassword(KEYRING_SERVICE, account) === null;
119
+ } catch {
120
+ return false;
121
+ }
122
+ }
123
+ function stripTokenFieldsFromFile() {
104
124
  const existing = readConfigFile();
105
- if (!existing || existing.token === void 0) return;
125
+ if (!existing) return;
126
+ if (existing.token === void 0 && existing.access_token === void 0 && existing.refresh_token === void 0) return;
106
127
  delete existing.token;
128
+ delete existing.access_token;
129
+ delete existing.refresh_token;
107
130
  writeConfigFile(existing);
108
131
  }
109
- async function migrateLegacyToken(keyring) {
110
- const existing = readConfigFile();
111
- if (!existing?.token) return null;
112
- const token = existing.token;
113
- if (!keyring) return token;
114
- let keyringHasToken = false;
115
- try {
116
- keyringHasToken = await keyring.getPassword(KEYRING_SERVICE, KEYRING_ACCOUNT) !== null;
117
- } catch {
118
- keyringHasToken = false;
132
+ function readMetadataExpiresAt() {
133
+ return readConfigFile()?.token_expires_at;
134
+ }
135
+ function writeMetadataExpiresAt(value) {
136
+ const existing = readConfigFile() ?? {};
137
+ if (value === void 0) {
138
+ delete existing.token_expires_at;
139
+ } else {
140
+ existing.token_expires_at = value;
119
141
  }
120
- if (keyringHasToken) {
121
- try {
122
- stripTokenFromFile();
123
- } catch (err) {
124
- console.warn(`rekor: failed to strip stale token from ${CONFIG_FILE} (${err.message}); will retry next run.`);
142
+ writeConfigFile(existing);
143
+ }
144
+ async function migrateLegacyFileToken(keyring) {
145
+ const existing = readConfigFile();
146
+ if (!existing) return null;
147
+ if (existing.access_token) {
148
+ const out = {
149
+ kind: "oauth",
150
+ access_token: existing.access_token,
151
+ refresh_token: existing.refresh_token,
152
+ expires_at: existing.token_expires_at
153
+ };
154
+ if (keyring) {
155
+ try {
156
+ const accessExisting = await keyring.getPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS);
157
+ if (!accessExisting) {
158
+ await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS, existing.access_token);
159
+ if (existing.refresh_token) {
160
+ await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH, existing.refresh_token);
161
+ }
162
+ }
163
+ try {
164
+ stripTokenFieldsFromFile();
165
+ } catch (err) {
166
+ console.warn(`rekor: failed to strip legacy OAuth tokens from ${CONFIG_FILE} (${err.message}).`);
167
+ }
168
+ } catch (err) {
169
+ console.warn(`rekor: OAuth migration to keychain failed (${err.message}); continuing with file-backed.`);
170
+ }
125
171
  }
126
- return null;
172
+ return out;
127
173
  }
128
- try {
129
- await keyring.setPassword(KEYRING_SERVICE, KEYRING_ACCOUNT, token);
174
+ if (existing.token) {
175
+ const token = existing.token;
176
+ if (!keyring) return { kind: "rec", token };
130
177
  try {
131
- stripTokenFromFile();
178
+ const recExisting = await keyring.getPassword(KEYRING_SERVICE, KEY_REC);
179
+ if (recExisting) {
180
+ try {
181
+ stripTokenFieldsFromFile();
182
+ } catch (err) {
183
+ console.warn(`rekor: failed to strip stale token from ${CONFIG_FILE} (${err.message}).`);
184
+ }
185
+ return null;
186
+ }
187
+ await keyring.setPassword(KEYRING_SERVICE, KEY_REC, token);
188
+ try {
189
+ stripTokenFieldsFromFile();
190
+ } catch (err) {
191
+ console.warn(`rekor: failed to strip legacy token from ${CONFIG_FILE} (${err.message}).`);
192
+ }
132
193
  } catch (err) {
133
- console.warn(`rekor: failed to strip legacy token from ${CONFIG_FILE} (${err.message}); will retry next run.`);
194
+ console.warn(`rekor: keychain migration failed (${err.message}); continuing with file-backed token.`);
134
195
  }
135
- } catch (err) {
136
- console.warn(`rekor: keyring migration failed (${err.message}); continuing with file-backed token.`);
196
+ return { kind: "rec", token };
137
197
  }
138
- return token;
198
+ return null;
139
199
  }
140
- async function getToken() {
200
+ async function getResolvedToken() {
141
201
  const envToken = process.env["REKOR_TOKEN"];
142
- if (envToken) return envToken;
202
+ if (envToken) {
203
+ return { kind: "rec", token: envToken };
204
+ }
143
205
  const keyring = await getKeyring();
144
- const migrated = await migrateLegacyToken(keyring);
206
+ const migrated = await migrateLegacyFileToken(keyring);
145
207
  if (migrated) return migrated;
146
208
  if (keyring) {
147
- const stored = await keyring.getPassword(KEYRING_SERVICE, KEYRING_ACCOUNT);
148
- if (stored) return stored;
209
+ const [rec, access, refresh] = await Promise.all([
210
+ keyring.getPassword(KEYRING_SERVICE, KEY_REC),
211
+ keyring.getPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS),
212
+ keyring.getPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH)
213
+ ]);
214
+ if (rec) return { kind: "rec", token: rec };
215
+ if (access) {
216
+ const out = { kind: "oauth", access_token: access };
217
+ if (refresh) out.refresh_token = refresh;
218
+ const expiresAt = readMetadataExpiresAt();
219
+ if (expiresAt) out.expires_at = expiresAt;
220
+ return out;
221
+ }
149
222
  }
150
- const existing = readConfigFile();
151
- return existing?.token ?? null;
223
+ return null;
152
224
  }
153
- async function setToken(token) {
225
+ async function setRecToken(token) {
154
226
  const keyring = await getKeyring();
155
227
  if (keyring) {
156
228
  try {
157
- await keyring.setPassword(KEYRING_SERVICE, KEYRING_ACCOUNT, token);
229
+ const [accessCleared, refreshCleared] = await Promise.all([
230
+ clearSlot(keyring, KEY_OAUTH_ACCESS),
231
+ clearSlot(keyring, KEY_OAUTH_REFRESH)
232
+ ]);
233
+ const stuck = [
234
+ accessCleared ? null : KEY_OAUTH_ACCESS,
235
+ refreshCleared ? null : KEY_OAUTH_REFRESH
236
+ ].filter((a) => a !== null);
237
+ if (stuck.length > 0) {
238
+ console.warn(
239
+ [
240
+ `rekor: stale OAuth credential remains in OS keychain after delete. Commands work but logout won't fully clear. Manually:`,
241
+ ...stuck.map((a) => ` ${manualCleanupCommand(a)}`)
242
+ ].join("\n")
243
+ );
244
+ }
245
+ await keyring.setPassword(KEYRING_SERVICE, KEY_REC, token);
246
+ writeMetadataExpiresAt(void 0);
158
247
  try {
159
- stripTokenFromFile();
248
+ stripTokenFieldsFromFile();
160
249
  } catch (err) {
161
- console.warn(`rekor: failed to strip stale token from ${CONFIG_FILE} (${err.message}).`);
250
+ console.warn(`rekor: failed to strip stale tokens from ${CONFIG_FILE} (${err.message}).`);
162
251
  }
163
252
  return;
164
253
  } catch (err) {
165
- console.warn(`rekor: keyring write failed (${err.message}); falling back to file storage.`);
254
+ if (err instanceof StaleKeyringSlotError) throw err;
255
+ console.warn(`rekor: keychain write failed (${err.message}); falling back to file storage.`);
166
256
  }
167
257
  }
168
258
  const existing = readConfigFile() ?? {};
259
+ delete existing.access_token;
260
+ delete existing.refresh_token;
261
+ delete existing.token_expires_at;
169
262
  existing.token = token;
170
263
  writeConfigFile(existing);
171
264
  }
172
- async function clearToken() {
265
+ async function setOAuthTokens(accessToken, refreshToken, expiresAt) {
173
266
  const keyring = await getKeyring();
174
267
  if (keyring) {
175
- const deleted = await keyring.deletePassword(KEYRING_SERVICE, KEYRING_ACCOUNT);
176
- if (!deleted) {
177
- let stillThere = true;
268
+ try {
269
+ if (!await clearSlot(keyring, KEY_REC)) {
270
+ throw new StaleKeyringSlotError(KEY_REC);
271
+ }
272
+ await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS, accessToken);
273
+ if (refreshToken) {
274
+ await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH, refreshToken);
275
+ } else {
276
+ await clearSlot(keyring, KEY_OAUTH_REFRESH);
277
+ }
278
+ writeMetadataExpiresAt(expiresAt);
178
279
  try {
179
- stillThere = await keyring.getPassword(KEYRING_SERVICE, KEYRING_ACCOUNT) !== null;
180
- } catch {
181
- stillThere = true;
280
+ stripTokenFieldsFromFile();
281
+ } catch (err) {
282
+ console.warn(`rekor: failed to strip stale tokens from ${CONFIG_FILE} (${err.message}).`);
182
283
  }
183
- if (stillThere) {
284
+ return;
285
+ } catch (err) {
286
+ if (err instanceof StaleKeyringSlotError) throw err;
287
+ console.warn(`rekor: keychain write failed (${err.message}); falling back to file storage.`);
288
+ }
289
+ }
290
+ const existing = readConfigFile() ?? {};
291
+ delete existing.token;
292
+ existing.access_token = accessToken;
293
+ if (refreshToken) existing.refresh_token = refreshToken;
294
+ existing.token_expires_at = expiresAt;
295
+ writeConfigFile(existing);
296
+ }
297
+ async function clearAllTokens() {
298
+ const keyring = await getKeyring();
299
+ if (keyring) {
300
+ const slots = [KEY_REC, KEY_OAUTH_ACCESS, KEY_OAUTH_REFRESH];
301
+ const cleared = await Promise.all(slots.map((s) => clearSlot(keyring, s)));
302
+ for (const [i, ok] of cleared.entries()) {
303
+ if (!ok) {
304
+ const account = slots[i];
184
305
  console.warn(
185
- `rekor: could not clear keyring slot. Subsequent commands may still pick the stale token. Manually:
186
- ${manualCleanupCommand()}`
306
+ `rekor: could not clear keychain slot "${account}". Subsequent commands may still pick the stale token. Manually:
307
+ ${manualCleanupCommand(account)}`
187
308
  );
188
309
  }
189
310
  }
190
311
  }
191
312
  const existing = readConfigFile();
192
- if (existing && existing.token !== void 0) {
193
- delete existing.token;
194
- writeConfigFile(existing);
313
+ if (existing) {
314
+ let dirty = false;
315
+ for (const k of ["token", "access_token", "refresh_token", "token_expires_at"]) {
316
+ if (existing[k] !== void 0) {
317
+ delete existing[k];
318
+ dirty = true;
319
+ }
320
+ }
321
+ if (dirty) writeConfigFile(existing);
195
322
  }
196
323
  }
197
324
 
198
- // src/auth.ts
199
- async function login(token, apiUrl) {
200
- await setToken(token);
201
- const config = loadConfig();
202
- saveConfig({
203
- ...config,
204
- api_url: apiUrl ?? config.api_url
325
+ // src/oauth.ts
326
+ import * as http from "http";
327
+ var OAUTH_CALLBACK_PORT = 3927;
328
+ var DEFAULT_AUTHKIT_DOMAIN = "";
329
+ var DEFAULT_AUTHKIT_CLIENT_ID = "";
330
+ function getAuthKitDomain() {
331
+ const value = process.env["REKOR_AUTHKIT_DOMAIN"] || DEFAULT_AUTHKIT_DOMAIN;
332
+ if (!value) {
333
+ throw new Error("REKOR_AUTHKIT_DOMAIN is not configured \u2014 set the env var to your AuthKit tenant (e.g. https://<tenant>.authkit.app).");
334
+ }
335
+ return value;
336
+ }
337
+ function getAuthKitClientId() {
338
+ const value = process.env["REKOR_AUTHKIT_CLIENT_ID"] || DEFAULT_AUTHKIT_CLIENT_ID;
339
+ if (!value) {
340
+ throw new Error("REKOR_AUTHKIT_CLIENT_ID is not configured \u2014 set the env var to the AuthKit public PKCE client id registered for the Rekor CLI.");
341
+ }
342
+ return value;
343
+ }
344
+ function expiresInToIso(expiresInSeconds) {
345
+ return new Date(Date.now() + expiresInSeconds * 1e3).toISOString();
346
+ }
347
+ function asTokenResponse(value) {
348
+ if (typeof value !== "object" || value === null) {
349
+ throw new Error("AuthKit returned a non-object token payload");
350
+ }
351
+ const v = value;
352
+ if (typeof v.access_token !== "string" || typeof v.expires_in !== "number") {
353
+ throw new Error("AuthKit token payload missing required fields");
354
+ }
355
+ const out = { access_token: v.access_token, expires_in: v.expires_in };
356
+ if (typeof v.refresh_token === "string") out.refresh_token = v.refresh_token;
357
+ return out;
358
+ }
359
+ async function exchangeCodeForTokens(authkitDomain, clientId, code, codeVerifier, redirectUri) {
360
+ const response = await fetch(`${authkitDomain}/oauth2/token`, {
361
+ method: "POST",
362
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
363
+ body: new URLSearchParams({
364
+ grant_type: "authorization_code",
365
+ code,
366
+ code_verifier: codeVerifier,
367
+ redirect_uri: redirectUri,
368
+ client_id: clientId
369
+ }).toString()
205
370
  });
371
+ if (!response.ok) {
372
+ const body = await response.text();
373
+ throw new Error(`Token exchange failed (${response.status}): ${body}`);
374
+ }
375
+ return asTokenResponse(await response.json());
206
376
  }
207
-
208
- // src/browser-login.ts
209
- import { createServer } from "http";
210
- import { randomBytes } from "crypto";
211
- var DEFAULT_APP_URL = "https://rekor.pro";
212
- var TIMEOUT_MS = 12e4;
213
- var FALLBACK_URL_DELAY_MS = 5e3;
214
- async function browserLogin(apiUrl) {
215
- const open = await import("open").then((m) => m.default);
216
- const state = randomBytes(32).toString("hex");
217
- const config = loadConfig();
218
- let handled = false;
377
+ var SessionExpiredError = class extends Error {
378
+ constructor() {
379
+ super("SESSION_EXPIRED");
380
+ this.name = "SessionExpiredError";
381
+ }
382
+ };
383
+ async function refreshAccessToken(authkitDomain, clientId, refreshToken) {
384
+ const response = await fetch(`${authkitDomain}/oauth2/token`, {
385
+ method: "POST",
386
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
387
+ body: new URLSearchParams({
388
+ grant_type: "refresh_token",
389
+ refresh_token: refreshToken,
390
+ client_id: clientId
391
+ }).toString()
392
+ });
393
+ if (!response.ok) {
394
+ const status = response.status;
395
+ const body = await response.text();
396
+ if (status === 400 || status === 401) {
397
+ try {
398
+ const parsed = JSON.parse(body);
399
+ if (parsed.error === "invalid_grant") throw new SessionExpiredError();
400
+ } catch (err) {
401
+ if (err instanceof SessionExpiredError) throw err;
402
+ }
403
+ }
404
+ throw new Error(`Token refresh failed (${status}): ${body}`);
405
+ }
406
+ return asTokenResponse(await response.json());
407
+ }
408
+ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
219
409
  return new Promise((resolve, reject) => {
220
- const server = createServer((req, res) => {
221
- const url = new URL(req.url, `http://127.0.0.1`);
410
+ let handled = false;
411
+ const server = http.createServer((req, res) => {
412
+ const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
222
413
  if (url.pathname !== "/callback") {
223
414
  res.writeHead(404);
224
415
  res.end();
@@ -229,144 +420,200 @@ async function browserLogin(apiUrl) {
229
420
  res.end();
230
421
  return;
231
422
  }
232
- const token = url.searchParams.get("token");
233
- const returnedState = url.searchParams.get("state");
234
- if (returnedState !== state) {
423
+ const code = url.searchParams.get("code");
424
+ const state = url.searchParams.get("state");
425
+ const error = url.searchParams.get("error");
426
+ const errorDescription = url.searchParams.get("error_description");
427
+ if (error) {
428
+ handled = true;
429
+ res.writeHead(400, { "Content-Type": "text/html" });
430
+ res.end(errorPage(errorDescription || error));
431
+ cleanup();
432
+ reject(new Error(`OAuth error: ${errorDescription || error}`));
433
+ return;
434
+ }
435
+ if (state !== expectedState) {
235
436
  handled = true;
236
437
  res.writeHead(400, { "Content-Type": "text/html" });
237
- res.end(errorPage("Authentication failed: state mismatch. Please try again."));
438
+ res.end(errorPage("Invalid state parameter"));
238
439
  cleanup();
239
- reject(new Error("State mismatch \u2014 possible CSRF attempt"));
440
+ reject(new Error("OAuth state mismatch \u2014 possible CSRF attempt"));
240
441
  return;
241
442
  }
242
- if (!token) {
443
+ if (!code) {
243
444
  handled = true;
244
445
  res.writeHead(400, { "Content-Type": "text/html" });
245
- res.end(errorPage("Authentication failed: no token received."));
446
+ res.end(errorPage("No authorization code received"));
246
447
  cleanup();
247
- reject(new Error("No token in callback"));
448
+ reject(new Error("No authorization code received"));
248
449
  return;
249
450
  }
250
451
  handled = true;
251
- const orgId = url.searchParams.get("org_id") ?? void 0;
252
- const persist = async () => {
253
- await setToken(token);
254
- saveConfig({
255
- ...config,
256
- api_url: apiUrl ?? config.api_url,
257
- org_id: orgId
258
- });
259
- };
260
- persist().then(
261
- () => {
262
- res.writeHead(200, { "Content-Type": "text/html" });
263
- res.end(successPage());
264
- cleanup();
265
- resolve();
266
- },
267
- (err) => {
268
- const safeMessage = err.message.replace(/rec_[A-Za-z0-9_-]+/g, "rec_[REDACTED]");
269
- console.error(`rekor: failed to store credentials \u2014 ${safeMessage}`);
270
- res.writeHead(500, { "Content-Type": "text/html" });
271
- res.end(errorPage("Failed to store credentials. Check your terminal for details."));
272
- cleanup();
273
- reject(err);
274
- }
275
- );
452
+ res.writeHead(200, { "Content-Type": "text/html" });
453
+ res.end(successPage());
454
+ cleanup();
455
+ resolve({ code });
276
456
  });
277
457
  const timeout = setTimeout(() => {
278
458
  cleanup();
279
- reject(new Error("Login timed out \u2014 no response from browser within 2 minutes"));
280
- }, TIMEOUT_MS);
281
- let fallbackTimer;
282
- let cleanedUp = false;
459
+ reject(new Error("Timed out waiting for login. Run `rekor login` again."));
460
+ }, timeoutMs);
283
461
  function cleanup() {
284
- if (cleanedUp) return;
285
- cleanedUp = true;
286
462
  clearTimeout(timeout);
287
- if (fallbackTimer) {
288
- clearTimeout(fallbackTimer);
289
- fallbackTimer = void 0;
290
- }
291
463
  server.close();
292
464
  }
293
- server.listen(0, "127.0.0.1", () => {
294
- const addr = server.address();
295
- if (!addr || typeof addr === "string") {
296
- cleanup();
297
- reject(new Error("Failed to start local server"));
298
- return;
465
+ server.on("error", (err) => {
466
+ cleanup();
467
+ if (err.code === "EADDRINUSE") {
468
+ reject(new Error(`Port ${port} is in use. Close the other process and retry.`));
469
+ } else {
470
+ reject(err);
299
471
  }
300
- const port = addr.port;
301
- const appUrl = process.env["REKOR_APP_URL"] || DEFAULT_APP_URL;
302
- const authUrl = `${appUrl}/cli-auth?port=${port}&state=${state}`;
303
- console.log("Opening browser for authentication...");
304
- fallbackTimer = setTimeout(() => {
305
- fallbackTimer = void 0;
306
- console.log(`If the browser didn't open, visit: ${authUrl}`);
307
- }, FALLBACK_URL_DELAY_MS);
308
- open(authUrl).catch(() => {
309
- if (!fallbackTimer) return;
310
- clearTimeout(fallbackTimer);
311
- fallbackTimer = void 0;
312
- console.log("Could not open browser automatically.");
313
- console.log(`Visit: ${authUrl}`);
314
- });
315
472
  });
473
+ server.listen(port, "127.0.0.1");
316
474
  });
317
475
  }
318
476
  function successPage() {
319
477
  return `<!DOCTYPE html>
320
- <html>
321
- <head><title>Rekor CLI</title></head>
478
+ <html><head><title>Rekor CLI</title></head>
322
479
  <body style="font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa;">
323
480
  <div style="text-align: center;">
324
481
  <h1 style="font-size: 1.25rem; font-weight: 600;">Authentication successful</h1>
325
482
  <p style="color: #666; margin-top: 0.5rem;">You can close this tab and return to your terminal.</p>
326
483
  </div>
327
- </body>
328
- </html>`;
484
+ </body></html>`;
485
+ }
486
+ function escapeHtml(input) {
487
+ return input.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
329
488
  }
330
489
  function errorPage(message) {
331
490
  return `<!DOCTYPE html>
332
- <html>
333
- <head><title>Rekor CLI</title></head>
491
+ <html><head><title>Rekor CLI</title></head>
334
492
  <body style="font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa;">
335
493
  <div style="text-align: center;">
336
494
  <h1 style="font-size: 1.25rem; font-weight: 600; color: #dc2626;">Authentication failed</h1>
337
- <p style="color: #666; margin-top: 0.5rem;">${message}</p>
495
+ <p style="color: #666; margin-top: 0.5rem;">${escapeHtml(message)}</p>
338
496
  </div>
339
- </body>
340
- </html>`;
497
+ </body></html>`;
498
+ }
499
+
500
+ // src/auth.ts
501
+ async function login(token, apiUrl) {
502
+ await setRecToken(token);
503
+ const config = loadConfig();
504
+ saveConfig({
505
+ ...config,
506
+ api_url: apiUrl ?? config.api_url
507
+ });
508
+ }
509
+ var REFRESH_LEEWAY_MS = 6e4;
510
+ async function getAccessToken() {
511
+ const resolved = await getResolvedToken();
512
+ if (!resolved) return null;
513
+ if (resolved.kind === "rec") return resolved.token;
514
+ const expiresAtMs = resolved.expires_at ? new Date(resolved.expires_at).getTime() : Number.NaN;
515
+ if (!Number.isFinite(expiresAtMs) || expiresAtMs > Date.now() + REFRESH_LEEWAY_MS) {
516
+ return resolved.access_token;
517
+ }
518
+ if (!resolved.refresh_token) {
519
+ throw new Error("Access token expired and no refresh token available. Run `rekor login` again.");
520
+ }
521
+ try {
522
+ const result = await refreshAccessToken(getAuthKitDomain(), getAuthKitClientId(), resolved.refresh_token);
523
+ const newExpiresAt = expiresInToIso(result.expires_in);
524
+ await setOAuthTokens(result.access_token, result.refresh_token ?? resolved.refresh_token, newExpiresAt);
525
+ return result.access_token;
526
+ } catch (err) {
527
+ if (err instanceof SessionExpiredError) {
528
+ await clearAllTokens();
529
+ throw new Error("Session expired. Run `rekor login` again.");
530
+ }
531
+ throw err;
532
+ }
533
+ }
534
+ async function currentAuthKind() {
535
+ const resolved = await getResolvedToken();
536
+ return resolved?.kind ?? null;
537
+ }
538
+
539
+ // src/pkce.ts
540
+ import * as crypto from "crypto";
541
+ function generateCodeVerifier() {
542
+ return crypto.randomBytes(32).toString("base64url");
543
+ }
544
+ function generateCodeChallenge(verifier) {
545
+ return crypto.createHash("sha256").update(verifier).digest().toString("base64url");
546
+ }
547
+ function generateState() {
548
+ return crypto.randomBytes(16).toString("base64url");
341
549
  }
342
550
 
343
551
  // src/commands/login.ts
552
+ var FALLBACK_URL_DELAY_MS = 5e3;
344
553
  var loginCommand = new Command("login").description("Authenticate with Rekor").option("--token <token>", "API key for headless/CI authentication (rec_...)").option("--api-url <url>", "API base URL").action(async (opts) => {
345
554
  if (opts.token) {
346
555
  await login(opts.token, opts.apiUrl);
347
556
  console.log("Authenticated successfully");
348
- } else {
349
- try {
350
- await browserLogin(opts.apiUrl);
351
- console.log("Authenticated successfully");
352
- } catch (err) {
353
- console.error(
354
- `Login failed: ${err instanceof Error ? err.message : "Unknown error"}`
355
- );
356
- process.exit(1);
357
- }
557
+ return;
558
+ }
559
+ try {
560
+ await browserLoginPkce(opts.apiUrl);
561
+ console.log("Authenticated successfully");
562
+ } catch (err) {
563
+ console.error(
564
+ `Login failed: ${err instanceof Error ? err.message : "Unknown error"}`
565
+ );
566
+ process.exit(1);
358
567
  }
359
568
  });
569
+ async function browserLoginPkce(apiUrl) {
570
+ const open = await import("open").then((m) => m.default);
571
+ const codeVerifier = generateCodeVerifier();
572
+ const codeChallenge = generateCodeChallenge(codeVerifier);
573
+ const state = generateState();
574
+ const port = OAUTH_CALLBACK_PORT;
575
+ const redirectUri = `http://127.0.0.1:${port}/callback`;
576
+ const authkitDomain = getAuthKitDomain();
577
+ const clientId = getAuthKitClientId();
578
+ const authorizeUrl = new URL(`${authkitDomain}/oauth2/authorize`);
579
+ authorizeUrl.searchParams.set("client_id", clientId);
580
+ authorizeUrl.searchParams.set("redirect_uri", redirectUri);
581
+ authorizeUrl.searchParams.set("response_type", "code");
582
+ authorizeUrl.searchParams.set("code_challenge", codeChallenge);
583
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
584
+ authorizeUrl.searchParams.set("state", state);
585
+ authorizeUrl.searchParams.set("scope", "openid profile email offline_access");
586
+ console.log("Opening browser for authentication...");
587
+ const callbackPromise = startCallbackServer(port, state);
588
+ let fallbackPrinted = false;
589
+ const fallbackTimer = setTimeout(() => {
590
+ fallbackPrinted = true;
591
+ console.log(`If the browser didn't open, visit: ${authorizeUrl.toString()}`);
592
+ }, FALLBACK_URL_DELAY_MS);
593
+ open(authorizeUrl.toString()).catch(() => {
594
+ if (fallbackPrinted) return;
595
+ clearTimeout(fallbackTimer);
596
+ console.log("Could not open browser automatically.");
597
+ console.log(`Visit: ${authorizeUrl.toString()}`);
598
+ });
599
+ let code;
600
+ try {
601
+ ({ code } = await callbackPromise);
602
+ } finally {
603
+ clearTimeout(fallbackTimer);
604
+ }
605
+ const tokens = await exchangeCodeForTokens(authkitDomain, clientId, code, codeVerifier, redirectUri);
606
+ const expiresAt = expiresInToIso(tokens.expires_in);
607
+ await setOAuthTokens(tokens.access_token, tokens.refresh_token, expiresAt);
608
+ const config = loadConfig();
609
+ saveConfig({
610
+ ...config,
611
+ api_url: apiUrl ?? config.api_url
612
+ });
613
+ }
360
614
 
361
615
  // src/commands/logout.ts
362
616
  import { Command as Command2 } from "commander";
363
- var logoutCommand = new Command2("logout").description("Remove stored authentication credentials").action(async () => {
364
- await clearToken();
365
- console.log("Logged out successfully");
366
- });
367
-
368
- // src/commands/workspaces.ts
369
- import { Command as Command3 } from "commander";
370
617
 
371
618
  // src/client.ts
372
619
  var ApiClient = class {
@@ -377,7 +624,7 @@ var ApiClient = class {
377
624
  this.baseUrl = config.api_url;
378
625
  }
379
626
  getToken() {
380
- if (!this._tokenPromise) this._tokenPromise = getToken();
627
+ if (!this._tokenPromise) this._tokenPromise = getAccessToken();
381
628
  return this._tokenPromise;
382
629
  }
383
630
  async authHeaders() {
@@ -414,6 +661,24 @@ var ApiClient = class {
414
661
  }
415
662
  };
416
663
 
664
+ // src/commands/logout.ts
665
+ var logoutCommand = new Command2("logout").description("Remove stored authentication credentials").action(async () => {
666
+ const kind = await currentAuthKind();
667
+ if (kind === "oauth") {
668
+ try {
669
+ const client = new ApiClient();
670
+ await client.request("POST", "/v1/auth/logout");
671
+ } catch (err) {
672
+ console.warn(`rekor: server-side logout failed (${err instanceof Error ? err.message : "unknown"}); clearing local credentials anyway.`);
673
+ }
674
+ }
675
+ await clearAllTokens();
676
+ console.log("Logged out successfully");
677
+ });
678
+
679
+ // src/commands/workspaces.ts
680
+ import { Command as Command3 } from "commander";
681
+
417
682
  // src/output.ts
418
683
  import chalk from "chalk";
419
684
  import Table from "cli-table3";
@@ -972,7 +1237,7 @@ tokensCommand.command("revoke <token_id>").description("Revoke an API token").ac
972
1237
  // package.json
973
1238
  var package_default = {
974
1239
  name: "rekor-cli",
975
- version: "0.1.19",
1240
+ version: "0.1.20",
976
1241
  type: "module",
977
1242
  engines: {
978
1243
  node: ">=20.0.0"
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/program.ts","../src/commands/login.ts","../src/config.ts","../src/token-store.ts","../src/auth.ts","../src/browser-login.ts","../src/commands/logout.ts","../src/commands/workspaces.ts","../src/client.ts","../src/output.ts","../src/helpers.ts","../src/commands/collections.ts","../src/commands/records.ts","../src/commands/sql.ts","../src/commands/relationships.ts","../src/commands/query-relationships.ts","../src/commands/attachments.ts","../src/commands/hooks.ts","../src/commands/triggers.ts","../src/commands/endpoints.ts","../src/commands/batch.ts","../src/commands/providers.ts","../src/commands/tokens.ts","../package.json","../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { loginCommand } from './commands/login.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { workspacesCommand } from './commands/workspaces.js';\nimport { collectionsCommand } from './commands/collections.js';\nimport { recordsCommand } from './commands/records.js';\nimport { sqlCommand } from './commands/sql.js';\nimport { relationshipsCommand } from './commands/relationships.js';\nimport { queryRelationshipsCommand } from './commands/query-relationships.js';\nimport { attachmentsCommand } from './commands/attachments.js';\nimport { hooksCommand } from './commands/hooks.js';\nimport { triggersCommand } from './commands/triggers.js';\nimport { endpointsCommand } from './commands/endpoints.js';\nimport { batchCommand } from './commands/batch.js';\nimport { providersCommand } from './commands/providers.js';\nimport { tokensCommand } from './commands/tokens.js';\nimport pkg from '../package.json' with { type: 'json' };\n\nexport const program = new Command('rekor')\n .description('Rekor CLI — System of Record for AI agents')\n .version(pkg.version)\n .option('--workspace <id>', 'Workspace ID')\n .option('--output <format>', 'Output format: json or table', 'table');\n\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(workspacesCommand);\nprogram.addCommand(collectionsCommand);\nprogram.addCommand(recordsCommand);\nprogram.addCommand(sqlCommand);\nprogram.addCommand(relationshipsCommand);\nprogram.addCommand(queryRelationshipsCommand);\nprogram.addCommand(attachmentsCommand);\nprogram.addCommand(hooksCommand);\nprogram.addCommand(triggersCommand);\nprogram.addCommand(batchCommand);\nprogram.addCommand(providersCommand);\nprogram.addCommand(tokensCommand);\nprogram.addCommand(endpointsCommand);\n","import { Command } from 'commander';\nimport { login } from '../auth.js';\nimport { browserLogin } from '../browser-login.js';\n\nexport const loginCommand = new Command('login')\n .description('Authenticate with Rekor')\n .option('--token <token>', 'API key for headless/CI authentication (rec_...)')\n .option('--api-url <url>', 'API base URL')\n .action(async (opts: { token?: string; apiUrl?: string }) => {\n if (opts.token) {\n await login(opts.token, opts.apiUrl);\n console.log('Authenticated successfully');\n } else {\n try {\n await browserLogin(opts.apiUrl);\n console.log('Authenticated successfully');\n } catch (err) {\n console.error(\n `Login failed: ${err instanceof Error ? err.message : 'Unknown error'}`,\n );\n process.exit(1);\n }\n }\n });\n","import { readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\nconst CONFIG_DIR = join(homedir(), '.config', 'rekor');\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.json');\n\nexport interface Config {\n api_url: string;\n default_workspace?: string;\n org_id?: string;\n}\n\ninterface ConfigFile extends Config {\n // Tokens may linger here from older CLI versions until token-store migrates them.\n token?: string;\n [key: string]: unknown;\n}\n\nexport function loadConfig(): Config {\n const envUrl = process.env['REKOR_API_URL'];\n\n try {\n const raw = readFileSync(CONFIG_FILE, 'utf-8');\n const stored = JSON.parse(raw) as ConfigFile;\n return {\n api_url: envUrl ?? stored.api_url ?? 'http://localhost:8787',\n default_workspace: stored.default_workspace,\n org_id: stored.org_id,\n };\n } catch {\n return {\n api_url: envUrl ?? 'http://localhost:8787',\n };\n }\n}\n\nexport function saveConfig(config: Config): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n let existing: ConfigFile = {} as ConfigFile;\n try {\n existing = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8')) as ConfigFile;\n } catch {\n existing = {} as ConfigFile;\n }\n const merged: ConfigFile = { ...existing, ...config };\n writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), { mode: 0o600 });\n}\n\nexport { CONFIG_DIR, CONFIG_FILE };\n","import * as fs from 'node:fs';\nimport { CONFIG_DIR, CONFIG_FILE } from './config.js';\n\nconst KEYRING_SERVICE = 'rekor';\nconst KEYRING_ACCOUNT = 'rec_token';\n\ninterface KeyringBinding {\n getPassword(service: string, account: string): Promise<string | null>;\n setPassword(service: string, account: string, password: string): Promise<void>;\n deletePassword(service: string, account: string): Promise<boolean>;\n}\n\nlet keyringCache: KeyringBinding | null | undefined;\n\nasync function getKeyring(): Promise<KeyringBinding | null> {\n if (keyringCache !== undefined) return keyringCache;\n try {\n const mod = await import('@napi-rs/keyring');\n const Entry = mod.Entry;\n keyringCache = {\n async getPassword(service, account) {\n try { return new Entry(service, account).getPassword(); } catch { return null; }\n },\n async setPassword(service, account, password) {\n new Entry(service, account).setPassword(password);\n },\n async deletePassword(service, account) {\n try { return new Entry(service, account).deletePassword(); } catch { return false; }\n },\n };\n } catch {\n keyringCache = null;\n }\n return keyringCache;\n}\n\nfunction manualCleanupCommand(): string {\n if (process.platform === 'darwin') {\n return `security delete-generic-password -s ${KEYRING_SERVICE} -a ${KEYRING_ACCOUNT}`;\n }\n if (process.platform === 'win32') {\n return `cmdkey /delete:${KEYRING_SERVICE}/${KEYRING_ACCOUNT}`;\n }\n if (process.platform === 'linux') {\n return `secret-tool clear service ${KEYRING_SERVICE} account ${KEYRING_ACCOUNT}`;\n }\n return `(remove the entry with service=\"${KEYRING_SERVICE}\" account=\"${KEYRING_ACCOUNT}\" from your OS credential store)`;\n}\n\ninterface LegacyConfigFile {\n api_url?: string;\n token?: string;\n default_workspace?: string;\n org_id?: string;\n [key: string]: unknown;\n}\n\nfunction readConfigFile(): LegacyConfigFile | null {\n if (!fs.existsSync(CONFIG_FILE)) return null;\n try {\n return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8')) as LegacyConfigFile;\n } catch {\n return null;\n }\n}\n\nfunction writeConfigFile(data: LegacyConfigFile): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), { mode: 0o600 });\n}\n\nfunction stripTokenFromFile(): void {\n const existing = readConfigFile();\n if (!existing || existing.token === undefined) return;\n delete existing.token;\n writeConfigFile(existing);\n}\n\nasync function migrateLegacyToken(keyring: KeyringBinding | null): Promise<string | null> {\n const existing = readConfigFile();\n if (!existing?.token) return null;\n const token = existing.token;\n if (!keyring) return token;\n // Keyring wins on conflict — strip stale file copy without overwriting.\n let keyringHasToken = false;\n try {\n keyringHasToken = (await keyring.getPassword(KEYRING_SERVICE, KEYRING_ACCOUNT)) !== null;\n } catch {\n keyringHasToken = false;\n }\n if (keyringHasToken) {\n try { stripTokenFromFile(); } catch (err) {\n console.warn(`rekor: failed to strip stale token from ${CONFIG_FILE} (${(err as Error).message}); will retry next run.`);\n }\n return null;\n }\n try {\n await keyring.setPassword(KEYRING_SERVICE, KEYRING_ACCOUNT, token);\n try { stripTokenFromFile(); } catch (err) {\n console.warn(`rekor: failed to strip legacy token from ${CONFIG_FILE} (${(err as Error).message}); will retry next run.`);\n }\n } catch (err) {\n console.warn(`rekor: keyring migration failed (${(err as Error).message}); continuing with file-backed token.`);\n }\n return token;\n}\n\nexport async function getToken(): Promise<string | null> {\n const envToken = process.env['REKOR_TOKEN'];\n if (envToken) return envToken;\n\n const keyring = await getKeyring();\n\n const migrated = await migrateLegacyToken(keyring);\n if (migrated) return migrated;\n\n if (keyring) {\n const stored = await keyring.getPassword(KEYRING_SERVICE, KEYRING_ACCOUNT);\n if (stored) return stored;\n }\n\n const existing = readConfigFile();\n return existing?.token ?? null;\n}\n\nexport async function setToken(token: string): Promise<void> {\n const keyring = await getKeyring();\n if (keyring) {\n try {\n await keyring.setPassword(KEYRING_SERVICE, KEYRING_ACCOUNT, token);\n try { stripTokenFromFile(); } catch (err) {\n console.warn(`rekor: failed to strip stale token from ${CONFIG_FILE} (${(err as Error).message}).`);\n }\n return;\n } catch (err) {\n console.warn(`rekor: keyring write failed (${(err as Error).message}); falling back to file storage.`);\n }\n }\n const existing = readConfigFile() ?? {};\n existing.token = token;\n writeConfigFile(existing);\n}\n\nexport async function clearToken(): Promise<void> {\n const keyring = await getKeyring();\n if (keyring) {\n const deleted = await keyring.deletePassword(KEYRING_SERVICE, KEYRING_ACCOUNT);\n // Only verify on reported failure — success path doesn't need a second RPC.\n if (!deleted) {\n let stillThere = true;\n try {\n stillThere = (await keyring.getPassword(KEYRING_SERVICE, KEYRING_ACCOUNT)) !== null;\n } catch {\n stillThere = true;\n }\n if (stillThere) {\n console.warn(\n `rekor: could not clear keyring slot. Subsequent commands may still pick the stale token. Manually:\\n ${manualCleanupCommand()}`,\n );\n }\n }\n }\n const existing = readConfigFile();\n if (existing && existing.token !== undefined) {\n delete existing.token;\n writeConfigFile(existing);\n }\n}\n\nexport function __setKeyringForTesting(binding: KeyringBinding | null): void {\n keyringCache = binding;\n}\n\nexport function __resetKeyringForTesting(): void {\n keyringCache = undefined;\n}\n","import { loadConfig, saveConfig } from './config.js';\nimport { setToken } from './token-store.js';\n\nexport async function login(token: string, apiUrl?: string): Promise<void> {\n await setToken(token);\n const config = loadConfig();\n saveConfig({\n ...config,\n api_url: apiUrl ?? config.api_url,\n });\n}\n","import { createServer } from 'node:http';\nimport { randomBytes } from 'node:crypto';\nimport { loadConfig, saveConfig } from './config.js';\nimport { setToken } from './token-store.js';\n\nconst DEFAULT_APP_URL = 'https://rekor.pro';\nconst TIMEOUT_MS = 120_000;\nexport const FALLBACK_URL_DELAY_MS = 5_000;\n\nexport async function browserLogin(apiUrl?: string): Promise<void> {\n const open = await import('open').then((m) => m.default);\n\n const state = randomBytes(32).toString('hex');\n const config = loadConfig();\n\n let handled = false;\n\n return new Promise<void>((resolve, reject) => {\n const server = createServer((req, res) => {\n const url = new URL(req.url!, `http://127.0.0.1`);\n\n if (url.pathname !== '/callback') {\n res.writeHead(404);\n res.end();\n return;\n }\n\n // Async persist() lets a second callback sneak in before the first finishes.\n if (handled) {\n res.writeHead(409);\n res.end();\n return;\n }\n\n const token = url.searchParams.get('token');\n const returnedState = url.searchParams.get('state');\n\n if (returnedState !== state) {\n handled = true;\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage('Authentication failed: state mismatch. Please try again.'));\n cleanup();\n reject(new Error('State mismatch — possible CSRF attempt'));\n return;\n }\n\n if (!token) {\n handled = true;\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage('Authentication failed: no token received.'));\n cleanup();\n reject(new Error('No token in callback'));\n return;\n }\n\n handled = true;\n const orgId = url.searchParams.get('org_id') ?? undefined;\n\n const persist = async () => {\n await setToken(token);\n saveConfig({\n ...config,\n api_url: apiUrl ?? config.api_url,\n org_id: orgId,\n });\n };\n\n persist().then(\n () => {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(successPage());\n cleanup();\n resolve();\n },\n (err: Error) => {\n // Keyring error messages can include the credential value on some platforms — redact rec_* before logging.\n const safeMessage = err.message.replace(/rec_[A-Za-z0-9_-]+/g, 'rec_[REDACTED]');\n console.error(`rekor: failed to store credentials — ${safeMessage}`);\n res.writeHead(500, { 'Content-Type': 'text/html' });\n res.end(errorPage('Failed to store credentials. Check your terminal for details.'));\n cleanup();\n reject(err);\n },\n );\n });\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Login timed out — no response from browser within 2 minutes'));\n }, TIMEOUT_MS);\n\n let fallbackTimer: ReturnType<typeof setTimeout> | undefined;\n let cleanedUp = false;\n\n function cleanup() {\n if (cleanedUp) return;\n cleanedUp = true;\n clearTimeout(timeout);\n if (fallbackTimer) {\n clearTimeout(fallbackTimer);\n fallbackTimer = undefined;\n }\n server.close();\n }\n\n server.listen(0, '127.0.0.1', () => {\n const addr = server.address();\n if (!addr || typeof addr === 'string') {\n cleanup();\n reject(new Error('Failed to start local server'));\n return;\n }\n\n const port = addr.port;\n const appUrl = process.env['REKOR_APP_URL'] || DEFAULT_APP_URL;\n const authUrl = `${appUrl}/cli-auth?port=${port}&state=${state}`;\n\n console.log('Opening browser for authentication...');\n\n // open() resolves on spawn, not browser launch — .catch() won't fire on SSH/headless even when no browser appears.\n fallbackTimer = setTimeout(() => {\n fallbackTimer = undefined;\n console.log(`If the browser didn't open, visit: ${authUrl}`);\n }, FALLBACK_URL_DELAY_MS);\n\n // fallbackTimer === undefined means either the timer already printed the URL,\n // or cleanup() ran because login completed.\n open(authUrl).catch(() => {\n if (!fallbackTimer) return;\n clearTimeout(fallbackTimer);\n fallbackTimer = undefined;\n console.log('Could not open browser automatically.');\n console.log(`Visit: ${authUrl}`);\n });\n });\n });\n}\n\nfunction successPage(): string {\n return `<!DOCTYPE html>\n<html>\n<head><title>Rekor CLI</title></head>\n<body style=\"font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa;\">\n <div style=\"text-align: center;\">\n <h1 style=\"font-size: 1.25rem; font-weight: 600;\">Authentication successful</h1>\n <p style=\"color: #666; margin-top: 0.5rem;\">You can close this tab and return to your terminal.</p>\n </div>\n</body>\n</html>`;\n}\n\nfunction errorPage(message: string): string {\n return `<!DOCTYPE html>\n<html>\n<head><title>Rekor CLI</title></head>\n<body style=\"font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa;\">\n <div style=\"text-align: center;\">\n <h1 style=\"font-size: 1.25rem; font-weight: 600; color: #dc2626;\">Authentication failed</h1>\n <p style=\"color: #666; margin-top: 0.5rem;\">${message}</p>\n </div>\n</body>\n</html>`;\n}\n","import { Command } from 'commander';\nimport { clearToken } from '../token-store.js';\n\nexport const logoutCommand = new Command('logout')\n .description('Remove stored authentication credentials')\n .action(async () => {\n await clearToken();\n console.log('Logged out successfully');\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getFormat } from '../helpers.js';\n\nexport const workspacesCommand = new Command('workspaces')\n .description('Manage workspaces');\n\nworkspacesCommand.command('list')\n .description('List all workspaces')\n .option('--tag <tag>', 'Filter by tag')\n .action(async function (this: Command, opts: { tag?: string }) {\n const client = new ApiClient();\n const qs = opts.tag ? `?tag=${encodeURIComponent(opts.tag)}` : '';\n const data = await client.request('GET', `/v1/workspaces${qs}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('get <id>')\n .description('Get a workspace')\n .action(async function (this: Command, id: string) {\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/workspaces/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('create <id>')\n .description('Create a workspace')\n .requiredOption('--name <name>', 'Workspace name')\n .option('--description <desc>', 'Description')\n .option('--tags <tags>', 'Comma-separated tags (e.g., client:acme,billing)')\n .action(async function (this: Command, id: string, opts: { name: string; description?: string; tags?: string }) {\n const client = new ApiClient();\n const body: Record<string, unknown> = {\n name: opts.name,\n description: opts.description,\n };\n if (opts.tags) {\n body['tags'] = opts.tags.split(',').map(t => t.trim());\n }\n const data = await client.request('PUT', `/v1/workspaces/${id}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('tag <id>')\n .description('Set tags on a workspace')\n .requiredOption('--tags <tags>', 'Comma-separated tags (e.g., client:acme,billing)')\n .action(async function (this: Command, id: string, opts: { tags: string }) {\n const client = new ApiClient();\n const data = await client.request('PUT', `/v1/workspaces/${id}`, {\n tags: opts.tags.split(',').map(t => t.trim()),\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('delete <id>')\n .description('Delete a workspace')\n .action(async (_id: string) => {\n const client = new ApiClient();\n await client.request('DELETE', `/v1/workspaces/${_id}`);\n console.log('Deleted');\n });\n\n// --- Environment commands ---\n\nworkspacesCommand.command('create-preview <production-id>')\n .description('Create a preview workspace linked to a production workspace')\n .requiredOption('--name <name>', 'Preview workspace name')\n .option('--description <desc>', 'Description')\n .action(async function (this: Command, productionId: string, opts: { name: string; description?: string }) {\n const client = new ApiClient();\n const data = await client.request('POST', `/v1/${productionId}/preview`, {\n name: opts.name,\n description: opts.description,\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('list-previews <production-id>')\n .description('List preview workspaces for a production workspace')\n .action(async function (this: Command, productionId: string) {\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${productionId}/previews`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('promote <production-id>')\n .description('Promote config from a preview workspace to production (human-only)')\n .requiredOption('--from <preview-id>', 'Source preview workspace ID')\n .option('--dry-run', 'Show what would change without applying')\n .option('--collections <ids>', 'Comma-separated collection IDs to promote', (v: string) => v.split(','))\n .option('--triggers <ids>', 'Comma-separated trigger IDs to promote', (v: string) => v.split(','))\n .option('--hooks <ids>', 'Comma-separated hook IDs to promote', (v: string) => v.split(','))\n .action(async function (\n this: Command,\n productionId: string,\n opts: { from: string; dryRun?: boolean; collections?: string[]; triggers?: string[]; hooks?: string[] },\n ) {\n const client = new ApiClient();\n const data = await client.request('POST', `/v1/${productionId}/promote`, {\n source_workspace_id: opts.from,\n dry_run: opts.dryRun ?? false,\n collections: opts.collections,\n triggers: opts.triggers,\n hooks: opts.hooks,\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('rollback <production-id>')\n .description('Rollback a promotion (human-only)')\n .requiredOption('--promotion <promotion-id>', 'Promotion ID to rollback')\n .action(async function (this: Command, productionId: string, opts: { promotion: string }) {\n const client = new ApiClient();\n const data = await client.request('POST', `/v1/${productionId}/promote/rollback`, {\n promotion_id: opts.promotion,\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('promotions <production-id>')\n .description('List promotion history for a production workspace')\n .action(async function (this: Command, productionId: string) {\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${productionId}/promotions`);\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { loadConfig } from './config.js';\nimport { getToken } from './token-store.js';\n\nexport class ApiClient {\n readonly baseUrl: string;\n private _tokenPromise: Promise<string | null> | undefined;\n\n constructor() {\n const config = loadConfig();\n this.baseUrl = config.api_url;\n }\n\n private getToken(): Promise<string | null> {\n if (!this._tokenPromise) this._tokenPromise = getToken();\n return this._tokenPromise;\n }\n\n private async authHeaders(): Promise<Record<string, string>> {\n const token = await this.getToken();\n return token ? { 'Authorization': `Bearer ${token}` } : {};\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n ...(await this.authHeaders()),\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const json = await res.json() as { data?: T; error?: { message: string } };\n if (!res.ok) {\n throw new Error(json.error?.message ?? `HTTP ${res.status}`);\n }\n return json.data as T;\n }\n\n async uploadFile(url: string, body: BodyInit, contentType: string): Promise<void> {\n const res = await fetch(url, {\n method: 'PUT',\n headers: {\n ...(await this.authHeaders()),\n 'Content-Type': contentType,\n },\n body,\n });\n if (!res.ok) {\n throw new Error(`Upload failed: HTTP ${res.status}`);\n }\n }\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport type OutputFormat = 'json' | 'table';\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n if (format === 'json') {\n return JSON.stringify(data, null, 2);\n }\n\n if (Array.isArray(data)) {\n return formatTable(data as Record<string, unknown>[]);\n }\n\n if (typeof data === 'object' && data !== null) {\n return formatKeyValue(data as Record<string, unknown>);\n }\n\n return String(data);\n}\n\nfunction formatTable(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return chalk.dim('No results');\n\n const keys = Object.keys(rows[0]!);\n const table = new Table({ head: keys.map(k => chalk.bold(k)) });\n\n for (const row of rows) {\n table.push(keys.map(k => {\n const val = row[k];\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n }));\n }\n\n return table.toString();\n}\n\nfunction formatKeyValue(obj: Record<string, unknown>): string {\n const table = new Table();\n for (const [key, value] of Object.entries(obj)) {\n const displayValue = typeof value === 'object' ? JSON.stringify(value) : String(value ?? '');\n table.push({ [chalk.bold(key)]: displayValue });\n }\n return table.toString();\n}\n","import { readFileSync } from 'fs';\nimport { Command } from 'commander';\nimport { type OutputFormat } from './output.js';\n\nexport function parseData(data: string): Record<string, unknown> {\n if (data.startsWith('@')) {\n const content = readFileSync(data.slice(1), 'utf-8');\n return JSON.parse(content) as Record<string, unknown>;\n }\n return JSON.parse(data) as Record<string, unknown>;\n}\n\nexport function getWorkspace(cmd: Command): string {\n // Walk up the command chain to find --workspace on the root program\n let current: Command | null = cmd;\n while (current) {\n const ws = current.opts().workspace as string | undefined;\n if (ws) return ws;\n current = current.parent;\n }\n console.error('Error: --workspace is required');\n return process.exit(1);\n}\n\nexport function getFormat(cmd: Command): OutputFormat {\n return (cmd.parent?.parent?.opts().output ?? cmd.parent?.opts().output ?? 'table') as OutputFormat;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\n\nexport const collectionsCommand = new Command('collections')\n .description('Manage collections');\n\ncollectionsCommand.command('list')\n .description('List all collections in a workspace')\n .action(async function (this: Command) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/collections`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ncollectionsCommand.command('get <id>')\n .description('Get a collection')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/collections/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ncollectionsCommand.command('upsert <id>')\n .description('Create or update a collection')\n .requiredOption('--name <name>', 'Collection name')\n .option('--description <desc>', 'Description')\n .option('--schema <json>', 'JSON Schema (inline JSON or @filename)')\n .option('--icon <icon>', 'Icon name')\n .option('--color <color>', 'Hex color')\n .option('--sources <json>', 'External sources config (inline JSON or @filename)')\n .action(async function (this: Command, id: string, opts: { name: string; description?: string; schema?: string; icon?: string; color?: string; sources?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const body: Record<string, unknown> = { name: opts.name };\n if (opts.description) body['description'] = opts.description;\n if (opts.schema) body['json_schema'] = parseData(opts.schema);\n if (opts.icon) body['icon'] = opts.icon;\n if (opts.color) body['color'] = opts.color;\n if (opts.sources) body['sources'] = parseData(opts.sources);\n const data = await client.request('PUT', `/v1/${ws}/collections/${id}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ncollectionsCommand.command('delete <id>')\n .description('Delete a collection')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/collections/${id}`);\n console.log('Deleted');\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\n\nexport const recordsCommand = new Command('records')\n .description('Manage records');\n\nrecordsCommand.command('upsert <collection>')\n .description('Create or update a record')\n .requiredOption('--data <json>', 'Record data (inline JSON or @filename)')\n .option('--id <id>', 'Internal record ID (UUID) to update a known record')\n .option('--external-id <id>', 'External/agent-supplied ID for idempotent upsert')\n .option('--external-source <source>', 'Source system for external_id (e.g. stripe)')\n .action(async function (this: Command, collection: string, opts: { data: string; id?: string; externalId?: string; externalSource?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const body: Record<string, unknown> = { data: parseData(opts.data) };\n if (opts.externalId) body['external_id'] = opts.externalId;\n if (opts.externalSource) body['external_source'] = opts.externalSource;\n const path = opts.id\n ? `/v1/${ws}/records/${collection}/${opts.id}`\n : `/v1/${ws}/records/${collection}`;\n const data = await client.request('PUT', path, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nrecordsCommand.command('get <collection> <id>')\n .description('Get a record by ID')\n .action(async function (this: Command, collection: string, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/records/${collection}/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nrecordsCommand.command('delete <collection> <id>')\n .description('Delete a record')\n .action(async function (this: Command, collection: string, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/records/${collection}/${id}`);\n console.log('Deleted');\n });\n","import { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const sqlCommand = new Command('sql')\n .description('Execute a read-only SQL query against workspace data')\n .argument('[query]', 'SQL query (SELECT only)')\n .option('--file <path>', 'Read SQL from a file instead of argument')\n .option('--param <kv...>', 'Named parameters as key=value pairs (e.g., --param status=issued)')\n .action(async function (this: Command, queryArg: string | undefined, opts: { file?: string; param?: string[] }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n\n let query: string;\n if (opts.file) {\n query = readFileSync(opts.file, 'utf-8').trim();\n } else if (queryArg) {\n query = queryArg;\n } else {\n console.error('Error: provide a SQL query as argument or via --file');\n process.exit(1);\n }\n\n const params: Record<string, unknown> = {};\n if (opts.param) {\n for (const kv of opts.param) {\n const eqIdx = kv.indexOf('=');\n if (eqIdx === -1) {\n console.error(`Error: invalid param format \"${kv}\", expected key=value`);\n process.exit(1);\n }\n params[kv.slice(0, eqIdx)] = kv.slice(eqIdx + 1);\n }\n }\n\n const body: Record<string, unknown> = { query };\n if (Object.keys(params).length > 0) body.params = params;\n\n const data = await client.request('POST', `/v1/${ws}/sql`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\n\nexport const relationshipsCommand = new Command('relationships')\n .description('Manage relationships between records');\n\nrelationshipsCommand.command('upsert')\n .description('Create or update a relationship')\n .requiredOption('--source <collection/id>', 'Source record (collection/id)')\n .requiredOption('--target <collection/id>', 'Target record (collection/id)')\n .requiredOption('--type <type>', 'Relationship type')\n .option('--id <id>', 'Relationship ID')\n .option('--data <json>', 'Relationship metadata (inline JSON or @filename)')\n .action(async function (this: Command, opts: { source: string; target: string; type: string; id?: string; data?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const [sourceCollection, sourceId] = opts.source.split('/');\n const [targetCollection, targetId] = opts.target.split('/');\n const body: Record<string, unknown> = {\n rel_type: opts.type,\n source_collection: sourceCollection,\n source_id: sourceId,\n target_collection: targetCollection,\n target_id: targetId,\n };\n if (opts.id) body['id'] = opts.id;\n if (opts.data) body['data'] = parseData(opts.data);\n const path = opts.id ? `/v1/${ws}/relationships/${opts.id}` : `/v1/${ws}/relationships`;\n const data = await client.request('PUT', path, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nrelationshipsCommand.command('get <id>')\n .description('Get a relationship by ID')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/relationships/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nrelationshipsCommand.command('delete <id>')\n .description('Delete a relationship')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/relationships/${id}`);\n console.log('Deleted');\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const queryRelationshipsCommand = new Command('query-relationships')\n .description('Query related records')\n .argument('<collection>', 'Collection of the source record')\n .argument('<id>', 'Source record ID')\n .option('--type <type>', 'Filter by relationship type')\n .option('--direction <dir>', 'Direction: outgoing, incoming, or both', 'both')\n .option('--limit <n>', 'Max results', '50')\n .option('--offset <n>', 'Skip results', '0')\n .action(async function (this: Command, collection: string, id: string, opts: { type?: string; direction: string; limit: string; offset: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const params = new URLSearchParams();\n if (opts.type) params.set('rel_type', opts.type);\n // Map user-friendly direction names to backend API terms\n const directionMap: Record<string, string> = { outgoing: 'source', incoming: 'target', both: 'both' };\n params.set('direction', directionMap[opts.direction] ?? opts.direction);\n params.set('limit', opts.limit);\n params.set('offset', opts.offset);\n const data = await client.request('GET', `/v1/${ws}/records/${collection}/${id}/related?${params.toString()}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const attachmentsCommand = new Command('attachments')\n .description('Manage record attachments');\n\nattachmentsCommand.command('upload <collection> <id>')\n .description('Get a presigned upload URL for a record attachment. With --file, uploads the file content in one step.')\n .requiredOption('--filename <name>', 'File name or path (e.g. docs/guide.md)')\n .option('--content-type <type>', 'MIME type', 'application/octet-stream')\n .option('--file <path>', 'Local file to upload (skips presigned URL output, uploads directly)')\n .action(async function (this: Command, collection: string, id: string, opts: { filename: string; contentType: string; file?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('POST', `/v1/${ws}/records/${collection}/${id}/attachments`, {\n filename: opts.filename,\n content_type: opts.contentType,\n }) as { upload_url: string; [key: string]: unknown };\n\n if (opts.file) {\n const body = readFileSync(opts.file);\n const uploadUrl = data.upload_url.startsWith('http') ? data.upload_url : `${client.baseUrl}${data.upload_url}`;\n await client.uploadFile(uploadUrl, body, opts.contentType);\n console.log(formatOutput({ ...data, uploaded: true }, getFormat(this)));\n } else {\n console.log(formatOutput(data, getFormat(this)));\n }\n });\n\nattachmentsCommand.command('url <collection> <id>')\n .description('Get a download URL for an attachment by filename')\n .requiredOption('--filename <name>', 'File name or path (e.g. docs/guide.md)')\n .action(async function (this: Command, collection: string, id: string, opts: { filename: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const attachments = await client.request<Array<{ key: string; size: number; uploaded: string }>>('GET', `/v1/${ws}/records/${collection}/${id}/attachments`);\n const match = attachments.find(a => a.key.endsWith(`/${opts.filename}`));\n if (!match) {\n throw new Error(`Attachment \"${opts.filename}\" not found`);\n }\n const downloadUrl = `${client.baseUrl}/v1/${ws}/attachments/${match.key}`;\n console.log(formatOutput({ download_url: downloadUrl, ...match }, getFormat(this)));\n });\n\nattachmentsCommand.command('list <collection> <id>')\n .description('List attachments for a record')\n .option('--prefix <path>', 'Filter by path prefix (e.g. docs/)')\n .action(async function (this: Command, collection: string, id: string, opts: { prefix?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const query = opts.prefix ? `?prefix=${encodeURIComponent(opts.prefix)}` : '';\n const data = await client.request('GET', `/v1/${ws}/records/${collection}/${id}/attachments${query}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nattachmentsCommand.command('delete <collection> <id> <attachment-id>')\n .description('Delete an attachment')\n .action(async function (this: Command, collection: string, id: string, attachmentId: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/records/${collection}/${id}/attachments/${attachmentId}`);\n console.log('Deleted');\n });\n","import { randomUUID } from 'crypto';\nimport { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const hooksCommand = new Command('hooks')\n .description('Manage inbound webhook endpoints');\n\nhooksCommand.command('create')\n .description('Create a new inbound hook')\n .requiredOption('--name <name>', 'Hook name')\n .requiredOption('--secret <secret>', 'HMAC shared secret')\n .option('--id <id>', 'Hook ID (auto-generated if omitted)')\n .option('--collection-scope <collections>', 'Comma-separated collection scope')\n .action(async function (this: Command, opts: { name: string; secret: string; id?: string; collectionScope?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const hookId = opts.id ?? randomUUID();\n const body: Record<string, unknown> = {\n name: opts.name,\n secret: opts.secret,\n enabled: true,\n };\n if (opts.collectionScope) {\n body['collection_scope'] = opts.collectionScope.split(',');\n }\n const data = await client.request('PUT', `/v1/${ws}/hooks/${hookId}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nhooksCommand.command('get <id>')\n .description('Get a hook')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/hooks/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nhooksCommand.command('list')\n .description('List all hooks')\n .action(async function (this: Command) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/hooks`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nhooksCommand.command('delete <id>')\n .description('Delete a hook')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/hooks/${id}`);\n console.log('Deleted');\n });\n","import { randomUUID } from 'crypto';\nimport { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const triggersCommand = new Command('triggers')\n .description('Manage outbound triggers');\n\ntriggersCommand.command('create')\n .description('Create an outbound trigger')\n .requiredOption('--name <name>', 'Trigger name')\n .requiredOption('--url <url>', 'Target URL')\n .requiredOption('--secret <secret>', 'HMAC signing secret')\n .requiredOption('--events <events>', 'Comma-separated event types')\n .option('--id <id>', 'Trigger ID (auto-generated if omitted)')\n .option('--collection-scope <collections>', 'Comma-separated collection scope')\n .option('--filter <json>', 'Filter expression (JSON)')\n .action(async function (this: Command, opts: { name: string; url: string; secret: string; events: string; id?: string; collectionScope?: string; filter?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const triggerId = opts.id ?? randomUUID();\n const body: Record<string, unknown> = {\n name: opts.name,\n url: opts.url,\n secret: opts.secret,\n events: opts.events.split(','),\n enabled: true,\n };\n if (opts.collectionScope) {\n body['collection_scope'] = opts.collectionScope.split(',');\n }\n if (opts.filter) {\n body['filter'] = JSON.parse(opts.filter);\n }\n const data = await client.request('PUT', `/v1/${ws}/triggers/${triggerId}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntriggersCommand.command('get <id>')\n .description('Get a trigger')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/triggers/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntriggersCommand.command('list')\n .description('List all triggers')\n .action(async function (this: Command) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/triggers`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntriggersCommand.command('delete <id>')\n .description('Delete a trigger')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/triggers/${id}`);\n console.log('Deleted');\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const endpointsCommand = new Command('endpoints')\n .description('Manage MCP Factory endpoints');\n\nendpointsCommand.command('upsert <slug>')\n .description('Create or update an MCP endpoint')\n .option('--name <name>', 'Endpoint display name (required unless using --config)')\n .option('--description <desc>', 'Endpoint description')\n .option('--tool <spec>', 'Collection tool spec: collection:op1,op2 (repeatable)', collect, [])\n .option('--relationship <spec>', 'Relationship tool spec: rel_type:op1,op2 (repeatable)', collect, [])\n .option('--batch <spec>', 'Batch operation spec: collection_or_rel:op1,op2 (repeatable)', collect, [])\n .option('--sql-query', 'Enable sql_query tool')\n .option('--config <json>', 'Full endpoint config as JSON (supports name_override, description_override per tool). Use @file.json to read from file.')\n .action(async function (this: Command, slug: string, opts: {\n name?: string;\n description?: string;\n tool: string[];\n relationship: string[];\n batch: string[];\n sqlQuery?: boolean;\n config?: string;\n }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n\n let body: Record<string, unknown>;\n\n if (opts.config) {\n // Full JSON config — supports name_override, description_override per tool\n body = JSON.parse(opts.config);\n } else {\n if (!opts.name) {\n throw new Error('--name is required (or use --config for full JSON config)');\n }\n body = {\n name: opts.name,\n tools: opts.tool.map(parseToolSpec),\n };\n\n if (opts.description) body.description = opts.description;\n\n if (opts.relationship.length > 0) {\n body.relationships = opts.relationship.map(parseRelSpec);\n }\n\n if (opts.batch.length > 0) {\n const operations: Record<string, string[]> = {};\n for (const spec of opts.batch) {\n const parsed = parseSpec(spec);\n operations[parsed.key] = parsed.ops;\n }\n body.batch = { enabled: true, operations };\n }\n\n if (opts.sqlQuery) body.sql_query = true;\n }\n\n const data = await client.request('PUT', `/v1/${ws}/endpoints/${slug}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nendpointsCommand.command('get <slug>')\n .description('Get an endpoint')\n .option('--resolved', 'Include resolved collection schemas')\n .action(async function (this: Command, slug: string, opts: { resolved?: boolean }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const path = opts.resolved\n ? `/v1/${ws}/endpoints/${slug}/resolved`\n : `/v1/${ws}/endpoints/${slug}`;\n const data = await client.request('GET', path);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nendpointsCommand.command('list')\n .description('List all endpoints')\n .action(async function (this: Command) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/endpoints`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nendpointsCommand.command('delete <slug>')\n .description('Delete an endpoint')\n .action(async function (this: Command, slug: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/endpoints/${slug}`);\n console.log('Deleted');\n });\n\nendpointsCommand.command('url <slug>')\n .description('Get the MCP connection URL for an endpoint')\n .option('--transport <type>', 'Transport: mcp or sse', 'mcp')\n .action((_slug: string, opts: { transport: string }) => {\n const transport = opts.transport === 'sse' ? 'sse' : 'mcp';\n console.log(`https://mcp.rekor.pro/e/${_slug}/${transport}`);\n });\n\n// ---- Helpers ----\n\nfunction collect(value: string, previous: string[]): string[] {\n return [...previous, value];\n}\n\nfunction parseSpec(spec: string): { key: string; ops: string[] } {\n const [key, opsStr] = spec.split(':');\n if (!key || !opsStr) {\n throw new Error(`Invalid spec '${spec}'. Expected format: name:op1,op2`);\n }\n return { key, ops: opsStr.split(',') };\n}\n\nfunction parseToolSpec(spec: string): Record<string, unknown> {\n const { key, ops } = parseSpec(spec);\n return { collection: key, operations: ops };\n}\n\nfunction parseRelSpec(spec: string): Record<string, unknown> {\n const { key, ops } = parseSpec(spec);\n return { rel_type: key, operations: ops };\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\n\nexport const batchCommand = new Command('batch')\n .description('Execute atomic batch operations (up to 1,000 operations)')\n .requiredOption('--operations <json>', 'Operations array (inline JSON or @filename)')\n .action(async function (this: Command, opts: { operations: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const operations = parseData(opts.operations);\n const data = await client.request('POST', `/v1/${ws}/batch`, {\n operations: Array.isArray(operations) ? operations : [operations],\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\nconst VALID_PROVIDERS = 'openai, anthropic, google, mcp';\n\nexport const providersCommand = new Command('providers')\n .description('Import/export tool definitions between LLM providers and Record collections');\n\nprovidersCommand.command('import <provider>')\n .description(`Import tool definitions as collections. Providers: ${VALID_PROVIDERS}`)\n .requiredOption('--tools <json>', 'Tool definitions (inline JSON or @filename)')\n .action(async function (this: Command, provider: string, opts: { tools: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const tools = parseData(opts.tools);\n const data = await client.request('POST', `/v1/${ws}/providers/${provider}/import`, {\n tools: Array.isArray(tools) ? tools : [tools],\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nprovidersCommand.command('export <provider>')\n .description(`Export collections as tool definitions. Providers: ${VALID_PROVIDERS}`)\n .option('--collections <ids>', 'Comma-separated collection IDs (omit for all)')\n .option('--output <file>', 'Write output to file')\n .action(async function (this: Command, provider: string, opts: { collections?: string; output?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const query = opts.collections ? `?collections=${opts.collections}` : '';\n const data = await client.request('GET', `/v1/${ws}/providers/${provider}/export${query}`);\n\n if (opts.output) {\n const { writeFileSync } = await import('fs');\n writeFileSync(opts.output, JSON.stringify(data, null, 2));\n console.log(`Written to ${opts.output}`);\n } else {\n console.log(formatOutput(data, getFormat(this)));\n }\n });\n\nprovidersCommand.command('import-call <provider> <collection>')\n .description(`Create a record from a tool call in provider format. Providers: ${VALID_PROVIDERS}`)\n .requiredOption('--data <json>', 'Tool call data in provider format (inline JSON or @filename)')\n .option('--external-id <id>', 'External ID for idempotent upsert')\n .option('--external-source <source>', 'External source identifier')\n .action(async function (this: Command, provider: string, collection: string, opts: { data: string; externalId?: string; externalSource?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const callData = parseData(opts.data);\n const queryParts: string[] = [];\n if (opts.externalId) queryParts.push(`external_id=${encodeURIComponent(opts.externalId)}`);\n if (opts.externalSource) queryParts.push(`external_source=${encodeURIComponent(opts.externalSource)}`);\n const qs = queryParts.length ? `?${queryParts.join('&')}` : '';\n const data = await client.request('POST', `/v1/${ws}/providers/${provider}/records/${collection}${qs}`, callData);\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getFormat } from '../helpers.js';\n\nexport const tokensCommand = new Command('tokens')\n .description('Manage API tokens');\n\ntokensCommand.command('create')\n .description('Create a scoped API token')\n .requiredOption('--name <name>', 'Token name')\n .requiredOption('--grants <json>', 'Grant definitions as JSON array')\n .option('--expires-at <date>', 'Expiration date (ISO 8601, e.g., 2026-06-01T00:00:00Z)')\n .action(async function (this: Command, opts: { name: string; grants: string; expiresAt?: string }) {\n const client = new ApiClient();\n let grants: unknown;\n try {\n grants = JSON.parse(opts.grants);\n } catch {\n throw new Error('--grants must be valid JSON');\n }\n const body: Record<string, unknown> = { name: opts.name, grants };\n if (opts.expiresAt) body.expires_at = opts.expiresAt;\n const data = await client.request('POST', '/v1/tokens', body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntokensCommand.command('list')\n .description('List API tokens')\n .action(async function (this: Command) {\n const client = new ApiClient();\n const data = await client.request('GET', '/v1/tokens');\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntokensCommand.command('revoke <token_id>')\n .description('Revoke an API token')\n .action(async function (this: Command, tokenId: string) {\n const client = new ApiClient();\n await client.request('DELETE', `/v1/tokens/${tokenId}`);\n console.log('Token revoked');\n });\n","{\n \"name\": \"rekor-cli\",\n \"version\": \"0.1.19\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"bin\": {\n \"rekor\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"dev\": \"tsup --watch\"\n },\n \"dependencies\": {\n \"@napi-rs/keyring\": \"^1.1.6\",\n \"chalk\": \"^5.4.1\",\n \"cli-table3\": \"^0.6.5\",\n \"commander\": \"^13.1.0\",\n \"open\": \"^11.0.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.5.0\",\n \"tsup\": \"^8.4.0\",\n \"typescript\": \"^5.8.2\",\n \"vitest\": \"~3.0.9\"\n }\n}\n","import { program } from './program.js';\n\nprogram.parse();\n"],"mappings":"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","names":["Command","Command","Command","Command","readFileSync","Command","Command","Command","Command","Command","Command","readFileSync","Command","readFileSync","Command","Command","Command","Command","Command","readFileSync","Command","readFileSync","Command","Command","randomUUID","Command","Command","randomUUID","Command","Command","Command","Command","Command","Command","writeFileSync","Command","Command","Command"]}
1
+ {"version":3,"sources":["../src/program.ts","../src/commands/login.ts","../src/config.ts","../src/token-store.ts","../src/oauth.ts","../src/auth.ts","../src/pkce.ts","../src/commands/logout.ts","../src/client.ts","../src/commands/workspaces.ts","../src/output.ts","../src/helpers.ts","../src/commands/collections.ts","../src/commands/records.ts","../src/commands/sql.ts","../src/commands/relationships.ts","../src/commands/query-relationships.ts","../src/commands/attachments.ts","../src/commands/hooks.ts","../src/commands/triggers.ts","../src/commands/endpoints.ts","../src/commands/batch.ts","../src/commands/providers.ts","../src/commands/tokens.ts","../package.json","../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { loginCommand } from './commands/login.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { workspacesCommand } from './commands/workspaces.js';\nimport { collectionsCommand } from './commands/collections.js';\nimport { recordsCommand } from './commands/records.js';\nimport { sqlCommand } from './commands/sql.js';\nimport { relationshipsCommand } from './commands/relationships.js';\nimport { queryRelationshipsCommand } from './commands/query-relationships.js';\nimport { attachmentsCommand } from './commands/attachments.js';\nimport { hooksCommand } from './commands/hooks.js';\nimport { triggersCommand } from './commands/triggers.js';\nimport { endpointsCommand } from './commands/endpoints.js';\nimport { batchCommand } from './commands/batch.js';\nimport { providersCommand } from './commands/providers.js';\nimport { tokensCommand } from './commands/tokens.js';\nimport pkg from '../package.json' with { type: 'json' };\n\nexport const program = new Command('rekor')\n .description('Rekor CLI — System of Record for AI agents')\n .version(pkg.version)\n .option('--workspace <id>', 'Workspace ID')\n .option('--output <format>', 'Output format: json or table', 'table');\n\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(workspacesCommand);\nprogram.addCommand(collectionsCommand);\nprogram.addCommand(recordsCommand);\nprogram.addCommand(sqlCommand);\nprogram.addCommand(relationshipsCommand);\nprogram.addCommand(queryRelationshipsCommand);\nprogram.addCommand(attachmentsCommand);\nprogram.addCommand(hooksCommand);\nprogram.addCommand(triggersCommand);\nprogram.addCommand(batchCommand);\nprogram.addCommand(providersCommand);\nprogram.addCommand(tokensCommand);\nprogram.addCommand(endpointsCommand);\n","import { Command } from 'commander';\nimport { login } from '../auth.js';\nimport { loadConfig, saveConfig } from '../config.js';\nimport {\n exchangeCodeForTokens,\n expiresInToIso,\n startCallbackServer,\n getAuthKitDomain,\n getAuthKitClientId,\n OAUTH_CALLBACK_PORT,\n} from '../oauth.js';\nimport {\n generateCodeVerifier,\n generateCodeChallenge,\n generateState,\n} from '../pkce.js';\nimport { setOAuthTokens } from '../token-store.js';\n\nconst FALLBACK_URL_DELAY_MS = 5_000;\n\nexport const loginCommand = new Command('login')\n .description('Authenticate with Rekor')\n .option('--token <token>', 'API key for headless/CI authentication (rec_...)')\n .option('--api-url <url>', 'API base URL')\n .action(async (opts: { token?: string; apiUrl?: string }) => {\n if (opts.token) {\n await login(opts.token, opts.apiUrl);\n console.log('Authenticated successfully');\n return;\n }\n\n try {\n await browserLoginPkce(opts.apiUrl);\n console.log('Authenticated successfully');\n } catch (err) {\n console.error(\n `Login failed: ${err instanceof Error ? err.message : 'Unknown error'}`,\n );\n process.exit(1);\n }\n });\n\nasync function browserLoginPkce(apiUrl?: string): Promise<void> {\n const open = await import('open').then(m => m.default);\n\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n const port = OAUTH_CALLBACK_PORT;\n const redirectUri = `http://127.0.0.1:${port}/callback`;\n\n const authkitDomain = getAuthKitDomain();\n const clientId = getAuthKitClientId();\n\n const authorizeUrl = new URL(`${authkitDomain}/oauth2/authorize`);\n authorizeUrl.searchParams.set('client_id', clientId);\n authorizeUrl.searchParams.set('redirect_uri', redirectUri);\n authorizeUrl.searchParams.set('response_type', 'code');\n authorizeUrl.searchParams.set('code_challenge', codeChallenge);\n authorizeUrl.searchParams.set('code_challenge_method', 'S256');\n authorizeUrl.searchParams.set('state', state);\n // offline_access asks AuthKit to issue a refresh_token alongside the access_token —\n // without it the CLI would re-prompt every ~1h when the access token expires.\n authorizeUrl.searchParams.set('scope', 'openid profile email offline_access');\n\n console.log('Opening browser for authentication...');\n\n // Start the callback server first so the redirect can land.\n const callbackPromise = startCallbackServer(port, state);\n\n // open() resolves on spawn, not browser launch — print a fallback URL after a delay.\n let fallbackPrinted = false;\n const fallbackTimer = setTimeout(() => {\n fallbackPrinted = true;\n console.log(`If the browser didn't open, visit: ${authorizeUrl.toString()}`);\n }, FALLBACK_URL_DELAY_MS);\n\n open(authorizeUrl.toString()).catch(() => {\n if (fallbackPrinted) return;\n clearTimeout(fallbackTimer);\n console.log('Could not open browser automatically.');\n console.log(`Visit: ${authorizeUrl.toString()}`);\n });\n\n let code: string;\n try {\n ({ code } = await callbackPromise);\n } finally {\n clearTimeout(fallbackTimer);\n }\n\n const tokens = await exchangeCodeForTokens(authkitDomain, clientId, code, codeVerifier, redirectUri);\n const expiresAt = expiresInToIso(tokens.expires_in);\n await setOAuthTokens(tokens.access_token, tokens.refresh_token, expiresAt);\n\n const config = loadConfig();\n saveConfig({\n ...config,\n api_url: apiUrl ?? config.api_url,\n });\n}\n","import { readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\nconst CONFIG_DIR = join(homedir(), '.config', 'rekor');\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.json');\n\nexport interface Config {\n api_url: string;\n default_workspace?: string;\n org_id?: string;\n}\n\ninterface ConfigFile extends Config {\n // Tokens may linger here from older CLI versions until token-store migrates them.\n token?: string;\n [key: string]: unknown;\n}\n\nexport function loadConfig(): Config {\n const envUrl = process.env['REKOR_API_URL'];\n\n try {\n const raw = readFileSync(CONFIG_FILE, 'utf-8');\n const stored = JSON.parse(raw) as ConfigFile;\n return {\n api_url: envUrl ?? stored.api_url ?? 'http://localhost:8787',\n default_workspace: stored.default_workspace,\n org_id: stored.org_id,\n };\n } catch {\n return {\n api_url: envUrl ?? 'http://localhost:8787',\n };\n }\n}\n\nexport function saveConfig(config: Config): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n let existing: ConfigFile = {} as ConfigFile;\n try {\n existing = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8')) as ConfigFile;\n } catch {\n existing = {} as ConfigFile;\n }\n const merged: ConfigFile = { ...existing, ...config };\n writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), { mode: 0o600 });\n}\n\nexport { CONFIG_DIR, CONFIG_FILE };\n","import * as fs from 'node:fs';\nimport { CONFIG_DIR, CONFIG_FILE } from './config.js';\n\nconst KEYRING_SERVICE = 'rekor';\nconst KEY_REC = 'rec_token';\nconst KEY_OAUTH_ACCESS = 'oauth_access_token';\nconst KEY_OAUTH_REFRESH = 'oauth_refresh_token';\n\ninterface KeyringBinding {\n getPassword(service: string, account: string): Promise<string | null>;\n setPassword(service: string, account: string, password: string): Promise<void>;\n deletePassword(service: string, account: string): Promise<boolean>;\n}\n\nlet keyringCache: KeyringBinding | null | undefined;\n\nasync function getKeyring(): Promise<KeyringBinding | null> {\n if (keyringCache !== undefined) return keyringCache;\n try {\n const mod = await import('@napi-rs/keyring');\n const Entry = mod.Entry;\n keyringCache = {\n async getPassword(service, account) {\n try { return new Entry(service, account).getPassword(); } catch { return null; }\n },\n async setPassword(service, account, password) {\n new Entry(service, account).setPassword(password);\n },\n async deletePassword(service, account) {\n try { return new Entry(service, account).deletePassword(); } catch { return false; }\n },\n };\n } catch {\n keyringCache = null;\n }\n return keyringCache;\n}\n\nfunction manualCleanupCommand(account: string): string {\n if (process.platform === 'darwin') {\n return `security delete-generic-password -s ${KEYRING_SERVICE} -a ${account}`;\n }\n if (process.platform === 'win32') {\n return `cmdkey /delete:${KEYRING_SERVICE}/${account}`;\n }\n if (process.platform === 'linux') {\n return `secret-tool clear service ${KEYRING_SERVICE} account ${account}`;\n }\n return `(remove service=\"${KEYRING_SERVICE}\" account=\"${account}\" from your OS credential store)`;\n}\n\ninterface LegacyConfigFile {\n api_url?: string;\n token?: string;\n access_token?: string;\n refresh_token?: string;\n token_expires_at?: string;\n default_workspace?: string;\n org_id?: string;\n [key: string]: unknown;\n}\n\nfunction readConfigFile(): LegacyConfigFile | null {\n if (!fs.existsSync(CONFIG_FILE)) return null;\n try {\n return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8')) as LegacyConfigFile;\n } catch {\n return null;\n }\n}\n\nfunction writeConfigFile(data: LegacyConfigFile): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), { mode: 0o600 });\n}\n\n// Delete reported success but get still returned a value — the keychain ignored the delete.\nexport class StaleKeyringSlotError extends Error {\n constructor(public readonly account: string) {\n super(\n `Stale credential remains in OS keychain slot \"${account}\" after delete. ` +\n `Clean it up manually and retry:\\n ${manualCleanupCommand(account)}`,\n );\n this.name = 'StaleKeyringSlotError';\n }\n}\n\nasync function clearSlot(keyring: KeyringBinding, account: string): Promise<boolean> {\n await keyring.deletePassword(KEYRING_SERVICE, account);\n try {\n return (await keyring.getPassword(KEYRING_SERVICE, account)) === null;\n } catch {\n return false;\n }\n}\n\nexport type ResolvedToken =\n | { kind: 'rec'; token: string }\n | { kind: 'oauth'; access_token: string; refresh_token?: string; expires_at?: string };\n\nfunction stripTokenFieldsFromFile(): void {\n const existing = readConfigFile();\n if (!existing) return;\n if (existing.token === undefined && existing.access_token === undefined && existing.refresh_token === undefined) return;\n delete existing.token;\n delete existing.access_token;\n delete existing.refresh_token;\n writeConfigFile(existing);\n}\n\nfunction readMetadataExpiresAt(): string | undefined {\n return readConfigFile()?.token_expires_at;\n}\n\nfunction writeMetadataExpiresAt(value: string | undefined): void {\n const existing = readConfigFile() ?? {};\n if (value === undefined) {\n delete existing.token_expires_at;\n } else {\n existing.token_expires_at = value;\n }\n writeConfigFile(existing);\n}\n\nasync function migrateLegacyFileToken(keyring: KeyringBinding | null): Promise<ResolvedToken | null> {\n const existing = readConfigFile();\n if (!existing) return null;\n\n // Prefer OAuth fields if present (newer file-fallback format), else legacy `token`.\n if (existing.access_token) {\n const out: ResolvedToken = {\n kind: 'oauth',\n access_token: existing.access_token,\n refresh_token: existing.refresh_token,\n expires_at: existing.token_expires_at,\n };\n if (keyring) {\n try {\n // Keyring wins on conflict — only migrate if slots are empty.\n const accessExisting = await keyring.getPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS);\n if (!accessExisting) {\n await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS, existing.access_token);\n if (existing.refresh_token) {\n await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH, existing.refresh_token);\n }\n }\n try { stripTokenFieldsFromFile(); } catch (err) {\n console.warn(`rekor: failed to strip legacy OAuth tokens from ${CONFIG_FILE} (${(err as Error).message}).`);\n }\n } catch (err) {\n console.warn(`rekor: OAuth migration to keychain failed (${(err as Error).message}); continuing with file-backed.`);\n }\n }\n return out;\n }\n\n if (existing.token) {\n const token = existing.token;\n if (!keyring) return { kind: 'rec', token };\n try {\n const recExisting = await keyring.getPassword(KEYRING_SERVICE, KEY_REC);\n if (recExisting) {\n // Keyring wins — strip stale file copy.\n try { stripTokenFieldsFromFile(); } catch (err) {\n console.warn(`rekor: failed to strip stale token from ${CONFIG_FILE} (${(err as Error).message}).`);\n }\n return null;\n }\n await keyring.setPassword(KEYRING_SERVICE, KEY_REC, token);\n try { stripTokenFieldsFromFile(); } catch (err) {\n console.warn(`rekor: failed to strip legacy token from ${CONFIG_FILE} (${(err as Error).message}).`);\n }\n } catch (err) {\n console.warn(`rekor: keychain migration failed (${(err as Error).message}); continuing with file-backed token.`);\n }\n return { kind: 'rec', token };\n }\n\n return null;\n}\n\n// Read order: REKOR_TOKEN env → rec_ slot → OAuth slot. rec_ wins so an OAuth fallback can't silently switch identities.\nexport async function getResolvedToken(): Promise<ResolvedToken | null> {\n const envToken = process.env['REKOR_TOKEN'];\n if (envToken) {\n // Always rec-kind — preserves `REKOR_TOKEN=dev` for DEV_BYPASS_AUTH and avoids the OAuth refresh path on plain strings.\n return { kind: 'rec', token: envToken };\n }\n\n const keyring = await getKeyring();\n const migrated = await migrateLegacyFileToken(keyring);\n if (migrated) return migrated;\n\n if (keyring) {\n // All three slots in parallel — rec_ wins read precedence but probing sequentially would block on empty slots.\n const [rec, access, refresh] = await Promise.all([\n keyring.getPassword(KEYRING_SERVICE, KEY_REC),\n keyring.getPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS),\n keyring.getPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH),\n ]);\n if (rec) return { kind: 'rec', token: rec };\n if (access) {\n const out: ResolvedToken = { kind: 'oauth', access_token: access };\n if (refresh) out.refresh_token = refresh;\n const expiresAt = readMetadataExpiresAt();\n if (expiresAt) out.expires_at = expiresAt;\n return out;\n }\n }\n\n return null;\n}\n\n// Backwards-compatible single-string accessor for callers that don't need the kind.\nexport async function getToken(): Promise<string | null> {\n const resolved = await getResolvedToken();\n if (!resolved) return null;\n return resolved.kind === 'rec' ? resolved.token : resolved.access_token;\n}\n\nexport async function setToken(token: string): Promise<void> {\n await setRecToken(token);\n}\n\nexport async function setRecToken(token: string): Promise<void> {\n const keyring = await getKeyring();\n if (keyring) {\n try {\n // Clear OAuth slots first — a stale OAuth would survive `rekor logout` and confuse mode-switch debugging.\n const [accessCleared, refreshCleared] = await Promise.all([\n clearSlot(keyring, KEY_OAUTH_ACCESS),\n clearSlot(keyring, KEY_OAUTH_REFRESH),\n ]);\n const stuck = [\n accessCleared ? null : KEY_OAUTH_ACCESS,\n refreshCleared ? null : KEY_OAUTH_REFRESH,\n ].filter((a): a is string => a !== null);\n if (stuck.length > 0) {\n console.warn(\n [\n `rekor: stale OAuth credential remains in OS keychain after delete. Commands work but logout won't fully clear. Manually:`,\n ...stuck.map(a => ` ${manualCleanupCommand(a)}`),\n ].join('\\n'),\n );\n }\n await keyring.setPassword(KEYRING_SERVICE, KEY_REC, token);\n writeMetadataExpiresAt(undefined);\n try { stripTokenFieldsFromFile(); } catch (err) {\n console.warn(`rekor: failed to strip stale tokens from ${CONFIG_FILE} (${(err as Error).message}).`);\n }\n return;\n } catch (err) {\n if (err instanceof StaleKeyringSlotError) throw err;\n console.warn(`rekor: keychain write failed (${(err as Error).message}); falling back to file storage.`);\n }\n }\n const existing = readConfigFile() ?? {};\n delete existing.access_token;\n delete existing.refresh_token;\n delete existing.token_expires_at;\n existing.token = token;\n writeConfigFile(existing);\n}\n\nexport async function setOAuthTokens(\n accessToken: string,\n refreshToken: string | undefined,\n expiresAt: string,\n): Promise<void> {\n const keyring = await getKeyring();\n if (keyring) {\n try {\n // rec_ wins the read race — a leftover would mask new OAuth tokens; verify empty after delete and fail loudly.\n if (!(await clearSlot(keyring, KEY_REC))) {\n throw new StaleKeyringSlotError(KEY_REC);\n }\n await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_ACCESS, accessToken);\n if (refreshToken) {\n await keyring.setPassword(KEYRING_SERVICE, KEY_OAUTH_REFRESH, refreshToken);\n } else {\n // Best-effort clear of any stale refresh slot when the new pair has none.\n await clearSlot(keyring, KEY_OAUTH_REFRESH);\n }\n writeMetadataExpiresAt(expiresAt);\n try { stripTokenFieldsFromFile(); } catch (err) {\n console.warn(`rekor: failed to strip stale tokens from ${CONFIG_FILE} (${(err as Error).message}).`);\n }\n return;\n } catch (err) {\n // StaleKeyringSlotError propagates — file fallback won't help if the keyring still holds rec_.\n if (err instanceof StaleKeyringSlotError) throw err;\n console.warn(`rekor: keychain write failed (${(err as Error).message}); falling back to file storage.`);\n }\n }\n const existing = readConfigFile() ?? {};\n delete existing.token;\n existing.access_token = accessToken;\n if (refreshToken) existing.refresh_token = refreshToken;\n existing.token_expires_at = expiresAt;\n writeConfigFile(existing);\n}\n\nexport async function clearToken(): Promise<void> {\n await clearAllTokens();\n}\n\nexport async function clearAllTokens(): Promise<void> {\n const keyring = await getKeyring();\n if (keyring) {\n const slots = [KEY_REC, KEY_OAUTH_ACCESS, KEY_OAUTH_REFRESH] as const;\n const cleared = await Promise.all(slots.map(s => clearSlot(keyring, s)));\n for (const [i, ok] of cleared.entries()) {\n if (!ok) {\n const account = slots[i]!;\n console.warn(\n `rekor: could not clear keychain slot \"${account}\". Subsequent commands may still pick the stale token. Manually:\\n ${manualCleanupCommand(account)}`,\n );\n }\n }\n }\n const existing = readConfigFile();\n if (existing) {\n let dirty = false;\n for (const k of ['token', 'access_token', 'refresh_token', 'token_expires_at'] as const) {\n if (existing[k] !== undefined) {\n delete existing[k];\n dirty = true;\n }\n }\n if (dirty) writeConfigFile(existing);\n }\n}\n\nexport function __setKeyringForTesting(binding: KeyringBinding | null): void {\n keyringCache = binding;\n}\n\nexport function __resetKeyringForTesting(): void {\n keyringCache = undefined;\n}\n","import * as http from 'node:http';\n\n// Fixed port for the OAuth redirect URI — must match what's registered in WorkOS AuthKit.\nexport const OAUTH_CALLBACK_PORT = 3927;\n\n// No live placeholders — a registrable fallback subdomain would let an attacker intercept codes from misconfigured installs.\nconst DEFAULT_AUTHKIT_DOMAIN = '';\nconst DEFAULT_AUTHKIT_CLIENT_ID = '';\n\nexport function getAuthKitDomain(): string {\n const value = process.env['REKOR_AUTHKIT_DOMAIN'] || DEFAULT_AUTHKIT_DOMAIN;\n if (!value) {\n throw new Error('REKOR_AUTHKIT_DOMAIN is not configured — set the env var to your AuthKit tenant (e.g. https://<tenant>.authkit.app).');\n }\n return value;\n}\n\nexport function getAuthKitClientId(): string {\n const value = process.env['REKOR_AUTHKIT_CLIENT_ID'] || DEFAULT_AUTHKIT_CLIENT_ID;\n if (!value) {\n throw new Error('REKOR_AUTHKIT_CLIENT_ID is not configured — set the env var to the AuthKit public PKCE client id registered for the Rekor CLI.');\n }\n return value;\n}\n\nexport interface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n}\n\nexport function expiresInToIso(expiresInSeconds: number): string {\n return new Date(Date.now() + expiresInSeconds * 1000).toISOString();\n}\n\nfunction asTokenResponse(value: unknown): TokenResponse {\n if (typeof value !== 'object' || value === null) {\n throw new Error('AuthKit returned a non-object token payload');\n }\n const v = value as Partial<TokenResponse>;\n if (typeof v.access_token !== 'string' || typeof v.expires_in !== 'number') {\n throw new Error('AuthKit token payload missing required fields');\n }\n const out: TokenResponse = { access_token: v.access_token, expires_in: v.expires_in };\n if (typeof v.refresh_token === 'string') out.refresh_token = v.refresh_token;\n return out;\n}\n\nexport async function exchangeCodeForTokens(\n authkitDomain: string,\n clientId: string,\n code: string,\n codeVerifier: string,\n redirectUri: string,\n): Promise<TokenResponse> {\n const response = await fetch(`${authkitDomain}/oauth2/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n client_id: clientId,\n }).toString(),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Token exchange failed (${response.status}): ${body}`);\n }\n\n return asTokenResponse(await response.json());\n}\n\nexport class SessionExpiredError extends Error {\n constructor() {\n super('SESSION_EXPIRED');\n this.name = 'SessionExpiredError';\n }\n}\n\nexport async function refreshAccessToken(\n authkitDomain: string,\n clientId: string,\n refreshToken: string,\n): Promise<TokenResponse> {\n const response = await fetch(`${authkitDomain}/oauth2/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n client_id: clientId,\n }).toString(),\n });\n\n if (!response.ok) {\n const status = response.status;\n const body = await response.text();\n\n if (status === 400 || status === 401) {\n try {\n const parsed = JSON.parse(body) as { error?: string };\n if (parsed.error === 'invalid_grant') throw new SessionExpiredError();\n } catch (err) {\n if (err instanceof SessionExpiredError) throw err;\n // Non-JSON body — fall through to generic error.\n }\n }\n\n throw new Error(`Token refresh failed (${status}): ${body}`);\n }\n\n return asTokenResponse(await response.json());\n}\n\nexport function startCallbackServer(\n port: number,\n expectedState: string,\n timeoutMs: number = 120_000,\n): Promise<{ code: string }> {\n return new Promise((resolve, reject) => {\n let handled = false;\n const server = http.createServer((req, res) => {\n const url = new URL(req.url || '/', `http://127.0.0.1:${port}`);\n if (url.pathname !== '/callback') {\n res.writeHead(404);\n res.end();\n return;\n }\n\n if (handled) {\n res.writeHead(409);\n res.end();\n return;\n }\n\n const code = url.searchParams.get('code');\n const state = url.searchParams.get('state');\n const error = url.searchParams.get('error');\n const errorDescription = url.searchParams.get('error_description');\n\n if (error) {\n handled = true;\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage(errorDescription || error));\n cleanup();\n reject(new Error(`OAuth error: ${errorDescription || error}`));\n return;\n }\n\n if (state !== expectedState) {\n handled = true;\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage('Invalid state parameter'));\n cleanup();\n reject(new Error('OAuth state mismatch — possible CSRF attempt'));\n return;\n }\n\n if (!code) {\n handled = true;\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(errorPage('No authorization code received'));\n cleanup();\n reject(new Error('No authorization code received'));\n return;\n }\n\n handled = true;\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(successPage());\n cleanup();\n resolve({ code });\n });\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Timed out waiting for login. Run `rekor login` again.'));\n }, timeoutMs);\n\n function cleanup(): void {\n clearTimeout(timeout);\n server.close();\n }\n\n server.on('error', (err: NodeJS.ErrnoException) => {\n cleanup();\n if (err.code === 'EADDRINUSE') {\n reject(new Error(`Port ${port} is in use. Close the other process and retry.`));\n } else {\n reject(err);\n }\n });\n\n server.listen(port, '127.0.0.1');\n });\n}\n\nfunction successPage(): string {\n return `<!DOCTYPE html>\n<html><head><title>Rekor CLI</title></head>\n<body style=\"font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa;\">\n <div style=\"text-align: center;\">\n <h1 style=\"font-size: 1.25rem; font-weight: 600;\">Authentication successful</h1>\n <p style=\"color: #666; margin-top: 0.5rem;\">You can close this tab and return to your terminal.</p>\n </div>\n</body></html>`;\n}\n\n// `message` comes from OAuth redirect params — encode so a compromised IdP can't inject HTML into the localhost page.\nfunction escapeHtml(input: string): string {\n return input\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nfunction errorPage(message: string): string {\n return `<!DOCTYPE html>\n<html><head><title>Rekor CLI</title></head>\n<body style=\"font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa;\">\n <div style=\"text-align: center;\">\n <h1 style=\"font-size: 1.25rem; font-weight: 600; color: #dc2626;\">Authentication failed</h1>\n <p style=\"color: #666; margin-top: 0.5rem;\">${escapeHtml(message)}</p>\n </div>\n</body></html>`;\n}\n","import { loadConfig, saveConfig } from './config.js';\nimport { getResolvedToken, setRecToken, setOAuthTokens, clearAllTokens, type ResolvedToken } from './token-store.js';\nimport { refreshAccessToken, expiresInToIso, getAuthKitDomain, getAuthKitClientId, SessionExpiredError } from './oauth.js';\n\n/** Persist a pasted rec_ token (CI / headless path). */\nexport async function login(token: string, apiUrl?: string): Promise<void> {\n await setRecToken(token);\n const config = loadConfig();\n saveConfig({\n ...config,\n api_url: apiUrl ?? config.api_url,\n });\n}\n\nconst REFRESH_LEEWAY_MS = 60_000;\n\n// Returns a valid access token; silently refreshes OAuth tokens within 60s of expiry.\nexport async function getAccessToken(): Promise<string | null> {\n const resolved = await getResolvedToken();\n if (!resolved) return null;\n\n if (resolved.kind === 'rec') return resolved.token;\n\n // OAuth path — refresh if near expiry. Missing/unparseable expires_at: assume valid, let the API surface a real 401.\n const expiresAtMs = resolved.expires_at ? new Date(resolved.expires_at).getTime() : Number.NaN;\n if (!Number.isFinite(expiresAtMs) || expiresAtMs > Date.now() + REFRESH_LEEWAY_MS) {\n return resolved.access_token;\n }\n if (!resolved.refresh_token) {\n throw new Error('Access token expired and no refresh token available. Run `rekor login` again.');\n }\n\n try {\n const result = await refreshAccessToken(getAuthKitDomain(), getAuthKitClientId(), resolved.refresh_token);\n const newExpiresAt = expiresInToIso(result.expires_in);\n await setOAuthTokens(result.access_token, result.refresh_token ?? resolved.refresh_token, newExpiresAt);\n return result.access_token;\n } catch (err) {\n if (err instanceof SessionExpiredError) {\n await clearAllTokens();\n throw new Error('Session expired. Run `rekor login` again.');\n }\n throw err;\n }\n}\n\n/** Auth kind for the current credential, without resolving the token itself. Used by logout to decide if it should call the revoke endpoint. */\nexport async function currentAuthKind(): Promise<ResolvedToken['kind'] | null> {\n const resolved = await getResolvedToken();\n return resolved?.kind ?? null;\n}\n\nexport async function isAuthenticated(): Promise<boolean> {\n return (await getResolvedToken()) !== null;\n}\n","import * as crypto from 'node:crypto';\n\nexport function generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString('base64url');\n}\n\nexport function generateCodeChallenge(verifier: string): string {\n return crypto.createHash('sha256').update(verifier).digest().toString('base64url');\n}\n\nexport function generateState(): string {\n return crypto.randomBytes(16).toString('base64url');\n}\n","import { Command } from 'commander';\nimport { clearAllTokens } from '../token-store.js';\nimport { currentAuthKind } from '../auth.js';\nimport { ApiClient } from '../client.js';\n\nexport const logoutCommand = new Command('logout')\n .description('Remove stored authentication credentials')\n .action(async () => {\n const kind = await currentAuthKind();\n\n // For OAuth sessions, ask the backend to revoke the WorkOS session so cross-device\n // logout works. Best-effort — errors don't block local credential cleanup.\n if (kind === 'oauth') {\n try {\n const client = new ApiClient();\n await client.request('POST', '/v1/auth/logout');\n } catch (err) {\n console.warn(`rekor: server-side logout failed (${err instanceof Error ? err.message : 'unknown'}); clearing local credentials anyway.`);\n }\n }\n\n await clearAllTokens();\n console.log('Logged out successfully');\n });\n","import { loadConfig } from './config.js';\nimport { getAccessToken } from './auth.js';\n\nexport class ApiClient {\n readonly baseUrl: string;\n private _tokenPromise: Promise<string | null> | undefined;\n\n constructor() {\n const config = loadConfig();\n this.baseUrl = config.api_url;\n }\n\n private getToken(): Promise<string | null> {\n if (!this._tokenPromise) this._tokenPromise = getAccessToken();\n return this._tokenPromise;\n }\n\n private async authHeaders(): Promise<Record<string, string>> {\n const token = await this.getToken();\n return token ? { 'Authorization': `Bearer ${token}` } : {};\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n ...(await this.authHeaders()),\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n\n const json = await res.json() as { data?: T; error?: { message: string } };\n if (!res.ok) {\n throw new Error(json.error?.message ?? `HTTP ${res.status}`);\n }\n return json.data as T;\n }\n\n async uploadFile(url: string, body: BodyInit, contentType: string): Promise<void> {\n const res = await fetch(url, {\n method: 'PUT',\n headers: {\n ...(await this.authHeaders()),\n 'Content-Type': contentType,\n },\n body,\n });\n if (!res.ok) {\n throw new Error(`Upload failed: HTTP ${res.status}`);\n }\n }\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getFormat } from '../helpers.js';\n\nexport const workspacesCommand = new Command('workspaces')\n .description('Manage workspaces');\n\nworkspacesCommand.command('list')\n .description('List all workspaces')\n .option('--tag <tag>', 'Filter by tag')\n .action(async function (this: Command, opts: { tag?: string }) {\n const client = new ApiClient();\n const qs = opts.tag ? `?tag=${encodeURIComponent(opts.tag)}` : '';\n const data = await client.request('GET', `/v1/workspaces${qs}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('get <id>')\n .description('Get a workspace')\n .action(async function (this: Command, id: string) {\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/workspaces/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('create <id>')\n .description('Create a workspace')\n .requiredOption('--name <name>', 'Workspace name')\n .option('--description <desc>', 'Description')\n .option('--tags <tags>', 'Comma-separated tags (e.g., client:acme,billing)')\n .action(async function (this: Command, id: string, opts: { name: string; description?: string; tags?: string }) {\n const client = new ApiClient();\n const body: Record<string, unknown> = {\n name: opts.name,\n description: opts.description,\n };\n if (opts.tags) {\n body['tags'] = opts.tags.split(',').map(t => t.trim());\n }\n const data = await client.request('PUT', `/v1/workspaces/${id}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('tag <id>')\n .description('Set tags on a workspace')\n .requiredOption('--tags <tags>', 'Comma-separated tags (e.g., client:acme,billing)')\n .action(async function (this: Command, id: string, opts: { tags: string }) {\n const client = new ApiClient();\n const data = await client.request('PUT', `/v1/workspaces/${id}`, {\n tags: opts.tags.split(',').map(t => t.trim()),\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('delete <id>')\n .description('Delete a workspace')\n .action(async (_id: string) => {\n const client = new ApiClient();\n await client.request('DELETE', `/v1/workspaces/${_id}`);\n console.log('Deleted');\n });\n\n// --- Environment commands ---\n\nworkspacesCommand.command('create-preview <production-id>')\n .description('Create a preview workspace linked to a production workspace')\n .requiredOption('--name <name>', 'Preview workspace name')\n .option('--description <desc>', 'Description')\n .action(async function (this: Command, productionId: string, opts: { name: string; description?: string }) {\n const client = new ApiClient();\n const data = await client.request('POST', `/v1/${productionId}/preview`, {\n name: opts.name,\n description: opts.description,\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('list-previews <production-id>')\n .description('List preview workspaces for a production workspace')\n .action(async function (this: Command, productionId: string) {\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${productionId}/previews`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('promote <production-id>')\n .description('Promote config from a preview workspace to production (human-only)')\n .requiredOption('--from <preview-id>', 'Source preview workspace ID')\n .option('--dry-run', 'Show what would change without applying')\n .option('--collections <ids>', 'Comma-separated collection IDs to promote', (v: string) => v.split(','))\n .option('--triggers <ids>', 'Comma-separated trigger IDs to promote', (v: string) => v.split(','))\n .option('--hooks <ids>', 'Comma-separated hook IDs to promote', (v: string) => v.split(','))\n .action(async function (\n this: Command,\n productionId: string,\n opts: { from: string; dryRun?: boolean; collections?: string[]; triggers?: string[]; hooks?: string[] },\n ) {\n const client = new ApiClient();\n const data = await client.request('POST', `/v1/${productionId}/promote`, {\n source_workspace_id: opts.from,\n dry_run: opts.dryRun ?? false,\n collections: opts.collections,\n triggers: opts.triggers,\n hooks: opts.hooks,\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('rollback <production-id>')\n .description('Rollback a promotion (human-only)')\n .requiredOption('--promotion <promotion-id>', 'Promotion ID to rollback')\n .action(async function (this: Command, productionId: string, opts: { promotion: string }) {\n const client = new ApiClient();\n const data = await client.request('POST', `/v1/${productionId}/promote/rollback`, {\n promotion_id: opts.promotion,\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nworkspacesCommand.command('promotions <production-id>')\n .description('List promotion history for a production workspace')\n .action(async function (this: Command, productionId: string) {\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${productionId}/promotions`);\n console.log(formatOutput(data, getFormat(this)));\n });\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport type OutputFormat = 'json' | 'table';\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n if (format === 'json') {\n return JSON.stringify(data, null, 2);\n }\n\n if (Array.isArray(data)) {\n return formatTable(data as Record<string, unknown>[]);\n }\n\n if (typeof data === 'object' && data !== null) {\n return formatKeyValue(data as Record<string, unknown>);\n }\n\n return String(data);\n}\n\nfunction formatTable(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return chalk.dim('No results');\n\n const keys = Object.keys(rows[0]!);\n const table = new Table({ head: keys.map(k => chalk.bold(k)) });\n\n for (const row of rows) {\n table.push(keys.map(k => {\n const val = row[k];\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n }));\n }\n\n return table.toString();\n}\n\nfunction formatKeyValue(obj: Record<string, unknown>): string {\n const table = new Table();\n for (const [key, value] of Object.entries(obj)) {\n const displayValue = typeof value === 'object' ? JSON.stringify(value) : String(value ?? '');\n table.push({ [chalk.bold(key)]: displayValue });\n }\n return table.toString();\n}\n","import { readFileSync } from 'fs';\nimport { Command } from 'commander';\nimport { type OutputFormat } from './output.js';\n\nexport function parseData(data: string): Record<string, unknown> {\n if (data.startsWith('@')) {\n const content = readFileSync(data.slice(1), 'utf-8');\n return JSON.parse(content) as Record<string, unknown>;\n }\n return JSON.parse(data) as Record<string, unknown>;\n}\n\nexport function getWorkspace(cmd: Command): string {\n // Walk up the command chain to find --workspace on the root program\n let current: Command | null = cmd;\n while (current) {\n const ws = current.opts().workspace as string | undefined;\n if (ws) return ws;\n current = current.parent;\n }\n console.error('Error: --workspace is required');\n return process.exit(1);\n}\n\nexport function getFormat(cmd: Command): OutputFormat {\n return (cmd.parent?.parent?.opts().output ?? cmd.parent?.opts().output ?? 'table') as OutputFormat;\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\n\nexport const collectionsCommand = new Command('collections')\n .description('Manage collections');\n\ncollectionsCommand.command('list')\n .description('List all collections in a workspace')\n .action(async function (this: Command) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/collections`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ncollectionsCommand.command('get <id>')\n .description('Get a collection')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/collections/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ncollectionsCommand.command('upsert <id>')\n .description('Create or update a collection')\n .requiredOption('--name <name>', 'Collection name')\n .option('--description <desc>', 'Description')\n .option('--schema <json>', 'JSON Schema (inline JSON or @filename)')\n .option('--icon <icon>', 'Icon name')\n .option('--color <color>', 'Hex color')\n .option('--sources <json>', 'External sources config (inline JSON or @filename)')\n .action(async function (this: Command, id: string, opts: { name: string; description?: string; schema?: string; icon?: string; color?: string; sources?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const body: Record<string, unknown> = { name: opts.name };\n if (opts.description) body['description'] = opts.description;\n if (opts.schema) body['json_schema'] = parseData(opts.schema);\n if (opts.icon) body['icon'] = opts.icon;\n if (opts.color) body['color'] = opts.color;\n if (opts.sources) body['sources'] = parseData(opts.sources);\n const data = await client.request('PUT', `/v1/${ws}/collections/${id}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ncollectionsCommand.command('delete <id>')\n .description('Delete a collection')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/collections/${id}`);\n console.log('Deleted');\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\n\nexport const recordsCommand = new Command('records')\n .description('Manage records');\n\nrecordsCommand.command('upsert <collection>')\n .description('Create or update a record')\n .requiredOption('--data <json>', 'Record data (inline JSON or @filename)')\n .option('--id <id>', 'Internal record ID (UUID) to update a known record')\n .option('--external-id <id>', 'External/agent-supplied ID for idempotent upsert')\n .option('--external-source <source>', 'Source system for external_id (e.g. stripe)')\n .action(async function (this: Command, collection: string, opts: { data: string; id?: string; externalId?: string; externalSource?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const body: Record<string, unknown> = { data: parseData(opts.data) };\n if (opts.externalId) body['external_id'] = opts.externalId;\n if (opts.externalSource) body['external_source'] = opts.externalSource;\n const path = opts.id\n ? `/v1/${ws}/records/${collection}/${opts.id}`\n : `/v1/${ws}/records/${collection}`;\n const data = await client.request('PUT', path, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nrecordsCommand.command('get <collection> <id>')\n .description('Get a record by ID')\n .action(async function (this: Command, collection: string, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/records/${collection}/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nrecordsCommand.command('delete <collection> <id>')\n .description('Delete a record')\n .action(async function (this: Command, collection: string, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/records/${collection}/${id}`);\n console.log('Deleted');\n });\n","import { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const sqlCommand = new Command('sql')\n .description('Execute a read-only SQL query against workspace data')\n .argument('[query]', 'SQL query (SELECT only)')\n .option('--file <path>', 'Read SQL from a file instead of argument')\n .option('--param <kv...>', 'Named parameters as key=value pairs (e.g., --param status=issued)')\n .action(async function (this: Command, queryArg: string | undefined, opts: { file?: string; param?: string[] }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n\n let query: string;\n if (opts.file) {\n query = readFileSync(opts.file, 'utf-8').trim();\n } else if (queryArg) {\n query = queryArg;\n } else {\n console.error('Error: provide a SQL query as argument or via --file');\n process.exit(1);\n }\n\n const params: Record<string, unknown> = {};\n if (opts.param) {\n for (const kv of opts.param) {\n const eqIdx = kv.indexOf('=');\n if (eqIdx === -1) {\n console.error(`Error: invalid param format \"${kv}\", expected key=value`);\n process.exit(1);\n }\n params[kv.slice(0, eqIdx)] = kv.slice(eqIdx + 1);\n }\n }\n\n const body: Record<string, unknown> = { query };\n if (Object.keys(params).length > 0) body.params = params;\n\n const data = await client.request('POST', `/v1/${ws}/sql`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\n\nexport const relationshipsCommand = new Command('relationships')\n .description('Manage relationships between records');\n\nrelationshipsCommand.command('upsert')\n .description('Create or update a relationship')\n .requiredOption('--source <collection/id>', 'Source record (collection/id)')\n .requiredOption('--target <collection/id>', 'Target record (collection/id)')\n .requiredOption('--type <type>', 'Relationship type')\n .option('--id <id>', 'Relationship ID')\n .option('--data <json>', 'Relationship metadata (inline JSON or @filename)')\n .action(async function (this: Command, opts: { source: string; target: string; type: string; id?: string; data?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const [sourceCollection, sourceId] = opts.source.split('/');\n const [targetCollection, targetId] = opts.target.split('/');\n const body: Record<string, unknown> = {\n rel_type: opts.type,\n source_collection: sourceCollection,\n source_id: sourceId,\n target_collection: targetCollection,\n target_id: targetId,\n };\n if (opts.id) body['id'] = opts.id;\n if (opts.data) body['data'] = parseData(opts.data);\n const path = opts.id ? `/v1/${ws}/relationships/${opts.id}` : `/v1/${ws}/relationships`;\n const data = await client.request('PUT', path, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nrelationshipsCommand.command('get <id>')\n .description('Get a relationship by ID')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/relationships/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nrelationshipsCommand.command('delete <id>')\n .description('Delete a relationship')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/relationships/${id}`);\n console.log('Deleted');\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const queryRelationshipsCommand = new Command('query-relationships')\n .description('Query related records')\n .argument('<collection>', 'Collection of the source record')\n .argument('<id>', 'Source record ID')\n .option('--type <type>', 'Filter by relationship type')\n .option('--direction <dir>', 'Direction: outgoing, incoming, or both', 'both')\n .option('--limit <n>', 'Max results', '50')\n .option('--offset <n>', 'Skip results', '0')\n .action(async function (this: Command, collection: string, id: string, opts: { type?: string; direction: string; limit: string; offset: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const params = new URLSearchParams();\n if (opts.type) params.set('rel_type', opts.type);\n // Map user-friendly direction names to backend API terms\n const directionMap: Record<string, string> = { outgoing: 'source', incoming: 'target', both: 'both' };\n params.set('direction', directionMap[opts.direction] ?? opts.direction);\n params.set('limit', opts.limit);\n params.set('offset', opts.offset);\n const data = await client.request('GET', `/v1/${ws}/records/${collection}/${id}/related?${params.toString()}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const attachmentsCommand = new Command('attachments')\n .description('Manage record attachments');\n\nattachmentsCommand.command('upload <collection> <id>')\n .description('Get a presigned upload URL for a record attachment. With --file, uploads the file content in one step.')\n .requiredOption('--filename <name>', 'File name or path (e.g. docs/guide.md)')\n .option('--content-type <type>', 'MIME type', 'application/octet-stream')\n .option('--file <path>', 'Local file to upload (skips presigned URL output, uploads directly)')\n .action(async function (this: Command, collection: string, id: string, opts: { filename: string; contentType: string; file?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('POST', `/v1/${ws}/records/${collection}/${id}/attachments`, {\n filename: opts.filename,\n content_type: opts.contentType,\n }) as { upload_url: string; [key: string]: unknown };\n\n if (opts.file) {\n const body = readFileSync(opts.file);\n const uploadUrl = data.upload_url.startsWith('http') ? data.upload_url : `${client.baseUrl}${data.upload_url}`;\n await client.uploadFile(uploadUrl, body, opts.contentType);\n console.log(formatOutput({ ...data, uploaded: true }, getFormat(this)));\n } else {\n console.log(formatOutput(data, getFormat(this)));\n }\n });\n\nattachmentsCommand.command('url <collection> <id>')\n .description('Get a download URL for an attachment by filename')\n .requiredOption('--filename <name>', 'File name or path (e.g. docs/guide.md)')\n .action(async function (this: Command, collection: string, id: string, opts: { filename: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const attachments = await client.request<Array<{ key: string; size: number; uploaded: string }>>('GET', `/v1/${ws}/records/${collection}/${id}/attachments`);\n const match = attachments.find(a => a.key.endsWith(`/${opts.filename}`));\n if (!match) {\n throw new Error(`Attachment \"${opts.filename}\" not found`);\n }\n const downloadUrl = `${client.baseUrl}/v1/${ws}/attachments/${match.key}`;\n console.log(formatOutput({ download_url: downloadUrl, ...match }, getFormat(this)));\n });\n\nattachmentsCommand.command('list <collection> <id>')\n .description('List attachments for a record')\n .option('--prefix <path>', 'Filter by path prefix (e.g. docs/)')\n .action(async function (this: Command, collection: string, id: string, opts: { prefix?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const query = opts.prefix ? `?prefix=${encodeURIComponent(opts.prefix)}` : '';\n const data = await client.request('GET', `/v1/${ws}/records/${collection}/${id}/attachments${query}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nattachmentsCommand.command('delete <collection> <id> <attachment-id>')\n .description('Delete an attachment')\n .action(async function (this: Command, collection: string, id: string, attachmentId: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/records/${collection}/${id}/attachments/${attachmentId}`);\n console.log('Deleted');\n });\n","import { randomUUID } from 'crypto';\nimport { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const hooksCommand = new Command('hooks')\n .description('Manage inbound webhook endpoints');\n\nhooksCommand.command('create')\n .description('Create a new inbound hook')\n .requiredOption('--name <name>', 'Hook name')\n .requiredOption('--secret <secret>', 'HMAC shared secret')\n .option('--id <id>', 'Hook ID (auto-generated if omitted)')\n .option('--collection-scope <collections>', 'Comma-separated collection scope')\n .action(async function (this: Command, opts: { name: string; secret: string; id?: string; collectionScope?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const hookId = opts.id ?? randomUUID();\n const body: Record<string, unknown> = {\n name: opts.name,\n secret: opts.secret,\n enabled: true,\n };\n if (opts.collectionScope) {\n body['collection_scope'] = opts.collectionScope.split(',');\n }\n const data = await client.request('PUT', `/v1/${ws}/hooks/${hookId}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nhooksCommand.command('get <id>')\n .description('Get a hook')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/hooks/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nhooksCommand.command('list')\n .description('List all hooks')\n .action(async function (this: Command) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/hooks`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nhooksCommand.command('delete <id>')\n .description('Delete a hook')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/hooks/${id}`);\n console.log('Deleted');\n });\n","import { randomUUID } from 'crypto';\nimport { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const triggersCommand = new Command('triggers')\n .description('Manage outbound triggers');\n\ntriggersCommand.command('create')\n .description('Create an outbound trigger')\n .requiredOption('--name <name>', 'Trigger name')\n .requiredOption('--url <url>', 'Target URL')\n .requiredOption('--secret <secret>', 'HMAC signing secret')\n .requiredOption('--events <events>', 'Comma-separated event types')\n .option('--id <id>', 'Trigger ID (auto-generated if omitted)')\n .option('--collection-scope <collections>', 'Comma-separated collection scope')\n .option('--filter <json>', 'Filter expression (JSON)')\n .action(async function (this: Command, opts: { name: string; url: string; secret: string; events: string; id?: string; collectionScope?: string; filter?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const triggerId = opts.id ?? randomUUID();\n const body: Record<string, unknown> = {\n name: opts.name,\n url: opts.url,\n secret: opts.secret,\n events: opts.events.split(','),\n enabled: true,\n };\n if (opts.collectionScope) {\n body['collection_scope'] = opts.collectionScope.split(',');\n }\n if (opts.filter) {\n body['filter'] = JSON.parse(opts.filter);\n }\n const data = await client.request('PUT', `/v1/${ws}/triggers/${triggerId}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntriggersCommand.command('get <id>')\n .description('Get a trigger')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/triggers/${id}`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntriggersCommand.command('list')\n .description('List all triggers')\n .action(async function (this: Command) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/triggers`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntriggersCommand.command('delete <id>')\n .description('Delete a trigger')\n .action(async function (this: Command, id: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/triggers/${id}`);\n console.log('Deleted');\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getWorkspace, getFormat } from '../helpers.js';\n\nexport const endpointsCommand = new Command('endpoints')\n .description('Manage MCP Factory endpoints');\n\nendpointsCommand.command('upsert <slug>')\n .description('Create or update an MCP endpoint')\n .option('--name <name>', 'Endpoint display name (required unless using --config)')\n .option('--description <desc>', 'Endpoint description')\n .option('--tool <spec>', 'Collection tool spec: collection:op1,op2 (repeatable)', collect, [])\n .option('--relationship <spec>', 'Relationship tool spec: rel_type:op1,op2 (repeatable)', collect, [])\n .option('--batch <spec>', 'Batch operation spec: collection_or_rel:op1,op2 (repeatable)', collect, [])\n .option('--sql-query', 'Enable sql_query tool')\n .option('--config <json>', 'Full endpoint config as JSON (supports name_override, description_override per tool). Use @file.json to read from file.')\n .action(async function (this: Command, slug: string, opts: {\n name?: string;\n description?: string;\n tool: string[];\n relationship: string[];\n batch: string[];\n sqlQuery?: boolean;\n config?: string;\n }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n\n let body: Record<string, unknown>;\n\n if (opts.config) {\n // Full JSON config — supports name_override, description_override per tool\n body = JSON.parse(opts.config);\n } else {\n if (!opts.name) {\n throw new Error('--name is required (or use --config for full JSON config)');\n }\n body = {\n name: opts.name,\n tools: opts.tool.map(parseToolSpec),\n };\n\n if (opts.description) body.description = opts.description;\n\n if (opts.relationship.length > 0) {\n body.relationships = opts.relationship.map(parseRelSpec);\n }\n\n if (opts.batch.length > 0) {\n const operations: Record<string, string[]> = {};\n for (const spec of opts.batch) {\n const parsed = parseSpec(spec);\n operations[parsed.key] = parsed.ops;\n }\n body.batch = { enabled: true, operations };\n }\n\n if (opts.sqlQuery) body.sql_query = true;\n }\n\n const data = await client.request('PUT', `/v1/${ws}/endpoints/${slug}`, body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nendpointsCommand.command('get <slug>')\n .description('Get an endpoint')\n .option('--resolved', 'Include resolved collection schemas')\n .action(async function (this: Command, slug: string, opts: { resolved?: boolean }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const path = opts.resolved\n ? `/v1/${ws}/endpoints/${slug}/resolved`\n : `/v1/${ws}/endpoints/${slug}`;\n const data = await client.request('GET', path);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nendpointsCommand.command('list')\n .description('List all endpoints')\n .action(async function (this: Command) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const data = await client.request('GET', `/v1/${ws}/endpoints`);\n console.log(formatOutput(data, getFormat(this)));\n });\n\nendpointsCommand.command('delete <slug>')\n .description('Delete an endpoint')\n .action(async function (this: Command, slug: string) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n await client.request('DELETE', `/v1/${ws}/endpoints/${slug}`);\n console.log('Deleted');\n });\n\nendpointsCommand.command('url <slug>')\n .description('Get the MCP connection URL for an endpoint')\n .option('--transport <type>', 'Transport: mcp or sse', 'mcp')\n .action((_slug: string, opts: { transport: string }) => {\n const transport = opts.transport === 'sse' ? 'sse' : 'mcp';\n console.log(`https://mcp.rekor.pro/e/${_slug}/${transport}`);\n });\n\n// ---- Helpers ----\n\nfunction collect(value: string, previous: string[]): string[] {\n return [...previous, value];\n}\n\nfunction parseSpec(spec: string): { key: string; ops: string[] } {\n const [key, opsStr] = spec.split(':');\n if (!key || !opsStr) {\n throw new Error(`Invalid spec '${spec}'. Expected format: name:op1,op2`);\n }\n return { key, ops: opsStr.split(',') };\n}\n\nfunction parseToolSpec(spec: string): Record<string, unknown> {\n const { key, ops } = parseSpec(spec);\n return { collection: key, operations: ops };\n}\n\nfunction parseRelSpec(spec: string): Record<string, unknown> {\n const { key, ops } = parseSpec(spec);\n return { rel_type: key, operations: ops };\n}\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\n\nexport const batchCommand = new Command('batch')\n .description('Execute atomic batch operations (up to 1,000 operations)')\n .requiredOption('--operations <json>', 'Operations array (inline JSON or @filename)')\n .action(async function (this: Command, opts: { operations: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const operations = parseData(opts.operations);\n const data = await client.request('POST', `/v1/${ws}/batch`, {\n operations: Array.isArray(operations) ? operations : [operations],\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { parseData, getWorkspace, getFormat } from '../helpers.js';\nconst VALID_PROVIDERS = 'openai, anthropic, google, mcp';\n\nexport const providersCommand = new Command('providers')\n .description('Import/export tool definitions between LLM providers and Record collections');\n\nprovidersCommand.command('import <provider>')\n .description(`Import tool definitions as collections. Providers: ${VALID_PROVIDERS}`)\n .requiredOption('--tools <json>', 'Tool definitions (inline JSON or @filename)')\n .action(async function (this: Command, provider: string, opts: { tools: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const tools = parseData(opts.tools);\n const data = await client.request('POST', `/v1/${ws}/providers/${provider}/import`, {\n tools: Array.isArray(tools) ? tools : [tools],\n });\n console.log(formatOutput(data, getFormat(this)));\n });\n\nprovidersCommand.command('export <provider>')\n .description(`Export collections as tool definitions. Providers: ${VALID_PROVIDERS}`)\n .option('--collections <ids>', 'Comma-separated collection IDs (omit for all)')\n .option('--output <file>', 'Write output to file')\n .action(async function (this: Command, provider: string, opts: { collections?: string; output?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const query = opts.collections ? `?collections=${opts.collections}` : '';\n const data = await client.request('GET', `/v1/${ws}/providers/${provider}/export${query}`);\n\n if (opts.output) {\n const { writeFileSync } = await import('fs');\n writeFileSync(opts.output, JSON.stringify(data, null, 2));\n console.log(`Written to ${opts.output}`);\n } else {\n console.log(formatOutput(data, getFormat(this)));\n }\n });\n\nprovidersCommand.command('import-call <provider> <collection>')\n .description(`Create a record from a tool call in provider format. Providers: ${VALID_PROVIDERS}`)\n .requiredOption('--data <json>', 'Tool call data in provider format (inline JSON or @filename)')\n .option('--external-id <id>', 'External ID for idempotent upsert')\n .option('--external-source <source>', 'External source identifier')\n .action(async function (this: Command, provider: string, collection: string, opts: { data: string; externalId?: string; externalSource?: string }) {\n const ws = getWorkspace(this);\n const client = new ApiClient();\n const callData = parseData(opts.data);\n const queryParts: string[] = [];\n if (opts.externalId) queryParts.push(`external_id=${encodeURIComponent(opts.externalId)}`);\n if (opts.externalSource) queryParts.push(`external_source=${encodeURIComponent(opts.externalSource)}`);\n const qs = queryParts.length ? `?${queryParts.join('&')}` : '';\n const data = await client.request('POST', `/v1/${ws}/providers/${provider}/records/${collection}${qs}`, callData);\n console.log(formatOutput(data, getFormat(this)));\n });\n","import { Command } from 'commander';\nimport { ApiClient } from '../client.js';\nimport { formatOutput } from '../output.js';\nimport { getFormat } from '../helpers.js';\n\nexport const tokensCommand = new Command('tokens')\n .description('Manage API tokens');\n\ntokensCommand.command('create')\n .description('Create a scoped API token')\n .requiredOption('--name <name>', 'Token name')\n .requiredOption('--grants <json>', 'Grant definitions as JSON array')\n .option('--expires-at <date>', 'Expiration date (ISO 8601, e.g., 2026-06-01T00:00:00Z)')\n .action(async function (this: Command, opts: { name: string; grants: string; expiresAt?: string }) {\n const client = new ApiClient();\n let grants: unknown;\n try {\n grants = JSON.parse(opts.grants);\n } catch {\n throw new Error('--grants must be valid JSON');\n }\n const body: Record<string, unknown> = { name: opts.name, grants };\n if (opts.expiresAt) body.expires_at = opts.expiresAt;\n const data = await client.request('POST', '/v1/tokens', body);\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntokensCommand.command('list')\n .description('List API tokens')\n .action(async function (this: Command) {\n const client = new ApiClient();\n const data = await client.request('GET', '/v1/tokens');\n console.log(formatOutput(data, getFormat(this)));\n });\n\ntokensCommand.command('revoke <token_id>')\n .description('Revoke an API token')\n .action(async function (this: Command, tokenId: string) {\n const client = new ApiClient();\n await client.request('DELETE', `/v1/tokens/${tokenId}`);\n console.log('Token revoked');\n });\n","{\n \"name\": \"rekor-cli\",\n \"version\": \"0.1.20\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"bin\": {\n \"rekor\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"dev\": \"tsup --watch\"\n },\n \"dependencies\": {\n \"@napi-rs/keyring\": \"^1.1.6\",\n \"chalk\": \"^5.4.1\",\n \"cli-table3\": \"^0.6.5\",\n \"commander\": \"^13.1.0\",\n \"open\": \"^11.0.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.5.0\",\n \"tsup\": \"^8.4.0\",\n \"typescript\": \"^5.8.2\",\n \"vitest\": \"~3.0.9\"\n }\n}\n","import { program } from './program.js';\n\nprogram.parse();\n"],"mappings":"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","names":["Command","Command","Command","Command","readFileSync","Command","Command","Command","Command","Command","Command","readFileSync","Command","readFileSync","Command","Command","Command","Command","Command","readFileSync","Command","readFileSync","Command","Command","randomUUID","Command","Command","randomUUID","Command","Command","Command","Command","Command","Command","writeFileSync","Command","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rekor-cli",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=20.0.0"