@akanjs/cli 2.1.0-rc.1 → 2.1.0-rc.11

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
@@ -484,7 +484,18 @@ var DEFAULT_OPTIMIZE_IMPORTS = [
484
484
  var WORKSPACE_BARREL_FACETS = ["ui", "webkit", "common", "client", "server"];
485
485
  var SSR_RUNTIME_PACKAGES = ["react", "react-dom", "react-server-dom-webpack"];
486
486
  var NATIVE_RUNTIME_PACKAGES = ["sharp"];
487
- var AKAN_RUNTIME_PACKAGES = new Set([...SSR_RUNTIME_PACKAGES, ...NATIVE_RUNTIME_PACKAGES]);
487
+ var DEFAULT_BACKEND_RUNTIME_PACKAGES = ["croner"];
488
+ var DATABASE_MODE_RUNTIME_PACKAGES = {
489
+ single: [],
490
+ multiple: ["@libsql/client", "bullmq", "ioredis", "protobufjs"],
491
+ cluster: ["bullmq", "ioredis", "postgres", "protobufjs"]
492
+ };
493
+ var AKAN_RUNTIME_PACKAGES = new Set([
494
+ ...SSR_RUNTIME_PACKAGES,
495
+ ...NATIVE_RUNTIME_PACKAGES,
496
+ ...DEFAULT_BACKEND_RUNTIME_PACKAGES,
497
+ ...Object.values(DATABASE_MODE_RUNTIME_PACKAGES).flat()
498
+ ]);
488
499
  var DEFAULT_AKAN_IMAGE_CONFIG = {
489
500
  deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
490
501
  imageSizes: [32, 48, 64, 96, 128, 256, 384],
@@ -693,13 +704,22 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
693
704
  if (AKAN_RUNTIME_PACKAGES.has(lib))
694
705
  return akanPackageJson.dependencies?.[lib] ?? akanPackageJson.peerDependencies?.[lib];
695
706
  }
707
+ #getProductionRuntimePackages() {
708
+ return [
709
+ ...this.externalLibs,
710
+ ...SSR_RUNTIME_PACKAGES,
711
+ ...NATIVE_RUNTIME_PACKAGES,
712
+ ...DEFAULT_BACKEND_RUNTIME_PACKAGES,
713
+ ...DATABASE_MODE_RUNTIME_PACKAGES[this.defaultDatabaseMode]
714
+ ];
715
+ }
696
716
  getProductionPackageJson(data = {}) {
697
717
  return {
698
718
  name: this.app.name,
699
719
  description: this.app.name,
700
720
  version: "1.0.0",
701
721
  main: "./main.js",
702
- dependencies: Object.fromEntries([...new Set([...this.externalLibs, ...SSR_RUNTIME_PACKAGES, ...NATIVE_RUNTIME_PACKAGES])].map((lib) => {
722
+ dependencies: Object.fromEntries([...new Set(this.#getProductionRuntimePackages())].map((lib) => {
703
723
  const version = this.#resolveProductionDependencyVersion(lib);
704
724
  if (!version)
705
725
  throw new Error(`Dependency ${lib} not found in package.json`);
@@ -1959,6 +1979,45 @@ var staticTemplateFileExtensions = new Set([
1959
1979
  ".woff2",
1960
1980
  ".xml"
1961
1981
  ]);
1982
+ var formatCommandArg = (value) => /^[\w@%+=:,./-]+$/.test(value) ? value : JSON.stringify(value);
1983
+ var formatCommandForDisplay = (command, args = []) => [command, ...args].map(formatCommandArg).join(" ");
1984
+
1985
+ class CommandExecutionError extends Error {
1986
+ command;
1987
+ args;
1988
+ cwd;
1989
+ code;
1990
+ signal;
1991
+ stdout;
1992
+ stderr;
1993
+ constructor({
1994
+ command,
1995
+ args = [],
1996
+ cwd,
1997
+ code,
1998
+ signal,
1999
+ stdout = "",
2000
+ stderr = "",
2001
+ cause
2002
+ }) {
2003
+ const displayCommand = formatCommandForDisplay(command, args);
2004
+ const status = signal ? `signal: ${signal}` : `exit code: ${code ?? "unknown"}`;
2005
+ const output = (stderr || stdout).trim();
2006
+ super([`Command failed: ${displayCommand}`, `cwd: ${cwd}`, status, output ? `
2007
+ ${output}` : ""].join(`
2008
+ `), {
2009
+ cause
2010
+ });
2011
+ this.name = "CommandExecutionError";
2012
+ this.command = command;
2013
+ this.args = args;
2014
+ this.cwd = cwd;
2015
+ this.code = code;
2016
+ this.signal = signal;
2017
+ this.stdout = stdout;
2018
+ this.stderr = stderr;
2019
+ }
2020
+ }
1962
2021
  var execEmoji = {
1963
2022
  workspace: "\uD83C\uDFE0",
1964
2023
  app: "\uD83D\uDE80",
@@ -2089,23 +2148,32 @@ class Executor {
2089
2148
  Logger4.raw(chalk4.red(data.toString()));
2090
2149
  }
2091
2150
  exec(command, options = {}) {
2151
+ const cwd = options.cwd?.toString() ?? this.cwdPath;
2092
2152
  const proc = exec(command, { cwd: this.cwdPath, ...options });
2153
+ let stdout = "";
2154
+ let stderr = "";
2093
2155
  proc.stdout?.on("data", (data) => {
2156
+ stdout += data.toString();
2094
2157
  this.#stdout(data);
2095
2158
  });
2096
2159
  proc.stderr?.on("data", (data) => {
2160
+ stderr += data.toString();
2097
2161
  this.#stdout(data);
2098
2162
  });
2099
2163
  return new Promise((resolve, reject) => {
2164
+ proc.on("error", (error) => {
2165
+ reject(new CommandExecutionError({ command, cwd, code: null, signal: null, stdout, stderr, cause: error }));
2166
+ });
2100
2167
  proc.on("exit", (code, signal) => {
2101
2168
  if (!!code || signal)
2102
- reject({ code, signal });
2169
+ reject(new CommandExecutionError({ command, cwd, code, signal, stdout, stderr }));
2103
2170
  else
2104
2171
  resolve({ code, signal });
2105
2172
  });
2106
2173
  });
2107
2174
  }
2108
2175
  spawn(command, args = [], options = {}) {
2176
+ const cwd = options.cwd?.toString() ?? this.cwdPath;
2109
2177
  const proc = spawn(command, args, {
2110
2178
  cwd: this.cwdPath,
2111
2179
  ...options
@@ -2123,9 +2191,12 @@ class Executor {
2123
2191
  this.#stdout(data);
2124
2192
  });
2125
2193
  return new Promise((resolve, reject) => {
2194
+ proc.on("error", (error) => {
2195
+ reject(new CommandExecutionError({ command, args, cwd, code: null, signal: null, stdout, stderr, cause: error }));
2196
+ });
2126
2197
  proc.on("close", (code, signal) => {
2127
2198
  if (code !== 0 || signal)
2128
- reject(stderr || stdout);
2199
+ reject(new CommandExecutionError({ command, args, cwd, code, signal, stdout, stderr }));
2129
2200
  else
2130
2201
  resolve(stdout);
2131
2202
  });
@@ -2139,20 +2210,37 @@ class Executor {
2139
2210
  return proc;
2140
2211
  }
2141
2212
  fork(modulePath, args = [], options = {}) {
2213
+ const cwd = options.cwd?.toString() ?? this.cwdPath;
2142
2214
  const proc = fork(modulePath, args, {
2143
2215
  cwd: this.cwdPath,
2144
2216
  ...options
2145
2217
  });
2218
+ let stdout = "";
2219
+ let stderr = "";
2146
2220
  proc.stdout?.on("data", (data) => {
2221
+ stdout += data.toString();
2147
2222
  this.#stdout(data);
2148
2223
  });
2149
2224
  proc.stderr?.on("data", (data) => {
2225
+ stderr += data.toString();
2150
2226
  this.#stderr(data);
2151
2227
  });
2152
2228
  return new Promise((resolve, reject) => {
2229
+ proc.on("error", (error) => {
2230
+ reject(new CommandExecutionError({
2231
+ command: modulePath,
2232
+ args,
2233
+ cwd,
2234
+ code: null,
2235
+ signal: null,
2236
+ stdout,
2237
+ stderr,
2238
+ cause: error
2239
+ }));
2240
+ });
2153
2241
  proc.on("exit", (code, signal) => {
2154
2242
  if (!!code || signal)
2155
- reject({ code, signal });
2243
+ reject(new CommandExecutionError({ command: modulePath, args, cwd, code, signal, stdout, stderr }));
2156
2244
  else
2157
2245
  resolve({ code, signal });
2158
2246
  });
@@ -3374,6 +3462,7 @@ class IncrementalBuilderHost {
3374
3462
  const candidates = [
3375
3463
  path8.join(app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts"),
3376
3464
  path8.join(app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts"),
3465
+ path8.join(import.meta.dir, "incrementalBuilder.proc.js"),
3377
3466
  path8.join(import.meta.dir, "incrementalBuilder.proc.ts")
3378
3467
  ];
3379
3468
  for (const c of candidates)
@@ -5348,9 +5437,7 @@ ${defaultNames.map((name) => `export default ${name};`).join(`
5348
5437
  }
5349
5438
  static resolveSsrClientRuntimeAliases() {
5350
5439
  const serverEntry = RouteClientBuilder.resolveAkanServerEntry();
5351
- const aliases = Object.fromEntries(SSR_CLIENT_ALIAS_EXTERNALS.map((specifier) => [specifier, Bun.resolveSync(specifier, serverEntry)]));
5352
- aliases[Bun.resolveSync("akanjs/fetch", serverEntry)] = "akanjs/fetch";
5353
- return aliases;
5440
+ return { [Bun.resolveSync("akanjs/fetch", serverEntry)]: "akanjs/fetch" };
5354
5441
  }
5355
5442
  static resolveSsrClientExternalOptions(command) {
5356
5443
  if (command === "start") {
@@ -5793,9 +5880,9 @@ class CssImportResolver {
5793
5880
  }
5794
5881
  async resolve(id, fromBase) {
5795
5882
  for (const resolve of [
5883
+ () => this.#resolveWithTsconfig(id),
5796
5884
  () => this.#resolveWithBun(id, fromBase),
5797
5885
  () => this.#resolveWithRequire(id, fromBase),
5798
- () => this.#resolveWithTsconfig(id),
5799
5886
  () => this.#resolvePackageStyle(id, fromBase)
5800
5887
  ]) {
5801
5888
  const resolved = await resolve();
@@ -5805,20 +5892,24 @@ class CssImportResolver {
5805
5892
  return null;
5806
5893
  }
5807
5894
  #resolveWithBun(id, fromBase) {
5808
- try {
5809
- const resolved = Bun.resolveSync(id, fromBase);
5810
- return CssImportResolver.isCssFile(resolved) ? resolved : null;
5811
- } catch {
5812
- return null;
5895
+ for (const base of this.#resolutionBases(fromBase)) {
5896
+ try {
5897
+ const resolved = Bun.resolveSync(id, base);
5898
+ if (CssImportResolver.isCssFile(resolved))
5899
+ return resolved;
5900
+ } catch {}
5813
5901
  }
5902
+ return null;
5814
5903
  }
5815
5904
  #resolveWithRequire(id, fromBase) {
5816
- try {
5817
- const resolved = __require.resolve(id, { paths: [fromBase] });
5818
- return CssImportResolver.isCssFile(resolved) ? resolved : null;
5819
- } catch {
5820
- return null;
5905
+ for (const base of this.#resolutionBases(fromBase)) {
5906
+ try {
5907
+ const resolved = __require.resolve(id, { paths: [base] });
5908
+ if (CssImportResolver.isCssFile(resolved))
5909
+ return resolved;
5910
+ } catch {}
5821
5911
  }
5912
+ return null;
5822
5913
  }
5823
5914
  async#resolveWithTsconfig(id) {
5824
5915
  const exact = this.#paths[id];
@@ -5846,8 +5937,25 @@ class CssImportResolver {
5846
5937
  const pkgName = CssImportResolver.getPackageName(id);
5847
5938
  if (!pkgName)
5848
5939
  return null;
5940
+ for (const base of this.#resolutionBases(fromBase)) {
5941
+ try {
5942
+ const pkgPath = __require.resolve(`${pkgName}/package.json`, { paths: [base] });
5943
+ const resolved = await this.#resolvePackageStyleFromPackageJson(id, pkgName, pkgPath);
5944
+ if (resolved)
5945
+ return resolved;
5946
+ } catch {}
5947
+ }
5948
+ for (const pkgPath of this.#packageJsonCandidates(pkgName)) {
5949
+ const resolved = await this.#resolvePackageStyleFromPackageJson(id, pkgName, pkgPath);
5950
+ if (resolved)
5951
+ return resolved;
5952
+ }
5953
+ return null;
5954
+ }
5955
+ async#resolvePackageStyleFromPackageJson(id, pkgName, pkgPath) {
5849
5956
  try {
5850
- const pkgPath = __require.resolve(`${pkgName}/package.json`, { paths: [fromBase] });
5957
+ if (!await Bun.file(pkgPath).exists())
5958
+ return null;
5851
5959
  const pkgDir = path22.dirname(pkgPath);
5852
5960
  const pkg = await Bun.file(pkgPath).json();
5853
5961
  const subpath = id === pkgName ? "." : `.${id.slice(pkgName.length)}`;
@@ -5858,6 +5966,17 @@ class CssImportResolver {
5858
5966
  return null;
5859
5967
  }
5860
5968
  }
5969
+ #resolutionBases(fromBase) {
5970
+ return [fromBase, this.#workspaceRoot, path22.dirname(Bun.main), path22.resolve(path22.dirname(Bun.main), "../..")];
5971
+ }
5972
+ #packageJsonCandidates(pkgName) {
5973
+ return [
5974
+ path22.join(this.#workspaceRoot, "pkgs", pkgName, "package.json"),
5975
+ path22.join(this.#workspaceRoot, "node_modules", pkgName, "package.json"),
5976
+ path22.join(path22.dirname(Bun.main), "node_modules", pkgName, "package.json"),
5977
+ path22.join(path22.dirname(Bun.main), "../../", pkgName, "package.json")
5978
+ ];
5979
+ }
5861
5980
  async#firstExisting(basePath2) {
5862
5981
  for (const suffix of CSS_IMPORT_EXTS) {
5863
5982
  const candidate = `${basePath2}${suffix}`;
@@ -6980,16 +7099,20 @@ class SsrBaseArtifactBuilder {
6980
7099
  return { rscClientUrl, vendorMap };
6981
7100
  }
6982
7101
  async#resolveAkanServerPath() {
6983
- const candidates = [
6984
- path30.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"),
6985
- path30.resolve(import.meta.dir, "../../server"),
6986
- path30.resolve(import.meta.dir, "../server")
6987
- ];
7102
+ const candidates = [];
7103
+ try {
7104
+ candidates.push(path30.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
7105
+ } catch {}
7106
+ candidates.push(path30.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path30.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
7107
+ try {
7108
+ candidates.push(path30.dirname(Bun.resolveSync("akanjs/server", path30.dirname(Bun.main))));
7109
+ } catch {}
7110
+ candidates.push(path30.join(path30.dirname(Bun.main), "node_modules/akanjs/server"), path30.join(path30.dirname(Bun.main), "../../akanjs/server"), path30.resolve(import.meta.dir, "../../server"), path30.resolve(import.meta.dir, "../server"));
6988
7111
  for (const candidate of candidates) {
6989
7112
  if (await Bun.file(path30.join(candidate, "rscClient.tsx")).exists())
6990
7113
  return candidate;
6991
7114
  }
6992
- return candidates[0];
7115
+ throw new Error(`[base-artifact] failed to locate akanjs/server; looked in: ${candidates.join(", ")}`);
6993
7116
  }
6994
7117
  async#buildStyleAssets() {
6995
7118
  const cssCompiler = new CssCompiler(this.#app);
@@ -7063,25 +7186,19 @@ var SSR_RENDER_EXTERNALS = [
7063
7186
  "react/jsx-dev-runtime",
7064
7187
  "react-dom",
7065
7188
  "react-dom/server.browser",
7189
+ "react-server-dom-webpack",
7190
+ "react-server-dom-webpack/server.node",
7066
7191
  "react-server-dom-webpack/client.node",
7067
7192
  "react-server-dom-webpack/client.browser"
7068
7193
  ];
7069
- var TYPECHECK_WORKER_CODE = `
7070
- import { TypeChecker } from "@akanjs/devkit";
7071
-
7072
- try {
7073
- const configPath = process.env.AKAN_TYPECHECK_TSCONFIG;
7074
- if (!configPath) throw new Error("AKAN_TYPECHECK_TSCONFIG is required");
7075
- const result = TypeChecker.checkProject(configPath);
7076
- if (result.errors.length > 0) {
7077
- console.error(result.message);
7078
- process.exit(1);
7079
- }
7080
- } catch (error) {
7081
- console.error(error instanceof Error ? error.message : String(error));
7082
- process.exit(1);
7083
- }
7084
- `;
7194
+ var AKAN_OPTIONAL_BACKEND_EXTERNALS = [
7195
+ "@libsql/client",
7196
+ "bullmq",
7197
+ "croner",
7198
+ "ioredis",
7199
+ "postgres",
7200
+ "protobufjs"
7201
+ ];
7085
7202
 
7086
7203
  class ApplicationBuildRunner {
7087
7204
  #app;
@@ -7150,7 +7267,9 @@ class ApplicationBuildRunner {
7150
7267
  }
7151
7268
  async#buildBackend() {
7152
7269
  const akanConfig2 = await this.#app.getConfig();
7153
- const backendExternals = [...new Set([...akanConfig2.externalLibs, ...SSR_RENDER_EXTERNALS])];
7270
+ const backendExternals = [
7271
+ ...new Set([...akanConfig2.externalLibs, ...SSR_RENDER_EXTERNALS, ...AKAN_OPTIONAL_BACKEND_EXTERNALS])
7272
+ ];
7154
7273
  const backendEntryPoints = [`${this.#app.cwdPath}/main.ts`, `${this.#app.cwdPath}/server.ts`];
7155
7274
  for (const entrypoint of backendEntryPoints) {
7156
7275
  if (!await Bun.file(entrypoint).exists())
@@ -7172,7 +7291,7 @@ class ApplicationBuildRunner {
7172
7291
  naming: { entry: "[name].[ext]", chunk: "chunk-[hash].[ext]" },
7173
7292
  conditions: ["react-server"],
7174
7293
  define: { "process.env.NODE_ENV": JSON.stringify("production") },
7175
- plugins: akanConfig2.externalLibs.length > 0 ? [this.#createExternalSpecifiersPlugin(akanConfig2.externalLibs)] : []
7294
+ plugins: backendExternals.length > 0 ? [this.#createExternalSpecifiersPlugin(backendExternals)] : []
7176
7295
  });
7177
7296
  return {
7178
7297
  entrypoints: backendEntryPoints.length + 1,
@@ -7225,7 +7344,8 @@ class ApplicationBuildRunner {
7225
7344
  return { typecheckDir, tsconfigPath };
7226
7345
  }
7227
7346
  async#checkProjectInChildProcess(tsconfigPath) {
7228
- const proc = Bun.spawn([process.execPath, "--eval", TYPECHECK_WORKER_CODE], {
7347
+ const entry = await this.#resolveTypecheckWorkerEntry();
7348
+ const proc = Bun.spawn([process.execPath, entry], {
7229
7349
  cwd: this.#app.workspace.workspaceRoot,
7230
7350
  env: this.#app.getCommandEnv({
7231
7351
  AKAN_COMMAND_TYPE: "typecheck",
@@ -7242,6 +7362,18 @@ class ApplicationBuildRunner {
7242
7362
  if (exitCode !== 0)
7243
7363
  throw new Error((stderr || stdout).trim() || `Typecheck failed with exit code ${exitCode}`);
7244
7364
  }
7365
+ async#resolveTypecheckWorkerEntry() {
7366
+ const candidates = [
7367
+ path32.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
7368
+ path32.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
7369
+ path32.join(import.meta.dir, "typecheck.proc.js"),
7370
+ path32.join(import.meta.dir, "typecheck.proc.ts")
7371
+ ];
7372
+ for (const candidate of candidates)
7373
+ if (await Bun.file(candidate).exists())
7374
+ return candidate;
7375
+ throw new Error(`[cli] typecheck worker entry not found; looked in: ${candidates.join(", ")}`);
7376
+ }
7245
7377
  async#buildOrThrow(label, config) {
7246
7378
  const result = await Bun.build(config);
7247
7379
  if (!result.success)
@@ -7507,10 +7639,31 @@ class ApplicationReleasePackager {
7507
7639
  `;
7508
7640
  }
7509
7641
  }
7642
+ // pkgs/@akanjs/devkit/applicationTestPreload.ts
7643
+ import path33 from "path";
7644
+ var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
7645
+ async function resolveSignalTestPreloadPath(target) {
7646
+ const candidates = [];
7647
+ const addResolvedPackageCandidate = (basePath2) => {
7648
+ try {
7649
+ candidates.push(path33.join(path33.dirname(Bun.resolveSync("akanjs/package.json", basePath2)), SIGNAL_TEST_PRELOAD_PATH));
7650
+ } catch {}
7651
+ };
7652
+ addResolvedPackageCandidate(target.cwdPath);
7653
+ addResolvedPackageCandidate(process.cwd());
7654
+ addResolvedPackageCandidate(path33.dirname(Bun.main));
7655
+ addResolvedPackageCandidate(import.meta.dir);
7656
+ candidates.push(path33.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path33.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path33.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path33.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path33.join(path33.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path33.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
7657
+ for (const candidate of [...new Set(candidates)]) {
7658
+ if (await Bun.file(candidate).exists())
7659
+ return candidate;
7660
+ }
7661
+ throw new Error(`Failed to locate ${SIGNAL_TEST_PRELOAD_PATH} from ${target.cwdPath}`);
7662
+ }
7510
7663
  // pkgs/@akanjs/devkit/builder.ts
7511
7664
  import { existsSync as existsSync2 } from "fs";
7512
7665
  import { mkdir as mkdir9 } from "fs/promises";
7513
- import path33 from "path";
7666
+ import path34 from "path";
7514
7667
  var SKIP_ENTRY_DIR_SET = new Set(["node_modules", "dist", "build", ".git", ".next"]);
7515
7668
  var assetExtensions = [".css", ".md", ".js", ".png", ".ico", ".svg", ".json", ".template"];
7516
7669
  var assetLoader = Object.fromEntries(assetExtensions.map((ext) => [ext, "file"]));
@@ -7527,14 +7680,14 @@ class Builder {
7527
7680
  #globEntrypoints(cwd, pattern) {
7528
7681
  const glob = new Bun.Glob(pattern);
7529
7682
  return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
7530
- const segments = relativePath.split(path33.sep);
7683
+ const segments = relativePath.split(path34.sep);
7531
7684
  return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
7532
- }).map((rel) => path33.join(cwd, rel));
7685
+ }).map((rel) => path34.join(cwd, rel));
7533
7686
  }
7534
7687
  #globFiles(cwd, pattern = "**/*.*") {
7535
7688
  const glob = new Bun.Glob(pattern);
7536
7689
  return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
7537
- const segments = relativePath.split(path33.sep);
7690
+ const segments = relativePath.split(path34.sep);
7538
7691
  return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
7539
7692
  });
7540
7693
  }
@@ -7542,17 +7695,17 @@ class Builder {
7542
7695
  const out = [];
7543
7696
  for (const p of additionalEntryPoints) {
7544
7697
  if (p.includes("*")) {
7545
- const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path33.sep}`) ? p.slice(cwd.length + 1) : p;
7698
+ const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path34.sep}`) ? p.slice(cwd.length + 1) : p;
7546
7699
  out.push(...this.#globEntrypoints(cwd, rel));
7547
7700
  } else
7548
- out.push(path33.isAbsolute(p) ? p : path33.join(cwd, p));
7701
+ out.push(path34.isAbsolute(p) ? p : path34.join(cwd, p));
7549
7702
  }
7550
7703
  return out;
7551
7704
  }
7552
7705
  #getBuildOptions({ bundle = false, additionalEntryPoints = [] } = {}) {
7553
7706
  const cwd = this.#executor.cwdPath;
7554
7707
  const entrypoints = [
7555
- ...bundle ? [path33.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
7708
+ ...bundle ? [path34.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
7556
7709
  ...this.#resolveAdditionalEntrypoints(cwd, additionalEntryPoints)
7557
7710
  ];
7558
7711
  return {
@@ -7573,9 +7726,9 @@ class Builder {
7573
7726
  for (const relativePath of this.#globFiles(cwd)) {
7574
7727
  if (relativePath === "package.json")
7575
7728
  continue;
7576
- const sourcePath = path33.join(cwd, relativePath);
7577
- const targetPath = path33.join(this.#distExecutor.cwdPath, relativePath);
7578
- await mkdir9(path33.dirname(targetPath), { recursive: true });
7729
+ const sourcePath = path34.join(cwd, relativePath);
7730
+ const targetPath = path34.join(this.#distExecutor.cwdPath, relativePath);
7731
+ await mkdir9(path34.dirname(targetPath), { recursive: true });
7579
7732
  await Bun.write(targetPath, Bun.file(sourcePath));
7580
7733
  }
7581
7734
  }
@@ -7586,13 +7739,13 @@ class Builder {
7586
7739
  return withoutFormatDir;
7587
7740
  if (!hasDotSlash && withoutFormatDir === publishedPath)
7588
7741
  return publishedPath;
7589
- const parsed = path33.posix.parse(withoutFormatDir);
7742
+ const parsed = path34.posix.parse(withoutFormatDir);
7590
7743
  if (![".js", ".mjs", ".cjs"].includes(parsed.ext))
7591
7744
  return withoutFormatDir;
7592
- const withoutExt = path33.posix.join(parsed.dir, parsed.name);
7745
+ const withoutExt = path34.posix.join(parsed.dir, parsed.name);
7593
7746
  const sourcePath = withoutExt.startsWith("./") ? withoutExt.slice(2) : withoutExt;
7594
7747
  const sourceCandidates = [`${sourcePath}.ts`, `${sourcePath}.tsx`];
7595
- const matchedSource = sourceCandidates.find((candidate) => existsSync2(path33.join(this.#executor.cwdPath, candidate)));
7748
+ const matchedSource = sourceCandidates.find((candidate) => existsSync2(path34.join(this.#executor.cwdPath, candidate)));
7596
7749
  if (!matchedSource)
7597
7750
  return withoutFormatDir;
7598
7751
  return hasDotSlash ? `./${matchedSource}` : matchedSource;
@@ -7642,7 +7795,7 @@ class Builder {
7642
7795
  }
7643
7796
  // pkgs/@akanjs/devkit/capacitorApp.ts
7644
7797
  import { cp as cp2, mkdir as mkdir10, rm as rm4 } from "fs/promises";
7645
- import path34 from "path";
7798
+ import path35 from "path";
7646
7799
  import { MobileProject } from "@trapezedev/project";
7647
7800
  import { capitalize as capitalize2 } from "akanjs/common";
7648
7801
 
@@ -7836,10 +7989,10 @@ class CapacitorApp {
7836
7989
  constructor(app, target) {
7837
7990
  this.app = app;
7838
7991
  this.target = target;
7839
- this.targetRootPath = path34.posix.join("mobile", this.target.name);
7840
- this.targetRoot = path34.join(this.app.cwdPath, this.targetRootPath);
7841
- this.targetWebRoot = path34.join(this.targetRoot, "www");
7842
- this.targetAssetRoot = path34.join(this.targetRoot, "assets");
7992
+ this.targetRootPath = path35.posix.join("mobile", this.target.name);
7993
+ this.targetRoot = path35.join(this.app.cwdPath, this.targetRootPath);
7994
+ this.targetWebRoot = path35.join(this.targetRoot, "www");
7995
+ this.targetAssetRoot = path35.join(this.targetRoot, "assets");
7843
7996
  this.project = new MobileProject(this.app.cwdPath, {
7844
7997
  android: { path: this.androidRootPath },
7845
7998
  ios: { path: this.iosProjectPath }
@@ -7855,9 +8008,9 @@ class CapacitorApp {
7855
8008
  await this.#writeCapacitorConfig();
7856
8009
  if (regenerate) {
7857
8010
  if (!platform || platform === "ios")
7858
- await rm4(path34.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
8011
+ await rm4(path35.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
7859
8012
  if (!platform || platform === "android")
7860
- await rm4(path34.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
8013
+ await rm4(path35.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
7861
8014
  }
7862
8015
  const project = this.project;
7863
8016
  await this.project.load();
@@ -7919,7 +8072,7 @@ class CapacitorApp {
7919
8072
  await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
7920
8073
  }
7921
8074
  async#updateAndroidBuildTypes() {
7922
- const appGradle = await FileEditor.create(path34.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
8075
+ const appGradle = await FileEditor.create(path35.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
7923
8076
  const buildTypesBlock = `
7924
8077
  debug {
7925
8078
  applicationIdSuffix ".debug"
@@ -7962,7 +8115,7 @@ class CapacitorApp {
7962
8115
  const gradleCommand = isWindows ? "gradlew.bat" : "./gradlew";
7963
8116
  await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
7964
8117
  stdio: "inherit",
7965
- cwd: path34.join(this.app.cwdPath, this.androidRootPath),
8118
+ cwd: path35.join(this.app.cwdPath, this.androidRootPath),
7966
8119
  env: this.#commandEnv("release", env)
7967
8120
  });
7968
8121
  }
@@ -7991,12 +8144,12 @@ class CapacitorApp {
7991
8144
  await this.#prepareAndroid({ operation: "release", env: "main" });
7992
8145
  }
7993
8146
  async prepareWww() {
7994
- const htmlSource = path34.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
8147
+ const htmlSource = path35.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
7995
8148
  if (!await Bun.file(htmlSource).exists())
7996
8149
  throw new Error(`CSR html for mobile target '${this.target.name}' not found: ${htmlSource}`);
7997
8150
  await rm4(this.targetWebRoot, { recursive: true, force: true });
7998
8151
  await mkdir10(this.targetWebRoot, { recursive: true });
7999
- await Bun.write(path34.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
8152
+ await Bun.write(path35.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
8000
8153
  }
8001
8154
  #injectMobileTargetMeta(html) {
8002
8155
  const basePath2 = this.target.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
@@ -8008,9 +8161,9 @@ class CapacitorApp {
8008
8161
  }
8009
8162
  async#writeCapacitorConfig() {
8010
8163
  await mkdir10(this.targetRoot, { recursive: true });
8011
- const appInfoPath = path34.relative(this.app.cwdPath, path34.join(this.app.cwdPath, "akan.app.json")).split(path34.sep).join("/");
8164
+ const appInfoPath = path35.relative(this.app.cwdPath, path35.join(this.app.cwdPath, "akan.app.json")).split(path35.sep).join("/");
8012
8165
  const content = `import type { AppScanResult } from "akanjs";
8013
- import { withBase } from "@akanjs/devkit/capacitor.base.config";
8166
+ import { withBase } from "akanjs/capacitor.base.config";
8014
8167
  import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
8015
8168
 
8016
8169
  export default withBase(
@@ -8029,18 +8182,18 @@ export default withBase(
8029
8182
  appInfo as AppScanResult,
8030
8183
  );
8031
8184
  `;
8032
- await Bun.write(path34.join(this.app.cwdPath, "capacitor.config.ts"), content);
8185
+ await Bun.write(path35.join(this.app.cwdPath, "capacitor.config.ts"), content);
8033
8186
  }
8034
8187
  async#prepareTargetAssets() {
8035
8188
  if (!this.target.assets)
8036
8189
  return;
8037
8190
  await mkdir10(this.targetAssetRoot, { recursive: true });
8038
8191
  if (this.target.assets.icon)
8039
- await cp2(path34.join(this.app.cwdPath, this.target.assets.icon), path34.join(this.targetAssetRoot, "icon.png"), {
8192
+ await cp2(path35.join(this.app.cwdPath, this.target.assets.icon), path35.join(this.targetAssetRoot, "icon.png"), {
8040
8193
  force: true
8041
8194
  });
8042
8195
  if (this.target.assets.splash)
8043
- await cp2(path34.join(this.app.cwdPath, this.target.assets.splash), path34.join(this.targetAssetRoot, "splash.png"), {
8196
+ await cp2(path35.join(this.app.cwdPath, this.target.assets.splash), path35.join(this.targetAssetRoot, "splash.png"), {
8044
8197
  force: true
8045
8198
  });
8046
8199
  }
@@ -8048,11 +8201,11 @@ export default withBase(
8048
8201
  const files = this.target.files?.[platform];
8049
8202
  if (!files)
8050
8203
  return;
8051
- const platformRoot = path34.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
8204
+ const platformRoot = path35.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
8052
8205
  await Promise.all(Object.entries(files).map(async ([to, from]) => {
8053
- const targetPath = path34.join(platformRoot, to);
8054
- await mkdir10(path34.dirname(targetPath), { recursive: true });
8055
- await cp2(path34.join(this.app.cwdPath, from), targetPath, { force: true });
8206
+ const targetPath = path35.join(platformRoot, to);
8207
+ await mkdir10(path35.dirname(targetPath), { recursive: true });
8208
+ await cp2(path35.join(this.app.cwdPath, from), targetPath, { force: true });
8056
8209
  }));
8057
8210
  }
8058
8211
  async#generateAssets({ operation, env }) {
@@ -8062,7 +8215,7 @@ export default withBase(
8062
8215
  "@capacitor/assets",
8063
8216
  "generate",
8064
8217
  "--assetPath",
8065
- path34.posix.join(this.targetRootPath, "assets"),
8218
+ path35.posix.join(this.targetRootPath, "assets"),
8066
8219
  "--iosProject",
8067
8220
  this.iosProjectPath,
8068
8221
  "--androidProject",
@@ -8247,8 +8400,8 @@ var Pkg = createInternalArgToken("Pkg");
8247
8400
  var Module = createInternalArgToken("Module");
8248
8401
  var Workspace = createInternalArgToken("Workspace");
8249
8402
  // pkgs/@akanjs/devkit/commandDecorators/command.ts
8403
+ import path36 from "path";
8250
8404
  import { confirm, input as input2, select as select2 } from "@inquirer/prompts";
8251
- import path35 from "path";
8252
8405
  import { Logger as Logger11 } from "akanjs/common";
8253
8406
  import chalk6 from "chalk";
8254
8407
  import { program } from "commander";
@@ -8506,6 +8659,37 @@ var formatCommandHelp = (command, key) => {
8506
8659
 
8507
8660
  // pkgs/@akanjs/devkit/commandDecorators/command.ts
8508
8661
  var camelToKebabCase2 = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
8662
+ var loggedCliErrorObjects = new WeakSet;
8663
+ var loggedCliErrorMessages = new Set;
8664
+ var formatCliError = (error) => {
8665
+ if (error instanceof Error)
8666
+ return error.message || error.name;
8667
+ if (typeof error === "string")
8668
+ return error.trim() || "Unknown error";
8669
+ if (error === null || error === undefined)
8670
+ return "Unknown error";
8671
+ try {
8672
+ const json = JSON.stringify(error);
8673
+ if (json)
8674
+ return json;
8675
+ } catch {
8676
+ return String(error);
8677
+ }
8678
+ return String(error) || "Unknown error";
8679
+ };
8680
+ var printCliError = (error) => {
8681
+ if (typeof error === "object" && error !== null) {
8682
+ if (loggedCliErrorObjects.has(error))
8683
+ return;
8684
+ loggedCliErrorObjects.add(error);
8685
+ }
8686
+ const message = formatCliError(error);
8687
+ if (loggedCliErrorMessages.has(message))
8688
+ return;
8689
+ loggedCliErrorMessages.add(message);
8690
+ Logger11.rawLog(`
8691
+ ${chalk6.red(message)}`);
8692
+ };
8509
8693
  var handleOption = (programCommand, argMeta) => {
8510
8694
  const {
8511
8695
  type,
@@ -8712,10 +8896,11 @@ var getInternalArgumentValue = async (argMeta, value, workspace) => {
8712
8896
  };
8713
8897
  var runCommands = async (...commands) => {
8714
8898
  process.on("unhandledRejection", (error) => {
8899
+ printCliError(error);
8715
8900
  process.exit(1);
8716
8901
  });
8717
8902
  const __dirname2 = getDirname(import.meta.url);
8718
- const packageJsonCandidates = [`${path35.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
8903
+ const packageJsonCandidates = [`${path36.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
8719
8904
  let cliPackageJson = null;
8720
8905
  for (const packageJsonPath of packageJsonCandidates) {
8721
8906
  if (!await FileSys.fileExists(packageJsonPath))
@@ -8802,9 +8987,7 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
8802
8987
  await targetMeta.handler.call(cmd, ...commandArgs);
8803
8988
  Logger11.rawLog();
8804
8989
  } catch (e) {
8805
- const errMsg = e instanceof Error ? e.message : typeof e === "string" ? e : JSON.stringify(e);
8806
- Logger11.rawLog(`
8807
- ${chalk6.red(errMsg)}`);
8990
+ printCliError(e);
8808
8991
  throw e;
8809
8992
  }
8810
8993
  });
@@ -8993,8 +9176,8 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
8993
9176
  return importSpecifiers;
8994
9177
  };
8995
9178
  var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
8996
- const configFile = ts6.readConfigFile(tsConfigPath, (path36) => {
8997
- return ts6.sys.readFile(path36);
9179
+ const configFile = ts6.readConfigFile(tsConfigPath, (path37) => {
9180
+ return ts6.sys.readFile(path37);
8998
9181
  });
8999
9182
  return ts6.parseJsonConfigFileContent(configFile.config, ts6.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
9000
9183
  };
@@ -9339,7 +9522,6 @@ class LibraryScript extends script("library", [LibraryRunner]) {
9339
9522
  }
9340
9523
 
9341
9524
  // pkgs/@akanjs/cli/application/application.runner.ts
9342
- import path36 from "path";
9343
9525
  import { confirm as confirm2, input as input4, select as select5 } from "@inquirer/prompts";
9344
9526
  import { StringOutputParser } from "@langchain/core/output_parsers";
9345
9527
  import { PromptTemplate as PromptTemplate2 } from "@langchain/core/prompts";
@@ -9405,14 +9587,14 @@ class ApplicationRunner extends runner("application") {
9405
9587
  }
9406
9588
  async test(exec2) {
9407
9589
  const isSignalTarget = exec2 instanceof AppExecutor || exec2 instanceof LibExecutor;
9408
- const preloadPath = path36.join(exec2.cwdPath, "../../pkgs/akanjs/test/signalTest.preload.ts");
9590
+ const preloadPath = isSignalTarget ? await resolveSignalTestPreloadPath(exec2) : null;
9409
9591
  const env = isSignalTarget ? {
9410
9592
  AKAN_TEST_SIGNAL: "1",
9411
9593
  AKAN_TEST_TARGET_TYPE: exec2.type,
9412
9594
  AKAN_TEST_TARGET_NAME: exec2.name,
9413
9595
  AKAN_TEST_LIBS: exec2.getScanInfo({ allowEmpty: true })?.getLibs().join(",") ?? ""
9414
9596
  } : {};
9415
- const args = isSignalTarget ? ["test", "--isolate", "--preload", preloadPath] : ["test", "--isolate"];
9597
+ const args = preloadPath ? ["test", "--isolate", "--preload", preloadPath] : ["test", "--isolate"];
9416
9598
  await exec2.spawn("bun", args, {
9417
9599
  ...isSignalTarget ? { env: { ...process.env, ...env } } : {},
9418
9600
  stdio: "inherit"
@@ -9582,8 +9764,15 @@ class ApplicationRunner extends runner("application") {
9582
9764
  cwd: `${workspace.workspaceRoot}/local`
9583
9765
  });
9584
9766
  return wasAlreadyUp;
9585
- } catch {
9586
- throw new Error(`Docker daemon is not running. Please install docker or start docker daemon and try again.`);
9767
+ } catch (error) {
9768
+ const detail = error instanceof Error ? error.message : typeof error === "string" ? error : JSON.stringify(error) || "Unknown error";
9769
+ throw new Error([
9770
+ "Docker daemon may not be running. Please install Docker or start the Docker daemon and try again.",
9771
+ `Original error:
9772
+ ${detail}`
9773
+ ].join(`
9774
+
9775
+ `));
9587
9776
  }
9588
9777
  }
9589
9778
  async dbdown(workspace) {
@@ -9704,12 +9893,17 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
9704
9893
  }
9705
9894
  }
9706
9895
  async test(exec2, { write = true } = {}) {
9896
+ if (exec2 instanceof LibExecutor) {
9897
+ await this.libraryScript.syncLibrary(exec2);
9898
+ const spinner3 = exec2.spinning(`Preparing ${exec2.name}...`);
9899
+ spinner3.succeed(`${exec2.name} prepared`);
9900
+ await this.applicationRunner.test(exec2);
9901
+ return;
9902
+ }
9707
9903
  const spinner2 = exec2.spinning(`Preparing ${exec2.name}...`);
9708
9904
  try {
9709
9905
  if (exec2 instanceof PkgExecutor)
9710
9906
  await exec2.scan({ refresh: true });
9711
- else if (exec2 instanceof LibExecutor)
9712
- await this.libraryScript.syncLibrary(exec2);
9713
9907
  else
9714
9908
  await exec2.scanSync({ write });
9715
9909
  spinner2.succeed(`${exec2.name} prepared`);
@@ -10007,11 +10201,17 @@ class PackageRunner extends runner("package") {
10007
10201
  await pkg.dist.mkdir(pkg.dist.cwdPath);
10008
10202
  const scanner = await TypeScriptDependencyScanner.from(pkg);
10009
10203
  const { npmDeps, npmDevDeps, missingDeps } = await scanner.getPackageBuildDependencies(pkg.name);
10010
- const packageRuntimeDependencies = {};
10204
+ const packageRuntimeDependencies = {
10205
+ "@akanjs/devkit": ["daisyui", "tailwind-scrollbar"]
10206
+ };
10011
10207
  const packageRuntimeDevDependencies = { akanjs: ["@biomejs/biome", "@types/bun"] };
10012
10208
  if (pkg.name === "@akanjs/cli") {
10013
10209
  const devkitPackageJson = await pkg.workspace.readJson("pkgs/@akanjs/devkit/package.json");
10014
- packageRuntimeDependencies[pkg.name] = Object.keys(devkitPackageJson.dependencies ?? {}).filter((dep) => dep !== "akanjs" && dep !== "@akanjs/devkit");
10210
+ packageRuntimeDependencies[pkg.name] = [
10211
+ ...Object.keys(devkitPackageJson.dependencies ?? {}),
10212
+ "daisyui",
10213
+ "tailwind-scrollbar"
10214
+ ].filter((dep) => dep !== "akanjs" && dep !== "@akanjs/devkit");
10015
10215
  }
10016
10216
  const bundledRuntimeDeps = new Set(pkg.name === "@akanjs/cli" ? ["@akanjs/devkit"] : []);
10017
10217
  const forcedRuntimeDeps = packageRuntimeDependencies[pkg.name] ?? [];
@@ -10092,11 +10292,14 @@ import chalk7 from "chalk";
10092
10292
  import * as QRcode from "qrcode";
10093
10293
 
10094
10294
  // pkgs/@akanjs/cli/npmRegistry.ts
10095
- async function getLatestPackageVersion(packageName, tag = "latest") {
10096
- const url = `https://registry.npmjs.org/${encodeURIComponent(packageName).replace(/^%40/, "@")}`;
10295
+ var defaultNpmRegistry = "https://registry.npmjs.org";
10296
+ var getNpmRegistryUrl = (registryUrl = process.env.AKAN_NPM_REGISTRY ?? defaultNpmRegistry) => registryUrl.replace(/\/+$/, "");
10297
+ async function getLatestPackageVersion(packageName, tag = "latest", registryUrl) {
10298
+ const registry = getNpmRegistryUrl(registryUrl);
10299
+ const url = `${registry}/${encodeURIComponent(packageName).replace(/^%40/, "@")}`;
10097
10300
  const res = await fetch(url);
10098
10301
  if (!res.ok)
10099
- throw new Error(`Failed to fetch ${packageName} metadata from npm registry`);
10302
+ throw new Error(`Failed to fetch ${packageName} metadata from ${registry}`);
10100
10303
  const metadata = await res.json();
10101
10304
  const version = metadata["dist-tags"]?.[tag];
10102
10305
  if (!version)
@@ -10227,10 +10430,10 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10227
10430
  }
10228
10431
  async update(workspace, tag = "latest") {
10229
10432
  if (!await workspace.exists("package.json"))
10230
- await workspace.spawn("npm", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`]);
10433
+ await workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`]);
10231
10434
  else
10232
10435
  await Promise.all([
10233
- workspace.spawn("npm", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`]),
10436
+ workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`]),
10234
10437
  this.#updateAkanPkgs(workspace, tag)
10235
10438
  ]);
10236
10439
  }
@@ -10243,6 +10446,10 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10243
10446
  rootPackageJson.dependencies.akanjs = latestPublishedVersion;
10244
10447
  if (rootPackageJson.devDependencies?.akanjs)
10245
10448
  rootPackageJson.devDependencies.akanjs = latestPublishedVersion;
10449
+ if (rootPackageJson.dependencies["@akanjs/devkit"])
10450
+ rootPackageJson.dependencies["@akanjs/devkit"] = latestPublishedVersion;
10451
+ if (rootPackageJson.devDependencies?.["@akanjs/devkit"])
10452
+ rootPackageJson.devDependencies["@akanjs/devkit"] = latestPublishedVersion;
10246
10453
  workspace.setPackageJson(rootPackageJson);
10247
10454
  await workspace.spawn("bun", ["install"]);
10248
10455
  }
@@ -10318,6 +10525,7 @@ class CloudCommand extends command("cloud", [CloudScript], ({ public: target })
10318
10525
 
10319
10526
  // pkgs/@akanjs/cli/guideline/guideline.prompt.ts
10320
10527
  import { randomPicks } from "akanjs/common";
10528
+
10321
10529
  class GuidelinePrompt extends Prompter {
10322
10530
  workspace;
10323
10531
  name;
@@ -11419,7 +11627,7 @@ class ScalarScript extends script("scalar", [ScalarRunner]) {
11419
11627
 
11420
11628
  // pkgs/@akanjs/cli/scalar/scalar.command.ts
11421
11629
  class ScalarCommand extends command("scalar", [ScalarScript], ({ public: target }) => ({
11422
- createScalar: target({ desc: "Create a new scalar type (simple data model without DB)" }).arg("scalarName", String, { desc: "name of scalar" }).option("ai", Boolean, { default: false, desc: "use ai to create scalar" }).with(Sys).exec(async function(scalarName, ai, sys3) {
11630
+ createScalar: target({ desc: "Create a new scalar type (simple data model without DB)" }).arg("scalarName", String, { desc: "name of scalar" }).with(Sys).option("ai", Boolean, { default: false, desc: "use ai to create scalar" }).exec(async function(scalarName, sys3, ai) {
11423
11631
  const name = lowerlize2(scalarName.replace(/ /g, ""));
11424
11632
  if (ai)
11425
11633
  await this.scalarScript.createScalarWithAi(sys3, name);
@@ -11439,42 +11647,66 @@ import { Logger as Logger17 } from "akanjs/common";
11439
11647
  // pkgs/@akanjs/cli/workspace/workspace.runner.ts
11440
11648
  import path38 from "path";
11441
11649
  var defaultWorkspacePeerDependencies = new Set([
11650
+ "@radix-ui/react-dialog",
11651
+ "@react-spring/web",
11652
+ "@use-gesture/react",
11653
+ "croner",
11654
+ "daisyui",
11442
11655
  "react",
11443
11656
  "react-dom",
11657
+ "react-icons",
11444
11658
  "react-refresh",
11445
11659
  "react-server-dom-webpack",
11660
+ "react-spring",
11446
11661
  "scheduler",
11662
+ "tailwind-scrollbar",
11447
11663
  "tailwindcss",
11448
11664
  "typescript"
11449
11665
  ]);
11450
11666
 
11451
11667
  class WorkspaceRunner extends runner("workspace") {
11452
- async createWorkspace(repoName, appName, { dirname: dirname3 = ".", init = true, akanVersion }) {
11668
+ async createWorkspace(repoName, appName, {
11669
+ dirname: dirname3 = ".",
11670
+ init = true,
11671
+ akanVersion,
11672
+ registryUrl
11673
+ }) {
11453
11674
  const cwdPath = process.cwd();
11454
11675
  const workspaceRoot = path38.join(cwdPath, dirname3, repoName);
11676
+ const normalizedRegistryUrl = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
11455
11677
  const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
11456
11678
  const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname3}/${repoName}...`);
11457
- const latestTypesBunVersion = await getLatestPackageVersion("@types/bun");
11679
+ const [latestBiomeVersion, latestTypesBunVersion] = await Promise.all([
11680
+ getLatestPackageVersion("@biomejs/biome", "latest", normalizedRegistryUrl),
11681
+ getLatestPackageVersion("@types/bun", "latest", normalizedRegistryUrl)
11682
+ ]);
11458
11683
  await workspace.applyTemplate({
11459
11684
  basePath: ".",
11460
11685
  template: "workspaceRoot",
11461
11686
  dict: { repoName, appName, serveDomain: "localhost" }
11462
11687
  });
11688
+ if (normalizedRegistryUrl)
11689
+ await workspace.writeFile(".npmrc", `registry=${normalizedRegistryUrl}/
11690
+ `);
11463
11691
  templateSpinner.succeed(`Workspace files created in ${dirname3}/${repoName}`);
11464
11692
  const [rootPackageJson, peerDependencies] = await Promise.all([
11465
11693
  workspace.getPackageJson(),
11466
11694
  this.#getAkanPeerDependencies()
11467
11695
  ]);
11696
+ const { typescript, ...dependencies } = peerDependencies;
11468
11697
  const packageJson = {
11469
11698
  ...rootPackageJson,
11470
11699
  dependencies: {
11471
11700
  ...rootPackageJson.dependencies,
11472
- ...peerDependencies,
11701
+ ...dependencies,
11473
11702
  akanjs: akanVersion
11474
11703
  },
11475
11704
  devDependencies: {
11476
11705
  ...rootPackageJson.devDependencies,
11477
- "@types/bun": latestTypesBunVersion
11706
+ "@biomejs/biome": latestBiomeVersion,
11707
+ "@types/bun": latestTypesBunVersion,
11708
+ "@akanjs/devkit": akanVersion,
11709
+ ...typescript ? { typescript } : {}
11478
11710
  }
11479
11711
  };
11480
11712
  await workspace.setPackageJson(packageJson);
@@ -11560,12 +11792,18 @@ class WorkspaceScript extends script("workspace", [
11560
11792
  LibraryScript,
11561
11793
  PackageScript
11562
11794
  ]) {
11563
- async createWorkspace(repoName, appName, { dirname: dirname3 = ".", installLibs = false, init = true }) {
11795
+ async createWorkspace(repoName, appName, {
11796
+ dirname: dirname3 = ".",
11797
+ installLibs = false,
11798
+ init = true,
11799
+ registryUrl
11800
+ }) {
11564
11801
  const akanVersion = await this.packageScript.version(null, { log: false });
11565
11802
  const workspace = await this.workspaceRunner.createWorkspace(repoName, appName, {
11566
11803
  dirname: dirname3,
11567
11804
  init,
11568
- akanVersion
11805
+ akanVersion,
11806
+ registryUrl
11569
11807
  });
11570
11808
  if (installLibs) {
11571
11809
  await this.libraryScript.installLibrary(workspace, "util");
@@ -11638,9 +11876,12 @@ class WorkspaceCommand extends command("workspace", [WorkspaceScript], ({ public
11638
11876
  }).option("init", Boolean, {
11639
11877
  desc: "Do you want to initialize the workspace? (Recommended)",
11640
11878
  default: true
11641
- }).exec(async function(workspaceName, app, dir, libs, init) {
11879
+ }).option("registry", String, {
11880
+ desc: "npm registry URL for installing Akan packages",
11881
+ default: process.env.AKAN_NPM_REGISTRY
11882
+ }).exec(async function(workspaceName, app, dir, libs, init, registry) {
11642
11883
  const appName = app || "app";
11643
- await this.workspaceScript.createWorkspace(workspaceName.toLowerCase().replace(/ /g, "-"), appName.toLowerCase().replace(/ /g, "-"), { dirname: dir, installLibs: libs, init });
11884
+ await this.workspaceScript.createWorkspace(workspaceName.toLowerCase().replace(/ /g, "-"), appName.toLowerCase().replace(/ /g, "-"), { dirname: dir, installLibs: libs, init, registryUrl: registry });
11644
11885
  }),
11645
11886
  lint: target({ desc: "Lint and fix code in a specific app/lib/pkg" }).with(Exec).option("fix", Boolean, { default: true }).with(Workspace).exec(async function(exec2, fix, workspace) {
11646
11887
  await this.workspaceScript.lint(exec2, workspace, { fix });