@akanjs/cli 2.1.1-rc.2 → 2.1.2-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.
package/index.js CHANGED
@@ -203,11 +203,13 @@ class HttpClient {
203
203
  class CloudApi {
204
204
  #api;
205
205
  #accessToken = null;
206
- static async fromHost(host) {
206
+ #workspace;
207
+ static async fromHost(workspace, host) {
207
208
  const hostConfig = await GlobalConfig.getHostConfig(host);
208
- return new CloudApi(hostConfig);
209
+ return new CloudApi(workspace, hostConfig);
209
210
  }
210
- constructor(hostConfig) {
211
+ constructor(workspace, hostConfig) {
212
+ this.#workspace = workspace;
211
213
  const host = akanCloudHost;
212
214
  this.#api = new HttpClient(`${host}/api`);
213
215
  this.#accessToken = hostConfig.auth?.accessToken ?? null;
@@ -223,16 +225,17 @@ class CloudApi {
223
225
  const data = await this.#api.post(`/uploadEnv/${devProjectId}`, formData);
224
226
  return data;
225
227
  }
226
- async downloadEnv(devProjectId, localPath) {
228
+ async downloadEnv(devProjectId) {
229
+ const localPath = `${this.#workspace.workspaceRoot}/local/env.tar`;
227
230
  await this.#api.getFile(`/downloadEnv/${devProjectId}`, localPath);
228
231
  }
229
232
  async getRemoteAuthToken(remoteId) {
230
233
  try {
231
234
  if (this.#accessToken) {
232
235
  if (GlobalConfig.needRefreshToken(this.#accessToken))
233
- return await this.refreshAuthToken();
236
+ return await this.#refreshAuthToken();
234
237
  else
235
- return await this.refreshAuthToken();
238
+ return await this.#refreshAuthToken();
236
239
  }
237
240
  const accessToken = await this.#api.get(`/getRemoteAuthToken/${remoteId}`);
238
241
  this.#accessToken = GlobalConfig.toAccessToken(accessToken);
@@ -244,10 +247,14 @@ class CloudApi {
244
247
  return null;
245
248
  }
246
249
  }
247
- async refreshAuthToken() {
248
- const response = await this.#api.post(`/refreshRemoteAuthToken`, {
249
- refreshToken: this.#accessToken?.refreshToken
250
- });
250
+ async#refreshAuthToken() {
251
+ const refreshToken = this.#accessToken?.refreshToken;
252
+ if (!refreshToken)
253
+ throw new Error("No refresh token");
254
+ return await this.refreshAuthToken(refreshToken);
255
+ }
256
+ async refreshAuthToken(refreshToken) {
257
+ const response = await this.#api.post(`/refreshRemoteAuthToken`, { refreshToken });
251
258
  this.#accessToken = GlobalConfig.toAccessToken(response);
252
259
  this.#api.setHeaders({ Authorization: `Bearer ${this.#accessToken.jwt}` });
253
260
  return this.#accessToken;
@@ -327,6 +334,31 @@ var supportedLlmModels = [
327
334
  "deepseek-chat",
328
335
  "deepseek-reasoner"
329
336
  ];
337
+ var parseTypescriptFileBlocks = (text) => {
338
+ const fileBlocks = [];
339
+ const codeBlockRegex = /```(?:typescript|ts|tsx)\s*\n([\s\S]*?)```/gi;
340
+ const filePathRegex = /^\s*\/\/\s*File:\s*(.+?)\s*$/im;
341
+ for (const codeBlock of text.matchAll(codeBlockRegex)) {
342
+ const content = codeBlock[1]?.trim();
343
+ if (!content)
344
+ continue;
345
+ const filePath = filePathRegex.exec(content)?.[1]?.trim();
346
+ if (!filePath)
347
+ continue;
348
+ fileBlocks.push({
349
+ filePath,
350
+ content: content.replace(filePathRegex, "").trim()
351
+ });
352
+ }
353
+ return fileBlocks;
354
+ };
355
+ var preserveTypescriptResponseContent = (previousContent, nextContent) => {
356
+ const previousWrites = parseTypescriptFileBlocks(previousContent);
357
+ const nextWrites = parseTypescriptFileBlocks(nextContent);
358
+ if (previousWrites.length > 0 && nextWrites.length === 0)
359
+ return previousContent;
360
+ return nextContent;
361
+ };
330
362
 
331
363
  class AiSession {
332
364
  static #cacheDir = "node_modules/.cache/akan/aiSession";
@@ -446,7 +478,7 @@ class AiSession {
446
478
  const humanMessage = new HumanMessage(question);
447
479
  this.messageHistory.push(humanMessage);
448
480
  const stream = await AiSession.#chat.stream(this.messageHistory);
449
- let reasoningResponse = "", fullResponse = "", tokenIdx = 0;
481
+ let reasoningResponse = "", fullResponse = "";
450
482
  for await (const chunk of stream) {
451
483
  if (loader.isSpinning())
452
484
  loader.succeed(`${AiSession.#chat.model} responded`);
@@ -467,7 +499,6 @@ class AiSession {
467
499
  fullResponse += content;
468
500
  onChunk(content);
469
501
  }
470
- tokenIdx++;
471
502
  }
472
503
  fullResponse += `
473
504
  `;
@@ -475,7 +506,7 @@ class AiSession {
475
506
  `);
476
507
  this.messageHistory.push(new AIMessage(fullResponse));
477
508
  return { content: fullResponse, messageHistory: this.messageHistory };
478
- } catch (error) {
509
+ } catch {
479
510
  loader.fail(`${AiSession.#chat.model} failed to respond`);
480
511
  throw new Error("Failed to stream response");
481
512
  }
@@ -485,7 +516,8 @@ class AiSession {
485
516
  onReasoning,
486
517
  maxTry = MAX_ASK_TRY,
487
518
  validate,
488
- approve
519
+ approve,
520
+ fallbackToPreviousTypescript
489
521
  } = {}) {
490
522
  for (let tryCount = 0;tryCount < maxTry; tryCount++) {
491
523
  let response = await this.ask(question, { onChunk, onReasoning });
@@ -493,7 +525,14 @@ class AiSession {
493
525
  const validateQuestion = `Double check if the response meets the requirements and conditions, and follow the instructions. If not, rewrite it.
494
526
  ${validate.map((v) => `- ${v}`).join(`
495
527
  `)}`;
496
- response = await this.ask(validateQuestion, { onChunk, onReasoning });
528
+ const validateResponse = await this.ask(validateQuestion, {
529
+ onChunk,
530
+ onReasoning
531
+ });
532
+ response = {
533
+ ...validateResponse,
534
+ content: fallbackToPreviousTypescript ? preserveTypescriptResponseContent(response.content, validateResponse.content) : validateResponse.content
535
+ };
497
536
  }
498
537
  const isConfirmed = approve ? true : await select({
499
538
  message: "Do you want to edit the response?",
@@ -526,15 +565,28 @@ ${validate.map((v) => `- ${v}`).join(`
526
565
  return this;
527
566
  }
528
567
  async writeTypescripts(question, executor, options = {}) {
529
- const content = await this.edit(question, options);
568
+ const content = await this.edit(question, {
569
+ ...options,
570
+ fallbackToPreviousTypescript: true
571
+ });
530
572
  const writes = this.#getTypescriptCodes(content);
573
+ if (!writes.length)
574
+ throw new Error("No parseable TypeScript file blocks were found in the AI response. Include `// File: <path>` in each code block.");
531
575
  for (const write of writes)
532
576
  await executor.writeFile(write.filePath, write.content);
533
577
  return await this.#tryFixTypescripts(writes, executor, options);
534
578
  }
535
- async#editTypescripts(question, options = {}) {
536
- const content = await this.edit(question, options);
537
- return this.#getTypescriptCodes(content);
579
+ async#editTypescripts(question, options = {}, fallbackWrites) {
580
+ const content = await this.edit(question, {
581
+ ...options,
582
+ fallbackToPreviousTypescript: true
583
+ });
584
+ const writes = this.#getTypescriptCodes(content);
585
+ if (!writes.length && fallbackWrites?.length)
586
+ return fallbackWrites;
587
+ if (!writes.length)
588
+ throw new Error("No parseable TypeScript file blocks were found in the AI response. Include `// File: <path>` in each code block.");
589
+ return writes;
538
590
  }
539
591
  async#tryFixTypescripts(writes, executor, options = {}) {
540
592
  const MAX_EDIT_TRY = 5;
@@ -543,13 +595,15 @@ ${validate.map((v) => `- ${v}`).join(`
543
595
  prefix: `\uD83E\uDD16akan-editor`
544
596
  }).start();
545
597
  const fileChecks = await Promise.all(writes.map(async ({ filePath }) => {
546
- const typeCheckResult = executor.typeCheck(filePath);
547
- const lintResult = await executor.lint(filePath);
548
- const needFix2 = !!typeCheckResult.fileErrors.length || !!lintResult.errors.length;
549
- return { filePath, typeCheckResult, lintResult, needFix: needFix2 };
598
+ const lintResult = await executor.lint(filePath, { fix: true });
599
+ const typeCheckResult = await executor.typeCheckAsync(filePath);
600
+ const hasTypeErrors = typeCheckResult.fileErrors.length > 0;
601
+ const hasLintErrors = lintResult.errors.length > 0;
602
+ const needFix = hasTypeErrors || hasLintErrors;
603
+ return { filePath, typeCheckResult, lintResult, needFix };
550
604
  }));
551
- const needFix = fileChecks.some((fileCheck) => fileCheck.needFix);
552
- if (needFix) {
605
+ const hasAnyFix = fileChecks.some((fileCheck) => fileCheck.needFix);
606
+ if (hasAnyFix) {
553
607
  loader.fail("Type checking and linting has some errors, try to fix them");
554
608
  fileChecks.forEach((fileCheck) => {
555
609
  Logger2.rawLog(`TypeCheck Result
@@ -565,7 +619,7 @@ ${fileCheck.lintResult.message}`);
565
619
  ...options,
566
620
  validate: undefined,
567
621
  approve: true
568
- });
622
+ }, writes);
569
623
  for (const write of writes)
570
624
  await executor.writeFile(write.filePath, write.content);
571
625
  } else {
@@ -576,21 +630,7 @@ ${fileCheck.lintResult.message}`);
576
630
  throw new Error("Failed to create scalar");
577
631
  }
578
632
  #getTypescriptCodes(text) {
579
- const codes = text.match(/```(typescript|tsx)([\s\S]*?)```/g);
580
- if (!codes)
581
- return [];
582
- const result = codes.map((code) => {
583
- const content = /```(typescript|tsx)([\s\S]*?)```/.exec(code)?.[2];
584
- if (!content)
585
- return null;
586
- const filePath = /\/\/ File: (.*?)(?:\n|$)/.exec(content)?.[1]?.trim();
587
- if (!filePath)
588
- return null;
589
- const contentWithoutFilepath = content.replace(`// File: ${filePath}
590
- `, "").trim();
591
- return { filePath, content: contentWithoutFilepath };
592
- });
593
- return result.filter((code) => code !== null);
633
+ return parseTypescriptFileBlocks(text);
594
634
  }
595
635
  async editMarkdown(request, options = {}) {
596
636
  const content = await this.edit(request, options);
@@ -608,13 +648,13 @@ ${fileCheck.lintResult.message}`);
608
648
  }
609
649
  // pkgs/@akanjs/devkit/akanApp/akanApp.host.ts
610
650
  import path9 from "path";
611
- import { Logger as Logger6 } from "akanjs/common";
651
+ import { Logger as Logger5 } from "akanjs/common";
612
652
 
613
653
  // pkgs/@akanjs/devkit/executors.ts
614
654
  import {
615
655
  exec,
616
656
  fork,
617
- spawn
657
+ spawn as spawn2
618
658
  } from "child_process";
619
659
  import { readFileSync as readFileSync3 } from "fs";
620
660
  import { copyFile, mkdir as mkdir2, readdir as readDirEntries, stat as stat2 } from "fs/promises";
@@ -622,7 +662,7 @@ import path7 from "path";
622
662
  import {
623
663
  capitalize,
624
664
  isRouteSourceFile,
625
- Logger as Logger4,
665
+ Logger as Logger3,
626
666
  parseRouteModuleKey,
627
667
  validatePageSourceFile,
628
668
  validateSubRoutePageKey
@@ -669,8 +709,18 @@ var DEFAULT_OPTIMIZE_IMPORTS = [
669
709
  "mui-core",
670
710
  "react-icons/*"
671
711
  ];
672
- var WORKSPACE_BARREL_FACETS = ["ui", "webkit", "common", "client", "server"];
673
- var SSR_RUNTIME_PACKAGES = ["react", "react-dom", "react-server-dom-webpack"];
712
+ var WORKSPACE_BARREL_FACETS = [
713
+ "ui",
714
+ "webkit",
715
+ "common",
716
+ "client",
717
+ "server"
718
+ ];
719
+ var SSR_RUNTIME_PACKAGES = [
720
+ "react",
721
+ "react-dom",
722
+ "react-server-dom-webpack"
723
+ ];
674
724
  var NATIVE_RUNTIME_PACKAGES = ["sharp"];
675
725
  var DEFAULT_BACKEND_RUNTIME_PACKAGES = ["croner"];
676
726
  var DATABASE_MODE_RUNTIME_PACKAGES = {
@@ -730,7 +780,12 @@ class AkanAppConfig {
730
780
  ...libs.flatMap((lib) => WORKSPACE_BARREL_FACETS.map((facet) => `@libs/${lib}/${facet}`)),
731
781
  ...config?.barrelImports ?? []
732
782
  ];
733
- this.optimizeImports = [...new Set([...DEFAULT_OPTIMIZE_IMPORTS, ...config?.optimizeImports ?? []])];
783
+ this.optimizeImports = [
784
+ ...new Set([
785
+ ...DEFAULT_OPTIMIZE_IMPORTS,
786
+ ...config?.optimizeImports ?? []
787
+ ])
788
+ ];
734
789
  this.images = mergeImageConfig(config?.images);
735
790
  this.i18n = resolveAkanI18nConfig(config?.i18n);
736
791
  process.env.AKAN_PUBLIC_DEFAULT_LOCALE = this.i18n.defaultLocale;
@@ -841,7 +896,13 @@ class AkanAppConfig {
841
896
  }
842
897
  #makeDockerContent(docker) {
843
898
  if (docker.content)
844
- return { content: docker.content, image: {}, preRuns: [], postRuns: [], command: [] };
899
+ return {
900
+ content: docker.content,
901
+ image: {},
902
+ preRuns: [],
903
+ postRuns: [],
904
+ command: []
905
+ };
845
906
  const preRunScripts = this.#getDockerRunScripts(docker.preRuns ?? []);
846
907
  const postRunScripts = this.#getDockerRunScripts(docker.postRuns ?? []);
847
908
  const imageScript = docker.image ? this.#getDockerImageScript(docker.image, "oven/bun:1-slim") : "FROM oven/bun:1-slim";
@@ -872,7 +933,13 @@ ENV AKAN_PUBLIC_LOCALES=${this.i18n.locales.join(",")}
872
933
  ENV AKAN_PUBLIC_OPERATION_MODE=cloud
873
934
 
874
935
  CMD [${command.map((c) => `"${c}"`).join(",")}]`;
875
- return { content, image: imageScript, preRuns: docker.preRuns ?? [], postRuns: docker.postRuns ?? [], command };
936
+ return {
937
+ content,
938
+ image: imageScript,
939
+ preRuns: docker.preRuns ?? [],
940
+ postRuns: docker.postRuns ?? [],
941
+ command
942
+ };
876
943
  }
877
944
  static async from(app) {
878
945
  const [configImp, baseDevEnv, libs, rootPackageJson] = await Promise.all([
@@ -898,9 +965,24 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
898
965
  ...SSR_RUNTIME_PACKAGES,
899
966
  ...NATIVE_RUNTIME_PACKAGES,
900
967
  ...DEFAULT_BACKEND_RUNTIME_PACKAGES,
901
- ...DATABASE_MODE_RUNTIME_PACKAGES[this.defaultDatabaseMode]
968
+ ...this.getDatabaseModeRuntimePackages()
902
969
  ];
903
970
  }
971
+ getDatabaseModeRuntimePackages(databaseMode = this.defaultDatabaseMode) {
972
+ return [...DATABASE_MODE_RUNTIME_PACKAGES[databaseMode]];
973
+ }
974
+ getMissingDatabaseModeDependencySpecs(databaseMode = this.defaultDatabaseMode) {
975
+ const rootDependencies = {
976
+ ...this.rootPackageJson.dependencies,
977
+ ...this.rootPackageJson.devDependencies
978
+ };
979
+ return this.getDatabaseModeRuntimePackages(databaseMode).filter((lib) => !rootDependencies[lib]).map((lib) => {
980
+ const version = this.#resolveProductionDependencyVersion(lib);
981
+ if (!version)
982
+ throw new Error(`Dependency ${lib} not found in package.json`);
983
+ return `${lib}@${version}`;
984
+ });
985
+ }
904
986
  getProductionPackageJson(data = {}) {
905
987
  return {
906
988
  name: this.app.name,
@@ -936,7 +1018,12 @@ function getAkanPackageJson() {
936
1018
  return akanPackageJson;
937
1019
  } catch {}
938
1020
  }
939
- akanPackageJson = { name: "akanjs", version: "0.0.0", description: "akanjs", dependencies: {} };
1021
+ akanPackageJson = {
1022
+ name: "akanjs",
1023
+ version: "0.0.0",
1024
+ description: "akanjs",
1025
+ dependencies: {}
1026
+ };
940
1027
  return akanPackageJson;
941
1028
  }
942
1029
  function mergeImageConfig(config = {}) {
@@ -960,7 +1047,9 @@ class AkanLibConfig {
960
1047
  this.externalLibs = config?.externalLibs ?? [];
961
1048
  }
962
1049
  static async from(lib) {
963
- const [configImp] = await Promise.all([import(`${lib.cwdPath}/akan.config.ts`).then((mod) => mod.default)]);
1050
+ const [configImp] = await Promise.all([
1051
+ import(`${lib.cwdPath}/akan.config.ts`).then((mod) => mod.default)
1052
+ ]);
964
1053
  const config = typeof configImp === "function" ? configImp(lib) : configImp;
965
1054
  return new AkanLibConfig(lib, config);
966
1055
  }
@@ -985,23 +1074,146 @@ import path2 from "path";
985
1074
  var getDirname = (url) => path2.dirname(new URL(url).pathname);
986
1075
 
987
1076
  // pkgs/@akanjs/devkit/linter.ts
1077
+ import { spawn } from "child_process";
988
1078
  import { existsSync, readFileSync } from "fs";
989
- import * as path3 from "path";
990
- import { Logger as Logger3 } from "akanjs/common";
1079
+ import path3 from "path";
991
1080
  import chalk2 from "chalk";
992
1081
 
993
1082
  class Linter {
994
- #logger = new Logger3("Linter");
995
1083
  lintRoot;
1084
+ #biomeBin;
996
1085
  constructor(cwdPath) {
997
- this.lintRoot = this.#findEslintRootPath(cwdPath);
1086
+ this.lintRoot = this.#findBiomeRootPath(cwdPath);
1087
+ const localBiomeBin = path3.join(this.lintRoot, "node_modules/.bin/biome");
1088
+ this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
998
1089
  }
999
- #findEslintRootPath(dir) {
1000
- const configPath2 = path3.join(dir, "eslint.config.ts");
1090
+ #findBiomeRootPath(dir) {
1091
+ const configPath2 = path3.join(dir, "biome.json");
1001
1092
  if (existsSync(configPath2))
1002
1093
  return dir;
1003
1094
  const parentDir = path3.dirname(dir);
1004
- return this.#findEslintRootPath(parentDir);
1095
+ if (parentDir === dir)
1096
+ throw new Error(`biome.json not found from ${dir}`);
1097
+ return this.#findBiomeRootPath(parentDir);
1098
+ }
1099
+ #toBiomePath(filePath) {
1100
+ const relativePath = path3.relative(this.lintRoot, filePath);
1101
+ if (!relativePath.startsWith("..") && !path3.isAbsolute(relativePath))
1102
+ return relativePath;
1103
+ return filePath;
1104
+ }
1105
+ #resolveFilePath(filePath) {
1106
+ return path3.isAbsolute(filePath) ? filePath : path3.join(this.lintRoot, filePath);
1107
+ }
1108
+ async#runBiome(args, input2) {
1109
+ return await new Promise((resolve, reject) => {
1110
+ const proc = spawn(this.#biomeBin, args, {
1111
+ cwd: this.lintRoot,
1112
+ stdio: ["pipe", "pipe", "pipe"]
1113
+ });
1114
+ let stdout = "";
1115
+ let stderr = "";
1116
+ proc.stdout.on("data", (data) => {
1117
+ stdout += data.toString();
1118
+ });
1119
+ proc.stderr.on("data", (data) => {
1120
+ stderr += data.toString();
1121
+ });
1122
+ proc.on("error", reject);
1123
+ proc.on("close", (code) => resolve({ stdout, stderr, code }));
1124
+ proc.stdin.end(input2);
1125
+ });
1126
+ }
1127
+ #parseBiomeReport(output) {
1128
+ const jsonStart = output.indexOf("{");
1129
+ const jsonEnd = output.lastIndexOf("}");
1130
+ if (jsonStart === -1 || jsonEnd === -1 || jsonEnd < jsonStart)
1131
+ throw new Error(output.trim() || "No Biome JSON output");
1132
+ return JSON.parse(output.slice(jsonStart, jsonEnd + 1));
1133
+ }
1134
+ #diagnosticFilePath(diagnostic, fallbackFilePath) {
1135
+ const diagnosticPath = diagnostic.location?.path;
1136
+ if (!diagnosticPath)
1137
+ return fallbackFilePath;
1138
+ return path3.isAbsolute(diagnosticPath) ? diagnosticPath : path3.join(this.lintRoot, diagnosticPath);
1139
+ }
1140
+ #createLintMessage(diagnostic) {
1141
+ const start = diagnostic.location?.start;
1142
+ const end = diagnostic.location?.end;
1143
+ return {
1144
+ line: Math.max(1, start?.line ?? 1),
1145
+ column: Math.max(1, start?.column ?? 1),
1146
+ endLine: end?.line,
1147
+ endColumn: end?.column,
1148
+ message: diagnostic.message,
1149
+ ruleId: diagnostic.category ?? null,
1150
+ severity: diagnostic.severity === "error" ? 2 : 1
1151
+ };
1152
+ }
1153
+ #toLintResults(report, filePath) {
1154
+ const resultsByPath = new Map;
1155
+ for (const diagnostic of report.diagnostics ?? []) {
1156
+ if (diagnostic.severity !== "error" && diagnostic.severity !== "warning")
1157
+ continue;
1158
+ const diagnosticFilePath = this.#diagnosticFilePath(diagnostic, filePath);
1159
+ const result = resultsByPath.get(diagnosticFilePath) ?? {
1160
+ filePath: diagnosticFilePath,
1161
+ messages: [],
1162
+ errorCount: 0,
1163
+ warningCount: 0,
1164
+ fixableErrorCount: 0,
1165
+ fixableWarningCount: 0
1166
+ };
1167
+ const message = this.#createLintMessage(diagnostic);
1168
+ result.messages.push(message);
1169
+ if (message.severity === 2)
1170
+ result.errorCount += 1;
1171
+ else
1172
+ result.warningCount += 1;
1173
+ resultsByPath.set(diagnosticFilePath, result);
1174
+ }
1175
+ return [
1176
+ resultsByPath.get(filePath) ?? {
1177
+ filePath,
1178
+ messages: [],
1179
+ errorCount: 0,
1180
+ warningCount: 0,
1181
+ fixableErrorCount: 0,
1182
+ fixableWarningCount: 0
1183
+ },
1184
+ ...[...resultsByPath.entries()].filter(([resultPath]) => resultPath !== filePath).map(([, result]) => result)
1185
+ ];
1186
+ }
1187
+ #splitMessages(results) {
1188
+ const messages = results.flatMap((result) => result.messages);
1189
+ return {
1190
+ errors: messages.filter((message) => message.severity === 2),
1191
+ warnings: messages.filter((message) => message.severity === 1)
1192
+ };
1193
+ }
1194
+ async#checkFile(filePath, { write = false } = {}) {
1195
+ const originalContent = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
1196
+ const { stdout, stderr } = await this.#runBiome([
1197
+ "check",
1198
+ ...write ? ["--write"] : [],
1199
+ "--reporter=json",
1200
+ "--max-diagnostics=none",
1201
+ "--no-errors-on-unmatched",
1202
+ "--config-path",
1203
+ path3.join(this.lintRoot, "biome.json"),
1204
+ this.#toBiomePath(filePath)
1205
+ ]);
1206
+ const report = this.#parseBiomeReport(stdout || stderr);
1207
+ const results = this.#toLintResults(report, filePath);
1208
+ const { errors, warnings } = this.#splitMessages(results);
1209
+ const output = write && existsSync(filePath) ? readFileSync(filePath, "utf8") : undefined;
1210
+ return {
1211
+ fixed: write && output !== originalContent,
1212
+ output,
1213
+ results,
1214
+ errors,
1215
+ warnings
1216
+ };
1005
1217
  }
1006
1218
  async lint(filePath, { fix = false, dryRun = false } = {}) {
1007
1219
  if (fix)
@@ -1009,9 +1221,10 @@ class Linter {
1009
1221
  return await this.lintFile(filePath);
1010
1222
  }
1011
1223
  async lintFile(filePath) {
1012
- if (!existsSync(filePath))
1224
+ const resolvedFilePath = this.#resolveFilePath(filePath);
1225
+ if (!existsSync(resolvedFilePath))
1013
1226
  throw new Error(`File not found: ${filePath}`);
1014
- return { fixed: false, results: [], errors: [], warnings: [] };
1227
+ return await this.#checkFile(resolvedFilePath);
1015
1228
  }
1016
1229
  formatLintResults(results) {
1017
1230
  if (results.length === 0)
@@ -1031,12 +1244,12 @@ ${chalk2.cyan(result.filePath)}`);
1031
1244
  const sourceContent = readFileSync(result.filePath, "utf8");
1032
1245
  sourceLines = sourceContent.split(`
1033
1246
  `);
1034
- } catch (error) {}
1247
+ } catch {}
1035
1248
  }
1036
1249
  result.messages.forEach((message) => {
1037
1250
  const type = message.severity === 2 ? "error" : "warning";
1038
1251
  const typeColor = message.severity === 2 ? chalk2.red : chalk2.yellow;
1039
- const icon = message.severity === 2 ? "\u274C" : "\u26A0\uFE0F";
1252
+ const icon = message.severity === 2 ? "x" : "!";
1040
1253
  const ruleInfo = message.ruleId ? chalk2.dim(` (${message.ruleId})`) : "";
1041
1254
  output.push(`
1042
1255
  ${icon} ${typeColor(type)}: ${message.message}${ruleInfo}`);
@@ -1055,7 +1268,7 @@ ${chalk2.dim(`${lineNumber} |`)} ${sourceLine}`);
1055
1268
  }
1056
1269
  });
1057
1270
  if (totalErrors === 0 && totalWarnings === 0)
1058
- return chalk2.bold("\u2705 No ESLint errors or warnings found");
1271
+ return chalk2.bold("No Biome errors or warnings found");
1059
1272
  const errorText = totalErrors > 0 ? chalk2.red(`${totalErrors} error(s)`) : "0 errors";
1060
1273
  const warningText = totalWarnings > 0 ? chalk2.yellow(`${totalWarnings} warning(s)`) : "0 warnings";
1061
1274
  const summary = [`
@@ -1070,23 +1283,26 @@ ${errorText}, ${warningText} found`];
1070
1283
  column: message.column,
1071
1284
  message: message.message,
1072
1285
  ruleId: message.ruleId,
1073
- severity: message.severity === 2 ? "error" : "warning",
1074
- fix: message.fix,
1075
- suggestions: message.suggestions
1286
+ severity: message.severity === 2 ? "error" : "warning"
1076
1287
  })));
1077
1288
  const stats = results.reduce((acc, result) => ({
1078
1289
  errorCount: acc.errorCount + result.errorCount,
1079
1290
  warningCount: acc.warningCount + result.warningCount,
1080
1291
  fixableErrorCount: acc.fixableErrorCount + result.fixableErrorCount,
1081
1292
  fixableWarningCount: acc.fixableWarningCount + result.fixableWarningCount
1082
- }), { errorCount: 0, warningCount: 0, fixableErrorCount: 0, fixableWarningCount: 0 });
1293
+ }), {
1294
+ errorCount: 0,
1295
+ warningCount: 0,
1296
+ fixableErrorCount: 0,
1297
+ fixableWarningCount: 0
1298
+ });
1083
1299
  return { results, details, stats };
1084
1300
  }
1085
1301
  async hasNoLintErrors(filePath) {
1086
1302
  try {
1087
1303
  const { results } = await this.lintFile(filePath);
1088
1304
  return results.every((result) => result.errorCount === 0);
1089
- } catch (error) {
1305
+ } catch {
1090
1306
  return false;
1091
1307
  }
1092
1308
  }
@@ -1099,12 +1315,28 @@ ${errorText}, ${warningText} found`];
1099
1315
  return results.flatMap((result) => result.messages.filter((message) => message.severity === 1));
1100
1316
  }
1101
1317
  async fixFile(filePath, dryRun = false) {
1102
- if (!existsSync(filePath))
1318
+ const resolvedFilePath = this.#resolveFilePath(filePath);
1319
+ if (!existsSync(resolvedFilePath))
1103
1320
  throw new Error(`File not found: ${filePath}`);
1104
- return { fixed: false, output: undefined, results: [], errors: [], warnings: [] };
1321
+ if (!dryRun)
1322
+ return await this.#checkFile(resolvedFilePath, { write: true });
1323
+ const source = readFileSync(resolvedFilePath, "utf8");
1324
+ const { stdout } = await this.#runBiome([
1325
+ "check",
1326
+ "--write",
1327
+ "--config-path",
1328
+ path3.join(this.lintRoot, "biome.json"),
1329
+ "--stdin-file-path",
1330
+ this.#toBiomePath(resolvedFilePath)
1331
+ ], source);
1332
+ const lintResult = await this.lintFile(resolvedFilePath);
1333
+ return { ...lintResult, fixed: stdout !== source, output: stdout };
1105
1334
  }
1106
1335
  async getConfigForFile(filePath) {
1107
- return {};
1336
+ const resolvedFilePath = this.#resolveFilePath(filePath);
1337
+ if (!existsSync(resolvedFilePath))
1338
+ throw new Error(`File not found: ${filePath}`);
1339
+ return JSON.parse(readFileSync(path3.join(this.lintRoot, "biome.json"), "utf8"));
1108
1340
  }
1109
1341
  async getProblematicRules(filePath) {
1110
1342
  const { results } = await this.lintFile(filePath);
@@ -1494,23 +1726,23 @@ async function assertScanConvention(exec, libRoot) {
1494
1726
  files.filter((filename) => !appRootAllowedFiles.has(filename)).forEach((filename) => {
1495
1727
  addViolation(filename, "unsupported app root file");
1496
1728
  });
1497
- dirs.filter((dirname2) => !appRootAllowedDirs.has(dirname2)).forEach((dirname2) => {
1498
- addViolation(dirname2, "unsupported app root folder");
1729
+ dirs.filter((dirname) => !appRootAllowedDirs.has(dirname)).forEach((dirname) => {
1730
+ addViolation(dirname, "unsupported app root folder");
1499
1731
  });
1500
1732
  }
1501
1733
  libRoot.files.filter((filename) => !isAllowedLibRootFile(filename)).forEach((filename) => {
1502
1734
  addViolation(path5.join("lib", filename), "unsupported lib root file");
1503
1735
  });
1504
- libRoot.dirs.filter((dirname2) => dirname2.startsWith("__") && !internalLibDirs.has(dirname2)).forEach((dirname2) => {
1505
- addViolation(path5.join("lib", dirname2), "unsupported internal lib folder");
1736
+ libRoot.dirs.filter((dirname) => dirname.startsWith("__") && !internalLibDirs.has(dirname)).forEach((dirname) => {
1737
+ addViolation(path5.join("lib", dirname), "unsupported internal lib folder");
1506
1738
  });
1507
- const databaseDirs = libRoot.dirs.filter((dirname2) => !dirname2.startsWith("_"));
1508
- const serviceDirs = libRoot.dirs.filter((dirname2) => dirname2.startsWith("_") && !dirname2.startsWith("__"));
1739
+ const databaseDirs = libRoot.dirs.filter((dirname) => !dirname.startsWith("_"));
1740
+ const serviceDirs = libRoot.dirs.filter((dirname) => dirname.startsWith("_") && !dirname.startsWith("__"));
1509
1741
  const scalarDirs = await exec.readdir("lib/__scalar");
1510
1742
  await Promise.all([
1511
- ...databaseDirs.map((dirname2) => validateModuleFiles(exec, violations, "database", path5.join("lib", dirname2))),
1512
- ...serviceDirs.map((dirname2) => validateModuleFiles(exec, violations, "service", path5.join("lib", dirname2))),
1513
- ...scalarDirs.map((dirname2) => validateModuleFiles(exec, violations, "scalar", path5.join("lib/__scalar", dirname2)))
1743
+ ...databaseDirs.map((dirname) => validateModuleFiles(exec, violations, "database", path5.join("lib", dirname))),
1744
+ ...serviceDirs.map((dirname) => validateModuleFiles(exec, violations, "service", path5.join("lib", dirname))),
1745
+ ...scalarDirs.map((dirname) => validateModuleFiles(exec, violations, "scalar", path5.join("lib/__scalar", dirname)))
1514
1746
  ]);
1515
1747
  if (violations.length > 0) {
1516
1748
  throw new Error(`[scan-convention]
@@ -1520,8 +1752,8 @@ ${violations.sort().map((violation) => `- ${violation}`).join(`
1520
1752
  }
1521
1753
  async function validateModuleFiles(exec, violations, kind, modulePath) {
1522
1754
  const { files, dirs } = await exec.getFilesAndDirs(modulePath);
1523
- dirs.forEach((dirname2) => {
1524
- violations.push(`${getScanPath(exec, path5.join(modulePath, dirname2))}: unsupported module folder`);
1755
+ dirs.forEach((dirname) => {
1756
+ violations.push(`${getScanPath(exec, path5.join(modulePath, dirname))}: unsupported module folder`);
1525
1757
  });
1526
1758
  files.forEach((filename) => {
1527
1759
  const filePath = path5.join(modulePath, filename);
@@ -1620,9 +1852,9 @@ class ScanInfo {
1620
1852
  files.zone.databases.push(name);
1621
1853
  });
1622
1854
  }),
1623
- ...serviceDirs.map(async (dirname2) => {
1624
- const name = dirname2.slice(1);
1625
- const filenames = await exec.readdir(path5.join("lib", dirname2));
1855
+ ...serviceDirs.map(async (dirname) => {
1856
+ const name = dirname.slice(1);
1857
+ const filenames = await exec.readdir(path5.join("lib", dirname));
1626
1858
  filenames.forEach((filename) => {
1627
1859
  if (filename.endsWith(".dictionary.ts"))
1628
1860
  files.dictionary.services.push(name);
@@ -2252,9 +2484,11 @@ var ROOT_LAYOUT_EXPORTS = new Set([
2252
2484
  "reconnect",
2253
2485
  "layoutStyle",
2254
2486
  "gaTrackingId",
2255
- "Loading"
2487
+ "Loading",
2488
+ "NotFound",
2489
+ "Error"
2256
2490
  ]);
2257
- var LAYOUT_ROUTE_EXPORTS = new Set(["default", "head", "generateHead", "Loading"]);
2491
+ var LAYOUT_ROUTE_EXPORTS = new Set(["default", "head", "generateHead", "Loading", "NotFound", "Error"]);
2258
2492
  function validateRouteSourceExports(source, filePath, kind, options = {}) {
2259
2493
  const sourceFile = ts3.createSourceFile(filePath, source, ts3.ScriptTarget.Latest, true, ts3.ScriptKind.TSX);
2260
2494
  const allowed = kind === "page" ? PAGE_ROUTE_EXPORTS : options.rootLayout ? ROOT_LAYOUT_EXPORTS : LAYOUT_ROUTE_EXPORTS;
@@ -2323,16 +2557,16 @@ class Executor {
2323
2557
  linter = null;
2324
2558
  constructor(name, cwdPath) {
2325
2559
  this.name = name;
2326
- this.logger = new Logger4(name);
2560
+ this.logger = new Logger3(name);
2327
2561
  this.logs = [];
2328
2562
  this.cwdPath = cwdPath;
2329
2563
  }
2330
2564
  #stdout(data) {
2331
2565
  if (Executor.verbose)
2332
- Logger4.raw(chalk4.dim(data.toString()));
2566
+ Logger3.raw(chalk4.dim(data.toString()));
2333
2567
  }
2334
2568
  #stderr(data) {
2335
- Logger4.raw(chalk4.red(data.toString()));
2569
+ Logger3.raw(chalk4.red(data.toString()));
2336
2570
  }
2337
2571
  exec(command, options = {}) {
2338
2572
  const cwd = options.cwd?.toString() ?? this.cwdPath;
@@ -2376,7 +2610,7 @@ class Executor {
2376
2610
  }
2377
2611
  spawn(command, args = [], options = {}) {
2378
2612
  const cwd = options.cwd?.toString() ?? this.cwdPath;
2379
- const proc = spawn(command, args, {
2613
+ const proc = spawn2(command, args, {
2380
2614
  cwd: this.cwdPath,
2381
2615
  ...options
2382
2616
  });
@@ -2422,7 +2656,7 @@ class Executor {
2422
2656
  });
2423
2657
  }
2424
2658
  spawnSync(command, args = [], options = {}) {
2425
- const proc = spawn(command, args, {
2659
+ const proc = spawn2(command, args, {
2426
2660
  cwd: this.cwdPath,
2427
2661
  ...options
2428
2662
  });
@@ -2554,7 +2788,7 @@ class Executor {
2554
2788
  contentStr = currentContent;
2555
2789
  } else {
2556
2790
  await FileSys.writeText(writePath, contentStr);
2557
- if (Logger4.isVerbose())
2791
+ if (Logger3.isVerbose())
2558
2792
  this.logger.rawLog(chalk4.yellow(`File Update: ${filePath}`));
2559
2793
  }
2560
2794
  } else {
@@ -2663,8 +2897,8 @@ class Executor {
2663
2897
  return null;
2664
2898
  const filename = typeof result === "object" ? result.filename : path7.basename(targetPath).replace(".js", ".ts");
2665
2899
  const content = typeof result === "object" ? result.content : result;
2666
- const dirname3 = path7.dirname(targetPath);
2667
- const convertedTargetPath = Object.entries(dict).reduce((path8, [key, value]) => path8.replace(new RegExp(`__${key}__`, "g"), value), `${dirname3}/${filename}`);
2900
+ const dirname2 = path7.dirname(targetPath);
2901
+ const convertedTargetPath = Object.entries(dict).reduce((path8, [key, value]) => path8.replace(new RegExp(`__${key}__`, "g"), value), `${dirname2}/${filename}`);
2668
2902
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2669
2903
  return this.writeFile(convertedTargetPath, content, { overwrite });
2670
2904
  } else if (targetPath.endsWith(".template")) {
@@ -2678,9 +2912,9 @@ class Executor {
2678
2912
  } else if (staticTemplateFileExtensions.has(path7.extname(targetPath).toLowerCase())) {
2679
2913
  const convertedTargetPath = Object.entries(dict).reduce((path8, [key, value]) => path8.replace(new RegExp(`__${key}__`, "g"), value), targetPath);
2680
2914
  const writePath = this.getPath(convertedTargetPath);
2681
- const dirname3 = path7.dirname(writePath);
2682
- if (!await FileSys.dirExists(dirname3))
2683
- await mkdir2(dirname3, { recursive: true });
2915
+ const dirname2 = path7.dirname(writePath);
2916
+ if (!await FileSys.dirExists(dirname2))
2917
+ await mkdir2(dirname2, { recursive: true });
2684
2918
  await copyFile(templatePath, writePath);
2685
2919
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2686
2920
  return { filePath: writePath, content: "" };
@@ -2761,6 +2995,48 @@ class Executor {
2761
2995
  const message = typeChecker.formatDiagnostics(fileDiagnostics);
2762
2996
  return { fileDiagnostics, fileErrors, fileWarnings, message };
2763
2997
  }
2998
+ async typeCheckAsync(filePath) {
2999
+ const path8 = this.getPath(filePath);
3000
+ const entry = await this.#resolveTypecheckWorkerEntry();
3001
+ const proc = Bun.spawn([process.execPath, entry], {
3002
+ cwd: this.cwdPath,
3003
+ env: {
3004
+ ...process.env,
3005
+ AKAN_TYPECHECK_CWD: this.cwdPath,
3006
+ AKAN_TYPECHECK_FILE: path8
3007
+ },
3008
+ stdout: "pipe",
3009
+ stderr: "pipe"
3010
+ });
3011
+ const [stdout, stderr, exitCode] = await Promise.all([
3012
+ new Response(proc.stdout).text(),
3013
+ new Response(proc.stderr).text(),
3014
+ proc.exited
3015
+ ]);
3016
+ if (exitCode !== 0)
3017
+ throw new Error((stderr || stdout).trim() || `Typecheck failed with exit code ${exitCode}`);
3018
+ const result = JSON.parse(stdout);
3019
+ return {
3020
+ fileDiagnostics: Array.from({ length: result.fileDiagnosticsCount }),
3021
+ fileErrors: Array.from({ length: result.fileErrorsCount }),
3022
+ fileWarnings: Array.from({ length: result.fileWarningsCount }),
3023
+ message: result.message
3024
+ };
3025
+ }
3026
+ async#resolveTypecheckWorkerEntry() {
3027
+ const dirname2 = getDirname(import.meta.url);
3028
+ const candidates = [
3029
+ path7.join(process.cwd(), "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
3030
+ path7.join(process.cwd(), "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
3031
+ path7.join(dirname2, "typecheck/typecheck.proc.ts"),
3032
+ path7.join(dirname2, "typecheck.proc.js"),
3033
+ path7.join(dirname2, "typecheck.proc.ts")
3034
+ ];
3035
+ for (const candidate of candidates)
3036
+ if (await Bun.file(candidate).exists())
3037
+ return candidate;
3038
+ throw new Error(`[devkit] typecheck worker entry not found; looked in: ${candidates.join(", ")}`);
3039
+ }
2764
3040
  getLinter() {
2765
3041
  this.linter ??= new Linter(this.cwdPath);
2766
3042
  return this.linter;
@@ -2808,7 +3084,15 @@ class WorkspaceExecutor extends Executor {
2808
3084
  const env = sourceEnv.AKAN_PUBLIC_ENV ?? "debug";
2809
3085
  if (!env)
2810
3086
  throw new Error("AKAN_PUBLIC_ENV is not set");
2811
- return { ...appName ? { appName } : {}, workspaceRoot, repoName, serveDomain, env, portOffset, workspaceId };
3087
+ return {
3088
+ ...appName ? { appName } : {},
3089
+ workspaceRoot,
3090
+ repoName,
3091
+ serveDomain,
3092
+ env,
3093
+ portOffset,
3094
+ workspaceId
3095
+ };
2812
3096
  }
2813
3097
  getWorkspaceId({
2814
3098
  allowEmpty
@@ -2868,12 +3152,12 @@ class WorkspaceExecutor extends Executor {
2868
3152
  }
2869
3153
  async getDirInModule(basePath2, name) {
2870
3154
  const AVOID_DIRS = ["__lib", "__scalar", `_`, `_${name}`];
2871
- const getDirs = async (dirname3, maxDepth = 3, results = [], prefix = "") => {
2872
- const dirs = await this.readdir(dirname3);
3155
+ const getDirs = async (dirname2, maxDepth = 3, results = [], prefix = "") => {
3156
+ const dirs = await this.readdir(dirname2);
2873
3157
  await Promise.all(dirs.map(async (dir) => {
2874
3158
  if (dir.includes("_") || AVOID_DIRS.includes(dir))
2875
3159
  return;
2876
- const dirPath = path7.join(dirname3, dir);
3160
+ const dirPath = path7.join(dirname2, dir);
2877
3161
  if ((await stat2(dirPath)).isDirectory()) {
2878
3162
  results.push(`${prefix}${dir}`);
2879
3163
  if (maxDepth > 0)
@@ -2893,12 +3177,12 @@ class WorkspaceExecutor extends Executor {
2893
3177
  }
2894
3178
  async#getDirHasFile(basePath2, targetFilename) {
2895
3179
  const AVOID_DIRS = ["node_modules", "dist", "public", "webkit"];
2896
- const getDirs = async (dirname3, maxDepth = 3, results = [], prefix = "") => {
2897
- const dirs = await this.readdir(dirname3);
3180
+ const getDirs = async (dirname2, maxDepth = 3, results = [], prefix = "") => {
3181
+ const dirs = await this.readdir(dirname2);
2898
3182
  await Promise.all(dirs.map(async (dir) => {
2899
3183
  if (AVOID_DIRS.includes(dir))
2900
3184
  return;
2901
- const dirPath = path7.join(dirname3, dir);
3185
+ const dirPath = path7.join(dirname2, dir);
2902
3186
  if ((await stat2(dirPath)).isDirectory()) {
2903
3187
  const hasTargetFile = await FileSys.fileExists(path7.join(dirPath, targetFilename));
2904
3188
  if (hasTargetFile)
@@ -3163,6 +3447,13 @@ class AppExecutor extends SysExecutor {
3163
3447
  getEnv() {
3164
3448
  return WorkspaceExecutor.getBaseDevEnv().env;
3165
3449
  }
3450
+ async getDevPort() {
3451
+ const basePort = 8282;
3452
+ const appNames = (await this.workspace.getApps()).sort((a, b) => a.localeCompare(b));
3453
+ const appIndex = Math.max(appNames.indexOf(this.name), 0);
3454
+ const portOffset = WorkspaceExecutor.getBaseDevEnv().portOffset;
3455
+ return basePort + appIndex + portOffset;
3456
+ }
3166
3457
  getCommandEnv(env = {}) {
3167
3458
  const basePort = 8282;
3168
3459
  const portOffset = WorkspaceExecutor.getBaseDevEnv().portOffset;
@@ -3196,7 +3487,12 @@ class AppExecutor extends SysExecutor {
3196
3487
  ]);
3197
3488
  } else
3198
3489
  await this.removeDir(".akan");
3199
- const env = this.getCommandEnv({ AKAN_COMMAND_TYPE: type, ...routeEnv });
3490
+ const devPort = type === "start" ? (await this.getDevPort()).toString() : undefined;
3491
+ const env = this.getCommandEnv({
3492
+ AKAN_COMMAND_TYPE: type,
3493
+ ...routeEnv,
3494
+ ...devPort ? { PORT: devPort, AKAN_PUBLIC_CLIENT_PORT: devPort, AKAN_PUBLIC_SERVER_PORT: devPort } : {}
3495
+ });
3200
3496
  return { env };
3201
3497
  }
3202
3498
  #publicEnv = null;
@@ -3615,7 +3911,7 @@ var createTunnel = async (service, { app, environment, port = service === "postg
3615
3911
 
3616
3912
  // pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.host.ts
3617
3913
  import path8 from "path";
3618
- import { Logger as Logger5 } from "akanjs/common";
3914
+ import { Logger as Logger4 } from "akanjs/common";
3619
3915
  var builderMsgTypeSet = new Set([
3620
3916
  "build-route-res",
3621
3917
  "builder-ready",
@@ -3627,7 +3923,7 @@ var builderMsgTypeSet = new Set([
3627
3923
  class IncrementalBuilderHost {
3628
3924
  static #restartBaseDelayMs = 1000;
3629
3925
  static #restartMaxDelayMs = 30000;
3630
- logger = new Logger5("IncrementalBuilderHost");
3926
+ logger = new Logger4("IncrementalBuilderHost");
3631
3927
  entry;
3632
3928
  env;
3633
3929
  app;
@@ -3875,7 +4171,7 @@ class BackendImportGraph {
3875
4171
 
3876
4172
  class AkanAppHost {
3877
4173
  app;
3878
- logger = new Logger6("AkanAppHost");
4174
+ logger = new Logger5("AkanAppHost");
3879
4175
  withInk;
3880
4176
  env;
3881
4177
  #backend = null;
@@ -4158,19 +4454,19 @@ class AkanAppHost {
4158
4454
  }
4159
4455
  }
4160
4456
  // pkgs/@akanjs/devkit/applicationBuildReporter.ts
4161
- import { Logger as Logger7 } from "akanjs/common";
4457
+ import { Logger as Logger6 } from "akanjs/common";
4162
4458
 
4163
4459
  class ApplicationBuildReporter {
4164
4460
  static create() {
4165
4461
  return {
4166
- phaseDone: (phase) => Logger7.rawLog(ApplicationBuildReporter.formatPhaseLine(phase))
4462
+ phaseDone: (phase) => Logger6.rawLog(ApplicationBuildReporter.formatPhaseLine(phase))
4167
4463
  };
4168
4464
  }
4169
4465
  static printSummary(result) {
4170
- Logger7.rawLog("");
4171
- Logger7.rawLog(`Route artifacts: ${result.artifactDir}`);
4172
- Logger7.rawLog(`Server output: ${result.outputDir}`);
4173
- Logger7.rawLog(`Done in ${ApplicationBuildReporter.formatDuration(result.durationMs)}`);
4466
+ Logger6.rawLog("");
4467
+ Logger6.rawLog(`Route artifacts: ${result.artifactDir}`);
4468
+ Logger6.rawLog(`Server output: ${result.outputDir}`);
4469
+ Logger6.rawLog(`Done in ${ApplicationBuildReporter.formatDuration(result.durationMs)}`);
4174
4470
  }
4175
4471
  static formatError(error) {
4176
4472
  if (error instanceof AggregateError) {
@@ -4322,6 +4618,9 @@ export async function generateHead(props: PageProps) {
4322
4618
  return inheritedLayout.head;
4323
4619
  }
4324
4620
 
4621
+ export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
4622
+ export const Error = userLayout.Error ?? inheritedLayout.Error;
4623
+
4325
4624
  export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
4326
4625
  return (
4327
4626
  <System.Provider
@@ -4351,6 +4650,9 @@ export async function generateHead(props: PageProps) {
4351
4650
  return inheritedLayout.head;
4352
4651
  }
4353
4652
 
4653
+ export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
4654
+ export const Error = userLayout.Error ?? inheritedLayout.Error;
4655
+
4354
4656
  export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
4355
4657
  return <UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>;
4356
4658
  }
@@ -4469,13 +4771,13 @@ import path14 from "path";
4469
4771
 
4470
4772
  // pkgs/@akanjs/devkit/transforms/barrelAnalyzer.ts
4471
4773
  import path12 from "path";
4472
- import { Logger as Logger8 } from "akanjs/common";
4774
+ import { Logger as Logger7 } from "akanjs/common";
4473
4775
  var REEXPORT_RE = /(?:^|\n)\s*export\s+(?:type\s+)?(?:(\*)(?:\s+as\s+(\w+))?|\{\s*([^}]*?)\s*\})\s+from\s+(["'])([^"']+)\4;?/g;
4474
4776
  var LOCAL_NAMED_RE = /(?:^|\n)\s*export\s+\{\s*([^}]*?)\s*\}(?!\s*from)/g;
4475
4777
  var CANDIDATE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
4476
4778
 
4477
4779
  class BarrelAnalyzer {
4478
- #logger = new Logger8("BarrelAnalyzer");
4780
+ #logger = new Logger7("BarrelAnalyzer");
4479
4781
  #opts;
4480
4782
  #cache = new Map;
4481
4783
  #tsTranspiler = new Bun.Transpiler({ loader: "ts" });
@@ -6175,7 +6477,7 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
6175
6477
  }
6176
6478
  // pkgs/@akanjs/devkit/frontendBuild/cssCompiler.ts
6177
6479
  import path23 from "path";
6178
- import { Logger as Logger9 } from "akanjs/common";
6480
+ import { Logger as Logger8 } from "akanjs/common";
6179
6481
  import { compile } from "tailwindcss";
6180
6482
 
6181
6483
  // pkgs/@akanjs/devkit/frontendBuild/cssImportResolver.ts
@@ -6320,7 +6622,7 @@ var NODE_MODULES_RE3 = /[\\/]node_modules[\\/]/;
6320
6622
  var AKANJS_NODE_MODULE_RE3 = /[\\/]node_modules[\\/]akanjs[\\/]/;
6321
6623
 
6322
6624
  class CssCompiler {
6323
- #logger = new Logger9("CssCompiler");
6625
+ #logger = new Logger8("CssCompiler");
6324
6626
  #transpiler = new Bun.Transpiler({ loader: "tsx" });
6325
6627
  #app;
6326
6628
  #cssImportResolver = null;
@@ -7728,7 +8030,7 @@ class ApplicationBuildRunner {
7728
8030
  import { cp, mkdir as mkdir8, rm as rm3 } from "fs/promises";
7729
8031
 
7730
8032
  // pkgs/@akanjs/devkit/uploadRelease.ts
7731
- import { HttpClient as HttpClient2, Logger as Logger10 } from "akanjs/common";
8033
+ import { HttpClient as HttpClient2, Logger as Logger9 } from "akanjs/common";
7732
8034
  var spinning = (message) => {
7733
8035
  const spinner = new Spinner(message, { prefix: message, enableSpin: true }).start();
7734
8036
  return spinner;
@@ -7741,7 +8043,7 @@ var uploadRelease = async (appName, {
7741
8043
  os,
7742
8044
  local
7743
8045
  }) => {
7744
- const logger = new Logger10("uploadRelease");
8046
+ const logger = new Logger9("uploadRelease");
7745
8047
  const basePath2 = local ? "http://localhost:8282/backend" : "https://cloud.akanjs.com/backend";
7746
8048
  const httpClient = new HttpClient2(basePath2);
7747
8049
  const buildPath = `${workspaceRoot}/releases/builds/${appName}-release.tar.gz`;
@@ -8727,7 +9029,7 @@ var Workspace = createInternalArgToken("Workspace");
8727
9029
  // pkgs/@akanjs/devkit/commandDecorators/command.ts
8728
9030
  import path36 from "path";
8729
9031
  import { confirm, input as input2, select as select2 } from "@inquirer/prompts";
8730
- import { Logger as Logger11 } from "akanjs/common";
9032
+ import { Logger as Logger10 } from "akanjs/common";
8731
9033
  import chalk6 from "chalk";
8732
9034
  import { program } from "commander";
8733
9035
 
@@ -9012,7 +9314,7 @@ var printCliError = (error) => {
9012
9314
  if (loggedCliErrorMessages.has(message))
9013
9315
  return;
9014
9316
  loggedCliErrorMessages.add(message);
9015
- Logger11.rawLog(`
9317
+ Logger10.rawLog(`
9016
9318
  ${chalk6.red(message)}`);
9017
9319
  };
9018
9320
  var handleOption = (programCommand, argMeta) => {
@@ -9241,7 +9543,7 @@ var runCommands = async (...commands) => {
9241
9543
  const hasCommand = process.argv.length > 2 && !process.argv[2]?.startsWith("-");
9242
9544
  if (hasHelpFlag || !hasCommand) {
9243
9545
  if (process.argv.length === 2 || process.argv.length === 3 && hasHelpFlag) {
9244
- Logger11.rawLog(formatHelp(commands, process.env.AKAN_VERSION));
9546
+ Logger10.rawLog(formatHelp(commands, process.env.AKAN_VERSION));
9245
9547
  process.exit(0);
9246
9548
  }
9247
9549
  }
@@ -9250,7 +9552,7 @@ var runCommands = async (...commands) => {
9250
9552
  });
9251
9553
  const installedAkanPackageJson = await FileSys.fileExists("./node_modules/akanjs/package.json") ? await FileSys.readJson("./node_modules/akanjs/package.json") : null;
9252
9554
  if (installedAkanPackageJson && installedAkanPackageJson.version !== process.env.AKAN_VERSION) {
9253
- Logger11.rawLog(chalk6.yellow(`
9555
+ Logger10.rawLog(chalk6.yellow(`
9254
9556
  Akan CLI version is mismatch with installed package. ${process.env.AKAN_VERSION} (global) vs ${installedAkanPackageJson.version} (akanjs)
9255
9557
  It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`));
9256
9558
  }
@@ -9286,7 +9588,7 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
9286
9588
  return formatCommandHelp(command, targetMeta.key);
9287
9589
  };
9288
9590
  programCommand.action(async (...args) => {
9289
- Logger11.rawLog();
9591
+ Logger10.rawLog();
9290
9592
  const cmdArgs = args.slice(0, args.length - 2);
9291
9593
  const opt = args[args.length - 2];
9292
9594
  const commandArgs = [];
@@ -9310,7 +9612,7 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
9310
9612
  const cmd = CommandContainer.get(command);
9311
9613
  try {
9312
9614
  await targetMeta.handler.call(cmd, ...commandArgs);
9313
- Logger11.rawLog();
9615
+ Logger10.rawLog();
9314
9616
  } catch (e) {
9315
9617
  printCliError(e);
9316
9618
  throw e;
@@ -9650,8 +9952,11 @@ import fsPromise from "fs/promises";
9650
9952
  import { input as input3, select as select3 } from "@inquirer/prompts";
9651
9953
  class Prompter {
9652
9954
  static async#getGuidelineRoot() {
9653
- const dirname3 = getDirname(import.meta.url);
9654
- const candidates = [`${dirname3}/guidelines`, `${dirname3}/../cli/guidelines`];
9955
+ const dirname2 = getDirname(import.meta.url);
9956
+ const candidates = [
9957
+ `${dirname2}/guidelines`,
9958
+ `${dirname2}/../cli/guidelines`
9959
+ ];
9655
9960
  for (const candidate of candidates) {
9656
9961
  try {
9657
9962
  await fsPromise.access(candidate);
@@ -9663,7 +9968,10 @@ class Prompter {
9663
9968
  static async selectGuideline() {
9664
9969
  const guidelineRoot = await Prompter.#getGuidelineRoot();
9665
9970
  const guideNames = (await fsPromise.readdir(guidelineRoot)).filter((name) => !name.startsWith("_"));
9666
- return await select3({ message: "Select a guideline", choices: guideNames.map((name) => ({ name, value: name })) });
9971
+ return await select3({
9972
+ message: "Select a guideline",
9973
+ choices: guideNames.map((name) => ({ name, value: name }))
9974
+ });
9667
9975
  }
9668
9976
  static async getGuideJson(guideName) {
9669
9977
  const guidelineRoot = await Prompter.#getGuidelineRoot();
@@ -9678,13 +9986,18 @@ class Prompter {
9678
9986
  return content;
9679
9987
  }
9680
9988
  static async getUpdateRequest(guideName) {
9681
- return await input3({ message: `What do you want to update in ${guideName}?` });
9989
+ return await input3({
9990
+ message: `What do you want to update in ${guideName}?`
9991
+ });
9682
9992
  }
9683
9993
  async makeTsFileUpdatePrompt({ context, request }) {
9684
9994
  return `You are a senior developer writing TypeScript-based programs using Akan.js, an in-house framework. Here's an overview of the Akan.js framework:
9685
9995
  ${await this.getDocumentation("framework")}
9686
9996
  Please understand the following background information, write code that meets the requirements, verify that it satisfies the validation conditions, and return the result.
9687
9997
 
9998
+ # Code Style
9999
+ - Use double quotes for all string literals in TypeScript/TSX code. Do not use single quotes.
10000
+
9688
10001
  # Background Information
9689
10002
  \`\`\`markdown
9690
10003
  ${context}
@@ -9734,7 +10047,8 @@ import { jsxDEV as jsxDEV2, Fragment as Fragment2 } from "react/jsx-dev-runtime"
9734
10047
  import { select as select6 } from "@inquirer/prompts";
9735
10048
 
9736
10049
  // pkgs/@akanjs/cli/application/application.script.ts
9737
- import { Logger as Logger13 } from "akanjs/common";
10050
+ import { confirm as confirm3 } from "@inquirer/prompts";
10051
+ import { Logger as Logger12 } from "akanjs/common";
9738
10052
 
9739
10053
  // pkgs/@akanjs/cli/semver.ts
9740
10054
  function parseVersion(version) {
@@ -9852,14 +10166,14 @@ import { StringOutputParser } from "@langchain/core/output_parsers";
9852
10166
  import { PromptTemplate as PromptTemplate2 } from "@langchain/core/prompts";
9853
10167
  import { RunnableSequence as RunnableSequence2 } from "@langchain/core/runnables";
9854
10168
  import { ChatOpenAI as ChatOpenAI3 } from "@langchain/openai";
9855
- import { Logger as Logger12 } from "akanjs/common";
10169
+ import { Logger as Logger11 } from "akanjs/common";
9856
10170
  import ora3 from "ora";
9857
10171
 
9858
10172
  // pkgs/@akanjs/cli/openBrowser.ts
9859
- import { spawn as spawn2 } from "child_process";
10173
+ import { spawn as spawn3 } from "child_process";
9860
10174
  function openBrowser(url) {
9861
10175
  const command3 = process.platform === "darwin" ? ["open", url] : process.platform === "win32" ? ["cmd", "/c", "start", "", url] : ["xdg-open", url];
9862
- const child = spawn2(command3[0], command3.slice(1), { detached: true, stdio: "ignore" });
10176
+ const child = spawn3(command3[0], command3.slice(1), { detached: true, stdio: "ignore" });
9863
10177
  child.on("error", () => {});
9864
10178
  child.unref();
9865
10179
  return Promise.resolve();
@@ -9937,7 +10251,7 @@ class ApplicationRunner extends runner("application") {
9937
10251
  const appHost = await new AkanAppHost(app, { env, withInk }).start();
9938
10252
  onStart?.();
9939
10253
  if (open)
9940
- setTimeout(() => openBrowser("http://localhost:8282"), 3000);
10254
+ setTimeout(() => openBrowser(`http://localhost:${env.AKAN_PUBLIC_CLIENT_PORT ?? env.PORT ?? "8282"}`), 3000);
9941
10255
  return appHost;
9942
10256
  }
9943
10257
  async buildIos(app, { target, env = "debug", regenerate = false } = {}) {
@@ -10045,7 +10359,7 @@ class ApplicationRunner extends runner("application") {
10045
10359
  return;
10046
10360
  for (const failure of failures) {
10047
10361
  const message = failure.error instanceof Error ? failure.error.message : String(failure.error);
10048
- Logger12.rawLog(`Mobile target ${failure.target} failed: ${message}`, undefined, "error");
10362
+ Logger11.rawLog(`Mobile target ${failure.target} failed: ${message}`, undefined, "error");
10049
10363
  }
10050
10364
  throw new Error(`${failures.length}/${results.length} mobile targets failed`);
10051
10365
  }
@@ -10162,7 +10476,38 @@ ${detail}`
10162
10476
  }
10163
10477
 
10164
10478
  // pkgs/@akanjs/cli/application/application.script.ts
10165
- class ApplicationScript extends script("application", [ApplicationRunner, LibraryScript]) {
10479
+ class ApplicationScript extends script("application", [
10480
+ ApplicationRunner,
10481
+ LibraryScript
10482
+ ]) {
10483
+ async confirmDatabaseModeDependencyInstall(databaseMode, installSpecs) {
10484
+ return await confirm3({
10485
+ message: [
10486
+ `Database mode '${databaseMode}' requires missing dependencies: ${installSpecs.join(", ")}.`,
10487
+ "Install them now?"
10488
+ ].join(" "),
10489
+ default: true
10490
+ });
10491
+ }
10492
+ async syncDatabaseModeDependencies(app, akanConfig3, databaseMode) {
10493
+ const installSpecs = akanConfig3.getMissingDatabaseModeDependencySpecs(databaseMode);
10494
+ if (installSpecs.length === 0)
10495
+ return;
10496
+ const shouldInstall = await this.confirmDatabaseModeDependencyInstall(databaseMode, installSpecs);
10497
+ if (!shouldInstall)
10498
+ throw new Error(`Database mode '${databaseMode}' requires missing dependencies: ${installSpecs.join(", ")}.`);
10499
+ const spinner2 = app.workspace.spinning(`Installing database dependencies for ${databaseMode} mode...`);
10500
+ try {
10501
+ await app.workspace.spawn("bun", ["add", ...installSpecs], {
10502
+ stdio: "inherit"
10503
+ });
10504
+ await app.workspace.getPackageJson({ refresh: true });
10505
+ spinner2.succeed(`Installed database dependencies for ${databaseMode} mode`);
10506
+ } catch (error) {
10507
+ spinner2.fail(`Failed to install database dependencies for ${databaseMode} mode`);
10508
+ throw error;
10509
+ }
10510
+ }
10166
10511
  async createApplication(appName, workspace, { start = false, libs = [] } = {}) {
10167
10512
  const spinner2 = workspace.spinning("Creating application...");
10168
10513
  const app = await this.applicationRunner.createApplication(appName, workspace, libs);
@@ -10187,25 +10532,33 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
10187
10532
  await app.scanSync();
10188
10533
  await this.applicationRunner.runScript(app, scriptFilename);
10189
10534
  }
10190
- async build(app, { write = true, fast = false, quiet = false } = {}) {
10535
+ async build(app, {
10536
+ write = true,
10537
+ fast = false,
10538
+ quiet = false
10539
+ } = {}) {
10191
10540
  await app.scanSync({ write });
10192
10541
  if (!quiet)
10193
- Logger13.rawLog(`Creating an optimized production build for ${app.name}...`);
10542
+ Logger12.rawLog(`Creating an optimized production build for ${app.name}...`);
10194
10543
  try {
10195
10544
  const result = await this.applicationRunner.build(app, {
10196
10545
  fast,
10197
10546
  spinner: !quiet
10198
10547
  });
10199
- Logger13.rawLog(`${app.name} built in dist/apps/${app.name}`);
10548
+ Logger12.rawLog(`${app.name} built in dist/apps/${app.name}`);
10200
10549
  if (!quiet)
10201
10550
  ApplicationBuildReporter.printSummary(result);
10202
10551
  } catch (error) {
10203
- Logger13.rawLog(`${app.name} build failed in dist/apps/${app.name}`, undefined, "error");
10204
- Logger13.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
10552
+ Logger12.rawLog(`${app.name} build failed in dist/apps/${app.name}`, undefined, "error");
10553
+ Logger12.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
10205
10554
  throw error;
10206
10555
  }
10207
10556
  }
10208
- async typecheck(app, { write = true, clean = false, incremental = true } = {}) {
10557
+ async typecheck(app, {
10558
+ write = true,
10559
+ clean = false,
10560
+ incremental = true
10561
+ } = {}) {
10209
10562
  await app.scanSync({ write });
10210
10563
  const spinner2 = app.spinning(`Typechecking ${app.name}...`);
10211
10564
  try {
@@ -10213,7 +10566,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
10213
10566
  spinner2.succeed(`${app.name} typechecked`);
10214
10567
  } catch (error) {
10215
10568
  spinner2.fail(`${app.name} typecheck failed`);
10216
- Logger13.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
10569
+ Logger12.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
10217
10570
  throw error;
10218
10571
  }
10219
10572
  }
@@ -10247,6 +10600,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
10247
10600
  await app.scanSync({ write });
10248
10601
  const akanConfig3 = await app.getConfig();
10249
10602
  const databaseMode = process.env.AKAN_DATABASE_MODE ?? akanConfig3.defaultDatabaseMode ?? "single";
10603
+ await this.syncDatabaseModeDependencies(app, akanConfig3, databaseMode);
10250
10604
  if (app.getEnv() === "local" && dbup && databaseMode !== "single") {
10251
10605
  const wasDbAlreadyUp = await this.dbup(app.workspace, databaseMode);
10252
10606
  if (!wasDbAlreadyUp)
@@ -10265,7 +10619,12 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
10265
10619
  });
10266
10620
  return akanAppHost;
10267
10621
  }
10268
- async buildIos(app, { write = true, target, env = "debug", regenerate = false } = {}) {
10622
+ async buildIos(app, {
10623
+ write = true,
10624
+ target,
10625
+ env = "debug",
10626
+ regenerate = false
10627
+ } = {}) {
10269
10628
  await app.scanSync({ write });
10270
10629
  await this.applicationRunner.buildIos(app, { target, env, regenerate });
10271
10630
  }
@@ -10278,15 +10637,32 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
10278
10637
  regenerate = false
10279
10638
  } = {}) {
10280
10639
  await app.scanSync({ write });
10281
- await this.applicationRunner.startIos(app, { open, operation, env, target, regenerate });
10640
+ await this.applicationRunner.startIos(app, {
10641
+ open,
10642
+ operation,
10643
+ env,
10644
+ target,
10645
+ regenerate
10646
+ });
10282
10647
  }
10283
- async releaseIos(app, { write = true, target, env = "main", regenerate = false, allowLocalRelease = false } = {}) {
10648
+ async releaseIos(app, {
10649
+ write = true,
10650
+ target,
10651
+ env = "main",
10652
+ regenerate = false,
10653
+ allowLocalRelease = false
10654
+ } = {}) {
10284
10655
  await app.scanSync({ write });
10285
10656
  if (env === "local" && !allowLocalRelease)
10286
10657
  throw new Error("releaseIos --env local is blocked. Pass allowLocalRelease only for explicit local release testing.");
10287
10658
  await this.applicationRunner.releaseIos(app, { target, env, regenerate });
10288
10659
  }
10289
- async buildAndroid(app, { write = true, target, env = "debug", regenerate = false } = {}) {
10660
+ async buildAndroid(app, {
10661
+ write = true,
10662
+ target,
10663
+ env = "debug",
10664
+ regenerate = false
10665
+ } = {}) {
10290
10666
  await app.scanSync({ write });
10291
10667
  await this.applicationRunner.buildAndroid(app, { target, env, regenerate });
10292
10668
  }
@@ -10299,13 +10675,29 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
10299
10675
  regenerate = false
10300
10676
  } = {}) {
10301
10677
  await app.scanSync({ write });
10302
- await this.applicationRunner.startAndroid(app, { open, operation, env, target, regenerate });
10678
+ await this.applicationRunner.startAndroid(app, {
10679
+ open,
10680
+ operation,
10681
+ env,
10682
+ target,
10683
+ regenerate
10684
+ });
10303
10685
  }
10304
- async releaseAndroid(app, assembleType, { write = true, target, env = "main", regenerate = false, allowLocalRelease = false } = {}) {
10686
+ async releaseAndroid(app, assembleType, {
10687
+ write = true,
10688
+ target,
10689
+ env = "main",
10690
+ regenerate = false,
10691
+ allowLocalRelease = false
10692
+ } = {}) {
10305
10693
  await app.scanSync({ write });
10306
10694
  if (env === "local" && !allowLocalRelease)
10307
10695
  throw new Error("releaseAndroid --env local is blocked. Pass allowLocalRelease only for explicit local release testing.");
10308
- await this.applicationRunner.releaseAndroid(app, assembleType, { target, env, regenerate });
10696
+ await this.applicationRunner.releaseAndroid(app, assembleType, {
10697
+ target,
10698
+ env,
10699
+ regenerate
10700
+ });
10309
10701
  }
10310
10702
  async configureApp(app) {
10311
10703
  await this.applicationRunner.configureApp(app);
@@ -10477,11 +10869,11 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
10477
10869
  }
10478
10870
 
10479
10871
  // pkgs/@akanjs/cli/cloud/cloud.script.ts
10480
- import { Logger as Logger16 } from "akanjs/common";
10872
+ import { Logger as Logger15 } from "akanjs/common";
10481
10873
 
10482
10874
  // pkgs/@akanjs/cli/package/package.runner.ts
10483
10875
  import path37 from "path";
10484
- import { Logger as Logger14 } from "akanjs/common";
10876
+ import { Logger as Logger13 } from "akanjs/common";
10485
10877
  var {$: $2 } = globalThis.Bun;
10486
10878
 
10487
10879
  class PackageRunner extends runner("package") {
@@ -10489,7 +10881,7 @@ class PackageRunner extends runner("package") {
10489
10881
  const pkgJson = process.env.USE_AKANJS_PKGS === "true" ? await FileSys.readJson(`${workspace?.workspaceRoot ?? process.cwd()}/pkgs/akanjs/package.json`) : await this.#getInstalledPackageJson();
10490
10882
  const version = pkgJson.name === "akanjs" ? pkgJson.version : pkgJson.dependencies?.akanjs ?? pkgJson.version;
10491
10883
  if (log)
10492
- Logger14.rawLog(`akanjs@${version}`);
10884
+ Logger13.rawLog(`akanjs@${version}`);
10493
10885
  return version;
10494
10886
  }
10495
10887
  async#getInstalledPackageJson() {
@@ -10616,8 +11008,8 @@ class PackageScript extends script("package", [PackageRunner]) {
10616
11008
 
10617
11009
  // pkgs/@akanjs/cli/cloud/cloud.runner.ts
10618
11010
  import path38 from "path";
10619
- import { confirm as confirm3, input as input5, select as select7 } from "@inquirer/prompts";
10620
- import { Logger as Logger15, sleep } from "akanjs/common";
11011
+ import { confirm as confirm4, input as input5, select as select7 } from "@inquirer/prompts";
11012
+ import { Logger as Logger14, sleep } from "akanjs/common";
10621
11013
  import chalk7 from "chalk";
10622
11014
  import * as QRcode from "qrcode";
10623
11015
 
@@ -10642,12 +11034,7 @@ var addRemoteEnvServerValue = "__addRemoteEnvServer";
10642
11034
  var removeRemoteEnvServerValue = "__removeRemoteEnvServer";
10643
11035
 
10644
11036
  class CloudRunner extends runner("cloud") {
10645
- #akanFrameworkPackages = new Set([
10646
- "akanjs",
10647
- "@akanjs/devkit",
10648
- "@akanjs/cli",
10649
- "create-akan-workspace"
10650
- ]);
11037
+ #akanFrameworkPackages = new Set(["akanjs", "@akanjs/devkit", "@akanjs/cli", "create-akan-workspace"]);
10651
11038
  #getRegistryArgs(registryUrl) {
10652
11039
  return registryUrl ? ["--registry", getNpmRegistryUrl(registryUrl)] : [];
10653
11040
  }
@@ -10697,7 +11084,7 @@ class CloudRunner extends runner("cloud") {
10697
11084
  const servers = await GlobalConfig.getRemoteEnvServers();
10698
11085
  const serverEntries = Object.entries(servers).sort(([nameA], [nameB]) => nameA.localeCompare(nameB));
10699
11086
  if (serverEntries.length === 0) {
10700
- Logger15.info("No remote env servers configured. Add the first remote server for SCP mode.");
11087
+ Logger14.info("No remote env servers configured. Add the first remote server for SCP mode.");
10701
11088
  return await this.#addRemoteEnvServer();
10702
11089
  }
10703
11090
  const selectedName = await select7({
@@ -10730,14 +11117,14 @@ class CloudRunner extends runner("cloud") {
10730
11117
  value: name
10731
11118
  }))
10732
11119
  });
10733
- const shouldRemove = await confirm3({
11120
+ const shouldRemove = await confirm4({
10734
11121
  message: `Remove remote env server "${selectedName}"?`,
10735
11122
  default: false
10736
11123
  });
10737
11124
  if (!shouldRemove)
10738
11125
  return;
10739
11126
  await GlobalConfig.removeRemoteEnvServer(selectedName);
10740
- Logger15.info(`Removed remote env server "${selectedName}"`);
11127
+ Logger14.info(`Removed remote env server "${selectedName}"`);
10741
11128
  }
10742
11129
  async#getRemoteEnvServerWithUsername() {
10743
11130
  const remoteServer = await this.#selectRemoteEnvServer();
@@ -10768,35 +11155,27 @@ class CloudRunner extends runner("cloud") {
10768
11155
  return `${config.username ? `${config.username}@` : ""}${config.host}`;
10769
11156
  }
10770
11157
  #getScpArgs(config, source, target) {
10771
- return [
10772
- ...config.port ? ["-P", config.port.toString()] : [],
10773
- source,
10774
- target
10775
- ];
11158
+ return [...config.port ? ["-P", config.port.toString()] : [], source, target];
10776
11159
  }
10777
11160
  #getSshArgs(config, command3) {
10778
- return [
10779
- ...config.port ? ["-p", config.port.toString()] : [],
10780
- this.#getSshTarget(config),
10781
- command3
10782
- ];
11161
+ return [...config.port ? ["-p", config.port.toString()] : [], this.#getSshTarget(config), command3];
10783
11162
  }
10784
- async login() {
11163
+ async login(workspace) {
10785
11164
  const config = await GlobalConfig.getHostConfig();
10786
- const cloudApi2 = new CloudApi(config);
11165
+ const cloudApi2 = new CloudApi(workspace, config);
10787
11166
  const self = config.auth ? await cloudApi2.getRemoteSelf() : null;
10788
11167
  if (self) {
10789
- Logger15.rawLog(chalk7.green(`
11168
+ Logger14.rawLog(chalk7.green(`
10790
11169
  \u2713 Already logged in akan cloud as ${self.nickname}
10791
11170
  `));
10792
11171
  return true;
10793
11172
  }
10794
11173
  const remoteId = crypto.randomUUID();
10795
11174
  const signinUrl = `${akanCloudUrl}/signin?remoteId=${remoteId}`;
10796
- Logger15.rawLog(chalk7.bold(`
11175
+ Logger14.rawLog(chalk7.bold(`
10797
11176
  ${chalk7.green("\u27A4")} Authentication Required`));
10798
- Logger15.rawLog(chalk7.dim("Please visit or click the following URL:"));
10799
- Logger15.rawLog(`${chalk7.cyan.underline(signinUrl)}
11177
+ Logger14.rawLog(chalk7.dim("Please visit or click the following URL:"));
11178
+ Logger14.rawLog(`${chalk7.cyan.underline(signinUrl)}
10800
11179
  `);
10801
11180
  try {
10802
11181
  const qrcode = await new Promise((resolve, reject) => {
@@ -10806,13 +11185,13 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10806
11185
  resolve(data);
10807
11186
  });
10808
11187
  });
10809
- Logger15.rawLog(qrcode);
11188
+ Logger14.rawLog(qrcode);
10810
11189
  await openBrowser(signinUrl);
10811
- Logger15.rawLog(chalk7.dim("Opening browser..."));
11190
+ Logger14.rawLog(chalk7.dim("Opening browser..."));
10812
11191
  } catch {
10813
- Logger15.rawLog(chalk7.yellow("Could not open browser. Please visit the URL manually."));
11192
+ Logger14.rawLog(chalk7.yellow("Could not open browser. Please visit the URL manually."));
10814
11193
  }
10815
- Logger15.rawLog(chalk7.dim("Waiting for authentication..."));
11194
+ Logger14.rawLog(chalk7.dim("Waiting for authentication..."));
10816
11195
  const MAX_RETRY = 300;
10817
11196
  for (let i = 0;i < MAX_RETRY; i++) {
10818
11197
  const accessToken = await cloudApi2.getRemoteAuthToken(remoteId);
@@ -10821,10 +11200,10 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10821
11200
  await GlobalConfig.setHostConfig(akanCloudHost, {
10822
11201
  auth: { accessToken, self: self2 }
10823
11202
  });
10824
- Logger15.rawLog(chalk7.green(`\r\u2713 Authentication successful!`));
10825
- Logger15.rawLog(chalk7.green.bold(`
11203
+ Logger14.rawLog(chalk7.green(`\r\u2713 Authentication successful!`));
11204
+ Logger14.rawLog(chalk7.green.bold(`
10826
11205
  \u2728 Welcome aboard, ${self2.nickname}!`));
10827
- Logger15.rawLog(chalk7.dim(`You're now ready to use Akan CLI!
11206
+ Logger14.rawLog(chalk7.dim(`You're now ready to use Akan CLI!
10828
11207
  `));
10829
11208
  return true;
10830
11209
  }
@@ -10836,17 +11215,17 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10836
11215
  const config = await GlobalConfig.getHostConfig();
10837
11216
  if (config.auth?.self) {
10838
11217
  await GlobalConfig.setHostConfig(akanCloudHost, {});
10839
- Logger15.rawLog(chalk7.magenta.bold(`
11218
+ Logger14.rawLog(chalk7.magenta.bold(`
10840
11219
  \uD83D\uDC4B Goodbye, ${config.auth.self.nickname}!`));
10841
- Logger15.rawLog(chalk7.dim(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
11220
+ Logger14.rawLog(chalk7.dim(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
10842
11221
  `));
10843
- Logger15.rawLog(chalk7.cyan("You have been successfully logged out."));
10844
- Logger15.rawLog(chalk7.dim(`Thank you for using Akan CLI. Come back soon! \uD83C\uDF1F
11222
+ Logger14.rawLog(chalk7.cyan("You have been successfully logged out."));
11223
+ Logger14.rawLog(chalk7.dim(`Thank you for using Akan CLI. Come back soon! \uD83C\uDF1F
10845
11224
  `));
10846
11225
  } else {
10847
- Logger15.rawLog(chalk7.yellow.bold(`
11226
+ Logger14.rawLog(chalk7.yellow.bold(`
10848
11227
  \u26A0\uFE0F No active session found`));
10849
- Logger15.rawLog(chalk7.dim(`You were not logged in to begin with
11228
+ Logger14.rawLog(chalk7.dim(`You were not logged in to begin with
10850
11229
  `));
10851
11230
  }
10852
11231
  }
@@ -10855,7 +11234,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10855
11234
  }
10856
11235
  resetLlm() {
10857
11236
  AiSession.setLlmConfig(null);
10858
- Logger15.rawLog(chalk7.green("\u2611\uFE0F LLM model config is cleared. Please run `akan set-llm` to set a new LLM model."));
11237
+ Logger14.rawLog(chalk7.green("\u2611\uFE0F LLM model config is cleared. Please run `akan set-llm` to set a new LLM model."));
10859
11238
  }
10860
11239
  async getAkanPkgs(workspace) {
10861
11240
  const pkgs = await workspace.getPkgs();
@@ -10879,8 +11258,8 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10879
11258
  }
10880
11259
  };
10881
11260
  const { nextVersion, latestPublishedVersion } = await getNextVersion(targetVersionPrefix, tag);
10882
- Logger15.info(`Latest published version of akanjs: ${latestPublishedVersion ?? "none"}`);
10883
- Logger15.info(`Next version of akanjs: ${nextVersion}`);
11261
+ Logger14.info(`Latest published version of akanjs: ${latestPublishedVersion ?? "none"}`);
11262
+ Logger14.info(`Next version of akanjs: ${nextVersion}`);
10884
11263
  for (const library of akanPkgs) {
10885
11264
  const packageJson = await workspace.readJson(`pkgs/${library}/package.json`);
10886
11265
  const newPackageJsonStr = JSON.stringify(this.#normalizeAkanPackageJson(packageJson, library, nextVersion), null, 2);
@@ -10890,30 +11269,24 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10890
11269
  await workspace.writeJson(`dist/pkgs/${library}/package.json`, newDistPackageJson);
10891
11270
  }
10892
11271
  if (confirmPublish) {
10893
- const isDeployConfirmed = await confirm3({
11272
+ const isDeployConfirmed = await confirm4({
10894
11273
  message: "Are you sure you want to deploy the libraries?"
10895
11274
  });
10896
11275
  if (!isDeployConfirmed) {
10897
- Logger15.error("Deployment cancelled");
11276
+ Logger14.error("Deployment cancelled");
10898
11277
  return;
10899
11278
  }
10900
11279
  }
10901
11280
  await Promise.all(akanPkgs.map(async (library) => {
10902
- Logger15.info(`Publishing ${library}@${nextVersion} to ${registry ?? "npm"}...`);
10903
- await workspace.spawn("npm", [
10904
- "publish",
10905
- "--tag",
10906
- tag,
10907
- ...this.#getRegistryArgs(registry),
10908
- ...this.#getLocalRegistryAuthArgs(registry)
10909
- ], {
11281
+ Logger14.info(`Publishing ${library}@${nextVersion} to ${registry ?? "npm"}...`);
11282
+ await workspace.spawn("npm", ["publish", "--tag", tag, ...this.#getRegistryArgs(registry), ...this.#getLocalRegistryAuthArgs(registry)], {
10910
11283
  cwd: path38.join(workspace.workspaceRoot, "dist/pkgs", library),
10911
11284
  env: this.#getRegistryEnv(registry),
10912
11285
  stdio: "inherit"
10913
11286
  });
10914
- Logger15.info(`${library}@${nextVersion} is published to ${registry ?? "npm"}`);
11287
+ Logger14.info(`${library}@${nextVersion} is published to ${registry ?? "npm"}`);
10915
11288
  }));
10916
- Logger15.info(`All libraries are published to ${registry ?? "npm"}`);
11289
+ Logger14.info(`All libraries are published to ${registry ?? "npm"}`);
10917
11290
  }
10918
11291
  async update(workspace, tag = "latest", { registryUrl } = {}) {
10919
11292
  const registry = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
@@ -10923,14 +11296,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10923
11296
  await workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`, ...registryArgs], { env });
10924
11297
  else
10925
11298
  await Promise.all([
10926
- workspace.spawn("bun", [
10927
- "update",
10928
- "-g",
10929
- "akanjs",
10930
- "--latest",
10931
- `--tag=${tag}`,
10932
- ...registryArgs
10933
- ], { env }),
11299
+ workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`, ...registryArgs], { env }),
10934
11300
  this.#updateAkanPkgs(workspace, tag, registry)
10935
11301
  ]);
10936
11302
  }
@@ -10954,12 +11320,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10954
11320
  }
10955
11321
  #normalizeAkanPackageJson(packageJson, packageName, version) {
10956
11322
  const normalized = { ...packageJson, version };
10957
- for (const field of [
10958
- "dependencies",
10959
- "devDependencies",
10960
- "peerDependencies",
10961
- "optionalDependencies"
10962
- ]) {
11323
+ for (const field of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
10963
11324
  const dependencies = normalized[field];
10964
11325
  if (!dependencies)
10965
11326
  continue;
@@ -10974,7 +11335,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10974
11335
  const envArchivePath = "local/env.tar";
10975
11336
  await workspace.mkdir("local");
10976
11337
  await workspace.remove(envArchivePath);
10977
- await cloudApi2.downloadEnv(workspaceId, path38.join(workspace.workspaceRoot, envArchivePath));
11338
+ await cloudApi2.downloadEnv(workspaceId);
10978
11339
  await workspace.spawn("tar", ["-xf", envArchivePath], {
10979
11340
  cwd: workspace.workspaceRoot
10980
11341
  });
@@ -10992,7 +11353,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10992
11353
  await workspace.mkdir("local");
10993
11354
  await workspace.remove(envArchivePath);
10994
11355
  try {
10995
- Logger15.info(`Downloading env archive from remote server "${remoteServer.name}"...`);
11356
+ Logger14.info(`Downloading env archive from remote server "${remoteServer.name}"...`);
10996
11357
  await workspace.spawn("scp", this.#getScpArgs(remoteServer.config, remoteTarget, envArchivePath), {
10997
11358
  cwd: workspace.workspaceRoot,
10998
11359
  stdio: "inherit"
@@ -11015,7 +11376,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
11015
11376
  cwd: workspace.workspaceRoot,
11016
11377
  stdio: "inherit"
11017
11378
  });
11018
- Logger15.info(`Uploading env archive to remote server "${remoteServer.name}"...`);
11379
+ Logger14.info(`Uploading env archive to remote server "${remoteServer.name}"...`);
11019
11380
  await workspace.spawn("scp", this.#getScpArgs(remoteServer.config, filePath, remoteTarget), {
11020
11381
  cwd: workspace.workspaceRoot,
11021
11382
  stdio: "inherit"
@@ -11039,19 +11400,15 @@ ${chalk7.green("\u27A4")} Authentication Required`));
11039
11400
  await workspace.spawn("tar", ["-cf", "local/env.tar", ...envFilePaths], {
11040
11401
  cwd: workspace.workspaceRoot
11041
11402
  });
11042
- Logger15.info(`Archived ${envFilePaths.length} environment files to local/env.tar`);
11403
+ Logger14.info(`Archived ${envFilePaths.length} environment files to local/env.tar`);
11043
11404
  return { files: envFilePaths, path: "local/env.tar" };
11044
11405
  }
11045
11406
  }
11046
11407
 
11047
11408
  // pkgs/@akanjs/cli/cloud/cloud.script.ts
11048
- class CloudScript extends script("cloud", [
11049
- CloudRunner,
11050
- ApplicationScript,
11051
- PackageScript
11052
- ]) {
11409
+ class CloudScript extends script("cloud", [CloudRunner, ApplicationScript, PackageScript]) {
11053
11410
  async login(workspace) {
11054
- await this.cloudRunner.login();
11411
+ await this.cloudRunner.login(workspace);
11055
11412
  }
11056
11413
  async logout(workspace) {
11057
11414
  await this.cloudRunner.logout();
@@ -11069,7 +11426,7 @@ class CloudScript extends script("cloud", [
11069
11426
  async downloadEnv(workspace) {
11070
11427
  const workspaceId = workspace.getWorkspaceId({ allowEmpty: true });
11071
11428
  if (workspaceId) {
11072
- const cloudApi2 = await CloudApi.fromHost();
11429
+ const cloudApi2 = await CloudApi.fromHost(workspace);
11073
11430
  await this.cloudRunner.downloadEnv(cloudApi2, workspace, workspaceId);
11074
11431
  return;
11075
11432
  }
@@ -11079,7 +11436,7 @@ class CloudScript extends script("cloud", [
11079
11436
  const workspaceId = workspace.getWorkspaceId({ allowEmpty: true });
11080
11437
  const { path: path39 } = await this.cloudRunner.gatherEnvFiles(workspace);
11081
11438
  if (workspaceId) {
11082
- const cloudApi2 = await CloudApi.fromHost();
11439
+ const cloudApi2 = await CloudApi.fromHost(workspace);
11083
11440
  await this.cloudRunner.uploadEnv(cloudApi2, workspaceId, path39);
11084
11441
  return;
11085
11442
  }
@@ -11100,7 +11457,7 @@ class CloudScript extends script("cloud", [
11100
11457
  const spinner2 = workspace.spinning("Updating Akan.js packages and CLI...");
11101
11458
  await this.cloudRunner.update(workspace, tag, { registryUrl });
11102
11459
  spinner2.succeed("Akan.js packages and CLI updated, global version is below");
11103
- Logger16.raw("> Akan version: ");
11460
+ Logger15.raw("> Akan version: ");
11104
11461
  await workspace.spawn("akan", ["--version"], { stdio: "inherit" });
11105
11462
  }
11106
11463
  }
@@ -11154,7 +11511,8 @@ class CloudCommand extends command("cloud", [CloudScript], ({ public: target })
11154
11511
  enum: [
11155
11512
  { label: "npm", value: "npm" },
11156
11513
  { label: "local", value: "local" }
11157
- ]
11514
+ ],
11515
+ default: process.env.USE_AKANJS_PKGS === "true" ? undefined : "npm"
11158
11516
  }).exec(async function(workspace, tag, registry) {
11159
11517
  await this.cloudScript.update(workspace, tag, {
11160
11518
  registryUrl: resolveRegistryUrl(registry)
@@ -11499,7 +11857,7 @@ class LibraryCommand extends command("library", [LibraryScript], ({ public: targ
11499
11857
  // pkgs/@akanjs/cli/localRegistry/localRegistry.runner.ts
11500
11858
  import { mkdir as mkdir11, rm as rm5 } from "fs/promises";
11501
11859
  import path39 from "path";
11502
- import { Logger as Logger17 } from "akanjs/common";
11860
+ import { Logger as Logger16 } from "akanjs/common";
11503
11861
  var defaultLocalRegistryUrl = "http://127.0.0.1:4873";
11504
11862
  var containerName = "akan-verdaccio";
11505
11863
  var smokeRepoName = "akan-local-smoke";
@@ -11513,7 +11871,7 @@ class LocalRegistryRunner extends runner("localRegistry") {
11513
11871
  const registry = this.getRegistryUrl(registryUrl);
11514
11872
  try {
11515
11873
  await workspace.spawn("docker", ["inspect", containerName]);
11516
- Logger17.info(`Local registry is already running at ${registry}`);
11874
+ Logger16.info(`Local registry is already running at ${registry}`);
11517
11875
  return registry;
11518
11876
  } catch {}
11519
11877
  const configPath2 = path39.join(workspace.workspaceRoot, "pkgs/@akanjs/cli/localRegistry/verdaccio.yaml");
@@ -11533,7 +11891,7 @@ class LocalRegistryRunner extends runner("localRegistry") {
11533
11891
  `${storagePath}:/verdaccio/storage`,
11534
11892
  "verdaccio/verdaccio:6"
11535
11893
  ], { stdio: "inherit" });
11536
- Logger17.info(`Local registry is running at ${registry}`);
11894
+ Logger16.info(`Local registry is running at ${registry}`);
11537
11895
  return registry;
11538
11896
  }
11539
11897
  async reset(workspace) {
@@ -11541,7 +11899,7 @@ class LocalRegistryRunner extends runner("localRegistry") {
11541
11899
  await workspace.spawn("docker", ["rm", "-f", containerName], { stdio: "inherit" });
11542
11900
  } catch {}
11543
11901
  await rm5(path39.join(workspace.workspaceRoot, ".akan/verdaccio"), { recursive: true, force: true });
11544
- Logger17.info("Local registry storage has been reset");
11902
+ Logger16.info("Local registry storage has been reset");
11545
11903
  }
11546
11904
  async smoke(workspace, { registryUrl } = {}) {
11547
11905
  const registry = this.getRegistryUrl(registryUrl);
@@ -11567,7 +11925,7 @@ class LocalRegistryRunner extends runner("localRegistry") {
11567
11925
  env: { ...process.env, AKAN_NPM_REGISTRY: registry, NPM_CONFIG_REGISTRY: registry },
11568
11926
  stdio: "inherit"
11569
11927
  });
11570
- Logger17.info(`Local registry smoke test completed for ${smokeRepoName}/${smokeAppName}`);
11928
+ Logger16.info(`Local registry smoke test completed for ${smokeRepoName}/${smokeAppName}`);
11571
11929
  }
11572
11930
  }
11573
11931
 
@@ -12433,7 +12791,7 @@ class ScalarCommand extends command("scalar", [ScalarScript], ({ public: target
12433
12791
 
12434
12792
  // pkgs/@akanjs/cli/workspace/workspace.script.ts
12435
12793
  import path41 from "path";
12436
- import { Logger as Logger18 } from "akanjs/common";
12794
+ import { Logger as Logger17 } from "akanjs/common";
12437
12795
 
12438
12796
  // pkgs/@akanjs/cli/workspace/workspace.runner.ts
12439
12797
  import path40 from "path";
@@ -12457,16 +12815,16 @@ var defaultWorkspacePeerDependencies = new Set([
12457
12815
 
12458
12816
  class WorkspaceRunner extends runner("workspace") {
12459
12817
  async createWorkspace(repoName, appName, {
12460
- dirname: dirname3 = ".",
12818
+ dirname: dirname2 = ".",
12461
12819
  init = true,
12462
12820
  akanVersion,
12463
12821
  registryUrl
12464
12822
  }) {
12465
12823
  const cwdPath = process.cwd();
12466
- const workspaceRoot = path40.join(cwdPath, dirname3, repoName);
12824
+ const workspaceRoot = path40.join(cwdPath, dirname2, repoName);
12467
12825
  const normalizedRegistryUrl = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
12468
12826
  const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
12469
- const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname3}/${repoName}...`);
12827
+ const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname2}/${repoName}...`);
12470
12828
  const [latestBiomeVersion, latestTypesBunVersion] = await Promise.all([
12471
12829
  getLatestPackageVersion("@biomejs/biome", "latest", normalizedRegistryUrl),
12472
12830
  getLatestPackageVersion("@types/bun", "latest", normalizedRegistryUrl)
@@ -12479,7 +12837,7 @@ class WorkspaceRunner extends runner("workspace") {
12479
12837
  if (normalizedRegistryUrl)
12480
12838
  await workspace.writeFile(".npmrc", `registry=${normalizedRegistryUrl}/
12481
12839
  `);
12482
- templateSpinner.succeed(`Workspace files created in ${dirname3}/${repoName}`);
12840
+ templateSpinner.succeed(`Workspace files created in ${dirname2}/${repoName}`);
12483
12841
  const [rootPackageJson, peerDependencies] = await Promise.all([
12484
12842
  workspace.getPackageJson(),
12485
12843
  this.#getAkanPeerDependencies()
@@ -12584,14 +12942,14 @@ class WorkspaceScript extends script("workspace", [
12584
12942
  PackageScript
12585
12943
  ]) {
12586
12944
  async createWorkspace(repoName, appName, {
12587
- dirname: dirname3 = ".",
12945
+ dirname: dirname2 = ".",
12588
12946
  installLibs = false,
12589
12947
  init = true,
12590
12948
  registryUrl
12591
12949
  }) {
12592
12950
  const akanVersion = await this.packageScript.version(null, { log: false });
12593
12951
  const workspace = await this.workspaceRunner.createWorkspace(repoName, appName, {
12594
- dirname: dirname3,
12952
+ dirname: dirname2,
12595
12953
  init,
12596
12954
  akanVersion,
12597
12955
  ...registryUrl ? { registryUrl } : {}
@@ -12608,11 +12966,11 @@ class WorkspaceScript extends script("workspace", [
12608
12966
  } catch (_) {
12609
12967
  gitSpinner.fail("Git repository initialization failed. It's not fatal, you can commit manually");
12610
12968
  }
12611
- const workspacePath = path41.join(dirname3, repoName);
12612
- Logger18.rawLog(`
12613
- \uD83C\uDF89 Welcome aboard! Workspace created in ${dirname3}/${repoName}`);
12614
- Logger18.rawLog(`\uD83D\uDE80 Run \`cd ${workspacePath} && akan start ${appName}\` to start the development server.`);
12615
- Logger18.rawLog(`
12969
+ const workspacePath = path41.join(dirname2, repoName);
12970
+ Logger17.rawLog(`
12971
+ \uD83C\uDF89 Welcome aboard! Workspace created in ${dirname2}/${repoName}`);
12972
+ Logger17.rawLog(`\uD83D\uDE80 Run \`cd ${workspacePath} && akan start ${appName}\` to start the development server.`);
12973
+ Logger17.rawLog(`
12616
12974
  \uD83D\uDC4B Happy coding!`);
12617
12975
  }
12618
12976
  async lint(exec2, workspace, { fix = true } = {}) {