@akanjs/cli 3.0.0-alpha.79 → 3.0.0-alpha.80

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 (76) hide show
  1. package/.build-stamp +1 -1
  2. package/{abstractCompactor-8yjc9sj4.js → abstractCompactor-pwc6d6yk.js} +3 -5
  3. package/{agent.command-q2rgd8jz.js → agent.command-180hh0ye.js} +11 -14
  4. package/{application.command-kd5zj0k9.js → application.command-gmcgen9y.js} +29 -34
  5. package/{applicationBuildRunner-8tqhxjd0.js → applicationBuildRunner-tavpx3fv.js} +9 -12
  6. package/{applicationReleasePackager-0jf6ejr4.js → applicationReleasePackager-ktjt0erc.js} +6 -7
  7. package/buildBatch.proc.js +12 -15
  8. package/capacitorApp-kwa67kzs.js +12 -0
  9. package/{cloud.command-v60xnfdx.js → cloud.command-gpq7qxrc.js} +15 -21
  10. package/{context.command-hac3x83c.js → context.command-dk2m2sjx.js} +19 -24
  11. package/dependencyScanner-c64m6fxp.js +8 -0
  12. package/{fleet.command-jv24wcae.js → fleet.command-3bkyyd3a.js} +67 -24
  13. package/getDirname-dr3jz1xg.js +7 -0
  14. package/{guideline.command-85x1tvjb.js → guideline.command-w6ddv13r.js} +16 -19
  15. package/incrementalBuilder.proc.js +17 -20
  16. package/{index-yz8988we.js → index-1kzsn94d.js} +1 -1
  17. package/{index-dz1q44m8.js → index-3c9n3nt8.js} +21 -21
  18. package/{index-76rn3g2c.js → index-47pj3aee.js} +4 -4
  19. package/{index-dfn0kqj7.js → index-5n0hf8r9.js} +19 -19
  20. package/{index-w0g7hcr7.js → index-5y7qba1c.js} +19 -19
  21. package/{index-1577bej2.js → index-6wwzs1bc.js} +2 -2
  22. package/{index-94hdqqka.js → index-92zztqy1.js} +6 -6
  23. package/{index-ffrhjdwd.js → index-a8h184wr.js} +7 -7
  24. package/{index-67546d0j.js → index-ayy5ecax.js} +1 -1
  25. package/{index-zec5gcx0.js → index-b2nt0w0k.js} +7 -7
  26. package/{index-xys926f2.js → index-by5gpp8x.js} +4 -4
  27. package/{index-47zynjx7.js → index-cd5x18qh.js} +32 -32
  28. package/{index-pzsryyjv.js → index-dq6wq1tv.js} +39 -39
  29. package/{index-psx0z6hb.js → index-ee8z8adx.js} +13 -13
  30. package/{index-zp0cmfgd.js → index-f7wewj2v.js} +22 -25
  31. package/{index-1szrbtj9.js → index-ft1sfjz0.js} +20 -23
  32. package/{index-k7731a4v.js → index-h7yw2z9n.js} +3 -3
  33. package/{index-egng0kc4.js → index-j9vnq8tr.js} +18 -18
  34. package/{index-zkrzv21w.js → index-k1n0h7dk.js} +519 -123
  35. package/{index-pj3hk9kt.js → index-k86zc21w.js} +57 -57
  36. package/{index-h5sr2nnj.js → index-mfm35dhh.js} +5 -5
  37. package/{index-qwfwk8be.js → index-qcracvc9.js} +8 -8
  38. package/{index-6w77v5df.js → index-saheq2bs.js} +4 -4
  39. package/{index-ta1mk0xh.js → index-v0s24t8j.js} +15 -15
  40. package/{index-safgeq9a.js → index-wet2ytnr.js} +8 -8
  41. package/{index-jn9b717k.js → index-xnhf8tr9.js} +1 -1
  42. package/{index-7605ykh6.js → index-xxe90kqy.js} +6 -6
  43. package/{index-25qfm3at.js → index-z3c9mmw4.js} +14 -16
  44. package/index.js +22 -27
  45. package/{library.command-nvp0wetm.js → library.command-wpedct6c.js} +7 -11
  46. package/{localRegistry.command-dnefn893.js → localRegistry.command-pjdxa01g.js} +20 -26
  47. package/{module.command-xs6ded4j.js → module.command-8n4kct3e.js} +13 -17
  48. package/{package.command-af8sxhff.js → package.command-fcbd0b1d.js} +8 -11
  49. package/package.json +2 -2
  50. package/{page.command-gr6rbz17.js → page.command-x4379grq.js} +7 -10
  51. package/{primitive.command-qjf4mbth.js → primitive.command-8etmnqhq.js} +13 -17
  52. package/{quality.command-9xhaxzm1.js → quality.command-hfx7z8yr.js} +11 -14
  53. package/recipeScanner-fpagtgc1.js +11 -0
  54. package/{repair.command-a2z4d5a0.js → repair.command-j0fs5qkz.js} +12 -15
  55. package/{routeSourceValidator-7fycdqyv.js → routeSourceValidator-ze6x894c.js} +0 -2
  56. package/{scalar.command-ax8taqh1.js → scalar.command-2emk89eh.js} +11 -15
  57. package/templates/workspaceRoot/package.json.template +1 -3
  58. package/typeChecker-3xgrzc2v.js +7 -0
  59. package/typecheck.proc.js +4 -5
  60. package/{workflow.command-gwkw0jae.js → workflow.command-cvpmzwjg.js} +22 -26
  61. package/{workspace.command-53qpkgzp.js → workspace.command-mbb5s3wx.js} +57 -64
  62. package/capacitorApp-szqr3cxr.js +0 -62
  63. package/dependencyScanner-aqg3dkks.js +0 -9
  64. package/getDirname-ka11hm7e.js +0 -8
  65. package/index-dp66vwr6.js +0 -348
  66. package/index-mxvakhsm.js +0 -66
  67. package/index-yb2wsc7f.js +0 -4
  68. package/recipeScanner-zrzev25x.js +0 -12
  69. package/typeChecker-yhs4eht8.js +0 -8
  70. /package/{index-19nz5chq.js → index-3d9y066c.js} +0 -0
  71. /package/{index-ynf37b66.js → index-a5vmm6x4.js} +0 -0
  72. /package/{index-5vy2jzar.js → index-ctphds8v.js} +0 -0
  73. /package/{index-0wae5ebk.js → index-meh558jy.js} +0 -0
  74. /package/{index-scemmfpj.js → index-n68jx79w.js} +0 -0
  75. /package/{index-ss469dec.js → index-nz8prx9g.js} +0 -0
  76. /package/{index-jcm6zr20.js → index-x23688ar.js} +0 -0
@@ -1,20 +1,74 @@
1
1
  // @bun
2
- import {
3
- getRootBoundarySegments,
4
- isRootBoundarySegments
5
- } from "./index-dp66vwr6.js";
6
- import {
7
- Spinner
8
- } from "./index-mxvakhsm.js";
9
- import {
10
- getDirname
11
- } from "./index-1577bej2.js";
12
2
  import {
13
3
  FileSys
14
- } from "./index-67546d0j.js";
4
+ } from "./index-ayy5ecax.js";
15
5
  import {
16
- __require
17
- } from "./index-yb2wsc7f.js";
6
+ getDirname2
7
+ } from "./index-6wwzs1bc.js";
8
+
9
+ // pkgs/@akanjs/devkit/spinner.ts
10
+ import ora from "ora";
11
+
12
+ class Spinner {
13
+ static padding = 12;
14
+ static oraOptions = { discardStdin: false };
15
+ static canAnimate(stream = process.stderr) {
16
+ return !stream.isTTY || stream.columns > 0;
17
+ }
18
+ spinner;
19
+ stopWatch = null;
20
+ startAt = new Date;
21
+ prefix;
22
+ message;
23
+ enableSpin;
24
+ constructor(message, { prefix = "", indent = 0, enableSpin = true } = {}) {
25
+ Spinner.padding = Math.max(Spinner.padding, prefix.length);
26
+ this.prefix = prefix;
27
+ this.message = message;
28
+ this.spinner = ora({ ...Spinner.oraOptions, text: message });
29
+ this.spinner.prefixText = prefix.padStart(Spinner.padding, " ");
30
+ this.spinner.indent = indent;
31
+ this.enableSpin = enableSpin && Spinner.canAnimate();
32
+ }
33
+ start() {
34
+ this.startAt = new Date;
35
+ if (this.enableSpin) {
36
+ this.spinner.start();
37
+ this.stopWatch = setInterval(() => {
38
+ this.spinner.prefixText = this.prefix.padStart(Spinner.padding, " ");
39
+ this.spinner.text = `${this.message} (${this.#getElapsedTimeStr({ floor: true })})`;
40
+ }, 1000);
41
+ } else
42
+ this.spinner.info();
43
+ return this;
44
+ }
45
+ succeed(message) {
46
+ this.spinner.succeed(`${message} (${this.#getElapsedTimeStr()})`);
47
+ this.#reset();
48
+ }
49
+ fail(message) {
50
+ this.spinner.fail(`${message} (${this.#getElapsedTimeStr()})`);
51
+ this.#reset();
52
+ }
53
+ isSpinning() {
54
+ return this.spinner.isSpinning;
55
+ }
56
+ #reset() {
57
+ if (this.stopWatch)
58
+ clearInterval(this.stopWatch);
59
+ this.stopWatch = null;
60
+ }
61
+ #getElapsedTimeStr({ floor = false } = {}) {
62
+ const ms = Date.now() - this.startAt.getTime();
63
+ if (ms < 1000)
64
+ return `${ms}ms`;
65
+ const s = Math.floor(ms / 1000);
66
+ if (s < 60)
67
+ return `${floor ? Math.floor(ms / 1000) : Math.floor(ms / 100) / 10}s`;
68
+ const m = Math.floor(s / 60);
69
+ return `${m}m ${s % 60}s`;
70
+ }
71
+ }
18
72
 
19
73
  // pkgs/@akanjs/devkit/executors.ts
20
74
  import {
@@ -26,14 +80,14 @@ import { readFileSync as readFileSync2 } from "fs";
26
80
  import {
27
81
  copyFile,
28
82
  cp as cpEntry,
29
- mkdir,
83
+ mkdir as mkdir2,
30
84
  readdir as readDirEntries,
31
85
  realpath,
32
86
  rm as rm2,
33
87
  stat,
34
88
  symlink
35
89
  } from "fs/promises";
36
- import path5 from "path";
90
+ import path7 from "path";
37
91
  import { pathToFileURL } from "url";
38
92
  import {
39
93
  capitalize,
@@ -49,7 +103,7 @@ import chalk2 from "chalk";
49
103
 
50
104
  // pkgs/@akanjs/devkit/agentsIndex.ts
51
105
  var recipeScannerLoad = null;
52
- var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-zrzev25x.js");
106
+ var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-fpagtgc1.js");
53
107
  var AGENT_BLOCK_START = "<!-- akan:agent:start -->";
54
108
  var AGENT_BLOCK_END = "<!-- akan:agent:end -->";
55
109
  var AGENT_VERSION_PREFIX = "<!-- akan:agent:version ";
@@ -59,9 +113,9 @@ ${block}`;
59
113
  var extractBlockVersion = (content) => content.match(/<!-- akan:agent:version ([^\s]+) -->/)?.[1] ?? null;
60
114
  var readDevkitVersion = async () => {
61
115
  const { readFile } = await import("fs/promises");
62
- const { getDirname: getDirname2 } = await import("./getDirname-ka11hm7e.js");
116
+ const { getDirname } = await import("./getDirname-dr3jz1xg.js");
63
117
  try {
64
- const raw = await readFile(`${getDirname2(import.meta.url)}/package.json`, "utf-8");
118
+ const raw = await readFile(`${getDirname(import.meta.url)}/package.json`, "utf-8");
65
119
  return JSON.parse(raw).version ?? null;
66
120
  } catch {
67
121
  return null;
@@ -715,10 +769,352 @@ var decreaseBuildNum = async (app) => {
715
769
  const akanConfigContent = akanConfig.replace(`buildNum: ${appConfig.mobile.buildNum}`, `buildNum: ${appConfig.mobile.buildNum - 1}`);
716
770
  fs.writeFileSync(akanConfigPath, akanConfigContent);
717
771
  };
772
+ // pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
773
+ import { mkdir } from "fs/promises";
774
+ import path3 from "path";
775
+
776
+ // pkgs/@akanjs/devkit/transforms/asyncDefaultExportDetector.ts
777
+ import fs2 from "fs";
778
+ import path2 from "path";
779
+
780
+ class AsyncDefaultExportDetector {
781
+ static #typescriptLoad;
782
+ static #loadTypescript() {
783
+ AsyncDefaultExportDetector.#typescriptLoad ??= import("typescript").then((mod) => mod.default ?? mod);
784
+ return AsyncDefaultExportDetector.#typescriptLoad;
785
+ }
786
+ static async detect(moduleAbsPath) {
787
+ try {
788
+ const typescript = await AsyncDefaultExportDetector.#loadTypescript();
789
+ const source = fs2.readFileSync(path2.resolve(moduleAbsPath), "utf8");
790
+ const sourceFile = typescript.createSourceFile(moduleAbsPath, source, typescript.ScriptTarget.Latest, true, AsyncDefaultExportDetector.#scriptKind(typescript, moduleAbsPath));
791
+ return new AsyncDefaultExportDetector(typescript).detectInSourceFile(sourceFile);
792
+ } catch {
793
+ return false;
794
+ }
795
+ }
796
+ #ts;
797
+ constructor(typescript) {
798
+ this.#ts = typescript;
799
+ }
800
+ detectInSourceFile(sourceFile) {
801
+ const ts = this.#ts;
802
+ const asyncBindings = new Map;
803
+ let defaultIdentifier = null;
804
+ for (const statement of sourceFile.statements) {
805
+ if (ts.isFunctionDeclaration(statement)) {
806
+ if (this.#hasModifier(statement, ts.SyntaxKind.DefaultKeyword)) {
807
+ return this.#hasModifier(statement, ts.SyntaxKind.AsyncKeyword);
808
+ }
809
+ if (statement.name) {
810
+ asyncBindings.set(statement.name.text, this.#hasModifier(statement, ts.SyntaxKind.AsyncKeyword));
811
+ }
812
+ continue;
813
+ }
814
+ if (ts.isVariableStatement(statement)) {
815
+ for (const declaration of statement.declarationList.declarations) {
816
+ if (!ts.isIdentifier(declaration.name))
817
+ continue;
818
+ asyncBindings.set(declaration.name.text, this.#isAsyncFunctionExpression(declaration.initializer));
819
+ }
820
+ continue;
821
+ }
822
+ if (ts.isExportAssignment(statement)) {
823
+ if (this.#isAsyncFunctionExpression(statement.expression))
824
+ return true;
825
+ if (ts.isIdentifier(statement.expression))
826
+ defaultIdentifier = statement.expression.text;
827
+ continue;
828
+ }
829
+ if (ts.isExportDeclaration(statement) && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
830
+ const exportClause = statement.exportClause;
831
+ for (const specifier of exportClause.elements) {
832
+ if (specifier.name.text !== "default")
833
+ continue;
834
+ defaultIdentifier = specifier.propertyName?.text ?? specifier.name.text;
835
+ }
836
+ }
837
+ }
838
+ return defaultIdentifier ? asyncBindings.get(defaultIdentifier) === true : false;
839
+ }
840
+ #hasModifier(node, kind) {
841
+ const ts = this.#ts;
842
+ return ts.canHaveModifiers(node) && (ts.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false);
843
+ }
844
+ #isAsyncFunctionExpression(node) {
845
+ const ts = this.#ts;
846
+ return Boolean(node && (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) && this.#hasModifier(node, ts.SyntaxKind.AsyncKeyword));
847
+ }
848
+ static #scriptKind(typescript, moduleAbsPath) {
849
+ return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ? typescript.ScriptKind.TSX : typescript.ScriptKind.TS;
850
+ }
851
+ }
852
+
853
+ // pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
854
+ var LAYOUT_KEY_RE = /^\.\/(.+\/)?_layout\.(tsx|ts|jsx|js)$/;
855
+ async function appHasStModule(appCwdPath) {
856
+ return Bun.file(path3.join(appCwdPath, "lib", "st.ts")).exists();
857
+ }
858
+ var IMPLICIT_LAYOUT_DIR = path3.join(".akan", "generated", "root-layouts");
859
+ var IMPLICIT_DICT_DIR = path3.join(".akan", "generated", "dict");
860
+ var IMPLICIT_OVERRIDES_DIR = path3.join(".akan", "generated", "overrides");
861
+ var OVERRIDES_KEY_RE = /^\.\/(.+\/)?_overrides\.(tsx|ts|jsx|js)$/;
862
+ async function writeGeneratedOverridesLayoutFile(opts) {
863
+ const filename = `${opts.key.replace(/^\.\//, "").replace(/[^a-zA-Z0-9]+/g, "_")}.tsx`;
864
+ const absPath = path3.join(path3.resolve(opts.appCwdPath), IMPLICIT_OVERRIDES_DIR, filename);
865
+ const userRel = path3.relative(path3.dirname(absPath), opts.userAbsPath).split(path3.sep).join("/");
866
+ const userSpecifier = userRel.startsWith(".") ? userRel : `./${userRel}`;
867
+ const source = `"use client";
868
+ import { UiOverrideProvider } from "akanjs/ui";
869
+ import { createElement, type ReactNode } from "react";
870
+ import value from ${JSON.stringify(userSpecifier)};
871
+
872
+ export default function AkanUiOverridesLayout({ children }: { children?: ReactNode }) {
873
+ return createElement(UiOverrideProvider, { value }, children);
874
+ }
875
+ `;
876
+ await Bun.write(absPath, source);
877
+ return absPath;
878
+ }
879
+ function getRootBoundarySegments(key) {
880
+ const match = LAYOUT_KEY_RE.exec(key);
881
+ if (!match)
882
+ return null;
883
+ const prefix = match[1]?.replace(/\/$/, "");
884
+ if (!prefix)
885
+ return [];
886
+ return prefix.split("/").filter(Boolean);
887
+ }
888
+ function implicitRootLayoutKey(segments) {
889
+ return `./${[...segments, "__root_layout"].join("/")}.tsx`;
890
+ }
891
+ function implicitRootLayoutAbsPath(appCwdPath, segments) {
892
+ const filename = segments.length ? `${segments.join("__")}__root_layout.tsx` : "__root_layout.tsx";
893
+ return path3.join(path3.resolve(appCwdPath), IMPLICIT_LAYOUT_DIR, filename);
894
+ }
895
+ function implicitDictionaryMacroAbsPath(appCwdPath) {
896
+ return path3.join(path3.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
897
+ }
898
+ function isRootBoundarySegments(segments, basePaths) {
899
+ const firstVisibleIndex = segments.findIndex((segment) => !/^\(.+\)$/.test(segment));
900
+ if (firstVisibleIndex === -1)
901
+ return segments.length <= 1;
902
+ if (segments.slice(firstVisibleIndex + 1).some((segment) => /^\(.+\)$/.test(segment)))
903
+ return false;
904
+ const visible = segments.slice(firstVisibleIndex);
905
+ const allowedBasePaths = new Set([...basePaths].map((basePath) => basePath.trim()).filter(Boolean));
906
+ return visible.length === 1 && (firstVisibleIndex > 0 || allowedBasePaths.has(visible[0] ?? ""));
907
+ }
908
+ function findRootBoundaries(pageKeys, appCwdPath, basePaths) {
909
+ const boundaries = new Map;
910
+ for (const key of pageKeys) {
911
+ const segments = getRootBoundarySegments(key);
912
+ if (!segments)
913
+ continue;
914
+ if (!isRootBoundarySegments(segments, basePaths))
915
+ continue;
916
+ const id = segments.join("/");
917
+ boundaries.set(id, {
918
+ sourceKey: key,
919
+ sourceAbsPath: path3.resolve(appCwdPath, "page", key.replace(/^\.\//, "")),
920
+ segments
921
+ });
922
+ }
923
+ const hasExplicitRootBoundary = [...boundaries.values()].some((boundary) => boundary.segments.length === 0);
924
+ if (!hasExplicitRootBoundary && boundaries.size === 0) {
925
+ boundaries.set("", { sourceKey: null, sourceAbsPath: null, segments: [] });
926
+ }
927
+ return [...boundaries.values()].sort((a, b) => a.segments.join("/").localeCompare(b.segments.join("/")));
928
+ }
929
+ function hasAncestorRootBoundary(boundary, boundaries) {
930
+ return boundaries.some((candidate) => candidate !== boundary && candidate.segments.length < boundary.segments.length && candidate.segments.every((segment, index) => boundary.segments[index] === segment));
931
+ }
932
+ function findExplicitRootLayoutAbsPath(pageKeys, appCwdPath) {
933
+ const rootLayoutKey = pageKeys.find((key) => {
934
+ const segments = getRootBoundarySegments(key);
935
+ return segments !== null && segments.length === 0;
936
+ });
937
+ return rootLayoutKey ? path3.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
938
+ }
939
+ function routePrefixForSegments(segments) {
940
+ const visible = segments.filter((segment) => !/^\(.+\)$/.test(segment));
941
+ return visible[0] ?? null;
942
+ }
943
+ async function assertEnvClientConvention(appCwdPath, appName) {
944
+ const envPath = path3.join(appCwdPath, "env", "env.client.ts");
945
+ if (!await Bun.file(envPath).exists()) {
946
+ throw new Error(`[route-convention] app "${appName}" must provide env/env.client.ts exporting "env" for generated System.Provider`);
947
+ }
948
+ }
949
+ async function writeGeneratedDictionaryMacroFile(appCwdPath, appName) {
950
+ const absPath = implicitDictionaryMacroAbsPath(appCwdPath);
951
+ await mkdir(path3.dirname(absPath), { recursive: true });
952
+ await Bun.write(absPath, `import { getAllDictionary } from "@apps/${appName}/lib/dict" with { type: "macro" };
953
+
954
+ export const allDictionary = getAllDictionary();
955
+ `);
956
+ return absPath;
957
+ }
958
+ async function writeGeneratedRootLayoutFile(opts) {
959
+ await assertEnvClientConvention(opts.appCwdPath, opts.appName);
960
+ const dictMacroAbsPath = opts.includeSystemProvider ? await writeGeneratedDictionaryMacroFile(opts.appCwdPath, opts.appName) : null;
961
+ const absPath = implicitRootLayoutAbsPath(opts.appCwdPath, opts.boundary.segments);
962
+ await mkdir(path3.dirname(absPath), { recursive: true });
963
+ const dictMacroRel = dictMacroAbsPath ? path3.relative(path3.dirname(absPath), dictMacroAbsPath).split(path3.sep).join("/") : null;
964
+ const dictMacroSpecifier = dictMacroRel ? dictMacroRel.startsWith(".") ? dictMacroRel : `./${dictMacroRel}` : null;
965
+ const sourceRel = opts.boundary.sourceAbsPath ? path3.relative(path3.dirname(absPath), opts.boundary.sourceAbsPath).split(path3.sep).join("/") : null;
966
+ const sourceSpecifier = sourceRel ? sourceRel.startsWith(".") ? sourceRel : `./${sourceRel}` : null;
967
+ const inheritedSourceAbsPath = opts.rootSourceAbsPath && opts.rootSourceAbsPath !== opts.boundary.sourceAbsPath ? opts.rootSourceAbsPath : null;
968
+ const inheritedSourceRel = inheritedSourceAbsPath ? path3.relative(path3.dirname(absPath), inheritedSourceAbsPath).split(path3.sep).join("/") : null;
969
+ const inheritedSourceSpecifier = inheritedSourceRel ? inheritedSourceRel.startsWith(".") ? inheritedSourceRel : `./${inheritedSourceRel}` : null;
970
+ const clientImport = opts.includeStInit ? `import { st } from "@apps/${opts.appName}/client";
971
+ void st;
972
+ ` : `import "@apps/${opts.appName}/client";
973
+ `;
974
+ const inheritedImport = inheritedSourceSpecifier ? `import * as inheritedLayout from ${JSON.stringify(inheritedSourceSpecifier)};
975
+ ` : `const inheritedLayout = {};
976
+ `;
977
+ const prefix = routePrefixForSegments(opts.boundary.segments);
978
+ const userImport = sourceSpecifier ? `import UserLayout, * as userLayout from ${JSON.stringify(sourceSpecifier)};
979
+ ` : `const UserLayout = ({ children }) => children;
980
+ const userLayout = {};
981
+ `;
982
+ const isAsyncUserLayout = opts.boundary.sourceAbsPath ? await AsyncDefaultExportDetector.detect(opts.boundary.sourceAbsPath) : false;
983
+ const userLayoutElement = "<UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>";
984
+ const layoutSignature = isAsyncUserLayout ? "export default async function GeneratedLayout" : "export default function GeneratedLayout";
985
+ const layoutBinding = isAsyncUserLayout ? ` const layout =
986
+ process.env.AKAN_PUBLIC_RENDER_ENV === "csr"
987
+ ? await UserLayout({ params, searchParams, children })
988
+ : ${userLayoutElement};
989
+ ` : "";
990
+ const layoutChild = isAsyncUserLayout ? "{layout}" : userLayoutElement;
991
+ const layoutReturn = isAsyncUserLayout ? "layout" : userLayoutElement;
992
+ const source = opts.includeSystemProvider ? `import type { LayoutProps, PageProps } from "akanjs/client";
993
+ import { loadFonts } from "akanjs/client";
994
+ import { System } from "akanjs/ui";
995
+ import { env } from "@apps/${opts.appName}/env/env.client";
996
+ import { allDictionary } from ${JSON.stringify(dictMacroSpecifier)};
997
+ ${clientImport}${inheritedImport}${userImport}
998
+ const userFonts = userLayout.fonts ?? inheritedLayout.fonts ?? [];
999
+ const defaultFonts = userFonts.filter((font) => font.default);
1000
+ if (defaultFonts.length > 1) throw new Error("[route-convention] only one default font is allowed per root layout");
1001
+ const defaultFont = defaultFonts[0];
1002
+ const defaultFontClassName = defaultFont ? (defaultFont.className ?? \`font-\${defaultFont.name}\`) : undefined;
1003
+
1004
+ export async function generateHead(props: PageProps) {
1005
+ if (userLayout.generateHead) return userLayout.generateHead(props);
1006
+ if (userLayout.head !== undefined) return userLayout.head;
1007
+ if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
1008
+ return inheritedLayout.head;
1009
+ }
1010
+
1011
+ export async function generateMetadata(props: PageProps) {
1012
+ if (userLayout.generateMetadata) return userLayout.generateMetadata(props);
1013
+ if (userLayout.metadata !== undefined) return userLayout.metadata;
1014
+ if (inheritedLayout.generateMetadata) return inheritedLayout.generateMetadata(props);
1015
+ return inheritedLayout.metadata;
1016
+ }
1017
+
1018
+ export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
1019
+ export const Error = userLayout.Error ?? inheritedLayout.Error;
1020
+ export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
1021
+
1022
+ ${layoutSignature}({ children, params, searchParams }: LayoutProps) {
1023
+ ${layoutBinding} return (
1024
+ <System.Provider
1025
+ of={GeneratedLayout as never}
1026
+ appName=${JSON.stringify(opts.appName)}
1027
+ ${prefix ? `prefix=${JSON.stringify(prefix)}
1028
+ ` : ""}params={params}
1029
+ manifest={userLayout.manifest ?? inheritedLayout.manifest}
1030
+ env={env}
1031
+ theme={userLayout.theme ?? inheritedLayout.theme}
1032
+ fonts={loadFonts(userFonts)}
1033
+ className={defaultFontClassName}
1034
+ gaTrackingId={userLayout.gaTrackingId ?? inheritedLayout.gaTrackingId}
1035
+ layoutStyle={userLayout.layoutStyle ?? inheritedLayout.layoutStyle}
1036
+ reconnect={userLayout.reconnect ?? inheritedLayout.reconnect ?? false}
1037
+ wsConnect={userLayout.wsConnect ?? inheritedLayout.wsConnect ?? true}
1038
+ allDictionary={process.env.AKAN_PUBLIC_RENDER_ENV === "ssr" ? allDictionary : undefined}
1039
+ >
1040
+ ${layoutChild}
1041
+ </System.Provider>
1042
+ );
1043
+ }
1044
+ ` : `import type { LayoutProps, PageProps } from "akanjs/client";
1045
+ ${inheritedImport}${userImport}
1046
+ export async function generateHead(props: PageProps) {
1047
+ if (userLayout.generateHead) return userLayout.generateHead(props);
1048
+ if (userLayout.head !== undefined) return userLayout.head;
1049
+ if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
1050
+ return inheritedLayout.head;
1051
+ }
1052
+
1053
+ export async function generateMetadata(props: PageProps) {
1054
+ if (userLayout.generateMetadata) return userLayout.generateMetadata(props);
1055
+ if (userLayout.metadata !== undefined) return userLayout.metadata;
1056
+ if (inheritedLayout.generateMetadata) return inheritedLayout.generateMetadata(props);
1057
+ return inheritedLayout.metadata;
1058
+ }
1059
+
1060
+ export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
1061
+ export const Error = userLayout.Error ?? inheritedLayout.Error;
1062
+ export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
1063
+
1064
+ ${layoutSignature}({ children, params, searchParams }: LayoutProps) {
1065
+ ${layoutBinding} return ${layoutReturn};
1066
+ }
1067
+ `;
1068
+ await Bun.write(absPath, source);
1069
+ return absPath;
1070
+ }
1071
+ async function resolveSsrPageEntries(opts) {
1072
+ const absPageDir = path3.resolve(opts.appCwdPath, "page");
1073
+ const hasSt = await appHasStModule(opts.appCwdPath);
1074
+ const basePaths = opts.basePaths ?? [];
1075
+ const rootSourceAbsPath = findExplicitRootLayoutAbsPath(opts.pageKeys, opts.appCwdPath);
1076
+ const rootBoundaries = findRootBoundaries(opts.pageKeys, opts.appCwdPath, basePaths);
1077
+ const rootLayoutKeys = new Set(opts.pageKeys.filter((key) => {
1078
+ const segments = getRootBoundarySegments(key);
1079
+ return segments !== null && isRootBoundarySegments(segments, basePaths);
1080
+ }));
1081
+ const base = await Promise.all(opts.pageKeys.filter((key) => !rootLayoutKeys.has(key)).map(async (key) => {
1082
+ const userAbsPath = path3.resolve(absPageDir, key);
1083
+ if (OVERRIDES_KEY_RE.test(key)) {
1084
+ const moduleAbsPath = await writeGeneratedOverridesLayoutFile({
1085
+ appCwdPath: opts.appCwdPath,
1086
+ key,
1087
+ userAbsPath
1088
+ });
1089
+ return { key, moduleAbsPath, seedAbsPaths: [userAbsPath] };
1090
+ }
1091
+ return { key, moduleAbsPath: userAbsPath };
1092
+ }));
1093
+ const generated = await Promise.all(rootBoundaries.map(async (boundary) => ({
1094
+ key: implicitRootLayoutKey(boundary.segments),
1095
+ moduleAbsPath: await writeGeneratedRootLayoutFile({
1096
+ appCwdPath: opts.appCwdPath,
1097
+ appName: opts.appName,
1098
+ boundary,
1099
+ rootSourceAbsPath,
1100
+ includeStInit: hasSt && boundary.segments.length === 0,
1101
+ includeSystemProvider: !hasAncestorRootBoundary(boundary, rootBoundaries)
1102
+ }),
1103
+ seedAbsPaths: [...new Set([boundary.sourceAbsPath, rootSourceAbsPath].filter((absPath) => absPath !== null))]
1104
+ })));
1105
+ const entries = [...base, ...generated];
1106
+ entries.sort((a, b) => a.key.localeCompare(b.key));
1107
+ return entries;
1108
+ }
1109
+ async function resolveSsrPageEntriesForApp(app, pageKeys) {
1110
+ const config = await app.getConfig();
1111
+ return resolveSsrPageEntries({ appCwdPath: app.cwdPath, appName: app.name, pageKeys, basePaths: config.basePaths });
1112
+ }
1113
+
718
1114
  // pkgs/@akanjs/devkit/linter.ts
719
1115
  import { spawn } from "child_process";
720
1116
  import { existsSync, readFileSync } from "fs";
721
- import path2 from "path";
1117
+ import path4 from "path";
722
1118
  import chalk from "chalk";
723
1119
  var parseBiomeReport = (output) => {
724
1120
  for (let start = output.indexOf("{");start !== -1; start = output.indexOf("{", start + 1)) {
@@ -775,13 +1171,13 @@ class Linter {
775
1171
  #biomeBin;
776
1172
  constructor(cwdPath) {
777
1173
  this.lintRoot = this.#findBiomeRootPath(cwdPath);
778
- this.configPath = Linter.#configPathIn(this.lintRoot) ?? path2.join(this.lintRoot, "biome.json");
779
- const localBiomeBin = path2.join(this.lintRoot, "node_modules/.bin/biome");
1174
+ this.configPath = Linter.#configPathIn(this.lintRoot) ?? path4.join(this.lintRoot, "biome.json");
1175
+ const localBiomeBin = path4.join(this.lintRoot, "node_modules/.bin/biome");
780
1176
  this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
781
1177
  }
782
1178
  static #configPathIn(dir) {
783
1179
  for (const fileName of BIOME_CONFIG_FILES) {
784
- const configPath = path2.join(dir, fileName);
1180
+ const configPath = path4.join(dir, fileName);
785
1181
  if (existsSync(configPath))
786
1182
  return configPath;
787
1183
  }
@@ -790,19 +1186,19 @@ class Linter {
790
1186
  #findBiomeRootPath(dir) {
791
1187
  if (Linter.#configPathIn(dir))
792
1188
  return dir;
793
- const parentDir = path2.dirname(dir);
1189
+ const parentDir = path4.dirname(dir);
794
1190
  if (parentDir === dir)
795
1191
  throw new Error(`biome.json not found from ${dir}`);
796
1192
  return this.#findBiomeRootPath(parentDir);
797
1193
  }
798
1194
  #toBiomePath(filePath) {
799
- const relativePath = path2.relative(this.lintRoot, filePath);
800
- if (!relativePath.startsWith("..") && !path2.isAbsolute(relativePath))
1195
+ const relativePath = path4.relative(this.lintRoot, filePath);
1196
+ if (!relativePath.startsWith("..") && !path4.isAbsolute(relativePath))
801
1197
  return relativePath;
802
1198
  return filePath;
803
1199
  }
804
1200
  #resolveFilePath(filePath) {
805
- return path2.isAbsolute(filePath) ? filePath : path2.join(this.lintRoot, filePath);
1201
+ return path4.isAbsolute(filePath) ? filePath : path4.join(this.lintRoot, filePath);
806
1202
  }
807
1203
  async#runBiome(args, input) {
808
1204
  return await new Promise((resolve, reject) => {
@@ -827,7 +1223,7 @@ class Linter {
827
1223
  const diagnosticPath = diagnostic.location?.path;
828
1224
  if (!diagnosticPath)
829
1225
  return fallbackFilePath;
830
- return path2.isAbsolute(diagnosticPath) ? diagnosticPath : path2.join(this.lintRoot, diagnosticPath);
1226
+ return path4.isAbsolute(diagnosticPath) ? diagnosticPath : path4.join(this.lintRoot, diagnosticPath);
831
1227
  }
832
1228
  #createLintMessage(diagnostic) {
833
1229
  const start = diagnostic.location?.start;
@@ -1057,7 +1453,7 @@ ${errorText}, ${warningText} found`];
1057
1453
 
1058
1454
  // pkgs/@akanjs/devkit/repoIdentity.ts
1059
1455
  import { execFileSync } from "child_process";
1060
- import path3 from "path";
1456
+ import path5 from "path";
1061
1457
  var resolved = new Map;
1062
1458
  var readRemoteName = (workspaceRoot) => {
1063
1459
  try {
@@ -1075,14 +1471,14 @@ var resolveRepoName = (workspaceRoot) => {
1075
1471
  const cached = resolved.get(workspaceRoot);
1076
1472
  if (cached)
1077
1473
  return cached;
1078
- const repoName = readRemoteName(workspaceRoot) ?? path3.basename(workspaceRoot);
1474
+ const repoName = readRemoteName(workspaceRoot) ?? path5.basename(workspaceRoot);
1079
1475
  resolved.set(workspaceRoot, repoName);
1080
1476
  return repoName;
1081
1477
  };
1082
1478
 
1083
1479
  // pkgs/@akanjs/devkit/scanInfo.ts
1084
1480
  import { rm } from "fs/promises";
1085
- import path4 from "path";
1481
+ import path6 from "path";
1086
1482
 
1087
1483
  // pkgs/@akanjs/devkit/workspaceLayout.ts
1088
1484
  var appRootAllowedFiles = new Set([
@@ -1186,16 +1582,16 @@ var moduleUiFileTypes = {
1186
1582
  scalar: new Set(["Template", "Unit"])
1187
1583
  };
1188
1584
  var testFilePattern = /\.(test|spec)\.(ts|tsx)$/;
1189
- var createDependencyScanner = async (exec) => (await import("./dependencyScanner-aqg3dkks.js")).TypeScriptDependencyScanner.from(exec);
1585
+ var createDependencyScanner = async (exec) => (await import("./dependencyScanner-c64m6fxp.js")).TypeScriptDependencyScanner.from(exec);
1190
1586
  var isAllowedTestFile = (filename) => testFilePattern.test(filename);
1191
- var getScanPath = (exec, relativePath) => path4.posix.join(`${exec.type}s`, exec.name, relativePath.split(path4.sep).join("/"));
1587
+ var getScanPath = (exec, relativePath) => path6.posix.join(`${exec.type}s`, exec.name, relativePath.split(path6.sep).join("/"));
1192
1588
  async function clearGeneratedRootCapacitorConfigs(exec) {
1193
1589
  if (exec.type !== "app")
1194
1590
  return;
1195
1591
  await Promise.all(generatedRootCapacitorConfigFiles.map((filename) => rm(exec.getPath(filename), { force: true })));
1196
1592
  }
1197
1593
  var getModuleNameFromPath = (kind, modulePath) => {
1198
- const dirname = path4.basename(modulePath);
1594
+ const dirname = path6.basename(modulePath);
1199
1595
  return kind === "service" ? dirname.replace(/^_+/, "") : dirname;
1200
1596
  };
1201
1597
  async function assertScanConvention(exec, libRoot) {
@@ -1217,18 +1613,18 @@ async function assertScanConvention(exec, libRoot) {
1217
1613
  for (const { relativePath, reason } of await exec.getPageConventionViolations())
1218
1614
  addViolation(relativePath, reason);
1219
1615
  libRoot.files.filter((filename) => !isAllowedLibFacetRootFile(filename)).forEach((filename) => {
1220
- addViolation(path4.join("lib", filename), "unsupported lib facet root file");
1616
+ addViolation(path6.join("lib", filename), "unsupported lib facet root file");
1221
1617
  });
1222
1618
  libRoot.dirs.filter((dirname) => dirname.startsWith("__") && !internalLibDirs.has(dirname)).forEach((dirname) => {
1223
- addViolation(path4.join("lib", dirname), "unsupported internal lib folder");
1619
+ addViolation(path6.join("lib", dirname), "unsupported internal lib folder");
1224
1620
  });
1225
1621
  const databaseDirs = libRoot.dirs.filter((dirname) => !dirname.startsWith("_"));
1226
1622
  const serviceDirs = libRoot.dirs.filter((dirname) => dirname.startsWith("_") && !dirname.startsWith("__"));
1227
1623
  const scalarDirs = await exec.readdir("lib/__scalar");
1228
1624
  await Promise.all([
1229
- ...databaseDirs.map((dirname) => validateModuleFiles(exec, violations, "database", path4.join("lib", dirname))),
1230
- ...serviceDirs.map((dirname) => validateModuleFiles(exec, violations, "service", path4.join("lib", dirname))),
1231
- ...scalarDirs.map((dirname) => validateModuleFiles(exec, violations, "scalar", path4.join("lib/__scalar", dirname)))
1625
+ ...databaseDirs.map((dirname) => validateModuleFiles(exec, violations, "database", path6.join("lib", dirname))),
1626
+ ...serviceDirs.map((dirname) => validateModuleFiles(exec, violations, "service", path6.join("lib", dirname))),
1627
+ ...scalarDirs.map((dirname) => validateModuleFiles(exec, violations, "scalar", path6.join("lib/__scalar", dirname)))
1232
1628
  ]);
1233
1629
  if (violations.length > 0) {
1234
1630
  throw new Error(`[scan-convention]
@@ -1240,11 +1636,11 @@ async function validateModuleFiles(exec, violations, kind, modulePath) {
1240
1636
  const { files, dirs } = await exec.getFilesAndDirs(modulePath);
1241
1637
  const moduleName = getModuleNameFromPath(kind, modulePath);
1242
1638
  dirs.forEach((dirname) => {
1243
- violations.push(`${getScanPath(exec, path4.join(modulePath, dirname))}: unsupported module folder`);
1639
+ violations.push(`${getScanPath(exec, path6.join(modulePath, dirname))}: unsupported module folder`);
1244
1640
  });
1245
1641
  const uiModuleName = moduleName[0].toUpperCase() + moduleName.slice(1);
1246
1642
  files.forEach((filename) => {
1247
- const filePath = path4.join(modulePath, filename);
1643
+ const filePath = path6.join(modulePath, filename);
1248
1644
  if (filename === "index.ts" || filename === "index.tsx" || isAllowedTestFile(filename))
1249
1645
  return;
1250
1646
  if (filename === `${moduleName}.abstract.md`)
@@ -1288,7 +1684,7 @@ class ScanInfo {
1288
1684
  { all: new Set, databases: new Set, services: new Set, scalars: new Set }
1289
1685
  ]));
1290
1686
  static async getScanResult(exec) {
1291
- const [akanConfig2, scanner, pkgs, libs] = await Promise.all([
1687
+ const [akanConfig, scanner, pkgs, libs] = await Promise.all([
1292
1688
  exec.getConfig(),
1293
1689
  createDependencyScanner(exec),
1294
1690
  exec.workspace.getPkgs(),
@@ -1324,7 +1720,7 @@ class ScanInfo {
1324
1720
  });
1325
1721
  await Promise.all([
1326
1722
  ...databaseDirs.map(async (name) => {
1327
- const filenames = await exec.readdir(path4.join("lib", name));
1723
+ const filenames = await exec.readdir(path6.join("lib", name));
1328
1724
  filenames.forEach((filename) => {
1329
1725
  if (filename.endsWith(".constant.ts"))
1330
1726
  files.constant.databases.push(name);
@@ -1352,7 +1748,7 @@ class ScanInfo {
1352
1748
  }),
1353
1749
  ...serviceDirs.map(async (dirname) => {
1354
1750
  const name = dirname.slice(1);
1355
- const filenames = await exec.readdir(path4.join("lib", dirname));
1751
+ const filenames = await exec.readdir(path6.join("lib", dirname));
1356
1752
  filenames.forEach((filename) => {
1357
1753
  if (filename.endsWith(".dictionary.ts"))
1358
1754
  files.dictionary.services.push(name);
@@ -1375,7 +1771,7 @@ class ScanInfo {
1375
1771
  });
1376
1772
  }),
1377
1773
  ...scalarDirs.map(async (name) => {
1378
- const filenames = await exec.readdir(path4.join("lib/__scalar", name));
1774
+ const filenames = await exec.readdir(path6.join("lib/__scalar", name));
1379
1775
  filenames.forEach((filename) => {
1380
1776
  if (filename.endsWith(".constant.ts"))
1381
1777
  files.constant.scalars.push(name);
@@ -1401,7 +1797,7 @@ class ScanInfo {
1401
1797
  name: exec.name,
1402
1798
  type: exec.type,
1403
1799
  repoName: exec.workspace.repoName,
1404
- serveDomain: WorkspaceExecutor.getBaseDevEnv(path4.join(exec.workspace.workspaceRoot, ".env")).serveDomain,
1800
+ serveDomain: WorkspaceExecutor.getBaseDevEnv(path6.join(exec.workspace.workspaceRoot, ".env")).serveDomain,
1405
1801
  files,
1406
1802
  libDeps,
1407
1803
  pkgDeps,
@@ -1409,7 +1805,7 @@ class ScanInfo {
1409
1805
  devDependencies: npmDevDeps.filter((dep) => !isAkanFrameworkDependency(dep)),
1410
1806
  routes
1411
1807
  };
1412
- const scanResult = akanConfig2 instanceof AkanAppConfig ? { ...common, akanConfig: akanConfig2 } : { ...common, akanConfig: akanConfig2 };
1808
+ const scanResult = akanConfig instanceof AkanAppConfig ? { ...common, akanConfig } : { ...common, akanConfig };
1413
1809
  return scanResult;
1414
1810
  }
1415
1811
  constructor(scanResult) {
@@ -1608,11 +2004,11 @@ class PkgInfo {
1608
2004
  const [tsconfig, rootPackageJson] = await Promise.all([exec.getTsConfig(), exec.workspace.getPackageJson()]);
1609
2005
  const scanner = await createDependencyScanner(exec);
1610
2006
  const npmSet = new Set(Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }));
1611
- const pkgPathSet = new Set(Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path5) => tsconfig.compilerOptions.paths?.[path5]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path5) => path5.replace("/*", "")));
2007
+ const pkgPathSet = new Set(Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path) => tsconfig.compilerOptions.paths?.[path]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path) => path.replace("/*", "")));
1612
2008
  const [npmDepSet, pkgPathDepSet] = await scanner.getImportSets([npmSet, pkgPathSet]);
1613
- const pkgDeps = [...pkgPathDepSet].map((path5) => {
1614
- const pathSplitLength = path5.split("/").length;
1615
- return (tsconfig.compilerOptions.paths?.[path5]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
2009
+ const pkgDeps = [...pkgPathDepSet].map((path) => {
2010
+ const pathSplitLength = path.split("/").length;
2011
+ return (tsconfig.compilerOptions.paths?.[path]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
1616
2012
  }).filter((pkg) => pkg !== exec.name);
1617
2013
  const pkgScanResult = {
1618
2014
  name: exec.name,
@@ -1949,10 +2345,10 @@ class Executor {
1949
2345
  });
1950
2346
  }
1951
2347
  getPath(filePath) {
1952
- if (path5.isAbsolute(filePath))
2348
+ if (path7.isAbsolute(filePath))
1953
2349
  return filePath;
1954
2350
  if (filePath.startsWith("."))
1955
- return path5.join(this.cwdPath, filePath);
2351
+ return path7.join(this.cwdPath, filePath);
1956
2352
  const baseParts = this.cwdPath.split(/[\\/]/).filter(Boolean);
1957
2353
  const targetParts = filePath.split(/[\\/]/).filter(Boolean);
1958
2354
  let overlapLength = 0;
@@ -1966,12 +2362,12 @@ class Executor {
1966
2362
  if (isOverlap)
1967
2363
  overlapLength = i;
1968
2364
  }
1969
- return path5.join(this.cwdPath, ...targetParts.slice(overlapLength));
2365
+ return path7.join(this.cwdPath, ...targetParts.slice(overlapLength));
1970
2366
  }
1971
2367
  async mkdir(dirPath) {
1972
2368
  const writePath = this.getPath(dirPath);
1973
2369
  if (!await FileSys.dirExists(writePath))
1974
- await mkdir(writePath, { recursive: true });
2370
+ await mkdir2(writePath, { recursive: true });
1975
2371
  this.logger.verbose(`Make directory ${writePath}`);
1976
2372
  return this;
1977
2373
  }
@@ -2009,7 +2405,7 @@ class Executor {
2009
2405
  return this;
2010
2406
  }
2011
2407
  async removeDir(dirPath) {
2012
- const readPath = path5.join(this.getPath(dirPath), ".");
2408
+ const readPath = path7.join(this.getPath(dirPath), ".");
2013
2409
  if (await FileSys.entryExists(readPath))
2014
2410
  await rm2(readPath, { recursive: true, force: true });
2015
2411
  this.logger.verbose(`Remove directory ${readPath}`);
@@ -2017,9 +2413,9 @@ class Executor {
2017
2413
  }
2018
2414
  async writeFile(filePath, content, { overwrite = true, silent = false } = {}) {
2019
2415
  const writePath = this.getPath(filePath);
2020
- const dir = path5.dirname(writePath);
2416
+ const dir = path7.dirname(writePath);
2021
2417
  if (!await FileSys.dirExists(dir))
2022
- await mkdir(dir, { recursive: true });
2418
+ await mkdir2(dir, { recursive: true });
2023
2419
  let contentStr = typeof content === "string" ? content : `${JSON.stringify(content, null, 2)}
2024
2420
  `;
2025
2421
  if (await FileSys.fileExists(writePath)) {
@@ -2043,7 +2439,7 @@ class Executor {
2043
2439
  await this.writeFile(filePath, content);
2044
2440
  }
2045
2441
  async getLocalFile(targetPath) {
2046
- const filePath = path5.isAbsolute(targetPath) ? targetPath : targetPath.replace(this.cwdPath, "");
2442
+ const filePath = path7.isAbsolute(targetPath) ? targetPath : targetPath.replace(this.cwdPath, "");
2047
2443
  const content = await this.readFile(filePath);
2048
2444
  return { filePath, content };
2049
2445
  }
@@ -2062,7 +2458,7 @@ class Executor {
2062
2458
  return;
2063
2459
  const isDirectory = (await stat(src)).isDirectory();
2064
2460
  if (!await FileSys.exists(dest) && isDirectory)
2065
- await mkdir(dest, { recursive: true });
2461
+ await mkdir2(dest, { recursive: true });
2066
2462
  if (dereference)
2067
2463
  await cpEntry(src, dest, { recursive: isDirectory, dereference: true, force: true });
2068
2464
  else
@@ -2140,26 +2536,26 @@ class Executor {
2140
2536
  const result = await getContent.default(scanInfo ?? null, dict, options);
2141
2537
  if (result === null)
2142
2538
  return null;
2143
- const filename = typeof result === "object" ? result.filename : path5.basename(targetPath).replace(".js", ".ts");
2539
+ const filename = typeof result === "object" ? result.filename : path7.basename(targetPath).replace(".js", ".ts");
2144
2540
  const content = typeof result === "object" ? result.content : result;
2145
- const dirname = path5.dirname(targetPath);
2146
- const convertedTargetPath = Object.entries(dict).reduce((path6, [key, value]) => path6.replace(new RegExp(`__${key}__`, "g"), value), `${dirname}/${filename}`);
2541
+ const dirname = path7.dirname(targetPath);
2542
+ const convertedTargetPath = Object.entries(dict).reduce((path, [key, value]) => path.replace(new RegExp(`__${key}__`, "g"), value), `${dirname}/${filename}`);
2147
2543
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2148
2544
  return this.writeFile(convertedTargetPath, content, { overwrite });
2149
2545
  } else if (targetPath.endsWith(".template")) {
2150
2546
  const content = await FileSys.readText(templatePath);
2151
- const convertedTargetPath = Object.entries(dict).reduce((path6, [key, value]) => path6.replace(new RegExp(`__${key}__`, "g"), value), targetPath.slice(0, -9));
2547
+ const convertedTargetPath = Object.entries(dict).reduce((path, [key, value]) => path.replace(new RegExp(`__${key}__`, "g"), value), targetPath.slice(0, -9));
2152
2548
  const convertedContent = Object.entries(dict).reduce((data, [key, value]) => data.replace(new RegExp(`<%= ${key} %>`, "g"), value), content);
2153
2549
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2154
2550
  return this.writeFile(convertedTargetPath, convertedContent, {
2155
2551
  overwrite
2156
2552
  });
2157
- } else if (staticTemplateFileExtensions.has(path5.extname(targetPath).toLowerCase())) {
2158
- const convertedTargetPath = Object.entries(dict).reduce((path6, [key, value]) => path6.replace(new RegExp(`__${key}__`, "g"), value), targetPath);
2553
+ } else if (staticTemplateFileExtensions.has(path7.extname(targetPath).toLowerCase())) {
2554
+ const convertedTargetPath = Object.entries(dict).reduce((path, [key, value]) => path.replace(new RegExp(`__${key}__`, "g"), value), targetPath);
2159
2555
  const writePath = this.getPath(convertedTargetPath);
2160
- const dirname = path5.dirname(writePath);
2556
+ const dirname = path7.dirname(writePath);
2161
2557
  if (!await FileSys.dirExists(dirname))
2162
- await mkdir(dirname, { recursive: true });
2558
+ await mkdir2(dirname, { recursive: true });
2163
2559
  await copyFile(templatePath, writePath);
2164
2560
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2165
2561
  return { filePath: writePath, content: "" };
@@ -2178,10 +2574,10 @@ class Executor {
2178
2574
  const templatePath = `${templateRoot}${template ? `/${template}` : ""}`;
2179
2575
  const prefixTemplatePath = templatePath;
2180
2576
  if ((await stat(prefixTemplatePath)).isFile()) {
2181
- const filename = path5.basename(prefixTemplatePath);
2577
+ const filename = path7.basename(prefixTemplatePath);
2182
2578
  const fileContent = await this.#applyTemplateFile({
2183
2579
  templatePath: prefixTemplatePath,
2184
- targetPath: path5.join(basePath, filename),
2580
+ targetPath: path7.join(basePath, filename),
2185
2581
  scanInfo,
2186
2582
  overwrite
2187
2583
  }, dict, options);
@@ -2189,19 +2585,19 @@ class Executor {
2189
2585
  } else {
2190
2586
  const subdirs = await readDirEntries(templatePath);
2191
2587
  const fileContents = (await Promise.all(subdirs.map(async (subdir) => {
2192
- const subpath = path5.join(templatePath, subdir);
2588
+ const subpath = path7.join(templatePath, subdir);
2193
2589
  if ((await stat(subpath)).isFile()) {
2194
2590
  const fileContent = await this.#applyTemplateFile({
2195
2591
  templatePath: subpath,
2196
- targetPath: path5.join(basePath, subdir),
2592
+ targetPath: path7.join(basePath, subdir),
2197
2593
  scanInfo,
2198
2594
  overwrite
2199
2595
  }, dict, options);
2200
2596
  return fileContent ? [fileContent] : [];
2201
2597
  } else
2202
2598
  return await this._applyTemplate({
2203
- basePath: path5.join(basePath, subdir),
2204
- template: path5.join(template, subdir),
2599
+ basePath: path7.join(basePath, subdir),
2600
+ template: path7.join(template, subdir),
2205
2601
  scanInfo,
2206
2602
  dict,
2207
2603
  overwrite,
@@ -2213,8 +2609,8 @@ class Executor {
2213
2609
  }
2214
2610
  async#resolveTemplateRoot() {
2215
2611
  const candidates = [
2216
- path5.resolve(getDirname(import.meta.url), "templates"),
2217
- path5.resolve(getDirname(import.meta.url), "../cli/templates")
2612
+ path7.resolve(getDirname2(import.meta.url), "templates"),
2613
+ path7.resolve(getDirname2(import.meta.url), "../cli/templates")
2218
2614
  ];
2219
2615
  for (const candidate of candidates) {
2220
2616
  if (await FileSys.dirExists(candidate))
@@ -2244,26 +2640,26 @@ class Executor {
2244
2640
  }
2245
2641
  }
2246
2642
  async getTypeChecker() {
2247
- const { TypeChecker } = await import("./typeChecker-yhs4eht8.js");
2643
+ const { TypeChecker } = await import("./typeChecker-3xgrzc2v.js");
2248
2644
  this.typeChecker ??= new TypeChecker(this);
2249
2645
  return this.typeChecker;
2250
2646
  }
2251
2647
  async typeCheck(filePath) {
2252
- const path6 = this.getPath(filePath);
2648
+ const path = this.getPath(filePath);
2253
2649
  const typeChecker = await this.getTypeChecker();
2254
- const { fileDiagnostics, fileErrors, fileWarnings } = typeChecker.check(path6);
2650
+ const { fileDiagnostics, fileErrors, fileWarnings } = typeChecker.check(path);
2255
2651
  const message = typeChecker.formatDiagnostics(fileDiagnostics);
2256
2652
  return { fileDiagnostics, fileErrors, fileWarnings, message };
2257
2653
  }
2258
2654
  async typeCheckAsync(filePath) {
2259
- const path6 = this.getPath(filePath);
2655
+ const path = this.getPath(filePath);
2260
2656
  const entry = await this.#resolveTypecheckWorkerEntry();
2261
2657
  const proc = Bun.spawn([process.execPath, entry], {
2262
2658
  cwd: this.cwdPath,
2263
2659
  env: {
2264
2660
  ...process.env,
2265
2661
  AKAN_TYPECHECK_CWD: this.cwdPath,
2266
- AKAN_TYPECHECK_FILE: path6
2662
+ AKAN_TYPECHECK_FILE: path
2267
2663
  },
2268
2664
  stdout: "pipe",
2269
2665
  stderr: "pipe"
@@ -2284,13 +2680,13 @@ class Executor {
2284
2680
  };
2285
2681
  }
2286
2682
  async#resolveTypecheckWorkerEntry() {
2287
- const dirname = getDirname(import.meta.url);
2683
+ const dirname = getDirname2(import.meta.url);
2288
2684
  const candidates = [
2289
- path5.join(process.cwd(), "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
2290
- path5.join(process.cwd(), "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
2291
- path5.join(dirname, "typecheck/typecheck.proc.ts"),
2292
- path5.join(dirname, "typecheck.proc.js"),
2293
- path5.join(dirname, "typecheck.proc.ts")
2685
+ path7.join(process.cwd(), "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
2686
+ path7.join(process.cwd(), "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
2687
+ path7.join(dirname, "typecheck/typecheck.proc.ts"),
2688
+ path7.join(dirname, "typecheck.proc.js"),
2689
+ path7.join(dirname, "typecheck.proc.ts")
2294
2690
  ];
2295
2691
  for (const candidate of candidates)
2296
2692
  if (await Bun.file(candidate).exists())
@@ -2302,9 +2698,9 @@ class Executor {
2302
2698
  return this.linter;
2303
2699
  }
2304
2700
  async lint(filePath, { fix = false, dryRun = false } = {}) {
2305
- const path6 = this.getPath(filePath);
2701
+ const path = this.getPath(filePath);
2306
2702
  const linter = this.getLinter();
2307
- const { results, errors, warnings } = await linter.lint(path6, {
2703
+ const { results, errors, warnings } = await linter.lint(path, {
2308
2704
  fix,
2309
2705
  dryRun
2310
2706
  });
@@ -2417,7 +2813,7 @@ class WorkspaceExecutor extends Executor {
2417
2813
  await Promise.all(dirs.map(async (dir) => {
2418
2814
  if (dir.includes("_") || AVOID_DIRS.includes(dir))
2419
2815
  return;
2420
- const dirPath = path5.join(dirname, dir);
2816
+ const dirPath = path7.join(dirname, dir);
2421
2817
  if ((await stat(dirPath)).isDirectory()) {
2422
2818
  results.push(`${prefix}${dir}`);
2423
2819
  if (maxDepth > 0)
@@ -2452,9 +2848,9 @@ class WorkspaceExecutor extends Executor {
2452
2848
  await Promise.all(dirs.map(async (dir) => {
2453
2849
  if (AVOID_DIRS.includes(dir))
2454
2850
  return;
2455
- const dirPath = path5.join(dirname, dir);
2851
+ const dirPath = path7.join(dirname, dir);
2456
2852
  if (await FileSys.dirExists(dirPath)) {
2457
- const hasTargetFile = await FileSys.fileExists(path5.join(dirPath, targetFilename));
2853
+ const hasTargetFile = await FileSys.fileExists(path7.join(dirPath, targetFilename));
2458
2854
  if (hasTargetFile)
2459
2855
  results.push(`${prefix}${dir}`);
2460
2856
  if (maxDepth > 0)
@@ -2520,15 +2916,15 @@ class SysExecutor extends Executor {
2520
2916
  return this.#akanConfig;
2521
2917
  }
2522
2918
  async getModules() {
2523
- const path6 = this.type === "app" ? `apps/${this.name}/lib` : `libs/${this.name}/lib`;
2524
- return await this.workspace.getDirInModule(path6, this.name);
2919
+ const path = this.type === "app" ? `apps/${this.name}/lib` : `libs/${this.name}/lib`;
2920
+ return await this.workspace.getDirInModule(path, this.name);
2525
2921
  }
2526
2922
  async getPageConventionViolations() {
2527
2923
  if (!await this.exists("page"))
2528
2924
  return [];
2529
2925
  const violations = [];
2530
2926
  for (const entry of await this.getAllFiles("**/*", { cwd: this.getPath("page") })) {
2531
- const relativePath = entry.split(path5.sep).join("/");
2927
+ const relativePath = entry.split(path7.sep).join("/");
2532
2928
  const reason = getPageSourceFileViolation(relativePath);
2533
2929
  if (reason)
2534
2930
  violations.push({ relativePath: `page/${relativePath}`, reason });
@@ -2637,7 +3033,7 @@ class SysExecutor extends Executor {
2637
3033
  await this.setPackageJson(libPkgJsonWithDeps);
2638
3034
  }
2639
3035
  async getLocalFile(targetPath) {
2640
- const filePath = path5.isAbsolute(targetPath) ? targetPath : `${this.type}s/${this.name}/${targetPath}`;
3036
+ const filePath = path7.isAbsolute(targetPath) ? targetPath : `${this.type}s/${this.name}/${targetPath}`;
2641
3037
  const content = await this.workspace.readFile(filePath);
2642
3038
  return { filePath, content };
2643
3039
  }
@@ -2723,7 +3119,7 @@ class SysExecutor extends Executor {
2723
3119
  class AppExecutor extends SysExecutor {
2724
3120
  static #routeSourceValidator = null;
2725
3121
  static async#getRouteSourceValidator() {
2726
- AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-7fycdqyv.js")).RouteSourceValidator;
3122
+ AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-ze6x894c.js")).RouteSourceValidator;
2727
3123
  return AppExecutor.#routeSourceValidator;
2728
3124
  }
2729
3125
  dist;
@@ -2734,9 +3130,9 @@ class AppExecutor extends SysExecutor {
2734
3130
  }
2735
3131
  static #execs = new Map;
2736
3132
  static from(executor, name) {
2737
- const exec2 = AppExecutor.#execs.get(name);
2738
- if (exec2)
2739
- return exec2;
3133
+ const exec = AppExecutor.#execs.get(name);
3134
+ if (exec)
3135
+ return exec;
2740
3136
  else if (executor instanceof WorkspaceExecutor)
2741
3137
  return new AppExecutor({ workspace: executor, name });
2742
3138
  else
@@ -2772,10 +3168,10 @@ class AppExecutor extends SysExecutor {
2772
3168
  };
2773
3169
  }
2774
3170
  async prepareCommand(type) {
2775
- const akanConfig2 = await this.getConfig();
2776
- const databaseMode = process.env.AKAN_DATABASE_MODE ?? akanConfig2.defaultDatabaseMode ?? "single";
3171
+ const akanConfig = await this.getConfig();
3172
+ const databaseMode = process.env.AKAN_DATABASE_MODE ?? akanConfig.defaultDatabaseMode ?? "single";
2777
3173
  const routeEnv = {
2778
- AKAN_PUBLIC_BASE_PATHS: [...akanConfig2.basePaths].join(","),
3174
+ AKAN_PUBLIC_BASE_PATHS: [...akanConfig.basePaths].join(","),
2779
3175
  AKAN_DATABASE_MODE: databaseMode
2780
3176
  };
2781
3177
  Object.assign(process.env, routeEnv);
@@ -2786,12 +3182,12 @@ class AppExecutor extends SysExecutor {
2786
3182
  await Promise.all([this.dist.mkdir("private"), this.dist.mkdir("public")]);
2787
3183
  await Promise.all([
2788
3184
  this.cp("private", `${this.dist.cwdPath}/private`, { dereference: true }),
2789
- ...akanConfig2.web.ssr ? [this.cp("public", `${this.dist.cwdPath}/public`, { dereference: true })] : []
3185
+ ...akanConfig.web.ssr ? [this.cp("public", `${this.dist.cwdPath}/public`, { dereference: true })] : []
2790
3186
  ]);
2791
3187
  } else {
2792
3188
  await this.removeDir(".akan");
2793
- if (!akanConfig2.web.ssr || !akanConfig2.web.csr)
2794
- this.logger.verbose(`akan.config.ts disables web.${!akanConfig2.web.ssr ? "ssr" : "csr"}; \`akan start\` still serves it, \`akan build\` will not`);
3189
+ if (!akanConfig.web.ssr || !akanConfig.web.csr)
3190
+ this.logger.verbose(`akan.config.ts disables web.${!akanConfig.web.ssr ? "ssr" : "csr"}; \`akan start\` still serves it, \`akan build\` will not`);
2795
3191
  }
2796
3192
  if (type === "start")
2797
3193
  process.env.NODE_ENV = "development";
@@ -2842,7 +3238,7 @@ class AppExecutor extends SysExecutor {
2842
3238
  async getPageKeys({ refresh } = {}) {
2843
3239
  if (this.#pageKeys && !refresh)
2844
3240
  return this.#pageKeys;
2845
- const akanConfig2 = await this.getConfig();
3241
+ const akanConfig = await this.getConfig();
2846
3242
  const glob = new Bun.Glob("**/*");
2847
3243
  const pageKeys = [];
2848
3244
  const owners = new Map;
@@ -2856,16 +3252,16 @@ class AppExecutor extends SysExecutor {
2856
3252
  absolute: false,
2857
3253
  onlyFiles: true
2858
3254
  })) {
2859
- const segments = rel.split(path5.sep);
3255
+ const segments = rel.split(path7.sep);
2860
3256
  if (segments.some((s) => s === "node_modules"))
2861
3257
  continue;
2862
3258
  const posix = `${root.keyPrefix}${segments.join("/")}`;
2863
- const absPath = path5.join(root.dir, ...segments);
3259
+ const absPath = path7.join(root.dir, ...segments);
2864
3260
  validatePageSourceFile(posix, { filePath: absPath });
2865
3261
  if (!isRouteSourceFile(posix))
2866
3262
  continue;
2867
3263
  const key = `./${posix}`;
2868
- validateSubRoutePageKey(key, akanConfig2.basePaths, {
3264
+ validateSubRoutePageKey(key, akanConfig.basePaths, {
2869
3265
  appName: this.name,
2870
3266
  filePath: absPath
2871
3267
  });
@@ -2884,7 +3280,7 @@ class AppExecutor extends SysExecutor {
2884
3280
  if (!owner)
2885
3281
  owners.set(routeId, { absPath, fromLib });
2886
3282
  const layoutSegments = getRootBoundarySegments(key);
2887
- const isRootLayout = layoutSegments !== null && isRootBoundarySegments(layoutSegments, akanConfig2.basePaths);
3283
+ const isRootLayout = layoutSegments !== null && isRootBoundarySegments(layoutSegments, akanConfig.basePaths);
2888
3284
  const routeSource = await Bun.file(absPath).text();
2889
3285
  const validator = await AppExecutor.#getRouteSourceValidator();
2890
3286
  if (parsed.kind === "overrides")
@@ -2915,10 +3311,10 @@ class AppExecutor extends SysExecutor {
2915
3311
  return pageKeys.filter((key) => !isDevOnly(key));
2916
3312
  }
2917
3313
  async getPageRoots() {
2918
- const akanConfig2 = await this.getConfig();
3314
+ const akanConfig = await this.getConfig();
2919
3315
  const pageDir = `${this.cwdPath}/page`;
2920
3316
  const roots = [{ dir: pageDir, realDir: pageDir, keyPrefix: "" }];
2921
- for (const parent of AppExecutor.#pageLibParents(akanConfig2.basePaths)) {
3317
+ for (const parent of AppExecutor.#pageLibParents(akanConfig.basePaths)) {
2922
3318
  const libsDir = `${pageDir}/${parent}${AppExecutor.#pageLibsDir}`;
2923
3319
  const entries = await readDirEntries(libsDir).catch(() => []);
2924
3320
  for (const entry of entries.sort()) {
@@ -2939,9 +3335,9 @@ class AppExecutor extends SysExecutor {
2939
3335
  return parents.length ? parents : [""];
2940
3336
  }
2941
3337
  async syncPages(libDeps) {
2942
- const akanConfig2 = await this.getConfig();
2943
- const parents = AppExecutor.#pageLibParents(akanConfig2.basePaths);
2944
- const libs = await this.#resolvePageLibs(akanConfig2.syncPageLibs, libDeps);
3338
+ const akanConfig = await this.getConfig();
3339
+ const parents = AppExecutor.#pageLibParents(akanConfig.basePaths);
3340
+ const libs = await this.#resolvePageLibs(akanConfig.syncPageLibs, libDeps);
2945
3341
  const linked = (await Promise.all(parents.map(async (parent) => {
2946
3342
  const libsDir = `${this.cwdPath}/page/${parent}${AppExecutor.#pageLibsDir}`;
2947
3343
  const entries = await readDirEntries(libsDir).catch(() => []);
@@ -2999,12 +3395,12 @@ class AppExecutor extends SysExecutor {
2999
3395
  static async#linkLibAsset(targetPath, linkPath) {
3000
3396
  const isWindows = process.platform === "win32";
3001
3397
  try {
3002
- const target = isWindows ? targetPath : path5.relative(path5.dirname(linkPath), targetPath);
3398
+ const target = isWindows ? targetPath : path7.relative(path7.dirname(linkPath), targetPath);
3003
3399
  await symlink(target, linkPath, isWindows ? "junction" : "dir");
3004
3400
  } catch (error) {
3005
3401
  if (!isWindows)
3006
3402
  throw error;
3007
- await mkdir(linkPath, { recursive: true });
3403
+ await mkdir2(linkPath, { recursive: true });
3008
3404
  await cpEntry(targetPath, linkPath, { recursive: true, dereference: true, force: true });
3009
3405
  }
3010
3406
  }
@@ -3041,7 +3437,7 @@ class AppExecutor extends SysExecutor {
3041
3437
  await this.writeFile(rel, content, opts);
3042
3438
  },
3043
3439
  readEnvClient: async () => {
3044
- const envClientPath = path5.join(this.cwdPath, "env", "env.client.ts");
3440
+ const envClientPath = path7.join(this.cwdPath, "env", "env.client.ts");
3045
3441
  if (!await FileSys.fileExists(envClientPath))
3046
3442
  return null;
3047
3443
  try {
@@ -3100,9 +3496,9 @@ class LibExecutor extends SysExecutor {
3100
3496
  }
3101
3497
  static #execs = new Map;
3102
3498
  static from(executor, name) {
3103
- const exec2 = LibExecutor.#execs.get(name);
3104
- if (exec2)
3105
- return exec2;
3499
+ const exec = LibExecutor.#execs.get(name);
3500
+ if (exec)
3501
+ return exec;
3106
3502
  else if (executor instanceof WorkspaceExecutor)
3107
3503
  return new LibExecutor({ workspace: executor, name });
3108
3504
  else
@@ -3151,7 +3547,7 @@ class PkgExecutor extends Executor {
3151
3547
  return rootVersion;
3152
3548
  try {
3153
3549
  const packageJsonPath = `pkgs/${dep}/package.json`;
3154
- if (!await Bun.file(path5.join(this.workspace.workspaceRoot, packageJsonPath)).exists())
3550
+ if (!await Bun.file(path7.join(this.workspace.workspaceRoot, packageJsonPath)).exists())
3155
3551
  return;
3156
3552
  const packageJson = await this.workspace.readJson(packageJsonPath);
3157
3553
  if (packageJson.name === dep)
@@ -3252,4 +3648,4 @@ class ModuleExecutor extends Executor {
3252
3648
  }
3253
3649
  }
3254
3650
 
3255
- export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, isScannedRootEntry, AppInfo, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
3651
+ export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, AsyncDefaultExportDetector, resolveSsrPageEntriesForApp, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, isScannedRootEntry, AppInfo, Spinner, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };