@koishi-ce/koishi 1.0.6 → 1.0.8

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/README.md CHANGED
@@ -33,11 +33,11 @@ bunx create-koishi-ce my-app
33
33
  | `--log-level [level]` | 2 | 日志等级 |
34
34
  | `--log-time [format]` | - | 日志时间戳格式 |
35
35
 
36
- 不带子命令运行 `koishi` 时输出帮助。
36
+ 不带子命令运行 `koishi` 时输出帮助。交互终端中启动时还会打印 Koishi-CE 启动横幅与字符画(仅 TTY,输出被重定向时不打印)。
37
37
 
38
38
  ## 守护进程机制
39
39
 
40
- `koishi start` 是守护父进程:以 Bun.spawn 拉起工作进程并保持 IPC 心跳,心跳超时强制终止。退出码约定:51 = 工作进程请求整体重启(配置文件或框架依赖变更),52 = 请求退出。工作进程内由 loader 读取配置、预检服务器端口(被占则干净退出)、创建应用并挂载 daemon 插件。
40
+ `koishi start` 是守护父进程:以 Bun.spawn 拉起工作进程,工作进程运行时崩溃后默认自动重启;IPC 心跳为可选配置(默认关闭,开启后超时未收到心跳将强制终止工作进程)。退出码约定:51 = 工作进程请求整体重启(配置文件或框架依赖变更),52 = 请求退出。工作进程内由 loader 读取配置、预检服务器端口(被占则干净退出)、创建应用并挂载 daemon 插件。
41
41
 
42
42
  ## 编程式用法
43
43
 
@@ -72,9 +72,9 @@ bunx create-koishi-ce my-app
72
72
 
73
73
  ## CLI
74
74
 
75
- `koishi start [file]` (alias `run`) starts the app, with options `--debug [namespace]`, `--log-level [level]` (default 2) and `--log-time [format]`. Running `koishi` without a subcommand prints help.
75
+ `koishi start [file]` (alias `run`) starts the app, with options `--debug [namespace]`, `--log-level [level]` (default 2) and `--log-time [format]`. Running `koishi` without a subcommand prints help. When started in an interactive terminal, a Koishi-CE startup banner with ASCII art is printed (TTY only, suppressed when output is redirected).
76
76
 
77
- The `start` command is a daemon parent: it spawns the worker via Bun.spawn with IPC heartbeats. Exit code 51 asks for a full restart, 52 asks to quit. The worker reads the config through the loader, prechecks server ports, creates the app and mounts the daemon plugin.
77
+ The `start` command is a daemon parent: it spawns the worker via Bun.spawn and restarts it by default after runtime crashes; IPC heartbeats are optional (off by default — once enabled, a missed heartbeat force-kills the worker). Exit code 51 asks for a full restart, 52 asks to quit. The worker reads the config through the loader, prechecks server ports, creates the app and mounts the daemon plugin.
78
78
 
79
79
  ## Programmatic usage
80
80
 
package/lib/cli/index.mjs CHANGED
@@ -7,7 +7,7 @@ var package_default = {
7
7
  name: "@koishi-ce/koishi",
8
8
  type: "module",
9
9
  description: "Cross-Platform Chatbot Framework Made with Love",
10
- version: "1.0.6",
10
+ version: "1.0.8",
11
11
  main: "lib/index.mjs",
12
12
  module: "lib/index.mjs",
13
13
  types: "lib/index.d.ts",
@@ -2,7 +2,9 @@ import { t as Loader } from "../index-B9rkkFue.js";
2
2
  import { Context, Dict, Schema } from "@koishi-ce/core";
3
3
  export * from "@koishi-ce/core";
4
4
  export * from "@koishi-ce/loader";
5
- //#region src/worker/daemon.d.ts
5
+ declare namespace daemon_d_exports {
6
+ export { Config$1 as Config, apply, name };
7
+ }
6
8
  /** 守护设置 */
7
9
  interface Config$1 {
8
10
  /** 运行时崩溃后是否自动重启 */
@@ -13,8 +15,11 @@ interface Config$1 {
13
15
  heartbeatTimeout?: number;
14
16
  }
15
17
  declare const Config$1: Schema<Config$1>;
16
- //#endregion
17
- //#region src/worker/logger.d.ts
18
+ declare const name = "daemon";
19
+ declare function apply(ctx: Context, config?: Config$1): void;
20
+ declare namespace logger_d_exports {
21
+ export { Config, prepare };
22
+ }
18
23
  /**
19
24
  * 配置文件形态的日志等级表。
20
25
  * 与 @koishi-ce/utils 中的实现略有差异:此处不强制用户提供 base 等级,
@@ -37,6 +42,15 @@ interface Config {
37
42
  showTime?: string | boolean;
38
43
  }
39
44
  declare const Config: Schema<Config>;
45
+ /**
46
+ * 在应用启动前应用日志配置。
47
+ *
48
+ * 处理顺序:配置文件中的等级表 → 时间格式与时间差显示 → CLI 环境变量覆盖 →
49
+ * 补全所有分组的 base 等级 → KOISHI_DEBUG 指定的命名空间设为 DEBUG 级。
50
+ *
51
+ * @param config 来自配置文件 logger 节点的设置
52
+ */
53
+ declare function prepare(config?: Config): void;
40
54
  //#endregion
41
55
  //#region src/worker/index.d.ts
42
56
  declare module "@koishi-ce/core" {
@@ -2,6 +2,7 @@ import { t as __exportAll } from "../rolldown-runtime-BBjsoOtd.mjs";
2
2
  import { t as Loader } from "../src-BnUZO8R-.mjs";
3
3
  import { Context, Logger, Schema, Time, defineProperty } from "@koishi-ce/core";
4
4
  import Loader$1, { resolvePlugin } from "@koishi-ce/loader";
5
+ import pc from "picocolors";
5
6
  import { existsSync, readFileSync } from "node:fs";
6
7
  import net from "node:net";
7
8
  import { dirname, resolve } from "node:path";
@@ -210,12 +211,31 @@ async function checkPorts(plugins, baseDir) {
210
211
  process.exit(1);
211
212
  }
212
213
  }
214
+ /** 启动字符画(ANSI Shadow 字体的 KOISHI CE) */
215
+ const banner = [
216
+ "██╗ ██╗ ██████╗ ██╗███████╗██╗ ██╗██╗ ██████╗███████╗",
217
+ "██║ ██╔╝██╔═══██╗██║██╔════╝██║ ██║██║ ██╔════╝██╔════╝",
218
+ "█████╔╝ ██║ ██║██║███████╗███████║██║█████╗██║ █████╗",
219
+ "██╔═██╗ ██║ ██║██║╚════██║██╔══██║██║╚════╝██║ ██╔══╝",
220
+ "██║ ██╗╚██████╔╝██║███████║██║ ██║██║ ╚██████╗███████╗",
221
+ "╚═╝ ╚═╝ ╚═════╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝╚══════╝"
222
+ ].join("\n");
223
+ /**
224
+ * 输出启动字符画。直走 stdout 而非 Logger 通道(多行消息会被日志器
225
+ * 统一缩进、首行混入时间戳前缀,破坏字符画对齐),因此以 isTTY 收敛:
226
+ * 测试与重定向/CI 等非交互环境自动跳过,不产生输出噪音。
227
+ */
228
+ function printBanner() {
229
+ if (!process.stdout.isTTY) return;
230
+ console.log(pc.white(banner));
231
+ }
213
232
  /** 应用启动主流程 */
214
233
  async function start() {
215
234
  const loader = new Loader$1();
216
235
  await loader.init(process.env["KOISHI_CONFIG_FILE"]);
217
236
  const config = await loader.readConfig(true);
218
237
  prepare(config.logger);
238
+ printBanner();
219
239
  await checkPorts(config.plugins ?? {}, loader.baseDir);
220
240
  if (config.timezoneOffset !== void 0) Time.setTimezoneOffset(config.timezoneOffset);
221
241
  if (config.stackTraceLimit !== void 0) Error.stackTraceLimit = config.stackTraceLimit;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@koishi-ce/koishi",
3
3
  "type": "module",
4
4
  "description": "Cross-Platform Chatbot Framework Made with Love",
5
- "version": "1.0.6",
5
+ "version": "1.0.8",
6
6
  "main": "lib/index.mjs",
7
7
  "module": "lib/index.mjs",
8
8
  "types": "lib/index.d.ts",
@@ -61,10 +61,10 @@
61
61
  }
62
62
  },
63
63
  "dependencies": {
64
- "@koishi-ce/core": "^1.0.1",
65
- "@koishi-ce/loader": "^1.0.5",
66
- "@koishi-ce/plugin-http": "^1.0.0",
67
- "@koishi-ce/plugin-proxy-agent": "^1.0.0",
64
+ "@koishi-ce/core": "^1.1.0",
65
+ "@koishi-ce/loader": "^1.0.6",
66
+ "@koishi-ce/plugin-http": "^1.0.1",
67
+ "@koishi-ce/plugin-proxy-agent": "^1.0.1",
68
68
  "@koishi-ce/plugin-server": "^1.0.1",
69
69
  "@koishi-ce/utils": "^1.0.0",
70
70
  "cac": "^7.0.0",
@@ -22,6 +22,7 @@ import {
22
22
  Time,
23
23
  } from "@koishi-ce/core";
24
24
  import Loader, { resolvePlugin } from "@koishi-ce/loader";
25
+ import pc from "picocolors";
25
26
  import * as daemon from "./daemon.ts";
26
27
  import * as logger from "./logger.ts";
27
28
 
@@ -200,12 +201,33 @@ async function checkPorts(plugins: Dict, baseDir: string) {
200
201
  }
201
202
  }
202
203
 
204
+ /** 启动字符画(ANSI Shadow 字体的 KOISHI CE) */
205
+ const banner = [
206
+ "██╗ ██╗ ██████╗ ██╗███████╗██╗ ██╗██╗ ██████╗███████╗",
207
+ "██║ ██╔╝██╔═══██╗██║██╔════╝██║ ██║██║ ██╔════╝██╔════╝",
208
+ "█████╔╝ ██║ ██║██║███████╗███████║██║█████╗██║ █████╗",
209
+ "██╔═██╗ ██║ ██║██║╚════██║██╔══██║██║╚════╝██║ ██╔══╝",
210
+ "██║ ██╗╚██████╔╝██║███████║██║ ██║██║ ╚██████╗███████╗",
211
+ "╚═╝ ╚═╝ ╚═════╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝╚══════╝",
212
+ ].join("\n");
213
+
214
+ /**
215
+ * 输出启动字符画。直走 stdout 而非 Logger 通道(多行消息会被日志器
216
+ * 统一缩进、首行混入时间戳前缀,破坏字符画对齐),因此以 isTTY 收敛:
217
+ * 测试与重定向/CI 等非交互环境自动跳过,不产生输出噪音。
218
+ */
219
+ function printBanner() {
220
+ if (!process.stdout.isTTY) return;
221
+ console.log(pc.white(banner));
222
+ }
223
+
203
224
  /** 应用启动主流程 */
204
225
  async function start() {
205
226
  const loader = new Loader();
206
227
  await loader.init(process.env["KOISHI_CONFIG_FILE"]);
207
228
  const config = await loader.readConfig(true);
208
229
  logger.prepare(config.logger);
230
+ printBanner();
209
231
 
210
232
  // 端口预检须在日志配置生效后、应用创建前执行
211
233
  await checkPorts(config.plugins ?? {}, loader.baseDir);