@akanjs/cli 3.0.0-alpha.88 → 3.0.0-alpha.89

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 (58) hide show
  1. package/.build-stamp +1 -1
  2. package/{abstractCompactor-pwc6d6yk.js → abstractCompactor-cefxzggj.js} +2 -2
  3. package/{agent.command-180hh0ye.js → agent.command-r93wmq7m.js} +6 -6
  4. package/{application.command-v8dywdqh.js → application.command-5nqfqgdn.js} +9 -8
  5. package/{applicationBuildRunner-27wyznpv.js → applicationBuildRunner-b21m07fs.js} +4 -3
  6. package/{applicationReleasePackager-ktjt0erc.js → applicationReleasePackager-3wh58n2m.js} +2 -2
  7. package/buildBatch.proc.js +4 -4
  8. package/{capacitorApp-kwa67kzs.js → capacitorApp-gzcx6txb.js} +3 -3
  9. package/{cloud.command-12k4wy4x.js → cloud.command-g0pk0k60.js} +11 -11
  10. package/{context.command-dk2m2sjx.js → context.command-qd8kqrnh.js} +14 -14
  11. package/{dependencyScanner-c64m6fxp.js → dependencyScanner-shs82ynp.js} +2 -2
  12. package/devTui-2xf0meaq.js +552 -0
  13. package/devTuiView-7jy8f30g.js +9 -0
  14. package/{guideline.command-w6ddv13r.js → guideline.command-f38x8jhw.js} +4 -4
  15. package/guidelines/agentRule/agentRule.instruction.md +9 -1
  16. package/guidelines/conventions/conventions.instruction.md +30 -0
  17. package/guidelines/modelStore/modelStore.instruction.md +12 -0
  18. package/guidelines/modelTemplate/modelTemplate.instruction.md +5 -0
  19. package/guidelines/runtimeRule/runtimeRule.instruction.md +37 -0
  20. package/incrementalBuilder.proc.js +8 -5
  21. package/{index-5y7qba1c.js → index-0emb9eat.js} +3 -3
  22. package/{index-cd5x18qh.js → index-3vvbv974.js} +4 -4
  23. package/{index-v0s24t8j.js → index-5xdqxbn9.js} +3 -3
  24. package/{index-k86zc21w.js → index-9bwhxrqf.js} +6 -6
  25. package/{index-ft1sfjz0.js → index-cezy7yb3.js} +66 -7
  26. package/{index-a6c5pc4p.js → index-d61rcfa2.js} +614 -62
  27. package/{index-gz0c482j.js → index-deekbtkj.js} +6 -6
  28. package/{index-saheq2bs.js → index-e82dyeqy.js} +1 -1
  29. package/{index-j9vnq8tr.js → index-h759vjfa.js} +3 -3
  30. package/{index-z3c9mmw4.js → index-jydtyzva.js} +2 -2
  31. package/{index-mfm35dhh.js → index-kcxmv48c.js} +1 -1
  32. package/{index-6c3ex9qw.js → index-kfnr6c19.js} +4 -4
  33. package/{index-1kzsn94d.js → index-mpmyqm1y.js} +1 -1
  34. package/{index-wet2ytnr.js → index-n85fer99.js} +2 -2
  35. package/{index-b2nt0w0k.js → index-pgsswppj.js} +1 -1
  36. package/{index-m9c7k0gm.js → index-pvb4vdwr.js} +1 -1
  37. package/{index-ayy5ecax.js → index-q0y2jq9j.js} +13 -1
  38. package/{index-k1n0h7dk.js → index-q8sn827n.js} +254 -126
  39. package/{index-dq6wq1tv.js → index-r50qen0z.js} +10 -10
  40. package/{index-5n0hf8r9.js → index-rntcdss1.js} +3 -3
  41. package/{index-a8h184wr.js → index-sjak5v5b.js} +6 -6
  42. package/{index-x23688ar.js → index-w8kmx1b6.js} +8 -4
  43. package/{index-qcracvc9.js → index-y74k5anj.js} +3 -3
  44. package/{index-xxe90kqy.js → index-zkvpaggp.js} +2 -2
  45. package/index.js +20 -20
  46. package/{library.command-wpedct6c.js → library.command-em103wtn.js} +4 -4
  47. package/{localRegistry.command-3cew8f75.js → localRegistry.command-gz8apn4y.js} +10 -10
  48. package/{module.command-8n4kct3e.js → module.command-451pztkc.js} +7 -7
  49. package/{package.command-fcbd0b1d.js → package.command-rfhyf38t.js} +5 -5
  50. package/package.json +2 -2
  51. package/{page.command-x4379grq.js → page.command-kt19da5g.js} +4 -4
  52. package/{primitive.command-8etmnqhq.js → primitive.command-pgy69ere.js} +8 -8
  53. package/{quality.command-hfx7z8yr.js → quality.command-gpe2vqb5.js} +3 -3
  54. package/{repair.command-j0fs5qkz.js → repair.command-2sbrz187.js} +6 -6
  55. package/{scalar.command-2emk89eh.js → scalar.command-jcf4e5sv.js} +6 -6
  56. package/{subspace.command-nr32nm35.js → subspace.command-kqzqtk0p.js} +6 -6
  57. package/{workflow.command-cvpmzwjg.js → workflow.command-m4z25a2p.js} +11 -11
  58. package/{workspace.command-rqnms515.js → workspace.command-dqgj9zbk.js} +22 -22
@@ -1,11 +1,126 @@
1
1
  // @bun
2
2
  import {
3
3
  FileSys
4
- } from "./index-ayy5ecax.js";
4
+ } from "./index-q0y2jq9j.js";
5
5
  import {
6
6
  getDirname2
7
7
  } from "./index-6wwzs1bc.js";
8
8
 
9
+ // pkgs/@akanjs/devkit/codegenLock.ts
10
+ import { mkdir, open, readFile, rm, stat } from "fs/promises";
11
+ import path from "path";
12
+ import { Logger } from "akanjs/common";
13
+
14
+ class CodegenLock {
15
+ static fileName = "codegen.lock";
16
+ static waitTimeoutMs = 1e4;
17
+ static unknownHolderStaleMs = 60000;
18
+ static #pollMs = 25;
19
+ static #logger = new Logger("CodegenLock");
20
+ static #queue = Promise.resolve();
21
+ static pathIn(workspaceRoot) {
22
+ return path.join(workspaceRoot, "local", ".akan", CodegenLock.fileName);
23
+ }
24
+ static async run(workspaceRoot, label, fn) {
25
+ const ahead = CodegenLock.#queue;
26
+ let done;
27
+ CodegenLock.#queue = new Promise((resolve) => {
28
+ done = resolve;
29
+ });
30
+ try {
31
+ await CodegenLock.#waitForQueue(ahead, label);
32
+ return await CodegenLock.#withFileLock(workspaceRoot, label, fn);
33
+ } finally {
34
+ done();
35
+ }
36
+ }
37
+ static async#waitForQueue(ahead, label) {
38
+ let timer = null;
39
+ const expired = new Promise((resolve) => {
40
+ timer = setTimeout(() => resolve("expired"), CodegenLock.waitTimeoutMs);
41
+ });
42
+ try {
43
+ if (await Promise.race([ahead.then(() => "done"), expired]) === "expired")
44
+ CodegenLock.#logger.warn(`codegen lock queued past ${CodegenLock.waitTimeoutMs}ms in this process; continuing without waiting (${label})`);
45
+ } finally {
46
+ if (timer)
47
+ clearTimeout(timer);
48
+ }
49
+ }
50
+ static async#withFileLock(workspaceRoot, label, fn) {
51
+ const lockPath = CodegenLock.pathIn(workspaceRoot);
52
+ await mkdir(path.dirname(lockPath), { recursive: true }).catch(() => {
53
+ return;
54
+ });
55
+ const held = await CodegenLock.#acquire(lockPath, label);
56
+ try {
57
+ return await fn();
58
+ } finally {
59
+ if (held)
60
+ await rm(lockPath, { force: true }).catch(() => {
61
+ return;
62
+ });
63
+ }
64
+ }
65
+ static async#acquire(lockPath, label) {
66
+ const deadline = Date.now() + CodegenLock.waitTimeoutMs;
67
+ for (;; ) {
68
+ const handle = await open(lockPath, "wx").catch(() => null);
69
+ if (handle) {
70
+ await handle.writeFile(JSON.stringify({ pid: process.pid, at: Date.now(), label })).catch(() => {
71
+ return;
72
+ });
73
+ await handle.close().catch(() => {
74
+ return;
75
+ });
76
+ return true;
77
+ }
78
+ if (await CodegenLock.#reclaimIfAbandoned(lockPath))
79
+ continue;
80
+ if (Date.now() >= deadline) {
81
+ CodegenLock.#logger.warn(`codegen lock at ${lockPath} held past ${CodegenLock.waitTimeoutMs}ms; continuing without it (${label})`);
82
+ return false;
83
+ }
84
+ await Bun.sleep(CodegenLock.#pollMs);
85
+ }
86
+ }
87
+ static async#reclaimIfAbandoned(lockPath) {
88
+ const info = await stat(lockPath).catch(() => null);
89
+ if (!info)
90
+ return true;
91
+ const holder = CodegenLock.#parseHolder(await readFile(lockPath, "utf8").catch(() => ""));
92
+ if (holder) {
93
+ if (CodegenLock.#isAlive(holder.pid))
94
+ return false;
95
+ } else if (Date.now() - info.mtimeMs < CodegenLock.unknownHolderStaleMs)
96
+ return false;
97
+ await rm(lockPath, { force: true }).catch(() => {
98
+ return;
99
+ });
100
+ return true;
101
+ }
102
+ static #parseHolder(raw) {
103
+ try {
104
+ const parsed = JSON.parse(raw);
105
+ if (typeof parsed.pid !== "number" || typeof parsed.at !== "number")
106
+ return null;
107
+ return { pid: parsed.pid, at: parsed.at, label: typeof parsed.label === "string" ? parsed.label : "" };
108
+ } catch {
109
+ return null;
110
+ }
111
+ }
112
+ static #isAlive(pid) {
113
+ if (!Number.isInteger(pid) || pid <= 0)
114
+ return false;
115
+ try {
116
+ process.kill(pid, 0);
117
+ return true;
118
+ } catch (error) {
119
+ return error.code === "EPERM";
120
+ }
121
+ }
122
+ }
123
+
9
124
  // pkgs/@akanjs/devkit/spinner.ts
10
125
  import ora from "ora";
11
126
 
@@ -80,20 +195,20 @@ import { readFileSync as readFileSync2 } from "fs";
80
195
  import {
81
196
  copyFile,
82
197
  cp as cpEntry,
83
- mkdir as mkdir2,
198
+ mkdir as mkdir3,
84
199
  readdir as readDirEntries,
85
200
  realpath,
86
- rm as rm2,
87
- stat,
201
+ rm as rm3,
202
+ stat as stat2,
88
203
  symlink
89
204
  } from "fs/promises";
90
- import path7 from "path";
205
+ import path8 from "path";
91
206
  import { pathToFileURL } from "url";
92
207
  import {
93
208
  capitalize,
94
209
  getPageSourceFileViolation,
95
210
  isRouteSourceFile,
96
- Logger,
211
+ Logger as Logger2,
97
212
  parseRouteModuleKey,
98
213
  validatePageSourceFile,
99
214
  validateSubRoutePageKey
@@ -241,8 +356,9 @@ ${CLAUDE_COMMENT_RULE}
241
356
 
242
357
  // pkgs/@akanjs/devkit/akanConfig/akanConfig.ts
243
358
  import fs from "fs";
244
- import path from "path";
359
+ import path2 from "path";
245
360
  import { fileURLToPath } from "url";
361
+ import { normalizeRoutePrefix } from "akanjs/base";
246
362
  import { resolveAkanI18nConfig } from "akanjs/common";
247
363
 
248
364
  // pkgs/@akanjs/devkit/akanConfig/types.ts
@@ -329,8 +445,8 @@ var normalizeIndexPath = (indexPath) => {
329
445
  const normalized = indexPath?.trim();
330
446
  if (!normalized)
331
447
  return;
332
- const path2 = `/${normalized.replace(/^\/+|\/+$/g, "")}`;
333
- return path2 === "/" ? "/" : path2;
448
+ const path = `/${normalized.replace(/^\/+|\/+$/g, "")}`;
449
+ return path === "/" ? "/" : path;
334
450
  };
335
451
  var normalizeStringList = (values) => {
336
452
  const normalized = values?.map((value) => value.trim()).filter(Boolean) ?? [];
@@ -397,6 +513,7 @@ class AkanAppConfig {
397
513
  optimizeImports;
398
514
  images;
399
515
  i18n;
516
+ api;
400
517
  publicEnv;
401
518
  mobile;
402
519
  hasMobileConfig;
@@ -430,6 +547,12 @@ class AkanAppConfig {
430
547
  this.i18n = resolveAkanI18nConfig(config?.i18n);
431
548
  process.env.AKAN_PUBLIC_DEFAULT_LOCALE = this.i18n.defaultLocale;
432
549
  process.env.AKAN_PUBLIC_LOCALES = this.i18n.locales.join(",");
550
+ this.api = {
551
+ prefix: normalizeRoutePrefix(config?.api?.prefix) ?? "/api",
552
+ websocketPrefix: normalizeRoutePrefix(config?.api?.websocketPrefix) ?? "/ws"
553
+ };
554
+ process.env.AKAN_PUBLIC_API_PREFIX = this.api.prefix;
555
+ process.env.AKAN_PUBLIC_WS_PREFIX = this.api.websocketPrefix;
433
556
  this.publicEnv = config?.publicEnv ?? [];
434
557
  this.secrets = config?.secrets ?? [];
435
558
  this.assets = {
@@ -604,6 +727,8 @@ ENV AKAN_PUBLIC_ENV=${this.baseDevEnv.env}
604
727
  ${this.basePaths.size ? `ENV AKAN_PUBLIC_BASE_PATHS=${[...this.basePaths].join(",")}` : ""}
605
728
  ENV AKAN_PUBLIC_DEFAULT_LOCALE=${this.i18n.defaultLocale}
606
729
  ENV AKAN_PUBLIC_LOCALES=${this.i18n.locales.join(",")}
730
+ ENV AKAN_PUBLIC_API_PREFIX=${this.api.prefix}
731
+ ENV AKAN_PUBLIC_WS_PREFIX=${this.api.websocketPrefix}
607
732
  ENV AKAN_PUBLIC_OPERATION_MODE=cloud
608
733
  ENV AKAN_LOG_TO_FILE=0
609
734
  ${webEnvLines}
@@ -618,7 +743,7 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
618
743
  static async from(app, { bustImportCache = false } = {}) {
619
744
  const [configImp, baseDevEnv, libs, rootPackageJson] = await Promise.all([
620
745
  AkanAppConfig.importConfigModule(app.cwdPath, { bustImportCache }),
621
- WorkspaceExecutor.getBaseDevEnv(path.join(app.workspace.workspaceRoot, ".env")),
746
+ WorkspaceExecutor.getBaseDevEnv(path2.join(app.workspace.workspaceRoot, ".env")),
622
747
  app.workspace.getLibs(),
623
748
  app.workspace.getPackageJson()
624
749
  ]);
@@ -698,11 +823,11 @@ var akanPackageJson = null;
698
823
  function getAkanPackageJson() {
699
824
  if (akanPackageJson)
700
825
  return akanPackageJson;
701
- const sourceDir = path.dirname(fileURLToPath(import.meta.url));
826
+ const sourceDir = path2.dirname(fileURLToPath(import.meta.url));
702
827
  const packageJsonPaths = [
703
- path.join(sourceDir, "../../../akanjs/package.json"),
704
- path.join(process.cwd(), "pkgs/akanjs/package.json"),
705
- path.join(path.dirname(Bun.main), "node_modules/akanjs/package.json")
828
+ path2.join(sourceDir, "../../../akanjs/package.json"),
829
+ path2.join(process.cwd(), "pkgs/akanjs/package.json"),
830
+ path2.join(path2.dirname(Bun.main), "node_modules/akanjs/package.json")
706
831
  ];
707
832
  try {
708
833
  packageJsonPaths.unshift(Bun.resolveSync("akanjs/package.json", sourceDir));
@@ -757,25 +882,25 @@ class AkanLibConfig {
757
882
  //! need to refactor
758
883
  var increaseBuildNum = async (app) => {
759
884
  const appConfig = await AkanAppConfig.from(app);
760
- const akanConfigPath = path.join(app.cwdPath, "akan.config.ts");
885
+ const akanConfigPath = path2.join(app.cwdPath, "akan.config.ts");
761
886
  const akanConfig = fs.readFileSync(akanConfigPath, "utf8");
762
887
  const akanConfigContent = akanConfig.replace(`buildNum: ${appConfig.mobile.buildNum}`, `buildNum: ${appConfig.mobile.buildNum + 1}`);
763
888
  fs.writeFileSync(akanConfigPath, akanConfigContent);
764
889
  };
765
890
  var decreaseBuildNum = async (app) => {
766
891
  const appConfig = await AkanAppConfig.from(app);
767
- const akanConfigPath = path.join(app.cwdPath, "akan.config.ts");
892
+ const akanConfigPath = path2.join(app.cwdPath, "akan.config.ts");
768
893
  const akanConfig = fs.readFileSync(akanConfigPath, "utf8");
769
894
  const akanConfigContent = akanConfig.replace(`buildNum: ${appConfig.mobile.buildNum}`, `buildNum: ${appConfig.mobile.buildNum - 1}`);
770
895
  fs.writeFileSync(akanConfigPath, akanConfigContent);
771
896
  };
772
897
  // pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
773
- import { mkdir } from "fs/promises";
774
- import path3 from "path";
898
+ import { mkdir as mkdir2 } from "fs/promises";
899
+ import path4 from "path";
775
900
 
776
901
  // pkgs/@akanjs/devkit/transforms/asyncDefaultExportDetector.ts
777
902
  import fs2 from "fs";
778
- import path2 from "path";
903
+ import path3 from "path";
779
904
 
780
905
  class AsyncDefaultExportDetector {
781
906
  static #typescriptLoad;
@@ -786,7 +911,7 @@ class AsyncDefaultExportDetector {
786
911
  static async detect(moduleAbsPath) {
787
912
  try {
788
913
  const typescript = await AsyncDefaultExportDetector.#loadTypescript();
789
- const source = fs2.readFileSync(path2.resolve(moduleAbsPath), "utf8");
914
+ const source = fs2.readFileSync(path3.resolve(moduleAbsPath), "utf8");
790
915
  const sourceFile = typescript.createSourceFile(moduleAbsPath, source, typescript.ScriptTarget.Latest, true, AsyncDefaultExportDetector.#scriptKind(typescript, moduleAbsPath));
791
916
  return new AsyncDefaultExportDetector(typescript).detectInSourceFile(sourceFile);
792
917
  } catch {
@@ -853,16 +978,16 @@ class AsyncDefaultExportDetector {
853
978
  // pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
854
979
  var LAYOUT_KEY_RE = /^\.\/(.+\/)?_layout\.(tsx|ts|jsx|js)$/;
855
980
  async function appHasStModule(appCwdPath) {
856
- return Bun.file(path3.join(appCwdPath, "lib", "st.ts")).exists();
981
+ return Bun.file(path4.join(appCwdPath, "lib", "st.ts")).exists();
857
982
  }
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");
983
+ var IMPLICIT_LAYOUT_DIR = path4.join(".akan", "generated", "root-layouts");
984
+ var IMPLICIT_DICT_DIR = path4.join(".akan", "generated", "dict");
985
+ var IMPLICIT_OVERRIDES_DIR = path4.join(".akan", "generated", "overrides");
861
986
  var OVERRIDES_KEY_RE = /^\.\/(.+\/)?_overrides\.(tsx|ts|jsx|js)$/;
862
987
  async function writeGeneratedOverridesLayoutFile(opts) {
863
988
  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("/");
989
+ const absPath = path4.join(path4.resolve(opts.appCwdPath), IMPLICIT_OVERRIDES_DIR, filename);
990
+ const userRel = path4.relative(path4.dirname(absPath), opts.userAbsPath).split(path4.sep).join("/");
866
991
  const userSpecifier = userRel.startsWith(".") ? userRel : `./${userRel}`;
867
992
  const source = `"use client";
868
993
  import { UiOverrideProvider } from "akanjs/ui";
@@ -890,10 +1015,10 @@ function implicitRootLayoutKey(segments) {
890
1015
  }
891
1016
  function implicitRootLayoutAbsPath(appCwdPath, segments) {
892
1017
  const filename = segments.length ? `${segments.join("__")}__root_layout.tsx` : "__root_layout.tsx";
893
- return path3.join(path3.resolve(appCwdPath), IMPLICIT_LAYOUT_DIR, filename);
1018
+ return path4.join(path4.resolve(appCwdPath), IMPLICIT_LAYOUT_DIR, filename);
894
1019
  }
895
1020
  function implicitDictionaryMacroAbsPath(appCwdPath) {
896
- return path3.join(path3.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
1021
+ return path4.join(path4.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
897
1022
  }
898
1023
  function isRootBoundarySegments(segments, basePaths) {
899
1024
  const firstVisibleIndex = segments.findIndex((segment) => !/^\(.+\)$/.test(segment));
@@ -916,7 +1041,7 @@ function findRootBoundaries(pageKeys, appCwdPath, basePaths) {
916
1041
  const id = segments.join("/");
917
1042
  boundaries.set(id, {
918
1043
  sourceKey: key,
919
- sourceAbsPath: path3.resolve(appCwdPath, "page", key.replace(/^\.\//, "")),
1044
+ sourceAbsPath: path4.resolve(appCwdPath, "page", key.replace(/^\.\//, "")),
920
1045
  segments
921
1046
  });
922
1047
  }
@@ -934,21 +1059,21 @@ function findExplicitRootLayoutAbsPath(pageKeys, appCwdPath) {
934
1059
  const segments = getRootBoundarySegments(key);
935
1060
  return segments !== null && segments.length === 0;
936
1061
  });
937
- return rootLayoutKey ? path3.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
1062
+ return rootLayoutKey ? path4.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
938
1063
  }
939
1064
  function routePrefixForSegments(segments) {
940
1065
  const visible = segments.filter((segment) => !/^\(.+\)$/.test(segment));
941
1066
  return visible[0] ?? null;
942
1067
  }
943
1068
  async function assertEnvClientConvention(appCwdPath, appName) {
944
- const envPath = path3.join(appCwdPath, "env", "env.client.ts");
1069
+ const envPath = path4.join(appCwdPath, "env", "env.client.ts");
945
1070
  if (!await Bun.file(envPath).exists()) {
946
1071
  throw new Error(`[route-convention] app "${appName}" must provide env/env.client.ts exporting "env" for generated System.Provider`);
947
1072
  }
948
1073
  }
949
1074
  async function writeGeneratedDictionaryMacroFile(appCwdPath, appName) {
950
1075
  const absPath = implicitDictionaryMacroAbsPath(appCwdPath);
951
- await mkdir(path3.dirname(absPath), { recursive: true });
1076
+ await mkdir2(path4.dirname(absPath), { recursive: true });
952
1077
  await Bun.write(absPath, `import { getAllDictionary } from "@apps/${appName}/lib/dict" with { type: "macro" };
953
1078
 
954
1079
  export const allDictionary = getAllDictionary();
@@ -959,13 +1084,13 @@ async function writeGeneratedRootLayoutFile(opts) {
959
1084
  await assertEnvClientConvention(opts.appCwdPath, opts.appName);
960
1085
  const dictMacroAbsPath = opts.includeSystemProvider ? await writeGeneratedDictionaryMacroFile(opts.appCwdPath, opts.appName) : null;
961
1086
  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;
1087
+ await mkdir2(path4.dirname(absPath), { recursive: true });
1088
+ const dictMacroRel = dictMacroAbsPath ? path4.relative(path4.dirname(absPath), dictMacroAbsPath).split(path4.sep).join("/") : null;
964
1089
  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;
1090
+ const sourceRel = opts.boundary.sourceAbsPath ? path4.relative(path4.dirname(absPath), opts.boundary.sourceAbsPath).split(path4.sep).join("/") : null;
966
1091
  const sourceSpecifier = sourceRel ? sourceRel.startsWith(".") ? sourceRel : `./${sourceRel}` : null;
967
1092
  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;
1093
+ const inheritedSourceRel = inheritedSourceAbsPath ? path4.relative(path4.dirname(absPath), inheritedSourceAbsPath).split(path4.sep).join("/") : null;
969
1094
  const inheritedSourceSpecifier = inheritedSourceRel ? inheritedSourceRel.startsWith(".") ? inheritedSourceRel : `./${inheritedSourceRel}` : null;
970
1095
  const clientImport = opts.includeStInit ? `import { st } from "@apps/${opts.appName}/client";
971
1096
  void st;
@@ -1069,7 +1194,7 @@ ${layoutBinding} return ${layoutReturn};
1069
1194
  return absPath;
1070
1195
  }
1071
1196
  async function resolveSsrPageEntries(opts) {
1072
- const absPageDir = path3.resolve(opts.appCwdPath, "page");
1197
+ const absPageDir = path4.resolve(opts.appCwdPath, "page");
1073
1198
  const hasSt = await appHasStModule(opts.appCwdPath);
1074
1199
  const basePaths = opts.basePaths ?? [];
1075
1200
  const rootSourceAbsPath = findExplicitRootLayoutAbsPath(opts.pageKeys, opts.appCwdPath);
@@ -1079,7 +1204,7 @@ async function resolveSsrPageEntries(opts) {
1079
1204
  return segments !== null && isRootBoundarySegments(segments, basePaths);
1080
1205
  }));
1081
1206
  const base = await Promise.all(opts.pageKeys.filter((key) => !rootLayoutKeys.has(key)).map(async (key) => {
1082
- const userAbsPath = path3.resolve(absPageDir, key);
1207
+ const userAbsPath = path4.resolve(absPageDir, key);
1083
1208
  if (OVERRIDES_KEY_RE.test(key)) {
1084
1209
  const moduleAbsPath = await writeGeneratedOverridesLayoutFile({
1085
1210
  appCwdPath: opts.appCwdPath,
@@ -1114,7 +1239,7 @@ async function resolveSsrPageEntriesForApp(app, pageKeys) {
1114
1239
  // pkgs/@akanjs/devkit/linter.ts
1115
1240
  import { spawn } from "child_process";
1116
1241
  import { existsSync, readFileSync } from "fs";
1117
- import path4 from "path";
1242
+ import path5 from "path";
1118
1243
  import chalk from "chalk";
1119
1244
  var parseBiomeReport = (output) => {
1120
1245
  for (let start = output.indexOf("{");start !== -1; start = output.indexOf("{", start + 1)) {
@@ -1171,13 +1296,13 @@ class Linter {
1171
1296
  #biomeBin;
1172
1297
  constructor(cwdPath) {
1173
1298
  this.lintRoot = this.#findBiomeRootPath(cwdPath);
1174
- this.configPath = Linter.#configPathIn(this.lintRoot) ?? path4.join(this.lintRoot, "biome.json");
1175
- const localBiomeBin = path4.join(this.lintRoot, "node_modules/.bin/biome");
1299
+ this.configPath = Linter.#configPathIn(this.lintRoot) ?? path5.join(this.lintRoot, "biome.json");
1300
+ const localBiomeBin = path5.join(this.lintRoot, "node_modules/.bin/biome");
1176
1301
  this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
1177
1302
  }
1178
1303
  static #configPathIn(dir) {
1179
1304
  for (const fileName of BIOME_CONFIG_FILES) {
1180
- const configPath = path4.join(dir, fileName);
1305
+ const configPath = path5.join(dir, fileName);
1181
1306
  if (existsSync(configPath))
1182
1307
  return configPath;
1183
1308
  }
@@ -1186,19 +1311,19 @@ class Linter {
1186
1311
  #findBiomeRootPath(dir) {
1187
1312
  if (Linter.#configPathIn(dir))
1188
1313
  return dir;
1189
- const parentDir = path4.dirname(dir);
1314
+ const parentDir = path5.dirname(dir);
1190
1315
  if (parentDir === dir)
1191
1316
  throw new Error(`biome.json not found from ${dir}`);
1192
1317
  return this.#findBiomeRootPath(parentDir);
1193
1318
  }
1194
1319
  #toBiomePath(filePath) {
1195
- const relativePath = path4.relative(this.lintRoot, filePath);
1196
- if (!relativePath.startsWith("..") && !path4.isAbsolute(relativePath))
1320
+ const relativePath = path5.relative(this.lintRoot, filePath);
1321
+ if (!relativePath.startsWith("..") && !path5.isAbsolute(relativePath))
1197
1322
  return relativePath;
1198
1323
  return filePath;
1199
1324
  }
1200
1325
  #resolveFilePath(filePath) {
1201
- return path4.isAbsolute(filePath) ? filePath : path4.join(this.lintRoot, filePath);
1326
+ return path5.isAbsolute(filePath) ? filePath : path5.join(this.lintRoot, filePath);
1202
1327
  }
1203
1328
  async#runBiome(args, input) {
1204
1329
  return await new Promise((resolve, reject) => {
@@ -1223,7 +1348,7 @@ class Linter {
1223
1348
  const diagnosticPath = diagnostic.location?.path;
1224
1349
  if (!diagnosticPath)
1225
1350
  return fallbackFilePath;
1226
- return path4.isAbsolute(diagnosticPath) ? diagnosticPath : path4.join(this.lintRoot, diagnosticPath);
1351
+ return path5.isAbsolute(diagnosticPath) ? diagnosticPath : path5.join(this.lintRoot, diagnosticPath);
1227
1352
  }
1228
1353
  #createLintMessage(diagnostic) {
1229
1354
  const start = diagnostic.location?.start;
@@ -1453,7 +1578,7 @@ ${errorText}, ${warningText} found`];
1453
1578
 
1454
1579
  // pkgs/@akanjs/devkit/repoIdentity.ts
1455
1580
  import { execFileSync } from "child_process";
1456
- import path5 from "path";
1581
+ import path6 from "path";
1457
1582
  var resolved = new Map;
1458
1583
  var readRemoteName = (workspaceRoot) => {
1459
1584
  try {
@@ -1471,14 +1596,14 @@ var resolveRepoName = (workspaceRoot) => {
1471
1596
  const cached = resolved.get(workspaceRoot);
1472
1597
  if (cached)
1473
1598
  return cached;
1474
- const repoName = readRemoteName(workspaceRoot) ?? path5.basename(workspaceRoot);
1599
+ const repoName = readRemoteName(workspaceRoot) ?? path6.basename(workspaceRoot);
1475
1600
  resolved.set(workspaceRoot, repoName);
1476
1601
  return repoName;
1477
1602
  };
1478
1603
 
1479
1604
  // pkgs/@akanjs/devkit/scanInfo.ts
1480
- import { rm } from "fs/promises";
1481
- import path6 from "path";
1605
+ import { rm as rm2 } from "fs/promises";
1606
+ import path7 from "path";
1482
1607
 
1483
1608
  // pkgs/@akanjs/devkit/workspaceLayout.ts
1484
1609
  var appRootAllowedFiles = new Set([
@@ -1582,16 +1707,16 @@ var moduleUiFileTypes = {
1582
1707
  scalar: new Set(["Template", "Unit"])
1583
1708
  };
1584
1709
  var testFilePattern = /\.(test|spec)\.(ts|tsx)$/;
1585
- var createDependencyScanner = async (exec) => (await import("./dependencyScanner-c64m6fxp.js")).TypeScriptDependencyScanner.from(exec);
1710
+ var createDependencyScanner = async (exec) => (await import("./dependencyScanner-shs82ynp.js")).TypeScriptDependencyScanner.from(exec);
1586
1711
  var isAllowedTestFile = (filename) => testFilePattern.test(filename);
1587
- var getScanPath = (exec, relativePath) => path6.posix.join(`${exec.type}s`, exec.name, relativePath.split(path6.sep).join("/"));
1712
+ var getScanPath = (exec, relativePath) => path7.posix.join(`${exec.type}s`, exec.name, relativePath.split(path7.sep).join("/"));
1588
1713
  async function clearGeneratedRootCapacitorConfigs(exec) {
1589
1714
  if (exec.type !== "app")
1590
1715
  return;
1591
- await Promise.all(generatedRootCapacitorConfigFiles.map((filename) => rm(exec.getPath(filename), { force: true })));
1716
+ await Promise.all(generatedRootCapacitorConfigFiles.map((filename) => rm2(exec.getPath(filename), { force: true })));
1592
1717
  }
1593
1718
  var getModuleNameFromPath = (kind, modulePath) => {
1594
- const dirname = path6.basename(modulePath);
1719
+ const dirname = path7.basename(modulePath);
1595
1720
  return kind === "service" ? dirname.replace(/^_+/, "") : dirname;
1596
1721
  };
1597
1722
  async function assertScanConvention(exec, libRoot) {
@@ -1613,18 +1738,18 @@ async function assertScanConvention(exec, libRoot) {
1613
1738
  for (const { relativePath, reason } of await exec.getPageConventionViolations())
1614
1739
  addViolation(relativePath, reason);
1615
1740
  libRoot.files.filter((filename) => !isAllowedLibFacetRootFile(filename)).forEach((filename) => {
1616
- addViolation(path6.join("lib", filename), "unsupported lib facet root file");
1741
+ addViolation(path7.join("lib", filename), "unsupported lib facet root file");
1617
1742
  });
1618
1743
  libRoot.dirs.filter((dirname) => dirname.startsWith("__") && !internalLibDirs.has(dirname)).forEach((dirname) => {
1619
- addViolation(path6.join("lib", dirname), "unsupported internal lib folder");
1744
+ addViolation(path7.join("lib", dirname), "unsupported internal lib folder");
1620
1745
  });
1621
1746
  const databaseDirs = libRoot.dirs.filter((dirname) => !dirname.startsWith("_"));
1622
1747
  const serviceDirs = libRoot.dirs.filter((dirname) => dirname.startsWith("_") && !dirname.startsWith("__"));
1623
1748
  const scalarDirs = await exec.readdir("lib/__scalar");
1624
1749
  await Promise.all([
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)))
1750
+ ...databaseDirs.map((dirname) => validateModuleFiles(exec, violations, "database", path7.join("lib", dirname))),
1751
+ ...serviceDirs.map((dirname) => validateModuleFiles(exec, violations, "service", path7.join("lib", dirname))),
1752
+ ...scalarDirs.map((dirname) => validateModuleFiles(exec, violations, "scalar", path7.join("lib/__scalar", dirname)))
1628
1753
  ]);
1629
1754
  if (violations.length > 0) {
1630
1755
  throw new Error(`[scan-convention]
@@ -1636,11 +1761,11 @@ async function validateModuleFiles(exec, violations, kind, modulePath) {
1636
1761
  const { files, dirs } = await exec.getFilesAndDirs(modulePath);
1637
1762
  const moduleName = getModuleNameFromPath(kind, modulePath);
1638
1763
  dirs.forEach((dirname) => {
1639
- violations.push(`${getScanPath(exec, path6.join(modulePath, dirname))}: unsupported module folder`);
1764
+ violations.push(`${getScanPath(exec, path7.join(modulePath, dirname))}: unsupported module folder`);
1640
1765
  });
1641
1766
  const uiModuleName = moduleName[0].toUpperCase() + moduleName.slice(1);
1642
1767
  files.forEach((filename) => {
1643
- const filePath = path6.join(modulePath, filename);
1768
+ const filePath = path7.join(modulePath, filename);
1644
1769
  if (filename === "index.ts" || filename === "index.tsx" || isAllowedTestFile(filename))
1645
1770
  return;
1646
1771
  if (filename === `${moduleName}.abstract.md`)
@@ -1720,7 +1845,7 @@ class ScanInfo {
1720
1845
  });
1721
1846
  await Promise.all([
1722
1847
  ...databaseDirs.map(async (name) => {
1723
- const filenames = await exec.readdir(path6.join("lib", name));
1848
+ const filenames = await exec.readdir(path7.join("lib", name));
1724
1849
  filenames.forEach((filename) => {
1725
1850
  if (filename.endsWith(".constant.ts"))
1726
1851
  files.constant.databases.push(name);
@@ -1748,7 +1873,7 @@ class ScanInfo {
1748
1873
  }),
1749
1874
  ...serviceDirs.map(async (dirname) => {
1750
1875
  const name = dirname.slice(1);
1751
- const filenames = await exec.readdir(path6.join("lib", dirname));
1876
+ const filenames = await exec.readdir(path7.join("lib", dirname));
1752
1877
  filenames.forEach((filename) => {
1753
1878
  if (filename.endsWith(".dictionary.ts"))
1754
1879
  files.dictionary.services.push(name);
@@ -1771,7 +1896,7 @@ class ScanInfo {
1771
1896
  });
1772
1897
  }),
1773
1898
  ...scalarDirs.map(async (name) => {
1774
- const filenames = await exec.readdir(path6.join("lib/__scalar", name));
1899
+ const filenames = await exec.readdir(path7.join("lib/__scalar", name));
1775
1900
  filenames.forEach((filename) => {
1776
1901
  if (filename.endsWith(".constant.ts"))
1777
1902
  files.constant.scalars.push(name);
@@ -1797,7 +1922,7 @@ class ScanInfo {
1797
1922
  name: exec.name,
1798
1923
  type: exec.type,
1799
1924
  repoName: exec.workspace.repoName,
1800
- serveDomain: WorkspaceExecutor.getBaseDevEnv(path6.join(exec.workspace.workspaceRoot, ".env")).serveDomain,
1925
+ serveDomain: WorkspaceExecutor.getBaseDevEnv(path7.join(exec.workspace.workspaceRoot, ".env")).serveDomain,
1801
1926
  files,
1802
1927
  libDeps,
1803
1928
  pkgDeps,
@@ -2194,16 +2319,16 @@ class Executor {
2194
2319
  linter = null;
2195
2320
  constructor(name, cwdPath) {
2196
2321
  this.name = name;
2197
- this.logger = new Logger(name);
2322
+ this.logger = new Logger2(name);
2198
2323
  this.logs = [];
2199
2324
  this.cwdPath = cwdPath;
2200
2325
  }
2201
2326
  #stdout(data) {
2202
2327
  if (Executor.verbose)
2203
- Logger.raw(chalk2.dim(data.toString()));
2328
+ Logger2.raw(chalk2.dim(data.toString()));
2204
2329
  }
2205
2330
  #stderr(data) {
2206
- Logger.raw(chalk2.red(data.toString()));
2331
+ Logger2.raw(chalk2.red(data.toString()));
2207
2332
  }
2208
2333
  exec(command, options = {}) {
2209
2334
  const cwd = options.cwd?.toString() ?? this.cwdPath;
@@ -2345,10 +2470,10 @@ class Executor {
2345
2470
  });
2346
2471
  }
2347
2472
  getPath(filePath) {
2348
- if (path7.isAbsolute(filePath))
2473
+ if (path8.isAbsolute(filePath))
2349
2474
  return filePath;
2350
2475
  if (filePath.startsWith("."))
2351
- return path7.join(this.cwdPath, filePath);
2476
+ return path8.join(this.cwdPath, filePath);
2352
2477
  const baseParts = this.cwdPath.split(/[\\/]/).filter(Boolean);
2353
2478
  const targetParts = filePath.split(/[\\/]/).filter(Boolean);
2354
2479
  let overlapLength = 0;
@@ -2362,12 +2487,12 @@ class Executor {
2362
2487
  if (isOverlap)
2363
2488
  overlapLength = i;
2364
2489
  }
2365
- return path7.join(this.cwdPath, ...targetParts.slice(overlapLength));
2490
+ return path8.join(this.cwdPath, ...targetParts.slice(overlapLength));
2366
2491
  }
2367
2492
  async mkdir(dirPath) {
2368
2493
  const writePath = this.getPath(dirPath);
2369
2494
  if (!await FileSys.dirExists(writePath))
2370
- await mkdir2(writePath, { recursive: true });
2495
+ await mkdir3(writePath, { recursive: true });
2371
2496
  this.logger.verbose(`Make directory ${writePath}`);
2372
2497
  return this;
2373
2498
  }
@@ -2405,17 +2530,17 @@ class Executor {
2405
2530
  return this;
2406
2531
  }
2407
2532
  async removeDir(dirPath) {
2408
- const readPath = path7.join(this.getPath(dirPath), ".");
2533
+ const readPath = path8.join(this.getPath(dirPath), ".");
2409
2534
  if (await FileSys.entryExists(readPath))
2410
- await rm2(readPath, { recursive: true, force: true });
2535
+ await rm3(readPath, { recursive: true, force: true });
2411
2536
  this.logger.verbose(`Remove directory ${readPath}`);
2412
2537
  return this;
2413
2538
  }
2414
2539
  async writeFile(filePath, content, { overwrite = true, silent = false } = {}) {
2415
2540
  const writePath = this.getPath(filePath);
2416
- const dir = path7.dirname(writePath);
2541
+ const dir = path8.dirname(writePath);
2417
2542
  if (!await FileSys.dirExists(dir))
2418
- await mkdir2(dir, { recursive: true });
2543
+ await mkdir3(dir, { recursive: true });
2419
2544
  let contentStr = typeof content === "string" ? content : `${JSON.stringify(content, null, 2)}
2420
2545
  `;
2421
2546
  if (await FileSys.fileExists(writePath)) {
@@ -2425,7 +2550,7 @@ class Executor {
2425
2550
  contentStr = currentContent;
2426
2551
  } else {
2427
2552
  await FileSys.writeText(writePath, contentStr);
2428
- if (Logger.isVerbose())
2553
+ if (Logger2.isVerbose())
2429
2554
  this.logger.rawLog(chalk2.yellow(`File Update: ${filePath}`));
2430
2555
  }
2431
2556
  } else {
@@ -2439,7 +2564,7 @@ class Executor {
2439
2564
  await this.writeFile(filePath, content);
2440
2565
  }
2441
2566
  async getLocalFile(targetPath) {
2442
- const filePath = path7.isAbsolute(targetPath) ? targetPath : targetPath.replace(this.cwdPath, "");
2567
+ const filePath = path8.isAbsolute(targetPath) ? targetPath : targetPath.replace(this.cwdPath, "");
2443
2568
  const content = await this.readFile(filePath);
2444
2569
  return { filePath, content };
2445
2570
  }
@@ -2456,9 +2581,9 @@ class Executor {
2456
2581
  const dest = this.getPath(destPath);
2457
2582
  if (!await FileSys.exists(src))
2458
2583
  return;
2459
- const isDirectory = (await stat(src)).isDirectory();
2584
+ const isDirectory = (await stat2(src)).isDirectory();
2460
2585
  if (!await FileSys.exists(dest) && isDirectory)
2461
- await mkdir2(dest, { recursive: true });
2586
+ await mkdir3(dest, { recursive: true });
2462
2587
  if (dereference)
2463
2588
  await cpEntry(src, dest, { recursive: isDirectory, dereference: true, force: true });
2464
2589
  else
@@ -2536,9 +2661,9 @@ class Executor {
2536
2661
  const result = await getContent.default(scanInfo ?? null, dict, options);
2537
2662
  if (result === null)
2538
2663
  return null;
2539
- const filename = typeof result === "object" ? result.filename : path7.basename(targetPath).replace(".js", ".ts");
2664
+ const filename = typeof result === "object" ? result.filename : path8.basename(targetPath).replace(".js", ".ts");
2540
2665
  const content = typeof result === "object" ? result.content : result;
2541
- const dirname = path7.dirname(targetPath);
2666
+ const dirname = path8.dirname(targetPath);
2542
2667
  const convertedTargetPath = Object.entries(dict).reduce((path, [key, value]) => path.replace(new RegExp(`__${key}__`, "g"), value), `${dirname}/${filename}`);
2543
2668
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2544
2669
  return this.writeFile(convertedTargetPath, content, { overwrite });
@@ -2550,12 +2675,12 @@ class Executor {
2550
2675
  return this.writeFile(convertedTargetPath, convertedContent, {
2551
2676
  overwrite
2552
2677
  });
2553
- } else if (staticTemplateFileExtensions.has(path7.extname(targetPath).toLowerCase())) {
2678
+ } else if (staticTemplateFileExtensions.has(path8.extname(targetPath).toLowerCase())) {
2554
2679
  const convertedTargetPath = Object.entries(dict).reduce((path, [key, value]) => path.replace(new RegExp(`__${key}__`, "g"), value), targetPath);
2555
2680
  const writePath = this.getPath(convertedTargetPath);
2556
- const dirname = path7.dirname(writePath);
2681
+ const dirname = path8.dirname(writePath);
2557
2682
  if (!await FileSys.dirExists(dirname))
2558
- await mkdir2(dirname, { recursive: true });
2683
+ await mkdir3(dirname, { recursive: true });
2559
2684
  await copyFile(templatePath, writePath);
2560
2685
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2561
2686
  return { filePath: writePath, content: "" };
@@ -2573,11 +2698,11 @@ class Executor {
2573
2698
  const templateRoot = await this.#resolveTemplateRoot();
2574
2699
  const templatePath = `${templateRoot}${template ? `/${template}` : ""}`;
2575
2700
  const prefixTemplatePath = templatePath;
2576
- if ((await stat(prefixTemplatePath)).isFile()) {
2577
- const filename = path7.basename(prefixTemplatePath);
2701
+ if ((await stat2(prefixTemplatePath)).isFile()) {
2702
+ const filename = path8.basename(prefixTemplatePath);
2578
2703
  const fileContent = await this.#applyTemplateFile({
2579
2704
  templatePath: prefixTemplatePath,
2580
- targetPath: path7.join(basePath, filename),
2705
+ targetPath: path8.join(basePath, filename),
2581
2706
  scanInfo,
2582
2707
  overwrite
2583
2708
  }, dict, options);
@@ -2585,19 +2710,19 @@ class Executor {
2585
2710
  } else {
2586
2711
  const subdirs = await readDirEntries(templatePath);
2587
2712
  const fileContents = (await Promise.all(subdirs.map(async (subdir) => {
2588
- const subpath = path7.join(templatePath, subdir);
2589
- if ((await stat(subpath)).isFile()) {
2713
+ const subpath = path8.join(templatePath, subdir);
2714
+ if ((await stat2(subpath)).isFile()) {
2590
2715
  const fileContent = await this.#applyTemplateFile({
2591
2716
  templatePath: subpath,
2592
- targetPath: path7.join(basePath, subdir),
2717
+ targetPath: path8.join(basePath, subdir),
2593
2718
  scanInfo,
2594
2719
  overwrite
2595
2720
  }, dict, options);
2596
2721
  return fileContent ? [fileContent] : [];
2597
2722
  } else
2598
2723
  return await this._applyTemplate({
2599
- basePath: path7.join(basePath, subdir),
2600
- template: path7.join(template, subdir),
2724
+ basePath: path8.join(basePath, subdir),
2725
+ template: path8.join(template, subdir),
2601
2726
  scanInfo,
2602
2727
  dict,
2603
2728
  overwrite,
@@ -2609,8 +2734,8 @@ class Executor {
2609
2734
  }
2610
2735
  async#resolveTemplateRoot() {
2611
2736
  const candidates = [
2612
- path7.resolve(getDirname2(import.meta.url), "templates"),
2613
- path7.resolve(getDirname2(import.meta.url), "../cli/templates")
2737
+ path8.resolve(getDirname2(import.meta.url), "templates"),
2738
+ path8.resolve(getDirname2(import.meta.url), "../cli/templates")
2614
2739
  ];
2615
2740
  for (const candidate of candidates) {
2616
2741
  if (await FileSys.dirExists(candidate))
@@ -2682,11 +2807,11 @@ class Executor {
2682
2807
  async#resolveTypecheckWorkerEntry() {
2683
2808
  const dirname = getDirname2(import.meta.url);
2684
2809
  const candidates = [
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")
2810
+ path8.join(process.cwd(), "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
2811
+ path8.join(process.cwd(), "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
2812
+ path8.join(dirname, "typecheck/typecheck.proc.ts"),
2813
+ path8.join(dirname, "typecheck.proc.js"),
2814
+ path8.join(dirname, "typecheck.proc.ts")
2690
2815
  ];
2691
2816
  for (const candidate of candidates)
2692
2817
  if (await Bun.file(candidate).exists())
@@ -2813,8 +2938,8 @@ class WorkspaceExecutor extends Executor {
2813
2938
  await Promise.all(dirs.map(async (dir) => {
2814
2939
  if (dir.includes("_") || AVOID_DIRS.includes(dir))
2815
2940
  return;
2816
- const dirPath = path7.join(dirname, dir);
2817
- if ((await stat(dirPath)).isDirectory()) {
2941
+ const dirPath = path8.join(dirname, dir);
2942
+ if ((await stat2(dirPath)).isDirectory()) {
2818
2943
  results.push(`${prefix}${dir}`);
2819
2944
  if (maxDepth > 0)
2820
2945
  await getDirs(dirPath, maxDepth - 1, results, `${prefix}${dir}/`);
@@ -2848,9 +2973,9 @@ class WorkspaceExecutor extends Executor {
2848
2973
  await Promise.all(dirs.map(async (dir) => {
2849
2974
  if (AVOID_DIRS.includes(dir))
2850
2975
  return;
2851
- const dirPath = path7.join(dirname, dir);
2976
+ const dirPath = path8.join(dirname, dir);
2852
2977
  if (await FileSys.dirExists(dirPath)) {
2853
- const hasTargetFile = await FileSys.fileExists(path7.join(dirPath, targetFilename));
2978
+ const hasTargetFile = await FileSys.fileExists(path8.join(dirPath, targetFilename));
2854
2979
  if (hasTargetFile)
2855
2980
  results.push(`${prefix}${dir}`);
2856
2981
  if (maxDepth > 0)
@@ -2924,7 +3049,7 @@ class SysExecutor extends Executor {
2924
3049
  return [];
2925
3050
  const violations = [];
2926
3051
  for (const entry of await this.getAllFiles("**/*", { cwd: this.getPath("page") })) {
2927
- const relativePath = entry.split(path7.sep).join("/");
3052
+ const relativePath = entry.split(path8.sep).join("/");
2928
3053
  const reason = getPageSourceFileViolation(relativePath);
2929
3054
  if (reason)
2930
3055
  violations.push({ relativePath: `page/${relativePath}`, reason });
@@ -2987,18 +3112,19 @@ class SysExecutor extends Executor {
2987
3112
  }) : await LibInfo.fromExecutor(this, {
2988
3113
  refresh
2989
3114
  });
2990
- if (write) {
2991
- await Promise.all(this.#getScanTemplateTasks(scanInfo));
2992
- await this.writeJson(`akan.${this.type}.json`, scanInfo.getScanResult());
2993
- if (this.type === "lib")
2994
- this.#updateDependencies(scanInfo);
2995
- if (writeLib) {
2996
- const libInfos = [...scanInfo.getLibInfos().values()];
2997
- await this.#updateDependencies(scanInfo);
2998
- await Promise.all(libInfos.flatMap((libInfo) => libInfo.exec.#getScanTemplateTasks(libInfo)));
2999
- }
3000
- await this.syncAgentsIndex(scanInfo);
3001
- }
3115
+ if (write)
3116
+ await CodegenLock.run(this.workspace.workspaceRoot, `scan:${this.name}`, async () => {
3117
+ await Promise.all(this.#getScanTemplateTasks(scanInfo));
3118
+ await this.writeJson(`akan.${this.type}.json`, scanInfo.getScanResult());
3119
+ if (this.type === "lib")
3120
+ this.#updateDependencies(scanInfo);
3121
+ if (writeLib) {
3122
+ const libInfos = [...scanInfo.getLibInfos().values()];
3123
+ await this.#updateDependencies(scanInfo);
3124
+ await Promise.all(libInfos.flatMap((libInfo) => libInfo.exec.#getScanTemplateTasks(libInfo)));
3125
+ }
3126
+ await this.syncAgentsIndex(scanInfo);
3127
+ });
3002
3128
  this.#scanInfo = scanInfo;
3003
3129
  return scanInfo;
3004
3130
  }
@@ -3033,7 +3159,7 @@ class SysExecutor extends Executor {
3033
3159
  await this.setPackageJson(libPkgJsonWithDeps);
3034
3160
  }
3035
3161
  async getLocalFile(targetPath) {
3036
- const filePath = path7.isAbsolute(targetPath) ? targetPath : `${this.type}s/${this.name}/${targetPath}`;
3162
+ const filePath = path8.isAbsolute(targetPath) ? targetPath : `${this.type}s/${this.name}/${targetPath}`;
3037
3163
  const content = await this.workspace.readFile(filePath);
3038
3164
  return { filePath, content };
3039
3165
  }
@@ -3172,6 +3298,8 @@ class AppExecutor extends SysExecutor {
3172
3298
  const databaseMode = process.env.AKAN_DATABASE_MODE ?? akanConfig.defaultDatabaseMode ?? "single";
3173
3299
  const routeEnv = {
3174
3300
  AKAN_PUBLIC_BASE_PATHS: [...akanConfig.basePaths].join(","),
3301
+ AKAN_PUBLIC_API_PREFIX: akanConfig.api.prefix,
3302
+ AKAN_PUBLIC_WS_PREFIX: akanConfig.api.websocketPrefix,
3175
3303
  AKAN_DATABASE_MODE: databaseMode
3176
3304
  };
3177
3305
  Object.assign(process.env, routeEnv);
@@ -3252,11 +3380,11 @@ class AppExecutor extends SysExecutor {
3252
3380
  absolute: false,
3253
3381
  onlyFiles: true
3254
3382
  })) {
3255
- const segments = rel.split(path7.sep);
3383
+ const segments = rel.split(path8.sep);
3256
3384
  if (segments.some((s) => s === "node_modules"))
3257
3385
  continue;
3258
3386
  const posix = `${root.keyPrefix}${segments.join("/")}`;
3259
- const absPath = path7.join(root.dir, ...segments);
3387
+ const absPath = path8.join(root.dir, ...segments);
3260
3388
  validatePageSourceFile(posix, { filePath: absPath });
3261
3389
  if (!isRouteSourceFile(posix))
3262
3390
  continue;
@@ -3395,12 +3523,12 @@ class AppExecutor extends SysExecutor {
3395
3523
  static async#linkLibAsset(targetPath, linkPath) {
3396
3524
  const isWindows = process.platform === "win32";
3397
3525
  try {
3398
- const target = isWindows ? targetPath : path7.relative(path7.dirname(linkPath), targetPath);
3526
+ const target = isWindows ? targetPath : path8.relative(path8.dirname(linkPath), targetPath);
3399
3527
  await symlink(target, linkPath, isWindows ? "junction" : "dir");
3400
3528
  } catch (error) {
3401
3529
  if (!isWindows)
3402
3530
  throw error;
3403
- await mkdir2(linkPath, { recursive: true });
3531
+ await mkdir3(linkPath, { recursive: true });
3404
3532
  await cpEntry(targetPath, linkPath, { recursive: true, dereference: true, force: true });
3405
3533
  }
3406
3534
  }
@@ -3437,7 +3565,7 @@ class AppExecutor extends SysExecutor {
3437
3565
  await this.writeFile(rel, content, opts);
3438
3566
  },
3439
3567
  readEnvClient: async () => {
3440
- const envClientPath = path7.join(this.cwdPath, "env", "env.client.ts");
3568
+ const envClientPath = path8.join(this.cwdPath, "env", "env.client.ts");
3441
3569
  if (!await FileSys.fileExists(envClientPath))
3442
3570
  return null;
3443
3571
  try {
@@ -3547,7 +3675,7 @@ class PkgExecutor extends Executor {
3547
3675
  return rootVersion;
3548
3676
  try {
3549
3677
  const packageJsonPath = `pkgs/${dep}/package.json`;
3550
- if (!await Bun.file(path7.join(this.workspace.workspaceRoot, packageJsonPath)).exists())
3678
+ if (!await Bun.file(path8.join(this.workspace.workspaceRoot, packageJsonPath)).exists())
3551
3679
  return;
3552
3680
  const packageJson = await this.workspace.readJson(packageJsonPath);
3553
3681
  if (packageJson.name === dep)
@@ -3648,4 +3776,4 @@ class ModuleExecutor extends Executor {
3648
3776
  }
3649
3777
  }
3650
3778
 
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 };
3779
+ export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, AsyncDefaultExportDetector, resolveSsrPageEntriesForApp, CodegenLock, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, isScannedRootEntry, AppInfo, Spinner, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };