You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

spawn-term

Package Overview
Dependencies
Maintainers
1
Versions
151
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

spawn-term - npm Package Compare versions

Comparing version
3.0.9
to
3.1.0
+1
-1
dist/cjs/src/types.d.ts

@@ -12,3 +12,3 @@ export type { SpawnCallback, SpawnError, SpawnOptions, SpawnResult } from 'cross-spawn-cb';

};
export type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => undefined;
export type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => void;
export declare const LineType: {

@@ -15,0 +15,0 @@ readonly stdout: 1;

@@ -1,1 +0,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":";;;;+BAmBaA;;;eAAAA;;;AAAN,IAAMA,WAAW;IACtBC,QAAQ;IACRC,QAAQ;AACV"}
{"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":";;;;+BAmBaA;;;eAAAA;;;AAAN,IAAMA,WAAW;IACtBC,QAAQ;IACRC,QAAQ;AACV"}

@@ -1,29 +0,1 @@

function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

@@ -49,3 +21,5 @@ import { Box, Text } from 'ink';

}),
running: /*#__PURE__*/ _jsx(Spinner, _object_spread({}, SPINNER))
running: /*#__PURE__*/ _jsx(Spinner, {
...SPINNER
})
};

@@ -52,0 +26,0 @@ const Header = /*#__PURE__*/ memo(function Header({ group, title, state }) {

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/ChildProcess.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\nimport { memo, useMemo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport figures from '../lib/figures.ts';\nimport type { ChildProcess as ChildProcessT, Line, State } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\nconst BLANK_LINE = { type: LineType.stdout, text: '' };\n\nconst ICONS = {\n error: <Text color=\"red\">{figures.cross}</Text>,\n success: <Text color=\"green\">{figures.tick}</Text>,\n running: <Spinner {...SPINNER} />,\n};\n\ntype ItemProps = {\n item: ChildProcessT;\n};\n\ntype HeaderProps = {\n group?: string;\n title: string;\n state: State;\n};\n\nconst Header = memo(\n function Header({ group, title, state }: HeaderProps) {\n const icon = ICONS[state];\n\n return (\n <Box>\n {icon}\n {group && <Text bold>{`${group}${figures.pointer} `}</Text>}\n <Text>{title}</Text>\n </Box>\n );\n },\n (a, b) => a.group === b.group && a.title === b.title && a.state === b.state\n);\n\ntype RunningSummaryProps = {\n line: Line;\n};\n\nconst RunningSummary = memo(function RunningSummary({ line }: RunningSummaryProps) {\n return (\n <Box marginLeft={2}>\n <Text>{line.text}</Text>\n </Box>\n );\n});\n\ntype LinesProps = {\n lines: Line[];\n};\n\nconst renderLine = (line, index) => {\n return (\n <Box key={index} minHeight={1}>\n <Text>{line.text}</Text>\n </Box>\n );\n};\n\nconst Lines = memo(function Lines({ lines }: LinesProps) {\n return (\n <Box flexDirection=\"column\" marginLeft={2}>\n {lines.map(renderLine)}\n </Box>\n );\n});\n\nconst Expanded = memo(function Expanded({ item }: ItemProps) {\n const { lines } = item;\n\n return (\n <Box flexDirection=\"column\">\n <Header group={item.group} title={item.title} state={item.state} />\n <Lines lines={lines} />\n </Box>\n );\n});\n\nconst Contracted = memo(function Contracted({ item }: ItemProps) {\n const { state, lines } = item;\n\n // remove ansi codes when displaying single lines\n const errors = useMemo(() => lines.filter((line) => line.type === LineType.stderr), [lines]);\n const summary = useMemo(() => lines.filter((line) => line.text.length > 0 && errors.indexOf(line) < 0).pop(), [lines, errors]);\n\n return (\n <Box flexDirection=\"column\">\n <Header group={item.group} title={item.title} state={item.state} />\n {state === 'running' && <RunningSummary line={summary || BLANK_LINE} />}\n {errors.length > 0 && <Lines lines={errors} />}\n </Box>\n );\n});\n\nexport default memo(function ChildProcess({ item }: ItemProps) {\n const { expanded } = item;\n return expanded ? <Expanded item={item} /> : <Contracted item={item} />;\n});\n"],"names":["Box","Text","memo","useMemo","SPINNER","figures","LineType","Spinner","BLANK_LINE","type","stdout","text","ICONS","error","color","cross","success","tick","running","Header","group","title","state","icon","bold","pointer","a","b","RunningSummary","line","marginLeft","renderLine","index","minHeight","Lines","lines","flexDirection","map","Expanded","item","Contracted","errors","filter","stderr","summary","length","indexOf","pop","ChildProcess","expanded"],"mappings":"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"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/ChildProcess.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\nimport { memo, useMemo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport figures from '../lib/figures.ts';\nimport type { ChildProcess as ChildProcessT, Line, State } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\nconst BLANK_LINE = { type: LineType.stdout, text: '' };\n\nconst ICONS = {\n error: <Text color=\"red\">{figures.cross}</Text>,\n success: <Text color=\"green\">{figures.tick}</Text>,\n running: <Spinner {...SPINNER} />,\n};\n\ntype ItemProps = {\n item: ChildProcessT;\n};\n\ntype HeaderProps = {\n group?: string;\n title: string;\n state: State;\n};\n\nconst Header = memo(\n function Header({ group, title, state }: HeaderProps) {\n const icon = ICONS[state];\n\n return (\n <Box>\n {icon}\n {group && <Text bold>{`${group}${figures.pointer} `}</Text>}\n <Text>{title}</Text>\n </Box>\n );\n },\n (a, b) => a.group === b.group && a.title === b.title && a.state === b.state\n);\n\ntype RunningSummaryProps = {\n line: Line;\n};\n\nconst RunningSummary = memo(function RunningSummary({ line }: RunningSummaryProps) {\n return (\n <Box marginLeft={2}>\n <Text>{line.text}</Text>\n </Box>\n );\n});\n\ntype LinesProps = {\n lines: Line[];\n};\n\nconst renderLine = (line, index) => {\n return (\n <Box key={index} minHeight={1}>\n <Text>{line.text}</Text>\n </Box>\n );\n};\n\nconst Lines = memo(function Lines({ lines }: LinesProps) {\n return (\n <Box flexDirection=\"column\" marginLeft={2}>\n {lines.map(renderLine)}\n </Box>\n );\n});\n\nconst Expanded = memo(function Expanded({ item }: ItemProps) {\n const { lines } = item;\n\n return (\n <Box flexDirection=\"column\">\n <Header group={item.group} title={item.title} state={item.state} />\n <Lines lines={lines} />\n </Box>\n );\n});\n\nconst Contracted = memo(function Contracted({ item }: ItemProps) {\n const { state, lines } = item;\n\n // remove ansi codes when displaying single lines\n const errors = useMemo(() => lines.filter((line) => line.type === LineType.stderr), [lines]);\n const summary = useMemo(() => lines.filter((line) => line.text.length > 0 && errors.indexOf(line) < 0).pop(), [lines, errors]);\n\n return (\n <Box flexDirection=\"column\">\n <Header group={item.group} title={item.title} state={item.state} />\n {state === 'running' && <RunningSummary line={summary || BLANK_LINE} />}\n {errors.length > 0 && <Lines lines={errors} />}\n </Box>\n );\n});\n\nexport default memo(function ChildProcess({ item }: ItemProps) {\n const { expanded } = item;\n return expanded ? <Expanded item={item} /> : <Contracted item={item} />;\n});\n"],"names":["Box","Text","memo","useMemo","SPINNER","figures","LineType","Spinner","BLANK_LINE","type","stdout","text","ICONS","error","color","cross","success","tick","running","Header","group","title","state","icon","bold","pointer","a","b","RunningSummary","line","marginLeft","renderLine","index","minHeight","Lines","lines","flexDirection","map","Expanded","item","Contracted","errors","filter","stderr","summary","length","indexOf","pop","ChildProcess","expanded"],"mappings":"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"}

@@ -1,29 +0,1 @@

function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

@@ -88,3 +60,5 @@ import { Box, Text, useStdout } from 'ink';

case 'running':
return /*#__PURE__*/ _jsx(Spinner, _object_spread({}, SPINNER));
return /*#__PURE__*/ _jsx(Spinner, {
...SPINNER
});
case 'success':

@@ -91,0 +65,0 @@ return /*#__PURE__*/ _jsx(Text, {

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/CompactProcessLine.tsx"],"sourcesContent":["import { Box, Text, useStdout } from 'ink';\nimport { memo, useMemo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport { clipText } from '../lib/clipText.ts';\nimport figures from '../lib/figures.ts';\nimport { calculateColumnWidth } from '../lib/format.ts';\nimport { useStore } from '../state/StoreContext.ts';\nimport type { ChildProcess, Line } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\ntype Props = {\n item: ChildProcess;\n isSelected?: boolean;\n};\n\nfunction getLastOutputLine(lines: Line[]): string {\n for (let i = lines.length - 1; i >= 0; i--) {\n if (lines[i].text.length > 0) {\n return lines[i].text;\n }\n }\n return '';\n}\n\nfunction getErrorCount(lines: Line[]): number {\n return lines.filter((line) => line.type === LineType.stderr).length;\n}\n\nexport default memo(function CompactProcessLine({ item, isSelected = false }: Props) {\n const store = useStore();\n const { stdout } = useStdout();\n const terminalWidth = stdout?.columns || 80;\n\n const { group, title, state, lines } = item;\n const selectionIndicator = isSelected ? figures.pointer : ' ';\n\n // Display name: prefer group, fall back to title\n const displayName = group || title;\n\n // Calculate widths - use dynamic column width based on longest name\n const selectionWidth = 1; // selection indicator\n const iconWidth = 2; // icon + space\n const maxGroupLength = store.getMaxGroupLength();\n const nameColumnWidth = calculateColumnWidth('max', terminalWidth, maxGroupLength);\n const gap = 1; // space between name and status\n const statusWidth = Math.max(0, terminalWidth - selectionWidth - iconWidth - nameColumnWidth - gap);\n\n // Clip name to column width and pad\n const clippedName = clipText(displayName, nameColumnWidth).padEnd(nameColumnWidth);\n\n // Status text based on state - clip to available width\n const statusText = useMemo(() => {\n if (state === 'running') {\n const lastLine = getLastOutputLine(lines);\n return lastLine ? clipText(lastLine, statusWidth) : '';\n }\n if (state === 'error') {\n const errorCount = getErrorCount(lines);\n const text = errorCount > 0 ? `${errorCount} error${errorCount > 1 ? 's' : ''}` : 'failed';\n return clipText(text, statusWidth);\n }\n return ''; // success - no status text\n }, [state, lines, statusWidth]);\n\n // Icon based on state\n const icon = useMemo(() => {\n switch (state) {\n case 'running':\n return <Spinner {...SPINNER} />;\n case 'success':\n return <Text color=\"green\">{figures.tick}</Text>;\n case 'error':\n return <Text color=\"red\">{figures.cross}</Text>;\n }\n }, [state]);\n\n // Status text color\n const statusColor = state === 'error' ? 'red' : 'gray';\n\n return (\n <Box width={terminalWidth}>\n <Text color={isSelected ? 'cyan' : undefined}>{selectionIndicator}</Text>\n <Box width={iconWidth}>{icon}</Box>\n <Box width={nameColumnWidth}>\n <Text inverse={isSelected}>{clippedName}</Text>\n </Box>\n {statusWidth > 0 && statusText && (\n <Box width={statusWidth + gap}>\n <Text color={statusColor}> {statusText}</Text>\n </Box>\n )}\n </Box>\n );\n});\n"],"names":["Box","Text","useStdout","memo","useMemo","SPINNER","clipText","figures","calculateColumnWidth","useStore","LineType","Spinner","getLastOutputLine","lines","i","length","text","getErrorCount","filter","line","type","stderr","CompactProcessLine","item","isSelected","store","stdout","terminalWidth","columns","group","title","state","selectionIndicator","pointer","displayName","selectionWidth","iconWidth","maxGroupLength","getMaxGroupLength","nameColumnWidth","gap","statusWidth","Math","max","clippedName","padEnd","statusText","lastLine","errorCount","icon","color","tick","cross","statusColor","width","undefined","inverse"],"mappings":"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"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/CompactProcessLine.tsx"],"sourcesContent":["import { Box, Text, useStdout } from 'ink';\nimport { memo, useMemo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport { clipText } from '../lib/clipText.ts';\nimport figures from '../lib/figures.ts';\nimport { calculateColumnWidth } from '../lib/format.ts';\nimport { useStore } from '../state/StoreContext.ts';\nimport type { ChildProcess, Line } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\ntype Props = {\n item: ChildProcess;\n isSelected?: boolean;\n};\n\nfunction getLastOutputLine(lines: Line[]): string {\n for (let i = lines.length - 1; i >= 0; i--) {\n if (lines[i].text.length > 0) {\n return lines[i].text;\n }\n }\n return '';\n}\n\nfunction getErrorCount(lines: Line[]): number {\n return lines.filter((line) => line.type === LineType.stderr).length;\n}\n\nexport default memo(function CompactProcessLine({ item, isSelected = false }: Props) {\n const store = useStore();\n const { stdout } = useStdout();\n const terminalWidth = stdout?.columns || 80;\n\n const { group, title, state, lines } = item;\n const selectionIndicator = isSelected ? figures.pointer : ' ';\n\n // Display name: prefer group, fall back to title\n const displayName = group || title;\n\n // Calculate widths - use dynamic column width based on longest name\n const selectionWidth = 1; // selection indicator\n const iconWidth = 2; // icon + space\n const maxGroupLength = store.getMaxGroupLength();\n const nameColumnWidth = calculateColumnWidth('max', terminalWidth, maxGroupLength);\n const gap = 1; // space between name and status\n const statusWidth = Math.max(0, terminalWidth - selectionWidth - iconWidth - nameColumnWidth - gap);\n\n // Clip name to column width and pad\n const clippedName = clipText(displayName, nameColumnWidth).padEnd(nameColumnWidth);\n\n // Status text based on state - clip to available width\n const statusText = useMemo(() => {\n if (state === 'running') {\n const lastLine = getLastOutputLine(lines);\n return lastLine ? clipText(lastLine, statusWidth) : '';\n }\n if (state === 'error') {\n const errorCount = getErrorCount(lines);\n const text = errorCount > 0 ? `${errorCount} error${errorCount > 1 ? 's' : ''}` : 'failed';\n return clipText(text, statusWidth);\n }\n return ''; // success - no status text\n }, [state, lines, statusWidth]);\n\n // Icon based on state\n const icon = useMemo(() => {\n switch (state) {\n case 'running':\n return <Spinner {...SPINNER} />;\n case 'success':\n return <Text color=\"green\">{figures.tick}</Text>;\n case 'error':\n return <Text color=\"red\">{figures.cross}</Text>;\n }\n }, [state]);\n\n // Status text color\n const statusColor = state === 'error' ? 'red' : 'gray';\n\n return (\n <Box width={terminalWidth}>\n <Text color={isSelected ? 'cyan' : undefined}>{selectionIndicator}</Text>\n <Box width={iconWidth}>{icon}</Box>\n <Box width={nameColumnWidth}>\n <Text inverse={isSelected}>{clippedName}</Text>\n </Box>\n {statusWidth > 0 && statusText && (\n <Box width={statusWidth + gap}>\n <Text color={statusColor}> {statusText}</Text>\n </Box>\n )}\n </Box>\n );\n});\n"],"names":["Box","Text","useStdout","memo","useMemo","SPINNER","clipText","figures","calculateColumnWidth","useStore","LineType","Spinner","getLastOutputLine","lines","i","length","text","getErrorCount","filter","line","type","stderr","CompactProcessLine","item","isSelected","store","stdout","terminalWidth","columns","group","title","state","selectionIndicator","pointer","displayName","selectionWidth","iconWidth","maxGroupLength","getMaxGroupLength","nameColumnWidth","gap","statusWidth","Math","max","clippedName","padEnd","statusText","lastLine","errorCount","icon","color","tick","cross","statusColor","width","undefined","inverse"],"mappings":"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"}

@@ -1,29 +0,1 @@

function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

@@ -39,3 +11,5 @@ import { Box, Text } from 'ink';

children: [
running > 0 ? /*#__PURE__*/ _jsx(Spinner, _object_spread({}, SPINNER)) : /*#__PURE__*/ _jsx(Text, {
running > 0 ? /*#__PURE__*/ _jsx(Spinner, {
...SPINNER
}) : /*#__PURE__*/ _jsx(Text, {
color: "green",

@@ -42,0 +16,0 @@ children: figures.tick

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/StatusBar.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\nimport { memo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport figures from '../lib/figures.ts';\nimport Spinner from './Spinner.ts';\n\ntype Props = {\n running: number;\n done: number;\n errors: number;\n errorLines: number;\n};\n\nexport default memo(function StatusBar({ running, done, errors, errorLines }: Props) {\n return (\n <Box>\n <Text>\n {running > 0 ? <Spinner {...SPINNER} /> : <Text color=\"green\">{figures.tick}</Text>}\n {` Running: ${running} | `}\n <Text color=\"green\">{figures.tick}</Text>\n {` Done: ${done} | `}\n <Text color=\"red\">{figures.cross}</Text>\n {` Errors: ${errors}`}\n {errorLines > 0 && <Text dimColor>{` (${errorLines} lines)`}</Text>}\n </Text>\n </Box>\n );\n});\n"],"names":["Box","Text","memo","SPINNER","figures","Spinner","StatusBar","running","done","errors","errorLines","color","tick","cross","dimColor"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAASA,GAAG,EAAEC,IAAI,QAAQ,MAAM;AAChC,SAASC,IAAI,QAAQ,QAAQ;AAC7B,SAASC,OAAO,QAAQ,kBAAkB;AAC1C,OAAOC,aAAa,oBAAoB;AACxC,OAAOC,aAAa,eAAe;AASnC,6BAAeH,KAAK,SAASI,UAAU,EAAEC,OAAO,EAAEC,IAAI,EAAEC,MAAM,EAAEC,UAAU,EAAS;IACjF,qBACE,KAACV;kBACC,cAAA,MAACC;;gBACEM,UAAU,kBAAI,KAACF,4BAAYF,0BAAc,KAACF;oBAAKU,OAAM;8BAASP,QAAQQ,IAAI;;gBAC1E,CAAC,UAAU,EAAEL,QAAQ,IAAI,CAAC;8BAC3B,KAACN;oBAAKU,OAAM;8BAASP,QAAQQ,IAAI;;gBAChC,CAAC,OAAO,EAAEJ,KAAK,IAAI,CAAC;8BACrB,KAACP;oBAAKU,OAAM;8BAAOP,QAAQS,KAAK;;gBAC/B,CAAC,SAAS,EAAEJ,QAAQ;gBACpBC,aAAa,mBAAK,KAACT;oBAAKa,QAAQ;8BAAE,CAAC,EAAE,EAAEJ,WAAW,OAAO,CAAC;;;;;AAInE,GAAG"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/StatusBar.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\nimport { memo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport figures from '../lib/figures.ts';\nimport Spinner from './Spinner.ts';\n\ntype Props = {\n running: number;\n done: number;\n errors: number;\n errorLines: number;\n};\n\nexport default memo(function StatusBar({ running, done, errors, errorLines }: Props) {\n return (\n <Box>\n <Text>\n {running > 0 ? <Spinner {...SPINNER} /> : <Text color=\"green\">{figures.tick}</Text>}\n {` Running: ${running} | `}\n <Text color=\"green\">{figures.tick}</Text>\n {` Done: ${done} | `}\n <Text color=\"red\">{figures.cross}</Text>\n {` Errors: ${errors}`}\n {errorLines > 0 && <Text dimColor>{` (${errorLines} lines)`}</Text>}\n </Text>\n </Box>\n );\n});\n"],"names":["Box","Text","memo","SPINNER","figures","Spinner","StatusBar","running","done","errors","errorLines","color","tick","cross","dimColor"],"mappings":";AAAA,SAASA,GAAG,EAAEC,IAAI,QAAQ,MAAM;AAChC,SAASC,IAAI,QAAQ,QAAQ;AAC7B,SAASC,OAAO,QAAQ,kBAAkB;AAC1C,OAAOC,aAAa,oBAAoB;AACxC,OAAOC,aAAa,eAAe;AASnC,6BAAeH,KAAK,SAASI,UAAU,EAAEC,OAAO,EAAEC,IAAI,EAAEC,MAAM,EAAEC,UAAU,EAAS;IACjF,qBACE,KAACV;kBACC,cAAA,MAACC;;gBACEM,UAAU,kBAAI,KAACF;oBAAS,GAAGF,OAAO;mCAAO,KAACF;oBAAKU,OAAM;8BAASP,QAAQQ,IAAI;;gBAC1E,CAAC,UAAU,EAAEL,QAAQ,IAAI,CAAC;8BAC3B,KAACN;oBAAKU,OAAM;8BAASP,QAAQQ,IAAI;;gBAChC,CAAC,OAAO,EAAEJ,KAAK,IAAI,CAAC;8BACrB,KAACP;oBAAKU,OAAM;8BAAOP,QAAQS,KAAK;;gBAC/B,CAAC,SAAS,EAAEJ,QAAQ;gBACpBC,aAAa,mBAAK,KAACT;oBAAKa,QAAQ;8BAAE,CAAC,EAAE,EAAEJ,WAAW,OAAO,CAAC;;;;;AAInE,GAAG"}

@@ -1,29 +0,1 @@

function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
var _xterm_default;

@@ -121,3 +93,5 @@ import * as xterm from '@xterm/headless';

let result = '';
let currentStyle = _object_spread({}, DEFAULT_STYLE);
let currentStyle = {
...DEFAULT_STYLE
};
let _hasContent = false;

@@ -124,0 +98,0 @@ // First pass: find the last non-empty cell to know where content ends

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/lib/TerminalBuffer.ts"],"sourcesContent":["import * as xterm from '@xterm/headless';\n\n// Handle both ESM and CJS module formats\nconst Terminal = (xterm as { Terminal: typeof xterm.Terminal; default?: { Terminal: typeof xterm.Terminal } }).Terminal || (xterm as { default?: { Terminal: typeof xterm.Terminal } }).default?.Terminal;\n\n// ANSI color mode constants from xterm.js\nconst COLOR_MODE_DEFAULT = 0;\nconst COLOR_MODE_16 = 16777216; // 0x1000000 - 16 color palette (0-15)\nconst COLOR_MODE_256 = 33554432; // 0x2000000 - 256 color palette\nconst COLOR_MODE_RGB = 50331648; // 0x3000000 - 24-bit RGB\n\n/**\n * Wrapper around @xterm/headless Terminal that provides a virtual terminal buffer.\n * Interprets ANSI escape sequences (cursor movement, line clearing, etc.) to produce\n * the actual rendered output rather than raw intermediate states.\n */\n// Cell attribute state for tracking changes\ninterface CellStyle {\n fg: number;\n fgMode: number;\n bg: number;\n bgMode: number;\n bold: boolean;\n dim: boolean;\n italic: boolean;\n underline: boolean;\n inverse: boolean;\n strikethrough: boolean;\n}\n\nconst DEFAULT_STYLE: CellStyle = {\n fg: -1,\n fgMode: COLOR_MODE_DEFAULT,\n bg: -1,\n bgMode: COLOR_MODE_DEFAULT,\n bold: false,\n dim: false,\n italic: false,\n underline: false,\n inverse: false,\n strikethrough: false,\n};\n\nfunction styleEquals(a: CellStyle, b: CellStyle): boolean {\n return a.fg === b.fg && a.fgMode === b.fgMode && a.bg === b.bg && a.bgMode === b.bgMode && a.bold === b.bold && a.dim === b.dim && a.italic === b.italic && a.underline === b.underline && a.inverse === b.inverse && a.strikethrough === b.strikethrough;\n}\n\nfunction buildAnsiCode(style: CellStyle): string {\n const codes: number[] = [];\n\n // Attributes\n if (style.bold) codes.push(1);\n if (style.dim) codes.push(2);\n if (style.italic) codes.push(3);\n if (style.underline) codes.push(4);\n if (style.inverse) codes.push(7);\n if (style.strikethrough) codes.push(9);\n\n // Foreground color\n if (style.fgMode === COLOR_MODE_16) {\n // 16-color palette: 0-7 are 30-37, 8-15 are 90-97\n if (style.fg < 8) {\n codes.push(30 + style.fg);\n } else {\n codes.push(90 + (style.fg - 8));\n }\n } else if (style.fgMode === COLOR_MODE_256) {\n codes.push(38, 5, style.fg);\n } else if (style.fgMode === COLOR_MODE_RGB) {\n // RGB is encoded in the color value\n const r = (style.fg >> 16) & 0xff;\n const g = (style.fg >> 8) & 0xff;\n const b = style.fg & 0xff;\n codes.push(38, 2, r, g, b);\n }\n\n // Background color\n if (style.bgMode === COLOR_MODE_16) {\n if (style.bg < 8) {\n codes.push(40 + style.bg);\n } else {\n codes.push(100 + (style.bg - 8));\n }\n } else if (style.bgMode === COLOR_MODE_256) {\n codes.push(48, 5, style.bg);\n } else if (style.bgMode === COLOR_MODE_RGB) {\n const r = (style.bg >> 16) & 0xff;\n const g = (style.bg >> 8) & 0xff;\n const b = style.bg & 0xff;\n codes.push(48, 2, r, g, b);\n }\n\n if (codes.length === 0) return '';\n return `\\x1b[${codes.join(';')}m`;\n}\n\nexport class TerminalBuffer {\n private terminal: InstanceType<typeof Terminal>;\n\n constructor(cols: number, scrollback = 10000) {\n this.terminal = new Terminal({\n cols,\n rows: 50, // Visible rows (doesn't matter much for headless)\n scrollback,\n allowProposedApi: true,\n });\n }\n\n /**\n * Write raw data to the terminal buffer.\n * The terminal interprets all ANSI sequences automatically.\n */\n write(data: string | Buffer): void {\n const str = typeof data === 'string' ? data : data.toString('utf8');\n this.terminal.write(str);\n }\n\n /**\n * Resize the terminal width.\n */\n resize(cols: number): void {\n this.terminal.resize(cols, this.terminal.rows);\n }\n\n /**\n * Extract the rendered lines from the terminal buffer.\n * This returns the actual visible content after all ANSI sequences\n * have been processed, with color codes preserved.\n */\n getLines(): string[] {\n const buffer = this.terminal.buffer.active;\n const lines: string[] = [];\n\n for (let i = 0; i < buffer.length; i++) {\n const bufferLine = buffer.getLine(i);\n if (!bufferLine) continue;\n\n let result = '';\n let currentStyle: CellStyle = { ...DEFAULT_STYLE };\n let _hasContent = false;\n\n // First pass: find the last non-empty cell to know where content ends\n let lastContentIndex = -1;\n for (let j = bufferLine.length - 1; j >= 0; j--) {\n const cell = bufferLine.getCell(j);\n if (cell && cell.getChars()) {\n lastContentIndex = j;\n break;\n }\n }\n\n // Second pass: build the line with ANSI codes\n for (let j = 0; j <= lastContentIndex; j++) {\n const cell = bufferLine.getCell(j);\n if (!cell) continue;\n\n const char = cell.getChars();\n const cellStyle: CellStyle = {\n fg: cell.getFgColor(),\n fgMode: cell.getFgColorMode(),\n bg: cell.getBgColor(),\n bgMode: cell.getBgColorMode(),\n bold: cell.isBold() !== 0,\n dim: cell.isDim() !== 0,\n italic: cell.isItalic() !== 0,\n underline: cell.isUnderline() !== 0,\n inverse: cell.isInverse() !== 0,\n strikethrough: cell.isStrikethrough() !== 0,\n };\n\n // Check if style changed\n if (!styleEquals(cellStyle, currentStyle)) {\n // Reset if going back to default, otherwise emit new style\n if (styleEquals(cellStyle, DEFAULT_STYLE)) {\n result += '\\x1b[0m';\n } else {\n // If we had styling before, reset first for clean transition\n if (!styleEquals(currentStyle, DEFAULT_STYLE)) {\n result += '\\x1b[0m';\n }\n result += buildAnsiCode(cellStyle);\n }\n currentStyle = cellStyle;\n }\n\n result += char || ' ';\n if (char) _hasContent = true;\n }\n\n // Reset at end of line if we had styling\n if (!styleEquals(currentStyle, DEFAULT_STYLE)) {\n result += '\\x1b[0m';\n }\n\n // Trim leading whitespace - tools like ncu/npm use cursor positioning\n // which creates lines with leading spaces when interpreted by xterm\n lines.push(result.trimStart());\n }\n\n // Trim trailing empty lines\n while (lines.length > 0 && lines[lines.length - 1] === '') {\n lines.pop();\n }\n\n return lines;\n }\n\n /**\n * Get the number of rendered lines.\n */\n get lineCount(): number {\n return this.getLines().length;\n }\n\n /**\n * Clean up terminal resources.\n */\n dispose(): void {\n this.terminal.dispose();\n }\n}\n"],"names":["xterm","Terminal","default","COLOR_MODE_DEFAULT","COLOR_MODE_16","COLOR_MODE_256","COLOR_MODE_RGB","DEFAULT_STYLE","fg","fgMode","bg","bgMode","bold","dim","italic","underline","inverse","strikethrough","styleEquals","a","b","buildAnsiCode","style","codes","push","r","g","length","join","TerminalBuffer","write","data","str","toString","terminal","resize","cols","rows","getLines","buffer","active","lines","i","bufferLine","getLine","result","currentStyle","_hasContent","lastContentIndex","j","cell","getCell","getChars","char","cellStyle","getFgColor","getFgColorMode","getBgColor","getBgColorMode","isBold","isDim","isItalic","isUnderline","isInverse","isStrikethrough","trimStart","pop","lineCount","dispose","scrollback","allowProposedApi"],"mappings":"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"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/lib/TerminalBuffer.ts"],"sourcesContent":["import * as xterm from '@xterm/headless';\n\n// Handle both ESM and CJS module formats\nconst Terminal = (xterm as { Terminal: typeof xterm.Terminal; default?: { Terminal: typeof xterm.Terminal } }).Terminal || (xterm as { default?: { Terminal: typeof xterm.Terminal } }).default?.Terminal;\n\n// ANSI color mode constants from xterm.js\nconst COLOR_MODE_DEFAULT = 0;\nconst COLOR_MODE_16 = 16777216; // 0x1000000 - 16 color palette (0-15)\nconst COLOR_MODE_256 = 33554432; // 0x2000000 - 256 color palette\nconst COLOR_MODE_RGB = 50331648; // 0x3000000 - 24-bit RGB\n\n/**\n * Wrapper around @xterm/headless Terminal that provides a virtual terminal buffer.\n * Interprets ANSI escape sequences (cursor movement, line clearing, etc.) to produce\n * the actual rendered output rather than raw intermediate states.\n */\n// Cell attribute state for tracking changes\ninterface CellStyle {\n fg: number;\n fgMode: number;\n bg: number;\n bgMode: number;\n bold: boolean;\n dim: boolean;\n italic: boolean;\n underline: boolean;\n inverse: boolean;\n strikethrough: boolean;\n}\n\nconst DEFAULT_STYLE: CellStyle = {\n fg: -1,\n fgMode: COLOR_MODE_DEFAULT,\n bg: -1,\n bgMode: COLOR_MODE_DEFAULT,\n bold: false,\n dim: false,\n italic: false,\n underline: false,\n inverse: false,\n strikethrough: false,\n};\n\nfunction styleEquals(a: CellStyle, b: CellStyle): boolean {\n return a.fg === b.fg && a.fgMode === b.fgMode && a.bg === b.bg && a.bgMode === b.bgMode && a.bold === b.bold && a.dim === b.dim && a.italic === b.italic && a.underline === b.underline && a.inverse === b.inverse && a.strikethrough === b.strikethrough;\n}\n\nfunction buildAnsiCode(style: CellStyle): string {\n const codes: number[] = [];\n\n // Attributes\n if (style.bold) codes.push(1);\n if (style.dim) codes.push(2);\n if (style.italic) codes.push(3);\n if (style.underline) codes.push(4);\n if (style.inverse) codes.push(7);\n if (style.strikethrough) codes.push(9);\n\n // Foreground color\n if (style.fgMode === COLOR_MODE_16) {\n // 16-color palette: 0-7 are 30-37, 8-15 are 90-97\n if (style.fg < 8) {\n codes.push(30 + style.fg);\n } else {\n codes.push(90 + (style.fg - 8));\n }\n } else if (style.fgMode === COLOR_MODE_256) {\n codes.push(38, 5, style.fg);\n } else if (style.fgMode === COLOR_MODE_RGB) {\n // RGB is encoded in the color value\n const r = (style.fg >> 16) & 0xff;\n const g = (style.fg >> 8) & 0xff;\n const b = style.fg & 0xff;\n codes.push(38, 2, r, g, b);\n }\n\n // Background color\n if (style.bgMode === COLOR_MODE_16) {\n if (style.bg < 8) {\n codes.push(40 + style.bg);\n } else {\n codes.push(100 + (style.bg - 8));\n }\n } else if (style.bgMode === COLOR_MODE_256) {\n codes.push(48, 5, style.bg);\n } else if (style.bgMode === COLOR_MODE_RGB) {\n const r = (style.bg >> 16) & 0xff;\n const g = (style.bg >> 8) & 0xff;\n const b = style.bg & 0xff;\n codes.push(48, 2, r, g, b);\n }\n\n if (codes.length === 0) return '';\n return `\\x1b[${codes.join(';')}m`;\n}\n\nexport class TerminalBuffer {\n private terminal: InstanceType<typeof Terminal>;\n\n constructor(cols: number, scrollback = 10000) {\n this.terminal = new Terminal({\n cols,\n rows: 50, // Visible rows (doesn't matter much for headless)\n scrollback,\n allowProposedApi: true,\n });\n }\n\n /**\n * Write raw data to the terminal buffer.\n * The terminal interprets all ANSI sequences automatically.\n */\n write(data: string | Buffer): void {\n const str = typeof data === 'string' ? data : data.toString('utf8');\n this.terminal.write(str);\n }\n\n /**\n * Resize the terminal width.\n */\n resize(cols: number): void {\n this.terminal.resize(cols, this.terminal.rows);\n }\n\n /**\n * Extract the rendered lines from the terminal buffer.\n * This returns the actual visible content after all ANSI sequences\n * have been processed, with color codes preserved.\n */\n getLines(): string[] {\n const buffer = this.terminal.buffer.active;\n const lines: string[] = [];\n\n for (let i = 0; i < buffer.length; i++) {\n const bufferLine = buffer.getLine(i);\n if (!bufferLine) continue;\n\n let result = '';\n let currentStyle: CellStyle = { ...DEFAULT_STYLE };\n let _hasContent = false;\n\n // First pass: find the last non-empty cell to know where content ends\n let lastContentIndex = -1;\n for (let j = bufferLine.length - 1; j >= 0; j--) {\n const cell = bufferLine.getCell(j);\n if (cell && cell.getChars()) {\n lastContentIndex = j;\n break;\n }\n }\n\n // Second pass: build the line with ANSI codes\n for (let j = 0; j <= lastContentIndex; j++) {\n const cell = bufferLine.getCell(j);\n if (!cell) continue;\n\n const char = cell.getChars();\n const cellStyle: CellStyle = {\n fg: cell.getFgColor(),\n fgMode: cell.getFgColorMode(),\n bg: cell.getBgColor(),\n bgMode: cell.getBgColorMode(),\n bold: cell.isBold() !== 0,\n dim: cell.isDim() !== 0,\n italic: cell.isItalic() !== 0,\n underline: cell.isUnderline() !== 0,\n inverse: cell.isInverse() !== 0,\n strikethrough: cell.isStrikethrough() !== 0,\n };\n\n // Check if style changed\n if (!styleEquals(cellStyle, currentStyle)) {\n // Reset if going back to default, otherwise emit new style\n if (styleEquals(cellStyle, DEFAULT_STYLE)) {\n result += '\\x1b[0m';\n } else {\n // If we had styling before, reset first for clean transition\n if (!styleEquals(currentStyle, DEFAULT_STYLE)) {\n result += '\\x1b[0m';\n }\n result += buildAnsiCode(cellStyle);\n }\n currentStyle = cellStyle;\n }\n\n result += char || ' ';\n if (char) _hasContent = true;\n }\n\n // Reset at end of line if we had styling\n if (!styleEquals(currentStyle, DEFAULT_STYLE)) {\n result += '\\x1b[0m';\n }\n\n // Trim leading whitespace - tools like ncu/npm use cursor positioning\n // which creates lines with leading spaces when interpreted by xterm\n lines.push(result.trimStart());\n }\n\n // Trim trailing empty lines\n while (lines.length > 0 && lines[lines.length - 1] === '') {\n lines.pop();\n }\n\n return lines;\n }\n\n /**\n * Get the number of rendered lines.\n */\n get lineCount(): number {\n return this.getLines().length;\n }\n\n /**\n * Clean up terminal resources.\n */\n dispose(): void {\n this.terminal.dispose();\n }\n}\n"],"names":["xterm","Terminal","default","COLOR_MODE_DEFAULT","COLOR_MODE_16","COLOR_MODE_256","COLOR_MODE_RGB","DEFAULT_STYLE","fg","fgMode","bg","bgMode","bold","dim","italic","underline","inverse","strikethrough","styleEquals","a","b","buildAnsiCode","style","codes","push","r","g","length","join","TerminalBuffer","write","data","str","toString","terminal","resize","cols","rows","getLines","buffer","active","lines","i","bufferLine","getLine","result","currentStyle","_hasContent","lastContentIndex","j","cell","getCell","getChars","char","cellStyle","getFgColor","getFgColorMode","getBgColor","getBgColorMode","isBold","isDim","isItalic","isUnderline","isInverse","isStrikethrough","trimStart","pop","lineCount","dispose","scrollback","allowProposedApi"],"mappings":"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"}

@@ -1,80 +0,1 @@

function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) {
symbols = symbols.filter(function(sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
}
keys.push.apply(keys, symbols);
}
return keys;
}
function _object_spread_props(target, source) {
source = source != null ? source : {};
if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function(key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _object_without_properties(source, excluded) {
if (source == null) return {};
var target = _object_without_properties_loose(source, excluded);
var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for(i = 0; i < sourceSymbolKeys.length; i++){
key = sourceSymbolKeys[i];
if (excluded.indexOf(key) >= 0) continue;
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
target[key] = source[key];
}
}
return target;
}
function _object_without_properties_loose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for(i = 0; i < sourceKeys.length; i++){
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
import { jsx as _jsx } from "react/jsx-runtime";

@@ -92,3 +13,3 @@ import spawn, { crossSpawn } from 'cross-spawn-cb';

import { ProcessStore } from './state/processStore.js';
class SessionImpl {
let SessionImpl = class SessionImpl {
spawn(command, args, spawnOptions, options, callback) {

@@ -98,12 +19,10 @@ if (this.closed) {

}
const { encoding, stdio } = spawnOptions, csOptions = _object_without_properties(spawnOptions, [
"encoding",
"stdio"
]);
const { encoding, stdio, ...csOptions } = spawnOptions;
if (stdio === 'inherit') {
// When Ink is not rendering (stdout not a TTY), pass output directly to stdout
if (!this.inkApp) {
const cp = crossSpawn(command, args, _object_spread_props(_object_spread({}, csOptions), {
const cp = crossSpawn(command, args, {
...csOptions,
stdio: 'inherit'
}));
});
spawn.worker(cp, csOptions, (err)=>{

@@ -321,5 +240,5 @@ const res = err ? err : {};

}
}
};
export function createSession(options = {}) {
return new SessionImpl(options);
}

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/session.tsx"],"sourcesContent":["import spawn, { crossSpawn, type SpawnResult } from 'cross-spawn-cb';\nimport crypto from 'crypto';\nimport { render } from 'ink';\nimport oo from 'on-one';\nimport Queue from 'queue-cb';\n\nimport App from './components/App.ts';\nimport { DEFAULT_MAX_FPS } from './constants.ts';\nimport concatWritable from './lib/concatWritable.ts';\nimport formatArguments from './lib/formatArguments.ts';\nimport { TerminalBuffer } from './lib/TerminalBuffer.ts';\nimport { ProcessStore } from './state/processStore.ts';\nimport type { ProcessOptions, SessionOptions, SpawnError, SpawnOptions, TerminalCallback } from './types.ts';\n\nexport interface Session {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void;\n close(): void;\n waitAndClose(callback?: () => void): void;\n}\n\nclass SessionImpl implements Session {\n private store: ProcessStore;\n private inkApp: ReturnType<typeof render> | null = null;\n private runningCount = 0;\n private closed = false;\n private waitCallbacks: (() => void)[] = [];\n private isInteractive: boolean;\n private terminalWidth: number;\n\n constructor(options: SessionOptions = {}) {\n this.store = new ProcessStore(options);\n this.isInteractive = options.interactive ?? false;\n // Use a very wide buffer to prevent line wrapping in xterm\n // Actual display truncation is handled by Ink components\n this.terminalWidth = 10000;\n\n // Only render Ink when stdout is a real terminal\n // When piped (e.g., nested spawn-term), skip Ink to avoid cursor positioning artifacts\n if (process.stdout.isTTY) {\n this.inkApp = render(<App store={this.store} />, {\n maxFps: DEFAULT_MAX_FPS,\n });\n }\n }\n\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void {\n if (this.closed) {\n throw new Error('Session is closed');\n }\n\n const { encoding, stdio, ...csOptions } = spawnOptions;\n\n if (stdio === 'inherit') {\n // When Ink is not rendering (stdout not a TTY), pass output directly to stdout\n if (!this.inkApp) {\n const cp = crossSpawn(command, args, { ...csOptions, stdio: 'inherit' });\n spawn.worker(cp, csOptions, (err?: SpawnError) => {\n const res = (err ? err : {}) as SpawnResult;\n res.stdout = null;\n res.stderr = null;\n res.output = [null, null, null];\n err ? callback(err) : callback(null, res);\n });\n return;\n }\n\n this.runningCount++;\n const id = crypto.randomUUID();\n\n // Create terminal buffer for ANSI sequence interpretation\n const terminalBuffer = new TerminalBuffer(this.terminalWidth);\n\n this.store.addProcess({\n id,\n title: [command].concat(formatArguments(args)).join(' '),\n state: 'running',\n lines: [],\n terminalBuffer,\n group: options.group,\n expanded: options.expanded,\n });\n\n const cp = crossSpawn(command, args, csOptions);\n\n // Pipe stdout and stderr directly to terminal buffer\n // Both streams go to the same buffer to maintain correct ordering\n if (cp.stdout) {\n cp.stdout.on('data', (chunk: Buffer) => {\n terminalBuffer.write(chunk);\n this.store.notify();\n });\n }\n if (cp.stderr) {\n cp.stderr.on('data', (chunk: Buffer) => {\n terminalBuffer.write(chunk);\n this.store.notify();\n });\n }\n\n // Wait for process to complete\n const queue = new Queue();\n if (cp.stdout) {\n queue.defer(oo.bind(null, cp.stdout, ['error', 'end', 'close']));\n }\n if (cp.stderr) {\n queue.defer(oo.bind(null, cp.stderr, ['error', 'end', 'close']));\n }\n queue.defer(spawn.worker.bind(null, cp, csOptions));\n queue.await((err?: SpawnError) => {\n const res = (err ? err : {}) as SpawnResult;\n res.stdout = null; // Not collecting raw output in inherit mode\n res.stderr = null;\n res.output = [null, null, null];\n this.store.updateProcess(id, { state: err ? 'error' : 'success' });\n\n this.onProcessComplete();\n err ? callback(err) : callback(null, res);\n });\n } else {\n // Non-inherit mode: collect output but don't display in UI\n const cp = crossSpawn(command, args, csOptions);\n const outputs = { stdout: null as ReturnType<typeof concatWritable> | null, stderr: null as ReturnType<typeof concatWritable> | null };\n\n const queue = new Queue();\n if (cp.stdout) {\n outputs.stdout = concatWritable((output) => {\n (outputs.stdout as unknown as { output: string }).output = output.toString(encoding || 'utf8');\n });\n queue.defer(oo.bind(null, cp.stdout.pipe(outputs.stdout), ['error', 'end', 'close', 'finish']));\n }\n if (cp.stderr) {\n outputs.stderr = concatWritable((output) => {\n (outputs.stderr as unknown as { output: string }).output = output.toString(encoding || 'utf8');\n });\n queue.defer(oo.bind(null, cp.stderr.pipe(outputs.stderr), ['error', 'end', 'close', 'finish']));\n }\n queue.defer(spawn.worker.bind(null, cp, csOptions));\n queue.await((err?: SpawnError) => {\n const res = (err ? err : {}) as SpawnResult;\n res.stdout = outputs.stdout ? (outputs.stdout as unknown as { output: string }).output : null;\n res.stderr = outputs.stderr ? (outputs.stderr as unknown as { output: string }).output : null;\n res.output = [res.stdout, res.stderr, null];\n err ? callback(err) : callback(null, res);\n });\n }\n }\n\n close(): void {\n if (this.closed) return;\n this.closed = true;\n this.cleanup();\n }\n\n waitAndClose(callback?: () => void): void {\n if (this.closed) {\n callback?.();\n return;\n }\n\n if (callback) this.waitCallbacks.push(callback);\n\n if (this.runningCount === 0) {\n if (this.isInteractive) {\n // In interactive mode, wait for user to quit (press 'q')\n const unsubscribe = this.store.subscribe(() => {\n if (this.store.getShouldExit()) {\n unsubscribe();\n this.closeAndCallWaitCallbacks();\n }\n });\n } else {\n this.closeAndCallWaitCallbacks();\n }\n }\n // If runningCount > 0, will close when it hits 0 in onProcessComplete\n }\n\n private onProcessComplete(): void {\n this.runningCount--;\n if (this.runningCount === 0 && this.waitCallbacks.length > 0) {\n if (this.isInteractive) {\n // In interactive mode, wait for user to quit (press 'q')\n const unsubscribe = this.store.subscribe(() => {\n if (this.store.getShouldExit()) {\n unsubscribe();\n this.closeAndCallWaitCallbacks();\n }\n });\n } else {\n this.closeAndCallWaitCallbacks();\n }\n }\n }\n\n private closeAndCallWaitCallbacks(): void {\n if (this.closed) return;\n this.closed = true;\n this.cleanup(() => {\n for (const cb of this.waitCallbacks) cb();\n this.waitCallbacks = [];\n });\n }\n\n private cleanup(onComplete?: () => void): void {\n // Signal exit to React component\n this.store.signalExit(() => {\n this.store.reset();\n process.stdout.write('\\x1b[?25h'); // show cursor\n });\n\n // Wait for Ink to finish\n if (this.inkApp) {\n this.inkApp\n .waitUntilExit()\n .then(() => {\n const cb = this.store.getExitCallback();\n cb?.();\n onComplete?.();\n })\n .catch(() => {\n const cb = this.store.getExitCallback();\n cb?.();\n onComplete?.();\n });\n this.inkApp = null;\n } else {\n onComplete?.();\n }\n }\n}\n\nexport function createSession(options: SessionOptions = {}): Session {\n return new SessionImpl(options);\n}\n"],"names":["spawn","crossSpawn","crypto","render","oo","Queue","App","DEFAULT_MAX_FPS","concatWritable","formatArguments","TerminalBuffer","ProcessStore","SessionImpl","command","args","spawnOptions","options","callback","closed","Error","encoding","stdio","csOptions","inkApp","cp","worker","err","res","stdout","stderr","output","runningCount","id","randomUUID","terminalBuffer","terminalWidth","store","addProcess","title","concat","join","state","lines","group","expanded","on","chunk","write","notify","queue","defer","bind","await","updateProcess","onProcessComplete","outputs","toString","pipe","close","cleanup","waitAndClose","waitCallbacks","push","isInteractive","unsubscribe","subscribe","getShouldExit","closeAndCallWaitCallbacks","length","cb","onComplete","signalExit","reset","process","waitUntilExit","then","getExitCallback","catch","interactive","isTTY","maxFps","createSession"],"mappings":"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"}
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/session.tsx"],"sourcesContent":["import spawn, { crossSpawn, type SpawnResult } from 'cross-spawn-cb';\nimport crypto from 'crypto';\nimport { render } from 'ink';\nimport oo from 'on-one';\nimport Queue from 'queue-cb';\n\nimport App from './components/App.ts';\nimport { DEFAULT_MAX_FPS } from './constants.ts';\nimport concatWritable from './lib/concatWritable.ts';\nimport formatArguments from './lib/formatArguments.ts';\nimport { TerminalBuffer } from './lib/TerminalBuffer.ts';\nimport { ProcessStore } from './state/processStore.ts';\nimport type { ProcessOptions, SessionOptions, SpawnError, SpawnOptions, TerminalCallback } from './types.ts';\n\nexport interface Session {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void;\n close(): void;\n waitAndClose(callback?: () => void): void;\n}\n\nclass SessionImpl implements Session {\n private store: ProcessStore;\n private inkApp: ReturnType<typeof render> | null = null;\n private runningCount = 0;\n private closed = false;\n private waitCallbacks: (() => void)[] = [];\n private isInteractive: boolean;\n private terminalWidth: number;\n\n constructor(options: SessionOptions = {}) {\n this.store = new ProcessStore(options);\n this.isInteractive = options.interactive ?? false;\n // Use a very wide buffer to prevent line wrapping in xterm\n // Actual display truncation is handled by Ink components\n this.terminalWidth = 10000;\n\n // Only render Ink when stdout is a real terminal\n // When piped (e.g., nested spawn-term), skip Ink to avoid cursor positioning artifacts\n if (process.stdout.isTTY) {\n this.inkApp = render(<App store={this.store} />, {\n maxFps: DEFAULT_MAX_FPS,\n });\n }\n }\n\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void {\n if (this.closed) {\n throw new Error('Session is closed');\n }\n\n const { encoding, stdio, ...csOptions } = spawnOptions;\n\n if (stdio === 'inherit') {\n // When Ink is not rendering (stdout not a TTY), pass output directly to stdout\n if (!this.inkApp) {\n const cp = crossSpawn(command, args, { ...csOptions, stdio: 'inherit' });\n spawn.worker(cp, csOptions, (err?: SpawnError) => {\n const res = (err ? err : {}) as SpawnResult;\n res.stdout = null;\n res.stderr = null;\n res.output = [null, null, null];\n err ? callback(err) : callback(null, res);\n });\n return;\n }\n\n this.runningCount++;\n const id = crypto.randomUUID();\n\n // Create terminal buffer for ANSI sequence interpretation\n const terminalBuffer = new TerminalBuffer(this.terminalWidth);\n\n this.store.addProcess({\n id,\n title: [command].concat(formatArguments(args)).join(' '),\n state: 'running',\n lines: [],\n terminalBuffer,\n group: options.group,\n expanded: options.expanded,\n });\n\n const cp = crossSpawn(command, args, csOptions);\n\n // Pipe stdout and stderr directly to terminal buffer\n // Both streams go to the same buffer to maintain correct ordering\n if (cp.stdout) {\n cp.stdout.on('data', (chunk: Buffer) => {\n terminalBuffer.write(chunk);\n this.store.notify();\n });\n }\n if (cp.stderr) {\n cp.stderr.on('data', (chunk: Buffer) => {\n terminalBuffer.write(chunk);\n this.store.notify();\n });\n }\n\n // Wait for process to complete\n const queue = new Queue();\n if (cp.stdout) {\n queue.defer(oo.bind(null, cp.stdout, ['error', 'end', 'close']));\n }\n if (cp.stderr) {\n queue.defer(oo.bind(null, cp.stderr, ['error', 'end', 'close']));\n }\n queue.defer(spawn.worker.bind(null, cp, csOptions));\n queue.await((err?: SpawnError) => {\n const res = (err ? err : {}) as SpawnResult;\n res.stdout = null; // Not collecting raw output in inherit mode\n res.stderr = null;\n res.output = [null, null, null];\n this.store.updateProcess(id, { state: err ? 'error' : 'success' });\n\n this.onProcessComplete();\n err ? callback(err) : callback(null, res);\n });\n } else {\n // Non-inherit mode: collect output but don't display in UI\n const cp = crossSpawn(command, args, csOptions);\n const outputs = { stdout: null as ReturnType<typeof concatWritable> | null, stderr: null as ReturnType<typeof concatWritable> | null };\n\n const queue = new Queue();\n if (cp.stdout) {\n outputs.stdout = concatWritable((output) => {\n (outputs.stdout as unknown as { output: string }).output = output.toString(encoding || 'utf8');\n });\n queue.defer(oo.bind(null, cp.stdout.pipe(outputs.stdout), ['error', 'end', 'close', 'finish']));\n }\n if (cp.stderr) {\n outputs.stderr = concatWritable((output) => {\n (outputs.stderr as unknown as { output: string }).output = output.toString(encoding || 'utf8');\n });\n queue.defer(oo.bind(null, cp.stderr.pipe(outputs.stderr), ['error', 'end', 'close', 'finish']));\n }\n queue.defer(spawn.worker.bind(null, cp, csOptions));\n queue.await((err?: SpawnError) => {\n const res = (err ? err : {}) as SpawnResult;\n res.stdout = outputs.stdout ? (outputs.stdout as unknown as { output: string }).output : null;\n res.stderr = outputs.stderr ? (outputs.stderr as unknown as { output: string }).output : null;\n res.output = [res.stdout, res.stderr, null];\n err ? callback(err) : callback(null, res);\n });\n }\n }\n\n close(): void {\n if (this.closed) return;\n this.closed = true;\n this.cleanup();\n }\n\n waitAndClose(callback?: () => void): void {\n if (this.closed) {\n callback?.();\n return;\n }\n\n if (callback) this.waitCallbacks.push(callback);\n\n if (this.runningCount === 0) {\n if (this.isInteractive) {\n // In interactive mode, wait for user to quit (press 'q')\n const unsubscribe = this.store.subscribe(() => {\n if (this.store.getShouldExit()) {\n unsubscribe();\n this.closeAndCallWaitCallbacks();\n }\n });\n } else {\n this.closeAndCallWaitCallbacks();\n }\n }\n // If runningCount > 0, will close when it hits 0 in onProcessComplete\n }\n\n private onProcessComplete(): void {\n this.runningCount--;\n if (this.runningCount === 0 && this.waitCallbacks.length > 0) {\n if (this.isInteractive) {\n // In interactive mode, wait for user to quit (press 'q')\n const unsubscribe = this.store.subscribe(() => {\n if (this.store.getShouldExit()) {\n unsubscribe();\n this.closeAndCallWaitCallbacks();\n }\n });\n } else {\n this.closeAndCallWaitCallbacks();\n }\n }\n }\n\n private closeAndCallWaitCallbacks(): void {\n if (this.closed) return;\n this.closed = true;\n this.cleanup(() => {\n for (const cb of this.waitCallbacks) cb();\n this.waitCallbacks = [];\n });\n }\n\n private cleanup(onComplete?: () => void): void {\n // Signal exit to React component\n this.store.signalExit(() => {\n this.store.reset();\n process.stdout.write('\\x1b[?25h'); // show cursor\n });\n\n // Wait for Ink to finish\n if (this.inkApp) {\n this.inkApp\n .waitUntilExit()\n .then(() => {\n const cb = this.store.getExitCallback();\n cb?.();\n onComplete?.();\n })\n .catch(() => {\n const cb = this.store.getExitCallback();\n cb?.();\n onComplete?.();\n });\n this.inkApp = null;\n } else {\n onComplete?.();\n }\n }\n}\n\nexport function createSession(options: SessionOptions = {}): Session {\n return new SessionImpl(options);\n}\n"],"names":["spawn","crossSpawn","crypto","render","oo","Queue","App","DEFAULT_MAX_FPS","concatWritable","formatArguments","TerminalBuffer","ProcessStore","SessionImpl","command","args","spawnOptions","options","callback","closed","Error","encoding","stdio","csOptions","inkApp","cp","worker","err","res","stdout","stderr","output","runningCount","id","randomUUID","terminalBuffer","terminalWidth","store","addProcess","title","concat","join","state","lines","group","expanded","on","chunk","write","notify","queue","defer","bind","await","updateProcess","onProcessComplete","outputs","toString","pipe","close","cleanup","waitAndClose","waitCallbacks","push","isInteractive","unsubscribe","subscribe","getShouldExit","closeAndCallWaitCallbacks","length","cb","onComplete","signalExit","reset","process","waitUntilExit","then","getExitCallback","catch","interactive","isTTY","maxFps","createSession"],"mappings":"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"}

@@ -12,3 +12,3 @@ export type { SpawnCallback, SpawnError, SpawnOptions, SpawnResult } from 'cross-spawn-cb';

};
export type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => undefined;
export type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => void;
export declare const LineType: {

@@ -15,0 +15,0 @@ readonly stdout: 1;

@@ -1,29 +0,1 @@

function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
import { DEFAULT_COLUMN_WIDTH } from '../constants.js';

@@ -44,3 +16,6 @@ import { LineType } from '../types.js';

const isNowComplete = update.state && update.state !== 'running';
this.processes = this.processes.map((p)=>p.id === id ? _object_spread({}, p, update) : p);
this.processes = this.processes.map((p)=>p.id === id ? {
...p,
...update
} : p);
// Track completion order

@@ -47,0 +22,0 @@ if (wasRunning && isNowComplete && !this.completedIds.includes(id)) {

@@ -1,1 +0,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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"}
{"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,1 +0,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"}
{"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"}
{
"name": "spawn-term",
"version": "3.0.9",
"version": "3.1.0",
"description": "Formats spawn with for terminal grouping",

@@ -24,2 +24,3 @@ "keywords": [

".": {
"types": "./dist/cjs/src/index-cjs.d.ts",
"import": "./dist/esm/index-esm.js",

@@ -31,3 +32,3 @@ "require": "./dist/cjs/index-cjs.js"

"main": "dist/cjs/index-cjs.js",
"types": "dist/cjs/index-cjs.d.ts",
"types": "dist/cjs/src/index-cjs.d.ts",
"files": [

@@ -41,3 +42,3 @@ "dist",

"prepublishOnly": "tsds validate",
"test": "mocha --no-timeouts test/**/*.test.*",
"test": "tsds test:node --no-timeouts",
"test:engines": "nvu engines tsds test:node --no-timeouts",

@@ -55,2 +56,3 @@ "version": "tsds version"

"devDependencies": {
"@biomejs/biome": "*",
"@types/mocha": "*",

@@ -61,3 +63,5 @@ "@types/node": "*",

"is-version": "*",
"pinkie-promise": "*"
"node-version-use": "*",
"pinkie-promise": "*",
"ts-dev-stack": "*"
},

@@ -64,0 +68,0 @@ "engines": {