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

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 (74) hide show
  1. package/.build-stamp +1 -1
  2. package/{agent.command-pggr92jj.js → agent.command-f0gqkfgz.js} +7 -6
  3. package/{application.command-692yap1d.js → application.command-x903m2qq.js} +5 -4
  4. package/buildBatch.proc.js +2 -1
  5. package/{capacitorApp-p0z5yab2.js → capacitorApp-9xswcgx7.js} +3 -2
  6. package/{cloud.command-wqfsyzv2.js → cloud.command-zs6kyf83.js} +8 -7
  7. package/{context.command-9bxtdn0w.js → context.command-fmepgjzg.js} +14 -13
  8. package/getDirname-m9s0cmhq.js +8 -0
  9. package/{guideline.command-nfqahxex.js → guideline.command-n6sw0a0c.js} +5 -4
  10. package/guidelines/conventions/conventions.generate.json +25 -0
  11. package/guidelines/conventions/conventions.instruction.md +668 -0
  12. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
  13. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +972 -0
  14. package/incrementalBuilder.proc.js +2 -1
  15. package/index-1577bej2.js +7 -0
  16. package/{index-bz2sfzzt.js → index-3vta1tqa.js} +4 -4
  17. package/{index-p3f4q532.js → index-4m0bphac.js} +3 -3
  18. package/{index-w6wbb612.js → index-5sn5w2mt.js} +13 -13
  19. package/{index-5dw57f0d.js → index-62955kn5.js} +6 -6
  20. package/{index-mssqn2sq.js → index-774gcx29.js} +43 -4
  21. package/{index-xhgtkekh.js → index-779ske1y.js} +1 -1
  22. package/{index-js368gk9.js → index-82jrh4hj.js} +5 -5
  23. package/{index-a1e0j63x.js → index-d43t8af2.js} +2 -2
  24. package/{index-gex7c8kd.js → index-eyyf2149.js} +34 -6
  25. package/{index-azv0xjb5.js → index-gcv8ncfh.js} +2 -2
  26. package/{index-7myvn0f0.js → index-j37qq1f2.js} +1 -1
  27. package/{index-ztpw544k.js → index-jf2ya7r2.js} +3 -3
  28. package/{index-vtj3zps1.js → index-jhpa13zj.js} +7 -7
  29. package/{index-6rhabeev.js → index-kdh76j26.js} +4 -2
  30. package/{index-5pmx7bkg.js → index-qzdjd4ct.js} +3 -3
  31. package/{index-2c3e2xh8.js → index-rxkpk7n4.js} +1 -1
  32. package/{index-4hek879p.js → index-xmmzf150.js} +1 -1
  33. package/{index-gmy45vz2.js → index-y4vkyhvv.js} +3 -3
  34. package/{index-vg0sj9nc.js → index-z8ptfkzv.js} +56 -18
  35. package/index.js +19 -18
  36. package/{library.command-md9715jz.js → library.command-cv9gdbmg.js} +4 -3
  37. package/{localRegistry.command-exkbamyj.js → localRegistry.command-d8fg36zc.js} +7 -6
  38. package/{module.command-w5aaddxk.js → module.command-qyr1s9cn.js} +7 -6
  39. package/{package.command-yfkrcy0z.js → package.command-wsjx0k47.js} +4 -3
  40. package/package.json +2 -2
  41. package/{page.command-echbavp4.js → page.command-rdzg65rm.js} +4 -3
  42. package/{primitive.command-9fbhspw2.js → primitive.command-89g38b53.js} +8 -7
  43. package/{quality.command-3pnt9yep.js → quality.command-0cs2z92d.js} +3 -2
  44. package/{repair.command-carj4vax.js → repair.command-6fphxfwj.js} +6 -5
  45. package/{scalar.command-51ryzypc.js → scalar.command-xfer69s6.js} +6 -5
  46. package/templates/crudPages/[__model__Id]/edit/page.tsx +1 -1
  47. package/templates/crudPages/new/page.tsx +1 -1
  48. package/templates/crudSinglePage/page.tsx +1 -1
  49. package/templates/module/__Model__.Util.tsx +1 -1
  50. package/templates/module/__Model__.Zone.tsx +3 -5
  51. package/templates/workspaceRoot/AGENTS.md.template +0 -972
  52. package/templates/workspaceRoot/biome.json.template +3 -244
  53. package/{workflow.command-91wmvm8k.js → workflow.command-2ygfqt4f.js} +13 -12
  54. package/{workspace.command-wa10mfd9.js → workspace.command-88m0zs64.js} +35 -33
  55. package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
  56. package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -34
  57. package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
  58. package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
  59. package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -18
  60. package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
  61. package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
  62. package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
  63. package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
  64. package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -19
  65. package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -62
  66. package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
  67. package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
  68. package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
  69. package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -99
  70. package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
  71. package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
  72. package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
  73. package/templates/workspaceRoot/.cursor/rules/ssr-first.mdc.template +0 -59
  74. package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
@@ -1,49 +1,12 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.5.2/schema.json",
3
- "vcs": {
4
- "enabled": true,
5
- "clientKind": "git",
6
- "useIgnoreFile": false
7
- },
2
+ "$schema": "https://biomejs.dev/schemas/2.4.4/schema.json",
3
+ "extends": ["@akanjs/devkit/biome.base.json"],
8
4
  "files": {
9
5
  "includes": [
10
6
  "**/*.ts",
11
7
  "**/*.tsx",
12
8
  "**/*.json",
13
9
  "**/*.jsonc",
14
- "!**/env.client.local.ts",
15
- "!**/env.client.debug.ts",
16
- "!**/env.client.develop.ts",
17
- "!**/env.client.main.ts",
18
- "!**/env.client.testing.ts",
19
- "!**/env.server.local.ts",
20
- "!**/env.server.develop.ts",
21
- "!**/env.server.main.ts",
22
- "!**/env.server.testing.ts",
23
- "!**/env.server.type.ts",
24
- "!apps/*/lib/cnst.ts",
25
- "!apps/*/lib/dict.ts",
26
- "!apps/*/lib/db.ts",
27
- "!apps/*/lib/srv.ts",
28
- "!apps/*/lib/st.ts",
29
- "!apps/*/lib/sig.ts",
30
- "!apps/*/lib/useClient.ts",
31
- "!apps/*/lib/useServer.ts",
32
- "!apps/*/client.ts",
33
- "!apps/*/server.ts",
34
- "!apps/*/lib/*/index.tsx",
35
- "!libs/*/lib/cnst.ts",
36
- "!libs/*/lib/dict.ts",
37
- "!libs/*/lib/db.ts",
38
- "!libs/*/lib/srv.ts",
39
- "!libs/*/lib/st.ts",
40
- "!libs/*/lib/sig.ts",
41
- "!libs/*/lib/useClient.ts",
42
- "!libs/*/lib/useServer.ts",
43
- "!libs/*/client.ts",
44
- "!libs/*/server.ts",
45
- "!libs/*/index.ts",
46
- "!libs/*/lib/*/index.tsx",
47
10
  "!infra/master/createRecords.ts",
48
11
  "!pkgs/contract/env.ts",
49
12
  "!!**/node_modules",
@@ -53,209 +16,5 @@
53
16
  "!!**/local",
54
17
  "!!**/ios/DerivedData"
55
18
  ]
56
- },
57
- "formatter": {
58
- "enabled": true,
59
- "indentStyle": "space",
60
- "indentWidth": 2,
61
- "lineWidth": 120
62
- },
63
- "linter": {
64
- "enabled": true,
65
- "rules": {
66
- "preset": "recommended",
67
- "suspicious": {
68
- "noConsole": {
69
- "level": "error",
70
- "options": {
71
- "allow": ["assert", "error", "info", "warn"]
72
- }
73
- },
74
- "noArrayIndexKey": "off",
75
- "noShadowRestrictedNames": "off",
76
- "noUnnecessaryConditions": {
77
- "level": "error"
78
- }
79
- },
80
- "correctness": {
81
- "noUnusedFunctionParameters": "off",
82
- "noUnusedImports": {
83
- "level": "error",
84
- "fix": "safe"
85
- },
86
- "useParseIntRadix": "off",
87
- "useExhaustiveDependencies": "off",
88
- "useHookAtTopLevel": "off"
89
- },
90
- "nursery": {
91
- "useSortedClasses": {
92
- "level": "error",
93
- "fix": "safe",
94
- "options": {
95
- "attributes": ["classList"],
96
- "functions": ["clsx", "cn"]
97
- }
98
- }
99
- },
100
- "a11y": "off",
101
- "complexity": {
102
- "noStaticOnlyClass": "off"
103
- },
104
- "style": {
105
- "useTemplate": {
106
- "level": "warn",
107
- "fix": "safe"
108
- }
109
- }
110
- },
111
- "domains": {
112
- "project": "recommended",
113
- "react": "recommended",
114
- "test": "recommended",
115
- "types": "all"
116
- }
117
- },
118
- "javascript": {
119
- "parser": {
120
- "unsafeParameterDecoratorsEnabled": true
121
- },
122
- "formatter": {
123
- "quoteStyle": "double"
124
- }
125
- },
126
- "assist": {
127
- "enabled": true,
128
- "actions": {
129
- "source": {
130
- "organizeImports": "on"
131
- }
132
- }
133
- },
134
- "overrides": [
135
- {
136
- "includes": [
137
- "apps/**/*.ts",
138
- "apps/**/*.tsx",
139
- "libs/**/*.ts",
140
- "libs/**/*.tsx",
141
- "!**/*.test.ts",
142
- "!**/*.test.tsx",
143
- "!**/*.spec.ts",
144
- "!**/*.spec.tsx",
145
- "!**/*.constant.ts",
146
- "!**/common/**",
147
- "!apps/akan/env/**"
148
- ],
149
- "plugins": ["./node_modules/@akanjs/devkit/lint/no-throw-raw-error.grit"]
150
- },
151
- {
152
- "includes": ["**/page/**/*.ts", "**/page/**/*.tsx", "**/*.Unit.tsx", "**/*.View.tsx"],
153
- "plugins": [
154
- "./node_modules/@akanjs/devkit/lint/no-import-client-functions.grit",
155
- "./node_modules/@akanjs/devkit/lint/no-use-client-in-server.grit"
156
- ]
157
- },
158
- {
159
- "includes": ["**/page/**/*.ts", "**/page/**/*.tsx"],
160
- "plugins": ["./node_modules/@akanjs/devkit/lint/non-scalar-props-restricted.grit"]
161
- },
162
- {
163
- "includes": ["**/*.constant.ts", "**/*.document.ts", "**/*.service.ts", "**/*.store.ts"],
164
- "plugins": ["./node_modules/@akanjs/devkit/lint/no-js-private-class-method.grit"]
165
- },
166
- {
167
- "includes": ["**/*.store.ts"],
168
- "plugins": ["./node_modules/@akanjs/devkit/lint/no-return-in-store-action.grit"]
169
- },
170
- {
171
- "includes": ["**/*.signal.ts"],
172
- "plugins": ["./node_modules/@akanjs/devkit/lint/no-redeclare-predefined-endpoint.grit"]
173
- },
174
- {
175
- "includes": [
176
- "**/ui/**/*.ts",
177
- "**/ui/**/*.tsx",
178
- "**/webkit/**/*.ts",
179
- "**/webkit/**/*.tsx",
180
- "**/common/**/*.ts",
181
- "**/page/**/*.tsx",
182
- "**/*.constant.ts",
183
- "**/*.store.ts",
184
- "**/*.Template.tsx",
185
- "**/*.Unit.tsx",
186
- "**/*.Util.tsx",
187
- "**/*.View.tsx",
188
- "**/*.Zone.tsx",
189
- "!**/*.test.ts",
190
- "!**/*.test.tsx",
191
- "!**/*.spec.ts",
192
- "!**/*.spec.tsx"
193
- ],
194
- "plugins": ["./node_modules/@akanjs/devkit/lint/no-bang-comment-in-client.grit"]
195
- },
196
- {
197
- "includes": [
198
- "**/*.constant.ts",
199
- "**/*.dictionary.ts",
200
- "**/*.document.ts",
201
- "**/*.service.ts",
202
- "**/*.signal.ts",
203
- "**/*.store.ts",
204
- "**/*.Template.tsx",
205
- "**/*.Unit.tsx",
206
- "**/*.Util.tsx",
207
- "**/*.View.tsx",
208
- "**/*.Zone.tsx"
209
- ],
210
- "plugins": ["./node_modules/@akanjs/devkit/lint/no-deep-internal-import.grit"]
211
- },
212
- {
213
- "includes": [
214
- "**/page/**/*.ts",
215
- "**/page/**/*.tsx",
216
- "**/index.ts",
217
- "**/index.tsx",
218
- "**/cnst.ts",
219
- "**/db.ts",
220
- "**/dict.ts",
221
- "**/option.ts",
222
- "**/sig.ts",
223
- "**/srv.ts",
224
- "**/st.ts",
225
- "**/*.constant.ts",
226
- "**/*.dictionary.ts",
227
- "**/*.document.ts",
228
- "**/*.service.ts",
229
- "**/*.signal.ts",
230
- "**/*.signal.test.ts",
231
- "**/*.service.test.ts",
232
- "**/*.store.ts",
233
- "**/*.Template.tsx",
234
- "**/*.Unit.tsx",
235
- "**/*.Util.tsx",
236
- "**/*.View.tsx",
237
- "**/*.Zone.tsx"
238
- ],
239
- "plugins": ["./node_modules/@akanjs/devkit/lint/no-import-external-library.grit"]
240
- },
241
- {
242
- "includes": [
243
- "apps/**/*.ts",
244
- "apps/**/*.tsx",
245
- "libs/**/*.ts",
246
- "libs/**/*.tsx",
247
- "!**/*.test.ts",
248
- "!**/*.test.tsx",
249
- "!**/*.spec.ts",
250
- "!**/*.spec.tsx"
251
- ],
252
- "plugins": [
253
- "./node_modules/@akanjs/devkit/lint/no-raw-palette-class.grit",
254
- "./node_modules/@akanjs/devkit/lint/no-arbitrary-color.grit",
255
- "./node_modules/@akanjs/devkit/lint/no-daisyui-legacy-class.grit",
256
- "./node_modules/@akanjs/devkit/lint/no-inline-color.grit",
257
- "./node_modules/@akanjs/devkit/lint/no-interpolated-arbitrary-class.grit"
258
- ]
259
- }
260
- ]
19
+ }
261
20
  }
@@ -1,32 +1,33 @@
1
1
  // @bun
2
2
  import {
3
3
  WorkflowRunner
4
- } from "./index-5pmx7bkg.js";
4
+ } from "./index-qzdjd4ct.js";
5
+ import {
6
+ ScalarScript
7
+ } from "./index-y4vkyhvv.js";
5
8
  import {
6
9
  PrimitiveScript
7
- } from "./index-bz2sfzzt.js";
10
+ } from "./index-3vta1tqa.js";
8
11
  import {
9
12
  ModuleScript
10
- } from "./index-vtj3zps1.js";
11
- import"./index-4hek879p.js";
12
- import {
13
- ScalarScript
14
- } from "./index-gmy45vz2.js";
13
+ } from "./index-jhpa13zj.js";
15
14
  import"./index-ss469dec.js";
15
+ import"./index-xmmzf150.js";
16
16
  import"./index-0cj2zxbm.js";
17
- import"./index-mssqn2sq.js";
17
+ import"./index-774gcx29.js";
18
18
  import {
19
19
  createWorkflowStepRegistry
20
- } from "./index-2c3e2xh8.js";
21
- import"./index-7myvn0f0.js";
20
+ } from "./index-rxkpk7n4.js";
21
+ import"./index-j37qq1f2.js";
22
22
  import {
23
23
  Workspace,
24
24
  command,
25
25
  script
26
- } from "./index-6rhabeev.js";
27
- import"./index-vg0sj9nc.js";
26
+ } from "./index-kdh76j26.js";
27
+ import"./index-z8ptfkzv.js";
28
28
  import"./index-mxvakhsm.js";
29
29
  import"./index-xys926f2.js";
30
+ import"./index-1577bej2.js";
30
31
  import"./index-67546d0j.js";
31
32
  import"./index-r24hmh0q.js";
32
33
 
@@ -1,48 +1,48 @@
1
1
  // @bun
2
2
  import {
3
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";
4
+ } from "./index-5sn5w2mt.js";
5
+ import"./index-jf2ya7r2.js";
6
+ import"./index-qzdjd4ct.js";
7
+ import"./index-y4vkyhvv.js";
8
+ import"./index-3vta1tqa.js";
9
+ import"./index-jhpa13zj.js";
10
+ import"./index-ss469dec.js";
11
+ import"./index-xmmzf150.js";
10
12
  import {
11
13
  CloudScript
12
- } from "./index-js368gk9.js";
14
+ } from "./index-82jrh4hj.js";
13
15
  import {
14
16
  getLatestPackageVersion,
15
17
  getNpmRegistryUrl
16
- } from "./index-p3f4q532.js";
18
+ } from "./index-4m0bphac.js";
17
19
  import {
18
20
  PackageScript
19
- } from "./index-azv0xjb5.js";
20
- import"./index-gmy45vz2.js";
21
- import"./index-ss469dec.js";
22
- import"./index-xhgtkekh.js";
21
+ } from "./index-gcv8ncfh.js";
22
+ import"./index-779ske1y.js";
23
23
  import {
24
24
  GlobalConfig
25
25
  } from "./index-0cj2zxbm.js";
26
26
  import {
27
27
  AgentScript
28
- } from "./index-gex7c8kd.js";
29
- import"./index-mssqn2sq.js";
30
- import"./index-2c3e2xh8.js";
31
- import"./index-7myvn0f0.js";
28
+ } from "./index-eyyf2149.js";
29
+ import"./index-774gcx29.js";
30
+ import"./index-rxkpk7n4.js";
31
+ import"./index-j37qq1f2.js";
32
32
  import {
33
33
  ApplicationScript
34
- } from "./index-5dw57f0d.js";
35
- import"./index-76rn3g2c.js";
34
+ } from "./index-62955kn5.js";
36
35
  import {
37
36
  LibraryScript
38
- } from "./index-a1e0j63x.js";
37
+ } from "./index-d43t8af2.js";
38
+ import"./index-76rn3g2c.js";
39
39
  import {
40
40
  Exec,
41
41
  Workspace,
42
42
  command,
43
43
  runner,
44
44
  script
45
- } from "./index-6rhabeev.js";
45
+ } from "./index-kdh76j26.js";
46
46
  import"./index-fgc8r6dj.js";
47
47
  import {
48
48
  ThemeValidator,
@@ -59,12 +59,13 @@ import {
59
59
  collectScopeRecipeSources,
60
60
  extractAgentBlock,
61
61
  renderScopeAgentBlock
62
- } from "./index-vg0sj9nc.js";
62
+ } from "./index-z8ptfkzv.js";
63
63
  import"./index-mxvakhsm.js";
64
64
  import {
65
65
  collectRecipeSources,
66
66
  scanRecipes
67
67
  } from "./index-xys926f2.js";
68
+ import"./index-1577bej2.js";
68
69
  import"./index-46tjzh6s.js";
69
70
  import {
70
71
  FileSys
@@ -77,6 +78,11 @@ import { Logger } from "akanjs/common";
77
78
 
78
79
  // pkgs/@akanjs/cli/workspace/workspace.runner.ts
79
80
  import path from "path";
81
+
82
+ // pkgs/@akanjs/devkit/biomeBase.ts
83
+ var biomeVersion = "2.4.4";
84
+
85
+ // pkgs/@akanjs/cli/workspace/workspace.runner.ts
80
86
  var defaultWorkspacePeerDependencies = new Set([
81
87
  "@react-spring/web",
82
88
  "@use-gesture/react",
@@ -113,17 +119,14 @@ class WorkspaceRunner extends runner("workspace") {
113
119
  dict,
114
120
  overwrite
115
121
  }));
116
- if (!cursorRules)
117
- return created;
118
- return [
119
- ...created,
120
- ...await workspace.applyTemplate({
122
+ if (cursorRules)
123
+ created.push(...await workspace.applyTemplate({
121
124
  basePath: ".cursor/rules",
122
125
  template: "workspaceRoot/.cursor/rules/akan.mdc.template",
123
126
  dict,
124
127
  overwrite
125
- })
126
- ];
128
+ }));
129
+ return created;
127
130
  }
128
131
  async createWorkspace(repoName, appName, {
129
132
  dirname = ".",
@@ -137,10 +140,7 @@ class WorkspaceRunner extends runner("workspace") {
137
140
  const normalizedRegistryUrl = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
138
141
  const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
139
142
  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
- ]);
143
+ const latestTypesBunVersion = await getLatestPackageVersion("@types/bun", "latest", normalizedRegistryUrl);
144
144
  await workspace.applyTemplate({
145
145
  basePath: ".",
146
146
  template: "workspaceRoot",
@@ -164,7 +164,7 @@ class WorkspaceRunner extends runner("workspace") {
164
164
  },
165
165
  devDependencies: {
166
166
  ...rootPackageJson.devDependencies,
167
- "@biomejs/biome": latestBiomeVersion,
167
+ "@biomejs/biome": biomeVersion,
168
168
  "@types/bun": latestTypesBunVersion,
169
169
  "@akanjs/devkit": akanVersion,
170
170
  ...typescript ? { typescript } : {}
@@ -372,6 +372,8 @@ class WorkspaceScript extends script("workspace", [
372
372
  async generateAgentRules(workspace, { overwrite = false, cursorRules = true } = {}) {
373
373
  const spinner = workspace.spinning("Generating agent rules...");
374
374
  const files = await this.workspaceRunner.generateAgentRules(workspace, { overwrite, cursorRules });
375
+ if (files.some((file) => file.filePath.endsWith("AGENTS.md")))
376
+ await this.agentScript.agent(workspace, "install", "agents-md", { force: overwrite });
375
377
  spinner.succeed(`Agent rules ready (${files.length} file${files.length === 1 ? "" : "s"})`);
376
378
  }
377
379
  async lint(exec, workspace, { fix = true } = {}) {
@@ -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.
@@ -1,44 +0,0 @@
1
- ---
2
- description: Coding style conventions for classes, functions, files, and types
3
- globs: **/*.{ts,tsx}
4
- alwaysApply: false
5
- ---
6
-
7
- # Coding Style
8
-
9
- - For large units of work, prefer declaring a class and running the flow through an instance instead of scattering many standalone functions.
10
- - Prefer class methods or `static` methods over unrelated top-level helper functions when the logic belongs to a class-level workflow.
11
- - Prefer ECMAScript `#private` fields and methods over TypeScript `private`, except in the four suffixes where `#private` is lint-banned (`*.constant.ts`, `*.document.ts`, `*.service.ts`, `*.store.ts`) — those use TypeScript `private`. `#private` is the house style under `srvkit/`, including `adapt()` classes.
12
- - In files that declare a class, avoid top-level functions or variables when they can reasonably live inside the class.
13
- - Prefer `const` function expressions over `function` declarations unless hoisting, overloads, generators, or framework conventions make `function` the better fit.
14
- - Prefer declaring only one class per file; split the file when two or more class declarations are needed.
15
- - For class-centered modules, prefer noun-style filenames that match the primary class name, such as `RouteClientBuilder.ts`, instead of verb-style wrapper filenames like `buildRouteClient.ts`.
16
- - Avoid keeping exported functions that only instantiate a class and immediately call one method. Prefer migrating callers to instantiate the class directly.
17
- - Except for React component files or convention files, TypeScript filenames should use camelCase.
18
- - In React components, keep one-off `className` strings inline. Only extract class name constants when the class is reused, conditionally composed, or too large to read comfortably in JSX.
19
-
20
- # File Size And Duplication
21
-
22
- - Keep files small. The house median is well under 50 lines; split a component before it reaches ~150 lines rather than adding section comments.
23
- - Ship every scaffold file even when it is empty — `export class XInternal extends internal(srv.x, () => ({})) {}`, empty dictionary stages, the `// state` / `// action` markers in an empty store. They mark where things go.
24
- - Never add a sibling helper file inside `lib/<model>/`. Helpers go to `common/`, `webkit/`, `srvkit/`, or `ui/`.
25
- - Prefer duplication to premature abstraction at the leaf. Near-identical sibling modules and per-vendor pages are deliberately copied, not parameterised. Copy the file and change the literals; share enums by import only.
26
-
27
- # TypeScript Shape
28
-
29
- - Use `interface` for object shapes and `type` only for unions and aliases.
30
- - Declare `interface <ComponentName>Props` immediately above the component with no blank line between, and put `className?: string` first. Name it for the component (`CardProps`, `WorldProps`), never for the model. Do not export it unless a sibling imports it.
31
- - Never use a non-null assertion. Narrow with `?.`, an early return, or a type predicate such as `.filter((id): id is string => !!id)`.
32
- - Escape with `as unknown as T`. Never `as any`.
33
- - Never annotate a component's return type. Annotate a helper only when the return is a union, a tuple, or a type predicate.
34
- - Use `as const` on every `enumOf(...)` array, every `via(Model, [...] as const, …)` Light tuple, and every module-scope lookup map. Never use the TypeScript `enum` keyword.
35
- - Async functions carry no `Async` suffix.
36
-
37
- # Test Code
38
-
39
- - Write TypeScript tests with Bun's test runner and import `describe`, `expect`, and `test` from `bun:test`.
40
- - Keep tests colocated with the source they cover using `*.test.ts` or `*.spec.ts`, following the existing nearby pattern.
41
- - Prefer focused behavior tests for public contracts and edge cases over implementation-detail assertions.
42
- - Split signal tests in two. `<model>.signal.spec.ts` holds reusable fixtures built on `sampleOf(cnst.XInput)` with explicit `Promise<cnst.X>` return types and **no assertions**. `<model>.signal.test.ts` holds the assertions: `describe("<Model> Signal")`, `let` fixtures at describe scope, one `beforeAll`, story-ordered `it`s, and negatives via `await expect(p).rejects.toThrow()`.
43
- - `lib/user/user.signal.spec.ts` is the one place agent types are re-exported and re-typed; import `UserAgent` / `AdminAgent` from there rather than from the shared lib directly.
44
- - A placeholder `it` with a descriptive title is an acceptable floor. Write a real suite when the behaviour is security-relevant.