@akanjs/cli 3.0.2 → 3.1.0-rc.0

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 (84) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-szbjv4gv.js → CodeAgent-q7a4srt6.js} +2 -2
  3. package/{CodeTui-5nw86ab6.js → CodeTui-ak23dxc9.js} +1 -1
  4. package/{TunnelShare-cwh9ezsm.js → TunnelShare-21mm6dr5.js} +2 -2
  5. package/{agent.command-np1dffkb.js → agent.command-f3gsc1gd.js} +5 -5
  6. package/akanCode.js +2 -2
  7. package/{application.command-gk69v1xs.js → application.command-3v2d53gd.js} +37 -15
  8. package/{applicationBuildRunner-wx09n9g6.js → applicationBuildRunner-1yaqsrdq.js} +115 -103
  9. package/buildBatch.proc.js +16 -5
  10. package/cloud.command-kk2rwkvw.js +187 -0
  11. package/cloud.script-r7eyfey4.js +20 -0
  12. package/{code.command-hmtx14b2.js → code.command-30sca09d.js} +6 -6
  13. package/commandManifest.json +1 -1
  14. package/{context.command-6aqvdx43.js → context.command-k7eqacq6.js} +13 -13
  15. package/context.runner-hqd1ppqe.js +21 -0
  16. package/{guideline.command-axvf68gc.js → guideline.command-dtczrqpf.js} +2 -2
  17. package/guidelines/agentRule/agentRule.instruction.md +10 -2
  18. package/guidelines/conventions/conventions.instruction.md +68 -25
  19. package/guidelines/cssRule/cssRule.instruction.md +19 -0
  20. package/guidelines/mcpRule/mcpRule.instruction.md +67 -12
  21. package/guidelines/queryRule/queryRule.instruction.md +11 -1
  22. package/guidelines/runtimeRule/runtimeRule.instruction.md +97 -16
  23. package/guidelines/ssrRule/ssrRule.instruction.md +10 -7
  24. package/guidelines/transportRule/transportRule.instruction.md +19 -0
  25. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +6 -6
  26. package/incrementalBuilder.proc.js +24 -3
  27. package/{index-h9ht6s60.js → index-05g3jayg.js} +1 -1
  28. package/{index-j38qkvkk.js → index-0bm04n5g.js} +12 -10
  29. package/{index-g38nhv87.js → index-2etcv0sc.js} +1 -1
  30. package/{index-zyw622y1.js → index-2mx692qq.js} +3 -3
  31. package/{index-jb0hmt3k.js → index-2t4tqd1c.js} +3 -3
  32. package/{index-50wb2a26.js → index-55mynnqs.js} +354 -129
  33. package/{index-q6ft9fkc.js → index-6jjtnhkw.js} +8 -3
  34. package/index-6w0rbr9d.js +68 -0
  35. package/{index-2wc41k5w.js → index-7bymavqk.js} +2 -2
  36. package/{index-gtjgnv36.js → index-aprt7pkz.js} +6 -9
  37. package/{index-1bjkfvm9.js → index-c1x0be5j.js} +2 -2
  38. package/{index-z750gk1j.js → index-c2yrsxdh.js} +13 -7
  39. package/{index-cb6yc5mb.js → index-c76k723e.js} +2 -2
  40. package/{index-6keyf4sg.js → index-ctanya41.js} +4 -4
  41. package/{index-f4e08ptp.js → index-e0cvze1s.js} +4 -4
  42. package/{index-hp3stk1m.js → index-fm46xrf1.js} +3 -3
  43. package/{index-3xmzr1p1.js → index-gnyf1fqy.js} +2 -2
  44. package/{index-zwd84m0w.js → index-jyv387qw.js} +4 -4
  45. package/{index-jk9xnck6.js → index-kjvrq3nc.js} +231 -133
  46. package/{index-xwprn9nr.js → index-nz15k0b6.js} +1 -1
  47. package/{index-nwd6qzvv.js → index-p9ystjrp.js} +138 -55
  48. package/index-q958tqqg.js +77 -0
  49. package/{index-50jjwg8y.js → index-qt22xstj.js} +1 -1
  50. package/{index-94s080qm.js → index-r2tpeb3n.js} +127 -1
  51. package/{index-bsv901fd.js → index-rwq3ekqc.js} +7 -7
  52. package/{index-t91a7339.js → index-tn4rpqp1.js} +96 -12
  53. package/{index-1gs9g12n.js → index-v29746vb.js} +4 -4
  54. package/index-ww9bhp67.js +62 -0
  55. package/{index-hxnnfy57.js → index-y8q31011.js} +180 -8
  56. package/index.js +22 -21
  57. package/{library.command-9m2rdwwz.js → library.command-gaga5bmq.js} +3 -3
  58. package/{localRegistry.command-kda81jyk.js → localRegistry.command-9e84e32q.js} +9 -9
  59. package/{module.command-q63dffya.js → module.command-7vpf6db4.js} +5 -5
  60. package/{package.command-y2jh0m99.js → package.command-twmvvf69.js} +3 -3
  61. package/package.json +2 -2
  62. package/{page.command-f3e4cwhh.js → page.command-5asq7fdf.js} +3 -3
  63. package/pipeline.command-d0v38572.js +1334 -0
  64. package/{primitive.command-r4kq75qj.js → primitive.command-dyrs2fm8.js} +6 -6
  65. package/projectTypecheck-cvtkrzp2.js +7 -0
  66. package/{quality.command-f7gzh26z.js → quality.command-6emsqpbg.js} +5 -4
  67. package/{repair.command-0qmyr6qa.js → repair.command-8t6aegv5.js} +5 -5
  68. package/{scalar.command-kddn7av4.js → scalar.command-bnggy1x7.js} +4 -4
  69. package/{subspace.command-ft65qvc4.js → subspace.command-f02j5tge.js} +158 -91
  70. package/templates/appSample/page/task/[taskId]/_index.tsx +2 -2
  71. package/templates/appSample/page/task/[taskId]/edit.tsx +2 -2
  72. package/templates/appSample/page/task/_index.tsx +2 -2
  73. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -2
  74. package/templates/crudPages/[__model__Id]/page.tsx +3 -3
  75. package/templates/crudPages/page.tsx +2 -2
  76. package/templates/crudSinglePage/page.tsx +3 -3
  77. package/templates/lib/cnst.ts +2 -2
  78. package/templates/lib/sig.ts +3 -3
  79. package/{tunnel.command-b3ymdk4f.js → tunnel.command-9x8nfn75.js} +16 -13
  80. package/{workflow.command-z1srcdfw.js → workflow.command-jx0wag5r.js} +10 -10
  81. package/{workspace.command-vp6vmx3z.js → workspace.command-cmj6mqyk.js} +57 -27
  82. package/cloud.command-tw06613r.js +0 -95
  83. package/cloud.script-64gzba8r.js +0 -20
  84. package/context.runner-hnkvv3z3.js +0 -21
package/.build-stamp CHANGED
@@ -1 +1 @@
1
- ed6c6a9442699bc1b0b2b6ddbe72d0cdd440f78e0d21be5e06bc85a7790491eb
1
+ c702579aa15c46bcfdf92573e0c21fe8ac72af8342adcec6e9978bcb7bea6f4b
@@ -1,8 +1,8 @@
1
1
  // @bun
2
2
  import {
3
3
  CodeAgent2
4
- } from "./index-jb0hmt3k.js";
5
- import"./index-xwprn9nr.js";
4
+ } from "./index-2t4tqd1c.js";
5
+ import"./index-nz15k0b6.js";
6
6
  import"./index-7md2g9vw.js";
7
7
  export {
8
8
  CodeAgent2 as CodeAgent
@@ -4,7 +4,7 @@ import {
4
4
  McpServerConfig,
5
5
  McpTokenStore,
6
6
  McpSignIn
7
- } from "./index-xwprn9nr.js";
7
+ } from "./index-nz15k0b6.js";
8
8
  import {
9
9
  CodeTuiLines2,
10
10
  CodeTuiAgents2,
@@ -1,8 +1,8 @@
1
1
  // @bun
2
2
  import {
3
3
  TunnelShare2
4
- } from "./index-2wc41k5w.js";
5
- import"./index-94s080qm.js";
4
+ } from "./index-7bymavqk.js";
5
+ import"./index-r2tpeb3n.js";
6
6
  import"./index-52w0fvh8.js";
7
7
  export {
8
8
  TunnelShare2 as TunnelShare
@@ -2,16 +2,16 @@
2
2
  import {
3
3
  Workspace,
4
4
  command
5
- } from "./index-q6ft9fkc.js";
5
+ } from "./index-6jjtnhkw.js";
6
6
  import"./index-52w0fvh8.js";
7
- import"./index-50wb2a26.js";
7
+ import"./index-55mynnqs.js";
8
8
  import"./index-hj6w4ka1.js";
9
- import"./index-h9ht6s60.js";
10
- import"./index-zyw622y1.js";
9
+ import"./index-05g3jayg.js";
10
+ import"./index-2mx692qq.js";
11
11
  import"./index-zzvvc845.js";
12
12
  import {
13
13
  AgentScript
14
- } from "./index-1gs9g12n.js";
14
+ } from "./index-v29746vb.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/agent/agent.command.ts
17
17
  class AgentCommand extends command("agent", [AgentScript], ({ public: target }) => ({
package/akanCode.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  CodeMailbox2,
29
29
  CodeSessionFork2,
30
30
  CodeAgent2
31
- } from "./index-jb0hmt3k.js";
31
+ } from "./index-2t4tqd1c.js";
32
32
  import {
33
33
  akanCodeDefaultModel2,
34
34
  akanCodeModel2,
@@ -39,7 +39,7 @@ import {
39
39
  import {
40
40
  SubagentPool2,
41
41
  akanCodePaths2
42
- } from "./index-xwprn9nr.js";
42
+ } from "./index-nz15k0b6.js";
43
43
  import"./index-7md2g9vw.js";
44
44
  import {
45
45
  CodeAgentRpcHost2
@@ -6,19 +6,20 @@ import {
6
6
  Exec,
7
7
  Workspace,
8
8
  command
9
- } from "./index-q6ft9fkc.js";
9
+ } from "./index-6jjtnhkw.js";
10
10
  import"./index-52w0fvh8.js";
11
- import"./index-50wb2a26.js";
12
- import {
13
- getMobileTargetChoices
14
- } from "./index-jk9xnck6.js";
11
+ import"./index-55mynnqs.js";
12
+ import"./index-kjvrq3nc.js";
15
13
  import"./index-k9rrten6.js";
16
- import"./index-1bjkfvm9.js";
14
+ import"./index-c1x0be5j.js";
17
15
  import {
18
16
  ApplicationScript
19
- } from "./index-nwd6qzvv.js";
17
+ } from "./index-p9ystjrp.js";
20
18
  import"./index-7md2g9vw.js";
21
- import"./index-50jjwg8y.js";
19
+ import"./index-qt22xstj.js";
20
+ import {
21
+ getMobileTargetChoices
22
+ } from "./index-q958tqqg.js";
22
23
 
23
24
  // pkgs/@akanjs/cli/application/application.command.ts
24
25
  var mobileTargetOption = {
@@ -31,6 +32,8 @@ var deviceOption = {
31
32
  default: ""
32
33
  };
33
34
  var teamOption = { flag: "T", desc: "Apple team id the signing is narrowed to", default: "" };
35
+ var signDesc = "sign with the identity AKAN_NATIVE_MACOS_* / AKAN_NATIVE_WINDOWS_* names (without it the env signs nothing)";
36
+ var notarizeDesc = "macOS: upload the signed app to Apple's notary service (takes --sign)";
34
37
  var devEnvs = ["local", "debug", "develop", "main"];
35
38
  var buildEnvOption = { enum: devEnvs, desc: "backend environment", default: "debug" };
36
39
  var startEnvOption = {
@@ -93,11 +96,14 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
93
96
  runtimeDir
94
97
  });
95
98
  }),
96
- build: target({ short: true, desc: "Build the application for production (frontend + backend)" }).with(App).option("write", Boolean, { desc: "write code generation", default: true }).option("fast", Boolean, { desc: "fast build", default: false }).option("quiet", Boolean, { desc: "hide build progress output", default: false }).exec(async function(app, write, fast, quiet) {
97
- await this.applicationScript.build(app, { write, fast, quiet });
99
+ build: target({ short: true, desc: "Build the application for production (frontend + backend)" }).with(App).option("write", Boolean, { desc: "write code generation", default: true }).option("fast", Boolean, { desc: "fast build", default: false }).option("quiet", Boolean, { desc: "hide build progress output", default: false }).option("profile", String, {
100
+ desc: "server env profile: bundle env/env.server.<env>.<profile>.ts in place of the environment's own file",
101
+ nullable: true
102
+ }).exec(async function(app, write, fast, quiet, profile) {
103
+ await this.applicationScript.build(app, { write, fast, quiet, profile: profile ?? undefined });
98
104
  }),
99
- typecheck: target({ short: true, desc: "Typecheck the application" }).with(App).option("write", Boolean, { desc: "write code generation", default: true }).option("clean", Boolean, { desc: "clear typecheck cache before running", default: false }).option("incremental", Boolean, { desc: "reuse TypeScript incremental cache", default: true }).exec(async function(app, write, clean, incremental) {
100
- await this.applicationScript.typecheck(app, { write, clean, incremental });
105
+ typecheck: target({ short: true, desc: "Typecheck an app or a library, its tests and specs included" }).with(Exec).option("write", Boolean, { desc: "write code generation", default: true }).option("clean", Boolean, { desc: "clear typecheck cache before running", default: false }).option("incremental", Boolean, { desc: "reuse TypeScript incremental cache", default: true }).option("tests", Boolean, { desc: "check its *.test.ts / *.spec.ts too, which nothing imports", default: true }).exec(async function(exec, write, clean, incremental, tests) {
106
+ await this.applicationScript.typecheck(exec, { write, clean, incremental, tests });
101
107
  }),
102
108
  test: target({ desc: "Prepare and test an app, library, or package" }).with(Exec).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(exec, write) {
103
109
  await this.applicationScript.test(exec, { write });
@@ -115,13 +121,15 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
115
121
  desc: "the CPU the app runs on, arm64 or x64 of this OS (default this computer's); a macOS app is arm64 only",
116
122
  enum: ["arm64", "x64"],
117
123
  nullable: true
118
- }).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(app, target, env, debug, installer, arch, write) {
124
+ }).option("sign", Boolean, { desc: signDesc, default: false }).option("notarize", Boolean, { desc: notarizeDesc, default: false }).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(app, target, env, debug, installer, arch, sign, notarize, write) {
119
125
  await this.applicationScript.buildDesktop(app, {
120
126
  target,
121
127
  env,
122
128
  profile: debug ? "debug" : "release",
123
129
  installer,
124
130
  write,
131
+ ...sign ? { sign } : {},
132
+ ...notarize ? { notarize } : {},
125
133
  ...arch ? { arch } : {}
126
134
  });
127
135
  }),
@@ -183,7 +191,7 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
183
191
  });
184
192
  }),
185
193
  packUpdate: target({
186
- desc: "Pack an unsigned over-the-air update of the mobile web bundle, for the signer to publish"
194
+ desc: "Pack an unsigned over-the-air update of the mobile web bundle for a signer; records it in <out>/pack.json, exits 2 when --against needs a new store build"
187
195
  }).with(App).option("platform", String, { enum: ["ios", "android"], desc: "the app it updates" }).option("target", String, mobileTargetOption).option("env", String, releaseEnvOption).option("out", String, {
188
196
  desc: "output folder (default: dist/native/<app>/<target>/updates/<platform>)",
189
197
  nullable: true
@@ -214,11 +222,25 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
214
222
  }).option("target", String, mobileTargetOption).option("env", String, releaseEnvOption).option("channel", String, {
215
223
  desc: "the manifest to publish to (default: the target's updates.channel, else --env)",
216
224
  nullable: true
217
- }).option("write", Boolean, { desc: "write code generation", default: true }).option("allowLocalRelease", Boolean, { flag: "l", desc: "allow release with --env local", default: false }).exec(async function(app, platform, target, env, channel, write, allowLocalRelease) {
225
+ }).option("upload", String, {
226
+ desc: "s3://<bucket>/<prefix> the release goes to, its manifests last (credentials: S3_* or AWS_* env)",
227
+ nullable: true
228
+ }).option("arch", String, {
229
+ desc: "desktop: the CPU of the apps it updates, arm64 or x64 of this OS (default this computer's)",
230
+ enum: ["arm64", "x64"],
231
+ nullable: true
232
+ }).option("sign", Boolean, {
233
+ desc: `${signDesc}; a signed app takes only a release signed the same way`,
234
+ default: false
235
+ }).option("notarize", Boolean, { desc: notarizeDesc, default: false }).option("write", Boolean, { desc: "write code generation", default: true }).option("allowLocalRelease", Boolean, { flag: "l", desc: "allow release with --env local", default: false }).exec(async function(app, platform, target, env, channel, upload, arch, sign, notarize, write, allowLocalRelease) {
218
236
  await this.applicationScript.publishUpdate(app, platform, {
219
237
  target,
220
238
  env,
239
+ ...sign ? { sign } : {},
240
+ ...notarize ? { notarize } : {},
221
241
  ...channel ? { channel } : {},
242
+ ...upload ? { upload } : {},
243
+ ...arch ? { arch } : {},
222
244
  write,
223
245
  allowLocalRelease
224
246
  });
@@ -1,50 +1,92 @@
1
1
  // @bun
2
2
  import {
3
+ ServerEnvProfile,
3
4
  Spinner
4
- } from "./index-50wb2a26.js";
5
- import"./index-gtjgnv36.js";
5
+ } from "./index-55mynnqs.js";
6
+ import"./index-aprt7pkz.js";
6
7
  import {
7
8
  AllRoutesBuilder,
8
9
  CsrArtifactBuilder,
9
10
  FontPruner,
10
11
  precompressArtifacts,
11
12
  SsrBaseArtifactBuilder
12
- } from "./index-z750gk1j.js";
13
+ } from "./index-c2yrsxdh.js";
13
14
  import"./index-52w0fvh8.js";
14
15
  import"./index-n68jx79w.js";
16
+ import {
17
+ ProjectTypecheck2
18
+ } from "./index-6w0rbr9d.js";
15
19
 
16
20
  // pkgs/@akanjs/devkit/applicationBuildRunner.ts
17
- import { mkdir, rm } from "fs/promises";
18
21
  import path2 from "path";
19
22
 
20
23
  // pkgs/@akanjs/devkit/transforms/serverEnvPlugin.ts
21
24
  import { existsSync, realpathSync } from "fs";
22
25
  import path from "path";
23
26
  var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24
- var createServerEnvPlugin = ({ envDir, environment, environments }) => {
27
+ var createServerEnvPlugin = ({
28
+ envDir,
29
+ environment,
30
+ environments,
31
+ profile,
32
+ onLibEnv
33
+ }) => {
25
34
  const others = [...new Set(environments)].filter((name) => name !== environment);
26
35
  const dirs = new Set([path.resolve(envDir), existsSync(envDir) ? realpathSync.native(envDir) : envDir]);
27
- const names = others.map(escapeRegExp).join("|");
28
- const filter = new RegExp(`^(?:${[...dirs].map(escapeRegExp).join("|")})[\\\\/]env\\.server\\.(?:${names})\\.ts$`);
36
+ const folder = `^(?:${[...dirs].map(escapeRegExp).join("|")})[\\\\/]env\\.server\\.`;
37
+ const filter = new RegExp(`${folder}(?:${others.map(escapeRegExp).join("|")})\\.ts$`);
38
+ const own = new RegExp(`${folder}${escapeRegExp(environment)}\\.ts$`);
39
+ const libEnvs = new Map;
40
+ const libEnv = async (file) => {
41
+ const profileFile = ServerEnvProfile.profileFileOf(file, profile ?? "");
42
+ const libRoot = path.dirname(path.dirname(file));
43
+ if (await Bun.file(profileFile).exists()) {
44
+ const secrets = ServerEnvProfile.secretPaths(await ServerEnvProfile.evaluate(profileFile, libRoot));
45
+ if (secrets.length)
46
+ throw new Error(`${profileFile} holds secret-named values, which the "${profile}" bundle carries to every computer it runs on: ${secrets.join(", ")}.`);
47
+ onLibEnv?.(file, { profileFile: true, stripped: [] });
48
+ return { loader: "ts", contents: await Bun.file(profileFile).text() };
49
+ }
50
+ const { exports } = new Bun.Transpiler({ loader: "ts" }).scan(await Bun.file(file).text());
51
+ if (exports.some((name) => name !== "env"))
52
+ throw new Error(`${file} exports ${exports.join(", ")}: a "${profile}" build carries only a lib env's \`env\`, so give the lib ${path.basename(profileFile)}.`);
53
+ const { value, stripped } = ServerEnvProfile.strip(await ServerEnvProfile.evaluate(file, libRoot));
54
+ onLibEnv?.(file, { profileFile: false, stripped });
55
+ return { loader: "js", contents: `export const env = ${JSON.stringify(value ?? {})};
56
+ ` };
57
+ };
29
58
  return {
30
59
  name: "akan-server-env",
31
60
  setup(build) {
32
- if (!others.length)
33
- return;
34
- build.onLoad({ filter }, async (args) => {
35
- const name = path.basename(args.path, ".ts").slice("env.server.".length);
36
- const { exports } = new Bun.Transpiler({ loader: "ts" }).scan(await Bun.file(args.path).text());
37
- const message = `env/env.server.${name}.ts is not in this build: \`akan build\` bundles the server env of AKAN_PUBLIC_ENV=${environment} alone, the environment its image runs. To run ${name}, build for it: AKAN_PUBLIC_ENV=${name} in the workspace's .env, which outranks the shell, or --env ${name} on a desktop or mobile build.`;
38
- return {
39
- loader: "js",
40
- contents: [
41
- `const refuse = () => { throw new Error(${JSON.stringify(message)}); };`,
42
- "const unbuilt = new Proxy({}, { get: refuse, has: refuse, ownKeys: refuse, getOwnPropertyDescriptor: refuse });",
43
- `export { ${exports.map((exported) => `unbuilt as ${JSON.stringify(exported)}`).join(", ")} };`
44
- ].join(`
61
+ if (profile)
62
+ build.onLoad({ filter: own }, async (args) => ({
63
+ loader: "ts",
64
+ contents: await Bun.file(path.join(path.dirname(args.path), `env.server.${environment}.${profile}.ts`)).text()
65
+ }));
66
+ if (others.length)
67
+ build.onLoad({ filter }, async (args) => {
68
+ const name = path.basename(args.path, ".ts").slice("env.server.".length);
69
+ const { exports } = new Bun.Transpiler({ loader: "ts" }).scan(await Bun.file(args.path).text());
70
+ const message = `env/env.server.${name}.ts is not in this build: \`akan build\` bundles the server env of AKAN_PUBLIC_ENV=${environment} alone, the environment its image runs. To run ${name}, build for it: AKAN_PUBLIC_ENV=${name} in the workspace's .env, which outranks the shell, or --env ${name} on a desktop or mobile build.`;
71
+ return {
72
+ loader: "js",
73
+ contents: [
74
+ `const refuse = () => { throw new Error(${JSON.stringify(message)}); };`,
75
+ "const unbuilt = new Proxy({}, { get: refuse, has: refuse, ownKeys: refuse, getOwnPropertyDescriptor: refuse });",
76
+ `export { ${exports.map((exported) => `unbuilt as ${JSON.stringify(exported)}`).join(", ")} };`
77
+ ].join(`
45
78
  `)
46
- };
47
- });
79
+ };
80
+ });
81
+ if (profile)
82
+ build.onLoad({ filter: /[\\/]env[\\/]env\.server\.[A-Za-z0-9-]+\.ts$/ }, async (args) => {
83
+ const name = path.basename(args.path, ".ts").slice("env.server.".length);
84
+ if (dirs.has(path.dirname(args.path)) || name === "type" || name === "example")
85
+ return { loader: "ts", contents: await Bun.file(args.path).text() };
86
+ if (!libEnvs.has(args.path))
87
+ libEnvs.set(args.path, libEnv(args.path));
88
+ return await libEnvs.get(args.path);
89
+ });
48
90
  }
49
91
  };
50
92
  };
@@ -72,31 +114,36 @@ var SSR_RENDER_EXTERNALS = [
72
114
  "react-server-dom-webpack/client.browser"
73
115
  ];
74
116
  var AKAN_BACKEND_MINIFY = { whitespace: true, syntax: true, identifiers: false };
75
- var AKAN_OPTIONAL_BACKEND_EXTERNALS = [
76
- "@libsql/client",
77
- "bullmq",
78
- "ioredis",
79
- "postgres",
80
- "protobufjs"
81
- ];
117
+ var AKAN_OPTIONAL_BACKEND_EXTERNALS = ["bullmq", "ioredis", "postgres", "protobufjs"];
82
118
 
83
119
  class ApplicationBuildRunner {
84
120
  #app;
85
121
  #fast;
86
122
  #reporter;
87
123
  #environment;
124
+ #profile;
88
125
  #spinner;
89
126
  #startedAt = Date.now();
90
127
  #phases = [];
91
- constructor(app, { fast = false, reporter, environment } = {}) {
128
+ constructor(app, { fast = false, reporter, environment, profile } = {}) {
92
129
  this.#app = app;
93
130
  this.#fast = fast;
94
131
  this.#reporter = reporter;
95
132
  this.#environment = environment;
133
+ this.#profile = profile;
134
+ }
135
+ get #envDir() {
136
+ return path2.join(this.#app.cwdPath, "env");
96
137
  }
97
138
  async build({ spinner = false } = {}) {
98
139
  this.#spinner = spinner;
99
- const { web, assets } = await this.#app.getConfig();
140
+ const { web, assets, baseDevEnv } = await this.#app.getConfig();
141
+ if (this.#profile)
142
+ await ServerEnvProfile.assertShippable({
143
+ envDir: this.#envDir,
144
+ environment: this.#environment ?? baseDevEnv.env,
145
+ profile: this.#profile
146
+ });
100
147
  await this.#runPhase("prepare", "Preparing output directory", () => this.#app.prepareCommand("build"));
101
148
  if (!this.#fast)
102
149
  await this.#runPhase("typecheck", "Typechecking", () => this.typecheck());
@@ -114,12 +161,21 @@ class ApplicationBuildRunner {
114
161
  };
115
162
  }
116
163
  async typecheck(options = {}) {
117
- const { clean = false, incremental = true } = options;
118
164
  await this.#app.getPageKeys({ refresh: true });
119
- const { typecheckDir, tsconfigPath } = await this.#writeTypecheckTsconfig(incremental);
120
- if (clean)
121
- await rm(path2.join(typecheckDir, "tsconfig.tsbuildinfo"), { force: true });
122
- await this.#checkProjectInChildProcess(tsconfigPath);
165
+ const typecheck = new ProjectTypecheck2(this.#app.cwdPath, this.#app.workspace.workspaceRoot, this.#app.getCommandEnv());
166
+ const libPageIncludes = (await this.#app.getPageRoots()).filter((root) => root.keyPrefix).flatMap((root) => {
167
+ const rel = path2.relative(typecheck.typecheckDir, root.realDir).split(path2.sep).join("/");
168
+ return [`${rel}/**/*.ts`, `${rel}/**/*.tsx`];
169
+ });
170
+ await typecheck.run([
171
+ "../../main.ts",
172
+ "../../server.ts",
173
+ "../../client.ts",
174
+ "../../page/**/*.ts",
175
+ "../../page/**/*.tsx",
176
+ ...libPageIncludes,
177
+ "../../../../pkgs/akanjs/*/types/**/*.d.ts"
178
+ ], options);
123
179
  }
124
180
  async#runPhase(id, label, task, summarize) {
125
181
  this.#reporter?.phaseStart?.({ id, label });
@@ -166,6 +222,24 @@ class ApplicationBuildRunner {
166
222
  const suffix = dirty.exitCode === 0 && dirty.stdout.toString().trim() ? "-dirty" : "";
167
223
  return `${sha.stdout.toString().trim()}${suffix}`;
168
224
  }
225
+ #serverEnv = null;
226
+ #warnedLibEnvs = new Set;
227
+ #serverEnvPlugin(baseEnv, branches) {
228
+ this.#serverEnv ??= createServerEnvPlugin({
229
+ envDir: this.#envDir,
230
+ environment: this.#environment ?? baseEnv,
231
+ environments: ["local", "testing", ...branches],
232
+ profile: this.#profile,
233
+ onLibEnv: (file, { profileFile, stripped }) => {
234
+ if (profileFile || !stripped.length || this.#warnedLibEnvs.has(file))
235
+ return;
236
+ this.#warnedLibEnvs.add(file);
237
+ const lib = path2.relative(this.#app.workspace.workspaceRoot, file);
238
+ this.#app.logger.warn(`${lib}: the "${this.#profile}" build leaves out ${stripped.join(", ")}. Give the lib ${path2.basename(ServerEnvProfile.profileFileOf(file, this.#profile ?? ""))} to say what this profile runs with.`);
239
+ }
240
+ });
241
+ return this.#serverEnv;
242
+ }
169
243
  async#buildBackend() {
170
244
  const { externalLibs, web, baseDevEnv, branches } = await this.#app.getConfig();
171
245
  const backendEntryPoints = [`${this.#app.cwdPath}/main.ts`, `${this.#app.cwdPath}/server.ts`];
@@ -180,11 +254,7 @@ class ApplicationBuildRunner {
180
254
  naming: { entry: "[name].[ext]", chunk: "chunk-[hash].[ext]" },
181
255
  define: { "process.env.NODE_ENV": JSON.stringify("production") }
182
256
  };
183
- const serverEnvPlugin = createServerEnvPlugin({
184
- envDir: path2.join(this.#app.cwdPath, "env"),
185
- environment: this.#environment ?? baseDevEnv.env,
186
- environments: ["local", "testing", ...branches]
187
- });
257
+ const serverEnvPlugin = this.#serverEnvPlugin(baseDevEnv.env, branches);
188
258
  const backendConfig = {
189
259
  ...sharedConfig,
190
260
  plugins: [this.#createExternalSpecifiersPlugin(externalLibs), serverEnvPlugin]
@@ -251,71 +321,13 @@ void run().catch((error) => {
251
321
  this.#app.log(`[cli] no route files under ${this.#app.cwdPath}/page \u2014 skipping SSR build`);
252
322
  return null;
253
323
  }
254
- const base = await new SsrBaseArtifactBuilder(this.#app, "build").build();
324
+ const { baseDevEnv, branches } = await this.#app.getConfig();
325
+ const base = await new SsrBaseArtifactBuilder(this.#app, "build", {
326
+ serverEnv: this.#serverEnvPlugin(baseDevEnv.env, branches)
327
+ }).build();
255
328
  const allRoutes = await new AllRoutesBuilder(this.#app, base.artifact, "build").build();
256
329
  return { base, allRoutes };
257
330
  }
258
- async#writeTypecheckTsconfig(incremental) {
259
- const typecheckDir = path2.join(this.#app.cwdPath, ".akan", "typecheck");
260
- await mkdir(typecheckDir, { recursive: true });
261
- const libPageIncludes = (await this.#app.getPageRoots()).filter((root) => root.keyPrefix).flatMap((root) => {
262
- const rel = path2.relative(typecheckDir, root.realDir).split(path2.sep).join("/");
263
- return [`${rel}/**/*.ts`, `${rel}/**/*.tsx`];
264
- });
265
- const tsconfig = {
266
- extends: "../../tsconfig.json",
267
- compilerOptions: {
268
- noEmit: true,
269
- incremental,
270
- tsBuildInfoFile: "./tsconfig.tsbuildinfo"
271
- },
272
- include: [
273
- "../../main.ts",
274
- "../../server.ts",
275
- "../../client.ts",
276
- "../../page/**/*.ts",
277
- "../../page/**/*.tsx",
278
- ...libPageIncludes,
279
- "../../../../pkgs/akanjs/*/types/**/*.d.ts"
280
- ],
281
- references: []
282
- };
283
- const tsconfigPath = path2.join(typecheckDir, "tsconfig.json");
284
- await Bun.write(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
285
- `);
286
- return { typecheckDir, tsconfigPath };
287
- }
288
- async#checkProjectInChildProcess(tsconfigPath) {
289
- const entry = await this.#resolveTypecheckWorkerEntry();
290
- const proc = Bun.spawn([process.execPath, entry], {
291
- cwd: this.#app.workspace.workspaceRoot,
292
- env: this.#app.getCommandEnv({
293
- AKAN_COMMAND_TYPE: "typecheck",
294
- AKAN_TYPECHECK_TSCONFIG: tsconfigPath
295
- }),
296
- stdout: "pipe",
297
- stderr: "pipe"
298
- });
299
- const [stdout, stderr, exitCode] = await Promise.all([
300
- new Response(proc.stdout).text(),
301
- new Response(proc.stderr).text(),
302
- proc.exited
303
- ]);
304
- if (exitCode !== 0)
305
- throw new Error((stderr || stdout).trim() || `Typecheck failed with exit code ${exitCode}`);
306
- }
307
- async#resolveTypecheckWorkerEntry() {
308
- const candidates = [
309
- path2.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
310
- path2.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
311
- path2.join(import.meta.dir, "typecheck.proc.js"),
312
- path2.join(import.meta.dir, "typecheck.proc.ts")
313
- ];
314
- for (const candidate of candidates)
315
- if (await Bun.file(candidate).exists())
316
- return candidate;
317
- throw new Error(`[cli] typecheck worker entry not found; looked in: ${candidates.join(", ")}`);
318
- }
319
331
  async#buildOrThrow(label, config) {
320
332
  const result = await Bun.build(config);
321
333
  if (!result.success)
@@ -6,7 +6,7 @@ import {
6
6
  resolveSsrPageEntriesForApp,
7
7
  WorkspaceExecutor,
8
8
  AppExecutor
9
- } from "./index-50wb2a26.js";
9
+ } from "./index-55mynnqs.js";
10
10
  import {
11
11
  computeRouteSeedIndex,
12
12
  saveRouteSeedIndex,
@@ -14,14 +14,14 @@ import {
14
14
  PagesBundleBuilder,
15
15
  CsrDevBundler,
16
16
  SsrDevBundler
17
- } from "./index-gtjgnv36.js";
17
+ } from "./index-aprt7pkz.js";
18
18
  import"./index-52w0fvh8.js";
19
19
  import {
20
20
  CsrArtifactBuilder,
21
21
  CssCompiler,
22
22
  FontOptimizer,
23
23
  SsrBaseArtifactBuilder
24
- } from "./index-z750gk1j.js";
24
+ } from "./index-c2yrsxdh.js";
25
25
  import"./index-n68jx79w.js";
26
26
 
27
27
  // pkgs/@akanjs/devkit/incrementalBuilder/buildBatch.proc.ts
@@ -44,6 +44,8 @@ class BuildBatch {
44
44
  await this.#buildBase();
45
45
  if (this.#request.needs.includes("csr"))
46
46
  await this.#buildCsr();
47
+ if (this.#request.needs.includes("shell"))
48
+ await this.#buildShell();
47
49
  if (this.#request.needs.includes("ssr"))
48
50
  await this.#buildSsrRegistry();
49
51
  if (this.#request.needs.includes("css"))
@@ -77,7 +79,7 @@ class BuildBatch {
77
79
  const message = ApplicationBuildReporter.formatError(err, this.#request.workspaceRoot);
78
80
  this.#logger.error(`${label} failed: ${message}`);
79
81
  this.#result.errors[need] = message;
80
- if (need !== "base")
82
+ if (need !== "base" && need !== "shell")
81
83
  this.#emitStatus(need, message);
82
84
  }
83
85
  async#buildBase() {
@@ -103,8 +105,17 @@ class BuildBatch {
103
105
  this.#fail("csr", "csr-rebundle", err);
104
106
  }
105
107
  }
108
+ async#buildShell() {
109
+ const started = Date.now();
110
+ try {
111
+ await new CsrArtifactBuilder(this.#app, "start", "en", { cssAssets: this.#request.cssAssets }).build();
112
+ this.#logger.verbose(`csr-shell ok (${Date.now() - started}ms)`);
113
+ } catch (err) {
114
+ this.#fail("shell", "csr-shell", err);
115
+ }
116
+ }
106
117
  async#rebuildCsrArtifact(started) {
107
- await new CsrArtifactBuilder(this.#app).build();
118
+ await new CsrArtifactBuilder(this.#app, "start", "en", { cssAssets: this.#request.cssAssets }).build();
108
119
  this.#logger.verbose(`csr-rebundle ok (${Date.now() - started}ms)`);
109
120
  if (this.#request.changedFiles.length === 0)
110
121
  return;