@akanjs/cli 2.4.2-rc.3 → 3.0.0-alpha.0
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.
- package/.build-stamp +1 -1
- package/{abstractCompactor-ghh1q9an.js → abstractCompactor-rk6twzvj.js} +4 -4
- package/{agent.command-de4r6vk8.js → agent.command-jfz8yfwy.js} +8 -7
- package/{application.command-nfsfm96y.js → application.command-3smsv7mq.js} +5 -5
- package/{applicationBuildRunner-554a2vnk.js → applicationBuildRunner-aq7mb3z6.js} +2 -1
- package/buildBatch.proc.js +7 -6
- package/{capacitorApp-yg9b4ajz.js → capacitorApp-q3mpmkkz.js} +3 -3
- package/{cloud.command-1qf95x67.js → cloud.command-rk4e9vrt.js} +10 -10
- package/{context.command-hhjyjtp7.js → context.command-ygzyb0xb.js} +16 -15
- package/{guideline.command-vj956kfr.js → guideline.command-1m1ctar3.js} +10 -10
- package/guidelines/componentRule/componentRule.instruction.md +2 -2
- package/guidelines/cssRule/cssRule.generate.json +1 -1
- package/guidelines/cssRule/cssRule.instruction.md +57 -34
- package/guidelines/framework/framework.instruction.md +1 -1
- package/guidelines/recipeRule/recipeRule.generate.json +31 -0
- package/guidelines/recipeRule/recipeRule.instruction.md +72 -0
- package/incrementalBuilder.proc.js +5 -5
- package/{index-v9jqrdd1.js → index-4yp06pn1.js} +100 -2
- package/{index-pfnh87f9.js → index-4zgs8g1w.js} +1 -1
- package/{index-7ppn9v4n.js → index-b978vs2e.js} +3 -3
- package/{index-s9s0n5fz.js → index-cn24dcqn.js} +2 -2
- package/{index-h971erkm.js → index-csqk9z5j.js} +3 -3
- package/{index-z36qzgzp.js → index-e3qskyt2.js} +3 -4
- package/{index-fbv96xaw.js → index-ev6rjw9n.js} +11 -11
- package/{index-h6eav7zx.js → index-f4gqk0dd.js} +6 -6
- package/{index-z5v766nx.js → index-fmgbwsr5.js} +6 -6
- package/{index-y1e79mz3.js → index-h0bngh79.js} +13 -13
- package/{index-dgeaqwmw.js → index-hjzr8ja1.js} +1 -1
- package/{index-d0h48d2f.js → index-jk9q6pse.js} +1 -1
- package/{index-xwfg9bam.js → index-jtm86byd.js} +120 -4
- package/{index-h5cvg9z9.js → index-ktprgc5g.js} +4 -4
- package/{index-zn9rh7sh.js → index-n0z3f2xg.js} +73 -24
- package/{index-7k9sj7j5.js → index-pyt2b4nw.js} +212 -0
- package/{index-acwxfncv.js → index-r4w8cry5.js} +4 -4
- package/{index-zfp1gz9f.js → index-sggm9qkv.js} +1 -1
- package/{index-04as43rp.js → index-vhv3xnjz.js} +16 -15
- package/index-xjd3rqzj.js +129 -0
- package/{index-xftstr5s.js → index-xwgm94zr.js} +1 -1
- package/index-xys926f2.js +136 -0
- package/index.js +19 -19
- package/{library.command-68ah07a3.js → library.command-pwfx8dx2.js} +4 -4
- package/{localRegistry.command-84dz000g.js → localRegistry.command-bxhqmd1d.js} +9 -9
- package/{module.command-t68xhamx.js → module.command-0t3ewata.js} +8 -8
- package/{package.command-00ncttab.js → package.command-7hmkxvpa.js} +4 -4
- package/package.json +2 -3
- package/{page.command-1096s18n.js → page.command-st6r4s0q.js} +4 -4
- package/{primitive.command-02eqpx6t.js → primitive.command-1qkxpzsn.js} +9 -9
- package/{quality.command-r9cageqb.js → quality.command-hy5vt1bh.js} +3 -3
- package/recipeScanner-tghkzrrt.js +12 -0
- package/{repair.command-7dynpnf1.js → repair.command-nakkq2zp.js} +7 -6
- package/{scalar.command-3kxy3fkh.js → scalar.command-fjq272gs.js} +7 -7
- package/templates/app/page/_index.tsx +55 -52
- package/templates/app/page/styles.css.template +12 -71
- package/templates/appSample/lib/task/Task.Template.tsx +2 -2
- package/templates/appSample/lib/task/Task.Unit.tsx +11 -11
- package/templates/appSample/lib/task/Task.Util.tsx +27 -28
- package/templates/appSample/lib/task/Task.View.tsx +22 -19
- package/templates/appSample/lib/task/Task.Zone.tsx +3 -3
- package/templates/appSample/page/task/[taskId]/_index.tsx +3 -3
- package/templates/appSample/page/task/[taskId]/edit.tsx +5 -5
- package/templates/appSample/page/task/_index.tsx +4 -4
- package/templates/appSample/page/task/_layout.tsx +1 -1
- package/templates/appSample/page/task/new.tsx +5 -5
- package/templates/appSample/ui/GlobalLoading.tsx +4 -4
- package/templates/appSample/ui/QuantityControl.tsx +5 -4
- package/templates/crudPages/[__model__Id]/page.tsx +1 -1
- package/templates/crudPages/page.tsx +1 -1
- package/templates/crudSinglePage/page.tsx +1 -1
- package/templates/module/__Model__.Template.tsx +2 -1
- package/templates/module/__Model__.Unit.tsx +2 -1
- package/templates/module/__Model__.Util.tsx +2 -1
- package/templates/module/__Model__.View.tsx +4 -3
- package/templates/module/__Model__.Zone.tsx +2 -1
- package/templates/workspaceRoot/AGENTS.md.template +11 -13
- package/templates/workspaceRoot/biome.json.template +1 -1
- package/{workflow.command-yy0d9gk3.js → workflow.command-jswbgk90.js} +15 -14
- package/{workspace.command-stv9g4a0.js → workspace.command-p9r9nckg.js} +87 -27
- package/{applicationReleasePackager-pjbxc793.js → applicationReleasePackager-yrrhbkv3.js} +3 -3
- package/{index-nsj2ftxj.js → index-3pgtw35d.js} +3 -3
package/.build-stamp
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
ce7835b9c7e649ebc830a1ac94fa9db80a2c2aaec64459445780b8dc7bd627a0
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
import {
|
|
3
|
+
AiSession
|
|
4
|
+
} from "./index-3pgtw35d.js";
|
|
2
5
|
import {
|
|
3
6
|
AbstractDoc
|
|
4
7
|
} from "./index-0wae5ebk.js";
|
|
5
|
-
import {
|
|
6
|
-
AiSession
|
|
7
|
-
} from "./index-nsj2ftxj.js";
|
|
8
|
-
import"./index-67546d0j.js";
|
|
9
8
|
import"./index-6pz1j0zj.js";
|
|
9
|
+
import"./index-67546d0j.js";
|
|
10
10
|
import"./index-r24hmh0q.js";
|
|
11
11
|
|
|
12
12
|
// pkgs/@akanjs/devkit/abstractCompactor.ts
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
AgentScript
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
6
|
-
import"./index-
|
|
7
|
-
import"./index-
|
|
4
|
+
} from "./index-n0z3f2xg.js";
|
|
5
|
+
import"./index-4yp06pn1.js";
|
|
6
|
+
import"./index-4zgs8g1w.js";
|
|
7
|
+
import"./index-xwgm94zr.js";
|
|
8
8
|
import {
|
|
9
9
|
Workspace,
|
|
10
10
|
command
|
|
11
|
-
} from "./index-
|
|
12
|
-
import"./index-
|
|
13
|
-
import"./index-67546d0j.js";
|
|
11
|
+
} from "./index-jk9q6pse.js";
|
|
12
|
+
import"./index-jtm86byd.js";
|
|
14
13
|
import"./index-6pz1j0zj.js";
|
|
14
|
+
import"./index-xys926f2.js";
|
|
15
|
+
import"./index-67546d0j.js";
|
|
15
16
|
import"./index-r24hmh0q.js";
|
|
16
17
|
|
|
17
18
|
// pkgs/@akanjs/cli/agent/agent.command.ts
|
|
@@ -4,23 +4,23 @@ import {
|
|
|
4
4
|
} from "./index-0wae5ebk.js";
|
|
5
5
|
import {
|
|
6
6
|
ApplicationScript
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-ev6rjw9n.js";
|
|
8
8
|
import {
|
|
9
9
|
getMobileTargetChoices
|
|
10
10
|
} from "./index-76rn3g2c.js";
|
|
11
|
-
import"./index-
|
|
11
|
+
import"./index-cn24dcqn.js";
|
|
12
12
|
import {
|
|
13
13
|
App,
|
|
14
14
|
Exec,
|
|
15
15
|
Sys,
|
|
16
16
|
Workspace,
|
|
17
17
|
command
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-jk9q6pse.js";
|
|
19
19
|
import"./index-fgc8r6dj.js";
|
|
20
|
-
import"./index-xwfg9bam.js";
|
|
21
|
-
import"./index-67546d0j.js";
|
|
22
20
|
import"./index-bjpxzr6s.js";
|
|
21
|
+
import"./index-jtm86byd.js";
|
|
23
22
|
import"./index-6pz1j0zj.js";
|
|
23
|
+
import"./index-67546d0j.js";
|
|
24
24
|
import"./index-r24hmh0q.js";
|
|
25
25
|
|
|
26
26
|
// pkgs/@akanjs/cli/application/application.command.ts
|
package/buildBatch.proc.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import {
|
|
3
|
-
AppExecutor,
|
|
4
|
-
WorkspaceExecutor
|
|
5
|
-
} from "./index-xwfg9bam.js";
|
|
6
|
-
import"./index-67546d0j.js";
|
|
7
2
|
import {
|
|
8
3
|
CsrArtifactBuilder,
|
|
9
4
|
CssCompiler,
|
|
10
5
|
FontOptimizer,
|
|
11
6
|
PagesBundleBuilder,
|
|
12
7
|
SsrBaseArtifactBuilder
|
|
13
|
-
} from "./index-
|
|
8
|
+
} from "./index-pyt2b4nw.js";
|
|
9
|
+
import"./index-xjd3rqzj.js";
|
|
14
10
|
import"./index-rh16j3c7.js";
|
|
15
11
|
import"./index-bjpxzr6s.js";
|
|
12
|
+
import {
|
|
13
|
+
AppExecutor,
|
|
14
|
+
WorkspaceExecutor
|
|
15
|
+
} from "./index-jtm86byd.js";
|
|
16
16
|
import"./index-6pz1j0zj.js";
|
|
17
|
+
import"./index-67546d0j.js";
|
|
17
18
|
import"./index-r24hmh0q.js";
|
|
18
19
|
|
|
19
20
|
// pkgs/@akanjs/devkit/incrementalBuilder/buildBatch.proc.ts
|
|
@@ -24,11 +24,11 @@ import {
|
|
|
24
24
|
selectLocalDevHost,
|
|
25
25
|
sortIosRunTargets,
|
|
26
26
|
writeRootCapacitorConfig
|
|
27
|
-
} from "./index-
|
|
27
|
+
} from "./index-sggm9qkv.js";
|
|
28
28
|
import"./index-76rn3g2c.js";
|
|
29
|
-
import"./index-
|
|
30
|
-
import"./index-67546d0j.js";
|
|
29
|
+
import"./index-jtm86byd.js";
|
|
31
30
|
import"./index-6pz1j0zj.js";
|
|
31
|
+
import"./index-67546d0j.js";
|
|
32
32
|
import"./index-r24hmh0q.js";
|
|
33
33
|
export {
|
|
34
34
|
writeRootCapacitorConfig,
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
CloudScript
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
6
|
-
import"./index-
|
|
4
|
+
} from "./index-f4gqk0dd.js";
|
|
5
|
+
import"./index-ktprgc5g.js";
|
|
6
|
+
import"./index-e3qskyt2.js";
|
|
7
7
|
import {
|
|
8
8
|
GlobalConfig
|
|
9
|
-
} from "./index-
|
|
10
|
-
import"./index-
|
|
9
|
+
} from "./index-3pgtw35d.js";
|
|
10
|
+
import"./index-ev6rjw9n.js";
|
|
11
11
|
import"./index-76rn3g2c.js";
|
|
12
|
-
import"./index-
|
|
12
|
+
import"./index-cn24dcqn.js";
|
|
13
13
|
import {
|
|
14
14
|
Workspace,
|
|
15
15
|
command
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-jk9q6pse.js";
|
|
17
17
|
import"./index-fgc8r6dj.js";
|
|
18
|
-
import"./index-xwfg9bam.js";
|
|
19
|
-
import"./index-46tjzh6s.js";
|
|
20
|
-
import"./index-67546d0j.js";
|
|
21
18
|
import"./index-bjpxzr6s.js";
|
|
19
|
+
import"./index-jtm86byd.js";
|
|
22
20
|
import"./index-6pz1j0zj.js";
|
|
21
|
+
import"./index-46tjzh6s.js";
|
|
22
|
+
import"./index-67546d0j.js";
|
|
23
23
|
import"./index-r24hmh0q.js";
|
|
24
24
|
|
|
25
25
|
// pkgs/@akanjs/cli/cloud/cloud.command.ts
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
ContextScript
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
6
|
-
import"./index-
|
|
7
|
-
import"./index-
|
|
8
|
-
import"./index-
|
|
9
|
-
import"./index-
|
|
10
|
-
import"./index-
|
|
4
|
+
} from "./index-h0bngh79.js";
|
|
5
|
+
import"./index-b978vs2e.js";
|
|
6
|
+
import"./index-csqk9z5j.js";
|
|
7
|
+
import"./index-r4w8cry5.js";
|
|
8
|
+
import"./index-vhv3xnjz.js";
|
|
9
|
+
import"./index-hjzr8ja1.js";
|
|
10
|
+
import"./index-fmgbwsr5.js";
|
|
11
11
|
import"./index-ss469dec.js";
|
|
12
|
-
import"./index-
|
|
13
|
-
import"./index-
|
|
14
|
-
import"./index-
|
|
15
|
-
import"./index-
|
|
16
|
-
import"./index-
|
|
12
|
+
import"./index-sggm9qkv.js";
|
|
13
|
+
import"./index-3pgtw35d.js";
|
|
14
|
+
import"./index-4yp06pn1.js";
|
|
15
|
+
import"./index-4zgs8g1w.js";
|
|
16
|
+
import"./index-xwgm94zr.js";
|
|
17
17
|
import"./index-76rn3g2c.js";
|
|
18
18
|
import {
|
|
19
19
|
Workspace,
|
|
20
20
|
command
|
|
21
|
-
} from "./index-
|
|
22
|
-
import"./index-
|
|
23
|
-
import"./index-67546d0j.js";
|
|
21
|
+
} from "./index-jk9q6pse.js";
|
|
22
|
+
import"./index-jtm86byd.js";
|
|
24
23
|
import"./index-6pz1j0zj.js";
|
|
24
|
+
import"./index-xys926f2.js";
|
|
25
|
+
import"./index-67546d0j.js";
|
|
25
26
|
import"./index-r24hmh0q.js";
|
|
26
27
|
|
|
27
28
|
// pkgs/@akanjs/cli/context/context.command.ts
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import {
|
|
3
|
-
Prompter
|
|
4
|
-
} from "./index-xftstr5s.js";
|
|
5
2
|
import {
|
|
6
3
|
AiSession
|
|
7
|
-
} from "./index-
|
|
4
|
+
} from "./index-3pgtw35d.js";
|
|
5
|
+
import {
|
|
6
|
+
Prompter
|
|
7
|
+
} from "./index-xwgm94zr.js";
|
|
8
8
|
import {
|
|
9
9
|
Workspace,
|
|
10
10
|
command,
|
|
11
11
|
runner,
|
|
12
12
|
script
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-jk9q6pse.js";
|
|
14
14
|
import {
|
|
15
15
|
getDirname
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-jtm86byd.js";
|
|
17
|
+
import"./index-6pz1j0zj.js";
|
|
17
18
|
import {
|
|
18
19
|
FileSys
|
|
19
20
|
} from "./index-67546d0j.js";
|
|
20
|
-
import"./index-6pz1j0zj.js";
|
|
21
21
|
import"./index-r24hmh0q.js";
|
|
22
22
|
|
|
23
23
|
// pkgs/@akanjs/cli/guideline/guideline.script.ts
|
|
@@ -151,7 +151,7 @@ ${await this.getDocumentation("framework")}
|
|
|
151
151
|
2. Documentation page writing method
|
|
152
152
|
${await this.getDocumentation("docPageRule")}
|
|
153
153
|
|
|
154
|
-
3. CSS rule with TailwindCSS and
|
|
154
|
+
3. CSS rule with TailwindCSS and akanjs/ui primitives (semantic tokens; no daisyui)
|
|
155
155
|
${await this.getDocumentation("cssRule")}
|
|
156
156
|
|
|
157
157
|
I want to update the Next.js server-side page located at ${writePath}.
|
|
@@ -165,8 +165,8 @@ Please update this page with the latest content below. A great design applicatio
|
|
|
165
165
|
${instruction}
|
|
166
166
|
|
|
167
167
|
Please follow these CSS rules when writing:
|
|
168
|
-
- Use tailwindcss
|
|
169
|
-
- Use
|
|
168
|
+
- Use tailwindcss with the semantic design tokens (bg-background, text-foreground, bg-primary, text-muted-foreground, border-border, \u2026)
|
|
169
|
+
- Use akanjs/ui primitives (Button, Badge, Input, Field, \u2026) instead of raw daisyui classes; do not use daisyui
|
|
170
170
|
|
|
171
171
|
Please return only the file result in the following format for easy parsing.
|
|
172
172
|
\`\`\`tsx
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Use this for shared UI rules across module, scalar, app UI, and docs components.
|
|
5
5
|
|
|
6
6
|
## Ownership
|
|
7
|
-
- Accept `className?: string` for reusable components and forward it through `
|
|
7
|
+
- Accept `className?: string` for reusable components and forward it through `cn` (from `akanjs/client`), or as the second argument of a recipe (`buttonRecipe(variants, className)`).
|
|
8
8
|
- Use semantic HTML and accessible labels for interactive elements.
|
|
9
9
|
- Use `akanjs/ui` and project UI libraries before adding new primitives.
|
|
10
10
|
- Keep presentation components small; move page composition to Zone and actions to Util or store.
|
|
@@ -26,7 +26,7 @@ Use this for shared UI rules across module, scalar, app UI, and docs components.
|
|
|
26
26
|
## Codegen Rules
|
|
27
27
|
- Do not put business workflow decisions in render code.
|
|
28
28
|
- Do not use undocumented UI components or props.
|
|
29
|
-
- Do not use hardcoded colors when
|
|
29
|
+
- Do not use hardcoded colors when semantic token classes (`bg-primary`, `text-foreground`, …) work.
|
|
30
30
|
- Do not create broad component abstractions before repeated patterns exist.
|
|
31
31
|
|
|
32
32
|
## Review Checklist
|
|
@@ -1,46 +1,69 @@
|
|
|
1
1
|
# CSS Rule Guideline
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
|
-
Use TailwindCSS
|
|
4
|
+
Use TailwindCSS with Akan's semantic design-token layer and the `akanjs/ui` primitives for app UI and docs pages.
|
|
5
5
|
|
|
6
6
|
## Ownership
|
|
7
7
|
- Use Tailwind utility classes for layout, spacing, typography, and responsive behavior.
|
|
8
|
-
- Use
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
8
|
+
- Use Akan's semantic color tokens — never a raw Tailwind palette color (`bg-blue-500`) or a hex value:
|
|
9
|
+
- Surfaces/text: `bg-background`, `text-foreground`, `bg-muted`, `text-muted-foreground`, `bg-card`, `bg-popover`, `border-border`, `border-input`, `ring-ring`.
|
|
10
|
+
- Brand/status: `primary`, `secondary`, `accent`, `destructive`, `success`, `warning`, `info`, `neutral`, `open` — each with a `-foreground` pair for text on that surface (e.g. `bg-primary text-primary-foreground`).
|
|
11
|
+
- Compose classes with `cn` from `akanjs/client` (token-aware tailwind-merge) — the only class-combining function. No object syntax: write `cond && "x"`.
|
|
12
|
+
- Forward `className` last so callers can extend styles.
|
|
13
|
+
|
|
14
|
+
## Recipe Layer
|
|
15
|
+
- Reusable or variant-like styling belongs in a recipe (a cva-style factory), not repeated inline class stacks.
|
|
16
|
+
- Framework primitives ship recipes: `buttonRecipe` and `badgeRecipe` from `akanjs/ui`. Call them as `buttonRecipe(variants, className?)` — the second argument is merged automatically, so you never wrap it in `cn()`:
|
|
17
|
+
- `buttonRecipe({ variant: "primary", size: "lg" }, "w-full rounded-2xl")`
|
|
18
|
+
- Prefer the `akanjs/ui` primitives (`Button`, `Badge`, `Input`, `Field`, `Table` …) over re-implementing a component's look with utility stacks. There is **no `Card`/`Box` primitive** — a card/box is a recipe surface (e.g. `appCard`), not an `akanjs/ui` component; do not `import { Card }`.
|
|
19
|
+
- App-specific repeated surfaces go one-per-file in `apps/<app>/ui/Recipe/` (server-safe, no `"use client"`) via `recipe(tv({ base, variants }))`, imported from `@apps/<app>/ui`. App recipes **extend** (surfaces the lib lacks — chat bubble, tile); they never re-define a lib component in parallel.
|
|
20
|
+
- Full recipe authoring/consumption policy: the `recipeRule` guideline. Never guess recipe names/imports — the authoritative list is `AGENTS.md` `## UI Recipes` plus the `list_recipes` tool.
|
|
21
|
+
|
|
22
|
+
## Customization Decision (where a design delta goes)
|
|
23
|
+
Screen code is invariant — a plain `<Button variant="primary">` never changes. Only these config files do:
|
|
24
|
+
- **Theme differs** (color/radius/font) → override token *values* in `apps/<app>/page/styles.css`.
|
|
25
|
+
- **A lib component's look differs** → recipe override: `export default override({ recipes: { button: neonButtonRecipe } })` in a `page/**/_overrides.tsx`. Every `<Button>` in that route subtree re-skins; behavior (async states, focus, a11y) is untouched. The swap recipe must accept the framework recipe's full variant surface.
|
|
26
|
+
- **Structure/behavior differs** (modal → drawer) → component override (`override({ Modal: BrandModal })`), reassembling headless parts.
|
|
27
|
+
- **A surface the lib lacks** → a new app recipe (extension).
|
|
28
|
+
- Do not fight the cascade with `!important`, and when the same inline className tweak repeats, promote it to a recipe override or a variant.
|
|
29
|
+
|
|
30
|
+
## Theme Declaration (`apps/<app>/page/styles.css`)
|
|
31
|
+
- The file imports Tailwind and the framework tokens, then overrides token *values* per theme:
|
|
32
|
+
```css
|
|
33
|
+
@import "tailwindcss";
|
|
34
|
+
@import "akanjs/ui/styles.css";
|
|
35
|
+
|
|
36
|
+
:root,
|
|
37
|
+
[data-theme="dark"] {
|
|
38
|
+
--background: #1a1a1a;
|
|
39
|
+
--foreground: #ffffff;
|
|
40
|
+
--primary: #ff493b;
|
|
41
|
+
--primary-foreground: #ffffff;
|
|
42
|
+
--muted: #2a2a2a;
|
|
43
|
+
--border: #3a3a3a;
|
|
44
|
+
}
|
|
45
|
+
[data-theme="light"] {
|
|
46
|
+
--background: #fafafa;
|
|
47
|
+
--foreground: #2c3e50;
|
|
48
|
+
--primary: #c33c32;
|
|
49
|
+
--primary-foreground: #ffffff;
|
|
50
|
+
--muted: #f5f5f5;
|
|
51
|
+
--border: #e5e5e5;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
- The framework maps these variables to Tailwind color names (`@theme inline` in `akanjs/ui/styles.css`), so a class like `bg-primary` / `text-foreground` resolves to different colors per `data-theme` — the app only sets values, never re-declares the mapping.
|
|
55
|
+
- Switching themes is toggling the `data-theme` attribute. Keep every token defined in both the dark and light blocks.
|
|
56
|
+
- Radius uses `rounded-box` (cards/modals), `rounded-field` (buttons/inputs), `rounded-selector` (toggles/checkboxes).
|
|
35
57
|
|
|
36
58
|
## Codegen Rules
|
|
37
|
-
- Do not hardcode hex
|
|
38
|
-
- Do not
|
|
59
|
+
- Do not hardcode hex or raw-palette colors (`bg-red-500`, `#ff0000`); use semantic tokens.
|
|
60
|
+
- Do not put inline color literals in `style={{ }}`; use token classes.
|
|
61
|
+
- Do not use `!important` to fight component composition.
|
|
39
62
|
- Do not hide focus states on interactive elements.
|
|
40
|
-
-
|
|
63
|
+
- When an `akanjs/ui` component is structurally too restrictive, re-skin it with a `page/**/_overrides.tsx` slot override (see the componentRule guideline), not `!important` utilities or a fork.
|
|
41
64
|
|
|
42
65
|
## Review Checklist
|
|
43
|
-
-
|
|
44
|
-
-
|
|
66
|
+
- All color goes through semantic tokens — no raw palette, no hex, no inline color.
|
|
67
|
+
- Repeated/variant styling uses a recipe; class composition uses `cn` (never raw `twMerge`/`clsx` imports).
|
|
68
|
+
- The instruction points to current docs pages and current Akan builder APIs.
|
|
45
69
|
- The output contract tells the model which file paths to return.
|
|
46
|
-
- The guide avoids broad framework essays when a concrete file rule is better.
|
|
@@ -25,7 +25,7 @@ Use this as the compact framework context for AI codegen. It should explain how
|
|
|
25
25
|
## Theming And UI Customization
|
|
26
26
|
When a request implies a distinct look and feel, do not stop at colors — customize both the theme and, when needed, the components.
|
|
27
27
|
|
|
28
|
-
- **Theme (`apps/<app>/page/styles.css`).** The app
|
|
28
|
+
- **Theme (`apps/<app>/page/styles.css`).** The app imports Tailwind and `akanjs/ui/styles.css`, then overrides semantic token *values* per theme under `:root, [data-theme="dark"]` and `[data-theme="light"]` (`--background`, `--foreground`, `--primary`, `--muted`, `--border`, … each with a `-foreground` pair for text). The framework maps them to Tailwind color names, so `bg-primary` / `text-foreground` follow the `data-theme` attribute; corner rounding uses `--radius-box` / `--radius-field`. Fetch `get_guideline` with `cssRule` for the full token set before a deep theme pass.
|
|
29
29
|
- **Components (`page/**/_overrides.tsx`).** When a default `akanjs/ui` component (Button, Modal, Table, Input, Select, …) is too restrictive for the design, re-skin it per route instead of forking, wrapping, or fighting it with utility classes. Write a drop-in replacement in `apps/<app>/ui/` typed against the slot contract (`AkanModalComponent`, or `AkanUiOverrides["<Slot>"]`), composing the framework's headless parts, then bind it in a `page/**/_overrides.tsx` manifest with a single `export default override({ Slot: BrandComponent })`. Overrides cascade down the route tree like layouts (closest ancestor wins). Fetch `get_guideline` with `componentRule` and read the `references/ui/customize` docs page for the slot list and patterns.
|
|
30
30
|
|
|
31
31
|
## Review Checklist
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Recipe Rule",
|
|
3
|
+
"description": "Akan UI recipe authoring and consumption rules (reusable-look layer)",
|
|
4
|
+
"group": "core",
|
|
5
|
+
"docsSource": "apps/akan/page/(docs)/docs/arch/ui-recipe.tsx",
|
|
6
|
+
"codegenPriority": 3,
|
|
7
|
+
"deprecated": false,
|
|
8
|
+
"scans": [
|
|
9
|
+
{
|
|
10
|
+
"type": "docs",
|
|
11
|
+
"description": "Current docs source for Recipe Rule",
|
|
12
|
+
"path": "apps/akan/page/(docs)/docs/arch/ui-recipe.tsx"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"type": "example",
|
|
16
|
+
"description": "Existing recipe definitions",
|
|
17
|
+
"path": "{apps,libs}/*/ui/Recipe/*.ts",
|
|
18
|
+
"sample": 4
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"update": {
|
|
22
|
+
"filePath": "./recipeRule.instruction.md",
|
|
23
|
+
"contents": ["purpose", "ownership", "consuming", "authoring", "codegen rules", "review checklist"],
|
|
24
|
+
"rules": [
|
|
25
|
+
"Use current Akan APIs only",
|
|
26
|
+
"Keep output parseable for codegen",
|
|
27
|
+
"Include ownership boundaries and review checklist"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"page": "apps/akan/page/(docs)/docs/arch/ui-recipe.tsx"
|
|
31
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Recipe Rule Guideline
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Recipes are the reusable-look layer of Akan UI: Tailwind-variant factories (`recipe(tv({...}))`) that sit between semantic
|
|
5
|
+
tokens (values) and components (behavior). This rule governs how agents **consume** and **author** recipes so a look is not
|
|
6
|
+
hallucinated, re-derived inline, or duplicated across an app.
|
|
7
|
+
|
|
8
|
+
## Ownership
|
|
9
|
+
- A recipe owns a **look** (a composition of semantic-token utility classes), never behavior. Behavior lives in components.
|
|
10
|
+
- **One recipe per file.** App/lib recipes live in `apps/<app>/ui/Recipe/<name>.ts` and `libs/<lib>/ui/Recipe/<name>.ts`,
|
|
11
|
+
re-exported from that folder's hand-written `index.ts`; framework recipes (`buttonRecipe`, `badgeRecipe`,
|
|
12
|
+
`inputRecipe`) mirror the same shape in `pkgs/akanjs/ui/recipe/<name>Recipe.ts`. Apps inherit the framework recipes by
|
|
13
|
+
re-exporting them from their own `Recipe/index.ts`, so a consumer imports every recipe from one barrel.
|
|
14
|
+
- The folder must be `Recipe` (PascalCase) in an app/lib `ui/`: the generated `ui/index.ts` exports PascalCase names
|
|
15
|
+
only, so a flat `appCard.recipe.ts` is silently skipped and becomes unimportable. Inside the folder any camelCase
|
|
16
|
+
filename is fine — the barrel only scans one level.
|
|
17
|
+
- Recipes use **semantic tokens only** in their `base`/`variants` (never raw palette or hex); they inherit the CSS token rules.
|
|
18
|
+
|
|
19
|
+
## Consuming Recipes
|
|
20
|
+
- Import by **exact name** from the owning barrel: `import { <name> } from "@apps/<app>/ui"` (or `akanjs/ui` for framework),
|
|
21
|
+
then call `<name>(variants?, className?)` — the second arg is merged automatically; no extra `cn()` wrapper is needed.
|
|
22
|
+
- The second arg is a `ClassNameValue`, so it takes **an array (and falsy entries), not just one string**:
|
|
23
|
+
`<name>({}, ["h-full", isWide && "w-full", className])`. Reaching for `cn()` to combine several classes is the
|
|
24
|
+
usual way the no-`cn` contract leaks — there is nothing `cn()` adds here that the recipe does not already do.
|
|
25
|
+
- **Do not guess** recipe names or import paths. The authoritative index is split by ownership: the root `AGENTS.md`
|
|
26
|
+
`## Recipes` (always loaded) lists **framework** recipes, and each app/lib's own `AGENTS.md` (`## Recipes In Scope`)
|
|
27
|
+
lists what that scope may additionally import — its own recipes plus its dependency libs'. Both carry every recipe's
|
|
28
|
+
variant surface and default, so consuming one never requires opening its file. The scoped index is regenerated by
|
|
29
|
+
`akan sync <name>` and kept honest by `akan lint <name>`, which fails when it is stale.
|
|
30
|
+
- Variant options are typed (`Parameters<typeof <name>>[0]`), so a wrong variant is a compile error — let tsc validate
|
|
31
|
+
options rather than memorizing strings.
|
|
32
|
+
|
|
33
|
+
## Recipe vs Component vs Constant — The Gate
|
|
34
|
+
The form of a shared look is decided by **counting**, not judgment (`akan lint` enforces this as `recipeGate`):
|
|
35
|
+
|
|
36
|
+
1. **Does the caller choose an option?** (at least one variant axis with 2+ values, or a boolean flag)
|
|
37
|
+
- **No** → it is **never a recipe** — a fixed look wrapped in a function is dead indirection.
|
|
38
|
+
- Reused with its own markup → a small **component** (`<Divider/>`, `<DocsList/>`, `<Screen/>`).
|
|
39
|
+
- Injected into another component's `className` prop → a shared **class constant** (`appNavClass`).
|
|
40
|
+
- Used once → plain **inline** classes.
|
|
41
|
+
- **Yes** → it is a recipe. Then:
|
|
42
|
+
2. **Does it need markup or behavior** (own tag, structure, state, a11y)?
|
|
43
|
+
- No → pages call the recipe directly on their own element (`panelRecipe({ padding: "row" })`).
|
|
44
|
+
- Yes → a component consumes the recipe internally (`<Button variant>` → `buttonRecipe`).
|
|
45
|
+
|
|
46
|
+
## Authoring Recipes
|
|
47
|
+
- A **reusable or repeated surface** (card, box, tile, chat bubble, hero, …) belongs in a recipe, **not** inline. If the same
|
|
48
|
+
token-class stack appears in more than one place, extract it into a recipe.
|
|
49
|
+
- **Before authoring, check the existing recipe indexes** (root `AGENTS.md` `## Recipes` for framework recipes, the
|
|
50
|
+
scope's own `AGENTS.md` `## Recipes In Scope` for app/lib recipes) and **reuse** a matching recipe instead of
|
|
51
|
+
creating a near-duplicate — registry sprawl comes from re-inventing looks that already exist.
|
|
52
|
+
- Add a new recipe as its own file, `ui/Recipe/<name>.ts` holding a single
|
|
53
|
+
`export const <name>Recipe = recipe(tv({ base, variants }))` plus a one-line JSDoc describing the surface, then
|
|
54
|
+
re-export it from `ui/Recipe/index.ts`. Name the export `<name>Recipe`; the filename drops the suffix.
|
|
55
|
+
- Keep declaration and css in that one file. Splitting a recipe into a hand-written variant type plus a separate style
|
|
56
|
+
file inverts the dependency: the variant type is currently *inferred* from the `tv` config
|
|
57
|
+
(`Parameters<typeof <name>Recipe>[0]`), which makes type/css drift structurally impossible, and the AGENTS listing
|
|
58
|
+
already exposes the surface without reading the file. There is nothing left for the split to buy.
|
|
59
|
+
- App recipes **extend** (surfaces the framework lacks); they never re-define a framework component's look in parallel.
|
|
60
|
+
|
|
61
|
+
## Codegen Rules
|
|
62
|
+
- Do not re-derive inline a look that an existing recipe already provides.
|
|
63
|
+
- Do not author a near-duplicate of an existing recipe; reuse or extend it.
|
|
64
|
+
- Do not guess recipe names or import paths; use the authoritative list.
|
|
65
|
+
- Do not put raw-palette / hex / inline color in a recipe; semantic tokens only.
|
|
66
|
+
|
|
67
|
+
## Review Checklist
|
|
68
|
+
- Repeated/variant surfaces are recipes, not inline class stacks duplicated across files.
|
|
69
|
+
- No two recipes describe the same look; consumers import by exact name from the correct barrel.
|
|
70
|
+
- New recipes live one-per-file in the owning `ui/Recipe/`, exported as `<name>Recipe`, token-only, with a one-line doc,
|
|
71
|
+
and re-exported from that folder's `index.ts`.
|
|
72
|
+
- The output contract tells the model which file paths to return.
|
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
import {
|
|
3
3
|
prepareDevWatchBatch
|
|
4
4
|
} from "./index-fgc8r6dj.js";
|
|
5
|
-
import {
|
|
6
|
-
AppExecutor,
|
|
7
|
-
WorkspaceExecutor
|
|
8
|
-
} from "./index-xwfg9bam.js";
|
|
9
|
-
import"./index-67546d0j.js";
|
|
10
5
|
import {
|
|
11
6
|
AutoImportSync,
|
|
12
7
|
DevChangePlanner,
|
|
@@ -18,7 +13,12 @@ import {
|
|
|
18
13
|
HmrWatcher,
|
|
19
14
|
WatchRootResolver
|
|
20
15
|
} from "./index-bjpxzr6s.js";
|
|
16
|
+
import {
|
|
17
|
+
AppExecutor,
|
|
18
|
+
WorkspaceExecutor
|
|
19
|
+
} from "./index-jtm86byd.js";
|
|
21
20
|
import"./index-6pz1j0zj.js";
|
|
21
|
+
import"./index-67546d0j.js";
|
|
22
22
|
import"./index-r24hmh0q.js";
|
|
23
23
|
|
|
24
24
|
// pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts
|