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
@@ -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;