spawn-term 3.0.8 → 3.1.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.
@@ -1,8 +1,3 @@
1
- /**
2
- * Wrapper around @xterm/headless Terminal that provides a virtual terminal buffer.
3
- * Interprets ANSI escape sequences (cursor movement, line clearing, etc.) to produce
4
- * the actual rendered output rather than raw intermediate states.
5
- */
6
1
  export declare class TerminalBuffer {
7
2
  private terminal;
8
3
  constructor(cols: number, scrollback?: number);
@@ -18,7 +13,7 @@ export declare class TerminalBuffer {
18
13
  /**
19
14
  * Extract the rendered lines from the terminal buffer.
20
15
  * This returns the actual visible content after all ANSI sequences
21
- * have been processed.
16
+ * have been processed, with color codes preserved.
22
17
  */
23
18
  getLines(): string[];
24
19
  /**
@@ -9,7 +9,7 @@ export type ProcessOptions = {
9
9
  group?: string;
10
10
  expanded?: boolean;
11
11
  };
12
- export type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => undefined;
12
+ export type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => void;
13
13
  export declare const LineType: {
14
14
  readonly stdout: 1;
15
15
  readonly stderr: 2;
@@ -1,31 +1,3 @@
1
- function _define_property(obj, key, value) {
2
- if (key in obj) {
3
- Object.defineProperty(obj, key, {
4
- value: value,
5
- enumerable: true,
6
- configurable: true,
7
- writable: true
8
- });
9
- } else {
10
- obj[key] = value;
11
- }
12
- return obj;
13
- }
14
- function _object_spread(target) {
15
- for(var i = 1; i < arguments.length; i++){
16
- var source = arguments[i] != null ? arguments[i] : {};
17
- var ownKeys = Object.keys(source);
18
- if (typeof Object.getOwnPropertySymbols === "function") {
19
- ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
20
- return Object.getOwnPropertyDescriptor(source, sym).enumerable;
21
- }));
22
- }
23
- ownKeys.forEach(function(key) {
24
- _define_property(target, key, source[key]);
25
- });
26
- }
27
- return target;
28
- }
29
1
  import { DEFAULT_COLUMN_WIDTH } from '../constants.js';
30
2
  import { LineType } from '../types.js';
31
3
  export class ProcessStore {
@@ -41,7 +13,10 @@ export class ProcessStore {
41
13
  const oldProcess = this.processes.find((p)=>p.id === id);
42
14
  const wasRunning = (oldProcess === null || oldProcess === void 0 ? void 0 : oldProcess.state) === 'running';
43
15
  const isNowComplete = update.state && update.state !== 'running';
44
- this.processes = this.processes.map((p)=>p.id === id ? _object_spread({}, p, update) : p);
16
+ this.processes = this.processes.map((p)=>p.id === id ? {
17
+ ...p,
18
+ ...update
19
+ } : p);
45
20
  // Track completion order
46
21
  if (wasRunning && isNowComplete && !this.completedIds.includes(id)) {
47
22
  this.completedIds = [
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/state/processStore.ts"],"sourcesContent":["import { DEFAULT_COLUMN_WIDTH } from '../constants.ts';\nimport type { ChildProcess, Line, SessionOptions } from '../types.ts';\nimport { LineType } from '../types.ts';\n\ntype Listener = () => void;\ntype Mode = 'normal' | 'interactive';\n\nexport class ProcessStore {\n private processes: ChildProcess[] = [];\n private completedIds: string[] = []; // Track completion order\n private listeners = new Set<Listener>();\n private shouldExit = false;\n private exitCallback: (() => void) | null = null;\n\n // UI state\n private mode: Mode = 'normal';\n private selectedIndex = 0;\n private expandedId: string | null = null;\n private scrollOffset = 0;\n private listScrollOffset = 0; // Viewport offset for process list\n private errorFooterExpanded = false; // For non-interactive error footer\n private bufferVersion = 0; // Increments on every notify() to trigger re-renders\n\n // Session-level display settings (set once at session creation)\n private header: string | undefined;\n private showStatusBar = false;\n private isInteractive = false;\n\n constructor(options: SessionOptions = {}) {\n this.header = options.header;\n this.showStatusBar = options.showStatusBar ?? false;\n this.isInteractive = options.interactive ?? false;\n }\n\n // useSyncExternalStore API\n subscribe = (listener: Listener): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n getSnapshot = (): ChildProcess[] => this.processes;\n\n // Filtered getters\n getRunningProcesses = (): ChildProcess[] => {\n return this.processes.filter((p) => p.state === 'running');\n };\n\n getCompletedProcesses = (): ChildProcess[] => {\n // Return in completion order\n return this.completedIds.map((id) => this.processes.find((p) => p.id === id)).filter((p): p is ChildProcess => p !== undefined);\n };\n\n getFailedProcesses = (): ChildProcess[] => {\n return this.processes.filter((p) => p.state === 'error');\n };\n\n // Counts\n getRunningCount = (): number => this.processes.filter((p) => p.state === 'running').length;\n getMaxGroupLength = (): number => {\n if (this.processes.length === 0) return DEFAULT_COLUMN_WIDTH;\n return Math.max(...this.processes.map((p) => (p.group || p.title).length));\n };\n getDoneCount = (): number => this.processes.filter((p) => p.state !== 'running').length;\n getErrorCount = (): number => this.processes.filter((p) => p.state === 'error').length;\n getErrorLineCount = (): number => {\n return this.processes.filter((p) => p.state === 'error').reduce((total, p) => total + this.getProcessLineCount(p.id), 0);\n };\n\n // UI state getters\n getMode = (): Mode => this.mode;\n getSelectedIndex = (): number => this.selectedIndex;\n getExpandedId = (): string | null => this.expandedId;\n getScrollOffset = (): number => this.scrollOffset;\n getListScrollOffset = (): number => this.listScrollOffset;\n getErrorFooterExpanded = (): boolean => this.errorFooterExpanded;\n getBufferVersion = (): number => this.bufferVersion;\n // Session-level getters (set at session creation, immutable)\n getHeader = (): string | undefined => this.header;\n getShowStatusBar = (): boolean => this.showStatusBar;\n getIsInteractive = (): boolean => this.isInteractive;\n isAllComplete = (): boolean => this.processes.length > 0 && this.processes.every((p) => p.state !== 'running');\n\n // Mutations - Ink handles render throttling at 30 FPS\n addProcess(process: ChildProcess): void {\n this.processes = [...this.processes, process];\n this.notify();\n }\n\n updateProcess(id: string, update: Partial<ChildProcess>): void {\n const oldProcess = this.processes.find((p) => p.id === id);\n const wasRunning = oldProcess?.state === 'running';\n const isNowComplete = update.state && update.state !== 'running';\n\n this.processes = this.processes.map((p) => (p.id === id ? { ...p, ...update } : p));\n\n // Track completion order\n if (wasRunning && isNowComplete && !this.completedIds.includes(id)) {\n this.completedIds = [...this.completedIds, id];\n }\n\n // Auto-expand error footer when all complete with errors (non-interactive only)\n if (!this.isInteractive && this.isAllComplete() && this.getErrorCount() > 0) {\n this.errorFooterExpanded = true;\n }\n\n this.notify();\n }\n\n appendLines(id: string, newLines: Line[]): void {\n const process = this.processes.find((p) => p.id === id);\n if (process) {\n this.updateProcess(id, { lines: process.lines.concat(newLines) });\n }\n }\n\n getProcess(id: string): ChildProcess | undefined {\n return this.processes.find((p) => p.id === id);\n }\n\n // Get rendered lines from terminal buffer or fallback to lines array\n getProcessLines(id: string): Line[] {\n const process = this.getProcess(id);\n if (!process) return [];\n if (process.terminalBuffer) {\n return process.terminalBuffer.getLines().map((text) => ({\n type: LineType.stdout,\n text,\n }));\n }\n return process.lines;\n }\n\n // Get line count from terminal buffer or lines array\n getProcessLineCount(id: string): number {\n const process = this.getProcess(id);\n if (!process) return 0;\n if (process.terminalBuffer) {\n return process.terminalBuffer.lineCount;\n }\n return process.lines.length;\n }\n\n // UI state mutations\n setMode(mode: Mode): void {\n this.mode = mode;\n if (mode === 'interactive') {\n this.selectedIndex = 0;\n }\n this.notify();\n }\n\n // Interactive mode navigation\n selectNext(visibleCount?: number): void {\n if (this.processes.length > 0) {\n this.selectedIndex = (this.selectedIndex + 1) % this.processes.length;\n this.adjustListScroll(visibleCount);\n this.notify();\n }\n }\n\n selectPrev(visibleCount?: number): void {\n if (this.processes.length > 0) {\n this.selectedIndex = (this.selectedIndex - 1 + this.processes.length) % this.processes.length;\n this.adjustListScroll(visibleCount);\n this.notify();\n }\n }\n\n private adjustListScroll(visibleCount?: number): void {\n if (!visibleCount || visibleCount <= 0) return;\n\n // Ensure selected item is visible in viewport\n if (this.selectedIndex < this.listScrollOffset) {\n // Selected is above viewport - scroll up\n this.listScrollOffset = this.selectedIndex;\n } else if (this.selectedIndex >= this.listScrollOffset + visibleCount) {\n // Selected is below viewport - scroll down\n this.listScrollOffset = this.selectedIndex - visibleCount + 1;\n }\n }\n\n getSelectedProcess(): ChildProcess | undefined {\n return this.processes[this.selectedIndex];\n }\n\n // Error footer methods (for non-interactive mode)\n toggleErrorFooter(): void {\n this.errorFooterExpanded = !this.errorFooterExpanded;\n this.notify();\n }\n\n expandErrorFooter(): void {\n if (!this.errorFooterExpanded) {\n this.errorFooterExpanded = true;\n this.notify();\n }\n }\n\n getErrorLines(): Array<{ processName: string; lines: Line[] }> {\n return this.getFailedProcesses().map((p) => ({\n processName: p.group || p.title,\n lines: this.getProcessLines(p.id),\n }));\n }\n\n // Expansion methods\n toggleExpand(): void {\n const selected = this.getSelectedProcess();\n if (!selected) return;\n\n if (this.expandedId === selected.id) {\n // Collapse\n this.expandedId = null;\n this.scrollOffset = 0;\n } else {\n // Expand\n this.expandedId = selected.id;\n this.scrollOffset = 0;\n }\n this.notify();\n }\n\n collapse(): void {\n this.expandedId = null;\n this.scrollOffset = 0;\n this.notify();\n }\n\n scrollDown(maxVisible: number): void {\n if (!this.expandedId) return;\n const lineCount = this.getProcessLineCount(this.expandedId);\n if (lineCount === 0) return;\n\n const maxOffset = Math.max(0, lineCount - maxVisible);\n if (this.scrollOffset < maxOffset) {\n this.scrollOffset++;\n this.notify();\n }\n }\n\n scrollUp(): void {\n if (!this.expandedId) return;\n if (this.scrollOffset > 0) {\n this.scrollOffset--;\n this.notify();\n }\n }\n\n // Page scrolling (scroll by maxVisible lines at once)\n scrollPageDown(maxVisible: number): void {\n if (!this.expandedId) return;\n const lineCount = this.getProcessLineCount(this.expandedId);\n if (lineCount === 0) return;\n\n const maxOffset = Math.max(0, lineCount - maxVisible);\n this.scrollOffset = Math.min(this.scrollOffset + maxVisible, maxOffset);\n this.notify();\n }\n\n scrollPageUp(maxVisible: number): void {\n if (!this.expandedId) return;\n this.scrollOffset = Math.max(0, this.scrollOffset - maxVisible);\n this.notify();\n }\n\n // Jump to top/bottom\n scrollToTop(): void {\n if (!this.expandedId) return;\n this.scrollOffset = 0;\n this.notify();\n }\n\n scrollToBottom(maxVisible: number): void {\n if (!this.expandedId) return;\n const lineCount = this.getProcessLineCount(this.expandedId);\n if (lineCount === 0) return;\n\n this.scrollOffset = Math.max(0, lineCount - maxVisible);\n this.notify();\n }\n\n // Exit signaling\n signalExit(callback: () => void): void {\n this.shouldExit = true;\n this.exitCallback = callback;\n this.notify();\n }\n\n getShouldExit = (): boolean => this.shouldExit;\n getExitCallback = (): (() => void) | null => this.exitCallback;\n\n reset(): void {\n // Dispose terminal buffers before clearing\n for (const process of this.processes) {\n process.terminalBuffer?.dispose();\n }\n this.processes = [];\n this.completedIds = [];\n this.shouldExit = false;\n this.exitCallback = null;\n this.mode = 'normal';\n this.selectedIndex = 0;\n this.expandedId = null;\n this.scrollOffset = 0;\n this.listScrollOffset = 0;\n this.errorFooterExpanded = false;\n this.header = undefined;\n }\n\n // Public notify for session to trigger updates when terminal buffer changes\n notify(): void {\n this.bufferVersion++;\n this.listeners.forEach((l) => {\n l();\n });\n }\n}\n\n// Note: No global singleton - session creates its own store instance\n"],"names":["DEFAULT_COLUMN_WIDTH","LineType","ProcessStore","addProcess","process","processes","notify","updateProcess","id","update","oldProcess","find","p","wasRunning","state","isNowComplete","map","completedIds","includes","isInteractive","isAllComplete","getErrorCount","errorFooterExpanded","appendLines","newLines","lines","concat","getProcess","getProcessLines","terminalBuffer","getLines","text","type","stdout","getProcessLineCount","lineCount","length","setMode","mode","selectedIndex","selectNext","visibleCount","adjustListScroll","selectPrev","listScrollOffset","getSelectedProcess","toggleErrorFooter","expandErrorFooter","getErrorLines","getFailedProcesses","processName","group","title","toggleExpand","selected","expandedId","scrollOffset","collapse","scrollDown","maxVisible","maxOffset","Math","max","scrollUp","scrollPageDown","min","scrollPageUp","scrollToTop","scrollToBottom","signalExit","callback","shouldExit","exitCallback","reset","dispose","header","undefined","bufferVersion","listeners","forEach","l","options","Set","showStatusBar","subscribe","listener","add","delete","getSnapshot","getRunningProcesses","filter","getCompletedProcesses","getRunningCount","getMaxGroupLength","getDoneCount","getErrorLineCount","reduce","total","getMode","getSelectedIndex","getExpandedId","getScrollOffset","getListScrollOffset","getErrorFooterExpanded","getBufferVersion","getHeader","getShowStatusBar","getIsInteractive","every","getShouldExit","getExitCallback","interactive"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/state/processStore.ts"],"sourcesContent":["import { DEFAULT_COLUMN_WIDTH } from '../constants.ts';\nimport type { ChildProcess, Line, SessionOptions } from '../types.ts';\nimport { LineType } from '../types.ts';\n\ntype Listener = () => void;\ntype Mode = 'normal' | 'interactive';\n\nexport class ProcessStore {\n private processes: ChildProcess[] = [];\n private completedIds: string[] = []; // Track completion order\n private listeners = new Set<Listener>();\n private shouldExit = false;\n private exitCallback: (() => void) | null = null;\n\n // UI state\n private mode: Mode = 'normal';\n private selectedIndex = 0;\n private expandedId: string | null = null;\n private scrollOffset = 0;\n private listScrollOffset = 0; // Viewport offset for process list\n private errorFooterExpanded = false; // For non-interactive error footer\n private bufferVersion = 0; // Increments on every notify() to trigger re-renders\n\n // Session-level display settings (set once at session creation)\n private header: string | undefined;\n private showStatusBar = false;\n private isInteractive = false;\n\n constructor(options: SessionOptions = {}) {\n this.header = options.header;\n this.showStatusBar = options.showStatusBar ?? false;\n this.isInteractive = options.interactive ?? false;\n }\n\n // useSyncExternalStore API\n subscribe = (listener: Listener): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n getSnapshot = (): ChildProcess[] => this.processes;\n\n // Filtered getters\n getRunningProcesses = (): ChildProcess[] => {\n return this.processes.filter((p) => p.state === 'running');\n };\n\n getCompletedProcesses = (): ChildProcess[] => {\n // Return in completion order\n return this.completedIds.map((id) => this.processes.find((p) => p.id === id)).filter((p): p is ChildProcess => p !== undefined);\n };\n\n getFailedProcesses = (): ChildProcess[] => {\n return this.processes.filter((p) => p.state === 'error');\n };\n\n // Counts\n getRunningCount = (): number => this.processes.filter((p) => p.state === 'running').length;\n getMaxGroupLength = (): number => {\n if (this.processes.length === 0) return DEFAULT_COLUMN_WIDTH;\n return Math.max(...this.processes.map((p) => (p.group || p.title).length));\n };\n getDoneCount = (): number => this.processes.filter((p) => p.state !== 'running').length;\n getErrorCount = (): number => this.processes.filter((p) => p.state === 'error').length;\n getErrorLineCount = (): number => {\n return this.processes.filter((p) => p.state === 'error').reduce((total, p) => total + this.getProcessLineCount(p.id), 0);\n };\n\n // UI state getters\n getMode = (): Mode => this.mode;\n getSelectedIndex = (): number => this.selectedIndex;\n getExpandedId = (): string | null => this.expandedId;\n getScrollOffset = (): number => this.scrollOffset;\n getListScrollOffset = (): number => this.listScrollOffset;\n getErrorFooterExpanded = (): boolean => this.errorFooterExpanded;\n getBufferVersion = (): number => this.bufferVersion;\n // Session-level getters (set at session creation, immutable)\n getHeader = (): string | undefined => this.header;\n getShowStatusBar = (): boolean => this.showStatusBar;\n getIsInteractive = (): boolean => this.isInteractive;\n isAllComplete = (): boolean => this.processes.length > 0 && this.processes.every((p) => p.state !== 'running');\n\n // Mutations - Ink handles render throttling at 30 FPS\n addProcess(process: ChildProcess): void {\n this.processes = [...this.processes, process];\n this.notify();\n }\n\n updateProcess(id: string, update: Partial<ChildProcess>): void {\n const oldProcess = this.processes.find((p) => p.id === id);\n const wasRunning = oldProcess?.state === 'running';\n const isNowComplete = update.state && update.state !== 'running';\n\n this.processes = this.processes.map((p) => (p.id === id ? { ...p, ...update } : p));\n\n // Track completion order\n if (wasRunning && isNowComplete && !this.completedIds.includes(id)) {\n this.completedIds = [...this.completedIds, id];\n }\n\n // Auto-expand error footer when all complete with errors (non-interactive only)\n if (!this.isInteractive && this.isAllComplete() && this.getErrorCount() > 0) {\n this.errorFooterExpanded = true;\n }\n\n this.notify();\n }\n\n appendLines(id: string, newLines: Line[]): void {\n const process = this.processes.find((p) => p.id === id);\n if (process) {\n this.updateProcess(id, { lines: process.lines.concat(newLines) });\n }\n }\n\n getProcess(id: string): ChildProcess | undefined {\n return this.processes.find((p) => p.id === id);\n }\n\n // Get rendered lines from terminal buffer or fallback to lines array\n getProcessLines(id: string): Line[] {\n const process = this.getProcess(id);\n if (!process) return [];\n if (process.terminalBuffer) {\n return process.terminalBuffer.getLines().map((text) => ({\n type: LineType.stdout,\n text,\n }));\n }\n return process.lines;\n }\n\n // Get line count from terminal buffer or lines array\n getProcessLineCount(id: string): number {\n const process = this.getProcess(id);\n if (!process) return 0;\n if (process.terminalBuffer) {\n return process.terminalBuffer.lineCount;\n }\n return process.lines.length;\n }\n\n // UI state mutations\n setMode(mode: Mode): void {\n this.mode = mode;\n if (mode === 'interactive') {\n this.selectedIndex = 0;\n }\n this.notify();\n }\n\n // Interactive mode navigation\n selectNext(visibleCount?: number): void {\n if (this.processes.length > 0) {\n this.selectedIndex = (this.selectedIndex + 1) % this.processes.length;\n this.adjustListScroll(visibleCount);\n this.notify();\n }\n }\n\n selectPrev(visibleCount?: number): void {\n if (this.processes.length > 0) {\n this.selectedIndex = (this.selectedIndex - 1 + this.processes.length) % this.processes.length;\n this.adjustListScroll(visibleCount);\n this.notify();\n }\n }\n\n private adjustListScroll(visibleCount?: number): void {\n if (!visibleCount || visibleCount <= 0) return;\n\n // Ensure selected item is visible in viewport\n if (this.selectedIndex < this.listScrollOffset) {\n // Selected is above viewport - scroll up\n this.listScrollOffset = this.selectedIndex;\n } else if (this.selectedIndex >= this.listScrollOffset + visibleCount) {\n // Selected is below viewport - scroll down\n this.listScrollOffset = this.selectedIndex - visibleCount + 1;\n }\n }\n\n getSelectedProcess(): ChildProcess | undefined {\n return this.processes[this.selectedIndex];\n }\n\n // Error footer methods (for non-interactive mode)\n toggleErrorFooter(): void {\n this.errorFooterExpanded = !this.errorFooterExpanded;\n this.notify();\n }\n\n expandErrorFooter(): void {\n if (!this.errorFooterExpanded) {\n this.errorFooterExpanded = true;\n this.notify();\n }\n }\n\n getErrorLines(): Array<{ processName: string; lines: Line[] }> {\n return this.getFailedProcesses().map((p) => ({\n processName: p.group || p.title,\n lines: this.getProcessLines(p.id),\n }));\n }\n\n // Expansion methods\n toggleExpand(): void {\n const selected = this.getSelectedProcess();\n if (!selected) return;\n\n if (this.expandedId === selected.id) {\n // Collapse\n this.expandedId = null;\n this.scrollOffset = 0;\n } else {\n // Expand\n this.expandedId = selected.id;\n this.scrollOffset = 0;\n }\n this.notify();\n }\n\n collapse(): void {\n this.expandedId = null;\n this.scrollOffset = 0;\n this.notify();\n }\n\n scrollDown(maxVisible: number): void {\n if (!this.expandedId) return;\n const lineCount = this.getProcessLineCount(this.expandedId);\n if (lineCount === 0) return;\n\n const maxOffset = Math.max(0, lineCount - maxVisible);\n if (this.scrollOffset < maxOffset) {\n this.scrollOffset++;\n this.notify();\n }\n }\n\n scrollUp(): void {\n if (!this.expandedId) return;\n if (this.scrollOffset > 0) {\n this.scrollOffset--;\n this.notify();\n }\n }\n\n // Page scrolling (scroll by maxVisible lines at once)\n scrollPageDown(maxVisible: number): void {\n if (!this.expandedId) return;\n const lineCount = this.getProcessLineCount(this.expandedId);\n if (lineCount === 0) return;\n\n const maxOffset = Math.max(0, lineCount - maxVisible);\n this.scrollOffset = Math.min(this.scrollOffset + maxVisible, maxOffset);\n this.notify();\n }\n\n scrollPageUp(maxVisible: number): void {\n if (!this.expandedId) return;\n this.scrollOffset = Math.max(0, this.scrollOffset - maxVisible);\n this.notify();\n }\n\n // Jump to top/bottom\n scrollToTop(): void {\n if (!this.expandedId) return;\n this.scrollOffset = 0;\n this.notify();\n }\n\n scrollToBottom(maxVisible: number): void {\n if (!this.expandedId) return;\n const lineCount = this.getProcessLineCount(this.expandedId);\n if (lineCount === 0) return;\n\n this.scrollOffset = Math.max(0, lineCount - maxVisible);\n this.notify();\n }\n\n // Exit signaling\n signalExit(callback: () => void): void {\n this.shouldExit = true;\n this.exitCallback = callback;\n this.notify();\n }\n\n getShouldExit = (): boolean => this.shouldExit;\n getExitCallback = (): (() => void) | null => this.exitCallback;\n\n reset(): void {\n // Dispose terminal buffers before clearing\n for (const process of this.processes) {\n process.terminalBuffer?.dispose();\n }\n this.processes = [];\n this.completedIds = [];\n this.shouldExit = false;\n this.exitCallback = null;\n this.mode = 'normal';\n this.selectedIndex = 0;\n this.expandedId = null;\n this.scrollOffset = 0;\n this.listScrollOffset = 0;\n this.errorFooterExpanded = false;\n this.header = undefined;\n }\n\n // Public notify for session to trigger updates when terminal buffer changes\n notify(): void {\n this.bufferVersion++;\n this.listeners.forEach((l) => {\n l();\n });\n }\n}\n\n// Note: No global singleton - session creates its own store instance\n"],"names":["DEFAULT_COLUMN_WIDTH","LineType","ProcessStore","addProcess","process","processes","notify","updateProcess","id","update","oldProcess","find","p","wasRunning","state","isNowComplete","map","completedIds","includes","isInteractive","isAllComplete","getErrorCount","errorFooterExpanded","appendLines","newLines","lines","concat","getProcess","getProcessLines","terminalBuffer","getLines","text","type","stdout","getProcessLineCount","lineCount","length","setMode","mode","selectedIndex","selectNext","visibleCount","adjustListScroll","selectPrev","listScrollOffset","getSelectedProcess","toggleErrorFooter","expandErrorFooter","getErrorLines","getFailedProcesses","processName","group","title","toggleExpand","selected","expandedId","scrollOffset","collapse","scrollDown","maxVisible","maxOffset","Math","max","scrollUp","scrollPageDown","min","scrollPageUp","scrollToTop","scrollToBottom","signalExit","callback","shouldExit","exitCallback","reset","dispose","header","undefined","bufferVersion","listeners","forEach","l","options","Set","showStatusBar","subscribe","listener","add","delete","getSnapshot","getRunningProcesses","filter","getCompletedProcesses","getRunningCount","getMaxGroupLength","getDoneCount","getErrorLineCount","reduce","total","getMode","getSelectedIndex","getExpandedId","getScrollOffset","getListScrollOffset","getErrorFooterExpanded","getBufferVersion","getHeader","getShowStatusBar","getIsInteractive","every","getShouldExit","getExitCallback","interactive"],"mappings":"AAAA,SAASA,oBAAoB,QAAQ,kBAAkB;AAEvD,SAASC,QAAQ,QAAQ,cAAc;AAKvC,OAAO,MAAMC;IA2EX,sDAAsD;IACtDC,WAAWC,OAAqB,EAAQ;QACtC,IAAI,CAACC,SAAS,GAAG;eAAI,IAAI,CAACA,SAAS;YAAED;SAAQ;QAC7C,IAAI,CAACE,MAAM;IACb;IAEAC,cAAcC,EAAU,EAAEC,MAA6B,EAAQ;QAC7D,MAAMC,aAAa,IAAI,CAACL,SAAS,CAACM,IAAI,CAAC,CAACC,IAAMA,EAAEJ,EAAE,KAAKA;QACvD,MAAMK,aAAaH,CAAAA,uBAAAA,iCAAAA,WAAYI,KAAK,MAAK;QACzC,MAAMC,gBAAgBN,OAAOK,KAAK,IAAIL,OAAOK,KAAK,KAAK;QAEvD,IAAI,CAACT,SAAS,GAAG,IAAI,CAACA,SAAS,CAACW,GAAG,CAAC,CAACJ,IAAOA,EAAEJ,EAAE,KAAKA,KAAK;gBAAE,GAAGI,CAAC;gBAAE,GAAGH,MAAM;YAAC,IAAIG;QAEhF,yBAAyB;QACzB,IAAIC,cAAcE,iBAAiB,CAAC,IAAI,CAACE,YAAY,CAACC,QAAQ,CAACV,KAAK;YAClE,IAAI,CAACS,YAAY,GAAG;mBAAI,IAAI,CAACA,YAAY;gBAAET;aAAG;QAChD;QAEA,gFAAgF;QAChF,IAAI,CAAC,IAAI,CAACW,aAAa,IAAI,IAAI,CAACC,aAAa,MAAM,IAAI,CAACC,aAAa,KAAK,GAAG;YAC3E,IAAI,CAACC,mBAAmB,GAAG;QAC7B;QAEA,IAAI,CAAChB,MAAM;IACb;IAEAiB,YAAYf,EAAU,EAAEgB,QAAgB,EAAQ;QAC9C,MAAMpB,UAAU,IAAI,CAACC,SAAS,CAACM,IAAI,CAAC,CAACC,IAAMA,EAAEJ,EAAE,KAAKA;QACpD,IAAIJ,SAAS;YACX,IAAI,CAACG,aAAa,CAACC,IAAI;gBAAEiB,OAAOrB,QAAQqB,KAAK,CAACC,MAAM,CAACF;YAAU;QACjE;IACF;IAEAG,WAAWnB,EAAU,EAA4B;QAC/C,OAAO,IAAI,CAACH,SAAS,CAACM,IAAI,CAAC,CAACC,IAAMA,EAAEJ,EAAE,KAAKA;IAC7C;IAEA,qEAAqE;IACrEoB,gBAAgBpB,EAAU,EAAU;QAClC,MAAMJ,UAAU,IAAI,CAACuB,UAAU,CAACnB;QAChC,IAAI,CAACJ,SAAS,OAAO,EAAE;QACvB,IAAIA,QAAQyB,cAAc,EAAE;YAC1B,OAAOzB,QAAQyB,cAAc,CAACC,QAAQ,GAAGd,GAAG,CAAC,CAACe,OAAU,CAAA;oBACtDC,MAAM/B,SAASgC,MAAM;oBACrBF;gBACF,CAAA;QACF;QACA,OAAO3B,QAAQqB,KAAK;IACtB;IAEA,qDAAqD;IACrDS,oBAAoB1B,EAAU,EAAU;QACtC,MAAMJ,UAAU,IAAI,CAACuB,UAAU,CAACnB;QAChC,IAAI,CAACJ,SAAS,OAAO;QACrB,IAAIA,QAAQyB,cAAc,EAAE;YAC1B,OAAOzB,QAAQyB,cAAc,CAACM,SAAS;QACzC;QACA,OAAO/B,QAAQqB,KAAK,CAACW,MAAM;IAC7B;IAEA,qBAAqB;IACrBC,QAAQC,IAAU,EAAQ;QACxB,IAAI,CAACA,IAAI,GAAGA;QACZ,IAAIA,SAAS,eAAe;YAC1B,IAAI,CAACC,aAAa,GAAG;QACvB;QACA,IAAI,CAACjC,MAAM;IACb;IAEA,8BAA8B;IAC9BkC,WAAWC,YAAqB,EAAQ;QACtC,IAAI,IAAI,CAACpC,SAAS,CAAC+B,MAAM,GAAG,GAAG;YAC7B,IAAI,CAACG,aAAa,GAAG,AAAC,CAAA,IAAI,CAACA,aAAa,GAAG,CAAA,IAAK,IAAI,CAAClC,SAAS,CAAC+B,MAAM;YACrE,IAAI,CAACM,gBAAgB,CAACD;YACtB,IAAI,CAACnC,MAAM;QACb;IACF;IAEAqC,WAAWF,YAAqB,EAAQ;QACtC,IAAI,IAAI,CAACpC,SAAS,CAAC+B,MAAM,GAAG,GAAG;YAC7B,IAAI,CAACG,aAAa,GAAG,AAAC,CAAA,IAAI,CAACA,aAAa,GAAG,IAAI,IAAI,CAAClC,SAAS,CAAC+B,MAAM,AAAD,IAAK,IAAI,CAAC/B,SAAS,CAAC+B,MAAM;YAC7F,IAAI,CAACM,gBAAgB,CAACD;YACtB,IAAI,CAACnC,MAAM;QACb;IACF;IAEQoC,iBAAiBD,YAAqB,EAAQ;QACpD,IAAI,CAACA,gBAAgBA,gBAAgB,GAAG;QAExC,8CAA8C;QAC9C,IAAI,IAAI,CAACF,aAAa,GAAG,IAAI,CAACK,gBAAgB,EAAE;YAC9C,yCAAyC;YACzC,IAAI,CAACA,gBAAgB,GAAG,IAAI,CAACL,aAAa;QAC5C,OAAO,IAAI,IAAI,CAACA,aAAa,IAAI,IAAI,CAACK,gBAAgB,GAAGH,cAAc;YACrE,2CAA2C;YAC3C,IAAI,CAACG,gBAAgB,GAAG,IAAI,CAACL,aAAa,GAAGE,eAAe;QAC9D;IACF;IAEAI,qBAA+C;QAC7C,OAAO,IAAI,CAACxC,SAAS,CAAC,IAAI,CAACkC,aAAa,CAAC;IAC3C;IAEA,kDAAkD;IAClDO,oBAA0B;QACxB,IAAI,CAACxB,mBAAmB,GAAG,CAAC,IAAI,CAACA,mBAAmB;QACpD,IAAI,CAAChB,MAAM;IACb;IAEAyC,oBAA0B;QACxB,IAAI,CAAC,IAAI,CAACzB,mBAAmB,EAAE;YAC7B,IAAI,CAACA,mBAAmB,GAAG;YAC3B,IAAI,CAAChB,MAAM;QACb;IACF;IAEA0C,gBAA+D;QAC7D,OAAO,IAAI,CAACC,kBAAkB,GAAGjC,GAAG,CAAC,CAACJ,IAAO,CAAA;gBAC3CsC,aAAatC,EAAEuC,KAAK,IAAIvC,EAAEwC,KAAK;gBAC/B3B,OAAO,IAAI,CAACG,eAAe,CAAChB,EAAEJ,EAAE;YAClC,CAAA;IACF;IAEA,oBAAoB;IACpB6C,eAAqB;QACnB,MAAMC,WAAW,IAAI,CAACT,kBAAkB;QACxC,IAAI,CAACS,UAAU;QAEf,IAAI,IAAI,CAACC,UAAU,KAAKD,SAAS9C,EAAE,EAAE;YACnC,WAAW;YACX,IAAI,CAAC+C,UAAU,GAAG;YAClB,IAAI,CAACC,YAAY,GAAG;QACtB,OAAO;YACL,SAAS;YACT,IAAI,CAACD,UAAU,GAAGD,SAAS9C,EAAE;YAC7B,IAAI,CAACgD,YAAY,GAAG;QACtB;QACA,IAAI,CAAClD,MAAM;IACb;IAEAmD,WAAiB;QACf,IAAI,CAACF,UAAU,GAAG;QAClB,IAAI,CAACC,YAAY,GAAG;QACpB,IAAI,CAAClD,MAAM;IACb;IAEAoD,WAAWC,UAAkB,EAAQ;QACnC,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;QACtB,MAAMpB,YAAY,IAAI,CAACD,mBAAmB,CAAC,IAAI,CAACqB,UAAU;QAC1D,IAAIpB,cAAc,GAAG;QAErB,MAAMyB,YAAYC,KAAKC,GAAG,CAAC,GAAG3B,YAAYwB;QAC1C,IAAI,IAAI,CAACH,YAAY,GAAGI,WAAW;YACjC,IAAI,CAACJ,YAAY;YACjB,IAAI,CAAClD,MAAM;QACb;IACF;IAEAyD,WAAiB;QACf,IAAI,CAAC,IAAI,CAACR,UAAU,EAAE;QACtB,IAAI,IAAI,CAACC,YAAY,GAAG,GAAG;YACzB,IAAI,CAACA,YAAY;YACjB,IAAI,CAAClD,MAAM;QACb;IACF;IAEA,sDAAsD;IACtD0D,eAAeL,UAAkB,EAAQ;QACvC,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;QACtB,MAAMpB,YAAY,IAAI,CAACD,mBAAmB,CAAC,IAAI,CAACqB,UAAU;QAC1D,IAAIpB,cAAc,GAAG;QAErB,MAAMyB,YAAYC,KAAKC,GAAG,CAAC,GAAG3B,YAAYwB;QAC1C,IAAI,CAACH,YAAY,GAAGK,KAAKI,GAAG,CAAC,IAAI,CAACT,YAAY,GAAGG,YAAYC;QAC7D,IAAI,CAACtD,MAAM;IACb;IAEA4D,aAAaP,UAAkB,EAAQ;QACrC,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;QACtB,IAAI,CAACC,YAAY,GAAGK,KAAKC,GAAG,CAAC,GAAG,IAAI,CAACN,YAAY,GAAGG;QACpD,IAAI,CAACrD,MAAM;IACb;IAEA,qBAAqB;IACrB6D,cAAoB;QAClB,IAAI,CAAC,IAAI,CAACZ,UAAU,EAAE;QACtB,IAAI,CAACC,YAAY,GAAG;QACpB,IAAI,CAAClD,MAAM;IACb;IAEA8D,eAAeT,UAAkB,EAAQ;QACvC,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;QACtB,MAAMpB,YAAY,IAAI,CAACD,mBAAmB,CAAC,IAAI,CAACqB,UAAU;QAC1D,IAAIpB,cAAc,GAAG;QAErB,IAAI,CAACqB,YAAY,GAAGK,KAAKC,GAAG,CAAC,GAAG3B,YAAYwB;QAC5C,IAAI,CAACrD,MAAM;IACb;IAEA,iBAAiB;IACjB+D,WAAWC,QAAoB,EAAQ;QACrC,IAAI,CAACC,UAAU,GAAG;QAClB,IAAI,CAACC,YAAY,GAAGF;QACpB,IAAI,CAAChE,MAAM;IACb;IAKAmE,QAAc;QACZ,2CAA2C;QAC3C,KAAK,MAAMrE,WAAW,IAAI,CAACC,SAAS,CAAE;gBACpCD;aAAAA,0BAAAA,QAAQyB,cAAc,cAAtBzB,8CAAAA,wBAAwBsE,OAAO;QACjC;QACA,IAAI,CAACrE,SAAS,GAAG,EAAE;QACnB,IAAI,CAACY,YAAY,GAAG,EAAE;QACtB,IAAI,CAACsD,UAAU,GAAG;QAClB,IAAI,CAACC,YAAY,GAAG;QACpB,IAAI,CAAClC,IAAI,GAAG;QACZ,IAAI,CAACC,aAAa,GAAG;QACrB,IAAI,CAACgB,UAAU,GAAG;QAClB,IAAI,CAACC,YAAY,GAAG;QACpB,IAAI,CAACZ,gBAAgB,GAAG;QACxB,IAAI,CAACtB,mBAAmB,GAAG;QAC3B,IAAI,CAACqD,MAAM,GAAGC;IAChB;IAEA,4EAA4E;IAC5EtE,SAAe;QACb,IAAI,CAACuE,aAAa;QAClB,IAAI,CAACC,SAAS,CAACC,OAAO,CAAC,CAACC;YACtBA;QACF;IACF;IA/RA,YAAYC,UAA0B,CAAC,CAAC,CAAE;aApBlC5E,YAA4B,EAAE;aAC9BY,eAAyB,EAAE,EAAE,yBAAyB;aACtD6D,YAAY,IAAII;aAChBX,aAAa;aACbC,eAAoC;QAE5C,WAAW;aACHlC,OAAa;aACbC,gBAAgB;aAChBgB,aAA4B;aAC5BC,eAAe;aACfZ,mBAAmB,GAAG,mCAAmC;aACzDtB,sBAAsB,OAAO,mCAAmC;aAChEuD,gBAAgB,GAAG,qDAAqD;aAIxEM,gBAAgB;aAChBhE,gBAAgB;QAQxB,2BAA2B;aAC3BiE,YAAY,CAACC;YACX,IAAI,CAACP,SAAS,CAACQ,GAAG,CAACD;YACnB,OAAO,IAAM,IAAI,CAACP,SAAS,CAACS,MAAM,CAACF;QACrC;aAEAG,cAAc,IAAsB,IAAI,CAACnF,SAAS;QAElD,mBAAmB;aACnBoF,sBAAsB;YACpB,OAAO,IAAI,CAACpF,SAAS,CAACqF,MAAM,CAAC,CAAC9E,IAAMA,EAAEE,KAAK,KAAK;QAClD;aAEA6E,wBAAwB;YACtB,6BAA6B;YAC7B,OAAO,IAAI,CAAC1E,YAAY,CAACD,GAAG,CAAC,CAACR,KAAO,IAAI,CAACH,SAAS,CAACM,IAAI,CAAC,CAACC,IAAMA,EAAEJ,EAAE,KAAKA,KAAKkF,MAAM,CAAC,CAAC9E,IAAyBA,MAAMgE;QACvH;aAEA3B,qBAAqB;YACnB,OAAO,IAAI,CAAC5C,SAAS,CAACqF,MAAM,CAAC,CAAC9E,IAAMA,EAAEE,KAAK,KAAK;QAClD;QAEA,SAAS;aACT8E,kBAAkB,IAAc,IAAI,CAACvF,SAAS,CAACqF,MAAM,CAAC,CAAC9E,IAAMA,EAAEE,KAAK,KAAK,WAAWsB,MAAM;aAC1FyD,oBAAoB;YAClB,IAAI,IAAI,CAACxF,SAAS,CAAC+B,MAAM,KAAK,GAAG,OAAOpC;YACxC,OAAO6D,KAAKC,GAAG,IAAI,IAAI,CAACzD,SAAS,CAACW,GAAG,CAAC,CAACJ,IAAM,AAACA,CAAAA,EAAEuC,KAAK,IAAIvC,EAAEwC,KAAK,AAAD,EAAGhB,MAAM;QAC1E;aACA0D,eAAe,IAAc,IAAI,CAACzF,SAAS,CAACqF,MAAM,CAAC,CAAC9E,IAAMA,EAAEE,KAAK,KAAK,WAAWsB,MAAM;aACvFf,gBAAgB,IAAc,IAAI,CAAChB,SAAS,CAACqF,MAAM,CAAC,CAAC9E,IAAMA,EAAEE,KAAK,KAAK,SAASsB,MAAM;aACtF2D,oBAAoB;YAClB,OAAO,IAAI,CAAC1F,SAAS,CAACqF,MAAM,CAAC,CAAC9E,IAAMA,EAAEE,KAAK,KAAK,SAASkF,MAAM,CAAC,CAACC,OAAOrF,IAAMqF,QAAQ,IAAI,CAAC/D,mBAAmB,CAACtB,EAAEJ,EAAE,GAAG;QACxH;QAEA,mBAAmB;aACnB0F,UAAU,IAAY,IAAI,CAAC5D,IAAI;aAC/B6D,mBAAmB,IAAc,IAAI,CAAC5D,aAAa;aACnD6D,gBAAgB,IAAqB,IAAI,CAAC7C,UAAU;aACpD8C,kBAAkB,IAAc,IAAI,CAAC7C,YAAY;aACjD8C,sBAAsB,IAAc,IAAI,CAAC1D,gBAAgB;aACzD2D,yBAAyB,IAAe,IAAI,CAACjF,mBAAmB;aAChEkF,mBAAmB,IAAc,IAAI,CAAC3B,aAAa;QACnD,6DAA6D;aAC7D4B,YAAY,IAA0B,IAAI,CAAC9B,MAAM;aACjD+B,mBAAmB,IAAe,IAAI,CAACvB,aAAa;aACpDwB,mBAAmB,IAAe,IAAI,CAACxF,aAAa;aACpDC,gBAAgB,IAAe,IAAI,CAACf,SAAS,CAAC+B,MAAM,GAAG,KAAK,IAAI,CAAC/B,SAAS,CAACuG,KAAK,CAAC,CAAChG,IAAMA,EAAEE,KAAK,KAAK;aAgNpG+F,gBAAgB,IAAe,IAAI,CAACtC,UAAU;aAC9CuC,kBAAkB,IAA2B,IAAI,CAACtC,YAAY;QApQ5D,IAAI,CAACG,MAAM,GAAGM,QAAQN,MAAM;YACPM;QAArB,IAAI,CAACE,aAAa,GAAGF,CAAAA,yBAAAA,QAAQE,aAAa,cAArBF,oCAAAA,yBAAyB;YACzBA;QAArB,IAAI,CAAC9D,aAAa,GAAG8D,CAAAA,uBAAAA,QAAQ8B,WAAW,cAAnB9B,kCAAAA,uBAAuB;IAC9C;AA4RF,EAEA,qEAAqE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/types.ts"],"sourcesContent":["export type { SpawnCallback, SpawnError, SpawnOptions, SpawnResult } from 'cross-spawn-cb';\n\nimport type { SpawnError, SpawnResult } from 'cross-spawn-cb';\n\n// Session-level options (set at session creation, immutable)\nexport type SessionOptions = {\n header?: string;\n showStatusBar?: boolean;\n interactive?: boolean;\n};\n\n// Per-process options (set when spawning each process)\nexport type ProcessOptions = {\n group?: string;\n expanded?: boolean;\n};\n\nexport type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => undefined;\n\nexport const LineType = {\n stdout: 1,\n stderr: 2,\n} as const;\n\nexport type Line = {\n type: (typeof LineType)[keyof typeof LineType];\n text: string;\n};\n\nexport type State = 'running' | 'error' | 'success';\n\n// Import type for TerminalBuffer (avoid circular dependency)\nimport type { TerminalBuffer } from './lib/TerminalBuffer.ts';\n\n// Internal representation of a child process\nexport type ChildProcess = {\n id: string;\n group?: string;\n title: string;\n state: State;\n lines: Line[];\n terminalBuffer?: TerminalBuffer; // Virtual terminal for ANSI interpretation\n expanded?: boolean;\n};\n"],"names":["LineType","stdout","stderr"],"mappings":"AAmBA,OAAO,MAAMA,WAAW;IACtBC,QAAQ;IACRC,QAAQ;AACV,EAAW"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/types.ts"],"sourcesContent":["export type { SpawnCallback, SpawnError, SpawnOptions, SpawnResult } from 'cross-spawn-cb';\n\nimport type { SpawnError, SpawnResult } from 'cross-spawn-cb';\n\n// Session-level options (set at session creation, immutable)\nexport type SessionOptions = {\n header?: string;\n showStatusBar?: boolean;\n interactive?: boolean;\n};\n\n// Per-process options (set when spawning each process)\nexport type ProcessOptions = {\n group?: string;\n expanded?: boolean;\n};\n\nexport type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => void;\n\nexport const LineType = {\n stdout: 1,\n stderr: 2,\n} as const;\n\nexport type Line = {\n type: (typeof LineType)[keyof typeof LineType];\n text: string;\n};\n\nexport type State = 'running' | 'error' | 'success';\n\n// Import type for TerminalBuffer (avoid circular dependency)\nimport type { TerminalBuffer } from './lib/TerminalBuffer.ts';\n\n// Internal representation of a child process\nexport type ChildProcess = {\n id: string;\n group?: string;\n title: string;\n state: State;\n lines: Line[];\n terminalBuffer?: TerminalBuffer; // Virtual terminal for ANSI interpretation\n expanded?: boolean;\n};\n"],"names":["LineType","stdout","stderr"],"mappings":"AAmBA,OAAO,MAAMA,WAAW;IACtBC,QAAQ;IACRC,QAAQ;AACV,EAAW"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spawn-term",
3
- "version": "3.0.8",
3
+ "version": "3.1.0",
4
4
  "description": "Formats spawn with for terminal grouping",
5
5
  "keywords": [
6
6
  "spawn",
@@ -21,13 +21,14 @@
21
21
  "type": "module",
22
22
  "exports": {
23
23
  ".": {
24
+ "types": "./dist/cjs/src/index-cjs.d.ts",
24
25
  "import": "./dist/esm/index-esm.js",
25
26
  "require": "./dist/cjs/index-cjs.js"
26
27
  },
27
28
  "./package.json": "./package.json"
28
29
  },
29
30
  "main": "dist/cjs/index-cjs.js",
30
- "types": "dist/cjs/index-cjs.d.ts",
31
+ "types": "dist/cjs/src/index-cjs.d.ts",
31
32
  "files": [
32
33
  "dist",
33
34
  "assets"
@@ -36,7 +37,7 @@
36
37
  "build": "tsds build",
37
38
  "format": "biome check --write --unsafe",
38
39
  "prepublishOnly": "tsds validate",
39
- "test": "mocha --no-timeouts test/**/*.test.*",
40
+ "test": "tsds test:node --no-timeouts",
40
41
  "test:engines": "nvu engines tsds test:node --no-timeouts",
41
42
  "version": "tsds version"
42
43
  },
@@ -49,12 +50,15 @@
49
50
  "react": "*"
50
51
  },
51
52
  "devDependencies": {
53
+ "@biomejs/biome": "*",
52
54
  "@types/mocha": "*",
53
55
  "@types/node": "*",
54
56
  "@types/react": "*",
55
57
  "cr": "*",
56
58
  "is-version": "*",
57
- "pinkie-promise": "*"
59
+ "node-version-use": "*",
60
+ "pinkie-promise": "*",
61
+ "ts-dev-stack": "*"
58
62
  },
59
63
  "engines": {
60
64
  "node": ">=0.8"