@gachlab/devup 0.7.0 → 0.8.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 (65) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +4 -2
  3. package/dist/control-plane/client.d.ts +17 -0
  4. package/dist/control-plane/client.d.ts.map +1 -0
  5. package/dist/control-plane/socket-server.d.ts +6 -0
  6. package/dist/control-plane/socket-server.d.ts.map +1 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +2653 -1713
  9. package/dist/index.js.map +1 -1
  10. package/dist/orchestrator/config-watcher.d.ts +22 -0
  11. package/dist/orchestrator/config-watcher.d.ts.map +1 -0
  12. package/dist/orchestrator/daemon.d.ts +38 -0
  13. package/dist/orchestrator/daemon.d.ts.map +1 -0
  14. package/dist/orchestrator/subcommands.d.ts +7 -0
  15. package/dist/orchestrator/subcommands.d.ts.map +1 -1
  16. package/dist/process/health-poller.d.ts +15 -0
  17. package/dist/process/health-poller.d.ts.map +1 -0
  18. package/dist/process/internals.d.ts +14 -0
  19. package/dist/process/internals.d.ts.map +1 -0
  20. package/dist/process/lifecycle.d.ts +31 -0
  21. package/dist/process/lifecycle.d.ts.map +1 -0
  22. package/dist/process/manager.d.ts +11 -13
  23. package/dist/process/manager.d.ts.map +1 -1
  24. package/dist/process/restarter.d.ts +26 -0
  25. package/dist/process/restarter.d.ts.map +1 -0
  26. package/dist/process/spawner.d.ts +38 -0
  27. package/dist/process/spawner.d.ts.map +1 -0
  28. package/dist/tui/App.d.ts.map +1 -1
  29. package/dist/tui/hooks/useBootSequence.d.ts +20 -0
  30. package/dist/tui/hooks/useBootSequence.d.ts.map +1 -0
  31. package/dist/tui/hooks/useContextualTips.d.ts +6 -0
  32. package/dist/tui/hooks/useContextualTips.d.ts.map +1 -0
  33. package/dist/tui/hooks/useControlPlane.d.ts +18 -0
  34. package/dist/tui/hooks/useControlPlane.d.ts.map +1 -0
  35. package/dist/tui/hooks/useHotReload.d.ts +6 -0
  36. package/dist/tui/hooks/useHotReload.d.ts.map +1 -0
  37. package/dist/tui/hooks/useLogsPause.d.ts +4 -0
  38. package/dist/tui/hooks/useLogsPause.d.ts.map +1 -0
  39. package/dist/tui/hooks/useProcessManager.d.ts +9 -0
  40. package/dist/tui/hooks/useProcessManager.d.ts.map +1 -1
  41. package/dist/tui/hooks/useTerminalSize.d.ts +4 -0
  42. package/dist/tui/hooks/useTerminalSize.d.ts.map +1 -0
  43. package/dist/utils/broadcaster.d.ts +6 -0
  44. package/dist/utils/broadcaster.d.ts.map +1 -0
  45. package/dist/utils/colors.d.ts +4 -0
  46. package/dist/utils/colors.d.ts.map +1 -0
  47. package/dist/utils/env.d.ts +5 -0
  48. package/dist/utils/env.d.ts.map +1 -0
  49. package/dist/utils/format.d.ts +3 -0
  50. package/dist/utils/format.d.ts.map +1 -0
  51. package/dist/utils/install-stamp.d.ts +6 -0
  52. package/dist/utils/install-stamp.d.ts.map +1 -0
  53. package/dist/utils/phases.d.ts +4 -0
  54. package/dist/utils/phases.d.ts.map +1 -0
  55. package/dist/utils/process-args.d.ts +8 -0
  56. package/dist/utils/process-args.d.ts.map +1 -0
  57. package/dist/utils/redact.d.ts +4 -0
  58. package/dist/utils/redact.d.ts.map +1 -0
  59. package/dist/utils/search.d.ts +17 -0
  60. package/dist/utils/search.d.ts.map +1 -0
  61. package/dist/utils/stats.d.ts +19 -0
  62. package/dist/utils/stats.d.ts.map +1 -0
  63. package/dist/utils.d.ts +10 -41
  64. package/dist/utils.d.ts.map +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1,22 @@
1
+ import type { ProcessManager } from '../process/manager.js';
2
+ export interface ConfigWatchOpts {
3
+ configPath: string;
4
+ baseCwd: string;
5
+ manager: ProcessManager;
6
+ /** Receives status lines: success, validation errors, reload errors. */
7
+ log: (msg: string) => void;
8
+ }
9
+ /** Re-loads the config, validates it, diffs against the running set, and
10
+ * applies add/remove/restart at the service level. A failed validation
11
+ * leaves the running set untouched. Pure (idempotent given the same
12
+ * config file + manager state), so both the TUI hook and the daemon
13
+ * can call it directly. */
14
+ export declare function applyConfigChange(opts: ConfigWatchOpts): Promise<void>;
15
+ /** Watch a config file and call applyConfigChange on each save, debounced
16
+ * to 250 ms. Uses `fs.watchFile` (polling, 500 ms) rather than `fs.watch`
17
+ * for cross-platform reliability — `fs.watch` on a single file is flaky
18
+ * on macOS (FSEvents) and has its own quirks on Windows. Polling a single
19
+ * file every 500 ms is negligible cost for a long-running daemon.
20
+ * In-flight guard coalesces back-to-back saves. Returns a cleanup function. */
21
+ export declare function watchConfig(opts: ConfigWatchOpts): () => void;
22
+ //# sourceMappingURL=config-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-watcher.d.ts","sourceRoot":"","sources":["../../src/orchestrator/config-watcher.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC;IACxB,wEAAwE;IACxE,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5B;AAED;;;;4BAI4B;AAC5B,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC5E;AAED;;;;;gFAKgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,IAAI,CA6B7D"}
@@ -0,0 +1,38 @@
1
+ import type { DevStackConfig, ServiceConfig } from '../config/types.js';
2
+ import type { CliArgs } from '../config/cli.js';
3
+ import type { Platform } from '../platform/types.js';
4
+ import type { ProxyConfigProvider, ProxyOpts } from '../proxy-config/types.js';
5
+ export declare function pidPathFor(projectName: string): string;
6
+ export declare function bootErrorPathFor(projectName: string): string;
7
+ /** Inspect the PID file. `pid=null` means no daemon recorded.
8
+ * `stale=true` means a pid file exists but the recorded pid is not alive. */
9
+ export declare function isDaemonRunning(projectName: string): {
10
+ pid: number | null;
11
+ stale: boolean;
12
+ };
13
+ export interface DaemonOpts {
14
+ config: DevStackConfig;
15
+ services: ServiceConfig[];
16
+ cliArgs: CliArgs;
17
+ platform: Platform;
18
+ env: Record<string, string>;
19
+ baseCwd: string;
20
+ proxyProvider: ProxyConfigProvider | null;
21
+ proxyOpts: ProxyOpts | null;
22
+ }
23
+ /** Runs in the detached child process. Boots the stack, opens the control
24
+ * plane, writes the PID file when ready (the parent's success signal), then
25
+ * stays alive until SIGTERM/SIGINT. */
26
+ export declare function daemonBody(opts: DaemonOpts): Promise<void>;
27
+ export interface DetachedOpts extends DaemonOpts {
28
+ out?: (line: string) => void;
29
+ }
30
+ /** Runs in the parent process. Validates state, spawns the daemon child
31
+ * detached, polls for the PID file (ready) or boot-error file (failure),
32
+ * prints the welcome line, and returns the exit code. */
33
+ export declare function runDetached(opts: DetachedOpts): Promise<number>;
34
+ export declare function stopDaemon(projectName: string, opts?: {
35
+ out?: (line: string) => void;
36
+ gracePeriodMs?: number;
37
+ }): Promise<number>;
38
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/orchestrator/daemon.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAgB,MAAM,0BAA0B,CAAC;AAO7F,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AACD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5D;AAMD;8EAC8E;AAC9E,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAW3F;AAID,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;CAC7B;AAED;;wCAEwC;AACxC,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2JhE;AA6ED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED;;0DAE0D;AAC1D,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAkErE;AAID,wBAAsB,UAAU,CAC9B,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GAClE,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
@@ -13,6 +13,13 @@ export declare function runInstall(opts: SubOpts & {
13
13
  concurrency?: number;
14
14
  }): Promise<number>;
15
15
  export declare function runStatus(opts: SubOpts): Promise<number>;
16
+ interface CtlOpts {
17
+ config: DevStackConfig;
18
+ out?: (line: string) => void;
19
+ socketPath?: string;
20
+ }
21
+ export declare function runCtl(argv: string[], opts: CtlOpts): Promise<number>;
22
+ export declare function runDown(opts: SubOpts): Promise<number>;
16
23
  export declare function runHelp(argv: string[], opts?: {
17
24
  out?: (l: string) => void;
18
25
  }): number;
@@ -1 +1 @@
1
- {"version":3,"file":"subcommands.d.ts","sourceRoot":"","sources":["../../src/orchestrator/subcommands.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIzD,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED,UAAU,OAAO;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAaD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB5E;AAoCD,wBAAsB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+B1F;AAiBD,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAe9D;AAID,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GAAG,MAAM,CA4BxF"}
1
+ {"version":3,"file":"subcommands.d.ts","sourceRoot":"","sources":["../../src/orchestrator/subcommands.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIzD,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED,UAAU,OAAO;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAaD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB5E;AAoCD,wBAAsB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+B1F;AAiBD,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAe9D;AAID,UAAU,OAAO;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAoBD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA0F3E;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5D;AAID,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GAAG,MAAM,CA0DxF"}
@@ -0,0 +1,15 @@
1
+ import type { ProcessState, ProcessManagerEvents } from './types.js';
2
+ interface HealthPollerOpts {
3
+ state: Map<string, ProcessState>;
4
+ events: ProcessManagerEvents;
5
+ }
6
+ /** Runs one round of health probes across every service in `state`.
7
+ * Suppresses probes during `healthCheck.startPeriod` grace window. */
8
+ export declare class HealthPoller {
9
+ private readonly state;
10
+ private readonly events;
11
+ constructor(opts: HealthPollerOpts);
12
+ checkAll(): Promise<void>;
13
+ }
14
+ export {};
15
+ //# sourceMappingURL=health-poller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-poller.d.ts","sourceRoot":"","sources":["../../src/process/health-poller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGrE,UAAU,gBAAgB;IACxB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED;uEACuE;AACvE,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,IAAI,EAAE,gBAAgB;IAK5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBhC"}
@@ -0,0 +1,14 @@
1
+ /** Buffered line splitter. Calls `onLine` for every newline-terminated chunk,
2
+ * preserves leftover for the next push. `flush()` emits any remaining tail. */
3
+ export declare function lineBuffer(onLine: (line: string) => void): {
4
+ push(chunk: Buffer): void;
5
+ flush(): void;
6
+ };
7
+ /** Accepts both '/foo/' (vim-style) and bare 'foo'. Case-insensitive by default. */
8
+ export declare function compileReadyPattern(pattern: string | undefined): RegExp | null;
9
+ /** Extracts the value tokens of `--watch` / `--watch-path` / `--watch=X` / `--watch-path=X`
10
+ * from a command's args list. Accepts both `--flag value` and `--flag=value` forms. */
11
+ export declare function extractWatchPaths(args: string[]): string[];
12
+ export declare const MAX_RESTARTS = 3;
13
+ export declare const BACKOFF_BASE_MS = 2000;
14
+ //# sourceMappingURL=internals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../../src/process/internals.ts"],"names":[],"mappings":"AAAA;gFACgF;AAChF,wBAAgB,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;gBAGzC,MAAM;;EAarB;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAS9E;AAED;wFACwF;AACxF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAgB1D;AAED,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,eAAe,OAAO,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { ChildProcess } from 'node:child_process';
2
+ import type { Platform } from '../platform/types.js';
3
+ import type { ProcessState } from './types.js';
4
+ interface LifecycleOpts {
5
+ state: Map<string, ProcessState>;
6
+ procs: Set<ChildProcess>;
7
+ platform: Platform;
8
+ }
9
+ /** Owns the kill-tree, watchBuild teardown, and graceful cleanup with SIGKILL
10
+ * fallback. Stateless beyond what's passed in via opts. */
11
+ export declare class Lifecycle {
12
+ private readonly state;
13
+ private readonly procs;
14
+ private readonly platform;
15
+ constructor(opts: LifecycleOpts);
16
+ /** Manual / external stop of a single service. Marks `intentionalStop` so the
17
+ * close handler doesn't auto-restart, kills the process tree, tears down the
18
+ * side-car watchBuild process if any. */
19
+ stop(name: string): void;
20
+ /** Tears down the side-car `watchBuild` process for a service (if any) and
21
+ * clears the reference. Safe to call repeatedly. */
22
+ stopWatchProc(state: ProcessState): void;
23
+ /** Graceful shutdown of every spawned process. Waits `gracePeriodMs` (default
24
+ * 3000) for clean exits, then SIGKILLs anything still alive. */
25
+ cleanup(opts?: {
26
+ gracePeriodMs?: number;
27
+ }): Promise<void>;
28
+ private findStateByProc;
29
+ }
30
+ export {};
31
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/process/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,UAAU,aAAa;IACrB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED;4DAC4D;AAC5D,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;gBAExB,IAAI,EAAE,aAAa;IAM/B;;8CAE0C;IAC1C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQxB;yDACqD;IACrD,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAOxC;qEACiE;IAC3D,OAAO,CAAC,IAAI,GAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CnE,OAAO,CAAC,eAAe;CAIxB"}
@@ -1,18 +1,23 @@
1
1
  import type { Platform } from '../platform/types.js';
2
2
  import type { ServiceConfig } from '../config/types.js';
3
3
  import type { ProcessState, ProcessManagerEvents } from './types.js';
4
- /** Accepts both '/foo/' (vim-style) and bare 'foo'. Case-insensitive by default. */
5
- export declare function compileReadyPattern(pattern: string | undefined): RegExp | null;
6
- /** Extracts the value tokens of `--watch` / `--watch-path` / `--watch=X` / `--watch-path=X`
7
- * from a command's args list. Accepts both `--flag value` and `--flag=value` forms. */
8
- export declare function extractWatchPaths(args: string[]): string[];
4
+ export { compileReadyPattern, extractWatchPaths } from './internals.js';
5
+ /** Thin facade composing Spawner, Restarter, HealthPoller, and Lifecycle.
6
+ * All four components share the same `state` Map and `procs` Set, so
7
+ * mutations from one are visible to the others.
8
+ *
9
+ * Public API is unchanged from the pre-refactor monolithic class —
10
+ * every TUI / orchestrator / control-plane call site keeps working. */
9
11
  export declare class ProcessManager {
10
12
  readonly state: Map<string, ProcessState>;
11
13
  private readonly procs;
12
14
  private readonly baseCwd;
13
15
  private readonly env;
14
- private readonly platform;
15
16
  private readonly events;
17
+ private readonly spawner;
18
+ private readonly restarter;
19
+ private readonly healthPoller;
20
+ private readonly lifecycle;
16
21
  constructor(opts: {
17
22
  baseCwd: string;
18
23
  env: Record<string, string>;
@@ -21,18 +26,11 @@ export declare class ProcessManager {
21
26
  });
22
27
  install(svc: ServiceConfig, colorIdx?: number): Promise<boolean>;
23
28
  start(svc: ServiceConfig, colorIdx: number, isRestart?: boolean): Promise<void>;
24
- private runPreBuild;
25
- private spawnWatchBuild;
26
- /** Create a state entry in 'crashed' status without spawning a process (used when preBuild fails). */
27
- private recordCrashedState;
28
29
  stop(name: string): void;
29
- private stopWatchProc;
30
30
  restart(name: string): Promise<void>;
31
31
  checkAllHealth(): Promise<void>;
32
32
  cleanup(opts?: {
33
33
  gracePeriodMs?: number;
34
34
  }): Promise<void>;
35
- private findStateByProc;
36
- private log;
37
35
  }
38
36
  //# sourceMappingURL=manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/process/manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQrE,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAS9E;AAED;wFACwF;AACxF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAgB1D;AAoBD,qBAAa,cAAc;IACzB,QAAQ,CAAC,KAAK,4BAAmC;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,IAAI,EAAE;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5B,QAAQ,EAAE,QAAQ,CAAC;QACnB,MAAM,EAAE,oBAAoB,CAAC;KAC9B;IAOK,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMhE,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAgHnF,OAAO,CAAC,WAAW;IA+BnB,OAAO,CAAC,eAAe;IAgBvB,sGAAsG;IACtG,OAAO,CAAC,kBAAkB;IAc1B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQxB,OAAO,CAAC,aAAa;IAOf,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB/B,OAAO,CAAC,IAAI,GAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAyCnE,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,GAAG;CAGZ"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/process/manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQrE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExE;;;;;wEAKwE;AACxE,qBAAa,cAAc;IACzB,QAAQ,CAAC,KAAK,4BAAmC;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,IAAI,EAAE;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5B,QAAQ,EAAE,QAAQ,CAAC;QACnB,MAAM,EAAE,oBAAoB,CAAC;KAC9B;IA6BD,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMhE,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7E,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,OAAO,CAAC,IAAI,GAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAG9D"}
@@ -0,0 +1,26 @@
1
+ import type { ServiceConfig } from '../config/types.js';
2
+ import type { ProcessState, ProcessManagerEvents } from './types.js';
3
+ import type { Spawner } from './spawner.js';
4
+ import type { Lifecycle } from './lifecycle.js';
5
+ interface RestarterOpts {
6
+ state: Map<string, ProcessState>;
7
+ events: ProcessManagerEvents;
8
+ spawner: Spawner;
9
+ lifecycle: Lifecycle;
10
+ }
11
+ /** Two responsibilities:
12
+ * 1. Manual restart (`restart(name)`) — full stop + respawn, **resets** the
13
+ * auto-restart counter so the user gets a fresh budget.
14
+ * 2. Auto-restart on crash (`scheduleAutoRestart`) — exponential backoff,
15
+ * capped at MAX_RESTARTS. Spawner invokes this in its close handler. */
16
+ export declare class Restarter {
17
+ private readonly state;
18
+ private readonly events;
19
+ private readonly spawner;
20
+ private readonly lifecycle;
21
+ constructor(opts: RestarterOpts);
22
+ restart(name: string): Promise<void>;
23
+ scheduleAutoRestart(svc: ServiceConfig, state: ProcessState, colorIdx: number): void;
24
+ }
25
+ export {};
26
+ //# sourceMappingURL=restarter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restarter.d.ts","sourceRoot":"","sources":["../../src/process/restarter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,UAAU,aAAa;IACrB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED;;;;4EAI4E;AAC5E,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,IAAI,EAAE,aAAa;IAOzB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1C,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAUrF"}
@@ -0,0 +1,38 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ import type { ServiceConfig } from '../config/types.js';
3
+ import type { ProcessState, ProcessManagerEvents } from './types.js';
4
+ import type { Lifecycle } from './lifecycle.js';
5
+ interface SpawnerOpts {
6
+ baseCwd: string;
7
+ env: Record<string, string>;
8
+ state: Map<string, ProcessState>;
9
+ procs: Set<ChildProcess>;
10
+ events: ProcessManagerEvents;
11
+ lifecycle: Lifecycle;
12
+ /** Called when a service exits non-zero, so the Restarter can schedule auto-restart. */
13
+ onCrash: (svc: ServiceConfig, state: ProcessState, colorIdx: number) => void;
14
+ }
15
+ /** Owns the spawn lifecycle: port check → preBuild → watch-path pre-flight →
16
+ * spawn → wire stdio (readyPattern + errorPattern + log) → watchBuild → close
17
+ * handler. On crash, delegates to `onCrash` (the Restarter wires this). */
18
+ export declare class Spawner {
19
+ private readonly baseCwd;
20
+ private readonly env;
21
+ private readonly state;
22
+ private readonly procs;
23
+ private readonly events;
24
+ private readonly lifecycle;
25
+ private readonly onCrash;
26
+ constructor(opts: SpawnerOpts);
27
+ start(svc: ServiceConfig, colorIdx: number, isRestart?: boolean): Promise<void>;
28
+ private wireStdio;
29
+ private wireCloseHandler;
30
+ private runPreBuild;
31
+ private spawnWatchBuild;
32
+ /** Create a state entry in 'crashed' status without spawning a process
33
+ * (used when preBuild fails or pre-flight checks fail). */
34
+ private recordCrashedState;
35
+ private log;
36
+ }
37
+ export {};
38
+ //# sourceMappingURL=spawner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawner.d.ts","sourceRoot":"","sources":["../../src/process/spawner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;IACzB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,wFAAwF;IACxF,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9E;AAED;;4EAE4E;AAC5E,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;gBAErC,IAAI,EAAE,WAAW;IAUvB,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA4DnF,OAAO,CAAC,SAAS;IA0BjB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,WAAW;IA+BnB,OAAO,CAAC,eAAe;IAgBvB;gEAC4D;IAC5D,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,GAAG;CAGZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAwBtD;;8FAE8F;AAC9F,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,MAAM,CAUR;AAED,UAAU,KAAK;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACzB;AAED,wBAAgB,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,KAAK,2CA8UlH"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAkBtD;;8FAE8F;AAC9F,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,MAAM,CAUR;AAED,UAAU,KAAK;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACzB;AAED,wBAAgB,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,KAAK,2CA6FlH"}
@@ -0,0 +1,20 @@
1
+ import type { Platform } from '../../platform/types.js';
2
+ import type { DevStackConfig, ServiceConfig } from '../../config/types.js';
3
+ import type { CliArgs } from '../../config/cli.js';
4
+ import type { ProcessManager } from '../../process/manager.js';
5
+ import { type LazyProxy } from '../../lazy/proxy.js';
6
+ import { type ExternalProc } from '../../process/external.js';
7
+ interface BootRefs {
8
+ lazyProxies: React.RefObject<Map<string, LazyProxy>>;
9
+ externals: React.RefObject<ExternalProc[]>;
10
+ }
11
+ /** Orchestrates the boot:
12
+ * 1. Externals first (docker compose etc.) — abort if any unhealthy.
13
+ * 2. In lazy mode: start always-on services in phase order, register lazy
14
+ * TCP proxies for the rest.
15
+ * 3. In normal mode: start every service in phase order.
16
+ *
17
+ * Within each phase, APIs are awaited via waitForPort; webs are not. */
18
+ export declare function useBootSequence(manager: ProcessManager | null, config: DevStackConfig, services: ServiceConfig[], cliArgs: CliArgs, platform: Platform, env: Record<string, string>, baseCwd: string, refs: BootRefs, pushLog: (svc: string, msg: string, colorIdx?: number) => void): void;
19
+ export {};
20
+ //# sourceMappingURL=useBootSequence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBootSequence.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useBootSequence.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAK/D,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9E,UAAU,QAAQ;IAChB,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IACrD,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;CAC5C;AAED;;;;;;yEAMyE;AACzE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,GAAG,IAAI,EAC9B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,GAC7D,IAAI,CA6GN"}
@@ -0,0 +1,6 @@
1
+ import type { ProcessState } from '../../process/types.js';
2
+ /** Surfaces a one-liner tip in teachable moments (high log volume, crash
3
+ * loop, etc.). Each tip shows at most once per session and auto-clears
4
+ * after 12 s. */
5
+ export declare function useContextualTips(totalLogs: number, hasSearch: boolean, hasFilter: boolean, states: Map<string, ProcessState>): string | null;
6
+ //# sourceMappingURL=useContextualTips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useContextualTips.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useContextualTips.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAI3D;;kBAEkB;AAClB,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,GAChC,MAAM,GAAG,IAAI,CAqBf"}
@@ -0,0 +1,18 @@
1
+ import type { ProcessManager } from '../../process/manager.js';
2
+ import type { LogSink } from '../../process/log-sink.js';
3
+ import type { Broadcaster } from '../../utils/broadcaster.js';
4
+ import type { ProcessState } from '../../process/types.js';
5
+ import { type SocketServerHandle } from '../../control-plane/socket-server.js';
6
+ /** Lifecycle of the Unix-socket JSON-RPC control plane. Mounts when the
7
+ * manager is ready; tears down on unmount.
8
+ *
9
+ * On listen failure (perms, dir missing, port already-in-use on the inode)
10
+ * devup keeps running without the control plane and logs a single notice. */
11
+ export declare function useControlPlane(manager: ProcessManager | null, projectName: string, logSink: LogSink | null, pushLog: (svc: string, msg: string, colorIdx?: number) => void, logBus: Broadcaster<{
12
+ svc: string;
13
+ text: string;
14
+ }>, stateBus: Broadcaster<{
15
+ name: string;
16
+ state: ProcessState;
17
+ }>): React.RefObject<SocketServerHandle | null>;
18
+ //# sourceMappingURL=useControlPlane.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useControlPlane.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useControlPlane.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAElG;;;;8EAI8E;AAC9E,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,GAAG,IAAI,EAC9B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,EAC9D,MAAM,EAAE,WAAW,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,QAAQ,EAAE,WAAW,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC,GAC3D,KAAK,CAAC,SAAS,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAwC5C"}
@@ -0,0 +1,6 @@
1
+ import type { ProcessManager } from '../../process/manager.js';
2
+ import type { CliArgs } from '../../config/cli.js';
3
+ /** Watches the resolved config file when --watch-config is on. Bridge between
4
+ * React's lifecycle and the pure `watchConfig` helper used by the daemon. */
5
+ export declare function useHotReload(manager: ProcessManager | null, cliArgs: CliArgs, baseCwd: string, pushLog: (svc: string, msg: string, colorIdx?: number) => void): void;
6
+ //# sourceMappingURL=useHotReload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHotReload.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useHotReload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAInD;8EAC8E;AAC9E,wBAAgB,YAAY,CAC1B,OAAO,EAAE,cAAc,GAAG,IAAI,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,GAC7D,IAAI,CAgBN"}
@@ -0,0 +1,4 @@
1
+ /** Couples the keyboard pause state (explicit `p` toggle OR auto-pause when
2
+ * scrolled up) with the process manager's logs sink. */
3
+ export declare function useLogsPause(setPaused: (paused: boolean) => void, logsPaused: boolean, logsScrollOffset: number): void;
4
+ //# sourceMappingURL=useLogsPause.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLogsPause.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useLogsPause.ts"],"names":[],"mappings":"AAEA;yDACyD;AACzD,wBAAgB,YAAY,CAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,EACpC,UAAU,EAAE,OAAO,EACnB,gBAAgB,EAAE,MAAM,GACvB,IAAI,CAIN"}
@@ -4,6 +4,7 @@ import type { Platform } from '../../platform/types.js';
4
4
  import type { ServiceConfig } from '../../config/types.js';
5
5
  import { type LogLevel } from '../../utils.js';
6
6
  import { LogSink } from '../../process/log-sink.js';
7
+ import { Broadcaster } from '../../utils/broadcaster.js';
7
8
  export interface LogEntry {
8
9
  svcName: string;
9
10
  text: string;
@@ -28,5 +29,13 @@ export declare function useProcessManager(platform: Platform, baseCwd: string, e
28
29
  setPaused: (paused: boolean) => void;
29
30
  pushLog: (svcName: string, text: string, colorIdx?: number) => void;
30
31
  manager: ProcessManager | null;
32
+ logBus: Broadcaster<{
33
+ svc: string;
34
+ text: string;
35
+ }>;
36
+ stateBus: Broadcaster<{
37
+ name: string;
38
+ state: ProcessState;
39
+ }>;
31
40
  };
32
41
  //# sourceMappingURL=useProcessManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useProcessManager.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useProcessManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAkC,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEpD,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,OAAO,GAAE,OAAO,GAAG,IAAW;;;;iBAuGH,aAAa,YAAY,MAAM;iBAC/B,MAAM;oBACH,MAAM;mBACP,aAAa,YAAY,MAAM;;;wBAjBrB,OAAO;uBAhBR,MAAM,QAAQ,MAAM;;EAwC3D"}
1
+ {"version":3,"file":"useProcessManager.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useProcessManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAkC,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,OAAO,GAAE,OAAO,GAAG,IAAW;;;;iBAgHH,aAAa,YAAY,MAAM;iBAC/B,MAAM;oBACH,MAAM;mBACP,aAAa,YAAY,MAAM;;;wBAjBrB,OAAO;uBAjBR,MAAM,QAAQ,MAAM;;;aApEb,MAAM;cAAQ,MAAM;;;cACjB,MAAM;eAAS,YAAY;;EA8G5E"}
@@ -0,0 +1,4 @@
1
+ /** Returns the current terminal row count, re-rendering on resize.
2
+ * Falls back to 40 when stdout isn't available (non-TTY mode). */
3
+ export declare function useTerminalSize(): number;
4
+ //# sourceMappingURL=useTerminalSize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTerminalSize.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useTerminalSize.ts"],"names":[],"mappings":"AAGA;mEACmE;AACnE,wBAAgB,eAAe,IAAI,MAAM,CAUxC"}
@@ -0,0 +1,6 @@
1
+ export declare class Broadcaster<T> {
2
+ private readonly subs;
3
+ subscribe(fn: (v: T) => void): () => void;
4
+ emit(v: T): void;
5
+ }
6
+ //# sourceMappingURL=broadcaster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcaster.d.ts","sourceRoot":"","sources":["../../src/utils/broadcaster.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW,CAAC,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAElD,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAKzC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI;CAKjB"}
@@ -0,0 +1,4 @@
1
+ /** Color palette used for the service-tag prefix in the logs panel.
2
+ * Wrapped modulo length when there are more services than entries. */
3
+ export declare const tagColors: string[];
4
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/utils/colors.ts"],"names":[],"mappings":"AAAA;uEACuE;AACvE,eAAO,MAAM,SAAS,UAIrB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** Reads a `.env`-style file and overlays it on top of `baseEnv`.
2
+ * Lines starting with `#` are comments. Quoted values get the quotes stripped.
3
+ * Existing keys in `baseEnv` win — file values only fill the gaps. */
4
+ export declare function parseEnvFile(filePath: string, baseEnv?: Record<string, string>): Record<string, string>;
5
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAEA;;uEAEuE;AACvE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiB3G"}
@@ -0,0 +1,3 @@
1
+ /** Formats a duration (in ms) as a short human string: 45s, 2m5s, 1h2m, 2d3h. */
2
+ export declare function fmtUptime(ms: number): string;
3
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAU5C"}
@@ -0,0 +1,6 @@
1
+ /** Returns true if the service's node_modules is missing or its install stamp
2
+ * doesn't match the current package.json hash. */
3
+ export declare function needsInstall(fullCwd: string): boolean;
4
+ /** Writes the install stamp file for a service after a successful `npm install`. */
5
+ export declare function writeInstallStamp(fullCwd: string): void;
6
+ //# sourceMappingURL=install-stamp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-stamp.d.ts","sourceRoot":"","sources":["../../src/utils/install-stamp.ts"],"names":[],"mappings":"AAIA;mDACmD;AACnD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CASrD;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKvD"}
@@ -0,0 +1,4 @@
1
+ import type { ServiceConfig } from '../config/types.js';
2
+ /** Groups a flat list of services by their `phase` field. */
3
+ export declare function groupByPhase(services: ServiceConfig[]): Record<number, ServiceConfig[]>;
4
+ //# sourceMappingURL=phases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phases.d.ts","sourceRoot":"","sources":["../../src/utils/phases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAMvF"}
@@ -0,0 +1,8 @@
1
+ import type { ServiceConfig } from '../config/types.js';
2
+ /** Builds the final args list for spawning a service: prepends `--max-old-space-size`
3
+ * for `node` commands when maxMem is set, plus any nodeArgs overrides. */
4
+ export declare function buildProcessArgs(svc: ServiceConfig): string[];
5
+ /** Builds the env for spawning a service: merges extraEnv and injects
6
+ * NODE_OPTIONS=--max-old-space-size when maxMem is set and cmd != 'node'. */
7
+ export declare function buildProcessEnv(svc: ServiceConfig, baseEnv: Record<string, string>): Record<string, string>;
8
+ //# sourceMappingURL=process-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-args.d.ts","sourceRoot":"","sources":["../../src/utils/process-args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;2EAC2E;AAC3E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,EAAE,CAK7D;AAED;8EAC8E;AAC9E,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU3G"}
@@ -0,0 +1,4 @@
1
+ /** Returns the env record with values redacted to *** for keys that look
2
+ * secret-ish (token / password / secret / key / auth). Case-insensitive. */
3
+ export declare function redactSecrets(env: Record<string, string> | undefined): Record<string, string>;
4
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/utils/redact.ts"],"names":[],"mappings":"AAAA;6EAC6E;AAC7E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO7F"}
@@ -0,0 +1,17 @@
1
+ export interface SearchMatcher {
2
+ test: (line: string) => boolean;
3
+ /** Set when the input was a vim-style /pattern/flags — used to drive highlighting. */
4
+ regex?: RegExp;
5
+ /** True when input started with `/` but produced an invalid regex; UI may show a hint. */
6
+ invalid?: boolean;
7
+ }
8
+ /** Compiles a search term to a matcher.
9
+ * - `/foo/` → regex (case-insensitive by default; honors flags after the closing slash)
10
+ * - anything else → case-insensitive substring (existing behavior)
11
+ * - invalid regex → falls back to substring, sets `invalid: true` */
12
+ export declare function compileSearchPattern(term: string | null): SearchMatcher | null;
13
+ export type LogLevel = 'error' | 'warn' | 'info';
14
+ /** Detects the level of a log line by case-insensitive keyword priority:
15
+ * error (and synonyms) > warn > info. Used by the L-level filter. */
16
+ export declare function detectLogLevel(line: string): LogLevel;
17
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/utils/search.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAChC,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;sEAGsE;AACtE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI,CAe9E;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD;sEACsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAMrD"}
@@ -0,0 +1,19 @@
1
+ /** Returns a copy of `names` sorted by the requested mode.
2
+ * - `'name'` → alphabetical
3
+ * - `'mem'` → highest mem first (string-parsed)
4
+ * - any other (treated as `'errors'`) → highest error count first */
5
+ export declare function sortServiceNames(names: string[], sortMode: string, statsMap: Record<string, {
6
+ cpu?: string;
7
+ mem?: string;
8
+ }>, procState: Record<string, {
9
+ errors?: number;
10
+ }>): string[];
11
+ /** Converts cumulative CPU seconds into a percentage of wall-clock time
12
+ * elapsed since the previous sample. */
13
+ export declare function calcCpuPercent(totalCpuSec: number, prevCpu: number, prevTime: number): number;
14
+ /** Hysteresis state machine for the "RAM pressure" banner.
15
+ * - turns on when usagePct ≥ highWatermark
16
+ * - turns off when usagePct < lowWatermark
17
+ * - stays as-is in the dead band between watermarks */
18
+ export declare function nextRamBannerVisibility(usagePct: number, previousVisible: boolean, highWatermark?: number, lowWatermark?: number): boolean;
19
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/utils/stats.ts"],"names":[],"mappings":"AAAA;;;sEAGsE;AACtE,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACxD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7C,MAAM,EAAE,CAQV;AAED;yCACyC;AACzC,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI7F;AAED;;;wDAGwD;AACxD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,OAAO,EACxB,aAAa,SAAK,EAClB,YAAY,SAAK,GAChB,OAAO,CAIT"}