@akanjs/cli 3.0.0-alpha.4 → 3.0.0-alpha.40

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 (108) hide show
  1. package/.build-stamp +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +1 -1
  4. package/{abstractCompactor-rk6twzvj.js → abstractCompactor-20e0cwbs.js} +3 -3
  5. package/{agent.command-jfz8yfwy.js → agent.command-e835fjem.js} +9 -8
  6. package/{application.command-mxyqtd6p.js → application.command-sjtbk6tr.js} +7 -6
  7. package/{applicationBuildRunner-cwk52sb7.js → applicationBuildRunner-7gnfz7ww.js} +7 -8
  8. package/{applicationReleasePackager-yrrhbkv3.js → applicationReleasePackager-93nzdfsy.js} +2 -2
  9. package/buildBatch.proc.js +6 -5
  10. package/{capacitorApp-j357ak1g.js → capacitorApp-qv7g3dp2.js} +29 -28
  11. package/{cloud.command-f87dwe52.js → cloud.command-y0e4eyqz.js} +11 -10
  12. package/{context.command-z5bf8bn7.js → context.command-vn87jb08.js} +17 -16
  13. package/{dependencyScanner-f6grrep3.js → dependencyScanner-rbs2407b.js} +1 -1
  14. package/getDirname-ka11hm7e.js +8 -0
  15. package/{guideline.command-1m1ctar3.js → guideline.command-s4hn2bsy.js} +7 -6
  16. package/guidelines/conventions/conventions.generate.json +25 -0
  17. package/guidelines/conventions/conventions.instruction.md +1173 -0
  18. package/guidelines/cssRule/cssRule.instruction.md +7 -0
  19. package/guidelines/framework/framework.instruction.md +1 -0
  20. package/guidelines/ssrRule/ssrRule.generate.json +31 -0
  21. package/guidelines/ssrRule/ssrRule.instruction.md +108 -0
  22. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
  23. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +972 -0
  24. package/incrementalBuilder.proc.js +7 -6
  25. package/{index-1s71fwrq.js → index-0h212yqe.js} +13 -13
  26. package/index-1577bej2.js +7 -0
  27. package/{index-e3qskyt2.js → index-33zce8gt.js} +8 -4
  28. package/{index-csqk9z5j.js → index-3dp7x6rc.js} +3 -3
  29. package/{index-cn24dcqn.js → index-73rnbwgg.js} +15 -7
  30. package/{index-tq1y56tp.js → index-8d2sv6pw.js} +39 -16
  31. package/{index-jtm86byd.js → index-8vkkm7v0.js} +125 -66
  32. package/{index-r4w8cry5.js → index-9jsnb4vw.js} +4 -4
  33. package/{index-ybybkec0.js → index-becx1t0k.js} +6 -6
  34. package/{index-4yp06pn1.js → index-g9e2fhw2.js} +49 -32
  35. package/{index-cap2k2ch.js → index-hg0qvhmx.js} +152 -241
  36. package/{index-xwgm94zr.js → index-j37qq1f2.js} +1 -1
  37. package/{index-n0z3f2xg.js → index-k6fvbcj1.js} +37 -6
  38. package/{index-6pz1j0zj.js → index-mxvakhsm.js} +6 -2
  39. package/{index-vhv3xnjz.js → index-mykmf6wd.js} +8 -8
  40. package/{index-y0k42k04.js → index-mz5jtaq7.js} +1 -1
  41. package/{index-jk9q6pse.js → index-n706txcv.js} +5 -3
  42. package/{index-hjzr8ja1.js → index-qc0tnhs2.js} +1 -1
  43. package/{index-rh16j3c7.js → index-qnv0aqmm.js} +12 -8
  44. package/{index-3pgtw35d.js → index-sh01r3pm.js} +2 -2
  45. package/{index-xj8bks3p.js → index-t71zvmt9.js} +9 -11
  46. package/{index-4zgs8g1w.js → index-tsmjxph2.js} +1 -1
  47. package/{index-fmgbwsr5.js → index-x33gnap3.js} +4 -4
  48. package/{index-b978vs2e.js → index-xyrb7pk5.js} +3 -3
  49. package/index.js +21 -20
  50. package/{library.command-pwfx8dx2.js → library.command-v5cyaw9t.js} +6 -5
  51. package/{localRegistry.command-r4zjx5py.js → localRegistry.command-53t758pt.js} +10 -9
  52. package/{module.command-0t3ewata.js → module.command-pq6w84xg.js} +10 -9
  53. package/{package.command-7hmkxvpa.js → package.command-qkcs60ts.js} +6 -5
  54. package/package.json +3 -4
  55. package/{page.command-st6r4s0q.js → page.command-qj5bfnh9.js} +6 -5
  56. package/{primitive.command-1qkxpzsn.js → primitive.command-bw0nes6x.js} +11 -10
  57. package/{quality.command-hy5vt1bh.js → quality.command-g1s2wt8b.js} +532 -87
  58. package/{recipeScanner-tghkzrrt.js → recipeScanner-zrzev25x.js} +3 -3
  59. package/{repair.command-nakkq2zp.js → repair.command-mzwtejpk.js} +8 -7
  60. package/{routeSourceValidator-cncd92fv.js → routeSourceValidator-7fycdqyv.js} +3 -39
  61. package/{scalar.command-fjq272gs.js → scalar.command-rm6k3c65.js} +9 -8
  62. package/templates/app/env/env.server.debug.ts.template +1 -5
  63. package/templates/app/env/env.server.develop.ts.template +1 -5
  64. package/templates/app/env/env.server.local.ts.template +1 -5
  65. package/templates/app/env/env.server.main.ts.template +1 -5
  66. package/templates/app/page/styles.css.template +3 -3
  67. package/templates/appSample/srvkit/AuthGuard.ts +9 -5
  68. package/templates/appSample/srvkit/SessionInternalArg.ts +4 -3
  69. package/templates/crudPages/[__model__Id]/edit/page.tsx +1 -1
  70. package/templates/crudPages/new/page.tsx +1 -1
  71. package/templates/crudSinglePage/page.tsx +1 -1
  72. package/templates/env/_env.server.type.ts +7 -5
  73. package/templates/lib/db.ts +4 -2
  74. package/templates/lib/dict.ts +1 -1
  75. package/templates/lib/sig.ts +1 -1
  76. package/templates/lib/srv.ts +6 -2
  77. package/templates/lib/useClient.ts +9 -3
  78. package/templates/module/__Model__.Util.tsx +1 -1
  79. package/templates/module/__Model__.Zone.tsx +3 -5
  80. package/templates/workspaceRoot/AGENTS.md.template +0 -831
  81. package/templates/workspaceRoot/CLAUDE.md.template +19 -0
  82. package/templates/workspaceRoot/biome.json.template +4 -217
  83. package/{typeChecker-kravn7ns.js → typeChecker-g6bh0xfv.js} +1 -1
  84. package/typecheck.proc.js +1 -1
  85. package/{workflow.command-jswbgk90.js → workflow.command-g2cgcgxn.js} +16 -15
  86. package/{workspace.command-h9wwcjpt.js → workspace.command-f7jerqb2.js} +70 -52
  87. package/templates/libRoot/base/baseLogic.ts +0 -14
  88. package/templates/libRoot/base/index.ts +0 -8
  89. package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
  90. package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -33
  91. package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
  92. package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
  93. package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -17
  94. package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
  95. package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
  96. package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
  97. package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
  98. package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -18
  99. package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -61
  100. package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
  101. package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
  102. package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
  103. package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -58
  104. package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
  105. package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
  106. package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
  107. package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
  108. /package/{index-r24hmh0q.js → index-yb2wsc7f.js} +0 -0
@@ -1,13 +1,16 @@
1
1
  // @bun
2
2
  import {
3
3
  Spinner
4
- } from "./index-6pz1j0zj.js";
4
+ } from "./index-mxvakhsm.js";
5
+ import {
6
+ getDirname
7
+ } from "./index-1577bej2.js";
5
8
  import {
6
9
  FileSys
7
10
  } from "./index-67546d0j.js";
8
11
  import {
9
12
  __require
10
- } from "./index-r24hmh0q.js";
13
+ } from "./index-yb2wsc7f.js";
11
14
 
12
15
  // pkgs/@akanjs/devkit/executors.ts
13
16
  import {
@@ -41,9 +44,24 @@ import chalk2 from "chalk";
41
44
 
42
45
  // pkgs/@akanjs/devkit/agentsIndex.ts
43
46
  var recipeScannerLoad = null;
44
- var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-tghkzrrt.js");
47
+ var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-zrzev25x.js");
45
48
  var AGENT_BLOCK_START = "<!-- akan:agent:start -->";
46
49
  var AGENT_BLOCK_END = "<!-- akan:agent:end -->";
50
+ var AGENT_VERSION_PREFIX = "<!-- akan:agent:version ";
51
+ var stampBlockVersion = (block, version) => `${AGENT_VERSION_PREFIX}${version} -->
52
+
53
+ ${block}`;
54
+ var extractBlockVersion = (content) => content.match(/<!-- akan:agent:version ([^\s]+) -->/)?.[1] ?? null;
55
+ var readDevkitVersion = async () => {
56
+ const { readFile } = await import("fs/promises");
57
+ const { getDirname: getDirname2 } = await import("./getDirname-ka11hm7e.js");
58
+ try {
59
+ const raw = await readFile(`${getDirname2(import.meta.url)}/package.json`, "utf-8");
60
+ return JSON.parse(raw).version ?? null;
61
+ } catch {
62
+ return null;
63
+ }
64
+ };
47
65
  var upsertAgentBlock = (existing, block) => {
48
66
  const managed = `${AGENT_BLOCK_START}
49
67
  ${block}
@@ -137,9 +155,29 @@ ${AGENT_BLOCK_START}
137
155
  ${block}
138
156
  ${AGENT_BLOCK_END}
139
157
  `;
158
+ var CLAUDE_COMMENT_RULE = `## Comments \u2014 Overrides Your Default
159
+
160
+ Write **no comments** unless the comment passes the test below. This is the rule agents break most often here, so it
161
+ is repeated outside the guide: a diff that adds a comment the test rejects is a diff to redo.
162
+
163
+ Before typing \`//\`, \`/*\`, or a doc block, ask \u2014 **does this sentence carry a fact that is nowhere in the code?**
164
+
165
+ - Restates the identifier, the signature, or the line under it \u2192 delete it.
166
+ - Labels a section (\`// helpers\`, \`// state\`) or narrates a step (\`// fetch the user\`, \`// then save\`) \u2192 delete it.
167
+ - JSDoc on an ordinary function, or a why/how preamble on ordinary logic \u2192 delete it.
168
+ - Explains the edit you just made, for whoever reads the diff \u2192 say it in your reply, not in the file.
169
+ - Names a vendor or protocol quirk, an infrastructure constraint, a library gotcha, security reasoning, a math
170
+ derivation, a domain field's business meaning, a state transition, or why an obvious alternative was rejected \u2192
171
+ keep it, one line.
172
+
173
+ That keep-list is exact \u2014 \`Comments\` in the guide is the full version. "It aids readability" and "this logic is
174
+ subtle" are not on it: rename or split the code instead. When you edit an existing file, match its density; if the
175
+ surrounding code carries none, your diff carries none.`;
140
176
  var renderScopeClaudeMd = (scope) => `# ${scope.name} \u2014 Claude Code Guide
141
177
 
142
178
  @AGENTS.md
179
+
180
+ ${CLAUDE_COMMENT_RULE}
143
181
  `;
144
182
 
145
183
  // pkgs/@akanjs/devkit/akanConfig/akanConfig.ts
@@ -182,8 +220,6 @@ var DEFAULT_OPTIMIZE_IMPORTS = [
182
220
  ];
183
221
  var WORKSPACE_BARREL_FACETS = ["ui", "webkit", "common", "client", "server"];
184
222
  var SSR_RUNTIME_PACKAGES = ["react", "react-dom", "react-server-dom-webpack"];
185
- var NATIVE_RUNTIME_PACKAGES = ["sharp"];
186
- var DEFAULT_BACKEND_RUNTIME_PACKAGES = ["croner"];
187
223
  var MOBILE_RUNTIME_PACKAGES = [
188
224
  "@capacitor/cli",
189
225
  "@capacitor/core",
@@ -212,8 +248,6 @@ var DATABASE_MODE_RUNTIME_PACKAGES = {
212
248
  };
213
249
  var AKAN_RUNTIME_PACKAGES = new Set([
214
250
  ...SSR_RUNTIME_PACKAGES,
215
- ...NATIVE_RUNTIME_PACKAGES,
216
- ...DEFAULT_BACKEND_RUNTIME_PACKAGES,
217
251
  ...MOBILE_RUNTIME_PACKAGES,
218
252
  ...Object.values(DATABASE_MODE_RUNTIME_PACKAGES).flat()
219
253
  ]);
@@ -505,13 +539,7 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
505
539
  return akanPackageJson.dependencies?.[lib] ?? akanPackageJson.peerDependencies?.[lib];
506
540
  }
507
541
  #getProductionRuntimePackages() {
508
- return [
509
- ...this.externalLibs,
510
- ...SSR_RUNTIME_PACKAGES,
511
- ...NATIVE_RUNTIME_PACKAGES,
512
- ...DEFAULT_BACKEND_RUNTIME_PACKAGES,
513
- ...this.getDatabaseModeRuntimePackages()
514
- ];
542
+ return [...this.externalLibs, ...SSR_RUNTIME_PACKAGES, ...this.getDatabaseModeRuntimePackages()];
515
543
  }
516
544
  getDatabaseModeRuntimePackages(databaseMode = this.defaultDatabaseMode) {
517
545
  return [...DATABASE_MODE_RUNTIME_PACKAGES[databaseMode]];
@@ -627,42 +655,47 @@ var decreaseBuildNum = async (app) => {
627
655
  const akanConfigContent = akanConfig.replace(`buildNum: ${appConfig.mobile.buildNum}`, `buildNum: ${appConfig.mobile.buildNum - 1}`);
628
656
  fs.writeFileSync(akanConfigPath, akanConfigContent);
629
657
  };
630
- // pkgs/@akanjs/devkit/getDirname.ts
631
- import path2 from "path";
632
- import { fileURLToPath as fileURLToPath2 } from "url";
633
- var getDirname = (url) => path2.dirname(fileURLToPath2(url));
634
-
635
658
  // pkgs/@akanjs/devkit/linter.ts
636
659
  import { spawn } from "child_process";
637
660
  import { existsSync, readFileSync } from "fs";
638
- import path3 from "path";
661
+ import path2 from "path";
639
662
  import chalk from "chalk";
663
+ var BIOME_CONFIG_FILES = ["biome.json", "biome.jsonc"];
640
664
 
641
665
  class Linter {
642
666
  lintRoot;
667
+ configPath;
643
668
  #biomeBin;
644
669
  constructor(cwdPath) {
645
670
  this.lintRoot = this.#findBiomeRootPath(cwdPath);
646
- const localBiomeBin = path3.join(this.lintRoot, "node_modules/.bin/biome");
671
+ this.configPath = Linter.#configPathIn(this.lintRoot) ?? path2.join(this.lintRoot, "biome.json");
672
+ const localBiomeBin = path2.join(this.lintRoot, "node_modules/.bin/biome");
647
673
  this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
648
674
  }
675
+ static #configPathIn(dir) {
676
+ for (const fileName of BIOME_CONFIG_FILES) {
677
+ const configPath = path2.join(dir, fileName);
678
+ if (existsSync(configPath))
679
+ return configPath;
680
+ }
681
+ return null;
682
+ }
649
683
  #findBiomeRootPath(dir) {
650
- const configPath = path3.join(dir, "biome.json");
651
- if (existsSync(configPath))
684
+ if (Linter.#configPathIn(dir))
652
685
  return dir;
653
- const parentDir = path3.dirname(dir);
686
+ const parentDir = path2.dirname(dir);
654
687
  if (parentDir === dir)
655
688
  throw new Error(`biome.json not found from ${dir}`);
656
689
  return this.#findBiomeRootPath(parentDir);
657
690
  }
658
691
  #toBiomePath(filePath) {
659
- const relativePath = path3.relative(this.lintRoot, filePath);
660
- if (!relativePath.startsWith("..") && !path3.isAbsolute(relativePath))
692
+ const relativePath = path2.relative(this.lintRoot, filePath);
693
+ if (!relativePath.startsWith("..") && !path2.isAbsolute(relativePath))
661
694
  return relativePath;
662
695
  return filePath;
663
696
  }
664
697
  #resolveFilePath(filePath) {
665
- return path3.isAbsolute(filePath) ? filePath : path3.join(this.lintRoot, filePath);
698
+ return path2.isAbsolute(filePath) ? filePath : path2.join(this.lintRoot, filePath);
666
699
  }
667
700
  async#runBiome(args, input) {
668
701
  return await new Promise((resolve, reject) => {
@@ -694,7 +727,7 @@ class Linter {
694
727
  const diagnosticPath = diagnostic.location?.path;
695
728
  if (!diagnosticPath)
696
729
  return fallbackFilePath;
697
- return path3.isAbsolute(diagnosticPath) ? diagnosticPath : path3.join(this.lintRoot, diagnosticPath);
730
+ return path2.isAbsolute(diagnosticPath) ? diagnosticPath : path2.join(this.lintRoot, diagnosticPath);
698
731
  }
699
732
  #createLintMessage(diagnostic) {
700
733
  const start = diagnostic.location?.start;
@@ -759,7 +792,7 @@ class Linter {
759
792
  "--max-diagnostics=none",
760
793
  "--no-errors-on-unmatched",
761
794
  "--config-path",
762
- path3.join(this.lintRoot, "biome.json"),
795
+ this.configPath,
763
796
  this.#toBiomePath(filePath)
764
797
  ]);
765
798
  const report = this.#parseBiomeReport(stdout || stderr);
@@ -880,14 +913,7 @@ ${errorText}, ${warningText} found`];
880
913
  if (!dryRun)
881
914
  return await this.#checkFile(resolvedFilePath, { write: true });
882
915
  const source = readFileSync(resolvedFilePath, "utf8");
883
- const { stdout } = await this.#runBiome([
884
- "check",
885
- "--write",
886
- "--config-path",
887
- path3.join(this.lintRoot, "biome.json"),
888
- "--stdin-file-path",
889
- this.#toBiomePath(resolvedFilePath)
890
- ], source);
916
+ const { stdout } = await this.#runBiome(["check", "--write", "--config-path", this.configPath, "--stdin-file-path", this.#toBiomePath(resolvedFilePath)], source);
891
917
  const lintResult = await this.lintFile(resolvedFilePath);
892
918
  return { ...lintResult, fixed: stdout !== source, output: stdout };
893
919
  }
@@ -895,7 +921,7 @@ ${errorText}, ${warningText} found`];
895
921
  const resolvedFilePath = this.#resolveFilePath(filePath);
896
922
  if (!existsSync(resolvedFilePath))
897
923
  throw new Error(`File not found: ${filePath}`);
898
- return JSON.parse(readFileSync(path3.join(this.lintRoot, "biome.json"), "utf8"));
924
+ return JSON.parse(readFileSync(this.configPath, "utf8"));
899
925
  }
900
926
  async getProblematicRules(filePath) {
901
927
  const { results } = await this.lintFile(filePath);
@@ -910,22 +936,36 @@ ${errorText}, ${warningText} found`];
910
936
  }
911
937
  }
912
938
 
939
+ // pkgs/@akanjs/devkit/repoIdentity.ts
940
+ import { execFileSync } from "child_process";
941
+ import path3 from "path";
942
+ var resolved = new Map;
943
+ var readRemoteName = (workspaceRoot) => {
944
+ try {
945
+ const url = execFileSync("git", ["config", "--get", "remote.origin.url"], {
946
+ cwd: workspaceRoot,
947
+ encoding: "utf-8",
948
+ stdio: ["ignore", "pipe", "ignore"]
949
+ }).trim();
950
+ return url.replace(/\.git$/, "").split(/[/:]/).pop() || null;
951
+ } catch {
952
+ return null;
953
+ }
954
+ };
955
+ var resolveRepoName = (workspaceRoot) => {
956
+ const cached = resolved.get(workspaceRoot);
957
+ if (cached)
958
+ return cached;
959
+ const repoName = readRemoteName(workspaceRoot) ?? path3.basename(workspaceRoot);
960
+ resolved.set(workspaceRoot, repoName);
961
+ return repoName;
962
+ };
963
+
913
964
  // pkgs/@akanjs/devkit/scanInfo.ts
914
965
  import { rm } from "fs/promises";
915
966
  import path4 from "path";
916
- var databaseFileTypes = [
917
- "constant",
918
- "dictionary",
919
- "document",
920
- "service",
921
- "signal",
922
- "store",
923
- "template",
924
- "unit",
925
- "util",
926
- "view",
927
- "zone"
928
- ];
967
+
968
+ // pkgs/@akanjs/devkit/workspaceLayout.ts
929
969
  var appRootAllowedFiles = new Set([
930
970
  "AGENTS.md",
931
971
  "CLAUDE.md",
@@ -939,25 +979,25 @@ var appRootAllowedFiles = new Set([
939
979
  "tsconfig.json",
940
980
  "tsconfig.tsbuildinfo"
941
981
  ]);
942
- var generatedRootCapacitorConfigFiles = ["capacitor.config.js", "capacitor.config.json"];
943
982
  var appRootAllowedDirs = new Set([
944
983
  ".akan",
945
984
  "android",
985
+ "common",
946
986
  "env",
947
987
  "ios",
948
988
  "lib",
949
989
  "mobile",
950
990
  "page",
991
+ "plugin",
951
992
  "private",
952
993
  "public",
953
994
  "script",
954
- "ui",
995
+ "secrets",
955
996
  "srvkit",
956
- "webkit",
957
- "common",
958
- "secrets"
997
+ "ui",
998
+ "webkit"
959
999
  ]);
960
- var libRootAllowedFiles = new Set([
1000
+ var libFacetRootAllowedFiles = new Set([
961
1001
  "cnst.ts",
962
1002
  "db.ts",
963
1003
  "dict.ts",
@@ -968,6 +1008,23 @@ var libRootAllowedFiles = new Set([
968
1008
  "useClient.ts",
969
1009
  "useServer.ts"
970
1010
  ]);
1011
+ var isScannedAppRootEntry = (name) => !name.startsWith(".") || appRootAllowedDirs.has(name);
1012
+
1013
+ // pkgs/@akanjs/devkit/scanInfo.ts
1014
+ var databaseFileTypes = [
1015
+ "constant",
1016
+ "dictionary",
1017
+ "document",
1018
+ "service",
1019
+ "signal",
1020
+ "store",
1021
+ "template",
1022
+ "unit",
1023
+ "util",
1024
+ "view",
1025
+ "zone"
1026
+ ];
1027
+ var generatedRootCapacitorConfigFiles = ["capacitor.config.js", "capacitor.config.json"];
971
1028
  var internalLibDirs = new Set(["__lib", "__scalar"]);
972
1029
  var moduleNonUiFileTypes = {
973
1030
  database: new Set(["constant", "dictionary", "document", "service", "signal", "store"]),
@@ -981,9 +1038,9 @@ var moduleUiFileTypes = {
981
1038
  };
982
1039
  var testFilePattern = /\.(test|spec)\.(ts|tsx)$/;
983
1040
  var rootSignalTestFilePattern = /^[A-Za-z][A-Za-z0-9_-]*\.signal\.(test|spec)\.(ts|tsx)$/;
984
- var createDependencyScanner = async (exec) => (await import("./dependencyScanner-f6grrep3.js")).TypeScriptDependencyScanner.from(exec);
1041
+ var createDependencyScanner = async (exec) => (await import("./dependencyScanner-rbs2407b.js")).TypeScriptDependencyScanner.from(exec);
985
1042
  var isAllowedTestFile = (filename) => testFilePattern.test(filename);
986
- var isAllowedLibRootFile = (filename) => libRootAllowedFiles.has(filename) || rootSignalTestFilePattern.test(filename);
1043
+ var isAllowedLibRootFile = (filename) => libFacetRootAllowedFiles.has(filename) || rootSignalTestFilePattern.test(filename);
987
1044
  var getScanPath = (exec, relativePath) => path4.posix.join(`${exec.type}s`, exec.name, relativePath.split(path4.sep).join("/"));
988
1045
  async function clearGeneratedRootCapacitorConfigs(exec) {
989
1046
  if (exec.type !== "app")
@@ -1628,7 +1685,7 @@ class Executor {
1628
1685
  }));
1629
1686
  });
1630
1687
  proc.on("exit", (code, signal) => {
1631
- if (!!code || signal)
1688
+ if (code || signal)
1632
1689
  reject(new CommandExecutionError({
1633
1690
  command,
1634
1691
  cwd,
@@ -1726,7 +1783,7 @@ class Executor {
1726
1783
  }));
1727
1784
  });
1728
1785
  proc.on("exit", (code, signal) => {
1729
- if (!!code || signal)
1786
+ if (code || signal)
1730
1787
  reject(new CommandExecutionError({
1731
1788
  command: modulePath,
1732
1789
  args,
@@ -2022,7 +2079,7 @@ class Executor {
2022
2079
  return this._applyTemplate({ ...options, dict });
2023
2080
  }
2024
2081
  async getTypeChecker() {
2025
- const { TypeChecker } = await import("./typeChecker-kravn7ns.js");
2082
+ const { TypeChecker } = await import("./typeChecker-g6bh0xfv.js");
2026
2083
  this.typeChecker ??= new TypeChecker(this);
2027
2084
  return this.typeChecker;
2028
2085
  }
@@ -2103,7 +2160,7 @@ class WorkspaceExecutor extends Executor {
2103
2160
  static #execs = new Map;
2104
2161
  static fromRoot({
2105
2162
  workspaceRoot = process.cwd(),
2106
- repoName = path5.basename(process.cwd())
2163
+ repoName = resolveRepoName(workspaceRoot)
2107
2164
  } = {}) {
2108
2165
  return WorkspaceExecutor.#execs.get(repoName) ?? new WorkspaceExecutor({ workspaceRoot, repoName });
2109
2166
  }
@@ -2479,7 +2536,7 @@ class SysExecutor extends Executor {
2479
2536
  class AppExecutor extends SysExecutor {
2480
2537
  static #routeSourceValidator = null;
2481
2538
  static async#getRouteSourceValidator() {
2482
- AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-cncd92fv.js")).RouteSourceValidator;
2539
+ AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-7fycdqyv.js")).RouteSourceValidator;
2483
2540
  return AppExecutor.#routeSourceValidator;
2484
2541
  }
2485
2542
  dist;
@@ -2547,6 +2604,8 @@ class AppExecutor extends SysExecutor {
2547
2604
  ]);
2548
2605
  } else
2549
2606
  await this.removeDir(".akan");
2607
+ if (type === "start")
2608
+ process.env.NODE_ENV = "development";
2550
2609
  const devPort = type === "start" ? (await this.getDevPort()).toString() : undefined;
2551
2610
  const env = this.getCommandEnv({
2552
2611
  AKAN_COMMAND_TYPE: type,
@@ -2960,7 +3019,7 @@ class PkgExecutor extends Executor {
2960
3019
  default: "./index.ts"
2961
3020
  }
2962
3021
  },
2963
- engines: { bun: ">=1.3.13" },
3022
+ engines: { bun: ">=1.4.0" },
2964
3023
  ...dependencyMaps
2965
3024
  };
2966
3025
  await Promise.all([this.dist.writeJson("package.json", distPkgJson), this.writeJson("package.json", distPkgJson)]);
@@ -3003,4 +3062,4 @@ class ModuleExecutor extends Executor {
3003
3062
  }
3004
3063
  }
3005
3064
 
3006
- export { AGENT_BLOCK_START, AGENT_BLOCK_END, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, getDirname, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
3065
+ export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, appRootAllowedFiles, appRootAllowedDirs, libFacetRootAllowedFiles, isScannedAppRootEntry, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  ModuleScript
4
- } from "./index-vhv3xnjz.js";
4
+ } from "./index-mykmf6wd.js";
5
5
  import {
6
6
  addFieldUiPolicyForType,
7
7
  coerceFieldDefault,
@@ -34,15 +34,15 @@ import {
34
34
  sourceFile,
35
35
  validationCommandsForTarget,
36
36
  viaBuilderParameterName
37
- } from "./index-4zgs8g1w.js";
37
+ } from "./index-tsmjxph2.js";
38
38
  import {
39
39
  script
40
- } from "./index-jk9q6pse.js";
40
+ } from "./index-n706txcv.js";
41
41
  import {
42
42
  AppExecutor,
43
43
  LibExecutor,
44
44
  ModuleExecutor
45
- } from "./index-jtm86byd.js";
45
+ } from "./index-8vkkm7v0.js";
46
46
 
47
47
  // pkgs/@akanjs/cli/primitive/primitive.script.ts
48
48
  import { capitalize } from "akanjs/common";
@@ -1,24 +1,24 @@
1
1
  // @bun
2
2
  import {
3
3
  CloudRunner
4
- } from "./index-xj8bks3p.js";
4
+ } from "./index-t71zvmt9.js";
5
5
  import {
6
6
  PackageScript
7
- } from "./index-e3qskyt2.js";
7
+ } from "./index-33zce8gt.js";
8
8
  import {
9
9
  AiSession,
10
10
  CloudApi,
11
11
  GlobalConfig
12
- } from "./index-3pgtw35d.js";
12
+ } from "./index-sh01r3pm.js";
13
13
  import {
14
14
  ApplicationScript
15
- } from "./index-tq1y56tp.js";
15
+ } from "./index-8d2sv6pw.js";
16
16
  import {
17
17
  script
18
- } from "./index-jk9q6pse.js";
18
+ } from "./index-n706txcv.js";
19
19
  import {
20
20
  PkgExecutor
21
- } from "./index-jtm86byd.js";
21
+ } from "./index-8vkkm7v0.js";
22
22
 
23
23
  // pkgs/@akanjs/cli/cloud/cloud.script.ts
24
24
  import { Logger } from "akanjs/common";
@@ -2,11 +2,16 @@
2
2
  import {
3
3
  workflowRunArtifactPath,
4
4
  workflowSyncDir
5
- } from "./index-4zgs8g1w.js";
5
+ } from "./index-tsmjxph2.js";
6
6
  import {
7
7
  AppExecutor,
8
- LibExecutor
9
- } from "./index-jtm86byd.js";
8
+ LibExecutor,
9
+ appRootAllowedDirs,
10
+ appRootAllowedFiles,
11
+ extractBlockVersion,
12
+ isScannedAppRootEntry,
13
+ readDevkitVersion
14
+ } from "./index-8vkkm7v0.js";
10
15
  import {
11
16
  collectRecipeSources,
12
17
  findInlineRecipeDuplicates,
@@ -121,7 +126,9 @@ var validationCommands = [
121
126
  "akan typecheck <app-name>",
122
127
  "akan test <app-or-lib-or-pkg>",
123
128
  "akan build <app-name>",
124
- "akan doctor --strict --format json"
129
+ "akan doctor --strict --format json",
130
+ "akan quality scan [--format json]",
131
+ "akan quality ssr [--format json]"
125
132
  ];
126
133
  var unknownGeneratedFilesFreshness = {
127
134
  status: "unknown",
@@ -150,33 +157,6 @@ var moduleShapeFiles = (module) => {
150
157
  ];
151
158
  };
152
159
  var constantFieldNames = (content) => [...content.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*field\(/g)].map((match) => match[1]).filter(Boolean);
153
- var appRootAllowFiles = new Set([
154
- "AGENTS.md",
155
- "CLAUDE.md",
156
- "akan.app.json",
157
- "akan.config.ts",
158
- "capacitor.config.ts",
159
- "client.ts",
160
- "main.ts",
161
- "package.json",
162
- "server.ts",
163
- "tsconfig.json"
164
- ]);
165
- var appRootAllowDirs = new Set([
166
- ".akan",
167
- "android",
168
- "common",
169
- "env",
170
- "ios",
171
- "lib",
172
- "page",
173
- "private",
174
- "public",
175
- "script",
176
- "srvkit",
177
- "ui",
178
- "webkit"
179
- ]);
180
160
  var safeReadDir = async (dirPath) => {
181
161
  try {
182
162
  return (await readdir(dirPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
@@ -389,6 +369,29 @@ class AkanContextAnalyzer {
389
369
  validationCommands
390
370
  };
391
371
  }
372
+ static async#agentGuideDrift(workspace) {
373
+ const installed = await readDevkitVersion();
374
+ if (!installed)
375
+ return null;
376
+ const content = await safeReadText(path.join(workspace.workspaceRoot, "AGENTS.md"));
377
+ if (content === null)
378
+ return null;
379
+ const stamped = extractBlockVersion(content);
380
+ if (stamped === installed)
381
+ return null;
382
+ const hint = "Re-render the AGENTS.md managed block from the installed framework release.";
383
+ if (!stamped)
384
+ return {
385
+ code: "agent-guide-unstamped",
386
+ message: `AGENTS.md carries no generated-version stamp, so its conventions may predate @akanjs/devkit ${installed}`,
387
+ hint
388
+ };
389
+ return {
390
+ code: "agent-guide-stale",
391
+ message: `AGENTS.md was generated by @akanjs/devkit ${stamped}, but ${installed} is installed`,
392
+ hint
393
+ };
394
+ }
392
395
  static async doctor(workspace, {
393
396
  strict = false,
394
397
  runIdOrPlan = null,
@@ -404,7 +407,9 @@ class AkanContextAnalyzer {
404
407
  for (const app of context.apps) {
405
408
  const appPath = path.join(workspace.workspaceRoot, app.path);
406
409
  for (const entry of await safeReadDir(appPath)) {
407
- const allowed = entry.isDirectory() ? appRootAllowDirs.has(entry.name) : appRootAllowFiles.has(entry.name);
410
+ if (!isScannedAppRootEntry(entry.name))
411
+ continue;
412
+ const allowed = entry.isDirectory() ? appRootAllowedDirs.has(entry.name) : appRootAllowedFiles.has(entry.name);
408
413
  if (!allowed) {
409
414
  const action = repairAction("module-shape", `akan repair module-shape --app ${app.name}`, "Review app root shape and remove or move the unknown entry.", false);
410
415
  diagnostics.push({
@@ -418,6 +423,18 @@ class AkanContextAnalyzer {
418
423
  }
419
424
  }
420
425
  }
426
+ const agentDrift = await AkanContextAnalyzer.#agentGuideDrift(workspace);
427
+ if (agentDrift) {
428
+ const action = repairAction("generated", "akan agent install agents-md", agentDrift.hint, true);
429
+ diagnostics.push({
430
+ severity: "warning",
431
+ code: agentDrift.code,
432
+ path: "AGENTS.md",
433
+ message: agentDrift.message,
434
+ repairActions: [action]
435
+ });
436
+ repairActions.push(action);
437
+ }
421
438
  for (const sys of [...context.apps, ...context.libs]) {
422
439
  for (const module of sys.modules) {
423
440
  if (!module.abstract.exists) {