@akanjs/cli 3.0.0-alpha.10 → 3.0.0-alpha.101

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 (135) 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-byytxs22.js} +3 -5
  5. package/{agent.command-f0gqkfgz.js → agent.command-v1a4746v.js} +11 -13
  6. package/{application.command-x903m2qq.js → application.command-fzdcnzhg.js} +65 -38
  7. package/{applicationBuildRunner-ha3y8ew8.js → applicationBuildRunner-s4gsk728.js} +27 -23
  8. package/{applicationReleasePackager-gg8ccbeh.js → applicationReleasePackager-28v9vbzk.js} +8 -9
  9. package/buildBatch.proc.js +12 -14
  10. package/capacitorApp-8d6d4zkm.js +12 -0
  11. package/{cloud.command-zs6kyf83.js → cloud.command-wygy2z05.js} +15 -18
  12. package/commandManifest.json +1 -1
  13. package/{context.command-fmepgjzg.js → context.command-4vdt1aqq.js} +19 -23
  14. package/dependencyScanner-shs82ynp.js +8 -0
  15. package/devTui-qnf1txdz.js +553 -0
  16. package/devTuiView-yzct2cq6.js +9 -0
  17. package/getDirname-dr3jz1xg.js +7 -0
  18. package/{guideline.command-n6sw0a0c.js → guideline.command-p92dq6ts.js} +16 -18
  19. package/guidelines/agentRule/agentRule.generate.json +31 -0
  20. package/guidelines/agentRule/agentRule.instruction.md +533 -0
  21. package/guidelines/conventions/conventions.instruction.md +447 -197
  22. package/guidelines/cssRule/cssRule.instruction.md +7 -0
  23. package/guidelines/framework/framework.generate.json +3 -2
  24. package/guidelines/framework/framework.instruction.md +1 -9
  25. package/guidelines/mcpRule/mcpRule.generate.json +35 -0
  26. package/guidelines/mcpRule/mcpRule.instruction.md +366 -0
  27. package/guidelines/modelStore/modelStore.instruction.md +12 -0
  28. package/guidelines/modelTemplate/modelTemplate.instruction.md +5 -0
  29. package/guidelines/queryRule/queryRule.generate.json +31 -0
  30. package/guidelines/queryRule/queryRule.instruction.md +178 -0
  31. package/guidelines/runtimeRule/runtimeRule.generate.json +25 -0
  32. package/guidelines/runtimeRule/runtimeRule.instruction.md +220 -0
  33. package/guidelines/ssrRule/ssrRule.instruction.md +49 -5
  34. package/guidelines/transportRule/transportRule.generate.json +31 -0
  35. package/guidelines/transportRule/transportRule.instruction.md +60 -0
  36. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +51 -760
  37. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +33 -0
  38. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +402 -0
  39. package/incrementalBuilder.proc.js +26 -25
  40. package/{index-jf2ya7r2.js → index-0amdxycf.js} +8 -8
  41. package/{index-779ske1y.js → index-1yxtbmbj.js} +27 -27
  42. package/{index-eyyf2149.js → index-29sxqfaw.js} +36 -37
  43. package/index-3d9y066c.js +76 -0
  44. package/{index-76rn3g2c.js → index-47pj3aee.js} +4 -4
  45. package/index-5svjba73.js +159 -0
  46. package/{index-1577bej2.js → index-6wwzs1bc.js} +2 -2
  47. package/{index-gcv8ncfh.js → index-7d6vny25.js} +16 -12
  48. package/{index-y4vkyhvv.js → index-8p8p0cf8.js} +14 -14
  49. package/{index-wnp7hwq7.js → index-92zztqy1.js} +7 -7
  50. package/{index-fgc8r6dj.js → index-a5vmm6x4.js} +3 -1
  51. package/{index-xys926f2.js → index-by5gpp8x.js} +4 -4
  52. package/{index-0cj2zxbm.js → index-c69j78kk.js} +12 -11
  53. package/{index-rxkpk7n4.js → index-fc1bh0a7.js} +4 -4
  54. package/{index-d43t8af2.js → index-gq44bqjt.js} +58 -25
  55. package/{index-774gcx29.js → index-gtmz74tj.js} +41 -34
  56. package/{index-j37qq1f2.js → index-h7yw2z9n.js} +7 -7
  57. package/{index-bjpxzr6s.js → index-hwkygn9s.js} +51 -3
  58. package/{index-xmmzf150.js → index-hyywke0f.js} +1 -1
  59. package/{index-46tjzh6s.js → index-kcxmv48c.js} +29 -29
  60. package/{index-xjd3rqzj.js → index-n68jx79w.js} +6 -15
  61. package/{index-qb61h0k7.js → index-p5neav9b.js} +1098 -1360
  62. package/{index-67546d0j.js → index-q0y2jq9j.js} +14 -2
  63. package/{index-3vta1tqa.js → index-qkk27bk6.js} +32 -32
  64. package/{index-z8ptfkzv.js → index-qsq3q8fy.js} +975 -242
  65. package/{index-qzdjd4ct.js → index-srdssqj7.js} +18 -18
  66. package/{index-j9cxndc0.js → index-w8kmx1b6.js} +20 -11
  67. package/{index-82jrh4hj.js → index-yks023mb.js} +13 -13
  68. package/{index-5sn5w2mt.js → index-yza7zkpt.js} +94 -61
  69. package/{index-jhpa13zj.js → index-zmjppp25.js} +57 -57
  70. package/{index-kdh76j26.js → index-znynzt5w.js} +100 -32
  71. package/{index-4m0bphac.js → index-zxgr3s8s.js} +31 -30
  72. package/{index-62955kn5.js → index-zz5jyd94.js} +1002 -128
  73. package/index.js +22 -25
  74. package/{library.command-cv9gdbmg.js → library.command-s4fszngs.js} +11 -10
  75. package/{localRegistry.command-d8fg36zc.js → localRegistry.command-gyw4da9z.js} +20 -23
  76. package/{module.command-qyr1s9cn.js → module.command-6n7dwvav.js} +13 -16
  77. package/{package.command-wsjx0k47.js → package.command-gr82ypnr.js} +8 -10
  78. package/package.json +5 -7
  79. package/{page.command-rdzg65rm.js → page.command-7gvgb3jb.js} +7 -9
  80. package/{primitive.command-89g38b53.js → primitive.command-tk5ckw38.js} +13 -16
  81. package/{quality.command-0cs2z92d.js → quality.command-38v81baf.js} +226 -105
  82. package/recipeScanner-fpagtgc1.js +11 -0
  83. package/{repair.command-6fphxfwj.js → repair.command-5xbwvsxp.js} +12 -14
  84. package/{routeSourceValidator-e4jmbfcx.js → routeSourceValidator-ze6x894c.js} +0 -2
  85. package/{scalar.command-xfer69s6.js → scalar.command-0epwcr5k.js} +11 -14
  86. package/subspace.command-e2t36xb2.js +755 -0
  87. package/templates/app/env/env.client.debug.ts.template +1 -5
  88. package/templates/app/env/env.client.develop.ts.template +1 -5
  89. package/templates/app/env/env.client.local.ts.template +1 -5
  90. package/templates/app/env/env.client.main.ts.template +1 -5
  91. package/templates/app/env/env.client.testing.ts.template +1 -5
  92. package/templates/app/env/env.client.type.ts +2 -6
  93. package/templates/app/env/env.server.debug.ts.template +1 -5
  94. package/templates/app/env/env.server.develop.ts.template +1 -5
  95. package/templates/app/env/env.server.local.ts.template +1 -5
  96. package/templates/app/env/env.server.main.ts.template +1 -5
  97. package/templates/app/main.ts +3 -1
  98. package/templates/appSample/lib/task/task.signal.ts +11 -6
  99. package/templates/appSample/srvkit/AuthGuard.ts +9 -5
  100. package/templates/appSample/srvkit/SessionInternalArg.ts +4 -3
  101. package/templates/crudPages/[__model__Id]/edit/page.tsx +5 -5
  102. package/templates/crudPages/[__model__Id]/page.tsx +10 -13
  103. package/templates/crudPages/new/page.tsx +5 -5
  104. package/templates/crudPages/page.tsx +9 -9
  105. package/templates/crudSinglePage/page.tsx +11 -7
  106. package/templates/env/_env.server.type.ts +7 -5
  107. package/templates/lib/db.ts +1 -1
  108. package/templates/lib/dict.ts +1 -1
  109. package/templates/lib/sig.ts +5 -1
  110. package/templates/lib/srv.ts +6 -2
  111. package/templates/module/__model__.dictionary.ts +4 -1
  112. package/templates/module/__model__.signal.ts +2 -3
  113. package/templates/module/__model__.store.ts +1 -2
  114. package/templates/workspaceRoot/.gitignore.template +0 -1
  115. package/templates/workspaceRoot/.husky/pre-commit.template +16 -0
  116. package/templates/workspaceRoot/.vscode/settings.json.template +1 -1
  117. package/templates/workspaceRoot/AGENTS.md.template +4 -0
  118. package/templates/workspaceRoot/CLAUDE.md.template +19 -0
  119. package/templates/workspaceRoot/biome.json.template +2 -1
  120. package/templates/workspaceRoot/docs/AI-DEVELOPMENT.md.template +10 -14
  121. package/templates/workspaceRoot/docs/GENERATED.md.template +12 -10
  122. package/templates/workspaceRoot/package.json.template +2 -4
  123. package/typeChecker-3xgrzc2v.js +7 -0
  124. package/typecheck.proc.js +4 -5
  125. package/{workflow.command-2ygfqt4f.js → workflow.command-kphbr7eh.js} +22 -25
  126. package/{workspace.command-vbgpjkf9.js → workspace.command-j1gatz3d.js} +96 -81
  127. package/capacitorApp-9xswcgx7.js +0 -61
  128. package/dependencyScanner-f6grrep3.js +0 -9
  129. package/getDirname-m9s0cmhq.js +0 -8
  130. package/index-mxvakhsm.js +0 -66
  131. package/index-r24hmh0q.js +0 -4
  132. package/recipeScanner-tghkzrrt.js +0 -12
  133. package/typeChecker-kravn7ns.js +0 -8
  134. /package/{index-0wae5ebk.js → index-meh558jy.js} +0 -0
  135. /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-zz5jyd94.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-qnf1txdz.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-kdh76j26.js";
14
- import"./index-z8ptfkzv.js";
15
- import"./index-mxvakhsm.js";
16
- import {
17
- getDirname
18
- } from "./index-1577bej2.js";
5
+ script,
6
+ command
7
+ } from "./index-znynzt5w.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-qsq3q8fy.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-c69j78kk.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)
@@ -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
+ }