@zakmandhro/bunti 0.1.4 → 0.2.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.
Files changed (203) hide show
  1. package/AGENTS.md +65 -0
  2. package/README.md +145 -34
  3. package/dist/cli.d.ts +44 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +147 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/colors.d.ts +144 -0
  8. package/dist/colors.d.ts.map +1 -0
  9. package/dist/colors.js +426 -0
  10. package/dist/colors.js.map +1 -0
  11. package/dist/components/Box.d.ts +11 -0
  12. package/dist/components/Box.d.ts.map +1 -0
  13. package/dist/components/Box.js +9 -0
  14. package/dist/components/Box.js.map +1 -0
  15. package/dist/components/Button.d.ts +24 -0
  16. package/dist/components/Button.d.ts.map +1 -0
  17. package/dist/components/Button.js +102 -0
  18. package/dist/components/Button.js.map +1 -0
  19. package/dist/components/Card.d.ts +33 -0
  20. package/dist/components/Card.d.ts.map +1 -0
  21. package/dist/components/Card.js +79 -0
  22. package/dist/components/Card.js.map +1 -0
  23. package/dist/components/Header.d.ts +23 -0
  24. package/dist/components/Header.d.ts.map +1 -0
  25. package/dist/components/Header.js +58 -0
  26. package/dist/components/Header.js.map +1 -0
  27. package/dist/components/Input.d.ts +25 -0
  28. package/dist/components/Input.d.ts.map +1 -0
  29. package/dist/components/Input.js +232 -0
  30. package/dist/components/Input.js.map +1 -0
  31. package/dist/components/Link.d.ts +21 -0
  32. package/dist/components/Link.d.ts.map +1 -0
  33. package/dist/components/Link.js +29 -0
  34. package/dist/components/Link.js.map +1 -0
  35. package/dist/components/Modal.d.ts +38 -0
  36. package/dist/components/Modal.d.ts.map +1 -0
  37. package/dist/components/Modal.js +87 -0
  38. package/dist/components/Modal.js.map +1 -0
  39. package/dist/components/Progress.d.ts +27 -0
  40. package/dist/components/Progress.d.ts.map +1 -0
  41. package/dist/components/Progress.js +39 -0
  42. package/dist/components/Progress.js.map +1 -0
  43. package/dist/components/Spinner.d.ts +19 -0
  44. package/dist/components/Spinner.d.ts.map +1 -0
  45. package/dist/components/Spinner.js +27 -0
  46. package/dist/components/Spinner.js.map +1 -0
  47. package/dist/components/index.d.ts +10 -0
  48. package/dist/components/index.d.ts.map +1 -0
  49. package/dist/components/index.js +10 -0
  50. package/dist/components/index.js.map +1 -0
  51. package/dist/data/nf-glyphs.d.ts +11 -0
  52. package/dist/data/nf-glyphs.d.ts.map +1 -0
  53. package/dist/data/nf-glyphs.js +535 -0
  54. package/dist/data/nf-glyphs.js.map +1 -0
  55. package/dist/data/nf-names.d.ts +8 -0
  56. package/dist/data/nf-names.d.ts.map +1 -0
  57. package/dist/data/nf-names.js +2 -0
  58. package/dist/data/nf-names.js.map +1 -0
  59. package/dist/demo-registry.d.ts +27 -0
  60. package/dist/demo-registry.d.ts.map +1 -0
  61. package/dist/demo-registry.js +57 -0
  62. package/dist/demo-registry.js.map +1 -0
  63. package/dist/demos/2048.ts +743 -0
  64. package/dist/demos/animation.ts +246 -0
  65. package/dist/demos/demo-layout.ts +124 -0
  66. package/dist/demos/engine.ts +374 -0
  67. package/dist/demos/interaction.ts +91 -0
  68. package/dist/demos/login.ts +203 -0
  69. package/dist/demos/mission-control.ts +558 -0
  70. package/dist/demos/showcase.ts +224 -0
  71. package/dist/detect.d.ts +104 -0
  72. package/dist/detect.d.ts.map +1 -0
  73. package/dist/detect.js +227 -0
  74. package/dist/detect.js.map +1 -0
  75. package/dist/diagnostics.d.ts +73 -0
  76. package/dist/diagnostics.d.ts.map +1 -0
  77. package/dist/diagnostics.js +225 -0
  78. package/dist/diagnostics.js.map +1 -0
  79. package/dist/dsl/context.d.ts +11 -0
  80. package/dist/dsl/context.d.ts.map +1 -0
  81. package/dist/dsl/context.js +563 -0
  82. package/dist/dsl/context.js.map +1 -0
  83. package/dist/dsl/hooks.d.ts +12 -0
  84. package/dist/dsl/hooks.d.ts.map +1 -0
  85. package/dist/dsl/hooks.js +148 -0
  86. package/dist/dsl/hooks.js.map +1 -0
  87. package/dist/dsl/interaction.d.ts +16 -0
  88. package/dist/dsl/interaction.d.ts.map +1 -0
  89. package/dist/dsl/interaction.js +101 -0
  90. package/dist/dsl/interaction.js.map +1 -0
  91. package/dist/dsl/layers.d.ts +14 -0
  92. package/dist/dsl/layers.d.ts.map +1 -0
  93. package/dist/dsl/layers.js +87 -0
  94. package/dist/dsl/layers.js.map +1 -0
  95. package/dist/dsl/motion.d.ts +10 -0
  96. package/dist/dsl/motion.d.ts.map +1 -0
  97. package/dist/dsl/motion.js +150 -0
  98. package/dist/dsl/motion.js.map +1 -0
  99. package/dist/dsl/render.d.ts +22 -0
  100. package/dist/dsl/render.d.ts.map +1 -0
  101. package/dist/dsl/render.js +69 -0
  102. package/dist/dsl/render.js.map +1 -0
  103. package/dist/dsl/types.d.ts +510 -0
  104. package/dist/dsl/types.d.ts.map +1 -0
  105. package/dist/dsl/types.js +33 -0
  106. package/dist/dsl/types.js.map +1 -0
  107. package/dist/dsl.d.ts +18 -0
  108. package/dist/dsl.d.ts.map +1 -0
  109. package/dist/dsl.js +17 -0
  110. package/dist/dsl.js.map +1 -0
  111. package/dist/easing.d.ts +45 -0
  112. package/dist/easing.d.ts.map +1 -0
  113. package/dist/easing.js +121 -0
  114. package/dist/easing.js.map +1 -0
  115. package/dist/geometry.d.ts +77 -0
  116. package/dist/geometry.d.ts.map +1 -0
  117. package/dist/geometry.js +130 -0
  118. package/dist/geometry.js.map +1 -0
  119. package/dist/icons-full.d.ts +5 -0
  120. package/dist/icons-full.d.ts.map +1 -0
  121. package/dist/icons-full.js +31 -0
  122. package/dist/icons-full.js.map +1 -0
  123. package/dist/icons.d.ts +442 -0
  124. package/dist/icons.d.ts.map +1 -0
  125. package/dist/icons.js +314 -0
  126. package/dist/icons.js.map +1 -0
  127. package/dist/index.d.ts +228 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +46 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/input.d.ts +177 -0
  132. package/dist/input.d.ts.map +1 -0
  133. package/dist/input.js +533 -0
  134. package/dist/input.js.map +1 -0
  135. package/dist/layout.d.ts +194 -0
  136. package/dist/layout.d.ts.map +1 -0
  137. package/dist/layout.js +673 -0
  138. package/dist/layout.js.map +1 -0
  139. package/dist/render.d.ts +49 -0
  140. package/dist/render.d.ts.map +1 -0
  141. package/dist/render.js +650 -0
  142. package/dist/render.js.map +1 -0
  143. package/dist/state.d.ts +226 -0
  144. package/dist/state.d.ts.map +1 -0
  145. package/dist/state.js +130 -0
  146. package/dist/state.js.map +1 -0
  147. package/dist/theme.d.ts +129 -0
  148. package/dist/theme.d.ts.map +1 -0
  149. package/dist/theme.js +167 -0
  150. package/dist/theme.js.map +1 -0
  151. package/dist/themes/catppuccin-mocha.d.ts +19 -0
  152. package/dist/themes/catppuccin-mocha.d.ts.map +1 -0
  153. package/dist/themes/catppuccin-mocha.js +36 -0
  154. package/dist/themes/catppuccin-mocha.js.map +1 -0
  155. package/dist/themes/dracula.d.ts +21 -0
  156. package/dist/themes/dracula.d.ts.map +1 -0
  157. package/dist/themes/dracula.js +37 -0
  158. package/dist/themes/dracula.js.map +1 -0
  159. package/dist/themes/github-light.d.ts +21 -0
  160. package/dist/themes/github-light.d.ts.map +1 -0
  161. package/dist/themes/github-light.js +36 -0
  162. package/dist/themes/github-light.js.map +1 -0
  163. package/dist/themes/index.d.ts +19 -0
  164. package/dist/themes/index.d.ts.map +1 -0
  165. package/dist/themes/index.js +17 -0
  166. package/dist/themes/index.js.map +1 -0
  167. package/dist/themes/nord.d.ts +23 -0
  168. package/dist/themes/nord.d.ts.map +1 -0
  169. package/dist/themes/nord.js +38 -0
  170. package/dist/themes/nord.js.map +1 -0
  171. package/dist/themes/one-dark-pro.d.ts +21 -0
  172. package/dist/themes/one-dark-pro.d.ts.map +1 -0
  173. package/dist/themes/one-dark-pro.js +36 -0
  174. package/dist/themes/one-dark-pro.js.map +1 -0
  175. package/dist/themes/tokyo-night.d.ts +20 -0
  176. package/dist/themes/tokyo-night.d.ts.map +1 -0
  177. package/dist/themes/tokyo-night.js +37 -0
  178. package/dist/themes/tokyo-night.js.map +1 -0
  179. package/dist/utils.d.ts +28 -0
  180. package/dist/utils.d.ts.map +1 -0
  181. package/dist/utils.js +158 -0
  182. package/dist/utils.js.map +1 -0
  183. package/dist/vendor/colors.d.ts +45 -0
  184. package/dist/vendor/colors.d.ts.map +1 -0
  185. package/dist/vendor/colors.js +72 -0
  186. package/dist/vendor/colors.js.map +1 -0
  187. package/llms.txt +79 -0
  188. package/package.json +52 -11
  189. package/src/colors.ts +0 -255
  190. package/src/components/Button.ts +0 -104
  191. package/src/components/Card.ts +0 -53
  192. package/src/components/Header.ts +0 -65
  193. package/src/components/Input.ts +0 -124
  194. package/src/components/index.ts +0 -4
  195. package/src/data/glyphs.ts +0 -30
  196. package/src/detect.ts +0 -60
  197. package/src/dsl.ts +0 -661
  198. package/src/icons.ts +0 -186
  199. package/src/index.ts +0 -72
  200. package/src/layout.ts +0 -640
  201. package/src/render.ts +0 -302
  202. package/src/state.ts +0 -148
  203. package/src/utils.ts +0 -165
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Bunti DSL primary entry point: render.
3
+ */
4
+ import { init } from '../icons';
5
+ import { flush, loop } from '../render';
6
+ import { ANSI, clearBackBuffer, createScreenState, } from '../state';
7
+ import { createScreenContext } from './context';
8
+ /**
9
+ * Starts a Bunti app: runs `callback` every frame (immediate mode —
10
+ * redraw the whole screen from state each call) and flushes only the
11
+ * changed cells to the terminal. The returned promise resolves when the
12
+ * loop stops (ctx.requestStop() or Ctrl+C). Pass `once: true` to render
13
+ * a single frame and return. Keyboard input needs a real TTY on stdin:
14
+ * piped input is ignored.
15
+ * @example
16
+ * await render((ctx) => {
17
+ * ctx.box({ width: 30, border: 'rounded' }, (s) => s.text('hi'));
18
+ * if (ctx.lastKey === 'q') ctx.requestStop();
19
+ * }, { keyboard: true, mouse: true, alternateBuffer: true, hideCursor: true });
20
+ */
21
+ export async function render(callback, options = {}) {
22
+ if (typeof Bun === 'undefined') {
23
+ throw new Error('Bunti is Bun-native and uses Bun runtime APIs. ' +
24
+ 'Run with Bun >=1.0: https://bun.sh — Node.js is not supported.');
25
+ }
26
+ // createScreenState runs env detection once per render() (state.terminal).
27
+ const state = createScreenState(options);
28
+ // Icon tier: an explicit ScreenOptions.nerdFont always wins; otherwise the
29
+ // detected profile decides ('yes'/'assumed-yes' -> Nerd Font glyphs).
30
+ if (options.nerdFont !== undefined) {
31
+ await init({ nerdFont: options.nerdFont });
32
+ }
33
+ else {
34
+ await init({ profile: state.terminal });
35
+ }
36
+ const tick = () => {
37
+ clearBackBuffer(state);
38
+ const b = createScreenContext(state);
39
+ if (typeof callback === 'string') {
40
+ b.blit(0, 0, callback);
41
+ }
42
+ else {
43
+ callback(b);
44
+ }
45
+ if (state.isStopped)
46
+ return;
47
+ b.flushFlow();
48
+ if (state.isStopped)
49
+ return;
50
+ flush(state);
51
+ };
52
+ if (options.once) {
53
+ tick();
54
+ // Let the terminal settle for a frame, then resolve. No interval or
55
+ // stdin listener was started in once mode, so nothing keeps the event
56
+ // loop alive and the host process (never killed by the library) can
57
+ // continue or exit naturally.
58
+ await new Promise((resolve) => {
59
+ setTimeout(resolve, 50);
60
+ });
61
+ // flush() hides the cursor per-frame when requested; a once-shot must
62
+ // not leave the user's cursor invisible.
63
+ if (options.hideCursor)
64
+ process.stdout.write(ANSI.showCursor);
65
+ return;
66
+ }
67
+ await loop(state, (_s) => tick());
68
+ }
69
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/dsl/render.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,IAAI,EACJ,eAAe,EACf,iBAAiB,GAElB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,QAA8C,EAC9C,UAA8C,EAAE;IAEhD,IAAI,OAAO,GAAG,KAAK,WAAW,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,iDAAiD;YAC/C,gEAAgE,CACnE,CAAC;IACJ,CAAC;IAED,2EAA2E;IAC3E,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEzC,2EAA2E;IAC3E,sEAAsE;IACtE,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,eAAe,CAAC,KAAK,CAAC,CAAC;QACvB,MAAM,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,CAAC,CAAC,CAAC;QACd,CAAC;QACD,IAAI,KAAK,CAAC,SAAS;YAAE,OAAO;QAC5B,CAAC,CAAC,SAAS,EAAE,CAAC;QACd,IAAI,KAAK,CAAC,SAAS;YAAE,OAAO;QAC5B,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,EAAE,CAAC;QACP,oEAAoE;QACpE,sEAAsE;QACtE,oEAAoE;QACpE,8BAA8B;QAC9B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,sEAAsE;QACtE,yCAAyC;QACzC,IAAI,OAAO,CAAC,UAAU;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IAED,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,510 @@
1
+ /**
2
+ * Bunti DSL shared types and constants.
3
+ */
4
+ import type { bg, darken, fg, Gradient, lighten, rgb } from '../colors';
5
+ import type { TerminalProfile } from '../detect';
6
+ import type { PlacedRectInput, PlacedRectOptions, Rect, RectInput, SplitOptions } from '../geometry';
7
+ import type { KeyEvent } from '../input';
8
+ import type { ListOptions, SideColors, StyleOptions, TableOptions } from '../layout';
9
+ import type { Cell, Hitbox, RGB, ScreenState } from '../state';
10
+ import type { Theme, ThemeColor, ThemeInput } from '../theme';
11
+ import type { BuntiColor } from '../vendor/colors';
12
+ /**
13
+ * Normalized key-name constants for `ctx.lastKey` / `ctx.keyPressed()`.
14
+ * Printable keys are their literal character ('a', 'A', ' '); mouse events
15
+ * arrive as the 'click' / 'wheel_up' / 'wheel_down' pseudo-keys.
16
+ * @example if (ctx.keyPressed(KEYS.ENTER)) submit();
17
+ */
18
+ export declare const KEYS: {
19
+ UP: string;
20
+ DOWN: string;
21
+ RIGHT: string;
22
+ LEFT: string;
23
+ ENTER: string;
24
+ ESCAPE: string;
25
+ TAB: string;
26
+ BACKSPACE: string;
27
+ SPACE: string;
28
+ HOME: string;
29
+ END: string;
30
+ DELETE: string;
31
+ PAGE_UP: string;
32
+ PAGE_DOWN: string;
33
+ INSERT: string;
34
+ /** Left-button click (emitted once, on release; requires `mouse: true`). */
35
+ CLICK: string;
36
+ /** Mouse wheel scrolled up (requires `mouse: true`). */
37
+ WHEEL_UP: string;
38
+ /** Mouse wheel scrolled down (requires `mouse: true`). */
39
+ WHEEL_DOWN: string;
40
+ };
41
+ /**
42
+ * Options for `ctx.box()`. Extends StyleOptions (width/height/padding/
43
+ * border/align/wrap) with placement, layering, and color controls.
44
+ */
45
+ export interface DSLBoxOptions extends StyleOptions {
46
+ /** Background fill: palette name, hex, ANSI-256 code, RGB, Gradient, or theme token. */
47
+ bgColor?: string | number | RGB | Gradient | ThemeColor;
48
+ /**
49
+ * Default text color inside the box. 'blank' auto-picks black or white
50
+ * for WCAG contrast against `bgColor`.
51
+ */
52
+ color?: string | number | RGB | ThemeColor | 'blank';
53
+ /** Column offset (cells) inside the parent area. Unplaced boxes center. */
54
+ x?: number;
55
+ /** Row offset (cells) inside the parent area. Unplaced boxes center. */
56
+ y?: number;
57
+ /**
58
+ * Promotes the box onto its own composited layer at this z-index —
59
+ * shorthand for wrapping it in `ctx.layer(zIndex, ...)`.
60
+ */
61
+ zIndex?: number;
62
+ /** Pins the box to the top or bottom edge at full parent width. */
63
+ anchor?: 'top' | 'bottom';
64
+ /** Reserved size hint ('auto' sizes to content). */
65
+ size?: 'auto' | number;
66
+ /** Title rendered into the top border. */
67
+ title?: string;
68
+ /** Styler applied to the rendered title (e.g. a ThemeColor or color.bold). */
69
+ titleStyle?: (s: string) => string;
70
+ /** Stable identifier (useful with hitboxes/focus). */
71
+ id?: string;
72
+ /**
73
+ * Border color: single color value, a styler function, or per-side
74
+ * colors ({ top, bottom, left, right }).
75
+ */
76
+ borderColor?: string | number | RGB | ThemeColor | ((s: string) => string) | SideColors;
77
+ /** If true, the string is returned but NOT appended to the flow. */
78
+ detach?: boolean;
79
+ }
80
+ /** Options for `ctx.typewriter()`. */
81
+ export interface TypewriterOptions {
82
+ /** Keys the animation clock (restartable via `ctx.restartAnimation(id)`). */
83
+ id?: string;
84
+ /** Typing speed in characters per second (default 24). */
85
+ cps?: number;
86
+ /** Milliseconds to wait before typing starts. */
87
+ delay?: number;
88
+ /** Restart from the beginning after the full text is typed. */
89
+ loop?: boolean;
90
+ /** Cursor glyph (default '█'). */
91
+ cursor?: string;
92
+ /** Set false to disable cursor blinking after typing completes. */
93
+ blink?: boolean;
94
+ /** Cursor blink period in milliseconds (default 450). */
95
+ blinkRate?: number;
96
+ }
97
+ /** Frame snapshot returned by `ctx.typewriter()`. */
98
+ export interface TypewriterState {
99
+ /** The portion of the text typed so far. */
100
+ text: string;
101
+ /** The cursor glyph for this frame (' ' during blink-off phases). */
102
+ cursor: string;
103
+ /** True once the full text has been typed. */
104
+ done: boolean;
105
+ /** Number of graphemes typed so far. */
106
+ index: number;
107
+ /** Typing progress 0..1. */
108
+ progress: number;
109
+ }
110
+ /** Options for `ctx.layer()`. */
111
+ export interface LayerOptions {
112
+ /** Composite order: higher z-index layers paint on top (default 0). */
113
+ zIndex?: number;
114
+ /**
115
+ * Paints a drop shadow under the layer's painted content bounds
116
+ * (offset +2 columns, +1 row) at composite time. The shadow darkens
117
+ * whatever sits below it, including lower layers.
118
+ */
119
+ shadow?: boolean;
120
+ /**
121
+ * Dims everything below this layer by 0..1 (backdrop luminance scale
122
+ * toward black) before the layer composites. Applied in z-order, so
123
+ * lower layers are dimmed too.
124
+ */
125
+ backdrop?: number;
126
+ }
127
+ /**
128
+ * The contextual builder passed to every render closure. One frame = one
129
+ * callback invocation: read input, derive state, draw.
130
+ *
131
+ * Coordinate model: `x`/`y` are cell offsets local to the current context
132
+ * area (the whole screen at the root; the padded interior inside a box).
133
+ * At the root, `box()` paints straight into the screen buffer and centers
134
+ * when not given `x`/`y`; inside a box, drawing calls append to that box's
135
+ * text flow. Use `layer()`/`zIndex` for anything that must overlap.
136
+ */
137
+ export interface BuntiContext {
138
+ /**
139
+ * ANSI color helpers: picocolors-style stylers (`color.bold`,
140
+ * `color.cyan`, ...) plus Bunti's RGB helpers (`color.fg(value, text)`,
141
+ * `color.bg`, `color.rgb`, `color.darken`, `color.lighten`).
142
+ */
143
+ color: BuntiColor & {
144
+ darken: typeof darken;
145
+ lighten: typeof lighten;
146
+ rgb: typeof rgb;
147
+ fg: typeof fg;
148
+ bg: typeof bg;
149
+ };
150
+ /** The underlying screen state (buffers, options, input). Advanced use. */
151
+ state: ScreenState;
152
+ /** Width of the current context area in cells. */
153
+ width: number;
154
+ /** Height of the current context area in cells (rows). */
155
+ height: number;
156
+ /** The current context area as an absolute Rect. */
157
+ area: Rect;
158
+ /** True on the top-level screen context (false inside box/layer closures). */
159
+ isRoot: boolean;
160
+ /** Absolute column of this context's origin (for `blit`/`rect` math). */
161
+ offsetX: number;
162
+ /** Absolute row of this context's origin (for `blit`/`rect` math). */
163
+ offsetY: number;
164
+ /** Column the text flow ends at on its last line (local). */
165
+ readonly cursorX: number;
166
+ /** Row the text flow ends at (local) — where the next text/box lands. */
167
+ readonly cursorY: number;
168
+ /** Mouse column (0-based screen cells; requires `mouse: true`). */
169
+ mouseX: number;
170
+ /** Mouse row (0-based screen cells; requires `mouse: true`). */
171
+ mouseY: number;
172
+ /** Raw SGR button code of the most recent mouse event. */
173
+ mouseButton: number;
174
+ /** True while the left mouse button is held down. */
175
+ isMouseDown: boolean;
176
+ /**
177
+ * First unmodified key name of this frame, or undefined when no key
178
+ * arrived. Printable keys are the literal character ('a', ' '); special
179
+ * keys are normalized lowercase names ('up', 'enter', 'escape', 'f1');
180
+ * mouse events arrive as 'click' / 'wheel_up' / 'wheel_down'. Requires
181
+ * `keyboard: true` in the render options.
182
+ * @example if (ctx.lastKey === 'q') ctx.requestStop();
183
+ */
184
+ lastKey?: string;
185
+ /**
186
+ * All KeyEvents of this frame (multiple keys per frame arrive whole),
187
+ * including ctrl/alt combos and synthetic 'release' events that
188
+ * `lastKey` never carries. Requires `keyboard: true`.
189
+ * @example for (const e of ctx.keys) if (e.key === 'enter') submit();
190
+ */
191
+ keys: KeyEvent[];
192
+ /** Id of the currently focused focusable, if any. */
193
+ focusedId?: string;
194
+ /**
195
+ * Milliseconds elapsed since render() started. Drives time-based
196
+ * animation (fps-independent).
197
+ * @example const pulse = Math.sin(ctx.elapsedTime / 300);
198
+ */
199
+ elapsedTime: number;
200
+ /**
201
+ * The env-detected terminal profile (app, version, multiplexer, truecolor,
202
+ * sync output, Nerd Font policy). Detected once per render().
203
+ */
204
+ readonly terminal: TerminalProfile;
205
+ /**
206
+ * The active semantic theme for this subtree. Tokens are callable fg
207
+ * stylers that also carry `.rgb`/`.hex`, so they work as both text
208
+ * wrappers and color values.
209
+ * @example ctx.box({ bgColor: ctx.theme.surface }, (s) => s.text(ctx.theme.primary('hi')));
210
+ */
211
+ readonly theme: Theme;
212
+ /**
213
+ * Swaps the active theme live and requests a rerender. Sparse inputs are
214
+ * completed via createTheme() derivation.
215
+ * @example ctx.setTheme(dracula); // from '@zakmandhro/bunti/themes'
216
+ */
217
+ setTheme(theme: Theme | ThemeInput): void;
218
+ /**
219
+ * Runs the callback with an overridden theme for that subtree only.
220
+ * Partial inputs overlay the current theme; the previous theme is
221
+ * restored afterwards.
222
+ * @example ctx.themed({ primary: '#ff5f87' }, (sub) => sidebar(sub));
223
+ */
224
+ themed(theme: Theme | ThemeInput, callback: (sub: BuntiContext) => void): BuntiContext;
225
+ /**
226
+ * True if `name` was pressed (or auto-repeated) this frame. Requires
227
+ * `keyboard: true`.
228
+ * @example if (ctx.keyPressed('escape')) closeModal();
229
+ */
230
+ keyPressed(name: string): boolean;
231
+ /**
232
+ * True from a key's first press until its repeat stream expires
233
+ * (~150ms hold window) — smooth held-key movement on legacy terminals.
234
+ * @example if (ctx.isKeyHeld('right')) player.x += speed * ctx.dt;
235
+ */
236
+ isKeyHeld(name: string): boolean;
237
+ /**
238
+ * Appends text to the current flow at the cursor. Supports '\n' and
239
+ * pre-styled ANSI strings; returns the context for chaining.
240
+ * @example ctx.text(ctx.color.bold('Status: ')).text('ready\n');
241
+ */
242
+ text(str: string | number): BuntiContext;
243
+ /**
244
+ * Resolves an icon name to its glyph (Nerd Font, or ASCII fallback on
245
+ * plain terminals). Pure string return for template-literal safety.
246
+ * Curated names work out of the box; `import '@zakmandhro/bunti/icons-full'`
247
+ * unlocks all ~10.7k Nerd Font names.
248
+ * @example ctx.text(`${ctx.icon('rocket')} Launch`);
249
+ */
250
+ icon(name: string): string;
251
+ /**
252
+ * Paints a (possibly multi-line, ANSI-styled) string directly into the
253
+ * screen buffer at absolute cell coordinates — exact-position text,
254
+ * sprites, labels, and ASCII art.
255
+ * @example ctx.blit(2, 1, 'FPS 60', { fg: 'gold' });
256
+ */
257
+ blit(x: number, y: number, content: string, style?: Partial<Cell>): BuntiContext;
258
+ /**
259
+ * Fills a w×h cell rectangle at absolute coordinates with a style —
260
+ * bars, panels, charts, and backgrounds. Pure-background fills keep the
261
+ * characters already painted underneath.
262
+ * @example ctx.rect(0, 0, ctx.width, 3, { bg: ctx.theme.surface });
263
+ */
264
+ rect(x: number, y: number, w: number, h: number, style: Partial<Cell>): BuntiContext;
265
+ /**
266
+ * Crops a multi-line string to a width×height window starting at
267
+ * `scrollY` — the primitive for scrollable content.
268
+ */
269
+ viewport(content: string, width: number, height: number, scrollY?: number): string;
270
+ /**
271
+ * Runs the callback, wraps everything it appended in one color, and
272
+ * pushes the styled result to the flow. Returns the styled string.
273
+ */
274
+ span(options: {
275
+ color?: string | number | RGB | ((s: string) => string);
276
+ }, callback: (sub: BuntiContext) => void): string;
277
+ /**
278
+ * Draws a styled box and renders the callback inside its padded
279
+ * interior (a fresh sub-context). At the root, boxes paint directly to
280
+ * the screen and center unless given x/y; nested boxes join the parent
281
+ * flow. Returns the rendered string.
282
+ * @example ctx.box({ width: 40, border: 'rounded', title: 'Log' }, (s) => s.text('...'));
283
+ */
284
+ box(options: DSLBoxOptions, callback: (sub: BuntiContext) => void): string;
285
+ /**
286
+ * Renders the callback into a transparent buffer composited above the
287
+ * base content by z-index — THE primitive for modals, HUDs, popovers,
288
+ * and anything that must overlap other content.
289
+ * @example ctx.layer(10, (overlay) => overlay.box({ width: 30, height: 5 }, drawModal));
290
+ */
291
+ layer(zIndexOrOptions: number | LayerOptions, callback: (sub: BuntiContext) => void): BuntiContext;
292
+ layer(callback: (sub: BuntiContext) => void): BuntiContext;
293
+ /** Joins rendered blocks side-by-side, padding each to its own width. */
294
+ joinHorizontal(...blocks: string[]): string;
295
+ /** Stacks rendered blocks vertically (skips empty strings). */
296
+ joinVertical(...blocks: string[]): string;
297
+ /**
298
+ * Fills the whole screen background with a color or gradient.
299
+ * @example ctx.wallpaper(ctx.gradient({ colors: ['midnight', 'plasma'] }));
300
+ */
301
+ wallpaper(input: string | number | RGB | ThemeColor | RGB[] | Gradient | {
302
+ color: any;
303
+ }): void;
304
+ /**
305
+ * Builds a multi-stop Gradient value for `wallpaper`/`bgColor`.
306
+ * @example ctx.gradient({ colors: ['#0000ff', '#ff0000'], direction: 'horizontal' });
307
+ */
308
+ gradient(options: {
309
+ colors: (string | number | RGB | ThemeColor)[];
310
+ direction?: 'vertical' | 'horizontal';
311
+ steps?: number;
312
+ }): Gradient;
313
+ /** Builds an RGB color value for truecolor rendering. */
314
+ rgb(r: number, g: number, b: number): RGB;
315
+ /**
316
+ * Frame-persistent state. The keyed form is position-independent; the
317
+ * keyless form is positional (React-style) and must not be called
318
+ * conditionally. Setting a value requests a rerender.
319
+ * @example const [count, setCount] = ctx.useState('count', 0);
320
+ */
321
+ useState<T>(initial: T): [T, (val: T) => void];
322
+ useState<T>(key: string, initial: T): [T, (val: T) => void];
323
+ /**
324
+ * Like useState, but the value also persists across app restarts
325
+ * (stored in .tmp/bunti_store.json).
326
+ */
327
+ usePersistentState<T>(key: string, initial: T): [T, (val: T) => void];
328
+ /**
329
+ * Registers `id` in the Tab-focus cycle and returns true while it is
330
+ * focused. The first registered focusable receives initial focus.
331
+ */
332
+ focusable(id: string): boolean;
333
+ /** True while `id` holds focus. */
334
+ isFocused(id: string): boolean;
335
+ /** Moves focus to `id`. */
336
+ focus(id: string): void;
337
+ /** Advances focus to the next registered focusable (what Tab does). */
338
+ focusNext(): void;
339
+ /**
340
+ * Registers a clickable region and returns its interaction snapshot for
341
+ * this frame. Requires `mouse: true`.
342
+ * @example const { hovered, clicked } = ctx.hitbox('save', { x: 2, y: 5, width: 10, height: 1 });
343
+ */
344
+ hitbox(id: string, bounds: RectInput): {
345
+ box: Hitbox;
346
+ hovered: boolean;
347
+ pressed: boolean;
348
+ clicked: boolean;
349
+ };
350
+ /**
351
+ * Resolves a partial rect (percent/fr sizes allowed) against the current
352
+ * context area into absolute cells. `y` defaults to the flow cursor.
353
+ */
354
+ resolveRect(bounds: RectInput): Rect;
355
+ /**
356
+ * Places a rect within the current area with alignment defaults
357
+ * (centered unless overridden) — the same placement `box()` uses.
358
+ */
359
+ resolveLocalRect(bounds: PlacedRectInput, options?: PlacedRectOptions): Rect;
360
+ /**
361
+ * Splits the current area into tracks from fixed sizes, percentages,
362
+ * and 'fr' fill units — the layout workhorse for dashboards.
363
+ * @example const [sidebar, main] = ctx.split({ direction: 'horizontal', constraints: [24, '1fr'] });
364
+ */
365
+ split(options: SplitOptions): Rect[];
366
+ /**
367
+ * True while the mouse is inside the hitbox registered for `id`.
368
+ * @example const border = ctx.isHovered('card') ? theme.focus : theme.border;
369
+ */
370
+ isHovered(id: string): boolean;
371
+ /** Mouse currently down inside the hitbox. */
372
+ isPressed(id: string): boolean;
373
+ /**
374
+ * True exactly one frame per click (SGR release at the press origin) —
375
+ * fire actions here, not on isPressed.
376
+ * @example if (ctx.isClicked('save')) save();
377
+ */
378
+ isClicked(id: string): boolean;
379
+ /** Hover turned on for this hitbox this frame. */
380
+ isHoverEnter(id: string): boolean;
381
+ /** Hover turned off for this hitbox this frame. */
382
+ isHoverLeave(id: string): boolean;
383
+ /**
384
+ * Renders a selectable list with built-in up/down keyboard navigation,
385
+ * mouse hover/click selection, and theme-token highlighting. Selection
386
+ * state lives in `useState(`${id}_index`)`.
387
+ * @example ctx.list('menu', ['Start', 'Options', 'Quit'], { maxVisible: 5 });
388
+ */
389
+ list(id: string, items: string[], options?: ListOptions): BuntiContext;
390
+ /**
391
+ * Renders rows of cells as an aligned table with shared borders.
392
+ * @example ctx.table([['NAME', 'STATUS'], ['api', 'ready']], { width: '100%' });
393
+ */
394
+ table(rows: string[][], options?: TableOptions): BuntiContext;
395
+ /**
396
+ * 0→1 progress over `duration` ms. loop: true wraps, 'yoyo' bounces
397
+ * 0→1→0. Pass `id` for a restartable clock (restartAnimation).
398
+ * @example const t = ctx.animate(800, { loop: 'yoyo', easing: easeInOutCubic });
399
+ */
400
+ animate(duration: number, options?: {
401
+ loop?: boolean | 'yoyo';
402
+ delay?: number;
403
+ id?: string;
404
+ easing?: (t: number) => number;
405
+ }): number;
406
+ /** Interpolates between two colors at `progress` 0..1, returning RGB. */
407
+ fade(from: string | number | RGB, to: string | number | RGB, progress: number): RGB;
408
+ /** Types `text` out over time with a blinking block cursor. */
409
+ typewriter(text: string, options?: TypewriterOptions): TypewriterState;
410
+ /** Deterministic time-bucketed flicker (fps-independent). */
411
+ flicker(intensity?: number, options?: {
412
+ id?: string;
413
+ interval?: number;
414
+ }): boolean;
415
+ /**
416
+ * Fetches async data without blocking the render loop: kicks off the
417
+ * fetcher (re-running every `interval` ms when set) and returns the
418
+ * latest { data, loading, error } snapshot each frame. Prefer the keyed
419
+ * form; the keyless form is positional.
420
+ * @example const { data, loading } = ctx.useAsync('stats', fetchStats, { interval: 5000 });
421
+ */
422
+ useAsync<T>(fetcher: () => Promise<T>, options?: {
423
+ interval?: number;
424
+ }): {
425
+ data: T | undefined;
426
+ loading: boolean;
427
+ error: Error | undefined;
428
+ };
429
+ useAsync<T>(key: string, fetcher: () => Promise<T>, options?: {
430
+ interval?: number;
431
+ }): {
432
+ data: T | undefined;
433
+ loading: boolean;
434
+ error: Error | undefined;
435
+ };
436
+ /**
437
+ * Stops the render loop and restores the terminal (the promise returned
438
+ * by render() then resolves). Also triggered by Ctrl+C.
439
+ * @example if (ctx.lastKey === 'q') ctx.requestStop();
440
+ */
441
+ requestStop(): void;
442
+ /** Flushes the pending flow to the buffer (called by render(); rare). */
443
+ flushFlow(): void;
444
+ /** Milliseconds since the previous frame, clamped to 100 (0 outside loop()). */
445
+ readonly dt: number;
446
+ /** Frame counter, incremented once per render tick (0 outside loop()). */
447
+ readonly frame: number;
448
+ /**
449
+ * Enter/exit progress keyed on a visibility flag. progress runs 0→1
450
+ * (eased) when `visible` turns on and 1→0 when it turns off; `mounted`
451
+ * stays true through the exit so callers keep rendering while animating
452
+ * out. THE primitive for modal/panel entrances and exits.
453
+ * @example const { progress, mounted } = ctx.transition('panel', open, { duration: 200 });
454
+ */
455
+ transition(id: string, visible: boolean, options?: {
456
+ duration?: number;
457
+ easing?: (t: number) => number;
458
+ exitDuration?: number;
459
+ }): {
460
+ progress: number;
461
+ mounted: boolean;
462
+ };
463
+ /**
464
+ * Cascading entrance progress: item `index` starts index*delay ms into
465
+ * the timeline and animates for `duration` ms. Pass `id` to drive it from
466
+ * an animate()-style clock (restartable via restartAnimation).
467
+ * @example rows.forEach((row, i) => draw(row, ctx.stagger(i, { delay: 60, duration: 240 })));
468
+ */
469
+ stagger(index: number, options: {
470
+ delay: number;
471
+ duration: number;
472
+ easing?: (t: number) => number;
473
+ id?: string;
474
+ }): number;
475
+ /** Resets an animate()/typewriter()/stagger() id clock to "now". */
476
+ restartAnimation(id: string): void;
477
+ }
478
+ /**
479
+ * The DSL state container allowing stable references with dynamic capture targets.
480
+ */
481
+ export interface DSLState {
482
+ /** Text-flow fragments accumulated for the active capture target. */
483
+ activeContents: string[];
484
+ /** Saved capture targets for nested box/span closures. */
485
+ stack: string[][];
486
+ /** Layers queued this frame, composited by flushFlow. */
487
+ layers: RenderLayer[];
488
+ /** Monotonic tiebreaker so equal z-indexes keep declaration order. */
489
+ layerOrder: number;
490
+ /** Stack of subtree theme overrides pushed by ctx.themed(). */
491
+ themeStack: Theme[];
492
+ /** Direct-rendered box areas this frame (root only; dev diagnostics). */
493
+ boxRects?: Rect[];
494
+ }
495
+ /** One queued overlay buffer awaiting composite (see ctx.layer()). */
496
+ export interface RenderLayer {
497
+ /** Composite order: higher paints later (on top). */
498
+ zIndex: number;
499
+ /** Declaration-order tiebreaker for equal z-indexes. */
500
+ order: number;
501
+ /** The layer's transparent cell buffer. */
502
+ buffer: Cell[];
503
+ /** Composite-time drop shadow under the painted bounds. */
504
+ shadow?: boolean;
505
+ /** Composite-time whole-screen dim (0..1) below this layer. */
506
+ backdrop?: number;
507
+ /** Tight bounds of the layer's painted cells (null when empty). */
508
+ bounds: Rect | null;
509
+ }
510
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dsl/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Bunti DSL shared types and constants.
3
+ */
4
+ /**
5
+ * Normalized key-name constants for `ctx.lastKey` / `ctx.keyPressed()`.
6
+ * Printable keys are their literal character ('a', 'A', ' '); mouse events
7
+ * arrive as the 'click' / 'wheel_up' / 'wheel_down' pseudo-keys.
8
+ * @example if (ctx.keyPressed(KEYS.ENTER)) submit();
9
+ */
10
+ export const KEYS = {
11
+ UP: 'up',
12
+ DOWN: 'down',
13
+ RIGHT: 'right',
14
+ LEFT: 'left',
15
+ ENTER: 'enter',
16
+ ESCAPE: 'escape',
17
+ TAB: 'tab',
18
+ BACKSPACE: 'backspace',
19
+ SPACE: ' ',
20
+ HOME: 'home',
21
+ END: 'end',
22
+ DELETE: 'delete',
23
+ PAGE_UP: 'pageup',
24
+ PAGE_DOWN: 'pagedown',
25
+ INSERT: 'insert',
26
+ /** Left-button click (emitted once, on release; requires `mouse: true`). */
27
+ CLICK: 'click',
28
+ /** Mouse wheel scrolled up (requires `mouse: true`). */
29
+ WHEEL_UP: 'wheel_up',
30
+ /** Mouse wheel scrolled down (requires `mouse: true`). */
31
+ WHEEL_DOWN: 'wheel_down',
32
+ };
33
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/dsl/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,KAAK;IACV,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,GAAG;IACV,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,QAAQ;IACjB,SAAS,EAAE,UAAU;IACrB,MAAM,EAAE,QAAQ;IAChB,4EAA4E;IAC5E,KAAK,EAAE,OAAO;IACd,wDAAwD;IACxD,QAAQ,EAAE,UAAU;IACpB,0DAA0D;IAC1D,UAAU,EAAE,YAAY;CACzB,CAAC"}
package/dist/dsl.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Bunti High-Level Contextual DSL
3
+ * Scoped closure API with contextual capabilities via trait-based composition.
4
+ *
5
+ * Implementation lives in src/dsl/ — this barrel preserves the public surface:
6
+ * - context: createDSLContext + box rendering + createScreenContext
7
+ * - render: the render() entry point
8
+ * - hooks: useState / useAsync / usePersistentState
9
+ * - interaction: hitbox / hover / press / click + focus management
10
+ * - layers: transparent buffers + compositing
11
+ * - motion: animate / typewriter / flicker / fade
12
+ * - types: shared interfaces + KEYS
13
+ */
14
+ export { createScreenContext } from './dsl/context';
15
+ export { render } from './dsl/render';
16
+ export type { BuntiContext, DSLBoxOptions, LayerOptions, TypewriterOptions, TypewriterState, } from './dsl/types';
17
+ export { KEYS } from './dsl/types';
18
+ //# sourceMappingURL=dsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsl.d.ts","sourceRoot":"","sources":["../src/dsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,YAAY,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC"}