everything-dev 0.3.2 → 1.3.2

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 (308) 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 +317 -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 +309 -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/mf.cjs +77 -0
  123. package/dist/mf.cjs.map +1 -0
  124. package/dist/mf.d.cts +19 -0
  125. package/dist/mf.d.cts.map +1 -0
  126. package/dist/mf.d.mts +19 -0
  127. package/dist/mf.d.mts.map +1 -0
  128. package/dist/mf.mjs +71 -0
  129. package/dist/mf.mjs.map +1 -0
  130. package/dist/near-cli.cjs +196 -0
  131. package/dist/near-cli.cjs.map +1 -0
  132. package/dist/near-cli.mjs +193 -0
  133. package/dist/near-cli.mjs.map +1 -0
  134. package/dist/network.cjs +9 -0
  135. package/dist/network.cjs.map +1 -0
  136. package/dist/network.mjs +8 -0
  137. package/dist/network.mjs.map +1 -0
  138. package/dist/orchestrator.cjs +441 -0
  139. package/dist/orchestrator.cjs.map +1 -0
  140. package/dist/orchestrator.d.cts +40 -0
  141. package/dist/orchestrator.d.cts.map +1 -0
  142. package/dist/orchestrator.d.mts +40 -0
  143. package/dist/orchestrator.d.mts.map +1 -0
  144. package/dist/orchestrator.mjs +436 -0
  145. package/dist/orchestrator.mjs.map +1 -0
  146. package/dist/plugin.cjs +825 -0
  147. package/dist/plugin.cjs.map +1 -0
  148. package/dist/plugin.d.cts +347 -0
  149. package/dist/plugin.d.cts.map +1 -0
  150. package/dist/plugin.d.mts +348 -0
  151. package/dist/plugin.d.mts.map +1 -0
  152. package/dist/plugin.mjs +822 -0
  153. package/dist/plugin.mjs.map +1 -0
  154. package/dist/process-registry.cjs +120 -0
  155. package/dist/process-registry.cjs.map +1 -0
  156. package/dist/process-registry.d.cts +25 -0
  157. package/dist/process-registry.d.cts.map +1 -0
  158. package/dist/process-registry.d.mts +25 -0
  159. package/dist/process-registry.d.mts.map +1 -0
  160. package/dist/process-registry.mjs +119 -0
  161. package/dist/process-registry.mjs.map +1 -0
  162. package/dist/sdk.cjs +61 -0
  163. package/dist/sdk.d.cts +5 -0
  164. package/dist/sdk.d.mts +5 -0
  165. package/dist/sdk.mjs +6 -0
  166. package/dist/shared.cjs +143 -0
  167. package/dist/shared.cjs.map +1 -0
  168. package/dist/shared.d.cts +33 -0
  169. package/dist/shared.d.cts.map +1 -0
  170. package/dist/shared.d.mts +33 -0
  171. package/dist/shared.d.mts.map +1 -0
  172. package/dist/shared.mjs +140 -0
  173. package/dist/shared.mjs.map +1 -0
  174. package/dist/types.cjs +160 -0
  175. package/dist/types.cjs.map +1 -0
  176. package/dist/types.d.cts +269 -0
  177. package/dist/types.d.cts.map +1 -0
  178. package/dist/types.d.mts +269 -0
  179. package/dist/types.d.mts.map +1 -0
  180. package/dist/types.mjs +144 -0
  181. package/dist/types.mjs.map +1 -0
  182. package/dist/ui/head.cjs +67 -0
  183. package/dist/ui/head.cjs.map +1 -0
  184. package/dist/ui/head.d.cts +19 -0
  185. package/dist/ui/head.d.cts.map +1 -0
  186. package/dist/ui/head.d.mts +19 -0
  187. package/dist/ui/head.d.mts.map +1 -0
  188. package/dist/ui/head.mjs +61 -0
  189. package/dist/ui/head.mjs.map +1 -0
  190. package/dist/ui/index.cjs +32 -0
  191. package/dist/ui/index.d.cts +7 -0
  192. package/dist/ui/index.d.mts +7 -0
  193. package/dist/ui/index.mjs +6 -0
  194. package/dist/ui/metadata.cjs +106 -0
  195. package/dist/ui/metadata.cjs.map +1 -0
  196. package/dist/ui/metadata.d.cts +35 -0
  197. package/dist/ui/metadata.d.cts.map +1 -0
  198. package/dist/ui/metadata.d.mts +35 -0
  199. package/dist/ui/metadata.d.mts.map +1 -0
  200. package/dist/ui/metadata.mjs +100 -0
  201. package/dist/ui/metadata.mjs.map +1 -0
  202. package/dist/ui/router.cjs +56 -0
  203. package/dist/ui/router.cjs.map +1 -0
  204. package/dist/ui/router.d.cts +11 -0
  205. package/dist/ui/router.d.cts.map +1 -0
  206. package/dist/ui/router.d.mts +11 -0
  207. package/dist/ui/router.d.mts.map +1 -0
  208. package/dist/ui/router.mjs +51 -0
  209. package/dist/ui/router.mjs.map +1 -0
  210. package/dist/ui/runtime.cjs +65 -0
  211. package/dist/ui/runtime.cjs.map +1 -0
  212. package/dist/ui/runtime.d.cts +29 -0
  213. package/dist/ui/runtime.d.cts.map +1 -0
  214. package/dist/ui/runtime.d.mts +29 -0
  215. package/dist/ui/runtime.d.mts.map +1 -0
  216. package/dist/ui/runtime.mjs +53 -0
  217. package/dist/ui/runtime.mjs.map +1 -0
  218. package/dist/ui/types.cjs +0 -0
  219. package/dist/ui/types.d.cts +52 -0
  220. package/dist/ui/types.d.cts.map +1 -0
  221. package/dist/ui/types.d.mts +52 -0
  222. package/dist/ui/types.d.mts.map +1 -0
  223. package/dist/ui/types.mjs +1 -0
  224. package/dist/utils/banner.cjs +24 -0
  225. package/dist/utils/banner.cjs.map +1 -0
  226. package/dist/utils/banner.mjs +23 -0
  227. package/dist/utils/banner.mjs.map +1 -0
  228. package/dist/utils/linkify.cjs +15 -0
  229. package/dist/utils/linkify.cjs.map +1 -0
  230. package/dist/utils/linkify.mjs +14 -0
  231. package/dist/utils/linkify.mjs.map +1 -0
  232. package/dist/utils/run.cjs +40 -0
  233. package/dist/utils/run.cjs.map +1 -0
  234. package/dist/utils/run.mjs +39 -0
  235. package/dist/utils/run.mjs.map +1 -0
  236. package/dist/utils/theme.cjs +44 -0
  237. package/dist/utils/theme.cjs.map +1 -0
  238. package/dist/utils/theme.mjs +37 -0
  239. package/dist/utils/theme.mjs.map +1 -0
  240. package/package.json +269 -80
  241. package/src/api-contract.ts +309 -0
  242. package/src/api.ts +181 -0
  243. package/src/app.ts +346 -0
  244. package/src/cli/catalog.ts +49 -0
  245. package/src/cli/help.ts +13 -0
  246. package/src/cli/init.ts +415 -0
  247. package/src/cli/parse.ts +130 -0
  248. package/src/cli/prompts.ts +64 -0
  249. package/src/cli.ts +203 -1507
  250. package/src/components/dev-view.tsx +104 -41
  251. package/src/components/streaming-view.ts +89 -22
  252. package/src/config.ts +462 -532
  253. package/src/contract.meta.ts +96 -0
  254. package/src/contract.ts +164 -561
  255. package/src/dev-logs.ts +85 -0
  256. package/src/dev-session.ts +318 -0
  257. package/src/fastkv.ts +153 -0
  258. package/src/federation.server.ts +43 -0
  259. package/src/host.ts +526 -0
  260. package/src/index.ts +6 -3
  261. package/src/integrity.ts +54 -0
  262. package/src/mf.ts +105 -0
  263. package/src/near-cli.ts +284 -0
  264. package/src/network.ts +3 -0
  265. package/src/orchestrator.ts +648 -0
  266. package/src/plugin.ts +1116 -2303
  267. package/src/process-registry.ts +154 -0
  268. package/src/scripts/sync-api-contract.ts +24 -0
  269. package/src/sdk.ts +14 -0
  270. package/src/shared.ts +206 -0
  271. package/src/types.ts +152 -206
  272. package/src/ui/head.ts +34 -27
  273. package/src/ui/index.ts +3 -3
  274. package/src/ui/metadata.ts +95 -0
  275. package/src/ui/router.ts +22 -6
  276. package/src/ui/runtime.ts +55 -6
  277. package/src/ui/types.ts +24 -11
  278. package/src/utils/banner.ts +10 -6
  279. package/src/utils/run.ts +26 -27
  280. package/src/utils/theme.ts +3 -66
  281. package/src/components/monitor-view.tsx +0 -475
  282. package/src/components/status-view.tsx +0 -173
  283. package/src/lib/env.ts +0 -109
  284. package/src/lib/near-cli.ts +0 -289
  285. package/src/lib/nova.ts +0 -266
  286. package/src/lib/orchestrator.ts +0 -276
  287. package/src/lib/process-registry.ts +0 -166
  288. package/src/lib/process.ts +0 -549
  289. package/src/lib/resource-monitor/assertions.ts +0 -234
  290. package/src/lib/resource-monitor/command.ts +0 -283
  291. package/src/lib/resource-monitor/diff.ts +0 -157
  292. package/src/lib/resource-monitor/errors.ts +0 -127
  293. package/src/lib/resource-monitor/index.ts +0 -305
  294. package/src/lib/resource-monitor/platform/darwin.ts +0 -306
  295. package/src/lib/resource-monitor/platform/index.ts +0 -35
  296. package/src/lib/resource-monitor/platform/linux.ts +0 -332
  297. package/src/lib/resource-monitor/platform/windows.ts +0 -298
  298. package/src/lib/resource-monitor/snapshot.ts +0 -217
  299. package/src/lib/resource-monitor/types.ts +0 -74
  300. package/src/lib/session-recorder/errors.ts +0 -102
  301. package/src/lib/session-recorder/flows/login.ts +0 -210
  302. package/src/lib/session-recorder/index.ts +0 -361
  303. package/src/lib/session-recorder/playwright.ts +0 -257
  304. package/src/lib/session-recorder/report.ts +0 -353
  305. package/src/lib/session-recorder/server.ts +0 -267
  306. package/src/lib/session-recorder/types.ts +0 -115
  307. package/src/lib/sync.ts +0 -1
  308. package/src/ui/files.ts +0 -134
@@ -1,276 +0,0 @@
1
- import { appendFile } from "node:fs/promises";
2
- import { Effect } from "every-plugin/effect";
3
- import path from "path";
4
- import {
5
- type DevViewHandle,
6
- type LogEntry,
7
- type ProcessState,
8
- renderDevView,
9
- } from "../components/dev-view";
10
- import { renderStreamingView } from "../components/streaming-view";
11
- import type { AppConfig, BosConfig } from "../config";
12
- import {
13
- getProcessConfig,
14
- makeDevProcess,
15
- type ProcessCallbacks,
16
- type ProcessHandle,
17
- } from "./process";
18
-
19
- let activeCleanup: (() => Promise<void>) | null = null;
20
-
21
- const LOG_NOISE_PATTERNS = [
22
- /\[ Federation Runtime \] Version .* from (host|ui) of shared singleton module/,
23
- /Executing an Effect versioned \d+\.\d+\.\d+ with a Runtime of version/,
24
- /you may want to dedupe the effect dependencies/,
25
- ];
26
-
27
- const isDebugMode = (): boolean => {
28
- return process.env.DEBUG === "true" || process.env.DEBUG === "1";
29
- };
30
-
31
- const shouldDisplayLog = (line: string): boolean => {
32
- if (isDebugMode()) return true;
33
- return !LOG_NOISE_PATTERNS.some((pattern) => pattern.test(line));
34
- };
35
-
36
- export interface AppOrchestrator {
37
- packages: string[];
38
- env: Record<string, string>;
39
- description: string;
40
- appConfig: AppConfig;
41
- bosConfig?: BosConfig;
42
- port?: number;
43
- interactive?: boolean;
44
- noLogs?: boolean;
45
- }
46
-
47
- const isInteractiveSupported = (): boolean => {
48
- return process.stdin.isTTY === true && process.stdout.isTTY === true;
49
- };
50
-
51
- const STARTUP_ORDER = ["ui-ssr", "ui", "api", "host"];
52
-
53
- const sortByOrder = (packages: string[]): string[] => {
54
- return [...packages].sort((a, b) => {
55
- const aIdx = STARTUP_ORDER.indexOf(a);
56
- const bIdx = STARTUP_ORDER.indexOf(b);
57
- if (aIdx === -1 && bIdx === -1) return 0;
58
- if (aIdx === -1) return 1;
59
- if (bIdx === -1) return -1;
60
- return aIdx - bIdx;
61
- });
62
- };
63
-
64
- const getLogDir = () => path.join(process.cwd(), ".bos", "logs");
65
- const getLogFile = () => {
66
- const now = new Date();
67
- const ts = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
68
- return path.join(getLogDir(), `dev-${ts}.log`);
69
- };
70
-
71
- const ensureLogDir = async () => {
72
- const dir = getLogDir();
73
- await Bun.spawn(["mkdir", "-p", dir]).exited;
74
- };
75
-
76
- const formatLogLine = (entry: LogEntry): string => {
77
- const ts = new Date(entry.timestamp).toISOString();
78
- const prefix = entry.isError ? "ERR" : "OUT";
79
- return `[${ts}] [${entry.source}] [${prefix}] ${entry.line}`;
80
- };
81
-
82
- export const runDevServers = (orchestrator: AppOrchestrator) =>
83
- Effect.gen(function* () {
84
- const orderedPackages = sortByOrder(orchestrator.packages);
85
-
86
- const initialProcesses: ProcessState[] = orderedPackages.map((pkg) => {
87
- const portOverride = pkg === "host" ? orchestrator.port : undefined;
88
- const config = getProcessConfig(pkg, undefined, portOverride);
89
- const source =
90
- pkg === "host"
91
- ? orchestrator.appConfig.host
92
- : pkg === "ui"
93
- ? orchestrator.appConfig.ui
94
- : pkg === "api"
95
- ? orchestrator.appConfig.api
96
- : undefined;
97
- return {
98
- name: pkg,
99
- status: "pending" as const,
100
- port: config?.port ?? 0,
101
- source,
102
- };
103
- });
104
-
105
- const handles: ProcessHandle[] = [];
106
- const allLogs: LogEntry[] = [];
107
- let logFile: string | null = null;
108
- let view: DevViewHandle | null = null;
109
- let shuttingDown = false;
110
-
111
- if (!orchestrator.noLogs) {
112
- yield* Effect.promise(async () => {
113
- await ensureLogDir();
114
- logFile = getLogFile();
115
- await Bun.write(
116
- logFile,
117
- `# BOS Dev Session: ${orchestrator.description}\n# Started: ${new Date().toISOString()}\n\n`,
118
- );
119
- });
120
- }
121
-
122
- const killAll = async () => {
123
- const reversed = [...handles].reverse();
124
- for (const handle of reversed) {
125
- try {
126
- await handle.kill();
127
- } catch {}
128
- }
129
- };
130
-
131
- const exportLogs = async () => {
132
- console.log("\n");
133
- console.log("═".repeat(70));
134
- console.log(` SESSION LOGS: ${orchestrator.description}`);
135
- console.log(
136
- ` Started: ${new Date(allLogs[0]?.timestamp || Date.now()).toISOString()}`,
137
- );
138
- console.log(` Total entries: ${allLogs.length}`);
139
- console.log("═".repeat(70));
140
- console.log("");
141
-
142
- for (const entry of allLogs) {
143
- console.log(formatLogLine(entry));
144
- }
145
-
146
- console.log("");
147
- console.log("═".repeat(70));
148
- console.log(" END OF LOGS");
149
- if (logFile) {
150
- console.log(` Full logs saved to: ${logFile}`);
151
- }
152
- console.log("═".repeat(70));
153
- console.log("");
154
- };
155
-
156
- const cleanup = async (showLogs = false) => {
157
- if (shuttingDown) return;
158
- shuttingDown = true;
159
- view?.unmount();
160
- await killAll();
161
- if (showLogs) {
162
- await exportLogs();
163
- }
164
- activeCleanup = null;
165
- };
166
-
167
- activeCleanup = cleanup;
168
-
169
- const useInteractive = orchestrator.interactive ?? isInteractiveSupported();
170
-
171
- view = useInteractive
172
- ? renderDevView(
173
- initialProcesses,
174
- orchestrator.description,
175
- orchestrator.env,
176
- () => cleanup(false),
177
- () => cleanup(true),
178
- )
179
- : renderStreamingView(
180
- initialProcesses,
181
- orchestrator.description,
182
- orchestrator.env,
183
- () => cleanup(false),
184
- () => cleanup(true),
185
- );
186
-
187
- const callbacks: ProcessCallbacks = {
188
- onStatus: (name, status, message) => {
189
- view?.updateProcess(name, status, message);
190
- },
191
- onLog: (name, line, isError) => {
192
- const entry: LogEntry = {
193
- source: name,
194
- line,
195
- timestamp: Date.now(),
196
- isError,
197
- };
198
- allLogs.push(entry);
199
-
200
- if (shouldDisplayLog(line)) {
201
- view?.addLog(name, line, isError);
202
- }
203
-
204
- if (logFile) {
205
- const logLine = formatLogLine(entry) + "\n";
206
- appendFile(logFile, logLine).catch(() => {});
207
- }
208
- },
209
- };
210
-
211
- for (const pkg of orderedPackages) {
212
- const portOverride = pkg === "host" ? orchestrator.port : undefined;
213
- const handle = yield* makeDevProcess(
214
- pkg,
215
- orchestrator.env,
216
- callbacks,
217
- portOverride,
218
- orchestrator.bosConfig,
219
- );
220
- handles.push(handle);
221
-
222
- yield* Effect.race(
223
- handle.waitForReady,
224
- Effect.sleep("30 seconds").pipe(
225
- Effect.andThen(
226
- Effect.sync(() => {
227
- callbacks.onLog(
228
- pkg,
229
- "Timeout waiting for ready, continuing...",
230
- true,
231
- );
232
- }),
233
- ),
234
- ),
235
- );
236
- }
237
-
238
- yield* Effect.addFinalizer(() => Effect.promise(() => cleanup(false)));
239
-
240
- yield* Effect.never;
241
- });
242
-
243
- export const startApp = (orchestrator: AppOrchestrator) => {
244
- const program = Effect.scoped(runDevServers(orchestrator)).pipe(
245
- Effect.catchAll((e) =>
246
- Effect.sync(() => {
247
- if (e instanceof Error) {
248
- console.error("App server error:", e.message);
249
- if (e.stack) {
250
- console.error(e.stack);
251
- }
252
- } else if (typeof e === "object" && e !== null) {
253
- console.error("App server error:", JSON.stringify(e, null, 2));
254
- } else {
255
- console.error("App server error:", e);
256
- }
257
- }),
258
- ),
259
- );
260
-
261
- const handleSignal = async () => {
262
- if (activeCleanup) {
263
- await activeCleanup();
264
- }
265
- };
266
-
267
- process.on("SIGINT", () => {
268
- handleSignal().finally(() => process.exit(0));
269
- });
270
-
271
- process.on("SIGTERM", () => {
272
- handleSignal().finally(() => process.exit(0));
273
- });
274
-
275
- Effect.runPromise(program);
276
- };
@@ -1,166 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { mkdir, readFile, writeFile } from "node:fs/promises";
3
- import { dirname, join } from "node:path";
4
- import { Context, Effect, Layer, Ref } from "every-plugin/effect";
5
- import { getProjectRoot } from "../config";
6
-
7
- const getPidFilePath = () => {
8
- try {
9
- return join(getProjectRoot(), ".bos", "pids.json");
10
- } catch {
11
- // Fallback to cwd if config not loaded
12
- return join(process.cwd(), ".bos", "pids.json");
13
- }
14
- };
15
-
16
- export interface TrackedProcess {
17
- pid: number;
18
- name: string;
19
- port: number;
20
- startedAt: number;
21
- command: string;
22
- }
23
-
24
- export interface ProcessRegistry {
25
- readonly tracked: Ref.Ref<Map<number, TrackedProcess>>;
26
- track: (proc: TrackedProcess) => Effect.Effect<void>;
27
- untrack: (pid: number) => Effect.Effect<void>;
28
- getAll: () => Effect.Effect<TrackedProcess[]>;
29
- killAll: (
30
- force?: boolean,
31
- ) => Effect.Effect<{ killed: number[]; failed: number[] }>;
32
- persist: () => Effect.Effect<void>;
33
- restore: () => Effect.Effect<void>;
34
- }
35
-
36
- const isProcessAlive = (pid: number): boolean => {
37
- try {
38
- process.kill(pid, 0);
39
- return true;
40
- } catch {
41
- return false;
42
- }
43
- };
44
-
45
- const killProcess = (pid: number, signal: NodeJS.Signals): boolean => {
46
- try {
47
- process.kill(pid, signal);
48
- return true;
49
- } catch {
50
- return false;
51
- }
52
- };
53
-
54
- const make = Effect.gen(function* () {
55
- const tracked = yield* Ref.make(new Map<number, TrackedProcess>());
56
- const pidFile = getPidFilePath();
57
-
58
- const track: ProcessRegistry["track"] = (proc) =>
59
- Effect.gen(function* () {
60
- yield* Ref.update(tracked, (m) => new Map(m).set(proc.pid, proc));
61
- yield* persist();
62
- });
63
-
64
- const untrack: ProcessRegistry["untrack"] = (pid) =>
65
- Effect.gen(function* () {
66
- yield* Ref.update(tracked, (m) => {
67
- const copy = new Map(m);
68
- copy.delete(pid);
69
- return copy;
70
- });
71
- yield* persist();
72
- });
73
-
74
- const getAll: ProcessRegistry["getAll"] = () =>
75
- Ref.get(tracked).pipe(Effect.map((m) => Array.from(m.values())));
76
-
77
- const killAll: ProcessRegistry["killAll"] = (force = false) =>
78
- Effect.gen(function* () {
79
- const procs = yield* getAll();
80
- const killed: number[] = [];
81
- const failed: number[] = [];
82
-
83
- for (const proc of procs) {
84
- if (!isProcessAlive(proc.pid)) {
85
- yield* untrack(proc.pid);
86
- continue;
87
- }
88
-
89
- const signal = force ? "SIGKILL" : "SIGTERM";
90
- if (killProcess(proc.pid, signal)) {
91
- killed.push(proc.pid);
92
- yield* untrack(proc.pid);
93
- } else {
94
- failed.push(proc.pid);
95
- }
96
- }
97
-
98
- if (!force && failed.length > 0) {
99
- yield* Effect.sleep("500 millis");
100
- for (const pid of [...failed]) {
101
- if (killProcess(pid, "SIGKILL")) {
102
- const idx = failed.indexOf(pid);
103
- if (idx !== -1) {
104
- failed.splice(idx, 1);
105
- killed.push(pid);
106
- }
107
- yield* untrack(pid);
108
- }
109
- }
110
- }
111
-
112
- yield* persist();
113
- return { killed, failed };
114
- });
115
-
116
- const persist: ProcessRegistry["persist"] = () =>
117
- Effect.gen(function* () {
118
- const procs = yield* getAll();
119
- const dir = dirname(pidFile);
120
-
121
- yield* Effect.tryPromise({
122
- try: async () => {
123
- if (!existsSync(dir)) {
124
- await mkdir(dir, { recursive: true });
125
- }
126
- await writeFile(pidFile, JSON.stringify(procs, null, 2));
127
- },
128
- catch: () => new Error("Failed to persist PIDs"),
129
- }).pipe(Effect.catchAll(() => Effect.void));
130
- });
131
-
132
- const restore: ProcessRegistry["restore"] = () =>
133
- Effect.gen(function* () {
134
- if (!existsSync(pidFile)) return;
135
-
136
- const content = yield* Effect.tryPromise({
137
- try: () => readFile(pidFile, "utf8"),
138
- catch: () => new Error("Failed to read PID file"),
139
- }).pipe(Effect.catchAll(() => Effect.succeed("")));
140
-
141
- if (!content) return;
142
-
143
- let procs: TrackedProcess[];
144
- try {
145
- procs = JSON.parse(content) as TrackedProcess[];
146
- } catch {
147
- return;
148
- }
149
-
150
- const alive = procs.filter((p) => isProcessAlive(p.pid));
151
- yield* Ref.set(tracked, new Map(alive.map((p) => [p.pid, p])));
152
- });
153
-
154
- yield* restore();
155
-
156
- return { tracked, track, untrack, getAll, killAll, persist, restore };
157
- });
158
-
159
- export class ProcessRegistryService extends Context.Tag("bos/ProcessRegistry")<
160
- ProcessRegistryService,
161
- ProcessRegistry
162
- >() {
163
- static Live = Layer.effect(ProcessRegistryService, make);
164
- }
165
-
166
- export const createProcessRegistry = (): Effect.Effect<ProcessRegistry> => make;