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

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 (59) hide show
  1. package/.build-stamp +1 -1
  2. package/{abstractCompactor-rk6twzvj.js → abstractCompactor-e5yq60qz.js} +2 -2
  3. package/{agent.command-jfz8yfwy.js → agent.command-b0fcx3r2.js} +7 -7
  4. package/{application.command-mxyqtd6p.js → application.command-cezdnvtq.js} +5 -5
  5. package/{applicationBuildRunner-cwk52sb7.js → applicationBuildRunner-ha3y8ew8.js} +4 -4
  6. package/{applicationReleasePackager-yrrhbkv3.js → applicationReleasePackager-gg8ccbeh.js} +1 -1
  7. package/buildBatch.proc.js +4 -4
  8. package/{capacitorApp-j357ak1g.js → capacitorApp-jaksw4cy.js} +3 -3
  9. package/{cloud.command-f87dwe52.js → cloud.command-6xvsd487.js} +9 -9
  10. package/{context.command-z5bf8bn7.js → context.command-ajn1b683.js} +15 -15
  11. package/{guideline.command-1m1ctar3.js → guideline.command-9ew6aqhm.js} +5 -5
  12. package/guidelines/ssrRule/ssrRule.generate.json +31 -0
  13. package/guidelines/ssrRule/ssrRule.instruction.md +108 -0
  14. package/incrementalBuilder.proc.js +3 -3
  15. package/{index-3pgtw35d.js → index-0cj2zxbm.js} +1 -1
  16. package/{index-jtm86byd.js → index-47qxw1tz.js} +28 -22
  17. package/{index-vhv3xnjz.js → index-60a3jfcz.js} +6 -6
  18. package/{index-b978vs2e.js → index-6npsfpxr.js} +3 -3
  19. package/{index-csqk9z5j.js → index-c94nq3c1.js} +3 -3
  20. package/{index-cn24dcqn.js → index-exhpp31y.js} +2 -2
  21. package/{index-y0k42k04.js → index-hk9rbcsz.js} +1 -1
  22. package/{index-hjzr8ja1.js → index-hrwzz2wf.js} +1 -1
  23. package/{index-rh16j3c7.js → index-j9cxndc0.js} +3 -2
  24. package/{index-jk9q6pse.js → index-jkynkyfk.js} +1 -1
  25. package/{index-4yp06pn1.js → index-jn9vfpwz.js} +9 -31
  26. package/{index-4zgs8g1w.js → index-m4kpmmtj.js} +1 -1
  27. package/{index-e3qskyt2.js → index-meh7mmz9.js} +2 -2
  28. package/{index-6pz1j0zj.js → index-mxvakhsm.js} +6 -2
  29. package/{index-n0z3f2xg.js → index-nfxq39kj.js} +4 -4
  30. package/{index-r4w8cry5.js → index-pfrt7qwh.js} +4 -4
  31. package/{index-cap2k2ch.js → index-qb61h0k7.js} +52 -17
  32. package/{index-xwgm94zr.js → index-qp089jp0.js} +1 -1
  33. package/{index-tq1y56tp.js → index-r7nqv8qj.js} +35 -12
  34. package/{index-1s71fwrq.js → index-vkqxw0ek.js} +11 -11
  35. package/{index-fmgbwsr5.js → index-wrrb8rxk.js} +4 -4
  36. package/{index-xj8bks3p.js → index-zbx0jheb.js} +4 -4
  37. package/{index-ybybkec0.js → index-zr2wvx69.js} +6 -6
  38. package/index.js +19 -19
  39. package/{library.command-pwfx8dx2.js → library.command-aa1g8nsa.js} +4 -4
  40. package/{localRegistry.command-r4zjx5py.js → localRegistry.command-jha3sn50.js} +8 -8
  41. package/{module.command-0t3ewata.js → module.command-b1zzgqde.js} +8 -8
  42. package/{package.command-7hmkxvpa.js → package.command-9qv6vr9s.js} +4 -4
  43. package/package.json +2 -2
  44. package/{page.command-st6r4s0q.js → page.command-k16pw244.js} +4 -4
  45. package/{primitive.command-1qkxpzsn.js → primitive.command-s60dn1ae.js} +9 -9
  46. package/{quality.command-hy5vt1bh.js → quality.command-p3vaze52.js} +456 -71
  47. package/{repair.command-nakkq2zp.js → repair.command-mfv749ha.js} +6 -6
  48. package/{scalar.command-fjq272gs.js → scalar.command-hs3nwzv1.js} +7 -7
  49. package/templates/lib/db.ts +3 -1
  50. package/templates/lib/useClient.ts +9 -3
  51. package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +3 -2
  52. package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +1 -0
  53. package/templates/workspaceRoot/.cursor/rules/ssr-first.mdc.template +59 -0
  54. package/templates/workspaceRoot/AGENTS.md.template +155 -15
  55. package/templates/workspaceRoot/biome.json.template +22 -0
  56. package/{workflow.command-jswbgk90.js → workflow.command-z0e0fk0z.js} +12 -12
  57. package/{workspace.command-h9wwcjpt.js → workspace.command-3ydyy991.js} +21 -21
  58. package/templates/libRoot/base/baseLogic.ts +0 -14
  59. package/templates/libRoot/base/index.ts +0 -8
@@ -1143,16 +1143,17 @@ class RouteClientBuilder {
1143
1143
  #knownEntries;
1144
1144
  #command;
1145
1145
  #discovery;
1146
+ #entries;
1146
1147
  constructor(options) {
1147
1148
  this.#app = options.app;
1148
1149
  this.#seeds = options.seeds;
1149
1150
  this.#knownEntries = options.knownEntries ?? new Set;
1150
1151
  this.#command = options.command ?? "start";
1151
1152
  this.#discovery = options.discovery;
1153
+ this.#entries = options.entries;
1152
1154
  }
1153
1155
  async build() {
1154
- const discovery = this.#discovery ?? await GraphClientEntryDiscovery.create(this.#app);
1155
- const discovered = await discovery.discover(this.#seeds);
1156
+ const discovered = this.#entries ?? await (this.#discovery ?? await GraphClientEntryDiscovery.create(this.#app)).discover(this.#seeds);
1156
1157
  const entries = discovered.filter((e) => !this.#knownEntries.has(e));
1157
1158
  if (entries.length === 0)
1158
1159
  return this.#emptyResult(discovered);
@@ -7,7 +7,7 @@ import {
7
7
  PkgExecutor,
8
8
  WorkspaceExecutor,
9
9
  getDirname
10
- } from "./index-jtm86byd.js";
10
+ } from "./index-47qxw1tz.js";
11
11
  import {
12
12
  FileSys
13
13
  } from "./index-67546d0j.js";
@@ -2,11 +2,14 @@
2
2
  import {
3
3
  workflowRunArtifactPath,
4
4
  workflowSyncDir
5
- } from "./index-4zgs8g1w.js";
5
+ } from "./index-m4kpmmtj.js";
6
6
  import {
7
7
  AppExecutor,
8
- LibExecutor
9
- } from "./index-jtm86byd.js";
8
+ LibExecutor,
9
+ appRootAllowedDirs,
10
+ appRootAllowedFiles,
11
+ isScannedAppRootEntry
12
+ } from "./index-47qxw1tz.js";
10
13
  import {
11
14
  collectRecipeSources,
12
15
  findInlineRecipeDuplicates,
@@ -150,33 +153,6 @@ var moduleShapeFiles = (module) => {
150
153
  ];
151
154
  };
152
155
  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
156
  var safeReadDir = async (dirPath) => {
181
157
  try {
182
158
  return (await readdir(dirPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
@@ -404,7 +380,9 @@ class AkanContextAnalyzer {
404
380
  for (const app of context.apps) {
405
381
  const appPath = path.join(workspace.workspaceRoot, app.path);
406
382
  for (const entry of await safeReadDir(appPath)) {
407
- const allowed = entry.isDirectory() ? appRootAllowDirs.has(entry.name) : appRootAllowFiles.has(entry.name);
383
+ if (!isScannedAppRootEntry(entry.name))
384
+ continue;
385
+ const allowed = entry.isDirectory() ? appRootAllowedDirs.has(entry.name) : appRootAllowedFiles.has(entry.name);
408
386
  if (!allowed) {
409
387
  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
388
  diagnostics.push({
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-jtm86byd.js";
5
+ } from "./index-47qxw1tz.js";
6
6
 
7
7
  // pkgs/@akanjs/devkit/workflow/utils.ts
8
8
  var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-jk9q6pse.js";
5
+ } from "./index-jkynkyfk.js";
6
6
  import {
7
7
  PkgExecutor
8
- } from "./index-jtm86byd.js";
8
+ } from "./index-47qxw1tz.js";
9
9
  import {
10
10
  TypeScriptDependencyScanner
11
11
  } from "./index-46tjzh6s.js";
@@ -4,6 +4,10 @@ import ora from "ora";
4
4
 
5
5
  class Spinner {
6
6
  static padding = 12;
7
+ static oraOptions = { discardStdin: false };
8
+ static canAnimate(stream = process.stderr) {
9
+ return !stream.isTTY || stream.columns > 0;
10
+ }
7
11
  spinner;
8
12
  stopWatch = null;
9
13
  startAt = new Date;
@@ -14,10 +18,10 @@ class Spinner {
14
18
  Spinner.padding = Math.max(Spinner.padding, prefix.length);
15
19
  this.prefix = prefix;
16
20
  this.message = message;
17
- this.spinner = ora(message);
21
+ this.spinner = ora({ ...Spinner.oraOptions, text: message });
18
22
  this.spinner.prefixText = prefix.padStart(Spinner.padding, " ");
19
23
  this.spinner.indent = indent;
20
- this.enableSpin = enableSpin;
24
+ this.enableSpin = enableSpin && Spinner.canAnimate();
21
25
  }
22
26
  start() {
23
27
  this.startAt = new Date;
@@ -1,14 +1,14 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-4yp06pn1.js";
4
+ } from "./index-jn9vfpwz.js";
5
5
  import {
6
6
  Prompter
7
- } from "./index-xwgm94zr.js";
7
+ } from "./index-qp089jp0.js";
8
8
  import {
9
9
  runner,
10
10
  script
11
- } from "./index-jk9q6pse.js";
11
+ } from "./index-jkynkyfk.js";
12
12
  import {
13
13
  AGENT_BLOCK_END,
14
14
  AGENT_BLOCK_START,
@@ -16,7 +16,7 @@ import {
16
16
  LibExecutor,
17
17
  renderRecipeEntries,
18
18
  upsertAgentBlock
19
- } from "./index-jtm86byd.js";
19
+ } from "./index-47qxw1tz.js";
20
20
  import {
21
21
  collectRecipeSources,
22
22
  scanRecipes
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  ModuleScript
4
- } from "./index-vhv3xnjz.js";
4
+ } from "./index-60a3jfcz.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-m4kpmmtj.js";
38
38
  import {
39
39
  script
40
- } from "./index-jk9q6pse.js";
40
+ } from "./index-jkynkyfk.js";
41
41
  import {
42
42
  AppExecutor,
43
43
  LibExecutor,
44
44
  ModuleExecutor
45
- } from "./index-jtm86byd.js";
45
+ } from "./index-47qxw1tz.js";
46
46
 
47
47
  // pkgs/@akanjs/cli/primitive/primitive.script.ts
48
48
  import { capitalize } from "akanjs/common";
@@ -9,7 +9,7 @@ import {
9
9
  createTsconfigPackageResolver,
10
10
  rewriteBarrelImports,
11
11
  transformUseClient
12
- } from "./index-rh16j3c7.js";
12
+ } from "./index-j9cxndc0.js";
13
13
  import {
14
14
  __require
15
15
  } from "./index-r24hmh0q.js";
@@ -415,11 +415,21 @@ class AllRoutesBuilder {
415
415
  const seedIndex = computeRouteSeedIndex(pageEntries);
416
416
  this.#app.verbose(`[build-all] discovered ${seedIndex.entries.length} routes`);
417
417
  this.#discovery = await GraphClientEntryDiscovery.create(this.#app);
418
+ const allEntries = [];
419
+ const seen = new Set;
418
420
  for (const entry of seedIndex.entries) {
419
421
  const seeds = Array.from(new Set([...seedIndex.globalLayoutFiles, ...entry.seeds]));
420
- const delta = await this.#buildRoute(entry.routeId, seeds);
421
- this.#mergeRoute(entry.routeId, delta);
422
+ for (const discovered of await this.#discovery.discover(seeds)) {
423
+ if (seen.has(discovered))
424
+ continue;
425
+ seen.add(discovered);
426
+ allEntries.push(discovered);
427
+ }
428
+ this.#routeIds.push(entry.routeId);
422
429
  }
430
+ this.#app.verbose(`[build-all] ${allEntries.length} client entries across ${this.#routeIds.length} routes`);
431
+ const delta = await this.#buildEntries(allEntries);
432
+ this.#mergeDelta(delta);
423
433
  this.#merged.knownEntries = Array.from(this.#knownSet);
424
434
  const manifest = {
425
435
  routeIds: this.#routeIds,
@@ -433,23 +443,30 @@ class AllRoutesBuilder {
433
443
  this.#app.verbose(`[build-all] wrote ${manifestPath} routes=${this.#routeIds.length} entries=${this.#merged.knownEntries.length}`);
434
444
  return { manifest, manifestPath, seedIndex };
435
445
  }
436
- async#buildRoute(routeId, seeds) {
446
+ async#buildEntries(entries) {
437
447
  if (!this.#discovery)
438
448
  throw new Error("[build-all] client entry discovery is not initialized");
449
+ if (entries.length === 0)
450
+ return {
451
+ manifestDelta: {},
452
+ ssrManifestDelta: { moduleLoading: null, moduleMap: {} },
453
+ newEntries: [],
454
+ clientDeps: []
455
+ };
439
456
  const started = Date.now();
440
457
  const delta = await new RouteClientBuilder({
441
458
  app: this.#app,
442
- routeId,
443
- seeds,
459
+ seeds: [],
460
+ entries,
444
461
  artifact: this.#artifact,
445
462
  knownEntries: this.#knownSet,
446
463
  discovery: this.#discovery,
447
464
  command: this.#command
448
465
  }).build();
449
- this.#app.verbose(`[build-all] ${routeId} +${delta.newEntries.length} entries (${Date.now() - started}ms)`);
466
+ this.#app.verbose(`[build-all] bundled ${delta.newEntries.length} entries (${Date.now() - started}ms)`);
450
467
  return delta;
451
468
  }
452
- #mergeRoute(routeId, delta) {
469
+ #mergeDelta(delta) {
453
470
  for (const [key, row] of Object.entries(delta.manifestDelta))
454
471
  this.#merged.clientManifest[key] = row;
455
472
  for (const [url, byName] of Object.entries(delta.ssrManifestDelta.moduleMap)) {
@@ -457,7 +474,6 @@ class AllRoutesBuilder {
457
474
  }
458
475
  for (const abs of delta.newEntries)
459
476
  this.#knownSet.add(abs);
460
- this.#routeIds.push(routeId);
461
477
  }
462
478
  }
463
479
 
@@ -794,10 +810,10 @@ import { compile } from "tailwindcss";
794
810
 
795
811
  // pkgs/@akanjs/devkit/frontendBuild/cssCandidateCache.ts
796
812
  import { stat } from "fs/promises";
797
- var CANDIDATE_RE = /-?(?:[\w@]|\[[^\]]+\])[\w:/.-]*(?:\[[^\]]+\][\w:/.-]*)*/g;
813
+ var CANDIDATE_RE = /-?(?:[\w@]|\[[^\]\s]+\])[\w:/.-]*(?:\[[^\]\s]+\][\w:/.-]*)*/g;
798
814
 
799
815
  class CssCandidateCache {
800
- static #version = 2;
816
+ static #version = 3;
801
817
  #path;
802
818
  #entries = new Map;
803
819
  #dirty = false;
@@ -2025,14 +2041,21 @@ function loaderFor2(absPath) {
2025
2041
  // pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
2026
2042
  import fs2 from "fs";
2027
2043
  import path12 from "path";
2044
+ import zlib from "zlib";
2028
2045
  var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
2029
2046
  var MIN_COMPRESS_BYTES = 1024;
2047
+ var BROTLI_QUALITY_BY_EXT = { ".css": 11 };
2048
+ var DEFAULT_BROTLI_QUALITY = 9;
2049
+ var GZIP_LEVEL = 9;
2030
2050
  async function precompressArtifacts(app) {
2031
- const roots = [path12.join(app.dist.cwdPath, ".akan/artifact/client")];
2032
- const result = { files: 0, inputBytes: 0, outputBytes: 0 };
2051
+ const roots = [
2052
+ path12.join(app.dist.cwdPath, ".akan/artifact/client"),
2053
+ path12.join(app.dist.cwdPath, ".akan/artifact/styles")
2054
+ ];
2055
+ const result = { files: 0, inputBytes: 0, outputBytes: 0, brotliBytes: 0 };
2033
2056
  await Promise.all(roots.map((root) => precompressRoot(root, result)));
2034
2057
  if (result.files > 0) {
2035
- app.verbose(`[precompress] wrote ${result.files} gzip sidecars (${formatBytes(result.inputBytes)} -> ${formatBytes(result.outputBytes)})`);
2058
+ app.verbose(`[precompress] wrote ${result.files} sidecars (${formatBytes(result.inputBytes)} -> gzip ${formatBytes(result.outputBytes)} / br ${formatBytes(result.brotliBytes)})`);
2036
2059
  }
2037
2060
  return result;
2038
2061
  }
@@ -2044,15 +2067,27 @@ async function precompressRoot(root, result) {
2044
2067
  if (!await shouldPrecompress(filePath))
2045
2068
  continue;
2046
2069
  const bytes = await Bun.file(filePath).bytes();
2047
- const gz = Bun.gzipSync(toArrayBuffer(bytes));
2048
- await Bun.write(`${filePath}.gz`, gz);
2070
+ const buffer = toArrayBuffer(bytes);
2071
+ const gz = Bun.gzipSync(buffer, { level: GZIP_LEVEL });
2072
+ const br = brotliCompress(buffer, path12.extname(filePath).toLowerCase());
2073
+ await Promise.all([Bun.write(`${filePath}.gz`, gz), Bun.write(`${filePath}.br`, br)]);
2049
2074
  result.files += 1;
2050
2075
  result.inputBytes += bytes.byteLength;
2051
2076
  result.outputBytes += gz.byteLength;
2077
+ result.brotliBytes += br.byteLength;
2052
2078
  }
2053
2079
  }
2080
+ function brotliCompress(buffer, ext) {
2081
+ const quality = BROTLI_QUALITY_BY_EXT[ext] ?? DEFAULT_BROTLI_QUALITY;
2082
+ return zlib.brotliCompressSync(buffer, {
2083
+ params: {
2084
+ [zlib.constants.BROTLI_PARAM_QUALITY]: quality,
2085
+ [zlib.constants.BROTLI_PARAM_SIZE_HINT]: buffer.byteLength
2086
+ }
2087
+ });
2088
+ }
2054
2089
  async function shouldPrecompress(filePath) {
2055
- if (filePath.endsWith(".gz"))
2090
+ if (filePath.endsWith(".gz") || filePath.endsWith(".br"))
2056
2091
  return false;
2057
2092
  if (!COMPRESSIBLE_EXTS.has(path12.extname(filePath).toLowerCase()))
2058
2093
  return false;
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  getDirname
4
- } from "./index-jtm86byd.js";
4
+ } from "./index-47qxw1tz.js";
5
5
 
6
6
  // pkgs/@akanjs/devkit/prompter.ts
7
7
  import fsPromise from "fs/promises";
@@ -4,11 +4,11 @@ import {
4
4
  } from "./index-76rn3g2c.js";
5
5
  import {
6
6
  LibraryScript
7
- } from "./index-cn24dcqn.js";
7
+ } from "./index-exhpp31y.js";
8
8
  import {
9
9
  runner,
10
10
  script
11
- } from "./index-jk9q6pse.js";
11
+ } from "./index-jkynkyfk.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-jtm86byd.js";
21
+ } from "./index-47qxw1tz.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-cwk52sb7.js")).ApplicationBuildRunner;
1902
- var loadReleasePackager = async () => (await import("./applicationReleasePackager-yrrhbkv3.js")).ApplicationReleasePackager;
1903
- var loadCapacitorApp = async () => (await import("./capacitorApp-j357ak1g.js")).CapacitorApp;
1904
- var loadAbstractCompactor = async () => (await import("./abstractCompactor-rk6twzvj.js")).AbstractCompactor;
1901
+ var loadBuildRunner = async () => (await import("./applicationBuildRunner-ha3y8ew8.js")).ApplicationBuildRunner;
1902
+ var loadReleasePackager = async () => (await import("./applicationReleasePackager-gg8ccbeh.js")).ApplicationReleasePackager;
1903
+ var loadCapacitorApp = async () => (await import("./capacitorApp-jaksw4cy.js")).CapacitorApp;
1904
+ var loadAbstractCompactor = async () => (await import("./abstractCompactor-e5yq60qz.js")).AbstractCompactor;
1905
1905
  var loadPrompts = async () => await import("@inquirer/prompts");
1906
1906
 
1907
1907
  class ApplicationRunner extends runner("application") {
@@ -2241,6 +2241,7 @@ ${detail}`
2241
2241
 
2242
2242
  // pkgs/@akanjs/cli/application/application.script.ts
2243
2243
  class ApplicationScript extends script("application", [ApplicationRunner, LibraryScript]) {
2244
+ static dbShutdownTimeoutMs = 20000;
2244
2245
  async confirmDatabaseModeDependencyInstall(databaseMode, installSpecs) {
2245
2246
  return await confirm({
2246
2247
  message: [
@@ -2418,10 +2419,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
2418
2419
  if (app.getEnv() === "local" && dbup && databaseMode !== "single") {
2419
2420
  const wasDbAlreadyUp = await this.dbup(app.workspace, databaseMode);
2420
2421
  if (!wasDbAlreadyUp)
2421
- process.on("SIGINT", async () => {
2422
- await this.dbdown(app.workspace);
2423
- process.exit(0);
2424
- });
2422
+ this.#stopDatabaseOnInterrupt(app.workspace);
2425
2423
  }
2426
2424
  const spinner = app.spinning("Preparing backend...");
2427
2425
  const akanAppHost = await this.applicationRunner.start(app, {
@@ -2518,9 +2516,34 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
2518
2516
  }
2519
2517
  async dbdown(workspace) {
2520
2518
  const spinner = workspace.spinning("Stopping local database...");
2521
- await this.applicationRunner.dbdown(workspace);
2519
+ try {
2520
+ await this.applicationRunner.dbdown(workspace);
2521
+ } catch (error) {
2522
+ spinner.fail("Local database failed to stop");
2523
+ throw error;
2524
+ }
2522
2525
  spinner.succeed("Local database (/local/docker-compose.yaml) is down");
2523
2526
  }
2527
+ #stopDatabaseOnInterrupt(workspace) {
2528
+ let stopping = false;
2529
+ process.on("SIGINT", () => {
2530
+ if (stopping) {
2531
+ Logger5.rawLog("Abandoning the local database teardown; containers are left running.", undefined, "warn");
2532
+ process.exit(130);
2533
+ }
2534
+ stopping = true;
2535
+ this.#stopDatabase(workspace).finally(() => process.exit(0));
2536
+ });
2537
+ }
2538
+ async#stopDatabase(workspace) {
2539
+ const timeout = new Promise((resolve) => setTimeout(() => resolve("timeout"), ApplicationScript.dbShutdownTimeoutMs));
2540
+ const result = await Promise.race([this.dbdown(workspace).catch(() => {
2541
+ return;
2542
+ }), timeout]);
2543
+ if (result !== "timeout")
2544
+ return;
2545
+ Logger5.rawLog(`Local database did not stop within ${ApplicationScript.dbShutdownTimeoutMs}ms; run \`akan dbdown\` once Docker responds.`, undefined, "warn");
2546
+ }
2524
2547
  async testSys(sys) {
2525
2548
  if (sys.type === "app")
2526
2549
  await this.testApplication(sys);
@@ -1,22 +1,22 @@
1
1
  // @bun
2
2
  import {
3
3
  RepairRunner
4
- } from "./index-b978vs2e.js";
4
+ } from "./index-6npsfpxr.js";
5
5
  import {
6
6
  WorkflowRunner
7
- } from "./index-csqk9z5j.js";
7
+ } from "./index-c94nq3c1.js";
8
8
  import {
9
9
  PrimitiveScript
10
- } from "./index-r4w8cry5.js";
10
+ } from "./index-pfrt7qwh.js";
11
11
  import {
12
12
  ModuleScript
13
- } from "./index-vhv3xnjz.js";
13
+ } from "./index-60a3jfcz.js";
14
14
  import {
15
15
  ScalarScript
16
- } from "./index-fmgbwsr5.js";
16
+ } from "./index-wrrb8rxk.js";
17
17
  import {
18
18
  isPlaceholderAppId
19
- } from "./index-y0k42k04.js";
19
+ } from "./index-hk9rbcsz.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-4yp06pn1.js";
30
+ } from "./index-jn9vfpwz.js";
31
31
  import {
32
32
  buildAkanModuleContextIndex,
33
33
  createWorkflowBaselineSummary,
34
34
  createWorkflowStepRegistry,
35
35
  jsonText,
36
36
  toolingRolloutGate
37
- } from "./index-4zgs8g1w.js";
37
+ } from "./index-m4kpmmtj.js";
38
38
  import {
39
39
  Prompter
40
- } from "./index-xwgm94zr.js";
40
+ } from "./index-qp089jp0.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-jk9q6pse.js";
48
+ } from "./index-jkynkyfk.js";
49
49
  import {
50
50
  AppExecutor
51
- } from "./index-jtm86byd.js";
51
+ } from "./index-47qxw1tz.js";
52
52
 
53
53
  // pkgs/@akanjs/cli/context/context.script.ts
54
54
  import { Logger } from "akanjs/common";
@@ -4,19 +4,19 @@ import {
4
4
  } from "./index-ss469dec.js";
5
5
  import {
6
6
  AiSession
7
- } from "./index-3pgtw35d.js";
7
+ } from "./index-0cj2zxbm.js";
8
8
  import {
9
9
  createPassedPrimitiveReport,
10
10
  generatedFilesForSync,
11
11
  scalarChangedFiles
12
- } from "./index-4zgs8g1w.js";
12
+ } from "./index-m4kpmmtj.js";
13
13
  import {
14
14
  Prompter
15
- } from "./index-xwgm94zr.js";
15
+ } from "./index-qp089jp0.js";
16
16
  import {
17
17
  runner,
18
18
  script
19
- } from "./index-jk9q6pse.js";
19
+ } from "./index-jkynkyfk.js";
20
20
 
21
21
  // pkgs/@akanjs/cli/scalar/scalar.prompt.ts
22
22
  import { input } from "@inquirer/prompts";
@@ -4,17 +4,17 @@ import {
4
4
  CloudApi,
5
5
  GlobalConfig,
6
6
  getDefaultHostConfig
7
- } from "./index-3pgtw35d.js";
7
+ } from "./index-0cj2zxbm.js";
8
8
  import {
9
9
  openBrowser
10
- } from "./index-tq1y56tp.js";
10
+ } from "./index-r7nqv8qj.js";
11
11
  import {
12
12
  runner
13
- } from "./index-jk9q6pse.js";
13
+ } from "./index-jkynkyfk.js";
14
14
  import {
15
15
  AppExecutor,
16
16
  WorkspaceExecutor
17
- } from "./index-jtm86byd.js";
17
+ } from "./index-47qxw1tz.js";
18
18
 
19
19
  // pkgs/@akanjs/cli/cloud/cloud.runner.ts
20
20
  import path from "path";
@@ -1,24 +1,24 @@
1
1
  // @bun
2
2
  import {
3
3
  CloudRunner
4
- } from "./index-xj8bks3p.js";
4
+ } from "./index-zbx0jheb.js";
5
5
  import {
6
6
  PackageScript
7
- } from "./index-e3qskyt2.js";
7
+ } from "./index-meh7mmz9.js";
8
8
  import {
9
9
  AiSession,
10
10
  CloudApi,
11
11
  GlobalConfig
12
- } from "./index-3pgtw35d.js";
12
+ } from "./index-0cj2zxbm.js";
13
13
  import {
14
14
  ApplicationScript
15
- } from "./index-tq1y56tp.js";
15
+ } from "./index-r7nqv8qj.js";
16
16
  import {
17
17
  script
18
- } from "./index-jk9q6pse.js";
18
+ } from "./index-jkynkyfk.js";
19
19
  import {
20
20
  PkgExecutor
21
- } from "./index-jtm86byd.js";
21
+ } from "./index-47qxw1tz.js";
22
22
 
23
23
  // pkgs/@akanjs/cli/cloud/cloud.script.ts
24
24
  import { Logger } from "akanjs/common";
package/index.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  getTargetCommandNames,
5
5
  getTargetMetas,
6
6
  runCommands
7
- } from "./index-jk9q6pse.js";
8
- import"./index-jtm86byd.js";
9
- import"./index-6pz1j0zj.js";
7
+ } from "./index-jkynkyfk.js";
8
+ import"./index-47qxw1tz.js";
9
+ import"./index-mxvakhsm.js";
10
10
  import"./index-67546d0j.js";
11
11
  import {
12
12
  __require
@@ -17,22 +17,22 @@ import path from "path";
17
17
 
18
18
  // pkgs/@akanjs/cli/commandModules.ts
19
19
  var commandModules = {
20
- workspace: async () => (await import("./workspace.command-h9wwcjpt.js")).WorkspaceCommand,
21
- agent: async () => (await import("./agent.command-jfz8yfwy.js")).AgentCommand,
22
- application: async () => (await import("./application.command-mxyqtd6p.js")).ApplicationCommand,
23
- library: async () => (await import("./library.command-pwfx8dx2.js")).LibraryCommand,
24
- localRegistry: async () => (await import("./localRegistry.command-r4zjx5py.js")).LocalRegistryCommand,
25
- package: async () => (await import("./package.command-7hmkxvpa.js")).PackageCommand,
26
- module: async () => (await import("./module.command-0t3ewata.js")).ModuleCommand,
27
- page: async () => (await import("./page.command-st6r4s0q.js")).PageCommand,
28
- context: async () => (await import("./context.command-z5bf8bn7.js")).ContextCommand,
29
- cloud: async () => (await import("./cloud.command-f87dwe52.js")).CloudCommand,
30
- guideline: async () => (await import("./guideline.command-1m1ctar3.js")).GuidelineCommand,
31
- scalar: async () => (await import("./scalar.command-fjq272gs.js")).ScalarCommand,
32
- primitive: async () => (await import("./primitive.command-1qkxpzsn.js")).PrimitiveCommand,
33
- quality: async () => (await import("./quality.command-hy5vt1bh.js")).QualityCommand,
34
- repair: async () => (await import("./repair.command-nakkq2zp.js")).RepairCommand,
35
- workflow: async () => (await import("./workflow.command-jswbgk90.js")).WorkflowCommand
20
+ workspace: async () => (await import("./workspace.command-3ydyy991.js")).WorkspaceCommand,
21
+ agent: async () => (await import("./agent.command-b0fcx3r2.js")).AgentCommand,
22
+ application: async () => (await import("./application.command-cezdnvtq.js")).ApplicationCommand,
23
+ library: async () => (await import("./library.command-aa1g8nsa.js")).LibraryCommand,
24
+ localRegistry: async () => (await import("./localRegistry.command-jha3sn50.js")).LocalRegistryCommand,
25
+ package: async () => (await import("./package.command-9qv6vr9s.js")).PackageCommand,
26
+ module: async () => (await import("./module.command-b1zzgqde.js")).ModuleCommand,
27
+ page: async () => (await import("./page.command-k16pw244.js")).PageCommand,
28
+ context: async () => (await import("./context.command-ajn1b683.js")).ContextCommand,
29
+ cloud: async () => (await import("./cloud.command-6xvsd487.js")).CloudCommand,
30
+ guideline: async () => (await import("./guideline.command-9ew6aqhm.js")).GuidelineCommand,
31
+ scalar: async () => (await import("./scalar.command-hs3nwzv1.js")).ScalarCommand,
32
+ primitive: async () => (await import("./primitive.command-s60dn1ae.js")).PrimitiveCommand,
33
+ quality: async () => (await import("./quality.command-p3vaze52.js")).QualityCommand,
34
+ repair: async () => (await import("./repair.command-mfv749ha.js")).RepairCommand,
35
+ workflow: async () => (await import("./workflow.command-z0e0fk0z.js")).WorkflowCommand
36
36
  };
37
37
  var commandModuleIds = Object.keys(commandModules);
38
38
 
@@ -1,14 +1,14 @@
1
1
  // @bun
2
2
  import {
3
3
  LibraryScript
4
- } from "./index-cn24dcqn.js";
4
+ } from "./index-exhpp31y.js";
5
5
  import {
6
6
  Lib,
7
7
  Workspace,
8
8
  command
9
- } from "./index-jk9q6pse.js";
10
- import"./index-jtm86byd.js";
11
- import"./index-6pz1j0zj.js";
9
+ } from "./index-jkynkyfk.js";
10
+ import"./index-47qxw1tz.js";
11
+ import"./index-mxvakhsm.js";
12
12
  import"./index-67546d0j.js";
13
13
  import"./index-r24hmh0q.js";
14
14