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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/.build-stamp +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +1 -1
  4. package/{abstractCompactor-rk6twzvj.js → abstractCompactor-20e0cwbs.js} +3 -3
  5. package/{agent.command-jfz8yfwy.js → agent.command-e835fjem.js} +9 -8
  6. package/{application.command-mxyqtd6p.js → application.command-sjtbk6tr.js} +7 -6
  7. package/{applicationBuildRunner-cwk52sb7.js → applicationBuildRunner-7gnfz7ww.js} +7 -8
  8. package/{applicationReleasePackager-yrrhbkv3.js → applicationReleasePackager-93nzdfsy.js} +2 -2
  9. package/buildBatch.proc.js +6 -5
  10. package/{capacitorApp-j357ak1g.js → capacitorApp-qv7g3dp2.js} +29 -28
  11. package/{cloud.command-f87dwe52.js → cloud.command-y0e4eyqz.js} +11 -10
  12. package/{context.command-z5bf8bn7.js → context.command-vn87jb08.js} +17 -16
  13. package/{dependencyScanner-f6grrep3.js → dependencyScanner-rbs2407b.js} +1 -1
  14. package/getDirname-ka11hm7e.js +8 -0
  15. package/{guideline.command-1m1ctar3.js → guideline.command-s4hn2bsy.js} +7 -6
  16. package/guidelines/conventions/conventions.generate.json +25 -0
  17. package/guidelines/conventions/conventions.instruction.md +1193 -0
  18. package/guidelines/cssRule/cssRule.instruction.md +7 -0
  19. package/guidelines/framework/framework.instruction.md +1 -0
  20. package/guidelines/ssrRule/ssrRule.generate.json +31 -0
  21. package/guidelines/ssrRule/ssrRule.instruction.md +108 -0
  22. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
  23. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +972 -0
  24. package/incrementalBuilder.proc.js +7 -6
  25. package/{index-1s71fwrq.js → index-0h212yqe.js} +13 -13
  26. package/index-1577bej2.js +7 -0
  27. package/{index-e3qskyt2.js → index-33zce8gt.js} +8 -4
  28. package/{index-csqk9z5j.js → index-3dp7x6rc.js} +3 -3
  29. package/{index-cn24dcqn.js → index-73rnbwgg.js} +15 -7
  30. package/{index-tq1y56tp.js → index-8d2sv6pw.js} +39 -16
  31. package/{index-jtm86byd.js → index-8vkkm7v0.js} +125 -66
  32. package/{index-r4w8cry5.js → index-9jsnb4vw.js} +4 -4
  33. package/{index-ybybkec0.js → index-becx1t0k.js} +6 -6
  34. package/{index-4yp06pn1.js → index-g9e2fhw2.js} +49 -32
  35. package/{index-cap2k2ch.js → index-hg0qvhmx.js} +152 -241
  36. package/{index-xwgm94zr.js → index-j37qq1f2.js} +1 -1
  37. package/{index-n0z3f2xg.js → index-k6fvbcj1.js} +37 -6
  38. package/{index-6pz1j0zj.js → index-mxvakhsm.js} +6 -2
  39. package/{index-vhv3xnjz.js → index-mykmf6wd.js} +8 -8
  40. package/{index-y0k42k04.js → index-mz5jtaq7.js} +1 -1
  41. package/{index-jk9q6pse.js → index-n706txcv.js} +5 -3
  42. package/{index-hjzr8ja1.js → index-qc0tnhs2.js} +1 -1
  43. package/{index-rh16j3c7.js → index-qnv0aqmm.js} +12 -8
  44. package/{index-3pgtw35d.js → index-sh01r3pm.js} +2 -2
  45. package/{index-xj8bks3p.js → index-t71zvmt9.js} +9 -11
  46. package/{index-4zgs8g1w.js → index-tsmjxph2.js} +1 -1
  47. package/{index-fmgbwsr5.js → index-x33gnap3.js} +4 -4
  48. package/{index-b978vs2e.js → index-xyrb7pk5.js} +3 -3
  49. package/index.js +21 -20
  50. package/{library.command-pwfx8dx2.js → library.command-v5cyaw9t.js} +6 -5
  51. package/{localRegistry.command-r4zjx5py.js → localRegistry.command-53t758pt.js} +10 -9
  52. package/{module.command-0t3ewata.js → module.command-pq6w84xg.js} +10 -9
  53. package/{package.command-7hmkxvpa.js → package.command-qkcs60ts.js} +6 -5
  54. package/package.json +3 -4
  55. package/{page.command-st6r4s0q.js → page.command-qj5bfnh9.js} +6 -5
  56. package/{primitive.command-1qkxpzsn.js → primitive.command-bw0nes6x.js} +11 -10
  57. package/{quality.command-hy5vt1bh.js → quality.command-g1s2wt8b.js} +532 -87
  58. package/{recipeScanner-tghkzrrt.js → recipeScanner-zrzev25x.js} +3 -3
  59. package/{repair.command-nakkq2zp.js → repair.command-mzwtejpk.js} +8 -7
  60. package/{routeSourceValidator-cncd92fv.js → routeSourceValidator-7fycdqyv.js} +3 -39
  61. package/{scalar.command-fjq272gs.js → scalar.command-rm6k3c65.js} +9 -8
  62. package/templates/app/env/env.server.debug.ts.template +1 -5
  63. package/templates/app/env/env.server.develop.ts.template +1 -5
  64. package/templates/app/env/env.server.local.ts.template +1 -5
  65. package/templates/app/env/env.server.main.ts.template +1 -5
  66. package/templates/app/page/styles.css.template +3 -3
  67. package/templates/appSample/srvkit/AuthGuard.ts +9 -5
  68. package/templates/appSample/srvkit/SessionInternalArg.ts +4 -3
  69. package/templates/crudPages/[__model__Id]/edit/page.tsx +1 -1
  70. package/templates/crudPages/new/page.tsx +1 -1
  71. package/templates/crudSinglePage/page.tsx +1 -1
  72. package/templates/env/_env.server.type.ts +7 -5
  73. package/templates/lib/db.ts +4 -2
  74. package/templates/lib/dict.ts +1 -1
  75. package/templates/lib/sig.ts +1 -1
  76. package/templates/lib/srv.ts +6 -2
  77. package/templates/lib/useClient.ts +9 -3
  78. package/templates/module/__Model__.Util.tsx +1 -1
  79. package/templates/module/__Model__.Zone.tsx +3 -5
  80. package/templates/workspaceRoot/AGENTS.md.template +0 -831
  81. package/templates/workspaceRoot/CLAUDE.md.template +19 -0
  82. package/templates/workspaceRoot/biome.json.template +4 -217
  83. package/{typeChecker-kravn7ns.js → typeChecker-g6bh0xfv.js} +1 -1
  84. package/typecheck.proc.js +1 -1
  85. package/{workflow.command-jswbgk90.js → workflow.command-g2cgcgxn.js} +16 -15
  86. package/{workspace.command-h9wwcjpt.js → workspace.command-f7jerqb2.js} +70 -52
  87. package/templates/libRoot/base/baseLogic.ts +0 -14
  88. package/templates/libRoot/base/index.ts +0 -8
  89. package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
  90. package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -33
  91. package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
  92. package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
  93. package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -17
  94. package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
  95. package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
  96. package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
  97. package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
  98. package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -18
  99. package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -61
  100. package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
  101. package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
  102. package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
  103. package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -58
  104. package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
  105. package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
  106. package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
  107. package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
  108. /package/{index-r24hmh0q.js → index-yb2wsc7f.js} +0 -0
@@ -8,7 +8,7 @@ import {
8
8
  DevGeneratedIndexSync,
9
9
  GraphClientEntryDiscovery,
10
10
  RouteClientBuilder
11
- } from "./index-rh16j3c7.js";
11
+ } from "./index-qnv0aqmm.js";
12
12
  import {
13
13
  HmrWatcher,
14
14
  WatchRootResolver
@@ -16,10 +16,11 @@ import {
16
16
  import {
17
17
  AppExecutor,
18
18
  WorkspaceExecutor
19
- } from "./index-jtm86byd.js";
20
- import"./index-6pz1j0zj.js";
19
+ } from "./index-8vkkm7v0.js";
20
+ import"./index-mxvakhsm.js";
21
+ import"./index-1577bej2.js";
21
22
  import"./index-67546d0j.js";
22
- import"./index-r24hmh0q.js";
23
+ import"./index-yb2wsc7f.js";
23
24
 
24
25
  // pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts
25
26
  import path2 from "path";
@@ -249,7 +250,7 @@ class IncrementalBuilder {
249
250
  return;
250
251
  this.#shuttingDown = true;
251
252
  const started = Date.now();
252
- this.#logger.info(`shutdown requested (${reason}); draining ${this.#inFlight} work item(s)`);
253
+ this.#logger.debug(`shutdown requested (${reason}); draining ${this.#inFlight} work item(s)`);
253
254
  if (this.#cssRebuildTimer) {
254
255
  clearTimeout(this.#cssRebuildTimer);
255
256
  this.#cssRebuildTimer = null;
@@ -262,7 +263,7 @@ class IncrementalBuilder {
262
263
  return;
263
264
  });
264
265
  const flushed = await BuilderChannel.drain();
265
- this.#logger.info(`drained in ${Date.now() - started}ms${flushed ? ` after flushing ${flushed} ipc write(s)` : ""}; exiting for recycle`);
266
+ this.#logger.debug(`drained in ${Date.now() - started}ms${flushed ? ` after flushing ${flushed} ipc write(s)` : ""}; exiting for recycle`);
266
267
  process.exit(0);
267
268
  }
268
269
  get shuttingDown() {
@@ -1,22 +1,22 @@
1
1
  // @bun
2
2
  import {
3
3
  RepairRunner
4
- } from "./index-b978vs2e.js";
4
+ } from "./index-xyrb7pk5.js";
5
5
  import {
6
6
  WorkflowRunner
7
- } from "./index-csqk9z5j.js";
7
+ } from "./index-3dp7x6rc.js";
8
+ import {
9
+ ScalarScript
10
+ } from "./index-x33gnap3.js";
8
11
  import {
9
12
  PrimitiveScript
10
- } from "./index-r4w8cry5.js";
13
+ } from "./index-9jsnb4vw.js";
11
14
  import {
12
15
  ModuleScript
13
- } from "./index-vhv3xnjz.js";
14
- import {
15
- ScalarScript
16
- } from "./index-fmgbwsr5.js";
16
+ } from "./index-mykmf6wd.js";
17
17
  import {
18
18
  isPlaceholderAppId
19
- } from "./index-y0k42k04.js";
19
+ } from "./index-mz5jtaq7.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-g9e2fhw2.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-tsmjxph2.js";
38
38
  import {
39
39
  Prompter
40
- } from "./index-xwgm94zr.js";
40
+ } from "./index-j37qq1f2.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-n706txcv.js";
49
49
  import {
50
50
  AppExecutor
51
- } from "./index-jtm86byd.js";
51
+ } from "./index-8vkkm7v0.js";
52
52
 
53
53
  // pkgs/@akanjs/cli/context/context.script.ts
54
54
  import { Logger } from "akanjs/common";
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ // pkgs/@akanjs/devkit/getDirname.ts
3
+ import path from "path";
4
+ import { fileURLToPath } from "url";
5
+ var getDirname = (url) => path.dirname(fileURLToPath(url));
6
+
7
+ export { getDirname };
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-jk9q6pse.js";
5
+ } from "./index-n706txcv.js";
6
6
  import {
7
7
  PkgExecutor
8
- } from "./index-jtm86byd.js";
8
+ } from "./index-8vkkm7v0.js";
9
9
  import {
10
10
  TypeScriptDependencyScanner
11
11
  } from "./index-46tjzh6s.js";
@@ -163,13 +163,17 @@ class PackageRunner extends runner("package") {
163
163
  "tailwind-scrollbar"
164
164
  ].filter((dep) => dep !== "akanjs" && dep !== "@akanjs/devkit");
165
165
  }
166
- const bundledRuntimeDeps = new Set(pkg.name === "@akanjs/cli" ? ["@akanjs/devkit"] : []);
166
+ const packageBundledRuntimeDependencies = {
167
+ "@akanjs/cli": ["@akanjs/devkit"],
168
+ akanjs: ["use-agentic"]
169
+ };
170
+ const bundledRuntimeDeps = new Set(packageBundledRuntimeDependencies[pkg.name] ?? []);
167
171
  const forcedRuntimeDeps = packageRuntimeDependencies[pkg.name] ?? [];
168
172
  const forcedRuntimeDevDeps = packageRuntimeDevDependencies[pkg.name] ?? [];
169
173
  const [rootPackageJson, pkgJson] = await Promise.all([pkg.workspace.getPackageJson(), pkg.getPackageJson()]);
170
174
  const optionalPeerDeps = new Set(Object.entries(pkgJson.peerDependenciesMeta ?? {}).filter(([, meta]) => meta.optional).map(([dep]) => dep));
171
175
  const packageRuntimeDeps = [...new Set([...npmDeps, ...forcedRuntimeDeps])].filter((dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep));
172
- const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])].filter((dep) => !optionalPeerDeps.has(dep));
176
+ const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])].filter((dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep));
173
177
  const rootDeps = { ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies };
174
178
  const missingForcedDeps = forcedRuntimeDeps.filter((dep) => !rootDeps[dep]);
175
179
  const missingForcedDevDeps = forcedRuntimeDevDeps.filter((dep) => !rootDeps[dep]);
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-4yp06pn1.js";
4
+ } from "./index-g9e2fhw2.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-4zgs8g1w.js";
26
+ } from "./index-tsmjxph2.js";
27
27
  import {
28
28
  runner
29
- } from "./index-jk9q6pse.js";
29
+ } from "./index-n706txcv.js";
30
30
 
31
31
  // pkgs/@akanjs/cli/workflow/workflow.runner.ts
32
32
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -2,16 +2,17 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-jk9q6pse.js";
5
+ } from "./index-n706txcv.js";
6
6
  import {
7
7
  LibExecutor
8
- } from "./index-jtm86byd.js";
8
+ } from "./index-8vkkm7v0.js";
9
9
 
10
10
  // pkgs/@akanjs/cli/semver.ts
11
- function parseVersion(version) {
11
+ var stripRangeOperator = (version) => version.replace(/^[\s^~>=<v]+/, "").trim();
12
+ var parseVersion = (version) => {
12
13
  return version.replace(/^[^\d]*/, "").split(/[.-]/).map((part) => Number.parseInt(part, 10)).map((part) => Number.isFinite(part) ? part : 0);
13
- }
14
- function compareSemver(a, b) {
14
+ };
15
+ var compareNumeric = (a, b) => {
15
16
  const left = parseVersion(a);
16
17
  const right = parseVersion(b);
17
18
  const length = Math.max(left.length, right.length);
@@ -21,7 +22,14 @@ function compareSemver(a, b) {
21
22
  return diff > 0 ? 1 : -1;
22
23
  }
23
24
  return 0;
24
- }
25
+ };
26
+ var compareSemver = (a, b) => {
27
+ try {
28
+ return Bun.semver.order(stripRangeOperator(a), stripRangeOperator(b));
29
+ } catch {
30
+ return compareNumeric(a, b);
31
+ }
32
+ };
25
33
 
26
34
  // pkgs/@akanjs/cli/library/library.runner.ts
27
35
  class LibraryRunner extends runner("library") {
@@ -70,7 +78,7 @@ class LibraryRunner extends runner("library") {
70
78
  return [dep, newerVersion];
71
79
  }));
72
80
  Object.keys(allDependencies).sort().forEach((dep) => {
73
- if (!!libPackageJson.dependencies?.[dep] || !!rootPackageJson.dependencies?.[dep])
81
+ if (libPackageJson.dependencies?.[dep] || rootPackageJson.dependencies?.[dep])
74
82
  dependencies[dep] = allDependencies[dep];
75
83
  else
76
84
  devDependencies[dep] = allDependencies[dep];
@@ -1,14 +1,14 @@
1
1
  // @bun
2
+ import {
3
+ LibraryScript
4
+ } from "./index-73rnbwgg.js";
2
5
  import {
3
6
  resolveMobileTargets
4
7
  } from "./index-76rn3g2c.js";
5
- import {
6
- LibraryScript
7
- } from "./index-cn24dcqn.js";
8
8
  import {
9
9
  runner,
10
10
  script
11
- } from "./index-jk9q6pse.js";
11
+ } from "./index-n706txcv.js";
12
12
  import {
13
13
  HmrWatcher,
14
14
  WatchRootResolver
@@ -18,10 +18,10 @@ import {
18
18
  LibExecutor,
19
19
  PkgExecutor,
20
20
  WorkspaceExecutor
21
- } from "./index-jtm86byd.js";
21
+ } from "./index-8vkkm7v0.js";
22
22
  import {
23
23
  __require
24
- } from "./index-r24hmh0q.js";
24
+ } from "./index-yb2wsc7f.js";
25
25
 
26
26
  // pkgs/@akanjs/devkit/applicationBuildReporter.ts
27
27
  import { Logger } from "akanjs/common";
@@ -350,7 +350,7 @@ class IncrementalBuilderHost {
350
350
  return false;
351
351
  this.#recycleRequested = true;
352
352
  this.#status = "recycling";
353
- this.logger.info(`recycling builder pid=${proc.pid} (${reason})`);
353
+ this.logger.debug(`recycling builder pid=${proc.pid} (${reason})`);
354
354
  this.#recycleTimer = setTimeout(() => {
355
355
  this.#recycleTimer = null;
356
356
  if (this.#proc !== proc)
@@ -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-7gnfz7ww.js")).ApplicationBuildRunner;
1902
+ var loadReleasePackager = async () => (await import("./applicationReleasePackager-93nzdfsy.js")).ApplicationReleasePackager;
1903
+ var loadCapacitorApp = async () => (await import("./capacitorApp-qv7g3dp2.js")).CapacitorApp;
1904
+ var loadAbstractCompactor = async () => (await import("./abstractCompactor-20e0cwbs.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, "error");
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, "error");
2546
+ }
2524
2547
  async testSys(sys) {
2525
2548
  if (sys.type === "app")
2526
2549
  await this.testApplication(sys);