@mnmal-ai/surface-core 0.15.0 → 0.16.0

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/dist/app.d.ts CHANGED
@@ -82,6 +82,13 @@ export interface AppOptions {
82
82
  * unchanged.
83
83
  */
84
84
  readonly anchored?: boolean;
85
+ /**
86
+ * Full-screen: the app runs in the terminal's alternate screen, the transcript scrolls in a
87
+ * viewport (PgUp / PgDn, End jumps back to the bottom while scrolled up) and the input, band and
88
+ * status row stay pinned. Default true. `SURFACE_FULLSCREEN=on|off` overrides it. Ignored off a
89
+ * TTY. `anchored` applies only when this is off.
90
+ */
91
+ readonly fullscreen?: boolean;
85
92
  /**
86
93
  * How `run()` prepares the terminal before the first frame (ground, pane wipe, bottom anchor).
87
94
  * Options here pass through to `prepareTerminal`, over an `anchor` that follows `anchored`.
@@ -125,11 +132,13 @@ interface AppProps {
125
132
  readonly rows?: number;
126
133
  }
127
134
  /** What `run()` prepares the terminal with, or `null` when the host has prepared it already. */
128
- export declare function runTerminalOptions(opts: Pick<AppOptions, 'anchored' | 'terminal'>): PrepareTerminalOptions | null;
135
+ export declare function runTerminalOptions(opts: Pick<AppOptions, 'anchored' | 'terminal'>, fullscreen: boolean): PrepareTerminalOptions | null;
129
136
  export declare function createApp(opts: AppOptions): {
130
137
  registry: Registry;
131
138
  App: (props: AppProps) => ReactElement;
132
139
  run(): Promise<void>;
140
+ /** Full-screen as resolved from the option and `SURFACE_FULLSCREEN`, before the TTY check. */
141
+ fullscreen: boolean;
133
142
  };
134
143
  export {};
135
144
  //# sourceMappingURL=app.d.ts.map
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /** Whether full-screen is on: `SURFACE_FULLSCREEN` (`on` / `off`) over the app's option over on. */
2
+ export declare function resolveFullscreen(option: boolean | undefined, env: string | undefined): {
3
+ readonly on: boolean;
4
+ readonly invalid: string | null;
5
+ };
6
+ /** Where the viewport is: following the bottom (`held: null`), or held with this top row. */
7
+ export interface Scroll {
8
+ readonly held: number | null;
9
+ }
10
+ export declare const FOLLOWING: Scroll;
11
+ /** The first content row shown. A held top past the end (the terminal grew) is clamped. */
12
+ export declare function viewTop(s: Scroll, content: number, viewport: number): number;
13
+ /** Content rows below the viewport. */
14
+ export declare function linesBelow(s: Scroll, content: number, viewport: number): number;
15
+ /** Scrolls by `delta` rows (negative is up). Reaching the bottom follows again. */
16
+ export declare function scrollBy(s: Scroll, delta: number, content: number, viewport: number): Scroll;
17
+ /** A PgUp/PgDn step: a viewport less one row of overlap, never under one. */
18
+ export declare function pageStep(viewport: number): number;
19
+ //# sourceMappingURL=fullscreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullscreen.d.ts","sourceRoot":"","sources":["../src/fullscreen.ts"],"names":[],"mappings":"AAEA,oGAAoG;AACpG,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,OAAO,GAAG,SAAS,EAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB;IAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAM3D;AAED,6FAA6F;AAC7F,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,eAAO,MAAM,SAAS,EAAE,MAAuB,CAAC;AAIhD,2FAA2F;AAC3F,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,uCAAuC;AACvC,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI5F;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjD"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { applySuggestion, mergeCompletions } from './complete.js';
4
4
  export { assertComposes, CompositionError, composeModules, RESERVED_GLOBAL_KEYS, type Registry } from './compose.js';
5
5
  export { atEnd, type Draft, type EditKeys, EMPTY_DRAFT, editKey, insertChunk, maskDraft, pasteToLine, wordLeft, wordRight } from './editor.js';
6
6
  export { CTRL_C_WINDOW_MS, ctrlC } from './exit-chord.js';
7
+ export { FOLLOWING, linesBelow, pageStep, resolveFullscreen, type Scroll, scrollBy, viewTop } from './fullscreen.js';
7
8
  export { EMPTY_HISTORY, HISTORY_MAX, type HistoryState, mayWalk, remember, settle, walk } from './history.js';
8
9
  export { normaliseKeySpec } from './key-spec.js';
9
10
  export { type KeyState, keySpecOf, type Route, resolveKey } from './keys.js';
@@ -12,6 +13,6 @@ export { type Overlay, panelOf, setPanel } from './overlay.js';
12
13
  export { clampSelection, commandUsage, completeDraft, enterRuns, MENU_NAME_WIDTH, menuWindow, moveSelection, type PaletteRow, paletteMatches, paletteQuery, paletteRows, parseCommandLine } from './palette.js';
13
14
  export { type InputRoute, routeInput } from './route-input.js';
14
15
  export { sanitise } from './sanitise.js';
15
- export { anchorPadding, CLEAR_PANE, DEFAULT_GROUND, groundSequence, type LiveMeasure, liveShrink, type PrepareTerminalOptions, prepareSequence, prepareTerminal, RESET_GROUND, reflowSequence, type TerminalOut, type TerminalProcess } from './terminal.js';
16
+ export { anchorPadding, CLEAR_PANE, DEFAULT_GROUND, groundSequence, type LiveMeasure, liveShrink, type PrepareTerminalOptions, prepareSequence, prepareTerminal, RESET_GROUND, reflowSequence, type TerminalOut, type TerminalProcess, WHEEL_ARROWS_OFF, WHEEL_ARROWS_ON } from './terminal.js';
16
17
  export { type AnswerEntry, type AppEntry, type AskEntry, addGap, answerEntry, arriveTurn, commitEntry, type Entry, emptyTranscript, type Flight, type GapEntry, heldAsks, markedFlights, type NoteEntry, sendTurn, type Transcript } from './transcript.js';
17
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,SAAS,EACT,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACtB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,KAAK,QAAQ,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,EACL,KAAK,KAAK,EACV,KAAK,QAAQ,EACb,WAAW,EACX,OAAO,EACP,WAAW,EACX,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,WAAW,EACX,KAAK,YAAY,EACjB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAI,EACL,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EACV,aAAa,EACb,KAAK,UAAU,EACf,cAAc,EACd,YAAY,EACZ,WAAW,EACX,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,cAAc,EACd,KAAK,WAAW,EAChB,UAAU,EACV,KAAK,sBAAsB,EAC3B,eAAe,EACf,eAAe,EACf,YAAY,EACZ,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,WAAW,EACX,KAAK,KAAK,EACV,eAAe,EACf,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,QAAQ,EACR,aAAa,EACb,KAAK,SAAS,EACd,QAAQ,EACR,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as maskDraft, A as completeDraft, B as EMPTY_HISTORY, C as reprintStart, D as MENU_NAME_WIDTH, E as unavailableReason, F as paletteQuery, G as walk, H as mayWalk, I as paletteRows, J as EMPTY_DRAFT, K as CTRL_C_WINDOW_MS, L as parseCommandLine, M as menuWindow, N as moveSelection, O as clampSelection, P as paletteMatches, Q as insertChunk, R as keySpecOf, S as reflowSequence, T as routeInput, U as remember, V as HISTORY_MAX, W as settle, X as editKey, Y as atEnd, Z as graphemeAt, _ as anchorPadding, a as answerEntry, at as RESERVED_GLOBAL_KEYS, b as prepareSequence, c as dropGaps, ct as normaliseKeySpec, d as markedFlights, et as pasteToLine, f as sendTurn, g as RESET_GROUND, h as REPRINT_LINES, i as addGap, it as CompositionError, j as enterRuns, k as commandUsage, l as emptyTranscript, lt as applySuggestion, m as DEFAULT_GROUND, n as setPanel, nt as wordRight, o as arriveTurn, ot as assertComposes, p as CLEAR_PANE, q as ctrlC, r as defineModule, rt as applyInput, s as commitEntry, st as composeModules, t as panelOf, tt as wordLeft, u as heldAsks, ut as mergeCompletions, v as groundSequence, w as sanitise, x as prepareTerminal, y as liveShrink, z as resolveKey } from "./overlay-DMjCbsaC.js";
1
+ import { $ as viewTop, A as clampSelection, B as keySpecOf, C as prepareTerminal, D as routeInput, E as sanitise, F as moveSelection, G as remember, H as EMPTY_HISTORY, I as paletteMatches, J as FOLLOWING, K as settle, L as paletteQuery, M as completeDraft, N as enterRuns, O as unavailableReason, P as menuWindow, Q as scrollBy, R as paletteRows, S as prepareSequence, T as reprintStart, U as HISTORY_MAX, V as resolveKey, W as mayWalk, X as pageStep, Y as linesBelow, Z as resolveFullscreen, _ as WHEEL_ARROWS_OFF, _t as applySuggestion, a as answerEntry, at as graphemeAt, b as groundSequence, c as dropGaps, ct as pasteToLine, d as markedFlights, dt as applyInput, et as CTRL_C_WINDOW_MS, f as sendTurn, ft as CompositionError, g as RESET_GROUND, gt as normaliseKeySpec, h as REPRINT_LINES, ht as composeModules, i as addGap, it as editKey, j as commandUsage, k as MENU_NAME_WIDTH, l as emptyTranscript, lt as wordLeft, m as DEFAULT_GROUND, mt as assertComposes, n as setPanel, nt as EMPTY_DRAFT, o as arriveTurn, ot as insertChunk, p as CLEAR_PANE, pt as RESERVED_GLOBAL_KEYS, q as walk, r as defineModule, rt as atEnd, s as commitEntry, st as maskDraft, t as panelOf, tt as ctrlC, u as heldAsks, ut as wordRight, v as WHEEL_ARROWS_ON, vt as mergeCompletions, w as reflowSequence, x as liveShrink, y as anchorPadding, z as parseCommandLine } from "./overlay-By-Ewn3S.js";
2
2
  import { spinnerFrame } from "@mnmal-ai/surface-kit";
3
3
  import { Box, Static, Text, measureElement, render, useApp, useInput, usePaste, useStdout } from "ink";
4
4
  import { Component, useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -117,11 +117,12 @@ function defaultPanelRows(terminalRows, opts) {
117
117
  return Math.max(3, terminalRows - SHELL_ROWS - (opts?.band === true ? BAND_ROWS : 0));
118
118
  }
119
119
  /** What `run()` prepares the terminal with, or `null` when the host has prepared it already. */
120
- function runTerminalOptions(opts) {
120
+ function runTerminalOptions(opts, fullscreen) {
121
121
  if (opts.terminal === false) return null;
122
122
  return {
123
123
  anchor: opts.anchored === true,
124
- ...opts.terminal
124
+ ...opts.terminal,
125
+ ...fullscreen ? { fullscreen } : {}
125
126
  };
126
127
  }
127
128
  function createApp(opts) {
@@ -140,9 +141,12 @@ function createApp(opts) {
140
141
  const presenceModule = registry.presence?.module ?? "";
141
142
  const panelRows = opts.panelRows ?? ((r) => defaultPanelRows(r, { band }));
142
143
  const anchored = opts.anchored === true;
144
+ const fs = resolveFullscreen(opts.fullscreen, process.env.SURFACE_FULLSCREEN);
143
145
  function App({ columns, rows }) {
144
146
  const { exit } = useApp();
145
147
  const stdout = useStdout().stdout;
148
+ const full = fs.on && stdout.isTTY === true;
149
+ const relays = anchored && !full;
146
150
  const [term, setTerm] = useState(() => ({
147
151
  columns: stdout.columns ?? 120,
148
152
  rows: stdout.rows ?? 30
@@ -174,7 +178,7 @@ function createApp(opts) {
174
178
  columns: stdout.columns ?? 120,
175
179
  rows: stdout.rows ?? 30
176
180
  });
177
- if (!anchored) return;
181
+ if (!relays) return;
178
182
  clearTimeout(timer);
179
183
  timer = setTimeout(() => {
180
184
  const now = {
@@ -193,7 +197,11 @@ function createApp(opts) {
193
197
  clearTimeout(timer);
194
198
  stdout.off("resize", onResize);
195
199
  };
196
- }, [stdout, relayout]);
200
+ }, [
201
+ stdout,
202
+ relayout,
203
+ relays
204
+ ]);
197
205
  const width = Math.max(1, (columns ?? term.columns) - 2 * gutter);
198
206
  const height = rows ?? term.rows;
199
207
  const showRail = registry.rail.length > 0 && width >= railMin;
@@ -238,6 +246,12 @@ function createApp(opts) {
238
246
  armedRef.current = a;
239
247
  setArmed(a);
240
248
  }, []);
249
+ const [scroll, setScroll] = useState(FOLLOWING);
250
+ const scrollRef = useRef(FOLLOWING);
251
+ const putScroll = useCallback((next) => {
252
+ scrollRef.current = next;
253
+ setScroll(next);
254
+ }, []);
241
255
  const defOf = useCallback((o) => o ? registry.panels.get(`${o.module}/${o.panel}`)?.def : void 0, []);
242
256
  const putHistory = useCallback((h) => {
243
257
  historyRef.current = h;
@@ -438,6 +452,7 @@ function createApp(opts) {
438
452
  }
439
453
  }, [ctxFor, putTranscript]);
440
454
  const handleLine = useCallback((line, sent) => {
455
+ putScroll(FOLLOWING);
441
456
  const text = line.trim();
442
457
  const open = overlayRef.current;
443
458
  const owner = open ? registry.panels.get(`${open.module}/${open.panel}`)?.def : void 0;
@@ -472,13 +487,43 @@ function createApp(opts) {
472
487
  putHistory,
473
488
  runTurn,
474
489
  guard,
475
- putOverlay
490
+ putOverlay,
491
+ putScroll
476
492
  ]);
477
493
  handleLineRef.current = handleLine;
494
+ const viewportRef = useRef(null);
495
+ const flightsRef = useRef(null);
496
+ const [measured, setMeasured] = useState({
497
+ content: 0,
498
+ viewport: 1
499
+ });
500
+ const measuredRef = useRef(measured);
501
+ const contentRows = useCallback(() => {
502
+ let rows = 0;
503
+ for (const e of transcriptRef.current.committed) rows += heights.current.get(e.key) ?? 1;
504
+ return rows + (flightsRef.current === null ? 0 : measureElement(flightsRef.current).height);
505
+ }, []);
506
+ const viewportRows = useCallback(() => viewportRef.current === null ? measuredRef.current.viewport : Math.max(1, measureElement(viewportRef.current).height), []);
507
+ useEffect(() => {
508
+ if (!full || viewportRef.current === null) return;
509
+ const now = {
510
+ content: contentRows(),
511
+ viewport: viewportRows()
512
+ };
513
+ const held = scrollRef.current.held;
514
+ if (held !== null && held >= Math.max(0, now.content - now.viewport)) putScroll(FOLLOWING);
515
+ const was = measuredRef.current;
516
+ if (now.content === was.content && now.viewport === was.viewport) return;
517
+ measuredRef.current = now;
518
+ setMeasured(now);
519
+ });
520
+ useEffect(() => {
521
+ if (fs.invalid !== null) print(`SURFACE_FULLSCREEN=${fs.invalid} ignored: use on or off`, "warn");
522
+ }, [print]);
478
523
  const liveRef = useRef(null);
479
524
  const lastLive = useRef(null);
480
525
  useEffect(() => {
481
- if (!anchored || liveRef.current === null) return;
526
+ if (!relays || liveRef.current === null) return;
482
527
  const now = {
483
528
  height: measureElement(liveRef.current).height,
484
529
  committed: transcript.committed.filter((e) => e.kind !== "gap").length,
@@ -491,9 +536,13 @@ function createApp(opts) {
491
536
  const panelOpen = overlay !== null || menu !== null;
492
537
  const wasPanelOpen = useRef(panelOpen);
493
538
  useEffect(() => {
494
- if (anchored && wasPanelOpen.current && !panelOpen) relayout();
539
+ if (relays && wasPanelOpen.current && !panelOpen) relayout();
495
540
  wasPanelOpen.current = panelOpen;
496
- }, [panelOpen, relayout]);
541
+ }, [
542
+ panelOpen,
543
+ relayout,
544
+ relays
545
+ ]);
497
546
  const [pendingLine, setPendingLine] = useState(null);
498
547
  useEffect(() => {
499
548
  if (pendingLine === null) return;
@@ -501,7 +550,7 @@ function createApp(opts) {
501
550
  handleLine(pendingLine);
502
551
  }, [pendingLine, handleLine]);
503
552
  const sendAfterClose = (line) => {
504
- if (anchored) setPendingLine(line);
553
+ if (relays) setPendingLine(line);
505
554
  else handleLine(line);
506
555
  };
507
556
  const putDraft = useCallback((d) => {
@@ -580,7 +629,8 @@ function createApp(opts) {
580
629
  } : null,
581
630
  menu: menu?.kind ?? null,
582
631
  draftEmpty: draft.text === "",
583
- armed: armedOn !== null && overlay?.module === armedOn.module && overlay.panel === armedOn.panel && draft.text === armedOn.key ? armedOn.key : null
632
+ armed: armedOn !== null && overlay?.module === armedOn.module && overlay.panel === armedOn.panel && draft.text === armedOn.key ? armedOn.key : null,
633
+ ...full ? { viewport: scrollRef.current.held === null ? "following" : "held" } : {}
584
634
  };
585
635
  const route = resolveKey(state, key, registry);
586
636
  switch (route.kind) {
@@ -731,6 +781,13 @@ function createApp(opts) {
731
781
  putDraft(atEnd(step.text));
732
782
  return;
733
783
  }
784
+ case "scroll": {
785
+ const content = contentRows();
786
+ const viewport = viewportRows();
787
+ const step = route.act === "page-up" ? -pageStep(viewport) : pageStep(viewport);
788
+ putScroll(route.act === "bottom" ? FOLLOWING : scrollBy(scrollRef.current, step, content, viewport));
789
+ return;
790
+ }
734
791
  case "submit": {
735
792
  putArmed(null);
736
793
  const line = draft.text;
@@ -941,6 +998,230 @@ function createApp(opts) {
941
998
  text: `… ${reprintFrom} earlier ${reprintFrom === 1 ? "entry" : "entries"} not reprinted`,
942
999
  tone: "dim"
943
1000
  }, ...transcript.committed.slice(reprintFrom)];
1001
+ const flightRows = /* @__PURE__ */ jsxs(Fragment, { children: [markedFlights(transcript).map((f) => /* @__PURE__ */ jsx(Box, { children: waiting(f, false) }, `marked:${f.id}`)), heldAsks(transcript).map((f) => /* @__PURE__ */ jsxs(Box, {
1002
+ flexDirection: "column",
1003
+ children: [askView ? /* @__PURE__ */ jsx(Safe, {
1004
+ module: "app",
1005
+ theme,
1006
+ render: () => askView({
1007
+ entry: f,
1008
+ held: true,
1009
+ theme,
1010
+ size: { columns: width }
1011
+ })
1012
+ }) : /* @__PURE__ */ jsxs(Text, {
1013
+ color: theme.color.accent,
1014
+ children: [
1015
+ theme.glyph.prompt,
1016
+ " ",
1017
+ sanitise(f.question)
1018
+ ]
1019
+ }), waiting(f, true)]
1020
+ }, f.id))] });
1021
+ const overlayRows = /* @__PURE__ */ jsxs(Fragment, { children: [
1022
+ panel && overlay ? /* @__PURE__ */ jsx(Box, {
1023
+ backgroundColor: theme.color.raised,
1024
+ paddingX: PANEL_PAD_X,
1025
+ paddingY: PANEL_PAD_Y,
1026
+ flexDirection: "column",
1027
+ children: /* @__PURE__ */ jsx(Safe, {
1028
+ module: overlay.module,
1029
+ theme,
1030
+ render: () => panel.view({
1031
+ state: overlay.state,
1032
+ theme,
1033
+ size: panelSize,
1034
+ ...armed !== null && armed.module === overlay.module && armed.panel === overlay.panel && draft.text === armed.key ? { armed: {
1035
+ key: armed.key,
1036
+ label: armed.label
1037
+ } } : {}
1038
+ })
1039
+ }, `${overlay.module}/${overlay.panel}`)
1040
+ }) : null,
1041
+ menu?.kind === "palette" ? /* @__PURE__ */ jsx(MenuList, {
1042
+ theme,
1043
+ rows: paletteItems.map((c) => ({
1044
+ key: c.name,
1045
+ name: commandUsage(c),
1046
+ detail: c.summary
1047
+ })),
1048
+ selected: menu.selected,
1049
+ height: menuRows,
1050
+ empty: `no command matches ${draft.text}`,
1051
+ hint: "tab complete · enter run · esc close"
1052
+ }) : null,
1053
+ menu?.kind === "completion" ? /* @__PURE__ */ jsx(MenuList, {
1054
+ theme,
1055
+ rows: menu.items.map((s) => ({
1056
+ key: s.insert,
1057
+ name: s.label,
1058
+ detail: s.detail ?? ""
1059
+ })),
1060
+ selected: menu.selected,
1061
+ height: menuRows,
1062
+ empty: "no completions",
1063
+ hint: "tab complete · esc close"
1064
+ }) : null
1065
+ ] });
1066
+ const pinnedRows = /* @__PURE__ */ jsxs(Fragment, { children: [
1067
+ band ? /* @__PURE__ */ jsxs(Box, {
1068
+ borderStyle: "bold",
1069
+ borderTop: false,
1070
+ borderRight: false,
1071
+ borderBottom: false,
1072
+ borderColor: theme.color.edge,
1073
+ backgroundColor: theme.color.surfaceAlt,
1074
+ paddingX: 1,
1075
+ paddingY: 1,
1076
+ flexDirection: "column",
1077
+ children: [/* @__PURE__ */ jsxs(Text, { children: [
1078
+ shownDraft.text.slice(0, shownDraft.cursor),
1079
+ under === "" ? /* @__PURE__ */ jsx(Text, {
1080
+ color: theme.color.cursor,
1081
+ children: "█"
1082
+ }) : /* @__PURE__ */ jsx(Text, {
1083
+ inverse: true,
1084
+ children: under
1085
+ }),
1086
+ under === "" ? "" : shownDraft.text.slice(shownDraft.cursor + under.length)
1087
+ ] }), /* @__PURE__ */ jsxs(Box, {
1088
+ marginTop: 1,
1089
+ children: [
1090
+ presence ? /* @__PURE__ */ jsx(Box, {
1091
+ flexShrink: 0,
1092
+ children: /* @__PURE__ */ jsxs(Text, {
1093
+ bold: true,
1094
+ children: [sanitise(presence.name), " "]
1095
+ })
1096
+ }) : null,
1097
+ /* @__PURE__ */ jsx(Box, {
1098
+ flexGrow: 1,
1099
+ minWidth: 0,
1100
+ children: /* @__PURE__ */ jsx(Text, {
1101
+ color: theme.color.dim,
1102
+ wrap: "truncate",
1103
+ children: presence?.view ? /* @__PURE__ */ jsx(Safe, {
1104
+ module: presenceModule,
1105
+ theme,
1106
+ render: () => presence.view?.({ theme })
1107
+ }) : null
1108
+ })
1109
+ }),
1110
+ /* @__PURE__ */ jsx(Box, {
1111
+ flexShrink: 0,
1112
+ paddingLeft: notice === null ? 0 : 2,
1113
+ children: /* @__PURE__ */ jsx(Text, {
1114
+ color: theme.color.warn,
1115
+ children: notice ?? " "
1116
+ })
1117
+ })
1118
+ ]
1119
+ })]
1120
+ }) : /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsxs(Text, {
1121
+ color: theme.color.accent,
1122
+ children: [theme.glyph.prompt, " "]
1123
+ }), shownDraft.text] }),
1124
+ toast ? /* @__PURE__ */ jsx(Text, {
1125
+ color: theme.color[toast.tone],
1126
+ children: toast.text
1127
+ }) : null,
1128
+ /* @__PURE__ */ jsxs(Box, {
1129
+ ...band ? { marginTop: 1 } : {},
1130
+ children: [registry.status.map((s) => /* @__PURE__ */ jsx(Box, {
1131
+ marginRight: 2,
1132
+ children: /* @__PURE__ */ jsx(Safe, {
1133
+ module: s.module,
1134
+ theme,
1135
+ render: () => s.item.view({ theme })
1136
+ })
1137
+ }, `${s.module}:${s.item.id}`)), [...status.entries()].map(([k, v]) => /* @__PURE__ */ jsxs(Text, {
1138
+ color: theme.color[v.tone],
1139
+ children: [v.text, " "]
1140
+ }, k))]
1141
+ })
1142
+ ] });
1143
+ const railColumn = /* @__PURE__ */ jsx(Fragment, { children: showRail ? /* @__PURE__ */ jsx(Box, {
1144
+ flexDirection: "column",
1145
+ width: 32,
1146
+ marginLeft: 1,
1147
+ children: registry.rail.map((r) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Safe, {
1148
+ module: r.module,
1149
+ theme,
1150
+ render: () => r.item.view({ theme })
1151
+ }) }, `${r.module}:${r.item.id}`))
1152
+ }) : null });
1153
+ if (full) {
1154
+ const { content, viewport } = measured;
1155
+ const top = viewTop(scroll, content, viewport);
1156
+ const below = linesBelow(scroll, content, viewport);
1157
+ const lo = top - viewport;
1158
+ const hi = top + 2 * viewport;
1159
+ const shown = [];
1160
+ let at = 0;
1161
+ let skipped = null;
1162
+ for (const e of transcript.committed) {
1163
+ const h = heights.current.get(e.key);
1164
+ const rows = h ?? 1;
1165
+ if (at + rows > lo && at < hi || h === void 0) {
1166
+ if (skipped === null) skipped = at;
1167
+ shown.push(e);
1168
+ }
1169
+ at += rows;
1170
+ }
1171
+ const rowsAbove = skipped ?? at;
1172
+ const markerText = `↓ ${below} lines below · End to jump back`;
1173
+ return /* @__PURE__ */ jsxs(Box, {
1174
+ flexDirection: "row",
1175
+ height,
1176
+ paddingX: gutter,
1177
+ children: [/* @__PURE__ */ jsxs(Box, {
1178
+ flexDirection: "column",
1179
+ flexGrow: 1,
1180
+ children: [/* @__PURE__ */ jsxs(Box, {
1181
+ ref: viewportRef,
1182
+ flexDirection: "column",
1183
+ flexGrow: 1,
1184
+ flexShrink: 1,
1185
+ minHeight: 1,
1186
+ overflow: "hidden",
1187
+ children: [/* @__PURE__ */ jsxs(Box, {
1188
+ flexDirection: "column",
1189
+ flexShrink: 0,
1190
+ marginTop: -(top - rowsAbove),
1191
+ children: [shown.map((e) => /* @__PURE__ */ jsx(Printed, {
1192
+ id: e.key,
1193
+ heights: heights.current,
1194
+ paddingX: 0,
1195
+ children: committed(e)
1196
+ }, e.key)), /* @__PURE__ */ jsx(Box, {
1197
+ ref: flightsRef,
1198
+ flexDirection: "column",
1199
+ flexShrink: 0,
1200
+ children: flightRows
1201
+ })]
1202
+ }), panelOpen ? /* @__PURE__ */ jsx(Box, {
1203
+ position: "absolute",
1204
+ bottom: 0,
1205
+ width: "100%",
1206
+ flexDirection: "column",
1207
+ children: overlayRows
1208
+ }) : below > 0 ? /* @__PURE__ */ jsx(Box, {
1209
+ position: "absolute",
1210
+ bottom: 0,
1211
+ children: /* @__PURE__ */ jsx(Text, {
1212
+ color: theme.color.dim,
1213
+ wrap: "truncate",
1214
+ children: markerText.padEnd(panelOuter.columns)
1215
+ })
1216
+ }) : null]
1217
+ }), /* @__PURE__ */ jsx(Box, {
1218
+ flexDirection: "column",
1219
+ flexShrink: 0,
1220
+ children: pinnedRows
1221
+ })]
1222
+ }), railColumn]
1223
+ });
1224
+ }
944
1225
  return /* @__PURE__ */ jsxs(Box, {
945
1226
  flexDirection: "column",
946
1227
  children: [/* @__PURE__ */ jsx(Static, {
@@ -959,170 +1240,30 @@ function createApp(opts) {
959
1240
  flexDirection: "column",
960
1241
  flexGrow: 1,
961
1242
  children: [
962
- markedFlights(transcript).map((f) => /* @__PURE__ */ jsx(Box, { children: waiting(f, false) }, `marked:${f.id}`)),
963
- heldAsks(transcript).map((f) => /* @__PURE__ */ jsxs(Box, {
964
- flexDirection: "column",
965
- children: [askView ? /* @__PURE__ */ jsx(Safe, {
966
- module: "app",
967
- theme,
968
- render: () => askView({
969
- entry: f,
970
- held: true,
971
- theme,
972
- size: { columns: width }
973
- })
974
- }) : /* @__PURE__ */ jsxs(Text, {
975
- color: theme.color.accent,
976
- children: [
977
- theme.glyph.prompt,
978
- " ",
979
- sanitise(f.question)
980
- ]
981
- }), waiting(f, true)]
982
- }, f.id)),
983
- panel && overlay ? /* @__PURE__ */ jsx(Box, {
984
- backgroundColor: theme.color.raised,
985
- paddingX: PANEL_PAD_X,
986
- paddingY: PANEL_PAD_Y,
987
- flexDirection: "column",
988
- children: /* @__PURE__ */ jsx(Safe, {
989
- module: overlay.module,
990
- theme,
991
- render: () => panel.view({
992
- state: overlay.state,
993
- theme,
994
- size: panelSize,
995
- ...armed !== null && armed.module === overlay.module && armed.panel === overlay.panel && draft.text === armed.key ? { armed: {
996
- key: armed.key,
997
- label: armed.label
998
- } } : {}
999
- })
1000
- }, `${overlay.module}/${overlay.panel}`)
1001
- }) : null,
1002
- menu?.kind === "palette" ? /* @__PURE__ */ jsx(MenuList, {
1003
- theme,
1004
- rows: paletteItems.map((c) => ({
1005
- key: c.name,
1006
- name: commandUsage(c),
1007
- detail: c.summary
1008
- })),
1009
- selected: menu.selected,
1010
- height: menuRows,
1011
- empty: `no command matches ${draft.text}`,
1012
- hint: "tab complete · enter run · esc close"
1013
- }) : null,
1014
- menu?.kind === "completion" ? /* @__PURE__ */ jsx(MenuList, {
1015
- theme,
1016
- rows: menu.items.map((s) => ({
1017
- key: s.insert,
1018
- name: s.label,
1019
- detail: s.detail ?? ""
1020
- })),
1021
- selected: menu.selected,
1022
- height: menuRows,
1023
- empty: "no completions",
1024
- hint: "tab complete · esc close"
1025
- }) : null,
1026
- band ? /* @__PURE__ */ jsxs(Box, {
1027
- borderStyle: "bold",
1028
- borderTop: false,
1029
- borderRight: false,
1030
- borderBottom: false,
1031
- borderColor: theme.color.edge,
1032
- backgroundColor: theme.color.surfaceAlt,
1033
- paddingX: 1,
1034
- paddingY: 1,
1035
- flexDirection: "column",
1036
- children: [/* @__PURE__ */ jsxs(Text, { children: [
1037
- shownDraft.text.slice(0, shownDraft.cursor),
1038
- under === "" ? /* @__PURE__ */ jsx(Text, {
1039
- color: theme.color.cursor,
1040
- children: "█"
1041
- }) : /* @__PURE__ */ jsx(Text, {
1042
- inverse: true,
1043
- children: under
1044
- }),
1045
- under === "" ? "" : shownDraft.text.slice(shownDraft.cursor + under.length)
1046
- ] }), /* @__PURE__ */ jsxs(Box, {
1047
- marginTop: 1,
1048
- children: [
1049
- presence ? /* @__PURE__ */ jsx(Box, {
1050
- flexShrink: 0,
1051
- children: /* @__PURE__ */ jsxs(Text, {
1052
- bold: true,
1053
- children: [sanitise(presence.name), " "]
1054
- })
1055
- }) : null,
1056
- /* @__PURE__ */ jsx(Box, {
1057
- flexGrow: 1,
1058
- minWidth: 0,
1059
- children: /* @__PURE__ */ jsx(Text, {
1060
- color: theme.color.dim,
1061
- wrap: "truncate",
1062
- children: presence?.view ? /* @__PURE__ */ jsx(Safe, {
1063
- module: presenceModule,
1064
- theme,
1065
- render: () => presence.view?.({ theme })
1066
- }) : null
1067
- })
1068
- }),
1069
- /* @__PURE__ */ jsx(Box, {
1070
- flexShrink: 0,
1071
- paddingLeft: notice === null ? 0 : 2,
1072
- children: /* @__PURE__ */ jsx(Text, {
1073
- color: theme.color.warn,
1074
- children: notice ?? " "
1075
- })
1076
- })
1077
- ]
1078
- })]
1079
- }) : /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsxs(Text, {
1080
- color: theme.color.accent,
1081
- children: [theme.glyph.prompt, " "]
1082
- }), shownDraft.text] }),
1083
- toast ? /* @__PURE__ */ jsx(Text, {
1084
- color: theme.color[toast.tone],
1085
- children: toast.text
1086
- }) : null,
1087
- /* @__PURE__ */ jsxs(Box, {
1088
- ...band ? { marginTop: 1 } : {},
1089
- children: [registry.status.map((s) => /* @__PURE__ */ jsx(Box, {
1090
- marginRight: 2,
1091
- children: /* @__PURE__ */ jsx(Safe, {
1092
- module: s.module,
1093
- theme,
1094
- render: () => s.item.view({ theme })
1095
- })
1096
- }, `${s.module}:${s.item.id}`)), [...status.entries()].map(([k, v]) => /* @__PURE__ */ jsxs(Text, {
1097
- color: theme.color[v.tone],
1098
- children: [v.text, " "]
1099
- }, k))]
1100
- })
1243
+ flightRows,
1244
+ overlayRows,
1245
+ pinnedRows
1101
1246
  ]
1102
- }), showRail ? /* @__PURE__ */ jsx(Box, {
1103
- flexDirection: "column",
1104
- width: 32,
1105
- marginLeft: 1,
1106
- children: registry.rail.map((r) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Safe, {
1107
- module: r.module,
1108
- theme,
1109
- render: () => r.item.view({ theme })
1110
- }) }, `${r.module}:${r.item.id}`))
1111
- }) : null]
1247
+ }), railColumn]
1112
1248
  })]
1113
1249
  });
1114
1250
  }
1115
1251
  return {
1116
1252
  registry,
1117
1253
  App,
1254
+ fullscreen: fs.on,
1118
1255
  async run() {
1119
- const prepare = runTerminalOptions(opts);
1256
+ const full = fs.on && process.stdout.isTTY === true;
1257
+ const prepare = runTerminalOptions(opts, full);
1120
1258
  const restore = prepare === null ? () => {} : prepareTerminal(process.stdout, prepare);
1121
- await render(/* @__PURE__ */ jsx(App, {}), { exitOnCtrlC: false }).waitUntilExit();
1259
+ await render(/* @__PURE__ */ jsx(App, {}), {
1260
+ exitOnCtrlC: false,
1261
+ alternateScreen: full
1262
+ }).waitUntilExit();
1122
1263
  restore();
1123
1264
  }
1124
1265
  };
1125
1266
  }
1126
1267
 
1127
1268
  //#endregion
1128
- export { CLEAR_PANE, CTRL_C_WINDOW_MS, CompositionError, DEFAULT_GROUND, EMPTY_DRAFT, EMPTY_HISTORY, HISTORY_MAX, MENU_NAME_WIDTH, RESERVED_GLOBAL_KEYS, RESET_GROUND, addGap, anchorPadding, answerEntry, applyInput, applySuggestion, arriveTurn, assertComposes, atEnd, clampSelection, commandUsage, commitEntry, completeDraft, composeModules, createApp, ctrlC, defaultPanelRows, defineModule, editKey, emptyTranscript, enterRuns, groundSequence, heldAsks, insertChunk, keySpecOf, liveShrink, markedFlights, maskDraft, mayWalk, menuWindow, mergeCompletions, moveSelection, normaliseKeySpec, paletteMatches, paletteQuery, paletteRows, panelOf, parseCommandLine, pasteToLine, prepareSequence, prepareTerminal, reflowSequence, remember, resolveKey, routeInput, sanitise, sendTurn, setPanel, settle, walk, wordLeft, wordRight };
1269
+ export { CLEAR_PANE, CTRL_C_WINDOW_MS, CompositionError, DEFAULT_GROUND, EMPTY_DRAFT, EMPTY_HISTORY, FOLLOWING, HISTORY_MAX, MENU_NAME_WIDTH, RESERVED_GLOBAL_KEYS, RESET_GROUND, WHEEL_ARROWS_OFF, WHEEL_ARROWS_ON, addGap, anchorPadding, answerEntry, applyInput, applySuggestion, arriveTurn, assertComposes, atEnd, clampSelection, commandUsage, commitEntry, completeDraft, composeModules, createApp, ctrlC, defaultPanelRows, defineModule, editKey, emptyTranscript, enterRuns, groundSequence, heldAsks, insertChunk, keySpecOf, linesBelow, liveShrink, markedFlights, maskDraft, mayWalk, menuWindow, mergeCompletions, moveSelection, normaliseKeySpec, pageStep, paletteMatches, paletteQuery, paletteRows, panelOf, parseCommandLine, pasteToLine, prepareSequence, prepareTerminal, reflowSequence, remember, resolveFullscreen, resolveKey, routeInput, sanitise, scrollBy, sendTurn, setPanel, settle, viewTop, walk, wordLeft, wordRight };
package/dist/keys.d.ts CHANGED
@@ -10,6 +10,8 @@ export interface KeyState {
10
10
  readonly draftEmpty: boolean;
11
11
  /** The focused panel's armed confirm key, set only while the draft is exactly it. */
12
12
  readonly armed?: string | null;
13
+ /** Full-screen's transcript viewport: following the bottom, or held. Absent inline. */
14
+ readonly viewport?: 'following' | 'held';
13
15
  }
14
16
  export type Route = {
15
17
  readonly kind: 'exit-chord';
@@ -40,6 +42,11 @@ export type Route = {
40
42
  readonly key: KeySpec;
41
43
  } | {
42
44
  readonly kind: 'cancel-turn';
45
+ }
46
+ /** Full-screen: move the transcript viewport. */
47
+ | {
48
+ readonly kind: 'scroll';
49
+ readonly act: 'page-up' | 'page-down' | 'bottom';
43
50
  } | {
44
51
  readonly kind: 'history';
45
52
  readonly dir: 'up' | 'down';
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,GAAG,OAAO,GAAG,IAAI,CAiBhD;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,MAAM,KAAK,GACb;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;CAAE,GACnE;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE;AAClC,sEAAsE;GACpE;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEhC,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,CA8D/E"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,GAAG,OAAO,GAAG,IAAI,CAiBhD;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC1C;AAED,MAAM,MAAM,KAAK,GACb;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;CAAE,GACnE;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE;AAClC,sEAAsE;GACpE;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE;AAClC,iDAAiD;GAC/C;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;CAAE,GAC7E;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEhC,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,CAsE/E"}
@@ -448,6 +448,47 @@ function ctrlC(armedAt, now, windowMs = CTRL_C_WINDOW_MS) {
448
448
  return armedAt !== null && now - armedAt <= windowMs ? "exit" : "arm";
449
449
  }
450
450
 
451
+ //#endregion
452
+ //#region src/fullscreen.ts
453
+ /** Whether full-screen is on: `SURFACE_FULLSCREEN` (`on` / `off`) over the app's option over on. */
454
+ function resolveFullscreen(option, env) {
455
+ const fallback = option ?? true;
456
+ const v = env?.trim().toLowerCase() ?? "";
457
+ if (v === "on") return {
458
+ on: true,
459
+ invalid: null
460
+ };
461
+ if (v === "off") return {
462
+ on: false,
463
+ invalid: null
464
+ };
465
+ return {
466
+ on: fallback,
467
+ invalid: v === "" ? null : env ?? null
468
+ };
469
+ }
470
+ const FOLLOWING = { held: null };
471
+ const bottomTop = (content, viewport) => Math.max(0, content - viewport);
472
+ /** The first content row shown. A held top past the end (the terminal grew) is clamped. */
473
+ function viewTop(s, content, viewport) {
474
+ const bottom = bottomTop(content, viewport);
475
+ return s.held === null ? bottom : Math.min(Math.max(0, s.held), bottom);
476
+ }
477
+ /** Content rows below the viewport. */
478
+ function linesBelow(s, content, viewport) {
479
+ return bottomTop(content, viewport) - viewTop(s, content, viewport);
480
+ }
481
+ /** Scrolls by `delta` rows (negative is up). Reaching the bottom follows again. */
482
+ function scrollBy(s, delta, content, viewport) {
483
+ const bottom = bottomTop(content, viewport);
484
+ const top = Math.min(Math.max(0, viewTop(s, content, viewport) + delta), bottom);
485
+ return top >= bottom ? FOLLOWING : { held: top };
486
+ }
487
+ /** A PgUp/PgDn step: a viewport less one row of overlap, never under one. */
488
+ function pageStep(viewport) {
489
+ return Math.max(1, viewport - 1);
490
+ }
491
+
451
492
  //#endregion
452
493
  //#region src/history.ts
453
494
  /**
@@ -623,6 +664,20 @@ function resolveKey(state, key, registry) {
623
664
  module: global.module,
624
665
  key: spec
625
666
  };
667
+ if (state.viewport !== void 0 && state.overlay === null) {
668
+ if (spec === "pageup") return {
669
+ kind: "scroll",
670
+ act: "page-up"
671
+ };
672
+ if (spec === "pagedown") return {
673
+ kind: "scroll",
674
+ act: "page-down"
675
+ };
676
+ if (spec === "end" && state.viewport === "held") return {
677
+ kind: "scroll",
678
+ act: "bottom"
679
+ };
680
+ }
626
681
  if (spec === "escape") return state.draftEmpty ? { kind: "cancel-turn" } : { kind: "ignore" };
627
682
  if (spec === "up") return {
628
683
  kind: "history",
@@ -862,13 +917,23 @@ function reprintStart(heights, budget) {
862
917
  }
863
918
  return 0;
864
919
  }
920
+ /**
921
+ * DEC private mode 1007 ("alternate scroll"): off, a terminal stops turning the mouse wheel into
922
+ * Up/Down in the alternate screen, which would walk input history. No mouse reporting is enabled,
923
+ * so drag-select stays the terminal's.
924
+ */
925
+ const WHEEL_ARROWS_OFF = "\x1B[?1007l";
926
+ /** Restores 1007. shortcut: assumes it was on (most terminals' default; xterm's is off); query it with DECRQM if that bites. */
927
+ const WHEEL_ARROWS_ON = "\x1B[?1007h";
865
928
  /** The bytes {@link prepareTerminal} writes, in order. */
866
929
  function prepareSequence(rows, opts = {}) {
867
- return (groundSequence(opts.ground) ?? "") + (opts.clear === false ? "" : CLEAR_PANE) + (opts.anchor === false ? "" : anchorPadding(rows));
930
+ const ground = groundSequence(opts.ground) ?? "";
931
+ if (opts.fullscreen === true) return ground + WHEEL_ARROWS_OFF;
932
+ return ground + (opts.clear === false ? "" : CLEAR_PANE) + (opts.anchor === false ? "" : anchorPadding(rows));
868
933
  }
869
934
  /**
870
- * Ground, clear and anchor the terminal before `render`. Returns a restore function that puts the
871
- * terminal's background back. It is also registered on `exit`, and SIGHUP / SIGTERM / SIGINT exit
935
+ * Ground, clear and anchor the terminal before `render` (in full-screen: ground and the wheel).
936
+ * Returns a restore function that puts the terminal's background and wheel back. It is also registered on `exit`, and SIGHUP / SIGTERM / SIGINT exit
872
937
  * through it, since their default action kills the process with no `exit` event (under Ink's raw
873
938
  * mode ctrl+c is input, so SIGINT only arrives from outside: `kill -INT`, a supervisor, tmux).
874
939
  * A terminal left black is worse than any rendering bug. A no-op off a TTY.
@@ -876,12 +941,13 @@ function prepareSequence(rows, opts = {}) {
876
941
  function prepareTerminal(out, opts = {}, proc = process) {
877
942
  if (out.isTTY !== true) return () => {};
878
943
  out.write(prepareSequence(out.rows, opts));
879
- if (groundSequence(opts.ground) === null) return () => {};
944
+ const back = (groundSequence(opts.ground) === null ? "" : RESET_GROUND) + (opts.fullscreen === true ? WHEEL_ARROWS_ON : "");
945
+ if (back === "") return () => {};
880
946
  let restored = false;
881
947
  const restore = () => {
882
948
  if (restored) return;
883
949
  restored = true;
884
- out.write(RESET_GROUND);
950
+ out.write(back);
885
951
  };
886
952
  proc.once("exit", restore);
887
953
  proc.once("SIGHUP", () => proc.exit(129));
@@ -1033,4 +1099,4 @@ function setPanel(o, kind, next) {
1033
1099
  }
1034
1100
 
1035
1101
  //#endregion
1036
- export { maskDraft as $, completeDraft as A, EMPTY_HISTORY as B, reprintStart as C, MENU_NAME_WIDTH as D, unavailableReason as E, paletteQuery as F, walk as G, mayWalk as H, paletteRows as I, EMPTY_DRAFT as J, CTRL_C_WINDOW_MS as K, parseCommandLine as L, menuWindow as M, moveSelection as N, clampSelection as O, paletteMatches as P, insertChunk as Q, keySpecOf as R, reflowSequence as S, routeInput as T, remember as U, HISTORY_MAX as V, settle as W, editKey as X, atEnd as Y, graphemeAt as Z, anchorPadding as _, answerEntry as a, RESERVED_GLOBAL_KEYS as at, prepareSequence as b, dropGaps as c, normaliseKeySpec as ct, markedFlights as d, pasteToLine as et, sendTurn as f, RESET_GROUND as g, REPRINT_LINES as h, addGap as i, CompositionError as it, enterRuns as j, commandUsage as k, emptyTranscript as l, applySuggestion as lt, DEFAULT_GROUND as m, setPanel as n, wordRight as nt, arriveTurn as o, assertComposes as ot, CLEAR_PANE as p, ctrlC as q, defineModule as r, applyInput as rt, commitEntry as s, composeModules as st, panelOf as t, wordLeft as tt, heldAsks as u, mergeCompletions as ut, groundSequence as v, sanitise as w, prepareTerminal as x, liveShrink as y, resolveKey as z };
1102
+ export { viewTop as $, clampSelection as A, keySpecOf as B, prepareTerminal as C, routeInput as D, sanitise as E, moveSelection as F, remember as G, EMPTY_HISTORY as H, paletteMatches as I, FOLLOWING as J, settle as K, paletteQuery as L, completeDraft as M, enterRuns as N, unavailableReason as O, menuWindow as P, scrollBy as Q, paletteRows as R, prepareSequence as S, reprintStart as T, HISTORY_MAX as U, resolveKey as V, mayWalk as W, pageStep as X, linesBelow as Y, resolveFullscreen as Z, WHEEL_ARROWS_OFF as _, applySuggestion as _t, answerEntry as a, graphemeAt as at, groundSequence as b, dropGaps as c, pasteToLine as ct, markedFlights as d, applyInput as dt, CTRL_C_WINDOW_MS as et, sendTurn as f, CompositionError as ft, RESET_GROUND as g, normaliseKeySpec as gt, REPRINT_LINES as h, composeModules as ht, addGap as i, editKey as it, commandUsage as j, MENU_NAME_WIDTH as k, emptyTranscript as l, wordLeft as lt, DEFAULT_GROUND as m, assertComposes as mt, setPanel as n, EMPTY_DRAFT as nt, arriveTurn as o, insertChunk as ot, CLEAR_PANE as p, RESERVED_GLOBAL_KEYS as pt, walk as q, defineModule as r, atEnd as rt, commitEntry as s, maskDraft as st, panelOf as t, ctrlC as tt, heldAsks as u, wordRight as ut, WHEEL_ARROWS_ON as v, mergeCompletions as vt, reflowSequence as w, liveShrink as x, anchorPadding as y, parseCommandLine as z };
package/dist/pure.d.ts CHANGED
@@ -3,6 +3,7 @@ export { applySuggestion, mergeCompletions } from './complete.js';
3
3
  export { assertComposes, CompositionError, composeModules, RESERVED_GLOBAL_KEYS, type Registry } from './compose.js';
4
4
  export { atEnd, type Draft, type EditKeys, EMPTY_DRAFT, editKey, insertChunk, maskDraft, pasteToLine, wordLeft, wordRight } from './editor.js';
5
5
  export { CTRL_C_WINDOW_MS, ctrlC } from './exit-chord.js';
6
+ export { FOLLOWING, linesBelow, pageStep, resolveFullscreen, type Scroll, scrollBy, viewTop } from './fullscreen.js';
6
7
  export { EMPTY_HISTORY, HISTORY_MAX, type HistoryState, mayWalk, remember, settle, walk } from './history.js';
7
8
  export { normaliseKeySpec } from './key-spec.js';
8
9
  export { type KeyState, keySpecOf, type Route, resolveKey } from './keys.js';
@@ -11,6 +12,6 @@ export { type Overlay, panelOf, setPanel } from './overlay.js';
11
12
  export { clampSelection, commandUsage, completeDraft, enterRuns, MENU_NAME_WIDTH, menuWindow, moveSelection, type PaletteRow, paletteMatches, paletteQuery, paletteRows, parseCommandLine } from './palette.js';
12
13
  export { type InputRoute, routeInput } from './route-input.js';
13
14
  export { sanitise } from './sanitise.js';
14
- export { anchorPadding, CLEAR_PANE, DEFAULT_GROUND, groundSequence, type LiveMeasure, liveShrink, type PrepareTerminalOptions, prepareSequence, prepareTerminal, RESET_GROUND, reflowSequence, type TerminalOut, type TerminalProcess } from './terminal.js';
15
+ export { anchorPadding, CLEAR_PANE, DEFAULT_GROUND, groundSequence, type LiveMeasure, liveShrink, type PrepareTerminalOptions, prepareSequence, prepareTerminal, RESET_GROUND, reflowSequence, type TerminalOut, type TerminalProcess, WHEEL_ARROWS_OFF, WHEEL_ARROWS_ON } from './terminal.js';
15
16
  export { type AnswerEntry, type AppEntry, type AskEntry, addGap, answerEntry, arriveTurn, commitEntry, type Entry, emptyTranscript, type Flight, type GapEntry, heldAsks, markedFlights, type NoteEntry, sendTurn, type Transcript } from './transcript.js';
16
17
  //# sourceMappingURL=pure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pure.d.ts","sourceRoot":"","sources":["../src/pure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,KAAK,QAAQ,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,EACL,KAAK,KAAK,EACV,KAAK,QAAQ,EACb,WAAW,EACX,OAAO,EACP,WAAW,EACX,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,WAAW,EACX,KAAK,YAAY,EACjB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAI,EACL,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EACV,aAAa,EACb,KAAK,UAAU,EACf,cAAc,EACd,YAAY,EACZ,WAAW,EACX,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,cAAc,EACd,KAAK,WAAW,EAChB,UAAU,EACV,KAAK,sBAAsB,EAC3B,eAAe,EACf,eAAe,EACf,YAAY,EACZ,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,WAAW,EACX,KAAK,KAAK,EACV,eAAe,EACf,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,QAAQ,EACR,aAAa,EACb,KAAK,SAAS,EACd,QAAQ,EACR,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"pure.d.ts","sourceRoot":"","sources":["../src/pure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,KAAK,QAAQ,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,EACL,KAAK,KAAK,EACV,KAAK,QAAQ,EACb,WAAW,EACX,OAAO,EACP,WAAW,EACX,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,iBAAiB,EACjB,KAAK,MAAM,EACX,QAAQ,EACR,OAAO,EACR,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,aAAa,EACb,WAAW,EACX,KAAK,YAAY,EACjB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAI,EACL,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EACV,aAAa,EACb,KAAK,UAAU,EACf,cAAc,EACd,YAAY,EACZ,WAAW,EACX,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,cAAc,EACd,KAAK,WAAW,EAChB,UAAU,EACV,KAAK,sBAAsB,EAC3B,eAAe,EACf,eAAe,EACf,YAAY,EACZ,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,gBAAgB,EAChB,eAAe,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,WAAW,EACX,KAAK,KAAK,EACV,eAAe,EACf,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,QAAQ,EACR,aAAa,EACb,KAAK,SAAS,EACd,QAAQ,EACR,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC"}
package/dist/pure.js CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as maskDraft, A as completeDraft, B as EMPTY_HISTORY, D as MENU_NAME_WIDTH, F as paletteQuery, G as walk, H as mayWalk, I as paletteRows, J as EMPTY_DRAFT, K as CTRL_C_WINDOW_MS, L as parseCommandLine, M as menuWindow, N as moveSelection, O as clampSelection, P as paletteMatches, Q as insertChunk, R as keySpecOf, S as reflowSequence, T as routeInput, U as remember, V as HISTORY_MAX, W as settle, X as editKey, Y as atEnd, _ as anchorPadding, a as answerEntry, at as RESERVED_GLOBAL_KEYS, b as prepareSequence, ct as normaliseKeySpec, d as markedFlights, et as pasteToLine, f as sendTurn, g as RESET_GROUND, i as addGap, it as CompositionError, j as enterRuns, k as commandUsage, l as emptyTranscript, lt as applySuggestion, m as DEFAULT_GROUND, n as setPanel, nt as wordRight, o as arriveTurn, ot as assertComposes, p as CLEAR_PANE, q as ctrlC, r as defineModule, rt as applyInput, s as commitEntry, st as composeModules, t as panelOf, tt as wordLeft, u as heldAsks, ut as mergeCompletions, v as groundSequence, w as sanitise, x as prepareTerminal, y as liveShrink, z as resolveKey } from "./overlay-DMjCbsaC.js";
1
+ import { $ as viewTop, A as clampSelection, B as keySpecOf, C as prepareTerminal, D as routeInput, E as sanitise, F as moveSelection, G as remember, H as EMPTY_HISTORY, I as paletteMatches, J as FOLLOWING, K as settle, L as paletteQuery, M as completeDraft, N as enterRuns, P as menuWindow, Q as scrollBy, R as paletteRows, S as prepareSequence, U as HISTORY_MAX, V as resolveKey, W as mayWalk, X as pageStep, Y as linesBelow, Z as resolveFullscreen, _ as WHEEL_ARROWS_OFF, _t as applySuggestion, a as answerEntry, b as groundSequence, ct as pasteToLine, d as markedFlights, dt as applyInput, et as CTRL_C_WINDOW_MS, f as sendTurn, ft as CompositionError, g as RESET_GROUND, gt as normaliseKeySpec, ht as composeModules, i as addGap, it as editKey, j as commandUsage, k as MENU_NAME_WIDTH, l as emptyTranscript, lt as wordLeft, m as DEFAULT_GROUND, mt as assertComposes, n as setPanel, nt as EMPTY_DRAFT, o as arriveTurn, ot as insertChunk, p as CLEAR_PANE, pt as RESERVED_GLOBAL_KEYS, q as walk, r as defineModule, rt as atEnd, s as commitEntry, st as maskDraft, t as panelOf, tt as ctrlC, u as heldAsks, ut as wordRight, v as WHEEL_ARROWS_ON, vt as mergeCompletions, w as reflowSequence, x as liveShrink, y as anchorPadding, z as parseCommandLine } from "./overlay-By-Ewn3S.js";
2
2
 
3
- export { CLEAR_PANE, CTRL_C_WINDOW_MS, CompositionError, DEFAULT_GROUND, EMPTY_DRAFT, EMPTY_HISTORY, HISTORY_MAX, MENU_NAME_WIDTH, RESERVED_GLOBAL_KEYS, RESET_GROUND, addGap, anchorPadding, answerEntry, applyInput, applySuggestion, arriveTurn, assertComposes, atEnd, clampSelection, commandUsage, commitEntry, completeDraft, composeModules, ctrlC, defineModule, editKey, emptyTranscript, enterRuns, groundSequence, heldAsks, insertChunk, keySpecOf, liveShrink, markedFlights, maskDraft, mayWalk, menuWindow, mergeCompletions, moveSelection, normaliseKeySpec, paletteMatches, paletteQuery, paletteRows, panelOf, parseCommandLine, pasteToLine, prepareSequence, prepareTerminal, reflowSequence, remember, resolveKey, routeInput, sanitise, sendTurn, setPanel, settle, walk, wordLeft, wordRight };
3
+ export { CLEAR_PANE, CTRL_C_WINDOW_MS, CompositionError, DEFAULT_GROUND, EMPTY_DRAFT, EMPTY_HISTORY, FOLLOWING, HISTORY_MAX, MENU_NAME_WIDTH, RESERVED_GLOBAL_KEYS, RESET_GROUND, WHEEL_ARROWS_OFF, WHEEL_ARROWS_ON, addGap, anchorPadding, answerEntry, applyInput, applySuggestion, arriveTurn, assertComposes, atEnd, clampSelection, commandUsage, commitEntry, completeDraft, composeModules, ctrlC, defineModule, editKey, emptyTranscript, enterRuns, groundSequence, heldAsks, insertChunk, keySpecOf, linesBelow, liveShrink, markedFlights, maskDraft, mayWalk, menuWindow, mergeCompletions, moveSelection, normaliseKeySpec, pageStep, paletteMatches, paletteQuery, paletteRows, panelOf, parseCommandLine, pasteToLine, prepareSequence, prepareTerminal, reflowSequence, remember, resolveFullscreen, resolveKey, routeInput, sanitise, scrollBy, sendTurn, setPanel, settle, viewTop, walk, wordLeft, wordRight };
@@ -48,6 +48,14 @@ export declare const REPRINT_LINES = 1000;
48
48
  * fit `budget` lines, and always the newest one, however tall.
49
49
  */
50
50
  export declare function reprintStart(heights: readonly number[], budget: number): number;
51
+ /**
52
+ * DEC private mode 1007 ("alternate scroll"): off, a terminal stops turning the mouse wheel into
53
+ * Up/Down in the alternate screen, which would walk input history. No mouse reporting is enabled,
54
+ * so drag-select stays the terminal's.
55
+ */
56
+ export declare const WHEEL_ARROWS_OFF = "\u001B[?1007l";
57
+ /** Restores 1007. shortcut: assumes it was on (most terminals' default; xterm's is off); query it with DECRQM if that bites. */
58
+ export declare const WHEEL_ARROWS_ON = "\u001B[?1007h";
51
59
  export interface PrepareTerminalOptions {
52
60
  /** `#rrggbb`, or `none` to leave the background alone. Default {@link DEFAULT_GROUND}. */
53
61
  readonly ground?: string | undefined;
@@ -55,6 +63,8 @@ export interface PrepareTerminalOptions {
55
63
  readonly clear?: boolean;
56
64
  /** Bottom-anchor the input. Default true. */
57
65
  readonly anchor?: boolean;
66
+ /** Full-screen: turn the wheel's arrow keys off (restored on exit), and never clear or anchor. */
67
+ readonly fullscreen?: boolean;
58
68
  }
59
69
  export interface TerminalOut {
60
70
  readonly isTTY?: boolean;
@@ -70,8 +80,8 @@ export interface TerminalProcess {
70
80
  exit(code: number): never;
71
81
  }
72
82
  /**
73
- * Ground, clear and anchor the terminal before `render`. Returns a restore function that puts the
74
- * terminal's background back. It is also registered on `exit`, and SIGHUP / SIGTERM / SIGINT exit
83
+ * Ground, clear and anchor the terminal before `render` (in full-screen: ground and the wheel).
84
+ * Returns a restore function that puts the terminal's background and wheel back. It is also registered on `exit`, and SIGHUP / SIGTERM / SIGINT exit
75
85
  * through it, since their default action kills the process with no `exit` event (under Ink's raw
76
86
  * mode ctrl+c is input, so SIGINT only arrives from outside: `kill -INT`, a supervisor, tmux).
77
87
  * A terminal left black is worse than any rendering bug. A no-op off a TTY.
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKxE;AAED,6DAA6D;AAC7D,eAAO,MAAM,YAAY,qBAAiB,CAAC;AAE3C,wEAAwE;AACxE,eAAO,MAAM,UAAU,+BAAyB,CAAC;AAEjD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE/D;AAED,oGAAoG;AACpG,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,MAAM,CAG7E;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAO/E;AAED,MAAM,WAAW,sBAAsB;IACrC,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,GAAE,sBAA2B,GAChC,MAAM,CAMR;AAED,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IAC5E,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,IAAI,GAAE,sBAA2B,EACjC,IAAI,GAAE,eAAyB,GAC9B,MAAM,IAAI,CAeZ"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKxE;AAED,6DAA6D;AAC7D,eAAO,MAAM,YAAY,qBAAiB,CAAC;AAE3C,wEAAwE;AACxE,eAAO,MAAM,UAAU,+BAAyB,CAAC;AAEjD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE/D;AAED,oGAAoG;AACpG,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,MAAM,CAG7E;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAO/E;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,kBAAgB,CAAC;AAC9C,gIAAgI;AAChI,eAAO,MAAM,eAAe,kBAAgB,CAAC;AAE7C,MAAM,WAAW,sBAAsB;IACrC,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,kGAAkG;IAClG,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,GAAE,sBAA2B,GAChC,MAAM,CAQR;AAED,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IAC5E,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,IAAI,GAAE,sBAA2B,EACjC,IAAI,GAAE,eAAyB,GAC9B,MAAM,IAAI,CAkBZ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnmal-ai/surface-core",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Pluggable terminal UI base on Ink 8 + React 19: module registry, createApp, the turn engine and the shell.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -23,8 +23,8 @@
23
23
  "dist"
24
24
  ],
25
25
  "dependencies": {
26
- "@mnmal-ai/surface-kit": "0.15.0",
27
- "@mnmal-ai/surface-theme": "0.15.0"
26
+ "@mnmal-ai/surface-kit": "0.16.0",
27
+ "@mnmal-ai/surface-theme": "0.16.0"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "ink": "^8.0.0",