linecraft 0.2.0 → 0.2.2

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 (110) hide show
  1. package/LICENSE +0 -1
  2. package/README.md +34 -8
  3. package/lib/component.d.ts +34 -0
  4. package/lib/component.d.ts.map +1 -0
  5. package/lib/component.js +42 -0
  6. package/lib/component.js.map +1 -0
  7. package/lib/components/code-debug.d.ts +35 -0
  8. package/lib/components/code-debug.d.ts.map +1 -0
  9. package/lib/components/code-debug.js +294 -0
  10. package/lib/components/code-debug.js.map +1 -0
  11. package/lib/components/fill.d.ts +15 -0
  12. package/lib/components/fill.d.ts.map +1 -0
  13. package/lib/components/fill.js +37 -0
  14. package/lib/components/fill.js.map +1 -0
  15. package/lib/components/index.d.ts +2 -2
  16. package/lib/components/index.d.ts.map +1 -1
  17. package/lib/components/index.js +2 -2
  18. package/lib/components/index.js.map +1 -1
  19. package/lib/components/progress-bar-grid.d.ts +1 -1
  20. package/lib/components/progress-bar-grid.d.ts.map +1 -1
  21. package/lib/components/progress-bar-grid.js +6 -6
  22. package/lib/components/progress-bar-grid.js.map +1 -1
  23. package/lib/components/prompt.d.ts +4 -5
  24. package/lib/components/prompt.d.ts.map +1 -1
  25. package/lib/components/prompt.js +17 -69
  26. package/lib/components/prompt.js.map +1 -1
  27. package/lib/components/section.d.ts +33 -0
  28. package/lib/components/section.d.ts.map +1 -0
  29. package/lib/components/section.js +178 -0
  30. package/lib/components/section.js.map +1 -0
  31. package/lib/components/segments.d.ts +26 -0
  32. package/lib/components/segments.d.ts.map +1 -0
  33. package/lib/components/segments.js +105 -0
  34. package/lib/components/segments.js.map +1 -0
  35. package/lib/components/spinner.d.ts +18 -16
  36. package/lib/components/spinner.d.ts.map +1 -1
  37. package/lib/components/spinner.js +63 -47
  38. package/lib/components/spinner.js.map +1 -1
  39. package/lib/components/style.test.js +11 -11
  40. package/lib/components/style.test.js.map +1 -1
  41. package/lib/components/styled.d.ts +17 -0
  42. package/lib/components/styled.d.ts.map +1 -0
  43. package/lib/components/styled.js +107 -0
  44. package/lib/components/styled.js.map +1 -0
  45. package/lib/components/styled.test.d.ts +2 -0
  46. package/lib/components/styled.test.d.ts.map +1 -0
  47. package/lib/components/styled.test.js +135 -0
  48. package/lib/components/styled.test.js.map +1 -0
  49. package/lib/index.d.ts +17 -13
  50. package/lib/index.d.ts.map +1 -1
  51. package/lib/index.js +13 -13
  52. package/lib/index.js.map +1 -1
  53. package/lib/index.test.js +17 -11
  54. package/lib/index.test.js.map +1 -1
  55. package/lib/layout/grid.d.ts +31 -35
  56. package/lib/layout/grid.d.ts.map +1 -1
  57. package/lib/layout/grid.js +437 -216
  58. package/lib/layout/grid.js.map +1 -1
  59. package/lib/layout/grid.test.js +332 -36
  60. package/lib/layout/grid.test.js.map +1 -1
  61. package/lib/native/ansi.d.ts +9 -0
  62. package/lib/native/ansi.d.ts.map +1 -1
  63. package/lib/native/ansi.js +9 -0
  64. package/lib/native/ansi.js.map +1 -1
  65. package/lib/native/diff.d.ts +5 -1
  66. package/lib/native/diff.d.ts.map +1 -1
  67. package/lib/native/diff.js +25 -7
  68. package/lib/native/diff.js.map +1 -1
  69. package/lib/native/region-renderer-debug.test.d.ts +2 -0
  70. package/lib/native/region-renderer-debug.test.d.ts.map +1 -0
  71. package/lib/native/region-renderer-debug.test.js +45 -0
  72. package/lib/native/region-renderer-debug.test.js.map +1 -0
  73. package/lib/native/region-renderer.d.ts +57 -148
  74. package/lib/native/region-renderer.d.ts.map +1 -1
  75. package/lib/native/region-renderer.js +455 -1124
  76. package/lib/native/region-renderer.js.map +1 -1
  77. package/lib/native/region.test.js +2 -20
  78. package/lib/native/region.test.js.map +1 -1
  79. package/lib/region-resize.test.d.ts +2 -0
  80. package/lib/region-resize.test.d.ts.map +1 -0
  81. package/lib/region-resize.test.js +124 -0
  82. package/lib/region-resize.test.js.map +1 -0
  83. package/lib/region.d.ts +97 -9
  84. package/lib/region.d.ts.map +1 -1
  85. package/lib/region.js +591 -185
  86. package/lib/region.js.map +1 -1
  87. package/lib/region.test.js +3 -3
  88. package/lib/region.test.js.map +1 -1
  89. package/lib/types.d.ts +9 -0
  90. package/lib/types.d.ts.map +1 -1
  91. package/lib/utils/file-link.d.ts +16 -0
  92. package/lib/utils/file-link.d.ts.map +1 -0
  93. package/lib/utils/file-link.js +23 -0
  94. package/lib/utils/file-link.js.map +1 -0
  95. package/lib/utils/prompt.d.ts +15 -0
  96. package/lib/utils/prompt.d.ts.map +1 -0
  97. package/lib/utils/prompt.js +128 -0
  98. package/lib/utils/prompt.js.map +1 -0
  99. package/lib/utils/terminal-theme.d.ts +36 -0
  100. package/lib/utils/terminal-theme.d.ts.map +1 -0
  101. package/lib/utils/terminal-theme.js +61 -0
  102. package/lib/utils/terminal-theme.js.map +1 -0
  103. package/lib/utils/text.d.ts +53 -3
  104. package/lib/utils/text.d.ts.map +1 -1
  105. package/lib/utils/text.js +194 -36
  106. package/lib/utils/text.js.map +1 -1
  107. package/lib/utils/wait-for-spacebar.d.ts.map +1 -1
  108. package/lib/utils/wait-for-spacebar.js +9 -6
  109. package/lib/utils/wait-for-spacebar.js.map +1 -1
  110. package/package.json +17 -13
package/LICENSE CHANGED
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
-
package/README.md CHANGED
@@ -41,6 +41,30 @@ r.set(
41
41
  r.destroy(true);
42
42
  ```
43
43
 
44
+ ## Performance
45
+
46
+ Linecraft is built for high-performance terminal rendering from Node.js. The renderer includes several optimizations to minimize terminal updates and CPU usage:
47
+
48
+ ### Frame Diffing
49
+ Only updates lines that actually changed. Unchanged lines are skipped entirely, reducing terminal writes by up to 90% for static content.
50
+
51
+ ### Render Throttling
52
+ Uses high-resolution timing (`process.hrtime.bigint()`) to limit frame rate (default: 30 FPS). Prevents excessive rendering during rapid updates while maintaining smooth animations.
53
+
54
+ ### Batched ANSI Operations
55
+ All ANSI escape sequences are batched into a single `stdout.write()` call per frame, minimizing syscalls and improving throughput.
56
+
57
+ ### Efficient Cursor Movement
58
+ Optimized ANSI cursor positioning that only moves when necessary. The renderer tracks viewport state to avoid redundant cursor movements.
59
+
60
+ ### Viewport Management
61
+ Only renders visible lines within the terminal viewport. Content that extends beyond the viewport is efficiently managed without unnecessary rendering.
62
+
63
+ ### Auto-Wrap Disabled
64
+ Disables terminal auto-wrap to prevent unwanted line breaks, ensuring precise control over terminal output layout.
65
+
66
+ These optimizations make Linecraft suitable for real-time terminal UIs, progress displays, and animated components without overwhelming the terminal or consuming excessive CPU.
67
+
44
68
  ## Core API
45
69
 
46
70
  ### Region
@@ -103,7 +127,7 @@ r.set(Styled({
103
127
 
104
128
  Wrap content in a bordered box with an optional title.
105
129
 
106
- ![Section Example](docs/examples/section.gif)
130
+ ![Section Example](https://raw.githubusercontent.com/matthew-dean/linecraft/main/docs/examples/section.gif)
107
131
 
108
132
  ```typescript
109
133
  import { Section } from 'linecraft';
@@ -128,7 +152,7 @@ r.set(Section(
128
152
 
129
153
  Display code errors and warnings with line numbers, context, and clickable file paths.
130
154
 
131
- ![CodeDebug Example](docs/examples/code-debug.gif)
155
+ ![CodeDebug Example](https://raw.githubusercontent.com/matthew-dean/linecraft/main/docs/examples/code-debug.gif)
132
156
 
133
157
  ```typescript
134
158
  import { CodeDebug } from 'linecraft';
@@ -161,7 +185,7 @@ r.set(CodeDebug({
161
185
 
162
186
  Animated spinners for loading states. Includes built-in styles or use custom frames.
163
187
 
164
- ![Spinner Example](docs/examples/spinner.gif)
188
+ ![Spinner Example](https://raw.githubusercontent.com/matthew-dean/linecraft/main/docs/examples/spinner.gif)
165
189
 
166
190
  ```typescript
167
191
  import { Spinner } from 'linecraft';
@@ -194,7 +218,7 @@ Spinners automatically stop when components are replaced or the region is destro
194
218
 
195
219
  Progress bars with customizable colors and styling.
196
220
 
197
- ![ProgressBar Example](docs/examples/progressbar.gif)
221
+ ![ProgressBar Example](https://raw.githubusercontent.com/matthew-dean/linecraft/main/docs/examples/progressbar.gif)
198
222
 
199
223
  ```typescript
200
224
  import { progressBar } from 'linecraft';
@@ -219,7 +243,7 @@ r.set(progressBar({
219
243
 
220
244
  Create segmented displays (like oh-my-zsh style prompts).
221
245
 
222
- ![Segments Example](docs/examples/segments.gif)
246
+ ![Segments Example](https://raw.githubusercontent.com/matthew-dean/linecraft/main/docs/examples/segments.gif)
223
247
 
224
248
  ```typescript
225
249
  import { Segments } from 'linecraft';
@@ -242,7 +266,7 @@ r.set(Segments({
242
266
 
243
267
  Create responsive grid layouts. Children automatically wrap to new rows when they exceed the number of explicit columns.
244
268
 
245
- ![Grid Example](docs/examples/grid.gif)
269
+ ![Grid Example](https://raw.githubusercontent.com/matthew-dean/linecraft/main/docs/examples/grid.gif)
246
270
 
247
271
  ```typescript
248
272
  import { Grid } from 'linecraft';
@@ -285,7 +309,7 @@ r.set(Grid({
285
309
 
286
310
  Fill available space with a character. Typically used within grids.
287
311
 
288
- ![Fill Example](docs/examples/fill.gif)
312
+ ![Fill Example](https://raw.githubusercontent.com/matthew-dean/linecraft/main/docs/examples/fill.gif)
289
313
 
290
314
  ```typescript
291
315
  import { fill } from 'linecraft';
@@ -357,4 +381,6 @@ Contributions welcome! Please open an issue or PR.
357
381
 
358
382
  ## License
359
383
 
360
- MIT
384
+ This project is licensed under the **MIT License**.
385
+
386
+ See the full license text in [`LICENSE`](./LICENSE).
@@ -0,0 +1,34 @@
1
+ import type { TerminalRegion } from './region';
2
+ /**
3
+ * RenderContext provides information needed for rendering
4
+ */
5
+ export interface RenderContext {
6
+ availableWidth: number;
7
+ region: TerminalRegion;
8
+ columnIndex: number;
9
+ rowIndex: number;
10
+ onUpdate?: () => void;
11
+ onCleanup?: (callback: () => void) => void;
12
+ }
13
+ /**
14
+ * Component type: can be a function or an object with a render method
15
+ */
16
+ export type Component = ((ctx: RenderContext) => string | string[] | null) | {
17
+ render: (ctx: RenderContext) => string | string[] | null;
18
+ };
19
+ /**
20
+ * Helper to call a component (handles both function and object forms)
21
+ */
22
+ export declare function callComponent(component: Component, ctx: RenderContext): string | string[] | null;
23
+ /**
24
+ * Create a child RenderContext from a parent, with optional overrides
25
+ * This ensures all properties from the parent are passed through, including onUpdate
26
+ */
27
+ export declare function createChildContext(parent: RenderContext, overrides: Partial<RenderContext>): RenderContext;
28
+ /**
29
+ * Render children components and return flattened lines
30
+ * Handles null returns, array flattening, and rowIndex tracking automatically
31
+ * Inspired by React's children rendering pattern
32
+ */
33
+ export declare function renderChildren(children: Component[], ctx: RenderContext): string[];
34
+ //# sourceMappingURL=component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,CAAC,CAAC,GAAG,EAAE,aAAa,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,GAClD;IAAE,MAAM,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC;AAEjE;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAKhG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,GAChC,aAAa,CAKf;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,EAAE,EACrB,GAAG,EAAE,aAAa,GACjB,MAAM,EAAE,CAgBV"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Helper to call a component (handles both function and object forms)
3
+ */
4
+ export function callComponent(component, ctx) {
5
+ if (typeof component === 'function') {
6
+ return component(ctx);
7
+ }
8
+ return component.render(ctx);
9
+ }
10
+ /**
11
+ * Create a child RenderContext from a parent, with optional overrides
12
+ * This ensures all properties from the parent are passed through, including onUpdate
13
+ */
14
+ export function createChildContext(parent, overrides) {
15
+ return {
16
+ ...parent,
17
+ ...overrides,
18
+ };
19
+ }
20
+ /**
21
+ * Render children components and return flattened lines
22
+ * Handles null returns, array flattening, and rowIndex tracking automatically
23
+ * Inspired by React's children rendering pattern
24
+ */
25
+ export function renderChildren(children, ctx) {
26
+ const lines = [];
27
+ for (const child of children) {
28
+ const result = callComponent(child, createChildContext(ctx, {
29
+ rowIndex: lines.length,
30
+ }));
31
+ if (result === null)
32
+ continue;
33
+ if (Array.isArray(result)) {
34
+ lines.push(...result);
35
+ }
36
+ else {
37
+ lines.push(result);
38
+ }
39
+ }
40
+ return lines;
41
+ }
42
+ //# sourceMappingURL=component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAqBA;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,SAAoB,EAAE,GAAkB;IACpE,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAqB,EACrB,SAAiC;IAEjC,OAAO;QACL,GAAG,MAAM;QACT,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAqB,EACrB,GAAkB;IAElB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,kBAAkB,CAAC,GAAG,EAAE;YAC1D,QAAQ,EAAE,KAAK,CAAC,MAAM;SACvB,CAAC,CAAC,CAAC;QAEJ,IAAI,MAAM,KAAK,IAAI;YAAE,SAAS;QAE9B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { Component } from '../component';
2
+ export type CodeDebugType = 'error' | 'warning' | 'info';
3
+ export interface CodeDebugOptions {
4
+ /** Line number where error starts (1-based) */
5
+ startLine: number;
6
+ /** Column number where error starts (1-based) */
7
+ startColumn: number;
8
+ /** Line number where error ends (1-based, optional) */
9
+ endLine?: number;
10
+ /** Column number where error ends (1-based, optional) */
11
+ endColumn?: number;
12
+ /** Source code line before the error line (optional) */
13
+ lineBefore?: string | null;
14
+ /** Source code line with the error */
15
+ errorLine: string;
16
+ /** Source code line after the error line (optional) */
17
+ lineAfter?: string | null;
18
+ /** Error or warning message */
19
+ message: string;
20
+ /** Short file path to display */
21
+ filePath: string;
22
+ /** Full resolved file path for clickable link */
23
+ fullPath: string;
24
+ /** Base directory for relative paths (optional) */
25
+ baseDir?: string;
26
+ /** Type of error: error, warning, or info */
27
+ type?: CodeDebugType;
28
+ /** Maximum column to show before forcing ellipsis (to make room for message) */
29
+ maxColumn?: number;
30
+ }
31
+ /**
32
+ * CodeDebug component - displays code errors/warnings with context
33
+ */
34
+ export declare function CodeDebug(options: CodeDebugOptions): Component;
35
+ //# sourceMappingURL=code-debug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-debug.d.ts","sourceRoot":"","sources":["../../src/components/code-debug.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,cAAc,CAAC;AAS7D,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiID;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CA+O9D"}
@@ -0,0 +1,294 @@
1
+ // Code debug component for displaying code errors/warnings with context
2
+ import { callComponent } from '../component';
3
+ import { applyStyle } from '../utils/colors';
4
+ import { wrapText, stripAnsi, truncateToWidth } from '../utils/text';
5
+ import { fileLink } from '../utils/file-link';
6
+ import { Section } from './section';
7
+ import { getColoredLineNumberColor } from '../utils/terminal-theme';
8
+ function calculateVisibleRange(code, availableWidth, targetStartCol, targetEndCol, maxColumn) {
9
+ const plainCode = stripAnsi(code);
10
+ const codeLength = plainCode.length;
11
+ // If code fits, show everything
12
+ if (codeLength <= availableWidth) {
13
+ return {
14
+ startCol: 1,
15
+ endCol: codeLength,
16
+ hasEllipsisStart: false,
17
+ hasEllipsisEnd: false,
18
+ };
19
+ }
20
+ // If maxColumn is set, we need to ensure we don't show beyond it
21
+ const effectiveMaxCol = maxColumn ? Math.min(maxColumn, codeLength) : codeLength;
22
+ // Calculate how much space we need for the target columns
23
+ const targetWidth = targetEndCol
24
+ ? targetEndCol - targetStartCol + 1
25
+ : 1; // Just the arrow
26
+ // If target doesn't fit, we'll need to truncate
27
+ if (targetWidth > availableWidth - 6) { // -6 for ellipsis on both sides if needed
28
+ // Target is too wide, just show middle with ellipsis
29
+ const midPoint = Math.floor((availableWidth - 6) / 2);
30
+ const startCol = Math.max(1, targetStartCol - midPoint);
31
+ const endCol = Math.min(effectiveMaxCol, startCol + availableWidth - 6);
32
+ return {
33
+ startCol,
34
+ endCol,
35
+ hasEllipsisStart: startCol > 1,
36
+ hasEllipsisEnd: endCol < codeLength,
37
+ };
38
+ }
39
+ // Try to center the target in the available space
40
+ const padding = Math.floor((availableWidth - targetWidth) / 2);
41
+ let startCol = Math.max(1, targetStartCol - padding);
42
+ let endCol = Math.min(effectiveMaxCol, startCol + availableWidth - 1);
43
+ // Adjust if we hit boundaries
44
+ if (endCol - startCol + 1 > availableWidth) {
45
+ endCol = startCol + availableWidth - 1;
46
+ }
47
+ if (endCol > effectiveMaxCol) {
48
+ endCol = effectiveMaxCol;
49
+ startCol = Math.max(1, endCol - availableWidth + 1);
50
+ }
51
+ if (startCol < 1) {
52
+ startCol = 1;
53
+ endCol = Math.min(effectiveMaxCol, availableWidth);
54
+ }
55
+ // Check if we need ellipsis
56
+ const hasEllipsisStart = startCol > 1;
57
+ const hasEllipsisEnd = endCol < codeLength;
58
+ return {
59
+ startCol,
60
+ endCol,
61
+ hasEllipsisStart,
62
+ hasEllipsisEnd,
63
+ };
64
+ }
65
+ /**
66
+ * Truncate code line to show specific column range with ellipsis
67
+ */
68
+ function truncateCodeLine(code, visibleRange, availableWidth) {
69
+ const { startCol, endCol, hasEllipsisStart, hasEllipsisEnd } = visibleRange;
70
+ const plainCode = stripAnsi(code);
71
+ if (!hasEllipsisStart && !hasEllipsisEnd) {
72
+ // No truncation needed, but ensure it fits
73
+ return truncateToWidth(code, availableWidth);
74
+ }
75
+ // Extract the visible portion (1-based columns in plain text)
76
+ const visiblePlain = plainCode.substring(startCol - 1, endCol);
77
+ // Calculate available width for code (minus ellipsis)
78
+ const ellipsisWidth = (hasEllipsisStart ? 3 : 0) + (hasEllipsisEnd ? 3 : 0);
79
+ const codeWidth = availableWidth - ellipsisWidth;
80
+ // Truncate the visible portion if it's still too wide
81
+ let truncatedPlain = visiblePlain;
82
+ if (stripAnsi(visiblePlain).length > codeWidth) {
83
+ truncatedPlain = truncateToWidth(visiblePlain, codeWidth);
84
+ }
85
+ if (hasEllipsisStart && hasEllipsisEnd) {
86
+ // Truncate both ends - show middle portion
87
+ const midPoint = Math.floor(codeWidth / 2);
88
+ const startPart = truncateToWidth(truncatedPlain, midPoint);
89
+ const endPart = truncateToWidth(truncatedPlain.substring(stripAnsi(truncatedPlain).length - (codeWidth - midPoint)), codeWidth - midPoint);
90
+ return `...${startPart}...${endPart}...`;
91
+ }
92
+ else if (hasEllipsisStart) {
93
+ return `...${truncatedPlain}`;
94
+ }
95
+ else {
96
+ return `${truncatedPlain}...`;
97
+ }
98
+ }
99
+ /**
100
+ * CodeDebug component - displays code errors/warnings with context
101
+ */
102
+ export function CodeDebug(options) {
103
+ return (ctx) => {
104
+ const { startLine, startColumn, endLine, endColumn, lineBefore, errorLine, lineAfter, message, filePath, fullPath, baseDir, type = 'error', maxColumn, } = options;
105
+ const availableWidth = ctx.availableWidth;
106
+ // Color scheme based on type
107
+ const colors = {
108
+ error: { primary: 'red', secondary: 'brightRed', message: 'brightRed' },
109
+ warning: { primary: 'yellow', secondary: 'brightYellow', message: 'brightYellow' },
110
+ info: { primary: 'cyan', secondary: 'brightCyan', message: 'brightCyan' },
111
+ };
112
+ const colorScheme = colors[type];
113
+ // Get appropriate line number color based on terminal theme
114
+ const lineNumberColor = getColoredLineNumberColor(); // For line numbers (colored)
115
+ // Calculate available width for code (reserve space for line numbers, separator, and spaces)
116
+ // Calculate the maximum width needed for any line number that will be displayed
117
+ const lineNumbersToCheck = [startLine];
118
+ if (lineBefore !== null && lineBefore !== undefined) {
119
+ lineNumbersToCheck.push(startLine - 1);
120
+ }
121
+ if (lineAfter !== null && lineAfter !== undefined) {
122
+ lineNumbersToCheck.push(startLine + 1);
123
+ }
124
+ const lineNumWidth = Math.max(...lineNumbersToCheck.map(n => String(n).length));
125
+ const codeAreaWidth = availableWidth - lineNumWidth - 2; // -2 for " " (2 spaces)
126
+ // Calculate visible range for error line
127
+ const targetEndCol = endColumn ?? startColumn;
128
+ const plainErrorLine = stripAnsi(errorLine);
129
+ const effectiveMaxCol = maxColumn ? Math.min(maxColumn, plainErrorLine.length) : plainErrorLine.length;
130
+ const visibleRange = calculateVisibleRange(errorLine, codeAreaWidth, startColumn, targetEndCol, effectiveMaxCol);
131
+ // Truncate error line
132
+ const truncatedErrorLine = truncateCodeLine(errorLine, visibleRange, codeAreaWidth);
133
+ // Calculate arrow/underline position relative to the truncated error line display
134
+ // Map original column positions to display positions
135
+ const truncatedPlain = stripAnsi(truncatedErrorLine);
136
+ // Helper to map original column to display position
137
+ const mapColumnToDisplay = (originalCol) => {
138
+ if (visibleRange.hasEllipsisStart && visibleRange.hasEllipsisEnd) {
139
+ // Format: "...start...end..."
140
+ // Visible range is in the middle
141
+ if (originalCol < visibleRange.startCol) {
142
+ return 1; // Before visible, point to start
143
+ }
144
+ else if (originalCol > visibleRange.endCol) {
145
+ return truncatedPlain.length; // After visible, point to end
146
+ }
147
+ else {
148
+ // In visible range: position = 4 (for "...") + (col - startCol + 1)
149
+ return 4 + (originalCol - visibleRange.startCol);
150
+ }
151
+ }
152
+ else if (visibleRange.hasEllipsisStart) {
153
+ // Format: "...code"
154
+ if (originalCol < visibleRange.startCol) {
155
+ return 1;
156
+ }
157
+ else {
158
+ return 4 + (originalCol - visibleRange.startCol);
159
+ }
160
+ }
161
+ else if (visibleRange.hasEllipsisEnd) {
162
+ // Format: "code..."
163
+ if (originalCol > visibleRange.endCol) {
164
+ return truncatedPlain.length;
165
+ }
166
+ else {
167
+ return originalCol;
168
+ }
169
+ }
170
+ else {
171
+ // No ellipsis, direct mapping
172
+ return originalCol;
173
+ }
174
+ };
175
+ const arrowCol = mapColumnToDisplay(startColumn);
176
+ let underlineStartCol = arrowCol;
177
+ let underlineEndCol = arrowCol;
178
+ if (endColumn) {
179
+ underlineStartCol = mapColumnToDisplay(startColumn);
180
+ underlineEndCol = mapColumnToDisplay(endColumn);
181
+ // Ensure valid range
182
+ if (underlineEndCol < underlineStartCol) {
183
+ underlineEndCol = underlineStartCol;
184
+ }
185
+ }
186
+ // Build the code block lines (will be wrapped in Section)
187
+ const codeLines = [];
188
+ // Title line: "Error in {filename}" or type-specific title
189
+ const pathText = baseDir && filePath.startsWith(baseDir)
190
+ ? filePath.substring(baseDir.length + 1)
191
+ : filePath;
192
+ const errorTypeTitle = type === 'error' ? 'Error' : type === 'warning' ? 'Warning' : 'Info';
193
+ const titleLine = applyStyle(`${errorTypeTitle} in ${pathText}`, { color: colorScheme.secondary, bold: true });
194
+ codeLines.push(titleLine);
195
+ // Line before (if exists)
196
+ if (lineBefore !== null && lineBefore !== undefined) {
197
+ const beforeLineNum = String(startLine - 1);
198
+ const beforeLineNumPadded = beforeLineNum.padStart(lineNumWidth);
199
+ const truncatedBefore = truncateToWidth(lineBefore, codeAreaWidth);
200
+ codeLines.push(applyStyle(`${beforeLineNumPadded} `, { color: lineNumberColor }) +
201
+ truncatedBefore);
202
+ }
203
+ // Error line
204
+ const errorLineNum = String(startLine);
205
+ const errorLineNumPadded = errorLineNum.padStart(lineNumWidth);
206
+ let errorLineDisplay = applyStyle(`${errorLineNumPadded} `, { color: lineNumberColor }) +
207
+ truncatedErrorLine;
208
+ codeLines.push(errorLineDisplay);
209
+ // Arrow/underline line
210
+ let indicatorLine = ' '.repeat(lineNumWidth) + ' ';
211
+ indicatorLine += ' '.repeat(Math.max(0, arrowCol - 1));
212
+ // Calculate where the connecting line should come down from (middle of underline or arrow position)
213
+ const connectCol = endColumn && underlineEndCol > underlineStartCol
214
+ ? Math.floor((underlineStartCol + underlineEndCol) / 2) // Middle of underline
215
+ : arrowCol; // Position of arrow
216
+ if (endColumn && underlineEndCol > underlineStartCol) {
217
+ // Underline with curved edges facing up and T-bar in the middle: ╰──┬──╯
218
+ const underlineLength = underlineEndCol - underlineStartCol;
219
+ const connectPosInUnderline = connectCol - underlineStartCol; // Position within the underline
220
+ if (underlineLength >= 3) {
221
+ // Build underline with T-bar: left curve, dashes, T-bar, dashes, right curve
222
+ const leftPart = '─'.repeat(Math.max(0, connectPosInUnderline - 1));
223
+ const rightPart = '─'.repeat(Math.max(0, underlineLength - connectPosInUnderline - 1));
224
+ indicatorLine += applyStyle('┖' + leftPart + '┬' + rightPart + '┚', { color: colorScheme.primary });
225
+ }
226
+ else if (underlineLength === 2) {
227
+ // Too short for T-bar, just use T in middle
228
+ indicatorLine += applyStyle('┖┬┚', { color: colorScheme.primary });
229
+ }
230
+ else {
231
+ // Single character, just use T
232
+ indicatorLine += applyStyle('╿', { color: colorScheme.primary });
233
+ }
234
+ }
235
+ else {
236
+ // Single point - use ┬ (T pointing up) which has horizontal bar pointing to code, vertical line going down
237
+ indicatorLine += applyStyle('╿', { color: colorScheme.primary });
238
+ }
239
+ codeLines.push(indicatorLine);
240
+ // Horizontal line to message (directly from T-bar or ┴, no extra vertical line)
241
+ const horizontalLine = ' '.repeat(lineNumWidth) + ' ';
242
+ const horizontalSpaces = ' '.repeat(Math.max(0, connectCol - 1));
243
+ const horizontalBar = applyStyle('└', { color: colorScheme.primary });
244
+ const horizontalDash = applyStyle('─ ', { color: colorScheme.primary });
245
+ const messageStart = horizontalLine + horizontalSpaces + horizontalBar + horizontalDash;
246
+ // Message lines
247
+ const messageWidth = availableWidth - stripAnsi(messageStart).length;
248
+ const messageLines = wrapText(message, messageWidth);
249
+ // First message line with connecting line
250
+ if (messageLines.length > 0) {
251
+ codeLines.push(messageStart +
252
+ applyStyle(messageLines[0], { color: colorScheme.message }));
253
+ // Remaining message lines (indented to start of first line)
254
+ const messageIndent = ' '.repeat(stripAnsi(messageStart).length);
255
+ for (let i = 1; i < messageLines.length; i++) {
256
+ codeLines.push(messageIndent + applyStyle(messageLines[i], { color: colorScheme.message }));
257
+ }
258
+ }
259
+ // Line after (if exists) - comes after the message
260
+ if (lineAfter !== null && lineAfter !== undefined) {
261
+ // Add empty line after message (within section)
262
+ codeLines.push('');
263
+ const afterLineNum = String(startLine + 1);
264
+ const afterLineNumPadded = afterLineNum.padStart(lineNumWidth);
265
+ const truncatedAfter = truncateToWidth(lineAfter, codeAreaWidth);
266
+ codeLines.push(applyStyle(`${afterLineNumPadded} `, { color: lineNumberColor }) +
267
+ truncatedAfter);
268
+ // Add another empty line after line after (within section)
269
+ codeLines.push('');
270
+ }
271
+ // Wrap in Section with left border only, no padding
272
+ const filePathDisplay = (() => {
273
+ const pathText = baseDir && filePath.startsWith(baseDir)
274
+ ? filePath.substring(baseDir.length + 1)
275
+ : filePath;
276
+ const pathWithLink = fileLink(fullPath, pathText);
277
+ const lineNumText = `:${startLine}${endLine && endLine !== startLine ? `:${endLine}` : ''}`;
278
+ return pathWithLink + lineNumText;
279
+ })();
280
+ // Use Section to wrap the code block with left border
281
+ const sectionComponent = Section({
282
+ title: filePathDisplay,
283
+ titleColor: colorScheme.secondary,
284
+ left: true,
285
+ right: false,
286
+ top: false,
287
+ bottom: false,
288
+ padding: 0,
289
+ borderColor: colorScheme.primary,
290
+ }, (ctx) => codeLines);
291
+ return callComponent(sectionComponent, ctx);
292
+ };
293
+ }
294
+ //# sourceMappingURL=code-debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-debug.js","sourceRoot":"","sources":["../../src/components/code-debug.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAGxE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAA8B,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAsB,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AA2CxF,SAAS,qBAAqB,CAC5B,IAAY,EACZ,cAAsB,EACtB,cAAsB,EACtB,YAAgC,EAChC,SAAkB;IAElB,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC;IAEpC,gCAAgC;IAChC,IAAI,UAAU,IAAI,cAAc,EAAE,CAAC;QACjC,OAAO;YACL,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,UAAU;YAClB,gBAAgB,EAAE,KAAK;YACvB,cAAc,EAAE,KAAK;SACtB,CAAC;IACJ,CAAC;IAED,iEAAiE;IACjE,MAAM,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAEjF,0DAA0D;IAC1D,MAAM,WAAW,GAAG,YAAY;QAC9B,CAAC,CAAC,YAAY,GAAG,cAAc,GAAG,CAAC;QACnC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB;IAExB,gDAAgD;IAChD,IAAI,WAAW,GAAG,cAAc,GAAG,CAAC,EAAE,CAAC,CAAC,0CAA0C;QAChF,qDAAqD;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,QAAQ,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC;QACxE,OAAO;YACL,QAAQ;YACR,MAAM;YACN,gBAAgB,EAAE,QAAQ,GAAG,CAAC;YAC9B,cAAc,EAAE,MAAM,GAAG,UAAU;SACpC,CAAC;IACJ,CAAC;IAED,kDAAkD;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC;IACrD,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,QAAQ,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC;IAEtE,8BAA8B;IAC9B,IAAI,MAAM,GAAG,QAAQ,GAAG,CAAC,GAAG,cAAc,EAAE,CAAC;QAC3C,MAAM,GAAG,QAAQ,GAAG,cAAc,GAAG,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,MAAM,GAAG,eAAe,EAAE,CAAC;QAC7B,MAAM,GAAG,eAAe,CAAC;QACzB,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,QAAQ,GAAG,CAAC,CAAC;QACb,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IACrD,CAAC;IAED,4BAA4B;IAC5B,MAAM,gBAAgB,GAAG,QAAQ,GAAG,CAAC,CAAC;IACtC,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,CAAC;IAE3C,OAAO;QACL,QAAQ;QACR,MAAM;QACN,gBAAgB;QAChB,cAAc;KACf,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,IAAY,EACZ,YAA0B,EAC1B,cAAsB;IAEtB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,cAAc,EAAE,GAAG,YAAY,CAAC;IAC5E,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAElC,IAAI,CAAC,gBAAgB,IAAI,CAAC,cAAc,EAAE,CAAC;QACzC,2CAA2C;QAC3C,OAAO,eAAe,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAC/C,CAAC;IAED,8DAA8D;IAC9D,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAE/D,sDAAsD;IACtD,MAAM,aAAa,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,SAAS,GAAG,cAAc,GAAG,aAAa,CAAC;IAEjD,sDAAsD;IACtD,IAAI,cAAc,GAAG,YAAY,CAAC;IAClC,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QAC/C,cAAc,GAAG,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,gBAAgB,IAAI,cAAc,EAAE,CAAC;QACvC,2CAA2C;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,eAAe,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,eAAe,CAC7B,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,EACnF,SAAS,GAAG,QAAQ,CACrB,CAAC;QACF,OAAO,MAAM,SAAS,MAAM,OAAO,KAAK,CAAC;IAC3C,CAAC;SAAM,IAAI,gBAAgB,EAAE,CAAC;QAC5B,OAAO,MAAM,cAAc,EAAE,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,cAAc,KAAK,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAyB;IACjD,OAAO,CAAC,GAAkB,EAAE,EAAE;QAC5B,MAAM,EACJ,SAAS,EACT,WAAW,EACX,OAAO,EACP,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,IAAI,GAAG,OAAO,EACd,SAAS,GACV,GAAG,OAAO,CAAC;QAEZ,MAAM,cAAc,GAAG,GAAG,CAAC,cAAc,CAAC;QAE1C,6BAA6B;QAC7B,MAAM,MAAM,GAAgF;YAC1F,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE;YACvE,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE;YAClF,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE;SAC1E,CAAC;QACF,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAEjC,4DAA4D;QAC5D,MAAM,eAAe,GAAG,yBAAyB,EAAE,CAAC,CAAC,6BAA6B;QAElF,6FAA6F;QAC7F,gFAAgF;QAChF,MAAM,kBAAkB,GAAa,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YACpD,kBAAkB,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAClD,kBAAkB,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAChF,MAAM,aAAa,GAAG,cAAc,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,yBAAyB;QAElF,yCAAyC;QACzC,MAAM,YAAY,GAAG,SAAS,IAAI,WAAW,CAAC;QAC9C,MAAM,cAAc,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC;QACvG,MAAM,YAAY,GAAG,qBAAqB,CACxC,SAAS,EACT,aAAa,EACb,WAAW,EACX,YAAY,EACZ,eAAe,CAChB,CAAC;QAEF,sBAAsB;QACtB,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,SAAS,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QAEpF,kFAAkF;QAClF,qDAAqD;QACrD,MAAM,cAAc,GAAG,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAErD,oDAAoD;QACpD,MAAM,kBAAkB,GAAG,CAAC,WAAmB,EAAU,EAAE;YACzD,IAAI,YAAY,CAAC,gBAAgB,IAAI,YAAY,CAAC,cAAc,EAAE,CAAC;gBACjE,8BAA8B;gBAC9B,iCAAiC;gBACjC,IAAI,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;oBACxC,OAAO,CAAC,CAAC,CAAC,iCAAiC;gBAC7C,CAAC;qBAAM,IAAI,WAAW,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;oBAC7C,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,8BAA8B;gBAC9D,CAAC;qBAAM,CAAC;oBACN,oEAAoE;oBACpE,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;iBAAM,IAAI,YAAY,CAAC,gBAAgB,EAAE,CAAC;gBACzC,oBAAoB;gBACpB,IAAI,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;oBACxC,OAAO,CAAC,CAAC;gBACX,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;iBAAM,IAAI,YAAY,CAAC,cAAc,EAAE,CAAC;gBACvC,oBAAoB;gBACpB,IAAI,WAAW,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;oBACtC,OAAO,cAAc,CAAC,MAAM,CAAC;gBAC/B,CAAC;qBAAM,CAAC;oBACN,OAAO,WAAW,CAAC;gBACrB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,8BAA8B;gBAC9B,OAAO,WAAW,CAAC;YACrB,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,iBAAiB,GAAG,QAAQ,CAAC;QACjC,IAAI,eAAe,GAAG,QAAQ,CAAC;QAE/B,IAAI,SAAS,EAAE,CAAC;YACd,iBAAiB,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;YACpD,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;YAChD,qBAAqB;YACrB,IAAI,eAAe,GAAG,iBAAiB,EAAE,CAAC;gBACxC,eAAe,GAAG,iBAAiB,CAAC;YACtC,CAAC;QACH,CAAC;QAED,0DAA0D;QAC1D,MAAM,SAAS,GAAa,EAAE,CAAC;QAE/B,2DAA2D;QAC3D,MAAM,QAAQ,GAAG,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;YACtD,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACxC,CAAC,CAAC,QAAQ,CAAC;QACb,MAAM,cAAc,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5F,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,cAAc,OAAO,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/G,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE1B,0BAA0B;QAC1B,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YACpD,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YAC5C,MAAM,mBAAmB,GAAG,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACjE,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;YACnE,SAAS,CAAC,IAAI,CACZ,UAAU,CAAC,GAAG,mBAAmB,IAAI,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;gBAClE,eAAe,CAChB,CAAC;QACJ,CAAC;QAED,aAAa;QACb,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,kBAAkB,GAAG,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC/D,IAAI,gBAAgB,GAAG,UAAU,CAAC,GAAG,kBAAkB,IAAI,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;YACtF,kBAAkB,CAAC;QACrB,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAEjC,uBAAuB;QACvB,IAAI,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;QACpD,aAAa,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;QAEvD,oGAAoG;QACpG,MAAM,UAAU,GAAG,SAAS,IAAI,eAAe,GAAG,iBAAiB;YACjE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,iBAAiB,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,sBAAsB;YAC9E,CAAC,CAAC,QAAQ,CAAC,CAAC,oBAAoB;QAElC,IAAI,SAAS,IAAI,eAAe,GAAG,iBAAiB,EAAE,CAAC;YACrD,yEAAyE;YACzE,MAAM,eAAe,GAAG,eAAe,GAAG,iBAAiB,CAAC;YAC5D,MAAM,qBAAqB,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAAC,gCAAgC;YAE9F,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;gBACzB,6EAA6E;gBAC7E,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,qBAAqB,GAAG,CAAC,CAAC,CAAC,CAAC;gBACpE,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,eAAe,GAAG,qBAAqB,GAAG,CAAC,CAAC,CAAC,CAAC;gBACvF,aAAa,IAAI,UAAU,CAAC,GAAG,GAAG,QAAQ,GAAG,GAAG,GAAG,SAAS,GAAG,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YACtG,CAAC;iBAAM,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;gBACjC,4CAA4C;gBAC5C,aAAa,IAAI,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,+BAA+B;gBAC/B,aAAa,IAAI,UAAU,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,2GAA2G;YAC3G,aAAa,IAAI,UAAU,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE9B,gFAAgF;QAChF,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;QACvD,MAAM,gBAAgB,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,MAAM,YAAY,GAAG,cAAc,GAAG,gBAAgB,GAAG,aAAa,GAAG,cAAc,CAAC;QAExF,gBAAgB;QAChB,MAAM,YAAY,GAAG,cAAc,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;QACrE,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAErD,0CAA0C;QAC1C,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,SAAS,CAAC,IAAI,CACZ,YAAY;gBACZ,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAC5D,CAAC;YAEF,4DAA4D;YAC5D,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;YACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,SAAS,CAAC,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC;QAED,mDAAmD;QACnD,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAClD,gDAAgD;YAChD,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEnB,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YAC3C,MAAM,kBAAkB,GAAG,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC/D,MAAM,cAAc,GAAG,eAAe,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;YACjE,SAAS,CAAC,IAAI,CACZ,UAAU,CAAC,GAAG,kBAAkB,IAAI,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;gBACjE,cAAc,CACf,CAAC;YAEF,2DAA2D;YAC3D,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;QAED,oDAAoD;QACpD,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE;YAC5B,MAAM,QAAQ,GAAG,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;gBACtD,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;gBACxC,CAAC,CAAC,QAAQ,CAAC;YACb,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAClD,MAAM,WAAW,GAAG,IAAI,SAAS,GAAG,OAAO,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC5F,OAAO,YAAY,GAAG,WAAW,CAAC;QACpC,CAAC,CAAC,EAAE,CAAC;QAEL,sDAAsD;QACtD,MAAM,gBAAgB,GAAG,OAAO,CAC9B;YACE,KAAK,EAAE,eAAe;YACtB,UAAU,EAAE,WAAW,CAAC,SAAS;YACjC,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,KAAK;YACV,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,CAAC;YACV,WAAW,EAAE,WAAW,CAAC,OAAO;SACjC,EACD,CAAC,GAAkB,EAAE,EAAE,CAAC,SAAS,CAClC,CAAC;QAEF,OAAO,aAAa,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Component } from '../component';
2
+ import type { Color, FillChar } from '../types';
3
+ export interface FillOptions {
4
+ backgroundColor?: Color;
5
+ }
6
+ /**
7
+ * Fill component - fills the available width with a repeated character
8
+ *
9
+ * Usage:
10
+ * fill('─') // Simple character
11
+ * fill({ char: '─', color: 'red' }) // Character with color
12
+ * fill('─', { backgroundColor: 'blue' }) // Character with additional options
13
+ */
14
+ export declare function fill(fillChar?: FillChar, options?: FillOptions): Component;
15
+ //# sourceMappingURL=fill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill.d.ts","sourceRoot":"","sources":["../../src/components/fill.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGhD,MAAM,WAAW,WAAW;IAC1B,eAAe,CAAC,EAAE,KAAK,CAAC;CACzB;AAYD;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAClB,QAAQ,GAAE,QAAc,EACxB,OAAO,GAAE,WAAgB,GACxB,SAAS,CAmBX"}
@@ -0,0 +1,37 @@
1
+ // Fill component - fills available width with a character
2
+ import { applyStyle } from '../utils/colors';
3
+ /**
4
+ * Normalize FillChar to { char, color } format
5
+ */
6
+ function normalizeFillChar(fillChar) {
7
+ if (typeof fillChar === 'string') {
8
+ return { char: fillChar };
9
+ }
10
+ return fillChar;
11
+ }
12
+ /**
13
+ * Fill component - fills the available width with a repeated character
14
+ *
15
+ * Usage:
16
+ * fill('─') // Simple character
17
+ * fill({ char: '─', color: 'red' }) // Character with color
18
+ * fill('─', { backgroundColor: 'blue' }) // Character with additional options
19
+ */
20
+ export function fill(fillChar = ' ', options = {}) {
21
+ return (ctx) => {
22
+ const { char, color } = normalizeFillChar(fillChar);
23
+ const availableWidth = ctx.availableWidth;
24
+ // During auto column measurement, availableWidth might be Infinity
25
+ // Fill components have no intrinsic width - they fill available space
26
+ // So during measurement, return empty string (0 width contribution)
27
+ if (!Number.isFinite(availableWidth) || availableWidth <= 0) {
28
+ return '';
29
+ }
30
+ const fillText = char.repeat(availableWidth);
31
+ return applyStyle(fillText, {
32
+ color,
33
+ backgroundColor: options.backgroundColor,
34
+ });
35
+ };
36
+ }
37
+ //# sourceMappingURL=fill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill.js","sourceRoot":"","sources":["../../src/components/fill.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAI1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAM7C;;GAEG;AACH,SAAS,iBAAiB,CAAC,QAAkB;IAC3C,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAClB,WAAqB,GAAG,EACxB,UAAuB,EAAE;IAEzB,OAAO,CAAC,GAAkB,EAAE,EAAE;QAC5B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,cAAc,GAAG,GAAG,CAAC,cAAc,CAAC;QAE1C,mEAAmE;QACnE,sEAAsE;QACtE,oEAAoE;QACpE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;YAC5D,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAE7C,OAAO,UAAU,CAAC,QAAQ,EAAE;YAC1B,KAAK;YACL,eAAe,EAAE,OAAO,CAAC,eAAe;SACzC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -1,3 +1,3 @@
1
- export { Spinner } from './spinner';
2
- export { showPrompt } from './prompt';
1
+ export { Prompt, type PromptOptions } from './prompt';
2
+ export { Section, type SectionOptions } from './section';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC"}
@@ -1,5 +1,5 @@
1
1
  // Component helpers and utilities
2
2
  // Re-export component classes and functions
3
- export { Spinner } from './spinner';
4
- export { showPrompt } from './prompt';
3
+ export { Prompt } from './prompt';
4
+ export { Section } from './section';
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,4CAA4C;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,4CAA4C;AAC5C,OAAO,EAAE,MAAM,EAAsB,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,OAAO,EAAuB,MAAM,WAAW,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { Component } from '../layout/grid';
1
+ import type { Component } from '../component';
2
2
  import type { Color } from '../types';
3
3
  export interface ProgressBarOptions {
4
4
  current: number;