@akanjs/cli 3.0.0-alpha.8 → 3.0.0-alpha.81

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 (152) hide show
  1. package/.build-stamp +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +1 -1
  4. package/{abstractCompactor-e5yq60qz.js → abstractCompactor-pwc6d6yk.js} +3 -5
  5. package/{agent.command-pggr92jj.js → agent.command-180hh0ye.js} +11 -12
  6. package/{application.command-692yap1d.js → application.command-4fq5pmdd.js} +59 -35
  7. package/{applicationBuildRunner-ha3y8ew8.js → applicationBuildRunner-tavpx3fv.js} +22 -20
  8. package/{applicationReleasePackager-gg8ccbeh.js → applicationReleasePackager-ktjt0erc.js} +8 -9
  9. package/buildBatch.proc.js +12 -13
  10. package/capacitorApp-kwa67kzs.js +12 -0
  11. package/{cloud.command-wqfsyzv2.js → cloud.command-wm3mtfve.js} +15 -17
  12. package/commandManifest.json +1 -1
  13. package/{context.command-9bxtdn0w.js → context.command-dk2m2sjx.js} +19 -22
  14. package/dependencyScanner-c64m6fxp.js +8 -0
  15. package/getDirname-dr3jz1xg.js +7 -0
  16. package/{guideline.command-nfqahxex.js → guideline.command-w6ddv13r.js} +16 -17
  17. package/guidelines/agentRule/agentRule.generate.json +31 -0
  18. package/guidelines/agentRule/agentRule.instruction.md +525 -0
  19. package/guidelines/conventions/conventions.generate.json +25 -0
  20. package/guidelines/conventions/conventions.instruction.md +847 -0
  21. package/guidelines/cssRule/cssRule.instruction.md +7 -0
  22. package/guidelines/framework/framework.generate.json +3 -2
  23. package/guidelines/framework/framework.instruction.md +1 -9
  24. package/guidelines/mcpRule/mcpRule.generate.json +25 -0
  25. package/guidelines/mcpRule/mcpRule.instruction.md +217 -0
  26. package/guidelines/queryRule/queryRule.generate.json +31 -0
  27. package/guidelines/queryRule/queryRule.instruction.md +143 -0
  28. package/guidelines/runtimeRule/runtimeRule.generate.json +25 -0
  29. package/guidelines/runtimeRule/runtimeRule.instruction.md +176 -0
  30. package/guidelines/ssrRule/ssrRule.instruction.md +49 -5
  31. package/guidelines/transportRule/transportRule.generate.json +31 -0
  32. package/guidelines/transportRule/transportRule.instruction.md +60 -0
  33. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
  34. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +263 -0
  35. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +33 -0
  36. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +402 -0
  37. package/incrementalBuilder.proc.js +21 -22
  38. package/{index-4hek879p.js → index-1kzsn94d.js} +1 -1
  39. package/{index-p3f4q532.js → index-1tgp56ke.js} +31 -30
  40. package/index-3d9y066c.js +76 -0
  41. package/{index-76rn3g2c.js → index-47pj3aee.js} +4 -4
  42. package/{index-gex7c8kd.js → index-5n0hf8r9.js} +65 -38
  43. package/{index-mssqn2sq.js → index-5y7qba1c.js} +79 -33
  44. package/index-6wwzs1bc.js +7 -0
  45. package/{index-wnp7hwq7.js → index-92zztqy1.js} +7 -7
  46. package/{index-fgc8r6dj.js → index-a5vmm6x4.js} +3 -1
  47. package/{index-azv0xjb5.js → index-a8h184wr.js} +15 -11
  48. package/{index-67546d0j.js → index-ayy5ecax.js} +1 -1
  49. package/{index-xhgtkekh.js → index-b2nt0w0k.js} +27 -27
  50. package/{index-xys926f2.js → index-by5gpp8x.js} +4 -4
  51. package/{index-bz2sfzzt.js → index-cd5x18qh.js} +32 -32
  52. package/{index-bjpxzr6s.js → index-ctphds8v.js} +1 -1
  53. package/{index-w6wbb612.js → index-dq6wq1tv.js} +94 -61
  54. package/{index-6rhabeev.js → index-ft1sfjz0.js} +36 -25
  55. package/{index-7myvn0f0.js → index-h7yw2z9n.js} +7 -7
  56. package/{index-5pmx7bkg.js → index-j9vnq8tr.js} +18 -18
  57. package/{index-vg0sj9nc.js → index-k1n0h7dk.js} +840 -201
  58. package/{index-vtj3zps1.js → index-k86zc21w.js} +57 -57
  59. package/{index-5dw57f0d.js → index-m7e0f1sy.js} +155 -76
  60. package/index-m9c7k0gm.js +159 -0
  61. package/{index-46tjzh6s.js → index-mfm35dhh.js} +29 -29
  62. package/{index-xjd3rqzj.js → index-n68jx79w.js} +6 -15
  63. package/{index-ztpw544k.js → index-qcracvc9.js} +8 -8
  64. package/{index-2c3e2xh8.js → index-saheq2bs.js} +4 -4
  65. package/{index-gmy45vz2.js → index-v0s24t8j.js} +14 -14
  66. package/{index-0cj2zxbm.js → index-wet2ytnr.js} +12 -11
  67. package/{index-j9cxndc0.js → index-x23688ar.js} +12 -7
  68. package/{index-a1e0j63x.js → index-xxe90kqy.js} +58 -25
  69. package/{index-js368gk9.js → index-ypvdw8nr.js} +13 -13
  70. package/{index-qb61h0k7.js → index-z3c9mmw4.js} +1098 -1360
  71. package/index.js +22 -24
  72. package/{library.command-md9715jz.js → library.command-wpedct6c.js} +11 -9
  73. package/{localRegistry.command-exkbamyj.js → localRegistry.command-gk773cte.js} +20 -22
  74. package/{module.command-w5aaddxk.js → module.command-8n4kct3e.js} +13 -15
  75. package/{package.command-yfkrcy0z.js → package.command-fcbd0b1d.js} +8 -9
  76. package/package.json +5 -7
  77. package/{page.command-echbavp4.js → page.command-x4379grq.js} +7 -8
  78. package/{primitive.command-9fbhspw2.js → primitive.command-8etmnqhq.js} +13 -15
  79. package/{quality.command-3pnt9yep.js → quality.command-hfx7z8yr.js} +226 -104
  80. package/recipeScanner-fpagtgc1.js +11 -0
  81. package/{repair.command-carj4vax.js → repair.command-j0fs5qkz.js} +12 -13
  82. package/{routeSourceValidator-e4jmbfcx.js → routeSourceValidator-ze6x894c.js} +0 -2
  83. package/{scalar.command-51ryzypc.js → scalar.command-2emk89eh.js} +11 -13
  84. package/subspace.command-3w3s1zas.js +714 -0
  85. package/templates/app/env/env.client.debug.ts.template +1 -5
  86. package/templates/app/env/env.client.develop.ts.template +1 -5
  87. package/templates/app/env/env.client.local.ts.template +1 -5
  88. package/templates/app/env/env.client.main.ts.template +1 -5
  89. package/templates/app/env/env.client.testing.ts.template +1 -5
  90. package/templates/app/env/env.client.type.ts +2 -6
  91. package/templates/app/env/env.server.debug.ts.template +1 -5
  92. package/templates/app/env/env.server.develop.ts.template +1 -5
  93. package/templates/app/env/env.server.local.ts.template +1 -5
  94. package/templates/app/env/env.server.main.ts.template +1 -5
  95. package/templates/app/main.ts +3 -1
  96. package/templates/appSample/lib/task/task.signal.ts +11 -6
  97. package/templates/appSample/srvkit/AuthGuard.ts +9 -5
  98. package/templates/appSample/srvkit/SessionInternalArg.ts +4 -3
  99. package/templates/crudPages/[__model__Id]/edit/page.tsx +6 -6
  100. package/templates/crudPages/[__model__Id]/page.tsx +10 -13
  101. package/templates/crudPages/new/page.tsx +6 -6
  102. package/templates/crudPages/page.tsx +9 -9
  103. package/templates/crudSinglePage/page.tsx +11 -7
  104. package/templates/env/_env.server.type.ts +7 -5
  105. package/templates/lib/db.ts +1 -1
  106. package/templates/lib/dict.ts +1 -1
  107. package/templates/lib/sig.ts +1 -1
  108. package/templates/lib/srv.ts +6 -2
  109. package/templates/module/__Model__.Util.tsx +1 -1
  110. package/templates/module/__Model__.Zone.tsx +3 -5
  111. package/templates/module/__model__.dictionary.ts +4 -1
  112. package/templates/module/__model__.signal.ts +2 -3
  113. package/templates/module/__model__.store.ts +1 -2
  114. package/templates/workspaceRoot/.gitignore.template +0 -1
  115. package/templates/workspaceRoot/AGENTS.md.template +4 -972
  116. package/templates/workspaceRoot/CLAUDE.md.template +19 -0
  117. package/templates/workspaceRoot/biome.json.template +4 -244
  118. package/templates/workspaceRoot/docs/AI-DEVELOPMENT.md.template +10 -14
  119. package/templates/workspaceRoot/docs/GENERATED.md.template +12 -10
  120. package/templates/workspaceRoot/package.json.template +2 -4
  121. package/typeChecker-3xgrzc2v.js +7 -0
  122. package/typecheck.proc.js +4 -5
  123. package/{workflow.command-91wmvm8k.js → workflow.command-cvpmzwjg.js} +21 -23
  124. package/{workspace.command-wa10mfd9.js → workspace.command-4ztb4fdh.js} +108 -91
  125. package/capacitorApp-p0z5yab2.js +0 -60
  126. package/dependencyScanner-f6grrep3.js +0 -9
  127. package/index-mxvakhsm.js +0 -66
  128. package/index-r24hmh0q.js +0 -4
  129. package/recipeScanner-tghkzrrt.js +0 -12
  130. package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
  131. package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -34
  132. package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
  133. package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
  134. package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -18
  135. package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
  136. package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
  137. package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
  138. package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
  139. package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -19
  140. package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -62
  141. package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
  142. package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
  143. package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
  144. package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -99
  145. package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
  146. package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
  147. package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
  148. package/templates/workspaceRoot/.cursor/rules/ssr-first.mdc.template +0 -59
  149. package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
  150. package/typeChecker-kravn7ns.js +0 -8
  151. /package/{index-0wae5ebk.js → index-meh558jy.js} +0 -0
  152. /package/{index-ss469dec.js → index-nz8prx9g.js} +0 -0
@@ -0,0 +1,159 @@
1
+ // @bun
2
+ import {
3
+ AppInfo
4
+ } from "./index-k1n0h7dk.js";
5
+
6
+ // pkgs/@akanjs/devkit/slicePlanner.ts
7
+ class SlicePlanner {
8
+ static memberDirs = ["apps", "libs", "pkgs"];
9
+ static toolchainDependencies = [
10
+ "@akanjs/cli",
11
+ "@akanjs/devkit",
12
+ "@biomejs/biome",
13
+ "@types/bun",
14
+ "akanjs",
15
+ "tailwindcss",
16
+ "typescript"
17
+ ];
18
+ static akanPackages = ["akanjs", "@akanjs/devkit", "@akanjs/cli"];
19
+ static async#frameworkPeers(workspace) {
20
+ const peers = new Set;
21
+ let found = false;
22
+ for (const akanPackage of SlicePlanner.akanPackages) {
23
+ for (const prefix of ["node_modules", "pkgs"]) {
24
+ const manifestPath = `${prefix}/${akanPackage}/package.json`;
25
+ if (!await workspace.exists(manifestPath))
26
+ continue;
27
+ const manifest = await workspace.readJson(manifestPath);
28
+ for (const peer of Object.keys(manifest.peerDependencies ?? {}))
29
+ peers.add(peer);
30
+ found = true;
31
+ break;
32
+ }
33
+ }
34
+ return found ? peers : null;
35
+ }
36
+ static typesPackageOf(dependency) {
37
+ return dependency.startsWith("@") ? `@types/${dependency.slice(1).replace("/", "__")}` : `@types/${dependency}`;
38
+ }
39
+ static async pruneDependencies(workspace, rootPackageJson, required) {
40
+ const peers = await SlicePlanner.#frameworkPeers(workspace);
41
+ const { workspaces: _workspaces, ...rest } = rootPackageJson;
42
+ if (!peers)
43
+ return {
44
+ packageJson: rest,
45
+ pruned: [],
46
+ warnings: [`dependencies carried whole \u2014 none of ${SlicePlanner.akanPackages.join(", ")} is installed`]
47
+ };
48
+ const keep = new Set([...SlicePlanner.toolchainDependencies, ...peers, ...required]);
49
+ for (const dependency of [...keep])
50
+ keep.add(SlicePlanner.typesPackageOf(dependency));
51
+ const pick = (entries) => Object.fromEntries(Object.entries(entries ?? {}).filter(([name]) => keep.has(name)));
52
+ const patched = rootPackageJson.patchedDependencies ?? {};
53
+ const packageJson = {
54
+ ...rest,
55
+ dependencies: pick(rootPackageJson.dependencies),
56
+ devDependencies: pick(rootPackageJson.devDependencies),
57
+ ...Object.keys(patched).length ? {
58
+ patchedDependencies: Object.fromEntries(Object.entries(patched).filter(([spec]) => keep.has(spec.slice(0, spec.lastIndexOf("@")))))
59
+ } : {}
60
+ };
61
+ const pruned = Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }).filter((name) => !keep.has(name)).sort();
62
+ return { packageJson, pruned, warnings: [] };
63
+ }
64
+ #app;
65
+ constructor(app) {
66
+ this.#app = app;
67
+ }
68
+ async#trackedFiles(paths) {
69
+ return await this.#app.workspace.listGitFiles(paths);
70
+ }
71
+ async#untrackedFiles(paths) {
72
+ const [tracked, all] = await Promise.all([
73
+ this.#app.workspace.listGitFiles(paths),
74
+ this.#app.workspace.listGitFiles(paths, { untracked: true })
75
+ ]);
76
+ const trackedSet = new Set(tracked);
77
+ return all.filter((file) => !trackedSet.has(file));
78
+ }
79
+ #isMemberFile(file) {
80
+ return SlicePlanner.memberDirs.includes(file.split("/")[0] ?? "");
81
+ }
82
+ static #requiredDependencies(appInfo) {
83
+ const scanResults = [
84
+ appInfo.getScanResult(),
85
+ ...[...appInfo.getLibInfos().values()].map((lib) => lib.getScanResult())
86
+ ];
87
+ return new Set([
88
+ ...scanResults.flatMap((scanResult) => [
89
+ ...scanResult.dependencies,
90
+ ...scanResult.devDependencies,
91
+ ...scanResult.pkgDeps
92
+ ])
93
+ ]);
94
+ }
95
+ async#patchWarnings(packageJson) {
96
+ const patchedDependencies = packageJson.patchedDependencies ?? {};
97
+ const missing = (await Promise.all(Object.entries(patchedDependencies).map(async ([spec, patchPath]) => await this.#app.workspace.exists(patchPath) ? null : `${spec} -> ${patchPath}`))).filter((entry) => !!entry);
98
+ return missing.length ? [`patchedDependencies references a missing patch file: ${missing.join(", ")}`] : [];
99
+ }
100
+ async plan() {
101
+ const appInfo = await AppInfo.fromExecutor(this.#app);
102
+ const libs = appInfo.getLibs();
103
+ const slicePaths = [`apps/${this.#app.name}`, ...libs.map((lib) => `libs/${lib}`)];
104
+ const [appFiles, allTracked, untracked, rootPackageJson] = await Promise.all([
105
+ this.#trackedFiles([`apps/${this.#app.name}`]),
106
+ this.#trackedFiles(["."]),
107
+ this.#untrackedFiles(slicePaths),
108
+ this.#app.workspace.getPackageJson()
109
+ ]);
110
+ const libFiles = Object.fromEntries(await Promise.all(libs.map(async (lib) => [lib, await this.#trackedFiles([`libs/${lib}`])])));
111
+ const rootFiles = allTracked.filter((file) => !this.#isMemberFile(file));
112
+ const required = SlicePlanner.#requiredDependencies(appInfo);
113
+ const {
114
+ packageJson,
115
+ pruned,
116
+ warnings: manifestWarnings
117
+ } = await SlicePlanner.pruneDependencies(this.#app.workspace, rootPackageJson, required);
118
+ const warnings = [
119
+ ...untracked.length ? [`${untracked.length} untracked file(s) under the slice paths: ${untracked.join(", ")}`] : [],
120
+ ...rootPackageJson.workspaces ? ["root `workspaces` dropped \u2014 a slice consumes akanjs from the registry"] : [],
121
+ ...manifestWarnings,
122
+ ...await this.#patchWarnings(rootPackageJson)
123
+ ];
124
+ return {
125
+ app: this.#app.name,
126
+ libs,
127
+ appFiles,
128
+ libFiles,
129
+ rootFiles,
130
+ packageJson,
131
+ requiredDependencies: [...required].sort(),
132
+ unusedDependencies: pruned,
133
+ warnings
134
+ };
135
+ }
136
+ }
137
+ var rootEntriesOf = (rootFiles) => [...new Set(rootFiles.map((file) => file.split("/")[0] ?? file))].sort();
138
+ function formatSlicePlan(plan) {
139
+ const libCounts = Object.entries(plan.libFiles).map(([lib, files]) => ` - libs/${lib}: ${files.length} files`);
140
+ const sections = [
141
+ "Akan Slice Plan",
142
+ `app: ${plan.app} (apps/${plan.app}: ${plan.appFiles.length} files)`,
143
+ `libs: ${plan.libs.length ? plan.libs.join(", ") : "(none)"}`,
144
+ ...libCounts,
145
+ `workspace shell: ${plan.rootFiles.length} files across ${rootEntriesOf(plan.rootFiles).join(", ")}`,
146
+ "",
147
+ `Root dependencies this slice does not use (${plan.unusedDependencies.length}) \u2014 pruned:`,
148
+ "",
149
+ ...plan.unusedDependencies.length ? plan.unusedDependencies.map((dep) => ` - ${dep}`) : [" (none)"],
150
+ "",
151
+ `Warnings (${plan.warnings.length}):`,
152
+ "",
153
+ ...plan.warnings.length ? plan.warnings.map((warning) => ` - ${warning}`) : [" (none)"]
154
+ ];
155
+ return sections.join(`
156
+ `);
157
+ }
158
+
159
+ export { SlicePlanner, formatSlicePlan };
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  FileSys
4
- } from "./index-67546d0j.js";
4
+ } from "./index-ayy5ecax.js";
5
5
 
6
6
  // pkgs/@akanjs/devkit/dependencyScanner.ts
7
7
  import { builtinModules } from "module";
@@ -9,39 +9,41 @@ import * as path from "path";
9
9
  import ignore from "ignore";
10
10
  import ts from "typescript";
11
11
  var testFileRegex = /\.(?:test|spec)\.[cm]?[tj]sx?$/;
12
+ var skipDirs = ["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android", "__fixtures__"];
13
+ var isSkippedPath = (filePath) => skipDirs.some((dir) => filePath.includes(`/${dir}/`) || filePath.startsWith(`${dir}/`));
12
14
  var builtinModuleSet = new Set([...builtinModules, ...builtinModules.map((mod) => `node:${mod}`)]);
13
15
  var stripShebang = (source) => source.replace(/^#!.*(?:\r?\n|$)/, "");
14
16
 
15
- class TypeScriptDependencyScanner {
17
+ class TypeScriptDependencyScanner2 {
16
18
  #fileDependencies = new Map;
17
19
  #fileRuntimeDependencies = new Map;
18
20
  #fileTypeDependencies = new Map;
19
21
  #visitedFiles = new Set;
20
22
  #tsTranspiler = new Bun.Transpiler({ loader: "ts" });
21
23
  #tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
22
- directory;
23
- rootPackageJson;
24
- ig;
25
- workspaceRoot;
24
+ #directory;
25
+ #rootPackageJson;
26
+ #ig;
27
+ #workspaceRoot;
26
28
  constructor(directory, {
27
29
  workspaceRoot,
28
30
  rootPackageJson,
29
31
  gitignorePatterns = []
30
32
  }) {
31
- this.directory = directory;
32
- this.rootPackageJson = rootPackageJson;
33
- this.ig = ignore().add(gitignorePatterns);
34
- this.workspaceRoot = workspaceRoot;
33
+ this.#directory = directory;
34
+ this.#rootPackageJson = rootPackageJson;
35
+ this.#ig = ignore().add(gitignorePatterns);
36
+ this.#workspaceRoot = workspaceRoot;
35
37
  }
36
38
  async getMonorepoDependencies(projectName, { pkgs = [], libs = [] } = {}) {
37
- const npmSet = new Set(Object.keys({ ...this.rootPackageJson.dependencies, ...this.rootPackageJson.devDependencies }));
39
+ const npmSet = new Set(Object.keys({ ...this.#rootPackageJson.dependencies, ...this.#rootPackageJson.devDependencies }));
38
40
  const pkgPathSet = new Set(pkgs);
39
41
  const libPathSet = new Set(libs.map((lib) => `@libs/${lib}`));
40
42
  await this.getDependencies();
41
43
  const [npmDepSet, pkgPathDepSet, libPathDepSet] = this.#getImportSetsFromDependencies([npmSet, pkgPathSet, libPathSet], this.#fileRuntimeDependencies);
42
44
  const [npmDevDepSet] = this.#getImportSetsFromDependencies([npmSet], this.#fileTypeDependencies);
43
45
  const pkgDeps = [...pkgPathDepSet];
44
- const libDeps = [...libPathDepSet].map((path2) => path2.replace("@libs/", "")).filter((libName) => libName !== projectName);
46
+ const libDeps = [...libPathDepSet].map((path) => path.replace("@libs/", "")).filter((libName) => libName !== projectName);
45
47
  return {
46
48
  pkgDeps,
47
49
  libDeps,
@@ -52,11 +54,11 @@ class TypeScriptDependencyScanner {
52
54
  async getPackageBuildDependencies(projectName) {
53
55
  const runtimeDeps = new Set;
54
56
  const devDeps = new Set;
55
- const sourceFiles = await this.#findTypeScriptFiles(this.directory, {
57
+ const sourceFiles = await this.#findTypeScriptFiles(this.#directory, {
56
58
  excludeBuildFiles: true,
57
59
  excludeTestFiles: true
58
60
  });
59
- const cssFiles = await this.#findCssFiles(this.directory);
61
+ const cssFiles = await this.#findCssFiles(this.#directory);
60
62
  for (const filePath of sourceFiles) {
61
63
  const fileContent = await FileSys.readText(filePath);
62
64
  const { imports, typeImports } = this.#extractImports(fileContent, filePath);
@@ -67,7 +69,7 @@ class TypeScriptDependencyScanner {
67
69
  const fileContent = await FileSys.readText(filePath);
68
70
  this.#addNormalizedImports(runtimeDeps, this.#extractCssPluginImports(fileContent), projectName);
69
71
  }
70
- const buildFilePath = path.join(this.directory, "build.ts");
72
+ const buildFilePath = path.join(this.#directory, "build.ts");
71
73
  if (await FileSys.fileExists(buildFilePath)) {
72
74
  const fileContent = await FileSys.readText(buildFilePath);
73
75
  const { imports, typeImports } = this.#extractImports(fileContent, buildFilePath);
@@ -75,7 +77,7 @@ class TypeScriptDependencyScanner {
75
77
  }
76
78
  for (const dep of runtimeDeps)
77
79
  devDeps.delete(dep);
78
- const rootDeps = { ...this.rootPackageJson.dependencies, ...this.rootPackageJson.devDependencies };
80
+ const rootDeps = { ...this.#rootPackageJson.dependencies, ...this.#rootPackageJson.devDependencies };
79
81
  const missingDeps = [];
80
82
  for (const dep of [...runtimeDeps, ...devDeps]) {
81
83
  if (rootDeps[dep] || await this.#hasWorkspacePackage(dep))
@@ -89,7 +91,7 @@ class TypeScriptDependencyScanner {
89
91
  };
90
92
  }
91
93
  async#hasWorkspacePackage(dep) {
92
- const packageJsonPath = path.join(this.workspaceRoot, "pkgs", dep, "package.json");
94
+ const packageJsonPath = path.join(this.#workspaceRoot, "pkgs", dep, "package.json");
93
95
  if (!await Bun.file(packageJsonPath).exists())
94
96
  return false;
95
97
  try {
@@ -132,9 +134,9 @@ class TypeScriptDependencyScanner {
132
134
  this.#fileRuntimeDependencies.clear();
133
135
  this.#fileTypeDependencies.clear();
134
136
  this.#visitedFiles.clear();
135
- const files = await this.#findTypeScriptFiles(this.directory);
137
+ const files = await this.#findTypeScriptFiles(this.#directory);
136
138
  for (const file of files)
137
- await this.#analyzeFile(file, this.directory);
139
+ await this.#analyzeFile(file, this.#directory);
138
140
  return this.#fileDependencies;
139
141
  }
140
142
  async#findTypeScriptFiles(directory, {
@@ -142,18 +144,17 @@ class TypeScriptDependencyScanner {
142
144
  excludeTestFiles = false
143
145
  } = {}) {
144
146
  const files = [];
145
- const skipDirs = ["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android"];
146
147
  const glob = new Bun.Glob("**/*.{ts,tsx}");
147
148
  for await (const filePath of glob.scan({ cwd: directory, onlyFiles: true })) {
148
- if (skipDirs.some((dir) => filePath.includes(`/${dir}/`) || filePath.startsWith(`${dir}/`)))
149
+ if (isSkippedPath(filePath))
149
150
  continue;
150
151
  if (excludeBuildFiles && filePath === "build.ts")
151
152
  continue;
152
153
  if (excludeTestFiles && testFileRegex.test(filePath))
153
154
  continue;
154
155
  const fullPath = path.join(directory, filePath);
155
- const relativePath = path.relative(this.workspaceRoot, fullPath);
156
- if (this.ig.ignores(relativePath))
156
+ const relativePath = path.relative(this.#workspaceRoot, fullPath);
157
+ if (this.#ig.ignores(relativePath))
157
158
  continue;
158
159
  files.push(fullPath);
159
160
  }
@@ -161,14 +162,13 @@ class TypeScriptDependencyScanner {
161
162
  }
162
163
  async#findCssFiles(directory) {
163
164
  const files = [];
164
- const skipDirs = ["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android"];
165
165
  const glob = new Bun.Glob("**/*.css");
166
166
  for await (const filePath of glob.scan({ cwd: directory, onlyFiles: true })) {
167
- if (skipDirs.some((dir) => filePath.includes(`/${dir}/`) || filePath.startsWith(`${dir}/`)))
167
+ if (isSkippedPath(filePath))
168
168
  continue;
169
169
  const fullPath = path.join(directory, filePath);
170
- const relativePath = path.relative(this.workspaceRoot, fullPath);
171
- if (this.ig.ignores(relativePath))
170
+ const relativePath = path.relative(this.#workspaceRoot, fullPath);
171
+ if (this.#ig.ignores(relativePath))
172
172
  continue;
173
173
  files.push(fullPath);
174
174
  }
@@ -289,7 +289,7 @@ class TypeScriptDependencyScanner {
289
289
  exec.workspace.getPackageJson(),
290
290
  exec.workspace.getGitignorePatterns()
291
291
  ]);
292
- return new TypeScriptDependencyScanner(exec.cwdPath, {
292
+ return new TypeScriptDependencyScanner2(exec.cwdPath, {
293
293
  workspaceRoot: exec.workspace.cwdPath,
294
294
  tsconfig,
295
295
  rootPackageJson,
@@ -298,4 +298,4 @@ class TypeScriptDependencyScanner {
298
298
  }
299
299
  }
300
300
 
301
- export { TypeScriptDependencyScanner };
301
+ export { TypeScriptDependencyScanner2 };
@@ -1,20 +1,11 @@
1
1
  // @bun
2
2
  // pkgs/@akanjs/devkit/frontendBuild/styleContract.ts
3
- var countBlocking = (v) => v.style.filter((s) => s.severity === "error").length + v.theme.length;
4
- var formatStyleContract = (v) => {
5
- const lines = [];
6
- for (const s of v.style) {
7
- lines.push(` [${s.severity}] ${s.rule} ${s.path}:${s.line}`);
8
- lines.push(` ${s.snippet}`);
9
- lines.push(` \u2192 ${s.suggestion}`);
10
- }
11
- for (const t of v.theme) {
12
- lines.push(` [error] contrast ${t.scope} ${t.pair} = ${t.ratio}:1 (min ${t.threshold}:1)`);
13
- lines.push(` \u2192 ${t.suggestion}`);
14
- }
15
- return lines.join(`
3
+ var countBlocking = (violations) => violations.theme.length;
4
+ var formatStyleContract = (violations) => violations.theme.flatMap((theme) => [
5
+ ` [error] contrast ${theme.scope} ${theme.pair} = ${theme.ratio}:1 (min ${theme.threshold}:1)`,
6
+ ` \u2192 ${theme.suggestion}`
7
+ ]).join(`
16
8
  `);
17
- };
18
9
 
19
10
  // pkgs/@akanjs/devkit/frontendBuild/themeValidator.ts
20
11
  var PAIRS = [
@@ -66,7 +57,7 @@ class ThemeValidator {
66
57
  foreground: front,
67
58
  ratio: Math.round(ratio * 100) / 100,
68
59
  threshold,
69
- suggestion: `${scope}\uC758 --${base}(${bg})\uC640 --${fg}(${front}) \uB300\uBE44\uAC00 ${ratio.toFixed(2)}:1 \uB85C \uCD5C\uC18C ${threshold}:1 \uBBF8\uB9CC\uC785\uB2C8\uB2E4. \uD55C\uCABD\uC744 \uB354 \uBC1D\uAC8C/\uC5B4\uB461\uAC8C \uC870\uC815\uD574 \uB300\uBE44\uB97C \uD655\uBCF4\uD558\uC138\uC694.`
60
+ suggestion: `In ${scope}, --${base} (${bg}) against --${fg} (${front}) is ${ratio.toFixed(2)}:1, under the ${threshold}:1 minimum. Lighten or darken one of them until it clears.`
70
61
  });
71
62
  }
72
63
  return violations;
@@ -1,17 +1,17 @@
1
1
  // @bun
2
2
  import {
3
- AkanContextAnalyzer
4
- } from "./index-mssqn2sq.js";
5
- import {
6
- createRepairReport,
3
+ writeWorkflowRunArtifact,
7
4
  generatedFilePathsForTarget,
8
- renderRepairReport,
9
5
  writeGeneratedSyncState,
10
- writeWorkflowRunArtifact
11
- } from "./index-2c3e2xh8.js";
6
+ createRepairReport,
7
+ renderRepairReport
8
+ } from "./index-saheq2bs.js";
9
+ import {
10
+ AkanContextAnalyzer
11
+ } from "./index-5y7qba1c.js";
12
12
  import {
13
13
  runner
14
- } from "./index-6rhabeev.js";
14
+ } from "./index-ft1sfjz0.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/repair/repair.runner.ts
17
17
  var commandForShell = (command) => command.startsWith("akan ") ? `bun run ${command}` : command;
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-vg0sj9nc.js";
5
+ } from "./index-k1n0h7dk.js";
6
6
 
7
7
  // pkgs/@akanjs/devkit/workflow/utils.ts
8
8
  var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `
@@ -914,9 +914,9 @@ ${options.closingIndent}}`);
914
914
  const beforeField = locator.fields[insertIndex];
915
915
  if (beforeField) {
916
916
  const leadingComments = ts.getLeadingCommentRanges(content, beforeField.fullStart) ?? [];
917
- const insertAt2 = lineStartAt(content, leadingComments[0]?.pos ?? beforeField.start);
918
- const indent2 = lineIndentAt(content, beforeField.start) || options.fieldIndent;
919
- return spliceText(content, insertAt2, insertAt2, `${indent2}${formattedLine}
917
+ const insertAt = lineStartAt(content, leadingComments[0]?.pos ?? beforeField.start);
918
+ const indent = lineIndentAt(content, beforeField.start) || options.fieldIndent;
919
+ return spliceText(content, insertAt, insertAt, `${indent}${formattedLine}
920
920
  `);
921
921
  }
922
922
  const afterField = locator.fields[locator.fields.length - 1];
@@ -1,22 +1,22 @@
1
1
  // @bun
2
2
  import {
3
- pluralizeName
4
- } from "./index-ss469dec.js";
5
- import {
6
- AiSession
7
- } from "./index-0cj2zxbm.js";
3
+ runner,
4
+ script
5
+ } from "./index-ft1sfjz0.js";
8
6
  import {
9
- createPassedPrimitiveReport,
10
7
  generatedFilesForSync,
8
+ createPassedPrimitiveReport,
11
9
  scalarChangedFiles
12
- } from "./index-2c3e2xh8.js";
10
+ } from "./index-saheq2bs.js";
11
+ import {
12
+ AiSession
13
+ } from "./index-wet2ytnr.js";
13
14
  import {
14
15
  Prompter
15
- } from "./index-7myvn0f0.js";
16
+ } from "./index-h7yw2z9n.js";
16
17
  import {
17
- runner,
18
- script
19
- } from "./index-6rhabeev.js";
18
+ pluralizeName
19
+ } from "./index-nz8prx9g.js";
20
20
 
21
21
  // pkgs/@akanjs/cli/scalar/scalar.prompt.ts
22
22
  import { input } from "@inquirer/prompts";
@@ -192,9 +192,9 @@ class ScalarRunner extends runner("scalar") {
192
192
  const { request, validate } = await prompt.requestUpdateDictonaryWithInstruction();
193
193
  await session.writeTypescripts(request, sys, { validate });
194
194
  for (const scalarName of followingScalarNames) {
195
- const prompt2 = new ScalarPrompt(sys, scalarName);
196
- const { request: request2, validate: validate2 } = await prompt2.requestUpdateDictonaryWithFollowing();
197
- await session.writeTypescripts(request2, sys, { validate: validate2 });
195
+ const prompt = new ScalarPrompt(sys, scalarName);
196
+ const { request, validate } = await prompt.requestUpdateDictonaryWithFollowing();
197
+ await session.writeTypescripts(request, sys, { validate });
198
198
  }
199
199
  }
200
200
  }
@@ -1,13 +1,13 @@
1
1
  // @bun
2
- import {
3
- Spinner
4
- } from "./index-mxvakhsm.js";
5
2
  import {
6
3
  FileSys
7
- } from "./index-67546d0j.js";
4
+ } from "./index-ayy5ecax.js";
5
+ import {
6
+ Spinner
7
+ } from "./index-k1n0h7dk.js";
8
8
 
9
9
  // pkgs/@akanjs/devkit/cloud/globalConfig.ts
10
- import { mkdir } from "fs/promises";
10
+ import { chmod, mkdir } from "fs/promises";
11
11
  import dayjs from "dayjs";
12
12
 
13
13
  // pkgs/@akanjs/devkit/cloud/constants.ts
@@ -34,8 +34,9 @@ class GlobalConfig {
34
34
  };
35
35
  }
36
36
  static async#setAkanGlobalConfig(akanConfig) {
37
- await mkdir(basePath, { recursive: true });
37
+ await mkdir(basePath, { recursive: true, mode: 448 });
38
38
  await Bun.write(configPath, JSON.stringify(akanConfig, null, 2));
39
+ await chmod(configPath, 384);
39
40
  }
40
41
  static async getHostConfig(host = GlobalConfig.akanCloudHost) {
41
42
  const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
@@ -240,7 +241,7 @@ import { ChatOpenAI } from "@langchain/openai";
240
241
  import { Logger } from "akanjs/common";
241
242
  import chalk from "chalk";
242
243
  var MAX_ASK_TRY = 300;
243
- var deepSeekLlmModels = ["deepseek-chat", "deepseek-reasoner"];
244
+ var deepSeekLlmModels = ["deepseek-v4-flash", "deepseek-v4-pro"];
244
245
  var openAiLlmModels = ["gpt-5.5"];
245
246
  var supportedLlmModels = [...deepSeekLlmModels, ...openAiLlmModels];
246
247
  var isOpenAiLlmModel = (model) => openAiLlmModels.includes(model);
@@ -275,10 +276,10 @@ class AiSession {
275
276
  static #chat = null;
276
277
  static async init({ temperature = 0, useExisting = true } = {}) {
277
278
  if (useExisting) {
278
- const llmConfig2 = await AiSession.getLlmConfig();
279
- if (llmConfig2) {
280
- AiSession.#setChatModel(llmConfig2.model, llmConfig2.apiKey);
281
- Logger.rawLog(chalk.dim(`\uD83E\uDD16akan editor uses existing LLM config (${llmConfig2.model})`));
279
+ const llmConfig = await AiSession.getLlmConfig();
280
+ if (llmConfig) {
281
+ AiSession.#setChatModel(llmConfig.model, llmConfig.apiKey);
282
+ Logger.rawLog(chalk.dim(`\uD83E\uDD16akan editor uses existing LLM config (${llmConfig.model})`));
282
283
  return AiSession;
283
284
  }
284
285
  } else
@@ -349,7 +349,7 @@ var resolveNodePackageExport = async (workspaceRoot, specifier) => {
349
349
  const subpath = specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
350
350
  const exported = resolvePackageExport(pkgJson.exports, subpath);
351
351
  const rel = exported ?? (subpath === "." ? pkgJson.module ?? pkgJson.main ?? "index.js" : null);
352
- if (!rel || !rel.startsWith("."))
352
+ if (!rel?.startsWith("."))
353
353
  return null;
354
354
  const entryFile = await resolveFileCandidate(path2.resolve(pkgDir, rel));
355
355
  if (!entryFile)
@@ -849,6 +849,7 @@ class ClientEntriesBundler {
849
849
  #externalSubpaths;
850
850
  #externalAliases;
851
851
  #command;
852
+ #target;
852
853
  #outputSubdir;
853
854
  #reactFastRefresh;
854
855
  #artifactDir;
@@ -870,6 +871,7 @@ class ClientEntriesBundler {
870
871
  this.#externalSubpaths = options.externalSubpaths ?? [];
871
872
  this.#externalAliases = options.externalAliases ?? {};
872
873
  this.#command = options.command ?? "start";
874
+ this.#target = options.target ?? "browser";
873
875
  this.#outputSubdir = options.outputSubdir ?? "client";
874
876
  this.#reactFastRefresh = options.reactFastRefresh ?? false;
875
877
  this.#artifactDir = `${this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath}/.akan/artifact`;
@@ -883,7 +885,7 @@ class ClientEntriesBundler {
883
885
  entrypoints: this.#opaqueEntries.entries,
884
886
  outdir: this.#outdir,
885
887
  splitting: true,
886
- target: "browser",
888
+ target: this.#target,
887
889
  format: "esm",
888
890
  naming: CLIENT_BUNDLE_NAMING,
889
891
  metafile: true,
@@ -1117,7 +1119,8 @@ var VENDOR_SPECIFIERS = [
1117
1119
  "akanjs/store",
1118
1120
  "akanjs/base",
1119
1121
  "akanjs/common",
1120
- "akanjs/constant"
1122
+ "akanjs/constant",
1123
+ "akanjs/fetch"
1121
1124
  ];
1122
1125
 
1123
1126
  // pkgs/@akanjs/devkit/frontendBuild/routeClientBuilder.ts
@@ -1226,12 +1229,11 @@ class RouteClientBuilder {
1226
1229
  }).bundle();
1227
1230
  }
1228
1231
  async#buildSsrBundle(bootstrapEntries) {
1229
- const externalOptions = RouteClientBuilder.resolveSsrClientExternalOptions(this.#command);
1230
1232
  return new ClientEntriesBundler({
1231
1233
  app: this.#app,
1232
1234
  entries: bootstrapEntries.buildEntries,
1233
1235
  plugins: [await createBarrelImportsPlugin(this.#app)],
1234
- ...externalOptions,
1236
+ ...RouteClientBuilder.resolveSsrClientBundleOptions(this.#command),
1235
1237
  outputSubdir: "client-ssr",
1236
1238
  command: this.#command
1237
1239
  }).bundle();
@@ -1293,15 +1295,16 @@ ${defaultNames.map((name) => `export default ${name};`).join(`
1293
1295
  const serverEntry = RouteClientBuilder.resolveAkanServerEntry();
1294
1296
  return { [Bun.resolveSync("akanjs/fetch", serverEntry)]: "akanjs/fetch" };
1295
1297
  }
1296
- static resolveSsrClientExternalOptions(command) {
1298
+ static resolveSsrClientBundleOptions(command) {
1297
1299
  if (command === "start") {
1298
1300
  return {
1301
+ target: "bun",
1299
1302
  external: SSR_CLIENT_EXTERNALS,
1300
1303
  externalSubpaths: ["akanjs/fetch"],
1301
1304
  externalAliases: RouteClientBuilder.resolveSsrClientRuntimeAliases()
1302
1305
  };
1303
1306
  }
1304
- return { external: SSR_CLIENT_ALIAS_EXTERNALS };
1307
+ return { target: "bun", external: SSR_CLIENT_ALIAS_EXTERNALS };
1305
1308
  }
1306
1309
  static resolveAkanServerEntry() {
1307
1310
  try {
@@ -1515,6 +1518,8 @@ class AutoImportSync {
1515
1518
  const [scope, project, facet] = parts;
1516
1519
  if (scope !== "apps" && scope !== "libs" || !project || !facet)
1517
1520
  return null;
1521
+ if (facet === "lib" && parts[3] === "__lib")
1522
+ return null;
1518
1523
  const role = roleFor(facet, base);
1519
1524
  if (!role)
1520
1525
  return null;