@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
@@ -1,87 +1,84 @@
1
1
  // @bun
2
2
  import {
3
- ContextScript
4
- } from "./index-w6wbb612.js";
5
- import"./index-ztpw544k.js";
6
- import"./index-5pmx7bkg.js";
7
- import"./index-bz2sfzzt.js";
8
- import"./index-vtj3zps1.js";
9
- import"./index-4hek879p.js";
3
+ FileSys
4
+ } from "./index-ayy5ecax.js";
10
5
  import {
11
- CloudScript
12
- } from "./index-js368gk9.js";
6
+ GlobalConfig
7
+ } from "./index-wet2ytnr.js";
13
8
  import {
14
- getLatestPackageVersion,
15
- getNpmRegistryUrl
16
- } from "./index-p3f4q532.js";
9
+ Exec,
10
+ Workspace,
11
+ runner,
12
+ script,
13
+ command
14
+ } from "./index-ft1sfjz0.js";
17
15
  import {
18
- PackageScript
19
- } from "./index-azv0xjb5.js";
20
- import"./index-gmy45vz2.js";
21
- import"./index-ss469dec.js";
22
- import"./index-xhgtkekh.js";
16
+ extractAgentBlock,
17
+ collectScopeRecipeSources,
18
+ renderScopeAgentBlock,
19
+ WorkspaceExecutor,
20
+ SysExecutor,
21
+ AppExecutor,
22
+ LibExecutor,
23
+ PkgExecutor
24
+ } from "./index-k1n0h7dk.js";
25
+ import"./index-6wwzs1bc.js";
23
26
  import {
24
- GlobalConfig
25
- } from "./index-0cj2zxbm.js";
27
+ countBlocking,
28
+ formatStyleContract,
29
+ ThemeValidator
30
+ } from "./index-n68jx79w.js";
31
+ import {
32
+ collectRecipeSources2,
33
+ scanRecipes2
34
+ } from "./index-by5gpp8x.js";
35
+ import"./index-saheq2bs.js";
36
+ import"./index-5y7qba1c.js";
37
+ import"./index-h7yw2z9n.js";
26
38
  import {
27
39
  AgentScript
28
- } from "./index-gex7c8kd.js";
29
- import"./index-mssqn2sq.js";
30
- import"./index-2c3e2xh8.js";
31
- import"./index-7myvn0f0.js";
40
+ } from "./index-5n0hf8r9.js";
32
41
  import {
33
42
  ApplicationScript
34
- } from "./index-5dw57f0d.js";
35
- import"./index-76rn3g2c.js";
43
+ } from "./index-m7e0f1sy.js";
36
44
  import {
37
45
  LibraryScript
38
- } from "./index-a1e0j63x.js";
46
+ } from "./index-xxe90kqy.js";
47
+ import"./index-ctphds8v.js";
48
+ import"./index-mfm35dhh.js";
39
49
  import {
40
- Exec,
41
- Workspace,
42
- command,
43
- runner,
44
- script
45
- } from "./index-6rhabeev.js";
46
- import"./index-fgc8r6dj.js";
50
+ PackageScript
51
+ } from "./index-a8h184wr.js";
47
52
  import {
48
- ThemeValidator,
49
- countBlocking,
50
- formatStyleContract
51
- } from "./index-xjd3rqzj.js";
52
- import"./index-bjpxzr6s.js";
53
+ getNpmRegistryUrl,
54
+ getLatestPackageVersion
55
+ } from "./index-1tgp56ke.js";
53
56
  import {
54
- AppExecutor,
55
- LibExecutor,
56
- PkgExecutor,
57
- SysExecutor,
58
- WorkspaceExecutor,
59
- collectScopeRecipeSources,
60
- extractAgentBlock,
61
- renderScopeAgentBlock
62
- } from "./index-vg0sj9nc.js";
63
- import"./index-mxvakhsm.js";
64
- import {
65
- collectRecipeSources,
66
- scanRecipes
67
- } from "./index-xys926f2.js";
68
- import"./index-46tjzh6s.js";
57
+ CloudScript
58
+ } from "./index-ypvdw8nr.js";
69
59
  import {
70
- FileSys
71
- } from "./index-67546d0j.js";
72
- import"./index-r24hmh0q.js";
73
-
74
- // pkgs/@akanjs/cli/workspace/workspace.script.ts
75
- import path2 from "path";
76
- import { Logger } from "akanjs/common";
60
+ ContextScript
61
+ } from "./index-dq6wq1tv.js";
62
+ import"./index-b2nt0w0k.js";
63
+ import"./index-qcracvc9.js";
64
+ import"./index-j9vnq8tr.js";
65
+ import"./index-k86zc21w.js";
66
+ import"./index-1kzsn94d.js";
67
+ import"./index-cd5x18qh.js";
68
+ import"./index-v0s24t8j.js";
69
+ import"./index-m9c7k0gm.js";
77
70
 
78
71
  // pkgs/@akanjs/cli/workspace/workspace.runner.ts
79
72
  import path from "path";
73
+
74
+ // pkgs/@akanjs/devkit/biomeBase.ts
75
+ var biomeVersion = "2.5.8";
76
+
77
+ // pkgs/@akanjs/cli/workspace/workspace.runner.ts
80
78
  var defaultWorkspacePeerDependencies = new Set([
81
79
  "@react-spring/web",
82
80
  "@use-gesture/react",
83
81
  "chance",
84
- "croner",
85
82
  "react",
86
83
  "react-dom",
87
84
  "react-icons",
@@ -93,6 +90,7 @@ var defaultWorkspacePeerDependencies = new Set([
93
90
  "tailwindcss",
94
91
  "typescript"
95
92
  ]);
93
+ var defaultMaxDiagnostics = 200;
96
94
 
97
95
  class WorkspaceRunner extends runner("workspace") {
98
96
  async generateAgentRules(workspace, { overwrite = false, cursorRules = true } = {}) {
@@ -113,17 +111,14 @@ class WorkspaceRunner extends runner("workspace") {
113
111
  dict,
114
112
  overwrite
115
113
  }));
116
- if (!cursorRules)
117
- return created;
118
- return [
119
- ...created,
120
- ...await workspace.applyTemplate({
114
+ if (cursorRules)
115
+ created.push(...await workspace.applyTemplate({
121
116
  basePath: ".cursor/rules",
122
117
  template: "workspaceRoot/.cursor/rules/akan.mdc.template",
123
118
  dict,
124
119
  overwrite
125
- })
126
- ];
120
+ }));
121
+ return created;
127
122
  }
128
123
  async createWorkspace(repoName, appName, {
129
124
  dirname = ".",
@@ -137,10 +132,7 @@ class WorkspaceRunner extends runner("workspace") {
137
132
  const normalizedRegistryUrl = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
138
133
  const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
139
134
  const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname}/${repoName}...`);
140
- const [latestBiomeVersion, latestTypesBunVersion] = await Promise.all([
141
- getLatestPackageVersion("@biomejs/biome", "latest", normalizedRegistryUrl),
142
- getLatestPackageVersion("@types/bun", "latest", normalizedRegistryUrl)
143
- ]);
135
+ const latestTypesBunVersion = await getLatestPackageVersion("@types/bun", "latest", normalizedRegistryUrl);
144
136
  await workspace.applyTemplate({
145
137
  basePath: ".",
146
138
  template: "workspaceRoot",
@@ -164,7 +156,7 @@ class WorkspaceRunner extends runner("workspace") {
164
156
  },
165
157
  devDependencies: {
166
158
  ...rootPackageJson.devDependencies,
167
- "@biomejs/biome": latestBiomeVersion,
159
+ "@biomejs/biome": biomeVersion,
168
160
  "@types/bun": latestTypesBunVersion,
169
161
  "@akanjs/devkit": akanVersion,
170
162
  ...typescript ? { typescript } : {}
@@ -236,24 +228,35 @@ class WorkspaceRunner extends runner("workspace") {
236
228
  }
237
229
  throw new Error(`[workspace] failed to locate akanjs package.json from ${import.meta.dir}`);
238
230
  }
239
- async lint(exec, workspace, { fix = true } = {}) {
231
+ async lint(exec, workspace, { fix = true, maxDiagnostics = defaultMaxDiagnostics } = {}) {
232
+ const configPath = await WorkspaceRunner.resolveBiomeConfigPath(workspace);
240
233
  await workspace.spawn("./node_modules/.bin/biome", [
241
234
  "check",
242
235
  ...fix ? ["--write"] : [],
243
236
  "--no-errors-on-unmatched",
237
+ `--max-diagnostics=${maxDiagnostics > 0 ? maxDiagnostics : "none"}`,
238
+ ...configPath ? ["--config-path", configPath] : [],
244
239
  exec.cwdPath
245
240
  ]);
246
241
  await this.#enforceStyleContract(exec);
247
242
  await this.#enforceRecipeGate(exec);
248
243
  await this.#enforceAgentsIndex(exec);
249
244
  }
245
+ static async resolveBiomeConfigPath(workspace) {
246
+ for (const fileName of ["biome.json", "biome.jsonc"]) {
247
+ const configPath = path.join(workspace.workspaceRoot, fileName);
248
+ if (await Bun.file(configPath).exists())
249
+ return configPath;
250
+ }
251
+ return null;
252
+ }
250
253
  async#enforceAgentsIndex(exec) {
251
254
  if (!(exec instanceof SysExecutor))
252
255
  return;
253
256
  const scope = { type: exec.type, name: exec.name };
254
257
  const scanInfo = await exec.scan({ write: false });
255
258
  const sources = await collectScopeRecipeSources(exec.workspace.workspaceRoot, scope, scanInfo.getScanResult().libDeps);
256
- const expected = renderScopeAgentBlock(scope, scanRecipes(sources));
259
+ const expected = renderScopeAgentBlock(scope, scanRecipes2(sources));
257
260
  const existing = await exec.exists("AGENTS.md") ? await exec.readFile("AGENTS.md") : null;
258
261
  const actual = existing ? extractAgentBlock(existing) : null;
259
262
  if (actual === expected.trim())
@@ -266,12 +269,12 @@ class WorkspaceRunner extends runner("workspace") {
266
269
  return;
267
270
  const uiDir = path.join(cwdPath, "ui");
268
271
  const sources = [
269
- ...await collectRecipeSources(uiDir, "ui/Recipe"),
270
- ...await collectRecipeSources(uiDir, "ui/recipe", "recipe")
272
+ ...await collectRecipeSources2(uiDir, "ui/Recipe"),
273
+ ...await collectRecipeSources2(uiDir, "ui/recipe", "recipe")
271
274
  ];
272
275
  if (sources.length === 0)
273
276
  return;
274
- const offenders = scanRecipes(sources).filter((recipe) => !Object.values(recipe.variants).some((values) => values.length >= 2 || values.length === 1 && values[0] === "true"));
277
+ const offenders = scanRecipes2(sources).filter((recipe) => !Object.values(recipe.variants).some((values) => values.length >= 2 || values.length === 1 && values[0] === "true"));
275
278
  if (offenders.length === 0)
276
279
  return;
277
280
  throw new Error(`[recipeGate] variant-less recipe(s): ${offenders.map((recipe) => recipe.name).join(", ")}
@@ -282,15 +285,18 @@ class WorkspaceRunner extends runner("workspace") {
282
285
  if (!cwdPath)
283
286
  return;
284
287
  const stylesCssPath = path.join(cwdPath, "page", "styles.css");
285
- const theme = await Bun.file(stylesCssPath).exists() ? new ThemeValidator().validate(await Bun.file(stylesCssPath).text()) : [];
286
- const violations = { style: [], theme };
288
+ if (!await Bun.file(stylesCssPath).exists())
289
+ return;
290
+ const violations = {
291
+ theme: new ThemeValidator().validate(await Bun.file(stylesCssPath).text())
292
+ };
287
293
  const blocking = countBlocking(violations);
288
294
  if (blocking === 0)
289
295
  return;
290
296
  throw new Error(`[themeValidator] ${blocking} blocking contrast violation(s):
291
297
  ${formatStyleContract(violations)}
292
298
 
293
- ` + "\uD14C\uB9C8 \uD1A0\uD070 \uAC12\uC758 \uC804\uACBD/\uBC30\uACBD \uCF58\uD2B8\uB77C\uC2A4\uD2B8\uB97C WCAG \uAE30\uC900 \uC774\uC0C1\uC73C\uB85C \uC870\uC815\uD558\uC138\uC694.");
299
+ ` + "Raise the foreground/background contrast of these theme token values to the WCAG threshold.");
294
300
  }
295
301
  async writeTopLevelEnv(workspace, devProjectId) {
296
302
  await workspace.writeFile(".env", `AKAN_WORKSPACE_ID=${devProjectId}
@@ -314,6 +320,8 @@ AKAN_PUBLIC_LOG_LEVEL=debug
314
320
  }
315
321
 
316
322
  // pkgs/@akanjs/cli/workspace/workspace.script.ts
323
+ import path2 from "path";
324
+ import { Logger } from "akanjs/common";
317
325
  class WorkspaceScript extends script("workspace", [
318
326
  WorkspaceRunner,
319
327
  ApplicationScript,
@@ -372,30 +380,33 @@ class WorkspaceScript extends script("workspace", [
372
380
  async generateAgentRules(workspace, { overwrite = false, cursorRules = true } = {}) {
373
381
  const spinner = workspace.spinning("Generating agent rules...");
374
382
  const files = await this.workspaceRunner.generateAgentRules(workspace, { overwrite, cursorRules });
383
+ if (files.some((file) => file.filePath.endsWith("AGENTS.md")))
384
+ await this.agentScript.agent(workspace, "install", "agents-md", { force: overwrite });
375
385
  spinner.succeed(`Agent rules ready (${files.length} file${files.length === 1 ? "" : "s"})`);
376
386
  }
377
- async lint(exec, workspace, { fix = true } = {}) {
387
+ async lint(exec, workspace, { fix = true, maxDiagnostics } = {}) {
378
388
  if (exec instanceof AppExecutor)
379
389
  await this.applicationScript.sync(exec);
380
390
  else if (exec instanceof LibExecutor)
381
391
  await this.libraryScript.syncLibrary(exec);
382
392
  const spinner = workspace.spinning(`Linting${fix ? " with fix" : ""}...`);
383
393
  try {
384
- await this.workspaceRunner.lint(exec, workspace, { fix });
394
+ await this.workspaceRunner.lint(exec, workspace, { fix, maxDiagnostics });
385
395
  spinner.succeed("Lint completed with no errors");
386
396
  } catch (error) {
387
397
  spinner.fail("Lint failed with errors");
388
398
  throw error;
389
399
  }
390
400
  }
391
- async lintAll(workspace, { fix = true } = {}) {
401
+ async lintAll(workspace, { fix = true, maxDiagnostics } = {}) {
392
402
  const [appNames, libNames, pkgNames] = await workspace.getExecs();
403
+ const options = { fix, maxDiagnostics };
393
404
  await Promise.all(appNames.map((appName) => this.applicationScript.sync(AppExecutor.from(workspace, appName))));
394
405
  await Promise.all(libNames.map((libName) => this.libraryScript.syncLibrary(LibExecutor.from(workspace, libName))));
395
406
  await Promise.all([
396
- ...appNames.map((appName) => this.workspaceRunner.lint(AppExecutor.from(workspace, appName), workspace, { fix })),
397
- ...libNames.map((libName) => this.workspaceRunner.lint(LibExecutor.from(workspace, libName), workspace, { fix })),
398
- ...pkgNames.filter((pkgName) => pkgName !== "contract").map((pkgName) => this.workspaceRunner.lint(PkgExecutor.from(workspace, pkgName), workspace, { fix }))
407
+ ...appNames.map((appName) => this.workspaceRunner.lint(AppExecutor.from(workspace, appName), workspace, options)),
408
+ ...libNames.map((libName) => this.workspaceRunner.lint(LibExecutor.from(workspace, libName), workspace, options)),
409
+ ...pkgNames.filter((pkgName) => pkgName !== "contract").map((pkgName) => this.workspaceRunner.lint(PkgExecutor.from(workspace, pkgName), workspace, options))
399
410
  ]);
400
411
  }
401
412
  async syncAll(workspace) {
@@ -477,11 +488,17 @@ class WorkspaceCommand extends command("workspace", [WorkspaceScript], ({ public
477
488
  }).option("overwrite", Boolean, { desc: "Overwrite existing agent rule files", default: false }).option("cursorRules", Boolean, { desc: "Generate .cursor/rules/akan.mdc", default: true }).with(Workspace).exec(async function(overwrite, cursorRules, workspace) {
478
489
  await this.workspaceScript.generateAgentRules(workspace, { overwrite, cursorRules });
479
490
  }),
480
- lint: target({ desc: "Lint and fix code in a specific app/lib/pkg" }).with(Exec).option("fix", Boolean, { default: true }).with(Workspace).exec(async function(exec, fix, workspace) {
481
- await this.workspaceScript.lint(exec, workspace, { fix });
491
+ lint: target({ desc: "Lint and fix code in a specific app/lib/pkg" }).with(Exec).option("fix", Boolean, { default: true }).option("maxDiagnostics", Number, {
492
+ desc: "How many diagnostics Biome prints before truncating (0 for no limit)",
493
+ default: defaultMaxDiagnostics
494
+ }).with(Workspace).exec(async function(exec, fix, maxDiagnostics, workspace) {
495
+ await this.workspaceScript.lint(exec, workspace, { fix, maxDiagnostics });
482
496
  }),
483
- lintAll: target({ desc: "Lint and fix code in all apps and libraries" }).option("fix", Boolean, { default: true }).with(Workspace).exec(async function(fix, workspace) {
484
- await this.workspaceScript.lintAll(workspace, { fix });
497
+ lintAll: target({ desc: "Lint and fix code in all apps and libraries" }).option("fix", Boolean, { default: true }).option("maxDiagnostics", Number, {
498
+ desc: "How many diagnostics Biome prints before truncating (0 for no limit)",
499
+ default: defaultMaxDiagnostics
500
+ }).with(Workspace).exec(async function(fix, maxDiagnostics, workspace) {
501
+ await this.workspaceScript.lintAll(workspace, { fix, maxDiagnostics });
485
502
  }),
486
503
  syncAll: target({ desc: "Sync dependencies and configuration for all apps and libraries" }).with(Workspace).exec(async function(workspace) {
487
504
  await this.workspaceScript.syncAll(workspace);
@@ -1,60 +0,0 @@
1
- // @bun
2
- import {
3
- ANDROID_MIN_SDK_VERSION,
4
- CapacitorApp,
5
- PLACEHOLDER_APP_IDS,
6
- SWIFTUICORE_MIN_IOS_MAJOR,
7
- assertJsonSerializable,
8
- buildIosNativeRunCommand,
9
- classifyIosRunFailure,
10
- clearRootCapacitorConfigs,
11
- formatAndroidReleaseSigningError,
12
- formatIosRunFailureMessage,
13
- getAdbDeviceStateIssues,
14
- getAndroidLocalServerHost,
15
- getMissingAndroidReleaseSigningKeys,
16
- isPlaceholderAppId,
17
- materializeCapacitorConfig,
18
- parseDevicectlDevices,
19
- parseIosRuntimeMajor,
20
- parseSimctlDevices,
21
- raiseGradleMinSdkVersion,
22
- rootCapacitorConfigFilenames,
23
- rootCapacitorConfigPaths,
24
- sanitizeIosNativeRunEnv,
25
- selectLocalDevHost,
26
- sortIosRunTargets,
27
- writeRootCapacitorConfig
28
- } from "./index-xhgtkekh.js";
29
- import"./index-76rn3g2c.js";
30
- import"./index-vg0sj9nc.js";
31
- import"./index-mxvakhsm.js";
32
- import"./index-67546d0j.js";
33
- import"./index-r24hmh0q.js";
34
- export {
35
- writeRootCapacitorConfig,
36
- sortIosRunTargets,
37
- selectLocalDevHost,
38
- sanitizeIosNativeRunEnv,
39
- rootCapacitorConfigPaths,
40
- rootCapacitorConfigFilenames,
41
- raiseGradleMinSdkVersion,
42
- parseSimctlDevices,
43
- parseIosRuntimeMajor,
44
- parseDevicectlDevices,
45
- materializeCapacitorConfig,
46
- isPlaceholderAppId,
47
- getMissingAndroidReleaseSigningKeys,
48
- getAndroidLocalServerHost,
49
- getAdbDeviceStateIssues,
50
- formatIosRunFailureMessage,
51
- formatAndroidReleaseSigningError,
52
- clearRootCapacitorConfigs,
53
- classifyIosRunFailure,
54
- buildIosNativeRunCommand,
55
- assertJsonSerializable,
56
- SWIFTUICORE_MIN_IOS_MAJOR,
57
- PLACEHOLDER_APP_IDS,
58
- CapacitorApp,
59
- ANDROID_MIN_SDK_VERSION
60
- };
@@ -1,9 +0,0 @@
1
- // @bun
2
- import {
3
- TypeScriptDependencyScanner
4
- } from "./index-46tjzh6s.js";
5
- import"./index-67546d0j.js";
6
- import"./index-r24hmh0q.js";
7
- export {
8
- TypeScriptDependencyScanner
9
- };
package/index-mxvakhsm.js DELETED
@@ -1,66 +0,0 @@
1
- // @bun
2
- // pkgs/@akanjs/devkit/spinner.ts
3
- import ora from "ora";
4
-
5
- class Spinner {
6
- static padding = 12;
7
- static oraOptions = { discardStdin: false };
8
- static canAnimate(stream = process.stderr) {
9
- return !stream.isTTY || stream.columns > 0;
10
- }
11
- spinner;
12
- stopWatch = null;
13
- startAt = new Date;
14
- prefix;
15
- message;
16
- enableSpin;
17
- constructor(message, { prefix = "", indent = 0, enableSpin = true } = {}) {
18
- Spinner.padding = Math.max(Spinner.padding, prefix.length);
19
- this.prefix = prefix;
20
- this.message = message;
21
- this.spinner = ora({ ...Spinner.oraOptions, text: message });
22
- this.spinner.prefixText = prefix.padStart(Spinner.padding, " ");
23
- this.spinner.indent = indent;
24
- this.enableSpin = enableSpin && Spinner.canAnimate();
25
- }
26
- start() {
27
- this.startAt = new Date;
28
- if (this.enableSpin) {
29
- this.spinner.start();
30
- this.stopWatch = setInterval(() => {
31
- this.spinner.prefixText = this.prefix.padStart(Spinner.padding, " ");
32
- this.spinner.text = `${this.message} (${this.#getElapsedTimeStr({ floor: true })})`;
33
- }, 1000);
34
- } else
35
- this.spinner.info();
36
- return this;
37
- }
38
- succeed(message) {
39
- this.spinner.succeed(`${message} (${this.#getElapsedTimeStr()})`);
40
- this.#reset();
41
- }
42
- fail(message) {
43
- this.spinner.fail(`${message} (${this.#getElapsedTimeStr()})`);
44
- this.#reset();
45
- }
46
- isSpinning() {
47
- return this.spinner.isSpinning;
48
- }
49
- #reset() {
50
- if (this.stopWatch)
51
- clearInterval(this.stopWatch);
52
- this.stopWatch = null;
53
- }
54
- #getElapsedTimeStr({ floor = false } = {}) {
55
- const ms = Date.now() - this.startAt.getTime();
56
- if (ms < 1000)
57
- return `${ms}ms`;
58
- const s = Math.floor(ms / 1000);
59
- if (s < 60)
60
- return `${floor ? Math.floor(ms / 1000) : Math.floor(ms / 100) / 10}s`;
61
- const m = Math.floor(s / 60);
62
- return `${m}m ${s % 60}s`;
63
- }
64
- }
65
-
66
- export { Spinner };
package/index-r24hmh0q.js DELETED
@@ -1,4 +0,0 @@
1
- // @bun
2
- var __require = import.meta.require;
3
-
4
- export { __require };
@@ -1,12 +0,0 @@
1
- // @bun
2
- import {
3
- collectRecipeSources,
4
- findInlineRecipeDuplicates,
5
- scanRecipes
6
- } from "./index-xys926f2.js";
7
- import"./index-r24hmh0q.js";
8
- export {
9
- scanRecipes,
10
- findInlineRecipeDuplicates,
11
- collectRecipeSources
12
- };
@@ -1,43 +0,0 @@
1
- ---
2
- description: Akan page routing conventions
3
- globs: apps/**/page/**/*.{ts,tsx,js,jsx}
4
- alwaysApply: false
5
- ---
6
-
7
- # Akan Page Routing
8
-
9
- - `apps/<app>/page` may contain route modules only. Do not add helper logic or component-only files there.
10
- - Route source files under `page/` must use `.tsx`. Do not add `logic.ts`, `.js`, or `.jsx` files under `page/`.
11
- - Route pages use `_index.tsx`; layouts use `_layout.tsx`.
12
- - Reserved `_*.tsx` route filenames are limited to `_index.tsx` and `_layout.tsx`; do not add files like `_Component.tsx` or `_helper.tsx`.
13
- - Page filenames must not start with an uppercase letter. Move helper components like `Component.tsx` to app `ui`, `common`, or `lib` instead.
14
- - Dynamic segments use `[id]`; route groups use directories like `(user)`, `(public)`, `(tab)`, or `(detail)`.
15
- - Page modules should usually export `default`, `pageConfig`, `head`, `generateHead`, or `Loading`.
16
- - Prefer `export default function Page` or `export default async function Page` for page components.
17
- - Before changing route behavior, check nearby routes for the expected pattern.
18
-
19
- ## Page Body Shape
20
-
21
- ```tsx
22
- interface PageProps {
23
- params: { taskId: string };
24
- }
25
-
26
- export default async function Page({ params }: PageProps) {
27
- const { l } = usePage();
28
- getSelf({ unauthorize: "/signin" });
29
- const { taskId } = params;
30
- const [{ task }] = await Promise.all([fetch.viewTask(taskId)]);
31
- return <Task.View.General task={task} />;
32
- }
33
-
34
- export const pageConfig = { transition: "stack" } satisfies PageConfig;
35
- ```
36
-
37
- - There is no `loader=` / `render=` page prop. Pages are `export default async function Page`.
38
- - Declare `interface PageProps { params: {...}; searchParams?: {...} }` immediately above the default export.
39
- - Body order: `usePage()`, auth, destructure params, fetch, return.
40
- - Run independent fetches through `Promise.all`, even when there is only one.
41
- - Gate auth at `_layout.tsx`; repeating `getSelf({ unauthorize: "/signin" })` in the page is fine and common.
42
- - Keep `async` even when nothing is awaited — it marks a real server page.
43
- - No `useState`, no `useEffect`, and no comments in page files.
@@ -1,34 +0,0 @@
1
- ---
2
- description: sync-enforced Akan app/lib layout and generated index conventions
3
- globs: apps/**/*,libs/**/*
4
- alwaysApply: false
5
- ---
6
-
7
- # Akan Sync Conventions
8
-
9
- - `apps/<appName>` root may only contain these files: `AGENTS.md`, `CLAUDE.md`, `akan.app.json`, `akan.config.ts`, `capacitor.config.ts`, `client.ts`, `main.ts`, `package.json`, `server.ts`, `tsconfig.json`.
10
- - `apps/<appName>` root may only contain these folders: `.akan`, `android`, `common`, `env`, `ios`, `lib`, `mobile`, `page`, `plugin`, `private`, `public`, `script`, `secrets`, `srvkit`, `ui`, `webkit`.
11
- - `akan sync` maintains a scoped agent guide per app/lib (`apps/<app>/AGENTS.md` / `libs/<lib>/AGENTS.md`); the `akan:agent` block in it is generated, content outside the markers is hand-editable, and `akan lint` fails when the block is stale.
12
- - Do not add `apps/*/base`; place shared app utilities under `apps/*/common`.
13
- - `apps/*/lib` and `libs/*/lib` root files are limited to generated/support files: `cnst.ts`, `db.ts`, `dict.ts`, `option.ts`, `sig.ts`, `srv.ts`, `st.ts`, `useClient.ts`, `useServer.ts`.
14
- - Domain module folders are `lib/<model>` for database modules, `lib/_<service>` for service modules, and `lib/__scalar/<scalar>` for scalar modules.
15
- - Database module UI files are limited to `<Model>.Template.tsx`, `<Model>.Unit.tsx`, `<Model>.Util.tsx`, `<Model>.View.tsx`, and `<Model>.Zone.tsx`.
16
- - Service module UI files are limited to `<Service>.Util.tsx` and `<Service>.Zone.tsx`.
17
- - Scalar module UI files are limited to `<Scalar>.Template.tsx` and `<Scalar>.Unit.tsx`.
18
- - Module `*.test.ts`, `*.test.tsx`, `*.spec.ts`, and `*.spec.tsx` files are allowed.
19
- - `ui/index.ts`, `webkit/index.ts`, `srvkit/index.ts`, `common/index.ts`, and module `lib/**/index.ts` files are generated by `akan sync`; do not hand-edit or track them.
20
- - Generated facet indexes export only 1-depth files/folders with `export * from "./name";`.
21
-
22
- ## Layer Placement
23
-
24
- | Folder | Admission test | Naming |
25
- |---|---|---|
26
- | `common/` | pure, isomorphic, zero-dependency; may import only sibling `common/*` and `akanjs/base`. Cannot import `Err`, so keep throwing code out of it. | camelCase file, filename equals the single export |
27
- | `webkit/` | touches `window` / `navigator` / Capacitor, or is a React hook | `use<Thing>.tsx` — `.tsx` even with no JSX |
28
- | `srvkit/` | touches `node:*`, `Bun`, `process.env`, a secret, or a server SDK | camelCase file, PascalCase class |
29
- | `ui/` | renders JSX and is not bound to one model | PascalCase component, camelCase sidecar (`swipeCard.util.ts`) |
30
-
31
- - Hooks return a named object of async closures, never a tuple.
32
- - Only layer-root `index.ts` barrels are generated. A `ui/<Folder>/index.tsx` that builds a namespace is hand-written source; the distinguishing test is that a generated barrel contains nothing but `export * from "./X";` lines.
33
- - `ui/<Folder>/index_.tsx` (trailing underscore) is the `"use client"` + `lazy()` boundary, with a server-safe `index.tsx` beside it. Collapsing the pair into one file breaks RSC.
34
- - Never add a sibling helper file inside `lib/<model>/`; helpers belong in one of the folders above.
@@ -1,16 +0,0 @@
1
- ---
2
- description: Application test commands after source changes
3
- alwaysApply: true
4
- ---
5
-
6
- # Application Test Commands
7
-
8
- - After changing application source code, test the app with `bun run akan start <appName>`.
9
- - Test production build generation with `bun run akan build <appName>`.
10
- - To test a built artifact locally, run it from the generated app directory with the required Akan runtime environment variables.
11
-
12
- ```bash
13
- cd dist/apps/<appName> && USE_AKANJS_PKGS=true AKAN_PUBLIC_REPO_NAME=akansoft AKAN_PUBLIC_SERVE_DOMAIN="akanjs.com" AKAN_PUBLIC_APP_NAME=seon AKAN_PUBLIC_ENV=local AKAN_PUBLIC_OPERATION_MODE=local SERVER_MODE=federation AKAN_PUBLIC_BASE_PATHS=operator,office,homepage bun main.js
14
- ```
15
-
16
- - Adjust `<appName>`, `AKAN_PUBLIC_APP_NAME`, and `AKAN_PUBLIC_BASE_PATHS` to match the app being tested.
@@ -1,12 +0,0 @@
1
- ---
2
- description: Keep edits scoped and avoid unrelated churn
3
- alwaysApply: true
4
- ---
5
-
6
- # Change Scope
7
-
8
- - Keep edits scoped to the requested task and the directly related files.
9
- - Do not reformat unrelated files or rewrite nearby code just for style.
10
- - Do not revert or overwrite unrelated user changes in a dirty working tree.
11
- - Prefer established nearby patterns over introducing a new abstraction.
12
- - Add new abstractions only when they remove real duplication or match an existing project pattern.
@@ -1,18 +0,0 @@
1
- ---
2
- description: Client/server boundary conventions for Akan apps
3
- globs: apps/**/*.{ts,tsx},libs/**/*.{ts,tsx},pkgs/akanjs/**/*.{ts,tsx}
4
- alwaysApply: false
5
- ---
6
-
7
- # Client Server Boundaries
8
-
9
- - Use `"use client";` at the top of client component files.
10
- - Be careful when importing client-only code from page or layout modules.
11
- - Keep page props serializable unless the existing route pattern clearly allows otherwise.
12
- - Let server page/layout files own route-level concerns: `usePage`, headers, static layout, and `akanjs/ui` `Tab` composition.
13
- - Keep interactive loading, submit/import actions, local form inputs, and `router.push` inside client `Util`, `Template`, or `Zone` components.
14
- - Prefer server-rendered `Tab` shells for static mode selection; put one client component inside each `Tab.Panel` instead of managing the selected mode with extra `useState`.
15
- - In domain UI the boundary is mechanical, not a judgment call: `Template`, `Zone`, and `Util` are always client components with `"use client"` on line 1; `Unit` and `View` are always server components and never carry the directive. `usePage()` is still legal in server files.
16
- - Preserve established domain file roles such as `.document.ts`, `.service.ts`, `.store.ts`, `.constant.ts`, and `.client.ts`.
17
- - When unsure, inspect nearby files in the same app or package before introducing a new boundary pattern.
18
- - The boundary is only half the rule: how *little* ends up on the client is the other half. See `ssr-first.mdc`.
@@ -1,25 +0,0 @@
1
- ---
2
- description: Do not narrate code; document only what the code cannot say
3
- alwaysApply: true
4
- ---
5
-
6
- # Comments
7
-
8
- Do not narrate code. Do document the thing the code cannot say. Both halves are the rule.
9
-
10
- - Never add a comment that restates the identifier, the signature, or the control flow.
11
- - Prefer clear names and structure so ordinary logic needs no explanation.
12
- - Do not add JSDoc, section banners, or "why/how" comments for ordinary logic.
13
- - Comment density tracks the layer, not the author: pages carry none, product `lib/` and `ui/` code stays under 1 %, and `srvkit/` adapters and `guards.ts` carry as much as the external constraints require.
14
- - A comment is warranted for: a vendor spec or protocol quirk; an infrastructure constraint; a third-party library gotcha; security reasoning; why a rule that looks arbitrary is correct; a math derivation; a domain field's business meaning; a state transition above a document chain method; why an obvious alternative was rejected.
15
- - In-code markers:
16
- 1. `TODO` — unfinished work that must be tracked in-code
17
- 2. `FIXME` — known broken or incorrect behavior that must be fixed
18
- 3. `XXX` — dangerous / surprising hazard that a reader must not miss
19
- 4. `//!` — disabled or must-fix code
20
- 5. `//?` — an explanatory aside
21
- 6. `//*` — a design note
22
- 7. Deletion caution — warn why removing a line or block would break something non-obvious
23
- - Keep allowed comments one short line when possible.
24
- - Every suppression carries a reason: `// biome-ignore lint/<rule>: <why>`. Never a bare disable block.
25
- - Match nearby file style: if the surrounding code has few comments, keep it that way.