@inerrata-corporation/errata 2.0.0-dev.26 → 2.0.0-dev.27

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/errata.mjs +60 -35
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -20628,7 +20628,7 @@ import { randomUUID as randomUUID2 } from "node:crypto";
20628
20628
  function defaultConfig() {
20629
20629
  return {
20630
20630
  version: 1,
20631
- cloudUrl: process.env["ERRATA_CLOUD_URL"] ?? "http://localhost:8787",
20631
+ cloudUrl: process.env["ERRATA_CLOUD_URL"] ?? DEFAULT_CLOUD_URL,
20632
20632
  apiKey: null,
20633
20633
  accessToken: null,
20634
20634
  refreshToken: null,
@@ -20674,10 +20674,12 @@ function machineId() {
20674
20674
  saveConfig({ ...cfg, machineId: id });
20675
20675
  return id;
20676
20676
  }
20677
+ var DEFAULT_CLOUD_URL;
20677
20678
  var init_config = __esm({
20678
20679
  "src/config.ts"() {
20679
20680
  "use strict";
20680
20681
  init_paths();
20682
+ DEFAULT_CLOUD_URL = "https://inerrata-gateway.onrender.com";
20681
20683
  }
20682
20684
  });
20683
20685
 
@@ -20751,7 +20753,7 @@ function assertDeviceCodeEndpointAllowed(url2, inspection) {
20751
20753
  allowed: false,
20752
20754
  label: "gateway device-code blocked",
20753
20755
  reason: "device-code login mints legacy v1 keys, while gateway launch uses console-issued keys/JWTs",
20754
- guidance: "Use `errata login --token <console errk_...>` or `errata login --oauth`."
20756
+ guidance: "Use `errata login` for OAuth or `errata login --token <console errk_...>`."
20755
20757
  };
20756
20758
  throw new CloudEndpointPolicyError(formatCloudEndpointBlock(url2, decision), decision);
20757
20759
  }
@@ -20895,6 +20897,7 @@ function authedCloudClient(cfg, opts = {}) {
20895
20897
  accessToken: cfg.accessToken,
20896
20898
  ...cfg.refreshToken ? { refreshToken: cfg.refreshToken } : {},
20897
20899
  fetchFn,
20900
+ ...opts.timeoutMs ? { timeoutMs: opts.timeoutMs } : {},
20898
20901
  ...tokenEndpoint && cfg.refreshToken ? {
20899
20902
  refreshFn: (rt) => refreshAccessToken(opts.fetchFn ?? fetch, tokenEndpoint, {
20900
20903
  refreshToken: rt,
@@ -20913,9 +20916,13 @@ function authedCloudClient(cfg, opts = {}) {
20913
20916
  return new CloudClient({
20914
20917
  baseUrl,
20915
20918
  ...cfg.apiKey ? { apiKey: cfg.apiKey } : {},
20916
- fetchFn
20919
+ fetchFn,
20920
+ ...opts.timeoutMs ? { timeoutMs: opts.timeoutMs } : {}
20917
20921
  });
20918
20922
  }
20923
+ function hasCloudCredential(cfg) {
20924
+ return Boolean(cfg.accessToken || cfg.apiKey);
20925
+ }
20919
20926
  var init_cloud_auth = __esm({
20920
20927
  "src/cloud-auth.ts"() {
20921
20928
  "use strict";
@@ -34482,7 +34489,7 @@ function createMcpHandler(store, ctx = {}) {
34482
34489
  function buildToolContext() {
34483
34490
  try {
34484
34491
  const cfg = loadConfig();
34485
- if (cfg.consent.sync && cfg.apiKey && cfg.cloudUrl) {
34492
+ if (cfg.consent.sync && hasCloudCredential(cfg) && cfg.cloudUrl) {
34486
34493
  return { cloud: authedCloudClient(cfg) };
34487
34494
  }
34488
34495
  } catch {
@@ -40858,11 +40865,11 @@ var TelemetryRecorder = class {
40858
40865
  return out2;
40859
40866
  }
40860
40867
  /**
40861
- * Flush to the cloud iff consent + apiKey are present. Returns how many were
40868
+ * Flush to the cloud iff consent + a cloud credential are present. Returns how many were
40862
40869
  * accepted (0 when skipped). On network failure the batch is re-queued.
40863
40870
  */
40864
40871
  async flush(cloud, opts) {
40865
- if (!opts.consent || !opts.apiKey) {
40872
+ if (!opts.consent || !opts.credentialPresent) {
40866
40873
  this.drain();
40867
40874
  return { sent: 0, skipped: true };
40868
40875
  }
@@ -41156,6 +41163,7 @@ function autodetectProfile(root) {
41156
41163
 
41157
41164
  // src/engine.ts
41158
41165
  init_config();
41166
+ init_cloud_auth();
41159
41167
 
41160
41168
  // src/notify.ts
41161
41169
  init_config();
@@ -41274,7 +41282,7 @@ function maybeFlushDigests() {
41274
41282
  }
41275
41283
 
41276
41284
  // src/engine.ts
41277
- var DAEMON_VERSION = true ? "2.0.0-dev.26" : "2.0.0-alpha.0";
41285
+ var DAEMON_VERSION = true ? "2.0.0-dev.27" : "2.0.0-alpha.0";
41278
41286
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
41279
41287
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
41280
41288
  var GIT_OP_MUTE_MS = 4e3;
@@ -42277,7 +42285,7 @@ function createWorkspaceEngine(opts) {
42277
42285
  }
42278
42286
  const t = await telemetry.flush(cloud, {
42279
42287
  consent: freshCfg.consent.telemetry,
42280
- apiKey: opts.apiKey ?? freshCfg.apiKey
42288
+ credentialPresent: Boolean(opts.apiKey) || hasCloudCredential(freshCfg)
42281
42289
  });
42282
42290
  if (t.sent > 0) {
42283
42291
  console.log(`[errata] telemetry: ${t.sent} events sent`);
@@ -42314,6 +42322,8 @@ async function startDaemon(opts) {
42314
42322
  if (opts.apiKey) {
42315
42323
  merged.apiKey = opts.apiKey;
42316
42324
  merged.accessToken = null;
42325
+ merged.refreshToken = null;
42326
+ merged.tokenEndpoint = null;
42317
42327
  }
42318
42328
  const cloud = authedCloudClient(merged);
42319
42329
  let webUiUrl = "";
@@ -42463,7 +42473,6 @@ function pidAlive(pid) {
42463
42473
 
42464
42474
  // src/multi.ts
42465
42475
  init_dist();
42466
- init_src6();
42467
42476
  init_src4();
42468
42477
  import { readFileSync as readFileSync17, unlinkSync as unlinkSync3, writeFileSync as writeFileSync14 } from "node:fs";
42469
42478
 
@@ -43064,6 +43073,7 @@ function isDaemonAlive(lockPath) {
43064
43073
  // src/multi.ts
43065
43074
  init_config();
43066
43075
  init_cloud_endpoint_policy();
43076
+ init_cloud_auth();
43067
43077
  function normPath(p) {
43068
43078
  return p.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
43069
43079
  }
@@ -43098,21 +43108,25 @@ async function startMultiDaemon(opts = {}) {
43098
43108
  const cfg = loadConfig();
43099
43109
  const CLOUD_TIMEOUT_MS = 12e4;
43100
43110
  const initialCloudUrl = normalizeCloudUrl(opts.cloudUrl ?? cfg.cloudUrl);
43101
- const cloud = new CloudClient({
43102
- baseUrl: initialCloudUrl,
43103
- timeoutMs: CLOUD_TIMEOUT_MS,
43104
- fetchFn: guardCloudFetch(initialCloudUrl),
43105
- ...opts.apiKey ?? cfg.apiKey ? { apiKey: opts.apiKey ?? cfg.apiKey ?? void 0 } : {}
43106
- });
43111
+ const initialCfg = { ...cfg, cloudUrl: initialCloudUrl };
43112
+ if (opts.apiKey) {
43113
+ initialCfg.apiKey = opts.apiKey;
43114
+ initialCfg.accessToken = null;
43115
+ initialCfg.refreshToken = null;
43116
+ initialCfg.tokenEndpoint = null;
43117
+ }
43118
+ const cloud = authedCloudClient(initialCfg, { timeoutMs: CLOUD_TIMEOUT_MS });
43107
43119
  const cloudNow = () => {
43108
43120
  const c = loadConfig();
43109
43121
  const baseUrl2 = normalizeCloudUrl(opts.cloudUrl ?? c.cloudUrl);
43110
- return new CloudClient({
43111
- baseUrl: baseUrl2,
43112
- timeoutMs: CLOUD_TIMEOUT_MS,
43113
- fetchFn: guardCloudFetch(baseUrl2),
43114
- ...opts.apiKey ?? c.apiKey ? { apiKey: opts.apiKey ?? c.apiKey ?? void 0 } : {}
43115
- });
43122
+ const current = { ...c, cloudUrl: baseUrl2 };
43123
+ if (opts.apiKey) {
43124
+ current.apiKey = opts.apiKey;
43125
+ current.accessToken = null;
43126
+ current.refreshToken = null;
43127
+ current.tokenEndpoint = null;
43128
+ }
43129
+ return authedCloudClient(current, { timeoutMs: CLOUD_TIMEOUT_MS });
43116
43130
  };
43117
43131
  const sharedDbPath = sharedStorePath();
43118
43132
  ensureParent(sharedDbPath);
@@ -43813,7 +43827,7 @@ async function loginOAuthLoopback(opts) {
43813
43827
  if (opts.timeoutMs) {
43814
43828
  setTimeout(() => {
43815
43829
  server.close();
43816
- reject(new Error("login timed out \u2014 run `errata login --oauth` again"));
43830
+ reject(new Error("login timed out \u2014 run `errata login` again"));
43817
43831
  }, opts.timeoutMs).unref?.();
43818
43832
  }
43819
43833
  }
@@ -44087,8 +44101,8 @@ Commands:
44087
44101
  Flags: --port N (default 7891)
44088
44102
  mcp Run the MCP stdio server \u2014 the agent's full errata tool
44089
44103
  surface (navigation, problems, claims, burst, health)
44090
- login Register or sign in with the cloud
44091
- logout Clear local API key
44104
+ login Sign in with the cloud (OAuth by default; --device for legacy)
44105
+ logout Clear local cloud credentials
44092
44106
  sync now Flush outbox to the cloud once
44093
44107
  privacy Show what is collected/scrubbed + your consent state
44094
44108
  consent <channel> <on|off>
@@ -44100,7 +44114,7 @@ Commands:
44100
44114
  Desktop toasts on problem open/resolve + review ready
44101
44115
 
44102
44116
  Environment:
44103
- ERRATA_CLOUD_URL Cloud base URL (default http://localhost:8787)
44117
+ ERRATA_CLOUD_URL Cloud base URL (default ${DEFAULT_CLOUD_URL})
44104
44118
  ERRATA_ALLOW_DIRECT_V1_CLOUD=1 Allow non-local legacy v1 cloud testing
44105
44119
  `);
44106
44120
  }
@@ -44188,7 +44202,7 @@ async function cmdInit() {
44188
44202
  console.log("");
44189
44203
  console.log("Next:");
44190
44204
  console.log(" errata start # observe this repo");
44191
- if (!cfgNow.apiKey) {
44205
+ if (!hasCloudCredential(cfgNow)) {
44192
44206
  console.log(" errata login # connect a cloud account (or: --token <key>)");
44193
44207
  }
44194
44208
  if (!cfgNow.consent.sync) {
@@ -44288,7 +44302,7 @@ async function cmdStatus() {
44288
44302
  );
44289
44303
  console.log(` cloud:`);
44290
44304
  console.log(` url: ${cfg.cloudUrl}`);
44291
- console.log(` logged in: ${cfg.apiKey || cfg.accessToken ? `yes (${cfg.email})` : "no"}`);
44305
+ console.log(` logged in: ${hasCloudCredential(cfg) ? `yes (${cfg.email})` : "no"}`);
44292
44306
  const inspection = await inspectCloudEndpoint(cfg.cloudUrl);
44293
44307
  const decision = evaluateCloudEndpoint(cfg.cloudUrl, inspection);
44294
44308
  const service = inspection.service ? ` \xB7 service ${inspection.service}` : "";
@@ -44297,7 +44311,7 @@ async function cmdStatus() {
44297
44311
  console.log(` policy: blocked - ${decision.reason}`);
44298
44312
  if (decision.guidance) console.log(` ${decision.guidance}`);
44299
44313
  }
44300
- if (cfg.apiKey || cfg.accessToken) {
44314
+ if (hasCloudCredential(cfg)) {
44301
44315
  if (!decision.allowed) {
44302
44316
  console.log(
44303
44317
  ` reachable: ${inspection.reachable ? `yes (${inspection.probe})` : `no (${inspection.error ?? "unreachable"})`}`
@@ -44381,6 +44395,7 @@ function parseFlags(args2) {
44381
44395
  else if (a === "--token") out2.token = args2[++i2];
44382
44396
  else if (a.startsWith("--token=")) out2.token = a.slice("--token=".length);
44383
44397
  else if (a === "--oauth") out2.oauth = true;
44398
+ else if (a === "--device") out2.device = true;
44384
44399
  else if (!a.startsWith("--")) out2._.push(a);
44385
44400
  }
44386
44401
  return out2;
@@ -44406,6 +44421,9 @@ async function applyToken(cfg, token) {
44406
44421
  try {
44407
44422
  const me = await c.me();
44408
44423
  cfg.apiKey = token;
44424
+ cfg.accessToken = null;
44425
+ cfg.refreshToken = null;
44426
+ cfg.tokenEndpoint = null;
44409
44427
  cfg.userId = me.agentId;
44410
44428
  cfg.email = me.handle;
44411
44429
  saveConfig(cfg);
@@ -44442,7 +44460,7 @@ async function cmdLoginOAuth(cfg) {
44442
44460
  result = await loginOAuthLoopback({ cloudUrl: cfg.cloudUrl, timeoutMs: 5 * 6e4 });
44443
44461
  } catch (err2) {
44444
44462
  console.error(`oauth login failed: ${err2 instanceof Error ? err2.message : err2}`);
44445
- console.error(` fall back to device code: errata login`);
44463
+ console.error(` fall back to device code: errata login --device`);
44446
44464
  console.error(` or paste a key: errata login --token <key>`);
44447
44465
  process.exitCode = 1;
44448
44466
  return;
@@ -44450,6 +44468,7 @@ async function cmdLoginOAuth(cfg) {
44450
44468
  cfg.accessToken = result.tokens.accessToken;
44451
44469
  cfg.refreshToken = result.tokens.refreshToken ?? null;
44452
44470
  cfg.tokenEndpoint = result.tokenEndpoint;
44471
+ cfg.apiKey = null;
44453
44472
  saveConfig(cfg);
44454
44473
  try {
44455
44474
  const me = await authedCloudClient(cfg).me();
@@ -44469,7 +44488,7 @@ async function cmdLogin() {
44469
44488
  await applyToken(cfg, flags2.token);
44470
44489
  return;
44471
44490
  }
44472
- if (flags2.oauth) {
44491
+ if (flags2.oauth || !flags2.device) {
44473
44492
  await cmdLoginOAuth(cfg);
44474
44493
  return;
44475
44494
  }
@@ -44517,6 +44536,9 @@ async function cmdLogin() {
44517
44536
  if (poll.status === "pending") continue;
44518
44537
  if (poll.status === "authorized" && poll.apiKey) {
44519
44538
  cfg.apiKey = poll.apiKey;
44539
+ cfg.accessToken = null;
44540
+ cfg.refreshToken = null;
44541
+ cfg.tokenEndpoint = null;
44520
44542
  cfg.userId = poll.agentId ?? null;
44521
44543
  cfg.email = poll.handle ?? handle2;
44522
44544
  saveConfig(cfg);
@@ -44541,6 +44563,9 @@ async function cmdLogin() {
44541
44563
  async function cmdLogout() {
44542
44564
  const cfg = loadConfig();
44543
44565
  cfg.apiKey = null;
44566
+ cfg.accessToken = null;
44567
+ cfg.refreshToken = null;
44568
+ cfg.tokenEndpoint = null;
44544
44569
  cfg.userId = null;
44545
44570
  cfg.email = null;
44546
44571
  saveConfig(cfg);
@@ -44904,7 +44929,7 @@ async function cmdBurst(args2) {
44904
44929
  let ctx = {};
44905
44930
  if (!local) {
44906
44931
  const cfg = loadConfig();
44907
- if (cfg.apiKey || cfg.accessToken) ctx = { cloud: authedCloudClient(cfg) };
44932
+ if (hasCloudCredential(cfg)) ctx = { cloud: authedCloudClient(cfg) };
44908
44933
  }
44909
44934
  await withStore(async (store) => {
44910
44935
  const result = await runTool2(
@@ -45496,7 +45521,7 @@ async function cmdPrivacy() {
45496
45521
  sync: ${onoff(cfg.consent.sync)}
45497
45522
  telemetry: ${onoff(cfg.consent.telemetry)}
45498
45523
  packages: ${onoff(cfg.consent.contributePackages)}
45499
- logged in: ${cfg.apiKey ? `yes (${cfg.email})` : "no"}
45524
+ logged in: ${hasCloudCredential(cfg) ? `yes (${cfg.email})` : "no"}
45500
45525
 
45501
45526
  Change it: errata consent sync on | errata consent telemetry off
45502
45527
  Kill switch: errata consent all off (or errata logout to drop your key)
@@ -45519,8 +45544,8 @@ async function cmdConsent(args2) {
45519
45544
  console.log(
45520
45545
  `consent updated \u2192 sync=${cfg.consent.sync ? "on" : "off"} telemetry=${cfg.consent.telemetry ? "on" : "off"} packages=${cfg.consent.contributePackages ? "on" : "off"}`
45521
45546
  );
45522
- if ((channel === "sync" || channel === "all") && value && !cfg.apiKey) {
45523
- console.log(" note: run `errata login` to actually upload (no API key yet).");
45547
+ if ((channel === "sync" || channel === "all") && value && !hasCloudCredential(cfg)) {
45548
+ console.log(" note: run `errata login` to actually upload (no cloud credential yet).");
45524
45549
  }
45525
45550
  }
45526
45551
  async function cmdDash(args2) {
@@ -45812,7 +45837,7 @@ async function cmdNotifications(state) {
45812
45837
  }
45813
45838
  async function cmdFeedback(args2) {
45814
45839
  const cfg = loadConfig();
45815
- if (!cfg.apiKey) {
45840
+ if (!hasCloudCredential(cfg)) {
45816
45841
  console.error("not logged in \u2014 run `errata login` first.");
45817
45842
  process.exit(2);
45818
45843
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.0-dev.26",
3
+ "version": "2.0.0-dev.27",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {