@akanjs/cli 3.0.0-alpha.70 → 3.0.0-alpha.72

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-20e0cwbs.js → abstractCompactor-8yjc9sj4.js} +1 -1
  3. package/{agent.command-964bf8qg.js → agent.command-z0cam80t.js} +6 -6
  4. package/{application.command-n45n18sc.js → application.command-2dct57za.js} +34 -12
  5. package/{applicationBuildRunner-af0wtspv.js → applicationBuildRunner-ds8acdfz.js} +3 -3
  6. package/{applicationReleasePackager-93nzdfsy.js → applicationReleasePackager-0jf6ejr4.js} +2 -2
  7. package/buildBatch.proc.js +4 -4
  8. package/{capacitorApp-vnvnvdhf.js → capacitorApp-md7dnt25.js} +2 -2
  9. package/{cloud.command-kx1bh5yq.js → cloud.command-8j7xrxsm.js} +10 -10
  10. package/commandManifest.json +1 -1
  11. package/{context.command-g1a65x6j.js → context.command-xjf4y7em.js} +14 -14
  12. package/{dependencyScanner-rbs2407b.js → dependencyScanner-aqg3dkks.js} +1 -1
  13. package/{guideline.command-xphyhvwh.js → guideline.command-yzm0qevv.js} +4 -4
  14. package/guidelines/conventions/conventions.instruction.md +267 -440
  15. package/guidelines/framework/framework.generate.json +3 -2
  16. package/guidelines/framework/framework.instruction.md +0 -9
  17. package/guidelines/mcpRule/mcpRule.instruction.md +5 -8
  18. package/guidelines/queryRule/queryRule.generate.json +31 -0
  19. package/guidelines/queryRule/queryRule.instruction.md +143 -0
  20. package/guidelines/runtimeRule/runtimeRule.generate.json +25 -0
  21. package/guidelines/runtimeRule/runtimeRule.instruction.md +176 -0
  22. package/guidelines/ssrRule/ssrRule.instruction.md +49 -5
  23. package/guidelines/transportRule/transportRule.generate.json +31 -0
  24. package/guidelines/transportRule/transportRule.instruction.md +60 -0
  25. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +17 -392
  26. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +33 -0
  27. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +402 -0
  28. package/incrementalBuilder.proc.js +5 -5
  29. package/{index-4rw4qhe6.js → index-116w1dap.js} +4 -4
  30. package/{index-mkn5qagt.js → index-5r4e65hb.js} +128 -59
  31. package/{index-abyjt72y.js → index-61x7qthy.js} +17 -21
  32. package/{index-bqqts262.js → index-763h7h9g.js} +1 -1
  33. package/{index-wnp7hwq7.js → index-94hdqqka.js} +1 -1
  34. package/{index-v5fdxdre.js → index-9gqzgfsd.js} +4 -4
  35. package/{index-fahkq20v.js → index-a341yqdh.js} +3 -3
  36. package/{index-e31ghfp5.js → index-akz5xvyw.js} +17 -5
  37. package/{index-va15r8h5.js → index-bmz9crym.js} +13 -6
  38. package/{index-qt4nfr0n.js → index-eed7vc38.js} +66 -33
  39. package/{index-46tjzh6s.js → index-h5sr2nnj.js} +24 -24
  40. package/{index-nkwmnqwn.js → index-h9cybjep.js} +92 -19
  41. package/{index-p681w089.js → index-hvbdre8z.js} +4 -10
  42. package/{index-qnv0aqmm.js → index-jcm6zr20.js} +3 -1
  43. package/{index-j37qq1f2.js → index-k7731a4v.js} +4 -4
  44. package/{index-ytaqtc04.js → index-q0s2dp3y.js} +1 -1
  45. package/{index-nj3w0r34.js → index-q13s3e01.js} +3 -3
  46. package/{index-0ngvvgry.js → index-qge1hc70.js} +5 -5
  47. package/{index-sh01r3pm.js → index-safgeq9a.js} +3 -2
  48. package/{index-xjd3rqzj.js → index-scemmfpj.js} +6 -15
  49. package/{index-rbnpe8cp.js → index-te6r1b79.js} +19 -23
  50. package/{index-yg3hxk2k.js → index-vrra4ttx.js} +6 -6
  51. package/{index-8gybxemv.js → index-y3wyqcsp.js} +6 -6
  52. package/{index-hee7egtm.js → index-ym9g9ggs.js} +21 -21
  53. package/{index-fgc8r6dj.js → index-ynf37b66.js} +3 -1
  54. package/{index-rb65xnw9.js → index-z52nhkjs.js} +4 -4
  55. package/index.js +18 -18
  56. package/{library.command-rfpd27yv.js → library.command-w8b53vtt.js} +4 -4
  57. package/{localRegistry.command-pyxfe0fs.js → localRegistry.command-ymrgda7e.js} +9 -9
  58. package/{module.command-qhaxad0p.js → module.command-7pje37dv.js} +7 -7
  59. package/{package.command-2k22q9nt.js → package.command-jg4qk8ts.js} +4 -4
  60. package/package.json +3 -4
  61. package/{page.command-ymk9dqh4.js → page.command-abbpj96j.js} +3 -3
  62. package/{primitive.command-9k45zpc1.js → primitive.command-jw4yv918.js} +8 -8
  63. package/{quality.command-bf6vkxe5.js → quality.command-06j6qy6n.js} +34 -4
  64. package/{repair.command-egvvm6xf.js → repair.command-x6resn10.js} +5 -5
  65. package/{scalar.command-bt1facyj.js → scalar.command-mj2vx6rj.js} +6 -6
  66. package/templates/appSample/lib/task/task.signal.ts +11 -6
  67. package/templates/crudPages/[__model__Id]/edit/page.tsx +5 -5
  68. package/templates/crudPages/[__model__Id]/page.tsx +10 -13
  69. package/templates/crudPages/new/page.tsx +5 -5
  70. package/templates/crudPages/page.tsx +9 -9
  71. package/templates/crudSinglePage/page.tsx +11 -7
  72. package/templates/module/__model__.dictionary.ts +4 -1
  73. package/templates/module/__model__.signal.ts +2 -3
  74. package/templates/module/__model__.store.ts +1 -2
  75. package/templates/workspaceRoot/AGENTS.md.template +4 -0
  76. package/{typeChecker-g6bh0xfv.js → typeChecker-yhs4eht8.js} +1 -1
  77. package/typecheck.proc.js +1 -1
  78. package/{workflow.command-v1n3wg7v.js → workflow.command-pmw2tere.js} +11 -11
  79. package/{workspace.command-yvvqvhzz.js → workspace.command-x32k2vma.js} +29 -26
@@ -1,14 +1,14 @@
1
1
  // @bun
2
2
  import {
3
3
  LibraryScript
4
- } from "./index-p681w089.js";
4
+ } from "./index-hvbdre8z.js";
5
5
  import {
6
6
  resolveMobileTargets
7
7
  } from "./index-76rn3g2c.js";
8
8
  import {
9
9
  runner,
10
10
  script
11
- } from "./index-e31ghfp5.js";
11
+ } from "./index-akz5xvyw.js";
12
12
  import {
13
13
  HmrWatcher,
14
14
  WatchRootResolver
@@ -18,7 +18,7 @@ import {
18
18
  LibExecutor,
19
19
  PkgExecutor,
20
20
  WorkspaceExecutor
21
- } from "./index-nkwmnqwn.js";
21
+ } from "./index-h9cybjep.js";
22
22
  import {
23
23
  __require
24
24
  } from "./index-yb2wsc7f.js";
@@ -72,9 +72,10 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause)}` : "";
72
72
  import { confirm } from "@inquirer/prompts";
73
73
  import { Logger as Logger5 } from "akanjs/common";
74
74
 
75
+ // pkgs/@akanjs/cli/application/application.runner.ts
76
+ import path5 from "path";
77
+
75
78
  // pkgs/@akanjs/devkit/akanApp/akanApp.host.ts
76
- import { stat } from "fs/promises";
77
- import path2 from "path";
78
79
  import { Logger as Logger3 } from "akanjs/common";
79
80
 
80
81
  // pkgs/@akanjs/devkit/sshTunnel.ts
@@ -470,38 +471,23 @@ class BuilderRequestRouter {
470
471
  }
471
472
  }
472
473
 
473
- // pkgs/@akanjs/devkit/akanApp/akanApp.host.ts
474
- var backendMsgTypeSet = new Set(["build-route", "build-csr"]);
475
- var BACKEND_RESTART_DEBOUNCE_MS = 120;
476
- var BACKEND_GRACEFUL_TIMEOUT_MS = 8000;
477
- var BACKEND_RECOVERY_BASE_DELAY_MS = 1000;
478
- var BACKEND_RECOVERY_MAX_DELAY_MS = 30000;
474
+ // pkgs/@akanjs/devkit/akanApp/BackendImportGraph.ts
475
+ import { stat } from "fs/promises";
476
+ import path3 from "path";
477
+
478
+ // pkgs/@akanjs/devkit/akanApp/devHostPolicy.ts
479
+ import path2 from "path";
479
480
  var BACKEND_RECOVERY_MAX_ATTEMPTS = 5;
480
- var BACKEND_STDERR_TAIL_LIMIT = 40;
481
- var BUILDER_READY_TIMEOUT_MS = 150000;
482
- var BUILDER_START_MAX_ATTEMPTS = 3;
483
481
  var HELD_BUILDER_REQUEST_LIMIT = 64;
484
- var BUILDER_RSS_RECYCLE_QUIET_MS = 750;
485
482
  var BUILDER_MIN_RSS_RECYCLE_INTERVAL_MS = 30000;
486
483
  var BUILDER_TIGHT_RSS_REPORT_LIMIT = 2;
487
- var BUILDER_RSS_SETTLE_MS = 20000;
488
- var PS_RSS_TIMEOUT_MS = 2000;
489
484
  var BUILDER_RSS_HARD_MULTIPLE = 1.5;
490
485
  var DEV_IDLE_SUSPEND_MS = 300000;
491
486
  var DEV_IDLE_MIN_UPTIME_MS = 30000;
492
- var BUILDER_RECOVERY_BASE_DELAY_MS = 2000;
493
- var BUILDER_RECOVERY_MAX_DELAY_MS = 60000;
494
487
  var SOURCE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
495
- var NON_SOURCE_EXT_RE = /\.(css|scss|sass|less|json|svg|png|jpe?g|webp|gif|avif|ico|woff2?|ttf|otf|mp3|mp4|wav|html)$/i;
496
488
  var SERVER_SUFFIXES = [".service.ts", ".document.ts"];
497
489
  var SHARED_SUFFIXES = [".constant.ts", ".dictionary.ts", ".signal.ts"];
498
490
  var RUNTIME_METADATA_BASENAMES = new Set(["dict.ts", "sig.ts", "useClient.ts", "useServer.ts"]);
499
- var GRAPH_IMPORT_KINDS = new Set([
500
- "import-statement",
501
- "require-call",
502
- "require-resolve",
503
- "dynamic-import"
504
- ]);
505
491
  var shouldRestartBackendByDevPlan = (message) => {
506
492
  if (!message.devPlan)
507
493
  return null;
@@ -682,6 +668,15 @@ var mergeInvalidateMessages = (current, next) => {
682
668
  var buildStatusReplaySequence = (pendingReplay, latestByPhase) => [...pendingReplay, ...latestByPhase.values()];
683
669
  var filesChangedSince = (before, after) => [...before].filter(([file, stamp]) => after.get(file) !== stamp).map(([file]) => file);
684
670
 
671
+ // pkgs/@akanjs/devkit/akanApp/BackendImportGraph.ts
672
+ var NON_SOURCE_EXT_RE = /\.(css|scss|sass|less|json|svg|png|jpe?g|webp|gif|avif|ico|woff2?|ttf|otf|mp3|mp4|wav|html)$/i;
673
+ var GRAPH_IMPORT_KINDS = new Set([
674
+ "import-statement",
675
+ "require-call",
676
+ "require-resolve",
677
+ "dynamic-import"
678
+ ]);
679
+
685
680
  class BackendImportGraph {
686
681
  #app;
687
682
  #logger;
@@ -704,7 +699,7 @@ class BackendImportGraph {
704
699
  return this.#lastRefreshSucceeded;
705
700
  }
706
701
  has(file) {
707
- return this.#files.has(path2.resolve(file));
702
+ return this.#files.has(path3.resolve(file));
708
703
  }
709
704
  async fingerprint() {
710
705
  const stamps = await Promise.all([...this.#files].map(async (file) => {
@@ -732,9 +727,9 @@ class BackendImportGraph {
732
727
  const roots = await this.#entrypoints();
733
728
  const files = new Set;
734
729
  const queue = [...roots];
735
- const workspaceRoot = path2.resolve(this.#app.workspace.workspaceRoot);
730
+ const workspaceRoot = path3.resolve(this.#app.workspace.workspaceRoot);
736
731
  while (queue.length > 0) {
737
- const current = path2.resolve(queue.pop());
732
+ const current = path3.resolve(queue.pop());
738
733
  if (files.has(current))
739
734
  continue;
740
735
  if (!this.#isWorkspaceSource(current, workspaceRoot))
@@ -743,7 +738,7 @@ class BackendImportGraph {
743
738
  if (!imports)
744
739
  continue;
745
740
  files.add(current);
746
- const importerDir = path2.dirname(current);
741
+ const importerDir = path3.dirname(current);
747
742
  for (const imp of imports) {
748
743
  if (!GRAPH_IMPORT_KINDS.has(imp.kind) || !imp.path || NON_SOURCE_EXT_RE.test(imp.path))
749
744
  continue;
@@ -774,7 +769,7 @@ class BackendImportGraph {
774
769
  const roots = [`${this.#app.cwdPath}/main.ts`, `${this.#app.cwdPath}/server.ts`];
775
770
  const existing = [];
776
771
  for (const root of roots) {
777
- const abs = path2.resolve(root);
772
+ const abs = path3.resolve(root);
778
773
  if (await Bun.file(abs).exists())
779
774
  existing.push(abs);
780
775
  }
@@ -783,25 +778,25 @@ class BackendImportGraph {
783
778
  #resolve(specifier, importerDir) {
784
779
  try {
785
780
  const resolved = Bun.resolveSync(specifier, importerDir);
786
- if (!path2.isAbsolute(resolved))
781
+ if (!path3.isAbsolute(resolved))
787
782
  return null;
788
- if (!SOURCE_EXTS.has(path2.extname(resolved).toLowerCase()))
783
+ if (!SOURCE_EXTS.has(path3.extname(resolved).toLowerCase()))
789
784
  return null;
790
- return path2.resolve(resolved);
785
+ return path3.resolve(resolved);
791
786
  } catch {
792
787
  return null;
793
788
  }
794
789
  }
795
790
  #isWorkspaceSource(file, workspaceRoot) {
796
- const rel = path2.relative(workspaceRoot, file);
797
- if (rel.startsWith("..") || path2.isAbsolute(rel))
791
+ const rel = path3.relative(workspaceRoot, file);
792
+ if (rel.startsWith("..") || path3.isAbsolute(rel))
798
793
  return false;
799
- if (rel.includes(`${path2.sep}node_modules${path2.sep}`) || rel.includes(`${path2.sep}.akan${path2.sep}`))
794
+ if (rel.includes(`${path3.sep}node_modules${path3.sep}`) || rel.includes(`${path3.sep}.akan${path3.sep}`))
800
795
  return false;
801
- return SOURCE_EXTS.has(path2.extname(file).toLowerCase());
796
+ return SOURCE_EXTS.has(path3.extname(file).toLowerCase());
802
797
  }
803
798
  #scanImports(file, source) {
804
- const ext = path2.extname(file).toLowerCase();
799
+ const ext = path3.extname(file).toLowerCase();
805
800
  if (ext === ".tsx")
806
801
  return this.#tsxTranspiler.scanImports(source);
807
802
  if (ext === ".jsx")
@@ -812,6 +807,21 @@ class BackendImportGraph {
812
807
  }
813
808
  }
814
809
 
810
+ // pkgs/@akanjs/devkit/akanApp/akanApp.host.ts
811
+ var backendMsgTypeSet = new Set(["build-route", "build-csr"]);
812
+ var BACKEND_RESTART_DEBOUNCE_MS = 120;
813
+ var BACKEND_GRACEFUL_TIMEOUT_MS = 8000;
814
+ var BACKEND_RECOVERY_BASE_DELAY_MS = 1000;
815
+ var BACKEND_RECOVERY_MAX_DELAY_MS = 30000;
816
+ var BACKEND_STDERR_TAIL_LIMIT = 40;
817
+ var BUILDER_READY_TIMEOUT_MS = 150000;
818
+ var BUILDER_START_MAX_ATTEMPTS = 3;
819
+ var BUILDER_RSS_RECYCLE_QUIET_MS = 750;
820
+ var BUILDER_RSS_SETTLE_MS = 20000;
821
+ var PS_RSS_TIMEOUT_MS = 2000;
822
+ var BUILDER_RECOVERY_BASE_DELAY_MS = 2000;
823
+ var BUILDER_RECOVERY_MAX_DELAY_MS = 60000;
824
+
815
825
  class AkanAppHost {
816
826
  app;
817
827
  logger = new Logger3("AkanAppHost");
@@ -907,6 +917,7 @@ class AkanAppHost {
907
917
  }
908
918
  #startBackend(startStatus = null) {
909
919
  this.#builderRequests.startGeneration();
920
+ this.#discardPendingBuilderMessages("the backend restarted while the builder was away");
910
921
  this.#backendStartStatus = startStatus;
911
922
  this.#backendGaveUp = false;
912
923
  this.#setBackendLifecycleState("starting");
@@ -1498,6 +1509,12 @@ ${this.#backendStderrTail.join(`
1498
1509
  this.#pendingBuilderMessages.push(message);
1499
1510
  this.logger.verbose(`[builder] holding ${message.type} until the builder is ready (${this.#pendingBuilderMessages.length} waiting)`);
1500
1511
  }
1512
+ #discardPendingBuilderMessages(reason) {
1513
+ const held = this.#pendingBuilderMessages.splice(0);
1514
+ if (held.length === 0)
1515
+ return;
1516
+ this.logger.verbose(`[builder] dropped ${held.length} held builder request(s): ${reason}`);
1517
+ }
1501
1518
  #failPendingBuilderMessages(reason) {
1502
1519
  const held = this.#pendingBuilderMessages.splice(0);
1503
1520
  if (held.length === 0)
@@ -1858,20 +1875,20 @@ ${this.#backendStderrTail.join(`
1858
1875
  }
1859
1876
  }
1860
1877
  // pkgs/@akanjs/devkit/applicationTestPreload.ts
1861
- import path3 from "path";
1878
+ import path4 from "path";
1862
1879
  var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
1863
1880
  async function resolveSignalTestPreloadPath(target) {
1864
1881
  const candidates = [];
1865
1882
  const addResolvedPackageCandidate = (basePath) => {
1866
1883
  try {
1867
- candidates.push(path3.join(path3.dirname(Bun.resolveSync("akanjs/package.json", basePath)), SIGNAL_TEST_PRELOAD_PATH));
1884
+ candidates.push(path4.join(path4.dirname(Bun.resolveSync("akanjs/package.json", basePath)), SIGNAL_TEST_PRELOAD_PATH));
1868
1885
  } catch {}
1869
1886
  };
1870
1887
  addResolvedPackageCandidate(target.cwdPath);
1871
1888
  addResolvedPackageCandidate(process.cwd());
1872
- addResolvedPackageCandidate(path3.dirname(Bun.main));
1889
+ addResolvedPackageCandidate(path4.dirname(Bun.main));
1873
1890
  addResolvedPackageCandidate(import.meta.dir);
1874
- candidates.push(path3.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path3.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path3.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path3.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path3.join(path3.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path3.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
1891
+ candidates.push(path4.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.join(path4.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
1875
1892
  const uniqueCandidates = [...new Set(candidates)];
1876
1893
  for (const candidate of uniqueCandidates) {
1877
1894
  if (await Bun.file(candidate).exists())
@@ -1898,10 +1915,10 @@ function openBrowser(url) {
1898
1915
  }
1899
1916
 
1900
1917
  // pkgs/@akanjs/cli/application/application.runner.ts
1901
- var loadBuildRunner = async () => (await import("./applicationBuildRunner-af0wtspv.js")).ApplicationBuildRunner;
1902
- var loadReleasePackager = async () => (await import("./applicationReleasePackager-93nzdfsy.js")).ApplicationReleasePackager;
1903
- var loadCapacitorApp = async () => (await import("./capacitorApp-vnvnvdhf.js")).CapacitorApp;
1904
- var loadAbstractCompactor = async () => (await import("./abstractCompactor-20e0cwbs.js")).AbstractCompactor;
1918
+ var loadBuildRunner = async () => (await import("./applicationBuildRunner-ds8acdfz.js")).ApplicationBuildRunner;
1919
+ var loadReleasePackager = async () => (await import("./applicationReleasePackager-0jf6ejr4.js")).ApplicationReleasePackager;
1920
+ var loadCapacitorApp = async () => (await import("./capacitorApp-md7dnt25.js")).CapacitorApp;
1921
+ var loadAbstractCompactor = async () => (await import("./abstractCompactor-8yjc9sj4.js")).AbstractCompactor;
1905
1922
  var loadPrompts = async () => await import("@inquirer/prompts");
1906
1923
 
1907
1924
  class ApplicationRunner extends runner("application") {
@@ -1915,7 +1932,7 @@ class ApplicationRunner extends runner("application") {
1915
1932
  return AppExecutor.from(workspace, appName);
1916
1933
  }
1917
1934
  async removeApplication(app) {
1918
- await app.workspace.exec(`rm -rf apps/${app.name}`);
1935
+ await app.workspace.removeDir(`apps/${app.name}`);
1919
1936
  }
1920
1937
  async getConfig(app) {
1921
1938
  return await app.getConfig();
@@ -1945,10 +1962,69 @@ class ApplicationRunner extends runner("application") {
1945
1962
  stdio: "inherit"
1946
1963
  });
1947
1964
  }
1965
+ #runtimeDirOf(app, override) {
1966
+ return path5.resolve(override ?? process.env.AKAN_RUNTIME_DIR ?? path5.join(app.workspace.workspaceRoot, "local", "apps", app.name, "runtime"));
1967
+ }
1968
+ async runLogs(app, options) {
1969
+ const { LogControlUnavailableError, LogTailClient } = await import("akanjs/server/logging/logTailClient");
1970
+ const { LogQueryMatcher } = await import("akanjs/server/logging/logQuery");
1971
+ const runtimeDir = this.#runtimeDirOf(app, options.runtimeDir);
1972
+ const socketPath = LogTailClient.socketPath(runtimeDir);
1973
+ const { level, grep, endpoint, trace, child, role, origin, since } = options;
1974
+ const query = Object.fromEntries(Object.entries({ level, grep, endpoint, trace, child, role, origin, since }).filter(([, value]) => value !== undefined && value !== null && value !== ""));
1975
+ const print = (record) => process.stdout.write(options.json ? `${JSON.stringify(record)}
1976
+ ` : Logger4.render(record));
1977
+ const note = (text) => process.stderr.write(`[akan logs] ${text}
1978
+ `);
1979
+ let finish = null;
1980
+ const closed = new Promise((resolve) => {
1981
+ finish = resolve;
1982
+ });
1983
+ let client;
1984
+ try {
1985
+ client = await LogTailClient.connect(socketPath, {
1986
+ onRecord: (entry) => print(entry.record),
1987
+ onEvent: (response) => {
1988
+ if (response.type === "dropped")
1989
+ note(`${response.count} records dropped (reader too slow)`);
1990
+ },
1991
+ onClose: () => finish?.()
1992
+ });
1993
+ } catch (error) {
1994
+ if (error instanceof LogControlUnavailableError)
1995
+ throw new Error(`${app.name} is not running (no ${path5.basename(socketPath)} in ${runtimeDir}). Start it with \`akan start ${app.name}\`, or pass --runtime-dir for a built app.`);
1996
+ throw error;
1997
+ }
1998
+ const sinceMs = since ? LogQueryMatcher.parseSince(since) : undefined;
1999
+ const noteCoverage = (coverage) => {
2000
+ if (sinceMs !== undefined && coverage.from !== null && sinceMs < coverage.from)
2001
+ note(`${LogTailClient.describeCoverage(coverage)}; older records are not retained`);
2002
+ };
2003
+ if (endpoint)
2004
+ note("requests served by the primitive query fast path carry no endpoint and are not shown");
2005
+ if (options.follow === false) {
2006
+ const { entries, coverage } = await client.history({
2007
+ ...query,
2008
+ ...options.replay ? { limit: options.replay } : {}
2009
+ });
2010
+ for (const entry of entries)
2011
+ print(entry.record);
2012
+ noteCoverage(coverage);
2013
+ client.close();
2014
+ return;
2015
+ }
2016
+ const subscribed = await client.subscribe(query, { replay: options.replay });
2017
+ noteCoverage(subscribed.coverage);
2018
+ const stop = () => client.close();
2019
+ process.once("SIGINT", stop);
2020
+ process.once("SIGTERM", stop);
2021
+ await closed;
2022
+ }
1948
2023
  async runConsole(app) {
1949
2024
  const serverPath = `${app.cwdPath}/server.ts`;
1950
2025
  if (!await app.exists("server.ts"))
1951
2026
  throw new Error(`Server file not found: apps/${app.name}/server.ts`);
2027
+ const runtimeDir = this.#runtimeDirOf(app);
1952
2028
  const code = `
1953
2029
  const serverModule = await import(${JSON.stringify(serverPath)});
1954
2030
  const { assertAkanConsoleAllowed, startAkanConsole } = await import("akanjs/server");
@@ -1958,6 +2034,7 @@ assertAkanConsoleAllowed(server.env);
1958
2034
  await server.start({ listen: false, web: false });
1959
2035
  try {
1960
2036
  await startAkanConsole(server, {
2037
+ runtimeDir: ${JSON.stringify(runtimeDir)},
1961
2038
  globals: {
1962
2039
  srv: serverModule.srv,
1963
2040
  sig: serverModule.sig,
@@ -2355,6 +2432,9 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
2355
2432
  await app.scanSync();
2356
2433
  await this.applicationRunner.runConsole(app);
2357
2434
  }
2435
+ async logs(app, options) {
2436
+ await this.applicationRunner.runLogs(app, options);
2437
+ }
2358
2438
  async build(app, { write = true, fast = false, quiet = false } = {}) {
2359
2439
  await app.scanSync({ write });
2360
2440
  if (!quiet)
@@ -2544,17 +2624,6 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
2544
2624
  return;
2545
2625
  Logger5.rawLog(`Local database did not stop within ${ApplicationScript.dbShutdownTimeoutMs}ms; run \`akan dbdown\` once Docker responds.`, undefined, "error");
2546
2626
  }
2547
- async testSys(sys) {
2548
- if (sys.type === "app")
2549
- await this.testApplication(sys);
2550
- else
2551
- await this.libraryScript.testLibrary(sys);
2552
- }
2553
- async testApplication(app) {
2554
- const spinner = app.spinning("Testing application...");
2555
- await this.applicationRunner.test(app);
2556
- spinner.succeed(`Application ${app.name} (apps/${app.name}) test is successful`);
2557
- }
2558
2627
  }
2559
2628
 
2560
2629
  export { openBrowser, ApplicationScript };
@@ -9,7 +9,7 @@ import {
9
9
  createTsconfigPackageResolver,
10
10
  rewriteBarrelImports,
11
11
  transformUseClient
12
- } from "./index-qnv0aqmm.js";
12
+ } from "./index-jcm6zr20.js";
13
13
  import {
14
14
  resolveSsrPageEntriesForApp
15
15
  } from "./index-f39512t6.js";
@@ -1131,7 +1131,7 @@ class FontOptimizer {
1131
1131
  #cssParts = [];
1132
1132
  #woff2Ready = null;
1133
1133
  static #ksX1001Text = null;
1134
- static #cacheVersion = 1;
1134
+ static #cacheVersion = 2;
1135
1135
  constructor(app, command = "start") {
1136
1136
  this.#app = app;
1137
1137
  this.#command = command;
@@ -1182,9 +1182,12 @@ class FontOptimizer {
1182
1182
  sources.push({ subsetFile: filePath, ...stamp });
1183
1183
  }
1184
1184
  if (this.#getFontSubsets(font).includes("auto"))
1185
- sources.push({ autoSubsetText: this.#hashFontConfig(await this.#collectAutoSubsetText()) });
1185
+ sources.push({ autoSubsetText: this.#cacheDigest(await this.#collectAutoSubsetText()) });
1186
1186
  }
1187
- return this.#hashFontConfig({ version: FontOptimizer.#cacheVersion, fonts, sources });
1187
+ return this.#cacheDigest({ version: FontOptimizer.#cacheVersion, fonts, sources });
1188
+ }
1189
+ #cacheDigest(value) {
1190
+ return new Bun.CryptoHasher("sha256").update(this.#stableStringify(value)).digest("hex");
1188
1191
  }
1189
1192
  async#fileStamp(filePath) {
1190
1193
  try {
@@ -1460,16 +1463,19 @@ class FontOptimizer {
1460
1463
  }
1461
1464
  async#collectAutoSubsetText() {
1462
1465
  const libPageRoots = (await this.#app.getPageRoots()).filter((root) => root.keyPrefix).map((root) => root.dir);
1463
- const roots = [...["page", "ui"].map((dir) => path8.join(this.#app.cwdPath, dir)), ...libPageRoots];
1466
+ const roots = [...["page", "ui", "lib"].map((dir) => path8.join(this.#app.cwdPath, dir)), ...libPageRoots];
1464
1467
  const glob = new Bun.Glob("**/*.{ts,tsx,js,jsx,html,md}");
1465
1468
  const parts = [];
1466
- await Promise.all(roots.map(async (root) => {
1467
- if (!await stat2(root).then((entry) => entry.isDirectory(), () => false))
1468
- return;
1469
- for await (const filePath of glob.scan({ cwd: root, absolute: true })) {
1469
+ for (const root of [...new Set(roots)].sort()) {
1470
+ const isDir = await stat2(root).then((entry) => entry.isDirectory(), () => false);
1471
+ if (!isDir)
1472
+ continue;
1473
+ const filePaths = [];
1474
+ for await (const filePath of glob.scan({ cwd: root, absolute: true }))
1475
+ filePaths.push(filePath);
1476
+ for (const filePath of filePaths.sort())
1470
1477
  parts.push(await Bun.file(filePath).text());
1471
- }
1472
- }));
1478
+ }
1473
1479
  return parts.join("");
1474
1480
  }
1475
1481
  #rangeText(start, end) {
@@ -2247,14 +2253,4 @@ ${preparedCssText}`).toString(36);
2247
2253
  }
2248
2254
  }
2249
2255
  }
2250
- // pkgs/@akanjs/devkit/frontendBuild/styleGuard.ts
2251
- var PREFIX = "(?:bg|text|border(?:-[tblrxy])?(?:-[se])?|ring(?:-offset)?|fill|stroke|shadow|from|to|via|divide|outline|decoration|placeholder|caret|accent)";
2252
- var PALETTE = "(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)";
2253
- var LEAD = "(^|[\\s\"'`{(\\[:!])";
2254
- var TAIL = "(?=[\\s\"'`})\\]:/!,]|$)";
2255
- var RAW_PALETTE_RE = new RegExp(`${LEAD}((?:${PREFIX})-)${PALETTE}-\\d{2,3}${TAIL}`, "g");
2256
- var INTERPOLATED_ARBITRARY_RE = new RegExp(`${LEAD}[a-z][a-z0-9-]*-\\[[^\\]\`]*\\$\\{`, "g");
2257
- var DAISYUI_LEGACY_RE = new RegExp(`${LEAD}(?:` + "btn-(?:primary|secondary|accent|neutral|info|success|warning|error|ghost|link|outline|square|circle|wide|block|xs|sm|md|lg)|" + "badge-(?:primary|secondary|accent|neutral|info|success|warning|error|ghost|outline)|" + "alert-(?:info|success|warning|error)|" + "input-(?:bordered|primary|secondary|accent|ghost|error)|" + "select-(?:bordered|primary|ghost)|textarea-(?:bordered|primary|ghost)|" + "checkbox-(?:primary|secondary|accent)|toggle-(?:primary|secondary|accent)|" + "loading-(?:spinner|dots|ring|ball|bars|infinity)|" + "card-(?:body|title|actions)|modal-(?:box|action|backdrop)|" + "collapse-(?:title|content|arrow|plus)|dropdown-(?:content|end|start|hover)|" + "stat-(?:title|value|desc)|tabs-(?:boxed|lifted|bordered)|tab-active|" + "menu-(?:title|dropdown)|steps-(?:horizontal|vertical)|join-item|" + "mockup-(?:code|phone|browser|window)|drawer-(?:side|content|toggle)" + `)${TAIL}`, "g");
2258
- var DAISYUI_TOKEN = "(?:base-(?:100|200|300|content)|(?:primary|secondary|accent|neutral|info|success|warning|error)-content|error)";
2259
- var DAISYUI_TOKEN_RE = new RegExp(`${LEAD}(?:${PREFIX})-${DAISYUI_TOKEN}${TAIL}`, "g");
2260
2256
  export { AllRoutesBuilder, CsrArtifactBuilder, CssCompiler, FontOptimizer, FontPruner, PagesBundleBuilder, precompressArtifacts, SsrBaseArtifactBuilder };
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-e31ghfp5.js";
5
+ } from "./index-akz5xvyw.js";
6
6
 
7
7
  // pkgs/@akanjs/cli/page/page.runner.ts
8
8
  class PageRunner extends runner("page") {
@@ -143,7 +143,7 @@ ${summary.join(", ")} found${output.join(`
143
143
  try {
144
144
  const { diagnostics } = this.check(filePath);
145
145
  return diagnostics.length === 0;
146
- } catch (error) {
146
+ } catch (_error) {
147
147
  return false;
148
148
  }
149
149
  }
@@ -4,19 +4,19 @@ import {
4
4
  } from "./index-ss469dec.js";
5
5
  import {
6
6
  AiSession
7
- } from "./index-sh01r3pm.js";
7
+ } from "./index-safgeq9a.js";
8
8
  import {
9
9
  createPassedPrimitiveReport,
10
10
  generatedFilesForSync,
11
11
  scalarChangedFiles
12
- } from "./index-ytaqtc04.js";
12
+ } from "./index-q0s2dp3y.js";
13
13
  import {
14
14
  Prompter
15
- } from "./index-j37qq1f2.js";
15
+ } from "./index-k7731a4v.js";
16
16
  import {
17
17
  runner,
18
18
  script
19
- } from "./index-e31ghfp5.js";
19
+ } from "./index-akz5xvyw.js";
20
20
 
21
21
  // pkgs/@akanjs/cli/scalar/scalar.prompt.ts
22
22
  import { input } from "@inquirer/prompts";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-va15r8h5.js";
4
+ } from "./index-bmz9crym.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-ytaqtc04.js";
26
+ } from "./index-q0s2dp3y.js";
27
27
  import {
28
28
  runner
29
- } from "./index-e31ghfp5.js";
29
+ } from "./index-akz5xvyw.js";
30
30
 
31
31
  // pkgs/@akanjs/cli/workflow/workflow.runner.ts
32
32
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -6,7 +6,7 @@ import {
6
6
  ModuleExecutor,
7
7
  PkgExecutor,
8
8
  WorkspaceExecutor
9
- } from "./index-nkwmnqwn.js";
9
+ } from "./index-h9cybjep.js";
10
10
  import {
11
11
  getDirname
12
12
  } from "./index-1577bej2.js";
@@ -383,6 +383,16 @@ var prompts = async () => await import("@inquirer/prompts");
383
383
  var select = (config, context) => prompts().then((m) => m.select(config, context));
384
384
  var confirm = (config, context) => prompts().then((m) => m.confirm(config, context));
385
385
  var input = (config, context) => prompts().then((m) => m.input(config, context));
386
+ var assertEnumChoice = (argMeta, value) => {
387
+ const enumChoices = argMeta.argsOption.enum;
388
+ if (!enumChoices || typeof enumChoices === "function")
389
+ return;
390
+ const choices = normalizeEnumChoices(enumChoices);
391
+ if (choices.some((choice) => String(choice.value) === String(value)))
392
+ return;
393
+ const label = argMeta.type === "Option" ? `option '--${camelToKebabCase3(argMeta.name)}'` : `argument '${argMeta.name}'`;
394
+ throw new Error(`${label} argument '${String(value)}' is invalid. Allowed choices are ${choices.map((choice) => choice.name).join(", ")}.`);
395
+ };
386
396
  var resolveEnumChoices = async (argMeta, context) => {
387
397
  const enumChoices = argMeta.argsOption.enum;
388
398
  if (!enumChoices)
@@ -396,9 +406,10 @@ var getOptionValue = async (argMeta, opt, context) => {
396
406
  name,
397
407
  argsOption: { enum: enumChoices, default: defaultValue, type, desc, nullable, example, ask }
398
408
  } = argMeta;
399
- if (opt[argMeta.name] !== undefined)
409
+ if (opt[argMeta.name] !== undefined) {
410
+ assertEnumChoice(argMeta, opt[argMeta.name]);
400
411
  return convertArgValue(opt[argMeta.name], type ?? "string");
401
- else if (defaultValue !== undefined)
412
+ } else if (defaultValue !== undefined)
402
413
  return defaultValue;
403
414
  if (enumChoices) {
404
415
  const choices = normalizeEnumChoices(await resolveEnumChoices(argMeta, context) ?? []);
@@ -424,9 +435,10 @@ var getArgumentValue = async (argMeta, value) => {
424
435
  name,
425
436
  argsOption: { default: defaultValue, type, desc, nullable, example, ask }
426
437
  } = argMeta;
427
- if (value !== undefined)
438
+ if (value !== undefined) {
439
+ assertEnumChoice(argMeta, value);
428
440
  return convertArgValue(value, type ?? "string");
429
- else if (defaultValue !== undefined)
441
+ } else if (defaultValue !== undefined)
430
442
  return defaultValue;
431
443
  else if (nullable)
432
444
  return null;
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  workflowRunArtifactPath,
4
4
  workflowSyncDir
5
- } from "./index-ytaqtc04.js";
5
+ } from "./index-q0s2dp3y.js";
6
6
  import {
7
7
  AppExecutor,
8
8
  LibExecutor,
@@ -11,7 +11,7 @@ import {
11
11
  readDevkitVersion,
12
12
  rootAllowedDirs,
13
13
  rootAllowedFiles
14
- } from "./index-nkwmnqwn.js";
14
+ } from "./index-h9cybjep.js";
15
15
  import {
16
16
  collectRecipeSources,
17
17
  findInlineRecipeDuplicates,
@@ -25,14 +25,21 @@ import {
25
25
  import { readdir } from "fs/promises";
26
26
  import path from "path";
27
27
  import { capitalize } from "akanjs/common";
28
- var resourceList = [
28
+ var guidelineResourceUri = (name) => `akan://guidelines/${name}`;
29
+ var staticResourceList = [
29
30
  { uri: "akan://docs/framework", name: "Akan framework guide", mimeType: "text/markdown" },
30
- { uri: "akan://guidelines/framework", name: "Framework guideline", mimeType: "text/markdown" },
31
- { uri: "akan://guidelines/modelSignal", name: "Model signal guideline", mimeType: "text/markdown" },
32
31
  { uri: "akan://workspace/summary", name: "Workspace summary", mimeType: "application/json" },
33
32
  { uri: "akan://workspace/apps", name: "Workspace apps", mimeType: "application/json" },
34
33
  { uri: "akan://workspace/modules", name: "Workspace modules", mimeType: "application/json" }
35
34
  ];
35
+ var buildResourceList = (guidelineNames) => [
36
+ ...staticResourceList,
37
+ ...guidelineNames.map((name) => ({
38
+ uri: guidelineResourceUri(name),
39
+ name: `${name} guideline`,
40
+ mimeType: "text/markdown"
41
+ }))
42
+ ];
36
43
  var cursorMcpConfigPath = ".cursor/mcp.json";
37
44
  var claudeMcpConfigPath = ".mcp.json";
38
45
  var codexMcpConfigPath = ".codex/config.toml";
@@ -626,4 +633,4 @@ class AkanContextAnalyzer {
626
633
  }
627
634
  }
628
635
 
629
- export { resourceList, codexMcpConfigPath, akanMcpInstallTargets, akanMcpInstallConfigPaths, createAkanMcpServer, createAkanCodexMcpServerBlock, upsertCodexMcpServerBlock, renderDoctorText, AkanContextAnalyzer };
636
+ export { buildResourceList, codexMcpConfigPath, akanMcpInstallTargets, akanMcpInstallConfigPaths, createAkanMcpServer, createAkanCodexMcpServerBlock, upsertCodexMcpServerBlock, renderDoctorText, AkanContextAnalyzer };