@akanjs/devkit 3.0.0-beta.9 → 3.0.0

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 (341) hide show
  1. package/DEV_RUNTIME_KNOBS.md +44 -26
  2. package/README.ko.md +21 -7
  3. package/README.md +17 -8
  4. package/abstractDoc.test.ts +6 -15
  5. package/abstractDoc.ts +6 -8
  6. package/agentsIndex.test.ts +4 -7
  7. package/agentsIndex.ts +6 -22
  8. package/akanApp/BackendImportGraph.test.ts +8 -22
  9. package/akanApp/BackendImportGraph.ts +1 -20
  10. package/akanApp/akanApp.host.test.ts +56 -3
  11. package/akanApp/akanApp.host.ts +218 -278
  12. package/akanApp/devBootLatch.test.ts +39 -0
  13. package/akanApp/devBootLatch.ts +39 -0
  14. package/akanApp/devHostPolicy.test.ts +81 -35
  15. package/akanApp/devHostPolicy.ts +41 -102
  16. package/akanConfig/akanBin.test.ts +62 -0
  17. package/akanConfig/akanBin.ts +78 -0
  18. package/akanConfig/akanConfig.test.ts +439 -141
  19. package/akanConfig/akanConfig.ts +359 -275
  20. package/akanConfig/index.ts +1 -0
  21. package/akanConfig/types.ts +22 -8
  22. package/akanContext.ts +110 -160
  23. package/akanMcpContract.ts +28 -73
  24. package/appSelectionMemory.ts +1 -4
  25. package/applicationBuildReporter.ts +37 -5
  26. package/applicationBuildRunner.test.ts +41 -5
  27. package/applicationBuildRunner.ts +71 -63
  28. package/applicationTestPreload.ts +3 -12
  29. package/artifact/implicitRootLayout.test.ts +32 -30
  30. package/artifact/implicitRootLayout.ts +58 -106
  31. package/artifact/routeSeedIndex.test.ts +7 -6
  32. package/artifact/routeSeedIndex.ts +11 -44
  33. package/biome.base.json +35 -2
  34. package/biomeBase.ts +2 -5
  35. package/cloud/cloudApi.test.ts +202 -0
  36. package/cloud/cloudApi.ts +77 -39
  37. package/cloud/configLock.test.ts +64 -0
  38. package/cloud/configLock.ts +96 -0
  39. package/cloud/constants.ts +26 -5
  40. package/cloud/globalConfig.ts +71 -32
  41. package/codeAgent/agent/AkanCodeServices.ts +97 -0
  42. package/codeAgent/agent/AkanContextFiles.ts +94 -0
  43. package/codeAgent/agent/CodeAgent.ts +551 -0
  44. package/codeAgent/agent/CodeAgentAsks.ts +66 -0
  45. package/codeAgent/agent/CodeAgentEventMapper.ts +225 -0
  46. package/codeAgent/agent/CodeAgentGate.ts +93 -0
  47. package/codeAgent/agent/CodeAgentProxy.ts +82 -0
  48. package/codeAgent/agent/CodeAgentRpcHost.ts +103 -0
  49. package/codeAgent/agent/CodeAgentRpcListener.ts +109 -0
  50. package/codeAgent/agent/CodeAgentStreamPrinter.ts +86 -0
  51. package/codeAgent/agent/CodeAgentSuspended.ts +85 -0
  52. package/codeAgent/agent/CodeAgentUi.ts +47 -0
  53. package/codeAgent/agent/CodeMailbox.ts +148 -0
  54. package/codeAgent/agent/CodeSessionFork.ts +56 -0
  55. package/codeAgent/agent/CodeSessionIndex.ts +78 -0
  56. package/codeAgent/agent/SubagentPool.ts +214 -0
  57. package/codeAgent/agent/akanCodeModel.ts +47 -0
  58. package/codeAgent/agent/akanCodePaths.ts +31 -0
  59. package/codeAgent/agent/akanContextFiles.test.ts +114 -0
  60. package/codeAgent/agent/akanSystemPrompt.ts +46 -0
  61. package/codeAgent/agent/codeAgent.test.ts +178 -0
  62. package/codeAgent/agent/codeAgentContract.test.ts +523 -0
  63. package/codeAgent/agent/codeAgentProxy.test.ts +74 -0
  64. package/codeAgent/agent/codeAgentRpcListener.test.ts +113 -0
  65. package/codeAgent/agent/codeAgentSuspended.test.ts +47 -0
  66. package/codeAgent/agent/codeMailbox.test.ts +76 -0
  67. package/codeAgent/agent/codeSessionFork.test.ts +58 -0
  68. package/codeAgent/agent/codeSessionIndex.test.ts +77 -0
  69. package/codeAgent/agent/consoleToStderr.ts +8 -0
  70. package/codeAgent/agent/jsonLines.ts +29 -0
  71. package/codeAgent/agent/stringArg.ts +5 -0
  72. package/codeAgent/feedback/DevLogFeedback.ts +82 -0
  73. package/codeAgent/feedback/PreviewChrome.ts +82 -0
  74. package/codeAgent/feedback/PreviewFeedback.ts +46 -0
  75. package/codeAgent/feedback/PreviewView.ts +95 -0
  76. package/codeAgent/feedback/TurnFeedback.ts +98 -0
  77. package/codeAgent/feedback/VerifyFeedback.ts +40 -0
  78. package/codeAgent/feedback/previewChrome.test.ts +73 -0
  79. package/codeAgent/index.ts +34 -0
  80. package/codeAgent/skills/akan-code/SKILL.md +130 -0
  81. package/codeAgent/skills/akan-debug/SKILL.md +42 -0
  82. package/codeAgent/skills/akan-deps/SKILL.md +50 -0
  83. package/codeAgent/skills/akan-err/SKILL.md +39 -0
  84. package/codeAgent/skills/akan-module/SKILL.md +45 -0
  85. package/codeAgent/skills/akan-scaffold/SKILL.md +76 -0
  86. package/codeAgent/skills/akan-scalar/SKILL.md +52 -0
  87. package/codeAgent/skills/akan-service/SKILL.md +34 -0
  88. package/codeAgent/skills/akan-store/SKILL.md +67 -0
  89. package/codeAgent/skills/akan-ui/SKILL.md +63 -0
  90. package/codeAgent/skills/akan-validate/SKILL.md +44 -0
  91. package/codeAgent/tools/AkanCli.ts +50 -0
  92. package/codeAgent/tools/AkanCodePlugins.ts +136 -0
  93. package/codeAgent/tools/AkanEditScope.ts +48 -0
  94. package/codeAgent/tools/AkanEnvKeys.ts +50 -0
  95. package/codeAgent/tools/AkanToolPack.ts +92 -0
  96. package/codeAgent/tools/AkanVerifier.ts +48 -0
  97. package/codeAgent/tools/AskToolPack.ts +99 -0
  98. package/codeAgent/tools/MailToolPack.ts +76 -0
  99. package/codeAgent/tools/McpClient.ts +187 -0
  100. package/codeAgent/tools/McpOAuth.ts +233 -0
  101. package/codeAgent/tools/McpOAuthLoopback.ts +64 -0
  102. package/codeAgent/tools/McpServerConfig.ts +129 -0
  103. package/codeAgent/tools/McpSignIn.ts +158 -0
  104. package/codeAgent/tools/McpTokenStore.ts +81 -0
  105. package/codeAgent/tools/McpToolPack.ts +199 -0
  106. package/codeAgent/tools/SessionToolPack.ts +91 -0
  107. package/codeAgent/tools/WebToolPack.ts +147 -0
  108. package/codeAgent/tools/akanCodePlugins.test.ts +677 -0
  109. package/codeAgent/tools/askToolPack.test.ts +116 -0
  110. package/codeAgent/tools/mcpOAuth.test.ts +612 -0
  111. package/codeAgent/tools/mcpServerConfig.test.ts +212 -0
  112. package/codegenLock.test.ts +4 -13
  113. package/codegenLock.ts +3 -17
  114. package/commandDecorators/argMeta.ts +1 -5
  115. package/commandDecorators/camelToKebabCase.ts +1 -0
  116. package/commandDecorators/command.ts +46 -102
  117. package/commandDecorators/commandBuilder.ts +30 -61
  118. package/commandDecorators/commandDecorators.test.ts +2 -10
  119. package/commandDecorators/dependencyBuilder.ts +10 -1
  120. package/commandDecorators/helpFormatter.ts +68 -145
  121. package/commandDecorators/index.ts +0 -2
  122. package/commandDecorators/targetMeta.ts +9 -7
  123. package/createTunnel.ts +7 -14
  124. package/csrE2e/csrE2eHarness.fixture.ts +505 -0
  125. package/csrE2e/csrFastRefresh.e2e.test.ts +233 -0
  126. package/csrE2e/csrPageStack.e2e.test.ts +252 -0
  127. package/csrE2e/csrPatchFirst.e2e.test.ts +87 -0
  128. package/csrE2e/csrRootLayout.e2e.test.ts +134 -0
  129. package/csrE2e/devHmrLatency.e2e.test.ts +391 -0
  130. package/csrE2e/registryVendor.e2e.test.ts +221 -0
  131. package/csrE2e/ssrRegistry.e2e.test.ts +644 -0
  132. package/dependencyScanner.test.ts +4 -16
  133. package/dependencyScanner.ts +31 -80
  134. package/devkitUtils.test.ts +48 -20
  135. package/executors.linkFallback.test.ts +103 -0
  136. package/executors.test.ts +176 -106
  137. package/executors.ts +212 -498
  138. package/fileEditor.ts +9 -37
  139. package/{getDirname.test.ts → fileSys.test.ts} +5 -3
  140. package/fileSys.ts +22 -9
  141. package/formSetterScanner.ts +3 -16
  142. package/frontendBuild/allRoutesBuilder.ts +7 -21
  143. package/frontendBuild/autoImportSync.test.ts +27 -38
  144. package/frontendBuild/autoImportSync.ts +31 -65
  145. package/frontendBuild/buildRouteClient.test.ts +123 -37
  146. package/frontendBuild/bundleDefine.test.ts +12 -0
  147. package/frontendBuild/bundleDefine.ts +16 -0
  148. package/frontendBuild/clientBuildTypes.ts +5 -36
  149. package/frontendBuild/clientEntriesBundler.ts +9 -40
  150. package/frontendBuild/clientEntryDiscovery.test.ts +112 -0
  151. package/frontendBuild/clientEntryDiscovery.ts +122 -110
  152. package/frontendBuild/csrArtifactBuilder.ts +9 -31
  153. package/frontendBuild/csrDevArtifactWriter.test.ts +151 -0
  154. package/frontendBuild/csrDevArtifactWriter.ts +307 -0
  155. package/frontendBuild/csrDevBundler.test.ts +66 -0
  156. package/frontendBuild/csrDevBundler.ts +95 -0
  157. package/frontendBuild/csrDevFactoryCheck.test.ts +33 -0
  158. package/frontendBuild/csrDevFactoryCheck.ts +39 -0
  159. package/frontendBuild/csrDevModuleCompiler.test.ts +293 -0
  160. package/frontendBuild/csrDevModuleCompiler.ts +422 -0
  161. package/frontendBuild/csrDevPatcher.test.ts +572 -0
  162. package/frontendBuild/csrDevPatcher.ts +548 -0
  163. package/frontendBuild/csrDevPaths.ts +145 -0
  164. package/frontendBuild/csrDevResolver.test.ts +239 -0
  165. package/frontendBuild/csrDevResolver.ts +363 -0
  166. package/frontendBuild/csrDevTypes.ts +61 -0
  167. package/frontendBuild/csrEntryFiles.ts +24 -0
  168. package/frontendBuild/cssCandidateCache.test.ts +0 -6
  169. package/frontendBuild/cssCandidateCache.ts +6 -41
  170. package/frontendBuild/cssCompiler.ts +31 -82
  171. package/frontendBuild/cssImportResolver.ts +6 -19
  172. package/frontendBuild/devChangePlanner.ts +7 -10
  173. package/frontendBuild/devGeneratedIndexSync.test.ts +12 -27
  174. package/frontendBuild/devGeneratedIndexSync.ts +1 -4
  175. package/frontendBuild/devRegistryBundler.ts +192 -0
  176. package/frontendBuild/fontOptimizer.test.ts +6 -14
  177. package/frontendBuild/fontOptimizer.ts +15 -72
  178. package/frontendBuild/fontPruner.test.ts +5 -10
  179. package/frontendBuild/fontPruner.ts +5 -20
  180. package/frontendBuild/frontendBuild.test.ts +57 -70
  181. package/frontendBuild/hmrChangeClassifier.ts +2 -2
  182. package/frontendBuild/hmrWatcher.test.ts +59 -32
  183. package/frontendBuild/hmrWatcher.ts +31 -74
  184. package/frontendBuild/index.ts +4 -0
  185. package/frontendBuild/pagesBundleBuilder.ts +28 -30
  186. package/frontendBuild/pagesEntrySourceGenerator.ts +56 -6
  187. package/frontendBuild/precompressArtifacts.ts +5 -18
  188. package/frontendBuild/registryMetadataFingerprint.test.ts +63 -0
  189. package/frontendBuild/registryMetadataFingerprint.ts +28 -0
  190. package/frontendBuild/routeClientBuilder.ts +100 -62
  191. package/frontendBuild/routesManifestArtifactSerializer.ts +5 -36
  192. package/frontendBuild/serverGraphFile.test.ts +77 -0
  193. package/frontendBuild/serverGraphFile.ts +93 -0
  194. package/frontendBuild/sourceMtimeIndex.test.ts +41 -97
  195. package/frontendBuild/sourceMtimeIndex.ts +19 -130
  196. package/frontendBuild/ssrBaseArtifactBuilder.ts +19 -13
  197. package/frontendBuild/ssrDevBundler.ts +85 -0
  198. package/frontendBuild/styleContract.ts +1 -8
  199. package/frontendBuild/themeValidator.ts +4 -26
  200. package/frontendBuild/watchRootResolver.test.ts +23 -42
  201. package/frontendBuild/watchRootResolver.ts +5 -27
  202. package/getRelatedCnsts.ts +12 -92
  203. package/incrementalBuilder/buildBatch.proc.ts +147 -63
  204. package/incrementalBuilder/buildBatchProtocol.ts +13 -38
  205. package/incrementalBuilder/buildBatchRunner.test.ts +65 -0
  206. package/incrementalBuilder/buildBatchRunner.ts +26 -38
  207. package/incrementalBuilder/builderChannel.test.ts +24 -49
  208. package/incrementalBuilder/builderChannel.ts +6 -37
  209. package/incrementalBuilder/builderRequestRouter.test.ts +0 -8
  210. package/incrementalBuilder/builderRequestRouter.ts +5 -24
  211. package/incrementalBuilder/builderWorkQueue.test.ts +94 -0
  212. package/incrementalBuilder/builderWorkQueue.ts +126 -0
  213. package/incrementalBuilder/devWatchBatch.test.ts +21 -24
  214. package/incrementalBuilder/incrementalBuilder.host.test.ts +53 -56
  215. package/incrementalBuilder/incrementalBuilder.host.ts +68 -81
  216. package/incrementalBuilder/incrementalBuilder.proc.test.ts +270 -0
  217. package/incrementalBuilder/incrementalBuilder.proc.ts +596 -208
  218. package/index.ts +5 -19
  219. package/integration/devResourceProbe.ts +50 -56
  220. package/integration/devStability.integration.test.ts +105 -199
  221. package/integration/devStabilityHarness.test.ts +13 -28
  222. package/integration/devStabilityHarness.ts +65 -330
  223. package/integration/ssrMemoryProbe.ts +41 -167
  224. package/libSource.test.ts +4 -15
  225. package/libSource.ts +19 -31
  226. package/lint/__fixtures__/no-document-cookie/bad.tsx +4 -0
  227. package/lint/__fixtures__/no-document-cookie/good.tsx +7 -0
  228. package/lint/__fixtures__/no-web-only-api-outside-webkit/bad.tsx +7 -0
  229. package/lint/__fixtures__/no-web-only-api-outside-webkit/good.tsx +11 -0
  230. package/lint/__fixtures__/no-web-storage/bad.tsx +6 -0
  231. package/lint/__fixtures__/no-web-storage/good.tsx +7 -0
  232. package/lint/gritRules.test.ts +8 -24
  233. package/lint/no-deep-internal-import.grit +2 -2
  234. package/lint/no-document-cookie.grit +29 -0
  235. package/lint/no-redeclare-predefined-endpoint.grit +2 -1
  236. package/lint/no-web-only-api-outside-webkit.grit +44 -0
  237. package/lint/no-web-storage.grit +30 -0
  238. package/linter.test.ts +1 -2
  239. package/linter.ts +26 -116
  240. package/mobile/desktopBin.test.ts +182 -0
  241. package/mobile/desktopBin.ts +144 -0
  242. package/mobile/desktopServerStage.test.ts +252 -0
  243. package/mobile/desktopServerStage.ts +178 -0
  244. package/mobile/index.ts +9 -0
  245. package/mobile/mobileTarget.test.ts +57 -8
  246. package/mobile/mobileTarget.ts +45 -26
  247. package/mobile/nativeApi.test.ts +30 -0
  248. package/mobile/nativeApi.ts +40 -0
  249. package/mobile/nativeApp.test.ts +184 -0
  250. package/mobile/nativeApp.ts +454 -0
  251. package/mobile/nativeAppLine.test.ts +69 -0
  252. package/mobile/nativeAppLine.ts +71 -0
  253. package/mobile/nativeConfig.test.ts +438 -0
  254. package/mobile/nativeConfig.ts +294 -0
  255. package/mobile/nativePluginFolders.test.ts +81 -0
  256. package/mobile/nativePluginFolders.ts +60 -0
  257. package/mobile/nativeWebDir.test.ts +80 -0
  258. package/mobile/nativeWebDir.ts +66 -0
  259. package/mobile/placeholderAppId.test.ts +13 -0
  260. package/mobile/placeholderAppId.ts +16 -0
  261. package/mobile/usageDescriptions.test.ts +27 -0
  262. package/mobile/usageDescriptions.ts +24 -0
  263. package/package.json +11 -11
  264. package/packageExports.test.ts +3 -18
  265. package/packageExportsMap.ts +3 -19
  266. package/piDependencyPins.test.ts +46 -0
  267. package/platformTest/BunTestReport.test.ts +60 -0
  268. package/platformTest/BunTestReport.ts +65 -0
  269. package/platformTest/IdleWatchedProcess.test.ts +56 -0
  270. package/platformTest/IdleWatchedProcess.ts +73 -0
  271. package/platformTest/LinuxDockerTarget.ts +105 -0
  272. package/platformTest/PlatformTestRun.test.ts +64 -0
  273. package/platformTest/PlatformTestRun.ts +141 -0
  274. package/platformTest/PlatformTestTarget.ts +142 -0
  275. package/platformTest/TestSnapshot.test.ts +72 -0
  276. package/platformTest/TestSnapshot.ts +103 -0
  277. package/platformTest/WindowsSshTarget.ts +151 -0
  278. package/prompter.ts +3 -13
  279. package/qualityScanner.test.ts +9 -26
  280. package/qualityScanner.ts +200 -286
  281. package/recipeScanner.test.ts +7 -12
  282. package/recipeScanner.ts +9 -38
  283. package/repoIdentity.ts +2 -9
  284. package/routeSourceValidator.test.ts +0 -1
  285. package/routeSourceValidator.ts +7 -42
  286. package/scanInfo.ts +91 -225
  287. package/selectModel.ts +1 -2
  288. package/semver.ts +3 -5
  289. package/slicePlanner.test.ts +6 -24
  290. package/slicePlanner.ts +11 -32
  291. package/spinner.test.ts +3 -8
  292. package/spinner.ts +4 -16
  293. package/sshTunnel.ts +1 -6
  294. package/ssrScanner.test.ts +1 -6
  295. package/ssrScanner.ts +103 -113
  296. package/stripAnsi.ts +3 -0
  297. package/subspace.test.ts +9 -25
  298. package/subspace.ts +48 -115
  299. package/subspaceConfig.ts +3 -11
  300. package/testHelpers.ts +194 -0
  301. package/transforms/asyncDefaultExportDetector.ts +3 -11
  302. package/transforms/barrelAnalyzer.ts +43 -135
  303. package/transforms/barrelImportsPlugin.ts +38 -175
  304. package/transforms/externalizeFrameworkPlugin.test.ts +39 -118
  305. package/transforms/externalizeFrameworkPlugin.ts +13 -87
  306. package/transforms/moduleSyntax.ts +32 -0
  307. package/transforms/rscUseClientTransform.ts +42 -20
  308. package/transforms/serverEnvPlugin.test.ts +103 -0
  309. package/transforms/serverEnvPlugin.ts +41 -0
  310. package/transforms/transforms.test.ts +166 -44
  311. package/transforms/tsconfigPackageResolver.test.ts +6 -24
  312. package/transforms/useClientBundlePlugin.ts +6 -23
  313. package/typeChecker.ts +7 -63
  314. package/types.ts +2 -0
  315. package/uploadRelease.ts +10 -25
  316. package/workflow/artifacts.ts +18 -0
  317. package/workflow/executor.test.ts +1 -12
  318. package/workflow/executor.ts +101 -110
  319. package/workflow/index.ts +0 -1
  320. package/workflow/moduleIndex.test.ts +4 -15
  321. package/workflow/moduleIndex.ts +9 -49
  322. package/workflow/plan.ts +18 -25
  323. package/workflow/render.ts +80 -96
  324. package/workflow/rolloutGate.test.ts +1 -1
  325. package/workflow/source.ts +52 -69
  326. package/workflow/sourceAst.ts +50 -0
  327. package/workspaceLayout.test.ts +18 -3
  328. package/workspaceLayout.ts +22 -23
  329. package/abstractCompactor.ts +0 -112
  330. package/aiEditor.test.ts +0 -60
  331. package/aiEditor.ts +0 -387
  332. package/applicationReleasePackager.ts +0 -209
  333. package/capacitorApp.test.ts +0 -372
  334. package/capacitorApp.ts +0 -1648
  335. package/commandDecorators/commandMeta.ts +0 -7
  336. package/commandDecorators/types.ts +0 -10
  337. package/getDirname.ts +0 -4
  338. package/guideline.ts +0 -19
  339. package/local/optimize-resource/ipcprobe/child.ts +0 -1
  340. package/local/optimize-resource/ipcprobe/parent.ts +0 -11
  341. package/workflow/primitive.ts +0 -59
package/index.ts CHANGED
@@ -1,38 +1,23 @@
1
- // Types only, deliberately. This barrel re-exports all 40 devkit facets, so a single *value* import
2
- // from it loads every one of them — measured at 417MB / 654ms, versus 38MB / 38ms for the one subpath
3
- // the caller actually needed. That is how `commandDecorators/command.ts` silently put ink, typescript,
4
- // ssh2, @trapezedev/project, @langchain/* and the cloud stack into every process that registered a CLI
5
- // command, and it is the single largest regression this package can suffer from a one-line edit.
6
- //
7
- // `export type *` erases at runtime (verified on Bun 1.3.14: the re-exported module is never loaded),
8
- // so `import type { App } from "@akanjs/devkit"` stays free and readable while a value import fails to
9
- // compile with a self-explaining error:
10
- //
11
- // TS1362: 'FileSys' cannot be used as a value because it was exported using 'export type'.
12
- //
13
- // Import values from the owning facet instead: `import { FileSys } from "@akanjs/devkit/fileSys"`.
14
- // Keep this file type-only; do not "fix" a TS1362 by widening an entry back to `export *`.
15
- export type * from "./aiEditor";
1
+ // XXX: types only. A value import from this barrel loads every facet (ink, typescript, ssh2, …) into the process;
2
+ // `export type *` erases at runtime. Import values from the owning facet (`@akanjs/devkit/fileSys`) and never "fix" a
3
+ // TS1362 by widening an entry back to `export *`.
16
4
  export type * from "./akanApp";
17
5
  export type * from "./akanConfig";
18
6
  export type * from "./akanContext";
19
7
  export type * from "./akanMcpContract";
20
8
  export type * from "./applicationBuildReporter";
21
9
  export type * from "./applicationBuildRunner";
22
- export type * from "./applicationReleasePackager";
23
10
  export type * from "./applicationTestPreload";
24
11
  export type * from "./artifact";
25
- export type * from "./capacitorApp";
26
12
  export type * from "./cloud";
13
+ export type * from "./codeAgent";
27
14
  export type * from "./commandDecorators";
28
15
  export type * from "./createTunnel";
29
16
  export type * from "./dependencyScanner";
30
17
  export type * from "./executors";
31
18
  export type * from "./fileSys";
32
19
  export type * from "./frontendBuild";
33
- export type * from "./getDirname";
34
20
  export type * from "./getRelatedCnsts";
35
- export type * from "./guideline";
36
21
  export type * from "./incrementalBuilder";
37
22
  export type * from "./mobile";
38
23
  export type * from "./packageExportsMap";
@@ -42,6 +27,7 @@ export type * from "./recipeScanner";
42
27
  export type * from "./scanInfo";
43
28
  export type * from "./selectModel";
44
29
  export type * from "./spinner";
30
+ export type * from "./stripAnsi";
45
31
  export type * from "./transforms";
46
32
  export type * from "./typeChecker";
47
33
  export type * from "./types";
@@ -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();