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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/.build-stamp +1 -1
  2. package/CodeAgent-awv258wb.js +9 -0
  3. package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
  4. package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
  5. package/CodeTui-1nqh35ez.js +1457 -0
  6. package/README.md +3 -0
  7. package/TunnelShare-scf4e4pd.js +9 -0
  8. package/{agent.command-d2gfxfck.js → agent.command-1s9ag7sb.js} +8 -9
  9. package/akanCode.js +102 -0
  10. package/{application.command-pj2m7584.js → application.command-49hwy6va.js} +51 -78
  11. package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-ybyp97pv.js} +63 -64
  12. package/{applicationReleasePackager-4yasxwv9.js → applicationReleasePackager-esnrphw8.js} +40 -60
  13. package/buildBatch.proc.js +19 -24
  14. package/{capacitorApp-36rbr858.js → capacitorApp-1synz4en.js} +3 -4
  15. package/cloud.command-d7rqtzt9.js +94 -0
  16. package/cloud.script-bkbpcr96.js +19 -0
  17. package/code.command-nn48xzej.js +154 -0
  18. package/commandManifest.json +1 -1
  19. package/consoleToStderr-h5bryj94.js +7 -0
  20. package/context.command-s3mcmvpa.js +48 -0
  21. package/context.runner-k99nb5pk.js +21 -0
  22. package/{dependencyScanner-shs82ynp.js → dependencyScanner-ye2e6pdz.js} +2 -2
  23. package/{devTui-40ggmd99.js → devTui-q7k7bakd.js} +122 -40
  24. package/fileSys-5ngz93ga.js +9 -0
  25. package/guideline.command-sct4qnt5.js +42 -0
  26. package/guidelines/agentRule/agentRule.instruction.md +206 -25
  27. package/guidelines/conventions/conventions.instruction.md +79 -24
  28. package/guidelines/fieldRule/fieldRule.instruction.md +1 -0
  29. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  30. package/guidelines/queryRule/queryRule.instruction.md +17 -7
  31. package/guidelines/runtimeRule/runtimeRule.instruction.md +74 -0
  32. package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
  33. package/guidelines/transportRule/transportRule.instruction.md +51 -0
  34. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
  35. package/incrementalBuilder.proc.js +31 -48
  36. package/{index-h7yw2z9n.js → index-0bq14vr1.js} +8 -14
  37. package/index-13ffe9wp.js +69 -0
  38. package/index-22d57v4c.js +266 -0
  39. package/{index-fz5q3gd7.js → index-31yr441d.js} +10 -17
  40. package/index-3hx1z96c.js +87 -0
  41. package/index-3sq321ak.js +53 -0
  42. package/{index-kcxmv48c.js → index-3t7g9e4r.js} +45 -79
  43. package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
  44. package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
  45. package/{index-259dsnz3.js → index-5pc1qrbv.js} +5 -8
  46. package/index-7md2g9vw.js +6 -0
  47. package/index-8mna0947.js +187 -0
  48. package/{index-zry5nz81.js → index-8sf7wmdr.js} +51 -30
  49. package/{index-2tv3fdx4.js → index-9d9bgcx4.js} +342 -765
  50. package/index-9dp031by.js +12 -0
  51. package/{index-ne2qy0nk.js → index-ahemdr5n.js} +12 -12
  52. package/{index-ws5e0j51.js → index-as7xmyz8.js} +40 -24
  53. package/index-axzjaqve.js +1118 -0
  54. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  55. package/index-c6eggbee.js +123 -0
  56. package/index-d2242ksy.js +99 -0
  57. package/{index-a64esmtb.js → index-ddxvdd1p.js} +169 -305
  58. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  59. package/{index-pnqbkf5p.js → index-dzf3r49a.js} +6 -2
  60. package/{index-w8kmx1b6.js → index-fgq75haa.js} +198 -290
  61. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  62. package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
  63. package/{index-wt7qrtd4.js → index-mxav6j3c.js} +93 -232
  64. package/{index-gyd220p2.js → index-myhc3c1j.js} +554 -577
  65. package/{index-600zhnve.js → index-nv5976x3.js} +56 -197
  66. package/index-p6pbz9n5.js +25 -0
  67. package/{index-4edzf1gr.js → index-przybvy5.js} +77 -150
  68. package/index-smme4r47.js +49 -0
  69. package/{index-mak3cd28.js → index-w2zdcw3k.js} +137 -255
  70. package/index-wa5jbxj1.js +760 -0
  71. package/{index-v0qh106m.js → index-ww4z397j.js} +527 -723
  72. package/{index-j9yhg404.js → index-xqjwd384.js} +4 -7
  73. package/{index-7737gxcp.js → index-xqpzbab5.js} +107 -241
  74. package/index-xsjh6nzh.js +2729 -0
  75. package/{index-ktb5njgy.js → index-ygn77a5w.js} +47 -99
  76. package/index-ztp3e73t.js +700 -0
  77. package/index.js +23 -22
  78. package/{library.command-nbsky672.js → library.command-1gx04jgn.js} +4 -5
  79. package/{localRegistry.command-yeq57wjr.js → localRegistry.command-zndxj1q6.js} +22 -42
  80. package/{module.command-29vqzrh8.js → module.command-3waddk95.js} +8 -11
  81. package/{package.command-axv0abmn.js → package.command-zrc7br1y.js} +6 -7
  82. package/package.json +14 -5
  83. package/{page.command-vs9s3zrh.js → page.command-vpjgardh.js} +4 -5
  84. package/{primitive.command-cbxmqbtc.js → primitive.command-sz84tk4t.js} +9 -22
  85. package/prompter-ptaa3nk0.js +8 -0
  86. package/{quality.command-gmbs7nws.js → quality.command-g869hafs.js} +203 -376
  87. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  88. package/{repair.command-bqsjptsj.js → repair.command-chsnjvvv.js} +11 -35
  89. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  90. package/{scalar.command-6k1vhe9s.js → scalar.command-2v21newx.js} +7 -10
  91. package/skills/akan-code/SKILL.md +130 -0
  92. package/skills/akan-debug/SKILL.md +42 -0
  93. package/skills/akan-deps/SKILL.md +50 -0
  94. package/skills/akan-err/SKILL.md +39 -0
  95. package/skills/akan-module/SKILL.md +45 -0
  96. package/skills/akan-scaffold/SKILL.md +76 -0
  97. package/skills/akan-scalar/SKILL.md +52 -0
  98. package/skills/akan-service/SKILL.md +34 -0
  99. package/skills/akan-store/SKILL.md +67 -0
  100. package/skills/akan-ui/SKILL.md +63 -0
  101. package/skills/akan-validate/SKILL.md +44 -0
  102. package/{subspace.command-fwjfcts7.js → subspace.command-ckcbwfp1.js} +138 -67
  103. package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
  104. package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
  105. package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
  106. package/templates/appSample/lib/task/task.abstract.ts +12 -32
  107. package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
  108. package/templates/appSample/lib/task/task.signal.test.ts +15 -1
  109. package/templates/appSample/lib/task/task.signal.ts +1 -1
  110. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
  111. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
  112. package/templates/client.ts +7 -30
  113. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
  114. package/templates/crudPages/[__model__Id]/page.tsx +2 -1
  115. package/templates/crudPages/new/page.tsx +2 -1
  116. package/templates/crudPages/page.tsx +2 -1
  117. package/templates/crudSinglePage/page.tsx +2 -1
  118. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  119. package/templates/lib/__lib/lib.document.ts +0 -2
  120. package/templates/lib/sig.ts +8 -30
  121. package/templates/localDev/docker-compose.yaml.template +3 -14
  122. package/templates/module/__model__.signal.ts +12 -4
  123. package/templates/pkgRoot/tsconfig.json.template +2 -7
  124. package/templates/server.ts +0 -2
  125. package/templates/service/__model__.abstract.md.template +8 -0
  126. package/tunnel.command-kd2yr4fx.js +129 -0
  127. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  128. package/typecheck.proc.js +1 -1
  129. package/workflow.command-44252cqv.js +79 -0
  130. package/{workspace.command-8s050m0h.js → workspace.command-fqcztt5p.js} +77 -109
  131. package/abstractCompactor-mjh5ppsq.js +0 -101
  132. package/cloud.command-jshwdq22.js +0 -93
  133. package/context.command-ez8a0zyz.js +0 -80
  134. package/devTuiView-c08ccbat.js +0 -9
  135. package/getDirname-dr3jz1xg.js +0 -7
  136. package/guideline.command-xmqwx8zm.js +0 -359
  137. package/guidelines/agentRule/agentRule.generate.json +0 -31
  138. package/guidelines/componentRule/componentRule.generate.json +0 -31
  139. package/guidelines/conventions/conventions.generate.json +0 -25
  140. package/guidelines/cssRule/cssRule.generate.json +0 -31
  141. package/guidelines/docPageRule/docPageRule.generate.json +0 -31
  142. package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
  143. package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
  144. package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
  145. package/guidelines/enumConstant/enumConstant.generate.json +0 -31
  146. package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
  147. package/guidelines/fieldRule/fieldRule.generate.json +0 -31
  148. package/guidelines/framework/framework.generate.json +0 -32
  149. package/guidelines/mcpRule/mcpRule.generate.json +0 -35
  150. package/guidelines/modelConstant/modelConstant.generate.json +0 -32
  151. package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
  152. package/guidelines/modelDocument/modelDocument.generate.json +0 -31
  153. package/guidelines/modelService/modelService.generate.json +0 -31
  154. package/guidelines/modelSignal/modelSignal.generate.json +0 -31
  155. package/guidelines/modelStore/modelStore.generate.json +0 -31
  156. package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
  157. package/guidelines/modelUnit/modelUnit.generate.json +0 -31
  158. package/guidelines/modelUtil/modelUtil.generate.json +0 -31
  159. package/guidelines/modelView/modelView.generate.json +0 -31
  160. package/guidelines/modelZone/modelZone.generate.json +0 -31
  161. package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
  162. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
  163. package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
  164. package/guidelines/queryRule/queryRule.generate.json +0 -31
  165. package/guidelines/recipeRule/recipeRule.generate.json +0 -31
  166. package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
  167. package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
  168. package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
  169. package/guidelines/scalarModule/scalarModule.generate.json +0 -31
  170. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
  171. package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
  172. package/guidelines/ssrRule/ssrRule.generate.json +0 -31
  173. package/guidelines/transportRule/transportRule.generate.json +0 -31
  174. package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
  175. package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
  176. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
  177. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
  178. package/index-2hq52jq3.js +0 -465
  179. package/index-6wwzs1bc.js +0 -7
  180. package/index-8pm30m73.js +0 -841
  181. package/index-kn1h7p1x.js +0 -560
  182. package/index-meh558jy.js +0 -65
  183. package/index-rwg2aa4f.js +0 -229
  184. package/templates/__scalar/__model__/__model__.abstract.md +0 -28
  185. package/templates/module/__model__.abstract.md +0 -28
  186. package/templates/service/__model__.abstract.md +0 -28
  187. package/workflow.command-nwpcdc8p.js +0 -107
@@ -1,7 +1,10 @@
1
1
  // @bun
2
2
  import {
3
- FileSys
4
- } from "./index-q0y2jq9j.js";
3
+ SOURCE_EXTS
4
+ } from "./index-khpfpcsd.js";
5
+ import {
6
+ FileSys2
7
+ } from "./index-5b6tavv3.js";
5
8
 
6
9
  // pkgs/@akanjs/devkit/frontendBuild/clientEntryDiscovery.ts
7
10
  import path3 from "path";
@@ -9,6 +12,40 @@ import path3 from "path";
9
12
  // pkgs/@akanjs/devkit/transforms/barrelAnalyzer.ts
10
13
  import path from "path";
11
14
  import { Logger } from "akanjs/common";
15
+
16
+ // pkgs/@akanjs/devkit/transforms/moduleSyntax.ts
17
+ var loaderFor = (absPath) => {
18
+ if (absPath.endsWith(".tsx"))
19
+ return "tsx";
20
+ if (absPath.endsWith(".jsx"))
21
+ return "jsx";
22
+ if (absPath.endsWith(".ts"))
23
+ return "ts";
24
+ return "js";
25
+ };
26
+ var parseNamedList = (listBody) => {
27
+ const out = [];
28
+ for (const raw of listBody.split(",")) {
29
+ let rest = raw.trim();
30
+ if (!rest)
31
+ continue;
32
+ let isType = false;
33
+ if (rest.startsWith("type ")) {
34
+ isType = true;
35
+ rest = rest.slice(5).trim();
36
+ }
37
+ const asMatch = /^(\w+)\s+as\s+(\w+)$/.exec(rest);
38
+ if (asMatch) {
39
+ out.push({ imported: asMatch[1] ?? "", local: asMatch[2] ?? "", isType });
40
+ continue;
41
+ }
42
+ if (/^\w+$/.test(rest))
43
+ out.push({ imported: rest, local: rest, isType });
44
+ }
45
+ return out;
46
+ };
47
+
48
+ // pkgs/@akanjs/devkit/transforms/barrelAnalyzer.ts
12
49
  var REEXPORT_RE = /(?:^|\n)\s*export\s+(?:type\s+)?(?:(\*)(?:\s+as\s+(\w+))?|\{\s*([^}]*?)\s*\})\s+from\s+(["'])([^"']+)\4;?/g;
13
50
  var LOCAL_NAMED_RE = /(?:^|\n)\s*export\s+\{\s*([^}]*?)\s*\}(?!\s*from)/g;
14
51
  var CANDIDATE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
@@ -32,53 +69,53 @@ class BarrelAnalyzer {
32
69
  }
33
70
  async#analyzeSafe(pkgName) {
34
71
  try {
35
- return await this.#analyzeUncached(pkgName);
72
+ const pkg = await this.#opts.resolvePackage(pkgName);
73
+ if (!pkg)
74
+ return null;
75
+ const map = new Map;
76
+ await this.#walk(pkg.entryFile, pkg, map, new Set);
77
+ return map;
36
78
  } catch (err) {
37
79
  this.#logger.error(`analyze failed for ${pkgName}: ${err.message}`);
38
80
  return null;
39
81
  }
40
82
  }
41
- async#analyzeUncached(pkgName) {
42
- const pkg = await this.#opts.resolvePackage(pkgName);
43
- if (!pkg)
44
- return null;
45
- const map = new Map;
46
- const visited = new Set;
47
- await this.#walk(pkg.entryFile, pkg, map, visited);
48
- return map;
49
- }
50
83
  async#walk(absFile, pkg, map, visited) {
51
84
  if (visited.has(absFile))
52
85
  return;
53
86
  visited.add(absFile);
54
- const source = await readIfExists(absFile);
55
- if (source === null)
87
+ const file = Bun.file(absFile);
88
+ if (!await file.exists())
56
89
  return;
90
+ const source = await file.text();
57
91
  const currentSubpath = this.#subpathFor(pkg, absFile);
58
92
  if (!currentSubpath)
59
93
  return;
60
94
  const authoritative = this.#scanExports(source, absFile);
61
95
  authoritative.delete("default");
62
96
  const attributed = new Set;
63
- REEXPORT_RE.lastIndex = 0;
64
- let m = REEXPORT_RE.exec(source);
65
- while (m !== null) {
97
+ const attribute = (listBody, subpath) => {
98
+ for (const item of parseNamedList(listBody)) {
99
+ if (item.isType || item.imported === "default" || !authoritative.has(item.local))
100
+ continue;
101
+ attributed.add(item.local);
102
+ if (!map.has(item.local))
103
+ map.set(item.local, { subpath, originalName: item.imported });
104
+ }
105
+ };
106
+ const starSpecs = [];
107
+ for (const m of source.matchAll(REEXPORT_RE)) {
66
108
  const star = m[1];
67
109
  const nsAs = m[2];
68
110
  const namedList = m[3];
69
111
  const spec = m[5] ?? "";
70
- m = REEXPORT_RE.exec(source);
71
112
  if (!isRelative(spec))
72
113
  continue;
73
114
  if (star) {
74
- if (nsAs) {
115
+ if (nsAs)
75
116
  authoritative.delete(nsAs);
76
- continue;
77
- }
78
- const targetAbs = await this.#resolveRel(absFile, spec);
79
- if (!targetAbs)
80
- continue;
81
- await this.#walk(targetAbs, pkg, map, visited);
117
+ else
118
+ starSpecs.push(spec);
82
119
  continue;
83
120
  }
84
121
  if (namedList !== undefined) {
@@ -86,20 +123,8 @@ class BarrelAnalyzer {
86
123
  if (!targetAbs)
87
124
  continue;
88
125
  const targetSubpath = this.#subpathFor(pkg, targetAbs);
89
- if (!targetSubpath)
90
- continue;
91
- for (const item of parseNamedList(namedList)) {
92
- if (item.isType)
93
- continue;
94
- if (item.imported === "default")
95
- continue;
96
- if (!authoritative.has(item.local))
97
- continue;
98
- attributed.add(item.local);
99
- if (!map.has(item.local)) {
100
- map.set(item.local, { subpath: targetSubpath, originalName: item.imported });
101
- }
102
- }
126
+ if (targetSubpath)
127
+ attribute(namedList, targetSubpath);
103
128
  }
104
129
  }
105
130
  LOCAL_NAMED_RE.lastIndex = 0;
@@ -107,18 +132,7 @@ class BarrelAnalyzer {
107
132
  while (n !== null) {
108
133
  const body = n[1] ?? "";
109
134
  n = LOCAL_NAMED_RE.exec(source);
110
- for (const item of parseNamedList(body)) {
111
- if (item.isType)
112
- continue;
113
- if (item.imported === "default")
114
- continue;
115
- if (!authoritative.has(item.local))
116
- continue;
117
- attributed.add(item.local);
118
- if (!map.has(item.local)) {
119
- map.set(item.local, { subpath: currentSubpath, originalName: item.imported });
120
- }
121
- }
135
+ attribute(body, currentSubpath);
122
136
  }
123
137
  for (const name of authoritative) {
124
138
  if (attributed.has(name))
@@ -127,6 +141,11 @@ class BarrelAnalyzer {
127
141
  continue;
128
142
  map.set(name, { subpath: currentSubpath, originalName: name });
129
143
  }
144
+ for (const spec of starSpecs) {
145
+ const targetAbs = await this.#resolveRel(absFile, spec);
146
+ if (targetAbs)
147
+ await this.#walk(targetAbs, pkg, map, visited);
148
+ }
130
149
  }
131
150
  #scanExports(source, absFile) {
132
151
  try {
@@ -144,11 +163,12 @@ class BarrelAnalyzer {
144
163
  return null;
145
164
  if (pkg.preserveFilePath)
146
165
  return `${pkg.pkgName}/${rel.split(path.sep).join("/")}`;
147
- const noExt = stripKnownExt(rel);
148
- const tail = collapseIndex(noExt);
149
- if (tail === "")
150
- return pkg.pkgName;
151
- return `${pkg.pkgName}/${tail.split(path.sep).join("/")}`;
166
+ const ext = CANDIDATE_EXTS.find((candidate) => rel.endsWith(candidate));
167
+ const parts = (ext ? rel.slice(0, -ext.length) : rel).split(path.sep);
168
+ if (parts[parts.length - 1] === "index")
169
+ parts.pop();
170
+ const tail = parts.join("/");
171
+ return tail === "" ? pkg.pkgName : `${pkg.pkgName}/${tail}`;
152
172
  }
153
173
  async#resolveRel(fromFile, relSpec) {
154
174
  if (this.#opts.resolveRelative)
@@ -156,38 +176,9 @@ class BarrelAnalyzer {
156
176
  return defaultResolveRelative(fromFile, relSpec);
157
177
  }
158
178
  }
159
- var parseNamedList = (listBody) => {
160
- const out = [];
161
- for (const raw of listBody.split(",")) {
162
- const s = raw.trim();
163
- if (!s)
164
- continue;
165
- let rest = s;
166
- let isType = false;
167
- if (rest.startsWith("type ")) {
168
- isType = true;
169
- rest = rest.slice(5).trim();
170
- }
171
- const asMatch = /^(\w+)\s+as\s+(\w+)$/.exec(rest);
172
- if (asMatch) {
173
- out.push({ imported: asMatch[1] ?? "", local: asMatch[2] ?? "", isType });
174
- continue;
175
- }
176
- if (/^\w+$/.test(rest)) {
177
- out.push({ imported: rest, local: rest, isType });
178
- }
179
- }
180
- return out;
181
- };
182
179
  var isRelative = (spec) => {
183
180
  return spec.startsWith("./") || spec.startsWith("../") || spec === "." || spec === "..";
184
181
  };
185
- var readIfExists = async (absFile) => {
186
- const file = Bun.file(absFile);
187
- if (!await file.exists())
188
- return null;
189
- return file.text();
190
- };
191
182
  var defaultResolveRelative = async (fromFile, relSpec) => {
192
183
  const baseDir = path.dirname(fromFile);
193
184
  const joined = path.resolve(baseDir, relSpec);
@@ -208,19 +199,6 @@ var defaultResolveRelative = async (fromFile, relSpec) => {
208
199
  }
209
200
  return null;
210
201
  };
211
- var stripKnownExt = (relPath) => {
212
- for (const ext of CANDIDATE_EXTS) {
213
- if (relPath.endsWith(ext))
214
- return relPath.slice(0, -ext.length);
215
- }
216
- return relPath;
217
- };
218
- var collapseIndex = (relPathNoExt) => {
219
- const parts = relPathNoExt.split(path.sep);
220
- if (parts[parts.length - 1] === "index")
221
- parts.pop();
222
- return parts.join(path.sep);
223
- };
224
202
 
225
203
  // pkgs/@akanjs/devkit/transforms/barrelImportsPlugin.ts
226
204
  import path2 from "path";
@@ -239,13 +217,10 @@ var createBarrelImportsPlugin = async (app, { skipPath = defaultSkipPath, pipeAf
239
217
  }, async (args) => {
240
218
  const realPath = args.path.replace(/\?v=\d+$/, "");
241
219
  const loader = loaderFor(realPath);
242
- if (skipPath(realPath)) {
243
- const raw = await Bun.file(realPath).text();
244
- return { contents: raw, loader };
245
- }
246
220
  let source = await Bun.file(realPath).text();
247
- const hasMacroAttr = MACRO_ATTR_RE.test(source);
248
- if (!hasMacroAttr && barrels.length > 0) {
221
+ if (skipPath(realPath))
222
+ return { contents: source, loader };
223
+ if (!MACRO_ATTR_RE.test(source) && barrels.length > 0) {
249
224
  const rewritten = await rewriteBarrelImports(source, barrels, analyzer);
250
225
  if (rewritten !== null)
251
226
  source = rewritten;
@@ -263,10 +238,7 @@ var createBarrelImportsPlugin = async (app, { skipPath = defaultSkipPath, pipeAf
263
238
  var createTsconfigPackageResolver = async (app) => {
264
239
  const tsconfig = await app.getTsConfig();
265
240
  const tsconfigPaths = tsconfig.compilerOptions.paths ?? {};
266
- const wildcardEntries = Object.entries(tsconfigPaths).filter(([k]) => k.endsWith("/*")).map(([k, v]) => ({
267
- prefix: k.slice(0, -1),
268
- replacements: v
269
- })).sort((a, b) => b.prefix.length - a.prefix.length);
241
+ const wildcardEntries = Object.entries(tsconfigPaths).filter(([k]) => k.endsWith("/*")).map(([k, v]) => ({ prefix: k.slice(0, -1), replacements: v })).sort((a, b) => b.prefix.length - a.prefix.length);
270
242
  return async (pkgName) => {
271
243
  const exact = tsconfigPaths[pkgName];
272
244
  if (exact && exact.length > 0) {
@@ -278,13 +250,8 @@ var createTsconfigPackageResolver = async (app) => {
278
250
  return null;
279
251
  const parsed = path2.parse(entryFile);
280
252
  const lastSlash = pkgName.lastIndexOf("/");
281
- if (parsed.name !== "index" && lastSlash !== -1) {
282
- const facet = pkgName.slice(lastSlash + 1);
283
- const parentSpec = pkgName.slice(0, lastSlash);
284
- if (facet === parsed.name && parentSpec.length > 0) {
285
- return { pkgName: parentSpec, entryFile, pkgDir: parsed.dir };
286
- }
287
- }
253
+ if (parsed.name !== "index" && lastSlash > 0 && pkgName.slice(lastSlash + 1) === parsed.name)
254
+ return { pkgName: pkgName.slice(0, lastSlash), entryFile, pkgDir: parsed.dir };
288
255
  return { pkgName, entryFile, pkgDir: path2.dirname(entryFile) };
289
256
  }
290
257
  for (const { prefix, replacements } of wildcardEntries) {
@@ -300,20 +267,14 @@ var createTsconfigPackageResolver = async (app) => {
300
267
  const file = `${candidate}${ext}`;
301
268
  if (await Bun.file(file).exists()) {
302
269
  const lastSlash = pkgName.lastIndexOf("/");
303
- if (lastSlash !== -1) {
304
- const parentSpec = pkgName.slice(0, lastSlash);
305
- if (parentSpec.length > 0) {
306
- return { pkgName: parentSpec, entryFile: file, pkgDir: path2.dirname(file) };
307
- }
308
- }
309
- return { pkgName, entryFile: file, pkgDir: path2.dirname(file) };
270
+ const parentSpec = lastSlash > 0 ? pkgName.slice(0, lastSlash) : pkgName;
271
+ return { pkgName: parentSpec, entryFile: file, pkgDir: path2.dirname(file) };
310
272
  }
311
273
  }
312
274
  for (const ext of CANDIDATE_EXTS2) {
313
275
  const file = path2.join(candidate, `index${ext}`);
314
- if (await Bun.file(file).exists()) {
276
+ if (await Bun.file(file).exists())
315
277
  return { pkgName, entryFile: file, pkgDir: candidate };
316
- }
317
278
  }
318
279
  }
319
280
  return null;
@@ -358,8 +319,7 @@ var resolveNodePackageExport = async (workspaceRoot, specifier) => {
358
319
  const entryFile = await resolveFileCandidate(path2.resolve(pkgDir, rel));
359
320
  if (!entryFile)
360
321
  return null;
361
- const pkgEntryName = specifier;
362
- return { pkgName: pkgEntryName, entryFile, pkgDir: path2.dirname(entryFile), preserveFilePath: true };
322
+ return { pkgName: specifier, entryFile, pkgDir: path2.dirname(entryFile), preserveFilePath: true };
363
323
  } catch {
364
324
  return null;
365
325
  }
@@ -467,15 +427,11 @@ var findImportStatements = (source) => {
467
427
  const importClause = statement.importClause;
468
428
  if (!importClause)
469
429
  continue;
470
- const statementStart = statement.getStart(sourceFile);
471
- const statementEnd = statement.end;
472
430
  statements.push({
473
- start: statementStart,
474
- end: statementEnd,
431
+ start: statement.getStart(sourceFile),
432
+ end: statement.end,
475
433
  clause: source.slice(importClause.getStart(sourceFile), importClause.end).trim(),
476
- specifier: statement.moduleSpecifier.text,
477
- trailingSemicolon: source.slice(statement.moduleSpecifier.end, statement.end).includes(";"),
478
- raw: source.slice(statementStart, statementEnd)
434
+ specifier: statement.moduleSpecifier.text
479
435
  });
480
436
  }
481
437
  return statements;
@@ -507,35 +463,10 @@ var parseImportClause = (clause) => {
507
463
  const close = rest.indexOf("}");
508
464
  if (close === -1)
509
465
  return null;
510
- const inner = rest.slice(1, close);
511
- parsed.named = parseNamedImportList(inner);
512
- return parsed;
466
+ parsed.named = parseNamedList(rest.slice(1, close));
513
467
  }
514
468
  return parsed;
515
469
  };
516
- var parseNamedImportList = (body) => {
517
- const out = [];
518
- for (const raw of body.split(",")) {
519
- const s = raw.trim();
520
- if (!s)
521
- continue;
522
- let isType = false;
523
- let rest = s;
524
- if (rest.startsWith("type ")) {
525
- isType = true;
526
- rest = rest.slice(5).trim();
527
- }
528
- const asMatch = /^(\w+)\s+as\s+(\w+)$/.exec(rest);
529
- if (asMatch) {
530
- out.push({ imported: asMatch[1] ?? "", local: asMatch[2] ?? "", isType });
531
- continue;
532
- }
533
- if (/^\w+$/.test(rest)) {
534
- out.push({ imported: rest, local: rest, isType });
535
- }
536
- }
537
- return out;
538
- };
539
470
  var rewriteSingleStatement = (stmt, map) => {
540
471
  const clause = parseImportClause(stmt.clause);
541
472
  if (!clause)
@@ -544,9 +475,8 @@ var rewriteSingleStatement = (stmt, map) => {
544
475
  return null;
545
476
  if (clause.typeOnly && !clause.defaultImport)
546
477
  return null;
547
- if (!clause.named || clause.named.length === 0) {
478
+ if (!clause.named?.length)
548
479
  return null;
549
- }
550
480
  const remaining = [];
551
481
  const rewrites = new Map;
552
482
  for (const item of clause.named) {
@@ -566,21 +496,18 @@ var rewriteSingleStatement = (stmt, map) => {
566
496
  if (rewrites.size === 0)
567
497
  return null;
568
498
  const lines = [];
569
- const tail = ";";
570
- if (shouldPreserveBarrelSideEffects(stmt.specifier)) {
571
- lines.push(`import "${stmt.specifier}"${tail}`);
572
- }
499
+ if (shouldPreserveBarrelSideEffects(stmt.specifier))
500
+ lines.push(`import "${stmt.specifier}";`);
573
501
  if (clause.defaultImport || remaining.length > 0) {
574
502
  const parts = [];
575
503
  if (clause.defaultImport)
576
504
  parts.push(clause.defaultImport);
577
- if (remaining.length > 0) {
505
+ if (remaining.length > 0)
578
506
  parts.push(`{ ${remaining.map(serializeNamedItem).join(", ")} }`);
579
- }
580
- lines.push(`import ${parts.join(", ")} from "${stmt.specifier}"${tail}`);
507
+ lines.push(`import ${parts.join(", ")} from "${stmt.specifier}";`);
581
508
  }
582
509
  for (const [subpath, items] of rewrites) {
583
- lines.push(`import { ${items.map(serializeNamedItem).join(", ")} } from "${subpath}"${tail}`);
510
+ lines.push(`import { ${items.map(serializeNamedItem).join(", ")} } from "${subpath}";`);
584
511
  }
585
512
  return lines.join(`
586
513
  `);
@@ -592,19 +519,9 @@ var serializeNamedItem = (item) => {
592
519
  return `${prefix}${item.imported}`;
593
520
  return `${prefix}${item.imported} as ${item.local}`;
594
521
  };
595
- var loaderFor = (absPath) => {
596
- if (absPath.endsWith(".tsx"))
597
- return "tsx";
598
- if (absPath.endsWith(".jsx"))
599
- return "jsx";
600
- if (absPath.endsWith(".ts"))
601
- return "ts";
602
- return "js";
603
- };
604
522
 
605
523
  // pkgs/@akanjs/devkit/frontendBuild/clientEntryDiscovery.ts
606
524
  var USE_CLIENT_RE = /^\s*(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*["']use client["']/;
607
- var SOURCE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
608
525
  var NODE_MODULES_RE2 = /[\\/]node_modules[\\/]/;
609
526
  var AKANJS_NODE_MODULE_RE2 = /[\\/]node_modules[\\/]akanjs[\\/]/;
610
527
  var NON_SOURCE_EXT_RE = /\.(css|scss|sass|less|json|svg|png|jpe?g|webp|gif|avif|ico|woff2?|ttf|otf|mp3|mp4|wav)$/i;
@@ -796,18 +713,30 @@ import path6 from "path";
796
713
 
797
714
  // pkgs/@akanjs/devkit/transforms/rscUseClientTransform.ts
798
715
  import path4 from "path";
716
+ import ts2 from "typescript";
799
717
  var USE_CLIENT_RE2 = /^\s*(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*["']use client["']/;
800
718
  var IMPLICIT_ROOT_LAYOUT_RE = /[/\\]\.akan[/\\]generated[/\\](?:implicit-root-layout|root-layouts[/\\].*__root_layout)\.(tsx|ts|jsx|js)$/;
719
+ var STAR_REEXPORT_HINT_RE = /\bexport\s*\*\s*from\b/;
801
720
  function toClientReferencePath(absPath, workspaceRoot) {
802
721
  return path4.relative(path4.resolve(workspaceRoot), path4.resolve(absPath)).split(path4.sep).join("/");
803
722
  }
723
+ var starReexportSpecifiers = (source, filePath) => ts2.createSourceFile(filePath, source, ts2.ScriptTarget.Latest).statements.filter((statement) => ts2.isExportDeclaration(statement) && !statement.exportClause && !statement.isTypeOnly && !!statement.moduleSpecifier && ts2.isStringLiteral(statement.moduleSpecifier)).map((statement) => statement.moduleSpecifier.text);
724
+ var scanUseClientExports = (source, filePath, workspaceRoot) => {
725
+ const stars = USE_CLIENT_RE2.test(source) && STAR_REEXPORT_HINT_RE.test(source) ? starReexportSpecifiers(source, filePath) : [];
726
+ if (stars.length) {
727
+ const file = workspaceRoot ? toClientReferencePath(filePath, workspaceRoot) : filePath;
728
+ const listed = stars.slice(0, 3).map((specifier) => `\`export * from ${JSON.stringify(specifier)}\``);
729
+ const written = stars.length > 3 ? `${listed.join(", ")} (and ${stars.length - 3} more)` : listed.join(", ");
730
+ throw new Error(`${file} is a "use client" module, so it cannot ${written}: the server sees only the names a client module ` + `declares, and a star re-export declares none. Re-export them by name \u2014 \`export { \u2026 } from ${JSON.stringify(stars[0])}\`.`);
731
+ }
732
+ return new Bun.Transpiler({ loader: loaderFor(filePath) }).scan(source).exports;
733
+ };
804
734
  function transformUseClient(source, args) {
805
735
  if (!USE_CLIENT_RE2.test(source))
806
736
  return null;
807
737
  if (IMPLICIT_ROOT_LAYOUT_RE.test(args.path))
808
738
  return null;
809
- const transpiler = new Bun.Transpiler({ loader: loaderFor2(args.path) });
810
- const { exports } = transpiler.scan(source);
739
+ const exports = scanUseClientExports(source, args.path, args.workspaceRoot);
811
740
  if (exports.length === 0)
812
741
  return null;
813
742
  const referencePath = args.workspaceRoot ? toClientReferencePath(args.path, args.workspaceRoot) : args.path;
@@ -823,20 +752,21 @@ function transformUseClient(source, args) {
823
752
  return lines.join(`
824
753
  `);
825
754
  }
826
- function loaderFor2(absPath) {
827
- if (absPath.endsWith(".tsx"))
828
- return "tsx";
829
- if (absPath.endsWith(".jsx"))
830
- return "jsx";
831
- if (absPath.endsWith(".ts"))
832
- return "ts";
833
- return "js";
834
- }
835
755
 
836
756
  // pkgs/@akanjs/devkit/frontendBuild/clientEntriesBundler.ts
837
757
  import fs from "fs";
838
758
  import path5 from "path";
839
759
 
760
+ // pkgs/@akanjs/devkit/frontendBuild/bundleDefine.ts
761
+ var bundleDefine = (app, command, renderEnv) => {
762
+ const nodeEnv = command === "build" ? "production" : "development";
763
+ return {
764
+ "process.env.NODE_ENV": JSON.stringify(nodeEnv),
765
+ "process.env.AKAN_PUBLIC_RENDER_ENV": JSON.stringify(renderEnv),
766
+ ...Object.fromEntries(Object.entries(app.getPublicEnv()).map(([key, value]) => [`process.env.${key}`, JSON.stringify(value)]))
767
+ };
768
+ };
769
+
840
770
  // pkgs/@akanjs/devkit/frontendBuild/clientBuildTypes.ts
841
771
  var CLIENT_BUNDLE_NAMING = {
842
772
  entry: "[name]-[hash].[ext]",
@@ -856,7 +786,6 @@ class ClientEntriesBundler {
856
786
  #target;
857
787
  #outputSubdir;
858
788
  #reactFastRefresh;
859
- #artifactDir;
860
789
  #outdir;
861
790
  #servePrefix;
862
791
  #manifest = {};
@@ -878,8 +807,8 @@ class ClientEntriesBundler {
878
807
  this.#target = options.target ?? "browser";
879
808
  this.#outputSubdir = options.outputSubdir ?? "client";
880
809
  this.#reactFastRefresh = options.reactFastRefresh ?? false;
881
- this.#artifactDir = `${this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath}/.akan/artifact`;
882
- this.#outdir = `${this.#artifactDir}/${this.#outputSubdir}`;
810
+ const artifactDir = `${this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath}/.akan/artifact`;
811
+ this.#outdir = `${artifactDir}/${this.#outputSubdir}`;
883
812
  this.#servePrefix = `/_akan/${this.#outputSubdir}`;
884
813
  }
885
814
  async bundle() {
@@ -893,7 +822,7 @@ class ClientEntriesBundler {
893
822
  format: "esm",
894
823
  naming: CLIENT_BUNDLE_NAMING,
895
824
  metafile: true,
896
- define: this.#getDefine(),
825
+ define: bundleDefine(this.#app, this.#command, "ssr"),
897
826
  minify: this.#command === "build",
898
827
  optimizeImports: akanConfig.optimizeImports,
899
828
  reactFastRefresh: this.#command === "start" && this.#outputSubdir === "client" && this.#reactFastRefresh,
@@ -917,14 +846,6 @@ class ClientEntriesBundler {
917
846
  clientReferenceIdByAbsPath: this.#clientReferenceIdByAbsPath
918
847
  };
919
848
  }
920
- #getDefine() {
921
- const nodeEnv = this.#command === "build" ? "production" : "development";
922
- return {
923
- "process.env.NODE_ENV": JSON.stringify(nodeEnv),
924
- "process.env.AKAN_PUBLIC_RENDER_ENV": JSON.stringify("ssr"),
925
- ...Object.fromEntries(Object.entries(this.#app.getPublicEnv()).map(([key, value]) => [`process.env.${key}`, JSON.stringify(value)]))
926
- };
927
- }
928
849
  async#createOpaqueEntryAliases() {
929
850
  const aliasDir = path5.join(this.#app.cwdPath, ".akan", "generated", "client-entry-alias", this.#outputSubdir);
930
851
  fs.mkdirSync(aliasDir, { recursive: true });
@@ -955,18 +876,7 @@ ${absEntry}`).toString(36);
955
876
  `;
956
877
  }
957
878
  async#scanEntryExportNames(absEntry) {
958
- const source = await Bun.file(absEntry).text();
959
- const transpiler = new Bun.Transpiler({ loader: this.#loaderForEntry(absEntry) });
960
- return transpiler.scan(source).exports;
961
- }
962
- #loaderForEntry(absPath) {
963
- if (absPath.endsWith(".tsx"))
964
- return "tsx";
965
- if (absPath.endsWith(".jsx"))
966
- return "jsx";
967
- if (absPath.endsWith(".ts"))
968
- return "ts";
969
- return "js";
879
+ return scanUseClientExports(await Bun.file(absEntry).text(), absEntry, this.#app.workspace.workspaceRoot);
970
880
  }
971
881
  #createExternalSpecifiersPlugin() {
972
882
  const set = new Set(this.#external);
@@ -990,14 +900,11 @@ ${absEntry}`).toString(36);
990
900
  };
991
901
  }
992
902
  static #matchesExternalSpecifier(specifier, exactExternals, subpathExternals) {
993
- if (exactExternals.has(specifier))
903
+ if (exactExternals.has(specifier) || subpathExternals.has(specifier))
994
904
  return true;
995
- if (subpathExternals.has(specifier))
996
- return true;
997
- for (const external of subpathExternals) {
905
+ for (const external of subpathExternals)
998
906
  if (specifier.startsWith(`${external}/`))
999
907
  return true;
1000
- }
1001
908
  return false;
1002
909
  }
1003
910
  async#rewriteExternalImportSpecifiers(outputs) {
@@ -1128,14 +1035,6 @@ var VENDOR_SPECIFIERS = [
1128
1035
  ];
1129
1036
 
1130
1037
  // pkgs/@akanjs/devkit/frontendBuild/routeClientBuilder.ts
1131
- var SSR_CLIENT_EXTERNALS = [
1132
- "react",
1133
- "react-dom",
1134
- "react-dom/client",
1135
- "react/jsx-runtime",
1136
- "react/jsx-dev-runtime",
1137
- "akanjs/fetch"
1138
- ];
1139
1038
  var SSR_CLIENT_ALIAS_EXTERNALS = [
1140
1039
  "react",
1141
1040
  "react-dom",
@@ -1143,10 +1042,12 @@ var SSR_CLIENT_ALIAS_EXTERNALS = [
1143
1042
  "react/jsx-runtime",
1144
1043
  "react/jsx-dev-runtime"
1145
1044
  ];
1045
+ var SSR_CLIENT_EXTERNALS = [...SSR_CLIENT_ALIAS_EXTERNALS, "akanjs/fetch"];
1146
1046
 
1147
1047
  class RouteClientBuilder {
1148
1048
  #app;
1149
1049
  #seeds;
1050
+ #graphSeeds;
1150
1051
  #knownEntries;
1151
1052
  #command;
1152
1053
  #discovery;
@@ -1154,20 +1055,22 @@ class RouteClientBuilder {
1154
1055
  constructor(options) {
1155
1056
  this.#app = options.app;
1156
1057
  this.#seeds = options.seeds;
1058
+ this.#graphSeeds = options.graphSeeds;
1157
1059
  this.#knownEntries = options.knownEntries ?? new Set;
1158
1060
  this.#command = options.command ?? "start";
1159
1061
  this.#discovery = options.discovery;
1160
1062
  this.#entries = options.entries;
1161
1063
  }
1162
1064
  async build() {
1163
- const discovered = this.#entries ?? await (this.#discovery ?? await GraphClientEntryDiscovery.create(this.#app)).discover(this.#seeds);
1164
- const entries = discovered.filter((e) => !this.#knownEntries.has(e));
1165
- if (entries.length === 0)
1065
+ const discovered = this.#entries ?? await (await this.#getDiscovery()).discover(this.#seeds);
1066
+ if (discovered.every((e) => this.#knownEntries.has(e)))
1166
1067
  return this.#emptyResult(discovered);
1068
+ const entries = this.#graphSeeds ? [...new Set([...discovered, ...await (await this.#getDiscovery()).discover(this.#graphSeeds)])].sort() : discovered.filter((e) => !this.#knownEntries.has(e));
1167
1069
  const bootstrapEntries = await this.#createBootstrapEntries(entries);
1168
1070
  const browserBundle = await this.#buildBrowserBundle(bootstrapEntries);
1169
1071
  const ssrBundle = await this.#buildSsrBundle(bootstrapEntries);
1170
1072
  const acceptedEntries = new Set(entries);
1073
+ const routeEntries = new Set(discovered);
1171
1074
  const manifestDelta = {};
1172
1075
  const ssrModuleMap = {};
1173
1076
  const clientDeps = new Set;
@@ -1195,18 +1098,23 @@ class RouteClientBuilder {
1195
1098
  deps.add(path6.resolve(dep));
1196
1099
  const sortedDeps = [...deps].sort();
1197
1100
  clientDepsByEntry[originalEntry] = sortedDeps;
1198
- for (const dep of sortedDeps)
1199
- clientDeps.add(dep);
1101
+ if (routeEntries.has(originalEntry))
1102
+ for (const dep of sortedDeps)
1103
+ clientDeps.add(dep);
1200
1104
  }
1201
1105
  return {
1202
1106
  manifestDelta,
1203
1107
  ssrManifestDelta: { moduleLoading: null, moduleMap: ssrModuleMap },
1204
- newEntries: entries,
1108
+ newEntries: entries.filter((e) => !this.#knownEntries.has(e)),
1205
1109
  discoveredEntries: discovered,
1206
1110
  clientDeps: [...clientDeps].sort(),
1207
1111
  clientDepsByEntry
1208
1112
  };
1209
1113
  }
1114
+ async#getDiscovery() {
1115
+ this.#discovery ??= await GraphClientEntryDiscovery.create(this.#app);
1116
+ return this.#discovery;
1117
+ }
1210
1118
  #emptyResult(discoveredEntries = []) {
1211
1119
  return {
1212
1120
  manifestDelta: {},
@@ -1267,18 +1175,7 @@ ${absEntry}`).toString(36);
1267
1175
  return { buildEntries, originalByBuildEntry };
1268
1176
  }
1269
1177
  async#scanExportNames(absEntry) {
1270
- const source = await Bun.file(absEntry).text();
1271
- const transpiler = new Bun.Transpiler({ loader: this.#loaderFor(absEntry) });
1272
- return transpiler.scan(source).exports;
1273
- }
1274
- #loaderFor(absPath) {
1275
- if (absPath.endsWith(".tsx"))
1276
- return "tsx";
1277
- if (absPath.endsWith(".jsx"))
1278
- return "jsx";
1279
- if (absPath.endsWith(".ts"))
1280
- return "ts";
1281
- return "js";
1178
+ return scanUseClientExports(await Bun.file(absEntry).text(), absEntry, this.#app.workspace.workspaceRoot);
1282
1179
  }
1283
1180
  static normalizeNamedDefaultFunctionForFastRefresh(source) {
1284
1181
  let changed = false;
@@ -1346,7 +1243,7 @@ ${defaultNames.map((name) => `export default ${name};`).join(`
1346
1243
  // pkgs/@akanjs/devkit/frontendBuild/autoImportSync.ts
1347
1244
  import { readdir, readFile, stat } from "fs/promises";
1348
1245
  import path7 from "path";
1349
- import ts2 from "typescript";
1246
+ import ts3 from "typescript";
1350
1247
  var TEST_FILE_RE = /\.(test|spec)\.(ts|tsx)$/;
1351
1248
  var AKAN_BASE = {
1352
1249
  names: ["Int", "Float", "ID", "Any", "Upload", "enumOf", "dayjs"],
@@ -1440,6 +1337,7 @@ var LIB_BARRELS = {
1440
1337
  cnst: { barrel: "cnst", kind: "namespace" },
1441
1338
  srv: { barrel: "srv", kind: "namespace" }
1442
1339
  };
1340
+ var GLOBAL_NAMES = new Set(["fetch"]);
1443
1341
  var DOMAIN_DENYLIST = new Set([
1444
1342
  "Map",
1445
1343
  "Set",
@@ -1538,7 +1436,7 @@ class AutoImportSync {
1538
1436
  const next = transformSource(source, abs, ctx, resolveExtra);
1539
1437
  if (next === null || next === source)
1540
1438
  return false;
1541
- await FileSys.writeTextAtomic(abs, next);
1439
+ await FileSys2.writeTextAtomic(abs, next);
1542
1440
  return true;
1543
1441
  }
1544
1442
  async#extraResolverFor(abs, ctx) {
@@ -1639,13 +1537,14 @@ var targetFor = (symbol, ctx) => {
1639
1537
  return null;
1640
1538
  };
1641
1539
  var transformSource = (source, fileName, ctx, resolveExtra) => {
1642
- const sf = ts2.createSourceFile(fileName, source, ts2.ScriptTarget.Latest, true, scriptKindFor(fileName));
1540
+ const sf = ts3.createSourceFile(fileName, source, ts3.ScriptTarget.Latest, true, scriptKindFor(fileName));
1643
1541
  const bound = collectBoundNames(sf);
1644
1542
  const used = collectUsedReferences(sf);
1543
+ const bareGlobals = collectBareGlobalReferences(sf);
1645
1544
  const namedBySpecifier = new Map;
1646
1545
  const namespaceImports = [];
1647
1546
  for (const name of used) {
1648
- if (bound.has(name))
1547
+ if (bound.has(name) || bareGlobals.has(name))
1649
1548
  continue;
1650
1549
  const target = targetFor(name, ctx) ?? resolveExtra?.(name) ?? null;
1651
1550
  if (!target)
@@ -1660,7 +1559,7 @@ var transformSource = (source, fileName, ctx, resolveExtra) => {
1660
1559
  }
1661
1560
  if (namedBySpecifier.size === 0 && namespaceImports.length === 0)
1662
1561
  return null;
1663
- const importDecls = sf.statements.filter(ts2.isImportDeclaration);
1562
+ const importDecls = sf.statements.filter(ts3.isImportDeclaration);
1664
1563
  const anchor = importDecls.at(-1) ?? null;
1665
1564
  const namedImportsBySpecifier = collectExistingNamedImports(importDecls);
1666
1565
  const edits = [];
@@ -1716,48 +1615,61 @@ ${newStatements.join(`
1716
1615
  var collectBoundNames = (sf) => {
1717
1616
  const names = new Set;
1718
1617
  const visit = (node) => {
1719
- if (ts2.isImportClause(node)) {
1618
+ if (ts3.isImportClause(node)) {
1720
1619
  if (node.name)
1721
1620
  names.add(node.name.text);
1722
1621
  const bindings = node.namedBindings;
1723
- if (bindings && ts2.isNamespaceImport(bindings))
1622
+ if (bindings && ts3.isNamespaceImport(bindings))
1724
1623
  names.add(bindings.name.text);
1725
- if (bindings && ts2.isNamedImports(bindings))
1624
+ if (bindings && ts3.isNamedImports(bindings))
1726
1625
  for (const el of bindings.elements)
1727
1626
  names.add(el.name.text);
1728
1627
  }
1729
- if ((ts2.isVariableDeclaration(node) || ts2.isFunctionDeclaration(node) || ts2.isClassDeclaration(node) || ts2.isParameter(node) || ts2.isBindingElement(node) || ts2.isEnumDeclaration(node) || ts2.isTypeAliasDeclaration(node) || ts2.isInterfaceDeclaration(node)) && node.name && ts2.isIdentifier(node.name))
1628
+ if ((ts3.isVariableDeclaration(node) || ts3.isFunctionDeclaration(node) || ts3.isClassDeclaration(node) || ts3.isParameter(node) || ts3.isBindingElement(node) || ts3.isEnumDeclaration(node) || ts3.isTypeAliasDeclaration(node) || ts3.isInterfaceDeclaration(node)) && node.name && ts3.isIdentifier(node.name))
1730
1629
  names.add(node.name.text);
1731
- ts2.forEachChild(node, visit);
1630
+ ts3.forEachChild(node, visit);
1732
1631
  };
1733
- ts2.forEachChild(sf, visit);
1632
+ ts3.forEachChild(sf, visit);
1734
1633
  return names;
1735
1634
  };
1736
1635
  var collectUsedReferences = (sf) => {
1737
1636
  const used = new Set;
1738
1637
  const visit = (node) => {
1739
- if (ts2.isIdentifier(node) && isReferencePosition(node))
1638
+ if (ts3.isIdentifier(node) && isReferencePosition(node))
1740
1639
  used.add(node.text);
1741
- ts2.forEachChild(node, visit);
1640
+ ts3.forEachChild(node, visit);
1742
1641
  };
1743
- ts2.forEachChild(sf, visit);
1642
+ ts3.forEachChild(sf, visit);
1744
1643
  return used;
1745
1644
  };
1645
+ var collectBareGlobalReferences = (sf) => {
1646
+ const bare = new Set;
1647
+ const visit = (node) => {
1648
+ if (ts3.isIdentifier(node) && GLOBAL_NAMES.has(node.text) && isReferencePosition(node)) {
1649
+ const parent = node.parent;
1650
+ if (!(parent && ts3.isPropertyAccessExpression(parent) && parent.expression === node))
1651
+ bare.add(node.text);
1652
+ }
1653
+ ts3.forEachChild(node, visit);
1654
+ };
1655
+ ts3.forEachChild(sf, visit);
1656
+ return bare;
1657
+ };
1746
1658
  var isReferencePosition = (node) => {
1747
1659
  const parent = node.parent;
1748
1660
  if (!parent)
1749
1661
  return true;
1750
- if (ts2.isPropertyAccessExpression(parent) && parent.name === node)
1662
+ if (ts3.isPropertyAccessExpression(parent) && parent.name === node)
1751
1663
  return false;
1752
- if (ts2.isQualifiedName(parent) && parent.right === node)
1664
+ if (ts3.isQualifiedName(parent) && parent.right === node)
1753
1665
  return false;
1754
- if (ts2.isPropertyAssignment(parent) && parent.name === node)
1666
+ if (ts3.isPropertyAssignment(parent) && parent.name === node)
1755
1667
  return false;
1756
- if (ts2.isPropertySignature(parent) && parent.name === node)
1668
+ if (ts3.isPropertySignature(parent) && parent.name === node)
1757
1669
  return false;
1758
- if (ts2.isBindingElement(parent) && parent.propertyName === node)
1670
+ if (ts3.isBindingElement(parent) && parent.propertyName === node)
1759
1671
  return false;
1760
- if (ts2.isImportSpecifier(parent) || ts2.isExportSpecifier(parent))
1672
+ if (ts3.isImportSpecifier(parent) || ts3.isExportSpecifier(parent))
1761
1673
  return false;
1762
1674
  return true;
1763
1675
  };
@@ -1766,9 +1678,9 @@ var collectExistingNamedImports = (importDecls) => {
1766
1678
  for (const decl of importDecls) {
1767
1679
  const clause = decl.importClause;
1768
1680
  const bindings = clause?.namedBindings;
1769
- if (!clause || !bindings || !ts2.isNamedImports(bindings))
1681
+ if (!clause || !bindings || !ts3.isNamedImports(bindings))
1770
1682
  continue;
1771
- if (!ts2.isStringLiteral(decl.moduleSpecifier))
1683
+ if (!ts3.isStringLiteral(decl.moduleSpecifier))
1772
1684
  continue;
1773
1685
  const specifier = decl.moduleSpecifier.text;
1774
1686
  if (map.has(specifier))
@@ -1790,14 +1702,14 @@ var formatNamedImport = (specifier, names) => {
1790
1702
  var directivePrologueEnd = (sf) => {
1791
1703
  let end = -1;
1792
1704
  for (const stmt of sf.statements) {
1793
- if (ts2.isExpressionStatement(stmt) && ts2.isStringLiteral(stmt.expression))
1705
+ if (ts3.isExpressionStatement(stmt) && ts3.isStringLiteral(stmt.expression))
1794
1706
  end = stmt.getEnd();
1795
1707
  else
1796
1708
  break;
1797
1709
  }
1798
1710
  return end;
1799
1711
  };
1800
- var scriptKindFor = (fileName) => fileName.endsWith(".tsx") ? ts2.ScriptKind.TSX : ts2.ScriptKind.TS;
1712
+ var scriptKindFor = (fileName) => fileName.endsWith(".tsx") ? ts3.ScriptKind.TSX : ts3.ScriptKind.TS;
1801
1713
  var compareNames = (a, b) => {
1802
1714
  const [la, lb] = [a.toLowerCase(), b.toLowerCase()];
1803
1715
  if (la !== lb)
@@ -1847,18 +1759,18 @@ var collectDomainFiles = async (dir) => {
1847
1759
  return files;
1848
1760
  };
1849
1761
  var exportedPascalNames = (source, fileName) => {
1850
- const sf = ts2.createSourceFile(fileName, source, ts2.ScriptTarget.Latest, true);
1851
- const isExported = (node) => ts2.canHaveModifiers(node) && (ts2.getModifiers(node) ?? []).some((m) => m.kind === ts2.SyntaxKind.ExportKeyword);
1762
+ const sf = ts3.createSourceFile(fileName, source, ts3.ScriptTarget.Latest, true);
1763
+ const isExported = (node) => ts3.canHaveModifiers(node) && (ts3.getModifiers(node) ?? []).some((m) => m.kind === ts3.SyntaxKind.ExportKeyword);
1852
1764
  const names = [];
1853
1765
  for (const stmt of sf.statements) {
1854
- if ((ts2.isClassDeclaration(stmt) || ts2.isFunctionDeclaration(stmt) || ts2.isEnumDeclaration(stmt)) && stmt.name) {
1766
+ if ((ts3.isClassDeclaration(stmt) || ts3.isFunctionDeclaration(stmt) || ts3.isEnumDeclaration(stmt)) && stmt.name) {
1855
1767
  if (isExported(stmt))
1856
1768
  names.push(stmt.name.text);
1857
- } else if (ts2.isVariableStatement(stmt) && isExported(stmt)) {
1769
+ } else if (ts3.isVariableStatement(stmt) && isExported(stmt)) {
1858
1770
  for (const decl of stmt.declarationList.declarations)
1859
- if (ts2.isIdentifier(decl.name))
1771
+ if (ts3.isIdentifier(decl.name))
1860
1772
  names.push(decl.name.text);
1861
- } else if (ts2.isExportDeclaration(stmt) && stmt.exportClause && ts2.isNamedExports(stmt.exportClause)) {
1773
+ } else if (ts3.isExportDeclaration(stmt) && stmt.exportClause && ts3.isNamedExports(stmt.exportClause)) {
1862
1774
  for (const el of stmt.exportClause.elements)
1863
1775
  names.push(el.name.text);
1864
1776
  }
@@ -1872,7 +1784,6 @@ var relativeSpecifier = (fromDir, toFile) => {
1872
1784
 
1873
1785
  // pkgs/@akanjs/devkit/frontendBuild/devChangePlanner.ts
1874
1786
  import path8 from "path";
1875
- var SOURCE_EXTS2 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
1876
1787
  var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
1877
1788
  var BARREL_FACETS = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
1878
1789
  var CLIENT_SUFFIXES = [".Template.tsx", ".Unit.tsx", ".Util.tsx", ".View.tsx", ".Zone.tsx", ".store.ts"];
@@ -1934,7 +1845,7 @@ class DevChangePlanner {
1934
1845
  const abs = path8.resolve(file);
1935
1846
  const base = path8.basename(abs);
1936
1847
  const ext = path8.extname(abs).toLowerCase();
1937
- const isSource = SOURCE_EXTS2.has(ext);
1848
+ const isSource = SOURCE_EXTS.has(ext);
1938
1849
  const rel = path8.relative(this.#workspaceRoot, abs);
1939
1850
  const parts = rel.split(path8.sep).filter(Boolean);
1940
1851
  if (CONFIG_BASENAMES.has(base)) {
@@ -1949,15 +1860,15 @@ class DevChangePlanner {
1949
1860
  roles.add("barrel");
1950
1861
  reasons.add(isGenerated ? "generated-index" : "barrel-facet-child");
1951
1862
  }
1952
- if (isSource && this.#isServerBiased(abs, parts)) {
1863
+ if (isSource && this.#isServerBiased(base, parts)) {
1953
1864
  roles.add("server");
1954
1865
  reasons.add("server-path");
1955
1866
  }
1956
- if (isSource && this.#isClientBiased(abs, parts)) {
1867
+ if (isSource && this.#isClientBiased(base, parts)) {
1957
1868
  roles.add("client");
1958
1869
  reasons.add("client-path");
1959
1870
  }
1960
- if (isSource && this.#isSharedBiased(abs, parts)) {
1871
+ if (isSource && this.#isSharedBiased(base, parts)) {
1961
1872
  roles.add("shared");
1962
1873
  reasons.add("shared-path");
1963
1874
  }
@@ -1970,22 +1881,19 @@ class DevChangePlanner {
1970
1881
  roles.add("shared");
1971
1882
  reasons.add("server-client-overlap");
1972
1883
  }
1973
- if (roles.size === 0 && SOURCE_EXTS2.has(ext) && this.#isWorkspaceSource(rel)) {
1884
+ if (roles.size === 0 && SOURCE_EXTS.has(ext) && this.#isWorkspaceSource(rel)) {
1974
1885
  roles.add("shared");
1975
1886
  reasons.add("workspace-source-fallback");
1976
1887
  }
1977
1888
  return roles;
1978
1889
  }
1979
- #isServerBiased(abs, parts) {
1980
- const base = path8.basename(abs);
1890
+ #isServerBiased(base, parts) {
1981
1891
  return parts.includes("srvkit") || SERVER_SUFFIXES.some((suffix) => base.endsWith(suffix)) || base === "main.ts" || base === "server.ts";
1982
1892
  }
1983
- #isClientBiased(abs, parts) {
1984
- const base = path8.basename(abs);
1893
+ #isClientBiased(base, parts) {
1985
1894
  return parts.includes("ui") || parts.includes("webkit") || parts.includes("page") || CLIENT_SUFFIXES.some((suffix) => base.endsWith(suffix));
1986
1895
  }
1987
- #isSharedBiased(abs, parts) {
1988
- const base = path8.basename(abs);
1896
+ #isSharedBiased(base, parts) {
1989
1897
  return parts.includes("common") || SHARED_SUFFIXES.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES.has(base);
1990
1898
  }
1991
1899
  #isRuntimeMetadataFile(parts, base) {
@@ -2021,6 +1929,7 @@ var uniqueResolved = (files) => [...new Set(files.map((file) => path8.resolve(fi
2021
1929
  // pkgs/@akanjs/devkit/frontendBuild/devGeneratedIndexSync.ts
2022
1930
  import { mkdir as mkdir2, readdir as readdir2, readFile as readFile2, rm, stat as stat2 } from "fs/promises";
2023
1931
  import path9 from "path";
1932
+ import { capitalize } from "akanjs/common";
2024
1933
  var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
2025
1934
  var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
2026
1935
  var FACET_EXCLUDED_FILE_RE = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
@@ -2111,7 +2020,7 @@ class DevGeneratedIndexSync {
2111
2020
  if (current === content)
2112
2021
  return false;
2113
2022
  await mkdir2(dir, { recursive: true });
2114
- await FileSys.writeTextAtomic(indexPath, content);
2023
+ await FileSys2.writeTextAtomic(indexPath, content);
2115
2024
  return true;
2116
2025
  }
2117
2026
  async#contentForIndex(indexPath) {
@@ -2170,7 +2079,6 @@ export const ${modelName} = { ${fileTypes.join(", ")} };`;
2170
2079
  }
2171
2080
  }
2172
2081
  var exists = async (file) => stat2(file).then(() => true).catch(() => false);
2173
- var capitalize = (value) => `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
2174
2082
  var formatError2 = (err) => err instanceof Error ? err.message : String(err);
2175
2083
 
2176
- export { BarrelAnalyzer, createBarrelImportsPlugin, createTsconfigPackageResolver, rewriteBarrelImports, GraphClientEntryDiscovery, transformUseClient, ClientEntriesBundler, VENDOR_SPECIFIERS, RouteClientBuilder, AutoImportSync, DevChangePlanner, DevGeneratedIndexSync };
2084
+ export { loaderFor, BarrelAnalyzer, createBarrelImportsPlugin, createTsconfigPackageResolver, rewriteBarrelImports, GraphClientEntryDiscovery, transformUseClient, bundleDefine, ClientEntriesBundler, VENDOR_SPECIFIERS, RouteClientBuilder, AutoImportSync, DevChangePlanner, DevGeneratedIndexSync };