@akanjs/cli 3.1.0-rc.2 → 3.1.0-rc.21

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 (103) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-q50k4s45.js → CodeAgent-gzfc5t52.js} +2 -2
  3. package/{CodeAgentRpcHost-p7h6n2hp.js → CodeAgentRpcHost-9g27hmer.js} +1 -1
  4. package/{CodeTui-62g35ztk.js → CodeTui-bpsjs8wz.js} +47 -4
  5. package/TunnelShare-tfrnftgr.js +14 -0
  6. package/{agent.command-adfd5299.js → agent.command-67ysh3n6.js} +5 -5
  7. package/akanCode.js +7 -5
  8. package/{application.command-hj3gv1rx.js → application.command-q0tqw5pc.js} +38 -11
  9. package/{applicationBuildRunner-by10r9gf.js → applicationBuildRunner-wsszr305.js} +16 -9
  10. package/buildBatch.proc.js +7 -7
  11. package/{cloud.command-k2fhaape.js → cloud.command-e7tkxyx6.js} +17 -16
  12. package/cloud.script-krzh3d7k.js +24 -0
  13. package/{code.command-kt5zgcc2.js → code.command-ttk8tje2.js} +25 -12
  14. package/commandManifest.json +1 -1
  15. package/{context.command-8fgn42jw.js → context.command-bdsk2z2r.js} +17 -16
  16. package/context.runner-bxzv0gm0.js +25 -0
  17. package/{dependencyScanner-06z2dmrr.js → dependencyScanner-3afj2vt1.js} +1 -1
  18. package/{guideline.command-3yxxr2mm.js → guideline.command-man90n70.js} +2 -2
  19. package/guidelines/agentRule/agentRule.instruction.md +25 -10
  20. package/guidelines/conventions/conventions.instruction.md +486 -1084
  21. package/guidelines/cssRule/cssRule.instruction.md +16 -1
  22. package/guidelines/fieldRule/fieldRule.instruction.md +74 -0
  23. package/guidelines/framework/framework.instruction.md +4 -7
  24. package/guidelines/mcpRule/mcpRule.instruction.md +16 -9
  25. package/guidelines/modelConstant/modelConstant.instruction.md +2 -1
  26. package/guidelines/modelStore/modelStore.instruction.md +16 -0
  27. package/guidelines/pageRule/pageRule.instruction.md +80 -0
  28. package/guidelines/queryRule/queryRule.instruction.md +47 -12
  29. package/guidelines/runtimeRule/runtimeRule.instruction.md +89 -2
  30. package/guidelines/ssrRule/ssrRule.instruction.md +13 -0
  31. package/guidelines/transportRule/transportRule.instruction.md +107 -8
  32. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +4 -4
  33. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +70 -7
  34. package/incrementalBuilder.proc.js +4 -4
  35. package/{index-rhbabmja.js → index-033wne2j.js} +260 -259
  36. package/{index-xpdgxsj5.js → index-1r5a8bzx.js} +2216 -2216
  37. package/{index-jwqtchha.js → index-27y8t17p.js} +1 -1
  38. package/{index-wa5jbxj1.js → index-2mrn1mrg.js} +1 -0
  39. package/{index-t7nws9mx.js → index-2w8j2fnv.js} +661 -448
  40. package/{index-0909wckt.js → index-35m6bzm7.js} +238 -236
  41. package/{index-sqfdmb5b.js → index-4393nb4b.js} +4 -4
  42. package/{index-sby8fe1p.js → index-48edp6q4.js} +1 -1
  43. package/{index-g0vwzy9m.js → index-4v43h00g.js} +20 -21
  44. package/{index-azh29dc8.js → index-54wc2phm.js} +19 -14
  45. package/{index-k9rrten6.js → index-5nd1wtkv.js} +92 -94
  46. package/index-62md4dwy.js +260 -0
  47. package/{index-hnby7p9n.js → index-75n5q4ph.js} +7 -7
  48. package/{index-fjsv10hd.js → index-844q7f8z.js} +7 -7
  49. package/{index-tv8fjaba.js → index-8jehkey8.js} +4 -4
  50. package/{index-bea2gwc6.js → index-9mt4smfy.js} +2 -2
  51. package/{index-d2242ksy.js → index-at7bz0xq.js} +3 -0
  52. package/{index-3hx1z96c.js → index-bqbf654f.js} +1 -1
  53. package/{index-8zdwpxef.js → index-cae9m5jz.js} +119 -81
  54. package/{index-tz5evhdr.js → index-ebarbgba.js} +6 -6
  55. package/{index-2etqq75t.js → index-g6ax17x4.js} +1114 -1082
  56. package/{index-h85cxfkg.js → index-g9ks2k8c.js} +2 -2
  57. package/{index-nq045px5.js → index-h3r3nr9y.js} +356 -307
  58. package/{index-20cebtth.js → index-h6czey01.js} +79 -24
  59. package/{index-6726qr1m.js → index-jrmzcp66.js} +57 -58
  60. package/{index-q958tqqg.js → index-m9jj544v.js} +1 -1
  61. package/{index-8935h3n1.js → index-mdjc93e1.js} +1 -1
  62. package/{index-rk9sdys3.js → index-nv79n88g.js} +5 -5
  63. package/{index-kc8z134d.js → index-nx64dz92.js} +38 -15
  64. package/{index-z507nzhg.js → index-p2r64bpa.js} +4 -4
  65. package/{index-nq2ja5e0.js → index-pg1t468s.js} +3 -3
  66. package/{index-3reaaa1h.js → index-rc51f9ht.js} +29 -27
  67. package/{index-e9prnmyt.js → index-ta1dychm.js} +3 -3
  68. package/{index-2ahj896a.js → index-tvehn2sp.js} +1 -1
  69. package/{index-31ce9vhg.js → index-vkb9m4z7.js} +80 -38
  70. package/{index-58vvz603.js → index-xsd96yzw.js} +1 -1
  71. package/{index-pyxn1b53.js → index-zv5s8x58.js} +13 -13
  72. package/index.js +22 -22
  73. package/{library.command-8tw59xzj.js → library.command-6amzsrb8.js} +3 -3
  74. package/{localRegistry.command-tf3dmznd.js → localRegistry.command-yqc0nyhh.js} +15 -14
  75. package/{module.command-9vm8hffy.js → module.command-10x6jv6c.js} +5 -5
  76. package/{package.command-erbxe2tz.js → package.command-pwfvecjf.js} +4 -4
  77. package/package.json +21 -21
  78. package/{page.command-jpavcj0p.js → page.command-ahhgx9y1.js} +3 -3
  79. package/{pipeline.command-b8rzvjvv.js → pipeline.command-1ptr3e9y.js} +3 -3
  80. package/{primitive.command-sm32chzk.js → primitive.command-g5xwv6tj.js} +6 -6
  81. package/{projectTypecheck-jamtx95x.js → projectTypecheck-fx8x7cat.js} +1 -1
  82. package/{quality.command-pkd17n6y.js → quality.command-fw9ck061.js} +4 -4
  83. package/{repair.command-8y4mq6hs.js → repair.command-g8kecj96.js} +5 -5
  84. package/{scalar.command-q8khmyx5.js → scalar.command-fprap51w.js} +4 -4
  85. package/skills/akan-code/SKILL.md +4 -0
  86. package/skills/akan-store/SKILL.md +2 -1
  87. package/{subspace.command-51n0ykbx.js → subspace.command-sc0t527y.js} +11 -10
  88. package/templates/appSample/lib/task/Task.Util.tsx +7 -7
  89. package/templates/appSample/lib/task/Task.Zone.tsx +1 -1
  90. package/templates/appSample/ui/QuantityControl.tsx +2 -2
  91. package/templates/crudSinglePage/page.tsx +1 -1
  92. package/templates/lib/cnst.ts +0 -1
  93. package/templates/migration/__migrationId__.ts +23 -0
  94. package/templates/server.ts +8 -1
  95. package/templates/workspaceRoot/.gitignore.template +23 -52
  96. package/templates/workspaceRoot/biome.json.template +1 -1
  97. package/{tunnel.command-7820vtxq.js → tunnel.command-mqnsqbwf.js} +8 -7
  98. package/{workflow.command-n5sv4wqz.js → workflow.command-j0jgkr13.js} +10 -10
  99. package/{workspace.command-zdy60jh8.js → workspace.command-1r9hvvw0.js} +29 -28
  100. package/TunnelShare-f1egrktx.js +0 -13
  101. package/cloud.script-z8p5dz7e.js +0 -23
  102. package/context.runner-hnh0rg7m.js +0 -24
  103. package/index-n68jx79w.js +0 -120
@@ -35,44 +35,47 @@ import {
35
35
  filesChangedSince,
36
36
  HmrWatcher,
37
37
  WatchRootResolver
38
- } from "./index-k9rrten6.js";
38
+ } from "./index-5nd1wtkv.js";
39
39
  import {
40
40
  runner,
41
41
  script,
42
+ markCliErrorPrinted,
42
43
  assertPromptable
43
- } from "./index-31ce9vhg.js";
44
+ } from "./index-vkb9m4z7.js";
44
45
  import {
46
+ AppInfo,
47
+ CommandExecutionError,
45
48
  WorkspaceExecutor,
46
49
  AppExecutor,
47
50
  LibExecutor,
48
51
  PkgExecutor
49
- } from "./index-2etqq75t.js";
52
+ } from "./index-g6ax17x4.js";
50
53
  import {
51
54
  DesktopServerStage,
52
55
  UpdateUploader
53
- } from "./index-g0vwzy9m.js";
56
+ } from "./index-4v43h00g.js";
57
+ import {
58
+ resolveMobileTargets,
59
+ resolveAppId
60
+ } from "./index-m9jj544v.js";
54
61
  import {
55
62
  NativePublicEnv,
56
63
  UpdatePackFolder,
57
64
  NativeApp
58
- } from "./index-0909wckt.js";
65
+ } from "./index-35m6bzm7.js";
59
66
  import {
60
67
  LibraryScript
61
- } from "./index-bea2gwc6.js";
68
+ } from "./index-9mt4smfy.js";
62
69
  import {
63
70
  stripAnsi
64
71
  } from "./index-7md2g9vw.js";
65
72
  import {
66
73
  SlicePlanner,
67
74
  formatSlicePlan
68
- } from "./index-58vvz603.js";
75
+ } from "./index-xsd96yzw.js";
69
76
  import {
70
77
  openBrowser
71
78
  } from "./index-9dp031by.js";
72
- import {
73
- resolveMobileTargets,
74
- resolveAppId
75
- } from "./index-q958tqqg.js";
76
79
 
77
80
  // pkgs/@akanjs/cli/application/application.script.ts
78
81
  import { confirm } from "@inquirer/prompts";
@@ -196,7 +199,9 @@ var closeBunSocket = (socket, error) => {
196
199
 
197
200
  // pkgs/@akanjs/devkit/createTunnel.ts
198
201
  var createTunnel = async (service, { app, environment, port = service === "postgres" ? 5432 : 6379 }) => {
199
- const { serveDomain, repoName } = WorkspaceExecutor.getBaseDevEnv();
202
+ const baseDevEnv = WorkspaceExecutor.getBaseDevEnv();
203
+ WorkspaceExecutor.assertDeployableEnv(baseDevEnv, environment, `The ${service} tunnel`);
204
+ const { serveDomain, repoName } = baseDevEnv;
200
205
  const host = `${app.name}-${environment}.${serveDomain}`;
201
206
  const sshPort = process.env.SSH_TUNNEL_PORT ? parseInt(process.env.SSH_TUNNEL_PORT) : 32767;
202
207
  const dstHost = `${service}-0.${service}-svc.${app.name}-${environment}.svc.cluster.local`;
@@ -1894,7 +1899,7 @@ ${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
1894
1899
 
1895
1900
  // pkgs/@akanjs/cli/application/application.runner.ts
1896
1901
  import { Logger as Logger3, toError } from "akanjs/common";
1897
- var loadBuildRunner = async () => (await import("./applicationBuildRunner-by10r9gf.js")).ApplicationBuildRunner;
1902
+ var loadBuildRunner = async () => (await import("./applicationBuildRunner-wsszr305.js")).ApplicationBuildRunner;
1898
1903
  var loadPrompts = async () => await import("@inquirer/prompts");
1899
1904
 
1900
1905
  class ApplicationRunner extends runner("application") {
@@ -1936,8 +1941,12 @@ class ApplicationRunner extends runner("application") {
1936
1941
  const scriptPath = `script/${scriptName}.ts`;
1937
1942
  if (!await app.exists(scriptPath))
1938
1943
  throw new Error(`Script file not found: apps/${app.name}/${scriptPath}`);
1939
- await app.spawn("bun", [scriptPath], {
1940
- env: app.getCommandEnv({ AKAN_COMMAND_TYPE: "script", ...await app.getDatabaseModeEnv() }),
1944
+ await this.#spawnFromRoot(app, "script", [`${app.cwdPath}/${scriptPath}`]);
1945
+ }
1946
+ async#spawnFromRoot(app, commandType, args) {
1947
+ await app.spawn("bun", args, {
1948
+ cwd: app.workspace.workspaceRoot,
1949
+ env: app.getCommandEnv({ AKAN_COMMAND_TYPE: commandType, ...await app.getDatabaseModeEnv() }),
1941
1950
  stdio: "inherit"
1942
1951
  });
1943
1952
  }
@@ -2024,10 +2033,7 @@ try {
2024
2033
  await server.stop();
2025
2034
  }
2026
2035
  `;
2027
- await app.spawn("bun", ["-e", code], {
2028
- env: app.getCommandEnv({ AKAN_COMMAND_TYPE: "console", ...await app.getDatabaseModeEnv() }),
2029
- stdio: "inherit"
2030
- });
2036
+ await this.#spawnFromRoot(app, "console", ["-e", code]);
2031
2037
  }
2032
2038
  async transferDatabase(app, direction, dir) {
2033
2039
  const serverPath = `${app.cwdPath}/server.ts`;
@@ -2046,16 +2052,55 @@ try {
2046
2052
  await server.stop();
2047
2053
  }
2048
2054
  `;
2049
- await app.spawn("bun", ["-e", code], {
2050
- env: app.getCommandEnv({ AKAN_COMMAND_TYPE: "script", ...await app.getDatabaseModeEnv() }),
2051
- stdio: "inherit"
2055
+ await this.#spawnFromRoot(app, "script", ["-e", code]);
2056
+ }
2057
+ async migrate(app, argv) {
2058
+ const serverPath = `${app.cwdPath}/server.ts`;
2059
+ if (!await app.exists("server.ts"))
2060
+ throw new Error(`Server file not found: apps/${app.name}/server.ts`);
2061
+ const code = `
2062
+ const argv = ${JSON.stringify(argv)};
2063
+ let loaded;
2064
+ try {
2065
+ loaded = await import(${JSON.stringify(serverPath)});
2066
+ } catch (error) {
2067
+ console.error(error);
2068
+ const { MigrationCommand } = await import("akanjs/server");
2069
+ process.exitCode = await MigrationCommand.print(MigrationCommand.failure(null, error), MigrationCommand.jsonOf(argv));
2070
+ }
2071
+ if (loaded) process.exitCode = await loaded.migrations.command(loaded.server, argv, ${JSON.stringify(`akan migrate ${app.name}`)});
2072
+ `;
2073
+ try {
2074
+ await this.#spawnFromRoot(app, "script", ["-e", code]);
2075
+ } catch (error) {
2076
+ if (!(error instanceof CommandExecutionError) || error.code === null)
2077
+ throw error;
2078
+ process.exitCode = error.code;
2079
+ }
2080
+ }
2081
+ async createMigration(app, migrationName, now = new Date) {
2082
+ const words = migrationName.split(/[^A-Za-z0-9]+/).filter(Boolean);
2083
+ const name = words.map((word, idx) => (idx ? word.charAt(0).toUpperCase() : word.charAt(0).toLowerCase()) + word.slice(1)).join("");
2084
+ if (!/^[A-Za-z][A-Za-z0-9]*$/.test(name))
2085
+ throw new Error(`"${migrationName}" is no migration name; name what it does in camelCase, e.g. bizLicenseOwnership`);
2086
+ const migrationId = `${now.toISOString().replace(/\D/g, "").slice(0, 12)}_${name}`;
2087
+ const filePath = `${AppInfo.migrationDir}/${migrationId}.ts`;
2088
+ if (await app.exists(filePath))
2089
+ throw new Error(`apps/${app.name}/${filePath} already exists`);
2090
+ const title = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase();
2091
+ await app.applyTemplate({
2092
+ basePath: AppInfo.migrationDir,
2093
+ template: "migration",
2094
+ dict: { migrationId, title: title.charAt(0).toUpperCase() + title.slice(1) },
2095
+ overwrite: false
2052
2096
  });
2097
+ return migrationId;
2053
2098
  }
2054
2099
  async typecheck(app, options = {}) {
2055
2100
  await new (await loadBuildRunner())(app).typecheck(options);
2056
2101
  }
2057
2102
  async typecheckLibrary(lib, options = {}) {
2058
- const { ProjectTypecheck } = await import("./projectTypecheck-jamtx95x.js");
2103
+ const { ProjectTypecheck } = await import("./projectTypecheck-fx8x7cat.js");
2059
2104
  const root = lib.workspace.workspaceRoot;
2060
2105
  await new ProjectTypecheck(lib.cwdPath, root, { ...process.env, AKAN_WORKSPACE_ROOT: root }).run([
2061
2106
  "../../server.ts",
@@ -3337,6 +3382,14 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3337
3382
  await app.scanSync();
3338
3383
  await this.applicationRunner.runConsole(app);
3339
3384
  }
3385
+ async migrate(app, argv) {
3386
+ await app.scanSync();
3387
+ await this.applicationRunner.migrate(app, argv);
3388
+ }
3389
+ async createMigration(app, migrationName) {
3390
+ const migrationId = await this.applicationRunner.createMigration(app, migrationName);
3391
+ Logger6.rawLog(`Created apps/${app.name}/script/migration/${migrationId}.ts; plan it with \`akan migrate ${app.name} plan ${migrationId}\``);
3392
+ }
3340
3393
  async logs(app, options) {
3341
3394
  await this.applicationRunner.runLogs(app, options);
3342
3395
  }
@@ -3357,6 +3410,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3357
3410
  } catch (error) {
3358
3411
  Logger6.rawLog(`${app.name} build failed in dist/apps/${app.name}`, undefined, "error");
3359
3412
  Logger6.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
3413
+ markCliErrorPrinted(error);
3360
3414
  throw error;
3361
3415
  }
3362
3416
  }
@@ -3379,6 +3433,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3379
3433
  } catch (error) {
3380
3434
  spinner.fail(`${exec.name} typecheck failed`);
3381
3435
  Logger6.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
3436
+ markCliErrorPrinted(error);
3382
3437
  throw error;
3383
3438
  }
3384
3439
  }
@@ -3633,7 +3688,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3633
3688
  await Promise.all(shares.map(async (share) => await share.close()));
3634
3689
  }, "Abandoning the tunnel release; the shares expire on their own.");
3635
3690
  await Promise.all(apps.map(async (app) => {
3636
- const { TunnelShare } = await import("./TunnelShare-f1egrktx.js");
3691
+ const { TunnelShare } = await import("./TunnelShare-tfrnftgr.js");
3637
3692
  const share = await TunnelShare.open(app, { workspace: app.workspace });
3638
3693
  shares.push(share);
3639
3694
  urls.set(app.name, share.url);
@@ -2,23 +2,73 @@
2
2
  import {
3
3
  FileSys2
4
4
  } from "./index-52w0fvh8.js";
5
+ import {
6
+ resolveMobileTargets
7
+ } from "./index-m9jj544v.js";
5
8
  import {
6
9
  NativePublicEnv,
7
10
  UpdatePackFolder,
8
11
  NativeApp
9
- } from "./index-0909wckt.js";
10
- import {
11
- resolveMobileTargets
12
- } from "./index-q958tqqg.js";
12
+ } from "./index-35m6bzm7.js";
13
13
  import {
14
14
  ExitCodeError
15
- } from "./index-31ce9vhg.js";
15
+ } from "./index-vkb9m4z7.js";
16
16
  import {
17
17
  ConfigLock
18
- } from "./index-3hx1z96c.js";
18
+ } from "./index-bqbf654f.js";
19
+
20
+ // pkgs/@akanjs/devkit/cloud/cloudHttpError.ts
21
+ import { isRecord } from "akanjs/common";
22
+
23
+ class CloudHttpError extends Error {
24
+ status;
25
+ statusText;
26
+ url;
27
+ body;
28
+ headers;
29
+ static #errKey = /^[\w$-]+\.error\.[\w$-]+$/;
30
+ name = "CloudHttpError";
31
+ constructor(status, statusText, url, body, headers = new Headers) {
32
+ super(`${status} ${statusText} from ${url}: ${body.slice(0, 200)}`);
33
+ this.status = status;
34
+ this.statusText = statusText;
35
+ this.url = url;
36
+ this.body = body;
37
+ this.headers = headers;
38
+ }
39
+ static async of(response, url) {
40
+ return new CloudHttpError(response.status, response.statusText, url, await response.text(), response.headers);
41
+ }
42
+ static statusOf(error) {
43
+ return error instanceof CloudHttpError ? error.status : null;
44
+ }
45
+ get error() {
46
+ try {
47
+ const parsed = JSON.parse(this.body);
48
+ return isRecord(parsed) && typeof parsed.error === "string" ? parsed.error : null;
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+ get errKey() {
54
+ const { error } = this;
55
+ return error && CloudHttpError.#errKey.test(error) ? error : null;
56
+ }
57
+ get retryAfterMs() {
58
+ return CloudHttpError.retryAfterMs(this.headers.get("retry-after"));
59
+ }
60
+ static retryAfterMs(header) {
61
+ const value = header?.trim() ?? "";
62
+ if (!value)
63
+ return null;
64
+ const ms = /^\d+$/.test(value) ? Number(value) * 1000 : Date.parse(value) - Date.now();
65
+ return Number.isFinite(ms) ? Math.max(0, ms) : null;
66
+ }
67
+ }
19
68
 
20
69
  // pkgs/@akanjs/devkit/cloud/globalConfig.ts
21
70
  import { mkdir, rm, writeFile } from "fs/promises";
71
+ import { trimTrailingSlashes } from "akanjs/common";
22
72
  import dayjs from "dayjs";
23
73
 
24
74
  // pkgs/@akanjs/devkit/cloud/constants.ts
@@ -68,7 +118,7 @@ class GlobalConfig {
68
118
  }
69
119
  static #normalizeHost(host) {
70
120
  const url = URL.canParse(host) ? new URL(host) : null;
71
- return url && (url.protocol === "https:" || url.protocol === "http:") ? `${url.origin}${url.pathname.replace(/\/+$/, "")}` : host.replace(/\/+$/, "");
121
+ return url && (url.protocol === "https:" || url.protocol === "http:") ? `${url.origin}${trimTrailingSlashes(url.pathname)}` : trimTrailingSlashes(host);
72
122
  }
73
123
  static async getHostConfig(host = GlobalConfig.akanCloudHost) {
74
124
  const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
@@ -169,55 +219,6 @@ class GlobalConfig {
169
219
  }
170
220
  }
171
221
 
172
- // pkgs/@akanjs/devkit/cloud/cloudHttpError.ts
173
- import { isRecord } from "akanjs/common";
174
-
175
- class CloudHttpError extends Error {
176
- status;
177
- statusText;
178
- url;
179
- body;
180
- headers;
181
- static #errKey = /^[\w$-]+\.error\.[\w$-]+$/;
182
- name = "CloudHttpError";
183
- constructor(status, statusText, url, body, headers = new Headers) {
184
- super(`${status} ${statusText} from ${url}: ${body.slice(0, 200)}`);
185
- this.status = status;
186
- this.statusText = statusText;
187
- this.url = url;
188
- this.body = body;
189
- this.headers = headers;
190
- }
191
- static async of(response, url) {
192
- return new CloudHttpError(response.status, response.statusText, url, await response.text(), response.headers);
193
- }
194
- static statusOf(error) {
195
- return error instanceof CloudHttpError ? error.status : null;
196
- }
197
- get error() {
198
- try {
199
- const parsed = JSON.parse(this.body);
200
- return isRecord(parsed) && typeof parsed.error === "string" ? parsed.error : null;
201
- } catch {
202
- return null;
203
- }
204
- }
205
- get errKey() {
206
- const { error } = this;
207
- return error && CloudHttpError.#errKey.test(error) ? error : null;
208
- }
209
- get retryAfterMs() {
210
- return CloudHttpError.retryAfterMs(this.headers.get("retry-after"));
211
- }
212
- static retryAfterMs(header) {
213
- const value = header?.trim() ?? "";
214
- if (!value)
215
- return null;
216
- const ms = /^\d+$/.test(value) ? Number(value) * 1000 : Date.parse(value) - Date.now();
217
- return Number.isFinite(ms) ? Math.max(0, ms) : null;
218
- }
219
- }
220
-
221
222
  // pkgs/@akanjs/devkit/cloud/cloudApi.ts
222
223
  class HttpClient {
223
224
  baseUrl;
@@ -370,7 +371,6 @@ class CloudApi {
370
371
  }
371
372
  }
372
373
  }
373
-
374
374
  // pkgs/@akanjs/devkit/cloud/cloudUpdates.ts
375
375
  import path2 from "path";
376
376
  import { Logger as Logger2 } from "akanjs/common";
@@ -585,7 +585,6 @@ ${(release.problems ?? []).map((problem) => ` - ${problem}`).join(`
585
585
  });
586
586
  }
587
587
  }
588
-
589
588
  // pkgs/@akanjs/devkit/cloud/pipelineSecrets.ts
590
589
  import { capitalize, Logger as Logger3, PipelineNames } from "akanjs/common";
591
590
  class PipelineSecrets {
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // pkgs/@akanjs/devkit/mobile/mobileTarget.ts
3
- var trimSlashes = (value) => value.replace(/^\/+|\/+$/g, "");
3
+ import { trimSlashes } from "akanjs/common";
4
4
  var getMobileTargets = async (app) => {
5
5
  const config = await app.getConfig();
6
6
  return Object.entries(config.native.targets).map(([name, target]) => ({ name, config: target }));
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  getMobileTargetChoices
4
- } from "./index-q958tqqg.js";
4
+ } from "./index-m9jj544v.js";
5
5
 
6
6
  // pkgs/@akanjs/cli/application/commandOptions.ts
7
7
  var targetChoices = async ({ app }) => await getMobileTargetChoices(app);
@@ -10,7 +10,7 @@ import {
10
10
  isScannedRootEntry,
11
11
  AppExecutor,
12
12
  LibExecutor
13
- } from "./index-2etqq75t.js";
13
+ } from "./index-g6ax17x4.js";
14
14
  import {
15
15
  FileSys2
16
16
  } from "./index-52w0fvh8.js";
@@ -23,7 +23,7 @@ import {
23
23
  workflowPathsForPlan,
24
24
  workflowRunArtifactPath,
25
25
  workflowSyncDir
26
- } from "./index-rhbabmja.js";
26
+ } from "./index-033wne2j.js";
27
27
 
28
28
  // pkgs/@akanjs/devkit/akanContext.ts
29
29
  import { readdir } from "fs/promises";
@@ -79,7 +79,7 @@ var upsertCodexMcpServerBlock = (existing, block, { force = false } = {}) => {
79
79
  if (!match) {
80
80
  if (!existing.trim())
81
81
  return nextBlock;
82
- return `${existing.replace(/\s*$/, "")}
82
+ return `${existing.trimEnd()}
83
83
 
84
84
  ${nextBlock}`;
85
85
  }
@@ -532,14 +532,14 @@ class AkanContextAnalyzer {
532
532
  if (frameworkDeclared.size > 0) {
533
533
  const agentsMd = await Bun.file(path.join(workspace.workspaceRoot, "AGENTS.md")).text().catch(() => "");
534
534
  const listed = listedByImport(sectionOf(agentsMd, "## Recipes")).get("akanjs/ui") ?? new Set;
535
- pushIndexDiagnostic("AGENTS.md", [...frameworkDeclared].filter((name) => !listed.has(name)).sort(), [...listed].filter((name) => !frameworkDeclared.has(name)).sort(), "akan agent install agents-md");
535
+ pushIndexDiagnostic("AGENTS.md", [...frameworkDeclared].filter((name) => !listed.has(name)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0), [...listed].filter((name) => !frameworkDeclared.has(name)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0), "akan agent install agents-md");
536
536
  }
537
537
  for (const sys of [...context.apps, ...context.libs]) {
538
538
  const own = declaredByImport.get(`@${sys.path}/ui`) ?? new Set;
539
539
  const scopeMd = await Bun.file(path.join(workspace.workspaceRoot, sys.path, "AGENTS.md")).text().catch(() => "");
540
540
  const groups = listedByImport(sectionOf(scopeMd, "## Recipes In Scope"));
541
541
  const ownListed = groups.get(`@${sys.path}/ui`) ?? new Set;
542
- const missing = [...own].filter((name) => !ownListed.has(name)).sort();
542
+ const missing = [...own].filter((name) => !ownListed.has(name)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
543
543
  const stale = [...groups.entries()].flatMap(([importFrom, names]) => [...names].filter((name) => !(declaredByImport.get(importFrom) ?? new Set).has(name))).sort();
544
544
  pushIndexDiagnostic(`${sys.path}/AGENTS.md`, missing, stale, `akan sync ${sys.name}`);
545
545
  }
@@ -1,17 +1,40 @@
1
1
  // @bun
2
2
  import {
3
3
  resolveSsrPageEntriesForApp
4
- } from "./index-2etqq75t.js";
4
+ } from "./index-g6ax17x4.js";
5
5
  import {
6
6
  bundleDefine,
7
7
  CsrEntryFiles,
8
8
  PagesEntrySourceGenerator,
9
9
  PagesBundleBuilder
10
- } from "./index-nq045px5.js";
10
+ } from "./index-h3r3nr9y.js";
11
11
 
12
12
  // pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
13
13
  import { mkdir, rm, unlink } from "fs/promises";
14
+ import path2 from "path";
15
+
16
+ // pkgs/@akanjs/devkit/transforms/browserDirnamePlugin.ts
14
17
  import path from "path";
18
+ var vendorScript = /[\\/]node_modules[\\/].+\.[cm]?js$/;
19
+ var createBrowserDirnamePlugin = () => ({
20
+ name: "akan-browser-dirname",
21
+ setup(build) {
22
+ build.onLoad({ filter: vendorScript }, async (args) => {
23
+ const source = await Bun.file(args.path).text();
24
+ if (!source.includes("__dirname") && !source.includes("__filename"))
25
+ return;
26
+ const posixPath = args.path.replaceAll("\\", "/");
27
+ const filename = posixPath.slice(posixPath.indexOf("/node_modules/"));
28
+ const define = { __dirname: JSON.stringify(path.posix.dirname(filename)), __filename: JSON.stringify(filename) };
29
+ return {
30
+ loader: "js",
31
+ contents: new Bun.Transpiler({ loader: "js", target: "browser", define }).transformSync(source)
32
+ };
33
+ });
34
+ }
35
+ });
36
+
37
+ // pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
15
38
  class CsrArtifactBuilder {
16
39
  #app;
17
40
  #command;
@@ -67,11 +90,11 @@ ${logs}` : ""}`);
67
90
  minify: true,
68
91
  define: bundleDefine(app, command, "csr"),
69
92
  optimizeImports,
70
- plugins: [PagesBundleBuilder.createCssStubPlugin()]
93
+ plugins: [PagesBundleBuilder.createCssStubPlugin(), createBrowserDirnamePlugin()]
71
94
  };
72
95
  }
73
96
  static publicEnvPath(app) {
74
- return path.join(app.dist.cwdPath, ".akan", "artifact", "csr-public-env.json");
97
+ return path2.join(app.dist.cwdPath, ".akan", "artifact", "csr-public-env.json");
75
98
  }
76
99
  static async writePublicEnv(app, define) {
77
100
  const prefix = "process.env.";
@@ -89,20 +112,20 @@ ${logs}` : ""}`);
89
112
  return CsrEntryFiles.entryFilename(basePath);
90
113
  }
91
114
  static basePathOfHtml(htmlPath) {
92
- const name = path.basename(htmlPath, ".html");
115
+ const name = path2.basename(htmlPath, ".html");
93
116
  return name === "index" ? "" : name;
94
117
  }
95
118
  get #outputDir() {
96
- return path.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, this.#command === "build" ? "csr" : ".akan/artifact/csr");
119
+ return path2.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, this.#command === "build" ? "csr" : ".akan/artifact/csr");
97
120
  }
98
121
  get #generatedDir() {
99
- return path.join(this.#app.cwdPath, ".akan/generated/csr");
122
+ return path2.join(this.#app.cwdPath, ".akan/generated/csr");
100
123
  }
101
124
  get #artifactDir() {
102
- return path.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact");
125
+ return path2.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact");
103
126
  }
104
127
  #generatedPath(filename) {
105
- return path.join(this.#generatedDir, filename);
128
+ return path2.join(this.#generatedDir, filename);
106
129
  }
107
130
  async#createEntryFile(basePath, pageEntries) {
108
131
  return [
@@ -135,7 +158,7 @@ void bootCsr(pages);
135
158
  async#loadCssAssets() {
136
159
  if (this.#cssAssets)
137
160
  return this.#cssAssets;
138
- const artifactFile = Bun.file(path.join(this.#artifactDir, "base-artifact.json"));
161
+ const artifactFile = Bun.file(path2.join(this.#artifactDir, "base-artifact.json"));
139
162
  if (!await artifactFile.exists())
140
163
  return {};
141
164
  const artifact = await artifactFile.json();
@@ -150,7 +173,7 @@ void bootCsr(pages);
150
173
  const basePath = CsrArtifactBuilder.basePathOfHtml(htmlPath);
151
174
  const cssAsset = cssAssets[basePath];
152
175
  if (!cssAsset) {
153
- this.#app.logger.warn(`[csr-build] base-artifact.json has no compiled stylesheet for ${basePath || "root"}; ${path.basename(htmlPath)} ships without CSS`);
176
+ this.#app.logger.warn(`[csr-build] base-artifact.json has no compiled stylesheet for ${basePath || "root"}; ${path2.basename(htmlPath)} ships without CSS`);
154
177
  }
155
178
  const inlined = await this.#inlineHtmlAssets(await htmlFile.text(), htmlPath, cssAsset);
156
179
  for (const filePath of inlined.jsFiles)
@@ -171,7 +194,7 @@ ${remainingAssets.join(`
171
194
  async#inlineHtmlAssets(html, htmlPath, cssAsset) {
172
195
  let next = html;
173
196
  if (cssAsset) {
174
- const css = await Bun.file(path.join(this.#artifactDir, cssAsset.cssRelPath)).text();
197
+ const css = await Bun.file(path2.join(this.#artifactDir, cssAsset.cssRelPath)).text();
175
198
  next = CsrArtifactBuilder.injectBeforeHeadEnd(next, CsrArtifactBuilder.createInlineStyle(css));
176
199
  }
177
200
  const jsFiles = [];
@@ -189,7 +212,7 @@ ${remainingAssets.join(`
189
212
  if (predicate(filePath))
190
213
  files.push(filePath);
191
214
  }
192
- return files.sort();
215
+ return files.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
193
216
  }
194
217
  static injectBeforeHeadEnd(html, snippet) {
195
218
  const scannable = CsrArtifactBuilder.blankEmbeddedContent(html);
@@ -205,7 +228,7 @@ ${html.slice(bodyStart)}`;
205
228
  ${snippet}`;
206
229
  }
207
230
  static blankEmbeddedContent(html) {
208
- return html.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>|<style\b[^>]*>[\s\S]*?<\/style\s*>|<!--[\s\S]*?-->/gi, (match) => " ".repeat(match.length));
231
+ return html.replace(/<script\b[^>]*>[\s\S]*?(?:<\/script(?:[\s/][^<>]*)?>|$)|<style\b[^>]*>[\s\S]*?(?:<\/style(?:[\s/][^<>]*)?>|$)|<!--[\s\S]*?(?:--!?>|$)/gi, (match) => " ".repeat(match.length));
209
232
  }
210
233
  static createInlineStyle(css) {
211
234
  return `<style data-akan-css="active">
@@ -241,7 +264,7 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
241
264
  throw new Error(`[csr-build] cannot inline external script: ${src}`);
242
265
  }
243
266
  const normalized = src.startsWith("/") ? src.slice(1) : src;
244
- return path.resolve(path.dirname(htmlPath), normalized);
267
+ return path2.resolve(path2.dirname(htmlPath), normalized);
245
268
  }
246
269
  }
247
270
 
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-31ce9vhg.js";
5
+ } from "./index-vkb9m4z7.js";
6
6
  import {
7
7
  ModuleExecutor
8
- } from "./index-2etqq75t.js";
8
+ } from "./index-g6ax17x4.js";
9
9
  import {
10
10
  sourceFile,
11
11
  moduleSourcePaths,
@@ -13,10 +13,10 @@ import {
13
13
  createPassedPrimitiveReport,
14
14
  bilingualLabelForField,
15
15
  bilingualDescriptionForField
16
- } from "./index-rhbabmja.js";
16
+ } from "./index-033wne2j.js";
17
17
  import {
18
18
  PageScript
19
- } from "./index-jwqtchha.js";
19
+ } from "./index-27y8t17p.js";
20
20
  import {
21
21
  pluralizeName
22
22
  } from "./index-nz8prx9g.js";
@@ -5,13 +5,13 @@ import {
5
5
  writeGeneratedSyncState,
6
6
  createRepairReport,
7
7
  renderRepairReport
8
- } from "./index-rhbabmja.js";
8
+ } from "./index-033wne2j.js";
9
9
  import {
10
10
  AkanContextAnalyzer
11
- } from "./index-rk9sdys3.js";
11
+ } from "./index-nv79n88g.js";
12
12
  import {
13
13
  runner
14
- } from "./index-31ce9vhg.js";
14
+ } from "./index-vkb9m4z7.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/repair/repair.runner.ts
17
17
  var spawnShell = async (workspace, command) => await workspace.spawn("bash", ["-lc", command.startsWith("akan ") ? `bun run ${command}` : command], {