@akanjs/cli 3.0.0-beta.16 → 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 (134) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-zgccwajm.js → CodeAgent-0035exh3.js} +2 -2
  3. package/{CodeTui-993tx7gf.js → CodeTui-eweg1hep.js} +384 -28
  4. package/{agent.command-n664dtcv.js → agent.command-65zqfkg0.js} +6 -6
  5. package/akanCode.js +11 -9
  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-4x35k1z6.js → cloud.command-960bgbf4.js} +8 -8
  12. package/{cloud.script-3k8nbbpn.js → cloud.script-qhcnqt1n.js} +8 -8
  13. package/{code.command-mrfb7a1g.js → code.command-4feh3ef7.js} +7 -7
  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-sxg87a8f.js → index-14zrtgfa.js} +164 -98
  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-5405kc0x.js → index-jwexzh42.js} +363 -247
  39. package/{index-wfwknnje.js → index-jwrpsrg3.js} +8 -6
  40. package/{index-kvzjda3v.js → index-m41ptvat.js} +5 -5
  41. package/{index-qh7brn20.js → index-mt2154s2.js} +6 -2
  42. package/{index-xjc7gg65.js → index-pn8mhpps.js} +23 -33
  43. package/{index-vpx68e4x.js → index-q9c3c0hy.js} +2 -2
  44. package/{index-v17gj504.js → index-rpgxs245.js} +2 -2
  45. package/{index-twq9p2sp.js → index-s5rhm04y.js} +0 -6
  46. package/{index-018dszb3.js → index-sbfk9daf.js} +10 -3
  47. package/{index-zg0v1zte.js → index-wcg582a8.js} +5 -5
  48. package/{index-6na0sd2b.js → index-ycy302an.js} +5 -2
  49. package/{index-qhtj9y6j.js → index-yw6g3bbv.js} +74 -21
  50. package/{index-2pm1j01n.js → index-zmj143x7.js} +4 -4
  51. package/{index-zn8qgeqx.js → index-zq0mr3hh.js} +1 -1
  52. package/index.js +21 -21
  53. package/{library.command-m8p2r1dh.js → library.command-fp0nhr62.js} +3 -3
  54. package/{localRegistry.command-tt00nwwg.js → localRegistry.command-8y0ecxb9.js} +7 -7
  55. package/{module.command-mfzvqt0n.js → module.command-kqkn48t2.js} +5 -5
  56. package/{package.command-8sy6jjwy.js → package.command-qverjh22.js} +4 -4
  57. package/package.json +8 -6
  58. package/{page.command-taenb02b.js → page.command-94bwhd0g.js} +3 -3
  59. package/{primitive.command-7kpncmkk.js → primitive.command-2ydvtah2.js} +6 -6
  60. package/{prompter-9mn3kp36.js → prompter-1f8d9pcc.js} +1 -1
  61. package/{quality.command-1ar94hrw.js → quality.command-fa0gth4p.js} +3 -4
  62. package/{repair.command-n08t6j8p.js → repair.command-4qng2hpm.js} +5 -5
  63. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  64. package/{scalar.command-mq8qfp4t.js → scalar.command-pb2y95sh.js} +4 -4
  65. package/skills/akan-code/SKILL.md +122 -0
  66. package/skills/akan-module/SKILL.md +2 -2
  67. package/skills/akan-store/SKILL.md +6 -2
  68. package/{subspace.command-x9897gj4.js → subspace.command-vkxmwp74.js} +4 -4
  69. package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
  70. package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
  71. package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
  72. package/templates/appSample/lib/task/task.abstract.ts +12 -32
  73. package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
  74. package/templates/appSample/lib/task/task.signal.test.ts +14 -0
  75. package/templates/appSample/lib/task/task.signal.ts +1 -1
  76. package/templates/appSample/srvkit/AuthGuard.ts +4 -1
  77. package/templates/appSample/srvkit/SessionInternalArg.ts +3 -1
  78. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
  79. package/templates/crudPages/[__model__Id]/page.tsx +2 -1
  80. package/templates/crudPages/new/page.tsx +2 -1
  81. package/templates/crudPages/page.tsx +2 -1
  82. package/templates/crudSinglePage/page.tsx +2 -1
  83. package/templates/module/__model__.signal.ts +12 -4
  84. package/templates/pkgRoot/tsconfig.json.template +2 -7
  85. package/templates/service/__model__.abstract.md.template +8 -0
  86. package/{tunnel.command-ht2es78c.js → tunnel.command-02cvp9nf.js} +2 -2
  87. package/{workflow.command-tvz4nm9n.js → workflow.command-132txnrh.js} +9 -9
  88. package/{workspace.command-ayqa1rgt.js → workspace.command-d5wkswek.js} +21 -21
  89. package/context.runner-bys6ykcp.js +0 -22
  90. package/guidelines/agentRule/agentRule.generate.json +0 -31
  91. package/guidelines/componentRule/componentRule.generate.json +0 -31
  92. package/guidelines/conventions/conventions.generate.json +0 -25
  93. package/guidelines/cssRule/cssRule.generate.json +0 -31
  94. package/guidelines/docPageRule/docPageRule.generate.json +0 -31
  95. package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
  96. package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
  97. package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
  98. package/guidelines/enumConstant/enumConstant.generate.json +0 -31
  99. package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
  100. package/guidelines/fieldRule/fieldRule.generate.json +0 -31
  101. package/guidelines/framework/framework.generate.json +0 -32
  102. package/guidelines/mcpRule/mcpRule.generate.json +0 -35
  103. package/guidelines/modelConstant/modelConstant.generate.json +0 -32
  104. package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
  105. package/guidelines/modelDocument/modelDocument.generate.json +0 -31
  106. package/guidelines/modelService/modelService.generate.json +0 -31
  107. package/guidelines/modelSignal/modelSignal.generate.json +0 -31
  108. package/guidelines/modelStore/modelStore.generate.json +0 -31
  109. package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
  110. package/guidelines/modelUnit/modelUnit.generate.json +0 -31
  111. package/guidelines/modelUtil/modelUtil.generate.json +0 -31
  112. package/guidelines/modelView/modelView.generate.json +0 -31
  113. package/guidelines/modelZone/modelZone.generate.json +0 -31
  114. package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
  115. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
  116. package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
  117. package/guidelines/queryRule/queryRule.generate.json +0 -31
  118. package/guidelines/recipeRule/recipeRule.generate.json +0 -31
  119. package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
  120. package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
  121. package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
  122. package/guidelines/scalarModule/scalarModule.generate.json +0 -31
  123. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
  124. package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
  125. package/guidelines/ssrRule/ssrRule.generate.json +0 -31
  126. package/guidelines/transportRule/transportRule.generate.json +0 -31
  127. package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
  128. package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
  129. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
  130. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -34
  131. package/index-jgrnpt6y.js +0 -121
  132. package/templates/__scalar/__model__/__model__.abstract.md +0 -28
  133. package/templates/module/__model__.abstract.md +0 -28
  134. package/templates/service/__model__.abstract.md +0 -28
@@ -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 {
@@ -1,4 +1,160 @@
1
1
  // @bun
2
+ // pkgs/@akanjs/cli/code/CodeTuiLines.ts
3
+ import stringWidth from "string-width";
4
+
5
+ class CodeTuiLines2 {
6
+ static width(text) {
7
+ return stringWidth(text);
8
+ }
9
+ static rows(rows, width, keyBase) {
10
+ const lines = [];
11
+ rows.forEach((row, idx) => {
12
+ for (const line of CodeTuiLines2.#row(row, Math.max(8, width), `${keyBase}:${idx}`))
13
+ lines.push(line);
14
+ });
15
+ return lines;
16
+ }
17
+ static #row(row, width, key) {
18
+ const prefix = row.prefix;
19
+ const head = prefix ? CodeTuiLines2.width(prefix.text) : 0;
20
+ const hang = row.hang ?? " ".repeat(head);
21
+ const body = width - Math.max(head, CodeTuiLines2.width(hang));
22
+ const wrapped = CodeTuiLines2.#wrap(row.spans, Math.max(4, body));
23
+ if (!wrapped.length)
24
+ wrapped.push([]);
25
+ return wrapped.map((spans, at) => ({
26
+ key: `${key}:${at}`,
27
+ spans: [...at === 0 ? prefix ? [prefix] : [] : hang ? [{ text: hang }] : [], ...spans]
28
+ }));
29
+ }
30
+ static #wrap(spans, width) {
31
+ const lines = [];
32
+ let line = [];
33
+ let used = 0;
34
+ let soft = false;
35
+ const push = (fromWrap) => {
36
+ lines.push(line);
37
+ line = [];
38
+ used = 0;
39
+ soft = fromWrap;
40
+ };
41
+ for (const span of spans) {
42
+ const { text, ...style } = span;
43
+ for (const piece of text.split(`
44
+ `).flatMap((part, at) => at ? [null, part] : [part])) {
45
+ if (piece === null) {
46
+ push(false);
47
+ continue;
48
+ }
49
+ for (const word of CodeTuiLines2.#words(piece)) {
50
+ const size = CodeTuiLines2.width(word);
51
+ if (!word.trim() && !used && soft)
52
+ continue;
53
+ if (used && used + size > width)
54
+ push(true);
55
+ if (size > width) {
56
+ for (const chunk of CodeTuiLines2.#chunks(word, width)) {
57
+ if (used)
58
+ push(true);
59
+ line.push({ ...style, text: chunk });
60
+ used = CodeTuiLines2.width(chunk);
61
+ if (used >= width)
62
+ push(true);
63
+ }
64
+ continue;
65
+ }
66
+ line.push({ ...style, text: word });
67
+ used += size;
68
+ }
69
+ }
70
+ }
71
+ if (line.length)
72
+ lines.push(line);
73
+ return lines;
74
+ }
75
+ static #words(text) {
76
+ return text.match(/\S+\s*|\s+/g) ?? [];
77
+ }
78
+ static #chunks(word, width) {
79
+ const chunks = [];
80
+ let chunk = "";
81
+ for (const char of word) {
82
+ if (CodeTuiLines2.width(chunk + char) > width) {
83
+ chunks.push(chunk);
84
+ chunk = char;
85
+ } else
86
+ chunk += char;
87
+ }
88
+ if (chunk)
89
+ chunks.push(chunk);
90
+ return chunks;
91
+ }
92
+ static text(line) {
93
+ return line.spans.map((span) => span.text).join("");
94
+ }
95
+ }
96
+
97
+ // pkgs/@akanjs/cli/code/CodeTuiAgents.ts
98
+ class CodeTuiAgents2 {
99
+ static markWidth = 4;
100
+ static minDescription = 12;
101
+ static rows(agents, session, width, now = Date.now()) {
102
+ if (!agents.length)
103
+ return [];
104
+ const kindColumn = Math.max(...agents.map((agent) => CodeTuiLines2.width(agent.kind))) + 2;
105
+ return [
106
+ {
107
+ key: "agents:self",
108
+ spans: [{ text: "\u276F ", color: "cyan" }, { text: "\u23FA ", color: "green" }, { text: session }]
109
+ },
110
+ ...agents.map((agent, at) => ({
111
+ key: `agents:${agent.id || at}`,
112
+ spans: CodeTuiAgents2.#row(agent, kindColumn, width, now)
113
+ }))
114
+ ];
115
+ }
116
+ static #row(agent, kindColumn, width, now) {
117
+ const meta = `${CodeTuiAgents2.elapsed(now - agent.startedAt)} \xB7 \u2193 ${CodeTuiAgents2.tokens(agent.tokens)} tokens`;
118
+ const head = CodeTuiAgents2.markWidth + kindColumn;
119
+ const room = width - head - CodeTuiLines2.width(meta) - 2;
120
+ const spans = [{ text: " \u25EF ", color: "yellow" }, { text: agent.kind.padEnd(kindColumn) }];
121
+ if (room < CodeTuiAgents2.minDescription)
122
+ return [...spans, { text: CodeTuiAgents2.#clip(agent.description, Math.max(1, width - head)) }];
123
+ const description = CodeTuiAgents2.#clip(agent.description, room);
124
+ const pad = " ".repeat(Math.max(0, room - CodeTuiLines2.width(description)));
125
+ return [...spans, { text: `${description}${pad}` }, { text: ` ${meta}`, dim: true }];
126
+ }
127
+ static elapsed(ms) {
128
+ const total = Math.max(0, Math.round(ms / 1000));
129
+ const hours = Math.floor(total / 3600);
130
+ const minutes = Math.floor(total % 3600 / 60);
131
+ const seconds = total % 60;
132
+ if (hours)
133
+ return `${hours}h ${minutes}m`;
134
+ if (minutes)
135
+ return `${minutes}m ${seconds}s`;
136
+ return `${seconds}s`;
137
+ }
138
+ static tokens(count) {
139
+ if (count < 1000)
140
+ return `${Math.max(0, Math.round(count))}`;
141
+ if (count < 1e6)
142
+ return `${(count / 1000).toFixed(1)}k`;
143
+ return `${(count / 1e6).toFixed(1)}M`;
144
+ }
145
+ static #clip(text, width) {
146
+ if (CodeTuiLines2.width(text) <= width)
147
+ return text;
148
+ let clipped = "";
149
+ for (const char of text) {
150
+ if (CodeTuiLines2.width(clipped + char) > width - 1)
151
+ break;
152
+ clipped += char;
153
+ }
154
+ return `${clipped}\u2026`;
155
+ }
156
+ }
157
+
2
158
  // pkgs/@akanjs/cli/code/CodeTuiClipboard.ts
3
159
  import { existsSync } from "fs";
4
160
  import { tmpdir } from "os";
@@ -93,7 +249,7 @@ class CodeTuiCommands2 {
93
249
  static all = [
94
250
  { name: "help", desc: "list these commands and the keys" },
95
251
  { name: "tools", desc: "what this session can call" },
96
- { name: "model", desc: "switch model", arg: "<provider>/<id>" },
252
+ { name: "model", desc: "switch model, or list what is available", arg: "[<provider>/<id>]" },
97
253
  { name: "effort", desc: "how hard the model thinks before it answers", arg: "<level>" },
98
254
  { name: "thinking", desc: "show the model's reasoning, or fold it away again" },
99
255
  { name: "compact", desc: "summarise the conversation to free the window", arg: "[notes]" },
@@ -102,6 +258,7 @@ class CodeTuiCommands2 {
102
258
  { name: "name", desc: "name this session", arg: "<text>" },
103
259
  { name: "fork", desc: "continue this conversation twice; the copy takes over here", arg: "[name]" },
104
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|login|reload]" },
105
262
  { name: "peers", desc: "the other akan code sessions running here" },
106
263
  { name: "msg", desc: "hand a message to another session", arg: "<peer> <text>" },
107
264
  { name: "quit", desc: "leave the session" }
@@ -131,109 +288,16 @@ class CodeTuiCommands2 {
131
288
  "esc interrupt \xB7 pgup/pgdn scroll \xB7 ^c quit",
132
289
  "@ completes a file in this repo \xB7 \u2190 at the start of the prompt lists past sessions",
133
290
  "",
291
+ "Scroll: the wheel scrolls this transcript \xB7 hold shift to select text with the mouse instead",
292
+ "",
134
293
  "Images: cmd+v attaches what is on the clipboard \xB7 ^v does too, without the terminal in the way",
135
294
  "",
136
- '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".'
137
296
  ].join(`
138
297
  `);
139
298
  }
140
299
  }
141
300
 
142
- // pkgs/@akanjs/cli/code/CodeTuiLines.ts
143
- import stringWidth from "string-width";
144
-
145
- class CodeTuiLines2 {
146
- static width(text) {
147
- return stringWidth(text);
148
- }
149
- static rows(rows, width, keyBase) {
150
- const lines = [];
151
- rows.forEach((row, idx) => {
152
- for (const line of CodeTuiLines2.#row(row, Math.max(8, width), `${keyBase}:${idx}`))
153
- lines.push(line);
154
- });
155
- return lines;
156
- }
157
- static #row(row, width, key) {
158
- const prefix = row.prefix;
159
- const head = prefix ? CodeTuiLines2.width(prefix.text) : 0;
160
- const hang = row.hang ?? " ".repeat(head);
161
- const body = width - Math.max(head, CodeTuiLines2.width(hang));
162
- const wrapped = CodeTuiLines2.#wrap(row.spans, Math.max(4, body));
163
- if (!wrapped.length)
164
- wrapped.push([]);
165
- return wrapped.map((spans, at) => ({
166
- key: `${key}:${at}`,
167
- spans: [...at === 0 ? prefix ? [prefix] : [] : hang ? [{ text: hang }] : [], ...spans]
168
- }));
169
- }
170
- static #wrap(spans, width) {
171
- const lines = [];
172
- let line = [];
173
- let used = 0;
174
- let soft = false;
175
- const push = (fromWrap) => {
176
- lines.push(line);
177
- line = [];
178
- used = 0;
179
- soft = fromWrap;
180
- };
181
- for (const span of spans) {
182
- const { text, ...style } = span;
183
- for (const piece of text.split(`
184
- `).flatMap((part, at) => at ? [null, part] : [part])) {
185
- if (piece === null) {
186
- push(false);
187
- continue;
188
- }
189
- for (const word of CodeTuiLines2.#words(piece)) {
190
- const size = CodeTuiLines2.width(word);
191
- if (!word.trim() && !used && soft)
192
- continue;
193
- if (used && used + size > width)
194
- push(true);
195
- if (size > width) {
196
- for (const chunk of CodeTuiLines2.#chunks(word, width)) {
197
- if (used)
198
- push(true);
199
- line.push({ ...style, text: chunk });
200
- used = CodeTuiLines2.width(chunk);
201
- if (used >= width)
202
- push(true);
203
- }
204
- continue;
205
- }
206
- line.push({ ...style, text: word });
207
- used += size;
208
- }
209
- }
210
- }
211
- if (line.length)
212
- lines.push(line);
213
- return lines;
214
- }
215
- static #words(text) {
216
- return text.match(/\S+\s*|\s+/g) ?? [];
217
- }
218
- static #chunks(word, width) {
219
- const chunks = [];
220
- let chunk = "";
221
- for (const char of word) {
222
- if (CodeTuiLines2.width(chunk + char) > width) {
223
- chunks.push(chunk);
224
- chunk = char;
225
- } else
226
- chunk += char;
227
- }
228
- if (chunk)
229
- chunks.push(chunk);
230
- return chunks;
231
- }
232
- static text(line) {
233
- return line.spans.map((span) => span.text).join("");
234
- }
235
- }
236
-
237
301
  // pkgs/@akanjs/cli/code/CodeTuiEditor.ts
238
302
  class CodeTuiEditor2 {
239
303
  #text = "";
@@ -271,6 +335,8 @@ class CodeTuiEditor2 {
271
335
  this.set(this.#text.slice(0, this.#caret) + clean + this.#text.slice(this.#caret), this.#caret + clean.length);
272
336
  }
273
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);
274
340
  this.insert(`
275
341
  `);
276
342
  }
@@ -724,4 +790,4 @@ class CodeTuiParts2 {
724
790
  }
725
791
  }
726
792
 
727
- export { CodeTuiClipboard2, CodeTuiCommands2, CodeTuiLines2, CodeTuiEditor2, CodeTuiFiles2, CodeTuiMarkdown2, CodeTuiParts2 };
793
+ export { CodeTuiLines2, CodeTuiAgents2, CodeTuiClipboard2, CodeTuiCommands2, CodeTuiEditor2, CodeTuiFiles2, CodeTuiMarkdown2, CodeTuiParts2 };
@@ -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 };
@@ -1141,13 +1141,6 @@ export async function generateHead(props: PageProps) {
1141
1141
  return inheritedLayout.head;
1142
1142
  }
1143
1143
 
1144
- export async function generateMetadata(props: PageProps) {
1145
- if (userLayout.generateMetadata) return userLayout.generateMetadata(props);
1146
- if (userLayout.metadata !== undefined) return userLayout.metadata;
1147
- if (inheritedLayout.generateMetadata) return inheritedLayout.generateMetadata(props);
1148
- return inheritedLayout.metadata;
1149
- }
1150
-
1151
1144
  export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
1152
1145
  export const Error = userLayout.Error ?? inheritedLayout.Error;
1153
1146
  export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
@@ -1164,7 +1157,6 @@ ${layoutBinding} return (
1164
1157
  theme={userLayout.theme ?? inheritedLayout.theme}
1165
1158
  fonts={loadFonts(userFonts)}
1166
1159
  className={defaultFontClassName}
1167
- gaTrackingId={userLayout.gaTrackingId ?? inheritedLayout.gaTrackingId}
1168
1160
  layoutStyle={userLayout.layoutStyle ?? inheritedLayout.layoutStyle}
1169
1161
  reconnect={userLayout.reconnect ?? inheritedLayout.reconnect ?? false}
1170
1162
  wsConnect={userLayout.wsConnect ?? inheritedLayout.wsConnect ?? true}
@@ -1185,13 +1177,6 @@ export async function generateHead(props: PageProps) {
1185
1177
  return inheritedLayout.head;
1186
1178
  }
1187
1179
 
1188
- export async function generateMetadata(props: PageProps) {
1189
- if (userLayout.generateMetadata) return userLayout.generateMetadata(props);
1190
- if (userLayout.metadata !== undefined) return userLayout.metadata;
1191
- if (inheritedLayout.generateMetadata) return inheritedLayout.generateMetadata(props);
1192
- return inheritedLayout.metadata;
1193
- }
1194
-
1195
1180
  export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
1196
1181
  export const Error = userLayout.Error ?? inheritedLayout.Error;
1197
1182
  export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
@@ -2139,11 +2124,12 @@ class PkgInfo {
2139
2124
  const [tsconfig, rootPackageJson] = await Promise.all([exec.getTsConfig(), exec.workspace.getPackageJson()]);
2140
2125
  const scanner = await createDependencyScanner(exec);
2141
2126
  const npmSet = new Set(Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }));
2142
- const pkgPathSet = new Set(Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path) => tsconfig.compilerOptions.paths?.[path]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path) => path.replace("/*", "")));
2127
+ const workspacePathOf = (resolve) => resolve.replace(/^\.\//, "");
2128
+ const pkgPathSet = new Set(Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path) => tsconfig.compilerOptions.paths?.[path]?.some((resolve) => workspacePathOf(resolve).startsWith("pkgs/"))).map((path) => path.replace("/*", "")));
2143
2129
  const [npmDepSet, pkgPathDepSet] = await scanner.getImportSets([npmSet, pkgPathSet]);
2144
2130
  const pkgDeps = [...pkgPathDepSet].map((path) => {
2145
2131
  const pathSplitLength = path.split("/").length;
2146
- return (tsconfig.compilerOptions.paths?.[path]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
2132
+ return workspacePathOf(tsconfig.compilerOptions.paths?.[path]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
2147
2133
  }).filter((pkg) => pkg !== exec.name);
2148
2134
  const pkgScanResult = {
2149
2135
  name: exec.name,
@@ -3255,7 +3241,7 @@ class SysExecutor extends Executor {
3255
3241
  class AppExecutor extends SysExecutor {
3256
3242
  static #routeSourceValidator = null;
3257
3243
  static async#getRouteSourceValidator() {
3258
- AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-apyqw7wk.js")).RouteSourceValidator;
3244
+ AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-7ycnfz0e.js")).RouteSourceValidator;
3259
3245
  return AppExecutor.#routeSourceValidator;
3260
3246
  }
3261
3247
  dist;
@@ -1,14 +1,14 @@
1
1
  // @bun
2
2
  import {
3
3
  AppExecutor
4
- } from "./index-p4p9t45x.js";
4
+ } from "./index-bwxpk2cj.js";
5
5
  import {
6
6
  jsonText,
7
7
  createWorkflowBaselineSummary,
8
8
  buildAkanModuleContextIndex,
9
9
  createWorkflowStepRegistry,
10
10
  toolingRolloutGate
11
- } from "./index-qhtj9y6j.js";
11
+ } from "./index-yw6g3bbv.js";
12
12
  import {
13
13
  buildResourceList,
14
14
  codexMcpConfigPath,
@@ -18,32 +18,32 @@ import {
18
18
  upsertCodexMcpServerBlock,
19
19
  renderDoctorText,
20
20
  AkanContextAnalyzer
21
- } from "./index-v17gj504.js";
21
+ } from "./index-rpgxs245.js";
22
22
  import {
23
23
  isPlaceholderAppId2
24
- } from "./index-3cymrzsb.js";
24
+ } from "./index-erfc1x40.js";
25
25
  import {
26
26
  CommandContainer,
27
27
  runner
28
- } from "./index-6na0sd2b.js";
28
+ } from "./index-ycy302an.js";
29
29
  import {
30
30
  Prompter2
31
- } from "./index-twq9p2sp.js";
31
+ } from "./index-s5rhm04y.js";
32
32
  import {
33
33
  RepairRunner
34
- } from "./index-4cvpzkq6.js";
34
+ } from "./index-ef228gzf.js";
35
35
  import {
36
36
  WorkflowRunner
37
- } from "./index-2pm1j01n.js";
37
+ } from "./index-zmj143x7.js";
38
38
  import {
39
39
  ModuleScript
40
- } from "./index-xjc7gg65.js";
40
+ } from "./index-pn8mhpps.js";
41
41
  import {
42
42
  PrimitiveScript
43
- } from "./index-te0y1c0m.js";
43
+ } from "./index-d9fjz06h.js";
44
44
  import {
45
45
  ScalarScript
46
- } from "./index-vpx68e4x.js";
46
+ } from "./index-q9c3c0hy.js";
47
47
  import {
48
48
  getMobileTargets
49
49
  } from "./index-47pj3aee.js";
@@ -1021,7 +1021,7 @@ ${payload}`);
1021
1021
  test: "`akan test <app-or-lib-or-pkg>` prepares the target and runs its tests.",
1022
1022
  build: "`akan build <app-name>` creates a production build after preparing generated files.",
1023
1023
  doctor: "`akan doctor --strict --format json` reports agent-readable workspace convention diagnostics and validation hints.",
1024
- "guideline show": "`akan guideline show <name>` prints an Akan codegen guideline instruction.",
1024
+ "guideline show": "`akan guideline show <name>` prints an Akan guideline instruction.",
1025
1025
  workflow: "`akan workflow list|explain|plan|apply|validate|report` lists, plans, applies, validates, and reports agent-readable Akan workflows.",
1026
1026
  "workflow list": "`akan workflow list` lists parseable read-only workflow specs.",
1027
1027
  "workflow explain": "`akan workflow explain <workflow>` explains inputs, optional surfaces, steps, and validation.",
@@ -1,12 +1,12 @@
1
1
  // @bun
2
2
  import {
3
3
  script
4
- } from "./index-6na0sd2b.js";
4
+ } from "./index-ycy302an.js";
5
5
  import {
6
6
  AppExecutor,
7
7
  LibExecutor,
8
8
  ModuleExecutor
9
- } from "./index-p4p9t45x.js";
9
+ } from "./index-bwxpk2cj.js";
10
10
  import {
11
11
  compactDiagnostics,
12
12
  createPrimitiveWriteReport,
@@ -18,6 +18,8 @@ import {
18
18
  nextActionsForTarget,
19
19
  lowerlize,
20
20
  normalizeFieldType,
21
+ ensureNamedImport,
22
+ ensureBaseImport,
21
23
  ensureBaseTypeImport,
22
24
  coerceFieldDefault,
23
25
  fieldExpression,
@@ -39,10 +41,10 @@ import {
39
41
  hasSignalFactoryEntry,
40
42
  insertSignalFactoryEntry,
41
43
  addFieldUiPolicyForType
42
- } from "./index-qhtj9y6j.js";
44
+ } from "./index-yw6g3bbv.js";
43
45
  import {
44
46
  ModuleScript
45
- } from "./index-xjc7gg65.js";
47
+ } from "./index-pn8mhpps.js";
46
48
 
47
49
  // pkgs/@akanjs/cli/primitive/primitive.script.ts
48
50
  import { capitalize } from "akanjs/common";
@@ -210,6 +212,8 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
210
212
  if (defaultCoercion.diagnostic)
211
213
  diagnostics.push(defaultCoercion.diagnostic);
212
214
  constantContent = ensureBaseTypeImport(constantContent, input.type);
215
+ if (input.type === "Date" && defaultCoercion.expression)
216
+ constantContent = ensureBaseImport(constantContent, "dayjs");
213
217
  }
214
218
  if (enumValues) {
215
219
  const defaultCoercion = coerceFieldDefault("enum", input.defaultValue, { enumValues });
@@ -353,7 +357,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
353
357
  signal: name ? {
354
358
  className: `${moduleClassName}Endpoint`,
355
359
  entryLine: [
356
- `${name}: mutation(Boolean)`,
360
+ `${name}: mutation(Boolean, { guards: [None] })`,
357
361
  ` .exec(async function () {`,
358
362
  ` return await this.${serviceRef}Service.${name}();`,
359
363
  ` }),`
@@ -388,7 +392,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
388
392
  signal: name && queryName ? {
389
393
  className: `${moduleClassName}Slice`,
390
394
  entryLine: [
391
- `${name}: init()`,
395
+ `${name}: init({ guards: [None] })`,
392
396
  ` .exec(function () {`,
393
397
  ` return this.${serviceRef}Service.${queryName}();`,
394
398
  ` }),`
@@ -476,7 +480,8 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
476
480
  });
477
481
  }
478
482
  const nextServiceContent = serviceMethodExists ? serviceContent : insertClassMethod(serviceContent, serviceClassName, spec.serviceMethod.block);
479
- const nextSignalContent = insertSignalFactoryEntry(signalContent, spec.signal.className, spec.entryName, spec.signal.entryLine, spec.signal.param);
483
+ const insertedSignalContent = insertSignalFactoryEntry(signalContent, spec.signal.className, spec.entryName, spec.signal.entryLine, spec.signal.param);
484
+ const nextSignalContent = insertedSignalContent ? ensureNamedImport(insertedSignalContent, "akanjs/signal", "None") : insertedSignalContent;
480
485
  if (!nextServiceContent) {
481
486
  diagnostics.push({
482
487
  severity: "error",
@@ -1,16 +1,16 @@
1
1
  // @bun
2
2
  import {
3
3
  jsonText
4
- } from "./index-qhtj9y6j.js";
4
+ } from "./index-yw6g3bbv.js";
5
5
  import {
6
6
  akanMcpInstallTargets
7
- } from "./index-v17gj504.js";
7
+ } from "./index-rpgxs245.js";
8
8
  import {
9
9
  script
10
- } from "./index-6na0sd2b.js";
10
+ } from "./index-ycy302an.js";
11
11
  import {
12
12
  ContextRunner2
13
- } from "./index-g9zghs4h.js";
13
+ } from "./index-cjw1sj1x.js";
14
14
 
15
15
  // pkgs/@akanjs/cli/context/context.script.ts
16
16
  import { Logger } from "akanjs/common";