@akanjs/cli 3.1.0-rc.20 → 3.1.0-rc.22

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 (76) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-n3tzjm91.js → CodeAgent-fee0pnwp.js} +2 -2
  3. package/{CodeTui-fnm9ft4d.js → CodeTui-xh71b2k8.js} +1 -1
  4. package/TunnelShare-s7bpe55e.js +14 -0
  5. package/{agent.command-3qxf4xcj.js → agent.command-tge9rvmt.js} +5 -5
  6. package/akanCode.js +2 -2
  7. package/{application.command-zfja7x4r.js → application.command-j5b8yrcf.js} +35 -9
  8. package/{applicationBuildRunner-vh4j6vdv.js → applicationBuildRunner-s41mgz21.js} +21 -7
  9. package/buildBatch.proc.js +9 -9
  10. package/{cloud.command-fcc8e8tp.js → cloud.command-q9srng6e.js} +13 -13
  11. package/cloud.script-vfsd4gxs.js +24 -0
  12. package/{code.command-130bdmhe.js → code.command-n6r6zt97.js} +6 -6
  13. package/commandManifest.json +1 -1
  14. package/{context.command-0qx447mb.js → context.command-1je84w1b.js} +16 -16
  15. package/context.runner-xg0ngz93.js +25 -0
  16. package/{guideline.command-cv5bmrx2.js → guideline.command-0e0sx2vg.js} +2 -2
  17. package/guidelines/conventions/conventions.instruction.md +42 -13
  18. package/guidelines/mcpRule/mcpRule.instruction.md +88 -47
  19. package/guidelines/pageRule/pageRule.instruction.md +53 -8
  20. package/guidelines/runtimeRule/runtimeRule.instruction.md +8 -1
  21. package/guidelines/ssrRule/ssrRule.instruction.md +8 -5
  22. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +1 -1
  23. package/incrementalBuilder.proc.js +3 -3
  24. package/{index-fmzcs8v6.js → index-1bhv9dh4.js} +4 -4
  25. package/{index-qtfmtcrw.js → index-1xqq3va9.js} +71 -18
  26. package/{index-86jt2a0e.js → index-3xhak9e0.js} +1 -1
  27. package/{index-tamvyvj3.js → index-4fe4qqgn.js} +3 -3
  28. package/{index-g1mbppa9.js → index-551gh8h2.js} +5 -5
  29. package/{index-trpasv9q.js → index-5m0s0gdv.js} +1 -1
  30. package/index-6mprvdt8.js +566 -0
  31. package/{index-192ha4xh.js → index-6nqnqzv1.js} +1 -1
  32. package/{index-dye8pnxx.js → index-73esn3y2.js} +1 -1
  33. package/{index-4mhy6qme.js → index-7xy30jev.js} +4 -4
  34. package/{index-1xj2t7cb.js → index-85h3dhe0.js} +7 -7
  35. package/{index-axs61rna.js → index-8abyrfw8.js} +5 -4
  36. package/{index-1p98exm2.js → index-94jq9cbz.js} +2 -2
  37. package/{index-cpb3nvma.js → index-9h0z0tjr.js} +2 -2
  38. package/{index-hsadfb6c.js → index-c9rfak6r.js} +7 -7
  39. package/{index-w44cy4vs.js → index-cgyqx6q1.js} +2 -2
  40. package/{index-d72hfmdm.js → index-cq5x7a9k.js} +8 -8
  41. package/{index-j237xtew.js → index-deckcwbg.js} +2 -2
  42. package/{index-vk0pa0mn.js → index-ex35dg39.js} +2 -1
  43. package/{index-35hc95h5.js → index-f9118j70.js} +1 -1
  44. package/{index-jw1zm273.js → index-g5px5pxd.js} +53 -9
  45. package/{index-va06nr10.js → index-gxqvev8w.js} +52 -12
  46. package/{index-fyq1z6kt.js → index-hagw9c94.js} +3 -3
  47. package/{index-pydbnfez.js → index-p44jnjfr.js} +2 -2
  48. package/{index-awbdfcf2.js → index-rp9anyeb.js} +4 -4
  49. package/{index-j4mkhz93.js → index-t8npm331.js} +3 -3
  50. package/{index-5edzv8fn.js → index-tbmtmkhx.js} +2 -2
  51. package/{index-1djcjcre.js → index-vyh8kemm.js} +3 -3
  52. package/{index-qwa5k1j8.js → index-x7bny3wv.js} +1 -1
  53. package/index.js +22 -22
  54. package/{library.command-erp2f56n.js → library.command-ys9s0mtc.js} +3 -3
  55. package/{localRegistry.command-hj3p16p5.js → localRegistry.command-kmp3sd47.js} +12 -12
  56. package/{module.command-gs2r615e.js → module.command-5sx9453y.js} +5 -5
  57. package/{package.command-j10r76ax.js → package.command-s0d3417k.js} +3 -3
  58. package/package.json +2 -2
  59. package/{page.command-4h4a8pnh.js → page.command-zsa03pmc.js} +3 -3
  60. package/{pipeline.command-a2nrk26m.js → pipeline.command-j8h6qsha.js} +2 -2
  61. package/{primitive.command-w6t0asqz.js → primitive.command-n2978nmw.js} +6 -6
  62. package/{projectTypecheck-f534enqj.js → projectTypecheck-qg2jf80j.js} +1 -1
  63. package/{quality.command-77x7vbbx.js → quality.command-7kgz46st.js} +2 -2
  64. package/{repair.command-y6sstev7.js → repair.command-2sszcckw.js} +5 -5
  65. package/{routeSourceValidator-7ycnfz0e.js → routeSourceValidator-6jd0q6r6.js} +47 -14
  66. package/{scalar.command-20b8cy0k.js → scalar.command-230jrhzf.js} +4 -4
  67. package/{subspace.command-baz73jpk.js → subspace.command-y5v4ypd3.js} +8 -8
  68. package/templates/migration/__migrationId__.ts +23 -0
  69. package/templates/server.ts +8 -1
  70. package/{tunnel.command-2kw8vt9g.js → tunnel.command-ja29zghd.js} +7 -7
  71. package/{workflow.command-2djwmpqf.js → workflow.command-0eg8czt5.js} +10 -10
  72. package/{workspace.command-jqs7vjhe.js → workspace.command-zcym1dk5.js} +24 -24
  73. package/TunnelShare-661cxz5e.js +0 -14
  74. package/cloud.script-1xt3tnts.js +0 -24
  75. package/context.runner-1vsjztjg.js +0 -25
  76. package/index-665zp9rs.js +0 -271
@@ -22,26 +22,26 @@ import {
22
22
  renderWorkflowApply,
23
23
  renderWorkflowValidation,
24
24
  renderWorkflowRunArtifact
25
- } from "./index-trpasv9q.js";
25
+ } from "./index-5m0s0gdv.js";
26
26
  import {
27
27
  AkanContextAnalyzer
28
- } from "./index-5edzv8fn.js";
28
+ } from "./index-tbmtmkhx.js";
29
29
  import {
30
30
  CommandContainer,
31
31
  runner
32
- } from "./index-jw1zm273.js";
32
+ } from "./index-g5px5pxd.js";
33
33
  import {
34
34
  ModuleScript
35
- } from "./index-fmzcs8v6.js";
35
+ } from "./index-1bhv9dh4.js";
36
36
  import {
37
37
  PrimitiveScript
38
- } from "./index-awbdfcf2.js";
38
+ } from "./index-rp9anyeb.js";
39
39
  import {
40
40
  spawnShell
41
- } from "./index-j4mkhz93.js";
41
+ } from "./index-t8npm331.js";
42
42
  import {
43
43
  ScalarScript
44
- } from "./index-1p98exm2.js";
44
+ } from "./index-94jq9cbz.js";
45
45
 
46
46
  // pkgs/@akanjs/cli/workflow/workflow.runner.ts
47
47
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  resolveSsrPageEntriesForApp
4
- } from "./index-va06nr10.js";
4
+ } from "./index-gxqvev8w.js";
5
5
  import {
6
6
  computeRouteSeedIndex,
7
7
  saveRouteSeedIndex,
@@ -9,7 +9,7 @@ import {
9
9
  ClientEntriesBundler,
10
10
  VENDOR_SPECIFIERS,
11
11
  RouteClientBuilder
12
- } from "./index-w44cy4vs.js";
12
+ } from "./index-cgyqx6q1.js";
13
13
  import {
14
14
  SOURCE_EXTS
15
15
  } from "./index-5nd1wtkv.js";
@@ -19,7 +19,7 @@ import {
19
19
  createTsconfigPackageResolver,
20
20
  rewriteBarrelImports,
21
21
  PagesBundleBuilder
22
- } from "./index-192ha4xh.js";
22
+ } from "./index-6nqnqzv1.js";
23
23
  import {
24
24
  CssBlockParser
25
25
  } from "./index-62md4dwy.js";
@@ -1240,7 +1240,8 @@ class FontPruner {
1240
1240
  { dir: path5.join(this.#artifactRoot, "client"), label: ".akan/artifact/client", needles: bundled },
1241
1241
  { dir: path5.join(this.#artifactRoot, "client-ssr"), label: ".akan/artifact/client-ssr", needles: bundled },
1242
1242
  { dir: path5.join(this.#artifactRoot, "server"), label: ".akan/artifact/server", needles: bundled },
1243
- { dir: path5.join(this.#app.dist.cwdPath, "csr"), label: "csr", needles: bundled }
1243
+ { dir: path5.join(this.#app.dist.cwdPath, "csr"), label: "csr", needles: bundled },
1244
+ { dir: path5.join(this.#app.dist.cwdPath, "mcp-apps"), label: "mcp-apps", needles: bundled }
1244
1245
  ];
1245
1246
  for (const root of roots) {
1246
1247
  const pending = root.needles.filter((candidate) => !referrers.has(candidate.rel));
@@ -2,12 +2,12 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-jw1zm273.js";
5
+ } from "./index-g5px5pxd.js";
6
6
  import {
7
7
  generatedFilesForSync,
8
8
  createPassedPrimitiveReport,
9
9
  scalarChangedFiles
10
- } from "./index-trpasv9q.js";
10
+ } from "./index-5m0s0gdv.js";
11
11
  import {
12
12
  pluralizeName
13
13
  } from "./index-nz8prx9g.js";
@@ -9,10 +9,10 @@ import {
9
9
  NativePublicEnv,
10
10
  UpdatePackFolder,
11
11
  NativeApp
12
- } from "./index-g1mbppa9.js";
12
+ } from "./index-551gh8h2.js";
13
13
  import {
14
14
  ExitCodeError
15
- } from "./index-jw1zm273.js";
15
+ } from "./index-g5px5pxd.js";
16
16
  import {
17
17
  ConfigLock
18
18
  } from "./index-bqbf654f.js";
@@ -4,26 +4,26 @@ import {
4
4
  CloudApi,
5
5
  CloudUpdates,
6
6
  PipelineSecrets
7
- } from "./index-cpb3nvma.js";
7
+ } from "./index-9h0z0tjr.js";
8
8
  import {
9
9
  PkgExecutor
10
- } from "./index-va06nr10.js";
10
+ } from "./index-gxqvev8w.js";
11
11
  import {
12
12
  NativePublicEnv,
13
13
  UpdatePackFolder
14
- } from "./index-g1mbppa9.js";
14
+ } from "./index-551gh8h2.js";
15
15
  import {
16
16
  script
17
- } from "./index-jw1zm273.js";
17
+ } from "./index-g5px5pxd.js";
18
18
  import {
19
19
  ApplicationScript
20
- } from "./index-qtfmtcrw.js";
20
+ } from "./index-1xqq3va9.js";
21
21
  import {
22
22
  PackageScript
23
- } from "./index-j237xtew.js";
23
+ } from "./index-deckcwbg.js";
24
24
  import {
25
25
  CloudRunner
26
- } from "./index-fyq1z6kt.js";
26
+ } from "./index-hagw9c94.js";
27
27
 
28
28
  // pkgs/@akanjs/cli/cloud/cloud.script.ts
29
29
  import { Logger } from "akanjs/common";
@@ -19,11 +19,11 @@ import {
19
19
  CsrDevPaths,
20
20
  PagesEntrySourceGenerator,
21
21
  PagesBundleBuilder
22
- } from "./index-192ha4xh.js";
22
+ } from "./index-6nqnqzv1.js";
23
23
  import {
24
24
  AsyncDefaultExportDetector,
25
25
  resolveSsrPageEntriesForApp
26
- } from "./index-va06nr10.js";
26
+ } from "./index-gxqvev8w.js";
27
27
 
28
28
  // pkgs/@akanjs/devkit/frontendBuild/autoImportSync.ts
29
29
  import { readdir, readFile, stat } from "fs/promises";
@@ -1,13 +1,13 @@
1
1
  // @bun
2
2
  import {
3
3
  AppExecutor
4
- } from "./index-va06nr10.js";
4
+ } from "./index-gxqvev8w.js";
5
5
  import {
6
6
  jsonText,
7
7
  createWorkflowBaselineSummary,
8
8
  buildAkanModuleContextIndex,
9
9
  toolingRolloutGate
10
- } from "./index-trpasv9q.js";
10
+ } from "./index-5m0s0gdv.js";
11
11
  import {
12
12
  buildResourceList,
13
13
  codexMcpConfigPath,
@@ -17,29 +17,29 @@ import {
17
17
  upsertCodexMcpServerBlock,
18
18
  renderDoctorText,
19
19
  AkanContextAnalyzer
20
- } from "./index-5edzv8fn.js";
20
+ } from "./index-tbmtmkhx.js";
21
21
  import {
22
22
  runner
23
- } from "./index-jw1zm273.js";
23
+ } from "./index-g5px5pxd.js";
24
24
  import {
25
25
  isPlaceholderAppId
26
- } from "./index-vk0pa0mn.js";
26
+ } from "./index-ex35dg39.js";
27
27
  import {
28
28
  getMobileTargets,
29
29
  appIdsOf
30
30
  } from "./index-m9jj544v.js";
31
31
  import {
32
32
  NativeApp
33
- } from "./index-g1mbppa9.js";
33
+ } from "./index-551gh8h2.js";
34
34
  import {
35
35
  Prompter2
36
36
  } from "./index-zzvvc845.js";
37
37
  import {
38
38
  RepairRunner
39
- } from "./index-j4mkhz93.js";
39
+ } from "./index-t8npm331.js";
40
40
  import {
41
41
  WorkflowRunner
42
- } from "./index-1xj2t7cb.js";
42
+ } from "./index-85h3dhe0.js";
43
43
 
44
44
  // pkgs/@akanjs/devkit/akanMcpContract.ts
45
45
  import path from "path";
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-jw1zm273.js";
5
+ } from "./index-g5px5pxd.js";
6
6
  import {
7
7
  FileSys2
8
8
  } from "./index-52w0fvh8.js";
9
9
  import {
10
10
  PkgExecutor
11
- } from "./index-va06nr10.js";
11
+ } from "./index-gxqvev8w.js";
12
12
  import {
13
13
  TypeScriptDependencyScanner2
14
14
  } from "./index-tvehn2sp.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  DesktopBin,
4
4
  UpdatePackFolder
5
- } from "./index-g1mbppa9.js";
5
+ } from "./index-551gh8h2.js";
6
6
  // pkgs/@akanjs/devkit/mobile/desktopServerStage.ts
7
7
  import { cp, mkdir, readdir, rm, writeFile } from "fs/promises";
8
8
  import path from "path";
@@ -16,6 +16,7 @@ class DesktopServerStage {
16
16
  "console.js",
17
17
  "console-runtime.js",
18
18
  "csr",
19
+ "mcp-apps",
19
20
  "public",
20
21
  ".akan"
21
22
  ]);
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  AppInfo
4
- } from "./index-va06nr10.js";
4
+ } from "./index-gxqvev8w.js";
5
5
 
6
6
  // pkgs/@akanjs/devkit/slicePlanner.ts
7
7
  class SlicePlanner {
@@ -10,7 +10,7 @@ import {
10
10
  LibExecutor,
11
11
  PkgExecutor,
12
12
  ModuleExecutor
13
- } from "./index-va06nr10.js";
13
+ } from "./index-gxqvev8w.js";
14
14
 
15
15
  // pkgs/@akanjs/devkit/commandDecorators/camelToKebabCase.ts
16
16
  var camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
@@ -289,8 +289,9 @@ var formatCommandHelp = (command, key) => {
289
289
  const optName = `${flag}--${kebabName}${negation}`;
290
290
  const optDesc = opt.desc ?? "";
291
291
  const defaultVal = opt.default !== undefined ? chalk.gray(` [default: ${String(opt.default)}]`) : "";
292
+ const repeatable = opt.multiple ? chalk.gray(" (repeatable)") : "";
292
293
  const choices = opt.enum ? chalk.gray(typeof opt.enum === "function" ? " ([dynamic choices])" : ` (${opt.enum.map(formatChoice).join(", ")})`) : "";
293
- lines.push(` ${chalk.green(optName)} ${chalk.gray(optDesc)}${defaultVal}${choices}`);
294
+ lines.push(` ${chalk.green(optName)} ${chalk.gray(optDesc)}${defaultVal}${choices}${repeatable}`);
294
295
  }
295
296
  lines.push("");
296
297
  }
@@ -301,6 +302,10 @@ var formatCommandHelp = (command, key) => {
301
302
  // pkgs/@akanjs/devkit/commandDecorators/command.ts
302
303
  var loggedCliErrorObjects = new WeakSet;
303
304
  var loggedCliErrorMessages = new Set;
305
+ var markCliErrorPrinted = (error) => {
306
+ if (typeof error === "object" && error !== null)
307
+ loggedCliErrorObjects.add(error);
308
+ };
304
309
  var formatCliError = (error) => {
305
310
  if (error instanceof Error)
306
311
  return error.message || error.name;
@@ -341,7 +346,12 @@ var handleOption = (programCommand, argMeta) => {
341
346
  } = argMeta.argsOption;
342
347
  const kebabName = camelToKebabCase(argMeta.name);
343
348
  const choices = enumChoices && typeof enumChoices !== "function" ? normalizeEnumChoices(enumChoices) : null;
344
- programCommand.option(`-${flag}, --${kebabName}${type === "boolean" ? " [boolean]" : ` <${kebabName}>`}`, `${desc}${ask ? ` (${ask})` : ""}${example ? ` (example: ${example})` : ""}${choices ? ` (choices: ${choices.map((choice) => choice.name).join(", ")})` : ""}`);
349
+ const flags = `-${flag}, --${kebabName}${type === "boolean" ? " [boolean]" : ` <${kebabName}>`}`;
350
+ const description = `${desc}${ask ? ` (${ask})` : ""}${example ? ` (example: ${example})` : ""}${choices ? ` (choices: ${choices.map((choice) => choice.name).join(", ")})` : ""}`;
351
+ if (argMeta.argsOption.multiple)
352
+ programCommand.option(flags, description, (value, previous = []) => [...previous, value]);
353
+ else
354
+ programCommand.option(flags, description);
345
355
  if (type === "boolean" && argMeta.argsOption.default === true)
346
356
  programCommand.option(`--no-${kebabName}`, `turn off --${kebabName}`);
347
357
  return programCommand;
@@ -359,6 +369,17 @@ var convertArgValue = (value, type) => {
359
369
  else
360
370
  return value === true || value === "true";
361
371
  };
372
+ var givenOptionsOf = (argMetas, opt) => {
373
+ const given = {};
374
+ for (const argMeta of argMetas) {
375
+ if (argMeta.type !== "Option" || opt[argMeta.name] === undefined)
376
+ continue;
377
+ const type = argMeta.argsOption.type ?? "string";
378
+ const value = opt[argMeta.name];
379
+ given[argMeta.name] = Array.isArray(value) ? value.map((each) => convertArgValue(each, type)) : convertArgValue(value, type);
380
+ }
381
+ return given;
382
+ };
362
383
  var normalizeEnumChoices = (enumChoices) => enumChoices.map((choice) => typeof choice === "object" ? { value: choice.value, name: choice.label } : { value: choice, name: choice.toString() });
363
384
  var prompts = async () => await import("@inquirer/prompts");
364
385
  var select = (config, context) => prompts().then((m) => m.select(config, context));
@@ -384,8 +405,14 @@ var inputMessageOf = ({ name, argsOption: { desc, example, ask } }) => ask ? `${
384
405
  var getOptionValue = async (argMeta, opt, context) => {
385
406
  const {
386
407
  name,
387
- argsOption: { enum: enumChoices, default: defaultValue, type, desc, nullable, ask }
408
+ argsOption: { enum: enumChoices, default: defaultValue, type, desc, nullable, ask, multiple }
388
409
  } = argMeta;
410
+ if (multiple) {
411
+ const values = opt[argMeta.name] ?? [];
412
+ for (const value of values)
413
+ assertEnumChoice(argMeta, value);
414
+ return values.map((value) => convertArgValue(value, type ?? "string"));
415
+ }
389
416
  if (opt[argMeta.name] !== undefined) {
390
417
  assertEnumChoice(argMeta, opt[argMeta.name]);
391
418
  return convertArgValue(opt[argMeta.name], type ?? "string");
@@ -574,6 +601,7 @@ var getInternalArgumentValue = async (argMeta, value, workspace) => {
574
601
  };
575
602
  var runCommands = async (...commands) => {
576
603
  let failureExitCode = 1;
604
+ let reportFailure = async (_error) => {};
577
605
  process.on("unhandledRejection", (error) => {
578
606
  printCliError(error);
579
607
  process.exit(ExitCodeError.codeOf(error) ?? failureExitCode);
@@ -614,9 +642,19 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
614
642
  hidden: targetMeta.targetOption.devOnly
615
643
  });
616
644
  const targetFailureExitCode = targetMeta.targetOption.failureExitCode;
617
- if (targetFailureExitCode !== undefined)
618
- programCommand.exitOverride((error) => process.exit(error.exitCode === 0 ? 0 : targetFailureExitCode));
645
+ const usageExitCode = targetMeta.targetOption.usageExitCode ?? targetFailureExitCode;
646
+ const { onFailure } = targetMeta.targetOption;
619
647
  const [allArgMetas] = getArgMetas(command, targetMeta.key);
648
+ if (usageExitCode !== undefined || onFailure)
649
+ programCommand.exitOverride((error) => {
650
+ if (error.exitCode === 0)
651
+ process.exit(0);
652
+ const refused = new ExitCodeError(error.message.replace(/^error: /, ""), usageExitCode ?? error.exitCode);
653
+ markCliErrorPrinted(refused);
654
+ const given = givenOptionsOf(allArgMetas, programCommand.opts());
655
+ reportFailure = async (failure) => await onFailure?.(failure, { usage: true, given });
656
+ throw refused;
657
+ });
620
658
  for (const argMeta of allArgMetas) {
621
659
  if (argMeta.type === "Option")
622
660
  programCommand = handleOption(programCommand, argMeta);
@@ -643,6 +681,7 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
643
681
  Logger.rawLog();
644
682
  const cmdArgs = args.slice(0, args.length - 2);
645
683
  const opt = args[args.length - 2];
684
+ reportFailure = async (failure) => await onFailure?.(failure, { usage: false, given: givenOptionsOf(allArgMetas, opt) });
646
685
  const commandArgs = [];
647
686
  if (targetMeta.targetOption.runsOnWorkspaceRoot)
648
687
  await assertCurrentDirectoryIsWorkspaceRoot();
@@ -681,13 +720,18 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
681
720
  }
682
721
  }
683
722
  }
684
- await program.parseAsync(process.argv).catch((error) => {
723
+ await program.parseAsync(process.argv).catch(async (error) => {
685
724
  printCliError(error);
725
+ await reportFailure(error).catch(printCliError);
686
726
  process.exit(ExitCodeError.codeOf(error) ?? failureExitCode);
687
727
  });
688
728
  };
689
729
  // pkgs/@akanjs/devkit/commandDecorators/commandBuilder.ts
690
- var argMetaOf = (type, name, primitive, argsOption, idx) => ({ name, argsOption: { ...argsOption, type: normalizePrimitiveArgType(primitive) }, key: "", idx, type });
730
+ var argMetaOf = (type, name, primitive, argsOption, idx) => {
731
+ if (type === "Argument" && argsOption?.multiple)
732
+ throw new Error(`argument '${name}' cannot be multiple`);
733
+ return { name, argsOption: { ...argsOption, type: normalizePrimitiveArgType(primitive) }, key: "", idx, type };
734
+ };
691
735
 
692
736
  class TargetBuilder {
693
737
  targetOption;
@@ -758,4 +802,4 @@ function command(refName, depsOrBuilder, builder) {
758
802
  }
759
803
  return CommandBase;
760
804
  }
761
- export { getTargetMetas, getTargetCommandNames, App, Apps, Lib, Sys, SysOrOnlyApp, Exec, Pkg, Module, Workspace, CommandContainer, runner, script, ExitCodeError, assertPromptable, runCommands, command };
805
+ export { getTargetMetas, getTargetCommandNames, App, Apps, Lib, Sys, SysOrOnlyApp, Exec, Pkg, Module, Workspace, CommandContainer, runner, script, ExitCodeError, markCliErrorPrinted, assertPromptable, runCommands, command };
@@ -1344,8 +1344,9 @@ var IMPLICIT_LAYOUT_DIR = path6.join(".akan", "generated", "root-layouts");
1344
1344
  var IMPLICIT_DICT_DIR = path6.join(".akan", "generated", "dict");
1345
1345
  var IMPLICIT_OVERRIDES_DIR = path6.join(".akan", "generated", "overrides");
1346
1346
  var OVERRIDES_KEY_RE = /^\.\/(.+\/)?_overrides\.(tsx|ts|jsx|js)$/;
1347
+ var posixRelative = (fromDir, toAbsPath) => path6.relative(fromDir, toAbsPath).split(path6.sep).join("/");
1347
1348
  var importSpecifier = (fromAbsPath, toAbsPath) => {
1348
- const rel = path6.relative(path6.dirname(fromAbsPath), toAbsPath).split(path6.sep).join("/");
1349
+ const rel = posixRelative(path6.dirname(fromAbsPath), toAbsPath);
1349
1350
  return rel.startsWith(".") ? rel : `./${rel}`;
1350
1351
  };
1351
1352
  async function writeGeneratedOverridesLayoutFile(opts) {
@@ -1449,15 +1450,15 @@ async function writeGeneratedRootLayoutFile(opts) {
1449
1450
  void st;
1450
1451
  ` : `import "@apps/${opts.appName}/client";
1451
1452
  `;
1452
- const inheritedLabel = inheritedSourceAbsPath ? path6.relative(opts.appCwdPath, inheritedSourceAbsPath) : "";
1453
+ const inheritedLabel = inheritedSourceAbsPath ? posixRelative(opts.appCwdPath, inheritedSourceAbsPath) : "";
1453
1454
  const inheritedImport = inheritedSourceSpecifier ? `import * as inheritedModule from ${JSON.stringify(inheritedSourceSpecifier)};
1454
- const inheritedLayout = resolveRouteModule(inheritedModule as never, ${JSON.stringify(inheritedLabel)}).module as LayoutModule;
1455
+ const inheritedLayout = assertGuardOnChain(${JSON.stringify(inheritedLabel)}, resolveRouteModule(inheritedModule as never, ${JSON.stringify(inheritedLabel)})).module as LayoutModule;
1455
1456
  ` : `const inheritedLayout: LayoutModule = {};
1456
1457
  `;
1457
1458
  const prefix = opts.boundary.segments.find((segment) => !/^\(.+\)$/.test(segment)) ?? null;
1458
- const userLabel = opts.boundary.sourceAbsPath ? path6.relative(opts.appCwdPath, opts.boundary.sourceAbsPath) : "";
1459
+ const userLabel = opts.boundary.sourceAbsPath ? posixRelative(opts.appCwdPath, opts.boundary.sourceAbsPath) : "";
1459
1460
  const userImport = sourceSpecifier ? `import * as userModule from ${JSON.stringify(sourceSpecifier)};
1460
- const userLayout = resolveRouteModule(userModule as never, ${JSON.stringify(userLabel)}).module as LayoutModule;
1461
+ const userLayout = assertGuardOnChain(${JSON.stringify(userLabel)}, resolveRouteModule(userModule as never, ${JSON.stringify(userLabel)})).module as LayoutModule;
1461
1462
  const UserLayout = userLayout.default as (props: LayoutProps) => ReactNode | Promise<ReactNode>;
1462
1463
  ` : `const UserLayout = ({ children }: LayoutProps) => children;
1463
1464
  const userLayout: LayoutModule = {};
@@ -1473,6 +1474,7 @@ const userLayout: LayoutModule = {};
1473
1474
  const layoutChild = isAsyncUserLayout ? "{layout}" : userLayoutElement;
1474
1475
  const layoutReturn = isAsyncUserLayout ? "layout" : userLayoutElement;
1475
1476
  const headLayouts = opts.includeSystemProvider ? "[inheritedLayout, userLayout]" : "[userLayout]";
1477
+ const guardExport = opts.includeSystemProvider ? "export const guard = RouteGuards.compose(inheritedLayout.guard, userLayout.guard);" : "export const guard = userLayout.guard;";
1476
1478
  const layoutExports = `export async function generateHead(props: PageProps) {
1477
1479
  const heads = await Promise.all(
1478
1480
  ${headLayouts}.map((layout) => (layout.generateHead ? layout.generateHead(props) : layout.head)),
@@ -1484,13 +1486,15 @@ export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
1484
1486
  export const Error = userLayout.Error ?? inheritedLayout.Error;
1485
1487
  export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
1486
1488
  export const Loading = userLayout.Loading;
1489
+ ${guardExport}
1487
1490
 
1488
1491
  ${layoutSignature}({ children, params, searchParams }: LayoutProps) {
1489
1492
  ${layoutBinding} return `;
1490
1493
  const source = opts.includeSystemProvider ? `import type { LayoutModule, LayoutProps, PageProps } from "akanjs/client";
1491
- import { loadFonts, resolveRouteModule, RouteHead } from "akanjs/client";
1494
+ import { assertGuardOnChain, loadFonts, RouteGuards, resolveRouteModule, RouteHead } from "akanjs/client";
1492
1495
  import type { ReactNode } from "react";
1493
1496
  import { System } from "akanjs/ui";
1497
+ import type { McpAppRootProps } from "akanjs/webkit";
1494
1498
  import { env } from "@apps/${opts.appName}/env/env.client";
1495
1499
  import { allDictionary } from ${JSON.stringify(dictMacroSpecifier)};
1496
1500
  ${clientImport}${inheritedImport}${userImport}
@@ -1524,8 +1528,24 @@ ${layoutExports}(
1524
1528
  </System.Provider>
1525
1529
  );
1526
1530
  }
1531
+
1532
+ export function McpAppRoot({ children, params, path }: McpAppRootProps) {
1533
+ return (
1534
+ <System.App
1535
+ params={params}
1536
+ path={path}
1537
+ env={env}
1538
+ theme={theme}
1539
+ viewport={viewport}
1540
+ fonts={loadFonts(userFonts)}
1541
+ className={defaultFontClassName}
1542
+ >
1543
+ {children}
1544
+ </System.App>
1545
+ );
1546
+ }
1527
1547
  ` : `import type { LayoutModule, LayoutProps, PageProps } from "akanjs/client";
1528
- import { resolveRouteModule, RouteHead } from "akanjs/client";
1548
+ import { assertGuardOnChain, resolveRouteModule, RouteHead } from "akanjs/client";
1529
1549
  import type { ReactNode } from "react";
1530
1550
  ${inheritedImport}${userImport}
1531
1551
  ${layoutExports}${layoutReturn};
@@ -2251,6 +2271,7 @@ var resolveRepoName = (workspaceRoot) => {
2251
2271
  };
2252
2272
 
2253
2273
  // pkgs/@akanjs/devkit/scanInfo.ts
2274
+ import { createHash } from "crypto";
2254
2275
  import path11 from "path";
2255
2276
 
2256
2277
  // pkgs/@akanjs/devkit/workspaceLayout.ts
@@ -2574,10 +2595,13 @@ class ScanInfo {
2574
2595
  var isAkanFrameworkDependency = (dep) => dep === "akanjs" || dep.startsWith("akanjs/");
2575
2596
 
2576
2597
  class AppInfo extends ScanInfo {
2598
+ static migrationDir = "script/migration";
2599
+ static #migrationIdRe = /^\d{12}_[A-Za-z][A-Za-z0-9]*$/;
2577
2600
  type = "app";
2578
2601
  exec;
2579
2602
  akanConfig;
2580
2603
  libDeps;
2604
+ migrations;
2581
2605
  static appInfos = new Map;
2582
2606
  static async fromExecutor(exec, options = {}) {
2583
2607
  const existingAppInfo = AppInfo.appInfos.get(exec.name);
@@ -2589,16 +2613,20 @@ class AppInfo extends ScanInfo {
2589
2613
  const libExecutor = LibExecutor.from(exec, libName);
2590
2614
  LibInfo.libInfos.set(libName, await LibInfo.fromExecutor(libExecutor));
2591
2615
  }));
2592
- const libDeps = await AppInfo.#getAllLibDeps(exec, scanResult.libDeps);
2593
- const appInfo = new AppInfo(exec, scanResult, libDeps);
2616
+ const [libDeps, migrations] = await Promise.all([
2617
+ AppInfo.#getAllLibDeps(exec, scanResult.libDeps),
2618
+ AppInfo.scanMigrations(exec)
2619
+ ]);
2620
+ const appInfo = new AppInfo(exec, scanResult, libDeps, migrations);
2594
2621
  AppInfo.appInfos.set(exec.name, appInfo);
2595
2622
  return appInfo;
2596
2623
  }
2597
- constructor(exec, scanResult, libDeps) {
2624
+ constructor(exec, scanResult, libDeps, migrations = []) {
2598
2625
  super(scanResult);
2599
2626
  this.exec = exec;
2600
2627
  this.akanConfig = scanResult.akanConfig;
2601
2628
  this.libDeps = libDeps;
2629
+ this.migrations = migrations;
2602
2630
  }
2603
2631
  getScanResult() {
2604
2632
  return this.scanResult;
@@ -2606,6 +2634,18 @@ class AppInfo extends ScanInfo {
2606
2634
  setRoutes(routes) {
2607
2635
  this.scanResult.routes = routes;
2608
2636
  }
2637
+ static async scanMigrations(exec) {
2638
+ const files = (await exec.readdir(AppInfo.migrationDir)).filter((file) => file.endsWith(".ts") && !/\.(test|spec|d)\.ts$/.test(file));
2639
+ return await Promise.all(files.map(async (file) => {
2640
+ const id = file.slice(0, -".ts".length);
2641
+ if (!AppInfo.#migrationIdRe.test(id))
2642
+ throw new Error(`${AppInfo.migrationDir}/${file}: a migration is named <yyyyMMddHHmm>_<camelName>.ts; create one with \`akan create-migration\``);
2643
+ const source = (await exec.readFile(`${AppInfo.migrationDir}/${file}`)).replace(/^\uFEFF/, "").replaceAll(`\r
2644
+ `, `
2645
+ `);
2646
+ return { id, checksum: createHash("sha256").update(source).digest("hex") };
2647
+ }));
2648
+ }
2609
2649
  static async#getAllLibDeps(exec, libDeps, libSet = new Set) {
2610
2650
  await Promise.all(libDeps.map(async (libName) => {
2611
2651
  if (libSet.has(libName))
@@ -3741,7 +3781,7 @@ class SysExecutor extends Executor {
3741
3781
  class AppExecutor extends SysExecutor {
3742
3782
  static #routeSourceValidator = null;
3743
3783
  static async#getRouteSourceValidator() {
3744
- AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-7ycnfz0e.js")).RouteSourceValidator;
3784
+ AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-6jd0q6r6.js")).RouteSourceValidator;
3745
3785
  return AppExecutor.#routeSourceValidator;
3746
3786
  }
3747
3787
  dist;
@@ -4268,4 +4308,4 @@ class ModuleExecutor extends Executor {
4268
4308
  }
4269
4309
  }
4270
4310
 
4271
- export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, binPlatforms, ServerEnvProfile, AkanAppConfig, AkanWorkspaceConfig, AsyncDefaultExportDetector, resolveSsrPageEntriesForApp, CodegenLock, Linter, LibSource, formatLibStatuses, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, libFacetRootHintOf, barrelFacetDirs, facetIndexShadowOf, rootEntryHintOf, isScannedRootEntry, AppInfo, Spinner, ProjectTypecheck2, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
4311
+ export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, binPlatforms, ServerEnvProfile, AkanAppConfig, AkanWorkspaceConfig, AsyncDefaultExportDetector, resolveSsrPageEntriesForApp, CodegenLock, Linter, LibSource, formatLibStatuses, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, libFacetRootHintOf, barrelFacetDirs, facetIndexShadowOf, rootEntryHintOf, isScannedRootEntry, AppInfo, Spinner, ProjectTypecheck2, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
@@ -5,15 +5,15 @@ import {
5
5
  CloudApi,
6
6
  CloudUpdates,
7
7
  PipelineSecrets
8
- } from "./index-cpb3nvma.js";
8
+ } from "./index-9h0z0tjr.js";
9
9
  import {
10
10
  WorkspaceExecutor,
11
11
  AppExecutor
12
- } from "./index-va06nr10.js";
12
+ } from "./index-gxqvev8w.js";
13
13
  import {
14
14
  runner,
15
15
  assertPromptable
16
- } from "./index-jw1zm273.js";
16
+ } from "./index-g5px5pxd.js";
17
17
  import {
18
18
  SubspaceConfig
19
19
  } from "./index-4pf8g7ff.js";
@@ -2,12 +2,12 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-jw1zm273.js";
5
+ } from "./index-g5px5pxd.js";
6
6
  import {
7
7
  LibSource,
8
8
  formatLibStatuses,
9
9
  LibExecutor
10
- } from "./index-va06nr10.js";
10
+ } from "./index-gxqvev8w.js";
11
11
 
12
12
  // pkgs/@akanjs/cli/library/library.script.ts
13
13
  import { Logger } from "akanjs/common";
@@ -1,12 +1,12 @@
1
1
  // @bun
2
2
  import {
3
3
  script
4
- } from "./index-jw1zm273.js";
4
+ } from "./index-g5px5pxd.js";
5
5
  import {
6
6
  AppExecutor,
7
7
  LibExecutor,
8
8
  ModuleExecutor
9
- } from "./index-va06nr10.js";
9
+ } from "./index-gxqvev8w.js";
10
10
  import {
11
11
  workflowStatus,
12
12
  compactDiagnostics,
@@ -41,10 +41,10 @@ import {
41
41
  hasSignalFactoryEntry,
42
42
  insertSignalFactoryEntry,
43
43
  addFieldUiPolicyForType
44
- } from "./index-trpasv9q.js";
44
+ } from "./index-5m0s0gdv.js";
45
45
  import {
46
46
  ModuleScript
47
- } from "./index-fmzcs8v6.js";
47
+ } from "./index-1bhv9dh4.js";
48
48
 
49
49
  // pkgs/@akanjs/cli/primitive/primitive.script.ts
50
50
  import { capitalize, lowerlize } from "akanjs/common";
@@ -5,13 +5,13 @@ import {
5
5
  writeGeneratedSyncState,
6
6
  createRepairReport,
7
7
  renderRepairReport
8
- } from "./index-trpasv9q.js";
8
+ } from "./index-5m0s0gdv.js";
9
9
  import {
10
10
  AkanContextAnalyzer
11
- } from "./index-5edzv8fn.js";
11
+ } from "./index-tbmtmkhx.js";
12
12
  import {
13
13
  runner
14
- } from "./index-jw1zm273.js";
14
+ } from "./index-g5px5pxd.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/repair/repair.runner.ts
17
17
  var spawnShell = async (workspace, command) => await workspace.spawn("bash", ["-lc", command.startsWith("akan ") ? `bun run ${command}` : command], {
@@ -10,7 +10,7 @@ import {
10
10
  isScannedRootEntry,
11
11
  AppExecutor,
12
12
  LibExecutor
13
- } from "./index-va06nr10.js";
13
+ } from "./index-gxqvev8w.js";
14
14
  import {
15
15
  FileSys2
16
16
  } from "./index-52w0fvh8.js";
@@ -23,7 +23,7 @@ import {
23
23
  workflowPathsForPlan,
24
24
  workflowRunArtifactPath,
25
25
  workflowSyncDir
26
- } from "./index-trpasv9q.js";
26
+ } from "./index-5m0s0gdv.js";
27
27
 
28
28
  // pkgs/@akanjs/devkit/akanContext.ts
29
29
  import { readdir } from "fs/promises";