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,298 +0,0 @@
1
- import { Effect, Layer } from "effect";
2
- import { execShellSafe, powershellSafe } from "../command";
3
- import type {
4
- MemoryInfo,
5
- PlatformOperations,
6
- PortInfo,
7
- ProcessInfo,
8
- } from "../types";
9
- import { PlatformService } from "../types";
10
-
11
- const getPortInfo = (
12
- ports: number[]
13
- ): Effect.Effect<Record<number, PortInfo>, never> =>
14
- Effect.gen(function* () {
15
- yield* Effect.logInfo(`[windows] Checking ${ports.length} ports`);
16
-
17
- const result: Record<number, PortInfo> = {};
18
- for (const port of ports) {
19
- result[port] = { port, pid: null, command: null, state: "FREE" };
20
- }
21
-
22
- if (ports.length === 0) return result;
23
-
24
- const output = yield* execShellSafe("netstat -ano -p TCP");
25
- if (!output) {
26
- yield* Effect.logDebug(
27
- "[windows] No netstat output, all ports appear free"
28
- );
29
- return result;
30
- }
31
-
32
- const lines = output.split("\n").filter(Boolean);
33
- yield* Effect.logDebug(`[windows] Parsing ${lines.length} netstat lines`);
34
-
35
- for (const line of lines) {
36
- if (!line.includes("LISTENING")) continue;
37
-
38
- const parts = line.trim().split(/\s+/);
39
- if (parts.length < 5) continue;
40
-
41
- const localAddr = parts[1];
42
- const portMatch = localAddr.match(/:(\d+)$/);
43
- if (!portMatch) continue;
44
-
45
- const port = parseInt(portMatch[1], 10);
46
- if (!ports.includes(port)) continue;
47
-
48
- const pid = parseInt(parts[4], 10);
49
-
50
- let command: string | null = null;
51
- if (pid) {
52
- const cmdOutput = yield* execShellSafe(
53
- `wmic process where ProcessId=${pid} get Name /format:list`
54
- );
55
- const nameMatch = cmdOutput.match(/Name=(.+)/);
56
- command = nameMatch ? nameMatch[1].trim() : null;
57
- }
58
-
59
- result[port] = {
60
- port,
61
- pid,
62
- command,
63
- state: "LISTEN",
64
- };
65
-
66
- yield* Effect.logDebug(
67
- `[windows] Port :${port} bound to PID ${pid} (${command})`
68
- );
69
- }
70
-
71
- const boundCount = Object.values(result).filter(
72
- (p) => p.state === "LISTEN"
73
- ).length;
74
- yield* Effect.logInfo(
75
- `[windows] Found ${boundCount}/${ports.length} ports in use`
76
- );
77
-
78
- return result;
79
- });
80
-
81
- const getProcessTree = (
82
- rootPids: number[]
83
- ): Effect.Effect<ProcessInfo[], never> =>
84
- Effect.gen(function* () {
85
- yield* Effect.logInfo(
86
- `[windows] Building process tree for ${rootPids.length} root PIDs`
87
- );
88
-
89
- const processes: ProcessInfo[] = [];
90
- const visited = new Set<number>();
91
-
92
- const getProcess = (
93
- pid: number
94
- ): Effect.Effect<ProcessInfo | null, never> =>
95
- Effect.gen(function* () {
96
- if (visited.has(pid)) return null;
97
- visited.add(pid);
98
-
99
- const output = yield* execShellSafe(
100
- `wmic process where ProcessId=${pid} get ProcessId,ParentProcessId,WorkingSetSize,Name,CommandLine /format:csv`
101
- );
102
- const lines = output
103
- .split("\n")
104
- .filter((l) => l.trim() && !l.startsWith("Node"));
105
- if (lines.length === 0) return null;
106
-
107
- const parts = lines[0].split(",");
108
- if (parts.length < 5) return null;
109
-
110
- const cmdLine = parts[1] || "";
111
- const name = parts[2] || "";
112
- const ppid = parseInt(parts[3], 10);
113
- const procId = parseInt(parts[4], 10);
114
- const rss = parseInt(parts[5], 10) || 0;
115
-
116
- yield* Effect.logDebug(
117
- `[windows] Process ${pid}: ${name} (RSS: ${(rss / 1024).toFixed(0)}KB)`
118
- );
119
-
120
- return {
121
- pid: procId,
122
- ppid,
123
- command: name,
124
- args: cmdLine.split(/\s+/).slice(1),
125
- rss,
126
- children: [],
127
- };
128
- });
129
-
130
- const getChildren = (pid: number): Effect.Effect<number[], never> =>
131
- Effect.gen(function* () {
132
- const output = yield* execShellSafe(
133
- `wmic process where ParentProcessId=${pid} get ProcessId /format:list`
134
- );
135
- const matches = output.match(/ProcessId=(\d+)/g);
136
- if (!matches) return [];
137
-
138
- const children = matches.map((m) =>
139
- parseInt(m.replace("ProcessId=", ""), 10)
140
- );
141
-
142
- if (children.length > 0) {
143
- yield* Effect.logDebug(
144
- `[windows] PID ${pid} has ${children.length} children: ${children.join(", ")}`
145
- );
146
- }
147
-
148
- return children;
149
- });
150
-
151
- const traverse = (pid: number): Effect.Effect<void, never> =>
152
- Effect.gen(function* () {
153
- const proc = yield* getProcess(pid);
154
- if (!proc) return;
155
-
156
- const children = yield* getChildren(pid);
157
- proc.children = children;
158
- processes.push(proc);
159
-
160
- for (const child of children) {
161
- yield* traverse(child);
162
- }
163
- });
164
-
165
- for (const pid of rootPids) {
166
- yield* traverse(pid);
167
- }
168
-
169
- yield* Effect.logInfo(
170
- `[windows] Process tree contains ${processes.length} processes`
171
- );
172
-
173
- return processes;
174
- });
175
-
176
- const getMemoryInfo = (): Effect.Effect<MemoryInfo, never> =>
177
- Effect.gen(function* () {
178
- yield* Effect.logDebug("[windows] Getting memory info");
179
-
180
- const script = `
181
- $os = Get-CimInstance Win32_OperatingSystem
182
- $total = $os.TotalVisibleMemorySize * 1024
183
- $free = $os.FreePhysicalMemory * 1024
184
- Write-Output "$total,$free"
185
- `;
186
- const output = yield* powershellSafe(script);
187
-
188
- if (!output) {
189
- yield* Effect.logWarning("[windows] Could not get memory info");
190
- return { total: 0, used: 0, free: 0, processRss: 0 };
191
- }
192
-
193
- const [totalStr, freeStr] = output.split(",");
194
- const total = parseInt(totalStr, 10) || 0;
195
- const free = parseInt(freeStr, 10) || 0;
196
-
197
- const totalMB = (total / 1024 / 1024).toFixed(0);
198
- const usedMB = ((total - free) / 1024 / 1024).toFixed(0);
199
- yield* Effect.logDebug(
200
- `[windows] Memory: ${usedMB}MB used / ${totalMB}MB total`
201
- );
202
-
203
- return {
204
- total,
205
- used: total - free,
206
- free,
207
- processRss: 0,
208
- };
209
- });
210
-
211
- const getAllProcesses = (): Effect.Effect<ProcessInfo[], never> =>
212
- Effect.gen(function* () {
213
- yield* Effect.logDebug("[windows] Getting all processes");
214
-
215
- const processes: ProcessInfo[] = [];
216
-
217
- const output = yield* execShellSafe(
218
- "wmic process get ProcessId,ParentProcessId,WorkingSetSize,Name /format:csv"
219
- );
220
- const lines = output
221
- .split("\n")
222
- .filter((l) => l.trim() && !l.startsWith("Node"));
223
-
224
- for (const line of lines) {
225
- const parts = line.split(",");
226
- if (parts.length < 4) continue;
227
-
228
- const name = parts[1] || "";
229
- const ppid = parseInt(parts[2], 10);
230
- const pid = parseInt(parts[3], 10);
231
- const rss = parseInt(parts[4], 10) || 0;
232
-
233
- if (isNaN(pid)) continue;
234
-
235
- processes.push({
236
- pid,
237
- ppid: isNaN(ppid) ? 0 : ppid,
238
- command: name,
239
- args: [],
240
- rss,
241
- children: [],
242
- });
243
- }
244
-
245
- yield* Effect.logDebug(
246
- `[windows] Found ${processes.length} total processes`
247
- );
248
-
249
- return processes;
250
- });
251
-
252
- const findChildProcesses = (pid: number): Effect.Effect<number[], never> =>
253
- Effect.gen(function* () {
254
- yield* Effect.logDebug(`[windows] Finding all children of PID ${pid}`);
255
-
256
- const children: number[] = [];
257
- const visited = new Set<number>();
258
-
259
- const recurse = (parentPid: number): Effect.Effect<void, never> =>
260
- Effect.gen(function* () {
261
- if (visited.has(parentPid)) return;
262
- visited.add(parentPid);
263
-
264
- const output = yield* execShellSafe(
265
- `wmic process where ParentProcessId=${parentPid} get ProcessId /format:list`
266
- );
267
- const matches = output.match(/ProcessId=(\d+)/g);
268
- if (!matches) return;
269
-
270
- for (const match of matches) {
271
- const childPid = parseInt(match.replace("ProcessId=", ""), 10);
272
- if (!isNaN(childPid)) {
273
- children.push(childPid);
274
- yield* recurse(childPid);
275
- }
276
- }
277
- });
278
-
279
- yield* recurse(pid);
280
-
281
- if (children.length > 0) {
282
- yield* Effect.logDebug(
283
- `[windows] PID ${pid} has ${children.length} descendants`
284
- );
285
- }
286
-
287
- return children;
288
- });
289
-
290
- const windowsOperations: PlatformOperations = {
291
- getPortInfo,
292
- getProcessTree,
293
- getMemoryInfo,
294
- getAllProcesses,
295
- findChildProcesses,
296
- };
297
-
298
- export const WindowsLayer = Layer.succeed(PlatformService, windowsOperations);
@@ -1,217 +0,0 @@
1
- import { Effect } from "effect";
2
- import { loadConfig } from "../../config";
3
- import { PlatformService, withPlatform } from "./platform";
4
- import type { MonitorConfig, ProcessInfo, Snapshot } from "./types";
5
-
6
- export const getPortsToMonitor = (
7
- config?: MonitorConfig,
8
- ): Effect.Effect<number[]> =>
9
- Effect.gen(function* () {
10
- if (config?.ports && config.ports.length > 0) {
11
- yield* Effect.logDebug(
12
- `Using configured ports: ${config.ports.join(", ")}`,
13
- );
14
- return config.ports;
15
- }
16
-
17
- // Load config and get ports from runtime config
18
- const result = yield* Effect.tryPromise({
19
- try: () => loadConfig({ path: config?.configPath }),
20
- catch: () => new Error("Config not found"),
21
- }).pipe(Effect.catchAll(() => Effect.succeed(null)));
22
-
23
- if (result?.runtime) {
24
- const ports = [
25
- result.runtime.hostUrl,
26
- result.runtime.ui.url,
27
- result.runtime.api.url,
28
- ]
29
- .map((url) => {
30
- try {
31
- return parseInt(new URL(url).port || "0");
32
- } catch {
33
- return 0;
34
- }
35
- })
36
- .filter((p) => p > 0);
37
- return ports;
38
- }
39
-
40
- return [3000, 3002, 3014];
41
- });
42
-
43
- export const getConfigPathSafe = (
44
- config?: MonitorConfig,
45
- ): Effect.Effect<string | null> =>
46
- Effect.tryPromise({
47
- try: async () => {
48
- const result = await loadConfig({ path: config?.configPath });
49
- return result?.source.path ?? null;
50
- },
51
- catch: () => new Error("Config not found"),
52
- }).pipe(Effect.catchAll(() => Effect.succeed(null)));
53
-
54
- export const createSnapshot = (
55
- config?: MonitorConfig,
56
- ): Effect.Effect<Snapshot, never, PlatformService> =>
57
- Effect.gen(function* () {
58
- yield* Effect.logInfo("Creating system snapshot");
59
-
60
- const platform = yield* PlatformService;
61
- const ports = yield* getPortsToMonitor(config);
62
- const configPath = yield* getConfigPathSafe(config);
63
-
64
- yield* Effect.logDebug(`Monitoring ports: ${ports.join(", ")}`);
65
-
66
- const portInfo = yield* platform.getPortInfo(ports);
67
- const boundPorts = Object.values(portInfo).filter(
68
- (p) => p.state !== "FREE",
69
- );
70
-
71
- yield* Effect.logInfo(`Found ${boundPorts.length} bound ports`);
72
-
73
- const rootPids = boundPorts
74
- .map((p) => p.pid)
75
- .filter((pid): pid is number => pid !== null);
76
-
77
- const processes =
78
- rootPids.length > 0 ? yield* platform.getProcessTree(rootPids) : [];
79
-
80
- yield* Effect.logInfo(`Tracked ${processes.length} processes in tree`);
81
-
82
- const memory = yield* platform.getMemoryInfo();
83
-
84
- const totalRss = processes.reduce((sum, p) => sum + p.rss, 0);
85
- memory.processRss = totalRss;
86
-
87
- yield* Effect.logDebug(
88
- `Total process RSS: ${(totalRss / 1024 / 1024).toFixed(1)}MB`,
89
- );
90
-
91
- const snapshot: Snapshot = {
92
- timestamp: Date.now(),
93
- configPath,
94
- ports: portInfo,
95
- processes,
96
- memory,
97
- platform: process.platform,
98
- };
99
-
100
- yield* Effect.logInfo(
101
- `Snapshot created at ${new Date(snapshot.timestamp).toISOString()}`,
102
- );
103
-
104
- return snapshot;
105
- });
106
-
107
- export const createSnapshotWithPlatform = (
108
- config?: MonitorConfig,
109
- ): Effect.Effect<Snapshot> => withPlatform(createSnapshot(config));
110
-
111
- export const findProcessesByPattern = (
112
- patterns: string[],
113
- ): Effect.Effect<ProcessInfo[], never, PlatformService> =>
114
- Effect.gen(function* () {
115
- yield* Effect.logDebug(
116
- `Finding processes matching: ${patterns.join(", ")}`,
117
- );
118
-
119
- const platform = yield* PlatformService;
120
- const allProcesses = yield* platform.getAllProcesses();
121
-
122
- const matched = allProcesses.filter((proc) =>
123
- patterns.some((pattern) =>
124
- proc.command.toLowerCase().includes(pattern.toLowerCase()),
125
- ),
126
- );
127
-
128
- yield* Effect.logInfo(
129
- `Found ${matched.length} processes matching patterns`,
130
- );
131
-
132
- return matched;
133
- });
134
-
135
- export const findBosProcesses = (): Effect.Effect<
136
- ProcessInfo[],
137
- never,
138
- PlatformService
139
- > => {
140
- const patterns = ["bun", "rspack", "rsbuild", "esbuild", "webpack", "node"];
141
- return findProcessesByPattern(patterns);
142
- };
143
-
144
- export const isProcessAliveSync = (pid: number): boolean => {
145
- try {
146
- process.kill(pid, 0);
147
- return true;
148
- } catch {
149
- return false;
150
- }
151
- };
152
-
153
- export const isProcessAlive = (pid: number): Effect.Effect<boolean> =>
154
- Effect.sync(() => isProcessAliveSync(pid));
155
-
156
- export const waitForProcessDeath = (
157
- pid: number,
158
- timeoutMs = 5000,
159
- ): Effect.Effect<boolean> =>
160
- Effect.gen(function* () {
161
- yield* Effect.logDebug(
162
- `Waiting for PID ${pid} to die (timeout: ${timeoutMs}ms)`,
163
- );
164
- const start = Date.now();
165
-
166
- while (Date.now() - start < timeoutMs) {
167
- const alive = yield* isProcessAlive(pid);
168
- if (!alive) {
169
- yield* Effect.logDebug(`PID ${pid} is dead`);
170
- return true;
171
- }
172
- yield* Effect.sleep("100 millis");
173
- }
174
-
175
- const finalAlive = yield* isProcessAlive(pid);
176
- if (finalAlive) {
177
- yield* Effect.logWarning(`PID ${pid} still alive after ${timeoutMs}ms`);
178
- }
179
- return !finalAlive;
180
- });
181
-
182
- export const waitForPortFree = (
183
- port: number,
184
- timeoutMs = 5000,
185
- ): Effect.Effect<boolean, never, PlatformService> =>
186
- Effect.gen(function* () {
187
- yield* Effect.logDebug(
188
- `Waiting for port :${port} to be free (timeout: ${timeoutMs}ms)`,
189
- );
190
- const platform = yield* PlatformService;
191
- const start = Date.now();
192
-
193
- while (Date.now() - start < timeoutMs) {
194
- const portInfo = yield* platform.getPortInfo([port]);
195
- if (portInfo[port].state === "FREE") {
196
- yield* Effect.logDebug(`Port :${port} is now free`);
197
- return true;
198
- }
199
- yield* Effect.sleep("100 millis");
200
- }
201
-
202
- const finalPortInfo = yield* platform.getPortInfo([port]);
203
- const isFree = finalPortInfo[port].state === "FREE";
204
-
205
- if (!isFree) {
206
- yield* Effect.logWarning(
207
- `Port :${port} still bound after ${timeoutMs}ms`,
208
- );
209
- }
210
-
211
- return isFree;
212
- });
213
-
214
- export const waitForPortFreeWithPlatform = (
215
- port: number,
216
- timeoutMs = 5000,
217
- ): Effect.Effect<boolean> => withPlatform(waitForPortFree(port, timeoutMs));
@@ -1,74 +0,0 @@
1
- import { Context, Effect } from "effect";
2
-
3
- export interface PortInfo {
4
- port: number;
5
- pid: number | null;
6
- command: string | null;
7
- state: "LISTEN" | "ESTABLISHED" | "TIME_WAIT" | "FREE";
8
- name?: string;
9
- }
10
-
11
- export interface ProcessInfo {
12
- pid: number;
13
- ppid: number;
14
- command: string;
15
- args: string[];
16
- rss: number;
17
- children: number[];
18
- startTime?: number;
19
- }
20
-
21
- export interface MemoryInfo {
22
- total: number;
23
- used: number;
24
- free: number;
25
- processRss: number;
26
- }
27
-
28
- export interface Snapshot {
29
- timestamp: number;
30
- configPath: string | null;
31
- ports: Record<number, PortInfo>;
32
- processes: ProcessInfo[];
33
- memory: MemoryInfo;
34
- platform: NodeJS.Platform;
35
- }
36
-
37
- export interface SnapshotDiff {
38
- from: Snapshot;
39
- to: Snapshot;
40
- orphanedProcesses: ProcessInfo[];
41
- stillBoundPorts: PortInfo[];
42
- freedPorts: number[];
43
- memoryDeltaBytes: number;
44
- newProcesses: ProcessInfo[];
45
- killedProcesses: ProcessInfo[];
46
- }
47
-
48
- export interface MonitorConfig {
49
- ports?: number[];
50
- processPatterns?: string[];
51
- refreshInterval?: number;
52
- configPath?: string;
53
- }
54
-
55
- export interface PlatformOperations {
56
- readonly getPortInfo: (
57
- ports: number[]
58
- ) => Effect.Effect<Record<number, PortInfo>, never>;
59
-
60
- readonly getProcessTree: (
61
- rootPids: number[]
62
- ) => Effect.Effect<ProcessInfo[], never>;
63
-
64
- readonly getMemoryInfo: () => Effect.Effect<MemoryInfo, never>;
65
-
66
- readonly getAllProcesses: () => Effect.Effect<ProcessInfo[], never>;
67
-
68
- readonly findChildProcesses: (pid: number) => Effect.Effect<number[], never>;
69
- }
70
-
71
- export class PlatformService extends Context.Tag("PlatformService")<
72
- PlatformService,
73
- PlatformOperations
74
- >() {}
@@ -1,102 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- export class SessionTimeout extends Data.TaggedError("SessionTimeout")<{
4
- readonly timeoutMs: number;
5
- readonly elapsedMs: number;
6
- }> {
7
- get message() {
8
- return `Session timed out after ${this.elapsedMs}ms (limit: ${this.timeoutMs}ms)`;
9
- }
10
- }
11
-
12
- export class BrowserLaunchFailed extends Data.TaggedError("BrowserLaunchFailed")<{
13
- readonly reason: string;
14
- readonly headless: boolean;
15
- }> {
16
- get message() {
17
- return `Failed to launch browser (headless: ${this.headless}): ${this.reason}`;
18
- }
19
- }
20
-
21
- export class ServerStartFailed extends Data.TaggedError("ServerStartFailed")<{
22
- readonly server: string;
23
- readonly port: number;
24
- readonly reason: string;
25
- }> {
26
- get message() {
27
- return `Failed to start ${this.server} on port ${this.port}: ${this.reason}`;
28
- }
29
- }
30
-
31
- export class ServerNotReady extends Data.TaggedError("ServerNotReady")<{
32
- readonly servers: string[];
33
- readonly timeoutMs: number;
34
- }> {
35
- get message() {
36
- return `Servers not ready after ${this.timeoutMs}ms: ${this.servers.join(", ")}`;
37
- }
38
- }
39
-
40
- export class FlowExecutionFailed extends Data.TaggedError("FlowExecutionFailed")<{
41
- readonly flowName: string;
42
- readonly step: string;
43
- readonly reason: string;
44
- }> {
45
- get message() {
46
- return `Flow "${this.flowName}" failed at step "${this.step}": ${this.reason}`;
47
- }
48
- }
49
-
50
- export class SnapshotFailed extends Data.TaggedError("SnapshotFailed")<{
51
- readonly reason: string;
52
- }> {
53
- get message() {
54
- return `Failed to capture snapshot: ${this.reason}`;
55
- }
56
- }
57
-
58
- export class ExportFailed extends Data.TaggedError("ExportFailed")<{
59
- readonly path: string;
60
- readonly reason: string;
61
- }> {
62
- get message() {
63
- return `Failed to export session to ${this.path}: ${this.reason}`;
64
- }
65
- }
66
-
67
- export class BrowserMetricsFailed extends Data.TaggedError("BrowserMetricsFailed")<{
68
- readonly reason: string;
69
- }> {
70
- get message() {
71
- return `Failed to collect browser metrics: ${this.reason}`;
72
- }
73
- }
74
-
75
- export class PopupNotDetected extends Data.TaggedError("PopupNotDetected")<{
76
- readonly timeoutMs: number;
77
- }> {
78
- get message() {
79
- return `Popup window not detected within ${this.timeoutMs}ms`;
80
- }
81
- }
82
-
83
- export class AuthenticationFailed extends Data.TaggedError("AuthenticationFailed")<{
84
- readonly step: string;
85
- readonly reason: string;
86
- }> {
87
- get message() {
88
- return `Authentication failed at "${this.step}": ${this.reason}`;
89
- }
90
- }
91
-
92
- export type SessionRecorderError =
93
- | SessionTimeout
94
- | BrowserLaunchFailed
95
- | ServerStartFailed
96
- | ServerNotReady
97
- | FlowExecutionFailed
98
- | SnapshotFailed
99
- | ExportFailed
100
- | BrowserMetricsFailed
101
- | PopupNotDetected
102
- | AuthenticationFailed;