@akanjs/cli 3.0.0-alpha.11 → 3.0.0-alpha.110

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 (140) hide show
  1. package/.build-stamp +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +1 -1
  4. package/{abstractCompactor-e5yq60qz.js → abstractCompactor-mjh5ppsq.js} +3 -5
  5. package/{agent.command-a3n15c6t.js → agent.command-d2gfxfck.js} +11 -13
  6. package/{application.command-rdm3et0g.js → application.command-pj2m7584.js} +65 -38
  7. package/{applicationBuildRunner-6m8n71w4.js → applicationBuildRunner-kxwbssgn.js} +27 -23
  8. package/{applicationReleasePackager-gg8ccbeh.js → applicationReleasePackager-4yasxwv9.js} +8 -9
  9. package/buildBatch.proc.js +12 -14
  10. package/capacitorApp-36rbr858.js +12 -0
  11. package/{cloud.command-56aeekqn.js → cloud.command-gxqp8xdv.js} +15 -18
  12. package/commandManifest.json +1 -1
  13. package/{context.command-ysxawe7h.js → context.command-ez8a0zyz.js} +19 -23
  14. package/dependencyScanner-shs82ynp.js +8 -0
  15. package/devTui-40ggmd99.js +553 -0
  16. package/devTuiView-c08ccbat.js +9 -0
  17. package/getDirname-dr3jz1xg.js +7 -0
  18. package/{guideline.command-yqf9a372.js → guideline.command-xmqwx8zm.js} +24 -22
  19. package/guidelines/agentRule/agentRule.generate.json +31 -0
  20. package/guidelines/agentRule/agentRule.instruction.md +531 -0
  21. package/guidelines/conventions/conventions.instruction.md +493 -369
  22. package/guidelines/framework/framework.generate.json +3 -2
  23. package/guidelines/framework/framework.instruction.md +0 -9
  24. package/guidelines/mcpRule/mcpRule.generate.json +35 -0
  25. package/guidelines/mcpRule/mcpRule.instruction.md +460 -0
  26. package/guidelines/modelStore/modelStore.instruction.md +12 -0
  27. package/guidelines/modelTemplate/modelTemplate.instruction.md +5 -0
  28. package/guidelines/queryRule/queryRule.generate.json +31 -0
  29. package/guidelines/queryRule/queryRule.instruction.md +178 -0
  30. package/guidelines/runtimeRule/runtimeRule.generate.json +25 -0
  31. package/guidelines/runtimeRule/runtimeRule.instruction.md +220 -0
  32. package/guidelines/ssrRule/ssrRule.instruction.md +51 -5
  33. package/guidelines/transportRule/transportRule.generate.json +31 -0
  34. package/guidelines/transportRule/transportRule.instruction.md +60 -0
  35. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +54 -764
  36. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +33 -0
  37. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +467 -0
  38. package/incrementalBuilder.proc.js +26 -25
  39. package/{index-8pd02prk.js → index-259dsnz3.js} +58 -25
  40. package/{index-yzsxc30b.js → index-2tv3fdx4.js} +975 -234
  41. package/index-3d9y066c.js +76 -0
  42. package/{index-76rn3g2c.js → index-47pj3aee.js} +4 -4
  43. package/{index-m90fn8xe.js → index-4edzf1gr.js} +32 -32
  44. package/{index-3789fdpg.js → index-600zhnve.js} +94 -61
  45. package/{index-1577bej2.js → index-6wwzs1bc.js} +2 -2
  46. package/{index-cv9cxs5k.js → index-7737gxcp.js} +18 -18
  47. package/{index-a5cs7d8r.js → index-8few9nyh.js} +13 -13
  48. package/{index-mewacxye.js → index-8pm30m73.js} +57 -57
  49. package/{index-wnp7hwq7.js → index-92zztqy1.js} +7 -7
  50. package/{index-fgc8r6dj.js → index-a5vmm6x4.js} +3 -1
  51. package/{index-cav1azma.js → index-a64esmtb.js} +1106 -1369
  52. package/{index-nwqqssnb.js → index-aj7tyh5w.js} +26 -23
  53. package/{index-xys926f2.js → index-by5gpp8x.js} +4 -4
  54. package/{index-yzmqvg23.js → index-fz5q3gd7.js} +8 -8
  55. package/{index-kcsa1zff.js → index-gyd220p2.js} +4 -4
  56. package/{index-j37qq1f2.js → index-h7yw2z9n.js} +7 -7
  57. package/{index-bjpxzr6s.js → index-hwkygn9s.js} +51 -3
  58. package/index-j9yhg404.js +159 -0
  59. package/{index-46tjzh6s.js → index-kcxmv48c.js} +29 -29
  60. package/{index-0cj2zxbm.js → index-kn1h7p1x.js} +12 -11
  61. package/{index-e4b2ae6b.js → index-ktb5njgy.js} +41 -34
  62. package/{index-etwh7sd3.js → index-mak3cd28.js} +100 -32
  63. package/{index-xjd3rqzj.js → index-n68jx79w.js} +6 -15
  64. package/{index-z1s5f4e0.js → index-ne2qy0nk.js} +36 -37
  65. package/{index-65aeh789.js → index-pnqbkf5p.js} +1 -1
  66. package/{index-67546d0j.js → index-q0y2jq9j.js} +14 -2
  67. package/{index-4mgkgba3.js → index-rwg2aa4f.js} +14 -14
  68. package/{index-bzznxgcx.js → index-v0qh106m.js} +1002 -128
  69. package/{index-j9cxndc0.js → index-w8kmx1b6.js} +20 -11
  70. package/{index-h5whaj26.js → index-ws5e0j51.js} +16 -12
  71. package/{index-9va8zayb.js → index-wt7qrtd4.js} +27 -27
  72. package/index.js +22 -25
  73. package/{library.command-x6t29a30.js → library.command-nbsky672.js} +11 -10
  74. package/{localRegistry.command-649g1n7b.js → localRegistry.command-ts6t5e5a.js} +20 -23
  75. package/{module.command-8w8ys5t3.js → module.command-29vqzrh8.js} +13 -16
  76. package/{package.command-zgy7f3fz.js → package.command-axv0abmn.js} +8 -10
  77. package/package.json +5 -7
  78. package/{page.command-yjmnkyk2.js → page.command-vs9s3zrh.js} +7 -9
  79. package/{primitive.command-gfqaagsg.js → primitive.command-cbxmqbtc.js} +13 -16
  80. package/{quality.command-ec8r1dn3.js → quality.command-gmbs7nws.js} +184 -334
  81. package/recipeScanner-fpagtgc1.js +11 -0
  82. package/{repair.command-p9ey6mkm.js → repair.command-bqsjptsj.js} +12 -14
  83. package/{routeSourceValidator-e4jmbfcx.js → routeSourceValidator-apyqw7wk.js} +90 -19
  84. package/{scalar.command-9dhmqhtm.js → scalar.command-6k1vhe9s.js} +11 -14
  85. package/subspace.command-35a3t6vv.js +755 -0
  86. package/templates/app/env/env.client.debug.ts.template +1 -5
  87. package/templates/app/env/env.client.develop.ts.template +1 -5
  88. package/templates/app/env/env.client.local.ts.template +1 -5
  89. package/templates/app/env/env.client.main.ts.template +1 -5
  90. package/templates/app/env/env.client.testing.ts.template +1 -5
  91. package/templates/app/env/env.client.type.ts +2 -6
  92. package/templates/app/env/env.server.debug.ts.template +1 -5
  93. package/templates/app/env/env.server.develop.ts.template +1 -5
  94. package/templates/app/env/env.server.local.ts.template +1 -5
  95. package/templates/app/env/env.server.main.ts.template +1 -5
  96. package/templates/app/main.ts +3 -1
  97. package/templates/app/page/_index.tsx +3 -3
  98. package/templates/app/page/_layout.tsx +31 -32
  99. package/templates/appSample/lib/task/task.signal.ts +11 -6
  100. package/templates/appSample/page/task/[taskId]/_index.tsx +22 -27
  101. package/templates/appSample/page/task/[taskId]/edit.tsx +25 -30
  102. package/templates/appSample/page/task/_index.tsx +3 -7
  103. package/templates/appSample/page/task/_layout.tsx +4 -15
  104. package/templates/appSample/page/task/new.tsx +4 -10
  105. package/templates/appSample/srvkit/AuthGuard.ts +2 -2
  106. package/templates/crudPages/[__model__Id]/edit/page.tsx +27 -29
  107. package/templates/crudPages/[__model__Id]/page.tsx +24 -32
  108. package/templates/crudPages/new/page.tsx +26 -25
  109. package/templates/crudPages/page.tsx +27 -26
  110. package/templates/crudSinglePage/page.tsx +26 -21
  111. package/templates/env/_env.server.type.ts +7 -5
  112. package/templates/lib/db.ts +1 -1
  113. package/templates/lib/dict.ts +1 -1
  114. package/templates/lib/sig.ts +5 -1
  115. package/templates/lib/srv.ts +6 -2
  116. package/templates/module/__model__.dictionary.ts +4 -1
  117. package/templates/module/__model__.signal.ts +2 -3
  118. package/templates/module/__model__.store.ts +1 -2
  119. package/templates/workspaceRoot/.gitignore.template +0 -1
  120. package/templates/workspaceRoot/.husky/pre-commit.template +16 -0
  121. package/templates/workspaceRoot/.vscode/settings.json.template +1 -1
  122. package/templates/workspaceRoot/AGENTS.md.template +4 -0
  123. package/templates/workspaceRoot/CLAUDE.md.template +19 -0
  124. package/templates/workspaceRoot/biome.json.template +1 -1
  125. package/templates/workspaceRoot/docs/AI-DEVELOPMENT.md.template +10 -14
  126. package/templates/workspaceRoot/docs/GENERATED.md.template +12 -10
  127. package/templates/workspaceRoot/package.json.template +2 -4
  128. package/typeChecker-3xgrzc2v.js +7 -0
  129. package/typecheck.proc.js +4 -5
  130. package/{workflow.command-ycwc6zr6.js → workflow.command-nwpcdc8p.js} +22 -25
  131. package/{workspace.command-xhyhajxa.js → workspace.command-aczjxzbf.js} +64 -66
  132. package/capacitorApp-mr81qdxq.js +0 -61
  133. package/dependencyScanner-f6grrep3.js +0 -9
  134. package/getDirname-m9s0cmhq.js +0 -8
  135. package/index-mxvakhsm.js +0 -66
  136. package/index-r24hmh0q.js +0 -4
  137. package/recipeScanner-tghkzrrt.js +0 -12
  138. package/typeChecker-kravn7ns.js +0 -8
  139. /package/{index-0wae5ebk.js → index-meh558jy.js} +0 -0
  140. /package/{index-ss469dec.js → index-nz8prx9g.js} +0 -0
@@ -0,0 +1,553 @@
1
+ // @bun
2
+ import {
3
+ openBrowser,
4
+ plainTextOf,
5
+ HOST_SOURCE,
6
+ DevLogBuffer
7
+ } from "./index-v0qh106m.js";
8
+
9
+ // pkgs/@akanjs/cli/application/devTui.tsx
10
+ import { render } from "ink";
11
+
12
+ // pkgs/@akanjs/cli/clipboard.ts
13
+ var clipboardCommands = () => {
14
+ if (process.platform === "darwin")
15
+ return [["pbcopy"]];
16
+ if (process.platform === "win32")
17
+ return [["clip"]];
18
+ return [["wl-copy"], ["xclip", "-selection", "clipboard"], ["xsel", "--clipboard", "--input"]];
19
+ };
20
+ var writeClipboard = async (text) => {
21
+ for (const command of clipboardCommands()) {
22
+ try {
23
+ const proc = Bun.spawn(command, {
24
+ stdin: new TextEncoder().encode(text),
25
+ stdout: "ignore",
26
+ stderr: "ignore"
27
+ });
28
+ if (await proc.exited === 0)
29
+ return true;
30
+ } catch {}
31
+ }
32
+ return false;
33
+ };
34
+
35
+ // pkgs/@akanjs/cli/ui/DevTuiApp.tsx
36
+ import { Box, Text, useInput } from "ink";
37
+ import { useEffect, useState } from "react";
38
+ import { jsxDEV } from "react/jsx-dev-runtime";
39
+ var stateGlyph = {
40
+ starting: { glyph: "\u25D0", color: "yellow" },
41
+ ready: { glyph: "\u25CF", color: "green" },
42
+ restarting: { glyph: "\u25D0", color: "yellow" },
43
+ recovering: { glyph: "\u25D0", color: "yellow" },
44
+ suspended: { glyph: "\u25CC", color: "blue" },
45
+ failed: { glyph: "\u2717", color: "red" },
46
+ stopped: { glyph: "\u25CB", color: "gray" }
47
+ };
48
+ var Rail = ({ rows, selected, readyCount, appCount, width, height }) => /* @__PURE__ */ jsxDEV(Box, {
49
+ flexDirection: "column",
50
+ width,
51
+ height,
52
+ borderStyle: "round",
53
+ borderColor: "gray",
54
+ paddingX: 1,
55
+ children: [
56
+ /* @__PURE__ */ jsxDEV(Text, {
57
+ dimColor: true,
58
+ children: [
59
+ "apps ",
60
+ readyCount,
61
+ "/",
62
+ appCount
63
+ ]
64
+ }, undefined, true, undefined, this),
65
+ /* @__PURE__ */ jsxDEV(Box, {
66
+ flexDirection: "column",
67
+ flexGrow: 1,
68
+ children: rows.map((row, idx) => {
69
+ const marker = row.state ? stateGlyph[row.state] : null;
70
+ return /* @__PURE__ */ jsxDEV(Text, {
71
+ inverse: idx === selected,
72
+ wrap: "truncate",
73
+ children: [
74
+ marker ? /* @__PURE__ */ jsxDEV(Text, {
75
+ color: marker.color,
76
+ children: marker.glyph
77
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(Text, {
78
+ dimColor: true,
79
+ children: "\u25C7"
80
+ }, undefined, false, undefined, this),
81
+ /* @__PURE__ */ jsxDEV(Text, {
82
+ dimColor: true,
83
+ children: " ".repeat(row.depth * 2 + 1)
84
+ }, undefined, false, undefined, this),
85
+ row.appIndex === null ? null : /* @__PURE__ */ jsxDEV(Text, {
86
+ dimColor: true,
87
+ children: `${row.appIndex} `
88
+ }, undefined, false, undefined, this),
89
+ row.label,
90
+ row.port === null ? null : /* @__PURE__ */ jsxDEV(Text, {
91
+ dimColor: true,
92
+ children: ` ${row.port}`
93
+ }, undefined, false, undefined, this)
94
+ ]
95
+ }, `${row.app ?? "*"}/${row.source ?? "*"}`, true, undefined, this);
96
+ })
97
+ }, undefined, false, undefined, this)
98
+ ]
99
+ }, undefined, true, undefined, this);
100
+ var LogPane = ({ lines, title, above, below, following, prefix, prefixWidth, width, height }) => /* @__PURE__ */ jsxDEV(Box, {
101
+ flexDirection: "column",
102
+ width,
103
+ height,
104
+ borderStyle: "round",
105
+ borderColor: following ? "gray" : "cyan",
106
+ paddingX: 1,
107
+ children: [
108
+ /* @__PURE__ */ jsxDEV(Text, {
109
+ wrap: "truncate",
110
+ children: [
111
+ title,
112
+ following ? null : /* @__PURE__ */ jsxDEV(Text, {
113
+ color: "cyan",
114
+ children: ` \u25B2${above} \u25BC${below} paused`
115
+ }, undefined, false, undefined, this)
116
+ ]
117
+ }, undefined, true, undefined, this),
118
+ /* @__PURE__ */ jsxDEV(Box, {
119
+ flexDirection: "column",
120
+ flexGrow: 1,
121
+ children: lines.map((line) => /* @__PURE__ */ jsxDEV(Text, {
122
+ wrap: "truncate",
123
+ children: [
124
+ prefix === "none" ? null : /* @__PURE__ */ jsxDEV(Text, {
125
+ dimColor: true,
126
+ children: `${(prefix === "app" ? line.app : line.source).padEnd(prefixWidth)} \u2502 `
127
+ }, undefined, false, undefined, this),
128
+ line.text
129
+ ]
130
+ }, line.seq, true, undefined, this))
131
+ }, undefined, false, undefined, this)
132
+ ]
133
+ }, undefined, true, undefined, this);
134
+ var DevTuiApp = ({ actions }) => {
135
+ const [snapshot, setSnapshot] = useState(actions.snapshot);
136
+ useEffect(() => {
137
+ const unsubscribe = actions.subscribe(() => setSnapshot(actions.snapshot()));
138
+ setSnapshot(actions.snapshot());
139
+ return unsubscribe;
140
+ }, [actions]);
141
+ useInput((input, key) => {
142
+ if (snapshot.editingGrep) {
143
+ if (key.escape) {
144
+ actions.setGrep("");
145
+ actions.setEditingGrep(false);
146
+ } else if (key.return)
147
+ actions.setEditingGrep(false);
148
+ else if (key.backspace || key.delete)
149
+ actions.setGrep(snapshot.grep.slice(0, -1));
150
+ else if (input && !key.ctrl && !key.meta)
151
+ actions.setGrep(snapshot.grep + input);
152
+ return;
153
+ }
154
+ const page = Math.max(1, snapshot.logRows - 1);
155
+ if (input === "q" || key.ctrl && input === "c")
156
+ actions.quit();
157
+ else if (key.upArrow)
158
+ actions.scroll(key.shift ? -page : -1);
159
+ else if (key.downArrow)
160
+ actions.scroll(key.shift ? page : 1);
161
+ else if (key.pageUp)
162
+ actions.scroll(-page);
163
+ else if (key.pageDown)
164
+ actions.scroll(page);
165
+ else if (input === "G" || input === "f")
166
+ actions.follow();
167
+ else if (key.tab)
168
+ actions.moveSelection(key.shift ? -1 : 1);
169
+ else if (input === "/")
170
+ actions.setEditingGrep(true);
171
+ else if (input === "e")
172
+ actions.toggleErrorsOnly();
173
+ else if (input === "c")
174
+ actions.clear();
175
+ else if (input === "y")
176
+ actions.copyLines();
177
+ else if (input === "Y")
178
+ actions.copyPath();
179
+ else if (input === "o")
180
+ actions.openSelected();
181
+ else if (input === "r")
182
+ actions.restartSelected();
183
+ else if (/^[1-9]$/.test(input))
184
+ actions.selectApp(Number(input) - 1);
185
+ });
186
+ return /* @__PURE__ */ jsxDEV(Box, {
187
+ flexDirection: "column",
188
+ width: snapshot.columns,
189
+ height: snapshot.terminalRows,
190
+ children: [
191
+ /* @__PURE__ */ jsxDEV(Box, {
192
+ flexDirection: "row",
193
+ height: snapshot.bodyHeight,
194
+ children: [
195
+ /* @__PURE__ */ jsxDEV(Rail, {
196
+ rows: snapshot.rows,
197
+ selected: snapshot.selected,
198
+ readyCount: snapshot.readyCount,
199
+ appCount: snapshot.appCount,
200
+ width: snapshot.railWidth,
201
+ height: snapshot.bodyHeight
202
+ }, undefined, false, undefined, this),
203
+ /* @__PURE__ */ jsxDEV(LogPane, {
204
+ lines: snapshot.lines,
205
+ title: snapshot.title,
206
+ above: snapshot.above,
207
+ below: snapshot.below,
208
+ following: snapshot.following,
209
+ prefix: snapshot.prefix,
210
+ prefixWidth: snapshot.prefixWidth,
211
+ width: Math.max(20, snapshot.columns - snapshot.railWidth),
212
+ height: snapshot.bodyHeight
213
+ }, undefined, false, undefined, this)
214
+ ]
215
+ }, undefined, true, undefined, this),
216
+ snapshot.editingGrep ? /* @__PURE__ */ jsxDEV(Text, {
217
+ children: [
218
+ /* @__PURE__ */ jsxDEV(Text, {
219
+ color: "cyan",
220
+ children: "grep "
221
+ }, undefined, false, undefined, this),
222
+ snapshot.grep,
223
+ /* @__PURE__ */ jsxDEV(Text, {
224
+ inverse: true,
225
+ children: " "
226
+ }, undefined, false, undefined, this),
227
+ /* @__PURE__ */ jsxDEV(Text, {
228
+ dimColor: true,
229
+ children: " enter to apply \xB7 esc to clear"
230
+ }, undefined, false, undefined, this)
231
+ ]
232
+ }, undefined, true, undefined, this) : snapshot.notice ? /* @__PURE__ */ jsxDEV(Text, {
233
+ color: "cyan",
234
+ wrap: "truncate",
235
+ children: snapshot.notice
236
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(Text, {
237
+ dimColor: true,
238
+ wrap: "truncate",
239
+ children: `Tab next \xB7 1-9 app \xB7 \u2191\u2193 scroll (shift page) \xB7 G follow${snapshot.following ? "" : " (paused)"} \xB7 / grep${snapshot.grep ? ` (${snapshot.grep})` : ""} \xB7 e errors${snapshot.errorsOnly ? " on" : ""} \xB7 c clear \xB7 y copy \xB7 Y path \xB7 o open \xB7 r restart \xB7 q quit`
240
+ }, undefined, false, undefined, this)
241
+ ]
242
+ }, undefined, true, undefined, this);
243
+ };
244
+
245
+ // pkgs/@akanjs/cli/application/devLogWindow.ts
246
+ var windowOf = (lines, rows, anchor) => {
247
+ const height = Math.max(1, Math.trunc(rows));
248
+ const end = anchor === null ? lines.length : endOf(lines, height, anchor);
249
+ const start = Math.max(0, end - height);
250
+ return {
251
+ lines: lines.slice(start, end),
252
+ above: start,
253
+ below: lines.length - end,
254
+ following: anchor === null
255
+ };
256
+ };
257
+ var scrollAnchor = (lines, rows, anchor, delta) => {
258
+ const height = Math.max(1, Math.trunc(rows));
259
+ if (lines.length <= height)
260
+ return null;
261
+ const end = anchor === null ? lines.length : endOf(lines, height, anchor);
262
+ const next = Math.min(lines.length, Math.max(height, end + Math.trunc(delta)));
263
+ if (next >= lines.length)
264
+ return null;
265
+ return lines[next - 1]?.seq ?? null;
266
+ };
267
+ var endOf = (lines, height, anchor) => {
268
+ for (let idx = lines.length - 1;idx >= 0; idx -= 1) {
269
+ const line = lines[idx];
270
+ if (line && line.seq <= anchor)
271
+ return idx + 1;
272
+ }
273
+ return Math.min(lines.length, height);
274
+ };
275
+
276
+ // pkgs/@akanjs/cli/application/devTui.tsx
277
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
278
+
279
+ class DevTui {
280
+ static frameMs = 34;
281
+ static footerRows = 1;
282
+ static paneChromeRows = 3;
283
+ static noticeMs = 4000;
284
+ #buffer = new DevLogBuffer;
285
+ #listeners = new Set;
286
+ #supervisor;
287
+ #instance;
288
+ #statuses = [];
289
+ #target = { app: null, source: null };
290
+ #anchor = null;
291
+ #grep = "";
292
+ #editingGrep = false;
293
+ #errorsOnly = false;
294
+ #frameTimer = null;
295
+ #cachedSnapshot = null;
296
+ #notice = "";
297
+ #noticeTimer = null;
298
+ constructor(supervisor) {
299
+ this.#supervisor = supervisor;
300
+ this.#statuses = supervisor.statuses;
301
+ process.stdout.on("resize", this.#onResize);
302
+ this.#instance = render(/* @__PURE__ */ jsxDEV2(DevTuiApp, {
303
+ actions: {
304
+ subscribe: this.#subscribe,
305
+ snapshot: this.#snapshot,
306
+ moveSelection: this.#moveSelection,
307
+ selectApp: this.#selectApp,
308
+ scroll: this.#scroll,
309
+ follow: this.#follow,
310
+ setGrep: this.#setGrep,
311
+ setEditingGrep: this.#setEditingGrep,
312
+ toggleErrorsOnly: this.#toggleErrorsOnly,
313
+ clear: this.#clear,
314
+ copyLines: this.#copyLines,
315
+ copyPath: this.#copyPath,
316
+ openSelected: this.#openSelected,
317
+ restartSelected: this.#restartSelected,
318
+ quit: this.#quit
319
+ }
320
+ }, undefined, false, undefined, this), { patchConsole: false });
321
+ }
322
+ onOutput = (app, kind, text) => {
323
+ this.#buffer.push(app, kind, text);
324
+ this.#scheduleFrame();
325
+ };
326
+ onStatus = (statuses) => {
327
+ this.#statuses = statuses;
328
+ this.#scheduleFrame();
329
+ };
330
+ onNote = (text, level) => {
331
+ this.#buffer.push("akan", level === "warn" ? "stderr" : "stdout", `${text}
332
+ `);
333
+ this.#scheduleFrame();
334
+ };
335
+ waitForExit = async () => {
336
+ await this.#instance.waitUntilExit();
337
+ };
338
+ close = () => {
339
+ if (this.#frameTimer)
340
+ clearTimeout(this.#frameTimer);
341
+ this.#frameTimer = null;
342
+ if (this.#noticeTimer)
343
+ clearTimeout(this.#noticeTimer);
344
+ this.#noticeTimer = null;
345
+ process.stdout.off("resize", this.#onResize);
346
+ this.#instance.unmount();
347
+ for (const line of this.#buffer.flushPartials())
348
+ process.stdout.write(`${line.app} \u2502 ${line.text}
349
+ `);
350
+ for (const status of this.#statuses)
351
+ process.stdout.write(`${status.name} ${status.url} \u2014 ${status.state}
352
+ `);
353
+ const log = this.#supervisor.sessionLog;
354
+ for (const name of log.appNames)
355
+ process.stdout.write(`${name} log: ${log.relativePathOf(name)}
356
+ `);
357
+ };
358
+ #subscribe = (listener) => {
359
+ this.#listeners.add(listener);
360
+ return () => {
361
+ this.#listeners.delete(listener);
362
+ };
363
+ };
364
+ #railRows() {
365
+ const rows = [
366
+ { app: null, source: null, label: "all apps", state: null, port: null, depth: 0, appIndex: null }
367
+ ];
368
+ this.#statuses.forEach((status, idx) => {
369
+ rows.push({
370
+ app: status.name,
371
+ source: null,
372
+ label: status.name,
373
+ state: status.state,
374
+ port: status.port,
375
+ depth: 0,
376
+ appIndex: idx < 9 ? idx + 1 : null
377
+ });
378
+ if (status.name !== this.#target.app)
379
+ return;
380
+ for (const source of this.#buffer.sourcesOf(status.name))
381
+ rows.push({ app: status.name, source, label: source, state: null, port: null, depth: 1, appIndex: null });
382
+ });
383
+ return rows;
384
+ }
385
+ #indexOfTarget(rows) {
386
+ const found = rows.findIndex((row) => row.app === this.#target.app && row.source === this.#target.source);
387
+ return found < 0 ? 0 : found;
388
+ }
389
+ #filtered(target) {
390
+ return this.#buffer.select({
391
+ app: target.app ?? null,
392
+ source: target.source ?? null,
393
+ grep: this.#grep,
394
+ errorsOnly: this.#errorsOnly
395
+ });
396
+ }
397
+ #snapshot = () => {
398
+ if (this.#cachedSnapshot)
399
+ return this.#cachedSnapshot;
400
+ const terminalRows = Math.max(8, process.stdout.rows ?? 24);
401
+ const columns = Math.max(40, process.stdout.columns ?? 80);
402
+ const bodyHeight = Math.max(DevTui.paneChromeRows + 1, terminalRows - DevTui.footerRows);
403
+ const logRows = Math.max(1, bodyHeight - DevTui.paneChromeRows);
404
+ const rows = this.#railRows();
405
+ const view = windowOf(this.#filtered(this.#target), logRows, this.#anchor);
406
+ const status = this.#statuses.find((candidate) => candidate.name === this.#target.app);
407
+ const railLabelWidth = rows.reduce((max, row) => Math.max(max, row.label.length + row.depth * 2), 0);
408
+ this.#cachedSnapshot = {
409
+ rows,
410
+ selected: this.#indexOfTarget(rows),
411
+ title: status ? `${status.name}${this.#target.source ? ` \xB7 ${this.#target.source}` : ""} \xB7 ${status.url} \xB7 ${status.state}${status.detail ? ` (${status.detail})` : ""}` : "all apps",
412
+ lines: view.lines,
413
+ above: view.above,
414
+ below: view.below,
415
+ following: view.following,
416
+ prefix: this.#target.app === null ? "app" : this.#target.source === null ? "source" : "none",
417
+ prefixWidth: this.#target.app === null ? this.#appWidth() : this.#sourceWidth(),
418
+ grep: this.#grep,
419
+ errorsOnly: this.#errorsOnly,
420
+ editingGrep: this.#editingGrep,
421
+ notice: this.#notice,
422
+ readyCount: this.#statuses.filter((candidate) => candidate.state === "ready").length,
423
+ appCount: this.#statuses.length,
424
+ logRows,
425
+ bodyHeight,
426
+ railWidth: Math.min(34, Math.max(20, railLabelWidth + 10)),
427
+ columns,
428
+ terminalRows
429
+ };
430
+ return this.#cachedSnapshot;
431
+ };
432
+ #appWidth() {
433
+ return this.#statuses.reduce((max, status) => Math.max(max, status.name.length), 0);
434
+ }
435
+ #sourceWidth() {
436
+ let width = HOST_SOURCE.length;
437
+ for (const status of this.#statuses)
438
+ for (const source of this.#buffer.sourcesOf(status.name))
439
+ width = Math.max(width, source.length);
440
+ return width;
441
+ }
442
+ #scheduleFrame() {
443
+ if (this.#frameTimer)
444
+ return;
445
+ this.#frameTimer = setTimeout(() => {
446
+ this.#frameTimer = null;
447
+ this.#renderNow();
448
+ }, DevTui.frameMs);
449
+ }
450
+ #renderNow() {
451
+ this.#cachedSnapshot = null;
452
+ for (const listener of this.#listeners)
453
+ listener();
454
+ }
455
+ #onResize = () => this.#renderNow();
456
+ #moveSelection = (delta) => {
457
+ const rows = this.#railRows();
458
+ const next = ((this.#indexOfTarget(rows) + delta) % rows.length + rows.length) % rows.length;
459
+ const row = rows[next];
460
+ if (row)
461
+ this.#setTarget({ app: row.app, source: row.source });
462
+ };
463
+ #selectApp = (index) => {
464
+ const status = this.#statuses[index];
465
+ if (status)
466
+ this.#setTarget({ app: status.name, source: null });
467
+ };
468
+ #setTarget(target) {
469
+ this.#target = { app: target.app ?? null, source: target.source ?? null };
470
+ this.#anchor = null;
471
+ this.#renderNow();
472
+ }
473
+ #scroll = (delta) => {
474
+ this.#anchor = scrollAnchor(this.#filtered(this.#target), this.#snapshot().logRows, this.#anchor, delta);
475
+ this.#renderNow();
476
+ };
477
+ #follow = () => {
478
+ this.#anchor = null;
479
+ this.#renderNow();
480
+ };
481
+ #setGrep = (grep) => {
482
+ this.#grep = grep;
483
+ this.#anchor = null;
484
+ this.#renderNow();
485
+ };
486
+ #setEditingGrep = (editing) => {
487
+ this.#editingGrep = editing;
488
+ this.#renderNow();
489
+ };
490
+ #toggleErrorsOnly = () => {
491
+ this.#errorsOnly = !this.#errorsOnly;
492
+ this.#anchor = null;
493
+ this.#renderNow();
494
+ };
495
+ #clear = () => {
496
+ this.#buffer.clear(this.#target.app ?? null);
497
+ this.#anchor = null;
498
+ this.#renderNow();
499
+ };
500
+ #copyLines = () => {
501
+ const lines = this.#filtered(this.#target);
502
+ if (lines.length === 0) {
503
+ this.#setNotice("nothing to copy");
504
+ return;
505
+ }
506
+ const text = plainTextOf(lines, { withApp: this.#target.app === null });
507
+ writeClipboard(text).then((copied) => {
508
+ this.#setNotice(copied ? `copied ${lines.length} lines` : `no clipboard here \u2014 ${this.#logPaths().join(" \xB7 ")}`);
509
+ });
510
+ };
511
+ #copyPath = () => {
512
+ const paths = this.#logPaths();
513
+ writeClipboard(paths.join(`
514
+ `)).then((copied) => {
515
+ this.#setNotice(copied ? `copied ${paths.join(" \xB7 ")}` : paths.join(" \xB7 "));
516
+ });
517
+ };
518
+ #logPaths() {
519
+ const log = this.#supervisor.sessionLog;
520
+ const app = this.#target.app;
521
+ return (app ? [app] : log.appNames).map((name) => log.relativePathOf(name));
522
+ }
523
+ #setNotice(text) {
524
+ this.#notice = text;
525
+ if (this.#noticeTimer)
526
+ clearTimeout(this.#noticeTimer);
527
+ this.#noticeTimer = setTimeout(() => {
528
+ this.#notice = "";
529
+ this.#noticeTimer = null;
530
+ this.#renderNow();
531
+ }, DevTui.noticeMs);
532
+ this.#renderNow();
533
+ }
534
+ #openSelected = () => {
535
+ const status = this.#selectedStatus();
536
+ if (status)
537
+ openBrowser(status.url);
538
+ };
539
+ #restartSelected = () => {
540
+ const status = this.#selectedStatus();
541
+ if (status)
542
+ this.#supervisor.restart(status.name);
543
+ };
544
+ #selectedStatus() {
545
+ return this.#statuses.find((candidate) => candidate.name === this.#target.app);
546
+ }
547
+ #quit = () => {
548
+ this.#instance.unmount();
549
+ };
550
+ }
551
+ export {
552
+ DevTui
553
+ };
@@ -0,0 +1,9 @@
1
+ // @bun
2
+ // pkgs/@akanjs/cli/application/devTuiView.ts
3
+ var createDevTuiView = async (supervisor) => {
4
+ const { DevTui } = await import("./devTui-40ggmd99.js");
5
+ return new DevTui(supervisor);
6
+ };
7
+ export {
8
+ createDevTuiView
9
+ };
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ import {
3
+ getDirname2
4
+ } from "./index-6wwzs1bc.js";
5
+ export {
6
+ getDirname2 as getDirname
7
+ };
@@ -1,25 +1,23 @@
1
1
  // @bun
2
- import {
3
- AiSession
4
- } from "./index-0cj2zxbm.js";
5
- import {
6
- Prompter
7
- } from "./index-j37qq1f2.js";
8
2
  import {
9
3
  Workspace,
10
- command,
11
4
  runner,
12
- script
13
- } from "./index-etwh7sd3.js";
14
- import"./index-yzsxc30b.js";
15
- import"./index-mxvakhsm.js";
16
- import {
17
- getDirname
18
- } from "./index-1577bej2.js";
5
+ script,
6
+ command
7
+ } from "./index-mak3cd28.js";
19
8
  import {
20
9
  FileSys
21
- } from "./index-67546d0j.js";
22
- import"./index-r24hmh0q.js";
10
+ } from "./index-q0y2jq9j.js";
11
+ import"./index-2tv3fdx4.js";
12
+ import {
13
+ getDirname2
14
+ } from "./index-6wwzs1bc.js";
15
+ import {
16
+ Prompter
17
+ } from "./index-h7yw2z9n.js";
18
+ import {
19
+ AiSession
20
+ } from "./index-kn1h7p1x.js";
23
21
 
24
22
  // pkgs/@akanjs/cli/guideline/guideline.script.ts
25
23
  import { Logger } from "akanjs/common";
@@ -65,7 +63,7 @@ class GuidelinePrompt extends Prompter {
65
63
  const scanResult = await Promise.all(targetFilePaths.map(async (filePath) => ({ ...scan, ...await this.workspace.getLocalFile(filePath) })));
66
64
  scanFiles.push(...scanResult);
67
65
  }
68
- const resultPath = `${getDirname(import.meta.url)}/../guidelines/${this.name}/${guideJson.update.filePath}`;
66
+ const resultPath = `${getDirname2(import.meta.url)}/../guidelines/${this.name}/${guideJson.update.filePath}`;
69
67
  const writePath = `${this.workspace.workspaceRoot}/pkgs/@akanjs/cli/guidelines/${this.name}/${guideJson.update.filePath}`;
70
68
  const isResultExists = await this.workspace.exists(writePath);
71
69
  const existingResult = isResultExists ? await this.workspace.readFile(resultPath) : null;
@@ -107,7 +105,7 @@ ${guideJson.update.rules.map((rule) => `- ${rule}`).join(`
107
105
  }
108
106
  async requestUpdateInstruction(updateRequest) {
109
107
  const guideJson = await Prompter.getGuideJson(this.name);
110
- const resultPath = `${getDirname(import.meta.url)}/../guidelines/${this.name}/${guideJson.update.filePath}`;
108
+ const resultPath = `${getDirname2(import.meta.url)}/../guidelines/${this.name}/${guideJson.update.filePath}`;
111
109
  const writePath = `${this.workspace.workspaceRoot}/pkgs/@akanjs/cli/guidelines/${this.name}/${guideJson.update.filePath}`;
112
110
  const isResultExists = await this.workspace.exists(writePath);
113
111
  if (!isResultExists)
@@ -137,9 +135,11 @@ Request: ${updateRequest}
137
135
  async requestCreateDocumentPage(page) {
138
136
  const writePath = this.#resolveDocsPagePath(page);
139
137
  if (!await this.workspace.exists(writePath))
140
- await this.workspace.writeFile(writePath, `export default function Page() {
138
+ await this.workspace.writeFile(writePath, `import { page } from "akanjs/client";
139
+
140
+ export default page().render(() => {
141
141
  return <div>No Content</div>;
142
- }
142
+ });
143
143
  `);
144
144
  const instruction = await Prompter.getInstruction(this.name);
145
145
  const pageContent = await this.workspace.getLocalFile(writePath);
@@ -180,9 +180,11 @@ Please return only the file result in the following format for easy parsing.
180
180
  async requestUpdateDocumentPage(page, updateRequest) {
181
181
  const writePath = this.#resolveDocsPagePath(page);
182
182
  if (!await this.workspace.exists(writePath))
183
- await this.workspace.writeFile(writePath, `export default function Page() {
183
+ await this.workspace.writeFile(writePath, `import { page } from "akanjs/client";
184
+
185
+ export default page().render(() => {
184
186
  return <div>No Content</div>;
185
- }
187
+ });
186
188
  `);
187
189
  const instruction = await Prompter.getInstruction(this.name);
188
190
  const pageContent = await this.workspace.getLocalFile(writePath);
@@ -0,0 +1,31 @@
1
+ {
2
+ "title": "In-Page Agent Rule",
3
+ "description": "How an akan screen exposes itself to an in-page agent — st.tool, subscribed keys, built-ins, and the chat",
4
+ "group": "core",
5
+ "codegenPriority": 4,
6
+ "deprecated": false,
7
+ "scans": [
8
+ {
9
+ "type": "example",
10
+ "description": "Components publishing an agent tool beside the control that already performs the action",
11
+ "path": "{apps,libs}/*/**/*.tsx",
12
+ "sample": 4
13
+ }
14
+ ],
15
+ "update": {
16
+ "filePath": "./agentRule.instruction.md",
17
+ "contents": [
18
+ "what a declaration publishes",
19
+ "mounting the chat",
20
+ "publishing a tool",
21
+ "forms and reading state",
22
+ "built-in tools"
23
+ ],
24
+ "rules": [
25
+ "Use current Akan APIs only",
26
+ "State the rule before the reason, and keep the reason to one clause",
27
+ "Never describe a store class as an exposure surface — only st.tool and subscribed keys publish",
28
+ "Keep it workspace-neutral — no app or repo names"
29
+ ]
30
+ }
31
+ }