@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.
- package/DEV_RUNTIME_KNOBS.md +44 -26
- package/README.ko.md +21 -7
- package/README.md +17 -8
- package/abstractDoc.test.ts +6 -15
- package/abstractDoc.ts +6 -8
- package/agentsIndex.test.ts +4 -7
- package/agentsIndex.ts +6 -22
- package/akanApp/BackendImportGraph.test.ts +8 -22
- package/akanApp/BackendImportGraph.ts +1 -20
- package/akanApp/akanApp.host.test.ts +56 -3
- package/akanApp/akanApp.host.ts +218 -278
- package/akanApp/devBootLatch.test.ts +39 -0
- package/akanApp/devBootLatch.ts +39 -0
- package/akanApp/devHostPolicy.test.ts +81 -35
- package/akanApp/devHostPolicy.ts +41 -102
- package/akanConfig/akanBin.test.ts +62 -0
- package/akanConfig/akanBin.ts +78 -0
- package/akanConfig/akanConfig.test.ts +439 -141
- package/akanConfig/akanConfig.ts +359 -275
- package/akanConfig/index.ts +1 -0
- package/akanConfig/types.ts +22 -8
- package/akanContext.ts +110 -160
- package/akanMcpContract.ts +28 -73
- package/appSelectionMemory.ts +1 -4
- package/applicationBuildReporter.ts +37 -5
- package/applicationBuildRunner.test.ts +41 -5
- package/applicationBuildRunner.ts +71 -63
- package/applicationTestPreload.ts +3 -12
- package/artifact/implicitRootLayout.test.ts +32 -30
- package/artifact/implicitRootLayout.ts +58 -106
- package/artifact/routeSeedIndex.test.ts +7 -6
- package/artifact/routeSeedIndex.ts +11 -44
- package/biome.base.json +35 -2
- package/biomeBase.ts +2 -5
- package/cloud/cloudApi.test.ts +202 -0
- package/cloud/cloudApi.ts +77 -39
- package/cloud/configLock.test.ts +64 -0
- package/cloud/configLock.ts +96 -0
- package/cloud/constants.ts +26 -5
- package/cloud/globalConfig.ts +71 -32
- package/codeAgent/agent/AkanCodeServices.ts +97 -0
- package/codeAgent/agent/AkanContextFiles.ts +94 -0
- package/codeAgent/agent/CodeAgent.ts +551 -0
- package/codeAgent/agent/CodeAgentAsks.ts +66 -0
- package/codeAgent/agent/CodeAgentEventMapper.ts +225 -0
- package/codeAgent/agent/CodeAgentGate.ts +93 -0
- package/codeAgent/agent/CodeAgentProxy.ts +82 -0
- package/codeAgent/agent/CodeAgentRpcHost.ts +103 -0
- package/codeAgent/agent/CodeAgentRpcListener.ts +109 -0
- package/codeAgent/agent/CodeAgentStreamPrinter.ts +86 -0
- package/codeAgent/agent/CodeAgentSuspended.ts +85 -0
- package/codeAgent/agent/CodeAgentUi.ts +47 -0
- package/codeAgent/agent/CodeMailbox.ts +148 -0
- package/codeAgent/agent/CodeSessionFork.ts +56 -0
- package/codeAgent/agent/CodeSessionIndex.ts +78 -0
- package/codeAgent/agent/SubagentPool.ts +214 -0
- package/codeAgent/agent/akanCodeModel.ts +47 -0
- package/codeAgent/agent/akanCodePaths.ts +31 -0
- package/codeAgent/agent/akanContextFiles.test.ts +114 -0
- package/codeAgent/agent/akanSystemPrompt.ts +46 -0
- package/codeAgent/agent/codeAgent.test.ts +178 -0
- package/codeAgent/agent/codeAgentContract.test.ts +523 -0
- package/codeAgent/agent/codeAgentProxy.test.ts +74 -0
- package/codeAgent/agent/codeAgentRpcListener.test.ts +113 -0
- package/codeAgent/agent/codeAgentSuspended.test.ts +47 -0
- package/codeAgent/agent/codeMailbox.test.ts +76 -0
- package/codeAgent/agent/codeSessionFork.test.ts +58 -0
- package/codeAgent/agent/codeSessionIndex.test.ts +77 -0
- package/codeAgent/agent/consoleToStderr.ts +8 -0
- package/codeAgent/agent/jsonLines.ts +29 -0
- package/codeAgent/agent/stringArg.ts +5 -0
- package/codeAgent/feedback/DevLogFeedback.ts +82 -0
- package/codeAgent/feedback/PreviewChrome.ts +82 -0
- package/codeAgent/feedback/PreviewFeedback.ts +46 -0
- package/codeAgent/feedback/PreviewView.ts +95 -0
- package/codeAgent/feedback/TurnFeedback.ts +98 -0
- package/codeAgent/feedback/VerifyFeedback.ts +40 -0
- package/codeAgent/feedback/previewChrome.test.ts +73 -0
- package/codeAgent/index.ts +34 -0
- package/codeAgent/skills/akan-code/SKILL.md +130 -0
- package/codeAgent/skills/akan-debug/SKILL.md +42 -0
- package/codeAgent/skills/akan-deps/SKILL.md +50 -0
- package/codeAgent/skills/akan-err/SKILL.md +39 -0
- package/codeAgent/skills/akan-module/SKILL.md +45 -0
- package/codeAgent/skills/akan-scaffold/SKILL.md +76 -0
- package/codeAgent/skills/akan-scalar/SKILL.md +52 -0
- package/codeAgent/skills/akan-service/SKILL.md +34 -0
- package/codeAgent/skills/akan-store/SKILL.md +67 -0
- package/codeAgent/skills/akan-ui/SKILL.md +63 -0
- package/codeAgent/skills/akan-validate/SKILL.md +44 -0
- package/codeAgent/tools/AkanCli.ts +50 -0
- package/codeAgent/tools/AkanCodePlugins.ts +136 -0
- package/codeAgent/tools/AkanEditScope.ts +48 -0
- package/codeAgent/tools/AkanEnvKeys.ts +50 -0
- package/codeAgent/tools/AkanToolPack.ts +92 -0
- package/codeAgent/tools/AkanVerifier.ts +48 -0
- package/codeAgent/tools/AskToolPack.ts +99 -0
- package/codeAgent/tools/MailToolPack.ts +76 -0
- package/codeAgent/tools/McpClient.ts +187 -0
- package/codeAgent/tools/McpOAuth.ts +233 -0
- package/codeAgent/tools/McpOAuthLoopback.ts +64 -0
- package/codeAgent/tools/McpServerConfig.ts +129 -0
- package/codeAgent/tools/McpSignIn.ts +158 -0
- package/codeAgent/tools/McpTokenStore.ts +81 -0
- package/codeAgent/tools/McpToolPack.ts +199 -0
- package/codeAgent/tools/SessionToolPack.ts +91 -0
- package/codeAgent/tools/WebToolPack.ts +147 -0
- package/codeAgent/tools/akanCodePlugins.test.ts +677 -0
- package/codeAgent/tools/askToolPack.test.ts +116 -0
- package/codeAgent/tools/mcpOAuth.test.ts +612 -0
- package/codeAgent/tools/mcpServerConfig.test.ts +212 -0
- package/codegenLock.test.ts +4 -13
- package/codegenLock.ts +3 -17
- package/commandDecorators/argMeta.ts +1 -5
- package/commandDecorators/camelToKebabCase.ts +1 -0
- package/commandDecorators/command.ts +46 -102
- package/commandDecorators/commandBuilder.ts +30 -61
- package/commandDecorators/commandDecorators.test.ts +2 -10
- package/commandDecorators/dependencyBuilder.ts +10 -1
- package/commandDecorators/helpFormatter.ts +68 -145
- package/commandDecorators/index.ts +0 -2
- package/commandDecorators/targetMeta.ts +9 -7
- package/createTunnel.ts +7 -14
- package/csrE2e/csrE2eHarness.fixture.ts +505 -0
- package/csrE2e/csrFastRefresh.e2e.test.ts +233 -0
- package/csrE2e/csrPageStack.e2e.test.ts +252 -0
- package/csrE2e/csrPatchFirst.e2e.test.ts +87 -0
- package/csrE2e/csrRootLayout.e2e.test.ts +134 -0
- package/csrE2e/devHmrLatency.e2e.test.ts +391 -0
- package/csrE2e/registryVendor.e2e.test.ts +221 -0
- package/csrE2e/ssrRegistry.e2e.test.ts +644 -0
- package/dependencyScanner.test.ts +4 -16
- package/dependencyScanner.ts +31 -80
- package/devkitUtils.test.ts +48 -20
- package/executors.linkFallback.test.ts +103 -0
- package/executors.test.ts +176 -106
- package/executors.ts +212 -498
- package/fileEditor.ts +9 -37
- package/{getDirname.test.ts → fileSys.test.ts} +5 -3
- package/fileSys.ts +22 -9
- package/formSetterScanner.ts +3 -16
- package/frontendBuild/allRoutesBuilder.ts +7 -21
- package/frontendBuild/autoImportSync.test.ts +27 -38
- package/frontendBuild/autoImportSync.ts +31 -65
- package/frontendBuild/buildRouteClient.test.ts +123 -37
- package/frontendBuild/bundleDefine.test.ts +12 -0
- package/frontendBuild/bundleDefine.ts +16 -0
- package/frontendBuild/clientBuildTypes.ts +5 -36
- package/frontendBuild/clientEntriesBundler.ts +9 -40
- package/frontendBuild/clientEntryDiscovery.test.ts +112 -0
- package/frontendBuild/clientEntryDiscovery.ts +122 -110
- package/frontendBuild/csrArtifactBuilder.ts +9 -31
- package/frontendBuild/csrDevArtifactWriter.test.ts +151 -0
- package/frontendBuild/csrDevArtifactWriter.ts +307 -0
- package/frontendBuild/csrDevBundler.test.ts +66 -0
- package/frontendBuild/csrDevBundler.ts +95 -0
- package/frontendBuild/csrDevFactoryCheck.test.ts +33 -0
- package/frontendBuild/csrDevFactoryCheck.ts +39 -0
- package/frontendBuild/csrDevModuleCompiler.test.ts +293 -0
- package/frontendBuild/csrDevModuleCompiler.ts +422 -0
- package/frontendBuild/csrDevPatcher.test.ts +572 -0
- package/frontendBuild/csrDevPatcher.ts +548 -0
- package/frontendBuild/csrDevPaths.ts +145 -0
- package/frontendBuild/csrDevResolver.test.ts +239 -0
- package/frontendBuild/csrDevResolver.ts +363 -0
- package/frontendBuild/csrDevTypes.ts +61 -0
- package/frontendBuild/csrEntryFiles.ts +24 -0
- package/frontendBuild/cssCandidateCache.test.ts +0 -6
- package/frontendBuild/cssCandidateCache.ts +6 -41
- package/frontendBuild/cssCompiler.ts +31 -82
- package/frontendBuild/cssImportResolver.ts +6 -19
- package/frontendBuild/devChangePlanner.ts +7 -10
- package/frontendBuild/devGeneratedIndexSync.test.ts +12 -27
- package/frontendBuild/devGeneratedIndexSync.ts +1 -4
- package/frontendBuild/devRegistryBundler.ts +192 -0
- package/frontendBuild/fontOptimizer.test.ts +6 -14
- package/frontendBuild/fontOptimizer.ts +15 -72
- package/frontendBuild/fontPruner.test.ts +5 -10
- package/frontendBuild/fontPruner.ts +5 -20
- package/frontendBuild/frontendBuild.test.ts +57 -70
- package/frontendBuild/hmrChangeClassifier.ts +2 -2
- package/frontendBuild/hmrWatcher.test.ts +59 -32
- package/frontendBuild/hmrWatcher.ts +31 -74
- package/frontendBuild/index.ts +4 -0
- package/frontendBuild/pagesBundleBuilder.ts +28 -30
- package/frontendBuild/pagesEntrySourceGenerator.ts +56 -6
- package/frontendBuild/precompressArtifacts.ts +5 -18
- package/frontendBuild/registryMetadataFingerprint.test.ts +63 -0
- package/frontendBuild/registryMetadataFingerprint.ts +28 -0
- package/frontendBuild/routeClientBuilder.ts +100 -62
- package/frontendBuild/routesManifestArtifactSerializer.ts +5 -36
- package/frontendBuild/serverGraphFile.test.ts +77 -0
- package/frontendBuild/serverGraphFile.ts +93 -0
- package/frontendBuild/sourceMtimeIndex.test.ts +41 -97
- package/frontendBuild/sourceMtimeIndex.ts +19 -130
- package/frontendBuild/ssrBaseArtifactBuilder.ts +19 -13
- package/frontendBuild/ssrDevBundler.ts +85 -0
- package/frontendBuild/styleContract.ts +1 -8
- package/frontendBuild/themeValidator.ts +4 -26
- package/frontendBuild/watchRootResolver.test.ts +23 -42
- package/frontendBuild/watchRootResolver.ts +5 -27
- package/getRelatedCnsts.ts +12 -92
- package/incrementalBuilder/buildBatch.proc.ts +147 -63
- package/incrementalBuilder/buildBatchProtocol.ts +13 -38
- package/incrementalBuilder/buildBatchRunner.test.ts +65 -0
- package/incrementalBuilder/buildBatchRunner.ts +26 -38
- package/incrementalBuilder/builderChannel.test.ts +24 -49
- package/incrementalBuilder/builderChannel.ts +6 -37
- package/incrementalBuilder/builderRequestRouter.test.ts +0 -8
- package/incrementalBuilder/builderRequestRouter.ts +5 -24
- package/incrementalBuilder/builderWorkQueue.test.ts +94 -0
- package/incrementalBuilder/builderWorkQueue.ts +126 -0
- package/incrementalBuilder/devWatchBatch.test.ts +21 -24
- package/incrementalBuilder/incrementalBuilder.host.test.ts +53 -56
- package/incrementalBuilder/incrementalBuilder.host.ts +68 -81
- package/incrementalBuilder/incrementalBuilder.proc.test.ts +270 -0
- package/incrementalBuilder/incrementalBuilder.proc.ts +596 -208
- package/index.ts +5 -19
- package/integration/devResourceProbe.ts +50 -56
- package/integration/devStability.integration.test.ts +105 -199
- package/integration/devStabilityHarness.test.ts +13 -28
- package/integration/devStabilityHarness.ts +65 -330
- package/integration/ssrMemoryProbe.ts +41 -167
- package/libSource.test.ts +4 -15
- package/libSource.ts +19 -31
- package/lint/__fixtures__/no-document-cookie/bad.tsx +4 -0
- package/lint/__fixtures__/no-document-cookie/good.tsx +7 -0
- package/lint/__fixtures__/no-web-only-api-outside-webkit/bad.tsx +7 -0
- package/lint/__fixtures__/no-web-only-api-outside-webkit/good.tsx +11 -0
- package/lint/__fixtures__/no-web-storage/bad.tsx +6 -0
- package/lint/__fixtures__/no-web-storage/good.tsx +7 -0
- package/lint/gritRules.test.ts +8 -24
- package/lint/no-deep-internal-import.grit +2 -2
- package/lint/no-document-cookie.grit +29 -0
- package/lint/no-redeclare-predefined-endpoint.grit +2 -1
- package/lint/no-web-only-api-outside-webkit.grit +44 -0
- package/lint/no-web-storage.grit +30 -0
- package/linter.test.ts +1 -2
- package/linter.ts +26 -116
- package/mobile/desktopBin.test.ts +182 -0
- package/mobile/desktopBin.ts +144 -0
- package/mobile/desktopServerStage.test.ts +252 -0
- package/mobile/desktopServerStage.ts +178 -0
- package/mobile/index.ts +9 -0
- package/mobile/mobileTarget.test.ts +57 -8
- package/mobile/mobileTarget.ts +45 -26
- package/mobile/nativeApi.test.ts +30 -0
- package/mobile/nativeApi.ts +40 -0
- package/mobile/nativeApp.test.ts +184 -0
- package/mobile/nativeApp.ts +454 -0
- package/mobile/nativeAppLine.test.ts +69 -0
- package/mobile/nativeAppLine.ts +71 -0
- package/mobile/nativeConfig.test.ts +438 -0
- package/mobile/nativeConfig.ts +294 -0
- package/mobile/nativePluginFolders.test.ts +81 -0
- package/mobile/nativePluginFolders.ts +60 -0
- package/mobile/nativeWebDir.test.ts +80 -0
- package/mobile/nativeWebDir.ts +66 -0
- package/mobile/placeholderAppId.test.ts +13 -0
- package/mobile/placeholderAppId.ts +16 -0
- package/mobile/usageDescriptions.test.ts +27 -0
- package/mobile/usageDescriptions.ts +24 -0
- package/package.json +11 -11
- package/packageExports.test.ts +3 -18
- package/packageExportsMap.ts +3 -19
- package/piDependencyPins.test.ts +46 -0
- package/platformTest/BunTestReport.test.ts +60 -0
- package/platformTest/BunTestReport.ts +65 -0
- package/platformTest/IdleWatchedProcess.test.ts +56 -0
- package/platformTest/IdleWatchedProcess.ts +73 -0
- package/platformTest/LinuxDockerTarget.ts +105 -0
- package/platformTest/PlatformTestRun.test.ts +64 -0
- package/platformTest/PlatformTestRun.ts +141 -0
- package/platformTest/PlatformTestTarget.ts +142 -0
- package/platformTest/TestSnapshot.test.ts +72 -0
- package/platformTest/TestSnapshot.ts +103 -0
- package/platformTest/WindowsSshTarget.ts +151 -0
- package/prompter.ts +3 -13
- package/qualityScanner.test.ts +9 -26
- package/qualityScanner.ts +200 -286
- package/recipeScanner.test.ts +7 -12
- package/recipeScanner.ts +9 -38
- package/repoIdentity.ts +2 -9
- package/routeSourceValidator.test.ts +0 -1
- package/routeSourceValidator.ts +7 -42
- package/scanInfo.ts +91 -225
- package/selectModel.ts +1 -2
- package/semver.ts +3 -5
- package/slicePlanner.test.ts +6 -24
- package/slicePlanner.ts +11 -32
- package/spinner.test.ts +3 -8
- package/spinner.ts +4 -16
- package/sshTunnel.ts +1 -6
- package/ssrScanner.test.ts +1 -6
- package/ssrScanner.ts +103 -113
- package/stripAnsi.ts +3 -0
- package/subspace.test.ts +9 -25
- package/subspace.ts +48 -115
- package/subspaceConfig.ts +3 -11
- package/testHelpers.ts +194 -0
- package/transforms/asyncDefaultExportDetector.ts +3 -11
- package/transforms/barrelAnalyzer.ts +43 -135
- package/transforms/barrelImportsPlugin.ts +38 -175
- package/transforms/externalizeFrameworkPlugin.test.ts +39 -118
- package/transforms/externalizeFrameworkPlugin.ts +13 -87
- package/transforms/moduleSyntax.ts +32 -0
- package/transforms/rscUseClientTransform.ts +42 -20
- package/transforms/serverEnvPlugin.test.ts +103 -0
- package/transforms/serverEnvPlugin.ts +41 -0
- package/transforms/transforms.test.ts +166 -44
- package/transforms/tsconfigPackageResolver.test.ts +6 -24
- package/transforms/useClientBundlePlugin.ts +6 -23
- package/typeChecker.ts +7 -63
- package/types.ts +2 -0
- package/uploadRelease.ts +10 -25
- package/workflow/artifacts.ts +18 -0
- package/workflow/executor.test.ts +1 -12
- package/workflow/executor.ts +101 -110
- package/workflow/index.ts +0 -1
- package/workflow/moduleIndex.test.ts +4 -15
- package/workflow/moduleIndex.ts +9 -49
- package/workflow/plan.ts +18 -25
- package/workflow/render.ts +80 -96
- package/workflow/rolloutGate.test.ts +1 -1
- package/workflow/source.ts +52 -69
- package/workflow/sourceAst.ts +50 -0
- package/workspaceLayout.test.ts +18 -3
- package/workspaceLayout.ts +22 -23
- package/abstractCompactor.ts +0 -112
- package/aiEditor.test.ts +0 -60
- package/aiEditor.ts +0 -387
- package/applicationReleasePackager.ts +0 -209
- package/capacitorApp.test.ts +0 -372
- package/capacitorApp.ts +0 -1648
- package/commandDecorators/commandMeta.ts +0 -7
- package/commandDecorators/types.ts +0 -10
- package/getDirname.ts +0 -4
- package/guideline.ts +0 -19
- package/local/optimize-resource/ipcprobe/child.ts +0 -1
- package/local/optimize-resource/ipcprobe/parent.ts +0 -11
- package/workflow/primitive.ts +0 -59
package/index.ts
CHANGED
|
@@ -1,38 +1,23 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
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:
|
|
11
|
+
role: Role;
|
|
12
12
|
command: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface DevResourceProbeOptions {
|
|
16
16
|
appName: string;
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
-
|
|
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
|
|
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
|
-
|
|
57
|
-
|
|
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.#
|
|
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
|
-
//
|
|
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
|
-
|
|
173
|
-
|
|
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:
|
|
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 ===
|
|
202
|
-
if (root) kept.set(
|
|
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 ===
|
|
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();
|