@jrichman/ink 6.3.1 → 6.4.1

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 (53) hide show
  1. package/build/components/Box.d.ts +26 -2
  2. package/build/components/Box.js +8 -3
  3. package/build/components/Box.js.map +1 -1
  4. package/build/data-limited-lru-map.d.ts +19 -0
  5. package/build/data-limited-lru-map.js +51 -0
  6. package/build/data-limited-lru-map.js.map +1 -0
  7. package/build/devtools.d.ts +1 -1
  8. package/build/devtools.js +10 -1
  9. package/build/devtools.js.map +1 -1
  10. package/build/dom.d.ts +18 -6
  11. package/build/dom.js +25 -6
  12. package/build/dom.js.map +1 -1
  13. package/build/index.d.ts +4 -1
  14. package/build/index.js +4 -1
  15. package/build/index.js.map +1 -1
  16. package/build/ink.d.ts +15 -1
  17. package/build/ink.js +62 -12
  18. package/build/ink.js.map +1 -1
  19. package/build/measure-element.d.ts +0 -8
  20. package/build/measure-element.js +0 -50
  21. package/build/measure-element.js.map +1 -1
  22. package/build/measure-text.d.ts +11 -3
  23. package/build/measure-text.js +169 -13
  24. package/build/measure-text.js.map +1 -1
  25. package/build/output.d.ts +8 -2
  26. package/build/output.js +111 -61
  27. package/build/output.js.map +1 -1
  28. package/build/reconciler.js +24 -0
  29. package/build/reconciler.js.map +1 -1
  30. package/build/render-background.js +1 -1
  31. package/build/render-background.js.map +1 -1
  32. package/build/render-border.js +13 -5
  33. package/build/render-border.js.map +1 -1
  34. package/build/render-node-to-output.d.ts +2 -0
  35. package/build/render-node-to-output.js +233 -54
  36. package/build/render-node-to-output.js.map +1 -1
  37. package/build/render.d.ts +7 -3
  38. package/build/render.js +1 -0
  39. package/build/render.js.map +1 -1
  40. package/build/resize-observer.d.ts +22 -0
  41. package/build/resize-observer.js +59 -0
  42. package/build/resize-observer.js.map +1 -0
  43. package/build/scroll.d.ts +3 -0
  44. package/build/scroll.js +58 -1
  45. package/build/scroll.js.map +1 -1
  46. package/build/text-wrap.d.ts +6 -0
  47. package/build/text-wrap.js +130 -0
  48. package/build/text-wrap.js.map +1 -0
  49. package/package.json +6 -6
  50. package/readme.md +15 -1
  51. package/build/wrap-text.d.ts +0 -3
  52. package/build/wrap-text.js +0 -31
  53. package/build/wrap-text.js.map +0 -1
@@ -0,0 +1,59 @@
1
+ export class ResizeObserverEntry {
2
+ target;
3
+ contentRect;
4
+ constructor(target, contentRect) {
5
+ this.target = target;
6
+ this.contentRect = contentRect;
7
+ }
8
+ }
9
+ export default class ResizeObserver {
10
+ callback;
11
+ observedElements = new Set();
12
+ constructor(callback) {
13
+ this.callback = callback;
14
+ }
15
+ observe(element) {
16
+ if (this.observedElements.has(element)) {
17
+ return;
18
+ }
19
+ this.observedElements.add(element);
20
+ element.resizeObservers ||= new Set();
21
+ element.resizeObservers.add(this);
22
+ let lastMeasuredSize = element.internal_lastMeasuredSize;
23
+ if (lastMeasuredSize === undefined && element.yogaNode) {
24
+ const width = element.yogaNode.getComputedWidth();
25
+ const height = element.yogaNode.getComputedHeight();
26
+ lastMeasuredSize = { width, height };
27
+ element.internal_lastMeasuredSize = lastMeasuredSize;
28
+ }
29
+ if (lastMeasuredSize) {
30
+ const entry = new ResizeObserverEntry(element, lastMeasuredSize);
31
+ try {
32
+ this.callback([entry], this);
33
+ }
34
+ catch (error) {
35
+ console.error(error);
36
+ }
37
+ }
38
+ }
39
+ unobserve(element) {
40
+ this.observedElements.delete(element);
41
+ element.resizeObservers?.delete(this);
42
+ }
43
+ disconnect() {
44
+ for (const element of this.observedElements) {
45
+ element.resizeObservers?.delete(this);
46
+ }
47
+ this.observedElements.clear();
48
+ }
49
+ // Internal method called by Ink during layout
50
+ internalTrigger(entries) {
51
+ try {
52
+ this.callback(entries, this);
53
+ }
54
+ catch (error) {
55
+ console.error(error);
56
+ }
57
+ }
58
+ }
59
+ //# sourceMappingURL=resize-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resize-observer.js","sourceRoot":"","sources":["../src/resize-observer.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,mBAAmB;IAErB;IACA;IAFV,YACU,MAAkB,EAClB,WAA4C;QAD5C,WAAM,GAAN,MAAM,CAAY;QAClB,gBAAW,GAAX,WAAW,CAAiC;IACnD,CAAC;CACJ;AAED,MAAM,CAAC,OAAO,OAAO,cAAc;IAGL;IAFZ,gBAAgB,GAAG,IAAI,GAAG,EAAc,CAAC;IAE1D,YAA6B,QAAgC;QAAhC,aAAQ,GAAR,QAAQ,CAAwB;IAAG,CAAC;IAEjE,OAAO,CAAC,OAAmB;QAC1B,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACxC,OAAO;QACR,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,CAAC,eAAe,KAAK,IAAI,GAAG,EAAE,CAAC;QACtC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAElC,IAAI,gBAAgB,GAAG,OAAO,CAAC,yBAAyB,CAAC;QACzD,IAAI,gBAAgB,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;YACpD,gBAAgB,GAAG,EAAC,KAAK,EAAE,MAAM,EAAC,CAAC;YACnC,OAAO,CAAC,yBAAyB,GAAG,gBAAgB,CAAC;QACtD,CAAC;QAED,IAAI,gBAAgB,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,IAAI,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;YACjE,IAAI,CAAC;gBACJ,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACF,CAAC;IACF,CAAC;IAED,SAAS,CAAC,OAAmB;QAC5B,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtC,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,UAAU;QACT,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC7C,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,8CAA8C;IAC9C,eAAe,CAAC,OAA8B;QAC7C,IAAI,CAAC;YACJ,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACF,CAAC;CACD"}
package/build/scroll.d.ts CHANGED
@@ -4,5 +4,8 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { type DOMElement } from './dom.js';
7
+ export declare function getScrollHeight(node: DOMElement): number;
8
+ export declare function getScrollWidth(node: DOMElement): number;
9
+ export declare function calculateScroll(node: DOMElement): void;
7
10
  export declare function getScrollTop(node: DOMElement): number;
8
11
  export declare function getScrollLeft(node: DOMElement): number;
package/build/scroll.js CHANGED
@@ -4,7 +4,64 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import Yoga from 'yoga-layout';
7
- import { getScrollHeight, getScrollWidth } from './measure-element.js';
7
+ function calculateScrollDimensions(node) {
8
+ const { yogaNode } = node;
9
+ if (!yogaNode) {
10
+ return { scrollHeight: 0, scrollWidth: 0 };
11
+ }
12
+ const top = yogaNode.getComputedBorder(Yoga.EDGE_TOP);
13
+ const left = yogaNode.getComputedBorder(Yoga.EDGE_LEFT);
14
+ let maxBottom = top;
15
+ let maxRight = yogaNode.getComputedPadding(Yoga.EDGE_LEFT);
16
+ for (let i = 0; i < yogaNode.getChildCount(); i++) {
17
+ const child = yogaNode.getChild(i);
18
+ const childBottom = child.getComputedTop() +
19
+ child.getComputedHeight() +
20
+ child.getComputedMargin(Yoga.EDGE_BOTTOM);
21
+ if (childBottom > maxBottom) {
22
+ maxBottom = childBottom;
23
+ }
24
+ const childRight = child.getComputedLeft() +
25
+ child.getComputedWidth() +
26
+ child.getComputedMargin(Yoga.EDGE_RIGHT);
27
+ if (childRight > maxRight) {
28
+ maxRight = childRight;
29
+ }
30
+ }
31
+ const scrollHeight = maxBottom - top + yogaNode.getComputedPadding(Yoga.EDGE_BOTTOM);
32
+ const scrollWidth = maxRight - left + yogaNode.getComputedPadding(Yoga.EDGE_RIGHT);
33
+ return { scrollHeight, scrollWidth };
34
+ }
35
+ export function getScrollHeight(node) {
36
+ return node.internal_scrollState?.scrollHeight ?? 0;
37
+ }
38
+ export function getScrollWidth(node) {
39
+ return node.internal_scrollState?.scrollWidth ?? 0;
40
+ }
41
+ export function calculateScroll(node) {
42
+ const { yogaNode } = node;
43
+ if (!yogaNode) {
44
+ return;
45
+ }
46
+ const { scrollHeight, scrollWidth } = calculateScrollDimensions(node);
47
+ const clientHeight = yogaNode.getComputedHeight() -
48
+ yogaNode.getComputedBorder(Yoga.EDGE_TOP) -
49
+ yogaNode.getComputedBorder(Yoga.EDGE_BOTTOM);
50
+ const scrollTop = Math.max(0, Math.min(node.style.scrollTop ?? 0, scrollHeight - clientHeight));
51
+ const clientWidth = yogaNode.getComputedWidth() -
52
+ yogaNode.getComputedBorder(Yoga.EDGE_LEFT) -
53
+ yogaNode.getComputedBorder(Yoga.EDGE_RIGHT);
54
+ let scrollLeft = node.style.scrollLeft ?? 0;
55
+ scrollLeft = Math.max(0, Math.min(scrollLeft, scrollWidth - clientWidth));
56
+ node.internal_scrollState = {
57
+ scrollHeight,
58
+ scrollWidth,
59
+ scrollTop,
60
+ scrollLeft,
61
+ clientHeight,
62
+ clientWidth,
63
+ };
64
+ }
8
65
  export function getScrollTop(node) {
9
66
  const { yogaNode } = node;
10
67
  if (!yogaNode) {
@@ -1 +1 @@
1
- {"version":3,"file":"scroll.js","sourceRoot":"","sources":["../src/scroll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,IAAI,MAAM,aAAa,CAAC;AAE/B,OAAO,EAAC,eAAe,EAAE,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAErE,MAAM,UAAU,YAAY,CAAC,IAAgB;IAC5C,MAAM,EAAC,QAAQ,EAAC,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,YAAY,GACjB,QAAQ,CAAC,iBAAiB,EAAE;QAC5B,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACzC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE9C,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,EAAC,SAAS,EAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IAC7B,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QACnC,SAAS,GAAG,CAAC,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAgB;IAC7C,MAAM,EAAC,QAAQ,EAAC,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,WAAW,GAChB,QAAQ,CAAC,gBAAgB,EAAE;QAC3B,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC;QAC1C,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAE7C,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"scroll.js","sourceRoot":"","sources":["../src/scroll.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type StyledChar } from '@alcalzone/ansi-tokenize';
2
+ export declare const sliceStyledChars: (styledChars: StyledChar[], begin: number, end?: number) => StyledChar[];
3
+ export declare const truncateStyledChars: (styledChars: StyledChar[], columns: number, options?: {
4
+ position?: "start" | "middle" | "end";
5
+ }) => StyledChar[];
6
+ export declare const wrapStyledChars: (styledChars: StyledChar[], columns: number) => StyledChar[][];
@@ -0,0 +1,130 @@
1
+ import { inkCharacterWidth, styledCharsWidth } from './measure-text.js';
2
+ export const sliceStyledChars = (styledChars, begin, end) => {
3
+ let width = 0;
4
+ const result = [];
5
+ for (const char of styledChars) {
6
+ const charWidth = inkCharacterWidth(char.value);
7
+ const charStart = width;
8
+ const charEnd = width + charWidth;
9
+ if (end !== undefined && charEnd > end) {
10
+ break;
11
+ }
12
+ if (charStart >= begin) {
13
+ result.push(char);
14
+ }
15
+ width += charWidth;
16
+ }
17
+ return result;
18
+ };
19
+ export const truncateStyledChars = (styledChars, columns, options = {}) => {
20
+ const { position = 'end' } = options;
21
+ const truncationCharacter = '…';
22
+ const truncationStyledChar = {
23
+ type: 'char',
24
+ value: truncationCharacter,
25
+ fullWidth: false,
26
+ styles: [],
27
+ };
28
+ if (columns < 1) {
29
+ return [];
30
+ }
31
+ if (columns === 1) {
32
+ return [truncationStyledChar];
33
+ }
34
+ const textWidth = styledCharsWidth(styledChars);
35
+ if (textWidth <= columns) {
36
+ return styledChars;
37
+ }
38
+ const truncationWidth = inkCharacterWidth(truncationCharacter);
39
+ if (position === 'start') {
40
+ const right = sliceStyledChars(styledChars, textWidth - columns + truncationWidth, textWidth);
41
+ return [truncationStyledChar, ...right];
42
+ }
43
+ if (position === 'middle') {
44
+ const leftWidth = Math.ceil(columns / 2);
45
+ const rightWidth = columns - leftWidth;
46
+ const left = sliceStyledChars(styledChars, 0, leftWidth - truncationWidth);
47
+ const right = sliceStyledChars(styledChars, textWidth - rightWidth, textWidth);
48
+ return [...left, truncationStyledChar, ...right];
49
+ }
50
+ const left = sliceStyledChars(styledChars, 0, columns - truncationWidth);
51
+ return [...left, truncationStyledChar];
52
+ };
53
+ const wrapWord = (rows, word, columns) => {
54
+ let currentLine = rows.at(-1);
55
+ let visible = styledCharsWidth(currentLine);
56
+ for (const character of word) {
57
+ const characterLength = inkCharacterWidth(character.value);
58
+ if (visible + characterLength > columns && visible > 0) {
59
+ rows.push([]);
60
+ currentLine = rows.at(-1);
61
+ visible = styledCharsWidth(currentLine);
62
+ }
63
+ currentLine.push(character);
64
+ visible += characterLength;
65
+ }
66
+ };
67
+ export const wrapStyledChars = (styledChars, columns) => {
68
+ const rows = [[]];
69
+ const words = [];
70
+ let currentWord = [];
71
+ for (const char of styledChars) {
72
+ if (char.value === '\n' || char.value === ' ') {
73
+ if (currentWord.length > 0) {
74
+ words.push(currentWord);
75
+ }
76
+ currentWord = [];
77
+ words.push([char]);
78
+ }
79
+ else {
80
+ currentWord.push(char);
81
+ }
82
+ }
83
+ if (currentWord.length > 0) {
84
+ words.push(currentWord);
85
+ }
86
+ let isAtStartOfLogicalLine = true;
87
+ for (const word of words) {
88
+ if (word.length === 0) {
89
+ continue;
90
+ }
91
+ if (word[0].value === '\n') {
92
+ rows.push([]);
93
+ isAtStartOfLogicalLine = true;
94
+ continue;
95
+ }
96
+ const wordWidth = styledCharsWidth(word);
97
+ const rowWidth = styledCharsWidth(rows.at(-1));
98
+ if (rowWidth + wordWidth > columns) {
99
+ if (!isAtStartOfLogicalLine &&
100
+ word[0].value === ' ' &&
101
+ word.length === 1) {
102
+ continue;
103
+ }
104
+ if (!isAtStartOfLogicalLine) {
105
+ while (rows.at(-1).length > 0 && rows.at(-1).at(-1).value === ' ') {
106
+ rows.at(-1).pop();
107
+ }
108
+ }
109
+ if (wordWidth > columns) {
110
+ if (rowWidth > 0) {
111
+ rows.push([]);
112
+ }
113
+ wrapWord(rows, word, columns);
114
+ }
115
+ else {
116
+ rows.push([]);
117
+ rows.at(-1).push(...word);
118
+ }
119
+ }
120
+ else {
121
+ rows.at(-1).push(...word);
122
+ }
123
+ if (isAtStartOfLogicalLine &&
124
+ !(word[0].value === ' ' && word.length === 1)) {
125
+ isAtStartOfLogicalLine = false;
126
+ }
127
+ }
128
+ return rows;
129
+ };
130
+ //# sourceMappingURL=text-wrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-wrap.js","sourceRoot":"","sources":["../src/text-wrap.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jrichman/ink",
3
- "version": "6.3.1",
4
- "description": "React for CLI local version for Gemini CLI",
3
+ "version": "6.4.1",
4
+ "description": "React for CLI",
5
5
  "license": "MIT",
6
6
  "repository": "jacob314/ink",
7
7
  "author": {
@@ -43,7 +43,7 @@
43
43
  "text"
44
44
  ],
45
45
  "dependencies": {
46
- "@alcalzone/ansi-tokenize": "^0.2.0",
46
+ "@alcalzone/ansi-tokenize": "^0.2.1",
47
47
  "ansi-escapes": "^7.0.0",
48
48
  "ansi-styles": "^6.2.1",
49
49
  "auto-bind": "^5.0.1",
@@ -55,6 +55,7 @@
55
55
  "es-toolkit": "^1.39.10",
56
56
  "indent-string": "^5.0.0",
57
57
  "is-in-ci": "^2.0.0",
58
+ "mnemonist": "^0.40.3",
58
59
  "patch-console": "^2.0.0",
59
60
  "react-reconciler": "^0.32.0",
60
61
  "signal-exit": "^3.0.7",
@@ -62,7 +63,6 @@
62
63
  "stack-utils": "^2.0.6",
63
64
  "string-width": "^8.1.0",
64
65
  "type-fest": "^4.27.0",
65
- "widest-line": "^5.0.0",
66
66
  "wrap-ansi": "^9.0.0",
67
67
  "ws": "^8.18.0",
68
68
  "yoga-layout": "~3.2.1"
@@ -73,8 +73,8 @@
73
73
  "@sinonjs/fake-timers": "^14.0.0",
74
74
  "@types/ms": "^2.1.0",
75
75
  "@types/node": "^22.15.24",
76
- "@types/react": "^19.1.8",
77
- "@types/react-reconciler": "^0.32.0",
76
+ "@types/react": "^19.1.5",
77
+ "@types/react-reconciler": "^0.32.2",
78
78
  "@types/signal-exit": "^3.0.0",
79
79
  "@types/sinon": "^17.0.3",
80
80
  "@types/stack-utils": "^2.0.2",
package/readme.md CHANGED
@@ -73,7 +73,6 @@ Feel free to play around with the code and fork this Repl at [https://repl.it/@v
73
73
 
74
74
  ## Who's Using Ink?
75
75
 
76
- - [Codex](https://github.com/openai/codex) - An agentic coding tool made by OpenAI.
77
76
  - [Claude Code](https://github.com/anthropics/claude-code) - An agentic coding tool made by Anthropic.
78
77
  - [Gemini CLI](https://github.com/google-gemini/gemini-cli) - An agentic coding tool made by Google.
79
78
  - [GitHub Copilot for CLI](https://githubnext.com/projects/copilot-cli) - Just say what you want the shell to do.
@@ -123,6 +122,7 @@ Feel free to play around with the code and fork this Repl at [https://repl.it/@v
123
122
  - [tweakcc](https://github.com/Piebald-AI/tweakcc) - Customize your Claude Code styling.
124
123
  - [argonaut](https://github.com/darksworm/argonaut) - Manage Argo CD resources.
125
124
  - [Qodo Command](https://github.com/qodo-ai/command) - Build, run, and manage AI agents.
125
+ - [Nanocoder](https://github.com/nano-collective/nanocoder) - A community-built, local-first AI coding agent with multi-provider support.
126
126
 
127
127
  *(PRs welcome. Append new entries at the end. Repos must have 100+ stars and showcase Ink beyond a basic list picker.)*
128
128
 
@@ -2009,6 +2009,13 @@ Default: `process.stdin`
2009
2009
 
2010
2010
  Input stream where app will listen for input.
2011
2011
 
2012
+ ###### stderr
2013
+
2014
+ Type: `stream.Writable`\
2015
+ Default: `process.stderr`
2016
+
2017
+ Error stream.
2018
+
2012
2019
  ###### exitOnCtrlC
2013
2020
 
2014
2021
  Type: `boolean`\
@@ -2028,6 +2035,13 @@ That way, both are visible and don't overlap each other.
2028
2035
 
2029
2036
  This functionality is powered by [patch-console](https://github.com/vadimdemedes/patch-console), so if you need to disable Ink's interception of output but want to build something custom, you can use that.
2030
2037
 
2038
+ ###### onRender
2039
+
2040
+ Type: `({renderTime: number}) => void`\
2041
+ Default: `undefined`
2042
+
2043
+ Runs the given callback after each render and re-render with a metrics object.
2044
+
2031
2045
  ###### debug
2032
2046
 
2033
2047
  Type: `boolean`\
@@ -1,3 +0,0 @@
1
- import { type Styles } from './styles.js';
2
- declare const wrapText: (text: string, maxWidth: number, wrapType: Styles["textWrap"]) => string;
3
- export default wrapText;
@@ -1,31 +0,0 @@
1
- import wrapAnsi from 'wrap-ansi';
2
- import cliTruncate from 'cli-truncate';
3
- const cache = {};
4
- const wrapText = (text, maxWidth, wrapType) => {
5
- const cacheKey = text + String(maxWidth) + String(wrapType);
6
- const cachedText = cache[cacheKey];
7
- if (cachedText) {
8
- return cachedText;
9
- }
10
- let wrappedText = text;
11
- if (wrapType === 'wrap') {
12
- wrappedText = wrapAnsi(text, maxWidth, {
13
- trim: false,
14
- hard: true,
15
- });
16
- }
17
- if (wrapType.startsWith('truncate')) {
18
- let position = 'end';
19
- if (wrapType === 'truncate-middle') {
20
- position = 'middle';
21
- }
22
- if (wrapType === 'truncate-start') {
23
- position = 'start';
24
- }
25
- wrappedText = cliTruncate(text, maxWidth, { position });
26
- }
27
- cache[cacheKey] = wrappedText;
28
- return wrappedText;
29
- };
30
- export default wrapText;
31
- //# sourceMappingURL=wrap-text.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrap-text.js","sourceRoot":"","sources":["../src/wrap-text.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,WAAW,MAAM,cAAc,CAAC;AAGvC,MAAM,KAAK,GAA2B,EAAE,CAAC;AAEzC,MAAM,QAAQ,GAAG,CAChB,IAAY,EACZ,QAAgB,EAChB,QAA4B,EACnB,EAAE;IACX,MAAM,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEnC,IAAI,UAAU,EAAE,CAAC;QAChB,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,IAAI,WAAW,GAAG,IAAI,CAAC;IAEvB,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACzB,WAAW,GAAG,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE;YACtC,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;SACV,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,QAAS,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,IAAI,QAAQ,GAA+B,KAAK,CAAC;QAEjD,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;YACpC,QAAQ,GAAG,QAAQ,CAAC;QACrB,CAAC;QAED,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;YACnC,QAAQ,GAAG,OAAO,CAAC;QACpB,CAAC;QAED,WAAW,GAAG,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAC,QAAQ,EAAC,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC;IAE9B,OAAO,WAAW,CAAC;AACpB,CAAC,CAAC;AAEF,eAAe,QAAQ,CAAC"}