@akanjs/cli 3.0.0-beta.2 → 3.0.0-beta.20

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 (187) hide show
  1. package/.build-stamp +1 -1
  2. package/CodeAgent-awv258wb.js +9 -0
  3. package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
  4. package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
  5. package/CodeTui-1nqh35ez.js +1457 -0
  6. package/README.md +3 -0
  7. package/TunnelShare-scf4e4pd.js +9 -0
  8. package/{agent.command-d2gfxfck.js → agent.command-1s9ag7sb.js} +8 -9
  9. package/akanCode.js +102 -0
  10. package/{application.command-pj2m7584.js → application.command-49hwy6va.js} +51 -78
  11. package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-ybyp97pv.js} +63 -64
  12. package/{applicationReleasePackager-4yasxwv9.js → applicationReleasePackager-esnrphw8.js} +40 -60
  13. package/buildBatch.proc.js +19 -24
  14. package/{capacitorApp-36rbr858.js → capacitorApp-1synz4en.js} +3 -4
  15. package/cloud.command-d7rqtzt9.js +94 -0
  16. package/cloud.script-bkbpcr96.js +19 -0
  17. package/code.command-nn48xzej.js +154 -0
  18. package/commandManifest.json +1 -1
  19. package/consoleToStderr-h5bryj94.js +7 -0
  20. package/context.command-s3mcmvpa.js +48 -0
  21. package/context.runner-k99nb5pk.js +21 -0
  22. package/{dependencyScanner-shs82ynp.js → dependencyScanner-ye2e6pdz.js} +2 -2
  23. package/{devTui-40ggmd99.js → devTui-q7k7bakd.js} +122 -40
  24. package/fileSys-5ngz93ga.js +9 -0
  25. package/guideline.command-sct4qnt5.js +42 -0
  26. package/guidelines/agentRule/agentRule.instruction.md +206 -25
  27. package/guidelines/conventions/conventions.instruction.md +79 -24
  28. package/guidelines/fieldRule/fieldRule.instruction.md +1 -0
  29. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  30. package/guidelines/queryRule/queryRule.instruction.md +17 -7
  31. package/guidelines/runtimeRule/runtimeRule.instruction.md +74 -0
  32. package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
  33. package/guidelines/transportRule/transportRule.instruction.md +51 -0
  34. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
  35. package/incrementalBuilder.proc.js +31 -48
  36. package/{index-h7yw2z9n.js → index-0bq14vr1.js} +8 -14
  37. package/index-13ffe9wp.js +69 -0
  38. package/index-22d57v4c.js +266 -0
  39. package/{index-fz5q3gd7.js → index-31yr441d.js} +10 -17
  40. package/index-3hx1z96c.js +87 -0
  41. package/index-3sq321ak.js +53 -0
  42. package/{index-kcxmv48c.js → index-3t7g9e4r.js} +45 -79
  43. package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
  44. package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
  45. package/{index-259dsnz3.js → index-5pc1qrbv.js} +5 -8
  46. package/index-7md2g9vw.js +6 -0
  47. package/index-8mna0947.js +187 -0
  48. package/{index-zry5nz81.js → index-8sf7wmdr.js} +51 -30
  49. package/{index-2tv3fdx4.js → index-9d9bgcx4.js} +342 -765
  50. package/index-9dp031by.js +12 -0
  51. package/{index-ne2qy0nk.js → index-ahemdr5n.js} +12 -12
  52. package/{index-ws5e0j51.js → index-as7xmyz8.js} +40 -24
  53. package/index-axzjaqve.js +1118 -0
  54. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  55. package/index-c6eggbee.js +123 -0
  56. package/index-d2242ksy.js +99 -0
  57. package/{index-a64esmtb.js → index-ddxvdd1p.js} +169 -305
  58. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  59. package/{index-pnqbkf5p.js → index-dzf3r49a.js} +6 -2
  60. package/{index-w8kmx1b6.js → index-fgq75haa.js} +198 -290
  61. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  62. package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
  63. package/{index-wt7qrtd4.js → index-mxav6j3c.js} +93 -232
  64. package/{index-gyd220p2.js → index-myhc3c1j.js} +554 -577
  65. package/{index-600zhnve.js → index-nv5976x3.js} +56 -197
  66. package/index-p6pbz9n5.js +25 -0
  67. package/{index-4edzf1gr.js → index-przybvy5.js} +77 -150
  68. package/index-smme4r47.js +49 -0
  69. package/{index-mak3cd28.js → index-w2zdcw3k.js} +137 -255
  70. package/index-wa5jbxj1.js +760 -0
  71. package/{index-v0qh106m.js → index-ww4z397j.js} +527 -723
  72. package/{index-j9yhg404.js → index-xqjwd384.js} +4 -7
  73. package/{index-7737gxcp.js → index-xqpzbab5.js} +107 -241
  74. package/index-xsjh6nzh.js +2729 -0
  75. package/{index-ktb5njgy.js → index-ygn77a5w.js} +47 -99
  76. package/index-ztp3e73t.js +700 -0
  77. package/index.js +23 -22
  78. package/{library.command-nbsky672.js → library.command-1gx04jgn.js} +4 -5
  79. package/{localRegistry.command-yeq57wjr.js → localRegistry.command-zndxj1q6.js} +22 -42
  80. package/{module.command-29vqzrh8.js → module.command-3waddk95.js} +8 -11
  81. package/{package.command-axv0abmn.js → package.command-zrc7br1y.js} +6 -7
  82. package/package.json +14 -5
  83. package/{page.command-vs9s3zrh.js → page.command-vpjgardh.js} +4 -5
  84. package/{primitive.command-cbxmqbtc.js → primitive.command-sz84tk4t.js} +9 -22
  85. package/prompter-ptaa3nk0.js +8 -0
  86. package/{quality.command-gmbs7nws.js → quality.command-g869hafs.js} +203 -376
  87. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  88. package/{repair.command-bqsjptsj.js → repair.command-chsnjvvv.js} +11 -35
  89. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  90. package/{scalar.command-6k1vhe9s.js → scalar.command-2v21newx.js} +7 -10
  91. package/skills/akan-code/SKILL.md +130 -0
  92. package/skills/akan-debug/SKILL.md +42 -0
  93. package/skills/akan-deps/SKILL.md +50 -0
  94. package/skills/akan-err/SKILL.md +39 -0
  95. package/skills/akan-module/SKILL.md +45 -0
  96. package/skills/akan-scaffold/SKILL.md +76 -0
  97. package/skills/akan-scalar/SKILL.md +52 -0
  98. package/skills/akan-service/SKILL.md +34 -0
  99. package/skills/akan-store/SKILL.md +67 -0
  100. package/skills/akan-ui/SKILL.md +63 -0
  101. package/skills/akan-validate/SKILL.md +44 -0
  102. package/{subspace.command-fwjfcts7.js → subspace.command-ckcbwfp1.js} +138 -67
  103. package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
  104. package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
  105. package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
  106. package/templates/appSample/lib/task/task.abstract.ts +12 -32
  107. package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
  108. package/templates/appSample/lib/task/task.signal.test.ts +15 -1
  109. package/templates/appSample/lib/task/task.signal.ts +1 -1
  110. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
  111. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
  112. package/templates/client.ts +7 -30
  113. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
  114. package/templates/crudPages/[__model__Id]/page.tsx +2 -1
  115. package/templates/crudPages/new/page.tsx +2 -1
  116. package/templates/crudPages/page.tsx +2 -1
  117. package/templates/crudSinglePage/page.tsx +2 -1
  118. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  119. package/templates/lib/__lib/lib.document.ts +0 -2
  120. package/templates/lib/sig.ts +8 -30
  121. package/templates/localDev/docker-compose.yaml.template +3 -14
  122. package/templates/module/__model__.signal.ts +12 -4
  123. package/templates/pkgRoot/tsconfig.json.template +2 -7
  124. package/templates/server.ts +0 -2
  125. package/templates/service/__model__.abstract.md.template +8 -0
  126. package/tunnel.command-kd2yr4fx.js +129 -0
  127. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  128. package/typecheck.proc.js +1 -1
  129. package/workflow.command-44252cqv.js +79 -0
  130. package/{workspace.command-8s050m0h.js → workspace.command-fqcztt5p.js} +77 -109
  131. package/abstractCompactor-mjh5ppsq.js +0 -101
  132. package/cloud.command-jshwdq22.js +0 -93
  133. package/context.command-ez8a0zyz.js +0 -80
  134. package/devTuiView-c08ccbat.js +0 -9
  135. package/getDirname-dr3jz1xg.js +0 -7
  136. package/guideline.command-xmqwx8zm.js +0 -359
  137. package/guidelines/agentRule/agentRule.generate.json +0 -31
  138. package/guidelines/componentRule/componentRule.generate.json +0 -31
  139. package/guidelines/conventions/conventions.generate.json +0 -25
  140. package/guidelines/cssRule/cssRule.generate.json +0 -31
  141. package/guidelines/docPageRule/docPageRule.generate.json +0 -31
  142. package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
  143. package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
  144. package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
  145. package/guidelines/enumConstant/enumConstant.generate.json +0 -31
  146. package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
  147. package/guidelines/fieldRule/fieldRule.generate.json +0 -31
  148. package/guidelines/framework/framework.generate.json +0 -32
  149. package/guidelines/mcpRule/mcpRule.generate.json +0 -35
  150. package/guidelines/modelConstant/modelConstant.generate.json +0 -32
  151. package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
  152. package/guidelines/modelDocument/modelDocument.generate.json +0 -31
  153. package/guidelines/modelService/modelService.generate.json +0 -31
  154. package/guidelines/modelSignal/modelSignal.generate.json +0 -31
  155. package/guidelines/modelStore/modelStore.generate.json +0 -31
  156. package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
  157. package/guidelines/modelUnit/modelUnit.generate.json +0 -31
  158. package/guidelines/modelUtil/modelUtil.generate.json +0 -31
  159. package/guidelines/modelView/modelView.generate.json +0 -31
  160. package/guidelines/modelZone/modelZone.generate.json +0 -31
  161. package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
  162. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
  163. package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
  164. package/guidelines/queryRule/queryRule.generate.json +0 -31
  165. package/guidelines/recipeRule/recipeRule.generate.json +0 -31
  166. package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
  167. package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
  168. package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
  169. package/guidelines/scalarModule/scalarModule.generate.json +0 -31
  170. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
  171. package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
  172. package/guidelines/ssrRule/ssrRule.generate.json +0 -31
  173. package/guidelines/transportRule/transportRule.generate.json +0 -31
  174. package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
  175. package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
  176. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
  177. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
  178. package/index-2hq52jq3.js +0 -465
  179. package/index-6wwzs1bc.js +0 -7
  180. package/index-8pm30m73.js +0 -841
  181. package/index-kn1h7p1x.js +0 -560
  182. package/index-meh558jy.js +0 -65
  183. package/index-rwg2aa4f.js +0 -229
  184. package/templates/__scalar/__model__/__model__.abstract.md +0 -28
  185. package/templates/module/__model__.abstract.md +0 -28
  186. package/templates/service/__model__.abstract.md +0 -28
  187. package/workflow.command-nwpcdc8p.js +0 -107
@@ -25,12 +25,13 @@ var scanRecipes2 = (sources) => {
25
25
  const parsed = parseRecipeCall(declaration.initializer);
26
26
  if (!parsed)
27
27
  continue;
28
+ const doc = getLeadingDoc(source.content, statement);
28
29
  recipes.push({
29
30
  name: declaration.name.text,
30
31
  importFrom: source.importFrom,
31
32
  variants: parsed.variants,
32
33
  ...parsed.defaultVariants ? { defaultVariants: parsed.defaultVariants } : {},
33
- ...getLeadingDoc(source.content, statement) ? { doc: getLeadingDoc(source.content, statement) } : {},
34
+ ...doc ? { doc } : {},
34
35
  ...parsed.base ? { base: parsed.base } : {}
35
36
  });
36
37
  }
@@ -1,11 +1,286 @@
1
1
  // @bun
2
+ // pkgs/@akanjs/devkit/applicationBuildReporter.ts
3
+ import { realpathSync } from "fs";
4
+ import path from "path";
5
+ import { Logger } from "akanjs/common";
6
+
7
+ class ApplicationBuildReporter {
8
+ static create() {
9
+ return {
10
+ phaseDone: (phase) => Logger.rawLog(ApplicationBuildReporter.formatPhaseLine(phase))
11
+ };
12
+ }
13
+ static printSummary(result) {
14
+ Logger.rawLog("");
15
+ Logger.rawLog(`Route artifacts: ${result.artifactDir}`);
16
+ Logger.rawLog(`Server output: ${result.outputDir}`);
17
+ Logger.rawLog(`Done in ${ApplicationBuildReporter.formatDuration(result.durationMs)}`);
18
+ }
19
+ static formatError(error, workspaceRoot = process.cwd()) {
20
+ if (error instanceof AggregateError) {
21
+ const nestedMessages = error.errors.map((nestedError, index) => ApplicationBuildReporter.formatError(nestedError, workspaceRoot).trim() || `Unknown error ${index + 1}`).map((message) => message.replace(/^/gm, " ")).join(`
22
+ `);
23
+ return nestedMessages ? `${error.message}
24
+ ${nestedMessages}` : error.message;
25
+ }
26
+ if (error instanceof Error) {
27
+ const causeMessage = error.cause ? `
28
+ Caused by: ${ApplicationBuildReporter.formatError(error.cause, workspaceRoot)}` : "";
29
+ return `${ApplicationBuildReporter.#withLocation(error.message, error, workspaceRoot)}${causeMessage}`;
30
+ }
31
+ if (typeof error === "object" && error !== null && "message" in error)
32
+ return ApplicationBuildReporter.#withLocation(String(error.message), error, workspaceRoot);
33
+ return String(error);
34
+ }
35
+ static #withLocation(message, error, workspaceRoot) {
36
+ const { position } = error;
37
+ if (!position?.file)
38
+ return message;
39
+ const file = ApplicationBuildReporter.#relativeToWorkspace(position.file, workspaceRoot);
40
+ const location = position.line > 0 ? `${file}:${position.line}:${position.column}` : file;
41
+ return message.includes(location) ? message : message.replace(/^.*/, (headline) => `${headline} (${location})`);
42
+ }
43
+ static #relativeToWorkspace(file, workspaceRoot) {
44
+ if (!path.isAbsolute(file))
45
+ return file;
46
+ for (const root of [workspaceRoot, ApplicationBuildReporter.#realpathOf(workspaceRoot)]) {
47
+ const relative = path.relative(root, file);
48
+ if (!relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative))
49
+ return relative.replaceAll(path.sep, "/");
50
+ }
51
+ return file;
52
+ }
53
+ static #realpathOf(dir) {
54
+ try {
55
+ return realpathSync(dir);
56
+ } catch {
57
+ return dir;
58
+ }
59
+ }
60
+ static formatDuration(ms) {
61
+ if (ms < 1000)
62
+ return `${ms}ms`;
63
+ if (ms < 60000)
64
+ return `${Math.round(ms / 100) / 10}s`;
65
+ const seconds = Math.floor(ms / 1000);
66
+ return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
67
+ }
68
+ static formatPhaseLine(phase) {
69
+ const summary = phase.summary ? `: ${phase.summary}` : "";
70
+ return `\u2713 ${phase.label}${summary} (${ApplicationBuildReporter.formatDuration(phase.durationMs)})`;
71
+ }
72
+ }
73
+
2
74
  // pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
3
75
  import fs from "fs";
4
- import path3 from "path";
76
+ import path5 from "path";
5
77
 
6
78
  // pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
7
- import path from "path";
79
+ import path3 from "path";
80
+
81
+ // pkgs/@akanjs/devkit/akanApp/devHostPolicy.ts
82
+ import path2 from "path";
83
+ var BACKEND_RECOVERY_MAX_ATTEMPTS = 5;
84
+ var HELD_BUILDER_REQUEST_LIMIT = 64;
85
+ var BUILDER_MIN_RSS_RECYCLE_INTERVAL_MS = 30000;
86
+ var BUILDER_TIGHT_RSS_REPORT_LIMIT = 2;
87
+ var BUILDER_RSS_HARD_MULTIPLE = 1.5;
88
+ var DEV_IDLE_SUSPEND_MS = 300000;
89
+ var DEV_IDLE_MIN_UPTIME_MS = 30000;
8
90
  var SOURCE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
91
+ var SERVER_SUFFIXES = [".service.ts", ".document.ts"];
92
+ var SHARED_SUFFIXES = [".constant.ts", ".dictionary.ts", ".signal.ts"];
93
+ var RUNTIME_METADATA_BASENAMES = new Set(["dict.ts", "sig.ts", "useClient.ts", "useServer.ts"]);
94
+ var shouldRestartBackendByDevPlan = (message) => {
95
+ if (!message.devPlan)
96
+ return null;
97
+ if (message.devPlan.actions.includes("report-error"))
98
+ return false;
99
+ if (message.devPlan.actions.includes("restart-builder"))
100
+ return false;
101
+ return message.devPlan.actions.includes("restart-backend");
102
+ };
103
+ var shouldRestartBuilderByDevPlan = (message) => message.devPlan?.actions.includes("restart-builder") ?? false;
104
+ var shouldAbandonBackendRecovery = (attempts, maxAttempts = BACKEND_RECOVERY_MAX_ATTEMPTS) => attempts >= maxAttempts;
105
+ var normalizeBackendReportedGeneration = (generation) => generation >= 0 ? generation : undefined;
106
+ var shouldRestartDevHostByDevPlan = (message) => message.devPlan?.actions.includes("restart-dev-host") ?? message.kinds.includes("config");
107
+ var devHostStateByBackendState = {
108
+ starting: "starting",
109
+ ready: "ready",
110
+ "restart-pending": "restarting",
111
+ recovering: "recovering",
112
+ stopping: "stopped",
113
+ stopped: "stopped"
114
+ };
115
+ var devHostStateOf = (state, gaveUp) => state === "stopped" && gaveUp ? "failed" : devHostStateByBackendState[state];
116
+ var RESTART_ROLE_ORDER = ["server", "shared", "barrel", "config"];
117
+ var generationValue = (generation) => generation ?? -1;
118
+ var isLegacyBackendFallbackFile = (file, workspaceRoot) => {
119
+ const abs = path2.resolve(file);
120
+ const ext = path2.extname(abs).toLowerCase();
121
+ if (!SOURCE_EXTS.has(ext))
122
+ return false;
123
+ const rel = path2.relative(path2.resolve(workspaceRoot), abs);
124
+ if (!rel || rel.startsWith("..") || path2.isAbsolute(rel))
125
+ return false;
126
+ const parts = rel.split(path2.sep).filter(Boolean);
127
+ const [scope] = parts;
128
+ if (scope !== "apps" && scope !== "libs" && scope !== "pkgs")
129
+ return false;
130
+ const base = path2.basename(abs);
131
+ return parts.includes("srvkit") || parts.includes("common") || SERVER_SUFFIXES.some((suffix) => base.endsWith(suffix)) || SHARED_SUFFIXES.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES.has(base) || base === "main.ts" || base === "server.ts";
132
+ };
133
+ var shouldMarkBuildPhaseRecovered = (previousByPhase, status) => {
134
+ const previous = previousByPhase.get(status.phase);
135
+ return Boolean(previous && status.ok && !previous.ok && generationValue(status.generation) >= previous.generation);
136
+ };
137
+ var createBackendBuildStatus = ({
138
+ generation,
139
+ ok,
140
+ files = [],
141
+ message
142
+ }) => ({
143
+ generation,
144
+ phase: "backend",
145
+ ok,
146
+ files,
147
+ message
148
+ });
149
+ var backendRestartReasonFromMessage = (message) => {
150
+ const roleSet = new Set;
151
+ for (const role of message.devPlan?.roles ?? []) {
152
+ if (role === "server" || role === "shared" || role === "barrel" || role === "config")
153
+ roleSet.add(role);
154
+ }
155
+ return {
156
+ generation: message.devPlan?.generation ?? message.generation,
157
+ files: [...new Set(message.files)].sort(),
158
+ roles: RESTART_ROLE_ORDER.filter((role) => roleSet.has(role))
159
+ };
160
+ };
161
+ var mergeBackendRestartReasons = (current, next) => ({
162
+ generation: generationValue(next.generation) >= generationValue(current?.generation) ? next.generation : current?.generation,
163
+ files: [...new Set([...current?.files ?? [], ...next.files])].sort(),
164
+ roles: RESTART_ROLE_ORDER.filter((role) => current?.roles.includes(role) || next.roles.includes(role))
165
+ });
166
+ var shouldReplaceLastGoodMessage = (current, next) => !current || generationValue(next.data.generation) >= generationValue(current.data.generation);
167
+ var shouldQueueBuildStatusReplay = (backendReady, pendingReplayCount) => !backendReady || pendingReplayCount > 0;
168
+ var hasBuildFailureForGeneration = (statusByPhase, generation) => {
169
+ if (typeof generation !== "number")
170
+ return false;
171
+ for (const status of statusByPhase.values()) {
172
+ if (!status.ok && status.generation === generation)
173
+ return true;
174
+ }
175
+ return false;
176
+ };
177
+ var decideBuilderRssRecycle = ({
178
+ rssBytes,
179
+ ceilingBytes,
180
+ buildFailed,
181
+ msSinceLastRecycle,
182
+ minIntervalMs = BUILDER_MIN_RSS_RECYCLE_INTERVAL_MS
183
+ }) => {
184
+ if (!ceilingBytes)
185
+ return "unbounded";
186
+ if (rssBytes < ceilingBytes)
187
+ return "below-ceiling";
188
+ if (buildFailed)
189
+ return "build-failed";
190
+ if (msSinceLastRecycle !== null && msSinceLastRecycle < minIntervalMs)
191
+ return "too-soon";
192
+ return "recycle";
193
+ };
194
+ var decideBuilderRssSettle = ({
195
+ rssBytes,
196
+ ceilingBytes,
197
+ hardMultiple = BUILDER_RSS_HARD_MULTIPLE
198
+ }) => rssBytes >= ceilingBytes * hardMultiple ? "recycle-now" : "wait-and-recheck";
199
+ var decideIdleSuspend = ({
200
+ enabled,
201
+ suspended,
202
+ builderReady,
203
+ backendReady,
204
+ buildFailed,
205
+ restartPending,
206
+ msSinceWake,
207
+ minUptimeMs = DEV_IDLE_MIN_UPTIME_MS
208
+ }) => {
209
+ if (!enabled)
210
+ return "disabled";
211
+ if (suspended)
212
+ return "already-suspended";
213
+ if (!builderReady)
214
+ return "builder-not-ready";
215
+ if (!backendReady)
216
+ return "backend-not-ready";
217
+ if (buildFailed)
218
+ return "build-failed";
219
+ if (restartPending)
220
+ return "restart-pending";
221
+ if (msSinceWake !== null && msSinceWake < minUptimeMs)
222
+ return "too-soon";
223
+ return "suspend";
224
+ };
225
+ var resolveIdleSuspendMs = (raw) => {
226
+ if (raw === undefined || raw === "")
227
+ return DEV_IDLE_SUSPEND_MS;
228
+ const parsed = Number(raw);
229
+ if (!Number.isFinite(parsed) || parsed <= 0)
230
+ return null;
231
+ return Math.round(parsed);
232
+ };
233
+ var hasAnyBuildFailure = (statusByPhase) => [...statusByPhase.values()].some((status) => !status.ok);
234
+ var shouldRefreshConfigOnIdleWake = (batch) => !!batch && batch.kinds.has("config");
235
+ var RETURNING_BUILDER_STATUSES = new Set(["starting", "recycling", "restarting"]);
236
+ var shouldHoldForReturningBuilder = ({
237
+ status,
238
+ heldCount,
239
+ limit = HELD_BUILDER_REQUEST_LIMIT
240
+ }) => RETURNING_BUILDER_STATUSES.has(status) && heldCount < limit;
241
+ var shouldWarnBuilderRssCeilingTight = (reportsSinceRecycle, limit = BUILDER_TIGHT_RSS_REPORT_LIMIT) => reportsSinceRecycle >= limit;
242
+ var isRssCeilingUnreachable = (freshRssBytes, ceilingBytes) => freshRssBytes !== null && ceilingBytes !== null && freshRssBytes >= ceilingBytes;
243
+ var shouldRelayRecycledFrontendState = (current, next) => {
244
+ if (!current || current.type !== next.type)
245
+ return true;
246
+ if (current.type === "pages-updated" && next.type === "pages-updated")
247
+ return current.data.bundlePath !== next.data.bundlePath;
248
+ if (current.type === "css-updated" && next.type === "css-updated")
249
+ return JSON.stringify(current.data.cssAssets) !== JSON.stringify(next.data.cssAssets);
250
+ return true;
251
+ };
252
+ var mergeDevPlans = (current, next) => {
253
+ if (!current)
254
+ return next;
255
+ if (!next)
256
+ return current;
257
+ const reasonByFile = { ...current.reasonByFile };
258
+ for (const [file, reasons] of Object.entries(next.reasonByFile)) {
259
+ reasonByFile[file] = [...new Set([...reasonByFile[file] ?? [], ...reasons])].sort();
260
+ }
261
+ return {
262
+ generation: Math.max(current.generation, next.generation),
263
+ files: [...new Set([...current.files, ...next.files])].sort(),
264
+ generatedFiles: [...new Set([...current.generatedFiles, ...next.generatedFiles])].sort(),
265
+ roles: [...new Set([...current.roles, ...next.roles])].sort(),
266
+ actions: [...new Set([...current.actions, ...next.actions])].sort(),
267
+ reasonByFile
268
+ };
269
+ };
270
+ var mergeInvalidateMessages = (current, next) => {
271
+ const generation = Math.max(generationValue(current.generation), generationValue(next.generation));
272
+ return {
273
+ type: "invalidate",
274
+ kinds: [...new Set([...current.kinds, ...next.kinds])].sort(),
275
+ files: [...new Set([...current.files, ...next.files])].sort(),
276
+ generation: generation >= 0 ? generation : undefined,
277
+ devPlan: mergeDevPlans(current.devPlan, next.devPlan)
278
+ };
279
+ };
280
+ var buildStatusReplaySequence = (pendingReplay, latestByPhase) => [...pendingReplay, ...latestByPhase.values()];
281
+ var filesChangedSince = (before, after) => [...before].filter(([file, stamp]) => after.get(file) !== stamp).map(([file]) => file);
282
+
283
+ // pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
9
284
  var CSS_EXTS = new Set([".css"]);
10
285
  var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
11
286
 
@@ -13,10 +288,10 @@ class HmrChangeClassifier {
13
288
  classify(abs) {
14
289
  if (this.#isUninteresting(abs))
15
290
  return "ignore";
16
- const base = path.basename(abs);
291
+ const base = path3.basename(abs);
17
292
  if (CONFIG_BASENAMES.has(base))
18
293
  return "config";
19
- const ext = path.extname(abs).toLowerCase();
294
+ const ext = path3.extname(abs).toLowerCase();
20
295
  if (CSS_EXTS.has(ext))
21
296
  return "css";
22
297
  if (SOURCE_EXTS.has(ext))
@@ -24,16 +299,16 @@ class HmrChangeClassifier {
24
299
  return "ignore";
25
300
  }
26
301
  #isUninteresting(abs) {
27
- const base = path.basename(abs);
302
+ const base = path3.basename(abs);
28
303
  if (!base)
29
304
  return true;
30
305
  if (base.startsWith("."))
31
306
  return true;
32
307
  if (base.endsWith("~") || base.endsWith(".swp") || base.endsWith(".swx") || base.endsWith(".tmp"))
33
308
  return true;
34
- if (abs.includes(`${path.sep}node_modules${path.sep}`))
309
+ if (abs.includes(`${path3.sep}node_modules${path3.sep}`))
35
310
  return true;
36
- if (abs.includes(`${path.sep}.akan${path.sep}`))
311
+ if (abs.includes(`${path3.sep}.akan${path3.sep}`))
37
312
  return true;
38
313
  return false;
39
314
  }
@@ -41,7 +316,7 @@ class HmrChangeClassifier {
41
316
 
42
317
  // pkgs/@akanjs/devkit/frontendBuild/sourceMtimeIndex.ts
43
318
  import { readdir, stat } from "fs/promises";
44
- import path2 from "path";
319
+ import path4 from "path";
45
320
  var UNREADABLE = Number.NaN;
46
321
 
47
322
  class SourceMtimeIndex {
@@ -104,7 +379,7 @@ class SourceMtimeIndex {
104
379
  if (!this.#primed)
105
380
  return;
106
381
  await Promise.all(paths.map(async (file) => {
107
- const abs = path2.resolve(file);
382
+ const abs = path4.resolve(file);
108
383
  const stats = await stat(abs).catch(() => null);
109
384
  if (!stats?.isFile()) {
110
385
  this.#files.delete(abs);
@@ -190,7 +465,7 @@ class SourceMtimeIndex {
190
465
  for (const entry of entries) {
191
466
  if (SourceMtimeIndex.#skipDirent(entry.name))
192
467
  continue;
193
- const abs = path2.join(dir, entry.name);
468
+ const abs = path4.join(dir, entry.name);
194
469
  if (entry.isDirectory()) {
195
470
  descend.push(abs);
196
471
  continue;
@@ -217,7 +492,7 @@ class SourceMtimeIndex {
217
492
  }
218
493
  if (known) {
219
494
  for (const abs of [...this.#files.keys()]) {
220
- if (present.has(abs) || path2.dirname(abs) !== dir)
495
+ if (present.has(abs) || path4.dirname(abs) !== dir)
221
496
  continue;
222
497
  this.#files.delete(abs);
223
498
  changed?.add(abs);
@@ -235,7 +510,7 @@ class SourceMtimeIndex {
235
510
  this.#unsettled.delete(dir);
236
511
  }
237
512
  #forget(dir) {
238
- const prefix = `${dir}${path2.sep}`;
513
+ const prefix = `${dir}${path4.sep}`;
239
514
  this.#dirs.delete(dir);
240
515
  this.#unreadable.delete(dir);
241
516
  this.#unsettled.delete(dir);
@@ -273,8 +548,8 @@ class SourceMtimeIndex {
273
548
  return !name || name.startsWith(".") || name === "node_modules";
274
549
  }
275
550
  static #pruneNestedRoots(roots) {
276
- const resolved = [...new Set(roots.map((root) => path2.resolve(root)))].sort();
277
- return resolved.filter((root) => !resolved.some((other) => other !== root && root.startsWith(`${other}${path2.sep}`)));
551
+ const resolved = [...new Set(roots.map((root) => path4.resolve(root)))].sort();
552
+ return resolved.filter((root) => !resolved.some((other) => other !== root && root.startsWith(`${other}${path4.sep}`)));
278
553
  }
279
554
  }
280
555
 
@@ -298,7 +573,7 @@ class HmrWatcher {
298
573
  #reportedCompensating = false;
299
574
  #reportedGaps = "";
300
575
  constructor(opts) {
301
- this.#roots = [...new Set(opts.roots.map((r) => path3.resolve(r)))];
576
+ this.#roots = [...new Set(opts.roots.map((r) => path5.resolve(r)))];
302
577
  this.#debounceMs = opts.debounceMs ?? 80;
303
578
  this.#verifyDelayMs = opts.verifyDelayMs ?? 250;
304
579
  this.#onBatch = opts.onBatch;
@@ -314,7 +589,7 @@ class HmrWatcher {
314
589
  const w = fs.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
315
590
  if (!filename)
316
591
  return;
317
- const abs = path3.resolve(root, filename.toString());
592
+ const abs = path5.resolve(root, filename.toString());
318
593
  this.#queue(abs);
319
594
  });
320
595
  this.#watchers.push(w);
@@ -464,7 +739,7 @@ class HmrWatcher {
464
739
  // pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
465
740
  import fs2 from "fs";
466
741
  import { readFile } from "fs/promises";
467
- import path4 from "path";
742
+ import path6 from "path";
468
743
 
469
744
  class WatchRootResolver {
470
745
  #app;
@@ -473,20 +748,20 @@ class WatchRootResolver {
473
748
  }
474
749
  async resolve() {
475
750
  const tsconfig = await this.#app.getTsConfig();
476
- const appDir = path4.resolve(this.#app.cwdPath);
477
- const appsContainer = path4.dirname(appDir);
478
- const libsContainer = path4.resolve(this.#app.workspace.workspaceRoot, "libs");
479
- const libRoots = await this.#resolveLibRoots(libsContainer);
751
+ const appDir = path6.resolve(this.#app.cwdPath);
752
+ const appsContainer = path6.dirname(appDir);
753
+ const libsContainer = path6.resolve(this.#app.workspace.workspaceRoot, "libs");
754
+ const libRoots = (await this.#resolveLibDeps(libsContainer))?.map((name) => path6.join(libsContainer, name)).filter((dir) => fs2.existsSync(dir));
480
755
  const set = new Set;
481
- set.add(path4.resolve(`${this.#app.cwdPath}/page`));
756
+ set.add(path6.resolve(`${this.#app.cwdPath}/page`));
482
757
  for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
483
758
  for (const target of targets) {
484
759
  if (!target)
485
760
  continue;
486
- if (path4.isAbsolute(target))
761
+ if (path6.isAbsolute(target))
487
762
  continue;
488
763
  const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
489
- const resolved = path4.resolve(this.#app.workspace.workspaceRoot, cleaned);
764
+ const resolved = path6.resolve(this.#app.workspace.workspaceRoot, cleaned);
490
765
  if (resolved === libsContainer && libRoots) {
491
766
  for (const root of libRoots)
492
767
  set.add(root);
@@ -499,17 +774,11 @@ class WatchRootResolver {
499
774
  }
500
775
  return [...set];
501
776
  }
502
- async#resolveLibRoots(libsContainer) {
503
- const libDeps = await this.#resolveLibDeps(libsContainer);
504
- if (!libDeps)
505
- return null;
506
- return libDeps.map((name) => path4.join(libsContainer, name)).filter((dir) => fs2.existsSync(dir));
507
- }
508
777
  async#resolveLibDeps(libsContainer) {
509
778
  const scanInfo = this.#app.getScanInfo({ allowEmpty: true });
510
779
  if (scanInfo?.type === "app")
511
780
  return scanInfo.libDeps;
512
- const direct = await WatchRootResolver.#readManifestLibDeps(path4.join(this.#app.cwdPath, "akan.app.json"));
781
+ const direct = await WatchRootResolver.#readManifestLibDeps(path6.join(this.#app.cwdPath, "akan.app.json"));
513
782
  if (!direct)
514
783
  return null;
515
784
  const closure = new Set;
@@ -519,7 +788,7 @@ class WatchRootResolver {
519
788
  if (!name || closure.has(name))
520
789
  continue;
521
790
  closure.add(name);
522
- const nested = await WatchRootResolver.#readManifestLibDeps(path4.join(libsContainer, name, "akan.lib.json"));
791
+ const nested = await WatchRootResolver.#readManifestLibDeps(path6.join(libsContainer, name, "akan.lib.json"));
523
792
  if (!nested)
524
793
  return null;
525
794
  queue.push(...nested);
@@ -538,4 +807,4 @@ class WatchRootResolver {
538
807
  }
539
808
  }
540
809
 
541
- export { HmrWatcher, WatchRootResolver };
810
+ export { ApplicationBuildReporter, BUILDER_MIN_RSS_RECYCLE_INTERVAL_MS, SOURCE_EXTS, shouldRestartBackendByDevPlan, shouldRestartBuilderByDevPlan, shouldAbandonBackendRecovery, normalizeBackendReportedGeneration, shouldRestartDevHostByDevPlan, devHostStateOf, isLegacyBackendFallbackFile, shouldMarkBuildPhaseRecovered, createBackendBuildStatus, backendRestartReasonFromMessage, mergeBackendRestartReasons, shouldReplaceLastGoodMessage, shouldQueueBuildStatusReplay, hasBuildFailureForGeneration, decideBuilderRssRecycle, decideBuilderRssSettle, decideIdleSuspend, resolveIdleSuspendMs, hasAnyBuildFailure, shouldRefreshConfigOnIdleWake, shouldHoldForReturningBuilder, shouldWarnBuilderRssCeilingTight, isRssCeilingUnreachable, shouldRelayRecycledFrontendState, mergeInvalidateMessages, buildStatusReplaySequence, filesChangedSince, HmrWatcher, WatchRootResolver };