@akanjs/cli 3.0.0-beta.8 → 3.0.0

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-2vmp9qe0.js +9 -0
  3. package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
  4. package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
  5. package/CodeTui-5ed6bg2a.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-gn73rhe7.js} +8 -9
  10. package/akanCode.js +102 -0
  11. package/application.command-e968t0hw.js +246 -0
  12. package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-64taxseg.js} +121 -77
  13. package/buildBatch.proc.js +120 -32
  14. package/cloud.command-0jm301rr.js +95 -0
  15. package/cloud.script-nemnzjpv.js +20 -0
  16. package/code.command-18kcm7hq.js +154 -0
  17. package/commandManifest.json +1 -1
  18. package/consoleToStderr-h5bryj94.js +7 -0
  19. package/context.command-trd9bn18.js +48 -0
  20. package/context.runner-y5hwh673.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-bdmdn2de.js +42 -0
  25. package/guidelines/agentRule/agentRule.instruction.md +154 -26
  26. package/guidelines/conventions/conventions.instruction.md +134 -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-0wpybxtr.js +2729 -0
  36. package/{index-kcxmv48c.js → index-2ahj896a.js} +45 -79
  37. package/index-2wc41k5w.js +49 -0
  38. package/index-3hx1z96c.js +87 -0
  39. package/{index-2tv3fdx4.js → index-3w94e7n3.js} +1228 -1458
  40. package/{index-hwkygn9s.js → index-48k96p55.js} +325 -36
  41. package/index-4npz05nm.js +187 -0
  42. package/{index-q0y2jq9j.js → index-52w0fvh8.js} +21 -4
  43. package/index-6he6gvfg.js +4300 -0
  44. package/index-7md2g9vw.js +6 -0
  45. package/{index-04bk599g.js → index-93j60em0.js} +10 -17
  46. package/index-94s080qm.js +266 -0
  47. package/index-9dp031by.js +12 -0
  48. package/{index-ktb5njgy.js → index-9z771ptz.js} +49 -99
  49. package/{index-y6n8nmny.js → index-abxpehf8.js} +75 -203
  50. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  51. package/{index-9077wzd2.js → index-by9pxkr0.js} +43 -26
  52. package/index-c6eggbee.js +123 -0
  53. package/index-d2242ksy.js +99 -0
  54. package/index-drehwpdt.js +1119 -0
  55. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  56. package/{index-ffvk10zz.js → index-f3c78nd6.js} +107 -241
  57. package/index-gbggbqcp.js +1058 -0
  58. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  59. package/index-hsmtysz4.js +53 -0
  60. package/{index-j9yhg404.js → index-jmrn54tt.js} +4 -7
  61. package/{index-a64esmtb.js → index-kcdj1z5v.js} +523 -1022
  62. package/{index-d43r08tf.js → index-kqabytj7.js} +77 -150
  63. package/{index-vyvre9en.js → index-mbxbhay5.js} +6 -2
  64. package/{index-vxtad5bd.js → index-mgxpx3f2.js} +5 -8
  65. package/index-p6pbz9n5.js +25 -0
  66. package/{index-sj5vxr8f.js → index-p993efkq.js} +981 -897
  67. package/{index-2xp0kfkt.js → index-pmhqttv3.js} +37 -25
  68. package/index-tqm7jjcn.js +700 -0
  69. package/{index-0g7r8xz3.js → index-vpj42xwt.js} +114 -232
  70. package/index-wa5jbxj1.js +760 -0
  71. package/{index-k2j1hc4r.js → index-wprnsjms.js} +12 -12
  72. package/{index-gyd220p2.js → index-y3mphr1m.js} +554 -577
  73. package/index-yg7jhz8x.js +69 -0
  74. package/{index-h7yw2z9n.js → index-zzvvc845.js} +8 -14
  75. package/index.js +23 -22
  76. package/{library.command-qzzbj6d8.js → library.command-9h749a1x.js} +4 -5
  77. package/{localRegistry.command-vyrgg4xw.js → localRegistry.command-2bqqhxyz.js} +23 -43
  78. package/{module.command-rq5hq3ax.js → module.command-nv8nzgft.js} +8 -12
  79. package/{package.command-d9hd6v9n.js → package.command-mq4bggp6.js} +6 -7
  80. package/package.json +15 -7
  81. package/{page.command-126d56te.js → page.command-j639n707.js} +4 -5
  82. package/{primitive.command-taxd1538.js → primitive.command-kz6849th.js} +9 -23
  83. package/prompter-76k56b37.js +8 -0
  84. package/{quality.command-6gsna0a3.js → quality.command-4hyabwkb.js} +205 -377
  85. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  86. package/{repair.command-tq2dgy72.js → repair.command-a9awpbqr.js} +11 -35
  87. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  88. package/{scalar.command-3bcmrrkv.js → scalar.command-ma4fpm9m.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-3k2pmrs4.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-xwr46b66.js +129 -0
  155. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  156. package/typecheck.proc.js +1 -1
  157. package/workflow.command-t7wqe4h7.js +79 -0
  158. package/{workspace.command-06wvstgr.js → workspace.command-4derhzrh.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,60 +1,45 @@
1
1
  // @bun
2
2
  import {
3
3
  AppExecutor
4
- } from "./index-2tv3fdx4.js";
4
+ } from "./index-3w94e7n3.js";
5
5
  import {
6
6
  jsonText,
7
7
  createWorkflowBaselineSummary,
8
8
  buildAkanModuleContextIndex,
9
- createWorkflowStepRegistry,
10
9
  toolingRolloutGate
11
- } from "./index-gyd220p2.js";
10
+ } from "./index-y3mphr1m.js";
12
11
  import {
13
12
  buildResourceList,
14
13
  codexMcpConfigPath,
15
- akanMcpInstallTargets,
16
14
  akanMcpInstallConfigPaths,
17
15
  createAkanMcpServer,
18
16
  createAkanCodexMcpServerBlock,
19
17
  upsertCodexMcpServerBlock,
20
18
  renderDoctorText,
21
19
  AkanContextAnalyzer
22
- } from "./index-ktb5njgy.js";
20
+ } from "./index-9z771ptz.js";
23
21
  import {
24
- CommandContainer,
25
- runner,
26
- script
27
- } from "./index-0g7r8xz3.js";
22
+ runner
23
+ } from "./index-vpj42xwt.js";
28
24
  import {
29
- isPlaceholderAppId2
30
- } from "./index-wt7qrtd4.js";
25
+ getMobileTargets,
26
+ appIdsOf,
27
+ NativeApp,
28
+ isPlaceholderAppId
29
+ } from "./index-gbggbqcp.js";
31
30
  import {
32
- Prompter
33
- } from "./index-h7yw2z9n.js";
31
+ Prompter2
32
+ } from "./index-zzvvc845.js";
34
33
  import {
35
34
  RepairRunner
36
- } from "./index-04bk599g.js";
35
+ } from "./index-93j60em0.js";
37
36
  import {
38
37
  WorkflowRunner
39
- } from "./index-ffvk10zz.js";
40
- import {
41
- ModuleScript
42
- } from "./index-5ystnsd5.js";
43
- import {
44
- PrimitiveScript
45
- } from "./index-d43r08tf.js";
46
- import {
47
- ScalarScript
48
- } from "./index-a17x49vg.js";
49
- import {
50
- getMobileTargets
51
- } from "./index-47pj3aee.js";
52
-
53
- // pkgs/@akanjs/cli/context/context.script.ts
54
- import { Logger } from "akanjs/common";
38
+ } from "./index-f3c78nd6.js";
55
39
 
56
40
  // pkgs/@akanjs/devkit/akanMcpContract.ts
57
41
  import path from "path";
42
+ import { isRecord } from "akanjs/common";
58
43
  var emptySchema = { type: "object", properties: {} };
59
44
  var stringProperty = { type: "string" };
60
45
  var booleanProperty = { type: "boolean" };
@@ -138,18 +123,11 @@ var inspectAkanContextInputSchema = {
138
123
  },
139
124
  required: ["question", "draft", "review", "request"]
140
125
  };
141
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
142
126
  var slugPart = (value) => typeof value === "string" ? value.trim().replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase() : "";
143
127
  var optionalString = (args, key) => {
144
128
  const value = args[key];
145
129
  return typeof value === "string" && value ? value : undefined;
146
130
  };
147
- var nestedStringArg = (args, key) => {
148
- const value = args[key];
149
- if (typeof value !== "string" || !value)
150
- throw new Error(`MCP tool argument "${key}" is required.`);
151
- return value;
152
- };
153
131
  var isInspectAkanContextRequestType = (value) => typeof value === "string" && inspectAkanContextRequestTypes.includes(value);
154
132
  var parseJsonOutput = (output) => JSON.parse(output);
155
133
  var workspacePath = (workspace, filePath) => path.isAbsolute(filePath) ? filePath : path.join(workspace.workspaceRoot, filePath);
@@ -204,50 +182,31 @@ var inspectAkanContextPropsArg = (args) => {
204
182
  if (!isInspectAkanContextRequestType(args.request.type)) {
205
183
  throw new Error('MCP tool argument "request.type" must be a supported inspect_akan_context request type.');
206
184
  }
207
- const draft = { reason: nestedStringArg(args.draft, "reason"), type: args.draft.type };
185
+ const base = { question, draft: { reason: stringArg(args.draft, "reason"), type: args.draft.type }, review };
208
186
  const request = args.request;
209
187
  if (request.type === "workspaceOverview")
210
- return { question, draft, review, request: { type: request.type } };
188
+ return { ...base, request: { type: request.type } };
211
189
  if (request.type === "moduleContext")
212
190
  return {
213
- question,
214
- draft,
215
- review,
216
- request: {
217
- type: request.type,
218
- app: nestedStringArg(request, "app"),
219
- module: nestedStringArg(request, "module")
220
- }
191
+ ...base,
192
+ request: { type: request.type, app: stringArg(request, "app"), module: stringArg(request, "module") }
221
193
  };
222
194
  if (request.type === "fieldInsertionContext")
223
195
  return {
224
- question,
225
- draft,
226
- review,
196
+ ...base,
227
197
  request: {
228
198
  type: request.type,
229
- app: nestedStringArg(request, "app"),
230
- module: nestedStringArg(request, "module"),
231
- field: nestedStringArg(request, "field"),
232
- fieldType: nestedStringArg(request, "fieldType")
199
+ app: stringArg(request, "app"),
200
+ module: stringArg(request, "module"),
201
+ field: stringArg(request, "field"),
202
+ fieldType: stringArg(request, "fieldType")
233
203
  }
234
204
  };
235
205
  if (request.type === "workflowDiagnostics")
236
- return {
237
- question,
238
- draft,
239
- review,
240
- request: { type: request.type, runIdOrPlan: nestedStringArg(request, "runIdOrPlan") }
241
- };
206
+ return { ...base, request: { type: request.type, runIdOrPlan: stringArg(request, "runIdOrPlan") } };
242
207
  return {
243
- question,
244
- draft,
245
- review,
246
- request: {
247
- type: "escape",
248
- reason: nestedStringArg(request, "reason"),
249
- nextStep: optionalString(request, "nextStep")
250
- }
208
+ ...base,
209
+ request: { type: "escape", reason: stringArg(request, "reason"), nextStep: optionalString(request, "nextStep") }
251
210
  };
252
211
  };
253
212
  var inspectDiagnostic = (severity, code, message) => ({ severity, code, message });
@@ -471,22 +430,11 @@ var inspectAkanContext = async (workspace, args) => {
471
430
  strict: true,
472
431
  runIdOrPlan: workspacePath(workspace, props.request.runIdOrPlan)
473
432
  });
474
- const baselineSummary = createWorkflowBaselineSummary((doctor.baselineDiagnostics ?? []).map((diagnostic) => ({
475
- severity: diagnostic.severity,
476
- code: diagnostic.code,
477
- message: diagnostic.message,
478
- scope: diagnostic.scope,
479
- context: diagnostic.context
480
- })), { detailsIncluded: false });
481
- diagnostics.push(...(doctor.workflowDiagnostics ?? doctor.diagnostics).map((diagnostic) => ({
482
- severity: diagnostic.severity,
483
- code: diagnostic.code,
484
- message: diagnostic.message,
485
- scope: diagnostic.scope,
486
- context: {
487
- ...diagnostic.context,
488
- ...diagnostic.path ? { paths: [diagnostic.path] } : {}
489
- }
433
+ const toWorkflowDiagnostic = ({ severity, code, message, scope }, context) => ({ severity, code, message, scope, context });
434
+ const baselineSummary = createWorkflowBaselineSummary((doctor.baselineDiagnostics ?? []).map((diagnostic) => toWorkflowDiagnostic(diagnostic, diagnostic.context)), { detailsIncluded: false });
435
+ diagnostics.push(...(doctor.workflowDiagnostics ?? doctor.diagnostics).map((diagnostic) => toWorkflowDiagnostic(diagnostic, {
436
+ ...diagnostic.context,
437
+ ...diagnostic.path ? { paths: [diagnostic.path] } : {}
490
438
  })));
491
439
  return baseResult("workflowDiagnostics", [
492
440
  {
@@ -504,9 +452,10 @@ var inspectAkanContext = async (workspace, args) => {
504
452
  workflowDiagnostics: doctor.workflowDiagnostics?.length ?? 0
505
453
  });
506
454
  }
455
+ const moduleRequest = props.request.type === "moduleContext" || props.request.type === "fieldInsertionContext" ? props.request : null;
507
456
  const context = await AkanContextAnalyzer.analyze(workspace, {
508
- app: props.request.type === "moduleContext" || props.request.type === "fieldInsertionContext" ? props.request.app : null,
509
- module: props.request.type === "moduleContext" || props.request.type === "fieldInsertionContext" ? props.request.module : null,
457
+ app: moduleRequest?.app ?? null,
458
+ module: moduleRequest?.module ?? null,
510
459
  includeAbstractContent: false
511
460
  });
512
461
  if (props.request.type === "workspaceOverview") {
@@ -594,41 +543,22 @@ var inspectAkanContext = async (workspace, args) => {
594
543
  });
595
544
  };
596
545
 
597
- // pkgs/@akanjs/cli/context/context.workflowRegistry.ts
598
- var createCliWorkflowStepRegistry = (workspace) => createWorkflowStepRegistry({
599
- workspace,
600
- createModule: (sys, module) => CommandContainer.get(ModuleScript).createModuleTemplate(sys, module),
601
- createScalar: (sys, scalar) => CommandContainer.get(ScalarScript).createScalar(sys, scalar),
602
- createUi: (input) => CommandContainer.get(PrimitiveScript).createUi(workspace, input),
603
- addField: (input) => CommandContainer.get(PrimitiveScript).addField(workspace, input),
604
- addEnumField: (input) => CommandContainer.get(PrimitiveScript).addEnumField(workspace, input),
605
- addMutation: (input) => CommandContainer.get(PrimitiveScript).addMutation(workspace, input),
606
- addSlice: (input) => CommandContainer.get(PrimitiveScript).addSlice(workspace, input)
607
- });
608
-
609
546
  // pkgs/@akanjs/cli/context/context.runner.ts
610
547
  var toolErrorText = (error) => {
611
548
  const message = error instanceof Error ? error.message : String(error);
612
549
  return message.replace(/\/(?:[^\s"'/]+\/)*(?=(?:pkgs|apps|libs|infra)\/)/g, "<workspace>/");
613
550
  };
614
- var workflowDiagnosticFromContext = (diagnostic) => ({
615
- severity: diagnostic.severity,
616
- code: diagnostic.code,
617
- message: diagnostic.message,
618
- scope: diagnostic.scope,
619
- context: diagnostic.context
620
- });
621
551
  var compactDoctorWorkspaceResult = (result, includeBaselineDetails) => {
622
552
  const baselineDiagnostics = result.baselineDiagnostics ?? [];
623
- if (baselineDiagnostics.length === 0) {
624
- return {
625
- ...result,
626
- baselineSummary: createWorkflowBaselineSummary([], { detailsIncluded: includeBaselineDetails })
627
- };
628
- }
629
- const baselineSummary = createWorkflowBaselineSummary(baselineDiagnostics.map(workflowDiagnosticFromContext), {
630
- detailsIncluded: includeBaselineDetails
631
- });
553
+ const baselineSummary = createWorkflowBaselineSummary(baselineDiagnostics.map(({ severity, code, message, scope, context }) => ({
554
+ severity,
555
+ code,
556
+ message,
557
+ scope,
558
+ context
559
+ })), { detailsIncluded: includeBaselineDetails });
560
+ if (baselineDiagnostics.length === 0)
561
+ return { ...result, baselineSummary };
632
562
  return {
633
563
  ...result,
634
564
  baselineSummary,
@@ -637,17 +567,13 @@ var compactDoctorWorkspaceResult = (result, includeBaselineDetails) => {
637
567
  };
638
568
  };
639
569
 
640
- class ContextRunner extends runner("context") {
570
+ class ContextRunner2 extends runner("context") {
641
571
  async getContext(workspace, {
642
572
  format = "markdown",
643
573
  app = null,
644
574
  module = null
645
575
  } = {}) {
646
- const context = await AkanContextAnalyzer.analyze(workspace, {
647
- app,
648
- module,
649
- includeAbstractContent: !!module
650
- });
576
+ const context = await AkanContextAnalyzer.analyze(workspace, { app, module, includeAbstractContent: !!module });
651
577
  return format === "json" ? jsonText(context) : AkanContextAnalyzer.renderMarkdown(context, { module });
652
578
  }
653
579
  async doctor(workspace, {
@@ -663,19 +589,32 @@ class ContextRunner extends runner("context") {
663
589
  async#doctorIos(workspace, format) {
664
590
  const appNames = await workspace.getApps();
665
591
  const diagnostics = [];
592
+ let toolchainChecked = false;
666
593
  for (const appName of appNames) {
667
594
  const app = AppExecutor.from(workspace, appName);
668
595
  const config = await app.getConfig();
669
- if (!config.hasMobileConfig)
596
+ if (!config.hasNativeConfig)
670
597
  continue;
598
+ if (!toolchainChecked) {
599
+ toolchainChecked = true;
600
+ const report = await NativeApp.doctor(app.cwdPath, ["ios"]);
601
+ for (const check of report.checks.filter((check) => !check.ok || check.warn))
602
+ diagnostics.push({
603
+ severity: check.ok ? "warning" : "error",
604
+ code: "native-toolchain",
605
+ path: `${check.group} \u203A ${check.name}`,
606
+ message: [check.detail, check.hint].filter(Boolean).join(" ")
607
+ });
608
+ }
671
609
  for (const { name, config: target } of await getMobileTargets(app)) {
672
- if (!isPlaceholderAppId2(target.appId))
610
+ const placeholder = appIdsOf(target.appId).find(isPlaceholderAppId);
611
+ if (!placeholder)
673
612
  continue;
674
613
  diagnostics.push({
675
614
  severity: "warning",
676
615
  code: "mobile-appid-placeholder",
677
616
  path: `apps/${appName}/akan.config.ts`,
678
- message: `Mobile target '${name}' uses placeholder bundle id '${target.appId}'. Apple's developer portal almost always already claims it, so signing to a physical device fails with "cannot be registered to your development team". Set a unique mobile.appId (reverse-DNS of your org).`
617
+ message: `Native target '${name}' uses placeholder bundle id '${placeholder}'. Apple's developer portal almost always already claims it, so signing to a physical device fails with "cannot be registered to your development team". Set a unique native.appId (reverse-DNS of your org).`
679
618
  });
680
619
  }
681
620
  }
@@ -684,7 +623,7 @@ class ContextRunner extends runner("context") {
684
623
  return jsonText({ schemaVersion: 1, kind: "ios", status, diagnostics });
685
624
  const lines = [`Akan iOS diagnostics for ${workspace.repoName}`];
686
625
  if (diagnostics.length === 0)
687
- lines.push(" No mobile configuration issues found.");
626
+ lines.push(" No native configuration issues found.");
688
627
  else
689
628
  for (const diagnostic of diagnostics) {
690
629
  lines.push(` [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`);
@@ -694,7 +633,7 @@ class ContextRunner extends runner("context") {
694
633
  `);
695
634
  }
696
635
  async getGuidelineResource(name) {
697
- return await Prompter.getInstruction(name);
636
+ return await Prompter2.getInstruction(name);
698
637
  }
699
638
  async installMcp(workspace, target, { force = false, mode = "readonly" } = {}) {
700
639
  if (target === "codex")
@@ -710,13 +649,7 @@ class ContextRunner extends runner("context") {
710
649
  if (currentAkanServer && !force && JSON.stringify(currentAkanServer) !== JSON.stringify(nextAkanServer)) {
711
650
  throw new Error(`${configPath} already has an "akan" MCP server. Re-run with --force to overwrite it.`);
712
651
  }
713
- const nextConfig = {
714
- ...existing,
715
- mcpServers: {
716
- ...mcpServers,
717
- akan: nextAkanServer
718
- }
719
- };
652
+ const nextConfig = { ...existing, mcpServers: { ...mcpServers, akan: nextAkanServer } };
720
653
  await workspace.writeFile(configPath, `${JSON.stringify(nextConfig, null, 2)}
721
654
  `);
722
655
  return configPath;
@@ -773,7 +706,7 @@ class ContextRunner extends runner("context") {
773
706
  return modules;
774
707
  }
775
708
  if (name === "get_guideline")
776
- return await Prompter.getInstruction(stringArg(args, "name"));
709
+ return await Prompter2.getInstruction(stringArg(args, "name"));
777
710
  if (name === "doctor_workspace")
778
711
  return compactDoctorWorkspaceResult(await AkanContextAnalyzer.doctor(workspace, {
779
712
  strict: !!args.strict,
@@ -809,7 +742,7 @@ class ContextRunner extends runner("context") {
809
742
  format: "json",
810
743
  dryRun: !!args.dryRun,
811
744
  workspace,
812
- registry: createCliWorkflowStepRegistry(workspace)
745
+ registry: WorkflowRunner.stepRegistry(workspace)
813
746
  }));
814
747
  const validationTarget = typeof report.validationTarget === "string" ? report.validationTarget : typeof report.applyReportPath === "string" ? report.applyReportPath : stringArg(args, "planPath");
815
748
  return {
@@ -863,14 +796,14 @@ ${payload}`);
863
796
  const respondError = (id, code, message, framing) => {
864
797
  writeMessage({ jsonrpc: "2.0", id: id ?? null, error: { code, message } }, framing);
865
798
  };
866
- const guidelineNames = await Prompter.listGuidelines();
799
+ const guidelineNames = await Prompter2.listGuidelines();
867
800
  const resources = buildResourceList(guidelineNames);
868
801
  const readResource = async (uri) => {
869
802
  if (uri === "akan://docs/framework")
870
- return { uri, mimeType: "text/markdown", text: await Prompter.getInstruction("framework") };
803
+ return { uri, mimeType: "text/markdown", text: await Prompter2.getInstruction("framework") };
871
804
  const guideline = /^akan:\/\/guidelines\/(.+)$/.exec(uri)?.[1];
872
805
  if (guideline)
873
- return { uri, mimeType: "text/markdown", text: await Prompter.getInstruction(guideline) };
806
+ return { uri, mimeType: "text/markdown", text: await Prompter2.getInstruction(guideline) };
874
807
  const context = await AkanContextAnalyzer.analyze(workspace);
875
808
  if (uri === "akan://workspace/summary")
876
809
  return { uri, mimeType: "application/json", text: jsonText(context, { trailingNewline: false }) };
@@ -902,22 +835,14 @@ ${payload}`);
902
835
  serverInfo: { name: "akan", version: process.env.AKAN_VERSION ?? "0.0.0" }
903
836
  }, framing);
904
837
  } else if (request.method === "tools/list") {
905
- respond(request.id, {
906
- tools: this.listMcpTools(mode, { guidelineNames })
907
- }, framing);
838
+ respond(request.id, { tools: this.listMcpTools(mode, { guidelineNames }) }, framing);
908
839
  } else if (request.method === "tools/call") {
909
840
  const name = params.name;
910
841
  const args = params.arguments ?? {};
911
842
  try {
912
843
  const result = await this.callMcpTool(workspace, name, args, { mode });
913
- respond(request.id, {
914
- content: [
915
- {
916
- type: "text",
917
- text: typeof result === "string" ? result : jsonText(result, { trailingNewline: false })
918
- }
919
- ]
920
- }, framing);
844
+ const text = typeof result === "string" ? result : jsonText(result, { trailingNewline: false });
845
+ respond(request.id, { content: [{ type: "text", text }] }, framing);
921
846
  } catch (error) {
922
847
  respond(request.id, { content: [{ type: "text", text: toolErrorText(error) }], isError: true }, framing);
923
848
  }
@@ -1026,7 +951,7 @@ ${payload}`);
1026
951
  test: "`akan test <app-or-lib-or-pkg>` prepares the target and runs its tests.",
1027
952
  build: "`akan build <app-name>` creates a production build after preparing generated files.",
1028
953
  doctor: "`akan doctor --strict --format json` reports agent-readable workspace convention diagnostics and validation hints.",
1029
- "guideline show": "`akan guideline show <name>` prints an Akan codegen guideline instruction.",
954
+ "guideline show": "`akan guideline show <name>` prints an Akan guideline instruction.",
1030
955
  workflow: "`akan workflow list|explain|plan|apply|validate|report` lists, plans, applies, validates, and reports agent-readable Akan workflows.",
1031
956
  "workflow list": "`akan workflow list` lists parseable read-only workflow specs.",
1032
957
  "workflow explain": "`akan workflow explain <workflow>` explains inputs, optional surfaces, steps, and validation.",
@@ -1049,57 +974,4 @@ ${payload}`);
1049
974
  }
1050
975
  }
1051
976
 
1052
- // pkgs/@akanjs/cli/context/context.script.ts
1053
- var resolveMcpInstallTargets = (target) => {
1054
- if (!target || target === "all")
1055
- return [...akanMcpInstallTargets];
1056
- if (akanMcpInstallTargets.includes(target))
1057
- return [target];
1058
- throw new Error(`Unknown MCP install target: ${target}. Use cursor, claude, codex, or all.`);
1059
- };
1060
- var mcpTargetLabels = {
1061
- cursor: "Cursor",
1062
- claude: "Claude Code",
1063
- codex: "Codex"
1064
- };
1065
-
1066
- class ContextScript extends script("context", [ContextRunner]) {
1067
- async context(workspace, options = {}) {
1068
- Logger.rawLog(await this.contextRunner.getContext(workspace, options));
1069
- }
1070
- async doctor(workspace, options = {}) {
1071
- Logger.rawLog(await this.contextRunner.doctor(workspace, options));
1072
- }
1073
- async mcpInstall(workspace, target, { force = false, mode = "apply" } = {}) {
1074
- const targets = resolveMcpInstallTargets(target);
1075
- const written = [];
1076
- for (const t of targets) {
1077
- const configPath = await this.contextRunner.installMcp(workspace, t, { force, mode });
1078
- written.push(`${mcpTargetLabels[t]}: ${configPath}`);
1079
- }
1080
- Logger.rawLog(`Akan MCP server installed (${mode} mode):
1081
- ${written.map((line) => `- ${line}`).join(`
1082
- `)}`);
1083
- }
1084
- async mcp(workspace, { mode = "apply" } = {}) {
1085
- await this.contextRunner.runMcp(workspace, { mode });
1086
- }
1087
- async mcpCall(workspace, tool, {
1088
- mode = "readonly",
1089
- args = null,
1090
- format = "json"
1091
- } = {}) {
1092
- let parsedArgs = {};
1093
- if (args) {
1094
- const parsed = JSON.parse(args);
1095
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1096
- throw new Error("MCP call args must be a JSON object.");
1097
- }
1098
- parsedArgs = parsed;
1099
- }
1100
- const result = await this.contextRunner.callMcpTool(workspace, tool, parsedArgs, { mode });
1101
- Logger.rawLog(format === "json" ? jsonText(result) : String(result));
1102
- }
1103
- }
1104
-
1105
- export { ContextScript };
977
+ export { ContextRunner2 };
@@ -14,25 +14,26 @@ class LibSource {
14
14
  const relative = file.slice(this.#prefix.length);
15
15
  return !LibSource.unhashedDirs.includes(relative.split("/")[0] ?? "");
16
16
  }
17
- async#hashableContent(file) {
18
- const content = await this.#lib.workspace.readFile(file);
19
- if (file !== `${this.#prefix}package.json`)
20
- return content;
21
- const manifest = JSON.parse(content);
17
+ static unstamped(manifestContent) {
18
+ const manifest = JSON.parse(manifestContent);
22
19
  delete manifest[LibSource.manifestKey];
23
20
  return JSON.stringify(manifest);
24
21
  }
25
- async computeHash() {
26
- const files = (await this.#lib.workspace.listGitFiles([`libs/${this.#lib.name}`], { untracked: true })).filter((file) => this.#isHashed(file));
22
+ static async hashFiles(files, manifestFile, read) {
27
23
  const hasher = new Bun.CryptoHasher("sha256");
28
24
  for (const file of files) {
25
+ const content = await read(file);
29
26
  hasher.update(file);
30
27
  hasher.update("\x00");
31
- hasher.update(await this.#hashableContent(file));
28
+ hasher.update(file === manifestFile ? LibSource.unstamped(content) : content);
32
29
  hasher.update("\x00");
33
30
  }
34
31
  return hasher.digest("hex").slice(0, 32);
35
32
  }
33
+ async computeHash() {
34
+ const files = (await this.#lib.workspace.listGitFiles([`libs/${this.#lib.name}`], { untracked: true })).filter((file) => this.#isHashed(file));
35
+ return await LibSource.hashFiles(files, `${this.#prefix}package.json`, (file) => this.#lib.workspace.readFile(file));
36
+ }
36
37
  async read() {
37
38
  const manifest = await this.#lib.getPackageJson();
38
39
  const akan = manifest[LibSource.manifestKey];
@@ -2,16 +2,16 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-0g7r8xz3.js";
5
+ } from "./index-vpj42xwt.js";
6
6
  import {
7
- FileSys
8
- } from "./index-q0y2jq9j.js";
7
+ FileSys2
8
+ } from "./index-52w0fvh8.js";
9
9
  import {
10
10
  PkgExecutor
11
- } from "./index-2tv3fdx4.js";
11
+ } from "./index-3w94e7n3.js";
12
12
  import {
13
13
  TypeScriptDependencyScanner2
14
- } from "./index-kcxmv48c.js";
14
+ } from "./index-2ahj896a.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/package/package.runner.ts
17
17
  import path2 from "path";
@@ -112,7 +112,7 @@ class PackageRunner extends runner("package") {
112
112
  "create-akan-workspace"
113
113
  ];
114
114
  async version(workspace, { log = true } = {}) {
115
- const pkgJson = process.env.USE_AKANJS_PKGS === "true" ? await FileSys.readJson(`${workspace?.workspaceRoot ?? process.cwd()}/pkgs/akanjs/package.json`) : await this.#getInstalledPackageJson();
115
+ const pkgJson = process.env.USE_AKANJS_PKGS === "true" ? await FileSys2.readJson(`${workspace?.workspaceRoot ?? process.cwd()}/pkgs/akanjs/package.json`) : await this.#getInstalledPackageJson();
116
116
  const version = pkgJson.name === "akanjs" ? pkgJson.version : pkgJson.dependencies?.akanjs ?? pkgJson.version;
117
117
  if (log)
118
118
  Logger.rawLog(`akanjs@${version}`);
@@ -129,14 +129,19 @@ class PackageRunner extends runner("package") {
129
129
  for (const packageJsonPath of packageJsonCandidates) {
130
130
  if (!await Bun.file(packageJsonPath).exists())
131
131
  continue;
132
- const packageJson = await FileSys.readJson(packageJsonPath);
132
+ const packageJson = await FileSys2.readJson(packageJsonPath);
133
133
  if (packageJson.name === "akanjs" || packageJson.name === "@akanjs/cli")
134
134
  return packageJson;
135
135
  }
136
136
  throw new Error(`[package] failed to locate akanjs package.json from ${path2.dirname(Bun.main)}`);
137
137
  }
138
138
  async createPackage(workspace, pkgName) {
139
- await workspace.applyTemplate({ basePath: `pkgs/${pkgName}`, template: "pkgRoot", dict: { pkgName } });
139
+ const workspaceRootPath = ["pkgs", ...pkgName.split("/")].map(() => "..").join("/");
140
+ await workspace.applyTemplate({
141
+ basePath: `pkgs/${pkgName}`,
142
+ template: "pkgRoot",
143
+ dict: { pkgName, workspaceRootPath }
144
+ });
140
145
  await workspace.setPkgTsPaths(pkgName);
141
146
  }
142
147
  async removePackage(pkg) {
@@ -144,8 +149,7 @@ class PackageRunner extends runner("package") {
144
149
  await pkg.workspace.unsetPkgTsPaths(pkg.name);
145
150
  }
146
151
  async scanSync(pkg) {
147
- const scanResult = await pkg.scan();
148
- return scanResult;
152
+ return await pkg.scan();
149
153
  }
150
154
  async buildPackage(pkg) {
151
155
  await $`rm -rf ${pkg.dist.cwdPath}`;
@@ -153,7 +157,14 @@ class PackageRunner extends runner("package") {
153
157
  const scanner = await TypeScriptDependencyScanner2.from(pkg);
154
158
  const { npmDeps, npmDevDeps, missingDeps } = await scanner.getPackageBuildDependencies(pkg.name);
155
159
  const packageRuntimeDependencies = {
156
- "@akanjs/devkit": ["tailwind-scrollbar"]
160
+ "@akanjs/devkit": [
161
+ "tailwind-scrollbar",
162
+ "@earendil-works/chord",
163
+ "@earendil-works/pi-agent-core",
164
+ "@earendil-works/pi-ai",
165
+ "@earendil-works/pi-telemetry",
166
+ "@earendil-works/pi-tui"
167
+ ]
157
168
  };
158
169
  const packageRuntimeDevDependencies = { akanjs: ["@biomejs/biome", "@types/bun"] };
159
170
  if (pkg.name === "@akanjs/cli") {
@@ -164,17 +175,23 @@ class PackageRunner extends runner("package") {
164
175
  ].filter((dep) => dep !== "akanjs" && dep !== "@akanjs/devkit");
165
176
  }
166
177
  const packageBundledRuntimeDependencies = {
167
- "@akanjs/cli": ["@akanjs/devkit"],
168
- akanjs: ["use-agentic"]
178
+ "@akanjs/cli": ["@akanjs/devkit", "@akanjs/native"],
179
+ "@akanjs/devkit": ["@akanjs/native"],
180
+ akanjs: ["use-agentic", "@akanjs/native"]
169
181
  };
170
182
  const bundledRuntimeDeps = new Set(packageBundledRuntimeDependencies[pkg.name] ?? []);
171
183
  const forcedRuntimeDeps = packageRuntimeDependencies[pkg.name] ?? [];
172
184
  const forcedRuntimeDevDeps = packageRuntimeDevDependencies[pkg.name] ?? [];
173
185
  const [rootPackageJson, pkgJson] = await Promise.all([pkg.workspace.getPackageJson(), pkg.getPackageJson()]);
174
186
  const optionalPeerDeps = new Set(Object.entries(pkgJson.peerDependenciesMeta ?? {}).filter(([, meta]) => meta.optional).map(([dep]) => dep));
175
- const packageRuntimeDeps = [...new Set([...npmDeps, ...forcedRuntimeDeps])].filter((dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep));
176
- const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])].filter((dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep));
177
- const rootDeps = { ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies };
187
+ const isShipped = (dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep);
188
+ const packageRuntimeDeps = [...new Set([...npmDeps, ...forcedRuntimeDeps])].filter(isShipped);
189
+ const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])].filter(isShipped);
190
+ const rootDeps = {
191
+ ...rootPackageJson.overrides,
192
+ ...rootPackageJson.dependencies,
193
+ ...rootPackageJson.devDependencies
194
+ };
178
195
  const missingForcedDeps = forcedRuntimeDeps.filter((dep) => !rootDeps[dep]);
179
196
  const missingForcedDevDeps = forcedRuntimeDevDeps.filter((dep) => !rootDeps[dep]);
180
197
  const requiredMissingDeps = missingDeps.filter((dep) => !optionalPeerDeps.has(dep));
@@ -192,7 +209,8 @@ class PackageRunner extends runner("package") {
192
209
  stdio: "inherit"
193
210
  });
194
211
  } else {
195
- await $`cp -r ${pkg.cwdPath}/. ${pkg.dist.cwdPath}`;
212
+ await pkg.dist.cp(pkg.cwdPath, pkg.dist.cwdPath);
213
+ await $`rm -rf ${pkg.dist.cwdPath}/local`;
196
214
  await Promise.all([
197
215
  pkg.generateDistPackageJson(packageRuntimeDeps, packageRuntimeDevDeps),
198
216
  pkg.generateTsconfigJson()
@@ -266,7 +284,7 @@ class PackageRunner extends runner("package") {
266
284
  if (!await Bun.file(distPackageJsonPath).exists()) {
267
285
  throw new Error(`[package] dist package not found for ${pkg.name}. Run build-package first.`);
268
286
  }
269
- const pkgJson = await FileSys.readJson(distPackageJsonPath);
287
+ const pkgJson = await FileSys2.readJson(distPackageJsonPath);
270
288
  if (pkgJson.name !== pkg.name) {
271
289
  throw new Error(`[package] dist package name mismatch: expected ${pkg.name}, got ${pkgJson.name ?? "(missing)"}`);
272
290
  }
@@ -275,12 +293,9 @@ class PackageRunner extends runner("package") {
275
293
  if (pkgJson.publishConfig?.access !== "public") {
276
294
  throw new Error(`[package] ${pkg.name} must publish with publishConfig.access=public`);
277
295
  }
278
- if (!await Bun.file(`${pkg.dist.cwdPath}/README.md`).exists()) {
279
- throw new Error(`[package] README.md is missing from dist package ${pkg.name}`);
280
- }
281
- if (!await Bun.file(`${pkg.dist.cwdPath}/README.ko.md`).exists()) {
282
- throw new Error(`[package] README.ko.md is missing from dist package ${pkg.name}`);
283
- }
296
+ for (const readme of ["README.md", "README.ko.md"])
297
+ if (!await Bun.file(`${pkg.dist.cwdPath}/${readme}`).exists())
298
+ throw new Error(`[package] ${readme} is missing from dist package ${pkg.name}`);
284
299
  const binEntries = typeof pkgJson.bin === "string" ? [pkgJson.bin] : Object.values(pkgJson.bin ?? {});
285
300
  if (binEntries.some((binPath) => binPath.endsWith(".ts"))) {
286
301
  throw new Error(`[package] ${pkg.name} dist bin entries must not point at TypeScript sources`);
@@ -297,6 +312,9 @@ class PackageRunner extends runner("package") {
297
312
  cwd: pkg.workspace.workspaceRoot
298
313
  });
299
314
  const [packResult] = JSON.parse(packOutput);
315
+ const localFiles = (packResult?.files ?? []).filter((file) => file.path?.startsWith("local/"));
316
+ if (localFiles.length > 0)
317
+ throw new Error(`[package] ${pkg.name} would publish ${localFiles.length} test-run files under local/`);
300
318
  return {
301
319
  name: pkg.name,
302
320
  version: pkgJson.version,
@@ -313,9 +331,8 @@ class PackageRunner extends runner("package") {
313
331
  peerExportsMaps.set(pkg.name, await PackageExportsMap.from(pkg.dist.cwdPath));
314
332
  }
315
333
  const results = [];
316
- for (const pkg of pkgs) {
334
+ for (const pkg of pkgs)
317
335
  results.push(await this.verifyDistPackage(pkg, { peerExportsMaps }));
318
- }
319
336
  return results;
320
337
  }
321
338
  async#copyPackageReadmes(pkg) {