@boba-cli/machine 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,443 @@
1
+ /**
2
+ * Color support levels for terminal output.
3
+ * @public
4
+ */
5
+ interface ColorSupport {
6
+ /** The maximum color level supported (0-3). */
7
+ readonly level: number;
8
+ /** Whether basic 16-color support is available. */
9
+ readonly hasBasic: boolean;
10
+ /** Whether 256-color support is available. */
11
+ readonly has256: boolean;
12
+ /** Whether 16 million (true color) support is available. */
13
+ readonly has16m: boolean;
14
+ }
15
+ /**
16
+ * Terminal background mode.
17
+ * @public
18
+ */
19
+ type TerminalBackground = 'dark' | 'light' | 'unknown';
20
+ /**
21
+ * Terminal dimensions.
22
+ * @public
23
+ */
24
+ interface TerminalSize {
25
+ /** Width in columns. */
26
+ readonly columns: number;
27
+ /** Height in rows. */
28
+ readonly rows: number;
29
+ }
30
+ /**
31
+ * Disposable resource that can be cleaned up.
32
+ * @public
33
+ */
34
+ interface Disposable {
35
+ /** Dispose of the resource. */
36
+ dispose(): void;
37
+ }
38
+ /**
39
+ * Handler for terminal input data.
40
+ * @public
41
+ */
42
+ type InputHandler = (data: Uint8Array) => void;
43
+ /**
44
+ * Handler for terminal resize events.
45
+ * @public
46
+ */
47
+ type ResizeHandler = (size: TerminalSize) => void;
48
+ /**
49
+ * Handler for signals (SIGINT, SIGTERM, etc.).
50
+ * @public
51
+ */
52
+ type SignalHandler = () => void;
53
+ /**
54
+ * Terminal adapter interface for platform-agnostic terminal operations.
55
+ * @public
56
+ */
57
+ interface TerminalAdapter extends Disposable {
58
+ /**
59
+ * Subscribe to input data.
60
+ * @param handler - Callback to receive input as Uint8Array
61
+ * @returns Disposable to unsubscribe
62
+ */
63
+ onInput(handler: InputHandler): Disposable;
64
+ /**
65
+ * Subscribe to resize events.
66
+ * @param handler - Callback to receive new terminal size
67
+ * @returns Disposable to unsubscribe
68
+ */
69
+ onResize(handler: ResizeHandler): Disposable;
70
+ /**
71
+ * Write data to the terminal output.
72
+ * @param data - String data to write
73
+ */
74
+ write(data: string): void;
75
+ /**
76
+ * Get the current terminal size.
77
+ * @returns Current terminal dimensions
78
+ */
79
+ getSize(): TerminalSize;
80
+ /**
81
+ * Enable raw mode (no line buffering, no echo).
82
+ */
83
+ enableRawMode(): void;
84
+ /**
85
+ * Disable raw mode.
86
+ */
87
+ disableRawMode(): void;
88
+ /**
89
+ * Check if the terminal is a TTY.
90
+ * @returns True if the terminal is a TTY
91
+ */
92
+ isTTY(): boolean;
93
+ }
94
+ /**
95
+ * Signal adapter interface for handling OS signals.
96
+ * @public
97
+ */
98
+ interface SignalAdapter extends Disposable {
99
+ /**
100
+ * Subscribe to interrupt signals (SIGINT in Node, beforeunload in browser).
101
+ * @param handler - Callback to invoke on interrupt
102
+ * @returns Disposable to unsubscribe
103
+ */
104
+ onInterrupt(handler: SignalHandler): Disposable;
105
+ /**
106
+ * Subscribe to termination signals (SIGTERM in Node).
107
+ * @param handler - Callback to invoke on termination
108
+ * @returns Disposable to unsubscribe
109
+ */
110
+ onTerminate(handler: SignalHandler): Disposable;
111
+ }
112
+ /**
113
+ * Clipboard adapter interface for platform-agnostic clipboard operations.
114
+ * @public
115
+ */
116
+ interface ClipboardAdapter {
117
+ /**
118
+ * Read text from the clipboard.
119
+ * @returns Promise resolving to clipboard text
120
+ */
121
+ read(): Promise<string>;
122
+ /**
123
+ * Write text to the clipboard.
124
+ * @param text - Text to write
125
+ * @returns Promise resolving when complete
126
+ */
127
+ write(text: string): Promise<void>;
128
+ /**
129
+ * Check if clipboard operations are available.
130
+ * @returns True if clipboard is available
131
+ */
132
+ isAvailable(): boolean;
133
+ }
134
+ /**
135
+ * Environment adapter interface for platform-agnostic environment access.
136
+ * @public
137
+ */
138
+ interface EnvironmentAdapter {
139
+ /**
140
+ * Get an environment variable value.
141
+ * @param name - Variable name
142
+ * @returns Variable value or undefined
143
+ */
144
+ get(name: string): string | undefined;
145
+ /**
146
+ * Get color support level.
147
+ * @returns Color support information
148
+ */
149
+ getColorSupport(): ColorSupport;
150
+ /**
151
+ * Detect terminal background mode.
152
+ * @returns Background mode (dark, light, or unknown)
153
+ */
154
+ getTerminalBackground(): TerminalBackground;
155
+ }
156
+ /**
157
+ * File stat information returned by filesystem operations.
158
+ * @public
159
+ */
160
+ interface FileStat {
161
+ /** File size in bytes. */
162
+ readonly size: number;
163
+ /** Unix file mode (permissions). */
164
+ readonly mode: number;
165
+ /** Last modification time. */
166
+ readonly mtime: Date;
167
+ /** Whether this is a directory. */
168
+ readonly isDirectory: boolean;
169
+ /** Whether this is a regular file. */
170
+ readonly isFile: boolean;
171
+ /** Whether this is a symbolic link. */
172
+ readonly isSymbolicLink: boolean;
173
+ }
174
+ /**
175
+ * Directory entry returned by readdir with withFileTypes option.
176
+ * @public
177
+ */
178
+ interface DirectoryEntry {
179
+ /** Name of the file or directory. */
180
+ readonly name: string;
181
+ /** Check if this entry is a directory. */
182
+ isDirectory(): boolean;
183
+ /** Check if this entry is a regular file. */
184
+ isFile(): boolean;
185
+ /** Check if this entry is a symbolic link. */
186
+ isSymbolicLink(): boolean;
187
+ }
188
+ /**
189
+ * FileSystem adapter interface for platform-agnostic file operations.
190
+ * @public
191
+ */
192
+ interface FileSystemAdapter {
193
+ /**
194
+ * Read directory contents.
195
+ * @param path - Directory path
196
+ * @param options - Options for reading directory
197
+ * @returns Array of directory entries or file names
198
+ */
199
+ readdir(path: string, options?: {
200
+ withFileTypes?: boolean;
201
+ }): Promise<DirectoryEntry[] | string[]>;
202
+ /**
203
+ * Get file/directory stats.
204
+ * @param path - File or directory path
205
+ * @returns File stat information
206
+ */
207
+ stat(path: string): Promise<FileStat>;
208
+ /**
209
+ * Read file contents as text.
210
+ * @param path - File path
211
+ * @param encoding - Text encoding (default: 'utf-8')
212
+ * @returns File contents as string
213
+ */
214
+ readFile(path: string, encoding?: string): Promise<string>;
215
+ /**
216
+ * Write text to a file.
217
+ * @param path - File path
218
+ * @param content - Text content to write
219
+ * @returns Promise resolving when complete
220
+ */
221
+ writeFile(path: string, content: string): Promise<void>;
222
+ /**
223
+ * Check if a file or directory exists.
224
+ * @param path - File or directory path
225
+ * @returns True if the path exists
226
+ */
227
+ exists(path: string): Promise<boolean>;
228
+ /**
229
+ * Create a directory.
230
+ * @param path - Directory path
231
+ * @param options - Options for directory creation
232
+ * @returns Promise resolving when complete
233
+ */
234
+ mkdir(path: string, options?: {
235
+ recursive?: boolean;
236
+ }): Promise<void>;
237
+ /**
238
+ * Delete a file.
239
+ * @param path - File path
240
+ * @returns Promise resolving when complete
241
+ */
242
+ unlink(path: string): Promise<void>;
243
+ /**
244
+ * Remove a directory.
245
+ * @param path - Directory path
246
+ * @param options - Options for directory removal
247
+ * @returns Promise resolving when complete
248
+ */
249
+ rmdir(path: string, options?: {
250
+ recursive?: boolean;
251
+ force?: boolean;
252
+ }): Promise<void>;
253
+ /**
254
+ * Rename or move a file or directory.
255
+ * @param src - Source path
256
+ * @param dst - Destination path
257
+ * @returns Promise resolving when complete
258
+ */
259
+ rename(src: string, dst: string): Promise<void>;
260
+ /**
261
+ * Copy a file.
262
+ * @param src - Source file path
263
+ * @param dst - Destination file path
264
+ * @returns Promise resolving when complete
265
+ */
266
+ copyFile(src: string, dst: string): Promise<void>;
267
+ /**
268
+ * Get current working directory.
269
+ * @returns Current working directory path
270
+ */
271
+ cwd(): string;
272
+ /**
273
+ * Get user's home directory.
274
+ * @returns Home directory path
275
+ */
276
+ homedir(): string;
277
+ }
278
+ /**
279
+ * Path adapter interface for platform-agnostic path operations.
280
+ * @public
281
+ */
282
+ interface PathAdapter {
283
+ /**
284
+ * Join path segments.
285
+ * @param segments - Path segments to join
286
+ * @returns Joined path
287
+ */
288
+ join(...segments: string[]): string;
289
+ /**
290
+ * Get directory name from path.
291
+ * @param path - File or directory path
292
+ * @returns Directory name
293
+ */
294
+ dirname(path: string): string;
295
+ /**
296
+ * Get base name from path.
297
+ * @param path - File or directory path
298
+ * @param ext - Optional extension to remove
299
+ * @returns Base name
300
+ */
301
+ basename(path: string, ext?: string): string;
302
+ /**
303
+ * Get file extension.
304
+ * @param path - File path
305
+ * @returns Extension (including dot)
306
+ */
307
+ extname(path: string): string;
308
+ /**
309
+ * Resolve path segments to absolute path.
310
+ * @param segments - Path segments to resolve
311
+ * @returns Absolute path
312
+ */
313
+ resolve(...segments: string[]): string;
314
+ /**
315
+ * Check if path is absolute.
316
+ * @param path - Path to check
317
+ * @returns True if path is absolute
318
+ */
319
+ isAbsolute(path: string): boolean;
320
+ /**
321
+ * Normalize a path.
322
+ * @param path - Path to normalize
323
+ * @returns Normalized path
324
+ */
325
+ normalize(path: string): string;
326
+ /**
327
+ * Platform-specific path separator.
328
+ */
329
+ readonly sep: string;
330
+ }
331
+ /**
332
+ * Archive adapter interface for zip/unzip operations.
333
+ * @public
334
+ */
335
+ interface ArchiveAdapter {
336
+ /**
337
+ * Create a zip archive from a directory.
338
+ * @param sourceDir - Source directory to archive
339
+ * @param destPath - Destination path for the zip file
340
+ */
341
+ zip(sourceDir: string, destPath: string): Promise<void>;
342
+ /**
343
+ * Extract a zip archive to a directory.
344
+ * @param archivePath - Path to the zip file
345
+ * @param destDir - Destination directory for extraction
346
+ */
347
+ unzip(archivePath: string, destDir: string): Promise<void>;
348
+ /**
349
+ * Check if archive operations are available.
350
+ * @returns True if archiving is supported on this platform
351
+ */
352
+ isAvailable(): boolean;
353
+ }
354
+ /**
355
+ * Chainable style function for terminal text styling.
356
+ * @public
357
+ */
358
+ interface StyleFn {
359
+ (text: string): string;
360
+ readonly bold: StyleFn;
361
+ readonly dim: StyleFn;
362
+ readonly italic: StyleFn;
363
+ readonly underline: StyleFn;
364
+ readonly strikethrough: StyleFn;
365
+ readonly inverse: StyleFn;
366
+ readonly hidden: StyleFn;
367
+ readonly black: StyleFn;
368
+ readonly red: StyleFn;
369
+ readonly green: StyleFn;
370
+ readonly yellow: StyleFn;
371
+ readonly blue: StyleFn;
372
+ readonly magenta: StyleFn;
373
+ readonly cyan: StyleFn;
374
+ readonly white: StyleFn;
375
+ readonly gray: StyleFn;
376
+ readonly grey: StyleFn;
377
+ readonly blackBright: StyleFn;
378
+ readonly redBright: StyleFn;
379
+ readonly greenBright: StyleFn;
380
+ readonly yellowBright: StyleFn;
381
+ readonly blueBright: StyleFn;
382
+ readonly magentaBright: StyleFn;
383
+ readonly cyanBright: StyleFn;
384
+ readonly whiteBright: StyleFn;
385
+ readonly bgBlack: StyleFn;
386
+ readonly bgRed: StyleFn;
387
+ readonly bgGreen: StyleFn;
388
+ readonly bgYellow: StyleFn;
389
+ readonly bgBlue: StyleFn;
390
+ readonly bgMagenta: StyleFn;
391
+ readonly bgCyan: StyleFn;
392
+ readonly bgWhite: StyleFn;
393
+ readonly bgBlackBright: StyleFn;
394
+ readonly bgRedBright: StyleFn;
395
+ readonly bgGreenBright: StyleFn;
396
+ readonly bgYellowBright: StyleFn;
397
+ readonly bgBlueBright: StyleFn;
398
+ readonly bgMagentaBright: StyleFn;
399
+ readonly bgCyanBright: StyleFn;
400
+ readonly bgWhiteBright: StyleFn;
401
+ hex(color: string): StyleFn;
402
+ rgb(r: number, g: number, b: number): StyleFn;
403
+ bgHex(color: string): StyleFn;
404
+ bgRgb(r: number, g: number, b: number): StyleFn;
405
+ ansi256(code: number): StyleFn;
406
+ bgAnsi256(code: number): StyleFn;
407
+ }
408
+ /**
409
+ * Style adapter for platform-agnostic terminal styling.
410
+ * @public
411
+ */
412
+ interface StyleAdapter {
413
+ /** The chainable style function. */
414
+ readonly style: StyleFn;
415
+ /** Whether styling is enabled. */
416
+ readonly enabled: boolean;
417
+ /** Color support level (0-3). */
418
+ readonly level: number;
419
+ }
420
+ /**
421
+ * Complete platform adapter combining all platform-specific functionality.
422
+ * @public
423
+ */
424
+ interface PlatformAdapter extends Disposable {
425
+ /** Terminal I/O adapter. */
426
+ readonly terminal: TerminalAdapter;
427
+ /** Signal handling adapter. */
428
+ readonly signals: SignalAdapter;
429
+ /** Clipboard operations adapter. */
430
+ readonly clipboard: ClipboardAdapter;
431
+ /** Environment access adapter. */
432
+ readonly environment: EnvironmentAdapter;
433
+ /** FileSystem operations adapter. */
434
+ readonly filesystem: FileSystemAdapter;
435
+ /** Path operations adapter. */
436
+ readonly path: PathAdapter;
437
+ /** Archive operations adapter. */
438
+ readonly archive: ArchiveAdapter;
439
+ /** Style adapter for terminal text styling. */
440
+ readonly style: StyleAdapter;
441
+ }
442
+
443
+ export type { ArchiveAdapter as A, ColorSupport as C, DirectoryEntry as D, EnvironmentAdapter as E, FileStat as F, InputHandler as I, PathAdapter as P, ResizeHandler as R, StyleFn as S, TerminalAdapter as T, ClipboardAdapter as a, Disposable as b, FileSystemAdapter as c, PlatformAdapter as d, SignalAdapter as e, SignalHandler as f, StyleAdapter as g, TerminalBackground as h, TerminalSize as i };
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@boba-cli/machine",
3
+ "description": "Platform abstraction layer for Boba terminal UIs",
4
+ "version": "0.1.0-alpha.1",
5
+ "devDependencies": {
6
+ "@types/archiver": "^6.0.4",
7
+ "@types/node": "^24.10.2",
8
+ "@types/unzipper": "^0.10.11",
9
+ "@vitest/ui": "^4.0.16",
10
+ "archiver": "^7.0.1",
11
+ "clipboardy": "^4.0.0",
12
+ "happy-dom": "^20.0.11",
13
+ "typescript": "5.8.2",
14
+ "unzipper": "^0.12.3",
15
+ "vitest": "^4.0.16"
16
+ },
17
+ "engines": {
18
+ "node": ">=20.0.0"
19
+ },
20
+ "exports": {
21
+ ".": {
22
+ "import": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "require": {
27
+ "types": "./dist/index.d.cts",
28
+ "default": "./dist/index.cjs"
29
+ }
30
+ },
31
+ "./node": {
32
+ "import": {
33
+ "types": "./dist/node/index.d.ts",
34
+ "default": "./dist/node/index.js"
35
+ },
36
+ "require": {
37
+ "types": "./dist/node/index.d.cts",
38
+ "default": "./dist/node/index.cjs"
39
+ }
40
+ },
41
+ "./browser": {
42
+ "import": {
43
+ "types": "./dist/browser/index.d.ts",
44
+ "default": "./dist/browser/index.js"
45
+ },
46
+ "require": {
47
+ "types": "./dist/browser/index.d.cts",
48
+ "default": "./dist/browser/index.cjs"
49
+ }
50
+ },
51
+ "./package.json": "./package.json"
52
+ },
53
+ "files": [
54
+ "dist"
55
+ ],
56
+ "license": "MIT",
57
+ "main": "./dist/index.cjs",
58
+ "module": "./dist/index.js",
59
+ "peerDependencies": {
60
+ "@xterm/xterm": "^5.0.0",
61
+ "archiver": "^7.0.0",
62
+ "clipboardy": "^4.0.0",
63
+ "supports-color": "^9.0.0",
64
+ "unzipper": "^0.12.0"
65
+ },
66
+ "peerDependenciesMeta": {
67
+ "archiver": {
68
+ "optional": true
69
+ },
70
+ "clipboardy": {
71
+ "optional": true
72
+ },
73
+ "supports-color": {
74
+ "optional": true
75
+ },
76
+ "unzipper": {
77
+ "optional": true
78
+ },
79
+ "@xterm/xterm": {
80
+ "optional": true
81
+ }
82
+ },
83
+ "sideEffects": false,
84
+ "type": "module",
85
+ "types": "./dist/index.d.ts",
86
+ "scripts": {
87
+ "build": "tsup",
88
+ "check:api-report": "api-extractor run",
89
+ "generate:api-report": "api-extractor run --local",
90
+ "lint": "eslint \"{src,test}/**/*.{ts,tsx}\"",
91
+ "test": "vitest run",
92
+ "test:browser": "vitest run test/browser",
93
+ "test:graceful-degradation": "vitest run -t \"\\[graceful-degradation\\]\""
94
+ }
95
+ }