@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/cjs/index.js CHANGED
@@ -916,28 +916,50 @@ var TypeScriptDependencyScanner = class {
916
916
 
917
917
  // pkgs/@akanjs/devkit/src/spinner.ts
918
918
  var import_ora2 = __toESM(require("ora"));
919
- var Spinner = class {
919
+ var Spinner = class _Spinner {
920
+ static padding = 12;
920
921
  spinner;
921
922
  stopWatch;
922
923
  startAt;
924
+ prefix;
923
925
  message;
924
- constructor(message, { prefix = "", indent = 0 } = {}) {
926
+ enableSpin;
927
+ constructor(message, { prefix = "", indent = 0, enableSpin = true } = {}) {
928
+ _Spinner.padding = Math.max(_Spinner.padding, prefix.length);
929
+ this.prefix = prefix;
925
930
  this.message = message;
926
931
  this.spinner = (0, import_ora2.default)(message);
927
- this.spinner.prefixText = prefix;
932
+ this.spinner.prefixText = prefix.padStart(_Spinner.padding, " ");
928
933
  this.spinner.indent = indent;
934
+ this.enableSpin = enableSpin;
929
935
  }
930
936
  start() {
931
937
  this.startAt = /* @__PURE__ */ new Date();
932
- const spinner = this.spinner.start();
933
- this.stopWatch = setInterval(() => {
934
- spinner.text = `${this.message} (${this.#getElapsedTimeStr()})`;
935
- }, 1e3);
938
+ if (this.enableSpin) {
939
+ this.spinner.start();
940
+ this.stopWatch = setInterval(() => {
941
+ this.spinner.prefixText = this.prefix.padStart(_Spinner.padding, " ");
942
+ this.spinner.text = `${this.message} (${this.#getElapsedTimeStr()})`;
943
+ }, 1e3);
944
+ } else
945
+ this.spinner.info();
936
946
  return this;
937
947
  }
938
948
  succeed(message) {
939
- clearInterval(this.stopWatch);
940
949
  this.spinner.succeed(`${message} (${this.#getElapsedTimeStr()})`);
950
+ this.#reset();
951
+ }
952
+ fail(message) {
953
+ this.spinner.fail(`${message} (${this.#getElapsedTimeStr()})`);
954
+ this.#reset();
955
+ }
956
+ isSpinning() {
957
+ return this.spinner.isSpinning;
958
+ }
959
+ #reset() {
960
+ if (this.stopWatch)
961
+ clearInterval(this.stopWatch);
962
+ this.stopWatch = null;
941
963
  }
942
964
  #getElapsedTimeStr() {
943
965
  const ms = (/* @__PURE__ */ new Date()).getTime() - this.startAt.getTime();
@@ -961,7 +983,11 @@ var execEmoji = {
961
983
  default: "\u2708\uFE0F"
962
984
  // for sys executor
963
985
  };
964
- var Executor = class {
986
+ var Executor = class _Executor {
987
+ static verbose = false;
988
+ static setVerbose(verbose) {
989
+ _Executor.verbose = verbose;
990
+ }
965
991
  name;
966
992
  logger;
967
993
  cwdPath;
@@ -991,7 +1017,11 @@ var Executor = class {
991
1017
  });
992
1018
  }
993
1019
  spawn(command, args = [], options = {}) {
994
- const proc = (0, import_child_process.spawn)(command, args, { cwd: this.cwdPath, stdio: "inherit", ...options });
1020
+ const proc = (0, import_child_process.spawn)(command, args, {
1021
+ cwd: this.cwdPath,
1022
+ stdio: _Executor.verbose ? "inherit" : "ignore",
1023
+ ...options
1024
+ });
995
1025
  proc.stdout?.on("data", (data) => {
996
1026
  Logger.raw(import_chalk.default.dim(data.toString()));
997
1027
  });
@@ -1010,7 +1040,7 @@ var Executor = class {
1010
1040
  fork(modulePath, args = [], options = {}) {
1011
1041
  const proc = (0, import_child_process.fork)(modulePath, args, {
1012
1042
  cwd: this.cwdPath,
1013
- stdio: ["ignore", "inherit", "inherit", "ipc"],
1043
+ stdio: _Executor.verbose ? ["ignore", "inherit", "inherit", "ipc"] : ["ignore", "ignore", "ignore", "ipc"],
1014
1044
  ...options
1015
1045
  });
1016
1046
  proc.stdout?.on("data", (data) => {
@@ -1092,8 +1122,8 @@ var Executor = class {
1092
1122
  this.logger.verbose(msg);
1093
1123
  return this;
1094
1124
  }
1095
- spinning(msg, { prefix = `${this.emoji}${this.name} -`, indent = 0 } = {}) {
1096
- return new Spinner(msg, { prefix, indent }).start();
1125
+ spinning(msg, { prefix = `${this.emoji}${this.name}`, indent = 0, enableSpin = !_Executor.verbose } = {}) {
1126
+ return new Spinner(msg, { prefix, indent, enableSpin }).start();
1097
1127
  }
1098
1128
  getTsConfig(pathname = "tsconfig.json") {
1099
1129
  const tsconfig = this.readJson(pathname);
@@ -1575,6 +1605,9 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
1575
1605
  return new _AppExecutor({ workspace: executor, name });
1576
1606
  return new _AppExecutor({ workspace: executor.workspace, name });
1577
1607
  }
1608
+ getEnv() {
1609
+ return this.workspace.getBaseDevEnv().env;
1610
+ }
1578
1611
  async getConfig(command) {
1579
1612
  return await getAppConfig(this.cwdPath, {
1580
1613
  ...this.workspace.getBaseDevEnv(),
@@ -2199,6 +2232,7 @@ var runCommands = async (...commands) => {
2199
2232
  `${sysType} in this workspace ${sysType}s/<${sysType}Name>`
2200
2233
  );
2201
2234
  }
2235
+ programCommand = programCommand.option(`-v, --verbose [boolean]`, `verbose output`);
2202
2236
  programCommand.action(async (...args) => {
2203
2237
  const cmdArgs = args.slice(0, args.length - 2);
2204
2238
  const opt = args[args.length - 2];
@@ -2211,6 +2245,8 @@ var runCommands = async (...commands) => {
2211
2245
  commandArgs[argMeta.idx] = await getArgumentValue(argMeta, cmdArgs[argMeta.idx], workspace);
2212
2246
  if (commandArgs[argMeta.idx] instanceof AppExecutor)
2213
2247
  process.env.NEXT_PUBLIC_APP_NAME = commandArgs[argMeta.idx].name;
2248
+ if (opt.verbose)
2249
+ Executor.setVerbose(true);
2214
2250
  }
2215
2251
  const cmd = new command();
2216
2252
  try {
@@ -2233,7 +2269,6 @@ var import_prompts4 = require("@inquirer/prompts");
2233
2269
  var import_messages = require("@langchain/core/messages");
2234
2270
  var import_openai2 = require("@langchain/openai");
2235
2271
  var import_chalk3 = __toESM(require("chalk"));
2236
- var import_ora3 = __toESM(require("ora"));
2237
2272
  var MAX_ASK_TRY = 300;
2238
2273
  var supportedLlmModels = ["deepseek-chat", "deepseek-reasoner"];
2239
2274
  var AiSession = class _AiSession {
@@ -2241,8 +2276,11 @@ var AiSession = class _AiSession {
2241
2276
  static async init({ temperature = 0.7, useExisting = true } = {}) {
2242
2277
  if (useExisting) {
2243
2278
  const llmConfig2 = this.getLlmConfig();
2244
- if (llmConfig2)
2245
- return this.#setChatModel(llmConfig2.model, llmConfig2.apiKey);
2279
+ if (llmConfig2) {
2280
+ this.#setChatModel(llmConfig2.model, llmConfig2.apiKey);
2281
+ Logger.rawLog(import_chalk3.default.dim(`\u{1F916}akan editor uses existing LLM config (${llmConfig2.model})`));
2282
+ return this;
2283
+ }
2246
2284
  }
2247
2285
  const llmConfig = await this.#requestLlmConfig();
2248
2286
  const { model, apiKey } = llmConfig;
@@ -2274,6 +2312,7 @@ var AiSession = class _AiSession {
2274
2312
  return { model, apiKey };
2275
2313
  }
2276
2314
  static async #validateApiKey(modelName, apiKey) {
2315
+ const spinner = new Spinner("Validating LLM API key...", { prefix: `\u{1F916}akan-editor` }).start();
2277
2316
  const chat = new import_openai2.ChatOpenAI({
2278
2317
  modelName,
2279
2318
  temperature: 0,
@@ -2281,9 +2320,10 @@ var AiSession = class _AiSession {
2281
2320
  });
2282
2321
  try {
2283
2322
  await chat.invoke("Hi, and just say 'ok'");
2323
+ spinner.succeed("LLM API key is valid");
2284
2324
  return true;
2285
2325
  } catch (error) {
2286
- Logger.rawLog(
2326
+ spinner.fail(
2287
2327
  import_chalk3.default.red(
2288
2328
  `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"`
2289
2329
  )
@@ -2304,14 +2344,16 @@ var AiSession = class _AiSession {
2304
2344
  await _AiSession.init();
2305
2345
  if (!_AiSession.#chat)
2306
2346
  throw new Error("Failed to initialize the AI session");
2307
- const loader = (0, import_ora3.default)(`${_AiSession.#chat.model} is thinking...`).start();
2347
+ const loader = new Spinner(`${_AiSession.#chat.model} is thinking...`, {
2348
+ prefix: `\u{1F916}akan-editor`
2349
+ }).start();
2308
2350
  try {
2309
2351
  const humanMessage = new import_messages.HumanMessage(question);
2310
2352
  this.messageHistory.push(humanMessage);
2311
2353
  const stream = await _AiSession.#chat.stream(this.messageHistory);
2312
2354
  let fullResponse = "", tokenIdx = 0;
2313
2355
  for await (const chunk of stream) {
2314
- if (loader.isSpinning)
2356
+ if (loader.isSpinning())
2315
2357
  loader.succeed(`${_AiSession.#chat.model} responded`);
2316
2358
  const content = chunk.content;
2317
2359
  if (typeof content === "string") {
@@ -2531,38 +2573,49 @@ var LibraryRunner = class {
2531
2573
  // pkgs/@akanjs/cli/src/library/library.script.ts
2532
2574
  var LibraryScript = class {
2533
2575
  #runner = new LibraryRunner();
2534
- async scanLibrary(lib, verbose = false) {
2576
+ async syncLibrary(lib) {
2577
+ const syncSpinner = lib.spinning("Syncing library...");
2535
2578
  const akanConfig = await lib.getConfig();
2536
2579
  const scanResult = await lib.scan({ akanConfig });
2537
- if (verbose)
2538
- lib.logger.rawLog(JSON.stringify(scanResult, null, 2));
2580
+ syncSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) is synced`);
2539
2581
  return scanResult;
2540
2582
  }
2541
- async syncLibrary(lib) {
2542
- const akanConfig = await lib.getConfig();
2543
- return await lib.scan({ akanConfig });
2544
- }
2545
2583
  async createLibrary(libName, workspace) {
2584
+ const spinner = workspace.spinning(`Creating ${libName} library`);
2546
2585
  const lib = await this.#runner.createLibrary(libName, workspace);
2586
+ spinner.succeed(`${libName} library (libs/${libName}) is created`);
2547
2587
  await this.syncLibrary(lib);
2548
2588
  }
2549
2589
  async removeLibrary(lib) {
2590
+ const spinner = lib.spinning("Removing library...");
2550
2591
  await this.#runner.removeLibrary(lib);
2592
+ spinner.succeed(`Library ${lib.name} (libs/${lib.name}) is removed`);
2551
2593
  }
2552
2594
  async installLibrary(workspace, libName) {
2595
+ const installSpinner = workspace.spinning(`Installing ${libName} library`);
2553
2596
  const lib = await this.#runner.installLibrary(workspace, libName);
2554
- workspace.log(`${libName} library installed`);
2597
+ installSpinner.succeed(`${libName} library (libs/${libName}) is installed`);
2598
+ const mergeSpinner = workspace.spinning("Merging library dependencies...");
2555
2599
  await this.#runner.mergeLibraryDependencies(lib);
2600
+ mergeSpinner.succeed(`${libName} library (libs/${libName}) dependencies merged to root package.json`);
2556
2601
  }
2557
2602
  async pushLibrary(lib, branch) {
2603
+ const pushSpinner = lib.spinning("Pushing library...");
2558
2604
  await this.#runner.pushLibrary(lib, branch);
2605
+ pushSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) pushed to ${branch} branch`);
2559
2606
  }
2560
2607
  async pullLibrary(lib, branch) {
2608
+ const pullSpinner = lib.spinning("Pulling library...");
2561
2609
  await this.#runner.pullLibrary(lib, branch);
2610
+ pullSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) pulled from ${branch} branch`);
2611
+ const mergeSpinner = lib.spinning("Merging library dependencies...");
2562
2612
  await this.#runner.mergeLibraryDependencies(lib);
2613
+ mergeSpinner.succeed(`Library ${lib.name} (libs/${lib.name}) dependencies merged to root package.json`);
2563
2614
  }
2564
2615
  async testLibrary(lib) {
2616
+ const spinner = lib.spinning("Testing library...");
2565
2617
  await this.#runner.testLibrary(lib);
2618
+ spinner.succeed(`Library ${lib.name} (libs/${lib.name}) test is successful`);
2566
2619
  }
2567
2620
  };
2568
2621
 
@@ -2579,7 +2632,7 @@ var import_fs9 = __toESM(require("fs"));
2579
2632
  var import_promises2 = __toESM(require("fs/promises"));
2580
2633
  var import_js_yaml2 = __toESM(require("js-yaml"));
2581
2634
  var import_open = __toESM(require("open"));
2582
- var import_ora4 = __toESM(require("ora"));
2635
+ var import_ora3 = __toESM(require("ora"));
2583
2636
  var import_path4 = __toESM(require("path"));
2584
2637
  var vite = __toESM(require("vite"));
2585
2638
  var import_vite_plugin_commonjs = __toESM(require("vite-plugin-commonjs"));
@@ -4487,7 +4540,6 @@ var ApplicationRunner = class {
4487
4540
  }
4488
4541
  async removeApplication(app) {
4489
4542
  await app.workspace.exec(`rm -rf apps/${app.name}`);
4490
- app.log(`Application ${app.name} removed`);
4491
4543
  }
4492
4544
  async getConfig(app) {
4493
4545
  return await getAppConfig(app.cwdPath, {
@@ -4550,7 +4602,7 @@ var ApplicationRunner = class {
4550
4602
  app.dist.writeJson("backend/package.json", appPackageJson);
4551
4603
  app.dist.writeFile(import_path4.default.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
4552
4604
  }
4553
- async startBackend(app, { open: open2 = false } = {}) {
4605
+ async startBackend(app, { open: open2 = false, onStart } = {}) {
4554
4606
  const { env } = await this.#prepareCommand(app, "start", "backend");
4555
4607
  const ctx = await esbuild2.context({
4556
4608
  write: true,
@@ -4564,14 +4616,15 @@ var ApplicationRunner = class {
4564
4616
  });
4565
4617
  await ctx.watch();
4566
4618
  await sleep(100);
4619
+ onStart?.();
4567
4620
  if (open2)
4568
4621
  setTimeout(() => (0, import_open.default)("http://localhost:8080/backend/graphql"), 3e3);
4569
- await app.dist.spawn("node", ["--watch", "backend/main.js"], { env });
4622
+ await app.dist.spawn("node", ["--watch", "backend/main.js"], { env, stdio: "inherit" });
4570
4623
  }
4571
4624
  async buildFrontend(app) {
4572
4625
  const { env } = await this.#prepareCommand(app, "build", "frontend");
4573
4626
  const akanConfig = await app.getConfig("build");
4574
- await app.spawn("npx", ["next", "build", "--no-lint"], { env, stdio: "ignore" });
4627
+ await app.spawn("npx", ["next", "build", "--no-lint"], { env });
4575
4628
  const buildResult = await esbuild2.build({
4576
4629
  entryPoints: [`${app.cwdPath}/next.config.ts`],
4577
4630
  outdir: `${app.dist.cwdPath}/frontend`,
@@ -4601,10 +4654,11 @@ var ApplicationRunner = class {
4601
4654
  ]);
4602
4655
  app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.dockerfile);
4603
4656
  }
4604
- async startFrontend(app, { open: open2 = false, turbo = true } = {}) {
4657
+ async startFrontend(app, { open: open2 = false, turbo = true, onStart } = {}) {
4605
4658
  const { env } = await this.#prepareCommand(app, "start", "frontend");
4606
4659
  if (open2)
4607
4660
  setTimeout(() => (0, import_open.default)("http://localhost:4200"), 3e3);
4661
+ onStart?.();
4608
4662
  await app.spawn("npx", ["next", "dev", "-p", "4200", ...turbo ? ["--turbo"] : []], { env });
4609
4663
  }
4610
4664
  async #getViteConfig(app, command) {
@@ -4687,10 +4741,11 @@ var ApplicationRunner = class {
4687
4741
  const config = await this.#getViteConfig(app, "build");
4688
4742
  await vite.build(config);
4689
4743
  }
4690
- async startCsr(app, { open: open2 = false } = {}) {
4744
+ async startCsr(app, { open: open2 = false, onStart } = {}) {
4691
4745
  const config = await this.#getViteConfig(app, "start");
4692
4746
  const server = await vite.createServer(config);
4693
4747
  await server.listen(4201);
4748
+ onStart?.();
4694
4749
  app.log(`CSR server is running on http://localhost:4201`);
4695
4750
  if (open2)
4696
4751
  setTimeout(() => (0, import_open.default)("http://localhost:4201"), 3e3);
@@ -4757,13 +4812,10 @@ var ApplicationRunner = class {
4757
4812
  dict: { repoName: workspace.repoName },
4758
4813
  overwrite: false
4759
4814
  });
4760
- await workspace.spawn(`docker`, ["compose", "up", "-d"], {
4761
- cwd: `${workspace.workspaceRoot}/local`,
4762
- stdio: "ignore"
4763
- });
4815
+ await workspace.spawn(`docker`, ["compose", "up", "-d"], { cwd: `${workspace.workspaceRoot}/local` });
4764
4816
  }
4765
4817
  async dbdown(workspace) {
4766
- await workspace.spawn(`docker`, ["compose", "down"], { cwd: `${workspace.workspaceRoot}/local`, stdio: "ignore" });
4818
+ await workspace.spawn(`docker`, ["compose", "down"], { cwd: `${workspace.workspaceRoot}/local` });
4767
4819
  }
4768
4820
  async configureApp(app) {
4769
4821
  const capacitorApp = new CapacitorApp(app);
@@ -4923,7 +4975,7 @@ var ApplicationRunner = class {
4923
4975
  const chatModel = new import_openai3.ChatOpenAI({ modelName: "gpt-4o", openAIApiKey });
4924
4976
  const projectName = await (0, import_prompts5.input)({ message: "please enter project name." });
4925
4977
  const projectDesc = await (0, import_prompts5.input)({ message: "please enter project description. (40 ~ 60 characters)" });
4926
- const spinner = (0, import_ora4.default)("Gerating project files...");
4978
+ const spinner = (0, import_ora3.default)("Gerating project files...");
4927
4979
  const mainPrompt = import_prompts6.PromptTemplate.fromTemplate(requestApplication());
4928
4980
  const chain = import_runnables2.RunnableSequence.from([mainPrompt, chatModel, new import_output_parsers.StringOutputParser()]);
4929
4981
  const resultOne = await chain.invoke({ projectName, projectDesc });
@@ -4962,20 +5014,22 @@ var ApplicationScript = class {
4962
5014
  #runner = new ApplicationRunner();
4963
5015
  libraryScript = new LibraryScript();
4964
5016
  async createApplication(appName, workspace, { start = false } = {}) {
5017
+ const spinner = workspace.spinning("Creating application...");
4965
5018
  const app = await this.#runner.createApplication(appName, workspace);
5019
+ spinner.succeed(`Application created in apps/${app.name}`);
4966
5020
  await this.syncApplication(app);
4967
5021
  if (start)
4968
5022
  await this.start(app, { open: true });
4969
5023
  }
4970
5024
  async removeApplication(app) {
5025
+ const spinner = app.spinning("Removing application...");
4971
5026
  await this.#runner.removeApplication(app);
5027
+ spinner.succeed(`Application ${app.name} (apps/${app.name}) removed`);
4972
5028
  }
4973
- async syncApplication(app, verbose = false) {
5029
+ async syncApplication(app) {
4974
5030
  const spinner = app.spinning("Scanning application...");
4975
5031
  const akanConfig = await this.#runner.getConfig(app);
4976
5032
  const scanResult = await this.#runner.scanSync(app, akanConfig);
4977
- if (verbose)
4978
- app.logger.rawLog(JSON.stringify(scanResult, null, 2));
4979
5033
  spinner.succeed("Application scanned");
4980
5034
  return scanResult;
4981
5035
  }
@@ -4994,24 +5048,39 @@ var ApplicationScript = class {
4994
5048
  await this.syncApplication(app);
4995
5049
  const spinner = app.spinning("Building backend...");
4996
5050
  await this.#runner.buildBackend(app);
4997
- spinner.succeed(`Successfully built in dist/apps/${app.name}/backend`);
5051
+ spinner.succeed(`Backend built in dist/apps/${app.name}/backend`);
4998
5052
  }
4999
- async startBackend(app, { open: open2 = false, sync = true } = {}) {
5053
+ async startBackend(app, { open: open2 = false, dbup = true, sync = true } = {}) {
5054
+ if (app.getEnv() === "local" && dbup)
5055
+ await this.dbup(app.workspace);
5000
5056
  if (sync)
5001
5057
  await this.syncApplication(app);
5002
- await this.#runner.startBackend(app, { open: open2 });
5058
+ const spinner = app.spinning("Preparing backend...");
5059
+ await this.#runner.startBackend(app, {
5060
+ open: open2,
5061
+ onStart: () => {
5062
+ spinner.succeed(`Backend prepared, ready to start`);
5063
+ }
5064
+ });
5003
5065
  }
5004
5066
  async buildFrontend(app, { sync = true } = {}) {
5005
5067
  if (sync)
5006
5068
  await this.syncApplication(app);
5007
5069
  const spinner = app.spinning("Building frontend...");
5008
5070
  await this.#runner.buildFrontend(app);
5009
- spinner.succeed(`Successfully built in dist/apps/${app.name}/frontend`);
5071
+ spinner.succeed(`Frontend built in dist/apps/${app.name}/frontend`);
5010
5072
  }
5011
5073
  async startFrontend(app, { open: open2 = false, turbo = false, sync = true } = {}) {
5012
5074
  if (sync)
5013
5075
  await this.syncApplication(app);
5014
- await this.#runner.startFrontend(app, { open: open2, turbo });
5076
+ const spinner = app.spinning("Preparing frontend...");
5077
+ await this.#runner.startFrontend(app, {
5078
+ open: open2,
5079
+ turbo,
5080
+ onStart: () => {
5081
+ spinner.succeed(`Frontend prepared, ready to start`);
5082
+ }
5083
+ });
5015
5084
  }
5016
5085
  async buildCsr(app, { sync = true } = {}) {
5017
5086
  if (sync)
@@ -5023,7 +5092,13 @@ var ApplicationScript = class {
5023
5092
  async startCsr(app, { open: open2 = false, sync = true } = {}) {
5024
5093
  if (sync)
5025
5094
  await this.syncApplication(app);
5026
- await this.#runner.startCsr(app, { open: open2 });
5095
+ const spinner = app.spinning("Preparing CSR...");
5096
+ await this.#runner.startCsr(app, {
5097
+ open: open2,
5098
+ onStart: () => {
5099
+ spinner.succeed(`CSR prepared, ready to start`);
5100
+ }
5101
+ });
5027
5102
  }
5028
5103
  async buildIos(app, { sync = true } = {}) {
5029
5104
  if (sync)
@@ -5062,13 +5137,17 @@ var ApplicationScript = class {
5062
5137
  await this.#runner.releaseAndroid(app);
5063
5138
  }
5064
5139
  async dumpDatabase(app, environment) {
5140
+ await this.dbdown(app.workspace);
5141
+ const spinner = app.spinning("Dumping database...");
5065
5142
  await this.#runner.dumpDatabase(app, environment);
5143
+ spinner.succeed(`Database dumped to dump/${app.name}-${environment}`);
5066
5144
  }
5067
5145
  async restoreDatabase(app, source, target) {
5146
+ const spinner = app.spinning("Restoring database...");
5068
5147
  await this.#runner.restoreDatabase(app, source, target);
5148
+ spinner.succeed(`Database restored from dump/${app.name}-${source} to ${app.name}-${target}`);
5069
5149
  }
5070
5150
  async pullDatabase(app, environment, dump) {
5071
- await this.dbdown(app.workspace);
5072
5151
  const hasDump = app.workspace.exists(`dump/${app.name}-${environment}`);
5073
5152
  if (dump || !hasDump)
5074
5153
  await this.dumpDatabase(app, environment);
@@ -5084,14 +5163,12 @@ var ApplicationScript = class {
5084
5163
  async dbup(workspace) {
5085
5164
  const spinner = workspace.spinning("Starting local database...");
5086
5165
  await this.#runner.dbup(workspace);
5087
- spinner.succeed(
5088
- "Local database(/local/docker-compose.yaml) is up, you can start your application and connect to the database"
5089
- );
5166
+ spinner.succeed("Local database (/local/docker-compose.yaml) is up");
5090
5167
  }
5091
5168
  async dbdown(workspace) {
5092
5169
  const spinner = workspace.spinning("Stopping local database...");
5093
5170
  await this.#runner.dbdown(workspace);
5094
- spinner.succeed("Local database(/local/docker-compose.yaml) is down");
5171
+ spinner.succeed("Local database (/local/docker-compose.yaml) is down");
5095
5172
  }
5096
5173
  async testSys(sys2) {
5097
5174
  if (sys2.type === "app")
@@ -5100,7 +5177,9 @@ var ApplicationScript = class {
5100
5177
  await this.libraryScript.testLibrary(sys2);
5101
5178
  }
5102
5179
  async testApplication(app) {
5180
+ const spinner = app.spinning("Testing application...");
5103
5181
  await this.#runner.testApplication(app);
5182
+ spinner.succeed(`Application ${app.name} (apps/${app.name}) test is successful`);
5104
5183
  }
5105
5184
  };
5106
5185
 
@@ -5113,8 +5192,8 @@ var ApplicationCommand = class {
5113
5192
  async removeApplication(app) {
5114
5193
  await this.applicationScript.removeApplication(app);
5115
5194
  }
5116
- async syncApplication(app, verbose) {
5117
- await this.applicationScript.syncApplication(app, verbose);
5195
+ async syncApplication(app) {
5196
+ await this.applicationScript.syncApplication(app);
5118
5197
  }
5119
5198
  async build(app) {
5120
5199
  await this.applicationScript.build(app);
@@ -5195,8 +5274,7 @@ __decorateClass([
5195
5274
  ], ApplicationCommand.prototype, "removeApplication", 1);
5196
5275
  __decorateClass([
5197
5276
  Target.Public(),
5198
- __decorateParam(0, App()),
5199
- __decorateParam(1, Option("verbose", { type: "boolean", desc: "verbose", default: false }))
5277
+ __decorateParam(0, App())
5200
5278
  ], ApplicationCommand.prototype, "syncApplication", 1);
5201
5279
  __decorateClass([
5202
5280
  Target.Public({ short: true }),
@@ -5365,17 +5443,25 @@ var PackageScript = class {
5365
5443
  await this.#runner.version(workspace);
5366
5444
  }
5367
5445
  async createPackage(workspace, pkgName) {
5446
+ const spinner = workspace.spinning(`Creating package in pkgs/${pkgName}...`);
5368
5447
  await this.#runner.createPackage(workspace, pkgName);
5448
+ spinner.succeed(`Package in pkgs/${pkgName} is created`);
5369
5449
  }
5370
5450
  async removePackage(pkg) {
5451
+ const spinner = pkg.spinning(`Removing package in pkgs/${pkg.name}...`);
5371
5452
  await this.#runner.removePackage(pkg);
5453
+ spinner.succeed("Package removed");
5372
5454
  }
5373
- async scanPackage(pkg) {
5455
+ async syncPackage(pkg) {
5456
+ const spinner = pkg.spinning("Scanning package...");
5374
5457
  const scanResult = await this.#runner.scanSync(pkg);
5375
- pkg.logger.rawLog(JSON.stringify(scanResult, null, 2));
5458
+ spinner.succeed("Package scanned");
5459
+ return scanResult;
5376
5460
  }
5377
5461
  async buildPackage(pkg) {
5462
+ const spinner = pkg.spinning("Building package...");
5378
5463
  await this.#runner.buildPackage(pkg);
5464
+ spinner.succeed("Package built");
5379
5465
  }
5380
5466
  };
5381
5467
 
@@ -5450,11 +5536,10 @@ ${import_chalk4.default.green("\u27A4")} Authentication Required`));
5450
5536
  }
5451
5537
  async setLlm() {
5452
5538
  await AiSession.init({ useExisting: true });
5453
- Logger.rawLog(import_chalk4.default.green("LLM model set successfully"));
5454
5539
  }
5455
5540
  resetLlm() {
5456
5541
  AiSession.setLlmConfig(null);
5457
- Logger.rawLog(import_chalk4.default.green("LLM model reset successfully"));
5542
+ Logger.rawLog(import_chalk4.default.green("\u2611\uFE0F LLM model config is cleared. Please run `akan set-llm` to set a new LLM model."));
5458
5543
  }
5459
5544
  async getAkanPkgs(workspace) {
5460
5545
  const pkgs = await workspace.getPkgs();
@@ -5484,7 +5569,7 @@ ${import_chalk4.default.green("\u27A4")} Authentication Required`));
5484
5569
  message: "Are you sure you want to deploy the libraries?"
5485
5570
  });
5486
5571
  if (!isDeployConfirmed) {
5487
- Logger.info("Deployment cancelled");
5572
+ Logger.error("Deployment cancelled");
5488
5573
  return;
5489
5574
  }
5490
5575
  await Promise.all(
@@ -5514,7 +5599,6 @@ ${import_chalk4.default.green("\u27A4")} Authentication Required`));
5514
5599
  workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
5515
5600
  workspace.spawn("pnpm", ["install"])
5516
5601
  ]);
5517
- Logger.info(`Akan.js is updated to the latest version ${latestPublishedVersionOfBase}`);
5518
5602
  }
5519
5603
  };
5520
5604
 
@@ -5522,19 +5606,19 @@ ${import_chalk4.default.green("\u27A4")} Authentication Required`));
5522
5606
  var CloudScript = class {
5523
5607
  #runner = new CloudRunner();
5524
5608
  #packageScript = new PackageScript();
5525
- async login() {
5609
+ async login(workspace) {
5526
5610
  await this.#runner.login();
5527
5611
  }
5528
- logout() {
5612
+ logout(workspace) {
5529
5613
  this.#runner.logout();
5530
5614
  }
5531
- async setLlm() {
5615
+ async setLlm(workspace) {
5532
5616
  await this.#runner.setLlm();
5533
5617
  }
5534
- resetLlm() {
5618
+ resetLlm(workspace) {
5535
5619
  this.#runner.resetLlm();
5536
5620
  }
5537
- async ask(question) {
5621
+ async ask(question, workspace) {
5538
5622
  await AiSession.init();
5539
5623
  const session = new AiSession();
5540
5624
  await session.ask(question);
@@ -5547,27 +5631,31 @@ var CloudScript = class {
5547
5631
  await this.#runner.deployAkan(workspace, akanPkgs);
5548
5632
  }
5549
5633
  async update(workspace) {
5634
+ const spinner = workspace.spinning("Updating Akan.js packages and CLI...");
5550
5635
  await this.#runner.update(workspace);
5636
+ spinner.succeed("Akan.js packages and CLI updated, global version is below");
5637
+ Logger.raw("> Akan version: ");
5638
+ await workspace.spawn("akan", ["--version"], { stdio: "inherit" });
5551
5639
  }
5552
5640
  };
5553
5641
 
5554
5642
  // pkgs/@akanjs/cli/src/cloud/cloud.command.ts
5555
5643
  var CloudCommand = class {
5556
5644
  cloudScript = new CloudScript();
5557
- async login() {
5558
- await this.cloudScript.login();
5645
+ async login(workspace) {
5646
+ await this.cloudScript.login(workspace);
5559
5647
  }
5560
- logout() {
5561
- this.cloudScript.logout();
5648
+ logout(workspace) {
5649
+ this.cloudScript.logout(workspace);
5562
5650
  }
5563
- async setLlm() {
5564
- await this.cloudScript.setLlm();
5651
+ async setLlm(workspace) {
5652
+ await this.cloudScript.setLlm(workspace);
5565
5653
  }
5566
- resetLlm() {
5567
- this.cloudScript.resetLlm();
5654
+ resetLlm(workspace) {
5655
+ this.cloudScript.resetLlm(workspace);
5568
5656
  }
5569
- async ask(question) {
5570
- await this.cloudScript.ask(question);
5657
+ async ask(question, workspace) {
5658
+ await this.cloudScript.ask(question, workspace);
5571
5659
  }
5572
5660
  async deployAkan(workspace) {
5573
5661
  await this.cloudScript.deployAkan(workspace);
@@ -5577,20 +5665,25 @@ var CloudCommand = class {
5577
5665
  }
5578
5666
  };
5579
5667
  __decorateClass([
5580
- Target.Public()
5668
+ Target.Public(),
5669
+ __decorateParam(0, Workspace())
5581
5670
  ], CloudCommand.prototype, "login", 1);
5582
5671
  __decorateClass([
5583
- Target.Public()
5672
+ Target.Public(),
5673
+ __decorateParam(0, Workspace())
5584
5674
  ], CloudCommand.prototype, "logout", 1);
5585
5675
  __decorateClass([
5586
- Target.Public()
5676
+ Target.Public(),
5677
+ __decorateParam(0, Workspace())
5587
5678
  ], CloudCommand.prototype, "setLlm", 1);
5588
5679
  __decorateClass([
5589
- Target.Public()
5680
+ Target.Public(),
5681
+ __decorateParam(0, Workspace())
5590
5682
  ], CloudCommand.prototype, "resetLlm", 1);
5591
5683
  __decorateClass([
5592
5684
  Target.Public(),
5593
- __decorateParam(0, Option("question", { ask: "question to ask" }))
5685
+ __decorateParam(0, Option("question", { ask: "question to ask" })),
5686
+ __decorateParam(1, Workspace())
5594
5687
  ], CloudCommand.prototype, "ask", 1);
5595
5688
  __decorateClass([
5596
5689
  Target.Public({ devOnly: true }),
@@ -5613,10 +5706,8 @@ var LibraryCommand = class {
5613
5706
  async removeLibrary(lib) {
5614
5707
  await this.libraryScript.removeLibrary(lib);
5615
5708
  }
5616
- async scanLibrary(lib) {
5617
- await this.libraryScript.scanLibrary(lib, true);
5618
- }
5619
- async buildLibrary(lib) {
5709
+ async syncLibrary(lib) {
5710
+ await this.libraryScript.syncLibrary(lib);
5620
5711
  }
5621
5712
  async installLibrary(name, workspace) {
5622
5713
  await this.libraryScript.installLibrary(workspace, name);
@@ -5640,11 +5731,7 @@ __decorateClass([
5640
5731
  __decorateClass([
5641
5732
  Target.Public(),
5642
5733
  __decorateParam(0, Lib())
5643
- ], LibraryCommand.prototype, "scanLibrary", 1);
5644
- __decorateClass([
5645
- Target.Public(),
5646
- __decorateParam(0, Lib())
5647
- ], LibraryCommand.prototype, "buildLibrary", 1);
5734
+ ], LibraryCommand.prototype, "syncLibrary", 1);
5648
5735
  __decorateClass([
5649
5736
  Target.Public(),
5650
5737
  __decorateParam(0, Option("name", { desc: "name of library" })),
@@ -6038,8 +6125,8 @@ var PackageCommand = class {
6038
6125
  async removePackage(pkg) {
6039
6126
  await this.packageScript.removePackage(pkg);
6040
6127
  }
6041
- async scanPackage(pkg) {
6042
- await this.packageScript.scanPackage(pkg);
6128
+ async syncPackage(pkg) {
6129
+ await this.packageScript.syncPackage(pkg);
6043
6130
  }
6044
6131
  async buildPackage(pkg) {
6045
6132
  await this.packageScript.buildPackage(pkg);
@@ -6061,7 +6148,7 @@ __decorateClass([
6061
6148
  __decorateClass([
6062
6149
  Target.Public(),
6063
6150
  __decorateParam(0, Pkg())
6064
- ], PackageCommand.prototype, "scanPackage", 1);
6151
+ ], PackageCommand.prototype, "syncPackage", 1);
6065
6152
  __decorateClass([
6066
6153
  Target.Public(),
6067
6154
  __decorateParam(0, Pkg())
@@ -6109,6 +6196,7 @@ var WorkspaceRunner = class {
6109
6196
  const cwdPath = process.cwd();
6110
6197
  const workspaceRoot = import_path5.default.join(cwdPath, dirname, repoName);
6111
6198
  const workspace = new WorkspaceExecutor({ workspaceRoot, repoName });
6199
+ const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname}/${repoName}...`);
6112
6200
  await workspace.applyTemplate({
6113
6201
  basePath: ".",
6114
6202
  template: "workspaceRoot",
@@ -6120,6 +6208,7 @@ var WorkspaceRunner = class {
6120
6208
  serveDomain: "localhost"
6121
6209
  }
6122
6210
  });
6211
+ templateSpinner.succeed(`Workspace files created in ${dirname}/${repoName}`);
6123
6212
  const rootPackageJson = workspace.readJson("package.json");
6124
6213
  const dependencies = [
6125
6214
  "@akanjs/base",
@@ -6152,10 +6241,12 @@ var WorkspaceRunner = class {
6152
6241
  }
6153
6242
  };
6154
6243
  workspace.writeFile("package.json", packageJson);
6155
- workspace.log("Installing dependencies...");
6244
+ const installSpinner = workspace.spinning("Installing dependencies with pnpm...");
6156
6245
  await workspace.spawn("pnpm", ["install", "--reporter=silent"]);
6157
- workspace.log("Initializing git repository and commit...");
6246
+ installSpinner.succeed("Dependencies installed with pnpm");
6247
+ const gitSpinner = workspace.spinning("Initializing git repository and commit...");
6158
6248
  await workspace.commit("Initial commit", { init: true });
6249
+ gitSpinner.succeed("Git repository initialized and committed");
6159
6250
  return workspace;
6160
6251
  }
6161
6252
  async generateMongo(workspace) {
@@ -6211,19 +6302,30 @@ var WorkspaceScript = class {
6211
6302
  await this.libraryScript.installLibrary(workspace, "util");
6212
6303
  await this.libraryScript.installLibrary(workspace, "shared");
6213
6304
  await this.applicationScript.createApplication(appName, workspace);
6214
- workspace.log(`Workspace created in ${workspace.workspaceRoot}`);
6215
- Logger.rawLog(`Run \`cd ${repoName} && akan start ${appName}\` to start the development server.`);
6305
+ Logger.rawLog(`
6306
+ \u{1F389} Welcome aboard! Workspace created in ${dirname}/${repoName}`);
6307
+ Logger.rawLog(`\u{1F680} Run \`cd ${repoName} && akan start ${appName}\` to start the development server.`);
6308
+ Logger.rawLog(`
6309
+ \u{1F44B} Happy coding!`);
6216
6310
  }
6217
6311
  async generateMongo(workspace) {
6312
+ const spinner = workspace.spinning("Generating Mongo connections...");
6218
6313
  await this.#runner.generateMongo(workspace);
6219
- workspace.log(`Mongo connections generated in infra/master/mongo-connections.json`);
6314
+ spinner.succeed(`Mongo connections generated in infra/master/mongo-connections.json`);
6220
6315
  }
6221
6316
  async lint(exec2, workspace, { fix = true } = {}) {
6222
6317
  if (exec2 instanceof AppExecutor)
6223
6318
  await this.applicationScript.syncApplication(exec2);
6224
6319
  else if (exec2 instanceof LibExecutor)
6225
6320
  await this.libraryScript.syncLibrary(exec2);
6226
- await this.#runner.lint(exec2, workspace, { fix });
6321
+ const spinner = workspace.spinning(`Linting${fix ? " with fix" : ""}...`);
6322
+ try {
6323
+ await this.#runner.lint(exec2, workspace, { fix });
6324
+ spinner.succeed("Lint completed with no errors");
6325
+ } catch (error) {
6326
+ spinner.fail("Lint failed with errors");
6327
+ throw error;
6328
+ }
6227
6329
  }
6228
6330
  async lintAll(workspace, { fix = true } = {}) {
6229
6331
  const [appNames, libNames, pkgNames] = await workspace.getExecs();