@akanjs/devkit 3.0.0-beta.2 → 3.0.0-beta.21

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 (289) hide show
  1. package/README.ko.md +2 -2
  2. package/README.md +3 -2
  3. package/abstractDoc.test.ts +6 -15
  4. package/abstractDoc.ts +6 -8
  5. package/agentsIndex.test.ts +4 -7
  6. package/agentsIndex.ts +6 -22
  7. package/akanApp/BackendImportGraph.test.ts +8 -22
  8. package/akanApp/BackendImportGraph.ts +1 -20
  9. package/akanApp/akanApp.host.test.ts +1 -3
  10. package/akanApp/akanApp.host.ts +82 -254
  11. package/akanApp/devHostPolicy.test.ts +10 -34
  12. package/akanApp/devHostPolicy.ts +12 -98
  13. package/akanConfig/akanConfig.test.ts +142 -106
  14. package/akanConfig/akanConfig.ts +147 -191
  15. package/akanConfig/types.ts +4 -3
  16. package/akanContext.ts +110 -160
  17. package/akanMcpContract.ts +28 -73
  18. package/appSelectionMemory.ts +1 -4
  19. package/applicationBuildReporter.ts +37 -5
  20. package/applicationBuildRunner.test.ts +5 -3
  21. package/applicationBuildRunner.ts +54 -61
  22. package/applicationTestPreload.ts +3 -12
  23. package/artifact/implicitRootLayout.test.ts +32 -30
  24. package/artifact/implicitRootLayout.ts +58 -106
  25. package/artifact/routeSeedIndex.test.ts +7 -6
  26. package/artifact/routeSeedIndex.ts +11 -44
  27. package/biome.base.json +32 -1
  28. package/biomeBase.ts +2 -5
  29. package/cloud/cloudApi.test.ts +202 -0
  30. package/cloud/cloudApi.ts +77 -39
  31. package/cloud/configLock.test.ts +64 -0
  32. package/cloud/configLock.ts +96 -0
  33. package/cloud/constants.ts +26 -5
  34. package/cloud/globalConfig.ts +70 -32
  35. package/codeAgent/agent/AkanCodeServices.ts +97 -0
  36. package/codeAgent/agent/AkanContextFiles.ts +94 -0
  37. package/codeAgent/agent/CodeAgent.ts +551 -0
  38. package/codeAgent/agent/CodeAgentAsks.ts +66 -0
  39. package/codeAgent/agent/CodeAgentEventMapper.ts +225 -0
  40. package/codeAgent/agent/CodeAgentGate.ts +93 -0
  41. package/codeAgent/agent/CodeAgentProxy.ts +82 -0
  42. package/codeAgent/agent/CodeAgentRpcHost.ts +103 -0
  43. package/codeAgent/agent/CodeAgentRpcListener.ts +109 -0
  44. package/codeAgent/agent/CodeAgentStreamPrinter.ts +86 -0
  45. package/codeAgent/agent/CodeAgentSuspended.ts +85 -0
  46. package/codeAgent/agent/CodeAgentUi.ts +47 -0
  47. package/codeAgent/agent/CodeMailbox.ts +148 -0
  48. package/codeAgent/agent/CodeSessionFork.ts +56 -0
  49. package/codeAgent/agent/CodeSessionIndex.ts +78 -0
  50. package/codeAgent/agent/SubagentPool.ts +214 -0
  51. package/codeAgent/agent/akanCodeModel.ts +47 -0
  52. package/codeAgent/agent/akanCodePaths.ts +31 -0
  53. package/codeAgent/agent/akanContextFiles.test.ts +114 -0
  54. package/codeAgent/agent/akanSystemPrompt.ts +46 -0
  55. package/codeAgent/agent/codeAgent.test.ts +178 -0
  56. package/codeAgent/agent/codeAgentContract.test.ts +523 -0
  57. package/codeAgent/agent/codeAgentProxy.test.ts +74 -0
  58. package/codeAgent/agent/codeAgentRpcListener.test.ts +113 -0
  59. package/codeAgent/agent/codeAgentSuspended.test.ts +47 -0
  60. package/codeAgent/agent/codeMailbox.test.ts +76 -0
  61. package/codeAgent/agent/codeSessionFork.test.ts +58 -0
  62. package/codeAgent/agent/codeSessionIndex.test.ts +77 -0
  63. package/codeAgent/agent/consoleToStderr.ts +8 -0
  64. package/codeAgent/agent/jsonLines.ts +29 -0
  65. package/codeAgent/agent/stringArg.ts +5 -0
  66. package/codeAgent/feedback/DevLogFeedback.ts +82 -0
  67. package/codeAgent/feedback/PreviewChrome.ts +82 -0
  68. package/codeAgent/feedback/PreviewFeedback.ts +46 -0
  69. package/codeAgent/feedback/PreviewView.ts +95 -0
  70. package/codeAgent/feedback/TurnFeedback.ts +98 -0
  71. package/codeAgent/feedback/VerifyFeedback.ts +40 -0
  72. package/codeAgent/feedback/previewChrome.test.ts +73 -0
  73. package/codeAgent/index.ts +34 -0
  74. package/codeAgent/skills/akan-code/SKILL.md +130 -0
  75. package/codeAgent/skills/akan-debug/SKILL.md +42 -0
  76. package/codeAgent/skills/akan-deps/SKILL.md +50 -0
  77. package/codeAgent/skills/akan-err/SKILL.md +39 -0
  78. package/codeAgent/skills/akan-module/SKILL.md +45 -0
  79. package/codeAgent/skills/akan-scaffold/SKILL.md +76 -0
  80. package/codeAgent/skills/akan-scalar/SKILL.md +52 -0
  81. package/codeAgent/skills/akan-service/SKILL.md +34 -0
  82. package/codeAgent/skills/akan-store/SKILL.md +67 -0
  83. package/codeAgent/skills/akan-ui/SKILL.md +63 -0
  84. package/codeAgent/skills/akan-validate/SKILL.md +44 -0
  85. package/codeAgent/tools/AkanCli.ts +50 -0
  86. package/codeAgent/tools/AkanCodePlugins.ts +136 -0
  87. package/codeAgent/tools/AkanEditScope.ts +48 -0
  88. package/codeAgent/tools/AkanEnvKeys.ts +50 -0
  89. package/codeAgent/tools/AkanToolPack.ts +92 -0
  90. package/codeAgent/tools/AkanVerifier.ts +48 -0
  91. package/codeAgent/tools/AskToolPack.ts +99 -0
  92. package/codeAgent/tools/MailToolPack.ts +76 -0
  93. package/codeAgent/tools/McpClient.ts +187 -0
  94. package/codeAgent/tools/McpOAuth.ts +233 -0
  95. package/codeAgent/tools/McpOAuthLoopback.ts +64 -0
  96. package/codeAgent/tools/McpServerConfig.ts +129 -0
  97. package/codeAgent/tools/McpSignIn.ts +158 -0
  98. package/codeAgent/tools/McpTokenStore.ts +81 -0
  99. package/codeAgent/tools/McpToolPack.ts +199 -0
  100. package/codeAgent/tools/SessionToolPack.ts +91 -0
  101. package/codeAgent/tools/WebToolPack.ts +147 -0
  102. package/codeAgent/tools/akanCodePlugins.test.ts +677 -0
  103. package/codeAgent/tools/askToolPack.test.ts +116 -0
  104. package/codeAgent/tools/mcpOAuth.test.ts +612 -0
  105. package/codeAgent/tools/mcpServerConfig.test.ts +212 -0
  106. package/codegenLock.test.ts +4 -13
  107. package/codegenLock.ts +3 -17
  108. package/commandDecorators/argMeta.ts +1 -5
  109. package/commandDecorators/camelToKebabCase.ts +1 -0
  110. package/commandDecorators/command.ts +46 -102
  111. package/commandDecorators/commandBuilder.ts +30 -61
  112. package/commandDecorators/commandDecorators.test.ts +2 -10
  113. package/commandDecorators/dependencyBuilder.ts +10 -1
  114. package/commandDecorators/helpFormatter.ts +68 -145
  115. package/commandDecorators/index.ts +0 -2
  116. package/commandDecorators/targetMeta.ts +9 -7
  117. package/createTunnel.ts +7 -14
  118. package/dependencyScanner.test.ts +4 -16
  119. package/dependencyScanner.ts +31 -80
  120. package/devkitUtils.test.ts +48 -20
  121. package/executors.linkFallback.test.ts +103 -0
  122. package/executors.test.ts +132 -106
  123. package/executors.ts +195 -496
  124. package/fileEditor.ts +9 -37
  125. package/{getDirname.test.ts → fileSys.test.ts} +5 -3
  126. package/fileSys.ts +6 -8
  127. package/formSetterScanner.ts +3 -16
  128. package/frontendBuild/allRoutesBuilder.ts +7 -21
  129. package/frontendBuild/autoImportSync.test.ts +27 -38
  130. package/frontendBuild/autoImportSync.ts +31 -65
  131. package/frontendBuild/buildRouteClient.test.ts +62 -37
  132. package/frontendBuild/bundleDefine.ts +12 -0
  133. package/frontendBuild/clientBuildTypes.ts +5 -36
  134. package/frontendBuild/clientEntriesBundler.ts +9 -40
  135. package/frontendBuild/clientEntryDiscovery.ts +6 -41
  136. package/frontendBuild/csrArtifactBuilder.ts +6 -25
  137. package/frontendBuild/cssCandidateCache.test.ts +0 -6
  138. package/frontendBuild/cssCandidateCache.ts +6 -41
  139. package/frontendBuild/cssCompiler.ts +29 -78
  140. package/frontendBuild/cssImportResolver.ts +6 -19
  141. package/frontendBuild/devChangePlanner.ts +7 -10
  142. package/frontendBuild/devGeneratedIndexSync.test.ts +12 -27
  143. package/frontendBuild/devGeneratedIndexSync.ts +1 -4
  144. package/frontendBuild/fontOptimizer.test.ts +6 -14
  145. package/frontendBuild/fontOptimizer.ts +15 -72
  146. package/frontendBuild/fontPruner.test.ts +5 -10
  147. package/frontendBuild/fontPruner.ts +5 -20
  148. package/frontendBuild/frontendBuild.test.ts +46 -69
  149. package/frontendBuild/hmrChangeClassifier.ts +2 -2
  150. package/frontendBuild/hmrWatcher.test.ts +8 -32
  151. package/frontendBuild/hmrWatcher.ts +14 -71
  152. package/frontendBuild/pagesBundleBuilder.ts +4 -29
  153. package/frontendBuild/precompressArtifacts.ts +5 -18
  154. package/frontendBuild/routeClientBuilder.ts +23 -46
  155. package/frontendBuild/routesManifestArtifactSerializer.ts +5 -36
  156. package/frontendBuild/sourceMtimeIndex.test.ts +41 -97
  157. package/frontendBuild/sourceMtimeIndex.ts +19 -130
  158. package/frontendBuild/ssrBaseArtifactBuilder.ts +2 -8
  159. package/frontendBuild/styleContract.ts +1 -8
  160. package/frontendBuild/themeValidator.ts +4 -26
  161. package/frontendBuild/watchRootResolver.test.ts +23 -42
  162. package/frontendBuild/watchRootResolver.ts +5 -27
  163. package/getRelatedCnsts.ts +12 -92
  164. package/incrementalBuilder/buildBatch.proc.ts +29 -58
  165. package/incrementalBuilder/buildBatchProtocol.ts +8 -36
  166. package/incrementalBuilder/buildBatchRunner.test.ts +34 -0
  167. package/incrementalBuilder/buildBatchRunner.ts +10 -31
  168. package/incrementalBuilder/builderChannel.test.ts +24 -49
  169. package/incrementalBuilder/builderChannel.ts +6 -37
  170. package/incrementalBuilder/builderRequestRouter.test.ts +0 -8
  171. package/incrementalBuilder/builderRequestRouter.ts +5 -24
  172. package/incrementalBuilder/devWatchBatch.test.ts +21 -24
  173. package/incrementalBuilder/incrementalBuilder.host.test.ts +18 -55
  174. package/incrementalBuilder/incrementalBuilder.host.ts +18 -76
  175. package/incrementalBuilder/incrementalBuilder.proc.test.ts +81 -0
  176. package/incrementalBuilder/incrementalBuilder.proc.ts +49 -161
  177. package/index.ts +5 -19
  178. package/integration/devResourceProbe.ts +50 -56
  179. package/integration/devStability.integration.test.ts +47 -194
  180. package/integration/devStabilityHarness.test.ts +13 -28
  181. package/integration/devStabilityHarness.ts +65 -330
  182. package/integration/ssrMemoryProbe.ts +41 -167
  183. package/libSource.test.ts +4 -15
  184. package/libSource.ts +19 -31
  185. package/lint/__fixtures__/no-document-cookie/bad.tsx +4 -0
  186. package/lint/__fixtures__/no-document-cookie/good.tsx +7 -0
  187. package/lint/__fixtures__/no-web-only-api-outside-webkit/bad.tsx +7 -0
  188. package/lint/__fixtures__/no-web-only-api-outside-webkit/good.tsx +11 -0
  189. package/lint/__fixtures__/no-web-storage/bad.tsx +6 -0
  190. package/lint/__fixtures__/no-web-storage/good.tsx +7 -0
  191. package/lint/gritRules.test.ts +8 -24
  192. package/lint/no-deep-internal-import.grit +2 -2
  193. package/lint/no-document-cookie.grit +29 -0
  194. package/lint/no-redeclare-predefined-endpoint.grit +2 -1
  195. package/lint/no-web-only-api-outside-webkit.grit +44 -0
  196. package/lint/no-web-storage.grit +30 -0
  197. package/linter.test.ts +1 -2
  198. package/linter.ts +26 -116
  199. package/mobile/index.ts +6 -0
  200. package/mobile/mobileTarget.ts +16 -13
  201. package/mobile/nativeApi.test.ts +30 -0
  202. package/mobile/nativeApi.ts +40 -0
  203. package/mobile/nativeApp.test.ts +85 -0
  204. package/mobile/nativeApp.ts +210 -0
  205. package/mobile/nativeConfig.test.ts +199 -0
  206. package/mobile/nativeConfig.ts +184 -0
  207. package/mobile/nativeWebDir.test.ts +80 -0
  208. package/mobile/nativeWebDir.ts +62 -0
  209. package/mobile/placeholderAppId.test.ts +13 -0
  210. package/mobile/placeholderAppId.ts +16 -0
  211. package/mobile/usageDescriptions.test.ts +27 -0
  212. package/mobile/usageDescriptions.ts +24 -0
  213. package/package.json +10 -10
  214. package/packageExports.test.ts +3 -18
  215. package/packageExportsMap.ts +3 -19
  216. package/piDependencyPins.test.ts +46 -0
  217. package/platformTest/BunTestReport.test.ts +60 -0
  218. package/platformTest/BunTestReport.ts +65 -0
  219. package/platformTest/IdleWatchedProcess.test.ts +56 -0
  220. package/platformTest/IdleWatchedProcess.ts +73 -0
  221. package/platformTest/LinuxDockerTarget.ts +105 -0
  222. package/platformTest/PlatformTestRun.test.ts +64 -0
  223. package/platformTest/PlatformTestRun.ts +141 -0
  224. package/platformTest/PlatformTestTarget.ts +142 -0
  225. package/platformTest/TestSnapshot.test.ts +72 -0
  226. package/platformTest/TestSnapshot.ts +103 -0
  227. package/platformTest/WindowsSshTarget.ts +151 -0
  228. package/prompter.ts +3 -13
  229. package/qualityScanner.test.ts +9 -26
  230. package/qualityScanner.ts +200 -286
  231. package/recipeScanner.test.ts +7 -12
  232. package/recipeScanner.ts +9 -38
  233. package/repoIdentity.ts +2 -9
  234. package/routeSourceValidator.test.ts +0 -1
  235. package/routeSourceValidator.ts +7 -42
  236. package/scanInfo.ts +91 -225
  237. package/selectModel.ts +1 -2
  238. package/semver.ts +3 -5
  239. package/slicePlanner.test.ts +6 -24
  240. package/slicePlanner.ts +11 -32
  241. package/spinner.test.ts +3 -8
  242. package/spinner.ts +4 -16
  243. package/sshTunnel.ts +1 -6
  244. package/ssrScanner.test.ts +1 -6
  245. package/ssrScanner.ts +103 -113
  246. package/stripAnsi.ts +3 -0
  247. package/subspace.test.ts +30 -25
  248. package/subspace.ts +81 -115
  249. package/subspaceConfig.ts +11 -9
  250. package/testHelpers.ts +194 -0
  251. package/transforms/asyncDefaultExportDetector.ts +3 -11
  252. package/transforms/barrelAnalyzer.ts +43 -135
  253. package/transforms/barrelImportsPlugin.ts +38 -175
  254. package/transforms/externalizeFrameworkPlugin.test.ts +39 -118
  255. package/transforms/externalizeFrameworkPlugin.ts +13 -87
  256. package/transforms/moduleSyntax.ts +32 -0
  257. package/transforms/rscUseClientTransform.ts +35 -20
  258. package/transforms/transforms.test.ts +153 -44
  259. package/transforms/tsconfigPackageResolver.test.ts +6 -24
  260. package/transforms/useClientBundlePlugin.ts +2 -22
  261. package/typeChecker.ts +7 -63
  262. package/types.ts +1 -0
  263. package/uploadRelease.ts +10 -25
  264. package/workflow/artifacts.ts +18 -0
  265. package/workflow/executor.test.ts +1 -12
  266. package/workflow/executor.ts +101 -110
  267. package/workflow/index.ts +0 -1
  268. package/workflow/moduleIndex.test.ts +4 -15
  269. package/workflow/moduleIndex.ts +9 -49
  270. package/workflow/plan.ts +18 -25
  271. package/workflow/render.ts +80 -96
  272. package/workflow/rolloutGate.test.ts +1 -1
  273. package/workflow/source.ts +52 -69
  274. package/workflow/sourceAst.ts +50 -0
  275. package/workspaceLayout.test.ts +13 -3
  276. package/workspaceLayout.ts +20 -23
  277. package/abstractCompactor.ts +0 -112
  278. package/aiEditor.test.ts +0 -60
  279. package/aiEditor.ts +0 -387
  280. package/applicationReleasePackager.ts +0 -209
  281. package/capacitorApp.test.ts +0 -372
  282. package/capacitorApp.ts +0 -1648
  283. package/commandDecorators/commandMeta.ts +0 -7
  284. package/commandDecorators/types.ts +0 -10
  285. package/getDirname.ts +0 -4
  286. package/guideline.ts +0 -19
  287. package/local/optimize-resource/ipcprobe/child.ts +0 -1
  288. package/local/optimize-resource/ipcprobe/parent.ts +0 -11
  289. package/workflow/primitive.ts +0 -59
@@ -3,58 +3,51 @@ import path from "node:path";
3
3
 
4
4
  export type DevResourceRole = "host" | "builder" | "batch" | "gateway" | "replica" | "rsc" | "other";
5
5
 
6
- export interface DevResourceProc {
6
+ export interface DevResourceProc<Role extends string = DevResourceRole> {
7
7
  pid: number;
8
8
  ppid: number;
9
9
  rssMb: number;
10
10
  cpuSec: number;
11
- role: DevResourceRole;
11
+ role: Role;
12
12
  command: string;
13
13
  }
14
14
 
15
15
  export interface DevResourceProbeOptions {
16
16
  appName: string;
17
- /** Must be the workspace root: package resolution has to match the real dev processes. */
17
+ // Must be the workspace root: package resolution has to match the real dev processes.
18
18
  workspaceRoot: string;
19
- /** A tenant runs `node_modules/@akanjs/cli`; this repo runs its own `dist` build. */
20
19
  cliEntry: string;
21
20
  port: number;
22
21
  edits: number;
23
22
  idleSeconds: number;
24
- /** `0` leaves idle suspend at its default; any other value also arms the suspend phase. */
23
+ // `0` leaves idle suspend at its default; any other value also arms the suspend phase.
25
24
  suspendSeconds: number;
26
- /** App-relative file to append a comment to, once per edit. */
27
25
  editPath: string;
28
26
  logPath: string;
29
27
  }
30
28
 
31
- /**
32
- * Process-tree RSS over boot, browse, edits and idle-suspend — probe #1 of
33
- * `04-measurement-harness.md`, and the source of every idle/warm/suspended number in the
34
- * `optimize-resource` docs.
35
- *
36
- * bun pkgs/@akanjs/devkit/integration/devResourceProbe.ts <app> [--idle=120] [--edits=3] [--suspend=60]
37
- *
38
- * Run it from the workspace root. Two things it exists to get right, both learned the hard way:
39
- * it walks the process tree to a **fixpoint** (the tree is seven levels deep in places, so a
40
- * fixed-depth walk silently misses the workers), and it **restores the edited file** in a `finally`
41
- * so a killed probe cannot leave a comment in the tree.
42
- *
43
- * On macOS, a plateau that drops with no activity is the OS trimming idle pages, not convergence —
44
- * report both numbers rather than the lower one.
45
- */
29
+ // Usage, from the workspace root:
30
+ // bun pkgs/@akanjs/devkit/integration/devResourceProbe.ts <app> [--idle=120] [--edits=3] [--suspend=60]
31
+ // On macOS a plateau that drops with no activity is the OS trimming idle pages, not convergence; report both.
46
32
  export class DevResourceProbe {
47
33
  static readonly #columns: DevResourceRole[] = ["host", "builder", "batch", "gateway", "replica", "rsc"];
48
34
 
49
- static parseArgs(argv: string[]): DevResourceProbeOptions {
35
+ static parseArgMap(argv: string[]) {
50
36
  const args = new Map(
51
37
  argv.slice(1).map((arg) => {
52
38
  const [key, value] = arg.replace(/^--/, "").split("=");
53
39
  return [key ?? "", value ?? "1"];
54
40
  }),
55
41
  );
56
- const appName = argv[0] ?? "akan";
57
- const num = (key: string, fallback: number) => Number(args.get(key) ?? fallback);
42
+ return {
43
+ appName: argv[0] ?? "akan",
44
+ args,
45
+ num: (key: string, fallback: number) => Number(args.get(key) ?? fallback),
46
+ };
47
+ }
48
+
49
+ static parseArgs(argv: string[]): DevResourceProbeOptions {
50
+ const { appName, args, num } = DevResourceProbe.parseArgMap(argv);
58
51
  return {
59
52
  appName,
60
53
  workspaceRoot: args.get("root") ?? process.cwd(),
@@ -108,7 +101,7 @@ export class DevResourceProbe {
108
101
  .catch(() => "")) !== original
109
102
  )
110
103
  await Bun.write(target, original);
111
- await this.#cleanup(host);
104
+ await DevResourceProbe.killTree(host, () => this.#sampleTree());
112
105
  }
113
106
  }
114
107
 
@@ -128,7 +121,7 @@ export class DevResourceProbe {
128
121
  console.info(`[probe] IDLE BASELINE ${idleTotal.toFixed(0)}MB`);
129
122
  await this.#reportMetrics("idle");
130
123
 
131
- // 4.2: every idle number understates, because route modules are evaluated on first request.
124
+ // Every idle number understates: route modules are evaluated on first request.
132
125
  const routes = await this.#staticRoutes();
133
126
  const first = await this.#browse(routes);
134
127
  console.info(`[probe] browsed ${routes.length} static route(s): ok=${first.ok} failed=${first.failed}`);
@@ -169,8 +162,14 @@ export class DevResourceProbe {
169
162
  return "other";
170
163
  }
171
164
 
172
- /** One `ps`, then walk from the host pid to a fixpoint — the tree is seven levels deep in places. */
173
- async #sampleTree(): Promise<DevResourceProc[]> {
165
+ #sampleTree(): Promise<DevResourceProc[]> {
166
+ return DevResourceProbe.sampleTree(this.#hostPid, (command) => this.#roleOf(command));
167
+ }
168
+
169
+ static async sampleTree<Role extends string>(
170
+ rootPid: number,
171
+ roleOf: (command: string) => Role,
172
+ ): Promise<DevResourceProc<Role>[]> {
174
173
  const proc = Bun.spawn(["ps", "-eo", "pid=,ppid=,rss=,time=,command="], { stdout: "pipe" });
175
174
  const text = await new Response(proc.stdout).text();
176
175
  await proc.exited;
@@ -192,20 +191,36 @@ export class DevResourceProbe {
192
191
  ppid: Number(ppid),
193
192
  rssMb: Number(rss) / 1024,
194
193
  cpuSec,
195
- role: this.#roleOf(command ?? ""),
194
+ role: roleOf(command ?? ""),
196
195
  command: command ?? "",
197
- } satisfies DevResourceProc;
196
+ } satisfies DevResourceProc<Role>;
198
197
  })
199
- .filter((proc): proc is DevResourceProc => proc !== null);
200
- const kept = new Map<number, DevResourceProc>();
201
- const root = all.find((proc) => proc.pid === this.#hostPid);
202
- if (root) kept.set(this.#hostPid, root);
198
+ .filter((proc): proc is DevResourceProc<Role> => proc !== null);
199
+ const kept = new Map<number, DevResourceProc<Role>>();
200
+ const root = all.find((proc) => proc.pid === rootPid);
201
+ if (root) kept.set(rootPid, root);
203
202
  for (let pass = 0; pass < 12; pass++) {
204
203
  const before = kept.size;
205
204
  for (const proc of all) if (kept.has(proc.ppid) && !kept.has(proc.pid)) kept.set(proc.pid, proc);
206
205
  if (kept.size === before) break;
207
206
  }
208
- return [...kept.values()].filter((proc) => proc.role !== "other" || proc.pid === this.#hostPid);
207
+ return [...kept.values()].filter((proc) => proc.role !== "other" || proc.pid === rootPid);
208
+ }
209
+
210
+ static async killTree(
211
+ root: { kill: (signal: NodeJS.Signals) => void },
212
+ sampleTree: () => Promise<{ pid: number }[]>,
213
+ ): Promise<void> {
214
+ for (const proc of (await sampleTree()).reverse()) {
215
+ try {
216
+ process.kill(proc.pid, "SIGKILL");
217
+ } catch {}
218
+ }
219
+ try {
220
+ root.kill("SIGKILL");
221
+ } catch {}
222
+ await Bun.sleep(1_000);
223
+ console.info(`[probe] survivors after kill: ${(await sampleTree()).length}`);
209
224
  }
210
225
 
211
226
  #row(label: string, procs: DevResourceProc[]): number {
@@ -221,10 +236,6 @@ export class DevResourceProbe {
221
236
  return total;
222
237
  }
223
238
 
224
- /**
225
- * Static route urls from the page tree: `(group)` segments are stripped, and a route with a
226
- * `[dynamic]` segment is skipped because it needs a real id to render.
227
- */
228
239
  async #staticRoutes(): Promise<string[]> {
229
240
  const glob = new Bun.Glob("**/_index.tsx");
230
241
  const cwd = path.join(this.#options.workspaceRoot, "apps", this.#options.appName, "page");
@@ -258,7 +269,6 @@ export class DevResourceProbe {
258
269
  return { ok, failed };
259
270
  }
260
271
 
261
- /** Only the counters 4.2 asks for; the raw payload is hundreds of fields. */
262
272
  async #reportMetrics(label: string): Promise<void> {
263
273
  const child = await (async () => {
264
274
  try {
@@ -285,9 +295,6 @@ export class DevResourceProbe {
285
295
  "rscWorkerRecycleCount",
286
296
  "httpFullSsrCount",
287
297
  ];
288
- // `rssBytes` is the replica's own; the RSC worker is a separate process reporting under
289
- // `rscWorker*`. These used to be the same field, because the worker's report shadowed the
290
- // replica's — so this line printed the worker's RSS labelled as the child's.
291
298
  const toMb = (bytes: unknown) => (Number(bytes ?? 0) / 1024 / 1024).toFixed(0);
292
299
  const parts = keys.map((key) => `${key}=${child[key] ?? "?"}`);
293
300
  console.info(
@@ -306,19 +313,6 @@ export class DevResourceProbe {
306
313
  }
307
314
  return false;
308
315
  }
309
-
310
- async #cleanup(host: { kill: (signal: NodeJS.Signals) => void }): Promise<void> {
311
- for (const proc of (await this.#sampleTree()).reverse()) {
312
- try {
313
- process.kill(proc.pid, "SIGKILL");
314
- } catch {}
315
- }
316
- try {
317
- host.kill("SIGKILL");
318
- } catch {}
319
- await Bun.sleep(1_000);
320
- console.info(`[probe] survivors after kill: ${(await this.#sampleTree()).length}`);
321
- }
322
316
  }
323
317
 
324
318
  if (import.meta.main) await new DevResourceProbe(DevResourceProbe.parseArgs(process.argv.slice(2))).run();