@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.
Files changed (79) hide show
  1. package/.build-stamp +1 -1
  2. package/{abstractCompactor-ghh1q9an.js → abstractCompactor-rk6twzvj.js} +4 -4
  3. package/{agent.command-de4r6vk8.js → agent.command-jfz8yfwy.js} +8 -7
  4. package/{application.command-nfsfm96y.js → application.command-3smsv7mq.js} +5 -5
  5. package/{applicationBuildRunner-554a2vnk.js → applicationBuildRunner-aq7mb3z6.js} +2 -1
  6. package/buildBatch.proc.js +7 -6
  7. package/{capacitorApp-yg9b4ajz.js → capacitorApp-q3mpmkkz.js} +3 -3
  8. package/{cloud.command-1qf95x67.js → cloud.command-rk4e9vrt.js} +10 -10
  9. package/{context.command-hhjyjtp7.js → context.command-ygzyb0xb.js} +16 -15
  10. package/{guideline.command-vj956kfr.js → guideline.command-1m1ctar3.js} +10 -10
  11. package/guidelines/componentRule/componentRule.instruction.md +2 -2
  12. package/guidelines/cssRule/cssRule.generate.json +1 -1
  13. package/guidelines/cssRule/cssRule.instruction.md +57 -34
  14. package/guidelines/framework/framework.instruction.md +1 -1
  15. package/guidelines/recipeRule/recipeRule.generate.json +31 -0
  16. package/guidelines/recipeRule/recipeRule.instruction.md +72 -0
  17. package/incrementalBuilder.proc.js +5 -5
  18. package/{index-v9jqrdd1.js → index-4yp06pn1.js} +100 -2
  19. package/{index-pfnh87f9.js → index-4zgs8g1w.js} +1 -1
  20. package/{index-7ppn9v4n.js → index-b978vs2e.js} +3 -3
  21. package/{index-s9s0n5fz.js → index-cn24dcqn.js} +2 -2
  22. package/{index-h971erkm.js → index-csqk9z5j.js} +3 -3
  23. package/{index-z36qzgzp.js → index-e3qskyt2.js} +3 -4
  24. package/{index-fbv96xaw.js → index-ev6rjw9n.js} +11 -11
  25. package/{index-h6eav7zx.js → index-f4gqk0dd.js} +6 -6
  26. package/{index-z5v766nx.js → index-fmgbwsr5.js} +6 -6
  27. package/{index-y1e79mz3.js → index-h0bngh79.js} +13 -13
  28. package/{index-dgeaqwmw.js → index-hjzr8ja1.js} +1 -1
  29. package/{index-d0h48d2f.js → index-jk9q6pse.js} +1 -1
  30. package/{index-xwfg9bam.js → index-jtm86byd.js} +120 -4
  31. package/{index-h5cvg9z9.js → index-ktprgc5g.js} +4 -4
  32. package/{index-zn9rh7sh.js → index-n0z3f2xg.js} +73 -24
  33. package/{index-7k9sj7j5.js → index-pyt2b4nw.js} +212 -0
  34. package/{index-acwxfncv.js → index-r4w8cry5.js} +4 -4
  35. package/{index-zfp1gz9f.js → index-sggm9qkv.js} +1 -1
  36. package/{index-04as43rp.js → index-vhv3xnjz.js} +16 -15
  37. package/index-xjd3rqzj.js +129 -0
  38. package/{index-xftstr5s.js → index-xwgm94zr.js} +1 -1
  39. package/index-xys926f2.js +136 -0
  40. package/index.js +19 -19
  41. package/{library.command-68ah07a3.js → library.command-pwfx8dx2.js} +4 -4
  42. package/{localRegistry.command-84dz000g.js → localRegistry.command-bxhqmd1d.js} +9 -9
  43. package/{module.command-t68xhamx.js → module.command-0t3ewata.js} +8 -8
  44. package/{package.command-00ncttab.js → package.command-7hmkxvpa.js} +4 -4
  45. package/package.json +2 -3
  46. package/{page.command-1096s18n.js → page.command-st6r4s0q.js} +4 -4
  47. package/{primitive.command-02eqpx6t.js → primitive.command-1qkxpzsn.js} +9 -9
  48. package/{quality.command-r9cageqb.js → quality.command-hy5vt1bh.js} +3 -3
  49. package/recipeScanner-tghkzrrt.js +12 -0
  50. package/{repair.command-7dynpnf1.js → repair.command-nakkq2zp.js} +7 -6
  51. package/{scalar.command-3kxy3fkh.js → scalar.command-fjq272gs.js} +7 -7
  52. package/templates/app/page/_index.tsx +55 -52
  53. package/templates/app/page/styles.css.template +12 -71
  54. package/templates/appSample/lib/task/Task.Template.tsx +2 -2
  55. package/templates/appSample/lib/task/Task.Unit.tsx +11 -11
  56. package/templates/appSample/lib/task/Task.Util.tsx +27 -28
  57. package/templates/appSample/lib/task/Task.View.tsx +22 -19
  58. package/templates/appSample/lib/task/Task.Zone.tsx +3 -3
  59. package/templates/appSample/page/task/[taskId]/_index.tsx +3 -3
  60. package/templates/appSample/page/task/[taskId]/edit.tsx +5 -5
  61. package/templates/appSample/page/task/_index.tsx +4 -4
  62. package/templates/appSample/page/task/_layout.tsx +1 -1
  63. package/templates/appSample/page/task/new.tsx +5 -5
  64. package/templates/appSample/ui/GlobalLoading.tsx +4 -4
  65. package/templates/appSample/ui/QuantityControl.tsx +5 -4
  66. package/templates/crudPages/[__model__Id]/page.tsx +1 -1
  67. package/templates/crudPages/page.tsx +1 -1
  68. package/templates/crudSinglePage/page.tsx +1 -1
  69. package/templates/module/__Model__.Template.tsx +2 -1
  70. package/templates/module/__Model__.Unit.tsx +2 -1
  71. package/templates/module/__Model__.Util.tsx +2 -1
  72. package/templates/module/__Model__.View.tsx +4 -3
  73. package/templates/module/__Model__.Zone.tsx +2 -1
  74. package/templates/workspaceRoot/AGENTS.md.template +11 -13
  75. package/templates/workspaceRoot/biome.json.template +1 -1
  76. package/{workflow.command-yy0d9gk3.js → workflow.command-jswbgk90.js} +15 -14
  77. package/{workspace.command-stv9g4a0.js → workspace.command-p9r9nckg.js} +87 -27
  78. package/{applicationReleasePackager-pjbxc793.js → applicationReleasePackager-yrrhbkv3.js} +3 -3
  79. package/{index-nsj2ftxj.js → index-3pgtw35d.js} +3 -3
@@ -4,7 +4,8 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
4
4
  return {
5
5
  filename: "Task.View.tsx",
6
6
  content: `import { type cnst, usePage } from "@apps/${dict.appName}/client";
7
- import { clsx } from "akanjs/client";
7
+ import { cn } from "akanjs/client";
8
+ import { badgeRecipe } from "akanjs/ui";
8
9
 
9
10
  // ===== Task.View.tsx =====
10
11
  // Convention: lib/<module>/ — PascalCase .tsx, View suffix = detail display component.
@@ -20,25 +21,25 @@ interface GeneralProps {
20
21
  export const General = ({ className, task }: GeneralProps) => {
21
22
  const { l } = usePage();
22
23
  const statusColor = {
23
- todo: "text-base-content/50",
24
+ todo: "text-foreground/50",
24
25
  inProgress: "text-primary",
25
26
  completed: "text-success",
26
27
  }[task.status];
27
28
 
28
29
  return (
29
- <div className={clsx("flex w-full flex-col gap-4", className)}>
30
+ <div className={cn("flex w-full flex-col gap-4", className)}>
30
31
  <div>
31
- <h1 className="font-bold text-2xl text-base-content">{task.title}</h1>
32
- <div className={clsx("mt-1 font-medium text-sm", statusColor)}>{l(\`taskStatus.\${task.status}\`)}</div>
32
+ <h1 className="font-bold text-2xl text-foreground">{task.title}</h1>
33
+ <div className={cn("mt-1 font-medium text-sm", statusColor)}>{l(\`taskStatus.\${task.status}\`)}</div>
33
34
  </div>
34
35
 
35
36
  {task.content && (
36
- <div className="rounded-lg border border-base-content/10 bg-base-100 p-4">
37
- <p className="whitespace-pre-wrap text-base-content/80 text-sm">{task.content}</p>
37
+ <div className="rounded-lg border border-foreground/10 bg-background p-4">
38
+ <p className="whitespace-pre-wrap text-foreground/80 text-sm">{task.content}</p>
38
39
  </div>
39
40
  )}
40
41
 
41
- <div className="flex items-center gap-4 text-base-content/60 text-sm">
42
+ <div className="flex items-center gap-4 text-foreground/60 text-sm">
42
43
  <div>
43
44
  <span className="font-medium">{l("task.taskDueLabel")} </span>
44
45
  {task.due ? task.due.toDate().toLocaleDateString() : l("task.taskNoDue")}
@@ -46,23 +47,25 @@ export const General = ({ className, task }: GeneralProps) => {
46
47
  </div>
47
48
 
48
49
  {task.workHistory && task.workHistory.length > 0 && (
49
- <div className="mt-2 border-base-content/10 border-t pt-4">
50
- <h3 className="mb-3 font-semibold text-base-content text-sm">{l("task.taskWorkHistoryTitle")}</h3>
50
+ <div className="mt-2 border-foreground/10 border-t pt-4">
51
+ <h3 className="mb-3 font-semibold text-foreground text-sm">{l("task.taskWorkHistoryTitle")}</h3>
51
52
  <ul className="space-y-2">
52
53
  {task.workHistory.map((entry, i) => (
53
54
  <li key={i} className="flex items-start gap-3 text-sm">
54
55
  <span
55
- className={clsx("badge badge-xs mt-0.5 shrink-0", {
56
- "badge-ghost": entry.action === "created",
57
- "badge-primary": entry.action === "started",
58
- "badge-success": entry.action === "completed",
59
- })}
56
+ className={cn(
57
+ badgeRecipe({
58
+ variant:
59
+ entry.action === "started" ? "primary" : entry.action === "completed" ? "success" : "default",
60
+ }),
61
+ "mt-0.5 shrink-0",
62
+ )}
60
63
  >
61
64
  {l(\`workHistoryAction.\${entry.action}\`)}
62
65
  </span>
63
66
  <div>
64
- <span className="text-base-content/60">{entry.at.toDate().toLocaleString()}</span>
65
- {entry.note && <span className="ml-2 text-base-content/50">{entry.note}</span>}
67
+ <span className="text-foreground/60">{entry.at.toDate().toLocaleString()}</span>
68
+ {entry.note && <span className="ml-2 text-foreground/50">{entry.note}</span>}
66
69
  </div>
67
70
  </li>
68
71
  ))}
@@ -76,9 +79,9 @@ export const General = ({ className, task }: GeneralProps) => {
76
79
  // ---- Expandable additional fields: ----
77
80
  // Compact: for narrow spaces like sidebars or modals
78
81
  // export const Compact = ({ className, task }: CompactProps) => (
79
- // <div className={clsx("text-sm", className)}>
82
+ // <div className={cn("text-sm", className)}>
80
83
  // <span className="font-medium">{task.title}</span>
81
- // {task.due && <span className="text-base-content/50 ml-2">Due: {new Date(task.due).toLocaleDateString()}</span>}
84
+ // {task.due && <span className="text-foreground/50 ml-2">Due: {new Date(task.due).toLocaleDateString()}</span>}
82
85
  // </div>
83
86
  // );
84
87
  `,
@@ -6,7 +6,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
6
6
  content: `"use client";
7
7
  import { type cnst, Task, usePage } from "@apps/${dict.appName}/client";
8
8
  import type { ClientInit, ClientView } from "akanjs/fetch";
9
- import { Link, Load } from "akanjs/ui";
9
+ import { Link, Load, buttonRecipe } from "akanjs/ui";
10
10
 
11
11
  // ===== Task.Zone.tsx =====
12
12
  // Convention: lib/<module>/ — PascalCase .tsx, Zone suffix = composition layer between pages and UI.
@@ -28,9 +28,9 @@ export const Card = ({ className, init }: CardProps) => {
28
28
  init={init}
29
29
  renderEmpty={() => (
30
30
  <div className="flex flex-col items-center gap-4 py-16 text-center">
31
- <div className="text-base-content/40 text-lg">{l("task.taskNoTasks")}</div>
31
+ <div className="text-foreground/40 text-lg">{l("task.taskNoTasks")}</div>
32
32
  <Link href="/task/new">
33
- <button className="btn btn-primary btn-sm">{l("task.taskCreateFirst")}</button>
33
+ <button className={buttonRecipe({ variant: "primary", size: "sm" })}>{l("task.taskCreateFirst")}</button>
34
34
  </Link>
35
35
  </div>
36
36
  )}
@@ -6,7 +6,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
6
6
  content: `
7
7
  import { fetch, usePage } from "@apps/${dict.appName}/client";
8
8
  import { Task } from "@apps/${dict.appName}/lib/task";
9
- import { Link } from "akanjs/ui";
9
+ import { Link, buttonRecipe } from "akanjs/ui";
10
10
 
11
11
  // ===== page/task/[taskId]/_index.tsx =====
12
12
  // Convention: Akan.js file-based routing with dynamic segments.
@@ -22,10 +22,10 @@ export default async function Page({ params: { taskId } }: PageProps) {
22
22
  return (
23
23
  <main className="mx-auto max-w-4xl px-6 py-8">
24
24
  <div className="mb-6 flex items-center justify-between">
25
- <a href="/task" className="btn btn-ghost btn-sm">
25
+ <a href="/task" className={buttonRecipe({ variant: "ghost", size: "sm" })}>
26
26
  {l("task.taskBackToTasks")}
27
27
  </a>
28
- <Link href={\`/task/\${taskId}/edit\`} className="btn btn-primary btn-sm">
28
+ <Link href={\`/task/\${taskId}/edit\`} className={buttonRecipe({ variant: "primary", size: "sm" })}>
29
29
  {l("task.taskEdit")}
30
30
  </Link>
31
31
  </div>
@@ -4,7 +4,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
4
4
  return {
5
5
  filename: "edit.tsx",
6
6
  content: `import { fetch, Task } from "@apps/${dict.appName}/client";
7
- import { Load, Link } from "akanjs/ui";
7
+ import { Load, Link, buttonRecipe } from "akanjs/ui";
8
8
 
9
9
  // ===== page/task/[taskId]/edit.tsx =====
10
10
  // Convention: Server-side edit form page using Load.Edit from akanjs/ui.
@@ -21,15 +21,15 @@ export default async function Page({ params: { taskId } }: PageProps) {
21
21
  return (
22
22
  <main className="mx-auto max-w-2xl px-6 py-8">
23
23
  <div className="mb-6">
24
- <Link href={\`/task/\${taskId}\`} className="btn btn-ghost btn-sm">
24
+ <Link href={\`/task/\${taskId}\`} className={buttonRecipe({ variant: "ghost", size: "sm" })}>
25
25
  ← Back to Task
26
26
  </Link>
27
27
  </div>
28
28
  <div className="mb-6">
29
- <h1 className="font-extrabold text-3xl text-base-content">Edit Task</h1>
30
- <p className="mt-1 text-base-content/60 text-sm">Update the task details</p>
29
+ <h1 className="font-extrabold text-3xl text-foreground">Edit Task</h1>
30
+ <p className="mt-1 text-foreground/60 text-sm">Update the task details</p>
31
31
  </div>
32
- <div className="rounded-xl border border-base-content/10 bg-base-100 p-6 shadow-sm">
32
+ <div className="rounded-xl border border-foreground/10 bg-background p-6 shadow-sm">
33
33
  <Load.Edit slice={fetch.slice.taskInPublic} edit={taskEdit} type="form" onSubmit={\`/task/\${taskId}\`}>
34
34
  <Task.Template.General />
35
35
  </Load.Edit>
@@ -4,7 +4,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
4
4
  return {
5
5
  filename: "_index.tsx",
6
6
  content: `import { fetch, Task, usePage } from "@apps/${dict.appName}/client";
7
- import { Link } from "akanjs/ui";
7
+ import { Link, buttonRecipe } from "akanjs/ui";
8
8
 
9
9
  // ===== page/task/_index.tsx =====
10
10
  // Convention: Akan.js file-based routing — _index.tsx is the index page for /task.
@@ -18,10 +18,10 @@ export default async function Page() {
18
18
  <main className="mx-auto max-w-4xl px-6 py-8">
19
19
  <div className="mb-6 flex items-center justify-between">
20
20
  <div>
21
- <h1 className="font-extrabold text-3xl text-base-content">{l("task.modelName")}</h1>
22
- <p className="mt-1 text-base-content/60 text-sm">{l("task.modelDesc")}</p>
21
+ <h1 className="font-extrabold text-3xl text-foreground">{l("task.modelName")}</h1>
22
+ <p className="mt-1 text-foreground/60 text-sm">{l("task.modelDesc")}</p>
23
23
  </div>
24
- <Link href="/task/new" className="btn btn-primary btn-sm">
24
+ <Link href="/task/new" className={buttonRecipe({ variant: "primary", size: "sm" })}>
25
25
  {l("task.taskNew")}
26
26
  </Link>
27
27
  </div>
@@ -14,7 +14,7 @@ interface LayoutProps {
14
14
  }
15
15
  export default function Layout({ children }: LayoutProps) {
16
16
  return (
17
- <div className="min-h-screen bg-base-200">
17
+ <div className="min-h-screen bg-muted">
18
18
  {children}
19
19
  </div>
20
20
  );
@@ -4,7 +4,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
4
4
  return {
5
5
  filename: "new.tsx",
6
6
  content: `import { type cnst, fetch, Task, usePage } from "@apps/${dict.appName}/client";
7
- import { Load, Link } from "akanjs/ui";
7
+ import { Load, Link, buttonRecipe } from "akanjs/ui";
8
8
 
9
9
  // ===== page/task/new.tsx =====
10
10
  // Convention: Server-side form page using Load.Edit from akanjs/ui.
@@ -19,15 +19,15 @@ export default async function Page() {
19
19
  return (
20
20
  <main className="mx-auto max-w-2xl px-6 py-8">
21
21
  <div className="mb-6">
22
- <Link href="/task" className="btn btn-ghost btn-sm">
22
+ <Link href="/task" className={buttonRecipe({ variant: "ghost", size: "sm" })}>
23
23
  ← Tasks
24
24
  </Link>
25
25
  </div>
26
26
  <div className="mb-6">
27
- <h1 className="font-extrabold text-3xl text-base-content">New Task</h1>
28
- <p className="mt-1 text-base-content/60 text-sm">Create a new task with title and description</p>
27
+ <h1 className="font-extrabold text-3xl text-foreground">New Task</h1>
28
+ <p className="mt-1 text-foreground/60 text-sm">Create a new task with title and description</p>
29
29
  </div>
30
- <div className="rounded-xl border border-base-content/10 bg-base-100 p-6 shadow-sm">
30
+ <div className="rounded-xl border border-foreground/10 bg-background p-6 shadow-sm">
31
31
  <Load.Edit slice={fetch.slice.taskInPublic} edit={taskForm} type="form" onCancel="back" onSubmit="/task">
32
32
  <Task.Template.General />
33
33
  </Load.Edit>
@@ -5,7 +5,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
5
5
  filename: "GlobalLoading.tsx",
6
6
  content: `"use client";
7
7
 
8
- import { clsx } from "akanjs/client";
8
+ import { cn } from "akanjs/client";
9
9
 
10
10
  // ===== GlobalLoading.tsx =====
11
11
  // Convention: ui/ folder — reusable visual components. PascalCase .tsx, "use client" directive.
@@ -19,9 +19,9 @@ interface GlobalLoadingProps {
19
19
 
20
20
  export const GlobalLoading = ({ className, message = "Loading..." }: GlobalLoadingProps) => {
21
21
  return (
22
- <div className={clsx("flex flex-col items-center justify-center gap-4 py-32", className)}>
23
- <span className="loading loading-spinner loading-lg text-primary" />
24
- <span className="text-base-content/60 text-sm">{message}</span>
22
+ <div className={cn("flex flex-col items-center justify-center gap-4 py-32", className)}>
23
+ <span className="inline-block size-8 animate-spin rounded-full border-2 border-primary border-t-transparent" />
24
+ <span className="text-foreground/60 text-sm">{message}</span>
25
25
  </div>
26
26
  );
27
27
  };
@@ -5,7 +5,8 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
5
5
  filename: "QuantityControl.tsx",
6
6
  content: `"use client";
7
7
 
8
- import { clsx } from "akanjs/client";
8
+ import { cn } from "akanjs/client";
9
+ import { buttonRecipe } from "akanjs/ui";
9
10
 
10
11
  // ===== QuantityControl.tsx =====
11
12
  // Convention: ui/ folder — reusable visual components. PascalCase .tsx, "use client" directive.
@@ -28,9 +29,9 @@ export const QuantityControl = ({
28
29
  max = 99,
29
30
  }: QuantityControlProps) => {
30
31
  return (
31
- <div className={clsx("inline-flex items-center gap-1", className)}>
32
+ <div className={cn("inline-flex items-center gap-1", className)}>
32
33
  <button
33
- className="btn btn-circle btn-outline btn-xs"
34
+ className={buttonRecipe({ variant: "outline", size: "icon" }, "size-6 rounded-full")}
34
35
  disabled={value <= min}
35
36
  onClick={() => onChange(Math.max(min, value - 1))}
36
37
  >
@@ -38,7 +39,7 @@ export const QuantityControl = ({
38
39
  </button>
39
40
  <span className="w-8 text-center font-medium tabular-nums">{value}</span>
40
41
  <button
41
- className="btn btn-circle btn-outline btn-xs"
42
+ className={buttonRecipe({ variant: "outline", size: "icon" }, "size-6 rounded-full")}
42
43
  disabled={value >= max}
43
44
  onClick={() => onChange(Math.min(max, value + 1))}
44
45
  >
@@ -38,7 +38,7 @@ export default async function Page({ params }: PageProps) {
38
38
  <div className="flex gap-4 font-bold text-lg items-center">
39
39
  <${dict.Model}.Zone.View view={${dict.model}View} />
40
40
  <Link href={\`/${dict.model}/\${${dict.model}.id}/edit\`}>
41
- <button className="btn">
41
+ <button className="inline-flex items-center justify-center gap-2 rounded-field bg-primary px-4 py-2 font-medium text-primary-foreground text-sm transition-colors hover:bg-primary/90">
42
42
  {l("base.updateModel", { model: l("${dict.model}.modelName") })}
43
43
  </button>
44
44
  </Link>
@@ -23,7 +23,7 @@ export default async function Page() {
23
23
  <div className="animate-fadeIn px-4 pt-4 flex gap-4 items-center">
24
24
  <div className="font-bold text-lg md:text-4xl">${dict.Model}s</div>
25
25
  <Link href={\`/${dict.model}/new\`}>
26
- <button className="btn">+ {l("base.createModel", { model: l("${dict.model}.modelName") })}</button>
26
+ <button className="inline-flex items-center justify-center gap-2 rounded-field bg-primary px-4 py-2 font-medium text-primary-foreground text-sm transition-colors hover:bg-primary/90">+ {l("base.createModel", { model: l("${dict.model}.modelName") })}</button>
27
27
  </Link>
28
28
  </div>
29
29
  <div>{l("${dict.model}.modelDesc")}</div>
@@ -20,7 +20,7 @@ export default async function Page() {
20
20
  <>
21
21
  <div className="animate-fadeIn flex items-center gap-4 px-4 pt-4">
22
22
  <div className="text-lg font-bold md:text-4xl">{l("${dict.model}.modelName")}</div>
23
- <Model.New className="btn btn-ghost" slice={fetch.slice["${dict.model}InPublic"]} renderTitle="id">
23
+ <Model.New className="inline-flex items-center gap-2 rounded-field px-3 py-1.5 text-sm transition-colors hover:bg-muted" slice={fetch.slice["${dict.model}InPublic"]} renderTitle="id">
24
24
  <${dict.Model}.Template.General />
25
25
  </Model.New>
26
26
  </div>
@@ -4,6 +4,7 @@ interface Dict {
4
4
  Model: string;
5
5
  model: string;
6
6
  sysName: string;
7
+ sysType: string;
7
8
  }
8
9
  export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dict) {
9
10
  return {
@@ -11,7 +12,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dic
11
12
  content: `
12
13
  "use client";
13
14
  import { Field, Layout } from "akanjs/ui";
14
- import { st, usePage } from "@${scanInfo?.type ?? "apps"}/${dict.sysName}/client";
15
+ import { st, usePage } from "@${dict.sysType}s/${dict.sysName}/client";
15
16
 
16
17
  interface GeneralProps {
17
18
  className?: string;
@@ -4,13 +4,14 @@ interface Dict {
4
4
  Model: string;
5
5
  model: string;
6
6
  sysName: string;
7
+ sysType: string;
7
8
  }
8
9
  export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dict) {
9
10
  return {
10
11
  filename: `${dict.Model}.Unit.tsx`,
11
12
  content: `
12
13
  import type { ModelProps } from "akanjs/client";
13
- import { cnst, usePage } from "@${scanInfo?.type ?? "apps"}/${dict.sysName}/client";
14
+ import { cnst, usePage } from "@${dict.sysType}s/${dict.sysName}/client";
14
15
  import { Link } from "akanjs/ui";
15
16
 
16
17
  export const Card = ({ ${dict.model}, href }: ModelProps<"${dict.model}", cnst.Light${dict.Model}>) => {
@@ -4,6 +4,7 @@ interface Dict {
4
4
  Model: string;
5
5
  model: string;
6
6
  sysName: string;
7
+ sysType: string;
7
8
  }
8
9
  export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dict) {
9
10
  return {
@@ -11,7 +12,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dic
11
12
  content: `
12
13
  "use client";
13
14
  import { Model } from "akanjs/ui";
14
- import { fetch, usePage } from "@${scanInfo?.type ?? "apps"}/${dict.sysName}/client";
15
+ import { fetch, usePage } from "@${dict.sysType}s/${dict.sysName}/client";
15
16
  import { BiTrash } from "react-icons/bi";
16
17
 
17
18
  interface RemoveProps {
@@ -4,13 +4,14 @@ interface Dict {
4
4
  Model: string;
5
5
  model: string;
6
6
  sysName: string;
7
+ sysType: string;
7
8
  }
8
9
  export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dict) {
9
10
  return {
10
11
  filename: `${dict.Model}.View.tsx`,
11
12
  content: `
12
- import { clsx } from "akanjs/client";
13
- import { cnst, usePage } from "@${scanInfo?.type ?? "apps"}/${dict.sysName}/client";
13
+ import { cn } from "akanjs/client";
14
+ import { cnst, usePage } from "@${dict.sysType}s/${dict.sysName}/client";
14
15
 
15
16
  interface GeneralProps {
16
17
  className?: string;
@@ -19,7 +20,7 @@ interface GeneralProps {
19
20
  export const General = ({ className, ${dict.model} }: GeneralProps) => {
20
21
  const { l } = usePage();
21
22
  return (
22
- <div className={clsx("w-full", className)}>
23
+ <div className={cn("w-full", className)}>
23
24
  <div>{l("${dict.model}.name")}: {${dict.model}.name}</div>
24
25
  </div>
25
26
  );
@@ -4,6 +4,7 @@ interface Dict {
4
4
  Model: string;
5
5
  model: string;
6
6
  sysName: string;
7
+ sysType: string;
7
8
  }
8
9
  export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dict) {
9
10
  return {
@@ -13,7 +14,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dic
13
14
  import { Load } from "akanjs/ui";
14
15
  // Alias the domain namespace so the Card/View exports below never collide with the model name
15
16
  // (a model literally named "card" or "view" would otherwise shadow this import).
16
- import { type cnst, ${dict.Model} as ${dict.Model}Domain } from "@${scanInfo?.type ?? "apps"}/${dict.sysName}/client";
17
+ import { type cnst, ${dict.Model} as ${dict.Model}Domain } from "@${dict.sysType}s/${dict.sysName}/client";
17
18
  import type { ClientInit, ClientView, SliceMeta } from "akanjs/fetch";
18
19
 
19
20
  interface CardProps {
@@ -239,7 +239,7 @@ final fallback when no CLI command covers the change.
239
239
  | Add a pure workflow / integration (e.g., Payment, Email) | `lib/_<service>/` → service, signal, store, dictionary, abstract | `akan sync <name>` |
240
240
  | Add a reusable value type (e.g., Address, WorkHistory) | `lib/__scalar/<type>/` → constant, dictionary, abstract | `akan sync <name>` |
241
241
  | Create a new URL-visitable page | `page/` → `_index.tsx`, `_layout.tsx`, `[param]/_index.tsx` | Rebuild (akan start auto-detects) |
242
- | Change the app color theme / design tokens | `apps/<app>/page/styles.css` → edit the daisyUI `@plugin "daisyui/theme"` blocks (`light`/`dark`, the `--color-*` variables) | akan start hot-reloads |
242
+ | Change the app color theme / design tokens | `apps/<app>/page/styles.css` → override the semantic token values under `:root, [data-theme="dark"]` and `[data-theme="light"]` (`--primary`, `--background`, `--foreground`, ) | akan start hot-reloads |
243
243
  | Add a form or reusable UI component | `ui/` → PascalCase `.tsx` with `"use client"` if needed | `akan sync <name>` |
244
244
  | Add a React hook or browser helper | `webkit/` → camelCase `.ts` with `"use client"` | `akan sync <name>` |
245
245
  | Add a server-only guard, middleware, or adaptor | `srvkit/` → PascalCase `.ts` | `akan sync <name>` |
@@ -439,11 +439,9 @@ const form = st.use.taskForm();
439
439
 
440
440
  // 4. apps/<app>/lib/<model>/<Model>.Unit.tsx
441
441
  // Display the new field in card/list views
442
- <span className={clsx("badge badge-sm", {
443
- "badge-error": task.priority === "high",
444
- "badge-warning": task.priority === "medium",
445
- "badge-ghost": task.priority === "low",
446
- })}>{task.priority}</span>
442
+ <Badge variant={task.priority === "high" ? "error" : task.priority === "medium" ? "warning" : "default"}>
443
+ {task.priority}
444
+ </Badge>
447
445
 
448
446
  // 5. Regenerate barrels
449
447
  // akan sync <name>
@@ -632,7 +630,7 @@ async startTask(taskId: string) {
632
630
 
633
631
  // 6. <Model>.Util.tsx — Reusable button component
634
632
  export const Start = ({ taskId }: { taskId: string }) => (
635
- <button className="btn btn-xs btn-primary" onClick={() => st.do.startTask(taskId)}>
633
+ <button className={buttonRecipe({ variant: "primary", size: "xs" })} onClick={() => st.do.startTask(taskId)}>
636
634
  Start
637
635
  </button>
638
636
  );
@@ -694,13 +692,13 @@ export class TaskInsight extends via(Task, (field) => ({
694
692
  // 3. <Model>.View.tsx — Display component consuming an Insight model
695
693
  export const Stats = ({ taskInsight }: { taskInsight: cnst.TaskInsight }) => (
696
694
  <div className="grid grid-cols-2 gap-4">
697
- <div className="stat rounded-lg border border-base-content/10 bg-base-100 p-4">
698
- <div className="stat-title text-base-content/60">{l("task.totalCount")}</div>
699
- <div className="stat-value text-primary">{taskInsight.totalCount}</div>
695
+ <div className="rounded-lg border border-border bg-card p-4">
696
+ <div className="text-muted-foreground text-sm">{l("task.totalCount")}</div>
697
+ <div className="font-bold text-2xl text-primary">{taskInsight.totalCount}</div>
700
698
  </div>
701
- <div className="stat rounded-lg border border-base-content/10 bg-base-100 p-4">
702
- <div className="stat-title text-base-content/60">{l("task.completedCount")}</div>
703
- <div className="stat-value text-success">{taskInsight.completedCount}</div>
699
+ <div className="rounded-lg border border-border bg-card p-4">
700
+ <div className="text-muted-foreground text-sm">{l("task.completedCount")}</div>
701
+ <div className="font-bold text-2xl text-success">{taskInsight.completedCount}</div>
704
702
  </div>
705
703
  </div>
706
704
  );
@@ -93,7 +93,7 @@
93
93
  "fix": "safe",
94
94
  "options": {
95
95
  "attributes": ["classList"],
96
- "functions": ["clsx", "cva"]
96
+ "functions": ["clsx", "cn"]
97
97
  }
98
98
  }
99
99
  },
@@ -1,32 +1,33 @@
1
1
  // @bun
2
2
  import {
3
3
  WorkflowRunner
4
- } from "./index-h971erkm.js";
5
- import {
6
- ScalarScript
7
- } from "./index-z5v766nx.js";
4
+ } from "./index-csqk9z5j.js";
8
5
  import {
9
6
  PrimitiveScript
10
- } from "./index-acwxfncv.js";
7
+ } from "./index-r4w8cry5.js";
11
8
  import {
12
9
  ModuleScript
13
- } from "./index-04as43rp.js";
14
- import"./index-dgeaqwmw.js";
10
+ } from "./index-vhv3xnjz.js";
11
+ import"./index-hjzr8ja1.js";
12
+ import {
13
+ ScalarScript
14
+ } from "./index-fmgbwsr5.js";
15
15
  import"./index-ss469dec.js";
16
- import"./index-v9jqrdd1.js";
16
+ import"./index-3pgtw35d.js";
17
+ import"./index-4yp06pn1.js";
17
18
  import {
18
19
  createWorkflowStepRegistry
19
- } from "./index-pfnh87f9.js";
20
- import"./index-xftstr5s.js";
21
- import"./index-nsj2ftxj.js";
20
+ } from "./index-4zgs8g1w.js";
21
+ import"./index-xwgm94zr.js";
22
22
  import {
23
23
  Workspace,
24
24
  command,
25
25
  script
26
- } from "./index-d0h48d2f.js";
27
- import"./index-xwfg9bam.js";
28
- import"./index-67546d0j.js";
26
+ } from "./index-jk9q6pse.js";
27
+ import"./index-jtm86byd.js";
29
28
  import"./index-6pz1j0zj.js";
29
+ import"./index-xys926f2.js";
30
+ import"./index-67546d0j.js";
30
31
  import"./index-r24hmh0q.js";
31
32
 
32
33
  // pkgs/@akanjs/cli/workflow/workflow.script.ts