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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -1959,6 +1959,45 @@ var staticTemplateFileExtensions = new Set([
1959
1959
  ".woff2",
1960
1960
  ".xml"
1961
1961
  ]);
1962
+ var formatCommandArg = (value) => /^[\w@%+=:,./-]+$/.test(value) ? value : JSON.stringify(value);
1963
+ var formatCommandForDisplay = (command, args = []) => [command, ...args].map(formatCommandArg).join(" ");
1964
+
1965
+ class CommandExecutionError extends Error {
1966
+ command;
1967
+ args;
1968
+ cwd;
1969
+ code;
1970
+ signal;
1971
+ stdout;
1972
+ stderr;
1973
+ constructor({
1974
+ command,
1975
+ args = [],
1976
+ cwd,
1977
+ code,
1978
+ signal,
1979
+ stdout = "",
1980
+ stderr = "",
1981
+ cause
1982
+ }) {
1983
+ const displayCommand = formatCommandForDisplay(command, args);
1984
+ const status = signal ? `signal: ${signal}` : `exit code: ${code ?? "unknown"}`;
1985
+ const output = (stderr || stdout).trim();
1986
+ super([`Command failed: ${displayCommand}`, `cwd: ${cwd}`, status, output ? `
1987
+ ${output}` : ""].join(`
1988
+ `), {
1989
+ cause
1990
+ });
1991
+ this.name = "CommandExecutionError";
1992
+ this.command = command;
1993
+ this.args = args;
1994
+ this.cwd = cwd;
1995
+ this.code = code;
1996
+ this.signal = signal;
1997
+ this.stdout = stdout;
1998
+ this.stderr = stderr;
1999
+ }
2000
+ }
1962
2001
  var execEmoji = {
1963
2002
  workspace: "\uD83C\uDFE0",
1964
2003
  app: "\uD83D\uDE80",
@@ -2089,23 +2128,32 @@ class Executor {
2089
2128
  Logger4.raw(chalk4.red(data.toString()));
2090
2129
  }
2091
2130
  exec(command, options = {}) {
2131
+ const cwd = options.cwd?.toString() ?? this.cwdPath;
2092
2132
  const proc = exec(command, { cwd: this.cwdPath, ...options });
2133
+ let stdout = "";
2134
+ let stderr = "";
2093
2135
  proc.stdout?.on("data", (data) => {
2136
+ stdout += data.toString();
2094
2137
  this.#stdout(data);
2095
2138
  });
2096
2139
  proc.stderr?.on("data", (data) => {
2140
+ stderr += data.toString();
2097
2141
  this.#stdout(data);
2098
2142
  });
2099
2143
  return new Promise((resolve, reject) => {
2144
+ proc.on("error", (error) => {
2145
+ reject(new CommandExecutionError({ command, cwd, code: null, signal: null, stdout, stderr, cause: error }));
2146
+ });
2100
2147
  proc.on("exit", (code, signal) => {
2101
2148
  if (!!code || signal)
2102
- reject({ code, signal });
2149
+ reject(new CommandExecutionError({ command, cwd, code, signal, stdout, stderr }));
2103
2150
  else
2104
2151
  resolve({ code, signal });
2105
2152
  });
2106
2153
  });
2107
2154
  }
2108
2155
  spawn(command, args = [], options = {}) {
2156
+ const cwd = options.cwd?.toString() ?? this.cwdPath;
2109
2157
  const proc = spawn(command, args, {
2110
2158
  cwd: this.cwdPath,
2111
2159
  ...options
@@ -2123,9 +2171,12 @@ class Executor {
2123
2171
  this.#stdout(data);
2124
2172
  });
2125
2173
  return new Promise((resolve, reject) => {
2174
+ proc.on("error", (error) => {
2175
+ reject(new CommandExecutionError({ command, args, cwd, code: null, signal: null, stdout, stderr, cause: error }));
2176
+ });
2126
2177
  proc.on("close", (code, signal) => {
2127
2178
  if (code !== 0 || signal)
2128
- reject(stderr || stdout);
2179
+ reject(new CommandExecutionError({ command, args, cwd, code, signal, stdout, stderr }));
2129
2180
  else
2130
2181
  resolve(stdout);
2131
2182
  });
@@ -2139,20 +2190,37 @@ class Executor {
2139
2190
  return proc;
2140
2191
  }
2141
2192
  fork(modulePath, args = [], options = {}) {
2193
+ const cwd = options.cwd?.toString() ?? this.cwdPath;
2142
2194
  const proc = fork(modulePath, args, {
2143
2195
  cwd: this.cwdPath,
2144
2196
  ...options
2145
2197
  });
2198
+ let stdout = "";
2199
+ let stderr = "";
2146
2200
  proc.stdout?.on("data", (data) => {
2201
+ stdout += data.toString();
2147
2202
  this.#stdout(data);
2148
2203
  });
2149
2204
  proc.stderr?.on("data", (data) => {
2205
+ stderr += data.toString();
2150
2206
  this.#stderr(data);
2151
2207
  });
2152
2208
  return new Promise((resolve, reject) => {
2209
+ proc.on("error", (error) => {
2210
+ reject(new CommandExecutionError({
2211
+ command: modulePath,
2212
+ args,
2213
+ cwd,
2214
+ code: null,
2215
+ signal: null,
2216
+ stdout,
2217
+ stderr,
2218
+ cause: error
2219
+ }));
2220
+ });
2153
2221
  proc.on("exit", (code, signal) => {
2154
2222
  if (!!code || signal)
2155
- reject({ code, signal });
2223
+ reject(new CommandExecutionError({ command: modulePath, args, cwd, code, signal, stdout, stderr }));
2156
2224
  else
2157
2225
  resolve({ code, signal });
2158
2226
  });
@@ -3374,6 +3442,7 @@ class IncrementalBuilderHost {
3374
3442
  const candidates = [
3375
3443
  path8.join(app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts"),
3376
3444
  path8.join(app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts"),
3445
+ path8.join(import.meta.dir, "incrementalBuilder.proc.js"),
3377
3446
  path8.join(import.meta.dir, "incrementalBuilder.proc.ts")
3378
3447
  ];
3379
3448
  for (const c of candidates)
@@ -5348,9 +5417,7 @@ ${defaultNames.map((name) => `export default ${name};`).join(`
5348
5417
  }
5349
5418
  static resolveSsrClientRuntimeAliases() {
5350
5419
  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;
5420
+ return { [Bun.resolveSync("akanjs/fetch", serverEntry)]: "akanjs/fetch" };
5354
5421
  }
5355
5422
  static resolveSsrClientExternalOptions(command) {
5356
5423
  if (command === "start") {
@@ -5793,9 +5860,9 @@ class CssImportResolver {
5793
5860
  }
5794
5861
  async resolve(id, fromBase) {
5795
5862
  for (const resolve of [
5863
+ () => this.#resolveWithTsconfig(id),
5796
5864
  () => this.#resolveWithBun(id, fromBase),
5797
5865
  () => this.#resolveWithRequire(id, fromBase),
5798
- () => this.#resolveWithTsconfig(id),
5799
5866
  () => this.#resolvePackageStyle(id, fromBase)
5800
5867
  ]) {
5801
5868
  const resolved = await resolve();
@@ -5805,20 +5872,24 @@ class CssImportResolver {
5805
5872
  return null;
5806
5873
  }
5807
5874
  #resolveWithBun(id, fromBase) {
5808
- try {
5809
- const resolved = Bun.resolveSync(id, fromBase);
5810
- return CssImportResolver.isCssFile(resolved) ? resolved : null;
5811
- } catch {
5812
- return null;
5875
+ for (const base of this.#resolutionBases(fromBase)) {
5876
+ try {
5877
+ const resolved = Bun.resolveSync(id, base);
5878
+ if (CssImportResolver.isCssFile(resolved))
5879
+ return resolved;
5880
+ } catch {}
5813
5881
  }
5882
+ return null;
5814
5883
  }
5815
5884
  #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;
5885
+ for (const base of this.#resolutionBases(fromBase)) {
5886
+ try {
5887
+ const resolved = __require.resolve(id, { paths: [base] });
5888
+ if (CssImportResolver.isCssFile(resolved))
5889
+ return resolved;
5890
+ } catch {}
5821
5891
  }
5892
+ return null;
5822
5893
  }
5823
5894
  async#resolveWithTsconfig(id) {
5824
5895
  const exact = this.#paths[id];
@@ -5846,8 +5917,25 @@ class CssImportResolver {
5846
5917
  const pkgName = CssImportResolver.getPackageName(id);
5847
5918
  if (!pkgName)
5848
5919
  return null;
5920
+ for (const base of this.#resolutionBases(fromBase)) {
5921
+ try {
5922
+ const pkgPath = __require.resolve(`${pkgName}/package.json`, { paths: [base] });
5923
+ const resolved = await this.#resolvePackageStyleFromPackageJson(id, pkgName, pkgPath);
5924
+ if (resolved)
5925
+ return resolved;
5926
+ } catch {}
5927
+ }
5928
+ for (const pkgPath of this.#packageJsonCandidates(pkgName)) {
5929
+ const resolved = await this.#resolvePackageStyleFromPackageJson(id, pkgName, pkgPath);
5930
+ if (resolved)
5931
+ return resolved;
5932
+ }
5933
+ return null;
5934
+ }
5935
+ async#resolvePackageStyleFromPackageJson(id, pkgName, pkgPath) {
5849
5936
  try {
5850
- const pkgPath = __require.resolve(`${pkgName}/package.json`, { paths: [fromBase] });
5937
+ if (!await Bun.file(pkgPath).exists())
5938
+ return null;
5851
5939
  const pkgDir = path22.dirname(pkgPath);
5852
5940
  const pkg = await Bun.file(pkgPath).json();
5853
5941
  const subpath = id === pkgName ? "." : `.${id.slice(pkgName.length)}`;
@@ -5858,6 +5946,17 @@ class CssImportResolver {
5858
5946
  return null;
5859
5947
  }
5860
5948
  }
5949
+ #resolutionBases(fromBase) {
5950
+ return [fromBase, this.#workspaceRoot, path22.dirname(Bun.main), path22.resolve(path22.dirname(Bun.main), "../..")];
5951
+ }
5952
+ #packageJsonCandidates(pkgName) {
5953
+ return [
5954
+ path22.join(this.#workspaceRoot, "pkgs", pkgName, "package.json"),
5955
+ path22.join(this.#workspaceRoot, "node_modules", pkgName, "package.json"),
5956
+ path22.join(path22.dirname(Bun.main), "node_modules", pkgName, "package.json"),
5957
+ path22.join(path22.dirname(Bun.main), "../../", pkgName, "package.json")
5958
+ ];
5959
+ }
5861
5960
  async#firstExisting(basePath2) {
5862
5961
  for (const suffix of CSS_IMPORT_EXTS) {
5863
5962
  const candidate = `${basePath2}${suffix}`;
@@ -6980,16 +7079,20 @@ class SsrBaseArtifactBuilder {
6980
7079
  return { rscClientUrl, vendorMap };
6981
7080
  }
6982
7081
  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
- ];
7082
+ const candidates = [];
7083
+ try {
7084
+ candidates.push(path30.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
7085
+ } catch {}
7086
+ candidates.push(path30.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path30.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
7087
+ try {
7088
+ candidates.push(path30.dirname(Bun.resolveSync("akanjs/server", path30.dirname(Bun.main))));
7089
+ } catch {}
7090
+ 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
7091
  for (const candidate of candidates) {
6989
7092
  if (await Bun.file(path30.join(candidate, "rscClient.tsx")).exists())
6990
7093
  return candidate;
6991
7094
  }
6992
- return candidates[0];
7095
+ throw new Error(`[base-artifact] failed to locate akanjs/server; looked in: ${candidates.join(", ")}`);
6993
7096
  }
6994
7097
  async#buildStyleAssets() {
6995
7098
  const cssCompiler = new CssCompiler(this.#app);
@@ -7063,25 +7166,11 @@ var SSR_RENDER_EXTERNALS = [
7063
7166
  "react/jsx-dev-runtime",
7064
7167
  "react-dom",
7065
7168
  "react-dom/server.browser",
7169
+ "react-server-dom-webpack",
7170
+ "react-server-dom-webpack/server.node",
7066
7171
  "react-server-dom-webpack/client.node",
7067
7172
  "react-server-dom-webpack/client.browser"
7068
7173
  ];
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
- `;
7085
7174
 
7086
7175
  class ApplicationBuildRunner {
7087
7176
  #app;
@@ -7172,7 +7261,7 @@ class ApplicationBuildRunner {
7172
7261
  naming: { entry: "[name].[ext]", chunk: "chunk-[hash].[ext]" },
7173
7262
  conditions: ["react-server"],
7174
7263
  define: { "process.env.NODE_ENV": JSON.stringify("production") },
7175
- plugins: akanConfig2.externalLibs.length > 0 ? [this.#createExternalSpecifiersPlugin(akanConfig2.externalLibs)] : []
7264
+ plugins: backendExternals.length > 0 ? [this.#createExternalSpecifiersPlugin(backendExternals)] : []
7176
7265
  });
7177
7266
  return {
7178
7267
  entrypoints: backendEntryPoints.length + 1,
@@ -7225,7 +7314,8 @@ class ApplicationBuildRunner {
7225
7314
  return { typecheckDir, tsconfigPath };
7226
7315
  }
7227
7316
  async#checkProjectInChildProcess(tsconfigPath) {
7228
- const proc = Bun.spawn([process.execPath, "--eval", TYPECHECK_WORKER_CODE], {
7317
+ const entry = await this.#resolveTypecheckWorkerEntry();
7318
+ const proc = Bun.spawn([process.execPath, entry], {
7229
7319
  cwd: this.#app.workspace.workspaceRoot,
7230
7320
  env: this.#app.getCommandEnv({
7231
7321
  AKAN_COMMAND_TYPE: "typecheck",
@@ -7242,6 +7332,18 @@ class ApplicationBuildRunner {
7242
7332
  if (exitCode !== 0)
7243
7333
  throw new Error((stderr || stdout).trim() || `Typecheck failed with exit code ${exitCode}`);
7244
7334
  }
7335
+ async#resolveTypecheckWorkerEntry() {
7336
+ const candidates = [
7337
+ path32.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
7338
+ path32.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
7339
+ path32.join(import.meta.dir, "typecheck.proc.js"),
7340
+ path32.join(import.meta.dir, "typecheck.proc.ts")
7341
+ ];
7342
+ for (const candidate of candidates)
7343
+ if (await Bun.file(candidate).exists())
7344
+ return candidate;
7345
+ throw new Error(`[cli] typecheck worker entry not found; looked in: ${candidates.join(", ")}`);
7346
+ }
7245
7347
  async#buildOrThrow(label, config) {
7246
7348
  const result = await Bun.build(config);
7247
7349
  if (!result.success)
@@ -7507,10 +7609,31 @@ class ApplicationReleasePackager {
7507
7609
  `;
7508
7610
  }
7509
7611
  }
7612
+ // pkgs/@akanjs/devkit/applicationTestPreload.ts
7613
+ import path33 from "path";
7614
+ var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
7615
+ async function resolveSignalTestPreloadPath(target) {
7616
+ const candidates = [];
7617
+ const addResolvedPackageCandidate = (basePath2) => {
7618
+ try {
7619
+ candidates.push(path33.join(path33.dirname(Bun.resolveSync("akanjs/package.json", basePath2)), SIGNAL_TEST_PRELOAD_PATH));
7620
+ } catch {}
7621
+ };
7622
+ addResolvedPackageCandidate(target.cwdPath);
7623
+ addResolvedPackageCandidate(process.cwd());
7624
+ addResolvedPackageCandidate(path33.dirname(Bun.main));
7625
+ addResolvedPackageCandidate(import.meta.dir);
7626
+ 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));
7627
+ for (const candidate of [...new Set(candidates)]) {
7628
+ if (await Bun.file(candidate).exists())
7629
+ return candidate;
7630
+ }
7631
+ throw new Error(`Failed to locate ${SIGNAL_TEST_PRELOAD_PATH} from ${target.cwdPath}`);
7632
+ }
7510
7633
  // pkgs/@akanjs/devkit/builder.ts
7511
7634
  import { existsSync as existsSync2 } from "fs";
7512
7635
  import { mkdir as mkdir9 } from "fs/promises";
7513
- import path33 from "path";
7636
+ import path34 from "path";
7514
7637
  var SKIP_ENTRY_DIR_SET = new Set(["node_modules", "dist", "build", ".git", ".next"]);
7515
7638
  var assetExtensions = [".css", ".md", ".js", ".png", ".ico", ".svg", ".json", ".template"];
7516
7639
  var assetLoader = Object.fromEntries(assetExtensions.map((ext) => [ext, "file"]));
@@ -7527,14 +7650,14 @@ class Builder {
7527
7650
  #globEntrypoints(cwd, pattern) {
7528
7651
  const glob = new Bun.Glob(pattern);
7529
7652
  return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
7530
- const segments = relativePath.split(path33.sep);
7653
+ const segments = relativePath.split(path34.sep);
7531
7654
  return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
7532
- }).map((rel) => path33.join(cwd, rel));
7655
+ }).map((rel) => path34.join(cwd, rel));
7533
7656
  }
7534
7657
  #globFiles(cwd, pattern = "**/*.*") {
7535
7658
  const glob = new Bun.Glob(pattern);
7536
7659
  return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
7537
- const segments = relativePath.split(path33.sep);
7660
+ const segments = relativePath.split(path34.sep);
7538
7661
  return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
7539
7662
  });
7540
7663
  }
@@ -7542,17 +7665,17 @@ class Builder {
7542
7665
  const out = [];
7543
7666
  for (const p of additionalEntryPoints) {
7544
7667
  if (p.includes("*")) {
7545
- const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path33.sep}`) ? p.slice(cwd.length + 1) : p;
7668
+ const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path34.sep}`) ? p.slice(cwd.length + 1) : p;
7546
7669
  out.push(...this.#globEntrypoints(cwd, rel));
7547
7670
  } else
7548
- out.push(path33.isAbsolute(p) ? p : path33.join(cwd, p));
7671
+ out.push(path34.isAbsolute(p) ? p : path34.join(cwd, p));
7549
7672
  }
7550
7673
  return out;
7551
7674
  }
7552
7675
  #getBuildOptions({ bundle = false, additionalEntryPoints = [] } = {}) {
7553
7676
  const cwd = this.#executor.cwdPath;
7554
7677
  const entrypoints = [
7555
- ...bundle ? [path33.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
7678
+ ...bundle ? [path34.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
7556
7679
  ...this.#resolveAdditionalEntrypoints(cwd, additionalEntryPoints)
7557
7680
  ];
7558
7681
  return {
@@ -7573,9 +7696,9 @@ class Builder {
7573
7696
  for (const relativePath of this.#globFiles(cwd)) {
7574
7697
  if (relativePath === "package.json")
7575
7698
  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 });
7699
+ const sourcePath = path34.join(cwd, relativePath);
7700
+ const targetPath = path34.join(this.#distExecutor.cwdPath, relativePath);
7701
+ await mkdir9(path34.dirname(targetPath), { recursive: true });
7579
7702
  await Bun.write(targetPath, Bun.file(sourcePath));
7580
7703
  }
7581
7704
  }
@@ -7586,13 +7709,13 @@ class Builder {
7586
7709
  return withoutFormatDir;
7587
7710
  if (!hasDotSlash && withoutFormatDir === publishedPath)
7588
7711
  return publishedPath;
7589
- const parsed = path33.posix.parse(withoutFormatDir);
7712
+ const parsed = path34.posix.parse(withoutFormatDir);
7590
7713
  if (![".js", ".mjs", ".cjs"].includes(parsed.ext))
7591
7714
  return withoutFormatDir;
7592
- const withoutExt = path33.posix.join(parsed.dir, parsed.name);
7715
+ const withoutExt = path34.posix.join(parsed.dir, parsed.name);
7593
7716
  const sourcePath = withoutExt.startsWith("./") ? withoutExt.slice(2) : withoutExt;
7594
7717
  const sourceCandidates = [`${sourcePath}.ts`, `${sourcePath}.tsx`];
7595
- const matchedSource = sourceCandidates.find((candidate) => existsSync2(path33.join(this.#executor.cwdPath, candidate)));
7718
+ const matchedSource = sourceCandidates.find((candidate) => existsSync2(path34.join(this.#executor.cwdPath, candidate)));
7596
7719
  if (!matchedSource)
7597
7720
  return withoutFormatDir;
7598
7721
  return hasDotSlash ? `./${matchedSource}` : matchedSource;
@@ -7642,7 +7765,7 @@ class Builder {
7642
7765
  }
7643
7766
  // pkgs/@akanjs/devkit/capacitorApp.ts
7644
7767
  import { cp as cp2, mkdir as mkdir10, rm as rm4 } from "fs/promises";
7645
- import path34 from "path";
7768
+ import path35 from "path";
7646
7769
  import { MobileProject } from "@trapezedev/project";
7647
7770
  import { capitalize as capitalize2 } from "akanjs/common";
7648
7771
 
@@ -7836,10 +7959,10 @@ class CapacitorApp {
7836
7959
  constructor(app, target) {
7837
7960
  this.app = app;
7838
7961
  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");
7962
+ this.targetRootPath = path35.posix.join("mobile", this.target.name);
7963
+ this.targetRoot = path35.join(this.app.cwdPath, this.targetRootPath);
7964
+ this.targetWebRoot = path35.join(this.targetRoot, "www");
7965
+ this.targetAssetRoot = path35.join(this.targetRoot, "assets");
7843
7966
  this.project = new MobileProject(this.app.cwdPath, {
7844
7967
  android: { path: this.androidRootPath },
7845
7968
  ios: { path: this.iosProjectPath }
@@ -7855,9 +7978,9 @@ class CapacitorApp {
7855
7978
  await this.#writeCapacitorConfig();
7856
7979
  if (regenerate) {
7857
7980
  if (!platform || platform === "ios")
7858
- await rm4(path34.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
7981
+ await rm4(path35.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
7859
7982
  if (!platform || platform === "android")
7860
- await rm4(path34.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
7983
+ await rm4(path35.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
7861
7984
  }
7862
7985
  const project = this.project;
7863
7986
  await this.project.load();
@@ -7919,7 +8042,7 @@ class CapacitorApp {
7919
8042
  await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
7920
8043
  }
7921
8044
  async#updateAndroidBuildTypes() {
7922
- const appGradle = await FileEditor.create(path34.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
8045
+ const appGradle = await FileEditor.create(path35.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
7923
8046
  const buildTypesBlock = `
7924
8047
  debug {
7925
8048
  applicationIdSuffix ".debug"
@@ -7962,7 +8085,7 @@ class CapacitorApp {
7962
8085
  const gradleCommand = isWindows ? "gradlew.bat" : "./gradlew";
7963
8086
  await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
7964
8087
  stdio: "inherit",
7965
- cwd: path34.join(this.app.cwdPath, this.androidRootPath),
8088
+ cwd: path35.join(this.app.cwdPath, this.androidRootPath),
7966
8089
  env: this.#commandEnv("release", env)
7967
8090
  });
7968
8091
  }
@@ -7991,12 +8114,12 @@ class CapacitorApp {
7991
8114
  await this.#prepareAndroid({ operation: "release", env: "main" });
7992
8115
  }
7993
8116
  async prepareWww() {
7994
- const htmlSource = path34.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
8117
+ const htmlSource = path35.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
7995
8118
  if (!await Bun.file(htmlSource).exists())
7996
8119
  throw new Error(`CSR html for mobile target '${this.target.name}' not found: ${htmlSource}`);
7997
8120
  await rm4(this.targetWebRoot, { recursive: true, force: true });
7998
8121
  await mkdir10(this.targetWebRoot, { recursive: true });
7999
- await Bun.write(path34.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
8122
+ await Bun.write(path35.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
8000
8123
  }
8001
8124
  #injectMobileTargetMeta(html) {
8002
8125
  const basePath2 = this.target.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
@@ -8008,9 +8131,9 @@ class CapacitorApp {
8008
8131
  }
8009
8132
  async#writeCapacitorConfig() {
8010
8133
  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("/");
8134
+ const appInfoPath = path35.relative(this.app.cwdPath, path35.join(this.app.cwdPath, "akan.app.json")).split(path35.sep).join("/");
8012
8135
  const content = `import type { AppScanResult } from "akanjs";
8013
- import { withBase } from "@akanjs/devkit/capacitor.base.config";
8136
+ import { withBase } from "akanjs/capacitor.base.config";
8014
8137
  import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
8015
8138
 
8016
8139
  export default withBase(
@@ -8029,18 +8152,18 @@ export default withBase(
8029
8152
  appInfo as AppScanResult,
8030
8153
  );
8031
8154
  `;
8032
- await Bun.write(path34.join(this.app.cwdPath, "capacitor.config.ts"), content);
8155
+ await Bun.write(path35.join(this.app.cwdPath, "capacitor.config.ts"), content);
8033
8156
  }
8034
8157
  async#prepareTargetAssets() {
8035
8158
  if (!this.target.assets)
8036
8159
  return;
8037
8160
  await mkdir10(this.targetAssetRoot, { recursive: true });
8038
8161
  if (this.target.assets.icon)
8039
- await cp2(path34.join(this.app.cwdPath, this.target.assets.icon), path34.join(this.targetAssetRoot, "icon.png"), {
8162
+ await cp2(path35.join(this.app.cwdPath, this.target.assets.icon), path35.join(this.targetAssetRoot, "icon.png"), {
8040
8163
  force: true
8041
8164
  });
8042
8165
  if (this.target.assets.splash)
8043
- await cp2(path34.join(this.app.cwdPath, this.target.assets.splash), path34.join(this.targetAssetRoot, "splash.png"), {
8166
+ await cp2(path35.join(this.app.cwdPath, this.target.assets.splash), path35.join(this.targetAssetRoot, "splash.png"), {
8044
8167
  force: true
8045
8168
  });
8046
8169
  }
@@ -8048,11 +8171,11 @@ export default withBase(
8048
8171
  const files = this.target.files?.[platform];
8049
8172
  if (!files)
8050
8173
  return;
8051
- const platformRoot = path34.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
8174
+ const platformRoot = path35.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
8052
8175
  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 });
8176
+ const targetPath = path35.join(platformRoot, to);
8177
+ await mkdir10(path35.dirname(targetPath), { recursive: true });
8178
+ await cp2(path35.join(this.app.cwdPath, from), targetPath, { force: true });
8056
8179
  }));
8057
8180
  }
8058
8181
  async#generateAssets({ operation, env }) {
@@ -8062,7 +8185,7 @@ export default withBase(
8062
8185
  "@capacitor/assets",
8063
8186
  "generate",
8064
8187
  "--assetPath",
8065
- path34.posix.join(this.targetRootPath, "assets"),
8188
+ path35.posix.join(this.targetRootPath, "assets"),
8066
8189
  "--iosProject",
8067
8190
  this.iosProjectPath,
8068
8191
  "--androidProject",
@@ -8247,8 +8370,8 @@ var Pkg = createInternalArgToken("Pkg");
8247
8370
  var Module = createInternalArgToken("Module");
8248
8371
  var Workspace = createInternalArgToken("Workspace");
8249
8372
  // pkgs/@akanjs/devkit/commandDecorators/command.ts
8373
+ import path36 from "path";
8250
8374
  import { confirm, input as input2, select as select2 } from "@inquirer/prompts";
8251
- import path35 from "path";
8252
8375
  import { Logger as Logger11 } from "akanjs/common";
8253
8376
  import chalk6 from "chalk";
8254
8377
  import { program } from "commander";
@@ -8506,6 +8629,37 @@ var formatCommandHelp = (command, key) => {
8506
8629
 
8507
8630
  // pkgs/@akanjs/devkit/commandDecorators/command.ts
8508
8631
  var camelToKebabCase2 = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
8632
+ var loggedCliErrorObjects = new WeakSet;
8633
+ var loggedCliErrorMessages = new Set;
8634
+ var formatCliError = (error) => {
8635
+ if (error instanceof Error)
8636
+ return error.message || error.name;
8637
+ if (typeof error === "string")
8638
+ return error.trim() || "Unknown error";
8639
+ if (error === null || error === undefined)
8640
+ return "Unknown error";
8641
+ try {
8642
+ const json = JSON.stringify(error);
8643
+ if (json)
8644
+ return json;
8645
+ } catch {
8646
+ return String(error);
8647
+ }
8648
+ return String(error) || "Unknown error";
8649
+ };
8650
+ var printCliError = (error) => {
8651
+ if (typeof error === "object" && error !== null) {
8652
+ if (loggedCliErrorObjects.has(error))
8653
+ return;
8654
+ loggedCliErrorObjects.add(error);
8655
+ }
8656
+ const message = formatCliError(error);
8657
+ if (loggedCliErrorMessages.has(message))
8658
+ return;
8659
+ loggedCliErrorMessages.add(message);
8660
+ Logger11.rawLog(`
8661
+ ${chalk6.red(message)}`);
8662
+ };
8509
8663
  var handleOption = (programCommand, argMeta) => {
8510
8664
  const {
8511
8665
  type,
@@ -8712,10 +8866,11 @@ var getInternalArgumentValue = async (argMeta, value, workspace) => {
8712
8866
  };
8713
8867
  var runCommands = async (...commands) => {
8714
8868
  process.on("unhandledRejection", (error) => {
8869
+ printCliError(error);
8715
8870
  process.exit(1);
8716
8871
  });
8717
8872
  const __dirname2 = getDirname(import.meta.url);
8718
- const packageJsonCandidates = [`${path35.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
8873
+ const packageJsonCandidates = [`${path36.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
8719
8874
  let cliPackageJson = null;
8720
8875
  for (const packageJsonPath of packageJsonCandidates) {
8721
8876
  if (!await FileSys.fileExists(packageJsonPath))
@@ -8802,9 +8957,7 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
8802
8957
  await targetMeta.handler.call(cmd, ...commandArgs);
8803
8958
  Logger11.rawLog();
8804
8959
  } catch (e) {
8805
- const errMsg = e instanceof Error ? e.message : typeof e === "string" ? e : JSON.stringify(e);
8806
- Logger11.rawLog(`
8807
- ${chalk6.red(errMsg)}`);
8960
+ printCliError(e);
8808
8961
  throw e;
8809
8962
  }
8810
8963
  });
@@ -8993,8 +9146,8 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
8993
9146
  return importSpecifiers;
8994
9147
  };
8995
9148
  var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
8996
- const configFile = ts6.readConfigFile(tsConfigPath, (path36) => {
8997
- return ts6.sys.readFile(path36);
9149
+ const configFile = ts6.readConfigFile(tsConfigPath, (path37) => {
9150
+ return ts6.sys.readFile(path37);
8998
9151
  });
8999
9152
  return ts6.parseJsonConfigFileContent(configFile.config, ts6.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
9000
9153
  };
@@ -9339,7 +9492,6 @@ class LibraryScript extends script("library", [LibraryRunner]) {
9339
9492
  }
9340
9493
 
9341
9494
  // pkgs/@akanjs/cli/application/application.runner.ts
9342
- import path36 from "path";
9343
9495
  import { confirm as confirm2, input as input4, select as select5 } from "@inquirer/prompts";
9344
9496
  import { StringOutputParser } from "@langchain/core/output_parsers";
9345
9497
  import { PromptTemplate as PromptTemplate2 } from "@langchain/core/prompts";
@@ -9405,14 +9557,14 @@ class ApplicationRunner extends runner("application") {
9405
9557
  }
9406
9558
  async test(exec2) {
9407
9559
  const isSignalTarget = exec2 instanceof AppExecutor || exec2 instanceof LibExecutor;
9408
- const preloadPath = path36.join(exec2.cwdPath, "../../pkgs/akanjs/test/signalTest.preload.ts");
9560
+ const preloadPath = isSignalTarget ? await resolveSignalTestPreloadPath(exec2) : null;
9409
9561
  const env = isSignalTarget ? {
9410
9562
  AKAN_TEST_SIGNAL: "1",
9411
9563
  AKAN_TEST_TARGET_TYPE: exec2.type,
9412
9564
  AKAN_TEST_TARGET_NAME: exec2.name,
9413
9565
  AKAN_TEST_LIBS: exec2.getScanInfo({ allowEmpty: true })?.getLibs().join(",") ?? ""
9414
9566
  } : {};
9415
- const args = isSignalTarget ? ["test", "--isolate", "--preload", preloadPath] : ["test", "--isolate"];
9567
+ const args = preloadPath ? ["test", "--isolate", "--preload", preloadPath] : ["test", "--isolate"];
9416
9568
  await exec2.spawn("bun", args, {
9417
9569
  ...isSignalTarget ? { env: { ...process.env, ...env } } : {},
9418
9570
  stdio: "inherit"
@@ -9582,8 +9734,15 @@ class ApplicationRunner extends runner("application") {
9582
9734
  cwd: `${workspace.workspaceRoot}/local`
9583
9735
  });
9584
9736
  return wasAlreadyUp;
9585
- } catch {
9586
- throw new Error(`Docker daemon is not running. Please install docker or start docker daemon and try again.`);
9737
+ } catch (error) {
9738
+ const detail = error instanceof Error ? error.message : typeof error === "string" ? error : JSON.stringify(error) || "Unknown error";
9739
+ throw new Error([
9740
+ "Docker daemon may not be running. Please install Docker or start the Docker daemon and try again.",
9741
+ `Original error:
9742
+ ${detail}`
9743
+ ].join(`
9744
+
9745
+ `));
9587
9746
  }
9588
9747
  }
9589
9748
  async dbdown(workspace) {
@@ -9704,12 +9863,17 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
9704
9863
  }
9705
9864
  }
9706
9865
  async test(exec2, { write = true } = {}) {
9866
+ if (exec2 instanceof LibExecutor) {
9867
+ await this.libraryScript.syncLibrary(exec2);
9868
+ const spinner3 = exec2.spinning(`Preparing ${exec2.name}...`);
9869
+ spinner3.succeed(`${exec2.name} prepared`);
9870
+ await this.applicationRunner.test(exec2);
9871
+ return;
9872
+ }
9707
9873
  const spinner2 = exec2.spinning(`Preparing ${exec2.name}...`);
9708
9874
  try {
9709
9875
  if (exec2 instanceof PkgExecutor)
9710
9876
  await exec2.scan({ refresh: true });
9711
- else if (exec2 instanceof LibExecutor)
9712
- await this.libraryScript.syncLibrary(exec2);
9713
9877
  else
9714
9878
  await exec2.scanSync({ write });
9715
9879
  spinner2.succeed(`${exec2.name} prepared`);
@@ -10007,11 +10171,17 @@ class PackageRunner extends runner("package") {
10007
10171
  await pkg.dist.mkdir(pkg.dist.cwdPath);
10008
10172
  const scanner = await TypeScriptDependencyScanner.from(pkg);
10009
10173
  const { npmDeps, npmDevDeps, missingDeps } = await scanner.getPackageBuildDependencies(pkg.name);
10010
- const packageRuntimeDependencies = {};
10174
+ const packageRuntimeDependencies = {
10175
+ "@akanjs/devkit": ["daisyui", "tailwind-scrollbar"]
10176
+ };
10011
10177
  const packageRuntimeDevDependencies = { akanjs: ["@biomejs/biome", "@types/bun"] };
10012
10178
  if (pkg.name === "@akanjs/cli") {
10013
10179
  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");
10180
+ packageRuntimeDependencies[pkg.name] = [
10181
+ ...Object.keys(devkitPackageJson.dependencies ?? {}),
10182
+ "daisyui",
10183
+ "tailwind-scrollbar"
10184
+ ].filter((dep) => dep !== "akanjs" && dep !== "@akanjs/devkit");
10015
10185
  }
10016
10186
  const bundledRuntimeDeps = new Set(pkg.name === "@akanjs/cli" ? ["@akanjs/devkit"] : []);
10017
10187
  const forcedRuntimeDeps = packageRuntimeDependencies[pkg.name] ?? [];
@@ -10227,10 +10397,10 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10227
10397
  }
10228
10398
  async update(workspace, tag = "latest") {
10229
10399
  if (!await workspace.exists("package.json"))
10230
- await workspace.spawn("npm", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`]);
10400
+ await workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`]);
10231
10401
  else
10232
10402
  await Promise.all([
10233
- workspace.spawn("npm", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`]),
10403
+ workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`]),
10234
10404
  this.#updateAkanPkgs(workspace, tag)
10235
10405
  ]);
10236
10406
  }
@@ -10243,6 +10413,10 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10243
10413
  rootPackageJson.dependencies.akanjs = latestPublishedVersion;
10244
10414
  if (rootPackageJson.devDependencies?.akanjs)
10245
10415
  rootPackageJson.devDependencies.akanjs = latestPublishedVersion;
10416
+ if (rootPackageJson.dependencies["@akanjs/devkit"])
10417
+ rootPackageJson.dependencies["@akanjs/devkit"] = latestPublishedVersion;
10418
+ if (rootPackageJson.devDependencies?.["@akanjs/devkit"])
10419
+ rootPackageJson.devDependencies["@akanjs/devkit"] = latestPublishedVersion;
10246
10420
  workspace.setPackageJson(rootPackageJson);
10247
10421
  await workspace.spawn("bun", ["install"]);
10248
10422
  }
@@ -10318,6 +10492,7 @@ class CloudCommand extends command("cloud", [CloudScript], ({ public: target })
10318
10492
 
10319
10493
  // pkgs/@akanjs/cli/guideline/guideline.prompt.ts
10320
10494
  import { randomPicks } from "akanjs/common";
10495
+
10321
10496
  class GuidelinePrompt extends Prompter {
10322
10497
  workspace;
10323
10498
  name;
@@ -11419,7 +11594,7 @@ class ScalarScript extends script("scalar", [ScalarRunner]) {
11419
11594
 
11420
11595
  // pkgs/@akanjs/cli/scalar/scalar.command.ts
11421
11596
  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) {
11597
+ 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
11598
  const name = lowerlize2(scalarName.replace(/ /g, ""));
11424
11599
  if (ai)
11425
11600
  await this.scalarScript.createScalarWithAi(sys3, name);
@@ -11439,11 +11614,19 @@ import { Logger as Logger17 } from "akanjs/common";
11439
11614
  // pkgs/@akanjs/cli/workspace/workspace.runner.ts
11440
11615
  import path38 from "path";
11441
11616
  var defaultWorkspacePeerDependencies = new Set([
11617
+ "@radix-ui/react-dialog",
11618
+ "@react-spring/web",
11619
+ "@use-gesture/react",
11620
+ "croner",
11621
+ "daisyui",
11442
11622
  "react",
11443
11623
  "react-dom",
11624
+ "react-icons",
11444
11625
  "react-refresh",
11445
11626
  "react-server-dom-webpack",
11627
+ "react-spring",
11446
11628
  "scheduler",
11629
+ "tailwind-scrollbar",
11447
11630
  "tailwindcss",
11448
11631
  "typescript"
11449
11632
  ]);
@@ -11454,7 +11637,10 @@ class WorkspaceRunner extends runner("workspace") {
11454
11637
  const workspaceRoot = path38.join(cwdPath, dirname3, repoName);
11455
11638
  const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
11456
11639
  const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname3}/${repoName}...`);
11457
- const latestTypesBunVersion = await getLatestPackageVersion("@types/bun");
11640
+ const [latestBiomeVersion, latestTypesBunVersion] = await Promise.all([
11641
+ getLatestPackageVersion("@biomejs/biome"),
11642
+ getLatestPackageVersion("@types/bun")
11643
+ ]);
11458
11644
  await workspace.applyTemplate({
11459
11645
  basePath: ".",
11460
11646
  template: "workspaceRoot",
@@ -11465,16 +11651,20 @@ class WorkspaceRunner extends runner("workspace") {
11465
11651
  workspace.getPackageJson(),
11466
11652
  this.#getAkanPeerDependencies()
11467
11653
  ]);
11654
+ const { typescript, ...dependencies } = peerDependencies;
11468
11655
  const packageJson = {
11469
11656
  ...rootPackageJson,
11470
11657
  dependencies: {
11471
11658
  ...rootPackageJson.dependencies,
11472
- ...peerDependencies,
11659
+ ...dependencies,
11473
11660
  akanjs: akanVersion
11474
11661
  },
11475
11662
  devDependencies: {
11476
11663
  ...rootPackageJson.devDependencies,
11477
- "@types/bun": latestTypesBunVersion
11664
+ "@biomejs/biome": latestBiomeVersion,
11665
+ "@types/bun": latestTypesBunVersion,
11666
+ "@akanjs/devkit": akanVersion,
11667
+ ...typescript ? { typescript } : {}
11478
11668
  }
11479
11669
  };
11480
11670
  await workspace.setPackageJson(packageJson);