rudel 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +37 -65
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1889,7 +1889,7 @@ async function run(app, inputs, context) {
1889
1889
  // package.json
1890
1890
  var package_default = {
1891
1891
  name: "rudel",
1892
- version: "0.1.15",
1892
+ version: "0.1.16",
1893
1893
  type: "module",
1894
1894
  description: "CLI for the Coding Agent Analytics Platform rudel.ai",
1895
1895
  license: "MIT",
@@ -18356,10 +18356,8 @@ async function runEnable() {
18356
18356
  failureStage: "auth_verify",
18357
18357
  error: auth.reason
18358
18358
  });
18359
- R2.error(auth.message);
18360
18359
  Gt("Run `rudel login` to authenticate.");
18361
- process.exitCode = 1;
18362
- return;
18360
+ return new Error(auth.message);
18363
18361
  }
18364
18362
  const { credentials } = auth;
18365
18363
  let orgs;
@@ -18376,9 +18374,7 @@ async function runEnable() {
18376
18374
  error,
18377
18375
  userId: auth.user.id
18378
18376
  });
18379
- R2.error("Failed to fetch organizations. Check your connection.");
18380
- process.exitCode = 1;
18381
- return;
18377
+ return new Error("Failed to fetch organizations. Check your connection.");
18382
18378
  }
18383
18379
  }
18384
18380
  if (orgs.length === 0) {
@@ -18388,10 +18384,8 @@ async function runEnable() {
18388
18384
  error: new Error("No organizations found"),
18389
18385
  userId: auth.user.id
18390
18386
  });
18391
- R2.error("No organizations found.");
18392
18387
  Gt("Create one at app.rudel.ai first.");
18393
- process.exitCode = 1;
18394
- return;
18388
+ return new Error("No organizations found.");
18395
18389
  }
18396
18390
  const cwd = process.cwd();
18397
18391
  const existingOrgId = await getProjectOrgId(cwd);
@@ -18538,7 +18532,7 @@ async function runEnable() {
18538
18532
  }
18539
18533
  Gt("Done!");
18540
18534
  if (totalFailed > 0 || hookInstallFailures > 0) {
18541
- process.exitCode = 1;
18535
+ return new Error(`Enable completed with ${hookInstallFailures} hook installation failure(s) and ${totalFailed} upload failure(s).`);
18542
18536
  }
18543
18537
  }
18544
18538
  var enableCommand = buildCommand({
@@ -20789,9 +20783,7 @@ async function runLogin(flags) {
20789
20783
  deviceCode = await requestDeviceCode(flags.apiBase);
20790
20784
  } catch (error) {
20791
20785
  captureLoginFailure("device_code_request", error);
20792
- R2.error(error instanceof Error ? error.message : String(error));
20793
- process.exitCode = 1;
20794
- return;
20786
+ return error instanceof Error ? error : new Error(String(error));
20795
20787
  }
20796
20788
  const verifyUrl = deviceCode.verification_uri_complete ?? `${deviceCode.verification_uri}?user_code=${encodeURIComponent(deviceCode.user_code)}`;
20797
20789
  captureCliProductAnalyticsEvent({
@@ -20821,9 +20813,7 @@ ${verifyUrl}`);
20821
20813
  const failureReason = normalizeFailureReason(error);
20822
20814
  captureLoginFailure(failureReason === "timeout" ? "browser_approval_timeout" : "token_exchange", error);
20823
20815
  spin.stop("Authentication failed");
20824
- R2.error(error instanceof Error ? error.message : String(error));
20825
- process.exitCode = 1;
20826
- return;
20816
+ return error instanceof Error ? error : new Error(String(error));
20827
20817
  }
20828
20818
  spin.message("Creating ingest token...");
20829
20819
  let ingestKey;
@@ -20832,9 +20822,7 @@ ${verifyUrl}`);
20832
20822
  } catch (error) {
20833
20823
  captureLoginFailure("api_key_create", error);
20834
20824
  spin.stop("Authentication failed");
20835
- R2.error(error instanceof Error ? error.message : String(error));
20836
- process.exitCode = 1;
20837
- return;
20825
+ return error instanceof Error ? error : new Error(String(error));
20838
20826
  }
20839
20827
  const client2 = createApiClient({
20840
20828
  apiBaseUrl: flags.apiBase,
@@ -20857,9 +20845,7 @@ ${verifyUrl}`);
20857
20845
  } catch (error) {
20858
20846
  captureLoginFailure("account_fetch", error);
20859
20847
  spin.stop("Authentication failed");
20860
- R2.error("Login failed: unable to fetch account details");
20861
- process.exitCode = 1;
20862
- return;
20848
+ return new Error("Login failed: unable to fetch account details");
20863
20849
  }
20864
20850
  try {
20865
20851
  saveCredentials({
@@ -20873,9 +20859,7 @@ ${verifyUrl}`);
20873
20859
  } catch (error) {
20874
20860
  captureLoginFailure("account_fetch", error);
20875
20861
  spin.stop("Authentication failed");
20876
- R2.error("Login failed: unable to persist credentials");
20877
- process.exitCode = 1;
20878
- return;
20862
+ return new Error("Login failed: unable to persist credentials");
20879
20863
  }
20880
20864
  captureCliProductAnalyticsEvent({
20881
20865
  distinctId: user.id,
@@ -20921,26 +20905,35 @@ var loginCommand = buildCommand({
20921
20905
  });
20922
20906
 
20923
20907
  // src/commands/logout.ts
20924
- async function runLogout() {
20908
+ async function runLogout(flags) {
20925
20909
  const credentials = loadCredentials();
20926
20910
  if (!credentials) {
20927
20911
  R2.info("Not logged in.");
20928
20912
  return;
20929
20913
  }
20930
- if (credentials.authType === "api-key") {
20914
+ if (credentials.authType === "api-key" && !flags.localOnly) {
20931
20915
  try {
20932
20916
  const client2 = createApiClient(credentials);
20933
20917
  await client2.cli.revokeToken();
20934
- } catch {
20935
- R2.warn("Failed to revoke token on server. Local credentials were cleared.");
20918
+ } catch (error) {
20919
+ const message = error instanceof Error ? error.message : String(error);
20920
+ return new Error(`Failed to revoke token on server: ${message}. Credentials were kept; retry or run \`rudel logout --local-only\`.`);
20936
20921
  }
20937
20922
  }
20938
20923
  clearCredentials();
20939
- R2.success("Logged out successfully.");
20924
+ R2.success(flags.localOnly ? "Logged out locally. Server token was not revoked." : "Logged out successfully.");
20940
20925
  }
20941
20926
  var logoutCommand = buildCommand({
20942
20927
  loader: async () => ({ default: runLogout }),
20943
- parameters: {},
20928
+ parameters: {
20929
+ flags: {
20930
+ localOnly: {
20931
+ kind: "boolean",
20932
+ brief: "Clear local credentials without revoking the server token",
20933
+ default: false
20934
+ }
20935
+ }
20936
+ },
20944
20937
  docs: {
20945
20938
  brief: "Log out and remove stored credentials"
20946
20939
  }
@@ -20951,10 +20944,8 @@ async function runSetOrg() {
20951
20944
  Wt2("rudel set-org");
20952
20945
  const credentials = loadCredentials();
20953
20946
  if (!credentials) {
20954
- R2.error("Not authenticated.");
20955
20947
  Gt("Run `rudel login` first.");
20956
- process.exitCode = 1;
20957
- return;
20948
+ return new Error("Not authenticated.");
20958
20949
  }
20959
20950
  let orgs;
20960
20951
  if (credentials.authType === "api-key") {
@@ -20964,16 +20955,12 @@ async function runSetOrg() {
20964
20955
  try {
20965
20956
  orgs = await client2.listMyOrganizations();
20966
20957
  } catch {
20967
- R2.error("Failed to fetch organizations. Check your connection.");
20968
- process.exitCode = 1;
20969
- return;
20958
+ return new Error("Failed to fetch organizations. Check your connection.");
20970
20959
  }
20971
20960
  }
20972
20961
  if (orgs.length === 0) {
20973
- R2.error("No organizations found.");
20974
20962
  Gt("Create one at app.rudel.ai first.");
20975
- process.exitCode = 1;
20976
- return;
20963
+ return new Error("No organizations found.");
20977
20964
  }
20978
20965
  const cwd = process.cwd();
20979
20966
  const currentOrgId = await getProjectOrgId(cwd);
@@ -21147,9 +21134,7 @@ function validateNotSubagent(filename) {
21147
21134
  async function runInteractiveUpload(flags) {
21148
21135
  const credentials = loadCredentials();
21149
21136
  if (!credentials && !flags.dryRun) {
21150
- R2.error("Not authenticated. Run `rudel login` first.");
21151
- process.exitCode = 1;
21152
- return;
21137
+ return new Error("Not authenticated. Run `rudel login` first.");
21153
21138
  }
21154
21139
  Wt2("rudel upload");
21155
21140
  const spin = be();
@@ -21242,7 +21227,7 @@ async function runInteractiveUpload(flags) {
21242
21227
  Gt("Done!");
21243
21228
  }
21244
21229
  if (summary.failed > 0) {
21245
- process.exitCode = 1;
21230
+ return new Error(`${summary.failed} upload(s) failed.`);
21246
21231
  }
21247
21232
  }
21248
21233
  function getAdapterName(source) {
@@ -21254,26 +21239,18 @@ function sessionCountHint(count) {
21254
21239
  async function runSingleUpload(flags, session) {
21255
21240
  const write = (msg) => {
21256
21241
  process.stdout.write(`${msg}
21257
- `);
21258
- };
21259
- const writeError = (msg) => {
21260
- process.stderr.write(`${msg}
21261
21242
  `);
21262
21243
  };
21263
21244
  const credentials = loadCredentials();
21264
21245
  if (!credentials && !flags.dryRun) {
21265
- writeError("Error: Not authenticated. Run `rudel login` first.");
21266
- process.exitCode = 1;
21267
- return;
21246
+ return new Error("Not authenticated. Run `rudel login` first.");
21268
21247
  }
21269
21248
  write(`Resolving session: ${session}`);
21270
21249
  let sessionInfo;
21271
21250
  try {
21272
21251
  sessionInfo = await resolveSession(session);
21273
21252
  } catch (error) {
21274
- writeError(`Error: ${error instanceof Error ? error.message : String(error)}`);
21275
- process.exitCode = 1;
21276
- return;
21253
+ return error instanceof Error ? error : new Error(String(error));
21277
21254
  }
21278
21255
  write(`Found session at: ${sessionInfo.transcriptPath}`);
21279
21256
  const gitInfo = await getGitInfo(sessionInfo.projectPath);
@@ -21331,16 +21308,13 @@ async function runSingleUpload(flags, session) {
21331
21308
  if (result.success) {
21332
21309
  write("Upload successful!");
21333
21310
  } else {
21334
- writeError(`Upload failed: ${result.error}`);
21335
- process.exitCode = 1;
21311
+ return new Error(`Upload failed: ${result.error}`);
21336
21312
  }
21337
21313
  }
21338
21314
  async function runRetryUpload(flags) {
21339
21315
  const credentials = loadCredentials();
21340
21316
  if (!credentials) {
21341
- R2.error("Not authenticated. Run `rudel login` first.");
21342
- process.exitCode = 1;
21343
- return;
21317
+ return new Error("Not authenticated. Run `rudel login` first.");
21344
21318
  }
21345
21319
  Wt2("rudel upload --retry");
21346
21320
  const failures = await loadFailedUploads();
@@ -21403,7 +21377,7 @@ async function runRetryUpload(flags) {
21403
21377
  renderBatchSummary(summary);
21404
21378
  Gt("Done!");
21405
21379
  if (summary.failed > 0) {
21406
- process.exitCode = 1;
21380
+ return new Error(`${summary.failed} upload(s) failed.`);
21407
21381
  }
21408
21382
  }
21409
21383
  async function runUpload(flags, ...sessions) {
@@ -21487,11 +21461,9 @@ async function runWhoami() {
21487
21461
  if (!result.authenticated) {
21488
21462
  if (result.reason === "no_credentials") {
21489
21463
  R2.info("Not logged in. Run `rudel login` to authenticate.");
21490
- } else {
21491
- R2.error(result.message);
21492
- process.exitCode = 1;
21464
+ return;
21493
21465
  }
21494
- return;
21466
+ return new Error(result.message);
21495
21467
  }
21496
21468
  R2.info(`Logged in as ${result.user.name} (${result.user.email})`);
21497
21469
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rudel",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "type": "module",
5
5
  "description": "CLI for the Coding Agent Analytics Platform rudel.ai",
6
6
  "license": "MIT",