@akanjs/cli 2.4.2-rc.3 → 3.0.0-alpha.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 (79) hide show
  1. package/.build-stamp +1 -1
  2. package/{abstractCompactor-ghh1q9an.js → abstractCompactor-rk6twzvj.js} +4 -4
  3. package/{agent.command-de4r6vk8.js → agent.command-jfz8yfwy.js} +8 -7
  4. package/{application.command-nfsfm96y.js → application.command-3smsv7mq.js} +5 -5
  5. package/{applicationBuildRunner-554a2vnk.js → applicationBuildRunner-aq7mb3z6.js} +2 -1
  6. package/buildBatch.proc.js +7 -6
  7. package/{capacitorApp-yg9b4ajz.js → capacitorApp-q3mpmkkz.js} +3 -3
  8. package/{cloud.command-1qf95x67.js → cloud.command-rk4e9vrt.js} +10 -10
  9. package/{context.command-hhjyjtp7.js → context.command-ygzyb0xb.js} +16 -15
  10. package/{guideline.command-vj956kfr.js → guideline.command-1m1ctar3.js} +10 -10
  11. package/guidelines/componentRule/componentRule.instruction.md +2 -2
  12. package/guidelines/cssRule/cssRule.generate.json +1 -1
  13. package/guidelines/cssRule/cssRule.instruction.md +57 -34
  14. package/guidelines/framework/framework.instruction.md +1 -1
  15. package/guidelines/recipeRule/recipeRule.generate.json +31 -0
  16. package/guidelines/recipeRule/recipeRule.instruction.md +72 -0
  17. package/incrementalBuilder.proc.js +5 -5
  18. package/{index-v9jqrdd1.js → index-4yp06pn1.js} +100 -2
  19. package/{index-pfnh87f9.js → index-4zgs8g1w.js} +1 -1
  20. package/{index-7ppn9v4n.js → index-b978vs2e.js} +3 -3
  21. package/{index-s9s0n5fz.js → index-cn24dcqn.js} +2 -2
  22. package/{index-h971erkm.js → index-csqk9z5j.js} +3 -3
  23. package/{index-z36qzgzp.js → index-e3qskyt2.js} +3 -4
  24. package/{index-fbv96xaw.js → index-ev6rjw9n.js} +11 -11
  25. package/{index-h6eav7zx.js → index-f4gqk0dd.js} +6 -6
  26. package/{index-z5v766nx.js → index-fmgbwsr5.js} +6 -6
  27. package/{index-y1e79mz3.js → index-h0bngh79.js} +13 -13
  28. package/{index-dgeaqwmw.js → index-hjzr8ja1.js} +1 -1
  29. package/{index-d0h48d2f.js → index-jk9q6pse.js} +1 -1
  30. package/{index-xwfg9bam.js → index-jtm86byd.js} +120 -4
  31. package/{index-h5cvg9z9.js → index-ktprgc5g.js} +4 -4
  32. package/{index-zn9rh7sh.js → index-n0z3f2xg.js} +73 -24
  33. package/{index-7k9sj7j5.js → index-pyt2b4nw.js} +212 -0
  34. package/{index-acwxfncv.js → index-r4w8cry5.js} +4 -4
  35. package/{index-zfp1gz9f.js → index-sggm9qkv.js} +1 -1
  36. package/{index-04as43rp.js → index-vhv3xnjz.js} +16 -15
  37. package/index-xjd3rqzj.js +129 -0
  38. package/{index-xftstr5s.js → index-xwgm94zr.js} +1 -1
  39. package/index-xys926f2.js +136 -0
  40. package/index.js +19 -19
  41. package/{library.command-68ah07a3.js → library.command-pwfx8dx2.js} +4 -4
  42. package/{localRegistry.command-84dz000g.js → localRegistry.command-bxhqmd1d.js} +9 -9
  43. package/{module.command-t68xhamx.js → module.command-0t3ewata.js} +8 -8
  44. package/{package.command-00ncttab.js → package.command-7hmkxvpa.js} +4 -4
  45. package/package.json +2 -3
  46. package/{page.command-1096s18n.js → page.command-st6r4s0q.js} +4 -4
  47. package/{primitive.command-02eqpx6t.js → primitive.command-1qkxpzsn.js} +9 -9
  48. package/{quality.command-r9cageqb.js → quality.command-hy5vt1bh.js} +3 -3
  49. package/recipeScanner-tghkzrrt.js +12 -0
  50. package/{repair.command-7dynpnf1.js → repair.command-nakkq2zp.js} +7 -6
  51. package/{scalar.command-3kxy3fkh.js → scalar.command-fjq272gs.js} +7 -7
  52. package/templates/app/page/_index.tsx +55 -52
  53. package/templates/app/page/styles.css.template +12 -71
  54. package/templates/appSample/lib/task/Task.Template.tsx +2 -2
  55. package/templates/appSample/lib/task/Task.Unit.tsx +11 -11
  56. package/templates/appSample/lib/task/Task.Util.tsx +27 -28
  57. package/templates/appSample/lib/task/Task.View.tsx +22 -19
  58. package/templates/appSample/lib/task/Task.Zone.tsx +3 -3
  59. package/templates/appSample/page/task/[taskId]/_index.tsx +3 -3
  60. package/templates/appSample/page/task/[taskId]/edit.tsx +5 -5
  61. package/templates/appSample/page/task/_index.tsx +4 -4
  62. package/templates/appSample/page/task/_layout.tsx +1 -1
  63. package/templates/appSample/page/task/new.tsx +5 -5
  64. package/templates/appSample/ui/GlobalLoading.tsx +4 -4
  65. package/templates/appSample/ui/QuantityControl.tsx +5 -4
  66. package/templates/crudPages/[__model__Id]/page.tsx +1 -1
  67. package/templates/crudPages/page.tsx +1 -1
  68. package/templates/crudSinglePage/page.tsx +1 -1
  69. package/templates/module/__Model__.Template.tsx +2 -1
  70. package/templates/module/__Model__.Unit.tsx +2 -1
  71. package/templates/module/__Model__.Util.tsx +2 -1
  72. package/templates/module/__Model__.View.tsx +4 -3
  73. package/templates/module/__Model__.Zone.tsx +2 -1
  74. package/templates/workspaceRoot/AGENTS.md.template +11 -13
  75. package/templates/workspaceRoot/biome.json.template +1 -1
  76. package/{workflow.command-yy0d9gk3.js → workflow.command-jswbgk90.js} +15 -14
  77. package/{workspace.command-stv9g4a0.js → workspace.command-p9r9nckg.js} +87 -27
  78. package/{applicationReleasePackager-pjbxc793.js → applicationReleasePackager-yrrhbkv3.js} +3 -3
  79. package/{index-nsj2ftxj.js → index-3pgtw35d.js} +3 -3
@@ -2,11 +2,16 @@
2
2
  import {
3
3
  workflowRunArtifactPath,
4
4
  workflowSyncDir
5
- } from "./index-pfnh87f9.js";
5
+ } from "./index-4zgs8g1w.js";
6
6
  import {
7
7
  AppExecutor,
8
8
  LibExecutor
9
- } from "./index-xwfg9bam.js";
9
+ } from "./index-jtm86byd.js";
10
+ import {
11
+ collectRecipeSources,
12
+ findInlineRecipeDuplicates,
13
+ scanRecipes
14
+ } from "./index-xys926f2.js";
10
15
  import {
11
16
  FileSys
12
17
  } from "./index-67546d0j.js";
@@ -146,6 +151,8 @@ var moduleShapeFiles = (module) => {
146
151
  };
147
152
  var constantFieldNames = (content) => [...content.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*field\(/g)].map((match) => match[1]).filter(Boolean);
148
153
  var appRootAllowFiles = new Set([
154
+ "AGENTS.md",
155
+ "CLAUDE.md",
149
156
  "akan.app.json",
150
157
  "akan.config.ts",
151
158
  "capacitor.config.ts",
@@ -461,6 +468,97 @@ class AkanContextAnalyzer {
461
468
  }
462
469
  }
463
470
  }
471
+ for (const sys of [...context.apps, ...context.libs]) {
472
+ const sources = await collectRecipeSources(path.join(workspace.workspaceRoot, sys.path, "ui"), "ui");
473
+ if (sources.length === 0)
474
+ continue;
475
+ const recipes = scanRecipes(sources);
476
+ const files = [];
477
+ const glob = new Bun.Glob("**/*.tsx");
478
+ for await (const abs of glob.scan({ cwd: path.join(workspace.workspaceRoot, sys.path), absolute: true })) {
479
+ if (/[\\/](node_modules|\.akan|dist)[\\/]|[\\/]v1[\\/]/.test(abs) || /\.(test|spec)\.tsx$/.test(abs))
480
+ continue;
481
+ files.push({
482
+ path: abs,
483
+ content: await Bun.file(abs).text().catch(() => "")
484
+ });
485
+ }
486
+ const duplicates = findInlineRecipeDuplicates(recipes, files);
487
+ if (duplicates.length === 0)
488
+ continue;
489
+ const preview = duplicates.slice(0, 3).map((duplicate) => `${path.relative(workspace.workspaceRoot, duplicate.path)}:${duplicate.line}`).join(", ");
490
+ diagnostics.push({
491
+ severity: "warning",
492
+ code: "recipe-inline-duplicate",
493
+ path: path.join(sys.path, "ui/Recipe"),
494
+ message: `${sys.name}: ${duplicates.length} inline className(s) re-author a recipe fingerprint (${preview}${duplicates.length > 3 ? ", \u2026" : ""}) \u2014 consume the recipe instead.`
495
+ });
496
+ }
497
+ const scanNames = async (uiDirPath, basename) => new Set(scanRecipes(await collectRecipeSources(uiDirPath, "ui", basename)).map((info) => info.name));
498
+ const declaredByImport = new Map;
499
+ declaredByImport.set("akanjs/ui", await scanNames(path.join(workspace.workspaceRoot, "pkgs/akanjs/ui"), "recipe"));
500
+ for (const sys of [...context.apps, ...context.libs])
501
+ declaredByImport.set(`@${sys.path}/ui`, await scanNames(path.join(workspace.workspaceRoot, sys.path, "ui")));
502
+ const sectionOf = (content, heading) => {
503
+ const match = new RegExp(`^${heading}$`, "m").exec(content);
504
+ if (!match)
505
+ return "";
506
+ const section = content.slice(match.index);
507
+ const sectionEnd = section.indexOf(`
508
+ ## `, 1);
509
+ return sectionEnd === -1 ? section : section.slice(0, sectionEnd);
510
+ };
511
+ const listedByImport = (body) => {
512
+ const groups = new Map;
513
+ let current = null;
514
+ for (const line of body.split(`
515
+ `)) {
516
+ const group = /^Import from `([^`]+)`:/.exec(line);
517
+ if (group) {
518
+ current = groups.get(group[1]) ?? new Set;
519
+ groups.set(group[1], current);
520
+ continue;
521
+ }
522
+ const item = /^- `([A-Za-z0-9_$]+)`/.exec(line);
523
+ if (item && current)
524
+ current.add(item[1]);
525
+ else if (!item)
526
+ current = null;
527
+ }
528
+ return groups;
529
+ };
530
+ const pushIndexDiagnostic = (indexPath, missing, stale, repairCommand) => {
531
+ if (missing.length === 0 && stale.length === 0)
532
+ return;
533
+ const action = repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true);
534
+ const parts = [
535
+ missing.length > 0 ? `${missing.length} declared but unlisted (${missing.slice(0, 5).join(", ")})` : "",
536
+ stale.length > 0 ? `${stale.length} listed but gone (${stale.slice(0, 5).join(", ")})` : ""
537
+ ].filter(Boolean);
538
+ diagnostics.push({
539
+ severity: "error",
540
+ code: "recipe-index-stale",
541
+ path: indexPath,
542
+ message: `${indexPath} recipe index is out of date \u2014 ${parts.join("; ")}. Agents read this list as authoritative.`,
543
+ repairActions: [action]
544
+ });
545
+ repairActions.push(action);
546
+ };
547
+ const frameworkDeclared = declaredByImport.get("akanjs/ui") ?? new Set;
548
+ if (frameworkDeclared.size > 0) {
549
+ const agentsMd = await Bun.file(path.join(workspace.workspaceRoot, "AGENTS.md")).text().catch(() => "");
550
+ const listed = listedByImport(sectionOf(agentsMd, "## Recipes")).get("akanjs/ui") ?? new Set;
551
+ pushIndexDiagnostic("AGENTS.md", [...frameworkDeclared].filter((name) => !listed.has(name)).sort(), [...listed].filter((name) => !frameworkDeclared.has(name)).sort(), "akan agent install agents-md");
552
+ }
553
+ for (const sys of [...context.apps, ...context.libs]) {
554
+ const own = declaredByImport.get(`@${sys.path}/ui`) ?? new Set;
555
+ const scopeMd = await Bun.file(path.join(workspace.workspaceRoot, sys.path, "AGENTS.md")).text().catch(() => "");
556
+ const groups = listedByImport(sectionOf(scopeMd, "## Recipes In Scope"));
557
+ const ownListed = groups.get(`@${sys.path}/ui`) ?? new Set;
558
+ const missing = [...own].filter((name) => !ownListed.has(name)).sort();
559
+ const stale = [...groups.entries()].flatMap(([importFrom, names]) => [...names].filter((name) => !(declaredByImport.get(importFrom) ?? new Set).has(name))).sort();
560
+ pushIndexDiagnostic(`${sys.path}/AGENTS.md`, missing, stale, `akan sync ${sys.name}`);
561
+ }
464
562
  const scopedDiagnostics = diagnostics.map((diagnostic) => ({
465
563
  ...diagnostic,
466
564
  scope: workflowPaths.length ? isWorkflowRelatedDiagnostic(diagnostic, workflowPaths) ? "workflow" : "baseline" : diagnostic.scope,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-xwfg9bam.js";
5
+ } from "./index-jtm86byd.js";
6
6
 
7
7
  // pkgs/@akanjs/devkit/workflow/utils.ts
8
8
  var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `
@@ -1,17 +1,17 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-v9jqrdd1.js";
4
+ } from "./index-4yp06pn1.js";
5
5
  import {
6
6
  createRepairReport,
7
7
  generatedFilePathsForTarget,
8
8
  renderRepairReport,
9
9
  writeGeneratedSyncState,
10
10
  writeWorkflowRunArtifact
11
- } from "./index-pfnh87f9.js";
11
+ } from "./index-4zgs8g1w.js";
12
12
  import {
13
13
  runner
14
- } from "./index-d0h48d2f.js";
14
+ } from "./index-jk9q6pse.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/repair/repair.runner.ts
17
17
  var commandForShell = (command) => command.startsWith("akan ") ? `bun run ${command}` : command;
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-d0h48d2f.js";
5
+ } from "./index-jk9q6pse.js";
6
6
  import {
7
7
  LibExecutor
8
- } from "./index-xwfg9bam.js";
8
+ } from "./index-jtm86byd.js";
9
9
 
10
10
  // pkgs/@akanjs/cli/semver.ts
11
11
  function parseVersion(version) {
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-v9jqrdd1.js";
4
+ } from "./index-4yp06pn1.js";
5
5
  import {
6
6
  WorkflowExecutor,
7
7
  compactWorkflowInputs,
@@ -23,10 +23,10 @@ import {
23
23
  workflowCommandsForPlan,
24
24
  workflowPlanApproval,
25
25
  writeWorkflowRunArtifact
26
- } from "./index-pfnh87f9.js";
26
+ } from "./index-4zgs8g1w.js";
27
27
  import {
28
28
  runner
29
- } from "./index-d0h48d2f.js";
29
+ } from "./index-jk9q6pse.js";
30
30
 
31
31
  // pkgs/@akanjs/cli/workflow/workflow.runner.ts
32
32
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-d0h48d2f.js";
5
+ } from "./index-jk9q6pse.js";
6
6
  import {
7
7
  PkgExecutor
8
- } from "./index-xwfg9bam.js";
8
+ } from "./index-jtm86byd.js";
9
9
  import {
10
10
  TypeScriptDependencyScanner
11
11
  } from "./index-46tjzh6s.js";
@@ -153,14 +153,13 @@ class PackageRunner extends runner("package") {
153
153
  const scanner = await TypeScriptDependencyScanner.from(pkg);
154
154
  const { npmDeps, npmDevDeps, missingDeps } = await scanner.getPackageBuildDependencies(pkg.name);
155
155
  const packageRuntimeDependencies = {
156
- "@akanjs/devkit": ["daisyui", "tailwind-scrollbar"]
156
+ "@akanjs/devkit": ["tailwind-scrollbar"]
157
157
  };
158
158
  const packageRuntimeDevDependencies = { akanjs: ["@biomejs/biome", "@types/bun"] };
159
159
  if (pkg.name === "@akanjs/cli") {
160
160
  const devkitPackageJson = await pkg.workspace.readJson("pkgs/@akanjs/devkit/package.json");
161
161
  packageRuntimeDependencies[pkg.name] = [
162
162
  ...Object.keys(devkitPackageJson.dependencies ?? {}),
163
- "daisyui",
164
163
  "tailwind-scrollbar"
165
164
  ].filter((dep) => dep !== "akanjs" && dep !== "@akanjs/devkit");
166
165
  }
@@ -4,21 +4,21 @@ import {
4
4
  } from "./index-76rn3g2c.js";
5
5
  import {
6
6
  LibraryScript
7
- } from "./index-s9s0n5fz.js";
7
+ } from "./index-cn24dcqn.js";
8
8
  import {
9
9
  runner,
10
10
  script
11
- } from "./index-d0h48d2f.js";
11
+ } from "./index-jk9q6pse.js";
12
+ import {
13
+ HmrWatcher,
14
+ WatchRootResolver
15
+ } from "./index-bjpxzr6s.js";
12
16
  import {
13
17
  AppExecutor,
14
18
  LibExecutor,
15
19
  PkgExecutor,
16
20
  WorkspaceExecutor
17
- } from "./index-xwfg9bam.js";
18
- import {
19
- HmrWatcher,
20
- WatchRootResolver
21
- } from "./index-bjpxzr6s.js";
21
+ } from "./index-jtm86byd.js";
22
22
  import {
23
23
  __require
24
24
  } from "./index-r24hmh0q.js";
@@ -1898,10 +1898,10 @@ function openBrowser(url) {
1898
1898
  }
1899
1899
 
1900
1900
  // pkgs/@akanjs/cli/application/application.runner.ts
1901
- var loadBuildRunner = async () => (await import("./applicationBuildRunner-554a2vnk.js")).ApplicationBuildRunner;
1902
- var loadReleasePackager = async () => (await import("./applicationReleasePackager-pjbxc793.js")).ApplicationReleasePackager;
1903
- var loadCapacitorApp = async () => (await import("./capacitorApp-yg9b4ajz.js")).CapacitorApp;
1904
- var loadAbstractCompactor = async () => (await import("./abstractCompactor-ghh1q9an.js")).AbstractCompactor;
1901
+ var loadBuildRunner = async () => (await import("./applicationBuildRunner-aq7mb3z6.js")).ApplicationBuildRunner;
1902
+ var loadReleasePackager = async () => (await import("./applicationReleasePackager-yrrhbkv3.js")).ApplicationReleasePackager;
1903
+ var loadCapacitorApp = async () => (await import("./capacitorApp-q3mpmkkz.js")).CapacitorApp;
1904
+ var loadAbstractCompactor = async () => (await import("./abstractCompactor-rk6twzvj.js")).AbstractCompactor;
1905
1905
  var loadPrompts = async () => await import("@inquirer/prompts");
1906
1906
 
1907
1907
  class ApplicationRunner extends runner("application") {
@@ -1,24 +1,24 @@
1
1
  // @bun
2
2
  import {
3
3
  CloudRunner
4
- } from "./index-h5cvg9z9.js";
4
+ } from "./index-ktprgc5g.js";
5
5
  import {
6
6
  PackageScript
7
- } from "./index-z36qzgzp.js";
7
+ } from "./index-e3qskyt2.js";
8
8
  import {
9
9
  AiSession,
10
10
  CloudApi,
11
11
  GlobalConfig
12
- } from "./index-nsj2ftxj.js";
12
+ } from "./index-3pgtw35d.js";
13
13
  import {
14
14
  ApplicationScript
15
- } from "./index-fbv96xaw.js";
15
+ } from "./index-ev6rjw9n.js";
16
16
  import {
17
17
  script
18
- } from "./index-d0h48d2f.js";
18
+ } from "./index-jk9q6pse.js";
19
19
  import {
20
20
  PkgExecutor
21
- } from "./index-xwfg9bam.js";
21
+ } from "./index-jtm86byd.js";
22
22
 
23
23
  // pkgs/@akanjs/cli/cloud/cloud.script.ts
24
24
  import { Logger } from "akanjs/common";
@@ -2,21 +2,21 @@
2
2
  import {
3
3
  pluralizeName
4
4
  } from "./index-ss469dec.js";
5
+ import {
6
+ AiSession
7
+ } from "./index-3pgtw35d.js";
5
8
  import {
6
9
  createPassedPrimitiveReport,
7
10
  generatedFilesForSync,
8
11
  scalarChangedFiles
9
- } from "./index-pfnh87f9.js";
12
+ } from "./index-4zgs8g1w.js";
10
13
  import {
11
14
  Prompter
12
- } from "./index-xftstr5s.js";
13
- import {
14
- AiSession
15
- } from "./index-nsj2ftxj.js";
15
+ } from "./index-xwgm94zr.js";
16
16
  import {
17
17
  runner,
18
18
  script
19
- } from "./index-d0h48d2f.js";
19
+ } from "./index-jk9q6pse.js";
20
20
 
21
21
  // pkgs/@akanjs/cli/scalar/scalar.prompt.ts
22
22
  import { input } from "@inquirer/prompts";
@@ -1,22 +1,22 @@
1
1
  // @bun
2
2
  import {
3
3
  RepairRunner
4
- } from "./index-7ppn9v4n.js";
4
+ } from "./index-b978vs2e.js";
5
5
  import {
6
6
  WorkflowRunner
7
- } from "./index-h971erkm.js";
8
- import {
9
- ScalarScript
10
- } from "./index-z5v766nx.js";
7
+ } from "./index-csqk9z5j.js";
11
8
  import {
12
9
  PrimitiveScript
13
- } from "./index-acwxfncv.js";
10
+ } from "./index-r4w8cry5.js";
14
11
  import {
15
12
  ModuleScript
16
- } from "./index-04as43rp.js";
13
+ } from "./index-vhv3xnjz.js";
14
+ import {
15
+ ScalarScript
16
+ } from "./index-fmgbwsr5.js";
17
17
  import {
18
18
  isPlaceholderAppId
19
- } from "./index-zfp1gz9f.js";
19
+ } from "./index-sggm9qkv.js";
20
20
  import {
21
21
  AkanContextAnalyzer,
22
22
  akanMcpInstallConfigPaths,
@@ -27,17 +27,17 @@ import {
27
27
  renderDoctorText,
28
28
  resourceList,
29
29
  upsertCodexMcpServerBlock
30
- } from "./index-v9jqrdd1.js";
30
+ } from "./index-4yp06pn1.js";
31
31
  import {
32
32
  buildAkanModuleContextIndex,
33
33
  createWorkflowBaselineSummary,
34
34
  createWorkflowStepRegistry,
35
35
  jsonText,
36
36
  toolingRolloutGate
37
- } from "./index-pfnh87f9.js";
37
+ } from "./index-4zgs8g1w.js";
38
38
  import {
39
39
  Prompter
40
- } from "./index-xftstr5s.js";
40
+ } from "./index-xwgm94zr.js";
41
41
  import {
42
42
  getMobileTargets
43
43
  } from "./index-76rn3g2c.js";
@@ -45,10 +45,10 @@ import {
45
45
  CommandContainer,
46
46
  runner,
47
47
  script
48
- } from "./index-d0h48d2f.js";
48
+ } from "./index-jk9q6pse.js";
49
49
  import {
50
50
  AppExecutor
51
- } from "./index-xwfg9bam.js";
51
+ } from "./index-jtm86byd.js";
52
52
 
53
53
  // pkgs/@akanjs/cli/context/context.script.ts
54
54
  import { Logger } from "akanjs/common";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-d0h48d2f.js";
5
+ } from "./index-jk9q6pse.js";
6
6
 
7
7
  // pkgs/@akanjs/cli/page/page.runner.ts
8
8
  class PageRunner extends runner("page") {
@@ -7,7 +7,7 @@ import {
7
7
  PkgExecutor,
8
8
  WorkspaceExecutor,
9
9
  getDirname
10
- } from "./index-xwfg9bam.js";
10
+ } from "./index-jtm86byd.js";
11
11
  import {
12
12
  FileSys
13
13
  } from "./index-67546d0j.js";
@@ -1,10 +1,10 @@
1
1
  // @bun
2
- import {
3
- FileSys
4
- } from "./index-67546d0j.js";
5
2
  import {
6
3
  Spinner
7
4
  } from "./index-6pz1j0zj.js";
5
+ import {
6
+ FileSys
7
+ } from "./index-67546d0j.js";
8
8
  import {
9
9
  __require
10
10
  } from "./index-r24hmh0q.js";
@@ -39,6 +39,109 @@ import {
39
39
  var {$ } = globalThis.Bun;
40
40
  import chalk2 from "chalk";
41
41
 
42
+ // pkgs/@akanjs/devkit/agentsIndex.ts
43
+ var recipeScannerLoad = null;
44
+ var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-tghkzrrt.js");
45
+ var AGENT_BLOCK_START = "<!-- akan:agent:start -->";
46
+ var AGENT_BLOCK_END = "<!-- akan:agent:end -->";
47
+ var upsertAgentBlock = (existing, block) => {
48
+ const managed = `${AGENT_BLOCK_START}
49
+ ${block}
50
+ ${AGENT_BLOCK_END}`;
51
+ const startIndex = existing.indexOf(AGENT_BLOCK_START);
52
+ const endIndex = existing.indexOf(AGENT_BLOCK_END);
53
+ if (startIndex >= 0 && endIndex > startIndex) {
54
+ return `${existing.slice(0, startIndex)}${managed}${existing.slice(endIndex + AGENT_BLOCK_END.length)}`;
55
+ }
56
+ return `${existing.replace(/\s*$/, "")}
57
+
58
+ ${managed}
59
+ `;
60
+ };
61
+ var extractAgentBlock = (content) => {
62
+ const startIndex = content.indexOf(AGENT_BLOCK_START);
63
+ const endIndex = content.indexOf(AGENT_BLOCK_END);
64
+ if (startIndex < 0 || endIndex <= startIndex)
65
+ return null;
66
+ return content.slice(startIndex + AGENT_BLOCK_START.length, endIndex).trim();
67
+ };
68
+ var signatureOf = (recipe) => {
69
+ const entries = Object.entries(recipe.variants);
70
+ if (entries.length === 0)
71
+ return "";
72
+ const parts = entries.map(([key, values]) => {
73
+ if (values.length === 1 && values[0] === "true")
74
+ return `${key}?`;
75
+ const def = recipe.defaultVariants?.[key];
76
+ return `${key}: ${values.map((value) => value === def ? `${value}*` : value).join("|")}`;
77
+ });
78
+ return `(${parts.join(" \xB7 ")})`;
79
+ };
80
+ var renderRecipeEntries = (recipes) => {
81
+ const groups = new Map;
82
+ for (const recipe of recipes)
83
+ groups.set(recipe.importFrom, [...groups.get(recipe.importFrom) ?? [], recipe]);
84
+ return [...groups.entries()].map(([importFrom, list]) => {
85
+ const items = list.sort((a, b) => a.name.localeCompare(b.name)).map((recipe) => `- \`${recipe.name}\`${signatureOf(recipe)}${recipe.doc ? ` \u2014 ${recipe.doc}` : ""}`).join(`
86
+ `);
87
+ return `Import from \`${importFrom}\`:
88
+ ${items}`;
89
+ }).join(`
90
+
91
+ `);
92
+ };
93
+ var collectScopeRecipeSources = async (workspaceRoot, scope, libDeps) => {
94
+ const { collectRecipeSources } = await loadRecipeScanner();
95
+ const sources = [
96
+ ...await collectRecipeSources(`${workspaceRoot}/${scope.type}s/${scope.name}/ui`, `@${scope.type}s/${scope.name}/ui`)
97
+ ];
98
+ for (const lib of [...new Set(libDeps)].sort()) {
99
+ if (scope.type === "lib" && lib === scope.name)
100
+ continue;
101
+ sources.push(...await collectRecipeSources(`${workspaceRoot}/libs/${lib}/ui`, `@libs/${lib}/ui`));
102
+ }
103
+ return sources;
104
+ };
105
+ var scanScopeRecipes = async (workspaceRoot, scope, libDeps) => {
106
+ const { scanRecipes } = await loadRecipeScanner();
107
+ return scanRecipes(await collectScopeRecipeSources(workspaceRoot, scope, libDeps));
108
+ };
109
+ var renderScopeAgentBlock = (scope, recipes) => {
110
+ const scopePath = `${scope.type}s/${scope.name}`;
111
+ const intro = `## Recipes In Scope
112
+
113
+ UI recipes importable from \`${scopePath}\` code, **in addition to** the framework recipes indexed in the root
114
+ \`AGENTS.md\` \`## Recipes\`. Same contract: import by exact name, then \`<name>(variants?, className?)\` \u2014 the second
115
+ arg merges internally and takes an array too, so never wrap it in \`cn()\`. \`*\` marks the default, \`key?\` is a
116
+ boolean flag. Do not guess recipe names or import paths; this index is regenerated by \`akan sync ${scope.name}\`
117
+ and verified by \`akan lint ${scope.name}\`.`;
118
+ if (recipes.length === 0) {
119
+ return `${intro}
120
+
121
+ No scope recipes yet. Before inlining a repeated surface (card, box, tile, \u2026), reuse a framework recipe from the
122
+ root \`AGENTS.md\` or author one as \`${scopePath}/ui/Recipe/<name>.ts\` (one recipe per file, re-exported from that
123
+ folder's \`index.ts\`) \u2014 see the \`recipeRule\` guideline.`;
124
+ }
125
+ return `${intro}
126
+
127
+ ${renderRecipeEntries(recipes)}`;
128
+ };
129
+ var renderScopeAgentsMd = (scope, block) => `# ${scope.name} \u2014 Agent Guide
130
+
131
+ Scoped guide for coding agents working in \`${scope.type}s/${scope.name}\`. Workspace-wide conventions live in the
132
+ root \`AGENTS.md\`; this file carries what is importable from this ${scope.type === "app" ? "app" : "library"}. The
133
+ section between the \`akan:agent\` markers is regenerated by \`akan sync ${scope.name}\`; edit anything outside the
134
+ markers freely.
135
+
136
+ ${AGENT_BLOCK_START}
137
+ ${block}
138
+ ${AGENT_BLOCK_END}
139
+ `;
140
+ var renderScopeClaudeMd = (scope) => `# ${scope.name} \u2014 Claude Code Guide
141
+
142
+ @AGENTS.md
143
+ `;
144
+
42
145
  // pkgs/@akanjs/devkit/akanConfig/akanConfig.ts
43
146
  import fs from "fs";
44
147
  import path from "path";
@@ -824,6 +927,8 @@ var databaseFileTypes = [
824
927
  "zone"
825
928
  ];
826
929
  var appRootAllowedFiles = new Set([
930
+ "AGENTS.md",
931
+ "CLAUDE.md",
827
932
  "akan.app.json",
828
933
  "akan.config.ts",
829
934
  "capacitor.config.ts",
@@ -2252,10 +2357,21 @@ class SysExecutor extends Executor {
2252
2357
  await this.#updateDependencies(scanInfo);
2253
2358
  await Promise.all(libInfos.flatMap((libInfo) => libInfo.exec.#getScanTemplateTasks(libInfo)));
2254
2359
  }
2360
+ await this.syncAgentsIndex(scanInfo);
2255
2361
  }
2256
2362
  this.#scanInfo = scanInfo;
2257
2363
  return scanInfo;
2258
2364
  }
2365
+ async syncAgentsIndex(scanInfo) {
2366
+ const info = scanInfo ?? await this.scan({ write: false });
2367
+ const scope = { type: this.type, name: this.name };
2368
+ const recipes = await scanScopeRecipes(this.workspace.workspaceRoot, scope, info.getScanResult().libDeps);
2369
+ const block = renderScopeAgentBlock(scope, recipes);
2370
+ const existing = await this.exists("AGENTS.md") ? await this.readFile("AGENTS.md") : null;
2371
+ await this.writeFile("AGENTS.md", existing?.trim() ? upsertAgentBlock(existing, block) : renderScopeAgentsMd(scope, block));
2372
+ if (!await this.exists("CLAUDE.md"))
2373
+ await this.writeFile("CLAUDE.md", renderScopeClaudeMd(scope));
2374
+ }
2259
2375
  async#updateDependencies(scanInfo) {
2260
2376
  const rootPackageJson = await this.workspace.getPackageJson();
2261
2377
  const libPackageJson = await this.getPackageJson();
@@ -2887,4 +3003,4 @@ class ModuleExecutor extends Executor {
2887
3003
  }
2888
3004
  }
2889
3005
 
2890
- export { getDirname, CommandExecutionError, Executor, WorkspaceExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
3006
+ export { AGENT_BLOCK_START, AGENT_BLOCK_END, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, getDirname, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
@@ -4,17 +4,17 @@ import {
4
4
  CloudApi,
5
5
  GlobalConfig,
6
6
  getDefaultHostConfig
7
- } from "./index-nsj2ftxj.js";
7
+ } from "./index-3pgtw35d.js";
8
8
  import {
9
9
  openBrowser
10
- } from "./index-fbv96xaw.js";
10
+ } from "./index-ev6rjw9n.js";
11
11
  import {
12
12
  runner
13
- } from "./index-d0h48d2f.js";
13
+ } from "./index-jk9q6pse.js";
14
14
  import {
15
15
  AppExecutor,
16
16
  WorkspaceExecutor
17
- } from "./index-xwfg9bam.js";
17
+ } from "./index-jtm86byd.js";
18
18
 
19
19
  // pkgs/@akanjs/cli/cloud/cloud.runner.ts
20
20
  import path from "path";