everything-dev 0.3.3 → 1.3.3

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 (313) hide show
  1. package/README.md +64 -0
  2. package/cli.js +10 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  4. package/dist/api-contract.cjs +172 -0
  5. package/dist/api-contract.cjs.map +1 -0
  6. package/dist/api-contract.mjs +171 -0
  7. package/dist/api-contract.mjs.map +1 -0
  8. package/dist/api.cjs +124 -0
  9. package/dist/api.cjs.map +1 -0
  10. package/dist/api.d.cts +36 -0
  11. package/dist/api.d.cts.map +1 -0
  12. package/dist/api.d.mts +36 -0
  13. package/dist/api.d.mts.map +1 -0
  14. package/dist/api.mjs +119 -0
  15. package/dist/api.mjs.map +1 -0
  16. package/dist/app.cjs +156 -0
  17. package/dist/app.cjs.map +1 -0
  18. package/dist/app.mjs +153 -0
  19. package/dist/app.mjs.map +1 -0
  20. package/dist/cli/catalog.cjs +30 -0
  21. package/dist/cli/catalog.cjs.map +1 -0
  22. package/dist/cli/catalog.mjs +29 -0
  23. package/dist/cli/catalog.mjs.map +1 -0
  24. package/dist/cli/help.cjs +16 -0
  25. package/dist/cli/help.cjs.map +1 -0
  26. package/dist/cli/help.mjs +16 -0
  27. package/dist/cli/help.mjs.map +1 -0
  28. package/dist/cli/init.cjs +287 -0
  29. package/dist/cli/init.cjs.map +1 -0
  30. package/dist/cli/init.d.cts +36 -0
  31. package/dist/cli/init.d.cts.map +1 -0
  32. package/dist/cli/init.d.mts +36 -0
  33. package/dist/cli/init.d.mts.map +1 -0
  34. package/dist/cli/init.mjs +279 -0
  35. package/dist/cli/init.mjs.map +1 -0
  36. package/dist/cli/parse.cjs +96 -0
  37. package/dist/cli/parse.cjs.map +1 -0
  38. package/dist/cli/parse.mjs +95 -0
  39. package/dist/cli/parse.mjs.map +1 -0
  40. package/dist/cli/prompts.cjs +42 -0
  41. package/dist/cli/prompts.cjs.map +1 -0
  42. package/dist/cli/prompts.mjs +41 -0
  43. package/dist/cli/prompts.mjs.map +1 -0
  44. package/dist/cli.cjs +167 -0
  45. package/dist/cli.cjs.map +1 -0
  46. package/dist/cli.d.cts +1 -0
  47. package/dist/cli.d.mts +1 -0
  48. package/dist/cli.mjs +166 -0
  49. package/dist/cli.mjs.map +1 -0
  50. package/dist/components/dev-view.cjs +307 -0
  51. package/dist/components/dev-view.cjs.map +1 -0
  52. package/dist/components/dev-view.mjs +306 -0
  53. package/dist/components/dev-view.mjs.map +1 -0
  54. package/dist/components/streaming-view.cjs +146 -0
  55. package/dist/components/streaming-view.cjs.map +1 -0
  56. package/dist/components/streaming-view.mjs +144 -0
  57. package/dist/components/streaming-view.mjs.map +1 -0
  58. package/dist/config.cjs +280 -0
  59. package/dist/config.cjs.map +1 -0
  60. package/dist/config.d.cts +35 -0
  61. package/dist/config.d.cts.map +1 -0
  62. package/dist/config.d.mts +35 -0
  63. package/dist/config.d.mts.map +1 -0
  64. package/dist/config.mjs +266 -0
  65. package/dist/config.mjs.map +1 -0
  66. package/dist/contract.cjs +209 -0
  67. package/dist/contract.cjs.map +1 -0
  68. package/dist/contract.d.cts +490 -0
  69. package/dist/contract.d.cts.map +1 -0
  70. package/dist/contract.d.mts +490 -0
  71. package/dist/contract.d.mts.map +1 -0
  72. package/dist/contract.meta.cjs +104 -0
  73. package/dist/contract.meta.cjs.map +1 -0
  74. package/dist/contract.meta.d.cts +141 -0
  75. package/dist/contract.meta.d.cts.map +1 -0
  76. package/dist/contract.meta.d.mts +141 -0
  77. package/dist/contract.meta.d.mts.map +1 -0
  78. package/dist/contract.meta.mjs +102 -0
  79. package/dist/contract.meta.mjs.map +1 -0
  80. package/dist/contract.mjs +186 -0
  81. package/dist/contract.mjs.map +1 -0
  82. package/dist/dev-logs.cjs +53 -0
  83. package/dist/dev-logs.cjs.map +1 -0
  84. package/dist/dev-logs.mjs +51 -0
  85. package/dist/dev-logs.mjs.map +1 -0
  86. package/dist/dev-session.cjs +195 -0
  87. package/dist/dev-session.cjs.map +1 -0
  88. package/dist/dev-session.mjs +194 -0
  89. package/dist/dev-session.mjs.map +1 -0
  90. package/dist/fastkv.cjs +89 -0
  91. package/dist/fastkv.cjs.map +1 -0
  92. package/dist/fastkv.d.cts +11 -0
  93. package/dist/fastkv.d.cts.map +1 -0
  94. package/dist/fastkv.d.mts +11 -0
  95. package/dist/fastkv.d.mts.map +1 -0
  96. package/dist/fastkv.mjs +82 -0
  97. package/dist/fastkv.mjs.map +1 -0
  98. package/dist/federation.server.cjs +27 -0
  99. package/dist/federation.server.cjs.map +1 -0
  100. package/dist/federation.server.mjs +27 -0
  101. package/dist/federation.server.mjs.map +1 -0
  102. package/dist/host.cjs +367 -0
  103. package/dist/host.cjs.map +1 -0
  104. package/dist/host.d.cts +22 -0
  105. package/dist/host.d.cts.map +1 -0
  106. package/dist/host.d.mts +22 -0
  107. package/dist/host.d.mts.map +1 -0
  108. package/dist/host.mjs +364 -0
  109. package/dist/host.mjs.map +1 -0
  110. package/dist/index.cjs +122 -0
  111. package/dist/index.d.cts +7 -0
  112. package/dist/index.d.mts +7 -0
  113. package/dist/index.mjs +9 -0
  114. package/dist/integrity.cjs +39 -0
  115. package/dist/integrity.cjs.map +1 -0
  116. package/dist/integrity.d.cts +7 -0
  117. package/dist/integrity.d.cts.map +1 -0
  118. package/dist/integrity.d.mts +7 -0
  119. package/dist/integrity.d.mts.map +1 -0
  120. package/dist/integrity.mjs +35 -0
  121. package/dist/integrity.mjs.map +1 -0
  122. package/dist/internal/manifest-normalizer.cjs +140 -0
  123. package/dist/internal/manifest-normalizer.cjs.map +1 -0
  124. package/dist/internal/manifest-normalizer.mjs +138 -0
  125. package/dist/internal/manifest-normalizer.mjs.map +1 -0
  126. package/dist/mf.cjs +77 -0
  127. package/dist/mf.cjs.map +1 -0
  128. package/dist/mf.d.cts +19 -0
  129. package/dist/mf.d.cts.map +1 -0
  130. package/dist/mf.d.mts +19 -0
  131. package/dist/mf.d.mts.map +1 -0
  132. package/dist/mf.mjs +71 -0
  133. package/dist/mf.mjs.map +1 -0
  134. package/dist/near-cli.cjs +196 -0
  135. package/dist/near-cli.cjs.map +1 -0
  136. package/dist/near-cli.mjs +193 -0
  137. package/dist/near-cli.mjs.map +1 -0
  138. package/dist/network.cjs +9 -0
  139. package/dist/network.cjs.map +1 -0
  140. package/dist/network.mjs +8 -0
  141. package/dist/network.mjs.map +1 -0
  142. package/dist/orchestrator.cjs +441 -0
  143. package/dist/orchestrator.cjs.map +1 -0
  144. package/dist/orchestrator.d.cts +40 -0
  145. package/dist/orchestrator.d.cts.map +1 -0
  146. package/dist/orchestrator.d.mts +40 -0
  147. package/dist/orchestrator.d.mts.map +1 -0
  148. package/dist/orchestrator.mjs +436 -0
  149. package/dist/orchestrator.mjs.map +1 -0
  150. package/dist/plugin.cjs +830 -0
  151. package/dist/plugin.cjs.map +1 -0
  152. package/dist/plugin.d.cts +347 -0
  153. package/dist/plugin.d.cts.map +1 -0
  154. package/dist/plugin.d.mts +348 -0
  155. package/dist/plugin.d.mts.map +1 -0
  156. package/dist/plugin.mjs +827 -0
  157. package/dist/plugin.mjs.map +1 -0
  158. package/dist/process-registry.cjs +120 -0
  159. package/dist/process-registry.cjs.map +1 -0
  160. package/dist/process-registry.d.cts +25 -0
  161. package/dist/process-registry.d.cts.map +1 -0
  162. package/dist/process-registry.d.mts +25 -0
  163. package/dist/process-registry.d.mts.map +1 -0
  164. package/dist/process-registry.mjs +119 -0
  165. package/dist/process-registry.mjs.map +1 -0
  166. package/dist/sdk.cjs +61 -0
  167. package/dist/sdk.d.cts +5 -0
  168. package/dist/sdk.d.mts +5 -0
  169. package/dist/sdk.mjs +6 -0
  170. package/dist/shared.cjs +143 -0
  171. package/dist/shared.cjs.map +1 -0
  172. package/dist/shared.d.cts +33 -0
  173. package/dist/shared.d.cts.map +1 -0
  174. package/dist/shared.d.mts +33 -0
  175. package/dist/shared.d.mts.map +1 -0
  176. package/dist/shared.mjs +140 -0
  177. package/dist/shared.mjs.map +1 -0
  178. package/dist/types.cjs +160 -0
  179. package/dist/types.cjs.map +1 -0
  180. package/dist/types.d.cts +269 -0
  181. package/dist/types.d.cts.map +1 -0
  182. package/dist/types.d.mts +269 -0
  183. package/dist/types.d.mts.map +1 -0
  184. package/dist/types.mjs +144 -0
  185. package/dist/types.mjs.map +1 -0
  186. package/dist/ui/head.cjs +67 -0
  187. package/dist/ui/head.cjs.map +1 -0
  188. package/dist/ui/head.d.cts +19 -0
  189. package/dist/ui/head.d.cts.map +1 -0
  190. package/dist/ui/head.d.mts +19 -0
  191. package/dist/ui/head.d.mts.map +1 -0
  192. package/dist/ui/head.mjs +61 -0
  193. package/dist/ui/head.mjs.map +1 -0
  194. package/dist/ui/index.cjs +32 -0
  195. package/dist/ui/index.d.cts +7 -0
  196. package/dist/ui/index.d.mts +7 -0
  197. package/dist/ui/index.mjs +6 -0
  198. package/dist/ui/metadata.cjs +106 -0
  199. package/dist/ui/metadata.cjs.map +1 -0
  200. package/dist/ui/metadata.d.cts +35 -0
  201. package/dist/ui/metadata.d.cts.map +1 -0
  202. package/dist/ui/metadata.d.mts +35 -0
  203. package/dist/ui/metadata.d.mts.map +1 -0
  204. package/dist/ui/metadata.mjs +100 -0
  205. package/dist/ui/metadata.mjs.map +1 -0
  206. package/dist/ui/router.cjs +56 -0
  207. package/dist/ui/router.cjs.map +1 -0
  208. package/dist/ui/router.d.cts +11 -0
  209. package/dist/ui/router.d.cts.map +1 -0
  210. package/dist/ui/router.d.mts +11 -0
  211. package/dist/ui/router.d.mts.map +1 -0
  212. package/dist/ui/router.mjs +51 -0
  213. package/dist/ui/router.mjs.map +1 -0
  214. package/dist/ui/runtime.cjs +65 -0
  215. package/dist/ui/runtime.cjs.map +1 -0
  216. package/dist/ui/runtime.d.cts +29 -0
  217. package/dist/ui/runtime.d.cts.map +1 -0
  218. package/dist/ui/runtime.d.mts +29 -0
  219. package/dist/ui/runtime.d.mts.map +1 -0
  220. package/dist/ui/runtime.mjs +53 -0
  221. package/dist/ui/runtime.mjs.map +1 -0
  222. package/dist/ui/types.cjs +0 -0
  223. package/dist/ui/types.d.cts +52 -0
  224. package/dist/ui/types.d.cts.map +1 -0
  225. package/dist/ui/types.d.mts +52 -0
  226. package/dist/ui/types.d.mts.map +1 -0
  227. package/dist/ui/types.mjs +1 -0
  228. package/dist/utils/banner.cjs +24 -0
  229. package/dist/utils/banner.cjs.map +1 -0
  230. package/dist/utils/banner.mjs +23 -0
  231. package/dist/utils/banner.mjs.map +1 -0
  232. package/dist/utils/linkify.cjs +15 -0
  233. package/dist/utils/linkify.cjs.map +1 -0
  234. package/dist/utils/linkify.mjs +14 -0
  235. package/dist/utils/linkify.mjs.map +1 -0
  236. package/dist/utils/run.cjs +40 -0
  237. package/dist/utils/run.cjs.map +1 -0
  238. package/dist/utils/run.mjs +39 -0
  239. package/dist/utils/run.mjs.map +1 -0
  240. package/dist/utils/theme.cjs +44 -0
  241. package/dist/utils/theme.cjs.map +1 -0
  242. package/dist/utils/theme.mjs +37 -0
  243. package/dist/utils/theme.mjs.map +1 -0
  244. package/package.json +269 -80
  245. package/src/api-contract.ts +309 -0
  246. package/src/api.ts +181 -0
  247. package/src/app.ts +346 -0
  248. package/src/cli/catalog.ts +49 -0
  249. package/src/cli/help.ts +13 -0
  250. package/src/cli/init.ts +386 -0
  251. package/src/cli/parse.ts +130 -0
  252. package/src/cli/prompts.ts +64 -0
  253. package/src/cli.ts +203 -1507
  254. package/src/components/dev-view.tsx +307 -255
  255. package/src/components/streaming-view.ts +164 -128
  256. package/src/config.ts +462 -532
  257. package/src/contract.meta.ts +96 -0
  258. package/src/contract.ts +164 -561
  259. package/src/dev-logs.ts +85 -0
  260. package/src/dev-session.ts +318 -0
  261. package/src/fastkv.ts +153 -0
  262. package/src/federation.server.ts +43 -0
  263. package/src/host.ts +526 -0
  264. package/src/index.ts +6 -3
  265. package/src/integrity.ts +54 -0
  266. package/src/internal/manifest-normalizer.ts +251 -0
  267. package/src/mf.ts +105 -0
  268. package/src/near-cli.ts +284 -0
  269. package/src/network.ts +3 -0
  270. package/src/orchestrator.ts +648 -0
  271. package/src/plugin.ts +1130 -2311
  272. package/src/process-registry.ts +154 -0
  273. package/src/scripts/sync-api-contract.ts +24 -0
  274. package/src/sdk.ts +14 -0
  275. package/src/shared.ts +206 -0
  276. package/src/types.ts +152 -206
  277. package/src/ui/head.ts +34 -27
  278. package/src/ui/index.ts +3 -3
  279. package/src/ui/metadata.ts +95 -0
  280. package/src/ui/router.ts +22 -6
  281. package/src/ui/runtime.ts +55 -6
  282. package/src/ui/types.ts +24 -11
  283. package/src/utils/banner.ts +10 -6
  284. package/src/utils/run.ts +26 -27
  285. package/src/utils/theme.ts +3 -66
  286. package/src/components/monitor-view.tsx +0 -475
  287. package/src/components/status-view.tsx +0 -173
  288. package/src/lib/env.ts +0 -109
  289. package/src/lib/near-cli.ts +0 -289
  290. package/src/lib/nova.ts +0 -266
  291. package/src/lib/orchestrator.ts +0 -276
  292. package/src/lib/process-registry.ts +0 -166
  293. package/src/lib/process.ts +0 -550
  294. package/src/lib/resource-monitor/assertions.ts +0 -234
  295. package/src/lib/resource-monitor/command.ts +0 -283
  296. package/src/lib/resource-monitor/diff.ts +0 -157
  297. package/src/lib/resource-monitor/errors.ts +0 -127
  298. package/src/lib/resource-monitor/index.ts +0 -305
  299. package/src/lib/resource-monitor/platform/darwin.ts +0 -306
  300. package/src/lib/resource-monitor/platform/index.ts +0 -35
  301. package/src/lib/resource-monitor/platform/linux.ts +0 -332
  302. package/src/lib/resource-monitor/platform/windows.ts +0 -298
  303. package/src/lib/resource-monitor/snapshot.ts +0 -217
  304. package/src/lib/resource-monitor/types.ts +0 -74
  305. package/src/lib/session-recorder/errors.ts +0 -102
  306. package/src/lib/session-recorder/flows/login.ts +0 -210
  307. package/src/lib/session-recorder/index.ts +0 -361
  308. package/src/lib/session-recorder/playwright.ts +0 -257
  309. package/src/lib/session-recorder/report.ts +0 -353
  310. package/src/lib/session-recorder/server.ts +0 -268
  311. package/src/lib/session-recorder/types.ts +0 -115
  312. package/src/lib/sync.ts +0 -1
  313. package/src/ui/files.ts +0 -134
@@ -4,148 +4,184 @@ import { colors, icons } from "../utils/theme";
4
4
  import type { ProcessState, ProcessStatus } from "./dev-view";
5
5
 
6
6
  const orange = chalk.hex("#ffaa00");
7
+ const PLUGIN_PREFIX = "plugin:";
7
8
 
8
9
  export interface StreamingViewHandle {
9
- updateProcess: (
10
- name: string,
11
- status: ProcessStatus,
12
- message?: string,
13
- ) => void;
14
- addLog: (source: string, line: string, isError?: boolean) => void;
15
- unmount: () => Promise<void> | void;
10
+ updateProcess: (name: string, status: ProcessStatus, message?: string) => void;
11
+ addLog: (source: string, line: string, isError?: boolean) => void;
12
+ unmount: () => Promise<void> | void;
16
13
  }
17
14
 
18
15
  const getTimestamp = (): string => {
19
- const now = new Date();
20
- return `${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}`;
16
+ const now = new Date();
17
+ return `${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}`;
21
18
  };
22
19
 
23
- const write = (text: string) => process.stdout.write(text + "\n");
20
+ const write = (text: string) => process.stdout.write(`${text}\n`);
24
21
 
25
22
  const getServiceColor = (name: string): ((s: string) => string) => {
26
- if (name === "host") return colors.cyan;
27
- if (name === "ui" || name === "ui-ssr") return colors.magenta;
28
- if (name === "api") return colors.blue;
29
- return colors.white;
23
+ if (name.startsWith(PLUGIN_PREFIX)) return orange;
24
+ if (name === "host") return colors.cyan;
25
+ if (name === "ui" || name === "ui-ssr") return colors.magenta;
26
+ if (name === "api") return colors.blue;
27
+ return colors.white;
28
+ };
29
+
30
+ const getDisplayName = (name: string): string => {
31
+ return name.startsWith(PLUGIN_PREFIX)
32
+ ? name.slice(PLUGIN_PREFIX.length).toUpperCase()
33
+ : name.toUpperCase();
34
+ };
35
+
36
+ const isPlugin = (name: string): boolean => name.startsWith(PLUGIN_PREFIX);
37
+
38
+ const getSectionedProcesses = (processes: ProcessState[]) => {
39
+ const plugins = processes.filter((p) => isPlugin(p.name));
40
+ const services = processes.filter((p) => !isPlugin(p.name));
41
+ const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];
42
+ if (plugins.length > 0) sections.push({ key: "plugins", title: "PLUGINS", processes: plugins });
43
+ if (services.length > 0)
44
+ sections.push({ key: "services", title: "SERVICES", processes: services });
45
+ return sections;
46
+ };
47
+
48
+ const getColumnWidths = (processes: ProcessState[]) => {
49
+ const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));
50
+ const source = Math.max(10, ...processes.map((p) => (p.source ? ` (${p.source})`.length : 0)));
51
+ return { name, source };
30
52
  };
31
53
 
32
54
  const getStatusIcon = (status: ProcessStatus): string => {
33
- switch (status) {
34
- case "pending":
35
- return icons.pending;
36
- case "starting":
37
- return icons.scan;
38
- case "ready":
39
- return icons.ok;
40
- case "error":
41
- return icons.err;
42
- }
55
+ switch (status) {
56
+ case "pending":
57
+ return icons.pending;
58
+ case "starting":
59
+ return icons.scan;
60
+ case "ready":
61
+ return icons.ok;
62
+ case "error":
63
+ return icons.err;
64
+ }
43
65
  };
44
66
 
45
67
  export function renderStreamingView(
46
- initialProcesses: ProcessState[],
47
- description: string,
48
- env: Record<string, string>,
49
- onExit?: () => Promise<void> | void,
50
- _onExportLogs?: () => Promise<void> | void,
68
+ initialProcesses: ProcessState[],
69
+ description: string,
70
+ env: Record<string, string>,
71
+ onExit?: () => Promise<void> | void,
51
72
  ): StreamingViewHandle {
52
- const processes = new Map<string, ProcessState>();
53
- for (const p of initialProcesses) {
54
- processes.set(p.name, { ...p });
55
- }
56
-
57
- let allReadyPrinted = false;
58
- const hostProcess = initialProcesses.find((p) => p.name === "host");
59
- const hostPort = hostProcess?.port || 3000;
60
- const proxyTarget = env.API_PROXY;
61
-
62
- console.log();
63
- console.log(colors.cyan(`${"─".repeat(52)}`));
64
- console.log(` ${icons.run} ${colors.cyan(description.toUpperCase())}`);
65
- console.log(colors.cyan(`${"─".repeat(52)}`));
66
- console.log();
67
-
68
- if (proxyTarget) {
69
- console.log(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`));
70
- console.log();
71
- }
72
-
73
- for (const proc of initialProcesses) {
74
- const color = getServiceColor(proc.name);
75
- const sourceLabel = proc.source ? ` (${proc.source})` : "";
76
- console.log(
77
- `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${proc.name.toUpperCase()}]`)} ${icons.pending} waiting${sourceLabel}`,
78
- );
79
- }
80
-
81
- const checkAllReady = () => {
82
- if (allReadyPrinted) return;
83
-
84
- const allReady = Array.from(processes.values()).every(
85
- (p) => p.status === "ready",
86
- );
87
- if (allReady) {
88
- allReadyPrinted = true;
89
- console.log();
90
- console.log(colors.dim(`${"─".repeat(52)}`));
91
- console.log(
92
- colors.green(`${icons.ok} All ${processes.size} services ready`),
93
- );
94
- console.log(colors.green(`${icons.arrow} http://localhost:${hostPort}`));
95
- console.log(colors.dim(`${"─".repeat(52)}`));
96
- console.log();
97
- }
98
- };
99
-
100
- const updateProcess = (
101
- name: string,
102
- status: ProcessStatus,
103
- message?: string,
104
- ) => {
105
- const proc = processes.get(name);
106
- if (!proc) return;
107
-
108
- proc.status = status;
109
- if (message) proc.message = message;
110
-
111
- const color = getServiceColor(name);
112
- const icon = getStatusIcon(status);
113
- const statusText =
114
- status === "ready"
115
- ? "ready"
116
- : status === "starting"
117
- ? "starting"
118
- : status === "error"
119
- ? "failed"
120
- : "waiting";
121
- const portStr = proc.port > 0 && status === "ready" ? ` :${proc.port}` : "";
122
-
123
- write(
124
- `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${name.toUpperCase()}]`)} ${status === "ready" ? colors.green(icon) : status === "error" ? colors.error(icon) : icon} ${statusText}${portStr}`,
125
- );
126
-
127
- checkAllReady();
128
- };
129
-
130
- const addLog = (source: string, line: string, isError = false) => {
131
- const color = getServiceColor(source);
132
- const logColor = isError ? colors.error : colors.dim;
133
- write(
134
- `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim("│")} ${logColor(linkify(line))}`,
135
- );
136
- };
137
-
138
- const unmount = () => {
139
- return onExit?.();
140
- };
141
-
142
- process.on("SIGINT", () => {
143
- console.log();
144
- console.log(colors.dim(`[${getTimestamp()}] Shutting down...`));
145
- Promise.resolve(unmount()).then(() => {
146
- process.exit(0);
147
- });
148
- });
149
-
150
- return { updateProcess, addLog, unmount };
73
+ const processes = new Map<string, ProcessState>();
74
+ for (const p of initialProcesses) {
75
+ processes.set(p.name, { ...p });
76
+ }
77
+
78
+ let allReadyPrinted = false;
79
+ const hostProcess = initialProcesses.find((p) => p.name === "host");
80
+ const hostPort = hostProcess?.port || 3000;
81
+ const proxyTarget = env.API_PROXY;
82
+ const sectionedProcesses = getSectionedProcesses(initialProcesses);
83
+ const columnWidths = getColumnWidths(initialProcesses);
84
+ const lastLogBySource = new Map<string, string>();
85
+
86
+ console.log();
87
+ console.log(colors.cyan(`${"─".repeat(52)}`));
88
+ console.log(` ${icons.run} ${colors.cyan(description.toUpperCase())}`);
89
+ console.log(colors.cyan(`${"─".repeat(52)}`));
90
+ console.log();
91
+
92
+ if (proxyTarget) {
93
+ console.log(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`));
94
+ console.log();
95
+ }
96
+
97
+ for (const section of sectionedProcesses) {
98
+ console.log(colors.cyan(` ${section.title}`));
99
+ for (const proc of section.processes) {
100
+ const color = getServiceColor(proc.name);
101
+ const sourceLabel = proc.source ? ` (${proc.source})` : "";
102
+ console.log(
103
+ `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`,
104
+ );
105
+ }
106
+ console.log();
107
+ }
108
+
109
+ const checkAllReady = () => {
110
+ if (allReadyPrinted) return;
111
+ const allReady = Array.from(processes.values()).every((p) => p.status === "ready");
112
+ if (allReady) {
113
+ allReadyPrinted = true;
114
+ console.log();
115
+ console.log(colors.dim(`${"─".repeat(52)}`));
116
+ console.log(colors.green(`${icons.ok} All ${processes.size} services ready`));
117
+ console.log(colors.green(`${icons.arrow} http://localhost:${hostPort}`));
118
+ console.log(colors.dim(`${"─".repeat(52)}`));
119
+ console.log();
120
+ }
121
+ };
122
+
123
+ const updateProcess = (name: string, status: ProcessStatus, message?: string) => {
124
+ const proc = processes.get(name);
125
+ if (!proc) return;
126
+
127
+ proc.status = status;
128
+ if (message) proc.message = message;
129
+
130
+ const color = getServiceColor(name);
131
+ const icon = getStatusIcon(status);
132
+ const displayName = getDisplayName(name).padEnd(columnWidths.name);
133
+ const sourceLabel = proc?.source ? ` (${proc.source})` : "";
134
+ const statusText =
135
+ status === "ready"
136
+ ? "ready"
137
+ : status === "starting"
138
+ ? "starting"
139
+ : status === "error"
140
+ ? "failed"
141
+ : "waiting";
142
+ const portStr = proc.port > 0 && status === "ready" ? ` :${proc.port}` : "";
143
+
144
+ write(
145
+ `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === "ready" ? colors.green(icon) : status === "error" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`,
146
+ );
147
+
148
+ checkAllReady();
149
+ };
150
+
151
+ const addLog = (source: string, line: string, isError = false) => {
152
+ const lastLine = lastLogBySource.get(source);
153
+ const nextLine = `${isError ? "ERR" : "OUT"}:${line}`;
154
+ if (lastLine === nextLine) return;
155
+ lastLogBySource.set(source, nextLine);
156
+
157
+ const color = getServiceColor(source);
158
+ const logColor = isError ? colors.error : colors.dim;
159
+ write(
160
+ `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim("│")} ${logColor(linkify(line))}`,
161
+ );
162
+ };
163
+
164
+ const unmount = () => onExit?.();
165
+
166
+ let signalCount = 0;
167
+ const forceExit = () => {
168
+ console.log("\n[CLI] Force exit");
169
+ process.exit(0);
170
+ };
171
+
172
+ process.on("SIGINT", () => {
173
+ signalCount++;
174
+ if (signalCount > 1) {
175
+ forceExit();
176
+ return;
177
+ }
178
+ console.log();
179
+ console.log(colors.dim(`[${getTimestamp()}] Shutting down...`));
180
+ const timeout = setTimeout(forceExit, 5000);
181
+ Promise.resolve(unmount()).then(() => {
182
+ clearTimeout(timeout);
183
+ });
184
+ });
185
+
186
+ return { updateProcess, addLog, unmount };
151
187
  }