spawn-term 1.1.7 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/cjs/components/App.js +110 -9
  2. package/dist/cjs/components/App.js.map +1 -1
  3. package/dist/cjs/components/CompactProcessLine.js +153 -0
  4. package/dist/cjs/components/CompactProcessLine.js.map +1 -0
  5. package/dist/cjs/components/Divider.js +24 -0
  6. package/dist/cjs/components/Divider.js.map +1 -0
  7. package/dist/cjs/components/ErrorDetailModal.js +115 -0
  8. package/dist/cjs/components/ErrorDetailModal.js.map +1 -0
  9. package/dist/cjs/components/ErrorListModal.js +135 -0
  10. package/dist/cjs/components/ErrorListModal.js.map +1 -0
  11. package/dist/cjs/components/StatusBar.js +104 -0
  12. package/dist/cjs/components/StatusBar.js.map +1 -0
  13. package/dist/cjs/createApp.js +30 -33
  14. package/dist/cjs/createApp.js.map +1 -1
  15. package/dist/cjs/lib/figures.js +1 -1
  16. package/dist/cjs/lib/figures.js.map +1 -1
  17. package/dist/cjs/src/components/App.d.ts +1 -5
  18. package/dist/cjs/src/components/CompactProcessLine.d.ts +6 -0
  19. package/dist/cjs/src/components/Divider.d.ts +2 -0
  20. package/dist/cjs/src/components/ErrorDetailModal.d.ts +8 -0
  21. package/dist/cjs/src/components/ErrorListModal.d.ts +8 -0
  22. package/dist/cjs/src/components/StatusBar.d.ts +8 -0
  23. package/dist/cjs/src/createApp.d.ts +4 -5
  24. package/dist/cjs/src/state/processStore.d.ts +38 -0
  25. package/dist/cjs/state/processStore.js +241 -0
  26. package/dist/cjs/state/processStore.js.map +1 -0
  27. package/dist/cjs/worker.js +70 -108
  28. package/dist/cjs/worker.js.map +1 -1
  29. package/dist/esm/components/App.js +108 -8
  30. package/dist/esm/components/App.js.map +1 -1
  31. package/dist/esm/components/CompactProcessLine.js +134 -0
  32. package/dist/esm/components/CompactProcessLine.js.map +1 -0
  33. package/dist/esm/components/Divider.js +13 -0
  34. package/dist/esm/components/Divider.js.map +1 -0
  35. package/dist/esm/components/ErrorDetailModal.js +99 -0
  36. package/dist/esm/components/ErrorDetailModal.js.map +1 -0
  37. package/dist/esm/components/ErrorListModal.js +116 -0
  38. package/dist/esm/components/ErrorListModal.js.map +1 -0
  39. package/dist/esm/components/StatusBar.js +87 -0
  40. package/dist/esm/components/StatusBar.js.map +1 -0
  41. package/dist/esm/createApp.js +31 -32
  42. package/dist/esm/createApp.js.map +1 -1
  43. package/dist/esm/src/components/App.d.ts +1 -5
  44. package/dist/esm/src/components/CompactProcessLine.d.ts +6 -0
  45. package/dist/esm/src/components/Divider.d.ts +2 -0
  46. package/dist/esm/src/components/ErrorDetailModal.d.ts +8 -0
  47. package/dist/esm/src/components/ErrorListModal.d.ts +8 -0
  48. package/dist/esm/src/components/StatusBar.d.ts +8 -0
  49. package/dist/esm/src/createApp.d.ts +4 -5
  50. package/dist/esm/src/state/processStore.d.ts +38 -0
  51. package/dist/esm/state/processStore.js +149 -0
  52. package/dist/esm/state/processStore.js.map +1 -0
  53. package/dist/esm/worker.js +59 -91
  54. package/dist/esm/worker.js.map +1 -1
  55. package/package.json +1 -2
  56. package/dist/cjs/src/state/Store.d.ts +0 -11
  57. package/dist/cjs/state/Store.js +0 -40
  58. package/dist/cjs/state/Store.js.map +0 -1
  59. package/dist/esm/src/state/Store.d.ts +0 -11
  60. package/dist/esm/state/Store.js +0 -19
  61. package/dist/esm/state/Store.js.map +0 -1
@@ -91,30 +91,6 @@ function _object_spread(target) {
91
91
  }
92
92
  return target;
93
93
  }
94
- function ownKeys(object, enumerableOnly) {
95
- var keys = Object.keys(object);
96
- if (Object.getOwnPropertySymbols) {
97
- var symbols = Object.getOwnPropertySymbols(object);
98
- if (enumerableOnly) {
99
- symbols = symbols.filter(function(sym) {
100
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
101
- });
102
- }
103
- keys.push.apply(keys, symbols);
104
- }
105
- return keys;
106
- }
107
- function _object_spread_props(target, source) {
108
- source = source != null ? source : {};
109
- if (Object.getOwnPropertyDescriptors) {
110
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
111
- } else {
112
- ownKeys(Object(source)).forEach(function(key) {
113
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
114
- });
115
- }
116
- return target;
117
- }
118
94
  function _object_without_properties(source, excluded) {
119
95
  if (source == null) return {};
120
96
  var target = _object_without_properties_loose(source, excluded);
@@ -149,86 +125,16 @@ function spawnTerminal(command, args, spawnOptions, options, callback) {
149
125
  "stdio"
150
126
  ]);
151
127
  if (stdio === 'inherit') {
152
- terminal.retain(function(store) {
153
- var id = _crypto.default.randomUUID();
154
- store.addProcess(_object_spread({
155
- id: id,
156
- title: [
157
- command
158
- ].concat((0, _formatArgumentsts.default)(args)).join(' '),
159
- state: 'running',
160
- lines: []
161
- }, options));
162
- var cp = (0, _crossspawncb.crossSpawn)(command, args, csOptions);
163
- var outputs = {
164
- stdout: null,
165
- stderr: null
166
- };
167
- var queue = new _queuecb.default();
168
- if (cp.stdout) {
169
- outputs.stdout = (0, _addLinests.default)(function(lines) {
170
- var item = store.processes.find(function(x) {
171
- return x.id === id;
172
- });
173
- store.updateProcess(_object_spread_props(_object_spread({}, item), {
174
- lines: item.lines.concat(lines.map(function(text) {
175
- return {
176
- type: _typests.LineType.stdout,
177
- text: text
178
- };
179
- }))
180
- }));
181
- });
182
- queue.defer(_onone.default.bind(null, cp.stdout.pipe(outputs.stdout), [
183
- 'error',
184
- 'end',
185
- 'close',
186
- 'finish'
187
- ]));
188
- }
189
- if (cp.stderr) {
190
- outputs.stderr = (0, _addLinests.default)(function(lines) {
191
- var item = store.processes.find(function(x) {
192
- return x.id === id;
193
- });
194
- store.updateProcess(_object_spread_props(_object_spread({}, item), {
195
- lines: item.lines.concat(lines.map(function(text) {
196
- return {
197
- type: _typests.LineType.stderr,
198
- text: text
199
- };
200
- }))
201
- }));
202
- });
203
- queue.defer(_onone.default.bind(null, cp.stderr.pipe(outputs.stderr), [
204
- 'error',
205
- 'end',
206
- 'close',
207
- 'finish'
208
- ]));
209
- }
210
- queue.defer(_crossspawncb.default.worker.bind(null, cp, csOptions));
211
- queue.await(function(err) {
212
- var res = err ? err : {};
213
- res.stdout = outputs.stdout ? outputs.stdout.output : null;
214
- res.stderr = outputs.stderr ? outputs.stderr.output : null;
215
- res.output = [
216
- res.stdout,
217
- res.stderr,
218
- null
219
- ];
220
- var item = store.processes.find(function(x) {
221
- return x.id === id;
222
- });
223
- store.updateProcess(_object_spread_props(_object_spread({}, item), {
224
- state: err ? 'error' : 'success'
225
- }));
226
- terminal.release(function() {
227
- err ? callback(err) : callback(null, res);
228
- });
229
- });
230
- });
231
- } else {
128
+ var store = terminal.retain();
129
+ var id = _crypto.default.randomUUID();
130
+ store.addProcess(_object_spread({
131
+ id: id,
132
+ title: [
133
+ command
134
+ ].concat((0, _formatArgumentsts.default)(args)).join(' '),
135
+ state: 'running',
136
+ lines: []
137
+ }, options));
232
138
  var cp = (0, _crossspawncb.crossSpawn)(command, args, csOptions);
233
139
  var outputs = {
234
140
  stdout: null,
@@ -236,8 +142,13 @@ function spawnTerminal(command, args, spawnOptions, options, callback) {
236
142
  };
237
143
  var queue = new _queuecb.default();
238
144
  if (cp.stdout) {
239
- outputs.stdout = (0, _concatWritablets.default)(function(output) {
240
- outputs.stdout.output = output.toString(encoding || 'utf8');
145
+ outputs.stdout = (0, _addLinests.default)(function(lines) {
146
+ store.appendLines(id, lines.map(function(text) {
147
+ return {
148
+ type: _typests.LineType.stdout,
149
+ text: text
150
+ };
151
+ }));
241
152
  });
242
153
  queue.defer(_onone.default.bind(null, cp.stdout.pipe(outputs.stdout), [
243
154
  'error',
@@ -247,8 +158,13 @@ function spawnTerminal(command, args, spawnOptions, options, callback) {
247
158
  ]));
248
159
  }
249
160
  if (cp.stderr) {
250
- outputs.stderr = (0, _concatWritablets.default)(function(output) {
251
- outputs.stderr.output = output.toString(encoding || 'utf8');
161
+ outputs.stderr = (0, _addLinests.default)(function(lines) {
162
+ store.appendLines(id, lines.map(function(text) {
163
+ return {
164
+ type: _typests.LineType.stderr,
165
+ text: text
166
+ };
167
+ }));
252
168
  });
253
169
  queue.defer(_onone.default.bind(null, cp.stderr.pipe(outputs.stderr), [
254
170
  'error',
@@ -267,6 +183,52 @@ function spawnTerminal(command, args, spawnOptions, options, callback) {
267
183
  res.stderr,
268
184
  null
269
185
  ];
186
+ store.updateProcess(id, {
187
+ state: err ? 'error' : 'success'
188
+ });
189
+ terminal.release(function() {
190
+ err ? callback(err) : callback(null, res);
191
+ });
192
+ });
193
+ } else {
194
+ var cp1 = (0, _crossspawncb.crossSpawn)(command, args, csOptions);
195
+ var outputs1 = {
196
+ stdout: null,
197
+ stderr: null
198
+ };
199
+ var queue1 = new _queuecb.default();
200
+ if (cp1.stdout) {
201
+ outputs1.stdout = (0, _concatWritablets.default)(function(output) {
202
+ outputs1.stdout.output = output.toString(encoding || 'utf8');
203
+ });
204
+ queue1.defer(_onone.default.bind(null, cp1.stdout.pipe(outputs1.stdout), [
205
+ 'error',
206
+ 'end',
207
+ 'close',
208
+ 'finish'
209
+ ]));
210
+ }
211
+ if (cp1.stderr) {
212
+ outputs1.stderr = (0, _concatWritablets.default)(function(output) {
213
+ outputs1.stderr.output = output.toString(encoding || 'utf8');
214
+ });
215
+ queue1.defer(_onone.default.bind(null, cp1.stderr.pipe(outputs1.stderr), [
216
+ 'error',
217
+ 'end',
218
+ 'close',
219
+ 'finish'
220
+ ]));
221
+ }
222
+ queue1.defer(_crossspawncb.default.worker.bind(null, cp1, csOptions));
223
+ queue1.await(function(err) {
224
+ var res = err ? err : {};
225
+ res.stdout = outputs1.stdout ? outputs1.stdout.output : null;
226
+ res.stderr = outputs1.stderr ? outputs1.stderr.output : null;
227
+ res.output = [
228
+ res.stdout,
229
+ res.stderr,
230
+ null
231
+ ];
270
232
  err ? callback(err) : callback(null, res);
271
233
  });
272
234
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/worker.ts"],"sourcesContent":["import spawn, { crossSpawn, type SpawnResult } from 'cross-spawn-cb';\nimport crypto from 'crypto';\nimport oo from 'on-one';\nimport Queue from 'queue-cb';\n\nimport createApp from './createApp.ts';\nimport addLines from './lib/addLines.ts';\nimport concatWritable from './lib/concatWritable.ts';\nimport formatArguments from './lib/formatArguments.ts';\n\nimport type { SpawnError, SpawnOptions, TerminalCallback, TerminalOptions } from './types.ts';\nimport { LineType } from './types.ts';\n\nconst terminal = createApp();\n\nexport default function spawnTerminal(command: string, args: string[], spawnOptions: SpawnOptions, options: TerminalOptions, callback: TerminalCallback): undefined {\n const { encoding, stdio, ...csOptions } = spawnOptions;\n\n if (stdio === 'inherit') {\n terminal.retain((store) => {\n const id = crypto.randomUUID();\n store.addProcess({ id, title: [command].concat(formatArguments(args)).join(' '), state: 'running', lines: [], ...options });\n\n const cp = crossSpawn(command, args, csOptions);\n const outputs = { stdout: null, stderr: null };\n\n const queue = new Queue();\n if (cp.stdout) {\n outputs.stdout = addLines((lines) => {\n const item = store.processes.find((x) => x.id === id);\n store.updateProcess({ ...item, lines: item.lines.concat(lines.map((text) => ({ type: LineType.stdout, text }))) });\n });\n queue.defer(oo.bind(null, cp.stdout.pipe(outputs.stdout), ['error', 'end', 'close', 'finish']));\n }\n if (cp.stderr) {\n outputs.stderr = addLines((lines) => {\n const item = store.processes.find((x) => x.id === id);\n store.updateProcess({ ...item, lines: item.lines.concat(lines.map((text) => ({ type: LineType.stderr, text }))) });\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.output : null;\n res.stderr = outputs.stderr ? outputs.stderr.output : null;\n res.output = [res.stdout, res.stderr, null];\n const item = store.processes.find((x) => x.id === id);\n store.updateProcess({ ...item, state: err ? 'error' : 'success' });\n\n terminal.release(() => {\n err ? callback(err) : callback(null, res);\n });\n });\n });\n } else {\n const cp = crossSpawn(command, args, csOptions);\n const outputs = { stdout: null, stderr: null };\n\n const queue = new Queue();\n if (cp.stdout) {\n outputs.stdout = concatWritable((output) => {\n outputs.stdout.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.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.output : null;\n res.stderr = outputs.stderr ? outputs.stderr.output : null;\n res.output = [res.stdout, res.stderr, null];\n err ? callback(err) : callback(null, res);\n });\n }\n}\n"],"names":["spawnTerminal","terminal","createApp","command","args","spawnOptions","options","callback","encoding","stdio","csOptions","retain","store","id","crypto","randomUUID","addProcess","title","concat","formatArguments","join","state","lines","cp","crossSpawn","outputs","stdout","stderr","queue","Queue","addLines","item","processes","find","x","updateProcess","map","text","type","LineType","defer","oo","bind","pipe","spawn","worker","await","err","res","output","release","concatWritable","toString"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/worker.ts"],"sourcesContent":["import spawn, { crossSpawn, type SpawnResult } from 'cross-spawn-cb';\nimport crypto from 'crypto';\nimport oo from 'on-one';\nimport Queue from 'queue-cb';\n\nimport createApp from './createApp.ts';\nimport addLines from './lib/addLines.ts';\nimport concatWritable from './lib/concatWritable.ts';\nimport formatArguments from './lib/formatArguments.ts';\n\nimport type { SpawnError, SpawnOptions, TerminalCallback, TerminalOptions } from './types.ts';\nimport { LineType } from './types.ts';\n\nconst terminal = createApp();\n\nexport default function spawnTerminal(command: string, args: string[], spawnOptions: SpawnOptions, options: TerminalOptions, callback: TerminalCallback): undefined {\n const { encoding, stdio, ...csOptions } = spawnOptions;\n\n if (stdio === 'inherit') {\n const store = terminal.retain();\n const id = crypto.randomUUID();\n store.addProcess({ id, title: [command].concat(formatArguments(args)).join(' '), state: 'running', lines: [], ...options });\n\n const cp = crossSpawn(command, args, csOptions);\n const outputs = { stdout: null, stderr: null };\n\n const queue = new Queue();\n if (cp.stdout) {\n outputs.stdout = addLines((lines) => {\n store.appendLines(\n id,\n lines.map((text) => ({ type: LineType.stdout, text }))\n );\n });\n queue.defer(oo.bind(null, cp.stdout.pipe(outputs.stdout), ['error', 'end', 'close', 'finish']));\n }\n if (cp.stderr) {\n outputs.stderr = addLines((lines) => {\n store.appendLines(\n id,\n lines.map((text) => ({ type: LineType.stderr, text }))\n );\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.output : null;\n res.stderr = outputs.stderr ? outputs.stderr.output : null;\n res.output = [res.stdout, res.stderr, null];\n store.updateProcess(id, { state: err ? 'error' : 'success' });\n\n terminal.release(() => {\n err ? callback(err) : callback(null, res);\n });\n });\n } else {\n const cp = crossSpawn(command, args, csOptions);\n const outputs = { stdout: null, stderr: null };\n\n const queue = new Queue();\n if (cp.stdout) {\n outputs.stdout = concatWritable((output) => {\n outputs.stdout.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.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.output : null;\n res.stderr = outputs.stderr ? outputs.stderr.output : null;\n res.output = [res.stdout, res.stderr, null];\n err ? callback(err) : callback(null, res);\n });\n }\n}\n"],"names":["spawnTerminal","terminal","createApp","command","args","spawnOptions","options","callback","encoding","stdio","csOptions","store","retain","id","crypto","randomUUID","addProcess","title","concat","formatArguments","join","state","lines","cp","crossSpawn","outputs","stdout","stderr","queue","Queue","addLines","appendLines","map","text","type","LineType","defer","oo","bind","pipe","spawn","worker","await","err","res","output","updateProcess","release","concatWritable","toString"],"mappings":"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"}
@@ -1,11 +1,111 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Box } from 'ink';
3
- import ChildProcess from './ChildProcess.js';
4
- export default function App({ store }) {
5
- return /*#__PURE__*/ _jsx(Box, {
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Box, Static, useApp, useInput, useStdin } from 'ink';
3
+ import { useEffect, useSyncExternalStore } from 'react';
4
+ import { processStore } from '../state/processStore.js';
5
+ import CompactProcessLine from './CompactProcessLine.js';
6
+ import Divider from './Divider.js';
7
+ import ErrorDetailModal from './ErrorDetailModal.js';
8
+ import ErrorListModal from './ErrorListModal.js';
9
+ import StatusBar from './StatusBar.js';
10
+ export default function App() {
11
+ const { exit } = useApp();
12
+ const { isRawModeSupported } = useStdin();
13
+ // Subscribe to store state
14
+ const processes = useSyncExternalStore(processStore.subscribe, processStore.getSnapshot);
15
+ const shouldExit = useSyncExternalStore(processStore.subscribe, processStore.getShouldExit);
16
+ const mode = useSyncExternalStore(processStore.subscribe, processStore.getMode);
17
+ const selectedErrorIndex = useSyncExternalStore(processStore.subscribe, processStore.getSelectedErrorIndex);
18
+ // Derived state
19
+ const completedProcesses = processStore.getCompletedProcesses();
20
+ const runningProcesses = processStore.getRunningProcesses();
21
+ const failedProcesses = processStore.getFailedProcesses();
22
+ const runningCount = processStore.getRunningCount();
23
+ const doneCount = processStore.getDoneCount();
24
+ const errorCount = processStore.getErrorCount();
25
+ const errorLineCount = processStore.getErrorLineCount();
26
+ // Handle exit signal
27
+ useEffect(()=>{
28
+ if (shouldExit) {
29
+ exit();
30
+ }
31
+ }, [
32
+ shouldExit,
33
+ exit
34
+ ]);
35
+ // Keyboard handling (only active when raw mode is supported)
36
+ useInput((input, key)=>{
37
+ if (mode === 'normal') {
38
+ if (input === 'e' && errorCount > 0) {
39
+ processStore.setMode('errorList');
40
+ }
41
+ } else if (mode === 'errorList') {
42
+ if (key.escape) {
43
+ processStore.setMode('normal');
44
+ } else if (key.downArrow) {
45
+ processStore.selectNextError();
46
+ } else if (key.upArrow) {
47
+ processStore.selectPrevError();
48
+ } else if (key.return) {
49
+ processStore.setMode('errorDetail');
50
+ }
51
+ } else if (mode === 'errorDetail') {
52
+ if (key.escape) {
53
+ processStore.setMode('errorList');
54
+ } else if (key.downArrow) {
55
+ processStore.selectNextError();
56
+ } else if (key.upArrow) {
57
+ processStore.selectPrevError();
58
+ }
59
+ }
60
+ }, {
61
+ isActive: isRawModeSupported === true
62
+ });
63
+ // Error list modal
64
+ if (mode === 'errorList') {
65
+ return /*#__PURE__*/ _jsx(ErrorListModal, {
66
+ errors: failedProcesses,
67
+ selectedIndex: selectedErrorIndex,
68
+ totalErrorLines: errorLineCount
69
+ });
70
+ }
71
+ // Error detail modal
72
+ if (mode === 'errorDetail') {
73
+ const selectedError = processStore.getSelectedError();
74
+ if (selectedError) {
75
+ return /*#__PURE__*/ _jsx(ErrorDetailModal, {
76
+ error: selectedError,
77
+ currentIndex: selectedErrorIndex,
78
+ totalErrors: failedProcesses.length
79
+ });
80
+ }
81
+ // Fallback if no error selected
82
+ processStore.setMode('errorList');
83
+ }
84
+ // Normal view
85
+ return /*#__PURE__*/ _jsxs(Box, {
6
86
  flexDirection: "column",
7
- children: store.processes.map((item)=>/*#__PURE__*/ _jsx(ChildProcess, {
8
- item: item
9
- }, item.id))
87
+ children: [
88
+ /*#__PURE__*/ _jsx(Static, {
89
+ items: completedProcesses,
90
+ children: (item)=>/*#__PURE__*/ _jsx(CompactProcessLine, {
91
+ item: item
92
+ }, item.id)
93
+ }),
94
+ completedProcesses.length > 0 && runningProcesses.length > 0 && /*#__PURE__*/ _jsx(Divider, {}),
95
+ runningProcesses.map((item)=>/*#__PURE__*/ _jsx(CompactProcessLine, {
96
+ item: item
97
+ }, item.id)),
98
+ processes.length > 0 && /*#__PURE__*/ _jsxs(_Fragment, {
99
+ children: [
100
+ /*#__PURE__*/ _jsx(Divider, {}),
101
+ /*#__PURE__*/ _jsx(StatusBar, {
102
+ running: runningCount,
103
+ done: doneCount,
104
+ errors: errorCount,
105
+ errorLines: errorLineCount
106
+ })
107
+ ]
108
+ })
109
+ ]
10
110
  });
11
111
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/App.tsx"],"sourcesContent":["import { Box } from 'ink';\nimport type Store from '../state/Store.ts';\nimport type { ChildProcess as ChildProcessT } from '../types.ts';\nimport ChildProcess from './ChildProcess.ts';\n\nexport interface AppProps {\n store: Store;\n}\n\nexport default function App({ store }: AppProps): React.JSX.Element {\n return (\n <Box flexDirection=\"column\">\n {store.processes.map((item: ChildProcessT) => (\n <ChildProcess key={item.id} item={item} />\n ))}\n </Box>\n );\n}\n"],"names":["Box","ChildProcess","App","store","flexDirection","processes","map","item","id"],"mappings":";AAAA,SAASA,GAAG,QAAQ,MAAM;AAG1B,OAAOC,kBAAkB,oBAAoB;AAM7C,eAAe,SAASC,IAAI,EAAEC,KAAK,EAAY;IAC7C,qBACE,KAACH;QAAII,eAAc;kBAChBD,MAAME,SAAS,CAACC,GAAG,CAAC,CAACC,qBACpB,KAACN;gBAA2BM,MAAMA;eAAfA,KAAKC,EAAE;;AAIlC"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/App.tsx"],"sourcesContent":["import { Box, Static, useApp, useInput, useStdin } from 'ink';\nimport { useEffect, useSyncExternalStore } from 'react';\nimport { processStore } from '../state/processStore.ts';\nimport CompactProcessLine from './CompactProcessLine.ts';\nimport Divider from './Divider.ts';\nimport ErrorDetailModal from './ErrorDetailModal.ts';\nimport ErrorListModal from './ErrorListModal.ts';\nimport StatusBar from './StatusBar.ts';\n\nexport default function App(): React.JSX.Element {\n const { exit } = useApp();\n const { isRawModeSupported } = useStdin();\n\n // Subscribe to store state\n const processes = useSyncExternalStore(processStore.subscribe, processStore.getSnapshot);\n const shouldExit = useSyncExternalStore(processStore.subscribe, processStore.getShouldExit);\n const mode = useSyncExternalStore(processStore.subscribe, processStore.getMode);\n const selectedErrorIndex = useSyncExternalStore(processStore.subscribe, processStore.getSelectedErrorIndex);\n\n // Derived state\n const completedProcesses = processStore.getCompletedProcesses();\n const runningProcesses = processStore.getRunningProcesses();\n const failedProcesses = processStore.getFailedProcesses();\n const runningCount = processStore.getRunningCount();\n const doneCount = processStore.getDoneCount();\n const errorCount = processStore.getErrorCount();\n const errorLineCount = processStore.getErrorLineCount();\n\n // Handle exit signal\n useEffect(() => {\n if (shouldExit) {\n exit();\n }\n }, [shouldExit, exit]);\n\n // Keyboard handling (only active when raw mode is supported)\n useInput(\n (input, key) => {\n if (mode === 'normal') {\n if (input === 'e' && errorCount > 0) {\n processStore.setMode('errorList');\n }\n } else if (mode === 'errorList') {\n if (key.escape) {\n processStore.setMode('normal');\n } else if (key.downArrow) {\n processStore.selectNextError();\n } else if (key.upArrow) {\n processStore.selectPrevError();\n } else if (key.return) {\n processStore.setMode('errorDetail');\n }\n } else if (mode === 'errorDetail') {\n if (key.escape) {\n processStore.setMode('errorList');\n } else if (key.downArrow) {\n processStore.selectNextError();\n } else if (key.upArrow) {\n processStore.selectPrevError();\n }\n }\n },\n { isActive: isRawModeSupported === true }\n );\n\n // Error list modal\n if (mode === 'errorList') {\n return <ErrorListModal errors={failedProcesses} selectedIndex={selectedErrorIndex} totalErrorLines={errorLineCount} />;\n }\n\n // Error detail modal\n if (mode === 'errorDetail') {\n const selectedError = processStore.getSelectedError();\n if (selectedError) {\n return <ErrorDetailModal error={selectedError} currentIndex={selectedErrorIndex} totalErrors={failedProcesses.length} />;\n }\n // Fallback if no error selected\n processStore.setMode('errorList');\n }\n\n // Normal view\n return (\n <Box flexDirection=\"column\">\n {/* Static area - completed processes (completion order) */}\n <Static items={completedProcesses}>{(item) => <CompactProcessLine key={item.id} item={item} />}</Static>\n\n {/* Divider between completed and running */}\n {completedProcesses.length > 0 && runningProcesses.length > 0 && <Divider />}\n\n {/* Dynamic area - running processes */}\n {runningProcesses.map((item) => (\n <CompactProcessLine key={item.id} item={item} />\n ))}\n\n {/* Status bar */}\n {processes.length > 0 && (\n <>\n <Divider />\n <StatusBar running={runningCount} done={doneCount} errors={errorCount} errorLines={errorLineCount} />\n </>\n )}\n </Box>\n );\n}\n"],"names":["Box","Static","useApp","useInput","useStdin","useEffect","useSyncExternalStore","processStore","CompactProcessLine","Divider","ErrorDetailModal","ErrorListModal","StatusBar","App","exit","isRawModeSupported","processes","subscribe","getSnapshot","shouldExit","getShouldExit","mode","getMode","selectedErrorIndex","getSelectedErrorIndex","completedProcesses","getCompletedProcesses","runningProcesses","getRunningProcesses","failedProcesses","getFailedProcesses","runningCount","getRunningCount","doneCount","getDoneCount","errorCount","getErrorCount","errorLineCount","getErrorLineCount","input","key","setMode","escape","downArrow","selectNextError","upArrow","selectPrevError","return","isActive","errors","selectedIndex","totalErrorLines","selectedError","getSelectedError","error","currentIndex","totalErrors","length","flexDirection","items","item","id","map","running","done","errorLines"],"mappings":"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"}
@@ -0,0 +1,134 @@
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
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
30
+ import { Box, Text, useStdout } from 'ink';
31
+ import { memo, useMemo } from 'react';
32
+ import figures from '../lib/figures.js';
33
+ import { LineType } from '../types.js';
34
+ import Spinner from './Spinner.js';
35
+ // From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2
36
+ const SPINNER = {
37
+ interval: 80,
38
+ frames: [
39
+ '⠋',
40
+ '⠙',
41
+ '⠹',
42
+ '⠸',
43
+ '⠼',
44
+ '⠴',
45
+ '⠦',
46
+ '⠧',
47
+ '⠇',
48
+ '⠏'
49
+ ]
50
+ };
51
+ function truncate(str, maxLength) {
52
+ if (str.length <= maxLength) return str;
53
+ return `${str.slice(0, maxLength - 1)}…`;
54
+ }
55
+ function getLastOutputLine(lines) {
56
+ for(let i = lines.length - 1; i >= 0; i--){
57
+ if (lines[i].text.length > 0) {
58
+ return lines[i].text;
59
+ }
60
+ }
61
+ return '';
62
+ }
63
+ function getErrorCount(lines) {
64
+ return lines.filter((line)=>line.type === LineType.stderr).length;
65
+ }
66
+ export default /*#__PURE__*/ memo(function CompactProcessLine({ item }) {
67
+ const { stdout } = useStdout();
68
+ const terminalWidth = (stdout === null || stdout === void 0 ? void 0 : stdout.columns) || 80;
69
+ const { group, title, state, lines } = item;
70
+ // Display name: prefer group, fall back to title
71
+ const displayName = group || title;
72
+ // Calculate widths - use fixed-width columns for alignment
73
+ const iconWidth = 2; // icon + space
74
+ const nameColumnWidth = 15; // fixed width for name column
75
+ const gap = 1; // space between name and status
76
+ const statusWidth = terminalWidth - iconWidth - nameColumnWidth - gap;
77
+ // Truncate name if needed and pad to column width
78
+ const truncatedName = truncate(displayName, nameColumnWidth).padEnd(nameColumnWidth);
79
+ // Status text based on state
80
+ const statusText = useMemo(()=>{
81
+ if (state === 'running') {
82
+ const lastLine = getLastOutputLine(lines);
83
+ return lastLine ? truncate(lastLine, statusWidth) : '';
84
+ }
85
+ if (state === 'error') {
86
+ const errorCount = getErrorCount(lines);
87
+ return errorCount > 0 ? `${errorCount} error${errorCount > 1 ? 's' : ''}` : 'failed';
88
+ }
89
+ return ''; // success - no status text
90
+ }, [
91
+ state,
92
+ lines,
93
+ statusWidth
94
+ ]);
95
+ // Icon based on state
96
+ const icon = useMemo(()=>{
97
+ switch(state){
98
+ case 'running':
99
+ return /*#__PURE__*/ _jsx(Spinner, _object_spread({}, SPINNER));
100
+ case 'success':
101
+ return /*#__PURE__*/ _jsx(Text, {
102
+ color: "green",
103
+ children: figures.tick
104
+ });
105
+ case 'error':
106
+ return /*#__PURE__*/ _jsx(Text, {
107
+ color: "red",
108
+ children: figures.cross
109
+ });
110
+ }
111
+ }, [
112
+ state
113
+ ]);
114
+ // Status text color
115
+ const statusColor = state === 'error' ? 'red' : 'gray';
116
+ return /*#__PURE__*/ _jsxs(Box, {
117
+ children: [
118
+ /*#__PURE__*/ _jsx(Box, {
119
+ width: iconWidth,
120
+ children: icon
121
+ }),
122
+ /*#__PURE__*/ _jsx(Text, {
123
+ children: truncatedName
124
+ }),
125
+ statusText && /*#__PURE__*/ _jsxs(Text, {
126
+ color: statusColor,
127
+ children: [
128
+ " ",
129
+ statusText
130
+ ]
131
+ })
132
+ ]
133
+ });
134
+ });
@@ -0,0 +1 @@
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 figures from '../lib/figures.ts';\nimport type { ChildProcess, Line } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\n// From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2\nconst SPINNER = {\n interval: 80,\n frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n};\n\ntype Props = {\n item: ChildProcess;\n};\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return `${str.slice(0, maxLength - 1)}…`;\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 }: Props) {\n const { stdout } = useStdout();\n const terminalWidth = stdout?.columns || 80;\n\n const { group, title, state, lines } = item;\n\n // Display name: prefer group, fall back to title\n const displayName = group || title;\n\n // Calculate widths - use fixed-width columns for alignment\n const iconWidth = 2; // icon + space\n const nameColumnWidth = 15; // fixed width for name column\n const gap = 1; // space between name and status\n const statusWidth = terminalWidth - iconWidth - nameColumnWidth - gap;\n\n // Truncate name if needed and pad to column width\n const truncatedName = truncate(displayName, nameColumnWidth).padEnd(nameColumnWidth);\n\n // Status text based on state\n const statusText = useMemo(() => {\n if (state === 'running') {\n const lastLine = getLastOutputLine(lines);\n return lastLine ? truncate(lastLine, statusWidth) : '';\n }\n if (state === 'error') {\n const errorCount = getErrorCount(lines);\n return errorCount > 0 ? `${errorCount} error${errorCount > 1 ? 's' : ''}` : 'failed';\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>\n <Box width={iconWidth}>{icon}</Box>\n <Text>{truncatedName}</Text>\n {statusText && <Text color={statusColor}> {statusText}</Text>}\n </Box>\n );\n});\n"],"names":["Box","Text","useStdout","memo","useMemo","figures","LineType","Spinner","SPINNER","interval","frames","truncate","str","maxLength","length","slice","getLastOutputLine","lines","i","text","getErrorCount","filter","line","type","stderr","CompactProcessLine","item","stdout","terminalWidth","columns","group","title","state","displayName","iconWidth","nameColumnWidth","gap","statusWidth","truncatedName","padEnd","statusText","lastLine","errorCount","icon","color","tick","cross","statusColor","width"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAASA,GAAG,EAAEC,IAAI,EAAEC,SAAS,QAAQ,MAAM;AAC3C,SAASC,IAAI,EAAEC,OAAO,QAAQ,QAAQ;AACtC,OAAOC,aAAa,oBAAoB;AAExC,SAASC,QAAQ,QAAQ,cAAc;AACvC,OAAOC,aAAa,eAAe;AAEnC,oHAAoH;AACpH,MAAMC,UAAU;IACdC,UAAU;IACVC,QAAQ;QAAC;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;KAAI;AAC5D;AAMA,SAASC,SAASC,GAAW,EAAEC,SAAiB;IAC9C,IAAID,IAAIE,MAAM,IAAID,WAAW,OAAOD;IACpC,OAAO,GAAGA,IAAIG,KAAK,CAAC,GAAGF,YAAY,GAAG,CAAC,CAAC;AAC1C;AAEA,SAASG,kBAAkBC,KAAa;IACtC,IAAK,IAAIC,IAAID,MAAMH,MAAM,GAAG,GAAGI,KAAK,GAAGA,IAAK;QAC1C,IAAID,KAAK,CAACC,EAAE,CAACC,IAAI,CAACL,MAAM,GAAG,GAAG;YAC5B,OAAOG,KAAK,CAACC,EAAE,CAACC,IAAI;QACtB;IACF;IACA,OAAO;AACT;AAEA,SAASC,cAAcH,KAAa;IAClC,OAAOA,MAAMI,MAAM,CAAC,CAACC,OAASA,KAAKC,IAAI,KAAKjB,SAASkB,MAAM,EAAEV,MAAM;AACrE;AAEA,6BAAeX,KAAK,SAASsB,mBAAmB,EAAEC,IAAI,EAAS;IAC7D,MAAM,EAAEC,MAAM,EAAE,GAAGzB;IACnB,MAAM0B,gBAAgBD,CAAAA,mBAAAA,6BAAAA,OAAQE,OAAO,KAAI;IAEzC,MAAM,EAAEC,KAAK,EAAEC,KAAK,EAAEC,KAAK,EAAEf,KAAK,EAAE,GAAGS;IAEvC,iDAAiD;IACjD,MAAMO,cAAcH,SAASC;IAE7B,2DAA2D;IAC3D,MAAMG,YAAY,GAAG,eAAe;IACpC,MAAMC,kBAAkB,IAAI,8BAA8B;IAC1D,MAAMC,MAAM,GAAG,gCAAgC;IAC/C,MAAMC,cAAcT,gBAAgBM,YAAYC,kBAAkBC;IAElE,kDAAkD;IAClD,MAAME,gBAAgB3B,SAASsB,aAAaE,iBAAiBI,MAAM,CAACJ;IAEpE,6BAA6B;IAC7B,MAAMK,aAAapC,QAAQ;QACzB,IAAI4B,UAAU,WAAW;YACvB,MAAMS,WAAWzB,kBAAkBC;YACnC,OAAOwB,WAAW9B,SAAS8B,UAAUJ,eAAe;QACtD;QACA,IAAIL,UAAU,SAAS;YACrB,MAAMU,aAAatB,cAAcH;YACjC,OAAOyB,aAAa,IAAI,GAAGA,WAAW,MAAM,EAAEA,aAAa,IAAI,MAAM,IAAI,GAAG;QAC9E;QACA,OAAO,IAAI,2BAA2B;IACxC,GAAG;QAACV;QAAOf;QAAOoB;KAAY;IAE9B,sBAAsB;IACtB,MAAMM,OAAOvC,QAAQ;QACnB,OAAQ4B;YACN,KAAK;gBACH,qBAAO,KAACzB,4BAAYC;YACtB,KAAK;gBACH,qBAAO,KAACP;oBAAK2C,OAAM;8BAASvC,QAAQwC,IAAI;;YAC1C,KAAK;gBACH,qBAAO,KAAC5C;oBAAK2C,OAAM;8BAAOvC,QAAQyC,KAAK;;QAC3C;IACF,GAAG;QAACd;KAAM;IAEV,oBAAoB;IACpB,MAAMe,cAAcf,UAAU,UAAU,QAAQ;IAEhD,qBACE,MAAChC;;0BACC,KAACA;gBAAIgD,OAAOd;0BAAYS;;0BACxB,KAAC1C;0BAAMqC;;YACNE,4BAAc,MAACvC;gBAAK2C,OAAOG;;oBAAa;oBAAEP;;;;;AAGjD,GAAG"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text, useStdout } from 'ink';
3
+ import { memo } from 'react';
4
+ export default /*#__PURE__*/ memo(function Divider() {
5
+ const { stdout } = useStdout();
6
+ const width = (stdout === null || stdout === void 0 ? void 0 : stdout.columns) || 80;
7
+ return /*#__PURE__*/ _jsx(Box, {
8
+ children: /*#__PURE__*/ _jsx(Text, {
9
+ dimColor: true,
10
+ children: '─'.repeat(width)
11
+ })
12
+ });
13
+ });
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/Divider.tsx"],"sourcesContent":["import { Box, Text, useStdout } from 'ink';\nimport { memo } from 'react';\n\nexport default memo(function Divider() {\n const { stdout } = useStdout();\n const width = stdout?.columns || 80;\n\n return (\n <Box>\n <Text dimColor>{'─'.repeat(width)}</Text>\n </Box>\n );\n});\n"],"names":["Box","Text","useStdout","memo","Divider","stdout","width","columns","dimColor","repeat"],"mappings":";AAAA,SAASA,GAAG,EAAEC,IAAI,EAAEC,SAAS,QAAQ,MAAM;AAC3C,SAASC,IAAI,QAAQ,QAAQ;AAE7B,6BAAeA,KAAK,SAASC;IAC3B,MAAM,EAAEC,MAAM,EAAE,GAAGH;IACnB,MAAMI,QAAQD,CAAAA,mBAAAA,6BAAAA,OAAQE,OAAO,KAAI;IAEjC,qBACE,KAACP;kBACC,cAAA,KAACC;YAAKO,QAAQ;sBAAE,IAAIC,MAAM,CAACH;;;AAGjC,GAAG"}