@inerrata-corporation/errata 2.0.17-dev.3577 → 2.0.18-dev.3596

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
@@ -82685,7 +82685,7 @@ function createWatchBreaker(deps) {
82685
82685
  }
82686
82686
 
82687
82687
  // src/engine.ts
82688
- var DAEMON_VERSION = true ? "2.0.17-dev.3577" : "2.0.0-alpha.0";
82688
+ var DAEMON_VERSION = true ? "2.0.18-dev.3596" : "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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.17-dev.3577",
3
+ "version": "2.0.18-dev.3596",
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)