@inerrata-corporation/errata 2.0.17 → 2.0.18-dev.3597

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/errata.mjs CHANGED
@@ -27795,8 +27795,8 @@ var init_config = __esm({
27795
27795
  "use strict";
27796
27796
  init_paths();
27797
27797
  LEGACY_CLOUD_URL = "https://inerrata-gateway.onrender.com";
27798
- DEFAULT_CLOUD_URL = true ? "https://inerrata.dev" : DEV_CLOUD_URL;
27799
- DEFAULT_UPDATE_CHANNEL = true ? "latest" : "dev";
27798
+ DEFAULT_CLOUD_URL = true ? "https://dev.inerrata.dev" : DEV_CLOUD_URL;
27799
+ DEFAULT_UPDATE_CHANNEL = false ? "latest" : "dev";
27800
27800
  }
27801
27801
  });
27802
27802
 
@@ -82685,7 +82685,7 @@ function createWatchBreaker(deps) {
82685
82685
  }
82686
82686
 
82687
82687
  // src/engine.ts
82688
- var DAEMON_VERSION = true ? "2.0.17" : "2.0.0-alpha.0";
82688
+ var DAEMON_VERSION = true ? "2.0.18-dev.3597" : "2.0.0-alpha.0";
82689
82689
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
82690
82690
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
82691
82691
  var GIT_OP_MUTE_MS = 4e3;
@@ -85531,6 +85531,17 @@ function workspaceCloud(cfg, entry, env2 = process.env) {
85531
85531
  profileName: name2
85532
85532
  };
85533
85533
  }
85534
+ function reportedIdentity(cfg, entry, env2 = process.env) {
85535
+ try {
85536
+ const ws = workspaceCloud(cfg, entry, env2);
85537
+ const machineDefault = cfg.activeInstallationProfile;
85538
+ const note = entry && ws.profileName !== machineDefault ? `this workspace pushes as profile "${ws.profileName ?? "top-level credential"}" (${ws.identity.reason}); machine default is "${machineDefault ?? "top-level credential"}"` : null;
85539
+ return { ok: true, config: ws.config, client: ws.client, profileName: ws.profileName, note };
85540
+ } catch (err2) {
85541
+ if (err2 instanceof IdentityBlockedError) return { ok: false, reason: err2.message };
85542
+ throw err2;
85543
+ }
85544
+ }
85534
85545
  function configWithDeviceLogin(cfg, input) {
85535
85546
  const name2 = input.profileName.trim();
85536
85547
  if (!name2 || name2.length > 80) throw new Error("profile name must be 1\u201380 characters");
@@ -92916,6 +92927,10 @@ async function main() {
92916
92927
  return cmdLogout();
92917
92928
  case "link":
92918
92929
  return cmdLink(rest);
92930
+ // Moving a workspace to another org/team IS the console link flow (the
92931
+ // page offers every org and team the person is in); `switch` names it.
92932
+ case "switch":
92933
+ return cmdLink(rest.filter((a) => a !== "--local"));
92919
92934
  case "unlink":
92920
92935
  return cmdUnlink();
92921
92936
  case "use":
@@ -93074,6 +93089,10 @@ Commands:
93074
93089
  --remote <name> derive the locator from a non-origin remote;
93075
93090
  --name <name> mint a locator-less project; no flags = re-resolve now
93076
93091
  --skip-hooks leave existing harness configuration unchanged
93092
+ switch Move THIS workspace to another of your orgs or teams (e.g. a
93093
+ company org \u2192 your personal org). Opens the Console to pick;
93094
+ only this workspace changes \u2014 your machine default and other
93095
+ workspaces stay put. Check with \`errata whoami\` from inside it.
93077
93096
  unlink Detach from the cloud project + disable ambient re-linking
93078
93097
  use [<handle>] Set the sticky session active agent the daemon acts as.
93079
93098
  No arg lists the agents you can act as + the current one;
@@ -93479,15 +93498,20 @@ async function cmdStatus() {
93479
93498
  const shellCloud = describeCloudTarget(cfg, {}, process.env, globalConfigPath());
93480
93499
  for (const line of cloudTargetDrift(daemonCloud, shellCloud)) console.log(` \u26A0 ${line}`);
93481
93500
  }
93482
- console.log(` profile: ${cfg.activeInstallationProfile ?? "(unbound legacy credential)"}`);
93483
- if (!hasCloudCredential(cfg)) {
93501
+ const shown = reportedIdentity(cfg, workspaceEntryForPath(ROOT));
93502
+ const ecfg = shown.ok ? shown.config : cfg;
93503
+ console.log(` profile: ${ecfg.activeInstallationProfile ?? "(unbound legacy credential)"}`);
93504
+ if (!shown.ok) console.log(` \u26A0 ${shown.reason} \u2014 this workspace's capture holds locally until fixed`);
93505
+ else if (shown.note) console.log(` \u21B3 ${shown.note}`);
93506
+ const who = shown.ok && shown.note ? "" : ` (${ecfg.email})`;
93507
+ if (!hasCloudCredential(ecfg)) {
93484
93508
  console.log(` logged in: no`);
93485
- } else if (cfg.accessToken) {
93486
- console.log(` logged in: yes (${cfg.email}) \u2014 attested daemon, can contribute`);
93509
+ } else if (ecfg.accessToken) {
93510
+ console.log(` logged in: yes${who} \u2014 attested daemon, can contribute`);
93487
93511
  } else {
93488
- console.log(` logged in: yes (${cfg.email}) \u2014 key capability enforced by Console installation/scopes`);
93512
+ console.log(` logged in: yes${who} \u2014 key capability enforced by Console installation/scopes`);
93489
93513
  }
93490
- const active3 = getActiveAgent(cfg);
93514
+ const active3 = getActiveAgent(ecfg);
93491
93515
  console.log(
93492
93516
  ` active agent: ${active3 ? `${active3.handle} (acting-as; \`errata use --none\` to clear)` : "default identity"}`
93493
93517
  );
@@ -93499,7 +93523,7 @@ async function cmdStatus() {
93499
93523
  console.log(` policy: blocked - ${decision.reason}`);
93500
93524
  if (decision.guidance) console.log(` ${decision.guidance}`);
93501
93525
  }
93502
- if (hasCloudCredential(cfg)) {
93526
+ if (hasCloudCredential(ecfg)) {
93503
93527
  if (!decision.allowed) {
93504
93528
  console.log(
93505
93529
  ` reachable: ${inspection.reachable ? `yes (${inspection.probe})` : `no (${inspection.error ?? "unreachable"})`}`
@@ -93508,7 +93532,7 @@ async function cmdStatus() {
93508
93532
  return;
93509
93533
  }
93510
93534
  try {
93511
- const c = authedCloudClient(cfg);
93535
+ const c = shown.ok ? shown.client : authedCloudClient(cfg);
93512
93536
  const me = await c.me();
93513
93537
  console.log(` reachable: yes \xB7 authenticated as ${me.handle} (${me.tier})`);
93514
93538
  } catch (err2) {
@@ -93603,19 +93627,26 @@ async function cmdWhoami(args2) {
93603
93627
  if (identity.invalid) process.exitCode = 1;
93604
93628
  return;
93605
93629
  }
93606
- if (!hasCloudCredential(cfg)) {
93630
+ const shown = reportedIdentity(cfg, workspaceEntryForPath(ROOT));
93631
+ if (!shown.ok) {
93632
+ console.error(`${shown.reason} \u2014 this workspace's capture holds locally (see \`errata whoami --workspace\`)`);
93633
+ process.exitCode = 1;
93634
+ return;
93635
+ }
93636
+ if (!hasCloudCredential(shown.config)) {
93607
93637
  console.error("not logged in \u2014 run `errata login` or select an installation profile");
93608
93638
  process.exitCode = 1;
93609
93639
  return;
93610
93640
  }
93611
93641
  try {
93612
- const active3 = getActiveAgent(cfg);
93613
- const response = await resolveWhoami(authedCloudClient(cfg), active3?.handle ?? null);
93642
+ const active3 = getActiveAgent(shown.config);
93643
+ const response = await resolveWhoami(shown.client, active3?.handle ?? null);
93614
93644
  if (args2.includes("--json")) {
93615
93645
  console.log(JSON.stringify(response, null, 2));
93616
93646
  return;
93617
93647
  }
93618
- for (const line of formatWhoami(response, cfg.activeInstallationProfile)) console.log(line);
93648
+ if (shown.note) console.log(`(${shown.note})`);
93649
+ for (const line of formatWhoami(response, shown.profileName ?? null)) console.log(line);
93619
93650
  } catch (err2) {
93620
93651
  console.error(`could not resolve context: ${err2 instanceof Error ? err2.message : err2}`);
93621
93652
  process.exitCode = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.17",
3
+ "version": "2.0.18-dev.3597",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -49,13 +49,18 @@ const ORIGIN_LABEL = { agent: 'agent burst', 'daemon-file': 'file recall', 'daem
49
49
  const pending = { isRefreshing: false, drawnAt: -1 }
50
50
 
51
51
  /**
52
- * Where the pane sits decides the UI. Docked beside the transcript (a wide
53
- * fullscreen terminal) it is the full map; anywhere else — waiting undrawn on a
54
- * narrow terminal, behind another tab, closed — the map collapses into the
55
- * status line. A pane the surface would only seat inline above the prompt is
56
- * closed unless the person asked for it with /minimap.
52
+ * Whether the pane is drawn decides the UI. Drawn — docked beside a fullscreen
53
+ * transcript, or inline above the prompt — it is the full map; waiting undrawn
54
+ * on a narrow terminal, behind another tab or closed by hand, the map collapses
55
+ * into the status line. The engine does the seating: an unasked pane waits
56
+ * below 144 columns and takes its place once the terminal widens. The pane is
57
+ * never closed here — closing an inline one dropped that request, and outside
58
+ * fullscreen every seat is inline, so the map stayed collapsed for the session.
57
59
  */
58
- const view = { placement: undefined as 'dock' | 'inline' | undefined, isAsked: false, isDocked: false, status: undefined as string | undefined }
60
+ const view = { isShown: false, status: undefined as string | undefined }
61
+
62
+ /** Rows an inline pane asks for: room for the map without burying the transcript. */
63
+ const INLINE_ROWS = 20
59
64
 
60
65
  const GROW_MS = 1200
61
66
  const TYPE_MS = 600
@@ -131,7 +136,7 @@ function startMotion($: EngineInterface): void {
131
136
  /** Lights the prior the agent is about to burst off, if the map shows it. */
132
137
  async function highlightSeed($: EngineInterface, id: string): Promise<boolean> {
133
138
  const map = await read($, graph)
134
- if (!view.isDocked || !map.nodes.some(n => !n.isSeed && n.id === id)) return false
139
+ if (!view.isShown || !map.nodes.some(n => !n.isSeed && n.id === id)) return false
135
140
  motion.highlight = id
136
141
  motion.highlightStart = await $.clock.now()
137
142
  motion.isPulseOn = true
@@ -167,7 +172,7 @@ async function recordJudgments($: EngineInterface, text: string): Promise<void>
167
172
  }
168
173
  if (fresh.length === 0) return
169
174
  await update($, verdicts, list => [...fresh, ...list.filter(v => !fresh.some(f => f.id === v.id))].slice(0, VERDICTS_KEPT))
170
- if (Object.keys(motion.marks).length > 0 && view.isDocked) {
175
+ if (Object.keys(motion.marks).length > 0 && view.isShown) {
171
176
  motion.markUntil = now + MARK_MS
172
177
  motion.isMarkOn = true
173
178
  startMotion($)
@@ -186,19 +191,15 @@ async function tick($: EngineInterface): Promise<void> {
186
191
 
187
192
  async function syncLayout($: EngineInterface): Promise<void> {
188
193
  const mine = (await $.ui.panes()).find(p => p.id === PANE)
189
- if (mine?.isPlaced && view.placement === 'inline' && !view.isAsked) {
190
- await $.ui.close({ id: PANE })
191
- view.placement = undefined
192
- }
193
- const isDocked = !!mine?.isPlaced && mine.isShown && view.placement === 'dock'
194
- view.isDocked = isDocked
194
+ const isShown = !!mine?.isPlaced && mine.isShown
195
+ view.isShown = isShown
195
196
  const latest = (await read($, verdicts))[0]
196
197
  const now = await $.clock.now()
197
198
  const verdictNote =
198
199
  latest && now - latest.at < VERDICT_STATUS_MS
199
200
  ? ` · ${JUDGMENT_STYLE[latest.kind].glyph} ${JUDGMENT_STYLE[latest.kind].verb} ${shortName(latest.name, 32)}`
200
201
  : ''
201
- const base = isDocked ? undefined : statusLine(await read($, graph))
202
+ const base = isShown ? undefined : statusLine(await read($, graph))
202
203
  const text = base === undefined ? undefined : base + verdictNote
203
204
  if (text !== view.status) {
204
205
  view.status = text
@@ -215,7 +216,7 @@ async function draw($: EngineInterface, b: Burst): Promise<void> {
215
216
  const laid = layoutBurst(b)
216
217
  // Set the reveal up before the graph lands, so its first render is frame 0, not a flash of the finished map.
217
218
  motion.highlight = undefined
218
- if (view.isDocked) {
219
+ if (view.isShown) {
219
220
  motion.graphAt = laid.at
220
221
  motion.start = await $.clock.now()
221
222
  motion.frame = { grow: 0, type: 0 }
@@ -299,7 +300,7 @@ async function primingHandles($: EngineInterface): Promise<HandleTable> {
299
300
  export const register: Register = on => {
300
301
  on('session.start', async ($, e, next) => {
301
302
  await $.command.register({ name: 'minimap', description: 'Open the errata minimap: the latest burst neighborhood that entered context' })
302
- void $.ui.open({ id: PANE, title: 'errata' })
303
+ void $.ui.open({ id: PANE, title: 'errata', rows: INLINE_ROWS })
303
304
  motion.bg = await themeBackground($)
304
305
  $.clock.every(1500, () => void tick($))
305
306
  return next(e)
@@ -312,8 +313,7 @@ export const register: Register = on => {
312
313
  })
313
314
 
314
315
  on('command.run', { command: 'minimap' }, async $ => {
315
- view.isAsked = true
316
- const opened = await $.ui.open({ id: PANE, title: 'errata', columns: 56 })
316
+ const opened = await $.ui.open({ id: PANE, title: 'errata', columns: 56, rows: INLINE_ROWS })
317
317
  pending.drawnAt = -1
318
318
  void refresh($)
319
319
  return { text: opened.isPlaced ? 'errata minimap opened.' : `minimap waits: ${opened.reason}` }
@@ -399,10 +399,10 @@ export const register: Register = on => {
399
399
 
400
400
  on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
401
401
  const { Box, Text } = $.ui.resolve(e)
402
- // The surface's word on where it seated us drives the status-line collapse (syncLayout).
403
- if (e.surface === 'terminal') view.placement = e.props.placement
404
402
  const width = Math.max(24, e.props.bodyColumns)
405
- const height = Math.max(14, (e.viewport?.rows ?? 30) - 4)
403
+ // Docked, the map takes the screen's height; inline it sits above the prompt and keeps to its row budget.
404
+ const screenRows = e.viewport?.rows ?? 30
405
+ const height = e.props.placement === 'inline' ? Math.max(14, Math.min(INLINE_ROWS, screenRows - 10)) : Math.max(14, screenRows - 4)
406
406
  const map = await read($, graph)
407
407
 
408
408
  const delivered = map.nodes.filter(n => !n.isSeed).sort((a, b) => b.score - a.score)