@akanjs/cli 3.0.0-alpha.75 → 3.0.0-alpha.77

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 (46) hide show
  1. package/.build-stamp +1 -1
  2. package/{agent.command-z0cam80t.js → agent.command-q2rgd8jz.js} +6 -6
  3. package/{application.command-2dct57za.js → application.command-tfrqva07.js} +8 -5
  4. package/{applicationBuildRunner-ds8acdfz.js → applicationBuildRunner-8tqhxjd0.js} +2 -2
  5. package/buildBatch.proc.js +3 -3
  6. package/{capacitorApp-md7dnt25.js → capacitorApp-szqr3cxr.js} +3 -3
  7. package/{cloud.command-8j7xrxsm.js → cloud.command-pjtg4azj.js} +8 -8
  8. package/commandManifest.json +1 -1
  9. package/{context.command-xjf4y7em.js → context.command-zx88k7e0.js} +13 -13
  10. package/{guideline.command-yzm0qevv.js → guideline.command-85x1tvjb.js} +3 -3
  11. package/incrementalBuilder.proc.js +2 -2
  12. package/{index-9gqzgfsd.js → index-0cdwa7qj.js} +2 -2
  13. package/{index-akz5xvyw.js → index-1szrbtj9.js} +1 -1
  14. package/{index-61x7qthy.js → index-25qfm3at.js} +1123 -1172
  15. package/{index-5r4e65hb.js → index-4930mtpt.js} +118 -5
  16. package/{index-q0s2dp3y.js → index-6w77v5df.js} +1 -1
  17. package/{index-z52nhkjs.js → index-7x5ks4ph.js} +4 -4
  18. package/{index-te6r1b79.js → index-dfn0kqj7.js} +3 -3
  19. package/{index-f39512t6.js → index-dp66vwr6.js} +117 -24
  20. package/{index-y3wyqcsp.js → index-e00k7eme.js} +5 -5
  21. package/{index-a341yqdh.js → index-egng0kc4.js} +3 -3
  22. package/{index-qge1hc70.js → index-ffrhjdwd.js} +2 -2
  23. package/{index-116w1dap.js → index-hffr3myr.js} +3 -3
  24. package/{index-eed7vc38.js → index-kpxg3p1v.js} +10 -10
  25. package/{index-q13s3e01.js → index-qwfwk8be.js} +3 -3
  26. package/{index-bmz9crym.js → index-w0g7hcr7.js} +2 -2
  27. package/{index-vrra4ttx.js → index-ws5zt62x.js} +4 -4
  28. package/index-ym4xqjhy.js +217 -0
  29. package/{index-763h7h9g.js → index-yz8988we.js} +1 -1
  30. package/{index-ym9g9ggs.js → index-zec5gcx0.js} +1 -1
  31. package/{index-h9cybjep.js → index-zkrzv21w.js} +12 -2
  32. package/index.js +19 -19
  33. package/{library.command-w8b53vtt.js → library.command-sjnqhzn2.js} +7 -4
  34. package/{localRegistry.command-ymrgda7e.js → localRegistry.command-02dy0h6v.js} +7 -7
  35. package/{module.command-7pje37dv.js → module.command-8vfy9pgk.js} +6 -6
  36. package/{package.command-jg4qk8ts.js → package.command-af8sxhff.js} +4 -4
  37. package/package.json +2 -2
  38. package/{page.command-abbpj96j.js → page.command-gr6rbz17.js} +4 -4
  39. package/{primitive.command-jw4yv918.js → primitive.command-63b8ytkf.js} +7 -7
  40. package/{quality.command-06j6qy6n.js → quality.command-9xhaxzm1.js} +3 -3
  41. package/{repair.command-x6resn10.js → repair.command-a2z4d5a0.js} +6 -6
  42. package/{scalar.command-mj2vx6rj.js → scalar.command-8ampjwsr.js} +5 -5
  43. package/templates/workspaceRoot/.gitignore.template +0 -1
  44. package/{workflow.command-pmw2tere.js → workflow.command-jkfmkbzh.js} +10 -10
  45. package/{workspace.command-x32k2vma.js → workspace.command-pg2qfpn7.js} +19 -19
  46. package/index-hvbdre8z.js +0 -122
@@ -1,24 +1,25 @@
1
1
  // @bun
2
2
  import {
3
3
  LibraryScript
4
- } from "./index-hvbdre8z.js";
4
+ } from "./index-ym4xqjhy.js";
5
5
  import {
6
6
  resolveMobileTargets
7
7
  } from "./index-76rn3g2c.js";
8
8
  import {
9
9
  runner,
10
10
  script
11
- } from "./index-akz5xvyw.js";
11
+ } from "./index-1szrbtj9.js";
12
12
  import {
13
13
  HmrWatcher,
14
14
  WatchRootResolver
15
15
  } from "./index-5vy2jzar.js";
16
16
  import {
17
17
  AppExecutor,
18
+ AppInfo,
18
19
  LibExecutor,
19
20
  PkgExecutor,
20
21
  WorkspaceExecutor
21
- } from "./index-h9cybjep.js";
22
+ } from "./index-zkrzv21w.js";
22
23
  import {
23
24
  __require
24
25
  } from "./index-yb2wsc7f.js";
@@ -68,6 +69,109 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause)}` : "";
68
69
  }
69
70
  }
70
71
 
72
+ // pkgs/@akanjs/devkit/slicePlanner.ts
73
+ class SlicePlanner {
74
+ static memberDirs = ["apps", "libs", "pkgs"];
75
+ static toolchainDependencies = [
76
+ "@akanjs/cli",
77
+ "@akanjs/devkit",
78
+ "@biomejs/biome",
79
+ "@types/bun",
80
+ "akanjs",
81
+ "typescript"
82
+ ];
83
+ #app;
84
+ constructor(app) {
85
+ this.#app = app;
86
+ }
87
+ async#trackedFiles(paths) {
88
+ return await this.#app.workspace.listGitFiles(paths);
89
+ }
90
+ async#untrackedFiles(paths) {
91
+ const [tracked, all] = await Promise.all([
92
+ this.#app.workspace.listGitFiles(paths),
93
+ this.#app.workspace.listGitFiles(paths, { untracked: true })
94
+ ]);
95
+ const trackedSet = new Set(tracked);
96
+ return all.filter((file) => !trackedSet.has(file));
97
+ }
98
+ #isMemberFile(file) {
99
+ return SlicePlanner.memberDirs.includes(file.split("/")[0] ?? "");
100
+ }
101
+ static #requiredDependencies(appInfo) {
102
+ const scanResults = [
103
+ appInfo.getScanResult(),
104
+ ...[...appInfo.getLibInfos().values()].map((lib) => lib.getScanResult())
105
+ ];
106
+ return new Set([
107
+ ...SlicePlanner.toolchainDependencies,
108
+ ...scanResults.flatMap((scanResult) => [
109
+ ...scanResult.dependencies,
110
+ ...scanResult.devDependencies,
111
+ ...scanResult.pkgDeps
112
+ ])
113
+ ]);
114
+ }
115
+ async#patchWarnings(packageJson) {
116
+ const patchedDependencies = packageJson.patchedDependencies ?? {};
117
+ const missing = (await Promise.all(Object.entries(patchedDependencies).map(async ([spec, patchPath]) => await this.#app.workspace.exists(patchPath) ? null : `${spec} -> ${patchPath}`))).filter((entry) => !!entry);
118
+ return missing.length ? [`patchedDependencies references a missing patch file: ${missing.join(", ")}`] : [];
119
+ }
120
+ async plan() {
121
+ const appInfo = await AppInfo.fromExecutor(this.#app);
122
+ const libs = appInfo.getLibs();
123
+ const slicePaths = [`apps/${this.#app.name}`, ...libs.map((lib) => `libs/${lib}`)];
124
+ const [appFiles, allTracked, untracked, rootPackageJson] = await Promise.all([
125
+ this.#trackedFiles([`apps/${this.#app.name}`]),
126
+ this.#trackedFiles(["."]),
127
+ this.#untrackedFiles(slicePaths),
128
+ this.#app.workspace.getPackageJson()
129
+ ]);
130
+ const libFiles = Object.fromEntries(await Promise.all(libs.map(async (lib) => [lib, await this.#trackedFiles([`libs/${lib}`])])));
131
+ const rootFiles = allTracked.filter((file) => !this.#isMemberFile(file));
132
+ const required = SlicePlanner.#requiredDependencies(appInfo);
133
+ const rootDependencies = { ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies };
134
+ const unusedDependencies = Object.keys(rootDependencies).filter((dep) => !required.has(dep)).sort();
135
+ const { workspaces: _workspaces, ...slicePackageJson } = rootPackageJson;
136
+ const warnings = [
137
+ ...untracked.length ? [`${untracked.length} untracked file(s) under the slice paths: ${untracked.join(", ")}`] : [],
138
+ ...rootPackageJson.workspaces ? ["root `workspaces` dropped \u2014 a slice consumes akanjs from the registry"] : [],
139
+ ...await this.#patchWarnings(rootPackageJson)
140
+ ];
141
+ return {
142
+ app: this.#app.name,
143
+ libs,
144
+ appFiles,
145
+ libFiles,
146
+ rootFiles,
147
+ packageJson: slicePackageJson,
148
+ unusedDependencies,
149
+ warnings
150
+ };
151
+ }
152
+ }
153
+ var rootEntriesOf = (rootFiles) => [...new Set(rootFiles.map((file) => file.split("/")[0] ?? file))].sort();
154
+ function formatSlicePlan(plan) {
155
+ const libCounts = Object.entries(plan.libFiles).map(([lib, files]) => ` - libs/${lib}: ${files.length} files`);
156
+ const sections = [
157
+ "Akan Slice Plan",
158
+ `app: ${plan.app} (apps/${plan.app}: ${plan.appFiles.length} files)`,
159
+ `libs: ${plan.libs.length ? plan.libs.join(", ") : "(none)"}`,
160
+ ...libCounts,
161
+ `workspace shell: ${plan.rootFiles.length} files across ${rootEntriesOf(plan.rootFiles).join(", ")}`,
162
+ "",
163
+ `Unused root dependencies (${plan.unusedDependencies.length}) \u2014 prune candidates, not pruned:`,
164
+ "",
165
+ ...plan.unusedDependencies.length ? plan.unusedDependencies.map((dep) => ` - ${dep}`) : [" (none)"],
166
+ "",
167
+ `Warnings (${plan.warnings.length}):`,
168
+ "",
169
+ ...plan.warnings.length ? plan.warnings.map((warning) => ` - ${warning}`) : [" (none)"]
170
+ ];
171
+ return sections.join(`
172
+ `);
173
+ }
174
+
71
175
  // pkgs/@akanjs/cli/application/application.script.ts
72
176
  import { confirm } from "@inquirer/prompts";
73
177
  import { Logger as Logger5 } from "akanjs/common";
@@ -1915,9 +2019,9 @@ function openBrowser(url) {
1915
2019
  }
1916
2020
 
1917
2021
  // pkgs/@akanjs/cli/application/application.runner.ts
1918
- var loadBuildRunner = async () => (await import("./applicationBuildRunner-ds8acdfz.js")).ApplicationBuildRunner;
2022
+ var loadBuildRunner = async () => (await import("./applicationBuildRunner-8tqhxjd0.js")).ApplicationBuildRunner;
1919
2023
  var loadReleasePackager = async () => (await import("./applicationReleasePackager-0jf6ejr4.js")).ApplicationReleasePackager;
1920
- var loadCapacitorApp = async () => (await import("./capacitorApp-md7dnt25.js")).CapacitorApp;
2024
+ var loadCapacitorApp = async () => (await import("./capacitorApp-szqr3cxr.js")).CapacitorApp;
1921
2025
  var loadAbstractCompactor = async () => (await import("./abstractCompactor-8yjc9sj4.js")).AbstractCompactor;
1922
2026
  var loadPrompts = async () => await import("@inquirer/prompts");
1923
2027
 
@@ -1931,6 +2035,9 @@ class ApplicationRunner extends runner("application") {
1931
2035
  });
1932
2036
  return AppExecutor.from(workspace, appName);
1933
2037
  }
2038
+ async planSlice(app) {
2039
+ return await new SlicePlanner(app).plan();
2040
+ }
1934
2041
  async removeApplication(app) {
1935
2042
  await app.workspace.removeDir(`apps/${app.name}`);
1936
2043
  }
@@ -2406,6 +2513,12 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
2406
2513
  await this.applicationRunner.removeApplication(app);
2407
2514
  spinner.succeed(`Application ${app.name} (apps/${app.name}) removed`);
2408
2515
  }
2516
+ async planSlice(app, format = "text") {
2517
+ const spinner = app.spinning("Planning distributable slice...");
2518
+ const plan = await this.applicationRunner.planSlice(app);
2519
+ spinner.succeed(`Slice planned (${plan.libs.length} libs, ${plan.warnings.length} warnings)`);
2520
+ Logger5.rawLog(format === "json" ? JSON.stringify(plan, null, 2) : formatSlicePlan(plan));
2521
+ }
2409
2522
  async sync(sys) {
2410
2523
  if (sys.type === "app")
2411
2524
  await sys.scanSync();
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-h9cybjep.js";
5
+ } from "./index-zkrzv21w.js";
6
6
 
7
7
  // pkgs/@akanjs/devkit/workflow/utils.ts
8
8
  var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  ModuleScript
4
- } from "./index-vrra4ttx.js";
4
+ } from "./index-ws5zt62x.js";
5
5
  import {
6
6
  addFieldUiPolicyForType,
7
7
  coerceFieldDefault,
@@ -34,15 +34,15 @@ import {
34
34
  sourceFile,
35
35
  validationCommandsForTarget,
36
36
  viaBuilderParameterName
37
- } from "./index-q0s2dp3y.js";
37
+ } from "./index-6w77v5df.js";
38
38
  import {
39
39
  script
40
- } from "./index-akz5xvyw.js";
40
+ } from "./index-1szrbtj9.js";
41
41
  import {
42
42
  AppExecutor,
43
43
  LibExecutor,
44
44
  ModuleExecutor
45
- } from "./index-h9cybjep.js";
45
+ } from "./index-zkrzv21w.js";
46
46
 
47
47
  // pkgs/@akanjs/cli/primitive/primitive.script.ts
48
48
  import { capitalize } from "akanjs/common";
@@ -1,14 +1,14 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-bmz9crym.js";
4
+ } from "./index-w0g7hcr7.js";
5
5
  import {
6
6
  Prompter
7
7
  } from "./index-k7731a4v.js";
8
8
  import {
9
9
  runner,
10
10
  script
11
- } from "./index-akz5xvyw.js";
11
+ } from "./index-1szrbtj9.js";
12
12
  import {
13
13
  AGENT_BLOCK_END,
14
14
  AGENT_BLOCK_START,
@@ -19,7 +19,7 @@ import {
19
19
  renderRecipeEntries,
20
20
  stampBlockVersion,
21
21
  upsertAgentBlock
22
- } from "./index-h9cybjep.js";
22
+ } from "./index-zkrzv21w.js";
23
23
  import {
24
24
  collectRecipeSources,
25
25
  scanRecipes
@@ -1,19 +1,102 @@
1
1
  // @bun
2
+ import {
3
+ __require
4
+ } from "./index-yb2wsc7f.js";
5
+
2
6
  // pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
3
7
  import { mkdir } from "fs/promises";
8
+ import path2 from "path";
9
+
10
+ // pkgs/@akanjs/devkit/transforms/asyncDefaultExportDetector.ts
11
+ import fs from "fs";
4
12
  import path from "path";
13
+
14
+ class AsyncDefaultExportDetector {
15
+ static #typescriptLoad;
16
+ static #loadTypescript() {
17
+ AsyncDefaultExportDetector.#typescriptLoad ??= import("typescript").then((mod) => mod.default ?? mod);
18
+ return AsyncDefaultExportDetector.#typescriptLoad;
19
+ }
20
+ static async detect(moduleAbsPath) {
21
+ try {
22
+ const typescript = await AsyncDefaultExportDetector.#loadTypescript();
23
+ const source = fs.readFileSync(path.resolve(moduleAbsPath), "utf8");
24
+ const sourceFile = typescript.createSourceFile(moduleAbsPath, source, typescript.ScriptTarget.Latest, true, AsyncDefaultExportDetector.#scriptKind(typescript, moduleAbsPath));
25
+ return new AsyncDefaultExportDetector(typescript).detectInSourceFile(sourceFile);
26
+ } catch {
27
+ return false;
28
+ }
29
+ }
30
+ #ts;
31
+ constructor(typescript) {
32
+ this.#ts = typescript;
33
+ }
34
+ detectInSourceFile(sourceFile) {
35
+ const ts = this.#ts;
36
+ const asyncBindings = new Map;
37
+ let defaultIdentifier = null;
38
+ for (const statement of sourceFile.statements) {
39
+ if (ts.isFunctionDeclaration(statement)) {
40
+ if (this.#hasModifier(statement, ts.SyntaxKind.DefaultKeyword)) {
41
+ return this.#hasModifier(statement, ts.SyntaxKind.AsyncKeyword);
42
+ }
43
+ if (statement.name) {
44
+ asyncBindings.set(statement.name.text, this.#hasModifier(statement, ts.SyntaxKind.AsyncKeyword));
45
+ }
46
+ continue;
47
+ }
48
+ if (ts.isVariableStatement(statement)) {
49
+ for (const declaration of statement.declarationList.declarations) {
50
+ if (!ts.isIdentifier(declaration.name))
51
+ continue;
52
+ asyncBindings.set(declaration.name.text, this.#isAsyncFunctionExpression(declaration.initializer));
53
+ }
54
+ continue;
55
+ }
56
+ if (ts.isExportAssignment(statement)) {
57
+ if (this.#isAsyncFunctionExpression(statement.expression))
58
+ return true;
59
+ if (ts.isIdentifier(statement.expression))
60
+ defaultIdentifier = statement.expression.text;
61
+ continue;
62
+ }
63
+ if (ts.isExportDeclaration(statement) && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
64
+ const exportClause = statement.exportClause;
65
+ for (const specifier of exportClause.elements) {
66
+ if (specifier.name.text !== "default")
67
+ continue;
68
+ defaultIdentifier = specifier.propertyName?.text ?? specifier.name.text;
69
+ }
70
+ }
71
+ }
72
+ return defaultIdentifier ? asyncBindings.get(defaultIdentifier) === true : false;
73
+ }
74
+ #hasModifier(node, kind) {
75
+ const ts = this.#ts;
76
+ return ts.canHaveModifiers(node) && (ts.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false);
77
+ }
78
+ #isAsyncFunctionExpression(node) {
79
+ const ts = this.#ts;
80
+ return Boolean(node && (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) && this.#hasModifier(node, ts.SyntaxKind.AsyncKeyword));
81
+ }
82
+ static #scriptKind(typescript, moduleAbsPath) {
83
+ return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ? typescript.ScriptKind.TSX : typescript.ScriptKind.TS;
84
+ }
85
+ }
86
+
87
+ // pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
5
88
  var LAYOUT_KEY_RE = /^\.\/(.+\/)?_layout\.(tsx|ts|jsx|js)$/;
6
89
  async function appHasStModule(appCwdPath) {
7
- return Bun.file(path.join(appCwdPath, "lib", "st.ts")).exists();
90
+ return Bun.file(path2.join(appCwdPath, "lib", "st.ts")).exists();
8
91
  }
9
- var IMPLICIT_LAYOUT_DIR = path.join(".akan", "generated", "root-layouts");
10
- var IMPLICIT_DICT_DIR = path.join(".akan", "generated", "dict");
11
- var IMPLICIT_OVERRIDES_DIR = path.join(".akan", "generated", "overrides");
92
+ var IMPLICIT_LAYOUT_DIR = path2.join(".akan", "generated", "root-layouts");
93
+ var IMPLICIT_DICT_DIR = path2.join(".akan", "generated", "dict");
94
+ var IMPLICIT_OVERRIDES_DIR = path2.join(".akan", "generated", "overrides");
12
95
  var OVERRIDES_KEY_RE = /^\.\/(.+\/)?_overrides\.(tsx|ts|jsx|js)$/;
13
96
  async function writeGeneratedOverridesLayoutFile(opts) {
14
97
  const filename = `${opts.key.replace(/^\.\//, "").replace(/[^a-zA-Z0-9]+/g, "_")}.tsx`;
15
- const absPath = path.join(path.resolve(opts.appCwdPath), IMPLICIT_OVERRIDES_DIR, filename);
16
- const userRel = path.relative(path.dirname(absPath), opts.userAbsPath).split(path.sep).join("/");
98
+ const absPath = path2.join(path2.resolve(opts.appCwdPath), IMPLICIT_OVERRIDES_DIR, filename);
99
+ const userRel = path2.relative(path2.dirname(absPath), opts.userAbsPath).split(path2.sep).join("/");
17
100
  const userSpecifier = userRel.startsWith(".") ? userRel : `./${userRel}`;
18
101
  const source = `"use client";
19
102
  import { UiOverrideProvider } from "akanjs/ui";
@@ -41,10 +124,10 @@ function implicitRootLayoutKey(segments) {
41
124
  }
42
125
  function implicitRootLayoutAbsPath(appCwdPath, segments) {
43
126
  const filename = segments.length ? `${segments.join("__")}__root_layout.tsx` : "__root_layout.tsx";
44
- return path.join(path.resolve(appCwdPath), IMPLICIT_LAYOUT_DIR, filename);
127
+ return path2.join(path2.resolve(appCwdPath), IMPLICIT_LAYOUT_DIR, filename);
45
128
  }
46
129
  function implicitDictionaryMacroAbsPath(appCwdPath) {
47
- return path.join(path.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
130
+ return path2.join(path2.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
48
131
  }
49
132
  function isRootBoundarySegments(segments, basePaths) {
50
133
  const firstVisibleIndex = segments.findIndex((segment) => !/^\(.+\)$/.test(segment));
@@ -67,7 +150,7 @@ function findRootBoundaries(pageKeys, appCwdPath, basePaths) {
67
150
  const id = segments.join("/");
68
151
  boundaries.set(id, {
69
152
  sourceKey: key,
70
- sourceAbsPath: path.resolve(appCwdPath, "page", key.replace(/^\.\//, "")),
153
+ sourceAbsPath: path2.resolve(appCwdPath, "page", key.replace(/^\.\//, "")),
71
154
  segments
72
155
  });
73
156
  }
@@ -85,21 +168,21 @@ function findExplicitRootLayoutAbsPath(pageKeys, appCwdPath) {
85
168
  const segments = getRootBoundarySegments(key);
86
169
  return segments !== null && segments.length === 0;
87
170
  });
88
- return rootLayoutKey ? path.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
171
+ return rootLayoutKey ? path2.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
89
172
  }
90
173
  function routePrefixForSegments(segments) {
91
174
  const visible = segments.filter((segment) => !/^\(.+\)$/.test(segment));
92
175
  return visible[0] ?? null;
93
176
  }
94
177
  async function assertEnvClientConvention(appCwdPath, appName) {
95
- const envPath = path.join(appCwdPath, "env", "env.client.ts");
178
+ const envPath = path2.join(appCwdPath, "env", "env.client.ts");
96
179
  if (!await Bun.file(envPath).exists()) {
97
180
  throw new Error(`[route-convention] app "${appName}" must provide env/env.client.ts exporting "env" for generated System.Provider`);
98
181
  }
99
182
  }
100
183
  async function writeGeneratedDictionaryMacroFile(appCwdPath, appName) {
101
184
  const absPath = implicitDictionaryMacroAbsPath(appCwdPath);
102
- await mkdir(path.dirname(absPath), { recursive: true });
185
+ await mkdir(path2.dirname(absPath), { recursive: true });
103
186
  await Bun.write(absPath, `import { getAllDictionary } from "@apps/${appName}/lib/dict" with { type: "macro" };
104
187
 
105
188
  export const allDictionary = getAllDictionary();
@@ -110,13 +193,13 @@ async function writeGeneratedRootLayoutFile(opts) {
110
193
  await assertEnvClientConvention(opts.appCwdPath, opts.appName);
111
194
  const dictMacroAbsPath = opts.includeSystemProvider ? await writeGeneratedDictionaryMacroFile(opts.appCwdPath, opts.appName) : null;
112
195
  const absPath = implicitRootLayoutAbsPath(opts.appCwdPath, opts.boundary.segments);
113
- await mkdir(path.dirname(absPath), { recursive: true });
114
- const dictMacroRel = dictMacroAbsPath ? path.relative(path.dirname(absPath), dictMacroAbsPath).split(path.sep).join("/") : null;
196
+ await mkdir(path2.dirname(absPath), { recursive: true });
197
+ const dictMacroRel = dictMacroAbsPath ? path2.relative(path2.dirname(absPath), dictMacroAbsPath).split(path2.sep).join("/") : null;
115
198
  const dictMacroSpecifier = dictMacroRel ? dictMacroRel.startsWith(".") ? dictMacroRel : `./${dictMacroRel}` : null;
116
- const sourceRel = opts.boundary.sourceAbsPath ? path.relative(path.dirname(absPath), opts.boundary.sourceAbsPath).split(path.sep).join("/") : null;
199
+ const sourceRel = opts.boundary.sourceAbsPath ? path2.relative(path2.dirname(absPath), opts.boundary.sourceAbsPath).split(path2.sep).join("/") : null;
117
200
  const sourceSpecifier = sourceRel ? sourceRel.startsWith(".") ? sourceRel : `./${sourceRel}` : null;
118
201
  const inheritedSourceAbsPath = opts.rootSourceAbsPath && opts.rootSourceAbsPath !== opts.boundary.sourceAbsPath ? opts.rootSourceAbsPath : null;
119
- const inheritedSourceRel = inheritedSourceAbsPath ? path.relative(path.dirname(absPath), inheritedSourceAbsPath).split(path.sep).join("/") : null;
202
+ const inheritedSourceRel = inheritedSourceAbsPath ? path2.relative(path2.dirname(absPath), inheritedSourceAbsPath).split(path2.sep).join("/") : null;
120
203
  const inheritedSourceSpecifier = inheritedSourceRel ? inheritedSourceRel.startsWith(".") ? inheritedSourceRel : `./${inheritedSourceRel}` : null;
121
204
  const clientImport = opts.includeStInit ? `import { st } from "@apps/${opts.appName}/client";
122
205
  void st;
@@ -130,6 +213,16 @@ void st;
130
213
  ` : `const UserLayout = ({ children }) => children;
131
214
  const userLayout = {};
132
215
  `;
216
+ const isAsyncUserLayout = opts.boundary.sourceAbsPath ? await AsyncDefaultExportDetector.detect(opts.boundary.sourceAbsPath) : false;
217
+ const userLayoutElement = "<UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>";
218
+ const layoutSignature = isAsyncUserLayout ? "export default async function GeneratedLayout" : "export default function GeneratedLayout";
219
+ const layoutBinding = isAsyncUserLayout ? ` const layout =
220
+ process.env.AKAN_PUBLIC_RENDER_ENV === "csr"
221
+ ? await UserLayout({ params, searchParams, children })
222
+ : ${userLayoutElement};
223
+ ` : "";
224
+ const layoutChild = isAsyncUserLayout ? "{layout}" : userLayoutElement;
225
+ const layoutReturn = isAsyncUserLayout ? "layout" : userLayoutElement;
133
226
  const source = opts.includeSystemProvider ? `import type { LayoutProps, PageProps } from "akanjs/client";
134
227
  import { loadFonts } from "akanjs/client";
135
228
  import { System } from "akanjs/ui";
@@ -160,8 +253,8 @@ export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
160
253
  export const Error = userLayout.Error ?? inheritedLayout.Error;
161
254
  export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
162
255
 
163
- export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
164
- return (
256
+ ${layoutSignature}({ children, params, searchParams }: LayoutProps) {
257
+ ${layoutBinding} return (
165
258
  <System.Provider
166
259
  of={GeneratedLayout as never}
167
260
  appName=${JSON.stringify(opts.appName)}
@@ -178,7 +271,7 @@ export default function GeneratedLayout({ children, params, searchParams }: Layo
178
271
  wsConnect={userLayout.wsConnect ?? inheritedLayout.wsConnect ?? true}
179
272
  allDictionary={process.env.AKAN_PUBLIC_RENDER_ENV === "ssr" ? allDictionary : undefined}
180
273
  >
181
- <UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>
274
+ ${layoutChild}
182
275
  </System.Provider>
183
276
  );
184
277
  }
@@ -202,15 +295,15 @@ export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
202
295
  export const Error = userLayout.Error ?? inheritedLayout.Error;
203
296
  export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
204
297
 
205
- export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
206
- return <UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>;
298
+ ${layoutSignature}({ children, params, searchParams }: LayoutProps) {
299
+ ${layoutBinding} return ${layoutReturn};
207
300
  }
208
301
  `;
209
302
  await Bun.write(absPath, source);
210
303
  return absPath;
211
304
  }
212
305
  async function resolveSsrPageEntries(opts) {
213
- const absPageDir = path.resolve(opts.appCwdPath, "page");
306
+ const absPageDir = path2.resolve(opts.appCwdPath, "page");
214
307
  const hasSt = await appHasStModule(opts.appCwdPath);
215
308
  const basePaths = opts.basePaths ?? [];
216
309
  const rootSourceAbsPath = findExplicitRootLayoutAbsPath(opts.pageKeys, opts.appCwdPath);
@@ -220,7 +313,7 @@ async function resolveSsrPageEntries(opts) {
220
313
  return segments !== null && isRootBoundarySegments(segments, basePaths);
221
314
  }));
222
315
  const base = await Promise.all(opts.pageKeys.filter((key) => !rootLayoutKeys.has(key)).map(async (key) => {
223
- const userAbsPath = path.resolve(absPageDir, key);
316
+ const userAbsPath = path2.resolve(absPageDir, key);
224
317
  if (OVERRIDES_KEY_RE.test(key)) {
225
318
  const moduleAbsPath = await writeGeneratedOverridesLayoutFile({
226
319
  appCwdPath: opts.appCwdPath,
@@ -252,4 +345,4 @@ async function resolveSsrPageEntriesForApp(app, pageKeys) {
252
345
  return resolveSsrPageEntries({ appCwdPath: app.cwdPath, appName: app.name, pageKeys, basePaths: config.basePaths });
253
346
  }
254
347
 
255
- export { getRootBoundarySegments, isRootBoundarySegments, resolveSsrPageEntriesForApp };
348
+ export { AsyncDefaultExportDetector, getRootBoundarySegments, isRootBoundarySegments, resolveSsrPageEntriesForApp };
@@ -1,10 +1,10 @@
1
1
  // @bun
2
2
  import {
3
3
  CloudRunner
4
- } from "./index-116w1dap.js";
4
+ } from "./index-hffr3myr.js";
5
5
  import {
6
6
  PackageScript
7
- } from "./index-qge1hc70.js";
7
+ } from "./index-ffrhjdwd.js";
8
8
  import {
9
9
  AiSession,
10
10
  CloudApi,
@@ -12,13 +12,13 @@ import {
12
12
  } from "./index-safgeq9a.js";
13
13
  import {
14
14
  ApplicationScript
15
- } from "./index-5r4e65hb.js";
15
+ } from "./index-4930mtpt.js";
16
16
  import {
17
17
  script
18
- } from "./index-akz5xvyw.js";
18
+ } from "./index-1szrbtj9.js";
19
19
  import {
20
20
  PkgExecutor
21
- } from "./index-h9cybjep.js";
21
+ } from "./index-zkrzv21w.js";
22
22
 
23
23
  // pkgs/@akanjs/cli/cloud/cloud.script.ts
24
24
  import { Logger } from "akanjs/common";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-bmz9crym.js";
4
+ } from "./index-w0g7hcr7.js";
5
5
  import {
6
6
  WorkflowExecutor,
7
7
  compactWorkflowInputs,
@@ -23,10 +23,10 @@ import {
23
23
  workflowCommandsForPlan,
24
24
  workflowPlanApproval,
25
25
  writeWorkflowRunArtifact
26
- } from "./index-q0s2dp3y.js";
26
+ } from "./index-6w77v5df.js";
27
27
  import {
28
28
  runner
29
- } from "./index-akz5xvyw.js";
29
+ } from "./index-1szrbtj9.js";
30
30
 
31
31
  // pkgs/@akanjs/cli/workflow/workflow.runner.ts
32
32
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-akz5xvyw.js";
5
+ } from "./index-1szrbtj9.js";
6
6
  import {
7
7
  PkgExecutor
8
- } from "./index-h9cybjep.js";
8
+ } from "./index-zkrzv21w.js";
9
9
  import {
10
10
  TypeScriptDependencyScanner
11
11
  } from "./index-h5sr2nnj.js";
@@ -7,14 +7,14 @@ import {
7
7
  } from "./index-safgeq9a.js";
8
8
  import {
9
9
  openBrowser
10
- } from "./index-5r4e65hb.js";
10
+ } from "./index-4930mtpt.js";
11
11
  import {
12
12
  runner
13
- } from "./index-akz5xvyw.js";
13
+ } from "./index-1szrbtj9.js";
14
14
  import {
15
15
  AppExecutor,
16
16
  WorkspaceExecutor
17
- } from "./index-h9cybjep.js";
17
+ } from "./index-zkrzv21w.js";
18
18
 
19
19
  // pkgs/@akanjs/cli/npmRegistry.ts
20
20
  var defaultNpmRegistry = "https://registry.npmjs.org";
@@ -1,22 +1,22 @@
1
1
  // @bun
2
2
  import {
3
3
  RepairRunner
4
- } from "./index-q13s3e01.js";
4
+ } from "./index-qwfwk8be.js";
5
5
  import {
6
6
  WorkflowRunner
7
- } from "./index-a341yqdh.js";
7
+ } from "./index-egng0kc4.js";
8
8
  import {
9
9
  ScalarScript
10
- } from "./index-9gqzgfsd.js";
10
+ } from "./index-0cdwa7qj.js";
11
11
  import {
12
12
  PrimitiveScript
13
- } from "./index-z52nhkjs.js";
13
+ } from "./index-7x5ks4ph.js";
14
14
  import {
15
15
  ModuleScript
16
- } from "./index-vrra4ttx.js";
16
+ } from "./index-ws5zt62x.js";
17
17
  import {
18
18
  isPlaceholderAppId
19
- } from "./index-ym9g9ggs.js";
19
+ } from "./index-zec5gcx0.js";
20
20
  import {
21
21
  AkanContextAnalyzer,
22
22
  akanMcpInstallConfigPaths,
@@ -27,14 +27,14 @@ import {
27
27
  createAkanMcpServer,
28
28
  renderDoctorText,
29
29
  upsertCodexMcpServerBlock
30
- } from "./index-bmz9crym.js";
30
+ } from "./index-w0g7hcr7.js";
31
31
  import {
32
32
  buildAkanModuleContextIndex,
33
33
  createWorkflowBaselineSummary,
34
34
  createWorkflowStepRegistry,
35
35
  jsonText,
36
36
  toolingRolloutGate
37
- } from "./index-q0s2dp3y.js";
37
+ } from "./index-6w77v5df.js";
38
38
  import {
39
39
  Prompter
40
40
  } from "./index-k7731a4v.js";
@@ -45,10 +45,10 @@ import {
45
45
  CommandContainer,
46
46
  runner,
47
47
  script
48
- } from "./index-akz5xvyw.js";
48
+ } from "./index-1szrbtj9.js";
49
49
  import {
50
50
  AppExecutor
51
- } from "./index-h9cybjep.js";
51
+ } from "./index-zkrzv21w.js";
52
52
 
53
53
  // pkgs/@akanjs/cli/context/context.script.ts
54
54
  import { Logger } from "akanjs/common";
@@ -1,17 +1,17 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-bmz9crym.js";
4
+ } from "./index-w0g7hcr7.js";
5
5
  import {
6
6
  createRepairReport,
7
7
  generatedFilePathsForTarget,
8
8
  renderRepairReport,
9
9
  writeGeneratedSyncState,
10
10
  writeWorkflowRunArtifact
11
- } from "./index-q0s2dp3y.js";
11
+ } from "./index-6w77v5df.js";
12
12
  import {
13
13
  runner
14
- } from "./index-akz5xvyw.js";
14
+ } from "./index-1szrbtj9.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/repair/repair.runner.ts
17
17
  var commandForShell = (command) => command.startsWith("akan ") ? `bun run ${command}` : command;
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  workflowRunArtifactPath,
4
4
  workflowSyncDir
5
- } from "./index-q0s2dp3y.js";
5
+ } from "./index-6w77v5df.js";
6
6
  import {
7
7
  AppExecutor,
8
8
  LibExecutor,
@@ -11,7 +11,7 @@ import {
11
11
  readDevkitVersion,
12
12
  rootAllowedDirs,
13
13
  rootAllowedFiles
14
- } from "./index-h9cybjep.js";
14
+ } from "./index-zkrzv21w.js";
15
15
  import {
16
16
  collectRecipeSources,
17
17
  findInlineRecipeDuplicates,