@akanjs/cli 3.1.0-rc.0 → 3.1.0-rc.10

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 (100) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-q7a4srt6.js → CodeAgent-rkjyxgec.js} +2 -2
  3. package/{CodeTui-ak23dxc9.js → CodeTui-h7pyj6xa.js} +1 -1
  4. package/TunnelShare-661cxz5e.js +14 -0
  5. package/{agent.command-f3gsc1gd.js → agent.command-3qxf4xcj.js} +5 -5
  6. package/akanCode.js +2 -2
  7. package/{application.command-3v2d53gd.js → application.command-m1kcd7jf.js} +54 -42
  8. package/{applicationBuildRunner-1yaqsrdq.js → applicationBuildRunner-dj0xkrep.js} +26 -33
  9. package/buildBatch.proc.js +24 -15
  10. package/{cloud.command-kk2rwkvw.js → cloud.command-9cp1t0f5.js} +63 -65
  11. package/cloud.script-dgstqt1m.js +24 -0
  12. package/{code.command-30sca09d.js → code.command-0ad6gw2a.js} +6 -6
  13. package/{context.command-k7eqacq6.js → context.command-0qx447mb.js} +17 -13
  14. package/context.runner-1vsjztjg.js +25 -0
  15. package/{dependencyScanner-06z2dmrr.js → dependencyScanner-3afj2vt1.js} +1 -1
  16. package/{guideline.command-dtczrqpf.js → guideline.command-cv5bmrx2.js} +2 -2
  17. package/guidelines/agentRule/agentRule.instruction.md +3 -3
  18. package/guidelines/conventions/conventions.instruction.md +457 -1069
  19. package/guidelines/cssRule/cssRule.instruction.md +28 -7
  20. package/guidelines/fieldRule/fieldRule.instruction.md +62 -0
  21. package/guidelines/framework/framework.instruction.md +4 -7
  22. package/guidelines/mcpRule/mcpRule.instruction.md +48 -20
  23. package/guidelines/modelConstant/modelConstant.instruction.md +2 -1
  24. package/guidelines/modelStore/modelStore.instruction.md +9 -0
  25. package/guidelines/pageRule/pageRule.instruction.md +80 -0
  26. package/guidelines/queryRule/queryRule.instruction.md +44 -11
  27. package/guidelines/runtimeRule/runtimeRule.instruction.md +113 -17
  28. package/guidelines/ssrRule/ssrRule.instruction.md +13 -0
  29. package/guidelines/transportRule/transportRule.instruction.md +135 -13
  30. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +4 -4
  31. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +68 -7
  32. package/incrementalBuilder.proc.js +10 -7
  33. package/index-192ha4xh.js +1173 -0
  34. package/{index-c76k723e.js → index-1p98exm2.js} +2 -2
  35. package/{index-rwq3ekqc.js → index-1xj2t7cb.js} +7 -7
  36. package/{index-nz15k0b6.js → index-20bxxyvn.js} +80 -80
  37. package/{index-qt22xstj.js → index-35hc95h5.js} +5 -3
  38. package/{index-jyv387qw.js → index-4mhy6qme.js} +4 -4
  39. package/{index-ww9bhp67.js → index-4pf8g7ff.js} +1 -1
  40. package/{index-2mx692qq.js → index-5edzv8fn.js} +5 -5
  41. package/{index-k9rrten6.js → index-5nd1wtkv.js} +92 -94
  42. package/index-62md4dwy.js +260 -0
  43. package/index-665zp9rs.js +271 -0
  44. package/{index-2etcv0sc.js → index-86jt2a0e.js} +1 -1
  45. package/{index-2t4tqd1c.js → index-8fp3b47h.js} +419 -418
  46. package/{index-c2yrsxdh.js → index-9z426msb.js} +109 -328
  47. package/{index-ctanya41.js → index-awbdfcf2.js} +4 -4
  48. package/{index-3hx1z96c.js → index-bqbf654f.js} +1 -1
  49. package/{index-tn4rpqp1.js → index-bspm21y1.js} +73 -49
  50. package/index-cpb3nvma.js +667 -0
  51. package/{index-p9ystjrp.js → index-d47ypebv.js} +97 -55
  52. package/{index-0bm04n5g.js → index-d72hfmdm.js} +15 -13
  53. package/{index-e0cvze1s.js → index-fmzcs8v6.js} +4 -4
  54. package/{index-y8q31011.js → index-fyq1z6kt.js} +68 -177
  55. package/{index-kjvrq3nc.js → index-g1mbppa9.js} +331 -250
  56. package/{index-gnyf1fqy.js → index-j237xtew.js} +6 -6
  57. package/{index-fm46xrf1.js → index-j4mkhz93.js} +3 -3
  58. package/{index-6jjtnhkw.js → index-jw1zm273.js} +74 -34
  59. package/{index-q958tqqg.js → index-m9jj544v.js} +1 -1
  60. package/index-mdjc93e1.js +33 -0
  61. package/{index-c1x0be5j.js → index-pydbnfez.js} +2 -2
  62. package/{index-7bymavqk.js → index-qwa5k1j8.js} +1 -1
  63. package/{index-v29746vb.js → index-tamvyvj3.js} +3 -3
  64. package/{index-05g3jayg.js → index-trpasv9q.js} +260 -259
  65. package/{index-2ahj896a.js → index-tvehn2sp.js} +1 -1
  66. package/{index-55mynnqs.js → index-va06nr10.js} +1434 -1173
  67. package/index-vk0pa0mn.js +240 -0
  68. package/{index-aprt7pkz.js → index-w44cy4vs.js} +2271 -3369
  69. package/index.js +22 -22
  70. package/{library.command-gaga5bmq.js → library.command-erp2f56n.js} +3 -3
  71. package/{localRegistry.command-9e84e32q.js → localRegistry.command-y176p558.js} +15 -11
  72. package/{module.command-7vpf6db4.js → module.command-gs2r615e.js} +5 -5
  73. package/{package.command-twmvvf69.js → package.command-j10r76ax.js} +4 -4
  74. package/package.json +21 -21
  75. package/{page.command-5asq7fdf.js → page.command-4h4a8pnh.js} +3 -3
  76. package/{pipeline.command-d0v38572.js → pipeline.command-a2nrk26m.js} +221 -220
  77. package/{primitive.command-dyrs2fm8.js → primitive.command-w6t0asqz.js} +6 -6
  78. package/{projectTypecheck-cvtkrzp2.js → projectTypecheck-f534enqj.js} +1 -1
  79. package/{quality.command-6emsqpbg.js → quality.command-77x7vbbx.js} +4 -4
  80. package/{repair.command-8t6aegv5.js → repair.command-y6sstev7.js} +5 -5
  81. package/{scalar.command-bnggy1x7.js → scalar.command-20b8cy0k.js} +4 -4
  82. package/{subspace.command-f02j5tge.js → subspace.command-5c7yasd7.js} +424 -364
  83. package/templates/app/env/env.client.type.ts +2 -3
  84. package/templates/app/page/styles.css.template +8 -0
  85. package/templates/appSample/lib/task/Task.Util.tsx +7 -7
  86. package/templates/appSample/lib/task/Task.Zone.tsx +1 -1
  87. package/templates/appSample/ui/QuantityControl.tsx +2 -2
  88. package/templates/crudSinglePage/page.tsx +1 -1
  89. package/templates/lib/cnst.ts +0 -1
  90. package/templates/workspaceRoot/.gitignore.template +23 -52
  91. package/templates/workspaceRoot/biome.json.template +1 -1
  92. package/{tunnel.command-9x8nfn75.js → tunnel.command-2kw8vt9g.js} +8 -4
  93. package/{workflow.command-jx0wag5r.js → workflow.command-2djwmpqf.js} +10 -10
  94. package/{workspace.command-cmj6mqyk.js → workspace.command-6qfgq4b4.js} +38 -34
  95. package/TunnelShare-21mm6dr5.js +0 -9
  96. package/cloud.script-r7eyfey4.js +0 -20
  97. package/context.runner-hqd1ppqe.js +0 -21
  98. package/index-6w0rbr9d.js +0 -68
  99. package/index-n68jx79w.js +0 -120
  100. package/index-r2tpeb3n.js +0 -392
@@ -2,12 +2,12 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-6jjtnhkw.js";
5
+ } from "./index-jw1zm273.js";
6
6
  import {
7
7
  generatedFilesForSync,
8
8
  createPassedPrimitiveReport,
9
9
  scalarChangedFiles
10
- } from "./index-05g3jayg.js";
10
+ } from "./index-trpasv9q.js";
11
11
  import {
12
12
  pluralizeName
13
13
  } from "./index-nz8prx9g.js";
@@ -22,26 +22,26 @@ import {
22
22
  renderWorkflowApply,
23
23
  renderWorkflowValidation,
24
24
  renderWorkflowRunArtifact
25
- } from "./index-05g3jayg.js";
25
+ } from "./index-trpasv9q.js";
26
26
  import {
27
27
  AkanContextAnalyzer
28
- } from "./index-2mx692qq.js";
28
+ } from "./index-5edzv8fn.js";
29
29
  import {
30
30
  CommandContainer,
31
31
  runner
32
- } from "./index-6jjtnhkw.js";
32
+ } from "./index-jw1zm273.js";
33
33
  import {
34
34
  ModuleScript
35
- } from "./index-e0cvze1s.js";
35
+ } from "./index-fmzcs8v6.js";
36
36
  import {
37
37
  PrimitiveScript
38
- } from "./index-ctanya41.js";
38
+ } from "./index-awbdfcf2.js";
39
39
  import {
40
40
  spawnShell
41
- } from "./index-fm46xrf1.js";
41
+ } from "./index-j4mkhz93.js";
42
42
  import {
43
43
  ScalarScript
44
- } from "./index-c76k723e.js";
44
+ } from "./index-1p98exm2.js";
45
45
 
46
46
  // pkgs/@akanjs/cli/workflow/workflow.runner.ts
47
47
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -1,7 +1,32 @@
1
1
  // @bun
2
2
  import {
3
3
  ConfigLock
4
- } from "./index-3hx1z96c.js";
4
+ } from "./index-bqbf654f.js";
5
+
6
+ // pkgs/@akanjs/devkit/codeAgent/agent/akanCodePaths.ts
7
+ import { existsSync } from "fs";
8
+ import { homedir } from "os";
9
+ import path from "path";
10
+ var builtinSkillsDir = () => {
11
+ const candidates = [path.join(import.meta.dir, "skills"), path.join(import.meta.dir, "..", "skills")];
12
+ return candidates.find((candidate) => existsSync(candidate));
13
+ };
14
+ var globalDir = () => process.env.AKAN_CODE_HOME ?? path.join(homedir(), ".akan", "code");
15
+ var akanCodePaths2 = {
16
+ workspaceDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code"),
17
+ sessionsDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "sessions"),
18
+ extensionsDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "extensions"),
19
+ skillsDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "skills"),
20
+ mailDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "mail"),
21
+ builtinSkillsDir,
22
+ mcpFile: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "mcp.json"),
23
+ globalMcpFile: () => path.join(globalDir(), "mcp.json"),
24
+ globalSkillsDir: () => path.join(globalDir(), "skills"),
25
+ globalDir,
26
+ authFile: () => path.join(globalDir(), "auth.json"),
27
+ mcpAuthFile: () => path.join(globalDir(), "mcpAuth.json"),
28
+ modelsFile: () => path.join(globalDir(), "models.json")
29
+ };
5
30
 
6
31
  // pkgs/@akanjs/devkit/codeAgent/agent/SubagentPool.ts
7
32
  import { codeAgentReadOnlyBuiltins } from "akanjs/common";
@@ -116,7 +141,7 @@ class SubagentPool2 {
116
141
  }
117
142
  }
118
143
  async#run(id, kind, prompt, signal) {
119
- const { CodeAgent } = await import("./CodeAgent-q7a4srt6.js");
144
+ const { CodeAgent } = await import("./CodeAgent-rkjyxgec.js");
120
145
  const budget = this.#options.parent.tools.subagent;
121
146
  const child = SubagentPool2.childOf(this.#options.parent, kind);
122
147
  const agent = await CodeAgent.create({
@@ -166,31 +191,6 @@ class SubagentPool2 {
166
191
  }
167
192
  }
168
193
 
169
- // pkgs/@akanjs/devkit/codeAgent/agent/akanCodePaths.ts
170
- import { existsSync } from "fs";
171
- import { homedir } from "os";
172
- import path from "path";
173
- var builtinSkillsDir = () => {
174
- const candidates = [path.join(import.meta.dir, "skills"), path.join(import.meta.dir, "..", "skills")];
175
- return candidates.find((candidate) => existsSync(candidate));
176
- };
177
- var globalDir = () => process.env.AKAN_CODE_HOME ?? path.join(homedir(), ".akan", "code");
178
- var akanCodePaths2 = {
179
- workspaceDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code"),
180
- sessionsDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "sessions"),
181
- extensionsDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "extensions"),
182
- skillsDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "skills"),
183
- mailDir: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "mail"),
184
- builtinSkillsDir,
185
- mcpFile: (workspaceRoot) => path.join(workspaceRoot, ".akan", "code", "mcp.json"),
186
- globalMcpFile: () => path.join(globalDir(), "mcp.json"),
187
- globalSkillsDir: () => path.join(globalDir(), "skills"),
188
- globalDir,
189
- authFile: () => path.join(globalDir(), "auth.json"),
190
- mcpAuthFile: () => path.join(globalDir(), "mcpAuth.json"),
191
- modelsFile: () => path.join(globalDir(), "models.json")
192
- };
193
-
194
194
  // pkgs/@akanjs/devkit/codeAgent/tools/McpServerConfig.ts
195
195
  import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
196
196
  import path2 from "path";
@@ -283,59 +283,6 @@ class McpServerConfig {
283
283
  }
284
284
  }
285
285
 
286
- // pkgs/@akanjs/devkit/codeAgent/tools/McpTokenStore.ts
287
- import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "fs";
288
- import path3 from "path";
289
- class McpTokenStore {
290
- static file() {
291
- return akanCodePaths2.mcpAuthFile();
292
- }
293
- static lockFile() {
294
- return `${McpTokenStore.file()}.lock`;
295
- }
296
- static read(name) {
297
- return McpTokenStore.#all()[name];
298
- }
299
- static names() {
300
- return Object.keys(McpTokenStore.#all());
301
- }
302
- static write(name, auth) {
303
- McpTokenStore.#save({ ...McpTokenStore.#all(), [name]: auth });
304
- }
305
- static clear(name) {
306
- const all = McpTokenStore.#all();
307
- if (!(name in all))
308
- return false;
309
- delete all[name];
310
- McpTokenStore.#save(all);
311
- return true;
312
- }
313
- static isExpired(auth) {
314
- return auth.expiresAt !== undefined && auth.expiresAt <= Date.now() + McpTokenStore.skewMs;
315
- }
316
- static skewMs = 60000;
317
- static #all() {
318
- const file = McpTokenStore.file();
319
- if (!existsSync3(file))
320
- return {};
321
- try {
322
- const parsed = JSON.parse(readFileSync2(file, "utf8"));
323
- return parsed.servers ?? {};
324
- } catch {
325
- return {};
326
- }
327
- }
328
- static #save(servers) {
329
- const file = McpTokenStore.file();
330
- mkdirSync2(path3.dirname(file), { recursive: true, mode: 448 });
331
- const temp = `${file}.${process.pid}.tmp`;
332
- writeFileSync2(temp, `${JSON.stringify({ servers }, null, 2)}
333
- `, { mode: 384 });
334
- renameSync(temp, file);
335
- chmodSync(file, 384);
336
- }
337
- }
338
-
339
286
  // pkgs/@akanjs/devkit/codeAgent/tools/McpOAuth.ts
340
287
  import { createHash, randomBytes } from "crypto";
341
288
 
@@ -560,6 +507,59 @@ class McpOAuthLoopback {
560
507
  }
561
508
  }
562
509
 
510
+ // pkgs/@akanjs/devkit/codeAgent/tools/McpTokenStore.ts
511
+ import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "fs";
512
+ import path3 from "path";
513
+ class McpTokenStore {
514
+ static file() {
515
+ return akanCodePaths2.mcpAuthFile();
516
+ }
517
+ static lockFile() {
518
+ return `${McpTokenStore.file()}.lock`;
519
+ }
520
+ static read(name) {
521
+ return McpTokenStore.#all()[name];
522
+ }
523
+ static names() {
524
+ return Object.keys(McpTokenStore.#all());
525
+ }
526
+ static write(name, auth) {
527
+ McpTokenStore.#save({ ...McpTokenStore.#all(), [name]: auth });
528
+ }
529
+ static clear(name) {
530
+ const all = McpTokenStore.#all();
531
+ if (!(name in all))
532
+ return false;
533
+ delete all[name];
534
+ McpTokenStore.#save(all);
535
+ return true;
536
+ }
537
+ static isExpired(auth) {
538
+ return auth.expiresAt !== undefined && auth.expiresAt <= Date.now() + McpTokenStore.skewMs;
539
+ }
540
+ static skewMs = 60000;
541
+ static #all() {
542
+ const file = McpTokenStore.file();
543
+ if (!existsSync3(file))
544
+ return {};
545
+ try {
546
+ const parsed = JSON.parse(readFileSync2(file, "utf8"));
547
+ return parsed.servers ?? {};
548
+ } catch {
549
+ return {};
550
+ }
551
+ }
552
+ static #save(servers) {
553
+ const file = McpTokenStore.file();
554
+ mkdirSync2(path3.dirname(file), { recursive: true, mode: 448 });
555
+ const temp = `${file}.${process.pid}.tmp`;
556
+ writeFileSync2(temp, `${JSON.stringify({ servers }, null, 2)}
557
+ `, { mode: 384 });
558
+ renameSync(temp, file);
559
+ chmodSync(file, 384);
560
+ }
561
+ }
562
+
563
563
  // pkgs/@akanjs/devkit/codeAgent/tools/McpSignIn.ts
564
564
  class McpSignIn {
565
565
  static #refreshing = new Map;
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  AppInfo
4
- } from "./index-55mynnqs.js";
4
+ } from "./index-va06nr10.js";
5
5
 
6
6
  // pkgs/@akanjs/devkit/slicePlanner.ts
7
7
  class SlicePlanner {
@@ -33,6 +33,9 @@ class SlicePlanner {
33
33
  }
34
34
  return found ? peers : null;
35
35
  }
36
+ static rootEntriesOf(rootFiles) {
37
+ return [...new Set(rootFiles.map((file) => file.split("/")[0] ?? file))].sort();
38
+ }
36
39
  static typesPackageOf(dependency) {
37
40
  return dependency.startsWith("@") ? `@types/${dependency.slice(1).replace("/", "__")}` : `@types/${dependency}`;
38
41
  }
@@ -131,7 +134,6 @@ class SlicePlanner {
131
134
  };
132
135
  }
133
136
  }
134
- var rootEntriesOf = (rootFiles) => [...new Set(rootFiles.map((file) => file.split("/")[0] ?? file))].sort();
135
137
  function formatSlicePlan(plan) {
136
138
  const libCounts = Object.entries(plan.libFiles).map(([lib, files]) => ` - libs/${lib}: ${files.length} files`);
137
139
  const sections = [
@@ -139,7 +141,7 @@ function formatSlicePlan(plan) {
139
141
  `app: ${plan.app} (apps/${plan.app}: ${plan.appFiles.length} files)`,
140
142
  `libs: ${plan.libs.length ? plan.libs.join(", ") : "(none)"}`,
141
143
  ...libCounts,
142
- `workspace shell: ${plan.rootFiles.length} files across ${rootEntriesOf(plan.rootFiles).join(", ")}`,
144
+ `workspace shell: ${plan.rootFiles.length} files across ${SlicePlanner.rootEntriesOf(plan.rootFiles).join(", ")}`,
143
145
  "",
144
146
  `Root dependencies this slice does not use (${plan.unusedDependencies.length}) \u2014 pruned:`,
145
147
  "",
@@ -1,16 +1,16 @@
1
1
  // @bun
2
2
  import {
3
3
  jsonText
4
- } from "./index-05g3jayg.js";
4
+ } from "./index-trpasv9q.js";
5
5
  import {
6
6
  akanMcpInstallTargets
7
- } from "./index-2mx692qq.js";
7
+ } from "./index-5edzv8fn.js";
8
8
  import {
9
9
  script
10
- } from "./index-6jjtnhkw.js";
10
+ } from "./index-jw1zm273.js";
11
11
  import {
12
12
  ContextRunner2
13
- } from "./index-0bm04n5g.js";
13
+ } from "./index-d72hfmdm.js";
14
14
 
15
15
  // pkgs/@akanjs/cli/context/context.script.ts
16
16
  import { Logger } from "akanjs/common";
@@ -55,7 +55,7 @@ class SubspaceConfig {
55
55
  assertPushable(branch) {
56
56
  if (this.pushableBranches.includes(branch))
57
57
  return;
58
- throw new Error(`Branch "${branch}" is not pushable. ${SubspaceConfig.source} allows: ${this.pushableBranches.join(", ")}`);
58
+ throw new Error(`Branch "${branch}" is not pushable. \`subspace.pushableBranches\` in the workspace root akan.config.ts allows: ${this.pushableBranches.join(", ")}`);
59
59
  }
60
60
  }
61
61
 
@@ -10,7 +10,7 @@ import {
10
10
  isScannedRootEntry,
11
11
  AppExecutor,
12
12
  LibExecutor
13
- } from "./index-55mynnqs.js";
13
+ } from "./index-va06nr10.js";
14
14
  import {
15
15
  FileSys2
16
16
  } from "./index-52w0fvh8.js";
@@ -23,7 +23,7 @@ import {
23
23
  workflowPathsForPlan,
24
24
  workflowRunArtifactPath,
25
25
  workflowSyncDir
26
- } from "./index-05g3jayg.js";
26
+ } from "./index-trpasv9q.js";
27
27
 
28
28
  // pkgs/@akanjs/devkit/akanContext.ts
29
29
  import { readdir } from "fs/promises";
@@ -79,7 +79,7 @@ var upsertCodexMcpServerBlock = (existing, block, { force = false } = {}) => {
79
79
  if (!match) {
80
80
  if (!existing.trim())
81
81
  return nextBlock;
82
- return `${existing.replace(/\s*$/, "")}
82
+ return `${existing.trimEnd()}
83
83
 
84
84
  ${nextBlock}`;
85
85
  }
@@ -532,14 +532,14 @@ class AkanContextAnalyzer {
532
532
  if (frameworkDeclared.size > 0) {
533
533
  const agentsMd = await Bun.file(path.join(workspace.workspaceRoot, "AGENTS.md")).text().catch(() => "");
534
534
  const listed = listedByImport(sectionOf(agentsMd, "## Recipes")).get("akanjs/ui") ?? new Set;
535
- pushIndexDiagnostic("AGENTS.md", [...frameworkDeclared].filter((name) => !listed.has(name)).sort(), [...listed].filter((name) => !frameworkDeclared.has(name)).sort(), "akan agent install agents-md");
535
+ pushIndexDiagnostic("AGENTS.md", [...frameworkDeclared].filter((name) => !listed.has(name)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0), [...listed].filter((name) => !frameworkDeclared.has(name)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0), "akan agent install agents-md");
536
536
  }
537
537
  for (const sys of [...context.apps, ...context.libs]) {
538
538
  const own = declaredByImport.get(`@${sys.path}/ui`) ?? new Set;
539
539
  const scopeMd = await Bun.file(path.join(workspace.workspaceRoot, sys.path, "AGENTS.md")).text().catch(() => "");
540
540
  const groups = listedByImport(sectionOf(scopeMd, "## Recipes In Scope"));
541
541
  const ownListed = groups.get(`@${sys.path}/ui`) ?? new Set;
542
- const missing = [...own].filter((name) => !ownListed.has(name)).sort();
542
+ const missing = [...own].filter((name) => !ownListed.has(name)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
543
543
  const stale = [...groups.entries()].flatMap(([importFrom, names]) => [...names].filter((name) => !(declaredByImport.get(importFrom) ?? new Set).has(name))).sort();
544
544
  pushIndexDiagnostic(`${sys.path}/AGENTS.md`, missing, stale, `akan sync ${sys.name}`);
545
545
  }
@@ -71,13 +71,6 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause, workspaceRoot)}`
71
71
  }
72
72
  }
73
73
 
74
- // pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
75
- import fs from "fs";
76
- import path5 from "path";
77
-
78
- // pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
79
- import path3 from "path";
80
-
81
74
  // pkgs/@akanjs/devkit/akanApp/devHostPolicy.ts
82
75
  import path2 from "path";
83
76
  var UNAVAILABLE_REDIS_HOST = "redis-tunnel-unavailable.invalid";
@@ -293,7 +286,83 @@ var mergeInvalidateMessages = (current, next) => {
293
286
  var buildStatusReplaySequence = (pendingReplay, latestByPhase) => [...pendingReplay, ...latestByPhase.values()];
294
287
  var filesChangedSince = (before, after) => [...before].filter(([file, stamp]) => after.get(file) !== stamp).map(([file]) => file);
295
288
 
289
+ // pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
290
+ import fs from "fs";
291
+ import { readFile } from "fs/promises";
292
+ import path3 from "path";
293
+
294
+ class WatchRootResolver {
295
+ #app;
296
+ constructor(app) {
297
+ this.#app = app;
298
+ }
299
+ async resolve() {
300
+ const tsconfig = await this.#app.getTsConfig();
301
+ const appDir = path3.resolve(this.#app.cwdPath);
302
+ const appsContainer = path3.dirname(appDir);
303
+ const libsContainer = path3.resolve(this.#app.workspace.workspaceRoot, "libs");
304
+ const libRoots = (await this.#resolveLibDeps(libsContainer))?.map((name) => path3.join(libsContainer, name)).filter((dir) => fs.existsSync(dir));
305
+ const set = new Set;
306
+ set.add(path3.resolve(`${this.#app.cwdPath}/page`));
307
+ for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
308
+ for (const target of targets) {
309
+ if (!target)
310
+ continue;
311
+ if (path3.isAbsolute(target))
312
+ continue;
313
+ const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
314
+ const resolved = path3.resolve(this.#app.workspace.workspaceRoot, cleaned);
315
+ if (resolved === libsContainer && libRoots) {
316
+ for (const root of libRoots)
317
+ set.add(root);
318
+ continue;
319
+ }
320
+ const root = resolved === appsContainer ? appDir : resolved;
321
+ if (fs.existsSync(root))
322
+ set.add(root);
323
+ }
324
+ }
325
+ return [...set];
326
+ }
327
+ async#resolveLibDeps(libsContainer) {
328
+ const scanInfo = this.#app.getScanInfo({ allowEmpty: true });
329
+ if (scanInfo?.type === "app")
330
+ return scanInfo.libDeps;
331
+ const direct = await WatchRootResolver.#readManifestLibDeps(path3.join(this.#app.cwdPath, "akan.app.json"));
332
+ if (!direct)
333
+ return null;
334
+ const closure = new Set;
335
+ const queue = [...direct];
336
+ while (queue.length > 0) {
337
+ const name = queue.shift();
338
+ if (!name || closure.has(name))
339
+ continue;
340
+ closure.add(name);
341
+ const nested = await WatchRootResolver.#readManifestLibDeps(path3.join(libsContainer, name, "akan.lib.json"));
342
+ if (!nested)
343
+ return null;
344
+ queue.push(...nested);
345
+ }
346
+ return [...closure];
347
+ }
348
+ static async#readManifestLibDeps(manifestPath) {
349
+ try {
350
+ const parsed = JSON.parse(await readFile(manifestPath, "utf8"));
351
+ if (!Array.isArray(parsed.libDeps))
352
+ return null;
353
+ return parsed.libDeps.filter((name) => typeof name === "string" && name.length > 0);
354
+ } catch {
355
+ return null;
356
+ }
357
+ }
358
+ }
359
+
360
+ // pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
361
+ import fs2 from "fs";
362
+ import path6 from "path";
363
+
296
364
  // pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
365
+ import path4 from "path";
297
366
  var CSS_EXTS = new Set([".css"]);
298
367
  var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
299
368
 
@@ -301,10 +370,10 @@ class HmrChangeClassifier {
301
370
  classify(abs) {
302
371
  if (this.#isUninteresting(abs))
303
372
  return "ignore";
304
- const base = path3.basename(abs);
373
+ const base = path4.basename(abs);
305
374
  if (CONFIG_BASENAMES.has(base))
306
375
  return "config";
307
- const ext = path3.extname(abs).toLowerCase();
376
+ const ext = path4.extname(abs).toLowerCase();
308
377
  if (CSS_EXTS.has(ext))
309
378
  return "css";
310
379
  if (SOURCE_EXTS.has(ext))
@@ -312,16 +381,16 @@ class HmrChangeClassifier {
312
381
  return "ignore";
313
382
  }
314
383
  #isUninteresting(abs) {
315
- const base = path3.basename(abs);
384
+ const base = path4.basename(abs);
316
385
  if (!base)
317
386
  return true;
318
387
  if (base.startsWith("."))
319
388
  return true;
320
389
  if (base.endsWith("~") || base.endsWith(".swp") || base.endsWith(".swx") || base.endsWith(".tmp"))
321
390
  return true;
322
- if (abs.includes(`${path3.sep}node_modules${path3.sep}`))
391
+ if (abs.includes(`${path4.sep}node_modules${path4.sep}`))
323
392
  return true;
324
- if (abs.includes(`${path3.sep}.akan${path3.sep}`))
393
+ if (abs.includes(`${path4.sep}.akan${path4.sep}`))
325
394
  return true;
326
395
  return false;
327
396
  }
@@ -329,7 +398,7 @@ class HmrChangeClassifier {
329
398
 
330
399
  // pkgs/@akanjs/devkit/frontendBuild/sourceMtimeIndex.ts
331
400
  import { readdir, stat } from "fs/promises";
332
- import path4 from "path";
401
+ import path5 from "path";
333
402
  var UNREADABLE = Number.NaN;
334
403
 
335
404
  class SourceMtimeIndex {
@@ -392,7 +461,7 @@ class SourceMtimeIndex {
392
461
  if (!this.#primed)
393
462
  return;
394
463
  await Promise.all(paths.map(async (file) => {
395
- const abs = path4.resolve(file);
464
+ const abs = path5.resolve(file);
396
465
  const stats = await stat(abs).catch(() => null);
397
466
  if (!stats?.isFile()) {
398
467
  this.#files.delete(abs);
@@ -478,7 +547,7 @@ class SourceMtimeIndex {
478
547
  for (const entry of entries) {
479
548
  if (SourceMtimeIndex.#skipDirent(entry.name))
480
549
  continue;
481
- const abs = path4.join(dir, entry.name);
550
+ const abs = path5.join(dir, entry.name);
482
551
  if (entry.isDirectory()) {
483
552
  descend.push(abs);
484
553
  continue;
@@ -505,7 +574,7 @@ class SourceMtimeIndex {
505
574
  }
506
575
  if (known) {
507
576
  for (const abs of [...this.#files.keys()]) {
508
- if (present.has(abs) || path4.dirname(abs) !== dir)
577
+ if (present.has(abs) || path5.dirname(abs) !== dir)
509
578
  continue;
510
579
  this.#files.delete(abs);
511
580
  changed?.add(abs);
@@ -523,7 +592,7 @@ class SourceMtimeIndex {
523
592
  this.#unsettled.delete(dir);
524
593
  }
525
594
  #forget(dir) {
526
- const prefix = `${dir}${path4.sep}`;
595
+ const prefix = `${dir}${path5.sep}`;
527
596
  this.#dirs.delete(dir);
528
597
  this.#unreadable.delete(dir);
529
598
  this.#unsettled.delete(dir);
@@ -561,8 +630,8 @@ class SourceMtimeIndex {
561
630
  return !name || name.startsWith(".") || name === "node_modules";
562
631
  }
563
632
  static #pruneNestedRoots(roots) {
564
- const resolved = [...new Set(roots.map((root) => path4.resolve(root)))].sort();
565
- return resolved.filter((root) => !resolved.some((other) => other !== root && root.startsWith(`${other}${path4.sep}`)));
633
+ const resolved = [...new Set(roots.map((root) => path5.resolve(root)))].sort();
634
+ return resolved.filter((root) => !resolved.some((other) => other !== root && root.startsWith(`${other}${path5.sep}`)));
566
635
  }
567
636
  }
568
637
 
@@ -587,7 +656,7 @@ class HmrWatcher {
587
656
  #reportedCompensating = false;
588
657
  #reportedGaps = "";
589
658
  constructor(opts) {
590
- this.#roots = [...new Set(opts.roots.map((r) => path5.resolve(r)))];
659
+ this.#roots = [...new Set(opts.roots.map((r) => path6.resolve(r)))];
591
660
  this.#debounceMs = opts.debounceMs ?? HmrWatcher.#envDebounceMs() ?? 30;
592
661
  this.#verifyDelayMs = opts.verifyDelayMs ?? 250;
593
662
  this.#onBatch = opts.onBatch;
@@ -600,10 +669,10 @@ class HmrWatcher {
600
669
  async start() {
601
670
  for (const root of this.#roots) {
602
671
  try {
603
- const w = fs.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
672
+ const w = fs2.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
604
673
  if (!filename)
605
674
  return;
606
- const abs = path5.resolve(root, filename.toString());
675
+ const abs = path6.resolve(root, filename.toString());
607
676
  this.#queue(abs);
608
677
  });
609
678
  w.on("error", (err) => {
@@ -729,7 +798,7 @@ class HmrWatcher {
729
798
  }
730
799
  #reportCoverageGaps() {
731
800
  const gaps = this.#index.coverageGaps;
732
- const key = gaps.map((gap) => `${gap.code}:${gap.path}`).sort().join("|");
801
+ const key = gaps.map((gap) => `${gap.code}:${gap.path}`).sort((a, b) => a < b ? -1 : a > b ? 1 : 0).join("|");
733
802
  if (key === this.#reportedGaps)
734
803
  return;
735
804
  this.#reportedGaps = key;
@@ -767,75 +836,4 @@ class HmrWatcher {
767
836
  }
768
837
  }
769
838
 
770
- // pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
771
- import fs2 from "fs";
772
- import { readFile } from "fs/promises";
773
- import path6 from "path";
774
-
775
- class WatchRootResolver {
776
- #app;
777
- constructor(app) {
778
- this.#app = app;
779
- }
780
- async resolve() {
781
- const tsconfig = await this.#app.getTsConfig();
782
- const appDir = path6.resolve(this.#app.cwdPath);
783
- const appsContainer = path6.dirname(appDir);
784
- const libsContainer = path6.resolve(this.#app.workspace.workspaceRoot, "libs");
785
- const libRoots = (await this.#resolveLibDeps(libsContainer))?.map((name) => path6.join(libsContainer, name)).filter((dir) => fs2.existsSync(dir));
786
- const set = new Set;
787
- set.add(path6.resolve(`${this.#app.cwdPath}/page`));
788
- for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
789
- for (const target of targets) {
790
- if (!target)
791
- continue;
792
- if (path6.isAbsolute(target))
793
- continue;
794
- const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
795
- const resolved = path6.resolve(this.#app.workspace.workspaceRoot, cleaned);
796
- if (resolved === libsContainer && libRoots) {
797
- for (const root of libRoots)
798
- set.add(root);
799
- continue;
800
- }
801
- const root = resolved === appsContainer ? appDir : resolved;
802
- if (fs2.existsSync(root))
803
- set.add(root);
804
- }
805
- }
806
- return [...set];
807
- }
808
- async#resolveLibDeps(libsContainer) {
809
- const scanInfo = this.#app.getScanInfo({ allowEmpty: true });
810
- if (scanInfo?.type === "app")
811
- return scanInfo.libDeps;
812
- const direct = await WatchRootResolver.#readManifestLibDeps(path6.join(this.#app.cwdPath, "akan.app.json"));
813
- if (!direct)
814
- return null;
815
- const closure = new Set;
816
- const queue = [...direct];
817
- while (queue.length > 0) {
818
- const name = queue.shift();
819
- if (!name || closure.has(name))
820
- continue;
821
- closure.add(name);
822
- const nested = await WatchRootResolver.#readManifestLibDeps(path6.join(libsContainer, name, "akan.lib.json"));
823
- if (!nested)
824
- return null;
825
- queue.push(...nested);
826
- }
827
- return [...closure];
828
- }
829
- static async#readManifestLibDeps(manifestPath) {
830
- try {
831
- const parsed = JSON.parse(await readFile(manifestPath, "utf8"));
832
- if (!Array.isArray(parsed.libDeps))
833
- return null;
834
- return parsed.libDeps.filter((name) => typeof name === "string" && name.length > 0);
835
- } catch {
836
- return null;
837
- }
838
- }
839
- }
840
-
841
839
  export { ApplicationBuildReporter, UNAVAILABLE_REDIS_HOST, redisTunnelPolicy, BUILDER_MIN_RSS_RECYCLE_INTERVAL_MS, SOURCE_EXTS, shouldRestartBackendByDevPlan, shouldRestartBuilderByDevPlan, shouldAbandonBackendRecovery, normalizeBackendReportedGeneration, shouldRestartDevHostByDevPlan, devHostStateOf, isLegacyBackendFallbackFile, shouldMarkBuildPhaseRecovered, shouldKeepBuildFailure, createBackendBuildStatus, backendRestartReasonFromMessage, mergeBackendRestartReasons, shouldReplaceLastGoodMessage, shouldQueueBuildStatusReplay, hasBuildFailureForGeneration, decideBuilderRssRecycle, decideBuilderRssSettle, decideIdleSuspend, resolveIdleSuspendMs, hasAnyBuildFailure, shouldRefreshConfigOnIdleWake, shouldHoldForReturningBuilder, shouldWarnBuilderRssCeilingTight, isRssCeilingUnreachable, shouldRelayRecycledFrontendState, mergeInvalidateMessages, buildStatusReplaySequence, filesChangedSince, HmrWatcher, WatchRootResolver };