@akanjs/cli 3.0.0-beta.19 → 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 (95) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-6cm97kay.js → CodeAgent-awv258wb.js} +2 -2
  3. package/{CodeTui-za4jsm41.js → CodeTui-1nqh35ez.js} +20 -22
  4. package/TunnelShare-scf4e4pd.js +9 -0
  5. package/{agent.command-e0wpbbyg.js → agent.command-1s9ag7sb.js} +8 -9
  6. package/akanCode.js +4 -4
  7. package/{application.command-8wyxqc8q.js → application.command-49hwy6va.js} +25 -56
  8. package/{applicationBuildRunner-n9gzaxd0.js → applicationBuildRunner-ybyp97pv.js} +33 -59
  9. package/{applicationReleasePackager-vpggfqgq.js → applicationReleasePackager-esnrphw8.js} +40 -60
  10. package/buildBatch.proc.js +19 -24
  11. package/{capacitorApp-q3z0qht0.js → capacitorApp-1synz4en.js} +3 -4
  12. package/{cloud.command-4zwa5dsx.js → cloud.command-d7rqtzt9.js} +16 -26
  13. package/cloud.script-bkbpcr96.js +19 -0
  14. package/{code.command-468c9d7s.js → code.command-nn48xzej.js} +22 -37
  15. package/context.command-s3mcmvpa.js +48 -0
  16. package/context.runner-k99nb5pk.js +21 -0
  17. package/{dependencyScanner-0z2h2tks.js → dependencyScanner-ye2e6pdz.js} +2 -2
  18. package/{devTui-ffjsarqa.js → devTui-q7k7bakd.js} +5 -9
  19. package/fileSys-5ngz93ga.js +9 -0
  20. package/{guideline.command-vhw13pqr.js → guideline.command-sct4qnt5.js} +4 -5
  21. package/guidelines/conventions/conventions.instruction.md +5 -1
  22. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  23. package/incrementalBuilder.proc.js +30 -48
  24. package/{index-s5rhm04y.js → index-0bq14vr1.js} +1 -1
  25. package/{index-10dkrrww.js → index-13ffe9wp.js} +4 -4
  26. package/{index-srmay5jw.js → index-22d57v4c.js} +84 -67
  27. package/{index-53176s7j.js → index-31yr441d.js} +10 -17
  28. package/index-3hx1z96c.js +87 -0
  29. package/{index-4m929vvn.js → index-3sq321ak.js} +10 -18
  30. package/{index-bhtmj233.js → index-3t7g9e4r.js} +41 -78
  31. package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
  32. package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
  33. package/{index-7ep8qtvp.js → index-5pc1qrbv.js} +5 -8
  34. package/{index-esk82rvk.js → index-8mna0947.js} +34 -71
  35. package/{index-sq2dzkzm.js → index-8sf7wmdr.js} +6 -6
  36. package/{index-crmeqnmf.js → index-9d9bgcx4.js} +283 -722
  37. package/{index-bwf965h6.js → index-ahemdr5n.js} +6 -6
  38. package/{index-ab0c38ea.js → index-as7xmyz8.js} +20 -20
  39. package/{index-bc88j1ry.js → index-axzjaqve.js} +94 -142
  40. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  41. package/{index-667w0yah.js → index-c6eggbee.js} +2 -5
  42. package/{index-a1w6934z.js → index-ddxvdd1p.js} +169 -305
  43. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  44. package/{index-22xtgmhn.js → index-dzf3r49a.js} +1 -1
  45. package/{index-89hy31kf.js → index-fgq75haa.js} +172 -287
  46. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  47. package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
  48. package/{index-vqx8bdxz.js → index-mxav6j3c.js} +78 -231
  49. package/{index-2446k7b4.js → index-myhc3c1j.js} +512 -588
  50. package/{index-3jrp517k.js → index-nv5976x3.js} +45 -128
  51. package/{index-zqgj2rt2.js → index-przybvy5.js} +69 -147
  52. package/{index-n3cv0tm4.js → index-smme4r47.js} +1 -1
  53. package/{index-qdgzsnhg.js → index-w2zdcw3k.js} +110 -231
  54. package/{index-14zrtgfa.js → index-wa5jbxj1.js} +6 -39
  55. package/{index-bftkz6cp.js → index-ww4z397j.js} +198 -555
  56. package/{index-kwaq3n9n.js → index-xqjwd384.js} +4 -7
  57. package/{index-txr7dj2g.js → index-xqpzbab5.js} +106 -240
  58. package/{index-e4v6vhxq.js → index-xsjh6nzh.js} +178 -165
  59. package/{index-18zybgkc.js → index-ygn77a5w.js} +47 -99
  60. package/{index-9d6nvkz2.js → index-ztp3e73t.js} +79 -35
  61. package/index.js +23 -24
  62. package/{library.command-cqr175dy.js → library.command-1gx04jgn.js} +4 -5
  63. package/{localRegistry.command-49z55qqz.js → localRegistry.command-zndxj1q6.js} +21 -42
  64. package/{module.command-9p8mm3b0.js → module.command-3waddk95.js} +6 -7
  65. package/{package.command-wxyz909t.js → package.command-zrc7br1y.js} +5 -6
  66. package/package.json +2 -2
  67. package/{page.command-gsrsfqqs.js → page.command-vpjgardh.js} +4 -5
  68. package/{primitive.command-ns1mptje.js → primitive.command-sz84tk4t.js} +9 -20
  69. package/{prompter-1f8d9pcc.js → prompter-ptaa3nk0.js} +2 -2
  70. package/{quality.command-e76k2q9k.js → quality.command-g869hafs.js} +129 -363
  71. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  72. package/{repair.command-pkrsm3cw.js → repair.command-chsnjvvv.js} +11 -35
  73. package/{scalar.command-0cpt3fc8.js → scalar.command-2v21newx.js} +5 -6
  74. package/skills/akan-code/SKILL.md +12 -4
  75. package/{subspace.command-fktpwp0g.js → subspace.command-ckcbwfp1.js} +39 -58
  76. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +3 -3
  77. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +3 -3
  78. package/templates/client.ts +7 -30
  79. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  80. package/templates/lib/__lib/lib.document.ts +0 -2
  81. package/templates/lib/sig.ts +8 -30
  82. package/templates/server.ts +0 -2
  83. package/{tunnel.command-d5jy9gk8.js → tunnel.command-kd2yr4fx.js} +5 -6
  84. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  85. package/typecheck.proc.js +1 -1
  86. package/workflow.command-44252cqv.js +79 -0
  87. package/{workspace.command-gv84eh1p.js → workspace.command-fqcztt5p.js} +72 -107
  88. package/TunnelShare-2j6s511d.js +0 -9
  89. package/cloud.script-fwx3vb34.js +0 -20
  90. package/context.command-dsnw0jby.js +0 -80
  91. package/context.runner-rs4rj15d.js +0 -22
  92. package/devTuiView-1q1mdgrv.js +0 -9
  93. package/getDirname-dr3jz1xg.js +0 -7
  94. package/index-6wwzs1bc.js +0 -7
  95. package/workflow.command-6tkcysmx.js +0 -105
@@ -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,6 +1042,7 @@ 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;
@@ -1275,18 +1175,7 @@ ${absEntry}`).toString(36);
1275
1175
  return { buildEntries, originalByBuildEntry };
1276
1176
  }
1277
1177
  async#scanExportNames(absEntry) {
1278
- const source = await Bun.file(absEntry).text();
1279
- const transpiler = new Bun.Transpiler({ loader: this.#loaderFor(absEntry) });
1280
- return transpiler.scan(source).exports;
1281
- }
1282
- #loaderFor(absPath) {
1283
- if (absPath.endsWith(".tsx"))
1284
- return "tsx";
1285
- if (absPath.endsWith(".jsx"))
1286
- return "jsx";
1287
- if (absPath.endsWith(".ts"))
1288
- return "ts";
1289
- return "js";
1178
+ return scanUseClientExports(await Bun.file(absEntry).text(), absEntry, this.#app.workspace.workspaceRoot);
1290
1179
  }
1291
1180
  static normalizeNamedDefaultFunctionForFastRefresh(source) {
1292
1181
  let changed = false;
@@ -1354,7 +1243,7 @@ ${defaultNames.map((name) => `export default ${name};`).join(`
1354
1243
  // pkgs/@akanjs/devkit/frontendBuild/autoImportSync.ts
1355
1244
  import { readdir, readFile, stat } from "fs/promises";
1356
1245
  import path7 from "path";
1357
- import ts2 from "typescript";
1246
+ import ts3 from "typescript";
1358
1247
  var TEST_FILE_RE = /\.(test|spec)\.(ts|tsx)$/;
1359
1248
  var AKAN_BASE = {
1360
1249
  names: ["Int", "Float", "ID", "Any", "Upload", "enumOf", "dayjs"],
@@ -1547,7 +1436,7 @@ class AutoImportSync {
1547
1436
  const next = transformSource(source, abs, ctx, resolveExtra);
1548
1437
  if (next === null || next === source)
1549
1438
  return false;
1550
- await FileSys.writeTextAtomic(abs, next);
1439
+ await FileSys2.writeTextAtomic(abs, next);
1551
1440
  return true;
1552
1441
  }
1553
1442
  async#extraResolverFor(abs, ctx) {
@@ -1648,7 +1537,7 @@ var targetFor = (symbol, ctx) => {
1648
1537
  return null;
1649
1538
  };
1650
1539
  var transformSource = (source, fileName, ctx, resolveExtra) => {
1651
- 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));
1652
1541
  const bound = collectBoundNames(sf);
1653
1542
  const used = collectUsedReferences(sf);
1654
1543
  const bareGlobals = collectBareGlobalReferences(sf);
@@ -1670,7 +1559,7 @@ var transformSource = (source, fileName, ctx, resolveExtra) => {
1670
1559
  }
1671
1560
  if (namedBySpecifier.size === 0 && namespaceImports.length === 0)
1672
1561
  return null;
1673
- const importDecls = sf.statements.filter(ts2.isImportDeclaration);
1562
+ const importDecls = sf.statements.filter(ts3.isImportDeclaration);
1674
1563
  const anchor = importDecls.at(-1) ?? null;
1675
1564
  const namedImportsBySpecifier = collectExistingNamedImports(importDecls);
1676
1565
  const edits = [];
@@ -1726,61 +1615,61 @@ ${newStatements.join(`
1726
1615
  var collectBoundNames = (sf) => {
1727
1616
  const names = new Set;
1728
1617
  const visit = (node) => {
1729
- if (ts2.isImportClause(node)) {
1618
+ if (ts3.isImportClause(node)) {
1730
1619
  if (node.name)
1731
1620
  names.add(node.name.text);
1732
1621
  const bindings = node.namedBindings;
1733
- if (bindings && ts2.isNamespaceImport(bindings))
1622
+ if (bindings && ts3.isNamespaceImport(bindings))
1734
1623
  names.add(bindings.name.text);
1735
- if (bindings && ts2.isNamedImports(bindings))
1624
+ if (bindings && ts3.isNamedImports(bindings))
1736
1625
  for (const el of bindings.elements)
1737
1626
  names.add(el.name.text);
1738
1627
  }
1739
- 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))
1740
1629
  names.add(node.name.text);
1741
- ts2.forEachChild(node, visit);
1630
+ ts3.forEachChild(node, visit);
1742
1631
  };
1743
- ts2.forEachChild(sf, visit);
1632
+ ts3.forEachChild(sf, visit);
1744
1633
  return names;
1745
1634
  };
1746
1635
  var collectUsedReferences = (sf) => {
1747
1636
  const used = new Set;
1748
1637
  const visit = (node) => {
1749
- if (ts2.isIdentifier(node) && isReferencePosition(node))
1638
+ if (ts3.isIdentifier(node) && isReferencePosition(node))
1750
1639
  used.add(node.text);
1751
- ts2.forEachChild(node, visit);
1640
+ ts3.forEachChild(node, visit);
1752
1641
  };
1753
- ts2.forEachChild(sf, visit);
1642
+ ts3.forEachChild(sf, visit);
1754
1643
  return used;
1755
1644
  };
1756
1645
  var collectBareGlobalReferences = (sf) => {
1757
1646
  const bare = new Set;
1758
1647
  const visit = (node) => {
1759
- if (ts2.isIdentifier(node) && GLOBAL_NAMES.has(node.text) && isReferencePosition(node)) {
1648
+ if (ts3.isIdentifier(node) && GLOBAL_NAMES.has(node.text) && isReferencePosition(node)) {
1760
1649
  const parent = node.parent;
1761
- if (!(parent && ts2.isPropertyAccessExpression(parent) && parent.expression === node))
1650
+ if (!(parent && ts3.isPropertyAccessExpression(parent) && parent.expression === node))
1762
1651
  bare.add(node.text);
1763
1652
  }
1764
- ts2.forEachChild(node, visit);
1653
+ ts3.forEachChild(node, visit);
1765
1654
  };
1766
- ts2.forEachChild(sf, visit);
1655
+ ts3.forEachChild(sf, visit);
1767
1656
  return bare;
1768
1657
  };
1769
1658
  var isReferencePosition = (node) => {
1770
1659
  const parent = node.parent;
1771
1660
  if (!parent)
1772
1661
  return true;
1773
- if (ts2.isPropertyAccessExpression(parent) && parent.name === node)
1662
+ if (ts3.isPropertyAccessExpression(parent) && parent.name === node)
1774
1663
  return false;
1775
- if (ts2.isQualifiedName(parent) && parent.right === node)
1664
+ if (ts3.isQualifiedName(parent) && parent.right === node)
1776
1665
  return false;
1777
- if (ts2.isPropertyAssignment(parent) && parent.name === node)
1666
+ if (ts3.isPropertyAssignment(parent) && parent.name === node)
1778
1667
  return false;
1779
- if (ts2.isPropertySignature(parent) && parent.name === node)
1668
+ if (ts3.isPropertySignature(parent) && parent.name === node)
1780
1669
  return false;
1781
- if (ts2.isBindingElement(parent) && parent.propertyName === node)
1670
+ if (ts3.isBindingElement(parent) && parent.propertyName === node)
1782
1671
  return false;
1783
- if (ts2.isImportSpecifier(parent) || ts2.isExportSpecifier(parent))
1672
+ if (ts3.isImportSpecifier(parent) || ts3.isExportSpecifier(parent))
1784
1673
  return false;
1785
1674
  return true;
1786
1675
  };
@@ -1789,9 +1678,9 @@ var collectExistingNamedImports = (importDecls) => {
1789
1678
  for (const decl of importDecls) {
1790
1679
  const clause = decl.importClause;
1791
1680
  const bindings = clause?.namedBindings;
1792
- if (!clause || !bindings || !ts2.isNamedImports(bindings))
1681
+ if (!clause || !bindings || !ts3.isNamedImports(bindings))
1793
1682
  continue;
1794
- if (!ts2.isStringLiteral(decl.moduleSpecifier))
1683
+ if (!ts3.isStringLiteral(decl.moduleSpecifier))
1795
1684
  continue;
1796
1685
  const specifier = decl.moduleSpecifier.text;
1797
1686
  if (map.has(specifier))
@@ -1813,14 +1702,14 @@ var formatNamedImport = (specifier, names) => {
1813
1702
  var directivePrologueEnd = (sf) => {
1814
1703
  let end = -1;
1815
1704
  for (const stmt of sf.statements) {
1816
- if (ts2.isExpressionStatement(stmt) && ts2.isStringLiteral(stmt.expression))
1705
+ if (ts3.isExpressionStatement(stmt) && ts3.isStringLiteral(stmt.expression))
1817
1706
  end = stmt.getEnd();
1818
1707
  else
1819
1708
  break;
1820
1709
  }
1821
1710
  return end;
1822
1711
  };
1823
- 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;
1824
1713
  var compareNames = (a, b) => {
1825
1714
  const [la, lb] = [a.toLowerCase(), b.toLowerCase()];
1826
1715
  if (la !== lb)
@@ -1870,18 +1759,18 @@ var collectDomainFiles = async (dir) => {
1870
1759
  return files;
1871
1760
  };
1872
1761
  var exportedPascalNames = (source, fileName) => {
1873
- const sf = ts2.createSourceFile(fileName, source, ts2.ScriptTarget.Latest, true);
1874
- 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);
1875
1764
  const names = [];
1876
1765
  for (const stmt of sf.statements) {
1877
- 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) {
1878
1767
  if (isExported(stmt))
1879
1768
  names.push(stmt.name.text);
1880
- } else if (ts2.isVariableStatement(stmt) && isExported(stmt)) {
1769
+ } else if (ts3.isVariableStatement(stmt) && isExported(stmt)) {
1881
1770
  for (const decl of stmt.declarationList.declarations)
1882
- if (ts2.isIdentifier(decl.name))
1771
+ if (ts3.isIdentifier(decl.name))
1883
1772
  names.push(decl.name.text);
1884
- } else if (ts2.isExportDeclaration(stmt) && stmt.exportClause && ts2.isNamedExports(stmt.exportClause)) {
1773
+ } else if (ts3.isExportDeclaration(stmt) && stmt.exportClause && ts3.isNamedExports(stmt.exportClause)) {
1885
1774
  for (const el of stmt.exportClause.elements)
1886
1775
  names.push(el.name.text);
1887
1776
  }
@@ -1895,7 +1784,6 @@ var relativeSpecifier = (fromDir, toFile) => {
1895
1784
 
1896
1785
  // pkgs/@akanjs/devkit/frontendBuild/devChangePlanner.ts
1897
1786
  import path8 from "path";
1898
- var SOURCE_EXTS2 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
1899
1787
  var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
1900
1788
  var BARREL_FACETS = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
1901
1789
  var CLIENT_SUFFIXES = [".Template.tsx", ".Unit.tsx", ".Util.tsx", ".View.tsx", ".Zone.tsx", ".store.ts"];
@@ -1957,7 +1845,7 @@ class DevChangePlanner {
1957
1845
  const abs = path8.resolve(file);
1958
1846
  const base = path8.basename(abs);
1959
1847
  const ext = path8.extname(abs).toLowerCase();
1960
- const isSource = SOURCE_EXTS2.has(ext);
1848
+ const isSource = SOURCE_EXTS.has(ext);
1961
1849
  const rel = path8.relative(this.#workspaceRoot, abs);
1962
1850
  const parts = rel.split(path8.sep).filter(Boolean);
1963
1851
  if (CONFIG_BASENAMES.has(base)) {
@@ -1972,15 +1860,15 @@ class DevChangePlanner {
1972
1860
  roles.add("barrel");
1973
1861
  reasons.add(isGenerated ? "generated-index" : "barrel-facet-child");
1974
1862
  }
1975
- if (isSource && this.#isServerBiased(abs, parts)) {
1863
+ if (isSource && this.#isServerBiased(base, parts)) {
1976
1864
  roles.add("server");
1977
1865
  reasons.add("server-path");
1978
1866
  }
1979
- if (isSource && this.#isClientBiased(abs, parts)) {
1867
+ if (isSource && this.#isClientBiased(base, parts)) {
1980
1868
  roles.add("client");
1981
1869
  reasons.add("client-path");
1982
1870
  }
1983
- if (isSource && this.#isSharedBiased(abs, parts)) {
1871
+ if (isSource && this.#isSharedBiased(base, parts)) {
1984
1872
  roles.add("shared");
1985
1873
  reasons.add("shared-path");
1986
1874
  }
@@ -1993,22 +1881,19 @@ class DevChangePlanner {
1993
1881
  roles.add("shared");
1994
1882
  reasons.add("server-client-overlap");
1995
1883
  }
1996
- if (roles.size === 0 && SOURCE_EXTS2.has(ext) && this.#isWorkspaceSource(rel)) {
1884
+ if (roles.size === 0 && SOURCE_EXTS.has(ext) && this.#isWorkspaceSource(rel)) {
1997
1885
  roles.add("shared");
1998
1886
  reasons.add("workspace-source-fallback");
1999
1887
  }
2000
1888
  return roles;
2001
1889
  }
2002
- #isServerBiased(abs, parts) {
2003
- const base = path8.basename(abs);
1890
+ #isServerBiased(base, parts) {
2004
1891
  return parts.includes("srvkit") || SERVER_SUFFIXES.some((suffix) => base.endsWith(suffix)) || base === "main.ts" || base === "server.ts";
2005
1892
  }
2006
- #isClientBiased(abs, parts) {
2007
- const base = path8.basename(abs);
1893
+ #isClientBiased(base, parts) {
2008
1894
  return parts.includes("ui") || parts.includes("webkit") || parts.includes("page") || CLIENT_SUFFIXES.some((suffix) => base.endsWith(suffix));
2009
1895
  }
2010
- #isSharedBiased(abs, parts) {
2011
- const base = path8.basename(abs);
1896
+ #isSharedBiased(base, parts) {
2012
1897
  return parts.includes("common") || SHARED_SUFFIXES.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES.has(base);
2013
1898
  }
2014
1899
  #isRuntimeMetadataFile(parts, base) {
@@ -2044,6 +1929,7 @@ var uniqueResolved = (files) => [...new Set(files.map((file) => path8.resolve(fi
2044
1929
  // pkgs/@akanjs/devkit/frontendBuild/devGeneratedIndexSync.ts
2045
1930
  import { mkdir as mkdir2, readdir as readdir2, readFile as readFile2, rm, stat as stat2 } from "fs/promises";
2046
1931
  import path9 from "path";
1932
+ import { capitalize } from "akanjs/common";
2047
1933
  var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
2048
1934
  var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
2049
1935
  var FACET_EXCLUDED_FILE_RE = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
@@ -2134,7 +2020,7 @@ class DevGeneratedIndexSync {
2134
2020
  if (current === content)
2135
2021
  return false;
2136
2022
  await mkdir2(dir, { recursive: true });
2137
- await FileSys.writeTextAtomic(indexPath, content);
2023
+ await FileSys2.writeTextAtomic(indexPath, content);
2138
2024
  return true;
2139
2025
  }
2140
2026
  async#contentForIndex(indexPath) {
@@ -2193,7 +2079,6 @@ export const ${modelName} = { ${fileTypes.join(", ")} };`;
2193
2079
  }
2194
2080
  }
2195
2081
  var exists = async (file) => stat2(file).then(() => true).catch(() => false);
2196
- var capitalize = (value) => `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
2197
2082
  var formatError2 = (err) => err instanceof Error ? err.message : String(err);
2198
2083
 
2199
- 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 };