@akanjs/cli 3.0.0-beta.17 → 3.0.0-beta.18

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 (133) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-gjqnc2mg.js → CodeAgent-0035exh3.js} +2 -2
  3. package/{CodeTui-nd9hqvrw.js → CodeTui-eweg1hep.js} +205 -34
  4. package/{agent.command-n664dtcv.js → agent.command-65zqfkg0.js} +6 -6
  5. package/akanCode.js +5 -3
  6. package/{application.command-t5542jte.js → application.command-2wcj5da3.js} +18 -11
  7. package/{applicationBuildRunner-x4gbfn7y.js → applicationBuildRunner-m0hhgwsx.js} +6 -5
  8. package/{applicationReleasePackager-z61ep017.js → applicationReleasePackager-vykfzgx3.js} +1 -1
  9. package/buildBatch.proc.js +2 -2
  10. package/{capacitorApp-shv3ajh5.js → capacitorApp-2daqhb5h.js} +2 -2
  11. package/{cloud.command-dk5tj39k.js → cloud.command-960bgbf4.js} +8 -8
  12. package/{cloud.script-ch3xrw3s.js → cloud.script-qhcnqt1n.js} +8 -8
  13. package/{code.command-88sebgnn.js → code.command-4feh3ef7.js} +6 -6
  14. package/{context.command-pqsm5jrk.js → context.command-kzehkx48.js} +14 -14
  15. package/context.runner-z0rrcz7b.js +22 -0
  16. package/{devTui-gy6mendg.js → devTui-ffjsarqa.js} +3 -3
  17. package/{devTuiView-y1548wy6.js → devTuiView-1q1mdgrv.js} +1 -1
  18. package/{guideline.command-rpc2emw8.js → guideline.command-3w2g20x4.js} +8 -13
  19. package/guidelines/conventions/conventions.instruction.md +37 -22
  20. package/guidelines/queryRule/queryRule.instruction.md +1 -1
  21. package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
  22. package/guidelines/transportRule/transportRule.instruction.md +10 -8
  23. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +4 -3
  24. package/incrementalBuilder.proc.js +1 -1
  25. package/{index-bzakk0c2.js → index-14zrtgfa.js} +5 -3
  26. package/{index-57p9p179.js → index-3hpxeys1.js} +6 -5
  27. package/{index-sn7dnzq4.js → index-4r42ext5.js} +1 -1
  28. package/{index-3mg4h788.js → index-6q589y9t.js} +2 -2
  29. package/index-9dp031by.js +12 -0
  30. package/{index-p4p9t45x.js → index-bwxpk2cj.js} +4 -18
  31. package/{index-g9zghs4h.js → index-cjw1sj1x.js} +12 -12
  32. package/{index-te0y1c0m.js → index-d9fjz06h.js} +12 -7
  33. package/{index-4n4821gp.js → index-dw943k93.js} +4 -4
  34. package/{index-4cvpzkq6.js → index-ef228gzf.js} +3 -3
  35. package/{index-3cymrzsb.js → index-erfc1x40.js} +17 -3
  36. package/{index-ns128c4q.js → index-h94faz96.js} +13 -20
  37. package/index-jd01kj5r.js +656 -0
  38. package/{index-2sq06vv0.js → index-jwexzh42.js} +200 -54
  39. package/{index-kvzjda3v.js → index-m41ptvat.js} +5 -5
  40. package/{index-qh7brn20.js → index-mt2154s2.js} +6 -2
  41. package/{index-xjc7gg65.js → index-pn8mhpps.js} +23 -33
  42. package/{index-vpx68e4x.js → index-q9c3c0hy.js} +2 -2
  43. package/{index-v17gj504.js → index-rpgxs245.js} +2 -2
  44. package/{index-twq9p2sp.js → index-s5rhm04y.js} +0 -6
  45. package/{index-p0tew3fq.js → index-sbfk9daf.js} +8 -3
  46. package/{index-n8kt2wh6.js → index-wcg582a8.js} +5 -5
  47. package/{index-6na0sd2b.js → index-ycy302an.js} +5 -2
  48. package/{index-qhtj9y6j.js → index-yw6g3bbv.js} +74 -21
  49. package/{index-2pm1j01n.js → index-zmj143x7.js} +4 -4
  50. package/{index-zn8qgeqx.js → index-zq0mr3hh.js} +1 -1
  51. package/index.js +21 -21
  52. package/{library.command-m8p2r1dh.js → library.command-fp0nhr62.js} +3 -3
  53. package/{localRegistry.command-yppdqrxv.js → localRegistry.command-8y0ecxb9.js} +7 -7
  54. package/{module.command-mfzvqt0n.js → module.command-kqkn48t2.js} +5 -5
  55. package/{package.command-cgp2p2v5.js → package.command-qverjh22.js} +4 -4
  56. package/package.json +2 -2
  57. package/{page.command-taenb02b.js → page.command-94bwhd0g.js} +3 -3
  58. package/{primitive.command-7kpncmkk.js → primitive.command-2ydvtah2.js} +6 -6
  59. package/{prompter-9mn3kp36.js → prompter-1f8d9pcc.js} +1 -1
  60. package/{quality.command-1ar94hrw.js → quality.command-fa0gth4p.js} +3 -4
  61. package/{repair.command-n08t6j8p.js → repair.command-4qng2hpm.js} +5 -5
  62. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  63. package/{scalar.command-mq8qfp4t.js → scalar.command-pb2y95sh.js} +4 -4
  64. package/skills/akan-code/SKILL.md +122 -0
  65. package/skills/akan-module/SKILL.md +2 -2
  66. package/skills/akan-store/SKILL.md +6 -2
  67. package/{subspace.command-jqv5n79w.js → subspace.command-vkxmwp74.js} +4 -4
  68. package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
  69. package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
  70. package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
  71. package/templates/appSample/lib/task/task.abstract.ts +12 -32
  72. package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
  73. package/templates/appSample/lib/task/task.signal.test.ts +14 -0
  74. package/templates/appSample/lib/task/task.signal.ts +1 -1
  75. package/templates/appSample/srvkit/AuthGuard.ts +4 -1
  76. package/templates/appSample/srvkit/SessionInternalArg.ts +3 -1
  77. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
  78. package/templates/crudPages/[__model__Id]/page.tsx +2 -1
  79. package/templates/crudPages/new/page.tsx +2 -1
  80. package/templates/crudPages/page.tsx +2 -1
  81. package/templates/crudSinglePage/page.tsx +2 -1
  82. package/templates/module/__model__.signal.ts +12 -4
  83. package/templates/pkgRoot/tsconfig.json.template +2 -7
  84. package/templates/service/__model__.abstract.md.template +8 -0
  85. package/{tunnel.command-ht2es78c.js → tunnel.command-02cvp9nf.js} +2 -2
  86. package/{workflow.command-tvz4nm9n.js → workflow.command-132txnrh.js} +9 -9
  87. package/{workspace.command-txv1yv5e.js → workspace.command-d5wkswek.js} +21 -21
  88. package/context.runner-bys6ykcp.js +0 -22
  89. package/guidelines/agentRule/agentRule.generate.json +0 -31
  90. package/guidelines/componentRule/componentRule.generate.json +0 -31
  91. package/guidelines/conventions/conventions.generate.json +0 -25
  92. package/guidelines/cssRule/cssRule.generate.json +0 -31
  93. package/guidelines/docPageRule/docPageRule.generate.json +0 -31
  94. package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
  95. package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
  96. package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
  97. package/guidelines/enumConstant/enumConstant.generate.json +0 -31
  98. package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
  99. package/guidelines/fieldRule/fieldRule.generate.json +0 -31
  100. package/guidelines/framework/framework.generate.json +0 -32
  101. package/guidelines/mcpRule/mcpRule.generate.json +0 -35
  102. package/guidelines/modelConstant/modelConstant.generate.json +0 -32
  103. package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
  104. package/guidelines/modelDocument/modelDocument.generate.json +0 -31
  105. package/guidelines/modelService/modelService.generate.json +0 -31
  106. package/guidelines/modelSignal/modelSignal.generate.json +0 -31
  107. package/guidelines/modelStore/modelStore.generate.json +0 -31
  108. package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
  109. package/guidelines/modelUnit/modelUnit.generate.json +0 -31
  110. package/guidelines/modelUtil/modelUtil.generate.json +0 -31
  111. package/guidelines/modelView/modelView.generate.json +0 -31
  112. package/guidelines/modelZone/modelZone.generate.json +0 -31
  113. package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
  114. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
  115. package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
  116. package/guidelines/queryRule/queryRule.generate.json +0 -31
  117. package/guidelines/recipeRule/recipeRule.generate.json +0 -31
  118. package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
  119. package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
  120. package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
  121. package/guidelines/scalarModule/scalarModule.generate.json +0 -31
  122. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
  123. package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
  124. package/guidelines/ssrRule/ssrRule.generate.json +0 -31
  125. package/guidelines/transportRule/transportRule.generate.json +0 -31
  126. package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
  127. package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
  128. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
  129. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -34
  130. package/index-qt8dqgnf.js +0 -250
  131. package/templates/__scalar/__model__/__model__.abstract.md +0 -28
  132. package/templates/module/__model__.abstract.md +0 -28
  133. package/templates/service/__model__.abstract.md +0 -28
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  isPlaceholderAppId2,
4
4
  CapacitorApp2
5
- } from "./index-3cymrzsb.js";
6
- import"./index-p4p9t45x.js";
5
+ } from "./index-erfc1x40.js";
6
+ import"./index-bwxpk2cj.js";
7
7
  import"./index-6wwzs1bc.js";
8
8
  import"./index-q0y2jq9j.js";
9
9
  export {
@@ -6,20 +6,20 @@ import {
6
6
  import {
7
7
  Workspace,
8
8
  command
9
- } from "./index-6na0sd2b.js";
10
- import"./index-p4p9t45x.js";
9
+ } from "./index-ycy302an.js";
10
+ import"./index-bwxpk2cj.js";
11
11
  import"./index-6wwzs1bc.js";
12
- import"./index-ns128c4q.js";
13
- import"./index-3mg4h788.js";
12
+ import"./index-h94faz96.js";
13
+ import"./index-6q589y9t.js";
14
14
  import"./index-hwkygn9s.js";
15
15
  import"./index-7md2g9vw.js";
16
16
  import"./index-kcxmv48c.js";
17
- import"./index-p0tew3fq.js";
18
- import"./index-57p9p179.js";
17
+ import"./index-sbfk9daf.js";
18
+ import"./index-3hpxeys1.js";
19
19
  import {
20
20
  CloudScript2
21
- } from "./index-n8kt2wh6.js";
22
- import"./index-sn7dnzq4.js";
21
+ } from "./index-wcg582a8.js";
22
+ import"./index-4r42ext5.js";
23
23
 
24
24
  // pkgs/@akanjs/cli/cloud/cloud.command.ts
25
25
  var localRegistryUrl = () => process.env.AKAN_NPM_REGISTRY ?? "http://127.0.0.1:4873";
@@ -1,17 +1,17 @@
1
1
  // @bun
2
2
  import {
3
3
  CloudScript2
4
- } from "./index-n8kt2wh6.js";
5
- import"./index-57p9p179.js";
6
- import"./index-ns128c4q.js";
7
- import"./index-sn7dnzq4.js";
8
- import"./index-3mg4h788.js";
9
- import"./index-p0tew3fq.js";
4
+ } from "./index-wcg582a8.js";
5
+ import"./index-3hpxeys1.js";
6
+ import"./index-h94faz96.js";
7
+ import"./index-4r42ext5.js";
8
+ import"./index-6q589y9t.js";
9
+ import"./index-sbfk9daf.js";
10
10
  import"./index-myj01w9r.js";
11
- import"./index-6na0sd2b.js";
11
+ import"./index-ycy302an.js";
12
12
  import"./index-7md2g9vw.js";
13
13
  import"./index-hwkygn9s.js";
14
- import"./index-p4p9t45x.js";
14
+ import"./index-bwxpk2cj.js";
15
15
  import"./index-6wwzs1bc.js";
16
16
  import"./index-kcxmv48c.js";
17
17
  import"./index-q0y2jq9j.js";
@@ -4,9 +4,9 @@ import {
4
4
  runner,
5
5
  script,
6
6
  command
7
- } from "./index-6na0sd2b.js";
7
+ } from "./index-ycy302an.js";
8
8
  import"./index-q0y2jq9j.js";
9
- import"./index-p4p9t45x.js";
9
+ import"./index-bwxpk2cj.js";
10
10
  import"./index-6wwzs1bc.js";
11
11
  import {
12
12
  akanCodeDefaultModel2,
@@ -20,7 +20,7 @@ class CodeRunner extends runner("code") {
20
20
  async serve(options) {
21
21
  await import("./consoleToStderr-h5bryj94.js");
22
22
  const [{ CodeAgent }, { CodeAgentRpcHost }] = await Promise.all([
23
- import("./CodeAgent-gjqnc2mg.js"),
23
+ import("./CodeAgent-0035exh3.js"),
24
24
  import("./CodeAgentRpcHost-qvwfv0n9.js")
25
25
  ]);
26
26
  const profile = CodeRunner.profileOf(options);
@@ -36,8 +36,8 @@ class CodeRunner extends runner("code") {
36
36
  }
37
37
  async tui(options, seed) {
38
38
  const [{ CodeAgent }, { CodeTui }] = await Promise.all([
39
- import("./CodeAgent-gjqnc2mg.js"),
40
- import("./CodeTui-nd9hqvrw.js")
39
+ import("./CodeAgent-0035exh3.js"),
40
+ import("./CodeTui-eweg1hep.js")
41
41
  ]);
42
42
  const profile = CodeRunner.profileOf(options);
43
43
  const apps = options.app ? [options.app] : await options.workspace.getApps();
@@ -71,7 +71,7 @@ class CodeRunner extends runner("code") {
71
71
  }
72
72
  }
73
73
  async run(prompt, options) {
74
- const { CodeAgent } = await import("./CodeAgent-gjqnc2mg.js");
74
+ const { CodeAgent } = await import("./CodeAgent-0035exh3.js");
75
75
  const profile = CodeRunner.profileOf(options);
76
76
  const agent = await CodeAgent.create({
77
77
  workspace: options.workspace,
@@ -2,25 +2,25 @@
2
2
  import {
3
3
  Workspace,
4
4
  command
5
- } from "./index-6na0sd2b.js";
5
+ } from "./index-ycy302an.js";
6
6
  import"./index-q0y2jq9j.js";
7
- import"./index-p4p9t45x.js";
7
+ import"./index-bwxpk2cj.js";
8
8
  import"./index-6wwzs1bc.js";
9
9
  import"./index-by5gpp8x.js";
10
- import"./index-qhtj9y6j.js";
11
- import"./index-v17gj504.js";
12
- import"./index-g9zghs4h.js";
13
- import"./index-3cymrzsb.js";
14
- import"./index-twq9p2sp.js";
15
- import"./index-4cvpzkq6.js";
16
- import"./index-2pm1j01n.js";
17
- import"./index-qh7brn20.js";
18
- import"./index-xjc7gg65.js";
19
- import"./index-te0y1c0m.js";
20
- import"./index-vpx68e4x.js";
10
+ import"./index-yw6g3bbv.js";
11
+ import"./index-rpgxs245.js";
12
+ import"./index-cjw1sj1x.js";
13
+ import"./index-erfc1x40.js";
14
+ import"./index-s5rhm04y.js";
15
+ import"./index-ef228gzf.js";
16
+ import"./index-zmj143x7.js";
17
+ import"./index-mt2154s2.js";
18
+ import"./index-pn8mhpps.js";
19
+ import"./index-d9fjz06h.js";
20
+ import"./index-q9c3c0hy.js";
21
21
  import {
22
22
  ContextScript
23
- } from "./index-4n4821gp.js";
23
+ } from "./index-dw943k93.js";
24
24
 
25
25
  // pkgs/@akanjs/cli/context/context.command.ts
26
26
  class ContextCommand extends command("context", [ContextScript], ({ public: target }) => ({
@@ -0,0 +1,22 @@
1
+ // @bun
2
+ import {
3
+ ContextRunner2
4
+ } from "./index-cjw1sj1x.js";
5
+ import"./index-zmj143x7.js";
6
+ import"./index-q9c3c0hy.js";
7
+ import"./index-d9fjz06h.js";
8
+ import"./index-ef228gzf.js";
9
+ import"./index-pn8mhpps.js";
10
+ import"./index-mt2154s2.js";
11
+ import"./index-rpgxs245.js";
12
+ import"./index-yw6g3bbv.js";
13
+ import"./index-s5rhm04y.js";
14
+ import"./index-erfc1x40.js";
15
+ import"./index-ycy302an.js";
16
+ import"./index-bwxpk2cj.js";
17
+ import"./index-by5gpp8x.js";
18
+ import"./index-6wwzs1bc.js";
19
+ import"./index-q0y2jq9j.js";
20
+ export {
21
+ ContextRunner2 as ContextRunner
22
+ };
@@ -2,12 +2,12 @@
2
2
  import {
3
3
  stripAnsi
4
4
  } from "./index-7md2g9vw.js";
5
- import {
6
- openBrowser
7
- } from "./index-ns128c4q.js";
8
5
  import {
9
6
  writeClipboard
10
7
  } from "./index-p6pbz9n5.js";
8
+ import {
9
+ openBrowser
10
+ } from "./index-9dp031by.js";
11
11
 
12
12
  // pkgs/@akanjs/cli/application/devTui.tsx
13
13
  import { render } from "ink";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // pkgs/@akanjs/cli/application/devTuiView.ts
3
3
  var createDevTuiView = async (supervisor) => {
4
- const { DevTui } = await import("./devTui-gy6mendg.js");
4
+ const { DevTui } = await import("./devTui-ffjsarqa.js");
5
5
  return new DevTui(supervisor);
6
6
  };
7
7
  export {
@@ -2,30 +2,29 @@
2
2
  import {
3
3
  script,
4
4
  command
5
- } from "./index-6na0sd2b.js";
5
+ } from "./index-ycy302an.js";
6
6
  import"./index-q0y2jq9j.js";
7
- import"./index-p4p9t45x.js";
7
+ import"./index-bwxpk2cj.js";
8
8
  import"./index-6wwzs1bc.js";
9
9
  import {
10
10
  Prompter2
11
- } from "./index-twq9p2sp.js";
11
+ } from "./index-s5rhm04y.js";
12
12
 
13
13
  // pkgs/@akanjs/cli/guideline/guideline.script.ts
14
14
  import { Logger } from "akanjs/common";
15
15
 
16
16
  class GuidelineScript extends script("guideline") {
17
- async guideline(action, name = null, format = "markdown") {
17
+ async guideline(action, name = null) {
18
18
  if (action === "list") {
19
19
  const guidelines = await Prompter2.listGuidelines();
20
- Logger.rawLog(format === "json" ? JSON.stringify({ guidelines }, null, 2) : guidelines.join(`
20
+ Logger.rawLog(guidelines.join(`
21
21
  `));
22
22
  return;
23
23
  }
24
24
  if (action === "show") {
25
25
  if (!name)
26
26
  throw new Error("Guideline name is required. Example: akan guideline show framework");
27
- const [instruction, guideJson] = await Promise.all([Prompter2.getInstruction(name), Prompter2.getGuideJson(name)]);
28
- Logger.rawLog(format === "json" ? JSON.stringify({ name, instruction, guideJson }, null, 2) : instruction);
27
+ Logger.rawLog(await Prompter2.getInstruction(name));
29
28
  return;
30
29
  }
31
30
  throw new Error(`Unknown guideline action: ${action}. Use "list" or "show".`);
@@ -34,12 +33,8 @@ class GuidelineScript extends script("guideline") {
34
33
 
35
34
  // pkgs/@akanjs/cli/guideline/guideline.command.ts
36
35
  class GuidelineCommand extends command("guideline", [GuidelineScript], ({ public: target }) => ({
37
- guideline: target({ desc: "List or show Akan AI guideline instructions" }).arg("action", String, { desc: "list or show" }).arg("name", String, { desc: "guideline name for show", nullable: true }).option("format", String, {
38
- desc: "output format",
39
- default: "markdown",
40
- enum: ["markdown", "json"]
41
- }).exec(async function(action, name, format) {
42
- await this.guidelineScript.guideline(action, name, format);
36
+ guideline: target({ desc: "List or show Akan AI guideline instructions" }).arg("action", String, { desc: "list or show" }).arg("name", String, { desc: "guideline name for show", nullable: true }).exec(async function(action, name) {
37
+ await this.guidelineScript.guideline(action, name);
43
38
  })
44
39
  })) {
45
40
  }
@@ -273,8 +273,10 @@ are, because those are the ones the server could have done.
273
273
  SEO snapshots, prerendering and pre-hydration E2E read, so await what the page needs immediately and stream
274
274
  the rest. `xListInY` / `xInsightInY` hold hydrated model instances that React Flight refuses as client props:
275
275
  consume them in a server component, never as a `Zone` prop.
276
- 6. **Use named `ReactNode` slots, not just `children`** — `Layout.Navbar` takes `title`, `back`, `left`, `right`,
277
- and `children`, so a client shell composes server content in five places instead of absorbing it.
276
+ 6. **Use named `ReactNode` slots, not just `children`** — a client shell that takes one slot per region lets a
277
+ server component supply each of them, instead of absorbing the whole subtree into the bundle. `Layout.Navbar`
278
+ declares `title` / `left` / `right` alongside `back` and `children`, but renders only the last two today, so
279
+ copy the shape rather than the component.
278
280
  7. **Let the server do the derived work.** Display and predicate logic belongs on `Light<Model>`; enum→class
279
281
  lookups belong in a module-scope `as const` map.
280
282
  8. **Gate auth on the server** — `getSelf({ unauthorize: "/signin" })` in `_layout.tsx`, before any HTML is sent.
@@ -421,8 +423,11 @@ stores need none, because state and CRUD actions are generated. The body is thre
421
423
  `this.setX(...)` → toast. The optimistic shape is mutate the client model, `void fetch.*`, then commit. Use
422
424
  `this.pick(...)` when the value must exist, `this.get()` when it may not, and `this.set({...})` to write. Mutate lists
423
425
  through the collection API (`this.set({ xList: xList.set(x).save() })`), not array spread. **An action returns
424
- nothing** (`no-return-in-store-action.grit`). **Never `import type { RootStore } from "../st"`** — it crashes
425
- `akan build` with a Bun SSR segfault.
426
+ nothing** (`no-return-in-store-action.grit`). **Reach another store through `this`:**
427
+ `import type { RootStore } from "../st"`, then `(this as unknown as RootStore).logout()` to call its action or
428
+ `(this as unknown as RootStore).set({ … })` / `.get()` to write or read its state. Every store is mixed into one root
429
+ at runtime, so the cast only tells the type what `this` already is. Keep it `import type` — `st.ts` imports every
430
+ store, so a value import is a cycle.
426
431
 
427
432
  **`<model>.dictionary.ts`** — fixed chain, with empty stages still written:
428
433
  `.of() → .model() → .insight() → .query() → .sort() → .enum() → .slice() → .endpoint() → .error() → .translate()`.
@@ -475,13 +480,14 @@ Full contract — credential handshake, room revalidation, socket cleanup scopin
475
480
  never bounded. **Losing the race does not cancel the work**: the handler runs to completion with nobody
476
481
  holding its result, so a deadline is an answer to the caller, not an undo.
477
482
  - **A cached answer is the endpoint's `{ cache: <ms> }`, and only a `query` taking no internal argument may have
478
- one.** The `Cache` middleware is registered by default and stands aside for every endpoint that declares
479
- nothing. Internal arguments are how a call learns who is asking (`.with(Self)`), so an endpoint that has them
480
- answers per caller and one shared entry would be one caller's answer handed to the next — that endpoint and
481
- every `mutation` are named in the log and left uncached. Guards run on every hit; what is cached is the
482
- handler's result, so `resolveReturn` still masks fields and resolves relations per call; a cache backend that
483
- is down is warned about and the call runs uncached. The default chain is `Logging → Timeout → Cache → handler`,
484
- and there is no `Retry` middleware.
483
+ one.** It is a step of the call, not a middleware, and stands aside for every endpoint that declares nothing.
484
+ Internal arguments are how a call learns who is asking (`.with(Self)`), so an endpoint that has them answers
485
+ per caller and one shared entry would be one caller's answer handed to the next — that endpoint and every
486
+ `mutation` are named in the log and left uncached. The lookup runs after the guards, so a hit reaches only a
487
+ caller they admitted; what is cached is the handler's result, so `resolveReturn` still masks fields and resolves
488
+ relations per call; a cache backend that is down is warned about and the call runs uncached. The default
489
+ middleware chain is `Logging → Timeout → <lib middlewares>`, then guards → internal arguments → cache →
490
+ handler, and there is no `Retry` middleware.
485
491
 
486
492
  ### Authorization Defaults
487
493
 
@@ -548,8 +554,11 @@ Full contract — filter-arg `ref` pickers, `getQueryMeta` summary counters, `la
548
554
  first "more". `isCumulativeOf<Model>` is the mode.
549
555
  - **"Is there more" is `hasMoreOf<Model>`, never `count > page * limit`.** It comes from the length of the batch
550
556
  the server returned, so it survives `{ insight: false }` and cannot drift from a count a live event moved.
551
- - **Hydrated vs raw:** server queries return hydrated `cnst.<Model>` instances (with `set`/`save`/`refresh`);
552
- client fetch results are raw `GetStateObject` plain data, functions stripped.
557
+ - **Hydrated vs raw:** server queries return hydrated `cnst.<Model>` instances (with `set`/`save`/`refresh`),
558
+ and so do client fetch results — `FetchClient` parses every return with `crystalize` defaulting to **true**
559
+ (`pkgs/akanjs/fetch/client/fetchClient.ts`). The raw `GetStateObject` shape is what the `<ref>Obj` /
560
+ `<ref>ObjList` / `<ref>ObjInsight` handles carry, because those pass `crystalize: false` on purpose so the
561
+ value can cross the RSC boundary as a client prop.
553
562
  - Every filter generates fourteen methods: `list` · `listIds` · `find` · `findId` · `pick` · `pickId` · `exists` ·
554
563
  `count` · `insight` · `query` · **`remove`** · **`removeOne`** · **`update`** · **`updateOne`**. The last four
555
564
  are query-level writes — one atomic UPDATE, **no hooks**, and therefore no `_postRemove` and no cascade. Use
@@ -587,7 +596,7 @@ Full contract — relevance ordering, `columns` / `weights`: `get_guideline` wit
587
596
  - Injected dependencies resolve by field-name convention: a field named `<refName>Service` resolves to the service registered under `<refName>`, and `<refName>Signal` likewise (`pkgs/akanjs/service/injectInfo.ts`).
588
597
  - The `Service`/`Signal` suffix is required — the injector strips it to derive the registry lookup key. Name the field after the target refName plus the suffix, not arbitrarily.
589
598
  - Preference order inside a service: `service<srv.XService>()` for another module's service · `plug(AdapterClass)` or `plug(StorageAdaptorRole)` for an adapter · `use<T>()` only to reach an `option.ts`-registered legacy singleton · `env(...)` for config.
590
- - **`memory(...)` takes a scalar or model class, not only a primitive** — `memory(Map, { of: CallStateInput })` serializes through the constant and travels as JSON text, so the Redis and sqlite-backed caches round-trip the same declaration. Never hand-encode JSON into a `String` memory.
599
+ - **`memory(...)` takes a scalar or model class, not only a primitive** — `memory(Map, { of: CallStateInput })` serializes through the constant and travels as JSON text, so the Redis and sqlite-backed caches round-trip the same declaration. Never hand-encode JSON into a `String` memory. A memory is scoped to the service or adaptor that declares it; `ttl` (milliseconds) sets how long each write lives unless the `set` call names its own `expireAt`, and a `Map` entry expires on its own.
591
600
 
592
601
  ### Adapters — `adapt()` And `plug()`
593
602
 
@@ -663,9 +672,11 @@ it.
663
672
  names itself as the issuer, so `/mcp` demands a bearer token, verifies its signature, and refuses one carrying no
664
673
  `aud`. A token is the app's own access JWT plus `aud`/`iss`/`client_id`, so `AccountMiddleware` and the guards
665
674
  judge it unchanged; there is no scope. Per-app knobs live in `env.server.*` under `oauth` (`consentPath` and
666
- `signinPath` with the basePath, `clients`, `dynamicRegistration`, `allowedRedirectSchemes`, `clientIdMetadata`,
667
- `enabled`). `/mcp` reads the `Authorization` header only — a cookie is dropped at the door — and `JWT_SECRET` is
668
- mandatory outside `local`, because the derived fallback is forgeable from three public names. A grant is revoked
675
+ `signinPath` with the basePath, `clients`, `dynamicRegistration`, `allowedRedirectSchemes`, `accessTokenSeconds`,
676
+ `clientIdMetadata`, `enabled`, plus `issuer` / `resource` — set those when a tunnel or an edge makes the derived
677
+ origin wrong, because an MCP client compares the issuer byte for byte). `/mcp` reads the `Authorization` header only — a cookie is dropped at the door — and `JWT_SECRET` (or
678
+ `security.jwtSecret`) is mandatory whenever `operationMode` is not `local`, because the derived fallback is
679
+ forgeable from three public names; `AKAN_ALLOW_DERIVED_JWT_SECRET=1` accepts that risk explicitly. A grant is revoked
669
680
  whole — `POST /oauth/revoke` (RFC 7009) by the client, `fetch.revokeOAuthConnection(sessionId)` by the account's
670
681
  owner, `fetch.listOAuthConnections()` to see them — and a revoked access token is refused at its next call.
671
682
  - **A person may, a model may not.** An agent's token names its `client_id` and `aud`; a browser session has
@@ -831,10 +842,11 @@ shape, so `cascade` never means "related" — it means one of exactly these:
831
842
  - Dynamic segments use `[id]`; route groups use directories like `(user)`, `(public)`, `(tab)`, or `(detail)`.
832
843
  - **A route file exports one thing**: `export default page()…render(…)` for a page, `layout()…render(…)` for a
833
844
  `_layout.tsx`, `rootLayout()…render(…)` for the app's (or a basePath's) root `_layout.tsx`. Every route setting
834
- is a stage of the chain — `.param()`, `.search()`, `.config()`, `.head()` / `.metadata()`, `.loading()`;
835
- `.notFound()` / `.error()` on a layout; `.fonts()` / `.theme()` / `.manifest()` / `.reconnect()` / `.wsConnect()`
836
- / `.layoutStyle()` / `.gaTrackingId()` on the root layout; `.prompt()` on a page. A named export beside the chain,
837
- or `page()` in a `_layout.tsx`, fails the build.
845
+ is a stage of the chain — `.param()`, `.search()`, `.config()`, `.head()`, `.loading()`; `.notFound()` /
846
+ `.error()` on a layout; `.fonts()` / `.theme()` / `.manifest()` / `.reconnect()` / `.wsConnect()` /
847
+ `.layoutStyle()` on the root layout; `.prompt()` on a page. A named export beside the chain, or `page()` in a
848
+ `_layout.tsx`, fails the build. `.head()` takes JSX — `<title>`, `<meta>`, `<link>` — or a function of the
849
+ route's args returning it; there is no metadata object, and analytics is the app's own script, not a stage.
838
850
  - **A page names every `[x]` segment of its path with `.param("x", Type)`** and reads a query key only through
839
851
  `.search("k", Type)`. Values arrive typed — `ID`/`String` → string, `Int`/`Float` → number, `Boolean`, `Date` →
840
852
  Dayjs, an `enumOf` class → its union, `[T]` → array — a path value the type refuses answers not-found, and a
@@ -922,12 +934,15 @@ when two shapes disagree.
922
934
  - `children: any` — newer files use `children: ReactNode`.
923
935
  - Hard-coded API keys or secrets in source; they belong in `option.ts` or env.
924
936
  - Large blocks of commented-out code left in place.
925
- - Cross-store writes through a `RootStore` cast — it collides with the Bun SSR-bundler segfault.
926
937
  - Stale `// TODO: Implement …` comments above implemented methods.
927
938
  - `{cond && <X/>}` in JSX, hard-coded Korean bypassing `l()`, and `window.alert(...)` for user feedback.
928
939
  - Bare `/* eslint-disable */` blocks — use `// biome-ignore lint/<rule>: <why>`.
929
940
  - Raw palette grays such as `text-gray-400` instead of the semantic tokens (`text-foreground/70`).
930
941
 
942
+ A store calling `(this as unknown as RootStore).<action>()` or `.set({ … })` over
943
+ `import type { RootStore } from "../st"` is **not** one of these — it is the sanctioned way to reach another store's
944
+ actions and state (see `<model>.store.ts` above).
945
+
931
946
  ## Secrets And Env Safety (`.env`, `infra/**`, `*secret*`, `*credential*`)
932
947
 
933
948
  - Never print, summarize, commit, or expose real secret values, credentials, tokens, private keys, or `.env` contents.
@@ -49,7 +49,7 @@ with it. `conventions` carries the invariants — this is the full contract behi
49
49
  `findBy<Filter>(...args, { select: { secretField: true } })` takes it inside the option object. The shapes do not
50
50
  swap: `{ select: … }` handed to the facade projects a field named `select`, which no model has, and the read comes
51
51
  back empty with no error. This is the only way to read a `field.secret(...)` value, which is otherwise stripped.
52
- - **Hydrated vs raw:** server queries return hydrated `cnst.<Model>` instances (with `set`/`save`/`refresh`); client fetch results are raw `GetStateObject` plain data (functions stripped, `pkgs/akanjs/base/types.ts`).
52
+ - **Hydrated vs raw:** server queries return hydrated `cnst.<Model>` instances (with `set`/`save`/`refresh`), and so do client fetch results — `FetchClient` parses every return with `crystalize` defaulting to **true** (`pkgs/akanjs/fetch/client/fetchClient.ts`). The raw `GetStateObject` shape (functions stripped, `pkgs/akanjs/base/types.ts`) is what the `<ref>Obj` / `<ref>ObjList` / `<ref>ObjInsight` handles carry, because those pass `crystalize: false` on purpose so the value can cross the RSC boundary as a client prop.
53
53
  - Every filter generates fourteen methods: `list` · `listIds` · `find` · `findId` · `pick` · `pickId` · `exists` ·
54
54
  `count` · `insight` · `query` · **`remove`** · **`removeOne`** · **`update`** · **`updateOne`**. The last four are
55
55
  query-level writes — one atomic UPDATE, **no hooks**, and therefore no `_postRemove` and no cascade. Use them on a
@@ -129,8 +129,10 @@ eight queries threw; per-section boundaries put each rejection at its own bounda
129
129
  soft-redirect script, so `getSelf({ unauthorize: "/signin" })` stays in `_layout.tsx` or the page body — never
130
130
  inside a streamed section.
131
131
 
132
- **⑥ Use named `ReactNode` slots, not just `children`.** `Layout.Navbar` accepts `title`, `back`, `left`, `right`,
133
- and `children`, so a client shell composes server-rendered content in five places instead of absorbing it.
132
+ **⑥ Use named `ReactNode` slots, not just `children`.** A client shell that takes one slot per region lets a
133
+ server component supply each of them, instead of absorbing the whole subtree into the bundle. `Layout.Navbar`
134
+ declares `title` / `left` / `right` alongside `back` and `children`, but its render body uses only `back` and
135
+ `children` — copy the shape, not that component.
134
136
 
135
137
  **⑦ Let the server do the derived work.** Display and predicate logic belongs on `Light<Model>` (`isNew()`,
136
138
  `canWrite(user?)`, `formatTimes()`), and enum→class lookups belong in a module-scope `as const` map. Both sides call
@@ -58,23 +58,25 @@ mutation is mounted under. `conventions` carries the invariants — this is the
58
58
 
59
59
  ## Cached Answers
60
60
 
61
- - **`{ cache: <ms> }` in an endpoint's signal option is the whole cache surface.** The `Cache` middleware is
62
- registered by default and stands aside unless an endpoint declares one — it used to be opt-in and to ignore the
63
- declared value for a hard-coded 60 seconds, which is the same shape the `timeout` bug had.
61
+ - **`{ cache: <ms> }` in an endpoint's signal option is the whole cache surface.** The lookup is a step of every
62
+ call and stands aside unless an endpoint declares one.
64
63
  - **Only a `query` that takes no internal argument may carry one.** The handler's inputs are its declared
65
64
  arguments plus its internal ones, so an endpoint with none of the latter answers the same thing to everyone who
66
65
  may read it — which is the only answer a shared entry can hold. An endpoint that takes `.with(Self)` answers
67
66
  per caller, and one entry would be one caller's answer handed to the next; that endpoint and every `mutation`
68
67
  are named once in the log and left uncached rather than silently ignored.
69
- - **The guards run on every hit.** A cache hit skips `next()`, and `next()` is what runs them, so the middleware
70
- calls `context.checkGuards()` itself before handing the entry over. Shared is not public.
71
- - **The entry is the handler's result, not the response.** The middleware wraps execution, so `resolveReturn`
68
+ - **The guards run before every hit.** The lookup sits after the guards and the internal arguments, inside the
69
+ call, so every middleware — the account resolution a lib registers among them — has already run and a hit
70
+ reaches only a caller the guards admitted. It used to be a middleware ahead of the lib's, and a guard reading
71
+ the account refused a signed-in caller on every hit. Shared is not public.
72
+ - **The entry is the handler's result, not the response.** The lookup wraps the handler only, so `resolveReturn`
72
73
  still runs per call on the cached value — field masking, `hidden`/`secret` stripping and relation resolution are
73
74
  never cached, and a relation still costs its own load. The cache saves the handler, not the serialization.
74
75
  - **A cache backend that is down does not take the endpoint down.** A failed read is warned and the call runs
75
76
  uncached; a failed write is warned and dropped.
76
- - The default middleware chain is `Logging → Timeout → Cache → handler`: a hung cache backend is bounded by the
77
- same deadline as the handler it stands in for. **`Retry` was removed** — an automatic re-run of an endpoint
77
+ - The default middleware chain is `Logging → Timeout → <lib middlewares>`, and the call inside it runs guards →
78
+ internal arguments → cache → handler: a hung cache backend is bounded by the same deadline as the handler it
79
+ stands in for. **`Retry` was removed** — an automatic re-run of an endpoint
78
80
  whose failure it cannot classify replays whatever the first attempt already did.
79
81
 
80
82
  ## Binary Pubsub
@@ -376,15 +376,16 @@ export default page()
376
376
  |---|---|
377
377
  | `interface PageProps { params }` + `[x]` folder | `.param("x", ID \| String \| Int \| …)` — one per `[x]` segment, every one of them, in path order |
378
378
  | `searchParams.k` | `.search("k", Type)`; `[Type]` for a repeated key; the value arrives typed and optional |
379
- | `params.lang` | `lang` — on every route's `.render()`, `.head()`, `.metadata()` and `.loading()` with no stage; `.param("lang")` is refused |
379
+ | `params.lang` | `lang` — on every route's `.render()`, `.head()` and `.loading()` with no stage; `.param("lang")` is refused |
380
380
  | `export const pageConfig = {…}` | `.config({…})` — `devOnly` stays a literal |
381
381
  | `export const head = <…/>` / `generateHead({ params })` | `.head(<…/>)` / `.head(({ x }) => <…/>)` |
382
- | `export const metadata` / `generateMetadata` | `.metadata({…})` / `.metadata((args) => …)` |
382
+ | `export const metadata` / `generateMetadata` | `.head(<><title>…</title><meta name="description" content="…" /></>)` — there is no object form |
383
383
  | `export function Loading()` | `.loading((args) => …)` |
384
384
  | `export default async function Page({ params, searchParams })` | `.render(async ({ x, k }) => { …same body… })` — `async` only if it awaits |
385
385
  | `_layout.tsx`: `export default function Layout({ children })` | `layout().render(({ children }) => …)` |
386
386
  | `export function NotFound` / `export function Error` | `.notFound(fn)` / `.error(fn)` on `layout()` |
387
- | root `_layout.tsx`: `fonts`, `theme`, `manifest`, `reconnect`, `wsConnect`, `layoutStyle`, `gaTrackingId` | `rootLayout().fonts([…]).theme("dark").manifest({…}).reconnect(false).wsConnect(false).layoutStyle("web").gaTrackingId("G-…")` |
387
+ | root `_layout.tsx`: `fonts`, `theme`, `manifest`, `reconnect`, `wsConnect`, `layoutStyle` | `rootLayout().fonts([…]).theme("dark").manifest({…}).reconnect(false).wsConnect(false).layoutStyle("web")` |
388
+ | root `_layout.tsx`: `gaTrackingId` | none — render the app's own `"use client"` analytics component from the root layout's `.render()` |
388
389
  | `prompt()` on `endpoint()` (removed) | `.prompt(name, description)` on the page that shows the same screen |
389
390
 
390
391
  Rules the loader and `akan sync` enforce: a chain module has no other export; `page()` belongs in a page file and
@@ -3,7 +3,7 @@ import {
3
3
  CodegenLock,
4
4
  WorkspaceExecutor,
5
5
  AppExecutor
6
- } from "./index-p4p9t45x.js";
6
+ } from "./index-bwxpk2cj.js";
7
7
  import"./index-q0y2jq9j.js";
8
8
  import"./index-6wwzs1bc.js";
9
9
  import {
@@ -249,7 +249,7 @@ class CodeTuiCommands2 {
249
249
  static all = [
250
250
  { name: "help", desc: "list these commands and the keys" },
251
251
  { name: "tools", desc: "what this session can call" },
252
- { name: "model", desc: "switch model", arg: "<provider>/<id>" },
252
+ { name: "model", desc: "switch model, or list what is available", arg: "[<provider>/<id>]" },
253
253
  { name: "effort", desc: "how hard the model thinks before it answers", arg: "<level>" },
254
254
  { name: "thinking", desc: "show the model's reasoning, or fold it away again" },
255
255
  { name: "compact", desc: "summarise the conversation to free the window", arg: "[notes]" },
@@ -258,7 +258,7 @@ class CodeTuiCommands2 {
258
258
  { name: "name", desc: "name this session", arg: "<text>" },
259
259
  { name: "fork", desc: "continue this conversation twice; the copy takes over here", arg: "[name]" },
260
260
  { name: "agents", desc: "what a sub-agent may be, and what one may spend" },
261
- { name: "mcp", desc: "the MCP servers this session reached", arg: "[add|remove|reload]" },
261
+ { name: "mcp", desc: "the MCP servers this session reached", arg: "[add|remove|login|reload]" },
262
262
  { name: "peers", desc: "the other akan code sessions running here" },
263
263
  { name: "msg", desc: "hand a message to another session", arg: "<peer> <text>" },
264
264
  { name: "quit", desc: "leave the session" }
@@ -292,7 +292,7 @@ class CodeTuiCommands2 {
292
292
  "",
293
293
  "Images: cmd+v attaches what is on the clipboard \xB7 ^v does too, without the terminal in the way",
294
294
  "",
295
- 'shift+enter needs a terminal that reports it \u2014 in VS Code bind it to send "\\u001b\\r".'
295
+ 'shift+enter needs a terminal that reports it \u2014 in VS Code bind it to send "\\\\u001b\\r".'
296
296
  ].join(`
297
297
  `);
298
298
  }
@@ -335,6 +335,8 @@ class CodeTuiEditor2 {
335
335
  this.set(this.#text.slice(0, this.#caret) + clean + this.#text.slice(this.#caret), this.#caret + clean.length);
336
336
  }
337
337
  newline() {
338
+ if (this.#text.slice(0, this.#caret).endsWith("\\"))
339
+ this.set(this.#text.slice(0, this.#caret - 1) + this.#text.slice(this.#caret), this.#caret - 1);
338
340
  this.insert(`
339
341
  `);
340
342
  }
@@ -6,14 +6,14 @@ import {
6
6
  } from "./index-myj01w9r.js";
7
7
  import {
8
8
  runner
9
- } from "./index-6na0sd2b.js";
9
+ } from "./index-ycy302an.js";
10
10
  import {
11
11
  WorkspaceExecutor,
12
12
  AppExecutor
13
- } from "./index-p4p9t45x.js";
13
+ } from "./index-bwxpk2cj.js";
14
14
  import {
15
15
  openBrowser
16
- } from "./index-ns128c4q.js";
16
+ } from "./index-9dp031by.js";
17
17
 
18
18
  // pkgs/@akanjs/cli/cloud/cloud.runner.ts
19
19
  import path from "path";
@@ -297,11 +297,12 @@ ${chalk.green("\u27A4")} Authentication Required`));
297
297
  const registry = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
298
298
  const registryArgs = this.#getRegistryArgs(registry);
299
299
  const env = this.#getRegistryEnv(registry);
300
+ const globalCliArgs = ["add", "-g", `@akanjs/cli@${tag}`, ...registryArgs];
300
301
  if (!await workspace.exists("package.json"))
301
- await workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`, ...registryArgs], { env });
302
+ await workspace.spawn("bun", globalCliArgs, { env });
302
303
  else
303
304
  await Promise.all([
304
- workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`, ...registryArgs], { env }),
305
+ workspace.spawn("bun", globalCliArgs, { env }),
305
306
  this.#updateAkanPkgs(workspace, tag, registry)
306
307
  ]);
307
308
  }
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  AppInfo
4
- } from "./index-p4p9t45x.js";
4
+ } from "./index-bwxpk2cj.js";
5
5
 
6
6
  // pkgs/@akanjs/devkit/slicePlanner.ts
7
7
  class SlicePlanner {
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-6na0sd2b.js";
5
+ } from "./index-ycy302an.js";
6
6
  import {
7
7
  LibExecutor
8
- } from "./index-p4p9t45x.js";
8
+ } from "./index-bwxpk2cj.js";
9
9
  import {
10
10
  LibSource,
11
11
  formatLibStatuses
@@ -0,0 +1,12 @@
1
+ // @bun
2
+ // pkgs/@akanjs/cli/openBrowser.ts
3
+ import { spawn } from "child_process";
4
+ function openBrowser(url) {
5
+ const command = process.platform === "darwin" ? ["open", url] : process.platform === "win32" ? ["cmd", "/c", "start", "", url] : ["xdg-open", url];
6
+ const child = spawn(command[0], command.slice(1), { detached: true, stdio: "ignore" });
7
+ child.on("error", () => {});
8
+ child.unref();
9
+ return Promise.resolve();
10
+ }
11
+
12
+ export { openBrowser };