@@ -139,34 +139,34 @@ Central orchestrator for all service lifecycles.
139139
140140``` typescript
141141interface ServiceState {
142- name: string ;
143- status: " stopped" | " starting" | " running" | " stopping" | " crashed" | " failed" ;
144- pid? : number ;
145- startedAt? : Date ;
146- exitCode? : number ;
147- port? : number ;
148- error? : string ;
142+ name: string
143+ status: " stopped" | " starting" | " running" | " stopping" | " crashed" | " failed"
144+ pid? : number
145+ startedAt? : Date
146+ exitCode? : number
147+ port? : number
148+ error? : string
149149}
150150
151151class ProcessManager extends EventEmitter {
152152 // Start a single service (resolves dependencies first)
153- async start(name : string ): Promise <void >;
153+ async start(name : string ): Promise <void >
154154
155155 // Start all services in dependency order
156- async startAll(): Promise <void >;
156+ async startAll(): Promise <void >
157157
158158 // Stop a service gracefully
159- async stop(name : string ): Promise <void >;
159+ async stop(name : string ): Promise <void >
160160
161161 // Stop all services (reverse dependency order)
162- async stopAll(): Promise <void >;
162+ async stopAll(): Promise <void >
163163
164164 // Restart a service
165- async restart(name : string ): Promise <void >;
165+ async restart(name : string ): Promise <void >
166166
167167 // Get current state
168- getState(name : string ): ServiceState ;
169- getAllStates(): ServiceState [];
168+ getState(name : string ): ServiceState
169+ getAllStates(): ServiceState []
170170
171171 // Events: 'state-change', 'log', 'error'
172172}
@@ -178,36 +178,36 @@ Manages log lines per service with configurable buffer size.
178178
179179``` typescript
180180interface LogLine {
181- timestamp: Date ;
182- service: string ;
183- content: string ;
184- stream: " stdout" | " stderr" ;
181+ timestamp: Date
182+ service: string
183+ content: string
184+ stream: " stdout" | " stderr"
185185}
186186
187187interface LogBuffer {
188188 // Add log line
189- append(service : string , line : string , stream : " stdout" | " stderr" ): void ;
189+ append(service : string , line : string , stream : " stdout" | " stderr" ): void
190190
191191 // Get logs for a service (most recent N lines)
192- get(service : string , limit ? : number ): LogLine [];
192+ get(service : string , limit ? : number ): LogLine []
193193
194194 // Get interleaved logs from all services
195- getAll(limit ? : number ): LogLine [];
195+ getAll(limit ? : number ): LogLine []
196196
197197 // Clear logs for a service
198- clear(service : string ): void ;
198+ clear(service : string ): void
199199}
200200```
201201
202202#### 3. UI State Management
203203
204204``` typescript
205205interface AppState {
206- services: ServiceState [];
207- selectedService: string | null ;
208- viewMode: " single" | " all" ; // View one service's logs or all interleaved
209- following: boolean ; // Auto-scroll to new logs
210- filter: string ; // Log search/filter
206+ services: ServiceState []
207+ selectedService: string | null
208+ viewMode: " single" | " all" // View one service's logs or all interleaved
209+ following: boolean // Auto-scroll to new logs
210+ filter: string // Log search/filter
211211}
212212```
213213
@@ -301,14 +301,14 @@ Start with config types and validation - this defines the contract for everythin
301301
302302``` typescript
303303// src/config/schema.ts
304- import { z } from " zod" ;
304+ import { z } from " zod"
305305
306306const HealthcheckSchema = z .object ({
307307 cmd: z .string (),
308308 interval: z .string ().default (" 2s" ),
309309 timeout: z .string ().default (" 5s" ),
310310 retries: z .number ().default (10 ),
311- });
311+ })
312312
313313const ServiceSchema = z .object ({
314314 cmd: z .string (),
@@ -319,14 +319,14 @@ const ServiceSchema = z.object({
319319 restart: z .enum ([" no" , " on-failure" , " always" ]).default (" no" ),
320320 color: z .string ().optional (),
321321 stop_signal: z .string ().default (" SIGTERM" ),
322- });
322+ })
323323
324324export const ConfigSchema = z .object ({
325325 name: z .string (),
326326 env: z .record (z .string ()).optional (),
327327 dotenv: z .string ().optional (),
328328 services: z .record (ServiceSchema ),
329- });
329+ })
330330```
331331
332332### Step 3: Process Spawner
@@ -335,7 +335,7 @@ Basic child process management using Bun's spawn API.
335335
336336``` typescript
337337// src/process/spawner.ts
338- import { spawn , type Subprocess } from " bun" ;
338+ import { spawn , type Subprocess } from " bun"
339339
340340export function spawnService(config : ServiceConfig ): Subprocess {
341341 const proc = spawn ({
@@ -344,9 +344,9 @@ export function spawnService(config: ServiceConfig): Subprocess {
344344 env: { ... process .env , ... config .env },
345345 stdout: " pipe" ,
346346 stderr: " pipe" ,
347- });
347+ })
348348
349- return proc ;
349+ return proc
350350}
351351```
352352
@@ -356,7 +356,7 @@ Start with the layout structure, then fill in components.
356356
357357``` tsx
358358// src/app.tsx
359- import { Box , Text , ScrollBox } from " @opentui/solid" ;
359+ import { Box , Text , ScrollBox } from " @opentui/solid"
360360
361361export function App() {
362362 return (
@@ -371,7 +371,7 @@ export function App() {
371371 <LogPanel />
372372 </Box >
373373 </Box >
374- );
374+ )
375375}
376376```
377377
@@ -387,20 +387,20 @@ Connect process manager events to UI state updates using Solid's reactivity.
387387
388388``` typescript
389389// Example test
390- import { test , expect } from " bun:test" ;
391- import { resolveDependencyOrder } from " ./process/dependencies" ;
390+ import { test , expect } from " bun:test"
391+ import { resolveDependencyOrder } from " ./process/dependencies"
392392
393393test (" resolves dependency order correctly" , () => {
394394 const services = {
395395 web: { depends_on: [" api" ] },
396396 api: { depends_on: [" postgres" , " redis" ] },
397397 postgres: {},
398398 redis: {},
399- };
399+ }
400400
401- const order = resolveDependencyOrder (services );
402- expect (order ).toEqual ([" postgres" , " redis" , " api" , " web" ]);
403- });
401+ const order = resolveDependencyOrder (services )
402+ expect (order ).toEqual ([" postgres" , " redis" , " api" , " web" ])
403+ })
404404```
405405
406406## Key opentui Components to Use
0 commit comments