@akanjs/cli 3.0.0-beta.9 → 3.0.1

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 (224) hide show
  1. package/.build-stamp +1 -1
  2. package/CodeAgent-zfab7pkn.js +9 -0
  3. package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
  4. package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
  5. package/CodeTui-0zhnr0pw.js +1457 -0
  6. package/README.ko.md +83 -28
  7. package/README.md +70 -27
  8. package/TunnelShare-cwh9ezsm.js +9 -0
  9. package/{agent.command-0q17pnrs.js → agent.command-aja6z9mn.js} +8 -9
  10. package/akanCode.js +102 -0
  11. package/application.command-049ehgx3.js +246 -0
  12. package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-75n5rpwp.js} +121 -77
  13. package/buildBatch.proc.js +120 -32
  14. package/cloud.command-gw4kqxt8.js +95 -0
  15. package/cloud.script-c723cpcb.js +20 -0
  16. package/code.command-x9t6z5nw.js +154 -0
  17. package/commandManifest.json +1 -1
  18. package/consoleToStderr-h5bryj94.js +7 -0
  19. package/context.command-yfbe1rtd.js +48 -0
  20. package/context.runner-erfe68j5.js +21 -0
  21. package/{dependencyScanner-shs82ynp.js → dependencyScanner-06z2dmrr.js} +2 -2
  22. package/{devTui-m1atgkc9.js → devTui-q7k7bakd.js} +122 -40
  23. package/fileSys-wzzrntkw.js +9 -0
  24. package/guideline.command-kq9gp690.js +42 -0
  25. package/guidelines/agentRule/agentRule.instruction.md +154 -26
  26. package/guidelines/conventions/conventions.instruction.md +138 -48
  27. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  28. package/guidelines/queryRule/queryRule.instruction.md +21 -7
  29. package/guidelines/runtimeRule/runtimeRule.instruction.md +291 -6
  30. package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
  31. package/guidelines/transportRule/transportRule.instruction.md +10 -8
  32. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +20 -0
  33. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
  34. package/incrementalBuilder.proc.js +564 -109
  35. package/{index-2tv3fdx4.js → index-150s07n8.js} +1230 -1459
  36. package/{index-vyvre9en.js → index-25fvrxmy.js} +6 -2
  37. package/{index-kcxmv48c.js → index-2ahj896a.js} +45 -79
  38. package/index-2wc41k5w.js +49 -0
  39. package/index-3hx1z96c.js +87 -0
  40. package/{index-q0y2jq9j.js → index-52w0fvh8.js} +21 -4
  41. package/{index-04bk599g.js → index-5g4rkrvt.js} +10 -17
  42. package/index-5pvxf7z0.js +53 -0
  43. package/index-5q14pwzd.js +69 -0
  44. package/{index-vxtad5bd.js → index-66yspb67.js} +5 -8
  45. package/index-7md2g9vw.js +6 -0
  46. package/index-7p4c0yer.js +1058 -0
  47. package/{index-d43r08tf.js → index-8b639zes.js} +77 -150
  48. package/{index-ktb5njgy.js → index-8kvy8qb4.js} +49 -99
  49. package/index-94s080qm.js +266 -0
  50. package/index-9dp031by.js +12 -0
  51. package/{index-0g7r8xz3.js → index-a37by9hn.js} +114 -232
  52. package/{index-k2j1hc4r.js → index-b95yhqjr.js} +12 -12
  53. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  54. package/{index-2xp0kfkt.js → index-br8pkrk1.js} +37 -25
  55. package/index-c14nsvnv.js +700 -0
  56. package/index-c6eggbee.js +123 -0
  57. package/index-d2242ksy.js +99 -0
  58. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  59. package/{index-a64esmtb.js → index-fkvb79qe.js} +523 -1022
  60. package/index-h54yj9wr.js +1119 -0
  61. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  62. package/{index-y6n8nmny.js → index-kn5d4jmg.js} +75 -203
  63. package/index-m3xsb1ms.js +4300 -0
  64. package/{index-gyd220p2.js → index-mb59b8x0.js} +554 -577
  65. package/{index-j9yhg404.js → index-mzjb6zp4.js} +4 -7
  66. package/index-p6pbz9n5.js +25 -0
  67. package/{index-sj5vxr8f.js → index-qe71g4ze.js} +983 -898
  68. package/index-rfcz04w9.js +187 -0
  69. package/{index-hwkygn9s.js → index-senscydg.js} +331 -36
  70. package/{index-ffvk10zz.js → index-vs8mefhy.js} +107 -241
  71. package/index-wa5jbxj1.js +760 -0
  72. package/index-y5ga5w9t.js +2729 -0
  73. package/{index-9077wzd2.js → index-y7hx1ygz.js} +43 -26
  74. package/{index-h7yw2z9n.js → index-zzvvc845.js} +8 -14
  75. package/index.js +23 -22
  76. package/{library.command-qzzbj6d8.js → library.command-keqjevpp.js} +4 -5
  77. package/{localRegistry.command-vyrgg4xw.js → localRegistry.command-pydeq5zf.js} +23 -43
  78. package/{module.command-rq5hq3ax.js → module.command-dkrnqx3v.js} +8 -12
  79. package/{package.command-d9hd6v9n.js → package.command-wmc0ys5y.js} +6 -7
  80. package/package.json +15 -7
  81. package/{page.command-126d56te.js → page.command-tf3erhrv.js} +4 -5
  82. package/{primitive.command-taxd1538.js → primitive.command-7hqpegj4.js} +9 -23
  83. package/prompter-76k56b37.js +8 -0
  84. package/{quality.command-6gsna0a3.js → quality.command-8122axq3.js} +205 -377
  85. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  86. package/{repair.command-tq2dgy72.js → repair.command-mcy12h0n.js} +11 -35
  87. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  88. package/{scalar.command-3bcmrrkv.js → scalar.command-vvvbzttc.js} +7 -11
  89. package/skills/akan-code/SKILL.md +130 -0
  90. package/skills/akan-debug/SKILL.md +42 -0
  91. package/skills/akan-deps/SKILL.md +50 -0
  92. package/skills/akan-err/SKILL.md +39 -0
  93. package/skills/akan-module/SKILL.md +45 -0
  94. package/skills/akan-scaffold/SKILL.md +76 -0
  95. package/skills/akan-scalar/SKILL.md +52 -0
  96. package/skills/akan-service/SKILL.md +34 -0
  97. package/skills/akan-store/SKILL.md +67 -0
  98. package/skills/akan-ui/SKILL.md +63 -0
  99. package/skills/akan-validate/SKILL.md +44 -0
  100. package/{subspace.command-eddzqpx3.js → subspace.command-pzvqfy5h.js} +53 -62
  101. package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
  102. package/templates/app/page/_index.tsx +257 -258
  103. package/templates/app/page/_layout.tsx +5 -1
  104. package/templates/app/page/_overrides.tsx +12 -0
  105. package/templates/app/page/styles.css.template +316 -14
  106. package/templates/app/public/apple-touch-icon.png +0 -0
  107. package/templates/app/public/favicon.ico +0 -0
  108. package/templates/app/public/jelly/cloud.webp +0 -0
  109. package/templates/app/public/jelly/comet.webp +0 -0
  110. package/templates/app/public/jelly/moon.webp +0 -0
  111. package/templates/app/public/jelly/planet.webp +0 -0
  112. package/templates/app/public/jelly/rocket.webp +0 -0
  113. package/templates/app/public/jelly/star.webp +0 -0
  114. package/templates/app/public/jelly/sugar.webp +0 -0
  115. package/templates/app/public/logo.png +0 -0
  116. package/templates/app/ui/Recipe/index.ts +9 -0
  117. package/templates/app/ui/Recipe/jellyButton.ts +63 -0
  118. package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
  119. package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
  120. package/templates/appSample/lib/task/Task.Unit.tsx +1 -1
  121. package/templates/appSample/lib/task/Task.Util.tsx +10 -13
  122. package/templates/appSample/lib/task/Task.View.tsx +2 -2
  123. package/templates/appSample/lib/task/Task.Zone.tsx +5 -2
  124. package/templates/appSample/lib/task/task.abstract.ts +12 -32
  125. package/templates/appSample/lib/task/task.signal.spec.ts +1 -15
  126. package/templates/appSample/lib/task/task.signal.test.ts +15 -1
  127. package/templates/appSample/lib/task/task.signal.ts +10 -8
  128. package/templates/appSample/page/task/[taskId]/_index.tsx +6 -6
  129. package/templates/appSample/page/task/[taskId]/edit.tsx +5 -4
  130. package/templates/appSample/page/task/_index.tsx +4 -3
  131. package/templates/appSample/page/task/_layout.tsx +1 -1
  132. package/templates/appSample/page/task/new.tsx +5 -4
  133. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
  134. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
  135. package/templates/appSample/ui/GlobalLoading.tsx +2 -1
  136. package/templates/appSample/ui/QuantityControl.tsx +3 -3
  137. package/templates/client.ts +7 -30
  138. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
  139. package/templates/crudPages/[__model__Id]/page.tsx +2 -1
  140. package/templates/crudPages/new/page.tsx +2 -1
  141. package/templates/crudPages/page.tsx +2 -1
  142. package/templates/crudSinglePage/page.tsx +2 -1
  143. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  144. package/templates/lib/__lib/lib.document.ts +0 -2
  145. package/templates/lib/sig.ts +8 -30
  146. package/templates/localDev/docker-compose.yaml.template +3 -14
  147. package/templates/module/__model__.signal.ts +12 -4
  148. package/templates/pkgRoot/tsconfig.json.template +2 -7
  149. package/templates/server.ts +1 -3
  150. package/templates/service/__model__.abstract.md.template +8 -0
  151. package/templates/workspaceRoot/.gitignore.template +0 -1
  152. package/templates/workspaceRoot/AGENTS.md.template +6 -0
  153. package/templates/workspaceRoot/package.json.template +1 -3
  154. package/tunnel.command-82zz5xnq.js +129 -0
  155. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  156. package/typecheck.proc.js +1 -1
  157. package/workflow.command-y8x3kgjv.js +79 -0
  158. package/{workspace.command-06wvstgr.js → workspace.command-jvsb7brc.js} +79 -109
  159. package/abstractCompactor-gmkc0z8j.js +0 -102
  160. package/application.command-18y0s485.js +0 -204
  161. package/applicationReleasePackager-4yasxwv9.js +0 -244
  162. package/capacitorApp-36rbr858.js +0 -12
  163. package/cloud.command-av97ndh6.js +0 -94
  164. package/cloud.script-cm11xjdz.js +0 -20
  165. package/context.command-5v37ef3n.js +0 -81
  166. package/devTuiView-0hc2emhe.js +0 -9
  167. package/getDirname-dr3jz1xg.js +0 -7
  168. package/guideline.command-4pz9g1rt.js +0 -360
  169. package/guidelines/agentRule/agentRule.generate.json +0 -31
  170. package/guidelines/componentRule/componentRule.generate.json +0 -31
  171. package/guidelines/conventions/conventions.generate.json +0 -25
  172. package/guidelines/cssRule/cssRule.generate.json +0 -31
  173. package/guidelines/docPageRule/docPageRule.generate.json +0 -31
  174. package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
  175. package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
  176. package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
  177. package/guidelines/enumConstant/enumConstant.generate.json +0 -31
  178. package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
  179. package/guidelines/fieldRule/fieldRule.generate.json +0 -31
  180. package/guidelines/framework/framework.generate.json +0 -32
  181. package/guidelines/mcpRule/mcpRule.generate.json +0 -35
  182. package/guidelines/modelConstant/modelConstant.generate.json +0 -32
  183. package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
  184. package/guidelines/modelDocument/modelDocument.generate.json +0 -31
  185. package/guidelines/modelService/modelService.generate.json +0 -31
  186. package/guidelines/modelSignal/modelSignal.generate.json +0 -31
  187. package/guidelines/modelStore/modelStore.generate.json +0 -31
  188. package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
  189. package/guidelines/modelUnit/modelUnit.generate.json +0 -31
  190. package/guidelines/modelUtil/modelUtil.generate.json +0 -31
  191. package/guidelines/modelView/modelView.generate.json +0 -31
  192. package/guidelines/modelZone/modelZone.generate.json +0 -31
  193. package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
  194. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
  195. package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
  196. package/guidelines/queryRule/queryRule.generate.json +0 -31
  197. package/guidelines/recipeRule/recipeRule.generate.json +0 -31
  198. package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
  199. package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
  200. package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
  201. package/guidelines/scalarModule/scalarModule.generate.json +0 -31
  202. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
  203. package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
  204. package/guidelines/ssrRule/ssrRule.generate.json +0 -31
  205. package/guidelines/transportRule/transportRule.generate.json +0 -31
  206. package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
  207. package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
  208. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
  209. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
  210. package/index-47pj3aee.js +0 -76
  211. package/index-5ystnsd5.js +0 -841
  212. package/index-6wwzs1bc.js +0 -7
  213. package/index-a17x49vg.js +0 -229
  214. package/index-m0xccmmm.js +0 -228
  215. package/index-meh558jy.js +0 -65
  216. package/index-rtxxan88.js +0 -471
  217. package/index-te54x9zm.js +0 -338
  218. package/index-w8kmx1b6.js +0 -2176
  219. package/index-wt7qrtd4.js +0 -1516
  220. package/templates/__scalar/__model__/__model__.abstract.md +0 -28
  221. package/templates/module/__model__.abstract.md +0 -28
  222. package/templates/service/__model__.abstract.md +0 -28
  223. package/templates/workspaceRoot/patches/react-dom@19.2.7.patch.template +0 -62
  224. package/workflow.command-gtdnzvbz.js +0 -108
@@ -1,23 +1,25 @@
1
1
  // @bun
2
2
  import {
3
3
  script
4
- } from "./index-0g7r8xz3.js";
4
+ } from "./index-a37by9hn.js";
5
5
  import {
6
6
  AppExecutor,
7
7
  LibExecutor,
8
8
  ModuleExecutor
9
- } from "./index-2tv3fdx4.js";
9
+ } from "./index-150s07n8.js";
10
10
  import {
11
+ workflowStatus,
11
12
  compactDiagnostics,
12
- createPrimitiveWriteReport,
13
13
  sourceFile,
14
14
  moduleComponentName,
15
15
  moduleSourcePaths,
16
16
  generatedFilesForSync,
17
17
  validationCommandsForTarget,
18
18
  nextActionsForTarget,
19
- lowerlize,
19
+ createPrimitiveWriteReport,
20
20
  normalizeFieldType,
21
+ ensureNamedImport,
22
+ ensureBaseImport,
21
23
  ensureBaseTypeImport,
22
24
  coerceFieldDefault,
23
25
  fieldExpression,
@@ -39,13 +41,13 @@ import {
39
41
  hasSignalFactoryEntry,
40
42
  insertSignalFactoryEntry,
41
43
  addFieldUiPolicyForType
42
- } from "./index-gyd220p2.js";
44
+ } from "./index-mb59b8x0.js";
43
45
  import {
44
46
  ModuleScript
45
- } from "./index-5ystnsd5.js";
47
+ } from "./index-rfcz04w9.js";
46
48
 
47
49
  // pkgs/@akanjs/cli/primitive/primitive.script.ts
48
- import { capitalize } from "akanjs/common";
50
+ import { capitalize, lowerlize } from "akanjs/common";
49
51
  class PrimitiveScript extends script("primitive", [ModuleScript]) {
50
52
  async resolveSys(workspace, target) {
51
53
  if (!target)
@@ -59,28 +61,11 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
59
61
  }
60
62
  async createUi(workspace, input) {
61
63
  const sys = await this.resolveSys(workspace, input.app);
62
- if (!sys || !input.module) {
63
- return createPrimitiveWriteReport({
64
- command: "create-ui",
65
- changedFiles: [],
66
- generatedFiles: [],
67
- validationCommands: [],
68
- diagnostics: compactDiagnostics([
69
- !sys && {
70
- severity: "error",
71
- code: "primitive-target-missing",
72
- message: "Target app or library was not found."
73
- },
74
- !input.module && {
75
- severity: "error",
76
- code: "primitive-input-missing",
77
- message: "Module is required.",
78
- input: "module"
79
- }
80
- ]),
81
- nextActions: []
82
- });
83
- }
64
+ if (!sys || !input.module)
65
+ return PrimitiveScript.#refuse("create-ui", compactDiagnostics([
66
+ !sys && PrimitiveScript.#targetMissing(),
67
+ !input.module && PrimitiveScript.#inputMissing("module")
68
+ ]));
84
69
  const mod = ModuleExecutor.from(sys, input.module);
85
70
  if (input.surface === "view")
86
71
  return await this.moduleScript.createView(mod);
@@ -96,30 +81,16 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
96
81
  return await this.addFieldToSources(workspace, { ...input, type: `${capitalize(input.field ?? "")}` }, { enumValues: values });
97
82
  }
98
83
  async addFieldToSources(workspace, input, { enumValues }) {
84
+ const command = enumValues ? "add-enum-field" : "add-field";
99
85
  const sys = await this.resolveSys(workspace, input.app);
100
86
  const ambiguousNumberTypes = new Set(["number", "numeric"]);
101
87
  const normalizedType = input.type ? normalizeFieldType(input.type) : null;
102
88
  const diagnostics = compactDiagnostics([
103
- !sys && { severity: "error", code: "primitive-target-missing", message: "Target app or library was not found." },
104
- !input.module && {
105
- severity: "error",
106
- code: "primitive-input-missing",
107
- message: "Module is required.",
108
- input: "module"
109
- },
110
- !input.field && {
111
- severity: "error",
112
- code: "primitive-input-missing",
113
- message: "Field is required.",
114
- input: "field"
115
- },
116
- !input.type && {
117
- severity: "error",
118
- code: "primitive-input-missing",
119
- message: "Type is required.",
120
- input: "type"
121
- },
122
- enumValues && enumValues.length === 0 ? { severity: "error", code: "primitive-input-missing", message: "Enum values are required.", input: "values" } : null,
89
+ !sys && PrimitiveScript.#targetMissing(),
90
+ !input.module && PrimitiveScript.#inputMissing("module"),
91
+ !input.field && PrimitiveScript.#inputMissing("field"),
92
+ !input.type && PrimitiveScript.#inputMissing("type"),
93
+ enumValues?.length === 0 && PrimitiveScript.#inputMissing("values", "Enum values are required."),
123
94
  input.type && ambiguousNumberTypes.has(input.type.toLowerCase()) ? {
124
95
  severity: "error",
125
96
  code: "primitive-field-type-unsupported",
@@ -133,16 +104,8 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
133
104
  input: "type"
134
105
  } : null
135
106
  ]);
136
- if (!sys || !input.module || !input.field || !input.type || diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
137
- return createPrimitiveWriteReport({
138
- command: enumValues ? "add-enum-field" : "add-field",
139
- changedFiles: [],
140
- generatedFiles: [],
141
- validationCommands: [],
142
- diagnostics,
143
- nextActions: []
144
- });
145
- }
107
+ if (!sys || !input.module || !input.field || !input.type || workflowStatus(diagnostics) === "failed")
108
+ return PrimitiveScript.#refuse(command, diagnostics);
146
109
  const moduleClassName = moduleComponentName(input.module);
147
110
  const inputClassName = `${moduleClassName}Input`;
148
111
  const paths = moduleSourcePaths(input.module);
@@ -150,32 +113,13 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
150
113
  const dictionaryPath = paths.dictionary;
151
114
  const templatePath = paths.template;
152
115
  const changedFiles = [];
153
- const generatedFiles = generatedFilesForSync(sys);
154
116
  const [hasConstant, hasDictionary] = await Promise.all([sys.exists(constantPath), sys.exists(dictionaryPath)]);
155
- if (!hasConstant) {
156
- diagnostics.push({
157
- severity: "error",
158
- code: "primitive-source-missing",
159
- message: `Constant source file was not found: ${constantPath}.`
160
- });
161
- }
162
- if (!hasDictionary) {
163
- diagnostics.push({
164
- severity: "error",
165
- code: "primitive-source-missing",
166
- message: `Dictionary source file was not found: ${dictionaryPath}.`
167
- });
168
- }
169
- if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
170
- return createPrimitiveWriteReport({
171
- command: enumValues ? "add-enum-field" : "add-field",
172
- changedFiles,
173
- generatedFiles,
174
- validationCommands: validationCommandsForTarget(sys.name),
175
- diagnostics,
176
- nextActions: nextActionsForTarget(sys.name)
177
- });
178
- }
117
+ if (!hasConstant)
118
+ diagnostics.push(PrimitiveScript.#sourceMissing("Constant", constantPath));
119
+ if (!hasDictionary)
120
+ diagnostics.push(PrimitiveScript.#sourceMissing("Dictionary", dictionaryPath));
121
+ if (workflowStatus(diagnostics) === "failed")
122
+ return PrimitiveScript.#report(command, sys, changedFiles, diagnostics);
179
123
  let constantContent = await sys.readFile(constantPath);
180
124
  let dictionaryContent = await sys.readFile(dictionaryPath);
181
125
  const fieldBuilderName = viaBuilderParameterName(constantContent, inputClassName) ?? "field";
@@ -210,6 +154,8 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
210
154
  if (defaultCoercion.diagnostic)
211
155
  diagnostics.push(defaultCoercion.diagnostic);
212
156
  constantContent = ensureBaseTypeImport(constantContent, input.type);
157
+ if (input.type === "Date" && defaultCoercion.expression)
158
+ constantContent = ensureBaseImport(constantContent, "dayjs");
213
159
  }
214
160
  if (enumValues) {
215
161
  const defaultCoercion = coerceFieldDefault("enum", input.defaultValue, { enumValues });
@@ -311,7 +257,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
311
257
  }
312
258
  }
313
259
  }
314
- if (!diagnostics.some((diagnostic) => diagnostic.severity === "error") && nextConstantContentWithLight && nextDictionaryContent) {
260
+ if (workflowStatus(diagnostics) === "passed" && nextConstantContentWithLight && nextDictionaryContent) {
315
261
  await sys.writeFile(constantPath, nextConstantContentWithLight);
316
262
  await sys.writeFile(dictionaryPath, nextDictionaryContent);
317
263
  changedFiles.push(sourceFile(sys, constantPath, "modify", "Field source shape was updated."), sourceFile(sys, dictionaryPath, "modify", "Field dictionary labels were updated."));
@@ -320,14 +266,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
320
266
  changedFiles.push(sourceFile(sys, templatePath, "modify", "Template field surface was updated."));
321
267
  }
322
268
  }
323
- return createPrimitiveWriteReport({
324
- command: enumValues ? "add-enum-field" : "add-field",
325
- changedFiles,
326
- generatedFiles,
327
- validationCommands: validationCommandsForTarget(sys.name),
328
- diagnostics,
329
- nextActions: nextActionsForTarget(sys.name)
330
- });
269
+ return PrimitiveScript.#report(command, sys, changedFiles, diagnostics);
331
270
  }
332
271
  async addMutation(workspace, input) {
333
272
  const moduleClassName = input.module ? moduleComponentName(input.module) : "";
@@ -353,7 +292,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
353
292
  signal: name ? {
354
293
  className: `${moduleClassName}Endpoint`,
355
294
  entryLine: [
356
- `${name}: mutation(Boolean)`,
295
+ `${name}: mutation(Boolean, { guards: [None] })`,
357
296
  ` .exec(async function () {`,
358
297
  ` return await this.${serviceRef}Service.${name}();`,
359
298
  ` }),`
@@ -388,7 +327,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
388
327
  signal: name && queryName ? {
389
328
  className: `${moduleClassName}Slice`,
390
329
  entryLine: [
391
- `${name}: init()`,
330
+ `${name}: init({ guards: [None] })`,
392
331
  ` .exec(function () {`,
393
332
  ` return this.${serviceRef}Service.${queryName}();`,
394
333
  ` }),`
@@ -401,60 +340,21 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
401
340
  async#writeServiceSignalEntry(workspace, spec) {
402
341
  const sys = await this.resolveSys(workspace, spec.app);
403
342
  const diagnostics = compactDiagnostics([
404
- !sys && { severity: "error", code: "primitive-target-missing", message: "Target app or library was not found." },
405
- !spec.module && {
406
- severity: "error",
407
- code: "primitive-input-missing",
408
- message: "Module is required.",
409
- input: "module"
410
- },
411
- !spec.entryName && {
412
- severity: "error",
413
- code: "primitive-input-missing",
414
- message: `${capitalize(spec.requiredInput)} name is required.`,
415
- input: spec.requiredInput
416
- }
343
+ !sys && PrimitiveScript.#targetMissing(),
344
+ !spec.module && PrimitiveScript.#inputMissing("module"),
345
+ !spec.entryName && PrimitiveScript.#inputMissing(spec.requiredInput, `${capitalize(spec.requiredInput)} name is required.`)
417
346
  ]);
418
- if (!sys || !spec.module || !spec.entryName || !spec.serviceMethod || !spec.signal) {
419
- return createPrimitiveWriteReport({
420
- command: spec.command,
421
- changedFiles: [],
422
- generatedFiles: [],
423
- validationCommands: [],
424
- diagnostics,
425
- nextActions: []
426
- });
427
- }
428
- const paths = moduleSourcePaths(spec.module);
429
- const servicePath = paths.service;
430
- const signalPath = paths.signal;
347
+ if (!sys || !spec.module || !spec.entryName || !spec.serviceMethod || !spec.signal)
348
+ return PrimitiveScript.#refuse(spec.command, diagnostics);
349
+ const { service: servicePath, signal: signalPath } = moduleSourcePaths(spec.module);
431
350
  const changedFiles = [];
432
- const generatedFiles = generatedFilesForSync(sys);
433
351
  const [hasServiceFile, hasSignalFile] = await Promise.all([sys.exists(servicePath), sys.exists(signalPath)]);
434
- if (!hasServiceFile) {
435
- diagnostics.push({
436
- severity: "error",
437
- code: "primitive-source-missing",
438
- message: `Service source file was not found: ${servicePath}.`
439
- });
440
- }
441
- if (!hasSignalFile) {
442
- diagnostics.push({
443
- severity: "error",
444
- code: "primitive-source-missing",
445
- message: `Signal source file was not found: ${signalPath}.`
446
- });
447
- }
448
- if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
449
- return createPrimitiveWriteReport({
450
- command: spec.command,
451
- changedFiles,
452
- generatedFiles,
453
- validationCommands: validationCommandsForTarget(sys.name),
454
- diagnostics,
455
- nextActions: nextActionsForTarget(sys.name)
456
- });
457
- }
352
+ if (!hasServiceFile)
353
+ diagnostics.push(PrimitiveScript.#sourceMissing("Service", servicePath));
354
+ if (!hasSignalFile)
355
+ diagnostics.push(PrimitiveScript.#sourceMissing("Signal", signalPath));
356
+ if (workflowStatus(diagnostics) === "failed")
357
+ return PrimitiveScript.#report(spec.command, sys, changedFiles, diagnostics);
458
358
  const serviceClassName = `${moduleComponentName(spec.module)}Service`;
459
359
  const serviceContent = await sys.readFile(servicePath);
460
360
  const signalContent = await sys.readFile(signalPath);
@@ -476,7 +376,8 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
476
376
  });
477
377
  }
478
378
  const nextServiceContent = serviceMethodExists ? serviceContent : insertClassMethod(serviceContent, serviceClassName, spec.serviceMethod.block);
479
- const nextSignalContent = insertSignalFactoryEntry(signalContent, spec.signal.className, spec.entryName, spec.signal.entryLine, spec.signal.param);
379
+ const insertedSignalContent = insertSignalFactoryEntry(signalContent, spec.signal.className, spec.entryName, spec.signal.entryLine, spec.signal.param);
380
+ const nextSignalContent = insertedSignalContent ? ensureNamedImport(insertedSignalContent, "akanjs/signal", "None") : insertedSignalContent;
480
381
  if (!nextServiceContent) {
481
382
  diagnostics.push({
482
383
  severity: "error",
@@ -515,20 +416,46 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
515
416
  message: `Edited ${signalPath} did not contain entry "${spec.entryName}" in ${spec.signal.className}.`
516
417
  });
517
418
  }
518
- if (!diagnostics.some((diagnostic) => diagnostic.severity === "error") && nextServiceContent && nextSignalContent) {
419
+ if (workflowStatus(diagnostics) === "passed" && nextServiceContent && nextSignalContent) {
519
420
  await sys.writeFile(servicePath, nextServiceContent);
520
421
  await sys.writeFile(signalPath, nextSignalContent);
521
422
  changedFiles.push(sourceFile(sys, servicePath, "modify", `Service ${spec.entryKind} was added.`), sourceFile(sys, signalPath, "modify", `Signal ${spec.entryKind} was added.`));
522
423
  }
424
+ return PrimitiveScript.#report(spec.command, sys, changedFiles, diagnostics);
425
+ }
426
+ static #refuse(command, diagnostics) {
427
+ return createPrimitiveWriteReport({
428
+ command,
429
+ changedFiles: [],
430
+ generatedFiles: [],
431
+ validationCommands: [],
432
+ diagnostics,
433
+ nextActions: []
434
+ });
435
+ }
436
+ static #report(command, sys, changedFiles, diagnostics) {
523
437
  return createPrimitiveWriteReport({
524
- command: spec.command,
438
+ command,
525
439
  changedFiles,
526
- generatedFiles,
440
+ generatedFiles: generatedFilesForSync(sys),
527
441
  validationCommands: validationCommandsForTarget(sys.name),
528
442
  diagnostics,
529
443
  nextActions: nextActionsForTarget(sys.name)
530
444
  });
531
445
  }
446
+ static #targetMissing() {
447
+ return { severity: "error", code: "primitive-target-missing", message: "Target app or library was not found." };
448
+ }
449
+ static #inputMissing(input, message = `${capitalize(input)} is required.`) {
450
+ return { severity: "error", code: "primitive-input-missing", message, input };
451
+ }
452
+ static #sourceMissing(kind, path) {
453
+ return {
454
+ severity: "error",
455
+ code: "primitive-source-missing",
456
+ message: `${kind} source file was not found: ${path}.`
457
+ };
458
+ }
532
459
  }
533
460
 
534
461
  export { PrimitiveScript };
@@ -4,27 +4,29 @@ import {
4
4
  readDevkitVersion,
5
5
  rootAllowedFiles,
6
6
  rootAllowedDirs,
7
+ rootEntryHintOf,
7
8
  isScannedRootEntry,
8
9
  AppExecutor,
9
10
  LibExecutor
10
- } from "./index-2tv3fdx4.js";
11
+ } from "./index-150s07n8.js";
11
12
  import {
12
- FileSys
13
- } from "./index-q0y2jq9j.js";
13
+ FileSys2
14
+ } from "./index-52w0fvh8.js";
14
15
  import {
15
16
  collectRecipeSources2,
16
17
  scanRecipes2,
17
18
  findInlineRecipeDuplicates2
18
- } from "./index-by5gpp8x.js";
19
+ } from "./index-hj6w4ka1.js";
19
20
  import {
21
+ workflowPathsForPlan,
20
22
  workflowRunArtifactPath,
21
23
  workflowSyncDir
22
- } from "./index-gyd220p2.js";
24
+ } from "./index-mb59b8x0.js";
23
25
 
24
26
  // pkgs/@akanjs/devkit/akanContext.ts
25
27
  import { readdir } from "fs/promises";
26
28
  import path from "path";
27
- import { capitalize } from "akanjs/common";
29
+ import { capitalize, isRecord } from "akanjs/common";
28
30
  var guidelineResourceUri = (name) => `akan://guidelines/${name}`;
29
31
  var staticResourceList = [
30
32
  { uri: "akan://docs/framework", name: "Akan framework guide", mimeType: "text/markdown" },
@@ -52,16 +54,13 @@ var akanMcpInstallConfigPaths = {
52
54
  var cursorWorkspaceFolder = "$" + "{workspaceFolder}";
53
55
  var claudeProjectDir = "$CLAUDE_PROJECT_DIR";
54
56
  var akanMcpCommand = (mode, { cd } = {}) => cd ? `cd "${cd}" && akan mcp --mode ${mode}` : `akan mcp --mode ${mode}`;
55
- var createAkanCursorMcpServer = (mode = "readonly") => ({
57
+ var bashMcpServer = (mode, cd) => ({
56
58
  type: "stdio",
57
59
  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 })]
60
+ args: ["-lc", akanMcpCommand(mode, { cd })]
64
61
  });
62
+ var createAkanCursorMcpServer = (mode = "readonly") => bashMcpServer(mode, cursorWorkspaceFolder);
63
+ var createAkanClaudeMcpServer = (mode = "readonly") => bashMcpServer(mode, claudeProjectDir);
65
64
  var createAkanMcpServer = (target, mode = "readonly") => target === "cursor" ? createAkanCursorMcpServer(mode) : createAkanClaudeMcpServer(mode);
66
65
  var akanCursorMcpServer = createAkanCursorMcpServer();
67
66
  var codexMcpServerTableHeader = "[mcp_servers.akan]";
@@ -164,41 +163,13 @@ var moduleShapeFiles = (module) => {
164
163
  ];
165
164
  };
166
165
  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");
166
+ var safeReadDir = async (dirPath) => (await readdir(dirPath, { withFileTypes: true }).catch(() => [])).sort((a, b) => a.name.localeCompare(b.name));
167
+ var safeReadText = (filePath) => FileSys2.readText(filePath).catch(() => null);
168
+ var safeReadJson = (filePath) => FileSys2.readJson(filePath).catch(() => null);
169
+ 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");
170
+ var isPathList = (value) => Array.isArray(value) && value.every((file) => isRecord(file) && typeof file.path === "string");
171
+ 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
172
  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
173
  var workflowPathsForArtifact = (artifact) => {
203
174
  if (isWorkflowPlan(artifact))
204
175
  return workflowPathsForPlan(artifact);
@@ -209,7 +180,7 @@ var workflowPathsForArtifact = (artifact) => {
209
180
  ...workflowPathsForPlan(artifact.plan)
210
181
  ];
211
182
  }
212
- if ("mode" in artifact && artifact.mode === "validate" && artifact.plan)
183
+ if ("mode" in artifact && artifact.mode === "validate" && isWorkflowPlan(artifact.plan))
213
184
  return workflowPathsForPlan(artifact.plan);
214
185
  return [];
215
186
  };
@@ -310,13 +281,13 @@ var getSysModules = async (workspace, sys, {
310
281
  const serviceName = entry.name.replace(/^_+/, "");
311
282
  if (moduleFilter && moduleFilter !== serviceName && moduleFilter !== entry.name)
312
283
  continue;
313
- if (!await FileSys.fileExists(path.join(libPath, entry.name, `${serviceName}.service.ts`)))
284
+ if (!await FileSys2.fileExists(path.join(libPath, entry.name, `${serviceName}.service.ts`)))
314
285
  continue;
315
286
  modules.push(await createModuleContext(workspace, sys, "service", entry.name, serviceName, includeAbstractContent));
316
287
  } else {
317
288
  if (moduleFilter && moduleFilter !== entry.name)
318
289
  continue;
319
- if (!await FileSys.fileExists(path.join(libPath, entry.name, `${entry.name}.constant.ts`)))
290
+ if (!await FileSys2.fileExists(path.join(libPath, entry.name, `${entry.name}.constant.ts`)))
320
291
  continue;
321
292
  modules.push(await createModuleContext(workspace, sys, "domain", entry.name, entry.name, includeAbstractContent));
322
293
  }
@@ -327,7 +298,7 @@ var getSysModules = async (workspace, sys, {
327
298
  continue;
328
299
  if (moduleFilter && moduleFilter !== entry.name)
329
300
  continue;
330
- if (!await FileSys.fileExists(path.join(scalarRoot, entry.name, `${entry.name}.constant.ts`)))
301
+ if (!await FileSys2.fileExists(path.join(scalarRoot, entry.name, `${entry.name}.constant.ts`)))
331
302
  continue;
332
303
  modules.push(await createModuleContext(workspace, sys, "scalar", entry.name, entry.name, includeAbstractContent));
333
304
  }
@@ -339,7 +310,7 @@ var getSysContext = async (workspace, type, name, options) => {
339
310
  type,
340
311
  name,
341
312
  path: `${type}s/${name}`,
342
- hasConfig: await FileSys.fileExists(path.join(sys.cwdPath, "akan.config.ts")),
313
+ hasConfig: await FileSys2.fileExists(path.join(sys.cwdPath, "akan.config.ts")),
343
314
  modules: await getSysModules(workspace, sys, {
344
315
  includeAbstractContent: options.includeAbstractContent,
345
316
  module: options.module
@@ -411,62 +382,47 @@ class AkanContextAnalyzer {
411
382
  repairAction("generated", "akan repair generated --app <app-or-lib>", "Refresh generated Akan files.", true),
412
383
  repairAction("format", "akan repair format --target <app-or-lib-or-pkg>", "Run the formatter/linter repair path.", true)
413
384
  ];
385
+ const report = (diagnostic, action) => {
386
+ diagnostics.push({ ...diagnostic, repairActions: [action] });
387
+ repairActions.push(action);
388
+ };
414
389
  for (const sys of [...context.apps, ...context.libs]) {
415
390
  const sysPath = path.join(workspace.workspaceRoot, sys.path);
416
391
  for (const entry of await safeReadDir(sysPath)) {
417
392
  if (!isScannedRootEntry(sys.type, entry.name))
418
393
  continue;
419
394
  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({
395
+ const rootEntryHint = rootEntryHintOf(sys.type, entry.name);
396
+ if (!allowed)
397
+ report({
423
398
  severity: "error",
424
399
  code: `${sys.type}-root-unknown-entry`,
425
400
  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
- }
401
+ message: `Unexpected ${entry.isDirectory() ? "folder" : "file"} in ${sys.type} root: ${sys.path}/${entry.name}${rootEntryHint ? ` (${rootEntryHint})` : ""}`
402
+ }, repairAction("module-shape", `akan repair module-shape --app ${sys.name}`, `Review ${sys.type} root shape and remove or move the unknown entry.`, false));
431
403
  }
432
404
  }
433
405
  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
- }
406
+ if (agentDrift)
407
+ report({ severity: "warning", code: agentDrift.code, path: "AGENTS.md", message: agentDrift.message }, repairAction("generated", "akan agent install agents-md", agentDrift.hint, true));
445
408
  for (const sys of [...context.apps, ...context.libs]) {
446
409
  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({
410
+ const moduleShapeCommand = `akan repair module-shape --app ${sys.name} --module ${module.name}`;
411
+ if (!module.abstract.exists)
412
+ report({
450
413
  severity: strict ? "error" : "warning",
451
414
  code: "module-abstract-missing",
452
415
  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
- }
416
+ message: `${capitalize(module.kind)} module ${sys.name}:${module.name} should include ${module.abstract.path}`
417
+ }, repairAction("module-shape", moduleShapeCommand, "Create the missing module abstract or inspect required source files.", false));
458
418
  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({
419
+ if (missingFiles.length)
420
+ report({
462
421
  severity: "error",
463
422
  code: "module-shape-invalid",
464
423
  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
- }
424
+ message: `${capitalize(module.kind)} module ${sys.name}:${module.name} is missing required files: ${missingFiles.join(", ")}`
425
+ }, repairAction("module-shape", moduleShapeCommand, "Review missing required module source files.", false));
470
426
  if (module.kind !== "service" && module.files.includes(`${module.name}.dictionary.ts`)) {
471
427
  const constantPath = path.join(workspace.workspaceRoot, module.path, `${module.name}.constant.ts`);
472
428
  const dictionaryPath = path.join(workspace.workspaceRoot, module.path, `${module.name}.dictionary.ts`);
@@ -478,15 +434,12 @@ class AkanContextAnalyzer {
478
434
  for (const fieldName of constantFieldNames(constantContent)) {
479
435
  if (new RegExp(`\\b${fieldName}\\s*:`).test(dictionaryContent))
480
436
  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({
437
+ report({
483
438
  severity: "warning",
484
439
  code: "dictionary-label-missing",
485
440
  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);
441
+ message: `Dictionary labels for ${sys.name}:${module.name}.${fieldName} were not found.`
442
+ }, repairAction("dictionary", `akan repair dictionary --app ${sys.name} --module ${module.name}`, "Add missing dictionary labels for source constant fields.", false));
490
443
  }
491
444
  }
492
445
  }
@@ -554,19 +507,16 @@ class AkanContextAnalyzer {
554
507
  const pushIndexDiagnostic = (indexPath, missing, stale, repairCommand) => {
555
508
  if (missing.length === 0 && stale.length === 0)
556
509
  return;
557
- const action = repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true);
558
510
  const parts = [
559
511
  missing.length > 0 ? `${missing.length} declared but unlisted (${missing.slice(0, 5).join(", ")})` : "",
560
512
  stale.length > 0 ? `${stale.length} listed but gone (${stale.slice(0, 5).join(", ")})` : ""
561
513
  ].filter(Boolean);
562
- diagnostics.push({
514
+ report({
563
515
  severity: "error",
564
516
  code: "recipe-index-stale",
565
517
  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);
518
+ message: `${indexPath} recipe index is out of date \u2014 ${parts.join("; ")}. Agents read this list as authoritative.`
519
+ }, repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true));
570
520
  };
571
521
  const frameworkDeclared = declaredByImport.get("akanjs/ui") ?? new Set;
572
522
  if (frameworkDeclared.size > 0) {