@akanjs/cli 0.0.138 → 0.0.139

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/esm/index.js CHANGED
@@ -903,28 +903,50 @@ var TypeScriptDependencyScanner = class {
903
903
 
904
904
  // pkgs/@akanjs/devkit/src/spinner.ts
905
905
  import ora2 from "ora";
906
- var Spinner = class {
906
+ var Spinner = class _Spinner {
907
+ static padding = 12;
907
908
  spinner;
908
909
  stopWatch;
909
910
  startAt;
911
+ prefix;
910
912
  message;
911
- constructor(message, { prefix = "", indent = 0 } = {}) {
913
+ enableSpin;
914
+ constructor(message, { prefix = "", indent = 0, enableSpin = true } = {}) {
915
+ _Spinner.padding = Math.max(_Spinner.padding, prefix.length);
916
+ this.prefix = prefix;
912
917
  this.message = message;
913
918
  this.spinner = ora2(message);
914
- this.spinner.prefixText = prefix;
919
+ this.spinner.prefixText = prefix.padStart(_Spinner.padding, " ");
915
920
  this.spinner.indent = indent;
921
+ this.enableSpin = enableSpin;
916
922
  }
917
923
  start() {
918
924
  this.startAt = /* @__PURE__ */ new Date();
919
- const spinner = this.spinner.start();
920
- this.stopWatch = setInterval(() => {
921
- spinner.text = `${this.message} (${this.#getElapsedTimeStr()})`;
922
- }, 1e3);
925
+ if (this.enableSpin) {
926
+ this.spinner.start();
927
+ this.stopWatch = setInterval(() => {
928
+ this.spinner.prefixText = this.prefix.padStart(_Spinner.padding, " ");
929
+ this.spinner.text = `${this.message} (${this.#getElapsedTimeStr()})`;
930
+ }, 1e3);
931
+ } else
932
+ this.spinner.info();
923
933
  return this;
924
934
  }
925
935
  succeed(message) {
926
- clearInterval(this.stopWatch);
927
936
  this.spinner.succeed(`${message} (${this.#getElapsedTimeStr()})`);
937
+ this.#reset();
938
+ }
939
+ fail(message) {
940
+ this.spinner.fail(`${message} (${this.#getElapsedTimeStr()})`);
941
+ this.#reset();
942
+ }
943
+ isSpinning() {
944
+ return this.spinner.isSpinning;
945
+ }
946
+ #reset() {
947
+ if (this.stopWatch)
948
+ clearInterval(this.stopWatch);
949
+ this.stopWatch = null;
928
950
  }
929
951
  #getElapsedTimeStr() {
930
952
  const ms = (/* @__PURE__ */ new Date()).getTime() - this.startAt.getTime();
@@ -948,7 +970,11 @@ var execEmoji = {
948
970
  default: "\u2708\uFE0F"
949
971
  // for sys executor
950
972
  };
951
- var Executor = class {
973
+ var Executor = class _Executor {
974
+ static verbose = false;
975
+ static setVerbose(verbose) {
976
+ _Executor.verbose = verbose;
977
+ }
952
978
  name;
953
979
  logger;
954
980
  cwdPath;
@@ -978,7 +1004,11 @@ var Executor = class {
978
1004
  });
979
1005
  }
980
1006
  spawn(command, args = [], options = {}) {
981
- const proc = spawn(command, args, { cwd: this.cwdPath, stdio: "inherit", ...options });
1007
+ const proc = spawn(command, args, {
1008
+ cwd: this.cwdPath,
1009
+ stdio: _Executor.verbose ? "inherit" : "ignore",
1010
+ ...options
1011
+ });
982
1012
  proc.stdout?.on("data", (data) => {
983
1013
  Logger.raw(chalk.dim(data.toString()));
984
1014
  });
@@ -997,7 +1027,7 @@ var Executor = class {
997
1027
  fork(modulePath, args = [], options = {}) {
998
1028
  const proc = fork(modulePath, args, {
999
1029
  cwd: this.cwdPath,
1000
- stdio: ["ignore", "inherit", "inherit", "ipc"],
1030
+ stdio: _Executor.verbose ? ["ignore", "inherit", "inherit", "ipc"] : ["ignore", "ignore", "ignore", "ipc"],
1001
1031
  ...options
1002
1032
  });
1003
1033
  proc.stdout?.on("data", (data) => {
@@ -1079,8 +1109,8 @@ var Executor = class {
1079
1109
  this.logger.verbose(msg);
1080
1110
  return this;
1081
1111
  }
1082
- spinning(msg, { prefix = `${this.emoji}${this.name} -`, indent = 0 } = {}) {
1083
- return new Spinner(msg, { prefix, indent }).start();
1112
+ spinning(msg, { prefix = `${this.emoji}${this.name}`, indent = 0, enableSpin = !_Executor.verbose } = {}) {
1113
+ return new Spinner(msg, { prefix, indent, enableSpin }).start();
1084
1114
  }
1085
1115
  getTsConfig(pathname = "tsconfig.json") {
1086
1116
  const tsconfig = this.readJson(pathname);
@@ -1562,6 +1592,9 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
1562
1592
  return new _AppExecutor({ workspace: executor, name });
1563
1593
  return new _AppExecutor({ workspace: executor.workspace, name });
1564
1594
  }
1595
+ getEnv() {
1596
+ return this.workspace.getBaseDevEnv().env;
1597
+ }
1565
1598
  async getConfig(command) {
1566
1599
  return await getAppConfig(this.cwdPath, {
1567
1600
  ...this.workspace.getBaseDevEnv(),
@@ -2186,6 +2219,7 @@ var runCommands = async (...commands) => {
2186
2219
  `${sysType} in this workspace ${sysType}s/<${sysType}Name>`
2187
2220
  );
2188
2221
  }
2222
+ programCommand = programCommand.option(`-v, --verbose [boolean]`, `verbose output`);
2189
2223
  programCommand.action(async (...args) => {
2190
2224
  const cmdArgs = args.slice(0, args.length - 2);
2191
2225
  const opt = args[args.length - 2];
@@ -2198,6 +2232,8 @@ var runCommands = async (...commands) => {
2198
2232
  commandArgs[argMeta.idx] = await getArgumentValue(argMeta, cmdArgs[argMeta.idx], workspace);
2199
2233
  if (commandArgs[argMeta.idx] instanceof AppExecutor)
2200
2234
  process.env.NEXT_PUBLIC_APP_NAME = commandArgs[argMeta.idx].name;
2235
+ if (opt.verbose)
2236
+ Executor.setVerbose(true);
2201
2237
  }
2202
2238
  const cmd = new command();
2203
2239
  try {
@@ -2220,7 +2256,6 @@ import { input as input2, select as select3 } from "@inquirer/prompts";
2220
2256
  import { AIMessage, HumanMessage } from "@langchain/core/messages";
2221
2257
  import { ChatOpenAI as ChatOpenAI2 } from "@langchain/openai";
2222
2258
  import chalk3 from "chalk";
2223
- import ora3 from "ora";
2224
2259
  var MAX_ASK_TRY = 300;
2225
2260
  var supportedLlmModels = ["deepseek-chat", "deepseek-reasoner"];
2226
2261
  var AiSession = class _AiSession {
@@ -2228,8 +2263,11 @@ var AiSession = class _AiSession {
2228
2263
  static async init({ temperature = 0.7, useExisting = true } = {}) {
2229
2264
  if (useExisting) {
2230
2265
  const llmConfig2 = this.getLlmConfig();
2231
- if (llmConfig2)
2232
- return this.#setChatModel(llmConfig2.model, llmConfig2.apiKey);
2266
+ if (llmConfig2) {
2267
+ this.#setChatModel(llmConfig2.model, llmConfig2.apiKey);
2268
+ Logger.rawLog(chalk3.dim(`\u{1F916}akan editor uses existing LLM config (${llmConfig2.model})`));
2269
+ return this;
2270
+ }
2233
2271
  }
2234
2272
  const llmConfig = await this.#requestLlmConfig();
2235
2273
  const { model, apiKey } = llmConfig;
@@ -2261,6 +2299,7 @@ var AiSession = class _AiSession {
2261
2299
  return { model, apiKey };
2262
2300
  }
2263
2301
  static async #validateApiKey(modelName, apiKey) {
2302
+ const spinner = new Spinner("Validating LLM API key...", { prefix: `\u{1F916}akan-editor` }).start();
2264
2303
  const chat = new ChatOpenAI2({
2265
2304
  modelName,
2266
2305
  temperature: 0,
@@ -2268,9 +2307,10 @@ var AiSession = class _AiSession {
2268
2307
  });
2269
2308
  try {
2270
2309
  await chat.invoke("Hi, and just say 'ok'");
2310
+ spinner.succeed("LLM API key is valid");
2271
2311
  return true;
2272
2312
  } catch (error) {
2273
- Logger.rawLog(
2313
+ spinner.fail(
2274
2314
  chalk3.red(
2275
2315
  `LLM API key is invalid. Please check your API key and try again. You can set it again by running "akan set-llm" or reset by running "akan reset-llm"`
2276
2316
  )
@@ -2291,14 +2331,16 @@ var AiSession = class _AiSession {
2291
2331
  await _AiSession.init();
2292
2332
  if (!_AiSession.#chat)
2293
2333
  throw new Error("Failed to initialize the AI session");
2294
- const loader = ora3(`${_AiSession.#chat.model} is thinking...`).start();
2334
+ const loader = new Spinner(`${_AiSession.#chat.model} is thinking...`, {
2335
+ prefix: `\u{1F916}akan-editor`
2336
+ }).start();
2295
2337
  try {
2296
2338
  const humanMessage = new HumanMessage(question);
2297
2339
  this.messageHistory.push(humanMessage);
2298
2340
  const stream = await _AiSession.#chat.stream(this.messageHistory);
2299
2341
  let fullResponse = "", tokenIdx = 0;
2300
2342
  for await (const chunk of stream) {
2301
- if (loader.isSpinning)
2343
+ if (loader.isSpinning())
2302
2344
  loader.succeed(`${_AiSession.#chat.model} responded`);
2303
2345
  const content = chunk.content;
2304
2346
  if (typeof content === "string") {
@@ -2518,38 +2560,49 @@ var LibraryRunner = class {
2518
2560
  // pkgs/@akanjs/cli/src/library/library.script.ts
2519
2561
  var LibraryScript = class {
2520
2562
  #runner = new LibraryRunner();
2521
- async scanLibrary(lib, verbose = false) {
2563
+ async syncLibrary(lib) {
2564
+ const syncSpinner = lib.spinning("Syncing library...");
2522
2565
  const akanConfig = await lib.getConfig();
2523
2566
  const scanResult = await lib.scan({ akanConfig });
2524
- if (verbose)
2525
- lib.logger.rawLog(JSON.stringify(scanResult, null, 2));
2567
+ syncSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) is synced`);
2526
2568
  return scanResult;
2527
2569
  }
2528
- async syncLibrary(lib) {
2529
- const akanConfig = await lib.getConfig();
2530
- return await lib.scan({ akanConfig });
2531
- }
2532
2570
  async createLibrary(libName, workspace) {
2571
+ const spinner = workspace.spinning(`Creating ${libName} library`);
2533
2572
  const lib = await this.#runner.createLibrary(libName, workspace);
2573
+ spinner.succeed(`${libName} library (libs/${libName}) is created`);
2534
2574
  await this.syncLibrary(lib);
2535
2575
  }
2536
2576
  async removeLibrary(lib) {
2577
+ const spinner = lib.spinning("Removing library...");
2537
2578
  await this.#runner.removeLibrary(lib);
2579
+ spinner.succeed(`Library ${lib.name} (libs/${lib.name}) is removed`);
2538
2580
  }
2539
2581
  async installLibrary(workspace, libName) {
2582
+ const installSpinner = workspace.spinning(`Installing ${libName} library`);
2540
2583
  const lib = await this.#runner.installLibrary(workspace, libName);
2541
- workspace.log(`${libName} library installed`);
2584
+ installSpinner.succeed(`${libName} library (libs/${libName}) is installed`);
2585
+ const mergeSpinner = workspace.spinning("Merging library dependencies...");
2542
2586
  await this.#runner.mergeLibraryDependencies(lib);
2587
+ mergeSpinner.succeed(`${libName} library (libs/${libName}) dependencies merged to root package.json`);
2543
2588
  }
2544
2589
  async pushLibrary(lib, branch) {
2590
+ const pushSpinner = lib.spinning("Pushing library...");
2545
2591
  await this.#runner.pushLibrary(lib, branch);
2592
+ pushSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) pushed to ${branch} branch`);
2546
2593
  }
2547
2594
  async pullLibrary(lib, branch) {
2595
+ const pullSpinner = lib.spinning("Pulling library...");
2548
2596
  await this.#runner.pullLibrary(lib, branch);
2597
+ pullSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) pulled from ${branch} branch`);
2598
+ const mergeSpinner = lib.spinning("Merging library dependencies...");
2549
2599
  await this.#runner.mergeLibraryDependencies(lib);
2600
+ mergeSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) dependencies merged to root package.json`);
2550
2601
  }
2551
2602
  async testLibrary(lib) {
2603
+ const spinner = lib.spinning("Testing library...");
2552
2604
  await this.#runner.testLibrary(lib);
2605
+ spinner.succeed(`Library ${lib.name} (libs/${lib.name}) test is successful`);
2553
2606
  }
2554
2607
  };
2555
2608
 
@@ -2566,7 +2619,7 @@ import fs11 from "fs";
2566
2619
  import fsPromise2 from "fs/promises";
2567
2620
  import yaml2 from "js-yaml";
2568
2621
  import openBrowser from "open";
2569
- import ora4 from "ora";
2622
+ import ora3 from "ora";
2570
2623
  import path5 from "path";
2571
2624
  import * as vite from "vite";
2572
2625
  import commonjs from "vite-plugin-commonjs";
@@ -4474,7 +4527,6 @@ var ApplicationRunner = class {
4474
4527
  }
4475
4528
  async removeApplication(app) {
4476
4529
  await app.workspace.exec(`rm -rf apps/${app.name}`);
4477
- app.log(`Application ${app.name} removed`);
4478
4530
  }
4479
4531
  async getConfig(app) {
4480
4532
  return await getAppConfig(app.cwdPath, {
@@ -4537,7 +4589,7 @@ var ApplicationRunner = class {
4537
4589
  app.dist.writeJson("backend/package.json", appPackageJson);
4538
4590
  app.dist.writeFile(path5.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
4539
4591
  }
4540
- async startBackend(app, { open: open2 = false } = {}) {
4592
+ async startBackend(app, { open: open2 = false, onStart } = {}) {
4541
4593
  const { env } = await this.#prepareCommand(app, "start", "backend");
4542
4594
  const ctx = await esbuild2.context({
4543
4595
  write: true,
@@ -4551,14 +4603,15 @@ var ApplicationRunner = class {
4551
4603
  });
4552
4604
  await ctx.watch();
4553
4605
  await sleep(100);
4606
+ onStart?.();
4554
4607
  if (open2)
4555
4608
  setTimeout(() => openBrowser("http://localhost:8080/backend/graphql"), 3e3);
4556
- await app.dist.spawn("node", ["--watch", "backend/main.js"], { env });
4609
+ await app.dist.spawn("node", ["--watch", "backend/main.js"], { env, stdio: "inherit" });
4557
4610
  }
4558
4611
  async buildFrontend(app) {
4559
4612
  const { env } = await this.#prepareCommand(app, "build", "frontend");
4560
4613
  const akanConfig = await app.getConfig("build");
4561
- await app.spawn("npx", ["next", "build", "--no-lint"], { env, stdio: "ignore" });
4614
+ await app.spawn("npx", ["next", "build", "--no-lint"], { env });
4562
4615
  const buildResult = await esbuild2.build({
4563
4616
  entryPoints: [`${app.cwdPath}/next.config.ts`],
4564
4617
  outdir: `${app.dist.cwdPath}/frontend`,
@@ -4588,10 +4641,11 @@ var ApplicationRunner = class {
4588
4641
  ]);
4589
4642
  app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.dockerfile);
4590
4643
  }
4591
- async startFrontend(app, { open: open2 = false, turbo = true } = {}) {
4644
+ async startFrontend(app, { open: open2 = false, turbo = true, onStart } = {}) {
4592
4645
  const { env } = await this.#prepareCommand(app, "start", "frontend");
4593
4646
  if (open2)
4594
4647
  setTimeout(() => openBrowser("http://localhost:4200"), 3e3);
4648
+ onStart?.();
4595
4649
  await app.spawn("npx", ["next", "dev", "-p", "4200", ...turbo ? ["--turbo"] : []], { env });
4596
4650
  }
4597
4651
  async #getViteConfig(app, command) {
@@ -4674,10 +4728,11 @@ var ApplicationRunner = class {
4674
4728
  const config = await this.#getViteConfig(app, "build");
4675
4729
  await vite.build(config);
4676
4730
  }
4677
- async startCsr(app, { open: open2 = false } = {}) {
4731
+ async startCsr(app, { open: open2 = false, onStart } = {}) {
4678
4732
  const config = await this.#getViteConfig(app, "start");
4679
4733
  const server = await vite.createServer(config);
4680
4734
  await server.listen(4201);
4735
+ onStart?.();
4681
4736
  app.log(`CSR server is running on http://localhost:4201`);
4682
4737
  if (open2)
4683
4738
  setTimeout(() => openBrowser("http://localhost:4201"), 3e3);
@@ -4744,13 +4799,10 @@ var ApplicationRunner = class {
4744
4799
  dict: { repoName: workspace.repoName },
4745
4800
  overwrite: false
4746
4801
  });
4747
- await workspace.spawn(`docker`, ["compose", "up", "-d"], {
4748
- cwd: `${workspace.workspaceRoot}/local`,
4749
- stdio: "ignore"
4750
- });
4802
+ await workspace.spawn(`docker`, ["compose", "up", "-d"], { cwd: `${workspace.workspaceRoot}/local` });
4751
4803
  }
4752
4804
  async dbdown(workspace) {
4753
- await workspace.spawn(`docker`, ["compose", "down"], { cwd: `${workspace.workspaceRoot}/local`, stdio: "ignore" });
4805
+ await workspace.spawn(`docker`, ["compose", "down"], { cwd: `${workspace.workspaceRoot}/local` });
4754
4806
  }
4755
4807
  async configureApp(app) {
4756
4808
  const capacitorApp = new CapacitorApp(app);
@@ -4910,7 +4962,7 @@ var ApplicationRunner = class {
4910
4962
  const chatModel = new ChatOpenAI3({ modelName: "gpt-4o", openAIApiKey });
4911
4963
  const projectName = await input3({ message: "please enter project name." });
4912
4964
  const projectDesc = await input3({ message: "please enter project description. (40 ~ 60 characters)" });
4913
- const spinner = ora4("Gerating project files...");
4965
+ const spinner = ora3("Gerating project files...");
4914
4966
  const mainPrompt = PromptTemplate2.fromTemplate(requestApplication());
4915
4967
  const chain = RunnableSequence2.from([mainPrompt, chatModel, new StringOutputParser()]);
4916
4968
  const resultOne = await chain.invoke({ projectName, projectDesc });
@@ -4949,20 +5001,22 @@ var ApplicationScript = class {
4949
5001
  #runner = new ApplicationRunner();
4950
5002
  libraryScript = new LibraryScript();
4951
5003
  async createApplication(appName, workspace, { start = false } = {}) {
5004
+ const spinner = workspace.spinning("Creating application...");
4952
5005
  const app = await this.#runner.createApplication(appName, workspace);
5006
+ spinner.succeed(`Application created in apps/${app.name}`);
4953
5007
  await this.syncApplication(app);
4954
5008
  if (start)
4955
5009
  await this.start(app, { open: true });
4956
5010
  }
4957
5011
  async removeApplication(app) {
5012
+ const spinner = app.spinning("Removing application...");
4958
5013
  await this.#runner.removeApplication(app);
5014
+ spinner.succeed(`Application ${app.name} (apps/${app.name}) removed`);
4959
5015
  }
4960
- async syncApplication(app, verbose = false) {
5016
+ async syncApplication(app) {
4961
5017
  const spinner = app.spinning("Scanning application...");
4962
5018
  const akanConfig = await this.#runner.getConfig(app);
4963
5019
  const scanResult = await this.#runner.scanSync(app, akanConfig);
4964
- if (verbose)
4965
- app.logger.rawLog(JSON.stringify(scanResult, null, 2));
4966
5020
  spinner.succeed("Application scanned");
4967
5021
  return scanResult;
4968
5022
  }
@@ -4981,24 +5035,39 @@ var ApplicationScript = class {
4981
5035
  await this.syncApplication(app);
4982
5036
  const spinner = app.spinning("Building backend...");
4983
5037
  await this.#runner.buildBackend(app);
4984
- spinner.succeed(`Successfully built in dist/apps/${app.name}/backend`);
5038
+ spinner.succeed(`Backend built in dist/apps/${app.name}/backend`);
4985
5039
  }
4986
- async startBackend(app, { open: open2 = false, sync = true } = {}) {
5040
+ async startBackend(app, { open: open2 = false, dbup = true, sync = true } = {}) {
5041
+ if (app.getEnv() === "local" && dbup)
5042
+ await this.dbup(app.workspace);
4987
5043
  if (sync)
4988
5044
  await this.syncApplication(app);
4989
- await this.#runner.startBackend(app, { open: open2 });
5045
+ const spinner = app.spinning("Preparing backend...");
5046
+ await this.#runner.startBackend(app, {
5047
+ open: open2,
5048
+ onStart: () => {
5049
+ spinner.succeed(`Backend prepared, ready to start`);
5050
+ }
5051
+ });
4990
5052
  }
4991
5053
  async buildFrontend(app, { sync = true } = {}) {
4992
5054
  if (sync)
4993
5055
  await this.syncApplication(app);
4994
5056
  const spinner = app.spinning("Building frontend...");
4995
5057
  await this.#runner.buildFrontend(app);
4996
- spinner.succeed(`Successfully built in dist/apps/${app.name}/frontend`);
5058
+ spinner.succeed(`Frontend built in dist/apps/${app.name}/frontend`);
4997
5059
  }
4998
5060
  async startFrontend(app, { open: open2 = false, turbo = false, sync = true } = {}) {
4999
5061
  if (sync)
5000
5062
  await this.syncApplication(app);
5001
- await this.#runner.startFrontend(app, { open: open2, turbo });
5063
+ const spinner = app.spinning("Preparing frontend...");
5064
+ await this.#runner.startFrontend(app, {
5065
+ open: open2,
5066
+ turbo,
5067
+ onStart: () => {
5068
+ spinner.succeed(`Frontend prepared, ready to start`);
5069
+ }
5070
+ });
5002
5071
  }
5003
5072
  async buildCsr(app, { sync = true } = {}) {
5004
5073
  if (sync)
@@ -5010,7 +5079,13 @@ var ApplicationScript = class {
5010
5079
  async startCsr(app, { open: open2 = false, sync = true } = {}) {
5011
5080
  if (sync)
5012
5081
  await this.syncApplication(app);
5013
- await this.#runner.startCsr(app, { open: open2 });
5082
+ const spinner = app.spinning("Preparing CSR...");
5083
+ await this.#runner.startCsr(app, {
5084
+ open: open2,
5085
+ onStart: () => {
5086
+ spinner.succeed(`CSR prepared, ready to start`);
5087
+ }
5088
+ });
5014
5089
  }
5015
5090
  async buildIos(app, { sync = true } = {}) {
5016
5091
  if (sync)
@@ -5049,13 +5124,17 @@ var ApplicationScript = class {
5049
5124
  await this.#runner.releaseAndroid(app);
5050
5125
  }
5051
5126
  async dumpDatabase(app, environment) {
5127
+ await this.dbdown(app.workspace);
5128
+ const spinner = app.spinning("Dumping database...");
5052
5129
  await this.#runner.dumpDatabase(app, environment);
5130
+ spinner.succeed(`Database dumped to dump/${app.name}-${environment}`);
5053
5131
  }
5054
5132
  async restoreDatabase(app, source, target) {
5133
+ const spinner = app.spinning("Restoring database...");
5055
5134
  await this.#runner.restoreDatabase(app, source, target);
5135
+ spinner.succeed(`Database restored from dump/${app.name}-${source} to ${app.name}-${target}`);
5056
5136
  }
5057
5137
  async pullDatabase(app, environment, dump) {
5058
- await this.dbdown(app.workspace);
5059
5138
  const hasDump = app.workspace.exists(`dump/${app.name}-${environment}`);
5060
5139
  if (dump || !hasDump)
5061
5140
  await this.dumpDatabase(app, environment);
@@ -5071,14 +5150,12 @@ var ApplicationScript = class {
5071
5150
  async dbup(workspace) {
5072
5151
  const spinner = workspace.spinning("Starting local database...");
5073
5152
  await this.#runner.dbup(workspace);
5074
- spinner.succeed(
5075
- "Local database(/local/docker-compose.yaml) is up, you can start your application and connect to the database"
5076
- );
5153
+ spinner.succeed("Local database (/local/docker-compose.yaml) is up");
5077
5154
  }
5078
5155
  async dbdown(workspace) {
5079
5156
  const spinner = workspace.spinning("Stopping local database...");
5080
5157
  await this.#runner.dbdown(workspace);
5081
- spinner.succeed("Local database(/local/docker-compose.yaml) is down");
5158
+ spinner.succeed("Local database (/local/docker-compose.yaml) is down");
5082
5159
  }
5083
5160
  async testSys(sys2) {
5084
5161
  if (sys2.type === "app")
@@ -5087,7 +5164,9 @@ var ApplicationScript = class {
5087
5164
  await this.libraryScript.testLibrary(sys2);
5088
5165
  }
5089
5166
  async testApplication(app) {
5167
+ const spinner = app.spinning("Testing application...");
5090
5168
  await this.#runner.testApplication(app);
5169
+ spinner.succeed(`Application ${app.name} (apps/${app.name}) test is successful`);
5091
5170
  }
5092
5171
  };
5093
5172
 
@@ -5100,8 +5179,8 @@ var ApplicationCommand = class {
5100
5179
  async removeApplication(app) {
5101
5180
  await this.applicationScript.removeApplication(app);
5102
5181
  }
5103
- async syncApplication(app, verbose) {
5104
- await this.applicationScript.syncApplication(app, verbose);
5182
+ async syncApplication(app) {
5183
+ await this.applicationScript.syncApplication(app);
5105
5184
  }
5106
5185
  async build(app) {
5107
5186
  await this.applicationScript.build(app);
@@ -5182,8 +5261,7 @@ __decorateClass([
5182
5261
  ], ApplicationCommand.prototype, "removeApplication", 1);
5183
5262
  __decorateClass([
5184
5263
  Target.Public(),
5185
- __decorateParam(0, App()),
5186
- __decorateParam(1, Option("verbose", { type: "boolean", desc: "verbose", default: false }))
5264
+ __decorateParam(0, App())
5187
5265
  ], ApplicationCommand.prototype, "syncApplication", 1);
5188
5266
  __decorateClass([
5189
5267
  Target.Public({ short: true }),
@@ -5352,17 +5430,25 @@ var PackageScript = class {
5352
5430
  await this.#runner.version(workspace);
5353
5431
  }
5354
5432
  async createPackage(workspace, pkgName) {
5433
+ const spinner = workspace.spinning(`Creating package in pkgs/${pkgName}...`);
5355
5434
  await this.#runner.createPackage(workspace, pkgName);
5435
+ spinner.succeed(`Package in pkgs/${pkgName} is created`);
5356
5436
  }
5357
5437
  async removePackage(pkg) {
5438
+ const spinner = pkg.spinning(`Removing package in pkgs/${pkg.name}...`);
5358
5439
  await this.#runner.removePackage(pkg);
5440
+ spinner.succeed("Package removed");
5359
5441
  }
5360
- async scanPackage(pkg) {
5442
+ async syncPackage(pkg) {
5443
+ const spinner = pkg.spinning("Scanning package...");
5361
5444
  const scanResult = await this.#runner.scanSync(pkg);
5362
- pkg.logger.rawLog(JSON.stringify(scanResult, null, 2));
5445
+ spinner.succeed("Package scanned");
5446
+ return scanResult;
5363
5447
  }
5364
5448
  async buildPackage(pkg) {
5449
+ const spinner = pkg.spinning("Building package...");
5365
5450
  await this.#runner.buildPackage(pkg);
5451
+ spinner.succeed("Package built");
5366
5452
  }
5367
5453
  };
5368
5454
 
@@ -5437,11 +5523,10 @@ ${chalk4.green("\u27A4")} Authentication Required`));
5437
5523
  }
5438
5524
  async setLlm() {
5439
5525
  await AiSession.init({ useExisting: true });
5440
- Logger.rawLog(chalk4.green("LLM model set successfully"));
5441
5526
  }
5442
5527
  resetLlm() {
5443
5528
  AiSession.setLlmConfig(null);
5444
- Logger.rawLog(chalk4.green("LLM model reset successfully"));
5529
+ Logger.rawLog(chalk4.green("\u2611\uFE0F LLM model config is cleared. Please run `akan set-llm` to set a new LLM model."));
5445
5530
  }
5446
5531
  async getAkanPkgs(workspace) {
5447
5532
  const pkgs = await workspace.getPkgs();
@@ -5471,7 +5556,7 @@ ${chalk4.green("\u27A4")} Authentication Required`));
5471
5556
  message: "Are you sure you want to deploy the libraries?"
5472
5557
  });
5473
5558
  if (!isDeployConfirmed) {
5474
- Logger.info("Deployment cancelled");
5559
+ Logger.error("Deployment cancelled");
5475
5560
  return;
5476
5561
  }
5477
5562
  await Promise.all(
@@ -5501,7 +5586,6 @@ ${chalk4.green("\u27A4")} Authentication Required`));
5501
5586
  workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
5502
5587
  workspace.spawn("pnpm", ["install"])
5503
5588
  ]);
5504
- Logger.info(`Akan.js is updated to the latest version ${latestPublishedVersionOfBase}`);
5505
5589
  }
5506
5590
  };
5507
5591
 
@@ -5509,19 +5593,19 @@ ${chalk4.green("\u27A4")} Authentication Required`));
5509
5593
  var CloudScript = class {
5510
5594
  #runner = new CloudRunner();
5511
5595
  #packageScript = new PackageScript();
5512
- async login() {
5596
+ async login(workspace) {
5513
5597
  await this.#runner.login();
5514
5598
  }
5515
- logout() {
5599
+ logout(workspace) {
5516
5600
  this.#runner.logout();
5517
5601
  }
5518
- async setLlm() {
5602
+ async setLlm(workspace) {
5519
5603
  await this.#runner.setLlm();
5520
5604
  }
5521
- resetLlm() {
5605
+ resetLlm(workspace) {
5522
5606
  this.#runner.resetLlm();
5523
5607
  }
5524
- async ask(question) {
5608
+ async ask(question, workspace) {
5525
5609
  await AiSession.init();
5526
5610
  const session = new AiSession();
5527
5611
  await session.ask(question);
@@ -5534,27 +5618,31 @@ var CloudScript = class {
5534
5618
  await this.#runner.deployAkan(workspace, akanPkgs);
5535
5619
  }
5536
5620
  async update(workspace) {
5621
+ const spinner = workspace.spinning("Updating Akan.js packages and CLI...");
5537
5622
  await this.#runner.update(workspace);
5623
+ spinner.succeed("Akan.js packages and CLI updated, global version is below");
5624
+ Logger.raw("> Akan version: ");
5625
+ await workspace.spawn("akan", ["--version"], { stdio: "inherit" });
5538
5626
  }
5539
5627
  };
5540
5628
 
5541
5629
  // pkgs/@akanjs/cli/src/cloud/cloud.command.ts
5542
5630
  var CloudCommand = class {
5543
5631
  cloudScript = new CloudScript();
5544
- async login() {
5545
- await this.cloudScript.login();
5632
+ async login(workspace) {
5633
+ await this.cloudScript.login(workspace);
5546
5634
  }
5547
- logout() {
5548
- this.cloudScript.logout();
5635
+ logout(workspace) {
5636
+ this.cloudScript.logout(workspace);
5549
5637
  }
5550
- async setLlm() {
5551
- await this.cloudScript.setLlm();
5638
+ async setLlm(workspace) {
5639
+ await this.cloudScript.setLlm(workspace);
5552
5640
  }
5553
- resetLlm() {
5554
- this.cloudScript.resetLlm();
5641
+ resetLlm(workspace) {
5642
+ this.cloudScript.resetLlm(workspace);
5555
5643
  }
5556
- async ask(question) {
5557
- await this.cloudScript.ask(question);
5644
+ async ask(question, workspace) {
5645
+ await this.cloudScript.ask(question, workspace);
5558
5646
  }
5559
5647
  async deployAkan(workspace) {
5560
5648
  await this.cloudScript.deployAkan(workspace);
@@ -5564,20 +5652,25 @@ var CloudCommand = class {
5564
5652
  }
5565
5653
  };
5566
5654
  __decorateClass([
5567
- Target.Public()
5655
+ Target.Public(),
5656
+ __decorateParam(0, Workspace())
5568
5657
  ], CloudCommand.prototype, "login", 1);
5569
5658
  __decorateClass([
5570
- Target.Public()
5659
+ Target.Public(),
5660
+ __decorateParam(0, Workspace())
5571
5661
  ], CloudCommand.prototype, "logout", 1);
5572
5662
  __decorateClass([
5573
- Target.Public()
5663
+ Target.Public(),
5664
+ __decorateParam(0, Workspace())
5574
5665
  ], CloudCommand.prototype, "setLlm", 1);
5575
5666
  __decorateClass([
5576
- Target.Public()
5667
+ Target.Public(),
5668
+ __decorateParam(0, Workspace())
5577
5669
  ], CloudCommand.prototype, "resetLlm", 1);
5578
5670
  __decorateClass([
5579
5671
  Target.Public(),
5580
- __decorateParam(0, Option("question", { ask: "question to ask" }))
5672
+ __decorateParam(0, Option("question", { ask: "question to ask" })),
5673
+ __decorateParam(1, Workspace())
5581
5674
  ], CloudCommand.prototype, "ask", 1);
5582
5675
  __decorateClass([
5583
5676
  Target.Public({ devOnly: true }),
@@ -5600,10 +5693,8 @@ var LibraryCommand = class {
5600
5693
  async removeLibrary(lib) {
5601
5694
  await this.libraryScript.removeLibrary(lib);
5602
5695
  }
5603
- async scanLibrary(lib) {
5604
- await this.libraryScript.scanLibrary(lib, true);
5605
- }
5606
- async buildLibrary(lib) {
5696
+ async syncLibrary(lib) {
5697
+ await this.libraryScript.syncLibrary(lib);
5607
5698
  }
5608
5699
  async installLibrary(name, workspace) {
5609
5700
  await this.libraryScript.installLibrary(workspace, name);
@@ -5627,11 +5718,7 @@ __decorateClass([
5627
5718
  __decorateClass([
5628
5719
  Target.Public(),
5629
5720
  __decorateParam(0, Lib())
5630
- ], LibraryCommand.prototype, "scanLibrary", 1);
5631
- __decorateClass([
5632
- Target.Public(),
5633
- __decorateParam(0, Lib())
5634
- ], LibraryCommand.prototype, "buildLibrary", 1);
5721
+ ], LibraryCommand.prototype, "syncLibrary", 1);
5635
5722
  __decorateClass([
5636
5723
  Target.Public(),
5637
5724
  __decorateParam(0, Option("name", { desc: "name of library" })),
@@ -6025,8 +6112,8 @@ var PackageCommand = class {
6025
6112
  async removePackage(pkg) {
6026
6113
  await this.packageScript.removePackage(pkg);
6027
6114
  }
6028
- async scanPackage(pkg) {
6029
- await this.packageScript.scanPackage(pkg);
6115
+ async syncPackage(pkg) {
6116
+ await this.packageScript.syncPackage(pkg);
6030
6117
  }
6031
6118
  async buildPackage(pkg) {
6032
6119
  await this.packageScript.buildPackage(pkg);
@@ -6048,7 +6135,7 @@ __decorateClass([
6048
6135
  __decorateClass([
6049
6136
  Target.Public(),
6050
6137
  __decorateParam(0, Pkg())
6051
- ], PackageCommand.prototype, "scanPackage", 1);
6138
+ ], PackageCommand.prototype, "syncPackage", 1);
6052
6139
  __decorateClass([
6053
6140
  Target.Public(),
6054
6141
  __decorateParam(0, Pkg())
@@ -6096,6 +6183,7 @@ var WorkspaceRunner = class {
6096
6183
  const cwdPath = process.cwd();
6097
6184
  const workspaceRoot = path6.join(cwdPath, dirname, repoName);
6098
6185
  const workspace = new WorkspaceExecutor({ workspaceRoot, repoName });
6186
+ const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname}/${repoName}...`);
6099
6187
  await workspace.applyTemplate({
6100
6188
  basePath: ".",
6101
6189
  template: "workspaceRoot",
@@ -6107,6 +6195,7 @@ var WorkspaceRunner = class {
6107
6195
  serveDomain: "localhost"
6108
6196
  }
6109
6197
  });
6198
+ templateSpinner.succeed(`Workspace files created in ${dirname}/${repoName}`);
6110
6199
  const rootPackageJson = workspace.readJson("package.json");
6111
6200
  const dependencies = [
6112
6201
  "@akanjs/base",
@@ -6139,10 +6228,12 @@ var WorkspaceRunner = class {
6139
6228
  }
6140
6229
  };
6141
6230
  workspace.writeFile("package.json", packageJson);
6142
- workspace.log("Installing dependencies...");
6231
+ const installSpinner = workspace.spinning("Installing dependencies with pnpm...");
6143
6232
  await workspace.spawn("pnpm", ["install", "--reporter=silent"]);
6144
- workspace.log("Initializing git repository and commit...");
6233
+ installSpinner.succeed("Dependencies installed with pnpm");
6234
+ const gitSpinner = workspace.spinning("Initializing git repository and commit...");
6145
6235
  await workspace.commit("Initial commit", { init: true });
6236
+ gitSpinner.succeed("Git repository initialized and committed");
6146
6237
  return workspace;
6147
6238
  }
6148
6239
  async generateMongo(workspace) {
@@ -6198,19 +6289,30 @@ var WorkspaceScript = class {
6198
6289
  await this.libraryScript.installLibrary(workspace, "util");
6199
6290
  await this.libraryScript.installLibrary(workspace, "shared");
6200
6291
  await this.applicationScript.createApplication(appName, workspace);
6201
- workspace.log(`Workspace created in ${workspace.workspaceRoot}`);
6202
- Logger.rawLog(`Run \`cd ${repoName} && akan start ${appName}\` to start the development server.`);
6292
+ Logger.rawLog(`
6293
+ \u{1F389} Welcome aboard! Workspace created in ${dirname}/${repoName}`);
6294
+ Logger.rawLog(`\u{1F680} Run \`cd ${repoName} && akan start ${appName}\` to start the development server.`);
6295
+ Logger.rawLog(`
6296
+ \u{1F44B} Happy coding!`);
6203
6297
  }
6204
6298
  async generateMongo(workspace) {
6299
+ const spinner = workspace.spinning("Generating Mongo connections...");
6205
6300
  await this.#runner.generateMongo(workspace);
6206
- workspace.log(`Mongo connections generated in infra/master/mongo-connections.json`);
6301
+ spinner.succeed(`Mongo connections generated in infra/master/mongo-connections.json`);
6207
6302
  }
6208
6303
  async lint(exec2, workspace, { fix = true } = {}) {
6209
6304
  if (exec2 instanceof AppExecutor)
6210
6305
  await this.applicationScript.syncApplication(exec2);
6211
6306
  else if (exec2 instanceof LibExecutor)
6212
6307
  await this.libraryScript.syncLibrary(exec2);
6213
- await this.#runner.lint(exec2, workspace, { fix });
6308
+ const spinner = workspace.spinning(`Linting${fix ? " with fix" : ""}...`);
6309
+ try {
6310
+ await this.#runner.lint(exec2, workspace, { fix });
6311
+ spinner.succeed("Lint completed with no errors");
6312
+ } catch (error) {
6313
+ spinner.fail("Lint failed with errors");
6314
+ throw error;
6315
+ }
6214
6316
  }
6215
6317
  async lintAll(workspace, { fix = true } = {}) {
6216
6318
  const [appNames, libNames, pkgNames] = await workspace.getExecs();