@akanjs/cli 3.0.0-alpha.0 → 3.0.0-alpha.10

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 (89) 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-f0gqkfgz.js} +8 -7
  4. package/{application.command-3smsv7mq.js → application.command-x903m2qq.js} +6 -5
  5. package/{applicationBuildRunner-aq7mb3z6.js → applicationBuildRunner-ha3y8ew8.js} +4 -4
  6. package/{applicationReleasePackager-yrrhbkv3.js → applicationReleasePackager-gg8ccbeh.js} +1 -1
  7. package/buildBatch.proc.js +5 -4
  8. package/{capacitorApp-q3mpmkkz.js → capacitorApp-9xswcgx7.js} +6 -3
  9. package/{cloud.command-rk4e9vrt.js → cloud.command-zs6kyf83.js} +10 -9
  10. package/{context.command-ygzyb0xb.js → context.command-fmepgjzg.js} +16 -15
  11. package/getDirname-m9s0cmhq.js +8 -0
  12. package/{guideline.command-1m1ctar3.js → guideline.command-n6sw0a0c.js} +6 -5
  13. package/guidelines/conventions/conventions.generate.json +25 -0
  14. package/guidelines/conventions/conventions.instruction.md +668 -0
  15. package/guidelines/ssrRule/ssrRule.generate.json +31 -0
  16. package/guidelines/ssrRule/ssrRule.instruction.md +108 -0
  17. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
  18. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +972 -0
  19. package/incrementalBuilder.proc.js +4 -3
  20. package/{index-3pgtw35d.js → index-0cj2zxbm.js} +1 -1
  21. package/index-1577bej2.js +7 -0
  22. package/{index-r4w8cry5.js → index-3vta1tqa.js} +4 -4
  23. package/{index-ktprgc5g.js → index-4m0bphac.js} +4 -4
  24. package/{index-h0bngh79.js → index-5sn5w2mt.js} +13 -13
  25. package/{index-ev6rjw9n.js → index-62955kn5.js} +37 -14
  26. package/{index-4yp06pn1.js → index-774gcx29.js} +49 -32
  27. package/{index-sggm9qkv.js → index-779ske1y.js} +86 -17
  28. package/{index-f4gqk0dd.js → index-82jrh4hj.js} +6 -6
  29. package/{index-cn24dcqn.js → index-d43t8af2.js} +2 -2
  30. package/{index-n0z3f2xg.js → index-eyyf2149.js} +34 -6
  31. package/{index-e3qskyt2.js → index-gcv8ncfh.js} +2 -2
  32. package/{index-xwgm94zr.js → index-j37qq1f2.js} +1 -1
  33. package/{index-rh16j3c7.js → index-j9cxndc0.js} +3 -2
  34. package/{index-b978vs2e.js → index-jf2ya7r2.js} +3 -3
  35. package/{index-vhv3xnjz.js → index-jhpa13zj.js} +8 -8
  36. package/{index-jk9q6pse.js → index-kdh76j26.js} +4 -2
  37. package/{index-6pz1j0zj.js → index-mxvakhsm.js} +6 -2
  38. package/{index-pyt2b4nw.js → index-qb61h0k7.js} +52 -17
  39. package/{index-csqk9z5j.js → index-qzdjd4ct.js} +3 -3
  40. package/{index-4zgs8g1w.js → index-rxkpk7n4.js} +1 -1
  41. package/{index-hjzr8ja1.js → index-xmmzf150.js} +1 -1
  42. package/{index-fmgbwsr5.js → index-y4vkyhvv.js} +4 -4
  43. package/{index-jtm86byd.js → index-z8ptfkzv.js} +84 -40
  44. package/index.js +20 -19
  45. package/{library.command-pwfx8dx2.js → library.command-cv9gdbmg.js} +5 -4
  46. package/{localRegistry.command-bxhqmd1d.js → localRegistry.command-d8fg36zc.js} +9 -8
  47. package/{module.command-0t3ewata.js → module.command-qyr1s9cn.js} +9 -8
  48. package/{package.command-7hmkxvpa.js → package.command-wsjx0k47.js} +5 -4
  49. package/package.json +2 -2
  50. package/{page.command-st6r4s0q.js → page.command-rdzg65rm.js} +5 -4
  51. package/{primitive.command-1qkxpzsn.js → primitive.command-89g38b53.js} +10 -9
  52. package/{quality.command-hy5vt1bh.js → quality.command-0cs2z92d.js} +459 -86
  53. package/{repair.command-nakkq2zp.js → repair.command-6fphxfwj.js} +7 -6
  54. package/{routeSourceValidator-cncd92fv.js → routeSourceValidator-e4jmbfcx.js} +2 -38
  55. package/{scalar.command-fjq272gs.js → scalar.command-xfer69s6.js} +8 -7
  56. package/templates/app/page/styles.css.template +3 -3
  57. package/templates/crudPages/[__model__Id]/edit/page.tsx +1 -1
  58. package/templates/crudPages/new/page.tsx +1 -1
  59. package/templates/crudSinglePage/page.tsx +1 -1
  60. package/templates/lib/db.ts +3 -1
  61. package/templates/lib/useClient.ts +9 -3
  62. package/templates/module/__Model__.Util.tsx +1 -1
  63. package/templates/module/__Model__.Zone.tsx +3 -5
  64. package/templates/workspaceRoot/AGENTS.md.template +0 -827
  65. package/templates/workspaceRoot/biome.json.template +3 -198
  66. package/templates/workspaceRoot/docs/AI-DEVELOPMENT.md.template +4 -1
  67. package/{workflow.command-jswbgk90.js → workflow.command-2ygfqt4f.js} +15 -14
  68. package/{workspace.command-p9r9nckg.js → workspace.command-vbgpjkf9.js} +37 -35
  69. package/templates/libRoot/base/baseLogic.ts +0 -14
  70. package/templates/libRoot/base/index.ts +0 -8
  71. package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
  72. package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -33
  73. package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
  74. package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
  75. package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -17
  76. package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
  77. package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
  78. package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
  79. package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
  80. package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -18
  81. package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -61
  82. package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
  83. package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
  84. package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
  85. package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -58
  86. package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
  87. package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
  88. package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
  89. package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
@@ -1,22 +1,24 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-4yp06pn1.js";
4
+ } from "./index-774gcx29.js";
5
5
  import {
6
6
  Prompter
7
- } from "./index-xwgm94zr.js";
7
+ } from "./index-j37qq1f2.js";
8
8
  import {
9
9
  runner,
10
10
  script
11
- } from "./index-jk9q6pse.js";
11
+ } from "./index-kdh76j26.js";
12
12
  import {
13
13
  AGENT_BLOCK_END,
14
14
  AGENT_BLOCK_START,
15
15
  AppExecutor,
16
16
  LibExecutor,
17
+ readDevkitVersion,
17
18
  renderRecipeEntries,
19
+ stampBlockVersion,
18
20
  upsertAgentBlock
19
- } from "./index-jtm86byd.js";
21
+ } from "./index-z8ptfkzv.js";
20
22
  import {
21
23
  collectRecipeSources,
22
24
  scanRecipes
@@ -103,19 +105,33 @@ ${scopeIndexPointer}
103
105
 
104
106
  `;
105
107
  };
108
+ var renderGuides = async (context) => {
109
+ const conventions = (await Prompter.getInstruction("conventions")).trim();
110
+ if (context.pkgs.some((pkg) => pkg.name === "akanjs"))
111
+ return conventions;
112
+ const onboarding = (await Prompter.getInstruction("workspaceOnboarding")).trim();
113
+ const appName = context.apps[0]?.name ?? "app";
114
+ return `${conventions}
115
+
116
+ ${onboarding.replaceAll("<%= appName %>", appName)}`;
117
+ };
106
118
  var renderManagedBlock = async (workspace) => {
107
119
  const context = await AkanContextAnalyzer.analyze(workspace);
108
120
  const frameworkGuide = await Prompter.getInstruction("framework");
109
121
  const appNames = context.apps.map((app) => app.name);
110
122
  const sampleCleanup = await renderSampleCleanup(workspace, appNames);
111
123
  const recipeIndex = await renderRecipeIndex(workspace);
112
- return `## Workspace
124
+ const guides = await renderGuides(context);
125
+ const version = await readDevkitVersion();
126
+ const block = `## Workspace
113
127
 
114
128
  - Repo: ${context.repoName}
115
129
  - Apps: ${context.apps.map((app) => app.name).join(", ") || "none"}
116
130
  - Libraries: ${context.libs.map((lib) => lib.name).join(", ") || "none"}
117
131
  - Packages: ${context.pkgs.map((pkg) => pkg.name).join(", ") || "none"}
118
132
 
133
+ ${guides}
134
+
119
135
  ${sampleCleanup}## Akan Module Abstracts
120
136
 
121
137
  - Before changing a domain, service, or scalar module, read its \`*.abstract.md\` file first.
@@ -148,7 +164,19 @@ ${context.validationCommands.map((command) => `- \`${command}\``).join(`
148
164
 
149
165
  ## Framework Guide
150
166
 
151
- ${frameworkGuide.trim()}`;
167
+ ${frameworkGuide.trim()}
168
+
169
+ ## Before You Finish
170
+
171
+ 1. \`bun run akan lint <appName>\` \u2014 Tailwind class order, \`Err\`, \`console\`, \`#private\` scope, unused imports.
172
+ 2. \`bun run akan typecheck <appName>\` \u2014 server/client boundary violations.
173
+ 3. \`bun run akan sync <appName>\` if you added, renamed, or deleted any file.
174
+ 4. Did you write or change a \`.tsx\` file? \`bun run akan quality ssr\` \u2014 did the server share hold, and did you add
175
+ a \`"use client"\` you cannot justify?
176
+ 5. Re-read the file you wrote against its section above.
177
+ 6. Did you add a comment? Delete it unless it documents an external constraint or a security decision.
178
+ 7. Did behavior or an invariant change? Update the module's \`*.abstract.md\`.`;
179
+ return version ? stampBlockVersion(block, version) : block;
152
180
  };
153
181
  var renderAgentsMd = async (workspace, existing) => {
154
182
  const block = await renderManagedBlock(workspace);
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-jk9q6pse.js";
5
+ } from "./index-kdh76j26.js";
6
6
  import {
7
7
  PkgExecutor
8
- } from "./index-jtm86byd.js";
8
+ } from "./index-z8ptfkzv.js";
9
9
  import {
10
10
  TypeScriptDependencyScanner
11
11
  } from "./index-46tjzh6s.js";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  getDirname
4
- } from "./index-jtm86byd.js";
4
+ } from "./index-1577bej2.js";
5
5
 
6
6
  // pkgs/@akanjs/devkit/prompter.ts
7
7
  import fsPromise from "fs/promises";
@@ -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);
@@ -1,17 +1,17 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-4yp06pn1.js";
4
+ } from "./index-774gcx29.js";
5
5
  import {
6
6
  createRepairReport,
7
7
  generatedFilePathsForTarget,
8
8
  renderRepairReport,
9
9
  writeGeneratedSyncState,
10
10
  writeWorkflowRunArtifact
11
- } from "./index-4zgs8g1w.js";
11
+ } from "./index-rxkpk7n4.js";
12
12
  import {
13
13
  runner
14
- } from "./index-jk9q6pse.js";
14
+ } from "./index-kdh76j26.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/repair/repair.runner.ts
17
17
  var commandForShell = (command) => command.startsWith("akan ") ? `bun run ${command}` : command;
@@ -1,13 +1,13 @@
1
1
  // @bun
2
- import {
3
- PageScript
4
- } from "./index-hjzr8ja1.js";
5
2
  import {
6
3
  pluralizeName
7
4
  } from "./index-ss469dec.js";
5
+ import {
6
+ PageScript
7
+ } from "./index-xmmzf150.js";
8
8
  import {
9
9
  AiSession
10
- } from "./index-3pgtw35d.js";
10
+ } from "./index-0cj2zxbm.js";
11
11
  import {
12
12
  bilingualDescriptionForField,
13
13
  bilingualLabelForField,
@@ -15,17 +15,17 @@ import {
15
15
  generatedFilesForSync,
16
16
  moduleSourcePaths,
17
17
  sourceFile
18
- } from "./index-4zgs8g1w.js";
18
+ } from "./index-rxkpk7n4.js";
19
19
  import {
20
20
  Prompter
21
- } from "./index-xwgm94zr.js";
21
+ } from "./index-j37qq1f2.js";
22
22
  import {
23
23
  runner,
24
24
  script
25
- } from "./index-jk9q6pse.js";
25
+ } from "./index-kdh76j26.js";
26
26
  import {
27
27
  ModuleExecutor
28
- } from "./index-jtm86byd.js";
28
+ } from "./index-z8ptfkzv.js";
29
29
  import {
30
30
  FileSys
31
31
  } from "./index-67546d0j.js";
@@ -5,9 +5,11 @@ import {
5
5
  LibExecutor,
6
6
  ModuleExecutor,
7
7
  PkgExecutor,
8
- WorkspaceExecutor,
8
+ WorkspaceExecutor
9
+ } from "./index-z8ptfkzv.js";
10
+ import {
9
11
  getDirname
10
- } from "./index-jtm86byd.js";
12
+ } from "./index-1577bej2.js";
11
13
  import {
12
14
  FileSys
13
15
  } from "./index-67546d0j.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;
@@ -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 = 1;
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
  AkanContextAnalyzer
4
- } from "./index-4yp06pn1.js";
4
+ } from "./index-774gcx29.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-rxkpk7n4.js";
27
27
  import {
28
28
  runner
29
- } from "./index-jk9q6pse.js";
29
+ } from "./index-kdh76j26.js";
30
30
 
31
31
  // pkgs/@akanjs/cli/workflow/workflow.runner.ts
32
32
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-jtm86byd.js";
5
+ } from "./index-z8ptfkzv.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,7 +2,7 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-jk9q6pse.js";
5
+ } from "./index-kdh76j26.js";
6
6
 
7
7
  // pkgs/@akanjs/cli/page/page.runner.ts
8
8
  class PageRunner extends runner("page") {
@@ -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-rxkpk7n4.js";
13
13
  import {
14
14
  Prompter
15
- } from "./index-xwgm94zr.js";
15
+ } from "./index-j37qq1f2.js";
16
16
  import {
17
17
  runner,
18
18
  script
19
- } from "./index-jk9q6pse.js";
19
+ } from "./index-kdh76j26.js";
20
20
 
21
21
  // pkgs/@akanjs/cli/scalar/scalar.prompt.ts
22
22
  import { input } from "@inquirer/prompts";