@akanjs/cli 3.0.0-beta.2 → 3.0.0-beta.20

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 (187) hide show
  1. package/.build-stamp +1 -1
  2. package/CodeAgent-awv258wb.js +9 -0
  3. package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
  4. package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
  5. package/CodeTui-1nqh35ez.js +1457 -0
  6. package/README.md +3 -0
  7. package/TunnelShare-scf4e4pd.js +9 -0
  8. package/{agent.command-d2gfxfck.js → agent.command-1s9ag7sb.js} +8 -9
  9. package/akanCode.js +102 -0
  10. package/{application.command-pj2m7584.js → application.command-49hwy6va.js} +51 -78
  11. package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-ybyp97pv.js} +63 -64
  12. package/{applicationReleasePackager-4yasxwv9.js → applicationReleasePackager-esnrphw8.js} +40 -60
  13. package/buildBatch.proc.js +19 -24
  14. package/{capacitorApp-36rbr858.js → capacitorApp-1synz4en.js} +3 -4
  15. package/cloud.command-d7rqtzt9.js +94 -0
  16. package/cloud.script-bkbpcr96.js +19 -0
  17. package/code.command-nn48xzej.js +154 -0
  18. package/commandManifest.json +1 -1
  19. package/consoleToStderr-h5bryj94.js +7 -0
  20. package/context.command-s3mcmvpa.js +48 -0
  21. package/context.runner-k99nb5pk.js +21 -0
  22. package/{dependencyScanner-shs82ynp.js → dependencyScanner-ye2e6pdz.js} +2 -2
  23. package/{devTui-40ggmd99.js → devTui-q7k7bakd.js} +122 -40
  24. package/fileSys-5ngz93ga.js +9 -0
  25. package/guideline.command-sct4qnt5.js +42 -0
  26. package/guidelines/agentRule/agentRule.instruction.md +206 -25
  27. package/guidelines/conventions/conventions.instruction.md +79 -24
  28. package/guidelines/fieldRule/fieldRule.instruction.md +1 -0
  29. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  30. package/guidelines/queryRule/queryRule.instruction.md +17 -7
  31. package/guidelines/runtimeRule/runtimeRule.instruction.md +74 -0
  32. package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
  33. package/guidelines/transportRule/transportRule.instruction.md +51 -0
  34. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
  35. package/incrementalBuilder.proc.js +31 -48
  36. package/{index-h7yw2z9n.js → index-0bq14vr1.js} +8 -14
  37. package/index-13ffe9wp.js +69 -0
  38. package/index-22d57v4c.js +266 -0
  39. package/{index-fz5q3gd7.js → index-31yr441d.js} +10 -17
  40. package/index-3hx1z96c.js +87 -0
  41. package/index-3sq321ak.js +53 -0
  42. package/{index-kcxmv48c.js → index-3t7g9e4r.js} +45 -79
  43. package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
  44. package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
  45. package/{index-259dsnz3.js → index-5pc1qrbv.js} +5 -8
  46. package/index-7md2g9vw.js +6 -0
  47. package/index-8mna0947.js +187 -0
  48. package/{index-zry5nz81.js → index-8sf7wmdr.js} +51 -30
  49. package/{index-2tv3fdx4.js → index-9d9bgcx4.js} +342 -765
  50. package/index-9dp031by.js +12 -0
  51. package/{index-ne2qy0nk.js → index-ahemdr5n.js} +12 -12
  52. package/{index-ws5e0j51.js → index-as7xmyz8.js} +40 -24
  53. package/index-axzjaqve.js +1118 -0
  54. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  55. package/index-c6eggbee.js +123 -0
  56. package/index-d2242ksy.js +99 -0
  57. package/{index-a64esmtb.js → index-ddxvdd1p.js} +169 -305
  58. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  59. package/{index-pnqbkf5p.js → index-dzf3r49a.js} +6 -2
  60. package/{index-w8kmx1b6.js → index-fgq75haa.js} +198 -290
  61. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  62. package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
  63. package/{index-wt7qrtd4.js → index-mxav6j3c.js} +93 -232
  64. package/{index-gyd220p2.js → index-myhc3c1j.js} +554 -577
  65. package/{index-600zhnve.js → index-nv5976x3.js} +56 -197
  66. package/index-p6pbz9n5.js +25 -0
  67. package/{index-4edzf1gr.js → index-przybvy5.js} +77 -150
  68. package/index-smme4r47.js +49 -0
  69. package/{index-mak3cd28.js → index-w2zdcw3k.js} +137 -255
  70. package/index-wa5jbxj1.js +760 -0
  71. package/{index-v0qh106m.js → index-ww4z397j.js} +527 -723
  72. package/{index-j9yhg404.js → index-xqjwd384.js} +4 -7
  73. package/{index-7737gxcp.js → index-xqpzbab5.js} +107 -241
  74. package/index-xsjh6nzh.js +2729 -0
  75. package/{index-ktb5njgy.js → index-ygn77a5w.js} +47 -99
  76. package/index-ztp3e73t.js +700 -0
  77. package/index.js +23 -22
  78. package/{library.command-nbsky672.js → library.command-1gx04jgn.js} +4 -5
  79. package/{localRegistry.command-yeq57wjr.js → localRegistry.command-zndxj1q6.js} +22 -42
  80. package/{module.command-29vqzrh8.js → module.command-3waddk95.js} +8 -11
  81. package/{package.command-axv0abmn.js → package.command-zrc7br1y.js} +6 -7
  82. package/package.json +14 -5
  83. package/{page.command-vs9s3zrh.js → page.command-vpjgardh.js} +4 -5
  84. package/{primitive.command-cbxmqbtc.js → primitive.command-sz84tk4t.js} +9 -22
  85. package/prompter-ptaa3nk0.js +8 -0
  86. package/{quality.command-gmbs7nws.js → quality.command-g869hafs.js} +203 -376
  87. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  88. package/{repair.command-bqsjptsj.js → repair.command-chsnjvvv.js} +11 -35
  89. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  90. package/{scalar.command-6k1vhe9s.js → scalar.command-2v21newx.js} +7 -10
  91. package/skills/akan-code/SKILL.md +130 -0
  92. package/skills/akan-debug/SKILL.md +42 -0
  93. package/skills/akan-deps/SKILL.md +50 -0
  94. package/skills/akan-err/SKILL.md +39 -0
  95. package/skills/akan-module/SKILL.md +45 -0
  96. package/skills/akan-scaffold/SKILL.md +76 -0
  97. package/skills/akan-scalar/SKILL.md +52 -0
  98. package/skills/akan-service/SKILL.md +34 -0
  99. package/skills/akan-store/SKILL.md +67 -0
  100. package/skills/akan-ui/SKILL.md +63 -0
  101. package/skills/akan-validate/SKILL.md +44 -0
  102. package/{subspace.command-fwjfcts7.js → subspace.command-ckcbwfp1.js} +138 -67
  103. package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
  104. package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
  105. package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
  106. package/templates/appSample/lib/task/task.abstract.ts +12 -32
  107. package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
  108. package/templates/appSample/lib/task/task.signal.test.ts +15 -1
  109. package/templates/appSample/lib/task/task.signal.ts +1 -1
  110. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
  111. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
  112. package/templates/client.ts +7 -30
  113. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
  114. package/templates/crudPages/[__model__Id]/page.tsx +2 -1
  115. package/templates/crudPages/new/page.tsx +2 -1
  116. package/templates/crudPages/page.tsx +2 -1
  117. package/templates/crudSinglePage/page.tsx +2 -1
  118. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  119. package/templates/lib/__lib/lib.document.ts +0 -2
  120. package/templates/lib/sig.ts +8 -30
  121. package/templates/localDev/docker-compose.yaml.template +3 -14
  122. package/templates/module/__model__.signal.ts +12 -4
  123. package/templates/pkgRoot/tsconfig.json.template +2 -7
  124. package/templates/server.ts +0 -2
  125. package/templates/service/__model__.abstract.md.template +8 -0
  126. package/tunnel.command-kd2yr4fx.js +129 -0
  127. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  128. package/typecheck.proc.js +1 -1
  129. package/workflow.command-44252cqv.js +79 -0
  130. package/{workspace.command-8s050m0h.js → workspace.command-fqcztt5p.js} +77 -109
  131. package/abstractCompactor-mjh5ppsq.js +0 -101
  132. package/cloud.command-jshwdq22.js +0 -93
  133. package/context.command-ez8a0zyz.js +0 -80
  134. package/devTuiView-c08ccbat.js +0 -9
  135. package/getDirname-dr3jz1xg.js +0 -7
  136. package/guideline.command-xmqwx8zm.js +0 -359
  137. package/guidelines/agentRule/agentRule.generate.json +0 -31
  138. package/guidelines/componentRule/componentRule.generate.json +0 -31
  139. package/guidelines/conventions/conventions.generate.json +0 -25
  140. package/guidelines/cssRule/cssRule.generate.json +0 -31
  141. package/guidelines/docPageRule/docPageRule.generate.json +0 -31
  142. package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
  143. package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
  144. package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
  145. package/guidelines/enumConstant/enumConstant.generate.json +0 -31
  146. package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
  147. package/guidelines/fieldRule/fieldRule.generate.json +0 -31
  148. package/guidelines/framework/framework.generate.json +0 -32
  149. package/guidelines/mcpRule/mcpRule.generate.json +0 -35
  150. package/guidelines/modelConstant/modelConstant.generate.json +0 -32
  151. package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
  152. package/guidelines/modelDocument/modelDocument.generate.json +0 -31
  153. package/guidelines/modelService/modelService.generate.json +0 -31
  154. package/guidelines/modelSignal/modelSignal.generate.json +0 -31
  155. package/guidelines/modelStore/modelStore.generate.json +0 -31
  156. package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
  157. package/guidelines/modelUnit/modelUnit.generate.json +0 -31
  158. package/guidelines/modelUtil/modelUtil.generate.json +0 -31
  159. package/guidelines/modelView/modelView.generate.json +0 -31
  160. package/guidelines/modelZone/modelZone.generate.json +0 -31
  161. package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
  162. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
  163. package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
  164. package/guidelines/queryRule/queryRule.generate.json +0 -31
  165. package/guidelines/recipeRule/recipeRule.generate.json +0 -31
  166. package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
  167. package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
  168. package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
  169. package/guidelines/scalarModule/scalarModule.generate.json +0 -31
  170. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
  171. package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
  172. package/guidelines/ssrRule/ssrRule.generate.json +0 -31
  173. package/guidelines/transportRule/transportRule.generate.json +0 -31
  174. package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
  175. package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
  176. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
  177. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
  178. package/index-2hq52jq3.js +0 -465
  179. package/index-6wwzs1bc.js +0 -7
  180. package/index-8pm30m73.js +0 -841
  181. package/index-kn1h7p1x.js +0 -560
  182. package/index-meh558jy.js +0 -65
  183. package/index-rwg2aa4f.js +0 -229
  184. package/templates/__scalar/__model__/__model__.abstract.md +0 -28
  185. package/templates/module/__model__.abstract.md +0 -28
  186. package/templates/service/__model__.abstract.md +0 -28
  187. package/workflow.command-nwpcdc8p.js +0 -107
@@ -7,24 +7,25 @@ import {
7
7
  isScannedRootEntry,
8
8
  AppExecutor,
9
9
  LibExecutor
10
- } from "./index-2tv3fdx4.js";
10
+ } from "./index-9d9bgcx4.js";
11
11
  import {
12
- FileSys
13
- } from "./index-q0y2jq9j.js";
12
+ FileSys2
13
+ } from "./index-5b6tavv3.js";
14
14
  import {
15
15
  collectRecipeSources2,
16
16
  scanRecipes2,
17
17
  findInlineRecipeDuplicates2
18
- } from "./index-by5gpp8x.js";
18
+ } from "./index-hj6w4ka1.js";
19
19
  import {
20
+ workflowPathsForPlan,
20
21
  workflowRunArtifactPath,
21
22
  workflowSyncDir
22
- } from "./index-gyd220p2.js";
23
+ } from "./index-myhc3c1j.js";
23
24
 
24
25
  // pkgs/@akanjs/devkit/akanContext.ts
25
26
  import { readdir } from "fs/promises";
26
27
  import path from "path";
27
- import { capitalize } from "akanjs/common";
28
+ import { capitalize, isRecord } from "akanjs/common";
28
29
  var guidelineResourceUri = (name) => `akan://guidelines/${name}`;
29
30
  var staticResourceList = [
30
31
  { uri: "akan://docs/framework", name: "Akan framework guide", mimeType: "text/markdown" },
@@ -52,16 +53,13 @@ var akanMcpInstallConfigPaths = {
52
53
  var cursorWorkspaceFolder = "$" + "{workspaceFolder}";
53
54
  var claudeProjectDir = "$CLAUDE_PROJECT_DIR";
54
55
  var akanMcpCommand = (mode, { cd } = {}) => cd ? `cd "${cd}" && akan mcp --mode ${mode}` : `akan mcp --mode ${mode}`;
55
- var createAkanCursorMcpServer = (mode = "readonly") => ({
56
+ var bashMcpServer = (mode, cd) => ({
56
57
  type: "stdio",
57
58
  command: "bash",
58
- args: ["-lc", akanMcpCommand(mode, { cd: cursorWorkspaceFolder })]
59
- });
60
- var createAkanClaudeMcpServer = (mode = "readonly") => ({
61
- type: "stdio",
62
- command: "bash",
63
- args: ["-lc", akanMcpCommand(mode, { cd: claudeProjectDir })]
59
+ args: ["-lc", akanMcpCommand(mode, { cd })]
64
60
  });
61
+ var createAkanCursorMcpServer = (mode = "readonly") => bashMcpServer(mode, cursorWorkspaceFolder);
62
+ var createAkanClaudeMcpServer = (mode = "readonly") => bashMcpServer(mode, claudeProjectDir);
65
63
  var createAkanMcpServer = (target, mode = "readonly") => target === "cursor" ? createAkanCursorMcpServer(mode) : createAkanClaudeMcpServer(mode);
66
64
  var akanCursorMcpServer = createAkanCursorMcpServer();
67
65
  var codexMcpServerTableHeader = "[mcp_servers.akan]";
@@ -164,41 +162,13 @@ var moduleShapeFiles = (module) => {
164
162
  ];
165
163
  };
166
164
  var constantFieldNames = (content) => [...content.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*field\(/g)].map((match) => match[1]).filter(Boolean);
167
- var safeReadDir = async (dirPath) => {
168
- try {
169
- return (await readdir(dirPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
170
- } catch {
171
- return [];
172
- }
173
- };
174
- var safeReadText = async (filePath) => {
175
- try {
176
- return await FileSys.readText(filePath);
177
- } catch {
178
- return null;
179
- }
180
- };
181
- var safeReadJson = async (filePath) => {
182
- try {
183
- return await FileSys.readJson(filePath);
184
- } catch {
185
- return null;
186
- }
187
- };
188
- var isWorkflowPlan = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && value.mode === "plan";
189
- var isWorkflowApplyReport = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && (value.mode === "apply" || value.mode === "dry-run");
165
+ var safeReadDir = async (dirPath) => (await readdir(dirPath, { withFileTypes: true }).catch(() => [])).sort((a, b) => a.name.localeCompare(b.name));
166
+ var safeReadText = (filePath) => FileSys2.readText(filePath).catch(() => null);
167
+ var safeReadJson = (filePath) => FileSys2.readJson(filePath).catch(() => null);
168
+ var isWorkflowPlan = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && value.mode === "plan" && ("inputs" in value) && isRecord(value.inputs) && ("predictedChanges" in value) && Array.isArray(value.predictedChanges) && value.predictedChanges.every((change) => isRecord(change) && typeof change.target === "string");
169
+ var isPathList = (value) => Array.isArray(value) && value.every((file) => isRecord(file) && typeof file.path === "string");
170
+ var isWorkflowApplyReport = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && (value.mode === "apply" || value.mode === "dry-run") && ("changedFiles" in value) && isPathList(value.changedFiles) && ("generatedFiles" in value) && isPathList(value.generatedFiles) && ("plan" in value) && isWorkflowPlan(value.plan);
190
171
  var isWorkflowRunArtifact = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1;
191
- var planInputString = (plan, key) => {
192
- const value = plan.inputs[key];
193
- return typeof value === "string" ? value : "";
194
- };
195
- var expandWorkflowTarget = (target, plan) => {
196
- const app = planInputString(plan, "app");
197
- const module = planInputString(plan, "module");
198
- const moduleClass = module ? capitalize(module) : "<Module>";
199
- return target.replace(/^\*\//, app ? `apps/${app}/` : "").replaceAll("<module>", module || "<module>").replaceAll("<Module>", moduleClass);
200
- };
201
- var workflowPathsForPlan = (plan) => plan.predictedChanges.map((change) => expandWorkflowTarget(change.target, plan));
202
172
  var workflowPathsForArtifact = (artifact) => {
203
173
  if (isWorkflowPlan(artifact))
204
174
  return workflowPathsForPlan(artifact);
@@ -209,7 +179,7 @@ var workflowPathsForArtifact = (artifact) => {
209
179
  ...workflowPathsForPlan(artifact.plan)
210
180
  ];
211
181
  }
212
- if ("mode" in artifact && artifact.mode === "validate" && artifact.plan)
182
+ if ("mode" in artifact && artifact.mode === "validate" && isWorkflowPlan(artifact.plan))
213
183
  return workflowPathsForPlan(artifact.plan);
214
184
  return [];
215
185
  };
@@ -310,13 +280,13 @@ var getSysModules = async (workspace, sys, {
310
280
  const serviceName = entry.name.replace(/^_+/, "");
311
281
  if (moduleFilter && moduleFilter !== serviceName && moduleFilter !== entry.name)
312
282
  continue;
313
- if (!await FileSys.fileExists(path.join(libPath, entry.name, `${serviceName}.service.ts`)))
283
+ if (!await FileSys2.fileExists(path.join(libPath, entry.name, `${serviceName}.service.ts`)))
314
284
  continue;
315
285
  modules.push(await createModuleContext(workspace, sys, "service", entry.name, serviceName, includeAbstractContent));
316
286
  } else {
317
287
  if (moduleFilter && moduleFilter !== entry.name)
318
288
  continue;
319
- if (!await FileSys.fileExists(path.join(libPath, entry.name, `${entry.name}.constant.ts`)))
289
+ if (!await FileSys2.fileExists(path.join(libPath, entry.name, `${entry.name}.constant.ts`)))
320
290
  continue;
321
291
  modules.push(await createModuleContext(workspace, sys, "domain", entry.name, entry.name, includeAbstractContent));
322
292
  }
@@ -327,7 +297,7 @@ var getSysModules = async (workspace, sys, {
327
297
  continue;
328
298
  if (moduleFilter && moduleFilter !== entry.name)
329
299
  continue;
330
- if (!await FileSys.fileExists(path.join(scalarRoot, entry.name, `${entry.name}.constant.ts`)))
300
+ if (!await FileSys2.fileExists(path.join(scalarRoot, entry.name, `${entry.name}.constant.ts`)))
331
301
  continue;
332
302
  modules.push(await createModuleContext(workspace, sys, "scalar", entry.name, entry.name, includeAbstractContent));
333
303
  }
@@ -339,7 +309,7 @@ var getSysContext = async (workspace, type, name, options) => {
339
309
  type,
340
310
  name,
341
311
  path: `${type}s/${name}`,
342
- hasConfig: await FileSys.fileExists(path.join(sys.cwdPath, "akan.config.ts")),
312
+ hasConfig: await FileSys2.fileExists(path.join(sys.cwdPath, "akan.config.ts")),
343
313
  modules: await getSysModules(workspace, sys, {
344
314
  includeAbstractContent: options.includeAbstractContent,
345
315
  module: options.module
@@ -411,62 +381,46 @@ class AkanContextAnalyzer {
411
381
  repairAction("generated", "akan repair generated --app <app-or-lib>", "Refresh generated Akan files.", true),
412
382
  repairAction("format", "akan repair format --target <app-or-lib-or-pkg>", "Run the formatter/linter repair path.", true)
413
383
  ];
384
+ const report = (diagnostic, action) => {
385
+ diagnostics.push({ ...diagnostic, repairActions: [action] });
386
+ repairActions.push(action);
387
+ };
414
388
  for (const sys of [...context.apps, ...context.libs]) {
415
389
  const sysPath = path.join(workspace.workspaceRoot, sys.path);
416
390
  for (const entry of await safeReadDir(sysPath)) {
417
391
  if (!isScannedRootEntry(sys.type, entry.name))
418
392
  continue;
419
393
  const allowed = entry.isDirectory() ? rootAllowedDirs[sys.type].has(entry.name) : rootAllowedFiles[sys.type].has(entry.name);
420
- if (!allowed) {
421
- const action = repairAction("module-shape", `akan repair module-shape --app ${sys.name}`, `Review ${sys.type} root shape and remove or move the unknown entry.`, false);
422
- diagnostics.push({
394
+ if (!allowed)
395
+ report({
423
396
  severity: "error",
424
397
  code: `${sys.type}-root-unknown-entry`,
425
398
  path: `${sys.path}/${entry.name}`,
426
- message: `Unexpected ${entry.isDirectory() ? "folder" : "file"} in ${sys.type} root: ${sys.path}/${entry.name}`,
427
- repairActions: [action]
428
- });
429
- repairActions.push(action);
430
- }
399
+ message: `Unexpected ${entry.isDirectory() ? "folder" : "file"} in ${sys.type} root: ${sys.path}/${entry.name}`
400
+ }, repairAction("module-shape", `akan repair module-shape --app ${sys.name}`, `Review ${sys.type} root shape and remove or move the unknown entry.`, false));
431
401
  }
432
402
  }
433
403
  const agentDrift = await AkanContextAnalyzer.#agentGuideDrift(workspace);
434
- if (agentDrift) {
435
- const action = repairAction("generated", "akan agent install agents-md", agentDrift.hint, true);
436
- diagnostics.push({
437
- severity: "warning",
438
- code: agentDrift.code,
439
- path: "AGENTS.md",
440
- message: agentDrift.message,
441
- repairActions: [action]
442
- });
443
- repairActions.push(action);
444
- }
404
+ if (agentDrift)
405
+ report({ severity: "warning", code: agentDrift.code, path: "AGENTS.md", message: agentDrift.message }, repairAction("generated", "akan agent install agents-md", agentDrift.hint, true));
445
406
  for (const sys of [...context.apps, ...context.libs]) {
446
407
  for (const module of sys.modules) {
447
- if (!module.abstract.exists) {
448
- const action = repairAction("module-shape", `akan repair module-shape --app ${sys.name} --module ${module.name}`, "Create the missing module abstract or inspect required source files.", false);
449
- diagnostics.push({
408
+ const moduleShapeCommand = `akan repair module-shape --app ${sys.name} --module ${module.name}`;
409
+ if (!module.abstract.exists)
410
+ report({
450
411
  severity: strict ? "error" : "warning",
451
412
  code: "module-abstract-missing",
452
413
  path: module.abstract.path,
453
- message: `${capitalize(module.kind)} module ${sys.name}:${module.name} should include ${module.abstract.path}`,
454
- repairActions: [action]
455
- });
456
- repairActions.push(action);
457
- }
414
+ message: `${capitalize(module.kind)} module ${sys.name}:${module.name} should include ${module.abstract.path}`
415
+ }, repairAction("module-shape", moduleShapeCommand, "Create the missing module abstract or inspect required source files.", false));
458
416
  const missingFiles = moduleShapeFiles(module).filter((filename) => !module.files.includes(filename));
459
- if (missingFiles.length) {
460
- const action = repairAction("module-shape", `akan repair module-shape --app ${sys.name} --module ${module.name}`, "Review missing required module source files.", false);
461
- diagnostics.push({
417
+ if (missingFiles.length)
418
+ report({
462
419
  severity: "error",
463
420
  code: "module-shape-invalid",
464
421
  path: module.path,
465
- message: `${capitalize(module.kind)} module ${sys.name}:${module.name} is missing required files: ${missingFiles.join(", ")}`,
466
- repairActions: [action]
467
- });
468
- repairActions.push(action);
469
- }
422
+ message: `${capitalize(module.kind)} module ${sys.name}:${module.name} is missing required files: ${missingFiles.join(", ")}`
423
+ }, repairAction("module-shape", moduleShapeCommand, "Review missing required module source files.", false));
470
424
  if (module.kind !== "service" && module.files.includes(`${module.name}.dictionary.ts`)) {
471
425
  const constantPath = path.join(workspace.workspaceRoot, module.path, `${module.name}.constant.ts`);
472
426
  const dictionaryPath = path.join(workspace.workspaceRoot, module.path, `${module.name}.dictionary.ts`);
@@ -478,15 +432,12 @@ class AkanContextAnalyzer {
478
432
  for (const fieldName of constantFieldNames(constantContent)) {
479
433
  if (new RegExp(`\\b${fieldName}\\s*:`).test(dictionaryContent))
480
434
  continue;
481
- const action = repairAction("dictionary", `akan repair dictionary --app ${sys.name} --module ${module.name}`, "Add missing dictionary labels for source constant fields.", false);
482
- diagnostics.push({
435
+ report({
483
436
  severity: "warning",
484
437
  code: "dictionary-label-missing",
485
438
  path: `${module.path}/${module.name}.dictionary.ts`,
486
- message: `Dictionary labels for ${sys.name}:${module.name}.${fieldName} were not found.`,
487
- repairActions: [action]
488
- });
489
- repairActions.push(action);
439
+ message: `Dictionary labels for ${sys.name}:${module.name}.${fieldName} were not found.`
440
+ }, repairAction("dictionary", `akan repair dictionary --app ${sys.name} --module ${module.name}`, "Add missing dictionary labels for source constant fields.", false));
490
441
  }
491
442
  }
492
443
  }
@@ -554,19 +505,16 @@ class AkanContextAnalyzer {
554
505
  const pushIndexDiagnostic = (indexPath, missing, stale, repairCommand) => {
555
506
  if (missing.length === 0 && stale.length === 0)
556
507
  return;
557
- const action = repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true);
558
508
  const parts = [
559
509
  missing.length > 0 ? `${missing.length} declared but unlisted (${missing.slice(0, 5).join(", ")})` : "",
560
510
  stale.length > 0 ? `${stale.length} listed but gone (${stale.slice(0, 5).join(", ")})` : ""
561
511
  ].filter(Boolean);
562
- diagnostics.push({
512
+ report({
563
513
  severity: "error",
564
514
  code: "recipe-index-stale",
565
515
  path: indexPath,
566
- message: `${indexPath} recipe index is out of date \u2014 ${parts.join("; ")}. Agents read this list as authoritative.`,
567
- repairActions: [action]
568
- });
569
- repairActions.push(action);
516
+ message: `${indexPath} recipe index is out of date \u2014 ${parts.join("; ")}. Agents read this list as authoritative.`
517
+ }, repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true));
570
518
  };
571
519
  const frameworkDeclared = declaredByImport.get("akanjs/ui") ?? new Set;
572
520
  if (frameworkDeclared.size > 0) {