@inerrata-corporation/errata 2.0.14-dev.3126 → 2.0.14-dev.3128

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 +202 -147
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -81027,7 +81027,7 @@ function createWatchBreaker(deps) {
81027
81027
  }
81028
81028
 
81029
81029
  // src/engine.ts
81030
- var DAEMON_VERSION = true ? "2.0.14-dev.3126" : "2.0.0-alpha.0";
81030
+ var DAEMON_VERSION = true ? "2.0.14-dev.3128" : "2.0.0-alpha.0";
81031
81031
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
81032
81032
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
81033
81033
  var GIT_OP_MUTE_MS = 4e3;
@@ -83521,6 +83521,151 @@ async function listenServer(fetchFn, port) {
83521
83521
  init_registry();
83522
83522
  init_identity2();
83523
83523
 
83524
+ // src/cli-identity.ts
83525
+ init_cloud_auth();
83526
+ init_config();
83527
+ init_consent();
83528
+ init_identity2();
83529
+ init_profile2();
83530
+
83531
+ // src/project-link.ts
83532
+ init_profile2();
83533
+ import { execFile as execFile3 } from "node:child_process";
83534
+ import { promisify } from "node:util";
83535
+ var execFileAsync = promisify(execFile3);
83536
+ function isClaimedElsewhere(err2) {
83537
+ if (!err2 || typeof err2 !== "object") return false;
83538
+ const e = err2;
83539
+ return e.status === 409 && e.code === "claimed_elsewhere";
83540
+ }
83541
+ function claimHoldStands(onDisk) {
83542
+ return Boolean(onDisk && !onDisk.projectId && onDisk.projectLinkHold);
83543
+ }
83544
+ var LINK_FIELDS = [
83545
+ "projectId",
83546
+ "projectLocator",
83547
+ "projectLinkHold",
83548
+ "projectLinkDisabled",
83549
+ "rootCommitReportedFor"
83550
+ ];
83551
+ function adoptLinkFields(into, from) {
83552
+ for (const k of LINK_FIELDS) {
83553
+ if (from[k] === void 0) delete into[k];
83554
+ else into[k] = from[k];
83555
+ }
83556
+ }
83557
+ async function readRootCommit(root) {
83558
+ try {
83559
+ const { stdout } = await execFileAsync("git", ["rev-list", "--max-parents=0", "HEAD"], {
83560
+ cwd: root,
83561
+ encoding: "utf8",
83562
+ timeout: 15e3,
83563
+ windowsHide: true
83564
+ });
83565
+ const sha2 = stdout.split(/\s+/).filter(Boolean).pop();
83566
+ return sha2 && /^[0-9a-f]{40,64}$/i.test(sha2) ? sha2.toLowerCase() : null;
83567
+ } catch {
83568
+ return null;
83569
+ }
83570
+ }
83571
+ async function ensureProjectLink(root, profile, client, rootCommit = readRootCommit) {
83572
+ if (profile.projectLinkDisabled) return { linked: false, reason: "disabled" };
83573
+ const locator = profile.repoLocator;
83574
+ if (!locator) return { linked: false, reason: "no-locator" };
83575
+ if (profile.projectId && profile.projectLocator === locator) {
83576
+ if (profile.rootCommitReportedFor !== profile.projectId && client.recordProjectRootCommit) {
83577
+ const sha2 = await rootCommit(root);
83578
+ if (sha2) {
83579
+ try {
83580
+ await client.recordProjectRootCommit(profile.projectId, sha2);
83581
+ profile.rootCommitReportedFor = profile.projectId;
83582
+ saveProfile(root, profile);
83583
+ } catch {
83584
+ }
83585
+ }
83586
+ }
83587
+ return { linked: false, reason: "already-linked" };
83588
+ }
83589
+ try {
83590
+ const sha2 = await rootCommit(root);
83591
+ const res = await client.resolveProject(locator, profile.name, sha2 ?? void 0);
83592
+ profile.projectId = res.project.id;
83593
+ profile.projectLocator = locator;
83594
+ if (sha2) profile.rootCommitReportedFor = res.project.id;
83595
+ delete profile.projectLinkHold;
83596
+ saveProfile(root, profile);
83597
+ return { linked: true, projectId: res.project.id, created: res.created };
83598
+ } catch (err2) {
83599
+ if (isClaimedElsewhere(err2)) {
83600
+ if (profile.projectLinkHold?.locator !== locator) {
83601
+ profile.projectLinkHold = { reason: "claimed-elsewhere", locator, since: Date.now() };
83602
+ saveProfile(root, profile);
83603
+ }
83604
+ return {
83605
+ linked: false,
83606
+ reason: "held",
83607
+ detail: "this repo is already on errata in another workspace \u2014 run `errata link` to join it or create your own project"
83608
+ };
83609
+ }
83610
+ return {
83611
+ linked: false,
83612
+ reason: "error",
83613
+ detail: err2 instanceof Error ? err2.message : String(err2)
83614
+ };
83615
+ }
83616
+ }
83617
+
83618
+ // src/cli-identity.ts
83619
+ init_registry();
83620
+ function workspaceCloud(cfg, entry, env2 = process.env) {
83621
+ if (registryCorrupt() && !env2["ERRATA_CONFIG_PATH"]) throw new IdentityBlockedError("workspace registry is unreadable");
83622
+ const identity = resolveWorkspaceIdentity(cfg, entry, env2);
83623
+ if (identity.invalid) throw new IdentityBlockedError(identity.reason);
83624
+ const name2 = identity.profileName ?? cfg.activeInstallationProfile;
83625
+ const profile = name2 ? cfg.installationProfiles[name2] : void 0;
83626
+ if (name2 && !profile) throw new IdentityBlockedError(`installation profile not found: ${name2}`);
83627
+ const config2 = profile ? { ...cfg, ...profile, activeInstallationProfile: name2 } : cfg;
83628
+ return {
83629
+ identity,
83630
+ config: config2,
83631
+ profile,
83632
+ hasCredential: hasCloudCredential(config2),
83633
+ client: name2 ? authedCloudClientForProfile(cfg, name2) : authedCloudClient(cfg),
83634
+ profileName: name2
83635
+ };
83636
+ }
83637
+ function configWithDeviceLogin(cfg, input) {
83638
+ const name2 = input.profileName.trim();
83639
+ if (!name2 || name2.length > 80) throw new Error("profile name must be 1\u201380 characters");
83640
+ const selected = input.makeDefault || cfg.activeInstallationProfile === name2;
83641
+ return {
83642
+ ...cfg,
83643
+ ...selected ? { ...input.profile, activeInstallationProfile: name2 } : {},
83644
+ installationProfiles: { ...cfg.installationProfiles, [name2]: input.profile }
83645
+ };
83646
+ }
83647
+ async function saveVerifiedInstallationProfile(name2, installationId, cfg) {
83648
+ const result = await authedCloudClient(cfg).context();
83649
+ if (result.context.installation_id?.toLowerCase() !== installationId.toLowerCase()) {
83650
+ throw new Error("credential belongs to a different installation (or is unbound); use login --device for the requested installation");
83651
+ }
83652
+ return saveInstallationProfile(name2, installationId, cfg);
83653
+ }
83654
+ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstallationProfile, log = console.log, env2 = process.env) {
83655
+ for (const entry of listWorkspaces()) {
83656
+ try {
83657
+ const cloud = workspaceCloud(cfg, entry, env2);
83658
+ if (cloud.profileName !== loggedInProfile || !cloud.hasCredential) continue;
83659
+ const profile = loadProfile(entry.path);
83660
+ if (!profile || !effectiveConsent(cloud.config, profile).sync) continue;
83661
+ refreshRepoLocator(entry.path, profile);
83662
+ const out2 = await ensureProjectLink(entry.path, profile, cloud.client);
83663
+ if (out2.linked) log(` linked ${profile.name} \u2192 project ${out2.projectId}${out2.created ? " (created)" : ""} \xB7 profile ${cloud.profileName ?? "default"}`);
83664
+ } catch {
83665
+ }
83666
+ }
83667
+ }
83668
+
83524
83669
  // src/instance-receipts.ts
83525
83670
  import { createHash as createHash18 } from "node:crypto";
83526
83671
  var FIELDS = ["contributedAtSeq", "cloudNodeId", "anchorsContributedDigest", "projectAnchorsContributedDigest", "semanticEdgesContributedDigest", "shipRefusedSinceSeq", "shipRefusedCount", "shipRefusedReason", "shipRefusedFingerprint"];
@@ -84912,93 +85057,6 @@ function liveCloudClient(src) {
84912
85057
  // src/multi.ts
84913
85058
  init_identity2();
84914
85059
 
84915
- // src/project-link.ts
84916
- init_profile2();
84917
- import { execFile as execFile3 } from "node:child_process";
84918
- import { promisify } from "node:util";
84919
- var execFileAsync = promisify(execFile3);
84920
- function isClaimedElsewhere(err2) {
84921
- if (!err2 || typeof err2 !== "object") return false;
84922
- const e = err2;
84923
- return e.status === 409 && e.code === "claimed_elsewhere";
84924
- }
84925
- function claimHoldStands(onDisk) {
84926
- return Boolean(onDisk && !onDisk.projectId && onDisk.projectLinkHold);
84927
- }
84928
- var LINK_FIELDS = [
84929
- "projectId",
84930
- "projectLocator",
84931
- "projectLinkHold",
84932
- "projectLinkDisabled",
84933
- "rootCommitReportedFor"
84934
- ];
84935
- function adoptLinkFields(into, from) {
84936
- for (const k of LINK_FIELDS) {
84937
- if (from[k] === void 0) delete into[k];
84938
- else into[k] = from[k];
84939
- }
84940
- }
84941
- async function readRootCommit(root) {
84942
- try {
84943
- const { stdout } = await execFileAsync("git", ["rev-list", "--max-parents=0", "HEAD"], {
84944
- cwd: root,
84945
- encoding: "utf8",
84946
- timeout: 15e3,
84947
- windowsHide: true
84948
- });
84949
- const sha2 = stdout.split(/\s+/).filter(Boolean).pop();
84950
- return sha2 && /^[0-9a-f]{40,64}$/i.test(sha2) ? sha2.toLowerCase() : null;
84951
- } catch {
84952
- return null;
84953
- }
84954
- }
84955
- async function ensureProjectLink(root, profile, client, rootCommit = readRootCommit) {
84956
- if (profile.projectLinkDisabled) return { linked: false, reason: "disabled" };
84957
- const locator = profile.repoLocator;
84958
- if (!locator) return { linked: false, reason: "no-locator" };
84959
- if (profile.projectId && profile.projectLocator === locator) {
84960
- if (profile.rootCommitReportedFor !== profile.projectId && client.recordProjectRootCommit) {
84961
- const sha2 = await rootCommit(root);
84962
- if (sha2) {
84963
- try {
84964
- await client.recordProjectRootCommit(profile.projectId, sha2);
84965
- profile.rootCommitReportedFor = profile.projectId;
84966
- saveProfile(root, profile);
84967
- } catch {
84968
- }
84969
- }
84970
- }
84971
- return { linked: false, reason: "already-linked" };
84972
- }
84973
- try {
84974
- const sha2 = await rootCommit(root);
84975
- const res = await client.resolveProject(locator, profile.name, sha2 ?? void 0);
84976
- profile.projectId = res.project.id;
84977
- profile.projectLocator = locator;
84978
- if (sha2) profile.rootCommitReportedFor = res.project.id;
84979
- delete profile.projectLinkHold;
84980
- saveProfile(root, profile);
84981
- return { linked: true, projectId: res.project.id, created: res.created };
84982
- } catch (err2) {
84983
- if (isClaimedElsewhere(err2)) {
84984
- if (profile.projectLinkHold?.locator !== locator) {
84985
- profile.projectLinkHold = { reason: "claimed-elsewhere", locator, since: Date.now() };
84986
- saveProfile(root, profile);
84987
- }
84988
- return {
84989
- linked: false,
84990
- reason: "held",
84991
- detail: "this repo is already on errata in another workspace \u2014 run `errata link` to join it or create your own project"
84992
- };
84993
- }
84994
- return {
84995
- linked: false,
84996
- reason: "error",
84997
- detail: err2 instanceof Error ? err2.message : String(err2)
84998
- };
84999
- }
85000
- }
85001
-
85002
85060
  // src/project-hydrate.ts
85003
85061
  init_src11();
85004
85062
  init_profile2();
@@ -89062,7 +89120,6 @@ async function startMultiDaemon(opts = {}) {
89062
89120
  // src/cli.ts
89063
89121
  init_src5();
89064
89122
  init_profile2();
89065
- init_consent();
89066
89123
  init_git_remote();
89067
89124
  init_config();
89068
89125
  init_src7();
@@ -90260,7 +90317,7 @@ Commands:
90260
90317
  login Sign in with the cloud. Default: short verification URL +
90261
90318
  typeable code (device-bridged OAuth). Flags: --browser
90262
90319
  (loopback code flow) \xB7 --token <key> \xB7
90263
- --device --installation <uuid> [--profile <name>]
90320
+ --device --installation <uuid> [--profile <name>] [--make-default]
90264
90321
  (headless, installation-bound console device authorization)
90265
90322
  logout Clear local cloud credentials
90266
90323
  doctor [--json] Verify profile, credential authority, renewal, endpoint,
@@ -90890,6 +90947,7 @@ function parseFlags(args2) {
90890
90947
  else if (a.startsWith("--token=")) out2.token = a.slice("--token=".length);
90891
90948
  else if (a === "--oauth") out2.oauth = true;
90892
90949
  else if (a === "--device") out2.device = true;
90950
+ else if (a === "--make-default") out2.makeDefault = true;
90893
90951
  else if (a === "--browser") out2.browser = true;
90894
90952
  else if (a === "--installation") out2.installation = args2[++i2];
90895
90953
  else if (a.startsWith("--installation=")) out2.installation = a.slice("--installation=".length);
@@ -90963,6 +91021,8 @@ async function applyToken(cfg, token) {
90963
91021
  cfg.oauthClientId = null;
90964
91022
  cfg.userId = me.agentId;
90965
91023
  cfg.email = me.handle;
91024
+ cfg.activeInstallationProfile = null;
91025
+ cfg.activeAgent = null;
90966
91026
  saveConfig(cfg);
90967
91027
  console.log(`logged in as ${me.handle} (${me.tier}) \u2014 key stored`);
90968
91028
  return true;
@@ -91013,7 +91073,9 @@ async function cmdLoginOAuth(cfg, useBrowserLoopback = false) {
91013
91073
  refreshToken: result.tokens.refreshToken ?? null,
91014
91074
  tokenEndpoint: result.tokenEndpoint,
91015
91075
  oauthClientId: result.clientId,
91016
- apiKey: null
91076
+ apiKey: null,
91077
+ activeInstallationProfile: null,
91078
+ activeAgent: null
91017
91079
  };
91018
91080
  try {
91019
91081
  const me = await authedCloudClient(nextCfg).me();
@@ -91054,58 +91116,38 @@ async function cmdLoginOAuthDevice(cfg, input) {
91054
91116
  console.log(`code: ${userCode} \xB7 expires in ${Math.round(expiresInSec / 60)} minutes`);
91055
91117
  }
91056
91118
  });
91057
- const nextCfg = {
91058
- ...cfg,
91059
- apiKey: null,
91060
- accessToken: result.tokens.accessToken,
91061
- refreshToken: result.tokens.refreshToken ?? null,
91062
- tokenEndpoint: result.tokenEndpoint,
91063
- oauthClientId: result.clientId,
91064
- activeInstallationProfile: profileName,
91065
- installationProfiles: {
91066
- ...cfg.installationProfiles,
91067
- [profileName]: {
91068
- installationId: result.installationId,
91069
- cloudUrl: cfg.cloudUrl,
91070
- apiKey: null,
91071
- accessToken: result.tokens.accessToken,
91072
- refreshToken: result.tokens.refreshToken ?? null,
91073
- tokenEndpoint: result.tokenEndpoint,
91074
- oauthClientId: result.clientId,
91075
- activeAgent: cfg.activeAgent
91076
- }
91119
+ const nextCfg = configWithDeviceLogin(loadConfig(), {
91120
+ profileName,
91121
+ makeDefault: input.makeDefault ?? !input.profileName,
91122
+ profile: {
91123
+ installationId: result.installationId,
91124
+ cloudUrl: cfg.cloudUrl,
91125
+ apiKey: null,
91126
+ accessToken: result.tokens.accessToken,
91127
+ refreshToken: result.tokens.refreshToken ?? null,
91128
+ tokenEndpoint: result.tokenEndpoint,
91129
+ oauthClientId: result.clientId,
91130
+ activeAgent: null
91077
91131
  }
91078
- };
91079
- const me = await authedCloudClient(nextCfg).me();
91080
- nextCfg.userId = me.agentId;
91081
- nextCfg.email = me.handle;
91132
+ });
91133
+ const me = await authedCloudClientForProfile(nextCfg, profileName).me();
91134
+ if (nextCfg.activeInstallationProfile === profileName) {
91135
+ nextCfg.userId = me.agentId;
91136
+ nextCfg.email = me.handle;
91137
+ }
91082
91138
  saveConfig(nextCfg);
91083
91139
  console.log(
91084
91140
  `logged in as ${me.handle} (${me.tier}) \xB7 profile ${profileName} \xB7 installation ${result.installationId}`
91085
91141
  );
91086
- await linkRegisteredWorkspaces(nextCfg);
91142
+ await linkRegisteredWorkspaces(nextCfg, profileName);
91143
+ console.log(`machine default: ${nextCfg.activeInstallationProfile ?? "top-level credential"}; workspaces using this profile: ${listWorkspaces().filter((w) => w.installationProfile === profileName || !w.installationProfile && nextCfg.activeInstallationProfile === profileName).map((w) => w.name).join(", ") || "none (bind a workspace to use it)"}`);
91087
91144
  } catch (err2) {
91088
91145
  console.error(`device login failed: ${err2 instanceof Error ? err2.message : err2}`);
91089
91146
  console.error(" no credential was stored; retry from Console \u2192 Connect");
91090
91147
  process.exitCode = 1;
91091
91148
  }
91092
91149
  }
91093
- async function linkRegisteredWorkspaces(cfg) {
91094
- const client = authedCloudClient(cfg);
91095
- for (const w of listWorkspaces()) {
91096
- try {
91097
- const profile = loadProfile(w.path);
91098
- if (!profile || !effectiveConsent(cfg, profile).sync) continue;
91099
- refreshRepoLocator(w.path, profile);
91100
- const out2 = await ensureProjectLink(w.path, profile, client);
91101
- if (out2.linked) {
91102
- console.log(` linked ${profile.name} \u2192 project ${out2.projectId}${out2.created ? " (created)" : ""}`);
91103
- }
91104
- } catch {
91105
- }
91106
- }
91107
- }
91108
- async function bindWorkspaceToLinkInstallation(cfg, out2, orgId) {
91150
+ async function bindWorkspaceToLinkInstallation(cfg, out2, orgId, cloudUrl) {
91109
91151
  const installationId = out2.installationId;
91110
91152
  if (!out2.deviceSession) {
91111
91153
  console.warn(
@@ -91129,7 +91171,7 @@ async function bindWorkspaceToLinkInstallation(cfg, out2, orgId) {
91129
91171
  ...cfg.installationProfiles,
91130
91172
  [profileName]: {
91131
91173
  installationId,
91132
- cloudUrl: cfg.cloudUrl,
91174
+ cloudUrl,
91133
91175
  apiKey: null,
91134
91176
  accessToken: minted.tokens.accessToken,
91135
91177
  refreshToken: minted.tokens.refreshToken ?? null,
@@ -91161,8 +91203,9 @@ async function cmdLink(args2) {
91161
91203
  return;
91162
91204
  }
91163
91205
  const cfg = loadConfig();
91206
+ const cloud = workspaceCloud(cfg, workspaceEntryForPath(ROOT));
91164
91207
  const wantsLocal = args2.includes("--local") || Boolean(flag("--project")) || Boolean(flag("--name"));
91165
- if (wantsLocal && !hasCloudCredential(cfg)) {
91208
+ if (wantsLocal && !cloud.hasCredential) {
91166
91209
  console.error("not logged in \u2014 run `errata login` first (linking needs your cloud identity)");
91167
91210
  process.exitCode = 1;
91168
91211
  return;
@@ -91187,7 +91230,7 @@ async function cmdLink(args2) {
91187
91230
  return;
91188
91231
  }
91189
91232
  saveProfile(ROOT, profile);
91190
- const activeProfile = cfg.activeInstallationProfile ? cfg.installationProfiles[cfg.activeInstallationProfile] : void 0;
91233
+ const activeProfile = cloud.profile;
91191
91234
  const facts = {
91192
91235
  locator: profile.repoLocator,
91193
91236
  name: profile.name,
@@ -91196,7 +91239,7 @@ async function cmdLink(args2) {
91196
91239
  };
91197
91240
  try {
91198
91241
  const out3 = await linkThroughConsole({
91199
- cloudUrl: cfg.cloudUrl,
91242
+ cloudUrl: cloud.config.cloudUrl,
91200
91243
  facts,
91201
91244
  timeoutMs: 15 * 6e4,
91202
91245
  onVerification: ({ url: url2, userCode, expiresInSec }) => {
@@ -91229,24 +91272,28 @@ async function cmdLink(args2) {
91229
91272
  );
91230
91273
  await refreshLinkedCodexHooks(args2);
91231
91274
  if (applied.wroteIgnore) console.log("wrote .errataignore (starter) \u2014 edit it; it is your hard control");
91232
- let reportClient = authedCloudClient(applied.config);
91275
+ let reportCloud = workspaceCloud(applied.config, workspaceEntryForPath(ROOT));
91276
+ let reportClient = reportCloud.client;
91233
91277
  if (out3.installationId && out3.installationId !== activeProfile?.installationId) {
91234
- const bound = await bindWorkspaceToLinkInstallation(applied.config, out3, d.orgId);
91278
+ const bound = await bindWorkspaceToLinkInstallation(applied.config, out3, d.orgId, cloud.config.cloudUrl);
91235
91279
  if (bound) {
91236
- reportClient = authedCloudClientForProfile(bound.config, bound.profileName);
91280
+ reportCloud = workspaceCloud(bound.config, workspaceEntryForPath(ROOT));
91281
+ reportClient = reportCloud.client;
91237
91282
  console.log(
91238
91283
  `this workspace now uses installation ${out3.installationId.slice(0, 8)} (profile ${bound.profileName}) in org ${d.orgId.slice(0, 8)}; your machine default is unchanged`
91239
91284
  );
91285
+ } else {
91286
+ return;
91240
91287
  }
91241
91288
  }
91242
- if (!hasCloudCredential(cfg)) {
91289
+ if (!reportCloud.hasCredential) {
91243
91290
  console.log(" note: run `errata login` so this daemon can sync under the link and report the history stage.");
91244
91291
  return;
91245
91292
  }
91246
91293
  const consents = historyConsents(applied.profile);
91247
91294
  const reported = await reportHistoryStage(reportClient, applied.profile, (line) => console.warn(line));
91248
91295
  if (reported?.consents) {
91249
- const synced = applyConsents(applied.profile, applied.config, reported.consents, (/* @__PURE__ */ new Date()).toISOString());
91296
+ const synced = applyConsents(applied.profile, loadConfig(), reported.consents, (/* @__PURE__ */ new Date()).toISOString());
91250
91297
  if (synced.changed) {
91251
91298
  saveProfile(ROOT, synced.profile);
91252
91299
  saveConfig(synced.config);
@@ -91258,7 +91305,7 @@ async function cmdLink(args2) {
91258
91305
  return;
91259
91306
  } catch (err2) {
91260
91307
  const message2 = err2 instanceof Error ? err2.message : String(err2);
91261
- if (!/does not offer the link flow/.test(message2) || !hasCloudCredential(cfg)) {
91308
+ if (!/does not offer the link flow/.test(message2) || !cloud.hasCredential) {
91262
91309
  console.error(`link failed: ${message2}`);
91263
91310
  process.exitCode = 1;
91264
91311
  return;
@@ -91266,7 +91313,7 @@ async function cmdLink(args2) {
91266
91313
  console.log(`${message2}; falling back to the ambient resolve`);
91267
91314
  }
91268
91315
  }
91269
- const client = authedCloudClient(cfg);
91316
+ const client = cloud.client;
91270
91317
  const adoptId = flag("--project");
91271
91318
  if (adoptId) {
91272
91319
  if (!profile.repoLocator) {
@@ -91323,7 +91370,12 @@ async function cmdUnlink() {
91323
91370
  async function cmdLogin() {
91324
91371
  const cfg = loadConfig();
91325
91372
  const flags2 = parseFlags(rest);
91326
- if (flags2.cloud) applyCloudUrl(cfg, flags2.cloud);
91373
+ if (flags2.profile && (!flags2.device || flags2.token)) {
91374
+ console.error("--profile requires --device --installation <uuid>; the machine default was not changed");
91375
+ process.exitCode = 1;
91376
+ return;
91377
+ }
91378
+ if (flags2.cloud) cfg.cloudUrl = normalizeCloudUrl(flags2.cloud);
91327
91379
  if (flags2.token) {
91328
91380
  await applyToken(cfg, flags2.token);
91329
91381
  printBoundWorkspaceNotice();
@@ -91337,7 +91389,8 @@ async function cmdLogin() {
91337
91389
  }
91338
91390
  await cmdLoginOAuthDevice(cfg, {
91339
91391
  installationId: flags2.installation,
91340
- ...flags2.profile ? { profileName: flags2.profile } : {}
91392
+ ...flags2.profile ? { profileName: flags2.profile } : {},
91393
+ ...flags2.makeDefault ? { makeDefault: true } : {}
91341
91394
  });
91342
91395
  printBoundWorkspaceNotice();
91343
91396
  return;
@@ -91399,6 +91452,8 @@ async function cmdLogin() {
91399
91452
  cfg.oauthClientId = null;
91400
91453
  cfg.userId = poll.agentId ?? null;
91401
91454
  cfg.email = poll.handle ?? handle2;
91455
+ cfg.activeInstallationProfile = null;
91456
+ cfg.activeAgent = null;
91402
91457
  saveConfig(cfg);
91403
91458
  try {
91404
91459
  const me = await authedCloudClient(cfg).me();
@@ -91459,7 +91514,7 @@ function printBoundWorkspaceNotice() {
91459
91514
  } catch {
91460
91515
  }
91461
91516
  }
91462
- function cmdInstallationProfile(args2) {
91517
+ async function cmdInstallationProfile(args2) {
91463
91518
  const cfg = loadConfig();
91464
91519
  const action = args2[0] ?? "list";
91465
91520
  if (action === "list") {
@@ -91496,7 +91551,7 @@ function cmdInstallationProfile(args2) {
91496
91551
  if (!hasCloudCredential(cfg)) {
91497
91552
  throw new Error("not logged in \u2014 install the Console credential before saving a profile");
91498
91553
  }
91499
- saveInstallationProfile(name2, installationId, cfg);
91554
+ await saveVerifiedInstallationProfile(name2, installationId, cfg);
91500
91555
  console.log(`profile saved: ${name2} \xB7 installation ${installationId}`);
91501
91556
  return;
91502
91557
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.14-dev.3126",
3
+ "version": "2.0.14-dev.3128",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {