@akanjs/cli 3.0.0-alpha.4 → 3.0.0-alpha.40

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 (108) hide show
  1. package/.build-stamp +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +1 -1
  4. package/{abstractCompactor-rk6twzvj.js → abstractCompactor-20e0cwbs.js} +3 -3
  5. package/{agent.command-jfz8yfwy.js → agent.command-e835fjem.js} +9 -8
  6. package/{application.command-mxyqtd6p.js → application.command-sjtbk6tr.js} +7 -6
  7. package/{applicationBuildRunner-cwk52sb7.js → applicationBuildRunner-7gnfz7ww.js} +7 -8
  8. package/{applicationReleasePackager-yrrhbkv3.js → applicationReleasePackager-93nzdfsy.js} +2 -2
  9. package/buildBatch.proc.js +6 -5
  10. package/{capacitorApp-j357ak1g.js → capacitorApp-qv7g3dp2.js} +29 -28
  11. package/{cloud.command-f87dwe52.js → cloud.command-y0e4eyqz.js} +11 -10
  12. package/{context.command-z5bf8bn7.js → context.command-vn87jb08.js} +17 -16
  13. package/{dependencyScanner-f6grrep3.js → dependencyScanner-rbs2407b.js} +1 -1
  14. package/getDirname-ka11hm7e.js +8 -0
  15. package/{guideline.command-1m1ctar3.js → guideline.command-s4hn2bsy.js} +7 -6
  16. package/guidelines/conventions/conventions.generate.json +25 -0
  17. package/guidelines/conventions/conventions.instruction.md +1173 -0
  18. package/guidelines/cssRule/cssRule.instruction.md +7 -0
  19. package/guidelines/framework/framework.instruction.md +1 -0
  20. package/guidelines/ssrRule/ssrRule.generate.json +31 -0
  21. package/guidelines/ssrRule/ssrRule.instruction.md +108 -0
  22. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
  23. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +972 -0
  24. package/incrementalBuilder.proc.js +7 -6
  25. package/{index-1s71fwrq.js → index-0h212yqe.js} +13 -13
  26. package/index-1577bej2.js +7 -0
  27. package/{index-e3qskyt2.js → index-33zce8gt.js} +8 -4
  28. package/{index-csqk9z5j.js → index-3dp7x6rc.js} +3 -3
  29. package/{index-cn24dcqn.js → index-73rnbwgg.js} +15 -7
  30. package/{index-tq1y56tp.js → index-8d2sv6pw.js} +39 -16
  31. package/{index-jtm86byd.js → index-8vkkm7v0.js} +125 -66
  32. package/{index-r4w8cry5.js → index-9jsnb4vw.js} +4 -4
  33. package/{index-ybybkec0.js → index-becx1t0k.js} +6 -6
  34. package/{index-4yp06pn1.js → index-g9e2fhw2.js} +49 -32
  35. package/{index-cap2k2ch.js → index-hg0qvhmx.js} +152 -241
  36. package/{index-xwgm94zr.js → index-j37qq1f2.js} +1 -1
  37. package/{index-n0z3f2xg.js → index-k6fvbcj1.js} +37 -6
  38. package/{index-6pz1j0zj.js → index-mxvakhsm.js} +6 -2
  39. package/{index-vhv3xnjz.js → index-mykmf6wd.js} +8 -8
  40. package/{index-y0k42k04.js → index-mz5jtaq7.js} +1 -1
  41. package/{index-jk9q6pse.js → index-n706txcv.js} +5 -3
  42. package/{index-hjzr8ja1.js → index-qc0tnhs2.js} +1 -1
  43. package/{index-rh16j3c7.js → index-qnv0aqmm.js} +12 -8
  44. package/{index-3pgtw35d.js → index-sh01r3pm.js} +2 -2
  45. package/{index-xj8bks3p.js → index-t71zvmt9.js} +9 -11
  46. package/{index-4zgs8g1w.js → index-tsmjxph2.js} +1 -1
  47. package/{index-fmgbwsr5.js → index-x33gnap3.js} +4 -4
  48. package/{index-b978vs2e.js → index-xyrb7pk5.js} +3 -3
  49. package/index.js +21 -20
  50. package/{library.command-pwfx8dx2.js → library.command-v5cyaw9t.js} +6 -5
  51. package/{localRegistry.command-r4zjx5py.js → localRegistry.command-53t758pt.js} +10 -9
  52. package/{module.command-0t3ewata.js → module.command-pq6w84xg.js} +10 -9
  53. package/{package.command-7hmkxvpa.js → package.command-qkcs60ts.js} +6 -5
  54. package/package.json +3 -4
  55. package/{page.command-st6r4s0q.js → page.command-qj5bfnh9.js} +6 -5
  56. package/{primitive.command-1qkxpzsn.js → primitive.command-bw0nes6x.js} +11 -10
  57. package/{quality.command-hy5vt1bh.js → quality.command-g1s2wt8b.js} +532 -87
  58. package/{recipeScanner-tghkzrrt.js → recipeScanner-zrzev25x.js} +3 -3
  59. package/{repair.command-nakkq2zp.js → repair.command-mzwtejpk.js} +8 -7
  60. package/{routeSourceValidator-cncd92fv.js → routeSourceValidator-7fycdqyv.js} +3 -39
  61. package/{scalar.command-fjq272gs.js → scalar.command-rm6k3c65.js} +9 -8
  62. package/templates/app/env/env.server.debug.ts.template +1 -5
  63. package/templates/app/env/env.server.develop.ts.template +1 -5
  64. package/templates/app/env/env.server.local.ts.template +1 -5
  65. package/templates/app/env/env.server.main.ts.template +1 -5
  66. package/templates/app/page/styles.css.template +3 -3
  67. package/templates/appSample/srvkit/AuthGuard.ts +9 -5
  68. package/templates/appSample/srvkit/SessionInternalArg.ts +4 -3
  69. package/templates/crudPages/[__model__Id]/edit/page.tsx +1 -1
  70. package/templates/crudPages/new/page.tsx +1 -1
  71. package/templates/crudSinglePage/page.tsx +1 -1
  72. package/templates/env/_env.server.type.ts +7 -5
  73. package/templates/lib/db.ts +4 -2
  74. package/templates/lib/dict.ts +1 -1
  75. package/templates/lib/sig.ts +1 -1
  76. package/templates/lib/srv.ts +6 -2
  77. package/templates/lib/useClient.ts +9 -3
  78. package/templates/module/__Model__.Util.tsx +1 -1
  79. package/templates/module/__Model__.Zone.tsx +3 -5
  80. package/templates/workspaceRoot/AGENTS.md.template +0 -831
  81. package/templates/workspaceRoot/CLAUDE.md.template +19 -0
  82. package/templates/workspaceRoot/biome.json.template +4 -217
  83. package/{typeChecker-kravn7ns.js → typeChecker-g6bh0xfv.js} +1 -1
  84. package/typecheck.proc.js +1 -1
  85. package/{workflow.command-jswbgk90.js → workflow.command-g2cgcgxn.js} +16 -15
  86. package/{workspace.command-h9wwcjpt.js → workspace.command-f7jerqb2.js} +70 -52
  87. package/templates/libRoot/base/baseLogic.ts +0 -14
  88. package/templates/libRoot/base/index.ts +0 -8
  89. package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
  90. package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -33
  91. package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
  92. package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
  93. package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -17
  94. package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
  95. package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
  96. package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
  97. package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
  98. package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -18
  99. package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -61
  100. package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
  101. package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
  102. package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
  103. package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -58
  104. package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
  105. package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
  106. package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
  107. package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
  108. /package/{index-r24hmh0q.js → index-yb2wsc7f.js} +0 -0
@@ -4,9 +4,9 @@ import {
4
4
  findInlineRecipeDuplicates,
5
5
  scanRecipes
6
6
  } from "./index-xys926f2.js";
7
- import"./index-r24hmh0q.js";
7
+ import"./index-yb2wsc7f.js";
8
8
  export {
9
- scanRecipes,
9
+ collectRecipeSources,
10
10
  findInlineRecipeDuplicates,
11
- collectRecipeSources
11
+ scanRecipes
12
12
  };
@@ -1,19 +1,20 @@
1
1
  // @bun
2
2
  import {
3
3
  RepairRunner
4
- } from "./index-b978vs2e.js";
5
- import"./index-4yp06pn1.js";
6
- import"./index-4zgs8g1w.js";
4
+ } from "./index-xyrb7pk5.js";
5
+ import"./index-g9e2fhw2.js";
6
+ import"./index-tsmjxph2.js";
7
7
  import {
8
8
  Workspace,
9
9
  command,
10
10
  script
11
- } from "./index-jk9q6pse.js";
12
- import"./index-jtm86byd.js";
13
- import"./index-6pz1j0zj.js";
11
+ } from "./index-n706txcv.js";
12
+ import"./index-8vkkm7v0.js";
13
+ import"./index-mxvakhsm.js";
14
14
  import"./index-xys926f2.js";
15
+ import"./index-1577bej2.js";
15
16
  import"./index-67546d0j.js";
16
- import"./index-r24hmh0q.js";
17
+ import"./index-yb2wsc7f.js";
17
18
 
18
19
  // pkgs/@akanjs/cli/repair/repair.script.ts
19
20
  import { Logger } from "akanjs/common";
@@ -1,50 +1,14 @@
1
1
  // @bun
2
- import"./index-r24hmh0q.js";
2
+ import"./index-yb2wsc7f.js";
3
3
 
4
4
  // pkgs/@akanjs/devkit/routeSourceValidator.ts
5
+ import { getRouteExports } from "akanjs/common";
5
6
  import ts from "typescript";
6
7
 
7
8
  class RouteSourceValidator {
8
- static #pageExports = new Set([
9
- "default",
10
- "pageConfig",
11
- "head",
12
- "metadata",
13
- "generateHead",
14
- "generateMetadata",
15
- "Loading"
16
- ]);
17
- static #rootLayoutExports = new Set([
18
- "default",
19
- "pageConfig",
20
- "head",
21
- "metadata",
22
- "generateHead",
23
- "generateMetadata",
24
- "fonts",
25
- "manifest",
26
- "theme",
27
- "reconnect",
28
- "layoutStyle",
29
- "gaTrackingId",
30
- "Loading",
31
- "NotFound",
32
- "Error"
33
- ]);
34
- static #layoutExports = new Set([
35
- "default",
36
- "pageConfig",
37
- "head",
38
- "metadata",
39
- "generateHead",
40
- "generateMetadata",
41
- "Loading",
42
- "NotFound",
43
- "Error"
44
- ]);
45
9
  static validateRouteSourceExports(source, filePath, kind, options = {}) {
46
10
  const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
47
- const allowed = kind === "page" ? RouteSourceValidator.#pageExports : options.rootLayout ? RouteSourceValidator.#rootLayoutExports : RouteSourceValidator.#layoutExports;
11
+ const allowed = getRouteExports(kind, { rootLayout: options.rootLayout });
48
12
  const exported = new Set;
49
13
  const assertExport = (name) => {
50
14
  if (!allowed.has(name)) {
@@ -1,21 +1,22 @@
1
1
  // @bun
2
2
  import {
3
3
  ScalarScript
4
- } from "./index-fmgbwsr5.js";
4
+ } from "./index-x33gnap3.js";
5
5
  import"./index-ss469dec.js";
6
- import"./index-3pgtw35d.js";
6
+ import"./index-sh01r3pm.js";
7
7
  import {
8
8
  renderPrimitiveReport
9
- } from "./index-4zgs8g1w.js";
10
- import"./index-xwgm94zr.js";
9
+ } from "./index-tsmjxph2.js";
10
+ import"./index-j37qq1f2.js";
11
11
  import {
12
12
  Sys,
13
13
  command
14
- } from "./index-jk9q6pse.js";
15
- import"./index-jtm86byd.js";
16
- import"./index-6pz1j0zj.js";
14
+ } from "./index-n706txcv.js";
15
+ import"./index-8vkkm7v0.js";
16
+ import"./index-mxvakhsm.js";
17
+ import"./index-1577bej2.js";
17
18
  import"./index-67546d0j.js";
18
- import"./index-r24hmh0q.js";
19
+ import"./index-yb2wsc7f.js";
19
20
 
20
21
  // pkgs/@akanjs/cli/scalar/scalar.command.ts
21
22
  import { Logger, lowerlize } from "akanjs/common";
@@ -1,7 +1,3 @@
1
- import { getEnv } from "akanjs/base";
2
-
3
1
  import type { ModulesOptions } from "../lib/option";
4
2
 
5
- export const env: ModulesOptions = {
6
- ...getEnv(),
7
- };
3
+ export const env: ModulesOptions = {};
@@ -1,7 +1,3 @@
1
- import { getEnv } from "akanjs/base";
2
-
3
1
  import type { ModulesOptions } from "../lib/option";
4
2
 
5
- export const env: ModulesOptions = {
6
- ...getEnv(),
7
- };
3
+ export const env: ModulesOptions = {};
@@ -1,7 +1,3 @@
1
- import { getEnv } from "akanjs/base";
2
-
3
1
  import type { ModulesOptions } from "../lib/option";
4
2
 
5
- export const env: ModulesOptions = {
6
- ...getEnv(),
7
- };
3
+ export const env: ModulesOptions = {};
@@ -1,7 +1,3 @@
1
- import { getEnv } from "akanjs/base";
2
-
3
1
  import type { ModulesOptions } from "../lib/option";
4
2
 
5
- export const env: ModulesOptions = {
6
- ...getEnv(),
7
- };
3
+ export const env: ModulesOptions = {};
@@ -1,10 +1,10 @@
1
1
  @import "tailwindcss";
2
2
  @import "akanjs/ui/styles.css";
3
3
 
4
- /* 테마 시스템(브랜드-중립 기본 팔레트 · @theme inline 매핑 · dark 변형 · 런타임 data-theme 전환)은
5
- akanjs/ui/styles.css(프레임워크)가 전부 제공한다. 앱은 import 만으로 즉시 동작한다.
4
+ /* The theme system (brand-neutral default palette, @theme inline mapping, dark variant, and runtime
5
+ data-theme switching) is fully provided by akanjs/ui/styles.css. This app works from the import alone.
6
6
 
7
- 앱만의 브랜드 색을 쓰려면 아래처럼 토큰만 override 하면 된다:
7
+ To use this app's own brand colors, override the tokens like this:
8
8
 
9
9
  :root,
10
10
  [data-theme="dark"] {
@@ -3,7 +3,7 @@ import type { AppInfo, LibInfo } from "akanjs";
3
3
  export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { appName: string }) {
4
4
  return {
5
5
  filename: "AuthGuard.ts",
6
- content: `import type { Guard, SignalContext } from "akanjs/signal";
6
+ content: `import type { Guard, GuardScope, SignalContext } from "akanjs/signal";
7
7
 
8
8
  // ===== AuthGuard.ts =====
9
9
  // Convention: srvkit/ folder — server-only helpers, cannot import from client code.
@@ -14,10 +14,14 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
14
14
 
15
15
  export class SignedIn implements Guard {
16
16
  static name = "SignedIn";
17
+ // "account" — the verdict reads the caller and nothing about the call, so an MCP catalogue can evaluate it with
18
+ // no arguments and hide what this caller certainly cannot use. Required: "resource" is never evaluated for a
19
+ // listing, so a guard like this one marked that way would filter nothing.
20
+ static scope: GuardScope = "account";
17
21
 
18
22
  canPass(context: SignalContext): boolean {
19
- const user = context.getHttpContext<{ user?: { id: string } }>().req.user;
20
- return !!user;
23
+ // Reads the account the middleware resolved, so the same guard answers over HTTP, a websocket and MCP alike.
24
+ return !!context.get<{ id?: string }>("account");
21
25
  }
22
26
  }
23
27
 
@@ -25,9 +29,9 @@ export class SignedIn implements Guard {
25
29
  // Role-based guard: only allow users with a specific role
26
30
  // export class IsAdmin implements Guard {
27
31
  // static name = "IsAdmin";
32
+ // static scope: GuardScope = "account";
28
33
  // canPass(context: SignalContext): boolean {
29
- // const user = context.getHttpContext<{ user?: { role: string } }>().req.user;
30
- // return user?.role === "admin";
34
+ // return context.get<{ role?: string }>("account")?.role === "admin";
31
35
  // }
32
36
  // }
33
37
  `,
@@ -15,8 +15,9 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { a
15
15
 
16
16
  export class CurrentUserId implements InternalArg<string | null> {
17
17
  getArg(context: SignalContext): string | null {
18
- const user = context.getHttpContext<{ user?: { id: string } }>().req.user;
19
- return user?.id ?? null;
18
+ // \`context.get\` reads what the account middleware resolved, on every transport. Branching on
19
+ // \`getHttpContext()\` would return null for the same caller arriving over a websocket or MCP.
20
+ return context.get<{ id?: string }>("account")?.id ?? null;
20
21
  }
21
22
  }
22
23
 
@@ -24,7 +25,7 @@ export class CurrentUserId implements InternalArg<string | null> {
24
25
  // Inject current session language/locale
25
26
  // export class CurrentLocale implements InternalArg<string> {
26
27
  // getArg(context: SignalContext): string {
27
- // return context.getHttpContext<{ locale?: string }>().req.locale ?? "en";
28
+ // return context.get<string>("locale") ?? "en";
28
29
  // }
29
30
  // }
30
31
  `,
@@ -30,7 +30,7 @@ export default async function Page({ params }: PageProps) {
30
30
  </div>
31
31
  <Load.Edit
32
32
  className="flex flex-col items-center"
33
- slice={fetch.slice["${dict.model}InPublic"]}
33
+ slice={fetch.slice.${dict.model}InPublic}
34
34
  edit={${dict.model}Edit}
35
35
  type="form"
36
36
  onCancel="back"
@@ -25,7 +25,7 @@ export default function Page() {
25
25
  </div>
26
26
  <Load.Edit
27
27
  className="flex flex-col items-center"
28
- slice={fetch.slice["${dict.model}InPublic"]}
28
+ slice={fetch.slice.${dict.model}InPublic}
29
29
  edit={${dict.model}Form}
30
30
  type="form"
31
31
  onCancel="back"
@@ -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="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">
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>
@@ -5,12 +5,14 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { [
5
5
  const libs = scanInfo.getLibs();
6
6
  return {
7
7
  filename: "env.server.type.ts",
8
- content: `
9
- ${libs.length ? libs.map((lib) => `import { env as ${lib}Option } from "@libs/${lib}/server";`).join("\n") : 'import { getEnv } from "akanjs/base";'}
8
+ content: libs.length
9
+ ? `
10
+ ${libs.map((lib) => `import { env as ${lib}Option } from "@libs/${lib}/server";`).join("\n")}
10
11
 
11
12
  export const libEnv = {
12
- ${libs.length ? libs.map((lib) => ` ...${lib}Option,`).join("\n") : " ...getEnv(),"}
13
- };
14
- `,
13
+ ${libs.map((lib) => ` ...${lib}Option,`).join("\n")}
14
+ };`
15
+ : `
16
+ export const libEnv = {};`,
15
17
  };
16
18
  }
@@ -13,10 +13,12 @@ ${scalarModules.map((module) => `import { ${capitalize(module)} } from "./__scal
13
13
  ${databaseModules.length ? `import * as cnst from "./cnst";` : ""}
14
14
  ${databaseModules.map((module) => `import * as ${module}Db from "./${module}/${module}.document";`).join("\n")}
15
15
 
16
- ${libs.map((lib) => `export { db as ${lib} } from "@libs/${lib}/server";`).join("\n")}
16
+ ${libs.map((lib) => `export * as ${lib} from "@libs/${lib}/lib/db";`).join("\n")}
17
17
 
18
18
  ${databaseModules.map((module) => `class ${capitalize(module)}Input extends by(cnst.${capitalize(module)}Input) {}`).join("\n")}
19
+ ${databaseModules.map((module) => `class ${capitalize(module)}Insight extends by(cnst.${capitalize(module)}Insight) {}`).join("\n")}
19
20
  ${databaseModules.length ? `export type { ${databaseModules.map((module) => `${capitalize(module)}Input`).join(", ")} };` : ""}
21
+ ${databaseModules.length ? `export type { ${databaseModules.map((module) => `${capitalize(module)}Insight`).join(", ")} };` : ""}
20
22
 
21
23
  ${scalarModules.map((module) => `export type * from "./__scalar/${module}/${module}.document";`).join("\n")}
22
24
  ${databaseModules.map((module) => `export type * from "./${module}/${module}.document";`).join("\n")}
@@ -24,7 +26,7 @@ ${databaseModules.map((module) => `export type * from "./${module}/${module}.doc
24
26
  ${databaseModules
25
27
  .map((module) => {
26
28
  const names = { Module: module.charAt(0).toUpperCase() + module.slice(1) };
27
- return `export const ${module} = DatabaseRegistry.buildModel("${module}" as const, ${names.Module}Input, ${module}Db.${names.Module}, ${module}Db.${names.Module}Model, cnst.${names.Module}, cnst.${names.Module}Insight, ${module}Db.${names.Module}Filter);`;
29
+ return `export const ${module} = DatabaseRegistry.buildModel("${module}" as const, ${names.Module}Input, ${module}Db.${names.Module}, ${module}Db.${names.Module}Model, cnst.${names.Module}, ${names.Module}Insight, ${module}Db.${names.Module}Filter);`;
28
30
  })
29
31
  .join("\n")}
30
32
  ${scalarModules.map((module) => `export const ${module} = DatabaseRegistry.buildScalar("${module}" as const, ${capitalize(module)});`).join("\n")}
@@ -9,7 +9,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { [
9
9
  const libs = scanInfo.getLibs();
10
10
  return `
11
11
  import { makeDictionary, makeTrans, registerScalarTrans, registerServiceTrans, registerModelTrans${libs.length === 0 ? `, dictionary as base` : ""} } from "akanjs/dictionary";
12
- ${libs.length ? libs.map((lib) => `import { dictionary as ${lib} } from "@libs/${lib}/server";`).join("\n") : ""}
12
+ ${libs.length ? libs.map((lib) => `import { dictionary as ${lib} } from "@libs/${lib}/lib/dict";`).join("\n") : ""}
13
13
 
14
14
  ${databaseModules.map((module) => `import * as ${module} from "./${module}/${module}.dictionary";`).join("\n")}
15
15
  ${serviceModules.map((module) => `import * as ${module} from "./_${module}/${module}.dictionary";`).join("\n")}
@@ -17,7 +17,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { [
17
17
  return `
18
18
  import { FetchClient, type FetchClientType } from "akanjs/fetch";
19
19
  import { SignalRegistry, serverSignal${libs.length === 0 ? ", fetch as base" : ""} } from "akanjs/signal";
20
- ${libs.map((lib) => `import { fetch as ${lib} } from "@libs/${lib}/server";`).join("\n")}
20
+ ${libs.map((lib) => `import { fetch as ${lib} } from "@libs/${lib}/lib/sig";`).join("\n")}
21
21
 
22
22
  ${[...scanInfo.database.entries()]
23
23
  .filter(([_, files]) => files.has("signal"))
@@ -13,7 +13,11 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { [
13
13
  const libs = scanInfo.getLibs();
14
14
  return `
15
15
  import { ServiceModel } from "akanjs/service";
16
- ${libs.length ? libs.map((lib) => `import { option as ${lib} } from "@libs/${lib}/server";`).join("\n") : 'import type { BackendEnv } from "akanjs/base";'}
16
+ ${
17
+ libs.length
18
+ ? libs.map((lib) => `import * as ${lib} from "@libs/${lib}/lib/option";`).join("\n")
19
+ : 'import type { BackendEnv } from "akanjs/base";'
20
+ }
17
21
 
18
22
  import * as cnst from "./cnst";
19
23
  import * as db from "./db";
@@ -21,7 +25,7 @@ import * as db from "./db";
21
25
  ${databaseModules.map((module) => `import { ${capitalize(module)}Service } from "./${module}/${module}.service";`).join("\n")}
22
26
  ${serviceModules.map((module) => `import { ${capitalize(module)}Service } from "./_${module}/${module}.service";`).join("\n")}
23
27
 
24
- ${libs.map((lib) => `export { srv as ${lib} } from "@libs/${lib}/server";`).join("\n")}
28
+ ${libs.map((lib) => `export * as ${lib} from "@libs/${lib}/lib/srv";`).join("\n")}
25
29
 
26
30
  ${databaseModules.map((module) => `export { ${capitalize(module)}Service } from "./${module}/${module}.service";`).join("\n")}
27
31
  ${serviceModules.map((module) => `export { ${capitalize(module)}Service } from "./_${module}/${module}.service";`).join("\n")}
@@ -1,16 +1,22 @@
1
1
  import type { AppInfo, LibInfo } from "akanjs";
2
2
 
3
3
  export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: { [key: string]: string } = {}) {
4
+ const isApp = (scanInfo?.type ?? "lib") === "app";
4
5
  return `
5
6
  import { makePageProto, registerClientRuntime } from "akanjs/client";
6
7
  import { FetchClient } from "akanjs/fetch";
7
8
  import * as cnst from "./cnst";
8
- import { getAllDictionary } from "./dict" with { type: "macro" };
9
- import type * as dict from "./dict";
9
+ ${isApp ? `import { getAllDictionary } from "./dict" with { type: "macro" };\n` : ""}import type * as dict from "./dict";
10
10
  import { getSerializedSignal } from "./sig" with { type: "macro" };
11
11
  import type * as signal from "./sig";
12
12
 
13
- const dictionary = process.env.AKAN_PUBLIC_RENDER_ENV === "csr" ? getAllDictionary() : {};
13
+ ${
14
+ isApp
15
+ ? `const dictionary = process.env.AKAN_PUBLIC_RENDER_ENV === "csr" ? getAllDictionary() : {};`
16
+ : `// dict.ts is cumulative, so a lib dictionary is a subset of the mounting app's. Translator state is global,
17
+ // so the app's seed already resolves l() here — seeding again would ship the same payload a second time.
18
+ const dictionary = {};`
19
+ }
14
20
  const pageProto = makePageProto<typeof dict>(dictionary);
15
21
  const fetchProto = FetchClient.build<typeof signal>(cnst, getSerializedSignal(), { Err: pageProto.Err });
16
22
  export const runtime = registerClientRuntime({ ...pageProto, ...fetchProto }, { scope: ${JSON.stringify(scanInfo?.type ?? "lib")} });
@@ -21,7 +21,7 @@ interface RemoveProps {
21
21
  export const Remove = ({ ${dict.model}Id }: RemoveProps) => {
22
22
  const { l } = usePage();
23
23
  return (
24
- <Model.Remove modelId={${dict.model}Id} slice={fetch.slice["${dict.model}"]}>
24
+ <Model.Remove modelId={${dict.model}Id} slice={fetch.slice.${dict.model}}>
25
25
  <BiTrash /> {l("base.remove")}
26
26
  </Model.Remove>
27
27
  );
@@ -12,9 +12,7 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dic
12
12
  content: `
13
13
  "use client";
14
14
  import { Load } from "akanjs/ui";
15
- // Alias the domain namespace so the Card/View exports below never collide with the model name
16
- // (a model literally named "card" or "view" would otherwise shadow this import).
17
- import { type cnst, ${dict.Model} as ${dict.Model}Domain } from "@${dict.sysType}s/${dict.sysName}/client";
15
+ import { type cnst, ${dict.Model} as ${dict.Model} } from "@${dict.sysType}s/${dict.sysName}/client";
18
16
  import type { ClientInit, ClientView, SliceMeta } from "akanjs/fetch";
19
17
 
20
18
  interface CardProps {
@@ -28,7 +26,7 @@ export const Card = ({ className, init, slice }: CardProps) => {
28
26
  className={className}
29
27
  init={init}
30
28
  renderItem={(${dict.model}) => (
31
- <${dict.Model}Domain.Unit.Card key={${dict.model}.id} href={\`/${dict.model}/\${${dict.model}.id}\`} ${dict.model}={${dict.model}} />
29
+ <${dict.Model}.Unit.Card key={${dict.model}.id} href={\`/${dict.model}/\${${dict.model}.id}\`} ${dict.model}={${dict.model}} />
32
30
  )}
33
31
  />
34
32
  );
@@ -39,7 +37,7 @@ interface ViewProps {
39
37
  view: ClientView<"${dict.model}", cnst.${dict.Model}>;
40
38
  }
41
39
  export const View = ({ view }: ViewProps) => {
42
- return <Load.View view={view} renderView={(${dict.model}) => <${dict.Model}Domain.View.General ${dict.model}={${dict.model}} />} />;
40
+ return <Load.View view={view} renderView={(${dict.model}) => <${dict.Model}.View.General ${dict.model}={${dict.model}} />} />;
43
41
  };
44
42
  `,
45
43
  };